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 typedef struct InspectorPanel
{
54 struct InspectorPanel
*nextPtr
;
58 WWindow
*inspected
; /* the window that's being inspected */
69 WMPopUpButton
*pagePopUp
;
71 /* first page. general stuff */
83 /* second page. attributes */
86 WMButton
*attrChk
[11];
88 /* 3rd page. more attributes */
90 #ifdef XKB_BUTTON_HINT
91 WMButton
*moreChk
[12];
93 WMButton
*moreChk
[11];
96 /* 4th page. icon and workspace */
100 WMTextField
*fileText
;
103 WMButton *updateIconBtn;
105 WMButton
*browseIconBtn
;
110 /* 5th page. application wide attributes */
115 unsigned int destroyed
:1;
116 unsigned int choosingIcon
:1;
119 extern Cursor wCursor
[WCUR_LAST
];
120 extern WDDomain
*WDWindowAttributes
;
121 extern WPreferences wPreferences
;
123 static InspectorPanel
*panelList
= NULL
;
124 static WMPropList
*ANoTitlebar
= NULL
;
125 static WMPropList
*ANoResizebar
;
126 static WMPropList
*ANoMiniaturizeButton
;
127 static WMPropList
*ANoCloseButton
;
128 static WMPropList
*ANoBorder
;
129 static WMPropList
*ANoHideOthers
;
130 static WMPropList
*ANoMouseBindings
;
131 static WMPropList
*ANoKeyBindings
;
132 static WMPropList
*ANoAppIcon
;
133 static WMPropList
*AKeepOnTop
;
134 static WMPropList
*AKeepOnBottom
;
135 static WMPropList
*AOmnipresent
;
136 static WMPropList
*ASkipWindowList
;
137 static WMPropList
*ASkipSwitchPanel
;
138 static WMPropList
*AKeepInsideScreen
;
139 static WMPropList
*AUnfocusable
;
140 static WMPropList
*AFocusAcrossWorkspace
;
141 static WMPropList
*AAlwaysUserIcon
;
142 static WMPropList
*AStartMiniaturized
;
143 static WMPropList
*AStartMaximized
;
144 static WMPropList
*ADontSaveSession
;
145 static WMPropList
*AEmulateAppIcon
;
146 static WMPropList
*AFullMaximize
;
147 static WMPropList
*ASharedAppIcon
;
148 static WMPropList
*ANoMiniaturizable
;
149 #ifdef XKB_BUTTON_HINT
150 static WMPropList
*ANoLanguageButton
;
152 static WMPropList
*AStartWorkspace
;
153 static WMPropList
*AIcon
;
155 /* application wide options */
156 static WMPropList
*AStartHidden
;
157 static WMPropList
*AnyWindow
;
158 static WMPropList
*EmptyString
;
159 static WMPropList
*Yes
, *No
;
164 static char *spec_text
;
165 static void applySettings(WMButton
*button
, InspectorPanel
*panel
);
167 #define UNDEFINED_POS 0xffffff
169 static InspectorPanel
*createInspectorForWindow(WWindow
*wwin
, int xpos
, int ypos
, Bool showSelectPanel
);
171 static void make_keys(void)
173 if (ANoTitlebar
!= NULL
)
176 AIcon
= WMCreatePLString("Icon");
177 ANoTitlebar
= WMCreatePLString("NoTitlebar");
178 ANoResizebar
= WMCreatePLString("NoResizebar");
179 ANoMiniaturizeButton
= WMCreatePLString("NoMiniaturizeButton");
180 ANoCloseButton
= WMCreatePLString("NoCloseButton");
181 ANoBorder
= WMCreatePLString("NoBorder");
182 ANoHideOthers
= WMCreatePLString("NoHideOthers");
183 ANoMouseBindings
= WMCreatePLString("NoMouseBindings");
184 ANoKeyBindings
= WMCreatePLString("NoKeyBindings");
185 ANoAppIcon
= WMCreatePLString("NoAppIcon");
186 AKeepOnTop
= WMCreatePLString("KeepOnTop");
187 AKeepOnBottom
= WMCreatePLString("KeepOnBottom");
188 AOmnipresent
= WMCreatePLString("Omnipresent");
189 ASkipWindowList
= WMCreatePLString("SkipWindowList");
190 ASkipSwitchPanel
= WMCreatePLString("SkipSwitchPanel");
191 AKeepInsideScreen
= WMCreatePLString("KeepInsideScreen");
192 AUnfocusable
= WMCreatePLString("Unfocusable");
193 AFocusAcrossWorkspace
= WMCreatePLString("FocusAcrossWorkspace");
194 AAlwaysUserIcon
= WMCreatePLString("AlwaysUserIcon");
195 AStartMiniaturized
= WMCreatePLString("StartMiniaturized");
196 AStartMaximized
= WMCreatePLString("StartMaximized");
197 AStartHidden
= WMCreatePLString("StartHidden");
198 ADontSaveSession
= WMCreatePLString("DontSaveSession");
199 AEmulateAppIcon
= WMCreatePLString("EmulateAppIcon");
200 AFullMaximize
= WMCreatePLString("FullMaximize");
201 ASharedAppIcon
= WMCreatePLString("SharedAppIcon");
202 ANoMiniaturizable
= WMCreatePLString("NoMiniaturizable");
203 #ifdef XKB_BUTTON_HINT
204 ANoLanguageButton
= WMCreatePLString("NoLanguageButton");
207 AStartWorkspace
= WMCreatePLString("StartWorkspace");
209 AnyWindow
= WMCreatePLString("*");
210 EmptyString
= WMCreatePLString("");
211 Yes
= WMCreatePLString("Yes");
212 No
= WMCreatePLString("No");
215 static void freeInspector(InspectorPanel
*panel
)
217 panel
->destroyed
= 1;
219 if (panel
->choosingIcon
)
222 WMDestroyWidget(panel
->win
);
223 XDestroyWindow(dpy
, panel
->parent
);
227 static void destroyInspector(WCoreWindow
*foo
, void *data
, XEvent
*event
)
229 InspectorPanel
*panel
;
233 while (panel
->frame
!= data
)
234 panel
= panel
->nextPtr
;
236 if (panelList
== panel
)
237 panelList
= panel
->nextPtr
;
240 while (tmp
->nextPtr
!= panel
) {
243 tmp
->nextPtr
= panel
->nextPtr
;
245 panel
->inspected
->flags
.inspector_open
= 0;
246 panel
->inspected
->inspector
= NULL
;
248 WMRemoveNotificationObserver(panel
);
250 wWindowUnmap(panel
->frame
);
251 wUnmanageWindow(panel
->frame
, True
, False
);
253 freeInspector(panel
);
256 void wDestroyInspectorPanels(void)
258 InspectorPanel
*panel
;
260 while (panelList
!= NULL
) {
262 panelList
= panelList
->nextPtr
;
263 wUnmanageWindow(panel
->frame
, False
, False
);
264 WMDestroyWidget(panel
->win
);
266 panel
->inspected
->flags
.inspector_open
= 0;
267 panel
->inspected
->inspector
= NULL
;
273 static void changePage(WMPopUpButton
*bPtr
, InspectorPanel
*panel
)
277 page
= WMGetPopUpButtonSelectedItem(bPtr
);
280 WMMapWidget(panel
->specFrm
);
281 WMMapWidget(panel
->specLbl
);
282 } else if (page
== 1) {
283 WMMapWidget(panel
->attrFrm
);
284 } else if (page
== 2) {
285 WMMapWidget(panel
->moreFrm
);
286 } else if (page
== 3) {
287 WMMapWidget(panel
->iconFrm
);
288 WMMapWidget(panel
->wsFrm
);
290 WMMapWidget(panel
->appFrm
);
294 WMUnmapWidget(panel
->specFrm
);
295 WMUnmapWidget(panel
->specLbl
);
298 WMUnmapWidget(panel
->attrFrm
);
300 WMUnmapWidget(panel
->moreFrm
);
302 WMUnmapWidget(panel
->iconFrm
);
303 WMUnmapWidget(panel
->wsFrm
);
305 if (page
!= 4 && panel
->appFrm
)
306 WMUnmapWidget(panel
->appFrm
);
309 #define USE_TEXT_FIELD 1
310 #define UPDATE_TEXT_FIELD 2
311 #define REVERT_TO_DEFAULT 4
313 static int showIconFor(WMScreen
*scrPtr
, InspectorPanel
*panel
, char *wm_instance
, char *wm_class
, int flags
)
315 WMPixmap
*pixmap
= (WMPixmap
*) NULL
;
316 char *file
= NULL
, *path
= NULL
;
317 char *db_icon
= NULL
;
319 if ((flags
& USE_TEXT_FIELD
) != 0) {
320 file
= WMGetTextFieldText(panel
->fileText
);
321 if (file
&& file
[0] == 0) {
326 db_icon
= wDefaultGetIconFile(wm_instance
, wm_class
, False
);
328 file
= wstrdup(db_icon
);
330 if (db_icon
!= NULL
&& (flags
& REVERT_TO_DEFAULT
) != 0) {
332 file
= wstrdup(db_icon
);
333 flags
|= UPDATE_TEXT_FIELD
;
336 if ((flags
& UPDATE_TEXT_FIELD
) != 0) {
337 WMSetTextFieldText(panel
->fileText
, file
);
341 path
= FindImage(wPreferences
.icon_path
, file
);
345 int len
= strlen(file
) + 80;
348 snprintf(buf
, len
, _("Could not find icon \"%s\" specified for this window"), file
);
349 wMessageDialog(panel
->frame
->screen_ptr
, _("Error"), buf
, _("OK"), NULL
, NULL
);
355 pixmap
= WMCreatePixmapFromFile(scrPtr
, path
);
360 int len
= strlen(file
) + 80;
363 snprintf(buf
, len
, _("Could not open specified icon \"%s\":%s"),
364 file
, RMessageForError(RErrorCode
));
365 wMessageDialog(panel
->frame
->screen_ptr
, _("Error"), buf
, _("OK"), NULL
, NULL
);
373 WMSetLabelImage(panel
->iconLbl
, pixmap
);
375 WMReleasePixmap(pixmap
);
381 static void updateIcon(WMButton
* button
, InspectorPanel
* panel
)
383 showIconFor(WMWidgetScreen(button
), panel
, NULL
, NULL
, USE_TEXT_FIELD
);
387 static int getBool(WMPropList
*value
)
391 if (!WMIsPLString(value
)) {
394 if (!(val
= WMGetFromPLString(value
))) {
398 if ((val
[1] == '\0' && (val
[0] == 'y' || val
[0] == 'Y' || val
[0] == 'T' || val
[0] == 't' || val
[0] == '1'))
399 || (strcasecmp(val
, "YES") == 0 || strcasecmp(val
, "TRUE") == 0)) {
402 } else if ((val
[1] == '\0'
403 && (val
[0] == 'n' || val
[0] == 'N' || val
[0] == 'F' || val
[0] == 'f' || val
[0] == '0'))
404 || (strcasecmp(val
, "NO") == 0 || strcasecmp(val
, "FALSE") == 0)) {
408 wwarning(_("can't convert \"%s\" to boolean"), val
);
413 #define UPDATE_DEFAULTS 1
417 * Will insert the attribute = value; pair in window's list,
418 * if it's different from the defaults.
419 * Defaults means either defaults database, or attributes saved
420 * for the default window "*". This is to let one revert options that are
421 * global because they were saved for all windows ("*").
426 insertAttribute(WMPropList
*dict
, WMPropList
*window
, WMPropList
*attr
, WMPropList
*value
, int flags
)
428 WMPropList
*def_win
, *def_value
= NULL
;
432 if (!(flags
& UPDATE_DEFAULTS
) && dict
) {
433 if ((def_win
= WMGetFromPLDictionary(dict
, AnyWindow
)) != NULL
) {
434 def_value
= WMGetFromPLDictionary(def_win
, attr
);
438 /* If we could not find defaults in database, fall to hardcoded values.
439 * Also this is true if we save defaults for all windows
442 def_value
= ((flags
& IS_BOOLEAN
) != 0) ? No
: EmptyString
;
444 if ((flags
& IS_BOOLEAN
))
445 update
= (getBool(value
) != getBool(def_value
));
447 update
= !WMIsPropListEqualTo(value
, def_value
);
451 WMPutInPLDictionary(window
, attr
, value
);
458 static void saveSettings(WMButton
*button
, InspectorPanel
*panel
)
460 WWindow
*wwin
= panel
->inspected
;
461 WDDomain
*db
= WDWindowAttributes
;
462 WMPropList
*dict
= db
->dictionary
;
463 WMPropList
*winDic
, *appDic
, *value
, *key
, *key2
;
466 int different
= 0, different2
= 0;
468 /* Save will apply the changes and save them */
469 applySettings(panel
->applyBtn
, panel
);
471 if (WMGetButtonSelected(panel
->instRb
) != 0)
472 key
= WMCreatePLString(wwin
->wm_instance
);
473 else if (WMGetButtonSelected(panel
->clsRb
) != 0)
474 key
= WMCreatePLString(wwin
->wm_class
);
475 else if (WMGetButtonSelected(panel
->bothRb
) != 0) {
478 buffer
= StrConcatDot(wwin
->wm_instance
, wwin
->wm_class
);
479 key
= WMCreatePLString(buffer
);
481 } else if (WMGetButtonSelected(panel
->defaultRb
) != 0) {
482 key
= WMRetainPropList(AnyWindow
);
483 flags
= UPDATE_DEFAULTS
;
491 dict
= WMCreatePLDictionary(NULL
, NULL
);
493 db
->dictionary
= dict
;
495 WMReleasePropList(key
);
500 if (showIconFor(WMWidgetScreen(button
), panel
, NULL
, NULL
, USE_TEXT_FIELD
) < 0)
503 WMPLSetCaseSensitive(True
);
505 winDic
= WMCreatePLDictionary(NULL
, NULL
);
506 appDic
= WMCreatePLDictionary(NULL
, NULL
);
508 /* Update icon for window */
509 icon_file
= WMGetTextFieldText(panel
->fileText
);
511 if (icon_file
[0] != 0) {
512 value
= WMCreatePLString(icon_file
);
513 different
|= insertAttribute(dict
, winDic
, AIcon
, value
, flags
);
514 different2
|= insertAttribute(dict
, appDic
, AIcon
, value
, flags
);
515 WMReleasePropList(value
);
521 int i
= WMGetPopUpButtonSelectedItem(panel
->wsP
);
525 if (i
>= 0 && i
< panel
->frame
->screen_ptr
->workspace_count
) {
526 value
= WMCreatePLString(panel
->frame
->screen_ptr
->workspaces
[i
]->name
);
527 different
|= insertAttribute(dict
, winDic
, AStartWorkspace
, value
, flags
);
528 WMReleasePropList(value
);
534 value
= (WMGetButtonSelected(panel
->alwChk
) != 0) ? Yes
: No
;
535 different
|= insertAttribute(dict
, winDic
, AAlwaysUserIcon
, value
, flags
);
537 value
= (WMGetButtonSelected(panel
->attrChk
[0]) != 0) ? Yes
: No
;
538 different
|= insertAttribute(dict
, winDic
, ANoTitlebar
, value
, flags
);
540 value
= (WMGetButtonSelected(panel
->attrChk
[1]) != 0) ? Yes
: No
;
541 different
|= insertAttribute(dict
, winDic
, ANoResizebar
, value
, flags
);
543 value
= (WMGetButtonSelected(panel
->attrChk
[2]) != 0) ? Yes
: No
;
544 different
|= insertAttribute(dict
, winDic
, ANoCloseButton
, value
, flags
);
546 value
= (WMGetButtonSelected(panel
->attrChk
[3]) != 0) ? Yes
: No
;
547 different
|= insertAttribute(dict
, winDic
, ANoMiniaturizeButton
, value
, flags
);
549 value
= (WMGetButtonSelected(panel
->attrChk
[4]) != 0) ? Yes
: No
;
550 different
|= insertAttribute(dict
, winDic
, ANoBorder
, value
, flags
);
552 value
= (WMGetButtonSelected(panel
->attrChk
[5]) != 0) ? Yes
: No
;
553 different
|= insertAttribute(dict
, winDic
, AKeepOnTop
, value
, flags
);
555 value
= (WMGetButtonSelected(panel
->attrChk
[6]) != 0) ? Yes
: No
;
556 different
|= insertAttribute(dict
, winDic
, AKeepOnBottom
, value
, flags
);
558 value
= (WMGetButtonSelected(panel
->attrChk
[7]) != 0) ? Yes
: No
;
559 different
|= insertAttribute(dict
, winDic
, AOmnipresent
, value
, flags
);
561 value
= (WMGetButtonSelected(panel
->attrChk
[8]) != 0) ? Yes
: No
;
562 different
|= insertAttribute(dict
, winDic
, AStartMiniaturized
, value
, flags
);
564 value
= (WMGetButtonSelected(panel
->attrChk
[9]) != 0) ? Yes
: No
;
565 different
|= insertAttribute(dict
, winDic
, AStartMaximized
, value
, flags
);
567 value
= (WMGetButtonSelected(panel
->attrChk
[10]) != 0) ? Yes
: No
;
568 different
|= insertAttribute(dict
, winDic
, AFullMaximize
, value
, flags
);
570 value
= (WMGetButtonSelected(panel
->moreChk
[0]) != 0) ? Yes
: No
;
571 different
|= insertAttribute(dict
, winDic
, ANoKeyBindings
, value
, flags
);
573 value
= (WMGetButtonSelected(panel
->moreChk
[1]) != 0) ? Yes
: No
;
574 different
|= insertAttribute(dict
, winDic
, ANoMouseBindings
, value
, flags
);
576 value
= (WMGetButtonSelected(panel
->moreChk
[2]) != 0) ? Yes
: No
;
577 different
|= insertAttribute(dict
, winDic
, ASkipWindowList
, value
, flags
);
579 value
= (WMGetButtonSelected(panel
->moreChk
[3]) != 0) ? Yes
: No
;
580 different
|= insertAttribute(dict
, winDic
, ASkipSwitchPanel
, value
, flags
);
582 value
= (WMGetButtonSelected(panel
->moreChk
[4]) != 0) ? Yes
: No
;
583 different
|= insertAttribute(dict
, winDic
, AUnfocusable
, value
, flags
);
585 value
= (WMGetButtonSelected(panel
->moreChk
[5]) != 0) ? Yes
: No
;
586 different
|= insertAttribute(dict
, winDic
, AKeepInsideScreen
, value
, flags
);
588 value
= (WMGetButtonSelected(panel
->moreChk
[6]) != 0) ? Yes
: No
;
589 different
|= insertAttribute(dict
, winDic
, ANoHideOthers
, value
, flags
);
591 value
= (WMGetButtonSelected(panel
->moreChk
[7]) != 0) ? Yes
: No
;
592 different
|= insertAttribute(dict
, winDic
, ADontSaveSession
, value
, flags
);
594 value
= (WMGetButtonSelected(panel
->moreChk
[8]) != 0) ? Yes
: No
;
595 different
|= insertAttribute(dict
, winDic
, AEmulateAppIcon
, value
, flags
);
597 value
= (WMGetButtonSelected(panel
->moreChk
[9]) != 0) ? Yes
: No
;
598 different
|= insertAttribute(dict
, winDic
, AFocusAcrossWorkspace
, value
, flags
);
600 value
= (WMGetButtonSelected(panel
->moreChk
[10]) != 0) ? Yes
: No
;
601 different
|= insertAttribute(dict
, winDic
, ANoMiniaturizable
, value
, flags
);
603 #ifdef XKB_BUTTON_HINT
604 value
= (WMGetButtonSelected(panel
->moreChk
[11]) != 0) ? Yes
: No
;
605 different
|= insertAttribute(dict
, winDic
, ANoLanguageButton
, value
, flags
);
608 if (wwin
->main_window
!= None
&& wApplicationOf(wwin
->main_window
) != NULL
) {
609 value
= (WMGetButtonSelected(panel
->appChk
[0]) != 0) ? Yes
: No
;
610 different2
|= insertAttribute(dict
, appDic
, AStartHidden
, value
, flags
);
612 value
= (WMGetButtonSelected(panel
->appChk
[1]) != 0) ? Yes
: No
;
613 different2
|= insertAttribute(dict
, appDic
, ANoAppIcon
, value
, flags
);
615 value
= (WMGetButtonSelected(panel
->appChk
[2]) != 0) ? Yes
: No
;
616 different2
|= insertAttribute(dict
, appDic
, ASharedAppIcon
, value
, flags
);
619 if (wwin
->fake_group
) {
620 key2
= WMCreatePLString(wwin
->fake_group
->identifier
);
621 if (WMIsPropListEqualTo(key
, key2
)) {
622 WMMergePLDictionaries(winDic
, appDic
, True
);
623 different
|= different2
;
625 WMRemoveFromPLDictionary(dict
, key2
);
627 WMPutInPLDictionary(dict
, key2
, appDic
);
630 WMReleasePropList(key2
);
631 WMReleasePropList(appDic
);
632 } else if (wwin
->main_window
!= wwin
->client_win
) {
633 WApplication
*wapp
= wApplicationOf(wwin
->main_window
);
636 char *instance
= wapp
->main_window_desc
->wm_instance
;
637 char *class = wapp
->main_window_desc
->wm_class
;
640 buffer
= StrConcatDot(instance
, class);
641 key2
= WMCreatePLString(buffer
);
644 if (WMIsPropListEqualTo(key
, key2
)) {
645 WMMergePLDictionaries(winDic
, appDic
, True
);
646 different
|= different2
;
648 WMRemoveFromPLDictionary(dict
, key2
);
650 WMPutInPLDictionary(dict
, key2
, appDic
);
652 WMReleasePropList(key2
);
653 WMReleasePropList(appDic
);
656 WMMergePLDictionaries(winDic
, appDic
, True
);
657 different
|= different2
;
658 WMReleasePropList(appDic
);
661 WMRemoveFromPLDictionary(dict
, key
);
663 WMPutInPLDictionary(dict
, key
, winDic
);
666 WMReleasePropList(key
);
667 WMReleasePropList(winDic
);
669 UpdateDomainFile(db
);
672 WMPLSetCaseSensitive(False
);
675 static void applySettings(WMButton
*button
, InspectorPanel
*panel
)
677 WWindow
*wwin
= panel
->inspected
;
678 WApplication
*wapp
= wApplicationOf(wwin
->main_window
);
679 int floating
, sunken
, skip_window_list
;
681 int old_no_bind_keys
;
682 int old_no_bind_mouse
;
684 old_omnipresent
= WFLAGP(wwin
, omnipresent
);
685 old_no_bind_keys
= WFLAGP(wwin
, no_bind_keys
);
686 old_no_bind_mouse
= WFLAGP(wwin
, no_bind_mouse
);
688 showIconFor(WMWidgetScreen(button
), panel
, NULL
, NULL
, USE_TEXT_FIELD
);
690 /* Attributes... --> Window Attributes */
691 WSETUFLAG(wwin
, no_titlebar
, WMGetButtonSelected(panel
->attrChk
[0]));
692 WSETUFLAG(wwin
, no_resizebar
, WMGetButtonSelected(panel
->attrChk
[1]));
693 WSETUFLAG(wwin
, no_close_button
, WMGetButtonSelected(panel
->attrChk
[2]));
694 WSETUFLAG(wwin
, no_miniaturize_button
, WMGetButtonSelected(panel
->attrChk
[3]));
695 WSETUFLAG(wwin
, no_border
, WMGetButtonSelected(panel
->attrChk
[4]));
696 floating
= WMGetButtonSelected(panel
->attrChk
[5]);
697 sunken
= WMGetButtonSelected(panel
->attrChk
[6]);
698 WSETUFLAG(wwin
, omnipresent
, WMGetButtonSelected(panel
->attrChk
[7]));
699 WSETUFLAG(wwin
, start_miniaturized
, WMGetButtonSelected(panel
->attrChk
[8]));
700 WSETUFLAG(wwin
, start_maximized
, WMGetButtonSelected(panel
->attrChk
[9]));
701 WSETUFLAG(wwin
, full_maximize
, WMGetButtonSelected(panel
->attrChk
[10]));
703 /* Attributes... --> Advanced Options */
704 WSETUFLAG(wwin
, no_bind_keys
, WMGetButtonSelected(panel
->moreChk
[0]));
705 WSETUFLAG(wwin
, no_bind_mouse
, WMGetButtonSelected(panel
->moreChk
[1]));
706 skip_window_list
= WMGetButtonSelected(panel
->moreChk
[2]);
707 WSETUFLAG(wwin
, skip_switchpanel
, WMGetButtonSelected(panel
->moreChk
[3]));
708 WSETUFLAG(wwin
, no_focusable
, WMGetButtonSelected(panel
->moreChk
[4]));
709 WSETUFLAG(wwin
, dont_move_off
, WMGetButtonSelected(panel
->moreChk
[5]));
710 WSETUFLAG(wwin
, no_hide_others
, WMGetButtonSelected(panel
->moreChk
[6]));
711 WSETUFLAG(wwin
, dont_save_session
, WMGetButtonSelected(panel
->moreChk
[7]));
712 WSETUFLAG(wwin
, emulate_appicon
, WMGetButtonSelected(panel
->moreChk
[8]));
713 WSETUFLAG(wwin
, focus_across_wksp
, WMGetButtonSelected(panel
->moreChk
[9]));
714 WSETUFLAG(wwin
, no_miniaturizable
, WMGetButtonSelected(panel
->moreChk
[10]));
715 #ifdef XKB_BUTTON_HINT
716 WSETUFLAG(wwin
, no_language_button
, WMGetButtonSelected(panel
->moreChk
[11]));
718 WSETUFLAG(wwin
, always_user_icon
, WMGetButtonSelected(panel
->alwChk
));
720 if (WFLAGP(wwin
, no_titlebar
) && wwin
->flags
.shaded
)
721 wUnshadeWindow(wwin
);
723 WSETUFLAG(wwin
, no_shadeable
, WFLAGP(wwin
, no_titlebar
));
726 if (!WFLAGP(wwin
, floating
))
727 ChangeStackingLevel(wwin
->frame
->core
, WMFloatingLevel
);
729 if (!WFLAGP(wwin
, sunken
))
730 ChangeStackingLevel(wwin
->frame
->core
, WMSunkenLevel
);
732 if (WFLAGP(wwin
, floating
) || WFLAGP(wwin
, sunken
))
733 ChangeStackingLevel(wwin
->frame
->core
, WMNormalLevel
);
736 WSETUFLAG(wwin
, sunken
, sunken
);
737 WSETUFLAG(wwin
, floating
, floating
);
738 wwin
->flags
.omnipresent
= 0;
740 if (WFLAGP(wwin
, skip_window_list
) != skip_window_list
) {
741 WSETUFLAG(wwin
, skip_window_list
, skip_window_list
);
742 UpdateSwitchMenu(wwin
->screen_ptr
, wwin
, skip_window_list
? ACTION_REMOVE
: ACTION_ADD
);
744 if (WFLAGP(wwin
, omnipresent
) != old_omnipresent
) {
745 WMPostNotificationName(WMNChangedState
, wwin
, "omnipresent");
749 if (WFLAGP(wwin
, no_bind_keys
) != old_no_bind_keys
) {
750 if (WFLAGP(wwin
, no_bind_keys
)) {
751 XUngrabKey(dpy
, AnyKey
, AnyModifier
, wwin
->frame
->core
->window
);
753 wWindowSetKeyGrabs(wwin
);
757 if (WFLAGP(wwin
, no_bind_mouse
) != old_no_bind_mouse
) {
758 wWindowResetMouseGrabs(wwin
);
761 wwin
->frame
->flags
.need_texture_change
= 1;
762 wWindowConfigureBorders(wwin
);
763 wFrameWindowPaint(wwin
->frame
);
764 wNETWMUpdateActions(wwin
, False
);
767 * Can't apply emulate_appicon because it will probably cause problems.
770 /* do application wide stuff */
771 WSETUFLAG(wapp
->main_window_desc
, start_hidden
, WMGetButtonSelected(panel
->appChk
[0]));
773 WSETUFLAG(wapp
->main_window_desc
, no_appicon
, WMGetButtonSelected(panel
->appChk
[1]));
775 WSETUFLAG(wapp
->main_window_desc
, shared_appicon
, WMGetButtonSelected(panel
->appChk
[2]));
777 if (WFLAGP(wapp
->main_window_desc
, no_appicon
))
778 removeAppIconFor(wapp
);
780 makeAppIconFor(wapp
);
782 if (wapp
->app_icon
&& wapp
->main_window
== wwin
->client_win
) {
783 char *file
= WMGetTextFieldText(panel
->fileText
);
789 wIconChangeImageFile(wapp
->app_icon
->icon
, file
);
792 wAppIconPaint(wapp
->app_icon
);
797 static void revertSettings(WMButton
*button
, InspectorPanel
*panel
)
799 WWindow
*wwin
= panel
->inspected
;
800 WApplication
*wapp
= wApplicationOf(wwin
->main_window
);
802 char *wm_instance
= NULL
;
803 char *wm_class
= NULL
;
804 int workspace
, level
;
806 if (panel
->instRb
&& WMGetButtonSelected(panel
->instRb
) != 0)
807 wm_instance
= wwin
->wm_instance
;
808 else if (panel
->clsRb
&& WMGetButtonSelected(panel
->clsRb
) != 0)
809 wm_class
= wwin
->wm_class
;
810 else if (panel
->bothRb
&& WMGetButtonSelected(panel
->bothRb
) != 0) {
811 wm_instance
= wwin
->wm_instance
;
812 wm_class
= wwin
->wm_class
;
814 memset(&wwin
->defined_user_flags
, 0, sizeof(WWindowAttributes
));
815 memset(&wwin
->user_flags
, 0, sizeof(WWindowAttributes
));
816 memset(&wwin
->client_flags
, 0, sizeof(WWindowAttributes
));
818 wWindowSetupInitialAttributes(wwin
, &level
, &workspace
);
820 for (i
= 0; i
< (sizeof(panel
->attrChk
) / sizeof(panel
->attrChk
[0])); i
++) {
825 flag
= WFLAGP(wwin
, no_titlebar
);
828 flag
= WFLAGP(wwin
, no_resizebar
);
831 flag
= WFLAGP(wwin
, no_close_button
);
834 flag
= WFLAGP(wwin
, no_miniaturize_button
);
837 flag
= WFLAGP(wwin
, no_border
);
840 flag
= WFLAGP(wwin
, floating
);
843 flag
= WFLAGP(wwin
, sunken
);
846 flag
= WFLAGP(wwin
, omnipresent
);
849 flag
= WFLAGP(wwin
, start_miniaturized
);
852 flag
= WFLAGP(wwin
, start_maximized
!= 0);
855 flag
= WFLAGP(wwin
, full_maximize
);
858 WMSetButtonSelected(panel
->attrChk
[i
], flag
);
860 for (i
= 0; i
< (sizeof(panel
->moreChk
) / sizeof(panel
->moreChk
[0])); i
++) {
865 flag
= WFLAGP(wwin
, no_bind_keys
);
868 flag
= WFLAGP(wwin
, no_bind_mouse
);
871 flag
= WFLAGP(wwin
, skip_window_list
);
874 flag
= WFLAGP(wwin
, skip_switchpanel
);
877 flag
= WFLAGP(wwin
, no_focusable
);
880 flag
= WFLAGP(wwin
, dont_move_off
);
883 flag
= WFLAGP(wwin
, no_hide_others
);
886 flag
= WFLAGP(wwin
, dont_save_session
);
889 flag
= WFLAGP(wwin
, emulate_appicon
);
892 flag
= WFLAGP(wwin
, focus_across_wksp
);
895 flag
= WFLAGP(wwin
, no_miniaturizable
);
897 #ifdef XKB_BUTTON_HINT
899 flag
= WFLAGP(wwin
, no_language_button
);
903 WMSetButtonSelected(panel
->moreChk
[i
], flag
);
905 if (panel
->appFrm
&& wapp
) {
906 for (i
= 0; i
< (sizeof(panel
->appChk
) / sizeof(panel
->appChk
[0])); i
++) {
911 flag
= WFLAGP(wapp
->main_window_desc
, start_hidden
);
914 flag
= WFLAGP(wapp
->main_window_desc
, no_appicon
);
917 flag
= WFLAGP(wapp
->main_window_desc
, shared_appicon
);
920 WMSetButtonSelected(panel
->appChk
[i
], flag
);
923 WMSetButtonSelected(panel
->alwChk
, WFLAGP(wwin
, always_user_icon
));
925 showIconFor(WMWidgetScreen(panel
->alwChk
), panel
, wm_instance
, wm_class
, REVERT_TO_DEFAULT
);
927 n
= wDefaultGetStartWorkspace(wwin
->screen_ptr
, wm_instance
, wm_class
);
929 if (n
>= 0 && n
< wwin
->screen_ptr
->workspace_count
) {
930 WMSetPopUpButtonSelectedItem(panel
->wsP
, n
+ 1);
932 WMSetPopUpButtonSelectedItem(panel
->wsP
, 0);
935 /* must auto apply, so that there wno't be internal
936 * inconsistencies between the state in the flags and
937 * the actual state of the window */
938 applySettings(panel
->applyBtn
, panel
);
941 static void chooseIconCallback(WMWidget
*self
, void *clientData
)
944 InspectorPanel
*panel
= (InspectorPanel
*) clientData
;
947 panel
->choosingIcon
= 1;
949 WMSetButtonEnabled(panel
->browseIconBtn
, False
);
951 result
= wIconChooserDialog(panel
->frame
->screen_ptr
, &file
,
952 panel
->inspected
->wm_instance
, panel
->inspected
->wm_class
);
954 panel
->choosingIcon
= 0;
956 if (!panel
->destroyed
) { /* kluge */
958 WMSetTextFieldText(panel
->fileText
, file
);
959 showIconFor(WMWidgetScreen(self
), panel
, NULL
, NULL
, USE_TEXT_FIELD
);
962 WMSetButtonEnabled(panel
->browseIconBtn
, True
);
964 freeInspector(panel
);
968 static void textEditedObserver(void *observerData
, WMNotification
*notification
)
970 InspectorPanel
*panel
= (InspectorPanel
*) observerData
;
972 if ((long)WMGetNotificationClientData(notification
) != WMReturnTextMovement
)
975 showIconFor(WMWidgetScreen(panel
->win
), panel
, NULL
, NULL
, USE_TEXT_FIELD
);
977 WMPerformButtonClick(panel->updateIconBtn);
981 static void selectSpecification(WMWidget
*bPtr
, void *data
)
983 InspectorPanel
*panel
= (InspectorPanel
*) data
;
985 WWindow
*wwin
= panel
->inspected
;
988 if (bPtr
== panel
->defaultRb
&& (wwin
->wm_instance
|| wwin
->wm_class
))
989 WMSetButtonEnabled(panel
->applyBtn
, False
);
991 WMSetButtonEnabled(panel
->applyBtn
, True
);
993 len
= 16 + strlen(wwin
->wm_instance
? wwin
->wm_instance
: "?")
994 + strlen(wwin
->wm_class
? wwin
->wm_class
: "?");
998 snprintf(str
, len
, _("Inspecting %s.%s"),
999 wwin
->wm_instance
? wwin
->wm_instance
: "?", wwin
->wm_class
? wwin
->wm_class
: "?");
1001 wFrameWindowChangeTitle(panel
->frame
->frame
, str
);
1006 static void selectWindow(WMWidget
*bPtr
, void *data
)
1008 InspectorPanel
*panel
= (InspectorPanel
*) data
;
1009 WWindow
*wwin
= panel
->inspected
;
1010 WScreen
*scr
= wwin
->screen_ptr
;
1014 if (XGrabPointer(dpy
, scr
->root_win
, True
,
1015 ButtonPressMask
, GrabModeAsync
, GrabModeAsync
, None
,
1016 wCursor
[WCUR_SELECT
], CurrentTime
) != GrabSuccess
) {
1017 wwarning("could not grab mouse pointer");
1021 WMSetLabelText(panel
->specLbl
, _("Click in the window you wish to inspect."));
1023 WMMaskEvent(dpy
, ButtonPressMask
, &event
);
1025 XUngrabPointer(dpy
, CurrentTime
);
1027 iwin
= wWindowFor(event
.xbutton
.subwindow
);
1029 if (iwin
&& !iwin
->flags
.internal_window
&& iwin
!= wwin
&& !iwin
->flags
.inspector_open
) {
1031 iwin
->flags
.inspector_open
= 1;
1032 iwin
->inspector
= createInspectorForWindow(iwin
,
1033 panel
->frame
->frame_x
, panel
->frame
->frame_y
, True
);
1034 wCloseInspectorForWindow(wwin
);
1036 WMSetLabelText(panel
->specLbl
, spec_text
);
1040 static InspectorPanel
*createInspectorForWindow(WWindow
*wwin
, int xpos
, int ypos
, Bool showSelectPanel
)
1042 WScreen
*scr
= wwin
->screen_ptr
;
1043 InspectorPanel
*panel
;
1047 int btn_width
, frame_width
;
1048 WMButton
*selectedBtn
= NULL
;
1049 #ifdef wrong_behaviour
1053 spec_text
= _("The configuration will apply to all\n"
1054 "windows that have their WM_CLASS\n"
1055 "property set to the above selected\n" "name, when saved.");
1057 panel
= wmalloc(sizeof(InspectorPanel
));
1058 memset(panel
, 0, sizeof(InspectorPanel
));
1060 panel
->destroyed
= 0;
1062 panel
->inspected
= wwin
;
1064 panel
->nextPtr
= panelList
;
1067 panel
->win
= WMCreateWindow(scr
->wmscreen
, "windowInspector");
1068 WMResizeWidget(panel
->win
, PWIDTH
, PHEIGHT
);
1070 /**** create common stuff ****/
1072 /* command buttons */
1073 /* (PWIDTH - (left and right margin) - (btn interval)) / 3 */
1074 btn_width
= (PWIDTH
- (2 * 15) - (2 * 10)) / 3;
1075 panel
->saveBtn
= WMCreateCommandButton(panel
->win
);
1076 WMSetButtonAction(panel
->saveBtn
, (WMAction
*) saveSettings
, panel
);
1077 WMMoveWidget(panel
->saveBtn
, (2 * (btn_width
+ 10)) + 15, PHEIGHT
- 40);
1078 WMSetButtonText(panel
->saveBtn
, _("Save"));
1079 WMResizeWidget(panel
->saveBtn
, btn_width
, 28);
1080 if (wPreferences
.flags
.noupdates
|| !(wwin
->wm_class
|| wwin
->wm_instance
))
1081 WMSetButtonEnabled(panel
->saveBtn
, False
);
1083 panel
->applyBtn
= WMCreateCommandButton(panel
->win
);
1084 WMSetButtonAction(panel
->applyBtn
, (WMAction
*) applySettings
, panel
);
1085 WMMoveWidget(panel
->applyBtn
, btn_width
+ 10 + 15, PHEIGHT
- 40);
1086 WMSetButtonText(panel
->applyBtn
, _("Apply"));
1087 WMResizeWidget(panel
->applyBtn
, btn_width
, 28);
1089 panel
->revertBtn
= WMCreateCommandButton(panel
->win
);
1090 WMSetButtonAction(panel
->revertBtn
, (WMAction
*) revertSettings
, panel
);
1091 WMMoveWidget(panel
->revertBtn
, 15, PHEIGHT
- 40);
1092 WMSetButtonText(panel
->revertBtn
, _("Reload"));
1093 WMResizeWidget(panel
->revertBtn
, btn_width
, 28);
1095 /* page selection popup button */
1096 panel
->pagePopUp
= WMCreatePopUpButton(panel
->win
);
1097 WMSetPopUpButtonAction(panel
->pagePopUp
, (WMAction
*) changePage
, panel
);
1098 WMMoveWidget(panel
->pagePopUp
, 25, 15);
1099 WMResizeWidget(panel
->pagePopUp
, PWIDTH
- 50, 20);
1101 WMAddPopUpButtonItem(panel
->pagePopUp
, _("Window Specification"));
1102 WMAddPopUpButtonItem(panel
->pagePopUp
, _("Window Attributes"));
1103 WMAddPopUpButtonItem(panel
->pagePopUp
, _("Advanced Options"));
1104 WMAddPopUpButtonItem(panel
->pagePopUp
, _("Icon and Initial Workspace"));
1105 WMAddPopUpButtonItem(panel
->pagePopUp
, _("Application Specific"));
1107 /**** window spec ****/
1108 frame_width
= PWIDTH
- (2 * 15);
1110 panel
->specFrm
= WMCreateFrame(panel
->win
);
1111 WMSetFrameTitle(panel
->specFrm
, _("Window Specification"));
1112 WMMoveWidget(panel
->specFrm
, 15, 65);
1113 WMResizeWidget(panel
->specFrm
, frame_width
, 145);
1115 panel
->defaultRb
= WMCreateRadioButton(panel
->specFrm
);
1116 WMMoveWidget(panel
->defaultRb
, 10, 78);
1117 WMResizeWidget(panel
->defaultRb
, frame_width
- (2 * 10), 20);
1118 WMSetButtonText(panel
->defaultRb
, _("Defaults for all windows"));
1119 WMSetButtonSelected(panel
->defaultRb
, False
);
1120 WMSetButtonAction(panel
->defaultRb
, selectSpecification
, panel
);
1122 if (wwin
->wm_class
&& wwin
->wm_instance
) {
1125 tmp
= wstrconcat(wwin
->wm_instance
, ".");
1126 str
= wstrconcat(tmp
, wwin
->wm_class
);
1128 panel
->bothRb
= WMCreateRadioButton(panel
->specFrm
);
1129 WMMoveWidget(panel
->bothRb
, 10, 18);
1130 WMResizeWidget(panel
->bothRb
, frame_width
- (2 * 10), 20);
1131 WMSetButtonText(panel
->bothRb
, str
);
1134 WMGroupButtons(panel
->defaultRb
, panel
->bothRb
);
1137 selectedBtn
= panel
->bothRb
;
1139 WMSetButtonAction(panel
->bothRb
, selectSpecification
, panel
);
1142 if (wwin
->wm_instance
) {
1143 panel
->instRb
= WMCreateRadioButton(panel
->specFrm
);
1144 WMMoveWidget(panel
->instRb
, 10, 38);
1145 WMResizeWidget(panel
->instRb
, frame_width
- (2 * 10), 20);
1146 WMSetButtonText(panel
->instRb
, wwin
->wm_instance
);
1147 WMGroupButtons(panel
->defaultRb
, panel
->instRb
);
1150 selectedBtn
= panel
->instRb
;
1152 WMSetButtonAction(panel
->instRb
, selectSpecification
, panel
);
1155 if (wwin
->wm_class
) {
1156 panel
->clsRb
= WMCreateRadioButton(panel
->specFrm
);
1157 WMMoveWidget(panel
->clsRb
, 10, 58);
1158 WMResizeWidget(panel
->clsRb
, frame_width
- (2 * 10), 20);
1159 WMSetButtonText(panel
->clsRb
, wwin
->wm_class
);
1160 WMGroupButtons(panel
->defaultRb
, panel
->clsRb
);
1163 selectedBtn
= panel
->clsRb
;
1165 WMSetButtonAction(panel
->clsRb
, selectSpecification
, panel
);
1168 panel
->selWinB
= WMCreateCommandButton(panel
->specFrm
);
1169 WMMoveWidget(panel
->selWinB
, 20, 145 - 24 - 10);
1170 WMResizeWidget(panel
->selWinB
, frame_width
- 2 * 10 - 20, 24);
1171 WMSetButtonText(panel
->selWinB
, _("Select window"));
1172 WMSetButtonAction(panel
->selWinB
, selectWindow
, panel
);
1174 panel
->specLbl
= WMCreateLabel(panel
->win
);
1175 WMMoveWidget(panel
->specLbl
, 15, 210);
1176 WMResizeWidget(panel
->specLbl
, frame_width
, 100);
1177 WMSetLabelText(panel
->specLbl
, spec_text
);
1178 WMSetLabelWraps(panel
->specLbl
, True
);
1180 WMSetLabelTextAlignment(panel
->specLbl
, WALeft
);
1182 /**** attributes ****/
1183 panel
->attrFrm
= WMCreateFrame(panel
->win
);
1184 WMSetFrameTitle(panel
->attrFrm
, _("Attributes"));
1185 WMMoveWidget(panel
->attrFrm
, 15, 45);
1186 WMResizeWidget(panel
->attrFrm
, frame_width
, 250);
1188 for (i
= 0; i
< (sizeof(panel
->attrChk
) / sizeof(panel
->attrChk
[0])); i
++) {
1189 char *caption
= NULL
;
1195 caption
= _("Disable titlebar");
1196 flag
= WFLAGP(wwin
, no_titlebar
);
1197 descr
= _("Remove the titlebar of this window.\n"
1198 "To access the window commands menu of a window\n"
1199 "without it's titlebar, press Control+Esc (or the\n"
1200 "equivalent shortcut, if you changed the default\n" "settings).");
1203 caption
= _("Disable resizebar");
1204 flag
= WFLAGP(wwin
, no_resizebar
);
1205 descr
= _("Remove the resizebar of this window.");
1208 caption
= _("Disable close button");
1209 flag
= WFLAGP(wwin
, no_close_button
);
1210 descr
= _("Remove the `close window' button of this window.");
1213 caption
= _("Disable miniaturize button");
1214 flag
= WFLAGP(wwin
, no_miniaturize_button
);
1215 descr
= _("Remove the `miniaturize window' button of the window.");
1218 caption
= _("Disable border");
1219 flag
= WFLAGP(wwin
, no_border
);
1220 descr
= _("Remove the 1 pixel black border around the window.");
1223 caption
= _("Keep on top (floating)");
1224 flag
= WFLAGP(wwin
, floating
);
1225 descr
= _("Keep the window over other windows, not allowing\n" "them to cover it.");
1228 caption
= _("Keep at bottom (sunken)");
1229 flag
= WFLAGP(wwin
, sunken
);
1230 descr
= _("Keep the window under all other windows.");
1233 caption
= _("Omnipresent");
1234 flag
= WFLAGP(wwin
, omnipresent
);
1235 descr
= _("Make window present in all workspaces.");
1238 caption
= _("Start miniaturized");
1239 flag
= WFLAGP(wwin
, start_miniaturized
);
1240 descr
= _("Make the window be automatically miniaturized when it's\n" "first shown.");
1243 caption
= _("Start maximized");
1244 flag
= WFLAGP(wwin
, start_maximized
!= 0);
1245 descr
= _("Make the window be automatically maximized when it's\n" "first shown.");
1248 caption
= _("Full screen maximization");
1249 flag
= WFLAGP(wwin
, full_maximize
);
1250 descr
= _("Make the window use the whole screen space when it's\n"
1251 "maximized. The titlebar and resizebar will be moved\n"
1252 "to outside the screen.");
1255 panel
->attrChk
[i
] = WMCreateSwitchButton(panel
->attrFrm
);
1256 WMMoveWidget(panel
->attrChk
[i
], 10, 20 * (i
+ 1));
1257 WMResizeWidget(panel
->attrChk
[i
], frame_width
- 15, 20);
1258 WMSetButtonSelected(panel
->attrChk
[i
], flag
);
1259 WMSetButtonText(panel
->attrChk
[i
], caption
);
1261 WMSetBalloonTextForView(descr
, WMWidgetView(panel
->attrChk
[i
]));
1264 /**** more attributes ****/
1265 panel
->moreFrm
= WMCreateFrame(panel
->win
);
1266 WMSetFrameTitle(panel
->moreFrm
, _("Advanced"));
1267 WMMoveWidget(panel
->moreFrm
, 15, 45);
1268 WMResizeWidget(panel
->moreFrm
, frame_width
, 265);
1270 for (i
= 0; i
< (sizeof(panel
->moreChk
) / sizeof(panel
->moreChk
[0])); i
++) {
1271 char *caption
= NULL
;
1277 caption
= _("Do not bind keyboard shortcuts");
1278 flag
= WFLAGP(wwin
, no_bind_keys
);
1279 descr
= _("Do not bind keyboard shortcuts from Window Maker\n"
1280 "when this window is focused. This will allow the\n"
1281 "window to receive all key combinations regardless\n"
1282 "of your shortcut configuration.");
1285 caption
= _("Do not bind mouse clicks");
1286 flag
= WFLAGP(wwin
, no_bind_mouse
);
1287 descr
= _("Do not bind mouse actions, such as `Alt'+drag\n"
1288 "in the window (when alt is the modifier you have\n" "configured).");
1291 caption
= _("Do not show in the window list");
1292 flag
= WFLAGP(wwin
, skip_window_list
);
1293 descr
= _("Do not list the window in the window list menu.");
1296 caption
= _("Do not show in the switch panel");
1297 flag
= WFLAGP(wwin
, skip_switchpanel
);
1298 descr
= _("Do not include in switchpanel while alternating windows.");
1301 caption
= _("Do not let it take focus");
1302 flag
= WFLAGP(wwin
, no_focusable
);
1303 descr
= _("Do not let the window take keyboard focus when you\n" "click on it.");
1306 caption
= _("Keep inside screen");
1307 flag
= WFLAGP(wwin
, dont_move_off
);
1308 descr
= _("Do not allow the window to move itself completely\n"
1309 "outside the screen. For bug compatibility.\n");
1312 caption
= _("Ignore 'Hide Others'");
1313 flag
= WFLAGP(wwin
, no_hide_others
);
1314 descr
= _("Do not hide the window when issuing the\n" "`HideOthers' command.");
1317 caption
= _("Ignore 'Save Session'");
1318 flag
= WFLAGP(wwin
, dont_save_session
);
1319 descr
= _("Do not save the associated application in the\n"
1320 "session's state, so that it won't be restarted\n"
1321 "together with other applications when Window Maker\n" "starts.");
1324 caption
= _("Emulate application icon");
1325 flag
= WFLAGP(wwin
, emulate_appicon
);
1326 descr
= _("Make this window act as an application that provides\n"
1327 "enough information to Window Maker for a dockable\n"
1328 "application icon to be created.");
1331 caption
= _("Focus across workspaces");
1332 flag
= WFLAGP(wwin
, focus_across_wksp
);
1333 descr
= _("Allow Window Maker to switch workspace to satisfy\n"
1334 "a focus request (annoying).");
1337 caption
= _("Do not let it be minimized");
1338 flag
= WFLAGP(wwin
, no_miniaturizable
);
1339 descr
= _("Do not let the window of this application be\n"
1342 #ifdef XKB_BUTTON_HINT
1344 caption
= _("Disable language button");
1345 flag
= WFLAGP(wwin
, no_language_button
);
1346 descr
= _("Remove the `toggle language' button of the window.");
1350 panel
->moreChk
[i
] = WMCreateSwitchButton(panel
->moreFrm
);
1351 WMMoveWidget(panel
->moreChk
[i
], 10, 20 * (i
+ 1));
1352 WMResizeWidget(panel
->moreChk
[i
], frame_width
- 15, 20);
1353 WMSetButtonSelected(panel
->moreChk
[i
], flag
);
1354 WMSetButtonText(panel
->moreChk
[i
], caption
);
1356 WMSetBalloonTextForView(descr
, WMWidgetView(panel
->moreChk
[i
]));
1359 /* miniwindow/workspace */
1360 panel
->iconFrm
= WMCreateFrame(panel
->win
);
1361 WMMoveWidget(panel
->iconFrm
, 15, 50);
1362 WMResizeWidget(panel
->iconFrm
, PWIDTH
- (2 * 15), 170);
1363 WMSetFrameTitle(panel
->iconFrm
, _("Miniwindow Image"));
1365 panel
->iconLbl
= WMCreateLabel(panel
->iconFrm
);
1366 WMMoveWidget(panel
->iconLbl
, PWIDTH
- (2 * 15) - 22 - 64, 20);
1367 WMResizeWidget(panel
->iconLbl
, 64, 64);
1368 WMSetLabelRelief(panel
->iconLbl
, WRGroove
);
1369 WMSetLabelImagePosition(panel
->iconLbl
, WIPImageOnly
);
1371 panel
->browseIconBtn
= WMCreateCommandButton(panel
->iconFrm
);
1372 WMSetButtonAction(panel
->browseIconBtn
, chooseIconCallback
, panel
);
1373 WMMoveWidget(panel
->browseIconBtn
, 22, 32);
1374 WMResizeWidget(panel
->browseIconBtn
, 120, 26);
1375 WMSetButtonText(panel
->browseIconBtn
, _("Browse..."));
1377 #ifdef wrong_behaviour
1378 WMSetButtonImagePosition(panel
->updateIconBtn
, WIPRight
);
1379 pixmap
= WMGetSystemPixmap(scr
->wmscreen
, WSIReturnArrow
);
1380 WMSetButtonImage(panel
->updateIconBtn
, pixmap
);
1381 WMReleasePixmap(pixmap
);
1382 pixmap
= WMGetSystemPixmap(scr
->wmscreen
, WSIHighlightedReturnArrow
);
1383 WMSetButtonAltImage(panel
->updateIconBtn
, pixmap
);
1384 WMReleasePixmap(pixmap
);
1387 panel
->fileLbl
= WMCreateLabel(panel
->iconFrm
);
1388 WMMoveWidget(panel
->fileLbl
, 20, 85);
1389 WMResizeWidget(panel
->fileLbl
, PWIDTH
- (2 * 15) - (2 * 20), 14);
1390 WMSetLabelText(panel
->fileLbl
, _("Icon filename:"));
1392 panel
->fileText
= WMCreateTextField(panel
->iconFrm
);
1393 WMMoveWidget(panel
->fileText
, 20, 105);
1394 WMResizeWidget(panel
->fileText
, PWIDTH
- (2 * 20) - (2 * 15), 20);
1395 WMSetTextFieldText(panel
->fileText
, NULL
);
1396 WMAddNotificationObserver(textEditedObserver
, panel
, WMTextDidEndEditingNotification
, panel
->fileText
);
1398 panel
->alwChk
= WMCreateSwitchButton(panel
->iconFrm
);
1399 WMMoveWidget(panel
->alwChk
, 20, 130);
1400 WMResizeWidget(panel
->alwChk
, PWIDTH
- (2 * 15) - (2 * 15), 30);
1401 WMSetButtonText(panel
->alwChk
, _("Ignore client supplied icon"));
1402 WMSetButtonSelected(panel
->alwChk
, WFLAGP(wwin
, always_user_icon
));
1404 panel
->wsFrm
= WMCreateFrame(panel
->win
);
1405 WMMoveWidget(panel
->wsFrm
, 15, 225);
1406 WMResizeWidget(panel
->wsFrm
, PWIDTH
- (2 * 15), 70);
1407 WMSetFrameTitle(panel
->wsFrm
, _("Initial Workspace"));
1409 WMSetBalloonTextForView(_("The workspace to place the window when it's"
1410 "first shown."), WMWidgetView(panel
->wsFrm
));
1412 panel
->wsP
= WMCreatePopUpButton(panel
->wsFrm
);
1413 WMMoveWidget(panel
->wsP
, 20, 30);
1414 WMResizeWidget(panel
->wsP
, PWIDTH
- (2 * 15) - (2 * 20), 20);
1415 WMAddPopUpButtonItem(panel
->wsP
, _("Nowhere in particular"));
1417 for (i
= 0; i
< wwin
->screen_ptr
->workspace_count
; i
++)
1418 WMAddPopUpButtonItem(panel
->wsP
, scr
->workspaces
[i
]->name
);
1420 i
= wDefaultGetStartWorkspace(wwin
->screen_ptr
, wwin
->wm_instance
, wwin
->wm_class
);
1421 if (i
>= 0 && i
<= wwin
->screen_ptr
->workspace_count
)
1422 WMSetPopUpButtonSelectedItem(panel
->wsP
, i
+ 1);
1424 WMSetPopUpButtonSelectedItem(panel
->wsP
, 0);
1426 /* application wide attributes */
1427 if (wwin
->main_window
!= None
) {
1428 WApplication
*wapp
= wApplicationOf(wwin
->main_window
);
1430 panel
->appFrm
= WMCreateFrame(panel
->win
);
1431 WMSetFrameTitle(panel
->appFrm
, _("Application Attributes"));
1432 WMMoveWidget(panel
->appFrm
, 15, 50);
1433 WMResizeWidget(panel
->appFrm
, frame_width
, 240);
1435 for (i
= 0; i
< (sizeof(panel
->appChk
) / sizeof(panel
->appChk
[0])); i
++) {
1436 char *caption
= NULL
;
1442 caption
= _("Start hidden");
1443 flag
= WFLAGP(wapp
->main_window_desc
, start_hidden
);
1444 descr
= _("Automatically hide application when it's started.");
1447 caption
= _("No application icon");
1448 flag
= WFLAGP(wapp
->main_window_desc
, no_appicon
);
1449 descr
= _("Disable the application icon for the application.\n"
1450 "Note that you won't be able to dock it anymore,\n"
1451 "and any icons that are already docked will stop\n"
1452 "working correctly.");
1455 caption
= _("Shared application icon");
1456 flag
= WFLAGP(wapp
->main_window_desc
, shared_appicon
);
1457 descr
= _("Use a single shared application icon for all of\n"
1458 "the instances of this application.\n");
1461 panel
->appChk
[i
] = WMCreateSwitchButton(panel
->appFrm
);
1462 WMMoveWidget(panel
->appChk
[i
], 10, 20 * (i
+ 1));
1463 WMResizeWidget(panel
->appChk
[i
], 205, 20);
1464 WMSetButtonSelected(panel
->appChk
[i
], flag
);
1465 WMSetButtonText(panel
->appChk
[i
], caption
);
1466 WMSetBalloonTextForView(descr
, WMWidgetView(panel
->appChk
[i
]));
1469 if (WFLAGP(wwin
, emulate_appicon
)) {
1470 WMSetButtonEnabled(panel
->appChk
[1], False
);
1471 WMSetButtonEnabled(panel
->moreChk
[7], True
);
1473 WMSetButtonEnabled(panel
->appChk
[1], True
);
1474 WMSetButtonEnabled(panel
->moreChk
[7], False
);
1479 if ((wwin
->transient_for
!= None
&& wwin
->transient_for
!= scr
->root_win
)
1480 || !wwin
->wm_class
|| !wwin
->wm_instance
)
1484 WMSetButtonEnabled(panel
->moreChk
[7], tmp
);
1486 WMSetPopUpButtonItemEnabled(panel
->pagePopUp
, 4, False
);
1487 panel
->appFrm
= NULL
;
1490 /* if the window is a transient, don't let it have a miniaturize
1492 if (wwin
->transient_for
!= None
&& wwin
->transient_for
!= scr
->root_win
)
1493 WMSetButtonEnabled(panel
->attrChk
[3], False
);
1495 WMSetButtonEnabled(panel
->attrChk
[3], True
);
1497 if (!wwin
->wm_class
&& !wwin
->wm_instance
) {
1498 WMSetPopUpButtonItemEnabled(panel
->pagePopUp
, 0, False
);
1501 WMRealizeWidget(panel
->win
);
1503 WMMapSubwidgets(panel
->win
);
1504 WMMapSubwidgets(panel
->specFrm
);
1505 WMMapSubwidgets(panel
->attrFrm
);
1506 WMMapSubwidgets(panel
->moreFrm
);
1507 WMMapSubwidgets(panel
->iconFrm
);
1508 WMMapSubwidgets(panel
->wsFrm
);
1510 WMMapSubwidgets(panel
->appFrm
);
1512 if (showSelectPanel
) {
1513 WMSetPopUpButtonSelectedItem(panel
->pagePopUp
, 0);
1514 changePage(panel
->pagePopUp
, panel
);
1516 WMSetPopUpButtonSelectedItem(panel
->pagePopUp
, 1);
1517 changePage(panel
->pagePopUp
, panel
);
1520 parent
= XCreateSimpleWindow(dpy
, scr
->root_win
, 0, 0, PWIDTH
, PHEIGHT
, 0, 0, 0);
1521 XSelectInput(dpy
, parent
, KeyPressMask
| KeyReleaseMask
);
1522 panel
->parent
= parent
;
1523 XReparentWindow(dpy
, WMWidgetXID(panel
->win
), parent
, 0, 0);
1525 WMMapWidget(panel
->win
);
1527 XSetTransientForHint(dpy
, parent
, wwin
->client_win
);
1529 if (xpos
== UNDEFINED_POS
) {
1530 x
= wwin
->frame_x
+ wwin
->frame
->core
->width
/ 2;
1531 y
= wwin
->frame_y
+ wwin
->frame
->top_width
* 2;
1532 if (y
+ PHEIGHT
> scr
->scr_height
)
1533 y
= scr
->scr_height
- PHEIGHT
- 30;
1534 if (x
+ PWIDTH
> scr
->scr_width
)
1535 x
= scr
->scr_width
- PWIDTH
;
1541 panel
->frame
= wManageInternalWindow(scr
, parent
, wwin
->client_win
, "Inspector", x
, y
, PWIDTH
, PHEIGHT
);
1544 selectedBtn
= panel
->defaultRb
;
1546 WMSetButtonSelected(selectedBtn
, True
);
1548 selectSpecification(selectedBtn
, panel
);
1550 /* kluge to know who should get the key events */
1551 panel
->frame
->client_leader
= WMWidgetXID(panel
->win
);
1553 WSETUFLAG(panel
->frame
, no_closable
, 0);
1554 WSETUFLAG(panel
->frame
, no_close_button
, 0);
1555 wWindowUpdateButtonImages(panel
->frame
);
1556 wFrameWindowShowButton(panel
->frame
->frame
, WFF_RIGHT_BUTTON
);
1557 panel
->frame
->frame
->on_click_right
= destroyInspector
;
1559 wWindowMap(panel
->frame
);
1561 showIconFor(WMWidgetScreen(panel
->alwChk
), panel
, wwin
->wm_instance
, wwin
->wm_class
, UPDATE_TEXT_FIELD
);
1566 void wShowInspectorForWindow(WWindow
*wwin
)
1568 if (wwin
->flags
.inspector_open
)
1571 WMSetBalloonEnabled(wwin
->screen_ptr
->wmscreen
, wPreferences
.help_balloon
);
1574 wwin
->flags
.inspector_open
= 1;
1575 wwin
->inspector
= createInspectorForWindow(wwin
, UNDEFINED_POS
, UNDEFINED_POS
, False
);
1578 void wHideInspectorForWindow(WWindow
*wwin
)
1580 WWindow
*pwin
= wwin
->inspector
->frame
;
1583 pwin
->flags
.hidden
= 1;
1585 wClientSetState(pwin
, IconicState
, None
);
1588 void wUnhideInspectorForWindow(WWindow
*wwin
)
1590 WWindow
*pwin
= wwin
->inspector
->frame
;
1592 pwin
->flags
.hidden
= 0;
1593 pwin
->flags
.mapped
= 1;
1594 XMapWindow(dpy
, pwin
->client_win
);
1595 XMapWindow(dpy
, pwin
->frame
->core
->window
);
1596 wClientSetState(pwin
, NormalState
, None
);
1599 WWindow
*wGetWindowOfInspectorForWindow(WWindow
*wwin
)
1601 if (wwin
->inspector
) {
1602 assert(wwin
->flags
.inspector_open
!= 0);
1604 return wwin
->inspector
->frame
;
1609 void wCloseInspectorForWindow(WWindow
*wwin
)
1611 WWindow
*pwin
= wwin
->inspector
->frame
; /* the inspector window */
1613 (*pwin
->frame
->on_click_right
) (NULL
, pwin
, NULL
);