如何在不通知窗口的情况下退出全屏?gTile扩展全屏分屏适配求助
嘿,这个需求确实戳中了日常使用的痛点——全屏窗口藏掉控件后,想分屏操作太麻烦了。好消息是,GNOME Shell扩展完全能实现这个功能,我来给你拆解具体的思路和实现步骤:
一、先给你吃颗定心丸:Shell扩展绝对能做到
GNOME Shell扩展可以直接和窗口管理器(Mutter)交互,读写EWMH标准里的窗口属性,包括_NET_WM_FULLSCREEN这类全屏状态标记。你之前找的EWMH相关资料方向是对的,只是没找对Shell扩展里对应的API而已。
二、核心实现步骤
1. 检测全屏窗口
在gTile的窗口处理逻辑里,先判断目标窗口是否处于全屏状态:
const isFullscreen = window.get_fullscreen(); // 或者更底层一点,检查窗口的WM状态属性 const state = window.get_state(); const isFullscreen = state & global.Meta.WindowState.FULLSCREEN;
2. 静默退出全屏(关键:不通知窗口)
普通的window.unmake_fullscreen()会给窗口发送事件,触发应用自己的全屏逻辑(比如视频播放器可能会弹出提示)。要实现“静默退出”,得用带NO_NOTIFY标志的API:
// GNOME 3.36+ 版本可用这个枚举 window.unmake_fullscreen_with_flags(global.Meta.FullscreenFlags.NO_NOTIFY);
这个方法会直接让窗口管理器取消全屏状态,但不会向窗口发送任何通知,窗口本身不会察觉到状态变化,完美解决你要隐藏控件的需求。
3. 应用分屏布局
退出全屏后,就可以复用gTile原本的分屏逻辑,把窗口调整到目标区域:
// 示例:把窗口放到左半屏 const monitor = window.get_monitor(); const monitorRect = global.display.get_monitor_geometry(monitor); const halfWidth = Math.floor(monitorRect.width / 2); // move_resize_frame的第一个参数false表示绕过窗口自身的大小约束 window.move_resize_frame(false, monitorRect.x, monitorRect.y, halfWidth, monitorRect.height);
三、整合到gTile的建议
你可以在gTile的核心分屏函数(比如处理快捷键或菜单点击的逻辑)开头,加入全屏检测和静默退出的代码。比如:
function handleTileAction(window, targetRect) { // 过滤掉不需要处理的窗口(比如dock、桌面) if (window.is_skip_taskbar() || window.is_skip_pager()) return; // 处理全屏窗口 if (window.get_fullscreen()) { try { window.unmake_fullscreen_with_flags(global.Meta.FullscreenFlags.NO_NOTIFY); } catch (e) { // 兼容旧版本GNOME,降级用普通方法(可能会通知窗口,但聊胜于无) window.unmake_fullscreen(); } } // 执行原本的分屏逻辑 window.move_resize_frame(false, targetRect.x, targetRect.y, targetRect.width, targetRect.height); }
四、测试验证
你可以用Looking Glass(按Alt+F2输入lg打开)快速验证:
- 切换到某个全屏窗口
- 在Looking Glass的控制台输入:
let win = global.display.focus_window; win.unmake_fullscreen_with_flags(global.Meta.FullscreenFlags.NO_NOTIFY); win.move_resize_frame(false, 0, 0, global.screen_width/2, global.screen_height);
如果窗口静默退出全屏并占满左半屏,就说明逻辑没问题了。
五、注意事项
- 部分特殊窗口(比如有些游戏或全屏应用)可能会强制恢复全屏,这种情况可以监听窗口的
notify::fullscreen信号,再次触发分屏逻辑,但大部分日常应用不会这么做。 - 不同GNOME版本的API可能略有差异,比如旧版本可能没有
FullscreenFlags.NO_NOTIFY,这时候可以降级用普通的unmake_fullscreen(),虽然会通知窗口,但至少能实现分屏功能。
内容的提问来源于stack exchange,提问作者Different55




