Skip to content

Linux fixes for KDE/Wayland, plus a few features (language, Claude Code chat fallback, code view) - #158

Open
AinzDerErste wants to merge 11 commits into
Louis-CFM:mainfrom
AinzDerErste:linux-fixes
Open

AinzDerErste wants to merge 11 commits into
Louis-CFM:mainfrom
AinzDerErste:linux-fixes

Conversation

@AinzDerErste

@AinzDerErste AinzDerErste commented Oct 2, 2026 •

Copy link
Copy Markdown

Hi, and thanks for Coucou. This is what I needed to make the Tauri app work well on my Linux setup, plus a few features I built along the way. Everything is in separate commits (11). I rebuilt the branch on the current main (0.1.3) and checked the tip (tsc, vite build, cargo check, the tests); I did not re-check every commit on its own after that. The Claude usage display is no longer part of this PR: it follows the Mac's design in #171, and #172 and #173 (answering Claude's questions, local models and Markdown) build on it. Those three are drafts until this one is merged.

Tested on: CachyOS (Arch), KDE Plasma 6.7 on Wayland, NVIDIA RTX 2080 Ti, two monitors, Konsole.
Not tested: Windows, macOS, GNOME, other terminals.

Linux fixes

  • NVIDIA crash on start. With NVIDIA's proprietary driver WebKitGTK's DMABUF renderer commits frames after announcing explicit sync without an acquire point, and KWin kills the app with a protocol error. WEBKIT_DISABLE_DMABUF_RENDERER=1 is now set when the driver is loaded (unless the user set it).
  • Choose the display. Wayland has no main display and the layer surface was never given an output. Settings → Island lives on lists every display; "Main display" asks XWayland's RandR for the primary output.
  • Island never auto-closed. WebKitGTK sends no mouseleave when the pointer leaves a layer surface. GTK's leave-notify is now reported to the page, the collapse timer restarts when an alert reaches an already open island, and a stale mouse-move right after the leave is ignored (it overtook the leave and put the mouse "inside" for good).
  • Drop and clicks. The drop sequence was started before the island opened and got stopped by the wake-up, which left "uploading" stuck. Cancel/Ask were covered by invisible elements. Also: ticker rows overlapped in WebKit (an absolute box without top), and notes now dismiss themselves.
  • Open terminal jumps to the Konsole tab of the session (D-Bus plus a short KWin script), finds code/code-oss/codium/cursor, and says so in the island when there is no editor.

