feat(window): use the frameless title bar on Linux (#279)

Linux windows used the GTK menu bar and the system title bar, unlike the frameless main toolbar on Windows.

Linux project and Settings windows now turn off decorations, install no GTK menu bar and draw the main menu and caption buttons in the title bar.

Co-authored-by: xRookieFight <[email protected]>
This commit is contained in:
xRookieFightandxRookieFight authored and GitHub committed 2026-10-31 12:43:01 +08:00
1 parent cbdc177bbc
commit a553dafa7a
8 files changed
+30 -12

No files matched your search

+3 -3
View File
@@ -1173,10 +1173,10 @@ pub fn model(spec: &[Entry], recent: &[RecentItem], config: &MenuConfig) -> Vec<
out
}
/// Whether the OS menu bar is used. Windows project windows draw IDEA's
/// hamburger menu in their own title bar instead.
/// Whether the OS menu bar is used. Windows and Linux project windows are
/// frameless and draw IDEA's hamburger menu in their own title bar instead.
pub fn native_menu_bar() -> bool {
!cfg!(target_os = "windows")
cfg!(target_os = "macos")
}
/// Rebuilds and installs the app menu from the current config and recent list.
+1 -1
View File
@@ -724,7 +724,7 @@ pub fn open_settings_window(
let mut config = window_config(app)?;
config.label = label.clone();
config.title = "Settings".into();
// Frameless on Windows like project windows (tauri.windows.conf.json): the page draws
// Frameless on Windows and Linux like project windows (tauri.<os>.conf.json): the page draws
// the title bar in the app theme instead of a system caption that follows the OS theme.
(config.width, config.height) = SETTINGS_SIZE;
(config.min_width, config.min_height) = (Some(SETTINGS_MIN_SIZE.0), Some(SETTINGS_MIN_SIZE.1));
+18
View File
@@ -0,0 +1,18 @@
{
"app": {
"windows": [
{
"label": "main",
"create": false,
"title": "OpenIDEA",
"width": 1440,
"height": 900,
"minWidth": 800,
"minHeight": 500,
"decorations": false,
"backgroundColor": "#E9EAEE",
"dragDropEnabled": true
}
]
}
}
+3 -3
View File
@@ -7,7 +7,7 @@ interface PlatformInfo {
version: string | null;
/** Native traffic lights overlay the title bar (Tauri, macOS, Overlay style). */
overlayTitleBar: boolean;
/** Frameless window: the title bar draws the main menu and caption buttons (Tauri, Windows). */
/** Frameless window: the title bar draws the main menu and caption buttons (Tauri, Windows and Linux). */
framelessTitleBar: boolean;
}
@@ -27,7 +27,7 @@ export const usePlatform = create<PlatformInfo>(() => {
os,
version: null,
overlayTitleBar: isTauri() && os === "macos",
framelessTitleBar: isTauri() && os === "windows",
framelessTitleBar: isTauri() && (os === "windows" || os === "linux"),
};
});
@@ -39,7 +39,7 @@ export async function loadPlatformInfo() {
os: info.platform,
version: info.version,
overlayTitleBar: info.platform === "macos",
framelessTitleBar: info.platform === "windows",
framelessTitleBar: info.platform === "windows" || info.platform === "linux",
});
} catch {
/* keep the user-agent guess */
+1 -1
View File
@@ -1,5 +1,5 @@
/**
* Windows title bar: IDEA's main menu button. Clicking ☰ expands the menu bar
* Frameless title bar (Windows, Linux): IDEA's main menu button. Clicking ☰ expands the menu bar
* in place (File Edit View …) with File open; hovering another title switches
* menus, ←/→ walk them, and closing the menu collapses the bar again. The
* entries come from the same spec as the native menu (`menu_model`). As in
+1 -1
View File
@@ -99,7 +99,7 @@
color: var(--fg-secondary);
}
/* Windows frameless window: caption buttons sit flush with the right and top edges. */
/* Frameless window (Windows, Linux): caption buttons sit flush with the right and top edges. */
.frameless {
padding-right: 0;
}
+2 -2
View File
@@ -256,7 +256,7 @@ function ToolbarEntry({ id, items }: { id: string; items: ReadonlyMap<string, Ti
/**
* 40px main toolbar. macOS: native traffic lights overlay its left edge.
* Windows: the window is frameless, so the bar carries IDEA's main menu (☰) and
* Windows and Linux: the window is frameless, so the bar carries IDEA's main menu (☰) and
* the caption buttons. `dialog`: a dialog window's bar (Settings), close button only.
* `lightEdit`: a LightEdit window's bar, its title and the menu but no toolbar widgets.
*/
@@ -279,7 +279,7 @@ export function TitleBar({
const [menuExpanded, setMenuExpanded] = useState(false);
const className = clsx(styles.bar, overlay && styles.overlay, frameless && styles.frameless);
// Distraction Free Mode: the window frame only. Where the title bar carries the
// main menu (Windows) it stays, or nothing would lead back out of the mode.
// main menu (Windows, Linux) it stays, or nothing would lead back out of the mode.
if (bare)
return (
<header className={className} data-tauri-drag-region data-titlebar="bare">
+1 -1
View File
@@ -1,5 +1,5 @@
/**
* Windows caption buttons (minimise, maximise / restore, close) for the frameless
* Caption buttons (minimise, maximise / restore, close) for the frameless
* title bar. Dialog windows (Settings) only have close, as in IDEA.
*/
import { useEffect, useState } from "react";