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@signal.qinetiq.com> QinetiQ - Malvern Technology Center
--- 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"); } }