gpt4 book ai didi

c - 在 X11 上拦截 WM_DELETE_WINDOW?

转载 作者:IT王子 更新时间:2023-10-28 23:54:27 26 4
gpt4 key购买 nike

我想拦截发布到我正在编写的应用程序的特定窗口选择的 WM_DELETE_WINDOW 消息 (AllTray),以便我可以对其执行操作而不是接收它的应用程序。我目前正在考虑在 GDK 级别尝试这个 via gdk_display_add_client_message_filter如果可能的话,但如果有 Xlib 解决方案,我也会很高兴;它似乎是可能的,但我似乎不明白我如何成功地做到这一点。

目前,我有两个程序(用 C 语言编写)正试图用来解决这个问题,the first one除了创建一个窗口并注册它知道 WM_DELETE_WINDOWthe second one 之外什么都不做试图捕获该消息,但似乎没有成功;它似乎什么也没做。我对文档的理解是错误的,还是我需要做一些额外的事情(或者我是否需要为此完全避免使用 GDK)?

背景是这样的:在我重写 AllTray 之前,它做事的方式似乎是试图拦截对 X 按钮本身的鼠标单击。对于某些窗口管理器,这可以正常工作,对于其他窗口管理器,它根本不起作用,而对于其他窗口管理器,用户必须手动配置它并指示 AllTray 关闭窗口的按钮在哪里。我正在寻找的解决方案不涉及 LD_LIBRARY_PRELOAD,并且适用于符合当前标准并发送 WM_DELETE_WINDOW ClientMessage 的任何窗口管理器/应用程序组合当窗口关闭时。

更新:我仍在寻找答案。我目前采取的路线是尝试重新设置窗口并自己管理它,但我就是无法让它工作。重新养育后,我似乎无法以任何方式取回它。我可能遗漏了一些非常基本的东西,但我无法弄清楚如何让它再次出现在我自己的窗口中,以将其重新显示在屏幕上。

更新 2:好吧,我又碰壁了。 X 服务器文档说要在窗口的事件掩码上设置 StructureNotifyMask 以接收 MapNotify 和 ReparentNotify 事件。我有兴趣接受其中任何一个。我目前的想法是创建一个仅用作事件接收器的窗口,然后当我获得有趣事件的事件时,通过创建和重新设置父级来对它们采取行动。但是,这似乎根本行不通。我实际收到的唯一事件是 PropertyNotify 事件。所以,这条路线似乎也做得不太好。

最佳答案

我不知道 X11,但我用 "Intercept WM_DELETE_WINDOW X11" 搜索了一下作为关键字。找到17k - MarkMailMplayer-commits r154 - trunk/libvo .在这两种情况下,他们都在做同样的事情。

 /* This is used to intercept window closing requests.  */
static Atom wm_delete_window;

static void x11_init() 中,

XMapWindow(display, win);
wm_delete_window = XInternAtom(display, "WM_DELETE_WINDOW", False);
XSetWMProtocols(display, win, &wm_delete_window, 1);

然后,在 static int x11_check_events() 中,

XEvent Event;
while (XPending(display)) {
XNextEvent(display, &Event);
if (Event.type == ClientMessage) {
if ((Atom)Event.xclient.data.l[0] == wm_delete_window) {
/* your code here */
}
}
}

参见 XInternAtom , XSetWMProtocolsXNextEvent .

我写完上面之后,找到了Handling window close in an X11 app :

When a user clicks the close button [x] on our X11 application we want it to pop a a dialog asking “do you really want to quit?”. This is a plain X app. No fancy GTK or QT widgets here. So how to catch the “window is being closed” message?

The answer is to tell the Window Manager we are interested in these event by calling XSetWMProtocols and registering a WM_DELETE_WINDOW message with it. Then we’ll get a client message from the Window Manager if someone tries to close the window, and it won’t close it, it’ll leave that us up to us. Here’s an example….

// example.cpp
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <iostream>

int main()
{
Display* display = XOpenDisplay(NULL);
Window window = XCreateSimpleWindow(display,
DefaultRootWindow(display),
0, 0,
500, 400,
0,
0, 0);

// register interest in the delete window message
Atom wmDeleteMessage = XInternAtom(display, "WM_DELETE_WINDOW", False);
XSetWMProtocols(display, window, &wmDeleteMessage, 1);

std::cout << "Starting up..." << std::endl;
XMapWindow(display, window);

while (true) {
XEvent event;
XNextEvent(display, &event);

if (event.type == ClientMessage &&
event.xclient.data.l[0] == wmDeleteMessage) {
std::cout << "Shutting down now!!!" << std::endl;
break;
}
}

XCloseDisplay(display);
return 0;
}

关于c - 在 X11 上拦截 WM_DELETE_WINDOW?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1157364/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com