! NEW SYSTRAY ! systray element as 'y', element dynamic size

This commit is contained in:
Martin Duquesnoy 2012-01-25 04:01:59 +01:00
parent f8dedf7231
commit 2eba3ccc64
16 changed files with 301 additions and 121 deletions

View File

@ -18,6 +18,7 @@ SRCS= \
src/util.c \ src/util.c \
src/fifo.c \ src/fifo.c \
src/status.c \ src/status.c \
src/systray.c \
src/mouse.c \ src/mouse.c \
src/log.c \ src/log.c \
src/wmfs.c src/wmfs.c

View File

@ -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_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_map(b) XMapWindow(W->dpy, b->win);
#define barwin_unmap(b) XUnmapWindow(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); #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); 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_remove(struct barwin *b);
void barwin_resize(struct barwin *b, int w, int h); void barwin_resize(struct barwin *b, int w, int h);

View File

@ -17,6 +17,7 @@
#include "status.h" #include "status.h"
#include "mouse.h" #include "mouse.h"
#include "screen.h" #include "screen.h"
#include "infobar.h"
#define THEME_DEFAULT (SLIST_FIRST(&W->h.theme)) #define THEME_DEFAULT (SLIST_FIRST(&W->h.theme))

View File

@ -54,7 +54,7 @@ event_enternotify(XEvent *e)
&& ev->window != W->root) && ev->window != W->root)
return; return;
if(ev->window == W->systray.win /* || systray_find(ev->window) */) if(ev->window == W->systray.win || systray_find(ev->window))
return; return;
if((c = client_gb_win(ev->window)) if((c = client_gb_win(ev->window))
@ -82,21 +82,27 @@ event_clientmessageevent(XEvent *e)
* Systray message * Systray message
* _NET_WM_SYSTRAY_TRAY_OPCODE * _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) if(ev->data.l[1] == XEMBED_EMBEDDED_NOTIFY)
{ {
/* systray_add(ev->data.l[2]); */ systray_add(ev->data.l[2]);
/* systray_update() */ systray_update();
} }
else if(ev->data.l[1] == XEMBED_REQUEST_FOCUS) 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, 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) switch(type)
{ {
@ -155,12 +161,12 @@ event_destroynotify(XEvent *e)
if((c = client_gb_win(ev->window))) if((c = client_gb_win(ev->window)))
client_remove(c); client_remove(c);
/*else if((s = systray_find(ev->window))) else if((s = systray_find(ev->window)))
{ {
ewmh_set_wm_state(s->win, WithdrawnState); ewmh_set_wm_state(s->win, WithdrawnState);
systray_del(s); systray_del(s);
systray_update(); systray_update();
}*/ }
} }
static void static void
@ -186,11 +192,12 @@ event_maprequest(XEvent *e)
if(!client_gb_win(ev->window)) if(!client_gb_win(ev->window))
client_new(ev->window, &at, false); 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(); systray_update();
}*/ }
} }
static void static void
@ -239,11 +246,11 @@ event_propertynotify(XEvent *e)
break; break;
} }
} }
/*else if((s = systray_find(ev->window))) else if((s = systray_find(ev->window)))
{ {
systray_state(s); systray_state(s);
systray_update(); systray_update();
}*/ }
} }
static void static void
@ -251,15 +258,15 @@ event_unmapnotify(XEvent *e)
{ {
XUnmapEvent *ev = &e->xunmap; XUnmapEvent *ev = &e->xunmap;
struct client *c; struct client *c;
struct systray *s; struct _systray *s;
if((c = client_gb_win(ev->window)) && ev->send_event) if((c = client_gb_win(ev->window)) && ev->send_event)
client_remove(c); client_remove(c);
/*else if((s = systray_find(ev->window))) else if((s = systray_find(ev->window)))
{ {
systray_del(s); systray_del(s);
systray_update(s); systray_update();
}*/ }
} }
static void static void
@ -303,21 +310,22 @@ event_mapnotify(XEvent *e)
if((c = client_gb_win(ev->window))) if((c = client_gb_win(ev->window)))
ewmh_set_wm_state(c->win, NormalState); 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_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 static void
event_selectionclearevent(XEvent *ev) event_selectionclearevent(XEvent *ev)
{ {
/* Getting selection if lost it */ /* Getting selection if lost it */
/* if(ev->xselectionclear.window == W->systray.win) if(ev->xselectionclear.window == W->systray.win)
systray_acquire(); systray_acquire();
systray_update();*/ systray_update();
} }
static void static void

