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"
56 #include <WINGs/WUtil.h>
58 typedef struct InspectorPanel
{
59 struct InspectorPanel
*nextPtr
;
63 WWindow
*inspected
; /* the window that's being inspected */
74 WMPopUpButton
*pagePopUp
;
76 /* first page. general stuff */
88 /* second page. attributes */
91 WMButton
*attrChk
[11];
93 /* 3rd page. more attributes */
95 #ifdef XKB_BUTTON_HINT
96 WMButton
*moreChk
[10];
101 /* 4th page. icon and workspace */
105 WMTextField
*fileText
;
108 WMButton *updateIconBtn;
110 WMButton
*browseIconBtn
;
115 /* 5th page. application wide attributes */
120 unsigned int destroyed
:1;
121 unsigned int choosingIcon
:1;
124 extern Cursor wCursor
[WCUR_LAST
];
126 extern WDDomain
*WDWindowAttributes
;
128 static InspectorPanel
*panelList
= NULL
;
130 extern WPreferences wPreferences
;
132 static WMPropList
*ANoTitlebar
= NULL
;
133 static WMPropList
*ANoResizebar
;
134 static WMPropList
*ANoMiniaturizeButton
;
135 static WMPropList
*ANoCloseButton
;
136 static WMPropList
*ANoBorder
;
137 static WMPropList
*ANoHideOthers
;
138 static WMPropList
*ANoMouseBindings
;
139 static WMPropList
*ANoKeyBindings
;
140 static WMPropList
*ANoAppIcon
;
141 static WMPropList
*AKeepOnTop
;
142 static WMPropList
*AKeepOnBottom
;
143 static WMPropList
*AOmnipresent
;
144 static WMPropList
*ASkipWindowList
;
145 static WMPropList
*AKeepInsideScreen
;
146 static WMPropList
*AUnfocusable
;
147 static WMPropList
*ADontFocusAcrossWorkspace
;
148 static WMPropList
*AAlwaysUserIcon
;
149 static WMPropList
*AStartMiniaturized
;
150 static WMPropList
*AStartMaximized
;
151 static WMPropList
*ADontSaveSession
;
152 static WMPropList
*AEmulateAppIcon
;
153 static WMPropList
*AFullMaximize
;
154 static WMPropList
*ASharedAppIcon
;
155 #ifdef XKB_BUTTON_HINT
156 static WMPropList
*ANoLanguageButton
;
159 static WMPropList
*AStartWorkspace
;
161 static WMPropList
*AIcon
;
163 /* application wide options */
164 static WMPropList
*AStartHidden
;
166 static WMPropList
*AnyWindow
;
167 static WMPropList
*EmptyString
;
168 static WMPropList
*Yes
, *No
;
173 static char *spec_text
;
175 static void applySettings(WMButton
* button
, InspectorPanel
* panel
);
177 #define UNDEFINED_POS 0xffffff
179 static InspectorPanel
*createInspectorForWindow(WWindow
* wwin
, int xpos
, int ypos
, Bool showSelectPanel
);
181 static void make_keys()
183 if (ANoTitlebar
!= NULL
)
186 AIcon
= WMCreatePLString("Icon");
187 ANoTitlebar
= WMCreatePLString("NoTitlebar");
188 ANoResizebar
= WMCreatePLString("NoResizebar");
189 ANoMiniaturizeButton
= WMCreatePLString("NoMiniaturizeButton");
190 ANoCloseButton
= WMCreatePLString("NoCloseButton");
191 ANoBorder
= WMCreatePLString("NoBorder");
192 ANoHideOthers
= WMCreatePLString("NoHideOthers");
193 ANoMouseBindings
= WMCreatePLString("NoMouseBindings");
194 ANoKeyBindings
= WMCreatePLString("NoKeyBindings");
195 ANoAppIcon
= WMCreatePLString("NoAppIcon");
196 AKeepOnTop
= WMCreatePLString("KeepOnTop");
197 AKeepOnBottom
= WMCreatePLString("KeepOnBottom");
198 AOmnipresent
= WMCreatePLString("Omnipresent");
199 ASkipWindowList
= WMCreatePLString("SkipWindowList");
200 AKeepInsideScreen
= WMCreatePLString("KeepInsideScreen");
201 AUnfocusable
= WMCreatePLString("Unfocusable");
202 ADontFocusAcrossWorkspace
= WMCreatePLString("DontFocusAcrossWorkspace");
203 AAlwaysUserIcon
= WMCreatePLString("AlwaysUserIcon");
204 AStartMiniaturized
= WMCreatePLString("StartMiniaturized");
205 AStartMaximized
= WMCreatePLString("StartMaximized");
206 AStartHidden
= WMCreatePLString("StartHidden");
207 ADontSaveSession
= WMCreatePLString("DontSaveSession");
208 AEmulateAppIcon
= WMCreatePLString("EmulateAppIcon");
209 AFullMaximize
= WMCreatePLString("FullMaximize");
210 ASharedAppIcon
= WMCreatePLString("SharedAppIcon");
211 #ifdef XKB_BUTTON_HINT
212 ANoLanguageButton
= WMCreatePLString("NoLanguageButton");
215 AStartWorkspace
= WMCreatePLString("StartWorkspace");
217 AnyWindow
= WMCreatePLString("*");
218 EmptyString
= WMCreatePLString("");
219 Yes
= WMCreatePLString("Yes");
220 No
= WMCreatePLString("No");
223 static void freeInspector(InspectorPanel
* panel
)
225 panel
->destroyed
= 1;
226 if (panel
->choosingIcon
)
229 WMDestroyWidget(panel
->win
);
231 XDestroyWindow(dpy
, panel
->parent
);
236 static void destroyInspector(WCoreWindow
* foo
, void *data
, XEvent
* event
)
238 InspectorPanel
*panel
;
242 while (panel
->frame
!= data
)
243 panel
= panel
->nextPtr
;
245 if (panelList
== panel
)
246 panelList
= panel
->nextPtr
;
249 while (tmp
->nextPtr
!= panel
) {
252 tmp
->nextPtr
= panel
->nextPtr
;
254 panel
->inspected
->flags
.inspector_open
= 0;
255 panel
->inspected
->inspector
= NULL
;
257 WMRemoveNotificationObserver(panel
);
259 wWindowUnmap(panel
->frame
);
260 wUnmanageWindow(panel
->frame
, True
, False
);
262 freeInspector(panel
);
265 void wDestroyInspectorPanels()
267 InspectorPanel
*panel
;
269 while (panelList
!= NULL
) {
271 panelList
= panelList
->nextPtr
;
272 wUnmanageWindow(panel
->frame
, False
, False
);
273 WMDestroyWidget(panel
->win
);
275 panel
->inspected
->flags
.inspector_open
= 0;
276 panel
->inspected
->inspector
= NULL
;
282 static void changePage(WMPopUpButton
* bPtr
, InspectorPanel
* panel
)
286 page
= WMGetPopUpButtonSelectedItem(bPtr
);
289 WMMapWidget(panel
->specFrm
);
290 WMMapWidget(panel
->specLbl
);
291 } else if (page
== 1) {
292 WMMapWidget(panel
->attrFrm
);
293 } else if (page
== 2) {
294 WMMapWidget(panel
->moreFrm
);
295 } else if (page
== 3) {
296 WMMapWidget(panel
->iconFrm
);
297 WMMapWidget(panel
->wsFrm
);
299 WMMapWidget(panel
->appFrm
);
303 WMUnmapWidget(panel
->specFrm
);
304 WMUnmapWidget(panel
->specLbl
);
307 WMUnmapWidget(panel
->attrFrm
);
309 WMUnmapWidget(panel
->moreFrm
);
311 WMUnmapWidget(panel
->iconFrm
);
312 WMUnmapWidget(panel
->wsFrm
);
314 if (page
!= 4 && panel
->appFrm
)
315 WMUnmapWidget(panel
->appFrm
);
318 #define USE_TEXT_FIELD 1
319 #define UPDATE_TEXT_FIELD 2
320 #define REVERT_TO_DEFAULT 4
322 static int showIconFor(WMScreen
* scrPtr
, InspectorPanel
* panel
, char *wm_instance
, char *wm_class
, int flags
)
324 WMPixmap
*pixmap
= (WMPixmap
*) NULL
;
325 char *file
= NULL
, *path
= NULL
;
326 char *db_icon
= NULL
;
328 if ((flags
& USE_TEXT_FIELD
) != 0) {
329 file
= WMGetTextFieldText(panel
->fileText
);
330 if (file
&& file
[0] == 0) {
335 db_icon
= wDefaultGetIconFile(panel
->inspected
->screen_ptr
, wm_instance
, wm_class
, False
);
337 file
= wstrdup(db_icon
);
339 if (db_icon
!= NULL
&& (flags
& REVERT_TO_DEFAULT
) != 0) {
341 file
= wstrdup(db_icon
);
342 flags
|= UPDATE_TEXT_FIELD
;
345 if ((flags
& UPDATE_TEXT_FIELD
) != 0) {
346 WMSetTextFieldText(panel
->fileText
, file
);
350 path
= FindImage(wPreferences
.icon_path
, file
);
354 int len
= strlen(file
) + 80;
357 snprintf(buf
, len
, _("Could not find icon \"%s\" specified for this window"), file
);
358 wMessageDialog(panel
->frame
->screen_ptr
, _("Error"), buf
, _("OK"), NULL
, NULL
);
364 pixmap
= WMCreatePixmapFromFile(scrPtr
, path
);
369 int len
= strlen(file
) + 80;
372 snprintf(buf
, len
, _("Could not open specified icon \"%s\":%s"),
373 file
, RMessageForError(RErrorCode
));
374 wMessageDialog(panel
->frame
->screen_ptr
, _("Error"), buf
, _("OK"), NULL
, NULL
);
382 WMSetLabelImage(panel
->iconLbl
, pixmap
);
384 WMReleasePixmap(pixmap
);
390 static void updateIcon(WMButton
* button
, InspectorPanel
* panel
)
392 showIconFor(WMWidgetScreen(button
), panel
, NULL
, NULL
, USE_TEXT_FIELD
);
396 static int getBool(WMPropList
* value
)
400 if (!WMIsPLString(value
)) {
403 if (!(val
= WMGetFromPLString(value
))) {
407 if ((val
[1] == '\0' && (val
[0] == 'y' || val
[0] == 'Y' || val
[0] == 'T' || val
[0] == 't' || val
[0] == '1'))
408 || (strcasecmp(val
, "YES") == 0 || strcasecmp(val
, "TRUE") == 0)) {
411 } else if ((val
[1] == '\0'
412 && (val
[0] == 'n' || val
[0] == 'N' || val
[0] == 'F' || val
[0] == 'f' || val
[0] == '0'))
413 || (strcasecmp(val
, "NO") == 0 || strcasecmp(val
, "FALSE") == 0)) {
417 wwarning(_("can't convert \"%s\" to boolean"), val
);
422 #define UPDATE_DEFAULTS 1
426 * Will insert the attribute = value; pair in window's list,
427 * if it's different from the defaults.
428 * Defaults means either defaults database, or attributes saved
429 * for the default window "*". This is to let one revert options that are
430 * global because they were saved for all windows ("*").
435 insertAttribute(WMPropList
* dict
, WMPropList
* window
, WMPropList
* attr
, WMPropList
* value
, int flags
)
437 WMPropList
*def_win
, *def_value
= NULL
;
441 if (!(flags
& UPDATE_DEFAULTS
) && dict
) {
442 if ((def_win
= WMGetFromPLDictionary(dict
, AnyWindow
)) != NULL
) {
443 def_value
= WMGetFromPLDictionary(def_win
, attr
);
447 /* If we could not find defaults in database, fall to hardcoded values.
448 * Also this is true if we save defaults for all windows
451 def_value
= ((flags
& IS_BOOLEAN
) != 0) ? No
: EmptyString
;
453 if ((flags
& IS_BOOLEAN
))
454 update
= (getBool(value
) != getBool(def_value
));
456 update
= !WMIsPropListEqualTo(value
, def_value
);
460 WMPutInPLDictionary(window
, attr
, value
);
467 static void saveSettings(WMButton
* button
, InspectorPanel
* panel
)
469 WWindow
*wwin
= panel
->inspected
;
470 WDDomain
*db
= WDWindowAttributes
;
471 WMPropList
*dict
= db
->dictionary
;
472 WMPropList
*winDic
, *appDic
, *value
, *key
, *key2
;
475 int different
= 0, different2
= 0;
477 /* Save will apply the changes and save them */
478 applySettings(panel
->applyBtn
, panel
);
480 if (WMGetButtonSelected(panel
->instRb
) != 0)
481 key
= WMCreatePLString(wwin
->wm_instance
);
482 else if (WMGetButtonSelected(panel
->clsRb
) != 0)
483 key
= WMCreatePLString(wwin
->wm_class
);
484 else if (WMGetButtonSelected(panel
->bothRb
) != 0) {
487 buffer
= StrConcatDot(wwin
->wm_instance
, wwin
->wm_class
);
488 key
= WMCreatePLString(buffer
);
490 } else if (WMGetButtonSelected(panel
->defaultRb
) != 0) {
491 key
= WMRetainPropList(AnyWindow
);
492 flags
= UPDATE_DEFAULTS
;
500 dict
= WMCreatePLDictionary(NULL
, NULL
);
502 db
->dictionary
= dict
;
504 WMReleasePropList(key
);
509 if (showIconFor(WMWidgetScreen(button
), panel
, NULL
, NULL
, USE_TEXT_FIELD
) < 0)
512 WMPLSetCaseSensitive(True
);
514 winDic
= WMCreatePLDictionary(NULL
, NULL
);
515 appDic
= WMCreatePLDictionary(NULL
, NULL
);
517 /* Update icon for window */
518 icon_file
= WMGetTextFieldText(panel
->fileText
);
520 if (icon_file
[0] != 0) {
521 value
= WMCreatePLString(icon_file
);
522 different
|= insertAttribute(dict
, winDic
, AIcon
, value
, flags
);
523 different2
|= insertAttribute(dict
, appDic
, AIcon
, value
, flags
);
524 WMReleasePropList(value
);
530 int i
= WMGetPopUpButtonSelectedItem(panel
->wsP
);
534 if (i
>= 0 && i
< panel
->frame
->screen_ptr
->workspace_count
) {
535 value
= WMCreatePLString(panel
->frame
->screen_ptr
->workspaces
[i
]->name
);
536 different
|= insertAttribute(dict
, winDic
, AStartWorkspace
, value
, flags
);
537 WMReleasePropList(value
);
543 value
= (WMGetButtonSelected(panel
->alwChk
) != 0) ? Yes
: No
;
544 different
|= insertAttribute(dict
, winDic
, AAlwaysUserIcon
, value
, flags
);
546 value
= (WMGetButtonSelected(panel
->attrChk
[0]) != 0) ? Yes
: No
;
547 different
|= insertAttribute(dict
, winDic
, ANoTitlebar
, value
, flags
);
549 value
= (WMGetButtonSelected(panel
->attrChk
[1]) != 0) ? Yes
: No
;
550 different
|= insertAttribute(dict
, winDic
, ANoResizebar
, value
, flags
);
552 value
= (WMGetButtonSelected(panel
->attrChk
[2]) != 0) ? Yes
: No
;
553 different
|= insertAttribute(dict
, winDic
, ANoCloseButton
, value
, flags
);
555 value
= (WMGetButtonSelected(panel
->attrChk
[3]) != 0) ? Yes
: No
;
556 different
|= insertAttribute(dict
, winDic
, ANoMiniaturizeButton
, value
, flags
);
558 value
= (WMGetButtonSelected(panel
->attrChk
[4]) != 0) ? Yes
: No
;
559 different
|= insertAttribute(dict
, winDic
, ANoBorder
, value
, flags
);
561 value
= (WMGetButtonSelected(panel
->attrChk
[5]) != 0) ? Yes
: No
;
562 different
|= insertAttribute(dict
, winDic
, AKeepOnTop
, value
, flags
);
564 value
= (WMGetButtonSelected(panel
->attrChk
[6]) != 0) ? Yes
: No
;
565 different
|= insertAttribute(dict
, winDic
, AKeepOnBottom
, value
, flags
);
567 value
= (WMGetButtonSelected(panel
->attrChk
[7]) != 0) ? Yes
: No
;
568 different
|= insertAttribute(dict
, winDic
, AOmnipresent
, value
, flags
);
570 value
= (WMGetButtonSelected(panel
->attrChk
[8]) != 0) ? Yes
: No
;
571 different
|= insertAttribute(dict
, winDic
, AStartMiniaturized
, value
, flags
);
573 value
= (WMGetButtonSelected(panel
->attrChk
[9]) != 0) ? Yes
: No
;
574 different
|= insertAttribute(dict
, winDic
, AStartMaximized
, value
, flags
);
576 value
= (WMGetButtonSelected(panel
->attrChk
[10]) != 0) ? Yes
: No
;
577 different
|= insertAttribute(dict
, winDic
, AFullMaximize
, value
, flags
);
579 value
= (WMGetButtonSelected(panel
->moreChk
[0]) != 0) ? Yes
: No
;
580 different
|= insertAttribute(dict
, winDic
, ANoKeyBindings
, value
, flags
);
582 value
= (WMGetButtonSelected(panel
->moreChk
[1]) != 0) ? Yes
: No
;
583 different
|= insertAttribute(dict
, winDic
, ANoMouseBindings
, value
, flags
);
585 value
= (WMGetButtonSelected(panel
->moreChk
[2]) != 0) ? Yes
: No
;
586 different
|= insertAttribute(dict
, winDic
, ASkipWindowList
, value
, flags
);
588 value
= (WMGetButtonSelected(panel
->moreChk
[3]) != 0) ? Yes
: No
;
589 different
|= insertAttribute(dict
, winDic
, AUnfocusable
, value
, flags
);
591 value
= (WMGetButtonSelected(panel
->moreChk
[4]) != 0) ? Yes
: No
;
592 different
|= insertAttribute(dict
, winDic
, AKeepInsideScreen
, value
, flags
);
594 value
= (WMGetButtonSelected(panel
->moreChk
[5]) != 0) ? Yes
: No
;
595 different
|= insertAttribute(dict
, winDic
, ANoHideOthers
, value
, flags
);
597 value
= (WMGetButtonSelected(panel
->moreChk
[6]) != 0) ? Yes
: No
;
598 different
|= insertAttribute(dict
, winDic
, ADontSaveSession
, value
, flags
);
600 value
= (WMGetButtonSelected(panel
->moreChk
[7]) != 0) ? Yes
: No
;
601 different
|= insertAttribute(dict
, winDic
, AEmulateAppIcon
, value
, flags
);
603 value
= (WMGetButtonSelected(panel
->moreChk
[8]) != 0) ? Yes
: No
;
604 different
|= insertAttribute(dict
, winDic
, ADontFocusAcrossWorkspace
, value
, flags
);
606 #ifdef XKB_BUTTON_HINT
607 value
= (WMGetButtonSelected(panel
->moreChk
[9]) != 0) ? Yes
: No
;
608 different
|= insertAttribute(dict
, winDic
, ANoLanguageButton
, value
, flags
);
611 if (wwin
->main_window
!= None
&& wApplicationOf(wwin
->main_window
) != NULL
) {
612 value
= (WMGetButtonSelected(panel
->appChk
[0]) != 0) ? Yes
: No
;
613 different2
|= insertAttribute(dict
, appDic
, AStartHidden
, value
, flags
);
615 value
= (WMGetButtonSelected(panel
->appChk
[1]) != 0) ? Yes
: No
;
616 different2
|= insertAttribute(dict
, appDic
, ANoAppIcon
, value
, flags
);
618 value
= (WMGetButtonSelected(panel
->appChk
[2]) != 0) ? Yes
: No
;
619 different2
|= insertAttribute(dict
, appDic
, ASharedAppIcon
, value
, flags
);
622 if (wwin
->fake_group
) {
623 key2
= WMCreatePLString(wwin
->fake_group
->identifier
);
624 if (WMIsPropListEqualTo(key
, key2
)) {
625 WMMergePLDictionaries(winDic
, appDic
, True
);
626 different
|= different2
;
628 WMRemoveFromPLDictionary(dict
, key2
);
630 WMPutInPLDictionary(dict
, key2
, appDic
);
633 WMReleasePropList(key2
);
634 WMReleasePropList(appDic
);
635 } else if (wwin
->main_window
!= wwin
->client_win
) {
636 WApplication
*wapp
= wApplicationOf(wwin
->main_window
);
639 char *instance
= wapp
->main_window_desc
->wm_instance
;
640 char *class = wapp
->main_window_desc
->wm_class
;
643 buffer
= StrConcatDot(instance
, class);
644 key2
= WMCreatePLString(buffer
);
647 if (WMIsPropListEqualTo(key
, key2
)) {
648 WMMergePLDictionaries(winDic
, appDic
, True
);
649 different
|= different2
;
651 WMRemoveFromPLDictionary(dict
, key2
);
653 WMPutInPLDictionary(dict
, key2
, appDic
);
656 WMReleasePropList(key2
);
657 WMReleasePropList(appDic
);
660 WMMergePLDictionaries(winDic
, appDic
, True
);
661 different
|= different2
;
662 WMReleasePropList(appDic
);
665 WMRemoveFromPLDictionary(dict
, key
);
667 WMPutInPLDictionary(dict
, key
, winDic
);
670 WMReleasePropList(key
);
671 WMReleasePropList(winDic
);
673 UpdateDomainFile(db
);
676 WMPLSetCaseSensitive(False
);
679 static void makeAppIconFor(WApplication
* wapp
)
681 WScreen
*scr
= wapp
->main_window_desc
->screen_ptr
;
686 if (!WFLAGP(wapp
->main_window_desc
, no_appicon
))
687 wapp
->app_icon
= wAppIconCreate(wapp
->main_window_desc
);
689 wapp
->app_icon
= NULL
;
691 if (wapp
->app_icon
) {
692 WIcon
*icon
= wapp
->app_icon
->icon
;
693 WDock
*clip
= scr
->workspaces
[scr
->current_workspace
]->clip
;
696 wapp
->app_icon
->main_window
= wapp
->main_window
;
698 if (clip
&& clip
->attract_icons
&& wDockFindFreeSlot(clip
, &x
, &y
)) {
699 wapp
->app_icon
->attracted
= 1;
700 if (!wapp
->app_icon
->icon
->shadowed
) {
701 wapp
->app_icon
->icon
->shadowed
= 1;
702 wapp
->app_icon
->icon
->force_paint
= 1;
704 wDockAttachIcon(clip
, wapp
->app_icon
, x
, y
);
706 PlaceIcon(scr
, &x
, &y
, wGetHeadForWindow(wapp
->main_window_desc
));
707 wAppIconMove(wapp
->app_icon
, x
, y
);
709 if (!clip
|| !wapp
->app_icon
->attracted
|| !clip
->collapsed
)
710 XMapWindow(dpy
, icon
->core
->window
);
712 if (wPreferences
.auto_arrange_icons
&& !wapp
->app_icon
->attracted
)
713 wArrangeIcons(wapp
->main_window_desc
->screen_ptr
, True
);
717 static void removeAppIconFor(WApplication
* wapp
)
722 if (wapp
->app_icon
->docked
&& !wapp
->app_icon
->attracted
) {
723 wapp
->app_icon
->running
= 0;
724 /* since we keep it, we don't care if it was attracted or not */
725 wapp
->app_icon
->attracted
= 0;
726 wapp
->app_icon
->icon
->shadowed
= 0;
727 wapp
->app_icon
->main_window
= None
;
728 wapp
->app_icon
->pid
= 0;
729 wapp
->app_icon
->icon
->owner
= NULL
;
730 wapp
->app_icon
->icon
->icon_win
= None
;
731 wapp
->app_icon
->icon
->force_paint
= 1;
732 wAppIconPaint(wapp
->app_icon
);
733 } else if (wapp
->app_icon
->docked
) {
734 wapp
->app_icon
->running
= 0;
735 wDockDetach(wapp
->app_icon
->dock
, wapp
->app_icon
);
737 wAppIconDestroy(wapp
->app_icon
);
739 wapp
->app_icon
= NULL
;
740 if (wPreferences
.auto_arrange_icons
)
741 wArrangeIcons(wapp
->main_window_desc
->screen_ptr
, True
);
744 static void applySettings(WMButton
* button
, InspectorPanel
* panel
)
746 WWindow
*wwin
= panel
->inspected
;
747 WApplication
*wapp
= wApplicationOf(wwin
->main_window
);
748 int floating
, sunken
, skip_window_list
;
750 int old_no_bind_keys
;
751 int old_no_bind_mouse
;
753 old_omnipresent
= WFLAGP(wwin
, omnipresent
);
754 old_no_bind_keys
= WFLAGP(wwin
, no_bind_keys
);
755 old_no_bind_mouse
= WFLAGP(wwin
, no_bind_mouse
);
757 showIconFor(WMWidgetScreen(button
), panel
, NULL
, NULL
, USE_TEXT_FIELD
);
759 /* Attributes... --> Window Attributes */
760 WSETUFLAG(wwin
, no_titlebar
, WMGetButtonSelected(panel
->attrChk
[0]));
761 WSETUFLAG(wwin
, no_resizebar
, WMGetButtonSelected(panel
->attrChk
[1]));
762 WSETUFLAG(wwin
, no_close_button
, WMGetButtonSelected(panel
->attrChk
[2]));
763 WSETUFLAG(wwin
, no_miniaturize_button
, WMGetButtonSelected(panel
->attrChk
[3]));
764 WSETUFLAG(wwin
, no_border
, WMGetButtonSelected(panel
->attrChk
[4]));
765 floating
= WMGetButtonSelected(panel
->attrChk
[5]);
766 sunken
= WMGetButtonSelected(panel
->attrChk
[6]);
767 WSETUFLAG(wwin
, omnipresent
, WMGetButtonSelected(panel
->attrChk
[7]));
768 WSETUFLAG(wwin
, start_miniaturized
, WMGetButtonSelected(panel
->attrChk
[8]));
769 WSETUFLAG(wwin
, start_maximized
, WMGetButtonSelected(panel
->attrChk
[9]));
770 WSETUFLAG(wwin
, full_maximize
, WMGetButtonSelected(panel
->attrChk
[10]));
772 /* Attributes... --> Advanced Options */
773 WSETUFLAG(wwin
, no_bind_keys
, WMGetButtonSelected(panel
->moreChk
[0]));
774 WSETUFLAG(wwin
, no_bind_mouse
, WMGetButtonSelected(panel
->moreChk
[1]));
775 skip_window_list
= WMGetButtonSelected(panel
->moreChk
[2]);
776 WSETUFLAG(wwin
, no_focusable
, WMGetButtonSelected(panel
->moreChk
[3]));
777 WSETUFLAG(wwin
, dont_move_off
, WMGetButtonSelected(panel
->moreChk
[4]));
778 WSETUFLAG(wwin
, no_hide_others
, WMGetButtonSelected(panel
->moreChk
[5]));
779 WSETUFLAG(wwin
, dont_save_session
, WMGetButtonSelected(panel
->moreChk
[6]));
780 WSETUFLAG(wwin
, emulate_appicon
, WMGetButtonSelected(panel
->moreChk
[7]));
781 WSETUFLAG(wwin
, dont_focus_across_wksp
, WMGetButtonSelected(panel
->moreChk
[8]));
782 #ifdef XKB_BUTTON_HINT
783 WSETUFLAG(wwin
, no_language_button
, WMGetButtonSelected(panel
->moreChk
[9]));
785 WSETUFLAG(wwin
, always_user_icon
, WMGetButtonSelected(panel
->alwChk
));
787 if (WFLAGP(wwin
, no_titlebar
) && wwin
->flags
.shaded
)
788 wUnshadeWindow(wwin
);
790 WSETUFLAG(wwin
, no_shadeable
, WFLAGP(wwin
, no_titlebar
));
793 if (!WFLAGP(wwin
, floating
))
794 ChangeStackingLevel(wwin
->frame
->core
, WMFloatingLevel
);
796 if (!WFLAGP(wwin
, sunken
))
797 ChangeStackingLevel(wwin
->frame
->core
, WMSunkenLevel
);
799 if (WFLAGP(wwin
, floating
) || WFLAGP(wwin
, sunken
))
800 ChangeStackingLevel(wwin
->frame
->core
, WMNormalLevel
);
803 WSETUFLAG(wwin
, sunken
, sunken
);
804 WSETUFLAG(wwin
, floating
, floating
);
805 wwin
->flags
.omnipresent
= 0;
807 if (WFLAGP(wwin
, skip_window_list
) != skip_window_list
) {
808 WSETUFLAG(wwin
, skip_window_list
, skip_window_list
);
809 UpdateSwitchMenu(wwin
->screen_ptr
, wwin
, skip_window_list
? ACTION_REMOVE
: ACTION_ADD
);
811 if (WFLAGP(wwin
, omnipresent
) != old_omnipresent
) {
812 WMPostNotificationName(WMNChangedState
, wwin
, "omnipresent");
816 if (WFLAGP(wwin
, no_bind_keys
) != old_no_bind_keys
) {
817 if (WFLAGP(wwin
, no_bind_keys
)) {
818 XUngrabKey(dpy
, AnyKey
, AnyModifier
, wwin
->frame
->core
->window
);
820 wWindowSetKeyGrabs(wwin
);
824 if (WFLAGP(wwin
, no_bind_mouse
) != old_no_bind_mouse
) {
825 wWindowResetMouseGrabs(wwin
);
828 wwin
->frame
->flags
.need_texture_change
= 1;
829 wWindowConfigureBorders(wwin
);
830 wFrameWindowPaint(wwin
->frame
);
832 wNETWMUpdateActions(wwin
, False
);
836 * Can't apply emulate_appicon because it will probably cause problems.
840 /* do application wide stuff */
841 WSETUFLAG(wapp
->main_window_desc
, start_hidden
, WMGetButtonSelected(panel
->appChk
[0]));
843 WSETUFLAG(wapp
->main_window_desc
, no_appicon
, WMGetButtonSelected(panel
->appChk
[1]));
845 WSETUFLAG(wapp
->main_window_desc
, shared_appicon
, WMGetButtonSelected(panel
->appChk
[2]));
847 if (WFLAGP(wapp
->main_window_desc
, no_appicon
))
848 removeAppIconFor(wapp
);
850 makeAppIconFor(wapp
);
852 if (wapp
->app_icon
&& wapp
->main_window
== wwin
->client_win
) {
853 char *file
= WMGetTextFieldText(panel
->fileText
);
859 wIconChangeImageFile(wapp
->app_icon
->icon
, file
);
862 wAppIconPaint(wapp
->app_icon
);
867 static void revertSettings(WMButton
* button
, InspectorPanel
* panel
)
869 WWindow
*wwin
= panel
->inspected
;
870 WApplication
*wapp
= wApplicationOf(wwin
->main_window
);
872 char *wm_instance
= NULL
;
873 char *wm_class
= NULL
;
874 int workspace
, level
;
876 if (panel
->instRb
&& WMGetButtonSelected(panel
->instRb
) != 0)
877 wm_instance
= wwin
->wm_instance
;
878 else if (panel
->clsRb
&& WMGetButtonSelected(panel
->clsRb
) != 0)
879 wm_class
= wwin
->wm_class
;
880 else if (panel
->bothRb
&& WMGetButtonSelected(panel
->bothRb
) != 0) {
881 wm_instance
= wwin
->wm_instance
;
882 wm_class
= wwin
->wm_class
;
884 memset(&wwin
->defined_user_flags
, 0, sizeof(WWindowAttributes
));
885 memset(&wwin
->user_flags
, 0, sizeof(WWindowAttributes
));
886 memset(&wwin
->client_flags
, 0, sizeof(WWindowAttributes
));
888 wWindowSetupInitialAttributes(wwin
, &level
, &workspace
);
890 for (i
= 0; i
< 11; i
++) {
895 flag
= WFLAGP(wwin
, no_titlebar
);
898 flag
= WFLAGP(wwin
, no_resizebar
);
901 flag
= WFLAGP(wwin
, no_close_button
);
904 flag
= WFLAGP(wwin
, no_miniaturize_button
);
907 flag
= WFLAGP(wwin
, no_border
);
910 flag
= WFLAGP(wwin
, floating
);
913 flag
= WFLAGP(wwin
, sunken
);
916 flag
= WFLAGP(wwin
, omnipresent
);
919 flag
= WFLAGP(wwin
, start_miniaturized
);
922 flag
= WFLAGP(wwin
, start_maximized
!= 0);
925 flag
= WFLAGP(wwin
, full_maximize
);
928 WMSetButtonSelected(panel
->attrChk
[i
], flag
);
930 for (i
= 0; i
< 9; i
++) {
935 flag
= WFLAGP(wwin
, no_bind_keys
);
938 flag
= WFLAGP(wwin
, no_bind_mouse
);
941 flag
= WFLAGP(wwin
, skip_window_list
);
944 flag
= WFLAGP(wwin
, no_focusable
);
947 flag
= WFLAGP(wwin
, dont_move_off
);
950 flag
= WFLAGP(wwin
, no_hide_others
);
953 flag
= WFLAGP(wwin
, dont_save_session
);
956 flag
= WFLAGP(wwin
, emulate_appicon
);
959 flag
= WFLAGP(wwin
, dont_focus_across_wksp
);
961 #ifdef XKB_BUTTON_HINT
963 flag
= WFLAGP(wwin
, no_language_button
);
967 WMSetButtonSelected(panel
->moreChk
[i
], flag
);
969 if (panel
->appFrm
&& wapp
) {
970 for (i
= 0; i
< 2; i
++) {
975 flag
= WFLAGP(wapp
->main_window_desc
, start_hidden
);
978 flag
= WFLAGP(wapp
->main_window_desc
, no_appicon
);
981 flag
= WFLAGP(wapp
->main_window_desc
, shared_appicon
);
984 WMSetButtonSelected(panel
->appChk
[i
], flag
);
987 WMSetButtonSelected(panel
->alwChk
, WFLAGP(wwin
, always_user_icon
));
989 showIconFor(WMWidgetScreen(panel
->alwChk
), panel
, wm_instance
, wm_class
, REVERT_TO_DEFAULT
);
991 n
= wDefaultGetStartWorkspace(wwin
->screen_ptr
, wm_instance
, wm_class
);
993 if (n
>= 0 && n
< wwin
->screen_ptr
->workspace_count
) {
994 WMSetPopUpButtonSelectedItem(panel
->wsP
, n
+ 1);
996 WMSetPopUpButtonSelectedItem(panel
->wsP
, 0);
999 /* must auto apply, so that there wno't be internal
1000 * inconsistencies between the state in the flags and
1001 * the actual state of the window */
1002 applySettings(panel
->applyBtn
, panel
);
1005 static void chooseIconCallback(WMWidget
* self
, void *clientData
)
1008 InspectorPanel
*panel
= (InspectorPanel
*) clientData
;
1011 panel
->choosingIcon
= 1;
1013 WMSetButtonEnabled(panel
->browseIconBtn
, False
);
1015 result
= wIconChooserDialog(panel
->frame
->screen_ptr
, &file
,
1016 panel
->inspected
->wm_instance
, panel
->inspected
->wm_class
);
1018 panel
->choosingIcon
= 0;
1020 if (!panel
->destroyed
) { /* kluge */
1022 WMSetTextFieldText(panel
->fileText
, file
);
1023 showIconFor(WMWidgetScreen(self
), panel
, NULL
, NULL
, USE_TEXT_FIELD
);
1026 WMSetButtonEnabled(panel
->browseIconBtn
, True
);
1028 freeInspector(panel
);
1032 static void textEditedObserver(void *observerData
, WMNotification
* notification
)
1034 InspectorPanel
*panel
= (InspectorPanel
*) observerData
;
1036 if ((long)WMGetNotificationClientData(notification
) != WMReturnTextMovement
)
1039 showIconFor(WMWidgetScreen(panel
->win
), panel
, NULL
, NULL
, USE_TEXT_FIELD
);
1041 WMPerformButtonClick(panel->updateIconBtn);
1045 static void selectSpecification(WMWidget
* bPtr
, void *data
)
1047 InspectorPanel
*panel
= (InspectorPanel
*) data
;
1049 WWindow
*wwin
= panel
->inspected
;
1052 if (bPtr
== panel
->defaultRb
&& (wwin
->wm_instance
|| wwin
->wm_class
)) {
1053 WMSetButtonEnabled(panel
->applyBtn
, False
);
1055 WMSetButtonEnabled(panel
->applyBtn
, True
);
1058 len
= 16 + strlen(wwin
->wm_instance
? wwin
->wm_instance
: "?")
1059 + strlen(wwin
->wm_class
? wwin
->wm_class
: "?");
1063 snprintf(str
, len
, _("Inspecting %s.%s"),
1064 wwin
->wm_instance
? wwin
->wm_instance
: "?", wwin
->wm_class
? wwin
->wm_class
: "?");
1066 wFrameWindowChangeTitle(panel
->frame
->frame
, str
);
1071 static void selectWindow(WMWidget
* bPtr
, void *data
)
1073 InspectorPanel
*panel
= (InspectorPanel
*) data
;
1074 WWindow
*wwin
= panel
->inspected
;
1075 WScreen
*scr
= wwin
->screen_ptr
;
1079 if (XGrabPointer(dpy
, scr
->root_win
, True
,
1080 ButtonPressMask
, GrabModeAsync
, GrabModeAsync
, None
,
1081 wCursor
[WCUR_SELECT
], CurrentTime
) != GrabSuccess
) {
1082 wwarning("could not grab mouse pointer");
1086 WMSetLabelText(panel
->specLbl
, _("Click in the window you wish to inspect."));
1088 WMMaskEvent(dpy
, ButtonPressMask
, &event
);
1090 XUngrabPointer(dpy
, CurrentTime
);
1092 iwin
= wWindowFor(event
.xbutton
.subwindow
);
1094 if (iwin
&& !iwin
->flags
.internal_window
&& iwin
!= wwin
&& !iwin
->flags
.inspector_open
) {
1096 iwin
->flags
.inspector_open
= 1;
1097 iwin
->inspector
= createInspectorForWindow(iwin
,
1098 panel
->frame
->frame_x
, panel
->frame
->frame_y
, True
);
1099 wCloseInspectorForWindow(wwin
);
1101 WMSetLabelText(panel
->specLbl
, spec_text
);
1105 static InspectorPanel
*createInspectorForWindow(WWindow
* wwin
, int xpos
, int ypos
, Bool showSelectPanel
)
1107 WScreen
*scr
= wwin
->screen_ptr
;
1108 InspectorPanel
*panel
;
1112 int btn_width
, frame_width
;
1113 WMButton
*selectedBtn
= NULL
;
1114 #ifdef wrong_behaviour
1118 spec_text
= _("The configuration will apply to all\n"
1119 "windows that have their WM_CLASS\n"
1120 "property set to the above selected\n" "name, when saved.");
1122 panel
= wmalloc(sizeof(InspectorPanel
));
1123 memset(panel
, 0, sizeof(InspectorPanel
));
1125 panel
->destroyed
= 0;
1127 panel
->inspected
= wwin
;
1129 panel
->nextPtr
= panelList
;
1132 panel
->win
= WMCreateWindow(scr
->wmscreen
, "windowInspector");
1133 WMResizeWidget(panel
->win
, PWIDTH
, PHEIGHT
);
1135 /**** create common stuff ****/
1137 /* command buttons */
1138 /* (PWIDTH - (left and right margin) - (btn interval)) / 3 */
1139 btn_width
= (PWIDTH
- (2 * 15) - (2 * 10)) / 3;
1140 panel
->saveBtn
= WMCreateCommandButton(panel
->win
);
1141 WMSetButtonAction(panel
->saveBtn
, (WMAction
*) saveSettings
, panel
);
1142 WMMoveWidget(panel
->saveBtn
, (2 * (btn_width
+ 10)) + 15, 310);
1143 WMSetButtonText(panel
->saveBtn
, _("Save"));
1144 WMResizeWidget(panel
->saveBtn
, btn_width
, 28);
1145 if (wPreferences
.flags
.noupdates
|| !(wwin
->wm_class
|| wwin
->wm_instance
))
1146 WMSetButtonEnabled(panel
->saveBtn
, False
);
1148 panel
->applyBtn
= WMCreateCommandButton(panel
->win
);
1149 WMSetButtonAction(panel
->applyBtn
, (WMAction
*) applySettings
, panel
);
1150 WMMoveWidget(panel
->applyBtn
, btn_width
+ 10 + 15, 310);
1151 WMSetButtonText(panel
->applyBtn
, _("Apply"));
1152 WMResizeWidget(panel
->applyBtn
, btn_width
, 28);
1154 panel
->revertBtn
= WMCreateCommandButton(panel
->win
);
1155 WMSetButtonAction(panel
->revertBtn
, (WMAction
*) revertSettings
, panel
);
1156 WMMoveWidget(panel
->revertBtn
, 15, 310);
1157 WMSetButtonText(panel
->revertBtn
, _("Reload"));
1158 WMResizeWidget(panel
->revertBtn
, btn_width
, 28);
1160 /* page selection popup button */
1161 panel
->pagePopUp
= WMCreatePopUpButton(panel
->win
);
1162 WMSetPopUpButtonAction(panel
->pagePopUp
, (WMAction
*) changePage
, panel
);
1163 WMMoveWidget(panel
->pagePopUp
, 25, 15);
1164 WMResizeWidget(panel
->pagePopUp
, PWIDTH
- 50, 20);
1166 WMAddPopUpButtonItem(panel
->pagePopUp
, _("Window Specification"));
1167 WMAddPopUpButtonItem(panel
->pagePopUp
, _("Window Attributes"));
1168 WMAddPopUpButtonItem(panel
->pagePopUp
, _("Advanced Options"));
1169 WMAddPopUpButtonItem(panel
->pagePopUp
, _("Icon and Initial Workspace"));
1170 WMAddPopUpButtonItem(panel
->pagePopUp
, _("Application Specific"));
1172 /**** window spec ****/
1173 frame_width
= PWIDTH
- (2 * 15);
1175 panel
->specFrm
= WMCreateFrame(panel
->win
);
1176 WMSetFrameTitle(panel
->specFrm
, _("Window Specification"));
1177 WMMoveWidget(panel
->specFrm
, 15, 65);
1178 WMResizeWidget(panel
->specFrm
, frame_width
, 145);
1180 panel
->defaultRb
= WMCreateRadioButton(panel
->specFrm
);
1181 WMMoveWidget(panel
->defaultRb
, 10, 78);
1182 WMResizeWidget(panel
->defaultRb
, frame_width
- (2 * 10), 20);
1183 WMSetButtonText(panel
->defaultRb
, _("Defaults for all windows"));
1184 WMSetButtonSelected(panel
->defaultRb
, False
);
1185 WMSetButtonAction(panel
->defaultRb
, selectSpecification
, panel
);
1187 if (wwin
->wm_class
&& wwin
->wm_instance
) {
1190 tmp
= wstrconcat(wwin
->wm_instance
, ".");
1191 str
= wstrconcat(tmp
, wwin
->wm_class
);
1193 panel
->bothRb
= WMCreateRadioButton(panel
->specFrm
);
1194 WMMoveWidget(panel
->bothRb
, 10, 18);
1195 WMResizeWidget(panel
->bothRb
, frame_width
- (2 * 10), 20);
1196 WMSetButtonText(panel
->bothRb
, str
);
1199 WMGroupButtons(panel
->defaultRb
, panel
->bothRb
);
1202 selectedBtn
= panel
->bothRb
;
1204 WMSetButtonAction(panel
->bothRb
, selectSpecification
, panel
);
1207 if (wwin
->wm_instance
) {
1208 panel
->instRb
= WMCreateRadioButton(panel
->specFrm
);
1209 WMMoveWidget(panel
->instRb
, 10, 38);
1210 WMResizeWidget(panel
->instRb
, frame_width
- (2 * 10), 20);
1211 WMSetButtonText(panel
->instRb
, wwin
->wm_instance
);
1212 WMGroupButtons(panel
->defaultRb
, panel
->instRb
);
1215 selectedBtn
= panel
->instRb
;
1217 WMSetButtonAction(panel
->instRb
, selectSpecification
, panel
);
1220 if (wwin
->wm_class
) {
1221 panel
->clsRb
= WMCreateRadioButton(panel
->specFrm
);
1222 WMMoveWidget(panel
->clsRb
, 10, 58);
1223 WMResizeWidget(panel
->clsRb
, frame_width
- (2 * 10), 20);
1224 WMSetButtonText(panel
->clsRb
, wwin
->wm_class
);
1225 WMGroupButtons(panel
->defaultRb
, panel
->clsRb
);
1228 selectedBtn
= panel
->clsRb
;
1230 WMSetButtonAction(panel
->clsRb
, selectSpecification
, panel
);
1233 panel
->selWinB
= WMCreateCommandButton(panel
->specFrm
);
1234 WMMoveWidget(panel
->selWinB
, 20, 145 - 24 - 10);
1235 WMResizeWidget(panel
->selWinB
, frame_width
- 2 * 10 - 20, 24);
1236 WMSetButtonText(panel
->selWinB
, _("Select window"));
1237 WMSetButtonAction(panel
->selWinB
, selectWindow
, panel
);
1239 panel
->specLbl
= WMCreateLabel(panel
->win
);
1240 WMMoveWidget(panel
->specLbl
, 15, 210);
1241 WMResizeWidget(panel
->specLbl
, frame_width
, 100);
1242 WMSetLabelText(panel
->specLbl
, spec_text
);
1243 WMSetLabelWraps(panel
->specLbl
, True
);
1245 WMSetLabelTextAlignment(panel
->specLbl
, WALeft
);
1247 /**** attributes ****/
1248 panel
->attrFrm
= WMCreateFrame(panel
->win
);
1249 WMSetFrameTitle(panel
->attrFrm
, _("Attributes"));
1250 WMMoveWidget(panel
->attrFrm
, 15, 45);
1251 WMResizeWidget(panel
->attrFrm
, frame_width
, 250);
1253 for (i
= 0; i
< 11; i
++) {
1254 char *caption
= NULL
;
1260 caption
= _("Disable titlebar");
1261 flag
= WFLAGP(wwin
, no_titlebar
);
1262 descr
= _("Remove the titlebar of this window.\n"
1263 "To access the window commands menu of a window\n"
1264 "without it's titlebar, press Control+Esc (or the\n"
1265 "equivalent shortcut, if you changed the default\n" "settings).");
1268 caption
= _("Disable resizebar");
1269 flag
= WFLAGP(wwin
, no_resizebar
);
1270 descr
= _("Remove the resizebar of this window.");
1273 caption
= _("Disable close button");
1274 flag
= WFLAGP(wwin
, no_close_button
);
1275 descr
= _("Remove the `close window' button of this window.");
1278 caption
= _("Disable miniaturize button");
1279 flag
= WFLAGP(wwin
, no_miniaturize_button
);
1280 descr
= _("Remove the `miniaturize window' button of the window.");
1283 caption
= _("Disable border");
1284 flag
= WFLAGP(wwin
, no_border
);
1285 descr
= _("Remove the 1 pixel black border around the window.");
1288 caption
= _("Keep on top (floating)");
1289 flag
= WFLAGP(wwin
, floating
);
1290 descr
= _("Keep the window over other windows, not allowing\n" "them to cover it.");
1293 caption
= _("Keep at bottom (sunken)");
1294 flag
= WFLAGP(wwin
, sunken
);
1295 descr
= _("Keep the window under all other windows.");
1298 caption
= _("Omnipresent");
1299 flag
= WFLAGP(wwin
, omnipresent
);
1300 descr
= _("Make window present in all workspaces.");
1303 caption
= _("Start miniaturized");
1304 flag
= WFLAGP(wwin
, start_miniaturized
);
1305 descr
= _("Make the window be automatically miniaturized when it's\n" "first shown.");
1308 caption
= _("Start maximized");
1309 flag
= WFLAGP(wwin
, start_maximized
!= 0);
1310 descr
= _("Make the window be automatically maximized when it's\n" "first shown.");
1313 caption
= _("Full screen maximization");
1314 flag
= WFLAGP(wwin
, full_maximize
);
1315 descr
= _("Make the window use the whole screen space when it's\n"
1316 "maximized. The titlebar and resizebar will be moved\n"
1317 "to outside the screen.");
1320 panel
->attrChk
[i
] = WMCreateSwitchButton(panel
->attrFrm
);
1321 WMMoveWidget(panel
->attrChk
[i
], 10, 20 * (i
+ 1));
1322 WMResizeWidget(panel
->attrChk
[i
], frame_width
- 15, 20);
1323 WMSetButtonSelected(panel
->attrChk
[i
], flag
);
1324 WMSetButtonText(panel
->attrChk
[i
], caption
);
1326 WMSetBalloonTextForView(descr
, WMWidgetView(panel
->attrChk
[i
]));
1329 /**** more attributes ****/
1330 panel
->moreFrm
= WMCreateFrame(panel
->win
);
1331 WMSetFrameTitle(panel
->moreFrm
, _("Advanced"));
1332 WMMoveWidget(panel
->moreFrm
, 15, 45);
1333 WMResizeWidget(panel
->moreFrm
, frame_width
, 250);
1336 #ifdef XKB_BUTTON_HINT
1342 char *caption
= NULL
;
1348 caption
= _("Do not bind keyboard shortcuts");
1349 flag
= WFLAGP(wwin
, no_bind_keys
);
1350 descr
= _("Do not bind keyboard shortcuts from Window Maker\n"
1351 "when this window is focused. This will allow the\n"
1352 "window to receive all key combinations regardless\n"
1353 "of your shortcut configuration.");
1356 caption
= _("Do not bind mouse clicks");
1357 flag
= WFLAGP(wwin
, no_bind_mouse
);
1358 descr
= _("Do not bind mouse actions, such as `Alt'+drag\n"
1359 "in the window (when alt is the modifier you have\n" "configured).");
1362 caption
= _("Do not show in the window list");
1363 flag
= WFLAGP(wwin
, skip_window_list
);
1364 descr
= _("Do not list the window in the window list menu.");
1367 caption
= _("Do not let it take focus");
1368 flag
= WFLAGP(wwin
, no_focusable
);
1369 descr
= _("Do not let the window take keyboard focus when you\n" "click on it.");
1372 caption
= _("Keep inside screen");
1373 flag
= WFLAGP(wwin
, dont_move_off
);
1374 descr
= _("Do not allow the window to move itself completely\n"
1375 "outside the screen. For bug compatibility.\n");
1378 caption
= _("Ignore 'Hide Others'");
1379 flag
= WFLAGP(wwin
, no_hide_others
);
1380 descr
= _("Do not hide the window when issuing the\n" "`HideOthers' command.");
1383 caption
= _("Ignore 'Save Session'");
1384 flag
= WFLAGP(wwin
, dont_save_session
);
1385 descr
= _("Do not save the associated application in the\n"
1386 "session's state, so that it won't be restarted\n"
1387 "together with other applications when Window Maker\n" "starts.");
1390 caption
= _("Emulate application icon");
1391 flag
= WFLAGP(wwin
, emulate_appicon
);
1392 descr
= _("Make this window act as an application that provides\n"
1393 "enough information to Window Maker for a dockable\n"
1394 "application icon to be created.");
1397 caption
= _("Don't focus across workspaces");
1398 flag
= WFLAGP(wwin
, dont_focus_across_wksp
);
1399 descr
= _("Do not allow Window Maker to switch workspace to satisfy\n"
1400 "a focus request (useful e.g. in the case of a multiple-tab\n"
1401 "firefox opening in a different workspace).");
1403 #ifdef XKB_BUTTON_HINT
1405 caption
= _("Disable language button");
1406 flag
= WFLAGP(wwin
, no_language_button
);
1407 descr
= _("Remove the `toggle language' button of the window.");
1411 panel
->moreChk
[i
] = WMCreateSwitchButton(panel
->moreFrm
);
1412 WMMoveWidget(panel
->moreChk
[i
], 10, 20 * (i
+ 1));
1413 WMResizeWidget(panel
->moreChk
[i
], frame_width
- 15, 20);
1414 WMSetButtonSelected(panel
->moreChk
[i
], flag
);
1415 WMSetButtonText(panel
->moreChk
[i
], caption
);
1417 WMSetBalloonTextForView(descr
, WMWidgetView(panel
->moreChk
[i
]));
1420 /* miniwindow/workspace */
1421 panel
->iconFrm
= WMCreateFrame(panel
->win
);
1422 WMMoveWidget(panel
->iconFrm
, 15, 50);
1423 WMResizeWidget(panel
->iconFrm
, PWIDTH
- (2 * 15), 170);
1424 WMSetFrameTitle(panel
->iconFrm
, _("Miniwindow Image"));
1426 panel
->iconLbl
= WMCreateLabel(panel
->iconFrm
);
1427 WMMoveWidget(panel
->iconLbl
, PWIDTH
- (2 * 15) - 22 - 64, 20);
1428 WMResizeWidget(panel
->iconLbl
, 64, 64);
1429 WMSetLabelRelief(panel
->iconLbl
, WRGroove
);
1430 WMSetLabelImagePosition(panel
->iconLbl
, WIPImageOnly
);
1432 panel
->browseIconBtn
= WMCreateCommandButton(panel
->iconFrm
);
1433 WMSetButtonAction(panel
->browseIconBtn
, chooseIconCallback
, panel
);
1434 WMMoveWidget(panel
->browseIconBtn
, 22, 32);
1435 WMResizeWidget(panel
->browseIconBtn
, 120, 26);
1436 WMSetButtonText(panel
->browseIconBtn
, _("Browse..."));
1438 #ifdef wrong_behaviour
1439 WMSetButtonImagePosition(panel
->updateIconBtn
, WIPRight
);
1440 pixmap
= WMGetSystemPixmap(scr
->wmscreen
, WSIReturnArrow
);
1441 WMSetButtonImage(panel
->updateIconBtn
, pixmap
);
1442 WMReleasePixmap(pixmap
);
1443 pixmap
= WMGetSystemPixmap(scr
->wmscreen
, WSIHighlightedReturnArrow
);
1444 WMSetButtonAltImage(panel
->updateIconBtn
, pixmap
);
1445 WMReleasePixmap(pixmap
);
1448 panel
->fileLbl
= WMCreateLabel(panel
->iconFrm
);
1449 WMMoveWidget(panel
->fileLbl
, 20, 85);
1450 WMResizeWidget(panel
->fileLbl
, PWIDTH
- (2 * 15) - (2 * 20), 14);
1451 WMSetLabelText(panel
->fileLbl
, _("Icon filename:"));
1453 panel
->fileText
= WMCreateTextField(panel
->iconFrm
);
1454 WMMoveWidget(panel
->fileText
, 20, 105);
1455 WMResizeWidget(panel
->fileText
, PWIDTH
- (2 * 20) - (2 * 15), 20);
1456 WMSetTextFieldText(panel
->fileText
, NULL
);
1457 WMAddNotificationObserver(textEditedObserver
, panel
, WMTextDidEndEditingNotification
, panel
->fileText
);
1459 panel
->alwChk
= WMCreateSwitchButton(panel
->iconFrm
);
1460 WMMoveWidget(panel
->alwChk
, 20, 130);
1461 WMResizeWidget(panel
->alwChk
, PWIDTH
- (2 * 15) - (2 * 15), 30);
1462 WMSetButtonText(panel
->alwChk
, _("Ignore client supplied icon"));
1463 WMSetButtonSelected(panel
->alwChk
, WFLAGP(wwin
, always_user_icon
));
1465 panel
->wsFrm
= WMCreateFrame(panel
->win
);
1466 WMMoveWidget(panel
->wsFrm
, 15, 225);
1467 WMResizeWidget(panel
->wsFrm
, PWIDTH
- (2 * 15), 70);
1468 WMSetFrameTitle(panel
->wsFrm
, _("Initial Workspace"));
1470 WMSetBalloonTextForView(_("The workspace to place the window when it's"
1471 "first shown."), WMWidgetView(panel
->wsFrm
));
1473 panel
->wsP
= WMCreatePopUpButton(panel
->wsFrm
);
1474 WMMoveWidget(panel
->wsP
, 20, 30);
1475 WMResizeWidget(panel
->wsP
, PWIDTH
- (2 * 15) - (2 * 20), 20);
1476 WMAddPopUpButtonItem(panel
->wsP
, _("Nowhere in particular"));
1477 for (i
= 0; i
< wwin
->screen_ptr
->workspace_count
; i
++) {
1478 WMAddPopUpButtonItem(panel
->wsP
, scr
->workspaces
[i
]->name
);
1481 i
= wDefaultGetStartWorkspace(wwin
->screen_ptr
, wwin
->wm_instance
, wwin
->wm_class
);
1482 if (i
>= 0 && i
<= wwin
->screen_ptr
->workspace_count
) {
1483 WMSetPopUpButtonSelectedItem(panel
->wsP
, i
+ 1);
1485 WMSetPopUpButtonSelectedItem(panel
->wsP
, 0);
1488 /* application wide attributes */
1489 if (wwin
->main_window
!= None
) {
1490 WApplication
*wapp
= wApplicationOf(wwin
->main_window
);
1492 panel
->appFrm
= WMCreateFrame(panel
->win
);
1493 WMSetFrameTitle(panel
->appFrm
, _("Application Attributes"));
1494 WMMoveWidget(panel
->appFrm
, 15, 50);
1495 WMResizeWidget(panel
->appFrm
, frame_width
, 240);
1497 for (i
= 0; i
< 3; i
++) {
1498 char *caption
= NULL
;
1504 caption
= _("Start hidden");
1505 flag
= WFLAGP(wapp
->main_window_desc
, start_hidden
);
1506 descr
= _("Automatically hide application when it's started.");
1509 caption
= _("No application icon");
1510 flag
= WFLAGP(wapp
->main_window_desc
, no_appicon
);
1511 descr
= _("Disable the application icon for the application.\n"
1512 "Note that you won't be able to dock it anymore,\n"
1513 "and any icons that are already docked will stop\n"
1514 "working correctly.");
1517 caption
= _("Shared application icon");
1518 flag
= WFLAGP(wapp
->main_window_desc
, shared_appicon
);
1519 descr
= _("Use a single shared application icon for all of\n"
1520 "the instances of this application.\n");
1523 panel
->appChk
[i
] = WMCreateSwitchButton(panel
->appFrm
);
1524 WMMoveWidget(panel
->appChk
[i
], 10, 20 * (i
+ 1));
1525 WMResizeWidget(panel
->appChk
[i
], 205, 20);
1526 WMSetButtonSelected(panel
->appChk
[i
], flag
);
1527 WMSetButtonText(panel
->appChk
[i
], caption
);
1529 WMSetBalloonTextForView(descr
, WMWidgetView(panel
->appChk
[i
]));
1532 if (WFLAGP(wwin
, emulate_appicon
)) {
1533 WMSetButtonEnabled(panel
->appChk
[1], False
);
1534 WMSetButtonEnabled(panel
->moreChk
[7], True
);
1536 WMSetButtonEnabled(panel
->appChk
[1], True
);
1537 WMSetButtonEnabled(panel
->moreChk
[7], False
);
1542 if ((wwin
->transient_for
!= None
&& wwin
->transient_for
!= scr
->root_win
)
1543 || !wwin
->wm_class
|| !wwin
->wm_instance
)
1547 WMSetButtonEnabled(panel
->moreChk
[7], tmp
);
1549 WMSetPopUpButtonItemEnabled(panel
->pagePopUp
, 4, False
);
1550 panel
->appFrm
= NULL
;
1553 /* if the window is a transient, don't let it have a miniaturize
1555 if (wwin
->transient_for
!= None
&& wwin
->transient_for
!= scr
->root_win
)
1556 WMSetButtonEnabled(panel
->attrChk
[3], False
);
1558 WMSetButtonEnabled(panel
->attrChk
[3], True
);
1560 if (!wwin
->wm_class
&& !wwin
->wm_instance
) {
1561 WMSetPopUpButtonItemEnabled(panel
->pagePopUp
, 0, False
);
1564 WMRealizeWidget(panel
->win
);
1566 WMMapSubwidgets(panel
->win
);
1567 WMMapSubwidgets(panel
->specFrm
);
1568 WMMapSubwidgets(panel
->attrFrm
);
1569 WMMapSubwidgets(panel
->moreFrm
);
1570 WMMapSubwidgets(panel
->iconFrm
);
1571 WMMapSubwidgets(panel
->wsFrm
);
1573 WMMapSubwidgets(panel
->appFrm
);
1575 if (showSelectPanel
) {
1576 WMSetPopUpButtonSelectedItem(panel
->pagePopUp
, 0);
1577 changePage(panel
->pagePopUp
, panel
);
1579 WMSetPopUpButtonSelectedItem(panel
->pagePopUp
, 1);
1580 changePage(panel
->pagePopUp
, panel
);
1583 parent
= XCreateSimpleWindow(dpy
, scr
->root_win
, 0, 0, PWIDTH
, PHEIGHT
, 0, 0, 0);
1584 XSelectInput(dpy
, parent
, KeyPressMask
| KeyReleaseMask
);
1585 panel
->parent
= parent
;
1586 XReparentWindow(dpy
, WMWidgetXID(panel
->win
), parent
, 0, 0);
1588 WMMapWidget(panel
->win
);
1590 XSetTransientForHint(dpy
, parent
, wwin
->client_win
);
1592 if (xpos
== UNDEFINED_POS
) {
1593 x
= wwin
->frame_x
+ wwin
->frame
->core
->width
/ 2;
1594 y
= wwin
->frame_y
+ wwin
->frame
->top_width
* 2;
1595 if (y
+ PHEIGHT
> scr
->scr_height
)
1596 y
= scr
->scr_height
- PHEIGHT
- 30;
1597 if (x
+ PWIDTH
> scr
->scr_width
)
1598 x
= scr
->scr_width
- PWIDTH
;
1604 panel
->frame
= wManageInternalWindow(scr
, parent
, wwin
->client_win
, "Inspector", x
, y
, PWIDTH
, PHEIGHT
);
1607 selectedBtn
= panel
->defaultRb
;
1609 WMSetButtonSelected(selectedBtn
, True
);
1611 selectSpecification(selectedBtn
, panel
);
1613 /* kluge to know who should get the key events */
1614 panel
->frame
->client_leader
= WMWidgetXID(panel
->win
);
1616 WSETUFLAG(panel
->frame
, no_closable
, 0);
1617 WSETUFLAG(panel
->frame
, no_close_button
, 0);
1618 wWindowUpdateButtonImages(panel
->frame
);
1619 wFrameWindowShowButton(panel
->frame
->frame
, WFF_RIGHT_BUTTON
);
1620 panel
->frame
->frame
->on_click_right
= destroyInspector
;
1622 wWindowMap(panel
->frame
);
1624 showIconFor(WMWidgetScreen(panel
->alwChk
), panel
, wwin
->wm_instance
, wwin
->wm_class
, UPDATE_TEXT_FIELD
);
1629 void wShowInspectorForWindow(WWindow
* wwin
)
1631 if (wwin
->flags
.inspector_open
)
1634 WMSetBalloonEnabled(wwin
->screen_ptr
->wmscreen
, wPreferences
.help_balloon
);
1637 wwin
->flags
.inspector_open
= 1;
1638 wwin
->inspector
= createInspectorForWindow(wwin
, UNDEFINED_POS
, UNDEFINED_POS
, False
);
1641 void wHideInspectorForWindow(WWindow
* wwin
)
1643 WWindow
*pwin
= wwin
->inspector
->frame
;
1646 pwin
->flags
.hidden
= 1;
1648 wClientSetState(pwin
, IconicState
, None
);
1651 void wUnhideInspectorForWindow(WWindow
* wwin
)
1653 WWindow
*pwin
= wwin
->inspector
->frame
;
1655 pwin
->flags
.hidden
= 0;
1656 pwin
->flags
.mapped
= 1;
1657 XMapWindow(dpy
, pwin
->client_win
);
1658 XMapWindow(dpy
, pwin
->frame
->core
->window
);
1659 wClientSetState(pwin
, NormalState
, None
);
1662 WWindow
*wGetWindowOfInspectorForWindow(WWindow
* wwin
)
1664 if (wwin
->inspector
) {
1665 assert(wwin
->flags
.inspector_open
!= 0);
1667 return wwin
->inspector
->frame
;
1672 void wCloseInspectorForWindow(WWindow
* wwin
)
1674 WWindow
*pwin
= wwin
->inspector
->frame
; /* the inspector window */
1676 (*pwin
->frame
->on_click_right
) (NULL
, pwin
, NULL
);