Add new Atom atom_NET_WM_PID to set pid info

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>
This commit is contained in:
Xu Li 2009-08-04 22:06:27 +08:00 committed by Emmanuele Bassi
parent 3abf393b87
commit f7edc97d8d
3 changed files with 38 additions and 10 deletions

View File

@ -76,6 +76,7 @@ void _clutter_x11_register_xinput ();
* atom name here. do not change the order! * atom name here. do not change the order!
*/ */
static const gchar *atom_names[] = { static const gchar *atom_names[] = {
"_NET_WM_PID",
"_NET_WM_PING", "_NET_WM_PING",
"_NET_WM_STATE", "_NET_WM_STATE",
"_NET_WM_STATE_FULLSCREEN", "_NET_WM_STATE_FULLSCREEN",
@ -201,16 +202,17 @@ clutter_backend_x11_post_parse (ClutterBackend *backend,
(char **) atom_names, n_atom_names, (char **) atom_names, n_atom_names,
False, atoms); False, atoms);
backend_x11->atom_NET_WM_PING = atoms[0]; backend_x11->atom_NET_WM_PID = atoms[0];
backend_x11->atom_NET_WM_STATE = atoms[1]; backend_x11->atom_NET_WM_PING = atoms[1];
backend_x11->atom_NET_WM_STATE_FULLSCREEN = atoms[2]; backend_x11->atom_NET_WM_STATE = atoms[2];
backend_x11->atom_NET_WM_USER_TIME = atoms[3]; backend_x11->atom_NET_WM_STATE_FULLSCREEN = atoms[3];
backend_x11->atom_WM_PROTOCOLS = atoms[4]; backend_x11->atom_NET_WM_USER_TIME = atoms[4];
backend_x11->atom_WM_DELETE_WINDOW = atoms[5]; backend_x11->atom_WM_PROTOCOLS = atoms[5];
backend_x11->atom_XEMBED = atoms[6]; backend_x11->atom_WM_DELETE_WINDOW = atoms[6];
backend_x11->atom_XEMBED_INFO = atoms[7]; backend_x11->atom_XEMBED = atoms[7];
backend_x11->atom_NET_WM_NAME = atoms[8]; backend_x11->atom_XEMBED_INFO = atoms[8];
backend_x11->atom_UTF8_STRING = atoms[9]; backend_x11->atom_NET_WM_NAME = atoms[9];
backend_x11->atom_UTF8_STRING = atoms[10];
} }
g_free (clutter_display_name); g_free (clutter_display_name);

View File

@ -64,6 +64,7 @@ struct _ClutterBackendX11
GSList *event_filters; GSList *event_filters;
/* props */ /* props */
Atom atom_NET_WM_PID;
Atom atom_NET_WM_PING; Atom atom_NET_WM_PING;
Atom atom_NET_WM_STATE; Atom atom_NET_WM_STATE;
Atom atom_NET_WM_STATE_FULLSCREEN; Atom atom_NET_WM_STATE_FULLSCREEN;

View File

@ -303,6 +303,30 @@ clutter_stage_x11_allocate (ClutterActor *self,
parent_class->allocate (self, box, flags); parent_class->allocate (self, box, flags);
} }
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 static inline void
set_wm_title (ClutterStageX11 *stage_x11) set_wm_title (ClutterStageX11 *stage_x11)
{ {
@ -376,6 +400,7 @@ clutter_stage_x11_realize (ClutterActor *actor)
{ {
ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (actor); ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (actor);
set_wm_pid (stage_x11);
set_wm_title (stage_x11); set_wm_title (stage_x11);
set_cursor_visible (stage_x11); set_cursor_visible (stage_x11);
} }