diff --git a/widget/gtk/nsWindow.cpp b/widget/gtk/nsWindow.cpp index 4d88b24e5fff..1bf159d6348a 100644 --- a/widget/gtk/nsWindow.cpp +++ b/widget/gtk/nsWindow.cpp @@ -390,7 +390,8 @@ static void GtkWindowSetTransientFor(GtkWindow* aWindow, GtkWindow* aParent) { } nsWindow::nsWindow() - : mDestroyMutex("nsWindow::mDestroyMutex"), + : mTitlebarRectMutex("nsWindow::mTitlebarRectMutex"), + mDestroyMutex("nsWindow::mDestroyMutex"), mIsDestroyed(false), mIsShown(false), mNeedsShow(false), @@ -5360,6 +5361,8 @@ void nsWindow::OnWindowStateEvent(GtkWidget* aWidget, } else { ClearTransparencyBitmap(); } + } else { + SetTitlebarRect(); } } @@ -7040,6 +7043,8 @@ void nsWindow::UpdateTopLevelOpaqueRegion() { moz_container_wayland_update_opaque_region(mContainer, radius); } #endif + + SetTitlebarRect(); } bool nsWindow::IsChromeWindowTitlebar() { @@ -7215,22 +7220,20 @@ nsresult nsWindow::UpdateTranslucentWindowAlphaInternal(const nsIntRect& aRect, #define TITLEBAR_HEIGHT 10 -LayoutDeviceIntRect nsWindow::GetTitlebarRect() { - // See NS_NATIVE_EGL_WINDOW why we can't block here. - auto ret = LayoutDeviceIntRect(); +void nsWindow::SetTitlebarRect() { + MutexAutoLock lock(mTitlebarRectMutex); - if (mDestroyMutex.TryLock()) { - if (mGdkWindow && mDrawInTitlebar) { - int height = 0; - if (DoDrawTilebarCorners()) { - height = GdkCeiledScaleFactor() * TITLEBAR_HEIGHT; - } - ret = LayoutDeviceIntRect(0, 0, mBounds.width, height); - } - mDestroyMutex.Unlock(); + if (!mGdkWindow || !DoDrawTilebarCorners()) { + mTitlebarRect = LayoutDeviceIntRect(); + return; } + mTitlebarRect = LayoutDeviceIntRect(0, 0, mBounds.width, + GdkCeiledScaleFactor() * TITLEBAR_HEIGHT); +} - return ret; +LayoutDeviceIntRect nsWindow::GetTitlebarRect() { + MutexAutoLock lock(mTitlebarRectMutex); + return mTitlebarRect; } void nsWindow::UpdateTitlebarTransparencyBitmap() { @@ -9018,6 +9021,8 @@ void nsWindow::SetDrawsInTitlebar(bool aState) { } else { ClearTransparencyBitmap(); } + } else { + SetTitlebarRect(); } } diff --git a/widget/gtk/nsWindow.h b/widget/gtk/nsWindow.h index 183b4a9e7ebf..e235d12c0837 100644 --- a/widget/gtk/nsWindow.h +++ b/widget/gtk/nsWindow.h @@ -367,6 +367,7 @@ class nsWindow final : public nsBaseWidget { nsresult SetNonClientMargins(const LayoutDeviceIntMargin&) override; void SetDrawsInTitlebar(bool aState); + void SetTitlebarRect(); mozilla::LayoutDeviceIntCoord GetTitlebarRadius(); LayoutDeviceIntRect GetTitlebarRect(); void UpdateWindowDraggingRegion( @@ -622,14 +623,10 @@ class nsWindow final : public nsBaseWidget { static GdkCursor* gsGtkCursorCache[eCursorCount]; // If true, draw our own window titlebar. - // - // Needs to be atomic because GetTitlebarRect() gets called from non-main - // threads. - // - // FIXME(emilio): GetTitlebarRect() reads other things that TSAN doesn't - // catch because mDrawInTitlebar is false on automation ~always. We should - // probably make GetTitlebarRect() simpler / properly thread-safe. - mozilla::Atomic mDrawInTitlebar{false}; + bool mDrawInTitlebar = false; + + mozilla::Mutex mTitlebarRectMutex; + LayoutDeviceIntRect mTitlebarRect MOZ_GUARDED_BY(mTitlebarRectMutex); mozilla::Mutex mDestroyMutex;