Features

  • Language setting (system / English / Deutsch / Français) for the chat's answers and the step labels, which were fixed to French.
  • Chat through Claude Code when there is no API key (claude -p on the user's login, hooks left out, follow-ups resume the session).
  • Font Awesome icons for the header and the phases (a few paths embedded with the CC BY 4.0 notice, nothing installed). This changes the header look on Windows too.
  • Code view. Clicking the overview's left card opens a small editor with the changed lines (context from the file, red/green), the last command and what it printed, like docs/media/claude-code.png. I could not find that view in the Swift code or in the history, so I built one; if you already have it, please drop this commit. To fill the terminal part the relay now forwards the last three lines a Bash command printed (the rest of tool_response is still dropped). See "Known limitations" below.
  • Halo easing. CSS cannot transition between gradients, so the halo colour is eased per frame.

Known limitations

  • The ticker and the pill are still shared by parallel sessions. There is one "Claude Code" pill, so with several sessions running the ticker (and the project name on it) mixes them. That was already so before this PR. The code view no longer depends on it: it keeps its data per session_id, remembers the folder each session started in (so a cd in the shell changes neither the name nor the paths), and shows the session that was active last. The last commit does that; the first version of this PR did not.
  • How it was checked. What the app receives was verified against the real events of a real session (field names and types of Edit and Bash, and the output lines). The per-session logic has a throwaway test (two sessions, a new prompt in one of them, a cd), and I watched the view follow real parallel sessions of mine consistently. The screenshots are staged (see below).
  • Windows, macOS and GNOME are untested.

Screenshots

Taken on KDE/Wayland. The code and the command output in the code view pictures come from a staged demo project (the invoice.ts of docs/media/claude-code.png, with invented test output), sent through the real relay, so the view can be shown reproducibly. The pictures follow in a comment (any usage card in the older pictures is from an earlier version of this PR and is gone).

Notes

  • I know CONTRIBUTING.md asks for one topic per PR. The commits are independent enough to cherry-pick, so I am happy to split this in whatever way suits you; just tell me which parts you want.
  • The build has no new warnings. I kept the existing Rust formatting instead of running rustfmt over old lines.

@AinzDerErste

AinzDerErste commented Oct 2, 2026 •

Copy link
Copy Markdown
Author

Screenshots, taken on KDE Plasma / Wayland.

The code and the command output are staged: a demo project (the invoice.ts of docs/media/claude-code.png, with invented test output) sent through the real relay, so the view can be shown reproducibly. The app, the relay and the rendering are the real ones, and so are the usage numbers.

Code view after an edit (changed lines with context from the file, the phases on the left):

code view

Code view with the last command and what it printed:

code view with terminal

The pictures live on a separate branch of my fork, not in this PR's diff.

The usage card that was in earlier pictures is not part of this PR any more; see #171.

Justin Minkmar added 11 commits October 3, 2026 13:26
With NVIDIA's proprietary driver, WebKitGTK's DMABUF renderer commits frames to a
Wayland surface after announcing explicit sync without an acquire point. The
compositor then closes the connection with a protocol error and the app dies on its
first frame.

Switch the DMABUF renderer off when the NVIDIA driver is loaded, unless the user set
WEBKIT_DISABLE_DMABUF_RENDERER themselves. Split prepare_environment into one
function per concern.
Wayland has no main display, and the layer surface was never assigned an output,
so the compositor picked one.

- Pin the layer surface to the chosen monitor (gtk_layer_set_monitor).
- Settings -> Island lives on lists every display by name and size.
- "Main display" now asks XWayland's RandR for the primary output, which KWin and
  Mutter set from the user's choice, and falls back to the first display.
- Report the compositor's pointer leave (GTK leave-notify) to the page. WebKitGTK
  sends no mouseleave when the pointer leaves the surface, so the island never
  learned the mouse was gone and never auto-closed.
- Restart the collapse timer when an alert reaches an island that is already open.
  forceHome cancelled it and only a state change started it again.
- Start the drop sequence after the island has opened. Waking a closed island passes
  through its default view, which stopped the sequence and left "uploading" stuck.
- Let clicks through #content and the hidden DOM view to the drop canvas' buttons;
  Cancel and Ask were covered by invisible elements.
- Give the ticker's dim text top:0. Without it WebKit places the absolute box one
  line below the text it should overlap.
- Let notes dismiss themselves after five seconds.
…there is no editor

- The relay passes Konsole's D-Bus names. The app switches to the tab over D-Bus
  and raises its window with a short KWin script, found by Konsole's process id and
  the tab's title.
- Look for code, code-insiders, code-oss, codium, vscodium and cursor in that order.
- When no editor is installed the island says so instead of silently opening the
  file manager.
- open_in_vscode returns an enum instead of a bool.
Settings -> Language (system, English, Deutsch, Français). An explicit choice tells
the chat to always answer in that language, whatever the question or the search
results are in. The step labels ("Runs", "Führt aus", "Exécute") follow it, where
they were fixed to French.
Without an API key the chat runs `claude -p` on the user's own login instead of
failing with "API key missing". Read, WebSearch and WebFetch are pre-approved, the
user's hooks are left out (--setting-sources project, run from a temp directory) so
the helper does not show up as a session, and follow-up questions resume the same
session.
Embed the handful of Font Awesome Free 7 (solid) paths in use, with the CC BY 4.0
notice, and drop the hand-drawn header icons. The tabs get a little more room.
Clicking the overview's left card opens an editor view while the session has
edited a file or run a command: Mochi and the Read / Edit / Bash / Done phases on
the left, on the right the changed lines in red and green with a few lines of
context, and under them the last command and what it printed. Nothing opens by
itself.

- snippet.rs reads the lines around an edit, only from a regular file inside the
  session's folder, up to 2 MB.
- The relay forwards the last three lines a Bash command printed, without colour
  codes; the rest of tool_response stays out.
CSS cannot transition between two gradients, so the halo's colour flipped in one
step. Ease colour and opacity per frame, like Mochi's position.
GTK's leave-notify reaches the page over IPC and can overtake the last mouse-move
WebKit was still handing it. That move put the mouse "inside" again after the leave,
and since nothing follows a pointer that is gone, the island never started its
auto-close timer; it stayed open until OK was pressed.

Ignore page mouse-moves for 400 ms after a leave. A real re-entry is picked up by the
next moves right after.
The view read its data from the one shared "Claude Code" pill. With several sessions
running, a new prompt in one of them wiped what the view showed and the project name
jumped between them.

Each session now has its own record, keyed by session_id, and the view shows the one
that was active last and has something to show. A session remembers the folder it
started in: its name, the paths in the diff and the folder the file is read from no
longer change when the shell cd's. A finished session is dropped after its view has
been shown; one that never says so is forgotten after 30 minutes.

Copy link
Copy Markdown
Owner

Thanks for all of this! Most of it has now landed on main another way (#307): the language setting (10 languages), plan usage (#171), questions (#172), local models (#173), KDE auto-close (#160). One blocker in what remains: claude -p --allowedTools Read WebSearch WebFetch pre-approves tools without a click, and Read + WebFetch together could send a local file anywhere if a prompt is injected. If you'd like to keep the Claude Code chat fallback, could you rebase it on main as its own PR without pre-approved tools?


Generated by Claude Code

This branch has not been deployed

No deployments
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.

2 participants