From 127bd8cece27ccd5182a37ede8826a794f29dd97 Mon Sep 17 00:00:00 2001 From: Mnikolenko Productengine Date: Fri, 14 Aug 2026 19:10:11 +0300 Subject: #6025 Add 'Join' modal web floater --- indra/newview/CMakeLists.txt | 2 + indra/newview/app_settings/settings.xml | 11 +++ indra/newview/llfloaterjoin.cpp | 97 ++++++++++++++++++++++ indra/newview/llfloaterjoin.h | 47 +++++++++++ indra/newview/llpanellogin.cpp | 6 +- indra/newview/llviewerfloaterreg.cpp | 2 + .../newview/skins/default/xui/en/floater_join.xml | 49 +++++++++++ 7 files changed, 210 insertions(+), 4 deletions(-) create mode 100644 indra/newview/llfloaterjoin.cpp create mode 100644 indra/newview/llfloaterjoin.h create mode 100644 indra/newview/skins/default/xui/en/floater_join.xml diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index c9db55c52d..668d2eae83 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -252,6 +252,7 @@ set(viewer_SOURCE_FILES llfloaterinspect.cpp llfloaterinventorysettings.cpp llfloaterinventorythumbnailshelper.cpp + llfloaterjoin.cpp llfloaterjoystick.cpp llfloaterlagmeter.cpp llfloaterland.cpp @@ -940,6 +941,7 @@ set(viewer_HEADER_FILES llfloaterinspect.h llfloaterinventorysettings.h llfloaterinventorythumbnailshelper.h + llfloaterjoin.h llfloaterjoystick.h llfloaterlagmeter.h llfloaterland.h diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 386f3bb46e..19310ea32f 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -3808,6 +3808,17 @@ Value 0 + JoinURL + + Comment + URL opened in the Join floater on the login screen + Persist + 1 + Type + String + Value + https://join.secondlife.com/ + JoystickAvatarEnabled Comment diff --git a/indra/newview/llfloaterjoin.cpp b/indra/newview/llfloaterjoin.cpp new file mode 100644 index 0000000000..19f8e29892 --- /dev/null +++ b/indra/newview/llfloaterjoin.cpp @@ -0,0 +1,97 @@ +/** + * @file llfloaterjoin.cpp + * @brief Modal floater for the Join page on the login screen + * + * $LicenseInfo:firstyear=2026&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2026, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llfloaterjoin.h" + +#include "llcommandhandler.h" +#include "llfloaterreg.h" +#include "llmediactrl.h" +#include "llui.h" +#include "llviewercontrol.h" + +static const F32 OVERLAY_OPACITY = 0.8f; + +// support for secondlife:///app/floaterjoin/{ACTION}/... SLapps +class LLFloaterJoinHandler : public LLCommandHandler +{ +public: + LLFloaterJoinHandler() : LLCommandHandler("floaterjoin", UNTRUSTED_THROTTLE) {} + + bool handle(const LLSD& params, const LLSD& query_map, const std::string& grid, LLMediaCtrl* web) + { + if (params.size() < 1) + return false; + + if (params[0].asString() == "close") + { + LLFloaterReg::hideInstance("join"); + } + + return true; + } +}; +LLFloaterJoinHandler gFloaterJoinHandler; + +LLFloaterJoin::LLFloaterJoin(const LLSD& key) + : LLModalDialog(key, /*modal=*/true) +{ +} + +bool LLFloaterJoin::postBuild() +{ + mWebBrowser = getChild("join_browser"); + return true; +} + +void LLFloaterJoin::draw() +{ + // darken everything behind the floater + LLVector2 window_size = LLUI::getInstance()->getWindowSize(); + LLRect screen_rect = calcScreenRect(); + gl_rect_2d(-screen_rect.mLeft, ll_round(window_size.mV[VY]) - screen_rect.mBottom, + ll_round(window_size.mV[VX]) - screen_rect.mLeft, -screen_rect.mBottom, + LLColor4(0.f, 0.f, 0.f, OVERLAY_OPACITY)); + + LLModalDialog::draw(); +} + +void LLFloaterJoin::onOpen(const LLSD& key) +{ + LLModalDialog::onOpen(key); + + std::string url = gSavedSettings.getString("JoinURL"); + if (key.has("url")) + { + url = key["url"].asString(); + } + + if (mWebBrowser && !url.empty()) + { + mWebBrowser->navigateTo(url, HTTP_CONTENT_TEXT_HTML); + } +} diff --git a/indra/newview/llfloaterjoin.h b/indra/newview/llfloaterjoin.h new file mode 100644 index 0000000000..32fc8a30d6 --- /dev/null +++ b/indra/newview/llfloaterjoin.h @@ -0,0 +1,47 @@ +/** + * @file llfloaterjoin.h + * @brief Modal floater for the Join page on the login screen + * + * $LicenseInfo:firstyear=2026&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2026, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#pragma once + +#include "llmodaldialog.h" + +class LLMediaCtrl; + +class LLFloaterJoin : public LLModalDialog +{ + friend class LLFloaterReg; +public: + bool postBuild() override; + void onOpen(const LLSD& key) override; + void draw() override; + +private: + LLFloaterJoin(const LLSD& key); + ~LLFloaterJoin() = default; + + LLMediaCtrl* mWebBrowser = nullptr; +}; + diff --git a/indra/newview/llpanellogin.cpp b/indra/newview/llpanellogin.cpp index 9b5a339958..54404d8fb4 100644 --- a/indra/newview/llpanellogin.cpp +++ b/indra/newview/llpanellogin.cpp @@ -65,6 +65,7 @@ #include "llmediactrl.h" #include "llrootview.h" +#include "llfloaterjoin.h" #include "llfloatertos.h" #include "lltrans.h" #include "llglheaders.h" @@ -1057,10 +1058,7 @@ void LLPanelLogin::onClickForgotPassword(void*) //static void LLPanelLogin::onClickSignUp(void*) { - if (sInstance) - { - LLWeb::loadURLExternal(sInstance->getString("sign_up_url")); - } + LLFloaterReg::showInstance("join"); } // static diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp index 0cfbcc06c0..f49b1ccbde 100644 --- a/indra/newview/llviewerfloaterreg.cpp +++ b/indra/newview/llviewerfloaterreg.cpp @@ -92,6 +92,7 @@ #include "llfloaterinspect.h" #include "llfloaterinventorysettings.h" #include "llfloaterinventorythumbnailshelper.h" +#include "llfloaterjoin.h" #include "llfloaterjoystick.h" #include "llfloaterlagmeter.h" #include "llfloaterland.h" @@ -406,6 +407,7 @@ void LLViewerFloaterReg::registerFloaters() LLFloaterReg::add("item_properties", "floater_item_properties.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); LLFloaterReg::add("task_properties", "floater_task_properties.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); LLFloaterReg::add("inventory_settings", "floater_inventory_settings.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); + LLFloaterReg::add("join", "floater_join.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); LLInspectAvatarUtil::registerFloater(); LLInspectGroupUtil::registerFloater(); LLInspectObjectUtil::registerFloater(); diff --git a/indra/newview/skins/default/xui/en/floater_join.xml b/indra/newview/skins/default/xui/en/floater_join.xml new file mode 100644 index 0000000000..dabda77b60 --- /dev/null +++ b/indra/newview/skins/default/xui/en/floater_join.xml @@ -0,0 +1,49 @@ + + + + + + + secondlife:///app/floaterjoin/close + + -- cgit v1.3 From 9ed2e1bc3005499ffcc6f0af33aef259c4bbe1e7 Mon Sep 17 00:00:00 2001 From: Mnikolenko Productengine Date: Thu, 20 Aug 2026 02:27:41 +0300 Subject: #6151 populate username/password from slapp parameters --- indra/newview/llfloaterjoin.cpp | 13 ++++++++++++- indra/newview/llpanellogin.cpp | 13 +++++++++++++ indra/newview/llpanellogin.h | 1 + indra/newview/skins/default/xui/en/floater_join.xml | 13 +++++++++++++ 4 files changed, 39 insertions(+), 1 deletion(-) diff --git a/indra/newview/llfloaterjoin.cpp b/indra/newview/llfloaterjoin.cpp index 19f8e29892..3222643635 100644 --- a/indra/newview/llfloaterjoin.cpp +++ b/indra/newview/llfloaterjoin.cpp @@ -31,6 +31,7 @@ #include "llcommandhandler.h" #include "llfloaterreg.h" #include "llmediactrl.h" +#include "llpanellogin.h" #include "llui.h" #include "llviewercontrol.h" @@ -47,10 +48,18 @@ public: if (params.size() < 1) return false; - if (params[0].asString() == "close") + const std::string action = params[0].asString(); + + if (action == "close") { LLFloaterReg::hideInstance("join"); } + else if (action == "join" && params.size() >= 3) + { + LLPanelLogin::setCredentialFields(LLURI::unescape(params[1].asString()), + LLURI::unescape(params[2].asString())); + LLFloaterReg::hideInstance("join"); + } return true; } @@ -94,4 +103,6 @@ void LLFloaterJoin::onOpen(const LLSD& key) { mWebBrowser->navigateTo(url, HTTP_CONTENT_TEXT_HTML); } + + centerOnScreen(); } diff --git a/indra/newview/llpanellogin.cpp b/indra/newview/llpanellogin.cpp index 54404d8fb4..d382ef2df5 100644 --- a/indra/newview/llpanellogin.cpp +++ b/indra/newview/llpanellogin.cpp @@ -536,6 +536,19 @@ void LLPanelLogin::reshapePanel() } } +//static +void LLPanelLogin::setCredentialFields(const std::string& username, const std::string& password) +{ + if (!sInstance) + return; + sInstance->getChild("username_combo")->setLabel(username); + sInstance->mUsernameLength = static_cast(username.length()); + sInstance->getChild("password_edit")->setValue(password); + sInstance->mPasswordLength = static_cast(password.length()); + sInstance->mPasswordModified = true; + sInstance->updateLoginButtons(); +} + //static void LLPanelLogin::populateFields(LLPointer credential, bool remember_user, bool remember_psswrd) { diff --git a/indra/newview/llpanellogin.h b/indra/newview/llpanellogin.h index a00081795e..453b645299 100644 --- a/indra/newview/llpanellogin.h +++ b/indra/newview/llpanellogin.h @@ -60,6 +60,7 @@ public: static void populateFields(LLPointer credential, bool remember_user, bool remember_psswrd); static void resetFields(); static void getFields(LLPointer& credential, bool& remember_user, bool& remember_psswrd); + static void setCredentialFields(const std::string& username, const std::string& password); static bool isCredentialSet() { return sCredentialSet; } diff --git a/indra/newview/skins/default/xui/en/floater_join.xml b/indra/newview/skins/default/xui/en/floater_join.xml index dabda77b60..45f48421f4 100644 --- a/indra/newview/skins/default/xui/en/floater_join.xml +++ b/indra/newview/skins/default/xui/en/floater_join.xml @@ -46,4 +46,17 @@ height="16"> secondlife:///app/floaterjoin/close + + + secondlife:///app/floaterjoin/join/testuser/testpassword + -- cgit v1.3 From ff35f62d33ad7084927c5c74f6ce3bc8fc8c0ffd Mon Sep 17 00:00:00 2001 From: Mnikolenko Productengine Date: Fri, 25 Sep 2026 17:56:37 +0300 Subject: #6151 set Remember username and password check boxes to checked after filling the fields --- indra/newview/app_settings/settings.xml | 22 ++++++++++++++++++++++ indra/newview/llfloaterjoin.cpp | 10 +++++++--- indra/newview/llpanellogin.cpp | 5 +++++ .../newview/skins/default/xui/en/floater_join.xml | 2 ++ 4 files changed, 36 insertions(+), 3 deletions(-) diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 19310ea32f..323ccdce46 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -3808,6 +3808,28 @@ Value 0 + JoinFloaterOverlayOpacity + + Comment + Opacity of the screen darkening overlay behind the Join floater + Persist + 1 + Type + F32 + Value + 0.8 + + JoinFloaterTestSLapp + + Comment + For testing only: Show links in the Join floater that trigger its close/join SLapps. + Persist + 1 + Type + Boolean + Value + 0 + JoinURL Comment diff --git a/indra/newview/llfloaterjoin.cpp b/indra/newview/llfloaterjoin.cpp index 3222643635..0c77c4cdfa 100644 --- a/indra/newview/llfloaterjoin.cpp +++ b/indra/newview/llfloaterjoin.cpp @@ -35,8 +35,6 @@ #include "llui.h" #include "llviewercontrol.h" -static const F32 OVERLAY_OPACITY = 0.8f; - // support for secondlife:///app/floaterjoin/{ACTION}/... SLapps class LLFloaterJoinHandler : public LLCommandHandler { @@ -79,12 +77,14 @@ bool LLFloaterJoin::postBuild() void LLFloaterJoin::draw() { + static LLCachedControl overlay_opacity(gSavedSettings, "JoinFloaterOverlayOpacity"); + // darken everything behind the floater LLVector2 window_size = LLUI::getInstance()->getWindowSize(); LLRect screen_rect = calcScreenRect(); gl_rect_2d(-screen_rect.mLeft, ll_round(window_size.mV[VY]) - screen_rect.mBottom, ll_round(window_size.mV[VX]) - screen_rect.mLeft, -screen_rect.mBottom, - LLColor4(0.f, 0.f, 0.f, OVERLAY_OPACITY)); + LLColor4(0.f, 0.f, 0.f, llclamp((F32)overlay_opacity, 0.f, 1.f))); LLModalDialog::draw(); } @@ -105,4 +105,8 @@ void LLFloaterJoin::onOpen(const LLSD& key) } centerOnScreen(); + + static LLCachedControl show_test_slapp(gSavedSettings, "JoinFloaterTestSLapp"); + getChild("test_close_link")->setVisible(show_test_slapp); + getChild("test_join_link")->setVisible(show_test_slapp); } diff --git a/indra/newview/llpanellogin.cpp b/indra/newview/llpanellogin.cpp index d382ef2df5..77b09a610c 100644 --- a/indra/newview/llpanellogin.cpp +++ b/indra/newview/llpanellogin.cpp @@ -547,6 +547,11 @@ void LLPanelLogin::setCredentialFields(const std::string& username, const std::s sInstance->mPasswordLength = static_cast(password.length()); sInstance->mPasswordModified = true; sInstance->updateLoginButtons(); + + sInstance->getChild("remember_name")->setValue(true); + LLUICtrl* remember_password = sInstance->getChild("remember_password"); + remember_password->setValue(true); + remember_password->setEnabled(true); } //static diff --git a/indra/newview/skins/default/xui/en/floater_join.xml b/indra/newview/skins/default/xui/en/floater_join.xml index 45f48421f4..28c879f36e 100644 --- a/indra/newview/skins/default/xui/en/floater_join.xml +++ b/indra/newview/skins/default/xui/en/floater_join.xml @@ -37,6 +37,7 @@ Date: Mon, 28 Sep 2026 20:47:25 +0300 Subject: #6380 Don't write sensitive slapp to the viewer log --- indra/newview/llcommandhandler.cpp | 14 ++++++++++++++ indra/newview/llcommandhandler.h | 4 ++++ indra/newview/llfloaterjoin.cpp | 3 +++ indra/newview/llurldispatcher.cpp | 9 ++++++++- 4 files changed, 29 insertions(+), 1 deletion(-) diff --git a/indra/newview/llcommandhandler.cpp b/indra/newview/llcommandhandler.cpp index 4038ae8002..1ccf578118 100644 --- a/indra/newview/llcommandhandler.cpp +++ b/indra/newview/llcommandhandler.cpp @@ -66,6 +66,7 @@ public: LLMediaCtrl* web, const std::string& nav_type, bool trusted_browser); + bool isSensitive(const std::string& cmd) const; private: void notifySlurlBlocked(); @@ -170,6 +171,13 @@ bool LLCommandHandlerRegistry::dispatch(const std::string& cmd, return info.mHandler->handle(params, query_map, grid, web); } +bool LLCommandHandlerRegistry::isSensitive(const std::string& cmd) const +{ + std::map::const_iterator it = mMap.find(cmd); + if (it == mMap.end() || !it->second.mHandler) return false; + return it->second.mHandler->isSensitive(); +} + void LLCommandHandlerRegistry::notifySlurlBlocked() { static bool slurl_blocked = false; @@ -231,6 +239,12 @@ bool LLCommandDispatcher::dispatch(const std::string& cmd, cmd, params, query_map, grid, web, nav_type, trusted_browser); } +// static +bool LLCommandDispatcher::isSensitive(const std::string& cmd) +{ + return LLCommandHandlerRegistry::instance().isSensitive(cmd); +} + static std::string lookup(LLCommandHandler::EUntrustedAccess value); LLSD LLCommandDispatcher::enumerate() diff --git a/indra/newview/llcommandhandler.h b/indra/newview/llcommandhandler.h index 7ec19d6538..f6c7565e6b 100644 --- a/indra/newview/llcommandhandler.h +++ b/indra/newview/llcommandhandler.h @@ -88,6 +88,8 @@ public: const std::string& nav_type) { return true; } + virtual bool isSensitive() const { return false; } + virtual bool handle(const LLSD& params, const LLSD& query_map, const std::string& grid, @@ -117,6 +119,8 @@ public: /// Return an LLSD::Map of registered LLCommandHandlers and associated /// info (e.g. EUntrustedAccess). static LLSD enumerate(); + + static bool isSensitive(const std::string& cmd); }; #endif diff --git a/indra/newview/llfloaterjoin.cpp b/indra/newview/llfloaterjoin.cpp index 0c77c4cdfa..b665c46fd4 100644 --- a/indra/newview/llfloaterjoin.cpp +++ b/indra/newview/llfloaterjoin.cpp @@ -41,6 +41,9 @@ class LLFloaterJoinHandler : public LLCommandHandler public: LLFloaterJoinHandler() : LLCommandHandler("floaterjoin", UNTRUSTED_THROTTLE) {} + // params/query_map can contain the join password, keep it out of the log + bool isSensitive() const override { return true; } + bool handle(const LLSD& params, const LLSD& query_map, const std::string& grid, LLMediaCtrl* web) { if (params.size() < 1) diff --git a/indra/newview/llurldispatcher.cpp b/indra/newview/llurldispatcher.cpp index 39a9f0f8bc..8caecbae77 100644 --- a/indra/newview/llurldispatcher.cpp +++ b/indra/newview/llurldispatcher.cpp @@ -159,7 +159,14 @@ bool LLURLDispatcherImpl::dispatchApp(const LLSLURL& slurl, LLMediaCtrl* web, bool trusted_browser) { - LL_INFOS() << "cmd: " << slurl.getAppCmd() << " path: " << slurl.getAppPath() << " query: " << slurl.getAppQuery() << LL_ENDL; + // don't log path/query for sensitive commands + std::string app_info = "cmd: " + slurl.getAppCmd(); + if (!LLCommandDispatcher::isSensitive(slurl.getAppCmd())) + { + app_info += " path: " + slurl.getAppPath().asString() + " query: " + slurl.getAppQuery(); + } + LL_INFOS() << app_info << LL_ENDL; + const LLSD& query_map = LLURI::queryMap(slurl.getAppQuery()); bool handled = LLCommandDispatcher::dispatch( slurl.getAppCmd(), slurl.getAppPath(), query_map, slurl.getGrid(), web, nav_type, trusted_browser); -- cgit v1.3 From cd5789cacb7943f266ee442549f4816fc1a8dc10 Mon Sep 17 00:00:00 2001 From: Mnikolenko Productengine Date: Mon, 28 Sep 2026 21:07:23 +0300 Subject: #6380 Added missing override specifier --- indra/newview/llfloaterjoin.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/newview/llfloaterjoin.cpp b/indra/newview/llfloaterjoin.cpp index b665c46fd4..08b39318f9 100644 --- a/indra/newview/llfloaterjoin.cpp +++ b/indra/newview/llfloaterjoin.cpp @@ -44,7 +44,7 @@ public: // params/query_map can contain the join password, keep it out of the log bool isSensitive() const override { return true; } - bool handle(const LLSD& params, const LLSD& query_map, const std::string& grid, LLMediaCtrl* web) + bool handle(const LLSD& params, const LLSD& query_map, const std::string& grid, LLMediaCtrl* web) override { if (params.size() < 1) return false; -- cgit v1.3 From ada5195605d925258b1bc7c75124505b27c3a52b Mon Sep 17 00:00:00 2001 From: Mnikolenko Productengine Date: Wed, 30 Sep 2026 17:53:50 +0300 Subject: Show ToS in a separate floater above Join page --- indra/llui/llmodaldialog.cpp | 7 +-- indra/llui/llmodaldialog.h | 3 +- indra/newview/CMakeLists.txt | 2 + indra/newview/app_settings/settings.xml | 22 ++++++++ indra/newview/llfloaterjoin.cpp | 35 +++++++++--- indra/newview/llfloaterjoin.h | 1 + indra/newview/llfloaterwebmodal.cpp | 63 ++++++++++++++++++++++ indra/newview/llfloaterwebmodal.h | 48 +++++++++++++++++ indra/newview/llviewerfloaterreg.cpp | 2 + .../newview/skins/default/xui/en/floater_join.xml | 32 ++++++++++- .../skins/default/xui/en/floater_web_modal.xml | 23 ++++++++ 11 files changed, 224 insertions(+), 14 deletions(-) create mode 100644 indra/newview/llfloaterwebmodal.cpp create mode 100644 indra/newview/llfloaterwebmodal.h create mode 100644 indra/newview/skins/default/xui/en/floater_web_modal.xml diff --git a/indra/llui/llmodaldialog.cpp b/indra/llui/llmodaldialog.cpp index 225ff607ad..73f3914160 100644 --- a/indra/llui/llmodaldialog.cpp +++ b/indra/llui/llmodaldialog.cpp @@ -40,9 +40,10 @@ // static std::list LLModalDialog::sModalStack; -LLModalDialog::LLModalDialog( const LLSD& key, bool modal ) +LLModalDialog::LLModalDialog( const LLSD& key, bool modal, bool hide_others ) : LLFloater(key), - mModal( modal ) + mModal( modal ), + mHideOthers( hide_others ) { if (modal) { @@ -101,7 +102,7 @@ void LLModalDialog::onOpen(const LLSD& key) if (mModal) { // If Modal, hide the active modal dialog - if (!sModalStack.empty()) + if (mHideOthers && !sModalStack.empty()) { LLModalDialog* front = sModalStack.front(); if (front != this) diff --git a/indra/llui/llmodaldialog.h b/indra/llui/llmodaldialog.h index 177664dde4..16ede3e515 100644 --- a/indra/llui/llmodaldialog.h +++ b/indra/llui/llmodaldialog.h @@ -39,7 +39,7 @@ class LLModalDialog; class LLModalDialog : public LLFloater { public: - LLModalDialog( const LLSD& key, bool modal = true ); + LLModalDialog( const LLSD& key, bool modal = true, bool hide_others = true ); virtual ~LLModalDialog(); /*virtual*/ bool postBuild(); @@ -76,6 +76,7 @@ private: LLFrameTimer mVisibleTime; const bool mModal; + const bool mHideOthers; static std::list sModalStack; // Top of stack is currently being displayed }; diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 668d2eae83..7429eebe86 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -320,6 +320,7 @@ set(viewer_SOURCE_FILES llfloaterurlentry.cpp llfloatervoicevolume.cpp llfloaterwebcontent.cpp + llfloaterwebmodal.cpp llfloaterwhitelistentry.cpp llfloaterwindowsize.cpp llfloaterworldmap.cpp @@ -1010,6 +1011,7 @@ set(viewer_HEADER_FILES llfloaterurlentry.h llfloatervoicevolume.h llfloaterwebcontent.h + llfloaterwebmodal.h llfloaterwhitelistentry.h llfloaterwindowsize.h llfloaterworldmap.h diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 323ccdce46..99035e029d 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -3819,6 +3819,28 @@ Value 0.8 + TermsAndConditionsURL + + Comment + URL pointing to Terms and Conditions page + Persist + 1 + Type + String + Value + https://lindenlab.com/legal/second-life-terms-and-conditions + + TermsOfServiceURL + + Comment + >URL pointing to Terms of Service page + Persist + 1 + Type + String + Value + https://lindenlab.com/tos + JoinFloaterTestSLapp Comment diff --git a/indra/newview/llfloaterjoin.cpp b/indra/newview/llfloaterjoin.cpp index 08b39318f9..a37fd60cb1 100644 --- a/indra/newview/llfloaterjoin.cpp +++ b/indra/newview/llfloaterjoin.cpp @@ -30,6 +30,8 @@ #include "llcommandhandler.h" #include "llfloaterreg.h" +#include "llframetimer.h" +#include "llfloaterwebmodal.h" #include "llmediactrl.h" #include "llpanellogin.h" #include "llui.h" @@ -55,6 +57,14 @@ public: { LLFloaterReg::hideInstance("join"); } + else if (action == "tos") + { + LLFloaterReg::showInstance("web_modal", LLSD().with("url", gSavedSettings.getString("TermsOfServiceURL"))); + } + else if (action == "tc") + { + LLFloaterReg::showInstance("web_modal", LLSD().with("url", gSavedSettings.getString("TermsAndConditionsURL"))); + } else if (action == "join" && params.size() >= 3) { LLPanelLogin::setCredentialFields(LLURI::unescape(params[1].asString()), @@ -82,12 +92,21 @@ void LLFloaterJoin::draw() { static LLCachedControl overlay_opacity(gSavedSettings, "JoinFloaterOverlayOpacity"); - // darken everything behind the floater - LLVector2 window_size = LLUI::getInstance()->getWindowSize(); - LLRect screen_rect = calcScreenRect(); - gl_rect_2d(-screen_rect.mLeft, ll_round(window_size.mV[VY]) - screen_rect.mBottom, - ll_round(window_size.mV[VX]) - screen_rect.mLeft, -screen_rect.mBottom, - LLColor4(0.f, 0.f, 0.f, llclamp((F32)overlay_opacity, 0.f, 1.f))); + // As a modal dialog this floater is drawn twice per frame (once by LLFloaterView and once + // by LLPopupView), so paint the overlay only on the first pass of each frame + U32 frame_count = LLFrameTimer::getFrameCount(); + if (mOverlayFrame != frame_count) + { + mOverlayFrame = frame_count; + + // darken everything behind the floater, in absolute window coordinates + LLVector2 window_size = LLUI::getInstance()->getWindowSize(); + LLUI::pushMatrix(); + LLUI::loadIdentity(); + gl_rect_2d(0, ll_round(window_size.mV[VY]), ll_round(window_size.mV[VX]), 0, + LLColor4(0.f, 0.f, 0.f, llclamp((F32)overlay_opacity, 0.f, 1.f))); + LLUI::popMatrix(); + } LLModalDialog::draw(); } @@ -107,9 +126,9 @@ void LLFloaterJoin::onOpen(const LLSD& key) mWebBrowser->navigateTo(url, HTTP_CONTENT_TEXT_HTML); } - centerOnScreen(); - static LLCachedControl show_test_slapp(gSavedSettings, "JoinFloaterTestSLapp"); getChild("test_close_link")->setVisible(show_test_slapp); getChild("test_join_link")->setVisible(show_test_slapp); + getChild("test_tos_link")->setVisible(show_test_slapp); + getChild("test_tc_link")->setVisible(show_test_slapp); } diff --git a/indra/newview/llfloaterjoin.h b/indra/newview/llfloaterjoin.h index 32fc8a30d6..8b69292f9d 100644 --- a/indra/newview/llfloaterjoin.h +++ b/indra/newview/llfloaterjoin.h @@ -43,5 +43,6 @@ private: ~LLFloaterJoin() = default; LLMediaCtrl* mWebBrowser = nullptr; + U32 mOverlayFrame = 0; }; diff --git a/indra/newview/llfloaterwebmodal.cpp b/indra/newview/llfloaterwebmodal.cpp new file mode 100644 index 0000000000..ac74af5d6f --- /dev/null +++ b/indra/newview/llfloaterwebmodal.cpp @@ -0,0 +1,63 @@ +/** + * @file llfloaterwebmodal.cpp + * @brief Modal floater for displaying a web page above other modal floaters + * + * $LicenseInfo:firstyear=2026&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2026, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llfloaterwebmodal.h" + +#include "llmediactrl.h" + +LLFloaterWebModal::LLFloaterWebModal(const LLSD& key) + // don't hide an existing modal floater (e.g. LLFloaterJoin) behind this one + : LLModalDialog(key, /*modal=*/true, /*hide_others=*/false) +{ +} + +bool LLFloaterWebModal::postBuild() +{ + mWebBrowser = getChild("web_modal_browser"); + mWebBrowser->addObserver(this); + return true; +} + +void LLFloaterWebModal::onOpen(const LLSD& key) +{ + LLModalDialog::onOpen(key); + + if (mWebBrowser && key.has("url")) + { + mWebBrowser->navigateTo(key["url"].asString(), HTTP_CONTENT_TEXT_HTML); + } +} + +void LLFloaterWebModal::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event) +{ + if (event == MEDIA_EVENT_NAME_CHANGED) + { + const std::string page_title = self->getMediaName(); + setTitle(page_title.empty() ? self->getLocation() : page_title); + } +} diff --git a/indra/newview/llfloaterwebmodal.h b/indra/newview/llfloaterwebmodal.h new file mode 100644 index 0000000000..fc10be3535 --- /dev/null +++ b/indra/newview/llfloaterwebmodal.h @@ -0,0 +1,48 @@ +/** + * @file llfloaterwebmodal.h + * @brief Modal floater for displaying a web page above other modal floaters + * + * $LicenseInfo:firstyear=2026&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2026, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#pragma once + +#include "llmodaldialog.h" +#include "llviewermediaobserver.h" + +class LLMediaCtrl; + +class LLFloaterWebModal : public LLModalDialog, public LLViewerMediaObserver +{ + friend class LLFloaterReg; +public: + bool postBuild() override; + void onOpen(const LLSD& key) override; + + void handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event) override; + +private: + LLFloaterWebModal(const LLSD& key); + ~LLFloaterWebModal() = default; + + LLMediaCtrl* mWebBrowser = nullptr; +}; diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp index f49b1ccbde..7d3b554709 100644 --- a/indra/newview/llviewerfloaterreg.cpp +++ b/indra/newview/llviewerfloaterreg.cpp @@ -155,6 +155,7 @@ #include "llfloatertranslationsettings.h" #include "llfloateruipreview.h" #include "llfloaterwebcontent.h" +#include "llfloaterwebmodal.h" #include "llfloatervoicevolume.h" #include "llfloaterwhitelistentry.h" #include "llfloaterwindowsize.h" @@ -521,6 +522,7 @@ void LLViewerFloaterReg::registerFloaters() LLFloaterReg::add("upload_sound", "floater_sound_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build, "upload"); LLFloaterReg::add("web_content", "floater_web_content.xml", (LLFloaterBuildFunc)&LLFloaterWebContent::create); + LLFloaterReg::add("web_modal", "floater_web_modal.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); LLFloaterReg::add("whitelist_entry", "floater_whitelist_entry.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); LLFloaterReg::add("window_size", "floater_window_size.xml", &LLFloaterReg::build); LLFloaterReg::add("world_map", "floater_world_map.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); diff --git a/indra/newview/skins/default/xui/en/floater_join.xml b/indra/newview/skins/default/xui/en/floater_join.xml index 28c879f36e..4b9d3a64bd 100644 --- a/indra/newview/skins/default/xui/en/floater_join.xml +++ b/indra/newview/skins/default/xui/en/floater_join.xml @@ -12,7 +12,9 @@ can_resize="false" can_drag_on_left="false" can_minimize="false" - can_close="false"> + can_close="false" + positioning="centered" + save_rect="false"> + secondlife:///app/floaterjoin/close - secondlife:///app/floaterjoin/join/testuser/testpassword + + secondlife:///app/floaterjoin/tos + + + secondlife:///app/floaterjoin/tc + diff --git a/indra/newview/skins/default/xui/en/floater_web_modal.xml b/indra/newview/skins/default/xui/en/floater_web_modal.xml new file mode 100644 index 0000000000..428522a403 --- /dev/null +++ b/indra/newview/skins/default/xui/en/floater_web_modal.xml @@ -0,0 +1,23 @@ + + + + -- cgit v1.3 From 7f3c72b84d2699b1ba8b0fcb5b1d38398bb9d0a8 Mon Sep 17 00:00:00 2001 From: Mnikolenko Productengine Date: Wed, 30 Sep 2026 17:57:35 +0300 Subject: Fix modal floater re-centering against a different rect, which caused visual jump --- indra/llui/llmodaldialog.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/indra/llui/llmodaldialog.cpp b/indra/llui/llmodaldialog.cpp index 73f3914160..0db9c20b20 100644 --- a/indra/llui/llmodaldialog.cpp +++ b/indra/llui/llmodaldialog.cpp @@ -29,6 +29,7 @@ #include "llmodaldialog.h" #include "llemojihelper.h" +#include "llfloater.h" #include "llfocusmgr.h" #include "v4color.h" #include "v2math.h" @@ -306,8 +307,10 @@ void LLModalDialog::draw() void LLModalDialog::centerOnScreen() { - LLVector2 window_size = LLUI::getInstance()->getWindowSize(); - centerWithin(LLRect(0, 0, ll_round(window_size.mV[VX]), ll_round(window_size.mV[VY]))); + // Use the floater view's rect (same as LLFloater::center()) rather than the raw + // window size, otherwise a reshape after the initial centering (e.g. triggered by embedded + // media content settling) re-centers the dialog against a different rect. + centerWithin(gFloaterView->getRect()); } // static -- cgit v1.3 From 4e5b6eab4ff073122a179ceafdaffcd6652763b6 Mon Sep 17 00:00:00 2001 From: Mnikolenko Productengine Date: Thu, 1 Oct 2026 18:30:56 +0300 Subject: Show scrollbar in Join floater when the viewer window is too small --- indra/newview/llfloaterjoin.cpp | 18 +++ indra/newview/llfloaterjoin.h | 3 + .../newview/skins/default/xui/en/floater_join.xml | 138 ++++++++++++--------- 3 files changed, 101 insertions(+), 58 deletions(-) diff --git a/indra/newview/llfloaterjoin.cpp b/indra/newview/llfloaterjoin.cpp index a37fd60cb1..4fab555753 100644 --- a/indra/newview/llfloaterjoin.cpp +++ b/indra/newview/llfloaterjoin.cpp @@ -85,13 +85,31 @@ LLFloaterJoin::LLFloaterJoin(const LLSD& key) bool LLFloaterJoin::postBuild() { mWebBrowser = getChild("join_browser"); + mNativeRect = getRect(); return true; } +void LLFloaterJoin::updateFloaterSize() +{ + const LLRect& screen_rect = gFloaterView->getRect(); + S32 width = llmin(mNativeRect.getWidth(), screen_rect.getWidth()); + S32 height = llmin(mNativeRect.getHeight(), screen_rect.getHeight()); + + // Shrink the floater to fit the screen, letting scroll container reveal the rest if + // the screen is currently smaller than the floater's native size, else restore it + if (width != getRect().getWidth() || height != getRect().getHeight()) + { + reshape(width, height); + center(); + } +} + void LLFloaterJoin::draw() { static LLCachedControl overlay_opacity(gSavedSettings, "JoinFloaterOverlayOpacity"); + updateFloaterSize(); + // As a modal dialog this floater is drawn twice per frame (once by LLFloaterView and once // by LLPopupView), so paint the overlay only on the first pass of each frame U32 frame_count = LLFrameTimer::getFrameCount(); diff --git a/indra/newview/llfloaterjoin.h b/indra/newview/llfloaterjoin.h index 8b69292f9d..5922a45e85 100644 --- a/indra/newview/llfloaterjoin.h +++ b/indra/newview/llfloaterjoin.h @@ -42,7 +42,10 @@ private: LLFloaterJoin(const LLSD& key); ~LLFloaterJoin() = default; + void updateFloaterSize(); + LLMediaCtrl* mWebBrowser = nullptr; U32 mOverlayFrame = 0; + LLRect mNativeRect; }; diff --git a/indra/newview/skins/default/xui/en/floater_join.xml b/indra/newview/skins/default/xui/en/floater_join.xml index 4b9d3a64bd..a3a6ea216a 100644 --- a/indra/newview/skins/default/xui/en/floater_join.xml +++ b/indra/newview/skins/default/xui/en/floater_join.xml @@ -15,15 +15,91 @@ can_close="false" positioning="centered" save_rect="false"> - + + name="join_scroll" + opaque="false" + border_visible="false" + mouse_opaque="false"> + + + + + + secondlife:///app/floaterjoin/close + + + secondlife:///app/floaterjoin/join/testuser/testpassword + + + secondlife:///app/floaterjoin/tos + + + secondlife:///app/floaterjoin/tc + + + - - - - secondlife:///app/floaterjoin/close - - - secondlife:///app/floaterjoin/join/testuser/testpassword - - - secondlife:///app/floaterjoin/tos - - - secondlife:///app/floaterjoin/tc - -- cgit v1.3 From 27c7dbf1edf41aaa0a953b501a92906cd355a58d Mon Sep 17 00:00:00 2001 From: Mnikolenko Productengine Date: Fri, 2 Oct 2026 19:24:54 +0300 Subject: Show Privacy page in a separate floater similar to ToS --- indra/newview/app_settings/settings.xml | 13 ++++++++++++- indra/newview/llfloaterjoin.cpp | 5 +++++ indra/newview/skins/default/xui/en/floater_join.xml | 13 +++++++++++++ 3 files changed, 30 insertions(+), 1 deletion(-) diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 99035e029d..b03779dc2f 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -3833,7 +3833,7 @@ TermsOfServiceURL Comment - >URL pointing to Terms of Service page + URL pointing to Terms of Service page Persist 1 Type @@ -3841,6 +3841,17 @@ Value https://lindenlab.com/tos + PrivacyPolicyURL + + Comment + URL pointing to Privacy Policy page + Persist + 1 + Type + String + Value + https://lindenlab.com/privacy + JoinFloaterTestSLapp Comment diff --git a/indra/newview/llfloaterjoin.cpp b/indra/newview/llfloaterjoin.cpp index 4fab555753..73fb8040c2 100644 --- a/indra/newview/llfloaterjoin.cpp +++ b/indra/newview/llfloaterjoin.cpp @@ -65,6 +65,10 @@ public: { LLFloaterReg::showInstance("web_modal", LLSD().with("url", gSavedSettings.getString("TermsAndConditionsURL"))); } + else if (action == "privacy") + { + LLFloaterReg::showInstance("web_modal", LLSD().with("url", gSavedSettings.getString("PrivacyPolicyURL"))); + } else if (action == "join" && params.size() >= 3) { LLPanelLogin::setCredentialFields(LLURI::unescape(params[1].asString()), @@ -149,4 +153,5 @@ void LLFloaterJoin::onOpen(const LLSD& key) getChild("test_join_link")->setVisible(show_test_slapp); getChild("test_tos_link")->setVisible(show_test_slapp); getChild("test_tc_link")->setVisible(show_test_slapp); + getChild("test_privacy_link")->setVisible(show_test_slapp); } diff --git a/indra/newview/skins/default/xui/en/floater_join.xml b/indra/newview/skins/default/xui/en/floater_join.xml index a3a6ea216a..8e29551447 100644 --- a/indra/newview/skins/default/xui/en/floater_join.xml +++ b/indra/newview/skins/default/xui/en/floater_join.xml @@ -98,6 +98,19 @@ height="16"> secondlife:///app/floaterjoin/tc + + secondlife:///app/floaterjoin/privacy + Date: Wed, 7 Oct 2026 15:59:24 +0300 Subject: Remove SLapp test elements --- indra/newview/app_settings/settings.xml | 11 ---- indra/newview/llfloaterjoin.cpp | 7 --- .../newview/skins/default/xui/en/floater_join.xml | 67 ---------------------- 3 files changed, 85 deletions(-) diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index b03779dc2f..9a9ca441f0 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -3852,17 +3852,6 @@ Value https://lindenlab.com/privacy - JoinFloaterTestSLapp - - Comment - For testing only: Show links in the Join floater that trigger its close/join SLapps. - Persist - 1 - Type - Boolean - Value - 0 - JoinURL Comment diff --git a/indra/newview/llfloaterjoin.cpp b/indra/newview/llfloaterjoin.cpp index 73fb8040c2..e82de2474f 100644 --- a/indra/newview/llfloaterjoin.cpp +++ b/indra/newview/llfloaterjoin.cpp @@ -147,11 +147,4 @@ void LLFloaterJoin::onOpen(const LLSD& key) { mWebBrowser->navigateTo(url, HTTP_CONTENT_TEXT_HTML); } - - static LLCachedControl show_test_slapp(gSavedSettings, "JoinFloaterTestSLapp"); - getChild("test_close_link")->setVisible(show_test_slapp); - getChild("test_join_link")->setVisible(show_test_slapp); - getChild("test_tos_link")->setVisible(show_test_slapp); - getChild("test_tc_link")->setVisible(show_test_slapp); - getChild("test_privacy_link")->setVisible(show_test_slapp); } diff --git a/indra/newview/skins/default/xui/en/floater_join.xml b/indra/newview/skins/default/xui/en/floater_join.xml index 8e29551447..fac0293097 100644 --- a/indra/newview/skins/default/xui/en/floater_join.xml +++ b/indra/newview/skins/default/xui/en/floater_join.xml @@ -44,73 +44,6 @@ name="join_browser" trusted_content="false" border_visible="false" /> - - - - secondlife:///app/floaterjoin/close - - - secondlife:///app/floaterjoin/join/testuser/testpassword - - - secondlife:///app/floaterjoin/tos - - - secondlife:///app/floaterjoin/tc - - - secondlife:///app/floaterjoin/privacy - Date: Wed, 7 Oct 2026 19:49:02 +0300 Subject: #6412 Update viewer version to 26.5 --- indra/newview/VIEWER_VERSION.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt index bb6eac98a9..3eb1386fcc 100644 --- a/indra/newview/VIEWER_VERSION.txt +++ b/indra/newview/VIEWER_VERSION.txt @@ -1 +1 @@ -26.4.0 +26.5.0 -- cgit v1.3 From 4fd91009c30dd0479568013c94ab424c23721485 Mon Sep 17 00:00:00 2001 From: Hecklezz Date: Wed, 7 Oct 2026 20:50:37 +1000 Subject: Fix crash in LLFile when paths contain unicode --- indra/llcommon/llfile.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/indra/llcommon/llfile.cpp b/indra/llcommon/llfile.cpp index 114df29f6e..a33fcdc9c4 100644 --- a/indra/llcommon/llfile.cpp +++ b/indra/llcommon/llfile.cpp @@ -188,7 +188,7 @@ std::string strerr(int errn) #if LL_WINDOWS && 0 // turn on to debug file-locking problems #define PROCESS_LOCKING_CHECK 1 -static void find_locking_process(const std::string& filename) +static void find_locking_process(const std::filesystem::path& filename) { // Only do any of this stuff (before LL_ENDL) if it will be logged. LL_DEBUGS("LLFile") << ""; @@ -200,14 +200,14 @@ static void find_locking_process(const std::string& filename) } else { - std::string tf(TEMP); - tf += "handle.tmp"; + std::filesystem::path tf = fsyspath(TEMP) / "handle.tmp"; + std::string utf8name = fsyspath(filename).string(); // http://technet.microsoft.com/en-us/sysinternals/bb896655 - std::string cmd(STRINGIZE("handle \"" << filename - // "openfiles /query /v | fgrep -i \"" << filename - << "\" > \"" << tf << '"')); + std::string cmd(STRINGIZE("handle \"" << utf8name + // "openfiles /query /v | fgrep -i \"" << utf8name + << "\" > \"" << fsyspath(tf).string() << '"')); LL_CONT << cmd; - if (system(cmd.c_str()) != 0) + if (_wsystem(ll_convert(cmd).c_str()) != 0) { LL_CONT << "\nDownload 'handle.exe' from http://technet.microsoft.com/en-us/sysinternals/bb896655"; } @@ -238,7 +238,7 @@ static int warnif(std::string_view desc, const std::filesystem::path& filename, // EEXIST. Don't log a warning if caller explicitly says this errno is okay. if (errn != suppress_warning) { - LL_WARNS("LLFile") << "Couldn't " << desc << " '" << filename << "' (errno " << errn << "): " << strerr(errn) << LL_ENDL; + LL_WARNS("LLFile") << "Couldn't " << desc << " '" << fsyspath(filename).string() << "' (errno " << errn << "): " << strerr(errn) << LL_ENDL; } #if PROCESS_LOCKING_CHECK // If the problem is "Permission denied," maybe it's because another @@ -267,7 +267,7 @@ static int warnif(std::string_view desc, const std::filesystem::path& filename, // Don't warn if caller explicitly says this errno is okay. if (errn != suppress_warning) { - LL_WARNS("LLFile") << "Couldn't " << desc << " '" << filename << "' (errno " << errn << "): " << ec.message() << LL_ENDL; + LL_WARNS("LLFile") << "Couldn't " << desc << " '" << fsyspath(filename).string() << "' (errno " << errn << "): " << ec.message() << LL_ENDL; } #if PROCESS_LOCKING_CHECK // Try to detect locked files by other processes @@ -988,7 +988,7 @@ bool LLFile::copy(const std::filesystem::path& source_path, const std::filesyste bool copied = std::filesystem::copy_file(source_path, target_path, options, ec); if (!copied) { - warnif(STRINGIZE("copy failed, to '" << target_path << "' from"), source_path, ec); + warnif(STRINGIZE("copy failed, to '" << fsyspath(target_path).string() << "' from"), source_path, ec); } return copied; } -- cgit v1.3