kwin/tabbox/tabbox.h

375 lines
12 KiB
C
Raw Normal View History

/********************************************************************
KWin - the KDE window manager
This file is part of the KDE project.
Copyright (C) 1999, 2000 Matthias Ettrich <ettrich@kde.org>
Copyright (C) 2003 Lubos Lunak <l.lunak@kde.org>
Copyright (C) 2009 Martin Gräßlin <mgraesslin@kde.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*********************************************************************/
#ifndef KWIN_TABBOX_H
#define KWIN_TABBOX_H
#include <QKeySequence>
#include <QTimer>
#include <QModelIndex>
#include "utils.h"
#include "tabbox/tabboxhandler.h"
class KConfigGroup;
class QAction;
class QMouseEvent;
class QKeyEvent;
class QWheelEvent;
namespace KWin
{
class Workspace;
class AbstractClient;
class X11EventFilter;
namespace TabBox
{
class DesktopChainManager;
class TabBoxConfig;
class TabBox;
class TabBoxHandlerImpl : public TabBoxHandler
2011-01-30 14:34:42 +00:00
{
public:
explicit TabBoxHandlerImpl(TabBox* tabBox);
Run clang-tidy with modernize-use-override check Summary: Currently code base of kwin can be viewed as two pieces. One is very ancient, and the other one is more modern, which uses new C++ features. The main problem with the ancient code is that it was written before C++11 era. So, no override or final keywords, lambdas, etc. Quite recently, KDE compiler settings were changed to show a warning if a virtual method has missing override keyword. As you might have already guessed, this fired back at us because of that ancient code. We had about 500 new compiler warnings. A "solution" was proposed to that problem - disable -Wno-suggest-override and the other similar warning for clang. It's hard to call a solution because those warnings are disabled not only for the old code, but also for new. This is not what we want! The main argument for not actually fixing the problem was that git history will be screwed as well because of human factor. While good git history is a very important thing, we should not go crazy about it and block every change that somehow alters git history. git blame allows to specify starting revision for a reason. The other argument (human factor) can be easily solved by using tools such as clang-tidy. clang-tidy is a clang-based linter for C++. It can be used for various things, e.g. fixing coding style(e.g. add missing braces to if statements, readability-braces-around-statements check), or in our case add missing override keywords. Test Plan: Compiles. Reviewers: #kwin, davidedmundson Reviewed By: #kwin, davidedmundson Subscribers: davidedmundson, apol, romangg, kwin Tags: #kwin Differential Revision: https://phabricator.kde.org/D22371
2019-07-22 16:52:26 +00:00
~TabBoxHandlerImpl() override;
int activeScreen() const override;
QWeakPointer< TabBoxClient > activeClient() const override;
int currentDesktop() const override;
QString desktopName(TabBoxClient* client) const override;
QString desktopName(int desktop) const override;
bool isKWinCompositing() const override;
QWeakPointer< TabBoxClient > nextClientFocusChain(TabBoxClient* client) const override;
QWeakPointer< TabBoxClient > firstClientFocusChain() const override;
bool isInFocusChain (TabBoxClient* client) const override;
int nextDesktopFocusChain(int desktop) const override;
int numberOfDesktops() const override;
TabBoxClientList stackingOrder() const override;
void elevateClient(TabBoxClient* c, QWindow *tabbox, bool elevate) const override;
void raiseClient(TabBoxClient *client) const override;
void restack(TabBoxClient *c, TabBoxClient *under) override;
void shadeClient(TabBoxClient *c, bool b) const override;
QWeakPointer< TabBoxClient > clientToAddToList(KWin::TabBox::TabBoxClient* client, int desktop) const override;
QWeakPointer< TabBoxClient > desktopClient() const override;
void activateAndClose() override;
void highlightWindows(TabBoxClient *window = nullptr, QWindow *controller = nullptr) override;
bool noModifierGrab() const override;
private:
bool checkDesktop(TabBoxClient* client, int desktop) const;
bool checkActivity(TabBoxClient* client) const;
bool checkApplications(TabBoxClient* client) const;
bool checkMinimized(TabBoxClient* client) const;
bool checkMultiScreen(TabBoxClient* client) const;
TabBox* m_tabBox;
DesktopChainManager* m_desktopFocusChain;
2011-01-30 14:34:42 +00:00
};
class TabBoxClientImpl : public TabBoxClient
2011-01-30 14:34:42 +00:00
{
public:
explicit TabBoxClientImpl(AbstractClient *client);
Run clang-tidy with modernize-use-override check Summary: Currently code base of kwin can be viewed as two pieces. One is very ancient, and the other one is more modern, which uses new C++ features. The main problem with the ancient code is that it was written before C++11 era. So, no override or final keywords, lambdas, etc. Quite recently, KDE compiler settings were changed to show a warning if a virtual method has missing override keyword. As you might have already guessed, this fired back at us because of that ancient code. We had about 500 new compiler warnings. A "solution" was proposed to that problem - disable -Wno-suggest-override and the other similar warning for clang. It's hard to call a solution because those warnings are disabled not only for the old code, but also for new. This is not what we want! The main argument for not actually fixing the problem was that git history will be screwed as well because of human factor. While good git history is a very important thing, we should not go crazy about it and block every change that somehow alters git history. git blame allows to specify starting revision for a reason. The other argument (human factor) can be easily solved by using tools such as clang-tidy. clang-tidy is a clang-based linter for C++. It can be used for various things, e.g. fixing coding style(e.g. add missing braces to if statements, readability-braces-around-statements check), or in our case add missing override keywords. Test Plan: Compiles. Reviewers: #kwin, davidedmundson Reviewed By: #kwin, davidedmundson Subscribers: davidedmundson, apol, romangg, kwin Tags: #kwin Differential Revision: https://phabricator.kde.org/D22371
2019-07-22 16:52:26 +00:00
~TabBoxClientImpl() override;
QString caption() const override;
QIcon icon() const override;
bool isMinimized() const override;
int x() const override;
int y() const override;
int width() const override;
int height() const override;
bool isCloseable() const override;
void close() override;
bool isFirstInTabBox() const override;
QUuid internalId() const override;
2011-01-30 14:34:42 +00:00
AbstractClient* client() const {
2011-01-30 14:34:42 +00:00
return m_client;
}
private:
AbstractClient* m_client;
2011-01-30 14:34:42 +00:00
};
class KWIN_EXPORT TabBox : public QObject
2011-01-30 14:34:42 +00:00
{
Q_OBJECT
2011-01-30 14:34:42 +00:00
public:
Run clang-tidy with modernize-use-override check Summary: Currently code base of kwin can be viewed as two pieces. One is very ancient, and the other one is more modern, which uses new C++ features. The main problem with the ancient code is that it was written before C++11 era. So, no override or final keywords, lambdas, etc. Quite recently, KDE compiler settings were changed to show a warning if a virtual method has missing override keyword. As you might have already guessed, this fired back at us because of that ancient code. We had about 500 new compiler warnings. A "solution" was proposed to that problem - disable -Wno-suggest-override and the other similar warning for clang. It's hard to call a solution because those warnings are disabled not only for the old code, but also for new. This is not what we want! The main argument for not actually fixing the problem was that git history will be screwed as well because of human factor. While good git history is a very important thing, we should not go crazy about it and block every change that somehow alters git history. git blame allows to specify starting revision for a reason. The other argument (human factor) can be easily solved by using tools such as clang-tidy. clang-tidy is a clang-based linter for C++. It can be used for various things, e.g. fixing coding style(e.g. add missing braces to if statements, readability-braces-around-statements check), or in our case add missing override keywords. Test Plan: Compiles. Reviewers: #kwin, davidedmundson Reviewed By: #kwin, davidedmundson Subscribers: davidedmundson, apol, romangg, kwin Tags: #kwin Differential Revision: https://phabricator.kde.org/D22371
2019-07-22 16:52:26 +00:00
~TabBox() override;
/**
* Returns the currently displayed client ( only works in TabBoxWindowsMode ).
* Returns 0 if no client is displayed.
*/
AbstractClient *currentClient();
/**
* Returns the list of clients potentially displayed ( only works in
* TabBoxWindowsMode ).
* Returns an empty list if no clients are available.
*/
QList<AbstractClient*> currentClientList();
/**
* Returns the currently displayed virtual desktop ( only works in
* TabBoxDesktopListMode )
* Returns -1 if no desktop is displayed.
*/
2011-01-30 14:34:42 +00:00
int currentDesktop();
/**
* Returns the list of desktops potentially displayed ( only works in
* TabBoxDesktopListMode )
* Returns an empty list if no are available.
*/
2011-01-30 14:34:42 +00:00
QList< int > currentDesktopList();
/**
* Change the currently selected client, and notify the effects.
*
* @see setCurrentDesktop
*/
void setCurrentClient(AbstractClient *newClient);
/**
* Change the currently selected desktop, and notify the effects.
*
* @see setCurrentClient
*/
2011-01-30 14:34:42 +00:00
void setCurrentDesktop(int newDesktop);
/**
* Sets the current mode to \a mode, either TabBoxDesktopListMode or TabBoxWindowsMode
*
* @see mode
*/
2011-01-30 14:34:42 +00:00
void setMode(TabBoxMode mode);
TabBoxMode mode() const {
return m_tabBoxMode;
}
/**
* Resets the tab box to display the active client in TabBoxWindowsMode, or the
* current desktop in TabBoxDesktopListMode
*/
2011-01-30 14:34:42 +00:00
void reset(bool partial_reset = false);
/**
* Shows the next or previous item, depending on \a next
*/
2011-01-30 14:34:42 +00:00
void nextPrev(bool next = true);
/**
* Shows the tab box after some delay.
*
* If the 'ShowDelay' setting is false, show() is simply called.
*
* Otherwise, we start a timer for the delay given in the settings and only
* do a show() when it times out.
*
* This means that you can alt-tab between windows and you don't see the
* tab box immediately. Not only does this make alt-tabbing faster, it gives
* less 'flicker' to the eyes. You don't need to see the tab box if you're
* just quickly switching between 2 or 3 windows. It seems to work quite
* nicely.
*/
2011-01-30 14:34:42 +00:00
void delayedShow();
/**
* Notify effects that the tab box is being hidden.
*/
void hide(bool abort = false);
/**
* Increases the reference count, preventing the default tabbox from showing.
*
* @see unreference
* @see isDisplayed
*/
void reference() {
++m_displayRefcount;
}
/**
* Decreases the reference count. Only when the reference count is 0 will
* the default tab box be shown.
*/
void unreference() {
--m_displayRefcount;
}
/**
* Returns whether the tab box is being displayed, either natively or by an
* effect.
*
* @see reference
* @see unreference
*/
bool isDisplayed() const {
return m_displayRefcount > 0;
2018-10-27 08:59:53 +00:00
}
/**
* @returns @c true if TabBox is shown, @c false if replaced by Effect
*/
bool isShown() const {
return m_isShown;
}
bool handleMouseEvent(QMouseEvent *event);
bool handleWheelEvent(QWheelEvent *event);
2011-01-30 14:34:42 +00:00
void grabbedKeyEvent(QKeyEvent* event);
bool isGrabbed() const {
return m_tabGrab || m_desktopGrab;
2017-09-13 16:46:55 +00:00
}
void initShortcuts();
AbstractClient* nextClientStatic(AbstractClient*) const;
AbstractClient* previousClientStatic(AbstractClient*) const;
int nextDesktopStatic(int iDesktop) const;
int previousDesktopStatic(int iDesktop) const;
void keyPress(int key);
void modifiersReleased();
bool forcedGlobalMouseGrab() const {
return m_forcedGlobalMouseGrab;
}
bool noModifierGrab() const {
return m_noModifierGrab;
}
void setCurrentIndex(QModelIndex index, bool notifyEffects = true);
static TabBox *self();
static TabBox *create(QObject *parent);
public Q_SLOTS:
/**
* Notify effects that the tab box is being shown, and only display the
* default tab box QFrame if no effect has referenced the tab box.
*/
2011-01-30 14:34:42 +00:00
void show();
void close(bool abort = false);
void accept(bool closeTabBox = true);
void slotWalkThroughDesktops();
void slotWalkBackThroughDesktops();
void slotWalkThroughDesktopList();
void slotWalkBackThroughDesktopList();
void slotWalkThroughWindows();
void slotWalkBackThroughWindows();
void slotWalkThroughWindowsAlternative();
void slotWalkBackThroughWindowsAlternative();
void slotWalkThroughCurrentAppWindows();
void slotWalkBackThroughCurrentAppWindows();
void slotWalkThroughCurrentAppWindowsAlternative();
void slotWalkBackThroughCurrentAppWindowsAlternative();
void handlerReady();
bool toggle(ElectricBorder eb);
Q_SIGNALS:
void tabBoxAdded(int);
void tabBoxClosed();
void tabBoxUpdated();
void tabBoxKeyEvent(QKeyEvent*);
2011-01-30 14:34:42 +00:00
private:
explicit TabBox(QObject *parent);
2011-01-30 14:34:42 +00:00
void loadConfig(const KConfigGroup& config, TabBoxConfig& tabBoxConfig);
bool startKDEWalkThroughWindows(TabBoxMode mode); // TabBoxWindowsMode | TabBoxWindowsAlternativeMode
bool startWalkThroughDesktops(TabBoxMode mode); // TabBoxDesktopMode | TabBoxDesktopListMode
bool startWalkThroughDesktops();
bool startWalkThroughDesktopList();
void navigatingThroughWindows(bool forward, const QKeySequence &shortcut, TabBoxMode mode); // TabBoxWindowsMode | TabBoxWindowsAlternativeMode
void KDEWalkThroughWindows(bool forward);
void CDEWalkThroughWindows(bool forward);
void walkThroughDesktops(bool forward);
void KDEOneStepThroughWindows(bool forward, TabBoxMode mode); // TabBoxWindowsMode | TabBoxWindowsAlternativeMode
void oneStepThroughDesktops(bool forward, TabBoxMode mode); // TabBoxDesktopMode | TabBoxDesktopListMode
void oneStepThroughDesktops(bool forward);
void oneStepThroughDesktopList(bool forward);
bool establishTabBoxGrab();
void removeTabBoxGrab();
template <typename Slot>
void key(const char *actionName, Slot slot, const QKeySequence &shortcut = QKeySequence());
void shadeActivate(AbstractClient *c);
bool toggleMode(TabBoxMode mode);
private Q_SLOTS:
void reconfigure();
void globalShortcutChanged(QAction *action, const QKeySequence &seq);
2011-01-30 14:34:42 +00:00
private:
TabBoxMode m_tabBoxMode;
TabBoxHandlerImpl* m_tabBox;
bool m_delayShow;
int m_delayShowTime;
QTimer m_delayedShowTimer;
int m_displayRefcount;
2011-01-30 14:34:42 +00:00
TabBoxConfig m_defaultConfig;
TabBoxConfig m_alternativeConfig;
TabBoxConfig m_defaultCurrentApplicationConfig;
TabBoxConfig m_alternativeCurrentApplicationConfig;
2011-01-30 14:34:42 +00:00
TabBoxConfig m_desktopConfig;
TabBoxConfig m_desktopListConfig;
// false if an effect has referenced the tabbox
// true if tabbox is active (independent on showTabbox setting)
bool m_isShown;
bool m_desktopGrab;
bool m_tabGrab;
// true if tabbox is in modal mode which does not require holding a modifier
bool m_noModifierGrab;
QKeySequence m_cutWalkThroughDesktops, m_cutWalkThroughDesktopsReverse;
QKeySequence m_cutWalkThroughDesktopList, m_cutWalkThroughDesktopListReverse;
QKeySequence m_cutWalkThroughWindows, m_cutWalkThroughWindowsReverse;
QKeySequence m_cutWalkThroughWindowsAlternative, m_cutWalkThroughWindowsAlternativeReverse;
QKeySequence m_cutWalkThroughCurrentAppWindows, m_cutWalkThroughCurrentAppWindowsReverse;
QKeySequence m_cutWalkThroughCurrentAppWindowsAlternative, m_cutWalkThroughCurrentAppWindowsAlternativeReverse;
bool m_forcedGlobalMouseGrab;
bool m_ready; // indicates whether the config is completely loaded
QList<ElectricBorder> m_borderActivate, m_borderAlternativeActivate;
QHash<ElectricBorder, QAction *> m_touchActivate;
QHash<ElectricBorder, QAction *> m_touchAlternativeActivate;
QScopedPointer<X11EventFilter> m_x11EventFilter;
static TabBox *s_self;
2011-01-30 14:34:42 +00:00
};
inline
TabBox *TabBox::self()
{
return s_self;
}
} // namespace TabBox
} // namespace
#endif