From 2eba3ccc64e871c3ed56ed48a7edd7df740dc6e4 Mon Sep 17 00:00:00 2001 From: Martin Duquesnoy Date: Wed, 25 Jan 2012 04:01:59 +0100 Subject: [PATCH] ! NEW SYSTRAY ! systray element as 'y', element dynamic size --- Makefile.in | 1 + src/barwin.h | 7 +- src/config.h | 1 + src/event.c | 52 ++++++++------ src/ewmh.c | 14 ++-- src/ewmh.h | 9 +-- src/infobar.c | 187 ++++++++++++++++++++++++++++++++++++++------------ src/infobar.h | 13 ++-- src/screen.c | 2 +- src/status.c | 3 + src/systray.c | 113 ++++++++++++++++++++++-------- src/systray.h | 4 +- src/tag.c | 3 + src/wmfs.c | 2 +- src/wmfs.h | 4 +- wmfsrc | 7 +- 16 files changed, 301 insertions(+), 121 deletions(-) diff --git a/Makefile.in b/Makefile.in index 349896a..0dfe6fe 100644 --- a/Makefile.in +++ b/Makefile.in @@ -18,6 +18,7 @@ SRCS= \ src/util.c \ src/fifo.c \ src/status.c \ + src/systray.c \ src/mouse.c \ src/log.c \ src/wmfs.c diff --git a/src/barwin.h b/src/barwin.h index a010758..ea6de95 100644 --- a/src/barwin.h +++ b/src/barwin.h @@ -22,9 +22,14 @@ #define barwin_refresh(b) XCopyArea(W->dpy, b->dr, b->win, W->gc, 0, 0, b->geo.w, b->geo.h, 0, 0) #define barwin_map(b) XMapWindow(W->dpy, b->win); #define barwin_unmap(b) XUnmapWindow(W->dpy, b->win); -#define barwin_move(b, x, y) XMoveWindow(W->dpy, b->win, x, y); #define barwin_reparent(b, w) XReparentWindow(W->dpy, b->win, w, 0, 0); +static inline void +barwin_move(struct barwin *b, int x, int y) +{ + XMoveWindow(W->dpy, b->win, (b->geo.x = x), (b->geo.y = y)); +} + struct barwin* barwin_new(Window parent, int x, int y, int w, int h, Color fg, Color bg, bool entermask); void barwin_remove(struct barwin *b); void barwin_resize(struct barwin *b, int w, int h); diff --git a/src/config.h b/src/config.h index 92a4a81..4070ecd 100644 --- a/src/config.h +++ b/src/config.h @@ -17,6 +17,7 @@ #include "status.h" #include "mouse.h" #include "screen.h" +#include "infobar.h" #define THEME_DEFAULT (SLIST_FIRST(&W->h.theme)) diff --git a/src/event.c b/src/event.c index 3a2fcfb..4df06be 100644 --- a/src/event.c +++ b/src/event.c @@ -54,7 +54,7 @@ event_enternotify(XEvent *e) && ev->window != W->root) return; - if(ev->window == W->systray.win /* || systray_find(ev->window) */) + if(ev->window == W->systray.win || systray_find(ev->window)) return; if((c = client_gb_win(ev->window)) @@ -82,21 +82,27 @@ event_clientmessageevent(XEvent *e) * Systray message * _NET_WM_SYSTRAY_TRAY_OPCODE */ - if(ev->window == W->systray.win && type == net_wm_system_tray_opcode) + if(ev->window == W->systray.win && type == net_system_tray_opcode) { if(ev->data.l[1] == XEMBED_EMBEDDED_NOTIFY) { - /* systray_add(ev->data.l[2]); */ - /* systray_update() */ + systray_add(ev->data.l[2]); + systray_update(); } else if(ev->data.l[1] == XEMBED_REQUEST_FOCUS) { - /* if((sy = systray_find(ev->data.l[2]))) + if((sy = systray_find(ev->data.l[2]))) ewmh_send_message(sy->win, sy->win, "_XEMBED", XEMBED_FOCUS_IN, - XEMBED_FOCUS_CURRENT, 0, 0, 0);*/ + XEMBED_FOCUS_CURRENT, 0, 0, 0); } } + else if(ev->window == W->root) + { + if(type == net_active_window) + if((sy = systray_find(ev->data.l[0]))) + XSetInputFocus(W->dpy, sy->win, RevertToNone, CurrentTime); + } switch(type) { @@ -155,12 +161,12 @@ event_destroynotify(XEvent *e) if((c = client_gb_win(ev->window))) client_remove(c); - /*else if((s = systray_find(ev->window))) + else if((s = systray_find(ev->window))) { ewmh_set_wm_state(s->win, WithdrawnState); systray_del(s); systray_update(); - }*/ + } } static void @@ -186,11 +192,12 @@ event_maprequest(XEvent *e) if(!client_gb_win(ev->window)) client_new(ev->window, &at, false); - /*else if((s = systray_find(ev->window))) + else if((s = systray_find(ev->window))) { - ewmh_send_message(s->win, s->win, "_XEMBED", CurrentTime, XEMBED_WINDOW_ACTIVATE, 0, 0, 0); + ewmh_send_message(s->win, s->win, "_XEMBED", CurrentTime, + XEMBED_WINDOW_ACTIVATE, 0, 0, 0); systray_update(); - }*/ + } } static void @@ -239,11 +246,11 @@ event_propertynotify(XEvent *e) break; } } - /*else if((s = systray_find(ev->window))) + else if((s = systray_find(ev->window))) { systray_state(s); systray_update(); - }*/ + } } static void @@ -251,15 +258,15 @@ event_unmapnotify(XEvent *e) { XUnmapEvent *ev = &e->xunmap; struct client *c; - struct systray *s; + struct _systray *s; if((c = client_gb_win(ev->window)) && ev->send_event) client_remove(c); - /*else if((s = systray_find(ev->window))) + else if((s = systray_find(ev->window))) { systray_del(s); - systray_update(s); - }*/ + systray_update(); + } } static void @@ -303,21 +310,22 @@ event_mapnotify(XEvent *e) if((c = client_gb_win(ev->window))) ewmh_set_wm_state(c->win, NormalState); - /*else if((s = systray_find(ev->window))) + else if((s = systray_find(ev->window))) { ewmh_set_wm_state(s->win, NormalState); - ewmh_send_message(s->win, s->win, "_XEMBED", CurrentTime, XEMBED_WINDOW_ACTIVATE, 0, 0, 0); - }*/ + ewmh_send_message(s->win, s->win, "_XEMBED", CurrentTime, + XEMBED_WINDOW_ACTIVATE, 0, 0, 0); + } } static void event_selectionclearevent(XEvent *ev) { /* Getting selection if lost it */ -/* if(ev->xselectionclear.window == W->systray.win) + if(ev->xselectionclear.window == W->systray.win) systray_acquire(); - systray_update();*/ + systray_update(); } static void diff --git a/src/ewmh.c b/src/ewmh.c index d4dfaa3..6e5d6c9 100644 --- a/src/ewmh.c +++ b/src/ewmh.c @@ -22,6 +22,7 @@ ewmh_init(void) /* EWMH hints */ W->net_atom[wm_state] = ATOM("WM_STATE"); + W->net_atom[wm_class] = ATOM("WM_CLASS"); W->net_atom[net_supported] = ATOM("_NET_SUPPORTED"); W->net_atom[net_client_list] = ATOM("_NET_CLIENT_LIST"); W->net_atom[net_frame_extents] = ATOM("_NET_FRAME_EXTENTS"); @@ -48,7 +49,8 @@ ewmh_init(void) W->net_atom[net_wm_state_fullscreen] = ATOM("_NET_WM_STATE_FULLSCREEN"); W->net_atom[net_wm_state_sticky] = ATOM("_NET_WM_STATE_STICKY"); W->net_atom[net_wm_state_demands_attention] = ATOM("_NET_WM_STATE_DEMANDS_ATTENTION"); - W->net_atom[net_wm_system_tray_opcode] = ATOM("_NET_SYSTEM_TRAY_OPCODE"); + W->net_atom[net_system_tray_s] = ATOM("_NET_SYSTEM_TRAY_S0"); + W->net_atom[net_system_tray_opcode] = ATOM("_NET_SYSTEM_TRAY_OPCODE"); W->net_atom[net_system_tray_message_data] = ATOM("_NET_SYSTEM_TRAY_MESSAGE_DATA"); W->net_atom[net_system_tray_visual] = ATOM("_NET_SYSTEM_TRAY_VISUAL"); W->net_atom[net_system_tray_orientation] = ATOM("_NET_SYSTEM_TRAY_ORIENTATION"); @@ -79,12 +81,14 @@ ewmh_init(void) /* Set _NET_SUPPORTING_WM_CHECK */ XChangeProperty(W->dpy, W->root, W->net_atom[net_supporting_wm_check], XA_WINDOW, 32, PropModeReplace, (unsigned char*)&W->root, 1); - /* - XChangeProperty(W->dpy, W->root, W->net_atom[net_wm_name], W->net_atom[utf8_string], 8, - PropModeReplace, (unsigned char*)&rootn, strlen(rootn)); XChangeProperty(W->dpy, W->root, ATOM("WM_CLASS"), XA_STRING, 8, - PropModeReplace, (unsigned char*)&class, strlen(class)); + PropModeReplace, (unsigned char*)&"wmfs", 4); + + XChangeProperty(W->dpy, W->root, W->net_atom[net_wm_name], W->net_atom[utf8_string], 8, + PropModeReplace, (unsigned char*)&"wmfs2", 5); + + /* * Set _NET_WM_PID XChangeProperty(W->dpy, W->root, W->net_atom[net_wm_pid], XA_CARDINAL, 32, diff --git a/src/ewmh.h b/src/ewmh.h index cb4dd80..5037bf2 100644 --- a/src/ewmh.h +++ b/src/ewmh.h @@ -31,15 +31,16 @@ #define XEMBED_ACTIVATE_ACCELERATOR 14 /* Details for XEMBED_FOCUS_IN: */ -#define XEMBED_FOCUS_CURRENT0 -#define XEMBED_FOCUS_FIRST 1 -#define XEMBED_FOCUS_LAST2 +#define XEMBED_FOCUS_CURRENT 0 +#define XEMBED_FOCUS_FIRST 1 +#define XEMBED_FOCUS_LAST 2 /* Ewmh hints list */ enum { /* ICCCM */ wm_state, + wm_class, /* EWMH */ net_supported, net_wm_name, @@ -67,7 +68,7 @@ enum net_wm_state_fullscreen, net_wm_state_sticky, net_wm_state_demands_attention, - net_wm_system_tray_opcode, + net_system_tray_opcode, net_system_tray_message_data, net_system_tray_s, net_system_tray_visual, diff --git a/src/infobar.c b/src/infobar.c index 5ec95c6..c9e800d 100644 --- a/src/infobar.c +++ b/src/infobar.c @@ -10,11 +10,14 @@ #include "util.h" #include "tag.h" #include "status.h" +#include "systray.h" static void infobar_elem_tag_init(struct element *e); static void infobar_elem_tag_update(struct element *e); static void infobar_elem_status_init(struct element *e); static void infobar_elem_status_update(struct element *e); +static void infobar_elem_systray_init(struct element *e); +static void infobar_elem_systray_update(struct element *e); const struct elem_funcs { @@ -23,12 +26,9 @@ const struct elem_funcs void (*func_update)(struct element *e); } elem_funcs[] = { - { 't', infobar_elem_tag_init, infobar_elem_tag_update }, - { 's', infobar_elem_status_init, infobar_elem_status_update }, - - /* { 'l', infobar_elem_layout_init, infobar_elem_layout_update }, - { 'S', infobar_elem_selbar_init, infobar_elem_selbar_update }, - */ + { 't', infobar_elem_tag_init, infobar_elem_tag_update }, + { 's', infobar_elem_status_init, infobar_elem_status_update }, + { 'y', infobar_elem_systray_init, infobar_elem_systray_update }, { '\0', NULL, NULL } }; @@ -51,32 +51,41 @@ infobar_elem_tag_init(struct element *e) e->statusctx = &e->infobar->theme->tags_n_sl; - TAILQ_FOREACH(t, &e->infobar->screen->tags, next) + if(SLIST_EMPTY(&e->bars)) { - s = draw_textw(e->infobar->theme, t->name) + PAD; - - /* Init barwin */ - b = barwin_new(e->infobar->bar->win, j, 0, s, e->geo.h, 0, 0, false); - - /* Set border */ - if(e->infobar->theme->tags_border_width) + TAILQ_FOREACH(t, &e->infobar->screen->tags, next) { - XSetWindowBorder(W->dpy, b->win, e->infobar->theme->tags_border_col); - XSetWindowBorderWidth(W->dpy, b->win, e->infobar->theme->tags_border_width); + s = draw_textw(e->infobar->theme, t->name) + PAD; + + /* Init barwin */ + b = barwin_new(e->infobar->bar->win, j, 0, s, e->geo.h, 0, 0, false); + + /* Set border */ + if(e->infobar->theme->tags_border_width) + { + XSetWindowBorder(W->dpy, b->win, e->infobar->theme->tags_border_col); + XSetWindowBorderWidth(W->dpy, b->win, e->infobar->theme->tags_border_width); + } + + b->ptr = (void*)t; + barwin_map(b); + + b->mousebinds = W->tmp_head.tag; + + SLIST_INSERT_TAIL(&e->bars, b, enext, prev); + + prev = b; + j += s; + } + } + else + { + SLIST_FOREACH(b, &e->bars, enext) + { + barwin_move(b, j, 0); + j += b->geo.w; } - - b->ptr = (void*)t; - barwin_map(b); - - b->mousebinds = W->tmp_head.tag; - - SLIST_INSERT_TAIL(&e->bars, b, enext, prev); - - prev = b; - j += s; } - - e->infobar->screen->elemupdate |= FLAGINT(ElemTag); } static void @@ -137,25 +146,77 @@ infobar_elem_status_init(struct element *e) e->geo.w = e->infobar->geo.w - e->geo.x - (en ? e->infobar->geo.w - en->geo.x : 0); - b = barwin_new(e->infobar->bar->win, e->geo.x, 0, e->geo.w, e->geo.h, 0, 0, false); + if(!(b = SLIST_FIRST(&e->bars))) + { + b = barwin_new(e->infobar->bar->win, e->geo.x, 0, e->geo.w, e->geo.h, 0, 0, false); + barwin_refresh_color(b); + SLIST_INSERT_HEAD(&e->bars, b, enext); + + e->infobar->statusctx = status_new_ctx(b, e->infobar->theme); + e->infobar->statusctx.status = strdup("wmfs2"); + e->infobar->statusctx.update = true; + } + else + { + barwin_move(b, e->geo.x, e->geo.y); + barwin_resize(b, e->geo.w, e->geo.h); + } b->fg = e->infobar->theme->bars.fg; b->bg = e->infobar->theme->bars.bg; barwin_map(b); - - SLIST_INSERT_HEAD(&e->bars, b, enext); - - e->infobar->statusctx = status_new_ctx(b, e->infobar->theme); - - e->infobar->screen->elemupdate |= FLAGINT(ElemStatus); - e->infobar->statusctx.status = strdup("wmfs2"); } static void infobar_elem_status_update(struct element *e) { - status_manage(&e->infobar->statusctx); + if(e->infobar->statusctx.update) + status_manage(&e->infobar->statusctx); + else + { + status_render(&e->infobar->statusctx); + status_copy_mousebind(&e->infobar->statusctx); + } + puts("status"); +} + +static void +infobar_elem_systray_init(struct element *e) +{ + struct barwin *b; + + /* Activate systray mask; no more systray element allowed now */ + W->flags |= WMFS_SYSTRAY; + + W->systray.infobar = e->infobar; + + e->geo.w = systray_get_width(); + infobar_elem_placement(e); + + if(!(b = SLIST_FIRST(&e->bars))) + { + b = barwin_new(e->infobar->bar->win, e->geo.x, 0, e->geo.w, e->geo.h, 0, 0, false); + XFreePixmap(W->dpy, b->dr); + SLIST_INSERT_HEAD(&e->bars, b, enext); + W->systray.barwin = b; + systray_acquire(); + } + else + { + barwin_move(b, e->geo.x, e->geo.y); + barwin_resize(b, e->geo.w, e->geo.h); + } + + XMoveResizeWindow(W->dpy, W->systray.win, 0, 0, e->geo.w, e->geo.h); +} + +static void +infobar_elem_systray_update(struct element *e) +{ + (void)e; + + systray_update(); } #define ELEM_INIT(a) \ @@ -187,15 +248,16 @@ infobar_elem_init(struct infobar *i) break; } + /* Only one systray element in a wmfs session */ + if(i->elemorder[n] == 'y' && W->flags & WMFS_SYSTRAY) + continue; + for(j = 0; j < (int)LEN(elem_funcs); ++j) if(elem_funcs[j].c == i->elemorder[n]) { ELEM_INIT(Left); - if(TAILQ_EMPTY(&i->elements)) - TAILQ_INSERT_HEAD(&i->elements, e, next); - else - TAILQ_INSERT_TAIL(&i->elements, e, next); + TAILQ_INSERT_TAIL(&i->elements, e, next); e->func_init(e); es = e; @@ -211,7 +273,7 @@ infobar_elem_init(struct infobar *i) for(k = l - 1; k >= n; --k) { /* Only one status */ - if(i->elemorder[k] == 's') + if(i->elemorder[k] == 's' || (i->elemorder[n] == 'y' && W->flags & WMFS_SYSTRAY)) continue; for(j = 0; j < (int)LEN(elem_funcs); ++j) @@ -244,12 +306,12 @@ infobar_elem_init(struct infobar *i) } void -infobar_elem_update(struct infobar *i) +infobar_elem_update(struct infobar *i, int type) { struct element *e; TAILQ_FOREACH(e, &i->elements, next) - if(i->screen->elemupdate & FLAGINT(e->type)) + if(type == e->type || type == -1) e->func_update(e); } @@ -270,6 +332,38 @@ infobar_elem_remove(struct element *e) free(e); } +void +infobar_elem_reinit(struct infobar *i) +{ + struct element *e; + + TAILQ_FOREACH(e, &i->elements, next) + { + /* Status element found, scan from the tail now */ + if(e->type == ElemStatus) + { + struct element *ee; + + TAILQ_FOREACH_REVERSE(ee, &i->elements, esub, next) + { + if(e == ee) + break; + + ee->func_init(ee); + ee->func_update(ee); + } + + e->func_init(e); + e->func_update(e); + + return; + } + + e->func_init(e); + e->func_update(e); + } +} + struct infobar* infobar_new(struct screen *s, char *name, struct theme *theme, enum barpos pos, const char *elem) { @@ -307,7 +401,7 @@ infobar_new(struct screen *s, char *name, struct theme *theme, enum barpos pos, void infobar_refresh(struct infobar *i) { - infobar_elem_update(i); + infobar_elem_update(i, -1); barwin_refresh(i->bar); } @@ -321,6 +415,9 @@ infobar_remove(struct infobar *i) free(i->name); free(i->status); + if(i == W->systray.infobar) + systray_freeicons(); + TAILQ_FOREACH(e, &i->elements, next) infobar_elem_remove(e); diff --git a/src/infobar.h b/src/infobar.h index ee95f3f..7192ade 100644 --- a/src/infobar.h +++ b/src/infobar.h @@ -8,16 +8,16 @@ #include "wmfs.h" #include "util.h" -#include "draw.h" #include "tag.h" -enum { ElemTag = 0, ElemStatus, ElemCustom, ElemLast }; +enum { ElemTag = 0, ElemStatus, ElemSystray, ElemCustom, ElemLast }; struct infobar *infobar_new(struct screen *s, char *name, struct theme *theme, enum barpos pos, const char *elem); -void infobar_elem_update(struct infobar *i); +void infobar_elem_update(struct infobar *i, int type); void infobar_refresh(struct infobar *i); void infobar_remove(struct infobar *i); void infobar_free(struct screen *s); +void infobar_elem_reinit(struct infobar *i); /* Basic placement of elements */ static inline void @@ -63,16 +63,13 @@ infobar_placement(struct infobar *i, enum barpos p) } static inline void -infobar_elem_screen_update(struct screen *s, int addf) +infobar_elem_screen_update(struct screen *s, int type) { struct infobar *i; - s->elemupdate |= FLAGINT(addf); - SLIST_FOREACH(i, &s->infobars, next) - infobar_elem_update(i); + infobar_elem_update(i, type); - s->elemupdate &= ~FLAGINT(addf); } static inline struct infobar* diff --git a/src/screen.c b/src/screen.c index fd3c422..a38250b 100644 --- a/src/screen.c +++ b/src/screen.c @@ -129,7 +129,7 @@ uicb_screen_prev(Uicb cmd) static void screen_move_client(struct client *c, struct screen *s) { - tag_client(s->seltag, c); + tag_client(s->seltag, c); } void diff --git a/src/status.c b/src/status.c index 7859736..df908e8 100644 --- a/src/status.c +++ b/src/status.c @@ -327,6 +327,8 @@ status_manage(struct status_ctx *ctx) if(!ctx->status) return; + ctx->update = false; + status_flush_list(ctx); status_parse(ctx); status_render(ctx); @@ -355,6 +357,7 @@ uicb_status(Uicb cmd) { free(ib->statusctx.status); ib->statusctx.status = xstrdup(p); + ib->statusctx.update = true; infobar_elem_screen_update(s, ElemStatus); } } diff --git a/src/systray.c b/src/systray.c index 5758414..878df78 100644 --- a/src/systray.c +++ b/src/systray.c @@ -5,47 +5,57 @@ #include "wmfs.h" #include "systray.h" +#include "ewmh.h" +#include "infobar.h" -bool +#define SYSTRAY_SPACING (2) + +void systray_acquire(void) { + Window w = 0; XSetWindowAttributes wattr = - { - .event_mask = ButtonPressMask | ExposureMask, - .override_redirect = true, - .background_pixmap = ParentRelative, - .background_pixel = 0 - }; + { + .event_mask = ButtonPressMask | ExposureMask, + .override_redirect = true, + .background_pixmap = ParentRelative, + .background_pixel = W->systray.infobar->theme->bars.bg, + }; if(!(W->flags & WMFS_SYSTRAY) || W->systray.win) - return false; + return; if(XGetSelectionOwner(W->dpy, W->net_atom[net_system_tray_s]) != None) { warnx("Can't initialize system tray: owned by another process."); - return False; + return; } - /* Init traywin window */ - XChangeWindowAttributes(W->dpy, W->systray.win, CWEventMask | CWOverrideRedirect | CWBackPixel, &wattr); - XSelectInput(W->dpy, W->systray.win, KeyPressMask | ButtonPressMask); - XMapRaised(W->dpy, W->systray.win); - XSetSelectionOwner(W->dpy, W->net_atom[net_system_tray_s], W->systray.win, CurrentTime); + SLIST_INIT(&W->systray.head); - if(XGetSelectionOwner(W->dpy, W->net_atom[net_system_tray_s]) != W->systray.win) + /* Init systray window */ + w = XCreateSimpleWindow(W->dpy, W->systray.barwin->win, 0, 0, + W->systray.barwin->geo.h, W->systray.barwin->geo.h, 0, 0, 0); + + XChangeWindowAttributes(W->dpy, w, CWEventMask | CWOverrideRedirect | CWBackPixel, &wattr); + XSelectInput(W->dpy, w, KeyPressMask | ButtonPressMask); + XMapRaised(W->dpy, w); + + XSetSelectionOwner(W->dpy, W->net_atom[net_system_tray_s], w, CurrentTime); + + if(XGetSelectionOwner(W->dpy, W->net_atom[net_system_tray_s]) != w) { + warnl("System tray: can't get systray manager"); systray_freeicons(); - warnx("System tray: can't get systray manager"); - - return false; + return; } ewmh_send_message(W->root, W->root, "MANAGER", CurrentTime, - W->net_atom[net_system_tray_s], W->systray.win, 0, 0); + W->net_atom[net_system_tray_s], w, 0, 0); - XSync(dpy, false); + XSync(W->dpy, false); - return true; + W->systray.win = w; } void @@ -60,16 +70,18 @@ systray_add(Window win) s->win = win; s->geo.h = W->systray.barwin->geo.h; - s->geo.w = W->systray.barwin->geo.w + 2; + s->geo.w = W->systray.barwin->geo.h + SYSTRAY_SPACING; - ewmh_set_win_state(s->win, WithdrawnState); + ewmh_set_wm_state(s->win, WithdrawnState); XSelectInput(W->dpy, s->win, StructureNotifyMask | PropertyChangeMask| EnterWindowMask | FocusChangeMask); XReparentWindow(W->dpy, s->win, W->systray.win, 0, 0); ewmh_send_message(s->win, s->win, "_XEMBED", CurrentTime, - XEMBED_EMBEDDED_NOTIFY, 0, W->systray,win, 0); + XEMBED_EMBEDDED_NOTIFY, 0, W->systray.win, 0); SLIST_INSERT_HEAD(&W->systray.head, s, next); + + W->systray.redim = true; } void @@ -80,6 +92,8 @@ systray_del(struct _systray *s) SLIST_REMOVE(&W->systray.head, s, _systray, next); free(s); + + W->systray.redim = true; } void @@ -95,13 +109,13 @@ systray_state(struct _systray *s) { code = XEMBED_WINDOW_ACTIVATE; XMapRaised(W->dpy, s->win); - ewmh_set_win_state(s->win, NormalState); + ewmh_set_wm_state(s->win, NormalState); } else { code = XEMBED_WINDOW_DEACTIVATE; XUnmapWindow(W->dpy, s->win); - ewmh_set_win_state(s->win, WithdrawnState); + ewmh_set_wm_state(s->win, WithdrawnState); } ewmh_send_message(s->win, s->win, "_XEMBED", CurrentTime, code, 0, 0, 0); @@ -120,13 +134,14 @@ systray_freeicons(void) i = SLIST_FIRST(&W->systray.head); SLIST_REMOVE_HEAD(&W->systray.head, next); - XUnmapWindow(dpy, i->win); - XReparentWindow(dpy, i->win, W->root, 0, 0); + XUnmapWindow(W->dpy, i->win); + XReparentWindow(W->dpy, i->win, W->root, 0, 0); free(i); } XSetSelectionOwner(W->dpy, W->net_atom[net_system_tray_s], None, CurrentTime); - XDestroyWindow(W->dpy, W->systray.win); + W->systray.barwin->geo.w = 0; + infobar_elem_reinit(W->systray.infobar); XSync(W->dpy, false); } @@ -144,3 +159,43 @@ systray_find(Window win) return NULL; } + +int +systray_get_width(void) +{ + int w = 1; + struct _systray *i; + + SLIST_FOREACH(i, &W->systray.head, next) + w += i->geo.w + SYSTRAY_SPACING; + + return w; +} + +void +systray_update(void) +{ + int x = 1; + struct _systray *i; + + if(!(W->flags & WMFS_SYSTRAY)) + return; + + if(W->systray.redim) + { + W->systray.redim = false; + infobar_elem_reinit(W->systray.infobar); + puts("update"); + } + + SLIST_FOREACH(i, &W->systray.head, next) + { + XMapWindow(W->dpy, i->win); + XMoveResizeWindow(W->dpy, i->win, (i->geo.x = x), 0, i->geo.w, i->geo.h); + + x += i->geo.w + SYSTRAY_SPACING; + } +} + + + diff --git a/src/systray.h b/src/systray.h index dc61405..41bfa6f 100644 --- a/src/systray.h +++ b/src/systray.h @@ -8,11 +8,13 @@ #include "wmfs.h" -bool systray_acquire(void); +void systray_acquire(void); void systray_add(Window win); void systray_del(struct _systray *s); void systray_state(struct _systray *s); void systray_freeicons(void); struct _systray *systray_find(Window win); +int systray_get_width(void); +void systray_update(void); #endif /* SYSTRAY_H */ diff --git a/src/tag.c b/src/tag.c index bcbbd6f..193d3f1 100644 --- a/src/tag.c +++ b/src/tag.c @@ -101,6 +101,8 @@ tag_client(struct tag *t, struct client *c) */ SLIST_INSERT_HEAD(&t->clients, c, tnext); + infobar_elem_screen_update(t->screen, ElemTag); + if(c->flags & CLIENT_IGNORE_LAYOUT) c->flags ^= CLIENT_IGNORE_LAYOUT; else if(!(c->flags & CLIENT_TABBED)) @@ -117,6 +119,7 @@ tag_client(struct tag *t, struct client *c) if(t != c->screen->seltag || c->flags & CLIENT_TABBED) client_unmap(c); + } void diff --git a/src/wmfs.c b/src/wmfs.c index 03fe5b9..3c5f405 100644 --- a/src/wmfs.c +++ b/src/wmfs.c @@ -202,7 +202,7 @@ wmfs_scan(void) int i, n, rf, nscreen = 0; int tag = -1, screen = -1, flags = -1; unsigned long ir, il; - long *ret, *tret; + long *ret = NULL, *tret; bool getg = false; XWindowAttributes wa; Window usl, usl2, *w = NULL, tm, focus; diff --git a/src/wmfs.h b/src/wmfs.h index effdc90..7c08516 100644 --- a/src/wmfs.h +++ b/src/wmfs.h @@ -113,6 +113,7 @@ struct status_ctx struct barwin *barwin; struct theme *theme; char *status; + bool update; SLIST_HEAD(, status_seq) statushead; }; @@ -149,7 +150,6 @@ struct screen struct geo geo, ugeo; struct tag *seltag; int id; - Flags elemupdate; TAILQ_HEAD(tsub, tag) tags; SLIST_HEAD(, infobar) infobars; SLIST_ENTRY(screen) next; @@ -346,6 +346,8 @@ struct wmfs struct { struct barwin *barwin; + struct infobar *infobar; + bool redim; Window win; SLIST_HEAD(, _systray) head; } systray; diff --git a/wmfsrc b/wmfsrc index a014a39..c184cde 100644 --- a/wmfsrc +++ b/wmfsrc @@ -38,11 +38,11 @@ # Frame / Client client_normal_fg = "#AABBAA" client_normal_bg = "#223322" - client_normal_statusline = "\s[left;#ff0000; x](1;client_close)" + client_normal_statusline = "\s[3;9;#121212;x] \s[2;8;#ff0000;x](1;client_close)" client_sel_fg = "#223322" client_sel_bg = "#AABBAA" - client_sel_statusline = "\s[left;#ff0000; x](1;client_close)" + client_sel_statusline = "\s[3;9;#121212;x] \s[2;8;#ff0000;x](1;client_close)" frame_bg = "#555555" client_titlebar_width = 12 @@ -64,11 +64,12 @@ # # t Tags # s Statustext (will take available space) + # y Systray (can be set only ONE time among all element) [bar] position = 0 screen = 0 - elements = "ts" # element order in bar + elements = "tsy" # element order in bar theme = "default" [/bar]