From fbf28cc80d4b9c43f1c99cd22de5539503d36f2b Mon Sep 17 00:00:00 2001 From: Maarten Maathuis Date: Mon, 1 Dec 2008 19:44:28 +0100 Subject: [PATCH] client: Expose leader_id. Signed-off-by: Maarten Maathuis Signed-off-by: Julien Danjou --- client.c | 5 +++++ common/atoms.list | 1 + common/tokenize.gperf | 1 + property.c | 46 +++++++++++++++++++++++++++++++++++++++++++ property.h | 1 + structs.h | 2 ++ 6 files changed, 56 insertions(+) diff --git a/client.c b/client.c index 5a6231abf..dc99bc825 100644 --- a/client.c +++ b/client.c @@ -465,6 +465,7 @@ client_manage(xcb_window_t w, xcb_get_geometry_reply_t *wgeom, int phys_screen, property_update_wm_normal_hints(c, NULL); property_update_wm_hints(c, NULL); property_update_wm_transient_for(c, NULL); + property_update_wm_client_leader(c, NULL); if(c->transient_for) screen = c->transient_for->screen; @@ -1478,6 +1479,7 @@ luaA_client_newindex(lua_State *L) * \lfield maximized_vertical The client is maximized vertically or not. * \lfield transient_for Return the client the window is transient for. * \lfield group_id Identification unique to a group of windows. + * \lfield leader_id Identification unique to windows spawned by the same command. * \lfield size_hints A table with size hints of the client: user_position, * user_size, program_position and program_size. */ @@ -1577,6 +1579,9 @@ luaA_client_index(lua_State *L) return 0; } break; + case A_TK_LEADER_ID: + lua_pushnumber(L, (*c)->leader_win); + break; case A_TK_MACHINE: if(!xutil_text_prop_get(globalconf.connection, (*c)->win, WM_CLIENT_MACHINE, &value, &slen)) diff --git a/common/atoms.list b/common/atoms.list index 6ab239d2d..f7205e186 100644 --- a/common/atoms.list +++ b/common/atoms.list @@ -53,3 +53,4 @@ _NET_WM_WINDOW_OPACITY _NET_SYSTEM_TRAY_ORIENTATION WM_CHANGE_STATE WM_WINDOW_ROLE +WM_CLIENT_LEADER diff --git a/common/tokenize.gperf b/common/tokenize.gperf index cb7a362a6..36f2238c9 100644 --- a/common/tokenize.gperf +++ b/common/tokenize.gperf @@ -37,6 +37,7 @@ icon icon_name image instance +leader_id left len line diff --git a/property.c b/property.c index b641a8b37..04a898d7b 100644 --- a/property.c +++ b/property.c @@ -69,6 +69,50 @@ property_handle_wm_transient_for(void *data, return 0; } + +/** Update leader hint of a client. + * \param c The client. + * \param reply (Optional) An existing reply. + */ +void +property_update_wm_client_leader(client_t *c, xcb_get_property_reply_t *reply) +{ + xcb_get_property_cookie_t client_leader_q; + void *data; + bool no_reply = !reply; + + if(no_reply) + { + client_leader_q = xcb_get_property_unchecked(globalconf.connection, false, c->win, + WM_CLIENT_LEADER, WINDOW, 0, 32); + + reply = xcb_get_property_reply(globalconf.connection, client_leader_q, NULL); + } + + if(reply && reply->value_len && (data = xcb_get_property_value(reply))) + c->leader_win = *(xcb_window_t *) data; + + /* Only free when we created a reply ourselves. */ + if(no_reply) + p_delete(&reply); +} + +static int +property_handle_wm_client_leader(void *data, + xcb_connection_t *connection, + uint8_t state, + xcb_window_t window, + xcb_atom_t name, + xcb_get_property_reply_t *reply) +{ + client_t *c = client_getbywin(window); + + if(c) + property_update_wm_client_leader(c, reply); + + return 0; +} + /** Update the size hints of a client. * \param c The client. */ @@ -394,6 +438,8 @@ void a_xcb_set_property_handlers(void) /* ICCCM stuff */ xcb_property_set_handler(&globalconf.prophs, WM_TRANSIENT_FOR, UINT_MAX, property_handle_wm_transient_for, NULL); + xcb_property_set_handler(&globalconf.prophs, WM_CLIENT_LEADER, UINT_MAX, + property_handle_wm_client_leader, NULL); xcb_property_set_handler(&globalconf.prophs, WM_NORMAL_HINTS, UINT_MAX, property_handle_wm_normal_hints, NULL); xcb_property_set_handler(&globalconf.prophs, WM_HINTS, UINT_MAX, diff --git a/property.h b/property.h index f62a520c8..e00851df4 100644 --- a/property.h +++ b/property.h @@ -25,6 +25,7 @@ #include "structs.h" void property_update_wm_transient_for(client_t *, xcb_get_property_reply_t *); +void property_update_wm_client_leader(client_t *c, xcb_get_property_reply_t *reply); void property_update_wm_normal_hints(client_t *, xcb_get_property_reply_t *); void property_update_wm_hints(client_t *, xcb_get_property_reply_t *); void property_update_wm_name(client_t *); diff --git a/structs.h b/structs.h index b61d5c7e9..ae32b7bc8 100644 --- a/structs.h +++ b/structs.h @@ -205,6 +205,8 @@ struct client_t xcb_window_t win; /** Window of the group leader */ xcb_window_t group_win; + /** Window holding command needed to start it (session management related) */ + xcb_window_t leader_win; /** Client logical screen */ int screen; /** Client physical screen */