diff options
Diffstat (limited to 'compton.c')
-rw-r--r-- | compton.c | 84 |
1 files changed, 74 insertions, 10 deletions
@@ -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 |