Browse Source

tauri: add basic custom titlebar (#5438)

Brendan Allan 3 months ago
parent
commit
59d4041aa4

+ 3 - 0
bun.lock

@@ -356,6 +356,7 @@
         "@tauri-apps/api": "^2",
         "@tauri-apps/api": "^2",
         "@tauri-apps/plugin-dialog": "~2",
         "@tauri-apps/plugin-dialog": "~2",
         "@tauri-apps/plugin-opener": "^2",
         "@tauri-apps/plugin-opener": "^2",
+        "@tauri-apps/plugin-os": "~2",
         "@tauri-apps/plugin-process": "~2",
         "@tauri-apps/plugin-process": "~2",
         "@tauri-apps/plugin-shell": "~2",
         "@tauri-apps/plugin-shell": "~2",
         "@tauri-apps/plugin-store": "~2",
         "@tauri-apps/plugin-store": "~2",
@@ -1663,6 +1664,8 @@
 
 
     "@tauri-apps/plugin-opener": ["@tauri-apps/[email protected]", "", { "dependencies": { "@tauri-apps/api": "^2.8.0" } }, "sha512-ei/yRRoCklWHImwpCcDK3VhNXx+QXM9793aQ64YxpqVF0BDuuIlXhZgiAkc15wnPVav+IbkYhmDJIv5R326Mew=="],
     "@tauri-apps/plugin-opener": ["@tauri-apps/[email protected]", "", { "dependencies": { "@tauri-apps/api": "^2.8.0" } }, "sha512-ei/yRRoCklWHImwpCcDK3VhNXx+QXM9793aQ64YxpqVF0BDuuIlXhZgiAkc15wnPVav+IbkYhmDJIv5R326Mew=="],
 
 
+    "@tauri-apps/plugin-os": ["@tauri-apps/[email protected]", "", { "dependencies": { "@tauri-apps/api": "^2.8.0" } }, "sha512-n+nXWeuSeF9wcEsSPmRnBEGrRgOy6jjkSU+UVCOV8YUGKb2erhDOxis7IqRXiRVHhY8XMKks00BJ0OAdkpf6+A=="],
+
     "@tauri-apps/plugin-process": ["@tauri-apps/[email protected]", "", { "dependencies": { "@tauri-apps/api": "^2.8.0" } }, "sha512-nCa4fGVaDL/B9ai03VyPOjfAHRHSBz5v6F/ObsB73r/dA3MHHhZtldaDMIc0V/pnUw9ehzr2iEG+XkSEyC0JJA=="],
     "@tauri-apps/plugin-process": ["@tauri-apps/[email protected]", "", { "dependencies": { "@tauri-apps/api": "^2.8.0" } }, "sha512-nCa4fGVaDL/B9ai03VyPOjfAHRHSBz5v6F/ObsB73r/dA3MHHhZtldaDMIc0V/pnUw9ehzr2iEG+XkSEyC0JJA=="],
 
 
     "@tauri-apps/plugin-shell": ["@tauri-apps/[email protected]", "", { "dependencies": { "@tauri-apps/api": "^2.8.0" } }, "sha512-Xod+pRcFxmOWFWEnqH5yZcA7qwAMuaaDkMR1Sply+F8VfBj++CGnj2xf5UoialmjZ2Cvd8qrvSCbU+7GgNVsKQ=="],
     "@tauri-apps/plugin-shell": ["@tauri-apps/[email protected]", "", { "dependencies": { "@tauri-apps/api": "^2.8.0" } }, "sha512-Xod+pRcFxmOWFWEnqH5yZcA7qwAMuaaDkMR1Sply+F8VfBj++CGnj2xf5UoialmjZ2Cvd8qrvSCbU+7GgNVsKQ=="],

+ 1 - 1
nix/hashes.json

@@ -1,3 +1,3 @@
 {
 {
-  "nodeModules": "sha256-JiPLmRyjpwiAJSDO6Sah/cMdncMicqQqGrBVOAVHMWA="
+  "nodeModules": "sha256-3CG0wAMQp2E6ghPUXbYaYifJorp9b1WvCtHD+o8Nhck="
 }
 }

+ 2 - 2
packages/desktop/index.html

@@ -14,7 +14,7 @@
     <meta property="og:image" content="/social-share.png" />
     <meta property="og:image" content="/social-share.png" />
     <meta property="twitter:image" content="/social-share.png" />
     <meta property="twitter:image" content="/social-share.png" />
   </head>
   </head>
-  <body class="antialiased overscroll-none select-none text-12-regular">
+  <body class="antialiased overscroll-none select-none text-12-regular overflow-hidden">
     <script>
     <script>
       ;(function () {
       ;(function () {
         const savedTheme = localStorage.getItem("theme") || "oc-1"
         const savedTheme = localStorage.getItem("theme") || "oc-1"
@@ -22,7 +22,7 @@
       })()
       })()
     </script>
     </script>
     <noscript>You need to enable JavaScript to run this app.</noscript>
     <noscript>You need to enable JavaScript to run this app.</noscript>
-    <div id="root"></div>
+    <div id="root" class="flex flex-col h-screen"></div>
     <script src="/src/entry.tsx" type="module"></script>
     <script src="/src/entry.tsx" type="module"></script>
   </body>
   </body>
 </html>
 </html>

+ 2 - 2
packages/desktop/src/pages/layout.tsx

@@ -426,7 +426,7 @@ export default function Layout(props: ParentProps) {
   }
   }
 
 
   return (
   return (
-    <div class="relative h-screen flex flex-col">
+    <div class="relative flex-1 flex flex-col">
       <header class="h-12 shrink-0 bg-background-base border-b border-border-weak-base flex" data-tauri-drag-region>
       <header class="h-12 shrink-0 bg-background-base border-b border-border-weak-base flex" data-tauri-drag-region>
         <A
         <A
           href="/"
           href="/"
@@ -512,7 +512,7 @@ export default function Layout(props: ParentProps) {
           </Show>
           </Show>
         </div>
         </div>
       </header>
       </header>
-      <div class="h-[calc(100vh-3rem)] flex">
+      <div class="h-[calc(100%-3rem)] flex">
         <div
         <div
           classList={{
           classList={{
             "relative @container w-12 pb-5 shrink-0 bg-background-base": true,
             "relative @container w-12 pb-5 shrink-0 bg-background-base": true,

+ 2 - 2
packages/tauri/index.html

@@ -14,7 +14,7 @@
     <meta property="og:image" content="/social-share.png" />
     <meta property="og:image" content="/social-share.png" />
     <meta property="twitter:image" content="/social-share.png" />
     <meta property="twitter:image" content="/social-share.png" />
   </head>
   </head>
-  <body class="antialiased overscroll-none select-none text-12-regular">
+  <body class="antialiased overscroll-none select-none text-12-regular overflow-hidden">
     <script>
     <script>
       ;(function () {
       ;(function () {
         const savedTheme = localStorage.getItem("theme") || "oc-1"
         const savedTheme = localStorage.getItem("theme") || "oc-1"
@@ -22,7 +22,7 @@
       })()
       })()
     </script>
     </script>
     <noscript>You need to enable JavaScript to run this app.</noscript>
     <noscript>You need to enable JavaScript to run this app.</noscript>
-    <div id="root"></div>
+    <div id="root" class="flex flex-col h-screen"></div>
     <script src="/src/index.tsx" type="module"></script>
     <script src="/src/index.tsx" type="module"></script>
   </body>
   </body>
 </html>
 </html>

+ 1 - 0
packages/tauri/package.json

@@ -16,6 +16,7 @@
     "@tauri-apps/api": "^2",
     "@tauri-apps/api": "^2",
     "@tauri-apps/plugin-dialog": "~2",
     "@tauri-apps/plugin-dialog": "~2",
     "@tauri-apps/plugin-opener": "^2",
     "@tauri-apps/plugin-opener": "^2",
+    "@tauri-apps/plugin-os": "~2",
     "@tauri-apps/plugin-process": "~2",
     "@tauri-apps/plugin-process": "~2",
     "@tauri-apps/plugin-shell": "~2",
     "@tauri-apps/plugin-shell": "~2",
     "@tauri-apps/plugin-store": "~2",
     "@tauri-apps/plugin-store": "~2",

+ 84 - 0
packages/tauri/src-tauri/Cargo.lock

@@ -1256,6 +1256,16 @@ dependencies = [
  "version_check",
  "version_check",
 ]
 ]
 
 
+[[package]]
+name = "gethostname"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1bd49230192a3797a9a4d6abe9b3eed6f7fa4c8a8a4947977c6f80025f92cbd8"
+dependencies = [
+ "rustix",
+ "windows-link 0.2.1",
+]
+
 [[package]]
 [[package]]
 name = "getrandom"
 name = "getrandom"
 version = "0.1.16"
 version = "0.1.16"
@@ -2309,6 +2319,16 @@ dependencies = [
  "objc2-foundation 0.3.2",
  "objc2-foundation 0.3.2",
 ]
 ]
 
 
+[[package]]
+name = "objc2-core-location"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ca347214e24bc973fc025fd0d36ebb179ff30536ed1f80252706db19ee452009"
+dependencies = [
+ "objc2 0.6.3",
+ "objc2-foundation 0.3.2",
+]
+
 [[package]]
 [[package]]
 name = "objc2-core-text"
 name = "objc2-core-text"
 version = "0.3.2"
 version = "0.3.2"
@@ -2440,6 +2460,7 @@ checksum = "96c1358452b371bf9f104e21ec536d37a650eb10f7ee379fff67d2e08d537f1f"
 dependencies = [
 dependencies = [
  "bitflags 2.10.0",
  "bitflags 2.10.0",
  "objc2 0.6.3",
  "objc2 0.6.3",
+ "objc2-core-foundation",
  "objc2-foundation 0.3.2",
  "objc2-foundation 0.3.2",
 ]
 ]
 
 
@@ -2461,8 +2482,27 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "d87d638e33c06f577498cbcc50491496a3ed4246998a7fbba7ccb98b1e7eab22"
 checksum = "d87d638e33c06f577498cbcc50491496a3ed4246998a7fbba7ccb98b1e7eab22"
 dependencies = [
 dependencies = [
  "bitflags 2.10.0",
  "bitflags 2.10.0",
+ "block2 0.6.2",
  "objc2 0.6.3",
  "objc2 0.6.3",
+ "objc2-cloud-kit",
+ "objc2-core-data",
  "objc2-core-foundation",
  "objc2-core-foundation",
+ "objc2-core-graphics",
+ "objc2-core-image",
+ "objc2-core-location",
+ "objc2-core-text",
+ "objc2-foundation 0.3.2",
+ "objc2-quartz-core 0.3.2",
+ "objc2-user-notifications",
+]
+
+[[package]]
+name = "objc2-user-notifications"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9df9128cbbfef73cda168416ccf7f837b62737d748333bfe9ab71c245d76613e"
+dependencies = [
+ "objc2 0.6.3",
  "objc2-foundation 0.3.2",
  "objc2-foundation 0.3.2",
 ]
 ]
 
 
@@ -2511,6 +2551,7 @@ dependencies = [
  "tauri-build",
  "tauri-build",
  "tauri-plugin-dialog",
  "tauri-plugin-dialog",
  "tauri-plugin-opener",
  "tauri-plugin-opener",
+ "tauri-plugin-os",
  "tauri-plugin-process",
  "tauri-plugin-process",
  "tauri-plugin-shell",
  "tauri-plugin-shell",
  "tauri-plugin-store",
  "tauri-plugin-store",
@@ -2535,6 +2576,22 @@ dependencies = [
  "pin-project-lite",
  "pin-project-lite",
 ]
 ]
 
 
+[[package]]
+name = "os_info"
+version = "3.13.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7c39b5918402d564846d5aba164c09a66cc88d232179dfd3e3c619a25a268392"
+dependencies = [
+ "android_system_properties",
+ "log",
+ "nix",
+ "objc2 0.6.3",
+ "objc2-foundation 0.3.2",
+ "objc2-ui-kit",
+ "serde",
+ "windows-sys 0.61.2",
+]
+
 [[package]]
 [[package]]
 name = "os_pipe"
 name = "os_pipe"
 version = "1.2.3"
 version = "1.2.3"
@@ -3872,6 +3929,15 @@ dependencies = [
  "syn 2.0.110",
  "syn 2.0.110",
 ]
 ]
 
 
+[[package]]
+name = "sys-locale"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8eab9a99a024a169fe8a903cf9d4a3b3601109bcc13bd9e3c6fff259138626c4"
+dependencies = [
+ "libc",
+]
+
 [[package]]
 [[package]]
 name = "system-deps"
 name = "system-deps"
 version = "6.2.2"
 version = "6.2.2"
@@ -4146,6 +4212,24 @@ dependencies = [
  "zbus",
  "zbus",
 ]
 ]
 
 
+[[package]]
+name = "tauri-plugin-os"
+version = "2.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d8f08346c8deb39e96f86973da0e2d76cbb933d7ac9b750f6dc4daf955a6f997"
+dependencies = [
+ "gethostname",
+ "log",
+ "os_info",
+ "serde",
+ "serde_json",
+ "serialize-to-javascript",
+ "sys-locale",
+ "tauri",
+ "tauri-plugin",
+ "thiserror 2.0.17",
+]
+
 [[package]]
 [[package]]
 name = "tauri-plugin-process"
 name = "tauri-plugin-process"
 version = "2.3.1"
 version = "2.3.1"

+ 1 - 0
packages/tauri/src-tauri/Cargo.toml

@@ -31,3 +31,4 @@ serde = { version = "1", features = ["derive"] }
 serde_json = "1"
 serde_json = "1"
 tokio = "1.48.0"
 tokio = "1.48.0"
 listeners = "0.3"
 listeners = "0.3"
+tauri-plugin-os = "2"

+ 2 - 1
packages/tauri/src-tauri/capabilities/default.json

@@ -13,6 +13,7 @@
     "dialog:default",
     "dialog:default",
     "process:default",
     "process:default",
     "store:default",
     "store:default",
-    "window-state:default"
+    "window-state:default",
+    "os:default"
   ]
   ]
 }
 }

