Improve dockapp recognition
[wmaker-crm.git] / src / wdefaults.c
blob9189fa7ec5ba8ce320ce7f25294c02a603a7c86a
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
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>
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 *ANoCloseButton;
59 static WMPropList *ANoBorder;
60 static WMPropList *ANoHideOthers;
61 static WMPropList *ANoMouseBindings;
62 static WMPropList *ANoKeyBindings;
63 static WMPropList *ANoAppIcon; /* app */
64 static WMPropList *AKeepOnTop;
65 static WMPropList *AKeepOnBottom;
66 static WMPropList *AOmnipresent;
67 static WMPropList *ASkipWindowList;
68 static WMPropList *AKeepInsideScreen;
69 static WMPropList *AUnfocusable;
70 static WMPropList *AAlwaysUserIcon;
71 static WMPropList *AStartMiniaturized;
72 static WMPropList *AStartMaximized;
73 static WMPropList *AStartHidden; /* app */
74 static WMPropList *ADontSaveSession; /* app */
75 static WMPropList *AEmulateAppIcon;
76 static WMPropList *ADontFocusAcrossWorkspace;
77 static WMPropList *AFullMaximize;
78 static WMPropList *ASharedAppIcon; /* app */
79 #ifdef XKB_BUTTON_HINT
80 static WMPropList *ANoLanguageButton;
81 #endif
82 static WMPropList *AStartWorkspace;
83 static WMPropList *AIcon;
84 static WMPropList *AnyWindow;
85 static WMPropList *No;
87 static void init_wdefaults(WScreen * scr)
89 AIcon = WMCreatePLString("Icon");
91 ANoTitlebar = WMCreatePLString("NoTitlebar");
92 ANoResizebar = WMCreatePLString("NoResizebar");
93 ANoMiniaturizeButton = WMCreatePLString("NoMiniaturizeButton");
94 ANoCloseButton = WMCreatePLString("NoCloseButton");
95 ANoBorder = WMCreatePLString("NoBorder");
96 ANoHideOthers = WMCreatePLString("NoHideOthers");
97 ANoMouseBindings = WMCreatePLString("NoMouseBindings");
98 ANoKeyBindings = WMCreatePLString("NoKeyBindings");
99 ANoAppIcon = WMCreatePLString("NoAppIcon");
100 AKeepOnTop = WMCreatePLString("KeepOnTop");
101 AKeepOnBottom = WMCreatePLString("KeepOnBottom");
102 AOmnipresent = WMCreatePLString("Omnipresent");
103 ASkipWindowList = WMCreatePLString("SkipWindowList");
104 AKeepInsideScreen = WMCreatePLString("KeepInsideScreen");
105 AUnfocusable = WMCreatePLString("Unfocusable");
106 AAlwaysUserIcon = WMCreatePLString("AlwaysUserIcon");
107 AStartMiniaturized = WMCreatePLString("StartMiniaturized");
108 AStartHidden = WMCreatePLString("StartHidden");
109 AStartMaximized = WMCreatePLString("StartMaximized");
110 ADontSaveSession = WMCreatePLString("DontSaveSession");
111 AEmulateAppIcon = WMCreatePLString("EmulateAppIcon");
112 ADontFocusAcrossWorkspace = WMCreatePLString("DontFocusAcrossWorkspace");
113 AFullMaximize = WMCreatePLString("FullMaximize");
114 ASharedAppIcon = WMCreatePLString("SharedAppIcon");
115 #ifdef XKB_BUTTON_HINT
116 ANoLanguageButton = WMCreatePLString("NoLanguageButton");
117 #endif
119 AStartWorkspace = WMCreatePLString("StartWorkspace");
121 AnyWindow = WMCreatePLString("*");
122 No = WMCreatePLString("No");
124 if (!scr->wattribs) {
125 scr->wattribs = PLGetDomain(wAttributeDomainName);
126 } */
129 static WMPropList *get_value(WMPropList * dict_win, WMPropList * dict_class, WMPropList * dict_name,
130 WMPropList * dict_any, WMPropList * option, WMPropList * default_value,
131 Bool useGlobalDefault)
133 WMPropList *value;
135 if (dict_win) {
136 value = WMGetFromPLDictionary(dict_win, option);
137 if (value)
138 return value;
141 if (dict_name) {
142 value = WMGetFromPLDictionary(dict_name, option);
143 if (value)
144 return value;
147 if (dict_class) {
148 value = WMGetFromPLDictionary(dict_class, option);
149 if (value)
150 return value;
153 if (!useGlobalDefault)
154 return NULL;
156 if (dict_any) {
157 value = WMGetFromPLDictionary(dict_any, option);
158 if (value)
159 return value;
162 return default_value;
166 *----------------------------------------------------------------------
167 * wDefaultFillAttributes--
168 * Retrieves attributes for the specified instance/class and
169 * fills attr with it. Values that are actually defined are also
170 * set in mask. If useGlobalDefault is True, the default for
171 * all windows ("*") will be used for when no values are found
172 * for that instance/class.
174 *----------------------------------------------------------------------
176 void
177 wDefaultFillAttributes(WScreen * scr, char *instance, char *class,
178 WWindowAttributes * attr, WWindowAttributes * mask, Bool useGlobalDefault)
180 WMPropList *value, *key1, *key2, *key3, *dw, *dc, *dn, *da;
182 if (class && instance) {
183 char *buffer;
185 buffer = wmalloc(strlen(class) + strlen(instance) + 2);
186 sprintf(buffer, "%s.%s", instance, class);
187 key1 = WMCreatePLString(buffer);
188 wfree(buffer);
189 } else {
190 key1 = NULL;
193 if (instance)
194 key2 = WMCreatePLString(instance);
195 else
196 key2 = NULL;
198 if (class)
199 key3 = WMCreatePLString(class);
200 else
201 key3 = NULL;
203 if (!ANoTitlebar) {
204 init_wdefaults(scr);
207 WMPLSetCaseSensitive(True);
209 if (WDWindowAttributes->dictionary) {
210 dw = key1 ? WMGetFromPLDictionary(WDWindowAttributes->dictionary, key1) : NULL;
211 dn = key2 ? WMGetFromPLDictionary(WDWindowAttributes->dictionary, key2) : NULL;
212 dc = key3 ? WMGetFromPLDictionary(WDWindowAttributes->dictionary, key3) : NULL;
213 if (useGlobalDefault)
214 da = WMGetFromPLDictionary(WDWindowAttributes->dictionary, AnyWindow);
215 else
216 da = NULL;
217 } else {
218 dw = NULL;
219 dn = NULL;
220 dc = NULL;
221 da = NULL;
223 if (key1)
224 WMReleasePropList(key1);
225 if (key2)
226 WMReleasePropList(key2);
227 if (key3)
228 WMReleasePropList(key3);
230 #define APPLY_VAL(value, flag, attrib) \
231 if (value) {attr->flag = getBool(attrib, value); \
232 if (mask) mask->flag = 1;}
234 /* get the data */
235 value = get_value(dw, dc, dn, da, ANoTitlebar, No, useGlobalDefault);
236 APPLY_VAL(value, no_titlebar, ANoTitlebar);
238 value = get_value(dw, dc, dn, da, ANoResizebar, No, useGlobalDefault);
239 APPLY_VAL(value, no_resizebar, ANoResizebar);
241 value = get_value(dw, dc, dn, da, ANoMiniaturizeButton, No, useGlobalDefault);
242 APPLY_VAL(value, no_miniaturize_button, ANoMiniaturizeButton);
244 value = get_value(dw, dc, dn, da, ANoCloseButton, No, useGlobalDefault);
245 APPLY_VAL(value, no_close_button, ANoCloseButton);
247 value = get_value(dw, dc, dn, da, ANoBorder, No, useGlobalDefault);
248 APPLY_VAL(value, no_border, ANoBorder);
250 value = get_value(dw, dc, dn, da, ANoHideOthers, No, useGlobalDefault);
251 APPLY_VAL(value, no_hide_others, ANoHideOthers);
253 value = get_value(dw, dc, dn, da, ANoMouseBindings, No, useGlobalDefault);
254 APPLY_VAL(value, no_bind_mouse, ANoMouseBindings);
256 value = get_value(dw, dc, dn, da, ANoKeyBindings, No, useGlobalDefault);
257 APPLY_VAL(value, no_bind_keys, ANoKeyBindings);
259 value = get_value(dw, dc, dn, da, ANoAppIcon, No, useGlobalDefault);
260 APPLY_VAL(value, no_appicon, ANoAppIcon);
262 value = get_value(dw, dc, dn, da, ASharedAppIcon, No, useGlobalDefault);
263 APPLY_VAL(value, shared_appicon, ASharedAppIcon);
265 value = get_value(dw, dc, dn, da, AKeepOnTop, No, useGlobalDefault);
266 APPLY_VAL(value, floating, AKeepOnTop);
268 value = get_value(dw, dc, dn, da, AKeepOnBottom, No, useGlobalDefault);
269 APPLY_VAL(value, sunken, AKeepOnBottom);
271 value = get_value(dw, dc, dn, da, AOmnipresent, No, useGlobalDefault);
272 APPLY_VAL(value, omnipresent, AOmnipresent);
274 value = get_value(dw, dc, dn, da, ASkipWindowList, No, useGlobalDefault);
275 APPLY_VAL(value, skip_window_list, ASkipWindowList);
277 value = get_value(dw, dc, dn, da, AKeepInsideScreen, No, useGlobalDefault);
278 APPLY_VAL(value, dont_move_off, AKeepInsideScreen);
280 value = get_value(dw, dc, dn, da, AUnfocusable, No, useGlobalDefault);
281 APPLY_VAL(value, no_focusable, AUnfocusable);
283 value = get_value(dw, dc, dn, da, AAlwaysUserIcon, No, useGlobalDefault);
284 APPLY_VAL(value, always_user_icon, AAlwaysUserIcon);
286 value = get_value(dw, dc, dn, da, AStartMiniaturized, No, useGlobalDefault);
287 APPLY_VAL(value, start_miniaturized, AStartMiniaturized);
289 value = get_value(dw, dc, dn, da, AStartHidden, No, useGlobalDefault);
290 APPLY_VAL(value, start_hidden, AStartHidden);
292 value = get_value(dw, dc, dn, da, AStartMaximized, No, useGlobalDefault);
293 APPLY_VAL(value, start_maximized, AStartMaximized);
295 value = get_value(dw, dc, dn, da, ADontSaveSession, No, useGlobalDefault);
296 APPLY_VAL(value, dont_save_session, ADontSaveSession);
298 value = get_value(dw, dc, dn, da, AEmulateAppIcon, No, useGlobalDefault);
299 APPLY_VAL(value, emulate_appicon, AEmulateAppIcon);
301 value = get_value(dw, dc, dn, da, ADontFocusAcrossWorkspace, No, useGlobalDefault);
302 APPLY_VAL(value, dont_focus_across_wksp, ADontFocusAcrossWorkspace);
304 value = get_value(dw, dc, dn, da, AFullMaximize, No, useGlobalDefault);
305 APPLY_VAL(value, full_maximize, AFullMaximize);
307 #ifdef XKB_BUTTON_HINT
308 value = get_value(dw, dc, dn, da, ANoLanguageButton, No, useGlobalDefault);
309 APPLY_VAL(value, no_language_button, ANoLanguageButton);
310 #endif
312 /* clean up */
313 WMPLSetCaseSensitive(False);
316 static WMPropList *get_generic_value(WScreen *scr, char *instance, char *class,
317 WMPropList *option, Bool noDefault)
319 WMPropList *value, *key, *dict;
321 value = NULL;
323 WMPLSetCaseSensitive(True);
325 if (class && instance) {
326 char *buffer;
328 buffer = wmalloc(strlen(class) + strlen(instance) + 2);
329 sprintf(buffer, "%s.%s", instance, class);
330 key = WMCreatePLString(buffer);
331 wfree(buffer);
333 dict = WMGetFromPLDictionary(WDWindowAttributes->dictionary, key);
334 WMReleasePropList(key);
336 if (dict) {
337 value = WMGetFromPLDictionary(dict, option);
341 if (!value && instance) {
342 key = WMCreatePLString(instance);
344 dict = WMGetFromPLDictionary(WDWindowAttributes->dictionary, key);
345 WMReleasePropList(key);
346 if (dict) {
347 value = WMGetFromPLDictionary(dict, option);
351 if (!value && class) {
352 key = WMCreatePLString(class);
354 dict = WMGetFromPLDictionary(WDWindowAttributes->dictionary, key);
355 WMReleasePropList(key);
357 if (dict) {
358 value = WMGetFromPLDictionary(dict, option);
362 if (!value && !noDefault) {
363 dict = WMGetFromPLDictionary(WDWindowAttributes->dictionary, AnyWindow);
365 if (dict) {
366 value = WMGetFromPLDictionary(dict, option);
370 WMPLSetCaseSensitive(False);
372 return value;
375 char *wDefaultGetIconFile(WScreen * scr, char *instance, char *class, Bool noDefault)
377 WMPropList *value;
378 char *tmp;
380 if (!ANoTitlebar) {
381 init_wdefaults(scr);
384 if (!WDWindowAttributes->dictionary)
385 return NULL;
387 value = get_generic_value(scr, instance, class, AIcon, noDefault);
389 if (!value)
390 return NULL;
392 tmp = getString(AIcon, value);
394 return tmp;
397 RImage *wDefaultGetImage(WScreen * scr, char *winstance, char *wclass)
399 char *file_name;
400 char *path;
401 RImage *image;
403 file_name = wDefaultGetIconFile(scr, winstance, wclass, False);
404 if (!file_name)
405 return NULL;
407 path = FindImage(wPreferences.icon_path, file_name);
409 if (!path) {
410 wwarning(_("could not find icon file \"%s\""), file_name);
411 return NULL;
414 image = RLoadImage(scr->rcontext, path, 0);
415 if (!image) {
416 wwarning(_("error loading image file \"%s\": %s"), path, RMessageForError(RErrorCode));
418 wfree(path);
420 image = wIconValidateIconSize(scr, image);
422 return image;
425 int wDefaultGetStartWorkspace(WScreen * scr, char *instance, char *class)
427 WMPropList *value;
428 int w, i;
429 char *tmp;
431 if (!ANoTitlebar) {
432 init_wdefaults(scr);
435 if (!WDWindowAttributes->dictionary)
436 return -1;
438 value = get_generic_value(scr, instance, class, AStartWorkspace, False);
440 if (!value)
441 return -1;
443 tmp = getString(AStartWorkspace, value);
445 if (!tmp || strlen(tmp) == 0)
446 return -1;
448 if (sscanf(tmp, "%i", &w) != 1) {
449 w = -1;
450 for (i = 0; i < scr->workspace_count; i++) {
451 if (strcmp(scr->workspaces[i]->name, tmp) == 0) {
452 w = i;
453 break;
456 } else {
457 w--;
460 return w;
463 void wDefaultChangeIcon(WScreen * scr, char *instance, char *class, char *file)
465 WDDomain *db = WDWindowAttributes;
466 WMPropList *icon_value = NULL, *value, *attr, *key, *def_win, *def_icon = NULL;
467 WMPropList *dict = db->dictionary;
468 int same = 0;
470 if (!dict) {
471 dict = WMCreatePLDictionary(NULL, NULL);
472 if (dict) {
473 db->dictionary = dict;
474 } else {
475 return;
479 WMPLSetCaseSensitive(True);
481 if (instance && class) {
482 char *buffer;
483 buffer = wmalloc(strlen(instance) + strlen(class) + 2);
484 sprintf(buffer, "%s.%s", instance, class);
485 key = WMCreatePLString(buffer);
486 wfree(buffer);
487 } else if (instance) {
488 key = WMCreatePLString(instance);
489 } else if (class) {
490 key = WMCreatePLString(class);
491 } else {
492 key = WMRetainPropList(AnyWindow);
495 if (file) {
496 value = WMCreatePLString(file);
497 icon_value = WMCreatePLDictionary(AIcon, value, NULL);
498 WMReleasePropList(value);
500 if ((def_win = WMGetFromPLDictionary(dict, AnyWindow)) != NULL) {
501 def_icon = WMGetFromPLDictionary(def_win, AIcon);
504 if (def_icon && !strcmp(WMGetFromPLString(def_icon), file))
505 same = 1;
508 if ((attr = WMGetFromPLDictionary(dict, key)) != NULL) {
509 if (WMIsPLDictionary(attr)) {
510 if (icon_value != NULL && !same)
511 WMMergePLDictionaries(attr, icon_value, False);
512 else
513 WMRemoveFromPLDictionary(attr, AIcon);
515 } else if (icon_value != NULL && !same) {
516 WMPutInPLDictionary(dict, key, icon_value);
518 if (!wPreferences.flags.noupdates) {
519 UpdateDomainFile(db);
522 WMReleasePropList(key);
523 if (icon_value)
524 WMReleasePropList(icon_value);
526 WMPLSetCaseSensitive(False);
529 /* --------------------------- Local ----------------------- */
531 static int getBool(WMPropList * key, WMPropList * value)
533 char *val;
535 if (!WMIsPLString(value)) {
536 wwarning(_("Wrong option format for key \"%s\". Should be %s."),
537 WMGetFromPLString(key), "Boolean");
538 return 0;
540 val = WMGetFromPLString(value);
542 if ((val[1] == '\0' && (val[0] == 'y' || val[0] == 'Y' || val[0] == 'T' || val[0] == 't' || val[0] == '1'))
543 || (strcasecmp(val, "YES") == 0 || strcasecmp(val, "TRUE") == 0)) {
545 return 1;
546 } else if ((val[1] == '\0'
547 && (val[0] == 'n' || val[0] == 'N' || val[0] == 'F' || val[0] == 'f' || val[0] == '0'))
548 || (strcasecmp(val, "NO") == 0 || strcasecmp(val, "FALSE") == 0)) {
550 return 0;
551 } else {
552 wwarning(_("can't convert \"%s\" to boolean"), val);
553 /* We return False if we can't convert to BOOLEAN.
554 * This is because all options defaults to False.
555 * -1 is not checked and thus is interpreted as True,
556 * which is not good.*/
557 return 0;
561 /* WARNING: Do not free the value returned by this function!! */
562 static char *getString(WMPropList * key, WMPropList * value)
564 if (!WMIsPLString(value)) {
565 wwarning(_("Wrong option format for key \"%s\". Should be %s."), WMGetFromPLString(key), "String");
566 return NULL;
569 return WMGetFromPLString(value);