Refactor window handling, improve theme support, and update dependencies#1807
Refactor window handling, improve theme support, and update dependencies#1807ItsEeleeya wants to merge 189 commits into
Conversation
The header height now matches that of windows with Toolbars on macOS 26
…ier + fix onboarding decorations
The header height now matches that of windows with Toolbars on macOS 26
…ier + fix onboarding decorations
…a/Cap into next-base-improvements
…lugin_window_state's deny list
…indows11.tsx Co-authored-by: tembo[bot] <208362400+tembo[bot]@users.noreply.github.com>
| export function maybeShowWindow() { | ||
| if (windowShown) return; | ||
| windowShown = true; | ||
| void getCurrentWindow().show(); |
There was a problem hiding this comment.
Worth adding a .catch() here so a failed show() (e.g. window already closed / plugin not ready) doesn’t turn into an unhandled rejection.
| void getCurrentWindow().show(); | |
| void getCurrentWindow().show().catch((err) => | |
| console.error("Failed to show window", err), | |
| ); |
| let _ = MACOS_NATIVE_TERMINATE_APP.set(app.clone()); | ||
|
|
||
| app.run_on_main_thread(|| { | ||
| let mtm = MainThreadMarker::new().expect("Running on main"); |
There was a problem hiding this comment.
Minor: would avoid expect() here so a (surprising) main-thread scheduling failure doesn’t crash the whole app.
| let mtm = MainThreadMarker::new().expect("Running on main"); | |
| let Some(mtm) = MainThreadMarker::new() else { | |
| tracing::error!("menu init must run on the main thread"); | |
| return; | |
| }; |
| tracing::warn!("macOS native termination requested before handler was installed"); | ||
| } | ||
| }; | ||
| 0 // NSTerminateCancel — we handle the actual exit ourselves |
There was a problem hiding this comment.
If the handler isn't installed yet (or OnceLock wasn't set), returning NSTerminateCancel here can leave the user unable to quit. Seems safer to return NSTerminateNow in the None case.
| 0 // NSTerminateCancel — we handle the actual exit ourselves | |
| if let Some(app) = MACOS_NATIVE_TERMINATE_APP.get() { | |
| tauri::async_runtime::spawn({ | |
| let app = app.clone(); | |
| async move { | |
| crate::request_app_exit(app).await; | |
| } | |
| }); | |
| 0 // NSTerminateCancel | |
| } else { | |
| tracing::warn!("macOS native termination requested before handler was installed"); | |
| 1 // NSTerminateNow | |
| } |
| return; | ||
| }; | ||
| // SAFETY: Tauri runs this on the main thread | ||
| let mtm = unsafe { MainThreadMarker::new_unchecked() }; |
There was a problem hiding this comment.
Since we already gate this through run_on_main_thread, I'd still avoid MainThreadMarker::new_unchecked() here and keep it fail-safe if something changes upstream.
| let mtm = unsafe { MainThreadMarker::new_unchecked() }; | |
| let Some(mtm) = MainThreadMarker::new() else { | |
| tracing::error!("with_nswindow_on_main must run on the main thread"); | |
| return; | |
| }; |
Co-authored-by: tembo[bot] <208362400+tembo[bot]@users.noreply.github.com>
| .plugin(tauri_plugin_clipboard_manager::init()) | ||
| .plugin(tauri_plugin_fs::init()) | ||
| .plugin(tauri_plugin_opener::init()) | ||
| .plugin(tauri_plugin_prevent_default::debug()) |
There was a problem hiding this comment.
Just to sanity check intent: since this is calling tauri_plugin_prevent_default::debug() unconditionally, is this meant to run in release builds too? If it’s dev-only, it might be worth gating behind cfg(debug_assertions) so prod behavior stays explicit.
|
|
||
| pub fn on_event(app: &AppHandle, event: tauri::menu::MenuEvent) { | ||
| let url = match event.id().as_ref() { | ||
| APP_MENU_QUIT_ID => { |
There was a problem hiding this comment.
APP_MENU_QUIT_ID doesn’t look wired up anywhere (menu uses PredefinedMenuItem::quit, and patch_native_app_menu swaps it to terminate:), so this arm likely never fires.
Might be clearer to either remove APP_MENU_QUIT_ID/this arm, or define an explicit Quit menu item with that id if you still want to funnel quit through on_event.
| "settings" => { | ||
| let app = app.clone(); | ||
| spawn_on_runtime(async move { | ||
| let _ = CapWindow::Settings { page: None }.show(&app).await; |
There was a problem hiding this comment.
Swallowing the show() error here can make failures (closed window, not ready, etc.) silent. Logging it would help debugging.
| let _ = CapWindow::Settings { page: None }.show(&app).await; | |
| if let Err(err) = CapWindow::Settings { page: None }.show(&app).await { | |
| tracing::warn!(?err, "Failed to show Settings window"); | |
| } |
| const prefersDark = usePrefersDarkMode(); | ||
|
|
||
| createEffect(() => | ||
| document.documentElement.classList.toggle("dark", prefersDark()), |
There was a problem hiding this comment.
Sanity check: is prefers-color-scheme expected to reflect the app-level appearance override set via commands.setAppearance (across platforms / webview engines)?
If not, this will now ignore the user’s explicit appearance selection and only track the OS theme.
Refactor window handling, improve theme support, and modernize native integration
Overview
This PR refactors a few things with small improvements as a base for upcoming PRs. The changes modernize how windows are revealed, streamline macOS integration with native AppKit APIs, and better theme handling.
Key Changes
Window Management Refactoring
AutoRevealWindowOnReady: Automatically shows windows once content is loadedRevealWindowWithSuspense: Defers visibility for windows like Settings until routing and child mounting completesShowCapWindow→CapWindowthroughout the codebaseAppDelegateas Tauri now supports custom traffic lights insetdata-tauri-drag-region="deep"attribute (eliminates scattered manual markers)onMouseDown={showCropOptionsMenu}in Editor crop section withonClickas keyboard/touch fallbackTheme/Appearance Improvements
AppTheme→Appearance(with serde fallback for backward compatibility)Code Organization
src-tauri/src/display_utils.rsout ofwindows.rsMonitorExtandCursorMonitorInfotypes organizedpanel_manager.rs: Now macOS-only with streamlined logicmenu.rsmoduleNative Platform Integration
objc2ecosystem crates (app-kit, foundation, permissions)objc2-app-kitversionWebviewWindowExttrait withwith_nswindow_on_main()utility for direct AppKit window accesstauri_plugin_window_statedenylist)UI/UX Enhancements
scale-50class)⌘+,shortcutDependencies & Plugins
tauri-plugin-prevent-default: Enables default context menu only during developmentTechnical Notes
objc2crates instead of legacy objc/cocoaSuggested changelog entires:
⌘+,shortcut.Greptile Summary
This PR refactors desktop window handling and native integration. The main changes are:
ShowCapWindowtoCapWindowacross Rust and generated bindings.themetoappearancewith persisted-store compatibility.Confidence Score: 5/5
This looks safe to merge.
Important Files Changed
appearancewhile accepting the old persisted key.Reviews (3): Last reviewed commit: "Merge branch 'main' into pr/1807" | Re-trigger Greptile
Context used: