added collapsing option
[wmaker-crm.git] / src / wdefaults.c
blob0f65e852d250acf999f164d5858edc38bfd866e1
1 /* wdefaults.c - window specific defaults
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.
23 #include "wconfig.h"
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <unistd.h>
28 #include <string.h>
29 #include <ctype.h>
31 #include <X11/Xlib.h>
32 #include <X11/Xutil.h>
33 #include <X11/keysym.h>
35 #include <wraster.h>
38 #include "WindowMaker.h"
39 #include "window.h"
40 #include "screen.h"
41 #include "funcs.h"
42 #include "workspace.h"
43 #include "defaults.h"
44 #include "icon.h"
47 /* Global stuff */
49 extern WPreferences wPreferences;
51 extern proplist_t wAttributeDomainName;
53 extern WDDomain *WDWindowAttributes;
56 /* Local stuff */
59 /* type converters */
60 static int getBool(proplist_t, proplist_t);
62 static char* getString(proplist_t, proplist_t);
65 static proplist_t ANoTitlebar = NULL;
66 static proplist_t ANoResizebar;
67 static proplist_t ANoMiniaturizeButton;
68 static proplist_t ANoCloseButton;
69 static proplist_t ANoBorder;
70 static proplist_t ANoHideOthers;
71 static proplist_t ANoMouseBindings;
72 static proplist_t ANoKeyBindings;
73 static proplist_t ANoAppIcon; /* app */
74 static proplist_t AKeepOnTop;
75 static proplist_t AKeepOnBottom;
76 static proplist_t AOmnipresent;
77 static proplist_t ASkipWindowList;
78 static proplist_t AKeepInsideScreen;
79 static proplist_t AUnfocusable;
80 static proplist_t AAlwaysUserIcon;
81 static proplist_t AStartMiniaturized;
82 static proplist_t AStartMaximized;
83 static proplist_t AStartHidden; /* app */
84 static proplist_t ADontSaveSession; /* app */
85 static proplist_t AEmulateAppIcon;
86 static proplist_t AFullMaximize;
87 static proplist_t ACollapseAppIcons; /* app */
88 #ifdef XKB_BUTTON_HINT
89 static proplist_t ANoLanguageButton;
90 #endif
92 static proplist_t AStartWorkspace;
94 static proplist_t AIcon;
97 static proplist_t AnyWindow;
98 static proplist_t No;
101 static void
102 init_wdefaults(WScreen *scr)
104 AIcon = PLMakeString("Icon");
106 ANoTitlebar = PLMakeString("NoTitlebar");
107 ANoResizebar = PLMakeString("NoResizebar");
108 ANoMiniaturizeButton = PLMakeString("NoMiniaturizeButton");
109 ANoCloseButton = PLMakeString("NoCloseButton");
110 ANoBorder = PLMakeString("NoBorder");
111 ANoHideOthers = PLMakeString("NoHideOthers");
112 ANoMouseBindings = PLMakeString("NoMouseBindings");
113 ANoKeyBindings = PLMakeString("NoKeyBindings");
114 ANoAppIcon = PLMakeString("NoAppIcon");
115 AKeepOnTop = PLMakeString("KeepOnTop");
116 AKeepOnBottom = PLMakeString("KeepOnBottom");
117 AOmnipresent = PLMakeString("Omnipresent");
118 ASkipWindowList = PLMakeString("SkipWindowList");
119 AKeepInsideScreen = PLMakeString("KeepInsideScreen");
120 AUnfocusable = PLMakeString("Unfocusable");
121 AAlwaysUserIcon = PLMakeString("AlwaysUserIcon");
122 AStartMiniaturized = PLMakeString("StartMiniaturized");
123 AStartHidden = PLMakeString("StartHidden");
124 AStartMaximized = PLMakeString("StartMaximized");
125 ADontSaveSession = PLMakeString("DontSaveSession");
126 AEmulateAppIcon = PLMakeString("EmulateAppIcon");
127 AFullMaximize = PLMakeString("FullMaximize");
128 ACollapseAppIcons = PLMakeString("CollapseAppIcons");
129 #ifdef XKB_BUTTON_HINT
130 ANoLanguageButton = PLMakeString("NoLanguageButton");
131 #endif
133 AStartWorkspace = PLMakeString("StartWorkspace");
135 AnyWindow = PLMakeString("*");
136 No = PLMakeString("No");
138 if (!scr->wattribs) {
139 scr->wattribs = PLGetDomain(wAttributeDomainName);
145 static proplist_t
146 get_value(proplist_t dict_win, proplist_t dict_class, proplist_t dict_name,
147 proplist_t dict_any, proplist_t option, proplist_t default_value,
148 Bool useGlobalDefault)
150 proplist_t value;
153 if (dict_win) {
154 value = PLGetDictionaryEntry(dict_win, option);
155 if (value)
156 return value;
159 if (dict_name) {
160 value = PLGetDictionaryEntry(dict_name, option);
161 if (value)
162 return value;
165 if (dict_class) {
166 value = PLGetDictionaryEntry(dict_class, option);
167 if (value)
168 return value;
171 if (!useGlobalDefault)
172 return NULL;
174 if (dict_any) {
175 value = PLGetDictionaryEntry(dict_any, option);
176 if (value)
177 return value;
180 return default_value;
185 *----------------------------------------------------------------------
186 * wDefaultFillAttributes--
187 * Retrieves attributes for the specified instance/class and
188 * fills attr with it. Values that are actually defined are also
189 * set in mask. If useGlobalDefault is True, the default for
190 * all windows ("*") will be used for when no values are found
191 * for that instance/class.
193 *----------------------------------------------------------------------
195 void
196 wDefaultFillAttributes(WScreen *scr, char *instance, char *class,
197 WWindowAttributes *attr,
198 WWindowAttributes *mask,
199 Bool useGlobalDefault)
201 proplist_t value;
202 proplist_t key1, key2, key3;
203 proplist_t dw, dc, dn, da;
206 if (class && instance) {
207 char *buffer = NULL;
208 buffer = wmalloc(strlen(class)+strlen(instance)+4);
209 key1 = PLMakeString(strcat(strcat(strcpy(buffer,instance),"."),class));
210 wfree(buffer);
211 } else
212 key1 = NULL;
214 if (instance)
215 key2 = PLMakeString(instance);
216 else
217 key2 = NULL;
219 if (class)
220 key3 = PLMakeString(class);
221 else
222 key3 = NULL;
224 if (!ANoTitlebar) {
225 init_wdefaults(scr);
228 PLSetStringCmpHook(NULL);
230 if (WDWindowAttributes->dictionary) {
231 dw = key1 ? PLGetDictionaryEntry(WDWindowAttributes->dictionary, key1) : NULL;
232 dn = key2 ? PLGetDictionaryEntry(WDWindowAttributes->dictionary, key2) : NULL;
233 dc = key3 ? PLGetDictionaryEntry(WDWindowAttributes->dictionary, key3) : NULL;
234 if (useGlobalDefault)
235 da = PLGetDictionaryEntry(WDWindowAttributes->dictionary, AnyWindow);
236 else
237 da = NULL;
238 } else {
239 dw = NULL;
240 dn = NULL;
241 dc = NULL;
242 da = NULL;
244 if (key1)
245 PLRelease(key1);
246 if (key2)
247 PLRelease(key2);
248 if (key3)
249 PLRelease(key3);
251 #define APPLY_VAL(value, flag, attrib) \
252 if (value) {attr->flag = getBool(attrib, value); \
253 if (mask) mask->flag = 1;}
255 /* get the data */
256 value = get_value(dw, dc, dn, da, ANoTitlebar, No, useGlobalDefault);
257 APPLY_VAL(value, no_titlebar, ANoTitlebar);
259 value = get_value(dw, dc, dn, da, ANoResizebar, No, useGlobalDefault);
260 APPLY_VAL(value, no_resizebar, ANoResizebar);
262 value = get_value(dw, dc, dn, da, ANoMiniaturizeButton, No, useGlobalDefault);
263 APPLY_VAL(value, no_miniaturize_button, ANoMiniaturizeButton);
265 value = get_value(dw, dc, dn, da, ANoCloseButton, No, useGlobalDefault);
266 APPLY_VAL(value, no_close_button, ANoCloseButton);
268 value = get_value(dw, dc, dn, da, ANoBorder, No, useGlobalDefault);
269 APPLY_VAL(value, no_border, ANoBorder);
271 value = get_value(dw, dc, dn, da, ANoHideOthers, No, useGlobalDefault);
272 APPLY_VAL(value, no_hide_others, ANoHideOthers);
274 value = get_value(dw, dc, dn, da, ANoMouseBindings, No, useGlobalDefault);
275 APPLY_VAL(value, no_bind_mouse, ANoMouseBindings);
277 value = get_value(dw, dc, dn, da, ANoKeyBindings, No, useGlobalDefault);
278 APPLY_VAL(value, no_bind_keys, ANoKeyBindings);
280 value = get_value(dw, dc, dn, da, ANoAppIcon, No, useGlobalDefault);
281 APPLY_VAL(value, no_appicon, ANoAppIcon);
283 value = get_value(dw, dc, dn, da, ACollapseAppIcons, No, useGlobalDefault);
284 APPLY_VAL(value, collapse_appicons, ACollapseAppIcons);
286 value = get_value(dw, dc, dn, da, AKeepOnTop, No, useGlobalDefault);
287 APPLY_VAL(value, floating, AKeepOnTop);
289 value = get_value(dw, dc, dn, da, AKeepOnBottom, No, useGlobalDefault);
290 APPLY_VAL(value, sunken, AKeepOnBottom);
292 value = get_value(dw, dc, dn, da, AOmnipresent, No, useGlobalDefault);
293 APPLY_VAL(value, omnipresent, AOmnipresent);
295 value = get_value(dw, dc, dn, da, ASkipWindowList, No, useGlobalDefault);
296 APPLY_VAL(value, skip_window_list, ASkipWindowList);
298 value = get_value(dw, dc, dn, da, AKeepInsideScreen, No, useGlobalDefault);
299 APPLY_VAL(value, dont_move_off, AKeepInsideScreen);
301 value = get_value(dw, dc, dn, da, AUnfocusable, No, useGlobalDefault);
302 APPLY_VAL(value, no_focusable, AUnfocusable);
304 value = get_value(dw, dc, dn, da, AAlwaysUserIcon, No, useGlobalDefault);
305 APPLY_VAL(value, always_user_icon, AAlwaysUserIcon);
307 value = get_value(dw, dc, dn, da, AStartMiniaturized, No, useGlobalDefault);
308 APPLY_VAL(value, start_miniaturized, AStartMiniaturized);
310 value = get_value(dw, dc, dn, da, AStartHidden, No, useGlobalDefault);
311 APPLY_VAL(value, start_hidden, AStartHidden);
313 value = get_value(dw, dc, dn, da, AStartMaximized, No, useGlobalDefault);
314 APPLY_VAL(value, start_maximized, AStartMaximized);
316 value = get_value(dw, dc, dn, da, ADontSaveSession, No, useGlobalDefault);
317 APPLY_VAL(value, dont_save_session, ADontSaveSession);
319 value = get_value(dw, dc, dn, da, AEmulateAppIcon, No, useGlobalDefault);
320 APPLY_VAL(value, emulate_appicon, AEmulateAppIcon);
322 value = get_value(dw, dc, dn, da, AFullMaximize, No, useGlobalDefault);
323 APPLY_VAL(value, full_maximize, AFullMaximize);
325 #ifdef XKB_BUTTON_HINT
326 value = get_value(dw, dc, dn, da, ANoLanguageButton, No, useGlobalDefault);
327 APPLY_VAL(value, no_language_button, ANoLanguageButton);
328 #endif
330 /* clean up */
331 PLSetStringCmpHook(StringCompareHook);
336 proplist_t
337 get_generic_value(WScreen *scr, char *instance, char *class, proplist_t option,
338 Bool noDefault)
340 proplist_t value, key, dict;
342 value = NULL;
344 PLSetStringCmpHook(NULL);
346 if (class && instance) {
347 char *buffer = NULL;
348 buffer = wmalloc(strlen(class)+strlen(instance)+4);
349 key = PLMakeString(strcat(strcat(strcpy(buffer,instance),"."),class));
351 dict = PLGetDictionaryEntry(WDWindowAttributes->dictionary, key);
352 PLRelease(key);
353 wfree(buffer);
355 if (dict) {
356 value = PLGetDictionaryEntry(dict, option);
360 if (!value && instance) {
361 key = PLMakeString(instance);
363 dict = PLGetDictionaryEntry(WDWindowAttributes->dictionary, key);
364 PLRelease(key);
365 if (dict) {
366 value = PLGetDictionaryEntry(dict, option);
370 if (!value && class) {
371 key = PLMakeString(class);
373 dict = PLGetDictionaryEntry(WDWindowAttributes->dictionary, key);
374 PLRelease(key);
376 if (dict) {
377 value = PLGetDictionaryEntry(dict, option);
381 if (!value && !noDefault) {
382 dict = PLGetDictionaryEntry(WDWindowAttributes->dictionary, AnyWindow);
384 if (dict) {
385 value = PLGetDictionaryEntry(dict, option);
389 PLSetStringCmpHook(StringCompareHook);
391 return value;
395 char*
396 wDefaultGetIconFile(WScreen *scr, char *instance, char *class,
397 Bool noDefault)
399 proplist_t value;
400 char *tmp;
402 if (!ANoTitlebar) {
403 init_wdefaults(scr);
406 if (!WDWindowAttributes->dictionary)
407 return NULL;
409 value = get_generic_value(scr, instance, class, AIcon, noDefault);
411 if (!value)
412 return NULL;
414 tmp = getString(AIcon, value);
416 return tmp;
420 RImage*
421 wDefaultGetImage(WScreen *scr, char *winstance, char *wclass)
423 char *file_name;
424 char *path;
425 RImage *image;
427 file_name = wDefaultGetIconFile(scr, winstance, wclass, False);
428 if (!file_name)
429 return NULL;
431 path = FindImage(wPreferences.icon_path, file_name);
433 if (!path) {
434 wwarning(_("could not find icon file \"%s\""), file_name);
435 return NULL;
438 image = RLoadImage(scr->rcontext, path, 0);
439 if (!image) {
440 wwarning(_("error loading image file \"%s\""), path, RMessageForError(RErrorCode));
442 wfree(path);
444 image = wIconValidateIconSize(scr, image);
446 return image;
451 wDefaultGetStartWorkspace(WScreen *scr, char *instance, char *class)
453 proplist_t value;
454 int w, i;
455 char *tmp;
457 if (!ANoTitlebar) {
458 init_wdefaults(scr);
461 if (!WDWindowAttributes->dictionary)
462 return -1;
464 value = get_generic_value(scr, instance, class, AStartWorkspace,
465 False);
467 if (!value)
468 return -1;
470 tmp = getString(AStartWorkspace, value);
472 if (!tmp || strlen(tmp)==0)
473 return -1;
475 if (sscanf(tmp, "%i", &w)!=1) {
476 w = -1;
477 for (i=0; i < scr->workspace_count; i++) {
478 if (strcmp(scr->workspaces[i]->name, tmp)==0) {
479 w = i;
480 break;
483 } else {
484 w--;
487 return w;
491 void
492 wDefaultChangeIcon(WScreen *scr, char *instance, char* class, char *file)
494 WDDomain *db = WDWindowAttributes;
495 proplist_t icon_value=NULL, value, attr, key, def_win, def_icon=NULL;
496 proplist_t dict = db->dictionary;
497 int same = 0;
499 if (!dict) {
500 dict = PLMakeDictionaryFromEntries(NULL, NULL, NULL);
501 if (dict) {
502 db->dictionary = dict;
503 value = PLMakeString(db->path);
504 PLSetFilename(dict, value);
505 PLRelease(value);
507 else
508 return;
511 PLSetStringCmpHook(NULL);
513 if (instance && class) {
514 char *buffer;
515 buffer = wmalloc(strlen(instance) + strlen(class) + 2);
516 strcat(strcat(strcpy(buffer, instance), "."), class);
517 key = PLMakeString(buffer);
518 wfree(buffer);
519 } else if (instance) {
520 key = PLMakeString(instance);
521 } else if (class) {
522 key = PLMakeString(class);
523 } else {
524 key = PLRetain(AnyWindow);
527 if (file) {
528 value = PLMakeString(file);
529 icon_value = PLMakeDictionaryFromEntries(AIcon, value, NULL);
530 PLRelease(value);
532 if ((def_win = PLGetDictionaryEntry(dict, AnyWindow)) != NULL) {
533 def_icon = PLGetDictionaryEntry(def_win, AIcon);
536 if (def_icon && !strcmp(PLGetString(def_icon), file))
537 same = 1;
540 if ((attr = PLGetDictionaryEntry(dict, key)) != NULL) {
541 if (PLIsDictionary(attr)) {
542 if (icon_value!=NULL && !same)
543 PLMergeDictionaries(attr, icon_value);
544 else
545 PLRemoveDictionaryEntry(attr, AIcon);
547 } else if (icon_value!=NULL && !same) {
548 PLInsertDictionaryEntry(dict, key, icon_value);
550 if (!wPreferences.flags.noupdates)
551 PLSave(dict, YES);
553 PLRelease(key);
554 if(icon_value)
555 PLRelease(icon_value);
557 PLSetStringCmpHook(StringCompareHook);
562 /* --------------------------- Local ----------------------- */
564 static int
565 getBool(proplist_t key, proplist_t value)
567 char *val;
569 if (!PLIsString(value)) {
570 wwarning(_("Wrong option format for key \"%s\". Should be %s."),
571 PLGetString(key), "Boolean");
572 return 0;
574 val = PLGetString(value);
576 if ((val[1]=='\0' && (val[0]=='y' || val[0]=='Y' || val[0]=='T'
577 || val[0]=='t' || val[0]=='1'))
578 || (strcasecmp(val, "YES")==0 || strcasecmp(val, "TRUE")==0)) {
580 return 1;
581 } else if ((val[1]=='\0'
582 && (val[0]=='n' || val[0]=='N' || val[0]=='F'
583 || val[0]=='f' || val[0]=='0'))
584 || (strcasecmp(val, "NO")==0 || strcasecmp(val, "FALSE")==0)) {
586 return 0;
587 } else {
588 wwarning(_("can't convert \"%s\" to boolean"), val);
589 /* We return False if we can't convert to BOOLEAN.
590 * This is because all options defaults to False.
591 * -1 is not checked and thus is interpreted as True,
592 * which is not good.*/
593 return 0;
600 * WARNING: Do not free value returned by this!!
602 static char*
603 getString(proplist_t key, proplist_t value)
605 if (!PLIsString(value)) {
606 wwarning(_("Wrong option format for key \"%s\". Should be %s."),
607 PLGetString(key), "String");
608 return NULL;
611 return PLGetString(value);