forked from mirrors/gecko-dev
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:
parent
e8f95a5a4c
commit
f6fda47ff4
2 changed files with 24 additions and 22 deletions
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue