~ctwm/ctwm/trunk

304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
1
/*
554.1.10 by Matthew Fuller
Pull out the simple cases of long-form twm+Claude copyright/license
2
 *       Copyright 1988 by Evans & Sutherland Computer Corporation,
3
 *                          Salt Lake City, Utah
4
 *  Portions Copyright 1989 by the Massachusetts Institute of Technology
5
 *                        Cambridge, Massachusetts
6
 *
7
 * Copyright 1992 Claude Lecommandeur.
11 by Claude Lecommandeur
CTWM version 3.2p1
8
 */
1 by Claude Lecommandeur
CTWM version 1.1
9
10
/**********************************************************************
11
 *
12
 * $XConsortium: add_window.c,v 1.153 91/07/10 13:17:26 dave Exp $
13
 *
14
 * Add a new window, put the titlbar and other stuff around
15
 * the window
16
 *
17
 * 31-Mar-88 Tom LaStrange        Initial Version.
18
 *
19
 * Do the necessary modification to be integrated in ctwm.
20
 * Can no longer be used for the standard twm.
21
 *
22
 * 22-April-92 Claude Lecommandeur.
23
 *
24
 **********************************************************************/
25
395.1.1 by Matthew Fuller
Move ctwm.h to always be included first.
26
#include "ctwm.h"
27
1 by Claude Lecommandeur
CTWM version 1.1
28
#include <stdio.h>
491.1.14 by Matthew Fuller
Remove incorrect pre-ANSI potential override prototypes for malloc()
29
#include <stdlib.h>
9 by Claude Lecommandeur
CTWM version 3.1
30
#include <string.h>
17 by Claude Lecommandeur
CTWM version 3.5
31
#include <sys/time.h>
492.2.15 by Matthew Fuller
Extract the shape.h include into just the .c files that need it.
32
1 by Claude Lecommandeur
CTWM version 1.1
33
#include <X11/Xatom.h>
492.2.15 by Matthew Fuller
Extract the shape.h include into just the .c files that need it.
34
#include <X11/extensions/shape.h>
340.1.1 by Matthew Fuller
Rearrange includes to be in what we'll call the Proper Order.
35
1 by Claude Lecommandeur
CTWM version 1.1
36
#include "add_window.h"
692.1.6 by Matthew Fuller
Conditionalize including captive.h.
37
#ifdef CAPTIVE
539.1.14 by Matthew Fuller
Sort includes.
38
#include "captive.h"
692.1.6 by Matthew Fuller
Conditionalize including captive.h.
39
#endif
518.1.28 by Matthew Fuller
Inagurate a colormaps.c by pulling the colormap functions out of
40
#include "colormaps.h"
615.1.40 by Matthew Fuller
Implement noticing CTWM_WM_NAME.
41
#include "ctwm_atoms.h"
539.1.14 by Matthew Fuller
Sort includes.
42
#include "functions.h"
1 by Claude Lecommandeur
CTWM version 1.1
43
#include "events.h"
615.1.26 by Matthew Fuller
Properly check and set both name properties at AddWindow() time.
44
#ifdef EWMH
45
# include "ewmh_atoms.h"
46
#endif
539.1.14 by Matthew Fuller
Sort includes.
47
#include "gram.tab.h"
14 by Claude Lecommandeur
CTWM version 3.4
48
#include "icons.h"
1 by Claude Lecommandeur
CTWM version 1.1
49
#include "iconmgr.h"
539.1.14 by Matthew Fuller
Sort includes.
50
#include "image.h"
51
#include "list.h"
252.1.1 by Olaf 'Rhialto' Seibert
Look at some _MOTIF_WM_HINTS; proof of concept version.
52
#include "mwmhints.h"
524.1.1 by Matthew Fuller
Pull occupation.h out of screen.h, and include it directly in the
53
#include "occupation.h"
539.1.14 by Matthew Fuller
Sort includes.
54
#include "otp.h"
55
#include "parse.h"
614.1.5 by Maxime Soulé
AddWindow() + Mouse-3 now uses layout
56
#include "r_area.h"
614.2.4 by Matthew Fuller
r_layout.h includes r_structs.h, so including it in screen.h
57
#include "r_layout.h"
539.1.14 by Matthew Fuller
Sort includes.
58
#include "screen.h"
702.1.4 by Matthew Fuller
Conditionalize a bunch of the session bits.
59
#ifdef SESSION
539.1.14 by Matthew Fuller
Sort includes.
60
#include "session.h"
702.1.4 by Matthew Fuller
Conditionalize a bunch of the session bits.
61
#endif
539.1.14 by Matthew Fuller
Sort includes.
62
#include "util.h"
524.1.3 by Matthew Fuller
Pull vscreen.h out of screen.h and #include it directly in the files
63
#include "vscreen.h"
700.1.8 by Matthew Fuller
ifdef away all the winbox setup stuff in add_window.c
64
#ifdef WINBOX
539.1.14 by Matthew Fuller
Sort includes.
65
#include "windowbox.h"
700.1.8 by Matthew Fuller
ifdef away all the winbox setup stuff in add_window.c
66
#endif
538.1.3 by Matthew Fuller
Rename the decorations*.h to win_decorations*.h.
67
#include "win_decorations.h"
523.1.11 by Matthew Fuller
Inagurate win_ops.c by moving the focus functions from util.c into it.
68
#include "win_ops.h"
518.1.22 by Matthew Fuller
Break the funcs for handling WindowRegion stuff out of add_window.c
69
#include "win_regions.h"
538.1.5 by Matthew Fuller
And rename over resize.h.
70
#include "win_resize.h"
675.1.7 by Olaf 'Rhialto' Seibert
Move the window ring functions to their own file.
71
#include "win_ring.h"
523.1.1 by Matthew Fuller
Inagurate a win_utils.c with GetWindowSizeHints().
72
#include "win_utils.h"
510.1.9 by Matthew Fuller
Only stuff left in workmgr is the actual workspace manager stuff.
73
#include "workspace_manager.h"
614.1.23 by Maxime Soulé
Some geometries can be relative to a monitor
74
#include "xparsegeometry.h"
1 by Claude Lecommandeur
CTWM version 1.1
75
76
77
int AddingX;
78
int AddingY;
134 by Richard Levitte
Resolve a lot of unsigned vs. signed conflicts, and a few other
79
unsigned int AddingW;
80
unsigned int AddingH;
1 by Claude Lecommandeur
CTWM version 1.1
81
207.1.11 by Richard Levitte
Make RandomPlacement respect the BorderLeft, BorderRight, BorderTop and BorderBottom settings
82
static int PlaceX = -1;
83
static int PlaceY = -1;
696.1.8 by Matthew Fuller
This func is purely vscreen stuff related, so we can conditionalize it
84
#ifdef VSCREEN
521.1.25 by Matthew Fuller
Staticize this func while I'm messing with stuff, since it's currently
85
static void DealWithNonSensicalGeometries(Display *dpy, Window vroot,
521.1.26 by Matthew Fuller
make indent
86
                TwmWindow *tmp_win);
696.1.8 by Matthew Fuller
This func is purely vscreen stuff related, so we can conditionalize it
87
#endif
1 by Claude Lecommandeur
CTWM version 1.1
88
89
char NoName[] = "Untitled"; /* name if no name is specified */
492.2.91 by Matthew Fuller
Track down a bunch more boolean vars, and make them bool.
90
bool resizeWhenAdd;
1 by Claude Lecommandeur
CTWM version 1.1
91
92
93
94
/***********************************************************************
95
 *
96
 *  Procedure:
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
97
 *      AddWindow - add a new window to the twm list
1 by Claude Lecommandeur
CTWM version 1.1
98
 *
99
 *  Returned Value:
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
100
 *      (TwmWindow *) - pointer to the TwmWindow structure
1 by Claude Lecommandeur
CTWM version 1.1
101
 *
102
 *  Inputs:
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
103
 *      w       - the window id of the window to add
556.1.67 by Matthew Fuller
Minimal fixup of this heading comment.
104
 *      wtype   - flag to tell if this is a normal window or some ctwm
105
 *                internal one.
20 by Claude Lecommandeur
CTWM version 3.6
106
 *
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
107
 *      iconp   - pointer to icon manager struct
1 by Claude Lecommandeur
CTWM version 1.1
108
 *
109
 ***********************************************************************
110
 */
