]> code.delx.au - spectrwm/blobdiff - spectrwm.c
Resolve memory leaks on exit
[spectrwm] / spectrwm.c
index ca7fe742615ad72932606e8f5de3955ed093bc96..2cc0d246b0fe30f4ffc4a69a3027bdcccb5b87c7 100644 (file)
@@ -678,7 +678,7 @@ struct quirk {
 #define SWM_Q_TRANSSZ          (1<<1)  /* transiend window size too small */
 #define SWM_Q_ANYWHERE         (1<<2)  /* don't position this window */
 #define SWM_Q_XTERM_FONTADJ    (1<<3)  /* adjust xterm fonts when resizing */
-#define SWM_Q_FULLSCREEN       (1<<4)  /* remove border */
+#define SWM_Q_FULLSCREEN       (1<<4)  /* remove border when fullscreen */
 #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. */
@@ -686,6 +686,7 @@ struct quirk {
 #define SWM_Q_IGNOREPID                (1<<9)  /* Ignore PID when determining ws. */
 #define SWM_Q_IGNORESPAWNWS    (1<<10) /* Ignore _SWM_WS when managing win. */
 #define SWM_Q_NOFOCUSCYCLE     (1<<11) /* Remove from normal focus cycle. */
+#define SWM_Q_MINIMALBORDER    (1<<12) /* Remove border when floating/unfocused */
 };
 TAILQ_HEAD(quirk_list, quirk);
 struct quirk_list              quirks = TAILQ_HEAD_INITIALIZER(quirks);
@@ -983,6 +984,8 @@ void         center_pointer(struct swm_region *);
 void    check_conn(void);
 void    clear_keys(void);
 int     clear_maximized(struct workspace *);
+void    clear_quirks(void);
+void    clear_spawns(void);
 void    clientmessage(xcb_client_message_event_t *);
 void    client_msg(struct ws_win *, xcb_atom_t, xcb_timestamp_t);
 int     conf_load(const char *, int);
@@ -3604,6 +3607,15 @@ unfocus_win(struct ws_win *win)
        if (win->ws->always_raise)
                raise_window(win);
 
+       /* Update border width */
+       if (win->bordered && (win->quirks & SWM_Q_MINIMALBORDER) &&
+           FLOATING(win)) {
+               win->bordered = 0;
+               X(win) += border_width;
+               Y(win) += border_width;
+               update_window(win);
+       }
+
        xcb_change_property(conn, XCB_PROP_MODE_REPLACE, win->s->root,
            ewmh[_NET_ACTIVE_WINDOW].atom, XCB_ATOM_WINDOW, 32, 1, &none);
 
@@ -3643,6 +3655,16 @@ focus_win(struct ws_win *win)
                                    &cfw->s->c[(MAXIMIZED(cfw) ?
                                    SWM_S_COLOR_UNFOCUS_MAXIMIZED :
                                    SWM_S_COLOR_UNFOCUS)].pixel);
+
+                               /* Update border width */
+                               if (cfw->bordered &&
+                                   (cfw->quirks & SWM_Q_MINIMALBORDER) &&
+                                   FLOATING(cfw)) {
+                                       cfw->bordered = 0;
+                                       X(cfw) += border_width;
+                                       Y(cfw) += border_width;
+                                       update_window(cfw);
+                               }
                        } else {
                                unfocus_win(cfw);
                        }
@@ -3731,10 +3753,20 @@ focus_win(struct ws_win *win)
                    &win->id);
        }
 
-       if (cfw != win)
+       if (cfw != win) {
                /* Update window border even if workspace is hidden. */
                update_window_color(win);
 
+               /* Update border width */
+               if (!win->bordered && WS_FOCUSED(win->ws) &&
+                   (win->quirks & SWM_Q_MINIMALBORDER) && FLOATING(win)) {
+                       win->bordered = 1;
+                       X(win) -= border_width;
+                       Y(win) -= border_width;
+                       update_window(win);
+               }
+       }
+
 out:
        bar_draw();
 
@@ -4707,9 +4739,11 @@ update_floater(struct ws_win *win)
                if (r != ws->old_r)
                        load_float_geom(win);
 
