Skip to content

fix(gui): draw the client-side titlebar only where the compositor declines one - #945

Open
4ni1ak wants to merge 1 commit into
AprilNEA:masterfrom
4ni1ak:fix/kde-double-decoration
Open

fix(gui): draw the client-side titlebar only where the compositor declines one#945
4ni1ak wants to merge 1 commit into
AprilNEA:masterfrom
4ni1ak:fix/kde-double-decoration

Conversation

@4ni1ak

@4ni1ak 4ni1ak commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

Summary

On KDE the compositor's titlebar and OpenLogi's own were both visible, stacked.

Fixes #890

Root cause

Every Linux window drew a client-side titlebar unconditionally:

.when(cfg!(target_os = "linux"), |this| this.child(app_title_bar(pal)))

The comment beside it explained why — "the compositor declines server-side
decorations and gpui's client-side fallback is otherwise unpainted"
— and that
is true of GNOME: Mutter does not implement xdg-decoration, so without this
the window has no chrome at all. It is not true of KWin, which does implement
it and hands back a real server-side titlebar. cfg!(target_os = "linux") reads
"Linux" as if it were one compositor.

Change

Ask the window what it actually negotiated:

pub fn needs_client_titlebar(window: &Window) -> bool {
    matches!(window.window_decorations(), Decorations::Client { .. })
}

The four render sites — main window, Settings, Add Device, the update-consent
prompt — drop their cfg! for that call. macOS and Windows always report
Server, so the platform check disappears rather than moving: one condition
that reads the same everywhere.

titlebar_options() still returns transparent options on Linux — that is what
permits a client-side bar. Whether one is drawn is now decided per window from
what the compositor said, and its doc comment now says so.

The issue also asks for a preference to choose the decoration type. That is not
here: with this, each compositor gets exactly the one it asked for, and a
setting would mostly exist to re-create the wrong half. Happy to add one if you
would still like it.

Testing

Linux, x86_64, Rust 1.98.0:

cargo fmt --all -- --check
cargo clippy --workspace --all-targets -- -D warnings   # RUSTFLAGS=-D warnings
cargo test --workspace

All green.

Verified visually on the reported platform — KDE Plasma, Wayland,
kwin_wayland, the same class as the report's KDE Neon:

  • On master, both the main window and the update-consent prompt show two
    titlebars: KWin's, and below it a second bar reading "OpenLogi" with its own
    minimize / maximize / close.
  • On this branch, each shows exactly one — KWin's, with its window controls and
    the pin button intact.

Same session, same compositor, GUI rebuilt between the two runs, screenshots
compared side by side.

Not verified: GNOME. That is the case the unconditional draw existed for, so
it is the one to re-check — a window with no titlebar there would mean
window_decorations() is not reporting Client as expected. Also not run on
this host: tests (macos), cargo-deny, macOS clippy; macOS and Windows are
unchanged by construction (both always report Server, exactly as
cfg!(target_os = "linux") was false for them).

@4ni1ak
4ni1ak requested a review from AprilNEA as a code owner August 24, 2026 19:52
@greptile-apps

greptile-apps Bot commented Aug 24, 2026

Copy link
Copy Markdown

Greptile Summary

The PR replaces the unconditional Linux client-side titlebar with a per-window decision based on the decoration mode negotiated with the compositor.

  • Adds a shared needs_client_titlebar helper using GPUI’s Decorations::Client state.
  • Applies the helper consistently to the main, Settings, Add Device, and update-consent windows.
  • Retains transparent Linux titlebar options while allowing server-decorating compositors such as KWin to provide the only visible titlebar.

Confidence Score: 5/5

The PR appears safe to merge.

No blocking failure remains.

Important Files Changed

Filename Overview
crates/openlogi-desktop/src/windows.rs Adds the shared decoration-mode predicate and updates documentation for Linux titlebar behavior.
crates/openlogi-desktop/src/app.rs Makes the main window’s custom titlebar conditional on negotiated client-side decorations.
crates/openlogi-desktop/src/windows/add_device.rs Applies the shared decoration decision to the Add Device window.
crates/openlogi-desktop/src/windows/settings.rs Applies the shared decoration decision while preserving the Settings window’s overlay and padding layout.
crates/openlogi-desktop/src/windows/update_consent.rs Applies the shared decoration decision to the update-consent window.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[Render window] --> B{Negotiated decorations}
    B -->|Client| C[Draw OpenLogi titlebar]
    B -->|Server| D[Use compositor titlebar]
    C --> E[Render window content]
    D --> E
Loading

Reviews (2): Last reviewed commit: "fix(gui): draw the client-side titlebar ..." | Re-trigger Greptile

@davidbudnick davidbudnick added type: bug Something is broken or behaves incorrectly area: gui Graphical user interface platform: all Cross-platform issue labels Aug 25, 2026
…lines one

Every Linux window drew its own titlebar unconditionally. That is right on
GNOME — Mutter does not implement `xdg-decoration`, gpui falls back to
client-side, and nothing paints the chrome unless the app does — but KWin
does implement it and hands back a real server-side titlebar. On KDE the two
stacked: the compositor's bar, and ours with its own minimize/maximize/close
underneath it.

Ask the window what it actually got instead of assuming. `needs_client_titlebar`
reads `Window::window_decorations()` and is true only for
`Decorations::Client`, which is also what macOS and Windows never report — so
the four render sites lose their `cfg!(target_os = "linux")` and gain one
honest check that reads the same on every platform.

Fixes AprilNEA#890
@4ni1ak
4ni1ak force-pushed the fix/kde-double-decoration branch from e57f71c to ec9f567 Compare August 25, 2026 15:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: gui Graphical user interface platform: all Cross-platform issue type: bug Something is broken or behaves incorrectly

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: On KDE, client and server side decoration are displayed together

2 participants