WPrefs: Disable compilation for code that is 'not_yet_fully_implemented'
[wmaker-crm.git] / src / winspector.c
blobbd56415549d1c8a4d4aa3e2424eddf80939dd583
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 "defaults.h"
39 #include "dialog.h"
40 #include "icon.h"
41 #include "stacking.h"
42 #include "application.h"
43 #include "appicon.h"
44 #include "actions.h"
45 #include "winspector.h"
46 #include "dock.h"
47 #include "client.h"
48 #include "wmspec.h"
49 #include "misc.h"
50 #include "switchmenu.h"
52 #include <WINGs/WUtil.h>
54 #define USE_TEXT_FIELD 1
55 #define UPDATE_TEXT_FIELD 2
56 #define REVERT_TO_DEFAULT 4
57 #define PWIDTH 290
58 #define PHEIGHT 360
59 #define UNDEFINED_POS 0xffffff
60 #define UPDATE_DEFAULTS 1
61 #define IS_BOOLEAN 2
63 typedef struct InspectorPanel {
64 struct InspectorPanel *nextPtr;
66 WWindow *frame;
67 WWindow *inspected; /* the window that's being inspected */
68 WMWindow *win;
69 Window parent;
71 /* common stuff */
72 WMButton *revertBtn;
73 WMButton *applyBtn;
74 WMButton *saveBtn;
75 WMPopUpButton *pagePopUp;
77 /* first page. general stuff */
78 WMFrame *specFrm;
79 WMButton *instRb;
80 WMButton *clsRb;
81 WMButton *bothRb;
82 WMButton *defaultRb;
83 WMButton *selWinB;
84 WMLabel *specLbl;
86 /* second page. attributes */
87 WMFrame *attrFrm;
88 WMButton *attrChk[11];
90 /* 3rd page. more attributes */
91 WMFrame *moreFrm;
92 #ifdef XKB_BUTTON_HINT
93 WMButton *moreChk[12];
94 #else
95 WMButton *moreChk[11];
96 #endif
98 /* 4th page. icon and workspace */
99 WMFrame *iconFrm;
100 WMLabel *iconLbl;
101 WMLabel *fileLbl;
102 WMTextField *fileText;
103 WMButton *alwChk;
104 WMButton *browseIconBtn;
105 WMFrame *wsFrm;
106 WMPopUpButton *wsP;
108 /* 5th page. application wide attributes */
109 WMFrame *appFrm;
110 WMButton *appChk[3];
112 unsigned int done:1;
113 unsigned int destroyed:1;
114 unsigned int choosingIcon:1;
115 } InspectorPanel;
117 static InspectorPanel *panelList = NULL;
118 static WMPropList *ANoTitlebar = NULL;
119 static WMPropList *ANoResizebar;
120 static WMPropList *ANoMiniaturizeButton;
121 static WMPropList *ANoCloseButton;
122 static WMPropList *ANoBorder;
123 static WMPropList *ANoHideOthers;
124 static WMPropList *ANoMouseBindings;
125 static WMPropList *ANoKeyBindings;
126 static WMPropList *ANoAppIcon;
127 static WMPropList *AKeepOnTop;
128 static WMPropList *AKeepOnBottom;
129 static WMPropList *AOmnipresent;
130 static WMPropList *ASkipWindowList;
131 static WMPropList *ASkipSwitchPanel;
132 static WMPropList *AKeepInsideScreen;
133 static WMPropList *AUnfocusable;
134 static WMPropList *AFocusAcrossWorkspace;
135 static WMPropList *AAlwaysUserIcon;
136 static WMPropList *AStartMiniaturized;
137 static WMPropList *AStartMaximized;
138 static WMPropList *ADontSaveSession;
139 static WMPropList *AEmulateAppIcon;
140 static WMPropList *AFullMaximize;
141 static WMPropList *ASharedAppIcon;
142 static WMPropList *ANoMiniaturizable;
143 #ifdef XKB_BUTTON_HINT
144 static WMPropList *ANoLanguageButton;
145 #endif
146 static WMPropList *AStartWorkspace;
147 static WMPropList *AIcon;
149 /* application wide options */
150 static WMPropList *AStartHidden;
151 static WMPropList *AnyWindow;
152 static WMPropList *EmptyString;
153 static WMPropList *Yes, *No;
155 static char *spec_text;
156 static void applySettings(WMWidget *button, void *panel);
158 static InspectorPanel *createInspectorForWindow(WWindow *wwin, int xpos, int ypos, Bool showSelectPanel);
160 static void create_tab_window_attributes(WWindow *wwin, InspectorPanel *panel, int frame_width);
161 static void create_tab_window_advanced(WWindow *wwin, InspectorPanel *panel, int frame_width);
162 static void create_tab_icon_workspace(WWindow *wwin, InspectorPanel *panel);
163 static void create_tab_app_specific(WWindow *wwin, InspectorPanel *panel, int frame_width);
165 static void make_keys(void)
167 if (ANoTitlebar != NULL)
168 return;
170 AIcon = WMCreatePLString("Icon");
171 ANoTitlebar = WMCreatePLString("NoTitlebar");
172 ANoResizebar = WMCreatePLString("NoResizebar");
173 ANoMiniaturizeButton = WMCreatePLString("NoMiniaturizeButton");
174 ANoCloseButton = WMCreatePLString("NoCloseButton");
175 ANoBorder = WMCreatePLString("NoBorder");
176 ANoHideOthers = WMCreatePLString("NoHideOthers");
177 ANoMouseBindings = WMCreatePLString("NoMouseBindings");
178 ANoKeyBindings = WMCreatePLString("NoKeyBindings");
179 ANoAppIcon = WMCreatePLString("NoAppIcon");
180 AKeepOnTop = WMCreatePLString("KeepOnTop");
181 AKeepOnBottom = WMCreatePLString("KeepOnBottom");
182 AOmnipresent = WMCreatePLString("Omnipresent");
183 ASkipWindowList = WMCreatePLString("SkipWindowList");
184 ASkipSwitchPanel = WMCreatePLString("SkipSwitchPanel");
185 AKeepInsideScreen = WMCreatePLString("KeepInsideScreen");
186 AUnfocusable = WMCreatePLString("Unfocusable");
187 AFocusAcrossWorkspace = WMCreatePLString("FocusAcrossWorkspace");
188 AAlwaysUserIcon = WMCreatePLString("AlwaysUserIcon");
189 AStartMiniaturized = WMCreatePLString("StartMiniaturized");
190 AStartMaximized = WMCreatePLString("StartMaximized");
191 AStartHidden = WMCreatePLString("StartHidden");
192 ADontSaveSession = WMCreatePLString("DontSaveSession");
193 AEmulateAppIcon = WMCreatePLString("EmulateAppIcon");
194 AFullMaximize = WMCreatePLString("FullMaximize");
195 ASharedAppIcon = WMCreatePLString("SharedAppIcon");
196 ANoMiniaturizable = WMCreatePLString("NoMiniaturizable");
197 #ifdef XKB_BUTTON_HINT
198 ANoLanguageButton = WMCreatePLString("NoLanguageButton");
199 #endif
201 AStartWorkspace = WMCreatePLString("StartWorkspace");
203 AnyWindow = WMCreatePLString("*");
204 EmptyString = WMCreatePLString("");
205 Yes = WMCreatePLString("Yes");
206 No = WMCreatePLString("No");
209 static void freeInspector(InspectorPanel *panel)
211 panel->destroyed = 1;
213 if (panel->choosingIcon)
214 return;
216 WMDestroyWidget(panel->win);
217 XDestroyWindow(dpy, panel->parent);
218 wfree(panel);
221 static void destroyInspector(WCoreWindow *foo, void *data, XEvent *event)
223 InspectorPanel *panel, *tmp;
225 /* Parameter not used, but tell the compiler that it is ok */
226 (void) foo;
227 (void) event;
229 panel = panelList;
230 while (panel->frame != data)
231 panel = panel->nextPtr;
233 if (panelList == panel) {
234 panelList = panel->nextPtr;
235 } else {
236 tmp = panelList;
237 while (tmp->nextPtr != panel)
238 tmp = tmp->nextPtr;
240 tmp->nextPtr = panel->nextPtr;
242 panel->inspected->flags.inspector_open = 0;
243 panel->inspected->inspector = NULL;
245 WMRemoveNotificationObserver(panel);
247 wWindowUnmap(panel->frame);
248 wUnmanageWindow(panel->frame, True, False);
250 freeInspector(panel);
253 void wDestroyInspectorPanels(void)
255 InspectorPanel *panel;
257 while (panelList != NULL) {
258 panel = panelList;
259 panelList = panelList->nextPtr;
260 wUnmanageWindow(panel->frame, False, False);
261 WMDestroyWidget(panel->win);
263 panel->inspected->flags.inspector_open = 0;
264 panel->inspected->inspector = NULL;
266 wfree(panel);
270 static void changePage(WMWidget *bPtr, void *client_data)
272 InspectorPanel *panel = (InspectorPanel *) client_data;
273 int page;
275 page = WMGetPopUpButtonSelectedItem(bPtr);
277 if (page == 0) {
278 WMMapWidget(panel->specFrm);
279 WMMapWidget(panel->specLbl);
280 } else if (page == 1) {
281 WMMapWidget(panel->attrFrm);
282 } else if (page == 2) {
283 WMMapWidget(panel->moreFrm);
284 } else if (page == 3) {
285 WMMapWidget(panel->iconFrm);
286 WMMapWidget(panel->wsFrm);
287 } else {
288 WMMapWidget(panel->appFrm);
291 if (page != 0) {
292 WMUnmapWidget(panel->specFrm);
293 WMUnmapWidget(panel->specLbl);
295 if (page != 1)
296 WMUnmapWidget(panel->attrFrm);
297 if (page != 2)
298 WMUnmapWidget(panel->moreFrm);
299 if (page != 3) {
300 WMUnmapWidget(panel->iconFrm);
301 WMUnmapWidget(panel->wsFrm);
303 if (page != 4 && panel->appFrm)
304 WMUnmapWidget(panel->appFrm);
307 static int showIconFor(WMScreen *scrPtr, InspectorPanel *panel, const char *wm_instance, const char *wm_class, int flags)
309 WMPixmap *pixmap = (WMPixmap *) NULL;
310 char *file = NULL, *path = NULL, *db_icon = NULL;
312 if ((flags & USE_TEXT_FIELD) != 0) {
313 file = WMGetTextFieldText(panel->fileText);
314 if (file && file[0] == 0) {
315 wfree(file);
316 file = NULL;
318 } else {
319 /* Get the application icon, default NOT included */
320 db_icon = wDefaultGetIconFile(wm_instance, wm_class, False);
321 if (db_icon != NULL)
322 file = wstrdup(db_icon);
324 if (db_icon != NULL && (flags & REVERT_TO_DEFAULT) != 0) {
325 if (file)
326 file = wstrdup(db_icon);
327 flags |= UPDATE_TEXT_FIELD;
330 if ((flags & UPDATE_TEXT_FIELD) != 0)
331 WMSetTextFieldText(panel->fileText, file);
333 if (file) {
334 path = FindImage(wPreferences.icon_path, file);
336 if (!path) {
337 char *buf;
338 int len = strlen(file) + 80;
340 buf = wmalloc(len);
341 snprintf(buf, len, _("Could not find icon \"%s\" specified for this window"), file);
342 wMessageDialog(panel->frame->screen_ptr, _("Error"), buf, _("OK"), NULL, NULL);
343 wfree(buf);
344 wfree(file);
345 return -1;
348 pixmap = WMCreatePixmapFromFile(scrPtr, path);
349 wfree(path);
351 if (!pixmap) {
352 char *buf;
353 int len = strlen(file) + 80;
355 buf = wmalloc(len);
356 snprintf(buf, len, _("Could not open specified icon \"%s\":%s"),
357 file, RMessageForError(RErrorCode));
358 wMessageDialog(panel->frame->screen_ptr, _("Error"), buf, _("OK"), NULL, NULL);
359 wfree(buf);
360 wfree(file);
361 return -1;
363 wfree(file);
366 WMSetLabelImage(panel->iconLbl, pixmap);
367 if (pixmap)
368 WMReleasePixmap(pixmap);
370 return 0;
373 static int getBool(WMPropList *value)
375 char *val;
377 if (!WMIsPLString(value))
378 return 0;
380 if (!(val = WMGetFromPLString(value)))
381 return 0;
383 if ((val[1] == '\0' &&
384 (val[0] == 'y' || val[0] == 'Y' || val[0] == 'T' ||
385 val[0] == 't' || val[0] == '1')) ||
386 (strcasecmp(val, "YES") == 0 || strcasecmp(val, "TRUE") == 0)) {
387 return 1;
388 } else if ((val[1] == '\0' &&
389 (val[0] == 'n' || val[0] == 'N' || val[0] == 'F' ||
390 val[0] == 'f' || val[0] == '0')) ||
391 (strcasecmp(val, "NO") == 0 || strcasecmp(val, "FALSE") == 0)) {
392 return 0;
393 } else {
394 wwarning(_("can't convert \"%s\" to boolean"), val);
395 return 0;
399 /* Will insert the attribute = value; pair in window's list,
400 * if it's different from the defaults.
401 * Defaults means either defaults database, or attributes saved
402 * for the default window "*". This is to let one revert options that are
403 * global because they were saved for all windows ("*"). */
404 static int
405 insertAttribute(WMPropList *dict, WMPropList *window, WMPropList *attr, WMPropList *value, int flags)
407 WMPropList *def_win, *def_value = NULL;
408 int update = 0, modified = 0;
410 if (!(flags & UPDATE_DEFAULTS) && dict) {
411 if ((def_win = WMGetFromPLDictionary(dict, AnyWindow)) != NULL)
412 def_value = WMGetFromPLDictionary(def_win, attr);
415 /* If we could not find defaults in database, fall to hardcoded values.
416 * Also this is true if we save defaults for all windows */
417 if (!def_value)
418 def_value = ((flags & IS_BOOLEAN) != 0) ? No : EmptyString;
420 if (flags & IS_BOOLEAN)
421 update = (getBool(value) != getBool(def_value));
422 else
423 update = !WMIsPropListEqualTo(value, def_value);
425 if (update) {
426 WMPutInPLDictionary(window, attr, value);
427 modified = 1;
430 return modified;
433 static void saveSettings(WMWidget *button, void *client_data)
435 InspectorPanel *panel = (InspectorPanel *) client_data;
436 WWindow *wwin = panel->inspected;
437 WDDomain *db = w_global.domain.window_attr;
438 WMPropList *dict = NULL;
439 WMPropList *winDic, *appDic, *value, *value1, *key = NULL, *key2;
440 char *icon_file, *buf1, *buf2;
441 int flags = 0, i = 0, different = 0, different2 = 0;
443 /* Save will apply the changes and save them */
444 applySettings(panel->applyBtn, panel);
446 if (WMGetButtonSelected(panel->instRb) != 0) {
447 key = WMCreatePLString(wwin->wm_instance);
448 } else if (WMGetButtonSelected(panel->clsRb) != 0) {
449 key = WMCreatePLString(wwin->wm_class);
450 } else if (WMGetButtonSelected(panel->bothRb) != 0) {
451 buf1 = StrConcatDot(wwin->wm_instance, wwin->wm_class);
452 key = WMCreatePLString(buf1);
453 wfree(buf1);
454 } else if (WMGetButtonSelected(panel->defaultRb) != 0) {
455 key = WMRetainPropList(AnyWindow);
456 flags = UPDATE_DEFAULTS;
459 if (!key)
460 return;
462 dict = db->dictionary;
463 if (!dict) {
464 dict = WMCreatePLDictionary(NULL, NULL);
465 if (dict) {
466 db->dictionary = dict;
467 } else {
468 WMReleasePropList(key);
469 return;
473 if (showIconFor(WMWidgetScreen(button), panel, NULL, NULL, USE_TEXT_FIELD) < 0)
474 return;
476 WMPLSetCaseSensitive(True);
478 winDic = WMCreatePLDictionary(NULL, NULL);
479 appDic = WMCreatePLDictionary(NULL, NULL);
481 /* Save the icon info */
482 /* The flag "Ignore client suplied icon is not selected" */
483 buf1 = wmalloc(4);
484 snprintf(buf1, 4, "%s", (WMGetButtonSelected(panel->alwChk) != 0) ? "Yes" : "No");
485 value1 = WMCreatePLString(buf1);
486 different |= insertAttribute(dict, winDic, AAlwaysUserIcon, value1, flags);
487 WMReleasePropList(value1);
488 wfree(buf1);
490 /* The icon filename (if exists) */
491 icon_file = WMGetTextFieldText(panel->fileText);
492 if ((icon_file) && (icon_file[0] != 0)) {
493 value = WMCreatePLString(icon_file);
494 different |= insertAttribute(dict, winDic, AIcon, value, flags);
495 different2 |= insertAttribute(dict, appDic, AIcon, value, flags);
496 WMReleasePropList(value);
497 wfree(icon_file);
500 i = WMGetPopUpButtonSelectedItem(panel->wsP) - 1;
501 if (i >= 0 && i < w_global.workspace.count) {
502 value = WMCreatePLString(w_global.workspace.array[i]->name);
503 different |= insertAttribute(dict, winDic, AStartWorkspace, value, flags);
504 WMReleasePropList(value);
507 flags |= IS_BOOLEAN;
509 value = (WMGetButtonSelected(panel->attrChk[0]) != 0) ? Yes : No;
510 different |= insertAttribute(dict, winDic, ANoTitlebar, value, flags);
512 value = (WMGetButtonSelected(panel->attrChk[1]) != 0) ? Yes : No;
513 different |= insertAttribute(dict, winDic, ANoResizebar, value, flags);
515 value = (WMGetButtonSelected(panel->attrChk[2]) != 0) ? Yes : No;
516 different |= insertAttribute(dict, winDic, ANoCloseButton, value, flags);
518 value = (WMGetButtonSelected(panel->attrChk[3]) != 0) ? Yes : No;
519 different |= insertAttribute(dict, winDic, ANoMiniaturizeButton, value, flags);
521 value = (WMGetButtonSelected(panel->attrChk[4]) != 0) ? Yes : No;
522 different |= insertAttribute(dict, winDic, ANoBorder, value, flags);
524 value = (WMGetButtonSelected(panel->attrChk[5]) != 0) ? Yes : No;
525 different |= insertAttribute(dict, winDic, AKeepOnTop, value, flags);
527 value = (WMGetButtonSelected(panel->attrChk[6]) != 0) ? Yes : No;
528 different |= insertAttribute(dict, winDic, AKeepOnBottom, value, flags);
530 value = (WMGetButtonSelected(panel->attrChk[7]) != 0) ? Yes : No;
531 different |= insertAttribute(dict, winDic, AOmnipresent, value, flags);
533 value = (WMGetButtonSelected(panel->attrChk[8]) != 0) ? Yes : No;
534 different |= insertAttribute(dict, winDic, AStartMiniaturized, value, flags);
536 value = (WMGetButtonSelected(panel->attrChk[9]) != 0) ? Yes : No;
537 different |= insertAttribute(dict, winDic, AStartMaximized, value, flags);
539 value = (WMGetButtonSelected(panel->attrChk[10]) != 0) ? Yes : No;
540 different |= insertAttribute(dict, winDic, AFullMaximize, value, flags);
542 value = (WMGetButtonSelected(panel->moreChk[0]) != 0) ? Yes : No;
543 different |= insertAttribute(dict, winDic, ANoKeyBindings, value, flags);
545 value = (WMGetButtonSelected(panel->moreChk[1]) != 0) ? Yes : No;
546 different |= insertAttribute(dict, winDic, ANoMouseBindings, value, flags);
548 value = (WMGetButtonSelected(panel->moreChk[2]) != 0) ? Yes : No;
549 different |= insertAttribute(dict, winDic, ASkipWindowList, value, flags);
551 value = (WMGetButtonSelected(panel->moreChk[3]) != 0) ? Yes : No;
552 different |= insertAttribute(dict, winDic, ASkipSwitchPanel, value, flags);
554 value = (WMGetButtonSelected(panel->moreChk[4]) != 0) ? Yes : No;
555 different |= insertAttribute(dict, winDic, AUnfocusable, value, flags);
557 value = (WMGetButtonSelected(panel->moreChk[5]) != 0) ? Yes : No;
558 different |= insertAttribute(dict, winDic, AKeepInsideScreen, value, flags);
560 value = (WMGetButtonSelected(panel->moreChk[6]) != 0) ? Yes : No;
561 different |= insertAttribute(dict, winDic, ANoHideOthers, value, flags);
563 value = (WMGetButtonSelected(panel->moreChk[7]) != 0) ? Yes : No;
564 different |= insertAttribute(dict, winDic, ADontSaveSession, value, flags);
566 value = (WMGetButtonSelected(panel->moreChk[8]) != 0) ? Yes : No;
567 different |= insertAttribute(dict, winDic, AEmulateAppIcon, value, flags);
569 value = (WMGetButtonSelected(panel->moreChk[9]) != 0) ? Yes : No;
570 different |= insertAttribute(dict, winDic, AFocusAcrossWorkspace, value, flags);
572 value = (WMGetButtonSelected(panel->moreChk[10]) != 0) ? Yes : No;
573 different |= insertAttribute(dict, winDic, ANoMiniaturizable, value, flags);
575 #ifdef XKB_BUTTON_HINT
576 value = (WMGetButtonSelected(panel->moreChk[11]) != 0) ? Yes : No;
577 different |= insertAttribute(dict, winDic, ANoLanguageButton, value, flags);
578 #endif
580 if (wwin->main_window != None && wApplicationOf(wwin->main_window) != NULL) {
581 value = (WMGetButtonSelected(panel->appChk[0]) != 0) ? Yes : No;
582 different2 |= insertAttribute(dict, appDic, AStartHidden, value, flags);
584 value = (WMGetButtonSelected(panel->appChk[1]) != 0) ? Yes : No;
585 different2 |= insertAttribute(dict, appDic, ANoAppIcon, value, flags);
587 value = (WMGetButtonSelected(panel->appChk[2]) != 0) ? Yes : No;
588 different2 |= insertAttribute(dict, appDic, ASharedAppIcon, value, flags);
591 if (wwin->fake_group) {
592 key2 = WMCreatePLString(wwin->fake_group->identifier);
593 if (WMIsPropListEqualTo(key, key2)) {
594 WMMergePLDictionaries(winDic, appDic, True);
595 different |= different2;
596 } else {
597 WMRemoveFromPLDictionary(dict, key2);
598 if (different2)
599 WMPutInPLDictionary(dict, key2, appDic);
601 WMReleasePropList(key2);
602 WMReleasePropList(appDic);
603 } else if (wwin->main_window != wwin->client_win) {
604 WApplication *wapp = wApplicationOf(wwin->main_window);
606 if (wapp) {
607 buf2 = StrConcatDot(wapp->main_window_desc->wm_instance,
608 wapp->main_window_desc->wm_class);
609 key2 = WMCreatePLString(buf2);
610 wfree(buf2);
612 if (WMIsPropListEqualTo(key, key2)) {
613 WMMergePLDictionaries(winDic, appDic, True);
614 different |= different2;
615 } else {
616 WMRemoveFromPLDictionary(dict, key2);
617 if (different2)
618 WMPutInPLDictionary(dict, key2, appDic);
620 WMReleasePropList(key2);
621 WMReleasePropList(appDic);
623 } else {
624 WMMergePLDictionaries(winDic, appDic, True);
625 different |= different2;
626 WMReleasePropList(appDic);
629 WMRemoveFromPLDictionary(dict, key);
630 if (different)
631 WMPutInPLDictionary(dict, key, winDic);
633 WMReleasePropList(key);
634 WMReleasePropList(winDic);
636 UpdateDomainFile(db);
638 /* clean up */
639 WMPLSetCaseSensitive(False);
642 static void applySettings(WMWidget *button, void *client_data)
644 InspectorPanel *panel = (InspectorPanel *) client_data;
645 WWindow *wwin = panel->inspected;
646 WApplication *wapp = wApplicationOf(wwin->main_window);
647 int floating, sunken, skip_window_list;
648 int old_omnipresent, old_no_bind_keys, old_no_bind_mouse;
650 old_omnipresent = WFLAGP(wwin, omnipresent);
651 old_no_bind_keys = WFLAGP(wwin, no_bind_keys);
652 old_no_bind_mouse = WFLAGP(wwin, no_bind_mouse);
654 showIconFor(WMWidgetScreen(button), panel, NULL, NULL, USE_TEXT_FIELD);
656 /* Attributes... --> Window Attributes */
657 WSETUFLAG(wwin, no_titlebar, WMGetButtonSelected(panel->attrChk[0]));
658 WSETUFLAG(wwin, no_resizebar, WMGetButtonSelected(panel->attrChk[1]));
659 WSETUFLAG(wwin, no_close_button, WMGetButtonSelected(panel->attrChk[2]));
660 WSETUFLAG(wwin, no_miniaturize_button, WMGetButtonSelected(panel->attrChk[3]));
661 WSETUFLAG(wwin, no_border, WMGetButtonSelected(panel->attrChk[4]));
662 floating = WMGetButtonSelected(panel->attrChk[5]);
663 sunken = WMGetButtonSelected(panel->attrChk[6]);
664 WSETUFLAG(wwin, omnipresent, WMGetButtonSelected(panel->attrChk[7]));
665 WSETUFLAG(wwin, start_miniaturized, WMGetButtonSelected(panel->attrChk[8]));
666 WSETUFLAG(wwin, start_maximized, WMGetButtonSelected(panel->attrChk[9]));
667 WSETUFLAG(wwin, full_maximize, WMGetButtonSelected(panel->attrChk[10]));
669 /* Attributes... --> Advanced Options */
670 WSETUFLAG(wwin, no_bind_keys, WMGetButtonSelected(panel->moreChk[0]));
671 WSETUFLAG(wwin, no_bind_mouse, WMGetButtonSelected(panel->moreChk[1]));
672 skip_window_list = WMGetButtonSelected(panel->moreChk[2]);
673 WSETUFLAG(wwin, skip_switchpanel, WMGetButtonSelected(panel->moreChk[3]));
674 WSETUFLAG(wwin, no_focusable, WMGetButtonSelected(panel->moreChk[4]));
675 WSETUFLAG(wwin, dont_move_off, WMGetButtonSelected(panel->moreChk[5]));
676 WSETUFLAG(wwin, no_hide_others, WMGetButtonSelected(panel->moreChk[6]));
677 WSETUFLAG(wwin, dont_save_session, WMGetButtonSelected(panel->moreChk[7]));
678 WSETUFLAG(wwin, emulate_appicon, WMGetButtonSelected(panel->moreChk[8]));
679 WSETUFLAG(wwin, focus_across_wksp, WMGetButtonSelected(panel->moreChk[9]));
680 WSETUFLAG(wwin, no_miniaturizable, WMGetButtonSelected(panel->moreChk[10]));
681 #ifdef XKB_BUTTON_HINT
682 WSETUFLAG(wwin, no_language_button, WMGetButtonSelected(panel->moreChk[11]));
683 #endif
684 WSETUFLAG(wwin, always_user_icon, WMGetButtonSelected(panel->alwChk));
686 if (WFLAGP(wwin, no_titlebar) && wwin->flags.shaded)
687 wUnshadeWindow(wwin);
689 WSETUFLAG(wwin, no_shadeable, WFLAGP(wwin, no_titlebar));
691 if (floating) {
692 if (!WFLAGP(wwin, floating))
693 ChangeStackingLevel(wwin->frame->core, WMFloatingLevel);
694 } else if (sunken) {
695 if (!WFLAGP(wwin, sunken))
696 ChangeStackingLevel(wwin->frame->core, WMSunkenLevel);
697 } else {
698 if (WFLAGP(wwin, floating) || WFLAGP(wwin, sunken))
699 ChangeStackingLevel(wwin->frame->core, WMNormalLevel);
702 WSETUFLAG(wwin, sunken, sunken);
703 WSETUFLAG(wwin, floating, floating);
704 wwin->flags.omnipresent = 0;
706 if (WFLAGP(wwin, skip_window_list) != skip_window_list) {
707 WSETUFLAG(wwin, skip_window_list, skip_window_list);
708 UpdateSwitchMenu(wwin->screen_ptr, wwin, skip_window_list ? ACTION_REMOVE : ACTION_ADD);
709 } else {
710 if (WFLAGP(wwin, omnipresent) != old_omnipresent)
711 WMPostNotificationName(WMNChangedState, wwin, "omnipresent");
714 if (WFLAGP(wwin, no_bind_keys) != old_no_bind_keys) {
715 if (WFLAGP(wwin, no_bind_keys))
716 XUngrabKey(dpy, AnyKey, AnyModifier, wwin->frame->core->window);
717 else
718 wWindowSetKeyGrabs(wwin);
721 if (WFLAGP(wwin, no_bind_mouse) != old_no_bind_mouse)
722 wWindowResetMouseGrabs(wwin);
724 wwin->frame->flags.need_texture_change = 1;
725 wWindowConfigureBorders(wwin);
726 wFrameWindowPaint(wwin->frame);
727 wNETWMUpdateActions(wwin, False);
729 /* Can't apply emulate_appicon because it will probably cause problems. */
730 if (wapp) {
731 /* do application wide stuff */
732 WSETUFLAG(wapp->main_window_desc, start_hidden, WMGetButtonSelected(panel->appChk[0]));
733 WSETUFLAG(wapp->main_window_desc, no_appicon, WMGetButtonSelected(panel->appChk[1]));
734 WSETUFLAG(wapp->main_window_desc, shared_appicon, WMGetButtonSelected(panel->appChk[2]));
736 if (WFLAGP(wapp->main_window_desc, no_appicon))
737 unpaint_app_icon(wapp);
738 else
739 paint_app_icon(wapp);
741 char *file = WMGetTextFieldText(panel->fileText);
742 if (file[0] == 0) {
743 wfree(file);
744 file = NULL;
747 /* If always_user_icon flag is set, but the user icon is not set
748 * we use client supplied icon and we unset the flag */
749 if ((WFLAGP(wwin, always_user_icon) && (!file))) {
750 /* Show the warning */
751 char *buf;
752 int len = 100;
754 buf = wmalloc(len);
755 snprintf(buf, len, _("Ignore client supplied icon is set, but icon filename textbox is empty. Using client supplied icon"));
756 wMessageDialog(panel->frame->screen_ptr, _("Warning"), buf, _("OK"), NULL, NULL);
757 wfree(buf);
758 wfree(file);
760 /* Change the flags */
761 WSETUFLAG(wwin, always_user_icon, 0);
762 WMSetButtonSelected(panel->alwChk, 0);
765 /* After test the always_user_icon flag value before,
766 * the "else" block is used only if the flag is set and
767 * the icon text box has an icon path */
768 if (!WFLAGP(wwin, always_user_icon)) {
769 /* Change App Icon image, using the icon provided by the client */
770 if (wapp->app_icon) {
771 RImage *image = get_rimage_icon_from_wm_hints(wapp->app_icon->icon);
772 if (image) {
773 set_icon_image_from_image(wapp->app_icon->icon, image);
774 update_icon_pixmap(wapp->app_icon->icon);
775 } else {
776 wIconUpdate(wapp->app_icon->icon);
780 /* Change icon image if the app is minimized,
781 * using the icon provided by the client */
782 if (wwin->icon) {
783 RImage *image = get_rimage_icon_from_wm_hints(wwin->icon);
784 if (image) {
785 set_icon_image_from_image(wwin->icon, image);
786 update_icon_pixmap(wwin->icon);
787 } else {
788 wIconUpdate(wwin->icon);
791 } else {
792 /* Change App Icon image */
793 if (wapp->app_icon)
794 wIconChangeImageFile(wapp->app_icon->icon, file);
796 /* Change icon image if the app is minimized */
797 if (wwin->icon)
798 wIconChangeImageFile(wwin->icon, file);
801 if (file)
802 wfree(file);
805 wNETFrameExtents(wwin);
808 static void revertSettings(WMWidget *button, void *client_data)
810 InspectorPanel *panel = (InspectorPanel *) client_data;
811 WWindow *wwin = panel->inspected;
812 WApplication *wapp = wApplicationOf(wwin->main_window);
813 int i, n, workspace, level;
814 char *wm_instance = NULL, *wm_class = NULL;
816 /* Parameter not used, but tell the compiler that it is ok */
817 (void) button;
819 if (panel->instRb && WMGetButtonSelected(panel->instRb) != 0)
820 wm_instance = wwin->wm_instance;
821 else if (panel->clsRb && WMGetButtonSelected(panel->clsRb) != 0)
822 wm_class = wwin->wm_class;
823 else if (panel->bothRb && WMGetButtonSelected(panel->bothRb) != 0) {
824 wm_instance = wwin->wm_instance;
825 wm_class = wwin->wm_class;
828 memset(&wwin->defined_user_flags, 0, sizeof(WWindowAttributes));
829 memset(&wwin->user_flags, 0, sizeof(WWindowAttributes));
830 memset(&wwin->client_flags, 0, sizeof(WWindowAttributes));
832 wWindowSetupInitialAttributes(wwin, &level, &workspace);
834 for (i = 0; i < (sizeof(panel->attrChk) / sizeof(panel->attrChk[0])); i++) {
835 int flag = 0;
837 switch (i) {
838 case 0:
839 flag = WFLAGP(wwin, no_titlebar);
840 break;
841 case 1:
842 flag = WFLAGP(wwin, no_resizebar);
843 break;
844 case 2:
845 flag = WFLAGP(wwin, no_close_button);
846 break;
847 case 3:
848 flag = WFLAGP(wwin, no_miniaturize_button);
849 break;
850 case 4:
851 flag = WFLAGP(wwin, no_border);
852 break;
853 case 5:
854 flag = WFLAGP(wwin, floating);
855 break;
856 case 6:
857 flag = WFLAGP(wwin, sunken);
858 break;
859 case 7:
860 flag = WFLAGP(wwin, omnipresent);
861 break;
862 case 8:
863 flag = WFLAGP(wwin, start_miniaturized);
864 break;
865 case 9:
866 flag = WFLAGP(wwin, start_maximized != 0);
867 break;
868 case 10:
869 flag = WFLAGP(wwin, full_maximize);
870 break;
872 WMSetButtonSelected(panel->attrChk[i], flag);
875 for (i = 0; i < (sizeof(panel->moreChk) / sizeof(panel->moreChk[0])); i++) {
876 int flag = 0;
878 switch (i) {
879 case 0:
880 flag = WFLAGP(wwin, no_bind_keys);
881 break;
882 case 1:
883 flag = WFLAGP(wwin, no_bind_mouse);
884 break;
885 case 2:
886 flag = WFLAGP(wwin, skip_window_list);
887 break;
888 case 3:
889 flag = WFLAGP(wwin, skip_switchpanel);
890 break;
891 case 4:
892 flag = WFLAGP(wwin, no_focusable);
893 break;
894 case 5:
895 flag = WFLAGP(wwin, dont_move_off);
896 break;
897 case 6:
898 flag = WFLAGP(wwin, no_hide_others);
899 break;
900 case 7:
901 flag = WFLAGP(wwin, dont_save_session);
902 break;
903 case 8:
904 flag = WFLAGP(wwin, emulate_appicon);
905 break;
906 case 9:
907 flag = WFLAGP(wwin, focus_across_wksp);
908 break;
909 case 10:
910 flag = WFLAGP(wwin, no_miniaturizable);
911 break;
912 #ifdef XKB_BUTTON_HINT
913 case 11:
914 flag = WFLAGP(wwin, no_language_button);
915 break;
916 #endif
918 WMSetButtonSelected(panel->moreChk[i], flag);
920 if (panel->appFrm && wapp) {
921 for (i = 0; i < (sizeof(panel->appChk) / sizeof(panel->appChk[0])); i++) {
922 int flag = 0;
924 switch (i) {
925 case 0:
926 flag = WFLAGP(wapp->main_window_desc, start_hidden);
927 break;
928 case 1:
929 flag = WFLAGP(wapp->main_window_desc, no_appicon);
930 break;
931 case 2:
932 flag = WFLAGP(wapp->main_window_desc, shared_appicon);
933 break;
935 WMSetButtonSelected(panel->appChk[i], flag);
938 WMSetButtonSelected(panel->alwChk, WFLAGP(wwin, always_user_icon));
940 showIconFor(WMWidgetScreen(panel->alwChk), panel, wm_instance, wm_class, REVERT_TO_DEFAULT);
942 n = wDefaultGetStartWorkspace(wm_instance, wm_class);
944 if (n >= 0 && n < w_global.workspace.count)
945 WMSetPopUpButtonSelectedItem(panel->wsP, n + 1);
946 else
947 WMSetPopUpButtonSelectedItem(panel->wsP, 0);
949 /* must auto apply, so that there wno't be internal
950 * inconsistencies between the state in the flags and
951 * the actual state of the window */
952 applySettings(panel->applyBtn, panel);
955 static void chooseIconCallback(WMWidget *self, void *clientData)
957 char *file;
958 InspectorPanel *panel = (InspectorPanel *) clientData;
959 int result;
961 panel->choosingIcon = 1;
963 WMSetButtonEnabled(panel->browseIconBtn, False);
965 result = wIconChooserDialog(panel->frame->screen_ptr, &file,
966 panel->inspected->wm_instance,
967 panel->inspected->wm_class);
969 panel->choosingIcon = 0;
971 if (!panel->destroyed) { /* kluge */
972 if (result) {
973 WMSetTextFieldText(panel->fileText, file);
974 showIconFor(WMWidgetScreen(self), panel, NULL, NULL, USE_TEXT_FIELD);
975 wfree(file);
977 WMSetButtonEnabled(panel->browseIconBtn, True);
978 } else {
979 freeInspector(panel);
983 static void textEditedObserver(void *observerData, WMNotification *notification)
985 InspectorPanel *panel = (InspectorPanel *) observerData;
987 if ((long)WMGetNotificationClientData(notification) != WMReturnTextMovement)
988 return;
990 showIconFor(WMWidgetScreen(panel->win), panel, NULL, NULL, USE_TEXT_FIELD);
993 static void selectSpecification(WMWidget *bPtr, void *data)
995 InspectorPanel *panel = (InspectorPanel *) data;
996 char *str;
997 WWindow *wwin = panel->inspected;
998 int len;
1000 if (bPtr == panel->defaultRb && (wwin->wm_instance || wwin->wm_class))
1001 WMSetButtonEnabled(panel->applyBtn, False);
1002 else
1003 WMSetButtonEnabled(panel->applyBtn, True);
1005 len = 16 + strlen(wwin->wm_instance ? wwin->wm_instance : "?")
1006 + strlen(wwin->wm_class ? wwin->wm_class : "?");
1008 str = wmalloc(len);
1010 snprintf(str, len, _("Inspecting %s.%s"),
1011 wwin->wm_instance ? wwin->wm_instance : "?", wwin->wm_class ? wwin->wm_class : "?");
1013 wFrameWindowChangeTitle(panel->frame->frame, str);
1015 wfree(str);
1018 static void selectWindow(WMWidget *bPtr, void *data)
1020 InspectorPanel *panel = (InspectorPanel *) data;
1021 WWindow *wwin = panel->inspected;
1022 WScreen *scr = wwin->screen_ptr;
1023 XEvent event;
1024 WWindow *iwin;
1026 /* Parameter not used, but tell the compiler that it is ok */
1027 (void) bPtr;
1029 if (XGrabPointer(dpy, scr->root_win, True,
1030 ButtonPressMask, GrabModeAsync, GrabModeAsync, None,
1031 wPreferences.cursor[WCUR_SELECT], CurrentTime) != GrabSuccess) {
1032 wwarning("could not grab mouse pointer");
1033 return;
1036 WMSetLabelText(panel->specLbl, _("Click in the window you wish to inspect."));
1037 WMMaskEvent(dpy, ButtonPressMask, &event);
1038 XUngrabPointer(dpy, CurrentTime);
1040 iwin = wWindowFor(event.xbutton.subwindow);
1041 if (iwin && !iwin->flags.internal_window && iwin != wwin && !iwin->flags.inspector_open) {
1042 iwin->flags.inspector_open = 1;
1043 iwin->inspector = createInspectorForWindow(iwin,
1044 panel->frame->frame_x, panel->frame->frame_y, True);
1045 wCloseInspectorForWindow(wwin);
1046 } else {
1047 WMSetLabelText(panel->specLbl, spec_text);
1051 static InspectorPanel *createInspectorForWindow(WWindow *wwin, int xpos, int ypos, Bool showSelectPanel)
1053 WScreen *scr = wwin->screen_ptr;
1054 InspectorPanel *panel;
1055 Window parent;
1056 char *str = NULL, *tmp = NULL;
1057 int x, y, btn_width, frame_width;
1058 WMButton *selectedBtn = NULL;
1060 spec_text = _("The configuration will apply to all\n"
1061 "windows that have their WM_CLASS\n"
1062 "property set to the above selected\n" "name, when saved.");
1064 panel = wmalloc(sizeof(InspectorPanel));
1065 memset(panel, 0, sizeof(InspectorPanel));
1067 panel->destroyed = 0;
1068 panel->inspected = wwin;
1069 panel->nextPtr = panelList;
1070 panelList = panel;
1071 panel->win = WMCreateWindow(scr->wmscreen, "windowInspector");
1072 WMResizeWidget(panel->win, PWIDTH, PHEIGHT);
1074 /**** create common stuff ****/
1075 /* command buttons */
1076 btn_width = (PWIDTH - (2 * 15) - (2 * 10)) / 3;
1077 panel->saveBtn = WMCreateCommandButton(panel->win);
1078 WMSetButtonAction(panel->saveBtn, saveSettings, panel);
1079 WMMoveWidget(panel->saveBtn, (2 * (btn_width + 10)) + 15, PHEIGHT - 40);
1080 WMSetButtonText(panel->saveBtn, _("Save"));
1081 WMResizeWidget(panel->saveBtn, btn_width, 28);
1082 if (wPreferences.flags.noupdates || !(wwin->wm_class || wwin->wm_instance))
1083 WMSetButtonEnabled(panel->saveBtn, False);
1085 panel->applyBtn = WMCreateCommandButton(panel->win);
1086 WMSetButtonAction(panel->applyBtn, applySettings, panel);
1087 WMMoveWidget(panel->applyBtn, btn_width + 10 + 15, PHEIGHT - 40);
1088 WMSetButtonText(panel->applyBtn, _("Apply"));
1089 WMResizeWidget(panel->applyBtn, btn_width, 28);
1091 panel->revertBtn = WMCreateCommandButton(panel->win);
1092 WMSetButtonAction(panel->revertBtn, revertSettings, panel);
1093 WMMoveWidget(panel->revertBtn, 15, PHEIGHT - 40);
1094 WMSetButtonText(panel->revertBtn, _("Reload"));
1095 WMResizeWidget(panel->revertBtn, btn_width, 28);
1097 /* page selection popup button */
1098 panel->pagePopUp = WMCreatePopUpButton(panel->win);
1099 WMSetPopUpButtonAction(panel->pagePopUp, changePage, panel);
1100 WMMoveWidget(panel->pagePopUp, 25, 15);
1101 WMResizeWidget(panel->pagePopUp, PWIDTH - 50, 20);
1103 WMAddPopUpButtonItem(panel->pagePopUp, _("Window Specification"));
1104 WMAddPopUpButtonItem(panel->pagePopUp, _("Window Attributes"));
1105 WMAddPopUpButtonItem(panel->pagePopUp, _("Advanced Options"));
1106 WMAddPopUpButtonItem(panel->pagePopUp, _("Icon and Initial Workspace"));
1107 WMAddPopUpButtonItem(panel->pagePopUp, _("Application Specific"));
1109 /**** window spec ****/
1110 frame_width = PWIDTH - (2 * 15);
1112 panel->specFrm = WMCreateFrame(panel->win);
1113 WMSetFrameTitle(panel->specFrm, _("Window Specification"));
1114 WMMoveWidget(panel->specFrm, 15, 65);
1115 WMResizeWidget(panel->specFrm, frame_width, 145);
1117 panel->defaultRb = WMCreateRadioButton(panel->specFrm);
1118 WMMoveWidget(panel->defaultRb, 10, 78);
1119 WMResizeWidget(panel->defaultRb, frame_width - (2 * 10), 20);
1120 WMSetButtonText(panel->defaultRb, _("Defaults for all windows"));
1121 WMSetButtonSelected(panel->defaultRb, False);
1122 WMSetButtonAction(panel->defaultRb, selectSpecification, panel);
1124 if (wwin->wm_class && wwin->wm_instance) {
1125 tmp = wstrconcat(wwin->wm_instance, ".");
1126 str = wstrconcat(tmp, wwin->wm_class);
1128 panel->bothRb = WMCreateRadioButton(panel->specFrm);
1129 WMMoveWidget(panel->bothRb, 10, 18);
1130 WMResizeWidget(panel->bothRb, frame_width - (2 * 10), 20);
1131 WMSetButtonText(panel->bothRb, str);
1132 wfree(tmp);
1133 wfree(str);
1134 WMGroupButtons(panel->defaultRb, panel->bothRb);
1136 if (!selectedBtn)
1137 selectedBtn = panel->bothRb;
1139 WMSetButtonAction(panel->bothRb, selectSpecification, panel);
1142 if (wwin->wm_instance) {
1143 panel->instRb = WMCreateRadioButton(panel->specFrm);
1144 WMMoveWidget(panel->instRb, 10, 38);
1145 WMResizeWidget(panel->instRb, frame_width - (2 * 10), 20);
1146 WMSetButtonText(panel->instRb, wwin->wm_instance);
1147 WMGroupButtons(panel->defaultRb, panel->instRb);
1149 if (!selectedBtn)
1150 selectedBtn = panel->instRb;
1152 WMSetButtonAction(panel->instRb, selectSpecification, panel);
1155 if (wwin->wm_class) {
1156 panel->clsRb = WMCreateRadioButton(panel->specFrm);
1157 WMMoveWidget(panel->clsRb, 10, 58);
1158 WMResizeWidget(panel->clsRb, frame_width - (2 * 10), 20);
1159 WMSetButtonText(panel->clsRb, wwin->wm_class);
1160 WMGroupButtons(panel->defaultRb, panel->clsRb);
1162 if (!selectedBtn)
1163 selectedBtn = panel->clsRb;
1165 WMSetButtonAction(panel->clsRb, selectSpecification, panel);
1168 panel->selWinB = WMCreateCommandButton(panel->specFrm);
1169 WMMoveWidget(panel->selWinB, 20, 145 - 24 - 10);
1170 WMResizeWidget(panel->selWinB, frame_width - 2 * 10 - 20, 24);
1171 WMSetButtonText(panel->selWinB, _("Select window"));
1172 WMSetButtonAction(panel->selWinB, selectWindow, panel);
1174 panel->specLbl = WMCreateLabel(panel->win);
1175 WMMoveWidget(panel->specLbl, 15, 210);
1176 WMResizeWidget(panel->specLbl, frame_width, 100);
1177 WMSetLabelText(panel->specLbl, spec_text);
1178 WMSetLabelWraps(panel->specLbl, True);
1180 WMSetLabelTextAlignment(panel->specLbl, WALeft);
1182 /**** attributes ****/
1183 create_tab_window_attributes(wwin, panel, frame_width);
1184 create_tab_window_advanced(wwin, panel, frame_width);
1185 create_tab_icon_workspace(wwin, panel);
1186 create_tab_app_specific(wwin, panel, frame_width);
1188 /* if the window is a transient, don't let it have a miniaturize button */
1189 if (wwin->transient_for != None && wwin->transient_for != scr->root_win)
1190 WMSetButtonEnabled(panel->attrChk[3], False);
1191 else
1192 WMSetButtonEnabled(panel->attrChk[3], True);
1194 if (!wwin->wm_class && !wwin->wm_instance)
1195 WMSetPopUpButtonItemEnabled(panel->pagePopUp, 0, False);
1197 WMRealizeWidget(panel->win);
1199 WMMapSubwidgets(panel->win);
1200 WMMapSubwidgets(panel->specFrm);
1201 WMMapSubwidgets(panel->attrFrm);
1202 WMMapSubwidgets(panel->moreFrm);
1203 WMMapSubwidgets(panel->iconFrm);
1204 WMMapSubwidgets(panel->wsFrm);
1205 if (panel->appFrm)
1206 WMMapSubwidgets(panel->appFrm);
1208 if (showSelectPanel) {
1209 WMSetPopUpButtonSelectedItem(panel->pagePopUp, 0);
1210 changePage(panel->pagePopUp, panel);
1211 } else {
1212 WMSetPopUpButtonSelectedItem(panel->pagePopUp, 1);
1213 changePage(panel->pagePopUp, panel);
1216 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, PWIDTH, PHEIGHT, 0, 0, 0);
1217 XSelectInput(dpy, parent, KeyPressMask | KeyReleaseMask);
1218 panel->parent = parent;
1219 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
1221 WMMapWidget(panel->win);
1223 XSetTransientForHint(dpy, parent, wwin->client_win);
1225 if (xpos == UNDEFINED_POS) {
1226 x = wwin->frame_x + wwin->frame->core->width / 2;
1227 y = wwin->frame_y + wwin->frame->top_width * 2;
1228 if (y + PHEIGHT > scr->scr_height)
1229 y = scr->scr_height - PHEIGHT - 30;
1230 if (x + PWIDTH > scr->scr_width)
1231 x = scr->scr_width - PWIDTH;
1232 } else {
1233 x = xpos;
1234 y = ypos;
1237 panel->frame = wManageInternalWindow(scr, parent, wwin->client_win, "Inspector", x, y, PWIDTH, PHEIGHT);
1239 if (!selectedBtn)
1240 selectedBtn = panel->defaultRb;
1242 WMSetButtonSelected(selectedBtn, True);
1243 selectSpecification(selectedBtn, panel);
1245 /* kluge to know who should get the key events */
1246 panel->frame->client_leader = WMWidgetXID(panel->win);
1248 WSETUFLAG(panel->frame, no_closable, 0);
1249 WSETUFLAG(panel->frame, no_close_button, 0);
1250 wWindowUpdateButtonImages(panel->frame);
1251 wFrameWindowShowButton(panel->frame->frame, WFF_RIGHT_BUTTON);
1252 panel->frame->frame->on_click_right = destroyInspector;
1254 wWindowMap(panel->frame);
1256 showIconFor(WMWidgetScreen(panel->alwChk), panel, wwin->wm_instance, wwin->wm_class, UPDATE_TEXT_FIELD);
1258 return panel;
1261 void wShowInspectorForWindow(WWindow *wwin)
1263 if (wwin->flags.inspector_open)
1264 return;
1266 WMSetBalloonEnabled(wwin->screen_ptr->wmscreen, wPreferences.help_balloon);
1268 make_keys();
1269 wwin->flags.inspector_open = 1;
1270 wwin->inspector = createInspectorForWindow(wwin, UNDEFINED_POS, UNDEFINED_POS, False);
1273 void wHideInspectorForWindow(WWindow *wwin)
1275 WWindow *pwin = wwin->inspector->frame;
1277 wWindowUnmap(pwin);
1278 pwin->flags.hidden = 1;
1280 wClientSetState(pwin, IconicState, None);
1283 void wUnhideInspectorForWindow(WWindow *wwin)
1285 WWindow *pwin = wwin->inspector->frame;
1287 pwin->flags.hidden = 0;
1288 pwin->flags.mapped = 1;
1289 XMapWindow(dpy, pwin->client_win);
1290 XMapWindow(dpy, pwin->frame->core->window);
1291 wClientSetState(pwin, NormalState, None);
1294 WWindow *wGetWindowOfInspectorForWindow(WWindow *wwin)
1296 if (!wwin->inspector)
1297 return NULL;
1299 assert(wwin->flags.inspector_open != 0);
1300 return wwin->inspector->frame;
1303 void wCloseInspectorForWindow(WWindow *wwin)
1305 WWindow *pwin = wwin->inspector->frame; /* the inspector window */
1307 (*pwin->frame->on_click_right) (NULL, pwin, NULL);
1310 static void create_tab_window_attributes(WWindow *wwin, InspectorPanel *panel, int frame_width)
1312 int i = 0;
1313 char *caption = NULL, *descr = NULL;
1314 int flag = 0;
1316 panel->attrFrm = WMCreateFrame(panel->win);
1317 WMSetFrameTitle(panel->attrFrm, _("Attributes"));
1318 WMMoveWidget(panel->attrFrm, 15, 45);
1319 WMResizeWidget(panel->attrFrm, frame_width, 250);
1321 for (i = 0; i < (sizeof(panel->attrChk) / sizeof(panel->attrChk[0])); i++) {
1322 switch (i) {
1323 case 0:
1324 caption = _("Disable titlebar");
1325 flag = WFLAGP(wwin, no_titlebar);
1326 descr = _("Remove the titlebar of this window.\n"
1327 "To access the window commands menu of a window\n"
1328 "without it's titlebar, press Control+Esc (or the\n"
1329 "equivalent shortcut, if you changed the default\n" "settings).");
1330 break;
1331 case 1:
1332 caption = _("Disable resizebar");
1333 flag = WFLAGP(wwin, no_resizebar);
1334 descr = _("Remove the resizebar of this window.");
1335 break;
1336 case 2:
1337 caption = _("Disable close button");
1338 flag = WFLAGP(wwin, no_close_button);
1339 descr = _("Remove the `close window' button of this window.");
1340 break;
1341 case 3:
1342 caption = _("Disable miniaturize button");
1343 flag = WFLAGP(wwin, no_miniaturize_button);
1344 descr = _("Remove the `miniaturize window' button of the window.");
1345 break;
1346 case 4:
1347 caption = _("Disable border");
1348 flag = WFLAGP(wwin, no_border);
1349 descr = _("Remove the 1 pixel black border around the window.");
1350 break;
1351 case 5:
1352 caption = _("Keep on top (floating)");
1353 flag = WFLAGP(wwin, floating);
1354 descr = _("Keep the window over other windows, not allowing\n" "them to cover it.");
1355 break;
1356 case 6:
1357 caption = _("Keep at bottom (sunken)");
1358 flag = WFLAGP(wwin, sunken);
1359 descr = _("Keep the window under all other windows.");
1360 break;
1361 case 7:
1362 caption = _("Omnipresent");
1363 flag = WFLAGP(wwin, omnipresent);
1364 descr = _("Make window present in all workspaces.");
1365 break;
1366 case 8:
1367 caption = _("Start miniaturized");
1368 flag = WFLAGP(wwin, start_miniaturized);
1369 descr = _("Make the window be automatically miniaturized when it's\n" "first shown.");
1370 break;
1371 case 9:
1372 caption = _("Start maximized");
1373 flag = WFLAGP(wwin, start_maximized != 0);
1374 descr = _("Make the window be automatically maximized when it's\n" "first shown.");
1375 break;
1376 case 10:
1377 caption = _("Full screen maximization");
1378 flag = WFLAGP(wwin, full_maximize);
1379 descr = _("Make the window use the whole screen space when it's\n"
1380 "maximized. The titlebar and resizebar will be moved\n"
1381 "to outside the screen.");
1382 break;
1384 panel->attrChk[i] = WMCreateSwitchButton(panel->attrFrm);
1385 WMMoveWidget(panel->attrChk[i], 10, 20 * (i + 1));
1386 WMResizeWidget(panel->attrChk[i], frame_width - 15, 20);
1387 WMSetButtonSelected(panel->attrChk[i], flag);
1388 WMSetButtonText(panel->attrChk[i], caption);
1390 WMSetBalloonTextForView(descr, WMWidgetView(panel->attrChk[i]));
1394 static void create_tab_window_advanced(WWindow *wwin, InspectorPanel *panel, int frame_width)
1396 int i = 0;
1397 char *caption = NULL, *descr = NULL;
1398 int flag = 0;
1400 panel->moreFrm = WMCreateFrame(panel->win);
1401 WMSetFrameTitle(panel->moreFrm, _("Advanced"));
1402 WMMoveWidget(panel->moreFrm, 15, 45);
1403 WMResizeWidget(panel->moreFrm, frame_width, 265);
1405 for (i = 0; i < (sizeof(panel->moreChk) / sizeof(panel->moreChk[0])); i++) {
1406 switch (i) {
1407 case 0:
1408 caption = _("Do not bind keyboard shortcuts");
1409 flag = WFLAGP(wwin, no_bind_keys);
1410 descr = _("Do not bind keyboard shortcuts from Window Maker\n"
1411 "when this window is focused. This will allow the\n"
1412 "window to receive all key combinations regardless\n"
1413 "of your shortcut configuration.");
1414 break;
1415 case 1:
1416 caption = _("Do not bind mouse clicks");
1417 flag = WFLAGP(wwin, no_bind_mouse);
1418 descr = _("Do not bind mouse actions, such as `Alt'+drag\n"
1419 "in the window (when alt is the modifier you have\n" "configured).");
1420 break;
1421 case 2:
1422 caption = _("Do not show in the window list");
1423 flag = WFLAGP(wwin, skip_window_list);
1424 descr = _("Do not list the window in the window list menu.");
1425 break;
1426 case 3:
1427 caption = _("Do not show in the switch panel");
1428 flag = WFLAGP(wwin, skip_switchpanel);
1429 descr = _("Do not include in switchpanel while alternating windows.");
1430 break;
1431 case 4:
1432 caption = _("Do not let it take focus");
1433 flag = WFLAGP(wwin, no_focusable);
1434 descr = _("Do not let the window take keyboard focus when you\n" "click on it.");
1435 break;
1436 case 5:
1437 caption = _("Keep inside screen");
1438 flag = WFLAGP(wwin, dont_move_off);
1439 descr = _("Do not allow the window to move itself completely\n"
1440 "outside the screen. For bug compatibility.\n");
1441 break;
1442 case 6:
1443 caption = _("Ignore 'Hide Others'");
1444 flag = WFLAGP(wwin, no_hide_others);
1445 descr = _("Do not hide the window when issuing the\n" "`HideOthers' command.");
1446 break;
1447 case 7:
1448 caption = _("Ignore 'Save Session'");
1449 flag = WFLAGP(wwin, dont_save_session);
1450 descr = _("Do not save the associated application in the\n"
1451 "session's state, so that it won't be restarted\n"
1452 "together with other applications when Window Maker\n" "starts.");
1453 break;
1454 case 8:
1455 caption = _("Emulate application icon");
1456 flag = WFLAGP(wwin, emulate_appicon);
1457 descr = _("Make this window act as an application that provides\n"
1458 "enough information to Window Maker for a dockable\n"
1459 "application icon to be created.");
1460 break;
1461 case 9:
1462 caption = _("Focus across workspaces");
1463 flag = WFLAGP(wwin, focus_across_wksp);
1464 descr = _("Allow Window Maker to switch workspace to satisfy\n"
1465 "a focus request (annoying).");
1466 break;
1467 case 10:
1468 caption = _("Do not let it be minimized");
1469 flag = WFLAGP(wwin, no_miniaturizable);
1470 descr = _("Do not let the window of this application be\n"
1471 "minimized.\n");
1472 break;
1473 #ifdef XKB_BUTTON_HINT
1474 case 11:
1475 caption = _("Disable language button");
1476 flag = WFLAGP(wwin, no_language_button);
1477 descr = _("Remove the `toggle language' button of the window.");
1478 break;
1479 #endif
1481 panel->moreChk[i] = WMCreateSwitchButton(panel->moreFrm);
1482 WMMoveWidget(panel->moreChk[i], 10, 20 * (i + 1));
1483 WMResizeWidget(panel->moreChk[i], frame_width - 15, 20);
1484 WMSetButtonSelected(panel->moreChk[i], flag);
1485 WMSetButtonText(panel->moreChk[i], caption);
1487 WMSetBalloonTextForView(descr, WMWidgetView(panel->moreChk[i]));
1491 static void create_tab_icon_workspace(WWindow *wwin, InspectorPanel *panel)
1493 int i = 0;
1495 /* miniwindow/workspace */
1496 panel->iconFrm = WMCreateFrame(panel->win);
1497 WMMoveWidget(panel->iconFrm, 15, 50);
1498 WMResizeWidget(panel->iconFrm, PWIDTH - (2 * 15), 170);
1499 WMSetFrameTitle(panel->iconFrm, _("Miniwindow Image"));
1501 panel->iconLbl = WMCreateLabel(panel->iconFrm);
1502 WMMoveWidget(panel->iconLbl, PWIDTH - (2 * 15) - 22 - 64, 20);
1503 WMResizeWidget(panel->iconLbl, 64, 64);
1504 WMSetLabelRelief(panel->iconLbl, WRGroove);
1505 WMSetLabelImagePosition(panel->iconLbl, WIPImageOnly);
1507 panel->browseIconBtn = WMCreateCommandButton(panel->iconFrm);
1508 WMSetButtonAction(panel->browseIconBtn, chooseIconCallback, panel);
1509 WMMoveWidget(panel->browseIconBtn, 22, 32);
1510 WMResizeWidget(panel->browseIconBtn, 120, 26);
1511 WMSetButtonText(panel->browseIconBtn, _("Browse..."));
1513 panel->fileLbl = WMCreateLabel(panel->iconFrm);
1514 WMMoveWidget(panel->fileLbl, 20, 85);
1515 WMResizeWidget(panel->fileLbl, PWIDTH - (2 * 15) - (2 * 20), 14);
1516 WMSetLabelText(panel->fileLbl, _("Icon filename:"));
1518 panel->fileText = WMCreateTextField(panel->iconFrm);
1519 WMMoveWidget(panel->fileText, 20, 105);
1520 WMResizeWidget(panel->fileText, PWIDTH - (2 * 20) - (2 * 15), 20);
1521 WMSetTextFieldText(panel->fileText, NULL);
1522 WMAddNotificationObserver(textEditedObserver, panel, WMTextDidEndEditingNotification, panel->fileText);
1524 panel->alwChk = WMCreateSwitchButton(panel->iconFrm);
1525 WMMoveWidget(panel->alwChk, 20, 130);
1526 WMResizeWidget(panel->alwChk, PWIDTH - (2 * 15) - (2 * 15), 30);
1527 WMSetButtonText(panel->alwChk, _("Ignore client supplied icon"));
1528 WMSetButtonSelected(panel->alwChk, WFLAGP(wwin, always_user_icon));
1530 panel->wsFrm = WMCreateFrame(panel->win);
1531 WMMoveWidget(panel->wsFrm, 15, 225);
1532 WMResizeWidget(panel->wsFrm, PWIDTH - (2 * 15), 70);
1533 WMSetFrameTitle(panel->wsFrm, _("Initial Workspace"));
1535 WMSetBalloonTextForView(_("The workspace to place the window when it's"
1536 "first shown."), WMWidgetView(panel->wsFrm));
1538 panel->wsP = WMCreatePopUpButton(panel->wsFrm);
1539 WMMoveWidget(panel->wsP, 20, 30);
1540 WMResizeWidget(panel->wsP, PWIDTH - (2 * 15) - (2 * 20), 20);
1541 WMAddPopUpButtonItem(panel->wsP, _("Nowhere in particular"));
1543 for (i = 0; i < w_global.workspace.count; i++)
1544 WMAddPopUpButtonItem(panel->wsP, w_global.workspace.array[i]->name);
1546 i = wDefaultGetStartWorkspace(wwin->wm_instance, wwin->wm_class);
1547 if (i >= 0 && i <= w_global.workspace.count)
1548 WMSetPopUpButtonSelectedItem(panel->wsP, i + 1);
1549 else
1550 WMSetPopUpButtonSelectedItem(panel->wsP, 0);
1553 static void create_tab_app_specific(WWindow *wwin, InspectorPanel *panel, int frame_width)
1555 WScreen *scr = wwin->screen_ptr;
1556 int i = 0, flag = 0, tmp;
1557 char *caption = NULL, *descr = NULL;
1560 if (wwin->main_window != None) {
1561 WApplication *wapp = wApplicationOf(wwin->main_window);
1563 panel->appFrm = WMCreateFrame(panel->win);
1564 WMSetFrameTitle(panel->appFrm, _("Application Attributes"));
1565 WMMoveWidget(panel->appFrm, 15, 50);
1566 WMResizeWidget(panel->appFrm, frame_width, 240);
1568 for (i = 0; i < (sizeof(panel->appChk) / sizeof(panel->appChk[0])); i++) {
1569 switch (i) {
1570 case 0:
1571 caption = _("Start hidden");
1572 flag = WFLAGP(wapp->main_window_desc, start_hidden);
1573 descr = _("Automatically hide application when it's started.");
1574 break;
1575 case 1:
1576 caption = _("No application icon");
1577 flag = WFLAGP(wapp->main_window_desc, no_appicon);
1578 descr = _("Disable the application icon for the application.\n"
1579 "Note that you won't be able to dock it anymore,\n"
1580 "and any icons that are already docked will stop\n"
1581 "working correctly.");
1582 break;
1583 case 2:
1584 caption = _("Shared application icon");
1585 flag = WFLAGP(wapp->main_window_desc, shared_appicon);
1586 descr = _("Use a single shared application icon for all of\n"
1587 "the instances of this application.\n");
1588 break;
1590 panel->appChk[i] = WMCreateSwitchButton(panel->appFrm);
1591 WMMoveWidget(panel->appChk[i], 10, 20 * (i + 1));
1592 WMResizeWidget(panel->appChk[i], 205, 20);
1593 WMSetButtonSelected(panel->appChk[i], flag);
1594 WMSetButtonText(panel->appChk[i], caption);
1595 WMSetBalloonTextForView(descr, WMWidgetView(panel->appChk[i]));
1598 if (WFLAGP(wwin, emulate_appicon)) {
1599 WMSetButtonEnabled(panel->appChk[1], False);
1600 WMSetButtonEnabled(panel->moreChk[7], True);
1601 } else {
1602 WMSetButtonEnabled(panel->appChk[1], True);
1603 WMSetButtonEnabled(panel->moreChk[7], False);
1605 } else {
1606 if ((wwin->transient_for != None && wwin->transient_for != scr->root_win)
1607 || !wwin->wm_class || !wwin->wm_instance)
1608 tmp = False;
1609 else
1610 tmp = True;
1612 WMSetButtonEnabled(panel->moreChk[7], tmp);
1614 WMSetPopUpButtonItemEnabled(panel->pagePopUp, 4, False);
1615 panel->appFrm = NULL;