View File

@ -22,6 +22,7 @@ ewmh_init(void)
/* EWMH hints */ /* EWMH hints */
W->net_atom[wm_state] = ATOM("WM_STATE"); 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_supported] = ATOM("_NET_SUPPORTED");
W->net_atom[net_client_list] = ATOM("_NET_CLIENT_LIST"); W->net_atom[net_client_list] = ATOM("_NET_CLIENT_LIST");
W->net_atom[net_frame_extents] = ATOM("_NET_FRAME_EXTENTS"); 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_fullscreen] = ATOM("_NET_WM_STATE_FULLSCREEN");
W->net_atom[net_wm_state_sticky] = ATOM("_NET_WM_STATE_STICKY"); 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_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_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_visual] = ATOM("_NET_SYSTEM_TRAY_VISUAL");
W->net_atom[net_system_tray_orientation] = ATOM("_NET_SYSTEM_TRAY_ORIENTATION"); W->net_atom[net_system_tray_orientation] = ATOM("_NET_SYSTEM_TRAY_ORIENTATION");
@ -79,12 +81,14 @@ ewmh_init(void)
/* Set _NET_SUPPORTING_WM_CHECK */ /* Set _NET_SUPPORTING_WM_CHECK */
XChangeProperty(W->dpy, W->root, W->net_atom[net_supporting_wm_check], XA_WINDOW, 32, XChangeProperty(W->dpy, W->root, W->net_atom[net_supporting_wm_check], XA_WINDOW, 32,
PropModeReplace, (unsigned char*)&W->root, 1); 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, 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 * Set _NET_WM_PID
XChangeProperty(W->dpy, W->root, W->net_atom[net_wm_pid], XA_CARDINAL, 32, XChangeProperty(W->dpy, W->root, W->net_atom[net_wm_pid], XA_CARDINAL, 32,

View File

@ -31,15 +31,16 @@
#define XEMBED_ACTIVATE_ACCELERATOR 14 #define XEMBED_ACTIVATE_ACCELERATOR 14
/* Details for XEMBED_FOCUS_IN: */ /* Details for XEMBED_FOCUS_IN: */
#define XEMBED_FOCUS_CURRENT0 #define XEMBED_FOCUS_CURRENT 0
#define XEMBED_FOCUS_FIRST 1 #define XEMBED_FOCUS_FIRST 1
#define XEMBED_FOCUS_LAST2 #define XEMBED_FOCUS_LAST 2
/* Ewmh hints list */ /* Ewmh hints list */
enum enum
{ {
/* ICCCM */ /* ICCCM */
wm_state, wm_state,
wm_class,
/* EWMH */ /* EWMH */
net_supported, net_supported,
net_wm_name, net_wm_name,
@ -67,7 +68,7 @@ enum
net_wm_state_fullscreen, net_wm_state_fullscreen,
net_wm_state_sticky, net_wm_state_sticky,
net_wm_state_demands_attention, net_wm_state_demands_attention,
net_wm_system_tray_opcode, net_system_tray_opcode,
net_system_tray_message_data, net_system_tray_message_data,
net_system_tray_s, net_system_tray_s,
net_system_tray_visual, net_system_tray_visual,

View File

@ -10,11 +10,14 @@
#include "util.h" #include "util.h"
#include "tag.h" #include "tag.h"
#include "status.h" #include "status.h"
#include "systray.h"
static void infobar_elem_tag_init(struct element *e); static void infobar_elem_tag_init(struct element *e);
static void infobar_elem_tag_update(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_init(struct element *e);
static void infobar_elem_status_update(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 const struct elem_funcs
{ {
@ -25,10 +28,7 @@ const struct elem_funcs
{ {
{ 't', infobar_elem_tag_init, infobar_elem_tag_update }, { 't', infobar_elem_tag_init, infobar_elem_tag_update },
{ 's', infobar_elem_status_init, infobar_elem_status_update }, { 's', infobar_elem_status_init, infobar_elem_status_update },
{ 'y', infobar_elem_systray_init, infobar_elem_systray_update },
/* { 'l', infobar_elem_layout_init, infobar_elem_layout_update },
{ 'S', infobar_elem_selbar_init, infobar_elem_selbar_update },
*/
{ '\0', NULL, NULL } { '\0', NULL, NULL }
}; };
@ -51,6 +51,8 @@ infobar_elem_tag_init(struct element *e)
e->statusctx = &e->infobar->theme->tags_n_sl; e->statusctx = &e->infobar->theme->tags_n_sl;
if(SLIST_EMPTY(&e->bars))
{
TAILQ_FOREACH(t, &e->infobar->screen->tags, next) TAILQ_FOREACH(t, &e->infobar->screen->tags, next)
{ {
s = draw_textw(e->infobar->theme, t->name) + PAD; s = draw_textw(e->infobar->theme, t->name) + PAD;
@ -75,8 +77,15 @@ infobar_elem_tag_init(struct element *e)
prev = b; prev = b;
j += s; j += s;
} }
}
e->infobar->screen->elemupdate |= FLAGINT(ElemTag); else
{
SLIST_FOREACH(b, &e->bars, enext)
{
barwin_move(b, j, 0);
j += b->geo.w;
}
}
} }
static void 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); e->geo.w = e->infobar->geo.w - e->geo.x - (en ? e->infobar->geo.w - en->geo.x : 0);
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); 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->fg = e->infobar->theme->bars.fg;
b->bg = e->infobar->theme->bars.bg; b->bg = e->infobar->theme->bars.bg;
barwin_map(b); 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 static void
infobar_elem_status_update(struct element *e) infobar_elem_status_update(struct element *e)
{ {
if(e->infobar->statusctx.update)
status_manage(&e->infobar->statusctx); 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) \ #define ELEM_INIT(a) \
@ -187,14 +248,15 @@ infobar_elem_init(struct infobar *i)
break; 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) for(j = 0; j < (int)LEN(elem_funcs); ++j)
if(elem_funcs[j].c == i->elemorder[n]) if(elem_funcs[j].c == i->elemorder[n])
{ {
ELEM_INIT(Left); 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); e->func_init(e);
@ -211,7 +273,7 @@ infobar_elem_init(struct infobar *i)
for(k = l - 1; k >= n; --k) for(k = l - 1; k >= n; --k)
{ {
/* Only one status */ /* Only one status */
if(i->elemorder[k] == 's') if(i->elemorder[k] == 's' || (i->elemorder[n] == 'y' && W->flags & WMFS_SYSTRAY))
continue; continue;
for(j = 0; j < (int)LEN(elem_funcs); ++j) for(j = 0; j < (int)LEN(elem_funcs); ++j)
@ -244,12 +306,12 @@ infobar_elem_init(struct infobar *i)
} }
void void
infobar_elem_update(struct infobar *i) infobar_elem_update(struct infobar *i, int type)
{ {
struct element *e; struct element *e;
TAILQ_FOREACH(e, &i->elements, next) TAILQ_FOREACH(e, &i->elements, next)
if(i->screen->elemupdate & FLAGINT(e->type)) if(type == e->type || type == -1)
e->func_update(e); e->func_update(e);
} }
@ -270,6 +332,38 @@ infobar_elem_remove(struct element *e)
free(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* struct infobar*
infobar_new(struct screen *s, char *name, struct theme *theme, enum barpos pos, const char *elem) 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 void
infobar_refresh(struct infobar *i) infobar_refresh(struct infobar *i)
{ {
infobar_elem_update(i); infobar_elem_update(i, -1);
barwin_refresh(i->bar); barwin_refresh(i->bar);
} }
@ -321,6 +415,9 @@ infobar_remove(struct infobar *i)
free(i->name); free(i->name);
free(i->status); free(i->status);
if(i == W->systray.infobar)
systray_freeicons();
TAILQ_FOREACH(e, &i->elements, next) TAILQ_FOREACH(e, &i->elements, next)
infobar_elem_remove(e); infobar_elem_remove(e);

View File

@ -8,16 +8,16 @@
#include "wmfs.h" #include "wmfs.h"
#include "util.h" #include "util.h"
#include "draw.h"
#include "tag.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); 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_refresh(struct infobar *i);
void infobar_remove(struct infobar *i); void infobar_remove(struct infobar *i);
void infobar_free(struct screen *s); void infobar_free(struct screen *s);
void infobar_elem_reinit(struct infobar *i);
/* Basic placement of elements */ /* Basic placement of elements */
static inline void static inline void
@ -63,16 +63,13 @@ infobar_placement(struct infobar *i, enum barpos p)
} }
static inline void static inline void
infobar_elem_screen_update(struct screen *s, int addf) infobar_elem_screen_update(struct screen *s, int type)
{ {
struct infobar *i; struct infobar *i;
s->elemupdate |= FLAGINT(addf);
SLIST_FOREACH(i, &s->infobars, next) SLIST_FOREACH(i, &s->infobars, next)
infobar_elem_update(i); infobar_elem_update(i, type);
s->elemupdate &= ~FLAGINT(addf);
} }
static inline struct infobar* static inline struct infobar*

View File

@ -327,6 +327,8 @@ status_manage(struct status_ctx *ctx)
if(!ctx->status) if(!ctx->status)
return; return;
ctx->update = false;
status_flush_list(ctx); status_flush_list(ctx);
status_parse(ctx); status_parse(ctx);
status_render(ctx); status_render(ctx);
@ -355,6 +357,7 @@ uicb_status(Uicb cmd)
{ {
free(ib->statusctx.status); free(ib->statusctx.status);
ib->statusctx.status = xstrdup(p); ib->statusctx.status = xstrdup(p);
ib->statusctx.update = true;
infobar_elem_screen_update(s, ElemStatus); infobar_elem_screen_update(s, ElemStatus);
} }
} }

View File

@ -5,47 +5,57 @@
#include "wmfs.h" #include "wmfs.h"
#include "systray.h" #include "systray.h"
#include "ewmh.h"
#include "infobar.h"
bool #define SYSTRAY_SPACING (2)
void
systray_acquire(void) systray_acquire(void)
{ {
Window w = 0;
XSetWindowAttributes wattr = XSetWindowAttributes wattr =
{ {
.event_mask = ButtonPressMask | ExposureMask, .event_mask = ButtonPressMask | ExposureMask,
.override_redirect = true, .override_redirect = true,
.background_pixmap = ParentRelative, .background_pixmap = ParentRelative,
.background_pixel = 0 .background_pixel = W->systray.infobar->theme->bars.bg,
}; };
if(!(W->flags & WMFS_SYSTRAY) || W->systray.win) if(!(W->flags & WMFS_SYSTRAY) || W->systray.win)
return false; return;
if(XGetSelectionOwner(W->dpy, W->net_atom[net_system_tray_s]) != None) if(XGetSelectionOwner(W->dpy, W->net_atom[net_system_tray_s]) != None)
{ {
warnx("Can't initialize system tray: owned by another process."); warnx("Can't initialize system tray: owned by another process.");
return False; return;
} }
/* Init traywin window */ SLIST_INIT(&W->systray.head);
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);
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(); systray_freeicons();
warnx("System tray: can't get systray manager"); return;
return false;
} }
ewmh_send_message(W->root, W->root, "MANAGER", CurrentTime, 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 void
@ -60,16 +70,18 @@ systray_add(Window win)
s->win = win; s->win = win;
s->geo.h = W->systray.barwin->geo.h; 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); XSelectInput(W->dpy, s->win, StructureNotifyMask | PropertyChangeMask| EnterWindowMask | FocusChangeMask);
XReparentWindow(W->dpy, s->win, W->systray.win, 0, 0); XReparentWindow(W->dpy, s->win, W->systray.win, 0, 0);
ewmh_send_message(s->win, s->win, "_XEMBED", CurrentTime, 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); SLIST_INSERT_HEAD(&W->systray.head, s, next);
W->systray.redim = true;
} }
void void
@ -80,6 +92,8 @@ systray_del(struct _systray *s)
SLIST_REMOVE(&W->systray.head, s, _systray, next); SLIST_REMOVE(&W->systray.head, s, _systray, next);
free(s); free(s);
W->systray.redim = true;
} }
void void
@ -95,13 +109,13 @@ systray_state(struct _systray *s)
{ {
code = XEMBED_WINDOW_ACTIVATE; code = XEMBED_WINDOW_ACTIVATE;
XMapRaised(W->dpy, s->win); XMapRaised(W->dpy, s->win);
ewmh_set_win_state(s->win, NormalState); ewmh_set_wm_state(s->win, NormalState);
} }
else else
{ {
code = XEMBED_WINDOW_DEACTIVATE; code = XEMBED_WINDOW_DEACTIVATE;
XUnmapWindow(W->dpy, s->win); 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); 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); i = SLIST_FIRST(&W->systray.head);
SLIST_REMOVE_HEAD(&W->systray.head, next); SLIST_REMOVE_HEAD(&W->systray.head, next);
XUnmapWindow(dpy, i->win); XUnmapWindow(W->dpy, i->win);
XReparentWindow(dpy, i->win, W->root, 0, 0); XReparentWindow(W->dpy, i->win, W->root, 0, 0);
free(i); free(i);
} }
XSetSelectionOwner(W->dpy, W->net_atom[net_system_tray_s], None, CurrentTime); 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); XSync(W->dpy, false);
} }
@ -144,3 +159,43 @@ systray_find(Window win)
return NULL; 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;
}
}

