在X11上截取WM_DELETE_WINDOW? [英] Intercept WM_DELETE_WINDOW on X11?

查看:121
本文介绍了在X11上截取WM_DELETE_WINDOW?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想拦截发布到我正在撰写的应用程序的特定窗口选项的 WM_DELETE_WINDOW 消息( AllTray ),以便我可以采取行动,而不是接收它的应用程序。我目前正在GDK级别尝试这样做。通过 gdk_display_add_client_message_filter ,如果可能的话,但如果有一个Xlib解决方案,我会很高兴;它似乎是可能的,但我似乎并不了解我如何成功地完成。

I'd like to intercept the WM_DELETE_WINDOW message that is posted to a certain selection of windows that an application I'm writing (AllTray), so that I can act on it instead of the application receiving it. I'm currently looking at trying this at the GDK level via gdk_display_add_client_message_filter if possible, but I'd be happy with an Xlib solution if there is one as well; it seems to be possible, but I just don't seem to be understanding how I am to do it successfully.

目前,我有我试图使用这两个程序(C写入),第一个不做任何事创建一个窗口并注册它知道关于 WM_DELETE_WINDOW 第二个试图抓住这个消息,但似乎没有这样做;它似乎完全没有做。我理解这个文档是错误的,还是有额外的东西,我需要做(或者我需要避免使用GDK完全为此)?

Currently, I have two programs (written in C) that I am trying to use to get this figured out, the first one does nothing but create a window and register that it knows about WM_DELETE_WINDOW, and the second one attempts to catch that message, but seems to fail in doing so; it appears to do precisely nothing. Am I understanding the documentation wrong on this, or is there something additional that I need to be doing (or do I need to avoid using GDK entirely for this)?

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

The background is this: Prior to my re-write of AllTray, the way it would do things appears to be to try to intercept a mouse-click on the X button itself. For some window managers, this worked properly, for others it didn't work at all, and for others, the user had to configure it manually and instruct AllTray where the button for closing the window was. What I am looking for is a solution that doesn't involve a LD_LIBRARY_PRELOAD and will work for any window manager/application combination that conforms to the current standards and sends a WM_DELETE_WINDOW ClientMessage when the window is closed.

更新:我还在寻找答案。目前我正在采取的路线是尝试重新思考窗户,自己管理,但是我不能让它工作。在回想起来时,我似乎无法以任何方式得到它。我可能会缺少一些非常基本的东西,但是我无法弄清楚如何将它再次出现在我自己的窗口上,让它回到屏幕上。

UPDATE: I'm still looking for an answer. The route that I am taking at the moment is to try to reparent the window and manage it myself, but I just cannot make it work. Upon reparenting, I don't seem to be able to get it back in any way. I may be missing something very fundamental, but I can't figure out how to actually make it appear it my own window again, to bring it back on the screen.

更新2 :好的,所以我打了另一个砖墙。 X服务器文档说要在窗口的事件掩码上设置StructureNotifyMask,以接收MapNotify和ReparentNotify事件。我也有兴趣收到。我目前的想法是创建一个窗口,作为一个事件接收器,然后当我得到有趣的事情的事件,通过创建和重新定位对它们采取行动。然而,这根本似乎没有起作用。我实际收到的唯一事件是PropertyNotify事件。所以,这条路线似乎还没有做得很好。

UPDATE 2: Alright, so I've hit another brick wall. The X server documentation says to set the StructureNotifyMask on the window's event mask to receive both MapNotify and ReparentNotify events. I'd be interested in receiving either. My current thinking was to create a window that served just as an event receiver, and then when I get events for interesting things, act on them by creating and reparenting. However, this simply doesn't seem to be working. The only events I actually receive are PropertyNotify events. So, this route doesn't seem to be doing very much good, either.

推荐答案

不幸的是,这个问题的最佳答案是一系列的无答案;有技术上的方法来完成它,但它们都有垮台,使它们非常不切实际:

