#define SWM_FOCUS_FOLLOW (1)
#define SWM_FOCUS_MANUAL (2)
+#define SWM_CK_NONE 0
+#define SWM_CK_ALL 0x7
+#define SWM_CK_FOCUS 0x1
+#define SWM_CK_POINTER 0x2
+#define SWM_CK_FALLBACK 0x4
+
#define SWM_CONF_DEFAULT (0)
#define SWM_CONF_KEYMAPPING (1)
char *get_notify_detail_label(uint8_t);
char *get_notify_mode_label(uint8_t);
#endif
+struct ws_win *get_pointer_win(xcb_window_t);
struct ws_win *get_region_focus(struct swm_region *);
xcb_screen_t *get_screen(int);
char *get_win_name(xcb_window_t);
quit(NULL, NULL);
}
+struct ws_win *
+get_pointer_win(xcb_window_t root)
+{
+ struct ws_win *win = NULL;
+ xcb_query_pointer_reply_t *r;
+
+ DNPRINTF(SWM_D_EVENT, "get_pointer_win: root: 0x%x.\n", root);
+
+ r = xcb_query_pointer_reply(conn, xcb_query_pointer(conn, root), NULL);
+ if (r) {
+ win = find_window(r->child);
+ if (win) {
+ DNPRINTF(SWM_D_EVENT, "get_pointer_win: 0x%x.\n",
+ win->id);
+ } else {
+ DNPRINTF(SWM_D_EVENT, "get_pointer_win: none.\n");
+ }
+ }
+
+ return win;
+}
+
struct swm_region *
-root_to_region(xcb_window_t root)
+root_to_region(xcb_window_t root, int check)
{
struct ws_win *cfw;
struct swm_region *r = NULL;
if (screens[i].root == root)
break;
- /* Try to find an actively focused window */
- gifr = xcb_get_input_focus_reply(conn, xcb_get_input_focus(conn), NULL);
- if (gifr) {
- cfw = find_window(gifr->focus);
- if (cfw && cfw->ws->r)
- r = cfw->ws->r;
+ if (check & SWM_CK_FOCUS) {
+ /* Try to find an actively focused window */
+ gifr = xcb_get_input_focus_reply(conn,
+ xcb_get_input_focus(conn), NULL);
+ if (gifr) {
+ cfw = find_window(gifr->focus);
+ if (cfw && cfw->ws->r)
+ r = cfw->ws->r;
- free(gifr);
+ free(gifr);
+ }
}
- if (r == NULL) {
+ if (r == NULL && check & SWM_CK_POINTER) {
/* No region with an active focus; try to use pointer. */
qpr = xcb_query_pointer_reply(conn, xcb_query_pointer(conn,
screens[i].root), NULL);
if (qpr) {
- DNPRINTF(SWM_D_MISC, "root_to_region: pointer: (%d,%d)\n",
- qpr->root_x, qpr->root_y);
+ DNPRINTF(SWM_D_MISC, "root_to_region: pointer: "
+ "(%d,%d)\n", qpr->root_x, qpr->root_y);
TAILQ_FOREACH(r, &screens[i].rl, entry)
- if (X(r) <= qpr->root_x && qpr->root_x < MAX_X(r) &&
- Y(r) <= qpr->root_y && qpr->root_y < MAX_Y(r))
+ if (X(r) <= qpr->root_x &&
+ qpr->root_x < MAX_X(r) &&
+ Y(r) <= qpr->root_y &&
+ qpr->root_y < MAX_Y(r))
break;
free(qpr);
}
}
/* Last resort. */
- if (r == NULL)
+ if (r == NULL && check & SWM_CK_FALLBACK)
r = TAILQ_FIRST(&screens[i].rl);
return (r);
void
focus_win(struct ws_win *win)
{
- struct ws_win *cfw = NULL;
+ struct ws_win *cfw = NULL, *parent = NULL, *w;
+ struct workspace *ws;
xcb_get_input_focus_reply_t *r;
DNPRINTF(SWM_D_FOCUS, "focus_win: window: 0x%x\n", WINID(win));
if (win->ws == NULL)
goto out;
- if (validate_ws(win->ws))
+ ws = win->ws;
+
+ if (validate_ws(ws))
goto out;
if (validate_win(win)) {
free(r);
}
- if (win->ws->focus != win) {
- if (win->ws->focus && win->ws->focus != cfw)
- unfocus_win(win->ws->focus);
- win->ws->focus = win;
+ if (ws->focus != win) {
+ if (ws->focus && ws->focus != cfw)
+ unfocus_win(ws->focus);
+ ws->focus = win;
+ }
+
+ /* If this window directs focus to a child window, then clear. */
+ if (win->focus_child)
+ win->focus_child = NULL;
+
+ /* If transient, adjust parent's focus child for focus_magic. */
+ if (win->transient) {
+ parent = find_window(win->transient);
+ if (parent && parent->focus_child != win)
+ parent->focus_child = win;
}
- if (cfw != win && win->ws->r != NULL) {
+ if (cfw != win && ws->r != NULL) {
/* Set input focus if no input hint, or indicated by hint. */
if (!(win->hints.flags & XCB_ICCCM_WM_HINT_INPUT) ||
(win->hints.flags & XCB_ICCCM_WM_HINT_INPUT &&
if (win->take_focus) {
/* java is special; always tell parent */
if (win->transient && win->java)
- client_msg(find_window(win->transient),
- a_takefocus, last_event_time);
+ client_msg(parent, a_takefocus,
+ last_event_time);
else
client_msg(win, a_takefocus, last_event_time);
}
xcb_change_window_attributes(conn, win->id, XCB_CW_BORDER_PIXEL,
- &win->ws->r->s->c[SWM_S_COLOR_FOCUS].pixel);
+ &ws->r->s->c[SWM_S_COLOR_FOCUS].pixel);
+
+ if (ws->cur_layout->flags & SWM_L_MAPONFOCUS ||
+ ws->always_raise) {
+ /* If a parent exists, map it first. */
+ if (parent) {
+ map_window(parent);
- if (win->ws->cur_layout->flags & SWM_L_MAPONFOCUS ||
- win->ws->always_raise)
+ /* Map siblings next. */
+ TAILQ_FOREACH(w, &ws->winlist, entry)
+ if (w != win && !w->iconic &&
+ w->transient == parent->id)
+ map_window(w);
+ }
+
+ /* Map focused window. */
map_window(win);
+ /* Finally, map children of focus window. */
+ TAILQ_FOREACH(w, &ws->winlist, entry)
+ if (w->transient == win->id && !w->iconic)
+ map_window(w);
+
+ }
+
xcb_change_property(conn, XCB_PROP_MODE_REPLACE, win->s->root,
ewmh[_NET_ACTIVE_WINDOW].atom, XCB_ATOM_WINDOW, 32, 1,
&win->id);
this_r->ws = new_ws;
new_ws->r = this_r;
+ /* Set focus_pending before stacking. */
+ if (focus_mode != SWM_FOCUS_FOLLOW)
+ new_ws->focus_pending = get_region_focus(new_ws->r);
+
stack();
/* unmap old windows */
TAILQ_FOREACH(win, &old_ws->winlist, entry)
unmap_window(win);
- if (focus_mode != SWM_FOCUS_FOLLOW)
- new_ws->focus_pending = get_region_focus(new_ws->r);
-
- if (new_ws->focus_pending && focus_mode != SWM_FOCUS_FOLLOW) {
- /* if workspaces were swapped, then don't wait to set focus */
- if (old_ws->r)
+ /* if workspaces were swapped, then don't wait to set focus */
+ if (old_ws->r && focus_mode != SWM_FOCUS_FOLLOW) {
+ if (new_ws->focus_pending) {
focus_win(new_ws->focus_pending);
- } else {
- /* make sure bar gets updated if ws is empty */
- bar_update();
+ } else {
+ /* Empty region, focus on root. */
+ xcb_set_input_focus(conn, XCB_INPUT_FOCUS_PARENT,
+ new_ws->r->s[new_ws->r->s->idx].root,
+ XCB_CURRENT_TIME);
+ }
}
+ /* Clear bar if new ws is empty. */
+ if (new_ws->focus_pending == NULL)
+ bar_update();
+
focus_flush();
DNPRINTF(SWM_D_WS, "switchws: done.\n");
void
cyclescr(struct swm_region *r, union arg *args)
{
+ struct ws_win *nfw;
struct swm_region *rr = NULL;
int i, num_screens;
if (rr == NULL)
return;
- focus_win(get_region_focus(rr));
+ nfw = get_region_focus(rr);
+ if (nfw) {
+ focus_win(nfw);
+ } else {
+ /* New region is empty; unfocus old region and warp pointer. */
+ unfocus_win(r->ws->focus);
+ xcb_set_input_focus(conn, XCB_INPUT_FOCUS_PARENT,
+ rr->s[i].root, XCB_CURRENT_TIME);
+
+ /* Clear bar since empty. */
+ bar_update();
+ }
focus_flush();
}
focus_win(get_focus_magic(winfocus));
- xcb_flush(conn);
+ focus_flush();
}
void
map_window(win);
}
+ /* Make sure fs_win is stacked last so it's on top. */
if (fs_win) {
stack_floater(fs_win, ws->r);
map_window(fs_win);
max_stack(struct workspace *ws, struct swm_geometry *g)
{
struct swm_geometry gg = *g;
- struct ws_win *win, *wintrans = NULL, *parent = NULL;
+ struct ws_win *w, *win = NULL, *parent = NULL;
int winno, num_screens;
DNPRINTF(SWM_D_STACK, "max_stack: workspace: %d\n", ws->idx);
if (winno == 0 && count_win(ws, 1) == 0)
return;
+ /* Figure out which top level window should be visible. */
+ if (ws->focus_pending)
+ win = ws->focus_pending;
+ else if (ws->focus)
+ win = ws->focus;
+ else
+ win = TAILQ_FIRST(&ws->winlist);
+
+ if (win->transient)
+ parent = find_window(win->transient);
+
+ DNPRINTF(SWM_D_STACK, "max_stack: win: 0x%x\n", win->id);
+
+ /* maximize all top level windows */
num_screens = xcb_setup_roots_length(xcb_get_setup(conn));
- TAILQ_FOREACH(win, &ws->winlist, entry) {
- if (win->transient) {
- wintrans = win;
- parent = find_window(win->transient);
+ TAILQ_FOREACH(w, &ws->winlist, entry) {
+ if (w->transient || w->iconic)
continue;
- }
- if (win->floating && !win->floatmaxed ) {
+ if (w->floating && !w->floatmaxed) {
/*
* retain geometry for retrieval on exit from
* max_stack mode
*/
- store_float_geom(win, ws->r);
- win->floatmaxed = 1;
+ store_float_geom(w, ws->r);
+ w->floatmaxed = 1;
}
/* only reconfigure if necessary */
- if (X(win) != gg.x || Y(win) != gg.y || WIDTH(win) != gg.w ||
- HEIGHT(win) != gg.h) {
- win->g = gg;
+ if (X(w) != gg.x || Y(w) != gg.y || WIDTH(w) != gg.w ||
+ HEIGHT(w) != gg.h) {
+ w->g = gg;
if (bar_enabled){
- win->bordered = 1;
+ w->bordered = 1;
} else {
- win->bordered = 0;
- WIDTH(win) += 2 * border_width;
- HEIGHT(win) += 2 * border_width;
+ w->bordered = 0;
+ WIDTH(w) += 2 * border_width;
+ HEIGHT(w) += 2 * border_width;
}
- update_window(win);
+ update_window(w);
}
- /* unmap only if we don't have multi screen */
- if (win != ws->focus)
- if (!(num_screens > 1 || outputs > 1))
- unmap_window(win);
+
+ /* Unmap unwanted windows if not multi-screen. */
+ if (!(num_screens > 1 || outputs > 1) && (w != win ||
+ w != parent || w->transient != win->id))
+ unmap_window(w);
}
- /* put the last transient on top */
- if (wintrans) {
- if (parent)
- map_window(parent);
- stack_floater(wintrans, ws->r);
- ws->focus = get_focus_magic(wintrans);
+ /* If a parent exists, map it first. */
+ if (parent) {
+ map_window(parent);
+
+ /* Map siblings next. */
+ TAILQ_FOREACH(w, &ws->winlist, entry)
+ if (w != win && !w->iconic &&
+ w->transient == parent->id) {
+ stack_floater(w, ws->r);
+ map_window(w);
+ }
}
+
+ /* Map focused window. */
+ map_window(win);
+
+ /* Finally, map children of focus window. */
+ TAILQ_FOREACH(w, &ws->winlist, entry)
+ if (w->transient == win->id && !w->iconic) {
+ stack_floater(w, ws->r);
+ map_window(w);
+ }
}
void
if (strncmp(s, resp, len) == 0) {
/* XXX this should be a callback to generalize */
set_swm_iconic(win, 0);
- xcb_flush(conn);
free(s);
break;
}
if (r->ws->focus->can_delete)
client_msg(r->ws->focus, a_delete, 0);
- xcb_flush(conn);
+ focus_flush();
}
int
return;
resize(win, args);
+ focus_flush();
}
#define SWM_MOVE_STEPS (50)
return;
move(win, args);
+ focus_flush();
}
/* user/key callable function IDs */
XCB_GRAB_MODE_SYNC, XCB_GRAB_MODE_ASYNC,
XCB_WINDOW_NONE, XCB_CURSOR_NONE,
buttons[i].button, buttons[i].mask);
-
- /* click to focus */
- xcb_grab_button(conn, 0, win->id, BUTTONMASK, XCB_GRAB_MODE_SYNC,
- XCB_GRAB_MODE_ASYNC, XCB_WINDOW_NONE, XCB_CURSOR_NONE,
- XCB_BUTTON_INDEX_1, XCB_BUTTON_MASK_ANY);
}
const char *quirkname[] = {
DNPRINTF(SWM_D_MISC, "set_child_transient: parent doesn't exist"
" for 0x%x trans 0x%x\n", win->id, win->transient);
- r = root_to_region(win->wa->root);
+ r = root_to_region(win->wa->root, SWM_CK_ALL);
ws = r->ws;
/* parent doen't exist in our window list */
TAILQ_FOREACH(w, &ws->winlist, entry) {
NULL);
/* Figure out which region the window belongs to. */
- r = root_to_region(win->wa->root);
+ r = root_to_region(win->wa->root, SWM_CK_ALL);
/* Ignore window border if there is one. */
WIDTH(win) = win->wa->width;
last_event_time = e->time;
if (kp->funcid == KF_SPAWN_CUSTOM)
- spawn_custom(root_to_region(e->root),
+ spawn_custom(root_to_region(e->root, SWM_CK_ALL),
&(keyfuncs[kp->funcid].args), kp->spawn_name);
else if (keyfuncs[kp->funcid].func)
- keyfuncs[kp->funcid].func(root_to_region(e->root),
+ keyfuncs[kp->funcid].func(root_to_region(e->root, SWM_CK_ALL),
&(keyfuncs[kp->funcid].args));
}
void
buttonpress(xcb_button_press_event_t *e)
{
- struct ws_win *win;
+ struct ws_win *win = NULL;
+ struct swm_region *r, *old_r;
int i;
int handled = 0;
- DNPRINTF(SWM_D_EVENT, "buttonpress: window 0x%x, detail: %u\n",
- e->event, e->detail);
+ DNPRINTF(SWM_D_EVENT, "buttonpress: win (x,y): 0x%x (%d,%d), "
+ "detail: %u, time: %u, root (x,y): 0x%x (%d,%d), child: 0x%x, "
+ "state: %u, same_screen: %s\n", e->event, e->event_x, e->event_y,
+ e->detail, e->time, e->root, e->root_x, e->root_y, e->child,
+ e->state, YESNO(e->same_screen));
+
+ if (e->event == e->root) {
+ if (e->child != 0) {
+ win = find_window(e->child);
+ /* Pass ButtonPress to window if it isn't managed. */
+ if (win == NULL)
+ goto out;
+ } else {
+ /* Focus on empty region */
+ /* If no windows on region if its empty. */
+ r = root_to_region(e->root, SWM_CK_POINTER);
+ if (r && TAILQ_EMPTY(&r->ws->winlist)) {
+ old_r = root_to_region(e->root, SWM_CK_FOCUS);
+ if (old_r && old_r != r)
+ unfocus_win(old_r->ws->focus);
+
+ xcb_set_input_focus(conn,
+ XCB_INPUT_FOCUS_PARENT, e->root, e->time);
+
+ /* Clear bar since empty. */
+ bar_update();
+
+ handled = 1;
+ goto out;
+ }
+ }
+ } else {
+ win = find_window(e->event);
+ }
- if ((win = find_window(e->event)) == NULL)
+ if (win == NULL)
return;
last_event_time = e->time;
handled = 1;
}
+out:
if (!handled) {
DNPRINTF(SWM_D_EVENT, "buttonpress: passing to window.\n");
+ /* Replay event to event window */
xcb_allow_events(conn, XCB_ALLOW_REPLAY_POINTER, e->time);
} else {
DNPRINTF(SWM_D_EVENT, "buttonpress: handled.\n");
+ /* Unfreeze grab events. */
+ xcb_allow_events(conn, XCB_ALLOW_SYNC_POINTER, e->time);
}
xcb_flush(conn);
wc[i++] = e->stack_mode;
}
- if (mask != 0)
+ if (mask != 0) {
xcb_configure_window(conn, e->window, mask, wc);
+ xcb_flush(conn);
+ }
} else if ((!win->manual || win->quirks & SWM_Q_ANYWHERE) &&
!(win->ewmh_flags & EWMH_F_FULLSCREEN)) {
if (win->ws->r)
win->g_floatvalid = 1;
- if (win->floating && r) {
+ if (win->floating && r && (win->transient ||
+ win->ws->cur_layout != &layouts[SWM_MAX_STACK])) {
WIDTH(win) = win->g_float.w;
HEIGHT(win) = win->g_float.h;
config_win(win, e);
xcb_flush(conn);
}
+
+ DNPRINTF(SWM_D_EVENT, "configurerequest: done.\n");
}
void
enternotify(xcb_enter_notify_event_t *e)
{
struct ws_win *win;
+ struct swm_region *old_r, *r;
DNPRINTF(SWM_D_FOCUS, "enternotify: time: %u, win (x,y): 0x%x "
"(%d,%d), mode: %s(%d), detail: %s(%d), root (x,y): 0x%x (%d,%d), "
return;
}
+ last_event_time = e->time;
+
if ((win = find_window(e->event)) == NULL) {
- DNPRINTF(SWM_D_EVENT, "enternotify: window is NULL; ignoring\n");
+ if (e->event == e->root) {
+ /* If no windows on pointer region, then focus root. */
+ r = root_to_region(e->root, SWM_CK_POINTER);
+ if (TAILQ_EMPTY(&r->ws->winlist)) {
+ old_r = root_to_region(e->root, SWM_CK_FOCUS);
+ if (old_r && old_r != r)
+ unfocus_win(old_r->ws->focus);
+
+ xcb_set_input_focus(conn,
+ XCB_INPUT_FOCUS_PARENT, e->root, e->time);
+
+ /* Clear bar since empty. */
+ bar_update();
+
+ focus_flush();
+ }
+ } else {
+ DNPRINTF(SWM_D_EVENT, "enternotify: window is NULL; "
+ "ignoring\n");
+ }
return;
}
- last_event_time = e->time;
-
focus_win(get_focus_magic(win));
xcb_flush(conn);
if (win->ws->focus_pending == win) {
focus_win(win);
win->ws->focus_pending = NULL;
+ focus_flush();
}
}
win = manage_window(e->window,
(war->map_state == XCB_MAP_STATE_VIEWABLE));
+ /* The new window should get focus; prepare. */
+ if (focus_mode != SWM_FOCUS_FOLLOW)
+ win->ws->focus_pending = get_focus_magic(win);
+
/* All windows need to be mapped if they are in the current workspace.*/
if (win->ws->r)
stack();
- /* The new window should get focus. */
- if (focus_mode != SWM_FOCUS_FOLLOW)
- win->ws->focus_pending = get_focus_magic(win);
-
/* Ignore EnterNotify to handle the mapnotify without interference. */
if (focus_mode == SWM_FOCUS_DEFAULT)
event_drain(XCB_ENTER_NOTIFY);
name = get_atom_name(e->atom);
DNPRINTF(SWM_D_EVENT, "propertynotify: window: 0x%x, atom: %s(%u), "
- "time: %#x\n", e->window, name, e->atom, e->time);
+ "time: %#x, state: %u\n", e->window, name, e->atom, e->time,
+ e->state);
free(name);
#endif
win = find_window(e->window);
DNPRINTF(SWM_D_EVENT, "unmapnotify: window: 0x%x\n", e->window);
- /* determine if we need to help unmanage this window */
+ /* If we aren't managing the window, then ignore. */
win = find_window(e->window);
if (win == NULL)
return;
ws = win->ws;
- if (getstate(e->window) == XCB_ICCCM_WM_STATE_NORMAL) {
- win->mapped = 0;
+ if (getstate(e->window) != XCB_ICCCM_WM_STATE_ICONIC)
set_win_state(win, XCB_ICCCM_WM_STATE_ICONIC);
- /* If we were focused, make sure we focus on something else. */
- if (win == ws->focus)
- if (focus_mode != SWM_FOCUS_FOLLOW)
+ if (win->mapped) {
+ /* window unmapped itself */
+ /* do unmap/unfocus/restack and unmanage */
+ win->mapped = 0;
+
+ /* If win was focused, make sure to focus on something else. */
+ if (win == ws->focus) {
+ if (focus_mode != SWM_FOCUS_FOLLOW) {
ws->focus_pending = get_focus_prev(win);
+ DNPRINTF(SWM_D_EVENT, "unmapnotify: "
+ "focus_pending: 0x%x\n",
+ WINID(ws->focus_pending));
+ }
+
+ unfocus_win(win);
+ }
- unfocus_win(win);
unmanage_window(win);
- stack();
- DNPRINTF(SWM_D_EVENT, "unmapnotify: focus_pending: 0x%x\n",
- ws->focus_pending->id);
+ if (ws->r)
+ stack();
- if (focus_mode != SWM_FOCUS_FOLLOW) {
+ if (focus_mode == SWM_FOCUS_FOLLOW) {
+ if (ws->r)
+ focus_win(get_pointer_win(ws->r->s->root));
+ } else {
if (ws->focus_pending) {
focus_win(ws->focus_pending);
ws->focus_pending = NULL;
}
}
-
- focus_flush();
}
+
+ if (getstate(e->window) == XCB_ICCCM_WM_STATE_NORMAL)
+ set_win_state(win, XCB_ICCCM_WM_STATE_ICONIC);
+
+ focus_flush();
}
#if 0
if (win == NULL) {
if (e->type == ewmh[_NET_ACTIVE_WINDOW].atom) {
+ /* Manage the window with maprequest. */
DNPRINTF(SWM_D_EVENT, "clientmessage: request focus on "
"unmanaged window.\n");
mre.window = e->window;
stack();
}
- xcb_flush(conn);
+ focus_flush();
}
void
enable_wm(void)
{
int num_screens, i;
- const uint32_t val = XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT;
+ const uint32_t val = XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT |
+ XCB_EVENT_MASK_ENTER_WINDOW;
xcb_screen_t *sc;
xcb_void_cookie_t wac;
xcb_generic_error_t *error;
free(error);
return 1;
}
+
+ /* click to focus on empty region */
+ xcb_grab_button(conn, 1, sc->root, BUTTONMASK,
+ XCB_GRAB_MODE_SYNC, XCB_GRAB_MODE_ASYNC, XCB_WINDOW_NONE,
+ XCB_CURSOR_NONE, XCB_BUTTON_INDEX_1, XCB_BUTTON_MASK_ANY);
}
return 0;
void
grab_windows(void)
{
- xcb_window_t *wins = NULL;
+ xcb_window_t *wins = NULL, trans;
int no;
int i, j, num_screens;
uint16_t state, manage, mapped;
no = xcb_query_tree_children_length(qtr);
/* attach windows to a region */
/* normal windows */
+ DNPRINTF(SWM_D_INIT, "grab_windows: grab top level windows.\n");
for (j = 0; j < no; j++) {
c = xcb_get_window_attributes(conn, wins[j]);
r = xcb_get_window_attributes_reply(conn, c, NULL);
- if (!r)
+ if (!r) {
+ DNPRINTF(SWM_D_INIT, "grab_windows: skip %#x; "
+ "doesn't exist.\n", wins[j]);
continue;
+ }
if (r->override_redirect) {
+ DNPRINTF(SWM_D_INIT, "grab_windows: skip %#x; "
+ "override_redirect set.\n", wins[j]);
free(r);
continue;
}
pc = xcb_icccm_get_wm_transient_for(conn, wins[j]);
if (xcb_icccm_get_wm_transient_for_reply(conn, pc,
- &wins[j], NULL)) {
+ &trans, NULL)) {
+ DNPRINTF(SWM_D_INIT, "grab_windows: skip %#x; "
+ "is transient for %#x.\n", wins[j], trans);
free(r);
continue;
}
state = getstate(wins[j]);
- manage = state == XCB_ICCCM_WM_STATE_ICONIC;
+ manage = state != XCB_ICCCM_WM_STATE_WITHDRAWN;
mapped = r->map_state != XCB_MAP_STATE_UNMAPPED;
if (mapped || manage)
manage_window(wins[j], mapped);
free(r);
}
/* transient windows */
+ DNPRINTF(SWM_D_INIT, "grab_windows: grab transient windows.\n");
for (j = 0; j < no; j++) {
c = xcb_get_window_attributes(conn, wins[j]);
r = xcb_get_window_attributes_reply(conn, c, NULL);
- if (!r)
+ if (!r) {
+ DNPRINTF(SWM_D_INIT, "grab_windows: skip %#x; "
+ "doesn't exist.\n", wins[j]);
continue;
+ }
if (r->override_redirect) {
+ DNPRINTF(SWM_D_INIT, "grab_windows: skip %#x; "
+ "override_redirect set.\n", wins[j]);
free(r);
continue;
}
free(r);
state = getstate(wins[j]);
- manage = state == XCB_ICCCM_WM_STATE_ICONIC;
+ manage = state != XCB_ICCCM_WM_STATE_WITHDRAWN;
mapped = r->map_state != XCB_MAP_STATE_UNMAPPED;
pc = xcb_icccm_get_wm_transient_for(conn, wins[j]);
if (xcb_icccm_get_wm_transient_for_reply(conn, pc,
- &wins[j], NULL) && manage)
+ &trans, NULL) && manage)
manage_window(wins[j], mapped);
}
free(qtr);
free(evt);
}
- /* if we are being restarted go focus on first window */
- if (winfocus) {
+ /* If just (re)started, set default focus if needed. */
+ if (winfocus && focus_mode == SWM_FOCUS_MANUAL) {
rr = winfocus->ws->r;
if (rr == NULL) {
/* not a visible window */
winfocus = NULL;
continue;
}
- /* move pointer to first screen if multi screen */
- if (num_screens > 1 || outputs > 1)
- xcb_warp_pointer(conn, XCB_WINDOW_NONE,
- rr->s[0].root, 0, 0, 0, 0, X(rr),
- Y(rr) + (bar_enabled ? bar_height : 0));
focus_win(get_region_focus(rr));
focus_flush();