]> code.delx.au - spectrwm/blobdiff - spectrwm.c
Resolve memory leaks on exit
[spectrwm] / spectrwm.c
index 1542fe1e512a5d38b06cbe2ad776681172ca147d..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);
@@ -1099,7 +1102,6 @@ void       print_win_geom(xcb_window_t);
 #endif
 void    propertynotify(xcb_property_notify_event_t *);
 void    quirk_free(struct quirk *);
-void    clear_quirks(void);
 void    quirk_insert(const char *, const char *, const char *, uint32_t, int);
 void    quirk_remove(struct quirk *);
 void    quirk_replace(struct quirk *, const char *, const char *, const char *,
@@ -1159,7 +1161,6 @@ int        spawn_expand(struct swm_region *, union arg *, const char *, char ***);
 void    spawn_insert(const char *, const char *, int);
 struct spawn_prog      *spawn_find(const char *);
 void    spawn_remove(struct spawn_prog *);
-void    clear_spawns(void);
 void    spawn_replace(struct spawn_prog *, const char *, const char *, int);
 void    spawn_select(struct swm_region *, union arg *, const char *, int *);
 void    stack_config(struct swm_region *, union arg *);
@@ -3606,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);
 
@@ -3645,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);
                        }
@@ -3733,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();
 
@@ -4709,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)) {
@@ -7747,6 +7779,7 @@ const char *quirkname[] = {
        "IGNOREPID",
        "IGNORESPAWNWS",
        "NOFOCUSCYCLE",
+       "MINIMALBORDER",
 };
 
 /* SWM_Q_DELIM: retain '|' for back compat for now (2009-08-11) */
@@ -10794,6 +10827,7 @@ shutdown_cleanup(void)
 
        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,
@@ -10813,19 +10847,39 @@ shutdown_cleanup(void)
                }
 
                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);
 
        free(bar_format);
+       free(bar_fonts);
        free(clock_format);
+       free(startup_exception);
 
-       if (bar_font_legacy)
+       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);