FocusChain operates on AbstractClient instead of Client

As external interface it still returns Client* to not force the casts
to be done at usages. This will be changed once the users are migrated
to AbstractClient*.
icc-effect-5.14.5
Martin Gräßlin 2015-03-05 10:24:54 +01:00
parent 0f54da9dde
commit fe7a6834b2
4 changed files with 50 additions and 48 deletions

View File

@ -18,6 +18,7 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*********************************************************************/
#include "focuschain.h"
#include "abstract_client.h"
#include "client.h"
#include "screens.h"
@ -39,7 +40,7 @@ FocusChain::~FocusChain()
s_manager = NULL;
}
void FocusChain::remove(Client *client)
void FocusChain::remove(AbstractClient *client)
{
for (DesktopChains::iterator it = m_desktopFocusChains.begin();
it != m_desktopFocusChains.end();
@ -52,7 +53,7 @@ void FocusChain::remove(Client *client)
void FocusChain::resize(uint previousSize, uint newSize)
{
for (uint i = previousSize + 1; i <= newSize; ++i) {
m_desktopFocusChains.insert(i, QList<Client*>());
m_desktopFocusChains.insert(i, QList<AbstractClient*>());
}
for (uint i = previousSize; i > newSize; --i) {
m_desktopFocusChains.remove(i);
@ -70,19 +71,19 @@ Client *FocusChain::getForActivation(uint desktop, int screen) const
if (it == m_desktopFocusChains.constEnd()) {
return NULL;
}
const QList<Client*> &chain = it.value();
const auto &chain = it.value();
for (int i = chain.size() - 1; i >= 0; --i) {
Client *tmp = chain.at(i);
auto tmp = chain.at(i);
// TODO: move the check into Client
if (tmp->isShown(false) && tmp->isOnCurrentActivity()
&& ( !m_separateScreenFocus || tmp->screen() == screen)) {
return tmp;
return dynamic_cast<Client*>(tmp);
}
}
return NULL;
}
void FocusChain::update(Client *client, FocusChain::Change change)
void FocusChain::update(AbstractClient *client, FocusChain::Change change)
{
if (!client->wantsTabFocus()) {
// Doesn't want tab focus, remove
@ -95,7 +96,7 @@ void FocusChain::update(Client *client, FocusChain::Change change)
for (DesktopChains::iterator it = m_desktopFocusChains.begin();
it != m_desktopFocusChains.end();
++it) {
QList<Client*> &chain = it.value();
auto &chain = it.value();
// Making first/last works only on current desktop, don't affect all desktops
if (it.key() == m_currentDesktop
&& (change == MakeFirst || change == MakeLast)) {
@ -113,7 +114,7 @@ void FocusChain::update(Client *client, FocusChain::Change change)
for (DesktopChains::iterator it = m_desktopFocusChains.begin();
it != m_desktopFocusChains.end();
++it) {
QList<Client*> &chain = it.value();
auto &chain = it.value();
if (client->isOnDesktop(it.key())) {
updateClientInChain(client, change, chain);
} else {
@ -126,7 +127,7 @@ void FocusChain::update(Client *client, FocusChain::Change change)
updateClientInChain(client, change, m_mostRecentlyUsed);
}
void FocusChain::updateClientInChain(Client *client, FocusChain::Change change, QList< Client * >& chain)
void FocusChain::updateClientInChain(AbstractClient *client, FocusChain::Change change, QList< AbstractClient * >& chain)
{
if (change == MakeFirst) {
makeFirstInChain(client, chain);
@ -137,7 +138,7 @@ void FocusChain::updateClientInChain(Client *client, FocusChain::Change change,
}
}
void FocusChain::insertClientIntoChain(Client *client, QList< Client * >& chain)
void FocusChain::insertClientIntoChain(AbstractClient *client, QList< AbstractClient * >& chain)
{
if (chain.contains(client)) {
return;
@ -152,7 +153,7 @@ void FocusChain::insertClientIntoChain(Client *client, QList< Client * >& chain)
}
}
void FocusChain::moveAfterClient(Client *client, Client *reference)
void FocusChain::moveAfterClient(AbstractClient *client, AbstractClient *reference)
{
if (!client->wantsTabFocus()) {
return;
@ -169,18 +170,18 @@ void FocusChain::moveAfterClient(Client *client, Client *reference)
moveAfterClientInChain(client, reference, m_mostRecentlyUsed);
}
void FocusChain::moveAfterClientInChain(Client *client, Client *reference, QList<Client *> &chain)
void FocusChain::moveAfterClientInChain(AbstractClient *client, AbstractClient *reference, QList<AbstractClient *> &chain)
{
if (!chain.contains(reference)) {
return;
}
if (Client::belongToSameApplication(reference, client)) {
if (AbstractClient::belongToSameApplication(reference, client)) {
chain.removeAll(client);
chain.insert(chain.indexOf(reference), client);
} else {
chain.removeAll(client);
for (int i = chain.size() - 1; i >= 0; --i) {
if (Client::belongToSameApplication(reference, chain.at(i))) {
if (AbstractClient::belongToSameApplication(reference, chain.at(i))) {
chain.insert(i, client);
break;
}
@ -188,7 +189,7 @@ void FocusChain::moveAfterClientInChain(Client *client, Client *reference, QList
}
}
Client *FocusChain::firstMostRecentlyUsed() const
AbstractClient *FocusChain::firstMostRecentlyUsed() const
{
if (m_mostRecentlyUsed.isEmpty()) {
return NULL;
@ -196,7 +197,7 @@ Client *FocusChain::firstMostRecentlyUsed() const
return m_mostRecentlyUsed.first();
}
Client *FocusChain::nextMostRecentlyUsed(Client *reference) const
AbstractClient *FocusChain::nextMostRecentlyUsed(AbstractClient *reference) const
{
if (m_mostRecentlyUsed.isEmpty()) {
return NULL;
@ -212,30 +213,30 @@ Client *FocusChain::nextMostRecentlyUsed(Client *reference) const
}
// copied from activation.cpp
bool FocusChain::isUsableFocusCandidate(Client *c, Client *prev) const
bool FocusChain::isUsableFocusCandidate(AbstractClient *c, AbstractClient *prev) const
{
return c != prev &&
c->isShown(false) && c->isOnCurrentDesktop() && c->isOnCurrentActivity() &&
(!m_separateScreenFocus || c->isOnScreen(prev ? prev->screen() : screens()->current()));
}
Client *FocusChain::nextForDesktop(Client *reference, uint desktop) const
Client *FocusChain::nextForDesktop(AbstractClient *reference, uint desktop) const
{
DesktopChains::const_iterator it = m_desktopFocusChains.find(desktop);
if (it == m_desktopFocusChains.end()) {
return NULL;
}
const QList<Client*> &chain = it.value();
const auto &chain = it.value();
for (int i = chain.size() - 1; i >= 0; --i) {
Client* client = chain.at(i);
auto client = chain.at(i);
if (isUsableFocusCandidate(client, reference)) {
return client;
return dynamic_cast<Client*>(client);
}
}
return NULL;
}
void FocusChain::makeFirstInChain(Client *client, QList< Client * >& chain)
void FocusChain::makeFirstInChain(AbstractClient *client, QList< AbstractClient * >& chain)
{
chain.removeAll(client);
if (client->isMinimized()) { // add it before the first minimized ...
@ -251,13 +252,13 @@ void FocusChain::makeFirstInChain(Client *client, QList< Client * >& chain)
}
}
void FocusChain::makeLastInChain(Client *client, QList< Client * >& chain)
void FocusChain::makeLastInChain(AbstractClient *client, QList< AbstractClient * >& chain)
{
chain.removeAll(client);
chain.prepend(client);
}
bool FocusChain::contains(Client *client, uint desktop) const
bool FocusChain::contains(AbstractClient *client, uint desktop) const
{
DesktopChains::const_iterator it = m_desktopFocusChains.find(desktop);
if (it == m_desktopFocusChains.end()) {

View File

@ -28,6 +28,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
namespace KWin
{
// forward declarations
class AbstractClient;
class Client;
/**
@ -79,7 +80,7 @@ public:
* @param change Where to move the Client
* @return void
**/
void update(Client *client, Change change);
void update(AbstractClient *client, Change change);
/**
* @brief Moves @p client behind the @p reference Client in all focus chains.
*
@ -87,7 +88,7 @@ public:
* @param reference The Client behind which the @p client should be moved
* @return void
**/
void moveAfterClient(Client *client, Client *reference);
void moveAfterClient(AbstractClient *client, AbstractClient *reference);
/**
* @brief Finds the best Client to become the new active Client in the focus chain for the given
* virtual @p desktop.
@ -120,7 +121,7 @@ public:
* @param client The Client to look for.
* @return bool @c true if the most recently used focus chain contains @p client, @c false otherwise.
**/
bool contains(Client *client) const;
bool contains(AbstractClient *client) const;
/**
* @brief Checks whether the focus chain for the given @p desktop contains the given @p client.
*
@ -130,7 +131,7 @@ public:
* @param desktop The virtual desktop whose focus chain should be used
* @return bool @c true if the focus chain for @p desktop contains @p client, @c false otherwise.
**/
bool contains(Client *client, uint desktop) const;
bool contains(AbstractClient *client, uint desktop) const;
/**
* @brief Queries the most recently used focus chain for the next Client after the given
* @p reference Client.
@ -144,7 +145,7 @@ public:
* @param reference The start point in the focus chain to search
* @return :Client* The relatively next Client in the most recently used chain.
**/
Client *nextMostRecentlyUsed(Client *reference) const;
AbstractClient *nextMostRecentlyUsed(AbstractClient *reference) const;
/**
* @brief Queries the focus chain for @p desktop for the next Client in relation to the given
* @p reference Client.
@ -156,14 +157,14 @@ public:
* @param desktop The virtual desktop whose focus chain should be used
* @return :Client* The next usable Client or @c null if none can be found.
**/
Client *nextForDesktop(Client *reference, uint desktop) const;
Client *nextForDesktop(AbstractClient *reference, uint desktop) const;
/**
* @brief Returns the first Client in the most recently used focus chain. First Client in this
* case means really the first Client in the chain and not the most recently used Client.
*
* @return :Client* The first Client in the most recently used chain.
**/
Client *firstMostRecentlyUsed() const;
AbstractClient *firstMostRecentlyUsed() const;
public Q_SLOTS:
/**
@ -182,11 +183,11 @@ public Q_SLOTS:
* @param client The Client to remove from all focus chains.
* @return void
**/
void remove(KWin::Client *client);
void remove(KWin::AbstractClient *client);
void setSeparateScreenFocus(bool enabled);
void setActiveClient(KWin::Client *client);
void setActiveClient(KWin::AbstractClient *client);
void setCurrentDesktop(uint previous, uint newDesktop);
bool isUsableFocusCandidate(Client *c, Client *prev) const;
bool isUsableFocusCandidate(AbstractClient *c, AbstractClient *prev) const;
private:
/**
@ -199,7 +200,7 @@ private:
* @param chain The focus chain to operate on
* @return void
**/
void makeFirstInChain(Client *client, QList<Client*> &chain);
void makeFirstInChain(AbstractClient *client, QList<AbstractClient*> &chain);
/**
* @brief Makes @p client the last Client in the given focus @p chain.
*
@ -210,22 +211,22 @@ private:
* @param chain The focus chain to operate on
* @return void
**/
void makeLastInChain(Client *client, QList<Client*> &chain);
void moveAfterClientInChain(Client *client, Client *reference, QList<Client*> &chain);
void updateClientInChain(Client *client, Change change, QList<Client*> &chain);
void insertClientIntoChain(Client *client, QList<Client*> &chain);
typedef QHash<uint, QList<Client*> > DesktopChains;
QList<Client*> m_mostRecentlyUsed;
void makeLastInChain(AbstractClient *client, QList<AbstractClient*> &chain);
void moveAfterClientInChain(AbstractClient *client, AbstractClient *reference, QList<AbstractClient*> &chain);
void updateClientInChain(AbstractClient *client, Change change, QList<AbstractClient*> &chain);
void insertClientIntoChain(AbstractClient *client, QList<AbstractClient*> &chain);
typedef QHash<uint, QList<AbstractClient*> > DesktopChains;
QList<AbstractClient*> m_mostRecentlyUsed;
DesktopChains m_desktopFocusChains;
bool m_separateScreenFocus;
Client *m_activeClient;
AbstractClient *m_activeClient;
uint m_currentDesktop;
KWIN_SINGLETON_VARIABLE(FocusChain, s_manager)
};
inline
bool FocusChain::contains(Client *client) const
bool FocusChain::contains(AbstractClient *client) const
{
return m_mostRecentlyUsed.contains(client);
}
@ -237,7 +238,7 @@ void FocusChain::setSeparateScreenFocus(bool enabled)
}
inline
void FocusChain::setActiveClient(Client *client)
void FocusChain::setActiveClient(AbstractClient *client)
{
m_activeClient = client;
}

View File

@ -111,7 +111,7 @@ QString TabBoxHandlerImpl::desktopName(int desktop) const
QWeakPointer<TabBoxClient> TabBoxHandlerImpl::nextClientFocusChain(TabBoxClient* client) const
{
if (TabBoxClientImpl* c = static_cast< TabBoxClientImpl* >(client)) {
Client* next = FocusChain::self()->nextMostRecentlyUsed(c->client());
auto next = FocusChain::self()->nextMostRecentlyUsed(c->client());
if (next)
return next->tabBoxClient();
}
@ -120,7 +120,7 @@ QWeakPointer<TabBoxClient> TabBoxHandlerImpl::nextClientFocusChain(TabBoxClient*
QWeakPointer< TabBoxClient > TabBoxHandlerImpl::firstClientFocusChain() const
{
if (Client *c = FocusChain::self()->firstMostRecentlyUsed()) {
if (auto c = FocusChain::self()->firstMostRecentlyUsed()) {
return QWeakPointer<TabBoxClient>(c->tabBoxClient());
} else {
return QWeakPointer<TabBoxClient>();

View File

@ -229,8 +229,8 @@ void Workspace::init()
connect(this, SIGNAL(clientActivated(KWin::Client*)), screenEdges, SIGNAL(checkBlocking()));
FocusChain *focusChain = FocusChain::create(this);
connect(this, SIGNAL(clientRemoved(KWin::Client*)), focusChain, SLOT(remove(KWin::Client*)));
connect(this, SIGNAL(clientActivated(KWin::Client*)), focusChain, SLOT(setActiveClient(KWin::Client*)));
connect(this, &Workspace::clientRemoved, focusChain, &FocusChain::remove);
connect(this, &Workspace::clientActivated, focusChain, &FocusChain::setActiveClient);
connect(VirtualDesktopManager::self(), SIGNAL(countChanged(uint,uint)), focusChain, SLOT(resize(uint,uint)));
connect(VirtualDesktopManager::self(), SIGNAL(currentChanged(uint,uint)), focusChain, SLOT(setCurrentDesktop(uint,uint)));
connect(options, SIGNAL(separateScreenFocusChanged(bool)), focusChain, SLOT(setSeparateScreenFocus(bool)));