Fix out of source build for i18n pot files
[wmaker-crm.git] / src / winspector.c
blob1e185f52356af4eda31ce8dd1839fc417ecaa33c
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 < wlengthof(panel->attrChk); 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 < wlengthof(panel->moreChk); 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 < wlengthof(panel->appChk); 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[256];
997 WWindow *wwin = panel->inspected;
999 if (bPtr == panel->defaultRb && (wwin->wm_instance || wwin->wm_class))
1000 WMSetButtonEnabled(panel->applyBtn, False);
1001 else
1002 WMSetButtonEnabled(panel->applyBtn, True);
1004 snprintf(str, sizeof(str),
1005 _("Inspecting %s.%s"),
1006 wwin->wm_instance ? wwin->wm_instance : "?",
1007 wwin->wm_class ? wwin->wm_class : "?");
1009 wFrameWindowChangeTitle(panel->frame->frame, str);
1012 static void selectWindow(WMWidget *bPtr, void *data)
1014 InspectorPanel *panel = (InspectorPanel *) data;
1015 WWindow *wwin = panel->inspected;
1016 WScreen *scr = wwin->screen_ptr;
1017 XEvent event;
1018 WWindow *iwin;
1020 /* Parameter not used, but tell the compiler that it is ok */
1021 (void) bPtr;
1023 if (XGrabPointer(dpy, scr->root_win, True,
1024 ButtonPressMask, GrabModeAsync, GrabModeAsync, None,
1025 wPreferences.cursor[WCUR_SELECT], CurrentTime) != GrabSuccess) {
1026 wwarning("could not grab mouse pointer");
1027 return;
1030 WMSetLabelText(panel->specLbl, _("Click in the window you wish to inspect."));
1031 WMMaskEvent(dpy, ButtonPressMask, &event);
1032 XUngrabPointer(dpy, CurrentTime);
1034 iwin = wWindowFor(event.xbutton.subwindow);
1035 if (iwin && !iwin->flags.internal_window && iwin != wwin && !iwin->flags.inspector_open) {
1036 iwin->flags.inspector_open = 1;
1037 iwin->inspector = createInspectorForWindow(iwin,
1038 panel->frame->frame_x, panel->frame->frame_y, True);
1039 wCloseInspectorForWindow(wwin);
1040 } else {
1041 WMSetLabelText(panel->specLbl, spec_text);
1045 static InspectorPanel *createInspectorForWindow(WWindow *wwin, int xpos, int ypos, Bool showSelectPanel)
1047 WScreen *scr = wwin->screen_ptr;
1048 InspectorPanel *panel;
1049 Window parent;
1050 char *str = NULL, *tmp = NULL;
1051 int x, y, btn_width, frame_width;
1052 WMButton *selectedBtn = NULL;
1054 spec_text = _("The configuration will apply to all\n"
1055 "windows that have their WM_CLASS\n"
1056 "property set to the above selected\n" "name, when saved.");
1058 panel = wmalloc(sizeof(InspectorPanel));
1059 memset(panel, 0, sizeof(InspectorPanel));
1061 panel->destroyed = 0;
1062 panel->inspected = wwin;
1063 panel->nextPtr = panelList;
1064 panelList = panel;
1065 panel->win = WMCreateWindow(scr->wmscreen, "windowInspector");
1066 WMResizeWidget(panel->win, PWIDTH, PHEIGHT);
1068 /**** create common stuff ****/
1069 /* command buttons */
1070 btn_width = (PWIDTH - (2 * 15) - (2 * 10)) / 3;
1071 panel->saveBtn = WMCreateCommandButton(panel->win);
1072 WMSetButtonAction(panel->saveBtn, saveSettings, panel);
1073 WMMoveWidget(panel->saveBtn, (2 * (btn_width + 10)) + 15, PHEIGHT - 40);
1074 WMSetButtonText(panel->saveBtn, _("Save"));
1075 WMResizeWidget(panel->saveBtn, btn_width, 28);
1076 if (wPreferences.flags.noupdates || !(wwin->wm_class || wwin->wm_instance))
1077 WMSetButtonEnabled(panel->saveBtn, False);
1079 panel->applyBtn = WMCreateCommandButton(panel->win);
1080 WMSetButtonAction(panel->applyBtn, applySettings, panel);
1081 WMMoveWidget(panel->applyBtn, btn_width + 10 + 15, PHEIGHT - 40);
1082 WMSetButtonText(panel->applyBtn, _("Apply"));
1083 WMResizeWidget(panel->applyBtn, btn_width, 28);
1085 panel->revertBtn = WMCreateCommandButton(panel->win);
1086 WMSetButtonAction(panel->revertBtn, revertSettings, panel);
1087 WMMoveWidget(panel->revertBtn, 15, PHEIGHT - 40);
1088 WMSetButtonText(panel->revertBtn, _("Reload"));
1089 WMResizeWidget(panel->revertBtn, btn_width, 28);
1091 /* page selection popup button */
1092 panel->pagePopUp = WMCreatePopUpButton(panel->win);
1093 WMSetPopUpButtonAction(panel->pagePopUp, changePage, panel);
1094 WMMoveWidget(panel->pagePopUp, 25, 15);
1095 WMResizeWidget(panel->pagePopUp, PWIDTH - 50, 20);
1097 WMAddPopUpButtonItem(panel->pagePopUp, _("Window Specification"));
1098 WMAddPopUpButtonItem(panel->pagePopUp, _("Window Attributes"));
1099 WMAddPopUpButtonItem(panel->pagePopUp, _("Advanced Options"));
1100 WMAddPopUpButtonItem(panel->pagePopUp, _("Icon and Initial Workspace"));
1101 WMAddPopUpButtonItem(panel->pagePopUp, _("Application Specific"));
1103 /**** window spec ****/
1104 frame_width = PWIDTH - (2 * 15);
1106 panel->specFrm = WMCreateFrame(panel->win);
1107 WMSetFrameTitle(panel->specFrm, _("Window Specification"));
1108 WMMoveWidget(panel->specFrm, 15, 65);
1109 WMResizeWidget(panel->specFrm, frame_width, 145);
1111 panel->defaultRb = WMCreateRadioButton(panel->specFrm);
1112 WMMoveWidget(panel->defaultRb, 10, 78);
1113 WMResizeWidget(panel->defaultRb, frame_width - (2 * 10), 20);
1114 WMSetButtonText(panel->defaultRb, _("Defaults for all windows"));
1115 WMSetButtonSelected(panel->defaultRb, False);
1116 WMSetButtonAction(panel->defaultRb, selectSpecification, panel);
1118 if (wwin->wm_class && wwin->wm_instance) {
1119 tmp = wstrconcat(wwin->wm_instance, ".");
1120 str = wstrconcat(tmp, wwin->wm_class);
1122 panel->bothRb = WMCreateRadioButton(panel->specFrm);
1123 WMMoveWidget(panel->bothRb, 10, 18);
1124 WMResizeWidget(panel->bothRb, frame_width - (2 * 10), 20);
1125 WMSetButtonText(panel->bothRb, str);
1126 wfree(tmp);
1127 wfree(str);
1128 WMGroupButtons(panel->defaultRb, panel->bothRb);
1130 if (!selectedBtn)
1131 selectedBtn = panel->bothRb;
1133 WMSetButtonAction(panel->bothRb, selectSpecification, panel);
1136 if (wwin->wm_instance) {
1137 panel->instRb = WMCreateRadioButton(panel->specFrm);
1138 WMMoveWidget(panel->instRb, 10, 38);
1139 WMResizeWidget(panel->instRb, frame_width - (2 * 10), 20);
1140 WMSetButtonText(panel->instRb, wwin->wm_instance);
1141 WMGroupButtons(panel->defaultRb, panel->instRb);
1143 if (!selectedBtn)
1144 selectedBtn = panel->instRb;
1146 WMSetButtonAction(panel->instRb, selectSpecification, panel);
1149 if (wwin->wm_class) {
1150 panel->clsRb = WMCreateRadioButton(panel->specFrm);
1151 WMMoveWidget(panel->clsRb, 10, 58);
1152 WMResizeWidget(panel->clsRb, frame_width - (2 * 10), 20);
1153 WMSetButtonText(panel->clsRb, wwin->wm_class);
1154 WMGroupButtons(panel->defaultRb, panel->clsRb);
1156 if (!selectedBtn)
1157 selectedBtn = panel->clsRb;
1159 WMSetButtonAction(panel->clsRb, selectSpecification, panel);
1162 panel->selWinB = WMCreateCommandButton(panel->specFrm);
1163 WMMoveWidget(panel->selWinB, 20, 145 - 24 - 10);
1164 WMResizeWidget(panel->selWinB, frame_width - 2 * 10 - 20, 24);
1165 WMSetButtonText(panel->selWinB, _("Select window"));
1166 WMSetButtonAction(panel->selWinB, selectWindow, panel);
1168 panel->specLbl = WMCreateLabel(panel->win);
1169 WMMoveWidget(panel->specLbl, 15, 210);
1170 WMResizeWidget(panel->specLbl, frame_width, 100);
1171 WMSetLabelText(panel->specLbl, spec_text);
1172 WMSetLabelWraps(panel->specLbl, True);
1174 WMSetLabelTextAlignment(panel->specLbl, WALeft);
1176 /**** attributes ****/
1177 create_tab_window_attributes(wwin, panel, frame_width);
1178 create_tab_window_advanced(wwin, panel, frame_width);
1179 create_tab_icon_workspace(wwin, panel);
1180 create_tab_app_specific(wwin, panel, frame_width);
1182 /* if the window is a transient, don't let it have a miniaturize button */
1183 if (wwin->transient_for != None && wwin->transient_for != scr->root_win)
1184 WMSetButtonEnabled(panel->attrChk[3], False);
1185 else
1186 WMSetButtonEnabled(panel->attrChk[3], True);
1188 if (!wwin->wm_class && !wwin->wm_instance)
1189 WMSetPopUpButtonItemEnabled(panel->pagePopUp, 0, False);
1191 WMRealizeWidget(panel->win);
1193 WMMapSubwidgets(panel->win);
1194 WMMapSubwidgets(panel->specFrm);
1195 WMMapSubwidgets(panel->attrFrm);
1196 WMMapSubwidgets(panel->moreFrm);
1197 WMMapSubwidgets(panel->iconFrm);
1198 WMMapSubwidgets(panel->wsFrm);
1199 if (panel->appFrm)
1200 WMMapSubwidgets(panel->appFrm);
1202 if (showSelectPanel) {
1203 WMSetPopUpButtonSelectedItem(panel->pagePopUp, 0);
1204 changePage(panel->pagePopUp, panel);
1205 } else {
1206 WMSetPopUpButtonSelectedItem(panel->pagePopUp, 1);
1207 changePage(panel->pagePopUp, panel);
1210 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, PWIDTH, PHEIGHT, 0, 0, 0);
1211 XSelectInput(dpy, parent, KeyPressMask | KeyReleaseMask);
1212 panel->parent = parent;
1213 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
1215 WMMapWidget(panel->win);
1217 XSetTransientForHint(dpy, parent, wwin->client_win);
1219 if (xpos == UNDEFINED_POS) {
1220 x = wwin->frame_x + wwin->frame->core->width / 2;
1221 y = wwin->frame_y + wwin->frame->top_width * 2;
1222 if (y + PHEIGHT > scr->scr_height)
1223 y = scr->scr_height - PHEIGHT - 30;
1224 if (x + PWIDTH > scr->scr_width)
1225 x = scr->scr_width - PWIDTH;
1226 } else {
1227 x = xpos;
1228 y = ypos;
1231 panel->frame = wManageInternalWindow(scr, parent, wwin->client_win, "Inspector", x, y, PWIDTH, PHEIGHT);
1233 if (!selectedBtn)
1234 selectedBtn = panel->defaultRb;
1236 WMSetButtonSelected(selectedBtn, True);
1237 selectSpecification(selectedBtn, panel);
1239 /* kluge to know who should get the key events */
1240 panel->frame->client_leader = WMWidgetXID(panel->win);
1242 WSETUFLAG(panel->frame, no_closable, 0);
1243 WSETUFLAG(panel->frame, no_close_button, 0);
1244 wWindowUpdateButtonImages(panel->frame);
1245 wFrameWindowShowButton(panel->frame->frame, WFF_RIGHT_BUTTON);
1246 panel->frame->frame->on_click_right = destroyInspector;
1248 wWindowMap(panel->frame);
1250 showIconFor(WMWidgetScreen(panel->alwChk), panel, wwin->wm_instance, wwin->wm_class, UPDATE_TEXT_FIELD);
1252 return panel;
1255 void wShowInspectorForWindow(WWindow *wwin)
1257 if (wwin->flags.inspector_open)
1258 return;
1260 WMSetBalloonEnabled(wwin->screen_ptr->wmscreen, wPreferences.help_balloon);
1262 make_keys();
1263 wwin->flags.inspector_open = 1;
1264 wwin->inspector = createInspectorForWindow(wwin, UNDEFINED_POS, UNDEFINED_POS, False);
1267 void wHideInspectorForWindow(WWindow *wwin)
1269 WWindow *pwin = wwin->inspector->frame;
1271 wWindowUnmap(pwin);
1272 pwin->flags.hidden = 1;
1274 wClientSetState(pwin, IconicState, None);
1277 void wUnhideInspectorForWindow(WWindow *wwin)
1279 WWindow *pwin = wwin->inspector->frame;
1281 pwin->flags.hidden = 0;
1282 pwin->flags.mapped = 1;
1283 XMapWindow(dpy, pwin->client_win);
1284 XMapWindow(dpy, pwin->frame->core->window);
1285 wClientSetState(pwin, NormalState, None);
1288 WWindow *wGetWindowOfInspectorForWindow(WWindow *wwin)
1290 if (!wwin->inspector)
1291 return NULL;
1293 assert(wwin->flags.inspector_open != 0);
1294 return wwin->inspector->frame;
1297 void wCloseInspectorForWindow(WWindow *wwin)
1299 WWindow *pwin = wwin->inspector->frame; /* the inspector window */
1301 (*pwin->frame->on_click_right) (NULL, pwin, NULL);
1304 static void create_tab_window_attributes(WWindow *wwin, InspectorPanel *panel, int frame_width)
1306 int i = 0;
1307 char *caption = NULL, *descr = NULL;
1308 int flag = 0;
1310 panel->attrFrm = WMCreateFrame(panel->win);
1311 WMSetFrameTitle(panel->attrFrm, _("Attributes"));
1312 WMMoveWidget(panel->attrFrm, 15, 45);
1313 WMResizeWidget(panel->attrFrm, frame_width, 250);
1315 for (i = 0; i < wlengthof(panel->attrChk); i++) {
1316 switch (i) {
1317 case 0:
1318 caption = _("Disable titlebar");
1319 flag = WFLAGP(wwin, no_titlebar);
1320 descr = _("Remove the titlebar of this window.\n"
1321 "To access the window commands menu of a window\n"
1322 "without it's titlebar, press Control+Esc (or the\n"
1323 "equivalent shortcut, if you changed the default\n" "settings).");
1324 break;
1325 case 1:
1326 caption = _("Disable resizebar");
1327 flag = WFLAGP(wwin, no_resizebar);
1328 descr = _("Remove the resizebar of this window.");
1329 break;
1330 case 2:
1331 caption = _("Disable close button");
1332 flag = WFLAGP(wwin, no_close_button);
1333 descr = _("Remove the `close window' button of this window.");
1334 break;
1335 case 3:
1336 caption = _("Disable miniaturize button");
1337 flag = WFLAGP(wwin, no_miniaturize_button);
1338 descr = _("Remove the `miniaturize window' button of the window.");
1339 break;
1340 case 4:
1341 caption = _("Disable border");
1342 flag = WFLAGP(wwin, no_border);
1343 descr = _("Remove the 1 pixel black border around the window.");
1344 break;
1345 case 5:
1346 caption = _("Keep on top (floating)");
1347 flag = WFLAGP(wwin, floating);
1348 descr = _("Keep the window over other windows, not allowing\n" "them to cover it.");
1349 break;
1350 case 6:
1351 caption = _("Keep at bottom (sunken)");
1352 flag = WFLAGP(wwin, sunken);
1353 descr = _("Keep the window under all other windows.");
1354 break;
1355 case 7:
1356 caption = _("Omnipresent");
1357 flag = WFLAGP(wwin, omnipresent);
1358 descr = _("Make window present in all workspaces.");
1359 break;
1360 case 8:
1361 caption = _("Start miniaturized");
1362 flag = WFLAGP(wwin, start_miniaturized);
1363 descr = _("Make the window be automatically miniaturized when it's\n" "first shown.");
1364 break;
1365 case 9:
1366 caption = _("Start maximized");
1367 flag = WFLAGP(wwin, start_maximized != 0);
1368 descr = _("Make the window be automatically maximized when it's\n" "first shown.");
1369 break;
1370 case 10:
1371 caption = _("Full screen maximization");
1372 flag = WFLAGP(wwin, full_maximize);
1373 descr = _("Make the window use the whole screen space when it's\n"
1374 "maximized. The titlebar and resizebar will be moved\n"
1375 "to outside the screen.");
1376 break;
1378 panel->attrChk[i] = WMCreateSwitchButton(panel->attrFrm);
1379 WMMoveWidget(panel->attrChk[i], 10, 20 * (i + 1));
1380 WMResizeWidget(panel->attrChk[i], frame_width - 15, 20);
1381 WMSetButtonSelected(panel->attrChk[i], flag);
1382 WMSetButtonText(panel->attrChk[i], caption);
1384 WMSetBalloonTextForView(descr, WMWidgetView(panel->attrChk[i]));
1388 static void create_tab_window_advanced(WWindow *wwin, InspectorPanel *panel, int frame_width)
1390 int i = 0;
1391 char *caption = NULL, *descr = NULL;
1392 int flag = 0;
1394 panel->moreFrm = WMCreateFrame(panel->win);
1395 WMSetFrameTitle(panel->moreFrm, _("Advanced"));
1396 WMMoveWidget(panel->moreFrm, 15, 45);
1397 WMResizeWidget(panel->moreFrm, frame_width, 265);
1399 for (i = 0; i < wlengthof(panel->moreChk); i++) {
1400 switch (i) {
1401 case 0:
1402 caption = _("Do not bind keyboard shortcuts");
1403 flag = WFLAGP(wwin, no_bind_keys);
1404 descr = _("Do not bind keyboard shortcuts from Window Maker\n"
1405 "when this window is focused. This will allow the\n"
1406 "window to receive all key combinations regardless\n"
1407 "of your shortcut configuration.");
1408 break;
1409 case 1:
1410 caption = _("Do not bind mouse clicks");
1411 flag = WFLAGP(wwin, no_bind_mouse);
1412 descr = _("Do not bind mouse actions, such as `Alt'+drag\n"
1413 "in the window (when alt is the modifier you have\n" "configured).");
1414 break;
1415 case 2:
1416 caption = _("Do not show in the window list");
1417 flag = WFLAGP(wwin, skip_window_list);
1418 descr = _("Do not list the window in the window list menu.");
1419 break;
1420 case 3:
1421 caption = _("Do not show in the switch panel");
1422 flag = WFLAGP(wwin, skip_switchpanel);
1423 descr = _("Do not include in switchpanel while alternating windows.");
1424 break;
1425 case 4:
1426 caption = _("Do not let it take focus");
1427 flag = WFLAGP(wwin, no_focusable);
1428 descr = _("Do not let the window take keyboard focus when you\n" "click on it.");
1429 break;
1430 case 5:
1431 caption = _("Keep inside screen");
1432 flag = WFLAGP(wwin, dont_move_off);
1433 descr = _("Do not allow the window to move itself completely\n"
1434 "outside the screen. For bug compatibility.\n");
1435 break;
1436 case 6:
1437 caption = _("Ignore 'Hide Others'");
1438 flag = WFLAGP(wwin, no_hide_others);
1439 descr = _("Do not hide the window when issuing the\n" "`HideOthers' command.");
1440 break;
1441 case 7:
1442 caption = _("Ignore 'Save Session'");
1443 flag = WFLAGP(wwin, dont_save_session);
1444 descr = _("Do not save the associated application in the\n"
1445 "session's state, so that it won't be restarted\n"
1446 "together with other applications when Window Maker\n" "starts.");
1447 break;
1448 case 8:
1449 caption = _("Emulate application icon");
1450 flag = WFLAGP(wwin, emulate_appicon);
1451 descr = _("Make this window act as an application that provides\n"
1452 "enough information to Window Maker for a dockable\n"
1453 "application icon to be created.");
1454 break;
1455 case 9:
1456 caption = _("Focus across workspaces");
1457 flag = WFLAGP(wwin, focus_across_wksp);
1458 descr = _("Allow Window Maker to switch workspace to satisfy\n"
1459 "a focus request (annoying).");
1460 break;
1461 case 10:
1462 caption = _("Do not let it be minimized");
1463 flag = WFLAGP(wwin, no_miniaturizable);
1464 descr = _("Do not let the window of this application be\n"
1465 "minimized.\n");
1466 break;
1467 #ifdef XKB_BUTTON_HINT
1468 case 11:
1469 caption = _("Disable language button");
1470 flag = WFLAGP(wwin, no_language_button);
1471 descr = _("Remove the `toggle language' button of the window.");
1472 break;
1473 #endif
1475 panel->moreChk[i] = WMCreateSwitchButton(panel->moreFrm);
1476 WMMoveWidget(panel->moreChk[i], 10, 20 * (i + 1));
1477 WMResizeWidget(panel->moreChk[i], frame_width - 15, 20);
1478 WMSetButtonSelected(panel->moreChk[i], flag);
1479 WMSetButtonText(panel->moreChk[i], caption);
1481 WMSetBalloonTextForView(descr, WMWidgetView(panel->moreChk[i]));
1485 static void create_tab_icon_workspace(WWindow *wwin, InspectorPanel *panel)
1487 int i = 0;
1489 /* miniwindow/workspace */
1490 panel->iconFrm = WMCreateFrame(panel->win);
1491 WMMoveWidget(panel->iconFrm, 15, 50);
1492 WMResizeWidget(panel->iconFrm, PWIDTH - (2 * 15), 170);
1493 WMSetFrameTitle(panel->iconFrm, _("Miniwindow Image"));
1495 panel->iconLbl = WMCreateLabel(panel->iconFrm);
1496 WMMoveWidget(panel->iconLbl, PWIDTH - (2 * 15) - 22 - 64, 20);
1497 WMResizeWidget(panel->iconLbl, 64, 64);
1498 WMSetLabelRelief(panel->iconLbl, WRGroove);
1499 WMSetLabelImagePosition(panel->iconLbl, WIPImageOnly);
1501 panel->browseIconBtn = WMCreateCommandButton(panel->iconFrm);
1502 WMSetButtonAction(panel->browseIconBtn, chooseIconCallback, panel);
1503 WMMoveWidget(panel->browseIconBtn, 22, 32);
1504 WMResizeWidget(panel->browseIconBtn, 120, 26);
1505 WMSetButtonText(panel->browseIconBtn, _("Browse..."));
1507 panel->fileLbl = WMCreateLabel(panel->iconFrm);
1508 WMMoveWidget(panel->fileLbl, 20, 85);
1509 WMResizeWidget(panel->fileLbl, PWIDTH - (2 * 15) - (2 * 20), 14);
1510 WMSetLabelText(panel->fileLbl, _("Icon filename:"));
1512 panel->fileText = WMCreateTextField(panel->iconFrm);
1513 WMMoveWidget(panel->fileText, 20, 105);
1514 WMResizeWidget(panel->fileText, PWIDTH - (2 * 20) - (2 * 15), 20);
1515 WMSetTextFieldText(panel->fileText, NULL);
1516 WMAddNotificationObserver(textEditedObserver, panel, WMTextDidEndEditingNotification, panel->fileText);
1518 panel->alwChk = WMCreateSwitchButton(panel->iconFrm);
1519 WMMoveWidget(panel->alwChk, 20, 130);
1520 WMResizeWidget(panel->alwChk, PWIDTH - (2 * 15) - (2 * 15), 30);
1521 WMSetButtonText(panel->alwChk, _("Ignore client supplied icon"));
1522 WMSetButtonSelected(panel->alwChk, WFLAGP(wwin, always_user_icon));
1524 panel->wsFrm = WMCreateFrame(panel->win);
1525 WMMoveWidget(panel->wsFrm, 15, 225);
1526 WMResizeWidget(panel->wsFrm, PWIDTH - (2 * 15), 70);
1527 WMSetFrameTitle(panel->wsFrm, _("Initial Workspace"));
1529 WMSetBalloonTextForView(_("The workspace to place the window when it's"
1530 "first shown."), WMWidgetView(panel->wsFrm));
1532 panel->wsP = WMCreatePopUpButton(panel->wsFrm);
1533 WMMoveWidget(panel->wsP, 20, 30);
1534 WMResizeWidget(panel->wsP, PWIDTH - (2 * 15) - (2 * 20), 20);
1535 WMAddPopUpButtonItem(panel->wsP, _("Nowhere in particular"));
1537 for (i = 0; i < w_global.workspace.count; i++)
1538 WMAddPopUpButtonItem(panel->wsP, w_global.workspace.array[i]->name);
1540 i = wDefaultGetStartWorkspace(wwin->wm_instance, wwin->wm_class);
1541 if (i >= 0 && i <= w_global.workspace.count)
1542 WMSetPopUpButtonSelectedItem(panel->wsP, i + 1);
1543 else
1544 WMSetPopUpButtonSelectedItem(panel->wsP, 0);
1547 static void create_tab_app_specific(WWindow *wwin, InspectorPanel *panel, int frame_width)
1549 WScreen *scr = wwin->screen_ptr;
1550 int i = 0, flag = 0, tmp;
1551 char *caption = NULL, *descr = NULL;
1554 if (wwin->main_window != None) {
1555 WApplication *wapp = wApplicationOf(wwin->main_window);
1557 panel->appFrm = WMCreateFrame(panel->win);
1558 WMSetFrameTitle(panel->appFrm, _("Application Attributes"));
1559 WMMoveWidget(panel->appFrm, 15, 50);
1560 WMResizeWidget(panel->appFrm, frame_width, 240);
1562 for (i = 0; i < wlengthof(panel->appChk); i++) {
1563 switch (i) {
1564 case 0:
1565 caption = _("Start hidden");
1566 flag = WFLAGP(wapp->main_window_desc, start_hidden);
1567 descr = _("Automatically hide application when it's started.");
1568 break;
1569 case 1:
1570 caption = _("No application icon");
1571 flag = WFLAGP(wapp->main_window_desc, no_appicon);
1572 descr = _("Disable the application icon for the application.\n"
1573 "Note that you won't be able to dock it anymore,\n"
1574 "and any icons that are already docked will stop\n"
1575 "working correctly.");
1576 break;
1577 case 2:
1578 caption = _("Shared application icon");
1579 flag = WFLAGP(wapp->main_window_desc, shared_appicon);
1580 descr = _("Use a single shared application icon for all of\n"
1581 "the instances of this application.\n");
1582 break;
1584 panel->appChk[i] = WMCreateSwitchButton(panel->appFrm);
1585 WMMoveWidget(panel->appChk[i], 10, 20 * (i + 1));
1586 WMResizeWidget(panel->appChk[i], 205, 20);
1587 WMSetButtonSelected(panel->appChk[i], flag);
1588 WMSetButtonText(panel->appChk[i], caption);
1589 WMSetBalloonTextForView(descr, WMWidgetView(panel->appChk[i]));
1592 if (WFLAGP(wwin, emulate_appicon)) {
1593 WMSetButtonEnabled(panel->appChk[1], False);
1594 WMSetButtonEnabled(panel->moreChk[7], True);
1595 } else {
1596 WMSetButtonEnabled(panel->appChk[1], True);
1597 WMSetButtonEnabled(panel->moreChk[7], False);
1599 } else {
1600 if ((wwin->transient_for != None && wwin->transient_for != scr->root_win)
1601 || !wwin->wm_class || !wwin->wm_instance)
1602 tmp = False;
1603 else
1604 tmp = True;
1606 WMSetButtonEnabled(panel->moreChk[7], tmp);
1608 WMSetPopUpButtonItemEnabled(panel->pagePopUp, 4, False);
1609 panel->appFrm = NULL;