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 WDDomain
*WDWindowAttributes
;
119 static InspectorPanel
*panelList
= NULL
;
120 static WMPropList
*ANoTitlebar
= NULL
;
121 static WMPropList
*ANoResizebar
;
122 static WMPropList
*ANoMiniaturizeButton
;
123 static WMPropList
*ANoCloseButton
;
124 static WMPropList
*ANoBorder
;
125 static WMPropList
*ANoHideOthers
;
126 static WMPropList
*ANoMouseBindings
;
127 static WMPropList
*ANoKeyBindings
;
128 static WMPropList
*ANoAppIcon
;
129 static WMPropList
*AKeepOnTop
;
130 static WMPropList
*AKeepOnBottom
;
131 static WMPropList
*AOmnipresent
;
132 static WMPropList
*ASkipWindowList
;
133 static WMPropList
*ASkipSwitchPanel
;
134 static WMPropList
*AKeepInsideScreen
;
135 static WMPropList
*AUnfocusable
;
136 static WMPropList
*AFocusAcrossWorkspace
;
137 static WMPropList
*AAlwaysUserIcon
;
138 static WMPropList
*AStartMiniaturized
;
139 static WMPropList
*AStartMaximized
;
140 static WMPropList
*ADontSaveSession
;
141 static WMPropList
*AEmulateAppIcon
;
142 static WMPropList
*AFullMaximize
;
143 static WMPropList
*ASharedAppIcon
;
144 static WMPropList
*ANoMiniaturizable
;
145 #ifdef XKB_BUTTON_HINT
146 static WMPropList
*ANoLanguageButton
;
148 static WMPropList
*AStartWorkspace
;
149 static WMPropList
*AIcon
;
151 /* application wide options */
152 static WMPropList
*AStartHidden
;
153 static WMPropList
*AnyWindow
;
154 static WMPropList
*EmptyString
;
155 static WMPropList
*Yes
, *No
;
157 static char *spec_text
;
158 static void applySettings(WMButton
*button
, InspectorPanel
*panel
);
160 static InspectorPanel
*createInspectorForWindow(WWindow
*wwin
, int xpos
, int ypos
, Bool showSelectPanel
);
162 static void create_tab_window_attributes(WWindow
*wwin
, InspectorPanel
*panel
, int frame_width
);
163 static void create_tab_window_advanced(WWindow
*wwin
, InspectorPanel
*panel
, int frame_width
);
164 static void create_tab_icon_workspace(WWindow
*wwin
, InspectorPanel
*panel
, int frame_width
);
165 static void create_tab_app_specific(WWindow
*wwin
, InspectorPanel
*panel
, int frame_width
);
167 static void make_keys(void)
169 if (ANoTitlebar
!= NULL
)
172 AIcon
= WMCreatePLString("Icon");
173 ANoTitlebar
= WMCreatePLString("NoTitlebar");
174 ANoResizebar
= WMCreatePLString("NoResizebar");
175 ANoMiniaturizeButton
= WMCreatePLString("NoMiniaturizeButton");
176 ANoCloseButton
= WMCreatePLString("NoCloseButton");
177 ANoBorder
= WMCreatePLString("NoBorder");
178 ANoHideOthers
= WMCreatePLString("NoHideOthers");
179 ANoMouseBindings
= WMCreatePLString("NoMouseBindings");
180 ANoKeyBindings
= WMCreatePLString("NoKeyBindings");
181 ANoAppIcon
= WMCreatePLString("NoAppIcon");
182 AKeepOnTop
= WMCreatePLString("KeepOnTop");
183 AKeepOnBottom
= WMCreatePLString("KeepOnBottom");
184 AOmnipresent
= WMCreatePLString("Omnipresent");
185 ASkipWindowList
= WMCreatePLString("SkipWindowList");
186 ASkipSwitchPanel
= WMCreatePLString("SkipSwitchPanel");
187 AKeepInsideScreen
= WMCreatePLString("KeepInsideScreen");
188 AUnfocusable
= WMCreatePLString("Unfocusable");
189 AFocusAcrossWorkspace
= WMCreatePLString("FocusAcrossWorkspace");
190 AAlwaysUserIcon
= WMCreatePLString("AlwaysUserIcon");
191 AStartMiniaturized
= WMCreatePLString("StartMiniaturized");
192 AStartMaximized
= WMCreatePLString("StartMaximized");
193 AStartHidden
= WMCreatePLString("StartHidden");
194 ADontSaveSession
= WMCreatePLString("DontSaveSession");
195 AEmulateAppIcon
= WMCreatePLString("EmulateAppIcon");
196 AFullMaximize
= WMCreatePLString("FullMaximize");
197 ASharedAppIcon
= WMCreatePLString("SharedAppIcon");
198 ANoMiniaturizable
= WMCreatePLString("NoMiniaturizable");
199 #ifdef XKB_BUTTON_HINT
200 ANoLanguageButton
= WMCreatePLString("NoLanguageButton");
203 AStartWorkspace
= WMCreatePLString("StartWorkspace");
205 AnyWindow
= WMCreatePLString("*");
206 EmptyString
= WMCreatePLString("");
207 Yes
= WMCreatePLString("Yes");
208 No
= WMCreatePLString("No");
211 static void freeInspector(InspectorPanel
*panel
)
213 panel
->destroyed
= 1;
215 if (panel
->choosingIcon
)
218 WMDestroyWidget(panel
->win
);
219 XDestroyWindow(dpy
, panel
->parent
);
223 static void destroyInspector(WCoreWindow
*foo
, void *data
, XEvent
*event
)
225 InspectorPanel
*panel
, *tmp
;
228 while (panel
->frame
!= data
)
229 panel
= panel
->nextPtr
;
231 if (panelList
== panel
) {
232 panelList
= panel
->nextPtr
;
235 while (tmp
->nextPtr
!= panel
)
238 tmp
->nextPtr
= panel
->nextPtr
;
240 panel
->inspected
->flags
.inspector_open
= 0;
241 panel
->inspected
->inspector
= NULL
;
243 WMRemoveNotificationObserver(panel
);
245 wWindowUnmap(panel
->frame
);
246 wUnmanageWindow(panel
->frame
, True
, False
);
248 freeInspector(panel
);
251 void wDestroyInspectorPanels(void)
253 InspectorPanel
*panel
;
255 while (panelList
!= NULL
) {
257 panelList
= panelList
->nextPtr
;
258 wUnmanageWindow(panel
->frame
, False
, False
);
259 WMDestroyWidget(panel
->win
);
261 panel
->inspected
->flags
.inspector_open
= 0;
262 panel
->inspected
->inspector
= NULL
;
268 static void changePage(WMPopUpButton
*bPtr
, InspectorPanel
*panel
)
272 page
= WMGetPopUpButtonSelectedItem(bPtr
);
275 WMMapWidget(panel
->specFrm
);
276 WMMapWidget(panel
->specLbl
);
277 } else if (page
== 1) {
278 WMMapWidget(panel
->attrFrm
);
279 } else if (page
== 2) {
280 WMMapWidget(panel
->moreFrm
);
281 } else if (page
== 3) {
282 WMMapWidget(panel
->iconFrm
);
283 WMMapWidget(panel
->wsFrm
);
285 WMMapWidget(panel
->appFrm
);
289 WMUnmapWidget(panel
->specFrm
);
290 WMUnmapWidget(panel
->specLbl
);
293 WMUnmapWidget(panel
->attrFrm
);
295 WMUnmapWidget(panel
->moreFrm
);
297 WMUnmapWidget(panel
->iconFrm
);
298 WMUnmapWidget(panel
->wsFrm
);
300 if (page
!= 4 && panel
->appFrm
)
301 WMUnmapWidget(panel
->appFrm
);
304 static int showIconFor(WMScreen
*scrPtr
, InspectorPanel
*panel
, const char *wm_instance
, const char *wm_class
, int flags
)
306 WMPixmap
*pixmap
= (WMPixmap
*) NULL
;
307 char *file
= NULL
, *path
= NULL
, *db_icon
= NULL
;
309 if ((flags
& USE_TEXT_FIELD
) != 0) {
310 file
= WMGetTextFieldText(panel
->fileText
);
311 if (file
&& file
[0] == 0) {
316 /* Get the application icon, default NOT included */
317 db_icon
= wDefaultGetIconFile(wm_instance
, wm_class
, False
);
319 file
= wstrdup(db_icon
);
321 if (db_icon
!= NULL
&& (flags
& REVERT_TO_DEFAULT
) != 0) {
323 file
= wstrdup(db_icon
);
324 flags
|= UPDATE_TEXT_FIELD
;
327 if ((flags
& UPDATE_TEXT_FIELD
) != 0)
328 WMSetTextFieldText(panel
->fileText
, file
);
331 path
= FindImage(wPreferences
.icon_path
, file
);
335 int len
= strlen(file
) + 80;
338 snprintf(buf
, len
, _("Could not find icon \"%s\" specified for this window"), file
);
339 wMessageDialog(panel
->frame
->screen_ptr
, _("Error"), buf
, _("OK"), NULL
, NULL
);
345 pixmap
= WMCreatePixmapFromFile(scrPtr
, path
);
350 int len
= strlen(file
) + 80;
353 snprintf(buf
, len
, _("Could not open specified icon \"%s\":%s"),
354 file
, RMessageForError(RErrorCode
));
355 wMessageDialog(panel
->frame
->screen_ptr
, _("Error"), buf
, _("OK"), NULL
, NULL
);
363 WMSetLabelImage(panel
->iconLbl
, pixmap
);
365 WMReleasePixmap(pixmap
);
370 static int getBool(WMPropList
*value
)
374 if (!WMIsPLString(value
))
377 if (!(val
= WMGetFromPLString(value
)))
380 if ((val
[1] == '\0' &&
381 (val
[0] == 'y' || val
[0] == 'Y' || val
[0] == 'T' ||
382 val
[0] == 't' || val
[0] == '1')) ||
383 (strcasecmp(val
, "YES") == 0 || strcasecmp(val
, "TRUE") == 0)) {
385 } else if ((val
[1] == '\0' &&
386 (val
[0] == 'n' || val
[0] == 'N' || val
[0] == 'F' ||
387 val
[0] == 'f' || val
[0] == '0')) ||
388 (strcasecmp(val
, "NO") == 0 || strcasecmp(val
, "FALSE") == 0)) {
391 wwarning(_("can't convert \"%s\" to boolean"), val
);
396 /* Will insert the attribute = value; pair in window's list,
397 * if it's different from the defaults.
398 * Defaults means either defaults database, or attributes saved
399 * for the default window "*". This is to let one revert options that are
400 * global because they were saved for all windows ("*"). */
402 insertAttribute(WMPropList
*dict
, WMPropList
*window
, WMPropList
*attr
, WMPropList
*value
, int flags
)
404 WMPropList
*def_win
, *def_value
= NULL
;
405 int update
= 0, modified
= 0;
407 if (!(flags
& UPDATE_DEFAULTS
) && dict
) {
408 if ((def_win
= WMGetFromPLDictionary(dict
, AnyWindow
)) != NULL
)
409 def_value
= WMGetFromPLDictionary(def_win
, attr
);
412 /* If we could not find defaults in database, fall to hardcoded values.
413 * Also this is true if we save defaults for all windows */
415 def_value
= ((flags
& IS_BOOLEAN
) != 0) ? No
: EmptyString
;
417 if (flags
& IS_BOOLEAN
)
418 update
= (getBool(value
) != getBool(def_value
));
420 update
= !WMIsPropListEqualTo(value
, def_value
);
423 WMPutInPLDictionary(window
, attr
, value
);
430 static void saveSettings(WMButton
*button
, InspectorPanel
*panel
)
432 WWindow
*wwin
= panel
->inspected
;
433 WDDomain
*db
= WDWindowAttributes
;
434 WMPropList
*dict
= NULL
;
435 WMPropList
*winDic
, *appDic
, *value
, *value1
, *key
= NULL
, *key2
;
436 char *icon_file
, *buf1
, *buf2
;
437 int flags
= 0, i
= 0, different
= 0, different2
= 0;
439 /* Save will apply the changes and save them */
440 applySettings(panel
->applyBtn
, panel
);
442 if (WMGetButtonSelected(panel
->instRb
) != 0) {
443 key
= WMCreatePLString(wwin
->wm_instance
);
444 } else if (WMGetButtonSelected(panel
->clsRb
) != 0) {
445 key
= WMCreatePLString(wwin
->wm_class
);
446 } else if (WMGetButtonSelected(panel
->bothRb
) != 0) {
447 buf1
= StrConcatDot(wwin
->wm_instance
, wwin
->wm_class
);
448 key
= WMCreatePLString(buf1
);
450 } else if (WMGetButtonSelected(panel
->defaultRb
) != 0) {
451 key
= WMRetainPropList(AnyWindow
);
452 flags
= UPDATE_DEFAULTS
;
458 dict
= db
->dictionary
;
460 dict
= WMCreatePLDictionary(NULL
, NULL
);
462 db
->dictionary
= dict
;
464 WMReleasePropList(key
);
469 if (showIconFor(WMWidgetScreen(button
), panel
, NULL
, NULL
, USE_TEXT_FIELD
) < 0)
472 WMPLSetCaseSensitive(True
);
474 winDic
= WMCreatePLDictionary(NULL
, NULL
);
475 appDic
= WMCreatePLDictionary(NULL
, NULL
);
477 /* Save the icon info */
478 /* The flag "Ignore client suplied icon is not selected" */
480 snprintf(buf1
, 4, "%s", (WMGetButtonSelected(panel
->alwChk
) != 0) ? "Yes" : "No");
481 value1
= WMCreatePLString(buf1
);
482 different
|= insertAttribute(dict
, winDic
, AAlwaysUserIcon
, value1
, flags
);
483 WMReleasePropList(value1
);
486 /* The icon filename (if exists) */
487 icon_file
= WMGetTextFieldText(panel
->fileText
);
488 if ((icon_file
) && (icon_file
[0] != 0)) {
489 value
= WMCreatePLString(icon_file
);
490 different
|= insertAttribute(dict
, winDic
, AIcon
, value
, flags
);
491 different2
|= insertAttribute(dict
, appDic
, AIcon
, value
, flags
);
492 WMReleasePropList(value
);
496 i
= WMGetPopUpButtonSelectedItem(panel
->wsP
) - 1;
497 if (i
>= 0 && i
< w_global
.workspace
.count
) {
498 value
= WMCreatePLString(panel
->frame
->screen_ptr
->workspaces
[i
]->name
);
499 different
|= insertAttribute(dict
, winDic
, AStartWorkspace
, value
, flags
);
500 WMReleasePropList(value
);
505 value
= (WMGetButtonSelected(panel
->attrChk
[0]) != 0) ? Yes
: No
;
506 different
|= insertAttribute(dict
, winDic
, ANoTitlebar
, value
, flags
);
508 value
= (WMGetButtonSelected(panel
->attrChk
[1]) != 0) ? Yes
: No
;
509 different
|= insertAttribute(dict
, winDic
, ANoResizebar
, value
, flags
);
511 value
= (WMGetButtonSelected(panel
->attrChk
[2]) != 0) ? Yes
: No
;
512 different
|= insertAttribute(dict
, winDic
, ANoCloseButton
, value
, flags
);
514 value
= (WMGetButtonSelected(panel
->attrChk
[3]) != 0) ? Yes
: No
;
515 different
|= insertAttribute(dict
, winDic
, ANoMiniaturizeButton
, value
, flags
);
517 value
= (WMGetButtonSelected(panel
->attrChk
[4]) != 0) ? Yes
: No
;
518 different
|= insertAttribute(dict
, winDic
, ANoBorder
, value
, flags
);
520 value
= (WMGetButtonSelected(panel
->attrChk
[5]) != 0) ? Yes
: No
;
521 different
|= insertAttribute(dict
, winDic
, AKeepOnTop
, value
, flags
);
523 value
= (WMGetButtonSelected(panel
->attrChk
[6]) != 0) ? Yes
: No
;
524 different
|= insertAttribute(dict
, winDic
, AKeepOnBottom
, value
, flags
);
526 value
= (WMGetButtonSelected(panel
->attrChk
[7]) != 0) ? Yes
: No
;
527 different
|= insertAttribute(dict
, winDic
, AOmnipresent
, value
, flags
);
529 value
= (WMGetButtonSelected(panel
->attrChk
[8]) != 0) ? Yes
: No
;
530 different
|= insertAttribute(dict
, winDic
, AStartMiniaturized
, value
, flags
);
532 value
= (WMGetButtonSelected(panel
->attrChk
[9]) != 0) ? Yes
: No
;
533 different
|= insertAttribute(dict
, winDic
, AStartMaximized
, value
, flags
);
535 value
= (WMGetButtonSelected(panel
->attrChk
[10]) != 0) ? Yes
: No
;
536 different
|= insertAttribute(dict
, winDic
, AFullMaximize
, value
, flags
);
538 value
= (WMGetButtonSelected(panel
->moreChk
[0]) != 0) ? Yes
: No
;
539 different
|= insertAttribute(dict
, winDic
, ANoKeyBindings
, value
, flags
);
541 value
= (WMGetButtonSelected(panel
->moreChk
[1]) != 0) ? Yes
: No
;
542 different
|= insertAttribute(dict
, winDic
, ANoMouseBindings
, value
, flags
);
544 value
= (WMGetButtonSelected(panel
->moreChk
[2]) != 0) ? Yes
: No
;
545 different
|= insertAttribute(dict
, winDic
, ASkipWindowList
, value
, flags
);
547 value
= (WMGetButtonSelected(panel
->moreChk
[3]) != 0) ? Yes
: No
;
548 different
|= insertAttribute(dict
, winDic
, ASkipSwitchPanel
, value
, flags
);
550 value
= (WMGetButtonSelected(panel
->moreChk
[4]) != 0) ? Yes
: No
;
551 different
|= insertAttribute(dict
, winDic
, AUnfocusable
, value
, flags
);
553 value
= (WMGetButtonSelected(panel
->moreChk
[5]) != 0) ? Yes
: No
;
554 different
|= insertAttribute(dict
, winDic
, AKeepInsideScreen
, value
, flags
);
556 value
= (WMGetButtonSelected(panel
->moreChk
[6]) != 0) ? Yes
: No
;
557 different
|= insertAttribute(dict
, winDic
, ANoHideOthers
, value
, flags
);
559 value
= (WMGetButtonSelected(panel
->moreChk
[7]) != 0) ? Yes
: No
;
560 different
|= insertAttribute(dict
, winDic
, ADontSaveSession
, value
, flags
);
562 value
= (WMGetButtonSelected(panel
->moreChk
[8]) != 0) ? Yes
: No
;
563 different
|= insertAttribute(dict
, winDic
, AEmulateAppIcon
, value
, flags
);
565 value
= (WMGetButtonSelected(panel
->moreChk
[9]) != 0) ? Yes
: No
;
566 different
|= insertAttribute(dict
, winDic
, AFocusAcrossWorkspace
, value
, flags
);
568 value
= (WMGetButtonSelected(panel
->moreChk
[10]) != 0) ? Yes
: No
;
569 different
|= insertAttribute(dict
, winDic
, ANoMiniaturizable
, value
, flags
);
571 #ifdef XKB_BUTTON_HINT
572 value
= (WMGetButtonSelected(panel
->moreChk
[11]) != 0) ? Yes
: No
;
573 different
|= insertAttribute(dict
, winDic
, ANoLanguageButton
, value
, flags
);
576 if (wwin
->main_window
!= None
&& wApplicationOf(wwin
->main_window
) != NULL
) {
577 value
= (WMGetButtonSelected(panel
->appChk
[0]) != 0) ? Yes
: No
;
578 different2
|= insertAttribute(dict
, appDic
, AStartHidden
, value
, flags
);
580 value
= (WMGetButtonSelected(panel
->appChk
[1]) != 0) ? Yes
: No
;
581 different2
|= insertAttribute(dict
, appDic
, ANoAppIcon
, value
, flags
);
583 value
= (WMGetButtonSelected(panel
->appChk
[2]) != 0) ? Yes
: No
;
584 different2
|= insertAttribute(dict
, appDic
, ASharedAppIcon
, value
, flags
);
587 if (wwin
->fake_group
) {
588 key2
= WMCreatePLString(wwin
->fake_group
->identifier
);
589 if (WMIsPropListEqualTo(key
, key2
)) {
590 WMMergePLDictionaries(winDic
, appDic
, True
);
591 different
|= different2
;
593 WMRemoveFromPLDictionary(dict
, key2
);
595 WMPutInPLDictionary(dict
, key2
, appDic
);
597 WMReleasePropList(key2
);
598 WMReleasePropList(appDic
);
599 } else if (wwin
->main_window
!= wwin
->client_win
) {
600 WApplication
*wapp
= wApplicationOf(wwin
->main_window
);
603 buf2
= StrConcatDot(wapp
->main_window_desc
->wm_instance
,
604 wapp
->main_window_desc
->wm_class
);
605 key2
= WMCreatePLString(buf2
);
608 if (WMIsPropListEqualTo(key
, key2
)) {
609 WMMergePLDictionaries(winDic
, appDic
, True
);
610 different
|= different2
;
612 WMRemoveFromPLDictionary(dict
, key2
);
614 WMPutInPLDictionary(dict
, key2
, appDic
);
616 WMReleasePropList(key2
);
617 WMReleasePropList(appDic
);
620 WMMergePLDictionaries(winDic
, appDic
, True
);
621 different
|= different2
;
622 WMReleasePropList(appDic
);
625 WMRemoveFromPLDictionary(dict
, key
);
627 WMPutInPLDictionary(dict
, key
, winDic
);
629 WMReleasePropList(key
);
630 WMReleasePropList(winDic
);
632 UpdateDomainFile(db
);
635 WMPLSetCaseSensitive(False
);
638 static void applySettings(WMButton
*button
, InspectorPanel
*panel
)
640 WWindow
*wwin
= panel
->inspected
;
641 WApplication
*wapp
= wApplicationOf(wwin
->main_window
);
642 int floating
, sunken
, skip_window_list
;
643 int old_omnipresent
, old_no_bind_keys
, old_no_bind_mouse
;
645 old_omnipresent
= WFLAGP(wwin
, omnipresent
);
646 old_no_bind_keys
= WFLAGP(wwin
, no_bind_keys
);
647 old_no_bind_mouse
= WFLAGP(wwin
, no_bind_mouse
);
649 showIconFor(WMWidgetScreen(button
), panel
, NULL
, NULL
, USE_TEXT_FIELD
);
651 /* Attributes... --> Window Attributes */
652 WSETUFLAG(wwin
, no_titlebar
, WMGetButtonSelected(panel
->attrChk
[0]));
653 WSETUFLAG(wwin
, no_resizebar
, WMGetButtonSelected(panel
->attrChk
[1]));
654 WSETUFLAG(wwin
, no_close_button
, WMGetButtonSelected(panel
->attrChk
[2]));
655 WSETUFLAG(wwin
, no_miniaturize_button
, WMGetButtonSelected(panel
->attrChk
[3]));
656 WSETUFLAG(wwin
, no_border
, WMGetButtonSelected(panel
->attrChk
[4]));
657 floating
= WMGetButtonSelected(panel
->attrChk
[5]);
658 sunken
= WMGetButtonSelected(panel
->attrChk
[6]);
659 WSETUFLAG(wwin
, omnipresent
, WMGetButtonSelected(panel
->attrChk
[7]));
660 WSETUFLAG(wwin
, start_miniaturized
, WMGetButtonSelected(panel
->attrChk
[8]));
661 WSETUFLAG(wwin
, start_maximized
, WMGetButtonSelected(panel
->attrChk
[9]));
662 WSETUFLAG(wwin
, full_maximize
, WMGetButtonSelected(panel
->attrChk
[10]));
664 /* Attributes... --> Advanced Options */
665 WSETUFLAG(wwin
, no_bind_keys
, WMGetButtonSelected(panel
->moreChk
[0]));
666 WSETUFLAG(wwin
, no_bind_mouse
, WMGetButtonSelected(panel
->moreChk
[1]));
667 skip_window_list
= WMGetButtonSelected(panel
->moreChk
[2]);
668 WSETUFLAG(wwin
, skip_switchpanel
, WMGetButtonSelected(panel
->moreChk
[3]));
669 WSETUFLAG(wwin
, no_focusable
, WMGetButtonSelected(panel
->moreChk
[4]));
670 WSETUFLAG(wwin
, dont_move_off
, WMGetButtonSelected(panel
->moreChk
[5]));
671 WSETUFLAG(wwin
, no_hide_others
, WMGetButtonSelected(panel
->moreChk
[6]));
672 WSETUFLAG(wwin
, dont_save_session
, WMGetButtonSelected(panel
->moreChk
[7]));
673 WSETUFLAG(wwin
, emulate_appicon
, WMGetButtonSelected(panel
->moreChk
[8]));
674 WSETUFLAG(wwin
, focus_across_wksp
, WMGetButtonSelected(panel
->moreChk
[9]));
675 WSETUFLAG(wwin
, no_miniaturizable
, WMGetButtonSelected(panel
->moreChk
[10]));
676 #ifdef XKB_BUTTON_HINT
677 WSETUFLAG(wwin
, no_language_button
, WMGetButtonSelected(panel
->moreChk
[11]));
679 WSETUFLAG(wwin
, always_user_icon
, WMGetButtonSelected(panel
->alwChk
));
681 if (WFLAGP(wwin
, no_titlebar
) && wwin
->flags
.shaded
)
682 wUnshadeWindow(wwin
);
684 WSETUFLAG(wwin
, no_shadeable
, WFLAGP(wwin
, no_titlebar
));
687 if (!WFLAGP(wwin
, floating
))
688 ChangeStackingLevel(wwin
->frame
->core
, WMFloatingLevel
);
690 if (!WFLAGP(wwin
, sunken
))
691 ChangeStackingLevel(wwin
->frame
->core
, WMSunkenLevel
);
693 if (WFLAGP(wwin
, floating
) || WFLAGP(wwin
, sunken
))
694 ChangeStackingLevel(wwin
->frame
->core
, WMNormalLevel
);
697 WSETUFLAG(wwin
, sunken
, sunken
);
698 WSETUFLAG(wwin
, floating
, floating
);
699 wwin
->flags
.omnipresent
= 0;
701 if (WFLAGP(wwin
, skip_window_list
) != skip_window_list
) {
702 WSETUFLAG(wwin
, skip_window_list
, skip_window_list
);
703 UpdateSwitchMenu(wwin
->screen_ptr
, wwin
, skip_window_list
? ACTION_REMOVE
: ACTION_ADD
);
705 if (WFLAGP(wwin
, omnipresent
) != old_omnipresent
)
706 WMPostNotificationName(WMNChangedState
, wwin
, "omnipresent");
709 if (WFLAGP(wwin
, no_bind_keys
) != old_no_bind_keys
) {
710 if (WFLAGP(wwin
, no_bind_keys
))
711 XUngrabKey(dpy
, AnyKey
, AnyModifier
, wwin
->frame
->core
->window
);
713 wWindowSetKeyGrabs(wwin
);
716 if (WFLAGP(wwin
, no_bind_mouse
) != old_no_bind_mouse
)
717 wWindowResetMouseGrabs(wwin
);
719 wwin
->frame
->flags
.need_texture_change
= 1;
720 wWindowConfigureBorders(wwin
);
721 wFrameWindowPaint(wwin
->frame
);
722 wNETWMUpdateActions(wwin
, False
);
724 /* Can't apply emulate_appicon because it will probably cause problems. */
726 /* do application wide stuff */
727 WSETUFLAG(wapp
->main_window_desc
, start_hidden
, WMGetButtonSelected(panel
->appChk
[0]));
728 WSETUFLAG(wapp
->main_window_desc
, no_appicon
, WMGetButtonSelected(panel
->appChk
[1]));
729 WSETUFLAG(wapp
->main_window_desc
, shared_appicon
, WMGetButtonSelected(panel
->appChk
[2]));
731 if (WFLAGP(wapp
->main_window_desc
, no_appicon
))
732 unpaint_app_icon(wapp
);
734 paint_app_icon(wapp
);
736 char *file
= WMGetTextFieldText(panel
->fileText
);
742 /* If always_user_icon flag is set, but the user icon is not set
743 * we use client supplied icon and we unset the flag */
744 if ((WFLAGP(wwin
, always_user_icon
) && (!file
))) {
745 /* Show the warning */
750 snprintf(buf
, len
, _("Ignore client supplied icon is set, but icon filename textbox is empty. Using client supplied icon"));
751 wMessageDialog(panel
->frame
->screen_ptr
, _("Warning"), buf
, _("OK"), NULL
, NULL
);
755 /* Change the flags */
756 WSETUFLAG(wwin
, always_user_icon
, 0);
757 WMSetButtonSelected(panel
->alwChk
, 0);
760 /* After test the always_user_icon flag value before,
761 * the "else" block is used only if the flag is set and
762 * the icon text box has an icon path */
763 if (!WFLAGP(wwin
, always_user_icon
)) {
764 /* Change App Icon image, using the icon provided by the client */
765 if (wapp
->app_icon
) {
766 RImage
*image
= get_rimage_icon_from_wm_hints(wapp
->app_icon
->icon
);
768 set_icon_image_from_image(wapp
->app_icon
->icon
, image
);
769 update_icon_pixmap(wapp
->app_icon
->icon
);
771 wIconUpdate(wapp
->app_icon
->icon
);
775 /* Change icon image if the app is minimized,
776 * using the icon provided by the client */
778 RImage
*image
= get_rimage_icon_from_wm_hints(wwin
->icon
);
780 set_icon_image_from_image(wwin
->icon
, image
);
781 update_icon_pixmap(wwin
->icon
);
783 wIconUpdate(wwin
->icon
);
787 /* Change App Icon image */
789 wIconChangeImageFile(wapp
->app_icon
->icon
, file
);
791 /* Change icon image if the app is minimized */
793 wIconChangeImageFile(wwin
->icon
, file
);
800 wNETFrameExtents(wwin
);
803 static void revertSettings(WMButton
*button
, InspectorPanel
*panel
)
805 WWindow
*wwin
= panel
->inspected
;
806 WApplication
*wapp
= wApplicationOf(wwin
->main_window
);
807 int i
, n
, workspace
, level
;
808 char *wm_instance
= NULL
, *wm_class
= NULL
;
810 if (panel
->instRb
&& WMGetButtonSelected(panel
->instRb
) != 0)
811 wm_instance
= wwin
->wm_instance
;
812 else if (panel
->clsRb
&& WMGetButtonSelected(panel
->clsRb
) != 0)
813 wm_class
= wwin
->wm_class
;
814 else if (panel
->bothRb
&& WMGetButtonSelected(panel
->bothRb
) != 0) {
815 wm_instance
= wwin
->wm_instance
;
816 wm_class
= wwin
->wm_class
;
819 memset(&wwin
->defined_user_flags
, 0, sizeof(WWindowAttributes
));
820 memset(&wwin
->user_flags
, 0, sizeof(WWindowAttributes
));
821 memset(&wwin
->client_flags
, 0, sizeof(WWindowAttributes
));
823 wWindowSetupInitialAttributes(wwin
, &level
, &workspace
);
825 for (i
= 0; i
< (sizeof(panel
->attrChk
) / sizeof(panel
->attrChk
[0])); i
++) {
830 flag
= WFLAGP(wwin
, no_titlebar
);
833 flag
= WFLAGP(wwin
, no_resizebar
);
836 flag
= WFLAGP(wwin
, no_close_button
);
839 flag
= WFLAGP(wwin
, no_miniaturize_button
);
842 flag
= WFLAGP(wwin
, no_border
);
845 flag
= WFLAGP(wwin
, floating
);
848 flag
= WFLAGP(wwin
, sunken
);
851 flag
= WFLAGP(wwin
, omnipresent
);
854 flag
= WFLAGP(wwin
, start_miniaturized
);
857 flag
= WFLAGP(wwin
, start_maximized
!= 0);
860 flag
= WFLAGP(wwin
, full_maximize
);
863 WMSetButtonSelected(panel
->attrChk
[i
], flag
);
866 for (i
= 0; i
< (sizeof(panel
->moreChk
) / sizeof(panel
->moreChk
[0])); i
++) {
871 flag
= WFLAGP(wwin
, no_bind_keys
);
874 flag
= WFLAGP(wwin
, no_bind_mouse
);
877 flag
= WFLAGP(wwin
, skip_window_list
);
880 flag
= WFLAGP(wwin
, skip_switchpanel
);
883 flag
= WFLAGP(wwin
, no_focusable
);
886 flag
= WFLAGP(wwin
, dont_move_off
);
889 flag
= WFLAGP(wwin
, no_hide_others
);
892 flag
= WFLAGP(wwin
, dont_save_session
);
895 flag
= WFLAGP(wwin
, emulate_appicon
);
898 flag
= WFLAGP(wwin
, focus_across_wksp
);
901 flag
= WFLAGP(wwin
, no_miniaturizable
);
903 #ifdef XKB_BUTTON_HINT
905 flag
= WFLAGP(wwin
, no_language_button
);
909 WMSetButtonSelected(panel
->moreChk
[i
], flag
);
911 if (panel
->appFrm
&& wapp
) {
912 for (i
= 0; i
< (sizeof(panel
->appChk
) / sizeof(panel
->appChk
[0])); i
++) {
917 flag
= WFLAGP(wapp
->main_window_desc
, start_hidden
);
920 flag
= WFLAGP(wapp
->main_window_desc
, no_appicon
);
923 flag
= WFLAGP(wapp
->main_window_desc
, shared_appicon
);
926 WMSetButtonSelected(panel
->appChk
[i
], flag
);
929 WMSetButtonSelected(panel
->alwChk
, WFLAGP(wwin
, always_user_icon
));
931 showIconFor(WMWidgetScreen(panel
->alwChk
), panel
, wm_instance
, wm_class
, REVERT_TO_DEFAULT
);
933 n
= wDefaultGetStartWorkspace(wwin
->screen_ptr
, wm_instance
, wm_class
);
935 if (n
>= 0 && n
< w_global
.workspace
.count
)
936 WMSetPopUpButtonSelectedItem(panel
->wsP
, n
+ 1);
938 WMSetPopUpButtonSelectedItem(panel
->wsP
, 0);
940 /* must auto apply, so that there wno't be internal
941 * inconsistencies between the state in the flags and
942 * the actual state of the window */
943 applySettings(panel
->applyBtn
, panel
);
946 static void chooseIconCallback(WMWidget
*self
, void *clientData
)
949 InspectorPanel
*panel
= (InspectorPanel
*) clientData
;
952 panel
->choosingIcon
= 1;
954 WMSetButtonEnabled(panel
->browseIconBtn
, False
);
956 result
= wIconChooserDialog(panel
->frame
->screen_ptr
, &file
,
957 panel
->inspected
->wm_instance
,
958 panel
->inspected
->wm_class
);
960 panel
->choosingIcon
= 0;
962 if (!panel
->destroyed
) { /* kluge */
964 WMSetTextFieldText(panel
->fileText
, file
);
965 showIconFor(WMWidgetScreen(self
), panel
, NULL
, NULL
, USE_TEXT_FIELD
);
968 WMSetButtonEnabled(panel
->browseIconBtn
, True
);
970 freeInspector(panel
);
974 static void textEditedObserver(void *observerData
, WMNotification
*notification
)
976 InspectorPanel
*panel
= (InspectorPanel
*) observerData
;
978 if ((long)WMGetNotificationClientData(notification
) != WMReturnTextMovement
)
981 showIconFor(WMWidgetScreen(panel
->win
), panel
, NULL
, NULL
, USE_TEXT_FIELD
);
984 static void selectSpecification(WMWidget
*bPtr
, void *data
)
986 InspectorPanel
*panel
= (InspectorPanel
*) data
;
988 WWindow
*wwin
= panel
->inspected
;
991 if (bPtr
== panel
->defaultRb
&& (wwin
->wm_instance
|| wwin
->wm_class
))
992 WMSetButtonEnabled(panel
->applyBtn
, False
);
994 WMSetButtonEnabled(panel
->applyBtn
, True
);
996 len
= 16 + strlen(wwin
->wm_instance
? wwin
->wm_instance
: "?")
997 + strlen(wwin
->wm_class
? wwin
->wm_class
: "?");
1001 snprintf(str
, len
, _("Inspecting %s.%s"),
1002 wwin
->wm_instance
? wwin
->wm_instance
: "?", wwin
->wm_class
? wwin
->wm_class
: "?");
1004 wFrameWindowChangeTitle(panel
->frame
->frame
, str
);
1009 static void selectWindow(WMWidget
*bPtr
, void *data
)
1011 InspectorPanel
*panel
= (InspectorPanel
*) data
;
1012 WWindow
*wwin
= panel
->inspected
;
1013 WScreen
*scr
= wwin
->screen_ptr
;
1017 if (XGrabPointer(dpy
, scr
->root_win
, True
,
1018 ButtonPressMask
, GrabModeAsync
, GrabModeAsync
, None
,
1019 wPreferences
.cursor
[WCUR_SELECT
], CurrentTime
) != GrabSuccess
) {
1020 wwarning("could not grab mouse pointer");
1024 WMSetLabelText(panel
->specLbl
, _("Click in the window you wish to inspect."));
1025 WMMaskEvent(dpy
, ButtonPressMask
, &event
);
1026 XUngrabPointer(dpy
, CurrentTime
);
1028 iwin
= wWindowFor(event
.xbutton
.subwindow
);
1029 if (iwin
&& !iwin
->flags
.internal_window
&& iwin
!= wwin
&& !iwin
->flags
.inspector_open
) {
1030 iwin
->flags
.inspector_open
= 1;
1031 iwin
->inspector
= createInspectorForWindow(iwin
,
1032 panel
->frame
->frame_x
, panel
->frame
->frame_y
, True
);
1033 wCloseInspectorForWindow(wwin
);
1035 WMSetLabelText(panel
->specLbl
, spec_text
);
1039 static InspectorPanel
*createInspectorForWindow(WWindow
*wwin
, int xpos
, int ypos
, Bool showSelectPanel
)
1041 WScreen
*scr
= wwin
->screen_ptr
;
1042 InspectorPanel
*panel
;
1044 char *str
= NULL
, *tmp
= NULL
;
1045 int x
, y
, btn_width
, frame_width
;
1046 WMButton
*selectedBtn
= NULL
;
1048 spec_text
= _("The configuration will apply to all\n"
1049 "windows that have their WM_CLASS\n"
1050 "property set to the above selected\n" "name, when saved.");
1052 panel
= wmalloc(sizeof(InspectorPanel
));
1053 memset(panel
, 0, sizeof(InspectorPanel
));
1055 panel
->destroyed
= 0;
1056 panel
->inspected
= wwin
;
1057 panel
->nextPtr
= panelList
;
1059 panel
->win
= WMCreateWindow(scr
->wmscreen
, "windowInspector");
1060 WMResizeWidget(panel
->win
, PWIDTH
, PHEIGHT
);
1062 /**** create common stuff ****/
1063 /* command buttons */
1064 btn_width
= (PWIDTH
- (2 * 15) - (2 * 10)) / 3;
1065 panel
->saveBtn
= WMCreateCommandButton(panel
->win
);
1066 WMSetButtonAction(panel
->saveBtn
, (WMAction
*) saveSettings
, panel
);
1067 WMMoveWidget(panel
->saveBtn
, (2 * (btn_width
+ 10)) + 15, PHEIGHT
- 40);
1068 WMSetButtonText(panel
->saveBtn
, _("Save"));
1069 WMResizeWidget(panel
->saveBtn
, btn_width
, 28);
1070 if (wPreferences
.flags
.noupdates
|| !(wwin
->wm_class
|| wwin
->wm_instance
))
1071 WMSetButtonEnabled(panel
->saveBtn
, False
);
1073 panel
->applyBtn
= WMCreateCommandButton(panel
->win
);
1074 WMSetButtonAction(panel
->applyBtn
, (WMAction
*) applySettings
, panel
);
1075 WMMoveWidget(panel
->applyBtn
, btn_width
+ 10 + 15, PHEIGHT
- 40);
1076 WMSetButtonText(panel
->applyBtn
, _("Apply"));
1077 WMResizeWidget(panel
->applyBtn
, btn_width
, 28);
1079 panel
->revertBtn
= WMCreateCommandButton(panel
->win
);
1080 WMSetButtonAction(panel
->revertBtn
, (WMAction
*) revertSettings
, panel
);
1081 WMMoveWidget(panel
->revertBtn
, 15, PHEIGHT
- 40);
1082 WMSetButtonText(panel
->revertBtn
, _("Reload"));
1083 WMResizeWidget(panel
->revertBtn
, btn_width
, 28);
1085 /* page selection popup button */
1086 panel
->pagePopUp
= WMCreatePopUpButton(panel
->win
);
1087 WMSetPopUpButtonAction(panel
->pagePopUp
, (WMAction
*) changePage
, panel
);
1088 WMMoveWidget(panel
->pagePopUp
, 25, 15);
1089 WMResizeWidget(panel
->pagePopUp
, PWIDTH
- 50, 20);
1091 WMAddPopUpButtonItem(panel
->pagePopUp
, _("Window Specification"));
1092 WMAddPopUpButtonItem(panel
->pagePopUp
, _("Window Attributes"));
1093 WMAddPopUpButtonItem(panel
->pagePopUp
, _("Advanced Options"));
1094 WMAddPopUpButtonItem(panel
->pagePopUp
, _("Icon and Initial Workspace"));
1095 WMAddPopUpButtonItem(panel
->pagePopUp
, _("Application Specific"));
1097 /**** window spec ****/
1098 frame_width
= PWIDTH
- (2 * 15);
1100 panel
->specFrm
= WMCreateFrame(panel
->win
);
1101 WMSetFrameTitle(panel
->specFrm
, _("Window Specification"));
1102 WMMoveWidget(panel
->specFrm
, 15, 65);
1103 WMResizeWidget(panel
->specFrm
, frame_width
, 145);
1105 panel
->defaultRb
= WMCreateRadioButton(panel
->specFrm
);
1106 WMMoveWidget(panel
->defaultRb
, 10, 78);
1107 WMResizeWidget(panel
->defaultRb
, frame_width
- (2 * 10), 20);
1108 WMSetButtonText(panel
->defaultRb
, _("Defaults for all windows"));
1109 WMSetButtonSelected(panel
->defaultRb
, False
);
1110 WMSetButtonAction(panel
->defaultRb
, selectSpecification
, panel
);
1112 if (wwin
->wm_class
&& wwin
->wm_instance
) {
1113 tmp
= wstrconcat(wwin
->wm_instance
, ".");
1114 str
= wstrconcat(tmp
, wwin
->wm_class
);
1116 panel
->bothRb
= WMCreateRadioButton(panel
->specFrm
);
1117 WMMoveWidget(panel
->bothRb
, 10, 18);
1118 WMResizeWidget(panel
->bothRb
, frame_width
- (2 * 10), 20);
1119 WMSetButtonText(panel
->bothRb
, str
);
1122 WMGroupButtons(panel
->defaultRb
, panel
->bothRb
);
1125 selectedBtn
= panel
->bothRb
;
1127 WMSetButtonAction(panel
->bothRb
, selectSpecification
, panel
);
1130 if (wwin
->wm_instance
) {
1131 panel
->instRb
= WMCreateRadioButton(panel
->specFrm
);
1132 WMMoveWidget(panel
->instRb
, 10, 38);
1133 WMResizeWidget(panel
->instRb
, frame_width
- (2 * 10), 20);
1134 WMSetButtonText(panel
->instRb
, wwin
->wm_instance
);
1135 WMGroupButtons(panel
->defaultRb
, panel
->instRb
);
1138 selectedBtn
= panel
->instRb
;
1140 WMSetButtonAction(panel
->instRb
, selectSpecification
, panel
);
1143 if (wwin
->wm_class
) {
1144 panel
->clsRb
= WMCreateRadioButton(panel
->specFrm
);
1145 WMMoveWidget(panel
->clsRb
, 10, 58);
1146 WMResizeWidget(panel
->clsRb
, frame_width
- (2 * 10), 20);
1147 WMSetButtonText(panel
->clsRb
, wwin
->wm_class
);
1148 WMGroupButtons(panel
->defaultRb
, panel
->clsRb
);
1151 selectedBtn
= panel
->clsRb
;
1153 WMSetButtonAction(panel
->clsRb
, selectSpecification
, panel
);
1156 panel
->selWinB
= WMCreateCommandButton(panel
->specFrm
);
1157 WMMoveWidget(panel
->selWinB
, 20, 145 - 24 - 10);
1158 WMResizeWidget(panel
->selWinB
, frame_width
- 2 * 10 - 20, 24);
1159 WMSetButtonText(panel
->selWinB
, _("Select window"));
1160 WMSetButtonAction(panel
->selWinB
, selectWindow
, panel
);
1162 panel
->specLbl
= WMCreateLabel(panel
->win
);
1163 WMMoveWidget(panel
->specLbl
, 15, 210);
1164 WMResizeWidget(panel
->specLbl
, frame_width
, 100);
1165 WMSetLabelText(panel
->specLbl
, spec_text
);
1166 WMSetLabelWraps(panel
->specLbl
, True
);
1168 WMSetLabelTextAlignment(panel
->specLbl
, WALeft
);
1170 /**** attributes ****/
1171 create_tab_window_attributes(wwin
, panel
, frame_width
);
1172 create_tab_window_advanced(wwin
, panel
, frame_width
);
1173 create_tab_icon_workspace(wwin
, panel
, frame_width
);
1174 create_tab_app_specific(wwin
, panel
, frame_width
);
1176 /* if the window is a transient, don't let it have a miniaturize button */
1177 if (wwin
->transient_for
!= None
&& wwin
->transient_for
!= scr
->root_win
)
1178 WMSetButtonEnabled(panel
->attrChk
[3], False
);
1180 WMSetButtonEnabled(panel
->attrChk
[3], True
);
1182 if (!wwin
->wm_class
&& !wwin
->wm_instance
)
1183 WMSetPopUpButtonItemEnabled(panel
->pagePopUp
, 0, False
);
1185 WMRealizeWidget(panel
->win
);
1187 WMMapSubwidgets(panel
->win
);
1188 WMMapSubwidgets(panel
->specFrm
);
1189 WMMapSubwidgets(panel
->attrFrm
);
1190 WMMapSubwidgets(panel
->moreFrm
);
1191 WMMapSubwidgets(panel
->iconFrm
);
1192 WMMapSubwidgets(panel
->wsFrm
);
1194 WMMapSubwidgets(panel
->appFrm
);
1196 if (showSelectPanel
) {
1197 WMSetPopUpButtonSelectedItem(panel
->pagePopUp
, 0);
1198 changePage(panel
->pagePopUp
, panel
);
1200 WMSetPopUpButtonSelectedItem(panel
->pagePopUp
, 1);
1201 changePage(panel
->pagePopUp
, panel
);
1204 parent
= XCreateSimpleWindow(dpy
, scr
->root_win
, 0, 0, PWIDTH
, PHEIGHT
, 0, 0, 0);
1205 XSelectInput(dpy
, parent
, KeyPressMask
| KeyReleaseMask
);
1206 panel
->parent
= parent
;
1207 XReparentWindow(dpy
, WMWidgetXID(panel
->win
), parent
, 0, 0);
1209 WMMapWidget(panel
->win
);
1211 XSetTransientForHint(dpy
, parent
, wwin
->client_win
);
1213 if (xpos
== UNDEFINED_POS
) {
1214 x
= wwin
->frame_x
+ wwin
->frame
->core
->width
/ 2;
1215 y
= wwin
->frame_y
+ wwin
->frame
->top_width
* 2;
1216 if (y
+ PHEIGHT
> scr
->scr_height
)
1217 y
= scr
->scr_height
- PHEIGHT
- 30;
1218 if (x
+ PWIDTH
> scr
->scr_width
)
1219 x
= scr
->scr_width
- PWIDTH
;
1225 panel
->frame
= wManageInternalWindow(scr
, parent
, wwin
->client_win
, "Inspector", x
, y
, PWIDTH
, PHEIGHT
);
1228 selectedBtn
= panel
->defaultRb
;
1230 WMSetButtonSelected(selectedBtn
, True
);
1231 selectSpecification(selectedBtn
, panel
);
1233 /* kluge to know who should get the key events */
1234 panel
->frame
->client_leader
= WMWidgetXID(panel
->win
);
1236 WSETUFLAG(panel
->frame
, no_closable
, 0);
1237 WSETUFLAG(panel
->frame
, no_close_button
, 0);
1238 wWindowUpdateButtonImages(panel
->frame
);
1239 wFrameWindowShowButton(panel
->frame
->frame
, WFF_RIGHT_BUTTON
);
1240 panel
->frame
->frame
->on_click_right
= destroyInspector
;
1242 wWindowMap(panel
->frame
);
1244 showIconFor(WMWidgetScreen(panel
->alwChk
), panel
, wwin
->wm_instance
, wwin
->wm_class
, UPDATE_TEXT_FIELD
);
1249 void wShowInspectorForWindow(WWindow
*wwin
)
1251 if (wwin
->flags
.inspector_open
)
1254 WMSetBalloonEnabled(wwin
->screen_ptr
->wmscreen
, wPreferences
.help_balloon
);
1257 wwin
->flags
.inspector_open
= 1;
1258 wwin
->inspector
= createInspectorForWindow(wwin
, UNDEFINED_POS
, UNDEFINED_POS
, False
);
1261 void wHideInspectorForWindow(WWindow
*wwin
)
1263 WWindow
*pwin
= wwin
->inspector
->frame
;
1266 pwin
->flags
.hidden
= 1;
1268 wClientSetState(pwin
, IconicState
, None
);
1271 void wUnhideInspectorForWindow(WWindow
*wwin
)
1273 WWindow
*pwin
= wwin
->inspector
->frame
;
1275 pwin
->flags
.hidden
= 0;
1276 pwin
->flags
.mapped
= 1;
1277 XMapWindow(dpy
, pwin
->client_win
);
1278 XMapWindow(dpy
, pwin
->frame
->core
->window
);
1279 wClientSetState(pwin
, NormalState
, None
);
1282 WWindow
*wGetWindowOfInspectorForWindow(WWindow
*wwin
)
1284 if (!wwin
->inspector
)
1287 assert(wwin
->flags
.inspector_open
!= 0);
1288 return wwin
->inspector
->frame
;
1291 void wCloseInspectorForWindow(WWindow
*wwin
)
1293 WWindow
*pwin
= wwin
->inspector
->frame
; /* the inspector window */
1295 (*pwin
->frame
->on_click_right
) (NULL
, pwin
, NULL
);
1298 static void create_tab_window_attributes(WWindow
*wwin
, InspectorPanel
*panel
, int frame_width
)
1301 char *caption
= NULL
, *descr
= NULL
;
1304 panel
->attrFrm
= WMCreateFrame(panel
->win
);
1305 WMSetFrameTitle(panel
->attrFrm
, _("Attributes"));
1306 WMMoveWidget(panel
->attrFrm
, 15, 45);
1307 WMResizeWidget(panel
->attrFrm
, frame_width
, 250);
1309 for (i
= 0; i
< (sizeof(panel
->attrChk
) / sizeof(panel
->attrChk
[0])); i
++) {
1312 caption
= _("Disable titlebar");
1313 flag
= WFLAGP(wwin
, no_titlebar
);
1314 descr
= _("Remove the titlebar of this window.\n"
1315 "To access the window commands menu of a window\n"
1316 "without it's titlebar, press Control+Esc (or the\n"
1317 "equivalent shortcut, if you changed the default\n" "settings).");
1320 caption
= _("Disable resizebar");
1321 flag
= WFLAGP(wwin
, no_resizebar
);
1322 descr
= _("Remove the resizebar of this window.");
1325 caption
= _("Disable close button");
1326 flag
= WFLAGP(wwin
, no_close_button
);
1327 descr
= _("Remove the `close window' button of this window.");
1330 caption
= _("Disable miniaturize button");
1331 flag
= WFLAGP(wwin
, no_miniaturize_button
);
1332 descr
= _("Remove the `miniaturize window' button of the window.");
1335 caption
= _("Disable border");
1336 flag
= WFLAGP(wwin
, no_border
);
1337 descr
= _("Remove the 1 pixel black border around the window.");
1340 caption
= _("Keep on top (floating)");
1341 flag
= WFLAGP(wwin
, floating
);
1342 descr
= _("Keep the window over other windows, not allowing\n" "them to cover it.");
1345 caption
= _("Keep at bottom (sunken)");
1346 flag
= WFLAGP(wwin
, sunken
);
1347 descr
= _("Keep the window under all other windows.");
1350 caption
= _("Omnipresent");
1351 flag
= WFLAGP(wwin
, omnipresent
);
1352 descr
= _("Make window present in all workspaces.");
1355 caption
= _("Start miniaturized");
1356 flag
= WFLAGP(wwin
, start_miniaturized
);
1357 descr
= _("Make the window be automatically miniaturized when it's\n" "first shown.");
1360 caption
= _("Start maximized");
1361 flag
= WFLAGP(wwin
, start_maximized
!= 0);
1362 descr
= _("Make the window be automatically maximized when it's\n" "first shown.");
1365 caption
= _("Full screen maximization");
1366 flag
= WFLAGP(wwin
, full_maximize
);
1367 descr
= _("Make the window use the whole screen space when it's\n"
1368 "maximized. The titlebar and resizebar will be moved\n"
1369 "to outside the screen.");
1372 panel
->attrChk
[i
] = WMCreateSwitchButton(panel
->attrFrm
);
1373 WMMoveWidget(panel
->attrChk
[i
], 10, 20 * (i
+ 1));
1374 WMResizeWidget(panel
->attrChk
[i
], frame_width
- 15, 20);
1375 WMSetButtonSelected(panel
->attrChk
[i
], flag
);
1376 WMSetButtonText(panel
->attrChk
[i
], caption
);
1378 WMSetBalloonTextForView(descr
, WMWidgetView(panel
->attrChk
[i
]));
1382 static void create_tab_window_advanced(WWindow
*wwin
, InspectorPanel
*panel
, int frame_width
)
1385 char *caption
= NULL
, *descr
= NULL
;
1388 panel
->moreFrm
= WMCreateFrame(panel
->win
);
1389 WMSetFrameTitle(panel
->moreFrm
, _("Advanced"));
1390 WMMoveWidget(panel
->moreFrm
, 15, 45);
1391 WMResizeWidget(panel
->moreFrm
, frame_width
, 265);
1393 for (i
= 0; i
< (sizeof(panel
->moreChk
) / sizeof(panel
->moreChk
[0])); i
++) {
1396 caption
= _("Do not bind keyboard shortcuts");
1397 flag
= WFLAGP(wwin
, no_bind_keys
);
1398 descr
= _("Do not bind keyboard shortcuts from Window Maker\n"
1399 "when this window is focused. This will allow the\n"
1400 "window to receive all key combinations regardless\n"
1401 "of your shortcut configuration.");
1404 caption
= _("Do not bind mouse clicks");
1405 flag
= WFLAGP(wwin
, no_bind_mouse
);
1406 descr
= _("Do not bind mouse actions, such as `Alt'+drag\n"
1407 "in the window (when alt is the modifier you have\n" "configured).");
1410 caption
= _("Do not show in the window list");
1411 flag
= WFLAGP(wwin
, skip_window_list
);
1412 descr
= _("Do not list the window in the window list menu.");
1415 caption
= _("Do not show in the switch panel");
1416 flag
= WFLAGP(wwin
, skip_switchpanel
);
1417 descr
= _("Do not include in switchpanel while alternating windows.");
1420 caption
= _("Do not let it take focus");
1421 flag
= WFLAGP(wwin
, no_focusable
);
1422 descr
= _("Do not let the window take keyboard focus when you\n" "click on it.");
1425 caption
= _("Keep inside screen");
1426 flag
= WFLAGP(wwin
, dont_move_off
);
1427 descr
= _("Do not allow the window to move itself completely\n"
1428 "outside the screen. For bug compatibility.\n");
1431 caption
= _("Ignore 'Hide Others'");
1432 flag
= WFLAGP(wwin
, no_hide_others
);
1433 descr
= _("Do not hide the window when issuing the\n" "`HideOthers' command.");
1436 caption
= _("Ignore 'Save Session'");
1437 flag
= WFLAGP(wwin
, dont_save_session
);
1438 descr
= _("Do not save the associated application in the\n"
1439 "session's state, so that it won't be restarted\n"
1440 "together with other applications when Window Maker\n" "starts.");
1443 caption
= _("Emulate application icon");
1444 flag
= WFLAGP(wwin
, emulate_appicon
);
1445 descr
= _("Make this window act as an application that provides\n"
1446 "enough information to Window Maker for a dockable\n"
1447 "application icon to be created.");
1450 caption
= _("Focus across workspaces");
1451 flag
= WFLAGP(wwin
, focus_across_wksp
);
1452 descr
= _("Allow Window Maker to switch workspace to satisfy\n"
1453 "a focus request (annoying).");
1456 caption
= _("Do not let it be minimized");
1457 flag
= WFLAGP(wwin
, no_miniaturizable
);
1458 descr
= _("Do not let the window of this application be\n"
1461 #ifdef XKB_BUTTON_HINT
1463 caption
= _("Disable language button");
1464 flag
= WFLAGP(wwin
, no_language_button
);
1465 descr
= _("Remove the `toggle language' button of the window.");
1469 panel
->moreChk
[i
] = WMCreateSwitchButton(panel
->moreFrm
);
1470 WMMoveWidget(panel
->moreChk
[i
], 10, 20 * (i
+ 1));
1471 WMResizeWidget(panel
->moreChk
[i
], frame_width
- 15, 20);
1472 WMSetButtonSelected(panel
->moreChk
[i
], flag
);
1473 WMSetButtonText(panel
->moreChk
[i
], caption
);
1475 WMSetBalloonTextForView(descr
, WMWidgetView(panel
->moreChk
[i
]));
1479 static void create_tab_icon_workspace(WWindow
*wwin
, InspectorPanel
*panel
, int frame_width
)
1481 WScreen
*scr
= wwin
->screen_ptr
;
1484 /* miniwindow/workspace */
1485 panel
->iconFrm
= WMCreateFrame(panel
->win
);
1486 WMMoveWidget(panel
->iconFrm
, 15, 50);
1487 WMResizeWidget(panel
->iconFrm
, PWIDTH
- (2 * 15), 170);
1488 WMSetFrameTitle(panel
->iconFrm
, _("Miniwindow Image"));
1490 panel
->iconLbl
= WMCreateLabel(panel
->iconFrm
);
1491 WMMoveWidget(panel
->iconLbl
, PWIDTH
- (2 * 15) - 22 - 64, 20);
1492 WMResizeWidget(panel
->iconLbl
, 64, 64);
1493 WMSetLabelRelief(panel
->iconLbl
, WRGroove
);
1494 WMSetLabelImagePosition(panel
->iconLbl
, WIPImageOnly
);
1496 panel
->browseIconBtn
= WMCreateCommandButton(panel
->iconFrm
);
1497 WMSetButtonAction(panel
->browseIconBtn
, chooseIconCallback
, panel
);
1498 WMMoveWidget(panel
->browseIconBtn
, 22, 32);
1499 WMResizeWidget(panel
->browseIconBtn
, 120, 26);
1500 WMSetButtonText(panel
->browseIconBtn
, _("Browse..."));
1502 panel
->fileLbl
= WMCreateLabel(panel
->iconFrm
);
1503 WMMoveWidget(panel
->fileLbl
, 20, 85);
1504 WMResizeWidget(panel
->fileLbl
, PWIDTH
- (2 * 15) - (2 * 20), 14);
1505 WMSetLabelText(panel
->fileLbl
, _("Icon filename:"));
1507 panel
->fileText
= WMCreateTextField(panel
->iconFrm
);
1508 WMMoveWidget(panel
->fileText
, 20, 105);
1509 WMResizeWidget(panel
->fileText
, PWIDTH
- (2 * 20) - (2 * 15), 20);
1510 WMSetTextFieldText(panel
->fileText
, NULL
);
1511 WMAddNotificationObserver(textEditedObserver
, panel
, WMTextDidEndEditingNotification
, panel
->fileText
);
1513 panel
->alwChk
= WMCreateSwitchButton(panel
->iconFrm
);
1514 WMMoveWidget(panel
->alwChk
, 20, 130);
1515 WMResizeWidget(panel
->alwChk
, PWIDTH
- (2 * 15) - (2 * 15), 30);
1516 WMSetButtonText(panel
->alwChk
, _("Ignore client supplied icon"));
1517 WMSetButtonSelected(panel
->alwChk
, WFLAGP(wwin
, always_user_icon
));
1519 panel
->wsFrm
= WMCreateFrame(panel
->win
);
1520 WMMoveWidget(panel
->wsFrm
, 15, 225);
1521 WMResizeWidget(panel
->wsFrm
, PWIDTH
- (2 * 15), 70);
1522 WMSetFrameTitle(panel
->wsFrm
, _("Initial Workspace"));
1524 WMSetBalloonTextForView(_("The workspace to place the window when it's"
1525 "first shown."), WMWidgetView(panel
->wsFrm
));
1527 panel
->wsP
= WMCreatePopUpButton(panel
->wsFrm
);
1528 WMMoveWidget(panel
->wsP
, 20, 30);
1529 WMResizeWidget(panel
->wsP
, PWIDTH
- (2 * 15) - (2 * 20), 20);
1530 WMAddPopUpButtonItem(panel
->wsP
, _("Nowhere in particular"));
1532 for (i
= 0; i
< w_global
.workspace
.count
; i
++)
1533 WMAddPopUpButtonItem(panel
->wsP
, scr
->workspaces
[i
]->name
);
1535 i
= wDefaultGetStartWorkspace(wwin
->screen_ptr
, wwin
->wm_instance
, wwin
->wm_class
);
1536 if (i
>= 0 && i
<= w_global
.workspace
.count
)
1537 WMSetPopUpButtonSelectedItem(panel
->wsP
, i
+ 1);
1539 WMSetPopUpButtonSelectedItem(panel
->wsP
, 0);
1542 static void create_tab_app_specific(WWindow
*wwin
, InspectorPanel
*panel
, int frame_width
)
1544 WScreen
*scr
= wwin
->screen_ptr
;
1545 int i
= 0, flag
= 0, tmp
;
1546 char *caption
= NULL
, *descr
= NULL
;
1549 if (wwin
->main_window
!= None
) {
1550 WApplication
*wapp
= wApplicationOf(wwin
->main_window
);
1552 panel
->appFrm
= WMCreateFrame(panel
->win
);
1553 WMSetFrameTitle(panel
->appFrm
, _("Application Attributes"));
1554 WMMoveWidget(panel
->appFrm
, 15, 50);
1555 WMResizeWidget(panel
->appFrm
, frame_width
, 240);
1557 for (i
= 0; i
< (sizeof(panel
->appChk
) / sizeof(panel
->appChk
[0])); i
++) {
1560 caption
= _("Start hidden");
1561 flag
= WFLAGP(wapp
->main_window_desc
, start_hidden
);
1562 descr
= _("Automatically hide application when it's started.");
1565 caption
= _("No application icon");
1566 flag
= WFLAGP(wapp
->main_window_desc
, no_appicon
);
1567 descr
= _("Disable the application icon for the application.\n"
1568 "Note that you won't be able to dock it anymore,\n"
1569 "and any icons that are already docked will stop\n"
1570 "working correctly.");
1573 caption
= _("Shared application icon");
1574 flag
= WFLAGP(wapp
->main_window_desc
, shared_appicon
);
1575 descr
= _("Use a single shared application icon for all of\n"
1576 "the instances of this application.\n");
1579 panel
->appChk
[i
] = WMCreateSwitchButton(panel
->appFrm
);
1580 WMMoveWidget(panel
->appChk
[i
], 10, 20 * (i
+ 1));
1581 WMResizeWidget(panel
->appChk
[i
], 205, 20);
1582 WMSetButtonSelected(panel
->appChk
[i
], flag
);
1583 WMSetButtonText(panel
->appChk
[i
], caption
);
1584 WMSetBalloonTextForView(descr
, WMWidgetView(panel
->appChk
[i
]));
1587 if (WFLAGP(wwin
, emulate_appicon
)) {
1588 WMSetButtonEnabled(panel
->appChk
[1], False
);
1589 WMSetButtonEnabled(panel
->moreChk
[7], True
);
1591 WMSetButtonEnabled(panel
->appChk
[1], True
);
1592 WMSetButtonEnabled(panel
->moreChk
[7], False
);
1595 if ((wwin
->transient_for
!= None
&& wwin
->transient_for
!= scr
->root_win
)
1596 || !wwin
->wm_class
|| !wwin
->wm_instance
)
1601 WMSetButtonEnabled(panel
->moreChk
[7], tmp
);
1603 WMSetPopUpButtonItemEnabled(panel
->pagePopUp
, 4, False
);
1604 panel
->appFrm
= NULL
;