summaryrefslogtreecommitdiffstats
path: root/compton.c
diff options
context:
space:
mode:
Diffstat (limited to 'compton.c')
-rw-r--r--compton.c84
1 files changed, 74 insertions, 10 deletions
diff --git a/compton.c b/compton.c
index c1016769f..a90538110 100644
--- a/compton.c
+++ b/compton.c
@@ -2705,6 +2705,76 @@ wid_get_prop_window(session_t *ps, Window wid, Atom aprop) {
}
/**
+ * Update focused state of a window.
+ */
+static void
+win_update_focused(session_t *ps, win *w) {
+ bool focused_old = w->focused;
+
+ w->focused = w->focused_real;
+
+ // Use wintype_focus, and treat WM windows and override-redirected
+ // windows specially
+ if (ps->o.wintype_focus[w->window_type]
+ || (ps->o.mark_wmwin_focused && w->wmwin)
+ || (ps->o.mark_ovredir_focused
+ && w->id == w->client_win && !w->wmwin)
+ || win_match(w, ps->o.focus_blacklist, &w->cache_fcblst))
+ w->focused = true;
+
+ // If window grouping detection is enabled, mark the window active if
+ // its group is
+ if (ps->o.track_leader && ps->active_leader
+ && win_get_leader(ps, w) == ps->active_leader) {
+ w->focused = true;
+ }
+
+ if (w->focused != focused_old)
+ w->flags |= WFLAG_OPCT_CHANGE;
+}
+
+/**
+ * Set real focused state of a window.
+ */
+static void
+win_set_focused(session_t *ps, win *w, bool focused) {
+ // Unmapped windows will have their focused state reset on map
+ if (IsUnmapped == w->a.map_state)
+ return;
+
+ if (w->focused_real != focused) {
+ w->focused_real = focused;
+
+ // If window grouping detection is enabled
+ if (ps->o.track_leader) {
+ Window leader = win_get_leader(ps, w);
+
+ // If the window gets focused, replace the old active_leader
+ if (w->focused_real && leader != ps->active_leader) {
+ Window active_leader_old = ps->active_leader;
+
+ ps->active_leader = leader;
+
+ group_update_focused(ps, active_leader_old);
+ group_update_focused(ps, leader);
+ }
+ // If the group get unfocused, remove it from active_leader
+ else if (!w->focused_real && leader && leader == ps->active_leader
+ && !group_is_focused(ps, leader)) {
+ ps->active_leader = None;
+ group_update_focused(ps, leader);
+ }
+
+ // The window itself must be updated anyway
+ win_update_focused(ps, w);
+ }
+ // Otherwise, only update the window itself
+ else {
+ win_update_focused(ps, w);
+ }
+ }
+}
+/**
* Update leader of a window.
*/
static void
@@ -2719,6 +2789,10 @@ win_update_leader(session_t *ps, win *w) {
leader = wid_get_prop_window(ps, w->client_win, ps->atom_client_leader);
win_set_leader(ps, w, leader);
+
+#ifdef DEBUG_LEADER
+ printf_dbgf("(%#010lx): client %#010lx, leader %#010lx, cache %#010lx\n", w->id, w->client_win, w->leader, win_get_leader(ps, w));
+#endif
}
/**
@@ -2753,16 +2827,6 @@ win_set_leader(session_t *ps, win *w, Window nleader) {
}
/**
- * Get the leader of a window.
- *
- * This function updates w->cache_leader if necessary.
- */
-static Window
-win_get_leader(session_t *ps, win *w) {
- return win_get_leader_raw(ps, w, 0);
-}
-
-/**
* Internal function of win_get_leader().
*/
static Window