systray: add KDE work around

Signed-off-by: Julien Danjou <julien@danjou.info>
This commit is contained in:
Julien Danjou 2008-06-30 13:06:23 +02:00
parent 0e42c66d49
commit 207f06d720
4 changed files with 75 additions and 12 deletions

View File

@ -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);

24
event.c
View File

@ -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.

View File

@ -21,6 +21,7 @@
#include <xcb/xcb.h>
#include <xcb/xcb_icccm.h>
#include <xcb/xcb_atom.h>
#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.

View File

@ -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 *);