You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何在不通知窗口的情况下退出全屏?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打开)快速验证:

  1. 切换到某个全屏窗口
  2. 在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

火山引擎 最新活动