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.
26 #include <X11/Xutil.h>
32 #include "WindowMaker.h"
37 #include "workspace.h"
42 #include "application.h"
45 #include "winspector.h"
50 #include "switchmenu.h"
52 #include <WINGs/WUtil.h>
54 #define USE_TEXT_FIELD 1
55 #define UPDATE_TEXT_FIELD 2
56 #define REVERT_TO_DEFAULT 4
59 #define UNDEFINED_POS 0xffffff
60 #define UPDATE_DEFAULTS 1
63 typedef struct InspectorPanel
{
64 struct InspectorPanel
*nextPtr
;
67 WWindow
*inspected
; /* the window that's being inspected */
75 WMPopUpButton
*pagePopUp
;
77 /* first page. general stuff */
86 /* second page. attributes */
88 WMButton
*attrChk
[11];
90 /* 3rd page. more attributes */
92 #ifdef XKB_BUTTON_HINT
93 WMButton
*moreChk
[12];
95 WMButton
*moreChk
[11];
98 /* 4th page. icon and workspace */
102 WMTextField
*fileText
;
104 WMButton
*browseIconBtn
;
108 /* 5th page. application wide attributes */
113 unsigned int destroyed
:1;
114 unsigned int choosingIcon
:1;
117 static InspectorPanel
*panelList
= NULL
;
118 static WMPropList
*ANoTitlebar
= NULL
;
119 static WMPropList
*ANoResizebar
;
120 static WMPropList
*ANoMiniaturizeButton
;
121 static WMPropList
*ANoCloseButton
;
122 static WMPropList
*ANoBorder
;
123 static WMPropList
*ANoHideOthers
;
124 static WMPropList
*ANoMouseBindings
;
125 static WMPropList
*ANoKeyBindings
;
126 static WMPropList
*ANoAppIcon
;
127 static WMPropList
*AKeepOnTop
;
128 static WMPropList
*AKeepOnBottom
;
129 static WMPropList
*AOmnipresent
;
130 static WMPropList
*ASkipWindowList
;
131 static WMPropList
*ASkipSwitchPanel
;
132 static WMPropList
*AKeepInsideScreen
;
133 static WMPropList
*AUnfocusable
;
134 static WMPropList
*AFocusAcrossWorkspace
;
135 static WMPropList
*AAlwaysUserIcon
;
136 static WMPropList
*AStartMiniaturized
;
137 static WMPropList
*AStartMaximized
;
138 static WMPropList
*ADontSaveSession
;
139 static WMPropList
*AEmulateAppIcon
;
140 static WMPropList
*AFullMaximize
;
141 static WMPropList
*ASharedAppIcon
;
142 static WMPropList
*ANoMiniaturizable
;
143 #ifdef XKB_BUTTON_HINT
144 static WMPropList
*ANoLanguageButton
;
146 static WMPropList
*AStartWorkspace
;
147 static WMPropList
*AIcon
;
149 /* application wide options */
150 static WMPropList
*AStartHidden
;
151 static WMPropList
*AnyWindow
;
152 static WMPropList
*EmptyString
;
153 static WMPropList
*Yes
, *No
;
155 static char *spec_text
;
156 static void applySettings(WMWidget
*button
, void *panel
);
158 static InspectorPanel
*createInspectorForWindow(WWindow
*wwin
, int xpos
, int ypos
, Bool showSelectPanel
);
160 static void create_tab_window_attributes(WWindow
*wwin
, InspectorPanel
*panel
, int frame_width
);
161 static void create_tab_window_advanced(WWindow
*wwin
, InspectorPanel
*panel
, int frame_width
);
162 static void create_tab_icon_workspace(WWindow
*wwin
, InspectorPanel
*panel
);
163 static void create_tab_app_specific(WWindow
*wwin
, InspectorPanel
*panel
, int frame_width
);
165 static void make_keys(void)
167 if (ANoTitlebar
!= NULL
)
170 AIcon
= WMCreatePLString("Icon");
171 ANoTitlebar
= WMCreatePLString("NoTitlebar");
172 ANoResizebar
= WMCreatePLString("NoResizebar");
173 ANoMiniaturizeButton
= WMCreatePLString("NoMiniaturizeButton");
174 ANoCloseButton
= WMCreatePLString("NoCloseButton");
175 ANoBorder
= WMCreatePLString("NoBorder");
176 ANoHideOthers
= WMCreatePLString("NoHideOthers");
177 ANoMouseBindings
= WMCreatePLString("NoMouseBindings");
178 ANoKeyBindings
= WMCreatePLString("NoKeyBindings");
179 ANoAppIcon
= WMCreatePLString("NoAppIcon");
180 AKeepOnTop
= WMCreatePLString("KeepOnTop");
181 AKeepOnBottom
= WMCreatePLString("KeepOnBottom");
182 AOmnipresent
= WMCreatePLString("Omnipresent");
183 ASkipWindowList
= WMCreatePLString("SkipWindowList");
184 ASkipSwitchPanel
= WMCreatePLString("SkipSwitchPanel");
185 AKeepInsideScreen
= WMCreatePLString("KeepInsideScreen");
186 AUnfocusable
= WMCreatePLString("Unfocusable");
187 AFocusAcrossWorkspace
= WMCreatePLString("FocusAcrossWorkspace");
188 AAlwaysUserIcon
= WMCreatePLString("AlwaysUserIcon");
189 AStartMiniaturized
= WMCreatePLString("StartMiniaturized");
190 AStartMaximized
= WMCreatePLString("StartMaximized");
191 AStartHidden
= WMCreatePLString("StartHidden");
192 ADontSaveSession
= WMCreatePLString("DontSaveSession");
193 AEmulateAppIcon
= WMCreatePLString("EmulateAppIcon");
194 AFullMaximize
= WMCreatePLString("FullMaximize");
195 ASharedAppIcon
= WMCreatePLString("SharedAppIcon");
196 ANoMiniaturizable
= WMCreatePLString("NoMiniaturizable");
197 #ifdef XKB_BUTTON_HINT
198 ANoLanguageButton
= WMCreatePLString("NoLanguageButton");
201 AStartWorkspace
= WMCreatePLString("StartWorkspace");
203 AnyWindow
= WMCreatePLString("*");
204 EmptyString
= WMCreatePLString("");
205 Yes
= WMCreatePLString("Yes");
206 No
= WMCreatePLString("No");
209 static void freeInspector(InspectorPanel
*panel
)
211 panel
->destroyed
= 1;
213 if (panel
->choosingIcon
)
216 WMDestroyWidget(panel
->win
);
217 XDestroyWindow(dpy
, panel
->parent
);
221 static void destroyInspector(WCoreWindow
*foo
, void *data
, XEvent
*event
)
223 InspectorPanel
*panel
, *tmp
;
225 /* Parameter not used, but tell the compiler that it is ok */
230 while (panel
->frame
!= data
)
231 panel
= panel
->nextPtr
;
233 if (panelList
== panel
) {
234 panelList
= panel
->nextPtr
;
237 while (tmp
->nextPtr
!= panel
)
240 tmp
->nextPtr
= panel
->nextPtr
;
242 panel
->inspected
->flags
.inspector_open
= 0;
243 panel
->inspected
->inspector
= NULL
;
245 WMRemoveNotificationObserver(panel
);
247 wWindowUnmap(panel
->frame
);
248 wUnmanageWindow(panel
->frame
, True
, False
);
250 freeInspector(panel
);
253 void wDestroyInspectorPanels(void)
255 InspectorPanel
*panel
;
257 while (panelList
!= NULL
) {
259 panelList
= panelList
->nextPtr
;
260 wUnmanageWindow(panel
->frame
, False
, False
);
261 WMDestroyWidget(panel
->win
);
263 panel
->inspected
->flags
.inspector_open
= 0;
264 panel
->inspected
->inspector
= NULL
;
270 static void changePage(WMWidget
*bPtr
, void *client_data
)
272 InspectorPanel
*panel
= (InspectorPanel
*) client_data
;
275 page
= WMGetPopUpButtonSelectedItem(bPtr
);
278 WMMapWidget(panel
->specFrm
);
279 WMMapWidget(panel
->specLbl
);
280 } else if (page
== 1) {
281 WMMapWidget(panel
->attrFrm
);
282 } else if (page
== 2) {
283 WMMapWidget(panel
->moreFrm
);
284 } else if (page
== 3) {
285 WMMapWidget(panel
->iconFrm
);
286 WMMapWidget(panel
->wsFrm
);
288 WMMapWidget(panel
->appFrm
);
292 WMUnmapWidget(panel
->specFrm
);
293 WMUnmapWidget(panel
->specLbl
);
296 WMUnmapWidget(panel
->attrFrm
);
298 WMUnmapWidget(panel
->moreFrm
);
300 WMUnmapWidget(panel
->iconFrm
);
301 WMUnmapWidget(panel
->wsFrm
);
303 if (page
!= 4 && panel
->appFrm
)
304 WMUnmapWidget(panel
->appFrm
);
307 static int showIconFor(WMScreen
*scrPtr
, InspectorPanel
*panel
, const char *wm_instance
, const char *wm_class
, int flags
)
309 WMPixmap
*pixmap
= (WMPixmap
*) NULL
;
310 char *file
= NULL
, *path
= NULL
;
312 if ((flags
& USE_TEXT_FIELD
) != 0) {
313 file
= WMGetTextFieldText(panel
->fileText
);
314 if (file
&& file
[0] == 0) {
318 } else if (flags
& REVERT_TO_DEFAULT
) {
321 /* Get the application icon, default NOT included */
322 db_icon
= wDefaultGetIconFile(wm_instance
, wm_class
, False
);
323 if (db_icon
!= NULL
) {
324 file
= wstrdup(db_icon
);
325 flags
|= UPDATE_TEXT_FIELD
;
329 if ((flags
& UPDATE_TEXT_FIELD
) != 0)
330 WMSetTextFieldText(panel
->fileText
, file
);
333 path
= FindImage(wPreferences
.icon_path
, file
);
337 int len
= strlen(file
) + 80;
340 snprintf(buf
, len
, _("Could not find icon \"%s\" specified for this window"), file
);
341 wMessageDialog(panel
->frame
->screen_ptr
, _("Error"), buf
, _("OK"), NULL
, NULL
);
347 pixmap
= WMCreatePixmapFromFile(scrPtr
, path
);
352 int len
= strlen(file
) + 80;
355 snprintf(buf
, len
, _("Could not open specified icon \"%s\":%s"),
356 file
, RMessageForError(RErrorCode
));
357 wMessageDialog(panel
->frame
->screen_ptr
, _("Error"), buf
, _("OK"), NULL
, NULL
);
365 WMSetLabelImage(panel
->iconLbl
, pixmap
);
367 WMReleasePixmap(pixmap
);
372 static int getBool(WMPropList
*value
)
376 if (!WMIsPLString(value
))
379 if (!(val
= WMGetFromPLString(value
)))
382 if ((val
[1] == '\0' &&
383 (val
[0] == 'y' || val
[0] == 'Y' || val
[0] == 'T' ||
384 val
[0] == 't' || val
[0] == '1')) ||
385 (strcasecmp(val
, "YES") == 0 || strcasecmp(val
, "TRUE") == 0)) {
387 } else if ((val
[1] == '\0' &&
388 (val
[0] == 'n' || val
[0] == 'N' || val
[0] == 'F' ||
389 val
[0] == 'f' || val
[0] == '0')) ||
390 (strcasecmp(val
, "NO") == 0 || strcasecmp(val
, "FALSE") == 0)) {
393 wwarning(_("can't convert \"%s\" to boolean"), val
);
398 /* Will insert the attribute = value; pair in window's list,
399 * if it's different from the defaults.
400 * Defaults means either defaults database, or attributes saved
401 * for the default window "*". This is to let one revert options that are
402 * global because they were saved for all windows ("*"). */
404 insertAttribute(WMPropList
*dict
, WMPropList
*window
, WMPropList
*attr
, WMPropList
*value
, int flags
)
406 WMPropList
*def_win
, *def_value
= NULL
;
407 int update
= 0, modified
= 0;
409 if (!(flags
& UPDATE_DEFAULTS
) && dict
) {
410 if ((def_win
= WMGetFromPLDictionary(dict
, AnyWindow
)) != NULL
)
411 def_value
= WMGetFromPLDictionary(def_win
, attr
);
414 /* If we could not find defaults in database, fall to hardcoded values.
415 * Also this is true if we save defaults for all windows */
417 def_value
= ((flags
& IS_BOOLEAN
) != 0) ? No
: EmptyString
;
419 if (flags
& IS_BOOLEAN
)
420 update
= (getBool(value
) != getBool(def_value
));
422 update
= !WMIsPropListEqualTo(value
, def_value
);
425 WMPutInPLDictionary(window
, attr
, value
);
432 static void saveSettings(WMWidget
*button
, void *client_data
)
434 InspectorPanel
*panel
= (InspectorPanel
*) client_data
;
435 WWindow
*wwin
= panel
->inspected
;
436 WDDomain
*db
= w_global
.domain
.window_attr
;
437 WMPropList
*dict
= NULL
;
438 WMPropList
*winDic
, *appDic
, *value
, *value1
, *key
= NULL
, *key2
;
439 char *icon_file
, *buf1
, *buf2
;
440 int flags
= 0, i
= 0, different
= 0, different2
= 0;
442 /* Save will apply the changes and save them */
443 applySettings(panel
->applyBtn
, panel
);
445 if (WMGetButtonSelected(panel
->instRb
) != 0) {
446 key
= WMCreatePLString(wwin
->wm_instance
);
447 } else if (WMGetButtonSelected(panel
->clsRb
) != 0) {
448 key
= WMCreatePLString(wwin
->wm_class
);
449 } else if (WMGetButtonSelected(panel
->bothRb
) != 0) {
450 buf1
= StrConcatDot(wwin
->wm_instance
, wwin
->wm_class
);
451 key
= WMCreatePLString(buf1
);
453 } else if (WMGetButtonSelected(panel
->defaultRb
) != 0) {
454 key
= WMRetainPropList(AnyWindow
);
455 flags
= UPDATE_DEFAULTS
;
461 dict
= db
->dictionary
;
463 dict
= WMCreatePLDictionary(NULL
, NULL
);
465 db
->dictionary
= dict
;
467 WMReleasePropList(key
);
472 if (showIconFor(WMWidgetScreen(button
), panel
, NULL
, NULL
, USE_TEXT_FIELD
) < 0)
475 WMPLSetCaseSensitive(True
);
477 winDic
= WMCreatePLDictionary(NULL
, NULL
);
478 appDic
= WMCreatePLDictionary(NULL
, NULL
);
480 /* Save the icon info */
481 /* The flag "Ignore client suplied icon is not selected" */
483 snprintf(buf1
, 4, "%s", (WMGetButtonSelected(panel
->alwChk
) != 0) ? "Yes" : "No");
484 value1
= WMCreatePLString(buf1
);
485 different
|= insertAttribute(dict
, winDic
, AAlwaysUserIcon
, value1
, flags
);
486 WMReleasePropList(value1
);
489 /* The icon filename (if exists) */
490 icon_file
= WMGetTextFieldText(panel
->fileText
);
491 if (icon_file
!= NULL
) {
492 if (icon_file
[0] != '\0') {
493 value
= WMCreatePLString(icon_file
);
494 different
|= insertAttribute(dict
, winDic
, AIcon
, value
, flags
);
495 different2
|= insertAttribute(dict
, appDic
, AIcon
, value
, flags
);
496 WMReleasePropList(value
);
501 i
= WMGetPopUpButtonSelectedItem(panel
->wsP
) - 1;
502 if (i
>= 0 && i
< w_global
.workspace
.count
) {
503 value
= WMCreatePLString(w_global
.workspace
.array
[i
]->name
);
504 different
|= insertAttribute(dict
, winDic
, AStartWorkspace
, value
, flags
);
505 WMReleasePropList(value
);
510 value
= (WMGetButtonSelected(panel
->attrChk
[0]) != 0) ? Yes
: No
;
511 different
|= insertAttribute(dict
, winDic
, ANoTitlebar
, value
, flags
);
513 value
= (WMGetButtonSelected(panel
->attrChk
[1]) != 0) ? Yes
: No
;
514 different
|= insertAttribute(dict
, winDic
, ANoResizebar
, value
, flags
);
516 value
= (WMGetButtonSelected(panel
->attrChk
[2]) != 0) ? Yes
: No
;
517 different
|= insertAttribute(dict
, winDic
, ANoCloseButton
, value
, flags
);
519 value
= (WMGetButtonSelected(panel
->attrChk
[3]) != 0) ? Yes
: No
;
520 different
|= insertAttribute(dict
, winDic
, ANoMiniaturizeButton
, value
, flags
);
522 value
= (WMGetButtonSelected(panel
->attrChk
[4]) != 0) ? Yes
: No
;
523 different
|= insertAttribute(dict
, winDic
, ANoBorder
, value
, flags
);
525 value
= (WMGetButtonSelected(panel
->attrChk
[5]) != 0) ? Yes
: No
;
526 different
|= insertAttribute(dict
, winDic
, AKeepOnTop
, value
, flags
);
528 value
= (WMGetButtonSelected(panel
->attrChk
[6]) != 0) ? Yes
: No
;
529 different
|= insertAttribute(dict
, winDic
, AKeepOnBottom
, value
, flags
);
531 value
= (WMGetButtonSelected(panel
->attrChk
[7]) != 0) ? Yes
: No
;
532 different
|= insertAttribute(dict
, winDic
, AOmnipresent
, value
, flags
);
534 value
= (WMGetButtonSelected(panel
->attrChk
[8]) != 0) ? Yes
: No
;
535 different
|= insertAttribute(dict
, winDic
, AStartMiniaturized
, value
, flags
);
537 value
= (WMGetButtonSelected(panel
->attrChk
[9]) != 0) ? Yes
: No
;
538 different
|= insertAttribute(dict
, winDic
, AStartMaximized
, value
, flags
);
540 value
= (WMGetButtonSelected(panel
->attrChk
[10]) != 0) ? Yes
: No
;
541 different
|= insertAttribute(dict
, winDic
, AFullMaximize
, value
, flags
);
543 value
= (WMGetButtonSelected(panel
->moreChk
[0]) != 0) ? Yes
: No
;
544 different
|= insertAttribute(dict
, winDic
, ANoKeyBindings
, value
, flags
);
546 value
= (WMGetButtonSelected(panel
->moreChk
[1]) != 0) ? Yes
: No
;
547 different
|= insertAttribute(dict
, winDic
, ANoMouseBindings
, value
, flags
);
549 value
= (WMGetButtonSelected(panel
->moreChk
[2]) != 0) ? Yes
: No
;
550 different
|= insertAttribute(dict
, winDic
, ASkipWindowList
, value
, flags
);
552 value
= (WMGetButtonSelected(panel
->moreChk
[3]) != 0) ? Yes
: No
;
553 different
|= insertAttribute(dict
, winDic
, ASkipSwitchPanel
, value
, flags
);
555 value
= (WMGetButtonSelected(panel
->moreChk
[4]) != 0) ? Yes
: No
;
556 different
|= insertAttribute(dict
, winDic
, AUnfocusable
, value
, flags
);
558 value
= (WMGetButtonSelected(panel
->moreChk
[5]) != 0) ? Yes
: No
;
559 different
|= insertAttribute(dict
, winDic
, AKeepInsideScreen
, value
, flags
);
561 value
= (WMGetButtonSelected(panel
->moreChk
[6]) != 0) ? Yes
: No
;
562 different
|= insertAttribute(dict
, winDic
, ANoHideOthers
, value
, flags
);
564 value
= (WMGetButtonSelected(panel
->moreChk
[7]) != 0) ? Yes
: No
;
565 different
|= insertAttribute(dict
, winDic
, ADontSaveSession
, value
, flags
);
567 value
= (WMGetButtonSelected(panel
->moreChk
[8]) != 0) ? Yes
: No
;
568 different
|= insertAttribute(dict
, winDic
, AEmulateAppIcon
, value
, flags
);
570 value
= (WMGetButtonSelected(panel
->moreChk
[9]) != 0) ? Yes
: No
;
571 different
|= insertAttribute(dict
, winDic
, AFocusAcrossWorkspace
, value
, flags
);
573 value
= (WMGetButtonSelected(panel
->moreChk
[10]) != 0) ? Yes
: No
;
574 different
|= insertAttribute(dict
, winDic
, ANoMiniaturizable
, value
, flags
);
576 #ifdef XKB_BUTTON_HINT
577 value
= (WMGetButtonSelected(panel
->moreChk
[11]) != 0) ? Yes
: No
;
578 different
|= insertAttribute(dict
, winDic
, ANoLanguageButton
, value
, flags
);
581 if (wwin
->main_window
!= None
&& wApplicationOf(wwin
->main_window
) != NULL
) {
582 value
= (WMGetButtonSelected(panel
->appChk
[0]) != 0) ? Yes
: No
;
583 different2
|= insertAttribute(dict
, appDic
, AStartHidden
, value
, flags
);
585 value
= (WMGetButtonSelected(panel
->appChk
[1]) != 0) ? Yes
: No
;
586 different2
|= insertAttribute(dict
, appDic
, ANoAppIcon
, value
, flags
);
588 value
= (WMGetButtonSelected(panel
->appChk
[2]) != 0) ? Yes
: No
;
589 different2
|= insertAttribute(dict
, appDic
, ASharedAppIcon
, value
, flags
);
592 if (wwin
->fake_group
) {
593 key2
= WMCreatePLString(wwin
->fake_group
->identifier
);
594 if (WMIsPropListEqualTo(key
, key2
)) {
595 WMMergePLDictionaries(winDic
, appDic
, True
);
596 different
|= different2
;
598 WMRemoveFromPLDictionary(dict
, key2
);
600 WMPutInPLDictionary(dict
, key2
, appDic
);
602 WMReleasePropList(key2
);
603 } else if (wwin
->main_window
!= wwin
->client_win
) {
604 WApplication
*wapp
= wApplicationOf(wwin
->main_window
);
607 buf2
= StrConcatDot(wapp
->main_window_desc
->wm_instance
,
608 wapp
->main_window_desc
->wm_class
);
609 key2
= WMCreatePLString(buf2
);
612 if (WMIsPropListEqualTo(key
, key2
)) {
613 WMMergePLDictionaries(winDic
, appDic
, True
);
614 different
|= different2
;
616 WMRemoveFromPLDictionary(dict
, key2
);
618 WMPutInPLDictionary(dict
, key2
, appDic
);
620 WMReleasePropList(key2
);
623 WMMergePLDictionaries(winDic
, appDic
, True
);
624 different
|= different2
;
626 WMReleasePropList(appDic
);
628 WMRemoveFromPLDictionary(dict
, key
);
630 WMPutInPLDictionary(dict
, key
, winDic
);
632 WMReleasePropList(key
);
633 WMReleasePropList(winDic
);
635 UpdateDomainFile(db
);
638 WMPLSetCaseSensitive(False
);
641 static void applySettings(WMWidget
*button
, void *client_data
)
643 InspectorPanel
*panel
= (InspectorPanel
*) client_data
;
644 WWindow
*wwin
= panel
->inspected
;
645 WApplication
*wapp
= wApplicationOf(wwin
->main_window
);
646 int floating
, sunken
, skip_window_list
;
647 int old_omnipresent
, old_no_bind_keys
, old_no_bind_mouse
;
649 old_omnipresent
= WFLAGP(wwin
, omnipresent
);
650 old_no_bind_keys
= WFLAGP(wwin
, no_bind_keys
);
651 old_no_bind_mouse
= WFLAGP(wwin
, no_bind_mouse
);
653 showIconFor(WMWidgetScreen(button
), panel
, NULL
, NULL
, USE_TEXT_FIELD
);
655 /* Attributes... --> Window Attributes */
656 WSETUFLAG(wwin
, no_titlebar
, WMGetButtonSelected(panel
->attrChk
[0]));
657 WSETUFLAG(wwin
, no_resizebar
, WMGetButtonSelected(panel
->attrChk
[1]));
658 WSETUFLAG(wwin
, no_close_button
, WMGetButtonSelected(panel
->attrChk
[2]));
659 WSETUFLAG(wwin
, no_miniaturize_button
, WMGetButtonSelected(panel
->attrChk
[3]));
660 WSETUFLAG(wwin
, no_border
, WMGetButtonSelected(panel
->attrChk
[4]));
661 floating
= WMGetButtonSelected(panel
->attrChk
[5]);
662 sunken
= WMGetButtonSelected(panel
->attrChk
[6]);
663 WSETUFLAG(wwin
, omnipresent
, WMGetButtonSelected(panel
->attrChk
[7]));
664 WSETUFLAG(wwin
, start_miniaturized
, WMGetButtonSelected(panel
->attrChk
[8]));
665 WSETUFLAG(wwin
, start_maximized
, WMGetButtonSelected(panel
->attrChk
[9]));
666 WSETUFLAG(wwin
, full_maximize
, WMGetButtonSelected(panel
->attrChk
[10]));
668 /* Attributes... --> Advanced Options */
669 WSETUFLAG(wwin
, no_bind_keys
, WMGetButtonSelected(panel
->moreChk
[0]));
670 WSETUFLAG(wwin
, no_bind_mouse
, WMGetButtonSelected(panel
->moreChk
[1]));
671 skip_window_list
= WMGetButtonSelected(panel
->moreChk
[2]);
672 WSETUFLAG(wwin
, skip_switchpanel
, WMGetButtonSelected(panel
->moreChk
[3]));
673 WSETUFLAG(wwin
, no_focusable
, WMGetButtonSelected(panel
->moreChk
[4]));
674 WSETUFLAG(wwin
, dont_move_off
, WMGetButtonSelected(panel
->moreChk
[5]));
675 WSETUFLAG(wwin
, no_hide_others
, WMGetButtonSelected(panel
->moreChk
[6]));
676 WSETUFLAG(wwin
, dont_save_session
, WMGetButtonSelected(panel
->moreChk
[7]));
677 WSETUFLAG(wwin
, emulate_appicon
, WMGetButtonSelected(panel
->moreChk
[8]));
678 WSETUFLAG(wwin
, focus_across_wksp
, WMGetButtonSelected(panel
->moreChk
[9]));
679 WSETUFLAG(wwin
, no_miniaturizable
, WMGetButtonSelected(panel
->moreChk
[10]));
680 #ifdef XKB_BUTTON_HINT
681 WSETUFLAG(wwin
, no_language_button
, WMGetButtonSelected(panel
->moreChk
[11]));
683 WSETUFLAG(wwin
, always_user_icon
, WMGetButtonSelected(panel
->alwChk
));
685 if (WFLAGP(wwin
, no_titlebar
) && wwin
->flags
.shaded
)
686 wUnshadeWindow(wwin
);
688 WSETUFLAG(wwin
, no_shadeable
, WFLAGP(wwin
, no_titlebar
));
691 if (!WFLAGP(wwin
, floating
))
692 ChangeStackingLevel(wwin
->frame
->core
, WMFloatingLevel
);
694 if (!WFLAGP(wwin
, sunken
))
695 ChangeStackingLevel(wwin
->frame
->core
, WMSunkenLevel
);
697 if (WFLAGP(wwin
, floating
) || WFLAGP(wwin
, sunken
))
698 ChangeStackingLevel(wwin
->frame
->core
, WMNormalLevel
);
701 WSETUFLAG(wwin
, sunken
, sunken
);
702 WSETUFLAG(wwin
, floating
, floating
);
703 wwin
->flags
.omnipresent
= 0;
705 if (WFLAGP(wwin
, skip_window_list
) != skip_window_list
) {
706 WSETUFLAG(wwin
, skip_window_list
, skip_window_list
);
707 UpdateSwitchMenu(wwin
->screen_ptr
, wwin
, skip_window_list
? ACTION_REMOVE
: ACTION_ADD
);
709 if (WFLAGP(wwin
, omnipresent
) != old_omnipresent
)
710 WMPostNotificationName(WMNChangedState
, wwin
, "omnipresent");
713 if (WFLAGP(wwin
, no_bind_keys
) != old_no_bind_keys
) {
714 if (WFLAGP(wwin
, no_bind_keys
))
715 XUngrabKey(dpy
, AnyKey
, AnyModifier
, wwin
->frame
->core
->window
);
717 wWindowSetKeyGrabs(wwin
);
720 if (WFLAGP(wwin
, no_bind_mouse
) != old_no_bind_mouse
)
721 wWindowResetMouseGrabs(wwin
);
723 wwin
->frame
->flags
.need_texture_change
= 1;
724 wWindowConfigureBorders(wwin
);
725 wFrameWindowPaint(wwin
->frame
);
726 wNETWMUpdateActions(wwin
, False
);
728 /* Can't apply emulate_appicon because it will probably cause problems. */
730 /* do application wide stuff */
731 WSETUFLAG(wapp
->main_window_desc
, start_hidden
, WMGetButtonSelected(panel
->appChk
[0]));
732 WSETUFLAG(wapp
->main_window_desc
, no_appicon
, WMGetButtonSelected(panel
->appChk
[1]));
733 WSETUFLAG(wapp
->main_window_desc
, shared_appicon
, WMGetButtonSelected(panel
->appChk
[2]));
735 if (WFLAGP(wapp
->main_window_desc
, no_appicon
))
736 unpaint_app_icon(wapp
);
738 paint_app_icon(wapp
);
740 char *file
= WMGetTextFieldText(panel
->fileText
);
746 /* If always_user_icon flag is set, but the user icon is not set
747 * we use client supplied icon and we unset the flag */
748 if ((WFLAGP(wwin
, always_user_icon
) && (!file
))) {
749 /* Show the warning */
754 snprintf(buf
, len
, _("Ignore client supplied icon is set, but icon filename textbox is empty. Using client supplied icon"));
755 wMessageDialog(panel
->frame
->screen_ptr
, _("Warning"), buf
, _("OK"), NULL
, NULL
);
759 /* Change the flags */
760 WSETUFLAG(wwin
, always_user_icon
, 0);
761 WMSetButtonSelected(panel
->alwChk
, 0);
764 /* After test the always_user_icon flag value before,
765 * the "else" block is used only if the flag is set and
766 * the icon text box has an icon path */
767 if (!WFLAGP(wwin
, always_user_icon
)) {
768 /* Change App Icon image, using the icon provided by the client */
769 if (wapp
->app_icon
) {
770 RImage
*image
= get_rimage_icon_from_wm_hints(wapp
->app_icon
->icon
);
772 set_icon_image_from_image(wapp
->app_icon
->icon
, image
);
773 update_icon_pixmap(wapp
->app_icon
->icon
);
775 wIconUpdate(wapp
->app_icon
->icon
);
779 /* Change icon image if the app is minimized,
780 * using the icon provided by the client */
782 RImage
*image
= get_rimage_icon_from_wm_hints(wwin
->icon
);
784 set_icon_image_from_image(wwin
->icon
, image
);
785 update_icon_pixmap(wwin
->icon
);
787 wIconUpdate(wwin
->icon
);
791 /* Change App Icon image */
793 wIconChangeImageFile(wapp
->app_icon
->icon
, file
);
795 /* Change icon image if the app is minimized */
797 wIconChangeImageFile(wwin
->icon
, file
);
804 wNETFrameExtents(wwin
);
807 static void revertSettings(WMWidget
*button
, void *client_data
)
809 InspectorPanel
*panel
= (InspectorPanel
*) client_data
;
810 WWindow
*wwin
= panel
->inspected
;
811 WApplication
*wapp
= wApplicationOf(wwin
->main_window
);
812 int i
, n
, workspace
, level
;
813 char *wm_instance
= NULL
, *wm_class
= NULL
;
815 /* Parameter not used, but tell the compiler that it is ok */
818 if (panel
->instRb
&& WMGetButtonSelected(panel
->instRb
) != 0)
819 wm_instance
= wwin
->wm_instance
;
820 else if (panel
->clsRb
&& WMGetButtonSelected(panel
->clsRb
) != 0)
821 wm_class
= wwin
->wm_class
;
822 else if (panel
->bothRb
&& WMGetButtonSelected(panel
->bothRb
) != 0) {
823 wm_instance
= wwin
->wm_instance
;
824 wm_class
= wwin
->wm_class
;
827 memset(&wwin
->defined_user_flags
, 0, sizeof(WWindowAttributes
));
828 memset(&wwin
->user_flags
, 0, sizeof(WWindowAttributes
));
829 memset(&wwin
->client_flags
, 0, sizeof(WWindowAttributes
));
831 wWindowSetupInitialAttributes(wwin
, &level
, &workspace
);
833 for (i
= 0; i
< wlengthof(panel
->attrChk
); i
++) {
838 flag
= WFLAGP(wwin
, no_titlebar
);
841 flag
= WFLAGP(wwin
, no_resizebar
);
844 flag
= WFLAGP(wwin
, no_close_button
);
847 flag
= WFLAGP(wwin
, no_miniaturize_button
);
850 flag
= WFLAGP(wwin
, no_border
);
853 flag
= WFLAGP(wwin
, floating
);
856 flag
= WFLAGP(wwin
, sunken
);
859 flag
= WFLAGP(wwin
, omnipresent
);
862 flag
= WFLAGP(wwin
, start_miniaturized
);
865 flag
= WFLAGP(wwin
, start_maximized
!= 0);
868 flag
= WFLAGP(wwin
, full_maximize
);
871 WMSetButtonSelected(panel
->attrChk
[i
], flag
);
874 for (i
= 0; i
< wlengthof(panel
->moreChk
); i
++) {
879 flag
= WFLAGP(wwin
, no_bind_keys
);
882 flag
= WFLAGP(wwin
, no_bind_mouse
);
885 flag
= WFLAGP(wwin
, skip_window_list
);
888 flag
= WFLAGP(wwin
, skip_switchpanel
);
891 flag
= WFLAGP(wwin
, no_focusable
);
894 flag
= WFLAGP(wwin
, dont_move_off
);
897 flag
= WFLAGP(wwin
, no_hide_others
);
900 flag
= WFLAGP(wwin
, dont_save_session
);
903 flag
= WFLAGP(wwin
, emulate_appicon
);
906 flag
= WFLAGP(wwin
, focus_across_wksp
);
909 flag
= WFLAGP(wwin
, no_miniaturizable
);
911 #ifdef XKB_BUTTON_HINT
913 flag
= WFLAGP(wwin
, no_language_button
);
917 WMSetButtonSelected(panel
->moreChk
[i
], flag
);
919 if (panel
->appFrm
&& wapp
) {
920 for (i
= 0; i
< wlengthof(panel
->appChk
); i
++) {
925 flag
= WFLAGP(wapp
->main_window_desc
, start_hidden
);
928 flag
= WFLAGP(wapp
->main_window_desc
, no_appicon
);
931 flag
= WFLAGP(wapp
->main_window_desc
, shared_appicon
);
934 WMSetButtonSelected(panel
->appChk
[i
], flag
);
937 WMSetButtonSelected(panel
->alwChk
, WFLAGP(wwin
, always_user_icon
));
939 showIconFor(WMWidgetScreen(panel
->alwChk
), panel
, wm_instance
, wm_class
, REVERT_TO_DEFAULT
);
941 n
= wDefaultGetStartWorkspace(wm_instance
, wm_class
);
943 if (n
>= 0 && n
< w_global
.workspace
.count
)
944 WMSetPopUpButtonSelectedItem(panel
->wsP
, n
+ 1);
946 WMSetPopUpButtonSelectedItem(panel
->wsP
, 0);
948 /* must auto apply, so that there wno't be internal
949 * inconsistencies between the state in the flags and
950 * the actual state of the window */
951 applySettings(panel
->applyBtn
, panel
);
954 static void chooseIconCallback(WMWidget
*self
, void *clientData
)
957 InspectorPanel
*panel
= (InspectorPanel
*) clientData
;
960 panel
->choosingIcon
= 1;
962 WMSetButtonEnabled(panel
->browseIconBtn
, False
);
964 result
= wIconChooserDialog(panel
->frame
->screen_ptr
, &file
,
965 panel
->inspected
->wm_instance
,
966 panel
->inspected
->wm_class
);
968 panel
->choosingIcon
= 0;
970 if (!panel
->destroyed
) { /* kluge */
972 WMSetTextFieldText(panel
->fileText
, file
);
973 showIconFor(WMWidgetScreen(self
), panel
, NULL
, NULL
, USE_TEXT_FIELD
);
975 WMSetButtonEnabled(panel
->browseIconBtn
, True
);
977 freeInspector(panel
);
983 static void textEditedObserver(void *observerData
, WMNotification
*notification
)
985 InspectorPanel
*panel
= (InspectorPanel
*) observerData
;
987 if ((long)WMGetNotificationClientData(notification
) != WMReturnTextMovement
)
990 showIconFor(WMWidgetScreen(panel
->win
), panel
, NULL
, NULL
, USE_TEXT_FIELD
);
993 static void selectSpecification(WMWidget
*bPtr
, void *data
)
995 InspectorPanel
*panel
= (InspectorPanel
*) data
;
997 WWindow
*wwin
= panel
->inspected
;
999 if (bPtr
== panel
->defaultRb
&& (wwin
->wm_instance
|| wwin
->wm_class
))
1000 WMSetButtonEnabled(panel
->applyBtn
, False
);
1002 WMSetButtonEnabled(panel
->applyBtn
, True
);
1004 snprintf(str
, sizeof(str
),
1005 _("Inspecting %s.%s"),
1006 wwin
->wm_instance
? wwin
->wm_instance
: "?",
1007 wwin
->wm_class
? wwin
->wm_class
: "?");
1009 wFrameWindowChangeTitle(panel
->frame
->frame
, str
);
1012 static void selectWindow(WMWidget
*bPtr
, void *data
)
1014 InspectorPanel
*panel
= (InspectorPanel
*) data
;
1015 WWindow
*wwin
= panel
->inspected
;
1016 WScreen
*scr
= wwin
->screen_ptr
;
1020 /* Parameter not used, but tell the compiler that it is ok */
1023 if (XGrabPointer(dpy
, scr
->root_win
, True
,
1024 ButtonPressMask
, GrabModeAsync
, GrabModeAsync
, None
,
1025 wPreferences
.cursor
[WCUR_SELECT
], CurrentTime
) != GrabSuccess
) {
1026 wwarning("could not grab mouse pointer");
1030 WMSetLabelText(panel
->specLbl
, _("Click in the window you wish to inspect."));
1031 WMMaskEvent(dpy
, ButtonPressMask
, &event
);
1032 XUngrabPointer(dpy
, CurrentTime
);
1034 iwin
= wWindowFor(event
.xbutton
.subwindow
);
1035 if (iwin
&& !iwin
->flags
.internal_window
&& iwin
!= wwin
&& !iwin
->flags
.inspector_open
) {
1036 iwin
->flags
.inspector_open
= 1;
1037 iwin
->inspector
= createInspectorForWindow(iwin
,
1038 panel
->frame
->frame_x
, panel
->frame
->frame_y
, True
);
1039 wCloseInspectorForWindow(wwin
);
1041 WMSetLabelText(panel
->specLbl
, spec_text
);
1045 static InspectorPanel
*createInspectorForWindow(WWindow
*wwin
, int xpos
, int ypos
, Bool showSelectPanel
)
1047 WScreen
*scr
= wwin
->screen_ptr
;
1048 InspectorPanel
*panel
;
1050 char *str
= NULL
, *tmp
= NULL
;
1051 int x
, y
, btn_width
, frame_width
;
1052 WMButton
*selectedBtn
= NULL
;
1054 spec_text
= _("The configuration will apply to all\n"
1055 "windows that have their WM_CLASS\n"
1056 "property set to the above selected\n" "name, when saved.");
1058 panel
= wmalloc(sizeof(InspectorPanel
));
1059 memset(panel
, 0, sizeof(InspectorPanel
));
1061 panel
->destroyed
= 0;
1062 panel
->inspected
= wwin
;
1063 panel
->nextPtr
= panelList
;
1065 panel
->win
= WMCreateWindow(scr
->wmscreen
, "windowInspector");
1066 WMResizeWidget(panel
->win
, PWIDTH
, PHEIGHT
);
1068 /**** create common stuff ****/
1069 /* command buttons */
1070 btn_width
= (PWIDTH
- (2 * 15) - (2 * 10)) / 3;
1071 panel
->saveBtn
= WMCreateCommandButton(panel
->win
);
1072 WMSetButtonAction(panel
->saveBtn
, saveSettings
, panel
);
1073 WMMoveWidget(panel
->saveBtn
, (2 * (btn_width
+ 10)) + 15, PHEIGHT
- 40);
1074 WMSetButtonText(panel
->saveBtn
, _("Save"));
1075 WMResizeWidget(panel
->saveBtn
, btn_width
, 28);
1076 if (wPreferences
.flags
.noupdates
|| !(wwin
->wm_class
|| wwin
->wm_instance
))
1077 WMSetButtonEnabled(panel
->saveBtn
, False
);
1079 panel
->applyBtn
= WMCreateCommandButton(panel
->win
);
1080 WMSetButtonAction(panel
->applyBtn
, applySettings
, panel
);
1081 WMMoveWidget(panel
->applyBtn
, btn_width
+ 10 + 15, PHEIGHT
- 40);
1082 WMSetButtonText(panel
->applyBtn
, _("Apply"));
1083 WMResizeWidget(panel
->applyBtn
, btn_width
, 28);
1085 panel
->revertBtn
= WMCreateCommandButton(panel
->win
);
1086 WMSetButtonAction(panel
->revertBtn
, revertSettings
, panel
);
1087 WMMoveWidget(panel
->revertBtn
, 15, PHEIGHT
- 40);
1088 WMSetButtonText(panel
->revertBtn
, _("Reload"));
1089 WMResizeWidget(panel
->revertBtn
, btn_width
, 28);
1091 /* page selection popup button */
1092 panel
->pagePopUp
= WMCreatePopUpButton(panel
->win
);
1093 WMSetPopUpButtonAction(panel
->pagePopUp
, changePage
, panel
);
1094 WMMoveWidget(panel
->pagePopUp
, 25, 15);
1095 WMResizeWidget(panel
->pagePopUp
, PWIDTH
- 50, 20);
1097 WMAddPopUpButtonItem(panel
->pagePopUp
, _("Window Specification"));
1098 WMAddPopUpButtonItem(panel
->pagePopUp
, _("Window Attributes"));
1099 WMAddPopUpButtonItem(panel
->pagePopUp
, _("Advanced Options"));
1100 WMAddPopUpButtonItem(panel
->pagePopUp
, _("Icon and Initial Workspace"));
1101 WMAddPopUpButtonItem(panel
->pagePopUp
, _("Application Specific"));
1103 /**** window spec ****/
1104 frame_width
= PWIDTH
- (2 * 15);
1106 panel
->specFrm
= WMCreateFrame(panel
->win
);
1107 WMSetFrameTitle(panel
->specFrm
, _("Window Specification"));
1108 WMMoveWidget(panel
->specFrm
, 15, 65);
1109 WMResizeWidget(panel
->specFrm
, frame_width
, 145);
1111 panel
->defaultRb
= WMCreateRadioButton(panel
->specFrm
);
1112 WMMoveWidget(panel
->defaultRb
, 10, 78);
1113 WMResizeWidget(panel
->defaultRb
, frame_width
- (2 * 10), 20);
1114 WMSetButtonText(panel
->defaultRb
, _("Defaults for all windows"));
1115 WMSetButtonSelected(panel
->defaultRb
, False
);
1116 WMSetButtonAction(panel
->defaultRb
, selectSpecification
, panel
);
1118 if (wwin
->wm_class
&& wwin
->wm_instance
) {
1119 tmp
= wstrconcat(wwin
->wm_instance
, ".");
1120 str
= wstrconcat(tmp
, wwin
->wm_class
);
1122 panel
->bothRb
= WMCreateRadioButton(panel
->specFrm
);
1123 WMMoveWidget(panel
->bothRb
, 10, 18);
1124 WMResizeWidget(panel
->bothRb
, frame_width
- (2 * 10), 20);
1125 WMSetButtonText(panel
->bothRb
, str
);
1128 WMGroupButtons(panel
->defaultRb
, panel
->bothRb
);
1131 selectedBtn
= panel
->bothRb
;
1133 WMSetButtonAction(panel
->bothRb
, selectSpecification
, panel
);
1136 if (wwin
->wm_instance
) {
1137 panel
->instRb
= WMCreateRadioButton(panel
->specFrm
);
1138 WMMoveWidget(panel
->instRb
, 10, 38);
1139 WMResizeWidget(panel
->instRb
, frame_width
- (2 * 10), 20);
1140 WMSetButtonText(panel
->instRb
, wwin
->wm_instance
);
1141 WMGroupButtons(panel
->defaultRb
, panel
->instRb
);
1144 selectedBtn
= panel
->instRb
;
1146 WMSetButtonAction(panel
->instRb
, selectSpecification
, panel
);
1149 if (wwin
->wm_class
) {
1150 panel
->clsRb
= WMCreateRadioButton(panel
->specFrm
);
1151 WMMoveWidget(panel
->clsRb
, 10, 58);
1152 WMResizeWidget(panel
->clsRb
, frame_width
- (2 * 10), 20);
1153 WMSetButtonText(panel
->clsRb
, wwin
->wm_class
);
1154 WMGroupButtons(panel
->defaultRb
, panel
->clsRb
);
1157 selectedBtn
= panel
->clsRb
;
1159 WMSetButtonAction(panel
->clsRb
, selectSpecification
, panel
);
1162 panel
->selWinB
= WMCreateCommandButton(panel
->specFrm
);
1163 WMMoveWidget(panel
->selWinB
, 20, 145 - 24 - 10);
1164 WMResizeWidget(panel
->selWinB
, frame_width
- 2 * 10 - 20, 24);
1165 WMSetButtonText(panel
->selWinB
, _("Select window"));
1166 WMSetButtonAction(panel
->selWinB
, selectWindow
, panel
);
1168 panel
->specLbl
= WMCreateLabel(panel
->win
);
1169 WMMoveWidget(panel
->specLbl
, 15, 210);
1170 WMResizeWidget(panel
->specLbl
, frame_width
, 100);
1171 WMSetLabelText(panel
->specLbl
, spec_text
);
1172 WMSetLabelWraps(panel
->specLbl
, True
);
1174 WMSetLabelTextAlignment(panel
->specLbl
, WALeft
);
1176 /**** attributes ****/
1177 create_tab_window_attributes(wwin
, panel
, frame_width
);
1178 create_tab_window_advanced(wwin
, panel
, frame_width
);
1179 create_tab_icon_workspace(wwin
, panel
);
1180 create_tab_app_specific(wwin
, panel
, frame_width
);
1182 /* if the window is a transient, don't let it have a miniaturize button */
1183 if (wwin
->transient_for
!= None
&& wwin
->transient_for
!= scr
->root_win
)
1184 WMSetButtonEnabled(panel
->attrChk
[3], False
);
1186 WMSetButtonEnabled(panel
->attrChk
[3], True
);
1188 if (!wwin
->wm_class
&& !wwin
->wm_instance
)
1189 WMSetPopUpButtonItemEnabled(panel
->pagePopUp
, 0, False
);
1191 WMRealizeWidget(panel
->win
);
1193 WMMapSubwidgets(panel
->win
);
1194 WMMapSubwidgets(panel
->specFrm
);
1195 WMMapSubwidgets(panel
->attrFrm
);
1196 WMMapSubwidgets(panel
->moreFrm
);
1197 WMMapSubwidgets(panel
->iconFrm
);
1198 WMMapSubwidgets(panel
->wsFrm
);
1200 WMMapSubwidgets(panel
->appFrm
);
1202 if (showSelectPanel
) {
1203 WMSetPopUpButtonSelectedItem(panel
->pagePopUp
, 0);
1204 changePage(panel
->pagePopUp
, panel
);
1206 WMSetPopUpButtonSelectedItem(panel
->pagePopUp
, 1);
1207 changePage(panel
->pagePopUp
, panel
);
1210 parent
= XCreateSimpleWindow(dpy
, scr
->root_win
, 0, 0, PWIDTH
, PHEIGHT
, 0, 0, 0);
1211 XSelectInput(dpy
, parent
, KeyPressMask
| KeyReleaseMask
);
1212 panel
->parent
= parent
;
1213 XReparentWindow(dpy
, WMWidgetXID(panel
->win
), parent
, 0, 0);
1215 WMMapWidget(panel
->win
);
1217 XSetTransientForHint(dpy
, parent
, wwin
->client_win
);
1219 if (xpos
== UNDEFINED_POS
) {
1220 x
= wwin
->frame_x
+ wwin
->frame
->core
->width
/ 2;
1221 y
= wwin
->frame_y
+ wwin
->frame
->top_width
* 2;
1222 if (y
+ PHEIGHT
> scr
->scr_height
)
1223 y
= scr
->scr_height
- PHEIGHT
- 30;
1224 if (x
+ PWIDTH
> scr
->scr_width
)
1225 x
= scr
->scr_width
- PWIDTH
;
1231 panel
->frame
= wManageInternalWindow(scr
, parent
, wwin
->client_win
, "Inspector", x
, y
, PWIDTH
, PHEIGHT
);
1234 selectedBtn
= panel
->defaultRb
;
1236 WMSetButtonSelected(selectedBtn
, True
);
1237 selectSpecification(selectedBtn
, panel
);
1239 /* kluge to know who should get the key events */
1240 panel
->frame
->client_leader
= WMWidgetXID(panel
->win
);
1242 WSETUFLAG(panel
->frame
, no_closable
, 0);
1243 WSETUFLAG(panel
->frame
, no_close_button
, 0);
1244 wWindowUpdateButtonImages(panel
->frame
);
1245 wFrameWindowShowButton(panel
->frame
->frame
, WFF_RIGHT_BUTTON
);
1246 panel
->frame
->frame
->on_click_right
= destroyInspector
;
1248 wWindowMap(panel
->frame
);
1250 showIconFor(WMWidgetScreen(panel
->alwChk
), panel
, wwin
->wm_instance
, wwin
->wm_class
, UPDATE_TEXT_FIELD
);
1255 void wShowInspectorForWindow(WWindow
*wwin
)
1257 if (wwin
->flags
.inspector_open
)
1260 WMSetBalloonEnabled(wwin
->screen_ptr
->wmscreen
, wPreferences
.help_balloon
);
1263 wwin
->flags
.inspector_open
= 1;
1264 wwin
->inspector
= createInspectorForWindow(wwin
, UNDEFINED_POS
, UNDEFINED_POS
, False
);
1267 void wHideInspectorForWindow(WWindow
*wwin
)
1269 WWindow
*pwin
= wwin
->inspector
->frame
;
1272 pwin
->flags
.hidden
= 1;
1274 wClientSetState(pwin
, IconicState
, None
);
1277 void wUnhideInspectorForWindow(WWindow
*wwin
)
1279 WWindow
*pwin
= wwin
->inspector
->frame
;
1281 pwin
->flags
.hidden
= 0;
1282 pwin
->flags
.mapped
= 1;
1283 XMapWindow(dpy
, pwin
->client_win
);
1284 XMapWindow(dpy
, pwin
->frame
->core
->window
);
1285 wClientSetState(pwin
, NormalState
, None
);
1288 WWindow
*wGetWindowOfInspectorForWindow(WWindow
*wwin
)
1290 if (!wwin
->inspector
)
1293 assert(wwin
->flags
.inspector_open
!= 0);
1294 return wwin
->inspector
->frame
;
1297 void wCloseInspectorForWindow(WWindow
*wwin
)
1299 WWindow
*pwin
= wwin
->inspector
->frame
; /* the inspector window */
1301 (*pwin
->frame
->on_click_right
) (NULL
, pwin
, NULL
);
1304 static void create_tab_window_attributes(WWindow
*wwin
, InspectorPanel
*panel
, int frame_width
)
1307 char *caption
= NULL
, *descr
= NULL
;
1310 panel
->attrFrm
= WMCreateFrame(panel
->win
);
1311 WMSetFrameTitle(panel
->attrFrm
, _("Attributes"));
1312 WMMoveWidget(panel
->attrFrm
, 15, 45);
1313 WMResizeWidget(panel
->attrFrm
, frame_width
, 250);
1315 for (i
= 0; i
< wlengthof(panel
->attrChk
); i
++) {
1318 caption
= _("Disable titlebar");
1319 flag
= WFLAGP(wwin
, no_titlebar
);
1320 descr
= _("Remove the titlebar of this window.\n"
1321 "To access the window commands menu of a window\n"
1322 "without it's titlebar, press Control+Esc (or the\n"
1323 "equivalent shortcut, if you changed the default\n" "settings).");
1326 caption
= _("Disable resizebar");
1327 flag
= WFLAGP(wwin
, no_resizebar
);
1328 descr
= _("Remove the resizebar of this window.");
1331 caption
= _("Disable close button");
1332 flag
= WFLAGP(wwin
, no_close_button
);
1333 descr
= _("Remove the `close window' button of this window.");
1336 caption
= _("Disable miniaturize button");
1337 flag
= WFLAGP(wwin
, no_miniaturize_button
);
1338 descr
= _("Remove the `miniaturize window' button of the window.");
1341 caption
= _("Disable border");
1342 flag
= WFLAGP(wwin
, no_border
);
1343 descr
= _("Remove the 1 pixel black border around the window.");
1346 caption
= _("Keep on top (floating)");
1347 flag
= WFLAGP(wwin
, floating
);
1348 descr
= _("Keep the window over other windows, not allowing\n" "them to cover it.");
1351 caption
= _("Keep at bottom (sunken)");
1352 flag
= WFLAGP(wwin
, sunken
);
1353 descr
= _("Keep the window under all other windows.");
1356 caption
= _("Omnipresent");
1357 flag
= WFLAGP(wwin
, omnipresent
);
1358 descr
= _("Make window present in all workspaces.");
1361 caption
= _("Start miniaturized");
1362 flag
= WFLAGP(wwin
, start_miniaturized
);
1363 descr
= _("Make the window be automatically miniaturized when it's\n" "first shown.");
1366 caption
= _("Start maximized");
1367 flag
= WFLAGP(wwin
, start_maximized
!= 0);
1368 descr
= _("Make the window be automatically maximized when it's\n" "first shown.");
1371 caption
= _("Full screen maximization");
1372 flag
= WFLAGP(wwin
, full_maximize
);
1373 descr
= _("Make the window use the whole screen space when it's\n"
1374 "maximized. The titlebar and resizebar will be moved\n"
1375 "to outside the screen.");
1378 panel
->attrChk
[i
] = WMCreateSwitchButton(panel
->attrFrm
);
1379 WMMoveWidget(panel
->attrChk
[i
], 10, 20 * (i
+ 1));
1380 WMResizeWidget(panel
->attrChk
[i
], frame_width
- 15, 20);
1381 WMSetButtonSelected(panel
->attrChk
[i
], flag
);
1382 WMSetButtonText(panel
->attrChk
[i
], caption
);
1384 WMSetBalloonTextForView(descr
, WMWidgetView(panel
->attrChk
[i
]));
1388 static void create_tab_window_advanced(WWindow
*wwin
, InspectorPanel
*panel
, int frame_width
)
1391 char *caption
= NULL
, *descr
= NULL
;
1394 panel
->moreFrm
= WMCreateFrame(panel
->win
);
1395 WMSetFrameTitle(panel
->moreFrm
, _("Advanced"));
1396 WMMoveWidget(panel
->moreFrm
, 15, 45);
1397 WMResizeWidget(panel
->moreFrm
, frame_width
, 265);
1399 for (i
= 0; i
< wlengthof(panel
->moreChk
); i
++) {
1402 caption
= _("Do not bind keyboard shortcuts");
1403 flag
= WFLAGP(wwin
, no_bind_keys
);
1404 descr
= _("Do not bind keyboard shortcuts from Window Maker\n"
1405 "when this window is focused. This will allow the\n"
1406 "window to receive all key combinations regardless\n"
1407 "of your shortcut configuration.");
1410 caption
= _("Do not bind mouse clicks");
1411 flag
= WFLAGP(wwin
, no_bind_mouse
);
1412 descr
= _("Do not bind mouse actions, such as `Alt'+drag\n"
1413 "in the window (when alt is the modifier you have\n" "configured).");
1416 caption
= _("Do not show in the window list");
1417 flag
= WFLAGP(wwin
, skip_window_list
);
1418 descr
= _("Do not list the window in the window list menu.");
1421 caption
= _("Do not show in the switch panel");
1422 flag
= WFLAGP(wwin
, skip_switchpanel
);
1423 descr
= _("Do not include in switch panel while cycling windows.");
1426 caption
= _("Do not let it take focus");
1427 flag
= WFLAGP(wwin
, no_focusable
);
1428 descr
= _("Do not let the window take keyboard focus when you\n" "click on it.");
1431 caption
= _("Keep inside screen");
1432 flag
= WFLAGP(wwin
, dont_move_off
);
1433 descr
= _("Do not allow the window to move itself completely\n"
1434 "outside the screen. For bug compatibility.\n");
1437 caption
= _("Ignore 'Hide Others'");
1438 flag
= WFLAGP(wwin
, no_hide_others
);
1439 descr
= _("Do not hide the window when issuing the\n" "`HideOthers' command.");
1442 caption
= _("Ignore 'Save Session'");
1443 flag
= WFLAGP(wwin
, dont_save_session
);
1444 descr
= _("Do not save the associated application in the\n"
1445 "session's state, so that it won't be restarted\n"
1446 "together with other applications when Window Maker\n" "starts.");
1449 caption
= _("Emulate application icon");
1450 flag
= WFLAGP(wwin
, emulate_appicon
);
1451 descr
= _("Make this window act as an application that provides\n"
1452 "enough information to Window Maker for a dockable\n"
1453 "application icon to be created.");
1456 caption
= _("Focus across workspaces");
1457 flag
= WFLAGP(wwin
, focus_across_wksp
);
1458 descr
= _("Allow Window Maker to switch workspace to satisfy\n"
1459 "a focus request (annoying).");
1462 caption
= _("Do not let it be minimized");
1463 flag
= WFLAGP(wwin
, no_miniaturizable
);
1464 descr
= _("Do not let the window of this application be\n"
1467 #ifdef XKB_BUTTON_HINT
1469 caption
= _("Disable language button");
1470 flag
= WFLAGP(wwin
, no_language_button
);
1471 descr
= _("Remove the `toggle language' button of the window.");
1475 panel
->moreChk
[i
] = WMCreateSwitchButton(panel
->moreFrm
);
1476 WMMoveWidget(panel
->moreChk
[i
], 10, 20 * (i
+ 1));
1477 WMResizeWidget(panel
->moreChk
[i
], frame_width
- 15, 20);
1478 WMSetButtonSelected(panel
->moreChk
[i
], flag
);
1479 WMSetButtonText(panel
->moreChk
[i
], caption
);
1481 WMSetBalloonTextForView(descr
, WMWidgetView(panel
->moreChk
[i
]));
1485 static void create_tab_icon_workspace(WWindow
*wwin
, InspectorPanel
*panel
)
1489 /* miniwindow/workspace */
1490 panel
->iconFrm
= WMCreateFrame(panel
->win
);
1491 WMMoveWidget(panel
->iconFrm
, 15, 50);
1492 WMResizeWidget(panel
->iconFrm
, PWIDTH
- (2 * 15), 170);
1493 WMSetFrameTitle(panel
->iconFrm
, _("Miniwindow Image"));
1495 panel
->iconLbl
= WMCreateLabel(panel
->iconFrm
);
1496 WMMoveWidget(panel
->iconLbl
, PWIDTH
- (2 * 15) - 22 - 64, 20);
1497 WMResizeWidget(panel
->iconLbl
, 64, 64);
1498 WMSetLabelRelief(panel
->iconLbl
, WRGroove
);
1499 WMSetLabelImagePosition(panel
->iconLbl
, WIPImageOnly
);
1501 panel
->browseIconBtn
= WMCreateCommandButton(panel
->iconFrm
);
1502 WMSetButtonAction(panel
->browseIconBtn
, chooseIconCallback
, panel
);
1503 WMMoveWidget(panel
->browseIconBtn
, 22, 32);
1504 WMResizeWidget(panel
->browseIconBtn
, 120, 26);
1505 WMSetButtonText(panel
->browseIconBtn
, _("Browse..."));
1507 panel
->fileLbl
= WMCreateLabel(panel
->iconFrm
);
1508 WMMoveWidget(panel
->fileLbl
, 20, 85);
1509 WMResizeWidget(panel
->fileLbl
, PWIDTH
- (2 * 15) - (2 * 20), 14);
1510 WMSetLabelText(panel
->fileLbl
, _("Icon filename:"));
1512 panel
->fileText
= WMCreateTextField(panel
->iconFrm
);
1513 WMMoveWidget(panel
->fileText
, 20, 105);
1514 WMResizeWidget(panel
->fileText
, PWIDTH
- (2 * 20) - (2 * 15), 20);
1515 WMSetTextFieldText(panel
->fileText
, NULL
);
1516 WMAddNotificationObserver(textEditedObserver
, panel
, WMTextDidEndEditingNotification
, panel
->fileText
);
1518 panel
->alwChk
= WMCreateSwitchButton(panel
->iconFrm
);
1519 WMMoveWidget(panel
->alwChk
, 20, 130);
1520 WMResizeWidget(panel
->alwChk
, PWIDTH
- (2 * 15) - (2 * 15), 30);
1521 WMSetButtonText(panel
->alwChk
, _("Ignore client supplied icon"));
1522 WMSetButtonSelected(panel
->alwChk
, WFLAGP(wwin
, always_user_icon
));
1524 panel
->wsFrm
= WMCreateFrame(panel
->win
);
1525 WMMoveWidget(panel
->wsFrm
, 15, 225);
1526 WMResizeWidget(panel
->wsFrm
, PWIDTH
- (2 * 15), 70);
1527 WMSetFrameTitle(panel
->wsFrm
, _("Initial Workspace"));
1529 WMSetBalloonTextForView(_("The workspace to place the window when it's"
1530 "first shown."), WMWidgetView(panel
->wsFrm
));
1532 panel
->wsP
= WMCreatePopUpButton(panel
->wsFrm
);
1533 WMMoveWidget(panel
->wsP
, 20, 30);
1534 WMResizeWidget(panel
->wsP
, PWIDTH
- (2 * 15) - (2 * 20), 20);
1535 WMAddPopUpButtonItem(panel
->wsP
, _("Nowhere in particular"));
1537 for (i
= 0; i
< w_global
.workspace
.count
; i
++)
1538 WMAddPopUpButtonItem(panel
->wsP
, w_global
.workspace
.array
[i
]->name
);
1540 i
= wDefaultGetStartWorkspace(wwin
->wm_instance
, wwin
->wm_class
);
1541 if (i
>= 0 && i
<= w_global
.workspace
.count
)
1542 WMSetPopUpButtonSelectedItem(panel
->wsP
, i
+ 1);
1544 WMSetPopUpButtonSelectedItem(panel
->wsP
, 0);
1547 static void create_tab_app_specific(WWindow
*wwin
, InspectorPanel
*panel
, int frame_width
)
1549 WScreen
*scr
= wwin
->screen_ptr
;
1550 int i
= 0, flag
= 0, tmp
;
1551 char *caption
= NULL
, *descr
= NULL
;
1554 if (wwin
->main_window
!= None
) {
1555 WApplication
*wapp
= wApplicationOf(wwin
->main_window
);
1557 panel
->appFrm
= WMCreateFrame(panel
->win
);
1558 WMSetFrameTitle(panel
->appFrm
, _("Application Attributes"));
1559 WMMoveWidget(panel
->appFrm
, 15, 50);
1560 WMResizeWidget(panel
->appFrm
, frame_width
, 240);
1562 for (i
= 0; i
< wlengthof(panel
->appChk
); i
++) {
1565 caption
= _("Start hidden");
1566 flag
= WFLAGP(wapp
->main_window_desc
, start_hidden
);
1567 descr
= _("Automatically hide application when it's started.");
1570 caption
= _("No application icon");
1571 flag
= WFLAGP(wapp
->main_window_desc
, no_appicon
);
1572 descr
= _("Disable the application icon for the application.\n"
1573 "Note that you won't be able to dock it anymore,\n"
1574 "and any icons that are already docked will stop\n"
1575 "working correctly.");
1578 caption
= _("Shared application icon");
1579 flag
= WFLAGP(wapp
->main_window_desc
, shared_appicon
);
1580 descr
= _("Use a single shared application icon for all of\n"
1581 "the instances of this application.\n");
1584 panel
->appChk
[i
] = WMCreateSwitchButton(panel
->appFrm
);
1585 WMMoveWidget(panel
->appChk
[i
], 10, 20 * (i
+ 1));
1586 WMResizeWidget(panel
->appChk
[i
], 205, 20);
1587 WMSetButtonSelected(panel
->appChk
[i
], flag
);
1588 WMSetButtonText(panel
->appChk
[i
], caption
);
1589 WMSetBalloonTextForView(descr
, WMWidgetView(panel
->appChk
[i
]));
1592 if (WFLAGP(wwin
, emulate_appicon
)) {
1593 WMSetButtonEnabled(panel
->appChk
[1], False
);
1594 WMSetButtonEnabled(panel
->moreChk
[7], True
);
1596 WMSetButtonEnabled(panel
->appChk
[1], True
);
1597 WMSetButtonEnabled(panel
->moreChk
[7], False
);
1600 if ((wwin
->transient_for
!= None
&& wwin
->transient_for
!= scr
->root_win
)
1601 || !wwin
->wm_class
|| !wwin
->wm_instance
)
1606 WMSetButtonEnabled(panel
->moreChk
[7], tmp
);
1608 WMSetPopUpButtonItemEnabled(panel
->pagePopUp
, 4, False
);
1609 panel
->appFrm
= NULL
;