Skip to content

Add a setting to hide the title bar - #2

Open
calops wants to merge 1 commit into
obazin:mainfrom
calops:settings/hide-title-bar
Open

calops wants to merge 1 commit into
obazin:mainfrom
calops:settings/hide-title-bar

Conversation

@calops

@calops calops commented Aug 30, 2026

Copy link
Copy Markdown
Contributor

Hide the title bar is now persisted with preferences. On Linux and Windows it takes effect next time Janis opens: main is constructed after preferences load, so GTK receives decorations = false before the window is realized. The app header then exposes minimize, maximize/restore and close. macOS keeps titleBarStyle: Overlay, so the toggle is not shown there.

Migration 4 adds hide_title_bar; the preference is part of get_preferences and set_title_bar_hidden. The settings UI has English and French strings, and docs/specs.md and CLAUDE.md describe the new command and behavior.

Verified with cargo fmt --check, cargo test (6 passed), debug and release cargo clippy -- -D warnings, pnpm check, pnpm test:unit (8 passed), targeted Prettier (changed code and specs), and a pnpm tauri dev smoke launch. The repository-wide Prettier check still reports the existing CLAUDE.md formatting mismatch. The commit is unsigned because 1Password's agent would not sign from this session.

Persist the frame preference in migration 4 and create main after loading
it, so GTK receives the decoration setting before it realizes the
window. On Linux and Windows the setting takes effect at the next app
launch; frameless windows expose minimize, maximize/restore and close
in the existing app header. macOS keeps its overlay titlebar and does
not show the setting.

The preference round-trip and migration path are covered in Rust tests.
The settings UI has English and French strings and the behavior is
recorded in the feature spec.

@obazin obazin left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this — the feature itself is solid, and the persistence plus the in-app min/max/close controls are exactly right. My one substantive concern is the apply mechanism in main.rs, which I think can be much simpler.

The whole window reconstruction — create = false, rebuilding via WebviewWindowBuilder::from_config, manually re-injecting the dev URL, the visible=falseshow() dance — hangs on this premise:

GTK only applies decorations before a window is realized

I don't think that holds for Tauri v2. Both getCurrentWindow().setDecorations(boolean) (JS) and WebviewWindow::set_decorations(bool) (Rust) toggle decorations on a live window, and neither documents a Linux/GTK "must set before realize" caveat (tao maps it to gtk_window_set_decorated, which takes effect at runtime).

If that's right, we can leave the window declared in tauri.conf.json as-is, delete the entire main.rs block, and apply the preference at runtime instead: in +layout.svelte's existing bootPromise (it already loads preferences), if (!isMac) getCurrentWindow().setDecorations(!prefs.hideTitleBar), and have the settings toggle call setDecorations(...) too. That removes the fragile Rust (no create=false, no from_config rebuild, no dev-URL re-injection, no read_preferences in setup) and, as a bonus, makes the toggle take effect immediately instead of on next launch.

The one thing worth confirming first: could you test setDecorations live on Linux/GTK on your side? The docs say it's unconditional, but you clearly hit something that pushed you toward construction-time. If it genuinely flickers or no-ops on some WM there, the construction-time approach is defensible and I'm happy to take the PR closer to as-is. On macOS it's moot (overlay style, the toggle is hidden) and on Windows runtime toggling is fine.

For completeness: decorations: false is also a static window option in tauri.conf.json, but since we want a per-user toggle rather than always-off, the runtime call is the right tool rather than the JSON one.

obazin added a commit that referenced this pull request Aug 31, 2026
Frameless-window toggle persisted with preferences (migration 4 adds
hide_title_bar; set_title_bar_hidden). On Windows/Linux it drops the native
window frame at runtime via the webview's setDecorations, so it applies
instantly rather than on next launch, and the app header then carries its own
minimize, maximize/restore and close controls. macOS keeps titleBarStyle:
Overlay, so the toggle is hidden there.

The apply path lives entirely in the frontend: PreferencesStore.init and
setTitleBarHidden call getCurrentWindow().setDecorations (guarded off macOS).
main.rs and tauri.conf.json are untouched — no window reconstruction, no reading
preferences in setup. This is the simpler alternative to PR #2's approach,
which rebuilt the window in Rust after loading preferences to satisfy a GTK
"decorations before realize" assumption; the Tauri v2 setDecorations API
documents no such runtime limitation. Needs a Linux/GTK smoke test to confirm.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ABuRgJiANb5a87eWFYRJ4B
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