gtk-rs中如何在窗口显示后触发代码?无需sleep实现窗口调整
解决gtk-rs窗口显示后触发代码的问题
可行方案
使用
connect_map信号替代connect_show:connect_map会在窗口**真正被映射到屏幕(完成渲染显示)**后触发,而非connect_show那样在调用show()前执行。修改代码中的信号连接部分:window.connect_map(|window| { println!("3"); // 在这里执行窗口位置大小调整的命令或逻辑 let output = Command::new("wmctrl") .args(["-r", "CSS", "-e", "1,640,100,680,768"]) .output() .expect("failed to execute process"); println!("{:?}", output); });利用
glib::idle_add延迟执行:
如果需要确保在主循环完成当前渲染任务后执行,可以将调整逻辑放到空闲回调中,它会在GTK主循环处理完所有待处理事件后运行:window.connect_show(|window| { println!("2"); glib::idle_add_local(move || { println!("3"); let output = Command::new("wmctrl") .args(["-r", "CSS", "-e", "1,640,100,680,768"]) .output() .expect("failed to execute process"); println!("{:?}", output); glib::ControlFlow::Break }); });监听窗口的
mapped属性变化:
通过监听GdkWindow的mapped属性,确认窗口已被映射后执行逻辑:if let Some(gdk_window) = window.window() { gdk_window.connect_notify_local("mapped", |gdk_window, _| { if gdk_window.is_mapped() { println!("3"); let output = Command::new("wmctrl") .args(["-r", "CSS", "-e", "1,640,100,680,768"]) .output() .expect("failed to execute process"); println!("{:?}", output); } }); }
原理说明
connect_show的触发时机是窗口的visible属性被设置为true时,此时窗口还未完成与窗口系统的映射、渲染到屏幕的操作。而connect_map、mapped属性变化或idle_add的回调,都会等待窗口真正完成屏幕渲染后才执行,因此无需额外添加sleep即可让wmctrl命令生效。
内容的提问来源于stack exchange,提问作者wyc
相关产品推荐
相关产品推荐

