648.1.1
by Matthew Fuller
Extract the funcs relating to shutting down ctwm ('restart' is a kind |
1 |
/*
|
2 |
* Shutdown (/restart) bits
|
|
3 |
*/
|
|
4 |
||
5 |
#include "ctwm.h" |
|
6 |
||
7 |
#include <stdlib.h> |
|
8 |
#include <stdio.h> |
|
9 |
#include <unistd.h> |
|
10 |
||
11 |
#include "animate.h" |
|
692.1.6
by Matthew Fuller
Conditionalize including captive.h. |
12 |
#ifdef CAPTIVE
|
648.1.1
by Matthew Fuller
Extract the funcs relating to shutting down ctwm ('restart' is a kind |
13 |
#include "captive.h" |
692.1.6
by Matthew Fuller
Conditionalize including captive.h. |
14 |
#endif
|
648.1.1
by Matthew Fuller
Extract the funcs relating to shutting down ctwm ('restart' is a kind |
15 |
#include "colormaps.h" |
16 |
#include "ctwm_atoms.h" |
|
17 |
#include "ctwm_shutdown.h" |
|
18 |
#include "screen.h" |
|
19 |
#include "session.h" |
|
20 |
#ifdef SOUNDS
|
|
21 |
# include "sound.h"
|
|
22 |
#endif
|
|
23 |
#include "otp.h" |
|
24 |
#include "win_ops.h" |
|
25 |
#include "win_utils.h" |
|
26 |
||
27 |
||
648.1.18
by Matthew Fuller
Rename these restore-config funcs so the names are a little less |
28 |
static void RestoreForShutdown(Time mytime); |
648.1.1
by Matthew Fuller
Extract the funcs relating to shutting down ctwm ('restart' is a kind |
29 |
|
30 |
||
31 |
/**
|
|
648.1.15
by Matthew Fuller
Comment up RestoreWithdrawnLocation() and drop a mark on one caller. |
32 |
* Put a window back where it should be if we don't (any longer) control
|
652.1.39
by Matthew Fuller
Update comment a bit. |
33 |
* it and reparent it back up to the root. This leaves it where it was
|
34 |
* before we started (well, adjusted by any moves we've made to it
|
|
35 |
* since), and placed so that if we restart and take it back over, it'll
|
|
36 |
* wind up right where it is now, so restarting doesn't shift windows all
|
|
37 |
* over the place.
|
|
648.1.1
by Matthew Fuller
Extract the funcs relating to shutting down ctwm ('restart' is a kind |
38 |
*/
|
39 |
void
|
|
648.1.18
by Matthew Fuller
Rename these restore-config funcs so the names are a little less |
40 |
RestoreWinConfig(TwmWindow *tmp) |
648.1.1
by Matthew Fuller
Extract the funcs relating to shutting down ctwm ('restart' is a kind |
41 |
{
|
652.1.38
by Matthew Fuller
Reindent due to elimination of a block, move the vars up to the top of |
42 |
int gravx, gravy; |
43 |
int newx, newy; |
|
44 |
||
45 |
// Things adjusting by the border have to move our border size, but
|
|
46 |
// subtract away from that the old border we're restoring.
|
|
47 |
const int borders = tmp->frame_bw + tmp->frame_bw3D - tmp->old_bw; |
|
48 |
||
648.1.15
by Matthew Fuller
Comment up RestoreWithdrawnLocation() and drop a mark on one caller. |
49 |
// If this window is "unmapped" by moving it way offscreen, and is in
|
50 |
// that state, move it back onto the window.
|
|
648.1.1
by Matthew Fuller
Extract the funcs relating to shutting down ctwm ('restart' is a kind |
51 |
if(tmp->UnmapByMovingFarAway && !visible(tmp)) { |
52 |
XMoveWindow(dpy, tmp->frame, tmp->frame_x, tmp->frame_y); |
|
53 |
}
|
|
648.1.15
by Matthew Fuller
Comment up RestoreWithdrawnLocation() and drop a mark on one caller. |
54 |
|
55 |
// If it's squeezed, unsqueeze it.
|
|
648.1.1
by Matthew Fuller
Extract the funcs relating to shutting down ctwm ('restart' is a kind |
56 |
if(tmp->squeezed) { |
57 |
Squeeze(tmp); |
|
58 |
}
|
|
648.1.15
by Matthew Fuller
Comment up RestoreWithdrawnLocation() and drop a mark on one caller. |
59 |
|
652.1.37
by Matthew Fuller
Invert this condition; just exit out early, instead of |
60 |
// This is apparently our standard "is this window still around?"
|
61 |
// idiom.
|
|
652.1.36
by Matthew Fuller
We're no longer using the XGetGeometry returns, so just use junk for |
62 |
if(XGetGeometry(dpy, tmp->w, &JunkRoot, &JunkX, &JunkY, |
652.1.37
by Matthew Fuller
Invert this condition; just exit out early, instead of |
63 |
&JunkWidth, &JunkHeight, &JunkBW, &JunkDepth) == 0) { |
64 |
// Well, give up...
|
|
65 |
return; |
|
66 |
}
|
|
652.1.38
by Matthew Fuller
Reindent due to elimination of a block, move the vars up to the top of |
67 |
|
68 |
// Get gravity bits to know how to move stuff around when we take
|
|
69 |
// away the decorations.
|
|
70 |
GetGravityOffsets(tmp, &gravx, &gravy); |
|
71 |
||
72 |
// We want to move the window to where it should be "outside" of our
|
|
73 |
// frame. This varies depending on the window gravity detail, and we
|
|
74 |
// have to account for that, since on re-startup we'll be doing it to
|
|
75 |
// resposition it after we re-wrap it.
|
|
76 |
//
|
|
77 |
// e.g., in simple "NorthWest" gravity, we just made the frame start
|
|
78 |
// where the window did, and shifted the app window right (by the
|
|
79 |
// border width) and down (by the border width + titlebar). However,
|
|
80 |
// "SouthEast" gravity means the bottom right of the frame is where
|
|
652.1.42
by Matthew Fuller
Fixup some tpyos and slightly improve some verbiage in comments. |
81 |
// the windows' was, and the window itself shifted left/up by the
|
82 |
// border. Compare e.g. an xterm with -geometry "+0+0" with one
|
|
83 |
// using "-0-0" as an easy trick to make windows with different
|
|
84 |
// geoms.
|
|
652.1.38
by Matthew Fuller
Reindent due to elimination of a block, move the vars up to the top of |
85 |
newx = tmp->frame_x; |
86 |
newy = tmp->frame_y; |
|
87 |
||
88 |
||
89 |
// So, first consider the north/south gravity. If gravity is North,
|
|
90 |
// we put the top of the frame where the window was and shifted
|
|
91 |
// everything inside down, so the top of the frame now is where the
|
|
92 |
// window should be put. With South-y gravity, the window should
|
|
93 |
// wind up at the bottom of the frame, which means we need to shift
|
|
94 |
// it down by the titlebar height, plus twice the border width. But
|
|
95 |
// if the vertical gravity is neutral, then the window needs to wind
|
|
96 |
// up staying right where it is, because we built the frame around it
|
|
97 |
// without moving it.
|
|
98 |
//
|
|
99 |
// Previous code here (and code elsewhere) expressed this calculation
|
|
100 |
// by the rather confusing idiom ((gravy + 1) * border_width), which
|
|
101 |
// gives the right answer, but is confusing as hell...
|
|
102 |
if(gravy < 0) { |
|
103 |
// North; where the frame starts (already set)
|
|
104 |
}
|
|
105 |
else if(gravy > 0) { |
|
106 |
// South; shift down title + 2*border
|
|
107 |
newy += tmp->title_height + 2 * borders; |
|
108 |
}
|
|
109 |
else { |
|
110 |
// Neutral; down by the titlebar + border.
|
|
111 |
newy += tmp->title_height + borders; |
|
112 |
}
|
|
113 |
||
114 |
||
652.1.42
by Matthew Fuller
Fixup some tpyos and slightly improve some verbiage in comments. |
115 |
// Now east/west. West means align with the frame start, east means
|
652.1.38
by Matthew Fuller
Reindent due to elimination of a block, move the vars up to the top of |
116 |
// align with the frame right edge, neutral means where it already
|
117 |
// is.
|
|
118 |
if(gravx < 0) { |
|
652.1.42
by Matthew Fuller
Fixup some tpyos and slightly improve some verbiage in comments. |
119 |
// West; it's already correct
|
652.1.38
by Matthew Fuller
Reindent due to elimination of a block, move the vars up to the top of |
120 |
}
|
121 |
else if(gravx > 0) { |
|
122 |
// East; shift over by 2*border
|
|
123 |
newx += 2 * borders; |
|
124 |
}
|
|
125 |
else { |
|
126 |
// Neutral; over by the left border
|
|
127 |
newx += borders; |
|
128 |
}
|
|
129 |
||
130 |
||
700.1.11
by Matthew Fuller
Hide these TwmWindow winbox-related fields behind an ifdef along with |
131 |
#ifdef WINBOX
|
652.1.38
by Matthew Fuller
Reindent due to elimination of a block, move the vars up to the top of |
132 |
// If it's in a WindowBox, reparent the frame back up to our real root
|
133 |
if(tmp->winbox && tmp->winbox->twmwin && tmp->frame) { |
|
134 |
int xbox, ybox; |
|
135 |
unsigned int j_bw; |
|
136 |
||
137 |
// XXX This isn't right, right? This will give coords relative
|
|
138 |
// to the window box, but we're using them relative to the real
|
|
139 |
// screen root?
|
|
140 |
if(XGetGeometry(dpy, tmp->frame, &JunkRoot, &xbox, &ybox, |
|
141 |
&JunkWidth, &JunkHeight, &j_bw, &JunkDepth)) { |
|
142 |
ReparentWindow(dpy, tmp, WinWin, Scr->Root, xbox, ybox); |
|
143 |
}
|
|
144 |
}
|
|
700.1.11
by Matthew Fuller
Hide these TwmWindow winbox-related fields behind an ifdef along with |
145 |
#endif
|
652.1.38
by Matthew Fuller
Reindent due to elimination of a block, move the vars up to the top of |
146 |
|
147 |
||
148 |
// Restore the original window border if there were one
|
|
149 |
if(tmp->old_bw) { |
|
150 |
XSetWindowBorderWidth(dpy, tmp->w, tmp->old_bw); |
|
151 |
}
|
|
152 |
||
153 |
// Reparent and move back to where it otter be
|
|
154 |
XReparentWindow(dpy, tmp->w, Scr->Root, newx, newy); |
|
155 |
||
156 |
// If it came with a pre-made icon window, hide it
|
|
157 |
if(tmp->wmhints->flags & IconWindowHint) { |
|
158 |
XUnmapWindow(dpy, tmp->wmhints->icon_window); |
|
159 |
}
|
|
648.1.15
by Matthew Fuller
Comment up RestoreWithdrawnLocation() and drop a mark on one caller. |
160 |
|
161 |
// Done
|
|
162 |
return; |
|
648.1.1
by Matthew Fuller
Extract the funcs relating to shutting down ctwm ('restart' is a kind |
163 |
}
|
164 |
||
165 |
||
166 |
/**
|
|
167 |
* Restore some window positions/etc in preparation for going away.
|
|
168 |
*/
|
|
169 |
static void |
|
648.1.18
by Matthew Fuller
Rename these restore-config funcs so the names are a little less |
170 |
RestoreForShutdown(Time mytime) |
648.1.1
by Matthew Fuller
Extract the funcs relating to shutting down ctwm ('restart' is a kind |
171 |
{
|
648.1.16
by Matthew Fuller
Comment up Reborder(). |
172 |
ScreenInfo *savedScr = Scr; // We need Scr flipped around... |
648.1.1
by Matthew Fuller
Extract the funcs relating to shutting down ctwm ('restart' is a kind |
173 |
|
174 |
XGrabServer(dpy); |
|
648.1.16
by Matthew Fuller
Comment up Reborder(). |
175 |
|
176 |
for(int scrnum = 0; scrnum < NumScreens; scrnum++) { |
|
648.1.1
by Matthew Fuller
Extract the funcs relating to shutting down ctwm ('restart' is a kind |
177 |
if((Scr = ScreenList[scrnum]) == NULL) { |
178 |
continue; |
|
179 |
}
|
|
180 |
||
648.1.16
by Matthew Fuller
Comment up Reborder(). |
181 |
// Force reinstalling any colormaps
|
182 |
InstallColormaps(0, &Scr->RootColormaps); |
|
183 |
||
652.1.26
by Matthew Fuller
Replace RestoreWinConfig() calls with explicit Reparent's in our |
184 |
// Pull all the windows out of their frames and reposition them
|
652.1.41
by Matthew Fuller
Slightly improve comment. |
185 |
// where the frame was, with approprate adjustments for gravity.
|
186 |
// This will preserve their positions when we restart, or put
|
|
187 |
// them back where they were before we started. Do it from the
|
|
188 |
// bottom up of our stacking order to preserve the stacking.
|
|
652.1.26
by Matthew Fuller
Replace RestoreWinConfig() calls with explicit Reparent's in our |
189 |
for(TwmWindow *tw = OtpBottomWin() ; tw != NULL |
190 |
; tw = OtpNextWinUp(tw)) { |
|
652.1.31
by Matthew Fuller
It turns out we really do need to do reworking of the coordinates to |
191 |
if(tw->isiconmgr || tw->iswspmgr || tw->isoccupy) { |
192 |
// Don't bother with internals...
|
|
193 |
continue; |
|
194 |
}
|
|
195 |
RestoreWinConfig(tw); |
|
648.1.1
by Matthew Fuller
Extract the funcs relating to shutting down ctwm ('restart' is a kind |
196 |
}
|
197 |
}
|
|
648.1.16
by Matthew Fuller
Comment up Reborder(). |
198 |
|
648.1.1
by Matthew Fuller
Extract the funcs relating to shutting down ctwm ('restart' is a kind |
199 |
XUngrabServer(dpy); |
648.1.16
by Matthew Fuller
Comment up Reborder(). |
200 |
|
201 |
// Restore
|
|
202 |
Scr = savedScr; |
|
203 |
||
204 |
// Focus away from any windows
|
|
648.1.1
by Matthew Fuller
Extract the funcs relating to shutting down ctwm ('restart' is a kind |
205 |
SetFocus(NULL, mytime); |
206 |
}
|
|
207 |
||
208 |
||
209 |
/**
|
|
648.1.19
by Matthew Fuller
Done() -> DoShutdown(). Imperative form is more descriptive, and it's |
210 |
* Cleanup and exit ctwm
|
648.1.1
by Matthew Fuller
Extract the funcs relating to shutting down ctwm ('restart' is a kind |
211 |
*/
|
212 |
void
|
|
648.1.19
by Matthew Fuller
Done() -> DoShutdown(). Imperative form is more descriptive, and it's |
213 |
DoShutdown(void) |
648.1.1
by Matthew Fuller
Extract the funcs relating to shutting down ctwm ('restart' is a kind |
214 |
{
|
648.1.20
by Matthew Fuller
Comment through shutdown/restart funcs, and note how weird things are |
215 |
|
648.1.1
by Matthew Fuller
Extract the funcs relating to shutting down ctwm ('restart' is a kind |
216 |
#ifdef SOUNDS
|
648.1.20
by Matthew Fuller
Comment through shutdown/restart funcs, and note how weird things are |
217 |
// Denounce ourselves
|
648.1.1
by Matthew Fuller
Extract the funcs relating to shutting down ctwm ('restart' is a kind |
218 |
play_exit_sound(); |
219 |
#endif
|
|
648.1.20
by Matthew Fuller
Comment through shutdown/restart funcs, and note how weird things are |
220 |
|
221 |
// Restore windows/colormaps for our absence.
|
|
648.1.18
by Matthew Fuller
Rename these restore-config funcs so the names are a little less |
222 |
RestoreForShutdown(CurrentTime); |
648.1.20
by Matthew Fuller
Comment through shutdown/restart funcs, and note how weird things are |
223 |
|
648.1.1
by Matthew Fuller
Extract the funcs relating to shutting down ctwm ('restart' is a kind |
224 |
#ifdef EWMH
|
648.1.20
by Matthew Fuller
Comment through shutdown/restart funcs, and note how weird things are |
225 |
// Clean up EWMH properties
|
648.1.1
by Matthew Fuller
Extract the funcs relating to shutting down ctwm ('restart' is a kind |
226 |
EwmhTerminate(); |
648.1.20
by Matthew Fuller
Comment through shutdown/restart funcs, and note how weird things are |
227 |
#endif
|
228 |
||
229 |
// Clean up our list of workspaces
|
|
648.1.1
by Matthew Fuller
Extract the funcs relating to shutting down ctwm ('restart' is a kind |
230 |
XDeleteProperty(dpy, Scr->Root, XA_WM_WORKSPACESLIST); |
648.1.20
by Matthew Fuller
Comment through shutdown/restart funcs, and note how weird things are |
231 |
|
692.1.5
by Matthew Fuller
Add ifdef's around references to Screen and CLargs members that are |
232 |
#ifdef CAPTIVE
|
648.1.20
by Matthew Fuller
Comment through shutdown/restart funcs, and note how weird things are |
233 |
// Shut down captive stuff
|
648.1.1
by Matthew Fuller
Extract the funcs relating to shutting down ctwm ('restart' is a kind |
234 |
if(CLarg.is_captive) { |
235 |
RemoveFromCaptiveList(Scr->captivename); |
|
236 |
}
|
|
692.1.5
by Matthew Fuller
Add ifdef's around references to Screen and CLargs members that are |
237 |
#endif
|
648.1.20
by Matthew Fuller
Comment through shutdown/restart funcs, and note how weird things are |
238 |
|
239 |
// Close up shop
|
|
648.1.1
by Matthew Fuller
Extract the funcs relating to shutting down ctwm ('restart' is a kind |
240 |
XCloseDisplay(dpy); |
241 |
exit(0); |
|
242 |
}
|
|
243 |
||
244 |
||
245 |
/**
|
|
246 |
* exec() ourself to restart.
|
|
247 |
*/
|
|
248 |
void
|
|
249 |
DoRestart(Time t) |
|
250 |
{
|
|
648.1.20
by Matthew Fuller
Comment through shutdown/restart funcs, and note how weird things are |
251 |
// Don't try to do any further animating
|
648.1.1
by Matthew Fuller
Extract the funcs relating to shutting down ctwm ('restart' is a kind |
252 |
StopAnimation(); |
253 |
XSync(dpy, 0); |
|
648.1.20
by Matthew Fuller
Comment through shutdown/restart funcs, and note how weird things are |
254 |
|
255 |
// Replace all the windows/colormaps as if we were going away. 'cuz
|
|
256 |
// we are.
|
|
648.1.18
by Matthew Fuller
Rename these restore-config funcs so the names are a little less |
257 |
RestoreForShutdown(t); |
648.1.1
by Matthew Fuller
Extract the funcs relating to shutting down ctwm ('restart' is a kind |
258 |
XSync(dpy, 0); |
259 |
||
648.1.20
by Matthew Fuller
Comment through shutdown/restart funcs, and note how weird things are |
260 |
// Shut down session management connection cleanly.
|
648.1.1
by Matthew Fuller
Extract the funcs relating to shutting down ctwm ('restart' is a kind |
261 |
if(smcConn) { |
262 |
SmcCloseConnection(smcConn, 0, NULL); |
|
263 |
}
|
|
264 |
||
648.1.20
by Matthew Fuller
Comment through shutdown/restart funcs, and note how weird things are |
265 |
// Re-run ourself
|
266 |
fprintf(stderr, "%s: restarting: %s\n", ProgramName, *Argv); |
|
648.1.1
by Matthew Fuller
Extract the funcs relating to shutting down ctwm ('restart' is a kind |
267 |
execvp(*Argv, Argv); |
648.1.20
by Matthew Fuller
Comment through shutdown/restart funcs, and note how weird things are |
268 |
|
269 |
// Uh oh, we shouldn't get here...
|
|
648.1.1
by Matthew Fuller
Extract the funcs relating to shutting down ctwm ('restart' is a kind |
270 |
fprintf(stderr, "%s: unable to restart: %s\n", ProgramName, *Argv); |
648.1.20
by Matthew Fuller
Comment through shutdown/restart funcs, and note how weird things are |
271 |
|
272 |
// We should probably un-RestoreForShutdown() etc. If that exec
|
|
273 |
// fails, we're in a really weird state...
|
|
648.1.21
by Matthew Fuller
At least add a XBell call if restart fails, so maybe we'll get a |
274 |
XBell(dpy, 0); |
648.1.1
by Matthew Fuller
Extract the funcs relating to shutting down ctwm ('restart' is a kind |
275 |
}
|