summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorErik Kundiman <erik@megapahit.org>2026-10-24 14:27:02 +0800
committerErik Kundiman <erik@megapahit.org>2026-10-24 14:27:02 +0800
commit15b3c7ba741c64d41e52fbff4074c19ee96ae39b (patch)
tree0c56e55fac9bfc58dba5b07fc82bffbb0d4731f2
parent57552eb04bdbb6db875cf414ccac552934240d7c (diff)
parentcb5dd9181198cab5fadc71fa548201af0234128f (diff)
Merge tag 'Second_Life_Release#cb5dd918-26.5' into 26.526.5
-rw-r--r--indra/llui/llclipboard.cpp5
-rw-r--r--indra/llwebrtc/llwebrtc.cpp24
-rw-r--r--indra/llwindow/llopenglview-objc.mm1
-rw-r--r--indra/llwindow/llwindowmacosx-objc.h2
-rw-r--r--indra/llwindow/llwindowmacosx-objc.mm4
-rw-r--r--indra/llwindow/llwindowmacosx.cpp26
-rw-r--r--indra/newview/app_settings/settings.xml2
-rw-r--r--indra/newview/llagent.cpp9
-rw-r--r--indra/newview/llvoicewebrtc.cpp6
9 files changed, 42 insertions, 37 deletions
diff --git a/indra/llui/llclipboard.cpp b/indra/llui/llclipboard.cpp
index 64896ccfcb..0483da001f 100644
--- a/indra/llui/llclipboard.cpp
+++ b/indra/llui/llclipboard.cpp
@@ -132,6 +132,11 @@ bool LLClipboard::addToClipboard(const LLWString &src, S32 pos, S32 len, bool us
LL_WARNS() << "Can't add the substring to clipboard: " << e.what() << LL_ENDL;
return false;
}
+
+ // Clipboards cannot contain NULL characters, so remove them first so they
+ // do not truncate the string.
+ mString.erase(std::remove(mString.begin(), mString.end(), 0), mString.end());
+
return (use_primary ? LLView::getWindow()->copyTextToPrimary(mString) : LLView::getWindow()->copyTextToClipboard(mString));
}
diff --git a/indra/llwebrtc/llwebrtc.cpp b/indra/llwebrtc/llwebrtc.cpp
index ff68437cf3..5af456a6a3 100644
--- a/indra/llwebrtc/llwebrtc.cpp
+++ b/indra/llwebrtc/llwebrtc.cpp
@@ -678,11 +678,11 @@ void LLWebRTCImpl::unsetDevicesObserver(LLWebRTCDevicesObserver *observer)
}
// must be run in the worker thread. Selects the configured capture device and
-// starts recording. By default capture runs the whole time voice is enabled
-// (never stopped for mute or between calls, so the AEC never cold-starts -- no
-// hiss on unmute), so this is a no-op when already recording. With "stop capture
-// while muted" it's only started while unmuted and once a connection's audio is
-// established. Device changes go through workerDeployDevices(), which stops
+// starts recording. By default capture only runs while unmuted and once a
+// connection's audio is established. With "stop capture while muted" disabled,
+// capture runs the whole time voice is enabled (never stopped for mute or between
+// calls, so the AEC never cold-starts -- no hiss on unmute), so this is a no-op
+// when already recording. Device changes go through workerDeployDevices(), which stops
// recording first to force a clean re-select; voice off goes through setVoiceEnabled(false).
void LLWebRTCImpl::workerStartRecording()
{
@@ -886,8 +886,8 @@ void LLWebRTCImpl::setVoiceEnabled(bool enable)
}
if (enable)
{
- // Voice on: start the capture device (by default it then stays
- // running across calls and mute/unmute), and start playout if
+ // Voice on: start the capture device (with "stop capture while muted" disabled
+ // it then stays running across calls and mute/unmute), and start playout if
// there's already a connection to render.
mDeviceModule->Init();
workerDeployDevices();
@@ -1092,11 +1092,11 @@ void LLWebRTCImpl::setMute(bool mute, int delay_ms)
void LLWebRTCImpl::intSetMute(bool mute, int delay_ms)
{
// Mute by zeroing the captured (post-APM) gain; the sender track is also
- // disabled per connection (see LLWebRTCPeerConnectionImpl::setMute). By
- // default the capture device stays running for the whole session, so
- // muting/unmuting never stops or starts it -- that's what avoids the AEC
- // cold-start hiss on unmute. With "stop capture while muted", it's stopped
- // after the mute delay and restarted on unmute (below).
+ // disabled per connection (see LLWebRTCPeerConnectionImpl::setMute). By
+ // default the capture device stops after the mute delay and restarts on
+ // unmute. With "stop capture while muted" disabled, it stays running for
+ // the whole session, so muting/unmuting never stops or starts it -- that's
+ // what avoids the AEC cold-start hiss on unmute.
if (mPeerCustomProcessor)
{
mPeerCustomProcessor->setGain(mMute ? 0.0f : mGain);
diff --git a/indra/llwindow/llopenglview-objc.mm b/indra/llwindow/llopenglview-objc.mm
index 7763f5ea0d..c5f355bef7 100644
--- a/indra/llwindow/llopenglview-objc.mm
+++ b/indra/llwindow/llopenglview-objc.mm
@@ -389,6 +389,7 @@ attributedStringInfo getSegments(NSAttributedString *str)
[self registerForDraggedTypes:[NSArray arrayWithObject:NSPasteboardTypeURL]];
+ [glContext release]; // setOpenGLContext: retains the context for the view.
return self;
}
diff --git a/indra/llwindow/llwindowmacosx-objc.h b/indra/llwindow/llwindowmacosx-objc.h
index e3a1253c1f..a22492c338 100644
--- a/indra/llwindow/llwindowmacosx-objc.h
+++ b/indra/llwindow/llwindowmacosx-objc.h
@@ -108,7 +108,7 @@ NSWindowRef createNSWindow(int x, int y, int width, int height);
#include <OpenGL/OpenGL.h>
GLViewRef createOpenGLView(NSWindowRef window, unsigned int samples, bool vsync);
-void glSwapBuffers(void* context);
+void glSwapBuffers(GLViewRef view);
CGLContextObj getCGLContextObj(GLViewRef view);
unsigned long getVramSize(GLViewRef view);
float getDeviceUnitSize(GLViewRef view);
diff --git a/indra/llwindow/llwindowmacosx-objc.mm b/indra/llwindow/llwindowmacosx-objc.mm
index 85208a5ac3..c93f191256 100644
--- a/indra/llwindow/llwindowmacosx-objc.mm
+++ b/indra/llwindow/llwindowmacosx-objc.mm
@@ -238,9 +238,9 @@ GLViewRef createOpenGLView(NSWindowRef window, unsigned int samples, bool vsync)
return glview;
}
-void glSwapBuffers(void* context)
+void glSwapBuffers(GLViewRef view)
{
- [(NSOpenGLContext*)context flushBuffer];
+ [[(LLOpenGLView*)view openGLContext] flushBuffer];
}
CGLContextObj getCGLContextObj(GLViewRef view)
diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp
index fa0816c457..500ed5ef87 100644
--- a/indra/llwindow/llwindowmacosx.cpp
+++ b/indra/llwindow/llwindowmacosx.cpp
@@ -876,15 +876,12 @@ void LLWindowMacOSX::destroyContext()
// We don't have a context
return;
}
- // Unhook the GL context from any drawable it may have
- if(mContext != NULL)
- {
- LL_DEBUGS("Window") << "destroyContext: unhooking drawable " << LL_ENDL;
- CGLSetCurrentContext(NULL);
- }
-
// Clean up remaining GL state before blowing away window
+ CGLSetCurrentContext(mContext);
gGLManager.shutdownGL();
+ CGLSetCurrentContext(NULL);
+ // The Cocoa view owns this context and releases it in removeGLView().
+ mContext = NULL;
// Clean up the pixel format
if(mPixelFormat != NULL)
@@ -893,12 +890,6 @@ void LLWindowMacOSX::destroyContext()
mPixelFormat = NULL;
}
- // Clean up the GL context
- if(mContext != NULL)
- {
- CGLDestroyContext(mContext);
- }
-
// Destroy our LLOpenGLView
if(mGLView != NULL)
{
@@ -1019,6 +1010,8 @@ void LLWindowMacOSX::gatherInput(bool app_has_focus)
{
updateCursor();
LLGameControl::processEvents(app_has_focus);
+ // Cocoa event handling can change the current context between frames.
+ restoreGLContext();
}
bool LLWindowMacOSX::getPosition(LLCoordScreen *position) const
@@ -1140,12 +1133,17 @@ bool LLWindowMacOSX::setSizeImpl(const LLCoordWindow size)
void LLWindowMacOSX::swapBuffers()
{
- CGLFlushDrawable(mContext);
+ if (mContext)
+ {
+ llassert(mGLView && getCGLContextObj(mGLView) == mContext);
+ glSwapBuffers(mGLView);
+ }
}
void LLWindowMacOSX::restoreGLContext()
{
CGLSetCurrentContext(mContext);
+ llassert(CGLGetCurrentContext() == mContext);
}
F32 LLWindowMacOSX::getGamma() const
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 22c5fa8b2d..029bed25b3 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -17690,7 +17690,7 @@
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
- <string>Boolean</string>
+ <string>S32</string>
<key>Value</key>
<integer>1</integer>
</map>
diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index 9a553fab4d..3301224832 100644
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -2537,6 +2537,11 @@ void LLAgent::endAnimationUpdateUI()
LLFloaterCamera::onAvatarEditingAppearance(true);
}
+ // Sync before updating attachment visibility
+ // Don't let this be called more than once if the camera
+ // mode hasn't changed. --JC
+ gAgentCamera.updateLastCamera();
+
if (isAgentAvatarValid())
{
gAgentAvatarp->updateAttachmentVisibility(gAgentCamera.getCameraMode());
@@ -2546,10 +2551,6 @@ void LLAgent::endAnimationUpdateUI()
{
gFloaterTools->dirty();
}
-
- // Don't let this be called more than once if the camera
- // mode hasn't changed. --JC
- gAgentCamera.updateLastCamera();
}
boost::signals2::connection LLAgent::setMouselookModeInCallback( const camera_signal_t::slot_type& cb )
diff --git a/indra/newview/llvoicewebrtc.cpp b/indra/newview/llvoicewebrtc.cpp
index 976f5bc42b..a06bffa3fb 100644
--- a/indra/newview/llvoicewebrtc.cpp
+++ b/indra/newview/llvoicewebrtc.cpp
@@ -324,11 +324,11 @@ void LLWebRTCVoiceClient::initWebRTC()
{
if (mWebRTCDeviceInterface)
{
- mWebRTCDeviceInterface->setStopCaptureOnMute(new_val.asBoolean());
+ mWebRTCDeviceInterface->setStopCaptureOnMute(new_val.asInteger());
}
});
}
- mWebRTCDeviceInterface->setStopCaptureOnMute(gSavedSettings.getBOOL("StopMicCaptureWhenMuted"));
+ mWebRTCDeviceInterface->setStopCaptureOnMute(gSavedSettings.getS32("StopMicCaptureWhenMuted"));
refreshDeviceLists();
}
@@ -1757,7 +1757,7 @@ void LLWebRTCVoiceClient::setMuteMic(bool muted)
mMuteMic = muted;
- if (mIsInTuningMode &&!gSavedSettings.getBOOL("StopMicCaptureWhenMuted"))
+ if (mIsInTuningMode &&!gSavedSettings.getS32("StopMicCaptureWhenMuted"))
{
return;
}