A little Xlib adventure

Mike Hearn m.hearn at signal.qinetiq.com
Tue Apr 29 07:59:00 CDT 2003


Got to start somewhere. This patch adds support for the netWM ping
protocol, which lets window managers like metacity present a nice "This
app is not responding, kill it?" window when the program freezes. This
unfortunately happens all too often with IE in particular, and while us
developers can see (and understand) critical section timeout messages,
people running from the menu or desktop icons cannot. 

I haven't bothered sending a message to the window (WM_NULL) because if
the program stops responding, it'll stop processing X messages as well.
If you want to test it out, just put an infinite loop in a test app then
try and close it. 

Tested with metacity from gnome2.2 - may work with latest KWin, if it
doesn't then file a bug in KDE bugzilla.

ChangeLog:
Support _NET_WM_PING protocol so the WM can detect freezes

-- 
Mike Hearn <m.hearn at signal.qinetiq.com>
QinetiQ - Malvern Technology Center
-------------- next part --------------
--- wine-20030318/dlls/x11drv/window.c	2003-01-30 01:07:43.000000000 +0000
+++ wine/dlls/x11drv/window.c	2003-04-29 12:05:52.000000000 +0100
@@ -23,6 +23,7 @@
 #include "config.h"
 
 #include <stdlib.h>
+#include <unistd.h>
 
 #include "ts_xlib.h"
 #include <X11/Xresource.h>
@@ -59,6 +60,8 @@
 Atom wmChangeState = None;
 Atom mwmHints = None;
 Atom kwmDockWindow = None;
+Atom netwmPid = None;
+Atom netwmPing = None;
 Atom _kde_net_wm_system_tray_window_for = None; /* KDE 2 Final */
 
 static LPCSTR whole_window_atom;
@@ -338,6 +341,7 @@
     i = 0;
     protocols[i++] = wmDeleteWindow;
     if (wmTakeFocus) protocols[i++] = wmTakeFocus;
+    if (netwmPing) protocols[i++] = netwmPing;
     XSetWMProtocols( display, data->whole_window, protocols, i );
 
     /* class hints */
@@ -373,6 +377,12 @@
                              XA_WINDOW, 32, PropModeReplace, (char*)&data->whole_window, 1 );
     }
 
+    /* set the WM_CLIENT_MACHINE and WM_LOCALE_NAME properties */
+    XSetWMProperties(display, data->whole_window, NULL, NULL, NULL, 0, NULL, NULL, NULL);
+    /* set the pid. together, these properties are needed so the window manager can kill us if we freeze */
+    i = getpid();
+    XChangeProperty(display, data->whole_window, netwmPid, XA_CARDINAL, 32, PropModeReplace, (char *)&i, 1);
+    
     if (mwmHints != None)
     {
         MwmHints mwm_hints;
@@ -627,6 +637,8 @@
     mwmHints = XInternAtom( display, _XA_MWM_HINTS, False );
     kwmDockWindow = XInternAtom( display, "KWM_DOCKWINDOW", False );
     _kde_net_wm_system_tray_window_for = XInternAtom( display, "_KDE_NET_WM_SYSTEM_TRAY_WINDOW_FOR", False );
+    netwmPid = XInternAtom( display, "_NET_WM_PID", False );
+    netwmPing = XInternAtom( display, "_NET_WM_PING", False );
     wine_tsx11_unlock();
 
     whole_window_atom  = MAKEINTATOMA( GlobalAddAtomA( "__wine_x11_whole_window" ));
--- wine-20030318/dlls/x11drv/event.c	2003-01-23 01:29:58.000000000 +0000
+++ wine/dlls/x11drv/event.c	2003-04-29 13:53:17.000000000 +0100
@@ -55,6 +55,7 @@
 extern Atom wmDeleteWindow;
 extern Atom dndProtocol;
 extern Atom dndSelection;
+extern Atom netwmPing;
 
 #define DndNotDnd       -1    /* OffiX drag&drop */
 #define DndUnknown      0
@@ -460,6 +461,15 @@
             if (!hwnd) hwnd = last_focus;
             if (hwnd && can_activate_window(hwnd)) set_focus( hwnd, event_time );
         }
+    } else if (protocol == netwmPing) {
+      XClientMessageEvent xev;
+      xev = *event;
+      
+      TRACE("NET_WM Ping\n");
+      xev.window = DefaultRootWindow(xev.display);
+      XSendEvent(xev.display, xev.window, False, SubstructureRedirectMask | SubstructureNotifyMask, (XEvent*)&xev);
+      /* this line is semi-stolen from gtk2 */
+      TRACE("NET_WM Pong\n");
     }
 }
 


More information about the wine-patches mailing list