File indexing completed on 2024-05-19 16:34:55
0001 /* 0002 KWin - the KDE window manager 0003 This file is part of the KDE project. 0004 0005 SPDX-FileCopyrightText: 1999, 2000 Matthias Ettrich <ettrich@kde.org> 0006 SPDX-FileCopyrightText: 2003 Lubos Lunak <l.lunak@kde.org> 0007 SPDX-FileCopyrightText: 2009 Martin Gräßlin <mgraesslin@kde.org> 0008 0009 SPDX-License-Identifier: GPL-2.0-or-later 0010 */ 0011 0012 #pragma once 0013 0014 #include "tabbox/tabboxhandler.h" 0015 #include "utils/common.h" 0016 #include <QKeySequence> 0017 #include <QModelIndex> 0018 #include <QTimer> 0019 0020 class KConfigGroup; 0021 class KLazyLocalizedString; 0022 class QAction; 0023 class QMouseEvent; 0024 class QKeyEvent; 0025 class QWheelEvent; 0026 0027 namespace KWin 0028 { 0029 0030 class Workspace; 0031 class Window; 0032 class X11EventFilter; 0033 namespace TabBox 0034 { 0035 class DesktopChainManager; 0036 class TabBoxConfig; 0037 class TabBox; 0038 class TabBoxHandlerImpl : public TabBoxHandler 0039 { 0040 public: 0041 explicit TabBoxHandlerImpl(TabBox *tabBox); 0042 ~TabBoxHandlerImpl() override; 0043 0044 int activeScreen() const override; 0045 QWeakPointer<TabBoxClient> activeClient() const override; 0046 int currentDesktop() const override; 0047 QString desktopName(TabBoxClient *client) const override; 0048 QString desktopName(int desktop) const override; 0049 bool isKWinCompositing() const override; 0050 QWeakPointer<TabBoxClient> nextClientFocusChain(TabBoxClient *client) const override; 0051 QWeakPointer<TabBoxClient> firstClientFocusChain() const override; 0052 bool isInFocusChain(TabBoxClient *client) const override; 0053 int nextDesktopFocusChain(int desktop) const override; 0054 int numberOfDesktops() const override; 0055 TabBoxClientList stackingOrder() const override; 0056 void elevateClient(TabBoxClient *c, QWindow *tabbox, bool elevate) const override; 0057 void raiseClient(TabBoxClient *client) const override; 0058 void restack(TabBoxClient *c, TabBoxClient *under) override; 0059 void shadeClient(TabBoxClient *c, bool b) const override; 0060 QWeakPointer<TabBoxClient> clientToAddToList(KWin::TabBox::TabBoxClient *client, int desktop) const override; 0061 QWeakPointer<TabBoxClient> desktopClient() const override; 0062 void activateAndClose() override; 0063 void highlightWindows(TabBoxClient *window = nullptr, QWindow *controller = nullptr) override; 0064 bool noModifierGrab() const override; 0065 0066 private: 0067 bool checkDesktop(TabBoxClient *client, int desktop) const; 0068 bool checkActivity(TabBoxClient *client) const; 0069 bool checkApplications(TabBoxClient *client) const; 0070 bool checkMinimized(TabBoxClient *client) const; 0071 bool checkMultiScreen(TabBoxClient *client) const; 0072 0073 TabBox *m_tabBox; 0074 DesktopChainManager *m_desktopFocusChain; 0075 }; 0076 0077 class TabBoxClientImpl : public TabBoxClient 0078 { 0079 public: 0080 explicit TabBoxClientImpl(Window *client); 0081 ~TabBoxClientImpl() override; 0082 0083 QString caption() const override; 0084 QIcon icon() const override; 0085 bool isMinimized() const override; 0086 int x() const override; 0087 int y() const override; 0088 int width() const override; 0089 int height() const override; 0090 bool isCloseable() const override; 0091 void close() override; 0092 bool isFirstInTabBox() const override; 0093 QUuid internalId() const override; 0094 0095 Window *client() const 0096 { 0097 return m_client; 0098 } 0099 0100 private: 0101 Window *m_client; 0102 }; 0103 0104 class KWIN_EXPORT TabBox : public QObject 0105 { 0106 Q_OBJECT 0107 public: 0108 explicit TabBox(); 0109 ~TabBox(); 0110 0111 /** 0112 * Returns the currently displayed client ( only works in TabBoxWindowsMode ). 0113 * Returns 0 if no client is displayed. 0114 */ 0115 Window *currentClient(); 0116 0117 /** 0118 * Returns the list of clients potentially displayed ( only works in 0119 * TabBoxWindowsMode ). 0120 * Returns an empty list if no clients are available. 0121 */ 0122 QList<Window *> currentClientList(); 0123 0124 /** 0125 * Returns the currently displayed virtual desktop ( only works in 0126 * TabBoxDesktopListMode ) 0127 * Returns -1 if no desktop is displayed. 0128 */ 0129 int currentDesktop(); 0130 0131 /** 0132 * Returns the list of desktops potentially displayed ( only works in 0133 * TabBoxDesktopListMode ) 0134 * Returns an empty list if no are available. 0135 */ 0136 QList<int> currentDesktopList(); 0137 0138 /** 0139 * Change the currently selected client, and notify the effects. 0140 * 0141 * @see setCurrentDesktop 0142 */ 0143 void setCurrentClient(Window *newClient); 0144 0145 /** 0146 * Change the currently selected desktop, and notify the effects. 0147 * 0148 * @see setCurrentClient 0149 */ 0150 void setCurrentDesktop(int newDesktop); 0151 0152 /** 0153 * Sets the current mode to \a mode, either TabBoxDesktopListMode or TabBoxWindowsMode 0154 * 0155 * @see mode 0156 */ 0157 void setMode(TabBoxMode mode); 0158 TabBoxMode mode() const 0159 { 0160 return m_tabBoxMode; 0161 } 0162 0163 /** 0164 * Resets the tab box to display the active client in TabBoxWindowsMode, or the 0165 * current desktop in TabBoxDesktopListMode 0166 */ 0167 void reset(bool partial_reset = false); 0168 0169 /** 0170 * Shows the next or previous item, depending on \a next 0171 */ 0172 void nextPrev(bool next = true); 0173 0174 /** 0175 * Shows the tab box after some delay. 0176 * 0177 * If the 'DelayTime' setting is 0, show() is simply called. 0178 * 0179 * Otherwise, we start a timer for the delay given in the settings and only 0180 * do a show() when it times out. 0181 * 0182 * This means that you can alt-tab between windows and you don't see the 0183 * tab box immediately. Not only does this make alt-tabbing faster, it gives 0184 * less 'flicker' to the eyes. You don't need to see the tab box if you're 0185 * just quickly switching between 2 or 3 windows. It seems to work quite 0186 * nicely. 0187 */ 0188 void delayedShow(); 0189 0190 /** 0191 * Notify effects that the tab box is being hidden. 0192 */ 0193 void hide(bool abort = false); 0194 0195 /** 0196 * Increases the reference count, preventing the default tabbox from showing. 0197 * 0198 * @see unreference 0199 * @see isDisplayed 0200 */ 0201 void reference() 0202 { 0203 ++m_displayRefcount; 0204 } 0205 0206 /** 0207 * Decreases the reference count. Only when the reference count is 0 will 0208 * the default tab box be shown. 0209 */ 0210 void unreference() 0211 { 0212 --m_displayRefcount; 0213 } 0214 0215 /** 0216 * Returns whether the tab box is being displayed, either natively or by an 0217 * effect. 0218 * 0219 * @see reference 0220 * @see unreference 0221 */ 0222 bool isDisplayed() const 0223 { 0224 return m_displayRefcount > 0; 0225 } 0226 0227 /** 0228 * @returns @c true if TabBox is shown, @c false if replaced by Effect 0229 */ 0230 bool isShown() const 0231 { 0232 return m_isShown; 0233 } 0234 0235 bool handleMouseEvent(QMouseEvent *event); 0236 bool handleWheelEvent(QWheelEvent *event); 0237 void grabbedKeyEvent(QKeyEvent *event); 0238 0239 bool isGrabbed() const 0240 { 0241 return m_tabGrab || m_desktopGrab; 0242 } 0243 0244 void initShortcuts(); 0245 0246 Window *nextClientStatic(Window *) const; 0247 Window *previousClientStatic(Window *) const; 0248 int nextDesktopStatic(int iDesktop) const; 0249 int previousDesktopStatic(int iDesktop) const; 0250 void keyPress(int key); 0251 void modifiersReleased(); 0252 0253 bool forcedGlobalMouseGrab() const 0254 { 0255 return m_forcedGlobalMouseGrab; 0256 } 0257 0258 bool noModifierGrab() const 0259 { 0260 return m_noModifierGrab; 0261 } 0262 void setCurrentIndex(QModelIndex index, bool notifyEffects = true); 0263 0264 public Q_SLOTS: 0265 /** 0266 * Notify effects that the tab box is being shown, and only display the 0267 * default tab box QFrame if no effect has referenced the tab box. 0268 */ 0269 void show(); 0270 void close(bool abort = false); 0271 void accept(bool closeTabBox = true); 0272 void slotWalkThroughDesktops(); 0273 void slotWalkBackThroughDesktops(); 0274 void slotWalkThroughDesktopList(); 0275 void slotWalkBackThroughDesktopList(); 0276 void slotWalkThroughWindows(); 0277 void slotWalkBackThroughWindows(); 0278 void slotWalkThroughWindowsAlternative(); 0279 void slotWalkBackThroughWindowsAlternative(); 0280 void slotWalkThroughCurrentAppWindows(); 0281 void slotWalkBackThroughCurrentAppWindows(); 0282 void slotWalkThroughCurrentAppWindowsAlternative(); 0283 void slotWalkBackThroughCurrentAppWindowsAlternative(); 0284 0285 void handlerReady(); 0286 0287 bool toggle(ElectricBorder eb); 0288 0289 Q_SIGNALS: 0290 void tabBoxAdded(int); 0291 void tabBoxClosed(); 0292 void tabBoxUpdated(); 0293 void tabBoxKeyEvent(QKeyEvent *); 0294 0295 private: 0296 explicit TabBox(QObject *parent); 0297 void loadConfig(const KConfigGroup &config, TabBoxConfig &tabBoxConfig); 0298 0299 bool startKDEWalkThroughWindows(TabBoxMode mode); // TabBoxWindowsMode | TabBoxWindowsAlternativeMode 0300 bool startWalkThroughDesktops(TabBoxMode mode); // TabBoxDesktopMode | TabBoxDesktopListMode 0301 bool startWalkThroughDesktops(); 0302 bool startWalkThroughDesktopList(); 0303 void navigatingThroughWindows(bool forward, const QKeySequence &shortcut, TabBoxMode mode); // TabBoxWindowsMode | TabBoxWindowsAlternativeMode 0304 void KDEWalkThroughWindows(bool forward); 0305 void CDEWalkThroughWindows(bool forward); 0306 void walkThroughDesktops(bool forward); 0307 void KDEOneStepThroughWindows(bool forward, TabBoxMode mode); // TabBoxWindowsMode | TabBoxWindowsAlternativeMode 0308 void oneStepThroughDesktops(bool forward, TabBoxMode mode); // TabBoxDesktopMode | TabBoxDesktopListMode 0309 void oneStepThroughDesktops(bool forward); 0310 void oneStepThroughDesktopList(bool forward); 0311 bool establishTabBoxGrab(); 0312 void removeTabBoxGrab(); 0313 template<typename Slot> 0314 void key(const KLazyLocalizedString &actionName, Slot slot, const QKeySequence &shortcut = QKeySequence()); 0315 0316 void shadeActivate(Window *c); 0317 0318 bool toggleMode(TabBoxMode mode); 0319 0320 private Q_SLOTS: 0321 void reconfigure(); 0322 void globalShortcutChanged(QAction *action, const QKeySequence &seq); 0323 0324 private: 0325 TabBoxMode m_tabBoxMode; 0326 TabBoxHandlerImpl *m_tabBox; 0327 int m_delayShowTime; 0328 0329 QTimer m_delayedShowTimer; 0330 int m_displayRefcount; 0331 0332 TabBoxConfig m_defaultConfig; 0333 TabBoxConfig m_alternativeConfig; 0334 TabBoxConfig m_defaultCurrentApplicationConfig; 0335 TabBoxConfig m_alternativeCurrentApplicationConfig; 0336 TabBoxConfig m_desktopConfig; 0337 TabBoxConfig m_desktopListConfig; 0338 // false if an effect has referenced the tabbox 0339 // true if tabbox is active (independent on showTabbox setting) 0340 bool m_isShown; 0341 bool m_desktopGrab; 0342 bool m_tabGrab; 0343 // true if tabbox is in modal mode which does not require holding a modifier 0344 bool m_noModifierGrab; 0345 QKeySequence m_cutWalkThroughDesktops, m_cutWalkThroughDesktopsReverse; 0346 QKeySequence m_cutWalkThroughDesktopList, m_cutWalkThroughDesktopListReverse; 0347 QKeySequence m_cutWalkThroughWindows, m_cutWalkThroughWindowsReverse; 0348 QKeySequence m_cutWalkThroughWindowsAlternative, m_cutWalkThroughWindowsAlternativeReverse; 0349 QKeySequence m_cutWalkThroughCurrentAppWindows, m_cutWalkThroughCurrentAppWindowsReverse; 0350 QKeySequence m_cutWalkThroughCurrentAppWindowsAlternative, m_cutWalkThroughCurrentAppWindowsAlternativeReverse; 0351 bool m_forcedGlobalMouseGrab; 0352 bool m_ready; // indicates whether the config is completely loaded 0353 QList<ElectricBorder> m_borderActivate, m_borderAlternativeActivate; 0354 QHash<ElectricBorder, QAction *> m_touchActivate; 0355 QHash<ElectricBorder, QAction *> m_touchAlternativeActivate; 0356 std::unique_ptr<X11EventFilter> m_x11EventFilter; 0357 }; 0358 0359 } // namespace TabBox 0360 } // namespace