notedeck

One damus client to rule them all
git clone git://jb55.com/notedeck
Log | Files | Refs | README | LICENSE

commit 1b77a312146f8b1a89bdaa78f570ec8f2c2a18cf
parent f2cbab62d8272d385cf5381078ea43842596f773
Author: William Casarin <jb55@jb55.com>
Date:   Tue, 10 Feb 2026 10:55:56 -0800

dave: use activateWithOptions and orderFrontRegardless on macOS

NSApplication::activate does not reliably bring the app to front
in Stage Manager single-window mode. Use NSRunningApplication
activateWithOptions with ActivateAllWindows and orderFrontRegardless
on the key window to force activation.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

Diffstat:
Mcrates/notedeck_dave/Cargo.toml | 2+-
Mcrates/notedeck_dave/src/lib.rs | 24++++++++++++++++++++----
2 files changed, 21 insertions(+), 5 deletions(-)

diff --git a/crates/notedeck_dave/Cargo.toml b/crates/notedeck_dave/Cargo.toml @@ -35,7 +35,7 @@ rfd = { workspace = true } [target.'cfg(target_os = "macos")'.dependencies] objc2 = "0.6.1" -objc2-app-kit = { version = "0.3.1", features = ["NSApplication", "NSResponder", "NSRunningApplication"] } +objc2-app-kit = { version = "0.3.1", features = ["NSApplication", "NSResponder", "NSRunningApplication", "NSWindow"] } [dev-dependencies] tokio = { version = "1", features = ["rt-multi-thread", "macros", "test-util"] } diff --git a/crates/notedeck_dave/src/lib.rs b/crates/notedeck_dave/src/lib.rs @@ -930,20 +930,36 @@ impl notedeck::App for Dave { /// Bring the application to the front. /// /// On macOS, egui's ViewportCommand::Focus focuses the window but doesn't -/// always activate the app (bring it in front of other apps), so we also -/// call NSApplication::activateIgnoringOtherApps. +/// always activate the app (bring it in front of other apps). Stage Manager +/// single-window mode is particularly aggressive, so we use both +/// NSRunningApplication::activateWithOptions and orderFrontRegardless +/// on the key window. fn activate_app(ctx: &egui::Context) { ctx.send_viewport_cmd(egui::ViewportCommand::Focus); #[cfg(target_os = "macos")] { use objc2::MainThreadMarker; - use objc2_app_kit::NSApplication; + use objc2_app_kit::{ + NSApplication, NSApplicationActivationOptions, NSRunningApplication, + }; // Safety: UI update runs on the main thread if let Some(mtm) = MainThreadMarker::new() { let app = NSApplication::sharedApplication(mtm); - unsafe { app.activate() }; + + // Activate via NSRunningApplication for per-process activation + let current = unsafe { NSRunningApplication::currentApplication() }; + unsafe { + current.activateWithOptions( + NSApplicationActivationOptions::ActivateAllWindows, + ); + }; + + // Also force the key window to front regardless of Stage Manager + if let Some(window) = app.keyWindow() { + unsafe { window.orderFrontRegardless() }; + } } } }