Added option to 'configure' to control debug information for compilation
[wmaker-crm.git] / src / winspector.c
blob25e13b288955a49dcf5a1ebf32e4477c8f486da8
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]));
773 WSETUFLAG(wapp->main_window_desc, no_appicon, WMGetButtonSelected(panel->appChk[1]));
774 WSETUFLAG(wapp->main_window_desc, shared_appicon, WMGetButtonSelected(panel->appChk[2]));
776 if (WFLAGP(wapp->main_window_desc, no_appicon))
777 unpaint_app_icon(wapp);
778 else
779 paint_app_icon(wapp);
781 if (wapp->app_icon && wapp->main_window == wwin->client_win) {
782 char *file = WMGetTextFieldText(panel->fileText);
784 if (file[0] == 0) {
785 wfree(file);
786 file = NULL;
789 wIconChangeImageFile(wapp->app_icon->icon, file);
790 if (file)
791 wfree(file);
793 wAppIconPaint(wapp->app_icon);
797 wNETFrameExtents(wwin);
800 static void revertSettings(WMButton *button, InspectorPanel *panel)
802 WWindow *wwin = panel->inspected;
803 WApplication *wapp = wApplicationOf(wwin->main_window);
804 int i, n;
805 char *wm_instance = NULL;
806 char *wm_class = NULL;
807 int workspace, level;
809 if (panel->instRb && WMGetButtonSelected(panel->instRb) != 0)
810 wm_instance = wwin->wm_instance;
811 else if (panel->clsRb && WMGetButtonSelected(panel->clsRb) != 0)
812 wm_class = wwin->wm_class;
813 else if (panel->bothRb && WMGetButtonSelected(panel->bothRb) != 0) {
814 wm_instance = wwin->wm_instance;
815 wm_class = wwin->wm_class;
817 memset(&wwin->defined_user_flags, 0, sizeof(WWindowAttributes));
818 memset(&wwin->user_flags, 0, sizeof(WWindowAttributes));
819 memset(&wwin->client_flags, 0, sizeof(WWindowAttributes));
821 wWindowSetupInitialAttributes(wwin, &level, &workspace);
823 for (i = 0; i < (sizeof(panel->attrChk) / sizeof(panel->attrChk[0])); i++) {
824 int flag = 0;
826 switch (i) {
827 case 0:
828 flag = WFLAGP(wwin, no_titlebar);
829 break;
830 case 1:
831 flag = WFLAGP(wwin, no_resizebar);
832 break;
833 case 2:
834 flag = WFLAGP(wwin, no_close_button);
835 break;
836 case 3:
837 flag = WFLAGP(wwin, no_miniaturize_button);
838 break;
839 case 4:
840 flag = WFLAGP(wwin, no_border);
841 break;
842 case 5:
843 flag = WFLAGP(wwin, floating);
844 break;
845 case 6:
846 flag = WFLAGP(wwin, sunken);
847 break;
848 case 7:
849 flag = WFLAGP(wwin, omnipresent);
850 break;
851 case 8:
852 flag = WFLAGP(wwin, start_miniaturized);
853 break;
854 case 9:
855 flag = WFLAGP(wwin, start_maximized != 0);
856 break;
857 case 10:
858 flag = WFLAGP(wwin, full_maximize);
859 break;
861 WMSetButtonSelected(panel->attrChk[i], flag);
863 for (i = 0; i < (sizeof(panel->moreChk) / sizeof(panel->moreChk[0])); i++) {
864 int flag = 0;
866 switch (i) {
867 case 0:
868 flag = WFLAGP(wwin, no_bind_keys);
869 break;
870 case 1:
871 flag = WFLAGP(wwin, no_bind_mouse);
872 break;
873 case 2:
874 flag = WFLAGP(wwin, skip_window_list);
875 break;
876 case 3:
877 flag = WFLAGP(wwin, skip_switchpanel);
878 break;
879 case 4:
880 flag = WFLAGP(wwin, no_focusable);
881 break;
882 case 5:
883 flag = WFLAGP(wwin, dont_move_off);
884 break;
885 case 6:
886 flag = WFLAGP(wwin, no_hide_others);
887 break;
888 case 7:
889 flag = WFLAGP(wwin, dont_save_session);
890 break;
891 case 8:
892 flag = WFLAGP(wwin, emulate_appicon);
893 break;
894 case 9:
895 flag = WFLAGP(wwin, focus_across_wksp);
896 break;
897 case 10:
898 flag = WFLAGP(wwin, no_miniaturizable);
899 break;
900 #ifdef XKB_BUTTON_HINT
901 case 11:
902 flag = WFLAGP(wwin, no_language_button);
903 break;
904 #endif
906 WMSetButtonSelected(panel->moreChk[i], flag);
908 if (panel->appFrm && wapp) {
909 for (i = 0; i < (sizeof(panel->appChk) / sizeof(panel->appChk[0])); i++) {
910 int flag = 0;
912 switch (i) {
913 case 0:
914 flag = WFLAGP(wapp->main_window_desc, start_hidden);
915 break;
916 case 1:
917 flag = WFLAGP(wapp->main_window_desc, no_appicon);
918 break;
919 case 2:
920 flag = WFLAGP(wapp->main_window_desc, shared_appicon);
921 break;
923 WMSetButtonSelected(panel->appChk[i], flag);
926 WMSetButtonSelected(panel->alwChk, WFLAGP(wwin, always_user_icon));
928 showIconFor(WMWidgetScreen(panel->alwChk), panel, wm_instance, wm_class, REVERT_TO_DEFAULT);
930 n = wDefaultGetStartWorkspace(wwin->screen_ptr, wm_instance, wm_class);
932 if (n >= 0 && n < wwin->screen_ptr->workspace_count) {
933 WMSetPopUpButtonSelectedItem(panel->wsP, n + 1);
934 } else {
935 WMSetPopUpButtonSelectedItem(panel->wsP, 0);
938 /* must auto apply, so that there wno't be internal
939 * inconsistencies between the state in the flags and
940 * the actual state of the window */
941 applySettings(panel->applyBtn, panel);
944 static void chooseIconCallback(WMWidget *self, void *clientData)
946 char *file;
947 InspectorPanel *panel = (InspectorPanel *) clientData;
948 int result;
950 panel->choosingIcon = 1;
952 WMSetButtonEnabled(panel->browseIconBtn, False);
954 result = wIconChooserDialog(panel->frame->screen_ptr, &file,
955 panel->inspected->wm_instance, panel->inspected->wm_class);
957 panel->choosingIcon = 0;
959 if (!panel->destroyed) { /* kluge */
960 if (result) {
961 WMSetTextFieldText(panel->fileText, file);
962 showIconFor(WMWidgetScreen(self), panel, NULL, NULL, USE_TEXT_FIELD);
963 wfree(file);
965 WMSetButtonEnabled(panel->browseIconBtn, True);
966 } else {
967 freeInspector(panel);
971 static void textEditedObserver(void *observerData, WMNotification *notification)
973 InspectorPanel *panel = (InspectorPanel *) observerData;
975 if ((long)WMGetNotificationClientData(notification) != WMReturnTextMovement)
976 return;
978 showIconFor(WMWidgetScreen(panel->win), panel, NULL, NULL, USE_TEXT_FIELD);
980 WMPerformButtonClick(panel->updateIconBtn);
984 static void selectSpecification(WMWidget *bPtr, void *data)
986 InspectorPanel *panel = (InspectorPanel *) data;
987 char *str;
988 WWindow *wwin = panel->inspected;
989 int len;
991 if (bPtr == panel->defaultRb && (wwin->wm_instance || wwin->wm_class))
992 WMSetButtonEnabled(panel->applyBtn, False);
993 else
994 WMSetButtonEnabled(panel->applyBtn, True);
996 len = 16 + strlen(wwin->wm_instance ? wwin->wm_instance : "?")
997 + strlen(wwin->wm_class ? wwin->wm_class : "?");
999 str = wmalloc(len);
1001 snprintf(str, len, _("Inspecting %s.%s"),
1002 wwin->wm_instance ? wwin->wm_instance : "?", wwin->wm_class ? wwin->wm_class : "?");
1004 wFrameWindowChangeTitle(panel->frame->frame, str);
1006 wfree(str);
1009 static void selectWindow(WMWidget *bPtr, void *data)
1011 InspectorPanel *panel = (InspectorPanel *) data;
1012 WWindow *wwin = panel->inspected;
1013 WScreen *scr = wwin->screen_ptr;
1014 XEvent event;
1015 WWindow *iwin;
1017 if (XGrabPointer(dpy, scr->root_win, True,
1018 ButtonPressMask, GrabModeAsync, GrabModeAsync, None,
1019 wCursor[WCUR_SELECT], CurrentTime) != GrabSuccess) {
1020 wwarning("could not grab mouse pointer");
1021 return;
1024 WMSetLabelText(panel->specLbl, _("Click in the window you wish to inspect."));
1026 WMMaskEvent(dpy, ButtonPressMask, &event);
1028 XUngrabPointer(dpy, CurrentTime);
1030 iwin = wWindowFor(event.xbutton.subwindow);
1032 if (iwin && !iwin->flags.internal_window && iwin != wwin && !iwin->flags.inspector_open) {
1034 iwin->flags.inspector_open = 1;
1035 iwin->inspector = createInspectorForWindow(iwin,
1036 panel->frame->frame_x, panel->frame->frame_y, True);
1037 wCloseInspectorForWindow(wwin);
1038 } else {
1039 WMSetLabelText(panel->specLbl, spec_text);
1043 static InspectorPanel *createInspectorForWindow(WWindow *wwin, int xpos, int ypos, Bool showSelectPanel)
1045 WScreen *scr = wwin->screen_ptr;
1046 InspectorPanel *panel;
1047 Window parent;
1048 int i;
1049 int x, y;
1050 int btn_width, frame_width;
1051 WMButton *selectedBtn = NULL;
1052 #ifdef wrong_behaviour
1053 WMPixmap *pixmap;
1054 #endif
1056 spec_text = _("The configuration will apply to all\n"
1057 "windows that have their WM_CLASS\n"
1058 "property set to the above selected\n" "name, when saved.");
1060 panel = wmalloc(sizeof(InspectorPanel));
1061 memset(panel, 0, sizeof(InspectorPanel));
1063 panel->destroyed = 0;
1065 panel->inspected = wwin;
1067 panel->nextPtr = panelList;
1068 panelList = panel;
1070 panel->win = WMCreateWindow(scr->wmscreen, "windowInspector");
1071 WMResizeWidget(panel->win, PWIDTH, PHEIGHT);
1073 /**** create common stuff ****/
1075 /* command buttons */
1076 /* (PWIDTH - (left and right margin) - (btn interval)) / 3 */
1077 btn_width = (PWIDTH - (2 * 15) - (2 * 10)) / 3;
1078 panel->saveBtn = WMCreateCommandButton(panel->win);
1079 WMSetButtonAction(panel->saveBtn, (WMAction *) saveSettings, panel);
1080 WMMoveWidget(panel->saveBtn, (2 * (btn_width + 10)) + 15, PHEIGHT - 40);
1081 WMSetButtonText(panel->saveBtn, _("Save"));
1082 WMResizeWidget(panel->saveBtn, btn_width, 28);
1083 if (wPreferences.flags.noupdates || !(wwin->wm_class || wwin->wm_instance))
1084 WMSetButtonEnabled(panel->saveBtn, False);
1086 panel->applyBtn = WMCreateCommandButton(panel->win);
1087 WMSetButtonAction(panel->applyBtn, (WMAction *) applySettings, panel);
1088 WMMoveWidget(panel->applyBtn, btn_width + 10 + 15, PHEIGHT - 40);
1089 WMSetButtonText(panel->applyBtn, _("Apply"));
1090 WMResizeWidget(panel->applyBtn, btn_width, 28);
1092 panel->revertBtn = WMCreateCommandButton(panel->win);
1093 WMSetButtonAction(panel->revertBtn, (WMAction *) revertSettings, panel);
1094 WMMoveWidget(panel->revertBtn, 15, PHEIGHT - 40);
1095 WMSetButtonText(panel->revertBtn, _("Reload"));
1096 WMResizeWidget(panel->revertBtn, btn_width, 28);
1098 /* page selection popup button */
1099 panel->pagePopUp = WMCreatePopUpButton(panel->win);
1100 WMSetPopUpButtonAction(panel->pagePopUp, (WMAction *) changePage, panel);
1101 WMMoveWidget(panel->pagePopUp, 25, 15);
1102 WMResizeWidget(panel->pagePopUp, PWIDTH - 50, 20);
1104 WMAddPopUpButtonItem(panel->pagePopUp, _("Window Specification"));
1105 WMAddPopUpButtonItem(panel->pagePopUp, _("Window Attributes"));
1106 WMAddPopUpButtonItem(panel->pagePopUp, _("Advanced Options"));
1107 WMAddPopUpButtonItem(panel->pagePopUp, _("Icon and Initial Workspace"));
1108 WMAddPopUpButtonItem(panel->pagePopUp, _("Application Specific"));
1110 /**** window spec ****/
1111 frame_width = PWIDTH - (2 * 15);
1113 panel->specFrm = WMCreateFrame(panel->win);
1114 WMSetFrameTitle(panel->specFrm, _("Window Specification"));
1115 WMMoveWidget(panel->specFrm, 15, 65);
1116 WMResizeWidget(panel->specFrm, frame_width, 145);
1118 panel->defaultRb = WMCreateRadioButton(panel->specFrm);
1119 WMMoveWidget(panel->defaultRb, 10, 78);
1120 WMResizeWidget(panel->defaultRb, frame_width - (2 * 10), 20);
1121 WMSetButtonText(panel->defaultRb, _("Defaults for all windows"));
1122 WMSetButtonSelected(panel->defaultRb, False);
1123 WMSetButtonAction(panel->defaultRb, selectSpecification, panel);
1125 if (wwin->wm_class && wwin->wm_instance) {
1126 char *str, *tmp;
1128 tmp = wstrconcat(wwin->wm_instance, ".");
1129 str = wstrconcat(tmp, wwin->wm_class);
1131 panel->bothRb = WMCreateRadioButton(panel->specFrm);
1132 WMMoveWidget(panel->bothRb, 10, 18);
1133 WMResizeWidget(panel->bothRb, frame_width - (2 * 10), 20);
1134 WMSetButtonText(panel->bothRb, str);
1135 wfree(tmp);
1136 wfree(str);
1137 WMGroupButtons(panel->defaultRb, panel->bothRb);
1139 if (!selectedBtn)
1140 selectedBtn = panel->bothRb;
1142 WMSetButtonAction(panel->bothRb, selectSpecification, panel);
1145 if (wwin->wm_instance) {
1146 panel->instRb = WMCreateRadioButton(panel->specFrm);
1147 WMMoveWidget(panel->instRb, 10, 38);
1148 WMResizeWidget(panel->instRb, frame_width - (2 * 10), 20);
1149 WMSetButtonText(panel->instRb, wwin->wm_instance);
1150 WMGroupButtons(panel->defaultRb, panel->instRb);
1152 if (!selectedBtn)
1153 selectedBtn = panel->instRb;
1155 WMSetButtonAction(panel->instRb, selectSpecification, panel);
1158 if (wwin->wm_class) {
1159 panel->clsRb = WMCreateRadioButton(panel->specFrm);
1160 WMMoveWidget(panel->clsRb, 10, 58);
1161 WMResizeWidget(panel->clsRb, frame_width - (2 * 10), 20);
1162 WMSetButtonText(panel->clsRb, wwin->wm_class);
1163 WMGroupButtons(panel->defaultRb, panel->clsRb);
1165 if (!selectedBtn)
1166 selectedBtn = panel->clsRb;
1168 WMSetButtonAction(panel->clsRb, selectSpecification, panel);
1171 panel->selWinB = WMCreateCommandButton(panel->specFrm);
1172 WMMoveWidget(panel->selWinB, 20, 145 - 24 - 10);
1173 WMResizeWidget(panel->selWinB, frame_width - 2 * 10 - 20, 24);
1174 WMSetButtonText(panel->selWinB, _("Select window"));
1175 WMSetButtonAction(panel->selWinB, selectWindow, panel);
1177 panel->specLbl = WMCreateLabel(panel->win);
1178 WMMoveWidget(panel->specLbl, 15, 210);
1179 WMResizeWidget(panel->specLbl, frame_width, 100);
1180 WMSetLabelText(panel->specLbl, spec_text);
1181 WMSetLabelWraps(panel->specLbl, True);
1183 WMSetLabelTextAlignment(panel->specLbl, WALeft);
1185 /**** attributes ****/
1186 panel->attrFrm = WMCreateFrame(panel->win);
1187 WMSetFrameTitle(panel->attrFrm, _("Attributes"));
1188 WMMoveWidget(panel->attrFrm, 15, 45);
1189 WMResizeWidget(panel->attrFrm, frame_width, 250);
1191 for (i = 0; i < (sizeof(panel->attrChk) / sizeof(panel->attrChk[0])); i++) {
1192 char *caption = NULL;
1193 int flag = 0;
1194 char *descr = NULL;
1196 switch (i) {
1197 case 0:
1198 caption = _("Disable titlebar");
1199 flag = WFLAGP(wwin, no_titlebar);
1200 descr = _("Remove the titlebar of this window.\n"
1201 "To access the window commands menu of a window\n"
1202 "without it's titlebar, press Control+Esc (or the\n"
1203 "equivalent shortcut, if you changed the default\n" "settings).");
1204 break;
1205 case 1:
1206 caption = _("Disable resizebar");
1207 flag = WFLAGP(wwin, no_resizebar);
1208 descr = _("Remove the resizebar of this window.");
1209 break;
1210 case 2:
1211 caption = _("Disable close button");
1212 flag = WFLAGP(wwin, no_close_button);
1213 descr = _("Remove the `close window' button of this window.");
1214 break;
1215 case 3:
1216 caption = _("Disable miniaturize button");
1217 flag = WFLAGP(wwin, no_miniaturize_button);
1218 descr = _("Remove the `miniaturize window' button of the window.");
1219 break;
1220 case 4:
1221 caption = _("Disable border");
1222 flag = WFLAGP(wwin, no_border);
1223 descr = _("Remove the 1 pixel black border around the window.");
1224 break;
1225 case 5:
1226 caption = _("Keep on top (floating)");
1227 flag = WFLAGP(wwin, floating);
1228 descr = _("Keep the window over other windows, not allowing\n" "them to cover it.");
1229 break;
1230 case 6:
1231 caption = _("Keep at bottom (sunken)");
1232 flag = WFLAGP(wwin, sunken);
1233 descr = _("Keep the window under all other windows.");
1234 break;
1235 case 7:
1236 caption = _("Omnipresent");
1237 flag = WFLAGP(wwin, omnipresent);
1238 descr = _("Make window present in all workspaces.");
1239 break;
1240 case 8:
1241 caption = _("Start miniaturized");
1242 flag = WFLAGP(wwin, start_miniaturized);
1243 descr = _("Make the window be automatically miniaturized when it's\n" "first shown.");
1244 break;
1245 case 9:
1246 caption = _("Start maximized");
1247 flag = WFLAGP(wwin, start_maximized != 0);
1248 descr = _("Make the window be automatically maximized when it's\n" "first shown.");
1249 break;
1250 case 10:
1251 caption = _("Full screen maximization");
1252 flag = WFLAGP(wwin, full_maximize);
1253 descr = _("Make the window use the whole screen space when it's\n"
1254 "maximized. The titlebar and resizebar will be moved\n"
1255 "to outside the screen.");
1256 break;
1258 panel->attrChk[i] = WMCreateSwitchButton(panel->attrFrm);
1259 WMMoveWidget(panel->attrChk[i], 10, 20 * (i + 1));
1260 WMResizeWidget(panel->attrChk[i], frame_width - 15, 20);
1261 WMSetButtonSelected(panel->attrChk[i], flag);
1262 WMSetButtonText(panel->attrChk[i], caption);
1264 WMSetBalloonTextForView(descr, WMWidgetView(panel->attrChk[i]));
1267 /**** more attributes ****/
1268 panel->moreFrm = WMCreateFrame(panel->win);
1269 WMSetFrameTitle(panel->moreFrm, _("Advanced"));
1270 WMMoveWidget(panel->moreFrm, 15, 45);
1271 WMResizeWidget(panel->moreFrm, frame_width, 265);
1273 for (i = 0; i < (sizeof(panel->moreChk) / sizeof(panel->moreChk[0])); i++) {
1274 char *caption = NULL;
1275 int flag = 0;
1276 char *descr = NULL;
1278 switch (i) {
1279 case 0:
1280 caption = _("Do not bind keyboard shortcuts");
1281 flag = WFLAGP(wwin, no_bind_keys);
1282 descr = _("Do not bind keyboard shortcuts from Window Maker\n"
1283 "when this window is focused. This will allow the\n"
1284 "window to receive all key combinations regardless\n"
1285 "of your shortcut configuration.");
1286 break;
1287 case 1:
1288 caption = _("Do not bind mouse clicks");
1289 flag = WFLAGP(wwin, no_bind_mouse);
1290 descr = _("Do not bind mouse actions, such as `Alt'+drag\n"
1291 "in the window (when alt is the modifier you have\n" "configured).");
1292 break;
1293 case 2:
1294 caption = _("Do not show in the window list");
1295 flag = WFLAGP(wwin, skip_window_list);
1296 descr = _("Do not list the window in the window list menu.");
1297 break;
1298 case 3:
1299 caption = _("Do not show in the switch panel");
1300 flag = WFLAGP(wwin, skip_switchpanel);
1301 descr = _("Do not include in switchpanel while alternating windows.");
1302 break;
1303 case 4:
1304 caption = _("Do not let it take focus");
1305 flag = WFLAGP(wwin, no_focusable);
1306 descr = _("Do not let the window take keyboard focus when you\n" "click on it.");
1307 break;
1308 case 5:
1309 caption = _("Keep inside screen");
1310 flag = WFLAGP(wwin, dont_move_off);
1311 descr = _("Do not allow the window to move itself completely\n"
1312 "outside the screen. For bug compatibility.\n");
1313 break;
1314 case 6:
1315 caption = _("Ignore 'Hide Others'");
1316 flag = WFLAGP(wwin, no_hide_others);
1317 descr = _("Do not hide the window when issuing the\n" "`HideOthers' command.");
1318 break;
1319 case 7:
1320 caption = _("Ignore 'Save Session'");
1321 flag = WFLAGP(wwin, dont_save_session);
1322 descr = _("Do not save the associated application in the\n"
1323 "session's state, so that it won't be restarted\n"
1324 "together with other applications when Window Maker\n" "starts.");
1325 break;
1326 case 8:
1327 caption = _("Emulate application icon");
1328 flag = WFLAGP(wwin, emulate_appicon);
1329 descr = _("Make this window act as an application that provides\n"
1330 "enough information to Window Maker for a dockable\n"
1331 "application icon to be created.");
1332 break;
1333 case 9:
1334 caption = _("Focus across workspaces");
1335 flag = WFLAGP(wwin, focus_across_wksp);
1336 descr = _("Allow Window Maker to switch workspace to satisfy\n"
1337 "a focus request (annoying).");
1338 break;
1339 case 10:
1340 caption = _("Do not let it be minimized");
1341 flag = WFLAGP(wwin, no_miniaturizable);
1342 descr = _("Do not let the window of this application be\n"
1343 "minimized.\n");
1344 break;
1345 #ifdef XKB_BUTTON_HINT
1346 case 11:
1347 caption = _("Disable language button");
1348 flag = WFLAGP(wwin, no_language_button);
1349 descr = _("Remove the `toggle language' button of the window.");
1350 break;
1351 #endif
1353 panel->moreChk[i] = WMCreateSwitchButton(panel->moreFrm);
1354 WMMoveWidget(panel->moreChk[i], 10, 20 * (i + 1));
1355 WMResizeWidget(panel->moreChk[i], frame_width - 15, 20);
1356 WMSetButtonSelected(panel->moreChk[i], flag);
1357 WMSetButtonText(panel->moreChk[i], caption);
1359 WMSetBalloonTextForView(descr, WMWidgetView(panel->moreChk[i]));
1362 /* miniwindow/workspace */
1363 panel->iconFrm = WMCreateFrame(panel->win);
1364 WMMoveWidget(panel->iconFrm, 15, 50);
1365 WMResizeWidget(panel->iconFrm, PWIDTH - (2 * 15), 170);
1366 WMSetFrameTitle(panel->iconFrm, _("Miniwindow Image"));
1368 panel->iconLbl = WMCreateLabel(panel->iconFrm);
1369 WMMoveWidget(panel->iconLbl, PWIDTH - (2 * 15) - 22 - 64, 20);
1370 WMResizeWidget(panel->iconLbl, 64, 64);
1371 WMSetLabelRelief(panel->iconLbl, WRGroove);
1372 WMSetLabelImagePosition(panel->iconLbl, WIPImageOnly);
1374 panel->browseIconBtn = WMCreateCommandButton(panel->iconFrm);
1375 WMSetButtonAction(panel->browseIconBtn, chooseIconCallback, panel);
1376 WMMoveWidget(panel->browseIconBtn, 22, 32);
1377 WMResizeWidget(panel->browseIconBtn, 120, 26);
1378 WMSetButtonText(panel->browseIconBtn, _("Browse..."));
1380 #ifdef wrong_behaviour
1381 WMSetButtonImagePosition(panel->updateIconBtn, WIPRight);
1382 pixmap = WMGetSystemPixmap(scr->wmscreen, WSIReturnArrow);
1383 WMSetButtonImage(panel->updateIconBtn, pixmap);
1384 WMReleasePixmap(pixmap);
1385 pixmap = WMGetSystemPixmap(scr->wmscreen, WSIHighlightedReturnArrow);
1386 WMSetButtonAltImage(panel->updateIconBtn, pixmap);
1387 WMReleasePixmap(pixmap);
1388 #endif
1390 panel->fileLbl = WMCreateLabel(panel->iconFrm);
1391 WMMoveWidget(panel->fileLbl, 20, 85);
1392 WMResizeWidget(panel->fileLbl, PWIDTH - (2 * 15) - (2 * 20), 14);
1393 WMSetLabelText(panel->fileLbl, _("Icon filename:"));
1395 panel->fileText = WMCreateTextField(panel->iconFrm);
1396 WMMoveWidget(panel->fileText, 20, 105);
1397 WMResizeWidget(panel->fileText, PWIDTH - (2 * 20) - (2 * 15), 20);
1398 WMSetTextFieldText(panel->fileText, NULL);
1399 WMAddNotificationObserver(textEditedObserver, panel, WMTextDidEndEditingNotification, panel->fileText);
1401 panel->alwChk = WMCreateSwitchButton(panel->iconFrm);
1402 WMMoveWidget(panel->alwChk, 20, 130);
1403 WMResizeWidget(panel->alwChk, PWIDTH - (2 * 15) - (2 * 15), 30);
1404 WMSetButtonText(panel->alwChk, _("Ignore client supplied icon"));
1405 WMSetButtonSelected(panel->alwChk, WFLAGP(wwin, always_user_icon));
1407 panel->wsFrm = WMCreateFrame(panel->win);
1408 WMMoveWidget(panel->wsFrm, 15, 225);
1409 WMResizeWidget(panel->wsFrm, PWIDTH - (2 * 15), 70);
1410 WMSetFrameTitle(panel->wsFrm, _("Initial Workspace"));
1412 WMSetBalloonTextForView(_("The workspace to place the window when it's"
1413 "first shown."), WMWidgetView(panel->wsFrm));
1415 panel->wsP = WMCreatePopUpButton(panel->wsFrm);
1416 WMMoveWidget(panel->wsP, 20, 30);
1417 WMResizeWidget(panel->wsP, PWIDTH - (2 * 15) - (2 * 20), 20);
1418 WMAddPopUpButtonItem(panel->wsP, _("Nowhere in particular"));
1420 for (i = 0; i < wwin->screen_ptr->workspace_count; i++)
1421 WMAddPopUpButtonItem(panel->wsP, scr->workspaces[i]->name);
1423 i = wDefaultGetStartWorkspace(wwin->screen_ptr, wwin->wm_instance, wwin->wm_class);
1424 if (i >= 0 && i <= wwin->screen_ptr->workspace_count)
1425 WMSetPopUpButtonSelectedItem(panel->wsP, i + 1);
1426 else
1427 WMSetPopUpButtonSelectedItem(panel->wsP, 0);
1429 /* application wide attributes */
1430 if (wwin->main_window != None) {
1431 WApplication *wapp = wApplicationOf(wwin->main_window);
1433 panel->appFrm = WMCreateFrame(panel->win);
1434 WMSetFrameTitle(panel->appFrm, _("Application Attributes"));
1435 WMMoveWidget(panel->appFrm, 15, 50);
1436 WMResizeWidget(panel->appFrm, frame_width, 240);
1438 for (i = 0; i < (sizeof(panel->appChk) / sizeof(panel->appChk[0])); i++) {
1439 char *caption = NULL;
1440 int flag = 0;
1441 char *descr = NULL;
1443 switch (i) {
1444 case 0:
1445 caption = _("Start hidden");
1446 flag = WFLAGP(wapp->main_window_desc, start_hidden);
1447 descr = _("Automatically hide application when it's started.");
1448 break;
1449 case 1:
1450 caption = _("No application icon");
1451 flag = WFLAGP(wapp->main_window_desc, no_appicon);
1452 descr = _("Disable the application icon for the application.\n"
1453 "Note that you won't be able to dock it anymore,\n"
1454 "and any icons that are already docked will stop\n"
1455 "working correctly.");
1456 break;
1457 case 2:
1458 caption = _("Shared application icon");
1459 flag = WFLAGP(wapp->main_window_desc, shared_appicon);
1460 descr = _("Use a single shared application icon for all of\n"
1461 "the instances of this application.\n");
1462 break;
1464 panel->appChk[i] = WMCreateSwitchButton(panel->appFrm);
1465 WMMoveWidget(panel->appChk[i], 10, 20 * (i + 1));
1466 WMResizeWidget(panel->appChk[i], 205, 20);
1467 WMSetButtonSelected(panel->appChk[i], flag);
1468 WMSetButtonText(panel->appChk[i], caption);
1469 WMSetBalloonTextForView(descr, WMWidgetView(panel->appChk[i]));
1472 if (WFLAGP(wwin, emulate_appicon)) {
1473 WMSetButtonEnabled(panel->appChk[1], False);
1474 WMSetButtonEnabled(panel->moreChk[7], True);
1475 } else {
1476 WMSetButtonEnabled(panel->appChk[1], True);
1477 WMSetButtonEnabled(panel->moreChk[7], False);
1479 } else {
1480 int tmp;
1482 if ((wwin->transient_for != None && wwin->transient_for != scr->root_win)
1483 || !wwin->wm_class || !wwin->wm_instance)
1484 tmp = False;
1485 else
1486 tmp = True;
1487 WMSetButtonEnabled(panel->moreChk[7], tmp);
1489 WMSetPopUpButtonItemEnabled(panel->pagePopUp, 4, False);
1490 panel->appFrm = NULL;
1493 /* if the window is a transient, don't let it have a miniaturize
1494 * button */
1495 if (wwin->transient_for != None && wwin->transient_for != scr->root_win)
1496 WMSetButtonEnabled(panel->attrChk[3], False);
1497 else
1498 WMSetButtonEnabled(panel->attrChk[3], True);
1500 if (!wwin->wm_class && !wwin->wm_instance) {
1501 WMSetPopUpButtonItemEnabled(panel->pagePopUp, 0, False);
1504 WMRealizeWidget(panel->win);
1506 WMMapSubwidgets(panel->win);
1507 WMMapSubwidgets(panel->specFrm);
1508 WMMapSubwidgets(panel->attrFrm);
1509 WMMapSubwidgets(panel->moreFrm);
1510 WMMapSubwidgets(panel->iconFrm);
1511 WMMapSubwidgets(panel->wsFrm);
1512 if (panel->appFrm)
1513 WMMapSubwidgets(panel->appFrm);
1515 if (showSelectPanel) {
1516 WMSetPopUpButtonSelectedItem(panel->pagePopUp, 0);
1517 changePage(panel->pagePopUp, panel);
1518 } else {
1519 WMSetPopUpButtonSelectedItem(panel->pagePopUp, 1);
1520 changePage(panel->pagePopUp, panel);
1523 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, PWIDTH, PHEIGHT, 0, 0, 0);
1524 XSelectInput(dpy, parent, KeyPressMask | KeyReleaseMask);
1525 panel->parent = parent;
1526 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
1528 WMMapWidget(panel->win);
1530 XSetTransientForHint(dpy, parent, wwin->client_win);
1532 if (xpos == UNDEFINED_POS) {
1533 x = wwin->frame_x + wwin->frame->core->width / 2;
1534 y = wwin->frame_y + wwin->frame->top_width * 2;
1535 if (y + PHEIGHT > scr->scr_height)
1536 y = scr->scr_height - PHEIGHT - 30;
1537 if (x + PWIDTH > scr->scr_width)
1538 x = scr->scr_width - PWIDTH;
1539 } else {
1540 x = xpos;
1541 y = ypos;
1544 panel->frame = wManageInternalWindow(scr, parent, wwin->client_win, "Inspector", x, y, PWIDTH, PHEIGHT);
1546 if (!selectedBtn)
1547 selectedBtn = panel->defaultRb;
1549 WMSetButtonSelected(selectedBtn, True);
1551 selectSpecification(selectedBtn, panel);
1553 /* kluge to know who should get the key events */
1554 panel->frame->client_leader = WMWidgetXID(panel->win);
1556 WSETUFLAG(panel->frame, no_closable, 0);
1557 WSETUFLAG(panel->frame, no_close_button, 0);
1558 wWindowUpdateButtonImages(panel->frame);
1559 wFrameWindowShowButton(panel->frame->frame, WFF_RIGHT_BUTTON);
1560 panel->frame->frame->on_click_right = destroyInspector;
1562 wWindowMap(panel->frame);
1564 showIconFor(WMWidgetScreen(panel->alwChk), panel, wwin->wm_instance, wwin->wm_class, UPDATE_TEXT_FIELD);
1566 return panel;
1569 void wShowInspectorForWindow(WWindow *wwin)
1571 if (wwin->flags.inspector_open)
1572 return;
1574 WMSetBalloonEnabled(wwin->screen_ptr->wmscreen, wPreferences.help_balloon);
1576 make_keys();
1577 wwin->flags.inspector_open = 1;
1578 wwin->inspector = createInspectorForWindow(wwin, UNDEFINED_POS, UNDEFINED_POS, False);
1581 void wHideInspectorForWindow(WWindow *wwin)
1583 WWindow *pwin = wwin->inspector->frame;
1585 wWindowUnmap(pwin);
1586 pwin->flags.hidden = 1;
1588 wClientSetState(pwin, IconicState, None);
1591 void wUnhideInspectorForWindow(WWindow *wwin)
1593 WWindow *pwin = wwin->inspector->frame;
1595 pwin->flags.hidden = 0;
1596 pwin->flags.mapped = 1;
1597 XMapWindow(dpy, pwin->client_win);
1598 XMapWindow(dpy, pwin->frame->core->window);
1599 wClientSetState(pwin, NormalState, None);
1602 WWindow *wGetWindowOfInspectorForWindow(WWindow *wwin)
1604 if (wwin->inspector) {
1605 assert(wwin->flags.inspector_open != 0);
1607 return wwin->inspector->frame;
1608 } else
1609 return NULL;
1612 void wCloseInspectorForWindow(WWindow *wwin)
1614 WWindow *pwin = wwin->inspector->frame; /* the inspector window */
1616 (*pwin->frame->on_click_right) (NULL, pwin, NULL);