111
497.1.16 by Matthew Fuller
Now that we've eliminated the magic about it, we can just turn this
112
TwmWindow *
113
AddWindow(Window w, AWType wtype, IconMgr *iconp, VirtualScreen *vs)
1 by Claude Lecommandeur
CTWM version 1.1
114
{
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
115
	TwmWindow *tmp_win;                 /* new twm window structure */
492.2.91 by Matthew Fuller
Track down a bunch more boolean vars, and make them bool.
116
	bool ask_user;               /* don't know where to put the window */
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
117
	int gravx, gravy;                   /* gravity signs for positioning */
118
	int namelen;
119
	int bw2;
702.1.4 by Matthew Fuller
Conditionalize a bunch of the session bits.
120
#ifdef SESSION
556.1.7 by Matthew Fuller
Pull vars only used in the saved-session bits into that scope.
121
	short restore_icon_x, restore_icon_y;
492.2.68 by Matthew Fuller
Convert TWMWinConfigEntry struct (used in session saving) over to
122
	bool restore_iconified = false;
123
	bool restore_icon_info_present = false;
702.1.4 by Matthew Fuller
Conditionalize a bunch of the session bits.
124
#endif
556.1.5 by Matthew Fuller
Slightly reorganize codeflow to let me split an if/else into two if's
125
	bool restoredFromPrevSession = false;
556.1.52 by Matthew Fuller
Comment occupation setting. Initializing saved_occupation lets us
126
	int saved_occupation = 0; /* <== [ Matthew McNeill Feb 1997 ] == */
492.2.66 by Matthew Fuller
This var is only used internally, so it's an easy bool conversion.
127
	bool random_placed = false;
700.1.8 by Matthew Fuller
ifdef away all the winbox setup stuff in add_window.c
128
#ifdef WINBOX
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
129
	WindowBox *winbox;
700.1.8 by Matthew Fuller
ifdef away all the winbox setup stuff in add_window.c
130
#endif
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
131
	Window vroot;
1 by Claude Lecommandeur
CTWM version 1.1
132
133
#ifdef DEBUG
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
134
	fprintf(stderr, "AddWindow: w = 0x%x\n", w);
1 by Claude Lecommandeur
CTWM version 1.1
135
#endif
17 by Claude Lecommandeur
CTWM version 3.5
136
692.1.5 by Matthew Fuller
Add ifdef's around references to Screen and CLargs members that are
137
#ifdef CAPTIVE
556.1.11 by Matthew Fuller
Add some comments/whitespace to the beginning bits of the func to
138
	/*
139
	 * Possibly this window should be in a captive sub-ctwm?  If so, we
140
	 * shouldn't mess with it at all.
141
	 */
389.1.46 by Matthew Fuller
Convert the 'captive' flag to is_captive and move it into CLarg.
142
	if(!CLarg.is_captive && RedirectToCaptive(w)) {
503.1.42 by Matthew Fuller
Expand thie comment a bit with my current understanding of how I don't
143
		/* XXX x-ref comment by SetNoRedirect() */
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
144
		return (NULL);
145
	}
692.1.5 by Matthew Fuller
Add ifdef's around references to Screen and CLargs members that are
146
#endif
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
147
556.1.11 by Matthew Fuller
Add some comments/whitespace to the beginning bits of the func to
148
149
	/*
150
	 * Allocate and initialize our tracking struct
151
	 */
491.1.8 by Matthew Fuller
Stop casting return values of [mc]alloc(). void * has existed for 27
152
	tmp_win = calloc(1, sizeof(TwmWindow));
556.1.3 by Matthew Fuller
Don't compare a pointer to 0, use NULL.
153
	if(tmp_win == NULL) {
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
154
		fprintf(stderr, "%s: Unable to allocate memory to manage window ID %lx.\n",
155
		        ProgramName, w);
156
		return NULL;
157
	}
158
556.1.11 by Matthew Fuller
Add some comments/whitespace to the beginning bits of the func to
159
	/*
160
	 * Some of these initializations are strictly unnecessary, since they
161
	 * evaluate out to 0, and calloc() gives us an already zero'd buffer.
162
	 * I'm leaving them anyway because a couple unnecessary stores are
163
	 * near enough to free considering everything we're doing, that the
164
	 * value as documentation stupendously outweighs the cost.
165
	 */
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
166
	tmp_win->w = w;
167
	tmp_win->zoomed = ZOOM_NONE;
497.1.16 by Matthew Fuller
Now that we've eliminated the magic about it, we can just turn this
168
	tmp_win->isiconmgr = (wtype == AWT_ICON_MANAGER);
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
169
	tmp_win->iconmgrp = iconp;
497.1.16 by Matthew Fuller
Now that we've eliminated the magic about it, we can just turn this
170
	tmp_win->iswspmgr = (wtype == AWT_WORKSPACE_MANAGER);
512.1.8 by Matthew Fuller
Add a bool into the TwmWindow to flag the Occupy window.
171
	tmp_win->isoccupy = (wtype == AWT_OCCUPY);
700.1.11 by Matthew Fuller
Hide these TwmWindow winbox-related fields behind an ifdef along with
172
#ifdef WINBOX
497.1.16 by Matthew Fuller
Now that we've eliminated the magic about it, we can just turn this
173
	tmp_win->iswinbox = (wtype == AWT_WINDOWBOX);
700.1.11 by Matthew Fuller
Hide these TwmWindow winbox-related fields behind an ifdef along with
174
#endif
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
175
	tmp_win->vs = vs;
176
	tmp_win->parent_vs = vs;
177
	tmp_win->savevs = NULL;
178
	tmp_win->cmaps.number_cwins = 0;
179
	tmp_win->savegeometry.width = -1;
556.1.9 by Matthew Fuller
Just pre-set these up front and let them be overwritten by the session
180
	tmp_win->widthEverChangedByUser = false;
181
	tmp_win->heightEverChangedByUser = false;
556.1.15 by Matthew Fuller
Move a few bits of static initialization up to earlier in the code.
182
	tmp_win->nameChanged = false;
556.1.26 by Matthew Fuller
More a few more static and never-touched initializations up to the
183
	tmp_win->squeezed = false;
184
	tmp_win->iconified = false;
185
	tmp_win->isicon = false;
186
	tmp_win->icon_on = false;
556.1.29 by Matthew Fuller
Move another few static initializations earlier.
187
	tmp_win->ring.cursor_valid = false;
188
	tmp_win->squeeze_info = NULL;
562 by Matthew Fuller
squeeze_info_copied is boolean, so make it bool.
189
	tmp_win->squeeze_info_copied = false;
556.1.26 by Matthew Fuller
More a few more static and never-touched initializations up to the
190
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
191
556.1.11 by Matthew Fuller
Add some comments/whitespace to the beginning bits of the func to
192
193
	/*
194
	 * Fetch a few bits of info about the window from the server, and
195
	 * tell the server to tell us about property changes; we'll need to
196
	 * know what happens.
556.1.19 by Matthew Fuller
Expand these early comments about the limitations of what we can look
197
	 *
198
	 * It's important that these remain relatively disconnected "early"
199
	 * bits; generally, they shouldn't rely on anything but the X Window
200
	 * in tmp_win->w to do their stuff.  e.g., anything that relies on
201
	 * other values in our ctwm TwmWindow tmp_win (window name, various
202
	 * flags, etc) has to come later.
556.1.11 by Matthew Fuller
Add some comments/whitespace to the beginning bits of the func to
203
	 */
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
204
	XSelectInput(dpy, tmp_win->w, PropertyChangeMask);
205
	XGetWindowAttributes(dpy, tmp_win->w, &tmp_win->attr);
206
	FetchWmProtocols(tmp_win);
207
	FetchWmColormapWindows(tmp_win);
556.1.18 by Matthew Fuller
Move the EWMH property getting up top too.
208
#ifdef EWMH
209
	EwmhGetProperties(tmp_win);
210
#endif /* EWMH */
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
211
556.1.19 by Matthew Fuller
Expand these early comments about the limitations of what we can look
212
213
	/*
556.1.41 by Matthew Fuller
Move setting old_bw up to as early as it can be.
214
	 * Some other simple early initialization that has to follow those
215
	 * bits.
216
	 */
217
	tmp_win->old_bw = tmp_win->attr.border_width;
218
219
220
	/*
556.1.19 by Matthew Fuller
Expand these early comments about the limitations of what we can look
221
	 * Setup window name and class bits.  A lot of following code starts
222
	 * to care about this; in particular, anything looking in our
223
	 * name_lists generally goes by the name/class, so we need to get
224
	 * these set pretty early in the process.
225
	 */
615.1.40 by Matthew Fuller
Implement noticing CTWM_WM_NAME.
226
	tmp_win->names.ctwm_wm_name = GetWMPropertyString(tmp_win->w,
615.1.47 by Matthew Fuller
make indent
227
	                              XA_CTWM_WM_NAME);
615.1.26 by Matthew Fuller
Properly check and set both name properties at AddWindow() time.
228
#ifdef EWMH
229
	tmp_win->names.net_wm_name = GetWMPropertyString(tmp_win->w,
230
	                             XA__NET_WM_NAME);
231
#endif
232
	tmp_win->names.wm_name = GetWMPropertyString(tmp_win->w, XA_WM_NAME);
233
	set_window_name(tmp_win);
556.1.16 by Matthew Fuller
Pull more of the bits for setting/default name/class up earlier and
234
	namelen = strlen(tmp_win->name);
235
641.1.8 by Matthew Fuller
Add various narrative comments through the startup process (outside of
236
	/* Setup class.  x-ref XXX in ctwm_main() about NoClass */
556.1.16 by Matthew Fuller
Pull more of the bits for setting/default name/class up earlier and
237
	tmp_win->class = NoClass;
238
	XGetClassHint(dpy, tmp_win->w, &tmp_win->class);
239
	if(tmp_win->class.res_name == NULL) {
240
		tmp_win->class.res_name = NoName;
241
	}
242
	if(tmp_win->class.res_class == NULL) {
243
		tmp_win->class.res_class = NoName;
244
	}
245
556.1.58 by Matthew Fuller
Grabbing the icon name doesn't rely on any of the other calculation,
246
	/* Grab the icon name too */
615.1.40 by Matthew Fuller
Implement noticing CTWM_WM_NAME.
247
	tmp_win->names.ctwm_wm_icon_name = GetWMPropertyString(tmp_win->w,
615.1.47 by Matthew Fuller
make indent
248
	                                   XA_CTWM_WM_ICON_NAME);
615.1.36 by Matthew Fuller
Add handling of _NET_WM_ICON_NAME as well.
249
#ifdef EWMH
250
	tmp_win->names.net_wm_icon_name = GetWMPropertyString(tmp_win->w,
615.1.40 by Matthew Fuller
Implement noticing CTWM_WM_NAME.
251
	                                  XA__NET_WM_ICON_NAME);
615.1.36 by Matthew Fuller
Add handling of _NET_WM_ICON_NAME as well.
252
#endif
615.1.33 by Matthew Fuller
Switch to using the inner name and the util func on window creation.
253
	tmp_win->names.wm_icon_name = GetWMPropertyString(tmp_win->w,
615.1.40 by Matthew Fuller
Implement noticing CTWM_WM_NAME.
254
	                              XA_WM_ICON_NAME);
615.1.33 by Matthew Fuller
Switch to using the inner name and the util func on window creation.
255
	set_window_icon_name(tmp_win);
256
556.1.58 by Matthew Fuller
Grabbing the icon name doesn't rely on any of the other calculation,
257
556.1.22 by Matthew Fuller
Wrap a macro around IsInList() to reduce repetition, and use it for
258
	/* Convenience macro */
259
#define CHKL(lst) IsInList(Scr->lst, tmp_win)
260
556.1.20 by Matthew Fuller
Update comments/whitespace.
261
556.1.17 by Matthew Fuller
Move all these transient-handling bits together.
262
	/* Is it a transient?  Or should we ignore that it is? */
263
	tmp_win->istransient = XGetTransientForHint(dpy, tmp_win->w,
264
	                       &tmp_win->transientfor);
265
	if(tmp_win->istransient) {
556.1.27 by Matthew Fuller
CHKL-ify this condition, and expand the comment about it.
266
		/*
558.1.10 by Matthew Fuller
Another tpyo and rewrap.
267
		 * XXX Should this be looking up transientfor instead of tmp_win?
268
		 * It seems like IgnoreTransient {} would list the windows that
269
		 * have transients we should ignore, while this condition makes
270
		 * it list the transient window names we should ignore.  Probably
271
		 * not trivial to fix if that's right, since it might b0rk
272
		 * existing configs...
556.1.27 by Matthew Fuller
CHKL-ify this condition, and expand the comment about it.
273
		 */
274
		if(CHKL(IgnoreTransientL)) {
556.1.17 by Matthew Fuller
Move all these transient-handling bits together.
275
			tmp_win->istransient = false;
276
		}
277
	}
278
556.1.11 by Matthew Fuller
Add some comments/whitespace to the beginning bits of the func to
279
702.1.4 by Matthew Fuller
Conditionalize a bunch of the session bits.
280
#ifdef SESSION
556.1.11 by Matthew Fuller
Add some comments/whitespace to the beginning bits of the func to
281
	/*
282
	 * Look up saved X Session info for the window if we have it.
283
	 */
556.1.6 by Matthew Fuller
Warp an inner scope around the GetWindowConfig block and do a little
284
	{
556.1.7 by Matthew Fuller
Pull vars only used in the saved-session bits into that scope.
285
		short saved_x, saved_y;
286
		unsigned short saved_width, saved_height;
287
		bool width_ever_changed_by_user;
288
		bool height_ever_changed_by_user;
289
556.1.6 by Matthew Fuller
Warp an inner scope around the GetWindowConfig block and do a little
290
		if(GetWindowConfig(tmp_win,
291
		                   &saved_x, &saved_y, &saved_width, &saved_height,
292
		                   &restore_iconified, &restore_icon_info_present,
293
		                   &restore_icon_x, &restore_icon_y,
294
		                   &width_ever_changed_by_user,
295
		                   &height_ever_changed_by_user,
296
		                   &saved_occupation)) {
297
			/* Got saved info, use it */
298
			restoredFromPrevSession = true;
299
300
			tmp_win->attr.x = saved_x;
301
			tmp_win->attr.y = saved_y;
302
303
			tmp_win->widthEverChangedByUser = width_ever_changed_by_user;
304
			tmp_win->heightEverChangedByUser = height_ever_changed_by_user;
305
306
			if(width_ever_changed_by_user) {
307
				tmp_win->attr.width = saved_width;
308
			}
309
310
			if(height_ever_changed_by_user) {
311
				tmp_win->attr.height = saved_height;
312
			}
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
313
		}
556.1.5 by Matthew Fuller
Slightly reorganize codeflow to let me split an if/else into two if's
314
	}
702.1.4 by Matthew Fuller
Conditionalize a bunch of the session bits.
315
#endif
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
316
556.1.11 by Matthew Fuller
Add some comments/whitespace to the beginning bits of the func to
317
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
318
	/*
556.1.20 by Matthew Fuller
Update comments/whitespace.
319
	 * Clip window to maximum size (either built-in ceiling, or
320
	 * config MaxWindowSize).
321
	 *
322
	 * Should look at window gravity?
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
323
	 */
324
	if(tmp_win->attr.width > Scr->MaxWindowWidth) {
325
		tmp_win->attr.width = Scr->MaxWindowWidth;
326
	}
327
	if(tmp_win->attr.height > Scr->MaxWindowHeight) {
328
		tmp_win->attr.height = Scr->MaxWindowHeight;
329
	}
330
556.1.12 by Matthew Fuller
Comment WM_HINTS block.
331
332
	/*
557.1.1 by Matthew Fuller
Add faked up wmhints in the case where we don't get any at all.
333
	 * Setup WM_HINTS bits.  If we get nothing, we hardcode an
334
	 * assumption.
556.1.12 by Matthew Fuller
Comment WM_HINTS block.
335
	 */
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
336
	tmp_win->wmhints = XGetWMHints(dpy, tmp_win->w);
557.1.1 by Matthew Fuller
Add faked up wmhints in the case where we don't get any at all.
337
	if(!tmp_win->wmhints) {
557.1.4 by Matthew Fuller
Move creating the synthetic hints into a function so we can reuse it.
338
		tmp_win->wmhints = gen_synthetic_wmhints(tmp_win);
557.1.1 by Matthew Fuller
Add faked up wmhints in the case where we don't get any at all.
339
		if(!tmp_win->wmhints) {
340
			fprintf(stderr, "Failed allocating memory for hints!\n");
341
			free(tmp_win); // XXX leaky
342
			return NULL;
343
		}
344
	}
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
345
702.1.4 by Matthew Fuller
Conditionalize a bunch of the session bits.
346
#ifdef SESSION
567.2.1 by Matthew Fuller
Additional comment.
347
	/*
348
	 * Override a few bits with saved stuff from previous session, if we
349
	 * have it.
350
	 */
557.1.2 by Matthew Fuller
wmhints is always allocated now, so GC NULL tests through AddWindow().
351
	if(restore_iconified) {
352
		tmp_win->wmhints->initial_state = IconicState;
353
		tmp_win->wmhints->flags |= StateHint;
354
	}
355
356
	if(restore_icon_info_present) {
357
		tmp_win->wmhints->icon_x = restore_icon_x;
358
		tmp_win->wmhints->icon_y = restore_icon_y;
359
		tmp_win->wmhints->flags |= IconPositionHint;
360
	}
702.1.4 by Matthew Fuller
Conditionalize a bunch of the session bits.
361
#endif
557.1.2 by Matthew Fuller
wmhints is always allocated now, so GC NULL tests through AddWindow().
362
625.1.1 by Matthew Fuller
Extract the adjustment of wmhints stuff into a separate function for
363
	/* Munge as necessary for other stuff */
364
	munge_wmhints(tmp_win, tmp_win->wmhints);
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
365
366
556.1.32 by Matthew Fuller
Box-ify this.
367
	/*
368
	 * Various flags that may be screen-wide or window specific.
369
	 */
556.1.22 by Matthew Fuller
Wrap a macro around IsInList() to reduce repetition, and use it for
370
	tmp_win->highlight = Scr->Highlight && !CHKL(NoHighlight);
371
	tmp_win->stackmode = Scr->StackMode && !CHKL(NoStackModeL);
372
	tmp_win->titlehighlight = Scr->TitleHighlight && !CHKL(NoTitleHighlight);
556.1.24 by Matthew Fuller
Slightly compact setting these two values, and move them earlier.
373
	tmp_win->AlwaysSqueezeToGravity = Scr->AlwaysSqueezeToGravity
374
	                                  || CHKL(AlwaysSqueezeToGravityL);
556.1.47 by Matthew Fuller
Move these ultra-simple ones up with the other pretty-damn-simple
375
	tmp_win->DontSetInactive = CHKL(DontSetInactive);
376
	tmp_win->AutoSqueeze = CHKL(AutoSqueeze);
556.1.24 by Matthew Fuller
Slightly compact setting these two values, and move them earlier.
377
	tmp_win->StartSqueezed =
378
#ifdef EWMH
379
	        (tmp_win->ewmhFlags & EWMH_STATE_SHADED) ||
380
#endif /* EWMH */
381
	        CHKL(StartSqueezed);
556.1.22 by Matthew Fuller
Wrap a macro around IsInList() to reduce repetition, and use it for
382
383
	tmp_win->auto_raise = Scr->AutoRaiseDefault || CHKL(AutoRaise);
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
384
	if(tmp_win->auto_raise) {
385
		Scr->NumAutoRaises++;
386
	}
387
556.1.22 by Matthew Fuller
Wrap a macro around IsInList() to reduce repetition, and use it for
388
	tmp_win->auto_lower = Scr->AutoLowerDefault || CHKL(AutoLower);
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
389
	if(tmp_win->auto_lower) {
390
		Scr->NumAutoLowers++;
391
	}
392
556.1.46 by Matthew Fuller
Move setting these Opaque{Move,Resize} flags up with the other simple
393
	tmp_win->OpaqueMove = Scr->DoOpaqueMove;
394
	if(CHKL(OpaqueMoveList)) {
395
		tmp_win->OpaqueMove = true;
396
	}
397
	else if(CHKL(NoOpaqueMoveList)) {
398
		tmp_win->OpaqueMove = false;
399
	}
400
401
	tmp_win->OpaqueResize = Scr->DoOpaqueResize;
402
	if(CHKL(OpaqueResizeList)) {
403
		tmp_win->OpaqueResize = true;
404
	}
405
	else if(CHKL(NoOpaqueResizeList)) {
406
		tmp_win->OpaqueResize = false;
407
	}
408
556.1.24 by Matthew Fuller
Slightly compact setting these two values, and move them earlier.
409
556.1.30 by Matthew Fuller
Rewrite the iconify_by_unmapping setting to be a little more explicit
410
	/*
411
	 * If a window is listed in IconifyByUnmapping {}, we always iconify
556.1.31 by Matthew Fuller
Tweak comment.
412
	 * by unmapping.  Else, if it's DontIconifyByUnmapping {} or is an
413
	 * icon manager, we don't i_b_u.  Else, we go with the Scr-wide
414
	 * default.
556.1.30 by Matthew Fuller
Rewrite the iconify_by_unmapping setting to be a little more explicit
415
	 */
416
	{
417
		bool ibum = CHKL(IconifyByUn);
418
		if(!ibum) {
419
			if(tmp_win->isiconmgr || CHKL(DontIconify)) {
420
				ibum = false; // redundant
421
			}
422
			else {
423
				ibum = Scr->IconifyByUnmapping;
424
			}
425
		}
426
		tmp_win->iconify_by_unmapping = ibum;
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
427
	}
428
429
556.1.33 by Matthew Fuller
Move UBMFA setting all together and comment.
430
	/*
431
	 * For transient windows or group members, we copy in UBMFA from its
432
	 * parent/leader/etc if we can find it.  Otherwise, it's just whether
433
	 * it's in the config list.
434
	 */
435
	tmp_win->UnmapByMovingFarAway = CHKL(UnmapByMovingFarAway);
492.2.75 by Matthew Fuller
Convert a bunch of boolean flags in the TwmWindow structure
436
	if(tmp_win->istransient || tmp_win->group) {
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
437
		TwmWindow *t = NULL;
492.2.75 by Matthew Fuller
Convert a bunch of boolean flags in the TwmWindow structure
438
		if(tmp_win->istransient) {
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
439
			t = GetTwmWindow(tmp_win->transientfor);
440
		}
441
		if(!t && tmp_win->group) {
442
			t = GetTwmWindow(tmp_win->group);
443
		}
444
		if(t) {
445
			tmp_win->UnmapByMovingFarAway = t->UnmapByMovingFarAway;
446
		}
447
	}
556.1.28 by Matthew Fuller
Whitespace.
448
556.1.33 by Matthew Fuller
Move UBMFA setting all together and comment.
449
556.1.34 by Matthew Fuller
Rewrite the conditional for linking in the Ring. Use CHKL()'s instead
450
	/*
451
	 * Link it up into the window ring if we should.  If it's in
452
	 * WindowRing {}, we should.  Otherwise, we shouldn't unless
453
	 * WindowRingAll is set.  If it is, we still exclude several special
454
	 * ctwm windows, stuff in WindowRingExclude {}, and some special EWMH
455
	 * settings.
456
	 */
457
	if(CHKL(WindowRingL) ||
458
	                (Scr->WindowRingAll && !tmp_win->iswspmgr
459
	                 && !tmp_win->isiconmgr
302.1.39 by Olaf 'Rhialto' Seibert
Add some support for NET_WM_WINDOW_TYPE : NET_WM_WINDOW_TYPE_DESKTOP
460
#ifdef EWMH
556.1.34 by Matthew Fuller
Rewrite the conditional for linking in the Ring. Use CHKL()'s instead
461
	                 && EwmhOnWindowRing(tmp_win)
302.1.39 by Olaf 'Rhialto' Seibert
Add some support for NET_WM_WINDOW_TYPE : NET_WM_WINDOW_TYPE_DESKTOP
462
#endif /* EWMH */
556.1.34 by Matthew Fuller
Rewrite the conditional for linking in the Ring. Use CHKL()'s instead
463
	                 && !CHKL(WindowRingExcludeL))) {
675.1.2 by Olaf 'Rhialto' Seibert
Factor out AddWindowToRing() and UnlinkWindowFromRing().
464
		AddWindowToRing(tmp_win);
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
465
	}
466
	else {
675.1.7 by Olaf 'Rhialto' Seibert
Move the window ring functions to their own file.
467
		InitWindowNotOnRing(tmp_win);
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
468
	}
469
556.1.34 by Matthew Fuller
Rewrite the conditional for linking in the Ring. Use CHKL()'s instead
470
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
471
	/*
556.1.35 by Matthew Fuller
Simplify and reduce nesting of code setting squeeze_info bits.
472
	 * Setup squeezing info.  We don't bother unless the server has Shape
612.3.12 by Matthew Fuller
Rewrap.
473
	 * available, and the window isn't in our DontSqueezeTitle list.
474
	 * Else, we do/not based on the SqueezeTitle setting.  Note that
556.1.38 by Matthew Fuller
Add extra clarification about SqueezeTitle; this slightly duplicates
475
	 * "SqueezeTitle" being specified at all squeezes everything; its
476
	 * argument list lets you set specific squeeze params for specific
477
	 * windows, but other windows still get the default.
556.1.35 by Matthew Fuller
Simplify and reduce nesting of code setting squeeze_info bits.
478
	 *
479
	 * Note that this does not have to be freed yet since it is coming
480
	 * from the screen list or from default_squeeze.  Places that change
481
	 * it [re]set squeeze_info_copied, and then the destroy handler looks
558.1.9 by Matthew Fuller
Tpyo.
482
	 * at that to determine whether to free squeeze_info.
556.1.40 by Matthew Fuller
Add a note about a strictly redundant check.
483
	 *
484
	 * XXX Technically, the HasShape test is redundant, since the config
485
	 * file parsing would never set Scr->SqueezeTitle unless HasShape
486
	 * were true anyway...
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
487
	 */
556.1.39 by Matthew Fuller
Move the conditionalization on the SqueezeTitle bool up to the outer
488
	if(HasShape && Scr->SqueezeTitle && !CHKL(DontSqueezeTitleL)) {
556.1.37 by Matthew Fuller
Use shortcut func to look up this window's info.
489
		tmp_win->squeeze_info = LookInListWin(Scr->SqueezeTitleL, tmp_win);
556.1.39 by Matthew Fuller
Move the conditionalization on the SqueezeTitle bool up to the outer
490
		if(!tmp_win->squeeze_info) {
556.1.35 by Matthew Fuller
Simplify and reduce nesting of code setting squeeze_info bits.
491
			static SqueezeInfo default_squeeze = { SIJ_LEFT, 0, 0 };
492
			tmp_win->squeeze_info = &default_squeeze;
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
493
		}
494
	}
495
556.1.35 by Matthew Fuller
Simplify and reduce nesting of code setting squeeze_info bits.
496
556.1.42 by Matthew Fuller
Comment up and CHKL-ize the border/titlebar bits.
497
	/*
498
	 * Motif WM hints are used in setting up border and titlebar bits, so
499
	 * put them in a block here to scope the MWM var.
500
	 */
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
501
	{
502
		MotifWmHints mwmHints;
492.2.41 by Matthew Fuller
bool-ify some of these local vars, that don't impact anything outside
503
		bool have_title;
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
504
505
		GetMWMHints(tmp_win->w, &mwmHints);
506
556.1.43 by Matthew Fuller
Collapse comments on border/title to a single narrative rather than
507
		/*
508
		 * Figure border bits.  These are all exclusive cases, so it
509
		 * winds up being first-match.
510
		 *
511
		 * - EWMH, MWM hints, and NoBorder{} can tell us to use none.
512
		 * - ThreeDBorderWidth means use it and no regular 2d frame_bw.
513
		 * - ClientBorderWidth tells us to use the XWindowAttributes
514
		 *   border size rather than ours.
515
		 * - Else, our BorderWidth is the [2d] border size.
516
		 *
517
		 * X-ref comments in win_decorations.c:SetBorderCursor() about
518
		 * the somewhat differing treatment of 3d vs non-3d border widths
519
		 * and their effects on the window coordinates.
520
		 */
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
521
		tmp_win->frame_bw3D = Scr->ThreeDBorderWidth;
302.1.39 by Olaf 'Rhialto' Seibert
Add some support for NET_WM_WINDOW_TYPE : NET_WM_WINDOW_TYPE_DESKTOP
522
		if(
523
#ifdef EWMH
524
		        !EwmhHasBorder(tmp_win) ||
525
#endif /* EWMH */
473.1.4 by Matthew Fuller
Let mwm_has_border() return a trivalent answer, and create a
526
		        (mwm_has_border(&mwmHints) == 0) ||
556.1.42 by Matthew Fuller
Comment up and CHKL-ize the border/titlebar bits.
527
		        CHKL(NoBorder)) {
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
528
			tmp_win->frame_bw = 0;
529
			tmp_win->frame_bw3D = 0;
530
		}
531
		else if(tmp_win->frame_bw3D != 0) {
532
			tmp_win->frame_bw = 0;
533
		}
534
		else if(Scr->ClientBorderWidth) {
535
			tmp_win->frame_bw = tmp_win->old_bw;
536
		}
537
		else {
538
			tmp_win->frame_bw = Scr->BorderWidth;
539
		}
556.1.42 by Matthew Fuller
Comment up and CHKL-ize the border/titlebar bits.
540
		bw2 = tmp_win->frame_bw * 2;  // Used repeatedly later
541
542
556.1.43 by Matthew Fuller
Collapse comments on border/title to a single narrative rather than
543
		/*
544
		 * Now, what about the titlebar?
545
		 *
546
		 * - Default to showing,
547
		 * - Then EWMH gets to say no in some special cases,
548
		 * - Then MWM can say yes/no (or refuse to say anything),
549
		 * - NoTitle (general setting) gets to override all of that,
550
		 * - Specific MakeTitle beats general NoTitle,
551
		 * - And specific NoTitle overrides MakeTitle.
552
		 */
492.2.41 by Matthew Fuller
bool-ify some of these local vars, that don't impact anything outside
553
		have_title = true;
685.1.18 by Matthew Fuller
Mark a few known dead sture that we want to leave for cleanliness or
554
		ALLOW_DEAD_STORE(have_title);
302.1.39 by Olaf 'Rhialto' Seibert
Add some support for NET_WM_WINDOW_TYPE : NET_WM_WINDOW_TYPE_DESKTOP
555
#ifdef EWMH
556
		have_title = EwmhHasTitle(tmp_win);
557
#endif /* EWMH */
473.1.4 by Matthew Fuller
Let mwm_has_border() return a trivalent answer, and create a
558
		if(mwm_sets_title(&mwmHints)) {
473.1.3 by Matthew Fuller
Use the wrappers instead of directly accessing stuff in mwmHints.
559
			have_title = mwm_has_title(&mwmHints);
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
560
		}
561
		if(Scr->NoTitlebar) {
492.2.41 by Matthew Fuller
bool-ify some of these local vars, that don't impact anything outside
562
			have_title = false;
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
563
		}
556.1.42 by Matthew Fuller
Comment up and CHKL-ize the border/titlebar bits.
564
		if(CHKL(MakeTitle)) {
492.2.41 by Matthew Fuller
bool-ify some of these local vars, that don't impact anything outside
565
			have_title = true;
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
566
		}
556.1.42 by Matthew Fuller
Comment up and CHKL-ize the border/titlebar bits.
567
		if(CHKL(NoTitle)) {
492.2.41 by Matthew Fuller
bool-ify some of these local vars, that don't impact anything outside
568
			have_title = false;
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
569
		}
570
556.1.42 by Matthew Fuller
Comment up and CHKL-ize the border/titlebar bits.
571
		/*
556.1.44 by Matthew Fuller
Improve comment a bit.
572
		 * Now mark up how big to make it.  title_height sets how tall
573
		 * the titlebar is, with magic treating 0 as "don't make a
556.1.83 by Matthew Fuller
Minor tweak and rewrap of comment.
574
		 * titlebar".  We only care about adding frame_bw and never
575
		 * frame_bw3D, since the 3d case interprets all the inner
576
		 * coordinates differently (x-ref above x-ref).
556.1.45 by Matthew Fuller
Move transient titlebar handling up with the other title bits.
577
		 *
578
		 * Transients may not be decorated regardless of the above
579
		 * figuring, so handle that here too.
556.1.42 by Matthew Fuller
Comment up and CHKL-ize the border/titlebar bits.
580
		 */
556.1.45 by Matthew Fuller
Move transient titlebar handling up with the other title bits.
581
		if(tmp_win->istransient && !Scr->DecorateTransients) {
582
			tmp_win->title_height = 0;
583
		}
584
		else if(have_title) {
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
585
			tmp_win->title_height = Scr->TitleHeight + tmp_win->frame_bw;
586
		}
587
		else {
588
			tmp_win->title_height = 0;
589
		}
664.1.2 by Matthew Fuller
Move setting this property down a hair, so it's outside the
590
	}
591
592
664.1.1 by Maxime Soulé
Set EWMH _NET_FRAME_EXTENTS property on windows when we adopt them, so
593
#ifdef EWMH
664.1.2 by Matthew Fuller
Move setting this property down a hair, so it's outside the
594
	/*
595
	 * Now that we know the title_height and the frame border width, we
596
	 * can set an EWMH property to tell the client how much we're adding
597
	 * around them.
598
	 */
599
	EwmhSet_NET_FRAME_EXTENTS(tmp_win);
600
#endif
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
601
602
556.1.48 by Matthew Fuller
Move the GetWindowSizeHints() up to the earlier point we can call it,
603
	/*
604
	 * Need the GetWindowAttributes() call and setting ->old_bw and
605
	 * ->frame_bw3D for some of the math in looking up the
606
	 *  WM_NORMAL_HINTS bits, so now we can do that.
607
	 */
608
	GetWindowSizeHints(tmp_win);
609
610
611
	/* Maybe we're ordering it to start off iconified? */
612
	if(CHKL(StartIconified)) {
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
613
		tmp_win->wmhints->initial_state = IconicState;
614
		tmp_win->wmhints->flags |= StateHint;
615
	}
616
617
556.1.49 by Matthew Fuller
Comment up the next few bits. Significantly expand comment as we get
618
	/*
619
	 * Figure gravity bits.  When restoring from a previous session, we
620
	 * always use NorthWest gravity.
621
	 */
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
622
	if(restoredFromPrevSession) {
623
		gravx = gravy = -1;
624
	}
625
	else {
626
		GetGravityOffsets(tmp_win, &gravx, &gravy);
627
	}
628
556.1.49 by Matthew Fuller
Comment up the next few bits. Significantly expand comment as we get
629
556.1.77 by Matthew Fuller
Clean up CHKL macro once we're done with it.
630
	/* So far that's the end of where we're using this */
631
#undef CHKL
632
556.1.49 by Matthew Fuller
Comment up the next few bits. Significantly expand comment as we get
633
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
634
	/*
556.1.49 by Matthew Fuller
Comment up the next few bits. Significantly expand comment as we get
635
	 * Now we start getting more into the active bits of things.  Start
636
	 * figuring out how we'll decide where to position it.  ask_user is
637
	 * slightly misnamed, as it doesn't actually mean ask the user, but
638
	 * rather whether the user/WM gets to choose or whether the
639
	 * application does.  That is, we only case about whether or not
640
	 * RandomPlacement if(ask_user==true) anyway.  ask_user=false means
641
	 * we just go with what's in the window's XWindowAttributes bits.
642
	 *
643
	 * We don't even consider overriding the window if:
644
	 *
645
	 * - It's a transient, or
646
	 * - the WM_NORMAL_HINTS property gave us a user-specified position
647
	 *   (USPosition), or
648
	 * - the hints gave us a a program-specific position (PPosition), and
649
	 *   the UsePPosition config param specifies we should use it.
650
	 *
651
	 * x-ref ICCCM discussion of WM_NORMAL_HINTS for some details on the
652
	 * flags
653
	 * (https://www.x.org/releases/X11R7.7/doc/xorg-docs/icccm/icccm.html#Client_Properties)
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
654
	 */
492.2.91 by Matthew Fuller
Track down a bunch more boolean vars, and make them bool.
655
	ask_user = true;
556.1.49 by Matthew Fuller
Comment up the next few bits. Significantly expand comment as we get
656
	if(tmp_win->istransient) {
657
		ask_user = false;
658
	}
659
	else if(tmp_win->hints.flags & USPosition) {
660
		ask_user = false;
661
	}
662
	else if(tmp_win->hints.flags & PPosition) {
663
		if(Scr->UsePPosition == PPOS_ON) {
664
			ask_user = false;
665
		}
666
		else if(Scr->UsePPosition == PPOS_NON_ZERO
667
		                && (tmp_win->attr.x != 0 || tmp_win->attr.y != 0)) {
668
			ask_user = false;
669
		}
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
670
	}
671
672
673
	/*
556.1.52 by Matthew Fuller
Comment occupation setting. Initializing saved_occupation lets us
674
	 * Set the window occupation.  If we pulled previous Session info,
675
	 * saved_occupation may have data from it that will be used;
676
	 * otherwise it's already zeroed and has no effect.  X-ref XXX
558.1.1 by Matthew Fuller
Tweak comment for understandability.
677
	 * comment on SetupOccupation() for notes on order of application of
678
	 * various sources for occupation.
556.1.52 by Matthew Fuller
Comment occupation setting. Initializing saved_occupation lets us
679
	 *
680
	 * Note that SetupOccupation() may update tmp_win->{parent_,}vs if
681
	 * needed to make the window visible in another vscreen.  It may also
682
	 * set tmp_win->vs to NULL if it has no occupation in the current
683
	 * workspace.
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
684
	 */
556.1.52 by Matthew Fuller
Comment occupation setting. Initializing saved_occupation lets us
685
	SetupOccupation(tmp_win, saved_occupation);
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
686
687
700.1.8 by Matthew Fuller
ifdef away all the winbox setup stuff in add_window.c
688
#ifdef WINBOX
556.1.53 by Matthew Fuller
Comment up the next few steps.
689
	/* Does it go in a window box? */
690
	winbox = findWindowBox(tmp_win);
700.1.8 by Matthew Fuller
ifdef away all the winbox setup stuff in add_window.c
691
#endif
556.1.53 by Matthew Fuller
Comment up the next few steps.
692
693
556.1.84 by Matthew Fuller
Add a little to the a comment about some seemingly-redundant code.
694
	/*
558.1.18 by Matthew Fuller
#if 0 out the early frame_{width,height} setting, and update the
695
	 * Set some values for the frame size.
696
	 *
697
	 * These get redone down below when we create the frame, when they're
698
	 * actually useful.  So why bother here?  There is some code down in
699
	 * the block where we prompt for a window position that calls some
700
	 * functions that need plausible values in them.  However, those code
701
	 * blocks calculate and set values themselves, so there shouldn't be
702
	 * any actual need for them here.  Left #if'd out for the present in
703
	 * case something turns up; this should be GC'd at some point if
704
	 * nothing does.
556.1.84 by Matthew Fuller
Add a little to the a comment about some seemingly-redundant code.
705
	 */
558.1.18 by Matthew Fuller
#if 0 out the early frame_{width,height} setting, and update the
706
#if 0
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
707
	tmp_win->frame_width  = tmp_win->attr.width  + 2 * tmp_win->frame_bw3D;
708
	tmp_win->frame_height = tmp_win->attr.height + 2 * tmp_win->frame_bw3D +
709
	                        tmp_win->title_height;
710
	ConstrainSize(tmp_win, &tmp_win->frame_width, &tmp_win->frame_height);
558.1.18 by Matthew Fuller
#if 0 out the early frame_{width,height} setting, and update the
711
#endif
556.1.53 by Matthew Fuller
Comment up the next few steps.
712
713
714
	/*
715
	 * See if there's a WindowRegion we should honor.  If so, it'll set
716
	 * the X/Y coords, and we'll want to accept them instead of doing our
717
	 * own (or the user's) positioning.
718
	 *
719
	 * This needs the frame_{width,height}.
720
	 */
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
721
	if(PlaceWindowInRegion(tmp_win, &(tmp_win->attr.x), &(tmp_win->attr.y))) {
492.2.91 by Matthew Fuller
Track down a bunch more boolean vars, and make them bool.
722
		ask_user = false;
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
723
	}
556.1.53 by Matthew Fuller
Comment up the next few steps.
724
725
726
	/*
727
	 * Maybe we have WindowGeometries {} set for it?  If so, we'll take
728
	 * that as our specifics too.
729
	 */
556.1.54 by Matthew Fuller
Rework the flow in WindowGeometries checking here to avoid walking the
730
	{
731
		char *geom = LookInListWin(Scr->WindowGeometries, tmp_win);
732
		if(geom) {
614.1.23 by Maxime Soulé
Some geometries can be relative to a monitor
733
			int mask = RLayoutXParseGeometry(Scr->Layout, geom,
734
			                                 &tmp_win->attr.x, &tmp_win->attr.y,
735
			                                 (unsigned int *) &tmp_win->attr.width,
736
			                                 (unsigned int *) &tmp_win->attr.height);
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
737
556.1.54 by Matthew Fuller
Rework the flow in WindowGeometries checking here to avoid walking the
738
			if(mask & XNegative) {
739
				tmp_win->attr.x += Scr->rootw - tmp_win->attr.width;
740
			}
741
			if(mask & YNegative) {
742
				tmp_win->attr.y += Scr->rooth - tmp_win->attr.height;
743
			}
744
			ask_user = false;
745
		}
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
746
	}
747
556.1.56 by Matthew Fuller
Comment next couple blocks, including the giant block of acutally
748
749
	/* Figure up what root window we should be working in */
556.1.55 by Matthew Fuller
Don't abuse the vs var as a temporary var here, just use the full name
750
	if(tmp_win->parent_vs) {
751
		vroot = tmp_win->parent_vs->window;
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
752
	}
753
	else {
754
		vroot = Scr->Root;      /* never */
755
		tmp_win->parent_vs = Scr->currentvs;
756
	}
700.1.8 by Matthew Fuller
ifdef away all the winbox setup stuff in add_window.c
757
#ifdef WINBOX
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
758
	if(winbox) {
759
		vroot = winbox->window;
760
	}
700.1.8 by Matthew Fuller
ifdef away all the winbox setup stuff in add_window.c
761
#endif
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
762
556.1.56 by Matthew Fuller
Comment next couple blocks, including the giant block of acutally
763
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
764
	/*
556.1.56 by Matthew Fuller
Comment next couple blocks, including the giant block of acutally
765
	 * Handle positioning of the window.  If we're very early in startup
766
	 * (setting up ctwm's own windows, taking over windows already on the
767
	 * screen), or restoring defined session stuff, or otherwise
768
	 * ask_user=false'd above, we just take the already set position
769
	 * info.  Otherwise, we handle it via RandomPlacement or user outline
770
	 * setting.
771
	 *
772
	 * XXX Somebody should go through these blocks in more detail,
773
	 * they're sure to need further cleaning and commenting.  IWBNI they
774
	 * could be encapsulated well enough to move out into separate
775
	 * functions, for extra readability...
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
776
	 */
777
	if(HandlingEvents && ask_user && !restoredFromPrevSession) {
778
		if((Scr->RandomPlacement == RP_ALL) ||
779
		                ((Scr->RandomPlacement == RP_UNMAPPED) &&
557.1.2 by Matthew Fuller
wmhints is always allocated now, so GC NULL tests through AddWindow().
780
		                 ((tmp_win->wmhints->initial_state == IconicState) ||
558.1.2 by Matthew Fuller
Move these comments inside the blocks.
781
		                  (! visible(tmp_win))))) {
558.1.15 by Matthew Fuller
make indent
782
			/* just stick it somewhere */
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
783
784
#ifdef DEBUG
785
			fprintf(stderr,
786
			        "DEBUG[RandomPlacement]: win: %dx%d+%d+%d, screen: %dx%d, title height: %d, random: +%d+%d\n",
787
			        tmp_win->attr.width, tmp_win->attr.height,
788
			        tmp_win->attr.x, tmp_win->attr.y,
789
			        Scr->rootw, Scr->rooth,
790
			        tmp_win->title_height,
791
			        PlaceX, PlaceY);
792
#endif
793
794
			/* Initiallise PlaceX and PlaceY */
795
			if(PlaceX < 0 && PlaceY < 0) {
796
				if(Scr->RandomDisplacementX >= 0) {
797
					PlaceX = Scr->BorderLeft + 5;
798
				}
799
				else {
800
					PlaceX = Scr->rootw - tmp_win->attr.width - Scr->BorderRight - 5;
801
				}
802
				if(Scr->RandomDisplacementY >= 0) {
803
					PlaceY = Scr->BorderTop + 5;
804
				}
805
				else
806
					PlaceY = Scr->rooth - tmp_win->attr.height - tmp_win->title_height
807
					         - Scr->BorderBottom - 5;
808
			}
809
810
			/* For a positive horizontal displacement, if the right edge
811
			   of the window would fall outside of the screen, start over
812
			   by placing the left edge of the window 5 pixels inside
813
			   the left edge of the screen.*/
814
			if(Scr->RandomDisplacementX >= 0
815
			                && (PlaceX + tmp_win->attr.width
816
			                    > Scr->rootw - Scr->BorderRight - 5)) {
817
				PlaceX = Scr->BorderLeft + 5;
818
			}
819
820
			/* For a negative horizontal displacement, if the left edge
821
			   of the window would fall outside of the screen, start over
822
			   by placing the right edge of the window 5 pixels inside
823
			   the right edge of the screen.*/
824
			if(Scr->RandomDisplacementX < 0 && PlaceX < Scr->BorderLeft + 5) {
825
				PlaceX = Scr->rootw - tmp_win->attr.width - Scr->BorderRight - 5;
826
			}
827
828
			/* For a positive vertical displacement, if the bottom edge
829
			   of the window would fall outside of the screen, start over
830
			   by placing the top edge of the window 5 pixels inside the
831
			   top edge of the screen.  Because we add the title height
832
			   further down, we need to count with it here as well.  */
833
			if(Scr->RandomDisplacementY >= 0
834
			                && (PlaceY + tmp_win->attr.height + tmp_win->title_height
835
			                    > Scr->rooth - Scr->BorderBottom - 5)) {
836
				PlaceY = Scr->BorderTop + 5;
837
			}
838
839
			/* For a negative vertical displacement, if the top edge of
840
			   the window would fall outside of the screen, start over by
841
			   placing the bottom edge of the window 5 pixels inside the
842
			   bottom edge of the screen.  Because we add the title height
843
			   further down, we need to count with it here as well.  */
844
			if(Scr->RandomDisplacementY < 0 && PlaceY < Scr->BorderTop + 5)
845
				PlaceY = Scr->rooth - tmp_win->attr.height - tmp_win->title_height
846
				         - Scr->BorderBottom - 5;
847
848
			/* Assign the current random placement to the new window, as
849
			   a preliminary measure.  Add the title height so things will
850
			   look right.  */
851
			tmp_win->attr.x = PlaceX;
852
			tmp_win->attr.y = PlaceY + tmp_win->title_height;
853
854
			/* If the window is not supposed to move off the screen, check
855
			   that it's still within the screen, and if not, attempt to
856
			   correct the situation. */
857
			if(Scr->DontMoveOff) {
858
				int available;
859
860
#ifdef DEBUG
861
				fprintf(stderr,
862
				        "DEBUG[DontMoveOff]: win: %dx%d+%d+%d, screen: %dx%d, bw2: %d, bw3D: %d\n",
863
				        tmp_win->attr.width, tmp_win->attr.height,
864
				        tmp_win->attr.x, tmp_win->attr.y,
865
				        Scr->rootw, Scr->rooth,
866
				        bw2, tmp_win->frame_bw3D);
867
#endif
868
869
				/* If the right edge of the window is outside the right edge
870
				   of the screen, we need to move the window left.  Note that
871
				   this can only happen with windows that are less than 50
872
				   pixels less wide than the screen. */
873
				if((tmp_win->attr.x + tmp_win->attr.width)  > Scr->rootw) {
874
					available = Scr->rootw - tmp_win->attr.width
707 by Maxime Soulé
Fixup window placement with DontMoveOff + 3d borders.
875
					            - 2 * tmp_win->frame_bw3D - bw2;
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
876
877
#ifdef DEBUG
878
					fprintf(stderr, "DEBUG[DontMoveOff]: availableX: %d\n",
879
					        available);
880
#endif
881
882
					/* If the window is wider than the screen or exactly the width
883
					 of the screen, the availability is exactly 0.  The result
884
					 will be to have the window placed as much to the left as
885
					 possible. */
886
					if(available <= 0) {
887
						available = 0;
888
					}
889
890
					/* Place the window exactly between the left and right edge of
891
					 the screen when possible.  If available was originally less
892
					 than zero, it means the window's left edge will be against
893
					 the screen's left edge, and the window's right edge will be
894
					 outside the screen.  */
895
					tmp_win->attr.x = available / 2;
896
				}
897
898
				/* If the bottom edge of the window is outside the bottom edge
899
				   of the screen, we need to move the window up.  Note that
900
				   this can only happen with windows that are less than 50
901
				   pixels less tall than the screen.  Don't forget to count
902
				   with the title height and the frame widths.  */
903
				if((tmp_win->attr.y + tmp_win->attr.height)  > Scr->rooth) {
904
					available = Scr->rooth - tmp_win->attr.height
707 by Maxime Soulé
Fixup window placement with DontMoveOff + 3d borders.
905
					            - tmp_win->title_height
906
					            - 2 * tmp_win->frame_bw3D - bw2;
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
907
908
#ifdef DEBUG
909
					fprintf(stderr, "DEBUG[DontMoveOff]: availableY: %d\n",
910
					        available);
911
#endif
912
913
					/* If the window is taller than the screen or exactly the
914
					 height of the screen, the availability is exactly 0.
915
					 The result will be to have the window placed as much to
916
					 the top as possible. */
917
					if(available <= 0) {
918
						available = 0;
919
					}
920
921
					/* Place the window exactly between the top and bottom edge of
922
					 the screen when possible.  If available was originally less
923
					 than zero, it means the window's top edge will be against
924
					 the screen's top edge, and the window's bottom edge will be
925
					 outside the screen.  Again, don't forget to add the title
926
					 height.  */
927
					tmp_win->attr.y = available / 2 + tmp_win->title_height;
928
				}
929
930
#ifdef DEBUG
931
				fprintf(stderr,
932
				        "DEBUG[DontMoveOff]: win: %dx%d+%d+%d, screen: %dx%d\n",
933
				        tmp_win->attr.width, tmp_win->attr.height,
934
				        tmp_win->attr.x, tmp_win->attr.y,
935
				        Scr->rootw, Scr->rooth);
936
#endif
937
			}
938
939
			/* We know that if the window's left edge has moved compared to
940
			   PlaceX, it will have moved to the left.  If it was moved less
941
			   than 15 pixel either way, change the next "random position"
942
			   30 pixels down and right. */
943
			if(PlaceX - tmp_win->attr.x < 15
944
			                || PlaceY - (tmp_win->attr.y - tmp_win->title_height) < 15) {
945
				PlaceX += Scr->RandomDisplacementX;
946
				PlaceY += Scr->RandomDisplacementY;
947
			}
948
492.2.66 by Matthew Fuller
This var is only used internally, so it's an easy bool conversion.
949
			random_placed = true;
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
950
		}
558.1.16 by Matthew Fuller
There's nothing inside this else{} but an if{}, so just make it an
951
		else if(!(tmp_win->wmhints->flags & StateHint &&
558.1.17 by Matthew Fuller
make indent
952
		                tmp_win->wmhints->initial_state == IconicState)) {
558.1.14 by Matthew Fuller
Pull comment down to next line.
953
			/* else prompt */
558.1.17 by Matthew Fuller
make indent
954
			bool firsttime = true;
955
			int found = 0;
956
			int width, height;
957
			XEvent event;
958
959
			/* better wait until all the mouse buttons have been
960
			 * released.
961
			 */
962
			while(1) {
963
				unsigned int qpmask;
964
				Window qproot;
965
				int stat;
966
967
				XUngrabServer(dpy);
968
				XSync(dpy, 0);
969
				XGrabServer(dpy);
970
971
				qpmask = 0;
972
				if(!XQueryPointer(dpy, Scr->Root, &qproot,
973
				                  &JunkChild, &JunkX, &JunkY,
974
				                  &AddingX, &AddingY, &qpmask)) {
502.1.7 by Matthew Fuller
Use a real var instead of the Junk here for a value we're actually
975
					qpmask = 0;
558.1.17 by Matthew Fuller
make indent
976
				}
977
978
				/* Clear out any but the Button bits */
979
				qpmask &= (Button1Mask | Button2Mask | Button3Mask |
980
				           Button4Mask | Button5Mask);
981
982
				/*
983
				 * watch out for changing screens
984
				 */
985
				if(firsttime) {
986
					if(qproot != Scr->Root) {
987
						int scrnum;
988
						for(scrnum = 0; scrnum < NumScreens; scrnum++) {
989
							if(qproot == RootWindow(dpy, scrnum)) {
990
								break;
991
							}
992
						}
993
						if(scrnum != NumScreens) {
994
							PreviousScreen = scrnum;
995
						}
996
					}
997
					if(Scr->currentvs) {
998
						vroot = Scr->currentvs->window;
999
					}
1000
					firsttime = false;
1001
				}
700.1.8 by Matthew Fuller
ifdef away all the winbox setup stuff in add_window.c
1002
#ifdef WINBOX
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
1003
				if(winbox) {
558.1.17 by Matthew Fuller
make indent
1004
					vroot = winbox->window;
1005
				}
700.1.8 by Matthew Fuller
ifdef away all the winbox setup stuff in add_window.c
1006
#endif
558.1.17 by Matthew Fuller
make indent
1007
1008
				/*
1009
				 * wait for buttons to come up; yuck
1010
				 */
1011
				if(qpmask != 0) {
1012
					continue;
1013
				}
1014
1015
				/*
1016
				 * this will cause a warp to the indicated root
1017
				 */
1018
				stat = XGrabPointer(dpy, vroot, False,
1019
				                    ButtonPressMask | ButtonReleaseMask |
1020
				                    PointerMotionMask | PointerMotionHintMask,
1021
				                    GrabModeAsync, GrabModeAsync,
1022
				                    vroot, UpperLeftCursor, CurrentTime);
1023
				if(stat == GrabSuccess) {
1024
					break;
1025
				}
1026
			}
1027
1028
			{
1029
				XRectangle ink_rect;
1030
				XRectangle logical_rect;
1031
1032
				XmbTextExtents(Scr->SizeFont.font_set,
1033
				               tmp_win->name, namelen,
1034
				               &ink_rect, &logical_rect);
1035
				width = SIZE_HINDENT + ink_rect.width;
683 by Michael van Elst
Use SizeFont's height instead of the text's height for figuring the
1036
				height = Scr->SizeFont.height + SIZE_VINDENT * 2;
558.1.17 by Matthew Fuller
make indent
1037
1038
				XmbTextExtents(Scr->SizeFont.font_set,
1039
				               ": ", 2,  NULL, &logical_rect);
1040
				Scr->SizeStringOffset = width + logical_rect.width;
1041
			}
1042
614.1.28 by Maxime Soulé
If CenterFeedbackWindow, feedback window centered in current monitor
1043
			MoveResizeSizeWindow(AddingX, AddingY,
1044
			                     Scr->SizeStringOffset + Scr->SizeStringWidth + SIZE_HINDENT,
1045
			                     height);
558.1.17 by Matthew Fuller
make indent
1046
			XMapRaised(dpy, Scr->SizeWindow);
1047
			InstallRootColormap();
1048
			FB(Scr->DefaultC.fore, Scr->DefaultC.back);
1049
			XmbDrawImageString(dpy, Scr->SizeWindow, Scr->SizeFont.font_set,
1050
			                   Scr->NormalGC, SIZE_HINDENT,
1051
			                   SIZE_VINDENT + Scr->SizeFont.ascent,
1052
			                   tmp_win->name, namelen);
1053
700.1.8 by Matthew Fuller
ifdef away all the winbox setup stuff in add_window.c
1054
#ifdef WINBOX
558.1.17 by Matthew Fuller
make indent
1055
			if(winbox) {
1056
				ConstrainedToWinBox(tmp_win, AddingX, AddingY, &AddingX, &AddingY);
1057
			}
700.1.8 by Matthew Fuller
ifdef away all the winbox setup stuff in add_window.c
1058
#endif
558.1.17 by Matthew Fuller
make indent
1059
1060
			AddingW = tmp_win->attr.width + bw2 + 2 * tmp_win->frame_bw3D;
1061
			AddingH = tmp_win->attr.height + tmp_win->title_height +
1062
			          bw2 + 2 * tmp_win->frame_bw3D;
1063
			MoveOutline(vroot, AddingX, AddingY, AddingW, AddingH,
1064
			            tmp_win->frame_bw, tmp_win->title_height + tmp_win->frame_bw3D);
1065
1066
			XmbDrawImageString(dpy, Scr->SizeWindow, Scr->SizeFont.font_set,
1067
			                   Scr->NormalGC, width,
1068
			                   SIZE_VINDENT + Scr->SizeFont.ascent, ": ", 2);
1069
			DisplayPosition(tmp_win, AddingX, AddingY);
1070
558.1.18 by Matthew Fuller
#if 0 out the early frame_{width,height} setting, and update the
1071
			/*
1072
			 * The TryTo*() and DoResize() calls below rely on having
1073
			 * frame_{width,height} set, so set them.
1074
			 */
614.1.14 by Maxime Soulé
Correct outline when 3D borders not used, but BorderSize is
1075
			tmp_win->frame_width  = AddingW - bw2;
1076
			tmp_win->frame_height = AddingH - bw2;
558.1.17 by Matthew Fuller
make indent
1077
			/*SetFocus (NULL, CurrentTime);*/
1078
			while(1) {
1079
				if(Scr->OpenWindowTimeout) {
1080
					const int fd = ConnectionNumber(dpy);
1081
					while(!XCheckMaskEvent(dpy, ButtonMotionMask | ButtonPressMask, &event)) {
1082
						fd_set mask;
1083
						struct timeval timeout = {
1084
							.tv_sec  = Scr->OpenWindowTimeout,
1085
							.tv_usec = 0,
1086
						};
1087
1088
						FD_ZERO(&mask);
1089
						FD_SET(fd, &mask);
1090
						found = select(fd + 1, &mask, NULL, NULL, &timeout);
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
1091
						if(found == 0) {
1092
							break;
1093
						}
1094
					}
558.1.17 by Matthew Fuller
make indent
1095
					if(found == 0) {
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
1096
						break;
1097
					}
558.1.17 by Matthew Fuller
make indent
1098
				}
1099
				else {
1100
					found = 1;
1101
					XMaskEvent(dpy, ButtonPressMask | PointerMotionMask, &event);
1102
				}
1103
				if(event.type == MotionNotify) {
1104
					/* discard any extra motion events before a release */
1105
					while(XCheckMaskEvent(dpy,
1106
					                      ButtonMotionMask | ButtonPressMask, &event))
1107
						if(event.type == ButtonPress) {
1108
							break;
1109
						}
1110
				}
1111
				FixRootEvent(&event);
1112
				if(event.type == ButtonPress) {
1113
					AddingX = event.xbutton.x_root;
1114
					AddingY = event.xbutton.y_root;
1115
1116
					/* TryTo*() need tmp_win->frame_{width,height} */
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
1117
					TryToGrid(tmp_win, &AddingX, &AddingY);
1118
					if(Scr->PackNewWindows) {
1119
						TryToPack(tmp_win, &AddingX, &AddingY);
1120
					}
558.1.17 by Matthew Fuller
make indent
1121
1122
					/* DontMoveOff prohibits user from off-screen placement */
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
1123
					if(Scr->DontMoveOff) {
1124
						ConstrainByBorders(tmp_win, &AddingX, AddingW, &AddingY, AddingH);
1125
					}
558.1.17 by Matthew Fuller
make indent
1126
					break;
1127
				}
1128
1129
				if(event.type != MotionNotify) {
1130
					continue;
1131
				}
1132
1133
				XQueryPointer(dpy, vroot, &JunkRoot, &JunkChild,
1134
				              &JunkX, &JunkY, &AddingX, &AddingY, &JunkMask);
1135
1136
				TryToGrid(tmp_win, &AddingX, &AddingY);
1137
				if(Scr->PackNewWindows) {
1138
					TryToPack(tmp_win, &AddingX, &AddingY);
1139
				}
1140
				if(Scr->DontMoveOff) {
1141
					ConstrainByBorders(tmp_win, &AddingX, AddingW, &AddingY, AddingH);
1142
				}
1143
				MoveOutline(vroot, AddingX, AddingY, AddingW, AddingH,
1144
				            tmp_win->frame_bw, tmp_win->title_height + tmp_win->frame_bw3D);
1145
1146
				DisplayPosition(tmp_win, AddingX, AddingY);
1147
			}
1148
1149
			if(found) {
1150
				if(event.xbutton.button == Button2) {
1151
					int lastx, lasty;
1152
					XRectangle logical_rect;
1153
1154
					XmbTextExtents(Scr->SizeFont.font_set,
1155
					               ": ", 2,  NULL, &logical_rect);
1156
					Scr->SizeStringOffset = width + logical_rect.width;
1157
614.1.28 by Maxime Soulé
If CenterFeedbackWindow, feedback window centered in current monitor
1158
					MoveResizeSizeWindow(event.xbutton.x_root, event.xbutton.y_root,
1159
					                     Scr->SizeStringOffset + Scr->SizeStringWidth + SIZE_HINDENT,
1160
					                     height);
558.1.17 by Matthew Fuller
make indent
1161
1162
					XmbDrawImageString(dpy, Scr->SizeWindow, Scr->SizeFont.font_set,
1163
					                   Scr->NormalGC, width,
1164
					                   SIZE_VINDENT + Scr->SizeFont.ascent, ": ", 2);
1165
1166
					if(0/*Scr->AutoRelativeResize*/) {
1167
						int dx = (tmp_win->attr.width / 4);
1168
						int dy = (tmp_win->attr.height / 4);
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
1169
1170
#define HALF_AVE_CURSOR_SIZE 8          /* so that it is visible */
558.1.17 by Matthew Fuller
make indent
1171
						if(dx < HALF_AVE_CURSOR_SIZE + Scr->BorderLeft) {
1172
							dx = HALF_AVE_CURSOR_SIZE + Scr->BorderLeft;
1173
						}
1174
						if(dy < HALF_AVE_CURSOR_SIZE + Scr->BorderTop) {
1175
							dy = HALF_AVE_CURSOR_SIZE + Scr->BorderTop;
1176
						}
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
1177
#undef HALF_AVE_CURSOR_SIZE
558.1.17 by Matthew Fuller
make indent
1178
						dx += (tmp_win->frame_bw + 1);
1179
						dy += (bw2 + tmp_win->title_height + 1);
1180
						if(AddingX + dx >= Scr->rootw - Scr->BorderRight) {
1181
							dx = Scr->rootw - Scr->BorderRight - AddingX - 1;
1182
						}
1183
						if(AddingY + dy >= Scr->rooth - Scr->BorderBottom) {
1184
							dy = Scr->rooth - Scr->BorderBottom - AddingY - 1;
1185
						}
1186
						if(dx > 0 && dy > 0) {
1187
							XWarpPointer(dpy, None, None, 0, 0, 0, 0, dx, dy);
1188
						}
1189
					}
1190
					else {
1191
						XWarpPointer(dpy, None, vroot, 0, 0, 0, 0,
1192
						             AddingX + AddingW / 2, AddingY + AddingH / 2);
1193
					}
1194
					AddStartResize(tmp_win, AddingX, AddingY, AddingW, AddingH);
1195
1196
					lastx = -10000;
1197
					lasty = -10000;
1198
					while(1) {
1199
						XMaskEvent(dpy,
1200
						           ButtonReleaseMask | ButtonMotionMask, &event);
1201
1202
						if(event.type == MotionNotify) {
1203
							/* discard any extra motion events before a release */
1204
							while(XCheckMaskEvent(dpy,
1205
							                      ButtonMotionMask | ButtonReleaseMask, &event))
1206
								if(event.type == ButtonRelease) {
1207
									break;
1208
								}
1209
						}
1210
						FixRootEvent(&event);
1211
1212
						if(event.type == ButtonRelease) {
1213
							AddEndResize(tmp_win);
1214
							break;
1215
						}
1216
1217
						if(event.type != MotionNotify) {
1218
							continue;
1219
						}
1220
1221
						/*
1222
						 * XXX - if we are going to do a loop, we ought to consider
1223
						 * using multiple GXxor lines so that we don't need to
1224
						 * grab the server.
1225
						 */
1226
						XQueryPointer(dpy, vroot, &JunkRoot, &JunkChild,
1227
						              &JunkX, &JunkY, &AddingX, &AddingY,
1228
						              &JunkMask);
1229
1230
						if(lastx != AddingX || lasty != AddingY) {
1231
							resizeWhenAdd = true;
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
1232
							/*
558.1.17 by Matthew Fuller
make indent
1233
							 * DR() calls SetupWindow(), which uses
1234
							 * frame_{width,height}.
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
1235
							 */
558.1.17 by Matthew Fuller
make indent
1236
							DoResize(AddingX, AddingY, tmp_win);
1237
							resizeWhenAdd = false;
1238
1239
							lastx = AddingX;
1240
							lasty = AddingY;
1241
						}
1242
1243
					}
1244
				}
1245
				else if(event.xbutton.button == Button3) {
614.1.5 by Maxime Soulé
AddWindow() + Mouse-3 now uses layout
1246
					RArea area;
1247
					int max_bottom, max_right;
1248
614.1.25 by Maxime Soulé
RArea struct is never malloc()ed anymore
1249
					area = RAreaNew(AddingX, AddingY, AddingW, AddingH);
614.1.5 by Maxime Soulé
AddWindow() + Mouse-3 now uses layout
1250
614.1.12 by Maxime Soulé
f.fill, f.pack & f.jump* functions detect inter-monitors edges
1251
					max_bottom = RLayoutFindMonitorBottomEdge(Scr->BorderedLayout, &area) - bw2;
1252
					max_right = RLayoutFindMonitorRightEdge(Scr->BorderedLayout, &area) - bw2;
558.1.17 by Matthew Fuller
make indent
1253
1254
					/*
1255
					 * Make window go to bottom of screen, and clip to right edge.
1256
					 * This is useful when popping up large windows and fixed
1257
					 * column text windows.
1258
					 */
614.1.5 by Maxime Soulé
AddWindow() + Mouse-3 now uses layout
1259
					if(AddingX + AddingW - 1 > max_right) {
1260
						AddingW = max_right - AddingX + 1;
558.1.17 by Matthew Fuller
make indent
1261
					}
614.1.5 by Maxime Soulé
AddWindow() + Mouse-3 now uses layout
1262
					AddingH = max_bottom - AddingY + 1;
558.1.17 by Matthew Fuller
make indent
1263
1264
					ConstrainSize(tmp_win, &AddingW, &AddingH);   /* w/o borders */
1265
					AddingW += bw2;
1266
					AddingH += bw2;
1267
					XMaskEvent(dpy, ButtonReleaseMask, &event);
1268
				}
1269
				else {
1270
					XMaskEvent(dpy, ButtonReleaseMask, &event);
1271
				}
1272
			}
1273
			MoveOutline(vroot, 0, 0, 0, 0, 0, 0);
1274
			XUnmapWindow(dpy, Scr->SizeWindow);
1275
			UninstallRootColormap();
1276
			XUngrabPointer(dpy, CurrentTime);
1277
1278
			tmp_win->attr.x = AddingX;
1279
			tmp_win->attr.y = AddingY + tmp_win->title_height;
1280
			tmp_win->attr.width = AddingW - bw2 - 2 * tmp_win->frame_bw3D;
1281
			tmp_win->attr.height = AddingH - tmp_win->title_height -
1282
			                       bw2 - 2 * tmp_win->frame_bw3D;
1283
1284
			XUngrabServer(dpy);
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
1285
		}
1286
	}
558.1.2 by Matthew Fuller
Move these comments inside the blocks.
1287
	else {
1288
		/*
1289
		 * Put it where asked, mod title bar.  If the gravity is towards
1290
		 * the top, move it by the title height.
1291
		 */
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
1292
		if(gravy < 0) {
1293
			tmp_win->attr.y -= gravy * tmp_win->title_height;
1294
		}
1295
	}
1296
556.1.56 by Matthew Fuller
Comment next couple blocks, including the giant block of acutally
1297
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
1298
#ifdef DEBUG
1299
	fprintf(stderr, "  position window  %d, %d  %dx%d\n",
1300
	        tmp_win->attr.x,
1301
	        tmp_win->attr.y,
1302
	        tmp_win->attr.width,
1303
	        tmp_win->attr.height);
1304
#endif
1305
556.1.57 by Matthew Fuller
Comment next couple of blocks.
1306
1307
	/*
1308
	 * Possibly need to tweak what it thinks of as its position to
1309
	 * account for borders.  XXX Verify conditionalization and math.
1310
	 */
1311
	if(!Scr->ClientBorderWidth) {
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
1312
		int delta = tmp_win->attr.border_width - tmp_win->frame_bw -
1313
		            tmp_win->frame_bw3D;
1314
		tmp_win->attr.x += gravx * delta;
1315
		tmp_win->attr.y += gravy * delta;
1316
	}
1317
556.1.57 by Matthew Fuller
Comment next couple of blocks.
1318
1319
	/*
1320
	 * Init the title width to the window's width.  This will be right as
1321
	 * long as you're not SqueezeTitle'ing; if you are, we rejigger it in
1322
	 * SetupFrame().
1323
	 */
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
1324
	tmp_win->title_width = tmp_win->attr.width;
1325
1326
556.1.59 by Matthew Fuller
Comment the last couple blocks before the point where we grab the
1327
	/*
556.1.71 by Matthew Fuller
Expand comment a little with an x-ref.
1328
	 * Figure initial screen size of writing out the window name.  This
1329
	 * is needed when laying out titlebar bits (down in the call chain
1330
	 * inside SetupFrame()).  The event handler updates this when it
1331
	 * changes.
556.1.59 by Matthew Fuller
Comment the last couple blocks before the point where we grab the
1332
	 */
556.1.70 by Matthew Fuller
Localize these rectangles used for XmbTextExtents instead of sharing
1333
	{
1334
		XRectangle logical_rect;
1335
		XmbTextExtents(Scr->TitleBarFont.font_set, tmp_win->name, namelen,
1336
		               NULL, &logical_rect);
1337
		tmp_win->name_width = logical_rect.width;
1338
	}
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
1339
556.1.59 by Matthew Fuller
Comment the last couple blocks before the point where we grab the
1340
556.1.60 by Matthew Fuller
Tpyo.
1341
	/* Remove original border if there is one; we make our own now */
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
1342
	if(tmp_win->old_bw) {
1343
		XSetWindowBorderWidth(dpy, tmp_win->w, 0);
1344
	}
1345
556.1.59 by Matthew Fuller
Comment the last couple blocks before the point where we grab the
1346
556.1.63 by Matthew Fuller
Move the color lookup bits before grabbing the server; they shouldn't
1347
	/*
1348
	 * Setup various color bits
1349
	 */
563.1.4 by Matthew Fuller
Mechanically translate all these full_name references to name.
1350
#define SETC(lst, save) GetColorFromList(Scr->lst, tmp_win->name, \
556.1.69 by Matthew Fuller
make indent
1351
                &tmp_win->class, &tmp_win->save)
556.1.63 by Matthew Fuller
Move the color lookup bits before grabbing the server; they shouldn't
1352
1353
	/* No distinction fore/back for borders in the lists */
558.1.3 by Matthew Fuller
Take out extraneous whitespace.
1354
	tmp_win->borderC.fore = Scr->BorderColorC.fore;
1355
	tmp_win->borderC.back = Scr->BorderColorC.back;
556.1.63 by Matthew Fuller
Move the color lookup bits before grabbing the server; they shouldn't
1356
	SETC(BorderColorL, borderC.fore);
1357
	SETC(BorderColorL, borderC.back);
1358
1359
	tmp_win->border_tile.fore = Scr->BorderTileC.fore;
1360
	tmp_win->border_tile.back = Scr->BorderTileC.back;
1361
	SETC(BorderTileForegroundL, border_tile.fore);
1362
	SETC(BorderTileBackgroundL, border_tile.back);
1363
558.1.3 by Matthew Fuller
Take out extraneous whitespace.
1364
	tmp_win->title.fore = Scr->TitleC.fore;
1365
	tmp_win->title.back = Scr->TitleC.back;
556.1.63 by Matthew Fuller
Move the color lookup bits before grabbing the server; they shouldn't
1366
	SETC(TitleForegroundL, title.fore);
556.2.2 by Matthew Fuller
Merge 556.1.63 for the move, to avoid conflicts.
1367
	SETC(TitleBackgroundL, title.back);
556.1.63 by Matthew Fuller
Move the color lookup bits before grabbing the server; they shouldn't
1368
1369
#undef SETC
1370
1371
	/* Shading on 3d bits */
1372
	if(Scr->use3Dtitles  && !Scr->BeNiceToColormap) {
1373
		GetShadeColors(&tmp_win->title);
1374
	}
1375
	if(Scr->use3Dborders && !Scr->BeNiceToColormap) {
1376
		GetShadeColors(&tmp_win->borderC);
1377
		GetShadeColors(&tmp_win->border_tile);
1378
	}
1379
1380
1381
	/*
1382
	 * Following bits are more active, and we want to make sure nothing
1383
	 * else gets to do anything with the server while we're doing it.
558.1.8 by Matthew Fuller
Comment about how I'm giving up on finding bits to pull out of the
1384
	 *
1385
	 * Minor investigations seems to suggest we could pull a number of
1386
	 * these things out (mostly to later, but probably some to earlier)
1387
	 * so we keep the server grabbed for a shorter period of time.  I'm
1388
	 * not putting significant effort into finding out what we could pull
1389
	 * out because it's already plenty fast, but there is probably fruit
1390
	 * that could be plucked if somebody finds it not so.
556.1.63 by Matthew Fuller
Move the color lookup bits before grabbing the server; they shouldn't
1391
	 */
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
1392
	XGrabServer(dpy);
1393
556.1.65 by Matthew Fuller
Comment and whitespace up the rest of the function.
1394
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
1395
	/*
1396
	 * Make sure the client window still exists.  We don't want to leave an
1397
	 * orphan frame window if it doesn't.  Since we now have the server
1398
	 * grabbed, the window can't disappear later without having been
1399
	 * reparented, so we'll get a DestroyNotify for it.  We won't have
1400
	 * gotten one for anything up to here, however.
1401
	 */
1402
	if(XGetGeometry(dpy, tmp_win->w, &JunkRoot, &JunkX, &JunkY,
1403
	                &JunkWidth, &JunkHeight, &JunkBW, &JunkDepth) == 0) {
675.1.2 by Olaf 'Rhialto' Seibert
Factor out AddWindowToRing() and UnlinkWindowFromRing().
1404
		UnlinkWindowFromRing(tmp_win);
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
1405
556.1.61 by Matthew Fuller
Drop a note about where we need to improve the snot out of cleanup.
1406
		/* XXX Leaky as all hell */
491.1.11 by Matthew Fuller
Stop casting arg to free(), especially to char *.
1407
		free(tmp_win);
1 by Claude Lecommandeur
CTWM version 1.1
1408
		XUngrabServer(dpy);
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
1409
		return(NULL);
1410
	}
1411
556.1.65 by Matthew Fuller
Comment and whitespace up the rest of the function.
1412
1413
	/* Link the window into our list of all the TwmWindow's */
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
1414
	tmp_win->next = Scr->FirstWindow;
1415
	if(Scr->FirstWindow != NULL) {
1416
		Scr->FirstWindow->prev = tmp_win;
1417
	}
1418
	tmp_win->prev = NULL;
1419
	Scr->FirstWindow = tmp_win;
1420
556.1.62 by Matthew Fuller
Add a little whitespacing and comments, and use some macros to make
1421
556.1.65 by Matthew Fuller
Comment and whitespace up the rest of the function.
1422
1423
	/*
1424
	 * Start creating the other X windows we wrap around it for
1425
	 * decorations.  X-ref discussion in win_decorations.c for the
1426
	 * details of what they all are and why they're there.
1427
	 *
1428
	 * XXX Good candidate for moving out into a helper function...
1429
	 */
1430
1431
1432
	/*
1433
	 * First, the frame
1434
	 */
556.1.72 by Matthew Fuller
Stick setting up the frame in its own scope and rewrap as necessary.
1435
	{
556.1.74 by Matthew Fuller
Pull these valuemask/attributes vars into the local scopes where
1436
		unsigned long valuemask;
1437
		XSetWindowAttributes attributes;
1438
556.1.79 by Matthew Fuller
Comment and slightly reorganize the bits for creating the frame
1439
		/*
1440
		 * Figure size/position.
1441
		 */
556.1.72 by Matthew Fuller
Stick setting up the frame in its own scope and rewrap as necessary.
1442
		tmp_win->frame_x = tmp_win->attr.x + tmp_win->old_bw
1443
		                   - tmp_win->frame_bw - tmp_win->frame_bw3D;
1444
		tmp_win->frame_y = tmp_win->attr.y - tmp_win->title_height
1445
		                   + tmp_win->old_bw
1446
		                   - tmp_win->frame_bw - tmp_win->frame_bw3D;
556.1.86 by Matthew Fuller
Tweak spacing and order of terms on these lines so they visually
1447
		tmp_win->frame_width  = tmp_win->attr.width  + 2 * tmp_win->frame_bw3D;
1448
		tmp_win->frame_height = tmp_win->attr.height + 2 * tmp_win->frame_bw3D
1449
		                        + tmp_win->title_height;
556.1.72 by Matthew Fuller
Stick setting up the frame in its own scope and rewrap as necessary.
1450
556.1.79 by Matthew Fuller
Comment and slightly reorganize the bits for creating the frame
1451
		/* Adjust based on hints */
556.1.72 by Matthew Fuller
Stick setting up the frame in its own scope and rewrap as necessary.
1452
		ConstrainSize(tmp_win, &tmp_win->frame_width, &tmp_win->frame_height);
556.1.79 by Matthew Fuller
Comment and slightly reorganize the bits for creating the frame
1453
1454
		/*
1455
		 * Adjust as necessary to keep things on-screen.  If we [ctwm]
1456
		 * chose the position, CBB() involves checking things like
1457
		 * MoveOffResistance etc to keep it on.
1458
		 */
556.1.72 by Matthew Fuller
Stick setting up the frame in its own scope and rewrap as necessary.
1459
		if(random_placed) {
1460
			ConstrainByBorders(tmp_win, &tmp_win->frame_x, tmp_win->frame_width,
1461
			                   &tmp_win->frame_y, tmp_win->frame_height);
1462
		}
1463
556.1.79 by Matthew Fuller
Comment and slightly reorganize the bits for creating the frame
1464
		/* No matter what, make sure SOME part of the window is on-screen */
614.1.6 by Maxime Soulé
AddWindow() verification that window is visible now uses layout
1465
		{
1466
			RArea area;
1467
			int min_x, min_y, max_bottom, max_right;
708 by Matthew Fuller
Bypass BorderedLayout for strut'd windows.
1468
			const RLayout *layout = Scr->BorderedLayout;
614.1.6 by Maxime Soulé
AddWindow() verification that window is visible now uses layout
1469
614.1.25 by Maxime Soulé
RArea struct is never malloc()ed anymore
1470
			area = RAreaNew(tmp_win->frame_x, tmp_win->frame_y,
1471
			                (int)tmp_win->frame_width,
1472
			                (int)tmp_win->frame_height);
614.1.6 by Maxime Soulé
AddWindow() verification that window is visible now uses layout
1473
708 by Matthew Fuller
Bypass BorderedLayout for strut'd windows.
1474
#ifdef EWMH
1475
			// Hack: windows with EWMH struts defined are trying to
1476
			// reserve a bit of the screen for themselves.  We currently
1477
			// do that by hacking strut'ed space into the BorderedLayout,
1478
			// which is a bogus way of doing things.  But it also means
1479
			// that here we're forcing the windows to be outside their
1480
			// own struts, which is nonsensical.
1481
			//
1482
			// Hack around that by making strut'd windows just use
1483
			// Layout, rather than BorderedLayout.  This is Wrong(tm)
1484
			// because the whole point of BorderedLayout is space
1485
			// reservation by the user, which we'd now be ignoring.  Also
1486
			// just because a window has its own struts doesn't mean it
1487
			// should get to ignore everyone else's struts too. However,
1488
			// this is at least consistent with pre-4.1.0 behavior, so
1489
			// it's not a _new_ bug.  And forcing windows outside their
1490
			// own reservation is way stupider...
1491
			if(tmp_win->ewmhFlags & EWMH_HAS_STRUT) {
1492
				layout = Scr->Layout;
1493
			}
1494
#endif
1495
1496
			RLayoutFindTopBottomEdges(layout, &area,
614.1.26 by Maxime Soulé
Correct add-window problem
1497
			                          &min_y, &max_bottom);
708 by Matthew Fuller
Bypass BorderedLayout for strut'd windows.
1498
			RLayoutFindLeftRightEdges(layout, &area,
614.1.26 by Maxime Soulé
Correct add-window problem
1499
			                          &min_x, &max_right);
614.1.6 by Maxime Soulé
AddWindow() verification that window is visible now uses layout
1500
614.1.56 by Matthew Fuller
Drop a comment about where this seems to put things.
1501
			// These conditions would only be true if the window was
1502
			// completely off-screen; in that case, the RLayout* calls
1503
			// above would have found the closest edges to move it to.
1504
			// We wind up sticking it in the top-left of the
1505
			// bottom-right-most monitor it would touch.
614.1.6 by Maxime Soulé
AddWindow() verification that window is visible now uses layout
1506
			if(area.x > max_right || area.y > max_bottom ||
1507
			                area.x + area.width <= min_x ||
1508
			                area.y + area.height <= min_y) {
1509
				tmp_win->frame_x = min_x;
1510
				tmp_win->frame_y = min_y;
1511
			}
556.1.79 by Matthew Fuller
Comment and slightly reorganize the bits for creating the frame
1512
		}
1513
696.1.8 by Matthew Fuller
This func is purely vscreen stuff related, so we can conditionalize it
1514
#ifdef VSCREEN
556.1.79 by Matthew Fuller
Comment and slightly reorganize the bits for creating the frame
1515
		/* May need adjusting for vscreens too */
1516
		DealWithNonSensicalGeometries(dpy, vroot, tmp_win);
696.1.8 by Matthew Fuller
This func is purely vscreen stuff related, so we can conditionalize it
1517
#endif
556.1.79 by Matthew Fuller
Comment and slightly reorganize the bits for creating the frame
1518
1519
1520
		/*
1521
		 * Setup the X attributes for the frame.
1522
		 */
556.1.72 by Matthew Fuller
Stick setting up the frame in its own scope and rewrap as necessary.
1523
		valuemask = CWBackPixmap | CWBorderPixel | CWBackPixel
1524
		            | CWCursor | CWEventMask;
1525
		attributes.background_pixmap = None;
1526
		attributes.border_pixel = tmp_win->border_tile.back;
1527
		attributes.background_pixel = tmp_win->border_tile.back;
1528
		attributes.cursor = Scr->FrameCursor;
1529
		attributes.event_mask = (SubstructureRedirectMask
1530
		                         | ButtonPressMask | ButtonReleaseMask
1531
		                         | EnterWindowMask | LeaveWindowMask
1532
		                         | ExposureMask);
556.1.79 by Matthew Fuller
Comment and slightly reorganize the bits for creating the frame
1533
1534
		/*
1535
		 * If we have BorderResizeCursors, we need to know about motions
1536
		 * in the window to know when to change (e.g., for corners).
1537
		 */
556.1.72 by Matthew Fuller
Stick setting up the frame in its own scope and rewrap as necessary.
1538
		if(Scr->BorderCursors) {
1539
			attributes.event_mask |= PointerMotionMask;
1540
		}
556.1.79 by Matthew Fuller
Comment and slightly reorganize the bits for creating the frame
1541
1542
		/*
1543
		 * If the real window specified save_under or a specific gravity,
1544
		 * set them on the frame too.
1545
		 */
556.1.72 by Matthew Fuller
Stick setting up the frame in its own scope and rewrap as necessary.
1546
		if(tmp_win->attr.save_under) {
1547
			attributes.save_under = True;
1548
			valuemask |= CWSaveUnder;
1549
		}
1550
		if(tmp_win->hints.flags & PWinGravity) {
1551
			attributes.win_gravity = tmp_win->hints.win_gravity;
1552
			valuemask |= CWWinGravity;
1553
		}
1554
556.1.79 by Matthew Fuller
Comment and slightly reorganize the bits for creating the frame
1555
1556
		/* And create */
556.1.72 by Matthew Fuller
Stick setting up the frame in its own scope and rewrap as necessary.
1557
		tmp_win->frame = XCreateWindow(dpy, vroot,
1558
		                               tmp_win->frame_x, tmp_win->frame_y,
1559
		                               tmp_win->frame_width,
1560
		                               tmp_win->frame_height,
1561
		                               tmp_win->frame_bw,
1562
		                               Scr->d_depth, CopyFromParent,
1563
		                               Scr->d_visual, valuemask, &attributes);
602.1.3 by Matthew Fuller
Add conditionals for NameDecorations.
1564
		if(Scr->NameDecorations) {
1565
			XStoreName(dpy, tmp_win->frame, "CTWM frame");
1566
		}
556.1.72 by Matthew Fuller
Stick setting up the frame in its own scope and rewrap as necessary.
1567
	}
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
1568
556.1.65 by Matthew Fuller
Comment and whitespace up the rest of the function.
1569
1570
	/*
1571
	 * Next, the titlebar, if we have one
1572
	 */
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
1573
	if(tmp_win->title_height) {
556.1.74 by Matthew Fuller
Pull these valuemask/attributes vars into the local scopes where
1574
		unsigned long valuemask;
1575
		XSetWindowAttributes attributes;
556.1.80 by Matthew Fuller
Tweak/comment this block about making the titlebar window. Use some
1576
		int x, y;
556.1.74 by Matthew Fuller
Pull these valuemask/attributes vars into the local scopes where
1577
556.1.80 by Matthew Fuller
Tweak/comment this block about making the titlebar window. Use some
1578
		/*
1579
		 * We need to know about keys/buttons and exposure of the
1580
		 * titlebar, for bindings and repaining.  And leave to X server
1581
		 * bits about border/background.
1582
		 */
1583
		valuemask = (CWEventMask | CWDontPropagate
1584
		             | CWBorderPixel | CWBackPixel);
1585
		attributes.event_mask = (KeyPressMask | ButtonPressMask
1586
		                         | ButtonReleaseMask | ExposureMask);
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
1587
		attributes.do_not_propagate_mask = PointerMotionMask;
1588
		attributes.border_pixel = tmp_win->borderC.back;
1589
		attributes.background_pixel = tmp_win->title.back;
556.1.80 by Matthew Fuller
Tweak/comment this block about making the titlebar window. Use some
1590
1591
1592
		/* Create */
1593
		x = y = tmp_win->frame_bw3D - tmp_win->frame_bw;
1594
		tmp_win->title_w = XCreateWindow(dpy, tmp_win->frame, x, y,
505.1.19 by Matthew Fuller
Remove casts from XCreateWindow() calls. Some of these were probably
1595
		                                 tmp_win->attr.width,
556.1.80 by Matthew Fuller
Tweak/comment this block about making the titlebar window. Use some
1596
		                                 Scr->TitleHeight, tmp_win->frame_bw,
1597
		                                 Scr->d_depth, CopyFromParent,
1598
		                                 Scr->d_visual, valuemask, &attributes);
602.1.3 by Matthew Fuller
Add conditionals for NameDecorations.
1599
		if(Scr->NameDecorations) {
1600
			XStoreName(dpy, tmp_win->title_w, "CTWM titlebar");
1601
		}
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
1602
	}
1603
	else {
556.1.81 by Matthew Fuller
Use None instead of 0 for a Window.
1604
		tmp_win->title_w = None;
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
1605
		tmp_win->squeeze_info = NULL;
1606
	}
1607
556.1.65 by Matthew Fuller
Comment and whitespace up the rest of the function.
1608
1609
	/*
1610
	 * If we're highlighting borders on focus, we need the pixmap to do
1611
	 * it.
1612
	 *
1613
	 * XXX I'm not at all sure this can't just be global and shared, so
1614
	 * we don't have to create one per window...
1615
	 */
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
1616
	if(tmp_win->highlight) {
492.1.12 by Matthew Fuller
Switch to using our functions for building these black/gray pixmaps.
1617
		char *which;
492.1.2 by Matthew Fuller
Use temporary vars for choosing between black/gray bits, instead of
1618
1619
		if(Scr->use3Dtitles && (Scr->Monochrome != COLOR)) {
492.1.12 by Matthew Fuller
Switch to using our functions for building these black/gray pixmaps.
1620
			which = "black";
492.1.2 by Matthew Fuller
Use temporary vars for choosing between black/gray bits, instead of
1621
		}
1622
		else {
492.1.12 by Matthew Fuller
Switch to using our functions for building these black/gray pixmaps.
1623
			which = "gray";
492.1.2 by Matthew Fuller
Use temporary vars for choosing between black/gray bits, instead of
1624
		}
492.1.12 by Matthew Fuller
Switch to using our functions for building these black/gray pixmaps.
1625
		tmp_win->gray = mk_blackgray_pixmap(which, vroot,
1626
		                                    tmp_win->border_tile.fore,
1627
		                                    tmp_win->border_tile.back);
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
1628
492.2.75 by Matthew Fuller
Convert a bunch of boolean flags in the TwmWindow structure
1629
		tmp_win->hasfocusvisible = true;
492.2.2 by Matthew Fuller
Convert various exported util.c funcs to C99 bool from X Bool. This
1630
		SetFocusVisualAttributes(tmp_win, false);
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
1631
	}
1632
	else {
1633
		tmp_win->gray = None;
1634
	}
1635
556.1.65 by Matthew Fuller
Comment and whitespace up the rest of the function.
1636
1637
	/*
1638
	 * Setup OTP bits for stacking
1639
	 */
575.2.12 by Matthew Fuller
Change my mine; we won't do this here.
1640
	OtpAdd(tmp_win, WinWin);
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
1641
556.1.65 by Matthew Fuller
Comment and whitespace up the rest of the function.
1642
1643
	/*
1644
	 * Setup the stuff inside the titlebar window, if we have it.  If we
1645
	 * don't, fake up the coordinates where the titlebar would be for
1646
	 * <reasons>.
1647
	 */
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
1648
	if(tmp_win->title_w) {
1649
		ComputeTitleLocation(tmp_win);
1650
		CreateWindowTitlebarButtons(tmp_win);
1651
		XMoveWindow(dpy, tmp_win->title_w,
1652
		            tmp_win->title_x, tmp_win->title_y);
1653
		XDefineCursor(dpy, tmp_win->title_w, Scr->TitleCursor);
1654
	}
1655
	else {
1656
		tmp_win->title_x = tmp_win->frame_bw3D - tmp_win->frame_bw;
1657
		tmp_win->title_y = tmp_win->frame_bw3D - tmp_win->frame_bw;
1658
	}
1659
556.1.65 by Matthew Fuller
Comment and whitespace up the rest of the function.
1660
1661
	/*
1662
	 * Setup various events we want to hear about related to this window.
1663
	 */
556.1.73 by Matthew Fuller
Slap a scope around this event listening setup and rewrap. No code
1664
	{
556.1.74 by Matthew Fuller
Pull these valuemask/attributes vars into the local scopes where
1665
		unsigned long valuemask;
1666
		XSetWindowAttributes attributes;
1667
556.1.73 by Matthew Fuller
Slap a scope around this event listening setup and rewrap. No code
1668
		valuemask = (CWEventMask | CWDontPropagate);
1669
		attributes.event_mask = (StructureNotifyMask | PropertyChangeMask
1670
		                         | ColormapChangeMask | VisibilityChangeMask
1671
		                         | FocusChangeMask
1672
		                         | EnterWindowMask | LeaveWindowMask);
1673
		attributes.do_not_propagate_mask = ButtonPressMask | ButtonReleaseMask
1674
		                                   | PointerMotionMask;
1675
		XChangeWindowAttributes(dpy, tmp_win->w, valuemask, &attributes);
1676
	}
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
1677
556.1.65 by Matthew Fuller
Comment and whitespace up the rest of the function.
1678
1679
	/*
1680
	 * Map up the title window if we have one.  As a sub-window of the
1681
	 * frame, it'll only actually show up in the screen if the frame
1682
	 * does, of course.
1683
	 */
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
1684
	if(tmp_win->title_w) {
1685
		XMapWindow(dpy, tmp_win->title_w);
1686
	}
1687
556.1.65 by Matthew Fuller
Comment and whitespace up the rest of the function.
1688
1689
	/*
558.1.20 by Matthew Fuller
Tweak comment; we shape anything as long as we have shape.
1690
	 * If the server's got Shape, look up info about the window's
558.1.21 by Matthew Fuller
Little further improvement.
1691
	 * Shape'ing, and subscribe to notifications about changes in it.
1692
	 * Actually, it's only the bounding we care about; the rest is
1693
	 * thrown away.
556.1.65 by Matthew Fuller
Comment and whitespace up the rest of the function.
1694
	 */
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
1695
	if(HasShape) {
1696
		int xws, yws, xbs, ybs;
1697
		unsigned wws, hws, wbs, hbs;
1698
		int boundingShaped, clipShaped;
1699
1700
		XShapeSelectInput(dpy, tmp_win->w, ShapeNotifyMask);
1701
		XShapeQueryExtents(dpy, tmp_win->w,
1702
		                   &boundingShaped, &xws, &yws, &wws, &hws,
1703
		                   &clipShaped, &xbs, &ybs, &wbs, &hbs);
1704
		tmp_win->wShaped = boundingShaped;
1705
	}
1706
556.1.65 by Matthew Fuller
Comment and whitespace up the rest of the function.
1707
1708
	/*
1709
	 * If it's a normal window (i.e., not one of ctwm's internal ones),
1710
	 * add it to the "save set", which means that even if ctwm disappears
1711
	 * without doing any cleanup, it'll still show back up on the screen
1712
	 * like normal.  Otherwise, if you kill or segfault ctwm, all the
1713
	 * other things you're running get their windows lost.
558.1.22 by Matthew Fuller
Use better spelling for "is the occupy window" in this condition, and
1714
	 *
1715
	 * XXX Conditional may be a little on the short side; I'm not sure it
1716
	 * catches all of our internals...
556.1.65 by Matthew Fuller
Comment and whitespace up the rest of the function.
1717
	 */
558.1.22 by Matthew Fuller
Use better spelling for "is the occupy window" in this condition, and
1718
	if(!(tmp_win->isiconmgr || tmp_win->iswspmgr || tmp_win->isoccupy)) {
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
1719
		XAddToSaveSet(dpy, tmp_win->w);
1720
	}
1721
556.1.65 by Matthew Fuller
Comment and whitespace up the rest of the function.
1722
1723
	/*
1724
	 * Now reparent the real window into our frame.
1725
	 */
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
1726
	XReparentWindow(dpy, tmp_win->w, tmp_win->frame, tmp_win->frame_bw3D,
1727
	                tmp_win->title_height + tmp_win->frame_bw3D);
556.1.65 by Matthew Fuller
Comment and whitespace up the rest of the function.
1728
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
1729
	/*
556.1.65 by Matthew Fuller
Comment and whitespace up the rest of the function.
1730
	 * Reparenting generates an UnmapNotify event, followed by a
1731
	 * MapNotify.  Set the map state to false to prevent a transition
1732
	 * back to WithdrawnState in HandleUnmapNotify.  ->mapped gets set
1733
	 * correctly again in HandleMapNotify.
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
1734
	 */
492.2.75 by Matthew Fuller
Convert a bunch of boolean flags in the TwmWindow structure
1735
	tmp_win->mapped = false;
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
1736
556.1.65 by Matthew Fuller
Comment and whitespace up the rest of the function.
1737
1738
	/*
1739
	 * Call SetupFrame() which does all sorta of magic figuring to set
1740
	 * the various coordinates and offsets and whatnot for all the pieces
1741
	 * inside our frame.
1742
	 */
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
1743
	SetupFrame(tmp_win, tmp_win->frame_x, tmp_win->frame_y,
488.1.44 by Matthew Fuller
Switch SetupFrame over to C99 bool.
1744
	           tmp_win->frame_width, tmp_win->frame_height, -1, true);
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
1745
556.1.65 by Matthew Fuller
Comment and whitespace up the rest of the function.
1746
1747
	/*
1748
	 * Don't setup the icon window and its bits; when the window is
1749
	 * iconified the first time, that handler will do what needs to be
1750
	 * done for it, so we don't have to.
1751
	 */
1752
1753
1754
	/*
1755
	 * If it's anything other than our own icon manager, setup button/key
1756
	 * bindings for it.  For icon managers, this is done for them at the
1757
	 * end of CreateIconManagers(), not here.  X-ref comments there and
1758
	 * on the function defs below for some discussion about whether it
1759
	 * _should_ work this way.
1760
	 */
492.2.75 by Matthew Fuller
Convert a bunch of boolean flags in the TwmWindow structure
1761
	if(!tmp_win->isiconmgr) {
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
1762
		GrabButtons(tmp_win);
1763
		GrabKeys(tmp_win);
1764
	}
1765
556.1.65 by Matthew Fuller
Comment and whitespace up the rest of the function.
1766
1767
	/* Add this window to the appropriate icon manager[s] */
522.1.1 by Matthew Fuller
Eliminate most (void) casts; they don't really add anything, and just
1768
	AddIconManager(tmp_win);
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
1769
556.1.65 by Matthew Fuller
Comment and whitespace up the rest of the function.
1770
1771
	/*
1772
	 * Stash up info about this TwmWindow and its screen in contexts on
556.1.78 by Matthew Fuller
Macroize setting these contexts for readability, and tweak comments.
1773
	 * the real window and our various decorations around it.  This is
1774
	 * how we find out what TwmWindow things like events are happening
1775
	 * in.
556.1.65 by Matthew Fuller
Comment and whitespace up the rest of the function.
1776
	 */
556.1.78 by Matthew Fuller
Macroize setting these contexts for readability, and tweak comments.
1777
#define SETCTXS(win) do { \
1778
                XSaveContext(dpy, win, TwmContext, (XPointer) tmp_win); \
1779
                XSaveContext(dpy, win, ScreenContext, (XPointer) Scr); \
1780
        } while(0)
