JasonWoof Got questions, comments, patches, etc.? Contact Jason Woofenden
Add opacity hint support for composite managers.
authorReginald Kennedy <rk@rejii.com>
Thu, 20 Sep 2012 09:40:21 +0000 (17:40 +0800)
committerReginald Kennedy <rk@rejii.com>
Thu, 7 Aug 2014 19:35:06 +0000 (03:35 +0800)
spectrwm.c
spectrwm.conf

index b60cbc7..493a328 100644 (file)
@@ -401,6 +401,9 @@ bool                 stack_enabled = true;
 bool            clock_enabled = true;
 bool            iconic_enabled = false;
 bool            urgent_enabled = false;
+int             composite_enabled = 0;
+double          opacity_focus = 1.0;
+double          opacity_unfocus = 0.6;
 char           *clock_format = NULL;
 bool            window_class_enabled = false;
 bool            window_instance_enabled = false;
@@ -710,6 +713,7 @@ enum {
        _NET_WM_STATE_MAXIMIZED_HORZ,
        _NET_WM_STATE_SKIP_PAGER,
        _NET_WM_STATE_SKIP_TASKBAR,
+       _NET_WM_WINDOW_OPACITY,
        _NET_WM_WINDOW_TYPE,
        _NET_WM_WINDOW_TYPE_DIALOG,
        _NET_WM_WINDOW_TYPE_DOCK,
@@ -753,6 +757,7 @@ struct ewmh_hint {
     {"_NET_WM_STATE_MAXIMIZED_HORZ", XCB_ATOM_NONE},
     {"_NET_WM_STATE_SKIP_PAGER", XCB_ATOM_NONE},
     {"_NET_WM_STATE_SKIP_TASKBAR", XCB_ATOM_NONE},
+    {"_NET_WM_WINDOW_OPACITY", XCB_ATOM_NONE},
     {"_NET_WM_WINDOW_TYPE", XCB_ATOM_NONE},
     {"_NET_WM_WINDOW_TYPE_DIALOG", XCB_ATOM_NONE},
     {"_NET_WM_WINDOW_TYPE_DOCK", XCB_ATOM_NONE},
@@ -1129,6 +1134,7 @@ void       setup_quirks(void);
 void    setup_screens(void);
 void    setup_spawn(void);
 void    set_child_transient(struct ws_win *, xcb_window_t *);
+void    set_opacity(struct ws_win *, uint32_t);
 void    set_win_state(struct ws_win *, uint8_t);
 void    shutdown_cleanup(void);
 void    sighdlr(int);
@@ -3436,6 +3442,19 @@ validate_ws(struct workspace *testws)
        return (1);
 }
 
+#define OPAQUE         0xffffffff
+void
+set_opacity(struct ws_win *win, uint32_t opacity)
+{
+       if (opacity != OPAQUE)
+               xcb_change_property(conn, XCB_PROP_MODE_REPLACE, win->id,
+                   ewmh[_NET_WM_WINDOW_OPACITY].atom, XCB_ATOM_CARDINAL, 32, 1,
+                   &opacity);
+       else
+               xcb_delete_property(conn, win->id,
+                   ewmh[_NET_WM_WINDOW_OPACITY].atom);
+}
+
 void
 unfocus_win(struct ws_win *win)
 {
@@ -3523,6 +3542,10 @@ focus_win(struct ws_win *win)
                                    &cfw->s->c[(MAXIMIZED(cfw) ?
                                    SWM_S_COLOR_UNFOCUS_MAXIMIZED :
                                    SWM_S_COLOR_UNFOCUS)].pixel);
+
+                               if (composite_enabled)
+                                       set_opacity(cfw,
+                                           opacity_unfocus * OPAQUE);
                        } else {
                                unfocus_win(cfw);
                        }
@@ -6048,15 +6071,22 @@ update_window_color(struct ws_win *win)
 {
        uint32_t        *pixel;
 
-       if (WS_FOCUSED(win->ws) && win->ws->focus == win)
+       if (WS_FOCUSED(win->ws) && win->ws->focus == win) {
                pixel = MAXIMIZED(win) ?
                    &win->s->c[SWM_S_COLOR_FOCUS_MAXIMIZED].pixel :
                    &win->s->c[SWM_S_COLOR_FOCUS].pixel;
-       else
+
+               if (composite_enabled)
+                       set_opacity(win, opacity_focus * OPAQUE);
+       } else {
                pixel = MAXIMIZED(win) ?
                    &win->s->c[SWM_S_COLOR_UNFOCUS_MAXIMIZED].pixel :
                    &win->s->c[SWM_S_COLOR_UNFOCUS].pixel;
 
+               if (composite_enabled)
+                       set_opacity(win, opacity_unfocus * OPAQUE);
+       }
+
        xcb_change_window_attributes(conn, win->id,
            XCB_CW_BORDER_PIXEL, pixel);
 }
