Add new Atom atom_NET_WM_PID to set pid info
authorXu Li <xu.li@intel.com>
Tue, 4 Aug 2009 14:06:27 +0000 (22:06 +0800)
committerEmmanuele Bassi <ebassi@linux.intel.com>
Fri, 14 Aug 2009 11:41:01 +0000 (12:41 +0100)
Clutter advertises itself on X11 as implementing the _NET_WM_PING protocol,
which is needed to be able to detect frozen applications; this allows us to
stop the destruction of the stage by blocking the CLUTTER_DELETE event and
wait for user feedback without the Window Manager thinking that the app has
gone unresponsive.

In order to implement the _NET_WM_PING protocol properly, though, we need
to add the _NET_WM_PID property on the Stage window, since the EWMH states:

  [_NET_WM_PID] MAY be used by the Window Manager to kill windows which
  do not respond to the _NET_WM_PING protocol.

Meaning that an unresponsive Clutter application might not be killable by
the window manager.

Fixes bug:

  http://bugzilla.openedhand.com/show_bug.cgi?id=1748

Signed-off-by: Emmanuele Bassi <ebassi@linux.intel.com>
clutter/x11/clutter-backend-x11.c
clutter/x11/clutter-backend-x11.h
clutter/x11/clutter-stage-x11.c

index 222fa10..c3773a7 100644 (file)
@@ -76,6 +76,7 @@ void  _clutter_x11_register_xinput ();
  * atom name here. do not change the order!
  */
 static const gchar *atom_names[] = {
+  "_NET_WM_PID",
   "_NET_WM_PING",
   "_NET_WM_STATE",
   "_NET_WM_STATE_FULLSCREEN",
@@ -201,16 +202,17 @@ clutter_backend_x11_post_parse (ClutterBackend  *backend,
                     (char **) atom_names, n_atom_names,
                     False, atoms);
 
-      backend_x11->atom_NET_WM_PING = atoms[0];
-      backend_x11->atom_NET_WM_STATE = atoms[1];
-      backend_x11->atom_NET_WM_STATE_FULLSCREEN = atoms[2];
-      backend_x11->atom_NET_WM_USER_TIME = atoms[3];
-      backend_x11->atom_WM_PROTOCOLS = atoms[4];
-      backend_x11->atom_WM_DELETE_WINDOW = atoms[5];
-      backend_x11->atom_XEMBED = atoms[6];
-      backend_x11->atom_XEMBED_INFO = atoms[7];
-      backend_x11->atom_NET_WM_NAME = atoms[8];
-      backend_x11->atom_UTF8_STRING = atoms[9];
+      backend_x11->atom_NET_WM_PID = atoms[0];
+      backend_x11->atom_NET_WM_PING = atoms[1];
+      backend_x11->atom_NET_WM_STATE = atoms[2];
+      backend_x11->atom_NET_WM_STATE_FULLSCREEN = atoms[3];
+      backend_x11->atom_NET_WM_USER_TIME = atoms[4];
+      backend_x11->atom_WM_PROTOCOLS = atoms[5];
+      backend_x11->atom_WM_DELETE_WINDOW = atoms[6];
+      backend_x11->atom_XEMBED = atoms[7];
+      backend_x11->atom_XEMBED_INFO = atoms[8];
+      backend_x11->atom_NET_WM_NAME = atoms[9];
+      backend_x11->atom_UTF8_STRING = atoms[10];
     }
 
   g_free (clutter_display_name);
index 3faa049..3074e45 100644 (file)
@@ -64,6 +64,7 @@ struct _ClutterBackendX11
   GSList  *event_filters;
 
   /* props */
+  Atom atom_NET_WM_PID;
   Atom atom_NET_WM_PING;
   Atom atom_NET_WM_STATE;
   Atom atom_NET_WM_STATE_FULLSCREEN;
index 178a8ca..722998f 100644 (file)
@@ -304,6 +304,30 @@ clutter_stage_x11_allocate (ClutterActor           *self,
 }
 
 static inline void
+set_wm_pid (ClutterStageX11 *stage_x11)
+{
+  ClutterBackendX11 *backend_x11 = stage_x11->backend;
+  long pid;
+
+  if (stage_x11->xwin == None)
+    return;
+
+  /* this will take care of WM_CLIENT_MACHINE and WM_LOCALE_NAME */
+  XSetWMProperties (stage_x11->xdpy, stage_x11->xwin,
+                    NULL,
+                    NULL,
+                    NULL, 0,
+                    NULL, NULL, NULL);
+
+  pid = getpid();
+  XChangeProperty (stage_x11->xdpy,
+                   stage_x11->xwin,
+                   backend_x11->atom_NET_WM_PID, XA_CARDINAL, 32,
+                   PropModeReplace,
+                   (guchar *) &pid, 1);
+}
+
+static inline void
 set_wm_title (ClutterStageX11 *stage_x11)
 {
   ClutterBackendX11 *backend_x11 = stage_x11->backend;
@@ -376,6 +400,7 @@ clutter_stage_x11_realize (ClutterActor *actor)
 {
   ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (actor);
 
+  set_wm_pid (stage_x11);
   set_wm_title (stage_x11);
   set_cursor_visible (stage_x11);
 }