JasonWoof Got questions, comments, patches, etc.? Contact Jason Woofenden
Plug memory and file descriptor leaks in conf_load().
[spectrwm.git] / scrotwm.c
index c2aece7..0c339a2 100644 (file)
--- a/scrotwm.c
+++ b/scrotwm.c
@@ -178,6 +178,7 @@ Atom                        aprot;
 Atom                   adelete;
 Atom                   takefocus;
 Atom                   a_wmname;
+Atom                   a_netwmname;
 Atom                   a_utf8_string;
 Atom                   a_string;
 Atom                   a_swm_iconic;
@@ -2446,6 +2447,7 @@ focus(struct swm_region *r, union arg *args)
        struct ws_win           *cur_focus = NULL;
        struct ws_win_list      *wl = NULL;
        struct workspace        *ws = NULL;
+       int                     all_iconics;
 
        if (!(r && r->ws))
                return;
@@ -2471,6 +2473,17 @@ focus(struct swm_region *r, union arg *args)
                return;
        ws = r->ws;
        wl = &ws->winlist;
+       if (TAILQ_EMPTY(wl))
+               return;
+       /* make sure there is at least one uniconified window */
+       all_iconics = 1;
+       TAILQ_FOREACH(winfocus, wl, entry)
+               if (winfocus->iconic == 0) {
+                       all_iconics = 0;
+                       break;
+               }
+       if (all_iconics)
+               return;
 
        winlostfocus = cur_focus;
 
@@ -3118,7 +3131,7 @@ send_to_ws(struct swm_region *r, union arg *args)
        unsigned char           ws_idx_str[SWM_PROPLEN];
        union arg               a;
 
-       if (r && r->ws)
+       if (r && r->ws && r->ws->focus)
                win = r->ws->focus;
        else
                return;
@@ -3146,6 +3159,8 @@ send_to_ws(struct swm_region *r, union arg *args)
        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 */
@@ -3267,7 +3282,7 @@ uniconify(struct swm_region *r, union arg *args)
                if (win->iconic == 0)
                        continue;
 
-               name = get_win_name(display, win->id, a_wmname, a_string,
+               name = get_win_name(display, win->id, a_netwmname, a_utf8_string,
                    &len);
                if (name == NULL)
                        continue;
@@ -3423,7 +3438,7 @@ search_resp_uniconify(char *resp, unsigned long len)
        TAILQ_FOREACH(win, &search_r->ws->winlist, entry) {
                if (win->iconic == 0)
                        continue;
-               name = get_win_name(display, win->id, a_wmname, a_string, &len);
+               name = get_win_name(display, win->id, a_netwmname, a_utf8_string, &len);
                if (name == NULL)
                        continue;
                if (asprintf(&s, "%s.%lu", name, win->id) == -1) {
@@ -5385,7 +5400,7 @@ conf_load(char *filename, int keymapping)
                if (wordlen == 0) {
                        warnx("%s: line %zd: no option found",
                            filename, lineno);
-                       return (1);
+                       goto out;
                }
                optind = -1;
                for (i = 0; i < LENGTH(configopt); i++) {
@@ -5399,12 +5414,12 @@ conf_load(char *filename, int keymapping)
                if (optind == -1) {
                        warnx("%s: line %zd: unknown option %.*s",
                            filename, lineno, wordlen, cp);
-                       return (1);
+                       goto out;
                }
                if (keymapping && strcmp(opt->optname, "bind")) {
                        warnx("%s: line %zd: invalid option %.*s",
                            filename, lineno, wordlen, cp);
-                       return (1);
+                       goto out;
                }
                cp += wordlen;
                cp += strspn(cp, " \t\n"); /* eat whitespace */
@@ -5417,7 +5432,7 @@ conf_load(char *filename, int keymapping)
                                if (wordlen == 0) {
                                        warnx("%s: line %zd: syntax error",
                                            filename, lineno);
-                                       return (1);
+                                       goto out;
                                }
                                asprintf(&optsub, "%.*s", wordlen, cp);
                        }
@@ -5444,6 +5459,12 @@ conf_load(char *filename, int keymapping)
        DNPRINTF(SWM_D_CONF, "conf_load end\n");
 
        return (0);
+
+out:
+       free(line);
+       fclose(config);
+
+       return (1);
 }
 
 void
@@ -6729,6 +6750,7 @@ main(int argc, char *argv[])
        adelete = XInternAtom(display, "WM_DELETE_WINDOW", False);
        takefocus = XInternAtom(display, "WM_TAKE_FOCUS", False);
        a_wmname = XInternAtom(display, "WM_NAME", False);
+       a_netwmname = XInternAtom(display, "_NET_WM_NAME", False);
        a_utf8_string = XInternAtom(display, "UTF8_STRING", False);
        a_string = XInternAtom(display, "STRING", False);
        a_swm_iconic = XInternAtom(display, "_SWM_ICONIC", False);