1781
1782
	/* The real window and our frame */
1783
	SETCTXS(tmp_win->w);
1784
	SETCTXS(tmp_win->frame);
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
1785
556.1.87 by Matthew Fuller
Tpyo.
1786
	/* Cram that all into any titlebar [sub]windows too */
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
1787
	if(tmp_win->title_height) {
1788
		int i;
1789
		int nb = Scr->TBInfo.nleft + Scr->TBInfo.nright;
1790
556.1.78 by Matthew Fuller
Macroize setting these contexts for readability, and tweak comments.
1791
		SETCTXS(tmp_win->title_w);
1792
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
1793
		for(i = 0; i < nb; i++) {
556.1.78 by Matthew Fuller
Macroize setting these contexts for readability, and tweak comments.
1794
			SETCTXS(tmp_win->titlebuttons[i].window);
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
1795
		}
1796
		if(tmp_win->hilite_wl) {
556.1.78 by Matthew Fuller
Macroize setting these contexts for readability, and tweak comments.
1797
			SETCTXS(tmp_win->hilite_wl);
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
1798
		}
1799
		if(tmp_win->hilite_wr) {
556.1.78 by Matthew Fuller
Macroize setting these contexts for readability, and tweak comments.
1800
			SETCTXS(tmp_win->hilite_wr);
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
1801
		}
1802
		if(tmp_win->lolite_wl) {
556.1.78 by Matthew Fuller
Macroize setting these contexts for readability, and tweak comments.
1803
			SETCTXS(tmp_win->lolite_wl);
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
1804
		}
1805
		if(tmp_win->lolite_wr) {
556.1.78 by Matthew Fuller
Macroize setting these contexts for readability, and tweak comments.
1806
			SETCTXS(tmp_win->lolite_wr);
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
1807
		}
1808
	}
