wmaker: Marked args as unused at places where conditional code is used
[wmaker-crm.git] / src / winspector.c
blobd861b9cc46fe6c322c24b6752dbba68196fa9184
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(WMButton *button, InspectorPanel *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 panel = panelList;
226 while (panel->frame != data)
227 panel = panel->nextPtr;
229 if (panelList == panel) {
230 panelList = panel->nextPtr;
231 } else {
232 tmp = panelList;
233 while (tmp->nextPtr != panel)
234 tmp = tmp->nextPtr;
236 tmp->nextPtr = panel->nextPtr;
238 panel->inspected->flags.inspector_open = 0;
239 panel->inspected->inspector = NULL;
241 WMRemoveNotificationObserver(panel);
243 wWindowUnmap(panel->frame);
244 wUnmanageWindow(panel->frame, True, False);
246 freeInspector(panel);
249 void wDestroyInspectorPanels(void)
251 InspectorPanel *panel;
253 while (panelList != NULL) {
254 panel = panelList;
255 panelList = panelList->nextPtr;
256 wUnmanageWindow(panel->frame, False, False);
257 WMDestroyWidget(panel->win);
259 panel->inspected->flags.inspector_open = 0;
260 panel->inspected->inspector = NULL;
262 wfree(panel);
266 static void changePage(WMPopUpButton *bPtr, InspectorPanel *panel)
268 int page;
270 page = WMGetPopUpButtonSelectedItem(bPtr);
272 if (page == 0) {
273 WMMapWidget(panel->specFrm);
274 WMMapWidget(panel->specLbl);
275 } else if (page == 1) {
276 WMMapWidget(panel->attrFrm);
277 } else if (page == 2) {
278 WMMapWidget(panel->moreFrm);
279 } else if (page == 3) {
280 WMMapWidget(panel->iconFrm);
281 WMMapWidget(panel->wsFrm);
282 } else {
283 WMMapWidget(panel->appFrm);
286 if (page != 0) {
287 WMUnmapWidget(panel->specFrm);
288 WMUnmapWidget(panel->specLbl);
290 if (page != 1)
291 WMUnmapWidget(panel->attrFrm);
292 if (page != 2)
293 WMUnmapWidget(panel->moreFrm);
294 if (page != 3) {
295 WMUnmapWidget(panel->iconFrm);
296 WMUnmapWidget(panel->wsFrm);
298 if (page != 4 && panel->appFrm)
299 WMUnmapWidget(panel->appFrm);
302 static int showIconFor(WMScreen *scrPtr, InspectorPanel *panel, const char *wm_instance, const char *wm_class, int flags)
304 WMPixmap *pixmap = (WMPixmap *) NULL;
305 char *file = NULL, *path = NULL, *db_icon = NULL;
307 if ((flags & USE_TEXT_FIELD) != 0) {
308 file = WMGetTextFieldText(panel->fileText);
309 if (file && file[0] == 0) {
310 wfree(file);
311 file = NULL;
313 } else {
314 /* Get the application icon, default NOT included */
315 db_icon = wDefaultGetIconFile(wm_instance, wm_class, False);
316 if (db_icon != NULL)
317 file = wstrdup(db_icon);
319 if (db_icon != NULL && (flags & REVERT_TO_DEFAULT) != 0) {
320 if (file)
321 file = wstrdup(db_icon);
322 flags |= UPDATE_TEXT_FIELD;
325 if ((flags & UPDATE_TEXT_FIELD) != 0)
326 WMSetTextFieldText(panel->fileText, file);
328 if (file) {
329 path = FindImage(wPreferences.icon_path, file);
331 if (!path) {
332 char *buf;
333 int len = strlen(file) + 80;
335 buf = wmalloc(len);
336 snprintf(buf, len, _("Could not find icon \"%s\" specified for this window"), file);
337 wMessageDialog(panel->frame->screen_ptr, _("Error"), buf, _("OK"), NULL, NULL);
338 wfree(buf);
339 wfree(file);
340 return -1;
343 pixmap = WMCreatePixmapFromFile(scrPtr, path);
344 wfree(path);
346 if (!pixmap) {
347 char *buf;
348 int len = strlen(file) + 80;
350 buf = wmalloc(len);
351 snprintf(buf, len, _("Could not open specified icon \"%s\":%s"),
352 file, RMessageForError(RErrorCode));
353 wMessageDialog(panel->frame->screen_ptr, _("Error"), buf, _("OK"), NULL, NULL);
354 wfree(buf);
355 wfree(file);
356 return -1;
358 wfree(file);
361 WMSetLabelImage(panel->iconLbl, pixmap);
362 if (pixmap)
363 WMReleasePixmap(pixmap);
365 return 0;
368 static int getBool(WMPropList *value)
370 char *val;
372 if (!WMIsPLString(value))
373 return 0;
375 if (!(val = WMGetFromPLString(value)))
376 return 0;
378 if ((val[1] == '\0' &&
379 (val[0] == 'y' || val[0] == 'Y' || val[0] == 'T' ||
380 val[0] == 't' || val[0] == '1')) ||
381 (strcasecmp(val, "YES") == 0 || strcasecmp(val, "TRUE") == 0)) {
382 return 1;
383 } else if ((val[1] == '\0' &&
384 (val[0] == 'n' || val[0] == 'N' || val[0] == 'F' ||
385 val[0] == 'f' || val[0] == '0')) ||
386 (strcasecmp(val, "NO") == 0 || strcasecmp(val, "FALSE") == 0)) {
387 return 0;
388 } else {
389 wwarning(_("can't convert \"%s\" to boolean"), val);
390 return 0;
394 /* Will insert the attribute = value; pair in window's list,
395 * if it's different from the defaults.
396 * Defaults means either defaults database, or attributes saved
397 * for the default window "*". This is to let one revert options that are
398 * global because they were saved for all windows ("*"). */
399 static int
400 insertAttribute(WMPropList *dict, WMPropList *window, WMPropList *attr, WMPropList *value, int flags)
402 WMPropList *def_win, *def_value = NULL;
403 int update = 0, modified = 0;
405 if (!(flags & UPDATE_DEFAULTS) && dict) {
406 if ((def_win = WMGetFromPLDictionary(dict, AnyWindow)) != NULL)
407 def_value = WMGetFromPLDictionary(def_win, attr);
410 /* If we could not find defaults in database, fall to hardcoded values.
411 * Also this is true if we save defaults for all windows */
412 if (!def_value)
413 def_value = ((flags & IS_BOOLEAN) != 0) ? No : EmptyString;
415 if (flags & IS_BOOLEAN)
416 update = (getBool(value) != getBool(def_value));
417 else
418 update = !WMIsPropListEqualTo(value, def_value);
420 if (update) {
421 WMPutInPLDictionary(window, attr, value);
422 modified = 1;
425 return modified;
428 static void saveSettings(WMButton *button, InspectorPanel *panel)
430 WWindow *wwin = panel->inspected;
431 WDDomain *db = w_global.domain.window_attr;
432 WMPropList *dict = NULL;
433 WMPropList *winDic, *appDic, *value, *value1, *key = NULL, *key2;
434 char *icon_file, *buf1, *buf2;
435 int flags = 0, i = 0, different = 0, different2 = 0;
437 /* Save will apply the changes and save them */
438 applySettings(panel->applyBtn, panel);
440 if (WMGetButtonSelected(panel->instRb) != 0) {
441 key = WMCreatePLString(wwin->wm_instance);
442 } else if (WMGetButtonSelected(panel->clsRb) != 0) {
443 key = WMCreatePLString(wwin->wm_class);
444 } else if (WMGetButtonSelected(panel->bothRb) != 0) {
445 buf1 = StrConcatDot(wwin->wm_instance, wwin->wm_class);
446 key = WMCreatePLString(buf1);
447 wfree(buf1);
448 } else if (WMGetButtonSelected(panel->defaultRb) != 0) {
449 key = WMRetainPropList(AnyWindow);
450 flags = UPDATE_DEFAULTS;
453 if (!key)
454 return;
456 dict = db->dictionary;
457 if (!dict) {
458 dict = WMCreatePLDictionary(NULL, NULL);
459 if (dict) {
460 db->dictionary = dict;
461 } else {
462 WMReleasePropList(key);
463 return;
467 if (showIconFor(WMWidgetScreen(button), panel, NULL, NULL, USE_TEXT_FIELD) < 0)
468 return;
470 WMPLSetCaseSensitive(True);
472 winDic = WMCreatePLDictionary(NULL, NULL);
473 appDic = WMCreatePLDictionary(NULL, NULL);
475 /* Save the icon info */
476 /* The flag "Ignore client suplied icon is not selected" */
477 buf1 = wmalloc(4);
478 snprintf(buf1, 4, "%s", (WMGetButtonSelected(panel->alwChk) != 0) ? "Yes" : "No");
479 value1 = WMCreatePLString(buf1);
480 different |= insertAttribute(dict, winDic, AAlwaysUserIcon, value1, flags);
481 WMReleasePropList(value1);
482 wfree(buf1);
484 /* The icon filename (if exists) */
485 icon_file = WMGetTextFieldText(panel->fileText);
486 if ((icon_file) && (icon_file[0] != 0)) {
487 value = WMCreatePLString(icon_file);
488 different |= insertAttribute(dict, winDic, AIcon, value, flags);
489 different2 |= insertAttribute(dict, appDic, AIcon, value, flags);
490 WMReleasePropList(value);
491 wfree(icon_file);
494 i = WMGetPopUpButtonSelectedItem(panel->wsP) - 1;
495 if (i >= 0 && i < w_global.workspace.count) {
496 value = WMCreatePLString(w_global.workspace.array[i]->name);
497 different |= insertAttribute(dict, winDic, AStartWorkspace, value, flags);
498 WMReleasePropList(value);
501 flags |= IS_BOOLEAN;
503 value = (WMGetButtonSelected(panel->attrChk[0]) != 0) ? Yes : No;
504 different |= insertAttribute(dict, winDic, ANoTitlebar, value, flags);
506 value = (WMGetButtonSelected(panel->attrChk[1]) != 0) ? Yes : No;
507 different |= insertAttribute(dict, winDic, ANoResizebar, value, flags);
509 value = (WMGetButtonSelected(panel->attrChk[2]) != 0) ? Yes : No;
510 different |= insertAttribute(dict, winDic, ANoCloseButton, value, flags);
512 value = (WMGetButtonSelected(panel->attrChk[3]) != 0) ? Yes : No;
513 different |= insertAttribute(dict, winDic, ANoMiniaturizeButton, value, flags);
515 value = (WMGetButtonSelected(panel->attrChk[4]) != 0) ? Yes : No;
516 different |= insertAttribute(dict, winDic, ANoBorder, value, flags);
518 value = (WMGetButtonSelected(panel->attrChk[5]) != 0) ? Yes : No;
519 different |= insertAttribute(dict, winDic, AKeepOnTop, value, flags);
521 value = (WMGetButtonSelected(panel->attrChk[6]) != 0) ? Yes : No;
522 different |= insertAttribute(dict, winDic, AKeepOnBottom, value, flags);
524 value = (WMGetButtonSelected(panel->attrChk[7]) != 0) ? Yes : No;
525 different |= insertAttribute(dict, winDic, AOmnipresent, value, flags);
527 value = (WMGetButtonSelected(panel->attrChk[8]) != 0) ? Yes : No;
528 different |= insertAttribute(dict, winDic, AStartMiniaturized, value, flags);
530 value = (WMGetButtonSelected(panel->attrChk[9]) != 0) ? Yes : No;
531 different |= insertAttribute(dict, winDic, AStartMaximized, value, flags);
533 value = (WMGetButtonSelected(panel->attrChk[10]) != 0) ? Yes : No;
534 different |= insertAttribute(dict, winDic, AFullMaximize, value, flags);
536 value = (WMGetButtonSelected(panel->moreChk[0]) != 0) ? Yes : No;
537 different |= insertAttribute(dict, winDic, ANoKeyBindings, value, flags);
539 value = (WMGetButtonSelected(panel->moreChk[1]) != 0) ? Yes : No;
540 different |= insertAttribute(dict, winDic, ANoMouseBindings, value, flags);
542 value = (WMGetButtonSelected(panel->moreChk[2]) != 0) ? Yes : No;
543 different |= insertAttribute(dict, winDic, ASkipWindowList, value, flags);
545 value = (WMGetButtonSelected(panel->moreChk[3]) != 0) ? Yes : No;
546 different |= insertAttribute(dict, winDic, ASkipSwitchPanel, value, flags);
548 value = (WMGetButtonSelected(panel->moreChk[4]) != 0) ? Yes : No;
549 different |= insertAttribute(dict, winDic, AUnfocusable, value, flags);
551 value = (WMGetButtonSelected(panel->moreChk[5]) != 0) ? Yes : No;
552 different |= insertAttribute(dict, winDic, AKeepInsideScreen, value, flags);
554 value = (WMGetButtonSelected(panel->moreChk[6]) != 0) ? Yes : No;
555 different |= insertAttribute(dict, winDic, ANoHideOthers, value, flags);
557 value = (WMGetButtonSelected(panel->moreChk[7]) != 0) ? Yes : No;
558 different |= insertAttribute(dict, winDic, ADontSaveSession, value, flags);
560 value = (WMGetButtonSelected(panel->moreChk[8]) != 0) ? Yes : No;
561 different |= insertAttribute(dict, winDic, AEmulateAppIcon, value, flags);
563 value = (WMGetButtonSelected(panel->moreChk[9]) != 0) ? Yes : No;
564 different |= insertAttribute(dict, winDic, AFocusAcrossWorkspace, value, flags);
566 value = (WMGetButtonSelected(panel->moreChk[10]) != 0) ? Yes : No;
567 different |= insertAttribute(dict, winDic, ANoMiniaturizable, value, flags);
569 #ifdef XKB_BUTTON_HINT
570 value = (WMGetButtonSelected(panel->moreChk[11]) != 0) ? Yes : No;
571 different |= insertAttribute(dict, winDic, ANoLanguageButton, value, flags);
572 #endif
574 if (wwin->main_window != None && wApplicationOf(wwin->main_window) != NULL) {
575 value = (WMGetButtonSelected(panel->appChk[0]) != 0) ? Yes : No;
576 different2 |= insertAttribute(dict, appDic, AStartHidden, value, flags);
578 value = (WMGetButtonSelected(panel->appChk[1]) != 0) ? Yes : No;
579 different2 |= insertAttribute(dict, appDic, ANoAppIcon, value, flags);
581 value = (WMGetButtonSelected(panel->appChk[2]) != 0) ? Yes : No;
582 different2 |= insertAttribute(dict, appDic, ASharedAppIcon, value, flags);
585 if (wwin->fake_group) {
586 key2 = WMCreatePLString(wwin->fake_group->identifier);
587 if (WMIsPropListEqualTo(key, key2)) {
588 WMMergePLDictionaries(winDic, appDic, True);
589 different |= different2;
590 } else {
591 WMRemoveFromPLDictionary(dict, key2);
592 if (different2)
593 WMPutInPLDictionary(dict, key2, appDic);
595 WMReleasePropList(key2);
596 WMReleasePropList(appDic);
597 } else if (wwin->main_window != wwin->client_win) {
598 WApplication *wapp = wApplicationOf(wwin->main_window);
600 if (wapp) {
601 buf2 = StrConcatDot(wapp->main_window_desc->wm_instance,
602 wapp->main_window_desc->wm_class);
603 key2 = WMCreatePLString(buf2);
604 wfree(buf2);
606 if (WMIsPropListEqualTo(key, key2)) {
607 WMMergePLDictionaries(winDic, appDic, True);
608 different |= different2;
609 } else {
610 WMRemoveFromPLDictionary(dict, key2);
611 if (different2)
612 WMPutInPLDictionary(dict, key2, appDic);
614 WMReleasePropList(key2);
615 WMReleasePropList(appDic);
617 } else {
618 WMMergePLDictionaries(winDic, appDic, True);
619 different |= different2;
620 WMReleasePropList(appDic);
623 WMRemoveFromPLDictionary(dict, key);
624 if (different)
625 WMPutInPLDictionary(dict, key, winDic);
627 WMReleasePropList(key);
628 WMReleasePropList(winDic);
630 UpdateDomainFile(db);
632 /* clean up */
633 WMPLSetCaseSensitive(False);
636 static void applySettings(WMButton *button, InspectorPanel *panel)
638 WWindow *wwin = panel->inspected;
639 WApplication *wapp = wApplicationOf(wwin->main_window);
640 int floating, sunken, skip_window_list;
641 int old_omnipresent, old_no_bind_keys, old_no_bind_mouse;
643 old_omnipresent = WFLAGP(wwin, omnipresent);
644 old_no_bind_keys = WFLAGP(wwin, no_bind_keys);
645 old_no_bind_mouse = WFLAGP(wwin, no_bind_mouse);
647 showIconFor(WMWidgetScreen(button), panel, NULL, NULL, USE_TEXT_FIELD);
649 /* Attributes... --> Window Attributes */
650 WSETUFLAG(wwin, no_titlebar, WMGetButtonSelected(panel->attrChk[0]));
651 WSETUFLAG(wwin, no_resizebar, WMGetButtonSelected(panel->attrChk[1]));
652 WSETUFLAG(wwin, no_close_button, WMGetButtonSelected(panel->attrChk[2]));
653 WSETUFLAG(wwin, no_miniaturize_button, WMGetButtonSelected(panel->attrChk[3]));
654 WSETUFLAG(wwin, no_border, WMGetButtonSelected(panel->attrChk[4]));
655 floating = WMGetButtonSelected(panel->attrChk[5]);
656 sunken = WMGetButtonSelected(panel->attrChk[6]);
657 WSETUFLAG(wwin, omnipresent, WMGetButtonSelected(panel->attrChk[7]));
658 WSETUFLAG(wwin, start_miniaturized, WMGetButtonSelected(panel->attrChk[8]));
659 WSETUFLAG(wwin, start_maximized, WMGetButtonSelected(panel->attrChk[9]));
660 WSETUFLAG(wwin, full_maximize, WMGetButtonSelected(panel->attrChk[10]));
662 /* Attributes... --> Advanced Options */
663 WSETUFLAG(wwin, no_bind_keys, WMGetButtonSelected(panel->moreChk[0]));
664 WSETUFLAG(wwin, no_bind_mouse, WMGetButtonSelected(panel->moreChk[1]));
665 skip_window_list = WMGetButtonSelected(panel->moreChk[2]);
666 WSETUFLAG(wwin, skip_switchpanel, WMGetButtonSelected(panel->moreChk[3]));
667 WSETUFLAG(wwin, no_focusable, WMGetButtonSelected(panel->moreChk[4]));
668 WSETUFLAG(wwin, dont_move_off, WMGetButtonSelected(panel->moreChk[5]));
669 WSETUFLAG(wwin, no_hide_others, WMGetButtonSelected(panel->moreChk[6]));
670 WSETUFLAG(wwin, dont_save_session, WMGetButtonSelected(panel->moreChk[7]));
671 WSETUFLAG(wwin, emulate_appicon, WMGetButtonSelected(panel->moreChk[8]));
672 WSETUFLAG(wwin, focus_across_wksp, WMGetButtonSelected(panel->moreChk[9]));
673 WSETUFLAG(wwin, no_miniaturizable, WMGetButtonSelected(panel->moreChk[10]));
674 #ifdef XKB_BUTTON_HINT
675 WSETUFLAG(wwin, no_language_button, WMGetButtonSelected(panel->moreChk[11]));
676 #endif
677 WSETUFLAG(wwin, always_user_icon, WMGetButtonSelected(panel->alwChk));
679 if (WFLAGP(wwin, no_titlebar) && wwin->flags.shaded)
680 wUnshadeWindow(wwin);
682 WSETUFLAG(wwin, no_shadeable, WFLAGP(wwin, no_titlebar));
684 if (floating) {
685 if (!WFLAGP(wwin, floating))
686 ChangeStackingLevel(wwin->frame->core, WMFloatingLevel);
687 } else if (sunken) {
688 if (!WFLAGP(wwin, sunken))
689 ChangeStackingLevel(wwin->frame->core, WMSunkenLevel);
690 } else {
691 if (WFLAGP(wwin, floating) || WFLAGP(wwin, sunken))
692 ChangeStackingLevel(wwin->frame->core, WMNormalLevel);
695 WSETUFLAG(wwin, sunken, sunken);
696 WSETUFLAG(wwin, floating, floating);
697 wwin->flags.omnipresent = 0;
699 if (WFLAGP(wwin, skip_window_list) != skip_window_list) {
700 WSETUFLAG(wwin, skip_window_list, skip_window_list);
701 UpdateSwitchMenu(wwin->screen_ptr, wwin, skip_window_list ? ACTION_REMOVE : ACTION_ADD);
702 } else {
703 if (WFLAGP(wwin, omnipresent) != old_omnipresent)
704 WMPostNotificationName(WMNChangedState, wwin, "omnipresent");
707 if (WFLAGP(wwin, no_bind_keys) != old_no_bind_keys) {
708 if (WFLAGP(wwin, no_bind_keys))
709 XUngrabKey(dpy, AnyKey, AnyModifier, wwin->frame->core->window);
710 else
711 wWindowSetKeyGrabs(wwin);
714 if (WFLAGP(wwin, no_bind_mouse) != old_no_bind_mouse)
715 wWindowResetMouseGrabs(wwin);
717 wwin->frame->flags.need_texture_change = 1;
718 wWindowConfigureBorders(wwin);
719 wFrameWindowPaint(wwin->frame);
720 wNETWMUpdateActions(wwin, False);
722 /* Can't apply emulate_appicon because it will probably cause problems. */
723 if (wapp) {
724 /* do application wide stuff */
725 WSETUFLAG(wapp->main_window_desc, start_hidden, WMGetButtonSelected(panel->appChk[0]));
726 WSETUFLAG(wapp->main_window_desc, no_appicon, WMGetButtonSelected(panel->appChk[1]));
727 WSETUFLAG(wapp->main_window_desc, shared_appicon, WMGetButtonSelected(panel->appChk[2]));
729 if (WFLAGP(wapp->main_window_desc, no_appicon))
730 unpaint_app_icon(wapp);
731 else
732 paint_app_icon(wapp);
734 char *file = WMGetTextFieldText(panel->fileText);
735 if (file[0] == 0) {
736 wfree(file);
737 file = NULL;
740 /* If always_user_icon flag is set, but the user icon is not set
741 * we use client supplied icon and we unset the flag */
742 if ((WFLAGP(wwin, always_user_icon) && (!file))) {
743 /* Show the warning */
744 char *buf;
745 int len = 100;
747 buf = wmalloc(len);
748 snprintf(buf, len, _("Ignore client supplied icon is set, but icon filename textbox is empty. Using client supplied icon"));
749 wMessageDialog(panel->frame->screen_ptr, _("Warning"), buf, _("OK"), NULL, NULL);
750 wfree(buf);
751 wfree(file);
753 /* Change the flags */
754 WSETUFLAG(wwin, always_user_icon, 0);
755 WMSetButtonSelected(panel->alwChk, 0);
758 /* After test the always_user_icon flag value before,
759 * the "else" block is used only if the flag is set and
760 * the icon text box has an icon path */
761 if (!WFLAGP(wwin, always_user_icon)) {
762 /* Change App Icon image, using the icon provided by the client */
763 if (wapp->app_icon) {
764 RImage *image = get_rimage_icon_from_wm_hints(wapp->app_icon->icon);
765 if (image) {
766 set_icon_image_from_image(wapp->app_icon->icon, image);
767 update_icon_pixmap(wapp->app_icon->icon);
768 } else {
769 wIconUpdate(wapp->app_icon->icon);
773 /* Change icon image if the app is minimized,
774 * using the icon provided by the client */
775 if (wwin->icon) {
776 RImage *image = get_rimage_icon_from_wm_hints(wwin->icon);
777 if (image) {
778 set_icon_image_from_image(wwin->icon, image);
779 update_icon_pixmap(wwin->icon);
780 } else {
781 wIconUpdate(wwin->icon);
784 } else {
785 /* Change App Icon image */
786 if (wapp->app_icon)
787 wIconChangeImageFile(wapp->app_icon->icon, file);
789 /* Change icon image if the app is minimized */
790 if (wwin->icon)
791 wIconChangeImageFile(wwin->icon, file);
794 if (file)
795 wfree(file);
798 wNETFrameExtents(wwin);
801 static void revertSettings(WMButton *button, InspectorPanel *panel)
803 WWindow *wwin = panel->inspected;
804 WApplication *wapp = wApplicationOf(wwin->main_window);
805 int i, n, workspace, level;
806 char *wm_instance = NULL, *wm_class = NULL;
808 if (panel->instRb && WMGetButtonSelected(panel->instRb) != 0)
809 wm_instance = wwin->wm_instance;
810 else if (panel->clsRb && WMGetButtonSelected(panel->clsRb) != 0)
811 wm_class = wwin->wm_class;
812 else if (panel->bothRb && WMGetButtonSelected(panel->bothRb) != 0) {
813 wm_instance = wwin->wm_instance;
814 wm_class = wwin->wm_class;
817 memset(&wwin->defined_user_flags, 0, sizeof(WWindowAttributes));
818 memset(&wwin->user_flags, 0, sizeof(WWindowAttributes));
819 memset(&wwin->client_flags, 0, sizeof(WWindowAttributes));
821 wWindowSetupInitialAttributes(wwin, &level, &workspace);
823 for (i = 0; i < (sizeof(panel->attrChk) / sizeof(panel->attrChk[0])); i++) {
824 int flag = 0;
826 switch (i) {
827 case 0:
828 flag = WFLAGP(wwin, no_titlebar);
829 break;
830 case 1:
831 flag = WFLAGP(wwin, no_resizebar);
832 break;
833 case 2:
834 flag = WFLAGP(wwin, no_close_button);
835 break;
836 case 3:
837 flag = WFLAGP(wwin, no_miniaturize_button);
838 break;
839 case 4:
840 flag = WFLAGP(wwin, no_border);
841 break;
842 case 5:
843 flag = WFLAGP(wwin, floating);
844 break;
845 case 6:
846 flag = WFLAGP(wwin, sunken);
847 break;
848 case 7:
849 flag = WFLAGP(wwin, omnipresent);
850 break;
851 case 8:
852 flag = WFLAGP(wwin, start_miniaturized);
853 break;
854 case 9:
855 flag = WFLAGP(wwin, start_maximized != 0);
856 break;
857 case 10:
858 flag = WFLAGP(wwin, full_maximize);
859 break;
861 WMSetButtonSelected(panel->attrChk[i], flag);
864 for (i = 0; i < (sizeof(panel->moreChk) / sizeof(panel->moreChk[0])); i++) {
865 int flag = 0;
867 switch (i) {
868 case 0:
869 flag = WFLAGP(wwin, no_bind_keys);
870 break;
871 case 1:
872 flag = WFLAGP(wwin, no_bind_mouse);
873 break;
874 case 2:
875 flag = WFLAGP(wwin, skip_window_list);
876 break;
877 case 3:
878 flag = WFLAGP(wwin, skip_switchpanel);
879 break;
880 case 4:
881 flag = WFLAGP(wwin, no_focusable);
882 break;
883 case 5:
884 flag = WFLAGP(wwin, dont_move_off);
885 break;
886 case 6:
887 flag = WFLAGP(wwin, no_hide_others);
888 break;
889 case 7:
890 flag = WFLAGP(wwin, dont_save_session);
891 break;
892 case 8:
893 flag = WFLAGP(wwin, emulate_appicon);
894 break;
895 case 9:
896 flag = WFLAGP(wwin, focus_across_wksp);
897 break;
898 case 10:
899 flag = WFLAGP(wwin, no_miniaturizable);
900 break;
901 #ifdef XKB_BUTTON_HINT
902 case 11:
903 flag = WFLAGP(wwin, no_language_button);
904 break;
905 #endif
907 WMSetButtonSelected(panel->moreChk[i], flag);
909 if (panel->appFrm && wapp) {
910 for (i = 0; i < (sizeof(panel->appChk) / sizeof(panel->appChk[0])); i++) {
911 int flag = 0;
913 switch (i) {
914 case 0:
915 flag = WFLAGP(wapp->main_window_desc, start_hidden);
916 break;
917 case 1:
918 flag = WFLAGP(wapp->main_window_desc, no_appicon);
919 break;
920 case 2:
921 flag = WFLAGP(wapp->main_window_desc, shared_appicon);
922 break;
924 WMSetButtonSelected(panel->appChk[i], flag);
927 WMSetButtonSelected(panel->alwChk, WFLAGP(wwin, always_user_icon));
929 showIconFor(WMWidgetScreen(panel->alwChk), panel, wm_instance, wm_class, REVERT_TO_DEFAULT);
931 n = wDefaultGetStartWorkspace(wm_instance, wm_class);
933 if (n >= 0 && n < w_global.workspace.count)
934 WMSetPopUpButtonSelectedItem(panel->wsP, n + 1);
935 else
936 WMSetPopUpButtonSelectedItem(panel->wsP, 0);
938 /* must auto apply, so that there wno't be internal
939 * inconsistencies between the state in the flags and
940 * the actual state of the window */
941 applySettings(panel->applyBtn, panel);
944 static void chooseIconCallback(WMWidget *self, void *clientData)
946 char *file;
947 InspectorPanel *panel = (InspectorPanel *) clientData;
948 int result;
950 panel->choosingIcon = 1;
952 WMSetButtonEnabled(panel->browseIconBtn, False);
954 result = wIconChooserDialog(panel->frame->screen_ptr, &file,
955 panel->inspected->wm_instance,
956 panel->inspected->wm_class);
958 panel->choosingIcon = 0;
960 if (!panel->destroyed) { /* kluge */
961 if (result) {
962 WMSetTextFieldText(panel->fileText, file);
963 showIconFor(WMWidgetScreen(self), panel, NULL, NULL, USE_TEXT_FIELD);
964 wfree(file);
966 WMSetButtonEnabled(panel->browseIconBtn, True);
967 } else {
968 freeInspector(panel);
972 static void textEditedObserver(void *observerData, WMNotification *notification)
974 InspectorPanel *panel = (InspectorPanel *) observerData;
976 if ((long)WMGetNotificationClientData(notification) != WMReturnTextMovement)
977 return;
979 showIconFor(WMWidgetScreen(panel->win), panel, NULL, NULL, USE_TEXT_FIELD);
982 static void selectSpecification(WMWidget *bPtr, void *data)
984 InspectorPanel *panel = (InspectorPanel *) data;
985 char *str;
986 WWindow *wwin = panel->inspected;
987 int len;
989 if (bPtr == panel->defaultRb && (wwin->wm_instance || wwin->wm_class))
990 WMSetButtonEnabled(panel->applyBtn, False);
991 else
992 WMSetButtonEnabled(panel->applyBtn, True);
994 len = 16 + strlen(wwin->wm_instance ? wwin->wm_instance : "?")
995 + strlen(wwin->wm_class ? wwin->wm_class : "?");
997 str = wmalloc(len);
999 snprintf(str, len, _("Inspecting %s.%s"),
1000 wwin->wm_instance ? wwin->wm_instance : "?", wwin->wm_class ? wwin->wm_class : "?");
1002 wFrameWindowChangeTitle(panel->frame->frame, str);
1004 wfree(str);
1007 static void selectWindow(WMWidget *bPtr, void *data)
1009 InspectorPanel *panel = (InspectorPanel *) data;
1010 WWindow *wwin = panel->inspected;
1011 WScreen *scr = wwin->screen_ptr;
1012 XEvent event;
1013 WWindow *iwin;
1015 if (XGrabPointer(dpy, scr->root_win, True,
1016 ButtonPressMask, GrabModeAsync, GrabModeAsync, None,
1017 wPreferences.cursor[WCUR_SELECT], CurrentTime) != GrabSuccess) {
1018 wwarning("could not grab mouse pointer");
1019 return;
1022 WMSetLabelText(panel->specLbl, _("Click in the window you wish to inspect."));
1023 WMMaskEvent(dpy, ButtonPressMask, &event);
1024 XUngrabPointer(dpy, CurrentTime);
1026 iwin = wWindowFor(event.xbutton.subwindow);
1027 if (iwin && !iwin->flags.internal_window && iwin != wwin && !iwin->flags.inspector_open) {
1028 iwin->flags.inspector_open = 1;
1029 iwin->inspector = createInspectorForWindow(iwin,
1030 panel->frame->frame_x, panel->frame->frame_y, True);
1031 wCloseInspectorForWindow(wwin);
1032 } else {
1033 WMSetLabelText(panel->specLbl, spec_text);
1037 static InspectorPanel *createInspectorForWindow(WWindow *wwin, int xpos, int ypos, Bool showSelectPanel)
1039 WScreen *scr = wwin->screen_ptr;
1040 InspectorPanel *panel;
1041 Window parent;
1042 char *str = NULL, *tmp = NULL;
1043 int x, y, btn_width, frame_width;
1044 WMButton *selectedBtn = NULL;
1046 spec_text = _("The configuration will apply to all\n"
1047 "windows that have their WM_CLASS\n"
1048 "property set to the above selected\n" "name, when saved.");
1050 panel = wmalloc(sizeof(InspectorPanel));
1051 memset(panel, 0, sizeof(InspectorPanel));
1053 panel->destroyed = 0;
1054 panel->inspected = wwin;
1055 panel->nextPtr = panelList;
1056 panelList = panel;
1057 panel->win = WMCreateWindow(scr->wmscreen, "windowInspector");
1058 WMResizeWidget(panel->win, PWIDTH, PHEIGHT);
1060 /**** create common stuff ****/
1061 /* command buttons */
1062 btn_width = (PWIDTH - (2 * 15) - (2 * 10)) / 3;
1063 panel->saveBtn = WMCreateCommandButton(panel->win);
1064 WMSetButtonAction(panel->saveBtn, (WMAction *) saveSettings, panel);
1065 WMMoveWidget(panel->saveBtn, (2 * (btn_width + 10)) + 15, PHEIGHT - 40);
1066 WMSetButtonText(panel->saveBtn, _("Save"));
1067 WMResizeWidget(panel->saveBtn, btn_width, 28);
1068 if (wPreferences.flags.noupdates || !(wwin->wm_class || wwin->wm_instance))
1069 WMSetButtonEnabled(panel->saveBtn, False);
1071 panel->applyBtn = WMCreateCommandButton(panel->win);
1072 WMSetButtonAction(panel->applyBtn, (WMAction *) applySettings, panel);
1073 WMMoveWidget(panel->applyBtn, btn_width + 10 + 15, PHEIGHT - 40);
1074 WMSetButtonText(panel->applyBtn, _("Apply"));
1075 WMResizeWidget(panel->applyBtn, btn_width, 28);
1077 panel->revertBtn = WMCreateCommandButton(panel->win);
1078 WMSetButtonAction(panel->revertBtn, (WMAction *) revertSettings, panel);
1079 WMMoveWidget(panel->revertBtn, 15, PHEIGHT - 40);
1080 WMSetButtonText(panel->revertBtn, _("Reload"));
1081 WMResizeWidget(panel->revertBtn, btn_width, 28);
1083 /* page selection popup button */
1084 panel->pagePopUp = WMCreatePopUpButton(panel->win);
1085 WMSetPopUpButtonAction(panel->pagePopUp, (WMAction *) changePage, panel);
1086 WMMoveWidget(panel->pagePopUp, 25, 15);
1087 WMResizeWidget(panel->pagePopUp, PWIDTH - 50, 20);
1089 WMAddPopUpButtonItem(panel->pagePopUp, _("Window Specification"));
1090 WMAddPopUpButtonItem(panel->pagePopUp, _("Window Attributes"));
1091 WMAddPopUpButtonItem(panel->pagePopUp, _("Advanced Options"));
1092 WMAddPopUpButtonItem(panel->pagePopUp, _("Icon and Initial Workspace"));
1093 WMAddPopUpButtonItem(panel->pagePopUp, _("Application Specific"));
1095 /**** window spec ****/
1096 frame_width = PWIDTH - (2 * 15);
1098 panel->specFrm = WMCreateFrame(panel->win);
1099 WMSetFrameTitle(panel->specFrm, _("Window Specification"));
1100 WMMoveWidget(panel->specFrm, 15, 65);
1101 WMResizeWidget(panel->specFrm, frame_width, 145);
1103 panel->defaultRb = WMCreateRadioButton(panel->specFrm);
1104 WMMoveWidget(panel->defaultRb, 10, 78);
1105 WMResizeWidget(panel->defaultRb, frame_width - (2 * 10), 20);
1106 WMSetButtonText(panel->defaultRb, _("Defaults for all windows"));
1107 WMSetButtonSelected(panel->defaultRb, False);
1108 WMSetButtonAction(panel->defaultRb, selectSpecification, panel);
1110 if (wwin->wm_class && wwin->wm_instance) {
1111 tmp = wstrconcat(wwin->wm_instance, ".");
1112 str = wstrconcat(tmp, wwin->wm_class);
1114 panel->bothRb = WMCreateRadioButton(panel->specFrm);
1115 WMMoveWidget(panel->bothRb, 10, 18);
1116 WMResizeWidget(panel->bothRb, frame_width - (2 * 10), 20);
1117 WMSetButtonText(panel->bothRb, str);
1118 wfree(tmp);
1119 wfree(str);
1120 WMGroupButtons(panel->defaultRb, panel->bothRb);
1122 if (!selectedBtn)
1123 selectedBtn = panel->bothRb;
1125 WMSetButtonAction(panel->bothRb, selectSpecification, panel);
1128 if (wwin->wm_instance) {
1129 panel->instRb = WMCreateRadioButton(panel->specFrm);
1130 WMMoveWidget(panel->instRb, 10, 38);
1131 WMResizeWidget(panel->instRb, frame_width - (2 * 10), 20);
1132 WMSetButtonText(panel->instRb, wwin->wm_instance);
1133 WMGroupButtons(panel->defaultRb, panel->instRb);
1135 if (!selectedBtn)
1136 selectedBtn = panel->instRb;
1138 WMSetButtonAction(panel->instRb, selectSpecification, panel);
1141 if (wwin->wm_class) {
1142 panel->clsRb = WMCreateRadioButton(panel->specFrm);
1143 WMMoveWidget(panel->clsRb, 10, 58);
1144 WMResizeWidget(panel->clsRb, frame_width - (2 * 10), 20);
1145 WMSetButtonText(panel->clsRb, wwin->wm_class);
1146 WMGroupButtons(panel->defaultRb, panel->clsRb);
1148 if (!selectedBtn)
1149 selectedBtn = panel->clsRb;
1151 WMSetButtonAction(panel->clsRb, selectSpecification, panel);
1154 panel->selWinB = WMCreateCommandButton(panel->specFrm);
1155 WMMoveWidget(panel->selWinB, 20, 145 - 24 - 10);
1156 WMResizeWidget(panel->selWinB, frame_width - 2 * 10 - 20, 24);
1157 WMSetButtonText(panel->selWinB, _("Select window"));
1158 WMSetButtonAction(panel->selWinB, selectWindow, panel);
1160 panel->specLbl = WMCreateLabel(panel->win);
1161 WMMoveWidget(panel->specLbl, 15, 210);
1162 WMResizeWidget(panel->specLbl, frame_width, 100);
1163 WMSetLabelText(panel->specLbl, spec_text);
1164 WMSetLabelWraps(panel->specLbl, True);
1166 WMSetLabelTextAlignment(panel->specLbl, WALeft);
1168 /**** attributes ****/
1169 create_tab_window_attributes(wwin, panel, frame_width);
1170 create_tab_window_advanced(wwin, panel, frame_width);
1171 create_tab_icon_workspace(wwin, panel);
1172 create_tab_app_specific(wwin, panel, frame_width);
1174 /* if the window is a transient, don't let it have a miniaturize button */
1175 if (wwin->transient_for != None && wwin->transient_for != scr->root_win)
1176 WMSetButtonEnabled(panel->attrChk[3], False);
1177 else
1178 WMSetButtonEnabled(panel->attrChk[3], True);
1180 if (!wwin->wm_class && !wwin->wm_instance)
1181 WMSetPopUpButtonItemEnabled(panel->pagePopUp, 0, False);
1183 WMRealizeWidget(panel->win);
1185 WMMapSubwidgets(panel->win);
1186 WMMapSubwidgets(panel->specFrm);
1187 WMMapSubwidgets(panel->attrFrm);
1188 WMMapSubwidgets(panel->moreFrm);
1189 WMMapSubwidgets(panel->iconFrm);
1190 WMMapSubwidgets(panel->wsFrm);
1191 if (panel->appFrm)
1192 WMMapSubwidgets(panel->appFrm);
1194 if (showSelectPanel) {
1195 WMSetPopUpButtonSelectedItem(panel->pagePopUp, 0);
1196 changePage(panel->pagePopUp, panel);
1197 } else {
1198 WMSetPopUpButtonSelectedItem(panel->pagePopUp, 1);
1199 changePage(panel->pagePopUp, panel);
1202 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, PWIDTH, PHEIGHT, 0, 0, 0);
1203 XSelectInput(dpy, parent, KeyPressMask | KeyReleaseMask);
1204 panel->parent = parent;
1205 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
1207 WMMapWidget(panel->win);
1209 XSetTransientForHint(dpy, parent, wwin->client_win);
1211 if (xpos == UNDEFINED_POS) {
1212 x = wwin->frame_x + wwin->frame->core->width / 2;
1213 y = wwin->frame_y + wwin->frame->top_width * 2;
1214 if (y + PHEIGHT > scr->scr_height)
1215 y = scr->scr_height - PHEIGHT - 30;
1216 if (x + PWIDTH > scr->scr_width)
1217 x = scr->scr_width - PWIDTH;
1218 } else {
1219 x = xpos;
1220 y = ypos;
1223 panel->frame = wManageInternalWindow(scr, parent, wwin->client_win, "Inspector", x, y, PWIDTH, PHEIGHT);
1225 if (!selectedBtn)
1226 selectedBtn = panel->defaultRb;
1228 WMSetButtonSelected(selectedBtn, True);
1229 selectSpecification(selectedBtn, panel);
1231 /* kluge to know who should get the key events */
1232 panel->frame->client_leader = WMWidgetXID(panel->win);
1234 WSETUFLAG(panel->frame, no_closable, 0);
1235 WSETUFLAG(panel->frame, no_close_button, 0);
1236 wWindowUpdateButtonImages(panel->frame);
1237 wFrameWindowShowButton(panel->frame->frame, WFF_RIGHT_BUTTON);
1238 panel->frame->frame->on_click_right = destroyInspector;
1240 wWindowMap(panel->frame);
1242 showIconFor(WMWidgetScreen(panel->alwChk), panel, wwin->wm_instance, wwin->wm_class, UPDATE_TEXT_FIELD);
1244 return panel;
1247 void wShowInspectorForWindow(WWindow *wwin)
1249 if (wwin->flags.inspector_open)
1250 return;
1252 WMSetBalloonEnabled(wwin->screen_ptr->wmscreen, wPreferences.help_balloon);
1254 make_keys();
1255 wwin->flags.inspector_open = 1;
1256 wwin->inspector = createInspectorForWindow(wwin, UNDEFINED_POS, UNDEFINED_POS, False);
1259 void wHideInspectorForWindow(WWindow *wwin)
1261 WWindow *pwin = wwin->inspector->frame;
1263 wWindowUnmap(pwin);
1264 pwin->flags.hidden = 1;
1266 wClientSetState(pwin, IconicState, None);
1269 void wUnhideInspectorForWindow(WWindow *wwin)
1271 WWindow *pwin = wwin->inspector->frame;
1273 pwin->flags.hidden = 0;
1274 pwin->flags.mapped = 1;
1275 XMapWindow(dpy, pwin->client_win);
1276 XMapWindow(dpy, pwin->frame->core->window);
1277 wClientSetState(pwin, NormalState, None);
1280 WWindow *wGetWindowOfInspectorForWindow(WWindow *wwin)
1282 if (!wwin->inspector)
1283 return NULL;
1285 assert(wwin->flags.inspector_open != 0);
1286 return wwin->inspector->frame;
1289 void wCloseInspectorForWindow(WWindow *wwin)
1291 WWindow *pwin = wwin->inspector->frame; /* the inspector window */
1293 (*pwin->frame->on_click_right) (NULL, pwin, NULL);
1296 static void create_tab_window_attributes(WWindow *wwin, InspectorPanel *panel, int frame_width)
1298 int i = 0;
1299 char *caption = NULL, *descr = NULL;
1300 int flag = 0;
1302 panel->attrFrm = WMCreateFrame(panel->win);
1303 WMSetFrameTitle(panel->attrFrm, _("Attributes"));
1304 WMMoveWidget(panel->attrFrm, 15, 45);
1305 WMResizeWidget(panel->attrFrm, frame_width, 250);
1307 for (i = 0; i < (sizeof(panel->attrChk) / sizeof(panel->attrChk[0])); i++) {
1308 switch (i) {
1309 case 0:
1310 caption = _("Disable titlebar");
1311 flag = WFLAGP(wwin, no_titlebar);
1312 descr = _("Remove the titlebar of this window.\n"
1313 "To access the window commands menu of a window\n"
1314 "without it's titlebar, press Control+Esc (or the\n"
1315 "equivalent shortcut, if you changed the default\n" "settings).");
1316 break;
1317 case 1:
1318 caption = _("Disable resizebar");
1319 flag = WFLAGP(wwin, no_resizebar);
1320 descr = _("Remove the resizebar of this window.");
1321 break;
1322 case 2:
1323 caption = _("Disable close button");
1324 flag = WFLAGP(wwin, no_close_button);
1325 descr = _("Remove the `close window' button of this window.");
1326 break;
1327 case 3:
1328 caption = _("Disable miniaturize button");
1329 flag = WFLAGP(wwin, no_miniaturize_button);
1330 descr = _("Remove the `miniaturize window' button of the window.");
1331 break;
1332 case 4:
1333 caption = _("Disable border");
1334 flag = WFLAGP(wwin, no_border);
1335 descr = _("Remove the 1 pixel black border around the window.");
1336 break;
1337 case 5:
1338 caption = _("Keep on top (floating)");
1339 flag = WFLAGP(wwin, floating);
1340 descr = _("Keep the window over other windows, not allowing\n" "them to cover it.");
1341 break;
1342 case 6:
1343 caption = _("Keep at bottom (sunken)");
1344 flag = WFLAGP(wwin, sunken);
1345 descr = _("Keep the window under all other windows.");
1346 break;
1347 case 7:
1348 caption = _("Omnipresent");
1349 flag = WFLAGP(wwin, omnipresent);
1350 descr = _("Make window present in all workspaces.");
1351 break;
1352 case 8:
1353 caption = _("Start miniaturized");
1354 flag = WFLAGP(wwin, start_miniaturized);
1355 descr = _("Make the window be automatically miniaturized when it's\n" "first shown.");
1356 break;
1357 case 9:
1358 caption = _("Start maximized");
1359 flag = WFLAGP(wwin, start_maximized != 0);
1360 descr = _("Make the window be automatically maximized when it's\n" "first shown.");
1361 break;
1362 case 10:
1363 caption = _("Full screen maximization");
1364 flag = WFLAGP(wwin, full_maximize);
1365 descr = _("Make the window use the whole screen space when it's\n"
1366 "maximized. The titlebar and resizebar will be moved\n"
1367 "to outside the screen.");
1368 break;
1370 panel->attrChk[i] = WMCreateSwitchButton(panel->attrFrm);
1371 WMMoveWidget(panel->attrChk[i], 10, 20 * (i + 1));
1372 WMResizeWidget(panel->attrChk[i], frame_width - 15, 20);
1373 WMSetButtonSelected(panel->attrChk[i], flag);
1374 WMSetButtonText(panel->attrChk[i], caption);
1376 WMSetBalloonTextForView(descr, WMWidgetView(panel->attrChk[i]));
1380 static void create_tab_window_advanced(WWindow *wwin, InspectorPanel *panel, int frame_width)
1382 int i = 0;
1383 char *caption = NULL, *descr = NULL;
1384 int flag = 0;
1386 panel->moreFrm = WMCreateFrame(panel->win);
1387 WMSetFrameTitle(panel->moreFrm, _("Advanced"));
1388 WMMoveWidget(panel->moreFrm, 15, 45);
1389 WMResizeWidget(panel->moreFrm, frame_width, 265);
1391 for (i = 0; i < (sizeof(panel->moreChk) / sizeof(panel->moreChk[0])); i++) {
1392 switch (i) {
1393 case 0:
1394 caption = _("Do not bind keyboard shortcuts");
1395 flag = WFLAGP(wwin, no_bind_keys);
1396 descr = _("Do not bind keyboard shortcuts from Window Maker\n"
1397 "when this window is focused. This will allow the\n"
1398 "window to receive all key combinations regardless\n"
1399 "of your shortcut configuration.");
1400 break;
1401 case 1:
1402 caption = _("Do not bind mouse clicks");
1403 flag = WFLAGP(wwin, no_bind_mouse);
1404 descr = _("Do not bind mouse actions, such as `Alt'+drag\n"
1405 "in the window (when alt is the modifier you have\n" "configured).");
1406 break;
1407 case 2:
1408 caption = _("Do not show in the window list");
1409 flag = WFLAGP(wwin, skip_window_list);
1410 descr = _("Do not list the window in the window list menu.");
1411 break;
1412 case 3:
1413 caption = _("Do not show in the switch panel");
1414 flag = WFLAGP(wwin, skip_switchpanel);
1415 descr = _("Do not include in switchpanel while alternating windows.");
1416 break;
1417 case 4:
1418 caption = _("Do not let it take focus");
1419 flag = WFLAGP(wwin, no_focusable);
1420 descr = _("Do not let the window take keyboard focus when you\n" "click on it.");
1421 break;
1422 case 5:
1423 caption = _("Keep inside screen");
1424 flag = WFLAGP(wwin, dont_move_off);
1425 descr = _("Do not allow the window to move itself completely\n"
1426 "outside the screen. For bug compatibility.\n");
1427 break;
1428 case 6:
1429 caption = _("Ignore 'Hide Others'");
1430 flag = WFLAGP(wwin, no_hide_others);
1431 descr = _("Do not hide the window when issuing the\n" "`HideOthers' command.");
1432 break;
1433 case 7:
1434 caption = _("Ignore 'Save Session'");
1435 flag = WFLAGP(wwin, dont_save_session);
1436 descr = _("Do not save the associated application in the\n"
1437 "session's state, so that it won't be restarted\n"
1438 "together with other applications when Window Maker\n" "starts.");
1439 break;
1440 case 8:
1441 caption = _("Emulate application icon");
1442 flag = WFLAGP(wwin, emulate_appicon);
1443 descr = _("Make this window act as an application that provides\n"
1444 "enough information to Window Maker for a dockable\n"
1445 "application icon to be created.");
1446 break;
1447 case 9:
1448 caption = _("Focus across workspaces");
1449 flag = WFLAGP(wwin, focus_across_wksp);
1450 descr = _("Allow Window Maker to switch workspace to satisfy\n"
1451 "a focus request (annoying).");
1452 break;
1453 case 10:
1454 caption = _("Do not let it be minimized");
1455 flag = WFLAGP(wwin, no_miniaturizable);
1456 descr = _("Do not let the window of this application be\n"
1457 "minimized.\n");
1458 break;
1459 #ifdef XKB_BUTTON_HINT
1460 case 11:
1461 caption = _("Disable language button");
1462 flag = WFLAGP(wwin, no_language_button);
1463 descr = _("Remove the `toggle language' button of the window.");
1464 break;
1465 #endif
1467 panel->moreChk[i] = WMCreateSwitchButton(panel->moreFrm);
1468 WMMoveWidget(panel->moreChk[i], 10, 20 * (i + 1));
1469 WMResizeWidget(panel->moreChk[i], frame_width - 15, 20);
1470 WMSetButtonSelected(panel->moreChk[i], flag);
1471 WMSetButtonText(panel->moreChk[i], caption);
1473 WMSetBalloonTextForView(descr, WMWidgetView(panel->moreChk[i]));
1477 static void create_tab_icon_workspace(WWindow *wwin, InspectorPanel *panel)
1479 int i = 0;
1481 /* miniwindow/workspace */
1482 panel->iconFrm = WMCreateFrame(panel->win);
1483 WMMoveWidget(panel->iconFrm, 15, 50);
1484 WMResizeWidget(panel->iconFrm, PWIDTH - (2 * 15), 170);
1485 WMSetFrameTitle(panel->iconFrm, _("Miniwindow Image"));
1487 panel->iconLbl = WMCreateLabel(panel->iconFrm);
1488 WMMoveWidget(panel->iconLbl, PWIDTH - (2 * 15) - 22 - 64, 20);
1489 WMResizeWidget(panel->iconLbl, 64, 64);
1490 WMSetLabelRelief(panel->iconLbl, WRGroove);
1491 WMSetLabelImagePosition(panel->iconLbl, WIPImageOnly);
1493 panel->browseIconBtn = WMCreateCommandButton(panel->iconFrm);
1494 WMSetButtonAction(panel->browseIconBtn, chooseIconCallback, panel);
1495 WMMoveWidget(panel->browseIconBtn, 22, 32);
1496 WMResizeWidget(panel->browseIconBtn, 120, 26);
1497 WMSetButtonText(panel->browseIconBtn, _("Browse..."));
1499 panel->fileLbl = WMCreateLabel(panel->iconFrm);
1500 WMMoveWidget(panel->fileLbl, 20, 85);
1501 WMResizeWidget(panel->fileLbl, PWIDTH - (2 * 15) - (2 * 20), 14);
1502 WMSetLabelText(panel->fileLbl, _("Icon filename:"));
1504 panel->fileText = WMCreateTextField(panel->iconFrm);
1505 WMMoveWidget(panel->fileText, 20, 105);
1506 WMResizeWidget(panel->fileText, PWIDTH - (2 * 20) - (2 * 15), 20);
1507 WMSetTextFieldText(panel->fileText, NULL);
1508 WMAddNotificationObserver(textEditedObserver, panel, WMTextDidEndEditingNotification, panel->fileText);
1510 panel->alwChk = WMCreateSwitchButton(panel->iconFrm);
1511 WMMoveWidget(panel->alwChk, 20, 130);
1512 WMResizeWidget(panel->alwChk, PWIDTH - (2 * 15) - (2 * 15), 30);
1513 WMSetButtonText(panel->alwChk, _("Ignore client supplied icon"));
1514 WMSetButtonSelected(panel->alwChk, WFLAGP(wwin, always_user_icon));
1516 panel->wsFrm = WMCreateFrame(panel->win);
1517 WMMoveWidget(panel->wsFrm, 15, 225);
1518 WMResizeWidget(panel->wsFrm, PWIDTH - (2 * 15), 70);
1519 WMSetFrameTitle(panel->wsFrm, _("Initial Workspace"));
1521 WMSetBalloonTextForView(_("The workspace to place the window when it's"
1522 "first shown."), WMWidgetView(panel->wsFrm));
1524 panel->wsP = WMCreatePopUpButton(panel->wsFrm);
1525 WMMoveWidget(panel->wsP, 20, 30);
1526 WMResizeWidget(panel->wsP, PWIDTH - (2 * 15) - (2 * 20), 20);
1527 WMAddPopUpButtonItem(panel->wsP, _("Nowhere in particular"));
1529 for (i = 0; i < w_global.workspace.count; i++)
1530 WMAddPopUpButtonItem(panel->wsP, w_global.workspace.array[i]->name);
1532 i = wDefaultGetStartWorkspace(wwin->wm_instance, wwin->wm_class);
1533 if (i >= 0 && i <= w_global.workspace.count)
1534 WMSetPopUpButtonSelectedItem(panel->wsP, i + 1);
1535 else
1536 WMSetPopUpButtonSelectedItem(panel->wsP, 0);
1539 static void create_tab_app_specific(WWindow *wwin, InspectorPanel *panel, int frame_width)
1541 WScreen *scr = wwin->screen_ptr;
1542 int i = 0, flag = 0, tmp;
1543 char *caption = NULL, *descr = NULL;
1546 if (wwin->main_window != None) {
1547 WApplication *wapp = wApplicationOf(wwin->main_window);
1549 panel->appFrm = WMCreateFrame(panel->win);
1550 WMSetFrameTitle(panel->appFrm, _("Application Attributes"));
1551 WMMoveWidget(panel->appFrm, 15, 50);
1552 WMResizeWidget(panel->appFrm, frame_width, 240);
1554 for (i = 0; i < (sizeof(panel->appChk) / sizeof(panel->appChk[0])); i++) {
1555 switch (i) {
1556 case 0:
1557 caption = _("Start hidden");
1558 flag = WFLAGP(wapp->main_window_desc, start_hidden);
1559 descr = _("Automatically hide application when it's started.");
1560 break;
1561 case 1:
1562 caption = _("No application icon");
1563 flag = WFLAGP(wapp->main_window_desc, no_appicon);
1564 descr = _("Disable the application icon for the application.\n"
1565 "Note that you won't be able to dock it anymore,\n"
1566 "and any icons that are already docked will stop\n"
1567 "working correctly.");
1568 break;
1569 case 2:
1570 caption = _("Shared application icon");
1571 flag = WFLAGP(wapp->main_window_desc, shared_appicon);
1572 descr = _("Use a single shared application icon for all of\n"
1573 "the instances of this application.\n");
1574 break;
1576 panel->appChk[i] = WMCreateSwitchButton(panel->appFrm);
1577 WMMoveWidget(panel->appChk[i], 10, 20 * (i + 1));
1578 WMResizeWidget(panel->appChk[i], 205, 20);
1579 WMSetButtonSelected(panel->appChk[i], flag);
1580 WMSetButtonText(panel->appChk[i], caption);
1581 WMSetBalloonTextForView(descr, WMWidgetView(panel->appChk[i]));
1584 if (WFLAGP(wwin, emulate_appicon)) {
1585 WMSetButtonEnabled(panel->appChk[1], False);
1586 WMSetButtonEnabled(panel->moreChk[7], True);
1587 } else {
1588 WMSetButtonEnabled(panel->appChk[1], True);
1589 WMSetButtonEnabled(panel->moreChk[7], False);
1591 } else {
1592 if ((wwin->transient_for != None && wwin->transient_for != scr->root_win)
1593 || !wwin->wm_class || !wwin->wm_instance)
1594 tmp = False;
1595 else
1596 tmp = True;
1598 WMSetButtonEnabled(panel->moreChk[7], tmp);
1600 WMSetPopUpButtonItemEnabled(panel->pagePopUp, 4, False);
1601 panel->appFrm = NULL;