Files
Thomas Eizinger 3e849ae852 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|
|---|---|
|<img width="1900" height="1174" alt="Screenshot From 2025-11-11
11-14-11"
src="https://github.com/user-attachments/assets/9439a69b-65ba-41d6-b1f8-4448e0f80728"
/>|<img width="1800" height="1000" alt="Screenshot From 2025-11-11
11-40-55"
src="https://github.com/user-attachments/assets/7884b2cc-3d9c-4b47-9a1e-c6462aef36ab"
/>|
|<img width="1900" height="1174" alt="Screenshot From 2025-11-11
11-14-16"
src="https://github.com/user-attachments/assets/2cfea825-5c08-45a5-873c-5afcbc1dbf16"
/>|<img width="1800" height="1000" alt="Screenshot From 2025-11-11
11-40-58"
src="https://github.com/user-attachments/assets/43ddd7c9-ce65-42f7-b972-28c6b172b70d"
/>|
|<img width="1900" height="1174" alt="Screenshot From 2025-11-11
11-14-19"
src="https://github.com/user-attachments/assets/446873a7-9023-4266-9377-ea7b8b4353ee"
/>|<img width="1800" height="1000" alt="Screenshot From 2025-11-11
11-41-01"
src="https://github.com/user-attachments/assets/64439383-f33f-461d-9b4a-6b4138bd675b"
/>|
|<img width="1900" height="1174" alt="Screenshot From 2025-11-11
11-14-22"
src="https://github.com/user-attachments/assets/6c39e06c-1d77-471f-91f1-32a78b90a21c"
/>|<img width="1800" height="1000" alt="Screenshot From 2025-11-11
11-41-04"
src="https://github.com/user-attachments/assets/b56912cb-9c85-4b5a-9295-dae6139b25c6"
/>|
|<img width="1900" height="1174" alt="Screenshot From 2025-11-11
11-14-26"
src="https://github.com/user-attachments/assets/5a5d638c-15bf-4523-8466-2e0977a03e22"
/>|<img width="1800" height="1000" alt="Screenshot From 2025-11-11
11-41-06"
src="https://github.com/user-attachments/assets/ed169b52-ef86-4dc4-8f25-852da622eaa1"
/>|
2025-11-11 05:51:08 +00:00

204 lines
6.5 KiB
TypeScript

