You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Gnome Shell扩展问题:窗口创建时无法正确定位如何解决?

问题分析与解决方案

你的问题核心在于窗口创建时机过早,window-created事件触发时,窗口尚未完成屏幕映射(即还未显示到桌面),Gnome Shell后续的默认窗口布局逻辑会覆盖你设置的位置。同时原代码存在全局事件ID被覆盖、重复触发调整的问题,以下是针对性修改:

修正后的代码

let windowCreatedId;

function init() {
}

function enable() {
    windowCreatedId = global.display.connect('window-created', onWindowCreated);
}

function disable() {
    global.display.disconnect(windowCreatedId);
}

function onWindowCreated(display, win) {
    // 仅处理普通应用窗口,跳过桌面、面板等特殊窗口
    if (win.get_window_type() !== Meta.WindowType.NORMAL) {
        return;
    }

    // 监听窗口映射事件(窗口显示到屏幕时触发)
    const mapEventId = win.connect('map-event', () => {
        // 延迟执行调整,让窗口管理器完成初始布局
        Clutter.idle_add(() => {
            resizeWindow(win);
            // 调整完成后断开事件连接,避免重复触发
            win.disconnect(mapEventId);
            return Clutter.SOURCE_REMOVE;
        });
    });
}

function resizeWindow(win) {
    // 排除最大化、全屏状态的窗口
    if (!win.maximized_horizontally && !win.maximized_vertically && !win.fullscreen) {
        // 第一个参数设为true可强制跳过窗口管理器位置约束(按需使用)
        win.move_resize_frame(false, 20, 20, 2000, 2000);
    }
}

关键修改说明

  1. 改用map-event事件:窗口被映射到屏幕后才触发该事件,此时窗口已完成初始布局,调整位置不会被系统默认逻辑覆盖。
  2. 延迟执行调整:通过Clutter.idle_add将调整操作放入Gnome Shell的空闲任务队列,确保系统窗口布局流程全部完成后再修改窗口位置。
  3. 避免全局事件ID冲突:为每个窗口单独绑定map-event事件,并在调整完成后断开连接,防止多窗口场景下事件ID被覆盖。
  4. 窗口类型过滤:跳过系统特殊窗口(如桌面、顶部面板),只处理普通应用窗口。
  5. 约束跳过选项:如果move_resize_frame第一个参数设为false仍无法生效,可改为true强制绕过窗口管理器的位置约束(但可能影响窗口吸附等默认功能)。

内容的提问来源于stack exchange,提问作者jqno

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 00:05:22