Use the first client as entrance to the focus chain if no active window
The recently used mode of TabBox uses the active window as the entrance into the focus chain. If there is no active window it does not find any Clients. To solve this issue the ClientModel now uses the first entry of the focus chain in case there is no active window. BUG: 305449 FIXED-IN: 4.9.1 REVIEW: 106088
This commit is contained in:
parent
74fe348b96
commit
a4fed7188c
8 changed files with 78 additions and 10 deletions
|
@ -138,7 +138,7 @@ int ClientModel::rowCount(const QModelIndex& parent) const
|
|||
count = qRound(sqrt(float(m_clientList.count())));
|
||||
break;
|
||||
}
|
||||
return qMax(count, 1);
|
||||
return count;
|
||||
}
|
||||
|
||||
QModelIndex ClientModel::parent(const QModelIndex& child) const
|
||||
|
@ -188,6 +188,12 @@ void ClientModel::createClientList(int desktop, bool partialReset)
|
|||
switch(tabBox->config().clientSwitchingMode()) {
|
||||
case TabBoxConfig::FocusChainSwitching: {
|
||||
TabBoxClient* c = tabBox->nextClientFocusChain(start).data();
|
||||
if (!c) {
|
||||
QSharedPointer<TabBoxClient> firstClient = tabBox->firstClientFocusChain().toStrongRef();
|
||||
if (firstClient) {
|
||||
c = firstClient.data();
|
||||
}
|
||||
}
|
||||
TabBoxClient* stop = c;
|
||||
while (c) {
|
||||
QWeakPointer<TabBoxClient> add = tabBox->clientToAddToList(c, desktop);
|
||||
|
|
|
@ -103,6 +103,15 @@ QWeakPointer<TabBoxClient> TabBoxHandlerImpl::nextClientFocusChain(TabBoxClient*
|
|||
return QWeakPointer<TabBoxClient>();
|
||||
}
|
||||
|
||||
QWeakPointer< TabBoxClient > TabBoxHandlerImpl::firstClientFocusChain() const
|
||||
{
|
||||
if (Client *c = m_tabBox->firstClientFocusChain()) {
|
||||
return QWeakPointer<TabBoxClient>(c->tabBoxClient());
|
||||
} else {
|
||||
return QWeakPointer<TabBoxClient>();
|
||||
}
|
||||
}
|
||||
|
||||
int TabBoxHandlerImpl::nextDesktopFocusChain(int desktop) const
|
||||
{
|
||||
return m_tabBox->nextDesktopFocusChain(desktop);
|
||||
|
@ -1519,6 +1528,14 @@ Client* TabBox::previousClientFocusChain(Client* c) const
|
|||
return globalFocusChain[ pos ];
|
||||
}
|
||||
|
||||
Client *TabBox::firstClientFocusChain() const
|
||||
{
|
||||
const ClientList &globalFocusChain = Workspace::self()->globalFocusChain();
|
||||
if (globalFocusChain.isEmpty())
|
||||
return NULL;
|
||||
return globalFocusChain.first();
|
||||
}
|
||||
|
||||
/*!
|
||||
auxiliary functions to travers all clients according to the static
|
||||
order. Useful for the CDE-style Alt-tab feature.
|
||||
|
|
|
@ -51,6 +51,7 @@ public:
|
|||
virtual QString desktopName(TabBoxClient* client) const;
|
||||
virtual QString desktopName(int desktop) const;
|
||||
virtual QWeakPointer< TabBoxClient > nextClientFocusChain(TabBoxClient* client) const;
|
||||
virtual QWeakPointer< TabBoxClient > firstClientFocusChain() const;
|
||||
virtual int nextDesktopFocusChain(int desktop) const;
|
||||
virtual int numberOfDesktops() const;
|
||||
virtual TabBoxClientList stackingOrder() const;
|
||||
|
@ -163,6 +164,7 @@ public:
|
|||
|
||||
Client* nextClientFocusChain(Client*) const;
|
||||
Client* previousClientFocusChain(Client*) const;
|
||||
Client* firstClientFocusChain() const;
|
||||
Client* nextClientStatic(Client*) const;
|
||||
Client* previousClientStatic(Client*) const;
|
||||
int nextDesktopFocusChain(int iDesktop) const;
|
||||
|
|
|
@ -111,6 +111,14 @@ public:
|
|||
* @return The next TabBoxClient in focus chain
|
||||
*/
|
||||
virtual QWeakPointer<TabBoxClient> nextClientFocusChain(TabBoxClient* client) const = 0;
|
||||
/**
|
||||
* This method is used by the ClientModel to find an entrance into the focus chain in case
|
||||
* there is no active Client.
|
||||
*
|
||||
* @return The first Client of the focus chain
|
||||
* @since 4.9.1
|
||||
**/
|
||||
virtual QWeakPointer<TabBoxClient> firstClientFocusChain() const = 0;
|
||||
/**
|
||||
* @param client The client whose desktop name should be retrieved
|
||||
* @return The desktop name of the given TabBoxClient. If the client is
|
||||
|
|
|
@ -39,10 +39,12 @@ void MockTabBoxHandler::grabbedKeyEvent(QKeyEvent *event) const
|
|||
|
||||
QWeakPointer< TabBox::TabBoxClient > MockTabBoxHandler::activeClient() const
|
||||
{
|
||||
if (!m_windows.isEmpty()) {
|
||||
return QWeakPointer< TabBox::TabBoxClient >(m_windows.first());
|
||||
}
|
||||
return QWeakPointer<TabBox::TabBoxClient>();
|
||||
return m_activeClient;
|
||||
}
|
||||
|
||||
void MockTabBoxHandler::setActiveClient(const QWeakPointer< TabBox::TabBoxClient >& client)
|
||||
{
|
||||
m_activeClient = client;
|
||||
}
|
||||
|
||||
QWeakPointer< TabBox::TabBoxClient > MockTabBoxHandler::clientToAddToList(TabBox::TabBoxClient *client, int desktop) const
|
||||
|
@ -59,11 +61,6 @@ QWeakPointer< TabBox::TabBoxClient > MockTabBoxHandler::clientToAddToList(TabBox
|
|||
|
||||
QWeakPointer< TabBox::TabBoxClient > MockTabBoxHandler::nextClientFocusChain(TabBox::TabBoxClient *client) const
|
||||
{
|
||||
if (!client) {
|
||||
if (!m_windows.isEmpty()) {
|
||||
return QWeakPointer< TabBox::TabBoxClient >(m_windows.first());
|
||||
}
|
||||
}
|
||||
QList< QSharedPointer< TabBox::TabBoxClient > >::const_iterator it = m_windows.constBegin();
|
||||
for (; it != m_windows.constEnd(); ++it) {
|
||||
if ((*it).data() == client) {
|
||||
|
@ -78,10 +75,19 @@ QWeakPointer< TabBox::TabBoxClient > MockTabBoxHandler::nextClientFocusChain(Tab
|
|||
return QWeakPointer< TabBox::TabBoxClient >();
|
||||
}
|
||||
|
||||
QWeakPointer< TabBox::TabBoxClient > MockTabBoxHandler::firstClientFocusChain() const
|
||||
{
|
||||
if (m_windows.isEmpty()) {
|
||||
return QWeakPointer<TabBox::TabBoxClient>();
|
||||
}
|
||||
return m_windows.first();
|
||||
}
|
||||
|
||||
QWeakPointer< TabBox::TabBoxClient > MockTabBoxHandler::createMockWindow(const QString &caption, WId id)
|
||||
{
|
||||
QSharedPointer< TabBox::TabBoxClient > client(new MockTabBoxClient(caption, id));
|
||||
m_windows.append(client);
|
||||
m_activeClient = client;
|
||||
return QWeakPointer< TabBox::TabBoxClient >(client);
|
||||
}
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@ public:
|
|||
virtual void activateAndClose() {
|
||||
}
|
||||
virtual QWeakPointer< TabBox::TabBoxClient > activeClient() const;
|
||||
void setActiveClient(const QWeakPointer<TabBox::TabBoxClient> &client);
|
||||
virtual int activeScreen() const {
|
||||
return 0;
|
||||
}
|
||||
|
@ -58,6 +59,7 @@ public:
|
|||
virtual void hideOutline() {
|
||||
}
|
||||
virtual QWeakPointer< TabBox::TabBoxClient > nextClientFocusChain(TabBox::TabBoxClient *client) const;
|
||||
virtual QWeakPointer<TabBox::TabBoxClient> firstClientFocusChain() const;
|
||||
virtual int nextDesktopFocusChain(int desktop) const {
|
||||
Q_UNUSED(desktop)
|
||||
return 1;
|
||||
|
@ -88,6 +90,7 @@ public:
|
|||
void closeWindow(TabBox::TabBoxClient *client);
|
||||
private:
|
||||
QList< QSharedPointer<TabBox::TabBoxClient> > m_windows;
|
||||
QWeakPointer<TabBox::TabBoxClient> m_activeClient;
|
||||
};
|
||||
} // namespace KWin
|
||||
#endif
|
||||
|
|
|
@ -44,4 +44,23 @@ void TestTabBoxClientModel::testLongestCaptionWithNullClient()
|
|||
QCOMPARE(clientModel->longestCaption(), QString());
|
||||
}
|
||||
|
||||
void TestTabBoxClientModel::testCreateClientListNoActiveClient()
|
||||
{
|
||||
MockTabBoxHandler tabboxhandler;
|
||||
tabboxhandler.setConfig(TabBox::TabBoxConfig());
|
||||
TabBox::ClientModel *clientModel = new TabBox::ClientModel(&tabboxhandler);
|
||||
clientModel->createClientList();
|
||||
QCOMPARE(clientModel->rowCount(), 0);
|
||||
// create two windows, rowCount() should go to two
|
||||
QWeakPointer<TabBox::TabBoxClient> client = tabboxhandler.createMockWindow(QString("test"), 1);
|
||||
tabboxhandler.createMockWindow(QString("test2"), 2);
|
||||
clientModel->createClientList();
|
||||
QCOMPARE(clientModel->rowCount(), 2);
|
||||
// let's ensure there is no active client
|
||||
tabboxhandler.setActiveClient(QWeakPointer<TabBox::TabBoxClient>());
|
||||
// now it should still have two members in the list
|
||||
clientModel->createClientList();
|
||||
QCOMPARE(clientModel->rowCount(), 2);
|
||||
}
|
||||
|
||||
QTEST_MAIN(TestTabBoxClientModel)
|
||||
|
|
|
@ -33,6 +33,13 @@ private slots:
|
|||
* See bug #303840
|
||||
**/
|
||||
void testLongestCaptionWithNullClient();
|
||||
/**
|
||||
* Tests the creation of the Client list for the case that
|
||||
* there is no active Client, but that Clients actually exist.
|
||||
*
|
||||
* See BUG: 305449
|
||||
**/
|
||||
void testCreateClientListNoActiveClient();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue