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
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
27 #include <X11/Xutil.h>
32 #include "WindowMaker.h"
37 #include "workspace.h"
43 #include "application.h"
46 #include "winspector.h"
52 #include <WINGs/WUtil.h>
54 typedef struct InspectorPanel
{
55 struct InspectorPanel
*nextPtr
;
59 WWindow
*inspected
; /* the window that's being inspected */
70 WMPopUpButton
*pagePopUp
;
72 /* first page. general stuff */
84 /* second page. attributes */
87 WMButton
*attrChk
[11];
89 /* 3rd page. more attributes */
91 #ifdef XKB_BUTTON_HINT
92 WMButton
*moreChk
[10];
97 /* 4th page. icon and workspace */
101 WMTextField
*fileText
;
104 WMButton *updateIconBtn;
106 WMButton
*browseIconBtn
;
111 /* 5th page. application wide attributes */
116 unsigned int destroyed
:1;
117 unsigned int choosingIcon
:1;
120 extern Cursor wCursor
[WCUR_LAST
];
122 extern WDDomain
*WDWindowAttributes
;
124 static InspectorPanel
*panelList
= NULL
;
126 extern WPreferences wPreferences
;
128 static WMPropList
*ANoTitlebar
= NULL
;
129 static WMPropList
*ANoResizebar
;
130 static WMPropList
*ANoMiniaturizeButton
;
131 static WMPropList
*ANoCloseButton
;
132 static WMPropList
*ANoBorder
;
133 static WMPropList
*ANoHideOthers
;
134 static WMPropList
*ANoMouseBindings
;
135 static WMPropList
*ANoKeyBindings
;
136 static WMPropList
*ANoAppIcon
;
137 static WMPropList
*AKeepOnTop
;
138 static WMPropList
*AKeepOnBottom
;
139 static WMPropList
*AOmnipresent
;
140 static WMPropList
*ASkipWindowList
;
141 static WMPropList
*AKeepInsideScreen
;
142 static WMPropList
*AUnfocusable
;
143 static WMPropList
*ADontFocusAcrossWorkspace
;
144 static WMPropList
*AAlwaysUserIcon
;
145 static WMPropList
*AStartMiniaturized
;
146 static WMPropList
*AStartMaximized
;
147 static WMPropList
*ADontSaveSession
;
148 static WMPropList
*AEmulateAppIcon
;
149 static WMPropList
*AFullMaximize
;
150 static WMPropList
*ASharedAppIcon
;
151 #ifdef XKB_BUTTON_HINT
152 static WMPropList
*ANoLanguageButton
;
155 static WMPropList
*AStartWorkspace
;
157 static WMPropList
*AIcon
;
159 /* application wide options */
160 static WMPropList
*AStartHidden
;
162 static WMPropList
*AnyWindow
;
163 static WMPropList
*EmptyString
;
164 static WMPropList
*Yes
, *No
;
169 static char *spec_text
;
171 static void applySettings(WMButton
* button
, InspectorPanel
* panel
);
173 #define UNDEFINED_POS 0xffffff
175 static InspectorPanel
*createInspectorForWindow(WWindow
* wwin
, int xpos
, int ypos
, Bool showSelectPanel
);
177 static void make_keys()
179 if (ANoTitlebar
!= NULL
)
182 AIcon
= WMCreatePLString("Icon");
183 ANoTitlebar
= WMCreatePLString("NoTitlebar");
184 ANoResizebar
= WMCreatePLString("NoResizebar");
185 ANoMiniaturizeButton
= WMCreatePLString("NoMiniaturizeButton");
186 ANoCloseButton
= WMCreatePLString("NoCloseButton");
187 ANoBorder
= WMCreatePLString("NoBorder");
188 ANoHideOthers
= WMCreatePLString("NoHideOthers");
189 ANoMouseBindings
= WMCreatePLString("NoMouseBindings");
190 ANoKeyBindings
= WMCreatePLString("NoKeyBindings");
191 ANoAppIcon
= WMCreatePLString("NoAppIcon");
192 AKeepOnTop
= WMCreatePLString("KeepOnTop");
193 AKeepOnBottom
= WMCreatePLString("KeepOnBottom");
194 AOmnipresent
= WMCreatePLString("Omnipresent");
195 ASkipWindowList
= WMCreatePLString("SkipWindowList");
196 AKeepInsideScreen
= WMCreatePLString("KeepInsideScreen");
197 AUnfocusable
= WMCreatePLString("Unfocusable");
198 ADontFocusAcrossWorkspace
= WMCreatePLString("DontFocusAcrossWorkspace");
199 AAlwaysUserIcon
= WMCreatePLString("AlwaysUserIcon");
200 AStartMiniaturized
= WMCreatePLString("StartMiniaturized");
201 AStartMaximized
= WMCreatePLString("StartMaximized");
202 AStartHidden
= WMCreatePLString("StartHidden");
203 ADontSaveSession
= WMCreatePLString("DontSaveSession");
204 AEmulateAppIcon
= WMCreatePLString("EmulateAppIcon");
205 AFullMaximize
= WMCreatePLString("FullMaximize");
206 ASharedAppIcon
= WMCreatePLString("SharedAppIcon");
207 #ifdef XKB_BUTTON_HINT
208 ANoLanguageButton
= WMCreatePLString("NoLanguageButton");
211 AStartWorkspace
= WMCreatePLString("StartWorkspace");
213 AnyWindow
= WMCreatePLString("*");
214 EmptyString
= WMCreatePLString("");
215 Yes
= WMCreatePLString("Yes");
216 No
= WMCreatePLString("No");
219 static void freeInspector(InspectorPanel
* panel
)
221 panel
->destroyed
= 1;
222 if (panel
->choosingIcon
)
225 WMDestroyWidget(panel
->win
);
227 XDestroyWindow(dpy
, panel
->parent
);
232 static void destroyInspector(WCoreWindow
* foo
, void *data
, XEvent
* event
)
234 InspectorPanel
*panel
;
238 while (panel
->frame
!= data
)
239 panel
= panel
->nextPtr
;
241 if (panelList
== panel
)
242 panelList
= panel
->nextPtr
;
245 while (tmp
->nextPtr
!= panel
) {
248 tmp
->nextPtr
= panel
->nextPtr
;
250 panel
->inspected
->flags
.inspector_open
= 0;
251 panel
->inspected
->inspector
= NULL
;
253 WMRemoveNotificationObserver(panel
);
255 wWindowUnmap(panel
->frame
);
256 wUnmanageWindow(panel
->frame
, True
, False
);
258 freeInspector(panel
);
261 void wDestroyInspectorPanels()
263 InspectorPanel
*panel
;
265 while (panelList
!= NULL
) {
267 panelList
= panelList
->nextPtr
;
268 wUnmanageWindow(panel
->frame
, False
, False
);
269 WMDestroyWidget(panel
->win
);
271 panel
->inspected
->flags
.inspector_open
= 0;
272 panel
->inspected
->inspector
= NULL
;
278 static void changePage(WMPopUpButton
* bPtr
, InspectorPanel
* panel
)
282 page
= WMGetPopUpButtonSelectedItem(bPtr
);
285 WMMapWidget(panel
->specFrm
);
286 WMMapWidget(panel
->specLbl
);
287 } else if (page
== 1) {
288 WMMapWidget(panel
->attrFrm
);
289 } else if (page
== 2) {
290 WMMapWidget(panel
->moreFrm
);
291 } else if (page
== 3) {
292 WMMapWidget(panel
->iconFrm
);
293 WMMapWidget(panel
->wsFrm
);
295 WMMapWidget(panel
->appFrm
);
299 WMUnmapWidget(panel
->specFrm
);
300 WMUnmapWidget(panel
->specLbl
);
303 WMUnmapWidget(panel
->attrFrm
);
305 WMUnmapWidget(panel
->moreFrm
);
307 WMUnmapWidget(panel
->iconFrm
);
308 WMUnmapWidget(panel
->wsFrm
);
310 if (page
!= 4 && panel
->appFrm
)
311 WMUnmapWidget(panel
->appFrm
);
314 #define USE_TEXT_FIELD 1
315 #define UPDATE_TEXT_FIELD 2
316 #define REVERT_TO_DEFAULT 4
318 static int showIconFor(WMScreen
* scrPtr
, InspectorPanel
* panel
, char *wm_instance
, char *wm_class
, int flags
)
320 WMPixmap
*pixmap
= (WMPixmap
*) NULL
;
321 char *file
= NULL
, *path
= NULL
;
322 char *db_icon
= NULL
;
324 if ((flags
& USE_TEXT_FIELD
) != 0) {
325 file
= WMGetTextFieldText(panel
->fileText
);
326 if (file
&& file
[0] == 0) {
331 db_icon
= wDefaultGetIconFile(panel
->inspected
->screen_ptr
, wm_instance
, wm_class
, False
);
333 file
= wstrdup(db_icon
);
335 if (db_icon
!= NULL
&& (flags
& REVERT_TO_DEFAULT
) != 0) {
337 file
= wstrdup(db_icon
);
338 flags
|= UPDATE_TEXT_FIELD
;
341 if ((flags
& UPDATE_TEXT_FIELD
) != 0) {
342 WMSetTextFieldText(panel
->fileText
, file
);
346 path
= FindImage(wPreferences
.icon_path
, file
);
350 int len
= strlen(file
) + 80;
353 snprintf(buf
, len
, _("Could not find icon \"%s\" specified for this window"), file
);
354 wMessageDialog(panel
->frame
->screen_ptr
, _("Error"), buf
, _("OK"), NULL
, NULL
);
360 pixmap
= WMCreatePixmapFromFile(scrPtr
, path
);
365 int len
= strlen(file
) + 80;
368 snprintf(buf
, len
, _("Could not open specified icon \"%s\":%s"),
369 file
, RMessageForError(RErrorCode
));
370 wMessageDialog(panel
->frame
->screen_ptr
, _("Error"), buf
, _("OK"), NULL
, NULL
);
378 WMSetLabelImage(panel
->iconLbl
, pixmap
);
380 WMReleasePixmap(pixmap
);
386 static void updateIcon(WMButton
* button
, InspectorPanel
* panel
)
388 showIconFor(WMWidgetScreen(button
), panel
, NULL
, NULL
, USE_TEXT_FIELD
);
392 static int getBool(WMPropList
* value
)
396 if (!WMIsPLString(value
)) {
399 if (!(val
= WMGetFromPLString(value
))) {
403 if ((val
[1] == '\0' && (val
[0] == 'y' || val
[0] == 'Y' || val
[0] == 'T' || val
[0] == 't' || val
[0] == '1'))
404 || (strcasecmp(val
, "YES") == 0 || strcasecmp(val
, "TRUE") == 0)) {
407 } else if ((val
[1] == '\0'
408 && (val
[0] == 'n' || val
[0] == 'N' || val
[0] == 'F' || val
[0] == 'f' || val
[0] == '0'))
409 || (strcasecmp(val
, "NO") == 0 || strcasecmp(val
, "FALSE") == 0)) {
413 wwarning(_("can't convert \"%s\" to boolean"), val
);
418 #define UPDATE_DEFAULTS 1
422 * Will insert the attribute = value; pair in window's list,
423 * if it's different from the defaults.
424 * Defaults means either defaults database, or attributes saved
425 * for the default window "*". This is to let one revert options that are
426 * global because they were saved for all windows ("*").
431 insertAttribute(WMPropList
* dict
, WMPropList
* window
, WMPropList
* attr
, WMPropList
* value
, int flags
)
433 WMPropList
*def_win
, *def_value
= NULL
;
437 if (!(flags
& UPDATE_DEFAULTS
) && dict
) {
438 if ((def_win
= WMGetFromPLDictionary(dict
, AnyWindow
)) != NULL
) {
439 def_value
= WMGetFromPLDictionary(def_win
, attr
);
443 /* If we could not find defaults in database, fall to hardcoded values.
444 * Also this is true if we save defaults for all windows
447 def_value
= ((flags
& IS_BOOLEAN
) != 0) ? No
: EmptyString
;
449 if ((flags
& IS_BOOLEAN
))
450 update
= (getBool(value
) != getBool(def_value
));
452 update
= !WMIsPropListEqualTo(value
, def_value
);
456 WMPutInPLDictionary(window
, attr
, value
);
463 static void saveSettings(WMButton
* button
, InspectorPanel
* panel
)
465 WWindow
*wwin
= panel
->inspected
;
466 WDDomain
*db
= WDWindowAttributes
;
467 WMPropList
*dict
= db
->dictionary
;
468 WMPropList
*winDic
, *appDic
, *value
, *key
, *key2
;
471 int different
= 0, different2
= 0;
473 /* Save will apply the changes and save them */
474 applySettings(panel
->applyBtn
, panel
);
476 if (WMGetButtonSelected(panel
->instRb
) != 0)
477 key
= WMCreatePLString(wwin
->wm_instance
);
478 else if (WMGetButtonSelected(panel
->clsRb
) != 0)
479 key
= WMCreatePLString(wwin
->wm_class
);
480 else if (WMGetButtonSelected(panel
->bothRb
) != 0) {
483 buffer
= StrConcatDot(wwin
->wm_instance
, wwin
->wm_class
);
484 key
= WMCreatePLString(buffer
);
486 } else if (WMGetButtonSelected(panel
->defaultRb
) != 0) {
487 key
= WMRetainPropList(AnyWindow
);
488 flags
= UPDATE_DEFAULTS
;
496 dict
= WMCreatePLDictionary(NULL
, NULL
);
498 db
->dictionary
= dict
;
500 WMReleasePropList(key
);
505 if (showIconFor(WMWidgetScreen(button
), panel
, NULL
, NULL
, USE_TEXT_FIELD
) < 0)
508 WMPLSetCaseSensitive(True
);
510 winDic
= WMCreatePLDictionary(NULL
, NULL
);
511 appDic
= WMCreatePLDictionary(NULL
, NULL
);
513 /* Update icon for window */
514 icon_file
= WMGetTextFieldText(panel
->fileText
);
516 if (icon_file
[0] != 0) {
517 value
= WMCreatePLString(icon_file
);
518 different
|= insertAttribute(dict
, winDic
, AIcon
, value
, flags
);
519 different2
|= insertAttribute(dict
, appDic
, AIcon
, value
, flags
);
520 WMReleasePropList(value
);
526 int i
= WMGetPopUpButtonSelectedItem(panel
->wsP
);
530 if (i
>= 0 && i
< panel
->frame
->screen_ptr
->workspace_count
) {
531 value
= WMCreatePLString(panel
->frame
->screen_ptr
->workspaces
[i
]->name
);
532 different
|= insertAttribute(dict
, winDic
, AStartWorkspace
, value
, flags
);
533 WMReleasePropList(value
);
539 value
= (WMGetButtonSelected(panel
->alwChk
) != 0) ? Yes
: No
;
540 different
|= insertAttribute(dict
, winDic
, AAlwaysUserIcon
, value
, flags
);
542 value
= (WMGetButtonSelected(panel
->attrChk
[0]) != 0) ? Yes
: No
;
543 different
|= insertAttribute(dict
, winDic
, ANoTitlebar
, value
, flags
);
545 value
= (WMGetButtonSelected(panel
->attrChk
[1]) != 0) ? Yes
: No
;
546 different
|= insertAttribute(dict
, winDic
, ANoResizebar
, value
, flags
);
548 value
= (WMGetButtonSelected(panel
->attrChk
[2]) != 0) ? Yes
: No
;
549 different
|= insertAttribute(dict
, winDic
, ANoCloseButton
, value
, flags
);
551 value
= (WMGetButtonSelected(panel
->attrChk
[3]) != 0) ? Yes
: No
;
552 different
|= insertAttribute(dict
, winDic
, ANoMiniaturizeButton
, value
, flags
);
554 value
= (WMGetButtonSelected(panel
->attrChk
[4]) != 0) ? Yes
: No
;
555 different
|= insertAttribute(dict
, winDic
, ANoBorder
, value
, flags
);
557 value
= (WMGetButtonSelected(panel
->attrChk
[5]) != 0) ? Yes
: No
;
558 different
|= insertAttribute(dict
, winDic
, AKeepOnTop
, value
, flags
);
560 value
= (WMGetButtonSelected(panel
->attrChk
[6]) != 0) ? Yes
: No
;
561 different
|= insertAttribute(dict
, winDic
, AKeepOnBottom
, value
, flags
);
563 value
= (WMGetButtonSelected(panel
->attrChk
[7]) != 0) ? Yes
: No
;
564 different
|= insertAttribute(dict
, winDic
, AOmnipresent
, value
, flags
);
566 value
= (WMGetButtonSelected(panel
->attrChk
[8]) != 0) ? Yes
: No
;
567 different
|= insertAttribute(dict
, winDic
, AStartMiniaturized
, value
, flags
);
569 value
= (WMGetButtonSelected(panel
->attrChk
[9]) != 0) ? Yes
: No
;
570 different
|= insertAttribute(dict
, winDic
, AStartMaximized
, value
, flags
);
572 value
= (WMGetButtonSelected(panel
->attrChk
[10]) != 0) ? Yes
: No
;
573 different
|= insertAttribute(dict
, winDic
, AFullMaximize
, value
, flags
);
575 value
= (WMGetButtonSelected(panel
->moreChk
[0]) != 0) ? Yes
: No
;
576 different
|= insertAttribute(dict
, winDic
, ANoKeyBindings
, value
, flags
);
578 value
= (WMGetButtonSelected(panel
->moreChk
[1]) != 0) ? Yes
: No
;
579 different
|= insertAttribute(dict
, winDic
, ANoMouseBindings
, value
, flags
);
581 value
= (WMGetButtonSelected(panel
->moreChk
[2]) != 0) ? Yes
: No
;
582 different
|= insertAttribute(dict
, winDic
, ASkipWindowList
, value
, flags
);
584 value
= (WMGetButtonSelected(panel
->moreChk
[3]) != 0) ? Yes
: No
;
585 different
|= insertAttribute(dict
, winDic
, AUnfocusable
, value
, flags
);
587 value
= (WMGetButtonSelected(panel
->moreChk
[4]) != 0) ? Yes
: No
;
588 different
|= insertAttribute(dict
, winDic
, AKeepInsideScreen
, value
, flags
);
590 value
= (WMGetButtonSelected(panel
->moreChk
[5]) != 0) ? Yes
: No
;
591 different
|= insertAttribute(dict
, winDic
, ANoHideOthers
, value
, flags
);
593 value
= (WMGetButtonSelected(panel
->moreChk
[6]) != 0) ? Yes
: No
;
594 different
|= insertAttribute(dict
, winDic
, ADontSaveSession
, value
, flags
);
596 value
= (WMGetButtonSelected(panel
->moreChk
[7]) != 0) ? Yes
: No
;
597 different
|= insertAttribute(dict
, winDic
, AEmulateAppIcon
, value
, flags
);
599 value
= (WMGetButtonSelected(panel
->moreChk
[8]) != 0) ? Yes
: No
;
600 different
|= insertAttribute(dict
, winDic
, ADontFocusAcrossWorkspace
, value
, flags
);
602 #ifdef XKB_BUTTON_HINT
603 value
= (WMGetButtonSelected(panel
->moreChk
[9]) != 0) ? Yes
: No
;
604 different
|= insertAttribute(dict
, winDic
, ANoLanguageButton
, value
, flags
);
607 if (wwin
->main_window
!= None
&& wApplicationOf(wwin
->main_window
) != NULL
) {
608 value
= (WMGetButtonSelected(panel
->appChk
[0]) != 0) ? Yes
: No
;
609 different2
|= insertAttribute(dict
, appDic
, AStartHidden
, value
, flags
);
611 value
= (WMGetButtonSelected(panel
->appChk
[1]) != 0) ? Yes
: No
;
612 different2
|= insertAttribute(dict
, appDic
, ANoAppIcon
, value
, flags
);
614 value
= (WMGetButtonSelected(panel
->appChk
[2]) != 0) ? Yes
: No
;
615 different2
|= insertAttribute(dict
, appDic
, ASharedAppIcon
, value
, flags
);
618 if (wwin
->fake_group
) {
619 key2
= WMCreatePLString(wwin
->fake_group
->identifier
);
620 if (WMIsPropListEqualTo(key
, key2
)) {
621 WMMergePLDictionaries(winDic
, appDic
, True
);
622 different
|= different2
;
624 WMRemoveFromPLDictionary(dict
, key2
);
626 WMPutInPLDictionary(dict
, key2
, appDic
);
629 WMReleasePropList(key2
);
630 WMReleasePropList(appDic
);
631 } else if (wwin
->main_window
!= wwin
->client_win
) {
632 WApplication
*wapp
= wApplicationOf(wwin
->main_window
);
635 char *instance
= wapp
->main_window_desc
->wm_instance
;
636 char *class = wapp
->main_window_desc
->wm_class
;
639 buffer
= StrConcatDot(instance
, class);
640 key2
= WMCreatePLString(buffer
);
643 if (WMIsPropListEqualTo(key
, key2
)) {
644 WMMergePLDictionaries(winDic
, appDic
, True
);
645 different
|= different2
;
647 WMRemoveFromPLDictionary(dict
, key2
);
649 WMPutInPLDictionary(dict
, key2
, appDic
);
652 WMReleasePropList(key2
);
653 WMReleasePropList(appDic
);
656 WMMergePLDictionaries(winDic
, appDic
, True
);
657 different
|= different2
;
658 WMReleasePropList(appDic
);
661 WMRemoveFromPLDictionary(dict
, key
);
663 WMPutInPLDictionary(dict
, key
, winDic
);
666 WMReleasePropList(key
);
667 WMReleasePropList(winDic
);
669 UpdateDomainFile(db
);
672 WMPLSetCaseSensitive(False
);
675 static void makeAppIconFor(WApplication
* wapp
)
677 WScreen
*scr
= wapp
->main_window_desc
->screen_ptr
;
682 if (!WFLAGP(wapp
->main_window_desc
, no_appicon
))
683 wapp
->app_icon
= wAppIconCreate(wapp
->main_window_desc
);
685 wapp
->app_icon
= NULL
;
687 if (wapp
->app_icon
) {
688 WIcon
*icon
= wapp
->app_icon
->icon
;
689 WDock
*clip
= scr
->workspaces
[scr
->current_workspace
]->clip
;
692 wapp
->app_icon
->main_window
= wapp
->main_window
;
694 if (clip
&& clip
->attract_icons
&& wDockFindFreeSlot(clip
, &x
, &y
)) {
695 wapp
->app_icon
->attracted
= 1;
696 if (!wapp
->app_icon
->icon
->shadowed
) {
697 wapp
->app_icon
->icon
->shadowed
= 1;
698 wapp
->app_icon
->icon
->force_paint
= 1;
700 wDockAttachIcon(clip
, wapp
->app_icon
, x
, y
);
702 PlaceIcon(scr
, &x
, &y
, wGetHeadForWindow(wapp
->main_window_desc
));
703 wAppIconMove(wapp
->app_icon
, x
, y
);
705 if (!clip
|| !wapp
->app_icon
->attracted
|| !clip
->collapsed
)
706 XMapWindow(dpy
, icon
->core
->window
);
708 if (wPreferences
.auto_arrange_icons
&& !wapp
->app_icon
->attracted
)
709 wArrangeIcons(wapp
->main_window_desc
->screen_ptr
, True
);
713 static void removeAppIconFor(WApplication
* wapp
)
718 if (wapp
->app_icon
->docked
&& !wapp
->app_icon
->attracted
) {
719 wapp
->app_icon
->running
= 0;
720 /* since we keep it, we don't care if it was attracted or not */
721 wapp
->app_icon
->attracted
= 0;
722 wapp
->app_icon
->icon
->shadowed
= 0;
723 wapp
->app_icon
->main_window
= None
;
724 wapp
->app_icon
->pid
= 0;
725 wapp
->app_icon
->icon
->owner
= NULL
;
726 wapp
->app_icon
->icon
->icon_win
= None
;
727 wapp
->app_icon
->icon
->force_paint
= 1;
728 wAppIconPaint(wapp
->app_icon
);
729 } else if (wapp
->app_icon
->docked
) {
730 wapp
->app_icon
->running
= 0;
731 wDockDetach(wapp
->app_icon
->dock
, wapp
->app_icon
);
733 wAppIconDestroy(wapp
->app_icon
);
735 wapp
->app_icon
= NULL
;
736 if (wPreferences
.auto_arrange_icons
)
737 wArrangeIcons(wapp
->main_window_desc
->screen_ptr
, True
);
740 static void applySettings(WMButton
* button
, InspectorPanel
* panel
)
742 WWindow
*wwin
= panel
->inspected
;
743 WApplication
*wapp
= wApplicationOf(wwin
->main_window
);
744 int floating
, sunken
, skip_window_list
;
746 int old_no_bind_keys
;
747 int old_no_bind_mouse
;
749 old_omnipresent
= WFLAGP(wwin
, omnipresent
);
750 old_no_bind_keys
= WFLAGP(wwin
, no_bind_keys
);
751 old_no_bind_mouse
= WFLAGP(wwin
, no_bind_mouse
);
753 showIconFor(WMWidgetScreen(button
), panel
, NULL
, NULL
, USE_TEXT_FIELD
);
755 /* Attributes... --> Window Attributes */
756 WSETUFLAG(wwin
, no_titlebar
, WMGetButtonSelected(panel
->attrChk
[0]));
757 WSETUFLAG(wwin
, no_resizebar
, WMGetButtonSelected(panel
->attrChk
[1]));
758 WSETUFLAG(wwin
, no_close_button
, WMGetButtonSelected(panel
->attrChk
[2]));
759 WSETUFLAG(wwin
, no_miniaturize_button
, WMGetButtonSelected(panel
->attrChk
[3]));
760 WSETUFLAG(wwin
, no_border
, WMGetButtonSelected(panel
->attrChk
[4]));
761 floating
= WMGetButtonSelected(panel
->attrChk
[5]);
762 sunken
= WMGetButtonSelected(panel
->attrChk
[6]);
763 WSETUFLAG(wwin
, omnipresent
, WMGetButtonSelected(panel
->attrChk
[7]));
764 WSETUFLAG(wwin
, start_miniaturized
, WMGetButtonSelected(panel
->attrChk
[8]));
765 WSETUFLAG(wwin
, start_maximized
, WMGetButtonSelected(panel
->attrChk
[9]));
766 WSETUFLAG(wwin
, full_maximize
, WMGetButtonSelected(panel
->attrChk
[10]));
768 /* Attributes... --> Advanced Options */
769 WSETUFLAG(wwin
, no_bind_keys
, WMGetButtonSelected(panel
->moreChk
[0]));
770 WSETUFLAG(wwin
, no_bind_mouse
, WMGetButtonSelected(panel
->moreChk
[1]));
771 skip_window_list
= WMGetButtonSelected(panel
->moreChk
[2]);
772 WSETUFLAG(wwin
, no_focusable
, WMGetButtonSelected(panel
->moreChk
[3]));
773 WSETUFLAG(wwin
, dont_move_off
, WMGetButtonSelected(panel
->moreChk
[4]));
774 WSETUFLAG(wwin
, no_hide_others
, WMGetButtonSelected(panel
->moreChk
[5]));
775 WSETUFLAG(wwin
, dont_save_session
, WMGetButtonSelected(panel
->moreChk
[6]));
776 WSETUFLAG(wwin
, emulate_appicon
, WMGetButtonSelected(panel
->moreChk
[7]));
777 WSETUFLAG(wwin
, dont_focus_across_wksp
, WMGetButtonSelected(panel
->moreChk
[8]));
778 #ifdef XKB_BUTTON_HINT
779 WSETUFLAG(wwin
, no_language_button
, WMGetButtonSelected(panel
->moreChk
[9]));
781 WSETUFLAG(wwin
, always_user_icon
, WMGetButtonSelected(panel
->alwChk
));
783 if (WFLAGP(wwin
, no_titlebar
) && wwin
->flags
.shaded
)
784 wUnshadeWindow(wwin
);
786 WSETUFLAG(wwin
, no_shadeable
, WFLAGP(wwin
, no_titlebar
));
789 if (!WFLAGP(wwin
, floating
))
790 ChangeStackingLevel(wwin
->frame
->core
, WMFloatingLevel
);
792 if (!WFLAGP(wwin
, sunken
))
793 ChangeStackingLevel(wwin
->frame
->core
, WMSunkenLevel
);
795 if (WFLAGP(wwin
, floating
) || WFLAGP(wwin
, sunken
))
796 ChangeStackingLevel(wwin
->frame
->core
, WMNormalLevel
);
799 WSETUFLAG(wwin
, sunken
, sunken
);
800 WSETUFLAG(wwin
, floating
, floating
);
801 wwin
->flags
.omnipresent
= 0;
803 if (WFLAGP(wwin
, skip_window_list
) != skip_window_list
) {
804 WSETUFLAG(wwin
, skip_window_list
, skip_window_list
);
805 UpdateSwitchMenu(wwin
->screen_ptr
, wwin
, skip_window_list
? ACTION_REMOVE
: ACTION_ADD
);
807 if (WFLAGP(wwin
, omnipresent
) != old_omnipresent
) {
808 WMPostNotificationName(WMNChangedState
, wwin
, "omnipresent");
812 if (WFLAGP(wwin
, no_bind_keys
) != old_no_bind_keys
) {
813 if (WFLAGP(wwin
, no_bind_keys
)) {
814 XUngrabKey(dpy
, AnyKey
, AnyModifier
, wwin
->frame
->core
->window
);
816 wWindowSetKeyGrabs(wwin
);
820 if (WFLAGP(wwin
, no_bind_mouse
) != old_no_bind_mouse
) {
821 wWindowResetMouseGrabs(wwin
);
824 wwin
->frame
->flags
.need_texture_change
= 1;
825 wWindowConfigureBorders(wwin
);
826 wFrameWindowPaint(wwin
->frame
);
827 wNETWMUpdateActions(wwin
, False
);
830 * Can't apply emulate_appicon because it will probably cause problems.
833 /* do application wide stuff */
834 WSETUFLAG(wapp
->main_window_desc
, start_hidden
, WMGetButtonSelected(panel
->appChk
[0]));
836 WSETUFLAG(wapp
->main_window_desc
, no_appicon
, WMGetButtonSelected(panel
->appChk
[1]));
838 WSETUFLAG(wapp
->main_window_desc
, shared_appicon
, WMGetButtonSelected(panel
->appChk
[2]));
840 if (WFLAGP(wapp
->main_window_desc
, no_appicon
))
841 removeAppIconFor(wapp
);
843 makeAppIconFor(wapp
);
845 if (wapp
->app_icon
&& wapp
->main_window
== wwin
->client_win
) {
846 char *file
= WMGetTextFieldText(panel
->fileText
);
852 wIconChangeImageFile(wapp
->app_icon
->icon
, file
);
855 wAppIconPaint(wapp
->app_icon
);
860 static void revertSettings(WMButton
* button
, InspectorPanel
* panel
)
862 WWindow
*wwin
= panel
->inspected
;
863 WApplication
*wapp
= wApplicationOf(wwin
->main_window
);
865 char *wm_instance
= NULL
;
866 char *wm_class
= NULL
;
867 int workspace
, level
;
869 if (panel
->instRb
&& WMGetButtonSelected(panel
->instRb
) != 0)
870 wm_instance
= wwin
->wm_instance
;
871 else if (panel
->clsRb
&& WMGetButtonSelected(panel
->clsRb
) != 0)
872 wm_class
= wwin
->wm_class
;
873 else if (panel
->bothRb
&& WMGetButtonSelected(panel
->bothRb
) != 0) {
874 wm_instance
= wwin
->wm_instance
;
875 wm_class
= wwin
->wm_class
;
877 memset(&wwin
->defined_user_flags
, 0, sizeof(WWindowAttributes
));
878 memset(&wwin
->user_flags
, 0, sizeof(WWindowAttributes
));
879 memset(&wwin
->client_flags
, 0, sizeof(WWindowAttributes
));
881 wWindowSetupInitialAttributes(wwin
, &level
, &workspace
);
883 for (i
= 0; i
< 11; i
++) {
888 flag
= WFLAGP(wwin
, no_titlebar
);
891 flag
= WFLAGP(wwin
, no_resizebar
);
894 flag
= WFLAGP(wwin
, no_close_button
);
897 flag
= WFLAGP(wwin
, no_miniaturize_button
);
900 flag
= WFLAGP(wwin
, no_border
);
903 flag
= WFLAGP(wwin
, floating
);
906 flag
= WFLAGP(wwin
, sunken
);
909 flag
= WFLAGP(wwin
, omnipresent
);
912 flag
= WFLAGP(wwin
, start_miniaturized
);
915 flag
= WFLAGP(wwin
, start_maximized
!= 0);
918 flag
= WFLAGP(wwin
, full_maximize
);
921 WMSetButtonSelected(panel
->attrChk
[i
], flag
);
923 for (i
= 0; i
< 9; i
++) {
928 flag
= WFLAGP(wwin
, no_bind_keys
);
931 flag
= WFLAGP(wwin
, no_bind_mouse
);
934 flag
= WFLAGP(wwin
, skip_window_list
);
937 flag
= WFLAGP(wwin
, no_focusable
);
940 flag
= WFLAGP(wwin
, dont_move_off
);
943 flag
= WFLAGP(wwin
, no_hide_others
);
946 flag
= WFLAGP(wwin
, dont_save_session
);
949 flag
= WFLAGP(wwin
, emulate_appicon
);
952 flag
= WFLAGP(wwin
, dont_focus_across_wksp
);
954 #ifdef XKB_BUTTON_HINT
956 flag
= WFLAGP(wwin
, no_language_button
);
960 WMSetButtonSelected(panel
->moreChk
[i
], flag
);
962 if (panel
->appFrm
&& wapp
) {
963 for (i
= 0; i
< 2; i
++) {
968 flag
= WFLAGP(wapp
->main_window_desc
, start_hidden
);
971 flag
= WFLAGP(wapp
->main_window_desc
, no_appicon
);
974 flag
= WFLAGP(wapp
->main_window_desc
, shared_appicon
);
977 WMSetButtonSelected(panel
->appChk
[i
], flag
);
980 WMSetButtonSelected(panel
->alwChk
, WFLAGP(wwin
, always_user_icon
));
982 showIconFor(WMWidgetScreen(panel
->alwChk
), panel
, wm_instance
, wm_class
, REVERT_TO_DEFAULT
);
984 n
= wDefaultGetStartWorkspace(wwin
->screen_ptr
, wm_instance
, wm_class
);
986 if (n
>= 0 && n
< wwin
->screen_ptr
->workspace_count
) {
987 WMSetPopUpButtonSelectedItem(panel
->wsP
, n
+ 1);
989 WMSetPopUpButtonSelectedItem(panel
->wsP
, 0);
992 /* must auto apply, so that there wno't be internal
993 * inconsistencies between the state in the flags and
994 * the actual state of the window */
995 applySettings(panel
->applyBtn
, panel
);
998 static void chooseIconCallback(WMWidget
* self
, void *clientData
)
1001 InspectorPanel
*panel
= (InspectorPanel
*) clientData
;
1004 panel
->choosingIcon
= 1;
1006 WMSetButtonEnabled(panel
->browseIconBtn
, False
);
1008 result
= wIconChooserDialog(panel
->frame
->screen_ptr
, &file
,
1009 panel
->inspected
->wm_instance
, panel
->inspected
->wm_class
);
1011 panel
->choosingIcon
= 0;
1013 if (!panel
->destroyed
) { /* kluge */
1015 WMSetTextFieldText(panel
->fileText
, file
);
1016 showIconFor(WMWidgetScreen(self
), panel
, NULL
, NULL
, USE_TEXT_FIELD
);
1019 WMSetButtonEnabled(panel
->browseIconBtn
, True
);
1021 freeInspector(panel
);
1025 static void textEditedObserver(void *observerData
, WMNotification
* notification
)
1027 InspectorPanel
*panel
= (InspectorPanel
*) observerData
;
1029 if ((long)WMGetNotificationClientData(notification
) != WMReturnTextMovement
)
1032 showIconFor(WMWidgetScreen(panel
->win
), panel
, NULL
, NULL
, USE_TEXT_FIELD
);
1034 WMPerformButtonClick(panel->updateIconBtn);
1038 static void selectSpecification(WMWidget
* bPtr
, void *data
)
1040 InspectorPanel
*panel
= (InspectorPanel
*) data
;
1042 WWindow
*wwin
= panel
->inspected
;
1045 if (bPtr
== panel
->defaultRb
&& (wwin
->wm_instance
|| wwin
->wm_class
)) {
1046 WMSetButtonEnabled(panel
->applyBtn
, False
);
1048 WMSetButtonEnabled(panel
->applyBtn
, True
);
1051 len
= 16 + strlen(wwin
->wm_instance
? wwin
->wm_instance
: "?")
1052 + strlen(wwin
->wm_class
? wwin
->wm_class
: "?");
1056 snprintf(str
, len
, _("Inspecting %s.%s"),
1057 wwin
->wm_instance
? wwin
->wm_instance
: "?", wwin
->wm_class
? wwin
->wm_class
: "?");
1059 wFrameWindowChangeTitle(panel
->frame
->frame
, str
);
1064 static void selectWindow(WMWidget
* bPtr
, void *data
)
1066 InspectorPanel
*panel
= (InspectorPanel
*) data
;
1067 WWindow
*wwin
= panel
->inspected
;
1068 WScreen
*scr
= wwin
->screen_ptr
;
1072 if (XGrabPointer(dpy
, scr
->root_win
, True
,
1073 ButtonPressMask
, GrabModeAsync
, GrabModeAsync
, None
,
1074 wCursor
[WCUR_SELECT
], CurrentTime
) != GrabSuccess
) {
1075 wwarning("could not grab mouse pointer");
1079 WMSetLabelText(panel
->specLbl
, _("Click in the window you wish to inspect."));
1081 WMMaskEvent(dpy
, ButtonPressMask
, &event
);
1083 XUngrabPointer(dpy
, CurrentTime
);
1085 iwin
= wWindowFor(event
.xbutton
.subwindow
);
1087 if (iwin
&& !iwin
->flags
.internal_window
&& iwin
!= wwin
&& !iwin
->flags
.inspector_open
) {
1089 iwin
->flags
.inspector_open
= 1;
1090 iwin
->inspector
= createInspectorForWindow(iwin
,
1091 panel
->frame
->frame_x
, panel
->frame
->frame_y
, True
);
1092 wCloseInspectorForWindow(wwin
);
1094 WMSetLabelText(panel
->specLbl
, spec_text
);
1098 static InspectorPanel
*createInspectorForWindow(WWindow
* wwin
, int xpos
, int ypos
, Bool showSelectPanel
)
1100 WScreen
*scr
= wwin
->screen_ptr
;
1101 InspectorPanel
*panel
;
1105 int btn_width
, frame_width
;
1106 WMButton
*selectedBtn
= NULL
;
1107 #ifdef wrong_behaviour
1111 spec_text
= _("The configuration will apply to all\n"
1112 "windows that have their WM_CLASS\n"
1113 "property set to the above selected\n" "name, when saved.");
1115 panel
= wmalloc(sizeof(InspectorPanel
));
1116 memset(panel
, 0, sizeof(InspectorPanel
));
1118 panel
->destroyed
= 0;
1120 panel
->inspected
= wwin
;
1122 panel
->nextPtr
= panelList
;
1125 panel
->win
= WMCreateWindow(scr
->wmscreen
, "windowInspector");
1126 WMResizeWidget(panel
->win
, PWIDTH
, PHEIGHT
);
1128 /**** create common stuff ****/
1130 /* command buttons */
1131 /* (PWIDTH - (left and right margin) - (btn interval)) / 3 */
1132 btn_width
= (PWIDTH
- (2 * 15) - (2 * 10)) / 3;
1133 panel
->saveBtn
= WMCreateCommandButton(panel
->win
);
1134 WMSetButtonAction(panel
->saveBtn
, (WMAction
*) saveSettings
, panel
);
1135 WMMoveWidget(panel
->saveBtn
, (2 * (btn_width
+ 10)) + 15, 310);
1136 WMSetButtonText(panel
->saveBtn
, _("Save"));
1137 WMResizeWidget(panel
->saveBtn
, btn_width
, 28);
1138 if (wPreferences
.flags
.noupdates
|| !(wwin
->wm_class
|| wwin
->wm_instance
))
1139 WMSetButtonEnabled(panel
->saveBtn
, False
);
1141 panel
->applyBtn
= WMCreateCommandButton(panel
->win
);
1142 WMSetButtonAction(panel
->applyBtn
, (WMAction
*) applySettings
, panel
);
1143 WMMoveWidget(panel
->applyBtn
, btn_width
+ 10 + 15, 310);
1144 WMSetButtonText(panel
->applyBtn
, _("Apply"));
1145 WMResizeWidget(panel
->applyBtn
, btn_width
, 28);
1147 panel
->revertBtn
= WMCreateCommandButton(panel
->win
);
1148 WMSetButtonAction(panel
->revertBtn
, (WMAction
*) revertSettings
, panel
);
1149 WMMoveWidget(panel
->revertBtn
, 15, 310);
1150 WMSetButtonText(panel
->revertBtn
, _("Reload"));
1151 WMResizeWidget(panel
->revertBtn
, btn_width
, 28);
1153 /* page selection popup button */
1154 panel
->pagePopUp
= WMCreatePopUpButton(panel
->win
);
1155 WMSetPopUpButtonAction(panel
->pagePopUp
, (WMAction
*) changePage
, panel
);
1156 WMMoveWidget(panel
->pagePopUp
, 25, 15);
1157 WMResizeWidget(panel
->pagePopUp
, PWIDTH
- 50, 20);
1159 WMAddPopUpButtonItem(panel
->pagePopUp
, _("Window Specification"));
1160 WMAddPopUpButtonItem(panel
->pagePopUp
, _("Window Attributes"));
1161 WMAddPopUpButtonItem(panel
->pagePopUp
, _("Advanced Options"));
1162 WMAddPopUpButtonItem(panel
->pagePopUp
, _("Icon and Initial Workspace"));
1163 WMAddPopUpButtonItem(panel
->pagePopUp
, _("Application Specific"));
1165 /**** window spec ****/
1166 frame_width
= PWIDTH
- (2 * 15);
1168 panel
->specFrm
= WMCreateFrame(panel
->win
);
1169 WMSetFrameTitle(panel
->specFrm
, _("Window Specification"));
1170 WMMoveWidget(panel
->specFrm
, 15, 65);
1171 WMResizeWidget(panel
->specFrm
, frame_width
, 145);
1173 panel
->defaultRb
= WMCreateRadioButton(panel
->specFrm
);
1174 WMMoveWidget(panel
->defaultRb
, 10, 78);
1175 WMResizeWidget(panel
->defaultRb
, frame_width
- (2 * 10), 20);
1176 WMSetButtonText(panel
->defaultRb
, _("Defaults for all windows"));
1177 WMSetButtonSelected(panel
->defaultRb
, False
);
1178 WMSetButtonAction(panel
->defaultRb
, selectSpecification
, panel
);
1180 if (wwin
->wm_class
&& wwin
->wm_instance
) {
1183 tmp
= wstrconcat(wwin
->wm_instance
, ".");
1184 str
= wstrconcat(tmp
, wwin
->wm_class
);
1186 panel
->bothRb
= WMCreateRadioButton(panel
->specFrm
);
1187 WMMoveWidget(panel
->bothRb
, 10, 18);
1188 WMResizeWidget(panel
->bothRb
, frame_width
- (2 * 10), 20);
1189 WMSetButtonText(panel
->bothRb
, str
);
1192 WMGroupButtons(panel
->defaultRb
, panel
->bothRb
);
1195 selectedBtn
= panel
->bothRb
;
1197 WMSetButtonAction(panel
->bothRb
, selectSpecification
, panel
);
1200 if (wwin
->wm_instance
) {
1201 panel
->instRb
= WMCreateRadioButton(panel
->specFrm
);
1202 WMMoveWidget(panel
->instRb
, 10, 38);
1203 WMResizeWidget(panel
->instRb
, frame_width
- (2 * 10), 20);
1204 WMSetButtonText(panel
->instRb
, wwin
->wm_instance
);
1205 WMGroupButtons(panel
->defaultRb
, panel
->instRb
);
1208 selectedBtn
= panel
->instRb
;
1210 WMSetButtonAction(panel
->instRb
, selectSpecification
, panel
);
1213 if (wwin
->wm_class
) {
1214 panel
->clsRb
= WMCreateRadioButton(panel
->specFrm
);
1215 WMMoveWidget(panel
->clsRb
, 10, 58);
1216 WMResizeWidget(panel
->clsRb
, frame_width
- (2 * 10), 20);
1217 WMSetButtonText(panel
->clsRb
, wwin
->wm_class
);
1218 WMGroupButtons(panel
->defaultRb
, panel
->clsRb
);
1221 selectedBtn
= panel
->clsRb
;
1223 WMSetButtonAction(panel
->clsRb
, selectSpecification
, panel
);
1226 panel
->selWinB
= WMCreateCommandButton(panel
->specFrm
);
1227 WMMoveWidget(panel
->selWinB
, 20, 145 - 24 - 10);
1228 WMResizeWidget(panel
->selWinB
, frame_width
- 2 * 10 - 20, 24);
1229 WMSetButtonText(panel
->selWinB
, _("Select window"));
1230 WMSetButtonAction(panel
->selWinB
, selectWindow
, panel
);
1232 panel
->specLbl
= WMCreateLabel(panel
->win
);
1233 WMMoveWidget(panel
->specLbl
, 15, 210);
1234 WMResizeWidget(panel
->specLbl
, frame_width
, 100);
1235 WMSetLabelText(panel
->specLbl
, spec_text
);
1236 WMSetLabelWraps(panel
->specLbl
, True
);
1238 WMSetLabelTextAlignment(panel
->specLbl
, WALeft
);
1240 /**** attributes ****/
1241 panel
->attrFrm
= WMCreateFrame(panel
->win
);
1242 WMSetFrameTitle(panel
->attrFrm
, _("Attributes"));
1243 WMMoveWidget(panel
->attrFrm
, 15, 45);
1244 WMResizeWidget(panel
->attrFrm
, frame_width
, 250);
1246 for (i
= 0; i
< 11; i
++) {
1247 char *caption
= NULL
;
1253 caption
= _("Disable titlebar");
1254 flag
= WFLAGP(wwin
, no_titlebar
);
1255 descr
= _("Remove the titlebar of this window.\n"
1256 "To access the window commands menu of a window\n"
1257 "without it's titlebar, press Control+Esc (or the\n"
1258 "equivalent shortcut, if you changed the default\n" "settings).");
1261 caption
= _("Disable resizebar");
1262 flag
= WFLAGP(wwin
, no_resizebar
);
1263 descr
= _("Remove the resizebar of this window.");
1266 caption
= _("Disable close button");
1267 flag
= WFLAGP(wwin
, no_close_button
);
1268 descr
= _("Remove the `close window' button of this window.");
1271 caption
= _("Disable miniaturize button");
1272 flag
= WFLAGP(wwin
, no_miniaturize_button
);
1273 descr
= _("Remove the `miniaturize window' button of the window.");
1276 caption
= _("Disable border");
1277 flag
= WFLAGP(wwin
, no_border
);
1278 descr
= _("Remove the 1 pixel black border around the window.");
1281 caption
= _("Keep on top (floating)");
1282 flag
= WFLAGP(wwin
, floating
);
1283 descr
= _("Keep the window over other windows, not allowing\n" "them to cover it.");
1286 caption
= _("Keep at bottom (sunken)");
1287 flag
= WFLAGP(wwin
, sunken
);
1288 descr
= _("Keep the window under all other windows.");
1291 caption
= _("Omnipresent");
1292 flag
= WFLAGP(wwin
, omnipresent
);
1293 descr
= _("Make window present in all workspaces.");
1296 caption
= _("Start miniaturized");
1297 flag
= WFLAGP(wwin
, start_miniaturized
);
1298 descr
= _("Make the window be automatically miniaturized when it's\n" "first shown.");
1301 caption
= _("Start maximized");
1302 flag
= WFLAGP(wwin
, start_maximized
!= 0);
1303 descr
= _("Make the window be automatically maximized when it's\n" "first shown.");
1306 caption
= _("Full screen maximization");
1307 flag
= WFLAGP(wwin
, full_maximize
);
1308 descr
= _("Make the window use the whole screen space when it's\n"
1309 "maximized. The titlebar and resizebar will be moved\n"
1310 "to outside the screen.");
1313 panel
->attrChk
[i
] = WMCreateSwitchButton(panel
->attrFrm
);
1314 WMMoveWidget(panel
->attrChk
[i
], 10, 20 * (i
+ 1));
1315 WMResizeWidget(panel
->attrChk
[i
], frame_width
- 15, 20);
1316 WMSetButtonSelected(panel
->attrChk
[i
], flag
);
1317 WMSetButtonText(panel
->attrChk
[i
], caption
);
1319 WMSetBalloonTextForView(descr
, WMWidgetView(panel
->attrChk
[i
]));
1322 /**** more attributes ****/
1323 panel
->moreFrm
= WMCreateFrame(panel
->win
);
1324 WMSetFrameTitle(panel
->moreFrm
, _("Advanced"));
1325 WMMoveWidget(panel
->moreFrm
, 15, 45);
1326 WMResizeWidget(panel
->moreFrm
, frame_width
, 250);
1329 #ifdef XKB_BUTTON_HINT
1335 char *caption
= NULL
;
1341 caption
= _("Do not bind keyboard shortcuts");
1342 flag
= WFLAGP(wwin
, no_bind_keys
);
1343 descr
= _("Do not bind keyboard shortcuts from Window Maker\n"
1344 "when this window is focused. This will allow the\n"
1345 "window to receive all key combinations regardless\n"
1346 "of your shortcut configuration.");
1349 caption
= _("Do not bind mouse clicks");
1350 flag
= WFLAGP(wwin
, no_bind_mouse
);
1351 descr
= _("Do not bind mouse actions, such as `Alt'+drag\n"
1352 "in the window (when alt is the modifier you have\n" "configured).");
1355 caption
= _("Do not show in the window list");
1356 flag
= WFLAGP(wwin
, skip_window_list
);
1357 descr
= _("Do not list the window in the window list menu.");
1360 caption
= _("Do not let it take focus");
1361 flag
= WFLAGP(wwin
, no_focusable
);
1362 descr
= _("Do not let the window take keyboard focus when you\n" "click on it.");
1365 caption
= _("Keep inside screen");
1366 flag
= WFLAGP(wwin
, dont_move_off
);
1367 descr
= _("Do not allow the window to move itself completely\n"
1368 "outside the screen. For bug compatibility.\n");
1371 caption
= _("Ignore 'Hide Others'");
1372 flag
= WFLAGP(wwin
, no_hide_others
);
1373 descr
= _("Do not hide the window when issuing the\n" "`HideOthers' command.");
1376 caption
= _("Ignore 'Save Session'");
1377 flag
= WFLAGP(wwin
, dont_save_session
);
1378 descr
= _("Do not save the associated application in the\n"
1379 "session's state, so that it won't be restarted\n"
1380 "together with other applications when Window Maker\n" "starts.");
1383 caption
= _("Emulate application icon");
1384 flag
= WFLAGP(wwin
, emulate_appicon
);
1385 descr
= _("Make this window act as an application that provides\n"
1386 "enough information to Window Maker for a dockable\n"
1387 "application icon to be created.");
1390 caption
= _("Don't focus across workspaces");
1391 flag
= WFLAGP(wwin
, dont_focus_across_wksp
);
1392 descr
= _("Do not allow Window Maker to switch workspace to satisfy\n"
1393 "a focus request (useful e.g. in the case of a multiple-tab\n"
1394 "firefox opening in a different workspace).");
1396 #ifdef XKB_BUTTON_HINT
1398 caption
= _("Disable language button");
1399 flag
= WFLAGP(wwin
, no_language_button
);
1400 descr
= _("Remove the `toggle language' button of the window.");
1404 panel
->moreChk
[i
] = WMCreateSwitchButton(panel
->moreFrm
);
1405 WMMoveWidget(panel
->moreChk
[i
], 10, 20 * (i
+ 1));
1406 WMResizeWidget(panel
->moreChk
[i
], frame_width
- 15, 20);
1407 WMSetButtonSelected(panel
->moreChk
[i
], flag
);
1408 WMSetButtonText(panel
->moreChk
[i
], caption
);
1410 WMSetBalloonTextForView(descr
, WMWidgetView(panel
->moreChk
[i
]));
1413 /* miniwindow/workspace */
1414 panel
->iconFrm
= WMCreateFrame(panel
->win
);
1415 WMMoveWidget(panel
->iconFrm
, 15, 50);
1416 WMResizeWidget(panel
->iconFrm
, PWIDTH
- (2 * 15), 170);
1417 WMSetFrameTitle(panel
->iconFrm
, _("Miniwindow Image"));
1419 panel
->iconLbl
= WMCreateLabel(panel
->iconFrm
);
1420 WMMoveWidget(panel
->iconLbl
, PWIDTH
- (2 * 15) - 22 - 64, 20);
1421 WMResizeWidget(panel
->iconLbl
, 64, 64);
1422 WMSetLabelRelief(panel
->iconLbl
, WRGroove
);
1423 WMSetLabelImagePosition(panel
->iconLbl
, WIPImageOnly
);
1425 panel
->browseIconBtn
= WMCreateCommandButton(panel
->iconFrm
);
1426 WMSetButtonAction(panel
->browseIconBtn
, chooseIconCallback
, panel
);
1427 WMMoveWidget(panel
->browseIconBtn
, 22, 32);
1428 WMResizeWidget(panel
->browseIconBtn
, 120, 26);
1429 WMSetButtonText(panel
->browseIconBtn
, _("Browse..."));
1431 #ifdef wrong_behaviour
1432 WMSetButtonImagePosition(panel
->updateIconBtn
, WIPRight
);
1433 pixmap
= WMGetSystemPixmap(scr
->wmscreen
, WSIReturnArrow
);
1434 WMSetButtonImage(panel
->updateIconBtn
, pixmap
);
1435 WMReleasePixmap(pixmap
);
1436 pixmap
= WMGetSystemPixmap(scr
->wmscreen
, WSIHighlightedReturnArrow
);
1437 WMSetButtonAltImage(panel
->updateIconBtn
, pixmap
);
1438 WMReleasePixmap(pixmap
);
1441 panel
->fileLbl
= WMCreateLabel(panel
->iconFrm
);
1442 WMMoveWidget(panel
->fileLbl
, 20, 85);
1443 WMResizeWidget(panel
->fileLbl
, PWIDTH
- (2 * 15) - (2 * 20), 14);
1444 WMSetLabelText(panel
->fileLbl
, _("Icon filename:"));
1446 panel
->fileText
= WMCreateTextField(panel
->iconFrm
);
1447 WMMoveWidget(panel
->fileText
, 20, 105);
1448 WMResizeWidget(panel
->fileText
, PWIDTH
- (2 * 20) - (2 * 15), 20);
1449 WMSetTextFieldText(panel
->fileText
, NULL
);
1450 WMAddNotificationObserver(textEditedObserver
, panel
, WMTextDidEndEditingNotification
, panel
->fileText
);
1452 panel
->alwChk
= WMCreateSwitchButton(panel
->iconFrm
);
1453 WMMoveWidget(panel
->alwChk
, 20, 130);
1454 WMResizeWidget(panel
->alwChk
, PWIDTH
- (2 * 15) - (2 * 15), 30);
1455 WMSetButtonText(panel
->alwChk
, _("Ignore client supplied icon"));
1456 WMSetButtonSelected(panel
->alwChk
, WFLAGP(wwin
, always_user_icon
));
1458 panel
->wsFrm
= WMCreateFrame(panel
->win
);
1459 WMMoveWidget(panel
->wsFrm
, 15, 225);
1460 WMResizeWidget(panel
->wsFrm
, PWIDTH
- (2 * 15), 70);
1461 WMSetFrameTitle(panel
->wsFrm
, _("Initial Workspace"));
1463 WMSetBalloonTextForView(_("The workspace to place the window when it's"
1464 "first shown."), WMWidgetView(panel
->wsFrm
));
1466 panel
->wsP
= WMCreatePopUpButton(panel
->wsFrm
);
1467 WMMoveWidget(panel
->wsP
, 20, 30);
1468 WMResizeWidget(panel
->wsP
, PWIDTH
- (2 * 15) - (2 * 20), 20);
1469 WMAddPopUpButtonItem(panel
->wsP
, _("Nowhere in particular"));
1470 for (i
= 0; i
< wwin
->screen_ptr
->workspace_count
; i
++) {
1471 WMAddPopUpButtonItem(panel
->wsP
, scr
->workspaces
[i
]->name
);
1474 i
= wDefaultGetStartWorkspace(wwin
->screen_ptr
, wwin
->wm_instance
, wwin
->wm_class
);
1475 if (i
>= 0 && i
<= wwin
->screen_ptr
->workspace_count
) {
1476 WMSetPopUpButtonSelectedItem(panel
->wsP
, i
+ 1);
1478 WMSetPopUpButtonSelectedItem(panel
->wsP
, 0);
1481 /* application wide attributes */
1482 if (wwin
->main_window
!= None
) {
1483 WApplication
*wapp
= wApplicationOf(wwin
->main_window
);
1485 panel
->appFrm
= WMCreateFrame(panel
->win
);
1486 WMSetFrameTitle(panel
->appFrm
, _("Application Attributes"));
1487 WMMoveWidget(panel
->appFrm
, 15, 50);
1488 WMResizeWidget(panel
->appFrm
, frame_width
, 240);
1490 for (i
= 0; i
< 3; i
++) {
1491 char *caption
= NULL
;
1497 caption
= _("Start hidden");
1498 flag
= WFLAGP(wapp
->main_window_desc
, start_hidden
);
1499 descr
= _("Automatically hide application when it's started.");
1502 caption
= _("No application icon");
1503 flag
= WFLAGP(wapp
->main_window_desc
, no_appicon
);
1504 descr
= _("Disable the application icon for the application.\n"
1505 "Note that you won't be able to dock it anymore,\n"
1506 "and any icons that are already docked will stop\n"
1507 "working correctly.");
1510 caption
= _("Shared application icon");
1511 flag
= WFLAGP(wapp
->main_window_desc
, shared_appicon
);
1512 descr
= _("Use a single shared application icon for all of\n"
1513 "the instances of this application.\n");
1516 panel
->appChk
[i
] = WMCreateSwitchButton(panel
->appFrm
);
1517 WMMoveWidget(panel
->appChk
[i
], 10, 20 * (i
+ 1));
1518 WMResizeWidget(panel
->appChk
[i
], 205, 20);
1519 WMSetButtonSelected(panel
->appChk
[i
], flag
);
1520 WMSetButtonText(panel
->appChk
[i
], caption
);
1522 WMSetBalloonTextForView(descr
, WMWidgetView(panel
->appChk
[i
]));
1525 if (WFLAGP(wwin
, emulate_appicon
)) {
1526 WMSetButtonEnabled(panel
->appChk
[1], False
);
1527 WMSetButtonEnabled(panel
->moreChk
[7], True
);
1529 WMSetButtonEnabled(panel
->appChk
[1], True
);
1530 WMSetButtonEnabled(panel
->moreChk
[7], False
);
1535 if ((wwin
->transient_for
!= None
&& wwin
->transient_for
!= scr
->root_win
)
1536 || !wwin
->wm_class
|| !wwin
->wm_instance
)
1540 WMSetButtonEnabled(panel
->moreChk
[7], tmp
);
1542 WMSetPopUpButtonItemEnabled(panel
->pagePopUp
, 4, False
);
1543 panel
->appFrm
= NULL
;
1546 /* if the window is a transient, don't let it have a miniaturize
1548 if (wwin
->transient_for
!= None
&& wwin
->transient_for
!= scr
->root_win
)
1549 WMSetButtonEnabled(panel
->attrChk
[3], False
);
1551 WMSetButtonEnabled(panel
->attrChk
[3], True
);
1553 if (!wwin
->wm_class
&& !wwin
->wm_instance
) {
1554 WMSetPopUpButtonItemEnabled(panel
->pagePopUp
, 0, False
);
1557 WMRealizeWidget(panel
->win
);
1559 WMMapSubwidgets(panel
->win
);
1560 WMMapSubwidgets(panel
->specFrm
);
1561 WMMapSubwidgets(panel
->attrFrm
);
1562 WMMapSubwidgets(panel
->moreFrm
);
1563 WMMapSubwidgets(panel
->iconFrm
);
1564 WMMapSubwidgets(panel
->wsFrm
);
1566 WMMapSubwidgets(panel
->appFrm
);
1568 if (showSelectPanel
) {
1569 WMSetPopUpButtonSelectedItem(panel
->pagePopUp
, 0);
1570 changePage(panel
->pagePopUp
, panel
);
1572 WMSetPopUpButtonSelectedItem(panel
->pagePopUp
, 1);
1573 changePage(panel
->pagePopUp
, panel
);
1576 parent
= XCreateSimpleWindow(dpy
, scr
->root_win
, 0, 0, PWIDTH
, PHEIGHT
, 0, 0, 0);
1577 XSelectInput(dpy
, parent
, KeyPressMask
| KeyReleaseMask
);
1578 panel
->parent
= parent
;
1579 XReparentWindow(dpy
, WMWidgetXID(panel
->win
), parent
, 0, 0);
1581 WMMapWidget(panel
->win
);
1583 XSetTransientForHint(dpy
, parent
, wwin
->client_win
);
1585 if (xpos
== UNDEFINED_POS
) {
1586 x
= wwin
->frame_x
+ wwin
->frame
->core
->width
/ 2;
1587 y
= wwin
->frame_y
+ wwin
->frame
->top_width
* 2;
1588 if (y
+ PHEIGHT
> scr
->scr_height
)
1589 y
= scr
->scr_height
- PHEIGHT
- 30;
1590 if (x
+ PWIDTH
> scr
->scr_width
)
1591 x
= scr
->scr_width
- PWIDTH
;
1597 panel
->frame
= wManageInternalWindow(scr
, parent
, wwin
->client_win
, "Inspector", x
, y
, PWIDTH
, PHEIGHT
);
1600 selectedBtn
= panel
->defaultRb
;
1602 WMSetButtonSelected(selectedBtn
, True
);
1604 selectSpecification(selectedBtn
, panel
);
1606 /* kluge to know who should get the key events */
1607 panel
->frame
->client_leader
= WMWidgetXID(panel
->win
);
1609 WSETUFLAG(panel
->frame
, no_closable
, 0);
1610 WSETUFLAG(panel
->frame
, no_close_button
, 0);
1611 wWindowUpdateButtonImages(panel
->frame
);
1612 wFrameWindowShowButton(panel
->frame
->frame
, WFF_RIGHT_BUTTON
);
1613 panel
->frame
->frame
->on_click_right
= destroyInspector
;
1615 wWindowMap(panel
->frame
);
1617 showIconFor(WMWidgetScreen(panel
->alwChk
), panel
, wwin
->wm_instance
, wwin
->wm_class
, UPDATE_TEXT_FIELD
);
1622 void wShowInspectorForWindow(WWindow
* wwin
)
1624 if (wwin
->flags
.inspector_open
)
1627 WMSetBalloonEnabled(wwin
->screen_ptr
->wmscreen
, wPreferences
.help_balloon
);
1630 wwin
->flags
.inspector_open
= 1;
1631 wwin
->inspector
= createInspectorForWindow(wwin
, UNDEFINED_POS
, UNDEFINED_POS
, False
);
1634 void wHideInspectorForWindow(WWindow
* wwin
)
1636 WWindow
*pwin
= wwin
->inspector
->frame
;
1639 pwin
->flags
.hidden
= 1;
1641 wClientSetState(pwin
, IconicState
, None
);
1644 void wUnhideInspectorForWindow(WWindow
* wwin
)
1646 WWindow
*pwin
= wwin
->inspector
->frame
;
1648 pwin
->flags
.hidden
= 0;
1649 pwin
->flags
.mapped
= 1;
1650 XMapWindow(dpy
, pwin
->client_win
);
1651 XMapWindow(dpy
, pwin
->frame
->core
->window
);
1652 wClientSetState(pwin
, NormalState
, None
);
1655 WWindow
*wGetWindowOfInspectorForWindow(WWindow
* wwin
)
1657 if (wwin
->inspector
) {
1658 assert(wwin
->flags
.inspector_open
!= 0);
1660 return wwin
->inspector
->frame
;
1665 void wCloseInspectorForWindow(WWindow
* wwin
)
1667 WWindow
*pwin
= wwin
->inspector
->frame
; /* the inspector window */
1669 (*pwin
->frame
->on_click_right
) (NULL
, pwin
, NULL
);