Bug 1880323 [Linux] Make nsWindow::GetTitlebarRect() thread safe r=emilio

- Implement nsWindow::SetTitlebarRect() and update titlebar area when nsWindow is resized.
- Make GetTitlebarRect() to only return value calculated at SetTitlebarRect().
- Protect both by mutex to make it thread safe.

Differential Revision: https://phabricator.services.mozilla.com/D202565
This commit is contained in:
stransky 2024-02-23 12:13:38 +00:00
parent e8f95a5a4c
commit f6fda47ff4
2 changed files with 24 additions and 22 deletions

View file

@ -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();
}
}

View file

@ -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<bool, mozilla::Relaxed> mDrawInTitlebar{false};
bool mDrawInTitlebar = false;
mozilla::Mutex mTitlebarRectMutex;
LayoutDeviceIntRect mTitlebarRect MOZ_GUARDED_BY(mTitlebarRectMutex);
mozilla::Mutex mDestroyMutex;