XftColor bar_font_color;
struct passwd *pwd;
char *startup_exception;
-unsigned int nr_exceptions = 0;
+unsigned int nr_exceptions = 0;
/* layout manager data */
struct swm_geometry {
void wkill(struct swm_region *, union arg *);
void workaround(void);
void xft_init(struct swm_region *);
-void _add_startup_exception(const char *, va_list);
-void add_startup_exception(const char *, ...);
+void _add_startup_exception(const char *, va_list);
+void add_startup_exception(const char *, ...);
RB_PROTOTYPE(key_tree, key, entry, key_cmp);
RB_GENERATE(key_tree, key, entry, key_cmp);
r->bar->id = xcb_generate_id(conn);
wa[0] = r->s->c[SWM_S_COLOR_BAR].pixel;
wa[1] = r->s->c[SWM_S_COLOR_BAR_BORDER_UNFOCUS].pixel;
- wa[2] = XCB_EVENT_MASK_EXPOSURE;
+ wa[2] = XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_POINTER_MOTION |
+ XCB_EVENT_MASK_POINTER_MOTION_HINT;
xcb_create_window(conn, XCB_COPY_FROM_PARENT, r->bar->id, r->s->root,
X(r->bar), Y(r->bar), WIDTH(r->bar), HEIGHT(r->bar),
free(r);
/* Use WM_NAME instead; no UTF-8. */
c = xcb_get_property(conn, 0, win, XCB_ATOM_WM_NAME,
- XCB_GET_PROPERTY_TYPE_ANY, 0, UINT_MAX);
+ XCB_GET_PROPERTY_TYPE_ANY, 0, UINT_MAX);
r = xcb_get_property_reply(conn, c, NULL);
if (!r)
}
if (r->length > 0)
name = strndup(xcb_get_property_value(r),
- xcb_get_property_value_length(r));
+ xcb_get_property_value_length(r));
free(r);
}
int
setconfspawn(char *selector, char *value, int flags)
{
- char *args;
-
- /* suppress unused warning since var is needed */
- (void)flags;
+ char *args;
+ char which[PATH_MAX];
+ size_t i;
args = expand_tilde(value);
DNPRINTF(SWM_D_SPAWN, "setconfspawn: [%s] [%s]\n", selector, args);
+ /* verify we have the goods */
+ snprintf(which, sizeof which, "which %s", value);
+ for (i = strlen("which "); i < strlen(which); i++)
+ if (which[i] == ' ') {
+ which[i] = '\0';
+ break;
+ }
+ if (flags == 0 && system(which) != 0)
+ add_startup_exception("could not find %s",
+ &which[strlen("which ")]);
+
setspawn(selector, args);
free(args);
{
setconfspawn("term", "xterm", 0);
setconfspawn("spawn_term", "xterm", 0);
- setconfspawn("screenshot_all", "screenshot.sh full", 0);
- setconfspawn("screenshot_wind", "screenshot.sh window", 0);
- setconfspawn("lock", "xlock", 0);
- setconfspawn("initscr", "initscreen.sh", 0);
setconfspawn("menu", "dmenu_run"
" -fn $bar_font"
" -nb $bar_color"
" -sb $bar_border"
" -sf $bar_color", 0);
- /* only test dmenu for now, really should expand this */
- if (system("dmenu -v") != 0)
- add_startup_exception("you must install dmenu");
+ /* these are not verified for existence */
+ setconfspawn("lock", "xlock", 1);
+ setconfspawn("screenshot_all", "screenshot.sh full", 1);
+ setconfspawn("screenshot_wind", "screenshot.sh window", 1);
+ setconfspawn("initscr", "initscreen.sh", 1);
}
/* key bindings */
conf_load(const char *filename, int keymapping)
{
FILE *config;
- char *line = NULL, *cp, *optsub, *optval;
+ char *line = NULL, *cp, *optsub, *optval = NULL;
size_t linelen, lineno = 0;
int wordlen, i, optidx;
struct config_option *opt = NULL;
if (line)
free(line);
- if ((line = fparseln(config, &linelen, &lineno, NULL, 0))
- == NULL) {
+ if ((line = fparseln(config, &linelen, &lineno, NULL,
+ FPARSELN_UNESCCOMM | FPARSELN_UNESCCONT)) == NULL) {
if (ferror(config))
err(1, "%s", filename);
else
cp += strspn(cp, "= \t\n"); /* eat trailing */
/* get RHS value */
optval = strdup(cp);
+ if (strlen(optval) == 0) {
+ add_startup_exception("%s: line %zd: must supply value "
+ "to %s", filename, lineno,
+ configopt[optidx].optname);
+ goto invalid;
+ }
/* call function to deal with it all */
if (configopt[optidx].func(optsub, optval,
configopt[optidx].funcflags) != 0) {
/* If no windows on pointer region, then focus root. */
r = root_to_region(e->root, SWM_CK_POINTER);
if (r == NULL) {
- DNPRINTF(SWM_D_EVENT, "enterntoify: "
+ DNPRINTF(SWM_D_EVENT, "enternotify: "
"NULL region; ignoring.\n");
return;
}
focus_win(get_focus_magic(win));
}
- focus_flush();
+ xcb_flush(conn);
}
#ifdef SWM_DEBUG
int ncrtc = 0;
#endif /* SWM_XRR_HAS_CRTC */
struct swm_region *r;
+ struct ws_win *win;
int num_screens;
xcb_randr_get_screen_resources_current_cookie_t src;
xcb_randr_get_screen_resources_current_reply_t *srr;
xcb_destroy_window(conn, r->id);
TAILQ_REMOVE(&screens[i].rl, r, entry);
TAILQ_INSERT_TAIL(&screens[i].orl, r, entry);
-
- if (r->s->r_focus == r)
- r->s->r_focus = NULL;
}
outputs = 0;
screen->height_in_pixels);
out:
+ /* Cleanup unused previously visible workspaces. */
+ TAILQ_FOREACH(r, &screens[i].orl, entry) {
+ TAILQ_FOREACH(win, &r->ws->winlist, entry)
+ unmap_window(win);
+
+ /* The screen shouldn't focus on an unused region. */
+ if (screens[i].r_focus == r)
+ screens[i].r_focus = NULL;
+ }
+
DNPRINTF(SWM_D_MISC, "scan_xrandr: done.\n");
}
for (i = 0; i < num_screens; i++) {
TAILQ_FOREACH(r, &screens[i].rl, entry)
bar_setup(r);
+ }
- if (screens[0].r_focus == NULL) {
- /* Focus on first region. */
- r = TAILQ_FIRST(&screens[0].rl);
- if (r)
+ stack();
+
+ /* Make sure a region has focus on each screen. */
+ for (i = 0; i < num_screens; i++) {
+ if (screens[i].r_focus == NULL) {
+ r = TAILQ_FIRST(&screens[i].rl);
+ if (r != NULL)
focus_region(r);
}
}
- stack();
bar_draw();
focus_flush();
}