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>
7
8This program is free software; you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
10the Free Software Foundation; either version 2 of the License, or
11(at your option) any later version.
12
13This program is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19along with this program. If not, see <http://www.gnu.org/licenses/>.
20*********************************************************************/
21
22#ifndef KWIN_UTILS_H
23#define KWIN_UTILS_H
24
25// cmake stuff
26#include <config-X11.h>
27#include <config-kwin.h>
28#include <kwinconfig.h>
29// kwin
30#include <kwinglobals.h>
31// KDE
32#include <KDE/NET>
33// Qt
34#include <QList>
35#include <QPoint>
36#include <QRect>
37#include <QScopedPointer>
38// X
39#include <X11/Xlib.h>
40#include <fixx11h.h>
41// system
42#include <limits.h>
43
44namespace KWin
45{
46
47// window types that are supported as normal windows (i.e. KWin actually manages them)
48const int SUPPORTED_MANAGED_WINDOW_TYPES_MASK = NET::NormalMask | NET::DesktopMask | NET::DockMask
49 | NET::ToolbarMask | NET::MenuMask | NET::DialogMask /*| NET::OverrideMask*/ | NET::TopMenuMask
50 | NET::UtilityMask | NET::SplashMask;
51// window types that are supported as unmanaged (mainly for compositing)
52const int SUPPORTED_UNMANAGED_WINDOW_TYPES_MASK = NET::NormalMask | NET::DesktopMask | NET::DockMask
53 | NET::ToolbarMask | NET::MenuMask | NET::DialogMask /*| NET::OverrideMask*/ | NET::TopMenuMask
54 | NET::UtilityMask | NET::SplashMask | NET::DropdownMenuMask | NET::PopupMenuMask
55 | NET::TooltipMask | NET::NotificationMask | NET::ComboBoxMask | NET::DNDIconMask;
56
57const long ClientWinMask = XCB_EVENT_MASK_KEY_PRESS | XCB_EVENT_MASK_KEY_RELEASE |
58 XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_BUTTON_RELEASE |
59 XCB_EVENT_MASK_KEYMAP_STATE |
60 XCB_EVENT_MASK_BUTTON_MOTION |
61 XCB_EVENT_MASK_POINTER_MOTION | // need this, too!
62 XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_LEAVE_WINDOW |
63 XCB_EVENT_MASK_FOCUS_CHANGE |
64 XCB_EVENT_MASK_EXPOSURE |
65 XCB_EVENT_MASK_STRUCTURE_NOTIFY |
66 XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT;
67
68const QPoint invalidPoint(INT_MIN, INT_MIN);
69
70class Toplevel;
71class Client;
72class Unmanaged;
73class Deleted;
74class Group;
75class Options;
76
77typedef QList< Toplevel* > ToplevelList;
78typedef QList< Client* > ClientList;
79typedef QList< const Client* > ConstClientList;
80typedef QList< Unmanaged* > UnmanagedList;
81typedef QList< Deleted* > DeletedList;
82
83typedef QList< Group* > GroupList;
84
85extern Options* options;
86
87enum Layer {
88 UnknownLayer = -1,
89 FirstLayer = 0,
90 DesktopLayer = FirstLayer,
91 BelowLayer,
92 NormalLayer,
93 DockLayer,
94 AboveLayer,
95 ActiveLayer, // active fullscreen, or active dialog
96 UnmanagedLayer, // layer for override redirect windows.
97 NumLayers // number of layers, must be last
98};
99
100// yes, I know this is not 100% like standard operator++
101inline void operator++(Layer& lay)
102{
103 lay = static_cast< Layer >(lay + 1);
104}
105
106// for Client::takeActivity()
107enum ActivityFlags {
108 ActivityFocus = 1 << 0, // focus the window
109 ActivityFocusForce = 1 << 1, // focus even if Dock etc.
110 ActivityRaise = 1 << 2 // raise the window
111};
112
113enum StrutArea {
114 StrutAreaInvalid = 0, // Null
115 StrutAreaTop = 1 << 0,
116 StrutAreaRight = 1 << 1,
117 StrutAreaBottom = 1 << 2,
118 StrutAreaLeft = 1 << 3,
119 StrutAreaAll = StrutAreaTop | StrutAreaRight | StrutAreaBottom | StrutAreaLeft
120};
121Q_DECLARE_FLAGS(StrutAreas, StrutArea)
122
123class StrutRect : public QRect
124{
125public:
126 explicit StrutRect(QRect rect = QRect(), StrutArea area = StrutAreaInvalid);
127 StrutRect(const StrutRect& other);
128 inline StrutArea area() const {
129 return m_area;
130 };
131private:
132 StrutArea m_area;
133};
134typedef QVector<StrutRect> StrutRects;
135
136// some enums to have more readable code, instead of using bools
137enum ForceGeometry_t { NormalGeometrySet, ForceGeometrySet };
138
139
140
141enum ShadeMode {
142 ShadeNone, // not shaded
143 ShadeNormal, // normally shaded - isShade() is true only here
144 ShadeHover, // "shaded", but visible due to hover unshade
145 ShadeActivated // "shaded", but visible due to alt+tab to the window
146};
147
148// Whether to keep all windows mapped when compositing (i.e. whether to have
149// actively updated window pixmaps).
150enum HiddenPreviews {
151 // The normal mode with regard to mapped windows. Hidden (minimized, etc.)
152 // and windows on inactive virtual desktops are not mapped, their pixmaps
153 // are only their icons.
154 HiddenPreviewsNever,
155 // Like normal mode, but shown windows (i.e. on inactive virtual desktops)
156 // are kept mapped, only hidden windows are unmapped.
157 HiddenPreviewsShown,
158 // All windows are kept mapped regardless of their state.
159 HiddenPreviewsAlways
160};
161
162class Motif
163{
164public:
165 // Read a window's current settings from its _MOTIF_WM_HINTS
166 // property. If it explicitly requests that decorations be shown
167 // or hidden, 'got_noborder' is set to true and 'noborder' is set
168 // appropriately.
169 static void readFlags(xcb_window_t w, bool& got_noborder, bool& noborder,
170 bool& resize, bool& move, bool& minimize, bool& maximize,
171 bool& close);
172 struct MwmHints {
173 ulong flags;
174 ulong functions;
175 ulong decorations;
176 long input_mode;
177 ulong status;
178 };
179 enum {
180 MWM_HINTS_FUNCTIONS = (1L << 0),
181 MWM_HINTS_DECORATIONS = (1L << 1),
182
183 MWM_FUNC_ALL = (1L << 0),
184 MWM_FUNC_RESIZE = (1L << 1),
185 MWM_FUNC_MOVE = (1L << 2),
186 MWM_FUNC_MINIMIZE = (1L << 3),
187 MWM_FUNC_MAXIMIZE = (1L << 4),
188 MWM_FUNC_CLOSE = (1L << 5)
189 };
190};
191
192// Class which saves original value of the variable, assigns the new value
193// to it, and in the destructor restores the value.
194// Used in Client::isMaximizable() and so on.
195// It also casts away contness and generally this looks like a hack.
196template< typename T >
197class TemporaryAssign
198{
199public:
200 TemporaryAssign(const T& var, const T& value)
201 : variable(var), orig(var) {
202 const_cast< T& >(variable) = value;
203 }
204 ~TemporaryAssign() {
205 const_cast< T& >(variable) = orig;
206 }
207private:
208 const T& variable;
209 T orig;
210};
211
212template <typename T>
213class ScopedCPointer : public QScopedPointer<T, QScopedPointerPodDeleter>
214{
215public:
216 ScopedCPointer(T *p = 0) : QScopedPointer<T, QScopedPointerPodDeleter>(p) {}
217};
218
219QByteArray getStringProperty(xcb_window_t w, xcb_atom_t prop, char separator = 0);
220void updateXTime();
221void grabXServer();
222void ungrabXServer();
223bool grabbedXServer();
224bool grabXKeyboard(xcb_window_t w = rootWindow());
225void ungrabXKeyboard();
226
227/**
228 * Small helper class which performs @link grabXServer in the ctor and
229 * @link ungrabXServer in the dtor. Use this class to ensure that grab and
230 * ungrab are matched.
231 **/
232class XServerGrabber
233{
234public:
235 XServerGrabber() {
236 grabXServer();
237 }
238 ~XServerGrabber() {
239 ungrabXServer();
240 }
241};
242
243// the docs say it's UrgencyHint, but it's often #defined as XUrgencyHint
244#ifndef UrgencyHint
245#define UrgencyHint XUrgencyHint
246#endif
247
248// for STL-like algo's
249#define KWIN_CHECK_PREDICATE( name, cls, check ) \
250 struct name \
251 { \
252 inline bool operator()( const cls* cl ) { return check; } \
253 }
254
255#define KWIN_COMPARE_PREDICATE( name, cls, type, check ) \
256 struct name \
257 { \
258 typedef type type_helper; /* in order to work also with type being 'const Client*' etc. */ \
259 inline name( const type_helper& compare_value ) : value( compare_value ) {} \
260 inline bool operator()( const cls* cl ) { return check; } \
261 const type_helper& value; \
262 }
263
264#define KWIN_PROCEDURE( name, cls, action ) \
265 struct name \
266 { \
267 inline void operator()( cls* cl ) { action; } \
268 }
269
270KWIN_CHECK_PREDICATE(TruePredicate, Client, cl == cl /*true, avoid warning about 'cl' */);
271
272template< typename T >
273Client* findClientInList(const ClientList& list, T predicate)
274{
275 for (ClientList::ConstIterator it = list.begin(); it != list.end(); ++it) {
276 if (predicate(const_cast< const Client* >(*it)))
277 return *it;
278 }
279 return NULL;
280}
281
282template< typename T >
283Unmanaged* findUnmanagedInList(const UnmanagedList& list, T predicate)
284{
285 for (UnmanagedList::ConstIterator it = list.begin(); it != list.end(); ++it) {
286 if (predicate(const_cast< const Unmanaged* >(*it)))
287 return *it;
288 }
289 return NULL;
290}
291
292inline
293int timestampCompare(xcb_timestamp_t time1, xcb_timestamp_t time2) // like strcmp()
294{
295 return NET::timestampCompare(time1, time2);
296}
297
298inline
299xcb_timestamp_t timestampDiff(xcb_timestamp_t time1, xcb_timestamp_t time2) // returns time2 - time1
300{
301 return NET::timestampDiff(time1, time2);
302}
303
304QPoint cursorPos();
305
306// converting between X11 mouse/keyboard state mask and Qt button/keyboard states
307int qtToX11Button(Qt::MouseButton button);
308Qt::MouseButton x11ToQtMouseButton(int button);
309int qtToX11State(Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers);
310Qt::MouseButtons x11ToQtMouseButtons(int state);
311Qt::KeyboardModifiers x11ToQtKeyboardModifiers(int state);
312
313void checkNonExistentClients();
314
315} // namespace
316
317// Must be outside namespace
318Q_DECLARE_OPERATORS_FOR_FLAGS(KWin::StrutAreas)
319
320#endif
321