1 /* $Id: desktop.c,v 1.1 2004/08/28 19:25:45 dannybackx Exp $ */
2 /*****************************************************************************/
3 /** Copyright 1988 by Evans & Sutherland Computer Corporation, **/
4 /** Salt Lake City, Utah **/
5 /** Portions Copyright 1989 by the Massachusetts Institute of Technology **/
6 /** Cambridge, Massachusetts **/
7 /** **/
8 /** All Rights Reserved **/
9 /** **/
10 /** Permission to use, copy, modify, and distribute this software and **/
11 /** its documentation for any purpose and without fee is hereby **/
12 /** granted, provided that the above copyright notice appear in all **/
13 /** copies and that both that copyright notice and this permis- **/
14 /** sion notice appear in supporting documentation, and that the **/
15 /** names of Evans & Sutherland and M.I.T. not be used in advertising **/
16 /** in publicity pertaining to distribution of the software without **/
17 /** specific, written prior permission. **/
18 /** **/
19 /** EVANS & SUTHERLAND AND M.I.T. DISCLAIM ALL WARRANTIES WITH REGARD **/
20 /** TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT- **/
21 /** ABILITY AND FITNESS, IN NO EVENT SHALL EVANS & SUTHERLAND OR **/
22 /** M.I.T. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAM- **/
23 /** AGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA **/
24 /** OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER **/
25 /** TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE **/
26 /** OR PERFORMANCE OF THIS SOFTWARE. **/
27 /*****************************************************************************/
28 /****************************************************************************
29 * This module is based on Twm, but has been siginificantly modified
30 * by Rob Nation
31 ****************************************************************************/
32 /***********************************************************************
33 * The rest of it is all my fault -- MLM
34 * mwm - "LessTif Window Manager"
35 ***********************************************************************/
36
37 #include <LTconfig.h>
38
39 #include <Xm/Xm.h>
40 #include <Xm/MwmUtil.h>
41 #include "mwm.h"
42
43 /****************************************************************************
44 *
45 * <Desktop description>
46 *
47 ****************************************************************************/
48
49 /*
50 * Unmaps a window on transition to a new desktop
51 */
52 static void
remove_from_desktop(ScreenInfo * scr,MwmWindow * t)53 remove_from_desktop(ScreenInfo *scr, MwmWindow *t)
54 {
55 XWindowAttributes winattrs;
56 unsigned long eventMask;
57
58 /*
59 * Prevent the receipt of an UnmapNotify, since that would
60 * cause a transition to the Withdrawn state.
61 */
62 XGetWindowAttributes(dpy, t->w, &winattrs);
63 eventMask = winattrs.your_event_mask;
64 XSelectInput(dpy, t->w, eventMask & ~StructureNotifyMask);
65 if (t->flags & ICONIFIED)
66 {
67 if (t->icon_pixmap_w != None)
68 XUnmapWindow(dpy, t->icon_pixmap_w);
69 if (t->icon_w != None)
70 XUnmapWindow(dpy, t->icon_w);
71 }
72 else if (t->flags & (MAPPED | MAP_PENDING))
73 {
74 XUnmapWindow(dpy, t->frame);
75 }
76 XSelectInput(dpy, t->w, eventMask);
77 PAGER_UpdateView(scr, t);
78 }
79
80 /*
81 * Maps a window on transition to a new desktop
82 */
83 static void
add_to_desktop(ScreenInfo * scr,MwmWindow * t)84 add_to_desktop(ScreenInfo *scr, MwmWindow *t)
85 {
86 if (t->flags & ICONIFIED)
87 {
88 if (t->icon_pixmap_w != None)
89 XMapWindow(dpy, t->icon_pixmap_w);
90 if (t->icon_w != None)
91 XMapWindow(dpy, t->icon_w);
92 }
93 else if (t->flags & MAPPED)
94 {
95 XMapWindow(dpy, t->frame);
96 t->flags |= MAP_PENDING;
97 XMapWindow(dpy, t->parent);
98 }
99 PAGER_UpdateView(scr, t);
100 }
101
102 /*
103 * save the desktop state
104 */
105 void
DT_SaveState(ScreenInfo * scr)106 DT_SaveState(ScreenInfo *scr)
107 {
108 MwmWindow *t;
109 unsigned long data[1];
110
111 for (t = scr->mwm_root.next; t != NULL; t = t->next)
112 {
113 data[0] = (unsigned long)t->Desk;
114 XChangeProperty(dpy, t->w, XA_WM_DESKTOP, XA_WM_DESKTOP, 32,
115 PropModeReplace, (unsigned char *)data, 1);
116 }
117
118 data[0] = (unsigned long)scr->current_desk;
119 XChangeProperty(dpy, scr->root_win, XA_WM_DESKTOP, XA_WM_DESKTOP, 32,
120 PropModeReplace, (unsigned char *)data, 1);
121
122 XSync(dpy, 0);
123 }
124
125 /*
126 * Move to a new desktop
127 */
128 void
DT_ChangeDesks(ScreenInfo * scr,int val1,int val2)129 DT_ChangeDesks(ScreenInfo *scr, int val1, int val2)
130 {
131 int oldDesk;
132 MwmWindow *t;
133 MwmWindow *FocusWin = 0;
134 static MwmWindow *StickyWin = 0;
135
136 oldDesk = scr->current_desk;
137
138 if (val1 != 0)
139 {
140 scr->current_desk = scr->current_desk + val1;
141 }
142 else
143 {
144 scr->current_desk = val2;
145 if (scr->current_desk == oldDesk)
146 return;
147 }
148
149 /* Scan the window list, mapping windows on the new Desk,
150 * unmapping windows on the old Desk */
151 XGrabServer(dpy);
152 for (t = scr->mwm_root.next; t != NULL; t = t->next)
153 {
154 /* Only change mapping for non-sticky windows */
155 if ((!(t->flags & STICKY)) && (!(t->flags & ICON_UNMAPPED)))
156 {
157 if (t->Desk == oldDesk)
158 {
159 if (scr->mwm_focus == t)
160 t->FocusDesk = oldDesk;
161 else
162 t->FocusDesk = -1;
163 remove_from_desktop(scr, t);
164 }
165 else if (t->Desk == scr->current_desk)
166 {
167 add_to_desktop(scr, t);
168 if (t->FocusDesk == scr->current_desk)
169 {
170 FocusWin = t;
171 }
172 }
173 }
174 else
175 {
176 /* Window is sticky */
177 t->Desk = scr->current_desk;
178 if (scr->mwm_focus == t)
179 {
180 t->FocusDesk = oldDesk;
181 StickyWin = t;
182 }
183 }
184 }
185 XUngrabServer(dpy);
186 for (t = scr->mwm_root.next; t != NULL; t = t->next)
187 {
188 /* If its an icon, and its sticking, autoplace it so
189 * that it doesn't wind up on top a a stationary
190 * icon */
191 if ((t->flags & STICKY) && (t->flags & ICONIFIED) &&
192 (!(t->flags & ICON_MOVED)) && (!(t->flags & ICON_UNMAPPED)))
193 ICON_AutoPlace(scr, t);
194 }
195 /* Better re-draw the pager now */
196 PAGER_Clear(scr);
197
198 if (Mwm.keyboard_focus_policy == XmEXPLICIT)
199 {
200 if (Mwm.auto_key_focus)
201 {
202 if (FocusWin)
203 {
204 WIN_SetFocusInTree(FocusWin);
205 WIN_SetFocus(scr, FocusWin->w, FocusWin);
206 }
207 else if (StickyWin && (StickyWin->flags && STICKY))
208 {
209 WIN_SetFocusInTree(StickyWin);
210 WIN_SetFocus(scr, StickyWin->w, StickyWin);
211 }
212 }
213 else
214 {
215 WIN_SetFocus(scr, scr->no_focus_win, NULL);
216 }
217 }
218 }
219
220 /*
221 * Move to a new desktop
222 */
223 void
DT_WindowChangingDesks(ScreenInfo * scr,MwmWindow * t,int val1)224 DT_WindowChangingDesks(ScreenInfo *scr, MwmWindow *t, int val1)
225 {
226 if (val1 == t->Desk)
227 return;
228
229 /* Scan the window list, mapping windows on the new Desk,
230 * unmapping windows on the old Desk */
231 /* Only change mapping for non-sticky windows */
232 if ((!(t->flags & STICKY)) && (!(t->flags & ICON_UNMAPPED)))
233 {
234 if (t->Desk == scr->current_desk)
235 {
236 t->Desk = val1;
237 remove_from_desktop(scr, t);
238 }
239 else if (val1 == scr->current_desk)
240 {
241 t->Desk = val1;
242 /* If its an icon, auto-place it */
243 if (t->flags & ICONIFIED)
244 ICON_AutoPlace(scr, t);
245 add_to_desktop(scr, t);
246 }
247 else
248 t->Desk = val1;
249
250 }
251 /* Better re-draw the pager now */
252 PAGER_Clear(scr);
253 }
254