From 3e849ae852932343312a70f3e935e3f84a745b88 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Tue, 11 Nov 2025 16:51:08 +1100 Subject: [PATCH] fix(gui-client): use Wayland rendering backend on Linux (#10849) Previously, we opted into the X11 GTK backend when rendering the GUI Client's window. This is causing issues on newer Linux distributions such as Fedora 43 where Wayland is now the only available compositor. Removing the X11 GTK requires us to draw our own CSDs such as titlebars and a close button. This PR does exactly that by adding a minimalistic title bar. To make better use of the space, we move the section headers into there. |Before|After| |---|---| |Screenshot From 2025-11-11
11-14-11|Screenshot From 2025-11-11
11-40-55| |Screenshot From 2025-11-11
11-14-16|Screenshot From 2025-11-11
11-40-58| |Screenshot From 2025-11-11
11-14-19|Screenshot From 2025-11-11
11-41-01| |Screenshot From 2025-11-11
11-14-22|Screenshot From 2025-11-11
11-41-04| |Screenshot From 2025-11-11
11-14-26|Screenshot From 2025-11-11
11-41-06| --- .../components/AdvancedSettingsPage.tsx | 4 - .../src-frontend/components/App.tsx | 191 ++++++++++-------- .../components/DiagnosticsPage.tsx | 4 - .../components/GeneralSettingsPage.tsx | 5 - .../src-frontend/components/OverviewPage.tsx | 2 +- .../src-frontend/components/Titlebar.tsx | 45 +++++ .../src-tauri/capabilities/default.json | 2 + .../src-tauri/src/bin/firezone-gui-client.rs | 6 - rust/gui-client/src-tauri/tauri.conf.json | 4 +- website/src/components/Changelog/GUI.tsx | 5 + 10 files changed, 166 insertions(+), 102 deletions(-) create mode 100644 rust/gui-client/src-frontend/components/Titlebar.tsx diff --git a/rust/gui-client/src-frontend/components/AdvancedSettingsPage.tsx b/rust/gui-client/src-frontend/components/AdvancedSettingsPage.tsx index d04e139c5..6b464aca9 100644 --- a/rust/gui-client/src-frontend/components/AdvancedSettingsPage.tsx +++ b/rust/gui-client/src-frontend/components/AdvancedSettingsPage.tsx @@ -45,10 +45,6 @@ export default function AdvancedSettingsPage({ return (
-
-

Advanced Settings

-
-

WARNING: These settings are intended for internal debug purposes only. Changing these is not supported and will diff --git a/rust/gui-client/src-frontend/components/App.tsx b/rust/gui-client/src-frontend/components/App.tsx index 6f1cb7da6..3b73c94ac 100644 --- a/rust/gui-client/src-frontend/components/App.tsx +++ b/rust/gui-client/src-frontend/components/App.tsx @@ -30,6 +30,7 @@ import { GeneralSettingsViewModel, SessionViewModel, } from "../generated/bindings"; +import Titlebar from "./Titlebar"; export default function App() { const [session, setSession] = useState(null); @@ -83,92 +84,120 @@ export default function App() { const isDev = import.meta.env.DEV; return ( -

- - - - - Overview - - - - General +
+ + } /> + } + /> + } + /> + } + /> + } /> + } + /> + +
+ + + + + Overview + + + + General + + + Advanced + + + + Diagnostics - Advanced - - - - Diagnostics - - - About - - - {isDev && ( - - - Color Palette + About - )} - - -
- - - } - /> - - } - /> - - } - /> - - } - /> - } /> - } /> - -
+ {isDev && ( + + + Color Palette + + + )} + + +
+ + + } + /> + + } + /> + + } + /> + + } + /> + } /> + } /> + +
+
); } diff --git a/rust/gui-client/src-frontend/components/DiagnosticsPage.tsx b/rust/gui-client/src-frontend/components/DiagnosticsPage.tsx index 424a3fd9c..6b9768f56 100644 --- a/rust/gui-client/src-frontend/components/DiagnosticsPage.tsx +++ b/rust/gui-client/src-frontend/components/DiagnosticsPage.tsx @@ -21,10 +21,6 @@ export default function Diagnostics({ return (
-
-

Diagnostic Logs

-
-

Log directory size:

diff --git a/rust/gui-client/src-frontend/components/GeneralSettingsPage.tsx b/rust/gui-client/src-frontend/components/GeneralSettingsPage.tsx index 9e2cad341..82d798f8e 100644 --- a/rust/gui-client/src-frontend/components/GeneralSettingsPage.tsx +++ b/rust/gui-client/src-frontend/components/GeneralSettingsPage.tsx @@ -43,13 +43,8 @@ export default function GeneralSettingsPage({ const startMinimizedInputId = useId(); const startOnLoginInputId = useId(); const connectOnStartInputId = useId(); - return (
-
-

General settings

-
-
{ e.preventDefault(); diff --git a/rust/gui-client/src-frontend/components/OverviewPage.tsx b/rust/gui-client/src-frontend/components/OverviewPage.tsx index 370ecb5ee..20d673ead 100644 --- a/rust/gui-client/src-frontend/components/OverviewPage.tsx +++ b/rust/gui-client/src-frontend/components/OverviewPage.tsx @@ -11,7 +11,7 @@ interface OverviewPageProps { export default function Overview(props: OverviewPageProps) { return ( -
+
Firezone Logo

Firezone

diff --git a/rust/gui-client/src-frontend/components/Titlebar.tsx b/rust/gui-client/src-frontend/components/Titlebar.tsx new file mode 100644 index 000000000..96ae96a79 --- /dev/null +++ b/rust/gui-client/src-frontend/components/Titlebar.tsx @@ -0,0 +1,45 @@ +import { XMarkIcon } from "@heroicons/react/16/solid"; +import { getCurrentWindow } from "@tauri-apps/api/window"; +import { Navbar } from "flowbite-react"; +import React from "react"; + +export interface TitlebarProps { + title?: string; +} + +export default function Titlebar({ title }: TitlebarProps) { + const handleMouseDown = (e: React.MouseEvent) => { + if (e.buttons === 1) { + getCurrentWindow().startDragging(); + } + }; + + return ( +
+ +

{title}

+
e.stopPropagation()} + onClick={() => getCurrentWindow().close()} + > + +
+
+
+ ); +} diff --git a/rust/gui-client/src-tauri/capabilities/default.json b/rust/gui-client/src-tauri/capabilities/default.json index bd4153aba..bf44a8d81 100644 --- a/rust/gui-client/src-tauri/capabilities/default.json +++ b/rust/gui-client/src-tauri/capabilities/default.json @@ -7,6 +7,8 @@ "core:path:default", "core:event:default", "core:window:default", + "core:window:allow-start-dragging", + "core:window:allow-close", "core:app:default", "core:resources:default", "core:menu:default", diff --git a/rust/gui-client/src-tauri/src/bin/firezone-gui-client.rs b/rust/gui-client/src-tauri/src/bin/firezone-gui-client.rs index 87b861439..918ed95b3 100644 --- a/rust/gui-client/src-tauri/src/bin/firezone-gui-client.rs +++ b/rust/gui-client/src-tauri/src/bin/firezone-gui-client.rs @@ -20,12 +20,6 @@ fn main() -> ExitCode { let mut bootstrap_log_guard = Some(firezone_logging::setup_bootstrap().expect("Failed to setup bootstrap logger")); - // Mitigates a bug in Ubuntu 22.04 - Under Wayland, some features of the window decorations like minimizing, closing the windows, etc., doesn't work unless you double-click the titlebar first. - // SAFETY: No other thread is running yet - unsafe { - std::env::set_var("GDK_BACKEND", "x11"); - } - let cli = Cli::parse(); let mut telemetry = if cli.is_telemetry_allowed() { diff --git a/rust/gui-client/src-tauri/tauri.conf.json b/rust/gui-client/src-tauri/tauri.conf.json index 80c904af2..108dcc29a 100644 --- a/rust/gui-client/src-tauri/tauri.conf.json +++ b/rust/gui-client/src-tauri/tauri.conf.json @@ -64,6 +64,7 @@ }, "windows": [ { + "decorations": false, "label": "main", "title": "Firezone", "url": "index.html", @@ -71,7 +72,8 @@ "resizable": false, "width": 900, "height": 500, - "visible": false + "visible": false, + "transparent": true } ] } diff --git a/website/src/components/Changelog/GUI.tsx b/website/src/components/Changelog/GUI.tsx index 401031493..113428bba 100644 --- a/website/src/components/Changelog/GUI.tsx +++ b/website/src/components/Changelog/GUI.tsx @@ -21,6 +21,11 @@ export default function GUI({ os }: { os: OS }) { Fixes an issue where the order of upstream / system DNS resolvers was not respected. + {os == OS.Linux && ( + + Fixes some rendering issues on Wayland-only systems. + + )}