View File

@ -8,11 +8,13 @@
#include "wmfs.h" #include "wmfs.h"
bool systray_acquire(void); void systray_acquire(void);
void systray_add(Window win); void systray_add(Window win);
void systray_del(struct _systray *s); void systray_del(struct _systray *s);
void systray_state(struct _systray *s); void systray_state(struct _systray *s);
void systray_freeicons(void); void systray_freeicons(void);
struct _systray *systray_find(Window win); struct _systray *systray_find(Window win);
int systray_get_width(void);
void systray_update(void);
#endif /* SYSTRAY_H */ #endif /* SYSTRAY_H */

View File

@ -101,6 +101,8 @@ tag_client(struct tag *t, struct client *c)
*/ */
SLIST_INSERT_HEAD(&t->clients, c, tnext); SLIST_INSERT_HEAD(&t->clients, c, tnext);
infobar_elem_screen_update(t->screen, ElemTag);
if(c->flags & CLIENT_IGNORE_LAYOUT) if(c->flags & CLIENT_IGNORE_LAYOUT)
c->flags ^= CLIENT_IGNORE_LAYOUT; c->flags ^= CLIENT_IGNORE_LAYOUT;
else if(!(c->flags & CLIENT_TABBED)) 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) if(t != c->screen->seltag || c->flags & CLIENT_TABBED)
client_unmap(c); client_unmap(c);
} }
void void

