/* function prototypes */
void adjust_font(struct ws_win *);
+char *argsep(char **);
void bar_cleanup(struct swm_region *);
void bar_extra_setup(void);
void bar_extra_stop(void);
free(real_args);
}
+/* Argument tokenizer. */
+char *
+argsep(char **sp) {
+ int single_quoted = 0, double_quoted = 0;
+ char *arg, *cp, *next;
+
+ if (*sp == NULL)
+ return NULL;
+
+ /* Eat and move characters until end of argument is found. */
+ for (arg = next = cp = *sp; *cp != '\0'; ++cp) {
+ if (!double_quoted && *cp == '\'') {
+ /* Eat single-quote. */
+ single_quoted = !single_quoted;
+ } else if (!single_quoted && *cp == '"') {
+ /* Eat double-quote. */
+ double_quoted = !double_quoted;
+ } else if (!single_quoted && *cp == '\\' && *(cp + 1) == '"') {
+ /* Eat backslash; copy escaped character to arg. */
+ *next++ = *(++cp);
+ } else if (!single_quoted && !double_quoted && *cp == '\\' &&
+ (*(cp + 1) == '\'' || *(cp + 1) == ' ')) {
+ /* Eat backslash; move escaped character. */
+ *next++ = *(++cp);
+ } else if (!single_quoted && !double_quoted &&
+ (*cp == ' ' || *cp == '\t')) {
+ /* Terminate argument. */
+ *next++ = '\0';
+ /* Point sp to beginning of next argument. */
+ *sp = ++cp;
+ break;
+ } else {
+ /* Move regular character. */
+ *next++ = *cp;
+ }
+ }
+
+ /* Terminate argument if end of string. */
+ if (*cp == '\0') {
+ *next = '\0';
+ *sp = NULL;
+ }
+
+ return arg;
+}
+
void
spawn_insert(const char *name, const char *args, int flags)
{
- char *arg, *cp, *ptr;
struct spawn_prog *sp;
+ char *arg, *dup, *ptr;
- DNPRINTF(SWM_D_SPAWN, "spawn_insert: %s\n", name);
+ DNPRINTF(SWM_D_SPAWN, "spawn_insert: %s[%s]\n", name, args);
+
+ if (args == NULL || *args == '\0')
+ return;
if ((sp = calloc(1, sizeof *sp)) == NULL)
err(1, "spawn_insert: calloc");
if ((sp->name = strdup(name)) == NULL)
err(1, "spawn_insert: strdup");
- /* convert the arguments to an argument list */
- if ((ptr = cp = strdup(args)) == NULL)
+ /* Convert the arguments to an argument list. */
+ if ((ptr = dup = strdup(args)) == NULL)
err(1, "spawn_insert: strdup");
- while ((arg = strsep(&ptr, " \t")) != NULL) {
- /* empty field; skip it */
+ while ((arg = argsep(&ptr)) != NULL) {
+ /* Null argument; skip it. */
if (*arg == '\0')
continue;
if ((sp->argv[sp->argc - 1] = strdup(arg)) == NULL)
err(1, "spawn_insert: strdup");
}
- free(cp);
+ free(dup);
sp->flags = flags;
+ DNPRINTF(SWM_D_SPAWN, "arg %d: [%s]\n", sp->argc, sp->argv[sp->argc-1]);
TAILQ_INSERT_TAIL(&spawns, sp, entry);
DNPRINTF(SWM_D_SPAWN, "spawn_insert: leave\n");
}
{
char *args;
+ if (selector == NULL || strlen(selector) == 0)
+ return (1);
+
args = expand_tilde(value);
DNPRINTF(SWM_D_SPAWN, "setconfspawn: [%s] [%s]\n", selector, args);
/* suppress unused warning since var is needed */
(void)flags;
- DNPRINTF(SWM_D_KEY, "setconfbinding: enter\n");
- if (selector == NULL) {
+ DNPRINTF(SWM_D_KEY, "setconfbinding: enter selector: [%s], "
+ "value: [%s]\n", selector, value);
+ if (selector == NULL || strlen(selector) == 0) {
DNPRINTF(SWM_D_KEY, "setconfbinding: unbind %s\n", value);
if (parsekeys(value, mod_key, &mod, &ks) == 0) {
kfid = KF_INVALID;
+ j];
keycode = xcb_key_symbols_get_keycode(syms,
XK_Num_Lock);
- if (kc == *keycode)
- numlockmask = (1 << i);
- free(keycode);
+ if (keycode) {
+ if (kc == *keycode)
+ numlockmask = (1 << i);
+ free(keycode);
+ }
}
}
free(modmap_r);
/* suppress unused warning since var is needed */
(void)flags;
- if (selector == NULL)
+ if (selector == NULL || strlen(selector) == 0)
return (0);
if ((str = strdup(selector)) == NULL)
int i, ws_id, num_screens;
char *b, *str;
- /* suppress unused warning since var is needed */
- (void)selector;
-
switch (flags) {
case SWM_S_BAR_ACTION:
free(bar_argv[0]);
int
setconfcolor(const char *selector, const char *value, int flags)
{
- setscreencolor(value, ((selector == NULL)?-1:atoi(selector)), flags);
+ setscreencolor(value,
+ (selector == NULL || strlen(selector) == 0) ? -1 : atoi(selector),
+ flags);
return (0);
}
struct ws_win *win, *ww;
int ws_idx;
char ws_idx_str[SWM_PROPLEN];
- char *name;
+ char *class, *instance, *name;
struct swm_region *r;
struct pid_e *p;
struct quirk *qp;
ewmh_autoquirk(win);
/* Determine initial quirks. */
- if (xcb_icccm_get_wm_class_reply(conn,
+ xcb_icccm_get_wm_class_reply(conn,
xcb_icccm_get_wm_class(conn, win->id),
- &win->ch, NULL)) {
- name = get_win_name(win->id);
+ &win->ch, NULL);
- DNPRINTF(SWM_D_CLASS, "manage_window: class: %s, instance: %s, "
- "name: %s\n",
- win->ch.class_name, win->ch.instance_name, name);
-
- /* java is retarded so treat it special */
- if (strstr(win->ch.instance_name, "sun-awt")) {
- DNPRINTF(SWM_D_CLASS, "manage_window: java window "
- "detected.\n");
- win->java = 1;
- }
-
- TAILQ_FOREACH(qp, &quirks, entry) {
- if (regexec(&qp->regex_class, win->ch.class_name, 0,
- NULL, 0) == 0 && regexec(&qp->regex_instance,
- win->ch.instance_name, 0, NULL, 0) == 0 &&
- regexec(&qp->regex_name, name, 0, NULL, 0) == 0) {
- DNPRINTF(SWM_D_CLASS, "manage_window: matched "
- "quirk: %s:%s:%s mask: %#lx\n", qp->class,
- qp->instance, qp->name, qp->quirk);
- if (qp->quirk & SWM_Q_FLOAT)
- win->floating = 1;
- win->quirks = qp->quirk;
- }
+ class = win->ch.class_name ? win->ch.class_name : "";
+ instance = win->ch.instance_name ? win->ch.instance_name : "";
+ name = get_win_name(win->id);
- }
+ DNPRINTF(SWM_D_CLASS, "manage_window: class: %s, instance: %s, "
+ "name: %s\n", class, instance, name);
- free(name);
+ /* java is retarded so treat it special */
+ if (win->ch.instance_name && strstr(win->ch.instance_name, "sun-awt")) {
+ DNPRINTF(SWM_D_CLASS, "manage_window: java window detected.\n");
+ win->java = 1;
}
+ TAILQ_FOREACH(qp, &quirks, entry) {
+ if (regexec(&qp->regex_class, class, 0, NULL, 0) == 0 &&
+ regexec(&qp->regex_instance, instance, 0, NULL, 0) == 0 &&
+ regexec(&qp->regex_name, name, 0, NULL, 0) == 0) {
+ DNPRINTF(SWM_D_CLASS, "manage_window: matched "
+ "quirk: %s:%s:%s mask: %#lx\n", qp->class,
+ qp->instance, qp->name, qp->quirk);
+ if (qp->quirk & SWM_Q_FLOAT)
+ win->floating = 1;
+ win->quirks = qp->quirk;
+ }
+ }
+
+ free(name);
+
/* Alter window position if quirky */
if (win->quirks & SWM_Q_ANYWHERE)
win->manual = 1;
void
mappingnotify(xcb_mapping_notify_event_t *e)
{
+ struct ws_win *w;
+ int i, j, num_screens;
+
xcb_refresh_keyboard_mapping(syms, e);
- if (e->request == XCB_MAPPING_KEYBOARD)
+ if (e->request == XCB_MAPPING_KEYBOARD) {
grabkeys();
+
+ /* Regrab buttons on all managed windows. */
+ num_screens = get_screen_count();
+ for (i = 0; i < num_screens; i++)
+ for (j = 0; j < workspace_limit; j++)
+ TAILQ_FOREACH(w, &screens[i].ws[j].winlist,
+ entry)
+ grabbuttons(w);
+ }
}
void
focus_flush();
}
} else if (e->state == XCB_PROPERTY_DELETE) {
+ /* Reload floating geometry in case region changed. */
+ if (win->floating)
+ load_float_geom(win);
+
/* The window is no longer iconic, restack ws. */
if (focus_mode != SWM_FOCUS_FOLLOW)
ws->focus_pending = get_focus_magic(win);