[packages/kde4-kdebase-workspace] - rel 2; fix kwin freezes (kde bug 306260)

arekm arekm at pld-linux.org
Wed Sep 5 21:15:50 CEST 2012


commit 4ecdbf439d0eb27b0e8d1b06576808d51ac2295c
Author: Arkadiusz Miśkiewicz <arekm at maven.pl>
Date:   Wed Sep 5 21:15:47 2012 +0200

    - rel 2; fix kwin freezes (kde bug 306260)

 kde4-kdebase-workspace-bug-306260.patch | 182 ++++++++++++++++++++++++++++++++
 1 file changed, 182 insertions(+)
---
diff --git a/kde4-kdebase-workspace-bug-306260.patch b/kde4-kdebase-workspace-bug-306260.patch
new file mode 100644
index 0000000..8f94490
--- /dev/null
+++ b/kde4-kdebase-workspace-bug-306260.patch
@@ -0,0 +1,182 @@
+commit 8452e6c3f01a65953705087e0d7ada87e2cc6997
+Author: Martin Gräßlin <mgraesslin at kde.org>
+Date:   Wed Sep 5 20:55:07 2012 +0200
+
+    Ensure that the start Client to build up the ClientModel is in the Focus Chain
+    
+    If the start Client is not part of the focus chain the call to
+    nextClientFocusChain() cannot return the Client again. So the loop break
+    condition is never reached and as the focus chain is not empty the call
+    always returns a not null Client which means KWin is caught in an endless
+    loop.
+    
+    This change checks that the starting Client is in the focus chain and if
+    not the first Client of the focus chain is used.
+    
+    BUG: 306260
+    BUG: 306275
+    FIXED-IN: 4.9.2
+
+diff --git a/kwin/tabbox/clientmodel.cpp b/kwin/tabbox/clientmodel.cpp
+index 9591bab..a67d979 100644
+--- a/kwin/tabbox/clientmodel.cpp
++++ b/kwin/tabbox/clientmodel.cpp
+@@ -188,7 +188,7 @@ void ClientModel::createClientList(int desktop, bool partialReset)
+     switch(tabBox->config().clientSwitchingMode()) {
+     case TabBoxConfig::FocusChainSwitching: {
+         TabBoxClient* c = start;
+-        if (!c) {
++        if (!tabBox->isInFocusChain(c)) {
+             QSharedPointer<TabBoxClient> firstClient = tabBox->firstClientFocusChain().toStrongRef();
+             if (firstClient) {
+                 c = firstClient.data();
+diff --git a/kwin/tabbox/tabbox.cpp b/kwin/tabbox/tabbox.cpp
+index d96d0bd..7a08d37 100644
+--- a/kwin/tabbox/tabbox.cpp
++++ b/kwin/tabbox/tabbox.cpp
+@@ -112,6 +112,14 @@ QWeakPointer< TabBoxClient > TabBoxHandlerImpl::firstClientFocusChain() const
+     }
+ }
+ 
++bool TabBoxHandlerImpl::isInFocusChain(TabBoxClient *client) const
++{
++    if (TabBoxClientImpl *c = static_cast<TabBoxClientImpl*>(client)) {
++        return Workspace::self()->globalFocusChain().contains(c->client());
++    }
++    return false;
++}
++
+ int TabBoxHandlerImpl::nextDesktopFocusChain(int desktop) const
+ {
+     return m_tabBox->nextDesktopFocusChain(desktop);
+diff --git a/kwin/tabbox/tabbox.h b/kwin/tabbox/tabbox.h
+index 6652f93..bba0b39 100644
+--- a/kwin/tabbox/tabbox.h
++++ b/kwin/tabbox/tabbox.h
+@@ -52,6 +52,7 @@ public:
+     virtual QString desktopName(int desktop) const;
+     virtual QWeakPointer< TabBoxClient > nextClientFocusChain(TabBoxClient* client) const;
+     virtual QWeakPointer< TabBoxClient > firstClientFocusChain() const;
++    virtual bool isInFocusChain (TabBoxClient* client) const;
+     virtual int nextDesktopFocusChain(int desktop) const;
+     virtual int numberOfDesktops() const;
+     virtual TabBoxClientList stackingOrder() const;
+diff --git a/kwin/tabbox/tabboxhandler.h b/kwin/tabbox/tabboxhandler.h
+index 7abddfc..2af65b2 100644
+--- a/kwin/tabbox/tabboxhandler.h
++++ b/kwin/tabbox/tabboxhandler.h
+@@ -120,6 +120,20 @@ public:
+      **/
+     virtual QWeakPointer<TabBoxClient> firstClientFocusChain() const = 0;
+     /**
++     * Checks whether the given @p client is part of the focus chain at all.
++     * This is useful to figure out whether the currently active Client can be used
++     * as a starting point to construct the recently used list.
++     *
++     * In case the @p client is not in the focus chain it is recommended to use the
++     * Client returned by @link firstClientFocusChain.
++     *
++     * The method accepts a @c null Client and in that case @c false is returned.
++     * @param client The Client to check whether it is in the Focus Chain
++     * @return @c true in case the Client is part of the focus chain, @c false otherwise.
++     * @since 4.9.2
++     **/
++    virtual bool isInFocusChain(TabBoxClient* client) const = 0;
++    /**
+     * @param client The client whose desktop name should be retrieved
+     * @return The desktop name of the given TabBoxClient. If the client is
+     * on all desktops the name of current desktop will be returned.
+diff --git a/kwin/tabbox/tests/mock_tabboxhandler.cpp b/kwin/tabbox/tests/mock_tabboxhandler.cpp
+index c3ad7a9..20fe8e8 100644
+--- a/kwin/tabbox/tests/mock_tabboxhandler.cpp
++++ b/kwin/tabbox/tests/mock_tabboxhandler.cpp
+@@ -72,6 +72,9 @@ QWeakPointer< TabBox::TabBoxClient > MockTabBoxHandler::nextClientFocusChain(Tab
+             }
+         }
+     }
++    if (!m_windows.isEmpty()) {
++        return QWeakPointer< TabBox::TabBoxClient >(m_windows.last());
++    }
+     return QWeakPointer< TabBox::TabBoxClient >();
+ }
+ 
+@@ -83,6 +86,20 @@ QWeakPointer< TabBox::TabBoxClient > MockTabBoxHandler::firstClientFocusChain()
+     return m_windows.first();
+ }
+ 
++bool MockTabBoxHandler::isInFocusChain(TabBox::TabBoxClient *client) const
++{
++    if (!client) {
++        return false;
++    }
++    QList< QSharedPointer< TabBox::TabBoxClient > >::const_iterator it = m_windows.constBegin();
++    for (; it != m_windows.constEnd(); ++it) {
++        if ((*it).data() == client) {
++            return true;
++        }
++    }
++    return false;
++}
++
+ QWeakPointer< TabBox::TabBoxClient > MockTabBoxHandler::createMockWindow(const QString &caption, WId id)
+ {
+     QSharedPointer< TabBox::TabBoxClient > client(new MockTabBoxClient(caption, id));
+diff --git a/kwin/tabbox/tests/mock_tabboxhandler.h b/kwin/tabbox/tests/mock_tabboxhandler.h
+index a223648..5578001 100644
+--- a/kwin/tabbox/tests/mock_tabboxhandler.h
++++ b/kwin/tabbox/tests/mock_tabboxhandler.h
+@@ -60,6 +60,7 @@ public:
+     }
+     virtual QWeakPointer< TabBox::TabBoxClient > nextClientFocusChain(TabBox::TabBoxClient *client) const;
+     virtual QWeakPointer<TabBox::TabBoxClient> firstClientFocusChain() const;
++    virtual bool isInFocusChain (TabBox::TabBoxClient* client) const;
+     virtual int nextDesktopFocusChain(int desktop) const {
+         Q_UNUSED(desktop)
+         return 1;
+diff --git a/kwin/tabbox/tests/test_tabbox_clientmodel.cpp b/kwin/tabbox/tests/test_tabbox_clientmodel.cpp
+index 79d0253..cee9860 100644
+--- a/kwin/tabbox/tests/test_tabbox_clientmodel.cpp
++++ b/kwin/tabbox/tests/test_tabbox_clientmodel.cpp
+@@ -63,4 +63,24 @@ void TestTabBoxClientModel::testCreateClientListNoActiveClient()
+     QCOMPARE(clientModel->rowCount(), 2);
+ }
+ 
++void TestTabBoxClientModel::testCreateClientListActiveClientNotInFocusChain()
++{
++    MockTabBoxHandler tabboxhandler;
++    tabboxhandler.setConfig(TabBox::TabBoxConfig());
++    TabBox::ClientModel *clientModel = new TabBox::ClientModel(&tabboxhandler);
++    // create two windows, rowCount() should go to two
++    QWeakPointer<TabBox::TabBoxClient> client = tabboxhandler.createMockWindow(QString("test"), 1);
++    client = tabboxhandler.createMockWindow(QString("test2"), 2);
++    clientModel->createClientList();
++    QCOMPARE(clientModel->rowCount(), 2);
++
++    // simulate that the active client is not in the focus chain
++    // for that we use the closeWindow of the MockTabBoxHandler which
++    // removes the Client from the Focus Chain but leaves the active window as it is
++    QSharedPointer<TabBox::TabBoxClient> clientOwner = client.toStrongRef();
++    tabboxhandler.closeWindow(client.data());
++    clientModel->createClientList();
++    QCOMPARE(clientModel->rowCount(), 1);
++}
++
+ QTEST_MAIN(TestTabBoxClientModel)
+diff --git a/kwin/tabbox/tests/test_tabbox_clientmodel.h b/kwin/tabbox/tests/test_tabbox_clientmodel.h
+index 2ec6608..fad7987 100644
+--- a/kwin/tabbox/tests/test_tabbox_clientmodel.h
++++ b/kwin/tabbox/tests/test_tabbox_clientmodel.h
+@@ -40,6 +40,13 @@ private slots:
+      * See BUG: 305449
+      **/
+     void testCreateClientListNoActiveClient();
++    /**
++     * Tests the creation of the Client list for the case that
++     * the active Client is not in the Focus chain.
++     *
++     * See BUG: 306260
++     **/
++    void testCreateClientListActiveClientNotInFocusChain();
+ };
+ 
+ #endif
================================================================

---- gitweb:

http://git.pld-linux.org/gitweb.cgi/packages/kde4-kdebase-workspace.git/commitdiff/4ecdbf439d0eb27b0e8d1b06576808d51ac2295c



More information about the pld-cvs-commit mailing list