1 /* wdefaults.c - window specific defaults
3 * Window Maker window manager
5 * Copyright (c) 1997, 1998 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,
32 #include <X11/Xutil.h>
33 #include <X11/keysym.h>
38 #include "WindowMaker.h"
42 #include "workspace.h"
49 extern WPreferences wPreferences
;
51 extern proplist_t wAttributeDomainName
;
53 extern WDDomain
*WDWindowAttributes
;
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 ANoHideOthers
;
70 static proplist_t ANoMouseBindings
;
71 static proplist_t ANoKeyBindings
;
72 static proplist_t ANoAppIcon
; /* app */
73 static proplist_t AKeepOnTop
;
74 static proplist_t AKeepOnBottom
;
75 static proplist_t AOmnipresent
;
76 static proplist_t ASkipWindowList
;
77 static proplist_t AKeepInsideScreen
;
78 static proplist_t AUnfocusable
;
79 static proplist_t AAlwaysUserIcon
;
80 static proplist_t AStartMiniaturized
;
81 static proplist_t AStartMaximized
;
82 static proplist_t AStartHidden
; /* app */
83 static proplist_t ADontSaveSession
; /* app */
84 static proplist_t AEmulateAppIcon
;
85 static proplist_t AFullMaximize
;
86 #ifdef XKB_BUTTON_HINT
87 static proplist_t ANoLanguageButton
;
90 static proplist_t AStartWorkspace
;
92 static proplist_t AIcon
;
95 static proplist_t AnyWindow
;
100 init_wdefaults(WScreen
*scr
)
102 AIcon
= PLMakeString("Icon");
104 ANoTitlebar
= PLMakeString("NoTitlebar");
105 ANoResizebar
= PLMakeString("NoResizebar");
106 ANoMiniaturizeButton
= PLMakeString("NoMiniaturizeButton");
107 ANoCloseButton
= PLMakeString("NoCloseButton");
108 ANoHideOthers
= PLMakeString("NoHideOthers");
109 ANoMouseBindings
= PLMakeString("NoMouseBindings");
110 ANoKeyBindings
= PLMakeString("NoKeyBindings");
111 ANoAppIcon
= PLMakeString("NoAppIcon");
112 AKeepOnTop
= PLMakeString("KeepOnTop");
113 AKeepOnBottom
= PLMakeString("KeepOnBottom");
114 AOmnipresent
= PLMakeString("Omnipresent");
115 ASkipWindowList
= PLMakeString("SkipWindowList");
116 AKeepInsideScreen
= PLMakeString("KeepInsideScreen");
117 AUnfocusable
= PLMakeString("Unfocusable");
118 AAlwaysUserIcon
= PLMakeString("AlwaysUserIcon");
119 AStartMiniaturized
= PLMakeString("StartMiniaturized");
120 AStartHidden
= PLMakeString("StartHidden");
121 AStartMaximized
= PLMakeString("StartMaximized");
122 ADontSaveSession
= PLMakeString("DontSaveSession");
123 AEmulateAppIcon
= PLMakeString("EmulateAppIcon");
124 AFullMaximize
= PLMakeString("FullMaximize");
125 #ifdef XKB_BUTTON_HINT
126 ANoLanguageButton
= PLMakeString("NoLanguageButton");
129 AStartWorkspace
= PLMakeString("StartWorkspace");
131 AnyWindow
= PLMakeString("*");
132 No
= PLMakeString("No");
134 if (!scr->wattribs) {
135 scr->wattribs = PLGetDomain(wAttributeDomainName);
142 get_value(proplist_t dict_win
, proplist_t dict_class
, proplist_t dict_name
,
143 proplist_t dict_any
, proplist_t option
, proplist_t default_value
,
144 Bool useGlobalDefault
)
150 value
= PLGetDictionaryEntry(dict_win
, option
);
156 value
= PLGetDictionaryEntry(dict_name
, option
);
162 value
= PLGetDictionaryEntry(dict_class
, option
);
167 if (!useGlobalDefault
)
171 value
= PLGetDictionaryEntry(dict_any
, option
);
176 return default_value
;
181 *----------------------------------------------------------------------
182 * wDefaultFillAttributes--
183 * Retrieves attributes for the specified instance/class and
184 * fills attr with it. Values that are actually defined are also
185 * set in mask. If useGlobalDefault is True, the default for
186 * all windows ("*") will be used for when no values are found
187 * for that instance/class.
189 *----------------------------------------------------------------------
192 wDefaultFillAttributes(WScreen
*scr
, char *instance
, char *class,
193 WWindowAttributes
*attr
,
194 WWindowAttributes
*mask
,
195 Bool useGlobalDefault
)
198 proplist_t key1
, key2
, key3
;
199 proplist_t dw
, dc
, dn
, da
;
202 if (class && instance
) {
204 buffer
= wmalloc(strlen(class)+strlen(instance
)+4);
205 key1
= PLMakeString(strcat(strcat(strcpy(buffer
,instance
),"."),class));
211 key2
= PLMakeString(instance
);
216 key3
= PLMakeString(class);
224 PLSetStringCmpHook(NULL
);
226 if (WDWindowAttributes
->dictionary
) {
227 dw
= key1
? PLGetDictionaryEntry(WDWindowAttributes
->dictionary
, key1
) : NULL
;
228 dn
= key2
? PLGetDictionaryEntry(WDWindowAttributes
->dictionary
, key2
) : NULL
;
229 dc
= key3
? PLGetDictionaryEntry(WDWindowAttributes
->dictionary
, key3
) : NULL
;
230 if (useGlobalDefault
)
231 da
= PLGetDictionaryEntry(WDWindowAttributes
->dictionary
, AnyWindow
);
247 #define APPLY_VAL(value, flag, attrib) \
248 if (value) {attr->flag = getBool(attrib, value); \
249 if (mask) mask->flag = 1;}
252 value
= get_value(dw
, dc
, dn
, da
, ANoTitlebar
, No
, useGlobalDefault
);
253 APPLY_VAL(value
, no_titlebar
, ANoTitlebar
);
255 value
= get_value(dw
, dc
, dn
, da
, ANoResizebar
, No
, useGlobalDefault
);
256 APPLY_VAL(value
, no_resizebar
, ANoResizebar
);
258 value
= get_value(dw
, dc
, dn
, da
, ANoMiniaturizeButton
, No
, useGlobalDefault
);
259 APPLY_VAL(value
, no_miniaturize_button
, ANoMiniaturizeButton
);
261 value
= get_value(dw
, dc
, dn
, da
, ANoCloseButton
, No
, useGlobalDefault
);
262 APPLY_VAL(value
, no_close_button
, ANoCloseButton
);
264 value
= get_value(dw
, dc
, dn
, da
, ANoHideOthers
, No
, useGlobalDefault
);
265 APPLY_VAL(value
, no_hide_others
, ANoHideOthers
);
267 value
= get_value(dw
, dc
, dn
, da
, ANoMouseBindings
, No
, useGlobalDefault
);
268 APPLY_VAL(value
, no_bind_mouse
, ANoMouseBindings
);
270 value
= get_value(dw
, dc
, dn
, da
, ANoKeyBindings
, No
, useGlobalDefault
);
271 APPLY_VAL(value
, no_bind_keys
, ANoKeyBindings
);
273 value
= get_value(dw
, dc
, dn
, da
, ANoAppIcon
, No
, useGlobalDefault
);
274 APPLY_VAL(value
, no_appicon
, ANoAppIcon
);
276 value
= get_value(dw
, dc
, dn
, da
, AKeepOnTop
, No
, useGlobalDefault
);
277 APPLY_VAL(value
, floating
, AKeepOnTop
);
279 value
= get_value(dw
, dc
, dn
, da
, AKeepOnBottom
, No
, useGlobalDefault
);
280 APPLY_VAL(value
, sunken
, AKeepOnBottom
);
282 value
= get_value(dw
, dc
, dn
, da
, AOmnipresent
, No
, useGlobalDefault
);
283 APPLY_VAL(value
, omnipresent
, AOmnipresent
);
285 value
= get_value(dw
, dc
, dn
, da
, ASkipWindowList
, No
, useGlobalDefault
);
286 APPLY_VAL(value
, skip_window_list
, ASkipWindowList
);
288 value
= get_value(dw
, dc
, dn
, da
, AKeepInsideScreen
, No
, useGlobalDefault
);
289 APPLY_VAL(value
, dont_move_off
, AKeepInsideScreen
);
291 value
= get_value(dw
, dc
, dn
, da
, AUnfocusable
, No
, useGlobalDefault
);
292 APPLY_VAL(value
, no_focusable
, AUnfocusable
);
294 value
= get_value(dw
, dc
, dn
, da
, AAlwaysUserIcon
, No
, useGlobalDefault
);
295 APPLY_VAL(value
, always_user_icon
, AAlwaysUserIcon
);
297 value
= get_value(dw
, dc
, dn
, da
, AStartMiniaturized
, No
, useGlobalDefault
);
298 APPLY_VAL(value
, start_miniaturized
, AStartMiniaturized
);
300 value
= get_value(dw
, dc
, dn
, da
, AStartHidden
, No
, useGlobalDefault
);
301 APPLY_VAL(value
, start_hidden
, AStartHidden
);
303 value
= get_value(dw
, dc
, dn
, da
, AStartMaximized
, No
, useGlobalDefault
);
304 APPLY_VAL(value
, start_maximized
, AStartMaximized
);
306 value
= get_value(dw
, dc
, dn
, da
, ADontSaveSession
, No
, useGlobalDefault
);
307 APPLY_VAL(value
, dont_save_session
, ADontSaveSession
);
309 value
= get_value(dw
, dc
, dn
, da
, AEmulateAppIcon
, No
, useGlobalDefault
);
310 APPLY_VAL(value
, emulate_appicon
, AEmulateAppIcon
);
312 value
= get_value(dw
, dc
, dn
, da
, AFullMaximize
, No
, useGlobalDefault
);
313 APPLY_VAL(value
, full_maximize
, AFullMaximize
);
315 #ifdef XKB_BUTTON_HINT
316 value
= get_value(dw
, dc
, dn
, da
, ANoLanguageButton
, No
, useGlobalDefault
);
317 APPLY_VAL(value
, no_language_button
, ANoLanguageButton
);
321 PLSetStringCmpHook(StringCompareHook
);
327 get_generic_value(WScreen
*scr
, char *instance
, char *class, proplist_t option
,
330 proplist_t value
, key
, dict
;
334 PLSetStringCmpHook(NULL
);
336 if (class && instance
) {
338 buffer
= wmalloc(strlen(class)+strlen(instance
)+4);
339 key
= PLMakeString(strcat(strcat(strcpy(buffer
,instance
),"."),class));
341 dict
= PLGetDictionaryEntry(WDWindowAttributes
->dictionary
, key
);
346 value
= PLGetDictionaryEntry(dict
, option
);
350 if (!value
&& instance
) {
351 key
= PLMakeString(instance
);
353 dict
= PLGetDictionaryEntry(WDWindowAttributes
->dictionary
, key
);
356 value
= PLGetDictionaryEntry(dict
, option
);
360 if (!value
&& class) {
361 key
= PLMakeString(class);
363 dict
= PLGetDictionaryEntry(WDWindowAttributes
->dictionary
, key
);
367 value
= PLGetDictionaryEntry(dict
, option
);
371 if (!value
&& !noDefault
) {
372 dict
= PLGetDictionaryEntry(WDWindowAttributes
->dictionary
, AnyWindow
);
375 value
= PLGetDictionaryEntry(dict
, option
);
379 PLSetStringCmpHook(StringCompareHook
);
386 wDefaultGetIconFile(WScreen
*scr
, char *instance
, char *class,
396 if (!WDWindowAttributes
->dictionary
)
399 value
= get_generic_value(scr
, instance
, class, AIcon
, noDefault
);
404 tmp
= getString(AIcon
, value
);
411 wDefaultGetImage(WScreen
*scr
, char *winstance
, char *wclass
)
417 file_name
= wDefaultGetIconFile(scr
, winstance
, wclass
, False
);
421 path
= FindImage(wPreferences
.icon_path
, file_name
);
424 wwarning(_("could not find icon file \"%s\""), file_name
);
428 image
= RLoadImage(scr
->rcontext
, path
, 0);
430 wwarning(_("error loading image file \"%s\""), path
, RMessageForError(RErrorCode
));
434 image
= wIconValidateIconSize(scr
, image
);
441 wDefaultGetStartWorkspace(WScreen
*scr
, char *instance
, char *class)
451 if (!WDWindowAttributes
->dictionary
)
454 value
= get_generic_value(scr
, instance
, class, AStartWorkspace
,
460 tmp
= getString(AStartWorkspace
, value
);
462 if (!tmp
|| strlen(tmp
)==0)
465 if (sscanf(tmp
, "%i", &w
)!=1) {
467 for (i
=0; i
< scr
->workspace_count
; i
++) {
468 if (strcmp(scr
->workspaces
[i
]->name
, tmp
)==0) {
482 wDefaultChangeIcon(WScreen
*scr
, char *instance
, char* class, char *file
)
484 WDDomain
*db
= WDWindowAttributes
;
485 proplist_t icon_value
=NULL
, value
, attr
, key
, def_win
, def_icon
=NULL
;
486 proplist_t dict
= db
->dictionary
;
490 dict
= PLMakeDictionaryFromEntries(NULL
, NULL
, NULL
);
492 db
->dictionary
= dict
;
493 value
= PLMakeString(db
->path
);
494 PLSetFilename(dict
, value
);
501 PLSetStringCmpHook(NULL
);
503 if (instance
&& class) {
505 buffer
= wmalloc(strlen(instance
) + strlen(class) + 2);
506 strcat(strcat(strcpy(buffer
, instance
), "."), class);
507 key
= PLMakeString(buffer
);
509 } else if (instance
) {
510 key
= PLMakeString(instance
);
512 key
= PLMakeString(class);
514 key
= PLRetain(AnyWindow
);
518 value
= PLMakeString(file
);
519 icon_value
= PLMakeDictionaryFromEntries(AIcon
, value
, NULL
);
522 if ((def_win
= PLGetDictionaryEntry(dict
, AnyWindow
)) != NULL
) {
523 def_icon
= PLGetDictionaryEntry(def_win
, AIcon
);
526 if (def_icon
&& !strcmp(PLGetString(def_icon
), file
))
530 if ((attr
= PLGetDictionaryEntry(dict
, key
)) != NULL
) {
531 if (PLIsDictionary(attr
)) {
532 if (icon_value
!=NULL
&& !same
)
533 PLMergeDictionaries(attr
, icon_value
);
535 PLRemoveDictionaryEntry(attr
, AIcon
);
537 } else if (icon_value
!=NULL
&& !same
) {
538 PLInsertDictionaryEntry(dict
, key
, icon_value
);
540 if (!wPreferences
.flags
.noupdates
)
545 PLRelease(icon_value
);
547 PLSetStringCmpHook(StringCompareHook
);
552 /* --------------------------- Local ----------------------- */
555 getBool(proplist_t key
, proplist_t value
)
559 if (!PLIsString(value
)) {
560 wwarning(_("Wrong option format for key \"%s\". Should be %s."),
561 PLGetString(key
), "Boolean");
564 val
= PLGetString(value
);
566 if ((val
[1]=='\0' && (val
[0]=='y' || val
[0]=='Y' || val
[0]=='T'
567 || val
[0]=='t' || val
[0]=='1'))
568 || (strcasecmp(val
, "YES")==0 || strcasecmp(val
, "TRUE")==0)) {
571 } else if ((val
[1]=='\0'
572 && (val
[0]=='n' || val
[0]=='N' || val
[0]=='F'
573 || val
[0]=='f' || val
[0]=='0'))
574 || (strcasecmp(val
, "NO")==0 || strcasecmp(val
, "FALSE")==0)) {
578 wwarning(_("can't convert \"%s\" to boolean"), val
);
579 /* We return False if we can't convert to BOOLEAN.
580 * This is because all options defaults to False.
581 * -1 is not checked and thus is interpreted as True,
582 * which is not good.*/
590 * WARNING: Do not free value returned by this!!
593 getString(proplist_t key
, proplist_t value
)
595 if (!PLIsString(value
)) {
596 wwarning(_("Wrong option format for key \"%s\". Should be %s."),
597 PLGetString(key
), "String");
601 return PLGetString(value
);