Skip to content

Instantly share code, notes, and snippets.

@dangra
Created May 21, 2010 15:59
Show Gist options
  • Save dangra/409014 to your computer and use it in GitHub Desktop.
Save dangra/409014 to your computer and use it in GitHub Desktop.
diff --git a/objects/wibox.c b/objects/wibox.c
index b3a06cb..c33f77f 100644
--- a/objects/wibox.c
+++ b/objects/wibox.c
@@ -21,6 +21,7 @@
#include <xcb/shape.h>
+#include "systray.h"
#include "screen.h"
#include "wibox.h"
#include "objects/client.h"
@@ -443,6 +444,10 @@ wibox_systray_refresh(wibox_t *wibox)
uint32_t config_win_vals_off[2] = { -512, -512 };
xembed_window_t *em;
int phys_screen = wibox->ctx.phys_screen;
+ screen_t screen = globalconf.screens.tab[phys_screen];
+
+ if(!screen.systray.registered)
+ systray_register(phys_screen);
if(wibox->visible
&& systray->widget->isvisible
@@ -450,10 +455,10 @@ wibox_systray_refresh(wibox_t *wibox)
{
/* Set background of the systray window. */
xcb_change_window_attributes(globalconf.connection,
- globalconf.screens.tab[phys_screen].systray.window,
+ screen.systray.window,
XCB_CW_BACK_PIXEL, config_back);
/* Map it. */
- xcb_map_window(globalconf.connection, globalconf.screens.tab[phys_screen].systray.window);
+ xcb_map_window(globalconf.connection, screen.systray.window);
/* Move it. */
switch(wibox->orientation)
{
@@ -477,16 +482,16 @@ wibox_systray_refresh(wibox_t *wibox)
break;
}
/* reparent */
- if(globalconf.screens.tab[phys_screen].systray.parent != wibox->window)
+ if(screen.systray.parent != wibox->window)
{
xcb_reparent_window(globalconf.connection,
- globalconf.screens.tab[phys_screen].systray.window,
+ screen.systray.window,
wibox->window,
config_win_vals[0], config_win_vals[1]);
- globalconf.screens.tab[phys_screen].systray.parent = wibox->window;
+ screen.systray.parent = wibox->window;
}
xcb_configure_window(globalconf.connection,
- globalconf.screens.tab[phys_screen].systray.window,
+ screen.systray.window,
XCB_CONFIG_WINDOW_X
| XCB_CONFIG_WINDOW_Y
| XCB_CONFIG_WINDOW_WIDTH
diff --git a/screen.h b/screen.h
index 6db22d5..dc4c4b8 100644
--- a/screen.h
+++ b/screen.h
@@ -37,6 +37,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 576c99d..a27011c 100644
--- a/systray.c
+++ b/systray.c
@@ -38,12 +38,33 @@
void
systray_init(int phys_screen)
{
+ xcb_screen_t *xscreen = xutil_screen_get(globalconf.connection, phys_screen);
+ screen_t screen = globalconf.screens.tab[phys_screen];
+
+ screen.systray.window = xcb_generate_id(globalconf.connection);
+ xcb_create_window(globalconf.connection, xscreen->root_depth,
+ screen.systray.window,
+ xscreen->root,
+ -1, -1, 1, 1, 0,
+ XCB_COPY_FROM_PARENT, xscreen->root_visual, 0, NULL);
+}
+
+/** 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);
char *atom_name;
xcb_intern_atom_cookie_t atom_systray_q;
xcb_intern_atom_reply_t *atom_systray_r;
xcb_atom_t atom_systray;
+ screen_t screen = globalconf.screens.tab[phys_screen];
+
+ /* Set registered even if it fails to don't try again unless forced */
+ screen.systray.registered = true;
/* Send requests */
if(!(atom_name = xcb_atom_name_by_screen("_NET_SYSTEM_TRAY", phys_screen)))
@@ -57,13 +78,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;
@@ -71,7 +85,7 @@ systray_init(int phys_screen)
ev.format = 32;
ev.type = MANAGER;
ev.data.data32[0] = XCB_CURRENT_TIME;
- ev.data.data32[2] = globalconf.screens.tab[phys_screen].systray.window;
+ ev.data.data32[2] = screen.systray.window;
ev.data.data32[3] = ev.data.data32[4] = 0;
if(!(atom_systray_r = xcb_intern_atom_reply(globalconf.connection, atom_systray_q, NULL)))
@@ -85,7 +99,7 @@ systray_init(int phys_screen)
p_delete(&atom_systray_r);
xcb_set_selection_owner(globalconf.connection,
- globalconf.screens.tab[phys_screen].systray.window,
+ screen.systray.window,
atom_systray,
XCB_CURRENT_TIME);
@@ -100,6 +114,11 @@ systray_cleanup(int phys_screen)
{
xcb_intern_atom_reply_t *atom_systray_r;
char *atom_name;
+ screen_t screen = globalconf.screens.tab[phys_screen];
+
+ if(!screen.systray.registered)
+ return;
+ 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,
diff --git a/systray.h b/systray.h
index f877599..6175006 100644
--- a/systray.h
+++ b/systray.h
@@ -26,6 +26,7 @@
#include "common/xembed.h"
void systray_init(int);
+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);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment