#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)
xcb_atom_t a_swm_ws;
volatile sig_atomic_t running = 1;
volatile sig_atomic_t restart_wm = 0;
+xcb_timestamp_t last_event_time = 0;
int outputs = 0;
-/*int last_focus_event = FocusOut;*/
int other_wm;
int ss_enabled = 0;
int xrandr_support;
Display *display;
xcb_connection_t *conn;
xcb_key_symbols_t *syms;
-xcb_timestamp_t last_event_time;
int cycle_empty = 0;
int cycle_visible = 0;
}
void
-update_iconic(struct ws_win *win, int newv)
+set_swm_iconic(struct ws_win *win, int newv)
{
int32_t v = newv;
if (title_class_enabled) {
strlcat(fmtnew, "+C", sz);
- if (title_name_enabled == 0)
+ if (!title_name_enabled)
strlcat(fmtnew, "+4<", sz);
}
size_t len;
char *b;
- if (bar_enabled == 0)
+ if (!bar_enabled)
return;
if (bar_extra && bar_extra_running) {
/* ignore short reads; it'll correct itself */
int i, num_screens;
/* do this here because the conf file is in memory */
- if (bar_extra && bar_extra_running == 0 && bar_argv[0]) {
+ if (bar_extra && !bar_extra_running && bar_argv[0]) {
/* launch external status app */
bar_extra_running = 1;
if (pipe(bar_pipe) == -1)
{
uint16_t data[2] = { state, XCB_ATOM_NONE };
- DNPRINTF(SWM_D_EVENT, "set_win_state: window: 0x%x\n", win->id);
+ DNPRINTF(SWM_D_EVENT, "set_win_state: window: 0x%x, state: %u\n",
+ win->id, state);
if (win == NULL)
return;
int count = 0;
TAILQ_FOREACH(win, &ws->winlist, entry) {
- if (count_transient == 0 && win->floating)
+ if (!count_transient && win->floating)
continue;
- if (count_transient == 0 && win->transient)
+ if (!count_transient && win->transient)
continue;
if (win->iconic)
continue;
}
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;
int i, num_screens;
xcb_query_pointer_reply_t *qpr;
+ xcb_get_input_focus_reply_t *gifr;
DNPRINTF(SWM_D_MISC, "root_to_region: window: 0x%x\n", root);
if (screens[i].root == root)
break;
- qpr = xcb_query_pointer_reply(conn, xcb_query_pointer(conn,
- screens[i].root), NULL);
+ 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;
- if (qpr) {
- DNPRINTF(SWM_D_MISC, "root_to_region: pointer: (%d,%d)\n",
- qpr->root_x, qpr->root_y);
- /* choose a region based on pointer location */
- 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))
- break;
- free(qpr);
+ 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);
+ 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))
+ break;
+ free(qpr);
+ }
+ }
+
+ /* Last resort. */
+ if (r == NULL && check & SWM_CK_FALLBACK)
r = TAILQ_FIRST(&screens[i].rl);
return (r);
get_focus_magic(struct ws_win *win)
{
struct ws_win *parent = NULL;
+ struct ws_win *child = NULL;
DNPRINTF(SWM_D_FOCUS, "get_focus_magic: window: 0x%x\n", WINID(win));
if (win == NULL)
if (win->transient) {
parent = find_window(win->transient);
- /* If parent prefers focus elsewhere, then do so. */
- if (parent && parent->focus_child) {
- if (validate_win(parent->focus_child) == 0)
- win = parent->focus_child;
+ /* If parent prefers focus elsewhere, then try to do so. */
+ if (parent && (child = parent->focus_child)) {
+ if (validate_win(child) == 0 && child->mapped)
+ win = child;
else
parent->focus_child = NULL;
}
}
- /* If this window prefers focus elsewhere, then do so. */
- if (win->focus_child) {
- if (validate_win(win->focus_child) == 0)
- win = win->focus_child;
+ /* If this window prefers focus elsewhere, then try to do so. */
+ if ((child = win->focus_child)) {
+ if (validate_win(child) == 0 && child->mapped)
+ win = child;
else
win->focus_child = NULL;
}
TAILQ_FOREACH(win, &old_ws->winlist, entry)
unmap_window(win);
- new_ws->focus_pending = get_region_focus(new_ws->r);
+ if (focus_mode != SWM_FOCUS_FOLLOW) {
+ new_ws->focus_pending = get_region_focus(new_ws->r);
- if (new_ws->focus_pending) {
/* if workspaces were swapped, then don't wait to set focus */
- if (old_ws->r)
- focus_win(new_ws->focus);
- } else {
- /* make sure bar gets updated if ws is empty */
- bar_update();
+ if (old_ws->r) {
+ if (new_ws->focus_pending) {
+ focus_win(new_ws->focus_pending);
+ } 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");
};
if (!cycle_all &&
- (cycle_empty == 0 && TAILQ_EMPTY(&s->ws[a.id].winlist)))
+ (!cycle_empty && TAILQ_EMPTY(&s->ws[a.id].winlist)))
continue;
- if (cycle_visible == 0 && s->ws[a.id].r != NULL)
+ if (!cycle_visible && s->ws[a.id].r != NULL)
continue;
switchws(r, &a);
void
cyclescr(struct swm_region *r, union arg *args)
{
+ struct ws_win *nfw;
struct swm_region *rr = NULL;
- int i, x, y, num_screens;
+ int i, num_screens;
num_screens = xcb_setup_roots_length(xcb_get_setup(conn));
/* do nothing if we don't have more than one screen */
if (rr == NULL)
return;
- /* move mouse to region */
- x = X(rr) + 1;
- y = Y(rr) + 1 + (bar_enabled ? bar_height : 0);
- xcb_warp_pointer(conn, XCB_WINDOW_NONE, rr->s[i].root, 0, 0, 0, 0,
- x, y);
-
- rr->ws->focus = 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);
- if (rr->ws->focus) {
- /* move to focus window */
- x = X(rr->ws->focus) + 1;
- y = Y(rr->ws->focus) + 1;
- xcb_warp_pointer(conn, XCB_WINDOW_NONE, rr->s[i].root, 0, 0, 0,
- 0, x, y);
+ /* Clear bar since empty. */
+ bar_update();
}
focus_flush();
/* make sure there is at least one uniconified window */
all_iconics = 1;
TAILQ_FOREACH(winfocus, wl, entry)
- if (winfocus->iconic == 0) {
+ if (!winfocus->iconic) {
all_iconics = 0;
break;
}
while (winfocus != cur_focus) {
if (winfocus == NULL)
winfocus = TAILQ_LAST(wl, ws_win_list);
- if (winfocus->iconic == 0)
+ if (!winfocus->iconic)
break;
winfocus = TAILQ_PREV(winfocus, ws_win_list,
entry);
while (winfocus != cur_focus) {
if (winfocus == NULL)
winfocus = TAILQ_FIRST(wl);
- if (winfocus->iconic == 0)
+ if (!winfocus->iconic)
break;
winfocus = TAILQ_NEXT(winfocus, entry);
}
return;
TAILQ_FOREACH(win, &ws->winlist, entry)
- if (win->transient == 0 && win->floating == 0
- && win->iconic == 0)
+ if (!win->transient && !win->floating && !win->iconic)
break;
if (win == NULL)
/* stack all the tiled windows */
i = j = 0, s = stacks;
TAILQ_FOREACH(win, &ws->winlist, entry) {
- if (win->transient != 0 || win->floating != 0)
+ if (win->transient || win->floating)
continue;
- if (win->iconic != 0)
+ if (win->iconic)
continue;
if (win->ewmh_flags & EWMH_F_FULLSCREEN) {
else
win_g.y += last_h + 2 * border_width;
- if (disable_border && bar_enabled == 0 && winno == 1){
+ if (disable_border && !bar_enabled && winno == 1){
bordered = 0;
win_g.w += 2 * border_width;
win_g.h += 2 * border_width;
notiles:
/* now, stack all the floaters and transients */
TAILQ_FOREACH(win, &ws->winlist, entry) {
- if (win->transient == 0 && win->floating == 0)
+ if (!win->transient && !win->floating)
continue;
- if (win->iconic == 1)
+ if (win->iconic)
continue;
if (win->ewmh_flags & EWMH_F_FULLSCREEN) {
fs_win = win;
continue;
}
- if (win->floating && win->floatmaxed == 0 ) {
+ if (win->floating && !win->floatmaxed ) {
/*
* retain geometry for retrieval on exit from
* max_stack mode
{
int wsid = args->id;
struct ws_win *win = NULL, *parent;
- struct workspace *ws, *nws;
+ struct workspace *ws, *nws, *pws;
char ws_idx_str[SWM_PROPLEN];
- union arg a;
if (wsid >= workspace_limit)
return;
win = r->ws->focus;
else
return;
- if (win == NULL)
- return;
+
if (win->ws->idx == wsid)
return;
- DNPRINTF(SWM_D_MOVE, "send_to_ws: window: 0x%x\n", win->id);
+ DNPRINTF(SWM_D_MOVE, "send_to_ws: win 0x%x, ws %d -> %d\n", win->id,
+ win->ws->idx, wsid);
ws = win->ws;
nws = &win->s->ws[wsid];
- 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;
+ /* Update the window's workspace property: _SWM_WS */
+ if (snprintf(ws_idx_str, SWM_PROPLEN, "%d", nws->idx) < SWM_PROPLEN) {
+ if (focus_mode != SWM_FOCUS_FOLLOW)
+ ws->focus_pending = get_focus_prev(win);
+
+ /* Move the parent if this is a transient window. */
+ if (win->transient) {
+ parent = find_window(win->transient);
+ if (parent) {
+ pws = parent->ws;
+ /* Set new focus in parent's ws if needed. */
+ if (pws->focus == parent) {
+ if (focus_mode != SWM_FOCUS_FOLLOW)
+ pws->focus_pending =
+ get_focus_prev(parent);
+
+ unfocus_win(parent);
+
+ if (focus_mode != SWM_FOCUS_FOLLOW)
+ pws->focus = pws->focus_pending;
+
+ if (focus_mode != SWM_FOCUS_FOLLOW)
+ pws->focus_pending = NULL;
+ }
+
+ /* Don't unmap parent if new ws is visible */
+ if (nws->r == NULL)
+ unmap_window(parent);
+
+ /* Transfer */
+ TAILQ_REMOVE(&ws->winlist, parent, entry);
+ TAILQ_INSERT_TAIL(&nws->winlist, parent, entry);
+ parent->ws = nws;
+
+ DNPRINTF(SWM_D_PROP, "send_to_ws: set "
+ "property: _SWM_WS: %s\n", ws_idx_str);
+ xcb_change_property(conn, XCB_PROP_MODE_REPLACE,
+ parent->id, a_swm_ws, XCB_ATOM_STRING, 8,
+ strlen(ws_idx_str), ws_idx_str);
+ }
}
- }
- unmap_window(win);
- TAILQ_REMOVE(&ws->winlist, win, entry);
- TAILQ_INSERT_TAIL(&nws->winlist, win, entry);
- if (TAILQ_EMPTY(&ws->winlist))
- r->ws->focus = NULL;
- win->ws = nws;
- /* Try to update the window's workspace property */
- if (snprintf(ws_idx_str, SWM_PROPLEN, "%d", nws->idx) < SWM_PROPLEN) {
+ unfocus_win(win);
+
+ /* Don't unmap if new ws is visible */
+ if (nws->r == NULL)
+ unmap_window(win);
+
+ /* Transfer */
+ TAILQ_REMOVE(&ws->winlist, win, entry);
+ TAILQ_INSERT_TAIL(&nws->winlist, win, entry);
+ win->ws = nws;
+
+ /* Set focus on new ws. */
+ unfocus_win(nws->focus);
+ nws->focus = win;
+
DNPRINTF(SWM_D_PROP, "send_to_ws: set property: _SWM_WS: %s\n",
ws_idx_str);
xcb_change_property(conn, XCB_PROP_MODE_REPLACE, win->id,
a_swm_ws, XCB_ATOM_STRING, 8, strlen(ws_idx_str),
ws_idx_str);
- }
- stack();
- bar_update();
+ /* Restack and set new focus. */
+ stack();
- focus_flush();
+ if (focus_mode != SWM_FOCUS_FOLLOW) {
+ focus_win(ws->focus_pending);
+ ws->focus_pending = NULL;
+ }
+
+ focus_flush();
+ }
+
+ DNPRINTF(SWM_D_MOVE, "send_to_ws: done.\n");
}
void
r->ws->always_raise = !r->ws->always_raise;
/* bring floaters back to top */
- if (r->ws->always_raise == 0)
+ if (!r->ws->always_raise)
stack();
focus_flush();
if (r->ws->focus == NULL)
return;
- update_iconic(r->ws->focus, 1);
+ set_swm_iconic(r->ws->focus, 1);
xcb_flush(conn);
}
TAILQ_FOREACH(win, &r->ws->winlist, entry) {
if (win->ws == NULL)
continue; /* should never happen */
- if (win->iconic == 0)
+ if (!win->iconic)
continue;
count++;
}
TAILQ_FOREACH(win, &r->ws->winlist, entry) {
if (win->ws == NULL)
continue; /* should never happen */
- if (win->iconic == 0)
+ if (!win->iconic)
continue;
name = get_win_name(win->id);
i = 1;
TAILQ_FOREACH(win, &r->ws->winlist, entry) {
- if (win->iconic == 1)
+ if (win->iconic)
continue;
sw = calloc(1, sizeof(struct search_window));
DNPRINTF(SWM_D_MISC, "search_resp_uniconify: resp: %s\n", resp);
TAILQ_FOREACH(win, &search_r->ws->winlist, entry) {
- if (win->iconic == 0)
+ if (!win->iconic)
continue;
name = get_win_name(win->id);
if (name == NULL)
free(name);
if (strncmp(s, resp, len) == 0) {
/* XXX this should be a callback to generalize */
- update_iconic(win, 0);
+ 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
"transient: 0x%x\n", win->id, YESNO(win->floating),
win->transient);
- if (!(win->transient != 0 || win->floating != 0))
+ if (!win->transient && !win->floating)
return;
/* reject resizes in max mode for floaters (transient ok) */
return;
win->manual = 1;
- if (win->floating == 0 && !win->transient) {
+ if (!win->floating && !win->transient) {
store_float_geom(win, r);
ewmh_update_win_state(win, ewmh[_NET_WM_STATE_ABOVE].atom,
_NET_WM_STATE_ADD);
else
return;
- if (!(win->transient != 0 || win->floating != 0))
+ if (!win->transient && !win->floating)
return;
move(win, args);
case SWM_S_FOCUS_MODE:
if (!strcmp(value, "default"))
focus_mode = SWM_FOCUS_DEFAULT;
- else if (!strcmp(value, "follow_cursor"))
+ else if (!strcmp(value, "follow") ||
+ !strcmp(value, "follow_cursor"))
focus_mode = SWM_FOCUS_FOLLOW;
else if (!strcmp(value, "manual"))
focus_mode = SWM_FOCUS_MANUAL;
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;
free(p);
p = NULL;
} else if ((ws_idx = get_ws_idx(win->id)) != -1 &&
- win->transient == 0) {
+ !win->transient) {
/* _SWM_WS is set; use that. */
win->ws = &r->s->ws[ws_idx];
} else if (trans && (ww = find_window(trans)) != NULL) {
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));
}
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)
{
struct ws_win *win;
- DNPRINTF(SWM_D_EVENT, "configurenotify: window: 0x%x\n",
- e->window);
+ DNPRINTF(SWM_D_EVENT, "configurenotify: win 0x%x, event win: 0x%x, "
+ "(x,y) WxH: (%d,%d) %ux%u, border: %u, above_sibling: 0x%x, "
+ "override_redirect: %s\n", e->window, e->event, e->x, e->y,
+ e->width, e->height, e->border_width, e->above_sibling,
+ YESNO(e->override_redirect));
win = find_window(e->window);
if (win) {
return;
}
- /* If we were focused, make sure we focus on something else. */
- if (win == win->ws->focus)
- win->ws->focus_pending = get_focus_prev(win);
+ if (focus_mode != SWM_FOCUS_FOLLOW) {
+ /* If we were focused, make sure we focus on something else. */
+ if (win == win->ws->focus)
+ win->ws->focus_pending = get_focus_prev(win);
+ }
unmanage_window(win);
stack();
- if (win->ws->focus_pending) {
- focus_win(win->ws->focus_pending);
- win->ws->focus_pending = NULL;
+ if (focus_mode != SWM_FOCUS_FOLLOW) {
+ if (win->ws->focus_pending) {
+ focus_win(win->ws->focus_pending);
+ win->ws->focus_pending = NULL;
+ }
}
free_window(win);
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);
win->mapped = 1;
set_win_state(win, XCB_ICCCM_WM_STATE_NORMAL);
- if (win->ws->focus_pending == win) {
- focus_win(win);
- win->ws->focus_pending = NULL;
+ if (focus_mode != SWM_FOCUS_FOLLOW) {
+ if (win->ws->focus_pending == win) {
+ focus_win(win);
+ win->ws->focus_pending = NULL;
+ }
}
xcb_flush(conn);
stack();
/* The new window should get focus. */
- win->ws->focus_pending = get_focus_magic(win);
+ 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)
last_event_time = e->time;
if (e->atom == a_swm_iconic) {
- if (e->state == XCB_PROPERTY_DELETE) {
- /* The window is no longer iconic, restack ws. */
- win->ws->focus_pending = get_focus_magic(win);
- stack();
+ if (e->state == XCB_PROPERTY_NEW_VALUE) {
+ if (focus_mode != SWM_FOCUS_FOLLOW)
+ win->ws->focus_pending = get_focus_prev(win);
- /* Flush EnterNotify for mapnotify, if needed. */
- focus_flush();
- return;
- } else if (e->state == XCB_PROPERTY_NEW_VALUE) {
- win->ws->focus_pending = get_focus_prev(win);
unfocus_win(win);
unmap_window(win);
if (win->ws->r) {
stack();
- focus_win(win->ws->focus_pending);
- win->ws->focus_pending = NULL;
+ if (focus_mode != SWM_FOCUS_FOLLOW) {
+ focus_win(win->ws->focus_pending);
+ win->ws->focus_pending = NULL;
+ }
focus_flush();
}
+ } else if (e->state == XCB_PROPERTY_DELETE) {
+ /* The window is no longer iconic, restack ws. */
+ if (focus_mode != SWM_FOCUS_FOLLOW)
+ win->ws->focus_pending = get_focus_magic(win);
+
+ stack();
+
+ /* Flush EnterNotify for mapnotify, if needed. */
+ focus_flush();
}
- } else if (e->atom == a_state && e->state == XCB_PROPERTY_NEW_VALUE) {
+ } else if (e->atom == a_state) {
/* State just changed, make sure it gets focused if mapped. */
- if (win->mapped && win->ws->focus_pending == win) {
- win->ws->focus_pending = NULL;
- focus_win(win);
+ if (e->state == XCB_PROPERTY_NEW_VALUE) {
+ if (focus_mode != SWM_FOCUS_FOLLOW) {
+ if (win->mapped &&
+ win->ws->focus_pending == win) {
+ focus_win(win->ws->focus_pending);
+ win->ws->focus_pending = NULL;
+ }
+ }
}
- }
-
- switch (e->atom) {
- case XCB_ATOM_WM_CLASS:
- case XCB_ATOM_WM_NAME:
+ } else if (e->atom == XCB_ATOM_WM_CLASS ||
+ e->atom == XCB_ATOM_WM_NAME) {
bar_update();
- break;
- default:
- break;
}
xcb_flush(conn);
unmapnotify(xcb_unmap_notify_event_t *e)
{
struct ws_win *win;
+ struct workspace *ws;
DNPRINTF(SWM_D_EVENT, "unmapnotify: window: 0x%x\n", e->window);
if (win == NULL)
return;
+ ws = win->ws;
+
if (getstate(e->window) == XCB_ICCCM_WM_STATE_NORMAL) {
+ win->mapped = 0;
+ set_win_state(win, XCB_ICCCM_WM_STATE_ICONIC);
+
/* If we were focused, make sure we focus on something else. */
- if (win == win->ws->focus)
- win->ws->focus_pending = get_focus_prev(win);
+ if (win == ws->focus)
+ if (focus_mode != SWM_FOCUS_FOLLOW)
+ ws->focus_pending = get_focus_prev(win);
+ unfocus_win(win);
unmanage_window(win);
stack();
- if (win->ws->focus_pending) {
- focus_win(win->ws->focus_pending);
- win->ws->focus_pending = NULL;
+ DNPRINTF(SWM_D_EVENT, "unmapnotify: focus_pending: 0x%x\n",
+ ws->focus_pending->id);
+
+ if (focus_mode != SWM_FOCUS_FOLLOW) {
+ if (ws->focus_pending) {
+ focus_win(ws->focus_pending);
+ ws->focus_pending = NULL;
+ }
}
focus_flush();
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;
while (running) {
while ((evt = xcb_poll_for_event(conn))) {
- if (running == 0)
+ if (!running)
goto done;
event_handle(evt);
free(evt);
if (errno != EINTR) {
DNPRINTF(SWM_D_MISC, "select failed");
}
- if (restart_wm == 1)
+ if (restart_wm)
restart(NULL, NULL);
- if (search_resp == 1)
+ if (search_resp)
search_do_resp();
- if (running == 0)
+ if (!running)
goto done;
if (bar_alarm) {
bar_alarm = 0;