b671087cac8d8ba2892e3c44035be0920a1eb535
[wmaker-crm.git] / src / winspector.c
blobb671087cac8d8ba2892e3c44035be0920a1eb535
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 db_icon = wDefaultGetIconFile(wm_instance, wm_class, False);
327 if (db_icon != NULL)
328 file = wstrdup(db_icon);
330 if (db_icon != NULL && (flags & REVERT_TO_DEFAULT) != 0) {
331 if (file)
332 file = wstrdup(db_icon);
333 flags |= UPDATE_TEXT_FIELD;
336 if ((flags & UPDATE_TEXT_FIELD) != 0) {
337 WMSetTextFieldText(panel->fileText, file);
340 if (file) {
341 path = FindImage(wPreferences.icon_path, file);
343 if (!path) {
344 char *buf;
345 int len = strlen(file) + 80;
347 buf = wmalloc(len);
348 snprintf(buf, len, _("Could not find icon \"%s\" specified for this window"), file);
349 wMessageDialog(panel->frame->screen_ptr, _("Error"), buf, _("OK"), NULL, NULL);
350 wfree(buf);
351 wfree(file);
352 return -1;
355 pixmap = WMCreatePixmapFromFile(scrPtr, path);
356 wfree(path);
358 if (!pixmap) {
359 char *buf;
360 int len = strlen(file) + 80;
362 buf = wmalloc(len);
363 snprintf(buf, len, _("Could not open specified icon \"%s\":%s"),
364 file, RMessageForError(RErrorCode));
365 wMessageDialog(panel->frame->screen_ptr, _("Error"), buf, _("OK"), NULL, NULL);
366 wfree(buf);
367 wfree(file);
368 return -1;
370 wfree(file);
373 WMSetLabelImage(panel->iconLbl, pixmap);
374 if (pixmap)
375 WMReleasePixmap(pixmap);
377 return 0;
380 #if 0
381 static void updateIcon(WMButton * button, InspectorPanel * panel)
383 showIconFor(WMWidgetScreen(button), panel, NULL, NULL, USE_TEXT_FIELD);
385 #endif
387 static int getBool(WMPropList *value)
389 char *val;
391 if (!WMIsPLString(value)) {
392 return 0;
394 if (!(val = WMGetFromPLString(value))) {
395 return 0;
398 if ((val[1] == '\0' && (val[0] == 'y' || val[0] == 'Y' || val[0] == 'T' || val[0] == 't' || val[0] == '1'))
399 || (strcasecmp(val, "YES") == 0 || strcasecmp(val, "TRUE") == 0)) {
401 return 1;
402 } else if ((val[1] == '\0'
403 && (val[0] == 'n' || val[0] == 'N' || val[0] == 'F' || val[0] == 'f' || val[0] == '0'))
404 || (strcasecmp(val, "NO") == 0 || strcasecmp(val, "FALSE") == 0)) {
406 return 0;
407 } else {
408 wwarning(_("can't convert \"%s\" to boolean"), val);
409 return 0;
413 #define UPDATE_DEFAULTS 1
414 #define IS_BOOLEAN 2
417 * Will insert the attribute = value; pair in window's list,
418 * if it's different from the defaults.
419 * Defaults means either defaults database, or attributes saved
420 * for the default window "*". This is to let one revert options that are
421 * global because they were saved for all windows ("*").
425 static int
426 insertAttribute(WMPropList *dict, WMPropList *window, WMPropList *attr, WMPropList *value, int flags)
428 WMPropList *def_win, *def_value = NULL;
429 int update = 0;
430 int modified = 0;
432 if (!(flags & UPDATE_DEFAULTS) && dict) {
433 if ((def_win = WMGetFromPLDictionary(dict, AnyWindow)) != NULL) {
434 def_value = WMGetFromPLDictionary(def_win, attr);
438 /* If we could not find defaults in database, fall to hardcoded values.
439 * Also this is true if we save defaults for all windows
441 if (!def_value)
442 def_value = ((flags & IS_BOOLEAN) != 0) ? No : EmptyString;
444 if ((flags & IS_BOOLEAN))
445 update = (getBool(value) != getBool(def_value));
446 else {
447 update = !WMIsPropListEqualTo(value, def_value);
450 if (update) {
451 WMPutInPLDictionary(window, attr, value);
452 modified = 1;
455 return modified;
458 static void saveSettings(WMButton *button, InspectorPanel *panel)
460 WWindow *wwin = panel->inspected;
461 WDDomain *db = WDWindowAttributes;
462 WMPropList *dict = db->dictionary;
463 WMPropList *winDic, *appDic, *value, *key, *key2;
464 char *icon_file;
465 int flags = 0;
466 int different = 0, different2 = 0;
468 /* Save will apply the changes and save them */
469 applySettings(panel->applyBtn, panel);
471 if (WMGetButtonSelected(panel->instRb) != 0)
472 key = WMCreatePLString(wwin->wm_instance);
473 else if (WMGetButtonSelected(panel->clsRb) != 0)
474 key = WMCreatePLString(wwin->wm_class);
475 else if (WMGetButtonSelected(panel->bothRb) != 0) {
476 char *buffer;
478 buffer = StrConcatDot(wwin->wm_instance, wwin->wm_class);
479 key = WMCreatePLString(buffer);
480 wfree(buffer);
481 } else if (WMGetButtonSelected(panel->defaultRb) != 0) {
482 key = WMRetainPropList(AnyWindow);
483 flags = UPDATE_DEFAULTS;
484 } else
485 key = NULL;
487 if (!key)
488 return;
490 if (!dict) {
491 dict = WMCreatePLDictionary(NULL, NULL);
492 if (dict) {
493 db->dictionary = dict;
494 } else {
495 WMReleasePropList(key);
496 return;
500 if (showIconFor(WMWidgetScreen(button), panel, NULL, NULL, USE_TEXT_FIELD) < 0)
501 return;
503 WMPLSetCaseSensitive(True);
505 winDic = WMCreatePLDictionary(NULL, NULL);
506 appDic = WMCreatePLDictionary(NULL, NULL);
508 /* Update icon for window */
509 icon_file = WMGetTextFieldText(panel->fileText);
510 if (icon_file) {
511 if (icon_file[0] != 0) {
512 value = WMCreatePLString(icon_file);
513 different |= insertAttribute(dict, winDic, AIcon, value, flags);
514 different2 |= insertAttribute(dict, appDic, AIcon, value, flags);
515 WMReleasePropList(value);
517 wfree(icon_file);
521 int i = WMGetPopUpButtonSelectedItem(panel->wsP);
523 i--;
525 if (i >= 0 && i < panel->frame->screen_ptr->workspace_count) {
526 value = WMCreatePLString(panel->frame->screen_ptr->workspaces[i]->name);
527 different |= insertAttribute(dict, winDic, AStartWorkspace, value, flags);
528 WMReleasePropList(value);
532 flags |= IS_BOOLEAN;
534 value = (WMGetButtonSelected(panel->alwChk) != 0) ? Yes : No;
535 different |= insertAttribute(dict, winDic, AAlwaysUserIcon, value, flags);
537 value = (WMGetButtonSelected(panel->attrChk[0]) != 0) ? Yes : No;
538 different |= insertAttribute(dict, winDic, ANoTitlebar, value, flags);
540 value = (WMGetButtonSelected(panel->attrChk[1]) != 0) ? Yes : No;
541 different |= insertAttribute(dict, winDic, ANoResizebar, value, flags);
543 value = (WMGetButtonSelected(panel->attrChk[2]) != 0) ? Yes : No;
544 different |= insertAttribute(dict, winDic, ANoCloseButton, value, flags);
546 value = (WMGetButtonSelected(panel->attrChk[3]) != 0) ? Yes : No;
547 different |= insertAttribute(dict, winDic, ANoMiniaturizeButton, value, flags);
549 value = (WMGetButtonSelected(panel->attrChk[4]) != 0) ? Yes : No;
550 different |= insertAttribute(dict, winDic, ANoBorder, value, flags);
552 value = (WMGetButtonSelected(panel->attrChk[5]) != 0) ? Yes : No;
553 different |= insertAttribute(dict, winDic, AKeepOnTop, value, flags);
555 value = (WMGetButtonSelected(panel->attrChk[6]) != 0) ? Yes : No;
556 different |= insertAttribute(dict, winDic, AKeepOnBottom, value, flags);
558 value = (WMGetButtonSelected(panel->attrChk[7]) != 0) ? Yes : No;
559 different |= insertAttribute(dict, winDic, AOmnipresent, value, flags);
561 value = (WMGetButtonSelected(panel->attrChk[8]) != 0) ? Yes : No;
562 different |= insertAttribute(dict, winDic, AStartMiniaturized, value, flags);
564 value = (WMGetButtonSelected(panel->attrChk[9]) != 0) ? Yes : No;
565 different |= insertAttribute(dict, winDic, AStartMaximized, value, flags);
567 value = (WMGetButtonSelected(panel->attrChk[10]) != 0) ? Yes : No;
568 different |= insertAttribute(dict, winDic, AFullMaximize, value, flags);
570 value = (WMGetButtonSelected(panel->moreChk[0]) != 0) ? Yes : No;
571 different |= insertAttribute(dict, winDic, ANoKeyBindings, value, flags);
573 value = (WMGetButtonSelected(panel->moreChk[1]) != 0) ? Yes : No;
574 different |= insertAttribute(dict, winDic, ANoMouseBindings, value, flags);
576 value = (WMGetButtonSelected(panel->moreChk[2]) != 0) ? Yes : No;
577 different |= insertAttribute(dict, winDic, ASkipWindowList, value, flags);
579 value = (WMGetButtonSelected(panel->moreChk[3]) != 0) ? Yes : No;
580 different |= insertAttribute(dict, winDic, ASkipSwitchPanel, value, flags);
582 value = (WMGetButtonSelected(panel->moreChk[4]) != 0) ? Yes : No;
583 different |= insertAttribute(dict, winDic, AUnfocusable, value, flags);
585 value = (WMGetButtonSelected(panel->moreChk[5]) != 0) ? Yes : No;
586 different |= insertAttribute(dict, winDic, AKeepInsideScreen, value, flags);
588 value = (WMGetButtonSelected(panel->moreChk[6]) != 0) ? Yes : No;
589 different |= insertAttribute(dict, winDic, ANoHideOthers, value, flags);
591 value = (WMGetButtonSelected(panel->moreChk[7]) != 0) ? Yes : No;
592 different |= insertAttribute(dict, winDic, ADontSaveSession, value, flags);
594 value = (WMGetButtonSelected(panel->moreChk[8]) != 0) ? Yes : No;
595 different |= insertAttribute(dict, winDic, AEmulateAppIcon, value, flags);
597 value = (WMGetButtonSelected(panel->moreChk[9]) != 0) ? Yes : No;
598 different |= insertAttribute(dict, winDic, AFocusAcrossWorkspace, value, flags);
600 value = (WMGetButtonSelected(panel->moreChk[10]) != 0) ? Yes : No;
601 different |= insertAttribute(dict, winDic, ANoMiniaturizable, value, flags);
603 #ifdef XKB_BUTTON_HINT
604 value = (WMGetButtonSelected(panel->moreChk[11]) != 0) ? Yes : No;
605 different |= insertAttribute(dict, winDic, ANoLanguageButton, value, flags);
606 #endif
608 if (wwin->main_window != None && wApplicationOf(wwin->main_window) != NULL) {
609 value = (WMGetButtonSelected(panel->appChk[0]) != 0) ? Yes : No;
610 different2 |= insertAttribute(dict, appDic, AStartHidden, value, flags);
612 value = (WMGetButtonSelected(panel->appChk[1]) != 0) ? Yes : No;
613 different2 |= insertAttribute(dict, appDic, ANoAppIcon, value, flags);
615 value = (WMGetButtonSelected(panel->appChk[2]) != 0) ? Yes : No;
616 different2 |= insertAttribute(dict, appDic, ASharedAppIcon, value, flags);
619 if (wwin->fake_group) {
620 key2 = WMCreatePLString(wwin->fake_group->identifier);
621 if (WMIsPropListEqualTo(key, key2)) {
622 WMMergePLDictionaries(winDic, appDic, True);
623 different |= different2;
624 } else {
625 WMRemoveFromPLDictionary(dict, key2);
626 if (different2) {
627 WMPutInPLDictionary(dict, key2, appDic);
630 WMReleasePropList(key2);
631 WMReleasePropList(appDic);
632 } else if (wwin->main_window != wwin->client_win) {
633 WApplication *wapp = wApplicationOf(wwin->main_window);
635 if (wapp) {
636 char *instance = wapp->main_window_desc->wm_instance;
637 char *class = wapp->main_window_desc->wm_class;
638 char *buffer;
640 buffer = StrConcatDot(instance, class);
641 key2 = WMCreatePLString(buffer);
642 wfree(buffer);
644 if (WMIsPropListEqualTo(key, key2)) {
645 WMMergePLDictionaries(winDic, appDic, True);
646 different |= different2;
647 } else {
648 WMRemoveFromPLDictionary(dict, key2);
649 if (different2)
650 WMPutInPLDictionary(dict, key2, appDic);
652 WMReleasePropList(key2);
653 WMReleasePropList(appDic);
655 } else {
656 WMMergePLDictionaries(winDic, appDic, True);
657 different |= different2;
658 WMReleasePropList(appDic);
661 WMRemoveFromPLDictionary(dict, key);
662 if (different) {
663 WMPutInPLDictionary(dict, key, winDic);
666 WMReleasePropList(key);
667 WMReleasePropList(winDic);
669 UpdateDomainFile(db);
671 /* clean up */
672 WMPLSetCaseSensitive(False);
675 static void applySettings(WMButton *button, InspectorPanel *panel)
677 WWindow *wwin = panel->inspected;
678 WApplication *wapp = wApplicationOf(wwin->main_window);
679 int floating, sunken, skip_window_list;
680 int old_omnipresent;
681 int old_no_bind_keys;
682 int old_no_bind_mouse;
684 old_omnipresent = WFLAGP(wwin, omnipresent);
685 old_no_bind_keys = WFLAGP(wwin, no_bind_keys);
686 old_no_bind_mouse = WFLAGP(wwin, no_bind_mouse);
688 showIconFor(WMWidgetScreen(button), panel, NULL, NULL, USE_TEXT_FIELD);
690 /* Attributes... --> Window Attributes */
691 WSETUFLAG(wwin, no_titlebar, WMGetButtonSelected(panel->attrChk[0]));
692 WSETUFLAG(wwin, no_resizebar, WMGetButtonSelected(panel->attrChk[1]));
693 WSETUFLAG(wwin, no_close_button, WMGetButtonSelected(panel->attrChk[2]));
694 WSETUFLAG(wwin, no_miniaturize_button, WMGetButtonSelected(panel->attrChk[3]));
695 WSETUFLAG(wwin, no_border, WMGetButtonSelected(panel->attrChk[4]));
696 floating = WMGetButtonSelected(panel->attrChk[5]);
697 sunken = WMGetButtonSelected(panel->attrChk[6]);
698 WSETUFLAG(wwin, omnipresent, WMGetButtonSelected(panel->attrChk[7]));
699 WSETUFLAG(wwin, start_miniaturized, WMGetButtonSelected(panel->attrChk[8]));
700 WSETUFLAG(wwin, start_maximized, WMGetButtonSelected(panel->attrChk[9]));
701 WSETUFLAG(wwin, full_maximize, WMGetButtonSelected(panel->attrChk[10]));
703 /* Attributes... --> Advanced Options */
704 WSETUFLAG(wwin, no_bind_keys, WMGetButtonSelected(panel->moreChk[0]));
705 WSETUFLAG(wwin, no_bind_mouse, WMGetButtonSelected(panel->moreChk[1]));
706 skip_window_list = WMGetButtonSelected(panel->moreChk[2]);
707 WSETUFLAG(wwin, skip_switchpanel, WMGetButtonSelected(panel->moreChk[3]));
708 WSETUFLAG(wwin, no_focusable, WMGetButtonSelected(panel->moreChk[4]));
709 WSETUFLAG(wwin, dont_move_off, WMGetButtonSelected(panel->moreChk[5]));
710 WSETUFLAG(wwin, no_hide_others, WMGetButtonSelected(panel->moreChk[6]));
711 WSETUFLAG(wwin, dont_save_session, WMGetButtonSelected(panel->moreChk[7]));
712 WSETUFLAG(wwin, emulate_appicon, WMGetButtonSelected(panel->moreChk[8]));
713 WSETUFLAG(wwin, focus_across_wksp, WMGetButtonSelected(panel->moreChk[9]));
714 WSETUFLAG(wwin, no_miniaturizable, WMGetButtonSelected(panel->moreChk[10]));
715 #ifdef XKB_BUTTON_HINT
716 WSETUFLAG(wwin, no_language_button, WMGetButtonSelected(panel->moreChk[11]));
717 #endif
718 WSETUFLAG(wwin, always_user_icon, WMGetButtonSelected(panel->alwChk));
720 if (WFLAGP(wwin, no_titlebar) && wwin->flags.shaded)
721 wUnshadeWindow(wwin);
723 WSETUFLAG(wwin, no_shadeable, WFLAGP(wwin, no_titlebar));
725 if (floating) {
726 if (!WFLAGP(wwin, floating))
727 ChangeStackingLevel(wwin->frame->core, WMFloatingLevel);
728 } else if (sunken) {
729 if (!WFLAGP(wwin, sunken))
730 ChangeStackingLevel(wwin->frame->core, WMSunkenLevel);
731 } else {
732 if (WFLAGP(wwin, floating) || WFLAGP(wwin, sunken))
733 ChangeStackingLevel(wwin->frame->core, WMNormalLevel);
736 WSETUFLAG(wwin, sunken, sunken);
737 WSETUFLAG(wwin, floating, floating);
738 wwin->flags.omnipresent = 0;
740 if (WFLAGP(wwin, skip_window_list) != skip_window_list) {
741 WSETUFLAG(wwin, skip_window_list, skip_window_list);
742 UpdateSwitchMenu(wwin->screen_ptr, wwin, skip_window_list ? ACTION_REMOVE : ACTION_ADD);
743 } else {
744 if (WFLAGP(wwin, omnipresent) != old_omnipresent) {
745 WMPostNotificationName(WMNChangedState, wwin, "omnipresent");
749 if (WFLAGP(wwin, no_bind_keys) != old_no_bind_keys) {
750 if (WFLAGP(wwin, no_bind_keys)) {
751 XUngrabKey(dpy, AnyKey, AnyModifier, wwin->frame->core->window);
752 } else {
753 wWindowSetKeyGrabs(wwin);
757 if (WFLAGP(wwin, no_bind_mouse) != old_no_bind_mouse) {
758 wWindowResetMouseGrabs(wwin);
761 wwin->frame->flags.need_texture_change = 1;
762 wWindowConfigureBorders(wwin);
763 wFrameWindowPaint(wwin->frame);
764 wNETWMUpdateActions(wwin, False);
767 * Can't apply emulate_appicon because it will probably cause problems.
769 if (wapp) {
770 /* do application wide stuff */
771 WSETUFLAG(wapp->main_window_desc, start_hidden, WMGetButtonSelected(panel->appChk[0]));
773 WSETUFLAG(wapp->main_window_desc, no_appicon, WMGetButtonSelected(panel->appChk[1]));
775 WSETUFLAG(wapp->main_window_desc, shared_appicon, WMGetButtonSelected(panel->appChk[2]));
777 if (WFLAGP(wapp->main_window_desc, no_appicon))
778 removeAppIconFor(wapp);
779 else
780 makeAppIconFor(wapp);
782 if (wapp->app_icon && wapp->main_window == wwin->client_win) {
783 char *file = WMGetTextFieldText(panel->fileText);
785 if (file[0] == 0) {
786 wfree(file);
787 file = NULL;
789 wIconChangeImageFile(wapp->app_icon->icon, file);
790 if (file)
791 wfree(file);
792 wAppIconPaint(wapp->app_icon);
797 static void revertSettings(WMButton *button, InspectorPanel *panel)
799 WWindow *wwin = panel->inspected;
800 WApplication *wapp = wApplicationOf(wwin->main_window);
801 int i, n;
802 char *wm_instance = NULL;
803 char *wm_class = NULL;
804 int workspace, level;
806 if (panel->instRb && WMGetButtonSelected(panel->instRb) != 0)
807 wm_instance = wwin->wm_instance;
808 else if (panel->clsRb && WMGetButtonSelected(panel->clsRb) != 0)
809 wm_class = wwin->wm_class;
810 else if (panel->bothRb && WMGetButtonSelected(panel->bothRb) != 0) {
811 wm_instance = wwin->wm_instance;
812 wm_class = wwin->wm_class;
814 memset(&wwin->defined_user_flags, 0, sizeof(WWindowAttributes));
815 memset(&wwin->user_flags, 0, sizeof(WWindowAttributes));
816 memset(&wwin->client_flags, 0, sizeof(WWindowAttributes));
818 wWindowSetupInitialAttributes(wwin, &level, &workspace);
820 for (i = 0; i < (sizeof(panel->attrChk) / sizeof(panel->attrChk[0])); i++) {
821 int flag = 0;
823 switch (i) {
824 case 0:
825 flag = WFLAGP(wwin, no_titlebar);
826 break;
827 case 1:
828 flag = WFLAGP(wwin, no_resizebar);
829 break;
830 case 2:
831 flag = WFLAGP(wwin, no_close_button);
832 break;
833 case 3:
834 flag = WFLAGP(wwin, no_miniaturize_button);
835 break;
836 case 4:
837 flag = WFLAGP(wwin, no_border);
838 break;
839 case 5:
840 flag = WFLAGP(wwin, floating);
841 break;
842 case 6:
843 flag = WFLAGP(wwin, sunken);
844 break;
845 case 7:
846 flag = WFLAGP(wwin, omnipresent);
847 break;
848 case 8:
849 flag = WFLAGP(wwin, start_miniaturized);
850 break;
851 case 9:
852 flag = WFLAGP(wwin, start_maximized != 0);
853 break;
854 case 10:
855 flag = WFLAGP(wwin, full_maximize);
856 break;
858 WMSetButtonSelected(panel->attrChk[i], flag);
860 for (i = 0; i < (sizeof(panel->moreChk) / sizeof(panel->moreChk[0])); i++) {
861 int flag = 0;
863 switch (i) {
864 case 0:
865 flag = WFLAGP(wwin, no_bind_keys);
866 break;
867 case 1:
868 flag = WFLAGP(wwin, no_bind_mouse);
869 break;
870 case 2:
871 flag = WFLAGP(wwin, skip_window_list);
872 break;
873 case 3:
874 flag = WFLAGP(wwin, skip_switchpanel);
875 break;
876 case 4:
877 flag = WFLAGP(wwin, no_focusable);
878 break;
879 case 5:
880 flag = WFLAGP(wwin, dont_move_off);
881 break;
882 case 6:
883 flag = WFLAGP(wwin, no_hide_others);
884 break;
885 case 7:
886 flag = WFLAGP(wwin, dont_save_session);
887 break;
888 case 8:
889 flag = WFLAGP(wwin, emulate_appicon);
890 break;
891 case 9:
892 flag = WFLAGP(wwin, focus_across_wksp);
893 break;
894 case 10:
895 flag = WFLAGP(wwin, no_miniaturizable);
896 break;
897 #ifdef XKB_BUTTON_HINT
898 case 11:
899 flag = WFLAGP(wwin, no_language_button);
900 break;
901 #endif
903 WMSetButtonSelected(panel->moreChk[i], flag);
905 if (panel->appFrm && wapp) {
906 for (i = 0; i < (sizeof(panel->appChk) / sizeof(panel->appChk[0])); i++) {
907 int flag = 0;
909 switch (i) {
910 case 0:
911 flag = WFLAGP(wapp->main_window_desc, start_hidden);
912 break;
913 case 1:
914 flag = WFLAGP(wapp->main_window_desc, no_appicon);
915 break;
916 case 2:
917 flag = WFLAGP(wapp->main_window_desc, shared_appicon);
918 break;
920 WMSetButtonSelected(panel->appChk[i], flag);
923 WMSetButtonSelected(panel->alwChk, WFLAGP(wwin, always_user_icon));
925 showIconFor(WMWidgetScreen(panel->alwChk), panel, wm_instance, wm_class, REVERT_TO_DEFAULT);
927 n = wDefaultGetStartWorkspace(wwin->screen_ptr, wm_instance, wm_class);
929 if (n >= 0 && n < wwin->screen_ptr->workspace_count) {
930 WMSetPopUpButtonSelectedItem(panel->wsP, n + 1);
931 } else {
932 WMSetPopUpButtonSelectedItem(panel->wsP, 0);
935 /* must auto apply, so that there wno't be internal
936 * inconsistencies between the state in the flags and
937 * the actual state of the window */
938 applySettings(panel->applyBtn, panel);
941 static void chooseIconCallback(WMWidget *self, void *clientData)
943 char *file;
944 InspectorPanel *panel = (InspectorPanel *) clientData;
945 int result;
947 panel->choosingIcon = 1;
949 WMSetButtonEnabled(panel->browseIconBtn, False);
951 result = wIconChooserDialog(panel->frame->screen_ptr, &file,
952 panel->inspected->wm_instance, panel->inspected->wm_class);
954 panel->choosingIcon = 0;
956 if (!panel->destroyed) { /* kluge */
957 if (result) {
958 WMSetTextFieldText(panel->fileText, file);
959 showIconFor(WMWidgetScreen(self), panel, NULL, NULL, USE_TEXT_FIELD);
960 wfree(file);
962 WMSetButtonEnabled(panel->browseIconBtn, True);
963 } else {
964 freeInspector(panel);
968 static void textEditedObserver(void *observerData, WMNotification *notification)
970 InspectorPanel *panel = (InspectorPanel *) observerData;
972 if ((long)WMGetNotificationClientData(notification) != WMReturnTextMovement)
973 return;
975 showIconFor(WMWidgetScreen(panel->win), panel, NULL, NULL, USE_TEXT_FIELD);
977 WMPerformButtonClick(panel->updateIconBtn);
981 static void selectSpecification(WMWidget *bPtr, void *data)
983 InspectorPanel *panel = (InspectorPanel *) data;
984 char *str;
985 WWindow *wwin = panel->inspected;
986 int len;
988 if (bPtr == panel->defaultRb && (wwin->wm_instance || wwin->wm_class))
989 WMSetButtonEnabled(panel->applyBtn, False);
990 else
991 WMSetButtonEnabled(panel->applyBtn, True);
993 len = 16 + strlen(wwin->wm_instance ? wwin->wm_instance : "?")
994 + strlen(wwin->wm_class ? wwin->wm_class : "?");
996 str = wmalloc(len);
998 snprintf(str, len, _("Inspecting %s.%s"),
999 wwin->wm_instance ? wwin->wm_instance : "?", wwin->wm_class ? wwin->wm_class : "?");
1001 wFrameWindowChangeTitle(panel->frame->frame, str);
1003 wfree(str);
1006 static void selectWindow(WMWidget *bPtr, void *data)
1008 InspectorPanel *panel = (InspectorPanel *) data;
1009 WWindow *wwin = panel->inspected;
1010 WScreen *scr = wwin->screen_ptr;
1011 XEvent event;
1012 WWindow *iwin;
1014 if (XGrabPointer(dpy, scr->root_win, True,
1015 ButtonPressMask, GrabModeAsync, GrabModeAsync, None,
1016 wCursor[WCUR_SELECT], CurrentTime) != GrabSuccess) {
1017 wwarning("could not grab mouse pointer");
1018 return;
1021 WMSetLabelText(panel->specLbl, _("Click in the window you wish to inspect."));
1023 WMMaskEvent(dpy, ButtonPressMask, &event);
1025 XUngrabPointer(dpy, CurrentTime);
1027 iwin = wWindowFor(event.xbutton.subwindow);
1029 if (iwin && !iwin->flags.internal_window && iwin != wwin && !iwin->flags.inspector_open) {
1031 iwin->flags.inspector_open = 1;
1032 iwin->inspector = createInspectorForWindow(iwin,
1033 panel->frame->frame_x, panel->frame->frame_y, True);
1034 wCloseInspectorForWindow(wwin);
1035 } else {
1036 WMSetLabelText(panel->specLbl, spec_text);
1040 static InspectorPanel *createInspectorForWindow(WWindow *wwin, int xpos, int ypos, Bool showSelectPanel)
1042 WScreen *scr = wwin->screen_ptr;
1043 InspectorPanel *panel;
1044 Window parent;
1045 int i;
1046 int x, y;
1047 int btn_width, frame_width;
1048 WMButton *selectedBtn = NULL;
1049 #ifdef wrong_behaviour
1050 WMPixmap *pixmap;
1051 #endif
1053 spec_text = _("The configuration will apply to all\n"
1054 "windows that have their WM_CLASS\n"
1055 "property set to the above selected\n" "name, when saved.");
1057 panel = wmalloc(sizeof(InspectorPanel));
1058 memset(panel, 0, sizeof(InspectorPanel));
1060 panel->destroyed = 0;
1062 panel->inspected = wwin;
1064 panel->nextPtr = panelList;
1065 panelList = panel;
1067 panel->win = WMCreateWindow(scr->wmscreen, "windowInspector");
1068 WMResizeWidget(panel->win, PWIDTH, PHEIGHT);
1070 /**** create common stuff ****/
1072 /* command buttons */
1073 /* (PWIDTH - (left and right margin) - (btn interval)) / 3 */
1074 btn_width = (PWIDTH - (2 * 15) - (2 * 10)) / 3;
1075 panel->saveBtn = WMCreateCommandButton(panel->win);
1076 WMSetButtonAction(panel->saveBtn, (WMAction *) saveSettings, panel);
1077 WMMoveWidget(panel->saveBtn, (2 * (btn_width + 10)) + 15, PHEIGHT - 40);
1078 WMSetButtonText(panel->saveBtn, _("Save"));
1079 WMResizeWidget(panel->saveBtn, btn_width, 28);
1080 if (wPreferences.flags.noupdates || !(wwin->wm_class || wwin->wm_instance))
1081 WMSetButtonEnabled(panel->saveBtn, False);
1083 panel->applyBtn = WMCreateCommandButton(panel->win);
1084 WMSetButtonAction(panel->applyBtn, (WMAction *) applySettings, panel);
1085 WMMoveWidget(panel->applyBtn, btn_width + 10 + 15, PHEIGHT - 40);
1086 WMSetButtonText(panel->applyBtn, _("Apply"));
1087 WMResizeWidget(panel->applyBtn, btn_width, 28);
1089 panel->revertBtn = WMCreateCommandButton(panel->win);
1090 WMSetButtonAction(panel->revertBtn, (WMAction *) revertSettings, panel);
1091 WMMoveWidget(panel->revertBtn, 15, PHEIGHT - 40);
1092 WMSetButtonText(panel->revertBtn, _("Reload"));
1093 WMResizeWidget(panel->revertBtn, btn_width, 28);
1095 /* page selection popup button */
1096 panel->pagePopUp = WMCreatePopUpButton(panel->win);
1097 WMSetPopUpButtonAction(panel->pagePopUp, (WMAction *) changePage, panel);
1098 WMMoveWidget(panel->pagePopUp, 25, 15);
1099 WMResizeWidget(panel->pagePopUp, PWIDTH - 50, 20);
1101 WMAddPopUpButtonItem(panel->pagePopUp, _("Window Specification"));
1102 WMAddPopUpButtonItem(panel->pagePopUp, _("Window Attributes"));
1103 WMAddPopUpButtonItem(panel->pagePopUp, _("Advanced Options"));
1104 WMAddPopUpButtonItem(panel->pagePopUp, _("Icon and Initial Workspace"));
1105 WMAddPopUpButtonItem(panel->pagePopUp, _("Application Specific"));
1107 /**** window spec ****/
1108 frame_width = PWIDTH - (2 * 15);
1110 panel->specFrm = WMCreateFrame(panel->win);
1111 WMSetFrameTitle(panel->specFrm, _("Window Specification"));
1112 WMMoveWidget(panel->specFrm, 15, 65);
1113 WMResizeWidget(panel->specFrm, frame_width, 145);
1115 panel->defaultRb = WMCreateRadioButton(panel->specFrm);
1116 WMMoveWidget(panel->defaultRb, 10, 78);
1117 WMResizeWidget(panel->defaultRb, frame_width - (2 * 10), 20);
1118 WMSetButtonText(panel->defaultRb, _("Defaults for all windows"));
1119 WMSetButtonSelected(panel->defaultRb, False);
1120 WMSetButtonAction(panel->defaultRb, selectSpecification, panel);
1122 if (wwin->wm_class && wwin->wm_instance) {
1123 char *str, *tmp;
1125 tmp = wstrconcat(wwin->wm_instance, ".");
1126 str = wstrconcat(tmp, wwin->wm_class);
1128 panel->bothRb = WMCreateRadioButton(panel->specFrm);
1129 WMMoveWidget(panel->bothRb, 10, 18);
1130 WMResizeWidget(panel->bothRb, frame_width - (2 * 10), 20);
1131 WMSetButtonText(panel->bothRb, str);
1132 wfree(tmp);
1133 wfree(str);
1134 WMGroupButtons(panel->defaultRb, panel->bothRb);
1136 if (!selectedBtn)
1137 selectedBtn = panel->bothRb;
1139 WMSetButtonAction(panel->bothRb, selectSpecification, panel);
1142 if (wwin->wm_instance) {
1143 panel->instRb = WMCreateRadioButton(panel->specFrm);
1144 WMMoveWidget(panel->instRb, 10, 38);
1145 WMResizeWidget(panel->instRb, frame_width - (2 * 10), 20);
1146 WMSetButtonText(panel->instRb, wwin->wm_instance);
1147 WMGroupButtons(panel->defaultRb, panel->instRb);
1149 if (!selectedBtn)
1150 selectedBtn = panel->instRb;
1152 WMSetButtonAction(panel->instRb, selectSpecification, panel);
1155 if (wwin->wm_class) {
1156 panel->clsRb = WMCreateRadioButton(panel->specFrm);
1157 WMMoveWidget(panel->clsRb, 10, 58);
1158 WMResizeWidget(panel->clsRb, frame_width - (2 * 10), 20);
1159 WMSetButtonText(panel->clsRb, wwin->wm_class);
1160 WMGroupButtons(panel->defaultRb, panel->clsRb);
1162 if (!selectedBtn)
1163 selectedBtn = panel->clsRb;
1165 WMSetButtonAction(panel->clsRb, selectSpecification, panel);
1168 panel->selWinB = WMCreateCommandButton(panel->specFrm);
1169 WMMoveWidget(panel->selWinB, 20, 145 - 24 - 10);
1170 WMResizeWidget(panel->selWinB, frame_width - 2 * 10 - 20, 24);
1171 WMSetButtonText(panel->selWinB, _("Select window"));
1172 WMSetButtonAction(panel->selWinB, selectWindow, panel);
1174 panel->specLbl = WMCreateLabel(panel->win);
1175 WMMoveWidget(panel->specLbl, 15, 210);
1176 WMResizeWidget(panel->specLbl, frame_width, 100);
1177 WMSetLabelText(panel->specLbl, spec_text);
1178 WMSetLabelWraps(panel->specLbl, True);
1180 WMSetLabelTextAlignment(panel->specLbl, WALeft);
1182 /**** attributes ****/
1183 panel->attrFrm = WMCreateFrame(panel->win);
1184 WMSetFrameTitle(panel->attrFrm, _("Attributes"));
1185 WMMoveWidget(panel->attrFrm, 15, 45);
1186 WMResizeWidget(panel->attrFrm, frame_width, 250);
1188 for (i = 0; i < (sizeof(panel->attrChk) / sizeof(panel->attrChk[0])); i++) {
1189 char *caption = NULL;
1190 int flag = 0;
1191 char *descr = NULL;
1193 switch (i) {
1194 case 0:
1195 caption = _("Disable titlebar");
1196 flag = WFLAGP(wwin, no_titlebar);
1197 descr = _("Remove the titlebar of this window.\n"
1198 "To access the window commands menu of a window\n"
1199 "without it's titlebar, press Control+Esc (or the\n"
1200 "equivalent shortcut, if you changed the default\n" "settings).");
1201 break;
1202 case 1:
1203 caption = _("Disable resizebar");
1204 flag = WFLAGP(wwin, no_resizebar);
1205 descr = _("Remove the resizebar of this window.");
1206 break;
1207 case 2:
1208 caption = _("Disable close button");
1209 flag = WFLAGP(wwin, no_close_button);
1210 descr = _("Remove the `close window' button of this window.");
1211 break;
1212 case 3:
1213 caption = _("Disable miniaturize button");
1214 flag = WFLAGP(wwin, no_miniaturize_button);
1215 descr = _("Remove the `miniaturize window' button of the window.");
1216 break;
1217 case 4:
1218 caption = _("Disable border");
1219 flag = WFLAGP(wwin, no_border);
1220 descr = _("Remove the 1 pixel black border around the window.");
1221 break;
1222 case 5:
1223 caption = _("Keep on top (floating)");
1224 flag = WFLAGP(wwin, floating);
1225 descr = _("Keep the window over other windows, not allowing\n" "them to cover it.");
1226 break;
1227 case 6:
1228 caption = _("Keep at bottom (sunken)");
1229 flag = WFLAGP(wwin, sunken);
1230 descr = _("Keep the window under all other windows.");
1231 break;
1232 case 7:
1233 caption = _("Omnipresent");
1234 flag = WFLAGP(wwin, omnipresent);
1235 descr = _("Make window present in all workspaces.");
1236 break;
1237 case 8:
1238 caption = _("Start miniaturized");
1239 flag = WFLAGP(wwin, start_miniaturized);
1240 descr = _("Make the window be automatically miniaturized when it's\n" "first shown.");
1241 break;
1242 case 9:
1243 caption = _("Start maximized");
1244 flag = WFLAGP(wwin, start_maximized != 0);
1245 descr = _("Make the window be automatically maximized when it's\n" "first shown.");
1246 break;
1247 case 10:
1248 caption = _("Full screen maximization");
1249 flag = WFLAGP(wwin, full_maximize);
1250 descr = _("Make the window use the whole screen space when it's\n"
1251 "maximized. The titlebar and resizebar will be moved\n"
1252 "to outside the screen.");
1253 break;
1255 panel->attrChk[i] = WMCreateSwitchButton(panel->attrFrm);
1256 WMMoveWidget(panel->attrChk[i], 10, 20 * (i + 1));
1257 WMResizeWidget(panel->attrChk[i], frame_width - 15, 20);
1258 WMSetButtonSelected(panel->attrChk[i], flag);
1259 WMSetButtonText(panel->attrChk[i], caption);
1261 WMSetBalloonTextForView(descr, WMWidgetView(panel->attrChk[i]));
1264 /**** more attributes ****/
1265 panel->moreFrm = WMCreateFrame(panel->win);
1266 WMSetFrameTitle(panel->moreFrm, _("Advanced"));
1267 WMMoveWidget(panel->moreFrm, 15, 45);
1268 WMResizeWidget(panel->moreFrm, frame_width, 265);
1270 for (i = 0; i < (sizeof(panel->moreChk) / sizeof(panel->moreChk[0])); i++) {
1271 char *caption = NULL;
1272 int flag = 0;
1273 char *descr = NULL;
1275 switch (i) {
1276 case 0:
1277 caption = _("Do not bind keyboard shortcuts");
1278 flag = WFLAGP(wwin, no_bind_keys);
1279 descr = _("Do not bind keyboard shortcuts from Window Maker\n"
1280 "when this window is focused. This will allow the\n"
1281 "window to receive all key combinations regardless\n"
1282 "of your shortcut configuration.");
1283 break;
1284 case 1:
1285 caption = _("Do not bind mouse clicks");
1286 flag = WFLAGP(wwin, no_bind_mouse);
1287 descr = _("Do not bind mouse actions, such as `Alt'+drag\n"
1288 "in the window (when alt is the modifier you have\n" "configured).");
1289 break;
1290 case 2:
1291 caption = _("Do not show in the window list");
1292 flag = WFLAGP(wwin, skip_window_list);
1293 descr = _("Do not list the window in the window list menu.");
1294 break;
1295 case 3:
1296 caption = _("Do not show in the switch panel");
1297 flag = WFLAGP(wwin, skip_switchpanel);
1298 descr = _("Do not include in switchpanel while alternating windows.");
1299 break;
1300 case 4:
1301 caption = _("Do not let it take focus");
1302 flag = WFLAGP(wwin, no_focusable);
1303 descr = _("Do not let the window take keyboard focus when you\n" "click on it.");
1304 break;
1305 case 5:
1306 caption = _("Keep inside screen");
1307 flag = WFLAGP(wwin, dont_move_off);
1308 descr = _("Do not allow the window to move itself completely\n"
1309 "outside the screen. For bug compatibility.\n");
1310 break;
1311 case 6:
1312 caption = _("Ignore 'Hide Others'");
1313 flag = WFLAGP(wwin, no_hide_others);
1314 descr = _("Do not hide the window when issuing the\n" "`HideOthers' command.");
1315 break;
1316 case 7:
1317 caption = _("Ignore 'Save Session'");
1318 flag = WFLAGP(wwin, dont_save_session);
1319 descr = _("Do not save the associated application in the\n"
1320 "session's state, so that it won't be restarted\n"
1321 "together with other applications when Window Maker\n" "starts.");
1322 break;
1323 case 8:
1324 caption = _("Emulate application icon");
1325 flag = WFLAGP(wwin, emulate_appicon);
1326 descr = _("Make this window act as an application that provides\n"
1327 "enough information to Window Maker for a dockable\n"
1328 "application icon to be created.");
1329 break;
1330 case 9:
1331 caption = _("Focus across workspaces");
1332 flag = WFLAGP(wwin, focus_across_wksp);
1333 descr = _("Allow Window Maker to switch workspace to satisfy\n"
1334 "a focus request (annoying).");
1335 break;
1336 case 10:
1337 caption = _("Do not let it be minimized");
1338 flag = WFLAGP(wwin, no_miniaturizable);
1339 descr = _("Do not let the window of this application be\n"
1340 "minimized.\n");
1341 break;
1342 #ifdef XKB_BUTTON_HINT
1343 case 11:
1344 caption = _("Disable language button");
1345 flag = WFLAGP(wwin, no_language_button);
1346 descr = _("Remove the `toggle language' button of the window.");
1347 break;
1348 #endif
1350 panel->moreChk[i] = WMCreateSwitchButton(panel->moreFrm);
1351 WMMoveWidget(panel->moreChk[i], 10, 20 * (i + 1));
1352 WMResizeWidget(panel->moreChk[i], frame_width - 15, 20);
1353 WMSetButtonSelected(panel->moreChk[i], flag);
1354 WMSetButtonText(panel->moreChk[i], caption);
1356 WMSetBalloonTextForView(descr, WMWidgetView(panel->moreChk[i]));
1359 /* miniwindow/workspace */
1360 panel->iconFrm = WMCreateFrame(panel->win);
1361 WMMoveWidget(panel->iconFrm, 15, 50);
1362 WMResizeWidget(panel->iconFrm, PWIDTH - (2 * 15), 170);
1363 WMSetFrameTitle(panel->iconFrm, _("Miniwindow Image"));
1365 panel->iconLbl = WMCreateLabel(panel->iconFrm);
1366 WMMoveWidget(panel->iconLbl, PWIDTH - (2 * 15) - 22 - 64, 20);
1367 WMResizeWidget(panel->iconLbl, 64, 64);
1368 WMSetLabelRelief(panel->iconLbl, WRGroove);
1369 WMSetLabelImagePosition(panel->iconLbl, WIPImageOnly);
1371 panel->browseIconBtn = WMCreateCommandButton(panel->iconFrm);
1372 WMSetButtonAction(panel->browseIconBtn, chooseIconCallback, panel);
1373 WMMoveWidget(panel->browseIconBtn, 22, 32);
1374 WMResizeWidget(panel->browseIconBtn, 120, 26);
1375 WMSetButtonText(panel->browseIconBtn, _("Browse..."));
1377 #ifdef wrong_behaviour
1378 WMSetButtonImagePosition(panel->updateIconBtn, WIPRight);
1379 pixmap = WMGetSystemPixmap(scr->wmscreen, WSIReturnArrow);
1380 WMSetButtonImage(panel->updateIconBtn, pixmap);
1381 WMReleasePixmap(pixmap);
1382 pixmap = WMGetSystemPixmap(scr->wmscreen, WSIHighlightedReturnArrow);
1383 WMSetButtonAltImage(panel->updateIconBtn, pixmap);
1384 WMReleasePixmap(pixmap);
1385 #endif
1387 panel->fileLbl = WMCreateLabel(panel->iconFrm);
1388 WMMoveWidget(panel->fileLbl, 20, 85);
1389 WMResizeWidget(panel->fileLbl, PWIDTH - (2 * 15) - (2 * 20), 14);
1390 WMSetLabelText(panel->fileLbl, _("Icon filename:"));
1392 panel->fileText = WMCreateTextField(panel->iconFrm);
1393 WMMoveWidget(panel->fileText, 20, 105);
1394 WMResizeWidget(panel->fileText, PWIDTH - (2 * 20) - (2 * 15), 20);
1395 WMSetTextFieldText(panel->fileText, NULL);
1396 WMAddNotificationObserver(textEditedObserver, panel, WMTextDidEndEditingNotification, panel->fileText);
1398 panel->alwChk = WMCreateSwitchButton(panel->iconFrm);
1399 WMMoveWidget(panel->alwChk, 20, 130);
1400 WMResizeWidget(panel->alwChk, PWIDTH - (2 * 15) - (2 * 15), 30);
1401 WMSetButtonText(panel->alwChk, _("Ignore client supplied icon"));
1402 WMSetButtonSelected(panel->alwChk, WFLAGP(wwin, always_user_icon));
1404 panel->wsFrm = WMCreateFrame(panel->win);
1405 WMMoveWidget(panel->wsFrm, 15, 225);
1406 WMResizeWidget(panel->wsFrm, PWIDTH - (2 * 15), 70);
1407 WMSetFrameTitle(panel->wsFrm, _("Initial Workspace"));
1409 WMSetBalloonTextForView(_("The workspace to place the window when it's"
1410 "first shown."), WMWidgetView(panel->wsFrm));
1412 panel->wsP = WMCreatePopUpButton(panel->wsFrm);
1413 WMMoveWidget(panel->wsP, 20, 30);
1414 WMResizeWidget(panel->wsP, PWIDTH - (2 * 15) - (2 * 20), 20);
1415 WMAddPopUpButtonItem(panel->wsP, _("Nowhere in particular"));
1417 for (i = 0; i < wwin->screen_ptr->workspace_count; i++)
1418 WMAddPopUpButtonItem(panel->wsP, scr->workspaces[i]->name);
1420 i = wDefaultGetStartWorkspace(wwin->screen_ptr, wwin->wm_instance, wwin->wm_class);
1421 if (i >= 0 && i <= wwin->screen_ptr->workspace_count)
1422 WMSetPopUpButtonSelectedItem(panel->wsP, i + 1);
1423 else
1424 WMSetPopUpButtonSelectedItem(panel->wsP, 0);
1426 /* application wide attributes */
1427 if (wwin->main_window != None) {
1428 WApplication *wapp = wApplicationOf(wwin->main_window);
1430 panel->appFrm = WMCreateFrame(panel->win);
1431 WMSetFrameTitle(panel->appFrm, _("Application Attributes"));
1432 WMMoveWidget(panel->appFrm, 15, 50);
1433 WMResizeWidget(panel->appFrm, frame_width, 240);
1435 for (i = 0; i < (sizeof(panel->appChk) / sizeof(panel->appChk[0])); i++) {
1436 char *caption = NULL;
1437 int flag = 0;
1438 char *descr = NULL;
1440 switch (i) {
1441 case 0:
1442 caption = _("Start hidden");
1443 flag = WFLAGP(wapp->main_window_desc, start_hidden);
1444 descr = _("Automatically hide application when it's started.");
1445 break;
1446 case 1:
1447 caption = _("No application icon");
1448 flag = WFLAGP(wapp->main_window_desc, no_appicon);
1449 descr = _("Disable the application icon for the application.\n"
1450 "Note that you won't be able to dock it anymore,\n"
1451 "and any icons that are already docked will stop\n"
1452 "working correctly.");
1453 break;
1454 case 2:
1455 caption = _("Shared application icon");
1456 flag = WFLAGP(wapp->main_window_desc, shared_appicon);
1457 descr = _("Use a single shared application icon for all of\n"
1458 "the instances of this application.\n");
1459 break;
1461 panel->appChk[i] = WMCreateSwitchButton(panel->appFrm);
1462 WMMoveWidget(panel->appChk[i], 10, 20 * (i + 1));
1463 WMResizeWidget(panel->appChk[i], 205, 20);
1464 WMSetButtonSelected(panel->appChk[i], flag);
1465 WMSetButtonText(panel->appChk[i], caption);
1466 WMSetBalloonTextForView(descr, WMWidgetView(panel->appChk[i]));
1469 if (WFLAGP(wwin, emulate_appicon)) {
1470 WMSetButtonEnabled(panel->appChk[1], False);
1471 WMSetButtonEnabled(panel->moreChk[7], True);
1472 } else {
1473 WMSetButtonEnabled(panel->appChk[1], True);
1474 WMSetButtonEnabled(panel->moreChk[7], False);
1476 } else {
1477 int tmp;
1479 if ((wwin->transient_for != None && wwin->transient_for != scr->root_win)
1480 || !wwin->wm_class || !wwin->wm_instance)
1481 tmp = False;
1482 else
1483 tmp = True;
1484 WMSetButtonEnabled(panel->moreChk[7], tmp);
1486 WMSetPopUpButtonItemEnabled(panel->pagePopUp, 4, False);
1487 panel->appFrm = NULL;
1490 /* if the window is a transient, don't let it have a miniaturize
1491 * button */
1492 if (wwin->transient_for != None && wwin->transient_for != scr->root_win)
1493 WMSetButtonEnabled(panel->attrChk[3], False);
1494 else
1495 WMSetButtonEnabled(panel->attrChk[3], True);
1497 if (!wwin->wm_class && !wwin->wm_instance) {
1498 WMSetPopUpButtonItemEnabled(panel->pagePopUp, 0, False);
1501 WMRealizeWidget(panel->win);
1503 WMMapSubwidgets(panel->win);
1504 WMMapSubwidgets(panel->specFrm);
1505 WMMapSubwidgets(panel->attrFrm);
1506 WMMapSubwidgets(panel->moreFrm);
1507 WMMapSubwidgets(panel->iconFrm);
1508 WMMapSubwidgets(panel->wsFrm);
1509 if (panel->appFrm)
1510 WMMapSubwidgets(panel->appFrm);
1512 if (showSelectPanel) {
1513 WMSetPopUpButtonSelectedItem(panel->pagePopUp, 0);
1514 changePage(panel->pagePopUp, panel);
1515 } else {
1516 WMSetPopUpButtonSelectedItem(panel->pagePopUp, 1);
1517 changePage(panel->pagePopUp, panel);
1520 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, PWIDTH, PHEIGHT, 0, 0, 0);
1521 XSelectInput(dpy, parent, KeyPressMask | KeyReleaseMask);
1522 panel->parent = parent;
1523 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
1525 WMMapWidget(panel->win);
1527 XSetTransientForHint(dpy, parent, wwin->client_win);
1529 if (xpos == UNDEFINED_POS) {
1530 x = wwin->frame_x + wwin->frame->core->width / 2;
1531 y = wwin->frame_y + wwin->frame->top_width * 2;
1532 if (y + PHEIGHT > scr->scr_height)
1533 y = scr->scr_height - PHEIGHT - 30;
1534 if (x + PWIDTH > scr->scr_width)
1535 x = scr->scr_width - PWIDTH;
1536 } else {
1537 x = xpos;
1538 y = ypos;
1541 panel->frame = wManageInternalWindow(scr, parent, wwin->client_win, "Inspector", x, y, PWIDTH, PHEIGHT);
1543 if (!selectedBtn)
1544 selectedBtn = panel->defaultRb;
1546 WMSetButtonSelected(selectedBtn, True);
1548 selectSpecification(selectedBtn, panel);
1550 /* kluge to know who should get the key events */
1551 panel->frame->client_leader = WMWidgetXID(panel->win);
1553 WSETUFLAG(panel->frame, no_closable, 0);
1554 WSETUFLAG(panel->frame, no_close_button, 0);
1555 wWindowUpdateButtonImages(panel->frame);
1556 wFrameWindowShowButton(panel->frame->frame, WFF_RIGHT_BUTTON);
1557 panel->frame->frame->on_click_right = destroyInspector;
1559 wWindowMap(panel->frame);
1561 showIconFor(WMWidgetScreen(panel->alwChk), panel, wwin->wm_instance, wwin->wm_class, UPDATE_TEXT_FIELD);
1563 return panel;
1566 void wShowInspectorForWindow(WWindow *wwin)
1568 if (wwin->flags.inspector_open)
1569 return;
1571 WMSetBalloonEnabled(wwin->screen_ptr->wmscreen, wPreferences.help_balloon);
1573 make_keys();
1574 wwin->flags.inspector_open = 1;
1575 wwin->inspector = createInspectorForWindow(wwin, UNDEFINED_POS, UNDEFINED_POS, False);
1578 void wHideInspectorForWindow(WWindow *wwin)
1580 WWindow *pwin = wwin->inspector->frame;
1582 wWindowUnmap(pwin);
1583 pwin->flags.hidden = 1;
1585 wClientSetState(pwin, IconicState, None);
1588 void wUnhideInspectorForWindow(WWindow *wwin)
1590 WWindow *pwin = wwin->inspector->frame;
1592 pwin->flags.hidden = 0;
1593 pwin->flags.mapped = 1;
1594 XMapWindow(dpy, pwin->client_win);
1595 XMapWindow(dpy, pwin->frame->core->window);
1596 wClientSetState(pwin, NormalState, None);
1599 WWindow *wGetWindowOfInspectorForWindow(WWindow *wwin)
1601 if (wwin->inspector) {
1602 assert(wwin->flags.inspector_open != 0);
1604 return wwin->inspector->frame;
1605 } else
1606 return NULL;
1609 void wCloseInspectorForWindow(WWindow *wwin)
1611 WWindow *pwin = wwin->inspector->frame; /* the inspector window */
1613 (*pwin->frame->on_click_right) (NULL, pwin, NULL);