summaryrefslogtreecommitdiff
path: root/src/client.h
blob: 7777d16ad36607b4ad1721fdec17b5b46107f5ad (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
/*      $Id$
 
        This program is free software; you can redistribute it and/or modify
        it under the terms of the GNU General Public License as published by
        the Free Software Foundation; either version 2, or (at your option)
        any later version.
 
        This program is distributed in the hope that it will be useful,
        but WITHOUT ANY WARRANTY; without even the implied warranty of
        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
        GNU General Public License for more details.
 
        You should have received a copy of the GNU General Public License
        along with this program; if not, write to the Free Software
        Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
        oroborus - (c) 2001 Ken Lynch
        xfwm4    - (c) 2002-2006 Olivier Fourdan
 
 */

#ifdef HAVE_CONFIG_H
#  include "config.h"
#endif

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <signal.h>
#include <unistd.h>
#include <sys/types.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xmd.h>
#include <X11/cursorfont.h>
#include <X11/extensions/shape.h>

#include <glib.h>
#include <gtk/gtk.h>
#include "screen.h"
#include "misc.h"
#include "hints.h"
#include "keyboard.h"
#include "mypixmap.h"
#include "mywindow.h"
#include "settings.h"

#ifndef INC_CLIENT_H
#define INC_CLIENT_H

#define APPLY                           1
#define REMOVE                          -1

#define PLACEMENT_MOUSE                 0
#define PLACEMENT_ROOT                  1

#define NO_CFG_FLAG                     0
#define CFG_CONSTRAINED                 (1<<0)
#define CFG_REQUEST                     (1<<1)
#define CFG_NOTIFY                      (1<<2)
#define CFG_FORCE_REDRAW                (1<<3)

#define INCLUDE_HIDDEN                  (1<<0)
#define INCLUDE_SKIP_FOCUS              (1<<1)
#define INCLUDE_ALL_WORKSPACES          (1<<2)
#define INCLUDE_SKIP_PAGER              (1<<3)
#define INCLUDE_SKIP_TASKBAR            (1<<4)

#define NO_UPDATE_FLAG                  0
#define UPDATE_KEY_GRABS                (1<<0)
#define UPDATE_BUTTON_GRABS             (1<<1)
#define UPDATE_FRAME                    (1<<2)
#define UPDATE_GRAVITY                  (1<<3)
#define UPDATE_CACHE                    (1<<4)
#define UPDATE_ALL                      (UPDATE_KEY_GRABS | \
                                         UPDATE_BUTTON_GRABS | \
                                         UPDATE_FRAME | \
                                         UPDATE_GRAVITY | \
                                         UPDATE_CACHE)

#ifndef CLIENT_MIN_VISIBLE
#define CLIENT_MIN_VISIBLE              15
#endif

#define XFWM_FLAG_HAS_BORDER            (1L<<0)
#define XFWM_FLAG_HAS_MENU              (1L<<1)
#define XFWM_FLAG_HAS_MAXIMIZE          (1L<<2)
#define XFWM_FLAG_HAS_CLOSE             (1L<<3)
#define XFWM_FLAG_HAS_HIDE              (1L<<4)
#define XFWM_FLAG_HAS_MOVE              (1L<<5)
#define XFWM_FLAG_HAS_RESIZE            (1L<<6)
#define XFWM_FLAG_HAS_STICK             (1L<<7)
#define XFWM_FLAG_FOCUS                 (1L<<8)
#define XFWM_FLAG_IS_RESIZABLE          (1L<<9)
#define XFWM_FLAG_MAP_PENDING           (1L<<10)
#define XFWM_FLAG_VISIBLE               (1L<<11)
#define XFWM_FLAG_MANAGED               (1L<<13)
#define XFWM_FLAG_SESSION_MANAGED       (1L<<14)
#define XFWM_FLAG_WORKSPACE_SET         (1L<<15)
#define XFWM_FLAG_WAS_SHOWN             (1L<<16)
#define XFWM_FLAG_DRAW_ACTIVE           (1L<<17)
#define XFWM_FLAG_SEEN_ACTIVE           (1L<<18)
#define XFWM_FLAG_FIRST_MAP             (1L<<19)
#define XFWM_FLAG_LEGACY_FULLSCREEN     (1L<<20)
#define XFWM_FLAG_MOVING_RESIZING       (1L<<21)

#define CLIENT_FLAG_HAS_STRUT           (1L<<0)
#define CLIENT_FLAG_HAS_STRUT_PARTIAL   (1L<<1)
#define CLIENT_FLAG_HAS_USER_TIME       (1L<<2)
#define CLIENT_FLAG_HAS_STARTUP_TIME    (1L<<3)
#define CLIENT_FLAG_ABOVE               (1L<<4)
#define CLIENT_FLAG_BELOW               (1L<<5)
#define CLIENT_FLAG_FULLSCREEN          (1L<<6)
#define CLIENT_FLAG_ICONIFIED           (1L<<7)
#define CLIENT_FLAG_MAXIMIZED_VERT      (1L<<8)
#define CLIENT_FLAG_MAXIMIZED_HORIZ     (1L<<9)
#define CLIENT_FLAG_MAXIMIZED           (CLIENT_FLAG_MAXIMIZED_VERT | \
                                         CLIENT_FLAG_MAXIMIZED_HORIZ)