Unfortunately, the best answer to this question is a series of non-answers; there are technically ways to accomplish it, but they all have downfalls that make them extremely impractical:


  1. 为应用程序创建X11代理,传递所有X11协议消息在应用程序和X服务器之间来回传递。然后,代理将过滤掉任何有趣的消息。这样做的缺点是,对于一个小小的功能来说这是一个非常大的开销,而X11协议是复杂的。也可能会出现意想不到的后果,这使得它更具吸引力。

  2. 作为标准应用程序启动,作为窗口管理器和有趣客户端应用程序之间的中介。这打破了一些事情,如XDnD。实际上,它与第一个选项不同,只是代理在Window级别而不是X11协议级别。

  3. 使用非便携式 LD_PRELOAD 库技巧。这有多个的缺点:$ b​​ $ b
  1. Create an X11 proxy for an application, passing all X11 protocol messages back and forth between the application and the X server. The proxy would then filter out any interesting messages. The downside to this is that this is an awful lot of overhead for a single little tiny feature, and the X11 protocol is complex. There could also be unintended consequences, which makes this an even more unattractive option.
  2. Launch as a standard application that acts as an intermediary between the window manager and "interesting" client applications. This breaks some things, such as XDnD. In effect, it is not unlike the first option, except that the proxy is at the Window level as opposed to the X11 protocol level.
  3. Use the non-portable LD_PRELOAD library trick. This has several downsides:

  1. 在动态链接器中不可移植:并非所有动态链接器都支持 LD_PRELOAD ,甚至在类UNIX系统之间。

  2. 它是不可移植的跨操作系统:并不是所有的操作系​​统都支持功能强大的动态链接器。

  3. 破坏网络透明度:共享对象/动态链接库必须作为执行的子进程驻留在主机上。

  4. 并非所有X11应用程序都使用Xlib;需要为应用程序可能用来与X11交谈的每个库写一个 LD_PRELOAD 模块。

  5. 另外到最后一点,即使他们在支持它的链接器下运行,并不是所有的应用程序都容易受到 LD_PRELOAD 的影响,因为它们可能不使用共享对象或DLL,以便与X沟通例如,考虑使用Java本身编写的X11协议库的Java应用程序。

  6. 在某些类UNIX操作系统上, LD_PRELOAD 如果要与setuid / setgid程序一起使用,库必须是setuid / setgid。当然,这是一个潜在的安全漏洞。

  7. 我确定我不能想到的更多的缺点。

  1. It is non-portable across dynamic linkers: not all dynamic linkers support LD_PRELOAD, even among UNIX-like systems.
  2. It is non-portable across operating systems: not all operating systems support featureful dynamic linkers.
  3. It breaks network-transparency: the shared object/dynamic link library must reside on the host as the child process that is being executed.
  4. Not all X11 applications use Xlib; it would be necessary to write one LD_PRELOAD module for each of the libraries that an application might use to talk with X11.
  5. In addition to the last point, not all applications would be susceptible to LD_PRELOAD even if they ran under a linker that supported it, because they may not use a shared object or DLL in order to communicate with X; consider, for example, a Java application which uses an X11 protocol library written in Java itself.
  6. On some UNIX-like operating systems, LD_PRELOAD libraries must be setuid/setgid if they are to be used with setuid/setgid programs. This is, of course, a potential security vulnerability.
  7. I am quite sure that are more downsides that I cannot think of.

li>

  • 实现X Window系统的扩展。不可移植的X11实现,复杂和复杂,所有的出来,绝对不出问题。

  • 实现扩展或插件到窗口管理器。窗口管理员有许多窗口管理员,因此这是非常不可行的。

  • Implement an extension to the X Window system. Non-portable among X11 implementations, complex and convoluted as all get out, and absolutely out of the question.
  • Implement extensions or plug-ins to window managers. There are as many window managers as there are opinions on window managers, and therefore this is utterly infeasible.
  • 最终,我能够最终通过使用完全独立的机制完成我的目标;有兴趣的人,请参阅AllTray 0.7.5.1dev及更高版本中的靠近托盘支持,包括 git github可用的主分支

    Ultimately, I was able to finally accomplish my goal by using a completely separate mechanism; anyone who is interested, please see the Close-to-Tray support in AllTray 0.7.5.1dev and later, including the git master branch available on github.

    这篇关于在X11上截取WM_DELETE_WINDOW?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