*** empty log message ***
[wmaker-crm.git] / src / workspace.c
blob570953541d4ee3d39886410759d8484d093a588b
1 /* workspace.c- Workspace management
2 *
3 * Window Maker window manager
4 *
5 * Copyright (c) 1997, 1998 Alfredo K. Kojima
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
20 * USA.
22 #include "wconfig.h"
24 #include <X11/Xlib.h>
25 #include <X11/Xutil.h>
26 #ifdef SHAPE
27 #include <X11/extensions/shape.h>
28 #endif
30 #include <stdlib.h>
31 #include <stdio.h>
32 #include <unistd.h>
33 #include <ctype.h>
34 #include <string.h>
36 #include "WindowMaker.h"
37 #include "wcore.h"
38 #include "framewin.h"
39 #include "window.h"
40 #include "icon.h"
41 #include "funcs.h"
42 #include "menu.h"
43 #include "application.h"
44 #include "dock.h"
45 #include "actions.h"
46 #include "workspace.h"
47 #include "appicon.h"
48 #ifdef GNOME_STUFF
49 #include "gnome.h"
50 #endif
51 #ifdef KWM_HINTS
52 #include "kwm.h"
53 #endif
55 #include <proplist.h>
58 extern WPreferences wPreferences;
59 extern XContext wWinContext;
62 static proplist_t dWorkspaces=NULL;
63 static proplist_t dClip, dName;
66 static void
67 make_keys()
69 if (dWorkspaces!=NULL)
70 return;
72 dWorkspaces = PLMakeString("Workspaces");
73 dName = PLMakeString("Name");
74 dClip = PLMakeString("Clip");
78 void
79 wWorkspaceMake(WScreen *scr, int count)
81 while (count>0) {
82 wWorkspaceNew(scr);
83 count--;
88 int
89 wWorkspaceNew(WScreen *scr)
91 WWorkspace *wspace, **list;
92 int i;
94 if (scr->workspace_count < MAX_WORKSPACES) {
95 scr->workspace_count++;
97 wspace = wmalloc(sizeof(WWorkspace));
98 wspace->name = NULL;
100 #ifdef KWM_HINTS
101 if (scr->flags.kwm_syncing_count) {
102 wspace->name = wKWMGetWorkspaceName(scr, scr->workspace_count-1);
104 #endif
105 if (!wspace->name) {
106 wspace->name = wmalloc(strlen(_("Workspace %i"))+8);
107 sprintf(wspace->name, _("Workspace %i"), scr->workspace_count);
111 if (!wPreferences.flags.noclip) {
112 wspace->clip = wDockCreate(scr, WM_CLIP);
113 } else
114 wspace->clip = NULL;
116 list = wmalloc(sizeof(WWorkspace*)*scr->workspace_count);
118 for (i=0; i<scr->workspace_count-1; i++) {
119 list[i] = scr->workspaces[i];
121 list[i] = wspace;
122 free(scr->workspaces);
123 scr->workspaces = list;
125 wWorkspaceMenuUpdate(scr, scr->workspace_menu);
126 wWorkspaceMenuUpdate(scr, scr->clip_ws_menu);
127 #ifdef GNOME_STUFF
128 wGNOMEUpdateWorkspaceHints(scr);
129 #endif
130 #ifdef KWM_HINTS
131 if (!scr->flags.kwm_syncing_count) {
132 wKWMUpdateWorkspaceCountHint(scr);
133 wKWMUpdateWorkspaceNameHint(scr, scr->workspace_count-1);
135 #ifdef not_used
136 wKWMSetUsableAreaHint(scr, scr->workspace_count-1);
137 #endif
138 #endif
139 XFlush(dpy);
141 return scr->workspace_count-1;
143 return -1;
148 Bool
149 wWorkspaceDelete(WScreen *scr, int workspace)
151 WWindow *tmp;
152 WWorkspace **list;
153 int i, j;
156 if (workspace<=0)
157 return False;
159 /* verify if workspace is in use by some window */
160 tmp = scr->focused_window;
161 while (tmp) {
162 if (!IS_OMNIPRESENT(tmp) && tmp->frame->workspace==workspace)
163 return False;
164 tmp = tmp->prev;
167 if (!wPreferences.flags.noclip) {
168 wDockDestroy(scr->workspaces[workspace]->clip);
169 scr->workspaces[workspace]->clip = NULL;
172 list = wmalloc(sizeof(WWorkspace*)*(scr->workspace_count-1));
173 j = 0;
174 for (i=0; i<scr->workspace_count; i++) {
175 if (i!=workspace)
176 list[j++] = scr->workspaces[i];
177 else {
178 if (scr->workspaces[i]->name)
179 free(scr->workspaces[i]->name);
180 free(scr->workspaces[i]);
183 free(scr->workspaces);
184 scr->workspaces = list;
186 scr->workspace_count--;
189 /* update menu */
190 wWorkspaceMenuUpdate(scr, scr->workspace_menu);
191 /* clip workspace menu */
192 wWorkspaceMenuUpdate(scr, scr->clip_ws_menu);
194 /* update also window menu */
195 if (scr->workspace_submenu) {
196 WMenu *menu = scr->workspace_submenu;
198 i = menu->entry_no;
199 while (i>scr->workspace_count)
200 wMenuRemoveItem(menu, --i);
201 wMenuRealize(menu);
203 /* and clip menu */
204 if (scr->clip_submenu) {
205 WMenu *menu = scr->clip_submenu;
207 i = menu->entry_no;
208 while (i>scr->workspace_count)
209 wMenuRemoveItem(menu, --i);
210 wMenuRealize(menu);
213 #ifdef GNOME_STUFF
214 wGNOMEUpdateWorkspaceHints(scr);
215 #endif
216 #ifdef KWM_HINTS
217 wKWMUpdateWorkspaceCountHint(scr);
218 #endif
220 if (scr->current_workspace >= scr->workspace_count)
221 wWorkspaceChange(scr, scr->workspace_count-1);
223 return True;
227 typedef struct WorkspaceNameData {
228 int count;
229 RImage *back;
230 RImage *text;
231 } WorkspaceNameData;
235 static void
236 hideWorkpaceName(void *data)
238 WScreen *scr = (WScreen*)data;
240 if (!scr->workspace_name_data || scr->workspace_name_data->count == 0) {
241 XUnmapWindow(dpy, scr->workspace_name);
243 if (scr->workspace_name_data) {
244 RDestroyImage(scr->workspace_name_data->back);
245 RDestroyImage(scr->workspace_name_data->text);
246 free(scr->workspace_name_data);
248 scr->workspace_name_data = NULL;
250 scr->workspace_name_timer = NULL;
251 } else {
252 RImage *img = RCloneImage(scr->workspace_name_data->back);
253 Pixmap pix;
255 scr->workspace_name_timer = WMAddTimerHandler(30, hideWorkpaceName,
256 scr);
258 RCombineImagesWithOpaqueness(img, scr->workspace_name_data->text,
259 scr->workspace_name_data->count*255/10);
261 RConvertImage(scr->rcontext, img, &pix);
263 RDestroyImage(img);
265 XSetWindowBackgroundPixmap(dpy, scr->workspace_name, pix);
266 XClearWindow(dpy, scr->workspace_name);
267 XFreePixmap(dpy, pix);
268 XFlush(dpy);
270 scr->workspace_name_data->count--;
276 static void
277 showWorkspaceName(WScreen *scr, int workspace)
279 WorkspaceNameData *data;
280 RXImage *ximg;
281 Pixmap text, mask;
282 int w, h;
283 char *name = scr->workspaces[workspace]->name;
284 int len = strlen(name);
285 int x, y;
287 if (scr->workspace_name_timer) {
288 WMDeleteTimerHandler(scr->workspace_name_timer);
289 XUnmapWindow(dpy, scr->workspace_name);
290 XFlush(dpy);
293 if (scr->workspace_name_data) {
294 RDestroyImage(scr->workspace_name_data->back);
295 RDestroyImage(scr->workspace_name_data->text);
296 free(scr->workspace_name_data);
299 #ifndef I18N_MB
300 XSetFont(dpy, scr->mono_gc, scr->workspace_name_font->font->fid);
301 XSetFont(dpy, scr->draw_gc, scr->workspace_name_font->font->fid);
302 #endif
304 data = wmalloc(sizeof(WorkspaceNameData));
306 w = wTextWidth(scr->workspace_name_font->font, name, len);
307 h = scr->workspace_name_font->height;
309 XResizeWindow(dpy, scr->workspace_name, w+4, h+4);
310 XMoveWindow(dpy, scr->workspace_name, (scr->scr_width - (w+4))/2,
311 (scr->scr_height - (h+4))/2);
313 text = XCreatePixmap(dpy, scr->w_win, w+4, h+4, scr->w_depth);
314 mask = XCreatePixmap(dpy, scr->w_win, w+4, h+4, 1);
316 XSetForeground(dpy, scr->draw_gc, scr->black_pixel);
317 XFillRectangle(dpy, text, scr->draw_gc, 0, 0, w+4, h+4);
319 XSetForeground(dpy, scr->mono_gc, 0);
320 XFillRectangle(dpy, mask, scr->mono_gc, 0, 0, w+4, h+4);
322 XSetForeground(dpy, scr->mono_gc, 1);
323 for (x = 0; x <= 4; x++) {
324 for (y = 0; y <= 4; y++) {
325 wDrawString(mask, scr->workspace_name_font, scr->mono_gc,
326 x, scr->workspace_name_font->y + y, name, len);
330 XSetForeground(dpy, scr->draw_gc, scr->white_pixel);
331 wDrawString(text, scr->workspace_name_font, scr->draw_gc,
332 2, scr->workspace_name_font->y + 2,
333 scr->workspaces[workspace]->name,
334 strlen(scr->workspaces[workspace]->name));
335 #ifdef SHAPE
336 XShapeCombineMask(dpy, scr->workspace_name, ShapeBounding, 0, 0, mask,
337 ShapeSet);
338 #endif
339 XSetWindowBackgroundPixmap(dpy, scr->workspace_name, text);
340 XClearWindow(dpy, scr->workspace_name);
342 data->text = RCreateImageFromDrawable(scr->rcontext, text, None);
344 XFreePixmap(dpy, text);
345 XFreePixmap(dpy, mask);
347 if (!data->text) {
348 XMapRaised(dpy, scr->workspace_name);
349 XFlush(dpy);
351 goto erro;
354 ximg = RGetXImage(scr->rcontext, scr->root_win,
355 (scr->scr_width - data->text->width)/2,
356 (scr->scr_height - data->text->height)/2,
357 data->text->width, data->text->height);
359 if (!ximg) {
360 goto erro;
363 XMapRaised(dpy, scr->workspace_name);
364 XFlush(dpy);
366 data->back = RCreateImageFromXImage(scr->rcontext, ximg->image, NULL);
367 RDestroyXImage(scr->rcontext, ximg);
369 if (!data->back) {
370 goto erro;
373 data->count = 10;
375 scr->workspace_name_data = data;
377 scr->workspace_name_timer = WMAddTimerHandler(300, hideWorkpaceName, scr);
379 return;
381 erro:
382 if (data->text)
383 RDestroyImage(data->text);
384 if (data->back)
385 RDestroyImage(data->back);
386 free(data);
388 scr->workspace_name_data = NULL;
390 scr->workspace_name_timer = WMAddTimerHandler(600, hideWorkpaceName, scr);
394 void
395 wWorkspaceChange(WScreen *scr, int workspace)
397 if (scr->flags.startup || scr->flags.startup2) {
398 return;
401 if (workspace != scr->current_workspace) {
402 wWorkspaceForceChange(scr, workspace);
403 } else {
404 showWorkspaceName(scr, workspace);
409 void
410 wWorkspaceRelativeChange(WScreen *scr, int amount)
412 int w;
414 w = scr->current_workspace + amount;
416 if (amount < 0) {
418 if (w >= 0)
419 wWorkspaceChange(scr, w);
420 else if (wPreferences.ws_cycle)
421 wWorkspaceChange(scr, scr->workspace_count + w);
423 } else if (amount > 0) {
425 if (w < scr->workspace_count)
426 wWorkspaceChange(scr, w);
427 else if (wPreferences.ws_advance)
428 wWorkspaceChange(scr, WMIN(w, MAX_WORKSPACES-1));
429 else if (wPreferences.ws_cycle)
430 wWorkspaceChange(scr, w % scr->workspace_count);
436 void
437 wWorkspaceForceChange(WScreen *scr, int workspace)
439 WWindow *tmp, *foc=NULL, *foc2=NULL;
441 if (workspace >= MAX_WORKSPACES || workspace < 0)
442 return;
444 SendHelperMessage(scr, 'C', workspace+1, NULL);
446 if (workspace > scr->workspace_count-1) {
447 wWorkspaceMake(scr, workspace - scr->workspace_count + 1);
450 wClipUpdateForWorkspaceChange(scr, workspace);
452 scr->current_workspace = workspace;
454 wWorkspaceMenuUpdate(scr, scr->workspace_menu);
456 wWorkspaceMenuUpdate(scr, scr->clip_ws_menu);
458 if ((tmp = scr->focused_window)!= NULL) {
459 if (IS_OMNIPRESENT(tmp) || tmp->flags.changing_workspace)
460 foc = tmp;
462 while (tmp) {
463 if (tmp->frame->workspace!=workspace && !tmp->flags.selected) {
464 /* unmap windows not on this workspace */
465 if ((tmp->flags.mapped||tmp->flags.shaded)
466 && !IS_OMNIPRESENT(tmp)
467 && !tmp->flags.changing_workspace) {
469 wWindowUnmap(tmp);
471 /* also unmap miniwindows not on this workspace */
472 if (tmp->flags.miniaturized && !IS_OMNIPRESENT(tmp)
473 && tmp->icon) {
474 if (!wPreferences.sticky_icons) {
475 XUnmapWindow(dpy, tmp->icon->core->window);
476 tmp->icon->mapped = 0;
477 } else {
478 tmp->icon->mapped = 1;
479 /* Why is this here? -Alfredo */
480 XMapWindow(dpy, tmp->icon->core->window);
483 /* update current workspace of omnipresent windows */
484 if (IS_OMNIPRESENT(tmp)) {
485 WApplication *wapp = wApplicationOf(tmp->main_window);
487 tmp->frame->workspace = workspace;
489 if (wapp) {
490 wapp->last_workspace = workspace;
492 if (!foc2)
493 foc2 = tmp;
495 } else {
496 /* change selected windows' workspace */
497 if (tmp->flags.selected) {
498 wWindowChangeWorkspace(tmp, workspace);
499 if (!tmp->flags.miniaturized && !foc) {
500 foc = tmp;
502 } else {
503 if (!tmp->flags.hidden) {
504 if (!(tmp->flags.mapped || tmp->flags.miniaturized)) {
505 /* remap windows that are on this workspace */
506 wWindowMap(tmp);
507 if (!foc)
508 foc = tmp;
510 /* Also map miniwindow if not omnipresent */
511 if (!wPreferences.sticky_icons &&
512 tmp->flags.miniaturized &&
513 !IS_OMNIPRESENT(tmp) && tmp->icon) {
514 tmp->icon->mapped = 1;
515 XMapWindow(dpy, tmp->icon->core->window);
520 tmp = tmp->prev;
523 if (!foc)
524 foc = foc2;
526 if (scr->focused_window->flags.mapped && !foc) {
527 foc = scr->focused_window;
529 if (wPreferences.focus_mode == WKF_CLICK) {
530 wSetFocusTo(scr, foc);
531 } else {
532 unsigned int mask;
533 int foo;
534 Window bar, win;
535 WWindow *tmp;
537 tmp = NULL;
538 if (XQueryPointer(dpy, scr->root_win, &bar, &win,
539 &foo, &foo, &foo, &foo, &mask)) {
540 tmp = wWindowFor(win);
542 if (!tmp && wPreferences.focus_mode == WKF_SLOPPY) {
543 wSetFocusTo(scr, foc);
544 } else {
545 wSetFocusTo(scr, tmp);
550 /* We need to always arrange icons when changing workspace, even if
551 * no autoarrange icons, because else the icons in different workspaces
552 * can be superposed.
553 * This can be avoided if appicons are also workspace specific.
555 if (!wPreferences.sticky_icons)
556 wArrangeIcons(scr, False);
558 if (scr->dock)
559 wAppIconPaint(scr->dock->icon_array[0]);
560 if (scr->clip_icon) {
561 if (scr->workspaces[workspace]->clip->auto_collapse ||
562 scr->workspaces[workspace]->clip->auto_raise_lower) {
563 /* to handle enter notify. This will also */
564 XUnmapWindow(dpy, scr->clip_icon->icon->core->window);
565 XMapWindow(dpy, scr->clip_icon->icon->core->window);
566 } else {
567 wClipIconPaint(scr->clip_icon);
571 showWorkspaceName(scr, workspace);
573 #ifdef GNOME_STUFF
574 wGNOMEUpdateCurrentWorkspaceHint(scr);
575 #endif
576 #ifdef KWM_HINTS
577 wKWMUpdateCurrentWorkspaceHint(scr);
578 #endif
579 /* XSync(dpy, False); */
583 static void
584 switchWSCommand(WMenu *menu, WMenuEntry *entry)
586 wWorkspaceChange(menu->frame->screen_ptr, (long)entry->clientdata);
591 static void
592 deleteWSCommand(WMenu *menu, WMenuEntry *entry)
594 wWorkspaceDelete(menu->frame->screen_ptr,
595 menu->frame->screen_ptr->workspace_count-1);
600 static void
601 newWSCommand(WMenu *menu, WMenuEntry *foo)
603 int ws;
605 ws = wWorkspaceNew(menu->frame->screen_ptr);
606 /* autochange workspace*/
607 if (ws>=0)
608 wWorkspaceChange(menu->frame->screen_ptr, ws);
612 if (ws<9) {
613 int kcode;
614 if (wKeyBindings[WKBD_WORKSPACE1+ws]) {
615 kcode = wKeyBindings[WKBD_WORKSPACE1+ws]->keycode;
616 entry->rtext =
617 wstrdup(XKeysymToString(XKeycodeToKeysym(dpy, kcode, 0)));
623 static char*
624 cropline(char *line)
626 char *start, *end;
628 if (strlen(line)==0)
629 return line;
631 start = line;
632 end = &(line[strlen(line)])-1;
633 while (isspace(*line) && *line!=0) line++;
634 while (isspace(*end) && end!=line) {
635 *end=0;
636 end--;
638 return line;
642 void
643 wWorkspaceRename(WScreen *scr, int workspace, char *name)
645 char buf[MAX_WORKSPACENAME_WIDTH+1];
646 char *tmp;
648 if (workspace >= scr->workspace_count)
649 return;
651 /* trim white spaces */
652 tmp = cropline(name);
654 if (strlen(tmp)==0) {
655 sprintf(buf, _("Workspace %i"), workspace+1);
656 } else {
657 strncpy(buf, tmp, MAX_WORKSPACENAME_WIDTH);
659 buf[MAX_WORKSPACENAME_WIDTH] = 0;
661 /* update workspace */
662 free(scr->workspaces[workspace]->name);
663 scr->workspaces[workspace]->name = wstrdup(buf);
665 if (scr->clip_ws_menu) {
666 if (strcmp(scr->clip_ws_menu->entries[workspace+2]->text, buf)!=0) {
667 free(scr->clip_ws_menu->entries[workspace+2]->text);
668 scr->clip_ws_menu->entries[workspace+2]->text = wstrdup(buf);
669 wMenuRealize(scr->clip_ws_menu);
672 if (scr->workspace_menu) {
673 if (strcmp(scr->workspace_menu->entries[workspace+2]->text, buf)!=0) {
674 free(scr->workspace_menu->entries[workspace+2]->text);
675 scr->workspace_menu->entries[workspace+2]->text = wstrdup(buf);
676 wMenuRealize(scr->workspace_menu);
680 UpdateSwitchMenuWorkspace(scr, workspace);
682 if (scr->clip_icon)
683 wClipIconPaint(scr->clip_icon);
685 #ifdef GNOME_STUFF
686 wGNOMEUpdateWorkspaceNamesHint(scr);
687 #endif
688 #ifdef KWM_HINTS
689 wKWMUpdateWorkspaceNameHint(scr, workspace);
690 #endif
696 /* callback for when menu entry is edited */
697 static void
698 onMenuEntryEdited(WMenu *menu, WMenuEntry *entry)
700 char *tmp;
702 tmp = entry->text;
703 wWorkspaceRename(menu->frame->screen_ptr, (long)entry->clientdata, tmp);
707 WMenu*
708 wWorkspaceMenuMake(WScreen *scr, Bool titled)
710 WMenu *wsmenu;
712 wsmenu = wMenuCreate(scr, titled ? _("Workspaces") : NULL, False);
713 if (!wsmenu) {
714 wwarning(_("could not create Workspace menu"));
715 return NULL;
718 /* callback to be called when an entry is edited */
719 wsmenu->on_edit = onMenuEntryEdited;
721 wMenuAddCallback(wsmenu, _("New"), newWSCommand, NULL);
722 wMenuAddCallback(wsmenu, _("Destroy Last"), deleteWSCommand, NULL);
724 return wsmenu;
729 void
730 wWorkspaceMenuUpdate(WScreen *scr, WMenu *menu)
732 int i;
733 long ws;
734 char title[MAX_WORKSPACENAME_WIDTH+1];
735 WMenuEntry *entry;
736 int tmp;
738 if (!menu)
739 return;
741 if (menu->entry_no < scr->workspace_count+2) {
742 /* new workspace(s) added */
743 i = scr->workspace_count-(menu->entry_no-2);
744 ws = menu->entry_no - 2;
745 while (i>0) {
746 strcpy(title, scr->workspaces[ws]->name);
748 entry = wMenuAddCallback(menu, title, switchWSCommand, (void*)ws);
749 entry->flags.indicator = 1;
750 entry->flags.editable = 1;
752 i--;
753 ws++;
755 } else if (menu->entry_no > scr->workspace_count+2) {
756 /* removed workspace(s) */
757 for (i = menu->entry_no-1; i >= scr->workspace_count+2; i--) {
758 wMenuRemoveItem(menu, i);
761 wMenuRealize(menu);
763 for (i=0; i<scr->workspace_count; i++) {
764 menu->entries[i+2]->flags.indicator_on = 0;
766 menu->entries[scr->current_workspace+2]->flags.indicator_on = 1;
768 /* don't let user destroy current workspace */
769 if (scr->current_workspace == scr->workspace_count-1) {
770 wMenuSetEnabled(menu, 1, False);
771 } else {
772 wMenuSetEnabled(menu, 1, True);
775 tmp = menu->frame->top_width + 5;
776 /* if menu got unreachable, bring it to a visible place */
777 if (menu->frame_x < tmp - (int)menu->frame->core->width)
778 wMenuMove(menu, tmp - (int)menu->frame->core->width, menu->frame_y, False);
780 wMenuPaint(menu);
784 void
785 wWorkspaceSaveState(WScreen *scr, proplist_t old_state)
787 proplist_t parr, pstr;
788 proplist_t wks_state, old_wks_state;
789 proplist_t foo, bar;
790 int i;
792 make_keys();
794 old_wks_state = PLGetDictionaryEntry(old_state, dWorkspaces);
795 parr = PLMakeArrayFromElements(NULL);
796 for (i=0; i < scr->workspace_count; i++) {
797 pstr = PLMakeString(scr->workspaces[i]->name);
798 wks_state = PLMakeDictionaryFromEntries(dName, pstr, NULL);
799 PLRelease(pstr);
800 if (!wPreferences.flags.noclip) {
801 pstr = wClipSaveWorkspaceState(scr, i);
802 PLInsertDictionaryEntry(wks_state, dClip, pstr);
803 PLRelease(pstr);
804 } else if (old_wks_state!=NULL) {
805 if ((foo = PLGetArrayElement(old_wks_state, i))!=NULL) {
806 if ((bar = PLGetDictionaryEntry(foo, dClip))!=NULL) {
807 PLInsertDictionaryEntry(wks_state, dClip, bar);
811 PLAppendArrayElement(parr, wks_state);
812 PLRelease(wks_state);
814 PLInsertDictionaryEntry(scr->session_state, dWorkspaces, parr);
815 PLRelease(parr);
819 void
820 wWorkspaceRestoreState(WScreen *scr)
822 proplist_t parr, pstr, wks_state;
823 proplist_t clip_state;
824 int i, wscount;
826 make_keys();
828 parr = PLGetDictionaryEntry(scr->session_state, dWorkspaces);
830 if (!parr)
831 return;
833 wscount = scr->workspace_count;
834 for (i=0; i < PLGetNumberOfElements(parr); i++) {
835 wks_state = PLGetArrayElement(parr, i);
836 if (PLIsDictionary(wks_state))
837 pstr = PLGetDictionaryEntry(wks_state, dName);
838 else
839 pstr = wks_state;
840 if (i >= scr->workspace_count)
841 wWorkspaceNew(scr);
842 if (scr->workspace_menu) {
843 free(scr->workspace_menu->entries[i+2]->text);
844 scr->workspace_menu->entries[i+2]->text = wstrdup(PLGetString(pstr));
845 scr->workspace_menu->flags.realized = 0;
847 free(scr->workspaces[i]->name);
848 scr->workspaces[i]->name = wstrdup(PLGetString(pstr));
849 if (!wPreferences.flags.noclip) {
850 clip_state = PLGetDictionaryEntry(wks_state, dClip);
851 if (scr->workspaces[i]->clip)
852 wDockDestroy(scr->workspaces[i]->clip);
853 scr->workspaces[i]->clip = wDockRestoreState(scr, clip_state,
854 WM_CLIP);
855 if (i>0)
856 wDockHideIcons(scr->workspaces[i]->clip);
858 #ifdef KWM_HINTS
859 wKWMUpdateWorkspaceNameHint(scr, i);
860 #endif
862 #ifdef GNOME_STUFF
863 wGNOMEUpdateWorkspaceNamesHint(scr);
864 #endif