JWM Source Documentation
desktop.c
Go to the documentation of this file.
1 
10 #include "jwm.h"
11 #include "desktop.h"
12 #include "main.h"
13 #include "client.h"
14 #include "clientlist.h"
15 #include "taskbar.h"
16 #include "error.h"
17 #include "menu.h"
18 #include "misc.h"
19 #include "background.h"
20 #include "settings.h"
21 #include "grab.h"
22 #include "event.h"
23 
24 static char **desktopNames = NULL;
25 static char *showingDesktop = NULL;
26 
28 void StartupDesktops(void)
29 {
30 
31  unsigned int x;
32 
33  if(desktopNames == NULL) {
34  desktopNames = Allocate(settings.desktopCount * sizeof(char*));
35  for(x = 0; x < settings.desktopCount; x++) {
36  desktopNames[x] = NULL;
37  }
38  }
39  for(x = 0; x < settings.desktopCount; x++) {
40  if(desktopNames[x] == NULL) {
41  desktopNames[x] = Allocate(4 * sizeof(char));
42  snprintf(desktopNames[x], 4, "%d", x + 1);
43  }
44  }
45  if(showingDesktop == NULL) {
46  showingDesktop = Allocate(settings.desktopCount * sizeof(char));
47  for(x = 0; x < settings.desktopCount; x++) {
48  showingDesktop[x] = 0;
49  }
50  }
51 }
52 
54 void DestroyDesktops(void)
55 {
56 
57  if(desktopNames) {
58  unsigned int x;
59  for(x = 0; x < settings.desktopCount; x++) {
61  }
63  desktopNames = NULL;
64  }
65  if(showingDesktop) {
67  showingDesktop = NULL;
68  }
69 
70 }
71 
73 unsigned int GetRightDesktop(unsigned int desktop)
74 {
75  const int y = desktop / settings.desktopWidth;
76  const int x = (desktop + 1) % settings.desktopWidth;
77  return y * settings.desktopWidth + x;
78 }
79 
81 unsigned int GetLeftDesktop(unsigned int desktop)
82 {
83  const int y = currentDesktop / settings.desktopWidth;
85  x = x > 0 ? x - 1 : settings.desktopWidth - 1;
86  return y * settings.desktopWidth + x;
87 }
88 
90 unsigned int GetAboveDesktop(unsigned int desktop)
91 {
94  }
96 }
97 
99 unsigned int GetBelowDesktop(unsigned int desktop)
100 {
102 }
103 
105 char RightDesktop(void)
106 {
107  if(settings.desktopWidth > 1) {
108  const unsigned int desktop = GetRightDesktop(currentDesktop);
109  ChangeDesktop(desktop);
110  return 1;
111  } else {
112  return 0;
113  }
114 }
115 
117 char LeftDesktop(void)
118 {
119  if(settings.desktopWidth > 1) {
120  const unsigned int desktop = GetLeftDesktop(currentDesktop);
121  ChangeDesktop(desktop);
122  return 1;
123  } else {
124  return 0;
125  }
126 }
127 
129 char AboveDesktop(void)
130 {
131  if(settings.desktopHeight > 1) {
132  const int desktop = GetAboveDesktop(currentDesktop);
133  ChangeDesktop(desktop);
134  return 1;
135  } else {
136  return 0;
137  }
138 }
139 
141 char BelowDesktop(void)
142 {
143  if(settings.desktopHeight > 1) {
144  const unsigned int desktop = GetBelowDesktop(currentDesktop);
145  ChangeDesktop(desktop);
146  return 1;
147  } else {
148  return 0;
149  }
150 }
151 
153 void ChangeDesktop(unsigned int desktop)
154 {
155 
156  ClientNode *np;
157  unsigned int x;
158 
159  if(JUNLIKELY(desktop >= settings.desktopCount)) {
160  return;
161  }
162 
163  if(currentDesktop == desktop) {
164  return;
165  }
166 
167  /* Hide clients from the old desktop.
168  * Note that we show clients in a separate loop to prevent an issue
169  * with clients losing focus.
170  */
171  for(x = 0; x < LAYER_COUNT; x++) {
172  for(np = nodes[x]; np; np = np->next) {
173  if(np->state.status & STAT_STICKY) {
174  continue;
175  }
176  if(np->state.desktop == currentDesktop) {
177  HideClient(np);
178  }
179  }
180  }
181 
182  /* Show clients on the new desktop. */
183  for(x = 0; x < LAYER_COUNT; x++) {
184  for(np = nodes[x]; np; np = np->next) {
185  if(np->state.status & STAT_STICKY) {
186  continue;
187  }
188  if(np->state.desktop == desktop) {
189  ShowClient(np);
190  }
191  }
192  }
193 
194  currentDesktop = desktop;
195 
199 
200  RequireRestack();
202 
203  LoadBackground(desktop);
204 
205 }
206 
208 Menu *CreateDesktopMenu(unsigned int mask, void *context)
209 {
210 
211  Menu *menu;
212  int x;
213 
214  menu = CreateMenu();
215  for(x = settings.desktopCount - 1; x >= 0; x--) {
216  const size_t len = strlen(desktopNames[x]);
218  item->next = menu->items;
219  menu->items = item;
220 
221  item->action.type = MA_DESKTOP;
222  item->action.context = context;
223  item->action.value = x;
224 
225  item->name = Allocate(len + 3);
226  item->name[0] = (mask & (1 << x)) ? '[' : ' ';
227  memcpy(&item->name[1], desktopNames[x], len);
228  item->name[len + 1] = (mask & (1 << x)) ? ']' : ' ';
229  item->name[len + 2] = 0;
230  }
231 
232  return menu;
233 
234 }
235 
237 Menu *CreateSendtoMenu(MenuActionType mask, void *context)
238 {
239 
240  Menu *menu;
241  int x;
242 
243  menu = CreateMenu();
244  for(x = settings.desktopCount - 1; x >= 0; x--) {
245  const size_t len = strlen(desktopNames[x]);
247  item->next = menu->items;
248  menu->items = item;
249 
250  item->action.type = MA_SENDTO | mask;
251  item->action.context = context;
252  item->action.value = x;
253 
254  item->name = Allocate(len + 3);
255  item->name[0] = (x == currentDesktop) ? '[' : ' ';
256  memcpy(&item->name[1], desktopNames[x], len);
257  item->name[len + 1] = (x == currentDesktop) ? ']' : ' ';
258  item->name[len + 2] = 0;
259  }
260 
261  return menu;
262 }
263 
265 void ShowDesktop(void)
266 {
267 
268  ClientNode *np;
269  int layer;
270 
271  GrabServer();
272  for(layer = 0; layer < LAYER_COUNT; layer++) {
273  for(np = nodes[layer]; np; np = np->next) {
274  if(np->state.status & STAT_NOLIST) {
275  continue;
276  }
277  if((np->state.desktop == currentDesktop) ||
278  (np->state.status & STAT_STICKY)) {
280  if(np->state.status & STAT_SDESKTOP) {
281  RestoreClient(np, 0);
282  }
283  } else {
284  if(np->state.status & STAT_ACTIVE) {
285  JXSetInputFocus(display, rootWindow, RevertToParent,
286  CurrentTime);
287  }
288  if(np->state.status & (STAT_MAPPED | STAT_SHADED)) {
289  MinimizeClient(np, 0);
290  np->state.status |= STAT_SDESKTOP;
291  }
292  }
293  }
294  }
295  }
296  RequireRestack();
298  JXSync(display, True);
299 
301  char first = 1;
302  JXSync(display, False);
303  for(layer = 0; layer < LAYER_COUNT; layer++) {
304  for(np = nodes[layer]; np; np = np->next) {
305  if(np->state.status & STAT_NOLIST) {
306  continue;
307  }
308  if((np->state.desktop == currentDesktop) ||
309  (np->state.status & STAT_STICKY)) {
310  if(first) {
311  FocusClient(np);
312  first = 0;
313  }
314  DrawBorder(np);
315  }
316  }
317  }
319  } else {
321  }
323  showingDesktop[currentDesktop]);
324  UngrabServer();
325 
326 }
327 
329 void SetDesktopName(unsigned int desktop, const char *str)
330 {
331 
332 
333  if(JUNLIKELY(!str)) {
334  Warning(_("empty Desktops Name tag"));
335  return;
336  }
337 
339 
340  if(!desktopNames) {
341  unsigned int x;
342  desktopNames = Allocate(settings.desktopCount * sizeof(char*));
343  for(x = 0; x < settings.desktopCount; x++) {
344  desktopNames[x] = NULL;
345  }
346  }
347 
348  Assert(desktopNames[desktop] == NULL);
349 
350  desktopNames[desktop] = CopyString(str);
351 
352 }
353 
355 const char *GetDesktopName(unsigned int desktop)
356 {
357  Assert(desktop < settings.desktopCount);
358  if(desktopNames && desktopNames[desktop]) {
359  return desktopNames[desktop];
360  } else {
361  return "";
362  }
363 }
364 

joewing.net / Projects / JWM