1 | /******************************************************************** |
2 | KWin - the KDE window manager |
3 | This file is part of the KDE project. |
4 | |
5 | Copyright (C) 1999, 2000 Matthias Ettrich <ettrich@kde.org> |
6 | Copyright (C) 2003 Lubos Lunak <l.lunak@kde.org> |
7 | Copyright (C) 2009 Martin Gräßlin <mgraesslin@kde.org> |
8 | |
9 | This program is free software; you can redistribute it and/or modify |
10 | it under the terms of the GNU General Public License as published by |
11 | the Free Software Foundation; either version 2 of the License, or |
12 | (at your option) any later version. |
13 | |
14 | This program is distributed in the hope that it will be useful, |
15 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
17 | GNU General Public License for more details. |
18 | |
19 | You should have received a copy of the GNU General Public License |
20 | along with this program. If not, see <http://www.gnu.org/licenses/>. |
21 | *********************************************************************/ |
22 | |
23 | #ifndef KWIN_TABBOX_H |
24 | #define KWIN_TABBOX_H |
25 | |
26 | #include <QTimer> |
27 | #include <QModelIndex> |
28 | #include <KDE/KShortcut> |
29 | #include "utils.h" |
30 | #include "tabbox/tabboxhandler.h" |
31 | |
32 | class KActionCollection; |
33 | class KConfigGroup; |
34 | class QKeyEvent; |
35 | |
36 | namespace KWin |
37 | { |
38 | |
39 | class Workspace; |
40 | class Client; |
41 | namespace TabBox |
42 | { |
43 | class DesktopChainManager; |
44 | class TabBoxConfig; |
45 | class TabBox; |
46 | class TabBoxHandlerImpl : public TabBoxHandler |
47 | { |
48 | public: |
49 | explicit TabBoxHandlerImpl(TabBox* tabBox); |
50 | virtual ~TabBoxHandlerImpl(); |
51 | |
52 | virtual int activeScreen() const; |
53 | virtual QWeakPointer< TabBoxClient > activeClient() const; |
54 | virtual int currentDesktop() const; |
55 | virtual QString desktopName(TabBoxClient* client) const; |
56 | virtual QString desktopName(int desktop) const; |
57 | virtual bool isKWinCompositing() const; |
58 | virtual QWeakPointer< TabBoxClient > nextClientFocusChain(TabBoxClient* client) const; |
59 | virtual QWeakPointer< TabBoxClient > firstClientFocusChain() const; |
60 | virtual bool isInFocusChain (TabBoxClient* client) const; |
61 | virtual int nextDesktopFocusChain(int desktop) const; |
62 | virtual int numberOfDesktops() const; |
63 | virtual TabBoxClientList stackingOrder() const; |
64 | virtual void elevateClient(TabBoxClient* c, WId tabbox, bool elevate) const; |
65 | virtual void raiseClient(TabBoxClient *client) const; |
66 | virtual void restack(TabBoxClient *c, TabBoxClient *under); |
67 | virtual QWeakPointer< TabBoxClient > clientToAddToList(KWin::TabBox::TabBoxClient* client, int desktop) const; |
68 | virtual QWeakPointer< TabBoxClient > desktopClient() const; |
69 | virtual void activateAndClose(); |
70 | |
71 | private: |
72 | bool checkDesktop(TabBoxClient* client, int desktop) const; |
73 | bool checkActivity(TabBoxClient* client) const; |
74 | bool checkApplications(TabBoxClient* client) const; |
75 | bool checkMinimized(TabBoxClient* client) const; |
76 | bool checkMultiScreen(TabBoxClient* client) const; |
77 | |
78 | TabBox* m_tabBox; |
79 | DesktopChainManager* m_desktopFocusChain; |
80 | }; |
81 | |
82 | class TabBoxClientImpl : public TabBoxClient |
83 | { |
84 | public: |
85 | explicit TabBoxClientImpl(Client *client); |
86 | virtual ~TabBoxClientImpl(); |
87 | |
88 | virtual QString caption() const; |
89 | virtual QPixmap icon(const QSize& size = QSize(32, 32)) const; |
90 | virtual WId window() const; |
91 | virtual bool isMinimized() const; |
92 | virtual int x() const; |
93 | virtual int y() const; |
94 | virtual int width() const; |
95 | virtual int height() const; |
96 | virtual bool isCloseable() const; |
97 | virtual void close(); |
98 | virtual bool isFirstInTabBox() const; |
99 | |
100 | Client* client() const { |
101 | return m_client; |
102 | } |
103 | |
104 | private: |
105 | Client* m_client; |
106 | }; |
107 | |
108 | class TabBox : public QObject |
109 | { |
110 | Q_OBJECT |
111 | Q_CLASSINFO("D-Bus Interface" , "org.kde.kwin" ) |
112 | public: |
113 | ~TabBox(); |
114 | |
115 | Client* currentClient(); |
116 | ClientList currentClientList(); |
117 | int currentDesktop(); |
118 | QList< int > currentDesktopList(); |
119 | |
120 | void setCurrentClient(Client* newClient); |
121 | void setCurrentDesktop(int newDesktop); |
122 | |
123 | void setMode(TabBoxMode mode); |
124 | TabBoxMode mode() const { |
125 | return m_tabBoxMode; |
126 | } |
127 | |
128 | void reset(bool partial_reset = false); |
129 | void nextPrev(bool next = true); |
130 | |
131 | void delayedShow(); |
132 | void hide(bool abort = false); |
133 | |
134 | /*! |
135 | Increase the reference count, preventing the default tabbox from showing. |
136 | |
137 | \sa unreference(), isDisplayed() |
138 | */ |
139 | void reference() { |
140 | ++m_displayRefcount; |
141 | } |
142 | /*! |
143 | Decrease the reference count. Only when the reference count is 0 will |
144 | the default tab box be shown. |
145 | */ |
146 | void unreference() { |
147 | --m_displayRefcount; |
148 | } |
149 | /*! |
150 | Returns whether the tab box is being displayed, either natively or by an |
151 | effect. |
152 | |
153 | \sa reference(), unreference() |
154 | */ |
155 | bool isDisplayed() const { |
156 | return m_displayRefcount > 0; |
157 | }; |
158 | |
159 | bool handleMouseEvent(XEvent* e); |
160 | void grabbedKeyEvent(QKeyEvent* event); |
161 | |
162 | bool isGrabbed() const { |
163 | return m_tabGrab || m_desktopGrab; |
164 | }; |
165 | |
166 | void initShortcuts(KActionCollection* keys); |
167 | |
168 | Client* nextClientStatic(Client*) const; |
169 | Client* previousClientStatic(Client*) const; |
170 | int nextDesktopStatic(int iDesktop) const; |
171 | int previousDesktopStatic(int iDesktop) const; |
172 | void keyPress(int key); |
173 | void keyRelease(const XKeyEvent& ev); |
174 | |
175 | static TabBox *self(); |
176 | static TabBox *create(QObject *parent); |
177 | |
178 | public slots: |
179 | void show(); |
180 | /** |
181 | * Only for DBus Interface to start primary KDE Walk through windows. |
182 | * @param modal Whether the TabBox should grab keyboard and mouse, that is go into modal |
183 | * mode or whether the TabBox is controlled externally (e.g. through an effect). |
184 | * @param layout The name of the layout to use, if null string (default) the configured layout is used |
185 | **/ |
186 | Q_SCRIPTABLE void open(bool modal = true, const QString &layout = QString()); |
187 | /** |
188 | * Opens the TabBox view embedded on a different window. This implies non-modal mode. |
189 | * The geometry of the TabBox is determined by offset, size and the alignment flags. |
190 | * If the alignment flags are set to center the view scales with the container. That is if |
191 | * the window where the TabBox is embedded onto resizes, the TabBox resizes, too. |
192 | * The alignment in combination with the offset determines to what border the TabBox is snapped. |
193 | * E.g. if horizontal alignment is right the offset is interpreted as the offset between right |
194 | * corner of TabBox view and the container view. When the container changes its geometry this |
195 | * offset is kept. So the offset on the left side would increase. |
196 | * @param wid The window Id the TabBox should be embedded onto |
197 | * @param offset The offset to one of the size borders |
198 | * @param size The size of the TabBox. To use the same size as the container, set alignment to center |
199 | * @param horizontalAlignment Either Qt::AlignLeft, Qt::AlignHCenter or Qt::AlignRight |
200 | * @param verticalAlignment Either Qt::AlignTop, Qt::AlignVCenter or Qt::AlignBottom |
201 | * @param layout The name of the layout to use, if null string (default) the configured layout is used |
202 | **/ |
203 | Q_SCRIPTABLE void openEmbedded(qulonglong wid, QPoint offset, QSize size, int horizontalAlignment, int verticalAlignment, const QString &layout = QString()); |
204 | Q_SCRIPTABLE void close(bool abort = false); |
205 | Q_SCRIPTABLE void accept(); |
206 | Q_SCRIPTABLE void reject(); |
207 | void slotWalkThroughDesktops(); |
208 | void slotWalkBackThroughDesktops(); |
209 | void slotWalkThroughDesktopList(); |
210 | void slotWalkBackThroughDesktopList(); |
211 | void slotWalkThroughWindows(); |
212 | void slotWalkBackThroughWindows(); |
213 | void slotWalkThroughWindowsAlternative(); |
214 | void slotWalkBackThroughWindowsAlternative(); |
215 | void slotWalkThroughCurrentAppWindows(); |
216 | void slotWalkBackThroughCurrentAppWindows(); |
217 | void slotWalkThroughCurrentAppWindowsAlternative(); |
218 | void slotWalkBackThroughCurrentAppWindowsAlternative(); |
219 | |
220 | void slotWalkThroughDesktopsKeyChanged(const QKeySequence& seq); |
221 | void slotWalkBackThroughDesktopsKeyChanged(const QKeySequence& seq); |
222 | void slotWalkThroughDesktopListKeyChanged(const QKeySequence& seq); |
223 | void slotWalkBackThroughDesktopListKeyChanged(const QKeySequence& seq); |
224 | void slotWalkThroughWindowsKeyChanged(const QKeySequence& seq); |
225 | void slotWalkBackThroughWindowsKeyChanged(const QKeySequence& seq); |
226 | void slotMoveToTabLeftKeyChanged(const QKeySequence& seq); |
227 | void slotMoveToTabRightKeyChanged(const QKeySequence& seq); |
228 | void slotWalkThroughWindowsAlternativeKeyChanged(const QKeySequence& seq); |
229 | void slotWalkBackThroughWindowsAlternativeKeyChanged(const QKeySequence& seq); |
230 | void slotWalkThroughCurrentAppWindowsKeyChanged(const QKeySequence& seq); |
231 | void slotWalkBackThroughCurrentAppWindowsKeyChanged(const QKeySequence& seq); |
232 | void slotWalkThroughCurrentAppWindowsAlternativeKeyChanged(const QKeySequence& seq); |
233 | void slotWalkBackThroughCurrentAppWindowsAlternativeKeyChanged(const QKeySequence& seq); |
234 | |
235 | void handlerReady(); |
236 | |
237 | bool toggle(ElectricBorder eb); |
238 | |
239 | signals: |
240 | void tabBoxAdded(int); |
241 | Q_SCRIPTABLE void tabBoxClosed(); |
242 | Q_SCRIPTABLE void itemSelected(); |
243 | void tabBoxUpdated(); |
244 | void tabBoxKeyEvent(QKeyEvent*); |
245 | |
246 | private: |
247 | explicit TabBox(QObject *parent); |
248 | void setCurrentIndex(QModelIndex index, bool notifyEffects = true); |
249 | void loadConfig(const KConfigGroup& config, TabBoxConfig& tabBoxConfig); |
250 | |
251 | bool startKDEWalkThroughWindows(TabBoxMode mode); // TabBoxWindowsMode | TabBoxWindowsAlternativeMode |
252 | bool startWalkThroughDesktops(TabBoxMode mode); // TabBoxDesktopMode | TabBoxDesktopListMode |
253 | bool startWalkThroughDesktops(); |
254 | bool startWalkThroughDesktopList(); |
255 | void navigatingThroughWindows(bool forward, const KShortcut& shortcut, TabBoxMode mode); // TabBoxWindowsMode | TabBoxWindowsAlternativeMode |
256 | void KDEWalkThroughWindows(bool forward); |
257 | void CDEWalkThroughWindows(bool forward); |
258 | void walkThroughDesktops(bool forward); |
259 | void KDEOneStepThroughWindows(bool forward, TabBoxMode mode); // TabBoxWindowsMode | TabBoxWindowsAlternativeMode |
260 | void oneStepThroughDesktops(bool forward, TabBoxMode mode); // TabBoxDesktopMode | TabBoxDesktopListMode |
261 | void oneStepThroughDesktops(bool forward); |
262 | void oneStepThroughDesktopList(bool forward); |
263 | bool establishTabBoxGrab(); |
264 | void removeTabBoxGrab(); |
265 | void modalActionsSwitch(bool enabled); |
266 | |
267 | private Q_SLOTS: |
268 | void reconfigure(); |
269 | |
270 | private: |
271 | TabBoxMode m_tabBoxMode; |
272 | TabBoxHandlerImpl* m_tabBox; |
273 | bool m_delayShow; |
274 | int m_delayShowTime; |
275 | |
276 | QTimer m_delayedShowTimer; |
277 | int m_displayRefcount; |
278 | |
279 | TabBoxConfig m_defaultConfig; |
280 | TabBoxConfig m_alternativeConfig; |
281 | TabBoxConfig m_defaultCurrentApplicationConfig; |
282 | TabBoxConfig m_alternativeCurrentApplicationConfig; |
283 | TabBoxConfig m_desktopConfig; |
284 | TabBoxConfig m_desktopListConfig; |
285 | // false if an effect has referenced the tabbox |
286 | // true if tabbox is active (independent on showTabbox setting) |
287 | bool m_isShown; |
288 | bool m_desktopGrab; |
289 | bool m_tabGrab; |
290 | // true if tabbox is in modal mode which does not require holding a modifier |
291 | bool m_noModifierGrab; |
292 | KShortcut m_cutWalkThroughDesktops, m_cutWalkThroughDesktopsReverse; |
293 | KShortcut m_cutWalkThroughDesktopList, m_cutWalkThroughDesktopListReverse; |
294 | KShortcut m_cutWalkThroughWindows, m_cutWalkThroughWindowsReverse; |
295 | KShortcut m_cutWalkThroughGroupWindows, m_cutWalkThroughGroupWindowsReverse; |
296 | KShortcut m_cutWalkThroughWindowsAlternative, m_cutWalkThroughWindowsAlternativeReverse; |
297 | KShortcut m_cutWalkThroughCurrentAppWindows, m_cutWalkThroughCurrentAppWindowsReverse; |
298 | KShortcut m_cutWalkThroughCurrentAppWindowsAlternative, m_cutWalkThroughCurrentAppWindowsAlternativeReverse; |
299 | bool m_forcedGlobalMouseGrab; |
300 | bool m_ready; // indicates whether the config is completely loaded |
301 | QList<ElectricBorder> m_borderActivate, m_borderAlternativeActivate; |
302 | |
303 | static TabBox *s_self; |
304 | }; |
305 | |
306 | inline |
307 | TabBox *TabBox::self() |
308 | { |
309 | return s_self; |
310 | } |
311 | |
312 | } // namespace TabBox |
313 | } // namespace |
314 | #endif |
315 | |