Bug fix #99: Rewrite focus detection logic

- Rewrite focus detection logic. Remove w->focused_real and use
  ps->active_win to identify focused window uniformly. Use a more
  expensive way to filter FocusIn/Out events to improve reliability.
  Only limited tests are done, and bugs are likely to be introduced.
  (#99)

- Known issue: Under fvwm, compton sometimes does not consistently
  report the window input gets sent to. But there's something wrong in
  that case: XGetInputFocus() shows the root window is focused but
  another window is receiving input.
This commit is contained in:
Richard Grenville
2013-09-18 21:50:57 +08:00
parent a6b76e954f
commit 4bd3db2bc7
5 changed files with 107 additions and 103 deletions

View File

@@ -954,8 +954,6 @@ typedef struct _win {
bool focused;
/// Override value of window focus state. Set by D-Bus method calls.
switch_t focused_force;
/// Whether the window is actually focused.
bool focused_real;
// Blacklist related members
/// Name of the window.
@@ -1695,6 +1693,14 @@ find_toplevel(session_t *ps, Window id) {
return NULL;
}
/**
* Check if a window is really focused.
*/
static inline bool
win_is_focused_real(session_t *ps, const win *w) {
return IsViewable == w->a.map_state && ps->active_win == w;
}
/**
* Find out the currently focused window.
*
@@ -1702,19 +1708,15 @@ find_toplevel(session_t *ps, Window id) {
*/
static inline win *
find_focused(session_t *ps) {
if (!ps->o.track_focus)
return NULL;
for (win *w = ps->list; w; w = w->next) {
if (w->focused_real && !w->destroyed)
return w;
}
if (!ps->o.track_focus) return NULL;
if (ps->active_win && win_is_focused_real(ps, ps->active_win))
return ps->active_win;
return NULL;
}
/**
* Copies a region
* Copies a region.
*/
static inline XserverRegion
copy_region(const session_t *ps, XserverRegion oldregion) {