version bump
[blackbox.git] / src / Window.hh
blob312eb2fc883237893665b0fdcb4d145164e1ac80
1 // -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
2 // Window.hh for Blackbox - an X11 Window manager
3 // Copyright (c) 2001 - 2005 Sean 'Shaleh' Perry <shaleh@debian.org>
4 // Copyright (c) 1997 - 2000, 2002 - 2005
5 // Bradley T Hughes <bhughes at trolltech.com>
6 //
7 // Permission is hereby granted, free of charge, to any person obtaining a
8 // copy of this software and associated documentation files (the "Software"),
9 // to deal in the Software without restriction, including without limitation
10 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 // and/or sell copies of the Software, and to permit persons to whom the
12 // Software is furnished to do so, subject to the following conditions:
14 // The above copyright notice and this permission notice shall be included in
15 // all copies or substantial portions of the Software.
17 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23 // DEALINGS IN THE SOFTWARE.
25 #ifndef __Window_hh
26 #define __Window_hh
28 #include "BlackboxResource.hh"
29 #include "Screen.hh"
31 #include <EWMH.hh>
34 enum WindowType {
35 WindowTypeNormal,
36 WindowTypeDialog,
37 WindowTypeDesktop,
38 WindowTypeDock,
39 WindowTypeMenu,
40 WindowTypeSplash,
41 WindowTypeToolbar,
42 WindowTypeUtility
45 enum WindowFunction {
46 WindowFunctionResize = 1<<0,
47 WindowFunctionMove = 1<<1,
48 WindowFunctionShade = 1<<2,
49 WindowFunctionIconify = 1<<3,
50 WindowFunctionMaximize = 1<<4,
51 WindowFunctionClose = 1<<5,
52 WindowFunctionChangeWorkspace = 1<<6,
53 WindowFunctionChangeLayer = 1<<7,
54 WindowFunctionFullScreen = 1<<8,
55 NoWindowFunctions = 0,
56 AllWindowFunctions = (WindowFunctionResize |
57 WindowFunctionMove |
58 WindowFunctionShade |
59 WindowFunctionIconify |
60 WindowFunctionMaximize |
61 WindowFunctionClose |
62 WindowFunctionChangeWorkspace |
63 WindowFunctionChangeLayer |
64 WindowFunctionFullScreen)
66 typedef unsigned short WindowFunctionFlags;
68 enum WindowDecoration {
69 WindowDecorationTitlebar = 1<<0,
70 WindowDecorationHandle = 1<<1,
71 WindowDecorationGrip = 1<<2,
72 WindowDecorationBorder = 1<<3,
73 WindowDecorationIconify = 1<<4,
74 WindowDecorationMaximize = 1<<5,
75 WindowDecorationClose = 1<<6,
76 NoWindowDecorations = 0,
77 AllWindowDecorations = (WindowDecorationTitlebar |
78 WindowDecorationHandle |
79 WindowDecorationGrip |
80 WindowDecorationBorder |
81 WindowDecorationIconify |
82 WindowDecorationMaximize |
83 WindowDecorationClose)
85 typedef unsigned char WindowDecorationFlags;
87 struct EWMH {
88 WindowType window_type;
89 unsigned int workspace;
90 unsigned int modal : 1;
91 unsigned int maxv : 1;
92 unsigned int maxh : 1;
93 unsigned int shaded : 1;
94 unsigned int skip_taskbar : 1;
95 unsigned int skip_pager : 1;
96 unsigned int hidden : 1;
97 unsigned int fullscreen : 1;
98 unsigned int above : 1;
99 unsigned int below : 1;
101 struct MotifHints {
102 WindowDecorationFlags decorations;
103 WindowFunctionFlags functions;
105 struct WMHints {
106 bool accept_focus;
107 Window window_group;
108 unsigned long initial_state;
110 struct WMNormalHints {
111 long flags;
112 unsigned int min_width, min_height;
113 unsigned int max_width, max_height;
114 unsigned int width_inc, height_inc;
115 unsigned int min_aspect_x, min_aspect_y;
116 unsigned int max_aspect_x, max_aspect_y;
117 unsigned int base_width, base_height;
118 unsigned int win_gravity;
120 struct WMProtocols {
121 unsigned int wm_delete_window : 1;
122 unsigned int wm_take_focus : 1;
126 class BlackboxWindow : public StackEntity, public bt::TimeoutHandler,
127 public bt::EventHandler, public bt::NoCopy {
128 Blackbox *blackbox;
129 BScreen *_screen;
130 bt::Timer *timer;
132 Time lastButtonPressTime; // used for double clicks, when were we clicked
134 unsigned int window_number;
136 struct ClientState {
137 unsigned int visible : 1; // is visible?
138 unsigned int iconic : 1; // is iconified?
139 unsigned int moving : 1; // is moving?
140 unsigned int resizing : 1; // is resizing?
141 unsigned int focused : 1; // has focus?
142 unsigned int shaped : 1; // does the frame use the shape extension?
145 struct _client {
146 Window window; // the client's window
147 Colormap colormap;
148 Window transient_for; // which window are we a transient for?
149 BlackboxWindowList transientList; // which windows are our transients?
151 bt::ustring title, visible_title, icon_title;
153 bt::Rect rect, premax;
155 int old_bw; // client's borderwidth
157 unsigned long current_state;
159 bt::EWMH::Strut *strut;
161 WindowFunctionFlags functions;
162 WindowDecorationFlags decorations;
164 ClientState state;
166 EWMH ewmh;
167 MotifHints motif;
168 WMHints wmhints;
169 WMNormalHints wmnormal;
170 WMProtocols wmprotocols;
171 } client;
174 * client window = the application's window
175 * frame window = the window drawn around the outside of the client window
176 * by the window manager which contains items like the
177 * titlebar and close button
178 * title = the titlebar drawn above the client window, it displays the
179 * window's name and any buttons for interacting with the window,
180 * such as iconify, maximize, and close
181 * label = the window in the titlebar where the title is drawn
182 * buttons = maximize, iconify, close
183 * handle = the bar drawn at the bottom of the window, which contains the
184 * left and right grips used for resizing the window
185 * grips = the smaller reactangles in the handle, one of each side of it.
186 * When clicked and dragged, these resize the window interactively
187 * border = the line drawn around the outside edge of the frame window,
188 * between the title, the bordered client window, and the handle.
189 * Also drawn between the grips and the handle
192 struct _frame {
193 // u -> unfocused, f -> has focus
194 Pixmap ulabel, flabel, utitle, ftitle, uhandle, fhandle,
195 ubutton, fbutton, pbutton, ugrip, fgrip;
197 Window window, // the frame
198 plate, // holds the client
199 title,
200 label,
201 handle,
202 close_button, iconify_button, maximize_button,
203 right_grip, left_grip;
205 // frame geometry
206 bt::Rect rect;
208 // used during move/resize
209 bt::Rect changing;
210 int corner;
213 * margins between the frame and client, this has nothing to do
214 * with EWMH, it is simply code reuse for similar functionality
216 bt::EWMH::Strut margin;
217 int grab_x, grab_y; // where was the window when it was grabbed?
219 unsigned int label_w; // width of the label
220 } frame;
222 Window createToplevelWindow();
223 Window createChildWindow(Window parent, unsigned long event_mask,
224 Cursor = None);
226 void associateClientWindow(void);
228 void decorate(void);
230 void positionButtons(bool redecorate_label = false);
231 void positionWindows(void);
233 void createTitlebar(void);
234 void destroyTitlebar(void);
235 void createHandle(void);
236 void destroyHandle(void);
237 void createGrips(void);
238 void destroyGrips(void);
239 void createIconifyButton(void);
240 void destroyIconifyButton(void);
241 void createMaximizeButton(void);
242 void destroyMaximizeButton(void);
243 void createCloseButton(void);
244 void destroyCloseButton(void);
246 void redrawWindowFrame(void) const;
247 void redrawTitle(void) const;
248 void redrawLabel(void) const;
249 void redrawAllButtons(void) const;
250 void redrawCloseButton(bool pressed = false) const;
251 void redrawIconifyButton(bool pressed = false) const;
252 void redrawMaximizeButton(bool pressed = false) const;
253 void redrawHandle(void) const;
254 void redrawGrips(void) const;
256 void setState(unsigned long new_state);
257 void updateEWMHState();
258 void updateEWMHAllowedActions();
260 void startMove();
261 void snapAdjust(int *x, int *y);
262 void continueMove(int x_root, int y_root);
263 void finishMove();
265 void startResize(Window window);
266 void continueResize(int x_root, int y_root);
267 void finishResize();
269 void showGeometry(const bt::Rect &r) const;
271 public:
272 BlackboxWindow(Blackbox *b, Window w, BScreen *s);
273 virtual ~BlackboxWindow(void);
275 inline bool isTransient(void) const
276 { return client.transient_for != 0; }
277 inline bool isGroupTransient(void) const
278 { return (client.transient_for != 0
279 && client.transient_for == client.wmhints.window_group); }
280 inline bool isModal(void) const
281 { return client.ewmh.modal; }
283 inline WindowType windowType(void) const
284 { return client.ewmh.window_type; }
286 inline bool hasWindowFunction(WindowFunction function) const
287 { return client.functions & function; }
288 inline bool hasWindowDecoration(WindowDecoration decoration) const
289 { return client.decorations & decoration; }
291 // ordered newest to oldest
292 inline const BlackboxWindowList &transients(void) const
293 { return client.transientList; }
295 void addTransient(BlackboxWindow *win);
296 void removeTransient(BlackboxWindow *win);
298 BlackboxWindow *findTransientFor(void) const;
299 BlackboxWindow *findNonTransientParent(void) const;
300 BlackboxWindowList buildFullTransientList(void) const;
302 BWindowGroup *findWindowGroup(void) const;
304 inline BScreen *screen(void) const
305 { return _screen; }
307 // StackEntity interface
308 inline Window windowID(void) const
309 { return frame.window; }
311 inline Window frameWindow(void) const
312 { return frame.window; }
313 inline Window clientWindow(void) const
314 { return client.window; }
316 inline const bt::ustring &title(void) const
317 { return client.title; }
318 inline const bt::ustring &iconTitle(void) const
319 { return client.icon_title.empty() ? client.title : client.icon_title; }
321 inline unsigned int workspace(void) const
322 { return client.ewmh.workspace; }
323 void setWorkspace(unsigned int new_workspace);
325 enum ChangeWorkspaceOption {
326 StayOnCurrentWorkspace,
327 SwitchToNewWorkspace
329 void changeWorkspace(unsigned int new_workspace,
330 ChangeWorkspaceOption how = StayOnCurrentWorkspace);
332 void changeLayer(StackingList::Layer new_layer);
334 inline unsigned int windowNumber(void) const
335 { return window_number; }
336 inline void setWindowNumber(int n)
337 { window_number = n; }
339 inline const bt::Rect &frameRect(void) const
340 { return frame.rect; }
341 inline const bt::Rect &clientRect(void) const
342 { return client.rect; }
344 const WMHints &wmHints(void) const
345 { return client.wmhints; }
346 const WMNormalHints &wmNormalHints(void) const
347 { return client.wmnormal; }
348 const WMProtocols &wmProtocols(void) const
349 { return client.wmprotocols; }
351 unsigned long currentState(void) const
352 { return client.current_state; }
354 inline bool isFocused(void) const
355 { return client.state.focused; }
356 void setFocused(bool focused);
357 bool setInputFocus(void);
359 inline bool isVisible(void) const
360 { return client.state.visible; }
361 void show(void);
362 void hide(void);
363 void close(void);
364 void activate(void);
366 inline bool isShaded(void) const
367 { return client.ewmh.shaded; }
368 void setShaded(bool shaded);
370 inline bool isIconic(void) const
371 { return client.state.iconic; }
372 void iconify(void); // call show() to deiconify
374 inline bool isMaximized(void) const
375 { return client.ewmh.maxh || client.ewmh.maxv; }
376 // ### change to setMaximized()?
377 void maximize(unsigned int button);
378 void remaximize(void);
380 inline bool isFullScreen(void) const
381 { return client.ewmh.fullscreen; }
382 void setFullScreen(bool b);
384 void reconfigure(void);
385 void grabButtons(void);
386 void ungrabButtons(void);
387 void restore(void);
388 void configure(int dx, int dy, unsigned int dw, unsigned int dh);
389 inline void configure(const bt::Rect &r)
390 { configure(r.x(), r.y(), r.width(), r.height()); }
392 void clientMessageEvent(const XClientMessageEvent * const ce);
393 void buttonPressEvent(const XButtonEvent * const be);
394 void buttonReleaseEvent(const XButtonEvent * const re);
395 void motionNotifyEvent(const XMotionEvent * const me);
396 void destroyNotifyEvent(const XDestroyWindowEvent * const /*unused*/);
397 void unmapNotifyEvent(const XUnmapEvent * const /*unused*/);
398 void reparentNotifyEvent(const XReparentEvent * const /*unused*/);
399 void propertyNotifyEvent(const XPropertyEvent * const pe);
400 void exposeEvent(const XExposeEvent * const ee);
401 void configureRequestEvent(const XConfigureRequestEvent * const cr);
402 void enterNotifyEvent(const XCrossingEvent * const ce);
403 void leaveNotifyEvent(const XCrossingEvent * const /*unused*/);
405 #ifdef SHAPE
406 void configureShape(void);
407 void shapeEvent(const XEvent * const /*unused*/);
408 #endif // SHAPE
410 virtual void timeout(bt::Timer *);
413 #endif // __Window_hh