1809
556.1.78 by Matthew Fuller
Macroize setting these contexts for readability, and tweak comments.
1810
#undef SETCTXS
556.1.65 by Matthew Fuller
Comment and whitespace up the rest of the function.
1811
1812
	/*
1813
	 * OK, that's all we need to do while the server's grabbed.  After
1814
	 * this point, other clients might sneak in stuff between our
1815
	 * actions, so they can't be considered atomic anymore.
1816
	 */
1 by Claude Lecommandeur
CTWM version 1.1
1817
	XUngrabServer(dpy);
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
1818
556.1.65 by Matthew Fuller
Comment and whitespace up the rest of the function.
1819
539.1.11 by Matthew Fuller
Improve comment around this ReGrab call so it better describes why
1820
	/*
1821
	 * If we were in the middle of a menu activated function that was
1822
	 * deferred (x-ref comments on DeferExecution()), re-grab to re-set
1823
	 * the special cursor, since we may have reset it above.
1824
	 *
1825
	 * Why could that possibly happen?  It would require a window coming
1826
	 * up and needing to be Add'd in the middle of selecting a window to
1827
	 * apply a function to, which is a pretty rare case, but I s'pose not
1828
	 * impossible...
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
1829
	 */
1830
	if(RootFunction) {
1831
		ReGrab();
1832
	}
