! 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/fifo.c \
src/status.c \
src/systray.c \
src/mouse.c \
src/log.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_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);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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 */

View File

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

View File

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

View File

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

7
wmfsrc
View File

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