reverted to KeepInsideScreen
[wmaker-crm.git] / src / wdefaults.c
blob5f193b8b28b7eb0cf3b444d434db5a205b432fca
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 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;
88 #endif
90 static proplist_t AStartWorkspace;
92 static proplist_t AIcon;
95 static proplist_t AnyWindow;
96 static proplist_t No;
99 static void
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");
127 #endif
129 AStartWorkspace = PLMakeString("StartWorkspace");
131 AnyWindow = PLMakeString("*");
132 No = PLMakeString("No");
134 if (!scr->wattribs) {
135 scr->wattribs = PLGetDomain(wAttributeDomainName);
141 static proplist_t
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)
146 proplist_t value;
149 if (dict_win) {
150 value = PLGetDictionaryEntry(dict_win, option);
151 if (value)
152 return value;
155 if (dict_name) {
156 value = PLGetDictionaryEntry(dict_name, option);
157 if (value)
158 return value;
161 if (dict_class) {
162 value = PLGetDictionaryEntry(dict_class, option);
163 if (value)
164 return value;
167 if (!useGlobalDefault)
168 return NULL;
170 if (dict_any) {
171 value = PLGetDictionaryEntry(dict_any, option);
172 if (value)
173 return value;
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 *----------------------------------------------------------------------
191 void
192 wDefaultFillAttributes(WScreen *scr, char *instance, char *class,
193 WWindowAttributes *attr,
194 WWindowAttributes *mask,
195 Bool useGlobalDefault)
197 proplist_t value;
198 proplist_t key1, key2, key3;
199 proplist_t dw, dc, dn, da;
202 if (class && instance) {
203 char *buffer = NULL;
204 buffer = wmalloc(strlen(class)+strlen(instance)+4);
205 key1 = PLMakeString(strcat(strcat(strcpy(buffer,instance),"."),class));
206 free(buffer);
207 } else
208 key1 = NULL;
210 if (instance)
211 key2 = PLMakeString(instance);
212 else
213 key2 = NULL;
215 if (class)
216 key3 = PLMakeString(class);
217 else
218 key3 = NULL;
220 if (!ANoTitlebar) {
221 init_wdefaults(scr);
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);
232 else
233 da = NULL;
234 } else {
235 dw = NULL;
236 dn = NULL;
237 dc = NULL;
238 da = NULL;
240 if (key1)
241 PLRelease(key1);
242 if (key2)
243 PLRelease(key2);
244 if (key3)
245 PLRelease(key3);
247 #define APPLY_VAL(value, flag, attrib) \
248 if (value) {attr->flag = getBool(attrib, value); \
249 if (mask) mask->flag = 1;}
251 /* get the data */
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);
318 #endif
320 /* clean up */
321 PLSetStringCmpHook(StringCompareHook);
326 proplist_t
327 get_generic_value(WScreen *scr, char *instance, char *class, proplist_t option,
328 Bool noDefault)
330 proplist_t value, key, dict;
332 value = NULL;
334 PLSetStringCmpHook(NULL);
336 if (class && instance) {
337 char *buffer = NULL;
338 buffer = wmalloc(strlen(class)+strlen(instance)+4);
339 key = PLMakeString(strcat(strcat(strcpy(buffer,instance),"."),class));
341 dict = PLGetDictionaryEntry(WDWindowAttributes->dictionary, key);
342 PLRelease(key);
343 free(buffer);
345 if (dict) {
346 value = PLGetDictionaryEntry(dict, option);
350 if (!value && instance) {
351 key = PLMakeString(instance);
353 dict = PLGetDictionaryEntry(WDWindowAttributes->dictionary, key);
354 PLRelease(key);
355 if (dict) {
356 value = PLGetDictionaryEntry(dict, option);
360 if (!value && class) {
361 key = PLMakeString(class);
363 dict = PLGetDictionaryEntry(WDWindowAttributes->dictionary, key);
364 PLRelease(key);
366 if (dict) {
367 value = PLGetDictionaryEntry(dict, option);
371 if (!value && !noDefault) {
372 dict = PLGetDictionaryEntry(WDWindowAttributes->dictionary, AnyWindow);
374 if (dict) {
375 value = PLGetDictionaryEntry(dict, option);
379 PLSetStringCmpHook(StringCompareHook);
381 return value;
385 char*
386 wDefaultGetIconFile(WScreen *scr, char *instance, char *class,
387 Bool noDefault)
389 proplist_t value;
390 char *tmp;
392 if (!ANoTitlebar) {
393 init_wdefaults(scr);
396 if (!WDWindowAttributes->dictionary)
397 return NULL;
399 value = get_generic_value(scr, instance, class, AIcon, noDefault);
401 if (!value)
402 return NULL;
404 tmp = getString(AIcon, value);
406 return tmp;
410 RImage*
411 wDefaultGetImage(WScreen *scr, char *winstance, char *wclass)
413 char *file_name;
414 char *path;
415 RImage *image;
417 file_name = wDefaultGetIconFile(scr, winstance, wclass, False);
418 if (!file_name)
419 return NULL;
421 path = FindImage(wPreferences.icon_path, file_name);
423 if (!path) {
424 wwarning(_("could not find icon file \"%s\""), file_name);
425 return NULL;
428 image = RLoadImage(scr->rcontext, path, 0);
429 if (!image) {
430 wwarning(_("error loading image file \"%s\""), path, RMessageForError(RErrorCode));
432 free(path);
434 image = wIconValidateIconSize(scr, image);
436 return image;
441 wDefaultGetStartWorkspace(WScreen *scr, char *instance, char *class)
443 proplist_t value;
444 int w, i;
445 char *tmp;
447 if (!ANoTitlebar) {
448 init_wdefaults(scr);
451 if (!WDWindowAttributes->dictionary)
452 return -1;
454 value = get_generic_value(scr, instance, class, AStartWorkspace,
455 False);
457 if (!value)
458 return -1;
460 tmp = getString(AStartWorkspace, value);
462 if (!tmp || strlen(tmp)==0)
463 return -1;
465 if (sscanf(tmp, "%i", &w)!=1) {
466 w = -1;
467 for (i=0; i < scr->workspace_count; i++) {
468 if (strcmp(scr->workspaces[i]->name, tmp)==0) {
469 w = i;
470 break;
473 } else {
474 w--;
477 return w;
481 void
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;
487 int same = 0;
489 if (!dict) {
490 dict = PLMakeDictionaryFromEntries(NULL, NULL, NULL);
491 if (dict) {
492 db->dictionary = dict;
493 value = PLMakeString(db->path);
494 PLSetFilename(dict, value);
495 PLRelease(value);
497 else
498 return;
501 PLSetStringCmpHook(NULL);
503 if (instance && class) {
504 char *buffer;
505 buffer = wmalloc(strlen(instance) + strlen(class) + 2);
506 strcat(strcat(strcpy(buffer, instance), "."), class);
507 key = PLMakeString(buffer);
508 free(buffer);
509 } else if (instance) {
510 key = PLMakeString(instance);
511 } else if (class) {
512 key = PLMakeString(class);
513 } else {
514 key = PLRetain(AnyWindow);
517 if (file) {
518 value = PLMakeString(file);
519 icon_value = PLMakeDictionaryFromEntries(AIcon, value, NULL);
520 PLRelease(value);
522 if ((def_win = PLGetDictionaryEntry(dict, AnyWindow)) != NULL) {
523 def_icon = PLGetDictionaryEntry(def_win, AIcon);
526 if (def_icon && !strcmp(PLGetString(def_icon), file))
527 same = 1;
530 if ((attr = PLGetDictionaryEntry(dict, key)) != NULL) {
531 if (PLIsDictionary(attr)) {
532 if (icon_value!=NULL && !same)
533 PLMergeDictionaries(attr, icon_value);
534 else
535 PLRemoveDictionaryEntry(attr, AIcon);
537 } else if (icon_value!=NULL && !same) {
538 PLInsertDictionaryEntry(dict, key, icon_value);
540 if (!wPreferences.flags.noupdates)
541 PLSave(dict, YES);
543 PLRelease(key);
544 if(icon_value)
545 PLRelease(icon_value);
547 PLSetStringCmpHook(StringCompareHook);
552 /* --------------------------- Local ----------------------- */
554 static int
555 getBool(proplist_t key, proplist_t value)
557 char *val;
559 if (!PLIsString(value)) {
560 wwarning(_("Wrong option format for key \"%s\". Should be %s."),
561 PLGetString(key), "Boolean");
562 return 0;
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)) {
570 return 1;
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)) {
576 return 0;
577 } else {
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.*/
583 return 0;
590 * WARNING: Do not free value returned by this!!
592 static char*
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");
598 return NULL;
601 return PLGetString(value);