fix(overlay): restore Wayland overlay on Tauri 2.11.5 (Linux) - #1700
Conversation
Wayland compositors (niri, KWin) only commit a layer surface on an
unmapped→mapped transition. On Tauri 2.11.5 the overlay never appeared,
and switching its position at runtime dropped it permanently.
Linux/Wayland changes (all under cfg(linux) where they touch the surface):
- Track gtk-layer-shell init in LAYER_SHELL_ACTIVE and skip layer-shell
calls on the non-layer-shell fallback window.
- Prime the surface with a show()+hide() cycle so the first real show()
maps it fresh instead of being a no-op on an already-mapped surface.
- In show_overlay_state, flip Tauri window visibility (overlay_window.show())
so emit("show-overlay") reaches the WebView, and set anchors + show
atomically on the GTK thread, synchronizing via a channel so emit runs
only after the surface is actually mapped. set_size/set_position stay on
the non-layer paths only (niri ignores them on mapped layer surfaces).
- Allocate the max overlay size up front on Linux; niri ignores set_size on
mapped layer surfaces, so the overlay could not grow with streamed text.
- On hide, unmap the GTK surface and flip Tauri visibility so repeated
shows keep working.
- On runtime position change, remap the surface (unmap → set anchors → map)
so the compositor commits the new Top/Bottom anchors.
Non-Linux platforms (Windows, macOS) are unchanged from v0.9.3: compact
initial size, set_size/set_position, Windows topmost re-assert, and the
original timing debug log.
Refactor: extract repeated GTK-surface logic into named helpers —
pump_gtk_events(), with_gtk_window(), gtk_show_layer_surface(),
gtk_remap_layer_surface(), position_overlay_window() — folding the
show/hide + main_iteration cycles and run_on_main_thread boilerplate
that were duplicated across prime, show_overlay_state,
update_overlay_position and hide_recording_overlay. Behavior unchanged.
bindings.ts is intentionally left as the v0.9.3 generated content.
On Wayland layer-shell, only remap the surface when it is currently mapped; for an unmapped surface just set the anchors so they apply on the next map. This keeps Tauri's window visibility untouched, so a mid-recording position switch no longer hides the overlay and an idle switch no longer flashes it.
|
Just to confirm this did work probably on your system? |
The function was only called from init_gtk_layer_shell, but its guard always triggered there because LAYER_SHELL_ACTIVE is stored later in the same function. Initial anchors are already set by the priming cycle, and subsequent shows re-apply anchors via gtk_show_layer_surface. No behavior change.
|
Yes, the fix works on my system. I tested it as described in the PR's testing section, and I've been using Handy from this PR branch daily. I've also added a few small improvements based on further review. |
Resolve overlay.rs conflicts by keeping the branch's GTK layer-shell show/remap paths on Linux while adopting main's Windows placement (place_windows_overlay, streaming-size cache) for the non-Linux paths.
Adopt main's main-thread overlay dispatch (cjpais#1810): show_overlay_state and update_overlay_position now hop to the GTK main thread, keeping the branch's layer-shell show/remap logic inside the *_on_main bodies.
|
@cjpais No — the main window has rendered correctly for me on NixOS/niri across all builds after the Tauri 2.11.5 switch. Left a note in #1806: #1806 (comment) |
|
Hi @cjpais — just checking in on this one. The branch is now up to date with Is there anything currently blocking this? For example:
Happy to do whatever makes this easier to land. |
|
FWIW, I built this on Opensuse Tumbleweed and it fixes the issue on KDE Wayland. Been running it since yesterday, it seems perfectly stable. Thanks a lot! |
|
I'm doing a review over this and there's possibly some changes I want to make. I'm just like a bit concerned about the changes as written I think the feedback from the issue itself might be worth taking into account, like the other user who offered his perspective on implementation, it may be able to simplify this implementation and maybe be a bit more robust It's just hard for me to review these Linux things unless I have time to really sit down in front of a Linux machine and make sure that it's solid basically if you could just take a look at the feedback from that other user, I would be grateful to hear some perspective |
|
Took a look at @arimxyer's feedback as you asked — and went a bit further: I tested a cherry-pick of a7dea9c8 onto current Scenarios covered: first show, streaming growth (256x46 → 400x120 on a mapped surface), runtime Top↔Bottom switch including mid-recording, and repeated show/hide cycles. Everything works, so his His analysis is correct, and it also names the problem this PR was working around: the fixed max-size window and "never resize a mapped layer surface" were my way around the same 0x0 surface he diagnosed properly. On the extra mechanics in this PR (surface priming, remap on position change, sync before the One caveat worth flagging from all this testing: there's a pre-existing glitch where the streaming card leaves faded pixels behind the compact overlay — WebKit doesn't clear the now-transparent region on state change. It reproduces on current
|
🧪 Test Build ReadyBuild artifacts for PR #1700 are available for testing. Download artifacts from workflow run Artifacts expire after 30 days. |
|
I'm also on niri and I've just built this locally and the overlay is working again for me |
|
@cjpais Tested on niri (multi-monitor Wayland). Almost everything works: first show, streaming growth 256x46 → 400x120 via One issue: the cursor-based I don't see a reliable client-side way to pick the monitor on Wayland: the global pointer position and the keyboard focus are deliberately not exposed to clients, and enigo's own Wayland backend has With the I'd suggest dropping the |
|
@xilec ive applied the fix, can you give it a build and test on your machine please? |
🧪 Test Build ReadyBuild artifacts for PR #1700 are available for testing. Download artifacts from workflow run Artifacts expire after 30 days. |
|
Just built it, works on KDE/Wayland. Can test multi monitor on Saturday. |
|
@cjpais Built and tested on commit 709fb68 on niri (multi-monitor Wayland) — everything works:
Good to merge from my side. Thanks for the quick turnaround! |
|
Thanks yall for the confirmation, merging |

Before Submitting This PR
Please confirm you have done the following:
If this is a feature or change that was previously closed/rejected:
Human Written Description
The Tauri 2.11.5 update in commit 5a7c0ea broke
overlay rendering on my system, and based on issue #1696 it is also broken on some
other systems. This PR narrowly fixes the overlay for Linux while preserving the
overlay behavior on other platforms.
Related Issues/Discussions
Fixes #1696
Community Feedback
Bug fix confirmed by the reporter in #1696 (KDE/KWin). Verified independently on
niri (another Wayland compositor) where the overlay was similarly invisible.
Testing
cd src-tauri && cargo buildon Tauri 2.11.5 (pinned[patch.crates-io]tao/tao-macros to rev
07f3742b1833b64be27b1ef991e38d557d4276c9).#[cfg(target_os = "linux")]; shared code was only moved into#[cfg(not(target_os = "linux"))]with no logic change.Screenshots/Videos (if applicable)
AI Assistance
If AI was used:
helper refactor, and code review. The final fix and its behavior on
Wayland were verified manually by the human contributor.