refactor: ensure Coco won't take focus on macOS (#891)

* refactor: ensure Coco won't take focus

Or the Window Management extension won't work

* bring back set_focus() on Win/Linux; doc code
This commit is contained in:
SteveLauC
2025-09-04 11:24:47 +08:00
committed by GitHub
parent 4a5a4da399
commit fd8d5819b8
5 changed files with 45 additions and 16 deletions

View File

@@ -50,6 +50,7 @@ Information about release notes of Coco App is provided here.
- refactor: index iOS apps and macOS apps that store icon in Assets.car #872
- refactor: accept both '-' and '\_' as locale str separator #876
- refactor: relax the file search conditions on macOS #883
- refactor: ensure Coco won't take focus #891
## 0.7.1 (2025-07-27)

28
src-tauri/Cargo.lock generated
View File

@@ -868,6 +868,7 @@ dependencies = [
"meval",
"notify 5.2.0",
"num2words",
"objc2-app-kit 0.3.1",
"once_cell",
"ordered-float",
"pizza-common",
@@ -930,7 +931,7 @@ dependencies = [
"block",
"cocoa-foundation",
"core-foundation 0.10.0",
"core-graphics",
"core-graphics 0.24.0",
"foreign-types 0.5.0",
"libc",
"objc",
@@ -1075,6 +1076,19 @@ dependencies = [
"libc",
]
[[package]]
name = "core-graphics"
version = "0.25.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "064badf302c3194842cf2c5d61f56cc88e54a759313879cdf03abdd27d0c3b97"
dependencies = [
"bitflags 2.9.0",
"core-foundation 0.10.0",
"core-graphics-types",
"foreign-types 0.5.0",
"libc",
]
[[package]]
name = "core-graphics-types"
version = "0.2.0"
@@ -1479,7 +1493,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "67fd9ae1736d6ebb2e472740fbee86fb2178b8d56feb98a6751411d4c95b7e72"
dependencies = [
"cocoa",
"core-graphics",
"core-graphics 0.24.0",
"dunce",
"gdk",
"gdkx11",
@@ -1568,7 +1582,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0cf6f550bbbdd5fe66f39d429cb2604bcdacbf00dca0f5bbe2e9306a0009b7c6"
dependencies = [
"core-foundation 0.10.0",
"core-graphics",
"core-graphics 0.24.0",
"foreign-types-shared 0.3.1",
"libc",
"log",
@@ -5742,7 +5756,7 @@ checksum = "18051cdd562e792cad055119e0cdb2cfc137e44e3987532e0f9659a77931bb08"
dependencies = [
"bytemuck",
"cfg_aliases",
"core-graphics",
"core-graphics 0.24.0",
"foreign-types 0.5.0",
"js-sys",
"log",
@@ -5989,7 +6003,7 @@ checksum = "1e59c1f38e657351a2e822eadf40d6a2ad4627b9c25557bc1180ec1b3295ef82"
dependencies = [
"bitflags 2.9.0",
"core-foundation 0.10.0",
"core-graphics",
"core-graphics 0.24.0",
"crossbeam-channel",
"dispatch",
"dlopen2",
@@ -6183,13 +6197,13 @@ dependencies = [
[[package]]
name = "tauri-nspanel"
version = "2.0.1"
source = "git+https://github.com/ahkohd/tauri-nspanel?branch=v2#d4b9df797959f8fa4701e8a20ff69d9605bb66e9"
source = "git+https://github.com/ahkohd/tauri-nspanel?branch=v2#18ffb9a201fbf6fedfaa382fd4b92315ea30ab1a"
dependencies = [
"bitflags 2.9.0",
"block",
"cocoa",
"core-foundation 0.10.0",
"core-graphics",
"core-graphics 0.25.0",
"objc",
"objc-foundation",
"objc_id",

View File

@@ -112,6 +112,7 @@ tauri-plugin-prevent-default = "1"
[target."cfg(target_os = \"macos\")".dependencies]
tauri-nspanel = { git = "https://github.com/ahkohd/tauri-nspanel", branch = "v2" }
objc2-app-kit = { version = "0.3.1", features = ["NSWindow"] }
[target."cfg(target_os = \"linux\")".dependencies]

View File

@@ -264,6 +264,16 @@ async fn show_coco(app_handle: AppHandle) {
let _ = window.show();
let _ = window.unminimize();
// The Window Management (WM) extension (macOS-only) controls the
// frontmost window. Setting focus on macOS makes Coco the frontmost
// window, which means the WM extension would control Coco instead of other
// windows, which is not what we want.
//
// On Linux/Windows, however, setting focus is a necessity to ensure that
// users open Coco's window, then they can start typing, without needing
// to click on the window.
#[cfg(not(target_os = "macos"))]
let _ = window.set_focus();
let _ = app_handle.emit("show-coco", ());

View File

@@ -1,13 +1,10 @@
//! credits to: https://github.com/ayangweb/ayangweb-EcoPaste/blob/169323dbe6365ffe4abb64d867439ed2ea84c6d1/src-tauri/src/core/setup/mac.rs
use crate::common::MAIN_WINDOW_LABEL;
use objc2_app_kit::NSNonactivatingPanelMask;
use tauri::{AppHandle, Emitter, EventTarget, WebviewWindow};
use tauri_nspanel::{WebviewWindowExt, cocoa::appkit::NSWindowCollectionBehavior, panel_delegate};
use crate::common::MAIN_WINDOW_LABEL;
#[allow(non_upper_case_globals)]
const NSWindowStyleMaskNonActivatingPanel: i32 = 1 << 7;
const WINDOW_FOCUS_EVENT: &str = "tauri://focus";
const WINDOW_BLUR_EVENT: &str = "tauri://blur";
const WINDOW_MOVED_EVENT: &str = "tauri://move";
@@ -22,11 +19,17 @@ pub fn platform(
// Convert ns_window to ns_panel
let panel = main_window.to_panel().unwrap();
// Make the window above the dock
panel.set_level(20);
// Do not steal focus from other windows
panel.set_style_mask(NSWindowStyleMaskNonActivatingPanel);
//
// Cast is safe
panel.set_style_mask(NSNonactivatingPanelMask.0 as i32);
// Set its level to NSFloatingWindowLevel to ensure it appears in front of
// all normal-level windows
//
// NOTE: some Chinese input methods use a level between NSDockWindowLevel (20)
// and NSMainMenuWindowLevel (24), setting our level above NSDockWindowLevel
// would block their window
panel.set_floating_panel(true);
// Open the window in the active workspace and full screen
panel.set_collection_behaviour(