tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit a383a1fc3258a12125040c927cffa631f126dfe3
parent 0de0fe7b26f4c4936e34ae3629331bba92321291
Author: stransky <stransky@redhat.com>
Date:   Thu, 20 Nov 2025 13:18:15 +0000

Bug 1998657 [Wayland] Set mIsVisible from frame callback r=emilio

Differential Revision: https://phabricator.services.mozilla.com/D273090

Diffstat:
Mwidget/gtk/WaylandSurface.cpp | 23+++++++++++++++++++++++
Mwidget/gtk/WaylandSurface.h | 6++++++
2 files changed, 29 insertions(+), 0 deletions(-)

diff --git a/widget/gtk/WaylandSurface.cpp b/widget/gtk/WaylandSurface.cpp @@ -389,6 +389,18 @@ void WaylandSurface::DisableDMABufFormatsLocked( mFormats = nullptr; } +void WaylandSurface::VisibleCallbackHandler() { + WaylandSurfaceLock lock(this); + LOGVERBOSE("WaylandSurface::VisibleCallbackHandler()"); + MozClearPointer(mVisibleFrameCallback, wl_callback_destroy); + // We can get frame callback after unmap due to queue sync. + // In this case just ignore it. + if (mIsMapped) { + mIsVisible = true; + mBufferAttached = true; + } +} + bool WaylandSurface::MapLocked(const WaylandSurfaceLock& aProofOfLock, wl_surface* aParentWLSurface, WaylandSurfaceLock* aParentWaylandSurfaceLock, @@ -436,6 +448,15 @@ bool WaylandSurface::MapLocked(const WaylandSurfaceLock& aProofOfLock, LOGWAYLAND(" register frame callback"); RequestFrameCallbackLocked(aProofOfLock); + MOZ_DIAGNOSTIC_ASSERT(!mVisibleFrameCallback); + static const struct wl_callback_listener listener{ + [](void* aData, struct wl_callback* callback, uint32_t time) { + RefPtr waylandSurface = static_cast<WaylandSurface*>(aData); + waylandSurface->VisibleCallbackHandler(); + }}; + mVisibleFrameCallback = wl_surface_frame(mSurface); + wl_callback_add_listener(mVisibleFrameCallback, &listener, this); + CommitLocked(aProofOfLock, /* aForceCommit */ true, /* aForceDisplayFlush */ true); @@ -538,6 +559,8 @@ void WaylandSurface::UnmapLocked(WaylandSurfaceLock& aSurfaceLock) { MozClearPointer(mPendingOpaqueRegion, wl_region_destroy); MozClearPointer(mOpaqueRegionFrameCallback, wl_callback_destroy); + MozClearPointer(mVisibleFrameCallback, wl_callback_destroy); + // Remove references to WaylandBuffers attached to mSurface, // we don't want to get any buffer release callback when we're unmapped. ReleaseAllWaylandTransactionsLocked(aSurfaceLock); diff --git a/widget/gtk/WaylandSurface.h b/widget/gtk/WaylandSurface.h @@ -80,6 +80,9 @@ class WaylandSurface final { // We've got first frame callback so we're really visible now. bool IsVisible() const { return mIsVisible; } + // Called from frame callback and sets the visible flag + void VisibleCallbackHandler(); + // Indicate that Wayland surface uses Gdk resources which // need to be released on main thread by GdkCleanUpLocked(). // It may be called after Unmap() to make sure @@ -374,6 +377,9 @@ class WaylandSurface final { bool mBufferTransformFlippedX = false; bool mBufferTransformFlippedY = false; + // Frame callback for mIsVisible flag + wl_callback* mVisibleFrameCallback = nullptr; + // Frame callbacks of this surface wl_callback* mFrameCallback = nullptr;