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