From 207f06d720c01f480b1e8478e46e9052062566f6 Mon Sep 17 00:00:00 2001 From: Julien Danjou Date: Mon, 30 Jun 2008 13:06:23 +0200 Subject: [PATCH] systray: add KDE work around Signed-off-by: Julien Danjou --- client.c | 17 ++++++++++------- event.c | 24 +++++++++++++++++++++--- systray.c | 44 ++++++++++++++++++++++++++++++++++++++++++-- systray.h | 2 ++ 4 files changed, 75 insertions(+), 12 deletions(-) diff --git a/client.c b/client.c index c1e56298..487f0927 100644 --- a/client.c +++ b/client.c @@ -367,9 +367,14 @@ client_manage(xcb_window_t w, xcb_get_geometry_reply_t *wgeom, int screen) xcb_window_t trans; bool rettrans, retloadprops; xcb_size_hints_t *u_size_hints; - const uint32_t select_input_val[] = { - XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_PROPERTY_CHANGE | - XCB_EVENT_MASK_ENTER_WINDOW }; + const uint32_t select_input_val[] = + { + XCB_EVENT_MASK_STRUCTURE_NOTIFY + | XCB_EVENT_MASK_PROPERTY_CHANGE + | XCB_EVENT_MASK_ENTER_WINDOW + }; + + xcb_change_window_attributes(globalconf.connection, w, XCB_CW_EVENT_MASK, select_input_val); c = p_new(client_t, 1); @@ -414,8 +419,6 @@ client_manage(xcb_window_t w, xcb_get_geometry_reply_t *wgeom, int screen) if(rettrans || c->isfixed) client_setfloating(c, true); - xcb_change_window_attributes(globalconf.connection, w, XCB_CW_EVENT_MASK, select_input_val); - /* Push client in client list */ client_list_push(&globalconf.clients, c); /* Append client in history: it'll be last. */ @@ -436,8 +439,8 @@ client_manage(xcb_window_t w, xcb_get_geometry_reply_t *wgeom, int screen) if(c->floating_placement && !retloadprops && u_size_hints - && !(xcb_size_hints_get_flags(u_size_hints) & (XCB_SIZE_US_POSITION_HINT | - XCB_SIZE_P_POSITION_HINT))) + && !(xcb_size_hints_get_flags(u_size_hints) & (XCB_SIZE_US_POSITION_HINT + | XCB_SIZE_P_POSITION_HINT))) { if(c->isfloating) client_resize(c, c->floating_placement(c), false); diff --git a/event.c b/event.c index 5bf8c167..d31a3805 100644 --- a/event.c +++ b/event.c @@ -428,7 +428,7 @@ static int event_handle_maprequest(void *data __attribute__ ((unused)), xcb_connection_t *connection, xcb_map_request_event_t *ev) { - int screen_nbr = 0; + int screen_nbr = 0, ret = 0; client_t *c; xcb_get_window_attributes_cookie_t wa_c; xcb_get_window_attributes_reply_t *wa_r; @@ -460,6 +460,23 @@ event_handle_maprequest(void *data __attribute__ ((unused)), client_raise(c); } } + else if(systray_iskdedockapp(ev->window)) + { + geom_c = xcb_get_geometry_unchecked(connection, ev->window); + + if(!(geom_r = xcb_get_geometry_reply(connection, geom_c, NULL))) + { + ret = -1; + goto bailout; + } + + /* get real screen */ + for(iter = xcb_setup_roots_iterator(xcb_get_setup(connection)), screen_nbr = 0; + iter.rem && iter.data->root != geom_r->root; xcb_screen_next (&iter), ++screen_nbr); + systray_request_handle(ev->window, screen_nbr, NULL); + + p_delete(&geom_r); + } else { geom_c = xcb_get_geometry_unchecked(connection, ev->window); @@ -475,7 +492,8 @@ event_handle_maprequest(void *data __attribute__ ((unused)), qp_r = xcb_query_pointer_reply(connection, qp_c, NULL); p_delete(&qp_r); } - return -1; + ret = -1; + goto bailout; } if(globalconf.screens_info->xinerama_is_active @@ -495,7 +513,7 @@ event_handle_maprequest(void *data __attribute__ ((unused)), bailout: p_delete(&wa_r); - return 0; + return ret; } /** The property notify event handler. diff --git a/systray.c b/systray.c index 32841d7e..67ea61a1 100644 --- a/systray.c +++ b/systray.c @@ -21,6 +21,7 @@ #include #include +#include #include "systray.h" #include "window.h" @@ -77,7 +78,7 @@ systray_init(int phys_screen) /** Handle a systray request. * \param embed_win The window to embed. */ -static int +int systray_request_handle(xcb_window_t embed_win, int phys_screen, xembed_info_t *info) { xembed_window_t *em; @@ -91,7 +92,7 @@ systray_request_handle(xcb_window_t embed_win, int phys_screen, xembed_info_t *i /* check if not already trayed */ if((em = xembed_getbywin(globalconf.embedded, embed_win))) - return 1; + return -1; xcb_change_window_attributes(globalconf.connection, embed_win, XCB_CW_EVENT_MASK, select_input_val); @@ -163,6 +164,45 @@ systray_process_client_message(xcb_client_message_event_t *ev) return ret; } +/** Check if a window is a KDE tray. + * \param w The window to check. + * \return True if it is, false otherwise. + */ +bool +systray_iskdedockapp(xcb_window_t w) +{ + xcb_atom_t kde_net_wm_sytem_tray_window_for; + xutil_intern_atom_request_t kde_net_wm_sytem_tray_window_for_q; + xcb_get_property_cookie_t kde_check_q; + xcb_get_property_reply_t *kde_check; + bool ret; + + /* Check if that is a KDE tray because it does not repect fdo standards, + * thanks KDE. */ + kde_net_wm_sytem_tray_window_for_q = + xutil_intern_atom(globalconf.connection, + &globalconf.atoms, + "_KDE_NET_WM_SYSTEM_TRAY_WINDOW_FOR"); + + kde_net_wm_sytem_tray_window_for = + xutil_intern_atom_reply(globalconf.connection, + &globalconf.atoms, + kde_net_wm_sytem_tray_window_for_q); + + kde_check_q = xcb_get_property_unchecked(globalconf.connection, false, w, + kde_net_wm_sytem_tray_window_for, + WINDOW, 0, 1); + + kde_check = xcb_get_property_reply(globalconf.connection, kde_check_q, NULL); + + /* it's a KDE systray ?*/ + ret = (kde_check && kde_check->value_len); + + p_delete(&kde_check); + + return ret; +} + /** Handle xembed client message. * \param ev The event. * \return 0 on no error. diff --git a/systray.h b/systray.h index b1278e56..278cb394 100644 --- a/systray.h +++ b/systray.h @@ -26,6 +26,8 @@ #include "common/xembed.h" void systray_init(int); +int systray_request_handle(xcb_window_t, int, xembed_info_t *); +bool systray_iskdedockapp(xcb_window_t); int systray_process_client_message(xcb_client_message_event_t *); int xembed_process_client_message(xcb_client_message_event_t *);