Merge branch 'master' into bacardi55
This commit is contained in:
55
src/client.c
55
src/client.c
@@ -340,6 +340,7 @@ client_above(Client *c)
|
||||
void
|
||||
client_focus(Client *c)
|
||||
{
|
||||
Client *cc;
|
||||
Window w;
|
||||
int d;
|
||||
|
||||
@@ -365,6 +366,14 @@ client_focus(Client *c)
|
||||
c->colors.frame = conf.client.borderfocus;
|
||||
c->colors.fg = conf.titlebar.fg_focus;
|
||||
c->colors.resizecorner = conf.client.resizecorner_focus;
|
||||
|
||||
/* Set focusontag option */
|
||||
for(cc = clients; cc; cc = cc->next)
|
||||
if(cc->focusontag == c->tag)
|
||||
cc->focusontag = -1;
|
||||
|
||||
c->focusontag = seltag[selscreen];
|
||||
|
||||
if(TBARH - BORDH && c->titlebar->stipple)
|
||||
c->titlebar->stipple_color = conf.titlebar.stipple.colors.focus;
|
||||
frame_update(c);
|
||||
@@ -616,7 +625,7 @@ client_map(Client *c)
|
||||
{
|
||||
CHECK(c);
|
||||
|
||||
if(c->flags & FSSFlag)
|
||||
if(c->flags & FSSFlag || c->flags & DockFlag)
|
||||
XMapWindow(dpy, c->win);
|
||||
else
|
||||
{
|
||||
@@ -689,10 +698,10 @@ client_manage(Window w, XWindowAttributes *wa, Bool ar)
|
||||
c->ogeo.height = c->geo.height = wa->height;
|
||||
c->free_geo = c->geo;
|
||||
c->tag = seltag[c->screen];
|
||||
c->focusontag = -1;
|
||||
|
||||
c->layer = (sel && sel->layer > 0) ? sel->layer : 1;
|
||||
|
||||
|
||||
at.event_mask = PropertyChangeMask;
|
||||
|
||||
frame_create(c);
|
||||
@@ -725,9 +734,9 @@ client_manage(Window w, XWindowAttributes *wa, Bool ar)
|
||||
client_raise(c);
|
||||
setwinstate(c->win, NormalState);
|
||||
ewmh_get_client_list();
|
||||
ewmh_manage_window_type(c);
|
||||
client_update_attributes(c);
|
||||
client_map(c);
|
||||
ewmh_manage_window_type(c);
|
||||
client_focus(c);
|
||||
|
||||
if(ar)
|
||||
@@ -833,8 +842,8 @@ client_moveresize(Client *c, XRectangle geo, Bool r)
|
||||
|
||||
XMoveResizeWindow(dpy, c->win, BORDH, TBARH, c->geo.width, c->geo.height);
|
||||
|
||||
client_configure(c);
|
||||
client_update_attributes(c);
|
||||
client_configure(c);
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -949,7 +958,7 @@ client_swap(Client *c1, Client *c2)
|
||||
CHECK(!(c1->flags & FreeFlag));
|
||||
CHECK(!(c2->flags & FreeFlag));
|
||||
|
||||
if(c1 == c2 || (c1->screen == c2->screen && c1->tag != c2->tag))
|
||||
if(c1 == c2)
|
||||
return;
|
||||
|
||||
/* Swap only the windows */
|
||||
@@ -1092,13 +1101,34 @@ client_unhide(Client *c)
|
||||
return;
|
||||
}
|
||||
|
||||
/** Select next or previous client to don't lose focus
|
||||
* \param c Client pointer
|
||||
*/
|
||||
void
|
||||
client_focus_next(Client *c)
|
||||
{
|
||||
Client *c_next = NULL;
|
||||
|
||||
for(c_next = clients;
|
||||
c_next && c_next != c->prev
|
||||
&& c_next->tag != c->tag
|
||||
&& c_next->screen != c->screen;
|
||||
c_next = c_next->next);
|
||||
|
||||
if(c_next && c_next->tag == seltag[selscreen]
|
||||
&& c_next->screen == selscreen)
|
||||
client_focus(c_next);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/** Unmanage a client
|
||||
* \param c Client pointer
|
||||
*/
|
||||
void
|
||||
client_unmanage(Client *c)
|
||||
{
|
||||
Client *c_next = NULL;
|
||||
Bool b = False;
|
||||
int i;
|
||||
|
||||
@@ -1122,7 +1152,7 @@ client_unmanage(Client *c)
|
||||
|
||||
/* Arrange */
|
||||
for(i = 0; i < screen_count() && !b; ++i)
|
||||
if(c->tag == seltag[i])
|
||||
if(c->tag == seltag[i] || tags[i][seltag[i]].tagad & TagFlag(c->tag))
|
||||
b = True;
|
||||
|
||||
if(b)
|
||||
@@ -1135,16 +1165,7 @@ client_unmanage(Client *c)
|
||||
|
||||
XFree(c->title);
|
||||
|
||||
/* To focus the previous client */
|
||||
for(c_next = clients;
|
||||
c_next && c_next != c->prev
|
||||
&& c_next->tag != c->tag
|
||||
&& c_next->screen != c->screen;
|
||||
c_next = c_next->next);
|
||||
|
||||
if(c_next && c_next->tag == seltag[selscreen]
|
||||
&& c_next->screen == selscreen)
|
||||
client_focus(c_next);
|
||||
client_focus_next(c);
|
||||
|
||||
free(c);
|
||||
|
||||
|
||||
34
src/config.c
34
src/config.c
@@ -182,8 +182,8 @@ conf_misc_section(void)
|
||||
void
|
||||
conf_bar_section(void)
|
||||
{
|
||||
struct conf_sec *bar, **mouse, *selbar;
|
||||
char *barbg;
|
||||
struct conf_sec *bar, **mouse, *selbar, *systray;
|
||||
char *barbg, sc = screen_count();
|
||||
|
||||
bar = fetch_section_first(NULL, "bar");
|
||||
|
||||
@@ -202,6 +202,20 @@ conf_bar_section(void)
|
||||
|
||||
free(mouse);
|
||||
|
||||
if((systray = fetch_section_first(bar, "systray")))
|
||||
{
|
||||
conf.systray.active = fetch_opt_first(systray, "true", "active").bool;
|
||||
|
||||
if((conf.systray.screen = fetch_opt_first(systray, "0", "screen").num) < 0
|
||||
|| conf.systray.screen >= sc)
|
||||
conf.systray.screen = 0;
|
||||
|
||||
if((conf.systray.spacing = fetch_opt_first(systray, "3", "spacing").num) < 0)
|
||||
conf.systray.spacing = 0;
|
||||
}
|
||||
else
|
||||
conf.systray.active = False;
|
||||
|
||||
selbar = fetch_section_first(bar, "selbar");
|
||||
conf.bars.selbar = selbar ? True : False;
|
||||
|
||||
@@ -462,28 +476,28 @@ conf_tag_section(void)
|
||||
conf.border.tag = fetch_opt_first(sec, "false", "border").bool;
|
||||
conf.tagautohide = fetch_opt_first(sec, "false", "autohide").bool;
|
||||
conf.tagnamecount = fetch_opt_first(sec, "false", "name_count").bool;
|
||||
|
||||
|
||||
|
||||
def_tag = fetch_section_first(sec, "default_tag");
|
||||
|
||||
position = fetch_opt_first(def_tag, "top", "infobar_position").str;
|
||||
if(!strcmp(position, "none")
|
||||
|| !strcmp(position, "hide")
|
||||
if(!strcmp(position, "none")
|
||||
|| !strcmp(position, "hide")
|
||||
|| !strcmp(position, "hidden"))
|
||||
bar_pos = IB_Hide;
|
||||
else if(!strcmp(position, "bottom")
|
||||
else if(!strcmp(position, "bottom")
|
||||
|| !strcmp(position, "down"))
|
||||
bar_pos = IB_Bottom;
|
||||
else
|
||||
bar_pos = IB_Top;
|
||||
|
||||
|
||||
/* If there is no tag in the conf or more than
|
||||
* MAXTAG (36) print an error and create only one.
|
||||
*/
|
||||
Tag default_tag = { fetch_opt_first(def_tag, "new tag", "name").str, NULL, 0, 1,
|
||||
fetch_opt_first(def_tag, "0.5", "mwfact").fnum,
|
||||
fetch_opt_first(def_tag, "1", "nmaster").num,
|
||||
False, fetch_opt_first(def_tag, "false", "resizehint").bool,
|
||||
fetch_opt_first(def_tag, "0.5", "mwfact").fnum,
|
||||
fetch_opt_first(def_tag, "1", "nmaster").num,
|
||||
False, fetch_opt_first(def_tag, "false", "resizehint").bool,
|
||||
False, False, bar_pos,
|
||||
layout_name_to_struct(conf.layout, fetch_opt_first(def_tag, "title_right", "layout").str, conf.nlayout, layout_list),
|
||||
0, NULL, 0 };
|
||||
|
||||
@@ -52,7 +52,7 @@ draw_text(Drawable d, int x, int y, char* fg, int pad, char *str)
|
||||
/* To draw image everywhere we can draw text */
|
||||
#ifdef HAVE_IMLIB
|
||||
char *ostr = NULL;
|
||||
int i, ni;
|
||||
int i, ni, sw = 0;
|
||||
ImageAttr im[128];
|
||||
|
||||
ostr = _strdup(str);
|
||||
@@ -61,8 +61,11 @@ draw_text(Drawable d, int x, int y, char* fg, int pad, char *str)
|
||||
{
|
||||
ni = parse_image_block(im, str);
|
||||
|
||||
if(infobar[conf.systray.screen].bar && d == infobar[conf.systray.screen].bar->dr)
|
||||
sw = systray_get_width();
|
||||
|
||||
for(i = 0; i < ni; ++i)
|
||||
draw_image(d, im[i].x, im[i].y, im[i].w, im[i].h, im[i].name);
|
||||
draw_image(d, im[i].x - sw, im[i].y, im[i].w, im[i].h, im[i].name);
|
||||
}
|
||||
#endif /* HAVE_IMLIB */
|
||||
|
||||
@@ -156,7 +159,7 @@ draw_image(Drawable dr, int x, int y, int w, int h, char *name)
|
||||
imlib_context_set_colormap(DefaultColormap(dpy, DefaultScreen(dpy)));
|
||||
imlib_context_set_drawable(dr);
|
||||
|
||||
image = imlib_load_image(name);
|
||||
image = imlib_load_image(patht(name));
|
||||
imlib_context_set_image(image);
|
||||
|
||||
if(w <= 0)
|
||||
|
||||
175
src/event.c
175
src/event.c
@@ -77,6 +77,7 @@ buttonpress(XButtonEvent *ev)
|
||||
if(ev->button == conf.client.mouse[i].button)
|
||||
if(conf.client.mouse[i].func)
|
||||
conf.client.mouse[i].func(conf.client.mouse[i].cmd);
|
||||
|
||||
/* Root */
|
||||
if(ev->window == ROOT)
|
||||
for(i = 0; i < conf.root.nmouse; ++i)
|
||||
@@ -162,6 +163,7 @@ void
|
||||
clientmessageevent(XClientMessageEvent *ev)
|
||||
{
|
||||
Client *c;
|
||||
Systray *sy;
|
||||
int s, i, mess_t = 0;
|
||||
Atom rt;
|
||||
int rf;
|
||||
@@ -195,8 +197,28 @@ clientmessageevent(XClientMessageEvent *ev)
|
||||
|
||||
/* Manage _NET_ACTIVE_WINDOW */
|
||||
else if(mess_t == net_active_window)
|
||||
{
|
||||
if((c = client_gb_win(ev->window)))
|
||||
client_focus(c);
|
||||
else if((sy = systray_find(ev->data.l[0])))
|
||||
XSetInputFocus(dpy, sy->win, RevertToNone, CurrentTime);
|
||||
}
|
||||
}
|
||||
else if(ev->window == traywin)
|
||||
{
|
||||
/* Manage _NET_WM_SYSTEM_TRAY_OPCODE */
|
||||
if(mess_t == net_wm_system_tray_opcode)
|
||||
{
|
||||
if(ev->data.l[1] == XEMBED_EMBEDDED_NOTIFY)
|
||||
{
|
||||
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])))
|
||||
ewmh_send_message(sy->win, sy->win, "_XEMBED",
|
||||
XEMBED_FOCUS_IN, XEMBED_FOCUS_CURRENT, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/* Manage _NET_WM_STATE */
|
||||
@@ -211,7 +233,7 @@ clientmessageevent(XClientMessageEvent *ev)
|
||||
|
||||
/* Manage _NET_WM_DESKTOP */
|
||||
if(mess_t == net_wm_desktop)
|
||||
if((c = client_gb_win(ev->window)))
|
||||
if((c = client_gb_win(ev->window)) && ev->data.l[0] != 0xFFFFFFFF)
|
||||
tag_transfert(c, ev->data.l[0]);
|
||||
|
||||
/* Manage _WMFS_STATUSTEXT_x */
|
||||
@@ -262,8 +284,8 @@ clientmessageevent(XClientMessageEvent *ev)
|
||||
return;
|
||||
}
|
||||
|
||||
/** ConfigureRequest & ConfigureNotify handle events
|
||||
* \param ev XEvent pointer
|
||||
/** ConfigureRequesthandle events
|
||||
* \param ev XConfigureRequestEvent pointer
|
||||
*/
|
||||
void
|
||||
configureevent(XConfigureRequestEvent *ev)
|
||||
@@ -275,7 +297,6 @@ configureevent(XConfigureRequestEvent *ev)
|
||||
if((c = client_gb_win(ev->window))
|
||||
|| (c = client_gb_win(ev->window)))
|
||||
{
|
||||
CHECK(!(c->flags & TileFlag));
|
||||
CHECK(!(c->flags & LMaxFlag));
|
||||
CHECK(!(c->flags & MaxFlag));
|
||||
CHECK(!(c->flags & FSSFlag));
|
||||
@@ -292,8 +313,13 @@ configureevent(XConfigureRequestEvent *ev)
|
||||
if(ev->value_mask & CWHeight)
|
||||
c->geo.height = ev->height;
|
||||
|
||||
if(c->flags & FreeFlag)
|
||||
if(c->flags & FreeFlag || !(c->flags & (TileFlag | LMaxFlag)))
|
||||
client_moveresize(c, c->geo, False);
|
||||
else
|
||||
{
|
||||
client_configure(c);
|
||||
arrange(c->screen, True);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -318,12 +344,19 @@ void
|
||||
destroynotify(XDestroyWindowEvent *ev)
|
||||
{
|
||||
Client *c;
|
||||
Systray *s;
|
||||
|
||||
if((c = client_gb_win(ev->window)))
|
||||
{
|
||||
client_unmanage(c);
|
||||
XSetErrorHandler(errorhandler);
|
||||
}
|
||||
else if((s = systray_find(ev->window)))
|
||||
{
|
||||
setwinstate(s->win, WithdrawnState);
|
||||
systray_del(s);
|
||||
systray_update();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -335,6 +368,7 @@ void
|
||||
enternotify(XCrossingEvent *ev)
|
||||
{
|
||||
Client *c;
|
||||
Systray *s;
|
||||
int n;
|
||||
|
||||
if((ev->mode != NotifyNormal
|
||||
@@ -342,6 +376,10 @@ enternotify(XCrossingEvent *ev)
|
||||
&& ev->window != ROOT)
|
||||
return;
|
||||
|
||||
/* Don't handle EnterNotify event if it's about systray */
|
||||
if((s = systray_find(ev->window)) || ev->window == traywin)
|
||||
return;
|
||||
|
||||
if(conf.focus_fmouse)
|
||||
{
|
||||
if((c = client_gb_win(ev->window))
|
||||
@@ -441,7 +479,7 @@ keypress(XKeyPressedEvent *ev)
|
||||
return;
|
||||
}
|
||||
|
||||
/** MapNotify handle event
|
||||
/** MappingNotify handle event
|
||||
* \param ev XMappingEvent pointer
|
||||
*/
|
||||
void
|
||||
@@ -455,6 +493,29 @@ mappingnotify(XMappingEvent *ev)
|
||||
return;
|
||||
}
|
||||
|
||||
/** MapNotify handle event
|
||||
* \param ev XMapEvent pointer
|
||||
*/
|
||||
void
|
||||
mapnotify(XMapEvent *ev)
|
||||
{
|
||||
Client *c;
|
||||
Systray *s;
|
||||
|
||||
if(ev->window != ev->event && !ev->send_event)
|
||||
return;
|
||||
|
||||
if((c = client_gb_win(ev->window)))
|
||||
setwinstate(c->win, NormalState);
|
||||
else if((s = systray_find(ev->window)))
|
||||
{
|
||||
setwinstate(s->win, NormalState);
|
||||
ewmh_send_message(s->win, s->win, "_XEMBED", CurrentTime, XEMBED_WINDOW_ACTIVATE, 0, 0, 0);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/** MapRequest handle event
|
||||
* \param ev XMapRequestEvent pointer
|
||||
*/
|
||||
@@ -463,11 +524,17 @@ maprequest(XMapRequestEvent *ev)
|
||||
{
|
||||
XWindowAttributes at;
|
||||
Client *c;
|
||||
Systray *s;
|
||||
|
||||
CHECK(XGetWindowAttributes(dpy, ev->window, &at));
|
||||
CHECK(!at.override_redirect);
|
||||
|
||||
if(!(c = client_gb_win(ev->window)))
|
||||
if((s = systray_find(ev->window)))
|
||||
{
|
||||
ewmh_send_message(s->win, s->win, "_XEMBED", CurrentTime, XEMBED_WINDOW_ACTIVATE, 0, 0, 0);
|
||||
systray_update();
|
||||
}
|
||||
else if(!(c = client_gb_win(ev->window)))
|
||||
client_manage(ev->window, &at, True);
|
||||
|
||||
return;
|
||||
@@ -480,12 +547,19 @@ void
|
||||
propertynotify(XPropertyEvent *ev)
|
||||
{
|
||||
Client *c;
|
||||
Systray *s;
|
||||
Window trans;
|
||||
XWMHints *h;
|
||||
|
||||
if(ev->state == PropertyDelete)
|
||||
return;
|
||||
|
||||
if((s = systray_find(ev->window)))
|
||||
{
|
||||
systray_state(s);
|
||||
systray_update();
|
||||
}
|
||||
|
||||
if((c = client_gb_win(ev->window)))
|
||||
{
|
||||
switch(ev->atom)
|
||||
@@ -494,7 +568,7 @@ propertynotify(XPropertyEvent *ev)
|
||||
XGetTransientForHint(dpy, c->win, &trans);
|
||||
if((c->flags & TileFlag || c->flags & MaxFlag))
|
||||
if(((c->flags & HintFlag && (client_gb_win(trans) != NULL)))
|
||||
|| (!(c->flags & HintFlag && (client_gb_win(trans) != NULL))))
|
||||
|| (!(c->flags & HintFlag && (client_gb_win(trans) != NULL))))
|
||||
arrange(c->screen, True);
|
||||
break;
|
||||
case XA_WM_NORMAL_HINTS:
|
||||
@@ -524,6 +598,33 @@ propertynotify(XPropertyEvent *ev)
|
||||
return;
|
||||
}
|
||||
|
||||
/** XReparentEvent handle event
|
||||
* \param ev XReparentEvent pointer
|
||||
*/
|
||||
void
|
||||
reparentnotify(XReparentEvent *ev)
|
||||
{
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/** SelectionClearEvent handle event
|
||||
* \param ev XSelectionClearEvent pointer
|
||||
*/
|
||||
void
|
||||
selectionclearevent(XSelectionClearEvent *ev)
|
||||
{
|
||||
/* Getting selection if lost it */
|
||||
if(ev->window == traywin)
|
||||
systray_acquire();
|
||||
|
||||
systray_update();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/** UnmapNotify handle event
|
||||
* \param ev XUnmapEvent pointer
|
||||
*/
|
||||
@@ -531,6 +632,7 @@ void
|
||||
unmapnotify(XUnmapEvent *ev)
|
||||
{
|
||||
Client *c;
|
||||
Systray *s;
|
||||
|
||||
if((c = client_gb_win(ev->window))
|
||||
&& ev->send_event
|
||||
@@ -540,31 +642,11 @@ unmapnotify(XUnmapEvent *ev)
|
||||
XSetErrorHandler(errorhandler);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/** Send a client event
|
||||
*\param data Event data
|
||||
*\param atom_name Event atom name
|
||||
*/
|
||||
void
|
||||
send_client_event(long data[5], char *atom_name)
|
||||
{
|
||||
XEvent ev;
|
||||
int i;
|
||||
|
||||
ev.xclient.type = ClientMessage;
|
||||
ev.xclient.serial = 0;
|
||||
ev.xclient.send_event = True;
|
||||
ev.xclient.message_type = ATOM(atom_name);
|
||||
ev.xclient.window = ROOT;
|
||||
ev.xclient.format = 32;
|
||||
|
||||
for(i = 0; i < 5; ++i, ev.xclient.data.l[i] = data[i]);
|
||||
|
||||
XSendEvent(dpy, ROOT, False, SubstructureRedirectMask | SubstructureNotifyMask, &ev);
|
||||
XSync(dpy, False);
|
||||
|
||||
if((s = systray_find(ev->window)))
|
||||
{
|
||||
systray_del(s);
|
||||
systray_update();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -579,18 +661,21 @@ getevent(XEvent ev)
|
||||
|
||||
switch(ev.type)
|
||||
{
|
||||
case ButtonPress: buttonpress(&ev.xbutton); break;
|
||||
case ClientMessage: clientmessageevent(&ev.xclient); break;
|
||||
case ConfigureRequest: configureevent(&ev.xconfigurerequest); break;
|
||||
case DestroyNotify: destroynotify(&ev.xdestroywindow); break;
|
||||
case EnterNotify: enternotify(&ev.xcrossing); break;
|
||||
case Expose: expose(&ev.xexpose); break;
|
||||
case FocusIn: focusin(&ev.xfocus); break;
|
||||
case KeyPress: keypress(&ev.xkey); break;
|
||||
case MapRequest: maprequest(&ev.xmaprequest); break;
|
||||
case MappingNotify: mappingnotify(&ev.xmapping); break;
|
||||
case PropertyNotify: propertynotify(&ev.xproperty); break;
|
||||
case UnmapNotify: unmapnotify(&ev.xunmap); break;
|
||||
case ButtonPress: buttonpress(&ev.xbutton); break;
|
||||
case ClientMessage: clientmessageevent(&ev.xclient); break;
|
||||
case ConfigureRequest: configureevent(&ev.xconfigurerequest); break;
|
||||
case DestroyNotify: destroynotify(&ev.xdestroywindow); break;
|
||||
case EnterNotify: enternotify(&ev.xcrossing); break;
|
||||
case Expose: expose(&ev.xexpose); break;
|
||||
case FocusIn: focusin(&ev.xfocus); break;
|
||||
case KeyPress: keypress(&ev.xkey); break;
|
||||
case MapNotify: mapnotify(&ev.xmap); break;
|
||||
case MapRequest: maprequest(&ev.xmaprequest); break;
|
||||
case MappingNotify: mappingnotify(&ev.xmapping); break;
|
||||
case PropertyNotify: propertynotify(&ev.xproperty); break;
|
||||
case ReparentNotify: reparentnotify(&ev.xreparent); break;
|
||||
case SelectionClear: selectionclearevent(&ev.xselectionclear); break;
|
||||
case UnmapNotify: unmapnotify(&ev.xunmap); break;
|
||||
default:
|
||||
|
||||
#ifdef HAVE_XRANDR
|
||||
|
||||
64
src/ewmh.c
64
src/ewmh.c
@@ -46,6 +46,8 @@ ewmh_init_hints(void)
|
||||
char root_name[] = WMFS_VERSION;
|
||||
char class[] = "wmfs", st[64];
|
||||
long pid = (long)getpid();
|
||||
char systray_atom[48];
|
||||
|
||||
|
||||
s = screen_count();
|
||||
net_atom = emalloc(net_last + s, sizeof(Atom));
|
||||
@@ -77,6 +79,17 @@ ewmh_init_hints(void)
|
||||
net_atom[net_wm_state_fullscreen] = ATOM("_NET_WM_STATE_FULLSCREEN");
|
||||
net_atom[net_wm_state_sticky] = ATOM("_NET_WM_STATE_STICKY");
|
||||
net_atom[net_wm_state_demands_attention] = ATOM("_NET_WM_STATE_DEMANDS_ATTENTION");
|
||||
net_atom[net_wm_system_tray_opcode] = ATOM("_NET_SYSTEM_TRAY_OPCODE");
|
||||
net_atom[net_system_tray_message_data] = ATOM("_NET_SYSTEM_TRAY_MESSAGE_DATA");
|
||||
net_atom[net_system_tray_visual] = ATOM("_NET_SYSTEM_TRAY_VISUAL");
|
||||
|
||||
snprintf(systray_atom, sizeof(systray_atom), "_NET_SYSTEM_TRAY_S%d", 0/*SCREEN*/);
|
||||
net_atom[net_system_tray_s] = ATOM(systray_atom);
|
||||
|
||||
net_atom[net_system_tray_orientation] = ATOM("_NET_SYSTEM_TRAY_ORIENTATION");
|
||||
net_atom[xembed] = ATOM("_XEMBED");
|
||||
net_atom[xembedinfo] = ATOM("_XEMBED_INFO");
|
||||
net_atom[manager] = ATOM("MANAGER");
|
||||
net_atom[utf8_string] = ATOM("UTF8_STRING");
|
||||
|
||||
/* WMFS hints */
|
||||
@@ -128,6 +141,54 @@ ewmh_init_hints(void)
|
||||
return;
|
||||
}
|
||||
|
||||
/** Send ewmh message
|
||||
*/
|
||||
void
|
||||
ewmh_send_message(Window d, Window w, char *atom, long d0, long d1, long d2, long d3, long d4)
|
||||
{
|
||||
|
||||
XClientMessageEvent e;
|
||||
|
||||
e.type = ClientMessage;
|
||||
e.message_type = ATOM(atom);
|
||||
e.window = w;
|
||||
e.format = 32;
|
||||
e.data.l[0] = d0;
|
||||
e.data.l[1] = d1;
|
||||
e.data.l[2] = d2;
|
||||
e.data.l[3] = d3;
|
||||
e.data.l[4] = d4;
|
||||
|
||||
XSendEvent(dpy, d, False, StructureNotifyMask, (XEvent*)&e);
|
||||
XSync(dpy, False);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/** Get xembed state
|
||||
*/
|
||||
long
|
||||
ewmh_get_xembed_state(Window win)
|
||||
{
|
||||
Atom rf;
|
||||
int f;
|
||||
ulong n, il;
|
||||
long ret = 0;
|
||||
uchar *data = NULL;
|
||||
|
||||
if(XGetWindowProperty(dpy, win, net_atom[xembedinfo], 0L, 2, False,
|
||||
net_atom[xembedinfo], &rf, &f, &n, &il, &data) != Success)
|
||||
return 0;
|
||||
|
||||
if(rf == net_atom[xembedinfo] && n == 2)
|
||||
ret = (long)data[1];
|
||||
|
||||
if(n && data)
|
||||
XFree(data);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/** Get the number of desktop (tag)
|
||||
*/
|
||||
void
|
||||
@@ -380,6 +441,8 @@ ewmh_manage_window_type(Client *c)
|
||||
/* Reparent it to ROOT win */
|
||||
XReparentWindow(dpy, c->win, ROOT, c->geo.x, c->geo.y);
|
||||
XRaiseWindow(dpy, c->win);
|
||||
|
||||
c->flags |= DockFlag;
|
||||
}
|
||||
/* MANAGE _NET_WM_WINDOW_TYPE_DIALOG */
|
||||
else if(atom[i] == net_atom[net_wm_window_type_dialog])
|
||||
@@ -406,7 +469,6 @@ ewmh_manage_window_type(Client *c)
|
||||
ldata[1] = atom[i];
|
||||
ewmh_manage_net_wm_state(ldata, c);
|
||||
}
|
||||
|
||||
XFree(data);
|
||||
}
|
||||
|
||||
|
||||
@@ -222,7 +222,8 @@ frame_update(Client *c)
|
||||
XClearWindow(dpy, c->button[i]);
|
||||
|
||||
if((!conf.titlebar.button[i].flags)
|
||||
|| ((conf.titlebar.button[i].flags & FreeFlag) && (c->flags & FreeFlag))
|
||||
|| ((conf.titlebar.button[i].flags & FreeFlag)
|
||||
&& ((c->flags & FreeFlag) || !(c->flags & (TileFlag | LMaxFlag))))
|
||||
|| ((conf.titlebar.button[i].flags & MaxFlag) && (c->flags & MaxFlag))
|
||||
|| ((conf.titlebar.button[i].flags & TileFlag) && (c->flags & TileFlag)))
|
||||
{
|
||||
|
||||
@@ -173,14 +173,10 @@ getinfo_nmaster(void)
|
||||
void
|
||||
getinfo(char *info)
|
||||
{
|
||||
long data[5];
|
||||
|
||||
if(!check_wmfs_running())
|
||||
return;
|
||||
|
||||
data[4] = True;
|
||||
|
||||
send_client_event(data, "_WMFS_UPDATE_HINTS");
|
||||
ewmh_send_message(ROOT, ROOT, "_WMFS_UPDATE_HINTS", 0, 0, 0, 0, True);
|
||||
|
||||
if(!strcmp(info, "tag"))
|
||||
getinfo_tag();
|
||||
|
||||
@@ -71,6 +71,7 @@ init(void)
|
||||
init_root();
|
||||
screen_init_geo();
|
||||
infobar_init();
|
||||
systray_acquire();
|
||||
init_status();
|
||||
ewmh_update_current_tag_prop();
|
||||
grabkeys();
|
||||
@@ -200,16 +201,16 @@ init_status(void)
|
||||
sprintf(conf.status_path, "%s/"DEF_STATUS, home);
|
||||
}
|
||||
|
||||
if (stat(conf.status_path, &st) == -1)
|
||||
if (stat(patht(conf.status_path), &st) == -1)
|
||||
{
|
||||
warn("%s", conf.status_path);
|
||||
warn("%s", patht(conf.status_path));
|
||||
return;
|
||||
}
|
||||
|
||||
if(st.st_size && st.st_mode & S_IXUSR)
|
||||
estatus = True;
|
||||
else
|
||||
warnx("status file specified in configuratin (status_path) or present in wmfs directory can't be executed, try 'chmod +x %s'.", conf.status_path);
|
||||
warnx("status file specified in configuratin (status_path) or present in wmfs directory can't be executed, try 'chmod +x %s'.", patht(conf.status_path));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -102,6 +102,8 @@ mouse_move_tag_client(Client *c)
|
||||
arrange(c->screen, True);
|
||||
}
|
||||
|
||||
client_focus_next(c);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -520,7 +520,7 @@ fetch_section_first(struct conf_sec *s, char *name)
|
||||
if (!s)
|
||||
{
|
||||
TAILQ_FOREACH(sec, &config, entry)
|
||||
if (!strcmp(sec->name, name)) {
|
||||
if(sec->name && !strcmp(sec->name, name)) {
|
||||
ret = sec;
|
||||
break;
|
||||
}
|
||||
@@ -528,7 +528,7 @@ fetch_section_first(struct conf_sec *s, char *name)
|
||||
else
|
||||
{
|
||||
TAILQ_FOREACH(sec, &s->sub, entry)
|
||||
if (!strcmp(sec->name, name)) {
|
||||
if (sec->name && !strcmp(sec->name, name)) {
|
||||
ret = sec;
|
||||
break;
|
||||
}
|
||||
|
||||
22
src/status.c
22
src/status.c
@@ -141,7 +141,10 @@ statustext_normal(int sc, char *str)
|
||||
char strwc[MAXSTATUS] = { 0 };
|
||||
char buf[MAXSTATUS] = { 0 };
|
||||
char col[8] = { 0 };
|
||||
int n, i, j, k;
|
||||
int n, i, j, k, sw = 0;
|
||||
|
||||
if(sc == conf.systray.screen)
|
||||
sw = systray_get_width();
|
||||
|
||||
for(i = j = n = 0; i < strlen(str); ++i, ++j)
|
||||
if(str[i] == '\\' && str[i + 1] == '#' && str[i + 8] == '\\')
|
||||
@@ -154,7 +157,7 @@ statustext_normal(int sc, char *str)
|
||||
strwc[j] = str[i];
|
||||
|
||||
/* Draw normal text without any blocks */
|
||||
draw_text(infobar[sc].bar->dr, (sgeo[sc].width - SHADH) - textw(strwc),
|
||||
draw_text(infobar[sc].bar->dr, (sgeo[sc].width - SHADH) - (textw(strwc) + sw),
|
||||
FHINFOBAR, infobar[sc].bar->fg, 0, strwc);
|
||||
|
||||
if(n)
|
||||
@@ -168,12 +171,12 @@ statustext_normal(int sc, char *str)
|
||||
for(j = 0, ++i; str[i] != '\\'; col[j++] = str[i++]);
|
||||
|
||||
/* Draw a rectangle with the bar color to draw the text properly */
|
||||
draw_rectangle(infobar[sc].bar->dr, (sgeo[sc].width - SHADH) - textw(&buf[k]),
|
||||
draw_rectangle(infobar[sc].bar->dr, (sgeo[sc].width - SHADH) - (textw(&buf[k]) + sw),
|
||||
0, INFOBARH - (sgeo[sc].width - SHADH) - textw(&buf[k]),
|
||||
INFOBARH, conf.colors.bar);
|
||||
|
||||
/* Draw text with its color */
|
||||
draw_text(infobar[sc].bar->dr, (sgeo[sc].width - SHADH) - textw(&buf[k]),
|
||||
draw_text(infobar[sc].bar->dr, (sgeo[sc].width - SHADH) - (textw(&buf[k]) + sw),
|
||||
FHINFOBAR, col, 0, &buf[k]);
|
||||
|
||||
strcpy(buf, strwc);
|
||||
@@ -192,7 +195,7 @@ void
|
||||
statustext_handle(int sc, char *str)
|
||||
{
|
||||
char *lastst;
|
||||
int i, nr, ng, ns, len;
|
||||
int i, nr, ng, ns, len, sw = 0;
|
||||
StatusRec r[128];
|
||||
StatusGraph g[128];
|
||||
StatusText s[128];
|
||||
@@ -201,6 +204,9 @@ statustext_handle(int sc, char *str)
|
||||
if(!str)
|
||||
return;
|
||||
|
||||
if(sc == conf.systray.screen)
|
||||
sw = systray_get_width();
|
||||
|
||||
barwin_refresh_color(infobar[sc].bar);
|
||||
|
||||
/* save last status text address (for free at the end) */
|
||||
@@ -219,15 +225,15 @@ statustext_handle(int sc, char *str)
|
||||
|
||||
/* Draw rectangles with stored properties. */
|
||||
for(i = 0; i < nr; ++i)
|
||||
draw_rectangle(infobar[sc].bar->dr, r[i].x, r[i].y, r[i].w, r[i].h, r[i].color);
|
||||
draw_rectangle(infobar[sc].bar->dr, r[i].x - sw, r[i].y, r[i].w, r[i].h, r[i].color);
|
||||
|
||||
/* Draw graphs with stored properties. */
|
||||
for(i = 0; i < ng; ++i)
|
||||
draw_graph(infobar[sc].bar->dr, g[i].x, g[i].y, g[i].w, g[i].h, g[i].color, g[i].data);
|
||||
draw_graph(infobar[sc].bar->dr, g[i].x - sw, g[i].y, g[i].w, g[i].h, g[i].color, g[i].data);
|
||||
|
||||
/* Draw located text with stored properties. */
|
||||
for(i = 0; i < ns; ++i)
|
||||
draw_text(infobar[sc].bar->dr, s[i].x, s[i].y, s[i].color, 0, s[i].text);
|
||||
draw_text(infobar[sc].bar->dr, s[i].x - sw, s[i].y, s[i].color, 0, s[i].text);
|
||||
|
||||
barwin_refresh(infobar[sc].bar);
|
||||
|
||||
|
||||
@@ -52,6 +52,7 @@
|
||||
#define AboveFlag (1 << 9)
|
||||
#define UrgentFlag (1 << 10)
|
||||
#define FLayFlag (1 << 11)
|
||||
#define DockFlag (1 << 12)
|
||||
|
||||
#define TagFlag(t) (1 << (t))
|
||||
|
||||
@@ -125,6 +126,14 @@ enum
|
||||
net_wm_state_fullscreen,
|
||||
net_wm_state_sticky,
|
||||
net_wm_state_demands_attention,
|
||||
net_wm_system_tray_opcode,
|
||||
net_system_tray_message_data,
|
||||
net_system_tray_s,
|
||||
net_system_tray_visual,
|
||||
net_system_tray_orientation,
|
||||
xembed,
|
||||
xembedinfo,
|
||||
manager,
|
||||
utf8_string,
|
||||
/* WMFS HINTS */
|
||||
wmfs_running,
|
||||
@@ -175,6 +184,7 @@ struct Client
|
||||
char *title;
|
||||
/* Tag num */
|
||||
uint tag;
|
||||
int focusontag;
|
||||
/* Screen */
|
||||
int screen;
|
||||
/* Layer */
|
||||
@@ -252,6 +262,15 @@ typedef struct
|
||||
void (*func)(int screen);
|
||||
} Layout;
|
||||
|
||||
/* Systray Structure */
|
||||
typedef struct Systray Systray;
|
||||
struct Systray
|
||||
{
|
||||
Window win;
|
||||
XRectangle geo;
|
||||
Systray *next, *prev;
|
||||
};
|
||||
|
||||
/* Tag Structure */
|
||||
typedef struct
|
||||
{
|
||||
@@ -430,6 +449,12 @@ typedef struct
|
||||
Bool tag;
|
||||
Bool layout;
|
||||
} border;
|
||||
struct
|
||||
{
|
||||
Bool active;
|
||||
int screen;
|
||||
int spacing;
|
||||
} systray;
|
||||
Alias alias[256];
|
||||
uint mouse_tag_action[TagActionLast];
|
||||
Layout layout[NUM_OF_LAYOUT];
|
||||
@@ -500,4 +525,10 @@ typedef struct
|
||||
char *uicb;
|
||||
} vicmd_to_uicb;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int version;
|
||||
int flags;
|
||||
} xembed_info;
|
||||
|
||||
#endif /* STRUCTS_H */
|
||||
|
||||
200
src/systray.c
200
src/systray.c
@@ -32,3 +32,203 @@
|
||||
|
||||
#include "wmfs.h"
|
||||
|
||||
#define TRAY_DWIDTH (infobar[conf.systray.screen].bar->geo.height + conf.systray.spacing)
|
||||
|
||||
Bool
|
||||
systray_acquire(void)
|
||||
{
|
||||
XSetWindowAttributes wattr;
|
||||
|
||||
if(!conf.systray.active || traywin)
|
||||
return False;
|
||||
|
||||
if(XGetSelectionOwner(dpy, net_atom[net_system_tray_s]) != None)
|
||||
{
|
||||
warnx("Can't initialize system tray: owned by another process");
|
||||
return False;
|
||||
}
|
||||
|
||||
/* Init traywin window */
|
||||
wattr.event_mask = ButtonPressMask | ExposureMask;
|
||||
wattr.override_redirect = True;
|
||||
wattr.background_pixmap = ParentRelative;
|
||||
wattr.background_pixel = conf.colors.bar;
|
||||
|
||||
traywin = XCreateSimpleWindow(dpy, infobar[conf.systray.screen].bar->win, -1, -1, 1, 1, 0, 0, conf.colors.bar);
|
||||
|
||||
XChangeWindowAttributes(dpy, traywin, CWEventMask | CWOverrideRedirect | CWBackPixel, &wattr);
|
||||
XSelectInput(dpy, traywin, KeyPressMask | ButtonPressMask);
|
||||
|
||||
XMapRaised(dpy, traywin);
|
||||
|
||||
XSetSelectionOwner(dpy, net_atom[net_system_tray_s], traywin, CurrentTime);
|
||||
|
||||
if(XGetSelectionOwner(dpy, net_atom[net_system_tray_s]) != traywin)
|
||||
{
|
||||
systray_freeicons();
|
||||
warnx("System tray: can't get systray manager");
|
||||
return False;
|
||||
}
|
||||
|
||||
ewmh_send_message(ROOT, ROOT, "MANAGER", CurrentTime, net_atom[net_system_tray_s], traywin, 0, 0);
|
||||
|
||||
XSync(dpy, False);
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
void
|
||||
systray_add(Window win)
|
||||
{
|
||||
Systray *s;
|
||||
|
||||
if(!conf.systray.active)
|
||||
return;
|
||||
|
||||
s = emalloc(1, sizeof(Systray));
|
||||
s->win = win;
|
||||
|
||||
s->geo.height = infobar[conf.systray.screen].bar->geo.height;
|
||||
s->geo.width = TRAY_DWIDTH;
|
||||
|
||||
setwinstate(s->win, WithdrawnState);
|
||||
XSelectInput(dpy, s->win, StructureNotifyMask | PropertyChangeMask| EnterWindowMask | FocusChangeMask);
|
||||
XReparentWindow(dpy, s->win, traywin, 0, 0);
|
||||
|
||||
ewmh_send_message(s->win, s->win, "_XEMBED", CurrentTime, XEMBED_EMBEDDED_NOTIFY, 0, traywin, 0);
|
||||
|
||||
/* Attach */
|
||||
if(trayicons)
|
||||
trayicons->prev = s;
|
||||
|
||||
s->next = trayicons;
|
||||
trayicons = s;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
systray_del(Systray *s)
|
||||
{
|
||||
Systray **ss;
|
||||
|
||||
if(!conf.systray.active)
|
||||
return;
|
||||
|
||||
for(ss = &trayicons; *ss && *ss != s; ss = &(*ss)->next);
|
||||
*ss = s->next;
|
||||
|
||||
IFREE(s);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
systray_state(Systray *s)
|
||||
{
|
||||
long flags;
|
||||
int code = 0;
|
||||
|
||||
if(!(flags = ewmh_get_xembed_state(s->win)) || !conf.systray.active)
|
||||
return;
|
||||
|
||||
if(flags & XEMBED_MAPPED)
|
||||
{
|
||||
code = XEMBED_WINDOW_ACTIVATE;
|
||||
XMapRaised(dpy, s->win);
|
||||
setwinstate(s->win, NormalState);
|
||||
}
|
||||
else
|
||||
{
|
||||
code = XEMBED_WINDOW_DEACTIVATE;
|
||||
XUnmapWindow(dpy, s->win);
|
||||
setwinstate(s->win, WithdrawnState);
|
||||
}
|
||||
|
||||
ewmh_send_message(s->win, s->win, "_XEMBED", CurrentTime, code, 0, 0, 0);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
systray_freeicons(void)
|
||||
{
|
||||
Systray *i;
|
||||
|
||||
if(!conf.systray.active)
|
||||
return;
|
||||
|
||||
for(i = trayicons; i; i = i->next)
|
||||
{
|
||||
XUnmapWindow(dpy, i->win);
|
||||
XReparentWindow(dpy, i->win, ROOT, 0, 0);
|
||||
IFREE(i);
|
||||
}
|
||||
|
||||
XSetSelectionOwner(dpy, net_atom[net_system_tray_s], None, CurrentTime);
|
||||
XDestroyWindow(dpy, traywin);
|
||||
|
||||
XSync(dpy, 0);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
Systray*
|
||||
systray_find(Window win)
|
||||
{
|
||||
Systray *i;
|
||||
|
||||
if(!conf.systray.active)
|
||||
return NULL;
|
||||
|
||||
for(i = trayicons; i; i = i->next)
|
||||
if(i->win == win)
|
||||
return i;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int
|
||||
systray_get_width(void)
|
||||
{
|
||||
int w = 0;
|
||||
Systray *i;
|
||||
|
||||
if(!conf.systray.active)
|
||||
return 0;
|
||||
|
||||
for(i = trayicons; i; i = i->next)
|
||||
w += i->geo.width + conf.systray.spacing + 1;
|
||||
|
||||
return w;
|
||||
}
|
||||
|
||||
void
|
||||
systray_update(void)
|
||||
{
|
||||
Systray *i;
|
||||
int x = 1;
|
||||
|
||||
if(!conf.systray.active)
|
||||
return;
|
||||
|
||||
if(!trayicons)
|
||||
{
|
||||
XMoveResizeWindow(dpy, traywin, infobar[conf.systray.screen].bar->geo.width - 1, 0, 1, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
for(i = trayicons; i; i = i->next)
|
||||
{
|
||||
XMapWindow(dpy, i->win);
|
||||
|
||||
XMoveResizeWindow(dpy, i->win, (i->geo.x = x), 0, i->geo.width, i->geo.height);
|
||||
|
||||
x += i->geo.width + conf.systray.spacing;
|
||||
}
|
||||
|
||||
XMoveResizeWindow(dpy, traywin, infobar[conf.systray.screen].bar->geo.width - x,
|
||||
0, x, infobar[conf.systray.screen].bar->geo.height);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
22
src/tag.c
22
src/tag.c
@@ -42,6 +42,9 @@ tag_set(int tag)
|
||||
Bool al = False;
|
||||
int i;
|
||||
|
||||
if(tag < 0 || tag > MAXTAG)
|
||||
return;
|
||||
|
||||
screen_get_sel();
|
||||
|
||||
prevseltag[selscreen] = seltag[selscreen];
|
||||
@@ -102,11 +105,17 @@ tag_set(int tag)
|
||||
tags[selscreen][tag].request_update = False;
|
||||
}
|
||||
|
||||
/* To focus the first client in the new tag */
|
||||
/* To focus selected client of the via focusontag option */
|
||||
for(c = clients; c; c = c->next)
|
||||
if(c->tag == seltag[selscreen] && c->screen == selscreen)
|
||||
if(c->focusontag == tag && c->screen == selscreen)
|
||||
break;
|
||||
|
||||
/* No focusontag option found on any client, try to find the first of the tag */
|
||||
if(!c)
|
||||
for(c = clients; c; c = c->next)
|
||||
if(c->tag == seltag[selscreen] && c->screen == selscreen)
|
||||
break;
|
||||
|
||||
client_focus((c) ? c : NULL);
|
||||
|
||||
return;
|
||||
@@ -123,7 +132,7 @@ tag_transfert(Client *c, int tag)
|
||||
|
||||
CHECK(c);
|
||||
|
||||
if(!tag)
|
||||
if(tag <= 0)
|
||||
tag = 1;
|
||||
|
||||
if(tag > conf.ntag[selscreen])
|
||||
@@ -134,8 +143,7 @@ tag_transfert(Client *c, int tag)
|
||||
|
||||
arrange(c->screen, True);
|
||||
|
||||
if(c == sel && c->tag != tag)
|
||||
client_focus(NULL);
|
||||
client_focus_next(c);
|
||||
|
||||
client_update_attributes(c);
|
||||
|
||||
@@ -502,9 +510,9 @@ tag_new(int s, char *name)
|
||||
displayedName = name;
|
||||
|
||||
Tag t = { displayedName, NULL, 0, 0,
|
||||
conf.default_tag.mwfact, conf.default_tag.nmaster,
|
||||
conf.default_tag.mwfact, conf.default_tag.nmaster,
|
||||
False, conf.default_tag.resizehint, False, False,
|
||||
conf.default_tag.barpos, conf.default_tag.layout,
|
||||
conf.default_tag.barpos, conf.default_tag.layout,
|
||||
0, NULL, 0 };
|
||||
|
||||
|
||||
|
||||
16
src/util.c
16
src/util.c
@@ -340,3 +340,19 @@ clean_value(char *str)
|
||||
return p;
|
||||
}
|
||||
|
||||
/* To use ~/ shortcut.. */
|
||||
char*
|
||||
patht(char *path)
|
||||
{
|
||||
static char ret[512];
|
||||
|
||||
if(!path)
|
||||
return NULL;
|
||||
|
||||
strcpy(ret, path);
|
||||
|
||||
if(strstr(path, "~/"))
|
||||
sprintf(ret, "%s/%s", getenv("HOME"), path + 2);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
35
src/wmfs.c
35
src/wmfs.c
@@ -92,6 +92,8 @@ quit(void)
|
||||
IFREE(tags);
|
||||
IFREE(seltag);
|
||||
|
||||
systray_freeicons();
|
||||
|
||||
XftFontClose(dpy, font);
|
||||
for(i = 0; i < CurLast; ++i)
|
||||
XFreeCursor(dpy, cursor[i]);
|
||||
@@ -214,26 +216,27 @@ scan(void)
|
||||
|
||||
if(XQueryTree(dpy, ROOT, &usl, &usl2, &w, &n))
|
||||
for(i = n - 1; i != -1; --i)
|
||||
if(XGetWindowAttributes(dpy, w[i], &wa)
|
||||
&& !(wa.override_redirect || XGetTransientForHint(dpy, w[i], &usl))
|
||||
&& wa.map_state == IsViewable)
|
||||
{
|
||||
XGetWindowAttributes(dpy, w[i], &wa);
|
||||
|
||||
if(!wa.override_redirect && wa.map_state == IsViewable)
|
||||
{
|
||||
if(XGetWindowProperty(dpy, w[i], ATOM("_WMFS_TAG"), 0, 32,
|
||||
False, XA_CARDINAL, &rt, &rf, &ir, &il, &ret) == Success && ret)
|
||||
False, XA_CARDINAL, &rt, &rf, &ir, &il, &ret) == Success && ret)
|
||||
{
|
||||
tag = *ret;
|
||||
XFree(ret);
|
||||
}
|
||||
|
||||
if(XGetWindowProperty(dpy, w[i], ATOM("_WMFS_SCREEN"), 0, 32,
|
||||
False, XA_CARDINAL, &rt, &rf, &ir, &il, &ret) == Success && ret)
|
||||
False, XA_CARDINAL, &rt, &rf, &ir, &il, &ret) == Success && ret)
|
||||
{
|
||||
screen = *ret;
|
||||
XFree(ret);
|
||||
}
|
||||
|
||||
if(XGetWindowProperty(dpy, w[i], ATOM("_WMFS_ISFREE"), 0, 32,
|
||||
False, XA_CARDINAL, &rt, &rf, &ir, &il, &ret) == Success && ret)
|
||||
False, XA_CARDINAL, &rt, &rf, &ir, &il, &ret) == Success && ret)
|
||||
{
|
||||
free = *ret;
|
||||
XFree(ret);
|
||||
@@ -250,6 +253,7 @@ scan(void)
|
||||
|
||||
client_update_attributes(c);
|
||||
}
|
||||
}
|
||||
|
||||
/* Set update layout request */
|
||||
for(c = clients; c; c = c->next)
|
||||
@@ -319,15 +323,11 @@ check_wmfs_running(void)
|
||||
void
|
||||
exec_uicb_function(char *func, char *cmd)
|
||||
{
|
||||
long data[5];
|
||||
|
||||
/* Check if wmfs is running (this function is executed when wmfs
|
||||
is already running normally...) */
|
||||
if(!check_wmfs_running())
|
||||
return;
|
||||
|
||||
data[4] = True;
|
||||
|
||||
XChangeProperty(dpy, ROOT, ATOM("_WMFS_FUNCTION"), ATOM("UTF8_STRING"),
|
||||
8, PropModeReplace, (uchar*)func, strlen(func));
|
||||
|
||||
@@ -337,7 +337,7 @@ exec_uicb_function(char *func, char *cmd)
|
||||
XChangeProperty(dpy, ROOT, ATOM("_WMFS_CMD"), ATOM("UTF8_STRING"),
|
||||
8, PropModeReplace, (uchar*)cmd, strlen(cmd));
|
||||
|
||||
send_client_event(data, "_WMFS_FUNCTION");
|
||||
ewmh_send_message(ROOT, ROOT, "_WMFS_FUNCTION", 0, 0, 0, 0, True);
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -349,11 +349,8 @@ void
|
||||
set_statustext(int s, char *str)
|
||||
{
|
||||
int i;
|
||||
long data[5];
|
||||
char atom_name[64];
|
||||
|
||||
data[4] = True;
|
||||
|
||||
if(!str)
|
||||
return;
|
||||
|
||||
@@ -366,7 +363,7 @@ set_statustext(int s, char *str)
|
||||
XChangeProperty(dpy, ROOT, ATOM(atom_name), ATOM("UTF8_STRING"),
|
||||
8, PropModeReplace, (uchar*)str, strlen(str));
|
||||
|
||||
send_client_event(data, atom_name);
|
||||
ewmh_send_message(ROOT, ROOT, atom_name, 0, 0, 0, 0, True);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -376,7 +373,7 @@ set_statustext(int s, char *str)
|
||||
XChangeProperty(dpy, ROOT, ATOM(atom_name), ATOM("UTF8_STRING"),
|
||||
8, PropModeReplace, (uchar*)str, strlen(str));
|
||||
|
||||
send_client_event(data, atom_name);
|
||||
ewmh_send_message(ROOT, ROOT, atom_name, 0, 0, 0, 0, True);
|
||||
}
|
||||
|
||||
return;
|
||||
@@ -387,14 +384,10 @@ set_statustext(int s, char *str)
|
||||
void
|
||||
update_status(void)
|
||||
{
|
||||
long data[5];
|
||||
|
||||
if(!check_wmfs_running())
|
||||
return;
|
||||
|
||||
data[4] = True;
|
||||
|
||||
send_client_event(data, "_WMFS_UPDATE_STATUS");
|
||||
ewmh_send_message(ROOT, ROOT, "_WMFS_UPDATE_STATUS", 0, 0, 0, 0, True);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
22
src/wmfs.h
22
src/wmfs.h
@@ -185,6 +185,7 @@ void client_size_hints(Client *c);
|
||||
void client_swap(Client *c1, Client *c2);
|
||||
void client_raise(Client *c);
|
||||
void client_unhide(Client *c);
|
||||
void client_focus_next(Client *c);
|
||||
void client_unmanage(Client *c);
|
||||
void client_unmap(Client *c);
|
||||
void client_set_rules(Client *c);
|
||||
@@ -211,6 +212,8 @@ void uicb_client_ignore_tag(uicb_t);
|
||||
|
||||
/* ewmh.c */
|
||||
void ewmh_init_hints(void);
|
||||
void ewmh_send_message(Window d, Window w, char *atom, long d0, long d1, long d2, long d3, long d4);
|
||||
long ewmh_get_xembed_state(Window win);
|
||||
void ewmh_get_number_of_desktop(void);
|
||||
void ewmh_update_current_tag_prop(void);
|
||||
void ewmh_get_client_list(void);
|
||||
@@ -240,10 +243,12 @@ void focusin(XFocusChangeEvent *ev);
|
||||
void grabkeys(void);
|
||||
void keypress(XKeyPressedEvent *ev);
|
||||
void mappingnotify(XMappingEvent *ev);
|
||||
void mapnotify(XMapEvent *ev);
|
||||
void maprequest(XMapRequestEvent *ev);
|
||||
void reparentnotify(XReparentEvent *ev);
|
||||
void selectionclearevent(XSelectionClearEvent *ev);
|
||||
void propertynotify(XPropertyEvent *ev);
|
||||
void unmapnotify(XUnmapEvent *ev);
|
||||
void send_client_event(long data[5], char *atom_name);
|
||||
void getevent(XEvent ev);
|
||||
|
||||
/* menu.c */
|
||||
@@ -291,6 +296,8 @@ int spawn(const char *str, ...);
|
||||
void swap_ptr(void **x, void **y);
|
||||
void uicb_spawn(uicb_t);
|
||||
char *clean_value(char *str);
|
||||
char* patht(char *path);
|
||||
|
||||
|
||||
#ifdef HAVE_IMLIB
|
||||
int parse_image_block(ImageAttr *im, char *str);
|
||||
@@ -341,7 +348,14 @@ void statustext_normal(int sc, char *str);
|
||||
void statustext_handle(int sc, char *str);
|
||||
|
||||
/* systray.c */
|
||||
|
||||
Bool systray_acquire(void);
|
||||
void systray_add(Window win);
|
||||
void systray_del(Systray *s);
|
||||
void systray_state(Systray *s);
|
||||
void systray_freeicons(void);
|
||||
Systray* systray_find(Window win);
|
||||
int systray_get_width(void);
|
||||
void systray_update(void);
|
||||
|
||||
/* layout.c */
|
||||
void arrange(int screen, Bool update_layout);
|
||||
@@ -435,6 +449,7 @@ XftFont *font;
|
||||
|
||||
/* Atoms list */
|
||||
Atom *net_atom;
|
||||
Atom trayatom;
|
||||
|
||||
/* InfoBar/Tags */
|
||||
InfoBar *infobar;
|
||||
@@ -458,6 +473,9 @@ Client *sel;
|
||||
func_name_list_t *func_list;
|
||||
extern const func_name_list_t layout_list[];
|
||||
uint numlockmask;
|
||||
Systray *trayicons;
|
||||
Window traywin;
|
||||
int tray_width;
|
||||
|
||||
#endif /* WMFS_H */
|
||||
|
||||
|
||||
Reference in New Issue
Block a user