From 4d7161dd7513c4798ac69aacbb39de73caf517cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20L=C3=BCbking?= Date: Tue, 24 Jan 2012 17:00:40 +0100 Subject: [PATCH] Delay added signal and other signal bindings for synced windows until the window is actually visually shown Makes animations of showing windows run completely and thus appear smoother REVIEW: 103742 --- client.cpp | 3 +-- composite.cpp | 8 +++++--- effects.cpp | 15 ++++++++++++--- effects.h | 1 + events.cpp | 4 ++-- toplevel.cpp | 11 +++++++++++ toplevel.h | 2 ++ 7 files changed, 34 insertions(+), 10 deletions(-) diff --git a/client.cpp b/client.cpp index fcb1a83ab3..775043aab7 100644 --- a/client.cpp +++ b/client.cpp @@ -2174,8 +2174,7 @@ void Client::sendSyncRequest() void Client::removeSyncSupport() { if (!ready_for_painting) { - ready_for_painting = true; - addRepaintFull(); + setReadyForPainting(); return; } syncRequest.isPending = false; diff --git a/composite.cpp b/composite.cpp index 55a7144007..3f0ef0dbdd 100644 --- a/composite.cpp +++ b/composite.cpp @@ -663,11 +663,13 @@ void Client::damageNotifyEvent(XDamageNotifyEvent* e) #ifdef HAVE_XSYNC if (syncRequest.isPending && isResize()) return; - if (syncRequest.counter == None) // cannot detect complete redraw, consider done now - ready_for_painting = true; + if (!ready_for_painting) { // avoid "setReadyForPainting()" function calling overhead + if (syncRequest.counter == None) // cannot detect complete redraw, consider done now + setReadyForPainting(); #else - ready_for_painting = true; + setReadyForPainting(); #endif + } Toplevel::damageNotifyEvent(e); } diff --git a/effects.cpp b/effects.cpp index b80be3d509..d229f6d502 100644 --- a/effects.cpp +++ b/effects.cpp @@ -373,16 +373,25 @@ void EffectsHandlerImpl::slotOpacityChanged(Toplevel *t, qreal oldOpacity) void EffectsHandlerImpl::slotClientAdded(Client *c) { - setupClientConnections(c); - emit windowAdded(c->effectWindow()); + if (c->readyForPainting()) + slotClientShown(c); + else + connect(c, SIGNAL(windowShown(KWin::Toplevel*)), SLOT(slotClientShown(KWin::Toplevel*))); } void EffectsHandlerImpl::slotUnmanagedAdded(Unmanaged *u) -{ +{ // regardless, unmanaged windows are -yet?- not synced anyway setupUnmanagedConnections(u); emit windowAdded(u->effectWindow()); } +void EffectsHandlerImpl::slotClientShown(KWin::Toplevel *c) +{ + Q_ASSERT(dynamic_cast(c)); + setupClientConnections(static_cast(c)); + emit windowAdded(c->effectWindow()); +} + void EffectsHandlerImpl::slotDeletedRemoved(KWin::Deleted *d) { emit windowDeleted(d->effectWindow()); diff --git a/effects.h b/effects.h index 4d49316856..30be28f354 100644 --- a/effects.h +++ b/effects.h @@ -184,6 +184,7 @@ public Q_SLOTS: protected Q_SLOTS: void slotDesktopChanged(int old); void slotClientAdded(KWin::Client *c); + void slotClientShown(KWin::Toplevel*); void slotUnmanagedAdded(KWin::Unmanaged *u); void slotWindowClosed(KWin::Toplevel *c); void slotClientActivated(KWin::Client *c); diff --git a/events.cpp b/events.cpp index 6a33253717..b631581894 100644 --- a/events.cpp +++ b/events.cpp @@ -1562,7 +1562,7 @@ void Client::keyPressEvent(uint key_code) void Client::syncEvent(XSyncAlarmNotifyEvent* e) { if (e->alarm == syncRequest.alarm && XSyncValueEqual(e->counter_value, syncRequest.value)) { - ready_for_painting = true; + setReadyForPainting(); syncRequest.isPending = false; if (syncRequest.failsafeTimeout) syncRequest.failsafeTimeout->stop(); @@ -1570,7 +1570,7 @@ void Client::syncEvent(XSyncAlarmNotifyEvent* e) if (syncRequest.timeout) syncRequest.timeout->stop(); performMoveResize(); - } else + } else // setReadyForPainting does as well, but there's a small chance for resize syncs after the resize ended addRepaintFull(); } } diff --git a/toplevel.cpp b/toplevel.cpp index ffe7f0c6ca..7cbbd970a6 100644 --- a/toplevel.cpp +++ b/toplevel.cpp @@ -329,6 +329,17 @@ void Toplevel::setOpacity(double new_opacity) } } +void Toplevel::setReadyForPainting() +{ + if (!ready_for_painting) { + ready_for_painting = true; + if (compositing()) { + addRepaintFull(); + emit windowShown(this); + } + } +} + void Toplevel::deleteEffectWindow() { delete effect_window; diff --git a/toplevel.h b/toplevel.h index 58a844ed3c..8e6ea87c9c 100644 --- a/toplevel.h +++ b/toplevel.h @@ -266,6 +266,7 @@ signals: void geometryChanged(); void geometryShapeChanged(KWin::Toplevel* toplevel, const QRect& old); void windowClosed(KWin::Toplevel* toplevel, KWin::Deleted* deleted); + void windowShown(KWin::Toplevel* toplevel); protected: virtual ~Toplevel(); @@ -280,6 +281,7 @@ protected: void addDamageFull(); void getWmClientLeader(); void getWmClientMachine(); + void setReadyForPainting(); /** * This function fetches the opaque region from this Toplevel.