Skip to content

fix(overlay): restore Wayland overlay on Tauri 2.11.5 (Linux)#1700

Open
xilec wants to merge 9 commits into
cjpais:mainfrom
xilec:fix/tauri-2.11.5-overlay-on-linux
Open

fix(overlay): restore Wayland overlay on Tauri 2.11.5 (Linux)#1700
xilec wants to merge 9 commits into
cjpais:mainfrom
xilec:fix/tauri-2.11.5-overlay-on-linux

Conversation

@xilec

@xilec xilec commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Before Submitting This PR

Please confirm you have done the following:

  • I have searched existing issues and pull requests (including closed ones) to ensure this isn't a duplicate
  • I have read CONTRIBUTING.md

If this is a feature or change that was previously closed/rejected:

  • I have explained in the description below why this should be reconsidered
  • I have gathered community feedback (link to discussion below)

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

  • Platform: Linux (NixOS, Wayland, niri).
  • Build: cd src-tauri && cargo build on Tauri 2.11.5 (pinned [patch.crates-io]
    tao/tao-macros to rev 07f3742b1833b64be27b1ef991e38d557d4276c9).
  • Manual verification on niri:
    • Overlay appears on the first transcription (previously invisible).
    • Overlay grows correctly with streamed text.
    • Runtime Top↔Bottom position switch works; overlay does not disappear.
    • Repeated show/hide cycles keep working.
  • Non-Linux platforms (Windows/macOS) are unchanged: all new code is under
    #[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

  • No AI was used in this PR
  • AI was used (please describe below)

If AI was used:

  • Tools used: opencode (AI coding assistant, model hy3-free, Kimi K2.7, reviewer Kimi K3)
  • How extensively: AI assisted with root-cause analysis, the GTK-surface
    helper refactor, and code review. The final fix and its behavior on
    Wayland were verified manually by the human contributor.

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.
@xilec
xilec marked this pull request as ready for review July 16, 2026 21:53
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.
@cjpais

cjpais commented Jul 20, 2026

Copy link
Copy Markdown
Owner

Just to confirm this did work probably on your system?

@xilec

xilec commented Jul 20, 2026

Copy link
Copy Markdown
Contributor Author

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[v0.9.3 regression] Recording overlay invisible on KDE Wayland (KWin) — GTK layer-shell broken after tauri fork → upstream switch

2 participants