X-Git-Url: https://jasonwoof.com/gitweb/?a=blobdiff_plain;f=spectrwm.c;h=5b97af2f11104da3f14fa6d2668cdb6cb11d9774;hb=ef048ac6ee49f942ee0029e04dfd8697a08f3d10;hp=1115cacddf0d5c67f6e028466ded27f9876cc7f6;hpb=d66a94fce3a9836fc2f86a111ac55c6b761411ae;p=spectrwm.git diff --git a/spectrwm.c b/spectrwm.c index 1115cac..5b97af2 100644 --- a/spectrwm.c +++ b/spectrwm.c @@ -173,6 +173,9 @@ u_int32_t swm_debug = 0 #define Y(r) (r)->g.y #define WIDTH(r) (r)->g.w #define HEIGHT(r) (r)->g.h +#define BORDER(w) (w->bordered ? border_width : 0) +#define MAX_X(r) ((r)->g.x + (r)->g.w) +#define MAX_Y(r) ((r)->g.y + (r)->g.h) #define SH_MIN(w) (w)->sh_mask & PMinSize #define SH_MIN_W(w) (w)->sh.min_width #define SH_MIN_H(w) (w)->sh.min_height @@ -354,13 +357,13 @@ struct ws_win { Window transient; struct ws_win *child_trans; /* transient child window */ struct swm_geometry g; /* current geometry */ - struct swm_geometry g_float; /* geometry when floating */ - struct swm_geometry rg_float; /* region geom when floating */ + struct swm_geometry g_float; /* region coordinates */ int g_floatvalid; /* g_float geometry validity */ int floatmaxed; /* whether maxed by max_stack */ int floating; int manual; int iconic; + int bordered; unsigned int ewmh_flags; int font_size_boundary[SWM_MAX_FONT_STEPS]; int font_steps; @@ -615,6 +618,8 @@ struct ewmh_hint { void store_float_geom(struct ws_win *, struct swm_region *); int floating_toggle_win(struct ws_win *); +void constrain_window(struct ws_win *, struct swm_region *, int); +void update_window(struct ws_win *); void spawn_select(struct swm_region *, union arg *, char *, int *); unsigned char *get_win_name(Window); @@ -786,8 +791,6 @@ ewmh_autoquirk(struct ws_win *win) int ewmh_set_win_fullscreen(struct ws_win *win, int fs) { - struct swm_geometry rg; - if (!win->ws->r) return (0); @@ -797,19 +800,18 @@ ewmh_set_win_fullscreen(struct ws_win *win, int fs) DNPRINTF(SWM_D_MISC, "ewmh_set_win_fullscreen: window: 0x%lx, " "fullscreen %s\n", win->id, YESNO(fs)); - rg = win->ws->r->g; - if (fs) { - store_float_geom(win, win->ws->r); + if (!win->g_floatvalid) + store_float_geom(win, win->ws->r); - win->g = rg; + win->g = win->ws->r->g; + win->bordered = 0; } else { if (win->g_floatvalid) { /* refloat at last floating relative position */ - X(win) = win->g_float.x - win->rg_float.x + rg.x; - Y(win) = win->g_float.y - win->rg_float.y + rg.y; - WIDTH(win) = win->g_float.w; - HEIGHT(win) = win->g_float.h; + win->g = win->g_float; + X(win) += X(win->ws->r); + Y(win) += Y(win->ws->r); } } @@ -1537,46 +1539,44 @@ bar_fmt(const char *fmtexp, char *fmtnew, struct swm_region *r, size_t sz) strlcat(fmtnew, "+4<+A+4<+V", sz); } +void +bar_replace_pad(char *tmp, int *limit, size_t sz) +{ + /* special case; no limit given, pad one space, instead */ + if (*limit == sz - 1) + *limit = 1; + snprintf(tmp, sz, "%*s", *limit, " "); +} + /* replaces the bar format character sequences (like in tmux(1)) */ char * bar_replace_seq(char *fmt, char *fmtrep, struct swm_region *r, size_t *offrep, size_t sz) { char *ptr; - char num[8], tmp[SWM_BAR_MAX]; - int limit; - size_t len, numoff = 0; + char tmp[SWM_BAR_MAX]; + int limit, size; + size_t len; /* reset strlcat(3) buffer */ *tmp = '\0'; /* get number, if any */ fmt++; - while (*fmt != '\0' && isdigit((unsigned char) *fmt)) { - if (numoff >= sizeof num - 1) - break; - num[numoff++] = *fmt++; - } - num[numoff] = '\0'; - - if ((limit = strtonum(num, 1, sizeof tmp - 1, NULL)) == 0) + size = 0; + if (sscanf(fmt, "%d%n", &limit, &size) != 1) + limit = sizeof tmp - 1; + if (limit <= 0 || limit >= sizeof tmp) limit = sizeof tmp - 1; - /* if number is too big, skip to the first non-digit */ - if (numoff >= sizeof num - 1) { - while (*fmt != '\0' && isdigit((unsigned char) *fmt)) - fmt++; - } /* there is nothing to replace (ie EOL) */ + fmt += size; if (*fmt == '\0') return (fmt); switch (*fmt) { case '<': - /* special case; no limit given, pad one space, instead */ - if (limit == sizeof tmp - 1) - limit = 1; - snprintf(tmp, sizeof tmp, "%*s", limit, " "); + bar_replace_pad(tmp, &limit, sizeof tmp); break; case 'A': snprintf(tmp, sizeof tmp, "%s", bar_ext); @@ -1917,7 +1917,7 @@ drain_enter_notify(void) while (XCheckMaskEvent(display, EnterWindowMask, &cne)) i++; - DNPRINTF(SWM_D_MISC, "drain_enter_notify: drained: %d\n", i); + DNPRINTF(SWM_D_EVENT, "drain_enter_notify: drained: %d\n", i); } void @@ -2001,7 +2001,7 @@ config_win(struct ws_win *win, XConfigureRequestEvent *ev) ce.display = display; ce.event = win->id; ce.window = win->id; - ce.border_width = border_width; + ce.border_width = BORDER(win); ce.above = None; } else { /* normal */ @@ -2046,8 +2046,8 @@ config_win(struct ws_win *win, XConfigureRequestEvent *ev) } /* adjust x and y for requested border_width. */ - ce.x += border_width - ev->border_width; - ce.y += border_width - ev->border_width; + ce.x += BORDER(win) - ev->border_width; + ce.y += BORDER(win) - ev->border_width; ce.border_width = ev->border_width; ce.above = ev->above; } @@ -2173,16 +2173,20 @@ root_to_region(Window root) int i, x, y, wx, wy; unsigned int mask; + DNPRINTF(SWM_D_MISC, "root_to_region: window: 0x%lx\n", root); + for (i = 0; i < ScreenCount(display); i++) if (screens[i].root == root) break; if (XQueryPointer(display, screens[i].root, &rr, &cr, &x, &y, &wx, &wy, &mask) != False) { + DNPRINTF(SWM_D_MISC, "root_to_region: pointer: (%d,%d)\n", + x, y); /* choose a region based on pointer location */ TAILQ_FOREACH(r, &screens[i].rl, entry) - if (x >= X(r) && x <= X(r) + WIDTH(r) && - y >= Y(r) && y <= Y(r) + HEIGHT(r)) + if (X(r) <= x && x < MAX_X(r) && + Y(r) <= y && y < MAX_Y(r)) break; } @@ -3018,46 +3022,65 @@ store_float_geom(struct ws_win *win, struct swm_region *r) { /* retain window geom and region geom */ win->g_float = win->g; - win->rg_float = r->g; + win->g_float.x -= X(r); + win->g_float.y -= Y(r); win->g_floatvalid = 1; + DNPRINTF(SWM_D_MISC, "store_float_geom: window: 0x%lx, g: (%d,%d)" + " %d x %d, g_float: (%d,%d) %d x %d\n", win->id, X(win), Y(win), + WIDTH(win), HEIGHT(win), win->g_float.x, win->g_float.y, + win->g_float.w, win->g_float.h); } void stack_floater(struct ws_win *win, struct swm_region *r) { - unsigned int mask; - XWindowChanges wc; - if (win == NULL) return; - bzero(&wc, sizeof wc); - mask = CWX | CWY | CWBorderWidth | CWWidth | CWHeight; + DNPRINTF(SWM_D_MISC, "stack_floater: window: 0x%lx\n", win->id); /* * to allow windows to change their size (e.g. mplayer fs) only retrieve * geom on ws switches or return from max mode */ - if (win->floatmaxed || (r != r->ws->old_r && win->g_floatvalid - && !(win->ewmh_flags & EWMH_F_FULLSCREEN))) { - /* - * use stored g and rg to set relative position and size - * as in old region or before max stack mode - */ - X(win) = win->g_float.x - win->rg_float.x + X(r); - Y(win) = win->g_float.y - win->rg_float.y + Y(r); - WIDTH(win) = win->g_float.w; - HEIGHT(win) = win->g_float.h; - win->g_floatvalid = 0; + if (win->g_floatvalid && (win->floatmaxed || (r != r->ws->old_r && + !(win->ewmh_flags & EWMH_F_FULLSCREEN)))) { + /* refloat at last floating relative position */ + win->g = win->g_float; + X(win) += X(r); + Y(win) += Y(r); } win->floatmaxed = 0; - if ((win->quirks & SWM_Q_FULLSCREEN) && (WIDTH(win) >= WIDTH(r)) && - (HEIGHT(win) >= HEIGHT(r))) - wc.border_width = 0; - else - wc.border_width = border_width; + /* + * if set to fullscreen mode, configure window to maximum size. + */ + if (win->ewmh_flags & EWMH_F_FULLSCREEN) { + if (!win->g_floatvalid) + store_float_geom(win, win->ws->r); + + win->g = win->ws->r->g; + } + + /* + * remove border on fullscreen floater when in fullscreen mode or when + * the quirk is present. + */ + if ((win->ewmh_flags & EWMH_F_FULLSCREEN) || + ((win->quirks & SWM_Q_FULLSCREEN) && + (WIDTH(win) >= WIDTH(r)) && (HEIGHT(win) >= HEIGHT(r)))) { + if (win->bordered) { + win->bordered = 0; + X(win) += border_width; + Y(win) += border_width; + } + } else if (!win->bordered) { + win->bordered = 1; + X(win) -= border_width; + Y(win) -= border_width; + } + if (win->transient && (win->quirks & SWM_Q_TRANSSZ)) { WIDTH(win) = (double)WIDTH(r) * dialog_ratio; HEIGHT(win) = (double)HEIGHT(r) * dialog_ratio; @@ -3068,39 +3091,14 @@ stack_floater(struct ws_win *win, struct swm_region *r) * floaters and transients are auto-centred unless moved * or resized */ - X(win) = X(r) + (WIDTH(r) - WIDTH(win)) / 2 - wc.border_width; - Y(win) = Y(r) + (HEIGHT(r) - HEIGHT(win)) / 2 - wc.border_width; - } - - /* win can be outside r if new r smaller than old r */ - /* Ensure top left corner inside r (move probs otherwise) */ - if (X(win) < X(r) - wc.border_width) - X(win) = X(r) - wc.border_width; - if (X(win) > X(r) + WIDTH(r) - 1) - X(win) = (WIDTH(win) > WIDTH(r)) ? X(r) : - (X(r) + WIDTH(r) - WIDTH(win) - 2 * wc.border_width); - if (Y(win) < Y(r) - wc.border_width) - Y(win) = Y(r) - wc.border_width; - if (Y(win) > Y(r) + HEIGHT(r) - 1) - Y(win) = (HEIGHT(win) > HEIGHT(r)) ? Y(r) : - (Y(r) + HEIGHT(r) - HEIGHT(win) - 2 * wc.border_width); - - wc.x = X(win); - wc.y = Y(win); - wc.width = WIDTH(win); - wc.height = HEIGHT(win); - - /* - * Retain floater and transient geometry for correct positioning - * when ws changes region - */ - if (!(win->ewmh_flags & EWMH_F_FULLSCREEN)) - store_float_geom(win, r); + X(win) = X(r) + (WIDTH(r) - WIDTH(win)) / 2 - BORDER(win); + Y(win) = Y(r) + (HEIGHT(r) - HEIGHT(win)) / 2 - BORDER(win); + } - DNPRINTF(SWM_D_MISC, "stack_floater: window: %lu, (x,y) w x h: (%d,%d) " - "%d x %d\n", win->id, wc.x, wc.y, wc.width, wc.height); + /* keep window within region bounds */ + constrain_window(win, r, 0); - XConfigureWindow(display, win->id, mask, &wc); + update_window(win); } /* @@ -3140,16 +3138,15 @@ adjust_font(struct ws_win *win) void stack_master(struct workspace *ws, struct swm_geometry *g, int rot, int flip) { - XWindowChanges wc; XWindowAttributes wa; struct swm_geometry win_g, r_g = *g; - struct ws_win *win, *fs_win = 0; + struct ws_win *win, *fs_win = NULL; int i, j, s, stacks; int w_inc = 1, h_inc, w_base = 1, h_base; int hrh, extra = 0, h_slice, last_h = 0; int split, colno, winno, mwin, msize, mscale; int remain, missing, v_slice, reconfigure; - unsigned int mask; + int bordered = 1; DNPRINTF(SWM_D_STACK, "stack_master: workspace: %d, rot: %s, " "flip: %s\n", ws->idx, YESNO(rot), YESNO(flip)); @@ -3275,37 +3272,41 @@ stack_master(struct workspace *ws, struct swm_geometry *g, int rot, int flip) else win_g.y += last_h + 2 * border_width; - bzero(&wc, sizeof wc); if (disable_border && bar_enabled == 0 && winno == 1){ - wc.border_width = 0; + bordered = 0; win_g.w += 2 * border_width; win_g.h += 2 * border_width; - } else - wc.border_width = border_width; - reconfigure = 0; + } else { + bordered = 1; + } if (rot) { if (X(win) != win_g.y || Y(win) != win_g.x || WIDTH(win) != win_g.h || HEIGHT(win) != win_g.w) { reconfigure = 1; - X(win) = wc.x = win_g.y; - Y(win) = wc.y = win_g.x; - WIDTH(win) = wc.width = win_g.h; - HEIGHT(win) = wc.height = win_g.w; + X(win) = win_g.y; + Y(win) = win_g.x; + WIDTH(win) = win_g.h; + HEIGHT(win) = win_g.w; } } else { if (X(win) != win_g.x || Y(win) != win_g.y || WIDTH(win) != win_g.w || HEIGHT(win) != win_g.h) { reconfigure = 1; - X(win) = wc.x = win_g.x; - Y(win) = wc.y = win_g.y; - WIDTH(win) = wc.width = win_g.w; - HEIGHT(win) = wc.height = win_g.h; + X(win) = win_g.x; + Y(win) = win_g.y; + WIDTH(win) = win_g.w; + HEIGHT(win) = win_g.h; } } + + if (bordered != win->bordered) { + reconfigure = 1; + win->bordered = bordered; + } + if (reconfigure) { adjust_font(win); - mask = CWX | CWY | CWWidth | CWHeight | CWBorderWidth; - XConfigureWindow(display, win->id, mask, &wc); + update_window(win); } if (XGetWindowAttributes(display, win->id, &wa)) @@ -3444,10 +3445,8 @@ horizontal_stack(struct workspace *ws, struct swm_geometry *g) void max_stack(struct workspace *ws, struct swm_geometry *g) { - XWindowChanges wc; struct swm_geometry gg = *g; struct ws_win *win, *wintrans = NULL, *parent = NULL; - unsigned int mask; int winno; DNPRINTF(SWM_D_STACK, "max_stack: workspace: %d\n", ws->idx); @@ -3478,21 +3477,16 @@ max_stack(struct workspace *ws, struct swm_geometry *g) /* only reconfigure if necessary */ if (X(win) != gg.x || Y(win) != gg.y || WIDTH(win) != gg.w || HEIGHT(win) != gg.h) { - bzero(&wc, sizeof wc); - X(win) = wc.x = gg.x; - Y(win) = wc.y = gg.y; + win->g = gg; if (bar_enabled){ - wc.border_width = border_width; - WIDTH(win) = wc.width = gg.w; - HEIGHT(win) = wc.height = gg.h; + win->bordered = 1; } else { - wc.border_width = 0; - WIDTH(win) = wc.width = gg.w + 2 * border_width; - HEIGHT(win) = wc.height = gg.h + - 2 * border_width; + win->bordered = 0; + WIDTH(win) += 2 * border_width; + HEIGHT(win) += 2 * border_width; } - mask = CWX | CWY | CWWidth | CWHeight | CWBorderWidth; - XConfigureWindow(display, win->id, mask, &wc); + + update_window(win); } /* unmap only if we don't have multi screen */ if (win != ws->focus) @@ -4033,8 +4027,8 @@ floating_toggle_win(struct ws_win *win) } else { if (win->g_floatvalid) { /* refloat at last floating relative position */ - X(win) = win->g_float.x - win->rg_float.x + X(r); - Y(win) = win->g_float.y - win->rg_float.y + Y(r); + X(win) = win->g_float.x + X(r); + Y(win) = win->g_float.y + Y(r); WIDTH(win) = win->g_float.w; HEIGHT(win) = win->g_float.h; } @@ -4071,38 +4065,40 @@ floating_toggle(struct swm_region *r, union arg *args) void constrain_window(struct ws_win *win, struct swm_region *r, int resizable) { - if (X(win) + WIDTH(win) > X(r) + WIDTH(r) - border_width) { + if (MAX_X(win) + BORDER(win) > MAX_X(r)) { if (resizable) - WIDTH(win) = X(r) + WIDTH(r) - X(win) - border_width; + WIDTH(win) = MAX_X(r) - X(win) - BORDER(win); else - X(win) = X(r) + WIDTH(r) - WIDTH(win) - border_width; + X(win) = MAX_X(r)- WIDTH(win) - BORDER(win); } - if (X(win) < X(r) - border_width) { + if (X(win) + BORDER(win) < X(r)) { if (resizable) - WIDTH(win) -= X(r) - X(win) - border_width; + WIDTH(win) -= X(r) - X(win) - BORDER(win); - X(win) = X(r) - border_width; + X(win) = X(r) - BORDER(win); } - if (Y(win) + HEIGHT(win) > Y(r) + HEIGHT(r) - border_width) { + if (MAX_Y(win) + BORDER(win) > MAX_Y(r)) { if (resizable) - HEIGHT(win) = Y(r) + HEIGHT(r) - Y(win) - border_width; + HEIGHT(win) = MAX_Y(r) - Y(win) - BORDER(win); else - Y(win) = Y(r) + HEIGHT(r) - HEIGHT(win) - border_width; + Y(win) = MAX_Y(r) - HEIGHT(win) - BORDER(win); } - if (Y(win) < Y(r) - border_width) { + if (Y(win) + BORDER(win) < Y(r)) { if (resizable) - HEIGHT(win) -= Y(r) - Y(win) - border_width; + HEIGHT(win) -= Y(r) - Y(win) - BORDER(win); - Y(win) = Y(r) - border_width; + Y(win) = Y(r) - BORDER(win); } - if (WIDTH(win) < 1) - WIDTH(win) = 1; - if (HEIGHT(win) < 1) - HEIGHT(win) = 1; + if (resizable) { + if (WIDTH(win) < 1) + WIDTH(win) = 1; + if (HEIGHT(win) < 1) + HEIGHT(win) = 1; + } } void @@ -4113,14 +4109,16 @@ update_window(struct ws_win *win) bzero(&wc, sizeof wc); mask = CWBorderWidth | CWWidth | CWHeight | CWX | CWY; - wc.border_width = border_width; + + wc.border_width = BORDER(win); wc.x = X(win); wc.y = Y(win); wc.width = WIDTH(win); wc.height = HEIGHT(win); - DNPRINTF(SWM_D_MISC, "update_window: window: 0x%lx, (x,y) w x h: " - "(%d,%d) %d x %d\n", win->id, wc.x, wc.y, wc.width, wc.height); + DNPRINTF(SWM_D_EVENT, "update_window: window: 0x%lx, (x,y) w x h: " + "(%d,%d) %d x %d, bordered: %s\n", win->id, wc.x, wc.y, wc.width, + wc.height, YESNO(win->bordered)); XConfigureWindow(display, win->id, mask, &wc); } @@ -4147,6 +4145,9 @@ resize(struct ws_win *win, union arg *args) return; r = win->ws->r; + if (win->ewmh_flags & EWMH_F_FULLSCREEN) + return; + DNPRINTF(SWM_D_MOUSE, "resize: window: 0x%lx, floating: %s, " "transient: 0x%lx\n", win->id, YESNO(win->floating), win->transient); @@ -4330,6 +4331,9 @@ move(struct ws_win *win, union arg *args) return; r = win->ws->r; + if (win->ewmh_flags & EWMH_F_FULLSCREEN) + return; + DNPRINTF(SWM_D_MOUSE, "move: window: 0x%lx, floating: %s, transient: " "0x%lx\n", win->id, YESNO(win->floating), win->transient); @@ -4339,7 +4343,7 @@ move(struct ws_win *win, union arg *args) win->manual = 1; if (win->floating == 0 && !win->transient) { - store_float_geom(win,r); + store_float_geom(win, r); ewmh_update_win_state(win, ewmh[_NET_WM_STATE_ABOVE].atom, _NET_WM_STATE_ADD); } @@ -4413,7 +4417,7 @@ move(struct ws_win *win, union arg *args) XSync(display, False); update_window(win); } - store_float_geom(win,r); + store_float_geom(win, r); XUngrabPointer(display, CurrentTime); /* drain events */ @@ -4951,6 +4955,7 @@ void setup_spawn(void) { setconfspawn("term", "xterm", 0); + setconfspawn("spawn_term", "xterm", 0); setconfspawn("screenshot_all", "screenshot.sh full", 0); setconfspawn("screenshot_wind", "screenshot.sh window", 0); setconfspawn("lock", "xlock", 0); @@ -5693,6 +5698,7 @@ setconfvalue(char *selector, char *value, int flags) break; case SWM_S_SPAWN_TERM: setconfspawn("term", value, 0); + setconfspawn("spawn_term", value, 0); break; case SWM_S_SS_APP: break; @@ -6186,9 +6192,7 @@ manage_window(Window id) Atom *prot = NULL, *pp; unsigned char ws_idx_str[SWM_PROPLEN], *prop = NULL; struct swm_region *r; - long mask = 0; const char *errstr; - XWindowChanges wc; struct pid_e *p; struct quirk *qp; @@ -6207,9 +6211,10 @@ manage_window(Window id) TAILQ_INSERT_AFTER(&win->ws->winlist, ww, win, entry); else if ((ww = win->ws->focus) && spawn_position == SWM_STACK_ABOVE) - TAILQ_INSERT_AFTER(&win->ws->winlist, win->ws->focus, win, entry); + TAILQ_INSERT_AFTER(&win->ws->winlist, win->ws->focus, + win, entry); else if (ww && spawn_position == SWM_STACK_BELOW) - TAILQ_INSERT_AFTER(&win->ws->winlist, win->ws->focus, win, entry); + TAILQ_INSERT_BEFORE(win->ws->focus, win, entry); else switch (spawn_position) { default: case SWM_STACK_TOP: @@ -6230,6 +6235,7 @@ manage_window(Window id) "new window"); win->id = id; + win->bordered = 0; /* see if we need to override the workspace */ p = find_pid(window_get_pid(id)); @@ -6307,19 +6313,38 @@ manage_window(Window id) win->s = r->s; /* this never changes */ if (trans && (ww = find_window(trans))) TAILQ_INSERT_AFTER(&ws->winlist, ww, win, entry); - else if (spawn_position == SWM_STACK_ABOVE && win->ws->focus) - TAILQ_INSERT_AFTER(&win->ws->winlist, win->ws->focus, win, entry); - else - TAILQ_INSERT_TAIL(&ws->winlist, win, entry); + else if (win->ws->focus && spawn_position == SWM_STACK_ABOVE) + TAILQ_INSERT_AFTER(&win->ws->winlist, win->ws->focus, win, + entry); + else if (win->ws->focus && spawn_position == SWM_STACK_BELOW) + TAILQ_INSERT_BEFORE(win->ws->focus, win, entry); + else switch (spawn_position) { + default: + case SWM_STACK_TOP: + case SWM_STACK_ABOVE: + TAILQ_INSERT_TAIL(&win->ws->winlist, win, entry); + break; + case SWM_STACK_BOTTOM: + case SWM_STACK_BELOW: + TAILQ_INSERT_HEAD(&win->ws->winlist, win, entry); + } + /* ignore window border if there is one. */ WIDTH(win) = win->wa.width; HEIGHT(win) = win->wa.height; - X(win) = win->wa.x; - Y(win) = win->wa.y; + X(win) = win->wa.x + win->wa.border_width; + Y(win) = win->wa.y + win->wa.border_width; + win->bordered = 0; win->g_floatvalid = 0; win->floatmaxed = 0; win->ewmh_flags = 0; + DNPRINTF(SWM_D_MISC, "manage_window: window: 0x%lx, (x,y) w x h: " + "(%d,%d) %d x %d, ws: %d\n", win->id, X(win), Y(win), WIDTH(win), + HEIGHT(win), ws->idx); + + constrain_window(win, r, 0); + /* Set window properties so we can remember this after reincarnation */ if (ws_idx_atom && prop == NULL && snprintf((char *)ws_idx_str, SWM_PROPLEN, "%d", ws->idx) < @@ -6362,16 +6387,10 @@ manage_window(Window id) /* alter window position if quirky */ if (win->quirks & SWM_Q_ANYWHERE) { win->manual = 1; /* don't center the quirky windows */ - bzero(&wc, sizeof wc); - mask = 0; - if (bar_enabled && Y(win) < bar_height) { - Y(win) = wc.y = bar_height; - mask |= CWY; - } - if (WIDTH(win) + X(win) > WIDTH(r)) { - X(win) = wc.x = WIDTH(r) - WIDTH(win) - 2; - mask |= CWX; - } + if (bar_enabled && Y(win) < bar_height) + Y(win) = bar_height; + if (WIDTH(win) + X(win) > WIDTH(r)) + X(win) = WIDTH(r) - WIDTH(win) - 2; border_me = 1; } @@ -6389,10 +6408,10 @@ manage_window(Window id) /* border me */ if (border_me) { - bzero(&wc, sizeof wc); - wc.border_width = border_width; - mask |= CWBorderWidth; - XConfigureWindow(display, win->id, mask, &wc); + win->bordered = 1; + X(win) -= border_width; + Y(win) -= border_width; + update_window(win); } XSelectInput(display, id, EnterWindowMask | FocusChangeMask | @@ -6558,9 +6577,6 @@ configurerequest(XEvent *e) if ((win = find_unmanaged_window(ev->window)) == NULL) new = 1; - DNPRINTF(SWM_D_EVENT, "configurerequest: window: 0x%lx, new: %s\n", - ev->window, YESNO(new)); - if (new) { bzero(&wc, sizeof wc); wc.x = ev->x; @@ -6570,9 +6586,31 @@ configurerequest(XEvent *e) wc.border_width = ev->border_width; wc.sibling = ev->above; wc.stack_mode = ev->detail; + + DNPRINTF(SWM_D_EVENT, "configurerequest: new window: 0x%lx, " + "new: %s, (x,y) w x h: (%d,%d) %d x %d\n", ev->window, + YESNO(new), wc.x, wc.y, wc.width, wc.height); + XConfigureWindow(display, ev->window, ev->value_mask, &wc); - } else + } else if ((!win->manual || win->quirks & SWM_Q_ANYWHERE) && + !(win->sh_mask & EWMH_F_FULLSCREEN)) { + win->g_float.x = ev->x - X(win->ws->r); + win->g_float.y = ev->y - Y(win->ws->r); + win->g_float.w = ev->width; + win->g_float.h = ev->height; + win->g_floatvalid = 1; + + if (win->floating) { + win->g = win->g_float; + win->g.x += X(win->ws->r); + win->g.y += Y(win->ws->r); + update_window(win); + } else { + config_win(win, ev); + } + } else { config_win(win, ev); + } } void @@ -6943,14 +6981,21 @@ visibilitynotify(XEvent *e) void clientmessage(XEvent *e) { - XClientMessageEvent *ev; - struct ws_win *win; + XClientMessageEvent *ev; + struct ws_win *win; ev = &e->xclient; win = find_window(ev->window); - if (win == NULL) + if (win == NULL) { + if (ev->message_type == ewmh[_NET_ACTIVE_WINDOW].atom) { + DNPRINTF(SWM_D_EVENT, "clientmessage: request focus on " + "unmanaged window.\n"); + e->xmaprequest.window = ev->window; + maprequest(e); + } return; + } DNPRINTF(SWM_D_EVENT, "clientmessage: window: 0x%lx, type: %ld\n", ev->window, ev->message_type); @@ -7132,7 +7177,7 @@ scan_xrandr(int i) /* map virtual screens onto physical screens */ #ifdef SWM_XRR_HAS_CRTC if (xrandr_support) { - sr = XRRGetScreenResources(display, screens[i].root); + sr = XRRGetScreenResourcesCurrent(display, screens[i].root); if (sr == NULL) new_region(&screens[i], 0, 0, DisplayWidth(display, i),