#endif
#endif
-/* #define SWM_DEBUG */
+/*#define SWM_DEBUG*/
#ifdef SWM_DEBUG
#define DPRINTF(x...) do { if (swm_debug) fprintf(stderr, x); } while (0)
#define DNPRINTF(n,x...) do { if (swm_debug & n) fprintf(stderr, x); } while (0)
};
void focus(struct swm_region *, union arg *);
-void focus_magic(struct ws_win *, int);
-#define SWM_F_GENERIC (0)
-#define SWM_F_TRANSIENT (1)
+void focus_magic(struct ws_win *);
+
/* quirks */
struct quirk {
char *class;
win->g.y = rg.y;
win->g.w = rg.w;
win->g.h = rg.h;
- } else {
+ } else {
if (win->g_floatvalid) {
/* refloat at last floating relative position */
win->g.x = win->g_float.x - win->rg_float.x + rg.x;
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");
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");
if (win->java == 0)
XSetInputFocus(display, win->id,
RevertToParent, CurrentTime);
+ XMapRaised(display, win->id);
grabbuttons(win, 1);
XSetWindowBorder(display, win->id,
win->ws->r->s->c[SWM_S_COLOR_FOCUS].color);
}
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;
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
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);
return;
}
+ sort_windows(wl);
+
stack();
}
if (winfocus == winlostfocus || winfocus == NULL)
return;
- focus_magic(winfocus, SWM_F_GENERIC);
+ focus_magic(winfocus);
}
void
if (winfocus->iconic == 0)
break;
- focus_magic(winfocus, SWM_F_GENERIC);
+ focus_magic(winfocus);
return;
}
if (head == NULL)
head = TAILQ_LAST(wl, ws_win_list);
winfocus = head;
- for (;;) {
- if (winfocus == NULL)
- break;
- if (!winfocus->iconic)
- break;
- winfocus = TAILQ_PREV(winfocus, ws_win_list, entry);
- if (winfocus == NULL)
- winfocus = TAILQ_LAST(wl, ws_win_list);
- if (winfocus == head) {
- winfocus = NULL;
- break;
- }
+ if (WINID(winfocus) == cur_focus->transient) {
+ head = TAILQ_PREV(winfocus, ws_win_list, entry);
+ if (head == NULL)
+ head = TAILQ_LAST(wl, ws_win_list);
+ winfocus = head;
+ }
+
+ /* skip iconics */
+ if (winfocus && winfocus->iconic) {
+ TAILQ_FOREACH_REVERSE(winfocus, wl, ws_win_list, entry)
+ if (winfocus->iconic == 0)
+ break;
}
break;
if (head == NULL)
head = TAILQ_FIRST(wl);
winfocus = head;
- for (;;) {
- if (winfocus == NULL)
- break;
- if (!winfocus->iconic)
- break;
- winfocus = TAILQ_NEXT(winfocus, entry);
- if (winfocus == NULL)
- winfocus = TAILQ_FIRST(wl);
- if (winfocus == head) {
- winfocus = NULL;
- break;
- }
+
+ /* skip iconics */
+ if (winfocus && winfocus->iconic) {
+ TAILQ_FOREACH(winfocus, wl, entry)
+ if (winfocus->iconic == 0)
+ break;
}
break;
default:
return;
}
-
if (winfocus == winlostfocus || winfocus == NULL)
return;
- focus_magic(winfocus, SWM_F_GENERIC);
+ focus_magic(winfocus);
}
void
* 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;
j++;
}
- notiles:
+notiles:
/* now, stack all the floaters and transients */
TAILQ_FOREACH(win, &ws->winlist, entry) {
if (win->transient == 0 && win->floating == 0)
continue;
- if (win->iconic == 0)
+ if (win->iconic == 1)
continue;
-
if (win->ewmh_flags & EWMH_F_FULLSCREEN) {
fs_win = win;
continue;
if (parent)
XMapRaised(display, parent->id);
stack_floater(wintrans, ws->r);
- focus_magic(wintrans, SWM_F_TRANSIENT);
+ focus_magic(wintrans);
}
}
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];
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);
DNPRINTF(SWM_D_MISC, "manage previously unmanaged window "
"%lu\n", win->id);
TAILQ_REMOVE(&win->ws->unmanagedlist, win, entry);
- TAILQ_INSERT_TAIL(&win->ws->winlist, win, entry);
if (win->transient)
set_child_transient(win);
+ if (trans && (ww = find_window(trans)))
+ TAILQ_INSERT_AFTER(&win->ws->winlist, ww, win, entry);
+ else
+ TAILQ_INSERT_TAIL(&win->ws->winlist, win, entry);
ewmh_update_actions(win);
return (win);
}
win->id = id;
win->ws = ws;
win->s = r->s; /* this never changes */
- TAILQ_INSERT_TAIL(&ws->winlist, win, entry);
+ if (trans && (ww = find_window(trans)))
+ TAILQ_INSERT_AFTER(&ws->winlist, ww, win, entry);
+ else
+ TAILQ_INSERT_TAIL(&ws->winlist, win, entry);
win->g.w = win->wa.width;
win->g.h = win->wa.height;
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))
/* focus on root just in case */
XSetInputFocus(display, PointerRoot, PointerRoot, CurrentTime);
- if (!win->floating)
- focus_prev(win);
+ focus_prev(win);
TAILQ_REMOVE(&win->ws->winlist, win, entry);
TAILQ_INSERT_TAIL(&win->ws->unmanagedlist, win, entry);
}
void
-focus_magic(struct ws_win *win, int do_trans)
+focus_magic(struct ws_win *win)
{
- DNPRINTF(SWM_D_FOCUS, "focus_magic: %lu %d\n", WINID(win), do_trans);
+ DNPRINTF(SWM_D_FOCUS, "focus_magic: %lu\n", WINID(win));
if (win == NULL)
return;
- if (do_trans == SWM_F_TRANSIENT && win->child_trans) {
+ if (win->child_trans) {
/* win = parent & has a transient so focus on that */
if (win->java) {
focus_win(win->child_trans);
if ((win = find_window(ev->window)) == NULL)
return;
- focus_magic(win, SWM_F_TRANSIENT);
+ focus_magic(win);
action = client_click;
for (i = 0; i < LENGTH(buttons); i++)
return;
}
- focus_magic(win, SWM_F_TRANSIENT);
+ focus_magic(win);
}
/* lets us use one switch statement for arbitrary mode/detail combinations */
/* make new win focused */
r = root_to_region(win->wa.root);
if (win->ws == r->ws)
- focus_magic(win, SWM_F_GENERIC);
+ focus_magic(win);
}
void
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);
}
}