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>
31 #include "WindowMaker.h"
36 #include "workspace.h"
42 #include "application.h"
45 #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
[10];
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
*AKeepInsideScreen
;
138 static WMPropList
*AUnfocusable
;
139 static WMPropList
*ADontFocusAcrossWorkspace
;
140 static WMPropList
*AAlwaysUserIcon
;
141 static WMPropList
*AStartMiniaturized
;
142 static WMPropList
*AStartMaximized
;
143 static WMPropList
*ADontSaveSession
;
144 static WMPropList
*AEmulateAppIcon
;
145 static WMPropList
*AFullMaximize
;
146 static WMPropList
*ASharedAppIcon
;
147 #ifdef XKB_BUTTON_HINT
148 static WMPropList
*ANoLanguageButton
;
150 static WMPropList
*AStartWorkspace
;
151 static WMPropList
*AIcon
;
153 /* application wide options */
154 static WMPropList
*AStartHidden
;
155 static WMPropList
*AnyWindow
;
156 static WMPropList
*EmptyString
;
157 static WMPropList
*Yes
, *No
;
162 static char *spec_text
;
163 static void applySettings(WMButton
* button
, InspectorPanel
* panel
);
165 #define UNDEFINED_POS 0xffffff
167 static InspectorPanel
*createInspectorForWindow(WWindow
* wwin
, int xpos
, int ypos
, Bool showSelectPanel
);
169 static void make_keys(void)
171 if (ANoTitlebar
!= NULL
)
174 AIcon
= WMCreatePLString("Icon");
175 ANoTitlebar
= WMCreatePLString("NoTitlebar");
176 ANoResizebar
= WMCreatePLString("NoResizebar");
177 ANoMiniaturizeButton
= WMCreatePLString("NoMiniaturizeButton");
178 ANoCloseButton
= WMCreatePLString("NoCloseButton");
179 ANoBorder
= WMCreatePLString("NoBorder");
180 ANoHideOthers
= WMCreatePLString("NoHideOthers");
181 ANoMouseBindings
= WMCreatePLString("NoMouseBindings");
182 ANoKeyBindings
= WMCreatePLString("NoKeyBindings");
183 ANoAppIcon
= WMCreatePLString("NoAppIcon");
184 AKeepOnTop
= WMCreatePLString("KeepOnTop");
185 AKeepOnBottom
= WMCreatePLString("KeepOnBottom");
186 AOmnipresent
= WMCreatePLString("Omnipresent");
187 ASkipWindowList
= WMCreatePLString("SkipWindowList");
188 AKeepInsideScreen
= WMCreatePLString("KeepInsideScreen");
189 AUnfocusable
= WMCreatePLString("Unfocusable");
190 ADontFocusAcrossWorkspace
= WMCreatePLString("DontFocusAcrossWorkspace");
191 AAlwaysUserIcon
= WMCreatePLString("AlwaysUserIcon");
192 AStartMiniaturized
= WMCreatePLString("StartMiniaturized");
193 AStartMaximized
= WMCreatePLString("StartMaximized");
194 AStartHidden
= WMCreatePLString("StartHidden");
195 ADontSaveSession
= WMCreatePLString("DontSaveSession");
196 AEmulateAppIcon
= WMCreatePLString("EmulateAppIcon");
197 AFullMaximize
= WMCreatePLString("FullMaximize");
198 ASharedAppIcon
= WMCreatePLString("SharedAppIcon");
199 #ifdef XKB_BUTTON_HINT
200 ANoLanguageButton
= WMCreatePLString("NoLanguageButton");
203 AStartWorkspace
= WMCreatePLString("StartWorkspace");
205 AnyWindow
= WMCreatePLString("*");
206 EmptyString
= WMCreatePLString("");
207 Yes
= WMCreatePLString("Yes");
208 No
= WMCreatePLString("No");
211 static void freeInspector(InspectorPanel
* panel
)
213 panel
->destroyed
= 1;
214 if (panel
->choosingIcon
)
217 WMDestroyWidget(panel
->win
);
219 XDestroyWindow(dpy
, panel
->parent
);
224 static void destroyInspector(WCoreWindow
* foo
, void *data
, XEvent
* event
)
226 InspectorPanel
*panel
;
230 while (panel
->frame
!= data
)
231 panel
= panel
->nextPtr
;
233 if (panelList
== panel
)
234 panelList
= panel
->nextPtr
;
237 while (tmp
->nextPtr
!= panel
) {
240 tmp
->nextPtr
= panel
->nextPtr
;
242 panel
->inspected
->flags
.inspector_open
= 0;
243 panel
->inspected
->inspector
= NULL
;
245 WMRemoveNotificationObserver(panel
);
247 wWindowUnmap(panel
->frame
);
248 wUnmanageWindow(panel
->frame
, True
, False
);
250 freeInspector(panel
);
253 void wDestroyInspectorPanels(void)
255 InspectorPanel
*panel
;
257 while (panelList
!= NULL
) {
259 panelList
= panelList
->nextPtr
;
260 wUnmanageWindow(panel
->frame
, False
, False
);
261 WMDestroyWidget(panel
->win
);
263 panel
->inspected
->flags
.inspector_open
= 0;
264 panel
->inspected
->inspector
= NULL
;
270 static void changePage(WMPopUpButton
* bPtr
, InspectorPanel
* panel
)
274 page
= WMGetPopUpButtonSelectedItem(bPtr
);
277 WMMapWidget(panel
->specFrm
);
278 WMMapWidget(panel
->specLbl
);
279 } else if (page
== 1) {
280 WMMapWidget(panel
->attrFrm
);
281 } else if (page
== 2) {
282 WMMapWidget(panel
->moreFrm
);
283 } else if (page
== 3) {
284 WMMapWidget(panel
->iconFrm
);
285 WMMapWidget(panel
->wsFrm
);
287 WMMapWidget(panel
->appFrm
);
291 WMUnmapWidget(panel
->specFrm
);
292 WMUnmapWidget(panel
->specLbl
);
295 WMUnmapWidget(panel
->attrFrm
);
297 WMUnmapWidget(panel
->moreFrm
);
299 WMUnmapWidget(panel
->iconFrm
);
300 WMUnmapWidget(panel
->wsFrm
);
302 if (page
!= 4 && panel
->appFrm
)
303 WMUnmapWidget(panel
->appFrm
);
306 #define USE_TEXT_FIELD 1
307 #define UPDATE_TEXT_FIELD 2
308 #define REVERT_TO_DEFAULT 4
310 static int showIconFor(WMScreen
* scrPtr
, InspectorPanel
* panel
, char *wm_instance
, char *wm_class
, int flags
)
312 WMPixmap
*pixmap
= (WMPixmap
*) NULL
;
313 char *file
= NULL
, *path
= NULL
;
314 char *db_icon
= NULL
;
316 if ((flags
& USE_TEXT_FIELD
) != 0) {
317 file
= WMGetTextFieldText(panel
->fileText
);
318 if (file
&& file
[0] == 0) {
323 db_icon
= wDefaultGetIconFile(panel
->inspected
->screen_ptr
, wm_instance
, wm_class
, False
);
325 file
= wstrdup(db_icon
);
327 if (db_icon
!= NULL
&& (flags
& REVERT_TO_DEFAULT
) != 0) {
329 file
= wstrdup(db_icon
);
330 flags
|= UPDATE_TEXT_FIELD
;
333 if ((flags
& UPDATE_TEXT_FIELD
) != 0) {
334 WMSetTextFieldText(panel
->fileText
, file
);
338 path
= FindImage(wPreferences
.icon_path
, file
);
342 int len
= strlen(file
) + 80;
345 snprintf(buf
, len
, _("Could not find icon \"%s\" specified for this window"), file
);
346 wMessageDialog(panel
->frame
->screen_ptr
, _("Error"), buf
, _("OK"), NULL
, NULL
);
352 pixmap
= WMCreatePixmapFromFile(scrPtr
, path
);
357 int len
= strlen(file
) + 80;
360 snprintf(buf
, len
, _("Could not open specified icon \"%s\":%s"),
361 file
, RMessageForError(RErrorCode
));
362 wMessageDialog(panel
->frame
->screen_ptr
, _("Error"), buf
, _("OK"), NULL
, NULL
);
370 WMSetLabelImage(panel
->iconLbl
, pixmap
);
372 WMReleasePixmap(pixmap
);
378 static void updateIcon(WMButton
* button
, InspectorPanel
* panel
)
380 showIconFor(WMWidgetScreen(button
), panel
, NULL
, NULL
, USE_TEXT_FIELD
);
384 static int getBool(WMPropList
* value
)
388 if (!WMIsPLString(value
)) {
391 if (!(val
= WMGetFromPLString(value
))) {
395 if ((val
[1] == '\0' && (val
[0] == 'y' || val
[0] == 'Y' || val
[0] == 'T' || val
[0] == 't' || val
[0] == '1'))
396 || (strcasecmp(val
, "YES") == 0 || strcasecmp(val
, "TRUE") == 0)) {
399 } else if ((val
[1] == '\0'
400 && (val
[0] == 'n' || val
[0] == 'N' || val
[0] == 'F' || val
[0] == 'f' || val
[0] == '0'))
401 || (strcasecmp(val
, "NO") == 0 || strcasecmp(val
, "FALSE") == 0)) {
405 wwarning(_("can't convert \"%s\" to boolean"), val
);
410 #define UPDATE_DEFAULTS 1
414 * Will insert the attribute = value; pair in window's list,
415 * if it's different from the defaults.
416 * Defaults means either defaults database, or attributes saved
417 * for the default window "*". This is to let one revert options that are
418 * global because they were saved for all windows ("*").
423 insertAttribute(WMPropList
* dict
, WMPropList
* window
, WMPropList
* attr
, WMPropList
* value
, int flags
)
425 WMPropList
*def_win
, *def_value
= NULL
;
429 if (!(flags
& UPDATE_DEFAULTS
) && dict
) {
430 if ((def_win
= WMGetFromPLDictionary(dict
, AnyWindow
)) != NULL
) {
431 def_value
= WMGetFromPLDictionary(def_win
, attr
);
435 /* If we could not find defaults in database, fall to hardcoded values.
436 * Also this is true if we save defaults for all windows
439 def_value
= ((flags
& IS_BOOLEAN
) != 0) ? No
: EmptyString
;
441 if ((flags
& IS_BOOLEAN
))
442 update
= (getBool(value
) != getBool(def_value
));
444 update
= !WMIsPropListEqualTo(value
, def_value
);
448 WMPutInPLDictionary(window
, attr
, value
);
455 static void saveSettings(WMButton
* button
, InspectorPanel
* panel
)
457 WWindow
*wwin
= panel
->inspected
;
458 WDDomain
*db
= WDWindowAttributes
;
459 WMPropList
*dict
= db
->dictionary
;
460 WMPropList
*winDic
, *appDic
, *value
, *key
, *key2
;
463 int different
= 0, different2
= 0;
465 /* Save will apply the changes and save them */
466 applySettings(panel
->applyBtn
, panel
);
468 if (WMGetButtonSelected(panel
->instRb
) != 0)
469 key
= WMCreatePLString(wwin
->wm_instance
);
470 else if (WMGetButtonSelected(panel
->clsRb
) != 0)
471 key
= WMCreatePLString(wwin
->wm_class
);
472 else if (WMGetButtonSelected(panel
->bothRb
) != 0) {
475 buffer
= StrConcatDot(wwin
->wm_instance
, wwin
->wm_class
);
476 key
= WMCreatePLString(buffer
);
478 } else if (WMGetButtonSelected(panel
->defaultRb
) != 0) {
479 key
= WMRetainPropList(AnyWindow
);
480 flags
= UPDATE_DEFAULTS
;
488 dict
= WMCreatePLDictionary(NULL
, NULL
);
490 db
->dictionary
= dict
;
492 WMReleasePropList(key
);
497 if (showIconFor(WMWidgetScreen(button
), panel
, NULL
, NULL
, USE_TEXT_FIELD
) < 0)
500 WMPLSetCaseSensitive(True
);
502 winDic
= WMCreatePLDictionary(NULL
, NULL
);
503 appDic
= WMCreatePLDictionary(NULL
, NULL
);
505 /* Update icon for window */
506 icon_file
= WMGetTextFieldText(panel
->fileText
);
508 if (icon_file
[0] != 0) {
509 value
= WMCreatePLString(icon_file
);
510 different
|= insertAttribute(dict
, winDic
, AIcon
, value
, flags
);
511 different2
|= insertAttribute(dict
, appDic
, AIcon
, value
, flags
);
512 WMReleasePropList(value
);
518 int i
= WMGetPopUpButtonSelectedItem(panel
->wsP
);
522 if (i
>= 0 && i
< panel
->frame
->screen_ptr
->workspace_count
) {
523 value
= WMCreatePLString(panel
->frame
->screen_ptr
->workspaces
[i
]->name
);
524 different
|= insertAttribute(dict
, winDic
, AStartWorkspace
, value
, flags
);
525 WMReleasePropList(value
);
531 value
= (WMGetButtonSelected(panel
->alwChk
) != 0) ? Yes
: No
;
532 different
|= insertAttribute(dict
, winDic
, AAlwaysUserIcon
, value
, flags
);
534 value
= (WMGetButtonSelected(panel
->attrChk
[0]) != 0) ? Yes
: No
;
535 different
|= insertAttribute(dict
, winDic
, ANoTitlebar
, value
, flags
);
537 value
= (WMGetButtonSelected(panel
->attrChk
[1]) != 0) ? Yes
: No
;
538 different
|= insertAttribute(dict
, winDic
, ANoResizebar
, value
, flags
);
540 value
= (WMGetButtonSelected(panel
->attrChk
[2]) != 0) ? Yes
: No
;
541 different
|= insertAttribute(dict
, winDic
, ANoCloseButton
, value
, flags
);
543 value
= (WMGetButtonSelected(panel
->attrChk
[3]) != 0) ? Yes
: No
;
544 different
|= insertAttribute(dict
, winDic
, ANoMiniaturizeButton
, value
, flags
);
546 value
= (WMGetButtonSelected(panel
->attrChk
[4]) != 0) ? Yes
: No
;
547 different
|= insertAttribute(dict
, winDic
, ANoBorder
, value
, flags
);
549 value
= (WMGetButtonSelected(panel
->attrChk
[5]) != 0) ? Yes
: No
;
550 different
|= insertAttribute(dict
, winDic
, AKeepOnTop
, value
, flags
);
552 value
= (WMGetButtonSelected(panel
->attrChk
[6]) != 0) ? Yes
: No
;
553 different
|= insertAttribute(dict
, winDic
, AKeepOnBottom
, value
, flags
);
555 value
= (WMGetButtonSelected(panel
->attrChk
[7]) != 0) ? Yes
: No
;
556 different
|= insertAttribute(dict
, winDic
, AOmnipresent
, value
, flags
);
558 value
= (WMGetButtonSelected(panel
->attrChk
[8]) != 0) ? Yes
: No
;
559 different
|= insertAttribute(dict
, winDic
, AStartMiniaturized
, value
, flags
);
561 value
= (WMGetButtonSelected(panel
->attrChk
[9]) != 0) ? Yes
: No
;
562 different
|= insertAttribute(dict
, winDic
, AStartMaximized
, value
, flags
);
564 value
= (WMGetButtonSelected(panel
->attrChk
[10]) != 0) ? Yes
: No
;
565 different
|= insertAttribute(dict
, winDic
, AFullMaximize
, value
, flags
);
567 value
= (WMGetButtonSelected(panel
->moreChk
[0]) != 0) ? Yes
: No
;
568 different
|= insertAttribute(dict
, winDic
, ANoKeyBindings
, value
, flags
);
570 value
= (WMGetButtonSelected(panel
->moreChk
[1]) != 0) ? Yes
: No
;
571 different
|= insertAttribute(dict
, winDic
, ANoMouseBindings
, value
, flags
);
573 value
= (WMGetButtonSelected(panel
->moreChk
[2]) != 0) ? Yes
: No
;
574 different
|= insertAttribute(dict
, winDic
, ASkipWindowList
, value
, flags
);
576 value
= (WMGetButtonSelected(panel
->moreChk
[3]) != 0) ? Yes
: No
;
577 different
|= insertAttribute(dict
, winDic
, AUnfocusable
, value
, flags
);
579 value
= (WMGetButtonSelected(panel
->moreChk
[4]) != 0) ? Yes
: No
;
580 different
|= insertAttribute(dict
, winDic
, AKeepInsideScreen
, value
, flags
);
582 value
= (WMGetButtonSelected(panel
->moreChk
[5]) != 0) ? Yes
: No
;
583 different
|= insertAttribute(dict
, winDic
, ANoHideOthers
, value
, flags
);
585 value
= (WMGetButtonSelected(panel
->moreChk
[6]) != 0) ? Yes
: No
;
586 different
|= insertAttribute(dict
, winDic
, ADontSaveSession
, value
, flags
);
588 value
= (WMGetButtonSelected(panel
->moreChk
[7]) != 0) ? Yes
: No
;
589 different
|= insertAttribute(dict
, winDic
, AEmulateAppIcon
, value
, flags
);
591 value
= (WMGetButtonSelected(panel
->moreChk
[8]) != 0) ? Yes
: No
;
592 different
|= insertAttribute(dict
, winDic
, ADontFocusAcrossWorkspace
, value
, flags
);
594 #ifdef XKB_BUTTON_HINT
595 value
= (WMGetButtonSelected(panel
->moreChk
[9]) != 0) ? Yes
: No
;
596 different
|= insertAttribute(dict
, winDic
, ANoLanguageButton
, value
, flags
);
599 if (wwin
->main_window
!= None
&& wApplicationOf(wwin
->main_window
) != NULL
) {
600 value
= (WMGetButtonSelected(panel
->appChk
[0]) != 0) ? Yes
: No
;
601 different2
|= insertAttribute(dict
, appDic
, AStartHidden
, value
, flags
);
603 value
= (WMGetButtonSelected(panel
->appChk
[1]) != 0) ? Yes
: No
;
604 different2
|= insertAttribute(dict
, appDic
, ANoAppIcon
, value
, flags
);
606 value
= (WMGetButtonSelected(panel
->appChk
[2]) != 0) ? Yes
: No
;
607 different2
|= insertAttribute(dict
, appDic
, ASharedAppIcon
, value
, flags
);
610 if (wwin
->fake_group
) {
611 key2
= WMCreatePLString(wwin
->fake_group
->identifier
);
612 if (WMIsPropListEqualTo(key
, key2
)) {
613 WMMergePLDictionaries(winDic
, appDic
, True
);
614 different
|= different2
;
616 WMRemoveFromPLDictionary(dict
, key2
);
618 WMPutInPLDictionary(dict
, key2
, appDic
);
621 WMReleasePropList(key2
);
622 WMReleasePropList(appDic
);
623 } else if (wwin
->main_window
!= wwin
->client_win
) {
624 WApplication
*wapp
= wApplicationOf(wwin
->main_window
);
627 char *instance
= wapp
->main_window_desc
->wm_instance
;
628 char *class = wapp
->main_window_desc
->wm_class
;
631 buffer
= StrConcatDot(instance
, class);
632 key2
= WMCreatePLString(buffer
);
635 if (WMIsPropListEqualTo(key
, key2
)) {
636 WMMergePLDictionaries(winDic
, appDic
, True
);
637 different
|= different2
;
639 WMRemoveFromPLDictionary(dict
, key2
);
641 WMPutInPLDictionary(dict
, key2
, appDic
);
644 WMReleasePropList(key2
);
645 WMReleasePropList(appDic
);
648 WMMergePLDictionaries(winDic
, appDic
, True
);
649 different
|= different2
;
650 WMReleasePropList(appDic
);
653 WMRemoveFromPLDictionary(dict
, key
);
655 WMPutInPLDictionary(dict
, key
, winDic
);
658 WMReleasePropList(key
);
659 WMReleasePropList(winDic
);
661 UpdateDomainFile(db
);
664 WMPLSetCaseSensitive(False
);
667 static void makeAppIconFor(WApplication
* wapp
)
669 WScreen
*scr
= wapp
->main_window_desc
->screen_ptr
;
674 if (!WFLAGP(wapp
->main_window_desc
, no_appicon
))
675 wapp
->app_icon
= wAppIconCreate(wapp
->main_window_desc
);
677 wapp
->app_icon
= NULL
;
679 if (wapp
->app_icon
) {
680 WIcon
*icon
= wapp
->app_icon
->icon
;
681 WDock
*clip
= scr
->workspaces
[scr
->current_workspace
]->clip
;
684 wapp
->app_icon
->main_window
= wapp
->main_window
;
686 if (clip
&& clip
->attract_icons
&& wDockFindFreeSlot(clip
, &x
, &y
)) {
687 wapp
->app_icon
->attracted
= 1;
688 if (!wapp
->app_icon
->icon
->shadowed
) {
689 wapp
->app_icon
->icon
->shadowed
= 1;
690 wapp
->app_icon
->icon
->force_paint
= 1;
692 wDockAttachIcon(clip
, wapp
->app_icon
, x
, y
);
694 PlaceIcon(scr
, &x
, &y
, wGetHeadForWindow(wapp
->main_window_desc
));
695 wAppIconMove(wapp
->app_icon
, x
, y
);
697 if (!clip
|| !wapp
->app_icon
->attracted
|| !clip
->collapsed
)
698 XMapWindow(dpy
, icon
->core
->window
);
700 if (wPreferences
.auto_arrange_icons
&& !wapp
->app_icon
->attracted
)
701 wArrangeIcons(wapp
->main_window_desc
->screen_ptr
, True
);
705 static void removeAppIconFor(WApplication
* wapp
)
710 if (wapp
->app_icon
->docked
&& !wapp
->app_icon
->attracted
) {
711 wapp
->app_icon
->running
= 0;
712 /* since we keep it, we don't care if it was attracted or not */
713 wapp
->app_icon
->attracted
= 0;
714 wapp
->app_icon
->icon
->shadowed
= 0;
715 wapp
->app_icon
->main_window
= None
;
716 wapp
->app_icon
->pid
= 0;
717 wapp
->app_icon
->icon
->owner
= NULL
;
718 wapp
->app_icon
->icon
->icon_win
= None
;
719 wapp
->app_icon
->icon
->force_paint
= 1;
720 wAppIconPaint(wapp
->app_icon
);
721 } else if (wapp
->app_icon
->docked
) {
722 wapp
->app_icon
->running
= 0;
723 wDockDetach(wapp
->app_icon
->dock
, wapp
->app_icon
);
725 wAppIconDestroy(wapp
->app_icon
);
727 wapp
->app_icon
= NULL
;
728 if (wPreferences
.auto_arrange_icons
)
729 wArrangeIcons(wapp
->main_window_desc
->screen_ptr
, True
);
732 static void applySettings(WMButton
* button
, InspectorPanel
* panel
)
734 WWindow
*wwin
= panel
->inspected
;
735 WApplication
*wapp
= wApplicationOf(wwin
->main_window
);
736 int floating
, sunken
, skip_window_list
;
738 int old_no_bind_keys
;
739 int old_no_bind_mouse
;
741 old_omnipresent
= WFLAGP(wwin
, omnipresent
);
742 old_no_bind_keys
= WFLAGP(wwin
, no_bind_keys
);
743 old_no_bind_mouse
= WFLAGP(wwin
, no_bind_mouse
);
745 showIconFor(WMWidgetScreen(button
), panel
, NULL
, NULL
, USE_TEXT_FIELD
);
747 /* Attributes... --> Window Attributes */
748 WSETUFLAG(wwin
, no_titlebar
, WMGetButtonSelected(panel
->attrChk
[0]));
749 WSETUFLAG(wwin
, no_resizebar
, WMGetButtonSelected(panel
->attrChk
[1]));
750 WSETUFLAG(wwin
, no_close_button
, WMGetButtonSelected(panel
->attrChk
[2]));
751 WSETUFLAG(wwin
, no_miniaturize_button
, WMGetButtonSelected(panel
->attrChk
[3]));
752 WSETUFLAG(wwin
, no_border
, WMGetButtonSelected(panel
->attrChk
[4]));
753 floating
= WMGetButtonSelected(panel
->attrChk
[5]);
754 sunken
= WMGetButtonSelected(panel
->attrChk
[6]);
755 WSETUFLAG(wwin
, omnipresent
, WMGetButtonSelected(panel
->attrChk
[7]));
756 WSETUFLAG(wwin
, start_miniaturized
, WMGetButtonSelected(panel
->attrChk
[8]));
757 WSETUFLAG(wwin
, start_maximized
, WMGetButtonSelected(panel
->attrChk
[9]));
758 WSETUFLAG(wwin
, full_maximize
, WMGetButtonSelected(panel
->attrChk
[10]));
760 /* Attributes... --> Advanced Options */
761 WSETUFLAG(wwin
, no_bind_keys
, WMGetButtonSelected(panel
->moreChk
[0]));
762 WSETUFLAG(wwin
, no_bind_mouse
, WMGetButtonSelected(panel
->moreChk
[1]));
763 skip_window_list
= WMGetButtonSelected(panel
->moreChk
[2]);
764 WSETUFLAG(wwin
, no_focusable
, WMGetButtonSelected(panel
->moreChk
[3]));
765 WSETUFLAG(wwin
, dont_move_off
, WMGetButtonSelected(panel
->moreChk
[4]));
766 WSETUFLAG(wwin
, no_hide_others
, WMGetButtonSelected(panel
->moreChk
[5]));
767 WSETUFLAG(wwin
, dont_save_session
, WMGetButtonSelected(panel
->moreChk
[6]));
768 WSETUFLAG(wwin
, emulate_appicon
, WMGetButtonSelected(panel
->moreChk
[7]));
769 WSETUFLAG(wwin
, dont_focus_across_wksp
, WMGetButtonSelected(panel
->moreChk
[8]));
770 #ifdef XKB_BUTTON_HINT
771 WSETUFLAG(wwin
, no_language_button
, WMGetButtonSelected(panel
->moreChk
[9]));
773 WSETUFLAG(wwin
, always_user_icon
, WMGetButtonSelected(panel
->alwChk
));
775 if (WFLAGP(wwin
, no_titlebar
) && wwin
->flags
.shaded
)
776 wUnshadeWindow(wwin
);
778 WSETUFLAG(wwin
, no_shadeable
, WFLAGP(wwin
, no_titlebar
));
781 if (!WFLAGP(wwin
, floating
))
782 ChangeStackingLevel(wwin
->frame
->core
, WMFloatingLevel
);
784 if (!WFLAGP(wwin
, sunken
))
785 ChangeStackingLevel(wwin
->frame
->core
, WMSunkenLevel
);
787 if (WFLAGP(wwin
, floating
) || WFLAGP(wwin
, sunken
))
788 ChangeStackingLevel(wwin
->frame
->core
, WMNormalLevel
);
791 WSETUFLAG(wwin
, sunken
, sunken
);
792 WSETUFLAG(wwin
, floating
, floating
);
793 wwin
->flags
.omnipresent
= 0;
795 if (WFLAGP(wwin
, skip_window_list
) != skip_window_list
) {
796 WSETUFLAG(wwin
, skip_window_list
, skip_window_list
);
797 UpdateSwitchMenu(wwin
->screen_ptr
, wwin
, skip_window_list
? ACTION_REMOVE
: ACTION_ADD
);
799 if (WFLAGP(wwin
, omnipresent
) != old_omnipresent
) {
800 WMPostNotificationName(WMNChangedState
, wwin
, "omnipresent");
804 if (WFLAGP(wwin
, no_bind_keys
) != old_no_bind_keys
) {
805 if (WFLAGP(wwin
, no_bind_keys
)) {
806 XUngrabKey(dpy
, AnyKey
, AnyModifier
, wwin
->frame
->core
->window
);
808 wWindowSetKeyGrabs(wwin
);
812 if (WFLAGP(wwin
, no_bind_mouse
) != old_no_bind_mouse
) {
813 wWindowResetMouseGrabs(wwin
);
816 wwin
->frame
->flags
.need_texture_change
= 1;
817 wWindowConfigureBorders(wwin
);
818 wFrameWindowPaint(wwin
->frame
);
819 wNETWMUpdateActions(wwin
, False
);
822 * Can't apply emulate_appicon because it will probably cause problems.
825 /* do application wide stuff */
826 WSETUFLAG(wapp
->main_window_desc
, start_hidden
, WMGetButtonSelected(panel
->appChk
[0]));
828 WSETUFLAG(wapp
->main_window_desc
, no_appicon
, WMGetButtonSelected(panel
->appChk
[1]));
830 WSETUFLAG(wapp
->main_window_desc
, shared_appicon
, WMGetButtonSelected(panel
->appChk
[2]));
832 if (WFLAGP(wapp
->main_window_desc
, no_appicon
))
833 removeAppIconFor(wapp
);
835 makeAppIconFor(wapp
);
837 if (wapp
->app_icon
&& wapp
->main_window
== wwin
->client_win
) {
838 char *file
= WMGetTextFieldText(panel
->fileText
);
844 wIconChangeImageFile(wapp
->app_icon
->icon
, file
);
847 wAppIconPaint(wapp
->app_icon
);
852 static void revertSettings(WMButton
* button
, InspectorPanel
* panel
)
854 WWindow
*wwin
= panel
->inspected
;
855 WApplication
*wapp
= wApplicationOf(wwin
->main_window
);
857 char *wm_instance
= NULL
;
858 char *wm_class
= NULL
;
859 int workspace
, level
;
861 if (panel
->instRb
&& WMGetButtonSelected(panel
->instRb
) != 0)
862 wm_instance
= wwin
->wm_instance
;
863 else if (panel
->clsRb
&& WMGetButtonSelected(panel
->clsRb
) != 0)
864 wm_class
= wwin
->wm_class
;
865 else if (panel
->bothRb
&& WMGetButtonSelected(panel
->bothRb
) != 0) {
866 wm_instance
= wwin
->wm_instance
;
867 wm_class
= wwin
->wm_class
;
869 memset(&wwin
->defined_user_flags
, 0, sizeof(WWindowAttributes
));
870 memset(&wwin
->user_flags
, 0, sizeof(WWindowAttributes
));
871 memset(&wwin
->client_flags
, 0, sizeof(WWindowAttributes
));
873 wWindowSetupInitialAttributes(wwin
, &level
, &workspace
);
875 for (i
= 0; i
< 11; i
++) {
880 flag
= WFLAGP(wwin
, no_titlebar
);
883 flag
= WFLAGP(wwin
, no_resizebar
);
886 flag
= WFLAGP(wwin
, no_close_button
);
889 flag
= WFLAGP(wwin
, no_miniaturize_button
);
892 flag
= WFLAGP(wwin
, no_border
);
895 flag
= WFLAGP(wwin
, floating
);
898 flag
= WFLAGP(wwin
, sunken
);
901 flag
= WFLAGP(wwin
, omnipresent
);
904 flag
= WFLAGP(wwin
, start_miniaturized
);
907 flag
= WFLAGP(wwin
, start_maximized
!= 0);
910 flag
= WFLAGP(wwin
, full_maximize
);
913 WMSetButtonSelected(panel
->attrChk
[i
], flag
);
915 for (i
= 0; i
< 9; i
++) {
920 flag
= WFLAGP(wwin
, no_bind_keys
);
923 flag
= WFLAGP(wwin
, no_bind_mouse
);
926 flag
= WFLAGP(wwin
, skip_window_list
);
929 flag
= WFLAGP(wwin
, no_focusable
);
932 flag
= WFLAGP(wwin
, dont_move_off
);
935 flag
= WFLAGP(wwin
, no_hide_others
);
938 flag
= WFLAGP(wwin
, dont_save_session
);
941 flag
= WFLAGP(wwin
, emulate_appicon
);
944 flag
= WFLAGP(wwin
, dont_focus_across_wksp
);
946 #ifdef XKB_BUTTON_HINT
948 flag
= WFLAGP(wwin
, no_language_button
);
952 WMSetButtonSelected(panel
->moreChk
[i
], flag
);
954 if (panel
->appFrm
&& wapp
) {
955 for (i
= 0; i
< 2; i
++) {
960 flag
= WFLAGP(wapp
->main_window_desc
, start_hidden
);
963 flag
= WFLAGP(wapp
->main_window_desc
, no_appicon
);
966 flag
= WFLAGP(wapp
->main_window_desc
, shared_appicon
);
969 WMSetButtonSelected(panel
->appChk
[i
], flag
);
972 WMSetButtonSelected(panel
->alwChk
, WFLAGP(wwin
, always_user_icon
));
974 showIconFor(WMWidgetScreen(panel
->alwChk
), panel
, wm_instance
, wm_class
, REVERT_TO_DEFAULT
);
976 n
= wDefaultGetStartWorkspace(wwin
->screen_ptr
, wm_instance
, wm_class
);
978 if (n
>= 0 && n
< wwin
->screen_ptr
->workspace_count
) {
979 WMSetPopUpButtonSelectedItem(panel
->wsP
, n
+ 1);
981 WMSetPopUpButtonSelectedItem(panel
->wsP
, 0);
984 /* must auto apply, so that there wno't be internal
985 * inconsistencies between the state in the flags and
986 * the actual state of the window */
987 applySettings(panel
->applyBtn
, panel
);
990 static void chooseIconCallback(WMWidget
* self
, void *clientData
)
993 InspectorPanel
*panel
= (InspectorPanel
*) clientData
;
996 panel
->choosingIcon
= 1;
998 WMSetButtonEnabled(panel
->browseIconBtn
, False
);
1000 result
= wIconChooserDialog(panel
->frame
->screen_ptr
, &file
,
1001 panel
->inspected
->wm_instance
, panel
->inspected
->wm_class
);
1003 panel
->choosingIcon
= 0;
1005 if (!panel
->destroyed
) { /* kluge */
1007 WMSetTextFieldText(panel
->fileText
, file
);
1008 showIconFor(WMWidgetScreen(self
), panel
, NULL
, NULL
, USE_TEXT_FIELD
);
1011 WMSetButtonEnabled(panel
->browseIconBtn
, True
);
1013 freeInspector(panel
);
1017 static void textEditedObserver(void *observerData
, WMNotification
* notification
)
1019 InspectorPanel
*panel
= (InspectorPanel
*) observerData
;
1021 if ((long)WMGetNotificationClientData(notification
) != WMReturnTextMovement
)
1024 showIconFor(WMWidgetScreen(panel
->win
), panel
, NULL
, NULL
, USE_TEXT_FIELD
);
1026 WMPerformButtonClick(panel->updateIconBtn);
1030 static void selectSpecification(WMWidget
* bPtr
, void *data
)
1032 InspectorPanel
*panel
= (InspectorPanel
*) data
;
1034 WWindow
*wwin
= panel
->inspected
;
1037 if (bPtr
== panel
->defaultRb
&& (wwin
->wm_instance
|| wwin
->wm_class
)) {
1038 WMSetButtonEnabled(panel
->applyBtn
, False
);
1040 WMSetButtonEnabled(panel
->applyBtn
, True
);
1043 len
= 16 + strlen(wwin
->wm_instance
? wwin
->wm_instance
: "?")
1044 + strlen(wwin
->wm_class
? wwin
->wm_class
: "?");
1048 snprintf(str
, len
, _("Inspecting %s.%s"),
1049 wwin
->wm_instance
? wwin
->wm_instance
: "?", wwin
->wm_class
? wwin
->wm_class
: "?");
1051 wFrameWindowChangeTitle(panel
->frame
->frame
, str
);
1056 static void selectWindow(WMWidget
* bPtr
, void *data
)
1058 InspectorPanel
*panel
= (InspectorPanel
*) data
;
1059 WWindow
*wwin
= panel
->inspected
;
1060 WScreen
*scr
= wwin
->screen_ptr
;
1064 if (XGrabPointer(dpy
, scr
->root_win
, True
,
1065 ButtonPressMask
, GrabModeAsync
, GrabModeAsync
, None
,
1066 wCursor
[WCUR_SELECT
], CurrentTime
) != GrabSuccess
) {
1067 wwarning("could not grab mouse pointer");
1071 WMSetLabelText(panel
->specLbl
, _("Click in the window you wish to inspect."));
1073 WMMaskEvent(dpy
, ButtonPressMask
, &event
);
1075 XUngrabPointer(dpy
, CurrentTime
);
1077 iwin
= wWindowFor(event
.xbutton
.subwindow
);
1079 if (iwin
&& !iwin
->flags
.internal_window
&& iwin
!= wwin
&& !iwin
->flags
.inspector_open
) {
1081 iwin
->flags
.inspector_open
= 1;
1082 iwin
->inspector
= createInspectorForWindow(iwin
,
1083 panel
->frame
->frame_x
, panel
->frame
->frame_y
, True
);
1084 wCloseInspectorForWindow(wwin
);
1086 WMSetLabelText(panel
->specLbl
, spec_text
);
1090 static InspectorPanel
*createInspectorForWindow(WWindow
* wwin
, int xpos
, int ypos
, Bool showSelectPanel
)
1092 WScreen
*scr
= wwin
->screen_ptr
;
1093 InspectorPanel
*panel
;
1097 int btn_width
, frame_width
;
1098 WMButton
*selectedBtn
= NULL
;
1099 #ifdef wrong_behaviour
1103 spec_text
= _("The configuration will apply to all\n"
1104 "windows that have their WM_CLASS\n"
1105 "property set to the above selected\n" "name, when saved.");
1107 panel
= wmalloc(sizeof(InspectorPanel
));
1108 memset(panel
, 0, sizeof(InspectorPanel
));
1110 panel
->destroyed
= 0;
1112 panel
->inspected
= wwin
;
1114 panel
->nextPtr
= panelList
;
1117 panel
->win
= WMCreateWindow(scr
->wmscreen
, "windowInspector");
1118 WMResizeWidget(panel
->win
, PWIDTH
, PHEIGHT
);
1120 /**** create common stuff ****/
1122 /* command buttons */
1123 /* (PWIDTH - (left and right margin) - (btn interval)) / 3 */
1124 btn_width
= (PWIDTH
- (2 * 15) - (2 * 10)) / 3;
1125 panel
->saveBtn
= WMCreateCommandButton(panel
->win
);
1126 WMSetButtonAction(panel
->saveBtn
, (WMAction
*) saveSettings
, panel
);
1127 WMMoveWidget(panel
->saveBtn
, (2 * (btn_width
+ 10)) + 15, 310);
1128 WMSetButtonText(panel
->saveBtn
, _("Save"));
1129 WMResizeWidget(panel
->saveBtn
, btn_width
, 28);
1130 if (wPreferences
.flags
.noupdates
|| !(wwin
->wm_class
|| wwin
->wm_instance
))
1131 WMSetButtonEnabled(panel
->saveBtn
, False
);
1133 panel
->applyBtn
= WMCreateCommandButton(panel
->win
);
1134 WMSetButtonAction(panel
->applyBtn
, (WMAction
*) applySettings
, panel
);
1135 WMMoveWidget(panel
->applyBtn
, btn_width
+ 10 + 15, 310);
1136 WMSetButtonText(panel
->applyBtn
, _("Apply"));
1137 WMResizeWidget(panel
->applyBtn
, btn_width
, 28);
1139 panel
->revertBtn
= WMCreateCommandButton(panel
->win
);
1140 WMSetButtonAction(panel
->revertBtn
, (WMAction
*) revertSettings
, panel
);
1141 WMMoveWidget(panel
->revertBtn
, 15, 310);
1142 WMSetButtonText(panel
->revertBtn
, _("Reload"));
1143 WMResizeWidget(panel
->revertBtn
, btn_width
, 28);
1145 /* page selection popup button */
1146 panel
->pagePopUp
= WMCreatePopUpButton(panel
->win
);
1147 WMSetPopUpButtonAction(panel
->pagePopUp
, (WMAction
*) changePage
, panel
);
1148 WMMoveWidget(panel
->pagePopUp
, 25, 15);
1149 WMResizeWidget(panel
->pagePopUp
, PWIDTH
- 50, 20);
1151 WMAddPopUpButtonItem(panel
->pagePopUp
, _("Window Specification"));
1152 WMAddPopUpButtonItem(panel
->pagePopUp
, _("Window Attributes"));
1153 WMAddPopUpButtonItem(panel
->pagePopUp
, _("Advanced Options"));
1154 WMAddPopUpButtonItem(panel
->pagePopUp
, _("Icon and Initial Workspace"));
1155 WMAddPopUpButtonItem(panel
->pagePopUp
, _("Application Specific"));
1157 /**** window spec ****/
1158 frame_width
= PWIDTH
- (2 * 15);
1160 panel
->specFrm
= WMCreateFrame(panel
->win
);
1161 WMSetFrameTitle(panel
->specFrm
, _("Window Specification"));
1162 WMMoveWidget(panel
->specFrm
, 15, 65);
1163 WMResizeWidget(panel
->specFrm
, frame_width
, 145);
1165 panel
->defaultRb
= WMCreateRadioButton(panel
->specFrm
);
1166 WMMoveWidget(panel
->defaultRb
, 10, 78);
1167 WMResizeWidget(panel
->defaultRb
, frame_width
- (2 * 10), 20);
1168 WMSetButtonText(panel
->defaultRb
, _("Defaults for all windows"));
1169 WMSetButtonSelected(panel
->defaultRb
, False
);
1170 WMSetButtonAction(panel
->defaultRb
, selectSpecification
, panel
);
1172 if (wwin
->wm_class
&& wwin
->wm_instance
) {
1175 tmp
= wstrconcat(wwin
->wm_instance
, ".");
1176 str
= wstrconcat(tmp
, wwin
->wm_class
);
1178 panel
->bothRb
= WMCreateRadioButton(panel
->specFrm
);
1179 WMMoveWidget(panel
->bothRb
, 10, 18);
1180 WMResizeWidget(panel
->bothRb
, frame_width
- (2 * 10), 20);
1181 WMSetButtonText(panel
->bothRb
, str
);
1184 WMGroupButtons(panel
->defaultRb
, panel
->bothRb
);
1187 selectedBtn
= panel
->bothRb
;
1189 WMSetButtonAction(panel
->bothRb
, selectSpecification
, panel
);
1192 if (wwin
->wm_instance
) {
1193 panel
->instRb
= WMCreateRadioButton(panel
->specFrm
);
1194 WMMoveWidget(panel
->instRb
, 10, 38);
1195 WMResizeWidget(panel
->instRb
, frame_width
- (2 * 10), 20);
1196 WMSetButtonText(panel
->instRb
, wwin
->wm_instance
);
1197 WMGroupButtons(panel
->defaultRb
, panel
->instRb
);
1200 selectedBtn
= panel
->instRb
;
1202 WMSetButtonAction(panel
->instRb
, selectSpecification
, panel
);
1205 if (wwin
->wm_class
) {
1206 panel
->clsRb
= WMCreateRadioButton(panel
->specFrm
);
1207 WMMoveWidget(panel
->clsRb
, 10, 58);
1208 WMResizeWidget(panel
->clsRb
, frame_width
- (2 * 10), 20);
1209 WMSetButtonText(panel
->clsRb
, wwin
->wm_class
);
1210 WMGroupButtons(panel
->defaultRb
, panel
->clsRb
);
1213 selectedBtn
= panel
->clsRb
;
1215 WMSetButtonAction(panel
->clsRb
, selectSpecification
, panel
);
1218 panel
->selWinB
= WMCreateCommandButton(panel
->specFrm
);
1219 WMMoveWidget(panel
->selWinB
, 20, 145 - 24 - 10);
1220 WMResizeWidget(panel
->selWinB
, frame_width
- 2 * 10 - 20, 24);
1221 WMSetButtonText(panel
->selWinB
, _("Select window"));
1222 WMSetButtonAction(panel
->selWinB
, selectWindow
, panel
);
1224 panel
->specLbl
= WMCreateLabel(panel
->win
);
1225 WMMoveWidget(panel
->specLbl
, 15, 210);
1226 WMResizeWidget(panel
->specLbl
, frame_width
, 100);
1227 WMSetLabelText(panel
->specLbl
, spec_text
);
1228 WMSetLabelWraps(panel
->specLbl
, True
);
1230 WMSetLabelTextAlignment(panel
->specLbl
, WALeft
);
1232 /**** attributes ****/
1233 panel
->attrFrm
= WMCreateFrame(panel
->win
);
1234 WMSetFrameTitle(panel
->attrFrm
, _("Attributes"));
1235 WMMoveWidget(panel
->attrFrm
, 15, 45);
1236 WMResizeWidget(panel
->attrFrm
, frame_width
, 250);
1238 for (i
= 0; i
< 11; i
++) {
1239 char *caption
= NULL
;
1245 caption
= _("Disable titlebar");
1246 flag
= WFLAGP(wwin
, no_titlebar
);
1247 descr
= _("Remove the titlebar of this window.\n"
1248 "To access the window commands menu of a window\n"
1249 "without it's titlebar, press Control+Esc (or the\n"
1250 "equivalent shortcut, if you changed the default\n" "settings).");
1253 caption
= _("Disable resizebar");
1254 flag
= WFLAGP(wwin
, no_resizebar
);
1255 descr
= _("Remove the resizebar of this window.");
1258 caption
= _("Disable close button");
1259 flag
= WFLAGP(wwin
, no_close_button
);
1260 descr
= _("Remove the `close window' button of this window.");
1263 caption
= _("Disable miniaturize button");
1264 flag
= WFLAGP(wwin
, no_miniaturize_button
);
1265 descr
= _("Remove the `miniaturize window' button of the window.");
1268 caption
= _("Disable border");
1269 flag
= WFLAGP(wwin
, no_border
);
1270 descr
= _("Remove the 1 pixel black border around the window.");
1273 caption
= _("Keep on top (floating)");
1274 flag
= WFLAGP(wwin
, floating
);
1275 descr
= _("Keep the window over other windows, not allowing\n" "them to cover it.");
1278 caption
= _("Keep at bottom (sunken)");
1279 flag
= WFLAGP(wwin
, sunken
);
1280 descr
= _("Keep the window under all other windows.");
1283 caption
= _("Omnipresent");
1284 flag
= WFLAGP(wwin
, omnipresent
);
1285 descr
= _("Make window present in all workspaces.");
1288 caption
= _("Start miniaturized");
1289 flag
= WFLAGP(wwin
, start_miniaturized
);
1290 descr
= _("Make the window be automatically miniaturized when it's\n" "first shown.");
1293 caption
= _("Start maximized");
1294 flag
= WFLAGP(wwin
, start_maximized
!= 0);
1295 descr
= _("Make the window be automatically maximized when it's\n" "first shown.");
1298 caption
= _("Full screen maximization");
1299 flag
= WFLAGP(wwin
, full_maximize
);
1300 descr
= _("Make the window use the whole screen space when it's\n"
1301 "maximized. The titlebar and resizebar will be moved\n"
1302 "to outside the screen.");
1305 panel
->attrChk
[i
] = WMCreateSwitchButton(panel
->attrFrm
);
1306 WMMoveWidget(panel
->attrChk
[i
], 10, 20 * (i
+ 1));
1307 WMResizeWidget(panel
->attrChk
[i
], frame_width
- 15, 20);
1308 WMSetButtonSelected(panel
->attrChk
[i
], flag
);
1309 WMSetButtonText(panel
->attrChk
[i
], caption
);
1311 WMSetBalloonTextForView(descr
, WMWidgetView(panel
->attrChk
[i
]));
1314 /**** more attributes ****/
1315 panel
->moreFrm
= WMCreateFrame(panel
->win
);
1316 WMSetFrameTitle(panel
->moreFrm
, _("Advanced"));
1317 WMMoveWidget(panel
->moreFrm
, 15, 45);
1318 WMResizeWidget(panel
->moreFrm
, frame_width
, 250);
1321 #ifdef XKB_BUTTON_HINT
1327 char *caption
= NULL
;
1333 caption
= _("Do not bind keyboard shortcuts");
1334 flag
= WFLAGP(wwin
, no_bind_keys
);
1335 descr
= _("Do not bind keyboard shortcuts from Window Maker\n"
1336 "when this window is focused. This will allow the\n"
1337 "window to receive all key combinations regardless\n"
1338 "of your shortcut configuration.");
1341 caption
= _("Do not bind mouse clicks");
1342 flag
= WFLAGP(wwin
, no_bind_mouse
);
1343 descr
= _("Do not bind mouse actions, such as `Alt'+drag\n"
1344 "in the window (when alt is the modifier you have\n" "configured).");
1347 caption
= _("Do not show in the window list");
1348 flag
= WFLAGP(wwin
, skip_window_list
);
1349 descr
= _("Do not list the window in the window list menu.");
1352 caption
= _("Do not let it take focus");
1353 flag
= WFLAGP(wwin
, no_focusable
);
1354 descr
= _("Do not let the window take keyboard focus when you\n" "click on it.");
1357 caption
= _("Keep inside screen");
1358 flag
= WFLAGP(wwin
, dont_move_off
);
1359 descr
= _("Do not allow the window to move itself completely\n"
1360 "outside the screen. For bug compatibility.\n");
1363 caption
= _("Ignore 'Hide Others'");
1364 flag
= WFLAGP(wwin
, no_hide_others
);
1365 descr
= _("Do not hide the window when issuing the\n" "`HideOthers' command.");
1368 caption
= _("Ignore 'Save Session'");
1369 flag
= WFLAGP(wwin
, dont_save_session
);
1370 descr
= _("Do not save the associated application in the\n"
1371 "session's state, so that it won't be restarted\n"
1372 "together with other applications when Window Maker\n" "starts.");
1375 caption
= _("Emulate application icon");
1376 flag
= WFLAGP(wwin
, emulate_appicon
);
1377 descr
= _("Make this window act as an application that provides\n"
1378 "enough information to Window Maker for a dockable\n"
1379 "application icon to be created.");
1382 caption
= _("Don't focus across workspaces");
1383 flag
= WFLAGP(wwin
, dont_focus_across_wksp
);
1384 descr
= _("Do not allow Window Maker to switch workspace to satisfy\n"
1385 "a focus request (useful e.g. in the case of a multiple-tab\n"
1386 "firefox opening in a different workspace).");
1388 #ifdef XKB_BUTTON_HINT
1390 caption
= _("Disable language button");
1391 flag
= WFLAGP(wwin
, no_language_button
);
1392 descr
= _("Remove the `toggle language' button of the window.");
1396 panel
->moreChk
[i
] = WMCreateSwitchButton(panel
->moreFrm
);
1397 WMMoveWidget(panel
->moreChk
[i
], 10, 20 * (i
+ 1));
1398 WMResizeWidget(panel
->moreChk
[i
], frame_width
- 15, 20);
1399 WMSetButtonSelected(panel
->moreChk
[i
], flag
);
1400 WMSetButtonText(panel
->moreChk
[i
], caption
);
1402 WMSetBalloonTextForView(descr
, WMWidgetView(panel
->moreChk
[i
]));
1405 /* miniwindow/workspace */
1406 panel
->iconFrm
= WMCreateFrame(panel
->win
);
1407 WMMoveWidget(panel
->iconFrm
, 15, 50);
1408 WMResizeWidget(panel
->iconFrm
, PWIDTH
- (2 * 15), 170);
1409 WMSetFrameTitle(panel
->iconFrm
, _("Miniwindow Image"));
1411 panel
->iconLbl
= WMCreateLabel(panel
->iconFrm
);
1412 WMMoveWidget(panel
->iconLbl
, PWIDTH
- (2 * 15) - 22 - 64, 20);
1413 WMResizeWidget(panel
->iconLbl
, 64, 64);
1414 WMSetLabelRelief(panel
->iconLbl
, WRGroove
);
1415 WMSetLabelImagePosition(panel
->iconLbl
, WIPImageOnly
);
1417 panel
->browseIconBtn
= WMCreateCommandButton(panel
->iconFrm
);
1418 WMSetButtonAction(panel
->browseIconBtn
, chooseIconCallback
, panel
);
1419 WMMoveWidget(panel
->browseIconBtn
, 22, 32);
1420 WMResizeWidget(panel
->browseIconBtn
, 120, 26);
1421 WMSetButtonText(panel
->browseIconBtn
, _("Browse..."));
1423 #ifdef wrong_behaviour
1424 WMSetButtonImagePosition(panel
->updateIconBtn
, WIPRight
);
1425 pixmap
= WMGetSystemPixmap(scr
->wmscreen
, WSIReturnArrow
);
1426 WMSetButtonImage(panel
->updateIconBtn
, pixmap
);
1427 WMReleasePixmap(pixmap
);
1428 pixmap
= WMGetSystemPixmap(scr
->wmscreen
, WSIHighlightedReturnArrow
);
1429 WMSetButtonAltImage(panel
->updateIconBtn
, pixmap
);
1430 WMReleasePixmap(pixmap
);
1433 panel
->fileLbl
= WMCreateLabel(panel
->iconFrm
);
1434 WMMoveWidget(panel
->fileLbl
, 20, 85);
1435 WMResizeWidget(panel
->fileLbl
, PWIDTH
- (2 * 15) - (2 * 20), 14);
1436 WMSetLabelText(panel
->fileLbl
, _("Icon filename:"));
1438 panel
->fileText
= WMCreateTextField(panel
->iconFrm
);
1439 WMMoveWidget(panel
->fileText
, 20, 105);
1440 WMResizeWidget(panel
->fileText
, PWIDTH
- (2 * 20) - (2 * 15), 20);
1441 WMSetTextFieldText(panel
->fileText
, NULL
);
1442 WMAddNotificationObserver(textEditedObserver
, panel
, WMTextDidEndEditingNotification
, panel
->fileText
);
1444 panel
->alwChk
= WMCreateSwitchButton(panel
->iconFrm
);
1445 WMMoveWidget(panel
->alwChk
, 20, 130);
1446 WMResizeWidget(panel
->alwChk
, PWIDTH
- (2 * 15) - (2 * 15), 30);
1447 WMSetButtonText(panel
->alwChk
, _("Ignore client supplied icon"));
1448 WMSetButtonSelected(panel
->alwChk
, WFLAGP(wwin
, always_user_icon
));
1450 panel
->wsFrm
= WMCreateFrame(panel
->win
);
1451 WMMoveWidget(panel
->wsFrm
, 15, 225);
1452 WMResizeWidget(panel
->wsFrm
, PWIDTH
- (2 * 15), 70);
1453 WMSetFrameTitle(panel
->wsFrm
, _("Initial Workspace"));
1455 WMSetBalloonTextForView(_("The workspace to place the window when it's"
1456 "first shown."), WMWidgetView(panel
->wsFrm
));
1458 panel
->wsP
= WMCreatePopUpButton(panel
->wsFrm
);
1459 WMMoveWidget(panel
->wsP
, 20, 30);
1460 WMResizeWidget(panel
->wsP
, PWIDTH
- (2 * 15) - (2 * 20), 20);
1461 WMAddPopUpButtonItem(panel
->wsP
, _("Nowhere in particular"));
1462 for (i
= 0; i
< wwin
->screen_ptr
->workspace_count
; i
++) {
1463 WMAddPopUpButtonItem(panel
->wsP
, scr
->workspaces
[i
]->name
);
1466 i
= wDefaultGetStartWorkspace(wwin
->screen_ptr
, wwin
->wm_instance
, wwin
->wm_class
);
1467 if (i
>= 0 && i
<= wwin
->screen_ptr
->workspace_count
) {
1468 WMSetPopUpButtonSelectedItem(panel
->wsP
, i
+ 1);
1470 WMSetPopUpButtonSelectedItem(panel
->wsP
, 0);
1473 /* application wide attributes */
1474 if (wwin
->main_window
!= None
) {
1475 WApplication
*wapp
= wApplicationOf(wwin
->main_window
);
1477 panel
->appFrm
= WMCreateFrame(panel
->win
);
1478 WMSetFrameTitle(panel
->appFrm
, _("Application Attributes"));
1479 WMMoveWidget(panel
->appFrm
, 15, 50);
1480 WMResizeWidget(panel
->appFrm
, frame_width
, 240);
1482 for (i
= 0; i
< 3; i
++) {
1483 char *caption
= NULL
;
1489 caption
= _("Start hidden");
1490 flag
= WFLAGP(wapp
->main_window_desc
, start_hidden
);
1491 descr
= _("Automatically hide application when it's started.");
1494 caption
= _("No application icon");
1495 flag
= WFLAGP(wapp
->main_window_desc
, no_appicon
);
1496 descr
= _("Disable the application icon for the application.\n"
1497 "Note that you won't be able to dock it anymore,\n"
1498 "and any icons that are already docked will stop\n"
1499 "working correctly.");
1502 caption
= _("Shared application icon");
1503 flag
= WFLAGP(wapp
->main_window_desc
, shared_appicon
);
1504 descr
= _("Use a single shared application icon for all of\n"
1505 "the instances of this application.\n");
1508 panel
->appChk
[i
] = WMCreateSwitchButton(panel
->appFrm
);
1509 WMMoveWidget(panel
->appChk
[i
], 10, 20 * (i
+ 1));
1510 WMResizeWidget(panel
->appChk
[i
], 205, 20);
1511 WMSetButtonSelected(panel
->appChk
[i
], flag
);
1512 WMSetButtonText(panel
->appChk
[i
], caption
);
1514 WMSetBalloonTextForView(descr
, WMWidgetView(panel
->appChk
[i
]));
1517 if (WFLAGP(wwin
, emulate_appicon
)) {
1518 WMSetButtonEnabled(panel
->appChk
[1], False
);
1519 WMSetButtonEnabled(panel
->moreChk
[7], True
);
1521 WMSetButtonEnabled(panel
->appChk
[1], True
);
1522 WMSetButtonEnabled(panel
->moreChk
[7], False
);
1527 if ((wwin
->transient_for
!= None
&& wwin
->transient_for
!= scr
->root_win
)
1528 || !wwin
->wm_class
|| !wwin
->wm_instance
)
1532 WMSetButtonEnabled(panel
->moreChk
[7], tmp
);
1534 WMSetPopUpButtonItemEnabled(panel
->pagePopUp
, 4, False
);
1535 panel
->appFrm
= NULL
;
1538 /* if the window is a transient, don't let it have a miniaturize
1540 if (wwin
->transient_for
!= None
&& wwin
->transient_for
!= scr
->root_win
)
1541 WMSetButtonEnabled(panel
->attrChk
[3], False
);
1543 WMSetButtonEnabled(panel
->attrChk
[3], True
);
1545 if (!wwin
->wm_class
&& !wwin
->wm_instance
) {
1546 WMSetPopUpButtonItemEnabled(panel
->pagePopUp
, 0, False
);
1549 WMRealizeWidget(panel
->win
);
1551 WMMapSubwidgets(panel
->win
);
1552 WMMapSubwidgets(panel
->specFrm
);
1553 WMMapSubwidgets(panel
->attrFrm
);
1554 WMMapSubwidgets(panel
->moreFrm
);
1555 WMMapSubwidgets(panel
->iconFrm
);
1556 WMMapSubwidgets(panel
->wsFrm
);
1558 WMMapSubwidgets(panel
->appFrm
);
1560 if (showSelectPanel
) {
1561 WMSetPopUpButtonSelectedItem(panel
->pagePopUp
, 0);
1562 changePage(panel
->pagePopUp
, panel
);
1564 WMSetPopUpButtonSelectedItem(panel
->pagePopUp
, 1);
1565 changePage(panel
->pagePopUp
, panel
);
1568 parent
= XCreateSimpleWindow(dpy
, scr
->root_win
, 0, 0, PWIDTH
, PHEIGHT
, 0, 0, 0);
1569 XSelectInput(dpy
, parent
, KeyPressMask
| KeyReleaseMask
);
1570 panel
->parent
= parent
;
1571 XReparentWindow(dpy
, WMWidgetXID(panel
->win
), parent
, 0, 0);
1573 WMMapWidget(panel
->win
);
1575 XSetTransientForHint(dpy
, parent
, wwin
->client_win
);
1577 if (xpos
== UNDEFINED_POS
) {
1578 x
= wwin
->frame_x
+ wwin
->frame
->core
->width
/ 2;
1579 y
= wwin
->frame_y
+ wwin
->frame
->top_width
* 2;
1580 if (y
+ PHEIGHT
> scr
->scr_height
)
1581 y
= scr
->scr_height
- PHEIGHT
- 30;
1582 if (x
+ PWIDTH
> scr
->scr_width
)
1583 x
= scr
->scr_width
- PWIDTH
;
1589 panel
->frame
= wManageInternalWindow(scr
, parent
, wwin
->client_win
, "Inspector", x
, y
, PWIDTH
, PHEIGHT
);
1592 selectedBtn
= panel
->defaultRb
;
1594 WMSetButtonSelected(selectedBtn
, True
);
1596 selectSpecification(selectedBtn
, panel
);
1598 /* kluge to know who should get the key events */
1599 panel
->frame
->client_leader
= WMWidgetXID(panel
->win
);
1601 WSETUFLAG(panel
->frame
, no_closable
, 0);
1602 WSETUFLAG(panel
->frame
, no_close_button
, 0);
1603 wWindowUpdateButtonImages(panel
->frame
);
1604 wFrameWindowShowButton(panel
->frame
->frame
, WFF_RIGHT_BUTTON
);
1605 panel
->frame
->frame
->on_click_right
= destroyInspector
;
1607 wWindowMap(panel
->frame
);
1609 showIconFor(WMWidgetScreen(panel
->alwChk
), panel
, wwin
->wm_instance
, wwin
->wm_class
, UPDATE_TEXT_FIELD
);
1614 void wShowInspectorForWindow(WWindow
* wwin
)
1616 if (wwin
->flags
.inspector_open
)
1619 WMSetBalloonEnabled(wwin
->screen_ptr
->wmscreen
, wPreferences
.help_balloon
);
1622 wwin
->flags
.inspector_open
= 1;
1623 wwin
->inspector
= createInspectorForWindow(wwin
, UNDEFINED_POS
, UNDEFINED_POS
, False
);
1626 void wHideInspectorForWindow(WWindow
* wwin
)
1628 WWindow
*pwin
= wwin
->inspector
->frame
;
1631 pwin
->flags
.hidden
= 1;
1633 wClientSetState(pwin
, IconicState
, None
);
1636 void wUnhideInspectorForWindow(WWindow
* wwin
)
1638 WWindow
*pwin
= wwin
->inspector
->frame
;
1640 pwin
->flags
.hidden
= 0;
1641 pwin
->flags
.mapped
= 1;
1642 XMapWindow(dpy
, pwin
->client_win
);
1643 XMapWindow(dpy
, pwin
->frame
->core
->window
);
1644 wClientSetState(pwin
, NormalState
, None
);
1647 WWindow
*wGetWindowOfInspectorForWindow(WWindow
* wwin
)
1649 if (wwin
->inspector
) {
1650 assert(wwin
->flags
.inspector_open
!= 0);
1652 return wwin
->inspector
->frame
;
1657 void wCloseInspectorForWindow(WWindow
* wwin
)
1659 WWindow
*pwin
= wwin
->inspector
->frame
; /* the inspector window */
1661 (*pwin
->frame
->on_click_right
) (NULL
, pwin
, NULL
);