#define CLIENT_FLAG_SHADED              (1L<<10)
#define CLIENT_FLAG_SKIP_PAGER          (1L<<11)
#define CLIENT_FLAG_SKIP_TASKBAR        (1L<<12)
#define CLIENT_FLAG_STATE_MODAL         (1L<<13)
#define CLIENT_FLAG_STICKY              (1L<<15)
#define CLIENT_FLAG_NAME_CHANGED        (1L<<16)
#define CLIENT_FLAG_DEMANDS_ATTENTION   (1L<<17)
#define CLIENT_FLAG_HAS_SHAPE           (1L<<18)

#define WM_FLAG_DELETE                  (1L<<0)
#define WM_FLAG_INPUT                   (1L<<1)
#define WM_FLAG_TAKEFOCUS               (1L<<2)
#define WM_FLAG_CONTEXT_HELP            (1L<<3)
#define WM_FLAG_URGENT                  (1L<<4)

#define CLIENT_FLAG_INITIAL_VALUES      XFWM_FLAG_HAS_BORDER | \
                                        XFWM_FLAG_HAS_MENU | \
                                        XFWM_FLAG_HAS_MAXIMIZE | \
                                        XFWM_FLAG_HAS_STICK | \
                                        XFWM_FLAG_HAS_HIDE | \
                                        XFWM_FLAG_HAS_CLOSE | \
                                        XFWM_FLAG_HAS_MOVE | \
                                        XFWM_FLAG_HAS_RESIZE | \
                                        XFWM_FLAG_FIRST_MAP

#define ALL_WORKSPACES                  (int) 0xFFFFFFFF

#define CONSTRAINED_WINDOW(c)           ((c->win_layer > WIN_LAYER_DESKTOP) && \
                                        !(c->type & (WINDOW_DESKTOP | WINDOW_DOCK)) && \
                                        !FLAG_TEST(c->xfwm_flags, XFWM_FLAG_LEGACY_FULLSCREEN))

#define WINDOW_TYPE_DIALOG              (WINDOW_DIALOG | \
                                         WINDOW_MODAL_DIALOG)
#define WINDOW_TYPE_DONT_PLACE          (WINDOW_DESKTOP | \
                                         WINDOW_DOCK | \
                                         WINDOW_UTILITY | \
                                         WINDOW_SPLASHSCREEN)
#define WINDOW_REGULAR_FOCUSABLE        (WINDOW_NORMAL | \
                                         WINDOW_DIALOG | \
                                         WINDOW_MODAL_DIALOG)
#define WINDOW_TYPE_DONT_FOCUS          (WINDOW_SPLASHSCREEN | \
                                         WINDOW_DOCK)



/* Convenient macros */
#define FLAG_TEST(flag,bits)                   (flag & (bits))
#define FLAG_TEST_ALL(flag,bits)               ((flag & (bits)) == (bits))
#define FLAG_TEST_AND_NOT(flag,bits1,bits2)    ((flag & (bits1 | bits2)) == (bits1))
#define FLAG_SET(flag,bits)                    (flag |= (bits))
#define FLAG_UNSET(flag,bits)                  (flag &= ~(bits))
#define FLAG_TOGGLE(flag,bits)                 (flag ^= (bits))

#define CLIENT_CAN_HIDE_WINDOW(c)       (!(c->transient_for) && \
                                         FLAG_TEST(c->xfwm_flags, XFWM_FLAG_HAS_HIDE) && \
                                         !FLAG_TEST(c->flags, CLIENT_FLAG_SKIP_TASKBAR))
#define CLIENT_CAN_MAXIMIZE_WINDOW(c)   FLAG_TEST_ALL(c->xfwm_flags, XFWM_FLAG_HAS_MAXIMIZE | \
                                                                     XFWM_FLAG_HAS_RESIZE | \
                                                                     XFWM_FLAG_IS_RESIZABLE)
#define CLIENT_CAN_STICK_WINDOW(c)      (!(c->transient_for) && \
                                         FLAG_TEST(c->xfwm_flags, XFWM_FLAG_HAS_STICK) && \
                                         !FLAG_TEST(c->flags, CLIENT_FLAG_SKIP_TASKBAR))

#define HINTS_ACCEPT_INPUT(wmhints)     (!(wmhints) || \
                                         ((wmhints) && !(wmhints->flags & InputHint)) || \
                                         ((wmhints) && (wmhints->flags & InputHint) && (wmhints->input)))

typedef enum
{
    UNSET = 0,
    WINDOW_NORMAL       = (1 << 0),
    WINDOW_DESKTOP      = (1 << 1),
    WINDOW_DOCK         = (1 << 2),
    WINDOW_DIALOG       = (1 << 3),
    WINDOW_MODAL_DIALOG = (1 << 4),
    WINDOW_TOOLBAR      = (1 << 5),
    WINDOW_MENU         = (1 << 6),
    WINDOW_UTILITY      = (1 << 7),
    WINDOW_SPLASHSCREEN = (1 << 8)
}
netWindowType;

