Skip to content

Commit 6140a4b

Browse files
fix(linux): prevent startup panic from unrealized capsule GDK window | fix(linux): 修复胶囊窗口因 GDK 未实例化导致的启动崩溃 (#792)
* fix(linux): prevent startup panic from unrealized capsule GDK window | fix(linux): 修复胶囊窗口因 GDK 未实例化导致的启动崩溃 On Linux X11, when the capsule window is created with `visible: false` + `transparent: true` in tauri.conf.json, its underlying GDK window is never realized. The subsequent call to `capsule.set_ignore_cursor_events(true)` triggers a panic inside tao's Linux event loop (event_loop.rs:457) because `window.window().unwrap()` returns `None` for an unrealized GDK window. The fix follows the same approach as voicebox PR#837 (PhamBit): force GDK window realization before calling set_ignore_cursor_events, by first moving the window off-screen and calling show(). The window is then repositioned correctly by the existing position_capsule_bottom_center() call and hidden as normal. Refs: - jamiepine/voicebox#837 - tauri-apps/tao#635 在 Linux X11 上,tauri.conf.json 中定义的 capsule 窗口设置了 visible: false + transparent: true,导致其底层 GDK 窗口从未被实例化。 随后调用 capsule.set_ignore_cursor_events(true) 时,tao 的 Linux 事件循环 (event_loop.rs:457) 因 window.window().unwrap() 返回 None 而 panic 崩溃。 修复方法参考 voicebox PR#837:在设置鼠标穿透前先将窗口移出屏幕并 调用 show() 强制 GDK 实例化,后续由原有的 position_capsule_bottom_center() 重新定位并隐藏。 * fix(linux): realize hidden capsule without showing it --------- Co-authored-by: Chris233 <h-chris233@outlook.com>
1 parent 6e79a0c commit 6140a4b

3 files changed

Lines changed: 26 additions & 2 deletions

File tree

openless-all/app/src-tauri/Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

openless-all/app/src-tauri/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ features = ["windows-native"]
9090

9191
[target.'cfg(target_os = "linux")'.dependencies]
9292
dbus = "0.9"
93+
gtk = "0.18"
9394
[target.'cfg(all(unix, not(target_os = "macos"), not(target_os = "android")))'.dependencies.keyring]
9495
version = "3.6.3"
9596
default-features = false

openless-all/app/src-tauri/src/lib.rs

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,9 @@ use std::sync::mpsc;
9595
use std::sync::Arc;
9696
use std::time::Duration;
9797

98+
#[cfg(target_os = "linux")]
99+
use gtk::prelude::WidgetExt;
100+
98101
const LOG_ROTATE_LIMIT_BYTES: u64 = 10 * 1024 * 1024;
99102
#[cfg(target_os = "macos")]
100103
const OPENLESS_BUNDLE_ID: &str = "com.openless.app";
@@ -520,8 +523,27 @@ fn run_desktop() {
520523
}
521524
// 纯光效舞台没有任何可点元素(✕/✓ 按钮已移除),而窗口放大到 460×180
522525
// 盖住屏幕底部中央 —— 必须鼠标穿透,否则会挡住底下应用的点击。
523-
if let Err(e) = capsule.set_ignore_cursor_events(true) {
524-
log::warn!("[capsule] set_ignore_cursor_events failed: {e}");
526+
// Linux 下 tao 的鼠标穿透实现会直接解包底层 GDK 窗口;visible=false 时
527+
// 窗口尚未 realize。这里只创建窗口系统资源而不 map,避免 X11 崩溃,
528+
// 也不会像 show() 那样在不支持窗口定位的 Wayland 上造成启动闪窗。
529+
#[cfg(target_os = "linux")]
530+
let cursor_passthrough_ready = match capsule.gtk_window() {
531+
Ok(gtk_window) => {
532+
gtk_window.realize();
533+
true
534+
}
535+
Err(e) => {
536+
log::warn!("[capsule] gtk_window failed; skipping cursor passthrough: {e}");
537+
false
538+
}
539+
};
540+
#[cfg(not(target_os = "linux"))]
541+
let cursor_passthrough_ready = true;
542+
543+
if cursor_passthrough_ready {
544+
if let Err(e) = capsule.set_ignore_cursor_events(true) {
545+
log::warn!("[capsule] set_ignore_cursor_events failed: {e}");
546+
}
525547
}
526548
if let Err(e) = position_capsule_bottom_center(&capsule, false) {
527549
log::warn!("[capsule] position failed: {e}");

0 commit comments

Comments
 (0)