wmaker: Added 'const' attribute to local variables
[wmaker-crm.git] / src / winspector.c
blob13f4799a549e7a6d7e9d4de1264a922c693f221f
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 extern Cursor wCursor[WCUR_LAST];
118 extern WDDomain *WDWindowAttributes;
119 extern WPreferences wPreferences;
121 static InspectorPanel *panelList = NULL;
122 static WMPropList *ANoTitlebar = NULL;
123 static WMPropList *ANoResizebar;
124 static WMPropList *ANoMiniaturizeButton;
125 static WMPropList *ANoCloseButton;
126 static WMPropList *ANoBorder;
127 static WMPropList *ANoHideOthers;
128 static WMPropList *ANoMouseBindings;
129 static WMPropList *ANoKeyBindings;
130 static WMPropList *ANoAppIcon;
131 static WMPropList *AKeepOnTop;
132 static WMPropList *AKeepOnBottom;
133 static WMPropList *AOmnipresent;
134 static WMPropList *ASkipWindowList;
135 static WMPropList *ASkipSwitchPanel;
136 static WMPropList *AKeepInsideScreen;
137 static WMPropList *AUnfocusable;
138 static WMPropList *AFocusAcrossWorkspace;
139 static WMPropList *AAlwaysUserIcon;
140 static WMPropList *AStartMiniaturized;
141 static WMPropList *AStartMaximized;
142 static WMPropList *ADontSaveSession;
143 static WMPropList *AEmulateAppIcon;
144 static WMPropList *AFullMaximize;
145 static WMPropList *ASharedAppIcon;
146 static WMPropList *ANoMiniaturizable;
147 #ifdef XKB_BUTTON_HINT
148 static WMPropList *ANoLanguageButton;
149 #endif
150 static WMPropList *AStartWorkspace;
151 static WMPropList *AIcon;
153 /* application wide options */
154 static WMPropList *AStartHidden;
155 static WMPropList *AnyWindow;
156 static WMPropList *EmptyString;
157 static WMPropList *Yes, *No;
159 static char *spec_text;
160 static void applySettings(WMButton *button, InspectorPanel *panel);
162 static InspectorPanel *createInspectorForWindow(WWindow *wwin, int xpos, int ypos, Bool showSelectPanel);
164 static void create_tab_window_attributes(WWindow *wwin, InspectorPanel *panel, int frame_width);
165 static void create_tab_window_advanced(WWindow *wwin, InspectorPanel *panel, int frame_width);
166 static void create_tab_icon_workspace(WWindow *wwin, InspectorPanel *panel, int frame_width);
167 static void create_tab_app_specific(WWindow *wwin, InspectorPanel *panel, int frame_width);
169 static void make_keys(void)
171 if (ANoTitlebar != NULL)
172 return;
174 AIcon = WMCreatePLString("Icon");
175 ANoTitlebar = WMCreatePLString("NoTitlebar");
176 ANoResizebar = WMCreatePLString("NoResizebar");
177 ANoMiniaturizeButton = WMCreatePLString("NoMiniaturizeButton");
178 ANoCloseButton = WMCreatePLString("NoCloseButton");
179 ANoBorder = WMCreatePLString("NoBorder");
180 ANoHideOthers = WMCreatePLString("NoHideOthers");
181 ANoMouseBindings = WMCreatePLString("NoMouseBindings");
182 ANoKeyBindings = WMCreatePLString("NoKeyBindings");
183 ANoAppIcon = WMCreatePLString("NoAppIcon");
184 AKeepOnTop = WMCreatePLString("KeepOnTop");
185 AKeepOnBottom = WMCreatePLString("KeepOnBottom");
186 AOmnipresent = WMCreatePLString("Omnipresent");
187 ASkipWindowList = WMCreatePLString("SkipWindowList");
188 ASkipSwitchPanel = WMCreatePLString("SkipSwitchPanel");
189 AKeepInsideScreen = WMCreatePLString("KeepInsideScreen");
190 AUnfocusable = WMCreatePLString("Unfocusable");
191 AFocusAcrossWorkspace = WMCreatePLString("FocusAcrossWorkspace");
192 AAlwaysUserIcon = WMCreatePLString("AlwaysUserIcon");
193 AStartMiniaturized = WMCreatePLString("StartMiniaturized");
194 AStartMaximized = WMCreatePLString("StartMaximized");
195 AStartHidden = WMCreatePLString("StartHidden");
196 ADontSaveSession = WMCreatePLString("DontSaveSession");
197 AEmulateAppIcon = WMCreatePLString("EmulateAppIcon");
198 AFullMaximize = WMCreatePLString("FullMaximize");
199 ASharedAppIcon = WMCreatePLString("SharedAppIcon");
200 ANoMiniaturizable = WMCreatePLString("NoMiniaturizable");
201 #ifdef XKB_BUTTON_HINT
202 ANoLanguageButton = WMCreatePLString("NoLanguageButton");
203 #endif
205 AStartWorkspace = WMCreatePLString("StartWorkspace");
207 AnyWindow = WMCreatePLString("*");
208 EmptyString = WMCreatePLString("");
209 Yes = WMCreatePLString("Yes");
210 No = WMCreatePLString("No");
213 static void freeInspector(InspectorPanel *panel)
215 panel->destroyed = 1;
217 if (panel->choosingIcon)
218 return;
220 WMDestroyWidget(panel->win);
221 XDestroyWindow(dpy, panel->parent);
222 wfree(panel);
225 static void destroyInspector(WCoreWindow *foo, void *data, XEvent *event)
227 InspectorPanel *panel, *tmp;
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(WMPopUpButton *bPtr, InspectorPanel *panel)
272 int page;
274 page = WMGetPopUpButtonSelectedItem(bPtr);
276 if (page == 0) {
277 WMMapWidget(panel->specFrm);
278 WMMapWidget(panel->specLbl);
279 } else if (page == 1) {
280 WMMapWidget(panel->attrFrm);
281 } else if (page == 2) {
282 WMMapWidget(panel->moreFrm);
283 } else if (page == 3) {
284 WMMapWidget(panel->iconFrm);
285 WMMapWidget(panel->wsFrm);
286 } else {
287 WMMapWidget(panel->appFrm);
290 if (page != 0) {
291 WMUnmapWidget(panel->specFrm);
292 WMUnmapWidget(panel->specLbl);
294 if (page != 1)
295 WMUnmapWidget(panel->attrFrm);
296 if (page != 2)
297 WMUnmapWidget(panel->moreFrm);
298 if (page != 3) {
299 WMUnmapWidget(panel->iconFrm);
300 WMUnmapWidget(panel->wsFrm);
302 if (page != 4 && panel->appFrm)
303 WMUnmapWidget(panel->appFrm);
306 static int showIconFor(WMScreen *scrPtr, InspectorPanel *panel, const char *wm_instance, const char *wm_class, int flags)
308 WMPixmap *pixmap = (WMPixmap *) NULL;
309 char *file = NULL, *path = NULL, *db_icon = NULL;
311 if ((flags & USE_TEXT_FIELD) != 0) {
312 file = WMGetTextFieldText(panel->fileText);
313 if (file && file[0] == 0) {
314 wfree(file);
315 file = NULL;
317 } else {
318 /* Get the application icon, default NOT included */
319 db_icon = wDefaultGetIconFile(wm_instance, wm_class, False);
320 if (db_icon != NULL)
321 file = wstrdup(db_icon);
323 if (db_icon != NULL && (flags & REVERT_TO_DEFAULT) != 0) {
324 if (file)
325 file = wstrdup(db_icon);
326 flags |= UPDATE_TEXT_FIELD;
329 if ((flags & UPDATE_TEXT_FIELD) != 0)
330 WMSetTextFieldText(panel->fileText, file);
332 if (file) {
333 path = FindImage(wPreferences.icon_path, file);
335 if (!path) {
336 char *buf;
337 int len = strlen(file) + 80;
339 buf = wmalloc(len);
340 snprintf(buf, len, _("Could not find icon \"%s\" specified for this window"), file);
341 wMessageDialog(panel->frame->screen_ptr, _("Error"), buf, _("OK"), NULL, NULL);
342 wfree(buf);
343 wfree(file);
344 return -1;
347 pixmap = WMCreatePixmapFromFile(scrPtr, path);
348 wfree(path);
350 if (!pixmap) {
351 char *buf;
352 int len = strlen(file) + 80;
354 buf = wmalloc(len);
355 snprintf(buf, len, _("Could not open specified icon \"%s\":%s"),
356 file, RMessageForError(RErrorCode));
357 wMessageDialog(panel->frame->screen_ptr, _("Error"), buf, _("OK"), NULL, NULL);
358 wfree(buf);
359 wfree(file);
360 return -1;
362 wfree(file);
365 WMSetLabelImage(panel->iconLbl, pixmap);
366 if (pixmap)
367 WMReleasePixmap(pixmap);
369 return 0;
372 static int getBool(WMPropList *value)
374 char *val;
376 if (!WMIsPLString(value))
377 return 0;
379 if (!(val = WMGetFromPLString(value)))
380 return 0;
382 if ((val[1] == '\0' &&
383 (val[0] == 'y' || val[0] == 'Y' || val[0] == 'T' ||
384 val[0] == 't' || val[0] == '1')) ||
385 (strcasecmp(val, "YES") == 0 || strcasecmp(val, "TRUE") == 0)) {
386 return 1;
387 } else if ((val[1] == '\0' &&
388 (val[0] == 'n' || val[0] == 'N' || val[0] == 'F' ||
389 val[0] == 'f' || val[0] == '0')) ||
390 (strcasecmp(val, "NO") == 0 || strcasecmp(val, "FALSE") == 0)) {
391 return 0;
392 } else {
393 wwarning(_("can't convert \"%s\" to boolean"), val);
394 return 0;
398 /* Will insert the attribute = value; pair in window's list,
399 * if it's different from the defaults.
400 * Defaults means either defaults database, or attributes saved
401 * for the default window "*". This is to let one revert options that are
402 * global because they were saved for all windows ("*"). */
403 static int
404 insertAttribute(WMPropList *dict, WMPropList *window, WMPropList *attr, WMPropList *value, int flags)
406 WMPropList *def_win, *def_value = NULL;
407 int update = 0, modified = 0;
409 if (!(flags & UPDATE_DEFAULTS) && dict) {
410 if ((def_win = WMGetFromPLDictionary(dict, AnyWindow)) != NULL)
411 def_value = WMGetFromPLDictionary(def_win, attr);
414 /* If we could not find defaults in database, fall to hardcoded values.
415 * Also this is true if we save defaults for all windows */
416 if (!def_value)
417 def_value = ((flags & IS_BOOLEAN) != 0) ? No : EmptyString;
419 if (flags & IS_BOOLEAN)
420 update = (getBool(value) != getBool(def_value));
421 else
422 update = !WMIsPropListEqualTo(value, def_value);
424 if (update) {
425 WMPutInPLDictionary(window, attr, value);
426 modified = 1;
429 return modified;
432 static void saveSettings(WMButton *button, InspectorPanel *panel)
434 WWindow *wwin = panel->inspected;
435 WDDomain *db = WDWindowAttributes;
436 WMPropList *dict = NULL;
437 WMPropList *winDic, *appDic, *value, *value1, *key = NULL, *key2;
438 char *icon_file, *buf1, *buf2;
439 int flags = 0, i = 0, different = 0, different2 = 0;
441 /* Save will apply the changes and save them */
442 applySettings(panel->applyBtn, panel);
444 if (WMGetButtonSelected(panel->instRb) != 0) {
445 key = WMCreatePLString(wwin->wm_instance);
446 } else if (WMGetButtonSelected(panel->clsRb) != 0) {
447 key = WMCreatePLString(wwin->wm_class);
448 } else if (WMGetButtonSelected(panel->bothRb) != 0) {
449 buf1 = StrConcatDot(wwin->wm_instance, wwin->wm_class);
450 key = WMCreatePLString(buf1);
451 wfree(buf1);
452 } else if (WMGetButtonSelected(panel->defaultRb) != 0) {
453 key = WMRetainPropList(AnyWindow);
454 flags = UPDATE_DEFAULTS;
457 if (!key)
458 return;
460 dict = db->dictionary;
461 if (!dict) {
462 dict = WMCreatePLDictionary(NULL, NULL);
463 if (dict) {
464 db->dictionary = dict;
465 } else {
466 WMReleasePropList(key);
467 return;
471 if (showIconFor(WMWidgetScreen(button), panel, NULL, NULL, USE_TEXT_FIELD) < 0)
472 return;
474 WMPLSetCaseSensitive(True);
476 winDic = WMCreatePLDictionary(NULL, NULL);
477 appDic = WMCreatePLDictionary(NULL, NULL);
479 /* Save the icon info */
480 /* The flag "Ignore client suplied icon is not selected" */
481 buf1 = wmalloc(4);
482 snprintf(buf1, 4, "%s", (WMGetButtonSelected(panel->alwChk) != 0) ? "Yes" : "No");
483 value1 = WMCreatePLString(buf1);
484 different |= insertAttribute(dict, winDic, AAlwaysUserIcon, value1, flags);
485 WMReleasePropList(value1);
486 wfree(buf1);
488 /* The icon filename (if exists) */
489 icon_file = WMGetTextFieldText(panel->fileText);
490 if ((icon_file) && (icon_file[0] != 0)) {
491 value = WMCreatePLString(icon_file);
492 different |= insertAttribute(dict, winDic, AIcon, value, flags);
493 different2 |= insertAttribute(dict, appDic, AIcon, value, flags);
494 WMReleasePropList(value);
495 wfree(icon_file);
498 i = WMGetPopUpButtonSelectedItem(panel->wsP) - 1;
499 if (i >= 0 && i < panel->frame->screen_ptr->workspace_count) {
500 value = WMCreatePLString(panel->frame->screen_ptr->workspaces[i]->name);
501 different |= insertAttribute(dict, winDic, AStartWorkspace, value, flags);
502 WMReleasePropList(value);
505 flags |= IS_BOOLEAN;
507 value = (WMGetButtonSelected(panel->attrChk[0]) != 0) ? Yes : No;
508 different |= insertAttribute(dict, winDic, ANoTitlebar, value, flags);
510 value = (WMGetButtonSelected(panel->attrChk[1]) != 0) ? Yes : No;
511 different |= insertAttribute(dict, winDic, ANoResizebar, value, flags);
513 value = (WMGetButtonSelected(panel->attrChk[2]) != 0) ? Yes : No;
514 different |= insertAttribute(dict, winDic, ANoCloseButton, value, flags);
516 value = (WMGetButtonSelected(panel->attrChk[3]) != 0) ? Yes : No;
517 different |= insertAttribute(dict, winDic, ANoMiniaturizeButton, value, flags);
519 value = (WMGetButtonSelected(panel->attrChk[4]) != 0) ? Yes : No;
520 different |= insertAttribute(dict, winDic, ANoBorder, value, flags);
522 value = (WMGetButtonSelected(panel->attrChk[5]) != 0) ? Yes : No;
523 different |= insertAttribute(dict, winDic, AKeepOnTop, value, flags);
525 value = (WMGetButtonSelected(panel->attrChk[6]) != 0) ? Yes : No;
526 different |= insertAttribute(dict, winDic, AKeepOnBottom, value, flags);
528 value = (WMGetButtonSelected(panel->attrChk[7]) != 0) ? Yes : No;
529 different |= insertAttribute(dict, winDic, AOmnipresent, value, flags);
531 value = (WMGetButtonSelected(panel->attrChk[8]) != 0) ? Yes : No;
532 different |= insertAttribute(dict, winDic, AStartMiniaturized, value, flags);
534 value = (WMGetButtonSelected(panel->attrChk[9]) != 0) ? Yes : No;
535 different |= insertAttribute(dict, winDic, AStartMaximized, value, flags);
537 value = (WMGetButtonSelected(panel->attrChk[10]) != 0) ? Yes : No;
538 different |= insertAttribute(dict, winDic, AFullMaximize, value, flags);
540 value = (WMGetButtonSelected(panel->moreChk[0]) != 0) ? Yes : No;
541 different |= insertAttribute(dict, winDic, ANoKeyBindings, value, flags);
543 value = (WMGetButtonSelected(panel->moreChk[1]) != 0) ? Yes : No;
544 different |= insertAttribute(dict, winDic, ANoMouseBindings, value, flags);
546 value = (WMGetButtonSelected(panel->moreChk[2]) != 0) ? Yes : No;
547 different |= insertAttribute(dict, winDic, ASkipWindowList, value, flags);
549 value = (WMGetButtonSelected(panel->moreChk[3]) != 0) ? Yes : No;
550 different |= insertAttribute(dict, winDic, ASkipSwitchPanel, value, flags);
552 value = (WMGetButtonSelected(panel->moreChk[4]) != 0) ? Yes : No;
553 different |= insertAttribute(dict, winDic, AUnfocusable, value, flags);
555 value = (WMGetButtonSelected(panel->moreChk[5]) != 0) ? Yes : No;
556 different |= insertAttribute(dict, winDic, AKeepInsideScreen, value, flags);
558 value = (WMGetButtonSelected(panel->moreChk[6]) != 0) ? Yes : No;
559 different |= insertAttribute(dict, winDic, ANoHideOthers, value, flags);
561 value = (WMGetButtonSelected(panel->moreChk[7]) != 0) ? Yes : No;
562 different |= insertAttribute(dict, winDic, ADontSaveSession, value, flags);
564 value = (WMGetButtonSelected(panel->moreChk[8]) != 0) ? Yes : No;
565 different |= insertAttribute(dict, winDic, AEmulateAppIcon, value, flags);
567 value = (WMGetButtonSelected(panel->moreChk[9]) != 0) ? Yes : No;
568 different |= insertAttribute(dict, winDic, AFocusAcrossWorkspace, value, flags);
570 value = (WMGetButtonSelected(panel->moreChk[10]) != 0) ? Yes : No;
571 different |= insertAttribute(dict, winDic, ANoMiniaturizable, value, flags);
573 #ifdef XKB_BUTTON_HINT
574 value = (WMGetButtonSelected(panel->moreChk[11]) != 0) ? Yes : No;
575 different |= insertAttribute(dict, winDic, ANoLanguageButton, value, flags);
576 #endif
578 if (wwin->main_window != None && wApplicationOf(wwin->main_window) != NULL) {
579 value = (WMGetButtonSelected(panel->appChk[0]) != 0) ? Yes : No;
580 different2 |= insertAttribute(dict, appDic, AStartHidden, value, flags);
582 value = (WMGetButtonSelected(panel->appChk[1]) != 0) ? Yes : No;
583 different2 |= insertAttribute(dict, appDic, ANoAppIcon, value, flags);
585 value = (WMGetButtonSelected(panel->appChk[2]) != 0) ? Yes : No;
586 different2 |= insertAttribute(dict, appDic, ASharedAppIcon, value, flags);
589 if (wwin->fake_group) {
590 key2 = WMCreatePLString(wwin->fake_group->identifier);
591 if (WMIsPropListEqualTo(key, key2)) {
592 WMMergePLDictionaries(winDic, appDic, True);
593 different |= different2;
594 } else {
595 WMRemoveFromPLDictionary(dict, key2);
596 if (different2)
597 WMPutInPLDictionary(dict, key2, appDic);
599 WMReleasePropList(key2);
600 WMReleasePropList(appDic);
601 } else if (wwin->main_window != wwin->client_win) {
602 WApplication *wapp = wApplicationOf(wwin->main_window);
604 if (wapp) {
605 buf2 = StrConcatDot(wapp->main_window_desc->wm_instance,
606 wapp->main_window_desc->wm_class);
607 key2 = WMCreatePLString(buf2);
608 wfree(buf2);
610 if (WMIsPropListEqualTo(key, key2)) {
611 WMMergePLDictionaries(winDic, appDic, True);
612 different |= different2;
613 } else {
614 WMRemoveFromPLDictionary(dict, key2);
615 if (different2)
616 WMPutInPLDictionary(dict, key2, appDic);
618 WMReleasePropList(key2);
619 WMReleasePropList(appDic);
621 } else {
622 WMMergePLDictionaries(winDic, appDic, True);
623 different |= different2;
624 WMReleasePropList(appDic);
627 WMRemoveFromPLDictionary(dict, key);
628 if (different)
629 WMPutInPLDictionary(dict, key, winDic);
631 WMReleasePropList(key);
632 WMReleasePropList(winDic);
634 UpdateDomainFile(db);
636 /* clean up */
637 WMPLSetCaseSensitive(False);
640 static void applySettings(WMButton *button, InspectorPanel *panel)
642 WWindow *wwin = panel->inspected;
643 WApplication *wapp = wApplicationOf(wwin->main_window);
644 int floating, sunken, skip_window_list;
645 int old_omnipresent, old_no_bind_keys, old_no_bind_mouse;
647 old_omnipresent = WFLAGP(wwin, omnipresent);
648 old_no_bind_keys = WFLAGP(wwin, no_bind_keys);
649 old_no_bind_mouse = WFLAGP(wwin, no_bind_mouse);
651 showIconFor(WMWidgetScreen(button), panel, NULL, NULL, USE_TEXT_FIELD);
653 /* Attributes... --> Window Attributes */
654 WSETUFLAG(wwin, no_titlebar, WMGetButtonSelected(panel->attrChk[0]));
655 WSETUFLAG(wwin, no_resizebar, WMGetButtonSelected(panel->attrChk[1]));
656 WSETUFLAG(wwin, no_close_button, WMGetButtonSelected(panel->attrChk[2]));
657 WSETUFLAG(wwin, no_miniaturize_button, WMGetButtonSelected(panel->attrChk[3]));
658 WSETUFLAG(wwin, no_border, WMGetButtonSelected(panel->attrChk[4]));
659 floating = WMGetButtonSelected(panel->attrChk[5]);
660 sunken = WMGetButtonSelected(panel->attrChk[6]);
661 WSETUFLAG(wwin, omnipresent, WMGetButtonSelected(panel->attrChk[7]));
662 WSETUFLAG(wwin, start_miniaturized, WMGetButtonSelected(panel->attrChk[8]));
663 WSETUFLAG(wwin, start_maximized, WMGetButtonSelected(panel->attrChk[9]));
664 WSETUFLAG(wwin, full_maximize, WMGetButtonSelected(panel->attrChk[10]));
666 /* Attributes... --> Advanced Options */
667 WSETUFLAG(wwin, no_bind_keys, WMGetButtonSelected(panel->moreChk[0]));
668 WSETUFLAG(wwin, no_bind_mouse, WMGetButtonSelected(panel->moreChk[1]));
669 skip_window_list = WMGetButtonSelected(panel->moreChk[2]);
670 WSETUFLAG(wwin, skip_switchpanel, WMGetButtonSelected(panel->moreChk[3]));
671 WSETUFLAG(wwin, no_focusable, WMGetButtonSelected(panel->moreChk[4]));
672 WSETUFLAG(wwin, dont_move_off, WMGetButtonSelected(panel->moreChk[5]));
673 WSETUFLAG(wwin, no_hide_others, WMGetButtonSelected(panel->moreChk[6]));
674 WSETUFLAG(wwin, dont_save_session, WMGetButtonSelected(panel->moreChk[7]));
675 WSETUFLAG(wwin, emulate_appicon, WMGetButtonSelected(panel->moreChk[8]));
676 WSETUFLAG(wwin, focus_across_wksp, WMGetButtonSelected(panel->moreChk[9]));
677 WSETUFLAG(wwin, no_miniaturizable, WMGetButtonSelected(panel->moreChk[10]));
678 #ifdef XKB_BUTTON_HINT
679 WSETUFLAG(wwin, no_language_button, WMGetButtonSelected(panel->moreChk[11]));
680 #endif
681 WSETUFLAG(wwin, always_user_icon, WMGetButtonSelected(panel->alwChk));
683 if (WFLAGP(wwin, no_titlebar) && wwin->flags.shaded)
684 wUnshadeWindow(wwin);
686 WSETUFLAG(wwin, no_shadeable, WFLAGP(wwin, no_titlebar));
688 if (floating) {
689 if (!WFLAGP(wwin, floating))
690 ChangeStackingLevel(wwin->frame->core, WMFloatingLevel);
691 } else if (sunken) {
692 if (!WFLAGP(wwin, sunken))
693 ChangeStackingLevel(wwin->frame->core, WMSunkenLevel);
694 } else {
695 if (WFLAGP(wwin, floating) || WFLAGP(wwin, sunken))
696 ChangeStackingLevel(wwin->frame->core, WMNormalLevel);
699 WSETUFLAG(wwin, sunken, sunken);
700 WSETUFLAG(wwin, floating, floating);
701 wwin->flags.omnipresent = 0;
703 if (WFLAGP(wwin, skip_window_list) != skip_window_list) {
704 WSETUFLAG(wwin, skip_window_list, skip_window_list);
705 UpdateSwitchMenu(wwin->screen_ptr, wwin, skip_window_list ? ACTION_REMOVE : ACTION_ADD);
706 } else {
707 if (WFLAGP(wwin, omnipresent) != old_omnipresent)
708 WMPostNotificationName(WMNChangedState, wwin, "omnipresent");
711 if (WFLAGP(wwin, no_bind_keys) != old_no_bind_keys) {
712 if (WFLAGP(wwin, no_bind_keys))
713 XUngrabKey(dpy, AnyKey, AnyModifier, wwin->frame->core->window);
714 else
715 wWindowSetKeyGrabs(wwin);
718 if (WFLAGP(wwin, no_bind_mouse) != old_no_bind_mouse)
719 wWindowResetMouseGrabs(wwin);
721 wwin->frame->flags.need_texture_change = 1;
722 wWindowConfigureBorders(wwin);
723 wFrameWindowPaint(wwin->frame);
724 wNETWMUpdateActions(wwin, False);
726 /* Can't apply emulate_appicon because it will probably cause problems. */
727 if (wapp) {
728 /* do application wide stuff */
729 WSETUFLAG(wapp->main_window_desc, start_hidden, WMGetButtonSelected(panel->appChk[0]));
730 WSETUFLAG(wapp->main_window_desc, no_appicon, WMGetButtonSelected(panel->appChk[1]));
731 WSETUFLAG(wapp->main_window_desc, shared_appicon, WMGetButtonSelected(panel->appChk[2]));
733 if (WFLAGP(wapp->main_window_desc, no_appicon))
734 unpaint_app_icon(wapp);
735 else
736 paint_app_icon(wapp);
738 char *file = WMGetTextFieldText(panel->fileText);
739 if (file[0] == 0) {
740 wfree(file);
741 file = NULL;
744 /* If always_user_icon flag is set, but the user icon is not set
745 * we use client supplied icon and we unset the flag */
746 if ((WFLAGP(wwin, always_user_icon) && (!file))) {
747 /* Show the warning */
748 char *buf;
749 int len = 100;
751 buf = wmalloc(len);
752 snprintf(buf, len, _("Ignore client supplied icon is set, but icon filename textbox is empty. Using client supplied icon"));
753 wMessageDialog(panel->frame->screen_ptr, _("Warning"), buf, _("OK"), NULL, NULL);
754 wfree(buf);
755 wfree(file);
757 /* Change the flags */
758 WSETUFLAG(wwin, always_user_icon, 0);
759 WMSetButtonSelected(panel->alwChk, 0);
762 /* After test the always_user_icon flag value before,
763 * the "else" block is used only if the flag is set and
764 * the icon text box has an icon path */
765 if (!WFLAGP(wwin, always_user_icon)) {
766 /* Change App Icon image, using the icon provided by the client */
767 if (wapp->app_icon) {
768 RImage *image = get_rimage_icon_from_wm_hints(wapp->app_icon->icon);
769 if (image) {
770 set_icon_image_from_image(wapp->app_icon->icon, image);
771 update_icon_pixmap(wapp->app_icon->icon);
772 } else {
773 wIconUpdate(wapp->app_icon->icon);
777 /* Change icon image if the app is minimized,
778 * using the icon provided by the client */
779 if (wwin->icon) {
780 RImage *image = get_rimage_icon_from_wm_hints(wwin->icon);
781 if (image) {
782 set_icon_image_from_image(wwin->icon, image);
783 update_icon_pixmap(wwin->icon);
784 } else {
785 wIconUpdate(wwin->icon);
788 } else {
789 /* Change App Icon image */
790 if (wapp->app_icon)
791 wIconChangeImageFile(wapp->app_icon->icon, file);
793 /* Change icon image if the app is minimized */
794 if (wwin->icon)
795 wIconChangeImageFile(wwin->icon, file);
798 if (file)
799 wfree(file);
802 wNETFrameExtents(wwin);
805 static void revertSettings(WMButton *button, InspectorPanel *panel)
807 WWindow *wwin = panel->inspected;
808 WApplication *wapp = wApplicationOf(wwin->main_window);
809 int i, n, workspace, level;
810 char *wm_instance = NULL, *wm_class = NULL;
812 if (panel->instRb && WMGetButtonSelected(panel->instRb) != 0)
813 wm_instance = wwin->wm_instance;
814 else if (panel->clsRb && WMGetButtonSelected(panel->clsRb) != 0)
815 wm_class = wwin->wm_class;
816 else if (panel->bothRb && WMGetButtonSelected(panel->bothRb) != 0) {
817 wm_instance = wwin->wm_instance;
818 wm_class = wwin->wm_class;
821 memset(&wwin->defined_user_flags, 0, sizeof(WWindowAttributes));
822 memset(&wwin->user_flags, 0, sizeof(WWindowAttributes));
823 memset(&wwin->client_flags, 0, sizeof(WWindowAttributes));
825 wWindowSetupInitialAttributes(wwin, &level, &workspace);
827 for (i = 0; i < (sizeof(panel->attrChk) / sizeof(panel->attrChk[0])); i++) {
828 int flag = 0;
830 switch (i) {
831 case 0:
832 flag = WFLAGP(wwin, no_titlebar);
833 break;
834 case 1:
835 flag = WFLAGP(wwin, no_resizebar);
836 break;
837 case 2:
838 flag = WFLAGP(wwin, no_close_button);
839 break;
840 case 3:
841 flag = WFLAGP(wwin, no_miniaturize_button);
842 break;
843 case 4:
844 flag = WFLAGP(wwin, no_border);
845 break;
846 case 5:
847 flag = WFLAGP(wwin, floating);
848 break;
849 case 6:
850 flag = WFLAGP(wwin, sunken);
851 break;
852 case 7:
853 flag = WFLAGP(wwin, omnipresent);
854 break;
855 case 8:
856 flag = WFLAGP(wwin, start_miniaturized);
857 break;
858 case 9:
859 flag = WFLAGP(wwin, start_maximized != 0);
860 break;
861 case 10:
862 flag = WFLAGP(wwin, full_maximize);
863 break;
865 WMSetButtonSelected(panel->attrChk[i], flag);
868 for (i = 0; i < (sizeof(panel->moreChk) / sizeof(panel->moreChk[0])); i++) {
869 int flag = 0;
871 switch (i) {
872 case 0:
873 flag = WFLAGP(wwin, no_bind_keys);
874 break;
875 case 1:
876 flag = WFLAGP(wwin, no_bind_mouse);
877 break;
878 case 2:
879 flag = WFLAGP(wwin, skip_window_list);
880 break;
881 case 3:
882 flag = WFLAGP(wwin, skip_switchpanel);
883 break;
884 case 4:
885 flag = WFLAGP(wwin, no_focusable);
886 break;
887 case 5:
888 flag = WFLAGP(wwin, dont_move_off);
889 break;
890 case 6:
891 flag = WFLAGP(wwin, no_hide_others);
892 break;
893 case 7:
894 flag = WFLAGP(wwin, dont_save_session);
895 break;
896 case 8:
897 flag = WFLAGP(wwin, emulate_appicon);
898 break;
899 case 9:
900 flag = WFLAGP(wwin, focus_across_wksp);
901 break;
902 case 10:
903 flag = WFLAGP(wwin, no_miniaturizable);
904 break;
905 #ifdef XKB_BUTTON_HINT
906 case 11:
907 flag = WFLAGP(wwin, no_language_button);
908 break;
909 #endif
911 WMSetButtonSelected(panel->moreChk[i], flag);
913 if (panel->appFrm && wapp) {
914 for (i = 0; i < (sizeof(panel->appChk) / sizeof(panel->appChk[0])); i++) {
915 int flag = 0;
917 switch (i) {
918 case 0:
919 flag = WFLAGP(wapp->main_window_desc, start_hidden);
920 break;
921 case 1:
922 flag = WFLAGP(wapp->main_window_desc, no_appicon);
923 break;
924 case 2:
925 flag = WFLAGP(wapp->main_window_desc, shared_appicon);
926 break;
928 WMSetButtonSelected(panel->appChk[i], flag);
931 WMSetButtonSelected(panel->alwChk, WFLAGP(wwin, always_user_icon));
933 showIconFor(WMWidgetScreen(panel->alwChk), panel, wm_instance, wm_class, REVERT_TO_DEFAULT);
935 n = wDefaultGetStartWorkspace(wwin->screen_ptr, wm_instance, wm_class);
937 if (n >= 0 && n < wwin->screen_ptr->workspace_count)
938 WMSetPopUpButtonSelectedItem(panel->wsP, n + 1);
939 else
940 WMSetPopUpButtonSelectedItem(panel->wsP, 0);
942 /* must auto apply, so that there wno't be internal
943 * inconsistencies between the state in the flags and
944 * the actual state of the window */
945 applySettings(panel->applyBtn, panel);
948 static void chooseIconCallback(WMWidget *self, void *clientData)
950 char *file;
951 InspectorPanel *panel = (InspectorPanel *) clientData;
952 int result;
954 panel->choosingIcon = 1;
956 WMSetButtonEnabled(panel->browseIconBtn, False);
958 result = wIconChooserDialog(panel->frame->screen_ptr, &file,
959 panel->inspected->wm_instance,
960 panel->inspected->wm_class);
962 panel->choosingIcon = 0;
964 if (!panel->destroyed) { /* kluge */
965 if (result) {
966 WMSetTextFieldText(panel->fileText, file);
967 showIconFor(WMWidgetScreen(self), panel, NULL, NULL, USE_TEXT_FIELD);
968 wfree(file);
970 WMSetButtonEnabled(panel->browseIconBtn, True);
971 } else {
972 freeInspector(panel);
976 static void textEditedObserver(void *observerData, WMNotification *notification)
978 InspectorPanel *panel = (InspectorPanel *) observerData;
980 if ((long)WMGetNotificationClientData(notification) != WMReturnTextMovement)
981 return;
983 showIconFor(WMWidgetScreen(panel->win), panel, NULL, NULL, USE_TEXT_FIELD);
986 static void selectSpecification(WMWidget *bPtr, void *data)
988 InspectorPanel *panel = (InspectorPanel *) data;
989 char *str;
990 WWindow *wwin = panel->inspected;
991 int len;
993 if (bPtr == panel->defaultRb && (wwin->wm_instance || wwin->wm_class))
994 WMSetButtonEnabled(panel->applyBtn, False);
995 else
996 WMSetButtonEnabled(panel->applyBtn, True);
998 len = 16 + strlen(wwin->wm_instance ? wwin->wm_instance : "?")
999 + strlen(wwin->wm_class ? wwin->wm_class : "?");
1001 str = wmalloc(len);
1003 snprintf(str, len, _("Inspecting %s.%s"),
1004 wwin->wm_instance ? wwin->wm_instance : "?", wwin->wm_class ? wwin->wm_class : "?");
1006 wFrameWindowChangeTitle(panel->frame->frame, str);
1008 wfree(str);
1011 static void selectWindow(WMWidget *bPtr, void *data)
1013 InspectorPanel *panel = (InspectorPanel *) data;
1014 WWindow *wwin = panel->inspected;
1015 WScreen *scr = wwin->screen_ptr;
1016 XEvent event;
1017 WWindow *iwin;
1019 if (XGrabPointer(dpy, scr->root_win, True,
1020 ButtonPressMask, GrabModeAsync, GrabModeAsync, None,
1021 wCursor[WCUR_SELECT], CurrentTime) != GrabSuccess) {
1022 wwarning("could not grab mouse pointer");
1023 return;
1026 WMSetLabelText(panel->specLbl, _("Click in the window you wish to inspect."));
1027 WMMaskEvent(dpy, ButtonPressMask, &event);
1028 XUngrabPointer(dpy, CurrentTime);
1030 iwin = wWindowFor(event.xbutton.subwindow);
1031 if (iwin && !iwin->flags.internal_window && iwin != wwin && !iwin->flags.inspector_open) {
1032 iwin->flags.inspector_open = 1;
1033 iwin->inspector = createInspectorForWindow(iwin,
1034 panel->frame->frame_x, panel->frame->frame_y, True);
1035 wCloseInspectorForWindow(wwin);
1036 } else {
1037 WMSetLabelText(panel->specLbl, spec_text);
1041 static InspectorPanel *createInspectorForWindow(WWindow *wwin, int xpos, int ypos, Bool showSelectPanel)
1043 WScreen *scr = wwin->screen_ptr;
1044 InspectorPanel *panel;
1045 Window parent;
1046 char *str = NULL, *tmp = NULL;
1047 int x, y, btn_width, frame_width;
1048 WMButton *selectedBtn = NULL;
1050 spec_text = _("The configuration will apply to all\n"
1051 "windows that have their WM_CLASS\n"
1052 "property set to the above selected\n" "name, when saved.");
1054 panel = wmalloc(sizeof(InspectorPanel));
1055 memset(panel, 0, sizeof(InspectorPanel));
1057 panel->destroyed = 0;
1058 panel->inspected = wwin;
1059 panel->nextPtr = panelList;
1060 panelList = panel;
1061 panel->win = WMCreateWindow(scr->wmscreen, "windowInspector");
1062 WMResizeWidget(panel->win, PWIDTH, PHEIGHT);
1064 /**** create common stuff ****/
1065 /* command buttons */
1066 btn_width = (PWIDTH - (2 * 15) - (2 * 10)) / 3;
1067 panel->saveBtn = WMCreateCommandButton(panel->win);
1068 WMSetButtonAction(panel->saveBtn, (WMAction *) saveSettings, panel);
1069 WMMoveWidget(panel->saveBtn, (2 * (btn_width + 10)) + 15, PHEIGHT - 40);
1070 WMSetButtonText(panel->saveBtn, _("Save"));
1071 WMResizeWidget(panel->saveBtn, btn_width, 28);
1072 if (wPreferences.flags.noupdates || !(wwin->wm_class || wwin->wm_instance))
1073 WMSetButtonEnabled(panel->saveBtn, False);
1075 panel->applyBtn = WMCreateCommandButton(panel->win);
1076 WMSetButtonAction(panel->applyBtn, (WMAction *) applySettings, panel);
1077 WMMoveWidget(panel->applyBtn, btn_width + 10 + 15, PHEIGHT - 40);
1078 WMSetButtonText(panel->applyBtn, _("Apply"));
1079 WMResizeWidget(panel->applyBtn, btn_width, 28);
1081 panel->revertBtn = WMCreateCommandButton(panel->win);
1082 WMSetButtonAction(panel->revertBtn, (WMAction *) revertSettings, panel);
1083 WMMoveWidget(panel->revertBtn, 15, PHEIGHT - 40);
1084 WMSetButtonText(panel->revertBtn, _("Reload"));
1085 WMResizeWidget(panel->revertBtn, btn_width, 28);
1087 /* page selection popup button */
1088 panel->pagePopUp = WMCreatePopUpButton(panel->win);
1089 WMSetPopUpButtonAction(panel->pagePopUp, (WMAction *) changePage, panel);
1090 WMMoveWidget(panel->pagePopUp, 25, 15);
1091 WMResizeWidget(panel->pagePopUp, PWIDTH - 50, 20);
1093 WMAddPopUpButtonItem(panel->pagePopUp, _("Window Specification"));
1094 WMAddPopUpButtonItem(panel->pagePopUp, _("Window Attributes"));
1095 WMAddPopUpButtonItem(panel->pagePopUp, _("Advanced Options"));
1096 WMAddPopUpButtonItem(panel->pagePopUp, _("Icon and Initial Workspace"));
1097 WMAddPopUpButtonItem(panel->pagePopUp, _("Application Specific"));
1099 /**** window spec ****/
1100 frame_width = PWIDTH - (2 * 15);
1102 panel->specFrm = WMCreateFrame(panel->win);
1103 WMSetFrameTitle(panel->specFrm, _("Window Specification"));
1104 WMMoveWidget(panel->specFrm, 15, 65);
1105 WMResizeWidget(panel->specFrm, frame_width, 145);
1107 panel->defaultRb = WMCreateRadioButton(panel->specFrm);
1108 WMMoveWidget(panel->defaultRb, 10, 78);
1109 WMResizeWidget(panel->defaultRb, frame_width - (2 * 10), 20);
1110 WMSetButtonText(panel->defaultRb, _("Defaults for all windows"));
1111 WMSetButtonSelected(panel->defaultRb, False);
1112 WMSetButtonAction(panel->defaultRb, selectSpecification, panel);
1114 if (wwin->wm_class && wwin->wm_instance) {
1115 tmp = wstrconcat(wwin->wm_instance, ".");
1116 str = wstrconcat(tmp, wwin->wm_class);
1118 panel->bothRb = WMCreateRadioButton(panel->specFrm);
1119 WMMoveWidget(panel->bothRb, 10, 18);
1120 WMResizeWidget(panel->bothRb, frame_width - (2 * 10), 20);
1121 WMSetButtonText(panel->bothRb, str);
1122 wfree(tmp);
1123 wfree(str);
1124 WMGroupButtons(panel->defaultRb, panel->bothRb);
1126 if (!selectedBtn)
1127 selectedBtn = panel->bothRb;
1129 WMSetButtonAction(panel->bothRb, selectSpecification, panel);
1132 if (wwin->wm_instance) {
1133 panel->instRb = WMCreateRadioButton(panel->specFrm);
1134 WMMoveWidget(panel->instRb, 10, 38);
1135 WMResizeWidget(panel->instRb, frame_width - (2 * 10), 20);
1136 WMSetButtonText(panel->instRb, wwin->wm_instance);
1137 WMGroupButtons(panel->defaultRb, panel->instRb);
1139 if (!selectedBtn)
1140 selectedBtn = panel->instRb;
1142 WMSetButtonAction(panel->instRb, selectSpecification, panel);
1145 if (wwin->wm_class) {
1146 panel->clsRb = WMCreateRadioButton(panel->specFrm);
1147 WMMoveWidget(panel->clsRb, 10, 58);
1148 WMResizeWidget(panel->clsRb, frame_width - (2 * 10), 20);
1149 WMSetButtonText(panel->clsRb, wwin->wm_class);
1150 WMGroupButtons(panel->defaultRb, panel->clsRb);
1152 if (!selectedBtn)
1153 selectedBtn = panel->clsRb;
1155 WMSetButtonAction(panel->clsRb, selectSpecification, panel);
1158 panel->selWinB = WMCreateCommandButton(panel->specFrm);
1159 WMMoveWidget(panel->selWinB, 20, 145 - 24 - 10);
1160 WMResizeWidget(panel->selWinB, frame_width - 2 * 10 - 20, 24);
1161 WMSetButtonText(panel->selWinB, _("Select window"));
1162 WMSetButtonAction(panel->selWinB, selectWindow, panel);
1164 panel->specLbl = WMCreateLabel(panel->win);
1165 WMMoveWidget(panel->specLbl, 15, 210);
1166 WMResizeWidget(panel->specLbl, frame_width, 100);
1167 WMSetLabelText(panel->specLbl, spec_text);
1168 WMSetLabelWraps(panel->specLbl, True);
1170 WMSetLabelTextAlignment(panel->specLbl, WALeft);
1172 /**** attributes ****/
1173 create_tab_window_attributes(wwin, panel, frame_width);
1174 create_tab_window_advanced(wwin, panel, frame_width);
1175 create_tab_icon_workspace(wwin, panel, frame_width);
1176 create_tab_app_specific(wwin, panel, frame_width);
1178 /* if the window is a transient, don't let it have a miniaturize button */
1179 if (wwin->transient_for != None && wwin->transient_for != scr->root_win)
1180 WMSetButtonEnabled(panel->attrChk[3], False);
1181 else
1182 WMSetButtonEnabled(panel->attrChk[3], True);
1184 if (!wwin->wm_class && !wwin->wm_instance)
1185 WMSetPopUpButtonItemEnabled(panel->pagePopUp, 0, False);
1187 WMRealizeWidget(panel->win);
1189 WMMapSubwidgets(panel->win);
1190 WMMapSubwidgets(panel->specFrm);
1191 WMMapSubwidgets(panel->attrFrm);
1192 WMMapSubwidgets(panel->moreFrm);
1193 WMMapSubwidgets(panel->iconFrm);
1194 WMMapSubwidgets(panel->wsFrm);
1195 if (panel->appFrm)
1196 WMMapSubwidgets(panel->appFrm);
1198 if (showSelectPanel) {
1199 WMSetPopUpButtonSelectedItem(panel->pagePopUp, 0);
1200 changePage(panel->pagePopUp, panel);
1201 } else {
1202 WMSetPopUpButtonSelectedItem(panel->pagePopUp, 1);
1203 changePage(panel->pagePopUp, panel);
1206 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, PWIDTH, PHEIGHT, 0, 0, 0);
1207 XSelectInput(dpy, parent, KeyPressMask | KeyReleaseMask);
1208 panel->parent = parent;
1209 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
1211 WMMapWidget(panel->win);
1213 XSetTransientForHint(dpy, parent, wwin->client_win);
1215 if (xpos == UNDEFINED_POS) {
1216 x = wwin->frame_x + wwin->frame->core->width / 2;
1217 y = wwin->frame_y + wwin->frame->top_width * 2;
1218 if (y + PHEIGHT > scr->scr_height)
1219 y = scr->scr_height - PHEIGHT - 30;
1220 if (x + PWIDTH > scr->scr_width)
1221 x = scr->scr_width - PWIDTH;
1222 } else {
1223 x = xpos;
1224 y = ypos;
1227 panel->frame = wManageInternalWindow(scr, parent, wwin->client_win, "Inspector", x, y, PWIDTH, PHEIGHT);
1229 if (!selectedBtn)
1230 selectedBtn = panel->defaultRb;
1232 WMSetButtonSelected(selectedBtn, True);
1233 selectSpecification(selectedBtn, panel);
1235 /* kluge to know who should get the key events */
1236 panel->frame->client_leader = WMWidgetXID(panel->win);
1238 WSETUFLAG(panel->frame, no_closable, 0);
1239 WSETUFLAG(panel->frame, no_close_button, 0);
1240 wWindowUpdateButtonImages(panel->frame);
1241 wFrameWindowShowButton(panel->frame->frame, WFF_RIGHT_BUTTON);
1242 panel->frame->frame->on_click_right = destroyInspector;
1244 wWindowMap(panel->frame);
1246 showIconFor(WMWidgetScreen(panel->alwChk), panel, wwin->wm_instance, wwin->wm_class, UPDATE_TEXT_FIELD);
1248 return panel;
1251 void wShowInspectorForWindow(WWindow *wwin)
1253 if (wwin->flags.inspector_open)
1254 return;
1256 WMSetBalloonEnabled(wwin->screen_ptr->wmscreen, wPreferences.help_balloon);
1258 make_keys();
1259 wwin->flags.inspector_open = 1;
1260 wwin->inspector = createInspectorForWindow(wwin, UNDEFINED_POS, UNDEFINED_POS, False);
1263 void wHideInspectorForWindow(WWindow *wwin)
1265 WWindow *pwin = wwin->inspector->frame;
1267 wWindowUnmap(pwin);
1268 pwin->flags.hidden = 1;
1270 wClientSetState(pwin, IconicState, None);
1273 void wUnhideInspectorForWindow(WWindow *wwin)
1275 WWindow *pwin = wwin->inspector->frame;
1277 pwin->flags.hidden = 0;
1278 pwin->flags.mapped = 1;
1279 XMapWindow(dpy, pwin->client_win);
1280 XMapWindow(dpy, pwin->frame->core->window);
1281 wClientSetState(pwin, NormalState, None);
1284 WWindow *wGetWindowOfInspectorForWindow(WWindow *wwin)
1286 if (!wwin->inspector)
1287 return NULL;
1289 assert(wwin->flags.inspector_open != 0);
1290 return wwin->inspector->frame;
1293 void wCloseInspectorForWindow(WWindow *wwin)
1295 WWindow *pwin = wwin->inspector->frame; /* the inspector window */
1297 (*pwin->frame->on_click_right) (NULL, pwin, NULL);
1300 static void create_tab_window_attributes(WWindow *wwin, InspectorPanel *panel, int frame_width)
1302 int i = 0;
1303 char *caption = NULL, *descr = NULL;
1304 int flag = 0;
1306 panel->attrFrm = WMCreateFrame(panel->win);
1307 WMSetFrameTitle(panel->attrFrm, _("Attributes"));
1308 WMMoveWidget(panel->attrFrm, 15, 45);
1309 WMResizeWidget(panel->attrFrm, frame_width, 250);
1311 for (i = 0; i < (sizeof(panel->attrChk) / sizeof(panel->attrChk[0])); i++) {
1312 switch (i) {
1313 case 0:
1314 caption = _("Disable titlebar");
1315 flag = WFLAGP(wwin, no_titlebar);
1316 descr = _("Remove the titlebar of this window.\n"
1317 "To access the window commands menu of a window\n"
1318 "without it's titlebar, press Control+Esc (or the\n"
1319 "equivalent shortcut, if you changed the default\n" "settings).");
1320 break;
1321 case 1:
1322 caption = _("Disable resizebar");
1323 flag = WFLAGP(wwin, no_resizebar);
1324 descr = _("Remove the resizebar of this window.");
1325 break;
1326 case 2:
1327 caption = _("Disable close button");
1328 flag = WFLAGP(wwin, no_close_button);
1329 descr = _("Remove the `close window' button of this window.");
1330 break;
1331 case 3:
1332 caption = _("Disable miniaturize button");
1333 flag = WFLAGP(wwin, no_miniaturize_button);
1334 descr = _("Remove the `miniaturize window' button of the window.");
1335 break;
1336 case 4:
1337 caption = _("Disable border");
1338 flag = WFLAGP(wwin, no_border);
1339 descr = _("Remove the 1 pixel black border around the window.");
1340 break;
1341 case 5:
1342 caption = _("Keep on top (floating)");
1343 flag = WFLAGP(wwin, floating);
1344 descr = _("Keep the window over other windows, not allowing\n" "them to cover it.");
1345 break;
1346 case 6:
1347 caption = _("Keep at bottom (sunken)");
1348 flag = WFLAGP(wwin, sunken);
1349 descr = _("Keep the window under all other windows.");
1350 break;
1351 case 7:
1352 caption = _("Omnipresent");
1353 flag = WFLAGP(wwin, omnipresent);
1354 descr = _("Make window present in all workspaces.");
1355 break;
1356 case 8:
1357 caption = _("Start miniaturized");
1358 flag = WFLAGP(wwin, start_miniaturized);
1359 descr = _("Make the window be automatically miniaturized when it's\n" "first shown.");
1360 break;
1361 case 9:
1362 caption = _("Start maximized");
1363 flag = WFLAGP(wwin, start_maximized != 0);
1364 descr = _("Make the window be automatically maximized when it's\n" "first shown.");
1365 break;
1366 case 10:
1367 caption = _("Full screen maximization");
1368 flag = WFLAGP(wwin, full_maximize);
1369 descr = _("Make the window use the whole screen space when it's\n"
1370 "maximized. The titlebar and resizebar will be moved\n"
1371 "to outside the screen.");
1372 break;
1374 panel->attrChk[i] = WMCreateSwitchButton(panel->attrFrm);
1375 WMMoveWidget(panel->attrChk[i], 10, 20 * (i + 1));
1376 WMResizeWidget(panel->attrChk[i], frame_width - 15, 20);
1377 WMSetButtonSelected(panel->attrChk[i], flag);
1378 WMSetButtonText(panel->attrChk[i], caption);
1380 WMSetBalloonTextForView(descr, WMWidgetView(panel->attrChk[i]));
1384 static void create_tab_window_advanced(WWindow *wwin, InspectorPanel *panel, int frame_width)
1386 int i = 0;
1387 char *caption = NULL, *descr = NULL;
1388 int flag = 0;
1390 panel->moreFrm = WMCreateFrame(panel->win);
1391 WMSetFrameTitle(panel->moreFrm, _("Advanced"));
1392 WMMoveWidget(panel->moreFrm, 15, 45);
1393 WMResizeWidget(panel->moreFrm, frame_width, 265);
1395 for (i = 0; i < (sizeof(panel->moreChk) / sizeof(panel->moreChk[0])); i++) {
1396 switch (i) {
1397 case 0:
1398 caption = _("Do not bind keyboard shortcuts");
1399 flag = WFLAGP(wwin, no_bind_keys);
1400 descr = _("Do not bind keyboard shortcuts from Window Maker\n"
1401 "when this window is focused. This will allow the\n"
1402 "window to receive all key combinations regardless\n"
1403 "of your shortcut configuration.");
1404 break;
1405 case 1:
1406 caption = _("Do not bind mouse clicks");
1407 flag = WFLAGP(wwin, no_bind_mouse);
1408 descr = _("Do not bind mouse actions, such as `Alt'+drag\n"
1409 "in the window (when alt is the modifier you have\n" "configured).");
1410 break;
1411 case 2:
1412 caption = _("Do not show in the window list");
1413 flag = WFLAGP(wwin, skip_window_list);
1414 descr = _("Do not list the window in the window list menu.");
1415 break;
1416 case 3:
1417 caption = _("Do not show in the switch panel");
1418 flag = WFLAGP(wwin, skip_switchpanel);
1419 descr = _("Do not include in switchpanel while alternating windows.");
1420 break;
1421 case 4:
1422 caption = _("Do not let it take focus");
1423 flag = WFLAGP(wwin, no_focusable);
1424 descr = _("Do not let the window take keyboard focus when you\n" "click on it.");
1425 break;
1426 case 5:
1427 caption = _("Keep inside screen");
1428 flag = WFLAGP(wwin, dont_move_off);
1429 descr = _("Do not allow the window to move itself completely\n"
1430 "outside the screen. For bug compatibility.\n");
1431 break;
1432 case 6:
1433 caption = _("Ignore 'Hide Others'");
1434 flag = WFLAGP(wwin, no_hide_others);
1435 descr = _("Do not hide the window when issuing the\n" "`HideOthers' command.");
1436 break;
1437 case 7:
1438 caption = _("Ignore 'Save Session'");
1439 flag = WFLAGP(wwin, dont_save_session);
1440 descr = _("Do not save the associated application in the\n"
1441 "session's state, so that it won't be restarted\n"
1442 "together with other applications when Window Maker\n" "starts.");
1443 break;
1444 case 8:
1445 caption = _("Emulate application icon");
1446 flag = WFLAGP(wwin, emulate_appicon);
1447 descr = _("Make this window act as an application that provides\n"
1448 "enough information to Window Maker for a dockable\n"
1449 "application icon to be created.");
1450 break;
1451 case 9:
1452 caption = _("Focus across workspaces");
1453 flag = WFLAGP(wwin, focus_across_wksp);
1454 descr = _("Allow Window Maker to switch workspace to satisfy\n"
1455 "a focus request (annoying).");
1456 break;
1457 case 10:
1458 caption = _("Do not let it be minimized");
1459 flag = WFLAGP(wwin, no_miniaturizable);
1460 descr = _("Do not let the window of this application be\n"
1461 "minimized.\n");
1462 break;
1463 #ifdef XKB_BUTTON_HINT
1464 case 11:
1465 caption = _("Disable language button");
1466 flag = WFLAGP(wwin, no_language_button);
1467 descr = _("Remove the `toggle language' button of the window.");
1468 break;
1469 #endif
1471 panel->moreChk[i] = WMCreateSwitchButton(panel->moreFrm);
1472 WMMoveWidget(panel->moreChk[i], 10, 20 * (i + 1));
1473 WMResizeWidget(panel->moreChk[i], frame_width - 15, 20);
1474 WMSetButtonSelected(panel->moreChk[i], flag);
1475 WMSetButtonText(panel->moreChk[i], caption);
1477 WMSetBalloonTextForView(descr, WMWidgetView(panel->moreChk[i]));
1481 static void create_tab_icon_workspace(WWindow *wwin, InspectorPanel *panel, int frame_width)
1483 WScreen *scr = wwin->screen_ptr;
1484 int i = 0;
1486 /* miniwindow/workspace */
1487 panel->iconFrm = WMCreateFrame(panel->win);
1488 WMMoveWidget(panel->iconFrm, 15, 50);
1489 WMResizeWidget(panel->iconFrm, PWIDTH - (2 * 15), 170);
1490 WMSetFrameTitle(panel->iconFrm, _("Miniwindow Image"));
1492 panel->iconLbl = WMCreateLabel(panel->iconFrm);
1493 WMMoveWidget(panel->iconLbl, PWIDTH - (2 * 15) - 22 - 64, 20);
1494 WMResizeWidget(panel->iconLbl, 64, 64);
1495 WMSetLabelRelief(panel->iconLbl, WRGroove);
1496 WMSetLabelImagePosition(panel->iconLbl, WIPImageOnly);
1498 panel->browseIconBtn = WMCreateCommandButton(panel->iconFrm);
1499 WMSetButtonAction(panel->browseIconBtn, chooseIconCallback, panel);
1500 WMMoveWidget(panel->browseIconBtn, 22, 32);
1501 WMResizeWidget(panel->browseIconBtn, 120, 26);
1502 WMSetButtonText(panel->browseIconBtn, _("Browse..."));
1504 panel->fileLbl = WMCreateLabel(panel->iconFrm);
1505 WMMoveWidget(panel->fileLbl, 20, 85);
1506 WMResizeWidget(panel->fileLbl, PWIDTH - (2 * 15) - (2 * 20), 14);
1507 WMSetLabelText(panel->fileLbl, _("Icon filename:"));
1509 panel->fileText = WMCreateTextField(panel->iconFrm);
1510 WMMoveWidget(panel->fileText, 20, 105);
1511 WMResizeWidget(panel->fileText, PWIDTH - (2 * 20) - (2 * 15), 20);
1512 WMSetTextFieldText(panel->fileText, NULL);
1513 WMAddNotificationObserver(textEditedObserver, panel, WMTextDidEndEditingNotification, panel->fileText);
1515 panel->alwChk = WMCreateSwitchButton(panel->iconFrm);
1516 WMMoveWidget(panel->alwChk, 20, 130);
1517 WMResizeWidget(panel->alwChk, PWIDTH - (2 * 15) - (2 * 15), 30);
1518 WMSetButtonText(panel->alwChk, _("Ignore client supplied icon"));
1519 WMSetButtonSelected(panel->alwChk, WFLAGP(wwin, always_user_icon));
1521 panel->wsFrm = WMCreateFrame(panel->win);
1522 WMMoveWidget(panel->wsFrm, 15, 225);
1523 WMResizeWidget(panel->wsFrm, PWIDTH - (2 * 15), 70);
1524 WMSetFrameTitle(panel->wsFrm, _("Initial Workspace"));
1526 WMSetBalloonTextForView(_("The workspace to place the window when it's"
1527 "first shown."), WMWidgetView(panel->wsFrm));
1529 panel->wsP = WMCreatePopUpButton(panel->wsFrm);
1530 WMMoveWidget(panel->wsP, 20, 30);
1531 WMResizeWidget(panel->wsP, PWIDTH - (2 * 15) - (2 * 20), 20);
1532 WMAddPopUpButtonItem(panel->wsP, _("Nowhere in particular"));
1534 for (i = 0; i < wwin->screen_ptr->workspace_count; i++)
1535 WMAddPopUpButtonItem(panel->wsP, scr->workspaces[i]->name);
1537 i = wDefaultGetStartWorkspace(wwin->screen_ptr, wwin->wm_instance, wwin->wm_class);
1538 if (i >= 0 && i <= wwin->screen_ptr->workspace_count)
1539 WMSetPopUpButtonSelectedItem(panel->wsP, i + 1);
1540 else
1541 WMSetPopUpButtonSelectedItem(panel->wsP, 0);
1544 static void create_tab_app_specific(WWindow *wwin, InspectorPanel *panel, int frame_width)
1546 WScreen *scr = wwin->screen_ptr;
1547 int i = 0, flag = 0, tmp;
1548 char *caption = NULL, *descr = NULL;
1551 if (wwin->main_window != None) {
1552 WApplication *wapp = wApplicationOf(wwin->main_window);
1554 panel->appFrm = WMCreateFrame(panel->win);
1555 WMSetFrameTitle(panel->appFrm, _("Application Attributes"));
1556 WMMoveWidget(panel->appFrm, 15, 50);
1557 WMResizeWidget(panel->appFrm, frame_width, 240);
1559 for (i = 0; i < (sizeof(panel->appChk) / sizeof(panel->appChk[0])); i++) {
1560 switch (i) {
1561 case 0:
1562 caption = _("Start hidden");
1563 flag = WFLAGP(wapp->main_window_desc, start_hidden);
1564 descr = _("Automatically hide application when it's started.");
1565 break;
1566 case 1:
1567 caption = _("No application icon");
1568 flag = WFLAGP(wapp->main_window_desc, no_appicon);
1569 descr = _("Disable the application icon for the application.\n"
1570 "Note that you won't be able to dock it anymore,\n"
1571 "and any icons that are already docked will stop\n"
1572 "working correctly.");
1573 break;
1574 case 2:
1575 caption = _("Shared application icon");
1576 flag = WFLAGP(wapp->main_window_desc, shared_appicon);
1577 descr = _("Use a single shared application icon for all of\n"
1578 "the instances of this application.\n");
1579 break;
1581 panel->appChk[i] = WMCreateSwitchButton(panel->appFrm);
1582 WMMoveWidget(panel->appChk[i], 10, 20 * (i + 1));
1583 WMResizeWidget(panel->appChk[i], 205, 20);
1584 WMSetButtonSelected(panel->appChk[i], flag);
1585 WMSetButtonText(panel->appChk[i], caption);
1586 WMSetBalloonTextForView(descr, WMWidgetView(panel->appChk[i]));
1589 if (WFLAGP(wwin, emulate_appicon)) {
1590 WMSetButtonEnabled(panel->appChk[1], False);
1591 WMSetButtonEnabled(panel->moreChk[7], True);
1592 } else {
1593 WMSetButtonEnabled(panel->appChk[1], True);
1594 WMSetButtonEnabled(panel->moreChk[7], False);
1596 } else {
1597 if ((wwin->transient_for != None && wwin->transient_for != scr->root_win)
1598 || !wwin->wm_class || !wwin->wm_instance)
1599 tmp = False;
1600 else
1601 tmp = True;
1603 WMSetButtonEnabled(panel->moreChk[7], tmp);
1605 WMSetPopUpButtonItemEnabled(panel->pagePopUp, 4, False);
1606 panel->appFrm = NULL;