noDefault changed to default_icon
[wmaker-crm.git] / src / winspector.c
blob65b21fa5dcac7ae3b6fc1f63d136a6a6df2bb8b1
1 /* winspector.c - window attribute inspector
3 * Window Maker window manager
5 * Copyright (c) 1997-2003 Alfredo K. Kojima
6 * Copyright (c) 1998-2003 Dan Pascu
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23 #include "wconfig.h"
25 #include <X11/Xlib.h>
26 #include <X11/Xutil.h>
27 #include <stdlib.h>
28 #include <stdio.h>
29 #include <string.h>
30 #include <strings.h>
32 #include "WindowMaker.h"
33 #include "screen.h"
34 #include "wcore.h"
35 #include "framewin.h"
36 #include "window.h"
37 #include "workspace.h"
38 #include "funcs.h"
39 #include "defaults.h"
40 #include "dialog.h"
41 #include "icon.h"
42 #include "stacking.h"
43 #include "application.h"
44 #include "appicon.h"
45 #include "actions.h"
46 #include "winspector.h"
47 #include "dock.h"
48 #include "client.h"
49 #include "wmspec.h"
51 #include <WINGs/WUtil.h>
53 typedef struct InspectorPanel {
54 struct InspectorPanel *nextPtr;
56 WWindow *frame;
58 WWindow *inspected; /* the window that's being inspected */
60 WMWindow *win;
62 Window parent;
64 /* common stuff */
65 WMButton *revertBtn;
66 WMButton *applyBtn;
67 WMButton *saveBtn;
69 WMPopUpButton *pagePopUp;
71 /* first page. general stuff */
73 WMFrame *specFrm;
74 WMButton *instRb;
75 WMButton *clsRb;
76 WMButton *bothRb;
77 WMButton *defaultRb;
79 WMButton *selWinB;
81 WMLabel *specLbl;
83 /* second page. attributes */
85 WMFrame *attrFrm;
86 WMButton *attrChk[11];
88 /* 3rd page. more attributes */
89 WMFrame *moreFrm;
90 #ifdef XKB_BUTTON_HINT
91 WMButton *moreChk[12];
92 #else
93 WMButton *moreChk[11];
94 #endif
96 /* 4th page. icon and workspace */
97 WMFrame *iconFrm;
98 WMLabel *iconLbl;
99 WMLabel *fileLbl;
100 WMTextField *fileText;
101 WMButton *alwChk;
103 WMButton *updateIconBtn;
105 WMButton *browseIconBtn;
107 WMFrame *wsFrm;
108 WMPopUpButton *wsP;
110 /* 5th page. application wide attributes */
111 WMFrame *appFrm;
112 WMButton *appChk[3];
114 unsigned int done:1;
115 unsigned int destroyed:1;
116 unsigned int choosingIcon:1;
117 } InspectorPanel;
119 extern Cursor wCursor[WCUR_LAST];
120 extern WDDomain *WDWindowAttributes;
121 extern WPreferences wPreferences;
123 static InspectorPanel *panelList = NULL;
124 static WMPropList *ANoTitlebar = NULL;
125 static WMPropList *ANoResizebar;
126 static WMPropList *ANoMiniaturizeButton;
127 static WMPropList *ANoCloseButton;
128 static WMPropList *ANoBorder;
129 static WMPropList *ANoHideOthers;
130 static WMPropList *ANoMouseBindings;
131 static WMPropList *ANoKeyBindings;
132 static WMPropList *ANoAppIcon;
133 static WMPropList *AKeepOnTop;
134 static WMPropList *AKeepOnBottom;
135 static WMPropList *AOmnipresent;
136 static WMPropList *ASkipWindowList;
137 static WMPropList *ASkipSwitchPanel;
138 static WMPropList *AKeepInsideScreen;
139 static WMPropList *AUnfocusable;
140 static WMPropList *AFocusAcrossWorkspace;
141 static WMPropList *AAlwaysUserIcon;
142 static WMPropList *AStartMiniaturized;
143 static WMPropList *AStartMaximized;
144 static WMPropList *ADontSaveSession;
145 static WMPropList *AEmulateAppIcon;
146 static WMPropList *AFullMaximize;
147 static WMPropList *ASharedAppIcon;
148 static WMPropList *ANoMiniaturizable;
149 #ifdef XKB_BUTTON_HINT
150 static WMPropList *ANoLanguageButton;
151 #endif
152 static WMPropList *AStartWorkspace;
153 static WMPropList *AIcon;
155 /* application wide options */
156 static WMPropList *AStartHidden;
157 static WMPropList *AnyWindow;
158 static WMPropList *EmptyString;
159 static WMPropList *Yes, *No;
161 #define PWIDTH 290
162 #define PHEIGHT 360
164 static char *spec_text;
165 static void applySettings(WMButton *button, InspectorPanel *panel);
167 #define UNDEFINED_POS 0xffffff
169 static InspectorPanel *createInspectorForWindow(WWindow *wwin, int xpos, int ypos, Bool showSelectPanel);
171 static void make_keys(void)
173 if (ANoTitlebar != NULL)
174 return;
176 AIcon = WMCreatePLString("Icon");
177 ANoTitlebar = WMCreatePLString("NoTitlebar");
178 ANoResizebar = WMCreatePLString("NoResizebar");
179 ANoMiniaturizeButton = WMCreatePLString("NoMiniaturizeButton");
180 ANoCloseButton = WMCreatePLString("NoCloseButton");
181 ANoBorder = WMCreatePLString("NoBorder");
182 ANoHideOthers = WMCreatePLString("NoHideOthers");
183 ANoMouseBindings = WMCreatePLString("NoMouseBindings");
184 ANoKeyBindings = WMCreatePLString("NoKeyBindings");
185 ANoAppIcon = WMCreatePLString("NoAppIcon");
186 AKeepOnTop = WMCreatePLString("KeepOnTop");
187 AKeepOnBottom = WMCreatePLString("KeepOnBottom");
188 AOmnipresent = WMCreatePLString("Omnipresent");
189 ASkipWindowList = WMCreatePLString("SkipWindowList");
190 ASkipSwitchPanel = WMCreatePLString("SkipSwitchPanel");
191 AKeepInsideScreen = WMCreatePLString("KeepInsideScreen");
192 AUnfocusable = WMCreatePLString("Unfocusable");
193 AFocusAcrossWorkspace = WMCreatePLString("FocusAcrossWorkspace");
194 AAlwaysUserIcon = WMCreatePLString("AlwaysUserIcon");
195 AStartMiniaturized = WMCreatePLString("StartMiniaturized");
196 AStartMaximized = WMCreatePLString("StartMaximized");
197 AStartHidden = WMCreatePLString("StartHidden");
198 ADontSaveSession = WMCreatePLString("DontSaveSession");
199 AEmulateAppIcon = WMCreatePLString("EmulateAppIcon");
200 AFullMaximize = WMCreatePLString("FullMaximize");
201 ASharedAppIcon = WMCreatePLString("SharedAppIcon");
202 ANoMiniaturizable = WMCreatePLString("NoMiniaturizable");
203 #ifdef XKB_BUTTON_HINT
204 ANoLanguageButton = WMCreatePLString("NoLanguageButton");
205 #endif
207 AStartWorkspace = WMCreatePLString("StartWorkspace");
209 AnyWindow = WMCreatePLString("*");
210 EmptyString = WMCreatePLString("");
211 Yes = WMCreatePLString("Yes");
212 No = WMCreatePLString("No");
215 static void freeInspector(InspectorPanel *panel)
217 panel->destroyed = 1;
219 if (panel->choosingIcon)
220 return;
222 WMDestroyWidget(panel->win);
223 XDestroyWindow(dpy, panel->parent);
224 wfree(panel);
227 static void destroyInspector(WCoreWindow *foo, void *data, XEvent *event)
229 InspectorPanel *panel;
230 InspectorPanel *tmp;
232 panel = panelList;
233 while (panel->frame != data)
234 panel = panel->nextPtr;
236 if (panelList == panel)
237 panelList = panel->nextPtr;
238 else {
239 tmp = panelList;
240 while (tmp->nextPtr != panel) {
241 tmp = tmp->nextPtr;
243 tmp->nextPtr = panel->nextPtr;
245 panel->inspected->flags.inspector_open = 0;
246 panel->inspected->inspector = NULL;
248 WMRemoveNotificationObserver(panel);
250 wWindowUnmap(panel->frame);
251 wUnmanageWindow(panel->frame, True, False);
253 freeInspector(panel);
256 void wDestroyInspectorPanels(void)
258 InspectorPanel *panel;
260 while (panelList != NULL) {
261 panel = panelList;
262 panelList = panelList->nextPtr;
263 wUnmanageWindow(panel->frame, False, False);
264 WMDestroyWidget(panel->win);
266 panel->inspected->flags.inspector_open = 0;
267 panel->inspected->inspector = NULL;
269 wfree(panel);
273 static void changePage(WMPopUpButton *bPtr, InspectorPanel *panel)
275 int page;
277 page = WMGetPopUpButtonSelectedItem(bPtr);
279 if (page == 0) {
280 WMMapWidget(panel->specFrm);
281 WMMapWidget(panel->specLbl);
282 } else if (page == 1) {
283 WMMapWidget(panel->attrFrm);
284 } else if (page == 2) {
285 WMMapWidget(panel->moreFrm);
286 } else if (page == 3) {
287 WMMapWidget(panel->iconFrm);
288 WMMapWidget(panel->wsFrm);
289 } else {
290 WMMapWidget(panel->appFrm);
293 if (page != 0) {
294 WMUnmapWidget(panel->specFrm);
295 WMUnmapWidget(panel->specLbl);
297 if (page != 1)
298 WMUnmapWidget(panel->attrFrm);
299 if (page != 2)
300 WMUnmapWidget(panel->moreFrm);
301 if (page != 3) {
302 WMUnmapWidget(panel->iconFrm);
303 WMUnmapWidget(panel->wsFrm);
305 if (page != 4 && panel->appFrm)
306 WMUnmapWidget(panel->appFrm);
309 #define USE_TEXT_FIELD 1
310 #define UPDATE_TEXT_FIELD 2
311 #define REVERT_TO_DEFAULT 4
313 static int showIconFor(WMScreen *scrPtr, InspectorPanel *panel, char *wm_instance, char *wm_class, int flags)
315 WMPixmap *pixmap = (WMPixmap *) NULL;
316 char *file = NULL, *path = NULL;
317 char *db_icon = NULL;
319 if ((flags & USE_TEXT_FIELD) != 0) {
320 file = WMGetTextFieldText(panel->fileText);
321 if (file && file[0] == 0) {
322 wfree(file);
323 file = NULL;
325 } else {
326 /* Get the application icon, default included */
327 db_icon = wDefaultGetIconFile(wm_instance, wm_class, True);
328 if (db_icon != NULL)
329 file = wstrdup(db_icon);
331 if (db_icon != NULL && (flags & REVERT_TO_DEFAULT) != 0) {
332 if (file)
333 file = wstrdup(db_icon);
334 flags |= UPDATE_TEXT_FIELD;
337 if ((flags & UPDATE_TEXT_FIELD) != 0) {
338 WMSetTextFieldText(panel->fileText, file);
341 if (file) {
342 path = FindImage(wPreferences.icon_path, file);
344 if (!path) {
345 char *buf;
346 int len = strlen(file) + 80;
348 buf = wmalloc(len);
349 snprintf(buf, len, _("Could not find icon \"%s\" specified for this window"), file);
350 wMessageDialog(panel->frame->screen_ptr, _("Error"), buf, _("OK"), NULL, NULL);
351 wfree(buf);
352 wfree(file);
353 return -1;
356 pixmap = WMCreatePixmapFromFile(scrPtr, path);
357 wfree(path);
359 if (!pixmap) {
360 char *buf;
361 int len = strlen(file) + 80;
363 buf = wmalloc(len);
364 snprintf(buf, len, _("Could not open specified icon \"%s\":%s"),
365 file, RMessageForError(RErrorCode));
366 wMessageDialog(panel->frame->screen_ptr, _("Error"), buf, _("OK"), NULL, NULL);
367 wfree(buf);
368 wfree(file);
369 return -1;
371 wfree(file);
374 WMSetLabelImage(panel->iconLbl, pixmap);
375 if (pixmap)
376 WMReleasePixmap(pixmap);
378 return 0;
381 #if 0
382 static void updateIcon(WMButton * button, InspectorPanel * panel)
384 showIconFor(WMWidgetScreen(button), panel, NULL, NULL, USE_TEXT_FIELD);
386 #endif
388 static int getBool(WMPropList *value)
390 char *val;
392 if (!WMIsPLString(value)) {
393 return 0;
395 if (!(val = WMGetFromPLString(value))) {
396 return 0;
399 if ((val[1] == '\0' && (val[0] == 'y' || val[0] == 'Y' || val[0] == 'T' || val[0] == 't' || val[0] == '1'))
400 || (strcasecmp(val, "YES") == 0 || strcasecmp(val, "TRUE") == 0)) {
402 return 1;
403 } else if ((val[1] == '\0'
404 && (val[0] == 'n' || val[0] == 'N' || val[0] == 'F' || val[0] == 'f' || val[0] == '0'))
405 || (strcasecmp(val, "NO") == 0 || strcasecmp(val, "FALSE") == 0)) {
407 return 0;
408 } else {
409 wwarning(_("can't convert \"%s\" to boolean"), val);
410 return 0;
414 #define UPDATE_DEFAULTS 1
415 #define IS_BOOLEAN 2
418 * Will insert the attribute = value; pair in window's list,
419 * if it's different from the defaults.
420 * Defaults means either defaults database, or attributes saved
421 * for the default window "*". This is to let one revert options that are
422 * global because they were saved for all windows ("*").
426 static int
427 insertAttribute(WMPropList *dict, WMPropList *window, WMPropList *attr, WMPropList *value, int flags)
429 WMPropList *def_win, *def_value = NULL;
430 int update = 0;
431 int modified = 0;
433 if (!(flags & UPDATE_DEFAULTS) && dict) {
434 if ((def_win = WMGetFromPLDictionary(dict, AnyWindow)) != NULL) {
435 def_value = WMGetFromPLDictionary(def_win, attr);
439 /* If we could not find defaults in database, fall to hardcoded values.
440 * Also this is true if we save defaults for all windows
442 if (!def_value)
443 def_value = ((flags & IS_BOOLEAN) != 0) ? No : EmptyString;
445 if ((flags & IS_BOOLEAN))
446 update = (getBool(value) != getBool(def_value));
447 else {
448 update = !WMIsPropListEqualTo(value, def_value);
451 if (update) {
452 WMPutInPLDictionary(window, attr, value);
453 modified = 1;
456 return modified;
459 static void saveSettings(WMButton *button, InspectorPanel *panel)
461 WWindow *wwin = panel->inspected;
462 WDDomain *db = WDWindowAttributes;
463 WMPropList *dict = db->dictionary;
464 WMPropList *winDic, *appDic, *value, *key, *key2;
465 char *icon_file;
466 int flags = 0;
467 int different = 0, different2 = 0;
469 /* Save will apply the changes and save them */
470 applySettings(panel->applyBtn, panel);
472 if (WMGetButtonSelected(panel->instRb) != 0)
473 key = WMCreatePLString(wwin->wm_instance);
474 else if (WMGetButtonSelected(panel->clsRb) != 0)
475 key = WMCreatePLString(wwin->wm_class);
476 else if (WMGetButtonSelected(panel->bothRb) != 0) {
477 char *buffer;
479 buffer = StrConcatDot(wwin->wm_instance, wwin->wm_class);
480 key = WMCreatePLString(buffer);
481 wfree(buffer);
482 } else if (WMGetButtonSelected(panel->defaultRb) != 0) {
483 key = WMRetainPropList(AnyWindow);
484 flags = UPDATE_DEFAULTS;
485 } else
486 key = NULL;
488 if (!key)
489 return;
491 if (!dict) {
492 dict = WMCreatePLDictionary(NULL, NULL);
493 if (dict) {
494 db->dictionary = dict;
495 } else {
496 WMReleasePropList(key);
497 return;
501 if (showIconFor(WMWidgetScreen(button), panel, NULL, NULL, USE_TEXT_FIELD) < 0)
502 return;
504 WMPLSetCaseSensitive(True);
506 winDic = WMCreatePLDictionary(NULL, NULL);
507 appDic = WMCreatePLDictionary(NULL, NULL);
509 /* Update icon for window */
510 icon_file = WMGetTextFieldText(panel->fileText);
511 if (icon_file) {
512 if (icon_file[0] != 0) {
513 value = WMCreatePLString(icon_file);
514 different |= insertAttribute(dict, winDic, AIcon, value, flags);
515 different2 |= insertAttribute(dict, appDic, AIcon, value, flags);
516 WMReleasePropList(value);
518 wfree(icon_file);
522 int i = WMGetPopUpButtonSelectedItem(panel->wsP);
524 i--;
526 if (i >= 0 && i < panel->frame->screen_ptr->workspace_count) {
527 value = WMCreatePLString(panel->frame->screen_ptr->workspaces[i]->name);
528 different |= insertAttribute(dict, winDic, AStartWorkspace, value, flags);
529 WMReleasePropList(value);
533 flags |= IS_BOOLEAN;
535 value = (WMGetButtonSelected(panel->alwChk) != 0) ? Yes : No;
536 different |= insertAttribute(dict, winDic, AAlwaysUserIcon, value, flags);
538 value = (WMGetButtonSelected(panel->attrChk[0]) != 0) ? Yes : No;
539 different |= insertAttribute(dict, winDic, ANoTitlebar, value, flags);
541 value = (WMGetButtonSelected(panel->attrChk[1]) != 0) ? Yes : No;
542 different |= insertAttribute(dict, winDic, ANoResizebar, value, flags);
544 value = (WMGetButtonSelected(panel->attrChk[2]) != 0) ? Yes : No;
545 different |= insertAttribute(dict, winDic, ANoCloseButton, value, flags);
547 value = (WMGetButtonSelected(panel->attrChk[3]) != 0) ? Yes : No;
548 different |= insertAttribute(dict, winDic, ANoMiniaturizeButton, value, flags);
550 value = (WMGetButtonSelected(panel->attrChk[4]) != 0) ? Yes : No;
551 different |= insertAttribute(dict, winDic, ANoBorder, value, flags);
553 value = (WMGetButtonSelected(panel->attrChk[5]) != 0) ? Yes : No;
554 different |= insertAttribute(dict, winDic, AKeepOnTop, value, flags);
556 value = (WMGetButtonSelected(panel->attrChk[6]) != 0) ? Yes : No;
557 different |= insertAttribute(dict, winDic, AKeepOnBottom, value, flags);
559 value = (WMGetButtonSelected(panel->attrChk[7]) != 0) ? Yes : No;
560 different |= insertAttribute(dict, winDic, AOmnipresent, value, flags);
562 value = (WMGetButtonSelected(panel->attrChk[8]) != 0) ? Yes : No;
563 different |= insertAttribute(dict, winDic, AStartMiniaturized, value, flags);
565 value = (WMGetButtonSelected(panel->attrChk[9]) != 0) ? Yes : No;
566 different |= insertAttribute(dict, winDic, AStartMaximized, value, flags);
568 value = (WMGetButtonSelected(panel->attrChk[10]) != 0) ? Yes : No;
569 different |= insertAttribute(dict, winDic, AFullMaximize, value, flags);
571 value = (WMGetButtonSelected(panel->moreChk[0]) != 0) ? Yes : No;
572 different |= insertAttribute(dict, winDic, ANoKeyBindings, value, flags);
574 value = (WMGetButtonSelected(panel->moreChk[1]) != 0) ? Yes : No;
575 different |= insertAttribute(dict, winDic, ANoMouseBindings, value, flags);
577 value = (WMGetButtonSelected(panel->moreChk[2]) != 0) ? Yes : No;
578 different |= insertAttribute(dict, winDic, ASkipWindowList, value, flags);
580 value = (WMGetButtonSelected(panel->moreChk[3]) != 0) ? Yes : No;
581 different |= insertAttribute(dict, winDic, ASkipSwitchPanel, value, flags);
583 value = (WMGetButtonSelected(panel->moreChk[4]) != 0) ? Yes : No;
584 different |= insertAttribute(dict, winDic, AUnfocusable, value, flags);
586 value = (WMGetButtonSelected(panel->moreChk[5]) != 0) ? Yes : No;
587 different |= insertAttribute(dict, winDic, AKeepInsideScreen, value, flags);
589 value = (WMGetButtonSelected(panel->moreChk[6]) != 0) ? Yes : No;
590 different |= insertAttribute(dict, winDic, ANoHideOthers, value, flags);
592 value = (WMGetButtonSelected(panel->moreChk[7]) != 0) ? Yes : No;
593 different |= insertAttribute(dict, winDic, ADontSaveSession, value, flags);
595 value = (WMGetButtonSelected(panel->moreChk[8]) != 0) ? Yes : No;
596 different |= insertAttribute(dict, winDic, AEmulateAppIcon, value, flags);
598 value = (WMGetButtonSelected(panel->moreChk[9]) != 0) ? Yes : No;
599 different |= insertAttribute(dict, winDic, AFocusAcrossWorkspace, value, flags);
601 value = (WMGetButtonSelected(panel->moreChk[10]) != 0) ? Yes : No;
602 different |= insertAttribute(dict, winDic, ANoMiniaturizable, value, flags);
604 #ifdef XKB_BUTTON_HINT
605 value = (WMGetButtonSelected(panel->moreChk[11]) != 0) ? Yes : No;
606 different |= insertAttribute(dict, winDic, ANoLanguageButton, value, flags);
607 #endif
609 if (wwin->main_window != None && wApplicationOf(wwin->main_window) != NULL) {
610 value = (WMGetButtonSelected(panel->appChk[0]) != 0) ? Yes : No;
611 different2 |= insertAttribute(dict, appDic, AStartHidden, value, flags);
613 value = (WMGetButtonSelected(panel->appChk[1]) != 0) ? Yes : No;
614 different2 |= insertAttribute(dict, appDic, ANoAppIcon, value, flags);
616 value = (WMGetButtonSelected(panel->appChk[2]) != 0) ? Yes : No;
617 different2 |= insertAttribute(dict, appDic, ASharedAppIcon, value, flags);
620 if (wwin->fake_group) {
621 key2 = WMCreatePLString(wwin->fake_group->identifier);
622 if (WMIsPropListEqualTo(key, key2)) {
623 WMMergePLDictionaries(winDic, appDic, True);
624 different |= different2;
625 } else {
626 WMRemoveFromPLDictionary(dict, key2);
627 if (different2) {
628 WMPutInPLDictionary(dict, key2, appDic);
631 WMReleasePropList(key2);
632 WMReleasePropList(appDic);
633 } else if (wwin->main_window != wwin->client_win) {
634 WApplication *wapp = wApplicationOf(wwin->main_window);
636 if (wapp) {
637 char *instance = wapp->main_window_desc->wm_instance;
638 char *class = wapp->main_window_desc->wm_class;
639 char *buffer;
641 buffer = StrConcatDot(instance, class);
642 key2 = WMCreatePLString(buffer);
643 wfree(buffer);
645 if (WMIsPropListEqualTo(key, key2)) {
646 WMMergePLDictionaries(winDic, appDic, True);
647 different |= different2;
648 } else {
649 WMRemoveFromPLDictionary(dict, key2);
650 if (different2)
651 WMPutInPLDictionary(dict, key2, appDic);
653 WMReleasePropList(key2);
654 WMReleasePropList(appDic);
656 } else {
657 WMMergePLDictionaries(winDic, appDic, True);
658 different |= different2;
659 WMReleasePropList(appDic);
662 WMRemoveFromPLDictionary(dict, key);
663 if (different) {
664 WMPutInPLDictionary(dict, key, winDic);
667 WMReleasePropList(key);
668 WMReleasePropList(winDic);
670 UpdateDomainFile(db);
672 /* clean up */
673 WMPLSetCaseSensitive(False);
676 static void applySettings(WMButton *button, InspectorPanel *panel)
678 WWindow *wwin = panel->inspected;
679 WApplication *wapp = wApplicationOf(wwin->main_window);
680 int floating, sunken, skip_window_list;
681 int old_omnipresent;
682 int old_no_bind_keys;
683 int old_no_bind_mouse;
685 old_omnipresent = WFLAGP(wwin, omnipresent);
686 old_no_bind_keys = WFLAGP(wwin, no_bind_keys);
687 old_no_bind_mouse = WFLAGP(wwin, no_bind_mouse);
689 showIconFor(WMWidgetScreen(button), panel, NULL, NULL, USE_TEXT_FIELD);
691 /* Attributes... --> Window Attributes */
692 WSETUFLAG(wwin, no_titlebar, WMGetButtonSelected(panel->attrChk[0]));
693 WSETUFLAG(wwin, no_resizebar, WMGetButtonSelected(panel->attrChk[1]));
694 WSETUFLAG(wwin, no_close_button, WMGetButtonSelected(panel->attrChk[2]));
695 WSETUFLAG(wwin, no_miniaturize_button, WMGetButtonSelected(panel->attrChk[3]));
696 WSETUFLAG(wwin, no_border, WMGetButtonSelected(panel->attrChk[4]));
697 floating = WMGetButtonSelected(panel->attrChk[5]);
698 sunken = WMGetButtonSelected(panel->attrChk[6]);
699 WSETUFLAG(wwin, omnipresent, WMGetButtonSelected(panel->attrChk[7]));
700 WSETUFLAG(wwin, start_miniaturized, WMGetButtonSelected(panel->attrChk[8]));
701 WSETUFLAG(wwin, start_maximized, WMGetButtonSelected(panel->attrChk[9]));
702 WSETUFLAG(wwin, full_maximize, WMGetButtonSelected(panel->attrChk[10]));
704 /* Attributes... --> Advanced Options */
705 WSETUFLAG(wwin, no_bind_keys, WMGetButtonSelected(panel->moreChk[0]));
706 WSETUFLAG(wwin, no_bind_mouse, WMGetButtonSelected(panel->moreChk[1]));
707 skip_window_list = WMGetButtonSelected(panel->moreChk[2]);
708 WSETUFLAG(wwin, skip_switchpanel, WMGetButtonSelected(panel->moreChk[3]));
709 WSETUFLAG(wwin, no_focusable, WMGetButtonSelected(panel->moreChk[4]));
710 WSETUFLAG(wwin, dont_move_off, WMGetButtonSelected(panel->moreChk[5]));
711 WSETUFLAG(wwin, no_hide_others, WMGetButtonSelected(panel->moreChk[6]));
712 WSETUFLAG(wwin, dont_save_session, WMGetButtonSelected(panel->moreChk[7]));
713 WSETUFLAG(wwin, emulate_appicon, WMGetButtonSelected(panel->moreChk[8]));
714 WSETUFLAG(wwin, focus_across_wksp, WMGetButtonSelected(panel->moreChk[9]));
715 WSETUFLAG(wwin, no_miniaturizable, WMGetButtonSelected(panel->moreChk[10]));
716 #ifdef XKB_BUTTON_HINT
717 WSETUFLAG(wwin, no_language_button, WMGetButtonSelected(panel->moreChk[11]));
718 #endif
719 WSETUFLAG(wwin, always_user_icon, WMGetButtonSelected(panel->alwChk));
721 if (WFLAGP(wwin, no_titlebar) && wwin->flags.shaded)
722 wUnshadeWindow(wwin);
724 WSETUFLAG(wwin, no_shadeable, WFLAGP(wwin, no_titlebar));
726 if (floating) {
727 if (!WFLAGP(wwin, floating))
728 ChangeStackingLevel(wwin->frame->core, WMFloatingLevel);
729 } else if (sunken) {
730 if (!WFLAGP(wwin, sunken))
731 ChangeStackingLevel(wwin->frame->core, WMSunkenLevel);
732 } else {
733 if (WFLAGP(wwin, floating) || WFLAGP(wwin, sunken))
734 ChangeStackingLevel(wwin->frame->core, WMNormalLevel);
737 WSETUFLAG(wwin, sunken, sunken);
738 WSETUFLAG(wwin, floating, floating);
739 wwin->flags.omnipresent = 0;
741 if (WFLAGP(wwin, skip_window_list) != skip_window_list) {
742 WSETUFLAG(wwin, skip_window_list, skip_window_list);
743 UpdateSwitchMenu(wwin->screen_ptr, wwin, skip_window_list ? ACTION_REMOVE : ACTION_ADD);
744 } else {
745 if (WFLAGP(wwin, omnipresent) != old_omnipresent) {
746 WMPostNotificationName(WMNChangedState, wwin, "omnipresent");
750 if (WFLAGP(wwin, no_bind_keys) != old_no_bind_keys) {
751 if (WFLAGP(wwin, no_bind_keys)) {
752 XUngrabKey(dpy, AnyKey, AnyModifier, wwin->frame->core->window);
753 } else {
754 wWindowSetKeyGrabs(wwin);
758 if (WFLAGP(wwin, no_bind_mouse) != old_no_bind_mouse) {
759 wWindowResetMouseGrabs(wwin);
762 wwin->frame->flags.need_texture_change = 1;
763 wWindowConfigureBorders(wwin);
764 wFrameWindowPaint(wwin->frame);
765 wNETWMUpdateActions(wwin, False);
768 * Can't apply emulate_appicon because it will probably cause problems.
770 if (wapp) {
771 /* do application wide stuff */
772 WSETUFLAG(wapp->main_window_desc, start_hidden, WMGetButtonSelected(panel->appChk[0]));
774 WSETUFLAG(wapp->main_window_desc, no_appicon, WMGetButtonSelected(panel->appChk[1]));
776 WSETUFLAG(wapp->main_window_desc, shared_appicon, WMGetButtonSelected(panel->appChk[2]));
778 if (WFLAGP(wapp->main_window_desc, no_appicon))
779 removeAppIconFor(wapp);
780 else
781 makeAppIconFor(wapp);
783 if (wapp->app_icon && wapp->main_window == wwin->client_win) {
784 char *file = WMGetTextFieldText(panel->fileText);
786 if (file[0] == 0) {
787 wfree(file);
788 file = NULL;
790 wIconChangeImageFile(wapp->app_icon->icon, file);
791 if (file)
792 wfree(file);
793 wAppIconPaint(wapp->app_icon);
798 static void revertSettings(WMButton *button, InspectorPanel *panel)
800 WWindow *wwin = panel->inspected;
801 WApplication *wapp = wApplicationOf(wwin->main_window);
802 int i, n;
803 char *wm_instance = NULL;
804 char *wm_class = NULL;
805 int workspace, level;
807 if (panel->instRb && WMGetButtonSelected(panel->instRb) != 0)
808 wm_instance = wwin->wm_instance;
809 else if (panel->clsRb && WMGetButtonSelected(panel->clsRb) != 0)
810 wm_class = wwin->wm_class;
811 else if (panel->bothRb && WMGetButtonSelected(panel->bothRb) != 0) {
812 wm_instance = wwin->wm_instance;
813 wm_class = wwin->wm_class;
815 memset(&wwin->defined_user_flags, 0, sizeof(WWindowAttributes));
816 memset(&wwin->user_flags, 0, sizeof(WWindowAttributes));
817 memset(&wwin->client_flags, 0, sizeof(WWindowAttributes));
819 wWindowSetupInitialAttributes(wwin, &level, &workspace);
821 for (i = 0; i < (sizeof(panel->attrChk) / sizeof(panel->attrChk[0])); i++) {
822 int flag = 0;
824 switch (i) {
825 case 0:
826 flag = WFLAGP(wwin, no_titlebar);
827 break;
828 case 1:
829 flag = WFLAGP(wwin, no_resizebar);
830 break;
831 case 2:
832 flag = WFLAGP(wwin, no_close_button);
833 break;
834 case 3:
835 flag = WFLAGP(wwin, no_miniaturize_button);
836 break;
837 case 4:
838 flag = WFLAGP(wwin, no_border);
839 break;
840 case 5:
841 flag = WFLAGP(wwin, floating);
842 break;
843 case 6:
844 flag = WFLAGP(wwin, sunken);
845 break;
846 case 7:
847 flag = WFLAGP(wwin, omnipresent);
848 break;
849 case 8:
850 flag = WFLAGP(wwin, start_miniaturized);
851 break;
852 case 9:
853 flag = WFLAGP(wwin, start_maximized != 0);
854 break;
855 case 10:
856 flag = WFLAGP(wwin, full_maximize);
857 break;
859 WMSetButtonSelected(panel->attrChk[i], flag);
861 for (i = 0; i < (sizeof(panel->moreChk) / sizeof(panel->moreChk[0])); i++) {
862 int flag = 0;
864 switch (i) {
865 case 0:
866 flag = WFLAGP(wwin, no_bind_keys);
867 break;
868 case 1:
869 flag = WFLAGP(wwin, no_bind_mouse);
870 break;
871 case 2:
872 flag = WFLAGP(wwin, skip_window_list);
873 break;
874 case 3:
875 flag = WFLAGP(wwin, skip_switchpanel);
876 break;
877 case 4:
878 flag = WFLAGP(wwin, no_focusable);
879 break;
880 case 5:
881 flag = WFLAGP(wwin, dont_move_off);
882 break;
883 case 6:
884 flag = WFLAGP(wwin, no_hide_others);
885 break;
886 case 7:
887 flag = WFLAGP(wwin, dont_save_session);
888 break;
889 case 8:
890 flag = WFLAGP(wwin, emulate_appicon);
891 break;
892 case 9:
893 flag = WFLAGP(wwin, focus_across_wksp);
894 break;
895 case 10:
896 flag = WFLAGP(wwin, no_miniaturizable);
897 break;
898 #ifdef XKB_BUTTON_HINT
899 case 11:
900 flag = WFLAGP(wwin, no_language_button);
901 break;
902 #endif
904 WMSetButtonSelected(panel->moreChk[i], flag);
906 if (panel->appFrm && wapp) {
907 for (i = 0; i < (sizeof(panel->appChk) / sizeof(panel->appChk[0])); i++) {
908 int flag = 0;
910 switch (i) {
911 case 0:
912 flag = WFLAGP(wapp->main_window_desc, start_hidden);
913 break;
914 case 1:
915 flag = WFLAGP(wapp->main_window_desc, no_appicon);
916 break;
917 case 2:
918 flag = WFLAGP(wapp->main_window_desc, shared_appicon);
919 break;
921 WMSetButtonSelected(panel->appChk[i], flag);
924 WMSetButtonSelected(panel->alwChk, WFLAGP(wwin, always_user_icon));
926 showIconFor(WMWidgetScreen(panel->alwChk), panel, wm_instance, wm_class, REVERT_TO_DEFAULT);
928 n = wDefaultGetStartWorkspace(wwin->screen_ptr, wm_instance, wm_class);
930 if (n >= 0 && n < wwin->screen_ptr->workspace_count) {
931 WMSetPopUpButtonSelectedItem(panel->wsP, n + 1);
932 } else {
933 WMSetPopUpButtonSelectedItem(panel->wsP, 0);
936 /* must auto apply, so that there wno't be internal
937 * inconsistencies between the state in the flags and
938 * the actual state of the window */
939 applySettings(panel->applyBtn, panel);
942 static void chooseIconCallback(WMWidget *self, void *clientData)
944 char *file;
945 InspectorPanel *panel = (InspectorPanel *) clientData;
946 int result;
948 panel->choosingIcon = 1;
950 WMSetButtonEnabled(panel->browseIconBtn, False);
952 result = wIconChooserDialog(panel->frame->screen_ptr, &file,
953 panel->inspected->wm_instance, panel->inspected->wm_class);
955 panel->choosingIcon = 0;
957 if (!panel->destroyed) { /* kluge */
958 if (result) {
959 WMSetTextFieldText(panel->fileText, file);
960 showIconFor(WMWidgetScreen(self), panel, NULL, NULL, USE_TEXT_FIELD);
961 wfree(file);
963 WMSetButtonEnabled(panel->browseIconBtn, True);
964 } else {
965 freeInspector(panel);
969 static void textEditedObserver(void *observerData, WMNotification *notification)
971 InspectorPanel *panel = (InspectorPanel *) observerData;
973 if ((long)WMGetNotificationClientData(notification) != WMReturnTextMovement)
974 return;
976 showIconFor(WMWidgetScreen(panel->win), panel, NULL, NULL, USE_TEXT_FIELD);
978 WMPerformButtonClick(panel->updateIconBtn);
982 static void selectSpecification(WMWidget *bPtr, void *data)
984 InspectorPanel *panel = (InspectorPanel *) data;
985 char *str;
986 WWindow *wwin = panel->inspected;
987 int len;
989 if (bPtr == panel->defaultRb && (wwin->wm_instance || wwin->wm_class))
990 WMSetButtonEnabled(panel->applyBtn, False);
991 else
992 WMSetButtonEnabled(panel->applyBtn, True);
994 len = 16 + strlen(wwin->wm_instance ? wwin->wm_instance : "?")
995 + strlen(wwin->wm_class ? wwin->wm_class : "?");
997 str = wmalloc(len);
999 snprintf(str, len, _("Inspecting %s.%s"),
1000 wwin->wm_instance ? wwin->wm_instance : "?", wwin->wm_class ? wwin->wm_class : "?");
1002 wFrameWindowChangeTitle(panel->frame->frame, str);
1004 wfree(str);
1007 static void selectWindow(WMWidget *bPtr, void *data)
1009 InspectorPanel *panel = (InspectorPanel *) data;
1010 WWindow *wwin = panel->inspected;
1011 WScreen *scr = wwin->screen_ptr;
1012 XEvent event;
1013 WWindow *iwin;
1015 if (XGrabPointer(dpy, scr->root_win, True,
1016 ButtonPressMask, GrabModeAsync, GrabModeAsync, None,
1017 wCursor[WCUR_SELECT], CurrentTime) != GrabSuccess) {
1018 wwarning("could not grab mouse pointer");
1019 return;
1022 WMSetLabelText(panel->specLbl, _("Click in the window you wish to inspect."));
1024 WMMaskEvent(dpy, ButtonPressMask, &event);
1026 XUngrabPointer(dpy, CurrentTime);
1028 iwin = wWindowFor(event.xbutton.subwindow);
1030 if (iwin && !iwin->flags.internal_window && iwin != wwin && !iwin->flags.inspector_open) {
1032 iwin->flags.inspector_open = 1;
1033 iwin->inspector = createInspectorForWindow(iwin,
1034 panel->frame->frame_x, panel->frame->frame_y, True);
1035 wCloseInspectorForWindow(wwin);
1036 } else {
1037 WMSetLabelText(panel->specLbl, spec_text);
1041 static InspectorPanel *createInspectorForWindow(WWindow *wwin, int xpos, int ypos, Bool showSelectPanel)
1043 WScreen *scr = wwin->screen_ptr;
1044 InspectorPanel *panel;
1045 Window parent;
1046 int i;
1047 int x, y;
1048 int btn_width, frame_width;
1049 WMButton *selectedBtn = NULL;
1050 #ifdef wrong_behaviour
1051 WMPixmap *pixmap;
1052 #endif
1054 spec_text = _("The configuration will apply to all\n"
1055 "windows that have their WM_CLASS\n"
1056 "property set to the above selected\n" "name, when saved.");
1058 panel = wmalloc(sizeof(InspectorPanel));
1059 memset(panel, 0, sizeof(InspectorPanel));
1061 panel->destroyed = 0;
1063 panel->inspected = wwin;
1065 panel->nextPtr = panelList;
1066 panelList = panel;
1068 panel->win = WMCreateWindow(scr->wmscreen, "windowInspector");
1069 WMResizeWidget(panel->win, PWIDTH, PHEIGHT);
1071 /**** create common stuff ****/
1073 /* command buttons */
1074 /* (PWIDTH - (left and right margin) - (btn interval)) / 3 */
1075 btn_width = (PWIDTH - (2 * 15) - (2 * 10)) / 3;
1076 panel->saveBtn = WMCreateCommandButton(panel->win);
1077 WMSetButtonAction(panel->saveBtn, (WMAction *) saveSettings, panel);
1078 WMMoveWidget(panel->saveBtn, (2 * (btn_width + 10)) + 15, PHEIGHT - 40);
1079 WMSetButtonText(panel->saveBtn, _("Save"));
1080 WMResizeWidget(panel->saveBtn, btn_width, 28);
1081 if (wPreferences.flags.noupdates || !(wwin->wm_class || wwin->wm_instance))
1082 WMSetButtonEnabled(panel->saveBtn, False);
1084 panel->applyBtn = WMCreateCommandButton(panel->win);
1085 WMSetButtonAction(panel->applyBtn, (WMAction *) applySettings, panel);
1086 WMMoveWidget(panel->applyBtn, btn_width + 10 + 15, PHEIGHT - 40);
1087 WMSetButtonText(panel->applyBtn, _("Apply"));
1088 WMResizeWidget(panel->applyBtn, btn_width, 28);
1090 panel->revertBtn = WMCreateCommandButton(panel->win);
1091 WMSetButtonAction(panel->revertBtn, (WMAction *) revertSettings, panel);
1092 WMMoveWidget(panel->revertBtn, 15, PHEIGHT - 40);
1093 WMSetButtonText(panel->revertBtn, _("Reload"));
1094 WMResizeWidget(panel->revertBtn, btn_width, 28);
1096 /* page selection popup button */
1097 panel->pagePopUp = WMCreatePopUpButton(panel->win);
1098 WMSetPopUpButtonAction(panel->pagePopUp, (WMAction *) changePage, panel);
1099 WMMoveWidget(panel->pagePopUp, 25, 15);
1100 WMResizeWidget(panel->pagePopUp, PWIDTH - 50, 20);
1102 WMAddPopUpButtonItem(panel->pagePopUp, _("Window Specification"));
1103 WMAddPopUpButtonItem(panel->pagePopUp, _("Window Attributes"));
1104 WMAddPopUpButtonItem(panel->pagePopUp, _("Advanced Options"));
1105 WMAddPopUpButtonItem(panel->pagePopUp, _("Icon and Initial Workspace"));
1106 WMAddPopUpButtonItem(panel->pagePopUp, _("Application Specific"));
1108 /**** window spec ****/
1109 frame_width = PWIDTH - (2 * 15);
1111 panel->specFrm = WMCreateFrame(panel->win);
1112 WMSetFrameTitle(panel->specFrm, _("Window Specification"));
1113 WMMoveWidget(panel->specFrm, 15, 65);
1114 WMResizeWidget(panel->specFrm, frame_width, 145);
1116 panel->defaultRb = WMCreateRadioButton(panel->specFrm);
1117 WMMoveWidget(panel->defaultRb, 10, 78);
1118 WMResizeWidget(panel->defaultRb, frame_width - (2 * 10), 20);
1119 WMSetButtonText(panel->defaultRb, _("Defaults for all windows"));
1120 WMSetButtonSelected(panel->defaultRb, False);
1121 WMSetButtonAction(panel->defaultRb, selectSpecification, panel);
1123 if (wwin->wm_class && wwin->wm_instance) {
1124 char *str, *tmp;
1126 tmp = wstrconcat(wwin->wm_instance, ".");
1127 str = wstrconcat(tmp, wwin->wm_class);
1129 panel->bothRb = WMCreateRadioButton(panel->specFrm);
1130 WMMoveWidget(panel->bothRb, 10, 18);
1131 WMResizeWidget(panel->bothRb, frame_width - (2 * 10), 20);
1132 WMSetButtonText(panel->bothRb, str);
1133 wfree(tmp);
1134 wfree(str);
1135 WMGroupButtons(panel->defaultRb, panel->bothRb);
1137 if (!selectedBtn)
1138 selectedBtn = panel->bothRb;
1140 WMSetButtonAction(panel->bothRb, selectSpecification, panel);
1143 if (wwin->wm_instance) {
1144 panel->instRb = WMCreateRadioButton(panel->specFrm);
1145 WMMoveWidget(panel->instRb, 10, 38);
1146 WMResizeWidget(panel->instRb, frame_width - (2 * 10), 20);
1147 WMSetButtonText(panel->instRb, wwin->wm_instance);
1148 WMGroupButtons(panel->defaultRb, panel->instRb);
1150 if (!selectedBtn)
1151 selectedBtn = panel->instRb;
1153 WMSetButtonAction(panel->instRb, selectSpecification, panel);
1156 if (wwin->wm_class) {
1157 panel->clsRb = WMCreateRadioButton(panel->specFrm);
1158 WMMoveWidget(panel->clsRb, 10, 58);
1159 WMResizeWidget(panel->clsRb, frame_width - (2 * 10), 20);
1160 WMSetButtonText(panel->clsRb, wwin->wm_class);
1161 WMGroupButtons(panel->defaultRb, panel->clsRb);
1163 if (!selectedBtn)
1164 selectedBtn = panel->clsRb;
1166 WMSetButtonAction(panel->clsRb, selectSpecification, panel);
1169 panel->selWinB = WMCreateCommandButton(panel->specFrm);
1170 WMMoveWidget(panel->selWinB, 20, 145 - 24 - 10);
1171 WMResizeWidget(panel->selWinB, frame_width - 2 * 10 - 20, 24);
1172 WMSetButtonText(panel->selWinB, _("Select window"));
1173 WMSetButtonAction(panel->selWinB, selectWindow, panel);
1175 panel->specLbl = WMCreateLabel(panel->win);
1176 WMMoveWidget(panel->specLbl, 15, 210);
1177 WMResizeWidget(panel->specLbl, frame_width, 100);
1178 WMSetLabelText(panel->specLbl, spec_text);
1179 WMSetLabelWraps(panel->specLbl, True);
1181 WMSetLabelTextAlignment(panel->specLbl, WALeft);
1183 /**** attributes ****/
1184 panel->attrFrm = WMCreateFrame(panel->win);
1185 WMSetFrameTitle(panel->attrFrm, _("Attributes"));
1186 WMMoveWidget(panel->attrFrm, 15, 45);
1187 WMResizeWidget(panel->attrFrm, frame_width, 250);
1189 for (i = 0; i < (sizeof(panel->attrChk) / sizeof(panel->attrChk[0])); i++) {
1190 char *caption = NULL;
1191 int flag = 0;
1192 char *descr = NULL;
1194 switch (i) {
1195 case 0:
1196 caption = _("Disable titlebar");
1197 flag = WFLAGP(wwin, no_titlebar);
1198 descr = _("Remove the titlebar of this window.\n"
1199 "To access the window commands menu of a window\n"
1200 "without it's titlebar, press Control+Esc (or the\n"
1201 "equivalent shortcut, if you changed the default\n" "settings).");
1202 break;
1203 case 1:
1204 caption = _("Disable resizebar");
1205 flag = WFLAGP(wwin, no_resizebar);
1206 descr = _("Remove the resizebar of this window.");
1207 break;
1208 case 2:
1209 caption = _("Disable close button");
1210 flag = WFLAGP(wwin, no_close_button);
1211 descr = _("Remove the `close window' button of this window.");
1212 break;
1213 case 3:
1214 caption = _("Disable miniaturize button");
1215 flag = WFLAGP(wwin, no_miniaturize_button);
1216 descr = _("Remove the `miniaturize window' button of the window.");
1217 break;
1218 case 4:
1219 caption = _("Disable border");
1220 flag = WFLAGP(wwin, no_border);
1221 descr = _("Remove the 1 pixel black border around the window.");
1222 break;
1223 case 5:
1224 caption = _("Keep on top (floating)");
1225 flag = WFLAGP(wwin, floating);
1226 descr = _("Keep the window over other windows, not allowing\n" "them to cover it.");
1227 break;
1228 case 6:
1229 caption = _("Keep at bottom (sunken)");
1230 flag = WFLAGP(wwin, sunken);
1231 descr = _("Keep the window under all other windows.");
1232 break;
1233 case 7:
1234 caption = _("Omnipresent");
1235 flag = WFLAGP(wwin, omnipresent);
1236 descr = _("Make window present in all workspaces.");
1237 break;
1238 case 8:
1239 caption = _("Start miniaturized");
1240 flag = WFLAGP(wwin, start_miniaturized);
1241 descr = _("Make the window be automatically miniaturized when it's\n" "first shown.");
1242 break;
1243 case 9:
1244 caption = _("Start maximized");
1245 flag = WFLAGP(wwin, start_maximized != 0);
1246 descr = _("Make the window be automatically maximized when it's\n" "first shown.");
1247 break;
1248 case 10:
1249 caption = _("Full screen maximization");
1250 flag = WFLAGP(wwin, full_maximize);
1251 descr = _("Make the window use the whole screen space when it's\n"
1252 "maximized. The titlebar and resizebar will be moved\n"
1253 "to outside the screen.");
1254 break;
1256 panel->attrChk[i] = WMCreateSwitchButton(panel->attrFrm);
1257 WMMoveWidget(panel->attrChk[i], 10, 20 * (i + 1));
1258 WMResizeWidget(panel->attrChk[i], frame_width - 15, 20);
1259 WMSetButtonSelected(panel->attrChk[i], flag);
1260 WMSetButtonText(panel->attrChk[i], caption);
1262 WMSetBalloonTextForView(descr, WMWidgetView(panel->attrChk[i]));
1265 /**** more attributes ****/
1266 panel->moreFrm = WMCreateFrame(panel->win);
1267 WMSetFrameTitle(panel->moreFrm, _("Advanced"));
1268 WMMoveWidget(panel->moreFrm, 15, 45);
1269 WMResizeWidget(panel->moreFrm, frame_width, 265);
1271 for (i = 0; i < (sizeof(panel->moreChk) / sizeof(panel->moreChk[0])); i++) {
1272 char *caption = NULL;
1273 int flag = 0;
1274 char *descr = NULL;
1276 switch (i) {
1277 case 0:
1278 caption = _("Do not bind keyboard shortcuts");
1279 flag = WFLAGP(wwin, no_bind_keys);
1280 descr = _("Do not bind keyboard shortcuts from Window Maker\n"
1281 "when this window is focused. This will allow the\n"
1282 "window to receive all key combinations regardless\n"
1283 "of your shortcut configuration.");
1284 break;
1285 case 1:
1286 caption = _("Do not bind mouse clicks");
1287 flag = WFLAGP(wwin, no_bind_mouse);
1288 descr = _("Do not bind mouse actions, such as `Alt'+drag\n"
1289 "in the window (when alt is the modifier you have\n" "configured).");
1290 break;
1291 case 2:
1292 caption = _("Do not show in the window list");
1293 flag = WFLAGP(wwin, skip_window_list);
1294 descr = _("Do not list the window in the window list menu.");
1295 break;
1296 case 3:
1297 caption = _("Do not show in the switch panel");
1298 flag = WFLAGP(wwin, skip_switchpanel);
1299 descr = _("Do not include in switchpanel while alternating windows.");
1300 break;
1301 case 4:
1302 caption = _("Do not let it take focus");
1303 flag = WFLAGP(wwin, no_focusable);
1304 descr = _("Do not let the window take keyboard focus when you\n" "click on it.");
1305 break;
1306 case 5:
1307 caption = _("Keep inside screen");
1308 flag = WFLAGP(wwin, dont_move_off);
1309 descr = _("Do not allow the window to move itself completely\n"
1310 "outside the screen. For bug compatibility.\n");
1311 break;
1312 case 6:
1313 caption = _("Ignore 'Hide Others'");
1314 flag = WFLAGP(wwin, no_hide_others);
1315 descr = _("Do not hide the window when issuing the\n" "`HideOthers' command.");
1316 break;
1317 case 7:
1318 caption = _("Ignore 'Save Session'");
1319 flag = WFLAGP(wwin, dont_save_session);
1320 descr = _("Do not save the associated application in the\n"
1321 "session's state, so that it won't be restarted\n"
1322 "together with other applications when Window Maker\n" "starts.");
1323 break;
1324 case 8:
1325 caption = _("Emulate application icon");
1326 flag = WFLAGP(wwin, emulate_appicon);
1327 descr = _("Make this window act as an application that provides\n"
1328 "enough information to Window Maker for a dockable\n"
1329 "application icon to be created.");
1330 break;
1331 case 9:
1332 caption = _("Focus across workspaces");
1333 flag = WFLAGP(wwin, focus_across_wksp);
1334 descr = _("Allow Window Maker to switch workspace to satisfy\n"
1335 "a focus request (annoying).");
1336 break;
1337 case 10:
1338 caption = _("Do not let it be minimized");
1339 flag = WFLAGP(wwin, no_miniaturizable);
1340 descr = _("Do not let the window of this application be\n"
1341 "minimized.\n");
1342 break;
1343 #ifdef XKB_BUTTON_HINT
1344 case 11:
1345 caption = _("Disable language button");
1346 flag = WFLAGP(wwin, no_language_button);
1347 descr = _("Remove the `toggle language' button of the window.");
1348 break;
1349 #endif
1351 panel->moreChk[i] = WMCreateSwitchButton(panel->moreFrm);
1352 WMMoveWidget(panel->moreChk[i], 10, 20 * (i + 1));
1353 WMResizeWidget(panel->moreChk[i], frame_width - 15, 20);
1354 WMSetButtonSelected(panel->moreChk[i], flag);
1355 WMSetButtonText(panel->moreChk[i], caption);
1357 WMSetBalloonTextForView(descr, WMWidgetView(panel->moreChk[i]));
1360 /* miniwindow/workspace */
1361 panel->iconFrm = WMCreateFrame(panel->win);
1362 WMMoveWidget(panel->iconFrm, 15, 50);
1363 WMResizeWidget(panel->iconFrm, PWIDTH - (2 * 15), 170);
1364 WMSetFrameTitle(panel->iconFrm, _("Miniwindow Image"));
1366 panel->iconLbl = WMCreateLabel(panel->iconFrm);
1367 WMMoveWidget(panel->iconLbl, PWIDTH - (2 * 15) - 22 - 64, 20);
1368 WMResizeWidget(panel->iconLbl, 64, 64);
1369 WMSetLabelRelief(panel->iconLbl, WRGroove);
1370 WMSetLabelImagePosition(panel->iconLbl, WIPImageOnly);
1372 panel->browseIconBtn = WMCreateCommandButton(panel->iconFrm);
1373 WMSetButtonAction(panel->browseIconBtn, chooseIconCallback, panel);
1374 WMMoveWidget(panel->browseIconBtn, 22, 32);
1375 WMResizeWidget(panel->browseIconBtn, 120, 26);
1376 WMSetButtonText(panel->browseIconBtn, _("Browse..."));
1378 #ifdef wrong_behaviour
1379 WMSetButtonImagePosition(panel->updateIconBtn, WIPRight);
1380 pixmap = WMGetSystemPixmap(scr->wmscreen, WSIReturnArrow);
1381 WMSetButtonImage(panel->updateIconBtn, pixmap);
1382 WMReleasePixmap(pixmap);
1383 pixmap = WMGetSystemPixmap(scr->wmscreen, WSIHighlightedReturnArrow);
1384 WMSetButtonAltImage(panel->updateIconBtn, pixmap);
1385 WMReleasePixmap(pixmap);
1386 #endif
1388 panel->fileLbl = WMCreateLabel(panel->iconFrm);
1389 WMMoveWidget(panel->fileLbl, 20, 85);
1390 WMResizeWidget(panel->fileLbl, PWIDTH - (2 * 15) - (2 * 20), 14);
1391 WMSetLabelText(panel->fileLbl, _("Icon filename:"));
1393 panel->fileText = WMCreateTextField(panel->iconFrm);
1394 WMMoveWidget(panel->fileText, 20, 105);
1395 WMResizeWidget(panel->fileText, PWIDTH - (2 * 20) - (2 * 15), 20);
1396 WMSetTextFieldText(panel->fileText, NULL);
1397 WMAddNotificationObserver(textEditedObserver, panel, WMTextDidEndEditingNotification, panel->fileText);
1399 panel->alwChk = WMCreateSwitchButton(panel->iconFrm);
1400 WMMoveWidget(panel->alwChk, 20, 130);
1401 WMResizeWidget(panel->alwChk, PWIDTH - (2 * 15) - (2 * 15), 30);
1402 WMSetButtonText(panel->alwChk, _("Ignore client supplied icon"));
1403 WMSetButtonSelected(panel->alwChk, WFLAGP(wwin, always_user_icon));
1405 panel->wsFrm = WMCreateFrame(panel->win);
1406 WMMoveWidget(panel->wsFrm, 15, 225);
1407 WMResizeWidget(panel->wsFrm, PWIDTH - (2 * 15), 70);
1408 WMSetFrameTitle(panel->wsFrm, _("Initial Workspace"));
1410 WMSetBalloonTextForView(_("The workspace to place the window when it's"
1411 "first shown."), WMWidgetView(panel->wsFrm));
1413 panel->wsP = WMCreatePopUpButton(panel->wsFrm);
1414 WMMoveWidget(panel->wsP, 20, 30);
1415 WMResizeWidget(panel->wsP, PWIDTH - (2 * 15) - (2 * 20), 20);
1416 WMAddPopUpButtonItem(panel->wsP, _("Nowhere in particular"));
1418 for (i = 0; i < wwin->screen_ptr->workspace_count; i++)
1419 WMAddPopUpButtonItem(panel->wsP, scr->workspaces[i]->name);
1421 i = wDefaultGetStartWorkspace(wwin->screen_ptr, wwin->wm_instance, wwin->wm_class);
1422 if (i >= 0 && i <= wwin->screen_ptr->workspace_count)
1423 WMSetPopUpButtonSelectedItem(panel->wsP, i + 1);
1424 else
1425 WMSetPopUpButtonSelectedItem(panel->wsP, 0);
1427 /* application wide attributes */
1428 if (wwin->main_window != None) {
1429 WApplication *wapp = wApplicationOf(wwin->main_window);
1431 panel->appFrm = WMCreateFrame(panel->win);
1432 WMSetFrameTitle(panel->appFrm, _("Application Attributes"));
1433 WMMoveWidget(panel->appFrm, 15, 50);
1434 WMResizeWidget(panel->appFrm, frame_width, 240);
1436 for (i = 0; i < (sizeof(panel->appChk) / sizeof(panel->appChk[0])); i++) {
1437 char *caption = NULL;
1438 int flag = 0;
1439 char *descr = NULL;
1441 switch (i) {
1442 case 0:
1443 caption = _("Start hidden");
1444 flag = WFLAGP(wapp->main_window_desc, start_hidden);
1445 descr = _("Automatically hide application when it's started.");
1446 break;
1447 case 1:
1448 caption = _("No application icon");
1449 flag = WFLAGP(wapp->main_window_desc, no_appicon);
1450 descr = _("Disable the application icon for the application.\n"
1451 "Note that you won't be able to dock it anymore,\n"
1452 "and any icons that are already docked will stop\n"
1453 "working correctly.");
1454 break;
1455 case 2:
1456 caption = _("Shared application icon");
1457 flag = WFLAGP(wapp->main_window_desc, shared_appicon);
1458 descr = _("Use a single shared application icon for all of\n"
1459 "the instances of this application.\n");
1460 break;
1462 panel->appChk[i] = WMCreateSwitchButton(panel->appFrm);
1463 WMMoveWidget(panel->appChk[i], 10, 20 * (i + 1));
1464 WMResizeWidget(panel->appChk[i], 205, 20);
1465 WMSetButtonSelected(panel->appChk[i], flag);
1466 WMSetButtonText(panel->appChk[i], caption);
1467 WMSetBalloonTextForView(descr, WMWidgetView(panel->appChk[i]));
1470 if (WFLAGP(wwin, emulate_appicon)) {
1471 WMSetButtonEnabled(panel->appChk[1], False);
1472 WMSetButtonEnabled(panel->moreChk[7], True);
1473 } else {
1474 WMSetButtonEnabled(panel->appChk[1], True);
1475 WMSetButtonEnabled(panel->moreChk[7], False);
1477 } else {
1478 int tmp;
1480 if ((wwin->transient_for != None && wwin->transient_for != scr->root_win)
1481 || !wwin->wm_class || !wwin->wm_instance)
1482 tmp = False;
1483 else
1484 tmp = True;
1485 WMSetButtonEnabled(panel->moreChk[7], tmp);
1487 WMSetPopUpButtonItemEnabled(panel->pagePopUp, 4, False);
1488 panel->appFrm = NULL;
1491 /* if the window is a transient, don't let it have a miniaturize
1492 * button */
1493 if (wwin->transient_for != None && wwin->transient_for != scr->root_win)
1494 WMSetButtonEnabled(panel->attrChk[3], False);
1495 else
1496 WMSetButtonEnabled(panel->attrChk[3], True);
1498 if (!wwin->wm_class && !wwin->wm_instance) {
1499 WMSetPopUpButtonItemEnabled(panel->pagePopUp, 0, False);
1502 WMRealizeWidget(panel->win);
1504 WMMapSubwidgets(panel->win);
1505 WMMapSubwidgets(panel->specFrm);
1506 WMMapSubwidgets(panel->attrFrm);
1507 WMMapSubwidgets(panel->moreFrm);
1508 WMMapSubwidgets(panel->iconFrm);
1509 WMMapSubwidgets(panel->wsFrm);
1510 if (panel->appFrm)
1511 WMMapSubwidgets(panel->appFrm);
1513 if (showSelectPanel) {
1514 WMSetPopUpButtonSelectedItem(panel->pagePopUp, 0);
1515 changePage(panel->pagePopUp, panel);
1516 } else {
1517 WMSetPopUpButtonSelectedItem(panel->pagePopUp, 1);
1518 changePage(panel->pagePopUp, panel);
1521 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, PWIDTH, PHEIGHT, 0, 0, 0);
1522 XSelectInput(dpy, parent, KeyPressMask | KeyReleaseMask);
1523 panel->parent = parent;
1524 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
1526 WMMapWidget(panel->win);
1528 XSetTransientForHint(dpy, parent, wwin->client_win);
1530 if (xpos == UNDEFINED_POS) {
1531 x = wwin->frame_x + wwin->frame->core->width / 2;
1532 y = wwin->frame_y + wwin->frame->top_width * 2;
1533 if (y + PHEIGHT > scr->scr_height)
1534 y = scr->scr_height - PHEIGHT - 30;
1535 if (x + PWIDTH > scr->scr_width)
1536 x = scr->scr_width - PWIDTH;
1537 } else {
1538 x = xpos;
1539 y = ypos;
1542 panel->frame = wManageInternalWindow(scr, parent, wwin->client_win, "Inspector", x, y, PWIDTH, PHEIGHT);
1544 if (!selectedBtn)
1545 selectedBtn = panel->defaultRb;
1547 WMSetButtonSelected(selectedBtn, True);
1549 selectSpecification(selectedBtn, panel);
1551 /* kluge to know who should get the key events */
1552 panel->frame->client_leader = WMWidgetXID(panel->win);
1554 WSETUFLAG(panel->frame, no_closable, 0);
1555 WSETUFLAG(panel->frame, no_close_button, 0);
1556 wWindowUpdateButtonImages(panel->frame);
1557 wFrameWindowShowButton(panel->frame->frame, WFF_RIGHT_BUTTON);
1558 panel->frame->frame->on_click_right = destroyInspector;
1560 wWindowMap(panel->frame);
1562 showIconFor(WMWidgetScreen(panel->alwChk), panel, wwin->wm_instance, wwin->wm_class, UPDATE_TEXT_FIELD);
1564 return panel;
1567 void wShowInspectorForWindow(WWindow *wwin)
1569 if (wwin->flags.inspector_open)
1570 return;
1572 WMSetBalloonEnabled(wwin->screen_ptr->wmscreen, wPreferences.help_balloon);
1574 make_keys();
1575 wwin->flags.inspector_open = 1;
1576 wwin->inspector = createInspectorForWindow(wwin, UNDEFINED_POS, UNDEFINED_POS, False);
1579 void wHideInspectorForWindow(WWindow *wwin)
1581 WWindow *pwin = wwin->inspector->frame;
1583 wWindowUnmap(pwin);
1584 pwin->flags.hidden = 1;
1586 wClientSetState(pwin, IconicState, None);
1589 void wUnhideInspectorForWindow(WWindow *wwin)
1591 WWindow *pwin = wwin->inspector->frame;
1593 pwin->flags.hidden = 0;
1594 pwin->flags.mapped = 1;
1595 XMapWindow(dpy, pwin->client_win);
1596 XMapWindow(dpy, pwin->frame->core->window);
1597 wClientSetState(pwin, NormalState, None);
1600 WWindow *wGetWindowOfInspectorForWindow(WWindow *wwin)
1602 if (wwin->inspector) {
1603 assert(wwin->flags.inspector_open != 0);
1605 return wwin->inspector->frame;
1606 } else
1607 return NULL;
1610 void wCloseInspectorForWindow(WWindow *wwin)
1612 WWindow *pwin = wwin->inspector->frame; /* the inspector window */
1614 (*pwin->frame->on_click_right) (NULL, pwin, NULL);