From a6296dda20192a9e77cd8d1a70c57ae19efa4125 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20L=C3=BCbking?= Date: Fri, 24 Aug 2012 23:03:58 +0200 Subject: [PATCH] delay unsynced window ready_for_painting state by at max 50ms (and thus trigger a full repaint with the state change) BUG: 295254 REVIEW: 106173 FIXED-IN: 4.9.1 --- client.cpp | 2 ++ composite.cpp | 10 ++++++++++ effects.cpp | 22 ++++++++++++++++------ effects.h | 1 + toplevel.cpp | 8 +++++++- toplevel.h | 4 +++- unmanaged.h | 1 + 7 files changed, 40 insertions(+), 8 deletions(-) diff --git a/client.cpp b/client.cpp index 09b0328587..48e797d303 100644 --- a/client.cpp +++ b/client.cpp @@ -2201,6 +2201,8 @@ void Client::getSyncCounter() void Client::sendSyncRequest() { #ifdef HAVE_XSYNC + delete m_readyForPaintingTimer; + m_readyForPaintingTimer = 0; if (syncRequest.counter == None || syncRequest.isPending) return; // do NOT, NEVER send a sync request when there's one on the stack. the clients will just stop respoding. FOREVER! ... diff --git a/composite.cpp b/composite.cpp index 12bb75a8df..ddca3d339f 100644 --- a/composite.cpp +++ b/composite.cpp @@ -737,12 +737,22 @@ void Client::damageNotifyEvent(XDamageNotifyEvent* e) setReadyForPainting(); } #else + if (!ready_for_painting) { setReadyForPainting(); + } #endif Toplevel::damageNotifyEvent(e); } +void Unmanaged::damageNotifyEvent(XDamageNotifyEvent* e) +{ + if (!ready_for_painting) { // avoid "setReadyForPainting()" function calling overhead + setReadyForPainting(); + } + Toplevel::damageNotifyEvent(e); +} + void Toplevel::addDamage(const QRect& r) { addDamage(r.x(), r.y(), r.width(), r.height()); diff --git a/effects.cpp b/effects.cpp index f3fd7e5118..608ddd6778 100644 --- a/effects.cpp +++ b/effects.cpp @@ -407,12 +407,6 @@ void EffectsHandlerImpl::slotClientAdded(Client *c) 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 *t) { Q_ASSERT(dynamic_cast(t)); @@ -422,6 +416,22 @@ void EffectsHandlerImpl::slotClientShown(KWin::Toplevel *t) emit windowAdded(c->effectWindow()); } +void EffectsHandlerImpl::slotUnmanagedAdded(Unmanaged *u) +{ + if (u->readyForPainting()) + slotUnmanagedShown(u); + else + connect(u, SIGNAL(windowShown(KWin::Toplevel*)), SLOT(slotUnmanagedShown(KWin::Toplevel*))); +} + +void EffectsHandlerImpl::slotUnmanagedShown(KWin::Toplevel *t) +{ + Q_ASSERT(dynamic_cast(t)); + Unmanaged *u = static_cast(t); + setupUnmanagedConnections(u); + emit windowAdded(u->effectWindow()); +} + void EffectsHandlerImpl::slotDeletedRemoved(KWin::Deleted *d) { emit windowDeleted(d->effectWindow()); diff --git a/effects.h b/effects.h index 014c4cf497..33a0d5bc57 100644 --- a/effects.h +++ b/effects.h @@ -187,6 +187,7 @@ protected Q_SLOTS: void slotClientAdded(KWin::Client *c); void slotClientShown(KWin::Toplevel*); void slotUnmanagedAdded(KWin::Unmanaged *u); + void slotUnmanagedShown(KWin::Toplevel*); void slotWindowClosed(KWin::Toplevel *c); void slotClientActivated(KWin::Client *c); void slotDeletedRemoved(KWin::Deleted *d); diff --git a/toplevel.cpp b/toplevel.cpp index 94178130e3..0bb1caca60 100644 --- a/toplevel.cpp +++ b/toplevel.cpp @@ -33,7 +33,7 @@ namespace KWin Toplevel::Toplevel(Workspace* ws) : vis(NULL) , info(NULL) - , ready_for_painting(true) + , ready_for_painting(false) , client(None) , frame(None) , wspace(ws) @@ -45,6 +45,10 @@ Toplevel::Toplevel(Workspace* ws) , unredirect(false) , unredirectSuspend(false) { + m_readyForPaintingTimer = new QTimer(this); + m_readyForPaintingTimer->setSingleShot(true); + connect(m_readyForPaintingTimer, SIGNAL(timeout()), SLOT(setReadyForPainting())); + m_readyForPaintingTimer->start(50); } Toplevel::~Toplevel() @@ -334,6 +338,8 @@ void Toplevel::setOpacity(double new_opacity) void Toplevel::setReadyForPainting() { if (!ready_for_painting) { + delete m_readyForPaintingTimer; + m_readyForPaintingTimer = 0; ready_for_painting = true; if (compositing()) { addRepaintFull(); diff --git a/toplevel.h b/toplevel.h index aba932141c..19f5dccfb3 100644 --- a/toplevel.h +++ b/toplevel.h @@ -313,7 +313,6 @@ protected: void addDamageFull(); void getWmClientLeader(); void getWmClientMachine(); - void setReadyForPainting(); /** * This function fetches the opaque region from this Toplevel. @@ -334,8 +333,11 @@ protected: int bit_depth; NETWinInfo2* info; bool ready_for_painting; + QTimer *m_readyForPaintingTimer; QRegion repaints_region; // updating, repaint just requires repaint of that area QRegion layer_repaints_region; +protected slots: + void setReadyForPainting(); private: static QByteArray staticWindowRole(WId); static QByteArray staticSessionId(WId); diff --git a/unmanaged.h b/unmanaged.h index b11d62b84c..f5684b5331 100644 --- a/unmanaged.h +++ b/unmanaged.h @@ -47,6 +47,7 @@ public: return UnmanagedLayer; } protected: + virtual void damageNotifyEvent(XDamageNotifyEvent* e); virtual void debug(QDebug& stream) const; virtual bool shouldUnredirect() const; private: