#define ALLMASK (ShiftMask | ControlMask | ALLMODMASK)
#define CLEANMASK(mask) (mask & ~(numlockmask|LockMask) & ALLMASK)
#define ISVISIBLE(C) ((C->workspace->viewer))
-#define LENGTH(X) (sizeof X / sizeof X[0])
+#define LENGTH(X) (sizeof(X) / sizeof(X[0]))
#ifndef MAX
#define MAX(A, B) ((A) > (B) ? (A) : (B))
#endif
PalSelected,
PalNotSelected,
PalOther,
+ PalIndicator,
PalLast
};
struct monitor {
char ltsymbol[16];
int num;
- int by;
struct rect geom;
struct rect win_geom;
- unsigned int sellt;
- unsigned int tagset[2];
struct workspace *workspace;
struct workspace *previous_workspace;
struct monitor *next;
- Window barwin;
- const struct layout *lt[2];
+ Window statusbar;
+ struct client_indicator *h_clind;
+ struct client_indicator *v_clind;
+ const struct layout *layout;
};
struct workspace {
int v;
};
+#define CI_VERTICAL 0
+#define CI_HORIZONTAL 1
+
+struct client_indicator {
+ struct rect geom;
+ Window win;
+ XftDraw *draw;
+ GC gc;
+ struct monitor *monitor;
+ int orientation;
+};
+
+static struct client_indicator* client_indicator_new(struct monitor *monitor, int orientation);
+static void client_indicator_free(struct client_indicator **indicator);
+static void client_indicator_update_geometry(struct client_indicator *ci);
+static void client_indicator_update(struct client_indicator *ci);
+static void client_indicator_set_visible(struct client_indicator *ci, int visible);
+static void client_indicator_resize(struct client_indicator *ci);
+
#define KBPTR_CENTER 0
#define KBPTR_NORTH (1 << 1)
#define KBPTR_EAST (1 << 2)
static void monitor_focus(struct monitor *mon);
static void monitor_free(struct monitor *mon);
static int monitor_is_floating(struct monitor *mon);
-static void monitor_resize_barwin(struct monitor *m);
+static void monitor_resize_statusbar(struct monitor *m);
+static void monitor_update_geometry(struct monitor *mon, int x, int y, int w, int h);
static void client_move_to_workspace(struct client *client, struct workspace *workspace);
static void client_configure(struct client *c);
static void configurenotify(XEvent *e);
static void configurerequest(XEvent *e);
-static struct monitor *createmon(void);
+static struct monitor *monitor_new(int num, int x, int y, int w, int h);
+static struct monitor *monitor_get(int num);
static void destroynotify(XEvent *e);
static void die(const char *errstr, ...);
static struct monitor *dirtomon(int dir);
char limitexceeded[LENGTH(tags) > 31 ? -1 : 1];
};
+static void client_indicator_update(struct client_indicator *ci)
+{
+ struct client *focused;
+
+ XCopyArea(dpy, root, ci->win, ci->gc,
+ ci->geom.x, ci->geom.y,
+ ci->geom.w, ci->geom.h,
+ 0, 0);
+
+ focused = ci->monitor->workspace->focused;
+
+ if(focused) {
+ int x, y, w, h;
+
+ if(ci->orientation == CI_HORIZONTAL) {
+ x = focused->geom.x - ci->geom.x;
+ y = clind_padding;
+ w = focused->geom.w + 2 * borderpx;
+ h = clind_height - clind_padding;
+ } else {
+ x = 0;
+ y = focused->geom.y - ci->geom.y;
+ w = clind_height - clind_padding;
+ h = focused->geom.h + 2 * borderpx;
+ }
+
+ XSetForeground(dpy, ci->gc, dc.palette[PalIndicator].color[ColBG]);
+ XFillRectangle(dpy, ci->win, ci->gc,
+ x, y, w, h);
+
+ XSetForeground(dpy, ci->gc, dc.palette[PalIndicator].color[ColFG]);
+ XDrawRectangle(dpy, ci->win, ci->gc,
+ x, y, w - 1, h - 1);
+ }
+
+ XSync(dpy, False);
+
+ return;
+}
+
+static void client_indicator_update_geometry(struct client_indicator *ci)
+{
+ if(ci->orientation == CI_HORIZONTAL) {
+ ci->geom.x = ci->monitor->geom.x;
+ ci->geom.y = ci->monitor->geom.y + bar_height;
+ ci->geom.w = ci->monitor->geom.w;
+ ci->geom.h = clind_height;
+ } else {
+ ci->geom.x = ci->monitor->geom.x + ci->monitor->geom.w - clind_height;
+ ci->geom.y = ci->monitor->geom.y + bar_height;
+ ci->geom.w = clind_height;
+ ci->geom.h = ci->monitor->geom.h - bar_height;
+ }
+
+ return;
+}
+
+static struct client_indicator* client_indicator_new(struct monitor *monitor, int orientation)
+{
+ struct client_indicator *ci;
+ unsigned long mask;
+ XSetWindowAttributes attrs;
+ int depth;
+ Visual *visual;
+
+ memset(&attrs, 0, sizeof(attrs));
+
+ attrs.override_redirect = True;
+ attrs.background_pixmap = ParentRelative;
+ attrs.event_mask = ButtonPressMask | ExposureMask;
+ mask = CWOverrideRedirect | CWBackPixmap | CWEventMask;
+ depth = DefaultDepth(dpy, screen);
+ visual = DefaultVisual(dpy, screen);
+
+ ci = malloc(sizeof(*ci));
+
+ if(ci) {
+ memset(ci, 0, sizeof(*ci));
+
+ ci->orientation = orientation;
+ ci->monitor = monitor;
+
+ client_indicator_update_geometry(ci);
+
+ printf("XCreateWindow(dpy, rppt, %d, %d, %d, %d, ...)\n",
+ ci->geom.x, ci->geom.y, ci->geom.w, ci->geom.h);
+ ci->win = XCreateWindow(dpy, root,
+ ci->geom.x, ci->geom.y, ci->geom.w, ci->geom.h, 0,
+ depth, CopyFromParent, visual,
+ mask, &attrs);
+ XSync(dpy, False);
+
+ ci->gc = XCreateGC(dpy, root, 0, NULL);
+ XSetLineAttributes(dpy, ci->gc, 1, LineSolid, CapButt, JoinMiter);
+
+ XDefineCursor(dpy, ci->win, cursor[CurNormal]);
+ }
+
+ return(ci);
+}
+
+static void client_indicator_free(struct client_indicator **indicator)
+{
+ if(!indicator || !*indicator) {
+ return;
+ }
+
+ XUnmapWindow(dpy, (*indicator)->win);
+ XDestroyWindow(dpy, (*indicator)->win);
+
+ free(*indicator);
+ *indicator = NULL;
+
+ return;
+}
+
+static void client_indicator_set_visible(struct client_indicator *ci, int visible)
+{
+#ifdef DEBUG_D
+ printf("client_indicator_set_visible(%s, %d)\n",
+ ci == ci->monitor->v_clind ? "v_clind" : "h_clind", visible);
+#endif
+
+ if(ci) {
+ if(visible) {
+ XMapRaised(dpy, ci->win);
+ } else {
+ XUnmapWindow(dpy, ci->win);
+ }
+ }
+
+ return;
+}
+
+static void client_indicator_resize(struct client_indicator *ci)
+{
+ ci->geom.x = ci->monitor->geom.x;
+ ci->geom.y = ci->monitor->geom.y + bar_height;
+ ci->geom.w = ci->monitor->geom.w;
+ ci->geom.h = clind_height;
+
+ XMoveResizeWindow(dpy, ci->win, ci->geom.x, ci->geom.y, ci->geom.w, ci->geom.h);
+ return;
+}
+
static int rule_match(struct rule const *rule, XClassHint *class_hint, const char *client_name)
{
const char *class, *instance;
void monitor_arrange_clients(struct monitor *monitor)
{
strncpy(monitor->ltsymbol,
- monitor->lt[monitor->sellt]->symbol,
+ monitor->layout->symbol,
sizeof(monitor->ltsymbol));
if(!monitor_is_floating(monitor)) {
- monitor->lt[monitor->sellt]->arrange(monitor);
+ monitor->layout->arrange(monitor);
}
restack(monitor);
monitor_focus(event_monitor);
}
- if(ev->window == selmon->barwin) {
+ if(ev->window == selmon->statusbar) {
i = 0;
x = 0;
foo.arrange = NULL;
show_workspace(&a);
- selmon->lt[selmon->sellt] = &foo;
+ selmon->layout = &foo;
for(i = 0; i < LENGTH(workspaces); i++) {
while(workspaces[i].clients) {
}
XftDrawDestroy(dc.draw);
+
g_object_unref(dc.font.layout);
XFreeGC(dpy, dc.gc);
XFreeCursor(dpy, cursor[CurNormal]);
}
}
- XUnmapWindow(dpy, mon->barwin);
- XDestroyWindow(dpy, mon->barwin);
+ client_indicator_free(&(mon->v_clind));
+ client_indicator_free(&(mon->h_clind));
+
+ XUnmapWindow(dpy, mon->statusbar);
+ XDestroyWindow(dpy, mon->statusbar);
free(mon);
num_monitors--;
void configurenotify(XEvent *e)
{
- struct monitor *m;
XConfigureEvent *ev = &e->xconfigure;
Bool dirty;
if(ev->window == root) {
- dirty = (screen_width != ev->width);
+ dirty = screen_width != ev->width ||
+ screen_height != ev->height;
screen_width = ev->width;
screen_height = ev->height;
if(updategeom() || dirty) {
+ struct monitor *mon;
+
if(dc.drawable != 0) {
XFreePixmap(dpy, dc.drawable);
}
dc.drawable = XCreatePixmap(dpy, root, screen_width, bar_height,
DefaultDepth(dpy, screen));
+
XftDrawChange(dc.draw, dc.drawable);
+
updatebars();
- for(m = mons; m; m = m->next) {
- monitor_resize_barwin(m);
+ for(mon = mons; mon; mon = mon->next) {
+ monitor_resize_statusbar(mon);
+
+ if(mon->v_clind && mon->h_clind) {
+ client_indicator_resize(mon->v_clind);
+ client_indicator_resize(mon->h_clind);
+ }
}
focus(NULL);
return;
}
-struct monitor *createmon(void)
+static struct monitor *monitor_new(int num, int x, int y, int w, int h)
{
struct monitor *m;
int i;
- m = (struct monitor *)calloc(1, sizeof(*m));
+ m = (struct monitor*)calloc(1, sizeof(*m));
if(!m) {
die("fatal: could not malloc() %u bytes\n", sizeof(*m));
}
- m->tagset[0] = 1;
- m->tagset[1] = 1;
- m->lt[0] = &layouts[0];
- m->lt[1] = &layouts[1 % LENGTH(layouts)];
+ m->layout = &layouts[0];
+ strncpy(m->ltsymbol, layouts[0].symbol, sizeof(m->ltsymbol));
+
+ monitor_update_geometry(m, x, y, w, h);
+ m->num = num;
+
+ m->h_clind = client_indicator_new(m, CI_HORIZONTAL);
+ m->v_clind = client_indicator_new(m, CI_VERTICAL);
+
+ if(!m->h_clind || !m->v_clind) {
+ die("fatal: could not allocate memory\n");
+ }
for(i = 0; i < LENGTH(workspaces); i++) {
if(!workspaces[i].viewer) {
}
}
- strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol);
+ if(!selmon) {
+ selmon = m;
+ }
+
num_monitors++;
return(m);
}
+static struct monitor *monitor_get(int num)
+{
+ struct monitor *mon;
+
+ for(mon = mons; mon; mon = mon->next) {
+ if(mon->num == num) {
+ break;
+ }
+ }
+
+ return(mon);
+}
+
void destroynotify(XEvent *e)
{
struct client *c;
unsigned int i;
int x;
- monitor_resize_barwin(m);
+ monitor_resize_statusbar(m);
wipe_bar(m, m == selmon ? PalSelected : PalNormal);
focused = selmon->workspace->focused;
drawtext(stext, PalNormal, False);
- XCopyArea(dpy, dc.drawable, m->barwin, dc.gc, 0, 0,
+ XCopyArea(dpy, dc.drawable, m->statusbar, dc.gc, 0, 0,
m->win_geom.w, bar_height, 0, 0);
XSync(dpy, False);
grabbuttons(c, True);
XSetWindowBorder(dpy, c->win, dc.palette[PalSelected].color[ColBorder]);
+
setfocus(c);
} else {
XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime);
}
selmon->workspace->focused = c;
+ client_indicator_update(selmon->h_clind);
+ client_indicator_update(selmon->v_clind);
drawbars();
return;
req = xatom[XembedInfo];
}
- if(XGetWindowProperty(dpy, c->win, prop, 0L, sizeof atom, False, req,
+ if(XGetWindowProperty(dpy, c->win, prop, 0L, sizeof(atom), False, req,
&da, &di, &dl, &dl, &p) == Success && p) {
atom = *(Atom *)p;
return;
}
-#ifdef XINERAMA
-static Bool isuniquegeom(XineramaScreenInfo *unique, size_t n,
- XineramaScreenInfo *info)
-{
- while(n--) {
- if(unique[n].x_org == info->x_org &&
- unique[n].y_org == info->y_org &&
- unique[n].width == info->width &&
- unique[n].height == info->height) {
- return(False);
- }
- }
-
- return(True);
-}
-#endif /* XINERAMA */
-
void keypress(XEvent *e)
{
unsigned int i;
c->geom.x = MAX(c->geom.x, mon->geom.x);
/* only fix client y-offset, if the client center might cover the bar */
- c->geom.y = MAX(c->geom.y, (mon->by == mon->geom.y &&
+ c->geom.y = MAX(c->geom.y, (mon->win_geom.y == mon->geom.y &&
(c->geom.x + (c->geom.w / 2) >= mon->win_geom.x) &&
(c->geom.x + (c->geom.w / 2) < mon->win_geom.x +
mon->win_geom.w)) ? bar_height : mon->geom.y);
}
if(n > 0) { /* override layout symbol */
- snprintf(m->ltsymbol, sizeof m->ltsymbol, "[%d]", n);
+ snprintf(m->ltsymbol, sizeof(m->ltsymbol), "[%d]", n);
}
for(c = nexttiled(m->workspace->clients); c; c = nexttiled(c->next)) {
return;
}
-void monitor_resize_barwin(struct monitor *m)
+void monitor_resize_statusbar(struct monitor *m)
{
- XMoveResizeWindow(dpy, m->barwin, m->win_geom.x, m->by, m->win_geom.w, bar_height);
+ XMoveResizeWindow(dpy, m->statusbar, m->geom.x, m->geom.y, m->geom.w, bar_height);
return;
}
struct client *client;
wc.stack_mode = Below;
- wc.sibling = monitor->barwin;
+ wc.sibling = monitor->statusbar;
for(client = monitor->workspace->clients; client; client = client->next) {
if(!client->isfloating && ISVISIBLE(client)) {
return;
}
-void setlayout(const union arg *arg)
+static const struct layout *layout_next(const struct layout *current)
{
- if(!arg || !arg->v || arg->v != selmon->lt[selmon->sellt]) {
- selmon->sellt ^= 1;
+ const struct layout *next;
+
+ next = current + 1;
+
+ if(next < &layouts[LENGTH(layouts) - 1]) {
+ return(next);
}
+ return(&layouts[0]);
+}
+
+void setlayout(const union arg *arg)
+{
if(arg && arg->v) {
- selmon->lt[selmon->sellt] = (struct layout*)arg->v;
+ selmon->layout = (struct layout*)arg->v;
+ } else {
+ selmon->layout = layout_next(selmon->layout);
}
- strncpy(selmon->ltsymbol, selmon->lt[selmon->sellt]->symbol,
+ strncpy(selmon->ltsymbol, selmon->layout->symbol,
sizeof(selmon->ltsymbol));
if(selmon->workspace->focused) {
drawbar(selmon);
}
+ client_indicator_update(selmon->v_clind);
+ client_indicator_update(selmon->h_clind);
+
return;
}
screen = DefaultScreen(dpy);
root = RootWindow(dpy, screen);
initfont(font);
- screen_width = DisplayWidth(dpy, screen);
- screen_height = DisplayHeight(dpy, screen);
- bar_height = dc.geom.h = dc.font.height + 2 * bar_padding;
- updategeom();
+
+ /* init appearance */
+ for(i = 0; i < PalLast; i++) {
+ palette_init(&dc.palette[i], &theme[i]);
+ }
/* init atoms */
wmatom[WMProtocols] = XInternAtom(dpy, "WM_PROTOCOLS", False);
cursor[CurResize] = XCreateFontCursor(dpy, XC_sizing);
cursor[CurMove] = XCreateFontCursor(dpy, XC_fleur);
- /* init appearance */
- for(i = 0; i < PalLast; i++) {
- palette_init(&dc.palette[i], &theme[i]);
- }
+ dc.gc = XCreateGC(dpy, root, 0, NULL);
+ XSetLineAttributes(dpy, dc.gc, 1, LineSolid, CapButt, JoinMiter);
+
+ screen_width = DisplayWidth(dpy, screen);
+ screen_height = DisplayHeight(dpy, screen);
+ bar_height = dc.geom.h = dc.font.height + 2 * bar_padding;
dc.drawable = XCreatePixmap(dpy, root, DisplayWidth(dpy, screen),
bar_height, DefaultDepth(dpy, screen));
+
dc.draw = XftDrawCreate(dpy, dc.drawable, DefaultVisual(dpy, screen),
- DefaultColormap(dpy, screen));
- dc.gc = XCreateGC(dpy, root, 0, NULL);
- XSetLineAttributes(dpy, dc.gc, 1, LineSolid, CapButt, JoinMiter);
+ DefaultColormap(dpy, screen));
+
+ updategeom();
/* init bars */
updatebars();
static int monitor_is_floating(struct monitor *mon)
{
- if(mon->lt[mon->sellt]->arrange) {
+ if(mon->layout->arrange) {
return(FALSE);
}
return;
}
-#if 0
-static void tag(const union arg *arg)
-{
- if(selmon->sel && arg->ui & TAGMASK) {
- selmon->sel->tags = arg->ui & TAGMASK;
- focus(NULL);
- workspace_update(selmon->workspace);
- }
-
- return;
-}
-#endif
-
static void tagmon(const union arg *arg)
{
if(selmon->workspace->focused && mons->next) {
static void bookshelf(struct monitor *monitor)
{
- int n, w, x;
+ int n, w, x, y;
int extraw;
int hpad;
return;
}
+ /* map the horizontal window bar */
+ client_indicator_set_visible(monitor->h_clind, TRUE);
+ client_indicator_set_visible(monitor->v_clind, FALSE);
+
/*
* Start at x position m->wx, which is likely not going to be
* 0 in a multi-head setup. In other words, m->wx and m->wy
hpad = (n + 1) * client_padding.h;
w = (monitor->win_geom.w - hpad) / n;
x = monitor->win_geom.x;
+ y = monitor->win_geom.y + clind_height + client_padding.v;
/* make the first window a bit larger if the width can't be divided evenly */
extraw = monitor->win_geom.w - hpad - (w * n);
client->inch = 0;
width = w + extraw - border;
- height = monitor->win_geom.h - border - 2 * client_padding.v;
+ height = monitor->win_geom.h - border -
+ 2 * client_padding.v - clind_height;
- client_resize_hints(client, x + client_padding.h, monitor->win_geom.y + client_padding.v,
+ client_resize_hints(client, x + client_padding.h, y,
width, height, False);
/*
return;
}
+ /* map the vertical window bar */
+ client_indicator_set_visible(monitor->h_clind, FALSE);
+ client_indicator_set_visible(monitor->v_clind, TRUE);
+
vpad = (n + 1) * client_padding.v;
h = (monitor->win_geom.h - vpad) / n;
y = monitor->win_geom.y;
client->incw = 0;
client->inch = 0;
- width = monitor->win_geom.w - border - 2 * client_padding.h;
+ width = monitor->win_geom.w - border -
+ 2 * client_padding.h - clind_height;
height = h + extrah - border;
client_resize_hints(client, monitor->win_geom.x + client_padding.v, y + client_padding.h,
XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime);
}
+ if(client->workspace->viewer) {
+ client_indicator_update(client->workspace->viewer->v_clind);
+ client_indicator_update(client->workspace->viewer->h_clind);
+ }
+
return;
}
void updatebars(void)
{
struct monitor *monitor;
+ int depth;
+ Visual *visual;
+ unsigned long mask;
XSetWindowAttributes attrs = {
.override_redirect = True,
.event_mask = ButtonPressMask|ExposureMask
};
+ depth = DefaultDepth(dpy, screen);
+ visual = DefaultVisual(dpy, screen);
+ mask = CWOverrideRedirect | CWBackPixmap | CWEventMask;
+
for(monitor = mons; monitor; monitor = monitor->next) {
- monitor->barwin = XCreateWindow(dpy, root, monitor->win_geom.x, monitor->by,
- monitor->win_geom.w, bar_height, 0,
- DefaultDepth(dpy, screen), CopyFromParent,
- DefaultVisual(dpy, screen),
- CWOverrideRedirect | CWBackPixmap | CWEventMask,
- &attrs);
+ if(monitor->statusbar != 0) {
+ XUnmapWindow(dpy, monitor->statusbar);
+ XDestroyWindow(dpy, monitor->statusbar);
+ }
- XDefineCursor(dpy, monitor->barwin, cursor[CurNormal]);
- XMapRaised(dpy, monitor->barwin);
+ monitor->statusbar = XCreateWindow(dpy, root,
+ monitor->geom.x, monitor->geom.y,
+ monitor->geom.w, bar_height, 0,
+ depth, CopyFromParent, visual,
+ mask, &attrs);
+
+ XDefineCursor(dpy, monitor->statusbar, cursor[CurNormal]);
+ XMapRaised(dpy, monitor->statusbar);
}
return;
monitor->win_geom.y = monitor->geom.y;
monitor->win_geom.h = monitor->geom.h;
monitor->win_geom.h -= bar_height;
- monitor->by = monitor->win_geom.y;
monitor->win_geom.y = monitor->win_geom.y + bar_height;
return;
}
-Bool updategeom(void)
+static void monitor_attach(struct monitor *mon)
{
- Bool dirty = False;
+ struct monitor **last;
- if(XineramaIsActive(dpy)) {
- int i, j, n, nn;
- XineramaScreenInfo *info = XineramaQueryScreens(dpy, &nn);
- XineramaScreenInfo *unique = NULL;
+ for(last = &mons; *last; last = &((*last)->next));
+ *last = mon;
- n = num_monitors;
+ return;
+}
- /* only consider unique geometries as separate screens */
- if(!(unique = (XineramaScreenInfo *)malloc(sizeof(*unique) * nn))) {
- die("fatal: could not malloc() %u bytes\n", sizeof(*unique) * nn);
- }
+static void monitor_update_geometry(struct monitor *mon, int x, int y, int w, int h)
+{
+ mon->geom.x = x;
+ mon->geom.y = y;
+ mon->geom.w = w;
+ mon->geom.h = h;
- for(i = 0, j = 0; i < nn; i++) {
- if(isuniquegeom(unique, j, &info[i])) {
- memcpy(&unique[j++], &info[i], sizeof(*unique));
- }
+ memcpy(&mon->win_geom, &mon->geom, sizeof(mon->win_geom));
+ updatebarpos(mon);
+
+ monitor_resize_statusbar(mon);
+
+ if(mon->v_clind && mon->h_clind) {
+ client_indicator_resize(mon->v_clind);
+ client_indicator_resize(mon->h_clind);
+ }
+
+ return;
+}
+
+static int have_xinerama_screen(int needle, XineramaScreenInfo *haystack, int num)
+{
+ int i;
+
+ for(i = 0; i < num; i++) {
+ if(haystack[i].screen_number == needle) {
+ return(TRUE);
}
+ }
- XFree(info);
- nn = j;
+ return(FALSE);
+}
- if(n <= nn) {
- struct monitor *monitor;
+static int updategeom(void)
+{
+ int dirty = FALSE;
- for(i = 0; i < (nn - n); i++) { /* new monitors available */
- struct monitor **ptr;
+ if(XineramaIsActive(dpy)) {
+ XineramaScreenInfo *info;
+ struct monitor *monitor;
+ int num_mons;
+ int i;
- for(ptr = &mons; *ptr; ptr = &((*ptr)->next));
- *ptr = createmon();
- }
+ info = XineramaQueryScreens(dpy, &num_mons);
- for(i = 0, monitor = mons; i < nn && monitor; monitor = monitor->next, i++) {
- if(i >= n || (unique[i].x_org != monitor->geom.x ||
- unique[i].y_org != monitor->geom.y ||
- unique[i].width != monitor->geom.w ||
- unique[i].height != monitor->geom.h)) {
- dirty = True;
- monitor->num = i;
- monitor->geom.x = unique[i].x_org;
- monitor->geom.y = unique[i].y_org;
- monitor->geom.w = unique[i].width;
- monitor->geom.h = unique[i].height;
-
- memcpy(&(monitor->win_geom), &(monitor->geom),
- sizeof(monitor->win_geom));
-
- updatebarpos(monitor);
- }
- }
- } else { /* less monitors available nn < n */
- struct monitor *monitor;
+ for(i = 0; i < num_mons; i++) {
+ struct monitor *mon;
+
+ mon = monitor_get(info->screen_number);
- for(i = nn; i < n; i++) {
- for(monitor = mons; monitor && monitor->next; monitor = monitor->next);
+ if(mon) {
+ monitor_update_geometry(mon, info[i].x_org, info[i].y_org,
+ info[i].width, info[i].height);
+ dirty = TRUE;
+ } else {
+ mon = monitor_new(info[i].screen_number,
+ info[i].x_org, info[i].y_org,
+ info[i].width, info[i].height);
+ monitor_attach(mon);
+ }
+ }
+
+ for(monitor = mons; monitor; monitor = monitor->next) {
+ if(!have_xinerama_screen(monitor->num, info, num_mons)) {
if(monitor == selmon) {
- selmon = mons;
+ selmon = dirtomon(1);
}
monitor_free(monitor);
}
}
- free(unique);
+ XFree(info);
} else {
if(!mons) {
- mons = createmon();
- }
-
- if(mons->geom.w != screen_width || mons->geom.h != screen_height) {
+ mons = monitor_new(0, 0, 0, screen_width, screen_height);
+ } else if(mons->geom.w != screen_width || mons->geom.h != screen_height) {
+ monitor_update_geometry(mons, 0, 0, screen_width, screen_height);
dirty = True;
- mons->geom.w = mons->win_geom.w = screen_width;
- mons->geom.h = mons->win_geom.h = screen_height;
- updatebarpos(mons);
}
}
}
for(monitor = mons; monitor; monitor = monitor->next) {
- if(window == monitor->barwin) {
+ if(window == monitor->statusbar) {
return(monitor);
}
}