/* dialog windows */
double dialog_ratio = 0.6;
/* status bar */
-#define SWM_BAR_MAX (256)
+#define SWM_BAR_MAX (356)
#define SWM_BAR_JUSTIFY_LEFT (0)
#define SWM_BAR_JUSTIFY_CENTER (1)
#define SWM_BAR_JUSTIFY_RIGHT (2)
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;
bool urgent_collapse = false;
char *clock_format = NULL;
bool window_class_enabled = false;
} layouts[] = {
/* stack, configure */
{ vertical_stack, vertical_config, 0, plain_stacker },
- { horizontal_stack, horizontal_config, 0, plain_stacker },
+// { horizontal_stack, horizontal_config, 0, plain_stacker },
{ max_stack, NULL,
SWM_L_MAPONFOCUS | SWM_L_FOCUSPREV, plain_stacker },
{ NULL, NULL, 0, NULL },
/* position of max_stack mode in the layouts array, index into layouts! */
#define SWM_V_STACK (0)
#define SWM_H_STACK (1)
-#define SWM_MAX_STACK (2)
+#define SWM_MAX_STACK (1)
#define SWM_H_SLICE (32)
#define SWM_V_SLICE (32)
_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,
{"_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},
char *get_stack_mode_name(uint8_t);
#endif
int32_t get_swm_ws(xcb_window_t);
+bool get_urgent(struct ws_win *);
char *get_win_name(xcb_window_t);
uint8_t get_win_state(xcb_window_t);
void get_wm_protocols(struct ws_win *);
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);
free(title);
}
+bool
+get_urgent(struct ws_win *win)
+{
+ xcb_icccm_wm_hints_t hints;
+ xcb_get_property_cookie_t c;
+ bool urgent = false;
+
+ if (win) {
+ c = xcb_icccm_get_wm_hints(conn, win->id);
+ if (xcb_icccm_get_wm_hints_reply(conn, c, &hints, NULL))
+ urgent = xcb_icccm_wm_hints_get_urgency(&hints);
+ }
+
+ return urgent;
+}
+
void
bar_urgent(char *s, size_t sz)
{
int i, j, num_screens;
bool urgent[SWM_WS_MAX];
char b[8];
- xcb_get_property_cookie_t c;
- xcb_icccm_wm_hints_t hints;
for (i = 0; i < workspace_limit; i++)
urgent[i] = false;
num_screens = get_screen_count();
for (i = 0; i < num_screens; i++)
for (j = 0; j < workspace_limit; j++)
- TAILQ_FOREACH(win, &screens[i].ws[j].winlist, entry) {
- c = xcb_icccm_get_wm_hints(conn, win->id);
- if (xcb_icccm_get_wm_hints_reply(conn, c,
- &hints, NULL) == 0)
- continue;
- if (hints.flags & XCB_ICCCM_WM_HINT_X_URGENCY)
- urgent[j] = true;
- }
+ TAILQ_FOREACH(win, &screens[i].ws[j].winlist, entry)
+ urgent[j] = get_urgent(win);
for (i = 0; i < workspace_limit; i++) {
if (urgent[i]) {
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)
{
&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);
}
struct workspace *ws = NULL;
union arg a;
int i;
- xcb_icccm_wm_hints_t hints;
if (!(r && r->ws))
goto out;
winfocus = TAILQ_FIRST(wl);
if (winfocus == cur_focus)
- winfocus = cur_focus->ws->focus_prev;
+ return;
break;
case SWM_ARG_ID_FOCUSURGENT:
/* Search forward for the next urgent window. */
head = TAILQ_FIRST(&r->s->ws[(ws->idx + i) %
workspace_limit].winlist);
- while (head != NULL &&
- (head = TAILQ_NEXT(head, entry)) != NULL) {
+ while (head) {
if (head == cur_focus) {
- winfocus = cur_focus;
- break;
- }
- if (xcb_icccm_get_wm_hints_reply(conn,
- xcb_icccm_get_wm_hints(conn, head->id),
- &hints, NULL) != 0 &&
- xcb_icccm_wm_hints_get_urgency(&hints)) {
+ if (i > 0) {
+ winfocus = cur_focus;
+ break;
+ }
+ } else if (get_urgent(head)) {
winfocus = head;
break;
}
+
+ head = TAILQ_NEXT(head, entry);
}
- if (winfocus != NULL)
+ if (winfocus)
break;
}
/* Switch ws if new focus is on a different ws. */
- if (winfocus != NULL && winfocus->ws != ws) {
+ if (winfocus && winfocus->ws != ws) {
a.id = winfocus->ws->idx;
switchws(r, &a);
}
win_g.y += last_h + 2 * border_width + tile_gap;
if (disable_border && !(bar_enabled && ws->bar_enabled) &&
- winno == 1){
+ winno == 1) {
bordered = false;
win_g.w += 2 * border_width;
win_g.h += 2 * border_width;
if (X(w) != gg.x || Y(w) != gg.y || WIDTH(w) != gg.w ||
HEIGHT(w) != gg.h) {
w->g = gg;
- if (bar_enabled && ws->bar_enabled){
- w->bordered = true;
- } else {
+
+ if (disable_border && !(bar_enabled && ws->bar_enabled)) {
w->bordered = false;
WIDTH(w) += 2 * border_width;
HEIGHT(w) += 2 * border_width;
+ } else {
+ w->bordered = true;
}
update_window(w);
{
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);
}
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,
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,
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++) {
{ "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 },
{ "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 },
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),