1 /* winspector.c - window attribute inspector
3 * Window Maker window manager
5 * Copyright (c) 1997-2003 Alfredo K. Kojima
6 * Copyright (c) 1998-2003 Dan Pascu
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
26 #include <X11/Xutil.h>
32 #include "WindowMaker.h"
37 #include "workspace.h"
43 #include "application.h"
46 #include "winspector.h"
52 #include <WINGs/WUtil.h>
54 typedef struct InspectorPanel
{
55 struct InspectorPanel
*nextPtr
;
59 WWindow
*inspected
; /* the window that's being inspected */
70 WMPopUpButton
*pagePopUp
;
72 /* first page. general stuff */
84 /* second page. attributes */
87 WMButton
*attrChk
[11];
89 /* 3rd page. more attributes */
91 #ifdef XKB_BUTTON_HINT
92 WMButton
*moreChk
[11];
94 WMButton
*moreChk
[10];
97 /* 4th page. icon and workspace */
101 WMTextField
*fileText
;
104 WMButton *updateIconBtn;
106 WMButton
*browseIconBtn
;
111 /* 5th page. application wide attributes */
116 unsigned int destroyed
:1;
117 unsigned int choosingIcon
:1;
120 extern Cursor wCursor
[WCUR_LAST
];
121 extern WDDomain
*WDWindowAttributes
;
122 extern WPreferences wPreferences
;
124 static InspectorPanel
*panelList
= NULL
;
125 static WMPropList
*ANoTitlebar
= NULL
;
126 static WMPropList
*ANoResizebar
;
127 static WMPropList
*ANoMiniaturizeButton
;
128 static WMPropList
*ANoCloseButton
;
129 static WMPropList
*ANoBorder
;
130 static WMPropList
*ANoHideOthers
;
131 static WMPropList
*ANoMouseBindings
;
132 static WMPropList
*ANoKeyBindings
;
133 static WMPropList
*ANoAppIcon
;
134 static WMPropList
*AKeepOnTop
;
135 static WMPropList
*AKeepOnBottom
;
136 static WMPropList
*AOmnipresent
;
137 static WMPropList
*ASkipWindowList
;
138 static WMPropList
*ASkipSwitchPanel
;
139 static WMPropList
*AKeepInsideScreen
;
140 static WMPropList
*AUnfocusable
;
141 static WMPropList
*AFocusAcrossWorkspace
;
142 static WMPropList
*AAlwaysUserIcon
;
143 static WMPropList
*AStartMiniaturized
;
144 static WMPropList
*AStartMaximized
;
145 static WMPropList
*ADontSaveSession
;
146 static WMPropList
*AEmulateAppIcon
;
147 static WMPropList
*AFullMaximize
;
148 static WMPropList
*ASharedAppIcon
;
149 #ifdef XKB_BUTTON_HINT
150 static WMPropList
*ANoLanguageButton
;
152 static WMPropList
*AStartWorkspace
;
153 static WMPropList
*AIcon
;
155 /* application wide options */
156 static WMPropList
*AStartHidden
;
157 static WMPropList
*AnyWindow
;
158 static WMPropList
*EmptyString
;
159 static WMPropList
*Yes
, *No
;
164 static char *spec_text
;
165 static void applySettings(WMButton
* button
, InspectorPanel
* panel
);
167 #define UNDEFINED_POS 0xffffff
169 static InspectorPanel
*createInspectorForWindow(WWindow
* wwin
, int xpos
, int ypos
, Bool showSelectPanel
);
171 static void make_keys(void)
173 if (ANoTitlebar
!= NULL
)
176 AIcon
= WMCreatePLString("Icon");
177 ANoTitlebar
= WMCreatePLString("NoTitlebar");
178 ANoResizebar
= WMCreatePLString("NoResizebar");
179 ANoMiniaturizeButton
= WMCreatePLString("NoMiniaturizeButton");
180 ANoCloseButton
= WMCreatePLString("NoCloseButton");
181 ANoBorder
= WMCreatePLString("NoBorder");
182 ANoHideOthers
= WMCreatePLString("NoHideOthers");
183 ANoMouseBindings
= WMCreatePLString("NoMouseBindings");
184 ANoKeyBindings
= WMCreatePLString("NoKeyBindings");
185 ANoAppIcon
= WMCreatePLString("NoAppIcon");
186 AKeepOnTop
= WMCreatePLString("KeepOnTop");
187 AKeepOnBottom
= WMCreatePLString("KeepOnBottom");
188 AOmnipresent
= WMCreatePLString("Omnipresent");
189 ASkipWindowList
= WMCreatePLString("SkipWindowList");
190 ASkipSwitchPanel
= WMCreatePLString("SkipSwitchPanel");
191 AKeepInsideScreen
= WMCreatePLString("KeepInsideScreen");
192 AUnfocusable
= WMCreatePLString("Unfocusable");
193 AFocusAcrossWorkspace
= WMCreatePLString("FocusAcrossWorkspace");
194 AAlwaysUserIcon
= WMCreatePLString("AlwaysUserIcon");
195 AStartMiniaturized
= WMCreatePLString("StartMiniaturized");
196 AStartMaximized
= WMCreatePLString("StartMaximized");
197 AStartHidden
= WMCreatePLString("StartHidden");
198 ADontSaveSession
= WMCreatePLString("DontSaveSession");
199 AEmulateAppIcon
= WMCreatePLString("EmulateAppIcon");
200 AFullMaximize
= WMCreatePLString("FullMaximize");
201 ASharedAppIcon
= WMCreatePLString("SharedAppIcon");
202 #ifdef XKB_BUTTON_HINT
203 ANoLanguageButton
= WMCreatePLString("NoLanguageButton");
206 AStartWorkspace
= WMCreatePLString("StartWorkspace");
208 AnyWindow
= WMCreatePLString("*");
209 EmptyString
= WMCreatePLString("");
210 Yes
= WMCreatePLString("Yes");
211 No
= WMCreatePLString("No");
214 static void freeInspector(InspectorPanel
* panel
)
216 panel
->destroyed
= 1;
217 if (panel
->choosingIcon
)
220 WMDestroyWidget(panel
->win
);
222 XDestroyWindow(dpy
, panel
->parent
);
227 static void destroyInspector(WCoreWindow
* foo
, void *data
, XEvent
* event
)
229 InspectorPanel
*panel
;
233 while (panel
->frame
!= data
)
234 panel
= panel
->nextPtr
;
236 if (panelList
== panel
)
237 panelList
= panel
->nextPtr
;
240 while (tmp
->nextPtr
!= panel
) {
243 tmp
->nextPtr
= panel
->nextPtr
;
245 panel
->inspected
->flags
.inspector_open
= 0;
246 panel
->inspected
->inspector
= NULL
;
248 WMRemoveNotificationObserver(panel
);
250 wWindowUnmap(panel
->frame
);
251 wUnmanageWindow(panel
->frame
, True
, False
);
253 freeInspector(panel
);
256 void wDestroyInspectorPanels(void)
258 InspectorPanel
*panel
;
260 while (panelList
!= NULL
) {
262 panelList
= panelList
->nextPtr
;
263 wUnmanageWindow(panel
->frame
, False
, False
);
264 WMDestroyWidget(panel
->win
);
266 panel
->inspected
->flags
.inspector_open
= 0;
267 panel
->inspected
->inspector
= NULL
;
273 static void changePage(WMPopUpButton
* bPtr
, InspectorPanel
* panel
)
277 page
= WMGetPopUpButtonSelectedItem(bPtr
);
280 WMMapWidget(panel
->specFrm
);
281 WMMapWidget(panel
->specLbl
);
282 } else if (page
== 1) {
283 WMMapWidget(panel
->attrFrm
);
284 } else if (page
== 2) {
285 WMMapWidget(panel
->moreFrm
);
286 } else if (page
== 3) {
287 WMMapWidget(panel
->iconFrm
);
288 WMMapWidget(panel
->wsFrm
);
290 WMMapWidget(panel
->appFrm
);
294 WMUnmapWidget(panel
->specFrm
);
295 WMUnmapWidget(panel
->specLbl
);
298 WMUnmapWidget(panel
->attrFrm
);
300 WMUnmapWidget(panel
->moreFrm
);
302 WMUnmapWidget(panel
->iconFrm
);
303 WMUnmapWidget(panel
->wsFrm
);
305 if (page
!= 4 && panel
->appFrm
)
306 WMUnmapWidget(panel
->appFrm
);
309 #define USE_TEXT_FIELD 1
310 #define UPDATE_TEXT_FIELD 2
311 #define REVERT_TO_DEFAULT 4
313 static int showIconFor(WMScreen
* scrPtr
, InspectorPanel
* panel
, char *wm_instance
, char *wm_class
, int flags
)
315 WMPixmap
*pixmap
= (WMPixmap
*) NULL
;
316 char *file
= NULL
, *path
= NULL
;
317 char *db_icon
= NULL
;
319 if ((flags
& USE_TEXT_FIELD
) != 0) {
320 file
= WMGetTextFieldText(panel
->fileText
);
321 if (file
&& file
[0] == 0) {
326 db_icon
= wDefaultGetIconFile(panel
->inspected
->screen_ptr
, wm_instance
, wm_class
, False
);
328 file
= wstrdup(db_icon
);
330 if (db_icon
!= NULL
&& (flags
& REVERT_TO_DEFAULT
) != 0) {
332 file
= wstrdup(db_icon
);
333 flags
|= UPDATE_TEXT_FIELD
;
336 if ((flags
& UPDATE_TEXT_FIELD
) != 0) {
337 WMSetTextFieldText(panel
->fileText
, file
);
341 path
= FindImage(wPreferences
.icon_path
, file
);
345 int len
= strlen(file
) + 80;
348 snprintf(buf
, len
, _("Could not find icon \"%s\" specified for this window"), file
);
349 wMessageDialog(panel
->frame
->screen_ptr
, _("Error"), buf
, _("OK"), NULL
, NULL
);
355 pixmap
= WMCreatePixmapFromFile(scrPtr
, path
);
360 int len
= strlen(file
) + 80;
363 snprintf(buf
, len
, _("Could not open specified icon \"%s\":%s"),
364 file
, RMessageForError(RErrorCode
));
365 wMessageDialog(panel
->frame
->screen_ptr
, _("Error"), buf
, _("OK"), NULL
, NULL
);
373 WMSetLabelImage(panel
->iconLbl
, pixmap
);
375 WMReleasePixmap(pixmap
);
381 static void updateIcon(WMButton
* button
, InspectorPanel
* panel
)
383 showIconFor(WMWidgetScreen(button
), panel
, NULL
, NULL
, USE_TEXT_FIELD
);
387 static int getBool(WMPropList
* value
)
391 if (!WMIsPLString(value
)) {
394 if (!(val
= WMGetFromPLString(value
))) {
398 if ((val
[1] == '\0' && (val
[0] == 'y' || val
[0] == 'Y' || val
[0] == 'T' || val
[0] == 't' || val
[0] == '1'))
399 || (strcasecmp(val
, "YES") == 0 || strcasecmp(val
, "TRUE") == 0)) {
402 } else if ((val
[1] == '\0'
403 && (val
[0] == 'n' || val
[0] == 'N' || val
[0] == 'F' || val
[0] == 'f' || val
[0] == '0'))
404 || (strcasecmp(val
, "NO") == 0 || strcasecmp(val
, "FALSE") == 0)) {
408 wwarning(_("can't convert \"%s\" to boolean"), val
);
413 #define UPDATE_DEFAULTS 1
417 * Will insert the attribute = value; pair in window's list,
418 * if it's different from the defaults.
419 * Defaults means either defaults database, or attributes saved
420 * for the default window "*". This is to let one revert options that are
421 * global because they were saved for all windows ("*").
426 insertAttribute(WMPropList
* dict
, WMPropList
* window
, WMPropList
* attr
, WMPropList
* value
, int flags
)
428 WMPropList
*def_win
, *def_value
= NULL
;
432 if (!(flags
& UPDATE_DEFAULTS
) && dict
) {
433 if ((def_win
= WMGetFromPLDictionary(dict
, AnyWindow
)) != NULL
) {
434 def_value
= WMGetFromPLDictionary(def_win
, attr
);
438 /* If we could not find defaults in database, fall to hardcoded values.
439 * Also this is true if we save defaults for all windows
442 def_value
= ((flags
& IS_BOOLEAN
) != 0) ? No
: EmptyString
;
444 if ((flags
& IS_BOOLEAN
))
445 update
= (getBool(value
) != getBool(def_value
));
447 update
= !WMIsPropListEqualTo(value
, def_value
);
451 WMPutInPLDictionary(window
, attr
, value
);
458 static void saveSettings(WMButton
* button
, InspectorPanel
* panel
)
460 WWindow
*wwin
= panel
->inspected
;
461 WDDomain
*db
= WDWindowAttributes
;
462 WMPropList
*dict
= db
->dictionary
;
463 WMPropList
*winDic
, *appDic
, *value
, *key
, *key2
;
466 int different
= 0, different2
= 0;
468 /* Save will apply the changes and save them */
469 applySettings(panel
->applyBtn
, panel
);
471 if (WMGetButtonSelected(panel
->instRb
) != 0)
472 key
= WMCreatePLString(wwin
->wm_instance
);
473 else if (WMGetButtonSelected(panel
->clsRb
) != 0)
474 key
= WMCreatePLString(wwin
->wm_class
);
475 else if (WMGetButtonSelected(panel
->bothRb
) != 0) {
478 buffer
= StrConcatDot(wwin
->wm_instance
, wwin
->wm_class
);
479 key
= WMCreatePLString(buffer
);
481 } else if (WMGetButtonSelected(panel
->defaultRb
) != 0) {
482 key
= WMRetainPropList(AnyWindow
);
483 flags
= UPDATE_DEFAULTS
;
491 dict
= WMCreatePLDictionary(NULL
, NULL
);
493 db
->dictionary
= dict
;
495 WMReleasePropList(key
);
500 if (showIconFor(WMWidgetScreen(button
), panel
, NULL
, NULL
, USE_TEXT_FIELD
) < 0)
503 WMPLSetCaseSensitive(True
);
505 winDic
= WMCreatePLDictionary(NULL
, NULL
);
506 appDic
= WMCreatePLDictionary(NULL
, NULL
);
508 /* Update icon for window */
509 icon_file
= WMGetTextFieldText(panel
->fileText
);
511 if (icon_file
[0] != 0) {
512 value
= WMCreatePLString(icon_file
);
513 different
|= insertAttribute(dict
, winDic
, AIcon
, value
, flags
);
514 different2
|= insertAttribute(dict
, appDic
, AIcon
, value
, flags
);
515 WMReleasePropList(value
);
521 int i
= WMGetPopUpButtonSelectedItem(panel
->wsP
);
525 if (i
>= 0 && i
< panel
->frame
->screen_ptr
->workspace_count
) {
526 value
= WMCreatePLString(panel
->frame
->screen_ptr
->workspaces
[i
]->name
);
527 different
|= insertAttribute(dict
, winDic
, AStartWorkspace
, value
, flags
);
528 WMReleasePropList(value
);
534 value
= (WMGetButtonSelected(panel
->alwChk
) != 0) ? Yes
: No
;
535 different
|= insertAttribute(dict
, winDic
, AAlwaysUserIcon
, value
, flags
);
537 value
= (WMGetButtonSelected(panel
->attrChk
[0]) != 0) ? Yes
: No
;
538 different
|= insertAttribute(dict
, winDic
, ANoTitlebar
, value
, flags
);
540 value
= (WMGetButtonSelected(panel
->attrChk
[1]) != 0) ? Yes
: No
;
541 different
|= insertAttribute(dict
, winDic
, ANoResizebar
, value
, flags
);
543 value
= (WMGetButtonSelected(panel
->attrChk
[2]) != 0) ? Yes
: No
;
544 different
|= insertAttribute(dict
, winDic
, ANoCloseButton
, value
, flags
);
546 value
= (WMGetButtonSelected(panel
->attrChk
[3]) != 0) ? Yes
: No
;
547 different
|= insertAttribute(dict
, winDic
, ANoMiniaturizeButton
, value
, flags
);
549 value
= (WMGetButtonSelected(panel
->attrChk
[4]) != 0) ? Yes
: No
;
550 different
|= insertAttribute(dict
, winDic
, ANoBorder
, value
, flags
);
552 value
= (WMGetButtonSelected(panel
->attrChk
[5]) != 0) ? Yes
: No
;
553 different
|= insertAttribute(dict
, winDic
, AKeepOnTop
, value
, flags
);
555 value
= (WMGetButtonSelected(panel
->attrChk
[6]) != 0) ? Yes
: No
;
556 different
|= insertAttribute(dict
, winDic
, AKeepOnBottom
, value
, flags
);
558 value
= (WMGetButtonSelected(panel
->attrChk
[7]) != 0) ? Yes
: No
;
559 different
|= insertAttribute(dict
, winDic
, AOmnipresent
, value
, flags
);
561 value
= (WMGetButtonSelected(panel
->attrChk
[8]) != 0) ? Yes
: No
;
562 different
|= insertAttribute(dict
, winDic
, AStartMiniaturized
, value
, flags
);
564 value
= (WMGetButtonSelected(panel
->attrChk
[9]) != 0) ? Yes
: No
;
565 different
|= insertAttribute(dict
, winDic
, AStartMaximized
, value
, flags
);
567 value
= (WMGetButtonSelected(panel
->attrChk
[10]) != 0) ? Yes
: No
;
568 different
|= insertAttribute(dict
, winDic
, AFullMaximize
, value
, flags
);
570 value
= (WMGetButtonSelected(panel
->moreChk
[0]) != 0) ? Yes
: No
;
571 different
|= insertAttribute(dict
, winDic
, ANoKeyBindings
, value
, flags
);
573 value
= (WMGetButtonSelected(panel
->moreChk
[1]) != 0) ? Yes
: No
;
574 different
|= insertAttribute(dict
, winDic
, ANoMouseBindings
, value
, flags
);
576 value
= (WMGetButtonSelected(panel
->moreChk
[2]) != 0) ? Yes
: No
;
577 different
|= insertAttribute(dict
, winDic
, ASkipWindowList
, value
, flags
);
579 value
= (WMGetButtonSelected(panel
->moreChk
[3]) != 0) ? Yes
: No
;
580 different
|= insertAttribute(dict
, winDic
, ASkipSwitchPanel
, value
, flags
);
582 value
= (WMGetButtonSelected(panel
->moreChk
[4]) != 0) ? Yes
: No
;
583 different
|= insertAttribute(dict
, winDic
, AUnfocusable
, value
, flags
);
585 value
= (WMGetButtonSelected(panel
->moreChk
[5]) != 0) ? Yes
: No
;
586 different
|= insertAttribute(dict
, winDic
, AKeepInsideScreen
, value
, flags
);
588 value
= (WMGetButtonSelected(panel
->moreChk
[6]) != 0) ? Yes
: No
;
589 different
|= insertAttribute(dict
, winDic
, ANoHideOthers
, value
, flags
);
591 value
= (WMGetButtonSelected(panel
->moreChk
[7]) != 0) ? Yes
: No
;
592 different
|= insertAttribute(dict
, winDic
, ADontSaveSession
, value
, flags
);
594 value
= (WMGetButtonSelected(panel
->moreChk
[8]) != 0) ? Yes
: No
;
595 different
|= insertAttribute(dict
, winDic
, AEmulateAppIcon
, value
, flags
);
597 value
= (WMGetButtonSelected(panel
->moreChk
[9]) != 0) ? Yes
: No
;
598 different
|= insertAttribute(dict
, winDic
, AFocusAcrossWorkspace
, value
, flags
);
600 #ifdef XKB_BUTTON_HINT
601 value
= (WMGetButtonSelected(panel
->moreChk
[10]) != 0) ? Yes
: No
;
602 different
|= insertAttribute(dict
, winDic
, ANoLanguageButton
, value
, flags
);
605 if (wwin
->main_window
!= None
&& wApplicationOf(wwin
->main_window
) != NULL
) {
606 value
= (WMGetButtonSelected(panel
->appChk
[0]) != 0) ? Yes
: No
;
607 different2
|= insertAttribute(dict
, appDic
, AStartHidden
, value
, flags
);
609 value
= (WMGetButtonSelected(panel
->appChk
[1]) != 0) ? Yes
: No
;
610 different2
|= insertAttribute(dict
, appDic
, ANoAppIcon
, value
, flags
);
612 value
= (WMGetButtonSelected(panel
->appChk
[2]) != 0) ? Yes
: No
;
613 different2
|= insertAttribute(dict
, appDic
, ASharedAppIcon
, value
, flags
);
616 if (wwin
->fake_group
) {
617 key2
= WMCreatePLString(wwin
->fake_group
->identifier
);
618 if (WMIsPropListEqualTo(key
, key2
)) {
619 WMMergePLDictionaries(winDic
, appDic
, True
);
620 different
|= different2
;
622 WMRemoveFromPLDictionary(dict
, key2
);
624 WMPutInPLDictionary(dict
, key2
, appDic
);
627 WMReleasePropList(key2
);
628 WMReleasePropList(appDic
);
629 } else if (wwin
->main_window
!= wwin
->client_win
) {
630 WApplication
*wapp
= wApplicationOf(wwin
->main_window
);
633 char *instance
= wapp
->main_window_desc
->wm_instance
;
634 char *class = wapp
->main_window_desc
->wm_class
;
637 buffer
= StrConcatDot(instance
, class);
638 key2
= WMCreatePLString(buffer
);
641 if (WMIsPropListEqualTo(key
, key2
)) {
642 WMMergePLDictionaries(winDic
, appDic
, True
);
643 different
|= different2
;
645 WMRemoveFromPLDictionary(dict
, key2
);
647 WMPutInPLDictionary(dict
, key2
, appDic
);
650 WMReleasePropList(key2
);
651 WMReleasePropList(appDic
);
654 WMMergePLDictionaries(winDic
, appDic
, True
);
655 different
|= different2
;
656 WMReleasePropList(appDic
);
659 WMRemoveFromPLDictionary(dict
, key
);
661 WMPutInPLDictionary(dict
, key
, winDic
);
664 WMReleasePropList(key
);
665 WMReleasePropList(winDic
);
667 UpdateDomainFile(db
);
670 WMPLSetCaseSensitive(False
);
673 static void makeAppIconFor(WApplication
* wapp
)
675 WScreen
*scr
= wapp
->main_window_desc
->screen_ptr
;
680 if (!WFLAGP(wapp
->main_window_desc
, no_appicon
))
681 wapp
->app_icon
= wAppIconCreate(wapp
->main_window_desc
);
683 wapp
->app_icon
= NULL
;
685 if (wapp
->app_icon
) {
686 WIcon
*icon
= wapp
->app_icon
->icon
;
687 WDock
*clip
= scr
->workspaces
[scr
->current_workspace
]->clip
;
690 wapp
->app_icon
->main_window
= wapp
->main_window
;
692 if (clip
&& clip
->attract_icons
&& wDockFindFreeSlot(clip
, &x
, &y
)) {
693 wapp
->app_icon
->attracted
= 1;
694 if (!wapp
->app_icon
->icon
->shadowed
) {
695 wapp
->app_icon
->icon
->shadowed
= 1;
696 wapp
->app_icon
->icon
->force_paint
= 1;
698 wDockAttachIcon(clip
, wapp
->app_icon
, x
, y
);
700 PlaceIcon(scr
, &x
, &y
, wGetHeadForWindow(wapp
->main_window_desc
));
701 wAppIconMove(wapp
->app_icon
, x
, y
);
703 if (!clip
|| !wapp
->app_icon
->attracted
|| !clip
->collapsed
)
704 XMapWindow(dpy
, icon
->core
->window
);
706 if (wPreferences
.auto_arrange_icons
&& !wapp
->app_icon
->attracted
)
707 wArrangeIcons(wapp
->main_window_desc
->screen_ptr
, True
);
711 static void removeAppIconFor(WApplication
* wapp
)
716 if (wapp
->app_icon
->docked
&& !wapp
->app_icon
->attracted
) {
717 wapp
->app_icon
->running
= 0;
718 /* since we keep it, we don't care if it was attracted or not */
719 wapp
->app_icon
->attracted
= 0;
720 wapp
->app_icon
->icon
->shadowed
= 0;
721 wapp
->app_icon
->main_window
= None
;
722 wapp
->app_icon
->pid
= 0;
723 wapp
->app_icon
->icon
->owner
= NULL
;
724 wapp
->app_icon
->icon
->icon_win
= None
;
725 wapp
->app_icon
->icon
->force_paint
= 1;
726 wAppIconPaint(wapp
->app_icon
);
727 } else if (wapp
->app_icon
->docked
) {
728 wapp
->app_icon
->running
= 0;
729 wDockDetach(wapp
->app_icon
->dock
, wapp
->app_icon
);
731 wAppIconDestroy(wapp
->app_icon
);
733 wapp
->app_icon
= NULL
;
734 if (wPreferences
.auto_arrange_icons
)
735 wArrangeIcons(wapp
->main_window_desc
->screen_ptr
, True
);
738 static void applySettings(WMButton
* button
, InspectorPanel
* panel
)
740 WWindow
*wwin
= panel
->inspected
;
741 WApplication
*wapp
= wApplicationOf(wwin
->main_window
);
742 int floating
, sunken
, skip_window_list
;
744 int old_no_bind_keys
;
745 int old_no_bind_mouse
;
747 old_omnipresent
= WFLAGP(wwin
, omnipresent
);
748 old_no_bind_keys
= WFLAGP(wwin
, no_bind_keys
);
749 old_no_bind_mouse
= WFLAGP(wwin
, no_bind_mouse
);
751 showIconFor(WMWidgetScreen(button
), panel
, NULL
, NULL
, USE_TEXT_FIELD
);
753 /* Attributes... --> Window Attributes */
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 /* Attributes... --> Advanced Options */
767 WSETUFLAG(wwin
, no_bind_keys
, WMGetButtonSelected(panel
->moreChk
[0]));
768 WSETUFLAG(wwin
, no_bind_mouse
, WMGetButtonSelected(panel
->moreChk
[1]));
769 skip_window_list
= WMGetButtonSelected(panel
->moreChk
[2]);
770 WSETUFLAG(wwin
, skip_switchpanel
, WMGetButtonSelected(panel
->moreChk
[3]));
771 WSETUFLAG(wwin
, no_focusable
, WMGetButtonSelected(panel
->moreChk
[4]));
772 WSETUFLAG(wwin
, dont_move_off
, WMGetButtonSelected(panel
->moreChk
[5]));
773 WSETUFLAG(wwin
, no_hide_others
, WMGetButtonSelected(panel
->moreChk
[6]));
774 WSETUFLAG(wwin
, dont_save_session
, WMGetButtonSelected(panel
->moreChk
[7]));
775 WSETUFLAG(wwin
, emulate_appicon
, WMGetButtonSelected(panel
->moreChk
[8]));
776 WSETUFLAG(wwin
, focus_across_wksp
, WMGetButtonSelected(panel
->moreChk
[9]));
777 #ifdef XKB_BUTTON_HINT
778 WSETUFLAG(wwin
, no_language_button
, WMGetButtonSelected(panel
->moreChk
[10]));
780 WSETUFLAG(wwin
, always_user_icon
, WMGetButtonSelected(panel
->alwChk
));
782 if (WFLAGP(wwin
, no_titlebar
) && wwin
->flags
.shaded
)
783 wUnshadeWindow(wwin
);
785 WSETUFLAG(wwin
, no_shadeable
, WFLAGP(wwin
, no_titlebar
));
788 if (!WFLAGP(wwin
, floating
))
789 ChangeStackingLevel(wwin
->frame
->core
, WMFloatingLevel
);
791 if (!WFLAGP(wwin
, sunken
))
792 ChangeStackingLevel(wwin
->frame
->core
, WMSunkenLevel
);
794 if (WFLAGP(wwin
, floating
) || WFLAGP(wwin
, sunken
))
795 ChangeStackingLevel(wwin
->frame
->core
, WMNormalLevel
);
798 WSETUFLAG(wwin
, sunken
, sunken
);
799 WSETUFLAG(wwin
, floating
, floating
);
800 wwin
->flags
.omnipresent
= 0;
802 if (WFLAGP(wwin
, skip_window_list
) != skip_window_list
) {
803 WSETUFLAG(wwin
, skip_window_list
, skip_window_list
);
804 UpdateSwitchMenu(wwin
->screen_ptr
, wwin
, skip_window_list
? ACTION_REMOVE
: ACTION_ADD
);
806 if (WFLAGP(wwin
, omnipresent
) != old_omnipresent
) {
807 WMPostNotificationName(WMNChangedState
, wwin
, "omnipresent");
811 if (WFLAGP(wwin
, no_bind_keys
) != old_no_bind_keys
) {
812 if (WFLAGP(wwin
, no_bind_keys
)) {
813 XUngrabKey(dpy
, AnyKey
, AnyModifier
, wwin
->frame
->core
->window
);
815 wWindowSetKeyGrabs(wwin
);
819 if (WFLAGP(wwin
, no_bind_mouse
) != old_no_bind_mouse
) {
820 wWindowResetMouseGrabs(wwin
);
823 wwin
->frame
->flags
.need_texture_change
= 1;
824 wWindowConfigureBorders(wwin
);
825 wFrameWindowPaint(wwin
->frame
);
826 wNETWMUpdateActions(wwin
, False
);
829 * 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
< 11; 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
, skip_switchpanel
);
939 flag
= WFLAGP(wwin
, no_focusable
);
942 flag
= WFLAGP(wwin
, dont_move_off
);
945 flag
= WFLAGP(wwin
, no_hide_others
);
948 flag
= WFLAGP(wwin
, dont_save_session
);
951 flag
= WFLAGP(wwin
, emulate_appicon
);
954 flag
= WFLAGP(wwin
, focus_across_wksp
);
956 #ifdef XKB_BUTTON_HINT
958 flag
= WFLAGP(wwin
, no_language_button
);
962 WMSetButtonSelected(panel
->moreChk
[i
], flag
);
964 if (panel
->appFrm
&& wapp
) {
965 for (i
= 0; i
< 3; i
++) {
970 flag
= WFLAGP(wapp
->main_window_desc
, start_hidden
);
973 flag
= WFLAGP(wapp
->main_window_desc
, no_appicon
);
976 flag
= WFLAGP(wapp
->main_window_desc
, shared_appicon
);
979 WMSetButtonSelected(panel
->appChk
[i
], flag
);
982 WMSetButtonSelected(panel
->alwChk
, WFLAGP(wwin
, always_user_icon
));
984 showIconFor(WMWidgetScreen(panel
->alwChk
), panel
, wm_instance
, wm_class
, REVERT_TO_DEFAULT
);
986 n
= wDefaultGetStartWorkspace(wwin
->screen_ptr
, wm_instance
, wm_class
);
988 if (n
>= 0 && n
< wwin
->screen_ptr
->workspace_count
) {
989 WMSetPopUpButtonSelectedItem(panel
->wsP
, n
+ 1);
991 WMSetPopUpButtonSelectedItem(panel
->wsP
, 0);
994 /* must auto apply, so that there wno't be internal
995 * inconsistencies between the state in the flags and
996 * the actual state of the window */
997 applySettings(panel
->applyBtn
, panel
);
1000 static void chooseIconCallback(WMWidget
* self
, void *clientData
)
1003 InspectorPanel
*panel
= (InspectorPanel
*) clientData
;
1006 panel
->choosingIcon
= 1;
1008 WMSetButtonEnabled(panel
->browseIconBtn
, False
);
1010 result
= wIconChooserDialog(panel
->frame
->screen_ptr
, &file
,
1011 panel
->inspected
->wm_instance
, panel
->inspected
->wm_class
);
1013 panel
->choosingIcon
= 0;
1015 if (!panel
->destroyed
) { /* kluge */
1017 WMSetTextFieldText(panel
->fileText
, file
);
1018 showIconFor(WMWidgetScreen(self
), panel
, NULL
, NULL
, USE_TEXT_FIELD
);
1021 WMSetButtonEnabled(panel
->browseIconBtn
, True
);
1023 freeInspector(panel
);
1027 static void textEditedObserver(void *observerData
, WMNotification
* notification
)
1029 InspectorPanel
*panel
= (InspectorPanel
*) observerData
;
1031 if ((long)WMGetNotificationClientData(notification
) != WMReturnTextMovement
)
1034 showIconFor(WMWidgetScreen(panel
->win
), panel
, NULL
, NULL
, USE_TEXT_FIELD
);
1036 WMPerformButtonClick(panel->updateIconBtn);
1040 static void selectSpecification(WMWidget
* bPtr
, void *data
)
1042 InspectorPanel
*panel
= (InspectorPanel
*) data
;
1044 WWindow
*wwin
= panel
->inspected
;
1047 if (bPtr
== panel
->defaultRb
&& (wwin
->wm_instance
|| wwin
->wm_class
)) {
1048 WMSetButtonEnabled(panel
->applyBtn
, False
);
1050 WMSetButtonEnabled(panel
->applyBtn
, True
);
1053 len
= 16 + strlen(wwin
->wm_instance
? wwin
->wm_instance
: "?")
1054 + strlen(wwin
->wm_class
? wwin
->wm_class
: "?");
1058 snprintf(str
, len
, _("Inspecting %s.%s"),
1059 wwin
->wm_instance
? wwin
->wm_instance
: "?", wwin
->wm_class
? wwin
->wm_class
: "?");
1061 wFrameWindowChangeTitle(panel
->frame
->frame
, str
);
1066 static void selectWindow(WMWidget
* bPtr
, void *data
)
1068 InspectorPanel
*panel
= (InspectorPanel
*) data
;
1069 WWindow
*wwin
= panel
->inspected
;
1070 WScreen
*scr
= wwin
->screen_ptr
;
1074 if (XGrabPointer(dpy
, scr
->root_win
, True
,
1075 ButtonPressMask
, GrabModeAsync
, GrabModeAsync
, None
,
1076 wCursor
[WCUR_SELECT
], CurrentTime
) != GrabSuccess
) {
1077 wwarning("could not grab mouse pointer");
1081 WMSetLabelText(panel
->specLbl
, _("Click in the window you wish to inspect."));
1083 WMMaskEvent(dpy
, ButtonPressMask
, &event
);
1085 XUngrabPointer(dpy
, CurrentTime
);
1087 iwin
= wWindowFor(event
.xbutton
.subwindow
);
1089 if (iwin
&& !iwin
->flags
.internal_window
&& iwin
!= wwin
&& !iwin
->flags
.inspector_open
) {
1091 iwin
->flags
.inspector_open
= 1;
1092 iwin
->inspector
= createInspectorForWindow(iwin
,
1093 panel
->frame
->frame_x
, panel
->frame
->frame_y
, True
);
1094 wCloseInspectorForWindow(wwin
);
1096 WMSetLabelText(panel
->specLbl
, spec_text
);
1100 static InspectorPanel
*createInspectorForWindow(WWindow
* wwin
, int xpos
, int ypos
, Bool showSelectPanel
)
1102 WScreen
*scr
= wwin
->screen_ptr
;
1103 InspectorPanel
*panel
;
1107 int btn_width
, frame_width
;
1108 WMButton
*selectedBtn
= NULL
;
1109 #ifdef wrong_behaviour
1113 spec_text
= _("The configuration will apply to all\n"
1114 "windows that have their WM_CLASS\n"
1115 "property set to the above selected\n" "name, when saved.");
1117 panel
= wmalloc(sizeof(InspectorPanel
));
1118 memset(panel
, 0, sizeof(InspectorPanel
));
1120 panel
->destroyed
= 0;
1122 panel
->inspected
= wwin
;
1124 panel
->nextPtr
= panelList
;
1127 panel
->win
= WMCreateWindow(scr
->wmscreen
, "windowInspector");
1128 WMResizeWidget(panel
->win
, PWIDTH
, PHEIGHT
);
1130 /**** create common stuff ****/
1132 /* command buttons */
1133 /* (PWIDTH - (left and right margin) - (btn interval)) / 3 */
1134 btn_width
= (PWIDTH
- (2 * 15) - (2 * 10)) / 3;
1135 panel
->saveBtn
= WMCreateCommandButton(panel
->win
);
1136 WMSetButtonAction(panel
->saveBtn
, (WMAction
*) saveSettings
, panel
);
1137 WMMoveWidget(panel
->saveBtn
, (2 * (btn_width
+ 10)) + 15, 310);
1138 WMSetButtonText(panel
->saveBtn
, _("Save"));
1139 WMResizeWidget(panel
->saveBtn
, btn_width
, 28);
1140 if (wPreferences
.flags
.noupdates
|| !(wwin
->wm_class
|| wwin
->wm_instance
))
1141 WMSetButtonEnabled(panel
->saveBtn
, False
);
1143 panel
->applyBtn
= WMCreateCommandButton(panel
->win
);
1144 WMSetButtonAction(panel
->applyBtn
, (WMAction
*) applySettings
, panel
);
1145 WMMoveWidget(panel
->applyBtn
, btn_width
+ 10 + 15, 310);
1146 WMSetButtonText(panel
->applyBtn
, _("Apply"));
1147 WMResizeWidget(panel
->applyBtn
, btn_width
, 28);
1149 panel
->revertBtn
= WMCreateCommandButton(panel
->win
);
1150 WMSetButtonAction(panel
->revertBtn
, (WMAction
*) revertSettings
, panel
);
1151 WMMoveWidget(panel
->revertBtn
, 15, 310);
1152 WMSetButtonText(panel
->revertBtn
, _("Reload"));
1153 WMResizeWidget(panel
->revertBtn
, btn_width
, 28);
1155 /* page selection popup button */
1156 panel
->pagePopUp
= WMCreatePopUpButton(panel
->win
);
1157 WMSetPopUpButtonAction(panel
->pagePopUp
, (WMAction
*) changePage
, panel
);
1158 WMMoveWidget(panel
->pagePopUp
, 25, 15);
1159 WMResizeWidget(panel
->pagePopUp
, PWIDTH
- 50, 20);
1161 WMAddPopUpButtonItem(panel
->pagePopUp
, _("Window Specification"));
1162 WMAddPopUpButtonItem(panel
->pagePopUp
, _("Window Attributes"));
1163 WMAddPopUpButtonItem(panel
->pagePopUp
, _("Advanced Options"));
1164 WMAddPopUpButtonItem(panel
->pagePopUp
, _("Icon and Initial Workspace"));
1165 WMAddPopUpButtonItem(panel
->pagePopUp
, _("Application Specific"));
1167 /**** window spec ****/
1168 frame_width
= PWIDTH
- (2 * 15);
1170 panel
->specFrm
= WMCreateFrame(panel
->win
);
1171 WMSetFrameTitle(panel
->specFrm
, _("Window Specification"));
1172 WMMoveWidget(panel
->specFrm
, 15, 65);
1173 WMResizeWidget(panel
->specFrm
, frame_width
, 145);
1175 panel
->defaultRb
= WMCreateRadioButton(panel
->specFrm
);
1176 WMMoveWidget(panel
->defaultRb
, 10, 78);
1177 WMResizeWidget(panel
->defaultRb
, frame_width
- (2 * 10), 20);
1178 WMSetButtonText(panel
->defaultRb
, _("Defaults for all windows"));
1179 WMSetButtonSelected(panel
->defaultRb
, False
);
1180 WMSetButtonAction(panel
->defaultRb
, selectSpecification
, panel
);
1182 if (wwin
->wm_class
&& wwin
->wm_instance
) {
1185 tmp
= wstrconcat(wwin
->wm_instance
, ".");
1186 str
= wstrconcat(tmp
, wwin
->wm_class
);
1188 panel
->bothRb
= WMCreateRadioButton(panel
->specFrm
);
1189 WMMoveWidget(panel
->bothRb
, 10, 18);
1190 WMResizeWidget(panel
->bothRb
, frame_width
- (2 * 10), 20);
1191 WMSetButtonText(panel
->bothRb
, str
);
1194 WMGroupButtons(panel
->defaultRb
, panel
->bothRb
);
1197 selectedBtn
= panel
->bothRb
;
1199 WMSetButtonAction(panel
->bothRb
, selectSpecification
, panel
);
1202 if (wwin
->wm_instance
) {
1203 panel
->instRb
= WMCreateRadioButton(panel
->specFrm
);
1204 WMMoveWidget(panel
->instRb
, 10, 38);
1205 WMResizeWidget(panel
->instRb
, frame_width
- (2 * 10), 20);
1206 WMSetButtonText(panel
->instRb
, wwin
->wm_instance
);
1207 WMGroupButtons(panel
->defaultRb
, panel
->instRb
);
1210 selectedBtn
= panel
->instRb
;
1212 WMSetButtonAction(panel
->instRb
, selectSpecification
, panel
);
1215 if (wwin
->wm_class
) {
1216 panel
->clsRb
= WMCreateRadioButton(panel
->specFrm
);
1217 WMMoveWidget(panel
->clsRb
, 10, 58);
1218 WMResizeWidget(panel
->clsRb
, frame_width
- (2 * 10), 20);
1219 WMSetButtonText(panel
->clsRb
, wwin
->wm_class
);
1220 WMGroupButtons(panel
->defaultRb
, panel
->clsRb
);
1223 selectedBtn
= panel
->clsRb
;
1225 WMSetButtonAction(panel
->clsRb
, selectSpecification
, panel
);
1228 panel
->selWinB
= WMCreateCommandButton(panel
->specFrm
);
1229 WMMoveWidget(panel
->selWinB
, 20, 145 - 24 - 10);
1230 WMResizeWidget(panel
->selWinB
, frame_width
- 2 * 10 - 20, 24);
1231 WMSetButtonText(panel
->selWinB
, _("Select window"));
1232 WMSetButtonAction(panel
->selWinB
, selectWindow
, panel
);
1234 panel
->specLbl
= WMCreateLabel(panel
->win
);
1235 WMMoveWidget(panel
->specLbl
, 15, 210);
1236 WMResizeWidget(panel
->specLbl
, frame_width
, 100);
1237 WMSetLabelText(panel
->specLbl
, spec_text
);
1238 WMSetLabelWraps(panel
->specLbl
, True
);
1240 WMSetLabelTextAlignment(panel
->specLbl
, WALeft
);
1242 /**** attributes ****/
1243 panel
->attrFrm
= WMCreateFrame(panel
->win
);
1244 WMSetFrameTitle(panel
->attrFrm
, _("Attributes"));
1245 WMMoveWidget(panel
->attrFrm
, 15, 45);
1246 WMResizeWidget(panel
->attrFrm
, frame_width
, 250);
1248 for (i
= 0; i
< 11; i
++) {
1249 char *caption
= NULL
;
1255 caption
= _("Disable titlebar");
1256 flag
= WFLAGP(wwin
, no_titlebar
);
1257 descr
= _("Remove the titlebar of this window.\n"
1258 "To access the window commands menu of a window\n"
1259 "without it's titlebar, press Control+Esc (or the\n"
1260 "equivalent shortcut, if you changed the default\n" "settings).");
1263 caption
= _("Disable resizebar");
1264 flag
= WFLAGP(wwin
, no_resizebar
);
1265 descr
= _("Remove the resizebar of this window.");
1268 caption
= _("Disable close button");
1269 flag
= WFLAGP(wwin
, no_close_button
);
1270 descr
= _("Remove the `close window' button of this window.");
1273 caption
= _("Disable miniaturize button");
1274 flag
= WFLAGP(wwin
, no_miniaturize_button
);
1275 descr
= _("Remove the `miniaturize window' button of the window.");
1278 caption
= _("Disable border");
1279 flag
= WFLAGP(wwin
, no_border
);
1280 descr
= _("Remove the 1 pixel black border around the window.");
1283 caption
= _("Keep on top (floating)");
1284 flag
= WFLAGP(wwin
, floating
);
1285 descr
= _("Keep the window over other windows, not allowing\n" "them to cover it.");
1288 caption
= _("Keep at bottom (sunken)");
1289 flag
= WFLAGP(wwin
, sunken
);
1290 descr
= _("Keep the window under all other windows.");
1293 caption
= _("Omnipresent");
1294 flag
= WFLAGP(wwin
, omnipresent
);
1295 descr
= _("Make window present in all workspaces.");
1298 caption
= _("Start miniaturized");
1299 flag
= WFLAGP(wwin
, start_miniaturized
);
1300 descr
= _("Make the window be automatically miniaturized when it's\n" "first shown.");
1303 caption
= _("Start maximized");
1304 flag
= WFLAGP(wwin
, start_maximized
!= 0);
1305 descr
= _("Make the window be automatically maximized when it's\n" "first shown.");
1308 caption
= _("Full screen maximization");
1309 flag
= WFLAGP(wwin
, full_maximize
);
1310 descr
= _("Make the window use the whole screen space when it's\n"
1311 "maximized. The titlebar and resizebar will be moved\n"
1312 "to outside the screen.");
1315 panel
->attrChk
[i
] = WMCreateSwitchButton(panel
->attrFrm
);
1316 WMMoveWidget(panel
->attrChk
[i
], 10, 20 * (i
+ 1));
1317 WMResizeWidget(panel
->attrChk
[i
], frame_width
- 15, 20);
1318 WMSetButtonSelected(panel
->attrChk
[i
], flag
);
1319 WMSetButtonText(panel
->attrChk
[i
], caption
);
1321 WMSetBalloonTextForView(descr
, WMWidgetView(panel
->attrChk
[i
]));
1324 /**** more attributes ****/
1325 panel
->moreFrm
= WMCreateFrame(panel
->win
);
1326 WMSetFrameTitle(panel
->moreFrm
, _("Advanced"));
1327 WMMoveWidget(panel
->moreFrm
, 15, 45);
1328 WMResizeWidget(panel
->moreFrm
, frame_width
, 250);
1331 #ifdef XKB_BUTTON_HINT
1337 char *caption
= NULL
;
1343 caption
= _("Do not bind keyboard shortcuts");
1344 flag
= WFLAGP(wwin
, no_bind_keys
);
1345 descr
= _("Do not bind keyboard shortcuts from Window Maker\n"
1346 "when this window is focused. This will allow the\n"
1347 "window to receive all key combinations regardless\n"
1348 "of your shortcut configuration.");
1351 caption
= _("Do not bind mouse clicks");
1352 flag
= WFLAGP(wwin
, no_bind_mouse
);
1353 descr
= _("Do not bind mouse actions, such as `Alt'+drag\n"
1354 "in the window (when alt is the modifier you have\n" "configured).");
1357 caption
= _("Do not show in the window list");
1358 flag
= WFLAGP(wwin
, skip_window_list
);
1359 descr
= _("Do not list the window in the window list menu.");
1362 caption
= _("Do not show in the switch panel");
1363 flag
= WFLAGP(wwin
, skip_switchpanel
);
1364 descr
= _("Do not include in switchpanel while alternating windows.");
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
= _("Focus across workspaces");
1398 flag
= WFLAGP(wwin
, focus_across_wksp
);
1399 descr
= _("Allow Window Maker to switch workspace to satisfy\n"
1400 "a focus request (annoying).");
1402 #ifdef XKB_BUTTON_HINT
1404 caption
= _("Disable language button");
1405 flag
= WFLAGP(wwin
, no_language_button
);
1406 descr
= _("Remove the `toggle language' button of the window.");
1410 panel
->moreChk
[i
] = WMCreateSwitchButton(panel
->moreFrm
);
1411 WMMoveWidget(panel
->moreChk
[i
], 10, 20 * (i
+ 1));
1412 WMResizeWidget(panel
->moreChk
[i
], frame_width
- 15, 20);
1413 WMSetButtonSelected(panel
->moreChk
[i
], flag
);
1414 WMSetButtonText(panel
->moreChk
[i
], caption
);
1416 WMSetBalloonTextForView(descr
, WMWidgetView(panel
->moreChk
[i
]));
1419 /* miniwindow/workspace */
1420 panel
->iconFrm
= WMCreateFrame(panel
->win
);
1421 WMMoveWidget(panel
->iconFrm
, 15, 50);
1422 WMResizeWidget(panel
->iconFrm
, PWIDTH
- (2 * 15), 170);
1423 WMSetFrameTitle(panel
->iconFrm
, _("Miniwindow Image"));
1425 panel
->iconLbl
= WMCreateLabel(panel
->iconFrm
);
1426 WMMoveWidget(panel
->iconLbl
, PWIDTH
- (2 * 15) - 22 - 64, 20);
1427 WMResizeWidget(panel
->iconLbl
, 64, 64);
1428 WMSetLabelRelief(panel
->iconLbl
, WRGroove
);
1429 WMSetLabelImagePosition(panel
->iconLbl
, WIPImageOnly
);
1431 panel
->browseIconBtn
= WMCreateCommandButton(panel
->iconFrm
);
1432 WMSetButtonAction(panel
->browseIconBtn
, chooseIconCallback
, panel
);
1433 WMMoveWidget(panel
->browseIconBtn
, 22, 32);
1434 WMResizeWidget(panel
->browseIconBtn
, 120, 26);
1435 WMSetButtonText(panel
->browseIconBtn
, _("Browse..."));
1437 #ifdef wrong_behaviour
1438 WMSetButtonImagePosition(panel
->updateIconBtn
, WIPRight
);
1439 pixmap
= WMGetSystemPixmap(scr
->wmscreen
, WSIReturnArrow
);
1440 WMSetButtonImage(panel
->updateIconBtn
, pixmap
);
1441 WMReleasePixmap(pixmap
);
1442 pixmap
= WMGetSystemPixmap(scr
->wmscreen
, WSIHighlightedReturnArrow
);
1443 WMSetButtonAltImage(panel
->updateIconBtn
, pixmap
);
1444 WMReleasePixmap(pixmap
);
1447 panel
->fileLbl
= WMCreateLabel(panel
->iconFrm
);
1448 WMMoveWidget(panel
->fileLbl
, 20, 85);
1449 WMResizeWidget(panel
->fileLbl
, PWIDTH
- (2 * 15) - (2 * 20), 14);
1450 WMSetLabelText(panel
->fileLbl
, _("Icon filename:"));
1452 panel
->fileText
= WMCreateTextField(panel
->iconFrm
);
1453 WMMoveWidget(panel
->fileText
, 20, 105);
1454 WMResizeWidget(panel
->fileText
, PWIDTH
- (2 * 20) - (2 * 15), 20);
1455 WMSetTextFieldText(panel
->fileText
, NULL
);
1456 WMAddNotificationObserver(textEditedObserver
, panel
, WMTextDidEndEditingNotification
, panel
->fileText
);
1458 panel
->alwChk
= WMCreateSwitchButton(panel
->iconFrm
);
1459 WMMoveWidget(panel
->alwChk
, 20, 130);
1460 WMResizeWidget(panel
->alwChk
, PWIDTH
- (2 * 15) - (2 * 15), 30);
1461 WMSetButtonText(panel
->alwChk
, _("Ignore client supplied icon"));
1462 WMSetButtonSelected(panel
->alwChk
, WFLAGP(wwin
, always_user_icon
));
1464 panel
->wsFrm
= WMCreateFrame(panel
->win
);
1465 WMMoveWidget(panel
->wsFrm
, 15, 225);
1466 WMResizeWidget(panel
->wsFrm
, PWIDTH
- (2 * 15), 70);
1467 WMSetFrameTitle(panel
->wsFrm
, _("Initial Workspace"));
1469 WMSetBalloonTextForView(_("The workspace to place the window when it's"
1470 "first shown."), WMWidgetView(panel
->wsFrm
));
1472 panel
->wsP
= WMCreatePopUpButton(panel
->wsFrm
);
1473 WMMoveWidget(panel
->wsP
, 20, 30);
1474 WMResizeWidget(panel
->wsP
, PWIDTH
- (2 * 15) - (2 * 20), 20);
1475 WMAddPopUpButtonItem(panel
->wsP
, _("Nowhere in particular"));
1476 for (i
= 0; i
< wwin
->screen_ptr
->workspace_count
; i
++) {
1477 WMAddPopUpButtonItem(panel
->wsP
, scr
->workspaces
[i
]->name
);
1480 i
= wDefaultGetStartWorkspace(wwin
->screen_ptr
, wwin
->wm_instance
, wwin
->wm_class
);
1481 if (i
>= 0 && i
<= wwin
->screen_ptr
->workspace_count
) {
1482 WMSetPopUpButtonSelectedItem(panel
->wsP
, i
+ 1);
1484 WMSetPopUpButtonSelectedItem(panel
->wsP
, 0);
1487 /* application wide attributes */
1488 if (wwin
->main_window
!= None
) {
1489 WApplication
*wapp
= wApplicationOf(wwin
->main_window
);
1491 panel
->appFrm
= WMCreateFrame(panel
->win
);
1492 WMSetFrameTitle(panel
->appFrm
, _("Application Attributes"));
1493 WMMoveWidget(panel
->appFrm
, 15, 50);
1494 WMResizeWidget(panel
->appFrm
, frame_width
, 240);
1496 for (i
= 0; i
< 3; i
++) {
1497 char *caption
= NULL
;
1503 caption
= _("Start hidden");
1504 flag
= WFLAGP(wapp
->main_window_desc
, start_hidden
);
1505 descr
= _("Automatically hide application when it's started.");
1508 caption
= _("No application icon");
1509 flag
= WFLAGP(wapp
->main_window_desc
, no_appicon
);
1510 descr
= _("Disable the application icon for the application.\n"
1511 "Note that you won't be able to dock it anymore,\n"
1512 "and any icons that are already docked will stop\n"
1513 "working correctly.");
1516 caption
= _("Shared application icon");
1517 flag
= WFLAGP(wapp
->main_window_desc
, shared_appicon
);
1518 descr
= _("Use a single shared application icon for all of\n"
1519 "the instances of this application.\n");
1522 panel
->appChk
[i
] = WMCreateSwitchButton(panel
->appFrm
);
1523 WMMoveWidget(panel
->appChk
[i
], 10, 20 * (i
+ 1));
1524 WMResizeWidget(panel
->appChk
[i
], 205, 20);
1525 WMSetButtonSelected(panel
->appChk
[i
], flag
);
1526 WMSetButtonText(panel
->appChk
[i
], caption
);
1528 WMSetBalloonTextForView(descr
, WMWidgetView(panel
->appChk
[i
]));
1531 if (WFLAGP(wwin
, emulate_appicon
)) {
1532 WMSetButtonEnabled(panel
->appChk
[1], False
);
1533 WMSetButtonEnabled(panel
->moreChk
[7], True
);
1535 WMSetButtonEnabled(panel
->appChk
[1], True
);
1536 WMSetButtonEnabled(panel
->moreChk
[7], False
);
1541 if ((wwin
->transient_for
!= None
&& wwin
->transient_for
!= scr
->root_win
)
1542 || !wwin
->wm_class
|| !wwin
->wm_instance
)
1546 WMSetButtonEnabled(panel
->moreChk
[7], tmp
);
1548 WMSetPopUpButtonItemEnabled(panel
->pagePopUp
, 4, False
);
1549 panel
->appFrm
= NULL
;
1552 /* if the window is a transient, don't let it have a miniaturize
1554 if (wwin
->transient_for
!= None
&& wwin
->transient_for
!= scr
->root_win
)
1555 WMSetButtonEnabled(panel
->attrChk
[3], False
);
1557 WMSetButtonEnabled(panel
->attrChk
[3], True
);
1559 if (!wwin
->wm_class
&& !wwin
->wm_instance
) {
1560 WMSetPopUpButtonItemEnabled(panel
->pagePopUp
, 0, False
);
1563 WMRealizeWidget(panel
->win
);
1565 WMMapSubwidgets(panel
->win
);
1566 WMMapSubwidgets(panel
->specFrm
);
1567 WMMapSubwidgets(panel
->attrFrm
);
1568 WMMapSubwidgets(panel
->moreFrm
);
1569 WMMapSubwidgets(panel
->iconFrm
);
1570 WMMapSubwidgets(panel
->wsFrm
);
1572 WMMapSubwidgets(panel
->appFrm
);
1574 if (showSelectPanel
) {
1575 WMSetPopUpButtonSelectedItem(panel
->pagePopUp
, 0);
1576 changePage(panel
->pagePopUp
, panel
);
1578 WMSetPopUpButtonSelectedItem(panel
->pagePopUp
, 1);
1579 changePage(panel
->pagePopUp
, panel
);
1582 parent
= XCreateSimpleWindow(dpy
, scr
->root_win
, 0, 0, PWIDTH
, PHEIGHT
, 0, 0, 0);
1583 XSelectInput(dpy
, parent
, KeyPressMask
| KeyReleaseMask
);
1584 panel
->parent
= parent
;
1585 XReparentWindow(dpy
, WMWidgetXID(panel
->win
), parent
, 0, 0);
1587 WMMapWidget(panel
->win
);
1589 XSetTransientForHint(dpy
, parent
, wwin
->client_win
);
1591 if (xpos
== UNDEFINED_POS
) {
1592 x
= wwin
->frame_x
+ wwin
->frame
->core
->width
/ 2;
1593 y
= wwin
->frame_y
+ wwin
->frame
->top_width
* 2;
1594 if (y
+ PHEIGHT
> scr
->scr_height
)
1595 y
= scr
->scr_height
- PHEIGHT
- 30;
1596 if (x
+ PWIDTH
> scr
->scr_width
)
1597 x
= scr
->scr_width
- PWIDTH
;
1603 panel
->frame
= wManageInternalWindow(scr
, parent
, wwin
->client_win
, "Inspector", x
, y
, PWIDTH
, PHEIGHT
);
1606 selectedBtn
= panel
->defaultRb
;
1608 WMSetButtonSelected(selectedBtn
, True
);
1610 selectSpecification(selectedBtn
, panel
);
1612 /* kluge to know who should get the key events */
1613 panel
->frame
->client_leader
= WMWidgetXID(panel
->win
);
1615 WSETUFLAG(panel
->frame
, no_closable
, 0);
1616 WSETUFLAG(panel
->frame
, no_close_button
, 0);
1617 wWindowUpdateButtonImages(panel
->frame
);
1618 wFrameWindowShowButton(panel
->frame
->frame
, WFF_RIGHT_BUTTON
);
1619 panel
->frame
->frame
->on_click_right
= destroyInspector
;
1621 wWindowMap(panel
->frame
);
1623 showIconFor(WMWidgetScreen(panel
->alwChk
), panel
, wwin
->wm_instance
, wwin
->wm_class
, UPDATE_TEXT_FIELD
);
1628 void wShowInspectorForWindow(WWindow
* wwin
)
1630 if (wwin
->flags
.inspector_open
)
1633 WMSetBalloonEnabled(wwin
->screen_ptr
->wmscreen
, wPreferences
.help_balloon
);
1636 wwin
->flags
.inspector_open
= 1;
1637 wwin
->inspector
= createInspectorForWindow(wwin
, UNDEFINED_POS
, UNDEFINED_POS
, False
);
1640 void wHideInspectorForWindow(WWindow
* wwin
)
1642 WWindow
*pwin
= wwin
->inspector
->frame
;
1645 pwin
->flags
.hidden
= 1;
1647 wClientSetState(pwin
, IconicState
, None
);
1650 void wUnhideInspectorForWindow(WWindow
* wwin
)
1652 WWindow
*pwin
= wwin
->inspector
->frame
;
1654 pwin
->flags
.hidden
= 0;
1655 pwin
->flags
.mapped
= 1;
1656 XMapWindow(dpy
, pwin
->client_win
);
1657 XMapWindow(dpy
, pwin
->frame
->core
->window
);
1658 wClientSetState(pwin
, NormalState
, None
);
1661 WWindow
*wGetWindowOfInspectorForWindow(WWindow
* wwin
)
1663 if (wwin
->inspector
) {
1664 assert(wwin
->flags
.inspector_open
!= 0);
1666 return wwin
->inspector
->frame
;
1671 void wCloseInspectorForWindow(WWindow
* wwin
)
1673 WWindow
*pwin
= wwin
->inspector
->frame
; /* the inspector window */
1675 (*pwin
->frame
->on_click_right
) (NULL
, pwin
, NULL
);