! NEW SYSTRAY ! systray element as 'y', element dynamic size
This commit is contained in:
parent
f8dedf7231
commit
2eba3ccc64
@ -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
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -17,6 +17,7 @@
|
||||
#include "status.h"
|
||||
#include "mouse.h"
|
||||
#include "screen.h"
|
||||
#include "infobar.h"
|
||||
|
||||
#define THEME_DEFAULT (SLIST_FIRST(&W->h.theme))
|
||||
|
||||
|
||||
52
src/event.c
52
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
|
||||
|
||||
14
src/ewmh.c
14
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,
|
||||
|
||||
@ -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,
|
||||
|
||||
187
src/infobar.c
187
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);
|
||||
|
||||
|
||||
@ -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*
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
113
src/systray.c
113
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@ -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 */
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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
7
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]
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user