View File

@ -202,7 +202,7 @@ wmfs_scan(void)
int i, n, rf, nscreen = 0; int i, n, rf, nscreen = 0;
int tag = -1, screen = -1, flags = -1; int tag = -1, screen = -1, flags = -1;
unsigned long ir, il; unsigned long ir, il;
long *ret, *tret; long *ret = NULL, *tret;
bool getg = false; bool getg = false;
XWindowAttributes wa; XWindowAttributes wa;
Window usl, usl2, *w = NULL, tm, focus; Window usl, usl2, *w = NULL, tm, focus;

View File

@ -113,6 +113,7 @@ struct status_ctx
struct barwin *barwin; struct barwin *barwin;
struct theme *theme; struct theme *theme;
char *status; char *status;
bool update;
SLIST_HEAD(, status_seq) statushead; SLIST_HEAD(, status_seq) statushead;
}; };
@ -149,7 +150,6 @@ struct screen
struct geo geo, ugeo; struct geo geo, ugeo;
struct tag *seltag; struct tag *seltag;
int id; int id;
Flags elemupdate;
TAILQ_HEAD(tsub, tag) tags; TAILQ_HEAD(tsub, tag) tags;
SLIST_HEAD(, infobar) infobars; SLIST_HEAD(, infobar) infobars;
SLIST_ENTRY(screen) next; SLIST_ENTRY(screen) next;
@ -346,6 +346,8 @@ struct wmfs
struct struct
{ {
struct barwin *barwin; struct barwin *barwin;
struct infobar *infobar;
bool redim;
Window win; Window win;
SLIST_HEAD(, _systray) head; SLIST_HEAD(, _systray) head;
} systray; } systray;

7
wmfsrc
View File

@ -38,11 +38,11 @@
# Frame / Client # Frame / Client
client_normal_fg = "#AABBAA" client_normal_fg = "#AABBAA"
client_normal_bg = "#223322" 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_fg = "#223322"
client_sel_bg = "#AABBAA" 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" frame_bg = "#555555"
client_titlebar_width = 12 client_titlebar_width = 12
@ -64,11 +64,12 @@
# #
# t Tags # t Tags
# s Statustext (will take available space) # s Statustext (will take available space)
# y Systray (can be set only ONE time among all element)
[bar] [bar]
position = 0 position = 0
screen = 0 screen = 0
elements = "ts" # element order in bar elements = "tsy" # element order in bar
theme = "default" theme = "default"
[/bar] [/bar]