window.c clean code 1
[wmaker-crm.git] / src / winspector.c
blobd3f49d03aad17ed87a792f16bc7a80047b7e4319
1 /* winspector.c - window attribute inspector
3 * Window Maker window manager
5 * Copyright (c) 1997-2003 Alfredo K. Kojima
6 * Copyright (c) 1998-2003 Dan Pascu
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23 #include "wconfig.h"
25 #include <X11/Xlib.h>
26 #include <X11/Xutil.h>
27 #include <stdlib.h>
28 #include <stdio.h>
29 #include <string.h>
30 #include <strings.h>
32 #include "WindowMaker.h"
33 #include "screen.h"
34 #include "wcore.h"
35 #include "framewin.h"
36 #include "window.h"
37 #include "workspace.h"
38 #include "funcs.h"
39 #include "defaults.h"
40 #include "dialog.h"
41 #include "icon.h"
42 #include "stacking.h"
43 #include "application.h"
44 #include "appicon.h"
45 #include "actions.h"
46 #include "winspector.h"
47 #include "dock.h"
48 #include "client.h"
49 #include "wmspec.h"
51 #include <WINGs/WUtil.h>
53 typedef struct InspectorPanel {
54 struct InspectorPanel *nextPtr;
56 WWindow *frame;
58 WWindow *inspected; /* the window that's being inspected */
60 WMWindow *win;
62 Window parent;
64 /* common stuff */
65 WMButton *revertBtn;
66 WMButton *applyBtn;
67 WMButton *saveBtn;
69 WMPopUpButton *pagePopUp;
71 /* first page. general stuff */
73 WMFrame *specFrm;
74 WMButton *instRb;
75 WMButton *clsRb;
76 WMButton *bothRb;
77 WMButton *defaultRb;
79 WMButton *selWinB;
81 WMLabel *specLbl;
83 /* second page. attributes */
85 WMFrame *attrFrm;
86 WMButton *attrChk[11];
88 /* 3rd page. more attributes */
89 WMFrame *moreFrm;
90 #ifdef XKB_BUTTON_HINT
91 WMButton *moreChk[12];
92 #else
93 WMButton *moreChk[11];
94 #endif
96 /* 4th page. icon and workspace */
97 WMFrame *iconFrm;
98 WMLabel *iconLbl;
99 WMLabel *fileLbl;
100 WMTextField *fileText;
101 WMButton *alwChk;
103 WMButton *updateIconBtn;
105 WMButton *browseIconBtn;
107 WMFrame *wsFrm;
108 WMPopUpButton *wsP;
110 /* 5th page. application wide attributes */
111 WMFrame *appFrm;
112 WMButton *appChk[3];
114 unsigned int done:1;
115 unsigned int destroyed:1;
116 unsigned int choosingIcon:1;
117 } InspectorPanel;
119 extern Cursor wCursor[WCUR_LAST];
120 extern WDDomain *WDWindowAttributes;
121 extern WPreferences wPreferences;
123 static InspectorPanel *panelList = NULL;
124 static WMPropList *ANoTitlebar = NULL;
125 static WMPropList *ANoResizebar;
126 static WMPropList *ANoMiniaturizeButton;
127 static WMPropList *ANoCloseButton;
128 static WMPropList *ANoBorder;
129 static WMPropList *ANoHideOthers;
130 static WMPropList *ANoMouseBindings;
131 static WMPropList *ANoKeyBindings;
132 static WMPropList *ANoAppIcon;
133 static WMPropList *AKeepOnTop;
134 static WMPropList *AKeepOnBottom;
135 static WMPropList *AOmnipresent;
136 static WMPropList *ASkipWindowList;
137 static WMPropList *ASkipSwitchPanel;
138 static WMPropList *AKeepInsideScreen;
139 static WMPropList *AUnfocusable;
140 static WMPropList *AFocusAcrossWorkspace;
141 static WMPropList *AAlwaysUserIcon;
142 static WMPropList *AStartMiniaturized;
143 static WMPropList *AStartMaximized;
144 static WMPropList *ADontSaveSession;
145 static WMPropList *AEmulateAppIcon;
146 static WMPropList *AFullMaximize;
147 static WMPropList *ASharedAppIcon;
148 static WMPropList *ANoMiniaturizable;
149 #ifdef XKB_BUTTON_HINT
150 static WMPropList *ANoLanguageButton;
151 #endif
152 static WMPropList *AStartWorkspace;
153 static WMPropList *AIcon;
155 /* application wide options */
156 static WMPropList *AStartHidden;
157 static WMPropList *AnyWindow;
158 static WMPropList *EmptyString;
159 static WMPropList *Yes, *No;
161 #define PWIDTH 290
162 #define PHEIGHT 360
164 static char *spec_text;
165 static void applySettings(WMButton *button, InspectorPanel *panel);
167 #define UNDEFINED_POS 0xffffff
169 static InspectorPanel *createInspectorForWindow(WWindow *wwin, int xpos, int ypos, Bool showSelectPanel);
171 static void make_keys(void)
173 if (ANoTitlebar != NULL)
174 return;
176 AIcon = WMCreatePLString("Icon");
177 ANoTitlebar = WMCreatePLString("NoTitlebar");
178 ANoResizebar = WMCreatePLString("NoResizebar");
179 ANoMiniaturizeButton = WMCreatePLString("NoMiniaturizeButton");
180 ANoCloseButton = WMCreatePLString("NoCloseButton");
181 ANoBorder = WMCreatePLString("NoBorder");
182 ANoHideOthers = WMCreatePLString("NoHideOthers");
183 ANoMouseBindings = WMCreatePLString("NoMouseBindings");
184 ANoKeyBindings = WMCreatePLString("NoKeyBindings");
185 ANoAppIcon = WMCreatePLString("NoAppIcon");
186 AKeepOnTop = WMCreatePLString("KeepOnTop");
187 AKeepOnBottom = WMCreatePLString("KeepOnBottom");
188 AOmnipresent = WMCreatePLString("Omnipresent");
189 ASkipWindowList = WMCreatePLString("SkipWindowList");
190 ASkipSwitchPanel = WMCreatePLString("SkipSwitchPanel");
191 AKeepInsideScreen = WMCreatePLString("KeepInsideScreen");
192 AUnfocusable = WMCreatePLString("Unfocusable");
193 AFocusAcrossWorkspace = WMCreatePLString("FocusAcrossWorkspace");
194 AAlwaysUserIcon = WMCreatePLString("AlwaysUserIcon");
195 AStartMiniaturized = WMCreatePLString("StartMiniaturized");
196 AStartMaximized = WMCreatePLString("StartMaximized");
197 AStartHidden = WMCreatePLString("StartHidden");
198 ADontSaveSession = WMCreatePLString("DontSaveSession");
199 AEmulateAppIcon = WMCreatePLString("EmulateAppIcon");
200 AFullMaximize = WMCreatePLString("FullMaximize");
201 ASharedAppIcon = WMCreatePLString("SharedAppIcon");
202 ANoMiniaturizable = WMCreatePLString("NoMiniaturizable");
203 #ifdef XKB_BUTTON_HINT
204 ANoLanguageButton = WMCreatePLString("NoLanguageButton");
205 #endif
207 AStartWorkspace = WMCreatePLString("StartWorkspace");
209 AnyWindow = WMCreatePLString("*");
210 EmptyString = WMCreatePLString("");
211 Yes = WMCreatePLString("Yes");
212 No = WMCreatePLString("No");
215 static void freeInspector(InspectorPanel *panel)
217 panel->destroyed = 1;
219 if (panel->choosingIcon)
220 return;
222 WMDestroyWidget(panel->win);
223 XDestroyWindow(dpy, panel->parent);
224 wfree(panel);
227 static void destroyInspector(WCoreWindow *foo, void *data, XEvent *event)
229 InspectorPanel *panel;
230 InspectorPanel *tmp;
232 panel = panelList;
233 while (panel->frame != data)
234 panel = panel->nextPtr;
236 if (panelList == panel)
237 panelList = panel->nextPtr;
238 else {
239 tmp = panelList;
240 while (tmp->nextPtr != panel) {
241 tmp = tmp->nextPtr;
243 tmp->nextPtr = panel->nextPtr;
245 panel->inspected->flags.inspector_open = 0;
246 panel->inspected->inspector = NULL;
248 WMRemoveNotificationObserver(panel);
250 wWindowUnmap(panel->frame);
251 wUnmanageWindow(panel->frame, True, False);
253 freeInspector(panel);
256 void wDestroyInspectorPanels(void)
258 InspectorPanel *panel;
260 while (panelList != NULL) {
261 panel = panelList;
262 panelList = panelList->nextPtr;
263 wUnmanageWindow(panel->frame, False, False);
264 WMDestroyWidget(panel->win);
266 panel->inspected->flags.inspector_open = 0;
267 panel->inspected->inspector = NULL;
269 wfree(panel);
273 static void changePage(WMPopUpButton *bPtr, InspectorPanel *panel)
275 int page;
277 page = WMGetPopUpButtonSelectedItem(bPtr);
279 if (page == 0) {
280 WMMapWidget(panel->specFrm);
281 WMMapWidget(panel->specLbl);
282 } else if (page == 1) {
283 WMMapWidget(panel->attrFrm);
284 } else if (page == 2) {
285 WMMapWidget(panel->moreFrm);
286 } else if (page == 3) {
287 WMMapWidget(panel->iconFrm);
288 WMMapWidget(panel->wsFrm);
289 } else {
290 WMMapWidget(panel->appFrm);
293 if (page != 0) {
294 WMUnmapWidget(panel->specFrm);
295 WMUnmapWidget(panel->specLbl);
297 if (page != 1)
298 WMUnmapWidget(panel->attrFrm);
299 if (page != 2)
300 WMUnmapWidget(panel->moreFrm);
301 if (page != 3) {
302 WMUnmapWidget(panel->iconFrm);
303 WMUnmapWidget(panel->wsFrm);
305 if (page != 4 && panel->appFrm)
306 WMUnmapWidget(panel->appFrm);
309 #define USE_TEXT_FIELD 1
310 #define UPDATE_TEXT_FIELD 2
311 #define REVERT_TO_DEFAULT 4
313 static int showIconFor(WMScreen *scrPtr, InspectorPanel *panel, char *wm_instance, char *wm_class, int flags)
315 WMPixmap *pixmap = (WMPixmap *) NULL;
316 char *file = NULL, *path = NULL;
317 char *db_icon = NULL;
319 if ((flags & USE_TEXT_FIELD) != 0) {
320 file = WMGetTextFieldText(panel->fileText);
321 if (file && file[0] == 0) {
322 wfree(file);
323 file = NULL;
325 } else {
326 /* Get the application icon, default included */
327 db_icon = wDefaultGetIconFile(wm_instance, wm_class, True);
328 if (db_icon != NULL)
329 file = wstrdup(db_icon);
331 if (db_icon != NULL && (flags & REVERT_TO_DEFAULT) != 0) {
332 if (file)
333 file = wstrdup(db_icon);
334 flags |= UPDATE_TEXT_FIELD;
337 if ((flags & UPDATE_TEXT_FIELD) != 0) {
338 WMSetTextFieldText(panel->fileText, file);
341 if (file) {
342 path = FindImage(wPreferences.icon_path, file);
344 if (!path) {
345 char *buf;
346 int len = strlen(file) + 80;
348 buf = wmalloc(len);
349 snprintf(buf, len, _("Could not find icon \"%s\" specified for this window"), file);
350 wMessageDialog(panel->frame->screen_ptr, _("Error"), buf, _("OK"), NULL, NULL);
351 wfree(buf);
352 wfree(file);
353 return -1;
356 pixmap = WMCreatePixmapFromFile(scrPtr, path);
357 wfree(path);
359 if (!pixmap) {
360 char *buf;
361 int len = strlen(file) + 80;
363 buf = wmalloc(len);
364 snprintf(buf, len, _("Could not open specified icon \"%s\":%s"),
365 file, RMessageForError(RErrorCode));
366 wMessageDialog(panel->frame->screen_ptr, _("Error"), buf, _("OK"), NULL, NULL);
367 wfree(buf);
368 wfree(file);
369 return -1;
371 wfree(file);
374 WMSetLabelImage(panel->iconLbl, pixmap);
375 if (pixmap)
376 WMReleasePixmap(pixmap);
378 return 0;
381 #if 0
382 static void updateIcon(WMButton * button, InspectorPanel * panel)
384 showIconFor(WMWidgetScreen(button), panel, NULL, NULL, USE_TEXT_FIELD);
386 #endif
388 static int getBool(WMPropList *value)
390 char *val;
392 if (!WMIsPLString(value)) {
393 return 0;
395 if (!(val = WMGetFromPLString(value))) {
396 return 0;
399 if ((val[1] == '\0' && (val[0] == 'y' || val[0] == 'Y' || val[0] == 'T' || val[0] == 't' || val[0] == '1'))
400 || (strcasecmp(val, "YES") == 0 || strcasecmp(val, "TRUE") == 0)) {
402 return 1;
403 } else if ((val[1] == '\0'
404 && (val[0] == 'n' || val[0] == 'N' || val[0] == 'F' || val[0] == 'f' || val[0] == '0'))
405 || (strcasecmp(val, "NO") == 0 || strcasecmp(val, "FALSE") == 0)) {
407 return 0;
408 } else {
409 wwarning(_("can't convert \"%s\" to boolean"), val);
410 return 0;
414 #define UPDATE_DEFAULTS 1
415 #define IS_BOOLEAN 2
418 * Will insert the attribute = value; pair in window's list,
419 * if it's different from the defaults.
420 * Defaults means either defaults database, or attributes saved
421 * for the default window "*". This is to let one revert options that are
422 * global because they were saved for all windows ("*").
426 static int
427 insertAttribute(WMPropList *dict, WMPropList *window, WMPropList *attr, WMPropList *value, int flags)
429 WMPropList *def_win, *def_value = NULL;
430 int update = 0;
431 int modified = 0;
433 if (!(flags & UPDATE_DEFAULTS) && dict) {
434 if ((def_win = WMGetFromPLDictionary(dict, AnyWindow)) != NULL) {
435 def_value = WMGetFromPLDictionary(def_win, attr);
439 /* If we could not find defaults in database, fall to hardcoded values.
440 * Also this is true if we save defaults for all windows
442 if (!def_value)
443 def_value = ((flags & IS_BOOLEAN) != 0) ? No : EmptyString;
445 if ((flags & IS_BOOLEAN))
446 update = (getBool(value) != getBool(def_value));
447 else {
448 update = !WMIsPropListEqualTo(value, def_value);
451 if (update) {
452 WMPutInPLDictionary(window, attr, value);
453 modified = 1;
456 return modified;
459 static void saveSettings(WMButton *button, InspectorPanel *panel)
461 WWindow *wwin = panel->inspected;
462 WDDomain *db = WDWindowAttributes;
463 WMPropList *dict = db->dictionary;
464 WMPropList *winDic, *appDic, *value, *key, *key2;
465 char *icon_file;
466 int flags = 0;
467 int different = 0, different2 = 0;
469 /* Save will apply the changes and save them */
470 applySettings(panel->applyBtn, panel);
472 if (WMGetButtonSelected(panel->instRb) != 0)
473 key = WMCreatePLString(wwin->wm_instance);
474 else if (WMGetButtonSelected(panel->clsRb) != 0)
475 key = WMCreatePLString(wwin->wm_class);
476 else if (WMGetButtonSelected(panel->bothRb) != 0) {
477 char *buffer;
479 buffer = StrConcatDot(wwin->wm_instance, wwin->wm_class);
480 key = WMCreatePLString(buffer);
481 wfree(buffer);
482 } else if (WMGetButtonSelected(panel->defaultRb) != 0) {
483 key = WMRetainPropList(AnyWindow);
484 flags = UPDATE_DEFAULTS;
485 } else
486 key = NULL;
488 if (!key)
489 return;
491 if (!dict) {
492 dict = WMCreatePLDictionary(NULL, NULL);
493 if (dict) {
494 db->dictionary = dict;
495 } else {
496 WMReleasePropList(key);
497 return;
501 if (showIconFor(WMWidgetScreen(button), panel, NULL, NULL, USE_TEXT_FIELD) < 0)
502 return;
504 WMPLSetCaseSensitive(True);
506 winDic = WMCreatePLDictionary(NULL, NULL);
507 appDic = WMCreatePLDictionary(NULL, NULL);
509 /* Update icon for window */
510 icon_file = WMGetTextFieldText(panel->fileText);
511 if (icon_file) {
512 if (icon_file[0] != 0) {
513 value = WMCreatePLString(icon_file);
514 different |= insertAttribute(dict, winDic, AIcon, value, flags);
515 different2 |= insertAttribute(dict, appDic, AIcon, value, flags);
516 WMReleasePropList(value);
518 wfree(icon_file);
522 int i = WMGetPopUpButtonSelectedItem(panel->wsP);
524 i--;
526 if (i >= 0 && i < panel->frame->screen_ptr->workspace_count) {
527 value = WMCreatePLString(panel->frame->screen_ptr->workspaces[i]->name);
528 different |= insertAttribute(dict, winDic, AStartWorkspace, value, flags);
529 WMReleasePropList(value);
533 flags |= IS_BOOLEAN;
535 value = (WMGetButtonSelected(panel->alwChk) != 0) ? Yes : No;
536 different |= insertAttribute(dict, winDic, AAlwaysUserIcon, value, flags);
538 value = (WMGetButtonSelected(panel->attrChk[0]) != 0) ? Yes : No;
539 different |= insertAttribute(dict, winDic, ANoTitlebar, value, flags);
541 value = (WMGetButtonSelected(panel->attrChk[1]) != 0) ? Yes : No;
542 different |= insertAttribute(dict, winDic, ANoResizebar, value, flags);
544 value = (WMGetButtonSelected(panel->attrChk[2]) != 0) ? Yes : No;
545 different |= insertAttribute(dict, winDic, ANoCloseButton, value, flags);
547 value = (WMGetButtonSelected(panel->attrChk[3]) != 0) ? Yes : No;
548 different |= insertAttribute(dict, winDic, ANoMiniaturizeButton, value, flags);
550 value = (WMGetButtonSelected(panel->attrChk[4]) != 0) ? Yes : No;
551 different |= insertAttribute(dict, winDic, ANoBorder, value, flags);
553 value = (WMGetButtonSelected(panel->attrChk[5]) != 0) ? Yes : No;
554 different |= insertAttribute(dict, winDic, AKeepOnTop, value, flags);
556 value = (WMGetButtonSelected(panel->attrChk[6]) != 0) ? Yes : No;
557 different |= insertAttribute(dict, winDic, AKeepOnBottom, value, flags);
559 value = (WMGetButtonSelected(panel->attrChk[7]) != 0) ? Yes : No;
560 different |= insertAttribute(dict, winDic, AOmnipresent, value, flags);
562 value = (WMGetButtonSelected(panel->attrChk[8]) != 0) ? Yes : No;
563 different |= insertAttribute(dict, winDic, AStartMiniaturized, value, flags);
565 value = (WMGetButtonSelected(panel->attrChk[9]) != 0) ? Yes : No;
566 different |= insertAttribute(dict, winDic, AStartMaximized, value, flags);
568 value = (WMGetButtonSelected(panel->attrChk[10]) != 0) ? Yes : No;
569 different |= insertAttribute(dict, winDic, AFullMaximize, value, flags);
571 value = (WMGetButtonSelected(panel->moreChk[0]) != 0) ? Yes : No;
572 different |= insertAttribute(dict, winDic, ANoKeyBindings, value, flags);
574 value = (WMGetButtonSelected(panel->moreChk[1]) != 0) ? Yes : No;
575 different |= insertAttribute(dict, winDic, ANoMouseBindings, value, flags);
577 value = (WMGetButtonSelected(panel->moreChk[2]) != 0) ? Yes : No;
578 different |= insertAttribute(dict, winDic, ASkipWindowList, value, flags);
580 value = (WMGetButtonSelected(panel->moreChk[3]) != 0) ? Yes : No;
581 different |= insertAttribute(dict, winDic, ASkipSwitchPanel, value, flags);
583 value = (WMGetButtonSelected(panel->moreChk[4]) != 0) ? Yes : No;
584 different |= insertAttribute(dict, winDic, AUnfocusable, value, flags);
586 value = (WMGetButtonSelected(panel->moreChk[5]) != 0) ? Yes : No;
587 different |= insertAttribute(dict, winDic, AKeepInsideScreen, value, flags);
589 value = (WMGetButtonSelected(panel->moreChk[6]) != 0) ? Yes : No;
590 different |= insertAttribute(dict, winDic, ANoHideOthers, value, flags);
592 value = (WMGetButtonSelected(panel->moreChk[7]) != 0) ? Yes : No;
593 different |= insertAttribute(dict, winDic, ADontSaveSession, value, flags);
595 value = (WMGetButtonSelected(panel->moreChk[8]) != 0) ? Yes : No;
596 different |= insertAttribute(dict, winDic, AEmulateAppIcon, value, flags);
598 value = (WMGetButtonSelected(panel->moreChk[9]) != 0) ? Yes : No;
599 different |= insertAttribute(dict, winDic, AFocusAcrossWorkspace, value, flags);
601 value = (WMGetButtonSelected(panel->moreChk[10]) != 0) ? Yes : No;
602 different |= insertAttribute(dict, winDic, ANoMiniaturizable, value, flags);
604 #ifdef XKB_BUTTON_HINT
605 value = (WMGetButtonSelected(panel->moreChk[11]) != 0) ? Yes : No;
606 different |= insertAttribute(dict, winDic, ANoLanguageButton, value, flags);
607 #endif
609 if (wwin->main_window != None && wApplicationOf(wwin->main_window) != NULL) {
610 value = (WMGetButtonSelected(panel->appChk[0]) != 0) ? Yes : No;
611 different2 |= insertAttribute(dict, appDic, AStartHidden, value, flags);
613 value = (WMGetButtonSelected(panel->appChk[1]) != 0) ? Yes : No;
614 different2 |= insertAttribute(dict, appDic, ANoAppIcon, value, flags);
616 value = (WMGetButtonSelected(panel->appChk[2]) != 0) ? Yes : No;
617 different2 |= insertAttribute(dict, appDic, ASharedAppIcon, value, flags);
620 if (wwin->fake_group) {
621 key2 = WMCreatePLString(wwin->fake_group->identifier);
622 if (WMIsPropListEqualTo(key, key2)) {
623 WMMergePLDictionaries(winDic, appDic, True);
624 different |= different2;
625 } else {
626 WMRemoveFromPLDictionary(dict, key2);
627 if (different2) {
628 WMPutInPLDictionary(dict, key2, appDic);
631 WMReleasePropList(key2);
632 WMReleasePropList(appDic);
633 } else if (wwin->main_window != wwin->client_win) {
634 WApplication *wapp = wApplicationOf(wwin->main_window);
636 if (wapp) {
637 char *instance = wapp->main_window_desc->wm_instance;
638 char *class = wapp->main_window_desc->wm_class;
639 char *buffer;
641 buffer = StrConcatDot(instance, class);
642 key2 = WMCreatePLString(buffer);
643 wfree(buffer);
645 if (WMIsPropListEqualTo(key, key2)) {
646 WMMergePLDictionaries(winDic, appDic, True);
647 different |= different2;
648 } else {
649 WMRemoveFromPLDictionary(dict, key2);
650 if (different2)
651 WMPutInPLDictionary(dict, key2, appDic);
653 WMReleasePropList(key2);
654 WMReleasePropList(appDic);
656 } else {
657 WMMergePLDictionaries(winDic, appDic, True);
658 different |= different2;
659 WMReleasePropList(appDic);
662 WMRemoveFromPLDictionary(dict, key);
663 if (different) {
664 WMPutInPLDictionary(dict, key, winDic);
667 WMReleasePropList(key);
668 WMReleasePropList(winDic);
670 UpdateDomainFile(db);
672 /* clean up */
673 WMPLSetCaseSensitive(False);
676 static void applySettings(WMButton *button, InspectorPanel *panel)
678 WWindow *wwin = panel->inspected;
679 WApplication *wapp = wApplicationOf(wwin->main_window);
680 int floating, sunken, skip_window_list;
681 int old_omnipresent;
682 int old_no_bind_keys;
683 int old_no_bind_mouse;
685 old_omnipresent = WFLAGP(wwin, omnipresent);
686 old_no_bind_keys = WFLAGP(wwin, no_bind_keys);
687 old_no_bind_mouse = WFLAGP(wwin, no_bind_mouse);
689 showIconFor(WMWidgetScreen(button), panel, NULL, NULL, USE_TEXT_FIELD);
691 /* Attributes... --> Window Attributes */
692 WSETUFLAG(wwin, no_titlebar, WMGetButtonSelected(panel->attrChk[0]));
693 WSETUFLAG(wwin, no_resizebar, WMGetButtonSelected(panel->attrChk[1]));
694 WSETUFLAG(wwin, no_close_button, WMGetButtonSelected(panel->attrChk[2]));
695 WSETUFLAG(wwin, no_miniaturize_button, WMGetButtonSelected(panel->attrChk[3]));
696 WSETUFLAG(wwin, no_border, WMGetButtonSelected(panel->attrChk[4]));
697 floating = WMGetButtonSelected(panel->attrChk[5]);
698 sunken = WMGetButtonSelected(panel->attrChk[6]);
699 WSETUFLAG(wwin, omnipresent, WMGetButtonSelected(panel->attrChk[7]));
700 WSETUFLAG(wwin, start_miniaturized, WMGetButtonSelected(panel->attrChk[8]));
701 WSETUFLAG(wwin, start_maximized, WMGetButtonSelected(panel->attrChk[9]));
702 WSETUFLAG(wwin, full_maximize, WMGetButtonSelected(panel->attrChk[10]));
704 /* Attributes... --> Advanced Options */
705 WSETUFLAG(wwin, no_bind_keys, WMGetButtonSelected(panel->moreChk[0]));
706 WSETUFLAG(wwin, no_bind_mouse, WMGetButtonSelected(panel->moreChk[1]));
707 skip_window_list = WMGetButtonSelected(panel->moreChk[2]);
708 WSETUFLAG(wwin, skip_switchpanel, WMGetButtonSelected(panel->moreChk[3]));
709 WSETUFLAG(wwin, no_focusable, WMGetButtonSelected(panel->moreChk[4]));
710 WSETUFLAG(wwin, dont_move_off, WMGetButtonSelected(panel->moreChk[5]));
711 WSETUFLAG(wwin, no_hide_others, WMGetButtonSelected(panel->moreChk[6]));
712 WSETUFLAG(wwin, dont_save_session, WMGetButtonSelected(panel->moreChk[7]));
713 WSETUFLAG(wwin, emulate_appicon, WMGetButtonSelected(panel->moreChk[8]));
714 WSETUFLAG(wwin, focus_across_wksp, WMGetButtonSelected(panel->moreChk[9]));
715 WSETUFLAG(wwin, no_miniaturizable, WMGetButtonSelected(panel->moreChk[10]));
716 #ifdef XKB_BUTTON_HINT
717 WSETUFLAG(wwin, no_language_button, WMGetButtonSelected(panel->moreChk[11]));
718 #endif
719 WSETUFLAG(wwin, always_user_icon, WMGetButtonSelected(panel->alwChk));
721 if (WFLAGP(wwin, no_titlebar) && wwin->flags.shaded)
722 wUnshadeWindow(wwin);
724 WSETUFLAG(wwin, no_shadeable, WFLAGP(wwin, no_titlebar));
726 if (floating) {
727 if (!WFLAGP(wwin, floating))
728 ChangeStackingLevel(wwin->frame->core, WMFloatingLevel);
729 } else if (sunken) {
730 if (!WFLAGP(wwin, sunken))
731 ChangeStackingLevel(wwin->frame->core, WMSunkenLevel);
732 } else {
733 if (WFLAGP(wwin, floating) || WFLAGP(wwin, sunken))
734 ChangeStackingLevel(wwin->frame->core, WMNormalLevel);
737 WSETUFLAG(wwin, sunken, sunken);
738 WSETUFLAG(wwin, floating, floating);
739 wwin->flags.omnipresent = 0;
741 if (WFLAGP(wwin, skip_window_list) != skip_window_list) {
742 WSETUFLAG(wwin, skip_window_list, skip_window_list);
743 UpdateSwitchMenu(wwin->screen_ptr, wwin, skip_window_list ? ACTION_REMOVE : ACTION_ADD);
744 } else {
745 if (WFLAGP(wwin, omnipresent) != old_omnipresent) {
746 WMPostNotificationName(WMNChangedState, wwin, "omnipresent");
750 if (WFLAGP(wwin, no_bind_keys) != old_no_bind_keys) {
751 if (WFLAGP(wwin, no_bind_keys)) {
752 XUngrabKey(dpy, AnyKey, AnyModifier, wwin->frame->core->window);
753 } else {
754 wWindowSetKeyGrabs(wwin);
758 if (WFLAGP(wwin, no_bind_mouse) != old_no_bind_mouse) {
759 wWindowResetMouseGrabs(wwin);
762 wwin->frame->flags.need_texture_change = 1;
763 wWindowConfigureBorders(wwin);
764 wFrameWindowPaint(wwin->frame);
765 wNETWMUpdateActions(wwin, False);
768 * Can't apply emulate_appicon because it will probably cause problems.
770 if (wapp) {
771 /* do application wide stuff */
772 WSETUFLAG(wapp->main_window_desc, start_hidden, WMGetButtonSelected(panel->appChk[0]));
773 WSETUFLAG(wapp->main_window_desc, no_appicon, WMGetButtonSelected(panel->appChk[1]));
774 WSETUFLAG(wapp->main_window_desc, shared_appicon, WMGetButtonSelected(panel->appChk[2]));
776 if (WFLAGP(wapp->main_window_desc, no_appicon))
777 unpaint_app_icon(wapp);
778 else
779 paint_app_icon(wapp);
781 char *file = WMGetTextFieldText(panel->fileText);
782 if (file[0] == 0) {
783 wfree(file);
784 file = NULL;
787 if (WFLAGP(wwin, always_user_icon)) {
788 /* Change icon image if the app is minimized */
789 if (wwin->icon)
790 wIconChangeImageFile(wwin->icon, file);
792 /* Change App Icon image */
793 if (wapp->app_icon)
794 wIconChangeImageFile(wapp->app_icon->icon, file);
795 } else {
796 /* Change App Icon image */
797 if (wapp->app_icon)
798 wIconUpdate(wapp->app_icon->icon, get_rimage_icon_from_wm_hints(wapp->app_icon->icon));
800 /* Change icon image if the app is minimized */
801 if (wwin->icon)
802 wIconUpdate(wwin->icon, get_rimage_icon_from_wm_hints(wwin->icon));
805 if (file)
806 wfree(file);
809 wNETFrameExtents(wwin);
812 static void revertSettings(WMButton *button, InspectorPanel *panel)
814 WWindow *wwin = panel->inspected;
815 WApplication *wapp = wApplicationOf(wwin->main_window);
816 int i, n;
817 char *wm_instance = NULL;
818 char *wm_class = NULL;
819 int workspace, level;
821 if (panel->instRb && WMGetButtonSelected(panel->instRb) != 0)
822 wm_instance = wwin->wm_instance;
823 else if (panel->clsRb && WMGetButtonSelected(panel->clsRb) != 0)
824 wm_class = wwin->wm_class;
825 else if (panel->bothRb && WMGetButtonSelected(panel->bothRb) != 0) {
826 wm_instance = wwin->wm_instance;
827 wm_class = wwin->wm_class;
829 memset(&wwin->defined_user_flags, 0, sizeof(WWindowAttributes));
830 memset(&wwin->user_flags, 0, sizeof(WWindowAttributes));
831 memset(&wwin->client_flags, 0, sizeof(WWindowAttributes));
833 wWindowSetupInitialAttributes(wwin, &level, &workspace);
835 for (i = 0; i < (sizeof(panel->attrChk) / sizeof(panel->attrChk[0])); i++) {
836 int flag = 0;
838 switch (i) {
839 case 0:
840 flag = WFLAGP(wwin, no_titlebar);
841 break;
842 case 1:
843 flag = WFLAGP(wwin, no_resizebar);
844 break;
845 case 2:
846 flag = WFLAGP(wwin, no_close_button);
847 break;
848 case 3:
849 flag = WFLAGP(wwin, no_miniaturize_button);
850 break;
851 case 4:
852 flag = WFLAGP(wwin, no_border);
853 break;
854 case 5:
855 flag = WFLAGP(wwin, floating);
856 break;
857 case 6:
858 flag = WFLAGP(wwin, sunken);
859 break;
860 case 7:
861 flag = WFLAGP(wwin, omnipresent);
862 break;
863 case 8:
864 flag = WFLAGP(wwin, start_miniaturized);
865 break;
866 case 9:
867 flag = WFLAGP(wwin, start_maximized != 0);
868 break;
869 case 10:
870 flag = WFLAGP(wwin, full_maximize);
871 break;
873 WMSetButtonSelected(panel->attrChk[i], flag);
875 for (i = 0; i < (sizeof(panel->moreChk) / sizeof(panel->moreChk[0])); i++) {
876 int flag = 0;
878 switch (i) {
879 case 0:
880 flag = WFLAGP(wwin, no_bind_keys);
881 break;
882 case 1:
883 flag = WFLAGP(wwin, no_bind_mouse);
884 break;
885 case 2:
886 flag = WFLAGP(wwin, skip_window_list);
887 break;
888 case 3:
889 flag = WFLAGP(wwin, skip_switchpanel);
890 break;
891 case 4:
892 flag = WFLAGP(wwin, no_focusable);
893 break;
894 case 5:
895 flag = WFLAGP(wwin, dont_move_off);
896 break;
897 case 6:
898 flag = WFLAGP(wwin, no_hide_others);
899 break;
900 case 7:
901 flag = WFLAGP(wwin, dont_save_session);
902 break;
903 case 8:
904 flag = WFLAGP(wwin, emulate_appicon);
905 break;
906 case 9:
907 flag = WFLAGP(wwin, focus_across_wksp);
908 break;
909 case 10:
910 flag = WFLAGP(wwin, no_miniaturizable);
911 break;
912 #ifdef XKB_BUTTON_HINT
913 case 11:
914 flag = WFLAGP(wwin, no_language_button);
915 break;
916 #endif
918 WMSetButtonSelected(panel->moreChk[i], flag);
920 if (panel->appFrm && wapp) {
921 for (i = 0; i < (sizeof(panel->appChk) / sizeof(panel->appChk[0])); i++) {
922 int flag = 0;
924 switch (i) {
925 case 0:
926 flag = WFLAGP(wapp->main_window_desc, start_hidden);
927 break;
928 case 1:
929 flag = WFLAGP(wapp->main_window_desc, no_appicon);
930 break;
931 case 2:
932 flag = WFLAGP(wapp->main_window_desc, shared_appicon);
933 break;
935 WMSetButtonSelected(panel->appChk[i], flag);
938 WMSetButtonSelected(panel->alwChk, WFLAGP(wwin, always_user_icon));
940 showIconFor(WMWidgetScreen(panel->alwChk), panel, wm_instance, wm_class, REVERT_TO_DEFAULT);
942 n = wDefaultGetStartWorkspace(wwin->screen_ptr, wm_instance, wm_class);
944 if (n >= 0 && n < wwin->screen_ptr->workspace_count) {
945 WMSetPopUpButtonSelectedItem(panel->wsP, n + 1);
946 } else {
947 WMSetPopUpButtonSelectedItem(panel->wsP, 0);
950 /* must auto apply, so that there wno't be internal
951 * inconsistencies between the state in the flags and
952 * the actual state of the window */
953 applySettings(panel->applyBtn, panel);
956 static void chooseIconCallback(WMWidget *self, void *clientData)
958 char *file;
959 InspectorPanel *panel = (InspectorPanel *) clientData;
960 int result;
962 panel->choosingIcon = 1;
964 WMSetButtonEnabled(panel->browseIconBtn, False);
966 result = wIconChooserDialog(panel->frame->screen_ptr, &file,
967 panel->inspected->wm_instance, panel->inspected->wm_class);
969 panel->choosingIcon = 0;
971 if (!panel->destroyed) { /* kluge */
972 if (result) {
973 WMSetTextFieldText(panel->fileText, file);
974 showIconFor(WMWidgetScreen(self), panel, NULL, NULL, USE_TEXT_FIELD);
975 wfree(file);
977 WMSetButtonEnabled(panel->browseIconBtn, True);
978 } else {
979 freeInspector(panel);
983 static void textEditedObserver(void *observerData, WMNotification *notification)
985 InspectorPanel *panel = (InspectorPanel *) observerData;
987 if ((long)WMGetNotificationClientData(notification) != WMReturnTextMovement)
988 return;
990 showIconFor(WMWidgetScreen(panel->win), panel, NULL, NULL, USE_TEXT_FIELD);
992 WMPerformButtonClick(panel->updateIconBtn);
996 static void selectSpecification(WMWidget *bPtr, void *data)
998 InspectorPanel *panel = (InspectorPanel *) data;
999 char *str;
1000 WWindow *wwin = panel->inspected;
1001 int len;
1003 if (bPtr == panel->defaultRb && (wwin->wm_instance || wwin->wm_class))
1004 WMSetButtonEnabled(panel->applyBtn, False);
1005 else
1006 WMSetButtonEnabled(panel->applyBtn, True);
1008 len = 16 + strlen(wwin->wm_instance ? wwin->wm_instance : "?")
1009 + strlen(wwin->wm_class ? wwin->wm_class : "?");
1011 str = wmalloc(len);
1013 snprintf(str, len, _("Inspecting %s.%s"),
1014 wwin->wm_instance ? wwin->wm_instance : "?", wwin->wm_class ? wwin->wm_class : "?");
1016 wFrameWindowChangeTitle(panel->frame->frame, str);
1018 wfree(str);
1021 static void selectWindow(WMWidget *bPtr, void *data)
1023 InspectorPanel *panel = (InspectorPanel *) data;
1024 WWindow *wwin = panel->inspected;
1025 WScreen *scr = wwin->screen_ptr;
1026 XEvent event;
1027 WWindow *iwin;
1029 if (XGrabPointer(dpy, scr->root_win, True,
1030 ButtonPressMask, GrabModeAsync, GrabModeAsync, None,
1031 wCursor[WCUR_SELECT], CurrentTime) != GrabSuccess) {
1032 wwarning("could not grab mouse pointer");
1033 return;
1036 WMSetLabelText(panel->specLbl, _("Click in the window you wish to inspect."));
1038 WMMaskEvent(dpy, ButtonPressMask, &event);
1040 XUngrabPointer(dpy, CurrentTime);
1042 iwin = wWindowFor(event.xbutton.subwindow);
1044 if (iwin && !iwin->flags.internal_window && iwin != wwin && !iwin->flags.inspector_open) {
1046 iwin->flags.inspector_open = 1;
1047 iwin->inspector = createInspectorForWindow(iwin,
1048 panel->frame->frame_x, panel->frame->frame_y, True);
1049 wCloseInspectorForWindow(wwin);
1050 } else {
1051 WMSetLabelText(panel->specLbl, spec_text);
1055 static InspectorPanel *createInspectorForWindow(WWindow *wwin, int xpos, int ypos, Bool showSelectPanel)
1057 WScreen *scr = wwin->screen_ptr;
1058 InspectorPanel *panel;
1059 Window parent;
1060 int i;
1061 int x, y;
1062 int btn_width, frame_width;
1063 WMButton *selectedBtn = NULL;
1064 #ifdef wrong_behaviour
1065 WMPixmap *pixmap;
1066 #endif
1068 spec_text = _("The configuration will apply to all\n"
1069 "windows that have their WM_CLASS\n"
1070 "property set to the above selected\n" "name, when saved.");
1072 panel = wmalloc(sizeof(InspectorPanel));
1073 memset(panel, 0, sizeof(InspectorPanel));
1075 panel->destroyed = 0;
1077 panel->inspected = wwin;
1079 panel->nextPtr = panelList;
1080 panelList = panel;
1082 panel->win = WMCreateWindow(scr->wmscreen, "windowInspector");
1083 WMResizeWidget(panel->win, PWIDTH, PHEIGHT);
1085 /**** create common stuff ****/
1087 /* command buttons */
1088 /* (PWIDTH - (left and right margin) - (btn interval)) / 3 */
1089 btn_width = (PWIDTH - (2 * 15) - (2 * 10)) / 3;
1090 panel->saveBtn = WMCreateCommandButton(panel->win);
1091 WMSetButtonAction(panel->saveBtn, (WMAction *) saveSettings, panel);
1092 WMMoveWidget(panel->saveBtn, (2 * (btn_width + 10)) + 15, PHEIGHT - 40);
1093 WMSetButtonText(panel->saveBtn, _("Save"));
1094 WMResizeWidget(panel->saveBtn, btn_width, 28);
1095 if (wPreferences.flags.noupdates || !(wwin->wm_class || wwin->wm_instance))
1096 WMSetButtonEnabled(panel->saveBtn, False);
1098 panel->applyBtn = WMCreateCommandButton(panel->win);
1099 WMSetButtonAction(panel->applyBtn, (WMAction *) applySettings, panel);
1100 WMMoveWidget(panel->applyBtn, btn_width + 10 + 15, PHEIGHT - 40);
1101 WMSetButtonText(panel->applyBtn, _("Apply"));
1102 WMResizeWidget(panel->applyBtn, btn_width, 28);
1104 panel->revertBtn = WMCreateCommandButton(panel->win);
1105 WMSetButtonAction(panel->revertBtn, (WMAction *) revertSettings, panel);
1106 WMMoveWidget(panel->revertBtn, 15, PHEIGHT - 40);
1107 WMSetButtonText(panel->revertBtn, _("Reload"));
1108 WMResizeWidget(panel->revertBtn, btn_width, 28);
1110 /* page selection popup button */
1111 panel->pagePopUp = WMCreatePopUpButton(panel->win);
1112 WMSetPopUpButtonAction(panel->pagePopUp, (WMAction *) changePage, panel);
1113 WMMoveWidget(panel->pagePopUp, 25, 15);
1114 WMResizeWidget(panel->pagePopUp, PWIDTH - 50, 20);
1116 WMAddPopUpButtonItem(panel->pagePopUp, _("Window Specification"));
1117 WMAddPopUpButtonItem(panel->pagePopUp, _("Window Attributes"));
1118 WMAddPopUpButtonItem(panel->pagePopUp, _("Advanced Options"));
1119 WMAddPopUpButtonItem(panel->pagePopUp, _("Icon and Initial Workspace"));
1120 WMAddPopUpButtonItem(panel->pagePopUp, _("Application Specific"));
1122 /**** window spec ****/
1123 frame_width = PWIDTH - (2 * 15);
1125 panel->specFrm = WMCreateFrame(panel->win);
1126 WMSetFrameTitle(panel->specFrm, _("Window Specification"));
1127 WMMoveWidget(panel->specFrm, 15, 65);
1128 WMResizeWidget(panel->specFrm, frame_width, 145);
1130 panel->defaultRb = WMCreateRadioButton(panel->specFrm);
1131 WMMoveWidget(panel->defaultRb, 10, 78);
1132 WMResizeWidget(panel->defaultRb, frame_width - (2 * 10), 20);
1133 WMSetButtonText(panel->defaultRb, _("Defaults for all windows"));
1134 WMSetButtonSelected(panel->defaultRb, False);
1135 WMSetButtonAction(panel->defaultRb, selectSpecification, panel);
1137 if (wwin->wm_class && wwin->wm_instance) {
1138 char *str, *tmp;
1140 tmp = wstrconcat(wwin->wm_instance, ".");
1141 str = wstrconcat(tmp, wwin->wm_class);
1143 panel->bothRb = WMCreateRadioButton(panel->specFrm);
1144 WMMoveWidget(panel->bothRb, 10, 18);
1145 WMResizeWidget(panel->bothRb, frame_width - (2 * 10), 20);
1146 WMSetButtonText(panel->bothRb, str);
1147 wfree(tmp);
1148 wfree(str);
1149 WMGroupButtons(panel->defaultRb, panel->bothRb);
1151 if (!selectedBtn)
1152 selectedBtn = panel->bothRb;
1154 WMSetButtonAction(panel->bothRb, selectSpecification, panel);
1157 if (wwin->wm_instance) {
1158 panel->instRb = WMCreateRadioButton(panel->specFrm);
1159 WMMoveWidget(panel->instRb, 10, 38);
1160 WMResizeWidget(panel->instRb, frame_width - (2 * 10), 20);
1161 WMSetButtonText(panel->instRb, wwin->wm_instance);
1162 WMGroupButtons(panel->defaultRb, panel->instRb);
1164 if (!selectedBtn)
1165 selectedBtn = panel->instRb;
1167 WMSetButtonAction(panel->instRb, selectSpecification, panel);
1170 if (wwin->wm_class) {
1171 panel->clsRb = WMCreateRadioButton(panel->specFrm);
1172 WMMoveWidget(panel->clsRb, 10, 58);
1173 WMResizeWidget(panel->clsRb, frame_width - (2 * 10), 20);
1174 WMSetButtonText(panel->clsRb, wwin->wm_class);
1175 WMGroupButtons(panel->defaultRb, panel->clsRb);
1177 if (!selectedBtn)
1178 selectedBtn = panel->clsRb;
1180 WMSetButtonAction(panel->clsRb, selectSpecification, panel);
1183 panel->selWinB = WMCreateCommandButton(panel->specFrm);
1184 WMMoveWidget(panel->selWinB, 20, 145 - 24 - 10);
1185 WMResizeWidget(panel->selWinB, frame_width - 2 * 10 - 20, 24);
1186 WMSetButtonText(panel->selWinB, _("Select window"));
1187 WMSetButtonAction(panel->selWinB, selectWindow, panel);
1189 panel->specLbl = WMCreateLabel(panel->win);
1190 WMMoveWidget(panel->specLbl, 15, 210);
1191 WMResizeWidget(panel->specLbl, frame_width, 100);
1192 WMSetLabelText(panel->specLbl, spec_text);
1193 WMSetLabelWraps(panel->specLbl, True);
1195 WMSetLabelTextAlignment(panel->specLbl, WALeft);
1197 /**** attributes ****/
1198 panel->attrFrm = WMCreateFrame(panel->win);
1199 WMSetFrameTitle(panel->attrFrm, _("Attributes"));
1200 WMMoveWidget(panel->attrFrm, 15, 45);
1201 WMResizeWidget(panel->attrFrm, frame_width, 250);
1203 for (i = 0; i < (sizeof(panel->attrChk) / sizeof(panel->attrChk[0])); i++) {
1204 char *caption = NULL;
1205 int flag = 0;
1206 char *descr = NULL;
1208 switch (i) {
1209 case 0:
1210 caption = _("Disable titlebar");
1211 flag = WFLAGP(wwin, no_titlebar);
1212 descr = _("Remove the titlebar of this window.\n"
1213 "To access the window commands menu of a window\n"
1214 "without it's titlebar, press Control+Esc (or the\n"
1215 "equivalent shortcut, if you changed the default\n" "settings).");
1216 break;
1217 case 1:
1218 caption = _("Disable resizebar");
1219 flag = WFLAGP(wwin, no_resizebar);
1220 descr = _("Remove the resizebar of this window.");
1221 break;
1222 case 2:
1223 caption = _("Disable close button");
1224 flag = WFLAGP(wwin, no_close_button);
1225 descr = _("Remove the `close window' button of this window.");
1226 break;
1227 case 3:
1228 caption = _("Disable miniaturize button");
1229 flag = WFLAGP(wwin, no_miniaturize_button);
1230 descr = _("Remove the `miniaturize window' button of the window.");
1231 break;
1232 case 4:
1233 caption = _("Disable border");
1234 flag = WFLAGP(wwin, no_border);
1235 descr = _("Remove the 1 pixel black border around the window.");
1236 break;
1237 case 5:
1238 caption = _("Keep on top (floating)");
1239 flag = WFLAGP(wwin, floating);
1240 descr = _("Keep the window over other windows, not allowing\n" "them to cover it.");
1241 break;
1242 case 6:
1243 caption = _("Keep at bottom (sunken)");
1244 flag = WFLAGP(wwin, sunken);
1245 descr = _("Keep the window under all other windows.");
1246 break;
1247 case 7:
1248 caption = _("Omnipresent");
1249 flag = WFLAGP(wwin, omnipresent);
1250 descr = _("Make window present in all workspaces.");
1251 break;
1252 case 8:
1253 caption = _("Start miniaturized");
1254 flag = WFLAGP(wwin, start_miniaturized);
1255 descr = _("Make the window be automatically miniaturized when it's\n" "first shown.");
1256 break;
1257 case 9:
1258 caption = _("Start maximized");
1259 flag = WFLAGP(wwin, start_maximized != 0);
1260 descr = _("Make the window be automatically maximized when it's\n" "first shown.");
1261 break;
1262 case 10:
1263 caption = _("Full screen maximization");
1264 flag = WFLAGP(wwin, full_maximize);
1265 descr = _("Make the window use the whole screen space when it's\n"
1266 "maximized. The titlebar and resizebar will be moved\n"
1267 "to outside the screen.");
1268 break;
1270 panel->attrChk[i] = WMCreateSwitchButton(panel->attrFrm);
1271 WMMoveWidget(panel->attrChk[i], 10, 20 * (i + 1));
1272 WMResizeWidget(panel->attrChk[i], frame_width - 15, 20);
1273 WMSetButtonSelected(panel->attrChk[i], flag);
1274 WMSetButtonText(panel->attrChk[i], caption);
1276 WMSetBalloonTextForView(descr, WMWidgetView(panel->attrChk[i]));
1279 /**** more attributes ****/
1280 panel->moreFrm = WMCreateFrame(panel->win);
1281 WMSetFrameTitle(panel->moreFrm, _("Advanced"));
1282 WMMoveWidget(panel->moreFrm, 15, 45);
1283 WMResizeWidget(panel->moreFrm, frame_width, 265);
1285 for (i = 0; i < (sizeof(panel->moreChk) / sizeof(panel->moreChk[0])); i++) {
1286 char *caption = NULL;
1287 int flag = 0;
1288 char *descr = NULL;
1290 switch (i) {
1291 case 0:
1292 caption = _("Do not bind keyboard shortcuts");
1293 flag = WFLAGP(wwin, no_bind_keys);
1294 descr = _("Do not bind keyboard shortcuts from Window Maker\n"
1295 "when this window is focused. This will allow the\n"
1296 "window to receive all key combinations regardless\n"
1297 "of your shortcut configuration.");
1298 break;
1299 case 1:
1300 caption = _("Do not bind mouse clicks");
1301 flag = WFLAGP(wwin, no_bind_mouse);
1302 descr = _("Do not bind mouse actions, such as `Alt'+drag\n"
1303 "in the window (when alt is the modifier you have\n" "configured).");
1304 break;
1305 case 2:
1306 caption = _("Do not show in the window list");
1307 flag = WFLAGP(wwin, skip_window_list);
1308 descr = _("Do not list the window in the window list menu.");
1309 break;
1310 case 3:
1311 caption = _("Do not show in the switch panel");
1312 flag = WFLAGP(wwin, skip_switchpanel);
1313 descr = _("Do not include in switchpanel while alternating windows.");
1314 break;
1315 case 4:
1316 caption = _("Do not let it take focus");
1317 flag = WFLAGP(wwin, no_focusable);
1318 descr = _("Do not let the window take keyboard focus when you\n" "click on it.");
1319 break;
1320 case 5:
1321 caption = _("Keep inside screen");
1322 flag = WFLAGP(wwin, dont_move_off);
1323 descr = _("Do not allow the window to move itself completely\n"
1324 "outside the screen. For bug compatibility.\n");
1325 break;
1326 case 6:
1327 caption = _("Ignore 'Hide Others'");
1328 flag = WFLAGP(wwin, no_hide_others);
1329 descr = _("Do not hide the window when issuing the\n" "`HideOthers' command.");
1330 break;
1331 case 7:
1332 caption = _("Ignore 'Save Session'");
1333 flag = WFLAGP(wwin, dont_save_session);
1334 descr = _("Do not save the associated application in the\n"
1335 "session's state, so that it won't be restarted\n"
1336 "together with other applications when Window Maker\n" "starts.");
1337 break;
1338 case 8:
1339 caption = _("Emulate application icon");
1340 flag = WFLAGP(wwin, emulate_appicon);
1341 descr = _("Make this window act as an application that provides\n"
1342 "enough information to Window Maker for a dockable\n"
1343 "application icon to be created.");
1344 break;
1345 case 9:
1346 caption = _("Focus across workspaces");
1347 flag = WFLAGP(wwin, focus_across_wksp);
1348 descr = _("Allow Window Maker to switch workspace to satisfy\n"
1349 "a focus request (annoying).");
1350 break;
1351 case 10:
1352 caption = _("Do not let it be minimized");
1353 flag = WFLAGP(wwin, no_miniaturizable);
1354 descr = _("Do not let the window of this application be\n"
1355 "minimized.\n");
1356 break;
1357 #ifdef XKB_BUTTON_HINT
1358 case 11:
1359 caption = _("Disable language button");
1360 flag = WFLAGP(wwin, no_language_button);
1361 descr = _("Remove the `toggle language' button of the window.");
1362 break;
1363 #endif
1365 panel->moreChk[i] = WMCreateSwitchButton(panel->moreFrm);
1366 WMMoveWidget(panel->moreChk[i], 10, 20 * (i + 1));
1367 WMResizeWidget(panel->moreChk[i], frame_width - 15, 20);
1368 WMSetButtonSelected(panel->moreChk[i], flag);
1369 WMSetButtonText(panel->moreChk[i], caption);
1371 WMSetBalloonTextForView(descr, WMWidgetView(panel->moreChk[i]));
1374 /* miniwindow/workspace */
1375 panel->iconFrm = WMCreateFrame(panel->win);
1376 WMMoveWidget(panel->iconFrm, 15, 50);
1377 WMResizeWidget(panel->iconFrm, PWIDTH - (2 * 15), 170);
1378 WMSetFrameTitle(panel->iconFrm, _("Miniwindow Image"));
1380 panel->iconLbl = WMCreateLabel(panel->iconFrm);
1381 WMMoveWidget(panel->iconLbl, PWIDTH - (2 * 15) - 22 - 64, 20);
1382 WMResizeWidget(panel->iconLbl, 64, 64);
1383 WMSetLabelRelief(panel->iconLbl, WRGroove);
1384 WMSetLabelImagePosition(panel->iconLbl, WIPImageOnly);
1386 panel->browseIconBtn = WMCreateCommandButton(panel->iconFrm);
1387 WMSetButtonAction(panel->browseIconBtn, chooseIconCallback, panel);
1388 WMMoveWidget(panel->browseIconBtn, 22, 32);
1389 WMResizeWidget(panel->browseIconBtn, 120, 26);
1390 WMSetButtonText(panel->browseIconBtn, _("Browse..."));
1392 #ifdef wrong_behaviour
1393 WMSetButtonImagePosition(panel->updateIconBtn, WIPRight);
1394 pixmap = WMGetSystemPixmap(scr->wmscreen, WSIReturnArrow);
1395 WMSetButtonImage(panel->updateIconBtn, pixmap);
1396 WMReleasePixmap(pixmap);
1397 pixmap = WMGetSystemPixmap(scr->wmscreen, WSIHighlightedReturnArrow);
1398 WMSetButtonAltImage(panel->updateIconBtn, pixmap);
1399 WMReleasePixmap(pixmap);
1400 #endif
1402 panel->fileLbl = WMCreateLabel(panel->iconFrm);
1403 WMMoveWidget(panel->fileLbl, 20, 85);
1404 WMResizeWidget(panel->fileLbl, PWIDTH - (2 * 15) - (2 * 20), 14);
1405 WMSetLabelText(panel->fileLbl, _("Icon filename:"));
1407 panel->fileText = WMCreateTextField(panel->iconFrm);
1408 WMMoveWidget(panel->fileText, 20, 105);
1409 WMResizeWidget(panel->fileText, PWIDTH - (2 * 20) - (2 * 15), 20);
1410 WMSetTextFieldText(panel->fileText, NULL);
1411 WMAddNotificationObserver(textEditedObserver, panel, WMTextDidEndEditingNotification, panel->fileText);
1413 panel->alwChk = WMCreateSwitchButton(panel->iconFrm);
1414 WMMoveWidget(panel->alwChk, 20, 130);
1415 WMResizeWidget(panel->alwChk, PWIDTH - (2 * 15) - (2 * 15), 30);
1416 WMSetButtonText(panel->alwChk, _("Ignore client supplied icon"));
1417 WMSetButtonSelected(panel->alwChk, WFLAGP(wwin, always_user_icon));
1419 panel->wsFrm = WMCreateFrame(panel->win);
1420 WMMoveWidget(panel->wsFrm, 15, 225);
1421 WMResizeWidget(panel->wsFrm, PWIDTH - (2 * 15), 70);
1422 WMSetFrameTitle(panel->wsFrm, _("Initial Workspace"));
1424 WMSetBalloonTextForView(_("The workspace to place the window when it's"
1425 "first shown."), WMWidgetView(panel->wsFrm));
1427 panel->wsP = WMCreatePopUpButton(panel->wsFrm);
1428 WMMoveWidget(panel->wsP, 20, 30);
1429 WMResizeWidget(panel->wsP, PWIDTH - (2 * 15) - (2 * 20), 20);
1430 WMAddPopUpButtonItem(panel->wsP, _("Nowhere in particular"));
1432 for (i = 0; i < wwin->screen_ptr->workspace_count; i++)
1433 WMAddPopUpButtonItem(panel->wsP, scr->workspaces[i]->name);
1435 i = wDefaultGetStartWorkspace(wwin->screen_ptr, wwin->wm_instance, wwin->wm_class);
1436 if (i >= 0 && i <= wwin->screen_ptr->workspace_count)
1437 WMSetPopUpButtonSelectedItem(panel->wsP, i + 1);
1438 else
1439 WMSetPopUpButtonSelectedItem(panel->wsP, 0);
1441 /* application wide attributes */
1442 if (wwin->main_window != None) {
1443 WApplication *wapp = wApplicationOf(wwin->main_window);
1445 panel->appFrm = WMCreateFrame(panel->win);
1446 WMSetFrameTitle(panel->appFrm, _("Application Attributes"));
1447 WMMoveWidget(panel->appFrm, 15, 50);
1448 WMResizeWidget(panel->appFrm, frame_width, 240);
1450 for (i = 0; i < (sizeof(panel->appChk) / sizeof(panel->appChk[0])); i++) {
1451 char *caption = NULL;
1452 int flag = 0;
1453 char *descr = NULL;
1455 switch (i) {
1456 case 0:
1457 caption = _("Start hidden");
1458 flag = WFLAGP(wapp->main_window_desc, start_hidden);
1459 descr = _("Automatically hide application when it's started.");
1460 break;
1461 case 1:
1462 caption = _("No application icon");
1463 flag = WFLAGP(wapp->main_window_desc, no_appicon);
1464 descr = _("Disable the application icon for the application.\n"
1465 "Note that you won't be able to dock it anymore,\n"
1466 "and any icons that are already docked will stop\n"
1467 "working correctly.");
1468 break;
1469 case 2:
1470 caption = _("Shared application icon");
1471 flag = WFLAGP(wapp->main_window_desc, shared_appicon);
1472 descr = _("Use a single shared application icon for all of\n"
1473 "the instances of this application.\n");
1474 break;
1476 panel->appChk[i] = WMCreateSwitchButton(panel->appFrm);
1477 WMMoveWidget(panel->appChk[i], 10, 20 * (i + 1));
1478 WMResizeWidget(panel->appChk[i], 205, 20);
1479 WMSetButtonSelected(panel->appChk[i], flag);
1480 WMSetButtonText(panel->appChk[i], caption);
1481 WMSetBalloonTextForView(descr, WMWidgetView(panel->appChk[i]));
1484 if (WFLAGP(wwin, emulate_appicon)) {
1485 WMSetButtonEnabled(panel->appChk[1], False);
1486 WMSetButtonEnabled(panel->moreChk[7], True);
1487 } else {
1488 WMSetButtonEnabled(panel->appChk[1], True);
1489 WMSetButtonEnabled(panel->moreChk[7], False);
1491 } else {
1492 int tmp;
1494 if ((wwin->transient_for != None && wwin->transient_for != scr->root_win)
1495 || !wwin->wm_class || !wwin->wm_instance)
1496 tmp = False;
1497 else
1498 tmp = True;
1499 WMSetButtonEnabled(panel->moreChk[7], tmp);
1501 WMSetPopUpButtonItemEnabled(panel->pagePopUp, 4, False);
1502 panel->appFrm = NULL;
1505 /* if the window is a transient, don't let it have a miniaturize
1506 * button */
1507 if (wwin->transient_for != None && wwin->transient_for != scr->root_win)
1508 WMSetButtonEnabled(panel->attrChk[3], False);
1509 else
1510 WMSetButtonEnabled(panel->attrChk[3], True);
1512 if (!wwin->wm_class && !wwin->wm_instance) {
1513 WMSetPopUpButtonItemEnabled(panel->pagePopUp, 0, False);
1516 WMRealizeWidget(panel->win);
1518 WMMapSubwidgets(panel->win);
1519 WMMapSubwidgets(panel->specFrm);
1520 WMMapSubwidgets(panel->attrFrm);
1521 WMMapSubwidgets(panel->moreFrm);
1522 WMMapSubwidgets(panel->iconFrm);
1523 WMMapSubwidgets(panel->wsFrm);
1524 if (panel->appFrm)
1525 WMMapSubwidgets(panel->appFrm);
1527 if (showSelectPanel) {
1528 WMSetPopUpButtonSelectedItem(panel->pagePopUp, 0);
1529 changePage(panel->pagePopUp, panel);
1530 } else {
1531 WMSetPopUpButtonSelectedItem(panel->pagePopUp, 1);
1532 changePage(panel->pagePopUp, panel);
1535 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, PWIDTH, PHEIGHT, 0, 0, 0);
1536 XSelectInput(dpy, parent, KeyPressMask | KeyReleaseMask);
1537 panel->parent = parent;
1538 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
1540 WMMapWidget(panel->win);
1542 XSetTransientForHint(dpy, parent, wwin->client_win);
1544 if (xpos == UNDEFINED_POS) {
1545 x = wwin->frame_x + wwin->frame->core->width / 2;
1546 y = wwin->frame_y + wwin->frame->top_width * 2;
1547 if (y + PHEIGHT > scr->scr_height)
1548 y = scr->scr_height - PHEIGHT - 30;
1549 if (x + PWIDTH > scr->scr_width)
1550 x = scr->scr_width - PWIDTH;
1551 } else {
1552 x = xpos;
1553 y = ypos;
1556 panel->frame = wManageInternalWindow(scr, parent, wwin->client_win, "Inspector", x, y, PWIDTH, PHEIGHT);
1558 if (!selectedBtn)
1559 selectedBtn = panel->defaultRb;
1561 WMSetButtonSelected(selectedBtn, True);
1563 selectSpecification(selectedBtn, panel);
1565 /* kluge to know who should get the key events */
1566 panel->frame->client_leader = WMWidgetXID(panel->win);
1568 WSETUFLAG(panel->frame, no_closable, 0);
1569 WSETUFLAG(panel->frame, no_close_button, 0);
1570 wWindowUpdateButtonImages(panel->frame);
1571 wFrameWindowShowButton(panel->frame->frame, WFF_RIGHT_BUTTON);
1572 panel->frame->frame->on_click_right = destroyInspector;
1574 wWindowMap(panel->frame);
1576 showIconFor(WMWidgetScreen(panel->alwChk), panel, wwin->wm_instance, wwin->wm_class, UPDATE_TEXT_FIELD);
1578 return panel;
1581 void wShowInspectorForWindow(WWindow *wwin)
1583 if (wwin->flags.inspector_open)
1584 return;
1586 WMSetBalloonEnabled(wwin->screen_ptr->wmscreen, wPreferences.help_balloon);
1588 make_keys();
1589 wwin->flags.inspector_open = 1;
1590 wwin->inspector = createInspectorForWindow(wwin, UNDEFINED_POS, UNDEFINED_POS, False);
1593 void wHideInspectorForWindow(WWindow *wwin)
1595 WWindow *pwin = wwin->inspector->frame;
1597 wWindowUnmap(pwin);
1598 pwin->flags.hidden = 1;
1600 wClientSetState(pwin, IconicState, None);
1603 void wUnhideInspectorForWindow(WWindow *wwin)
1605 WWindow *pwin = wwin->inspector->frame;
1607 pwin->flags.hidden = 0;
1608 pwin->flags.mapped = 1;
1609 XMapWindow(dpy, pwin->client_win);
1610 XMapWindow(dpy, pwin->frame->core->window);
1611 wClientSetState(pwin, NormalState, None);
1614 WWindow *wGetWindowOfInspectorForWindow(WWindow *wwin)
1616 if (wwin->inspector) {
1617 assert(wwin->flags.inspector_open != 0);
1619 return wwin->inspector->frame;
1620 } else
1621 return NULL;
1624 void wCloseInspectorForWindow(WWindow *wwin)
1626 WWindow *pwin = wwin->inspector->frame; /* the inspector window */
1628 (*pwin->frame->on_click_right) (NULL, pwin, NULL);