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.
32 #include <X11/Xutil.h>
33 #include <X11/keysym.h>
37 #include "WindowMaker.h"
41 #include "workspace.h"
46 extern WPreferences wPreferences
;
47 extern WDDomain
*WDWindowAttributes
;
52 static int getBool(WMPropList
*, WMPropList
*);
53 static char *getString(WMPropList
*, WMPropList
*);
54 static WMPropList
*ANoTitlebar
= NULL
;
55 static WMPropList
*ANoResizebar
;
56 static WMPropList
*ANoMiniaturizeButton
;
57 static WMPropList
*ANoMiniaturizable
;
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
*ASkipSwitchPanel
;
69 static WMPropList
*AKeepInsideScreen
;
70 static WMPropList
*AUnfocusable
;
71 static WMPropList
*AAlwaysUserIcon
;
72 static WMPropList
*AStartMiniaturized
;
73 static WMPropList
*AStartMaximized
;
74 static WMPropList
*AStartHidden
; /* app */
75 static WMPropList
*ADontSaveSession
; /* app */
76 static WMPropList
*AEmulateAppIcon
;
77 static WMPropList
*AFocusAcrossWorkspace
;
78 static WMPropList
*AFullMaximize
;
79 static WMPropList
*ASharedAppIcon
; /* app */
80 #ifdef XKB_BUTTON_HINT
81 static WMPropList
*ANoLanguageButton
;
83 static WMPropList
*AStartWorkspace
;
84 static WMPropList
*AIcon
;
85 static WMPropList
*AnyWindow
;
86 static WMPropList
*No
;
88 static void init_wdefaults(WScreen
* scr
)
90 AIcon
= WMCreatePLString("Icon");
92 ANoTitlebar
= WMCreatePLString("NoTitlebar");
93 ANoResizebar
= WMCreatePLString("NoResizebar");
94 ANoMiniaturizeButton
= WMCreatePLString("NoMiniaturizeButton");
95 ANoMiniaturizable
= WMCreatePLString("NoMiniaturizable");
96 ANoCloseButton
= WMCreatePLString("NoCloseButton");
97 ANoBorder
= WMCreatePLString("NoBorder");
98 ANoHideOthers
= WMCreatePLString("NoHideOthers");
99 ANoMouseBindings
= WMCreatePLString("NoMouseBindings");
100 ANoKeyBindings
= WMCreatePLString("NoKeyBindings");
101 ANoAppIcon
= WMCreatePLString("NoAppIcon");
102 AKeepOnTop
= WMCreatePLString("KeepOnTop");
103 AKeepOnBottom
= WMCreatePLString("KeepOnBottom");
104 AOmnipresent
= WMCreatePLString("Omnipresent");
105 ASkipWindowList
= WMCreatePLString("SkipWindowList");
106 ASkipSwitchPanel
= WMCreatePLString("SkipSwitchPanel");
107 AKeepInsideScreen
= WMCreatePLString("KeepInsideScreen");
108 AUnfocusable
= WMCreatePLString("Unfocusable");
109 AAlwaysUserIcon
= WMCreatePLString("AlwaysUserIcon");
110 AStartMiniaturized
= WMCreatePLString("StartMiniaturized");
111 AStartHidden
= WMCreatePLString("StartHidden");
112 AStartMaximized
= WMCreatePLString("StartMaximized");
113 ADontSaveSession
= WMCreatePLString("DontSaveSession");
114 AEmulateAppIcon
= WMCreatePLString("EmulateAppIcon");
115 AFocusAcrossWorkspace
= WMCreatePLString("FocusAcrossWorkspace");
116 AFullMaximize
= WMCreatePLString("FullMaximize");
117 ASharedAppIcon
= WMCreatePLString("SharedAppIcon");
118 #ifdef XKB_BUTTON_HINT
119 ANoLanguageButton
= WMCreatePLString("NoLanguageButton");
122 AStartWorkspace
= WMCreatePLString("StartWorkspace");
124 AnyWindow
= WMCreatePLString("*");
125 No
= WMCreatePLString("No");
128 static WMPropList
*get_value(WMPropList
* dict_win
, WMPropList
* dict_class
, WMPropList
* dict_name
,
129 WMPropList
* dict_any
, WMPropList
* option
, WMPropList
* default_value
,
130 Bool useGlobalDefault
)
135 value
= WMGetFromPLDictionary(dict_win
, option
);
141 value
= WMGetFromPLDictionary(dict_name
, option
);
147 value
= WMGetFromPLDictionary(dict_class
, option
);
152 if (!useGlobalDefault
)
156 value
= WMGetFromPLDictionary(dict_any
, option
);
161 return default_value
;
165 *----------------------------------------------------------------------
166 * wDefaultFillAttributes--
167 * Retrieves attributes for the specified instance/class and
168 * fills attr with it. Values that are actually defined are also
169 * set in mask. If useGlobalDefault is True, the default for
170 * all windows ("*") will be used for when no values are found
171 * for that instance/class.
173 *----------------------------------------------------------------------
176 wDefaultFillAttributes(WScreen
* scr
, char *instance
, char *class,
177 WWindowAttributes
* attr
, WWindowAttributes
* mask
, Bool useGlobalDefault
)
179 WMPropList
*value
, *key1
, *key2
, *key3
, *dw
, *dc
, *dn
, *da
;
181 if (class && instance
) {
184 buffer
= wmalloc(strlen(class) + strlen(instance
) + 2);
185 sprintf(buffer
, "%s.%s", instance
, class);
186 key1
= WMCreatePLString(buffer
);
193 key2
= WMCreatePLString(instance
);
198 key3
= WMCreatePLString(class);
206 WMPLSetCaseSensitive(True
);
208 if (WDWindowAttributes
->dictionary
) {
209 dw
= key1
? WMGetFromPLDictionary(WDWindowAttributes
->dictionary
, key1
) : NULL
;
210 dn
= key2
? WMGetFromPLDictionary(WDWindowAttributes
->dictionary
, key2
) : NULL
;
211 dc
= key3
? WMGetFromPLDictionary(WDWindowAttributes
->dictionary
, key3
) : NULL
;
212 if (useGlobalDefault
)
213 da
= WMGetFromPLDictionary(WDWindowAttributes
->dictionary
, AnyWindow
);
223 WMReleasePropList(key1
);
225 WMReleasePropList(key2
);
227 WMReleasePropList(key3
);
229 #define APPLY_VAL(value, flag, attrib) \
230 if (value) {attr->flag = getBool(attrib, value); \
231 if (mask) mask->flag = 1;}
234 value
= get_value(dw
, dc
, dn
, da
, ANoTitlebar
, No
, useGlobalDefault
);
235 APPLY_VAL(value
, no_titlebar
, ANoTitlebar
);
237 value
= get_value(dw
, dc
, dn
, da
, ANoResizebar
, No
, useGlobalDefault
);
238 APPLY_VAL(value
, no_resizebar
, ANoResizebar
);
240 value
= get_value(dw
, dc
, dn
, da
, ANoMiniaturizeButton
, No
, useGlobalDefault
);
241 APPLY_VAL(value
, no_miniaturize_button
, ANoMiniaturizeButton
);
243 value
= get_value(dw
, dc
, dn
, da
, ANoMiniaturizable
, No
, useGlobalDefault
);
244 APPLY_VAL(value
, no_miniaturizable
, ANoMiniaturizable
);
246 value
= get_value(dw
, dc
, dn
, da
, ANoCloseButton
, No
, useGlobalDefault
);
247 APPLY_VAL(value
, no_close_button
, ANoCloseButton
);
249 value
= get_value(dw
, dc
, dn
, da
, ANoBorder
, No
, useGlobalDefault
);
250 APPLY_VAL(value
, no_border
, ANoBorder
);
252 value
= get_value(dw
, dc
, dn
, da
, ANoHideOthers
, No
, useGlobalDefault
);
253 APPLY_VAL(value
, no_hide_others
, ANoHideOthers
);
255 value
= get_value(dw
, dc
, dn
, da
, ANoMouseBindings
, No
, useGlobalDefault
);
256 APPLY_VAL(value
, no_bind_mouse
, ANoMouseBindings
);
258 value
= get_value(dw
, dc
, dn
, da
, ANoKeyBindings
, No
, useGlobalDefault
);
259 APPLY_VAL(value
, no_bind_keys
, ANoKeyBindings
);
261 value
= get_value(dw
, dc
, dn
, da
, ANoAppIcon
, No
, useGlobalDefault
);
262 APPLY_VAL(value
, no_appicon
, ANoAppIcon
);
264 value
= get_value(dw
, dc
, dn
, da
, ASharedAppIcon
, No
, useGlobalDefault
);
265 APPLY_VAL(value
, shared_appicon
, ASharedAppIcon
);
267 value
= get_value(dw
, dc
, dn
, da
, AKeepOnTop
, No
, useGlobalDefault
);
268 APPLY_VAL(value
, floating
, AKeepOnTop
);
270 value
= get_value(dw
, dc
, dn
, da
, AKeepOnBottom
, No
, useGlobalDefault
);
271 APPLY_VAL(value
, sunken
, AKeepOnBottom
);
273 value
= get_value(dw
, dc
, dn
, da
, AOmnipresent
, No
, useGlobalDefault
);
274 APPLY_VAL(value
, omnipresent
, AOmnipresent
);
276 value
= get_value(dw
, dc
, dn
, da
, ASkipWindowList
, No
, useGlobalDefault
);
277 APPLY_VAL(value
, skip_window_list
, ASkipWindowList
);
279 value
= get_value(dw
, dc
, dn
, da
, ASkipSwitchPanel
, No
, useGlobalDefault
);
280 APPLY_VAL(value
, skip_switchpanel
, ASkipSwitchPanel
);
282 value
= get_value(dw
, dc
, dn
, da
, AKeepInsideScreen
, No
, useGlobalDefault
);
283 APPLY_VAL(value
, dont_move_off
, AKeepInsideScreen
);
285 value
= get_value(dw
, dc
, dn
, da
, AUnfocusable
, No
, useGlobalDefault
);
286 APPLY_VAL(value
, no_focusable
, AUnfocusable
);
288 value
= get_value(dw
, dc
, dn
, da
, AAlwaysUserIcon
, No
, useGlobalDefault
);
289 APPLY_VAL(value
, always_user_icon
, AAlwaysUserIcon
);
291 value
= get_value(dw
, dc
, dn
, da
, AStartMiniaturized
, No
, useGlobalDefault
);
292 APPLY_VAL(value
, start_miniaturized
, AStartMiniaturized
);
294 value
= get_value(dw
, dc
, dn
, da
, AStartHidden
, No
, useGlobalDefault
);
295 APPLY_VAL(value
, start_hidden
, AStartHidden
);
297 value
= get_value(dw
, dc
, dn
, da
, AStartMaximized
, No
, useGlobalDefault
);
298 APPLY_VAL(value
, start_maximized
, AStartMaximized
);
300 value
= get_value(dw
, dc
, dn
, da
, ADontSaveSession
, No
, useGlobalDefault
);
301 APPLY_VAL(value
, dont_save_session
, ADontSaveSession
);
303 value
= get_value(dw
, dc
, dn
, da
, AEmulateAppIcon
, No
, useGlobalDefault
);
304 APPLY_VAL(value
, emulate_appicon
, AEmulateAppIcon
);
306 value
= get_value(dw
, dc
, dn
, da
, AFocusAcrossWorkspace
, No
, useGlobalDefault
);
307 APPLY_VAL(value
, focus_across_wksp
, AFocusAcrossWorkspace
);
309 value
= get_value(dw
, dc
, dn
, da
, AFullMaximize
, No
, useGlobalDefault
);
310 APPLY_VAL(value
, full_maximize
, AFullMaximize
);
312 #ifdef XKB_BUTTON_HINT
313 value
= get_value(dw
, dc
, dn
, da
, ANoLanguageButton
, No
, useGlobalDefault
);
314 APPLY_VAL(value
, no_language_button
, ANoLanguageButton
);
318 WMPLSetCaseSensitive(False
);
321 static WMPropList
*get_generic_value(WScreen
*scr
, char *instance
, char *class,
322 WMPropList
*option
, Bool noDefault
)
324 WMPropList
*value
, *key
, *dict
;
328 WMPLSetCaseSensitive(True
);
330 if (class && instance
) {
333 buffer
= wmalloc(strlen(class) + strlen(instance
) + 2);
334 sprintf(buffer
, "%s.%s", instance
, class);
335 key
= WMCreatePLString(buffer
);
338 dict
= WMGetFromPLDictionary(WDWindowAttributes
->dictionary
, key
);
339 WMReleasePropList(key
);
342 value
= WMGetFromPLDictionary(dict
, option
);
346 if (!value
&& instance
) {
347 key
= WMCreatePLString(instance
);
349 dict
= WMGetFromPLDictionary(WDWindowAttributes
->dictionary
, key
);
350 WMReleasePropList(key
);
352 value
= WMGetFromPLDictionary(dict
, option
);
356 if (!value
&& class) {
357 key
= WMCreatePLString(class);
359 dict
= WMGetFromPLDictionary(WDWindowAttributes
->dictionary
, key
);
360 WMReleasePropList(key
);
363 value
= WMGetFromPLDictionary(dict
, option
);
367 if (!value
&& !noDefault
) {
368 dict
= WMGetFromPLDictionary(WDWindowAttributes
->dictionary
, AnyWindow
);
371 value
= WMGetFromPLDictionary(dict
, option
);
375 WMPLSetCaseSensitive(False
);
380 char *wDefaultGetIconFile(WScreen
* scr
, char *instance
, char *class, Bool noDefault
)
389 if (!WDWindowAttributes
->dictionary
)
392 value
= get_generic_value(scr
, instance
, class, AIcon
, noDefault
);
397 tmp
= getString(AIcon
, value
);
402 RImage
*wDefaultGetImage(WScreen
* scr
, char *winstance
, char *wclass
)
408 file_name
= wDefaultGetIconFile(scr
, winstance
, wclass
, False
);
412 path
= FindImage(wPreferences
.icon_path
, file_name
);
415 wwarning(_("could not find icon file \"%s\""), file_name
);
419 image
= RLoadImage(scr
->rcontext
, path
, 0);
421 wwarning(_("error loading image file \"%s\": %s"), path
, RMessageForError(RErrorCode
));
425 image
= wIconValidateIconSize(scr
, image
);
430 int wDefaultGetStartWorkspace(WScreen
* scr
, char *instance
, char *class)
440 if (!WDWindowAttributes
->dictionary
)
443 value
= get_generic_value(scr
, instance
, class, AStartWorkspace
, False
);
448 tmp
= getString(AStartWorkspace
, value
);
450 if (!tmp
|| strlen(tmp
) == 0)
453 if (sscanf(tmp
, "%i", &w
) != 1) {
455 for (i
= 0; i
< scr
->workspace_count
; i
++) {
456 if (strcmp(scr
->workspaces
[i
]->name
, tmp
) == 0) {
468 void wDefaultChangeIcon(WScreen
* scr
, char *instance
, char *class, char *file
)
470 WDDomain
*db
= WDWindowAttributes
;
471 WMPropList
*icon_value
= NULL
, *value
, *attr
, *key
, *def_win
, *def_icon
= NULL
;
472 WMPropList
*dict
= db
->dictionary
;
476 dict
= WMCreatePLDictionary(NULL
, NULL
);
478 db
->dictionary
= dict
;
484 WMPLSetCaseSensitive(True
);
486 if (instance
&& class) {
488 buffer
= wmalloc(strlen(instance
) + strlen(class) + 2);
489 sprintf(buffer
, "%s.%s", instance
, class);
490 key
= WMCreatePLString(buffer
);
492 } else if (instance
) {
493 key
= WMCreatePLString(instance
);
495 key
= WMCreatePLString(class);
497 key
= WMRetainPropList(AnyWindow
);
501 value
= WMCreatePLString(file
);
502 icon_value
= WMCreatePLDictionary(AIcon
, value
, NULL
);
503 WMReleasePropList(value
);
505 if ((def_win
= WMGetFromPLDictionary(dict
, AnyWindow
)) != NULL
) {
506 def_icon
= WMGetFromPLDictionary(def_win
, AIcon
);
509 if (def_icon
&& !strcmp(WMGetFromPLString(def_icon
), file
))
513 if ((attr
= WMGetFromPLDictionary(dict
, key
)) != NULL
) {
514 if (WMIsPLDictionary(attr
)) {
515 if (icon_value
!= NULL
&& !same
)
516 WMMergePLDictionaries(attr
, icon_value
, False
);
518 WMRemoveFromPLDictionary(attr
, AIcon
);
520 } else if (icon_value
!= NULL
&& !same
) {
521 WMPutInPLDictionary(dict
, key
, icon_value
);
523 if (!wPreferences
.flags
.noupdates
) {
524 UpdateDomainFile(db
);
527 WMReleasePropList(key
);
529 WMReleasePropList(icon_value
);
531 WMPLSetCaseSensitive(False
);
534 /* --------------------------- Local ----------------------- */
536 static int getBool(WMPropList
* key
, WMPropList
* value
)
540 if (!WMIsPLString(value
)) {
541 wwarning(_("Wrong option format for key \"%s\". Should be %s."),
542 WMGetFromPLString(key
), "Boolean");
545 val
= WMGetFromPLString(value
);
547 if ((val
[1] == '\0' && (val
[0] == 'y' || val
[0] == 'Y' || val
[0] == 'T' || val
[0] == 't' || val
[0] == '1'))
548 || (strcasecmp(val
, "YES") == 0 || strcasecmp(val
, "TRUE") == 0)) {
551 } else if ((val
[1] == '\0'
552 && (val
[0] == 'n' || val
[0] == 'N' || val
[0] == 'F' || val
[0] == 'f' || val
[0] == '0'))
553 || (strcasecmp(val
, "NO") == 0 || strcasecmp(val
, "FALSE") == 0)) {
557 wwarning(_("can't convert \"%s\" to boolean"), val
);
558 /* We return False if we can't convert to BOOLEAN.
559 * This is because all options defaults to False.
560 * -1 is not checked and thus is interpreted as True,
561 * which is not good.*/
566 /* WARNING: Do not free the value returned by this function!! */
567 static char *getString(WMPropList
* key
, WMPropList
* value
)
569 if (!WMIsPLString(value
)) {
570 wwarning(_("Wrong option format for key \"%s\". Should be %s."), WMGetFromPLString(key
), "String");
574 return WMGetFromPLString(value
);