From 1ce50e0c1bce33101a649398a716be4eb55cee5f Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Fri, 31 May 2024 08:43:35 -0700 Subject: [PATCH] Window border on Linux --- src-tauri/gen/schemas/linux-schema.json | 133 +++++++++++++++++++++++ src-tauri/src/http_request.rs | 4 +- src-tauri/src/lib.rs | 7 +- src-tauri/src/models.rs | 4 +- src-tauri/src/plugin.rs | 10 +- src-tauri/src/tauri_plugin_mac_window.rs | 34 +++--- src-tauri/src/updates.rs | 3 +- src-tauri/src/window_menu.rs | 4 +- src-web/components/DefaultLayout.tsx | 12 +- src-web/components/Settings/Settings.tsx | 4 +- 10 files changed, 180 insertions(+), 35 deletions(-) diff --git a/src-tauri/gen/schemas/linux-schema.json b/src-tauri/gen/schemas/linux-schema.json index e35feebf..4776f4b7 100644 --- a/src-tauri/gen/schemas/linux-schema.json +++ b/src-tauri/gen/schemas/linux-schema.json @@ -2216,6 +2216,13 @@ "shell:allow-open" ] }, + { + "description": "shell:allow-spawn -> Enables the spawn command without any pre-configured scope.", + "type": "string", + "enum": [ + "shell:allow-spawn" + ] + }, { "description": "shell:allow-stdin-write -> Enables the stdin_write command without any pre-configured scope.", "type": "string", @@ -2244,6 +2251,13 @@ "shell:deny-open" ] }, + { + "description": "shell:deny-spawn -> Denies the spawn command without any pre-configured scope.", + "type": "string", + "enum": [ + "shell:deny-spawn" + ] + }, { "description": "shell:deny-stdin-write -> Denies the stdin_write command without any pre-configured scope.", "type": "string", @@ -2498,6 +2512,69 @@ "clipboard-manager:deny-write-text" ] }, + { + "description": "deep-link:default -> Allows reading the opened deep link via the get_current command", + "type": "string", + "enum": [ + "deep-link:default" + ] + }, + { + "description": "deep-link:allow-get-current -> Enables the get_current command without any pre-configured scope.", + "type": "string", + "enum": [ + "deep-link:allow-get-current" + ] + }, + { + "description": "deep-link:allow-is-registered -> Enables the is_registered command without any pre-configured scope.", + "type": "string", + "enum": [ + "deep-link:allow-is-registered" + ] + }, + { + "description": "deep-link:allow-register -> Enables the register command without any pre-configured scope.", + "type": "string", + "enum": [ + "deep-link:allow-register" + ] + }, + { + "description": "deep-link:allow-unregister -> Enables the unregister command without any pre-configured scope.", + "type": "string", + "enum": [ + "deep-link:allow-unregister" + ] + }, + { + "description": "deep-link:deny-get-current -> Denies the get_current command without any pre-configured scope.", + "type": "string", + "enum": [ + "deep-link:deny-get-current" + ] + }, + { + "description": "deep-link:deny-is-registered -> Denies the is_registered command without any pre-configured scope.", + "type": "string", + "enum": [ + "deep-link:deny-is-registered" + ] + }, + { + "description": "deep-link:deny-register -> Denies the register command without any pre-configured scope.", + "type": "string", + "enum": [ + "deep-link:deny-register" + ] + }, + { + "description": "deep-link:deny-unregister -> Denies the unregister command without any pre-configured scope.", + "type": "string", + "enum": [ + "deep-link:deny-unregister" + ] + }, { "type": "string", "enum": [ @@ -5323,6 +5400,13 @@ "shell:allow-open" ] }, + { + "description": "shell:allow-spawn -> Enables the spawn command without any pre-configured scope.", + "type": "string", + "enum": [ + "shell:allow-spawn" + ] + }, { "description": "shell:allow-stdin-write -> Enables the stdin_write command without any pre-configured scope.", "type": "string", @@ -5351,6 +5435,13 @@ "shell:deny-open" ] }, + { + "description": "shell:deny-spawn -> Denies the spawn command without any pre-configured scope.", + "type": "string", + "enum": [ + "shell:deny-spawn" + ] + }, { "description": "shell:deny-stdin-write -> Denies the stdin_write command without any pre-configured scope.", "type": "string", @@ -5533,6 +5624,13 @@ "updater:allow-check" ] }, + { + "description": "updater:allow-download -> Enables the download command without any pre-configured scope.", + "type": "string", + "enum": [ + "updater:allow-download" + ] + }, { "description": "updater:allow-download-and-install -> Enables the download_and_install command without any pre-configured scope.", "type": "string", @@ -5540,6 +5638,13 @@ "updater:allow-download-and-install" ] }, + { + "description": "updater:allow-install -> Enables the install command without any pre-configured scope.", + "type": "string", + "enum": [ + "updater:allow-install" + ] + }, { "description": "updater:deny-check -> Denies the check command without any pre-configured scope.", "type": "string", @@ -5547,6 +5652,13 @@ "updater:deny-check" ] }, + { + "description": "updater:deny-download -> Denies the download command without any pre-configured scope.", + "type": "string", + "enum": [ + "updater:deny-download" + ] + }, { "description": "updater:deny-download-and-install -> Denies the download_and_install command without any pre-configured scope.", "type": "string", @@ -5554,6 +5666,13 @@ "updater:deny-download-and-install" ] }, + { + "description": "updater:deny-install -> Denies the install command without any pre-configured scope.", + "type": "string", + "enum": [ + "updater:deny-install" + ] + }, { "description": "webview:default -> Default permissions for the plugin.", "type": "string", @@ -5897,6 +6016,13 @@ "window:allow-minimize" ] }, + { + "description": "window:allow-monitor-from-point -> Enables the monitor_from_point command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:allow-monitor-from-point" + ] + }, { "description": "window:allow-outer-position -> Enables the outer_position command without any pre-configured scope.", "type": "string", @@ -6331,6 +6457,13 @@ "window:deny-minimize" ] }, + { + "description": "window:deny-monitor-from-point -> Denies the monitor_from_point command without any pre-configured scope.", + "type": "string", + "enum": [ + "window:deny-monitor-from-point" + ] + }, { "description": "window:deny-outer-position -> Denies the outer_position command without any pre-configured scope.", "type": "string", diff --git a/src-tauri/src/http_request.rs b/src-tauri/src/http_request.rs index 88976218..aaf1402d 100644 --- a/src-tauri/src/http_request.rs +++ b/src-tauri/src/http_request.rs @@ -7,11 +7,11 @@ use std::sync::Arc; use std::time::Duration; use base64::Engine; -use http::{HeaderMap, HeaderName, HeaderValue, Method}; use http::header::{ACCEPT, USER_AGENT}; +use http::{HeaderMap, HeaderName, HeaderValue, Method}; use log::{error, info, warn}; -use reqwest::{multipart, Url}; use reqwest::redirect::Policy; +use reqwest::{multipart, Url}; use sqlx::types::{Json, JsonValue}; use tauri::{Manager, WebviewWindow}; use tokio::sync::oneshot; diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index ea2be0e1..4b068b93 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -1563,6 +1563,11 @@ pub fn run() { builder = builder.plugin(tauri_plugin_mac_window::init()); } + #[cfg(target_os = "linux")] + { + builder = builder; // Don't complain about not being mut + } + builder .plugin( tauri_plugin_log::Builder::default() @@ -1804,6 +1809,7 @@ fn create_nested_window( } fn create_window(handle: &AppHandle, url: &str) -> WebviewWindow { + #[allow(unused_variables)] let menu = app_menu(handle).unwrap(); // This causes the window to not be clickable (in AppImage), so disable on Linux @@ -1830,7 +1836,6 @@ fn create_window(handle: &AppHandle, url: &str) -> WebviewWindow { #[cfg(target_os = "macos")] { win_builder = win_builder - // .menu(app_menu) .hidden_title(true) .title_bar_style(TitleBarStyle::Overlay); } diff --git a/src-tauri/src/models.rs b/src-tauri/src/models.rs index e25768a4..2982526f 100644 --- a/src-tauri/src/models.rs +++ b/src-tauri/src/models.rs @@ -4,9 +4,9 @@ use std::fs; use log::error; use rand::distributions::{Alphanumeric, DistString}; use serde::{Deserialize, Serialize}; -use sqlx::{Pool, Sqlite}; -use sqlx::types::{Json, JsonValue}; use sqlx::types::chrono::NaiveDateTime; +use sqlx::types::{Json, JsonValue}; +use sqlx::{Pool, Sqlite}; use tauri::{AppHandle, Manager, WebviewWindow, Wry}; use tokio::sync::Mutex; diff --git a/src-tauri/src/plugin.rs b/src-tauri/src/plugin.rs index c55ac836..1fd56d14 100644 --- a/src-tauri/src/plugin.rs +++ b/src-tauri/src/plugin.rs @@ -1,16 +1,16 @@ use std::rc::Rc; -use boa_engine::{ - Context, js_string, JsNativeError, JsValue, Module, module::SimpleModuleLoader, - property::Attribute, Source, -}; use boa_engine::builtins::promise::PromiseState; +use boa_engine::{ + js_string, module::SimpleModuleLoader, property::Attribute, Context, JsNativeError, JsValue, + Module, Source, +}; use boa_runtime::Console; use log::{debug, error}; use serde::{Deserialize, Serialize}; use serde_json::json; -use tauri::{AppHandle, Manager}; use tauri::path::BaseDirectory; +use tauri::{AppHandle, Manager}; use crate::models::{HttpRequest, WorkspaceExportResources}; diff --git a/src-tauri/src/tauri_plugin_mac_window.rs b/src-tauri/src/tauri_plugin_mac_window.rs index 6b6cec00..3cfbd439 100644 --- a/src-tauri/src/tauri_plugin_mac_window.rs +++ b/src-tauri/src/tauri_plugin_mac_window.rs @@ -1,7 +1,10 @@ use hex_color::HexColor; use objc::{msg_send, sel, sel_impl}; use rand::{distributions::Alphanumeric, Rng}; -use tauri::{Manager, plugin::{Builder, TauriPlugin}, Runtime, Window, WindowEvent}; +use tauri::{ + plugin::{Builder, TauriPlugin}, + Manager, Runtime, Window, WindowEvent, +}; const WINDOW_CONTROL_PAD_X: f64 = 13.0; const WINDOW_CONTROL_PAD_Y: f64 = 18.0; @@ -15,24 +18,21 @@ unsafe impl Sync for UnsafeWindowHandle {} pub fn init() -> TauriPlugin { Builder::new("mac_window") .on_window_ready(|window| { - #[cfg(target_os = "macos")] { + #[cfg(target_os = "macos")] + { setup_traffic_light_positioner(&window); let h = window.app_handle(); let window_for_theme = window.clone(); let id1 = h.listen("yaak_bg_changed", move |ev| { - let payload = serde_json::from_str::<&str>(ev.payload()) - .unwrap() - .trim(); + let payload = serde_json::from_str::<&str>(ev.payload()).unwrap().trim(); let color = HexColor::parse_rgb(payload).unwrap(); update_window_theme(window_for_theme.clone(), color); }); let window_for_title = window.clone(); let id2 = h.listen("yaak_title_changed", move |ev| { - let payload = serde_json::from_str::<&str>(ev.payload()) - .unwrap() - .trim(); + let payload = serde_json::from_str::<&str>(ev.payload()).unwrap().trim(); update_window_title(window_for_title.clone(), payload.to_string()); }); @@ -54,11 +54,7 @@ pub fn init() -> TauriPlugin { #[cfg(target_os = "macos")] fn update_window_title(window: Window, title: String) { - use cocoa::{ - appkit::NSWindow, - base::nil, - foundation::NSString, - }; + use cocoa::{appkit::NSWindow, base::nil, foundation::NSString}; unsafe { let window_handle = UnsafeWindowHandle(window.ns_window().unwrap()); @@ -76,7 +72,8 @@ fn update_window_title(window: Window, title: String) { label, ); }); - }} + } +} #[cfg(target_os = "macos")] fn update_window_theme(window: Window, color: HexColor) { @@ -156,9 +153,9 @@ struct WindowState { #[cfg(target_os = "macos")] pub fn setup_traffic_light_positioner(window: &Window) { - use cocoa::delegate; use cocoa::appkit::NSWindow; - use cocoa::base::{BOOL, id}; + use cocoa::base::{id, BOOL}; + use cocoa::delegate; use cocoa::foundation::NSUInteger; use objc::runtime::{Object, Sel}; use std::ffi::c_void; @@ -182,7 +179,6 @@ pub fn setup_traffic_light_positioner(window: &Window) { func(ptr); } - unsafe { let ns_win = window .ns_window() @@ -410,7 +406,9 @@ pub fn setup_traffic_light_positioner(window: &Window) { // Are we de-allocing this properly ? (I miss safe Rust :( ) let window_label = window.label().to_string(); - let app_state = WindowState { window: window.clone() }; + let app_state = WindowState { + window: window.clone(), + }; let app_box = Box::into_raw(Box::new(app_state)) as *mut c_void; let random_str: String = rand::thread_rng() .sample_iter(&Alphanumeric) diff --git a/src-tauri/src/updates.rs b/src-tauri/src/updates.rs index 5e5a92a9..414ae59c 100644 --- a/src-tauri/src/updates.rs +++ b/src-tauri/src/updates.rs @@ -65,8 +65,7 @@ impl YaakUpdater { .check() .await; - match update_check_result - { + match update_check_result { Ok(Some(update)) => { let h = app_handle.clone(); app_handle diff --git a/src-tauri/src/window_menu.rs b/src-tauri/src/window_menu.rs index d9a0b42a..2ffb2a77 100644 --- a/src-tauri/src/window_menu.rs +++ b/src-tauri/src/window_menu.rs @@ -1,8 +1,8 @@ -pub use tauri::AppHandle; use tauri::menu::{ - AboutMetadata, HELP_SUBMENU_ID, Menu, MenuItemBuilder, PredefinedMenuItem, Submenu, + AboutMetadata, Menu, MenuItemBuilder, PredefinedMenuItem, Submenu, HELP_SUBMENU_ID, WINDOW_SUBMENU_ID, }; +pub use tauri::AppHandle; use tauri::Wry; pub fn app_menu(app_handle: &AppHandle) -> tauri::Result> { diff --git a/src-web/components/DefaultLayout.tsx b/src-web/components/DefaultLayout.tsx index 581d6ece..20b510f3 100644 --- a/src-web/components/DefaultLayout.tsx +++ b/src-web/components/DefaultLayout.tsx @@ -2,12 +2,22 @@ import { Outlet } from 'react-router-dom'; import { DialogProvider } from './DialogContext'; import { GlobalHooks } from './GlobalHooks'; import { ToastProvider } from './ToastContext'; +import classNames from 'classnames'; +import { useOsInfo } from '../hooks/useOsInfo'; export function DefaultLayout() { + const osInfo = useOsInfo(); return ( - +
+ +
diff --git a/src-web/components/Settings/Settings.tsx b/src-web/components/Settings/Settings.tsx index 99fb8dc5..ddd33e4f 100644 --- a/src-web/components/Settings/Settings.tsx +++ b/src-web/components/Settings/Settings.tsx @@ -28,7 +28,7 @@ export const Settings = () => { useKeyPressEvent('Escape', () => getCurrent().close()); return ( - <> +
{ - +
); };