File indexing completed on 2024-05-19 05:32:27
0001 /* 0002 KWin - the KDE window manager 0003 This file is part of the KDE project. 0004 0005 SPDX-FileCopyrightText: 2009 Martin Gräßlin <mgraesslin@kde.org> 0006 0007 SPDX-License-Identifier: GPL-2.0-or-later 0008 */ 0009 0010 #pragma once 0011 0012 #include "tabboxconfig.h" 0013 0014 #include <QModelIndex> 0015 #include <QPixmap> 0016 #include <QString> 0017 0018 /** 0019 * @file 0020 * This file contains the classes which hide KWin core from tabbox. 0021 * 0022 * @author Martin Gräßlin <mgraesslin@kde.org> 0023 * @since 4.4 0024 */ 0025 0026 class QKeyEvent; 0027 0028 namespace KWin 0029 { 0030 0031 class Window; 0032 0033 /** 0034 * The TabBox is a model based view for displaying a list while switching windows. 0035 * This functionality is mostly referred to as Alt+Tab. TabBox itself does not provide support for 0036 * switching windows. This has to be done outside of TabBox inside an independent controller. 0037 * 0038 * The main entrance point to TabBox is the class TabBoxHandler, which has to be subclassed and implemented. 0039 * 0040 * The behavior of the TabBox is defined by the TabBoxConfig and has to be set in the TabBoxHandler. 0041 * 0042 * In order to use the TabBox the TabBoxConfig has to be set. The model has to be initialized by calling 0043 * TabBoxHandler::createModel(), as the 0044 * model is undefined when the TabBox is not active. The TabBox is activated by TabBoxHandler::show(). 0045 * Depending on the current set TabBoxConfig it is possible that the 0046 * highlight windows effect activated and that the view is not displayed at all. As already mentioned 0047 * the TabBox does not handle any updating of the selected item. This has to be done by invoking 0048 * TabBoxHandler::setCurrentIndex(). Nevertheless the TabBoxHandler provides methods to query for the 0049 * model index or the next or previous item, for a cursor position or for a given item. By invoking 0050 * TabBoxHandler::hide() the view, the 0051 * optional highlight windows effect are removed. The model is invalidated immediately. So if it is 0052 * necessary to retrieve the last selected item this has to be done before calling the hide method. 0053 * 0054 * The layout of the TabBox View and the items is completely customizable. Therefore TabBox provides 0055 * a widget LayoutConfig which includes a live preview (in kcmkwin/kwintabbox). The layout of items 0056 * can be defined by an xml document. That way the user is able to define own custom layouts. The view 0057 * itself is made up of two widgets: one to show the complete list and one to show only the selected 0058 * item. This way it is possible to have a view which shows for example a list containing only small 0059 * icons and nevertheless show the title of the currently selected client. 0060 */ 0061 namespace TabBox 0062 { 0063 class ClientModel; 0064 class TabBoxConfig; 0065 class TabBoxHandlerPrivate; 0066 0067 /** 0068 * This class is a wrapper around KWin Workspace. It is used for accessing the 0069 * required core methods from inside TabBox and has to be implemented in KWin core. 0070 * 0071 * @author Martin Gräßlin <mgraesslin@kde.org> 0072 * @since 4.4 0073 */ 0074 class TabBoxHandler : public QObject 0075 { 0076 Q_OBJECT 0077 public: 0078 TabBoxHandler(QObject *parent); 0079 ~TabBoxHandler() override; 0080 0081 /** 0082 * @return The id of the active screen 0083 */ 0084 virtual int activeScreen() const = 0; 0085 /** 0086 * @return The current active Window or NULL 0087 * if there is no active client. 0088 */ 0089 virtual Window *activeClient() const = 0; 0090 /** 0091 * @param client The client which is starting point to find the next client 0092 * @return The next Window in focus chain 0093 */ 0094 virtual Window *nextClientFocusChain(Window *client) const = 0; 0095 /** 0096 * This method is used by the ClientModel to find an entrance into the focus chain in case 0097 * there is no active Client. 0098 * 0099 * @return The first Client of the focus chain 0100 * @since 4.9.1 0101 */ 0102 virtual Window *firstClientFocusChain() const = 0; 0103 /** 0104 * Checks whether the given @p client is part of the focus chain at all. 0105 * This is useful to figure out whether the currently active Client can be used 0106 * as a starting point to construct the recently used list. 0107 * 0108 * In case the @p client is not in the focus chain it is recommended to use the 0109 * Client returned by firstClientFocusChain. 0110 * 0111 * The method accepts a @c null Client and in that case @c false is returned. 0112 * @param client The Client to check whether it is in the Focus Chain 0113 * @return @c true in case the Client is part of the focus chain, @c false otherwise. 0114 * @since 4.9.2 0115 */ 0116 virtual bool isInFocusChain(Window *client) const = 0; 0117 /** 0118 * @param client The client whose desktop name should be retrieved 0119 * @return The desktop name of the given Window. If the client is 0120 * on all desktops the name of current desktop will be returned. 0121 */ 0122 virtual QString desktopName(Window *client) const = 0; 0123 0124 /** 0125 * whether KWin is currently compositing and it's related features (elevating) can be used 0126 */ 0127 virtual bool isKWinCompositing() const = 0; 0128 0129 /** 0130 * De-/Elevate a client using the compositor (if enabled) 0131 */ 0132 virtual void elevateClient(Window *c, QWindow *tabbox, bool elevate) const = 0; 0133 0134 /** 0135 * Raise a client (w/o activating it) 0136 */ 0137 virtual void raiseClient(Window *c) const = 0; 0138 0139 /** 0140 * @param c The client to be restacked 0141 * @param under The client the other one will be placed below 0142 */ 0143 virtual void restack(Window *c, Window *under) = 0; 0144 0145 /** 0146 * Toggle between ShadeHover and ShadeNormal - not shaded windows are unaffected 0147 * @param c The client to be shaded 0148 * @param b Whether to un- or shade 0149 */ 0150 virtual void shadeClient(Window *c, bool b) const = 0; 0151 0152 virtual void highlightWindows(Window *window = nullptr, QWindow *controller = nullptr) = 0; 0153 0154 /** 0155 * @return The current stacking order of Windows 0156 */ 0157 virtual QList<Window *> stackingOrder() const = 0; 0158 /** 0159 * Determines if given client will be added to the list: 0160 * <UL> 0161 * <LI>if the client wants to have tab focus.</LI> 0162 * <LI>The client won't be added if it has modal dialogs</LI> 0163 * <LI>In that case the modal dialog will be returned if it isn't already 0164 * included</LI> 0165 * <LI>Won't be added if it isn't on active screen when using separate 0166 * screen focus</LI> 0167 * </UL> 0168 * @param client The client to be checked for inclusion 0169 * @param allDesktops Add clients from all desktops or only from current 0170 * @return The client to be included in the list or NULL if it isn't to be included 0171 */ 0172 virtual Window *clientToAddToList(Window *client) const = 0; 0173 /** 0174 * @return The first desktop window in the stacking order. 0175 */ 0176 virtual Window *desktopClient() const = 0; 0177 /** 0178 * Activates the currently selected client and closes the TabBox. 0179 */ 0180 virtual void activateAndClose() = 0; 0181 0182 /** 0183 * @return The currently used TabBoxConfig 0184 */ 0185 const TabBoxConfig &config() const; 0186 /** 0187 * Call this method when you want to change the currently used TabBoxConfig. 0188 * It fires the signal configChanged. 0189 * @param config Updates the currently used TabBoxConfig to config 0190 */ 0191 void setConfig(const TabBoxConfig &config); 0192 0193 /** 0194 * Call this method to show the TabBoxView. Depending on current 0195 * configuration this method might not do anything. 0196 * If highlight windows effect is to be used it will be activated. 0197 * @see TabBoxConfig::isShowTabBox 0198 * @see TabBoxConfig::isHighlightWindows 0199 */ 0200 void show(); 0201 /** 0202 * Hides the TabBoxView if shown. 0203 * Deactivates highlight windows effect if active. 0204 * @see show 0205 */ 0206 void hide(bool abort = false); 0207 0208 /** 0209 * Sets the current model index in the view and updates 0210 * highlight windows if active. 0211 * @param index The current Model index 0212 */ 0213 void setCurrentIndex(const QModelIndex &index); 0214 /** 0215 * @returns the current index 0216 */ 0217 const QModelIndex ¤tIndex() const; 0218 0219 /** 0220 * Retrieves the next or previous item of the current item. 0221 * @param forward next or previous item 0222 * @return The next or previous item. If there is no matching item 0223 * the current item will be returned. 0224 */ 0225 QModelIndex nextPrev(bool forward) const; 0226 0227 /** 0228 * Initializes the model based on the current config. 0229 * This method has to be invoked before showing the TabBox. 0230 * It can also be invoked when clients are added or removed. 0231 * In that case partialReset has to be true. 0232 * 0233 * @param partialReset Keep the currently selected item or regenerate everything 0234 */ 0235 void createModel(bool partialReset = false); 0236 0237 /** 0238 * Handles additional grabbed key events by the TabBox controller. 0239 * @param event The key event which has been grabbed 0240 */ 0241 virtual void grabbedKeyEvent(QKeyEvent *event) const; 0242 /** 0243 * @param pos The position to be tested in global coordinates 0244 * @return True if the view contains the point, otherwise false. 0245 */ 0246 bool containsPos(const QPoint &pos) const; 0247 /** 0248 * @param client The Window whose index should be returned 0249 * @return Returns the ModelIndex of given Window or an invalid ModelIndex 0250 * if the model does not contain the given Window. 0251 * @see ClientModel::index 0252 */ 0253 QModelIndex index(Window *client) const; 0254 /** 0255 * @return Returns the current list of Windows. 0256 * @see ClientModel::clientList 0257 */ 0258 QList<Window *> clientList() const; 0259 /** 0260 * @param index The index of the client to be returned 0261 * @return Returns the Window at given model index. If 0262 * the index is invalid, does not point to a Client or the list 0263 * is empty, NULL will be returned. 0264 */ 0265 Window *client(const QModelIndex &index) const; 0266 /** 0267 * @return The first model index. That is the model index at position 0, 0. 0268 * It is valid, as desktop has at least one desktop and if there are no 0269 * clients an empty item is created. 0270 */ 0271 QModelIndex first() const; 0272 0273 bool eventFilter(QObject *watcher, QEvent *event) override; 0274 0275 /** 0276 * @returns whether the TabBox operates in a no modifier grab mode. 0277 * In this mode a click on an item should directly accept and close the tabbox. 0278 */ 0279 virtual bool noModifierGrab() const = 0; 0280 0281 Q_SIGNALS: 0282 /** 0283 * This signal is fired when the TabBoxConfig changes 0284 * @see setConfig 0285 */ 0286 void configChanged(); 0287 void selectedIndexChanged(); 0288 0289 private Q_SLOTS: 0290 void initHighlightWindows(); 0291 0292 private: 0293 friend class TabBoxHandlerPrivate; 0294 TabBoxHandlerPrivate *d; 0295 }; 0296 0297 /** 0298 * Pointer to the global TabBoxHandler object. 0299 */ 0300 extern TabBoxHandler *tabBox; 0301 0302 } // namespace TabBox 0303 } // namespace KWin