1/********************************************************************
2 KWin - the KDE window manager
3 This file is part of the KDE project.
4
5Copyright (C) 1999, 2000 Matthias Ettrich <ettrich@kde.org>
6Copyright (C) 2003 Lubos Lunak <l.lunak@kde.org>
7Copyright (C) 2009 Martin Gräßlin <mgraesslin@kde.org>
8
9This program is free software; you can redistribute it and/or modify
10it under the terms of the GNU General Public License as published by
11the Free Software Foundation; either version 2 of the License, or
12(at your option) any later version.
13
14This program is distributed in the hope that it will be useful,
15but WITHOUT ANY WARRANTY; without even the implied warranty of
16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17GNU General Public License for more details.
18
19You should have received a copy of the GNU General Public License
20along 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
32class KActionCollection;
33class KConfigGroup;
34class QKeyEvent;
35
36namespace KWin
37{
38
39class Workspace;
40class Client;
41namespace TabBox
42{
43class DesktopChainManager;
44class TabBoxConfig;
45class TabBox;
46class TabBoxHandlerImpl : public TabBoxHandler
47{
48public:
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
71private:
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
82class TabBoxClientImpl : public TabBoxClient
83{
84public:
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
104private:
105 Client* m_client;
106};
107
108class TabBox : public QObject
109{
110 Q_OBJECT
111 Q_CLASSINFO("D-Bus Interface", "org.kde.kwin")
112public:
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
178public 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
239signals:
240 void tabBoxAdded(int);
241 Q_SCRIPTABLE void tabBoxClosed();
242 Q_SCRIPTABLE void itemSelected();
243 void tabBoxUpdated();
244 void tabBoxKeyEvent(QKeyEvent*);
245
246private:
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
267private Q_SLOTS:
268 void reconfigure();
269
270private:
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
306inline
307TabBox *TabBox::self()
308{
309 return s_self;
310}
311
312} // namespace TabBox
313} // namespace
314#endif
315