implemented different version of updategeom
This commit is contained in:
parent
f0a4845e7d
commit
07ad298133
@ -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}\"
|
||||||
|
234
dwm.c
234
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
|
|
||||||
XineramaScreenInfo *info = NULL;
|
|
||||||
Bool *flags = NULL;
|
|
||||||
|
|
||||||
if(XineramaIsActive(dpy))
|
|
||||||
info = XineramaQueryScreens(dpy, &n);
|
|
||||||
flags = (Bool *)malloc(sizeof(Bool) * n);
|
|
||||||
for(i = 0; i < n; i++)
|
|
||||||
flags[i] = False;
|
|
||||||
/* next double-loop seeks any combination of retrieved Xinerama info
|
|
||||||
* with existing monitors, this is used to avoid unnecessary
|
|
||||||
* re-allocations of monitor structs */
|
|
||||||
for(i = 0, nn = n; i < n; i++)
|
|
||||||
for(j = 0, m = mons; m; m = m->next, j++)
|
|
||||||
if(!flags[j]) {
|
|
||||||
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);
|
|
||||||
free(flags);
|
|
||||||
return j > 0;
|
|
||||||
}
|
|
||||||
/* next algorithm only considers unique geometries as separate screens */
|
|
||||||
for(i = 0; i < n; i++)
|
|
||||||
flags[i] = False; /* used for ignoring certain monitors */
|
|
||||||
for(i = 0, nn = n; i < n; i++)
|
|
||||||
for(j = 0; j < n; j++)
|
|
||||||
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 */
|
|
||||||
/* allocate monitor(s) for the new geometry setup */
|
|
||||||
for(i = 0; i < nn; i++) {
|
|
||||||
if(!(m = (Monitor *)malloc(sizeof(Monitor))))
|
|
||||||
die("fatal: could not malloc() %u bytes\n", sizeof(Monitor));
|
|
||||||
m->next = newmons;
|
|
||||||
newmons = m;
|
|
||||||
}
|
|
||||||
/* initialise monitor(s) */
|
|
||||||
#ifdef XINERAMA
|
#ifdef XINERAMA
|
||||||
if(XineramaIsActive(dpy)) {
|
if(XineramaIsActive(dpy)) {
|
||||||
for(i = 0, m = newmons; m && i < n; i++) {
|
int i, j, n, nn;
|
||||||
if(!flags[i]) { /* only use screens that aren't dublettes */
|
Monitor *m;
|
||||||
m->num = info[i].screen_number;
|
XineramaScreenInfo *info = XineramaQueryScreens(dpy, &nn);
|
||||||
m->mx = m->wx = info[i].x_org;
|
XineramaScreenInfo *unique = NULL;
|
||||||
m->my = m->wy = info[i].y_org;
|
|
||||||
m->mw = m->ww = info[i].width;
|
info = XineramaQueryScreens(dpy, &nn);
|
||||||
m->mh = m->wh = info[i].height;
|
for(n = 0, m = mons; m; m = m->next, n++);
|
||||||
m = m->next;
|
/* only consider unique geometries as separate screens */
|
||||||
}
|
if(!(unique = (XineramaScreenInfo *)malloc(sizeof(XineramaScreenInfo) * nn)))
|
||||||
}
|
die("fatal: could not malloc() %u bytes\n", sizeof(XineramaScreenInfo) * nn);
|
||||||
|
for(i = 0, j = 0; i < nn; i++)
|
||||||
|
if(isuniquegeom(unique, j, &info[i]))
|
||||||
|
memcpy(&unique[j++], &info[i], sizeof(XineramaScreenInfo));
|
||||||
XFree(info);
|
XFree(info);
|
||||||
free(flags);
|
nn = j;
|
||||||
|
if(n <= nn) {
|
||||||
|
for(i = 0; i < (nn - n); i++) { /* new monitors available */
|
||||||
|
for(m = mons; m && m->next; m = m->next);
|
||||||
|
if(m)
|
||||||
|
m->next = createmon();
|
||||||
|
else
|
||||||
|
mons = createmon();
|
||||||
|
}
|
||||||
|
for(i = 0, m = mons; i < nn && m; m = m->next, i++)
|
||||||
|
if(i >= n
|
||||||
|
|| (unique[i].x_org != m->mx || unique[i].y_org != m->my
|
||||||
|
|| unique[i].width != m->mw || unique[i].height != m->mh))
|
||||||
|
{
|
||||||
|
dirty = True;
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else { /* less monitors available */
|
||||||
|
cleanup();
|
||||||
|
setup();
|
||||||
|
}
|
||||||
|
free(unique);
|
||||||
}
|
}
|
||||||
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 */
|
}
|
||||||
cleanupmons();
|
if(dirty) {
|
||||||
selmon = mons = newmons;
|
selmon = mons;
|
||||||
selmon = wintomon(root);
|
selmon = wintomon(root);
|
||||||
return True;
|
}
|
||||||
|
return dirty;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
Loading…
Reference in New Issue
Block a user