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 /* Get the application icon, default included */
327 db_icon
= wDefaultGetIconFile(wm_instance
, wm_class
, True
);
329 file
= wstrdup(db_icon
);
331 if (db_icon
!= NULL
&& (flags
& REVERT_TO_DEFAULT
) != 0) {
333 file
= wstrdup(db_icon
);
334 flags
|= UPDATE_TEXT_FIELD
;
337 if ((flags
& UPDATE_TEXT_FIELD
) != 0) {
338 WMSetTextFieldText(panel
->fileText
, file
);
342 path
= FindImage(wPreferences
.icon_path
, file
);
346 int len
= strlen(file
) + 80;
349 snprintf(buf
, len
, _("Could not find icon \"%s\" specified for this window"), file
);
350 wMessageDialog(panel
->frame
->screen_ptr
, _("Error"), buf
, _("OK"), NULL
, NULL
);
356 pixmap
= WMCreatePixmapFromFile(scrPtr
, path
);
361 int len
= strlen(file
) + 80;
364 snprintf(buf
, len
, _("Could not open specified icon \"%s\":%s"),
365 file
, RMessageForError(RErrorCode
));
366 wMessageDialog(panel
->frame
->screen_ptr
, _("Error"), buf
, _("OK"), NULL
, NULL
);
374 WMSetLabelImage(panel
->iconLbl
, pixmap
);
376 WMReleasePixmap(pixmap
);
382 static void updateIcon(WMButton
* button
, InspectorPanel
* panel
)
384 showIconFor(WMWidgetScreen(button
), panel
, NULL
, NULL
, USE_TEXT_FIELD
);
388 static int getBool(WMPropList
*value
)
392 if (!WMIsPLString(value
)) {
395 if (!(val
= WMGetFromPLString(value
))) {
399 if ((val
[1] == '\0' && (val
[0] == 'y' || val
[0] == 'Y' || val
[0] == 'T' || val
[0] == 't' || val
[0] == '1'))
400 || (strcasecmp(val
, "YES") == 0 || strcasecmp(val
, "TRUE") == 0)) {
403 } else if ((val
[1] == '\0'
404 && (val
[0] == 'n' || val
[0] == 'N' || val
[0] == 'F' || val
[0] == 'f' || val
[0] == '0'))
405 || (strcasecmp(val
, "NO") == 0 || strcasecmp(val
, "FALSE") == 0)) {
409 wwarning(_("can't convert \"%s\" to boolean"), val
);
414 #define UPDATE_DEFAULTS 1
418 * Will insert the attribute = value; pair in window's list,
419 * if it's different from the defaults.
420 * Defaults means either defaults database, or attributes saved
421 * for the default window "*". This is to let one revert options that are
422 * global because they were saved for all windows ("*").
427 insertAttribute(WMPropList
*dict
, WMPropList
*window
, WMPropList
*attr
, WMPropList
*value
, int flags
)
429 WMPropList
*def_win
, *def_value
= NULL
;
433 if (!(flags
& UPDATE_DEFAULTS
) && dict
) {
434 if ((def_win
= WMGetFromPLDictionary(dict
, AnyWindow
)) != NULL
) {
435 def_value
= WMGetFromPLDictionary(def_win
, attr
);
439 /* If we could not find defaults in database, fall to hardcoded values.
440 * Also this is true if we save defaults for all windows
443 def_value
= ((flags
& IS_BOOLEAN
) != 0) ? No
: EmptyString
;
445 if ((flags
& IS_BOOLEAN
))
446 update
= (getBool(value
) != getBool(def_value
));
448 update
= !WMIsPropListEqualTo(value
, def_value
);
452 WMPutInPLDictionary(window
, attr
, value
);
459 static void saveSettings(WMButton
*button
, InspectorPanel
*panel
)
461 WWindow
*wwin
= panel
->inspected
;
462 WDDomain
*db
= WDWindowAttributes
;
463 WMPropList
*dict
= db
->dictionary
;
464 WMPropList
*winDic
, *appDic
, *value
, *key
, *key2
;
467 int different
= 0, different2
= 0;
469 /* Save will apply the changes and save them */
470 applySettings(panel
->applyBtn
, panel
);
472 if (WMGetButtonSelected(panel
->instRb
) != 0)
473 key
= WMCreatePLString(wwin
->wm_instance
);
474 else if (WMGetButtonSelected(panel
->clsRb
) != 0)
475 key
= WMCreatePLString(wwin
->wm_class
);
476 else if (WMGetButtonSelected(panel
->bothRb
) != 0) {
479 buffer
= StrConcatDot(wwin
->wm_instance
, wwin
->wm_class
);
480 key
= WMCreatePLString(buffer
);
482 } else if (WMGetButtonSelected(panel
->defaultRb
) != 0) {
483 key
= WMRetainPropList(AnyWindow
);
484 flags
= UPDATE_DEFAULTS
;
492 dict
= WMCreatePLDictionary(NULL
, NULL
);
494 db
->dictionary
= dict
;
496 WMReleasePropList(key
);
501 if (showIconFor(WMWidgetScreen(button
), panel
, NULL
, NULL
, USE_TEXT_FIELD
) < 0)
504 WMPLSetCaseSensitive(True
);
506 winDic
= WMCreatePLDictionary(NULL
, NULL
);
507 appDic
= WMCreatePLDictionary(NULL
, NULL
);
509 /* Update icon for window */
510 icon_file
= WMGetTextFieldText(panel
->fileText
);
512 if (icon_file
[0] != 0) {
513 value
= WMCreatePLString(icon_file
);
514 different
|= insertAttribute(dict
, winDic
, AIcon
, value
, flags
);
515 different2
|= insertAttribute(dict
, appDic
, AIcon
, value
, flags
);
516 WMReleasePropList(value
);
522 int i
= WMGetPopUpButtonSelectedItem(panel
->wsP
);
526 if (i
>= 0 && i
< panel
->frame
->screen_ptr
->workspace_count
) {
527 value
= WMCreatePLString(panel
->frame
->screen_ptr
->workspaces
[i
]->name
);
528 different
|= insertAttribute(dict
, winDic
, AStartWorkspace
, value
, flags
);
529 WMReleasePropList(value
);
535 value
= (WMGetButtonSelected(panel
->alwChk
) != 0) ? Yes
: No
;
536 different
|= insertAttribute(dict
, winDic
, AAlwaysUserIcon
, value
, flags
);
538 value
= (WMGetButtonSelected(panel
->attrChk
[0]) != 0) ? Yes
: No
;
539 different
|= insertAttribute(dict
, winDic
, ANoTitlebar
, value
, flags
);
541 value
= (WMGetButtonSelected(panel
->attrChk
[1]) != 0) ? Yes
: No
;
542 different
|= insertAttribute(dict
, winDic
, ANoResizebar
, value
, flags
);
544 value
= (WMGetButtonSelected(panel
->attrChk
[2]) != 0) ? Yes
: No
;
545 different
|= insertAttribute(dict
, winDic
, ANoCloseButton
, value
, flags
);
547 value
= (WMGetButtonSelected(panel
->attrChk
[3]) != 0) ? Yes
: No
;
548 different
|= insertAttribute(dict
, winDic
, ANoMiniaturizeButton
, value
, flags
);
550 value
= (WMGetButtonSelected(panel
->attrChk
[4]) != 0) ? Yes
: No
;
551 different
|= insertAttribute(dict
, winDic
, ANoBorder
, value
, flags
);
553 value
= (WMGetButtonSelected(panel
->attrChk
[5]) != 0) ? Yes
: No
;
554 different
|= insertAttribute(dict
, winDic
, AKeepOnTop
, value
, flags
);
556 value
= (WMGetButtonSelected(panel
->attrChk
[6]) != 0) ? Yes
: No
;
557 different
|= insertAttribute(dict
, winDic
, AKeepOnBottom
, value
, flags
);
559 value
= (WMGetButtonSelected(panel
->attrChk
[7]) != 0) ? Yes
: No
;
560 different
|= insertAttribute(dict
, winDic
, AOmnipresent
, value
, flags
);
562 value
= (WMGetButtonSelected(panel
->attrChk
[8]) != 0) ? Yes
: No
;
563 different
|= insertAttribute(dict
, winDic
, AStartMiniaturized
, value
, flags
);
565 value
= (WMGetButtonSelected(panel
->attrChk
[9]) != 0) ? Yes
: No
;
566 different
|= insertAttribute(dict
, winDic
, AStartMaximized
, value
, flags
);
568 value
= (WMGetButtonSelected(panel
->attrChk
[10]) != 0) ? Yes
: No
;
569 different
|= insertAttribute(dict
, winDic
, AFullMaximize
, value
, flags
);
571 value
= (WMGetButtonSelected(panel
->moreChk
[0]) != 0) ? Yes
: No
;
572 different
|= insertAttribute(dict
, winDic
, ANoKeyBindings
, value
, flags
);
574 value
= (WMGetButtonSelected(panel
->moreChk
[1]) != 0) ? Yes
: No
;
575 different
|= insertAttribute(dict
, winDic
, ANoMouseBindings
, value
, flags
);
577 value
= (WMGetButtonSelected(panel
->moreChk
[2]) != 0) ? Yes
: No
;
578 different
|= insertAttribute(dict
, winDic
, ASkipWindowList
, value
, flags
);
580 value
= (WMGetButtonSelected(panel
->moreChk
[3]) != 0) ? Yes
: No
;
581 different
|= insertAttribute(dict
, winDic
, ASkipSwitchPanel
, value
, flags
);
583 value
= (WMGetButtonSelected(panel
->moreChk
[4]) != 0) ? Yes
: No
;
584 different
|= insertAttribute(dict
, winDic
, AUnfocusable
, value
, flags
);
586 value
= (WMGetButtonSelected(panel
->moreChk
[5]) != 0) ? Yes
: No
;
587 different
|= insertAttribute(dict
, winDic
, AKeepInsideScreen
, value
, flags
);
589 value
= (WMGetButtonSelected(panel
->moreChk
[6]) != 0) ? Yes
: No
;
590 different
|= insertAttribute(dict
, winDic
, ANoHideOthers
, value
, flags
);
592 value
= (WMGetButtonSelected(panel
->moreChk
[7]) != 0) ? Yes
: No
;
593 different
|= insertAttribute(dict
, winDic
, ADontSaveSession
, value
, flags
);
595 value
= (WMGetButtonSelected(panel
->moreChk
[8]) != 0) ? Yes
: No
;
596 different
|= insertAttribute(dict
, winDic
, AEmulateAppIcon
, value
, flags
);
598 value
= (WMGetButtonSelected(panel
->moreChk
[9]) != 0) ? Yes
: No
;
599 different
|= insertAttribute(dict
, winDic
, AFocusAcrossWorkspace
, value
, flags
);
601 value
= (WMGetButtonSelected(panel
->moreChk
[10]) != 0) ? Yes
: No
;
602 different
|= insertAttribute(dict
, winDic
, ANoMiniaturizable
, value
, flags
);
604 #ifdef XKB_BUTTON_HINT
605 value
= (WMGetButtonSelected(panel
->moreChk
[11]) != 0) ? Yes
: No
;
606 different
|= insertAttribute(dict
, winDic
, ANoLanguageButton
, value
, flags
);
609 if (wwin
->main_window
!= None
&& wApplicationOf(wwin
->main_window
) != NULL
) {
610 value
= (WMGetButtonSelected(panel
->appChk
[0]) != 0) ? Yes
: No
;
611 different2
|= insertAttribute(dict
, appDic
, AStartHidden
, value
, flags
);
613 value
= (WMGetButtonSelected(panel
->appChk
[1]) != 0) ? Yes
: No
;
614 different2
|= insertAttribute(dict
, appDic
, ANoAppIcon
, value
, flags
);
616 value
= (WMGetButtonSelected(panel
->appChk
[2]) != 0) ? Yes
: No
;
617 different2
|= insertAttribute(dict
, appDic
, ASharedAppIcon
, value
, flags
);
620 if (wwin
->fake_group
) {
621 key2
= WMCreatePLString(wwin
->fake_group
->identifier
);
622 if (WMIsPropListEqualTo(key
, key2
)) {
623 WMMergePLDictionaries(winDic
, appDic
, True
);
624 different
|= different2
;
626 WMRemoveFromPLDictionary(dict
, key2
);
628 WMPutInPLDictionary(dict
, key2
, appDic
);
631 WMReleasePropList(key2
);
632 WMReleasePropList(appDic
);
633 } else if (wwin
->main_window
!= wwin
->client_win
) {
634 WApplication
*wapp
= wApplicationOf(wwin
->main_window
);
637 char *instance
= wapp
->main_window_desc
->wm_instance
;
638 char *class = wapp
->main_window_desc
->wm_class
;
641 buffer
= StrConcatDot(instance
, class);
642 key2
= WMCreatePLString(buffer
);
645 if (WMIsPropListEqualTo(key
, key2
)) {
646 WMMergePLDictionaries(winDic
, appDic
, True
);
647 different
|= different2
;
649 WMRemoveFromPLDictionary(dict
, key2
);
651 WMPutInPLDictionary(dict
, key2
, appDic
);
653 WMReleasePropList(key2
);
654 WMReleasePropList(appDic
);
657 WMMergePLDictionaries(winDic
, appDic
, True
);
658 different
|= different2
;
659 WMReleasePropList(appDic
);
662 WMRemoveFromPLDictionary(dict
, key
);
664 WMPutInPLDictionary(dict
, key
, winDic
);
667 WMReleasePropList(key
);
668 WMReleasePropList(winDic
);
670 UpdateDomainFile(db
);
673 WMPLSetCaseSensitive(False
);
676 static void applySettings(WMButton
*button
, InspectorPanel
*panel
)
678 WWindow
*wwin
= panel
->inspected
;
679 WApplication
*wapp
= wApplicationOf(wwin
->main_window
);
680 int floating
, sunken
, skip_window_list
;
682 int old_no_bind_keys
;
683 int old_no_bind_mouse
;
685 old_omnipresent
= WFLAGP(wwin
, omnipresent
);
686 old_no_bind_keys
= WFLAGP(wwin
, no_bind_keys
);
687 old_no_bind_mouse
= WFLAGP(wwin
, no_bind_mouse
);
689 showIconFor(WMWidgetScreen(button
), panel
, NULL
, NULL
, USE_TEXT_FIELD
);
691 /* Attributes... --> Window Attributes */
692 WSETUFLAG(wwin
, no_titlebar
, WMGetButtonSelected(panel
->attrChk
[0]));
693 WSETUFLAG(wwin
, no_resizebar
, WMGetButtonSelected(panel
->attrChk
[1]));
694 WSETUFLAG(wwin
, no_close_button
, WMGetButtonSelected(panel
->attrChk
[2]));
695 WSETUFLAG(wwin
, no_miniaturize_button
, WMGetButtonSelected(panel
->attrChk
[3]));
696 WSETUFLAG(wwin
, no_border
, WMGetButtonSelected(panel
->attrChk
[4]));
697 floating
= WMGetButtonSelected(panel
->attrChk
[5]);
698 sunken
= WMGetButtonSelected(panel
->attrChk
[6]);
699 WSETUFLAG(wwin
, omnipresent
, WMGetButtonSelected(panel
->attrChk
[7]));
700 WSETUFLAG(wwin
, start_miniaturized
, WMGetButtonSelected(panel
->attrChk
[8]));
701 WSETUFLAG(wwin
, start_maximized
, WMGetButtonSelected(panel
->attrChk
[9]));
702 WSETUFLAG(wwin
, full_maximize
, WMGetButtonSelected(panel
->attrChk
[10]));
704 /* Attributes... --> Advanced Options */
705 WSETUFLAG(wwin
, no_bind_keys
, WMGetButtonSelected(panel
->moreChk
[0]));
706 WSETUFLAG(wwin
, no_bind_mouse
, WMGetButtonSelected(panel
->moreChk
[1]));
707 skip_window_list
= WMGetButtonSelected(panel
->moreChk
[2]);
708 WSETUFLAG(wwin
, skip_switchpanel
, WMGetButtonSelected(panel
->moreChk
[3]));
709 WSETUFLAG(wwin
, no_focusable
, WMGetButtonSelected(panel
->moreChk
[4]));
710 WSETUFLAG(wwin
, dont_move_off
, WMGetButtonSelected(panel
->moreChk
[5]));
711 WSETUFLAG(wwin
, no_hide_others
, WMGetButtonSelected(panel
->moreChk
[6]));
712 WSETUFLAG(wwin
, dont_save_session
, WMGetButtonSelected(panel
->moreChk
[7]));
713 WSETUFLAG(wwin
, emulate_appicon
, WMGetButtonSelected(panel
->moreChk
[8]));
714 WSETUFLAG(wwin
, focus_across_wksp
, WMGetButtonSelected(panel
->moreChk
[9]));
715 WSETUFLAG(wwin
, no_miniaturizable
, WMGetButtonSelected(panel
->moreChk
[10]));
716 #ifdef XKB_BUTTON_HINT
717 WSETUFLAG(wwin
, no_language_button
, WMGetButtonSelected(panel
->moreChk
[11]));
719 WSETUFLAG(wwin
, always_user_icon
, WMGetButtonSelected(panel
->alwChk
));
721 if (WFLAGP(wwin
, no_titlebar
) && wwin
->flags
.shaded
)
722 wUnshadeWindow(wwin
);
724 WSETUFLAG(wwin
, no_shadeable
, WFLAGP(wwin
, no_titlebar
));
727 if (!WFLAGP(wwin
, floating
))
728 ChangeStackingLevel(wwin
->frame
->core
, WMFloatingLevel
);
730 if (!WFLAGP(wwin
, sunken
))
731 ChangeStackingLevel(wwin
->frame
->core
, WMSunkenLevel
);
733 if (WFLAGP(wwin
, floating
) || WFLAGP(wwin
, sunken
))
734 ChangeStackingLevel(wwin
->frame
->core
, WMNormalLevel
);
737 WSETUFLAG(wwin
, sunken
, sunken
);
738 WSETUFLAG(wwin
, floating
, floating
);
739 wwin
->flags
.omnipresent
= 0;
741 if (WFLAGP(wwin
, skip_window_list
) != skip_window_list
) {
742 WSETUFLAG(wwin
, skip_window_list
, skip_window_list
);
743 UpdateSwitchMenu(wwin
->screen_ptr
, wwin
, skip_window_list
? ACTION_REMOVE
: ACTION_ADD
);
745 if (WFLAGP(wwin
, omnipresent
) != old_omnipresent
) {
746 WMPostNotificationName(WMNChangedState
, wwin
, "omnipresent");
750 if (WFLAGP(wwin
, no_bind_keys
) != old_no_bind_keys
) {
751 if (WFLAGP(wwin
, no_bind_keys
)) {
752 XUngrabKey(dpy
, AnyKey
, AnyModifier
, wwin
->frame
->core
->window
);
754 wWindowSetKeyGrabs(wwin
);
758 if (WFLAGP(wwin
, no_bind_mouse
) != old_no_bind_mouse
) {
759 wWindowResetMouseGrabs(wwin
);
762 wwin
->frame
->flags
.need_texture_change
= 1;
763 wWindowConfigureBorders(wwin
);
764 wFrameWindowPaint(wwin
->frame
);
765 wNETWMUpdateActions(wwin
, False
);
768 * Can't apply emulate_appicon because it will probably cause problems.
771 /* do application wide stuff */
772 WSETUFLAG(wapp
->main_window_desc
, start_hidden
, WMGetButtonSelected(panel
->appChk
[0]));
773 WSETUFLAG(wapp
->main_window_desc
, no_appicon
, WMGetButtonSelected(panel
->appChk
[1]));
774 WSETUFLAG(wapp
->main_window_desc
, shared_appicon
, WMGetButtonSelected(panel
->appChk
[2]));
776 if (WFLAGP(wapp
->main_window_desc
, no_appicon
))
777 unpaint_app_icon(wapp
);
779 paint_app_icon(wapp
);
781 if (wapp
->app_icon
&& wapp
->main_window
== wwin
->client_win
) {
782 char *file
= WMGetTextFieldText(panel
->fileText
);
789 wIconChangeImageFile(wapp
->app_icon
->icon
, file
);
793 /* The image was updated in wIconChangeImageFile,
794 * so we don't need udpate it at wAppIconPaint */
795 wAppIconPaint(wapp
->app_icon
, False
);
799 wNETFrameExtents(wwin
);
802 static void revertSettings(WMButton
*button
, InspectorPanel
*panel
)
804 WWindow
*wwin
= panel
->inspected
;
805 WApplication
*wapp
= wApplicationOf(wwin
->main_window
);
807 char *wm_instance
= NULL
;
808 char *wm_class
= NULL
;
809 int workspace
, level
;
811 if (panel
->instRb
&& WMGetButtonSelected(panel
->instRb
) != 0)
812 wm_instance
= wwin
->wm_instance
;
813 else if (panel
->clsRb
&& WMGetButtonSelected(panel
->clsRb
) != 0)
814 wm_class
= wwin
->wm_class
;
815 else if (panel
->bothRb
&& WMGetButtonSelected(panel
->bothRb
) != 0) {
816 wm_instance
= wwin
->wm_instance
;
817 wm_class
= wwin
->wm_class
;
819 memset(&wwin
->defined_user_flags
, 0, sizeof(WWindowAttributes
));
820 memset(&wwin
->user_flags
, 0, sizeof(WWindowAttributes
));
821 memset(&wwin
->client_flags
, 0, sizeof(WWindowAttributes
));
823 wWindowSetupInitialAttributes(wwin
, &level
, &workspace
);
825 for (i
= 0; i
< (sizeof(panel
->attrChk
) / sizeof(panel
->attrChk
[0])); i
++) {
830 flag
= WFLAGP(wwin
, no_titlebar
);
833 flag
= WFLAGP(wwin
, no_resizebar
);
836 flag
= WFLAGP(wwin
, no_close_button
);
839 flag
= WFLAGP(wwin
, no_miniaturize_button
);
842 flag
= WFLAGP(wwin
, no_border
);
845 flag
= WFLAGP(wwin
, floating
);
848 flag
= WFLAGP(wwin
, sunken
);
851 flag
= WFLAGP(wwin
, omnipresent
);
854 flag
= WFLAGP(wwin
, start_miniaturized
);
857 flag
= WFLAGP(wwin
, start_maximized
!= 0);
860 flag
= WFLAGP(wwin
, full_maximize
);
863 WMSetButtonSelected(panel
->attrChk
[i
], flag
);
865 for (i
= 0; i
< (sizeof(panel
->moreChk
) / sizeof(panel
->moreChk
[0])); i
++) {
870 flag
= WFLAGP(wwin
, no_bind_keys
);
873 flag
= WFLAGP(wwin
, no_bind_mouse
);
876 flag
= WFLAGP(wwin
, skip_window_list
);
879 flag
= WFLAGP(wwin
, skip_switchpanel
);
882 flag
= WFLAGP(wwin
, no_focusable
);
885 flag
= WFLAGP(wwin
, dont_move_off
);
888 flag
= WFLAGP(wwin
, no_hide_others
);
891 flag
= WFLAGP(wwin
, dont_save_session
);
894 flag
= WFLAGP(wwin
, emulate_appicon
);
897 flag
= WFLAGP(wwin
, focus_across_wksp
);
900 flag
= WFLAGP(wwin
, no_miniaturizable
);
902 #ifdef XKB_BUTTON_HINT
904 flag
= WFLAGP(wwin
, no_language_button
);
908 WMSetButtonSelected(panel
->moreChk
[i
], flag
);
910 if (panel
->appFrm
&& wapp
) {
911 for (i
= 0; i
< (sizeof(panel
->appChk
) / sizeof(panel
->appChk
[0])); i
++) {
916 flag
= WFLAGP(wapp
->main_window_desc
, start_hidden
);
919 flag
= WFLAGP(wapp
->main_window_desc
, no_appicon
);
922 flag
= WFLAGP(wapp
->main_window_desc
, shared_appicon
);
925 WMSetButtonSelected(panel
->appChk
[i
], flag
);
928 WMSetButtonSelected(panel
->alwChk
, WFLAGP(wwin
, always_user_icon
));
930 showIconFor(WMWidgetScreen(panel
->alwChk
), panel
, wm_instance
, wm_class
, REVERT_TO_DEFAULT
);
932 n
= wDefaultGetStartWorkspace(wwin
->screen_ptr
, wm_instance
, wm_class
);
934 if (n
>= 0 && n
< wwin
->screen_ptr
->workspace_count
) {
935 WMSetPopUpButtonSelectedItem(panel
->wsP
, n
+ 1);
937 WMSetPopUpButtonSelectedItem(panel
->wsP
, 0);
940 /* must auto apply, so that there wno't be internal
941 * inconsistencies between the state in the flags and
942 * the actual state of the window */
943 applySettings(panel
->applyBtn
, panel
);
946 static void chooseIconCallback(WMWidget
*self
, void *clientData
)
949 InspectorPanel
*panel
= (InspectorPanel
*) clientData
;
952 panel
->choosingIcon
= 1;
954 WMSetButtonEnabled(panel
->browseIconBtn
, False
);
956 result
= wIconChooserDialog(panel
->frame
->screen_ptr
, &file
,
957 panel
->inspected
->wm_instance
, panel
->inspected
->wm_class
);
959 panel
->choosingIcon
= 0;
961 if (!panel
->destroyed
) { /* kluge */
963 WMSetTextFieldText(panel
->fileText
, file
);
964 showIconFor(WMWidgetScreen(self
), panel
, NULL
, NULL
, USE_TEXT_FIELD
);
967 WMSetButtonEnabled(panel
->browseIconBtn
, True
);
969 freeInspector(panel
);
973 static void textEditedObserver(void *observerData
, WMNotification
*notification
)
975 InspectorPanel
*panel
= (InspectorPanel
*) observerData
;
977 if ((long)WMGetNotificationClientData(notification
) != WMReturnTextMovement
)
980 showIconFor(WMWidgetScreen(panel
->win
), panel
, NULL
, NULL
, USE_TEXT_FIELD
);
982 WMPerformButtonClick(panel->updateIconBtn);
986 static void selectSpecification(WMWidget
*bPtr
, void *data
)
988 InspectorPanel
*panel
= (InspectorPanel
*) data
;
990 WWindow
*wwin
= panel
->inspected
;
993 if (bPtr
== panel
->defaultRb
&& (wwin
->wm_instance
|| wwin
->wm_class
))
994 WMSetButtonEnabled(panel
->applyBtn
, False
);
996 WMSetButtonEnabled(panel
->applyBtn
, True
);
998 len
= 16 + strlen(wwin
->wm_instance
? wwin
->wm_instance
: "?")
999 + strlen(wwin
->wm_class
? wwin
->wm_class
: "?");
1003 snprintf(str
, len
, _("Inspecting %s.%s"),
1004 wwin
->wm_instance
? wwin
->wm_instance
: "?", wwin
->wm_class
? wwin
->wm_class
: "?");
1006 wFrameWindowChangeTitle(panel
->frame
->frame
, str
);
1011 static void selectWindow(WMWidget
*bPtr
, void *data
)
1013 InspectorPanel
*panel
= (InspectorPanel
*) data
;
1014 WWindow
*wwin
= panel
->inspected
;
1015 WScreen
*scr
= wwin
->screen_ptr
;
1019 if (XGrabPointer(dpy
, scr
->root_win
, True
,
1020 ButtonPressMask
, GrabModeAsync
, GrabModeAsync
, None
,
1021 wCursor
[WCUR_SELECT
], CurrentTime
) != GrabSuccess
) {
1022 wwarning("could not grab mouse pointer");
1026 WMSetLabelText(panel
->specLbl
, _("Click in the window you wish to inspect."));
1028 WMMaskEvent(dpy
, ButtonPressMask
, &event
);
1030 XUngrabPointer(dpy
, CurrentTime
);
1032 iwin
= wWindowFor(event
.xbutton
.subwindow
);
1034 if (iwin
&& !iwin
->flags
.internal_window
&& iwin
!= wwin
&& !iwin
->flags
.inspector_open
) {
1036 iwin
->flags
.inspector_open
= 1;
1037 iwin
->inspector
= createInspectorForWindow(iwin
,
1038 panel
->frame
->frame_x
, panel
->frame
->frame_y
, True
);
1039 wCloseInspectorForWindow(wwin
);
1041 WMSetLabelText(panel
->specLbl
, spec_text
);
1045 static InspectorPanel
*createInspectorForWindow(WWindow
*wwin
, int xpos
, int ypos
, Bool showSelectPanel
)
1047 WScreen
*scr
= wwin
->screen_ptr
;
1048 InspectorPanel
*panel
;
1052 int btn_width
, frame_width
;
1053 WMButton
*selectedBtn
= NULL
;
1054 #ifdef wrong_behaviour
1058 spec_text
= _("The configuration will apply to all\n"
1059 "windows that have their WM_CLASS\n"
1060 "property set to the above selected\n" "name, when saved.");
1062 panel
= wmalloc(sizeof(InspectorPanel
));
1063 memset(panel
, 0, sizeof(InspectorPanel
));
1065 panel
->destroyed
= 0;
1067 panel
->inspected
= wwin
;
1069 panel
->nextPtr
= panelList
;
1072 panel
->win
= WMCreateWindow(scr
->wmscreen
, "windowInspector");
1073 WMResizeWidget(panel
->win
, PWIDTH
, PHEIGHT
);
1075 /**** create common stuff ****/
1077 /* command buttons */
1078 /* (PWIDTH - (left and right margin) - (btn interval)) / 3 */
1079 btn_width
= (PWIDTH
- (2 * 15) - (2 * 10)) / 3;
1080 panel
->saveBtn
= WMCreateCommandButton(panel
->win
);
1081 WMSetButtonAction(panel
->saveBtn
, (WMAction
*) saveSettings
, panel
);
1082 WMMoveWidget(panel
->saveBtn
, (2 * (btn_width
+ 10)) + 15, PHEIGHT
- 40);
1083 WMSetButtonText(panel
->saveBtn
, _("Save"));
1084 WMResizeWidget(panel
->saveBtn
, btn_width
, 28);
1085 if (wPreferences
.flags
.noupdates
|| !(wwin
->wm_class
|| wwin
->wm_instance
))
1086 WMSetButtonEnabled(panel
->saveBtn
, False
);
1088 panel
->applyBtn
= WMCreateCommandButton(panel
->win
);
1089 WMSetButtonAction(panel
->applyBtn
, (WMAction
*) applySettings
, panel
);
1090 WMMoveWidget(panel
->applyBtn
, btn_width
+ 10 + 15, PHEIGHT
- 40);
1091 WMSetButtonText(panel
->applyBtn
, _("Apply"));
1092 WMResizeWidget(panel
->applyBtn
, btn_width
, 28);
1094 panel
->revertBtn
= WMCreateCommandButton(panel
->win
);
1095 WMSetButtonAction(panel
->revertBtn
, (WMAction
*) revertSettings
, panel
);
1096 WMMoveWidget(panel
->revertBtn
, 15, PHEIGHT
- 40);
1097 WMSetButtonText(panel
->revertBtn
, _("Reload"));
1098 WMResizeWidget(panel
->revertBtn
, btn_width
, 28);
1100 /* page selection popup button */
1101 panel
->pagePopUp
= WMCreatePopUpButton(panel
->win
);
1102 WMSetPopUpButtonAction(panel
->pagePopUp
, (WMAction
*) changePage
, panel
);
1103 WMMoveWidget(panel
->pagePopUp
, 25, 15);
1104 WMResizeWidget(panel
->pagePopUp
, PWIDTH
- 50, 20);
1106 WMAddPopUpButtonItem(panel
->pagePopUp
, _("Window Specification"));
1107 WMAddPopUpButtonItem(panel
->pagePopUp
, _("Window Attributes"));
1108 WMAddPopUpButtonItem(panel
->pagePopUp
, _("Advanced Options"));
1109 WMAddPopUpButtonItem(panel
->pagePopUp
, _("Icon and Initial Workspace"));
1110 WMAddPopUpButtonItem(panel
->pagePopUp
, _("Application Specific"));
1112 /**** window spec ****/
1113 frame_width
= PWIDTH
- (2 * 15);
1115 panel
->specFrm
= WMCreateFrame(panel
->win
);
1116 WMSetFrameTitle(panel
->specFrm
, _("Window Specification"));
1117 WMMoveWidget(panel
->specFrm
, 15, 65);
1118 WMResizeWidget(panel
->specFrm
, frame_width
, 145);
1120 panel
->defaultRb
= WMCreateRadioButton(panel
->specFrm
);
1121 WMMoveWidget(panel
->defaultRb
, 10, 78);
1122 WMResizeWidget(panel
->defaultRb
, frame_width
- (2 * 10), 20);
1123 WMSetButtonText(panel
->defaultRb
, _("Defaults for all windows"));
1124 WMSetButtonSelected(panel
->defaultRb
, False
);
1125 WMSetButtonAction(panel
->defaultRb
, selectSpecification
, panel
);
1127 if (wwin
->wm_class
&& wwin
->wm_instance
) {
1130 tmp
= wstrconcat(wwin
->wm_instance
, ".");
1131 str
= wstrconcat(tmp
, wwin
->wm_class
);
1133 panel
->bothRb
= WMCreateRadioButton(panel
->specFrm
);
1134 WMMoveWidget(panel
->bothRb
, 10, 18);
1135 WMResizeWidget(panel
->bothRb
, frame_width
- (2 * 10), 20);
1136 WMSetButtonText(panel
->bothRb
, str
);
1139 WMGroupButtons(panel
->defaultRb
, panel
->bothRb
);
1142 selectedBtn
= panel
->bothRb
;
1144 WMSetButtonAction(panel
->bothRb
, selectSpecification
, panel
);
1147 if (wwin
->wm_instance
) {
1148 panel
->instRb
= WMCreateRadioButton(panel
->specFrm
);
1149 WMMoveWidget(panel
->instRb
, 10, 38);
1150 WMResizeWidget(panel
->instRb
, frame_width
- (2 * 10), 20);
1151 WMSetButtonText(panel
->instRb
, wwin
->wm_instance
);
1152 WMGroupButtons(panel
->defaultRb
, panel
->instRb
);
1155 selectedBtn
= panel
->instRb
;
1157 WMSetButtonAction(panel
->instRb
, selectSpecification
, panel
);
1160 if (wwin
->wm_class
) {
1161 panel
->clsRb
= WMCreateRadioButton(panel
->specFrm
);
1162 WMMoveWidget(panel
->clsRb
, 10, 58);
1163 WMResizeWidget(panel
->clsRb
, frame_width
- (2 * 10), 20);
1164 WMSetButtonText(panel
->clsRb
, wwin
->wm_class
);
1165 WMGroupButtons(panel
->defaultRb
, panel
->clsRb
);
1168 selectedBtn
= panel
->clsRb
;
1170 WMSetButtonAction(panel
->clsRb
, selectSpecification
, panel
);
1173 panel
->selWinB
= WMCreateCommandButton(panel
->specFrm
);
1174 WMMoveWidget(panel
->selWinB
, 20, 145 - 24 - 10);
1175 WMResizeWidget(panel
->selWinB
, frame_width
- 2 * 10 - 20, 24);
1176 WMSetButtonText(panel
->selWinB
, _("Select window"));
1177 WMSetButtonAction(panel
->selWinB
, selectWindow
, panel
);
1179 panel
->specLbl
= WMCreateLabel(panel
->win
);
1180 WMMoveWidget(panel
->specLbl
, 15, 210);
1181 WMResizeWidget(panel
->specLbl
, frame_width
, 100);
1182 WMSetLabelText(panel
->specLbl
, spec_text
);
1183 WMSetLabelWraps(panel
->specLbl
, True
);
1185 WMSetLabelTextAlignment(panel
->specLbl
, WALeft
);
1187 /**** attributes ****/
1188 panel
->attrFrm
= WMCreateFrame(panel
->win
);
1189 WMSetFrameTitle(panel
->attrFrm
, _("Attributes"));
1190 WMMoveWidget(panel
->attrFrm
, 15, 45);
1191 WMResizeWidget(panel
->attrFrm
, frame_width
, 250);
1193 for (i
= 0; i
< (sizeof(panel
->attrChk
) / sizeof(panel
->attrChk
[0])); i
++) {
1194 char *caption
= NULL
;
1200 caption
= _("Disable titlebar");
1201 flag
= WFLAGP(wwin
, no_titlebar
);
1202 descr
= _("Remove the titlebar of this window.\n"
1203 "To access the window commands menu of a window\n"
1204 "without it's titlebar, press Control+Esc (or the\n"
1205 "equivalent shortcut, if you changed the default\n" "settings).");
1208 caption
= _("Disable resizebar");
1209 flag
= WFLAGP(wwin
, no_resizebar
);
1210 descr
= _("Remove the resizebar of this window.");
1213 caption
= _("Disable close button");
1214 flag
= WFLAGP(wwin
, no_close_button
);
1215 descr
= _("Remove the `close window' button of this window.");
1218 caption
= _("Disable miniaturize button");
1219 flag
= WFLAGP(wwin
, no_miniaturize_button
);
1220 descr
= _("Remove the `miniaturize window' button of the window.");
1223 caption
= _("Disable border");
1224 flag
= WFLAGP(wwin
, no_border
);
1225 descr
= _("Remove the 1 pixel black border around the window.");
1228 caption
= _("Keep on top (floating)");
1229 flag
= WFLAGP(wwin
, floating
);
1230 descr
= _("Keep the window over other windows, not allowing\n" "them to cover it.");
1233 caption
= _("Keep at bottom (sunken)");
1234 flag
= WFLAGP(wwin
, sunken
);
1235 descr
= _("Keep the window under all other windows.");
1238 caption
= _("Omnipresent");
1239 flag
= WFLAGP(wwin
, omnipresent
);
1240 descr
= _("Make window present in all workspaces.");
1243 caption
= _("Start miniaturized");
1244 flag
= WFLAGP(wwin
, start_miniaturized
);
1245 descr
= _("Make the window be automatically miniaturized when it's\n" "first shown.");
1248 caption
= _("Start maximized");
1249 flag
= WFLAGP(wwin
, start_maximized
!= 0);
1250 descr
= _("Make the window be automatically maximized when it's\n" "first shown.");
1253 caption
= _("Full screen maximization");
1254 flag
= WFLAGP(wwin
, full_maximize
);
1255 descr
= _("Make the window use the whole screen space when it's\n"
1256 "maximized. The titlebar and resizebar will be moved\n"
1257 "to outside the screen.");
1260 panel
->attrChk
[i
] = WMCreateSwitchButton(panel
->attrFrm
);
1261 WMMoveWidget(panel
->attrChk
[i
], 10, 20 * (i
+ 1));
1262 WMResizeWidget(panel
->attrChk
[i
], frame_width
- 15, 20);
1263 WMSetButtonSelected(panel
->attrChk
[i
], flag
);
1264 WMSetButtonText(panel
->attrChk
[i
], caption
);
1266 WMSetBalloonTextForView(descr
, WMWidgetView(panel
->attrChk
[i
]));
1269 /**** more attributes ****/
1270 panel
->moreFrm
= WMCreateFrame(panel
->win
);
1271 WMSetFrameTitle(panel
->moreFrm
, _("Advanced"));
1272 WMMoveWidget(panel
->moreFrm
, 15, 45);
1273 WMResizeWidget(panel
->moreFrm
, frame_width
, 265);
1275 for (i
= 0; i
< (sizeof(panel
->moreChk
) / sizeof(panel
->moreChk
[0])); i
++) {
1276 char *caption
= NULL
;
1282 caption
= _("Do not bind keyboard shortcuts");
1283 flag
= WFLAGP(wwin
, no_bind_keys
);
1284 descr
= _("Do not bind keyboard shortcuts from Window Maker\n"
1285 "when this window is focused. This will allow the\n"
1286 "window to receive all key combinations regardless\n"
1287 "of your shortcut configuration.");
1290 caption
= _("Do not bind mouse clicks");
1291 flag
= WFLAGP(wwin
, no_bind_mouse
);
1292 descr
= _("Do not bind mouse actions, such as `Alt'+drag\n"
1293 "in the window (when alt is the modifier you have\n" "configured).");
1296 caption
= _("Do not show in the window list");
1297 flag
= WFLAGP(wwin
, skip_window_list
);
1298 descr
= _("Do not list the window in the window list menu.");
1301 caption
= _("Do not show in the switch panel");
1302 flag
= WFLAGP(wwin
, skip_switchpanel
);
1303 descr
= _("Do not include in switchpanel while alternating windows.");
1306 caption
= _("Do not let it take focus");
1307 flag
= WFLAGP(wwin
, no_focusable
);
1308 descr
= _("Do not let the window take keyboard focus when you\n" "click on it.");
1311 caption
= _("Keep inside screen");
1312 flag
= WFLAGP(wwin
, dont_move_off
);
1313 descr
= _("Do not allow the window to move itself completely\n"
1314 "outside the screen. For bug compatibility.\n");
1317 caption
= _("Ignore 'Hide Others'");
1318 flag
= WFLAGP(wwin
, no_hide_others
);
1319 descr
= _("Do not hide the window when issuing the\n" "`HideOthers' command.");
1322 caption
= _("Ignore 'Save Session'");
1323 flag
= WFLAGP(wwin
, dont_save_session
);
1324 descr
= _("Do not save the associated application in the\n"
1325 "session's state, so that it won't be restarted\n"
1326 "together with other applications when Window Maker\n" "starts.");
1329 caption
= _("Emulate application icon");
1330 flag
= WFLAGP(wwin
, emulate_appicon
);
1331 descr
= _("Make this window act as an application that provides\n"
1332 "enough information to Window Maker for a dockable\n"
1333 "application icon to be created.");
1336 caption
= _("Focus across workspaces");
1337 flag
= WFLAGP(wwin
, focus_across_wksp
);
1338 descr
= _("Allow Window Maker to switch workspace to satisfy\n"
1339 "a focus request (annoying).");
1342 caption
= _("Do not let it be minimized");
1343 flag
= WFLAGP(wwin
, no_miniaturizable
);
1344 descr
= _("Do not let the window of this application be\n"
1347 #ifdef XKB_BUTTON_HINT
1349 caption
= _("Disable language button");
1350 flag
= WFLAGP(wwin
, no_language_button
);
1351 descr
= _("Remove the `toggle language' button of the window.");
1355 panel
->moreChk
[i
] = WMCreateSwitchButton(panel
->moreFrm
);
1356 WMMoveWidget(panel
->moreChk
[i
], 10, 20 * (i
+ 1));
1357 WMResizeWidget(panel
->moreChk
[i
], frame_width
- 15, 20);
1358 WMSetButtonSelected(panel
->moreChk
[i
], flag
);
1359 WMSetButtonText(panel
->moreChk
[i
], caption
);
1361 WMSetBalloonTextForView(descr
, WMWidgetView(panel
->moreChk
[i
]));
1364 /* miniwindow/workspace */
1365 panel
->iconFrm
= WMCreateFrame(panel
->win
);
1366 WMMoveWidget(panel
->iconFrm
, 15, 50);
1367 WMResizeWidget(panel
->iconFrm
, PWIDTH
- (2 * 15), 170);
1368 WMSetFrameTitle(panel
->iconFrm
, _("Miniwindow Image"));
1370 panel
->iconLbl
= WMCreateLabel(panel
->iconFrm
);
1371 WMMoveWidget(panel
->iconLbl
, PWIDTH
- (2 * 15) - 22 - 64, 20);
1372 WMResizeWidget(panel
->iconLbl
, 64, 64);
1373 WMSetLabelRelief(panel
->iconLbl
, WRGroove
);
1374 WMSetLabelImagePosition(panel
->iconLbl
, WIPImageOnly
);
1376 panel
->browseIconBtn
= WMCreateCommandButton(panel
->iconFrm
);
1377 WMSetButtonAction(panel
->browseIconBtn
, chooseIconCallback
, panel
);
1378 WMMoveWidget(panel
->browseIconBtn
, 22, 32);
1379 WMResizeWidget(panel
->browseIconBtn
, 120, 26);
1380 WMSetButtonText(panel
->browseIconBtn
, _("Browse..."));
1382 #ifdef wrong_behaviour
1383 WMSetButtonImagePosition(panel
->updateIconBtn
, WIPRight
);
1384 pixmap
= WMGetSystemPixmap(scr
->wmscreen
, WSIReturnArrow
);
1385 WMSetButtonImage(panel
->updateIconBtn
, pixmap
);
1386 WMReleasePixmap(pixmap
);
1387 pixmap
= WMGetSystemPixmap(scr
->wmscreen
, WSIHighlightedReturnArrow
);
1388 WMSetButtonAltImage(panel
->updateIconBtn
, pixmap
);
1389 WMReleasePixmap(pixmap
);
1392 panel
->fileLbl
= WMCreateLabel(panel
->iconFrm
);
1393 WMMoveWidget(panel
->fileLbl
, 20, 85);
1394 WMResizeWidget(panel
->fileLbl
, PWIDTH
- (2 * 15) - (2 * 20), 14);
1395 WMSetLabelText(panel
->fileLbl
, _("Icon filename:"));
1397 panel
->fileText
= WMCreateTextField(panel
->iconFrm
);
1398 WMMoveWidget(panel
->fileText
, 20, 105);
1399 WMResizeWidget(panel
->fileText
, PWIDTH
- (2 * 20) - (2 * 15), 20);
1400 WMSetTextFieldText(panel
->fileText
, NULL
);
1401 WMAddNotificationObserver(textEditedObserver
, panel
, WMTextDidEndEditingNotification
, panel
->fileText
);
1403 panel
->alwChk
= WMCreateSwitchButton(panel
->iconFrm
);
1404 WMMoveWidget(panel
->alwChk
, 20, 130);
1405 WMResizeWidget(panel
->alwChk
, PWIDTH
- (2 * 15) - (2 * 15), 30);
1406 WMSetButtonText(panel
->alwChk
, _("Ignore client supplied icon"));
1407 WMSetButtonSelected(panel
->alwChk
, WFLAGP(wwin
, always_user_icon
));
1409 panel
->wsFrm
= WMCreateFrame(panel
->win
);
1410 WMMoveWidget(panel
->wsFrm
, 15, 225);
1411 WMResizeWidget(panel
->wsFrm
, PWIDTH
- (2 * 15), 70);
1412 WMSetFrameTitle(panel
->wsFrm
, _("Initial Workspace"));
1414 WMSetBalloonTextForView(_("The workspace to place the window when it's"
1415 "first shown."), WMWidgetView(panel
->wsFrm
));
1417 panel
->wsP
= WMCreatePopUpButton(panel
->wsFrm
);
1418 WMMoveWidget(panel
->wsP
, 20, 30);
1419 WMResizeWidget(panel
->wsP
, PWIDTH
- (2 * 15) - (2 * 20), 20);
1420 WMAddPopUpButtonItem(panel
->wsP
, _("Nowhere in particular"));
1422 for (i
= 0; i
< wwin
->screen_ptr
->workspace_count
; i
++)
1423 WMAddPopUpButtonItem(panel
->wsP
, scr
->workspaces
[i
]->name
);
1425 i
= wDefaultGetStartWorkspace(wwin
->screen_ptr
, wwin
->wm_instance
, wwin
->wm_class
);
1426 if (i
>= 0 && i
<= wwin
->screen_ptr
->workspace_count
)
1427 WMSetPopUpButtonSelectedItem(panel
->wsP
, i
+ 1);
1429 WMSetPopUpButtonSelectedItem(panel
->wsP
, 0);
1431 /* application wide attributes */
1432 if (wwin
->main_window
!= None
) {
1433 WApplication
*wapp
= wApplicationOf(wwin
->main_window
);
1435 panel
->appFrm
= WMCreateFrame(panel
->win
);
1436 WMSetFrameTitle(panel
->appFrm
, _("Application Attributes"));
1437 WMMoveWidget(panel
->appFrm
, 15, 50);
1438 WMResizeWidget(panel
->appFrm
, frame_width
, 240);
1440 for (i
= 0; i
< (sizeof(panel
->appChk
) / sizeof(panel
->appChk
[0])); i
++) {
1441 char *caption
= NULL
;
1447 caption
= _("Start hidden");
1448 flag
= WFLAGP(wapp
->main_window_desc
, start_hidden
);
1449 descr
= _("Automatically hide application when it's started.");
1452 caption
= _("No application icon");
1453 flag
= WFLAGP(wapp
->main_window_desc
, no_appicon
);
1454 descr
= _("Disable the application icon for the application.\n"
1455 "Note that you won't be able to dock it anymore,\n"
1456 "and any icons that are already docked will stop\n"
1457 "working correctly.");
1460 caption
= _("Shared application icon");
1461 flag
= WFLAGP(wapp
->main_window_desc
, shared_appicon
);
1462 descr
= _("Use a single shared application icon for all of\n"
1463 "the instances of this application.\n");
1466 panel
->appChk
[i
] = WMCreateSwitchButton(panel
->appFrm
);
1467 WMMoveWidget(panel
->appChk
[i
], 10, 20 * (i
+ 1));
1468 WMResizeWidget(panel
->appChk
[i
], 205, 20);
1469 WMSetButtonSelected(panel
->appChk
[i
], flag
);
1470 WMSetButtonText(panel
->appChk
[i
], caption
);
1471 WMSetBalloonTextForView(descr
, WMWidgetView(panel
->appChk
[i
]));
1474 if (WFLAGP(wwin
, emulate_appicon
)) {
1475 WMSetButtonEnabled(panel
->appChk
[1], False
);
1476 WMSetButtonEnabled(panel
->moreChk
[7], True
);
1478 WMSetButtonEnabled(panel
->appChk
[1], True
);
1479 WMSetButtonEnabled(panel
->moreChk
[7], False
);
1484 if ((wwin
->transient_for
!= None
&& wwin
->transient_for
!= scr
->root_win
)
1485 || !wwin
->wm_class
|| !wwin
->wm_instance
)
1489 WMSetButtonEnabled(panel
->moreChk
[7], tmp
);
1491 WMSetPopUpButtonItemEnabled(panel
->pagePopUp
, 4, False
);
1492 panel
->appFrm
= NULL
;
1495 /* if the window is a transient, don't let it have a miniaturize
1497 if (wwin
->transient_for
!= None
&& wwin
->transient_for
!= scr
->root_win
)
1498 WMSetButtonEnabled(panel
->attrChk
[3], False
);
1500 WMSetButtonEnabled(panel
->attrChk
[3], True
);
1502 if (!wwin
->wm_class
&& !wwin
->wm_instance
) {
1503 WMSetPopUpButtonItemEnabled(panel
->pagePopUp
, 0, False
);
1506 WMRealizeWidget(panel
->win
);
1508 WMMapSubwidgets(panel
->win
);
1509 WMMapSubwidgets(panel
->specFrm
);
1510 WMMapSubwidgets(panel
->attrFrm
);
1511 WMMapSubwidgets(panel
->moreFrm
);
1512 WMMapSubwidgets(panel
->iconFrm
);
1513 WMMapSubwidgets(panel
->wsFrm
);
1515 WMMapSubwidgets(panel
->appFrm
);
1517 if (showSelectPanel
) {
1518 WMSetPopUpButtonSelectedItem(panel
->pagePopUp
, 0);
1519 changePage(panel
->pagePopUp
, panel
);
1521 WMSetPopUpButtonSelectedItem(panel
->pagePopUp
, 1);
1522 changePage(panel
->pagePopUp
, panel
);
1525 parent
= XCreateSimpleWindow(dpy
, scr
->root_win
, 0, 0, PWIDTH
, PHEIGHT
, 0, 0, 0);
1526 XSelectInput(dpy
, parent
, KeyPressMask
| KeyReleaseMask
);
1527 panel
->parent
= parent
;
1528 XReparentWindow(dpy
, WMWidgetXID(panel
->win
), parent
, 0, 0);
1530 WMMapWidget(panel
->win
);
1532 XSetTransientForHint(dpy
, parent
, wwin
->client_win
);
1534 if (xpos
== UNDEFINED_POS
) {
1535 x
= wwin
->frame_x
+ wwin
->frame
->core
->width
/ 2;
1536 y
= wwin
->frame_y
+ wwin
->frame
->top_width
* 2;
1537 if (y
+ PHEIGHT
> scr
->scr_height
)
1538 y
= scr
->scr_height
- PHEIGHT
- 30;
1539 if (x
+ PWIDTH
> scr
->scr_width
)
1540 x
= scr
->scr_width
- PWIDTH
;
1546 panel
->frame
= wManageInternalWindow(scr
, parent
, wwin
->client_win
, "Inspector", x
, y
, PWIDTH
, PHEIGHT
);
1549 selectedBtn
= panel
->defaultRb
;
1551 WMSetButtonSelected(selectedBtn
, True
);
1553 selectSpecification(selectedBtn
, panel
);
1555 /* kluge to know who should get the key events */
1556 panel
->frame
->client_leader
= WMWidgetXID(panel
->win
);
1558 WSETUFLAG(panel
->frame
, no_closable
, 0);
1559 WSETUFLAG(panel
->frame
, no_close_button
, 0);
1560 wWindowUpdateButtonImages(panel
->frame
);
1561 wFrameWindowShowButton(panel
->frame
->frame
, WFF_RIGHT_BUTTON
);
1562 panel
->frame
->frame
->on_click_right
= destroyInspector
;
1564 wWindowMap(panel
->frame
);
1566 showIconFor(WMWidgetScreen(panel
->alwChk
), panel
, wwin
->wm_instance
, wwin
->wm_class
, UPDATE_TEXT_FIELD
);
1571 void wShowInspectorForWindow(WWindow
*wwin
)
1573 if (wwin
->flags
.inspector_open
)
1576 WMSetBalloonEnabled(wwin
->screen_ptr
->wmscreen
, wPreferences
.help_balloon
);
1579 wwin
->flags
.inspector_open
= 1;
1580 wwin
->inspector
= createInspectorForWindow(wwin
, UNDEFINED_POS
, UNDEFINED_POS
, False
);
1583 void wHideInspectorForWindow(WWindow
*wwin
)
1585 WWindow
*pwin
= wwin
->inspector
->frame
;
1588 pwin
->flags
.hidden
= 1;
1590 wClientSetState(pwin
, IconicState
, None
);
1593 void wUnhideInspectorForWindow(WWindow
*wwin
)
1595 WWindow
*pwin
= wwin
->inspector
->frame
;
1597 pwin
->flags
.hidden
= 0;
1598 pwin
->flags
.mapped
= 1;
1599 XMapWindow(dpy
, pwin
->client_win
);
1600 XMapWindow(dpy
, pwin
->frame
->core
->window
);
1601 wClientSetState(pwin
, NormalState
, None
);
1604 WWindow
*wGetWindowOfInspectorForWindow(WWindow
*wwin
)
1606 if (wwin
->inspector
) {
1607 assert(wwin
->flags
.inspector_open
!= 0);
1609 return wwin
->inspector
->frame
;
1614 void wCloseInspectorForWindow(WWindow
*wwin
)
1616 WWindow
*pwin
= wwin
->inspector
->frame
; /* the inspector window */
1618 (*pwin
->frame
->on_click_right
) (NULL
, pwin
, NULL
);