From f4e7bda01934d9b5d73ce54834ba0c0c4fa377e3 Mon Sep 17 00:00:00 2001 From: omartelo Date: Mon, 19 Oct 2026 14:36:00 -0300 Subject: [PATCH] fix(native): name the window lich so the dock groups it under lich's icon Gio takes the Wayland app_id and the X11 WM_CLASS from app.ID, which defaults to the binary's name. lich-native matches no .desktop entry, so GNOME docks (reported on Pop!_OS) showed the native window as a separate app with a generic icon beside lich's own. build/linux/lich.desktop claims "lich" (StartupWMClass=lich), the class the web window already uses. The dev window takes "lichdev" under LICH_DEV, as the web one does, so compositor rules for the daily driver never capture it. On Windows, Gio uses the same ID as the window class name; nothing else registers "lich". --- CHANGELOG.md | 1 + native/cmd/lich-native/main.go | 13 +++++++++++ native/cmd/lich-native/windowclass_test.go | 27 ++++++++++++++++++++++ 3 files changed, 41 insertions(+) create mode 100644 native/cmd/lich-native/windowclass_test.go diff --git a/CHANGELOG.md b/CHANGELOG.md index c17d3b6f..1e72d022 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `lich quit` no longer fails with "EOF" when lich quits before answering: it waits for the port to close instead of calling the lost reply a refusal. - On Wayland, the native window shows the desktop's own cursor, in its theme and size, where it could show another theme. On a monitor with a smaller scale than the largest one, the cursor no longer jumps as it enters the window. +- On Linux, the native window groups under lich's own icon in the dock, where it showed up as a separate app with a generic icon. ## [0.71.2] - 2026-10-19 diff --git a/native/cmd/lich-native/main.go b/native/cmd/lich-native/main.go index 04249877..11cf516d 100644 --- a/native/cmd/lich-native/main.go +++ b/native/cmd/lich-native/main.go @@ -56,6 +56,7 @@ var ( func main() { flag.Parse() + app.ID = windowClass(os.Getenv) rt, err := backendRuntime() if err != nil { log.Fatal(err) @@ -81,6 +82,18 @@ func main() { app.Main() } +// windowClass is the Wayland app_id and X11 WM_CLASS. Gio's default, the +// binary's name, matches no .desktop entry, so the dock shows the window as an +// unknown app beside lich's own icon. It mirrors the web window's (main.go's +// windowTarget): build/linux/lich.desktop claims "lich", and the dev window +// keeps its own so compositor rules for the daily driver never capture it. +func windowClass(getenv func(string) string) string { + if getenv("LICH_DEV") != "" { + return "lichdev" + } + return "lich" +} + type window struct { ctx context.Context client *lichclient.Client diff --git a/native/cmd/lich-native/windowclass_test.go b/native/cmd/lich-native/windowclass_test.go new file mode 100644 index 00000000..414229f3 --- /dev/null +++ b/native/cmd/lich-native/windowclass_test.go @@ -0,0 +1,27 @@ +package main + +import "testing" + +func TestWindowClass(t *testing.T) { + cases := []struct { + name string + dev string + want string + }{ + {"installed window matches lich.desktop", "", "lich"}, + {"dev window keeps its own", "1", "lichdev"}, + } + for _, c := range cases { + t.Run(c.name, func(t *testing.T) { + getenv := func(key string) string { + if key == "LICH_DEV" { + return c.dev + } + return "" + } + if got := windowClass(getenv); got != c.want { + t.Errorf("windowClass = %q, want %q", got, c.want) + } + }) + } +}