Skip to content

Commit

Permalink
c2: add new predefined target wm_state to match against `_NET_WM_ST…
Browse files Browse the repository at this point in the history
…ATE` in string

New predefined target `wm_state` for rule-based matching. Matches
against the cached `_NET_WM_STATE` property of a window in string
representation.

NOTE: `wm_state = 'fullscreen'` is not neccessarily identical to
`fullscreen`, and `wm_state = 'focused'` is not identical to `focused`.
  • Loading branch information
tryone144 committed Nov 29, 2020
1 parent 9125693 commit dac6785
Show file tree
Hide file tree
Showing 6 changed files with 34 additions and 5 deletions.
5 changes: 4 additions & 1 deletion man/picom.1.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,7 @@ With greater-than/less-than operators it looks like:

'NEGATION' (optional) is one or more exclamation marks;

'TARGET' is either a predefined target name, or the name of a window property to match. Supported predefined targets are `id`, `x`, `y`, `x2` (`x` + `widthb`), `y2` (like `x2`), `width`, `height`, `widthb` (`width` + 2 * `border_width`), `heightb` (like `widthb`), `border_width`, `fullscreen`, `override_redirect`, `argb` (whether the window has an ARGB visual), `focused`, `wmwin` (whether the window looks like a WM window, i.e. has no child window with `WM_STATE` and is not override-redirected), `bounding_shaped`, `rounded_corners` (requires *--detect-rounded-corners*), `client` (ID of client window), `window_type` (window type in string), `leader` (ID of window leader), `name`, `class_g` (= `WM_CLASS[1]`), `class_i` (= `WM_CLASS[0]`), and `role`.
'TARGET' is either a predefined target name, or the name of a window property to match. Supported predefined targets are `id`, `x`, `y`, `x2` (`x` + `widthb`), `y2` (like `x2`), `width`, `height`, `widthb` (`width` + 2 * `border_width`), `heightb` (like `widthb`), `border_width`, `fullscreen`, `override_redirect`, `argb` (whether the window has an ARGB visual), `focused`, `wmwin` (whether the window looks like a WM window, i.e. has no child window with `WM_STATE` and is not override-redirected), `bounding_shaped`, `rounded_corners` (requires *--detect-rounded-corners*), `client` (ID of client window), `window_type` (window type in string), `leader` (ID of window leader), `name`, `class_g` (= `WM_CLASS[1]`), `class_i` (= `WM_CLASS[0]`), `role`, and `wm_state` (window manager state hint in string).

'CLIENT/FRAME' is a single `@` if the window attribute should be be looked up on client window, nothing if on frame window;

Expand Down Expand Up @@ -307,6 +307,9 @@ Examples:
# If the window is a menu
window_type *= "menu"
_NET_WM_WINDOW_TYPE@:a *= "MENU"
# If the window is marked hidden
wm_state *= "hidden"
_NET_WM_STATE@:a *= "HIDDEN"
# If the window name contains "Firefox", ignore case
name *?= "Firefox"
_NET_WM_NAME@:s *?= "Firefox"
Expand Down
17 changes: 15 additions & 2 deletions src/c2.c
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ struct _c2_l {
C2_L_PCLASSG,
C2_L_PCLASSI,
C2_L_PROLE,
C2_L_PWMSTATE,
} predef;
enum c2_l_type {
C2_L_TUNDEFINED,
Expand Down Expand Up @@ -210,6 +211,7 @@ static const c2_predef_t C2_PREDEFS[] = {
[C2_L_PCLASSG] = {"class_g", C2_L_TSTRING, 0},
[C2_L_PCLASSI] = {"class_i", C2_L_TSTRING, 0},
[C2_L_PROLE] = {"role", C2_L_TSTRING, 0},
[C2_L_PWMSTATE] = {"wm_state", C2_L_TSTRING, 0},
};

/**
Expand Down Expand Up @@ -1395,10 +1397,21 @@ static inline void c2_match_once_leaf(session_t *ps, const struct managed_win *w
case C2_L_PCLASSG: tgt = w->class_general; break;
case C2_L_PCLASSI: tgt = w->class_instance; break;
case C2_L_PROLE: tgt = w->role; break;
case C2_L_PWMSTATE: {
ntargets = 0;
for (enum wm_state i = 1; i < NUM_WMSTATES; ++i) {
if (win_check_wm_state(w, i)) {
targets[ntargets++] = WMSTATES[i];
}
}
break;
}
default: assert(0); break;
}
ntargets = 1;
targets[0] = tgt;
if (tgt) {
ntargets = 1;
targets[0] = tgt;
}
}
// An atom type property, convert it to string
else if (pleaf->type == C2_L_TATOM) {
Expand Down
1 change: 1 addition & 0 deletions src/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,7 @@ typedef struct session {
typedef enum { WIN_EVMODE_UNKNOWN, WIN_EVMODE_FRAME, WIN_EVMODE_CLIENT } win_evmode_t;

extern const char *const WINTYPES[NUM_WINTYPES];
extern const char *const WMSTATES[NUM_WMSTATES];
extern session_t *ps_g;

void ev_xcb_error(session_t *ps, xcb_generic_error_t *err);
Expand Down
9 changes: 9 additions & 0 deletions src/picom.c
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,15 @@ const char *const WINTYPES[NUM_WINTYPES] = {
"popup_menu", "tooltip", "notification", "combo", "dnd",
};

/// Name string for window wm_states.
const char *const WMSTATES[NUM_WMSTATES] = {
"unknown", "modal", "sticky",
"maximized_vert", "maximized_horz", "shaded",
"skip_taskbar", "skip_pager", "hidden",
"fullscreen", "above", "below",
"demands_attention", "focused",
};

// clang-format off
/// Names of backends.
const char *const BACKEND_STRS[] = {[BKEND_XRENDER] = "xrender",
Expand Down
4 changes: 2 additions & 2 deletions src/win.c
Original file line number Diff line number Diff line change
Expand Up @@ -656,7 +656,7 @@ static win_wmstate_t wid_get_prop_wm_state(session_t *ps, xcb_window_t wid) {
for (unsigned i = 0; i < prop.nitems; ++i) {
for (enum wm_state j = 1; j < NUM_WMSTATES; ++j) {
if (ps->atoms_wmstates[j] == (xcb_atom_t)prop.p32[i]) {
wm_state |= (1 << (j - 1));
wm_state |= (win_wmstate_t)(1 << (j - 1));
}
}
}
Expand Down Expand Up @@ -1157,7 +1157,7 @@ bool win_check_wm_state(const struct managed_win *w, enum wm_state state) {
if (state == WMSTATE_UNKNOWN) {
return false;
}
return (w->wm_state & (1 << (state - 1))) != 0;
return (w->wm_state & (win_wmstate_t)(1 << (state - 1))) != 0;
}

/**
Expand Down
3 changes: 3 additions & 0 deletions src/win.h
Original file line number Diff line number Diff line change
Expand Up @@ -410,6 +410,9 @@ bool attr_pure win_is_fullscreen(const session_t *ps, const struct managed_win *
*/
bool attr_pure win_is_focused_raw(const session_t *ps, const struct managed_win *w);

/// check if window has specific wm_state.
bool attr_pure win_check_wm_state(const struct managed_win *w, enum wm_state state);

/// check if window has ARGB visual
bool attr_pure win_has_alpha(const struct managed_win *w);

Expand Down

0 comments on commit dac6785

Please sign in to comment.