* Copyright (c) 2009 Pierre-Yves Ritschard <pyr@spootnik.org>
* Copyright (c) 2010 Tuukka Kataja <stuge@xor.fi>
* Copyright (c) 2011 Jason L. Wright <jason@thought.net>
- * Copyright (c) 2011-2012 Reginald Kennedy <rk@rejii.com>
+ * Copyright (c) 2011-2013 Reginald Kennedy <rk@rejii.com>
* Copyright (c) 2011-2012 Lawrence Teo <lteo@lteo.net>
* Copyright (c) 2011-2012 Tiago Cunha <tcunha@gmx.com>
- * Copyright (c) 2012 David Hill <dhill@mindcry.org>
+ * Copyright (c) 2012-2013 David Hill <dhill@mindcry.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
#define SWM_ARG_ID_CYCLERG_DOWN (43)
#define SWM_ARG_ID_CYCLEWS_UP_ALL (44)
#define SWM_ARG_ID_CYCLEWS_DOWN_ALL (45)
+#define SWM_ARG_ID_CYCLEWS_MOVE_UP (46)
+#define SWM_ARG_ID_CYCLEWS_MOVE_DOWN (47)
#define SWM_ARG_ID_STACKINC (50)
#define SWM_ARG_ID_STACKDEC (51)
#define SWM_ARG_ID_SS_ALL (60)
#define SWM_Q_XTERM_FONTADJ (1<<3) /* adjust xterm fonts when resizing */
#define SWM_Q_FULLSCREEN (1<<4) /* remove border */
#define SWM_Q_FOCUSPREV (1<<5) /* focus on caller */
+#define SWM_Q_NOFOCUSONMAP (1<<6) /* Don't focus on window when mapped. */
+#define SWM_Q_FOCUSONMAP_SINGLE (1<<7) /* Only focus if single win of type. */
};
TAILQ_HEAD(quirk_list, quirk);
struct quirk_list quirks = TAILQ_HEAD_INITIALIZER(quirks);
KF_WS_22,
KF_WS_NEXT,
KF_WS_NEXT_ALL,
+ KF_WS_NEXT_MOVE,
KF_WS_PREV,
KF_WS_PREV_ALL,
+ KF_WS_PREV_MOVE,
KF_WS_PRIOR,
KF_DUMPWINS, /* MUST BE LAST */
KF_INVALID
struct ws_win *get_region_focus(struct swm_region *);
int get_region_index(struct swm_region *);
xcb_screen_t *get_screen(int);
+int get_screen_count(void);
#ifdef SWM_DEBUG
char *get_stack_mode_name(uint8_t);
#endif
void motionnotify(xcb_motion_notify_event_t *);
void move(struct ws_win *, union arg *);
void move_step(struct swm_region *, union arg *);
-uint32_t name_to_pixel(const char *);
+uint32_t name_to_pixel(int, const char *);
void name_workspace(struct swm_region *, union arg *);
void new_region(struct swm_screen *, int, int, int, int);
int parsekeys(char *, unsigned int, unsigned int *, KeySym *);
void screenchange(xcb_randr_screen_change_notify_event_t *);
void scan_xrandr(int);
void search_do_resp(void);
-void search_resp_name_workspace(const char *, unsigned long);
+void search_resp_name_workspace(const char *, size_t);
void search_resp_search_window(const char *);
void search_resp_search_workspace(const char *);
-void search_resp_uniconify(const char *, unsigned long);
+void search_resp_uniconify(const char *, size_t);
void search_win(struct swm_region *, union arg *);
void search_win_cleanup(void);
void search_workspace(struct swm_region *, union arg *);
}
int
+get_screen_count(void)
+{
+ const xcb_setup_t *r;
+
+ if ((r = xcb_get_setup(conn)) == NULL) {
+ DNPRINTF(SWM_D_MISC, "get_screen_count: xcb_get_setup\n");
+ check_conn();
+ }
+
+ return xcb_setup_roots_length(r);
+}
+
+int
get_region_index(struct swm_region *r)
{
struct swm_region *rr;
for (i = 0; i < LENGTH(ewmh); i++)
ewmh[i].atom = get_atom_from_string(ewmh[i].name);
- num_screens = xcb_setup_roots_length(xcb_get_setup(conn));
+ num_screens = get_screen_count();
for (i = 0; i < num_screens; i++) {
/* Support check window will be created by workaround(). */
sup_check = get_atom_from_string("_NET_SUPPORTING_WM_CHECK");
sup_list = get_atom_from_string("_NET_SUPPORTED");
- num_screens = xcb_setup_roots_length(xcb_get_setup(conn));
+ num_screens = get_screen_count();
for (i = 0; i < num_screens; i++) {
/* Get the support check window and destroy it */
}
uint32_t
-name_to_pixel(const char *colorname)
+name_to_pixel(int sidx, const char *colorname)
{
uint32_t result = 0;
char cname[32] = "#";
xcb_alloc_named_color_reply_t *nr;
uint16_t rr, gg, bb;
- screen = xcb_setup_roots_iterator(xcb_get_setup(conn)).data;
+ screen = get_screen(sidx);
cmap = screen->default_colormap;
/* color is in format rgb://rr/gg/bb */
{
int num_screens;
- num_screens = xcb_setup_roots_length(xcb_get_setup(conn));
+ num_screens = get_screen_count();
if (i > 0 && i <= num_screens) {
- screens[i - 1].c[c].pixel = name_to_pixel(val);
+ screens[i - 1].c[c].pixel = name_to_pixel(i - 1, val);
free(screens[i - 1].c[c].name);
if ((screens[i - 1].c[c].name = strdup(val)) == NULL)
err(1, "strdup");
} else if (i == -1) {
for (i = 0; i < num_screens; i++) {
- screens[i].c[c].pixel = name_to_pixel(val);
+ screens[i].c[c].pixel = name_to_pixel(0, val);
free(screens[i].c[c].name);
if ((screens[i].c[c].name = strdup(val)) == NULL)
err(1, "strdup");
int sidx, num_screens;
xcb_screen_t *screen;
- num_screens = xcb_setup_roots_length(xcb_get_setup(conn));
+ num_screens = get_screen_count();
if (sscanf(val, "screen[%d]:%ux%u+%u+%u", &sidx, &w, &h, &x, &y) != 5)
errx(1, "invalid custom region, "
"should be 'screen[<n>]:<n>x<n>+<n>+<n>");
for (i = 0; i < workspace_limit; i++)
urgent[i] = 0;
- num_screens = xcb_setup_roots_length(xcb_get_setup(conn));
+ num_screens = get_screen_count();
for (i = 0; i < num_screens; i++)
for (j = 0; j < workspace_limit; j++)
TAILQ_FOREACH(win, &screens[i].ws[j].winlist, entry) {
/* expand the format by first passing it through strftime(3) */
bar_fmt_expand(fmtexp, sizeof fmtexp);
- num_screens = xcb_setup_roots_length(xcb_get_setup(conn));
+ num_screens = get_screen_count();
for (i = 0; i < num_screens; i++) {
TAILQ_FOREACH(r, &screens[i].rl, entry) {
if (r->bar == NULL)
}
/* update bars as necessary */
- num_screens = xcb_setup_roots_length(xcb_get_setup(conn));
+ num_screens = get_screen_count();
for (i = 0; i < num_screens; i++)
TAILQ_FOREACH(tmpr, &screens[i].rl, entry)
if (tmpr->bar) {
struct ws_win *win;
int i, j, num_screens;
- num_screens = xcb_setup_roots_length(xcb_get_setup(conn));
+ num_screens = get_screen_count();
for (i = 0; i < num_screens; i++)
for (j = 0; j < workspace_limit; j++)
TAILQ_FOREACH(win, &screens[i].ws[j].winlist, entry)
DNPRINTF(SWM_D_MISC, "root_to_region: window: 0x%x\n", root);
- num_screens = xcb_setup_roots_length(xcb_get_setup(conn));
+ num_screens = get_screen_count();
for (i = 0; i < num_screens; i++)
if (screens[i].root == root)
break;
if (r == NULL && check & SWM_CK_FALLBACK)
r = TAILQ_FIRST(&screens[i].rl);
+ DNPRINTF(SWM_D_MISC, "root_to_region: idx: %d\n", get_region_index(r));
+
return (r);
}
struct ws_win *win;
int i, j, num_screens;
- num_screens = xcb_setup_roots_length(xcb_get_setup(conn));
+ num_screens = get_screen_count();
for (i = 0; i < num_screens; i++)
for (j = 0; j < workspace_limit; j++)
TAILQ_FOREACH(win, &screens[i].ws[j].unmanagedlist,
int i, j, num_screens;
xcb_query_tree_reply_t *r;
- num_screens = xcb_setup_roots_length(xcb_get_setup(conn));
+ num_screens = get_screen_count();
for (i = 0; i < num_screens; i++)
for (j = 0; j < workspace_limit; j++)
TAILQ_FOREACH(win, &screens[i].ws[j].winlist, entry)
if (win == NULL)
return;
- num_screens = xcb_setup_roots_length(xcb_get_setup(conn));
+ num_screens = get_screen_count();
for (i = 0; i < num_screens; i++)
TAILQ_FOREACH(r, &screens[i].rl, entry)
for (x = 0; x < workspace_limit; x++) {
if (testwin == NULL)
return (0);
- num_screens = xcb_setup_roots_length(xcb_get_setup(conn));
+ num_screens = get_screen_count();
for (i = 0; i < num_screens; i++)
TAILQ_FOREACH(r, &screens[i].rl, entry)
for (x = 0; x < workspace_limit; x++) {
int i, x, num_screens;
/* validate all ws */
- num_screens = xcb_setup_roots_length(xcb_get_setup(conn));
+ num_screens = get_screen_count();
for (i = 0; i < num_screens; i++)
TAILQ_FOREACH(r, &screens[i].rl, entry)
for (x = 0; x < workspace_limit; x++) {
if (old_r)
unfocus_win(old_r->ws->focus);
- xcb_set_input_focus(conn, XCB_INPUT_FOCUS_PARENT, r->s->root,
+ xcb_set_input_focus(conn, XCB_INPUT_FOCUS_PARENT, r->id,
XCB_CURRENT_TIME);
/* Clear bar since empty. */
this_r->ws = new_ws;
new_ws->r = this_r;
- /* Set focus_pending before stacking. */
- if (focus_mode != SWM_FOCUS_FOLLOW)
+ /* Set focus_pending before stacking, if needed. */
+ if (focus_mode != SWM_FOCUS_FOLLOW && (!new_ws->focus_pending ||
+ validate_win(new_ws->focus_pending)))
new_ws->focus_pending = get_region_focus(new_ws->r);
stack();
if (old_ws->r && focus_mode != SWM_FOCUS_FOLLOW) {
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);
+ new_ws->focus_pending = NULL;
}
}
- /* Clear bar if new ws is empty. */
- if (new_ws->focus_pending == NULL)
+ /* Clear bar and set focus on region input win if new ws is empty. */
+ if (new_ws->focus_pending == NULL && new_ws->focus == NULL) {
+ xcb_set_input_focus(conn, XCB_INPUT_FOCUS_PARENT, r->id,
+ XCB_CURRENT_TIME);
bar_draw();
+ }
focus_flush();
union arg a;
struct swm_screen *s = r->s;
int cycle_all = 0;
+ int move = 0;
DNPRINTF(SWM_D_WS, "cyclews: id: %d, screen[%d]:%dx%d+%d+%d, ws: %d\n",
args->id, r->s->idx, WIDTH(r), HEIGHT(r), X(r), Y(r), r->ws->idx);
a.id = r->ws->idx;
+
do {
switch (args->id) {
+ case SWM_ARG_ID_CYCLEWS_MOVE_UP:
+ move = 1;
+ /* FALLTHROUGH */
case SWM_ARG_ID_CYCLEWS_UP_ALL:
cycle_all = 1;
/* FALLTHROUGH */
case SWM_ARG_ID_CYCLEWS_UP:
- if (a.id < workspace_limit - 1)
- a.id++;
- else
- a.id = 0;
+ a.id = (a.id < workspace_limit - 1) ? a.id + 1 : 0;
break;
+ case SWM_ARG_ID_CYCLEWS_MOVE_DOWN:
+ move = 1;
+ /* FALLTHROUGH */
case SWM_ARG_ID_CYCLEWS_DOWN_ALL:
cycle_all = 1;
/* FALLTHROUGH */
case SWM_ARG_ID_CYCLEWS_DOWN:
- if (a.id > 0)
- a.id--;
- else
- a.id = workspace_limit - 1;
+ a.id = (a.id > 0) ? a.id - 1 : workspace_limit - 1;
break;
default:
return;
if (!cycle_visible && s->ws[a.id].r != NULL)
continue;
+ if (move)
+ send_to_ws(r, &a);
+
switchws(r, &a);
} while (a.id != r->ws->idx);
}
int ridx = args->id, i, num_screens;
struct swm_region *rr = NULL;
- num_screens = xcb_setup_roots_length(xcb_get_setup(conn));
+ num_screens = get_screen_count();
/* do nothing if we don't have more than one screen */
if (!(num_screens > 1 || outputs > 1))
return;
struct swm_region *rr = NULL;
int i, num_screens;
- num_screens = xcb_setup_roots_length(xcb_get_setup(conn));
+ num_screens = get_screen_count();
/* do nothing if we don't have more than one screen */
if (!(num_screens > 1 || outputs > 1))
return;
DNPRINTF(SWM_D_STACK, "stack: begin\n");
- num_screens = xcb_setup_roots_length(xcb_get_setup(conn));
+ num_screens = get_screen_count();
for (i = 0; i < num_screens; i++) {
#ifdef SWM_DEBUG
j = 0;
win = ws->focus_pending;
else if (ws->focus)
win = ws->focus;
+ else if (ws->focus_prev)
+ win = ws->focus_prev;
else
win = TAILQ_FIRST(&ws->winlist);
struct swm_region *rr = NULL;
union arg a;
- num_screens = xcb_setup_roots_length(xcb_get_setup(conn));
+ num_screens = get_screen_count();
/* do nothing if we don't have more than one screen */
if (!(num_screens > 1 || outputs > 1))
return;
unfocus_win(parent);
- if (focus_mode != SWM_FOCUS_FOLLOW)
+ 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 */
stack();
if (focus_mode != SWM_FOCUS_FOLLOW) {
- focus_win(ws->focus_pending);
- ws->focus_pending = NULL;
+ if (ws->focus_pending) {
+ focus_win(ws->focus_pending);
+ ws->focus_pending = NULL;
+ } else {
+ xcb_set_input_focus(conn,
+ XCB_INPUT_FOCUS_PARENT, r->id,
+ XCB_CURRENT_TIME);
+ }
}
focus_flush();
}
void
-search_resp_uniconify(const char *resp, unsigned long len)
+search_resp_uniconify(const char *resp, size_t len)
{
char *name;
struct ws_win *win;
}
void
-search_resp_name_workspace(const char *resp, unsigned long len)
+search_resp_name_workspace(const char *resp, size_t len)
{
struct workspace *ws;
{
ssize_t rbytes;
char *resp;
- unsigned long len;
+ size_t len;
DNPRINTF(SWM_D_MISC, "search_do_resp:\n");
int top = 0, left = 0, resizing;
int dx, dy;
xcb_cursor_t cursor;
- xcb_query_pointer_reply_t *xpr;
+ xcb_query_pointer_reply_t *xpr = NULL;
xcb_generic_event_t *evt;
xcb_motion_notify_event_t *mne;
xcb_timestamp_t timestamp = 0;
int move_stp = 0, moving;
struct swm_region *r = NULL;
- xcb_query_pointer_reply_t *qpr;
+ xcb_query_pointer_reply_t *qpr = NULL;
xcb_generic_event_t *evt;
xcb_motion_notify_event_t *mne;
{ "ws_22", switchws, {.id = 21} },
{ "ws_next", cyclews, {.id = SWM_ARG_ID_CYCLEWS_UP} },
{ "ws_next_all", cyclews, {.id = SWM_ARG_ID_CYCLEWS_UP_ALL} },
+ { "ws_next_move", cyclews, {.id = SWM_ARG_ID_CYCLEWS_MOVE_UP} },
{ "ws_prev", cyclews, {.id = SWM_ARG_ID_CYCLEWS_DOWN} },
{ "ws_prev_all", cyclews, {.id = SWM_ARG_ID_CYCLEWS_DOWN_ALL} },
+ { "ws_prev_move", cyclews, {.id = SWM_ARG_ID_CYCLEWS_MOVE_DOWN} },
{ "ws_prior", priorws, {0} },
{ "dumpwins", dumpwins, {0} }, /* MUST BE LAST */
{ "invalid key func", NULL, {0} },
for (kfid = 0; kfid < KF_INVALID; (kfid)++) {
if (strncasecmp(selector, keyfuncs[kfid].name,
SWM_FUNCNAME_LEN) == 0) {
- DNPRINTF(SWM_D_KEY, "setconfbinding: %s: match\n",
- selector);
+ DNPRINTF(SWM_D_KEY, "setconfbinding: %s: match "
+ "keyfunc\n", selector);
if (parsekeys(value, mod_key, &mod, &ks) == 0) {
setkeybinding(mod, ks, kfid, NULL);
return (0);
/* search by custom spawn name */
TAILQ_FOREACH(sp, &spawns, entry) {
if (strcasecmp(selector, sp->name) == 0) {
- DNPRINTF(SWM_D_KEY, "setconfbinding: %s: match\n",
- selector);
+ DNPRINTF(SWM_D_KEY, "setconfbinding: %s: match "
+ "spawn\n", selector);
if (parsekeys(value, mod_key, &mod, &ks) == 0) {
setkeybinding(mod, ks, KF_SPAWN_CUSTOM,
sp->name);
- /* Custom binding; validate spawn. */
- sp->flags ^= SWM_SPAWN_OPTIONAL;
return (0);
} else
return (1);
setkeybinding(MODKEY, XK_Left, KF_WS_PREV, NULL);
setkeybinding(MODKEY, XK_Up, KF_WS_NEXT_ALL, NULL);
setkeybinding(MODKEY, XK_Down, KF_WS_PREV_ALL, NULL);
+ setkeybinding(MODKEY_SHIFT, XK_Up, KF_WS_NEXT_MOVE,NULL);
+ setkeybinding(MODKEY_SHIFT, XK_Down, KF_WS_PREV_MOVE,NULL);
setkeybinding(MODKEY, XK_a, KF_WS_PRIOR, NULL);
#ifdef SWM_DEBUG
setkeybinding(MODKEY_SHIFT, XK_d, KF_DUMPWINS, NULL);
int
setkeymapping(char *selector, char *value, int flags)
{
- char keymapping_file[PATH_MAX];
+ char *keymapping_file;
/* suppress unused warnings since vars are needed */
(void)selector;
(void)flags;
DNPRINTF(SWM_D_KEY, "setkeymapping: enter\n");
- if (value[0] == '~')
- snprintf(keymapping_file, sizeof keymapping_file, "%s/%s",
- pwd->pw_dir, &value[1]);
- else
- strlcpy(keymapping_file, value, sizeof keymapping_file);
+
+ keymapping_file = expand_tilde(value);
+
clear_keys();
/* load new key bindings; if it fails, revert to default bindings */
if (conf_load(keymapping_file, SWM_CONF_KEYMAPPING)) {
clear_keys();
setup_keys();
}
+
+ free(keymapping_file);
+
DNPRINTF(SWM_D_KEY, "setkeymapping: leave\n");
return (0);
}
modifiers[2] = XCB_MOD_MASK_LOCK;
modifiers[3] = numlockmask | XCB_MOD_MASK_LOCK;
- num_screens = xcb_setup_roots_length(xcb_get_setup(conn));
+ num_screens = get_screen_count();
for (k = 0; k < num_screens; k++) {
if (TAILQ_EMPTY(&screens[k].rl))
continue;
xcb_ungrab_key(conn, XCB_GRAB_ANY, screens[k].root,
XCB_MOD_MASK_ANY);
RB_FOREACH(kp, key_tree, &keys) {
+ /* Skip unused ws binds. */
+ if ((int)kp->funcid > KF_WS_1 + workspace_limit - 1 &&
+ kp->funcid <= KF_WS_22)
+ continue;
+
+ /* Skip unused mvws binds. */
+ if ((int)kp->funcid > KF_MVWS_1 + workspace_limit - 1 &&
+ kp->funcid <= KF_MVWS_22)
+ continue;
+
if ((code = xcb_key_symbols_get_keycode(syms,
kp->keysym))) {
for (j = 0; j < LENGTH(modifiers); j++)
"XTERM_FONTADJ",
"FULLSCREEN",
"FOCUSPREV",
+ "NOFOCUSONMAP",
+ "FOCUSONMAP_SINGLE",
};
/* SWM_Q_WS: retain '|' for back compat for now (2009-08-11) */
errx(1, "setconfvalue: bar_enabled_ws: invalid "
"workspace %d.", ws_id + 1);
- num_screens = xcb_setup_roots_length(xcb_get_setup(conn));
+ num_screens = get_screen_count();
for (i = 0; i < num_screens; i++) {
ws = (struct workspace *)&screens[i].ws;
ws[ws_id].bar_enabled = atoi(value);
"<master_grow>:<master_add>:<stack_inc>:<always_raise>:"
"<type>'");
- num_screens = xcb_setup_roots_length(xcb_get_setup(conn));
+ num_screens = get_screen_count();
for (i = 0; i < num_screens; i++) {
ws = (struct workspace *)&screens[i].ws;
ws[ws_id].cur_layout = &layouts[st];
warnx("conf_load: no filename");
return (1);
}
+
+ DNPRINTF(SWM_D_CONF, "conf_load: open %s\n", filename);
+
if ((config = fopen(filename, "r")) == NULL) {
warn("conf_load: fopen: %s", filename);
return (1);
DNPRINTF(SWM_D_EVENT, "expose: window: 0x%x\n", e->window);
- num_screens = xcb_setup_roots_length(xcb_get_setup(conn));
+ num_screens = get_screen_count();
for (i = 0; i < num_screens; i++)
TAILQ_FOREACH(r, &screens[i].rl, entry)
if (e->window == WINID(r->bar))
if (win->ws->focus_pending) {
focus_win(win->ws->focus_pending);
win->ws->focus_pending = NULL;
+ } else if (win == win->ws->focus && win->ws->r) {
+ xcb_set_input_focus(conn, XCB_INPUT_FOCUS_PARENT,
+ win->ws->r->id, XCB_CURRENT_TIME);
}
}
void
maprequest(xcb_map_request_event_t *e)
{
- struct ws_win *win;
+ struct ws_win *win, *w = NULL;
xcb_get_window_attributes_reply_t *war;
DNPRINTF(SWM_D_EVENT, "maprequest: win 0x%x\n",
(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);
+ if (focus_mode != SWM_FOCUS_FOLLOW &&
+ !(win->quirks & SWM_Q_NOFOCUSONMAP)) {
+ if (win->quirks & SWM_Q_FOCUSONMAP_SINGLE) {
+ /* See if other wins of same type are already mapped. */
+ TAILQ_FOREACH(w, &win->ws->winlist, entry) {
+ if (w == win || !w->mapped)
+ continue;
+
+ if (!strcmp(w->ch.class_name,
+ win->ch.class_name) &&
+ !strcmp(w->ch.instance_name,
+ win->ch.instance_name))
+ break;
+ }
+ }
+
+ if (w == NULL)
+ 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)
last_event_time = e->time;
- num_screens = xcb_setup_roots_length(xcb_get_setup(conn));
+ if (focus_mode == SWM_FOCUS_MANUAL)
+ return;
+
+ num_screens = get_screen_count();
for (i = 0; i < num_screens; i++)
if (screens[i].root == e->root)
break;
propertynotify(xcb_property_notify_event_t *e)
{
struct ws_win *win;
+ struct workspace *ws;
#ifdef SWM_DEBUG
char *name;
if (win == NULL)
return;
+ ws = win->ws;
+
last_event_time = e->time;
if (e->atom == a_swm_iconic) {
if (e->state == XCB_PROPERTY_NEW_VALUE) {
if (focus_mode != SWM_FOCUS_FOLLOW)
- win->ws->focus_pending = get_focus_prev(win);
+ ws->focus_pending = get_focus_prev(win);
unfocus_win(win);
unmap_window(win);
- if (win->ws->r) {
+ if (ws->r) {
stack();
+
if (focus_mode != SWM_FOCUS_FOLLOW) {
- focus_win(win->ws->focus_pending);
- win->ws->focus_pending = NULL;
+ if (ws->focus_pending) {
+ focus_win(ws->focus_pending);
+ ws->focus_pending = NULL;
+ } else {
+ xcb_set_input_focus(conn,
+ XCB_INPUT_FOCUS_PARENT,
+ ws->r->id,
+ XCB_CURRENT_TIME);
+ }
}
+
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);
+ ws->focus_pending = get_focus_magic(win);
stack();
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;
+ ws->focus_pending == win) {
+ focus_win(ws->focus_pending);
+ ws->focus_pending = NULL;
}
}
}
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;
- }
+ } else if (ws->focus_pending) {
+ focus_win(ws->focus_pending);
+ ws->focus_pending = NULL;
+ } else if (ws->focus == NULL && ws->r) {
+ xcb_set_input_focus(conn, XCB_INPUT_FOCUS_PARENT,
+ ws->r->id, XCB_CURRENT_TIME);
}
}
xcb_generic_error_t *error;
/* this causes an error if some other window manager is running */
- num_screens = xcb_setup_roots_length(xcb_get_setup(conn));
+ num_screens = get_screen_count();
for (i = 0; i < num_screens; i++) {
if ((sc = get_screen(i)) == NULL)
errx(1, "ERROR: can't get screen %d.", i);
if ((screen = get_screen(i)) == NULL)
errx(1, "ERROR: can't get screen %d.", i);
- num_screens = xcb_setup_roots_length(xcb_get_setup(conn));
+ num_screens = get_screen_count();
if (i >= num_screens)
errx(1, "scan_xrandr: invalid screen");
DNPRINTF(SWM_D_EVENT, "screenchange: root: 0x%x\n", e->root);
- num_screens = xcb_setup_roots_length(xcb_get_setup(conn));
+ num_screens = get_screen_count();
/* silly event doesn't include the screen index */
for (i = 0; i < num_screens; i++)
if (screens[i].root == e->root)
xcb_get_property_cookie_t pc;
DNPRINTF(SWM_D_INIT, "grab_windows: begin\n");
- num_screens = xcb_setup_roots_length(xcb_get_setup(conn));
+ num_screens = get_screen_count();
for (i = 0; i < num_screens; i++) {
qtc = xcb_query_tree(conn, screens[i].root);
qtr = xcb_query_tree_reply(conn, qtc, NULL);
xcb_randr_query_version_cookie_t c;
xcb_randr_query_version_reply_t *r;
- num_screens = xcb_setup_roots_length(xcb_get_setup(conn));
+ num_screens = get_screen_count();
if ((screens = calloc(num_screens,
sizeof(struct swm_screen))) == NULL)
err(1, "setup_screens: calloc: failed to allocate memory for "
/* work around sun jdk bugs, code from wmname */
netwmcheck = get_atom_from_string("_NET_SUPPORTING_WM_CHECK");
- num_screens = xcb_setup_roots_length(xcb_get_setup(conn));
+ num_screens = get_screen_count();
for (i = 0; i < num_screens; i++) {
root = screens[i].root;
teardown_ewmh();
- num_screens = xcb_setup_roots_length(xcb_get_setup(conn));
+ num_screens = get_screen_count();
for (i = 0; i < num_screens; ++i) {
if (screens[i].bar_gc != 0)
xcb_free_gc(conn, screens[i].bar_gc);
setenv("SWM_STARTED", "YES", 1);
/* setup all bars */
- num_screens = xcb_setup_roots_length(xcb_get_setup(conn));
+ num_screens = get_screen_count();
for (i = 0; i < num_screens; i++)
TAILQ_FOREACH(r, &screens[i].rl, entry)
bar_setup(r);