+ 5 - 1
packages/tauri/src-tauri/src/lib.rs

@@ -4,7 +4,9 @@ use std::{
     sync::{Arc, Mutex},
     sync::{Arc, Mutex},
     time::{Duration, Instant},
     time::{Duration, Instant},
 };
 };
-use tauri::{AppHandle, LogicalSize, Manager, Monitor, RunEvent, WebviewUrl, WebviewWindow};
+use tauri::{
+    AppHandle, LogicalSize, Manager, Monitor, RunEvent, TitleBarStyle, WebviewUrl, WebviewWindow,
+};
 use tauri_plugin_dialog::{DialogExt, MessageDialogButtons, MessageDialogResult};
 use tauri_plugin_dialog::{DialogExt, MessageDialogButtons, MessageDialogResult};
 use tauri_plugin_shell::process::{CommandChild, CommandEvent};
 use tauri_plugin_shell::process::{CommandChild, CommandEvent};
 use tauri_plugin_shell::ShellExt;
 use tauri_plugin_shell::ShellExt;
@@ -107,6 +109,7 @@ pub fn run() {
     let updater_enabled = option_env!("TAURI_SIGNING_PRIVATE_KEY").is_some();
     let updater_enabled = option_env!("TAURI_SIGNING_PRIVATE_KEY").is_some();
 
 
     let mut builder = tauri::Builder::default()
     let mut builder = tauri::Builder::default()
+        .plugin(tauri_plugin_os::init())
         .plugin(tauri_plugin_window_state::Builder::new().build())
         .plugin(tauri_plugin_window_state::Builder::new().build())
         .plugin(tauri_plugin_store::Builder::new().build())
         .plugin(tauri_plugin_store::Builder::new().build())
         .plugin(tauri_plugin_dialog::init())
         .plugin(tauri_plugin_dialog::init())
@@ -180,6 +183,7 @@ pub fn run() {
                         .inner_size(size.width as f64, size.height as f64)
                         .inner_size(size.width as f64, size.height as f64)
                         .decorations(true)
                         .decorations(true)
                         .zoom_hotkeys_enabled(true)
                         .zoom_hotkeys_enabled(true)
+                        .title_bar_style(TitleBarStyle::Overlay)
                         .initialization_script(format!(
                         .initialization_script(format!(
                             r#"
                             r#"
                           window.__OPENCODE__ ??= {{}};
                           window.__OPENCODE__ ??= {{}};

+ 4 - 0
packages/tauri/src/index.tsx

@@ -5,6 +5,7 @@ import { runUpdater } from "./updater"
 import { onMount } from "solid-js"
 import { onMount } from "solid-js"
 import { open, save } from "@tauri-apps/plugin-dialog"
 import { open, save } from "@tauri-apps/plugin-dialog"
 import { open as shellOpen } from "@tauri-apps/plugin-shell"
 import { open as shellOpen } from "@tauri-apps/plugin-shell"
+import { type as ostype } from "@tauri-apps/plugin-os"
 
 
 const root = document.getElementById("root")
 const root = document.getElementById("root")
 if (import.meta.env.DEV && !(root instanceof HTMLElement)) {
 if (import.meta.env.DEV && !(root instanceof HTMLElement)) {
@@ -54,6 +55,9 @@ render(() => {
 
 
   return (
   return (
     <PlatformProvider value={platform}>
     <PlatformProvider value={platform}>
+      {ostype() === "macos" && (
+        <div class="bg-background-base border-b border-border-weak-base h-8" data-tauri-drag-region />
+      )}
       <App />
       <App />
     </PlatformProvider>
     </PlatformProvider>
   )
   )