implemented different version of updategeom

keyboard
Anselm R Garbe 15 years ago
parent f0a4845e7d
commit 07ad298133
  1. 8
      config.mk
  2. 224
      dwm.c

@ -20,10 +20,10 @@ LIBS = -L/usr/lib -lc -L${X11LIB} -lX11 ${XINERAMALIBS}
# flags # flags
CPPFLAGS = -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} CPPFLAGS = -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS}
#CFLAGS = -g -std=c99 -pedantic -Wall -O0 ${INCS} ${CPPFLAGS} CFLAGS = -g -std=c99 -pedantic -Wall -O0 ${INCS} ${CPPFLAGS}
CFLAGS = -std=c99 -pedantic -Wall -Os ${INCS} ${CPPFLAGS} #CFLAGS = -std=c99 -pedantic -Wall -Os ${INCS} ${CPPFLAGS}
#LDFLAGS = -g ${LIBS} LDFLAGS = -g ${LIBS}
LDFLAGS = -s ${LIBS} #LDFLAGS = -s ${LIBS}
# Solaris # Solaris
#CFLAGS = -fast ${INCS} -DVERSION=\"${VERSION}\" #CFLAGS = -fast ${INCS} -DVERSION=\"${VERSION}\"

224
dwm.c

@ -163,6 +163,7 @@ static void clearurgent(Client *c);
static void configure(Client *c); static void configure(Client *c);
static void configurenotify(XEvent *e); static void configurenotify(XEvent *e);
static void configurerequest(XEvent *e); static void configurerequest(XEvent *e);
static Monitor *createmon(void);
static void destroynotify(XEvent *e); static void destroynotify(XEvent *e);
static void detach(Client *c); static void detach(Client *c);
static void detachstack(Client *c); static void detachstack(Client *c);
@ -592,6 +593,22 @@ configurerequest(XEvent *e) {
XSync(dpy, False); XSync(dpy, False);
} }
Monitor *
createmon(void) {
Monitor *m;
if(!(m = (Monitor *)calloc(1, sizeof(Monitor))))
die("fatal: could not malloc() %u bytes\n", sizeof(Monitor));
m->tagset[0] = m->tagset[1] = 1;
m->mfact = mfact;
m->showbar = showbar;
m->topbar = topbar;
m->lt[0] = &layouts[0];
m->lt[1] = &layouts[1 % LENGTH(layouts)];
m->ltsymbol = layouts[0].symbol;
return m;
}
void void
destroynotify(XEvent *e) { destroynotify(XEvent *e) {
Client *c; Client *c;
@ -1005,6 +1022,19 @@ isprotodel(Client *c) {
return ret; return ret;
} }
#ifdef XINERAMA
static Bool
isuniquegeom(XineramaScreenInfo *unique, size_t len, XineramaScreenInfo *info) {
unsigned int i;
for(i = 0; i < len; i++)
if(unique[i].x_org == info->x_org && unique[i].y_org == info->y_org
&& unique[i].width == info->width && unique[i].height == info->height)
return False;
return True;
}
#endif /* XINERAMA */
void void
keypress(XEvent *e) { keypress(XEvent *e) {
unsigned int i; unsigned int i;
@ -1695,165 +1725,71 @@ updatebarpos(Monitor *m) {
Bool Bool
updategeom(void) { updategeom(void) {
int i, j, nn = 1, n = 1; Bool dirty = False;
Client *c;
Monitor *newmons = NULL, *m = NULL, *tm;
/* TODO:
* This function needs to be seriously re-designed:
*
* #ifdef XINERAMA
* 1. Determine number of already existing monitors n
* 2. Determine number of monitors Xinerama reports nn
* 3. if(n <= nn) {
* if(n < nn) {
* append nn-n monitors to current struct
* flag dirty
* }
* for(i = 0; i < nn; i++) {
* if(oldgeom != newgeom) {
* apply newgeom;
* flag dirty;
* }
* }
* }
* else {
* detach all clients
* destroy current monitor struct
* create new monitor struct
* attach all clients to first monitor
* flag dirty;
* }
* return dirty flag to caller
* if dirty is seen by caller:
* re-arrange bars/pixmaps
* arrange()
* #else
* don't share between XINERAMA and non-XINERAMA handling if it gets
* too ugly
* #endif
*/
#ifdef XINERAMA #ifdef XINERAMA
XineramaScreenInfo *info = NULL; if(XineramaIsActive(dpy)) {
Bool *flags = NULL; int i, j, n, nn;
Monitor *m;
if(XineramaIsActive(dpy)) XineramaScreenInfo *info = XineramaQueryScreens(dpy, &nn);
info = XineramaQueryScreens(dpy, &n); XineramaScreenInfo *unique = NULL;
flags = (Bool *)malloc(sizeof(Bool) * n);
for(i = 0; i < n; i++) info = XineramaQueryScreens(dpy, &nn);
flags[i] = False; for(n = 0, m = mons; m; m = m->next, n++);
/* next double-loop seeks any combination of retrieved Xinerama info /* only consider unique geometries as separate screens */
* with existing monitors, this is used to avoid unnecessary if(!(unique = (XineramaScreenInfo *)malloc(sizeof(XineramaScreenInfo) * nn)))
* re-allocations of monitor structs */ die("fatal: could not malloc() %u bytes\n", sizeof(XineramaScreenInfo) * nn);
for(i = 0, nn = n; i < n; i++) for(i = 0, j = 0; i < nn; i++)
for(j = 0, m = mons; m; m = m->next, j++) if(isuniquegeom(unique, j, &info[i]))
if(!flags[j]) { memcpy(&unique[j++], &info[i], sizeof(XineramaScreenInfo));
if((flags[j] = (
info[i].x_org == m->mx
&& info[i].y_org == m->my
&& info[i].width == m->mw
&& info[i].height == m->mh)
))
--nn;
}
if(nn == 0) { /* no need to re-allocate monitors */
j = 0;
for(i = 0, m = mons; m; m = m->next, i++) {
m->num = info[i].screen_number;
if(info[i].x_org != m->mx
|| info[i].y_org != m->my
|| info[i].width != m->mw
|| info[i].height != m->mh)
{
m->mx = m->wx = info[i].x_org;
m->my = m->wy = info[i].y_org;
m->mw = m->ww = info[i].width;
m->mh = m->wh = info[i].height;
updatebarpos(m);
j++;
}
}
XFree(info); XFree(info);
free(flags); nn = j;
return j > 0; if(n <= nn) {
} for(i = 0; i < (nn - n); i++) { /* new monitors available */
/* next algorithm only considers unique geometries as separate screens */ for(m = mons; m && m->next; m = m->next);
for(i = 0; i < n; i++) if(m)
flags[i] = False; /* used for ignoring certain monitors */ m->next = createmon();
for(i = 0, nn = n; i < n; i++) else
for(j = 0; j < n; j++) mons = createmon();
if(i != j && !flags[i]) {
if((flags[i] = (
info[i].x_org == info[j].x_org
&& info[i].y_org == info[j].y_org
&& info[i].width == info[j].width
&& info[i].height == info[j].height)
))
--nn;
} }
#endif /* XINERAMA */ for(i = 0, m = mons; i < nn && m; m = m->next, i++)
/* allocate monitor(s) for the new geometry setup */ if(i >= n
for(i = 0; i < nn; i++) { || (unique[i].x_org != m->mx || unique[i].y_org != m->my
if(!(m = (Monitor *)malloc(sizeof(Monitor)))) || unique[i].width != m->mw || unique[i].height != m->mh))
die("fatal: could not malloc() %u bytes\n", sizeof(Monitor)); {
m->next = newmons; dirty = True;
newmons = m; m->num = unique[i].screen_number;
m->mx = m->wx = unique[i].x_org;
m->my = m->wy = unique[i].y_org;
m->mw = m->ww = unique[i].width;
m->mh = m->wh = unique[i].height;
updatebarpos(m);
} }
/* initialise monitor(s) */
#ifdef XINERAMA
if(XineramaIsActive(dpy)) {
for(i = 0, m = newmons; m && i < n; i++) {
if(!flags[i]) { /* only use screens that aren't dublettes */
m->num = info[i].screen_number;
m->mx = m->wx = info[i].x_org;
m->my = m->wy = info[i].y_org;
m->mw = m->ww = info[i].width;
m->mh = m->wh = info[i].height;
m = m->next;
} }
else { /* less monitors available */
cleanup();
setup();
} }
XFree(info); free(unique);
free(flags);
} }
else else
#endif /* XINERAMA */ #endif /* XINERAMA */
/* default monitor setup */ /* default monitor setup */
{ {
m->num = 0; if(!mons)
m->mx = m->wx = 0; mons = createmon();
m->my = m->wy = 0; if(mons->mw != sw || mons->mh != sh) {
m->mw = m->ww = sw; dirty = True;
m->mh = m->wh = sh; mons->mw = mons->ww = sw;
} mons->mh = mons->wh = sh;
/* bar geometry setup */ updatebarpos(mons);
for(m = newmons; m; m = m->next) {
m->sel = m->stack = m->clients = NULL;
m->seltags = 0;
m->sellt = 0;
m->tagset[0] = m->tagset[1] = 1;
m->mfact = mfact;
m->showbar = showbar;
m->topbar = topbar;
m->lt[0] = &layouts[0];
m->lt[1] = &layouts[1 % LENGTH(layouts)];
m->ltsymbol = layouts[0].symbol;
updatebarpos(m);
} }
/* reassign left over clients of disappeared monitors */
for(tm = mons; tm; tm = tm->next)
while(tm->clients) {
c = tm->clients;
tm->clients = c->next;
detachstack(c);
c->mon = newmons;
attach(c);
attachstack(c);
} }
/* select focused monitor */ if(dirty) {
cleanupmons(); selmon = mons;
selmon = mons = newmons;
selmon = wintomon(root); selmon = wintomon(root);
return True; }
return dirty;
} }
void void

Loading…
Cancel
Save