diff --git a/debian/changelog b/debian/changelog index 3b3bf7e..8f01a32 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,11 @@ +steamos-compositor (1.29) brewmaster; urgency=medium + + * Tweaking focus and display logic in steamcompmgr to avoid event storms on newer + X servers. It looks like Damage semantics changed on Xserver 1.16 and we were + getting unexpected events after XDamageSubtract(). + + -- Pierre-Loup A. Griffais Fri, 03 Jul 2015 19:36:36 -0700 + steamos-compositor (1.28) brewmaster; urgency=medium * Add set_hd_mode.sh helper script, run at start of session; helps get out diff --git a/src/steamcompmgr.c b/src/steamcompmgr.c index 7990055..3009fb0 100644 --- a/src/steamcompmgr.c +++ b/src/steamcompmgr.c @@ -164,6 +164,10 @@ Bool hideCursorForScale; Bool hideCursorForMovement; unsigned int lastCursorMovedTime; +Bool focusDirty = False; + +unsigned long damageSequence = 0; + #define CURSOR_HIDE_TIME 3000 Bool gotXError = False; @@ -1181,12 +1185,13 @@ determine_and_apply_focus (Display *dpy) setup_pointer_barriers(dpy); - if (gameFocused || !gamesRunningCount) + if (gameFocused || !gamesRunningCount && list[0].id != focus->id) { XRaiseWindow(dpy, focus->id); - XSetInputFocus(dpy, focus->id, RevertToNone, CurrentTime); } - + + XSetInputFocus(dpy, focus->id, RevertToNone, CurrentTime); + if (!focus->nudged) { XMoveWindow(dpy, focus->id, 1, 1); @@ -1338,7 +1343,7 @@ map_win (Display *dpy, Window id, unsigned long sequence) w->validContents = False; - determine_and_apply_focus(dpy); + focusDirty = True; } static void @@ -1372,7 +1377,7 @@ unmap_win (Display *dpy, Window id, Bool fade) return; w->a.map_state = IsUnmapped; - determine_and_apply_focus(dpy); + focusDirty = True; finish_unmap_win (dpy, w); } @@ -1443,7 +1448,7 @@ add_win (Display *dpy, Window id, Window prev, unsigned long sequence) if (new->a.map_state == IsViewable) map_win (dpy, id, sequence); - determine_and_apply_focus (dpy); + focusDirty = True; } static void @@ -1473,9 +1478,9 @@ restack_win (Display *dpy, win *w, Window new_above) } w->next = *prev; *prev = w; + + focusDirty = True; } - - determine_and_apply_focus(dpy); } static void @@ -1510,7 +1515,7 @@ configure_win (Display *dpy, XConfigureEvent *ce) w->a.override_redirect = ce->override_redirect; restack_win (dpy, w, ce->above); - determine_and_apply_focus (dpy); + focusDirty = True; } static void @@ -1561,7 +1566,7 @@ destroy_win (Display *dpy, Window id, Bool gone, Bool fade) currentOverlayWindow = None; if (currentNotificationWindow == id && gone) currentNotificationWindow = None; - determine_and_apply_focus(dpy); + focusDirty = True; finish_destroy_win (dpy, id, gone); } @@ -1583,14 +1588,14 @@ damage_win (Display *dpy, XDamageNotifyEvent *de) // First damage event we get, compute focus; we only want to focus damaged // windows to have meaningful frames. if (w->gameID && w->damage_sequence == 0) - determine_and_apply_focus(dpy); + focusDirty = True; - w->damage_sequence = de->serial; + w->damage_sequence = damageSequence++; // If we just passed the focused window, we might be eliglible to take over if (focus && focus != w && w->gameID && w->damage_sequence > focus->damage_sequence) - determine_and_apply_focus(dpy); + focusDirty = True; w->damaged = 1; @@ -1981,6 +1986,8 @@ main (int argc, char **argv) for (;;) { + focusDirty = False; + do { XNextEvent (dpy, &ev); if ((ev.type & 0x7f) != KeymapNotify) @@ -2040,7 +2047,7 @@ main (int argc, char **argv) if (w) { get_size_hints(dpy, w); - determine_and_apply_focus(dpy); + focusDirty = True; } } } @@ -2085,7 +2092,7 @@ main (int argc, char **argv) if (w) { w->isSteam = get_prop(dpy, w->id, steamAtom, 0); - determine_and_apply_focus(dpy); + focusDirty = True; } } if (ev.xproperty.atom == gameAtom) @@ -2094,7 +2101,7 @@ main (int argc, char **argv) if (w) { w->gameID = get_prop(dpy, w->id, gameAtom, 0); - determine_and_apply_focus(dpy); + focusDirty = True; } } if (ev.xproperty.atom == overlayAtom) @@ -2103,7 +2110,7 @@ main (int argc, char **argv) if (w) { w->isOverlay = get_prop(dpy, w->id, overlayAtom, 0); - determine_and_apply_focus(dpy); + focusDirty = True; // Overlay windows need a RGBA pixmap, so destroy the old one there // It'll be reallocated as RGBA in ensure_win_resources() @@ -2119,14 +2126,14 @@ main (int argc, char **argv) if (w) { get_size_hints(dpy, w); - determine_and_apply_focus(dpy); + focusDirty = True; } } if (ev.xproperty.atom == gamesRunningAtom) { gamesRunningCount = get_prop(dpy, root, gamesRunningAtom, 0); - determine_and_apply_focus(dpy); + focusDirty = True; } if (ev.xproperty.atom == screenScaleAtom) { @@ -2137,7 +2144,7 @@ main (int argc, char **argv) if (w = find_win(dpy, currentFocusWindow)) w->damaged = 1; - determine_and_apply_focus(dpy); + focusDirty = True; } break; case ClientMessage: @@ -2149,7 +2156,7 @@ main (int argc, char **argv) { w->isFullscreen = ev.xclient.data.l[0]; - determine_and_apply_focus(dpy); + focusDirty = True; } } break; @@ -2208,6 +2215,9 @@ main (int argc, char **argv) break; } } while (QLength (dpy)); + + if (focusDirty == True) + determine_and_apply_focus(dpy); if (doRender) {