From f47b81699617f23d8bcef74f714c9a52ea6550b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Gra=C3=B1a?= Date: Fri, 21 May 2010 16:18:12 -0300 Subject: [PATCH] Register systray only if systray widgets are attached. (FS#503) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Daniel GraƱa Signed-off-by: Uli Schlachter --- event.h | 2 ++ objects/wibox.c | 4 ++++ objects/wibox.h | 2 ++ screen.h | 1 + systray.c | 58 +++++++++++++++++++++++++++++++++++++++++++------ systray.h | 2 ++ 6 files changed, 62 insertions(+), 7 deletions(-) diff --git a/event.h b/event.h index 04bfbf10e..1dc1e77de 100644 --- a/event.h +++ b/event.h @@ -22,6 +22,7 @@ #ifndef AWESOME_EVENT_H #define AWESOME_EVENT_H +#include "systray.h" #include "objects/wibox.h" #include "objects/client.h" @@ -30,6 +31,7 @@ awesome_refresh(void) { banning_refresh(); wibox_refresh(); + systray_refresh(); stack_refresh(); return xcb_flush(globalconf.connection); } diff --git a/objects/wibox.c b/objects/wibox.c index 4c3c142a6..57cb2b2c0 100644 --- a/objects/wibox.c +++ b/objects/wibox.c @@ -412,6 +412,8 @@ wibox_map(wibox_t *wibox) static void wibox_systray_refresh(wibox_t *wibox) { + wibox->has_systray = false; + if(!wibox->screen) return; @@ -426,6 +428,8 @@ wibox_systray_refresh(wibox_t *wibox) xembed_window_t *em; int phys_screen = wibox->ctx.phys_screen; + wibox->has_systray = true; + if(wibox->visible && systray->widget->isvisible && systray->geometry.width) diff --git a/objects/wibox.h b/objects/wibox.h index d18b1a112..914b79c2b 100644 --- a/objects/wibox.h +++ b/objects/wibox.h @@ -65,6 +65,8 @@ struct wibox_t /** The window's content and border */ image_t *bounding; } shape; + /** Has wibox an attached systray **/ + bool has_systray; }; void wibox_unref_simplified(wibox_t **); diff --git a/screen.h b/screen.h index d9a5f06f5..b1c75be66 100644 --- a/screen.h +++ b/screen.h @@ -40,6 +40,7 @@ struct a_screen xcb_window_t window; /** Systray window parent */ xcb_window_t parent; + bool registered; } systray; /** Previously focused client */ client_t *prev_client_focus; diff --git a/systray.c b/systray.c index cbdb0e868..e229035cb 100644 --- a/systray.c +++ b/systray.c @@ -27,6 +27,8 @@ #include "systray.h" #include "xwindow.h" #include "objects/widget.h" +#include "objects/wibox.h" +#include "common/array.h" #include "common/atoms.h" #include "common/xutil.h" @@ -37,6 +39,46 @@ */ void systray_init(int phys_screen) +{ + xcb_screen_t *xscreen = xutil_screen_get(globalconf.connection, phys_screen); + + globalconf.screens.tab[phys_screen].systray.window = xcb_generate_id(globalconf.connection); + xcb_create_window(globalconf.connection, xscreen->root_depth, + globalconf.screens.tab[phys_screen].systray.window, + xscreen->root, + -1, -1, 1, 1, 0, + XCB_COPY_FROM_PARENT, xscreen->root_visual, 0, NULL); +} + + +/** Refresh all systrays registrations per physical screen + */ +void +systray_refresh() +{ + bool has_systray; + int nscreen = xcb_setup_roots_length(xcb_get_setup(globalconf.connection)); + + for(int phys_screen = 0; phys_screen < nscreen; phys_screen++) + { + has_systray = false; + foreach(w, globalconf.wiboxes) + if(phys_screen == (*w)->ctx.phys_screen) + has_systray |= (*w)->has_systray; + + if(has_systray) + systray_register(phys_screen); + else + systray_cleanup(phys_screen); + } +} + + +/** Register systray in X. + * \param phys_screen Physical screen. + */ +void +systray_register(int phys_screen) { xcb_client_message_event_t ev; xcb_screen_t *xscreen = xutil_screen_get(globalconf.connection, phys_screen); @@ -45,6 +87,11 @@ systray_init(int phys_screen) xcb_intern_atom_reply_t *atom_systray_r; xcb_atom_t atom_systray; + /* Set registered even if it fails to don't try again unless forced */ + if(globalconf.screens.tab[phys_screen].systray.registered) + return; + globalconf.screens.tab[phys_screen].systray.registered = true; + /* Send requests */ if(!(atom_name = xcb_atom_name_by_screen("_NET_SYSTEM_TRAY", phys_screen))) { @@ -57,13 +104,6 @@ systray_init(int phys_screen) p_delete(&atom_name); - globalconf.screens.tab[phys_screen].systray.window = xcb_generate_id(globalconf.connection); - xcb_create_window(globalconf.connection, xscreen->root_depth, - globalconf.screens.tab[phys_screen].systray.window, - xscreen->root, - -1, -1, 1, 1, 0, - XCB_COPY_FROM_PARENT, xscreen->root_visual, 0, NULL); - /* Fill event */ p_clear(&ev, 1); ev.response_type = XCB_CLIENT_MESSAGE; @@ -101,6 +141,10 @@ systray_cleanup(int phys_screen) xcb_intern_atom_reply_t *atom_systray_r; char *atom_name; + if(!globalconf.screens.tab[phys_screen].systray.registered) + return; + globalconf.screens.tab[phys_screen].systray.registered = false; + if(!(atom_name = xcb_atom_name_by_screen("_NET_SYSTEM_TRAY", phys_screen)) || !(atom_systray_r = xcb_intern_atom_reply(globalconf.connection, xcb_intern_atom_unchecked(globalconf.connection, diff --git a/systray.h b/systray.h index f877599ad..829d5adf2 100644 --- a/systray.h +++ b/systray.h @@ -26,6 +26,8 @@ #include "common/xembed.h" void systray_init(int); +void systray_refresh(void); +void systray_register(int); void systray_cleanup(int); int systray_request_handle(xcb_window_t, int, xembed_info_t *); bool systray_iskdedockapp(xcb_window_t);