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
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
*AAlwaysUserIcon
;
148 static WMPropList
*AStartMiniaturized
;
149 static WMPropList
*AStartMaximized
;
150 static WMPropList
*ADontSaveSession
;
151 static WMPropList
*AEmulateAppIcon
;
152 static WMPropList
*AFullMaximize
;
153 static WMPropList
*ASharedAppIcon
;
154 #ifdef XKB_BUTTON_HINT
155 static WMPropList
*ANoLanguageButton
;
158 static WMPropList
*AStartWorkspace
;
160 static WMPropList
*AIcon
;
162 /* application wide options */
163 static WMPropList
*AStartHidden
;
165 static WMPropList
*AnyWindow
;
166 static WMPropList
*EmptyString
;
167 static WMPropList
*Yes
, *No
;
172 static char *spec_text
;
174 static void applySettings(WMButton
* button
, InspectorPanel
* panel
);
176 #define UNDEFINED_POS 0xffffff
178 static InspectorPanel
*createInspectorForWindow(WWindow
* wwin
, int xpos
, int ypos
, Bool showSelectPanel
);
180 static void make_keys()
182 if (ANoTitlebar
!= NULL
)
185 AIcon
= WMCreatePLString("Icon");
186 ANoTitlebar
= WMCreatePLString("NoTitlebar");
187 ANoResizebar
= WMCreatePLString("NoResizebar");
188 ANoMiniaturizeButton
= WMCreatePLString("NoMiniaturizeButton");
189 ANoCloseButton
= WMCreatePLString("NoCloseButton");
190 ANoBorder
= WMCreatePLString("NoBorder");
191 ANoHideOthers
= WMCreatePLString("NoHideOthers");
192 ANoMouseBindings
= WMCreatePLString("NoMouseBindings");
193 ANoKeyBindings
= WMCreatePLString("NoKeyBindings");
194 ANoAppIcon
= WMCreatePLString("NoAppIcon");
195 AKeepOnTop
= WMCreatePLString("KeepOnTop");
196 AKeepOnBottom
= WMCreatePLString("KeepOnBottom");
197 AOmnipresent
= WMCreatePLString("Omnipresent");
198 ASkipWindowList
= WMCreatePLString("SkipWindowList");
199 AKeepInsideScreen
= WMCreatePLString("KeepInsideScreen");
200 AUnfocusable
= WMCreatePLString("Unfocusable");
201 AAlwaysUserIcon
= WMCreatePLString("AlwaysUserIcon");
202 AStartMiniaturized
= WMCreatePLString("StartMiniaturized");
203 AStartMaximized
= WMCreatePLString("StartMaximized");
204 AStartHidden
= WMCreatePLString("StartHidden");
205 ADontSaveSession
= WMCreatePLString("DontSaveSession");
206 AEmulateAppIcon
= WMCreatePLString("EmulateAppIcon");
207 AFullMaximize
= WMCreatePLString("FullMaximize");
208 ASharedAppIcon
= WMCreatePLString("SharedAppIcon");
209 #ifdef XKB_BUTTON_HINT
210 ANoLanguageButton
= WMCreatePLString("NoLanguageButton");
213 AStartWorkspace
= WMCreatePLString("StartWorkspace");
215 AnyWindow
= WMCreatePLString("*");
216 EmptyString
= WMCreatePLString("");
217 Yes
= WMCreatePLString("Yes");
218 No
= WMCreatePLString("No");
221 static void freeInspector(InspectorPanel
* panel
)
223 panel
->destroyed
= 1;
224 if (panel
->choosingIcon
)
227 WMDestroyWidget(panel
->win
);
229 XDestroyWindow(dpy
, panel
->parent
);
234 static void destroyInspector(WCoreWindow
* foo
, void *data
, XEvent
* event
)
236 InspectorPanel
*panel
;
240 while (panel
->frame
!= data
)
241 panel
= panel
->nextPtr
;
243 if (panelList
== panel
)
244 panelList
= panel
->nextPtr
;
247 while (tmp
->nextPtr
!= panel
) {
250 tmp
->nextPtr
= panel
->nextPtr
;
252 panel
->inspected
->flags
.inspector_open
= 0;
253 panel
->inspected
->inspector
= NULL
;
255 WMRemoveNotificationObserver(panel
);
257 wWindowUnmap(panel
->frame
);
258 wUnmanageWindow(panel
->frame
, True
, False
);
260 freeInspector(panel
);
263 void wDestroyInspectorPanels()
265 InspectorPanel
*panel
;
267 while (panelList
!= NULL
) {
269 panelList
= panelList
->nextPtr
;
270 wUnmanageWindow(panel
->frame
, False
, False
);
271 WMDestroyWidget(panel
->win
);
273 panel
->inspected
->flags
.inspector_open
= 0;
274 panel
->inspected
->inspector
= NULL
;
280 static void changePage(WMPopUpButton
* bPtr
, InspectorPanel
* panel
)
284 page
= WMGetPopUpButtonSelectedItem(bPtr
);
287 WMMapWidget(panel
->specFrm
);
288 WMMapWidget(panel
->specLbl
);
289 } else if (page
== 1) {
290 WMMapWidget(panel
->attrFrm
);
291 } else if (page
== 2) {
292 WMMapWidget(panel
->moreFrm
);
293 } else if (page
== 3) {
294 WMMapWidget(panel
->iconFrm
);
295 WMMapWidget(panel
->wsFrm
);
297 WMMapWidget(panel
->appFrm
);
301 WMUnmapWidget(panel
->specFrm
);
302 WMUnmapWidget(panel
->specLbl
);
305 WMUnmapWidget(panel
->attrFrm
);
307 WMUnmapWidget(panel
->moreFrm
);
309 WMUnmapWidget(panel
->iconFrm
);
310 WMUnmapWidget(panel
->wsFrm
);
312 if (page
!= 4 && panel
->appFrm
)
313 WMUnmapWidget(panel
->appFrm
);
316 #define USE_TEXT_FIELD 1
317 #define UPDATE_TEXT_FIELD 2
318 #define REVERT_TO_DEFAULT 4
320 static int showIconFor(WMScreen
* scrPtr
, InspectorPanel
* panel
, char *wm_instance
, char *wm_class
, int flags
)
322 WMPixmap
*pixmap
= (WMPixmap
*) NULL
;
323 char *file
= NULL
, *path
= NULL
;
324 char *db_icon
= NULL
;
326 if ((flags
& USE_TEXT_FIELD
) != 0) {
327 file
= WMGetTextFieldText(panel
->fileText
);
328 if (file
&& file
[0] == 0) {
333 db_icon
= wDefaultGetIconFile(panel
->inspected
->screen_ptr
, wm_instance
, wm_class
, False
);
335 file
= wstrdup(db_icon
);
337 if (db_icon
!= NULL
&& (flags
& REVERT_TO_DEFAULT
) != 0) {
339 file
= wstrdup(db_icon
);
340 flags
|= UPDATE_TEXT_FIELD
;
343 if ((flags
& UPDATE_TEXT_FIELD
) != 0) {
344 WMSetTextFieldText(panel
->fileText
, file
);
348 path
= FindImage(wPreferences
.icon_path
, file
);
352 int len
= strlen(file
) + 80;
355 snprintf(buf
, len
, _("Could not find icon \"%s\" specified for this window"), file
);
356 wMessageDialog(panel
->frame
->screen_ptr
, _("Error"), buf
, _("OK"), NULL
, NULL
);
362 pixmap
= WMCreatePixmapFromFile(scrPtr
, path
);
367 int len
= strlen(file
) + 80;
370 snprintf(buf
, len
, _("Could not open specified icon \"%s\":%s"),
371 file
, RMessageForError(RErrorCode
));
372 wMessageDialog(panel
->frame
->screen_ptr
, _("Error"), buf
, _("OK"), NULL
, NULL
);
380 WMSetLabelImage(panel
->iconLbl
, pixmap
);
382 WMReleasePixmap(pixmap
);
388 static void updateIcon(WMButton
* button
, InspectorPanel
* panel
)
390 showIconFor(WMWidgetScreen(button
), panel
, NULL
, NULL
, USE_TEXT_FIELD
);
394 static int getBool(WMPropList
* value
)
398 if (!WMIsPLString(value
)) {
401 if (!(val
= WMGetFromPLString(value
))) {
405 if ((val
[1] == '\0' && (val
[0] == 'y' || val
[0] == 'Y' || val
[0] == 'T' || val
[0] == 't' || val
[0] == '1'))
406 || (strcasecmp(val
, "YES") == 0 || strcasecmp(val
, "TRUE") == 0)) {
409 } else if ((val
[1] == '\0'
410 && (val
[0] == 'n' || val
[0] == 'N' || val
[0] == 'F' || val
[0] == 'f' || val
[0] == '0'))
411 || (strcasecmp(val
, "NO") == 0 || strcasecmp(val
, "FALSE") == 0)) {
415 wwarning(_("can't convert \"%s\" to boolean"), val
);
420 #define UPDATE_DEFAULTS 1
424 * Will insert the attribute = value; pair in window's list,
425 * if it's different from the defaults.
426 * Defaults means either defaults database, or attributes saved
427 * for the default window "*". This is to let one revert options that are
428 * global because they were saved for all windows ("*").
433 insertAttribute(WMPropList
* dict
, WMPropList
* window
, WMPropList
* attr
, WMPropList
* value
, int flags
)
435 WMPropList
*def_win
, *def_value
= NULL
;
439 if (!(flags
& UPDATE_DEFAULTS
) && dict
) {
440 if ((def_win
= WMGetFromPLDictionary(dict
, AnyWindow
)) != NULL
) {
441 def_value
= WMGetFromPLDictionary(def_win
, attr
);
445 /* If we could not find defaults in database, fall to hardcoded values.
446 * Also this is true if we save defaults for all windows
449 def_value
= ((flags
& IS_BOOLEAN
) != 0) ? No
: EmptyString
;
451 if ((flags
& IS_BOOLEAN
))
452 update
= (getBool(value
) != getBool(def_value
));
454 update
= !WMIsPropListEqualTo(value
, def_value
);
458 WMPutInPLDictionary(window
, attr
, value
);
465 static void saveSettings(WMButton
* button
, InspectorPanel
* panel
)
467 WWindow
*wwin
= panel
->inspected
;
468 WDDomain
*db
= WDWindowAttributes
;
469 WMPropList
*dict
= db
->dictionary
;
470 WMPropList
*winDic
, *appDic
, *value
, *key
, *key2
;
473 int different
= 0, different2
= 0;
475 /* Save will apply the changes and save them */
476 applySettings(panel
->applyBtn
, panel
);
478 if (WMGetButtonSelected(panel
->instRb
) != 0)
479 key
= WMCreatePLString(wwin
->wm_instance
);
480 else if (WMGetButtonSelected(panel
->clsRb
) != 0)
481 key
= WMCreatePLString(wwin
->wm_class
);
482 else if (WMGetButtonSelected(panel
->bothRb
) != 0) {
485 buffer
= StrConcatDot(wwin
->wm_instance
, wwin
->wm_class
);
486 key
= WMCreatePLString(buffer
);
488 } else if (WMGetButtonSelected(panel
->defaultRb
) != 0) {
489 key
= WMRetainPropList(AnyWindow
);
490 flags
= UPDATE_DEFAULTS
;
498 dict
= WMCreatePLDictionary(NULL
, NULL
);
500 db
->dictionary
= dict
;
502 WMReleasePropList(key
);
507 if (showIconFor(WMWidgetScreen(button
), panel
, NULL
, NULL
, USE_TEXT_FIELD
) < 0)
510 WMPLSetCaseSensitive(True
);
512 winDic
= WMCreatePLDictionary(NULL
, NULL
);
513 appDic
= WMCreatePLDictionary(NULL
, NULL
);
515 /* Update icon for window */
516 icon_file
= WMGetTextFieldText(panel
->fileText
);
518 if (icon_file
[0] != 0) {
519 value
= WMCreatePLString(icon_file
);
520 different
|= insertAttribute(dict
, winDic
, AIcon
, value
, flags
);
521 different2
|= insertAttribute(dict
, appDic
, AIcon
, value
, flags
);
522 WMReleasePropList(value
);
528 int i
= WMGetPopUpButtonSelectedItem(panel
->wsP
);
532 if (i
>= 0 && i
< panel
->frame
->screen_ptr
->workspace_count
) {
533 value
= WMCreatePLString(panel
->frame
->screen_ptr
->workspaces
[i
]->name
);
534 different
|= insertAttribute(dict
, winDic
, AStartWorkspace
, value
, flags
);
535 WMReleasePropList(value
);
541 value
= (WMGetButtonSelected(panel
->alwChk
) != 0) ? Yes
: No
;
542 different
|= insertAttribute(dict
, winDic
, AAlwaysUserIcon
, value
, flags
);
544 value
= (WMGetButtonSelected(panel
->attrChk
[0]) != 0) ? Yes
: No
;
545 different
|= insertAttribute(dict
, winDic
, ANoTitlebar
, value
, flags
);
547 value
= (WMGetButtonSelected(panel
->attrChk
[1]) != 0) ? Yes
: No
;
548 different
|= insertAttribute(dict
, winDic
, ANoResizebar
, value
, flags
);
550 value
= (WMGetButtonSelected(panel
->attrChk
[2]) != 0) ? Yes
: No
;
551 different
|= insertAttribute(dict
, winDic
, ANoCloseButton
, value
, flags
);
553 value
= (WMGetButtonSelected(panel
->attrChk
[3]) != 0) ? Yes
: No
;
554 different
|= insertAttribute(dict
, winDic
, ANoMiniaturizeButton
, value
, flags
);
556 value
= (WMGetButtonSelected(panel
->attrChk
[4]) != 0) ? Yes
: No
;
557 different
|= insertAttribute(dict
, winDic
, ANoBorder
, value
, flags
);
559 value
= (WMGetButtonSelected(panel
->attrChk
[5]) != 0) ? Yes
: No
;
560 different
|= insertAttribute(dict
, winDic
, AKeepOnTop
, value
, flags
);
562 value
= (WMGetButtonSelected(panel
->attrChk
[6]) != 0) ? Yes
: No
;
563 different
|= insertAttribute(dict
, winDic
, AKeepOnBottom
, value
, flags
);
565 value
= (WMGetButtonSelected(panel
->attrChk
[7]) != 0) ? Yes
: No
;
566 different
|= insertAttribute(dict
, winDic
, AOmnipresent
, value
, flags
);
568 value
= (WMGetButtonSelected(panel
->attrChk
[8]) != 0) ? Yes
: No
;
569 different
|= insertAttribute(dict
, winDic
, AStartMiniaturized
, value
, flags
);
571 value
= (WMGetButtonSelected(panel
->attrChk
[9]) != 0) ? Yes
: No
;
572 different
|= insertAttribute(dict
, winDic
, AStartMaximized
, value
, flags
);
574 value
= (WMGetButtonSelected(panel
->attrChk
[10]) != 0) ? Yes
: No
;
575 different
|= insertAttribute(dict
, winDic
, AFullMaximize
, value
, flags
);
577 value
= (WMGetButtonSelected(panel
->moreChk
[0]) != 0) ? Yes
: No
;
578 different
|= insertAttribute(dict
, winDic
, ANoKeyBindings
, value
, flags
);
580 value
= (WMGetButtonSelected(panel
->moreChk
[1]) != 0) ? Yes
: No
;
581 different
|= insertAttribute(dict
, winDic
, ANoMouseBindings
, value
, flags
);
583 value
= (WMGetButtonSelected(panel
->moreChk
[2]) != 0) ? Yes
: No
;
584 different
|= insertAttribute(dict
, winDic
, ASkipWindowList
, value
, flags
);
586 value
= (WMGetButtonSelected(panel
->moreChk
[3]) != 0) ? Yes
: No
;
587 different
|= insertAttribute(dict
, winDic
, AUnfocusable
, value
, flags
);
589 value
= (WMGetButtonSelected(panel
->moreChk
[4]) != 0) ? Yes
: No
;
590 different
|= insertAttribute(dict
, winDic
, AKeepInsideScreen
, value
, flags
);
592 value
= (WMGetButtonSelected(panel
->moreChk
[5]) != 0) ? Yes
: No
;
593 different
|= insertAttribute(dict
, winDic
, ANoHideOthers
, value
, flags
);
595 value
= (WMGetButtonSelected(panel
->moreChk
[6]) != 0) ? Yes
: No
;
596 different
|= insertAttribute(dict
, winDic
, ADontSaveSession
, value
, flags
);
598 value
= (WMGetButtonSelected(panel
->moreChk
[7]) != 0) ? Yes
: No
;
599 different
|= insertAttribute(dict
, winDic
, AEmulateAppIcon
, value
, flags
);
601 #ifdef XKB_BUTTON_HINT
602 value
= (WMGetButtonSelected(panel
->moreChk
[8]) != 0) ? Yes
: No
;
603 different
|= insertAttribute(dict
, winDic
, ANoLanguageButton
, value
, flags
);
606 if (wwin
->main_window
!= None
&& wApplicationOf(wwin
->main_window
) != NULL
) {
607 value
= (WMGetButtonSelected(panel
->appChk
[0]) != 0) ? Yes
: No
;
608 different2
|= insertAttribute(dict
, appDic
, AStartHidden
, value
, flags
);
610 value
= (WMGetButtonSelected(panel
->appChk
[1]) != 0) ? Yes
: No
;
611 different2
|= insertAttribute(dict
, appDic
, ANoAppIcon
, value
, flags
);
613 value
= (WMGetButtonSelected(panel
->appChk
[2]) != 0) ? Yes
: No
;
614 different2
|= insertAttribute(dict
, appDic
, ASharedAppIcon
, value
, flags
);
617 if (wwin
->fake_group
) {
618 key2
= WMCreatePLString(wwin
->fake_group
->identifier
);
619 if (WMIsPropListEqualTo(key
, key2
)) {
620 WMMergePLDictionaries(winDic
, appDic
, True
);
621 different
|= different2
;
623 WMRemoveFromPLDictionary(dict
, key2
);
625 WMPutInPLDictionary(dict
, key2
, appDic
);
628 WMReleasePropList(key2
);
629 WMReleasePropList(appDic
);
630 } else if (wwin
->main_window
!= wwin
->client_win
) {
631 WApplication
*wapp
= wApplicationOf(wwin
->main_window
);
634 char *instance
= wapp
->main_window_desc
->wm_instance
;
635 char *class = wapp
->main_window_desc
->wm_class
;
638 buffer
= StrConcatDot(instance
, class);
639 key2
= WMCreatePLString(buffer
);
642 if (WMIsPropListEqualTo(key
, key2
)) {
643 WMMergePLDictionaries(winDic
, appDic
, True
);
644 different
|= different2
;
646 WMRemoveFromPLDictionary(dict
, key2
);
648 WMPutInPLDictionary(dict
, key2
, appDic
);
651 WMReleasePropList(key2
);
652 WMReleasePropList(appDic
);
655 WMMergePLDictionaries(winDic
, appDic
, True
);
656 different
|= different2
;
657 WMReleasePropList(appDic
);
660 WMRemoveFromPLDictionary(dict
, key
);
662 WMPutInPLDictionary(dict
, key
, winDic
);
665 WMReleasePropList(key
);
666 WMReleasePropList(winDic
);
668 UpdateDomainFile(db
);
671 WMPLSetCaseSensitive(False
);
674 static void makeAppIconFor(WApplication
* wapp
)
676 WScreen
*scr
= wapp
->main_window_desc
->screen_ptr
;
681 if (!WFLAGP(wapp
->main_window_desc
, no_appicon
))
682 wapp
->app_icon
= wAppIconCreate(wapp
->main_window_desc
);
684 wapp
->app_icon
= NULL
;
686 if (wapp
->app_icon
) {
687 WIcon
*icon
= wapp
->app_icon
->icon
;
688 WDock
*clip
= scr
->workspaces
[scr
->current_workspace
]->clip
;
691 wapp
->app_icon
->main_window
= wapp
->main_window
;
693 if (clip
&& clip
->attract_icons
&& wDockFindFreeSlot(clip
, &x
, &y
)) {
694 wapp
->app_icon
->attracted
= 1;
695 if (!wapp
->app_icon
->icon
->shadowed
) {
696 wapp
->app_icon
->icon
->shadowed
= 1;
697 wapp
->app_icon
->icon
->force_paint
= 1;
699 wDockAttachIcon(clip
, wapp
->app_icon
, x
, y
);
701 PlaceIcon(scr
, &x
, &y
, wGetHeadForWindow(wapp
->main_window_desc
));
702 wAppIconMove(wapp
->app_icon
, x
, y
);
704 if (!clip
|| !wapp
->app_icon
->attracted
|| !clip
->collapsed
)
705 XMapWindow(dpy
, icon
->core
->window
);
707 if (wPreferences
.auto_arrange_icons
&& !wapp
->app_icon
->attracted
)
708 wArrangeIcons(wapp
->main_window_desc
->screen_ptr
, True
);
712 static void removeAppIconFor(WApplication
* wapp
)
717 if (wapp
->app_icon
->docked
&& !wapp
->app_icon
->attracted
) {
718 wapp
->app_icon
->running
= 0;
719 /* since we keep it, we don't care if it was attracted or not */
720 wapp
->app_icon
->attracted
= 0;
721 wapp
->app_icon
->icon
->shadowed
= 0;
722 wapp
->app_icon
->main_window
= None
;
723 wapp
->app_icon
->pid
= 0;
724 wapp
->app_icon
->icon
->owner
= NULL
;
725 wapp
->app_icon
->icon
->icon_win
= None
;
726 wapp
->app_icon
->icon
->force_paint
= 1;
727 wAppIconPaint(wapp
->app_icon
);
728 } else if (wapp
->app_icon
->docked
) {
729 wapp
->app_icon
->running
= 0;
730 wDockDetach(wapp
->app_icon
->dock
, wapp
->app_icon
);
732 wAppIconDestroy(wapp
->app_icon
);
734 wapp
->app_icon
= NULL
;
735 if (wPreferences
.auto_arrange_icons
)
736 wArrangeIcons(wapp
->main_window_desc
->screen_ptr
, True
);
739 static void applySettings(WMButton
* button
, InspectorPanel
* panel
)
741 WWindow
*wwin
= panel
->inspected
;
742 WApplication
*wapp
= wApplicationOf(wwin
->main_window
);
743 int floating
, sunken
, skip_window_list
;
745 int old_no_bind_keys
;
746 int old_no_bind_mouse
;
748 old_omnipresent
= WFLAGP(wwin
, omnipresent
);
749 old_no_bind_keys
= WFLAGP(wwin
, no_bind_keys
);
750 old_no_bind_mouse
= WFLAGP(wwin
, no_bind_mouse
);
752 showIconFor(WMWidgetScreen(button
), panel
, NULL
, NULL
, USE_TEXT_FIELD
);
754 WSETUFLAG(wwin
, no_titlebar
, WMGetButtonSelected(panel
->attrChk
[0]));
755 WSETUFLAG(wwin
, no_resizebar
, WMGetButtonSelected(panel
->attrChk
[1]));
756 WSETUFLAG(wwin
, no_close_button
, WMGetButtonSelected(panel
->attrChk
[2]));
757 WSETUFLAG(wwin
, no_miniaturize_button
, WMGetButtonSelected(panel
->attrChk
[3]));
758 WSETUFLAG(wwin
, no_border
, WMGetButtonSelected(panel
->attrChk
[4]));
759 floating
= WMGetButtonSelected(panel
->attrChk
[5]);
760 sunken
= WMGetButtonSelected(panel
->attrChk
[6]);
761 WSETUFLAG(wwin
, omnipresent
, WMGetButtonSelected(panel
->attrChk
[7]));
762 WSETUFLAG(wwin
, start_miniaturized
, WMGetButtonSelected(panel
->attrChk
[8]));
763 WSETUFLAG(wwin
, start_maximized
, WMGetButtonSelected(panel
->attrChk
[9]));
764 WSETUFLAG(wwin
, full_maximize
, WMGetButtonSelected(panel
->attrChk
[10]));
766 WSETUFLAG(wwin
, no_bind_keys
, WMGetButtonSelected(panel
->moreChk
[0]));
767 WSETUFLAG(wwin
, no_bind_mouse
, WMGetButtonSelected(panel
->moreChk
[1]));
768 skip_window_list
= WMGetButtonSelected(panel
->moreChk
[2]);
769 WSETUFLAG(wwin
, no_focusable
, WMGetButtonSelected(panel
->moreChk
[3]));
770 WSETUFLAG(wwin
, dont_move_off
, WMGetButtonSelected(panel
->moreChk
[4]));
771 WSETUFLAG(wwin
, no_hide_others
, WMGetButtonSelected(panel
->moreChk
[5]));
772 WSETUFLAG(wwin
, dont_save_session
, WMGetButtonSelected(panel
->moreChk
[6]));
773 WSETUFLAG(wwin
, emulate_appicon
, WMGetButtonSelected(panel
->moreChk
[7]));
774 #ifdef XKB_BUTTON_HINT
775 WSETUFLAG(wwin
, no_language_button
, WMGetButtonSelected(panel
->moreChk
[8]));
777 WSETUFLAG(wwin
, always_user_icon
, WMGetButtonSelected(panel
->alwChk
));
779 if (WFLAGP(wwin
, no_titlebar
) && wwin
->flags
.shaded
)
780 wUnshadeWindow(wwin
);
782 WSETUFLAG(wwin
, no_shadeable
, WFLAGP(wwin
, no_titlebar
));
785 if (!WFLAGP(wwin
, floating
))
786 ChangeStackingLevel(wwin
->frame
->core
, WMFloatingLevel
);
788 if (!WFLAGP(wwin
, sunken
))
789 ChangeStackingLevel(wwin
->frame
->core
, WMSunkenLevel
);
791 if (WFLAGP(wwin
, floating
) || WFLAGP(wwin
, sunken
))
792 ChangeStackingLevel(wwin
->frame
->core
, WMNormalLevel
);
795 WSETUFLAG(wwin
, sunken
, sunken
);
796 WSETUFLAG(wwin
, floating
, floating
);
797 wwin
->flags
.omnipresent
= 0;
799 if (WFLAGP(wwin
, skip_window_list
) != skip_window_list
) {
800 WSETUFLAG(wwin
, skip_window_list
, skip_window_list
);
801 UpdateSwitchMenu(wwin
->screen_ptr
, wwin
, skip_window_list
? ACTION_REMOVE
: ACTION_ADD
);
803 if (WFLAGP(wwin
, omnipresent
) != old_omnipresent
) {
804 WMPostNotificationName(WMNChangedState
, wwin
, "omnipresent");
808 if (WFLAGP(wwin
, no_bind_keys
) != old_no_bind_keys
) {
809 if (WFLAGP(wwin
, no_bind_keys
)) {
810 XUngrabKey(dpy
, AnyKey
, AnyModifier
, wwin
->frame
->core
->window
);
812 wWindowSetKeyGrabs(wwin
);
816 if (WFLAGP(wwin
, no_bind_mouse
) != old_no_bind_mouse
) {
817 wWindowResetMouseGrabs(wwin
);
820 wwin
->frame
->flags
.need_texture_change
= 1;
821 wWindowConfigureBorders(wwin
);
822 wFrameWindowPaint(wwin
->frame
);
824 wNETWMUpdateActions(wwin
, False
);
828 * Can't apply emulate_appicon because it will probably cause problems.
832 /* do application wide stuff */
833 WSETUFLAG(wapp
->main_window_desc
, start_hidden
, WMGetButtonSelected(panel
->appChk
[0]));
835 WSETUFLAG(wapp
->main_window_desc
, no_appicon
, WMGetButtonSelected(panel
->appChk
[1]));
837 WSETUFLAG(wapp
->main_window_desc
, shared_appicon
, WMGetButtonSelected(panel
->appChk
[2]));
839 if (WFLAGP(wapp
->main_window_desc
, no_appicon
))
840 removeAppIconFor(wapp
);
842 makeAppIconFor(wapp
);
844 if (wapp
->app_icon
&& wapp
->main_window
== wwin
->client_win
) {
845 char *file
= WMGetTextFieldText(panel
->fileText
);
851 wIconChangeImageFile(wapp
->app_icon
->icon
, file
);
854 wAppIconPaint(wapp
->app_icon
);
859 static void revertSettings(WMButton
* button
, InspectorPanel
* panel
)
861 WWindow
*wwin
= panel
->inspected
;
862 WApplication
*wapp
= wApplicationOf(wwin
->main_window
);
864 char *wm_instance
= NULL
;
865 char *wm_class
= NULL
;
866 int workspace
, level
;
868 if (panel
->instRb
&& WMGetButtonSelected(panel
->instRb
) != 0)
869 wm_instance
= wwin
->wm_instance
;
870 else if (panel
->clsRb
&& WMGetButtonSelected(panel
->clsRb
) != 0)
871 wm_class
= wwin
->wm_class
;
872 else if (panel
->bothRb
&& WMGetButtonSelected(panel
->bothRb
) != 0) {
873 wm_instance
= wwin
->wm_instance
;
874 wm_class
= wwin
->wm_class
;
876 memset(&wwin
->defined_user_flags
, 0, sizeof(WWindowAttributes
));
877 memset(&wwin
->user_flags
, 0, sizeof(WWindowAttributes
));
878 memset(&wwin
->client_flags
, 0, sizeof(WWindowAttributes
));
880 wWindowSetupInitialAttributes(wwin
, &level
, &workspace
);
882 for (i
= 0; i
< 11; i
++) {
887 flag
= WFLAGP(wwin
, no_titlebar
);
890 flag
= WFLAGP(wwin
, no_resizebar
);
893 flag
= WFLAGP(wwin
, no_close_button
);
896 flag
= WFLAGP(wwin
, no_miniaturize_button
);
899 flag
= WFLAGP(wwin
, no_border
);
902 flag
= WFLAGP(wwin
, floating
);
905 flag
= WFLAGP(wwin
, sunken
);
908 flag
= WFLAGP(wwin
, omnipresent
);
911 flag
= WFLAGP(wwin
, start_miniaturized
);
914 flag
= WFLAGP(wwin
, start_maximized
!= 0);
917 flag
= WFLAGP(wwin
, full_maximize
);
920 WMSetButtonSelected(panel
->attrChk
[i
], flag
);
922 for (i
= 0; i
< 8; i
++) {
927 flag
= WFLAGP(wwin
, no_bind_keys
);
930 flag
= WFLAGP(wwin
, no_bind_mouse
);
933 flag
= WFLAGP(wwin
, skip_window_list
);
936 flag
= WFLAGP(wwin
, no_focusable
);
939 flag
= WFLAGP(wwin
, dont_move_off
);
942 flag
= WFLAGP(wwin
, no_hide_others
);
945 flag
= WFLAGP(wwin
, dont_save_session
);
948 flag
= WFLAGP(wwin
, emulate_appicon
);
950 #ifdef XKB_BUTTON_HINT
952 flag
= WFLAGP(wwin
, no_language_button
);
956 WMSetButtonSelected(panel
->moreChk
[i
], flag
);
958 if (panel
->appFrm
&& wapp
) {
959 for (i
= 0; i
< 2; i
++) {
964 flag
= WFLAGP(wapp
->main_window_desc
, start_hidden
);
967 flag
= WFLAGP(wapp
->main_window_desc
, no_appicon
);
970 flag
= WFLAGP(wapp
->main_window_desc
, shared_appicon
);
973 WMSetButtonSelected(panel
->appChk
[i
], flag
);
976 WMSetButtonSelected(panel
->alwChk
, WFLAGP(wwin
, always_user_icon
));
978 showIconFor(WMWidgetScreen(panel
->alwChk
), panel
, wm_instance
, wm_class
, REVERT_TO_DEFAULT
);
980 n
= wDefaultGetStartWorkspace(wwin
->screen_ptr
, wm_instance
, wm_class
);
982 if (n
>= 0 && n
< wwin
->screen_ptr
->workspace_count
) {
983 WMSetPopUpButtonSelectedItem(panel
->wsP
, n
+ 1);
985 WMSetPopUpButtonSelectedItem(panel
->wsP
, 0);
988 /* must auto apply, so that there wno't be internal
989 * inconsistencies between the state in the flags and
990 * the actual state of the window */
991 applySettings(panel
->applyBtn
, panel
);
994 static void chooseIconCallback(WMWidget
* self
, void *clientData
)
997 InspectorPanel
*panel
= (InspectorPanel
*) clientData
;
1000 panel
->choosingIcon
= 1;
1002 WMSetButtonEnabled(panel
->browseIconBtn
, False
);
1004 result
= wIconChooserDialog(panel
->frame
->screen_ptr
, &file
,
1005 panel
->inspected
->wm_instance
, panel
->inspected
->wm_class
);
1007 panel
->choosingIcon
= 0;
1009 if (!panel
->destroyed
) { /* kluge */
1011 WMSetTextFieldText(panel
->fileText
, file
);
1012 showIconFor(WMWidgetScreen(self
), panel
, NULL
, NULL
, USE_TEXT_FIELD
);
1015 WMSetButtonEnabled(panel
->browseIconBtn
, True
);
1017 freeInspector(panel
);
1021 static void textEditedObserver(void *observerData
, WMNotification
* notification
)
1023 InspectorPanel
*panel
= (InspectorPanel
*) observerData
;
1025 if ((long)WMGetNotificationClientData(notification
) != WMReturnTextMovement
)
1028 showIconFor(WMWidgetScreen(panel
->win
), panel
, NULL
, NULL
, USE_TEXT_FIELD
);
1030 WMPerformButtonClick(panel->updateIconBtn);
1034 static void selectSpecification(WMWidget
* bPtr
, void *data
)
1036 InspectorPanel
*panel
= (InspectorPanel
*) data
;
1038 WWindow
*wwin
= panel
->inspected
;
1041 if (bPtr
== panel
->defaultRb
&& (wwin
->wm_instance
|| wwin
->wm_class
)) {
1042 WMSetButtonEnabled(panel
->applyBtn
, False
);
1044 WMSetButtonEnabled(panel
->applyBtn
, True
);
1047 len
= 16 + strlen(wwin
->wm_instance
? wwin
->wm_instance
: "?")
1048 + strlen(wwin
->wm_class
? wwin
->wm_class
: "?");
1052 snprintf(str
, len
, _("Inspecting %s.%s"),
1053 wwin
->wm_instance
? wwin
->wm_instance
: "?", wwin
->wm_class
? wwin
->wm_class
: "?");
1055 wFrameWindowChangeTitle(panel
->frame
->frame
, str
);
1060 static void selectWindow(WMWidget
* bPtr
, void *data
)
1062 InspectorPanel
*panel
= (InspectorPanel
*) data
;
1063 WWindow
*wwin
= panel
->inspected
;
1064 WScreen
*scr
= wwin
->screen_ptr
;
1068 if (XGrabPointer(dpy
, scr
->root_win
, True
,
1069 ButtonPressMask
, GrabModeAsync
, GrabModeAsync
, None
,
1070 wCursor
[WCUR_SELECT
], CurrentTime
) != GrabSuccess
) {
1071 wwarning("could not grab mouse pointer");
1075 WMSetLabelText(panel
->specLbl
, _("Click in the window you wish to inspect."));
1077 WMMaskEvent(dpy
, ButtonPressMask
, &event
);
1079 XUngrabPointer(dpy
, CurrentTime
);
1081 iwin
= wWindowFor(event
.xbutton
.subwindow
);
1083 if (iwin
&& !iwin
->flags
.internal_window
&& iwin
!= wwin
&& !iwin
->flags
.inspector_open
) {
1085 iwin
->flags
.inspector_open
= 1;
1086 iwin
->inspector
= createInspectorForWindow(iwin
,
1087 panel
->frame
->frame_x
, panel
->frame
->frame_y
, True
);
1088 wCloseInspectorForWindow(wwin
);
1090 WMSetLabelText(panel
->specLbl
, spec_text
);
1094 static InspectorPanel
*createInspectorForWindow(WWindow
* wwin
, int xpos
, int ypos
, Bool showSelectPanel
)
1096 WScreen
*scr
= wwin
->screen_ptr
;
1097 InspectorPanel
*panel
;
1101 int btn_width
, frame_width
;
1102 WMButton
*selectedBtn
= NULL
;
1103 #ifdef wrong_behaviour
1107 spec_text
= _("The configuration will apply to all\n"
1108 "windows that have their WM_CLASS\n"
1109 "property set to the above selected\n" "name, when saved.");
1111 panel
= wmalloc(sizeof(InspectorPanel
));
1112 memset(panel
, 0, sizeof(InspectorPanel
));
1114 panel
->destroyed
= 0;
1116 panel
->inspected
= wwin
;
1118 panel
->nextPtr
= panelList
;
1121 panel
->win
= WMCreateWindow(scr
->wmscreen
, "windowInspector");
1122 WMResizeWidget(panel
->win
, PWIDTH
, PHEIGHT
);
1124 /**** create common stuff ****/
1126 /* command buttons */
1127 /* (PWIDTH - (left and right margin) - (btn interval)) / 3 */
1128 btn_width
= (PWIDTH
- (2 * 15) - (2 * 10)) / 3;
1129 panel
->saveBtn
= WMCreateCommandButton(panel
->win
);
1130 WMSetButtonAction(panel
->saveBtn
, (WMAction
*) saveSettings
, panel
);
1131 WMMoveWidget(panel
->saveBtn
, (2 * (btn_width
+ 10)) + 15, 310);
1132 WMSetButtonText(panel
->saveBtn
, _("Save"));
1133 WMResizeWidget(panel
->saveBtn
, btn_width
, 28);
1134 if (wPreferences
.flags
.noupdates
|| !(wwin
->wm_class
|| wwin
->wm_instance
))
1135 WMSetButtonEnabled(panel
->saveBtn
, False
);
1137 panel
->applyBtn
= WMCreateCommandButton(panel
->win
);
1138 WMSetButtonAction(panel
->applyBtn
, (WMAction
*) applySettings
, panel
);
1139 WMMoveWidget(panel
->applyBtn
, btn_width
+ 10 + 15, 310);
1140 WMSetButtonText(panel
->applyBtn
, _("Apply"));
1141 WMResizeWidget(panel
->applyBtn
, btn_width
, 28);
1143 panel
->revertBtn
= WMCreateCommandButton(panel
->win
);
1144 WMSetButtonAction(panel
->revertBtn
, (WMAction
*) revertSettings
, panel
);
1145 WMMoveWidget(panel
->revertBtn
, 15, 310);
1146 WMSetButtonText(panel
->revertBtn
, _("Reload"));
1147 WMResizeWidget(panel
->revertBtn
, btn_width
, 28);
1149 /* page selection popup button */
1150 panel
->pagePopUp
= WMCreatePopUpButton(panel
->win
);
1151 WMSetPopUpButtonAction(panel
->pagePopUp
, (WMAction
*) changePage
, panel
);
1152 WMMoveWidget(panel
->pagePopUp
, 25, 15);
1153 WMResizeWidget(panel
->pagePopUp
, PWIDTH
- 50, 20);
1155 WMAddPopUpButtonItem(panel
->pagePopUp
, _("Window Specification"));
1156 WMAddPopUpButtonItem(panel
->pagePopUp
, _("Window Attributes"));
1157 WMAddPopUpButtonItem(panel
->pagePopUp
, _("Advanced Options"));
1158 WMAddPopUpButtonItem(panel
->pagePopUp
, _("Icon and Initial Workspace"));
1159 WMAddPopUpButtonItem(panel
->pagePopUp
, _("Application Specific"));
1161 /**** window spec ****/
1162 frame_width
= PWIDTH
- (2 * 15);
1164 panel
->specFrm
= WMCreateFrame(panel
->win
);
1165 WMSetFrameTitle(panel
->specFrm
, _("Window Specification"));
1166 WMMoveWidget(panel
->specFrm
, 15, 65);
1167 WMResizeWidget(panel
->specFrm
, frame_width
, 145);
1169 panel
->defaultRb
= WMCreateRadioButton(panel
->specFrm
);
1170 WMMoveWidget(panel
->defaultRb
, 10, 78);
1171 WMResizeWidget(panel
->defaultRb
, frame_width
- (2 * 10), 20);
1172 WMSetButtonText(panel
->defaultRb
, _("Defaults for all windows"));
1173 WMSetButtonSelected(panel
->defaultRb
, False
);
1174 WMSetButtonAction(panel
->defaultRb
, selectSpecification
, panel
);
1176 if (wwin
->wm_class
&& wwin
->wm_instance
) {
1179 tmp
= wstrconcat(wwin
->wm_instance
, ".");
1180 str
= wstrconcat(tmp
, wwin
->wm_class
);
1182 panel
->bothRb
= WMCreateRadioButton(panel
->specFrm
);
1183 WMMoveWidget(panel
->bothRb
, 10, 18);
1184 WMResizeWidget(panel
->bothRb
, frame_width
- (2 * 10), 20);
1185 WMSetButtonText(panel
->bothRb
, str
);
1188 WMGroupButtons(panel
->defaultRb
, panel
->bothRb
);
1191 selectedBtn
= panel
->bothRb
;
1193 WMSetButtonAction(panel
->bothRb
, selectSpecification
, panel
);
1196 if (wwin
->wm_instance
) {
1197 panel
->instRb
= WMCreateRadioButton(panel
->specFrm
);
1198 WMMoveWidget(panel
->instRb
, 10, 38);
1199 WMResizeWidget(panel
->instRb
, frame_width
- (2 * 10), 20);
1200 WMSetButtonText(panel
->instRb
, wwin
->wm_instance
);
1201 WMGroupButtons(panel
->defaultRb
, panel
->instRb
);
1204 selectedBtn
= panel
->instRb
;
1206 WMSetButtonAction(panel
->instRb
, selectSpecification
, panel
);
1209 if (wwin
->wm_class
) {
1210 panel
->clsRb
= WMCreateRadioButton(panel
->specFrm
);
1211 WMMoveWidget(panel
->clsRb
, 10, 58);
1212 WMResizeWidget(panel
->clsRb
, frame_width
- (2 * 10), 20);
1213 WMSetButtonText(panel
->clsRb
, wwin
->wm_class
);
1214 WMGroupButtons(panel
->defaultRb
, panel
->clsRb
);
1217 selectedBtn
= panel
->clsRb
;
1219 WMSetButtonAction(panel
->clsRb
, selectSpecification
, panel
);
1222 panel
->selWinB
= WMCreateCommandButton(panel
->specFrm
);
1223 WMMoveWidget(panel
->selWinB
, 20, 145 - 24 - 10);
1224 WMResizeWidget(panel
->selWinB
, frame_width
- 2 * 10 - 20, 24);
1225 WMSetButtonText(panel
->selWinB
, _("Select window"));
1226 WMSetButtonAction(panel
->selWinB
, selectWindow
, panel
);
1228 panel
->specLbl
= WMCreateLabel(panel
->win
);
1229 WMMoveWidget(panel
->specLbl
, 15, 210);
1230 WMResizeWidget(panel
->specLbl
, frame_width
, 100);
1231 WMSetLabelText(panel
->specLbl
, spec_text
);
1232 WMSetLabelWraps(panel
->specLbl
, True
);
1234 WMSetLabelTextAlignment(panel
->specLbl
, WALeft
);
1236 /**** attributes ****/
1237 panel
->attrFrm
= WMCreateFrame(panel
->win
);
1238 WMSetFrameTitle(panel
->attrFrm
, _("Attributes"));
1239 WMMoveWidget(panel
->attrFrm
, 15, 45);
1240 WMResizeWidget(panel
->attrFrm
, frame_width
, 250);
1242 for (i
= 0; i
< 11; i
++) {
1243 char *caption
= NULL
;
1249 caption
= _("Disable titlebar");
1250 flag
= WFLAGP(wwin
, no_titlebar
);
1251 descr
= _("Remove the titlebar of this window.\n"
1252 "To access the window commands menu of a window\n"
1253 "without it's titlebar, press Control+Esc (or the\n"
1254 "equivalent shortcut, if you changed the default\n" "settings).");
1257 caption
= _("Disable resizebar");
1258 flag
= WFLAGP(wwin
, no_resizebar
);
1259 descr
= _("Remove the resizebar of this window.");
1262 caption
= _("Disable close button");
1263 flag
= WFLAGP(wwin
, no_close_button
);
1264 descr
= _("Remove the `close window' button of this window.");
1267 caption
= _("Disable miniaturize button");
1268 flag
= WFLAGP(wwin
, no_miniaturize_button
);
1269 descr
= _("Remove the `miniaturize window' button of the window.");
1272 caption
= _("Disable border");
1273 flag
= WFLAGP(wwin
, no_border
);
1274 descr
= _("Remove the 1 pixel black border around the window.");
1277 caption
= _("Keep on top (floating)");
1278 flag
= WFLAGP(wwin
, floating
);
1279 descr
= _("Keep the window over other windows, not allowing\n" "them to cover it.");
1282 caption
= _("Keep at bottom (sunken)");
1283 flag
= WFLAGP(wwin
, sunken
);
1284 descr
= _("Keep the window under all other windows.");
1287 caption
= _("Omnipresent");
1288 flag
= WFLAGP(wwin
, omnipresent
);
1289 descr
= _("Make window present in all workspaces.");
1292 caption
= _("Start miniaturized");
1293 flag
= WFLAGP(wwin
, start_miniaturized
);
1294 descr
= _("Make the window be automatically miniaturized when it's\n" "first shown.");
1297 caption
= _("Start maximized");
1298 flag
= WFLAGP(wwin
, start_maximized
!= 0);
1299 descr
= _("Make the window be automatically maximized when it's\n" "first shown.");
1302 caption
= _("Full screen maximization");
1303 flag
= WFLAGP(wwin
, full_maximize
);
1304 descr
= _("Make the window use the whole screen space when it's\n"
1305 "maximized. The titlebar and resizebar will be moved\n"
1306 "to outside the screen.");
1309 panel
->attrChk
[i
] = WMCreateSwitchButton(panel
->attrFrm
);
1310 WMMoveWidget(panel
->attrChk
[i
], 10, 20 * (i
+ 1));
1311 WMResizeWidget(panel
->attrChk
[i
], frame_width
- 15, 20);
1312 WMSetButtonSelected(panel
->attrChk
[i
], flag
);
1313 WMSetButtonText(panel
->attrChk
[i
], caption
);
1315 WMSetBalloonTextForView(descr
, WMWidgetView(panel
->attrChk
[i
]));
1318 /**** more attributes ****/
1319 panel
->moreFrm
= WMCreateFrame(panel
->win
);
1320 WMSetFrameTitle(panel
->moreFrm
, _("Advanced"));
1321 WMMoveWidget(panel
->moreFrm
, 15, 45);
1322 WMResizeWidget(panel
->moreFrm
, frame_width
, 250);
1325 #ifdef XKB_BUTTON_HINT
1331 char *caption
= NULL
;
1337 caption
= _("Do not bind keyboard shortcuts");
1338 flag
= WFLAGP(wwin
, no_bind_keys
);
1339 descr
= _("Do not bind keyboard shortcuts from Window Maker\n"
1340 "when this window is focused. This will allow the\n"
1341 "window to receive all key combinations regardless\n"
1342 "of your shortcut configuration.");
1345 caption
= _("Do not bind mouse clicks");
1346 flag
= WFLAGP(wwin
, no_bind_mouse
);
1347 descr
= _("Do not bind mouse actions, such as `Alt'+drag\n"
1348 "in the window (when alt is the modifier you have\n" "configured).");
1351 caption
= _("Do not show in the window list");
1352 flag
= WFLAGP(wwin
, skip_window_list
);
1353 descr
= _("Do not list the window in the window list menu.");
1356 caption
= _("Do not let it take focus");
1357 flag
= WFLAGP(wwin
, no_focusable
);
1358 descr
= _("Do not let the window take keyboard focus when you\n" "click on it.");
1361 caption
= _("Keep inside screen");
1362 flag
= WFLAGP(wwin
, dont_move_off
);
1363 descr
= _("Do not allow the window to move itself completely\n"
1364 "outside the screen. For bug compatibility.\n");
1367 caption
= _("Ignore 'Hide Others'");
1368 flag
= WFLAGP(wwin
, no_hide_others
);
1369 descr
= _("Do not hide the window when issuing the\n" "`HideOthers' command.");
1372 caption
= _("Ignore 'Save Session'");
1373 flag
= WFLAGP(wwin
, dont_save_session
);
1374 descr
= _("Do not save the associated application in the\n"
1375 "session's state, so that it won't be restarted\n"
1376 "together with other applications when Window Maker\n" "starts.");
1379 caption
= _("Emulate application icon");
1380 flag
= WFLAGP(wwin
, emulate_appicon
);
1381 descr
= _("Make this window act as an application that provides\n"
1382 "enough information to Window Maker for a dockable\n"
1383 "application icon to be created.");
1385 #ifdef XKB_BUTTON_HINT
1387 caption
= _("Disable language button");
1388 flag
= WFLAGP(wwin
, no_language_button
);
1389 descr
= _("Remove the `toggle language' button of the window.");
1393 panel
->moreChk
[i
] = WMCreateSwitchButton(panel
->moreFrm
);
1394 WMMoveWidget(panel
->moreChk
[i
], 10, 20 * (i
+ 1));
1395 WMResizeWidget(panel
->moreChk
[i
], frame_width
- 15, 20);
1396 WMSetButtonSelected(panel
->moreChk
[i
], flag
);
1397 WMSetButtonText(panel
->moreChk
[i
], caption
);
1399 WMSetBalloonTextForView(descr
, WMWidgetView(panel
->moreChk
[i
]));
1402 /* miniwindow/workspace */
1403 panel
->iconFrm
= WMCreateFrame(panel
->win
);
1404 WMMoveWidget(panel
->iconFrm
, 15, 50);
1405 WMResizeWidget(panel
->iconFrm
, PWIDTH
- (2 * 15), 170);
1406 WMSetFrameTitle(panel
->iconFrm
, _("Miniwindow Image"));
1408 panel
->iconLbl
= WMCreateLabel(panel
->iconFrm
);
1409 WMMoveWidget(panel
->iconLbl
, PWIDTH
- (2 * 15) - 22 - 64, 20);
1410 WMResizeWidget(panel
->iconLbl
, 64, 64);
1411 WMSetLabelRelief(panel
->iconLbl
, WRGroove
);
1412 WMSetLabelImagePosition(panel
->iconLbl
, WIPImageOnly
);
1414 panel
->browseIconBtn
= WMCreateCommandButton(panel
->iconFrm
);
1415 WMSetButtonAction(panel
->browseIconBtn
, chooseIconCallback
, panel
);
1416 WMMoveWidget(panel
->browseIconBtn
, 22, 32);
1417 WMResizeWidget(panel
->browseIconBtn
, 120, 26);
1418 WMSetButtonText(panel
->browseIconBtn
, _("Browse..."));
1420 #ifdef wrong_behaviour
1421 WMSetButtonImagePosition(panel
->updateIconBtn
, WIPRight
);
1422 pixmap
= WMGetSystemPixmap(scr
->wmscreen
, WSIReturnArrow
);
1423 WMSetButtonImage(panel
->updateIconBtn
, pixmap
);
1424 WMReleasePixmap(pixmap
);
1425 pixmap
= WMGetSystemPixmap(scr
->wmscreen
, WSIHighlightedReturnArrow
);
1426 WMSetButtonAltImage(panel
->updateIconBtn
, pixmap
);
1427 WMReleasePixmap(pixmap
);
1430 panel
->fileLbl
= WMCreateLabel(panel
->iconFrm
);
1431 WMMoveWidget(panel
->fileLbl
, 20, 85);
1432 WMResizeWidget(panel
->fileLbl
, PWIDTH
- (2 * 15) - (2 * 20), 14);
1433 WMSetLabelText(panel
->fileLbl
, _("Icon filename:"));
1435 panel
->fileText
= WMCreateTextField(panel
->iconFrm
);
1436 WMMoveWidget(panel
->fileText
, 20, 105);
1437 WMResizeWidget(panel
->fileText
, PWIDTH
- (2 * 20) - (2 * 15), 20);
1438 WMSetTextFieldText(panel
->fileText
, NULL
);
1439 WMAddNotificationObserver(textEditedObserver
, panel
, WMTextDidEndEditingNotification
, panel
->fileText
);
1441 panel
->alwChk
= WMCreateSwitchButton(panel
->iconFrm
);
1442 WMMoveWidget(panel
->alwChk
, 20, 130);
1443 WMResizeWidget(panel
->alwChk
, PWIDTH
- (2 * 15) - (2 * 15), 30);
1444 WMSetButtonText(panel
->alwChk
, _("Ignore client supplied icon"));
1445 WMSetButtonSelected(panel
->alwChk
, WFLAGP(wwin
, always_user_icon
));
1447 panel
->wsFrm
= WMCreateFrame(panel
->win
);
1448 WMMoveWidget(panel
->wsFrm
, 15, 225);
1449 WMResizeWidget(panel
->wsFrm
, PWIDTH
- (2 * 15), 70);
1450 WMSetFrameTitle(panel
->wsFrm
, _("Initial Workspace"));
1452 WMSetBalloonTextForView(_("The workspace to place the window when it's"
1453 "first shown."), WMWidgetView(panel
->wsFrm
));
1455 panel
->wsP
= WMCreatePopUpButton(panel
->wsFrm
);
1456 WMMoveWidget(panel
->wsP
, 20, 30);
1457 WMResizeWidget(panel
->wsP
, PWIDTH
- (2 * 15) - (2 * 20), 20);
1458 WMAddPopUpButtonItem(panel
->wsP
, _("Nowhere in particular"));
1459 for (i
= 0; i
< wwin
->screen_ptr
->workspace_count
; i
++) {
1460 WMAddPopUpButtonItem(panel
->wsP
, scr
->workspaces
[i
]->name
);
1463 i
= wDefaultGetStartWorkspace(wwin
->screen_ptr
, wwin
->wm_instance
, wwin
->wm_class
);
1464 if (i
>= 0 && i
<= wwin
->screen_ptr
->workspace_count
) {
1465 WMSetPopUpButtonSelectedItem(panel
->wsP
, i
+ 1);
1467 WMSetPopUpButtonSelectedItem(panel
->wsP
, 0);
1470 /* application wide attributes */
1471 if (wwin
->main_window
!= None
) {
1472 WApplication
*wapp
= wApplicationOf(wwin
->main_window
);
1474 panel
->appFrm
= WMCreateFrame(panel
->win
);
1475 WMSetFrameTitle(panel
->appFrm
, _("Application Attributes"));
1476 WMMoveWidget(panel
->appFrm
, 15, 50);
1477 WMResizeWidget(panel
->appFrm
, frame_width
, 240);
1479 for (i
= 0; i
< 3; i
++) {
1480 char *caption
= NULL
;
1486 caption
= _("Start hidden");
1487 flag
= WFLAGP(wapp
->main_window_desc
, start_hidden
);
1488 descr
= _("Automatically hide application when it's started.");
1491 caption
= _("No application icon");
1492 flag
= WFLAGP(wapp
->main_window_desc
, no_appicon
);
1493 descr
= _("Disable the application icon for the application.\n"
1494 "Note that you won't be able to dock it anymore,\n"
1495 "and any icons that are already docked will stop\n"
1496 "working correctly.");
1499 caption
= _("Shared application icon");
1500 flag
= WFLAGP(wapp
->main_window_desc
, shared_appicon
);
1501 descr
= _("Use a single shared application icon for all of\n"
1502 "the instances of this application.\n");
1505 panel
->appChk
[i
] = WMCreateSwitchButton(panel
->appFrm
);
1506 WMMoveWidget(panel
->appChk
[i
], 10, 20 * (i
+ 1));
1507 WMResizeWidget(panel
->appChk
[i
], 205, 20);
1508 WMSetButtonSelected(panel
->appChk
[i
], flag
);
1509 WMSetButtonText(panel
->appChk
[i
], caption
);
1511 WMSetBalloonTextForView(descr
, WMWidgetView(panel
->appChk
[i
]));
1514 if (WFLAGP(wwin
, emulate_appicon
)) {
1515 WMSetButtonEnabled(panel
->appChk
[1], False
);
1516 WMSetButtonEnabled(panel
->moreChk
[7], True
);
1518 WMSetButtonEnabled(panel
->appChk
[1], True
);
1519 WMSetButtonEnabled(panel
->moreChk
[7], False
);
1524 if ((wwin
->transient_for
!= None
&& wwin
->transient_for
!= scr
->root_win
)
1525 || !wwin
->wm_class
|| !wwin
->wm_instance
)
1529 WMSetButtonEnabled(panel
->moreChk
[7], tmp
);
1531 WMSetPopUpButtonItemEnabled(panel
->pagePopUp
, 4, False
);
1532 panel
->appFrm
= NULL
;
1535 /* if the window is a transient, don't let it have a miniaturize
1537 if (wwin
->transient_for
!= None
&& wwin
->transient_for
!= scr
->root_win
)
1538 WMSetButtonEnabled(panel
->attrChk
[3], False
);
1540 WMSetButtonEnabled(panel
->attrChk
[3], True
);
1542 if (!wwin
->wm_class
&& !wwin
->wm_instance
) {
1543 WMSetPopUpButtonItemEnabled(panel
->pagePopUp
, 0, False
);
1546 WMRealizeWidget(panel
->win
);
1548 WMMapSubwidgets(panel
->win
);
1549 WMMapSubwidgets(panel
->specFrm
);
1550 WMMapSubwidgets(panel
->attrFrm
);
1551 WMMapSubwidgets(panel
->moreFrm
);
1552 WMMapSubwidgets(panel
->iconFrm
);
1553 WMMapSubwidgets(panel
->wsFrm
);
1555 WMMapSubwidgets(panel
->appFrm
);
1557 if (showSelectPanel
) {
1558 WMSetPopUpButtonSelectedItem(panel
->pagePopUp
, 0);
1559 changePage(panel
->pagePopUp
, panel
);
1561 WMSetPopUpButtonSelectedItem(panel
->pagePopUp
, 1);
1562 changePage(panel
->pagePopUp
, panel
);
1565 parent
= XCreateSimpleWindow(dpy
, scr
->root_win
, 0, 0, PWIDTH
, PHEIGHT
, 0, 0, 0);
1566 XSelectInput(dpy
, parent
, KeyPressMask
| KeyReleaseMask
);
1567 panel
->parent
= parent
;
1568 XReparentWindow(dpy
, WMWidgetXID(panel
->win
), parent
, 0, 0);
1570 WMMapWidget(panel
->win
);
1572 XSetTransientForHint(dpy
, parent
, wwin
->client_win
);
1574 if (xpos
== UNDEFINED_POS
) {
1575 x
= wwin
->frame_x
+ wwin
->frame
->core
->width
/ 2;
1576 y
= wwin
->frame_y
+ wwin
->frame
->top_width
* 2;
1577 if (y
+ PHEIGHT
> scr
->scr_height
)
1578 y
= scr
->scr_height
- PHEIGHT
- 30;
1579 if (x
+ PWIDTH
> scr
->scr_width
)
1580 x
= scr
->scr_width
- PWIDTH
;
1586 panel
->frame
= wManageInternalWindow(scr
, parent
, wwin
->client_win
, "Inspector", x
, y
, PWIDTH
, PHEIGHT
);
1589 selectedBtn
= panel
->defaultRb
;
1591 WMSetButtonSelected(selectedBtn
, True
);
1593 selectSpecification(selectedBtn
, panel
);
1595 /* kluge to know who should get the key events */
1596 panel
->frame
->client_leader
= WMWidgetXID(panel
->win
);
1598 WSETUFLAG(panel
->frame
, no_closable
, 0);
1599 WSETUFLAG(panel
->frame
, no_close_button
, 0);
1600 wWindowUpdateButtonImages(panel
->frame
);
1601 wFrameWindowShowButton(panel
->frame
->frame
, WFF_RIGHT_BUTTON
);
1602 panel
->frame
->frame
->on_click_right
= destroyInspector
;
1604 wWindowMap(panel
->frame
);
1606 showIconFor(WMWidgetScreen(panel
->alwChk
), panel
, wwin
->wm_instance
, wwin
->wm_class
, UPDATE_TEXT_FIELD
);
1611 void wShowInspectorForWindow(WWindow
* wwin
)
1613 if (wwin
->flags
.inspector_open
)
1616 WMSetBalloonEnabled(wwin
->screen_ptr
->wmscreen
, wPreferences
.help_balloon
);
1619 wwin
->flags
.inspector_open
= 1;
1620 wwin
->inspector
= createInspectorForWindow(wwin
, UNDEFINED_POS
, UNDEFINED_POS
, False
);
1623 void wHideInspectorForWindow(WWindow
* wwin
)
1625 WWindow
*pwin
= wwin
->inspector
->frame
;
1628 pwin
->flags
.hidden
= 1;
1630 wClientSetState(pwin
, IconicState
, None
);
1633 void wUnhideInspectorForWindow(WWindow
* wwin
)
1635 WWindow
*pwin
= wwin
->inspector
->frame
;
1637 pwin
->flags
.hidden
= 0;
1638 pwin
->flags
.mapped
= 1;
1639 XMapWindow(dpy
, pwin
->client_win
);
1640 XMapWindow(dpy
, pwin
->frame
->core
->window
);
1641 wClientSetState(pwin
, NormalState
, None
);
1644 WWindow
*wGetWindowOfInspectorForWindow(WWindow
* wwin
)
1646 if (wwin
->inspector
) {
1647 assert(wwin
->flags
.inspector_open
!= 0);
1649 return wwin
->inspector
->frame
;
1654 void wCloseInspectorForWindow(WWindow
* wwin
)
1656 WWindow
*pwin
= wwin
->inspector
->frame
; /* the inspector window */
1658 (*pwin
->frame
->on_click_right
) (NULL
, pwin
, NULL
);