-               if ((win->quirks & SWM_Q_FULLSCREEN) &&
-                   WIDTH(win) >= WIDTH(r) && HEIGHT(win) >= HEIGHT(r)) {
-                       /* Remove border for FULLSCREEN quirk. */
+               if (((win->quirks & SWM_Q_FULLSCREEN) &&
+                    WIDTH(win) >= WIDTH(r) && HEIGHT(win) >= HEIGHT(r)) ||
+                   ((!WS_FOCUSED(win->ws) || win->ws->focus != win) &&
+                    (win->quirks & SWM_Q_MINIMALBORDER))) {
+                       /* Remove border */
                        win->bordered = false;
                } else if (!MANUAL(win)) {
                        if (TRANS(win) && (win->quirks & SWM_Q_TRANSSZ)) {
@@ -5858,10 +5892,13 @@ ewmh_update_current_desktop(void)
        int                     num_screens, i;
 
        num_screens = get_screen_count();
-       for (i = 0; i < num_screens; ++i)
-               xcb_change_property(conn, XCB_PROP_MODE_REPLACE,
-                   screens[i].root, ewmh[_NET_CURRENT_DESKTOP].atom,
-                   XCB_ATOM_CARDINAL, 32, 1, &screens[i].r_focus->ws->idx);
+       for (i = 0; i < num_screens; ++i) {
+               if (screens[i].r_focus)
+                       xcb_change_property(conn, XCB_PROP_MODE_REPLACE,
+                           screens[i].root, ewmh[_NET_CURRENT_DESKTOP].atom,
+                           XCB_ATOM_CARDINAL, 32, 1,
+                           &screens[i].r_focus->ws->idx);
+       }
 }
 
 void
@@ -7118,6 +7155,16 @@ spawn_remove(struct spawn_prog *sp)
        DNPRINTF(SWM_D_SPAWN, "spawn_remove: leave\n");
 }
 
+void
+clear_spawns(void)
+{
+       struct spawn_prog       *sp;
+
+       while ((sp = TAILQ_FIRST(&spawns)) != NULL) {
+               spawn_remove(sp);
+       }
+}
+
 struct spawn_prog*
 spawn_find(const char *name)
 {
@@ -7732,6 +7779,7 @@ const char *quirkname[] = {
        "IGNOREPID",
        "IGNORESPAWNWS",
        "NOFOCUSCYCLE",
+       "MINIMALBORDER",
 };
 
 /* SWM_Q_DELIM: retain '|' for back compat for now (2009-08-11) */
@@ -7872,6 +7920,16 @@ quirk_free(struct quirk *qp)
        free(qp);
 }
 
+void
+clear_quirks(void)
+{
+       struct quirk            *qp;
+
+       while ((qp = TAILQ_FIRST(&quirks)) != NULL) {
+               quirk_remove(qp);
+       }
+}
+
 void
 quirk_replace(struct quirk *qp, const char *class, const char *instance,
     const char *name, uint32_t quirk, int ws)
@@ -10761,10 +10819,17 @@ shutdown_cleanup(void)
 
        cursors_cleanup();
 
+       clear_quirks();
+       clear_spawns();
+       clear_keys();
+
        teardown_ewmh();
 
        num_screens = get_screen_count();
        for (i = 0; i < num_screens; ++i) {
+               struct swm_region       *r;
+               int j;
+
                xcb_set_input_focus(conn, XCB_INPUT_FOCUS_POINTER_ROOT,
                    screens[i].root, XCB_CURRENT_TIME);
 
@@ -10776,13 +10841,45 @@ shutdown_cleanup(void)
                        XftColorFree(display, DefaultVisual(display, i),
                            DefaultColormap(display, i), &search_font_color);
                }
+
+               for (j = 0; j < SWM_S_COLOR_MAX; ++j) {
+                       free(screens[i].c[j].name);
+               }
+
+               for (j = 0; j < SWM_WS_MAX; ++j) {
+                       struct ws_win           *win;
+
+                       free(screens[i].ws[j].name);
+
+                       while ((win = TAILQ_FIRST(&screens[i].ws[j].winlist)) != NULL) {
+                               TAILQ_REMOVE(&screens[i].ws[j].winlist, win, entry);
+                               free(win);
+                       }
+               }
+
+               while ((r = TAILQ_FIRST(&screens[i].rl)) != NULL) {
+                       TAILQ_REMOVE(&screens[i].rl, r, entry);
+                       free(r->bar);
+                       free(r);
+               }
+
+               while ((r = TAILQ_FIRST(&screens[i].orl)) != NULL) {
+                       TAILQ_REMOVE(&screens[i].rl, r, entry);
+                       free(r->bar);
+                       free(r);
+               }
        }
+       free(screens);
 
-       if (bar_font_legacy)
+       free(bar_format);
+       free(bar_fonts);
+       free(clock_format);
+       free(startup_exception);
+
+       if (bar_fs)
                XFreeFontSet(display, bar_fs);
-       else {
+       if (bar_font_legacy == false)
                XftFontClose(display, bar_font);
-       }
 
        xcb_key_symbols_free(syms);
        xcb_flush(conn);