Use inotify to check for changes to the defaults database. Workaround for
[wmaker-crm.git] / src / shutdown.c
Commit [+]AuthorDateLineData
9d2e6ef9 scottc1998-09-29 22:36:29 +00001/*
9af1c6c4 dan1998-10-21 14:43:47 +00002 * Window Maker window manager
6830b057 dan2004-10-12 21:28:27 +00003 *
4153e2fd dan2003-01-16 23:30:45 +00004 * Copyright (c) 1997-2003 Alfredo K. Kojima
6830b057 dan2004-10-12 21:28:27 +00005 *
9d2e6ef9 scottc1998-09-29 22:36:29 +00006 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
6830b057 dan2004-10-12 21:28:27 +000018 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
9d2e6ef9 scottc1998-09-29 22:36:29 +000019 * USA.
20 */
21
22#include "wconfig.h"
23
24#include <stdlib.h>
0261c326 dan1999-01-06 15:22:33 +000025#include <signal.h>
26#include <unistd.h>
9d2e6ef9 scottc1998-09-29 22:36:29 +000027
28#include <X11/Xlib.h>
29#include <X11/Xutil.h>
9d2e6ef9 scottc1998-09-29 22:36:29 +000030
31#include "WindowMaker.h"
32#include "window.h"
33#include "client.h"
34#include "funcs.h"
35#include "properties.h"
52917e53 dan1999-04-16 20:05:26 +000036#include "session.h"
9d2e6ef9 scottc1998-09-29 22:36:29 +000037#include "winspector.h"
70555308 kojima2004-10-16 22:05:04 +000038#include "wmspec.h"
9d2e6ef9 scottc1998-09-29 22:36:29 +000039
40extern Atom _XA_WM_DELETE_WINDOW;
41extern Time LastTimestamp;
9007a657 dan1998-11-23 11:32:19 +000042extern int wScreenCount;
9d2e6ef9 scottc1998-09-29 22:36:29 +000043
0261c326 dan1999-01-06 15:22:33 +000044
45static void wipeDesktop(WScreen *scr);
46
47
48/*
49 *----------------------------------------------------------------------
50 * Shutdown-
51 * Exits the window manager cleanly. If mode is WSLogoutMode,
52 * the whole X session will be closed, by killing all clients if
53 * no session manager is running or by asking a shutdown to
54 * it if its present.
6830b057 dan2004-10-12 21:28:27 +000055 *
0261c326 dan1999-01-06 15:22:33 +000056 *----------------------------------------------------------------------
57 */
58void
59Shutdown(WShutdownMode mode)
60{
61 int i;
56d85687 Rodney Padgett2008-08-09 11:39:24 +010062 extern int inotifyFD;
0261c326 dan1999-01-06 15:22:33 +000063
64 switch (mode) {
6830b057 dan2004-10-12 21:28:27 +000065 case WSLogoutMode:
416e3a82 dan1999-01-25 19:06:50 +000066#ifdef XSMP_ENABLED
6830b057 dan2004-10-12 21:28:27 +000067 wSessionRequestShutdown();
68 break;
0261c326 dan1999-01-06 15:22:33 +000069#else
6830b057 dan2004-10-12 21:28:27 +000070 /* fall through */
0261c326 dan1999-01-06 15:22:33 +000071#endif
6830b057 dan2004-10-12 21:28:27 +000072 case WSKillMode:
73 case WSExitMode:
74 /* if there is no session manager, send SAVE_YOURSELF to
75 * the clients */
416e3a82 dan1999-01-25 19:06:50 +000076#if 0
77#ifdef XSMP_ENABLED
6830b057 dan2004-10-12 21:28:27 +000078 if (!wSessionIsManaged())
416e3a82 dan1999-01-25 19:06:50 +000079#endif
6830b057 dan2004-10-12 21:28:27 +000080 for (i = 0; i < wScreenCount; i++) {
81 WScreen *scr;
82
83 scr = wScreenWithNumber(i);
84 if (scr) {
85 wSessionSendSaveYourself(scr);
86 }
87 }
416e3a82 dan1999-01-25 19:06:50 +000088#endif
56d85687 Rodney Padgett2008-08-09 11:39:24 +010089 close(inotifyFD);
6830b057 dan2004-10-12 21:28:27 +000090 for (i = 0; i < wScreenCount; i++) {
91 WScreen *scr;
416e3a82 dan1999-01-25 19:06:50 +000092
6830b057 dan2004-10-12 21:28:27 +000093 scr = wScreenWithNumber(i);
94 if (scr) {
95 if (scr->helper_pid)
96 kill(scr->helper_pid, SIGKILL);
416e3a82 dan1999-01-25 19:06:50 +000097
6830b057 dan2004-10-12 21:28:27 +000098 /* if the session is not being managed, save restart info */
416e3a82 dan1999-01-25 19:06:50 +000099#ifdef XSMP_ENABLED
6830b057 dan2004-10-12 21:28:27 +0000100 if (!wSessionIsManaged())
416e3a82 dan1999-01-25 19:06:50 +0000101#endif
6830b057 dan2004-10-12 21:28:27 +0000102 wSessionSaveClients(scr);
416e3a82 dan1999-01-25 19:06:50 +0000103
6830b057 dan2004-10-12 21:28:27 +0000104 wScreenSaveState(scr);
105
106 if (mode == WSKillMode)
107 wipeDesktop(scr);
108 else
109 RestoreDesktop(scr);
110 }
111 }
112 ExecExitScript();
113 Exit(0);
114 break;
115
116 case WSRestartPreparationMode:
117 for (i=0; i<wScreenCount; i++) {
118 WScreen *scr;
119
56d85687 Rodney Padgett2008-08-09 11:39:24 +0100120 close(inotifyFD);
6830b057 dan2004-10-12 21:28:27 +0000121 scr = wScreenWithNumber(i);
122 if (scr) {
123 if (scr->helper_pid)
124 kill(scr->helper_pid, SIGKILL);
6830b057 dan2004-10-12 21:28:27 +0000125 wScreenSaveState(scr);
6830b057 dan2004-10-12 21:28:27 +0000126 RestoreDesktop(scr);
127 }
128 }
129 break;
0261c326 dan1999-01-06 15:22:33 +0000130 }
131}
132
133
ccbb6e8e dan2000-09-24 02:31:58 +0000134static void
135restoreWindows(WMBag *bag, WMBagIterator iter)
0b87b7fa kojima2000-04-08 23:53:22 +0000136{
137 WCoreWindow *next;
138 WCoreWindow *core;
139 WWindow *wwin;
ccbb6e8e dan2000-09-24 02:31:58 +0000140
0b87b7fa kojima2000-04-08 23:53:22 +0000141
142 if (iter == NULL) {
6830b057 dan2004-10-12 21:28:27 +0000143 core = WMBagFirst(bag, &iter);
0b87b7fa kojima2000-04-08 23:53:22 +0000144 } else {
6830b057 dan2004-10-12 21:28:27 +0000145 core = WMBagNext(bag, &iter);
0b87b7fa kojima2000-04-08 23:53:22 +0000146 }
ccbb6e8e dan2000-09-24 02:31:58 +0000147
0b87b7fa kojima2000-04-08 23:53:22 +0000148 if (core == NULL)
6830b057 dan2004-10-12 21:28:27 +0000149 return;
ccbb6e8e dan2000-09-24 02:31:58 +0000150
0b87b7fa kojima2000-04-08 23:53:22 +0000151 restoreWindows(bag, iter);
ccbb6e8e dan2000-09-24 02:31:58 +0000152
0b87b7fa kojima2000-04-08 23:53:22 +0000153 /* go to the end of the list */
154 while (core->stacking->under)
6830b057 dan2004-10-12 21:28:27 +0000155 core = core->stacking->under;
0b87b7fa kojima2000-04-08 23:53:22 +0000156
157 while (core) {
6830b057 dan2004-10-12 21:28:27 +0000158 next = core->stacking->above;
ccbb6e8e dan2000-09-24 02:31:58 +0000159
6830b057 dan2004-10-12 21:28:27 +0000160 if (core->descriptor.parent_type==WCLASS_WINDOW) {
161 Window window;
0b87b7fa kojima2000-04-08 23:53:22 +0000162
6830b057 dan2004-10-12 21:28:27 +0000163 wwin = core->descriptor.parent;
164 window = wwin->client_win;
165 wUnmanageWindow(wwin, !wwin->flags.internal_window, False);
166 XMapWindow(dpy, window);
167 }
168 core = next;
0b87b7fa kojima2000-04-08 23:53:22 +0000169 }
170}
ccbb6e8e dan2000-09-24 02:31:58 +0000171
0b87b7fa kojima2000-04-08 23:53:22 +0000172
9d2e6ef9 scottc1998-09-29 22:36:29 +0000173/*
174 *----------------------------------------------------------------------
175 * RestoreDesktop--
176 * Puts the desktop in a usable state when exiting.
9007a657 dan1998-11-23 11:32:19 +0000177 *
9d2e6ef9 scottc1998-09-29 22:36:29 +0000178 * Side effects:
179 * All frame windows are removed and windows are reparented
6830b057 dan2004-10-12 21:28:27 +0000180 * back to root. Windows that are outside the screen are
181 * brought to a viable place.
182 *
183 *----------------------------------------------------------------------
9d2e6ef9 scottc1998-09-29 22:36:29 +0000184 */
185void
186RestoreDesktop(WScreen *scr)
187{
e7495baf dan1999-02-17 11:06:40 +0000188 if (scr->helper_pid > 0) {
6830b057 dan2004-10-12 21:28:27 +0000189 kill(scr->helper_pid, SIGTERM);
190 scr->helper_pid = 0;
9007a657 dan1998-11-23 11:32:19 +0000191 }
0261c326 dan1999-01-06 15:22:33 +0000192
9d2e6ef9 scottc1998-09-29 22:36:29 +0000193 XGrabServer(dpy);
194 wDestroyInspectorPanels();
195
196 /* reparent windows back to the root window, keeping the stacking order */
0b87b7fa kojima2000-04-08 23:53:22 +0000197 restoreWindows(scr->stacking_list, NULL);
9d2e6ef9 scottc1998-09-29 22:36:29 +0000198
199 XUngrabServer(dpy);
200 XSetInputFocus(dpy, PointerRoot, RevertToParent, CurrentTime);
201 wColormapInstallForWindow(scr, NULL);
202 PropCleanUp(scr->root_win);
70555308 kojima2004-10-16 22:05:04 +0000203 wNETWMCleanup(scr);
9d2e6ef9 scottc1998-09-29 22:36:29 +0000204 XSync(dpy, 0);
205}
206
207
208/*
209 *----------------------------------------------------------------------
0261c326 dan1999-01-06 15:22:33 +0000210 * wipeDesktop--
9d2e6ef9 scottc1998-09-29 22:36:29 +0000211 * Kills all windows in a screen. Send DeleteWindow to all windows
212 * that support it and KillClient on all windows that don't.
6830b057 dan2004-10-12 21:28:27 +0000213 *
9d2e6ef9 scottc1998-09-29 22:36:29 +0000214 * Side effects:
215 * All managed windows are closed.
6830b057 dan2004-10-12 21:28:27 +0000216 *
9d2e6ef9 scottc1998-09-29 22:36:29 +0000217 * TODO: change to XQueryTree()
6830b057 dan2004-10-12 21:28:27 +0000218 *----------------------------------------------------------------------
9d2e6ef9 scottc1998-09-29 22:36:29 +0000219 */
0261c326 dan1999-01-06 15:22:33 +0000220static void
221wipeDesktop(WScreen *scr)
9d2e6ef9 scottc1998-09-29 22:36:29 +0000222{
223 WWindow *wwin;
9007a657 dan1998-11-23 11:32:19 +0000224
9d2e6ef9 scottc1998-09-29 22:36:29 +0000225 wwin = scr->focused_window;
226 while (wwin) {
6830b057 dan2004-10-12 21:28:27 +0000227 if (wwin->protocols.DELETE_WINDOW)
228 wClientSendProtocol(wwin, _XA_WM_DELETE_WINDOW, LastTimestamp);
229 else
230 wClientKill(wwin);
231 wwin = wwin->prev;
9d2e6ef9 scottc1998-09-29 22:36:29 +0000232 }
233 XSync(dpy, False);
234}
235