#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);
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 *);
}
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;
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++) {
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;
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;
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;
"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];
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))
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));
+ num_screens = get_screen_count();
for (i = 0; i < num_screens; i++)
if (screens[i].root == e->root)
break;
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);