539.1.11 by Matthew Fuller
Improve comment around this ReGrab call so it better describes why
1833
556.1.65 by Matthew Fuller
Comment and whitespace up the rest of the function.
1834
1835
	/*
1836
	 * Add to the workspace manager.  Unless this IS the workspace
1837
	 * manager, in which case that would just be silly.
1838
	 */
497.1.13 by Matthew Fuller
Eliminate iswman intermediate var, just referencing tmp_win->iswspmgr
1839
	if(!tmp_win->iswspmgr) {
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
1840
		WMapAddWindow(tmp_win);
1841
	}
556.1.65 by Matthew Fuller
Comment and whitespace up the rest of the function.
1842
1843
692.1.9 by Matthew Fuller
ifdef a few remaining bits discovered by the compiler Builds with
1844
#ifdef CAPTIVE
556.1.65 by Matthew Fuller
Comment and whitespace up the rest of the function.
1845
	/*
1846
	 * If ths window being created is a new captive [sub-]ctwm, we setup
1847
	 * a property on it for unclear reasons.  x-ref comments on the
1848
	 * function.
1849
	 */
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
1850
	SetPropsIfCaptiveCtwm(tmp_win);
692.1.9 by Matthew Fuller
ifdef a few remaining bits discovered by the compiler Builds with
1851
#endif
556.1.65 by Matthew Fuller
Comment and whitespace up the rest of the function.
1852
1853
1854
	/*
1855
	 * Init saved geometry with the current, as if f.savegeometry was
1856
	 * called on the window right away.  That way f.restoregeometry can't
1857
	 * get confuzzled.
1858
	 */
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
1859
	savegeometry(tmp_win);
