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:
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;