使用Rust+WebKit2Gtk-rs开发浏览器时如何仅让WebView单独实现全屏
解决方案
WebKit2GTK默认的全屏逻辑是向承载WebView的顶层主窗口发送全屏请求,所以会触发整个应用窗口全屏,你可以通过自定义全屏信号的处理逻辑实现仅WebView单独全屏:
- 提前开启WebView的全屏权限:在WebView关联的
WebSettings中将enable-fullscreen属性设置为true - 阻止默认的全屏行为:分别连接WebView的
enter-fullscreen和leave-fullscreen信号,回调返回Inhibit(true)屏蔽默认的窗口全屏逻辑 - 自定义全屏容器:提前创建一个无装饰的
GtkWindow作为专门的全屏承载容器,进入全屏时执行以下操作:- 记录WebView在原有Gtk Box中的排列位置
- 将WebView从原Box中移除,添加到专门的全屏窗口中
- 将全屏窗口设置为满屏显示
- 退出全屏时执行反向操作:
- 将WebView从全屏容器中移除
- 将WebView插回原Box的原有排列位置
- 隐藏或销毁全屏容器
下面是参考代码片段:
use gtk::prelude::*; use webkit2gtk::prelude::*; use gtk::{Box, Window, WindowType, WindowTypeHint}; use webkit2gtk::{WebView, WebSettings}; use std::cell::RefCell; use std::rc::Rc; // 用Rc<RefCell>包裹跨闭包共享的变量 let shared_data = Rc::new(RefCell::new(None)); // 初始化全屏容器 let fullscreen_window = Window::new(WindowType::Toplevel); fullscreen_window.set_decorated(false); fullscreen_window.set_type_hint(WindowTypeHint::Fullscreen); // 假设你已初始化原容器box、webview let webview = WebView::new(); let settings = WebSettings::new(); settings.set_enable_fullscreen(true); webview.set_settings(&settings); // 保存原容器和WebView的初始位置 *shared_data.borrow_mut() = Some((box.clone(), box.child_position(&webview))); // 处理进入全屏信号 webview.connect_enter_fullscreen(clone!(@strong shared_data, @strong fullscreen_window => move |webview| { let (ref parent, _) = shared_data.borrow().as_ref().unwrap(); parent.remove(webview); fullscreen_window.add(webview); fullscreen_window.fullscreen(); fullscreen_window.show_all(); Inhibit(true) })); // 处理退出全屏信号 webview.connect_leave_fullscreen(clone!(@strong shared_data, @strong fullscreen_window => move |webview| { let (ref parent, position) = shared_data.borrow().as_ref().unwrap(); fullscreen_window.remove(webview); parent.add(webview); parent.reorder_child(webview, *position); fullscreen_window.unfullscreen(); fullscreen_window.hide(); Inhibit(true) }));
注:代码中的
clone!宏是GTK Rust绑定中常用的变量捕获宏,如果你项目中没有引入可以手动处理变量的所有权克隆。
内容的提问来源于stack exchange,提问作者NotEverSoAnxious
相关产品推荐
相关产品推荐