556.1.65 by Matthew Fuller
Comment and whitespace up the rest of the function.
1860
1861
1862
	/*
1863
	 * And that's it; we created all the bits!
1864
	 */
556.1.82 by Matthew Fuller
Remove redundant parens on the return; this more suits the style we're
1865
	return tmp_win;
1 by Claude Lecommandeur
CTWM version 1.1
1866
}
1867
1868
556.1.66 by Matthew Fuller
Add a little more whitespace here, to separate these utils from the
1869
1870
523.1.8 by Matthew Fuller
Drop some comments about the odd life of GrabButtons()/GrabKeys().
1871
/*
1872
 * XXX GrabButtons() and GrabKeys() are in a slightly odd state.  They're
1873
 * almost strictly a piece of the window-adding process, which is why
1874
 * they're here.  They're not static because the icon manager setup in
1875
 * CreateIconManagers() calls them explicitly, because they're also
1876
 * explicitly skipped in AddWindow() for icon manager windows.  I'm not
1877
 * sure that's necessary; x-ref comment in CIM() about some ideas on the
1878
 * matter.
1879
 *
1880
 * This should be resolved.  Until it is, they're left exported so the
1881
 * iconmgr code can all them, and they're left here (rather than moved to
1882
 * win_utils) on the guess that it may well be resolvable and so they'd
1883
 * stay here and be staticized in the end.
1884
 */
