qt/wayland: detach subsurface buffer on hide so inactive tabs don't ghost
All panes' wl_subsurfaces share the top-level QWindow's wl_surface
as their parent (commit ef4df3b8d). When a tab switches, Qt
hides the inactive pane's GhosttySurface widgets but the
subsurfaces stayed attached to the top-level with their last
buffers — so the old tab's terminal pixels showed through wherever
the new tab's content didn't cover them.
Add SubsurfacePresenter::hide() which attaches a NULL buffer to
the child surface (= no contribution to compositor frame). Call it
from QEvent::Hide alongside the existing
ghostty_surface_set_occlusion(false) which already throttles
libghostty's renderer thread.
On the next Show + present, the buffer reattaches and the pane
becomes visible again. ghostty_surface_set_occlusion(true) on
Show re-enables the renderer so it produces that first frame.
Co-Authored-By: claude-flow <ruv@ruv.net>
pull/12846/head
parent
ef4df3b8da
commit
52d4ee4136
|
|
@ -464,6 +464,14 @@ bool GhosttySurface::event(QEvent *e) {
|
|||
}
|
||||
} else if (e->type() == QEvent::Hide) {
|
||||
ghostty_surface_set_occlusion(m_surface, false);
|
||||
// Detach the subsurface buffer so this pane's last frame
|
||||
// doesn't ghost on top of whatever the now-active tab is
|
||||
// showing. The next Show + render reattaches a buffer and
|
||||
// makes it visible again.
|
||||
if (m_subsurfacePresenter) {
|
||||
m_subsurfacePresenter->hide();
|
||||
forceParentCommit();
|
||||
}
|
||||
}
|
||||
}
|
||||
return QWidget::event(e);
|
||||
|
|
|
|||
|
|
@ -487,4 +487,14 @@ void SubsurfacePresenter::setPosition(int x, int y) {
|
|||
wl_display_flush(m_display);
|
||||
}
|
||||
|
||||
void SubsurfacePresenter::hide() {
|
||||
if (!m_childSurface) return;
|
||||
// Attach NULL = no buffer. After commit + parent commit, the
|
||||
// subsurface contributes nothing to the compositor's frame.
|
||||
// Caller is responsible for forceParentCommit on its side.
|
||||
wl_surface_attach(m_childSurface, nullptr, 0, 0);
|
||||
wl_surface_commit(m_childSurface);
|
||||
wl_display_flush(m_display);
|
||||
}
|
||||
|
||||
} // namespace wayland
|
||||
|
|
|
|||
|
|
@ -134,6 +134,14 @@ public:
|
|||
// position to apply. No-op if the position hasn't changed.
|
||||
void setPosition(int x, int y);
|
||||
|
||||
// Detach the currently-attached buffer so the subsurface becomes
|
||||
// invisible. Called when the owning GhosttySurface hides (tab
|
||||
// switch) so the inactive pane's pixels don't ghost on top of
|
||||
// whatever the active tab is showing in the same on-screen
|
||||
// region. The next presentDmabuf call re-attaches a buffer and
|
||||
// the subsurface becomes visible again.
|
||||
void hide();
|
||||
|
||||
// Called from the wp_fractional_scale_v1.preferred_scale event.
|
||||
// Public so the C-style listener struct at file scope in the .cpp
|
||||
// can name it; not part of the API for other call sites.
|
||||
|
|
|
|||
Loading…
Reference in New Issue