From aace60be5934e772cf50f0aec711bcdfe8249673 Mon Sep 17 00:00:00 2001 From: Richard Grenville Date: Sun, 10 Mar 2013 18:45:54 +0800 Subject: [PATCH] Improvement: ARGB window matching & Enable track_focus with D-Bus - Add predefined matching target "argb" to match ARGB windows. - Make it possible to enable focus tracking on-the-fly with D-Bus method. --- dbus-examples/cdbus-driver.sh | 3 +++ man/compton.1.asciidoc | 2 +- src/c2.c | 1 + src/c2.h | 2 ++ src/common.h | 3 +++ src/compton.c | 28 ++++++++++++++++++++++++++-- src/dbus.c | 12 ++++++++++++ 7 files changed, 48 insertions(+), 3 deletions(-) diff --git a/dbus-examples/cdbus-driver.sh b/dbus-examples/cdbus-driver.sh index bd01b3f..b91242b 100755 --- a/dbus-examples/cdbus-driver.sh +++ b/dbus-examples/cdbus-driver.sh @@ -25,6 +25,9 @@ type_enum='uint16' # List all window ID compton manages (except destroyed ones) dbus-send --print-reply --dest="$service" "$object" "${interface}.list_win" +# Ensure we are tracking focus +dbus-send --print-reply --dest="$service" "$object" "${interface}.opts_set" string:track_focus boolean:true + # Get window ID of currently focused window focused=$(dbus-send --print-reply --dest="$service" "$object" "${interface}.find_win" string:focused | $SED -n 's/^[[:space:]]*'${type_win}'[[:space:]]*\([[:digit:]]*\).*/\1/p') diff --git a/man/compton.1.asciidoc b/man/compton.1.asciidoc index 9d4ac42..97a27de 100644 --- a/man/compton.1.asciidoc +++ b/man/compton.1.asciidoc @@ -197,7 +197,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`, `override_redirect`, `focused`, `wmwin`, `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`, `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), `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`. 'CLIENT/FRAME' is a single `@` if the window attribute should be be looked up on client window, nothing if on frame window; diff --git a/src/c2.c b/src/c2.c index 5bbb4e3..4e2b0df 100644 --- a/src/c2.c +++ b/src/c2.c @@ -1042,6 +1042,7 @@ c2_match_once_leaf(session_t *ps, win *w, const c2_l_t *pleaf, switch (pleaf->predef) { case C2_L_PID: tgt = wid; break; case C2_L_POVREDIR: tgt = w->a.override_redirect; break; + case C2_L_PARGB: tgt = (WMODE_ARGB == w->mode); break; case C2_L_PFOCUSED: tgt = w->focused_real; break; case C2_L_PWMWIN: tgt = w->wmwin; break; case C2_L_PCLIENT: tgt = w->client_win; break; diff --git a/src/c2.h b/src/c2.h index 000c684..c794da1 100644 --- a/src/c2.h +++ b/src/c2.h @@ -100,6 +100,7 @@ struct _c2_l { C2_L_PUNDEFINED, C2_L_PID, C2_L_POVREDIR, + C2_L_PARGB, C2_L_PFOCUSED, C2_L_PWMWIN, C2_L_PCLIENT, @@ -175,6 +176,7 @@ typedef struct { const static c2_predef_t C2_PREDEFS[] = { [C2_L_PID ] = { "id" , C2_L_TCARDINAL , 0 }, [C2_L_POVREDIR ] = { "override_redirect" , C2_L_TCARDINAL , 0 }, + [C2_L_PARGB ] = { "argb" , C2_L_TCARDINAL , 0 }, [C2_L_PFOCUSED ] = { "focused" , C2_L_TCARDINAL , 0 }, [C2_L_PWMWIN ] = { "wmwin" , C2_L_TCARDINAL , 0 }, [C2_L_PCLIENT ] = { "client" , C2_L_TWINDOW , 0 }, diff --git a/src/common.h b/src/common.h index 0d4f5a5..96ca602 100644 --- a/src/common.h +++ b/src/common.h @@ -1491,6 +1491,9 @@ win_set_focused_force(session_t *ps, win *w, switch_t val); void win_set_invert_color_force(session_t *ps, win *w, switch_t val); + +void +opts_init_track_focus(session_t *ps); //!@} #endif diff --git a/src/compton.c b/src/compton.c index ff1dd49..8bd8533 100644 --- a/src/compton.c +++ b/src/compton.c @@ -1822,6 +1822,9 @@ map_win(session_t *ps, Window id) { // Make sure the XSelectInput() requests are sent XSync(ps->dpy, False); + // Update window mode here to do matching of ARGB + win_determine_mode(ps, w); + // Detect client window here instead of in add_win() as the client // window should have been prepared at this point if (!w->client_win) { @@ -1982,8 +1985,6 @@ win_determine_mode(session_t *ps, win *w) { winmode_t mode = WMODE_SOLID; XRenderPictFormat *format; - /* if trans prop == -1 fall back on previous tests */ - if (w->a.class == InputOnly) { format = 0; } else { @@ -3247,6 +3248,29 @@ win_set_invert_color_force(session_t *ps, win *w, switch_t val) { win_determine_invert_color(ps, w); } } + +/** + * Enable focus tracking. + */ +void +opts_init_track_focus(session_t *ps) { + // Already tracking focus + if (ps->o.track_focus) + return; + + ps->o.track_focus = true; + + if (!ps->o.use_ewmh_active_win) { + // Start listening to FocusChange events + for (win *w = ps->list; w; w = w->next) + if (IsViewable == w->a.map_state) + XSelectInput(ps->dpy, w->id, + determine_evmask(ps, w->id, WIN_EVMODE_FRAME)); + } + + // Recheck focus + recheck_focus(ps); +} //!@} #endif diff --git a/src/dbus.c b/src/dbus.c index 39e4cf3..4dd6143 100644 --- a/src/dbus.c +++ b/src/dbus.c @@ -953,6 +953,18 @@ cdbus_process_opts_set(session_t *ps, DBusMessage *msg) { goto cdbus_process_opts_set_success; } + // track_focus + if (!strcmp("track_focus", target)) { + dbus_bool_t val = FALSE; + if (!cdbus_msg_get_arg(msg, 1, DBUS_TYPE_BOOLEAN, &val)) + return false; + // You could enable this option, but never turn if off + if (val) { + opts_init_track_focus(ps); + } + goto cdbus_process_opts_set_success; + } + // vsync if (!strcmp("vsync", target)) { const char * val = NULL;