【问题标题】:XLIB Decoration questionsXLIB装修问题
【发布时间】:2013-12-16 11:04:49
【问题描述】:

我正在编写一个小型窗口管理器,它在窗口周围添加基本装饰,但实际上我有几个关于添加/删除窗口装饰的问题。

第一个问题

实际上装饰是在 MapNotify 事件期间添加的,但这似乎不是一个好主意,因为每次使用新窗口触发 mapnotify 时,它也会向应用程序打开的菜单添加装饰,但我只想在主窗口中添加装饰。也许我必须检查当前窗口是否是另一个窗口的子窗口?实际上,我的代码只是创建具有特定名称的装饰窗口,因此在每个 MapNotify 请求中,如果在装饰窗口上启动 MapNotify 事件,我会给装饰窗口一个虚拟名称(父级),以便以这种方式将其与所有其他窗口区分开来,至少它不会添加其他装饰。 但我不明白 MapNotify 是否不仅针对父窗口而且还针对子窗口启动,可能风险是我添加了多个装饰窗口。 实际代码如下:

void map_notify_handler(XEvent local_event, Display* display, ScreenInfos infos){
    printf("Map Notify\n");
    XWindowAttributes win_attr;
    char *child_name;
    XGetWindowAttributes(display, local_event.xmap.window, &win_attr);
    XFetchName(display, local_event.xmap.window, &child_name);
    printf("Attributes: W: %d - H: %d - Name: %s\n", win_attr.width, win_attr.height, child_name);
    if(child_name!=NULL){
      if(strcmp(child_name, "Parent")){
        Window new_win = draw_window_with_name(display, RootWindow(display, infos.screen_num), "Parent", infos.screen_num, 
                           win_attr.x, win_attr.y, win_attr.width, win_attr.height+DECORATION_HEIGHT, 0, 
                           BlackPixel(display, infos.screen_num));
        XMapWindow(display, new_win);
        XReparentWindow(display,local_event.xmap.window, new_win,0, DECORATION_HEIGHT);
        XSelectInput(display, local_event.xmap.window, SubstructureNotifyMask);
        put_text(display, new_win, child_name, "9x15", 10, 10, BlackPixel(display,infos.screen_num), WhitePixel(display, infos.screen_num));
      }
    }
    XFree(child_name);
}

那么如何避免在除主应用程序窗口(或弹出窗口,有一种方法来区分窗口类型吗?我怎么知道呢?)之外的每个窗口上添加装饰

第二个问题

当我退出程序时,被销毁的窗口只是应用程序窗口而不是父装饰,如何销毁当前窗口以及装饰?

我尝试了以下方法:

void destroy_notify_handler(XEvent local_event, Display *display){
    Window window = local_event.xdestroywindow.event;
    XDestroyWindow(display, window);
}

但我收到以下错误:

发生错误:BadWindow(无效的 Window 参数)

我使用事件而不是窗口,因为它似乎包含父窗口(我从那里读到它:http://tronche.com/gui/x/xlib/events/window-state-change/destroy.html) 但即使我使用 window 我也有同样的问题。

或者也许我必须更早地销毁父窗口?也许在 UnMapNotify 期间?但是如何理解事件是仅仅因为窗口将要关闭还是出于其他原因而启动的呢?

感谢您的帮助:)

【问题讨论】:

    标签: xlib window-managers


    【解决方案1】:

    阅读EWMH 规范,您会找到所有问题的答案。

    1. Check "override redirect" 窗口标志
    2. 您正在尝试 销毁已经销毁的窗口。而不是使用 event.xdestroywindow.event 窗口 id 只是删除你的装饰 窗户。
    3. 如果你是,别忘了add client window to save set 写reparenting WM。这样,如果您杀死 wm 应用程序窗口 没有被破坏,而是重新回到根窗口

    【讨论】:

    • on #2:问题是我不明白如何删除装饰窗口。因为如果子窗口被破坏,我将无法访问父窗口。你能解释一下吗?
    • 在某处记住您的 new_win(例如,在键是主窗口 id 的哈希中)
    • 好的,明白了!谢谢。
    猜你喜欢
    • 2011-08-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-11
    • 1970-01-01
    • 2012-04-20
    • 2019-11-06
    • 2018-03-09
    相关资源
    最近更新 更多