Skip to content

[FEATURE] Desktop: Use custom titlebar instead of native GNOME/GTK titlebar on Linux #36225

Description

@cyrasafia

Feature hasn't been suggested before.

Describe the enhancement you want to request

On macOS and Windows, the opencode desktop app creates frameless/hidden-titlebar windows and renders its own custom titlebar. On Linux, neither branch applies, so the window uses Electron's default frame: true and the compositor (GNOME/Mutter, etc.) draws the native GTK titlebar. This is visually inconsistent with the other platforms and cannot be customized through opencode.json or opencode-desktop-flags.conf.

Current behavior: Native GNOME/GTK titlebar on Linux.

Expected behavior: The app's own custom titlebar on Linux, matching the Windows/macOS experience (or an option to opt in).

Root cause

In out/main/index.js (createMainWindow, around line 1237–1245):

...process.platform === "darwin" ? {
  titleBarStyle: "hidden",
  trafficLightPosition: { x: 14, y: 14 }
} : {},
...process.platform === "win32" ? {
  frame: false,
  titleBarStyle: "hidden",
  titleBarOverlay: overlay({ mode })
} : {},

There is no Linux branch, so BrowserWindow falls through to the default frame. Additionally, updateTitlebar() (around line 1185) returns early unless process.platform === "win32", so the custom-titlebar overlay logic is disabled on Linux even though the renderer already exposes a setTitlebar IPC (out/preload/index.js:112).

Environment

  • OpenCode desktop 1.17.15 (packaged), Electron 42.3.3 / Chrome 148
  • Linux, GNOME (Mutter) — reproduced on X11 and Wayland
  • Installed via system package at /opt/OpenCode/ai.opencode.desktop

Suggested fix

Add a Linux branch so the window is frameless with the app's custom titlebar, mirroring the Windows branch:

...process.platform === "linux" ? {
  frame: false,
  titleBarStyle: "hidden",
  titleBarOverlay: overlay({ mode })
} : {},

Electron 42 supports titleBarOverlay on Linux, so win.setTitleBarOverlay(...) should work. updateTitlebar() would also need its guard relaxed to allow win32 and linux (e.g. if (process.platform !== "win32" && process.platform !== "linux") return;).

If full frameless-on-Linux is too aggressive for tiling-WM users, a more conservative option is to gate it behind a setting/env var (e.g. OC_LINUX_DECORATIONS=custom|native, defaulting to custom), which also subsumes the request in #15292.

Why this matters

  • Visual/UX consistency across platforms
  • The app already ships the custom-titlebar UI for macOS/Windows — Linux gets a second-class experience
  • Native GTK titlebar theming often clashes with the app's dark/light theme, and GNOME's CSD doesn't always play well with the in-app header

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions