void horizontal_stack(struct workspace *, struct swm_geometry *);
void max_stack(struct workspace *, struct swm_geometry *);
+struct ws_win *find_window(Window);
+
void grabbuttons(struct ws_win *, int);
void new_region(struct swm_screen *, int, int, int, int);
void unmanage_window(struct ws_win *);
{ vertical_stack, vertical_config, 0, "[|]" },
{ horizontal_stack, horizontal_config, 0, "[-]" },
{ max_stack, NULL,
- SWM_L_FOCUSPREV | SWM_L_MAPONFOCUS, "[ ]"},
+ SWM_L_MAPONFOCUS | SWM_L_FOCUSPREV, "[ ]"},
{ NULL, NULL, 0, NULL },
};
};
void focus(struct swm_region *, union arg *);
-void focus_magic(struct ws_win *);
-
+void focus_magic(struct ws_win *, int);
+#define SWM_F_GENERIC (0)
+#define SWM_F_TRANSIENT (1)
/* quirks */
struct quirk {
char *class;
void
focus(struct swm_region *r, union arg *args)
{
- struct ws_win *winfocus, *winlostfocus;
- struct ws_win_list *wl;
- struct ws_win *cur_focus;
+ struct ws_win *winfocus = NULL, *winlostfocus = NULL;
+ struct ws_win *cur_focus = NULL;
+ struct ws_win_list *wl = NULL;
+ struct workspace *ws = NULL;
if (!(r && r->ws))
return;
else
winfocus = TAILQ_FIRST(&r->ws->winlist);
- focus_magic(winfocus);
+ focus_magic(winfocus, SWM_F_GENERIC);
return;
}
- cur_focus = r->ws->focus;
- if (cur_focus == NULL)
+ if (r->ws->focus == NULL)
return;
- wl = &cur_focus->ws->winlist;
+ cur_focus = r->ws->focus;
+ ws = r->ws;
+ wl = &ws->winlist;
winlostfocus = cur_focus;
switch (args->id) {
case SWM_ARG_ID_FOCUSPREV:
- winfocus = TAILQ_PREV(cur_focus, ws_win_list, entry);
- if (winfocus == NULL)
- winfocus = TAILQ_LAST(wl, ws_win_list);
- break;
+ if (cur_focus->transient)
+ winfocus = find_window(cur_focus->transient);
+ else if (ws->focus == cur_focus) {
+ /* if in max_stack try harder */
+ if (ws->cur_layout->flags & SWM_L_FOCUSPREV) {
+ if (cur_focus != ws->focus_prev)
+ winfocus = ws->focus_prev;
+ else if (cur_focus != ws->focus)
+ winfocus = ws->focus;
+ }
+ /* fallback and normal handling */
+ if (winfocus == NULL) {
+ if (TAILQ_FIRST(wl) == cur_focus)
+ winfocus = TAILQ_NEXT(cur_focus, entry);
+ else {
+ winfocus = TAILQ_PREV(ws->focus,
+ ws_win_list, entry);
+ if (winfocus == NULL)
+ winfocus = TAILQ_LAST(wl,
+ ws_win_list);
+ }
+ }
+ }
+ break;
case SWM_ARG_ID_FOCUSNEXT:
winfocus = TAILQ_NEXT(cur_focus, entry);
if (winfocus == NULL)
if (winfocus == winlostfocus || winfocus == NULL)
return;
- focus_magic(winfocus);
+ focus_magic(winfocus, SWM_F_GENERIC);
}
void
{
XWindowChanges wc;
struct swm_geometry gg = *g;
- struct ws_win *win, *wintrans = NULL;
+ struct ws_win *win, *wintrans = NULL, *parent = NULL;
unsigned int mask;
int winno;
TAILQ_FOREACH(win, &ws->winlist, entry) {
if (win->transient) {
wintrans = win;
+ parent = find_window(win->transient);
continue;
}
/* put the last transient on top */
if (wintrans) {
+ if (parent)
+ XMapRaised(display, parent->id);
stack_floater(wintrans, ws->r);
- focus_magic(wintrans); /* override */
+ focus_magic(wintrans, SWM_F_TRANSIENT);
}
}
return (0);
}
+void
+set_child_transient(struct ws_win *win)
+{
+ struct ws_win *parent;
+
+ parent = find_window(win->transient);
+ if (parent)
+ parent->child_trans = win;
+}
+
struct ws_win *
manage_window(Window id)
{
Window trans = 0;
struct workspace *ws;
- struct ws_win *win, *ww, *parent;
+ struct ws_win *win, *ww;
int format, i, ws_idx, n, border_me = 0;
unsigned long nitems, bytes;
Atom ws_idx_atom = 0, type;
"%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);
return (win);
}
XGetTransientForHint(display, id, &trans);
if (trans) {
win->transient = trans;
- parent = find_window(win->transient);
- if (parent)
- parent->child_trans = win;
+ set_child_transient(win);
DNPRINTF(SWM_D_MISC, "manage_window: win %lu transient %lu\n",
win->id, win->transient);
}
}
void
-focus_magic(struct ws_win *win)
+focus_magic(struct ws_win *win, int do_trans)
{
if (win == NULL)
return;
- if (win->child_trans) {
+ if (do_trans == SWM_F_TRANSIENT && 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);
+ focus_magic(win, SWM_F_TRANSIENT);
action = client_click;
for (i = 0; i < LENGTH(buttons); i++)
if ((win = find_window(ev->window)) == NULL)
return;
- focus_magic(win);
+ focus_magic(win, SWM_F_TRANSIENT);
}
void
/* make new win focused */
r = root_to_region(win->wa.root);
if (win->ws == r->ws)
- focus_magic(win);
+ focus_magic(win, SWM_F_GENERIC);
}
void