1885
1 by Claude Lecommandeur
CTWM version 1.1
1886
/***********************************************************************
1887
 *
1888
 *  Procedure:
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
1889
 *      GrabButtons - grab needed buttons for the window
1 by Claude Lecommandeur
CTWM version 1.1
1890
 *
1891
 *  Inputs:
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
1892
 *      tmp_win - the twm window structure to use
1 by Claude Lecommandeur
CTWM version 1.1
1893
 *
1894
 ***********************************************************************
1895
 */
1896
20 by Claude Lecommandeur
CTWM version 3.6
1897
#define grabbutton(button, modifier, window, pointer_mode) \
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
1898
        XGrabButton (dpy, button, modifier, window,  \
1899
                True, ButtonPressMask | ButtonReleaseMask, \
1900
                pointer_mode, GrabModeAsync, None,  \
1901
                Scr->FrameCursor);
12 by Claude Lecommandeur
CTWM version 3.3
1902
93 by Richard Levitte
- Convert all functions to use proper prototypes.
1903
void GrabButtons(TwmWindow *tmp_win)
1 by Claude Lecommandeur
CTWM version 1.1
1904
{
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
1905
	FuncButton *tmp;
1906
	int i;
1907
	unsigned int ModifierMask[8] = { ShiftMask, ControlMask, LockMask,
1908
	                                 Mod1Mask, Mod2Mask, Mod3Mask, Mod4Mask,
1909
	                                 Mod5Mask
1910
	                               };
1911
1912
	for(tmp = Scr->FuncButtonRoot.next; tmp != NULL; tmp = tmp->next) {
1913
		if((tmp->cont != C_WINDOW) || (tmp->func == 0)) {
1914
			continue;
1915
		}
1916
		grabbutton(tmp->num, tmp->mods, tmp_win->frame, GrabModeAsync);
1917
1918
		for(i = 0 ; i < 8 ; i++) {
1919
			if((Scr->IgnoreModifier & ModifierMask [i]) && !(tmp->mods & ModifierMask [i]))
1920
				grabbutton(tmp->num, tmp->mods | ModifierMask [i],
1921
				           tmp_win->frame, GrabModeAsync);
1922
		}
1923
	}
1924
	if(Scr->ClickToFocus) {
1925
		grabbutton(AnyButton, None, tmp_win->w, GrabModeSync);
1926
		for(i = 0 ; i < 8 ; i++) {
1927
			grabbutton(AnyButton, ModifierMask [i], tmp_win->w, GrabModeSync);
1928
		}
1929
	}
1930
	else if(Scr->RaiseOnClick) {
1931
		grabbutton(Scr->RaiseOnClickButton, None, tmp_win->w, GrabModeSync);
1932
		for(i = 0 ; i < 8 ; i++) {
1933
			grabbutton(Scr->RaiseOnClickButton,
1934
			           ModifierMask [i], tmp_win->w, GrabModeSync);
1935
		}
1936
	}
10 by Claude Lecommandeur
CTWM version 3.1p3
1937
}
448.1.6 by Matthew Fuller
undef these macros at the end of the funcs using them to limit scope a
1938
#undef grabbutton
10 by Claude Lecommandeur
CTWM version 3.1p3
1939
1 by Claude Lecommandeur
CTWM version 1.1
1940
/***********************************************************************
1941
 *
1942
 *  Procedure:
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
1943
 *      GrabKeys - grab needed keys for the window
1 by Claude Lecommandeur
CTWM version 1.1
1944
 *
1945
 *  Inputs:
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
1946
 *      tmp_win - the twm window structure to use
1 by Claude Lecommandeur
CTWM version 1.1
1947
 *
1948
 ***********************************************************************
1949
 */