@@ -7840,6 +7870,7 @@ enum {
        SWM_S_BOUNDARY_WIDTH,
        SWM_S_CLOCK_ENABLED,
        SWM_S_CLOCK_FORMAT,
+       SWM_S_COMPOSITE_ENABLED,
        SWM_S_CYCLE_EMPTY,
        SWM_S_CYCLE_VISIBLE,
        SWM_S_DIALOG_RATIO,
@@ -7850,6 +7881,8 @@ enum {
        SWM_S_FOCUS_MODE,
        SWM_S_ICONIC_ENABLED,
        SWM_S_JAVA_WORKAROUND,
+       SWM_S_OPACITY_FOCUS,
+       SWM_S_OPACITY_UNFOCUS,
        SWM_S_REGION_PADDING,
        SWM_S_SPAWN_ORDER,
        SWM_S_SPAWN_TERM,
@@ -8062,6 +8095,23 @@ setconfvalue(const char *selector, const char *value, int flags)
        case SWM_S_URGENT_ENABLED:
                urgent_enabled = (atoi(value) != 0);
                break;
+       case SWM_S_COMPOSITE_ENABLED:
+               composite_enabled = atoi(value);
+               break;
+       case SWM_S_OPACITY_FOCUS:
+               opacity_focus = atof(value);
+               if (opacity_focus > 1.0)
+                       opacity_focus = 1.0;
+               else if (opacity_focus < 0.0)
+                       opacity_focus = 0.0;
+               break;
+       case SWM_S_OPACITY_UNFOCUS:
+               opacity_unfocus = atof(value);
+               if (opacity_unfocus > 1.0)
+                       opacity_unfocus = 1.0;
+               else if (opacity_unfocus < 0.0)
+                       opacity_unfocus = 0.0;
+               break;
        case SWM_S_VERBOSE_LAYOUT:
                verbose_layout = (atoi(value) != 0);
                for (i = 0; layouts[i].l_stack != NULL; i++) {
@@ -8376,6 +8426,7 @@ struct config_option configopt[] = {
        { "color_focus_maximized",      setconfcolor,   SWM_S_COLOR_FOCUS_MAXIMIZED },
        { "color_unfocus",              setconfcolor,   SWM_S_COLOR_UNFOCUS },
        { "color_unfocus_maximized",    setconfcolor,   SWM_S_COLOR_UNFOCUS_MAXIMIZED },
+       { "composite_enabled",          setconfvalue,   SWM_S_COMPOSITE_ENABLED },
        { "cycle_empty",                setconfvalue,   SWM_S_CYCLE_EMPTY },
        { "cycle_visible",              setconfvalue,   SWM_S_CYCLE_VISIBLE },
        { "dialog_ratio",               setconfvalue,   SWM_S_DIALOG_RATIO },
@@ -8389,6 +8440,8 @@ struct config_option configopt[] = {
        { "keyboard_mapping",           setkeymapping,  0 },
        { "layout",                     setlayout,      0 },
        { "modkey",                     setconfmodkey,  0 },
+       { "opacity_focus",              setconfvalue,   SWM_S_OPACITY_FOCUS },
+       { "opacity_unfocus",            setconfvalue,   SWM_S_OPACITY_UNFOCUS },
        { "program",                    setconfspawn,   0 },
        { "quirk",                      setconfquirk,   0 },
        { "region",                     setconfregion,  0 },
@@ -8787,6 +8840,9 @@ manage_window(xcb_window_t id, int spawn_pos, bool mapped)
        xcb_change_window_attributes(conn, win->id, XCB_CW_BORDER_PIXEL |
            XCB_CW_EVENT_MASK, wa);
 
+       if (composite_enabled)
+               set_opacity(win, opacity_unfocus * OPAQUE);
+
        /* Get WM_SIZE_HINTS. */
        xcb_icccm_get_wm_normal_hints_reply(conn,
            xcb_icccm_get_wm_normal_hints(conn, win->id),
index fc012ce..f485c49 100644 (file)
 # Remove window border when bar is disabled and there is only one window in workspace
 # disable_border               = 1
 
+# Hinting for composite managers such as xcompmgr
+# composite_enabled    = 1
+# opacity_focus                = 1.0
+# opacity_unfocus      = 0.6
+
 # Bar Settings
 # bar_enabled          = 1
 # bar_border_width     = 1