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"
43 #include "application.h"
46 #include "winspector.h"
51 #include <WINGs/WUtil.h>
53 #define USE_TEXT_FIELD 1
54 #define UPDATE_TEXT_FIELD 2
55 #define REVERT_TO_DEFAULT 4
58 #define UNDEFINED_POS 0xffffff
59 #define UPDATE_DEFAULTS 1
62 typedef struct InspectorPanel
{
63 struct InspectorPanel
*nextPtr
;
66 WWindow
*inspected
; /* the window that's being inspected */
74 WMPopUpButton
*pagePopUp
;
76 /* first page. general stuff */
85 /* second page. attributes */
87 WMButton
*attrChk
[11];
89 /* 3rd page. more attributes */
91 #ifdef XKB_BUTTON_HINT
92 WMButton
*moreChk
[12];
94 WMButton
*moreChk
[11];
97 /* 4th page. icon and workspace */
101 WMTextField
*fileText
;
103 WMButton
*browseIconBtn
;
107 /* 5th page. application wide attributes */
112 unsigned int destroyed
:1;
113 unsigned int choosingIcon
:1;
116 extern Cursor wCursor
[WCUR_LAST
];
117 extern WDDomain
*WDWindowAttributes
;
118 extern WPreferences wPreferences
;
120 static InspectorPanel
*panelList
= NULL
;
121 static WMPropList
*ANoTitlebar
= NULL
;
122 static WMPropList
*ANoResizebar
;
123 static WMPropList
*ANoMiniaturizeButton
;
124 static WMPropList
*ANoCloseButton
;
125 static WMPropList
*ANoBorder
;
126 static WMPropList
*ANoHideOthers
;
127 static WMPropList
*ANoMouseBindings
;
128 static WMPropList
*ANoKeyBindings
;
129 static WMPropList
*ANoAppIcon
;
130 static WMPropList
*AKeepOnTop
;
131 static WMPropList
*AKeepOnBottom
;
132 static WMPropList
*AOmnipresent
;
133 static WMPropList
*ASkipWindowList
;
134 static WMPropList
*ASkipSwitchPanel
;
135 static WMPropList
*AKeepInsideScreen
;
136 static WMPropList
*AUnfocusable
;
137 static WMPropList
*AFocusAcrossWorkspace
;
138 static WMPropList
*AAlwaysUserIcon
;
139 static WMPropList
*AStartMiniaturized
;
140 static WMPropList
*AStartMaximized
;
141 static WMPropList
*ADontSaveSession
;
142 static WMPropList
*AEmulateAppIcon
;
143 static WMPropList
*AFullMaximize
;
144 static WMPropList
*ASharedAppIcon
;
145 static WMPropList
*ANoMiniaturizable
;
146 #ifdef XKB_BUTTON_HINT
147 static WMPropList
*ANoLanguageButton
;
149 static WMPropList
*AStartWorkspace
;
150 static WMPropList
*AIcon
;
152 /* application wide options */
153 static WMPropList
*AStartHidden
;
154 static WMPropList
*AnyWindow
;
155 static WMPropList
*EmptyString
;
156 static WMPropList
*Yes
, *No
;
158 static char *spec_text
;
159 static void applySettings(WMButton
*button
, InspectorPanel
*panel
);
161 static InspectorPanel
*createInspectorForWindow(WWindow
*wwin
, int xpos
, int ypos
, Bool showSelectPanel
);
163 static void create_tab_window_attributes(WWindow
*wwin
, InspectorPanel
*panel
, int frame_width
);
164 static void create_tab_window_advanced(WWindow
*wwin
, InspectorPanel
*panel
, int frame_width
);
165 static void create_tab_icon_workspace(WWindow
*wwin
, InspectorPanel
*panel
, int frame_width
);
166 static void create_tab_app_specific(WWindow
*wwin
, InspectorPanel
*panel
, int frame_width
);
168 static void make_keys(void)
170 if (ANoTitlebar
!= NULL
)
173 AIcon
= WMCreatePLString("Icon");
174 ANoTitlebar
= WMCreatePLString("NoTitlebar");
175 ANoResizebar
= WMCreatePLString("NoResizebar");
176 ANoMiniaturizeButton
= WMCreatePLString("NoMiniaturizeButton");
177 ANoCloseButton
= WMCreatePLString("NoCloseButton");
178 ANoBorder
= WMCreatePLString("NoBorder");
179 ANoHideOthers
= WMCreatePLString("NoHideOthers");
180 ANoMouseBindings
= WMCreatePLString("NoMouseBindings");
181 ANoKeyBindings
= WMCreatePLString("NoKeyBindings");
182 ANoAppIcon
= WMCreatePLString("NoAppIcon");
183 AKeepOnTop
= WMCreatePLString("KeepOnTop");
184 AKeepOnBottom
= WMCreatePLString("KeepOnBottom");
185 AOmnipresent
= WMCreatePLString("Omnipresent");
186 ASkipWindowList
= WMCreatePLString("SkipWindowList");
187 ASkipSwitchPanel
= WMCreatePLString("SkipSwitchPanel");
188 AKeepInsideScreen
= WMCreatePLString("KeepInsideScreen");
189 AUnfocusable
= WMCreatePLString("Unfocusable");
190 AFocusAcrossWorkspace
= WMCreatePLString("FocusAcrossWorkspace");
191 AAlwaysUserIcon
= WMCreatePLString("AlwaysUserIcon");
192 AStartMiniaturized
= WMCreatePLString("StartMiniaturized");
193 AStartMaximized
= WMCreatePLString("StartMaximized");
194 AStartHidden
= WMCreatePLString("StartHidden");
195 ADontSaveSession
= WMCreatePLString("DontSaveSession");
196 AEmulateAppIcon
= WMCreatePLString("EmulateAppIcon");
197 AFullMaximize
= WMCreatePLString("FullMaximize");
198 ASharedAppIcon
= WMCreatePLString("SharedAppIcon");
199 ANoMiniaturizable
= WMCreatePLString("NoMiniaturizable");
200 #ifdef XKB_BUTTON_HINT
201 ANoLanguageButton
= WMCreatePLString("NoLanguageButton");
204 AStartWorkspace
= WMCreatePLString("StartWorkspace");
206 AnyWindow
= WMCreatePLString("*");
207 EmptyString
= WMCreatePLString("");
208 Yes
= WMCreatePLString("Yes");
209 No
= WMCreatePLString("No");
212 static void freeInspector(InspectorPanel
*panel
)
214 panel
->destroyed
= 1;
216 if (panel
->choosingIcon
)
219 WMDestroyWidget(panel
->win
);
220 XDestroyWindow(dpy
, panel
->parent
);
224 static void destroyInspector(WCoreWindow
*foo
, void *data
, XEvent
*event
)
226 InspectorPanel
*panel
, *tmp
;
229 while (panel
->frame
!= data
)
230 panel
= panel
->nextPtr
;
232 if (panelList
== panel
) {
233 panelList
= panel
->nextPtr
;
236 while (tmp
->nextPtr
!= panel
)
239 tmp
->nextPtr
= panel
->nextPtr
;
241 panel
->inspected
->flags
.inspector_open
= 0;
242 panel
->inspected
->inspector
= NULL
;
244 WMRemoveNotificationObserver(panel
);
246 wWindowUnmap(panel
->frame
);
247 wUnmanageWindow(panel
->frame
, True
, False
);
249 freeInspector(panel
);
252 void wDestroyInspectorPanels(void)
254 InspectorPanel
*panel
;
256 while (panelList
!= NULL
) {
258 panelList
= panelList
->nextPtr
;
259 wUnmanageWindow(panel
->frame
, False
, False
);
260 WMDestroyWidget(panel
->win
);
262 panel
->inspected
->flags
.inspector_open
= 0;
263 panel
->inspected
->inspector
= NULL
;
269 static void changePage(WMPopUpButton
*bPtr
, InspectorPanel
*panel
)
273 page
= WMGetPopUpButtonSelectedItem(bPtr
);
276 WMMapWidget(panel
->specFrm
);
277 WMMapWidget(panel
->specLbl
);
278 } else if (page
== 1) {
279 WMMapWidget(panel
->attrFrm
);
280 } else if (page
== 2) {
281 WMMapWidget(panel
->moreFrm
);
282 } else if (page
== 3) {
283 WMMapWidget(panel
->iconFrm
);
284 WMMapWidget(panel
->wsFrm
);
286 WMMapWidget(panel
->appFrm
);
290 WMUnmapWidget(panel
->specFrm
);
291 WMUnmapWidget(panel
->specLbl
);
294 WMUnmapWidget(panel
->attrFrm
);
296 WMUnmapWidget(panel
->moreFrm
);
298 WMUnmapWidget(panel
->iconFrm
);
299 WMUnmapWidget(panel
->wsFrm
);
301 if (page
!= 4 && panel
->appFrm
)
302 WMUnmapWidget(panel
->appFrm
);
305 static int showIconFor(WMScreen
*scrPtr
, InspectorPanel
*panel
, char *wm_instance
, char *wm_class
, int flags
)
307 WMPixmap
*pixmap
= (WMPixmap
*) NULL
;
308 char *file
= NULL
, *path
= NULL
, *db_icon
= NULL
;
310 if ((flags
& USE_TEXT_FIELD
) != 0) {
311 file
= WMGetTextFieldText(panel
->fileText
);
312 if (file
&& file
[0] == 0) {
317 /* Get the application icon, default included */
318 db_icon
= wDefaultGetIconFile(wm_instance
, wm_class
, True
);
320 file
= wstrdup(db_icon
);
322 if (db_icon
!= NULL
&& (flags
& REVERT_TO_DEFAULT
) != 0) {
324 file
= wstrdup(db_icon
);
325 flags
|= UPDATE_TEXT_FIELD
;
328 if ((flags
& UPDATE_TEXT_FIELD
) != 0)
329 WMSetTextFieldText(panel
->fileText
, file
);
332 path
= FindImage(wPreferences
.icon_path
, file
);
336 int len
= strlen(file
) + 80;
339 snprintf(buf
, len
, _("Could not find icon \"%s\" specified for this window"), file
);
340 wMessageDialog(panel
->frame
->screen_ptr
, _("Error"), buf
, _("OK"), NULL
, NULL
);
346 pixmap
= WMCreatePixmapFromFile(scrPtr
, path
);
351 int len
= strlen(file
) + 80;
354 snprintf(buf
, len
, _("Could not open specified icon \"%s\":%s"),
355 file
, RMessageForError(RErrorCode
));
356 wMessageDialog(panel
->frame
->screen_ptr
, _("Error"), buf
, _("OK"), NULL
, NULL
);
364 WMSetLabelImage(panel
->iconLbl
, pixmap
);
366 WMReleasePixmap(pixmap
);
371 static int getBool(WMPropList
*value
)
375 if (!WMIsPLString(value
))
378 if (!(val
= WMGetFromPLString(value
)))
381 if ((val
[1] == '\0' &&
382 (val
[0] == 'y' || val
[0] == 'Y' || val
[0] == 'T' ||
383 val
[0] == 't' || val
[0] == '1')) ||
384 (strcasecmp(val
, "YES") == 0 || strcasecmp(val
, "TRUE") == 0)) {
386 } else if ((val
[1] == '\0' &&
387 (val
[0] == 'n' || val
[0] == 'N' || val
[0] == 'F' ||
388 val
[0] == 'f' || val
[0] == '0')) ||
389 (strcasecmp(val
, "NO") == 0 || strcasecmp(val
, "FALSE") == 0)) {
392 wwarning(_("can't convert \"%s\" to boolean"), val
);
397 /* Will insert the attribute = value; pair in window's list,
398 * if it's different from the defaults.
399 * Defaults means either defaults database, or attributes saved
400 * for the default window "*". This is to let one revert options that are
401 * global because they were saved for all windows ("*"). */
403 insertAttribute(WMPropList
*dict
, WMPropList
*window
, WMPropList
*attr
, WMPropList
*value
, int flags
)
405 WMPropList
*def_win
, *def_value
= NULL
;
406 int update
= 0, modified
= 0;
408 if (!(flags
& UPDATE_DEFAULTS
) && dict
) {
409 if ((def_win
= WMGetFromPLDictionary(dict
, AnyWindow
)) != NULL
)
410 def_value
= WMGetFromPLDictionary(def_win
, attr
);
413 /* If we could not find defaults in database, fall to hardcoded values.
414 * Also this is true if we save defaults for all windows */
416 def_value
= ((flags
& IS_BOOLEAN
) != 0) ? No
: EmptyString
;
418 if (flags
& IS_BOOLEAN
)
419 update
= (getBool(value
) != getBool(def_value
));
421 update
= !WMIsPropListEqualTo(value
, def_value
);
424 WMPutInPLDictionary(window
, attr
, value
);
431 static void saveSettings(WMButton
*button
, InspectorPanel
*panel
)
433 WWindow
*wwin
= panel
->inspected
;
434 WDDomain
*db
= WDWindowAttributes
;
435 WMPropList
*dict
= NULL
;
436 WMPropList
*winDic
, *appDic
, *value
, *key
= NULL
, *key2
;
437 char *icon_file
, *buf1
, *buf2
;
438 int flags
= 0, i
= 0, different
= 0, different2
= 0;
440 /* Save will apply the changes and save them */
441 applySettings(panel
->applyBtn
, panel
);
443 if (WMGetButtonSelected(panel
->instRb
) != 0) {
444 key
= WMCreatePLString(wwin
->wm_instance
);
445 } else if (WMGetButtonSelected(panel
->clsRb
) != 0) {
446 key
= WMCreatePLString(wwin
->wm_class
);
447 } else if (WMGetButtonSelected(panel
->bothRb
) != 0) {
448 buf1
= StrConcatDot(wwin
->wm_instance
, wwin
->wm_class
);
449 key
= WMCreatePLString(buf1
);
451 } else if (WMGetButtonSelected(panel
->defaultRb
) != 0) {
452 key
= WMRetainPropList(AnyWindow
);
453 flags
= UPDATE_DEFAULTS
;
459 dict
= db
->dictionary
;
461 dict
= WMCreatePLDictionary(NULL
, NULL
);
463 db
->dictionary
= dict
;
465 WMReleasePropList(key
);
470 if (showIconFor(WMWidgetScreen(button
), panel
, NULL
, NULL
, USE_TEXT_FIELD
) < 0)
473 WMPLSetCaseSensitive(True
);
475 winDic
= WMCreatePLDictionary(NULL
, NULL
);
476 appDic
= WMCreatePLDictionary(NULL
, NULL
);
478 /* Update icon for window */
479 icon_file
= WMGetTextFieldText(panel
->fileText
);
481 if (icon_file
[0] != 0) {
482 value
= WMCreatePLString(icon_file
);
483 different
|= insertAttribute(dict
, winDic
, AIcon
, value
, flags
);
484 different2
|= insertAttribute(dict
, appDic
, AIcon
, value
, flags
);
485 WMReleasePropList(value
);
490 i
= WMGetPopUpButtonSelectedItem(panel
->wsP
) - 1;
491 if (i
>= 0 && i
< panel
->frame
->screen_ptr
->workspace_count
) {
492 value
= WMCreatePLString(panel
->frame
->screen_ptr
->workspaces
[i
]->name
);
493 different
|= insertAttribute(dict
, winDic
, AStartWorkspace
, value
, flags
);
494 WMReleasePropList(value
);
499 value
= (WMGetButtonSelected(panel
->alwChk
) != 0) ? Yes
: No
;
500 different
|= insertAttribute(dict
, winDic
, AAlwaysUserIcon
, value
, flags
);
502 value
= (WMGetButtonSelected(panel
->attrChk
[0]) != 0) ? Yes
: No
;
503 different
|= insertAttribute(dict
, winDic
, ANoTitlebar
, value
, flags
);
505 value
= (WMGetButtonSelected(panel
->attrChk
[1]) != 0) ? Yes
: No
;
506 different
|= insertAttribute(dict
, winDic
, ANoResizebar
, value
, flags
);
508 value
= (WMGetButtonSelected(panel
->attrChk
[2]) != 0) ? Yes
: No
;
509 different
|= insertAttribute(dict
, winDic
, ANoCloseButton
, value
, flags
);
511 value
= (WMGetButtonSelected(panel
->attrChk
[3]) != 0) ? Yes
: No
;
512 different
|= insertAttribute(dict
, winDic
, ANoMiniaturizeButton
, value
, flags
);
514 value
= (WMGetButtonSelected(panel
->attrChk
[4]) != 0) ? Yes
: No
;
515 different
|= insertAttribute(dict
, winDic
, ANoBorder
, value
, flags
);
517 value
= (WMGetButtonSelected(panel
->attrChk
[5]) != 0) ? Yes
: No
;
518 different
|= insertAttribute(dict
, winDic
, AKeepOnTop
, value
, flags
);
520 value
= (WMGetButtonSelected(panel
->attrChk
[6]) != 0) ? Yes
: No
;
521 different
|= insertAttribute(dict
, winDic
, AKeepOnBottom
, value
, flags
);
523 value
= (WMGetButtonSelected(panel
->attrChk
[7]) != 0) ? Yes
: No
;
524 different
|= insertAttribute(dict
, winDic
, AOmnipresent
, value
, flags
);
526 value
= (WMGetButtonSelected(panel
->attrChk
[8]) != 0) ? Yes
: No
;
527 different
|= insertAttribute(dict
, winDic
, AStartMiniaturized
, value
, flags
);
529 value
= (WMGetButtonSelected(panel
->attrChk
[9]) != 0) ? Yes
: No
;
530 different
|= insertAttribute(dict
, winDic
, AStartMaximized
, value
, flags
);
532 value
= (WMGetButtonSelected(panel
->attrChk
[10]) != 0) ? Yes
: No
;
533 different
|= insertAttribute(dict
, winDic
, AFullMaximize
, value
, flags
);
535 value
= (WMGetButtonSelected(panel
->moreChk
[0]) != 0) ? Yes
: No
;
536 different
|= insertAttribute(dict
, winDic
, ANoKeyBindings
, value
, flags
);
538 value
= (WMGetButtonSelected(panel
->moreChk
[1]) != 0) ? Yes
: No
;
539 different
|= insertAttribute(dict
, winDic
, ANoMouseBindings
, value
, flags
);
541 value
= (WMGetButtonSelected(panel
->moreChk
[2]) != 0) ? Yes
: No
;
542 different
|= insertAttribute(dict
, winDic
, ASkipWindowList
, value
, flags
);
544 value
= (WMGetButtonSelected(panel
->moreChk
[3]) != 0) ? Yes
: No
;
545 different
|= insertAttribute(dict
, winDic
, ASkipSwitchPanel
, value
, flags
);
547 value
= (WMGetButtonSelected(panel
->moreChk
[4]) != 0) ? Yes
: No
;
548 different
|= insertAttribute(dict
, winDic
, AUnfocusable
, value
, flags
);
550 value
= (WMGetButtonSelected(panel
->moreChk
[5]) != 0) ? Yes
: No
;
551 different
|= insertAttribute(dict
, winDic
, AKeepInsideScreen
, value
, flags
);
553 value
= (WMGetButtonSelected(panel
->moreChk
[6]) != 0) ? Yes
: No
;
554 different
|= insertAttribute(dict
, winDic
, ANoHideOthers
, value
, flags
);
556 value
= (WMGetButtonSelected(panel
->moreChk
[7]) != 0) ? Yes
: No
;
557 different
|= insertAttribute(dict
, winDic
, ADontSaveSession
, value
, flags
);
559 value
= (WMGetButtonSelected(panel
->moreChk
[8]) != 0) ? Yes
: No
;
560 different
|= insertAttribute(dict
, winDic
, AEmulateAppIcon
, value
, flags
);
562 value
= (WMGetButtonSelected(panel
->moreChk
[9]) != 0) ? Yes
: No
;
563 different
|= insertAttribute(dict
, winDic
, AFocusAcrossWorkspace
, value
, flags
);
565 value
= (WMGetButtonSelected(panel
->moreChk
[10]) != 0) ? Yes
: No
;
566 different
|= insertAttribute(dict
, winDic
, ANoMiniaturizable
, value
, flags
);
568 #ifdef XKB_BUTTON_HINT
569 value
= (WMGetButtonSelected(panel
->moreChk
[11]) != 0) ? Yes
: No
;
570 different
|= insertAttribute(dict
, winDic
, ANoLanguageButton
, value
, flags
);
573 if (wwin
->main_window
!= None
&& wApplicationOf(wwin
->main_window
) != NULL
) {
574 value
= (WMGetButtonSelected(panel
->appChk
[0]) != 0) ? Yes
: No
;
575 different2
|= insertAttribute(dict
, appDic
, AStartHidden
, value
, flags
);
577 value
= (WMGetButtonSelected(panel
->appChk
[1]) != 0) ? Yes
: No
;
578 different2
|= insertAttribute(dict
, appDic
, ANoAppIcon
, value
, flags
);
580 value
= (WMGetButtonSelected(panel
->appChk
[2]) != 0) ? Yes
: No
;
581 different2
|= insertAttribute(dict
, appDic
, ASharedAppIcon
, value
, flags
);
584 if (wwin
->fake_group
) {
585 key2
= WMCreatePLString(wwin
->fake_group
->identifier
);
586 if (WMIsPropListEqualTo(key
, key2
)) {
587 WMMergePLDictionaries(winDic
, appDic
, True
);
588 different
|= different2
;
590 WMRemoveFromPLDictionary(dict
, key2
);
592 WMPutInPLDictionary(dict
, key2
, appDic
);
594 WMReleasePropList(key2
);
595 WMReleasePropList(appDic
);
596 } else if (wwin
->main_window
!= wwin
->client_win
) {
597 WApplication
*wapp
= wApplicationOf(wwin
->main_window
);
600 buf2
= StrConcatDot(wapp
->main_window_desc
->wm_instance
,
601 wapp
->main_window_desc
->wm_class
);
602 key2
= WMCreatePLString(buf2
);
605 if (WMIsPropListEqualTo(key
, key2
)) {
606 WMMergePLDictionaries(winDic
, appDic
, True
);
607 different
|= different2
;
609 WMRemoveFromPLDictionary(dict
, key2
);
611 WMPutInPLDictionary(dict
, key2
, appDic
);
613 WMReleasePropList(key2
);
614 WMReleasePropList(appDic
);
617 WMMergePLDictionaries(winDic
, appDic
, True
);
618 different
|= different2
;
619 WMReleasePropList(appDic
);
622 WMRemoveFromPLDictionary(dict
, key
);
624 WMPutInPLDictionary(dict
, key
, winDic
);
626 WMReleasePropList(key
);
627 WMReleasePropList(winDic
);
629 UpdateDomainFile(db
);
632 WMPLSetCaseSensitive(False
);
635 static void applySettings(WMButton
*button
, InspectorPanel
*panel
)
637 WWindow
*wwin
= panel
->inspected
;
638 WApplication
*wapp
= wApplicationOf(wwin
->main_window
);
639 int floating
, sunken
, skip_window_list
;
640 int old_omnipresent
, old_no_bind_keys
, old_no_bind_mouse
;
642 old_omnipresent
= WFLAGP(wwin
, omnipresent
);
643 old_no_bind_keys
= WFLAGP(wwin
, no_bind_keys
);
644 old_no_bind_mouse
= WFLAGP(wwin
, no_bind_mouse
);
646 showIconFor(WMWidgetScreen(button
), panel
, NULL
, NULL
, USE_TEXT_FIELD
);
648 /* Attributes... --> Window Attributes */
649 WSETUFLAG(wwin
, no_titlebar
, WMGetButtonSelected(panel
->attrChk
[0]));
650 WSETUFLAG(wwin
, no_resizebar
, WMGetButtonSelected(panel
->attrChk
[1]));
651 WSETUFLAG(wwin
, no_close_button
, WMGetButtonSelected(panel
->attrChk
[2]));
652 WSETUFLAG(wwin
, no_miniaturize_button
, WMGetButtonSelected(panel
->attrChk
[3]));
653 WSETUFLAG(wwin
, no_border
, WMGetButtonSelected(panel
->attrChk
[4]));
654 floating
= WMGetButtonSelected(panel
->attrChk
[5]);
655 sunken
= WMGetButtonSelected(panel
->attrChk
[6]);
656 WSETUFLAG(wwin
, omnipresent
, WMGetButtonSelected(panel
->attrChk
[7]));
657 WSETUFLAG(wwin
, start_miniaturized
, WMGetButtonSelected(panel
->attrChk
[8]));
658 WSETUFLAG(wwin
, start_maximized
, WMGetButtonSelected(panel
->attrChk
[9]));
659 WSETUFLAG(wwin
, full_maximize
, WMGetButtonSelected(panel
->attrChk
[10]));
661 /* Attributes... --> Advanced Options */
662 WSETUFLAG(wwin
, no_bind_keys
, WMGetButtonSelected(panel
->moreChk
[0]));
663 WSETUFLAG(wwin
, no_bind_mouse
, WMGetButtonSelected(panel
->moreChk
[1]));
664 skip_window_list
= WMGetButtonSelected(panel
->moreChk
[2]);
665 WSETUFLAG(wwin
, skip_switchpanel
, WMGetButtonSelected(panel
->moreChk
[3]));
666 WSETUFLAG(wwin
, no_focusable
, WMGetButtonSelected(panel
->moreChk
[4]));
667 WSETUFLAG(wwin
, dont_move_off
, WMGetButtonSelected(panel
->moreChk
[5]));
668 WSETUFLAG(wwin
, no_hide_others
, WMGetButtonSelected(panel
->moreChk
[6]));
669 WSETUFLAG(wwin
, dont_save_session
, WMGetButtonSelected(panel
->moreChk
[7]));
670 WSETUFLAG(wwin
, emulate_appicon
, WMGetButtonSelected(panel
->moreChk
[8]));
671 WSETUFLAG(wwin
, focus_across_wksp
, WMGetButtonSelected(panel
->moreChk
[9]));
672 WSETUFLAG(wwin
, no_miniaturizable
, WMGetButtonSelected(panel
->moreChk
[10]));
673 #ifdef XKB_BUTTON_HINT
674 WSETUFLAG(wwin
, no_language_button
, WMGetButtonSelected(panel
->moreChk
[11]));
676 WSETUFLAG(wwin
, always_user_icon
, WMGetButtonSelected(panel
->alwChk
));
678 if (WFLAGP(wwin
, no_titlebar
) && wwin
->flags
.shaded
)
679 wUnshadeWindow(wwin
);
681 WSETUFLAG(wwin
, no_shadeable
, WFLAGP(wwin
, no_titlebar
));
684 if (!WFLAGP(wwin
, floating
))
685 ChangeStackingLevel(wwin
->frame
->core
, WMFloatingLevel
);
687 if (!WFLAGP(wwin
, sunken
))
688 ChangeStackingLevel(wwin
->frame
->core
, WMSunkenLevel
);
690 if (WFLAGP(wwin
, floating
) || WFLAGP(wwin
, sunken
))
691 ChangeStackingLevel(wwin
->frame
->core
, WMNormalLevel
);
694 WSETUFLAG(wwin
, sunken
, sunken
);
695 WSETUFLAG(wwin
, floating
, floating
);
696 wwin
->flags
.omnipresent
= 0;
698 if (WFLAGP(wwin
, skip_window_list
) != skip_window_list
) {
699 WSETUFLAG(wwin
, skip_window_list
, skip_window_list
);
700 UpdateSwitchMenu(wwin
->screen_ptr
, wwin
, skip_window_list
? ACTION_REMOVE
: ACTION_ADD
);
702 if (WFLAGP(wwin
, omnipresent
) != old_omnipresent
)
703 WMPostNotificationName(WMNChangedState
, wwin
, "omnipresent");
706 if (WFLAGP(wwin
, no_bind_keys
) != old_no_bind_keys
) {
707 if (WFLAGP(wwin
, no_bind_keys
))
708 XUngrabKey(dpy
, AnyKey
, AnyModifier
, wwin
->frame
->core
->window
);
710 wWindowSetKeyGrabs(wwin
);
713 if (WFLAGP(wwin
, no_bind_mouse
) != old_no_bind_mouse
)
714 wWindowResetMouseGrabs(wwin
);
716 wwin
->frame
->flags
.need_texture_change
= 1;
717 wWindowConfigureBorders(wwin
);
718 wFrameWindowPaint(wwin
->frame
);
719 wNETWMUpdateActions(wwin
, False
);
721 /* Can't apply emulate_appicon because it will probably cause problems. */
723 /* do application wide stuff */
724 WSETUFLAG(wapp
->main_window_desc
, start_hidden
, WMGetButtonSelected(panel
->appChk
[0]));
725 WSETUFLAG(wapp
->main_window_desc
, no_appicon
, WMGetButtonSelected(panel
->appChk
[1]));
726 WSETUFLAG(wapp
->main_window_desc
, shared_appicon
, WMGetButtonSelected(panel
->appChk
[2]));
728 if (WFLAGP(wapp
->main_window_desc
, no_appicon
))
729 unpaint_app_icon(wapp
);
731 paint_app_icon(wapp
);
733 char *file
= WMGetTextFieldText(panel
->fileText
);
739 if (WFLAGP(wwin
, always_user_icon
)) {
740 /* Change icon image if the app is minimized */
742 wIconChangeImageFile(wwin
->icon
, file
);
744 /* Change App Icon image */
746 wIconChangeImageFile(wapp
->app_icon
->icon
, file
);
748 /* Change App Icon image */
750 wIconUpdate(wapp
->app_icon
->icon
, get_rimage_icon_from_wm_hints(wapp
->app_icon
->icon
));
752 /* Change icon image if the app is minimized */
754 wIconUpdate(wwin
->icon
, get_rimage_icon_from_wm_hints(wwin
->icon
));
761 wNETFrameExtents(wwin
);
764 static void revertSettings(WMButton
*button
, InspectorPanel
*panel
)
766 WWindow
*wwin
= panel
->inspected
;
767 WApplication
*wapp
= wApplicationOf(wwin
->main_window
);
768 int i
, n
, workspace
, level
;
769 char *wm_instance
= NULL
, *wm_class
= NULL
;
771 if (panel
->instRb
&& WMGetButtonSelected(panel
->instRb
) != 0)
772 wm_instance
= wwin
->wm_instance
;
773 else if (panel
->clsRb
&& WMGetButtonSelected(panel
->clsRb
) != 0)
774 wm_class
= wwin
->wm_class
;
775 else if (panel
->bothRb
&& WMGetButtonSelected(panel
->bothRb
) != 0) {
776 wm_instance
= wwin
->wm_instance
;
777 wm_class
= wwin
->wm_class
;
780 memset(&wwin
->defined_user_flags
, 0, sizeof(WWindowAttributes
));
781 memset(&wwin
->user_flags
, 0, sizeof(WWindowAttributes
));
782 memset(&wwin
->client_flags
, 0, sizeof(WWindowAttributes
));
784 wWindowSetupInitialAttributes(wwin
, &level
, &workspace
);
786 for (i
= 0; i
< (sizeof(panel
->attrChk
) / sizeof(panel
->attrChk
[0])); i
++) {
791 flag
= WFLAGP(wwin
, no_titlebar
);
794 flag
= WFLAGP(wwin
, no_resizebar
);
797 flag
= WFLAGP(wwin
, no_close_button
);
800 flag
= WFLAGP(wwin
, no_miniaturize_button
);
803 flag
= WFLAGP(wwin
, no_border
);
806 flag
= WFLAGP(wwin
, floating
);
809 flag
= WFLAGP(wwin
, sunken
);
812 flag
= WFLAGP(wwin
, omnipresent
);
815 flag
= WFLAGP(wwin
, start_miniaturized
);
818 flag
= WFLAGP(wwin
, start_maximized
!= 0);
821 flag
= WFLAGP(wwin
, full_maximize
);
824 WMSetButtonSelected(panel
->attrChk
[i
], flag
);
827 for (i
= 0; i
< (sizeof(panel
->moreChk
) / sizeof(panel
->moreChk
[0])); i
++) {
832 flag
= WFLAGP(wwin
, no_bind_keys
);
835 flag
= WFLAGP(wwin
, no_bind_mouse
);
838 flag
= WFLAGP(wwin
, skip_window_list
);
841 flag
= WFLAGP(wwin
, skip_switchpanel
);
844 flag
= WFLAGP(wwin
, no_focusable
);
847 flag
= WFLAGP(wwin
, dont_move_off
);
850 flag
= WFLAGP(wwin
, no_hide_others
);
853 flag
= WFLAGP(wwin
, dont_save_session
);
856 flag
= WFLAGP(wwin
, emulate_appicon
);
859 flag
= WFLAGP(wwin
, focus_across_wksp
);
862 flag
= WFLAGP(wwin
, no_miniaturizable
);
864 #ifdef XKB_BUTTON_HINT
866 flag
= WFLAGP(wwin
, no_language_button
);
870 WMSetButtonSelected(panel
->moreChk
[i
], flag
);
872 if (panel
->appFrm
&& wapp
) {
873 for (i
= 0; i
< (sizeof(panel
->appChk
) / sizeof(panel
->appChk
[0])); i
++) {
878 flag
= WFLAGP(wapp
->main_window_desc
, start_hidden
);
881 flag
= WFLAGP(wapp
->main_window_desc
, no_appicon
);
884 flag
= WFLAGP(wapp
->main_window_desc
, shared_appicon
);
887 WMSetButtonSelected(panel
->appChk
[i
], flag
);
890 WMSetButtonSelected(panel
->alwChk
, WFLAGP(wwin
, always_user_icon
));
892 showIconFor(WMWidgetScreen(panel
->alwChk
), panel
, wm_instance
, wm_class
, REVERT_TO_DEFAULT
);
894 n
= wDefaultGetStartWorkspace(wwin
->screen_ptr
, wm_instance
, wm_class
);
896 if (n
>= 0 && n
< wwin
->screen_ptr
->workspace_count
)
897 WMSetPopUpButtonSelectedItem(panel
->wsP
, n
+ 1);
899 WMSetPopUpButtonSelectedItem(panel
->wsP
, 0);
901 /* must auto apply, so that there wno't be internal
902 * inconsistencies between the state in the flags and
903 * the actual state of the window */
904 applySettings(panel
->applyBtn
, panel
);
907 static void chooseIconCallback(WMWidget
*self
, void *clientData
)
910 InspectorPanel
*panel
= (InspectorPanel
*) clientData
;
913 panel
->choosingIcon
= 1;
915 WMSetButtonEnabled(panel
->browseIconBtn
, False
);
917 result
= wIconChooserDialog(panel
->frame
->screen_ptr
, &file
,
918 panel
->inspected
->wm_instance
,
919 panel
->inspected
->wm_class
);
921 panel
->choosingIcon
= 0;
923 if (!panel
->destroyed
) { /* kluge */
925 WMSetTextFieldText(panel
->fileText
, file
);
926 showIconFor(WMWidgetScreen(self
), panel
, NULL
, NULL
, USE_TEXT_FIELD
);
929 WMSetButtonEnabled(panel
->browseIconBtn
, True
);
931 freeInspector(panel
);
935 static void textEditedObserver(void *observerData
, WMNotification
*notification
)
937 InspectorPanel
*panel
= (InspectorPanel
*) observerData
;
939 if ((long)WMGetNotificationClientData(notification
) != WMReturnTextMovement
)
942 showIconFor(WMWidgetScreen(panel
->win
), panel
, NULL
, NULL
, USE_TEXT_FIELD
);
945 static void selectSpecification(WMWidget
*bPtr
, void *data
)
947 InspectorPanel
*panel
= (InspectorPanel
*) data
;
949 WWindow
*wwin
= panel
->inspected
;
952 if (bPtr
== panel
->defaultRb
&& (wwin
->wm_instance
|| wwin
->wm_class
))
953 WMSetButtonEnabled(panel
->applyBtn
, False
);
955 WMSetButtonEnabled(panel
->applyBtn
, True
);
957 len
= 16 + strlen(wwin
->wm_instance
? wwin
->wm_instance
: "?")
958 + strlen(wwin
->wm_class
? wwin
->wm_class
: "?");
962 snprintf(str
, len
, _("Inspecting %s.%s"),
963 wwin
->wm_instance
? wwin
->wm_instance
: "?", wwin
->wm_class
? wwin
->wm_class
: "?");
965 wFrameWindowChangeTitle(panel
->frame
->frame
, str
);
970 static void selectWindow(WMWidget
*bPtr
, void *data
)
972 InspectorPanel
*panel
= (InspectorPanel
*) data
;
973 WWindow
*wwin
= panel
->inspected
;
974 WScreen
*scr
= wwin
->screen_ptr
;
978 if (XGrabPointer(dpy
, scr
->root_win
, True
,
979 ButtonPressMask
, GrabModeAsync
, GrabModeAsync
, None
,
980 wCursor
[WCUR_SELECT
], CurrentTime
) != GrabSuccess
) {
981 wwarning("could not grab mouse pointer");
985 WMSetLabelText(panel
->specLbl
, _("Click in the window you wish to inspect."));
986 WMMaskEvent(dpy
, ButtonPressMask
, &event
);
987 XUngrabPointer(dpy
, CurrentTime
);
989 iwin
= wWindowFor(event
.xbutton
.subwindow
);
990 if (iwin
&& !iwin
->flags
.internal_window
&& iwin
!= wwin
&& !iwin
->flags
.inspector_open
) {
991 iwin
->flags
.inspector_open
= 1;
992 iwin
->inspector
= createInspectorForWindow(iwin
,
993 panel
->frame
->frame_x
, panel
->frame
->frame_y
, True
);
994 wCloseInspectorForWindow(wwin
);
996 WMSetLabelText(panel
->specLbl
, spec_text
);
1000 static InspectorPanel
*createInspectorForWindow(WWindow
*wwin
, int xpos
, int ypos
, Bool showSelectPanel
)
1002 WScreen
*scr
= wwin
->screen_ptr
;
1003 InspectorPanel
*panel
;
1005 char *str
= NULL
, *tmp
= NULL
;
1006 int x
, y
, btn_width
, frame_width
;
1007 WMButton
*selectedBtn
= NULL
;
1009 spec_text
= _("The configuration will apply to all\n"
1010 "windows that have their WM_CLASS\n"
1011 "property set to the above selected\n" "name, when saved.");
1013 panel
= wmalloc(sizeof(InspectorPanel
));
1014 memset(panel
, 0, sizeof(InspectorPanel
));
1016 panel
->destroyed
= 0;
1017 panel
->inspected
= wwin
;
1018 panel
->nextPtr
= panelList
;
1020 panel
->win
= WMCreateWindow(scr
->wmscreen
, "windowInspector");
1021 WMResizeWidget(panel
->win
, PWIDTH
, PHEIGHT
);
1023 /**** create common stuff ****/
1024 /* command buttons */
1025 btn_width
= (PWIDTH
- (2 * 15) - (2 * 10)) / 3;
1026 panel
->saveBtn
= WMCreateCommandButton(panel
->win
);
1027 WMSetButtonAction(panel
->saveBtn
, (WMAction
*) saveSettings
, panel
);
1028 WMMoveWidget(panel
->saveBtn
, (2 * (btn_width
+ 10)) + 15, PHEIGHT
- 40);
1029 WMSetButtonText(panel
->saveBtn
, _("Save"));
1030 WMResizeWidget(panel
->saveBtn
, btn_width
, 28);
1031 if (wPreferences
.flags
.noupdates
|| !(wwin
->wm_class
|| wwin
->wm_instance
))
1032 WMSetButtonEnabled(panel
->saveBtn
, False
);
1034 panel
->applyBtn
= WMCreateCommandButton(panel
->win
);
1035 WMSetButtonAction(panel
->applyBtn
, (WMAction
*) applySettings
, panel
);
1036 WMMoveWidget(panel
->applyBtn
, btn_width
+ 10 + 15, PHEIGHT
- 40);
1037 WMSetButtonText(panel
->applyBtn
, _("Apply"));
1038 WMResizeWidget(panel
->applyBtn
, btn_width
, 28);
1040 panel
->revertBtn
= WMCreateCommandButton(panel
->win
);
1041 WMSetButtonAction(panel
->revertBtn
, (WMAction
*) revertSettings
, panel
);
1042 WMMoveWidget(panel
->revertBtn
, 15, PHEIGHT
- 40);
1043 WMSetButtonText(panel
->revertBtn
, _("Reload"));
1044 WMResizeWidget(panel
->revertBtn
, btn_width
, 28);
1046 /* page selection popup button */
1047 panel
->pagePopUp
= WMCreatePopUpButton(panel
->win
);
1048 WMSetPopUpButtonAction(panel
->pagePopUp
, (WMAction
*) changePage
, panel
);
1049 WMMoveWidget(panel
->pagePopUp
, 25, 15);
1050 WMResizeWidget(panel
->pagePopUp
, PWIDTH
- 50, 20);
1052 WMAddPopUpButtonItem(panel
->pagePopUp
, _("Window Specification"));
1053 WMAddPopUpButtonItem(panel
->pagePopUp
, _("Window Attributes"));
1054 WMAddPopUpButtonItem(panel
->pagePopUp
, _("Advanced Options"));
1055 WMAddPopUpButtonItem(panel
->pagePopUp
, _("Icon and Initial Workspace"));
1056 WMAddPopUpButtonItem(panel
->pagePopUp
, _("Application Specific"));
1058 /**** window spec ****/
1059 frame_width
= PWIDTH
- (2 * 15);
1061 panel
->specFrm
= WMCreateFrame(panel
->win
);
1062 WMSetFrameTitle(panel
->specFrm
, _("Window Specification"));
1063 WMMoveWidget(panel
->specFrm
, 15, 65);
1064 WMResizeWidget(panel
->specFrm
, frame_width
, 145);
1066 panel
->defaultRb
= WMCreateRadioButton(panel
->specFrm
);
1067 WMMoveWidget(panel
->defaultRb
, 10, 78);
1068 WMResizeWidget(panel
->defaultRb
, frame_width
- (2 * 10), 20);
1069 WMSetButtonText(panel
->defaultRb
, _("Defaults for all windows"));
1070 WMSetButtonSelected(panel
->defaultRb
, False
);
1071 WMSetButtonAction(panel
->defaultRb
, selectSpecification
, panel
);
1073 if (wwin
->wm_class
&& wwin
->wm_instance
) {
1074 tmp
= wstrconcat(wwin
->wm_instance
, ".");
1075 str
= wstrconcat(tmp
, wwin
->wm_class
);
1077 panel
->bothRb
= WMCreateRadioButton(panel
->specFrm
);
1078 WMMoveWidget(panel
->bothRb
, 10, 18);
1079 WMResizeWidget(panel
->bothRb
, frame_width
- (2 * 10), 20);
1080 WMSetButtonText(panel
->bothRb
, str
);
1083 WMGroupButtons(panel
->defaultRb
, panel
->bothRb
);
1086 selectedBtn
= panel
->bothRb
;
1088 WMSetButtonAction(panel
->bothRb
, selectSpecification
, panel
);
1091 if (wwin
->wm_instance
) {
1092 panel
->instRb
= WMCreateRadioButton(panel
->specFrm
);
1093 WMMoveWidget(panel
->instRb
, 10, 38);
1094 WMResizeWidget(panel
->instRb
, frame_width
- (2 * 10), 20);
1095 WMSetButtonText(panel
->instRb
, wwin
->wm_instance
);
1096 WMGroupButtons(panel
->defaultRb
, panel
->instRb
);
1099 selectedBtn
= panel
->instRb
;
1101 WMSetButtonAction(panel
->instRb
, selectSpecification
, panel
);
1104 if (wwin
->wm_class
) {
1105 panel
->clsRb
= WMCreateRadioButton(panel
->specFrm
);
1106 WMMoveWidget(panel
->clsRb
, 10, 58);
1107 WMResizeWidget(panel
->clsRb
, frame_width
- (2 * 10), 20);
1108 WMSetButtonText(panel
->clsRb
, wwin
->wm_class
);
1109 WMGroupButtons(panel
->defaultRb
, panel
->clsRb
);
1112 selectedBtn
= panel
->clsRb
;
1114 WMSetButtonAction(panel
->clsRb
, selectSpecification
, panel
);
1117 panel
->selWinB
= WMCreateCommandButton(panel
->specFrm
);
1118 WMMoveWidget(panel
->selWinB
, 20, 145 - 24 - 10);
1119 WMResizeWidget(panel
->selWinB
, frame_width
- 2 * 10 - 20, 24);
1120 WMSetButtonText(panel
->selWinB
, _("Select window"));
1121 WMSetButtonAction(panel
->selWinB
, selectWindow
, panel
);
1123 panel
->specLbl
= WMCreateLabel(panel
->win
);
1124 WMMoveWidget(panel
->specLbl
, 15, 210);
1125 WMResizeWidget(panel
->specLbl
, frame_width
, 100);
1126 WMSetLabelText(panel
->specLbl
, spec_text
);
1127 WMSetLabelWraps(panel
->specLbl
, True
);
1129 WMSetLabelTextAlignment(panel
->specLbl
, WALeft
);
1131 /**** attributes ****/
1132 create_tab_window_attributes(wwin
, panel
, frame_width
);
1133 create_tab_window_advanced(wwin
, panel
, frame_width
);
1134 create_tab_icon_workspace(wwin
, panel
, frame_width
);
1135 create_tab_app_specific(wwin
, panel
, frame_width
);
1137 /* if the window is a transient, don't let it have a miniaturize button */
1138 if (wwin
->transient_for
!= None
&& wwin
->transient_for
!= scr
->root_win
)
1139 WMSetButtonEnabled(panel
->attrChk
[3], False
);
1141 WMSetButtonEnabled(panel
->attrChk
[3], True
);
1143 if (!wwin
->wm_class
&& !wwin
->wm_instance
)
1144 WMSetPopUpButtonItemEnabled(panel
->pagePopUp
, 0, False
);
1146 WMRealizeWidget(panel
->win
);
1148 WMMapSubwidgets(panel
->win
);
1149 WMMapSubwidgets(panel
->specFrm
);
1150 WMMapSubwidgets(panel
->attrFrm
);
1151 WMMapSubwidgets(panel
->moreFrm
);
1152 WMMapSubwidgets(panel
->iconFrm
);
1153 WMMapSubwidgets(panel
->wsFrm
);
1155 WMMapSubwidgets(panel
->appFrm
);
1157 if (showSelectPanel
) {
1158 WMSetPopUpButtonSelectedItem(panel
->pagePopUp
, 0);
1159 changePage(panel
->pagePopUp
, panel
);
1161 WMSetPopUpButtonSelectedItem(panel
->pagePopUp
, 1);
1162 changePage(panel
->pagePopUp
, panel
);
1165 parent
= XCreateSimpleWindow(dpy
, scr
->root_win
, 0, 0, PWIDTH
, PHEIGHT
, 0, 0, 0);
1166 XSelectInput(dpy
, parent
, KeyPressMask
| KeyReleaseMask
);
1167 panel
->parent
= parent
;
1168 XReparentWindow(dpy
, WMWidgetXID(panel
->win
), parent
, 0, 0);
1170 WMMapWidget(panel
->win
);
1172 XSetTransientForHint(dpy
, parent
, wwin
->client_win
);
1174 if (xpos
== UNDEFINED_POS
) {
1175 x
= wwin
->frame_x
+ wwin
->frame
->core
->width
/ 2;
1176 y
= wwin
->frame_y
+ wwin
->frame
->top_width
* 2;
1177 if (y
+ PHEIGHT
> scr
->scr_height
)
1178 y
= scr
->scr_height
- PHEIGHT
- 30;
1179 if (x
+ PWIDTH
> scr
->scr_width
)
1180 x
= scr
->scr_width
- PWIDTH
;
1186 panel
->frame
= wManageInternalWindow(scr
, parent
, wwin
->client_win
, "Inspector", x
, y
, PWIDTH
, PHEIGHT
);
1189 selectedBtn
= panel
->defaultRb
;
1191 WMSetButtonSelected(selectedBtn
, True
);
1192 selectSpecification(selectedBtn
, panel
);
1194 /* kluge to know who should get the key events */
1195 panel
->frame
->client_leader
= WMWidgetXID(panel
->win
);
1197 WSETUFLAG(panel
->frame
, no_closable
, 0);
1198 WSETUFLAG(panel
->frame
, no_close_button
, 0);
1199 wWindowUpdateButtonImages(panel
->frame
);
1200 wFrameWindowShowButton(panel
->frame
->frame
, WFF_RIGHT_BUTTON
);
1201 panel
->frame
->frame
->on_click_right
= destroyInspector
;
1203 wWindowMap(panel
->frame
);
1205 showIconFor(WMWidgetScreen(panel
->alwChk
), panel
, wwin
->wm_instance
, wwin
->wm_class
, UPDATE_TEXT_FIELD
);
1210 void wShowInspectorForWindow(WWindow
*wwin
)
1212 if (wwin
->flags
.inspector_open
)
1215 WMSetBalloonEnabled(wwin
->screen_ptr
->wmscreen
, wPreferences
.help_balloon
);
1218 wwin
->flags
.inspector_open
= 1;
1219 wwin
->inspector
= createInspectorForWindow(wwin
, UNDEFINED_POS
, UNDEFINED_POS
, False
);
1222 void wHideInspectorForWindow(WWindow
*wwin
)
1224 WWindow
*pwin
= wwin
->inspector
->frame
;
1227 pwin
->flags
.hidden
= 1;
1229 wClientSetState(pwin
, IconicState
, None
);
1232 void wUnhideInspectorForWindow(WWindow
*wwin
)
1234 WWindow
*pwin
= wwin
->inspector
->frame
;
1236 pwin
->flags
.hidden
= 0;
1237 pwin
->flags
.mapped
= 1;
1238 XMapWindow(dpy
, pwin
->client_win
);
1239 XMapWindow(dpy
, pwin
->frame
->core
->window
);
1240 wClientSetState(pwin
, NormalState
, None
);
1243 WWindow
*wGetWindowOfInspectorForWindow(WWindow
*wwin
)
1245 if (!wwin
->inspector
)
1248 assert(wwin
->flags
.inspector_open
!= 0);
1249 return wwin
->inspector
->frame
;
1252 void wCloseInspectorForWindow(WWindow
*wwin
)
1254 WWindow
*pwin
= wwin
->inspector
->frame
; /* the inspector window */
1256 (*pwin
->frame
->on_click_right
) (NULL
, pwin
, NULL
);
1259 static void create_tab_window_attributes(WWindow
*wwin
, InspectorPanel
*panel
, int frame_width
)
1262 char *caption
= NULL
, *descr
= NULL
;
1265 panel
->attrFrm
= WMCreateFrame(panel
->win
);
1266 WMSetFrameTitle(panel
->attrFrm
, _("Attributes"));
1267 WMMoveWidget(panel
->attrFrm
, 15, 45);
1268 WMResizeWidget(panel
->attrFrm
, frame_width
, 250);
1270 for (i
= 0; i
< (sizeof(panel
->attrChk
) / sizeof(panel
->attrChk
[0])); i
++) {
1273 caption
= _("Disable titlebar");
1274 flag
= WFLAGP(wwin
, no_titlebar
);
1275 descr
= _("Remove the titlebar of this window.\n"
1276 "To access the window commands menu of a window\n"
1277 "without it's titlebar, press Control+Esc (or the\n"
1278 "equivalent shortcut, if you changed the default\n" "settings).");
1281 caption
= _("Disable resizebar");
1282 flag
= WFLAGP(wwin
, no_resizebar
);
1283 descr
= _("Remove the resizebar of this window.");
1286 caption
= _("Disable close button");
1287 flag
= WFLAGP(wwin
, no_close_button
);
1288 descr
= _("Remove the `close window' button of this window.");
1291 caption
= _("Disable miniaturize button");
1292 flag
= WFLAGP(wwin
, no_miniaturize_button
);
1293 descr
= _("Remove the `miniaturize window' button of the window.");
1296 caption
= _("Disable border");
1297 flag
= WFLAGP(wwin
, no_border
);
1298 descr
= _("Remove the 1 pixel black border around the window.");
1301 caption
= _("Keep on top (floating)");
1302 flag
= WFLAGP(wwin
, floating
);
1303 descr
= _("Keep the window over other windows, not allowing\n" "them to cover it.");
1306 caption
= _("Keep at bottom (sunken)");
1307 flag
= WFLAGP(wwin
, sunken
);
1308 descr
= _("Keep the window under all other windows.");
1311 caption
= _("Omnipresent");
1312 flag
= WFLAGP(wwin
, omnipresent
);
1313 descr
= _("Make window present in all workspaces.");
1316 caption
= _("Start miniaturized");
1317 flag
= WFLAGP(wwin
, start_miniaturized
);
1318 descr
= _("Make the window be automatically miniaturized when it's\n" "first shown.");
1321 caption
= _("Start maximized");
1322 flag
= WFLAGP(wwin
, start_maximized
!= 0);
1323 descr
= _("Make the window be automatically maximized when it's\n" "first shown.");
1326 caption
= _("Full screen maximization");
1327 flag
= WFLAGP(wwin
, full_maximize
);
1328 descr
= _("Make the window use the whole screen space when it's\n"
1329 "maximized. The titlebar and resizebar will be moved\n"
1330 "to outside the screen.");
1333 panel
->attrChk
[i
] = WMCreateSwitchButton(panel
->attrFrm
);
1334 WMMoveWidget(panel
->attrChk
[i
], 10, 20 * (i
+ 1));
1335 WMResizeWidget(panel
->attrChk
[i
], frame_width
- 15, 20);
1336 WMSetButtonSelected(panel
->attrChk
[i
], flag
);
1337 WMSetButtonText(panel
->attrChk
[i
], caption
);
1339 WMSetBalloonTextForView(descr
, WMWidgetView(panel
->attrChk
[i
]));
1343 static void create_tab_window_advanced(WWindow
*wwin
, InspectorPanel
*panel
, int frame_width
)
1346 char *caption
= NULL
, *descr
= NULL
;
1349 panel
->moreFrm
= WMCreateFrame(panel
->win
);
1350 WMSetFrameTitle(panel
->moreFrm
, _("Advanced"));
1351 WMMoveWidget(panel
->moreFrm
, 15, 45);
1352 WMResizeWidget(panel
->moreFrm
, frame_width
, 265);
1354 for (i
= 0; i
< (sizeof(panel
->moreChk
) / sizeof(panel
->moreChk
[0])); i
++) {
1357 caption
= _("Do not bind keyboard shortcuts");
1358 flag
= WFLAGP(wwin
, no_bind_keys
);
1359 descr
= _("Do not bind keyboard shortcuts from Window Maker\n"
1360 "when this window is focused. This will allow the\n"
1361 "window to receive all key combinations regardless\n"
1362 "of your shortcut configuration.");
1365 caption
= _("Do not bind mouse clicks");
1366 flag
= WFLAGP(wwin
, no_bind_mouse
);
1367 descr
= _("Do not bind mouse actions, such as `Alt'+drag\n"
1368 "in the window (when alt is the modifier you have\n" "configured).");
1371 caption
= _("Do not show in the window list");
1372 flag
= WFLAGP(wwin
, skip_window_list
);
1373 descr
= _("Do not list the window in the window list menu.");
1376 caption
= _("Do not show in the switch panel");
1377 flag
= WFLAGP(wwin
, skip_switchpanel
);
1378 descr
= _("Do not include in switchpanel while alternating windows.");
1381 caption
= _("Do not let it take focus");
1382 flag
= WFLAGP(wwin
, no_focusable
);
1383 descr
= _("Do not let the window take keyboard focus when you\n" "click on it.");
1386 caption
= _("Keep inside screen");
1387 flag
= WFLAGP(wwin
, dont_move_off
);
1388 descr
= _("Do not allow the window to move itself completely\n"
1389 "outside the screen. For bug compatibility.\n");
1392 caption
= _("Ignore 'Hide Others'");
1393 flag
= WFLAGP(wwin
, no_hide_others
);
1394 descr
= _("Do not hide the window when issuing the\n" "`HideOthers' command.");
1397 caption
= _("Ignore 'Save Session'");
1398 flag
= WFLAGP(wwin
, dont_save_session
);
1399 descr
= _("Do not save the associated application in the\n"
1400 "session's state, so that it won't be restarted\n"
1401 "together with other applications when Window Maker\n" "starts.");
1404 caption
= _("Emulate application icon");
1405 flag
= WFLAGP(wwin
, emulate_appicon
);
1406 descr
= _("Make this window act as an application that provides\n"
1407 "enough information to Window Maker for a dockable\n"
1408 "application icon to be created.");
1411 caption
= _("Focus across workspaces");
1412 flag
= WFLAGP(wwin
, focus_across_wksp
);
1413 descr
= _("Allow Window Maker to switch workspace to satisfy\n"
1414 "a focus request (annoying).");
1417 caption
= _("Do not let it be minimized");
1418 flag
= WFLAGP(wwin
, no_miniaturizable
);
1419 descr
= _("Do not let the window of this application be\n"
1422 #ifdef XKB_BUTTON_HINT
1424 caption
= _("Disable language button");
1425 flag
= WFLAGP(wwin
, no_language_button
);
1426 descr
= _("Remove the `toggle language' button of the window.");
1430 panel
->moreChk
[i
] = WMCreateSwitchButton(panel
->moreFrm
);
1431 WMMoveWidget(panel
->moreChk
[i
], 10, 20 * (i
+ 1));
1432 WMResizeWidget(panel
->moreChk
[i
], frame_width
- 15, 20);
1433 WMSetButtonSelected(panel
->moreChk
[i
], flag
);
1434 WMSetButtonText(panel
->moreChk
[i
], caption
);
1436 WMSetBalloonTextForView(descr
, WMWidgetView(panel
->moreChk
[i
]));
1440 static void create_tab_icon_workspace(WWindow
*wwin
, InspectorPanel
*panel
, int frame_width
)
1442 WScreen
*scr
= wwin
->screen_ptr
;
1445 /* miniwindow/workspace */
1446 panel
->iconFrm
= WMCreateFrame(panel
->win
);
1447 WMMoveWidget(panel
->iconFrm
, 15, 50);
1448 WMResizeWidget(panel
->iconFrm
, PWIDTH
- (2 * 15), 170);
1449 WMSetFrameTitle(panel
->iconFrm
, _("Miniwindow Image"));
1451 panel
->iconLbl
= WMCreateLabel(panel
->iconFrm
);
1452 WMMoveWidget(panel
->iconLbl
, PWIDTH
- (2 * 15) - 22 - 64, 20);
1453 WMResizeWidget(panel
->iconLbl
, 64, 64);
1454 WMSetLabelRelief(panel
->iconLbl
, WRGroove
);
1455 WMSetLabelImagePosition(panel
->iconLbl
, WIPImageOnly
);
1457 panel
->browseIconBtn
= WMCreateCommandButton(panel
->iconFrm
);
1458 WMSetButtonAction(panel
->browseIconBtn
, chooseIconCallback
, panel
);
1459 WMMoveWidget(panel
->browseIconBtn
, 22, 32);
1460 WMResizeWidget(panel
->browseIconBtn
, 120, 26);
1461 WMSetButtonText(panel
->browseIconBtn
, _("Browse..."));
1463 panel
->fileLbl
= WMCreateLabel(panel
->iconFrm
);
1464 WMMoveWidget(panel
->fileLbl
, 20, 85);
1465 WMResizeWidget(panel
->fileLbl
, PWIDTH
- (2 * 15) - (2 * 20), 14);
1466 WMSetLabelText(panel
->fileLbl
, _("Icon filename:"));
1468 panel
->fileText
= WMCreateTextField(panel
->iconFrm
);
1469 WMMoveWidget(panel
->fileText
, 20, 105);
1470 WMResizeWidget(panel
->fileText
, PWIDTH
- (2 * 20) - (2 * 15), 20);
1471 WMSetTextFieldText(panel
->fileText
, NULL
);
1472 WMAddNotificationObserver(textEditedObserver
, panel
, WMTextDidEndEditingNotification
, panel
->fileText
);
1474 panel
->alwChk
= WMCreateSwitchButton(panel
->iconFrm
);
1475 WMMoveWidget(panel
->alwChk
, 20, 130);
1476 WMResizeWidget(panel
->alwChk
, PWIDTH
- (2 * 15) - (2 * 15), 30);
1477 WMSetButtonText(panel
->alwChk
, _("Ignore client supplied icon"));
1478 WMSetButtonSelected(panel
->alwChk
, WFLAGP(wwin
, always_user_icon
));
1480 panel
->wsFrm
= WMCreateFrame(panel
->win
);
1481 WMMoveWidget(panel
->wsFrm
, 15, 225);
1482 WMResizeWidget(panel
->wsFrm
, PWIDTH
- (2 * 15), 70);
1483 WMSetFrameTitle(panel
->wsFrm
, _("Initial Workspace"));
1485 WMSetBalloonTextForView(_("The workspace to place the window when it's"
1486 "first shown."), WMWidgetView(panel
->wsFrm
));
1488 panel
->wsP
= WMCreatePopUpButton(panel
->wsFrm
);
1489 WMMoveWidget(panel
->wsP
, 20, 30);
1490 WMResizeWidget(panel
->wsP
, PWIDTH
- (2 * 15) - (2 * 20), 20);
1491 WMAddPopUpButtonItem(panel
->wsP
, _("Nowhere in particular"));
1493 for (i
= 0; i
< wwin
->screen_ptr
->workspace_count
; i
++)
1494 WMAddPopUpButtonItem(panel
->wsP
, scr
->workspaces
[i
]->name
);
1496 i
= wDefaultGetStartWorkspace(wwin
->screen_ptr
, wwin
->wm_instance
, wwin
->wm_class
);
1497 if (i
>= 0 && i
<= wwin
->screen_ptr
->workspace_count
)
1498 WMSetPopUpButtonSelectedItem(panel
->wsP
, i
+ 1);
1500 WMSetPopUpButtonSelectedItem(panel
->wsP
, 0);
1503 static void create_tab_app_specific(WWindow
*wwin
, InspectorPanel
*panel
, int frame_width
)
1505 WScreen
*scr
= wwin
->screen_ptr
;
1506 int i
= 0, flag
= 0, tmp
;
1507 char *caption
= NULL
, *descr
= NULL
;
1510 if (wwin
->main_window
!= None
) {
1511 WApplication
*wapp
= wApplicationOf(wwin
->main_window
);
1513 panel
->appFrm
= WMCreateFrame(panel
->win
);
1514 WMSetFrameTitle(panel
->appFrm
, _("Application Attributes"));
1515 WMMoveWidget(panel
->appFrm
, 15, 50);
1516 WMResizeWidget(panel
->appFrm
, frame_width
, 240);
1518 for (i
= 0; i
< (sizeof(panel
->appChk
) / sizeof(panel
->appChk
[0])); i
++) {
1521 caption
= _("Start hidden");
1522 flag
= WFLAGP(wapp
->main_window_desc
, start_hidden
);
1523 descr
= _("Automatically hide application when it's started.");
1526 caption
= _("No application icon");
1527 flag
= WFLAGP(wapp
->main_window_desc
, no_appicon
);
1528 descr
= _("Disable the application icon for the application.\n"
1529 "Note that you won't be able to dock it anymore,\n"
1530 "and any icons that are already docked will stop\n"
1531 "working correctly.");
1534 caption
= _("Shared application icon");
1535 flag
= WFLAGP(wapp
->main_window_desc
, shared_appicon
);
1536 descr
= _("Use a single shared application icon for all of\n"
1537 "the instances of this application.\n");
1540 panel
->appChk
[i
] = WMCreateSwitchButton(panel
->appFrm
);
1541 WMMoveWidget(panel
->appChk
[i
], 10, 20 * (i
+ 1));
1542 WMResizeWidget(panel
->appChk
[i
], 205, 20);
1543 WMSetButtonSelected(panel
->appChk
[i
], flag
);
1544 WMSetButtonText(panel
->appChk
[i
], caption
);
1545 WMSetBalloonTextForView(descr
, WMWidgetView(panel
->appChk
[i
]));
1548 if (WFLAGP(wwin
, emulate_appicon
)) {
1549 WMSetButtonEnabled(panel
->appChk
[1], False
);
1550 WMSetButtonEnabled(panel
->moreChk
[7], True
);
1552 WMSetButtonEnabled(panel
->appChk
[1], True
);
1553 WMSetButtonEnabled(panel
->moreChk
[7], False
);
1556 if ((wwin
->transient_for
!= None
&& wwin
->transient_for
!= scr
->root_win
)
1557 || !wwin
->wm_class
|| !wwin
->wm_instance
)
1562 WMSetButtonEnabled(panel
->moreChk
[7], tmp
);
1564 WMSetPopUpButtonItemEnabled(panel
->pagePopUp
, 4, False
);
1565 panel
->appFrm
= NULL
;