1 /*
2  * Copyright (C) 2000-2007 Carsten Haitzler, Geoff Harrison and various contributors
3  * Copyright (C) 2004-2021 Kim Woelders
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a copy
6  * of this software and associated documentation files (the "Software"), to
7  * deal in the Software without restriction, including without limitation the
8  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
9  * sell copies of the Software, and to permit persons to whom the Software is
10  * furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be included in
13  * all copies of the Software, its documentation and marketing & publicity
14  * materials, and acknowledgment shall be given in the documentation, materials
15  * and software packages that this Software was used.
16  *
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 BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
21  * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23  */
24 #ifndef _EWIN_H_
25 #define _EWIN_H_
26 
27 #include "config.h"
28 
29 #include "eobj.h"
30 #include "etypes.h"
31 #include "xwin.h"
32 
33 /* Window operation sources */
34 #define OPSRC_NA        0
35 #define OPSRC_APP       1
36 #define OPSRC_USER      2
37 #define OPSRC_WM        3
38 
39 typedef union {
40    unsigned char       all:8;
41    struct {
42       unsigned char       rsvd:2;
43       unsigned char       border:1;	/* W   */
44       unsigned char       close:1;	/*  AU */
45       unsigned char       focus:1;	/* WA  */
46       unsigned char       iconify:1;	/* W U */
47       unsigned char       move:1;	/*  AU */
48       unsigned char       size:1;	/*  AU */
49    } b;
50 } EWinInhibit;
51 
52 #define EwinInhGetApp(ewin, item)      (ewin->inh_app.b.item)
53 #define EwinInhSetApp(ewin, item, on)  ewin->inh_app.b.item = (on)
54 #define EwinInhGetUser(ewin, item)     (ewin->inh_user.b.item)
55 #define EwinInhSetUser(ewin, item, on) ewin->inh_user.b.item = (on)
56 #define EwinInhGetWM(ewin, item)       (ewin->inh_wm.b.item)
57 #define EwinInhSetWM(ewin, item, on)   ewin->inh_wm.b.item = (on)
58 
59 typedef struct {
60    void                (*Init)(EWin * ewin);
61    void                (*Layout)(EWin * ewin, int *px, int *py, int *pw,
62 				 int *ph);
63    void                (*MoveResize)(EWin * ewin, int resize);
64    void                (*Close)(EWin * ewin);
65 } EWinOps;
66 
67 struct _ewin {
68    EObj                o;
69    char                type;
70 #if USE_CONTAINER_WIN
71    Win                 win_container;
72 #endif
73    unsigned int        serial;
74 
75    const Border       *border;
76    const Border       *normal_border;
77    EWinBit            *bits;
78 
79    struct {
80       Win                 win;
81       int                 x, y, w, h, bw;
82       unsigned int        event_mask;
83    } client;
84 
85    struct {
86       char                state;
87       char                visibility;
88       char                shaped;
89       char                shaded;
90       unsigned char       click_grab_button;
91 
92       unsigned            snapstarted:1;	/* Started from snap cmd */
93       unsigned            identified:1;
94       unsigned            placed:1;
95       unsigned            iconified:1;
96       unsigned            docked:1;
97 
98       unsigned            click_grab_isset:1;
99       unsigned            maximized_horz:1;
100       unsigned            maximized_vert:1;
101       unsigned            fullscreen:1;
102       unsigned            zoomed:1;
103 
104       unsigned            active:1;
105       unsigned            modal:1;
106       unsigned            attention:1;
107 
108       unsigned            showingdesk:1;	/* Iconified by show desktop */
109       unsigned            sliding:1;
110       unsigned            moving:1;
111       unsigned            resizing:1;
112       unsigned            show_coords:1;
113       unsigned            shading:1;
114       unsigned            in_action:1;
115 
116       /* Derived state flags. Change only in EwinStateUpdate() */
117       unsigned            no_border:1;
118       unsigned            donthide:1;	/* Don't hide on show desktop */
119 
120       unsigned            inhibit_move:1;
121       unsigned            inhibit_resize:1;
122       unsigned            inhibit_iconify:1;
123       unsigned            inhibit_shade:1;
124       unsigned            inhibit_stick:1;
125       unsigned            inhibit_max_hor:1;
126       unsigned            inhibit_max_ver:1;
127       unsigned            inhibit_fullscreeen:1;
128       unsigned            inhibit_change_desk:1;
129       unsigned            inhibit_close:1;
130       unsigned            inhibit_stacking:1;
131 
132       unsigned            inhibit_actions:1;
133       unsigned            inhibit_focus:1;
134    } state;
135    struct {
136       /* User config */
137       unsigned int        opacity;
138       unsigned int        focused_opacity;
139       unsigned            never_use_area:1;
140       unsigned            ignorearrange:1;
141       unsigned            skip_ext_task:1;
142       unsigned            skip_ext_pager:1;
143       unsigned            skip_focuslist:1;
144       unsigned            skip_winlist:1;
145       unsigned            focusclick:1;	/* Click to focus */
146       unsigned            no_button_grabs:1;
147       unsigned            autoshade:1;	/* Autoshade on mouse in/out */
148       unsigned            no_argb:1;	/* Do not use ARGB frame */
149 
150       /* Derived from other properties */
151       unsigned            no_border:1;	/* Never apply border (MWM/netwm type) */
152       unsigned            no_resize_h:1;	/* ICCCM */
153       unsigned            no_resize_v:1;	/* ICCCM */
154 
155       /* Internal */
156       unsigned            autosave:1;
157       unsigned            donthide:1;	/* Don't hide on show desktop */
158       unsigned            vroot:1;	/* Virtual root window */
159       unsigned            no_actions:1;
160       unsigned            focus_when_mapped:1;
161    } props;
162    EWinInhibit         inh_app;
163    EWinInhibit         inh_user;
164    EWinInhibit         inh_wm;
165    struct {
166       char               *wm_icon_name;
167       char               *wm_role;
168       char               *wm_command;
169       char               *wm_machine;
170       /* WM_HINTS */
171       char                need_input;
172       char                start_iconified;
173       EX_Pixmap           icon_pmap, icon_mask;
174       EX_Window           icon_win;
175       EX_Window           group;
176       char                urgency;
177       /* WM_PROTOCOLS */
178       char                take_focus;
179       char                delete_window;
180       /* WM_TRANSIENT_FOR */
181       signed char         transient;
182       EX_Window           transient_for;	/* We are a transient for ... */
183       int                 transient_count;	/* We have <N> transients */
184       /* WM_CLIENT_LEADER */
185       EX_Window           client_leader;
186 
187       /* WM_NORMAL_HINTS */
188       int                 width_min, width_max;
189       int                 height_min, height_max;
190       int                 base_w, base_h;
191       int                 w_inc, h_inc;
192       int                 grav;
193       float               aspect_min, aspect_max;
194 
195       char                is_group_leader;
196    } icccm;
197    struct {
198       unsigned            valid:1;
199       unsigned            decor_border:1;
200       unsigned            decor_resizeh:1;
201       unsigned            decor_title:1;
202       unsigned            decor_menu:1;
203       unsigned            decor_minimize:1;
204       unsigned            decor_maximize:1;
205       unsigned            func_resize:1;
206       unsigned            func_move:1;
207       unsigned            func_minimize:1;
208       unsigned            func_maximize:1;
209       unsigned            func_close:1;
210    } mwm;
211    struct {
212       char               *wm_name;
213       char               *wm_icon_name;
214       unsigned int       *wm_icon, wm_icon_len;
215       unsigned int        opacity;
216       char                opacity_update;
217 #if USE_XSYNC
218       char                sync_request_enable;
219       XID                 sync_request_counter;
220       long long           sync_request_count;
221 #endif
222       union {
223 	 unsigned char       all;
224 	 struct {
225 	    unsigned            desktop:1;
226 	    unsigned            dock:1;
227 	    unsigned            toolbar:1;
228 	    unsigned            menu:1;
229 	    unsigned            utility:1;
230 	    unsigned            splash:1;
231 	    unsigned            dialog:1;
232 	    unsigned            normal:1;
233 	 } b;
234       } type;
235       unsigned int        current_state;
236       unsigned int        current_actions;
237    } ewmh;
238    struct {
239       signed char         gravity;
240       int                 ax, ay;	/* Current placed area */
241       int                 gx, gy;	/* Distance to edge given by gravity */
242    } place;
243    struct {
244       int                 left, right, top, bottom;
245    } strut;
246    struct {
247       char                shape;
248       char                border;
249    } update;
250 
251    int                 num_groups;
252    Group             **groups;
253    int                 area_x, area_y;
254    char               *session_id;
255    PmapMask            mini_pmm;
256 
257    int                 shape_x, shape_y, shape_w, shape_h;
258    int                 req_x, req_y;
259    int                 trg_x, trg_y;	/* Used during desk slides */
260 
261    Snapshot           *snap;
262    int                 head;	/* Unused? */
263 
264    int                 vx, vy;	/* Position in virtual root */
265    struct {			/* Saved state before maximization */
266       int                 x, y;	/* Position */
267       int                 w, h;	/* Size */
268    } save_max;
269    struct {			/* Saved state before fullscreen */
270       int                 x, y;	/* Position */
271       int                 w, h;	/* Size */
272       int                 layer;	/* Layer */
273    } save_fs;
274 
275    void               *data;	/* Data hook for internal windows */
276    const EWinOps      *ops;
277 
278    Timer              *timer;	/* Autoshade timer */
279 
280    void               *shape_data;	/* Shape drawing data hook */
281 };
282 
283 #define EWIN_STATE_NEW          0	/* New */
284 #define EWIN_STATE_STARTUP      1	/* New - during startup */
285 #define EWIN_STATE_WITHDRAWN    2
286 #define EWIN_STATE_ICONIC       3
287 #define EWIN_STATE_MAPPED       4
288 
289 #define EWIN_TYPE_NORMAL        0x00
290 #define EWIN_TYPE_DIALOG        0x01
291 #define EWIN_TYPE_MENU          0x02
292 #define EWIN_TYPE_ICONBOX       0x04
293 #define EWIN_TYPE_PAGER         0x08
294 #define EWIN_TYPE_MISC          0x10
295 
296 #define EWIN_GRAVITY_NW         0
297 #define EWIN_GRAVITY_NE         1
298 #define EWIN_GRAVITY_SW         2
299 #define EWIN_GRAVITY_SE         3
300 
301 #define EwinIsInternal(ewin)		((ewin)->type != EWIN_TYPE_NORMAL)
302 #define EwinIsTransientChild(ewin)	((ewin)->icccm.transient > 0)
303 #define EwinIsTransient(ewin)		((ewin)->icccm.transient != 0)
304 #define EwinGetTransientFor(ewin)	((ewin)->icccm.transient_for)
305 #define EwinGetTransientCount(ewin)	((ewin)->icccm.transient_count)
306 #define EwinIsWindowGroupLeader(ewin)	((ewin)->icccm.is_group_leader)
307 #define EwinGetWindowGroup(ewin)	((ewin)->icccm.group)
308 
309 #define EwinGetClientWin(ewin)		((ewin)->client.win)
310 #if USE_CONTAINER_WIN
311 #define EwinGetContainerWin(ewin)	((ewin)->win_container)
312 #define EwinGetClientConWin(ewin)	((ewin)->win_container)
313 #else
314 #define EwinGetContainerWin(ewin)	EoGetWin(ewin)
315 #define EwinGetClientConWin(ewin)	((ewin)->client.win)
316 #endif
317 #define EwinGetContainerXwin(ewin)	WinGetXwin(EwinGetContainerWin(ewin))
318 
319 #define EwinGetIcccmName(ewin)          EoGetName(ewin)
320 #define EwinGetIcccmCName(ewin)         EoGetCName(ewin)
321 #define EwinGetIcccmClass(ewin)         EoGetClass(ewin)
322 
323 /* arrange.c */
324 #define ARRANGE_VERBATIM    0
325 #define ARRANGE_BY_SIZE     1
326 #define ARRANGE_BY_POSITION 2
327 
328 void                SnapEwin(EWin * ewin, int dx, int dy, int *new_dx,
329 			     int *new_dy);
330 void                ArrangeEwin(EWin * ewin);
331 void                ArrangeEwinCentered(EWin * ewin);
332 void                ArrangeEwinXY(EWin * ewin, int *px, int *py);
333 void                ArrangeEwinCenteredXY(EWin * ewin, int *px, int *py);
334 void                ArrangeEwinCenteredOn(EWin * ewin, int x, int y, int w,
335 					  int h, int *px, int *py);
336 
337 void                ArrangeEwins(const char *params);
338 
339 /* coords.c */
340 void                CoordsShow(EWin * ewin);
341 void                CoordsShowOpacity(EWin * ewin);
342 void                CoordsHide(void);
343 
344 /* dock.c */
345 void                DockIt(EWin * ewin);
346 
347 /* draw.c */
348 void                DrawEwinShape(EWin * ewin, int md, int x, int y, int w,
349 				  int h, int firstlast);
350 void                DrawEwinShapeEnd(EWin * ewin);
351 int                 DrawEwinShapeNeedsGrab(int mode);
352 
353 /* ewins.c */
354 #define EWIN_CHANGE_NAME        (1<<0)
355 #define EWIN_CHANGE_ICON_NAME   (1<<1)
356 #define EWIN_CHANGE_ICON_PMAP   (1<<2)
357 #define EWIN_CHANGE_DESKTOP     (1<<3)
358 #define EWIN_CHANGE_LAYER       (1<<4)
359 #define EWIN_CHANGE_OPACITY     (1<<5)
360 #define EWIN_CHANGE_ATTENTION   (1<<6)
361 
362 EX_Window           EwinGetClientXwin(const EWin * ewin);
363 
364 void                EwinShapeSet(EWin * ewin);
365 int                 EwinRaise(EWin * ewin);
366 int                 EwinLower(EWin * ewin);
367 void                EwinShow(EWin * ewin);
368 void                EwinHide(EWin * ewin);
369 void                EwinKill(EWin * ewin);
370 void                DetermineEwinFloat(EWin * ewin, int dx, int dy);
371 EWin               *GetEwinPointerInClient(void);
372 EWin               *GetFocusEwin(void);
373 EWin               *GetContextEwin(void);
374 void                SetContextEwin(EWin * ewin);
375 void                EwinGetPosition(const EWin * ewin, int x, int y, int grav,
376 				    int *px, int *py);
377 void                EwinUpdateShapeInfo(EWin * ewin);
378 void                EwinPropagateShapes(EWin * ewin);
379 void                EwinStateUpdate(EWin * ewin);
380 EWin               *AddInternalToFamily(Win win, const char *bname, int type,
381 					const EWinOps * ops, void *ptr);
382 void                EwinReparent(EWin * ewin, Win parent);
383 void                EwinSetTitle(EWin * ewin, const char *title);
384 void                EwinSetClass(EWin * ewin, const char *name,
385 				 const char *clss);
386 const char         *EwinGetTitle(const EWin * ewin);
387 const char         *EwinGetIconName(const EWin * ewin);
388 const char         *EwinBorderGetName(const EWin * ewin);
389 void                EwinBorderGetSize(const EWin * ewin, int *bl, int *br,
390 				      int *bt, int *bb);
391 void                EwinBorderUpdateState(EWin * ewin);
392 int                 EwinIsOnScreen(const EWin * ewin);
393 int                 EwinIsOnDesktop(const EWin * ewin);
394 void                EwinRememberPositionSet(EWin * ewin);
395 void                EwinRememberPositionGet(EWin * ewin, Desk * dsk,
396 					    int *px, int *py);
397 void                EwinSetPlacementGravity(EWin * ewin, int x, int y);
398 void                EwinReposition(EWin * ewin);
399 void                EwinFlagsEncode(const EWin * ewin, unsigned int *flags);
400 void                EwinFlagsDecode(EWin * ewin, const unsigned int *flags);
401 void                EwinUpdateOpacity(EWin * ewin);
402 
403 void                EwinChange(EWin * ewin, unsigned int flag);
404 
405 void                EwinWarpTo(EWin * ewin, int force);
406 
407 EWin              **EwinListTransients(const EWin * ewin, int *num, int group);
408 EWin              **EwinListTransientFor(const EWin * ewin, int *num);
409 
410 void                EwinsManage(void);
411 void                EwinsSetFree(void);
412 void                EwinsShowDesktop(int on);
413 void                EwinsMoveStickyToDesk(Desk * d);
414 
415 /* ewin-ops.c */
416 /* Move/resize flags */
417 #define MRF_NOCHECK_ONSCREEN	(1<<16)
418 #define MRF_KEEP_MAXIMIZED	(1<<17)
419 
420 void                EwinMove(EWin * ewin, int x, int y, int flags);
421 void                EwinResize(EWin * ewin, int w, int h, int flags);
422 void                EwinMoveResize(EWin * ewin, int x, int y, int w, int h,
423 				   int flags);
424 void                EwinMoveResizeWithGravity(EWin * ewin, int x, int y, int w,
425 					      int h, int grav);
426 void                EwinMoveToDesktop(EWin * ewin, Desk * d);
427 void                EwinMoveToDesktopAt(EWin * ewin, Desk * d, int x, int y);
428 void                EwinIconify(EWin * ewin);
429 void                EwinAlone(EWin * ewin);
430 void                EwinDeIconify(EWin * ewin);
431 void                EwinInstantShade(EWin * ewin, int force);
432 void                EwinInstantUnShade(EWin * ewin);
433 void                EwinShade(EWin * ewin);
434 void                EwinUnShade(EWin * ewin);
435 void                EwinMoveToArea(EWin * ewin, int ax, int ay);
436 
437 void                EwinOpMove(EWin * ewin, int source, int x, int y);
438 void                EwinOpResize(EWin * ewin, int source, int w, int h);
439 void                EwinOpMoveResize(EWin * ewin, int source, int x, int y,
440 				     int w, int h);
441 void                EwinOpMoveToDesktopAt(EWin * ewin, int source, Desk * dsk,
442 					  int x, int y);
443 void                EwinOpFloatAt(EWin * ewin, int source, int x, int y);
444 void                EwinOpUnfloatAt(EWin * ewin, int source, Desk * d,
445 				    int x, int y);
446 void                EwinOpClose(EWin * ewin, int source);
447 void                EwinOpActivate(EWin * ewin, int source, int raise);
448 void                EwinOpKill(EWin * ewin, int source);
449 void                EwinOpRaise(EWin * ewin, int source);
450 void                EwinOpLower(EWin * ewin, int source);
451 void                EwinOpStick(EWin * ewin, int source, int on);
452 void                EwinOpSkipLists(EWin * ewin, int source, int skip);
453 void                EwinOpIconify(EWin * ewin, int source, int on);
454 void                EwinOpShade(EWin * ewin, int source, int on);
455 void                EwinOpSetLayer(EWin * ewin, int source, int layer);
456 void                EwinOpSetBorder(EWin * ewin, int source, const char *name);
457 void                EwinOpSetOpacity(EWin * ewin, int source, int opacity);
458 void                EwinOpSetFocusedOpacity(EWin * ewin, int source,
459 					    int opacity);
460 void                EwinOpMoveToDesk(EWin * ewin, int source, Desk * dsk,
461 				     int inc);
462 void                EwinOpFullscreen(EWin * ewin, int source, int on);
463 
464 /* finders.c */
465 EWin               *EwinFindByPtr(const EWin * ewin);
466 EWin               *EwinFindByClient(EX_Window win);
467 EWin               *EwinFindGroupMember(EWin * ewin);
468 EWin              **EwinsFindByExpr(const char *match, int *pnum, int *pflags);
469 EWin               *EwinFindByExpr(const char *match);
470 
471 /* icccm.c (for now) */
472 #if USE_XSYNC
473 int                 EwinSyncRequestSend(EWin * ewin);
474 void                EwinSyncRequestWait(EWin * ewin);
475 #endif
476 
477 /* moveresize.c */
478 void                MoveResizeMoveStart(EWin * ewin, int kbd, int constrained,
479 					int nogroup);
480 void                MoveResizeResizeStart(EWin * ewin, int kbd, int hv);
481 
482 void                MoveResizeSuspend(void);
483 void                MoveResizeResume(void);
484 void                MoveResizeEnd(EWin * ewin);
485 
486 /* size.c */
487 void                MaxSizeHV(EWin * ewin, const char *resize_type,
488 			      int hor, int ver, int flags);
489 
490 /* stacking.c */
491 EWin               *const *EwinListStackGet(int *num);
492 EWin               *const *EwinListFocusGet(int *num);
493 EWin               *const *EwinListGetForDesk(int *num, Desk * d);
494 EWin               *const *EwinListOrderGet(int *num);
495 EWin               *EwinListStackGetTop(void);
496 int                 EwinListStackIsRaised(const EWin * ewin);
497 
498 #define EwinListGetAll EwinListStackGet
499 
500 /* zoom.c */
501 #if ENABLE_ZOOM
502 void                Zoom(EWin * ewin, int on);
503 void                ReZoom(EWin * ewin);
504 #else
505 #define ReZoom(ewin)   do {} while(0)
506 #define Zoom(ewin, on) do {} while(0)
507 #endif
508 
509 #endif /* _EWIN_H_ */
510