Skip to content

fix(wayland): fix client-side decorations and apply them only when necessary - #1218

Merged
FabianLars merged 12 commits into
tauri-apps:devfrom
dgerhardt:fix-wayland-csd
Jun 29, 2026
Merged

fix(wayland): fix client-side decorations and apply them only when necessary#1218
FabianLars merged 12 commits into
tauri-apps:devfrom
dgerhardt:fix-wayland-csd

Conversation

@dgerhardt

Copy link
Copy Markdown
Contributor

This PR fixes multiple issues regarding window decoration handling on Wayland:

  1. The default client side decoration handling of GTK is now used once again. Custom CSD don't make any sense when no custom widgets are added to the title bar. Futhermore, the custom CSD didn't work correctly and introduced multiple bugs regarding the titlebar and server-side rendering on Wayland.

    This is mostly a revert of fix(wayland): add client side decorations & fix error protocol 71 #979.

    Fixes [request] Remove client decorations (linux/wayland) #1046, [bug] Window setTitle does not update header bar on Wayland tauri#13749, [bug] Window titlebar buttons absent on KDE Wayland tauri#14251, [bug] v2 regresses window manager control of decorations/titlebar tauri#14748
    Supersedes fix(wayland): decoration not clickable when initial visible is false #1055

  2. Window mouse events are once again propagated.

    This reverts fix(linux): prevent firing duplicate mouse events (fixes #939) #941, which broke CSD event handling on Wayland. A new fix for Pressing a mouse button has duplicit events on Linux #939 might now be needed.

    Fixes [bug] native window bar's buttons not working (on wayland) tauri#13440
    Might fix (unconfirmed) [bug][linux] Decorations are unresponsive if WebviewWindow is built with visible(false), then shown tauri#11856

  3. A workaround for a GTK bug has been added so compositors don't force decorations. This enables CSD for undecorated windows to ensure that compositors with server-side decoration support (e.g. KDE Plasma) do not apply them when decorations are disabled for the window. Changing the decoration state for existing windows is however still not supported.

    This is a workaround for a GTK bug: https://gitlab.gnome.org/GNOME/gtk/-/work_items/5479

    Fixes WindowBuilder::with_decorations(false) doesn't work on wayland kde. #899, [bug] decoration doesn't work on Wayland  tauri#6562

While these are individual fixes, they depend on each other, so I submit them in a single PR. With the latter changes, regressions, which only reverting #979 would cause, can be avoided.

dgerhardt added 4 commits May 7, 2026 15:55
The default client side decoration handling of GTK is now used once
again. Custom CSD don't make any sense when no custom widgets are added
to the title bar. Futhermore, the custom CSD didn't work correctly and
introduced multiple bugs regarding the titlebar and server-side
rendering on Wayland.

This is mostly a revert of tauri-apps#979.

Fixes tauri-apps#1046, tauri-apps/tauri#13749, tauri-apps/tauri#14251,
tauri-apps/tauri#14748
Supersedes tauri-apps#1055
This reverts tauri-apps#941, which broke CSD event handling on Wayland. A new fix
for tauri-apps#939 might now be needed.

Fixes tauri-apps/tauri#13440
Might fix (unconfirmed) tauri-apps/tauri#11856
This enables CSD for undecorated windows to ensure that compositors with
server-side decoration support (e.g. KDE Plasma) do not apply them when
decorations are disabled for the window. Changing the decoration state
for existing windows is however still not supported.

This is a workaround for a GTK bug:
https://gitlab.gnome.org/GNOME/gtk/-/work_items/5479

Fixes tauri-apps#899, tauri-apps/tauri#6562
@dgerhardt
dgerhardt requested a review from a team as a code owner May 7, 2026 14:29
@dgerhardt dgerhardt changed the title fix(wayland): apply client-side decorations only when necessary fix(wayland): fix client-side decorations and apply them only when necessary May 7, 2026
@github-actions

github-actions Bot commented May 7, 2026

Copy link
Copy Markdown
Contributor

Package Changes Through 6452e25

There are 1 changes which include tao with minor

Planned Package Versions

The following package releases are the planned based on the context of changes in this pull request.

package current next
tao 0.35.3 0.36.0

Add another change file through the GitHub UI by following this link.


Read about change files or the docs at github.com/jbolda/covector

@FabianLars

Copy link
Copy Markdown
Member

Thanks for the PR! Really happy to see this progressing. There's one major problem though, your PR now re-introduces the startup crash you can see in #979 PR description/video. Simply add .with_maximized(true) to the resizable example and it should crash straight away. At least it does in my WSL instance.

This ensures that the window is resizable before maximizing it to avoid
unexpected behavior.
@dgerhardt

Copy link
Copy Markdown
Contributor Author

Thanks for the quick feedback. While I wasn't able to reproduce the crash on my end (tested on Ubuntu 26.04, GNOME and KDE), the window did no longer correctly maximize in this situation for me.

I've added a commit to reapply the fix regarding maximize handling from #941. It fixes maximizing with disabled resizing for me and hopefully also the crash.

@FabianLars

Copy link
Copy Markdown
Member

Still crashes for me but the question would be how WSL-specific that is. If it doesn't happen on normal Linux systems i could actually live with that. I'll ask on discord for testers as well.

ElbertePlinio added a commit to pickforge/pickgauge that referenced this pull request Jun 11, 2026
tao's Wayland CSD wraps the header bar in a GtkEventBox with
above-child input, which swallows clicks on minimize/maximize/close
until a maximize/restore cycle re-stacks the input windows
(tauri-apps/tao#1218). Lower the box below its child at setup so the
buttons get their events back.

Also scope the float capsule's decoration CSS reset to that window via
a GTK widget name instead of applying it screen-wide.
ElbertePlinio added a commit to pickforge/pickscribe that referenced this pull request Jun 11, 2026
tao's Wayland CSD wraps the header bar in a GtkEventBox with
above-child input, which swallows clicks on minimize/maximize/close
until a maximize/restore cycle re-stacks the input windows
(tauri-apps/tao#1218). Lower the box below its child at setup so the
buttons get their events back.

Also scope the float capsule's decoration CSS reset to that window via
a GTK widget name instead of applying it screen-wide.
@FabianLars FabianLars linked an issue Jun 24, 2026 that may be closed by this pull request
@FabianLars

Copy link
Copy Markdown
Member

Simply add .with_maximized(true) to the resizable example and it should crash straight away. At least it does in my WSL instance.

idk if anything changed or if my comment was wrong, but it'll crash now if i add .with_maximized(true).with_decorations(false) - i assume that's what i meant back then as well, not sure.

@@ -0,0 +1,10 @@
---
"tao": patch

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need to change this, just fyi: I'm aiming for a new tao minor release and a tauri minor (2.12) just so we have more of an obvious point in time where this was changed and no hidden patch updates on cargo update or whatever.
(The dev branch is already for the next tao minor release so nothing actually changes)

@FabianLars

Copy link
Copy Markdown
Member

Sooo, i am okay with merging it as is but ideally we fix stuff before we actually release the changes

  1. The wsl crash may be fixed by applying the same workaround 098cfb3 but couldn't try that yet - i wouldn't block the release on a wsl specific crash that needs resizable, maximized and !decorations
  2. The duplicate press/release events: i think the simplest fix is to compare new event's timestamp with the old one but i'm not sure if this is something for tao or tauri, but probably tao

@Legend-Master any thoughts or concerns?

@Legend-Master

Copy link
Copy Markdown
Contributor

It seems like the minimize button and maximize buttons are now gone after this?

Before

image

After

image

@FabianLars

Copy link
Copy Markdown
Member

yes and as stupid as it sounds, this is actually correct. stupid gnome 😂 you should see the same button "issue" in all native gnome apps unless you use Gnome tweaks to change that.

I'm a bit torn about this as well though, I always hated this and don't know anyone who doesn't jump straight into gnome tweaks to fix it, but i think it's a tradeoff well worth to have working titlebars again.
If we have more resources for Linux we could take another look at our own CSD but probably makes sense to wait for the gtk4 migration

@Legend-Master

Copy link
Copy Markdown
Contributor

Yeah I see... 'fixed' it by gsettings set org.gnome.desktop.wm.preferences button-layout ":minimize,maximize,close" 😂

Honestly, I didn't experience any problems just testing the dev branch in WSL, and this PR does break that very combination (in WSL). I won't block this though seeing how many linked issues 😂

@dgerhardt

dgerhardt commented Jun 25, 2026

Copy link
Copy Markdown
Contributor Author

I tested again on my Ubuntu 24.04.1 VM and can't reproduce this issue. All window buttons appear when using Gnome Desktop and a Wayland session.

This seems to be in issue with the WSL environment. Running the same version of Ubuntu, gsettings get org.gnome.desktop.wm.preferences button-layout returns different results on a native/VM Ubuntu (:minimize,maximize,close) and on WSL (appmenu:close). This isn't an issue with TAO but affects all GTK-based apps. When I run gnome-calculator in WSL, the buttons are also missing.

gsettings set org.gnome.desktop.wm.preferences button-layout allows end users to customize the button layout globally for all apps (e.g. close,minimize,maximize: for a macOS-like layout). When it is overridden, TAO-based apps would be inconsistent for users that changed this setting intentionally.

I would suggest to just add a note to the documentation for developers on WSL mentioning the need to run the gsettings command once.

@FabianLars

Copy link
Copy Markdown
Member

All window buttons appear when using Gnome Desktop and a Wayland session.

Yeah, i pushed a change for that after Tony's comment that also works in wsl for me. Like i said, i am a bit torn about this but i believe most tauri devs would expect the buttons to be there so i added them back. I've not seen any errors caused by that yet.

I didn't merge this yet because i was trying a few things to get rid of the protocol error i mentioned but all solutions suck

@dgerhardt

dgerhardt commented Jun 25, 2026

Copy link
Copy Markdown
Contributor Author

Yeah, i pushed a change for that after Tony's comment that also works in wsl for me.

I should have mentioned: I retested with and without the button layout commit. It works fine outside of WSL and on WSL all GTK-based apps have a broken button layout without changing the setting.

@FabianLars

Copy link
Copy Markdown
Member

I tested again on my Ubuntu 24.04.1 VM and can't reproduce this issue. All window buttons appear when using Gnome Desktop and a Wayland session.

This seems to be in issue with the WSL environment.

More like this is one of the few things Ubuntu did right. They changed gnome's default. If you use fedora gnome for example it should behave similar-ish to wsl as it's vanilla gnome.

When it is overridden, TAO-based apps would be inconsistent for users that changed this setting intentionally.

Which is fine imo. If gnome wants CSD we might as well do CSD you know. Also, we've had the buttons with the now removed custom titlebar so keeping it for now sounds reasonable to me. We can re-iterate on that later though if we get negative feedback.


I didn't merge this yet because i was trying a few things to get rid of the protocol error i mentioned but all solutions suck

This is not wsl specific btw but at least weston specific (wsl uses weston) so i'll keep trying things but i'm very rusty with gtk so if somebody has ideas i'm all ears x)

@FabianLars

Copy link
Copy Markdown
Member

okayyy, any thoughts on the last 2 commits?

The first one to fix the crash is super duper ugly and i hate it but it's the best thing stupid me could come up with right now. I hope it holds it together until our gtk4 migration where we can set more of the required things on the window builder which hopefully doesn't even cause the issues we're dealing with here.

The second one to prevent duplicate events i think is the best approach we have - meaning the timestamp comparison, the implementation itself may be shit too, please tell me if so. Also, other events like MouseLeave are triggered twice as well but i did not see anyone ever complaining about this so i only touched the 3 events that were reverted here.

@Legend-Master

Copy link
Copy Markdown
Contributor

What works works I guess 😂, at least it doesn't crash in WSL now

@dgerhardt

Copy link
Copy Markdown
Contributor Author

I retested with the latest two commits on KDE Plasma. The crash fix actually also fixes maximize on startup behavior here, which was already broken on the dev branch before. Previously, the window would then often be in a weird maximized state without actually filling the full screen.

Which is fine imo. If gnome wants CSD we might as well do CSD you know. Also, we've had the buttons with the now removed custom titlebar so keeping it for now sounds reasonable to me. We can re-iterate on that later though if we get negative feedback.

Even if I might not agree with GNOME's design philosophy of not having minimize/maximize buttons at all, if a distro decides to go with it, I don't think there is a reason to actively work against that on the app side. But I do agree that it is reasonable to enforce the buttons for now to avoid a change of existing behavior.

@FabianLars

Copy link
Copy Markdown
Member

yeah i'm thinking of selling it as a gtk4 change once we update or something. but i'll leave that decision to whoever merges this pr

Comment thread src/platform_impl/linux/event_loop.rs Outdated
@FabianLars

Copy link
Copy Markdown
Member

fuck it we ball - we can always add it back, users can even copy the same code into their app.

@FabianLars
FabianLars merged commit 07f3742 into tauri-apps:dev Jun 29, 2026
20 checks passed
@github-actions github-actions Bot mentioned this pull request Jun 29, 2026
tsouth89 added a commit to tsouth89/toolport that referenced this pull request Aug 14, 2026
…ndow

The titlebar-button repro narrowed the bug: a maximize + restore cycle
durably heals the buttons, which is a stale input region on a window
created hidden and shown later (tao 0.35 on Wayland), not main-loop
blocking. Fixed upstream in tao 0.36 (tauri-apps/tao#1218, ships with
Tauri 2.12); until that bump, nudge the window size by one pixel and back
on every show so the surface reconfigures invisibly. Wayland-only, skipped
when maximized (already has a fresh configure, and resizing would
unmaximize).

The spawn_blocking conversions in the previous commit stay: they remove
real main-loop stalls (3s audit-log polls, keychain D-Bus reads) that
compound the same symptom, especially while gnome-keyring is crashing
(SBS-815).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
tsouth89 added a commit to tsouth89/toolport that referenced this pull request Aug 14, 2026
…stored geometry

Validated live on Ubuntu 26.04 (GNOME 50.1, Wayland, VMware): a plain
resize does NOT heal the stale input region — only the maximize state
change does. On reveal, flick maximize/unmaximize 150ms after show (the
surface must be mapped), wait for the state to settle, then enforce the
pre-flick size clamped to the current monitor's usable area, and center.

The clamp also fixes a second real bug this surfaced: the window-state
plugin can persist a size that no longer fits (broken restore geometry
saved on quit, or a saved state from a larger monitor), which reopened
the window below the fold. Clamping at reveal self-heals the persisted
state on the next quit.

Remove the flick when the Tauri 2.12 / tao 0.36 bump lands
(tauri-apps/tao#1218 is the real fix).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
tsouth89 added a commit to tsouth89/toolport that referenced this pull request Aug 14, 2026
…BS-813) (#716)

Moves 17 blocking Tauri commands (polled log readers, keychain reads and
writes, diagnostics) off the GTK main thread via spawn_blocking, and adds
a Wayland input-region workaround for the stale surface under tao 0.35.

Review rounds folded in:

- Paired credential mutations (set_secret, delete_secret,
  set_client_credentials, clear_client_credentials) hold the keyed auth
  mutation lock across the whole keychain+registry sequence. Moving to
  the blocking pool removed the serialization the GTK main loop used to
  provide for free.
- secret_status errs on a worker join failure instead of returning an
  empty list, so a failed read cannot read as "nothing is vaulted"
  (same shape as the SBS-789 fix).
- SecretsDialog retires in-flight vault probes before each mutation, on
  a generation separate from probe_auth so the auth spinner still clears.
- The Wayland nudge skips maximized and fullscreen windows, retries
  unmaximize rather than stranding the window maximized, and runs one at
  a time behind an atomic flag.

Known and deliberate: the nudge still drops a tiled Wayland window out of
its tile on reopen (no is-tiled API), and live validation on the reporting
Ubuntu/GNOME machine is still outstanding. The whole helper is removable
once Tauri 2.12 ships tao 0.36 (tauri-apps/tao#1218).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

4 participants