Skip to content

fix(inject): give App Expose/Mission Control/Show Desktop/Launchpad a GNOME implementation - #1446

Open
4ni1ak wants to merge 2 commits into
AprilNEA:masterfrom
4ni1ak:fix/gnome-window-actions
Open

4ni1ak wants to merge 2 commits into
AprilNEA:masterfrom
4ni1ak:fix/gnome-window-actions

Conversation

@4ni1ak

@4ni1ak 4ni1ak commented Sep 17, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Binding a control to App Expose (or Mission Control / Show Desktop / Launchpad) does nothing on GNOME — crates/openlogi-inject/src/inject/linux.rs::dispatch_native groups all four into a no-op branch that only logs no Linux equivalent — action skipped.

Root cause / approach

There genuinely is no universal Linux equivalent (different desktops bind Super differently — KDE opens KRunner, for instance), which is why the existing code punts entirely. But GNOME specifically has stable default keybindings for all four:

  • A bare tap of the Super key (org.gnome.mutter.overlay-key) toggles the Activities overview — this covers both MissionControl and AppExpose.
  • Super+D is GNOME's default "Show desktop".
  • Super+A is GNOME's default "Show Applications" (app grid) — covers LaunchpadShow.

I initially looked at the D-Bus route the issue mentions (org.gnome.Shell.Eval), since the reporter said it worked for them, but that method requires GNOME's "unsafe-mode" to be explicitly enabled (disabled by default), so it isn't something that works out of the box for most users. Plain synthetic key presses through the existing uinput device need no such opt-in and work exactly like a real keypress.

Changes

  • crates/openlogi-inject/src/inject/linux.rs: MissionControl/AppExpose/ShowDesktop/LaunchpadShow now go through a new gnome_key_or_skip helper — presses the matching GNOME keybinding under GNOME (detected via XDG_CURRENT_DESKTOP, case-insensitive substring match, matching the existing detection idiom in crates/openlogi-desktop/src/features/profiles/catalog.rs), and falls back to the original no-op + debug log everywhere else, per the issue's own request to leave other desktops alone until they have a stable implementation.

Testing

  • Added gnome_detection_matches_on_current_desktop_case_insensitively, covering exact match, a compound XDG_CURRENT_DESKTOP value (ubuntu:GNOME), a GNOME variant (gnome-classic), a non-GNOME desktop, and unset.
  • cargo fmt --all -- --check, cargo clippy -p openlogi-inject -p openlogi-agent-core -p openlogi-agent -p openlogi-hook -p openlogi-desktop -p openlogi-overlay --all-targets -- -D warnings, and cargo test for that same affected set (openlogi-inject's reverse-dependency closure) — all green.
  • Not runtime-tested on a GNOME session (none available to me) — the keycodes and keybindings are standard/documented GNOME defaults, but I couldn't confirm end-to-end that a synthetic Super tap actually triggers the overlay-key detection on real GNOME/Wayland hardware.

Fixes #1042

… GNOME implementation

These four window-manager actions had no universal Linux equivalent
and were silently skipped. GNOME's default keybindings cover all four
(a bare Super tap toggles the overview, Super+D shows the desktop,
Super+A shows the app grid) via plain synthetic key presses through
the existing uinput device — no D-Bus needed. Gated on
XDG_CURRENT_DESKTOP so other desktops (KDE binds Super to KRunner, for
one) keep the existing no-op.
@4ni1ak
4ni1ak requested a review from AprilNEA as a code owner September 17, 2026 02:09
@greptile-apps

greptile-apps Bot commented Sep 17, 2026

Copy link
Copy Markdown

RetriggerConfidence Score: 5/5

The PR appears safe to merge.

Summary

GNOME now runs native desktop actions through its standard Super-key shortcuts instead of skipping them. Other desktops keep the old skip behavior, and App Expose still skips because GNOME has no single-app equivalent.

  • Maps Mission Control to GNOME's Activities overview.
  • Maps Show Desktop and Launchpad to GNOME's default shortcuts.
  • Keeps unsupported desktop actions on the existing skip path.
Diagram
sequenceDiagram
    participant Caller
    participant Dispatch as dispatch_native
    participant GNOME as is_gnome
    participant Input as press_key

    Caller->>Dispatch: Send native action
    alt AppExpose
        Dispatch-->>Caller: Skip and log
    else MissionControl, ShowDesktop, or LaunchpadShow
        Dispatch->>GNOME: Check XDG_CURRENT_DESKTOP
        alt GNOME session
            GNOME-->>Dispatch: true
            Dispatch->>Input: Send GNOME shortcut
        else Other desktop
            GNOME-->>Dispatch: false
            Dispatch-->>Caller: Skip and log
        end
    end
Loading

Reviews (2) · Last reviewed commit: "fix(inject): stop AppExpose from opening..."

Comment thread crates/openlogi-inject/src/inject/linux.rs Outdated
Comment thread crates/openlogi-inject/src/inject/linux.rs Outdated
AppExpose and MissionControl shared one match arm sending GNOME's bare-Super
Activities tap, but Activities shows every window across every app --
AppExpose's contract is the frontmost app's windows only, which no tested
desktop (GNOME's Activities, KDE's Present Windows) actually has a stock
binding for. AppExpose now always skips with the existing "no Linux
equivalent" debug log instead of substituting the wrong scope.

Also replaced the env-var-mutating test for is_gnome() with a pure
desktop_is_gnome(str) helper: the previous test's SAFETY comment claimed a
private per-test mutex serialized access to the process environment, but
that mutex only serializes callers that take it -- it does nothing for
is_gnome() itself or any other concurrent reader, which is exactly the
class of race Rust 2024 made set_var/remove_var unsafe over. The pure
helper needs no unsafe and no env mutation at all.
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.

[Bug]: App Expose and other window actions are silently skipped on GNOME

1 participant