From b1fe084afef7d2f70d4cf555ad69170c53866099 Mon Sep 17 00:00:00 2001 From: Nathan Date: Mon, 25 May 2026 10:31:18 -0500 Subject: [PATCH] qt: repaint() inside resizeEvent so parent commit lands atomically MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit drainVulkan's update() schedules a paintEvent, but Qt may defer it past the resize cycle — meaning our sync-mode subsurface's cached state (the new-size dmabuf) doesn't apply until later. The old QPainter-blit path didn't have this gap because the terminal pixels and the resize commit were the SAME wl_surface.commit on the parent. repaint() forces the paintEvent synchronously inside syncSurfaceSize, which flushes Qt's backing store and commits the parent wl_surface right here. Our cached subsurface state applies in that same compositor frame. This restores the lockstep resize behavior of the original QPainter-only path, without giving up the zero-copy steady-state present. Co-Authored-By: claude-flow --- qt/src/GhosttySurface.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/qt/src/GhosttySurface.cpp b/qt/src/GhosttySurface.cpp index 23818e50a..648cf6c6d 100644 --- a/qt/src/GhosttySurface.cpp +++ b/qt/src/GhosttySurface.cpp @@ -249,6 +249,17 @@ void GhosttySurface::syncSurfaceSize() { m_subsurfacePresenter) { ghostty_surface_draw(m_surface); drainVulkan(); // runs presentDmabuf at the new size + commits + // Force an immediate paintEvent — repaint() bypasses Qt's + // event queue and runs synchronously, which (importantly) + // flushes Qt's backing store and commits the PARENT + // wl_surface right here. In sync mode our cached child + // subsurface state (the new-size dmabuf we just attached + // in drainVulkan) applies atomically with that parent + // commit, matching the old QPainter-blit path's atomicity: + // resize + new-size terminal content land in the same + // compositor frame instead of update()'s "next event loop + // turn" deferral. + repaint(); return; }