Make 'no miniaturizable' window property user-configurable
[wmaker-crm.git] / src / wdefaults.c
blobeba25732a76f38001f1140af049e36f3a3c366e7
1 /* wdefaults.c - window specific defaults
3 * Window Maker window manager
5 * Copyright (c) 1997-2003 Alfredo K. Kojima
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 along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 #include "wconfig.h"
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <unistd.h>
27 #include <string.h>
28 #include <strings.h>
29 #include <ctype.h>
31 #include <X11/Xlib.h>
32 #include <X11/Xutil.h>
33 #include <X11/keysym.h>
35 #include <wraster.h>
37 #include "WindowMaker.h"
38 #include "window.h"
39 #include "screen.h"
40 #include "funcs.h"
41 #include "workspace.h"
42 #include "defaults.h"
43 #include "icon.h"
45 /* Global stuff */
46 extern WPreferences wPreferences;
47 extern WMPropList *wAttributeDomainName;
48 extern WDDomain *WDWindowAttributes;
50 /* Local stuff */
52 /* type converters */
53 static int getBool(WMPropList *, WMPropList *);
54 static char *getString(WMPropList *, WMPropList *);
55 static WMPropList *ANoTitlebar = NULL;
56 static WMPropList *ANoResizebar;
57 static WMPropList *ANoMiniaturizeButton;
58 static WMPropList *ANoMiniaturizable;
59 static WMPropList *ANoCloseButton;
60 static WMPropList *ANoBorder;
61 static WMPropList *ANoHideOthers;
62 static WMPropList *ANoMouseBindings;
63 static WMPropList *ANoKeyBindings;
64 static WMPropList *ANoAppIcon; /* app */
65 static WMPropList *AKeepOnTop;
66 static WMPropList *AKeepOnBottom;
67 static WMPropList *AOmnipresent;
68 static WMPropList *ASkipWindowList;
69 static WMPropList *ASkipSwitchPanel;
70 static WMPropList *AKeepInsideScreen;
71 static WMPropList *AUnfocusable;
72 static WMPropList *AAlwaysUserIcon;
73 static WMPropList *AStartMiniaturized;
74 static WMPropList *AStartMaximized;
75 static WMPropList *AStartHidden; /* app */
76 static WMPropList *ADontSaveSession; /* app */
77 static WMPropList *AEmulateAppIcon;
78 static WMPropList *AFocusAcrossWorkspace;
79 static WMPropList *AFullMaximize;
80 static WMPropList *ASharedAppIcon; /* app */
81 #ifdef XKB_BUTTON_HINT
82 static WMPropList *ANoLanguageButton;
83 #endif
84 static WMPropList *AStartWorkspace;
85 static WMPropList *AIcon;
86 static WMPropList *AnyWindow;
87 static WMPropList *No;
89 static void init_wdefaults(WScreen * scr)
91 AIcon = WMCreatePLString("Icon");
93 ANoTitlebar = WMCreatePLString("NoTitlebar");
94 ANoResizebar = WMCreatePLString("NoResizebar");
95 ANoMiniaturizeButton = WMCreatePLString("NoMiniaturizeButton");
96 ANoMiniaturizable = WMCreatePLString("NoMiniaturizable");
97 ANoCloseButton = WMCreatePLString("NoCloseButton");
98 ANoBorder = WMCreatePLString("NoBorder");
99 ANoHideOthers = WMCreatePLString("NoHideOthers");
100 ANoMouseBindings = WMCreatePLString("NoMouseBindings");
101 ANoKeyBindings = WMCreatePLString("NoKeyBindings");
102 ANoAppIcon = WMCreatePLString("NoAppIcon");
103 AKeepOnTop = WMCreatePLString("KeepOnTop");
104 AKeepOnBottom = WMCreatePLString("KeepOnBottom");
105 AOmnipresent = WMCreatePLString("Omnipresent");
106 ASkipWindowList = WMCreatePLString("SkipWindowList");
107 ASkipSwitchPanel = WMCreatePLString("SkipSwitchPanel");
108 AKeepInsideScreen = WMCreatePLString("KeepInsideScreen");
109 AUnfocusable = WMCreatePLString("Unfocusable");
110 AAlwaysUserIcon = WMCreatePLString("AlwaysUserIcon");
111 AStartMiniaturized = WMCreatePLString("StartMiniaturized");
112 AStartHidden = WMCreatePLString("StartHidden");
113 AStartMaximized = WMCreatePLString("StartMaximized");
114 ADontSaveSession = WMCreatePLString("DontSaveSession");
115 AEmulateAppIcon = WMCreatePLString("EmulateAppIcon");
116 AFocusAcrossWorkspace = WMCreatePLString("FocusAcrossWorkspace");
117 AFullMaximize = WMCreatePLString("FullMaximize");
118 ASharedAppIcon = WMCreatePLString("SharedAppIcon");
119 #ifdef XKB_BUTTON_HINT
120 ANoLanguageButton = WMCreatePLString("NoLanguageButton");
121 #endif
123 AStartWorkspace = WMCreatePLString("StartWorkspace");
125 AnyWindow = WMCreatePLString("*");
126 No = WMCreatePLString("No");
128 if (!scr->wattribs) {
129 scr->wattribs = PLGetDomain(wAttributeDomainName);
130 } */
133 static WMPropList *get_value(WMPropList * dict_win, WMPropList * dict_class, WMPropList * dict_name,
134 WMPropList * dict_any, WMPropList * option, WMPropList * default_value,
135 Bool useGlobalDefault)
137 WMPropList *value;
139 if (dict_win) {
140 value = WMGetFromPLDictionary(dict_win, option);
141 if (value)
142 return value;
145 if (dict_name) {
146 value = WMGetFromPLDictionary(dict_name, option);
147 if (value)
148 return value;
151 if (dict_class) {
152 value = WMGetFromPLDictionary(dict_class, option);
153 if (value)
154 return value;
157 if (!useGlobalDefault)
158 return NULL;
160 if (dict_any) {
161 value = WMGetFromPLDictionary(dict_any, option);
162 if (value)
163 return value;
166 return default_value;
170 *----------------------------------------------------------------------
171 * wDefaultFillAttributes--
172 * Retrieves attributes for the specified instance/class and
173 * fills attr with it. Values that are actually defined are also
174 * set in mask. If useGlobalDefault is True, the default for
175 * all windows ("*") will be used for when no values are found
176 * for that instance/class.
178 *----------------------------------------------------------------------
180 void
181 wDefaultFillAttributes(WScreen * scr, char *instance, char *class,
182 WWindowAttributes * attr, WWindowAttributes * mask, Bool useGlobalDefault)
184 WMPropList *value, *key1, *key2, *key3, *dw, *dc, *dn, *da;
186 if (class && instance) {
187 char *buffer;
189 buffer = wmalloc(strlen(class) + strlen(instance) + 2);
190 sprintf(buffer, "%s.%s", instance, class);
191 key1 = WMCreatePLString(buffer);
192 wfree(buffer);
193 } else {
194 key1 = NULL;
197 if (instance)
198 key2 = WMCreatePLString(instance);
199 else
200 key2 = NULL;
202 if (class)
203 key3 = WMCreatePLString(class);
204 else
205 key3 = NULL;
207 if (!ANoTitlebar) {
208 init_wdefaults(scr);
211 WMPLSetCaseSensitive(True);
213 if (WDWindowAttributes->dictionary) {
214 dw = key1 ? WMGetFromPLDictionary(WDWindowAttributes->dictionary, key1) : NULL;
215 dn = key2 ? WMGetFromPLDictionary(WDWindowAttributes->dictionary, key2) : NULL;
216 dc = key3 ? WMGetFromPLDictionary(WDWindowAttributes->dictionary, key3) : NULL;
217 if (useGlobalDefault)
218 da = WMGetFromPLDictionary(WDWindowAttributes->dictionary, AnyWindow);
219 else
220 da = NULL;
221 } else {
222 dw = NULL;
223 dn = NULL;
224 dc = NULL;
225 da = NULL;
227 if (key1)
228 WMReleasePropList(key1);
229 if (key2)
230 WMReleasePropList(key2);
231 if (key3)
232 WMReleasePropList(key3);
234 #define APPLY_VAL(value, flag, attrib) \
235 if (value) {attr->flag = getBool(attrib, value); \
236 if (mask) mask->flag = 1;}
238 /* get the data */
239 value = get_value(dw, dc, dn, da, ANoTitlebar, No, useGlobalDefault);
240 APPLY_VAL(value, no_titlebar, ANoTitlebar);
242 value = get_value(dw, dc, dn, da, ANoResizebar, No, useGlobalDefault);
243 APPLY_VAL(value, no_resizebar, ANoResizebar);
245 value = get_value(dw, dc, dn, da, ANoMiniaturizeButton, No, useGlobalDefault);
246 APPLY_VAL(value, no_miniaturize_button, ANoMiniaturizeButton);
248 value = get_value(dw, dc, dn, da, ANoMiniaturizable, No, useGlobalDefault);
249 APPLY_VAL(value, no_miniaturizable, ANoMiniaturizable);
251 value = get_value(dw, dc, dn, da, ANoCloseButton, No, useGlobalDefault);
252 APPLY_VAL(value, no_close_button, ANoCloseButton);
254 value = get_value(dw, dc, dn, da, ANoBorder, No, useGlobalDefault);
255 APPLY_VAL(value, no_border, ANoBorder);
257 value = get_value(dw, dc, dn, da, ANoHideOthers, No, useGlobalDefault);
258 APPLY_VAL(value, no_hide_others, ANoHideOthers);
260 value = get_value(dw, dc, dn, da, ANoMouseBindings, No, useGlobalDefault);
261 APPLY_VAL(value, no_bind_mouse, ANoMouseBindings);
263 value = get_value(dw, dc, dn, da, ANoKeyBindings, No, useGlobalDefault);
264 APPLY_VAL(value, no_bind_keys, ANoKeyBindings);
266 value = get_value(dw, dc, dn, da, ANoAppIcon, No, useGlobalDefault);
267 APPLY_VAL(value, no_appicon, ANoAppIcon);
269 value = get_value(dw, dc, dn, da, ASharedAppIcon, No, useGlobalDefault);
270 APPLY_VAL(value, shared_appicon, ASharedAppIcon);
272 value = get_value(dw, dc, dn, da, AKeepOnTop, No, useGlobalDefault);
273 APPLY_VAL(value, floating, AKeepOnTop);
275 value = get_value(dw, dc, dn, da, AKeepOnBottom, No, useGlobalDefault);
276 APPLY_VAL(value, sunken, AKeepOnBottom);
278 value = get_value(dw, dc, dn, da, AOmnipresent, No, useGlobalDefault);
279 APPLY_VAL(value, omnipresent, AOmnipresent);
281 value = get_value(dw, dc, dn, da, ASkipWindowList, No, useGlobalDefault);
282 APPLY_VAL(value, skip_window_list, ASkipWindowList);
284 value = get_value(dw, dc, dn, da, ASkipSwitchPanel, No, useGlobalDefault);
285 APPLY_VAL(value, skip_switchpanel, ASkipSwitchPanel);
287 value = get_value(dw, dc, dn, da, AKeepInsideScreen, No, useGlobalDefault);
288 APPLY_VAL(value, dont_move_off, AKeepInsideScreen);
290 value = get_value(dw, dc, dn, da, AUnfocusable, No, useGlobalDefault);
291 APPLY_VAL(value, no_focusable, AUnfocusable);
293 value = get_value(dw, dc, dn, da, AAlwaysUserIcon, No, useGlobalDefault);
294 APPLY_VAL(value, always_user_icon, AAlwaysUserIcon);
296 value = get_value(dw, dc, dn, da, AStartMiniaturized, No, useGlobalDefault);
297 APPLY_VAL(value, start_miniaturized, AStartMiniaturized);
299 value = get_value(dw, dc, dn, da, AStartHidden, No, useGlobalDefault);
300 APPLY_VAL(value, start_hidden, AStartHidden);
302 value = get_value(dw, dc, dn, da, AStartMaximized, No, useGlobalDefault);
303 APPLY_VAL(value, start_maximized, AStartMaximized);
305 value = get_value(dw, dc, dn, da, ADontSaveSession, No, useGlobalDefault);
306 APPLY_VAL(value, dont_save_session, ADontSaveSession);
308 value = get_value(dw, dc, dn, da, AEmulateAppIcon, No, useGlobalDefault);
309 APPLY_VAL(value, emulate_appicon, AEmulateAppIcon);
311 value = get_value(dw, dc, dn, da, AFocusAcrossWorkspace, No, useGlobalDefault);
312 APPLY_VAL(value, focus_across_wksp, AFocusAcrossWorkspace);
314 value = get_value(dw, dc, dn, da, AFullMaximize, No, useGlobalDefault);
315 APPLY_VAL(value, full_maximize, AFullMaximize);
317 #ifdef XKB_BUTTON_HINT
318 value = get_value(dw, dc, dn, da, ANoLanguageButton, No, useGlobalDefault);
319 APPLY_VAL(value, no_language_button, ANoLanguageButton);
320 #endif
322 /* clean up */
323 WMPLSetCaseSensitive(False);
326 static WMPropList *get_generic_value(WScreen *scr, char *instance, char *class,
327 WMPropList *option, Bool noDefault)
329 WMPropList *value, *key, *dict;
331 value = NULL;
333 WMPLSetCaseSensitive(True);
335 if (class && instance) {
336 char *buffer;
338 buffer = wmalloc(strlen(class) + strlen(instance) + 2);
339 sprintf(buffer, "%s.%s", instance, class);
340 key = WMCreatePLString(buffer);
341 wfree(buffer);
343 dict = WMGetFromPLDictionary(WDWindowAttributes->dictionary, key);
344 WMReleasePropList(key);
346 if (dict) {
347 value = WMGetFromPLDictionary(dict, option);
351 if (!value && instance) {
352 key = WMCreatePLString(instance);
354 dict = WMGetFromPLDictionary(WDWindowAttributes->dictionary, key);
355 WMReleasePropList(key);
356 if (dict) {
357 value = WMGetFromPLDictionary(dict, option);
361 if (!value && class) {
362 key = WMCreatePLString(class);
364 dict = WMGetFromPLDictionary(WDWindowAttributes->dictionary, key);
365 WMReleasePropList(key);
367 if (dict) {
368 value = WMGetFromPLDictionary(dict, option);
372 if (!value && !noDefault) {
373 dict = WMGetFromPLDictionary(WDWindowAttributes->dictionary, AnyWindow);
375 if (dict) {
376 value = WMGetFromPLDictionary(dict, option);
380 WMPLSetCaseSensitive(False);
382 return value;
385 char *wDefaultGetIconFile(WScreen * scr, char *instance, char *class, Bool noDefault)
387 WMPropList *value;
388 char *tmp;
390 if (!ANoTitlebar) {
391 init_wdefaults(scr);
394 if (!WDWindowAttributes->dictionary)
395 return NULL;
397 value = get_generic_value(scr, instance, class, AIcon, noDefault);
399 if (!value)
400 return NULL;
402 tmp = getString(AIcon, value);
404 return tmp;
407 RImage *wDefaultGetImage(WScreen * scr, char *winstance, char *wclass)
409 char *file_name;
410 char *path;
411 RImage *image;
413 file_name = wDefaultGetIconFile(scr, winstance, wclass, False);
414 if (!file_name)
415 return NULL;
417 path = FindImage(wPreferences.icon_path, file_name);
419 if (!path) {
420 wwarning(_("could not find icon file \"%s\""), file_name);
421 return NULL;
424 image = RLoadImage(scr->rcontext, path, 0);
425 if (!image) {
426 wwarning(_("error loading image file \"%s\": %s"), path, RMessageForError(RErrorCode));
428 wfree(path);
430 image = wIconValidateIconSize(scr, image);
432 return image;
435 int wDefaultGetStartWorkspace(WScreen * scr, char *instance, char *class)
437 WMPropList *value;
438 int w, i;
439 char *tmp;
441 if (!ANoTitlebar) {
442 init_wdefaults(scr);
445 if (!WDWindowAttributes->dictionary)
446 return -1;
448 value = get_generic_value(scr, instance, class, AStartWorkspace, False);
450 if (!value)
451 return -1;
453 tmp = getString(AStartWorkspace, value);
455 if (!tmp || strlen(tmp) == 0)
456 return -1;
458 if (sscanf(tmp, "%i", &w) != 1) {
459 w = -1;
460 for (i = 0; i < scr->workspace_count; i++) {
461 if (strcmp(scr->workspaces[i]->name, tmp) == 0) {
462 w = i;
463 break;
466 } else {
467 w--;
470 return w;
473 void wDefaultChangeIcon(WScreen * scr, char *instance, char *class, char *file)
475 WDDomain *db = WDWindowAttributes;
476 WMPropList *icon_value = NULL, *value, *attr, *key, *def_win, *def_icon = NULL;
477 WMPropList *dict = db->dictionary;
478 int same = 0;
480 if (!dict) {
481 dict = WMCreatePLDictionary(NULL, NULL);
482 if (dict) {
483 db->dictionary = dict;
484 } else {
485 return;
489 WMPLSetCaseSensitive(True);
491 if (instance && class) {
492 char *buffer;
493 buffer = wmalloc(strlen(instance) + strlen(class) + 2);
494 sprintf(buffer, "%s.%s", instance, class);
495 key = WMCreatePLString(buffer);
496 wfree(buffer);
497 } else if (instance) {
498 key = WMCreatePLString(instance);
499 } else if (class) {
500 key = WMCreatePLString(class);
501 } else {
502 key = WMRetainPropList(AnyWindow);
505 if (file) {
506 value = WMCreatePLString(file);
507 icon_value = WMCreatePLDictionary(AIcon, value, NULL);
508 WMReleasePropList(value);
510 if ((def_win = WMGetFromPLDictionary(dict, AnyWindow)) != NULL) {
511 def_icon = WMGetFromPLDictionary(def_win, AIcon);
514 if (def_icon && !strcmp(WMGetFromPLString(def_icon), file))
515 same = 1;
518 if ((attr = WMGetFromPLDictionary(dict, key)) != NULL) {
519 if (WMIsPLDictionary(attr)) {
520 if (icon_value != NULL && !same)
521 WMMergePLDictionaries(attr, icon_value, False);
522 else
523 WMRemoveFromPLDictionary(attr, AIcon);
525 } else if (icon_value != NULL && !same) {
526 WMPutInPLDictionary(dict, key, icon_value);
528 if (!wPreferences.flags.noupdates) {
529 UpdateDomainFile(db);
532 WMReleasePropList(key);
533 if (icon_value)
534 WMReleasePropList(icon_value);
536 WMPLSetCaseSensitive(False);
539 /* --------------------------- Local ----------------------- */
541 static int getBool(WMPropList * key, WMPropList * value)
543 char *val;
545 if (!WMIsPLString(value)) {
546 wwarning(_("Wrong option format for key \"%s\". Should be %s."),
547 WMGetFromPLString(key), "Boolean");
548 return 0;
550 val = WMGetFromPLString(value);
552 if ((val[1] == '\0' && (val[0] == 'y' || val[0] == 'Y' || val[0] == 'T' || val[0] == 't' || val[0] == '1'))
553 || (strcasecmp(val, "YES") == 0 || strcasecmp(val, "TRUE") == 0)) {
555 return 1;
556 } else if ((val[1] == '\0'
557 && (val[0] == 'n' || val[0] == 'N' || val[0] == 'F' || val[0] == 'f' || val[0] == '0'))
558 || (strcasecmp(val, "NO") == 0 || strcasecmp(val, "FALSE") == 0)) {
560 return 0;
561 } else {
562 wwarning(_("can't convert \"%s\" to boolean"), val);
563 /* We return False if we can't convert to BOOLEAN.
564 * This is because all options defaults to False.
565 * -1 is not checked and thus is interpreted as True,
566 * which is not good.*/
567 return 0;
571 /* WARNING: Do not free the value returned by this function!! */
572 static char *getString(WMPropList * key, WMPropList * value)
574 if (!WMIsPLString(value)) {
575 wwarning(_("Wrong option format for key \"%s\". Should be %s."), WMGetFromPLString(key), "String");
576 return NULL;
579 return WMGetFromPLString(value);