mirror of
https://github.com/vale981/spectrwm
synced 2025-03-04 17:31:40 -05:00
Add support for _NET_WM_WINDOW_OPACITY.
Enables using compositing manager transparency to provide additional options for visual feedback. New options are available to enable/configure window opacity: opacity_hinting - utilize compositing manager window transparency. opacity_focus - opacity of focused window. opacity_unfocus - opacity of unfocused window. bar_opacity_focus - opacity of the status bar on the focused region. bar_opacity_unfocus - opacity of the status bar on unfocused regions. Opacity values range from 0.0 (fully transparent) to 1.0 (opaque). Default values: opacity_hinting = 0 # (disabled) opacity_focus = 1.0 opacity_unfocus = 0.75 bar_opacity_focus[1] = 1.0 bar_opacity_unfocus[1] = 0.75 Add ALWAYSOPAQUE quirk - disable opacity hinting on matching window(s).
This commit is contained in:
parent
b9053600c8
commit
141403f748
3 changed files with 267 additions and 65 deletions
31
spectrwm.1
31
spectrwm.1
|
@ -246,6 +246,20 @@ in some circumstances, due to the white-spaces in the default static format.
|
|||
See the
|
||||
.Ic bar_format
|
||||
option for more details.
|
||||
.It Ic bar_opacity_focus
|
||||
Bar transparency of the focused region on screen
|
||||
.Ar x
|
||||
when
|
||||
.Ic opacity_hinting
|
||||
is enabled. Values range from 0.0 (fully transparent) to 1.0 (opaque).
|
||||
Default is 1.0.
|
||||
.It Ic bar_opacity_unfocus Ns Bq Ar x
|
||||
Bar transparency of unfocused region(s) on screen
|
||||
.Ar x
|
||||
when
|
||||
.Ic opacity_hinting
|
||||
is enabled. Values range from 0.0 (fully transparent) to 1.0 (opaque).
|
||||
Default is 0.75.
|
||||
.It Ic bind Ns Bq Ar x
|
||||
Bind key or button combo to action
|
||||
.Ar x .
|
||||
|
@ -389,6 +403,19 @@ Defined in the format
|
|||
.Li ws Ns Bo Ar idx Bc : Ns Ar name ,
|
||||
e.g. ws[1]:Console sets the name of workspace 1 to
|
||||
.Dq Console .
|
||||
.It Ic opacity_focus
|
||||
The transparency of the focused window when
|
||||
.Ic opacity_hinting
|
||||
is enabled. Values range from 0.0 (fully transparent) to 1.0 (opaque).
|
||||
Default is 1.0.
|
||||
.It Ic opacity_hinting
|
||||
Utilize compositing manager window opacity (_NET_WM_WINDOW_OPACITY) as
|
||||
complementary visual feedback. Enable by setting to 1.
|
||||
.It Ic opacity_unfocus
|
||||
The transparency of unfocused windows when
|
||||
.Ic opacity_hinting
|
||||
is enabled. Values range from 0.0 (fully transparent) to 1.0 (opaque).
|
||||
Default is 0.75.
|
||||
.It Ic program Ns Bq Ar p
|
||||
Define new action to spawn a program
|
||||
.Ar p .
|
||||
|
@ -1157,6 +1184,10 @@ XTERM_FONTADJ
|
|||
The quirks themselves are described below:
|
||||
.Pp
|
||||
.Bl -tag -width "XTERM_FONTADJ<TAB>XXX" -offset indent -compact
|
||||
.It ALWAYSOPAQUE
|
||||
When
|
||||
.Ic opacity_hinting
|
||||
is enabled, disregard this window.
|
||||
.It ANYWHERE
|
||||
Allow window to position itself, uncentered.
|
||||
.It FLOAT
|
||||
|
|
294
spectrwm.c
294
spectrwm.c
|
@ -205,6 +205,8 @@ uint32_t swm_debug = 0
|
|||
|
||||
#define EWMH_F_MAXIMIZED (EWMH_F_MAXIMIZED_VERT | EWMH_F_MAXIMIZED_HORZ)
|
||||
|
||||
#define OPACITY_OPAQUE (0xffffffff)
|
||||
|
||||
/* convert 8-bit to 16-bit */
|
||||
#define RGB_8_TO_16(col) (((col) << 8) + (col))
|
||||
|
||||
|
@ -403,6 +405,9 @@ bool iconic_enabled = false;
|
|||
bool maximize_hide_bar = false;
|
||||
bool urgent_enabled = false;
|
||||
bool urgent_collapse = false;
|
||||
bool opacity_hinting = false;
|
||||
uint32_t opacity_focus = OPACITY_OPAQUE;
|
||||
uint32_t opacity_unfocus = (0.8 * OPACITY_OPAQUE);
|
||||
char *clock_format = NULL;
|
||||
bool window_class_enabled = false;
|
||||
bool window_instance_enabled = false;
|
||||
|
@ -450,6 +455,7 @@ struct swm_bar {
|
|||
xcb_pixmap_t buffer;
|
||||
struct swm_geometry g;
|
||||
struct swm_region *r; /* Associated region. */
|
||||
uint32_t opacity; /* Current opacity. */
|
||||
};
|
||||
|
||||
/* virtual "screens" */
|
||||
|
@ -486,6 +492,7 @@ struct ws_win {
|
|||
bool mapped;
|
||||
uint8_t state;
|
||||
bool bordered;
|
||||
uint32_t opacity;
|
||||
uint32_t ewmh_flags;
|
||||
int font_size_boundary[SWM_MAX_FONT_STEPS];
|
||||
int font_steps;
|
||||
|
@ -587,9 +594,9 @@ enum {
|
|||
};
|
||||
|
||||
enum {
|
||||
SWM_S_COLOR_BAR,
|
||||
SWM_S_COLOR_BAR_FOCUS,
|
||||
SWM_S_COLOR_BAR_SELECTED,
|
||||
SWM_S_COLOR_BAR_BORDER,
|
||||
SWM_S_COLOR_BAR_BORDER_FOCUS,
|
||||
SWM_S_COLOR_BAR_BORDER_UNFOCUS,
|
||||
SWM_S_COLOR_BAR_FONT,
|
||||
SWM_S_COLOR_BAR_FONT_SELECTED,
|
||||
|
@ -627,6 +634,8 @@ struct swm_screen {
|
|||
Visual *xvisual; /* Needed for Xft. */
|
||||
xcb_colormap_t colormap;
|
||||
xcb_gcontext_t gc;
|
||||
uint32_t bar_opacity_focus;
|
||||
uint32_t bar_opacity_unfocus;
|
||||
};
|
||||
struct swm_screen *screens;
|
||||
|
||||
|
@ -708,6 +717,7 @@ struct quirk {
|
|||
#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) /* No border when floating/unfocused. */
|
||||
#define SWM_Q_ALWAYSOPAQUE (1<<13) /* No opacity hinting. */
|
||||
};
|
||||
TAILQ_HEAD(quirk_list, quirk) quirks = TAILQ_HEAD_INITIALIZER(quirks);
|
||||
|
||||
|
@ -744,6 +754,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,
|
||||
|
@ -758,44 +769,46 @@ enum {
|
|||
struct ewmh_hint {
|
||||
char *name;
|
||||
xcb_atom_t atom;
|
||||
bool enabled;
|
||||
} ewmh[SWM_EWMH_HINT_MAX] = {
|
||||
/* must be in same order as in the enum */
|
||||
{"_NET_ACTIVE_WINDOW", XCB_ATOM_NONE},
|
||||
{"_NET_CLIENT_LIST", XCB_ATOM_NONE},
|
||||
{"_NET_CLOSE_WINDOW", XCB_ATOM_NONE},
|
||||
{"_NET_CURRENT_DESKTOP", XCB_ATOM_NONE},
|
||||
{"_NET_DESKTOP_GEOMETRY", XCB_ATOM_NONE},
|
||||
{"_NET_DESKTOP_NAMES", XCB_ATOM_NONE},
|
||||
{"_NET_DESKTOP_VIEWPORT", XCB_ATOM_NONE},
|
||||
{"_NET_MOVERESIZE_WINDOW", XCB_ATOM_NONE},
|
||||
{"_NET_NUMBER_OF_DESKTOPS", XCB_ATOM_NONE},
|
||||
{"_NET_REQUEST_FRAME_EXTENTS", XCB_ATOM_NONE},
|
||||
{"_NET_RESTACK_WINDOW", XCB_ATOM_NONE},
|
||||
{"_NET_WM_ACTION_ABOVE", XCB_ATOM_NONE},
|
||||
{"_NET_WM_ACTION_CLOSE", XCB_ATOM_NONE},
|
||||
{"_NET_WM_ACTION_FULLSCREEN", XCB_ATOM_NONE},
|
||||
{"_NET_WM_ACTION_MOVE", XCB_ATOM_NONE},
|
||||
{"_NET_WM_ACTION_RESIZE", XCB_ATOM_NONE},
|
||||
{"_NET_WM_ALLOWED_ACTIONS", XCB_ATOM_NONE},
|
||||
{"_NET_WM_DESKTOP", XCB_ATOM_NONE},
|
||||
{"_NET_WM_FULL_PLACEMENT", XCB_ATOM_NONE},
|
||||
{"_NET_WM_NAME", XCB_ATOM_NONE},
|
||||
{"_NET_WM_STATE", XCB_ATOM_NONE},
|
||||
{"_NET_WM_STATE_ABOVE", XCB_ATOM_NONE},
|
||||
{"_NET_WM_STATE_FULLSCREEN", XCB_ATOM_NONE},
|
||||
{"_NET_WM_STATE_HIDDEN", XCB_ATOM_NONE},
|
||||
{"_NET_WM_STATE_MAXIMIZED_VERT", XCB_ATOM_NONE},
|
||||
{"_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_TYPE", XCB_ATOM_NONE},
|
||||
{"_NET_WM_WINDOW_TYPE_DIALOG", XCB_ATOM_NONE},
|
||||
{"_NET_WM_WINDOW_TYPE_DOCK", XCB_ATOM_NONE},
|
||||
{"_NET_WM_WINDOW_TYPE_NORMAL", XCB_ATOM_NONE},
|
||||
{"_NET_WM_WINDOW_TYPE_SPLASH", XCB_ATOM_NONE},
|
||||
{"_NET_WM_WINDOW_TYPE_TOOLBAR", XCB_ATOM_NONE},
|
||||
{"_NET_WM_WINDOW_TYPE_UTILITY", XCB_ATOM_NONE},
|
||||
{"_SWM_WM_STATE_MANUAL", XCB_ATOM_NONE},
|
||||
{"_NET_ACTIVE_WINDOW", XCB_ATOM_NONE, true},
|
||||
{"_NET_CLIENT_LIST", XCB_ATOM_NONE, true},
|
||||
{"_NET_CLOSE_WINDOW", XCB_ATOM_NONE, true},
|
||||
{"_NET_CURRENT_DESKTOP", XCB_ATOM_NONE, true},
|
||||
{"_NET_DESKTOP_GEOMETRY", XCB_ATOM_NONE, true},
|
||||
{"_NET_DESKTOP_NAMES", XCB_ATOM_NONE, true},
|
||||
{"_NET_DESKTOP_VIEWPORT", XCB_ATOM_NONE, true},
|
||||
{"_NET_MOVERESIZE_WINDOW", XCB_ATOM_NONE, true},
|
||||
{"_NET_NUMBER_OF_DESKTOPS", XCB_ATOM_NONE, true},
|
||||
{"_NET_REQUEST_FRAME_EXTENTS", XCB_ATOM_NONE, true},
|
||||
{"_NET_RESTACK_WINDOW", XCB_ATOM_NONE, true},
|
||||
{"_NET_WM_ACTION_ABOVE", XCB_ATOM_NONE, true},
|
||||
{"_NET_WM_ACTION_CLOSE", XCB_ATOM_NONE, true},
|
||||
{"_NET_WM_ACTION_FULLSCREEN", XCB_ATOM_NONE, true},
|
||||
{"_NET_WM_ACTION_MOVE", XCB_ATOM_NONE, true},
|
||||
{"_NET_WM_ACTION_RESIZE", XCB_ATOM_NONE, true},
|
||||
{"_NET_WM_ALLOWED_ACTIONS", XCB_ATOM_NONE, true},
|
||||
{"_NET_WM_DESKTOP", XCB_ATOM_NONE, true},
|
||||
{"_NET_WM_FULL_PLACEMENT", XCB_ATOM_NONE, true},
|
||||
{"_NET_WM_NAME", XCB_ATOM_NONE, true},
|
||||
{"_NET_WM_STATE", XCB_ATOM_NONE, true},
|
||||
{"_NET_WM_STATE_ABOVE", XCB_ATOM_NONE, true},
|
||||
{"_NET_WM_STATE_FULLSCREEN", XCB_ATOM_NONE, true},
|
||||
{"_NET_WM_STATE_HIDDEN", XCB_ATOM_NONE, true},
|
||||
{"_NET_WM_STATE_MAXIMIZED_VERT", XCB_ATOM_NONE, true},
|
||||
{"_NET_WM_STATE_MAXIMIZED_HORZ", XCB_ATOM_NONE, true},
|
||||
{"_NET_WM_STATE_SKIP_PAGER", XCB_ATOM_NONE, true},
|
||||
{"_NET_WM_STATE_SKIP_TASKBAR", XCB_ATOM_NONE, true},
|
||||
{"_NET_WM_WINDOW_OPACITY", XCB_ATOM_NONE, false},
|
||||
{"_NET_WM_WINDOW_TYPE", XCB_ATOM_NONE, true},
|
||||
{"_NET_WM_WINDOW_TYPE_DIALOG", XCB_ATOM_NONE, true},
|
||||
{"_NET_WM_WINDOW_TYPE_DOCK", XCB_ATOM_NONE, true},
|
||||
{"_NET_WM_WINDOW_TYPE_NORMAL", XCB_ATOM_NONE, true},
|
||||
{"_NET_WM_WINDOW_TYPE_SPLASH", XCB_ATOM_NONE, true},
|
||||
{"_NET_WM_WINDOW_TYPE_TOOLBAR", XCB_ATOM_NONE, true},
|
||||
{"_NET_WM_WINDOW_TYPE_UTILITY", XCB_ATOM_NONE, true},
|
||||
{"_SWM_WM_STATE_MANUAL", XCB_ATOM_NONE, true},
|
||||
};
|
||||
|
||||
/* EWMH source type */
|
||||
|
@ -1080,6 +1093,7 @@ void ewmh_update_client_list(void);
|
|||
void ewmh_update_current_desktop(void);
|
||||
void ewmh_update_desktop_names(void);
|
||||
void ewmh_update_desktops(void);
|
||||
void ewmh_update_supported(void);
|
||||
void ewmh_change_wm_state(struct ws_win *, xcb_atom_t, long);
|
||||
void ewmh_update_wm_state(struct ws_win *);
|
||||
char *expand_tilde(const char *);
|
||||
|
@ -1209,6 +1223,7 @@ void search_workspace(struct binding *, struct swm_region *, union arg *);
|
|||
void send_to_rg(struct binding *, struct swm_region *, union arg *);
|
||||
void send_to_rg_relative(struct binding *, struct swm_region *, union arg *);
|
||||
void send_to_ws(struct binding *, struct swm_region *, union arg *);
|
||||
void set_bar_opacity(struct swm_bar *, uint32_t);
|
||||
void set_region(struct swm_region *);
|
||||
int setautorun(const char *, const char *, int);
|
||||
void setbinding(uint16_t, enum binding_type, uint32_t, enum actionid,
|
||||
|
@ -1216,6 +1231,7 @@ void setbinding(uint16_t, enum binding_type, uint32_t, enum actionid,
|
|||
int setconfbinding(const char *, const char *, int);
|
||||
int setconfcolor(const char *, const char *, int);
|
||||
int setconfmodkey(const char *, const char *, int);
|
||||
int setconfopacity(const char *, const char *, int);
|
||||
int setconfquirk(const char *, const char *, int);
|
||||
int setconfregion(const char *, const char *, int);
|
||||
int setconfspawn(const char *, const char *, int);
|
||||
|
@ -1234,6 +1250,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_win_opacity(struct ws_win *, uint32_t);
|
||||
void set_win_state(struct ws_win *, uint8_t);
|
||||
void shutdown_cleanup(void);
|
||||
void sighdlr(int);
|
||||
|
@ -1513,7 +1530,7 @@ void
|
|||
setup_ewmh(void)
|
||||
{
|
||||
xcb_window_t root, win;
|
||||
int i, j, num_screens;
|
||||
int i, num_screens;
|
||||
|
||||
for (i = 0; i < LENGTH(ewmh); i++)
|
||||
ewmh[i].atom = get_atom_from_string(ewmh[i].name);
|
||||
|
@ -1536,18 +1553,34 @@ setup_ewmh(void)
|
|||
xcb_change_property(conn, XCB_PROP_MODE_REPLACE, win,
|
||||
ewmh[_NET_WM_NAME].atom, a_utf8_string,
|
||||
8, strlen("spectrwm"), "spectrwm");
|
||||
}
|
||||
|
||||
ewmh_update_supported();
|
||||
ewmh_update_desktops();
|
||||
ewmh_get_desktop_names();
|
||||
}
|
||||
|
||||
void
|
||||
ewmh_update_supported(void)
|
||||
{
|
||||
xcb_window_t root;
|
||||
int i, j, num_screens;
|
||||
|
||||
num_screens = get_screen_count();
|
||||
for (i = 0; i < num_screens; i++) {
|
||||
root = screens[i].root;
|
||||
|
||||
/* Report supported atoms */
|
||||
xcb_delete_property(conn, root, a_net_supported);
|
||||
for (j = 0; j < LENGTH(ewmh); j++)
|
||||
for (j = 0; j < LENGTH(ewmh); j++) {
|
||||
if (!ewmh[j].enabled)
|
||||
continue;
|
||||
xcb_change_property(conn, XCB_PROP_MODE_APPEND, root,
|
||||
a_net_supported, XCB_ATOM_ATOM, 32, 1,
|
||||
&ewmh[j].atom);
|
||||
|
||||
DNPRINTF(SWM_D_CONF, "adding %s\n", ewmh[j].name);
|
||||
}
|
||||
}
|
||||
|
||||
ewmh_update_desktops();
|
||||
ewmh_get_desktop_names();
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1573,10 +1606,12 @@ teardown_ewmh(void)
|
|||
xcb_destroy_window(conn, id);
|
||||
xcb_delete_property(conn, screens[i].root,
|
||||
a_net_wm_check);
|
||||
xcb_delete_property(conn, screens[i].root,
|
||||
a_net_supported);
|
||||
}
|
||||
free(pr);
|
||||
|
||||
/* Cleanup _NET_SUPPORTED */
|
||||
xcb_delete_property(conn, screens[i].root,
|
||||
a_net_supported);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1951,8 +1986,8 @@ debug_refresh(struct ws_win *win)
|
|||
win->s->idx);
|
||||
|
||||
win->debug = xcb_generate_id(conn);
|
||||
wc[0] = win->s->c[SWM_S_COLOR_BAR].pixel;
|
||||
wc[1] = win->s->c[SWM_S_COLOR_BAR_BORDER].pixel;
|
||||
wc[0] = win->s->c[SWM_S_COLOR_BAR_FOCUS].pixel;
|
||||
wc[1] = win->s->c[SWM_S_COLOR_BAR_BORDER_FOCUS].pixel;
|
||||
wc[2] = win->s->colormap;
|
||||
|
||||
xcb_create_window(conn, win->s->depth, win->debug,
|
||||
|
@ -2018,7 +2053,7 @@ debug_refresh(struct ws_win *win)
|
|||
rect.width = width;
|
||||
rect.height = height;
|
||||
|
||||
gcv[0] = win->s->c[SWM_S_COLOR_BAR].pixel;
|
||||
gcv[0] = win->s->c[SWM_S_COLOR_BAR_FOCUS].pixel;
|
||||
xcb_change_gc(conn, win->s->gc, XCB_GC_FOREGROUND, gcv);
|
||||
xcb_poly_fill_rectangle(conn, win->debug, win->s->gc, 1, &rect);
|
||||
|
||||
|
@ -2301,7 +2336,7 @@ bar_print_legacy(struct swm_region *r, const char *s)
|
|||
rect.width = WIDTH(r->bar);
|
||||
rect.height = HEIGHT(r->bar);
|
||||
|
||||
gcv[0] = r->s->c[SWM_S_COLOR_BAR].pixel;
|
||||
gcv[0] = r->s->c[SWM_S_COLOR_BAR_FOCUS].pixel;
|
||||
xcb_change_gc(conn, r->s->gc, XCB_GC_FOREGROUND, gcv);
|
||||
xcb_poly_fill_rectangle(conn, r->bar->buffer, r->s->gc, 1, &rect);
|
||||
|
||||
|
@ -2354,7 +2389,7 @@ bar_print(struct swm_region *r, const char *s)
|
|||
rect.width = WIDTH(r->bar);
|
||||
rect.height = HEIGHT(r->bar);
|
||||
|
||||
gcv[0] = r->s->c[SWM_S_COLOR_BAR].pixel;
|
||||
gcv[0] = r->s->c[SWM_S_COLOR_BAR_FOCUS].pixel;
|
||||
xcb_change_gc(conn, r->s->gc, XCB_GC_FOREGROUND, gcv);
|
||||
xcb_poly_fill_rectangle(conn, r->bar->buffer, r->s->gc, 1, &rect);
|
||||
|
||||
|
@ -3123,7 +3158,7 @@ xft_init(struct swm_region *r)
|
|||
&color, &bar_font_color))
|
||||
warn("Xft error: unable to allocate color.");
|
||||
|
||||
PIXEL_TO_XRENDERCOLOR(r->s->c[SWM_S_COLOR_BAR].pixel, color);
|
||||
PIXEL_TO_XRENDERCOLOR(r->s->c[SWM_S_COLOR_BAR_FOCUS].pixel, color);
|
||||
|
||||
if (!XftColorAllocValue(display, r->s->xvisual, r->s->colormap, &color,
|
||||
&search_font_color))
|
||||
|
@ -3162,10 +3197,11 @@ bar_setup(struct swm_region *r)
|
|||
Y(r->bar) = bar_at_bottom ? (Y(r) + HEIGHT(r) - bar_height) : Y(r);
|
||||
WIDTH(r->bar) = WIDTH(r) - 2 * bar_border_width;
|
||||
HEIGHT(r->bar) = bar_height - 2 * bar_border_width;
|
||||
r->bar->opacity = OPACITY_OPAQUE;
|
||||
|
||||
/* Assume region is unfocused when we create the bar. */
|
||||
r->bar->id = xcb_generate_id(conn);
|
||||
wa[0] = r->s->c[SWM_S_COLOR_BAR].pixel;
|
||||
wa[0] = r->s->c[SWM_S_COLOR_BAR_FOCUS].pixel;
|
||||
wa[1] = r->s->c[SWM_S_COLOR_BAR_BORDER_UNFOCUS].pixel;
|
||||
wa[2] = XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_POINTER_MOTION |
|
||||
XCB_EVENT_MASK_POINTER_MOTION_HINT;
|
||||
|
@ -4028,6 +4064,47 @@ validate_ws(struct workspace *testws)
|
|||
return (1);
|
||||
}
|
||||
|
||||
void
|
||||
set_bar_opacity(struct swm_bar *bar, uint32_t opacity)
|
||||
{
|
||||
if (opacity == bar->opacity)
|
||||
return;
|
||||
DNPRINTF(SWM_D_BAR, "id: %#x, cur_opacity: %#x, opacity: %#x\n",
|
||||
bar->id, bar->opacity, opacity);
|
||||
|
||||
if (opacity != OPACITY_OPAQUE) {
|
||||
xcb_change_property(conn, XCB_PROP_MODE_REPLACE, bar->id,
|
||||
ewmh[_NET_WM_WINDOW_OPACITY].atom, XCB_ATOM_CARDINAL, 32, 1,
|
||||
&opacity);
|
||||
} else {
|
||||
xcb_delete_property(conn, bar->id,
|
||||
ewmh[_NET_WM_WINDOW_OPACITY].atom);
|
||||
}
|
||||
|
||||
bar->opacity = opacity;
|
||||
}
|
||||
|
||||
void
|
||||
set_win_opacity(struct ws_win *win, uint32_t opacity)
|
||||
{
|
||||
if (win->quirks & SWM_Q_ALWAYSOPAQUE)
|
||||
return;
|
||||
|
||||
if (opacity == win->opacity)
|
||||
return;
|
||||
|
||||
if (opacity != OPACITY_OPAQUE) {
|
||||
xcb_change_property(conn, XCB_PROP_MODE_REPLACE, win->frame,
|
||||
ewmh[_NET_WM_WINDOW_OPACITY].atom, XCB_ATOM_CARDINAL, 32, 1,
|
||||
&opacity);
|
||||
} else {
|
||||
xcb_delete_property(conn, win->frame,
|
||||
ewmh[_NET_WM_WINDOW_OPACITY].atom);
|
||||
}
|
||||
|
||||
win->opacity = opacity;
|
||||
}
|
||||
|
||||
void
|
||||
unfocus_win(struct ws_win *win)
|
||||
{
|
||||
|
@ -4142,6 +4219,8 @@ focus_win(struct ws_win *win)
|
|||
DNPRINTF(SWM_D_FOCUS, "skip refocus "
|
||||
"from override_redirect.\n");
|
||||
goto out;
|
||||
} else {
|
||||
unfocus_win(cfw);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4312,6 +4391,9 @@ set_region(struct swm_region *r)
|
|||
xcb_change_window_attributes(conn, rf->bar->id,
|
||||
XCB_CW_BORDER_PIXEL,
|
||||
&r->s->c[SWM_S_COLOR_BAR_BORDER_UNFOCUS].pixel);
|
||||
|
||||
if (opacity_hinting)
|
||||
set_bar_opacity(rf->bar, r->s->bar_opacity_unfocus);
|
||||
}
|
||||
|
||||
if (rf != NULL && rf != r && (X(rf) != X(r) || Y(rf) != Y(r) ||
|
||||
|
@ -4326,7 +4408,10 @@ set_region(struct swm_region *r)
|
|||
|
||||
/* Set region bar border to focus_color. */
|
||||
xcb_change_window_attributes(conn, r->bar->id,
|
||||
XCB_CW_BORDER_PIXEL, &r->s->c[SWM_S_COLOR_BAR_BORDER].pixel);
|
||||
XCB_CW_BORDER_PIXEL, &r->s->c[SWM_S_COLOR_BAR_BORDER_FOCUS].pixel);
|
||||
|
||||
if (opacity_hinting)
|
||||
set_bar_opacity(r->bar, r->s->bar_opacity_focus);
|
||||
|
||||
r->s->r_focus = r;
|
||||
|
||||
|
@ -6326,7 +6411,7 @@ search_win(struct binding *bp, struct swm_region *r, union arg *args)
|
|||
l_draw = XCreateGC(display, w, 0, &l_gcv);
|
||||
|
||||
XSetForeground(display, l_draw,
|
||||
r->s->c[SWM_S_COLOR_BAR].pixel);
|
||||
r->s->c[SWM_S_COLOR_BAR_FOCUS].pixel);
|
||||
|
||||
DRAWSTRING(display, w, bar_fs, l_draw, 2,
|
||||
(bar_fs_extents->max_logical_extent.height -
|
||||
|
@ -6929,15 +7014,22 @@ draw_frame(struct ws_win *win)
|
|||
DNPRINTF(SWM_D_EVENT, "win %#x frame disabled\n", win->id);
|
||||
}
|
||||
|
||||
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 (opacity_hinting)
|
||||
set_win_opacity(win, opacity_focus);
|
||||
} else {
|
||||
pixel = MAXIMIZED(win) ?
|
||||
&win->s->c[SWM_S_COLOR_UNFOCUS_MAXIMIZED].pixel :
|
||||
&win->s->c[SWM_S_COLOR_UNFOCUS].pixel;
|
||||
|
||||
if (opacity_hinting)
|
||||
set_win_opacity(win, opacity_unfocus);
|
||||
}
|
||||
|
||||
/* Top (with corners) */
|
||||
rect[n].x = 0;
|
||||
rect[n].y = 0;
|
||||
|
@ -7784,12 +7876,12 @@ spawn_expand(struct swm_region *r, union arg *args, const char *spawn_name,
|
|||
DNPRINTF(SWM_D_SPAWN, "raw arg: %s\n", ap);
|
||||
if (strcasecmp(ap, "$bar_border") == 0) {
|
||||
if ((real_args[c] =
|
||||
strdup(r->s->c[SWM_S_COLOR_BAR_BORDER].name))
|
||||
strdup(r->s->c[SWM_S_COLOR_BAR_BORDER_FOCUS].name))
|
||||
== NULL)
|
||||
err(1, "spawn_custom border color");
|
||||
} else if (strcasecmp(ap, "$bar_color") == 0) {
|
||||
if ((real_args[c] =
|
||||
strdup(r->s->c[SWM_S_COLOR_BAR].name))
|
||||
strdup(r->s->c[SWM_S_COLOR_BAR_FOCUS].name))
|
||||
== NULL)
|
||||
err(1, "spawn_custom bar color");
|
||||
} else if (strcasecmp(ap, "$bar_color_selected") == 0) {
|
||||
|
@ -8858,6 +8950,7 @@ const char *quirkname[] = {
|
|||
"IGNORESPAWNWS",
|
||||
"NOFOCUSCYCLE",
|
||||
"MINIMALBORDER",
|
||||
"ALWAYSOPAQUE",
|
||||
};
|
||||
|
||||
/* SWM_Q_DELIM: retain '|' for back compat for now (2009-08-11) */
|
||||
|
@ -9180,6 +9273,11 @@ enum {
|
|||
SWM_S_FOCUS_MODE,
|
||||
SWM_S_ICONIC_ENABLED,
|
||||
SWM_S_MAXIMIZE_HIDE_BAR,
|
||||
SWM_S_OPACITY_BAR_FOCUS,
|
||||
SWM_S_OPACITY_BAR_UNFOCUS,
|
||||
SWM_S_OPACITY_FOCUS,
|
||||
SWM_S_OPACITY_HINTING,
|
||||
SWM_S_OPACITY_UNFOCUS,
|
||||
SWM_S_REGION_PADDING,
|
||||
SWM_S_SPAWN_ORDER,
|
||||
SWM_S_SPAWN_TERM,
|
||||
|
@ -9390,6 +9488,11 @@ setconfvalue(const char *selector, const char *value, int flags)
|
|||
case SWM_S_URGENT_ENABLED:
|
||||
urgent_enabled = (atoi(value) != 0);
|
||||
break;
|
||||
case SWM_S_OPACITY_HINTING:
|
||||
opacity_hinting = (atoi(value) != 0);
|
||||
ewmh[_NET_WM_WINDOW_OPACITY].enabled = opacity_hinting;
|
||||
ewmh_update_supported();
|
||||
break;
|
||||
case SWM_S_VERBOSE_LAYOUT:
|
||||
verbose_layout = (atoi(value) != 0);
|
||||
for (i = 0; layouts[i].l_stack != NULL; i++) {
|
||||
|
@ -9484,6 +9587,57 @@ setconfmodkey(const char *selector, const char *value, int flags)
|
|||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
setconfopacity(const char *selector, const char *value, int flags)
|
||||
{
|
||||
int first, last, i = 0, num_screens;
|
||||
double d;
|
||||
uint32_t opacity;
|
||||
|
||||
num_screens = get_screen_count();
|
||||
|
||||
/* conf screen indices begin at 1; treat vals <= 0 as 'all screens.' */
|
||||
if (selector == NULL || strlen(selector) == 0 ||
|
||||
(last = atoi(selector) - 1) < 0) {
|
||||
first = 0;
|
||||
last = num_screens - 1;
|
||||
} else {
|
||||
first = last;
|
||||
}
|
||||
|
||||
if (last >= num_screens) {
|
||||
add_startup_exception("invalid screen index: %d out of bounds "
|
||||
"(maximum %d)", last + 1, num_screens);
|
||||
return (1);
|
||||
}
|
||||
|
||||
d = atof(value);
|
||||
if (d < 0.0)
|
||||
d = 0.0;
|
||||
else if (d > 1.0)
|
||||
d = 1.0;
|
||||
opacity = d * OPACITY_OPAQUE;
|
||||
|
||||
for (i = first; i <= last; ++i) {
|
||||
switch (flags) {
|
||||
case SWM_S_OPACITY_FOCUS:
|
||||
opacity_focus = opacity;
|
||||
break;
|
||||
case SWM_S_OPACITY_UNFOCUS:
|
||||
opacity_unfocus = opacity;
|
||||
break;
|
||||
case SWM_S_OPACITY_BAR_FOCUS:
|
||||
screens[i].bar_opacity_focus = opacity;
|
||||
break;
|
||||
case SWM_S_OPACITY_BAR_UNFOCUS:
|
||||
screens[i].bar_opacity_unfocus = opacity;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
setconfcolor(const char *selector, const char *value, int flags)
|
||||
{
|
||||
|
@ -9524,12 +9678,12 @@ setconfcolor(const char *selector, const char *value, int flags)
|
|||
setscreencolor(value, i,
|
||||
SWM_S_COLOR_UNFOCUS_MAXIMIZED);
|
||||
break;
|
||||
case SWM_S_COLOR_BAR:
|
||||
case SWM_S_COLOR_BAR_FOCUS:
|
||||
if (!screens[i].c[SWM_S_COLOR_BAR_FONT_SELECTED].manual)
|
||||
setscreencolor(value, i,
|
||||
SWM_S_COLOR_BAR_FONT_SELECTED);
|
||||
break;
|
||||
case SWM_S_COLOR_BAR_BORDER:
|
||||
case SWM_S_COLOR_BAR_BORDER_FOCUS:
|
||||
if (!screens[i].c[SWM_S_COLOR_BAR_SELECTED].manual)
|
||||
setscreencolor(value, i,
|
||||
SWM_S_COLOR_BAR_SELECTED);
|
||||
|
@ -9718,10 +9872,10 @@ struct config_option configopt[] = {
|
|||
{ "autorun", setautorun, 0 },
|
||||
{ "bar_action", setconfvalue, SWM_S_BAR_ACTION },
|
||||
{ "bar_at_bottom", setconfvalue, SWM_S_BAR_AT_BOTTOM },
|
||||
{ "bar_border", setconfcolor, SWM_S_COLOR_BAR_BORDER },
|
||||
{ "bar_border", setconfcolor, SWM_S_COLOR_BAR_BORDER_FOCUS },
|
||||
{ "bar_border_unfocus", setconfcolor, SWM_S_COLOR_BAR_BORDER_UNFOCUS },
|
||||
{ "bar_border_width", setconfvalue, SWM_S_BAR_BORDER_WIDTH },
|
||||
{ "bar_color", setconfcolor, SWM_S_COLOR_BAR },
|
||||
{ "bar_color", setconfcolor, SWM_S_COLOR_BAR_FOCUS },
|
||||
{ "bar_color_selected", setconfcolor, SWM_S_COLOR_BAR_SELECTED },
|
||||
{ "bar_delay", NULL, 0 }, /* dummy */
|
||||
{ "bar_enabled", setconfvalue, SWM_S_BAR_ENABLED },
|
||||
|
@ -9731,6 +9885,8 @@ struct config_option configopt[] = {
|
|||
{ "bar_font_color_selected", setconfcolor, SWM_S_COLOR_BAR_FONT_SELECTED },
|
||||
{ "bar_format", setconfvalue, SWM_S_BAR_FORMAT },
|
||||
{ "bar_justify", setconfvalue, SWM_S_BAR_JUSTIFY },
|
||||
{ "bar_opacity", setconfopacity, SWM_S_OPACITY_BAR_FOCUS },
|
||||
{ "bar_opacity_unfocus", setconfopacity, SWM_S_OPACITY_BAR_UNFOCUS },
|
||||
{ "bind", setconfbinding, 0 },
|
||||
{ "border_width", setconfvalue, SWM_S_BORDER_WIDTH },
|
||||
{ "boundary_width", setconfvalue, SWM_S_BOUNDARY_WIDTH },
|
||||
|
@ -9754,6 +9910,9 @@ struct config_option configopt[] = {
|
|||
{ "layout", setlayout, 0 },
|
||||
{ "maximize_hide_bar", setconfvalue, SWM_S_MAXIMIZE_HIDE_BAR },
|
||||
{ "modkey", setconfmodkey, 0 },
|
||||
{ "opacity_focus", setconfopacity, SWM_S_OPACITY_FOCUS },
|
||||
{ "opacity_hinting", setconfvalue, SWM_S_OPACITY_HINTING },
|
||||
{ "opacity_unfocus", setconfopacity, SWM_S_OPACITY_UNFOCUS },
|
||||
{ "program", setconfspawn, 0 },
|
||||
{ "quirk", setconfquirk, 0 },
|
||||
{ "region", setconfregion, 0 },
|
||||
|
@ -10118,6 +10277,9 @@ reparent_window(struct ws_win *win)
|
|||
win->s->visual, XCB_CW_BORDER_PIXEL | XCB_CW_EVENT_MASK |
|
||||
XCB_CW_COLORMAP, wa);
|
||||
|
||||
if (opacity_hinting)
|
||||
set_win_opacity(win, opacity_unfocus);
|
||||
|
||||
win->state = SWM_WIN_STATE_REPARENTING;
|
||||
c = xcb_reparent_window_checked(conn, win->id, win->frame, 0, 0);
|
||||
if ((error = xcb_request_check(conn, c))) {
|
||||
|
@ -12116,6 +12278,8 @@ setup_screens(void)
|
|||
DNPRINTF(SWM_D_WS, "init screen: %d\n", i);
|
||||
screens[i].idx = i;
|
||||
screens[i].r_focus = NULL;
|
||||
screens[i].bar_opacity_focus = OPACITY_OPAQUE;
|
||||
screens[i].bar_opacity_unfocus = 0.8 * OPACITY_OPAQUE;
|
||||
|
||||
TAILQ_INIT(&screens[i].rl);
|
||||
TAILQ_INIT(&screens[i].orl);
|
||||
|
@ -12178,10 +12342,10 @@ setup_screens(void)
|
|||
setscreencolor("rgb:88/88/88", i, SWM_S_COLOR_UNFOCUS);
|
||||
setscreencolor("rgb:88/88/88", i,
|
||||
SWM_S_COLOR_UNFOCUS_MAXIMIZED);
|
||||
setscreencolor("rgb:00/80/80", i, SWM_S_COLOR_BAR_BORDER);
|
||||
setscreencolor("rgb:00/80/80", i, SWM_S_COLOR_BAR_BORDER_FOCUS);
|
||||
setscreencolor("rgb:00/40/40", i,
|
||||
SWM_S_COLOR_BAR_BORDER_UNFOCUS);
|
||||
setscreencolor("black", i, SWM_S_COLOR_BAR);
|
||||
setscreencolor("black", i, SWM_S_COLOR_BAR_FOCUS);
|
||||
setscreencolor("rgb:00/80/80", i, SWM_S_COLOR_BAR_SELECTED);
|
||||
setscreencolor("rgb:a0/a0/a0", i, SWM_S_COLOR_BAR_FONT);
|
||||
setscreencolor("black", i, SWM_S_COLOR_BAR_FONT_SELECTED);
|
||||
|
|
|
@ -29,6 +29,13 @@
|
|||
# Remove window border when bar is disabled and there is only one window in workspace
|
||||
# disable_border = 1
|
||||
|
||||
# Utilize compositing manager window transparency as visual feedback.
|
||||
# opacity_hinting = 1
|
||||
# opacity_bar_focus[1] = 1.0
|
||||
# opacity_bar_unfocus[1] = 0.6
|
||||
# opacity_focus = 1.0
|
||||
# opacity_unfocus = 0.6
|
||||
|
||||
# Bar Settings
|
||||
# bar_enabled = 1
|
||||
# bar_border_width = 1
|
||||
|
|
Loading…
Add table
Reference in a new issue