struct _ClientPixmapCache
{
    xfwmPixmap pm_title[2];
    xfwmPixmap pm_sides[3][2];
    int previous_width;
    int previous_height;
};

struct _Client
{
    /* Reference to our screen structure */
    ScreenInfo *screen_info;
    
    Window window;
    Window frame;
    Window transient_for;
    Window *cmap_windows;
    xfwmWindow title;
    xfwmWindow sides[3];
    xfwmWindow corners[4];
    xfwmWindow buttons[BUTTON_COUNT];
    Window client_leader;
    Window group_leader;
    xfwmPixmap appmenu[3];
    Colormap cmap;
    unsigned long win_hints;
    unsigned long win_state;
    unsigned long win_layer;
    unsigned long serial;
    Atom type_atom;
    Visual *visual;
    XSizeHints *size;
    XWMHints *wmhints;
    XClassHint class;
    Client *next;
    Client *prev;
    netWindowType type;
    int x;
    int y;
    int width;
    int height;
    int depth;
    int border_width;
    int gravity;
    int win_workspace;
    unsigned int ignore_unmap;
    int old_x;
    int old_y;
    int old_width;
    int old_height;
    int fullscreen_old_x;
    int fullscreen_old_y;
    int fullscreen_old_width;
    int fullscreen_old_height;
    int fullscreen_old_layer;
    int initial_layer;
    int ncmap;
    int button_pressed[BUTTON_COUNT];
    int struts[12];
    gchar *name;
    GTimeVal last_op_time;
    Time user_time;
    unsigned long flags;
    unsigned long wm_flags;
    unsigned long xfwm_flags;
    /* Timout to manage blinking decorations for urgent windows */
    guint blink_timeout_id;
    /* Pixmap caching */
    ClientPixmapCache pm_cache;
    /* Opacity for the compositor */
    guint opacity;
    gboolean opacity_locked;
    
#ifdef HAVE_LIBSTARTUP_NOTIFICATION
    /* Startup notification */
    gchar *startup_id;
#endif /* HAVE_LIBSTARTUP_NOTIFICATION */
};

extern Client *clients;
extern unsigned int client_count;

Display *clientGetXDisplay (Client *);
void     clientClearLastOpTime (Client *);
void     clientUpdateWinState (Client *, XClientMessageEvent *);
void     clientUpdateUrgency (Client *);
void     clientCoordGravitate (Client *, int, int *, int *);
void     clientGravitate (Client *, int);
void     clientConfigure (Client *, XWindowChanges *, int, unsigned short);
void     clientGetMWMHints (Client *, gboolean);
void     clientGetWMNormalHints (Client *, gboolean);
void     clientGetWMProtocols (Client *);
void     clientClearPixmapCache (Client *);
void     clientUpdateIcon (Client * c);
Client  *clientFrame (DisplayInfo *, Window, gboolean);
void     clientUnframe (Client *, gboolean);
void     clientFrameAll (ScreenInfo *);
void     clientUnframeAll (ScreenInfo *);
void     clientInstallColormaps (Client *);
void     clientUpdateColormaps (Client *);
void     clientUpdateAllFrames (ScreenInfo *, gboolean);
void     clientGrabKeys (Client *);
void     clientUngrabKeys (Client *);
void     clientGrabButtons (Client *);
void     clientUngrabButtons (Client *);
Client  *clientGetFromWindow (ScreenInfo *, Window, int);
void     clientShow (Client *, gboolean);
void     clientHide (Client *, int, gboolean);
void     clientHideAll (Client *, int);
void     clientClearAllShowDesktop (ScreenInfo *);
void     clientToggleShowDesktop (ScreenInfo *);
void     clientClose (Client *);
void     clientKill (Client *);
void     clientEnterContextMenuState (Client *);
void     clientSetLayer (Client *, int);
void     clientSetWorkspace (Client *, int, gboolean);
void     clientShade (Client *);
void     clientUnshade (Client *);
void     clientToggleShaded (Client *);
void     clientStick (Client *, gboolean);
void     clientUnstick (Client *, gboolean);
void     clientToggleSticky (Client *, gboolean);
void     clientToggleFullscreen (Client *);
void     clientToggleAbove (Client *);
void     clientToggleBelow (Client *);
void     clientRemoveMaximizeFlag (Client *);
void     clientToggleMaximized (Client *, int, gboolean);
void     clientIncOpacity (Client *);
void     clientDecOpacity (Client *);
void     clientScreenResize(ScreenInfo *);
void     clientMove (Client *, XEvent *);
void     clientResize (Client *, int, XEvent *);
void     clientCycle (Client *, XEvent *);
void     clientButtonPress (Client *, Window, XButtonEvent *);
Client  *clientGetLeader (Client *);
#ifdef HAVE_LIBSTARTUP_NOTIFICATION
char    *clientGetStartupId (Client *);
#endif /* HAVE_LIBSTARTUP_NOTIFICATION */


#endif /* INC_CLIENT_H */