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