import {
Bars3Icon,
CogIcon,
DocumentMagnifyingGlassIcon,
HomeIcon,
InformationCircleIcon,
SwatchIcon,
WrenchScrewdriverIcon,
} from "@heroicons/react/24/solid";
import {
Sidebar,
SidebarCollapse,
SidebarItemGroup,
SidebarItems,
} from "flowbite-react";
import React, { useEffect, useState } from "react";
import { Route, Routes } from "react-router";
import About from "./AboutPage";
import AdvancedSettingsPage from "./AdvancedSettingsPage";
import ReactRouterSidebarItem from "./ReactRouterSidebarItem";
import ColorPalette from "./ColorPalettePage";
import Diagnostics from "./DiagnosticsPage";
import GeneralSettingsPage from "./GeneralSettingsPage";
import Overview from "./OverviewPage";
import {
AdvancedSettingsViewModel,
commands,
events,
FileCount,
GeneralSettingsViewModel,
SessionViewModel,
} from "../generated/bindings";
import Titlebar from "./Titlebar";
export default function App() {
const [session, setSession] = useState<SessionViewModel | null>(null);
const [logCount, setLogCount] = useState<FileCount | null>(null);
const [generalSettings, setGeneralSettings] =
useState<GeneralSettingsViewModel | null>(null);
const [advancedSettings, setAdvancedSettings] =
useState<AdvancedSettingsViewModel | null>(null);
useEffect(() => {
const sessionChangedUnlisten = events.sessionChanged.listen((e) => {
const session = e.payload;
console.log("session_changed", { session });
setSession(session);
});
const generalSettingsChangedUnlisten = events.generalSettingsChanged.listen(
(e) => {
const generalSettings = e.payload;
console.log("general_settings_changed", { settings: generalSettings });
setGeneralSettings(generalSettings);
}
);
const advancedSettingsChangedUnlisten =
events.advancedSettingsChanged.listen((e) => {
const advancedSettings = e.payload;
console.log("advanced_settings_changed", {
settings: advancedSettings,
});
setAdvancedSettings(advancedSettings);
});
const logsRecountedUnlisten = events.logsRecounted.listen((e) => {
const file_count = e.payload;
console.log("logs_recounted", { file_count });
setLogCount(file_count);
});
commands.updateState(); // Let the backend know that we (re)-initialised
return () => {
sessionChangedUnlisten.then((unlistenFn) => unlistenFn());
generalSettingsChangedUnlisten.then((unlistenFn) => unlistenFn());
advancedSettingsChangedUnlisten.then((unlistenFn) => unlistenFn());
logsRecountedUnlisten.then((unlistenFn) => unlistenFn());
};
}, []);
const isDev = import.meta.env.DEV;
return (
<div className="h-screen flex flex-col rounded-lg border border-neutral-300 overflow-hidden">
<Routes>
<Route path="/overview" element={<Titlebar title={"Firezone"} />} />
<Route
path="/general-settings"
element={<Titlebar title={"General Settings"} />}
/>
<Route
path="/advanced-settings"
element={<Titlebar title={"Advanced Settings"} />}
/>
<Route
path="/diagnostics"
element={<Titlebar title={"Diagnostics"} />}
/>
<Route path="/about" element={<Titlebar title={"About"} />} />
<Route
path="/colour-palette"
element={<Titlebar title={"Colour Palette"} />}
/>
</Routes>
<div className="flex-1 bg-neutral-50 flex flex-row">
<Sidebar
aria-label="Sidebar"
className="w-52 flex-shrink-0 border-r border-neutral-200"
>
<SidebarItems>
<SidebarItemGroup>
<ReactRouterSidebarItem icon={HomeIcon} href="/overview">
Overview
</ReactRouterSidebarItem>
<SidebarCollapse label="Settings" open={true} icon={Bars3Icon}>
<ReactRouterSidebarItem icon={CogIcon} href="/general-settings">
General
</ReactRouterSidebarItem>
<ReactRouterSidebarItem
icon={WrenchScrewdriverIcon}
href="/advanced-settings"
>
Advanced
</ReactRouterSidebarItem>
</SidebarCollapse>
<ReactRouterSidebarItem
icon={DocumentMagnifyingGlassIcon}
href="/diagnostics"
>
Diagnostics
</ReactRouterSidebarItem>
<ReactRouterSidebarItem
icon={InformationCircleIcon}
href="/about"
>
About
</ReactRouterSidebarItem>
</SidebarItemGroup>
{isDev && (
<SidebarItemGroup>
<ReactRouterSidebarItem
icon={SwatchIcon}
href="/colour-palette"
>
Color Palette
</ReactRouterSidebarItem>
</SidebarItemGroup>
)}
</SidebarItems>
</Sidebar>
<main className="flex-grow overflow-auto">
<Routes>
<Route
path="/overview"
element={
<Overview
session={session}
signIn={commands.signIn}
signOut={commands.signOut}
/>
}
/>
<Route
path="/general-settings"
element={
<GeneralSettingsPage
settings={generalSettings}
saveSettings={commands.applyGeneralSettings}
resetSettings={commands.resetGeneralSettings}
/>
}
/>
<Route
path="/advanced-settings"
element={
<AdvancedSettingsPage
settings={advancedSettings}
saveSettings={commands.applyAdvancedSettings}
resetSettings={commands.resetAdvancedSettings}
/>
}
/>
<Route
path="/diagnostics"
element={
<Diagnostics
logCount={logCount}
exportLogs={commands.exportLogs}
clearLogs={commands.clearLogs}
/>
}
/>
<Route path="/about" element={<About />} />
<Route path="/colour-palette" element={<ColorPalette />} />
</Routes>
</main>
</div>
</div>
);
}