summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
Diffstat (limited to 'indra')
-rw-r--r--indra/cmake/00-Common.cmake3
-rw-r--r--indra/cmake/CEFPlugin.cmake178
-rw-r--r--indra/cmake/CURL.cmake16
-rw-r--r--indra/cmake/LLPrimitive.cmake32
-rw-r--r--indra/cmake/UnixInstall.cmake4
-rw-r--r--indra/llwebrtc/CMakeLists.txt6
-rw-r--r--indra/media_plugins/cef/CMakeLists.txt57
-rw-r--r--indra/media_plugins/cef/media_plugin_cef.cpp16
-rw-r--r--indra/media_plugins/libvlc/CMakeLists.txt6
-rw-r--r--indra/newview/CMakeLists.txt6
-rw-r--r--indra/newview/PKGBUILD.in2
-rw-r--r--indra/newview/ViewerInstall.cmake4
-rw-r--r--indra/newview/app_settings/commands.xml11
-rw-r--r--indra/newview/app_settings/settings.xml28
-rw-r--r--indra/newview/llavatarpropertiesprocessor.cpp26
-rw-r--r--indra/newview/llavatarpropertiesprocessor.h25
-rw-r--r--indra/newview/llgroupcolormap.cpp150
-rw-r--r--indra/newview/llgroupcolormap.h64
-rw-r--r--indra/newview/llnetmap.cpp35
-rw-r--r--indra/newview/llpanelgroupgeneral.cpp76
-rw-r--r--indra/newview/llpanelgroupgeneral.h8
-rw-r--r--indra/newview/llquickprefs.cpp205
-rw-r--r--indra/newview/llquickprefs.h81
-rw-r--r--indra/newview/llstartup.cpp4
-rw-r--r--indra/newview/lltoolcomp.cpp55
-rw-r--r--indra/newview/lltoolcomp.h2
-rw-r--r--indra/newview/llviewerdisplay.cpp18
-rw-r--r--indra/newview/llviewerfloaterreg.cpp2
-rw-r--r--indra/newview/llviewermenu.cpp21
-rw-r--r--indra/newview/llvoavatar.cpp99
-rw-r--r--indra/newview/llvoavatar.h11
-rw-r--r--indra/newview/skins/default/xui/en/floater_quick_prefs.xml85
-rw-r--r--indra/newview/skins/default/xui/en/menu_viewer.xml8
-rw-r--r--indra/newview/skins/default/xui/en/panel_group_general.xml51
-rw-r--r--indra/newview/skins/default/xui/en/strings.xml2
35 files changed, 1288 insertions, 109 deletions
diff --git a/indra/cmake/00-Common.cmake b/indra/cmake/00-Common.cmake
index 42e211c84d..d02e6b123b 100644
--- a/indra/cmake/00-Common.cmake
+++ b/indra/cmake/00-Common.cmake
@@ -16,6 +16,7 @@ include_guard()
include(Variables)
include(Linker)
+include(UnixInstall)
# We go to some trouble to set LL_BUILD to the set of relevant compiler flags.
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} $ENV{LL_BUILD}")
@@ -127,7 +128,7 @@ endif (NOT CMAKE_CXX_COMPILER_ID MATCHES GNU AND WINDOWS)
if (LINUX OR CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
set( CMAKE_BUILD_WITH_INSTALL_RPATH TRUE )
- set( CMAKE_INSTALL_RPATH $ORIGIN $ORIGIN/../lib )
+ set( CMAKE_INSTALL_RPATH ${INSTALL_LIBRARY_DIR} )
set(CMAKE_EXE_LINKER_FLAGS "-Wl,--exclude-libs,ALL")
find_program(CCACHE_EXE ccache)
diff --git a/indra/cmake/CEFPlugin.cmake b/indra/cmake/CEFPlugin.cmake
index 31ed86213a..117c83353e 100644
--- a/indra/cmake/CEFPlugin.cmake
+++ b/indra/cmake/CEFPlugin.cmake
@@ -1,54 +1,187 @@
# -*- cmake -*-
include(Linking)
include(Prebuilt)
+include(UnixInstall)
include_guard()
add_library( ll::cef INTERFACE IMPORTED )
-if (CMAKE_SYSTEM_PROCESSOR MATCHES aarch64)
+if (${LINUX_DISTRO} MATCHES arch)
if (${PREBUILD_TRACKING_DIR}/sentinel_installed IS_NEWER_THAN ${PREBUILD_TRACKING_DIR}/dullahan_installed OR NOT ${dullahan_installed} EQUAL 0)
- if (NOT EXISTS ${CMAKE_BINARY_DIR}/v1.14.0-r3.tar.gz)
+ file(
+ COPY /usr/src/cef/libcef_dll
+ DESTINATION ${CMAKE_BINARY_DIR}
+ )
+ execute_process(
+ COMMAND sed -i "s/macro(L/cmake_minimum_required(VERSION 3.28)\\nmacro(SET_LIBRARY_TARGET_PROPERTIES)\\nendmacro()\\nmacro(L/" CMakeLists.txt
+ WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/libcef_dll
+ )
+ try_compile(LIBCEF_DLL_RESULT
+ PROJECT libcef_dll
+ SOURCE_DIR ${CMAKE_BINARY_DIR}/libcef_dll
+ BINARY_DIR ${CMAKE_BINARY_DIR}/libcef_dll
+ CMAKE_FLAGS
+ -DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE}
+ "-DCMAKE_CXX_FLAGS:STRING=-I/usr/include/cef -I/usr/src/cef -fPIC"
+ )
+ if (${LIBCEF_DLL_RESULT})
+ file(
+ COPY ${CMAKE_BINARY_DIR}/libcef_dll/libcef_dll_wrapper.a
+ DESTINATION ${ARCH_PREBUILT_DIRS_RELEASE}
+ )
+ endif ()
+ if (NOT EXISTS ${CMAKE_BINARY_DIR}/dullahan-1.30.0-CEF_147.0.10.tar.gz)
file(DOWNLOAD
- https://github.com/secondlife/dullahan/archive/refs/tags/v1.14.0-r3.tar.gz
- ${CMAKE_BINARY_DIR}/v1.14.0-r3.tar.gz
+ https://github.com/secondlife/dullahan/archive/refs/tags/v1.30.0-CEF_147.0.10.tar.gz
+ ${CMAKE_BINARY_DIR}/dullahan-1.30.0-CEF_147.0.10.tar.gz
+ )
+ endif ()
+ file(ARCHIVE_EXTRACT
+ INPUT ${CMAKE_BINARY_DIR}/dullahan-1.30.0-CEF_147.0.10.tar.gz
+ DESTINATION ${CMAKE_BINARY_DIR}
+ )
+ try_compile(DULLAHAN_RESULT
+ PROJECT dullahan
+ SOURCE_DIR ${CMAKE_BINARY_DIR}/dullahan-1.30.0-CEF_147.0.10
+ BINARY_DIR ${CMAKE_BINARY_DIR}/dullahan-1.30.0-CEF_147.0.10
+ CMAKE_FLAGS
+ -DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE}
+ -DCMAKE_INSTALL_PREFIX:PATH=${LIBS_PREBUILT_DIR}
+ -DCMAKE_INSTALL_LIBDIR:PATH=${ARCH_PREBUILT_DIRS_RELEASE}
+ -DCEF_WRAPPER_DIR:PATH=/usr/include/cef
+ -DCEF_WRAPPER_BUILD_DIR:PATH=${CMAKE_BINARY_DIR}/dullahan-1.30.0-CEF_147.0.10
+ -DCEF_LIBRARY_RELEASE:FILEPATH=${INSTALL_PREFIX}/${_LIB}/cef/libcef.so
+ -DCEF_DLL_LIBRARY_RELEASE:FILEPATH=${ARCH_PREBUILT_DIRS_RELEASE}/libcef_dll_wrapper.a
+ "-DCMAKE_CXX_FLAGS:STRING=-I/usr/include/cef -I/usr/src/cef -DWRAPPING_CEF_SHARED"
+ )
+ if (${DULLAHAN_RESULT})
+ file(MAKE_DIRECTORY ${LIBS_PREBUILT_DIR}/bin/release)
+ file(
+ COPY ${CMAKE_BINARY_DIR}/dullahan-1.30.0-CEF_147.0.10/dullahan_host
+ DESTINATION ${LIBS_PREBUILT_DIR}/bin/release
+ )
+ file(
+ COPY ${CMAKE_BINARY_DIR}/dullahan-1.30.0-CEF_147.0.10/libdullahan.a
+ DESTINATION ${ARCH_PREBUILT_DIRS_RELEASE}
+ )
+ file(MAKE_DIRECTORY ${LIBS_PREBUILT_DIR}/include/cef)
+ file(
+ COPY
+ ${CMAKE_BINARY_DIR}/dullahan-1.30.0-CEF_147.0.10/src/dullahan.h
+ ${CMAKE_BINARY_DIR}/dullahan-1.30.0-CEF_147.0.10/src/dullahan_version.h
+ DESTINATION ${LIBS_PREBUILT_DIR}/include/cef
+ )
+ file(WRITE ${PREBUILD_TRACKING_DIR}/dullahan_installed "0")
+ endif ()
+ endif ()
+elseif (${LINUX_DISTRO} MATCHES fedora)
+ if (${PREBUILD_TRACKING_DIR}/sentinel_installed IS_NEWER_THAN ${PREBUILD_TRACKING_DIR}/dullahan_installed OR NOT ${dullahan_installed} EQUAL 0)
+ file(
+ COPY /usr/src/cef-146.0.11/libcef_dll
+ DESTINATION ${CMAKE_BINARY_DIR}
+ )
+ execute_process(
+ COMMAND sed -i "s/macro(L/cmake_minimum_required(VERSION 3.28)\\nmacro(SET_LIBRARY_TARGET_PROPERTIES)\\nendmacro()\\nmacro(L/" CMakeLists.txt
+ WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/libcef_dll
+ )
+ try_compile(LIBCEF_DLL_RESULT
+ PROJECT libcef_dll
+ SOURCE_DIR ${CMAKE_BINARY_DIR}/libcef_dll
+ BINARY_DIR ${CMAKE_BINARY_DIR}/libcef_dll
+ CMAKE_FLAGS
+ -DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE}
+ "-DCMAKE_CXX_FLAGS:STRING=-I/usr/include/cef -I/usr/src/cef-146.0.11 -fPIC"
+ )
+ if (${LIBCEF_DLL_RESULT})
+ file(
+ COPY ${CMAKE_BINARY_DIR}/libcef_dll/libcef_dll_wrapper.a
+ DESTINATION ${ARCH_PREBUILT_DIRS_RELEASE}
+ )
+ endif ()
+ if (NOT EXISTS ${CMAKE_BINARY_DIR}/dullahan-1.29.0-CEF_146.0.12.tar.gz)
+ file(DOWNLOAD
+ https://github.com/secondlife/dullahan/archive/refs/tags/v1.29.0-CEF_146.0.12.tar.gz
+ ${CMAKE_BINARY_DIR}/dullahan-1.29.0-CEF_146.0.12.tar.gz
+ )
+ endif ()
+ file(ARCHIVE_EXTRACT
+ INPUT ${CMAKE_BINARY_DIR}/dullahan-1.29.0-CEF_146.0.12.tar.gz
+ DESTINATION ${CMAKE_BINARY_DIR}
+ )
+ try_compile(DULLAHAN_RESULT
+ PROJECT dullahan
+ SOURCE_DIR ${CMAKE_BINARY_DIR}/dullahan-1.29.0-CEF_146.0.12
+ BINARY_DIR ${CMAKE_BINARY_DIR}/dullahan-1.29.0-CEF_146.0.12
+ CMAKE_FLAGS
+ -DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE}
+ -DCMAKE_INSTALL_PREFIX:PATH=${LIBS_PREBUILT_DIR}
+ -DCMAKE_INSTALL_LIBDIR:PATH=${ARCH_PREBUILT_DIRS_RELEASE}
+ -DCEF_WRAPPER_DIR:PATH=/usr/include/cef
+ -DCEF_WRAPPER_BUILD_DIR:PATH=${CMAKE_BINARY_DIR}/dullahan-1.29.0-CEF_146.0.12
+ -DCEF_LIBRARY_RELEASE:FILEPATH=${INSTALL_PREFIX}/${_LIB}/cef/libcef.so
+ -DCEF_DLL_LIBRARY_RELEASE:FILEPATH=${ARCH_PREBUILT_DIRS_RELEASE}/libcef_dll_wrapper.a
+ "-DCMAKE_CXX_FLAGS:STRING=-I/usr/include/cef -I/usr/src/cef-146.0.11 -DWRAPPING_CEF_SHARED"
+ )
+ if (${DULLAHAN_RESULT})
+ file(MAKE_DIRECTORY ${LIBS_PREBUILT_DIR}/bin/release)
+ file(
+ COPY ${CMAKE_BINARY_DIR}/dullahan-1.29.0-CEF_146.0.12/dullahan_host
+ DESTINATION ${LIBS_PREBUILT_DIR}/bin/release
+ )
+ file(
+ COPY ${CMAKE_BINARY_DIR}/dullahan-1.29.0-CEF_146.0.12/libdullahan.a
+ DESTINATION ${ARCH_PREBUILT_DIRS_RELEASE}
+ )
+ file(MAKE_DIRECTORY ${LIBS_PREBUILT_DIR}/include/cef)
+ file(
+ COPY
+ ${CMAKE_BINARY_DIR}/dullahan-1.29.0-CEF_146.0.12/src/dullahan.h
+ ${CMAKE_BINARY_DIR}/dullahan-1.29.0-CEF_146.0.12/src/dullahan_version.h
+ DESTINATION ${LIBS_PREBUILT_DIR}/include/cef
+ )
+ file(WRITE ${PREBUILD_TRACKING_DIR}/dullahan_installed "0")
+ endif ()
+ endif ()
+elseif (CMAKE_SYSTEM_PROCESSOR MATCHES aarch64)
+ if (${PREBUILD_TRACKING_DIR}/sentinel_installed IS_NEWER_THAN ${PREBUILD_TRACKING_DIR}/dullahan_installed OR NOT ${dullahan_installed} EQUAL 0)
+ if (NOT EXISTS ${CMAKE_BINARY_DIR}/dullahan-1.24.0-CEF_139.0.40.tar.gz)
+ file(DOWNLOAD
+ https://github.com/secondlife/dullahan/archive/refs/tags/v1.24.0-CEF_139.0.40.tar.gz
+ ${CMAKE_BINARY_DIR}/dullahan-1.24.0-CEF_139.0.40.tar.gz
)
endif ()
file(ARCHIVE_EXTRACT
- INPUT ${CMAKE_BINARY_DIR}/v1.14.0-r3.tar.gz
+ INPUT ${CMAKE_BINARY_DIR}/dullahan-1.24.0-CEF_139.0.40.tar.gz
DESTINATION ${CMAKE_BINARY_DIR}
)
execute_process(
COMMAND sed -i "/#include <vector>/a #include <cstdint>" dullahan.h
- WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/dullahan-1.14.0-r3/src
+ WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/dullahan-1.24.0-CEF_139.0.40/src
)
file(MAKE_DIRECTORY ${LIBS_PREBUILT_DIR}/include/cef)
try_compile(DULLAHAN_RESULT
PROJECT dullahan
- SOURCE_DIR ${CMAKE_BINARY_DIR}/dullahan-1.14.0-r3
- BINARY_DIR ${CMAKE_BINARY_DIR}/dullahan-1.14.0-r3
+ SOURCE_DIR ${CMAKE_BINARY_DIR}/dullahan-1.24.0-CEF_139.0.40
+ BINARY_DIR ${CMAKE_BINARY_DIR}/dullahan-1.24.0-CEF_139.0.40
CMAKE_FLAGS
-DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE}
- -DCMAKE_OSX_ARCHITECTURES:STRING=${CMAKE_OSX_ARCHITECTURES}
- -DCMAKE_OSX_DEPLOYMENT_TARGET:STRING=${CMAKE_OSX_DEPLOYMENT_TARGET}
-DCMAKE_INSTALL_PREFIX:PATH=${LIBS_PREBUILT_DIR}
-DCMAKE_INSTALL_LIBDIR:PATH=${ARCH_PREBUILT_DIRS_RELEASE}
-DCMAKE_BUILD_WITH_INSTALL_RPATH:BOOL=ON
- -DBUILD_SHARED_LIBS:BOOL=${BUILD_SHARED_LIBS}
-DUSE_SPOTIFY_CEF:BOOL=ON
- -DSPOTIFY_CEF_URL:STRING=https://cef-builds.spotifycdn.com/cef_binary_118.4.1%2Bg3dd6078%2Bchromium-118.0.5993.54_linuxarm64_beta_minimal.tar.bz2
+ -DSPOTIFY_CEF_URL:STRING=https://cef-builds.spotifycdn.com/cef_binary_139.0.40%2Bg465474a%2Bchromium-139.0.7258.139_linuxarm64_minimal.tar.bz2
-DPROJECT_ARCH:STRING=${CMAKE_SYSTEM_PROCESSOR}
- -DENABLE_CXX11_ABI:BOOL=ON
)
if (${DULLAHAN_RESULT})
execute_process(
COMMAND ${CMAKE_MAKE_PROGRAM} install
- WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/dullahan-1.14.0-r3
+ WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/dullahan-1.24.0-CEF_139.0.40
OUTPUT_VARIABLE dullahan_installed
)
file(
COPY
- ${CMAKE_BINARY_DIR}/dullahan-1.14.0-r3/src/dullahan.h
- ${CMAKE_BINARY_DIR}/dullahan-1.14.0-r3/src/dullahan_version.h
+ ${CMAKE_BINARY_DIR}/dullahan-1.24.0-CEF_139.0.40/src/dullahan.h
+ ${CMAKE_BINARY_DIR}/dullahan-1.24.0-CEF_139.0.40/src/dullahan_version.h
DESTINATION ${LIBS_PREBUILT_DIR}/include/cef
)
file(WRITE ${PREBUILD_TRACKING_DIR}/dullahan_installed "${dullahan_installed}")
@@ -59,9 +192,17 @@ use_prebuilt_binary(dullahan)
endif ()
execute_process(
- COMMAND patchelf --remove-rpath bin/release/dullahan_host
+ COMMAND patchelf --set-rpath ${INSTALL_LIBRARY_DIR} bin/release/dullahan_host
WORKING_DIRECTORY ${LIBS_PREBUILT_DIR}
+)
+
+if (${LINUX_DISTRO} MATCHES arch OR (${LINUX_DISTRO} MATCHES fedora))
+ target_include_directories( ll::cef SYSTEM INTERFACE /usr/include/cef/include)
+ execute_process(
+ COMMAND patchelf --add-rpath ${INSTALL_PREFIX}/${_LIB}/cef bin/release/dullahan_host
+ WORKING_DIRECTORY ${LIBS_PREBUILT_DIR}
)
+endif ()
target_include_directories( ll::cef SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include/cef)
@@ -129,6 +270,9 @@ elseif (DARWIN)
)
elseif (LINUX)
+ if (${LINUX_DISTRO} MATCHES arch OR (${LINUX_DISTRO} MATCHES fedora))
+ target_link_directories( ll::cef INTERFACE ${INSTALL_PREFIX}/${_LIB}/cef )
+ endif ()
target_link_libraries( ll::cef INTERFACE
libdullahan.a
cef
diff --git a/indra/cmake/CURL.cmake b/indra/cmake/CURL.cmake
index 99045e3aa3..09fc43dff4 100644
--- a/indra/cmake/CURL.cmake
+++ b/indra/cmake/CURL.cmake
@@ -27,20 +27,20 @@ use_prebuilt_binary(curl)
endif ()
endif ()
elseif (${PREBUILD_TRACKING_DIR}/sentinel_installed IS_NEWER_THAN ${PREBUILD_TRACKING_DIR}/curl_installed OR NOT ${curl_installed} EQUAL 0)
- if (NOT EXISTS ${CMAKE_BINARY_DIR}/3p-curl-7.54.1-r3.tar.gz)
+ if (NOT EXISTS ${CMAKE_BINARY_DIR}/3p-curl-7.54.1-r4.tar.gz)
file(DOWNLOAD
- https://github.com/secondlife/3p-curl/archive/refs/tags/v7.54.1-r3.tar.gz
- ${CMAKE_BINARY_DIR}/3p-curl-7.54.1-r3.tar.gz
+ https://github.com/secondlife/3p-curl/archive/refs/tags/v7.54.1-r4.tar.gz
+ ${CMAKE_BINARY_DIR}/3p-curl-7.54.1-r4.tar.gz
)
endif ()
file(ARCHIVE_EXTRACT
- INPUT ${CMAKE_BINARY_DIR}/3p-curl-7.54.1-r3.tar.gz
+ INPUT ${CMAKE_BINARY_DIR}/3p-curl-7.54.1-r4.tar.gz
DESTINATION ${CMAKE_BINARY_DIR}
)
if (CMAKE_SYSTEM_PROCESSOR MATCHES aarch64)
execute_process(
COMMAND sed -i netrc.c -e "s/defined(HAVE_GETPWUID_R)/0/g" netrc.c
- WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/3p-curl-7.54.1-r3/curl/lib
+ WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/3p-curl-7.54.1-r4/curl/lib
)
endif ()
file(
@@ -60,16 +60,16 @@ elseif (${PREBUILD_TRACKING_DIR}/sentinel_installed IS_NEWER_THAN ${PREBUILD_TRA
set(ENV{CFLAGS} "-std=c90")
execute_process(
COMMAND ./configure --disable-alt-svc --disable-dict --disable-doh --disable-file --disable-gopher --disable-headers-api --disable-hsts --disable-imap --disable-ldap --disable-ldaps --disable-libcurl-option --disable-manual --disable-mqtt --disable-ntlm --disable-ntlm-wb --disable-pop3 --disable-rtsp --disable-shared --disable-smb --disable-smtp --disable-sspi --disable-telnet --disable-tftp --disable-tls-srp --disable-unix-sockets --disable-verbose --disable-versioned-symbols --enable-threaded-resolver --with-ssl=${LIBS_PREBUILT_DIR} --without-libidn2 --without-libpsl --without-libssh2 --prefix=${LIBS_PREBUILT_DIR} --libdir=${ARCH_PREBUILT_DIRS_RELEASE}
- WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/3p-curl-7.54.1-r3/curl
+ WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/3p-curl-7.54.1-r4/curl
)
execute_process(
COMMAND make -j${MAKE_JOBS}
- WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/3p-curl-7.54.1-r3/curl
+ WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/3p-curl-7.54.1-r4/curl
)
unset(ENV{CFLAGS})
execute_process(
COMMAND make install
- WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/3p-curl-7.54.1-r3/curl
+ WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/3p-curl-7.54.1-r4/curl
RESULT_VARIABLE curl_installed
)
if (CMAKE_SYSTEM_NAME MATCHES FreeBSD)
diff --git a/indra/cmake/LLPrimitive.cmake b/indra/cmake/LLPrimitive.cmake
index 81b40cb0b5..df8d96109f 100644
--- a/indra/cmake/LLPrimitive.cmake
+++ b/indra/cmake/LLPrimitive.cmake
@@ -28,25 +28,25 @@ if (TRUE)
target_link_libraries( ll::minizip-ng INTERFACE ${Minizip_LIBRARIES} )
target_link_libraries( ll::libxml INTERFACE ${Libxml2_LIBRARIES} )
if (${PREBUILD_TRACKING_DIR}/sentinel_installed IS_NEWER_THAN ${PREBUILD_TRACKING_DIR}/colladadom_installed OR NOT ${colladadom_installed} EQUAL 0)
- if (NOT EXISTS ${CMAKE_BINARY_DIR}/3p-colladadom-2.3-r10.tar.gz)
+ if (NOT EXISTS ${CMAKE_BINARY_DIR}/3p-colladadom-2.3-r11.tar.gz)
file(DOWNLOAD
- https://github.com/secondlife/3p-colladadom/archive/refs/tags/v2.3-r10.tar.gz
- ${CMAKE_BINARY_DIR}/3p-colladadom-2.3-r10.tar.gz
+ https://github.com/secondlife/3p-colladadom/archive/refs/tags/v2.3-r11.tar.gz
+ ${CMAKE_BINARY_DIR}/3p-colladadom-2.3-r11.tar.gz
)
endif ()
file(ARCHIVE_EXTRACT
- INPUT ${CMAKE_BINARY_DIR}/3p-colladadom-2.3-r10.tar.gz
+ INPUT ${CMAKE_BINARY_DIR}/3p-colladadom-2.3-r11.tar.gz
DESTINATION ${CMAKE_BINARY_DIR}
)
if (WINDOWS OR CMAKE_COMMAND MATCHES /usr/bin/cmake)
execute_process(
COMMAND sed -i "s/include_directories/cmake_minimum_required(VERSION 3.28)\\ninclude_directories/" CMakeLists.txt
- WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/3p-colladadom-2.3-r10
+ WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/3p-colladadom-2.3-r11
)
else ()
execute_process(
COMMAND sed -i "" -e "s/include_directories/cmake_minimum_required(VERSION 3.28)\\ninclude_directories/" CMakeLists.txt
- WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/3p-colladadom-2.3-r10
+ WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/3p-colladadom-2.3-r11
)
endif ()
if (WINDOWS)
@@ -54,12 +54,12 @@ if (TRUE)
COMMAND sed -i "s/SHARED/STATIC/" 1.4/CMakeLists.txt
COMMAND sed -i "/#include <cstdarg>/a #define WIN32" dae/daeUtils.cpp
COMMAND sed -i "/using namespace cdom;/a namespace boost{void boost::throw_exception(class std::exception const &){}}" dae/daeURI.cpp
- WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/3p-colladadom-2.3-r10/src
+ WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/3p-colladadom-2.3-r11/src
)
else ()
execute_process(
COMMAND sed -i "" -e "s/SHARED/STATIC/" src/1.4/CMakeLists.txt
- WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/3p-colladadom-2.3-r10
+ WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/3p-colladadom-2.3-r11
)
endif ()
if (DARWIN)
@@ -79,14 +79,14 @@ if (TRUE)
execute_process(
COMMAND sed -i "" -e "s/endif 0/endif/" dae/daeUtils.cpp
COMMAND sed -i "" -e "s/linux/FreeBSD/" dae/daeUtils.cpp
- WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/3p-colladadom-2.3-r10/src
+ WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/3p-colladadom-2.3-r11/src
)
endif ()
file(MAKE_DIRECTORY ${LIBS_PREBUILT_DIR}/include/collada/1.4)
try_compile(COLLADADOM_RESULT
PROJECT colladadom
- SOURCE_DIR ${CMAKE_BINARY_DIR}/3p-colladadom-2.3-r10
- BINARY_DIR ${CMAKE_BINARY_DIR}/3p-colladadom-2.3-r10
+ SOURCE_DIR ${CMAKE_BINARY_DIR}/3p-colladadom-2.3-r11
+ BINARY_DIR ${CMAKE_BINARY_DIR}/3p-colladadom-2.3-r11
TARGET collada14dom
CMAKE_FLAGS
-DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE}
@@ -106,13 +106,13 @@ if (TRUE)
)
if (WINDOWS)
execute_process(
- COMMAND MSBuild.exe ${CMAKE_BINARY_DIR}/3p-colladadom-2.3-r10/Project.slnx -p:Configuration=${CMAKE_BUILD_TYPE}
- WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/3p-colladadom-2.3-r10
+ COMMAND MSBuild.exe ${CMAKE_BINARY_DIR}/3p-colladadom-2.3-r11/Project.slnx -p:Configuration=${CMAKE_BUILD_TYPE}
+ WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/3p-colladadom-2.3-r11
OUTPUT_VARIABLE colladadom_installed
)
file(REMOVE_RECURSE ${LIBS_PREBUILT_DIR}/include/collada)
file(
- COPY ${CMAKE_BINARY_DIR}/3p-colladadom-2.3-r10/include
+ COPY ${CMAKE_BINARY_DIR}/3p-colladadom-2.3-r11/include
DESTINATION ${LIBS_PREBUILT_DIR}/include
)
file(RENAME
@@ -121,13 +121,13 @@ if (TRUE)
)
file(MAKE_DIRECTORY ${ARCH_PREBUILT_DIRS_RELEASE})
file(RENAME
- ${CMAKE_BINARY_DIR}/3p-colladadom-2.3-r10/src/1.4/${CMAKE_BUILD_TYPE}/collada14dom.lib
+ ${CMAKE_BINARY_DIR}/3p-colladadom-2.3-r11/src/1.4/${CMAKE_BUILD_TYPE}/collada14dom.lib
${ARCH_PREBUILT_DIRS_RELEASE}/libcollada14dom23-s.lib
)
elseif (${COLLADADOM_RESULT})
execute_process(
COMMAND ${CMAKE_MAKE_PROGRAM} install
- WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/3p-colladadom-2.3-r10
+ WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/3p-colladadom-2.3-r11
OUTPUT_VARIABLE colladadom_installed
)
file(RENAME
diff --git a/indra/cmake/UnixInstall.cmake b/indra/cmake/UnixInstall.cmake
index 1fd17a0142..b82cbbcc2f 100644
--- a/indra/cmake/UnixInstall.cmake
+++ b/indra/cmake/UnixInstall.cmake
@@ -22,8 +22,8 @@ if (INSTALL)
set(_LIB lib)
endif ()
- set(INSTALL_LIBRARY_DIR ${INSTALL_PREFIX}/${_LIB} CACHE PATH
- "Installation directory for read-only shared files.")
+ set(INSTALL_LIBRARY_DIR ${INSTALL_PREFIX}/${_LIB}/${VIEWER_BINARY_NAME} CACHE PATH
+ "Installation directory for dynamic library files and their resources.")
set(INSTALL_SHARE_DIR ${INSTALL_PREFIX}/share CACHE PATH
"Installation directory for read-only shared files.")
diff --git a/indra/llwebrtc/CMakeLists.txt b/indra/llwebrtc/CMakeLists.txt
index a01d9fc632..1c53b0263c 100644
--- a/indra/llwebrtc/CMakeLists.txt
+++ b/indra/llwebrtc/CMakeLists.txt
@@ -77,11 +77,11 @@ if (INSTALL)
if (DARWIN)
set(_LIB ../Frameworks)
elseif (${LINUX_DISTRO} MATCHES debian OR (${LINUX_DISTRO} MATCHES ubuntu))
- set(_LIB lib/${ARCH}-linux-gnu)
+ set(_LIB lib/${ARCH}-linux-gnu/${VIEWER_BINARY_NAME})
elseif (${LINUX_DISTRO} MATCHES fedora OR (${LINUX_DISTRO} MATCHES opensuse-tumbleweed) OR (${LINUX_DISTRO} MATCHES gentoo))
- set(_LIB lib${ADDRESS_SIZE})
+ set(_LIB lib${ADDRESS_SIZE}/${VIEWER_BINARY_NAME})
else ()
- set(_LIB lib)
+ set(_LIB lib/${VIEWER_BINARY_NAME})
endif ()
if (WINDOWS)
diff --git a/indra/media_plugins/cef/CMakeLists.txt b/indra/media_plugins/cef/CMakeLists.txt
index 236e117aa7..ee715cce03 100644
--- a/indra/media_plugins/cef/CMakeLists.txt
+++ b/indra/media_plugins/cef/CMakeLists.txt
@@ -50,7 +50,10 @@ if (LINUX)
)
list(APPEND media_plugin_cef_SOURCE_FILES ${LINUX_VOLUME_CATCHER})
- set(CMAKE_SHARED_LINKER_FLAGS "-Wl,--build-id -Wl,-rpath,'$ORIGIN:$ORIGIN/../../lib'")
+ set(CMAKE_SHARED_LINKER_FLAGS "-Wl,--build-id")
+ if (${LINUX_DISTRO} MATCHES arch OR (${LINUX_DISTRO} MATCHES fedora))
+ set(CMAKE_INSTALL_RPATH ${CMAKE_INSTALL_RPATH};${INSTALL_PREFIX}/${_LIB}/cef)
+ endif ()
list(APPEND media_plugin_cef_LINK_LIBRARIES llwindow )
elseif (DARWIN)
list(APPEND media_plugin_cef_SOURCE_FILES volume_catcher_null.cpp)
@@ -145,45 +148,47 @@ if (INSTALL)
)
elseif (LINUX)
if (${LINUX_DISTRO} MATCHES debian OR (${LINUX_DISTRO} MATCHES ubuntu))
- set(_LIB lib/${ARCH}-linux-gnu)
+ set(_LIB lib/${ARCH}-linux-gnu/${VIEWER_BINARY_NAME})
elseif (${LINUX_DISTRO} MATCHES fedora OR (${LINUX_DISTRO} MATCHES opensuse-tumbleweed) OR (${LINUX_DISTRO} MATCHES gentoo))
- set(_LIB lib${ADDRESS_SIZE})
+ set(_LIB lib${ADDRESS_SIZE}/${VIEWER_BINARY_NAME})
else ()
- set(_LIB lib)
+ set(_LIB lib/${VIEWER_BINARY_NAME})
endif ()
if (${LINUX_DISTRO} MATCHES arch)
install(
- PROGRAMS
- ${AUTOBUILD_INSTALL_DIR}/bin/release/chrome-sandbox
- ${AUTOBUILD_INSTALL_DIR}/bin/release/dullahan_host
+ PROGRAMS ${AUTOBUILD_INSTALL_DIR}/bin/release/dullahan_host
DESTINATION lib/${VIEWER_BINARY_NAME}
- #PERMISSIONS SETUID OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE
)
- else (${LINUX_DISTRO} MATCHES arch)
+ elseif (${LINUX_DISTRO} MATCHES fedora)
+ install(
+ PROGRAMS ${AUTOBUILD_INSTALL_DIR}/bin/release/dullahan_host
+ DESTINATION libexec/${VIEWER_BINARY_NAME}
+ )
+ else ()
install(
PROGRAMS
${AUTOBUILD_INSTALL_DIR}/bin/release/chrome-sandbox
${AUTOBUILD_INSTALL_DIR}/bin/release/dullahan_host
DESTINATION libexec/${VIEWER_BINARY_NAME}
- #PERMISSIONS SETUID OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE
)
- endif (${LINUX_DISTRO} MATCHES arch)
- install(
- FILES
- ${ARCH_PREBUILT_DIRS_RELEASE}/libcef.so
- ${ARCH_PREBUILT_DIRS_RELEASE}/libvk_swiftshader.so
- ${AUTOBUILD_INSTALL_DIR}/bin/release/snapshot_blob.bin
- ${AUTOBUILD_INSTALL_DIR}/bin/release/v8_context_snapshot.bin
- ${AUTOBUILD_INSTALL_DIR}/resources/chrome_100_percent.pak
- ${AUTOBUILD_INSTALL_DIR}/resources/chrome_200_percent.pak
- ${AUTOBUILD_INSTALL_DIR}/resources/icudtl.dat
- ${AUTOBUILD_INSTALL_DIR}/resources/resources.pak
- DESTINATION ${_LIB}
+ endif ()
+ if (NOT (${LINUX_DISTRO} MATCHES arch OR (${LINUX_DISTRO} MATCHES fedora)))
+ install(
+ FILES
+ ${ARCH_PREBUILT_DIRS_RELEASE}/libcef.so
+ ${ARCH_PREBUILT_DIRS_RELEASE}/libvk_swiftshader.so
+ ${AUTOBUILD_INSTALL_DIR}/lib/release/v8_context_snapshot.bin
+ ${AUTOBUILD_INSTALL_DIR}/resources/chrome_100_percent.pak
+ ${AUTOBUILD_INSTALL_DIR}/resources/chrome_200_percent.pak
+ ${AUTOBUILD_INSTALL_DIR}/resources/icudtl.dat
+ ${AUTOBUILD_INSTALL_DIR}/resources/resources.pak
+ DESTINATION ${_LIB}
)
- install(
- DIRECTORY ${AUTOBUILD_INSTALL_DIR}/resources/locales
- DESTINATION ${_LIB}
+ install(
+ DIRECTORY ${AUTOBUILD_INSTALL_DIR}/resources/locales
+ DESTINATION ${_LIB}
)
+ endif ()
elseif (WINDOWS)
set(_LIB llplugin)
install(
@@ -213,7 +218,7 @@ if (INSTALL)
DESTINATION llplugin
)
else ()
- set(_LIB lib)
+ set(_LIB lib/${VIEWER_BINARY_NAME})
endif ()
if (NOT WINDOWS)
install(TARGETS ${PROJECT_NAME} DESTINATION ${_LIB})
diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp
index a2b664c755..d5ec3dbb20 100644
--- a/indra/media_plugins/cef/media_plugin_cef.cpp
+++ b/indra/media_plugins/cef/media_plugin_cef.cpp
@@ -957,7 +957,6 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
{
authResponse(message_in);
}
-#if !LL_LINUX
if (message_name == "edit_undo")
{
mCEFLib->editUndo();
@@ -966,7 +965,6 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
{
mCEFLib->editRedo();
}
-#endif
if (message_name == "edit_cut")
{
mCEFLib->editCut();
@@ -979,7 +977,6 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
{
mCEFLib->editPaste();
}
-#if !LL_LINUX
if (message_name == "edit_delete")
{
mCEFLib->editDelete();
@@ -992,7 +989,6 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
{
mCEFLib->viewSource();
}
-#endif
}
else if (message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER)
{
@@ -1176,28 +1172,19 @@ void MediaPluginCEF::unicodeInput(std::string event, LLSD native_key_data = LLSD
//
void MediaPluginCEF::checkEditState()
{
-#if !LL_LINUX
bool can_undo = mCEFLib->editCanUndo();
bool can_redo = mCEFLib->editCanRedo();
-#endif
bool can_cut = mCEFLib->editCanCut();
bool can_copy = mCEFLib->editCanCopy();
bool can_paste = mCEFLib->editCanPaste();
-#if !LL_LINUX
bool can_delete = mCEFLib->editCanDelete();
bool can_select_all = mCEFLib->editCanSelectAll();
-#endif
-#if LL_LINUX
- if ((can_cut != mCanCut) || (can_copy != mCanCopy) || (can_paste != mCanPaste))
-#else
if ((can_undo != mCanUndo) || (can_redo != mCanRedo) || (can_cut != mCanCut) || (can_copy != mCanCopy)
|| (can_paste != mCanPaste) || (can_delete != mCanDelete) || (can_select_all != mCanSelectAll))
-#endif
{
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "edit_state");
-#if !LL_LINUX
if (can_undo != mCanUndo)
{
mCanUndo = can_undo;
@@ -1209,7 +1196,6 @@ void MediaPluginCEF::checkEditState()
mCanRedo = can_redo;
message.setValueBoolean("redo", can_redo);
}
-#endif
if (can_cut != mCanCut)
{
@@ -1229,7 +1215,6 @@ void MediaPluginCEF::checkEditState()
message.setValueBoolean("paste", can_paste);
}
-#if !LL_LINUX
if (can_delete != mCanDelete)
{
mCanDelete = can_delete;
@@ -1241,7 +1226,6 @@ void MediaPluginCEF::checkEditState()
mCanSelectAll = can_select_all;
message.setValueBoolean("select_all", can_select_all);
}
-#endif
sendMessage(message);
}
diff --git a/indra/media_plugins/libvlc/CMakeLists.txt b/indra/media_plugins/libvlc/CMakeLists.txt
index b8b3bd68f3..96790a8037 100644
--- a/indra/media_plugins/libvlc/CMakeLists.txt
+++ b/indra/media_plugins/libvlc/CMakeLists.txt
@@ -88,11 +88,11 @@ if (INSTALL)
DESTINATION ${_LIB}/plugins
)
elseif (${LINUX_DISTRO} MATCHES debian OR (${LINUX_DISTRO} MATCHES ubuntu))
- set(_LIB lib/${ARCH}-linux-gnu)
+ set(_LIB lib/${ARCH}-linux-gnu/${VIEWER_BINARY_NAME})
elseif (${LINUX_DISTRO} MATCHES fedora OR (${LINUX_DISTRO} MATCHES opensuse-tumbleweed) OR (${LINUX_DISTRO} MATCHES gentoo))
- set(_LIB lib${ADDRESS_SIZE})
+ set(_LIB lib${ADDRESS_SIZE}/${VIEWER_BINARY_NAME})
else ()
- set(_LIB lib)
+ set(_LIB lib/${VIEWER_BINARY_NAME})
endif ()
if (WINDOWS)
install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE}/${PROJECT_NAME}.dll DESTINATION llplugin)
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 9a2778f853..f19716af7e 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -342,6 +342,7 @@ set(viewer_SOURCE_FILES
llgltfmateriallist.cpp
llgltfmaterialpreviewmgr.cpp
llgroupactions.cpp
+ llgroupcolormap.cpp # group-based nameplate tinting
llgroupiconctrl.cpp
llgrouplist.cpp
llgroupmgr.cpp
@@ -560,6 +561,7 @@ set(viewer_SOURCE_FILES
llpreviewtexture.cpp
llproductinforequest.cpp
llprogressview.cpp
+ llquickprefs.cpp # Firestorm port: Quick Preferences floater
llrecentpeople.cpp
llreflectionmap.cpp
llreflectionmapmanager.cpp
@@ -1036,6 +1038,7 @@ set(viewer_HEADER_FILES
llgltfmateriallist.h
llgltfmaterialpreviewmgr.h
llgroupactions.h
+ llgroupcolormap.h # group-based nameplate tinting
llgroupiconctrl.h
llgrouplist.h
llgroupmgr.h
@@ -1239,6 +1242,7 @@ set(viewer_HEADER_FILES
llpreviewtexture.h
llproductinforequest.h
llprogressview.h
+ llquickprefs.h # Firestorm port: Quick Preferences floater
llrecentpeople.h
llreflectionmap.h
llreflectionmapmanager.h
@@ -2395,7 +2399,7 @@ if (LINUX)
set(CPACK_RPM_PACKAGE_DESCRIPTION ${VIEWER_PACKAGE_DESCRIPTION}
CACHE STRING "RPM package description.")
if (${LINUX_DISTRO} MATCHES fedora)
- set(CPACK_RPM_PACKAGE_REQUIRES "freealut, apr-util, boost-fiber, boost-program-options, boost-regex, boost-thread, boost-url, expat, fltk, mesa-libGLU, hunspell, libnghttp2, openjpeg, sdl2-compat, vlc-libs, vlc-plugins-base, libvorbis"
+ set(CPACK_RPM_PACKAGE_REQUIRES "freealut, apr-util, boost-fiber, boost-program-options, boost-regex, boost-thread, boost-url, cef, expat, fltk, mesa-libGLU, hunspell, libnghttp2, openjpeg, sdl2-compat, vlc-libs, vlc-plugins-base, libvorbis"
CACHE STRING "RPM package requirements.")
else ()
set(CPACK_RPM_PACKAGE_REQUIRES "libalut0, libapr-util1-0, libboost_fiber1_91_0, libboost_program_options1_91_0, libboost_regex1_91_0, libboost_thread1_91_0, libboost_url1_91_0, libboost_url1_91_0-x86-64-v3, libpng16-16 expat, libfltk1_3, libGLU1, libhunspell-1_7-0, libnghttp2-14, openjpeg2, libSDL2-2_0-0, libvlc5, libvorbis0"
diff --git a/indra/newview/PKGBUILD.in b/indra/newview/PKGBUILD.in
index 3de9558000..b2830ed145 100644
--- a/indra/newview/PKGBUILD.in
+++ b/indra/newview/PKGBUILD.in
@@ -6,7 +6,7 @@ pkgdesc="${VIEWER_PACKAGE_COMMENT}"
arch=('${CMAKE_SYSTEM_PROCESSOR}')
url="https://${VIEWER_PACKAGE_DOMAIN_NAME}"
license=('LGPL-2.1')
-depends=(freealut apr-util at-spi2-core boost-libs fltk glu hunspell libnghttp2 openjpeg2 sdl2 vlc libvorbis)
+depends=(freealut apr-util at-spi2-core boost-libs cef fltk glu hunspell libnghttp2 openjpeg2 sdl2 vlc libvorbis)
package() {
cd "$startdir"
diff --git a/indra/newview/ViewerInstall.cmake b/indra/newview/ViewerInstall.cmake
index 56a3394943..8f2827e1bc 100644
--- a/indra/newview/ViewerInstall.cmake
+++ b/indra/newview/ViewerInstall.cmake
@@ -201,7 +201,7 @@ if (LINUX)
if (USE_DISCORD)
install(
FILES ${ARCH_PREBUILT_DIRS_RELEASE}/libdiscord_partner_sdk.so
- DESTINATION ${_LIB}
+ DESTINATION ${_LIB}/${VIEWER_BINARY_NAME}
)
endif ()
if (USE_FMODSTUDIO)
@@ -209,7 +209,7 @@ if (LINUX)
${ARCH_PREBUILT_DIRS_RELEASE}/libfmod.so
${ARCH_PREBUILT_DIRS_RELEASE}/libfmod.so.13
${ARCH_PREBUILT_DIRS_RELEASE}/libfmod.so.13.34
- DESTINATION ${_LIB})
+ DESTINATION ${_LIB}/${VIEWER_BINARY_NAME})
endif (USE_FMODSTUDIO)
endif (LINUX)
diff --git a/indra/newview/app_settings/commands.xml b/indra/newview/app_settings/commands.xml
index 6a05466e06..9b80b40008 100644
--- a/indra/newview/app_settings/commands.xml
+++ b/indra/newview/app_settings/commands.xml
@@ -310,4 +310,15 @@
tooltip_ref="Command_ResyncAnimations_Tooltip"
execute_function="Tools.ResyncAnimations"
/>
+ <!-- Firestorm port: Quick Preferences toolbar button -->
+ <command name="quick_prefs"
+ available_in_toybox="true"
+ icon="Command_Preferences_Icon"
+ label_ref="Command_QuickPrefs_Label"
+ tooltip_ref="Command_QuickPrefs_Tooltip"
+ execute_function="Floater.ToggleOrBringToFront"
+ execute_parameters="quick_prefs"
+ is_running_function="Floater.IsOpen"
+ is_running_parameters="quick_prefs"
+ />
</commands>
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index f1e5217afd..481cafafd1 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -1337,6 +1337,34 @@
<key>Value</key>
<real>1.047197551</real>
</map>
+ <!-- NaCl/Firestorm port: mouselook right-click zoom -->
+ <key>_NACL_MLFovValues</key>
+ <map>
+ <key>Comment</key>
+ <string>Mouselook FOV zoom state: VX=normal FOV, VY=zoomed FOV, VZ=1 if currently zoomed</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Vector3</string>
+ <key>Value</key>
+ <array>
+ <real>1.047197551</real>
+ <real>1.047197551</real>
+ <real>0.0</real>
+ </array>
+ </map>
+ <key>FSScrollWheelExitsMouselook</key>
+ <map>
+ <key>Comment</key>
+ <string>If enabled, scrolling up while in mouselook (without right mouse held) exits mouselook</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <!-- End NaCl/Firestorm port -->
<key>CameraOffset</key>
<map>
<key>Comment</key>
diff --git a/indra/newview/llavatarpropertiesprocessor.cpp b/indra/newview/llavatarpropertiesprocessor.cpp
index 9d9948731f..aa24c69831 100644
--- a/indra/newview/llavatarpropertiesprocessor.cpp
+++ b/indra/newview/llavatarpropertiesprocessor.cpp
@@ -527,12 +527,28 @@ void LLAvatarPropertiesProcessor::processAvatarGroupsReply(LLMessageSystem* msg,
AvatarGroupsReply is automatically sent by the server in response to the
AvatarPropertiesRequest in addition to the AvatarPropertiesReply message.
*/
- LLUUID agent_id;
- LLUUID avatar_id;
- msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id);
- msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AvatarID, avatar_id);
+ LLAvatarGroups avatar_groups;
+ msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, avatar_groups.agent_id);
+ msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AvatarID, avatar_groups.avatar_id);
+
+ LL_DEBUGS("AvatarProperties") << "Received AvatarGroupsReply for "
+ << avatar_groups.avatar_id << LL_ENDL;
+
+ S32 group_count = msg->getNumberOfBlocksFast(_PREHASH_GroupData);
+ for (S32 i = 0; i < group_count; ++i)
+ {
+ LLAvatarGroups::LLGroupData gd;
+ msg->getU64Fast( _PREHASH_GroupData, _PREHASH_GroupPowers, gd.group_powers, i);
+ msg->getBOOLFast( _PREHASH_GroupData, _PREHASH_AcceptNotices, gd.accept_notices, i);
+ msg->getStringFast( _PREHASH_GroupData, _PREHASH_GroupTitle, gd.group_title, i);
+ msg->getUUIDFast( _PREHASH_GroupData, _PREHASH_GroupID, gd.group_id, i);
+ msg->getStringFast( _PREHASH_GroupData, _PREHASH_GroupName, gd.group_name, i);
+ msg->getUUIDFast( _PREHASH_GroupData, _PREHASH_GroupInsigniaID, gd.group_insignia_id, i);
+ avatar_groups.group_list.push_back(gd);
+ }
- LL_DEBUGS("AvatarProperties") << "Received AvatarGroupsReply for " << avatar_id << LL_ENDL;
+ LLAvatarPropertiesProcessor* self = getInstance();
+ self->notifyObservers(avatar_groups.avatar_id, &avatar_groups, APT_GROUPS);
}
void LLAvatarPropertiesProcessor::notifyObservers(const LLUUID& id, void* data, EAvatarProcessorType type)
diff --git a/indra/newview/llavatarpropertiesprocessor.h b/indra/newview/llavatarpropertiesprocessor.h
index 1592629fca..bfafe780ff 100644
--- a/indra/newview/llavatarpropertiesprocessor.h
+++ b/indra/newview/llavatarpropertiesprocessor.h
@@ -55,7 +55,8 @@ enum EAvatarProcessorType
APT_PICK_INFO,
APT_TEXTURES,
APT_CLASSIFIEDS,
- APT_CLASSIFIED_INFO
+ APT_CLASSIFIED_INFO,
+ APT_GROUPS // Group membership list with per-group role titles
};
// legacy data is supposed to match AvatarPropertiesReply,
@@ -117,6 +118,28 @@ struct LLAvatarData::LLGroupData
LLUUID group_insignia_id;
};
+/** Sent by the server automatically alongside AvatarPropertiesReply (UDP).
+ * Contains every group the avatar belongs to, including their selected
+ * role title in each group. The active group is the one whose group_title
+ * matches the avatar's current "Title" NameValue. */
+struct LLAvatarGroups
+{
+ LLUUID agent_id;
+ LLUUID avatar_id;
+
+ struct LLGroupData
+ {
+ U64 group_powers { 0 };
+ bool accept_notices{ false };
+ std::string group_title; // role title the avatar has selected in this group
+ LLUUID group_id;
+ std::string group_name;
+ LLUUID group_insignia_id;
+ };
+ typedef std::list<LLGroupData> group_list_t;
+ group_list_t group_list;
+};
+
struct LLPickData
{
LLUUID agent_id;
diff --git a/indra/newview/llgroupcolormap.cpp b/indra/newview/llgroupcolormap.cpp
new file mode 100644
index 0000000000..36fde1ce38
--- /dev/null
+++ b/indra/newview/llgroupcolormap.cpp
@@ -0,0 +1,150 @@
+/**
+ * @file llgroupcolormap.cpp
+ * @brief Per-group nameplate tint registry.
+ * $LicenseInfo:firstyear=2024&license=viewerlgpl$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llgroupcolormap.h"
+
+#include "lldir.h"
+#include "llsdserialize.h"
+#include "llsdutil_math.h" // ll_sd_from_color4 / ll_color4_from_sd
+#include "llvoavatar.h" // LLVOAvatar::invalidateNameTags()
+
+static constexpr char GROUP_COLOR_FILE[] = "settings_group_colors.xml";
+
+// ---------------------------------------------------------------------------
+// Constructor
+// ---------------------------------------------------------------------------
+
+LLGroupColorMap::LLGroupColorMap()
+{
+}
+
+// ---------------------------------------------------------------------------
+// Public API
+// ---------------------------------------------------------------------------
+
+void LLGroupColorMap::setGroupColor(const LLUUID& group_id, const LLColor4& color)
+{
+ if (group_id.isNull())
+ return;
+
+ // Treat fully-transparent as "no color" (remove entry)
+ if (color.mV[VW] < 0.01f)
+ {
+ clearGroupColor(group_id);
+ return;
+ }
+
+ mColors[group_id] = color;
+ saveToDisk();
+ invalidateAllNameTags();
+}
+
+LLColor4 LLGroupColorMap::getGroupColor(const LLUUID& group_id) const
+{
+ if (group_id.isNull())
+ return LLColor4::transparent;
+
+ auto it = mColors.find(group_id);
+ if (it != mColors.end())
+ return it->second;
+
+ return LLColor4::transparent;
+}
+
+bool LLGroupColorMap::hasGroupColor(const LLUUID& group_id) const
+{
+ if (group_id.isNull())
+ return false;
+ return mColors.find(group_id) != mColors.end();
+}
+
+void LLGroupColorMap::clearGroupColor(const LLUUID& group_id)
+{
+ if (mColors.erase(group_id) > 0)
+ {
+ saveToDisk();
+ invalidateAllNameTags();
+ }
+}
+
+// ---------------------------------------------------------------------------
+// Persistence
+// ---------------------------------------------------------------------------
+
+// static
+std::string LLGroupColorMap::getFilePath()
+{
+ std::string path = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "");
+ if (!path.empty())
+ return gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, GROUP_COLOR_FILE);
+ // Fall back to app_settings (before first login, path not yet set)
+ return gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, GROUP_COLOR_FILE);
+}
+
+void LLGroupColorMap::loadFromDisk()
+{
+ mColors.clear();
+
+ const std::string filepath = getFilePath();
+ if (!gDirUtilp->fileExists(filepath))
+ return;
+
+ llifstream stream(filepath.c_str());
+ if (!stream.is_open())
+ {
+ LL_WARNS("GroupColor") << "Cannot open " << filepath << LL_ENDL;
+ return;
+ }
+
+ LLSD data;
+ if (LLSDSerialize::fromXMLDocument(data, stream) < 0)
+ {
+ LL_WARNS("GroupColor") << "Failed to parse " << filepath << LL_ENDL;
+ return;
+ }
+
+ // Format: map of { group_uuid_string : [r, g, b, a] }
+ for (LLSD::map_const_iterator it = data.beginMap(); it != data.endMap(); ++it)
+ {
+ LLUUID group_id(it->first);
+ if (group_id.isNull()) continue;
+ LLColor4 color = ll_color4_from_sd(it->second);
+ if (color.mV[VW] >= 0.01f)
+ mColors[group_id] = color;
+ }
+
+ LL_INFOS("GroupColor") << "Loaded " << mColors.size()
+ << " group color(s) from " << filepath << LL_ENDL;
+}
+
+void LLGroupColorMap::saveToDisk() const
+{
+ const std::string filepath = getFilePath();
+
+ LLSD data = LLSD::emptyMap();
+ for (const auto& [group_id, color] : mColors)
+ data[group_id.asString()] = ll_sd_from_color4(color);
+
+ llofstream stream(filepath.c_str());
+ if (!stream.is_open())
+ {
+ LL_WARNS("GroupColor") << "Cannot write " << filepath << LL_ENDL;
+ return;
+ }
+ LLSDSerialize::toPrettyXML(data, stream);
+}
+
+// ---------------------------------------------------------------------------
+// Invalidation
+// ---------------------------------------------------------------------------
+
+// static
+void LLGroupColorMap::invalidateAllNameTags()
+{
+ LLVOAvatar::invalidateNameTags();
+}
diff --git a/indra/newview/llgroupcolormap.h b/indra/newview/llgroupcolormap.h
new file mode 100644
index 0000000000..d6f661c43a
--- /dev/null
+++ b/indra/newview/llgroupcolormap.h
@@ -0,0 +1,64 @@
+/**
+ * @file llgroupcolormap.h
+ * @brief Per-group nameplate tint registry.
+ *
+ * Stores a client-side color for each group UUID. When the group color is
+ * set, every avatar whose *active* group tag matches that UUID gets their
+ * nameplate rendered in that color instead of the default.
+ *
+ * Data is persisted to <account_dir>/settings_group_colors.xml so colors
+ * survive relogs. The file is keyed by group UUID string → LLColor4 LLSD.
+ *
+ * $LicenseInfo:firstyear=2024&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License version 2.1 only.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLGROUPCOLORMAP_H
+#define LL_LLGROUPCOLORMAP_H
+
+#include "llsingleton.h"
+#include "lluuid.h"
+#include "v4color.h"
+#include <unordered_map>
+
+class LLGroupColorMap : public LLSingleton<LLGroupColorMap>
+{
+ LLSINGLETON(LLGroupColorMap);
+ ~LLGroupColorMap() = default;
+ LOG_CLASS(LLGroupColorMap);
+
+public:
+ // ---- Color CRUD ---------------------------------------------------------
+
+ /** Set (or clear) the nameplate tint for a group.
+ * Pass LLColor4::transparent (alpha == 0) to remove the color entry. */
+ void setGroupColor(const LLUUID& group_id, const LLColor4& color);
+
+ /** Return the tint for @p group_id, or LLColor4::transparent if none. */
+ LLColor4 getGroupColor(const LLUUID& group_id) const;
+
+ /** True if a non-transparent color is stored for this group. */
+ bool hasGroupColor(const LLUUID& group_id) const;
+
+ /** Remove the color entry for this group. */
+ void clearGroupColor(const LLUUID& group_id);
+
+ // ---- Persistence --------------------------------------------------------
+ void loadFromDisk();
+ void saveToDisk() const;
+
+ // ---- Cache invalidation -------------------------------------------------
+ /** Called after a color is changed so nametags rebuild on next idle. */
+ static void invalidateAllNameTags();
+
+private:
+ static std::string getFilePath();
+
+ // group_uuid → RGBA color (std::hash<LLUUID> is specialised in lluuid.h)
+ std::unordered_map<LLUUID, LLColor4> mColors;
+};
+
+#endif // LL_LLGROUPCOLORMAP_H
diff --git a/indra/newview/llnetmap.cpp b/indra/newview/llnetmap.cpp
index 63ec43458b..a2a0731256 100644
--- a/indra/newview/llnetmap.cpp
+++ b/indra/newview/llnetmap.cpp
@@ -48,6 +48,8 @@
#include "llagentcamera.h"
#include "llappviewer.h" // for gDisconnected
#include "llavataractions.h"
+#include "llgroupcolormap.h" // group-based dot tinting
+#include "llvoavatar.h" // group-based dot tinting
#include "llcallingcard.h" // LLAvatarTracker
#include "llfloaterland.h"
#include "llfloaterworldmap.h"
@@ -432,6 +434,24 @@ void LLNetMap::draw()
LLColor4 color = LLAvatarActions::isFriend(uuid) ? map_avatar_friend_color : map_avatar_color;
+ // Group-based dot tinting: override with group color if one is set.
+ // Look up the avatar's active group UUID from the LLVOAvatar object.
+ if (LLViewerObject* obj = gObjectList.findObject(uuid))
+ {
+ if (LLVOAvatar* av = dynamic_cast<LLVOAvatar*>(obj))
+ {
+ LLUUID active_group = av->getActiveGroupID();
+ if (active_group.notNull())
+ {
+ LLColor4 group_color = LLGroupColorMap::getInstance()->getGroupColor(active_group);
+ if (group_color.mV[VW] >= 0.01f)
+ {
+ color = group_color;
+ }
+ }
+ }
+ }
+
unknown_relative_z = sorted_positions[i].mdV[VZ] >= COARSEUPDATE_MAX_Z &&
camera_position.mV[VZ] >= COARSEUPDATE_MAX_Z;
@@ -505,10 +525,23 @@ void LLNetMap::draw()
LLUIImagePtr you = LLWorldMapView::sAvatarYouLargeImage;
if (you)
{
+ // Group-based dot tinting for self: use gAgent.getGroupID() directly
+ LLColor4 self_color = UI_VERTEX_COLOR;
+ LLUUID self_group = gAgent.getGroupID();
+ if (self_group.notNull())
+ {
+ LLColor4 group_color = LLGroupColorMap::getInstance()->getGroupColor(self_group);
+ if (group_color.mV[VW] >= 0.01f)
+ {
+ self_color = group_color;
+ }
+ }
+
you->draw(ll_round(pos_map.mV[VX] - mDotRadius),
ll_round(pos_map.mV[VY] - mDotRadius),
dot_width,
- dot_width);
+ dot_width,
+ self_color);
F32 dist_to_cursor_squared = dist_vec_squared(LLVector2(pos_map.mV[VX], pos_map.mV[VY]),
LLVector2((F32)local_mouse_x, (F32)local_mouse_y));
diff --git a/indra/newview/llpanelgroupgeneral.cpp b/indra/newview/llpanelgroupgeneral.cpp
index 38ae818910..aaa5b2ce9c 100644
--- a/indra/newview/llpanelgroupgeneral.cpp
+++ b/indra/newview/llpanelgroupgeneral.cpp
@@ -28,6 +28,8 @@
#include "llpanelgroupgeneral.h"
+#include "llcolorswatch.h" // LLColorSwatchCtrl – group nameplate tinting
+#include "llgroupcolormap.h" // per-group nameplate tinting
#include "llavatarnamecache.h"
#include "llagent.h"
#include "llagentbenefits.h"
@@ -188,6 +190,22 @@ bool LLPanelGroupGeneral::postBuild()
mIncompleteMemberDataStr = getString("incomplete_member_data_str");
+ // Group nameplate tinting: wire up the color swatch
+ mGroupColorSwatch = getChild<LLColorSwatchCtrl>("group_nametag_color", recurse);
+ if (mGroupColorSwatch)
+ {
+ mGroupColorSwatch->setCanApplyImmediately(false);
+ mGroupColorSwatch->setCommitCallback([this](LLUICtrl*, const LLSD&) { onGroupColorChanged(); });
+ mGroupColorSwatch->setOnCancelCallback([this](LLUICtrl*, const LLSD&) { onGroupColorCancelled(); });
+ mGroupColorSwatch->setOnSelectCallback([this](LLUICtrl*, const LLSD&) { onGroupColorChanged(); });
+ refreshGroupColorSwatch();
+ }
+ LLButton* clear_color_btn = getChild<LLButton>("group_nametag_color_clear", recurse);
+ if (clear_color_btn)
+ {
+ clear_color_btn->setCommitCallback([this](LLUICtrl*, const LLSD&) { onGroupColorCleared(); });
+ }
+
// If the group_id is null, then we are creating a new group
if (mGroupID.isNull())
{
@@ -798,7 +816,65 @@ void LLPanelGroupGeneral::setGroupID(const LLUUID& id)
mInsignia->setImageAssetID(LLUUID::null);
+ // Refresh the nameplate color swatch to show the stored color for this group
+ refreshGroupColorSwatch();
+
resetDirty();
activate();
}
+
+// ---------------------------------------------------------------------------
+// Group nameplate tinting callbacks
+// ---------------------------------------------------------------------------
+
+void LLPanelGroupGeneral::onGroupColorChanged()
+{
+ if (!mGroupColorSwatch || mGroupID.isNull())
+ return;
+
+ LLColor4 color = mGroupColorSwatch->get();
+ LLGroupColorMap::getInstance()->setGroupColor(mGroupID, color);
+}
+
+void LLPanelGroupGeneral::onGroupColorCancelled()
+{
+ // Picker was cancelled — restore whatever is currently saved
+ refreshGroupColorSwatch();
+}
+
+void LLPanelGroupGeneral::onGroupColorCleared()
+{
+ if (mGroupID.isNull())
+ return;
+
+ LLGroupColorMap::getInstance()->clearGroupColor(mGroupID);
+ refreshGroupColorSwatch();
+}
+
+void LLPanelGroupGeneral::refreshGroupColorSwatch()
+{
+ if (!mGroupColorSwatch)
+ return;
+
+ if (mGroupID.isNull())
+ {
+ // No group selected — show a neutral white and disable
+ mGroupColorSwatch->set(LLColor4::white, false);
+ mGroupColorSwatch->setEnabled(false);
+ return;
+ }
+
+ mGroupColorSwatch->setEnabled(true);
+
+ LLColor4 stored = LLGroupColorMap::getInstance()->getGroupColor(mGroupID);
+ if (stored.mV[VW] >= 0.01f)
+ {
+ mGroupColorSwatch->set(stored, false);
+ }
+ else
+ {
+ // No color stored yet — show white as a neutral default
+ mGroupColorSwatch->set(LLColor4::white, false);
+ }
+}
diff --git a/indra/newview/llpanelgroupgeneral.h b/indra/newview/llpanelgroupgeneral.h
index 37db2e96a0..613cc7b3a6 100644
--- a/indra/newview/llpanelgroupgeneral.h
+++ b/indra/newview/llpanelgroupgeneral.h
@@ -39,6 +39,7 @@ class LLCheckBoxCtrl;
class LLComboBox;
class LLSpinCtrl;
class LLAvatarName;
+class LLColorSwatchCtrl; // group nameplate tinting
class LLPanelGroupGeneral : public LLPanelGroupTab
{
@@ -99,6 +100,13 @@ private:
LLComboBox *mComboActiveTitle;
LLComboBox *mComboMature;
LLCheckBoxCtrl *mCtrlReceiveGroupChat; // <exodus/>
+
+ // Group nameplate tinting (client-side, stored in LLGroupColorMap)
+ LLColorSwatchCtrl* mGroupColorSwatch { nullptr };
+ void onGroupColorChanged();
+ void onGroupColorCancelled();
+ void onGroupColorCleared();
+ void refreshGroupColorSwatch();
};
#endif
diff --git a/indra/newview/llquickprefs.cpp b/indra/newview/llquickprefs.cpp
new file mode 100644
index 0000000000..800aa7abac
--- /dev/null
+++ b/indra/newview/llquickprefs.cpp
@@ -0,0 +1,205 @@
+/**
+ * @file llquickprefs.cpp
+ * @brief Quick Preferences floater: hover height and bandwidth sliders.
+ *
+ * Ported from Firestorm Viewer (quickprefs.cpp).
+ * Original authors: WoLf Loonie, Zi Ree, Ansariel Hiller @ Second Life.
+ *
+ * $LicenseInfo:firstyear=2011&license=viewerlgpl$
+ * Phoenix Firestorm Viewer Source Code
+ * Copyright (C) 2011, WoLf Loonie @ Second Life
+ *
+ * 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.
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llquickprefs.h"
+
+#include "llagent.h"
+#include "llsliderctrl.h"
+#include "lltextbox.h"
+#include "llviewercontrol.h"
+#include "llviewerregion.h"
+#include "llvoavatar.h" // for MIN_HOVER_Z / MAX_HOVER_Z
+#include "llvoavatarself.h" // for gAgentAvatarp, isAgentAvatarValid()
+
+// ---------------------------------------------------------------------------
+// Constructor / destructor
+// ---------------------------------------------------------------------------
+
+LLFloaterQuickPrefs::LLFloaterQuickPrefs(const LLSD& key)
+ : LLFloater(key)
+ , mAvatarZOffsetSlider(nullptr)
+{
+}
+
+LLFloaterQuickPrefs::~LLFloaterQuickPrefs()
+{
+ if (mRegionChangedSlot.connected())
+ {
+ mRegionChangedSlot.disconnect();
+ }
+}
+
+// ---------------------------------------------------------------------------
+// postBuild – wire up all widgets
+// ---------------------------------------------------------------------------
+
+bool LLFloaterQuickPrefs::postBuild()
+{
+ // ---- Hover height slider ------------------------------------------------
+ mAvatarZOffsetSlider = getChild<LLSliderCtrl>("HoverHeightSlider");
+ mAvatarZOffsetSlider->setMinValue(MIN_HOVER_Z);
+ mAvatarZOffsetSlider->setMaxValue(MAX_HOVER_Z);
+
+ // Live preview while dragging
+ mAvatarZOffsetSlider->setCommitCallback(
+ boost::bind(&LLFloaterQuickPrefs::onAvatarZOffsetSliderMoved, this));
+
+ // Persist on release or typed entry
+ mAvatarZOffsetSlider->setSliderMouseUpCallback(
+ boost::bind(&LLFloaterQuickPrefs::onAvatarZOffsetFinalCommit, this));
+ mAvatarZOffsetSlider->setSliderEditorCommitCallback(
+ boost::bind(&LLFloaterQuickPrefs::onAvatarZOffsetFinalCommit, this));
+
+ // Pull current value from settings
+ syncAvatarZOffsetFromPreferenceSetting();
+
+ // Keep slider in sync when something else changes the setting (e.g. RLVa,
+ // the Edit Shape floater, or the standalone Hover Height floater).
+ if (gSavedPerAccountSettings.getControl("AvatarHoverOffsetZ"))
+ {
+ gSavedPerAccountSettings.getControl("AvatarHoverOffsetZ")
+ ->getCommitSignal()
+ ->connect(boost::bind(
+ &LLFloaterQuickPrefs::syncAvatarZOffsetFromPreferenceSetting, this));
+ }
+ else
+ {
+ LL_WARNS("QuickPrefs") << "Control 'AvatarHoverOffsetZ' not found" << LL_ENDL;
+ }
+
+ // Watch for region changes so we can enable/disable the slider
+ if (!mRegionChangedSlot.connected())
+ {
+ mRegionChangedSlot = gAgent.addRegionChangedCallback(
+ boost::bind(&LLFloaterQuickPrefs::onRegionChanged, this));
+ }
+ onRegionChanged(); // evaluate current region immediately
+
+ return true;
+}
+
+// ---------------------------------------------------------------------------
+// onClose
+// ---------------------------------------------------------------------------
+
+void LLFloaterQuickPrefs::onClose(bool app_quitting)
+{
+ if (mRegionChangedSlot.connected())
+ {
+ mRegionChangedSlot.disconnect();
+ }
+ LLFloater::onClose(app_quitting);
+}
+
+// ---------------------------------------------------------------------------
+// Hover height callbacks
+// ---------------------------------------------------------------------------
+
+void LLFloaterQuickPrefs::onAvatarZOffsetSliderMoved()
+{
+ F32 value = mAvatarZOffsetSlider->getValueF32();
+ LLVector3 offset(0.0f, 0.0f, llclamp(value, MIN_HOVER_Z, MAX_HOVER_Z));
+
+ LL_INFOS("Avatar") << "QuickPrefs: setting hover from slider moved " << offset[VZ] << LL_ENDL;
+
+ if (gAgent.getRegion() && gAgent.getRegion()->avatarHoverHeightEnabled())
+ {
+ if (mAvatarZOffsetSlider->isMouseHeldDown())
+ {
+ // Live preview: send to avatar but don't persist yet
+ if (isAgentAvatarValid())
+ {
+ gAgentAvatarp->setHoverOffset(offset, false);
+ }
+ }
+ else
+ {
+ // Committed (e.g. arrow-key step): persist immediately
+ gSavedPerAccountSettings.setF32("AvatarHoverOffsetZ", value);
+ }
+ }
+ else if (isAgentAvatarValid())
+ {
+ gSavedPerAccountSettings.setF32("AvatarHoverOffsetZ", value);
+ }
+}
+
+void LLFloaterQuickPrefs::onAvatarZOffsetFinalCommit()
+{
+ F32 value = mAvatarZOffsetSlider->getValueF32();
+ LL_INFOS("Avatar") << "QuickPrefs: setting hover from slider final commit " << value << LL_ENDL;
+ gSavedPerAccountSettings.setF32("AvatarHoverOffsetZ",
+ llclamp(value, MIN_HOVER_Z, MAX_HOVER_Z));
+}
+
+// ---------------------------------------------------------------------------
+// Enable / disable based on region support
+// ---------------------------------------------------------------------------
+
+void LLFloaterQuickPrefs::updateAvatarZOffsetEditEnabled()
+{
+ bool enabled = gAgent.getRegion() && gAgent.getRegion()->avatarHoverHeightEnabled();
+
+ if (!enabled && isAgentAvatarValid())
+ {
+ enabled = true;
+ }
+
+ mAvatarZOffsetSlider->setEnabled(enabled);
+
+ if (enabled)
+ {
+ syncAvatarZOffsetFromPreferenceSetting();
+ }
+}
+
+void LLFloaterQuickPrefs::onRegionChanged()
+{
+ LLViewerRegion* region = gAgent.getRegion();
+ if (region && region->simulatorFeaturesReceived())
+ {
+ updateAvatarZOffsetEditEnabled();
+ }
+ else if (region)
+ {
+ region->setSimulatorFeaturesReceivedCallback(
+ boost::bind(&LLFloaterQuickPrefs::onSimulatorFeaturesReceived, this, _1));
+ }
+}
+
+void LLFloaterQuickPrefs::onSimulatorFeaturesReceived(const LLUUID& region_id)
+{
+ LLViewerRegion* region = gAgent.getRegion();
+ if (region && region->getRegionID() == region_id)
+ {
+ updateAvatarZOffsetEditEnabled();
+ }
+}
+
+void LLFloaterQuickPrefs::syncAvatarZOffsetFromPreferenceSetting()
+{
+ F32 value = gSavedPerAccountSettings.getF32("AvatarHoverOffsetZ");
+ mAvatarZOffsetSlider->setValue(value, false); // false = no commit signal
+}
diff --git a/indra/newview/llquickprefs.h b/indra/newview/llquickprefs.h
new file mode 100644
index 0000000000..0ef56a4299
--- /dev/null
+++ b/indra/newview/llquickprefs.h
@@ -0,0 +1,81 @@
+/**
+ * @file llquickprefs.h
+ * @brief Quick Preferences floater: hover height and bandwidth sliders.
+ *
+ * Ported from Firestorm Viewer (quickprefs.h / quickprefs.cpp).
+ * Original authors: WoLf Loonie, Zi Ree, Ansariel Hiller @ Second Life.
+ *
+ * $LicenseInfo:firstyear=2011&license=viewerlgpl$
+ * Phoenix Firestorm Viewer Source Code
+ * Copyright (C) 2011, WoLf Loonie @ Second Life
+ *
+ * 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.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLQUICKPREFS_H
+#define LL_LLQUICKPREFS_H
+
+#include "llfloater.h"
+
+class LLSliderCtrl;
+class LLTextBox;
+
+/**
+ * @class LLFloaterQuickPrefs
+ *
+ * A lightweight "Quick Preferences" panel that lets the user adjust commonly
+ * tweaked settings on the fly without opening the full Preferences dialog:
+ * - Avatar hover height
+ * - Maximum network bandwidth
+ *
+ * Hover-height logic is ported 1:1 from Firestorm's FloaterQuickPrefs so that
+ * live-preview while dragging, final commit on mouse-up, and region-feature
+ * gating all work exactly the same way.
+ */
+class LLFloaterQuickPrefs : public LLFloater
+{
+public:
+ LLFloaterQuickPrefs(const LLSD& key);
+ virtual ~LLFloaterQuickPrefs();
+
+ bool postBuild() override;
+ void onClose(bool app_quitting) override;
+
+private:
+ // ---- Hover height -------------------------------------------------------
+ LLSliderCtrl* mAvatarZOffsetSlider;
+
+ /** Called every frame while the slider thumb is being dragged.
+ * Sends a live (non-persistent) hover offset to the avatar so the user
+ * gets immediate visual feedback. */
+ void onAvatarZOffsetSliderMoved();
+
+ /** Called when the drag ends (mouse-up) or the user types a value.
+ * Persists the value to AvatarHoverOffsetZ. */
+ void onAvatarZOffsetFinalCommit();
+
+ /** Enable/disable the slider based on whether the current region supports
+ * server-side hover height. */
+ void updateAvatarZOffsetEditEnabled();
+
+ /** Called when the region changes so we can re-evaluate the above. */
+ void onRegionChanged();
+ void onSimulatorFeaturesReceived(const LLUUID& region_id);
+
+ /** Pulls AvatarHoverOffsetZ from saved settings and pushes it to the slider
+ * without triggering a commit (avoids feedback loops). */
+ void syncAvatarZOffsetFromPreferenceSetting();
+
+ boost::signals2::connection mRegionChangedSlot;
+};
+
+#endif // LL_LLQUICKPREFS_H
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index 98a97b9457..e5c272a264 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -207,6 +207,7 @@
#include "llstartuplistener.h"
#include "lltoolbarview.h"
#include "llexperiencelog.h"
+#include "llgroupcolormap.h" // group-based nameplate tinting
#include "llcleanup.h"
#include "llenvironment.h"
@@ -3344,6 +3345,9 @@ void LLStartUp::initExperiences()
boost::bind(&LLAgent::getRegionCapability, &gAgent, _1));
LLExperienceLog::instance().initialize();
+
+ // Load per-group nameplate colors for this account
+ LLGroupColorMap::getInstance()->loadFromDisk();
}
void LLStartUp::cleanupNameCache()
diff --git a/indra/newview/lltoolcomp.cpp b/indra/newview/lltoolcomp.cpp
index c6e59a81c9..ff6c692699 100644
--- a/indra/newview/lltoolcomp.cpp
+++ b/indra/newview/lltoolcomp.cpp
@@ -52,6 +52,7 @@
#include "llagentcamera.h"
#include "llfloatertools.h"
#include "llviewercontrol.h"
+#include "llviewercamera.h" // NaCl: mouselook right-click zoom
extern LLControlGroup gSavedSettings;
@@ -791,10 +792,42 @@ bool LLToolCompGun::handleRightMouseDown(S32 x, S32 y, MASK mask)
return false;
*/
+ // NaCl: Right-click + scroll wheel zoom in mouselook (ported from Firestorm).
+ // When right mouse is pressed without Alt, record the current FOV as the
+ // pre-zoom value (VX) and swap in the stored zoom target (VY).
+ // VZ == 1.0 means "currently zoomed", 0.0 means "not zoomed".
+ if (!(gKeyboard->currentMask(true) & MASK_ALT))
+ {
+ LLVector3 mlFovValues = gSavedSettings.getVector3("_NACL_MLFovValues");
+ F32 cameraAngle = gSavedSettings.getF32("CameraAngle");
+ mlFovValues.mV[VX] = cameraAngle; // save normal FOV
+ mlFovValues.mV[VZ] = 1.0f; // mark as zoomed
+ gSavedSettings.setVector3("_NACL_MLFovValues", mlFovValues);
+ gSavedSettings.setF32("CameraAngle", mlFovValues.mV[VY]); // apply zoom FOV
+ }
+ // NaCl End
+
// Returning true will suppress the context menu
return true;
}
+// NaCl: Right-click + scroll wheel zoom in mouselook (ported from Firestorm).
+// Restore the pre-zoom FOV when the right mouse button is released.
+bool LLToolCompGun::handleRightMouseUp(S32 x, S32 y, MASK mask)
+{
+ LLVector3 mlFovValues = gSavedSettings.getVector3("_NACL_MLFovValues");
+ F32 cameraAngle = gSavedSettings.getF32("CameraAngle");
+ if (mlFovValues.mV[VZ] == 1.0f) // only restore if we entered zoom
+ {
+ mlFovValues.mV[VY] = cameraAngle; // save last zoomed FOV for next right-click
+ mlFovValues.mV[VZ] = 0.0f; // mark as not zoomed
+ gSavedSettings.setVector3("_NACL_MLFovValues", mlFovValues);
+ gSavedSettings.setF32("CameraAngle", mlFovValues.mV[VX]); // restore normal FOV
+ }
+ return true;
+}
+// NaCl End
+
bool LLToolCompGun::handleMouseUp(S32 x, S32 y, MASK mask)
{
@@ -831,10 +864,28 @@ void LLToolCompGun::handleDeselect()
bool LLToolCompGun::handleScrollWheel(S32 x, S32 y, S32 clicks)
{
- if (clicks > 0)
+ // NaCl: Right-click + scroll wheel zoom in mouselook (ported from Firestorm).
+ // If currently zoomed (right mouse held, VZ == 1.0), adjust the zoom level
+ // with the scroll wheel. Otherwise fall through to the original behaviour.
+ LLVector3 mlFovValues = gSavedSettings.getVector3("_NACL_MLFovValues");
+ F32 cameraAngle = gSavedSettings.getF32("CameraAngle");
+ mlFovValues.mV[VY] = cameraAngle;
+ if (mlFovValues.mV[VZ] > 0.0f)
+ {
+ // Scroll up (clicks > 0) = narrower FOV (zoom in); scroll down = wider (zoom out).
+ mlFovValues.mV[VY] = llclamp(
+ mlFovValues.mV[VY] + (F32)(clicks * 0.1f),
+ LLViewerCamera::getInstance()->getMinView(),
+ LLViewerCamera::getInstance()->getMaxView());
+ gSavedSettings.setVector3("_NACL_MLFovValues", mlFovValues);
+ gSavedSettings.setF32("CameraAngle", mlFovValues.mV[VY]);
+ }
+ else if (clicks > 0 && gSavedSettings.getBOOL("FSScrollWheelExitsMouselook"))
{
+ // Not zoomed: scroll up exits mouselook (original behaviour, now gated by setting).
gAgentCamera.changeCameraToDefault();
-
}
+ // NaCl End
+
return true;
}
diff --git a/indra/newview/lltoolcomp.h b/indra/newview/lltoolcomp.h
index 4b945967d1..d868b2e9bf 100644
--- a/indra/newview/lltoolcomp.h
+++ b/indra/newview/lltoolcomp.h
@@ -53,6 +53,7 @@ public:
virtual bool handleHover(S32 x, S32 y, MASK mask) { return mCur->handleHover( x, y, mask ); }
virtual bool handleScrollWheel(S32 x, S32 y, S32 clicks) { return mCur->handleScrollWheel( x, y, clicks ); }
virtual bool handleRightMouseDown(S32 x, S32 y, MASK mask) { return mCur->handleRightMouseDown( x, y, mask ); }
+ virtual bool handleRightMouseUp(S32 x, S32 y, MASK mask) { return mCur->handleRightMouseUp( x, y, mask ); } // NaCl: mouselook zoom
virtual LLViewerObject* getEditingObject() { return mCur->getEditingObject(); }
virtual LLVector3d getEditingPointGlobal() { return mCur->getEditingPointGlobal(); }
@@ -228,6 +229,7 @@ public:
virtual bool handleMouseDown(S32 x, S32 y, MASK mask) override;
virtual bool handleDoubleClick(S32 x, S32 y, MASK mask) override;
virtual bool handleRightMouseDown(S32 x, S32 y, MASK mask) override;
+ virtual bool handleRightMouseUp(S32 x, S32 y, MASK mask) override; // NaCl: mouselook zoom
virtual bool handleMouseUp(S32 x, S32 y, MASK mask) override;
virtual bool handleScrollWheel(S32 x, S32 y, S32 clicks) override;
virtual void onMouseCaptureLost() override;
diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp
index fe2d44a401..7d97151e9d 100644
--- a/indra/newview/llviewerdisplay.cpp
+++ b/indra/newview/llviewerdisplay.cpp
@@ -316,6 +316,24 @@ static void update_tp_display(bool minimized)
{
// Transition to REQUESTED. Viewer has sent some kind
// of TeleportRequest to the source simulator
+
+ // NaCl: Right-click + scroll wheel zoom in mouselook (ported from Firestorm).
+ // Reset the mouselook zoom state on teleport so we don't get stuck at
+ // the zoomed FOV after arriving at the destination.
+ if (gAgentCamera.cameraMouselook())
+ {
+ LLVector3 mlFovValues = gSavedSettings.getVector3("_NACL_MLFovValues");
+ bool wasZoomed = (mlFovValues.mV[VZ] > 0.0f);
+ mlFovValues.mV[VZ] = 0.0f; // clear "currently zoomed" flag
+ gSavedSettings.setVector3("_NACL_MLFovValues", mlFovValues);
+ if (wasZoomed)
+ {
+ // Restore the normal (pre-zoom) FOV
+ gSavedSettings.setF32("CameraAngle", mlFovValues.mV[VX]);
+ }
+ }
+ // NaCl End
+
gTeleportDisplayTimer.reset();
const std::string& msg = LLAgent::sTeleportProgressMessages["requesting"];
LL_INFOS("Teleport") << "A teleport request has been sent, setting state to TELEPORT_REQUESTED" << LL_ENDL;
diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp
index 50cc2442cb..2a2542ff57 100644
--- a/indra/newview/llviewerfloaterreg.cpp
+++ b/indra/newview/llviewerfloaterreg.cpp
@@ -85,6 +85,7 @@
#include "llfloatergroups.h"
#include "llfloaterhelpbrowser.h"
#include "llfloaterhoverheight.h"
+#include "llquickprefs.h" // Quick Preferences floater (Firestorm port)
#include "mpfloatertuning.h"
#include "llfloaterhowto.h"
#include "llfloaterhud.h"
@@ -393,6 +394,7 @@ void LLViewerFloaterReg::registerFloaters()
LLFloaterReg::add("help_browser", "floater_help_browser.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterHelpBrowser>);
LLFloaterReg::add("edit_hover_height", "floater_edit_hover_height.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterHoverHeight>);
+ LLFloaterReg::add("quick_prefs", "floater_quick_prefs.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterQuickPrefs>); // Firestorm port
LLFloaterReg::add("hud", "floater_hud.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterHUD>);
LLFloaterReg::add("mpv_performance", "floater_mp_performance.xml", (LLFloaterBuildFunc)&
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index 8dab1e42d0..4632800e2d 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -4784,6 +4784,19 @@ class LLViewMouselook : public view_listener_t
}
else
{
+ // NaCl: Right-click + scroll wheel zoom in mouselook (ported from Firestorm).
+ // If we were zoomed when the user toggles out of mouselook, restore the
+ // normal (pre-zoom) FOV before switching back to the default camera.
+ LLVector3 mlFovValues = gSavedSettings.getVector3("_NACL_MLFovValues");
+ F32 cameraAngle = gSavedSettings.getF32("CameraAngle");
+ if (mlFovValues.mV[VZ] > 0.0f)
+ {
+ mlFovValues.mV[VY] = cameraAngle; // preserve last zoomed FOV
+ mlFovValues.mV[VZ] = 0.0f;
+ gSavedSettings.setVector3("_NACL_MLFovValues", mlFovValues);
+ gSavedSettings.setF32("CameraAngle", mlFovValues.mV[VX]); // restore normal FOV
+ }
+ // NaCl End
gAgentCamera.changeCameraToDefault();
}
return true;
@@ -7154,6 +7167,13 @@ void handle_hover_height()
LLFloaterReg::showInstance("edit_hover_height");
}
+// Firestorm port: Quick Preferences floater (hover height, bandwidth)
+void handle_quick_prefs()
+{
+ LLFloaterReg::toggleInstance("quick_prefs");
+}
+// End Firestorm port
+
void handle_edit_physics()
{
LLFloaterSidePanelContainer::showPanel("appearance", LLSD().with("type", "edit_physics"));
@@ -9983,6 +10003,7 @@ void initialize_menus()
commit.add("EditShape", boost::bind(&handle_edit_shape));
commit.add("HoverHeight", boost::bind(&handle_hover_height));
commit.add("EditPhysics", boost::bind(&handle_edit_physics));
+ commit.add("QuickPrefs", boost::bind(&handle_quick_prefs)); // Firestorm port
// View menu
view_listener_t::addMenu(new LLViewMouselook(), "View.Mouselook");
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index 384b45ca4c..16f2064d1b 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -44,6 +44,7 @@
#include "llanimationstates.h"
#include "llavatarnamecache.h"
#include "llavatarpropertiesprocessor.h"
+#include "llgroupcolormap.h" // group-based nameplate tinting
#include "llavatarrendernotifier.h"
#include "llcontrolavatar.h"
#include "llexperiencecache.h"
@@ -674,6 +675,8 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,
mNameAlpha(0.f),
mRenderGroupTitles(sRenderGroupTitles),
mNameCloud(false),
+ mActiveGroupID(),
+ mGroupFetchPending(false),
mFirstTEMessageReceived( false ),
mFirstAppearanceMessageReceived( false ),
mCulled( false ),
@@ -3650,7 +3653,26 @@ void LLVOAvatar::idleUpdateNameTagText(bool new_name)
mNameAppearance = is_appearance;
mNameFriend = is_friend;
mNameCloud = is_cloud;
- mTitle = title ? title->getString() : "";
+
+ // Group-based nameplate tinting: when the title NameValue changes on a
+ // non-self avatar it means their active group (or role) changed. Fire
+ // a lightweight AvatarPropertiesRequest so the AvatarGroupsReply arrives
+ // and we can discover the active group UUID. We register ourselves as an
+ // observer for APT_GROUPS in processProperties() below.
+ const std::string new_title = title ? title->getString() : "";
+ if (!isSelf() && new_title != mTitle)
+ {
+ // Reset cached group UUID - it will be repopulated by the reply.
+ mActiveGroupID.setNull();
+ if (!mGroupFetchPending)
+ {
+ mGroupFetchPending = true;
+ LLAvatarPropertiesProcessor::getInstance()->addObserver(getID(), this);
+ LLAvatarPropertiesProcessor::getInstance()->sendAvatarLegacyPropertiesRequest(getID());
+ }
+ }
+
+ mTitle = new_title;
LLStringFn::replace_ascii_controlchars(mTitle,LL_UNKNOWN_CHAR);
new_name = true;
}
@@ -3883,7 +3905,80 @@ LLColor4 LLVOAvatar::getNameTagColor(bool is_friend)
// ...not using display names
color_name = "NameTagLegacy";
}
- return LLUIColorTable::getInstance()->getColor( color_name );
+
+ LLColor4 base_color = LLUIColorTable::getInstance()->getColor(color_name);
+
+ // Group-based nameplate tinting: override with the group color if one is set.
+ // For self, the active group UUID is always available via gAgent.
+ // For others, it is populated asynchronously via AvatarGroupsReply.
+ LLUUID active_group;
+ if (isSelf())
+ {
+ active_group = gAgent.getGroupID();
+ }
+ else
+ {
+ active_group = mActiveGroupID;
+ }
+
+ if (active_group.notNull())
+ {
+ LLColor4 group_color = LLGroupColorMap::getInstance()->getGroupColor(active_group);
+ if (group_color.mV[VW] >= 0.01f) // non-transparent = has a color set
+ {
+ return group_color;
+ }
+ }
+
+ return base_color;
+}
+
+// ---------------------------------------------------------------------------
+// Group-based nameplate tinting: observer callback
+// ---------------------------------------------------------------------------
+
+void LLVOAvatar::processProperties(void* data, EAvatarProcessorType type)
+{
+ if (type != APT_GROUPS)
+ return;
+
+ LLAvatarGroups* groups = static_cast<LLAvatarGroups*>(data);
+ if (!groups || groups->avatar_id != getID())
+ return;
+
+ // Un-register ourselves — we only need this one reply per title change.
+ LLAvatarPropertiesProcessor::getInstance()->removeObserver(getID(), this);
+ mGroupFetchPending = false;
+
+ // The active group is the one whose GroupTitle matches the avatar's
+ // current Title NameValue (mTitle). Each avatar can only have one
+ // selected role title displayed at a time, so this match is unambiguous.
+ for (const auto& gd : groups->group_list)
+ {
+ if (gd.group_title == mTitle)
+ {
+ mActiveGroupID = gd.group_id;
+ // Force nametag rebuild so new color is shown immediately.
+ clearNameTag();
+ return;
+ }
+ }
+
+ // No match found (e.g. avatar has no active group or title is blank).
+ mActiveGroupID.setNull();
+ clearNameTag();
+}
+
+// Request the group list for a non-self avatar so we can resolve their
+// active group UUID. Called from idleUpdateNameTagText on title change.
+void LLVOAvatar::sendAvatarGroupsRequest()
+{
+ if (!isSelf() && !mGroupFetchPending)
+ {
+ mGroupFetchPending = true;
+ LLAvatarPropertiesProcessor::getInstance()->addObserver(getID(), this);
+ LLAvatarPropertiesProcessor::getInstance()->sendAvatarLegacyPropertiesRequest(getID());
+ }
}
void LLVOAvatar::idleUpdateBelowWater()
diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h
index fc3a97a25d..0c3b82c886 100644
--- a/indra/newview/llvoavatar.h
+++ b/indra/newview/llvoavatar.h
@@ -36,6 +36,7 @@
#include <boost/signals2/trackable.hpp>
#include "llavatarappearance.h"
+#include "llavatarpropertiesprocessor.h" // LLAvatarPropertiesObserver (group tinting)
#include "llchat.h"
#include "lldrawpoolalpha.h"
#include "llviewerobject.h"
@@ -87,6 +88,7 @@ extern U32 gFrameCount;
class LLVOAvatar :
public LLAvatarAppearance,
public LLViewerObject,
+ public LLAvatarPropertiesObserver, // group-based nameplate tinting
public boost::signals2::trackable
{
LL_ALIGN_NEW;
@@ -292,6 +294,11 @@ public:
void idleUpdateNameTagAlpha(bool new_name, F32 alpha);
LLColor4 getNameTagColor(bool is_friend);
void clearNameTag();
+
+ // LLAvatarPropertiesObserver: receives APT_GROUPS reply for group-tint lookup
+ /*virtual*/ void processProperties(void* data, EAvatarProcessorType type) override;
+ void sendAvatarGroupsRequest();
+ const LLUUID& getActiveGroupID() const { return mActiveGroupID; }
static void invalidateNameTag(const LLUUID& agent_id);
// force all name tags to rebuild, useful when display names turned on/off
static void invalidateNameTags();
@@ -1122,6 +1129,10 @@ private:
F32 mNameAlpha;
S32 mRenderGroupTitles;
+ // Group-based nameplate tinting
+ LLUUID mActiveGroupID; // active group UUID; null until known
+ bool mGroupFetchPending; // true while AvatarPropertiesRequest is in flight
+
//--------------------------------------------------------------------
// Display the name (then optionally fade it out)
//--------------------------------------------------------------------
diff --git a/indra/newview/skins/default/xui/en/floater_quick_prefs.xml b/indra/newview/skins/default/xui/en/floater_quick_prefs.xml
new file mode 100644
index 0000000000..8b20fda6f5
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_quick_prefs.xml
@@ -0,0 +1,85 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<!--
+ floater_quick_prefs.xml
+ Quick Preferences panel – ported from Firestorm Viewer.
+ Provides on-the-fly access to avatar hover height and max bandwidth.
+-->
+<floater
+ positioning="cascading"
+ can_minimize="true"
+ can_close="true"
+ can_resize="false"
+ height="96"
+ width="320"
+ layout="topleft"
+ name="quick_prefs"
+ single_instance="true"
+ help_topic="quick_prefs"
+ save_rect="true"
+ save_visibility="false"
+ title="QUICK PREFERENCES">
+
+ <!-- ── Hover Height ─────────────────────────────────────────────────── -->
+ <text
+ type="string"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="10"
+ top="28"
+ width="100"
+ name="HoverHeightLabel"
+ tool_tip="Adjust your avatar's hover height above the ground">
+ Hover Height:
+ </text>
+
+ <slider
+ control_name="HoverHeightSlider"
+ decimal_digits="3"
+ enabled="false"
+ can_edit_text="true"
+ follows="left|right|top"
+ height="16"
+ increment="0.001"
+ initial_value="0.0"
+ label_width="0"
+ layout="topleft"
+ left="110"
+ right="-10"
+ top="30"
+ name="HoverHeightSlider"
+ tool_tip="Drag to set your avatar hover height (-3.0 to +3.0 m)" />
+
+ <!-- ── Max Bandwidth ────────────────────────────────────────────────── -->
+ <text
+ type="string"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="10"
+ top_pad="12"
+ width="100"
+ name="MaxBandwidthLabel"
+ tool_tip="Set the maximum network bandwidth in Kbps">
+ Max Bandwidth:
+ </text>
+
+ <slider
+ control_name="ThrottleBandwidthKBPS"
+ decimal_digits="0"
+ can_edit_text="true"
+ follows="left|right|top"
+ height="16"
+ increment="50"
+ initial_value="500"
+ max_val="3000"
+ min_val="50"
+ label_width="0"
+ layout="topleft"
+ left="110"
+ right="-10"
+ top_delta="-2"
+ name="max_bandwidth"
+ tool_tip="Network bandwidth in Kbps (50 – 3000)" />
+
+</floater>
diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml
index 5335e0f8bd..48ee13bf21 100644
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -206,6 +206,14 @@
function="Edit.EnableHoverHeight" />
</menu_item_call>
<menu_item_call
+ label="Quick Preferences..."
+ layout="topleft"
+ name="Quick Preferences"
+ shortcut="alt|control|Q">
+ <menu_item_call.on_click
+ function="QuickPrefs" />
+ </menu_item_call>
+ <menu_item_call
label="Edit shape..."
layout="topleft"
name="Edit My Shape">
diff --git a/indra/newview/skins/default/xui/en/panel_group_general.xml b/indra/newview/skins/default/xui/en/panel_group_general.xml
index d97411f5ab..e0fec0f5fd 100644
--- a/indra/newview/skins/default/xui/en/panel_group_general.xml
+++ b/indra/newview/skins/default/xui/en/panel_group_general.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel
label="General"
- height="420"
+ height="580"
width="304"
class="panel_group_general"
name="general_tab">
@@ -95,6 +95,53 @@ Hover your mouse over the options for more help.
visible="true"
width="120" />
</panel>
+
+ <!-- Nameplate tinting: isolated panel, placed after group_info_top -->
+ <panel
+ name="nametag_color_panel"
+ follows="left|right|top"
+ layout="topleft"
+ left="0"
+ top="129"
+ width="304"
+ height="36"
+ background_visible="false">
+ <text
+ type="string"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="5"
+ top="2"
+ width="160"
+ name="nametag_color_label"
+ text_color="EmphasisColor">
+ Nameplate Color:
+ </text>
+ <color_swatch
+ can_apply_immediately="false"
+ follows="left|top"
+ height="22"
+ label=""
+ label_height="0"
+ layout="topleft"
+ left="170"
+ top="2"
+ name="group_nametag_color"
+ tool_tip="Click to set nameplate color for this group"
+ width="54" />
+ <button
+ follows="left|top"
+ height="22"
+ label="Clear"
+ layout="topleft"
+ left="230"
+ top="2"
+ name="group_nametag_color_clear"
+ tool_tip="Remove the nameplate color for this group"
+ width="60" />
+ </panel>
+
<text_editor
type="string"
follows="left|top|right"
@@ -104,7 +151,7 @@ Hover your mouse over the options for more help.
max_length="511"
name="charter"
parse_urls="true"
- top="105"
+ top="170"
right="-4"
bg_readonly_color="DkGray2"
text_readonly_color="White"
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index 6e48577064..418dd7ef45 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -4219,6 +4219,7 @@ name="Command_360_Capture_Label">360 snapshot</string>
<string name="Command_Picks_Label">Picks</string>
<string name="Command_Places_Label">Places</string>
<string name="Command_Preferences_Label">Preferences</string>
+ <string name="Command_QuickPrefs_Label">Quick Prefs</string>
<string name="Command_Profile_Label">Profile</string>
<string name="Command_Report_Abuse_Label">Report Abuse</string>
<string name="Command_Search_Label">Search</string>
@@ -4254,6 +4255,7 @@ name="Command_360_Capture_Tooltip">Capture a 360 equirectangular image</string>
<string name="Command_Picks_Tooltip">Places to show as favorites in your profile</string>
<string name="Command_Places_Tooltip">Places you've saved</string>
<string name="Command_Preferences_Tooltip">Preferences</string>
+ <string name="Command_QuickPrefs_Tooltip">Quickly adjust hover height and bandwidth</string>
<string name="Command_Profile_Tooltip">Edit or view your profile</string>
<string name="Command_Report_Abuse_Tooltip">Report Abuse</string>
<string name="Command_Search_Tooltip">Find places, events, people</string>