X-Git-Url: https://jasonwoof.com/gitweb/?a=blobdiff_plain;f=scrotwm.c;h=a2997cc167b4776114c2d2b2ecf6c5f2870de599;hb=af851bfc41facb5b4632d8b9938df2813be61684;hp=e201cb28e3e25889d082c8930988b1ef136865c3;hpb=3dcbf305451dc18f9d602db81162ea026c20eefa;p=spectrwm.git diff --git a/scrotwm.c b/scrotwm.c index e201cb2..a2997cc 100644 --- a/scrotwm.c +++ b/scrotwm.c @@ -933,8 +933,9 @@ dumpwins(struct swm_region *r, union arg *args) if (!XGetWindowAttributes(display, win->id, &wa)) fprintf(stderr, "window: %lu failed " "XGetWindowAttributes\n", win->id); - fprintf(stderr, "window: %lu map_state: %d state: %d\n", - win->id, wa.map_state, state); + fprintf(stderr, "window: %lu map_state: %d state: %d " + "transient: %lu\n", + win->id, wa.map_state, state, win->transient); } fprintf(stderr, "===== unmanaged window list =====\n"); @@ -943,8 +944,9 @@ dumpwins(struct swm_region *r, union arg *args) if (!XGetWindowAttributes(display, win->id, &wa)) fprintf(stderr, "window: %lu failed " "XGetWindowAttributes\n", win->id); - fprintf(stderr, "window: %lu map_state: %d state: %d\n", - win->id, wa.map_state, state); + fprintf(stderr, "window: %lu map_state: %d state: %d " + "transient: %lu\n", + win->id, wa.map_state, state, win->transient); } fprintf(stderr, "=================================\n"); @@ -2065,6 +2067,29 @@ cyclescr(struct swm_region *r, union arg *args) } void +sort_windows(struct ws_win_list *wl) +{ + struct ws_win *win, *parent, *nxt; + + if (wl == NULL) + return; + + for (win = TAILQ_FIRST(wl); win != TAILQ_END(wl); win = nxt) { + nxt = TAILQ_NEXT(win, entry); + if (win->transient) { + parent = find_window(win->transient); + if (parent == NULL) { + fprintf(stderr, "not possible bug\n"); + continue; + } + TAILQ_REMOVE(wl, win, entry); + TAILQ_INSERT_AFTER(wl, parent, win, entry); + } + } + +} + +void swapwin(struct swm_region *r, union arg *args) { struct ws_win *target, *source; @@ -2085,8 +2110,12 @@ swapwin(struct swm_region *r, union arg *args) switch (args->id) { case SWM_ARG_ID_SWAPPREV: + if (source->transient) + source = find_window(source->transient); target = TAILQ_PREV(source, ws_win_list, entry); - TAILQ_REMOVE(wl, cur_focus, entry); + if (target && target->transient) + target = find_window(target->transient); + TAILQ_REMOVE(wl, source, entry); if (target == NULL) TAILQ_INSERT_TAIL(wl, source, entry); else @@ -2094,6 +2123,9 @@ swapwin(struct swm_region *r, union arg *args) break; case SWM_ARG_ID_SWAPNEXT: target = TAILQ_NEXT(source, entry); + /* move the parent and let the sort handle the move */ + if (source->transient) + source = find_window(source->transient); TAILQ_REMOVE(wl, source, entry); if (target == NULL) TAILQ_INSERT_HEAD(wl, source, entry); @@ -2127,6 +2159,8 @@ swapwin(struct swm_region *r, union arg *args) return; } + sort_windows(wl); + stack(); } @@ -2269,7 +2303,6 @@ focus(struct swm_region *r, union arg *args) default: return; } - if (winfocus == winlostfocus || winfocus == NULL) return; @@ -2406,22 +2439,22 @@ stack_floater(struct ws_win *win, struct swm_region *r) * floaters and transients are auto-centred unless moved * or resized */ - win->g.x = r->g.x + (WIDTH(r) - win->g.w) / 2 - border_width; - win->g.y = r->g.y + (HEIGHT(r) - win->g.h) / 2 - border_width; + win->g.x = r->g.x + (WIDTH(r) - win->g.w) / 2 - wc.border_width; + win->g.y = r->g.y + (HEIGHT(r) - win->g.h) / 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 (win->g.x < r->g.x - border_width) - win->g.x = r->g.x - border_width; + if (win->g.x < r->g.x - wc.border_width) + win->g.x = r->g.x - wc.border_width; if (win->g.x > r->g.x + r->g.w - 1) win->g.x = (win->g.w > r->g.w) ? r->g.x : - (r->g.x + r->g.w - win->g.w - 2 * border_width); - if (win->g.y < r->g.y - border_width) - win->g.y = r->g.y - border_width; + (r->g.x + r->g.w - win->g.w - 2 * wc.border_width); + if (win->g.y < r->g.y - wc.border_width) + win->g.y = r->g.y - wc.border_width; if (win->g.y > r->g.y + r->g.h - 1) win->g.y = (win->g.h > r->g.h) ? r->g.y : - (r->g.y + r->g.h - win->g.h - 2 * border_width); + (r->g.y + r->g.h - win->g.h - 2 * wc.border_width); wc.x = win->g.x; wc.y = win->g.y; @@ -2842,7 +2875,7 @@ void send_to_ws(struct swm_region *r, union arg *args) { int wsid = args->id; - struct ws_win *win = win; + struct ws_win *win = NULL, *parent; struct workspace *ws, *nws; Atom ws_idx_atom = 0; unsigned char ws_idx_str[SWM_PROPLEN]; @@ -2864,6 +2897,15 @@ send_to_ws(struct swm_region *r, union arg *args) a.id = SWM_ARG_ID_FOCUSPREV; focus(r, &a); + if (win->transient) { + parent = find_window(win->transient); + if (parent) { + unmap_window(parent); + TAILQ_REMOVE(&ws->winlist, parent, entry); + TAILQ_INSERT_TAIL(&nws->winlist, parent, entry); + parent->ws = nws; + } + } unmap_window(win); TAILQ_REMOVE(&ws->winlist, win, entry); TAILQ_INSERT_TAIL(&nws->winlist, win, entry); @@ -4735,10 +4777,6 @@ manage_window(Window id) XSelectInput(display, id, EnterWindowMask | FocusChangeMask | PropertyChangeMask | StructureNotifyMask); - if (win->iconic) - set_win_state(win, IconicState); - else - set_win_state(win, NormalState); /* floaters need to be mapped if they are in the current workspace */ if ((win->floating || win->transient) && (ws->idx == r->ws->idx)) @@ -5236,6 +5274,21 @@ unmapnotify(XEvent *e) if (getstate(e->xunmap.window) == NormalState) { unmanage_window(win); stack(); + + /* giant hack for apps that don't destroy transient windows */ + /* eat a bunch of events to prevent remanaging the window */ + XEvent cne; + while (XCheckWindowEvent(display, e->xunmap.window, + EnterWindowMask, &cne)) + ; + while (XCheckWindowEvent(display, e->xunmap.window, + StructureNotifyMask, &cne)) + ; + while (XCheckWindowEvent(display, e->xunmap.window, + SubstructureNotifyMask, &cne)) + ; + /* resend unmap because we ated it */ + XUnmapWindow(display, e->xunmap.window); } }