1950
20 by Claude Lecommandeur
CTWM version 3.6
1951
#define grabkey(funckey, modifier, window) \
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
1952
        XGrabKey(dpy, funckey->keycode, funckey->mods | modifier, window, True, \
1953
                GrabModeAsync, GrabModeAsync);
20 by Claude Lecommandeur
CTWM version 3.6
1954
#define ungrabkey(funckey, modifier, window) \
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
1955
        XUngrabKey (dpy, funckey->keycode, funckey->mods | modifier, window);
3 by Claude Lecommandeur
CTWM version 1.3
1956
93 by Richard Levitte
- Convert all functions to use proper prototypes.
1957
void GrabKeys(TwmWindow *tmp_win)
1 by Claude Lecommandeur
CTWM version 1.1
1958
{
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
1959
	FuncKey *tmp;
1960
	IconMgr *p;
1961
	int i;
1962
	unsigned int ModifierMask[8] = { ShiftMask, ControlMask, LockMask,
1963
	                                 Mod1Mask, Mod2Mask, Mod3Mask, Mod4Mask,
1964
	                                 Mod5Mask
1965
	                               };
1966
1967
	for(tmp = Scr->FuncKeyRoot.next; tmp != NULL; tmp = tmp->next) {
1968
		switch(tmp->cont) {
1969
			case C_WINDOW:
1970
				/* case C_WORKSPACE: */
448.1.5 by Matthew Fuller
Restrict this #define to the one place it's used. Maybe extraneous,
1971
#define AltMask (Alt1Mask | Alt2Mask | Alt3Mask | Alt4Mask | Alt5Mask)
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
1972
				if(tmp->mods & AltMask) {
1973
					break;
1974
				}
448.1.5 by Matthew Fuller
Restrict this #define to the one place it's used. Maybe extraneous,
1975
#undef AltMask
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
1976
1977
				grabkey(tmp, 0, tmp_win->w);
1978
1979
				for(i = 0 ; i < 8 ; i++) {
1980
					if((Scr->IgnoreModifier & ModifierMask [i]) &&
1981
					                !(tmp->mods & ModifierMask [i])) {
1982
						grabkey(tmp, ModifierMask [i], tmp_win->w);
1983
					}
1984
				}
1985
				break;
1986
1987
			case C_ICON:
1988
				if(!tmp_win->icon || tmp_win->icon->w) {
1989
					break;
1990
				}
1991
1992
				grabkey(tmp, 0, tmp_win->icon->w);
1993
1994
				for(i = 0 ; i < 8 ; i++) {
1995
					if((Scr->IgnoreModifier & ModifierMask [i]) &&
1996
					                !(tmp->mods & ModifierMask [i])) {
1997
						grabkey(tmp, ModifierMask [i], tmp_win->icon->w);
1998
					}
1999
				}
2000
				break;
2001
2002
			case C_TITLE:
2003
				if(!tmp_win->title_w) {
2004
					break;
2005
				}
2006
2007
				grabkey(tmp, 0, tmp_win->title_w);
2008
2009
				for(i = 0 ; i < 8 ; i++) {
2010
					if((Scr->IgnoreModifier & ModifierMask [i]) &&
2011
					                !(tmp->mods & ModifierMask [i])) {
2012
						grabkey(tmp, ModifierMask [i], tmp_win->title_w);
2013
					}
2014
				}
2015
				break;
2016
2017
			case C_NAME:
2018
				grabkey(tmp, 0, tmp_win->w);
2019
				for(i = 0 ; i < 8 ; i++) {
2020
					if((Scr->IgnoreModifier & ModifierMask [i]) &&
2021
					                !(tmp->mods & ModifierMask [i])) {
2022
						grabkey(tmp, ModifierMask [i], tmp_win->w);
2023
					}
2024
				}
2025
				if(tmp_win->icon && tmp_win->icon->w) {
2026
					grabkey(tmp, 0, tmp_win->icon->w);
2027
2028
					for(i = 0 ; i < 8 ; i++) {
2029
						if((Scr->IgnoreModifier & ModifierMask [i]) &&
2030
						                !(tmp->mods & ModifierMask [i])) {
2031
							grabkey(tmp, ModifierMask [i], tmp_win->icon->w);
2032
						}
2033
					}
2034
				}
2035
				if(tmp_win->title_w) {
2036
					grabkey(tmp, 0, tmp_win->title_w);
2037
2038
					for(i = 0 ; i < 8 ; i++) {
2039
						if((Scr->IgnoreModifier & ModifierMask [i]) &&
2040
						                !(tmp->mods & ModifierMask [i])) {
2041
							grabkey(tmp, ModifierMask [i], tmp_win->title_w);
2042
						}
2043
					}
2044
				}
2045
				break;
302.1.39 by Olaf 'Rhialto' Seibert
Add some support for NET_WM_WINDOW_TYPE : NET_WM_WINDOW_TYPE_DESKTOP
2046
2047
#ifdef EWMH_DESKTOP_ROOT
2048
			case C_ROOT:
2049
				if(tmp_win->ewmhWindowType != wt_Desktop) {
2050
					break;
2051
				}
2052
2053
				grabkey(tmp, 0, tmp_win->w);
2054
2055
				for(i = 0 ; i < 8 ; i++) {
2056
					if((Scr->IgnoreModifier & ModifierMask [i]) &&
2057
					                !(tmp->mods & ModifierMask [i])) {
2058
						grabkey(tmp, ModifierMask [i], tmp_win->w);
2059
					}
2060
				}
2061
				break;
2062
#endif /* EWMH */
2063
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
2064
				/*
2065
				case C_ROOT:
2066
				    XGrabKey(dpy, tmp->keycode, tmp->mods, Scr->Root, True,
2067
				        GrabModeAsync, GrabModeAsync);
2068
				    break;
2069
				*/
2070
		}
2071
	}
2072
	for(tmp = Scr->FuncKeyRoot.next; tmp != NULL; tmp = tmp->next) {
2073
		if(tmp->cont == C_ICONMGR && !Scr->NoIconManagers) {
2074
			for(p = Scr->iconmgr; p != NULL; p = p->next) {
2075
				ungrabkey(tmp, 0, p->twm_win->w);
2076
2077
				for(i = 0 ; i < 8 ; i++) {
2078
					if((Scr->IgnoreModifier & ModifierMask [i]) &&
2079
					                !(tmp->mods & ModifierMask [i])) {
2080
						ungrabkey(tmp, ModifierMask [i], p->twm_win->w);
2081
					}
2082
				}
2083
			}
2084
		}
2085
	}
2086
}
448.1.6 by Matthew Fuller
undef these macros at the end of the funcs using them to limit scope a
2087
#undef grabkey
2088
#undef ungrabkey
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
2089
2090
696.1.8 by Matthew Fuller
This func is purely vscreen stuff related, so we can conditionalize it
2091
#ifdef VSCREEN
184 by Richard Levitte
Fix the following issues:
2092
/*
2093
 * This is largely for Xinerama support with VirtualScreens.
2094
 * In this case, windows may be on something other then the main screen
2095
 * on startup, or the mapping may be relative to the right side of the
2096
 * screen, which is on a different monitor, which will cause issues with
2097
 * the virtual screens.
2098
 *
2099
 * It probably needs to be congnizant of windows that are actually owned by
2100
 * other workspaces, and ignore them (this needs to be revisited), or perhaps
2101
 * that functionality is appropriate in AddWindow().  This needs to be dug into
2102
 * more deply.
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
2103
 *
184 by Richard Levitte
Fix the following issues:
2104
 * this approach assumes screens that are next to each other horizontally,
2105
 * Other possibilities need to be investigated and accounted for.
2106
 */
521.1.25 by Matthew Fuller
Staticize this func while I'm messing with stuff, since it's currently
2107
static void
2108
DealWithNonSensicalGeometries(Display *mydpy, Window vroot,
521.1.26 by Matthew Fuller
make indent
2109
                              TwmWindow *tmp_win)
184 by Richard Levitte
Fix the following issues:
2110
{
304.1.2 by Matthew Fuller
Run 'make indent' to reindent the world.
2111
	Window              vvroot;
2112
	int                 x, y;
2113
	unsigned int        w, h;
2114
	unsigned int        j;
2115
	VirtualScreen       *myvs, *vs;
2116
	int                 dropx = 0;
2117
2118
	if(! vroot) {
2119
		return;
2120
	}
2121
2122
	if(!(XGetGeometry(mydpy, vroot, &vvroot, &x, &y, &w, &h, &j, &j))) {
2123
		return;
2124
	}
2125
2126
	myvs = findIfVScreenOf(x, y);
2127
2128
	/*
2129
	 * probably need to rethink this  for unmapped vs's.  ugh.
2130
	 */
2131
	if(!myvs) {
2132
		return;
2133
	}
2134
2135
	for(vs = myvs->next; vs; vs = vs->next) {
2136
		dropx += vs->w;
2137
	}
2138
2139
	for(vs = Scr->vScreenList; vs && vs != myvs; vs = vs->next) {
2140
		dropx -= vs->w;
2141
	}
2142
2143
	if(tmp_win->frame_x > 0 && tmp_win->frame_x >= w) {
2144
		tmp_win->frame_x -= abs(dropx);
2145
	}
2146
	else {
2147
	}
184 by Richard Levitte
Fix the following issues:
2148
2149
}
696.1.8 by Matthew Fuller
This func is purely vscreen stuff related, so we can conditionalize it
2150
#endif // VSCREEN