From 8883d60d0afa2ed9dd1ef68bc21fe1b9a65a59ff Mon Sep 17 00:00:00 2001 From: Christophe Besson Date: Mon, 7 Sep 2026 15:01:12 +0200 Subject: fix(client): break the Wayland ready-to-show deadlock MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some Wayland compositors never schedule a first paint for an unmapped surface, but the window stays unmapped until show() runs, which was gated entirely on that paint's ready-to-show event — a cycle with no way out on its own. Observed under GNOME/Mutter on a VM whose virtio-gpu device fails command-buffer creation. Add a bounded fallback show(), guarded on isVisible() so it's a no-op once the event has already fired normally and doesn't steal focus back from whatever the person switched to. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_01CHKaCz2gq3ya8t13CvQ7Hp --- packages/meshbay-client/src/main.js | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'packages/meshbay-client/src/main.js') diff --git a/packages/meshbay-client/src/main.js b/packages/meshbay-client/src/main.js index de8de8f..27c81b8 100644 --- a/packages/meshbay-client/src/main.js +++ b/packages/meshbay-client/src/main.js @@ -453,6 +453,16 @@ function createWindow() { }); win.once('ready-to-show', () => win.show()); + // Some Wayland compositors (observed under GNOME/Mutter on a VM with a + // virtio-gpu device whose command-buffer creation fails) never schedule a + // first paint for a surface that isn't mapped yet — but Electron won't map + // it (show()) until `ready-to-show` fires, which waits for that paint. The + // two conditions deadlock the window invisible forever. This bounded + // fallback breaks the cycle. Guarded on isVisible(): show() also raises + // and refocuses an already-visible window, so once the event has fired + // normally (real GPU/X11 hosts, well under 2s) this must stay a no-op + // rather than yank focus back from whatever the person switched to. + setTimeout(() => { if (!win.isDestroyed() && !win.isVisible()) win.show(); }, 2000); // The hub must never become the document origin. Anything that would navigate // away from the packaged interface is refused, and an external link opens in -- cgit v1.2.3