-/* © 2006-2007 Anselm R. Garbe <garbeam at gmail dot com>
- * © 2006-2007 Sander van Dijk <a dot h dot vandijk at gmail dot com>
- * © 2007 Premysl Hruby <dfenze at gmail dot com>
- * © 2007 Szabolcs Nagy <nszabolcs at gmail dot com>
- * See LICENSE file for license details. */
+/* See LICENSE file for copyright and license details. */
#include "dwm.h"
#include <stdlib.h>
#include <string.h>
/* static */
+static char prop[128];
+
static void
attachstack(Client *c) {
c->snext = stack;
clients = c;
}
+void
+ban(Client *c) {
+ if(c->isbanned)
+ return;
+ XUnmapWindow(dpy, c->win);
+ setclientstate(c, IconicState);
+ c->isbanned = True;
+ c->unmapped++;
+}
+
void
configure(Client *c) {
XConfigureEvent ce;
void
focus(Client *c) {
- if( !c && selscreen || c && !isvisible(c))
+ if((!c && selscreen) || (c && !isvisible(c)))
for(c = stack; c && !isvisible(c); c = c->snext);
if(sel && sel != c) {
grabbuttons(sel, False);
XKillClient(dpy, sel->win);
}
+Bool
+getprops(Client *c) {
+ unsigned int i;
+ Bool result = False;
+
+ if(gettextprop(c->win, dwmprops, prop, sizeof prop)) {
+ for(i = 0; i < ntags && i < sizeof prop - 1 && prop[i] != '\0'; i++)
+ if((c->tags[i] = prop[i] == '1'))
+ result = True;
+ if(i < sizeof prop - 1 && prop[i] != '\0')
+ c->isfloating = prop[i] == '1';
+ }
+ return result;
+}
+
void
manage(Window w, XWindowAttributes *wa) {
+ unsigned int i;
Client *c, *t = NULL;
Window trans;
Status rettrans;
updatetitle(c);
if((rettrans = XGetTransientForHint(dpy, w, &trans) == Success))
for(t = clients; t && t->win != trans; t = t->next);
- settags(c, t);
+ if(t)
+ for(i = 0; i < ntags; i++)
+ c->tags[i] = t->tags[i];
+ if(!getprops(c))
+ applyrules(c);
if(!c->isfloating)
c->isfloating = (rettrans == Success) || c->isfixed;
+ setprops(c);
attach(c);
attachstack(c);
- c->isbanned = True;
- XMoveWindow(dpy, w, c->x + 2 * sw, c->y);
- XMapWindow(dpy, w);
- setclientstate(c, NormalState);
- focus(c);
- lt->arrange();
+ XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h); /* some windows require this */
+ ban(c);
+ arrange();
}
void
resize(Client *c, int x, int y, int w, int h, Bool sizehints) {
- float dx, dy, max, min, ratio;
- XWindowChanges wc;
+ double dx, dy, max, min, ratio;
+ XWindowChanges wc;
- if(w <= 0 || h <= 0)
- return;
if(sizehints) {
- if(c->minay > 0 && c->maxay > 0 && (h - c->baseh) > 0) {
- dx = (float)(w - c->basew);
- dy = (float)(h - c->baseh);
- min = (float)(c->minax) / (float)(c->minay);
- max = (float)(c->maxax) / (float)(c->maxay);
+ if(c->minay > 0 && c->maxay > 0 && (h - c->baseh) > 0 && (w - c->basew) > 0) {
+ dx = (double)(w - c->basew);
+ dy = (double)(h - c->baseh);
+ min = (double)(c->minax) / (double)(c->minay);
+ max = (double)(c->maxax) / (double)(c->maxay);
ratio = dx / dy;
if(max > 0 && min > 0 && ratio > 0) {
if(ratio < min) {
}
void
-togglefloating(const char *arg) {
- if(!sel || lt->arrange == floating)
+setprops(Client *c) {
+ unsigned int i;
+
+ for(i = 0; i < ntags && i < sizeof prop - 1; i++)
+ prop[i] = c->tags[i] ? '1' : '0';
+ if(i < sizeof prop - 1)
+ prop[i++] = c->isfloating ? '1' : '0';
+ prop[i] = '\0';
+ XChangeProperty(dpy, c->win, dwmprops, XA_STRING, 8,
+ PropModeReplace, (unsigned char *)prop, i);
+}
+
+void
+unban(Client *c) {
+ if(!c->isbanned)
return;
- sel->isfloating = !sel->isfloating;
- if(sel->isfloating)
- resize(sel, sel->x, sel->y, sel->w, sel->h, True);
- lt->arrange();
+ XMapWindow(dpy, c->win);
+ setclientstate(c, NormalState);
+ c->isbanned = False;
+}
+
+void
+unmanage(Client *c, long state) {
+ XWindowChanges wc;
+
+ wc.border_width = c->oldborder;
+ /* The server grab construct avoids race conditions. */
+ XGrabServer(dpy);
+ XSetErrorHandler(xerrordummy);
+ XConfigureWindow(dpy, c->win, CWBorderWidth, &wc); /* restore border */
+ detach(c);
+ detachstack(c);
+ if(sel == c)
+ focus(NULL);
+ XUngrabButton(dpy, AnyButton, AnyModifier, c->win);
+ setclientstate(c, state);
+ free(c->tags);
+ free(c);
+ XSync(dpy, False);
+ XSetErrorHandler(xerror);
+ XUngrabServer(dpy);
+ if(state != NormalState)
+ arrange();
}
void
void
updatetitle(Client *c) {
- char **list = NULL;
- int n;
- XTextProperty name;
-
- name.nitems = 0;
- c->name[0] = 0;
- XGetTextProperty(dpy, c->win, &name, netatom[NetWMName]);
- if(!name.nitems)
- XGetWMName(dpy, c->win, &name);
- if(!name.nitems)
- return;
- if(name.encoding == XA_STRING)
- strncpy(c->name, (char *)name.value, sizeof c->name - 1);
- else {
- if(XmbTextPropertyToTextList(dpy, &name, &list, &n) >= Success
- && n > 0 && *list)
- {
- strncpy(c->name, *list, sizeof c->name - 1);
- XFreeStringList(list);
- }
- }
- c->name[sizeof c->name - 1] = '\0';
- XFree(name.value);
-}
-
-void
-unmanage(Client *c) {
- XWindowChanges wc;
-
- wc.border_width = c->oldborder;
- /* The server grab construct avoids race conditions. */
- XGrabServer(dpy);
- XSetErrorHandler(xerrordummy);
- XConfigureWindow(dpy, c->win, CWBorderWidth, &wc); /* restore border */
- detach(c);
- detachstack(c);
- if(sel == c)
- focus(NULL);
- XUngrabButton(dpy, AnyButton, AnyModifier, c->win);
- setclientstate(c, WithdrawnState);
- free(c->tags);
- free(c);
- XSync(dpy, False);
- XSetErrorHandler(xerror);
- XUngrabServer(dpy);
- lt->arrange();
+ if(!gettextprop(c->win, netatom[NetWMName], c->name, sizeof c->name))
+ gettextprop(c->win, wmatom[WMName], c->name, sizeof c->name);
}