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"
42 #include "application.h"
45 #include "winspector.h"
50 #include "switchmenu.h"
52 #include <WINGs/WUtil.h>
54 #define USE_TEXT_FIELD 1
55 #define UPDATE_TEXT_FIELD 2
56 #define REVERT_TO_DEFAULT 4
59 #define UNDEFINED_POS 0xffffff
60 #define UPDATE_DEFAULTS 1
63 typedef struct InspectorPanel
{
64 struct InspectorPanel
*nextPtr
;
67 WWindow
*inspected
; /* the window that's being inspected */
75 WMPopUpButton
*pagePopUp
;
77 /* first page. general stuff */
86 /* second page. attributes */
88 WMButton
*attrChk
[11];
90 /* 3rd page. more attributes */
92 #ifdef XKB_BUTTON_HINT
93 WMButton
*moreChk
[12];
95 WMButton
*moreChk
[11];
98 /* 4th page. icon and workspace */
102 WMTextField
*fileText
;
104 WMButton
*browseIconBtn
;
108 /* 5th page. application wide attributes */
113 unsigned int destroyed
:1;
114 unsigned int choosingIcon
:1;
117 static InspectorPanel
*panelList
= NULL
;
118 static WMPropList
*ANoTitlebar
= NULL
;
119 static WMPropList
*ANoResizebar
;
120 static WMPropList
*ANoMiniaturizeButton
;
121 static WMPropList
*ANoCloseButton
;
122 static WMPropList
*ANoBorder
;
123 static WMPropList
*ANoHideOthers
;
124 static WMPropList
*ANoMouseBindings
;
125 static WMPropList
*ANoKeyBindings
;
126 static WMPropList
*ANoAppIcon
;
127 static WMPropList
*AKeepOnTop
;
128 static WMPropList
*AKeepOnBottom
;
129 static WMPropList
*AOmnipresent
;
130 static WMPropList
*ASkipWindowList
;
131 static WMPropList
*ASkipSwitchPanel
;
132 static WMPropList
*AKeepInsideScreen
;
133 static WMPropList
*AUnfocusable
;
134 static WMPropList
*AFocusAcrossWorkspace
;
135 static WMPropList
*AAlwaysUserIcon
;
136 static WMPropList
*AStartMiniaturized
;
137 static WMPropList
*AStartMaximized
;
138 static WMPropList
*ADontSaveSession
;
139 static WMPropList
*AEmulateAppIcon
;
140 static WMPropList
*AFullMaximize
;
141 static WMPropList
*ASharedAppIcon
;
142 static WMPropList
*ANoMiniaturizable
;
143 #ifdef XKB_BUTTON_HINT
144 static WMPropList
*ANoLanguageButton
;
146 static WMPropList
*AStartWorkspace
;
147 static WMPropList
*AIcon
;
149 /* application wide options */
150 static WMPropList
*AStartHidden
;
151 static WMPropList
*AnyWindow
;
152 static WMPropList
*EmptyString
;
153 static WMPropList
*Yes
, *No
;
155 static char *spec_text
;
156 static void applySettings(WMWidget
*button
, void *panel
);
158 static InspectorPanel
*createInspectorForWindow(WWindow
*wwin
, int xpos
, int ypos
, Bool showSelectPanel
);
160 static void create_tab_window_attributes(WWindow
*wwin
, InspectorPanel
*panel
, int frame_width
);
161 static void create_tab_window_advanced(WWindow
*wwin
, InspectorPanel
*panel
, int frame_width
);
162 static void create_tab_icon_workspace(WWindow
*wwin
, InspectorPanel
*panel
);
163 static void create_tab_app_specific(WWindow
*wwin
, InspectorPanel
*panel
, int frame_width
);
165 static void make_keys(void)
167 if (ANoTitlebar
!= NULL
)
170 AIcon
= WMCreatePLString("Icon");
171 ANoTitlebar
= WMCreatePLString("NoTitlebar");
172 ANoResizebar
= WMCreatePLString("NoResizebar");
173 ANoMiniaturizeButton
= WMCreatePLString("NoMiniaturizeButton");
174 ANoCloseButton
= WMCreatePLString("NoCloseButton");
175 ANoBorder
= WMCreatePLString("NoBorder");
176 ANoHideOthers
= WMCreatePLString("NoHideOthers");
177 ANoMouseBindings
= WMCreatePLString("NoMouseBindings");
178 ANoKeyBindings
= WMCreatePLString("NoKeyBindings");
179 ANoAppIcon
= WMCreatePLString("NoAppIcon");
180 AKeepOnTop
= WMCreatePLString("KeepOnTop");
181 AKeepOnBottom
= WMCreatePLString("KeepOnBottom");
182 AOmnipresent
= WMCreatePLString("Omnipresent");
183 ASkipWindowList
= WMCreatePLString("SkipWindowList");
184 ASkipSwitchPanel
= WMCreatePLString("SkipSwitchPanel");
185 AKeepInsideScreen
= WMCreatePLString("KeepInsideScreen");
186 AUnfocusable
= WMCreatePLString("Unfocusable");
187 AFocusAcrossWorkspace
= WMCreatePLString("FocusAcrossWorkspace");
188 AAlwaysUserIcon
= WMCreatePLString("AlwaysUserIcon");
189 AStartMiniaturized
= WMCreatePLString("StartMiniaturized");
190 AStartMaximized
= WMCreatePLString("StartMaximized");
191 AStartHidden
= WMCreatePLString("StartHidden");
192 ADontSaveSession
= WMCreatePLString("DontSaveSession");
193 AEmulateAppIcon
= WMCreatePLString("EmulateAppIcon");
194 AFullMaximize
= WMCreatePLString("FullMaximize");
195 ASharedAppIcon
= WMCreatePLString("SharedAppIcon");
196 ANoMiniaturizable
= WMCreatePLString("NoMiniaturizable");
197 #ifdef XKB_BUTTON_HINT
198 ANoLanguageButton
= WMCreatePLString("NoLanguageButton");
201 AStartWorkspace
= WMCreatePLString("StartWorkspace");
203 AnyWindow
= WMCreatePLString("*");
204 EmptyString
= WMCreatePLString("");
205 Yes
= WMCreatePLString("Yes");
206 No
= WMCreatePLString("No");
209 static void freeInspector(InspectorPanel
*panel
)
211 panel
->destroyed
= 1;
213 if (panel
->choosingIcon
)
216 WMDestroyWidget(panel
->win
);
217 XDestroyWindow(dpy
, panel
->parent
);
221 static void destroyInspector(WCoreWindow
*foo
, void *data
, XEvent
*event
)
223 InspectorPanel
*panel
, *tmp
;
225 /* Parameter not used, but tell the compiler that it is ok */
230 while (panel
->frame
!= data
)
231 panel
= panel
->nextPtr
;
233 if (panelList
== panel
) {
234 panelList
= panel
->nextPtr
;
237 while (tmp
->nextPtr
!= panel
)
240 tmp
->nextPtr
= panel
->nextPtr
;
242 panel
->inspected
->flags
.inspector_open
= 0;
243 panel
->inspected
->inspector
= NULL
;
245 WMRemoveNotificationObserver(panel
);
247 wWindowUnmap(panel
->frame
);
248 wUnmanageWindow(panel
->frame
, True
, False
);
250 freeInspector(panel
);
253 void wDestroyInspectorPanels(void)
255 InspectorPanel
*panel
;
257 while (panelList
!= NULL
) {
259 panelList
= panelList
->nextPtr
;
260 wUnmanageWindow(panel
->frame
, False
, False
);
261 WMDestroyWidget(panel
->win
);
263 panel
->inspected
->flags
.inspector_open
= 0;
264 panel
->inspected
->inspector
= NULL
;
270 static void changePage(WMWidget
*bPtr
, void *client_data
)
272 InspectorPanel
*panel
= (InspectorPanel
*) client_data
;
275 page
= WMGetPopUpButtonSelectedItem(bPtr
);
278 WMMapWidget(panel
->specFrm
);
279 WMMapWidget(panel
->specLbl
);
280 } else if (page
== 1) {
281 WMMapWidget(panel
->attrFrm
);
282 } else if (page
== 2) {
283 WMMapWidget(panel
->moreFrm
);
284 } else if (page
== 3) {
285 WMMapWidget(panel
->iconFrm
);
286 WMMapWidget(panel
->wsFrm
);
288 WMMapWidget(panel
->appFrm
);
292 WMUnmapWidget(panel
->specFrm
);
293 WMUnmapWidget(panel
->specLbl
);
296 WMUnmapWidget(panel
->attrFrm
);
298 WMUnmapWidget(panel
->moreFrm
);
300 WMUnmapWidget(panel
->iconFrm
);
301 WMUnmapWidget(panel
->wsFrm
);
303 if (page
!= 4 && panel
->appFrm
)
304 WMUnmapWidget(panel
->appFrm
);
307 static int showIconFor(WMScreen
*scrPtr
, InspectorPanel
*panel
, const char *wm_instance
, const char *wm_class
, int flags
)
309 WMPixmap
*pixmap
= (WMPixmap
*) NULL
;
310 char *file
= NULL
, *path
= NULL
, *db_icon
= NULL
;
312 if ((flags
& USE_TEXT_FIELD
) != 0) {
313 file
= WMGetTextFieldText(panel
->fileText
);
314 if (file
&& file
[0] == 0) {
319 /* Get the application icon, default NOT included */
320 db_icon
= wDefaultGetIconFile(wm_instance
, wm_class
, False
);
322 file
= wstrdup(db_icon
);
324 if (db_icon
!= NULL
&& (flags
& REVERT_TO_DEFAULT
) != 0) {
326 file
= wstrdup(db_icon
);
327 flags
|= UPDATE_TEXT_FIELD
;
330 if ((flags
& UPDATE_TEXT_FIELD
) != 0)
331 WMSetTextFieldText(panel
->fileText
, file
);
334 path
= FindImage(wPreferences
.icon_path
, file
);
338 int len
= strlen(file
) + 80;
341 snprintf(buf
, len
, _("Could not find icon \"%s\" specified for this window"), file
);
342 wMessageDialog(panel
->frame
->screen_ptr
, _("Error"), buf
, _("OK"), NULL
, NULL
);
348 pixmap
= WMCreatePixmapFromFile(scrPtr
, path
);
353 int len
= strlen(file
) + 80;
356 snprintf(buf
, len
, _("Could not open specified icon \"%s\":%s"),
357 file
, RMessageForError(RErrorCode
));
358 wMessageDialog(panel
->frame
->screen_ptr
, _("Error"), buf
, _("OK"), NULL
, NULL
);
366 WMSetLabelImage(panel
->iconLbl
, pixmap
);
368 WMReleasePixmap(pixmap
);
373 static int getBool(WMPropList
*value
)
377 if (!WMIsPLString(value
))
380 if (!(val
= WMGetFromPLString(value
)))
383 if ((val
[1] == '\0' &&
384 (val
[0] == 'y' || val
[0] == 'Y' || val
[0] == 'T' ||
385 val
[0] == 't' || val
[0] == '1')) ||
386 (strcasecmp(val
, "YES") == 0 || strcasecmp(val
, "TRUE") == 0)) {
388 } else if ((val
[1] == '\0' &&
389 (val
[0] == 'n' || val
[0] == 'N' || val
[0] == 'F' ||
390 val
[0] == 'f' || val
[0] == '0')) ||
391 (strcasecmp(val
, "NO") == 0 || strcasecmp(val
, "FALSE") == 0)) {
394 wwarning(_("can't convert \"%s\" to boolean"), val
);
399 /* Will insert the attribute = value; pair in window's list,
400 * if it's different from the defaults.
401 * Defaults means either defaults database, or attributes saved
402 * for the default window "*". This is to let one revert options that are
403 * global because they were saved for all windows ("*"). */
405 insertAttribute(WMPropList
*dict
, WMPropList
*window
, WMPropList
*attr
, WMPropList
*value
, int flags
)
407 WMPropList
*def_win
, *def_value
= NULL
;
408 int update
= 0, modified
= 0;
410 if (!(flags
& UPDATE_DEFAULTS
) && dict
) {
411 if ((def_win
= WMGetFromPLDictionary(dict
, AnyWindow
)) != NULL
)
412 def_value
= WMGetFromPLDictionary(def_win
, attr
);
415 /* If we could not find defaults in database, fall to hardcoded values.
416 * Also this is true if we save defaults for all windows */
418 def_value
= ((flags
& IS_BOOLEAN
) != 0) ? No
: EmptyString
;
420 if (flags
& IS_BOOLEAN
)
421 update
= (getBool(value
) != getBool(def_value
));
423 update
= !WMIsPropListEqualTo(value
, def_value
);
426 WMPutInPLDictionary(window
, attr
, value
);
433 static void saveSettings(WMWidget
*button
, void *client_data
)
435 InspectorPanel
*panel
= (InspectorPanel
*) client_data
;
436 WWindow
*wwin
= panel
->inspected
;
437 WDDomain
*db
= w_global
.domain
.window_attr
;
438 WMPropList
*dict
= NULL
;
439 WMPropList
*winDic
, *appDic
, *value
, *value1
, *key
= NULL
, *key2
;
440 char *icon_file
, *buf1
, *buf2
;
441 int flags
= 0, i
= 0, different
= 0, different2
= 0;
443 /* Save will apply the changes and save them */
444 applySettings(panel
->applyBtn
, panel
);
446 if (WMGetButtonSelected(panel
->instRb
) != 0) {
447 key
= WMCreatePLString(wwin
->wm_instance
);
448 } else if (WMGetButtonSelected(panel
->clsRb
) != 0) {
449 key
= WMCreatePLString(wwin
->wm_class
);
450 } else if (WMGetButtonSelected(panel
->bothRb
) != 0) {
451 buf1
= StrConcatDot(wwin
->wm_instance
, wwin
->wm_class
);
452 key
= WMCreatePLString(buf1
);
454 } else if (WMGetButtonSelected(panel
->defaultRb
) != 0) {
455 key
= WMRetainPropList(AnyWindow
);
456 flags
= UPDATE_DEFAULTS
;
462 dict
= db
->dictionary
;
464 dict
= WMCreatePLDictionary(NULL
, NULL
);
466 db
->dictionary
= dict
;
468 WMReleasePropList(key
);
473 if (showIconFor(WMWidgetScreen(button
), panel
, NULL
, NULL
, USE_TEXT_FIELD
) < 0)
476 WMPLSetCaseSensitive(True
);
478 winDic
= WMCreatePLDictionary(NULL
, NULL
);
479 appDic
= WMCreatePLDictionary(NULL
, NULL
);
481 /* Save the icon info */
482 /* The flag "Ignore client suplied icon is not selected" */
484 snprintf(buf1
, 4, "%s", (WMGetButtonSelected(panel
->alwChk
) != 0) ? "Yes" : "No");
485 value1
= WMCreatePLString(buf1
);
486 different
|= insertAttribute(dict
, winDic
, AAlwaysUserIcon
, value1
, flags
);
487 WMReleasePropList(value1
);
490 /* The icon filename (if exists) */
491 icon_file
= WMGetTextFieldText(panel
->fileText
);
492 if ((icon_file
) && (icon_file
[0] != 0)) {
493 value
= WMCreatePLString(icon_file
);
494 different
|= insertAttribute(dict
, winDic
, AIcon
, value
, flags
);
495 different2
|= insertAttribute(dict
, appDic
, AIcon
, value
, flags
);
496 WMReleasePropList(value
);
500 i
= WMGetPopUpButtonSelectedItem(panel
->wsP
) - 1;
501 if (i
>= 0 && i
< w_global
.workspace
.count
) {
502 value
= WMCreatePLString(w_global
.workspace
.array
[i
]->name
);
503 different
|= insertAttribute(dict
, winDic
, AStartWorkspace
, value
, flags
);
504 WMReleasePropList(value
);
509 value
= (WMGetButtonSelected(panel
->attrChk
[0]) != 0) ? Yes
: No
;
510 different
|= insertAttribute(dict
, winDic
, ANoTitlebar
, value
, flags
);
512 value
= (WMGetButtonSelected(panel
->attrChk
[1]) != 0) ? Yes
: No
;
513 different
|= insertAttribute(dict
, winDic
, ANoResizebar
, value
, flags
);
515 value
= (WMGetButtonSelected(panel
->attrChk
[2]) != 0) ? Yes
: No
;
516 different
|= insertAttribute(dict
, winDic
, ANoCloseButton
, value
, flags
);
518 value
= (WMGetButtonSelected(panel
->attrChk
[3]) != 0) ? Yes
: No
;
519 different
|= insertAttribute(dict
, winDic
, ANoMiniaturizeButton
, value
, flags
);
521 value
= (WMGetButtonSelected(panel
->attrChk
[4]) != 0) ? Yes
: No
;
522 different
|= insertAttribute(dict
, winDic
, ANoBorder
, value
, flags
);
524 value
= (WMGetButtonSelected(panel
->attrChk
[5]) != 0) ? Yes
: No
;
525 different
|= insertAttribute(dict
, winDic
, AKeepOnTop
, value
, flags
);
527 value
= (WMGetButtonSelected(panel
->attrChk
[6]) != 0) ? Yes
: No
;
528 different
|= insertAttribute(dict
, winDic
, AKeepOnBottom
, value
, flags
);
530 value
= (WMGetButtonSelected(panel
->attrChk
[7]) != 0) ? Yes
: No
;
531 different
|= insertAttribute(dict
, winDic
, AOmnipresent
, value
, flags
);
533 value
= (WMGetButtonSelected(panel
->attrChk
[8]) != 0) ? Yes
: No
;
534 different
|= insertAttribute(dict
, winDic
, AStartMiniaturized
, value
, flags
);
536 value
= (WMGetButtonSelected(panel
->attrChk
[9]) != 0) ? Yes
: No
;
537 different
|= insertAttribute(dict
, winDic
, AStartMaximized
, value
, flags
);
539 value
= (WMGetButtonSelected(panel
->attrChk
[10]) != 0) ? Yes
: No
;
540 different
|= insertAttribute(dict
, winDic
, AFullMaximize
, value
, flags
);
542 value
= (WMGetButtonSelected(panel
->moreChk
[0]) != 0) ? Yes
: No
;
543 different
|= insertAttribute(dict
, winDic
, ANoKeyBindings
, value
, flags
);
545 value
= (WMGetButtonSelected(panel
->moreChk
[1]) != 0) ? Yes
: No
;
546 different
|= insertAttribute(dict
, winDic
, ANoMouseBindings
, value
, flags
);
548 value
= (WMGetButtonSelected(panel
->moreChk
[2]) != 0) ? Yes
: No
;
549 different
|= insertAttribute(dict
, winDic
, ASkipWindowList
, value
, flags
);
551 value
= (WMGetButtonSelected(panel
->moreChk
[3]) != 0) ? Yes
: No
;
552 different
|= insertAttribute(dict
, winDic
, ASkipSwitchPanel
, value
, flags
);
554 value
= (WMGetButtonSelected(panel
->moreChk
[4]) != 0) ? Yes
: No
;
555 different
|= insertAttribute(dict
, winDic
, AUnfocusable
, value
, flags
);
557 value
= (WMGetButtonSelected(panel
->moreChk
[5]) != 0) ? Yes
: No
;
558 different
|= insertAttribute(dict
, winDic
, AKeepInsideScreen
, value
, flags
);
560 value
= (WMGetButtonSelected(panel
->moreChk
[6]) != 0) ? Yes
: No
;
561 different
|= insertAttribute(dict
, winDic
, ANoHideOthers
, value
, flags
);
563 value
= (WMGetButtonSelected(panel
->moreChk
[7]) != 0) ? Yes
: No
;
564 different
|= insertAttribute(dict
, winDic
, ADontSaveSession
, value
, flags
);
566 value
= (WMGetButtonSelected(panel
->moreChk
[8]) != 0) ? Yes
: No
;
567 different
|= insertAttribute(dict
, winDic
, AEmulateAppIcon
, value
, flags
);
569 value
= (WMGetButtonSelected(panel
->moreChk
[9]) != 0) ? Yes
: No
;
570 different
|= insertAttribute(dict
, winDic
, AFocusAcrossWorkspace
, value
, flags
);
572 value
= (WMGetButtonSelected(panel
->moreChk
[10]) != 0) ? Yes
: No
;
573 different
|= insertAttribute(dict
, winDic
, ANoMiniaturizable
, value
, flags
);
575 #ifdef XKB_BUTTON_HINT
576 value
= (WMGetButtonSelected(panel
->moreChk
[11]) != 0) ? Yes
: No
;
577 different
|= insertAttribute(dict
, winDic
, ANoLanguageButton
, value
, flags
);
580 if (wwin
->main_window
!= None
&& wApplicationOf(wwin
->main_window
) != NULL
) {
581 value
= (WMGetButtonSelected(panel
->appChk
[0]) != 0) ? Yes
: No
;
582 different2
|= insertAttribute(dict
, appDic
, AStartHidden
, value
, flags
);
584 value
= (WMGetButtonSelected(panel
->appChk
[1]) != 0) ? Yes
: No
;
585 different2
|= insertAttribute(dict
, appDic
, ANoAppIcon
, value
, flags
);
587 value
= (WMGetButtonSelected(panel
->appChk
[2]) != 0) ? Yes
: No
;
588 different2
|= insertAttribute(dict
, appDic
, ASharedAppIcon
, value
, flags
);
591 if (wwin
->fake_group
) {
592 key2
= WMCreatePLString(wwin
->fake_group
->identifier
);
593 if (WMIsPropListEqualTo(key
, key2
)) {
594 WMMergePLDictionaries(winDic
, appDic
, True
);
595 different
|= different2
;
597 WMRemoveFromPLDictionary(dict
, key2
);
599 WMPutInPLDictionary(dict
, key2
, appDic
);
601 WMReleasePropList(key2
);
602 WMReleasePropList(appDic
);
603 } else if (wwin
->main_window
!= wwin
->client_win
) {
604 WApplication
*wapp
= wApplicationOf(wwin
->main_window
);
607 buf2
= StrConcatDot(wapp
->main_window_desc
->wm_instance
,
608 wapp
->main_window_desc
->wm_class
);
609 key2
= WMCreatePLString(buf2
);
612 if (WMIsPropListEqualTo(key
, key2
)) {
613 WMMergePLDictionaries(winDic
, appDic
, True
);
614 different
|= different2
;
616 WMRemoveFromPLDictionary(dict
, key2
);
618 WMPutInPLDictionary(dict
, key2
, appDic
);
620 WMReleasePropList(key2
);
621 WMReleasePropList(appDic
);
624 WMMergePLDictionaries(winDic
, appDic
, True
);
625 different
|= different2
;
626 WMReleasePropList(appDic
);
629 WMRemoveFromPLDictionary(dict
, key
);
631 WMPutInPLDictionary(dict
, key
, winDic
);
633 WMReleasePropList(key
);
634 WMReleasePropList(winDic
);
636 UpdateDomainFile(db
);
639 WMPLSetCaseSensitive(False
);
642 static void applySettings(WMWidget
*button
, void *client_data
)
644 InspectorPanel
*panel
= (InspectorPanel
*) client_data
;
645 WWindow
*wwin
= panel
->inspected
;
646 WApplication
*wapp
= wApplicationOf(wwin
->main_window
);
647 int floating
, sunken
, skip_window_list
;
648 int old_omnipresent
, old_no_bind_keys
, old_no_bind_mouse
;
650 old_omnipresent
= WFLAGP(wwin
, omnipresent
);
651 old_no_bind_keys
= WFLAGP(wwin
, no_bind_keys
);
652 old_no_bind_mouse
= WFLAGP(wwin
, no_bind_mouse
);
654 showIconFor(WMWidgetScreen(button
), panel
, NULL
, NULL
, USE_TEXT_FIELD
);
656 /* Attributes... --> Window Attributes */
657 WSETUFLAG(wwin
, no_titlebar
, WMGetButtonSelected(panel
->attrChk
[0]));
658 WSETUFLAG(wwin
, no_resizebar
, WMGetButtonSelected(panel
->attrChk
[1]));
659 WSETUFLAG(wwin
, no_close_button
, WMGetButtonSelected(panel
->attrChk
[2]));
660 WSETUFLAG(wwin
, no_miniaturize_button
, WMGetButtonSelected(panel
->attrChk
[3]));
661 WSETUFLAG(wwin
, no_border
, WMGetButtonSelected(panel
->attrChk
[4]));
662 floating
= WMGetButtonSelected(panel
->attrChk
[5]);
663 sunken
= WMGetButtonSelected(panel
->attrChk
[6]);
664 WSETUFLAG(wwin
, omnipresent
, WMGetButtonSelected(panel
->attrChk
[7]));
665 WSETUFLAG(wwin
, start_miniaturized
, WMGetButtonSelected(panel
->attrChk
[8]));
666 WSETUFLAG(wwin
, start_maximized
, WMGetButtonSelected(panel
->attrChk
[9]));
667 WSETUFLAG(wwin
, full_maximize
, WMGetButtonSelected(panel
->attrChk
[10]));
669 /* Attributes... --> Advanced Options */
670 WSETUFLAG(wwin
, no_bind_keys
, WMGetButtonSelected(panel
->moreChk
[0]));
671 WSETUFLAG(wwin
, no_bind_mouse
, WMGetButtonSelected(panel
->moreChk
[1]));
672 skip_window_list
= WMGetButtonSelected(panel
->moreChk
[2]);
673 WSETUFLAG(wwin
, skip_switchpanel
, WMGetButtonSelected(panel
->moreChk
[3]));
674 WSETUFLAG(wwin
, no_focusable
, WMGetButtonSelected(panel
->moreChk
[4]));
675 WSETUFLAG(wwin
, dont_move_off
, WMGetButtonSelected(panel
->moreChk
[5]));
676 WSETUFLAG(wwin
, no_hide_others
, WMGetButtonSelected(panel
->moreChk
[6]));
677 WSETUFLAG(wwin
, dont_save_session
, WMGetButtonSelected(panel
->moreChk
[7]));
678 WSETUFLAG(wwin
, emulate_appicon
, WMGetButtonSelected(panel
->moreChk
[8]));
679 WSETUFLAG(wwin
, focus_across_wksp
, WMGetButtonSelected(panel
->moreChk
[9]));
680 WSETUFLAG(wwin
, no_miniaturizable
, WMGetButtonSelected(panel
->moreChk
[10]));
681 #ifdef XKB_BUTTON_HINT
682 WSETUFLAG(wwin
, no_language_button
, WMGetButtonSelected(panel
->moreChk
[11]));
684 WSETUFLAG(wwin
, always_user_icon
, WMGetButtonSelected(panel
->alwChk
));
686 if (WFLAGP(wwin
, no_titlebar
) && wwin
->flags
.shaded
)
687 wUnshadeWindow(wwin
);
689 WSETUFLAG(wwin
, no_shadeable
, WFLAGP(wwin
, no_titlebar
));
692 if (!WFLAGP(wwin
, floating
))
693 ChangeStackingLevel(wwin
->frame
->core
, WMFloatingLevel
);
695 if (!WFLAGP(wwin
, sunken
))
696 ChangeStackingLevel(wwin
->frame
->core
, WMSunkenLevel
);
698 if (WFLAGP(wwin
, floating
) || WFLAGP(wwin
, sunken
))
699 ChangeStackingLevel(wwin
->frame
->core
, WMNormalLevel
);
702 WSETUFLAG(wwin
, sunken
, sunken
);
703 WSETUFLAG(wwin
, floating
, floating
);
704 wwin
->flags
.omnipresent
= 0;
706 if (WFLAGP(wwin
, skip_window_list
) != skip_window_list
) {
707 WSETUFLAG(wwin
, skip_window_list
, skip_window_list
);
708 UpdateSwitchMenu(wwin
->screen_ptr
, wwin
, skip_window_list
? ACTION_REMOVE
: ACTION_ADD
);
710 if (WFLAGP(wwin
, omnipresent
) != old_omnipresent
)
711 WMPostNotificationName(WMNChangedState
, wwin
, "omnipresent");
714 if (WFLAGP(wwin
, no_bind_keys
) != old_no_bind_keys
) {
715 if (WFLAGP(wwin
, no_bind_keys
))
716 XUngrabKey(dpy
, AnyKey
, AnyModifier
, wwin
->frame
->core
->window
);
718 wWindowSetKeyGrabs(wwin
);
721 if (WFLAGP(wwin
, no_bind_mouse
) != old_no_bind_mouse
)
722 wWindowResetMouseGrabs(wwin
);
724 wwin
->frame
->flags
.need_texture_change
= 1;
725 wWindowConfigureBorders(wwin
);
726 wFrameWindowPaint(wwin
->frame
);
727 wNETWMUpdateActions(wwin
, False
);
729 /* Can't apply emulate_appicon because it will probably cause problems. */
731 /* do application wide stuff */
732 WSETUFLAG(wapp
->main_window_desc
, start_hidden
, WMGetButtonSelected(panel
->appChk
[0]));
733 WSETUFLAG(wapp
->main_window_desc
, no_appicon
, WMGetButtonSelected(panel
->appChk
[1]));
734 WSETUFLAG(wapp
->main_window_desc
, shared_appicon
, WMGetButtonSelected(panel
->appChk
[2]));
736 if (WFLAGP(wapp
->main_window_desc
, no_appicon
))
737 unpaint_app_icon(wapp
);
739 paint_app_icon(wapp
);
741 char *file
= WMGetTextFieldText(panel
->fileText
);
747 /* If always_user_icon flag is set, but the user icon is not set
748 * we use client supplied icon and we unset the flag */
749 if ((WFLAGP(wwin
, always_user_icon
) && (!file
))) {
750 /* Show the warning */
755 snprintf(buf
, len
, _("Ignore client supplied icon is set, but icon filename textbox is empty. Using client supplied icon"));
756 wMessageDialog(panel
->frame
->screen_ptr
, _("Warning"), buf
, _("OK"), NULL
, NULL
);
760 /* Change the flags */
761 WSETUFLAG(wwin
, always_user_icon
, 0);
762 WMSetButtonSelected(panel
->alwChk
, 0);
765 /* After test the always_user_icon flag value before,
766 * the "else" block is used only if the flag is set and
767 * the icon text box has an icon path */
768 if (!WFLAGP(wwin
, always_user_icon
)) {
769 /* Change App Icon image, using the icon provided by the client */
770 if (wapp
->app_icon
) {
771 RImage
*image
= get_rimage_icon_from_wm_hints(wapp
->app_icon
->icon
);
773 set_icon_image_from_image(wapp
->app_icon
->icon
, image
);
774 update_icon_pixmap(wapp
->app_icon
->icon
);
776 wIconUpdate(wapp
->app_icon
->icon
);
780 /* Change icon image if the app is minimized,
781 * using the icon provided by the client */
783 RImage
*image
= get_rimage_icon_from_wm_hints(wwin
->icon
);
785 set_icon_image_from_image(wwin
->icon
, image
);
786 update_icon_pixmap(wwin
->icon
);
788 wIconUpdate(wwin
->icon
);
792 /* Change App Icon image */
794 wIconChangeImageFile(wapp
->app_icon
->icon
, file
);
796 /* Change icon image if the app is minimized */
798 wIconChangeImageFile(wwin
->icon
, file
);
805 wNETFrameExtents(wwin
);
808 static void revertSettings(WMWidget
*button
, void *client_data
)
810 InspectorPanel
*panel
= (InspectorPanel
*) client_data
;
811 WWindow
*wwin
= panel
->inspected
;
812 WApplication
*wapp
= wApplicationOf(wwin
->main_window
);
813 int i
, n
, workspace
, level
;
814 char *wm_instance
= NULL
, *wm_class
= NULL
;
816 /* Parameter not used, but tell the compiler that it is ok */
819 if (panel
->instRb
&& WMGetButtonSelected(panel
->instRb
) != 0)
820 wm_instance
= wwin
->wm_instance
;
821 else if (panel
->clsRb
&& WMGetButtonSelected(panel
->clsRb
) != 0)
822 wm_class
= wwin
->wm_class
;
823 else if (panel
->bothRb
&& WMGetButtonSelected(panel
->bothRb
) != 0) {
824 wm_instance
= wwin
->wm_instance
;
825 wm_class
= wwin
->wm_class
;
828 memset(&wwin
->defined_user_flags
, 0, sizeof(WWindowAttributes
));
829 memset(&wwin
->user_flags
, 0, sizeof(WWindowAttributes
));
830 memset(&wwin
->client_flags
, 0, sizeof(WWindowAttributes
));
832 wWindowSetupInitialAttributes(wwin
, &level
, &workspace
);
834 for (i
= 0; i
< (sizeof(panel
->attrChk
) / sizeof(panel
->attrChk
[0])); i
++) {
839 flag
= WFLAGP(wwin
, no_titlebar
);
842 flag
= WFLAGP(wwin
, no_resizebar
);
845 flag
= WFLAGP(wwin
, no_close_button
);
848 flag
= WFLAGP(wwin
, no_miniaturize_button
);
851 flag
= WFLAGP(wwin
, no_border
);
854 flag
= WFLAGP(wwin
, floating
);
857 flag
= WFLAGP(wwin
, sunken
);
860 flag
= WFLAGP(wwin
, omnipresent
);
863 flag
= WFLAGP(wwin
, start_miniaturized
);
866 flag
= WFLAGP(wwin
, start_maximized
!= 0);
869 flag
= WFLAGP(wwin
, full_maximize
);
872 WMSetButtonSelected(panel
->attrChk
[i
], flag
);
875 for (i
= 0; i
< (sizeof(panel
->moreChk
) / sizeof(panel
->moreChk
[0])); i
++) {
880 flag
= WFLAGP(wwin
, no_bind_keys
);
883 flag
= WFLAGP(wwin
, no_bind_mouse
);
886 flag
= WFLAGP(wwin
, skip_window_list
);
889 flag
= WFLAGP(wwin
, skip_switchpanel
);
892 flag
= WFLAGP(wwin
, no_focusable
);
895 flag
= WFLAGP(wwin
, dont_move_off
);
898 flag
= WFLAGP(wwin
, no_hide_others
);
901 flag
= WFLAGP(wwin
, dont_save_session
);
904 flag
= WFLAGP(wwin
, emulate_appicon
);
907 flag
= WFLAGP(wwin
, focus_across_wksp
);
910 flag
= WFLAGP(wwin
, no_miniaturizable
);
912 #ifdef XKB_BUTTON_HINT
914 flag
= WFLAGP(wwin
, no_language_button
);
918 WMSetButtonSelected(panel
->moreChk
[i
], flag
);
920 if (panel
->appFrm
&& wapp
) {
921 for (i
= 0; i
< (sizeof(panel
->appChk
) / sizeof(panel
->appChk
[0])); i
++) {
926 flag
= WFLAGP(wapp
->main_window_desc
, start_hidden
);
929 flag
= WFLAGP(wapp
->main_window_desc
, no_appicon
);
932 flag
= WFLAGP(wapp
->main_window_desc
, shared_appicon
);
935 WMSetButtonSelected(panel
->appChk
[i
], flag
);
938 WMSetButtonSelected(panel
->alwChk
, WFLAGP(wwin
, always_user_icon
));
940 showIconFor(WMWidgetScreen(panel
->alwChk
), panel
, wm_instance
, wm_class
, REVERT_TO_DEFAULT
);
942 n
= wDefaultGetStartWorkspace(wm_instance
, wm_class
);
944 if (n
>= 0 && n
< w_global
.workspace
.count
)
945 WMSetPopUpButtonSelectedItem(panel
->wsP
, n
+ 1);
947 WMSetPopUpButtonSelectedItem(panel
->wsP
, 0);
949 /* must auto apply, so that there wno't be internal
950 * inconsistencies between the state in the flags and
951 * the actual state of the window */
952 applySettings(panel
->applyBtn
, panel
);
955 static void chooseIconCallback(WMWidget
*self
, void *clientData
)
958 InspectorPanel
*panel
= (InspectorPanel
*) clientData
;
961 panel
->choosingIcon
= 1;
963 WMSetButtonEnabled(panel
->browseIconBtn
, False
);
965 result
= wIconChooserDialog(panel
->frame
->screen_ptr
, &file
,
966 panel
->inspected
->wm_instance
,
967 panel
->inspected
->wm_class
);
969 panel
->choosingIcon
= 0;
971 if (!panel
->destroyed
) { /* kluge */
973 WMSetTextFieldText(panel
->fileText
, file
);
974 showIconFor(WMWidgetScreen(self
), panel
, NULL
, NULL
, USE_TEXT_FIELD
);
977 WMSetButtonEnabled(panel
->browseIconBtn
, True
);
979 freeInspector(panel
);
983 static void textEditedObserver(void *observerData
, WMNotification
*notification
)
985 InspectorPanel
*panel
= (InspectorPanel
*) observerData
;
987 if ((long)WMGetNotificationClientData(notification
) != WMReturnTextMovement
)
990 showIconFor(WMWidgetScreen(panel
->win
), panel
, NULL
, NULL
, USE_TEXT_FIELD
);
993 static void selectSpecification(WMWidget
*bPtr
, void *data
)
995 InspectorPanel
*panel
= (InspectorPanel
*) data
;
997 WWindow
*wwin
= panel
->inspected
;
1000 if (bPtr
== panel
->defaultRb
&& (wwin
->wm_instance
|| wwin
->wm_class
))
1001 WMSetButtonEnabled(panel
->applyBtn
, False
);
1003 WMSetButtonEnabled(panel
->applyBtn
, True
);
1005 len
= 16 + strlen(wwin
->wm_instance
? wwin
->wm_instance
: "?")
1006 + strlen(wwin
->wm_class
? wwin
->wm_class
: "?");
1010 snprintf(str
, len
, _("Inspecting %s.%s"),
1011 wwin
->wm_instance
? wwin
->wm_instance
: "?", wwin
->wm_class
? wwin
->wm_class
: "?");
1013 wFrameWindowChangeTitle(panel
->frame
->frame
, str
);
1018 static void selectWindow(WMWidget
*bPtr
, void *data
)
1020 InspectorPanel
*panel
= (InspectorPanel
*) data
;
1021 WWindow
*wwin
= panel
->inspected
;
1022 WScreen
*scr
= wwin
->screen_ptr
;
1026 /* Parameter not used, but tell the compiler that it is ok */
1029 if (XGrabPointer(dpy
, scr
->root_win
, True
,
1030 ButtonPressMask
, GrabModeAsync
, GrabModeAsync
, None
,
1031 wPreferences
.cursor
[WCUR_SELECT
], CurrentTime
) != GrabSuccess
) {
1032 wwarning("could not grab mouse pointer");
1036 WMSetLabelText(panel
->specLbl
, _("Click in the window you wish to inspect."));
1037 WMMaskEvent(dpy
, ButtonPressMask
, &event
);
1038 XUngrabPointer(dpy
, CurrentTime
);
1040 iwin
= wWindowFor(event
.xbutton
.subwindow
);
1041 if (iwin
&& !iwin
->flags
.internal_window
&& iwin
!= wwin
&& !iwin
->flags
.inspector_open
) {
1042 iwin
->flags
.inspector_open
= 1;
1043 iwin
->inspector
= createInspectorForWindow(iwin
,
1044 panel
->frame
->frame_x
, panel
->frame
->frame_y
, True
);
1045 wCloseInspectorForWindow(wwin
);
1047 WMSetLabelText(panel
->specLbl
, spec_text
);
1051 static InspectorPanel
*createInspectorForWindow(WWindow
*wwin
, int xpos
, int ypos
, Bool showSelectPanel
)
1053 WScreen
*scr
= wwin
->screen_ptr
;
1054 InspectorPanel
*panel
;
1056 char *str
= NULL
, *tmp
= NULL
;
1057 int x
, y
, btn_width
, frame_width
;
1058 WMButton
*selectedBtn
= NULL
;
1060 spec_text
= _("The configuration will apply to all\n"
1061 "windows that have their WM_CLASS\n"
1062 "property set to the above selected\n" "name, when saved.");
1064 panel
= wmalloc(sizeof(InspectorPanel
));
1065 memset(panel
, 0, sizeof(InspectorPanel
));
1067 panel
->destroyed
= 0;
1068 panel
->inspected
= wwin
;
1069 panel
->nextPtr
= panelList
;
1071 panel
->win
= WMCreateWindow(scr
->wmscreen
, "windowInspector");
1072 WMResizeWidget(panel
->win
, PWIDTH
, PHEIGHT
);
1074 /**** create common stuff ****/
1075 /* command buttons */
1076 btn_width
= (PWIDTH
- (2 * 15) - (2 * 10)) / 3;
1077 panel
->saveBtn
= WMCreateCommandButton(panel
->win
);
1078 WMSetButtonAction(panel
->saveBtn
, saveSettings
, panel
);
1079 WMMoveWidget(panel
->saveBtn
, (2 * (btn_width
+ 10)) + 15, PHEIGHT
- 40);
1080 WMSetButtonText(panel
->saveBtn
, _("Save"));
1081 WMResizeWidget(panel
->saveBtn
, btn_width
, 28);
1082 if (wPreferences
.flags
.noupdates
|| !(wwin
->wm_class
|| wwin
->wm_instance
))
1083 WMSetButtonEnabled(panel
->saveBtn
, False
);
1085 panel
->applyBtn
= WMCreateCommandButton(panel
->win
);
1086 WMSetButtonAction(panel
->applyBtn
, applySettings
, panel
);
1087 WMMoveWidget(panel
->applyBtn
, btn_width
+ 10 + 15, PHEIGHT
- 40);
1088 WMSetButtonText(panel
->applyBtn
, _("Apply"));
1089 WMResizeWidget(panel
->applyBtn
, btn_width
, 28);
1091 panel
->revertBtn
= WMCreateCommandButton(panel
->win
);
1092 WMSetButtonAction(panel
->revertBtn
, revertSettings
, panel
);
1093 WMMoveWidget(panel
->revertBtn
, 15, PHEIGHT
- 40);
1094 WMSetButtonText(panel
->revertBtn
, _("Reload"));
1095 WMResizeWidget(panel
->revertBtn
, btn_width
, 28);
1097 /* page selection popup button */
1098 panel
->pagePopUp
= WMCreatePopUpButton(panel
->win
);
1099 WMSetPopUpButtonAction(panel
->pagePopUp
, changePage
, panel
);
1100 WMMoveWidget(panel
->pagePopUp
, 25, 15);
1101 WMResizeWidget(panel
->pagePopUp
, PWIDTH
- 50, 20);
1103 WMAddPopUpButtonItem(panel
->pagePopUp
, _("Window Specification"));
1104 WMAddPopUpButtonItem(panel
->pagePopUp
, _("Window Attributes"));
1105 WMAddPopUpButtonItem(panel
->pagePopUp
, _("Advanced Options"));
1106 WMAddPopUpButtonItem(panel
->pagePopUp
, _("Icon and Initial Workspace"));
1107 WMAddPopUpButtonItem(panel
->pagePopUp
, _("Application Specific"));
1109 /**** window spec ****/
1110 frame_width
= PWIDTH
- (2 * 15);
1112 panel
->specFrm
= WMCreateFrame(panel
->win
);
1113 WMSetFrameTitle(panel
->specFrm
, _("Window Specification"));
1114 WMMoveWidget(panel
->specFrm
, 15, 65);
1115 WMResizeWidget(panel
->specFrm
, frame_width
, 145);
1117 panel
->defaultRb
= WMCreateRadioButton(panel
->specFrm
);
1118 WMMoveWidget(panel
->defaultRb
, 10, 78);
1119 WMResizeWidget(panel
->defaultRb
, frame_width
- (2 * 10), 20);
1120 WMSetButtonText(panel
->defaultRb
, _("Defaults for all windows"));
1121 WMSetButtonSelected(panel
->defaultRb
, False
);
1122 WMSetButtonAction(panel
->defaultRb
, selectSpecification
, panel
);
1124 if (wwin
->wm_class
&& wwin
->wm_instance
) {
1125 tmp
= wstrconcat(wwin
->wm_instance
, ".");
1126 str
= wstrconcat(tmp
, wwin
->wm_class
);
1128 panel
->bothRb
= WMCreateRadioButton(panel
->specFrm
);
1129 WMMoveWidget(panel
->bothRb
, 10, 18);
1130 WMResizeWidget(panel
->bothRb
, frame_width
- (2 * 10), 20);
1131 WMSetButtonText(panel
->bothRb
, str
);
1134 WMGroupButtons(panel
->defaultRb
, panel
->bothRb
);
1137 selectedBtn
= panel
->bothRb
;
1139 WMSetButtonAction(panel
->bothRb
, selectSpecification
, panel
);
1142 if (wwin
->wm_instance
) {
1143 panel
->instRb
= WMCreateRadioButton(panel
->specFrm
);
1144 WMMoveWidget(panel
->instRb
, 10, 38);
1145 WMResizeWidget(panel
->instRb
, frame_width
- (2 * 10), 20);
1146 WMSetButtonText(panel
->instRb
, wwin
->wm_instance
);
1147 WMGroupButtons(panel
->defaultRb
, panel
->instRb
);
1150 selectedBtn
= panel
->instRb
;
1152 WMSetButtonAction(panel
->instRb
, selectSpecification
, panel
);
1155 if (wwin
->wm_class
) {
1156 panel
->clsRb
= WMCreateRadioButton(panel
->specFrm
);
1157 WMMoveWidget(panel
->clsRb
, 10, 58);
1158 WMResizeWidget(panel
->clsRb
, frame_width
- (2 * 10), 20);
1159 WMSetButtonText(panel
->clsRb
, wwin
->wm_class
);
1160 WMGroupButtons(panel
->defaultRb
, panel
->clsRb
);
1163 selectedBtn
= panel
->clsRb
;
1165 WMSetButtonAction(panel
->clsRb
, selectSpecification
, panel
);
1168 panel
->selWinB
= WMCreateCommandButton(panel
->specFrm
);
1169 WMMoveWidget(panel
->selWinB
, 20, 145 - 24 - 10);
1170 WMResizeWidget(panel
->selWinB
, frame_width
- 2 * 10 - 20, 24);
1171 WMSetButtonText(panel
->selWinB
, _("Select window"));
1172 WMSetButtonAction(panel
->selWinB
, selectWindow
, panel
);
1174 panel
->specLbl
= WMCreateLabel(panel
->win
);
1175 WMMoveWidget(panel
->specLbl
, 15, 210);
1176 WMResizeWidget(panel
->specLbl
, frame_width
, 100);
1177 WMSetLabelText(panel
->specLbl
, spec_text
);
1178 WMSetLabelWraps(panel
->specLbl
, True
);
1180 WMSetLabelTextAlignment(panel
->specLbl
, WALeft
);
1182 /**** attributes ****/
1183 create_tab_window_attributes(wwin
, panel
, frame_width
);
1184 create_tab_window_advanced(wwin
, panel
, frame_width
);
1185 create_tab_icon_workspace(wwin
, panel
);
1186 create_tab_app_specific(wwin
, panel
, frame_width
);
1188 /* if the window is a transient, don't let it have a miniaturize button */
1189 if (wwin
->transient_for
!= None
&& wwin
->transient_for
!= scr
->root_win
)
1190 WMSetButtonEnabled(panel
->attrChk
[3], False
);
1192 WMSetButtonEnabled(panel
->attrChk
[3], True
);
1194 if (!wwin
->wm_class
&& !wwin
->wm_instance
)
1195 WMSetPopUpButtonItemEnabled(panel
->pagePopUp
, 0, False
);
1197 WMRealizeWidget(panel
->win
);
1199 WMMapSubwidgets(panel
->win
);
1200 WMMapSubwidgets(panel
->specFrm
);
1201 WMMapSubwidgets(panel
->attrFrm
);
1202 WMMapSubwidgets(panel
->moreFrm
);
1203 WMMapSubwidgets(panel
->iconFrm
);
1204 WMMapSubwidgets(panel
->wsFrm
);
1206 WMMapSubwidgets(panel
->appFrm
);
1208 if (showSelectPanel
) {
1209 WMSetPopUpButtonSelectedItem(panel
->pagePopUp
, 0);
1210 changePage(panel
->pagePopUp
, panel
);
1212 WMSetPopUpButtonSelectedItem(panel
->pagePopUp
, 1);
1213 changePage(panel
->pagePopUp
, panel
);
1216 parent
= XCreateSimpleWindow(dpy
, scr
->root_win
, 0, 0, PWIDTH
, PHEIGHT
, 0, 0, 0);
1217 XSelectInput(dpy
, parent
, KeyPressMask
| KeyReleaseMask
);
1218 panel
->parent
= parent
;
1219 XReparentWindow(dpy
, WMWidgetXID(panel
->win
), parent
, 0, 0);
1221 WMMapWidget(panel
->win
);
1223 XSetTransientForHint(dpy
, parent
, wwin
->client_win
);
1225 if (xpos
== UNDEFINED_POS
) {
1226 x
= wwin
->frame_x
+ wwin
->frame
->core
->width
/ 2;
1227 y
= wwin
->frame_y
+ wwin
->frame
->top_width
* 2;
1228 if (y
+ PHEIGHT
> scr
->scr_height
)
1229 y
= scr
->scr_height
- PHEIGHT
- 30;
1230 if (x
+ PWIDTH
> scr
->scr_width
)
1231 x
= scr
->scr_width
- PWIDTH
;
1237 panel
->frame
= wManageInternalWindow(scr
, parent
, wwin
->client_win
, "Inspector", x
, y
, PWIDTH
, PHEIGHT
);
1240 selectedBtn
= panel
->defaultRb
;
1242 WMSetButtonSelected(selectedBtn
, True
);
1243 selectSpecification(selectedBtn
, panel
);
1245 /* kluge to know who should get the key events */
1246 panel
->frame
->client_leader
= WMWidgetXID(panel
->win
);
1248 WSETUFLAG(panel
->frame
, no_closable
, 0);
1249 WSETUFLAG(panel
->frame
, no_close_button
, 0);
1250 wWindowUpdateButtonImages(panel
->frame
);
1251 wFrameWindowShowButton(panel
->frame
->frame
, WFF_RIGHT_BUTTON
);
1252 panel
->frame
->frame
->on_click_right
= destroyInspector
;
1254 wWindowMap(panel
->frame
);
1256 showIconFor(WMWidgetScreen(panel
->alwChk
), panel
, wwin
->wm_instance
, wwin
->wm_class
, UPDATE_TEXT_FIELD
);
1261 void wShowInspectorForWindow(WWindow
*wwin
)
1263 if (wwin
->flags
.inspector_open
)
1266 WMSetBalloonEnabled(wwin
->screen_ptr
->wmscreen
, wPreferences
.help_balloon
);
1269 wwin
->flags
.inspector_open
= 1;
1270 wwin
->inspector
= createInspectorForWindow(wwin
, UNDEFINED_POS
, UNDEFINED_POS
, False
);
1273 void wHideInspectorForWindow(WWindow
*wwin
)
1275 WWindow
*pwin
= wwin
->inspector
->frame
;
1278 pwin
->flags
.hidden
= 1;
1280 wClientSetState(pwin
, IconicState
, None
);
1283 void wUnhideInspectorForWindow(WWindow
*wwin
)
1285 WWindow
*pwin
= wwin
->inspector
->frame
;
1287 pwin
->flags
.hidden
= 0;
1288 pwin
->flags
.mapped
= 1;
1289 XMapWindow(dpy
, pwin
->client_win
);
1290 XMapWindow(dpy
, pwin
->frame
->core
->window
);
1291 wClientSetState(pwin
, NormalState
, None
);
1294 WWindow
*wGetWindowOfInspectorForWindow(WWindow
*wwin
)
1296 if (!wwin
->inspector
)
1299 assert(wwin
->flags
.inspector_open
!= 0);
1300 return wwin
->inspector
->frame
;
1303 void wCloseInspectorForWindow(WWindow
*wwin
)
1305 WWindow
*pwin
= wwin
->inspector
->frame
; /* the inspector window */
1307 (*pwin
->frame
->on_click_right
) (NULL
, pwin
, NULL
);
1310 static void create_tab_window_attributes(WWindow
*wwin
, InspectorPanel
*panel
, int frame_width
)
1313 char *caption
= NULL
, *descr
= NULL
;
1316 panel
->attrFrm
= WMCreateFrame(panel
->win
);
1317 WMSetFrameTitle(panel
->attrFrm
, _("Attributes"));
1318 WMMoveWidget(panel
->attrFrm
, 15, 45);
1319 WMResizeWidget(panel
->attrFrm
, frame_width
, 250);
1321 for (i
= 0; i
< (sizeof(panel
->attrChk
) / sizeof(panel
->attrChk
[0])); i
++) {
1324 caption
= _("Disable titlebar");
1325 flag
= WFLAGP(wwin
, no_titlebar
);
1326 descr
= _("Remove the titlebar of this window.\n"
1327 "To access the window commands menu of a window\n"
1328 "without it's titlebar, press Control+Esc (or the\n"
1329 "equivalent shortcut, if you changed the default\n" "settings).");
1332 caption
= _("Disable resizebar");
1333 flag
= WFLAGP(wwin
, no_resizebar
);
1334 descr
= _("Remove the resizebar of this window.");
1337 caption
= _("Disable close button");
1338 flag
= WFLAGP(wwin
, no_close_button
);
1339 descr
= _("Remove the `close window' button of this window.");
1342 caption
= _("Disable miniaturize button");
1343 flag
= WFLAGP(wwin
, no_miniaturize_button
);
1344 descr
= _("Remove the `miniaturize window' button of the window.");
1347 caption
= _("Disable border");
1348 flag
= WFLAGP(wwin
, no_border
);
1349 descr
= _("Remove the 1 pixel black border around the window.");
1352 caption
= _("Keep on top (floating)");
1353 flag
= WFLAGP(wwin
, floating
);
1354 descr
= _("Keep the window over other windows, not allowing\n" "them to cover it.");
1357 caption
= _("Keep at bottom (sunken)");
1358 flag
= WFLAGP(wwin
, sunken
);
1359 descr
= _("Keep the window under all other windows.");
1362 caption
= _("Omnipresent");
1363 flag
= WFLAGP(wwin
, omnipresent
);
1364 descr
= _("Make window present in all workspaces.");
1367 caption
= _("Start miniaturized");
1368 flag
= WFLAGP(wwin
, start_miniaturized
);
1369 descr
= _("Make the window be automatically miniaturized when it's\n" "first shown.");
1372 caption
= _("Start maximized");
1373 flag
= WFLAGP(wwin
, start_maximized
!= 0);
1374 descr
= _("Make the window be automatically maximized when it's\n" "first shown.");
1377 caption
= _("Full screen maximization");
1378 flag
= WFLAGP(wwin
, full_maximize
);
1379 descr
= _("Make the window use the whole screen space when it's\n"
1380 "maximized. The titlebar and resizebar will be moved\n"
1381 "to outside the screen.");
1384 panel
->attrChk
[i
] = WMCreateSwitchButton(panel
->attrFrm
);
1385 WMMoveWidget(panel
->attrChk
[i
], 10, 20 * (i
+ 1));
1386 WMResizeWidget(panel
->attrChk
[i
], frame_width
- 15, 20);
1387 WMSetButtonSelected(panel
->attrChk
[i
], flag
);
1388 WMSetButtonText(panel
->attrChk
[i
], caption
);
1390 WMSetBalloonTextForView(descr
, WMWidgetView(panel
->attrChk
[i
]));
1394 static void create_tab_window_advanced(WWindow
*wwin
, InspectorPanel
*panel
, int frame_width
)
1397 char *caption
= NULL
, *descr
= NULL
;
1400 panel
->moreFrm
= WMCreateFrame(panel
->win
);
1401 WMSetFrameTitle(panel
->moreFrm
, _("Advanced"));
1402 WMMoveWidget(panel
->moreFrm
, 15, 45);
1403 WMResizeWidget(panel
->moreFrm
, frame_width
, 265);
1405 for (i
= 0; i
< (sizeof(panel
->moreChk
) / sizeof(panel
->moreChk
[0])); i
++) {
1408 caption
= _("Do not bind keyboard shortcuts");
1409 flag
= WFLAGP(wwin
, no_bind_keys
);
1410 descr
= _("Do not bind keyboard shortcuts from Window Maker\n"
1411 "when this window is focused. This will allow the\n"
1412 "window to receive all key combinations regardless\n"
1413 "of your shortcut configuration.");
1416 caption
= _("Do not bind mouse clicks");
1417 flag
= WFLAGP(wwin
, no_bind_mouse
);
1418 descr
= _("Do not bind mouse actions, such as `Alt'+drag\n"
1419 "in the window (when alt is the modifier you have\n" "configured).");
1422 caption
= _("Do not show in the window list");
1423 flag
= WFLAGP(wwin
, skip_window_list
);
1424 descr
= _("Do not list the window in the window list menu.");
1427 caption
= _("Do not show in the switch panel");
1428 flag
= WFLAGP(wwin
, skip_switchpanel
);
1429 descr
= _("Do not include in switchpanel while alternating windows.");
1432 caption
= _("Do not let it take focus");
1433 flag
= WFLAGP(wwin
, no_focusable
);
1434 descr
= _("Do not let the window take keyboard focus when you\n" "click on it.");
1437 caption
= _("Keep inside screen");
1438 flag
= WFLAGP(wwin
, dont_move_off
);
1439 descr
= _("Do not allow the window to move itself completely\n"
1440 "outside the screen. For bug compatibility.\n");
1443 caption
= _("Ignore 'Hide Others'");
1444 flag
= WFLAGP(wwin
, no_hide_others
);
1445 descr
= _("Do not hide the window when issuing the\n" "`HideOthers' command.");
1448 caption
= _("Ignore 'Save Session'");
1449 flag
= WFLAGP(wwin
, dont_save_session
);
1450 descr
= _("Do not save the associated application in the\n"
1451 "session's state, so that it won't be restarted\n"
1452 "together with other applications when Window Maker\n" "starts.");
1455 caption
= _("Emulate application icon");
1456 flag
= WFLAGP(wwin
, emulate_appicon
);
1457 descr
= _("Make this window act as an application that provides\n"
1458 "enough information to Window Maker for a dockable\n"
1459 "application icon to be created.");
1462 caption
= _("Focus across workspaces");
1463 flag
= WFLAGP(wwin
, focus_across_wksp
);
1464 descr
= _("Allow Window Maker to switch workspace to satisfy\n"
1465 "a focus request (annoying).");
1468 caption
= _("Do not let it be minimized");
1469 flag
= WFLAGP(wwin
, no_miniaturizable
);
1470 descr
= _("Do not let the window of this application be\n"
1473 #ifdef XKB_BUTTON_HINT
1475 caption
= _("Disable language button");
1476 flag
= WFLAGP(wwin
, no_language_button
);
1477 descr
= _("Remove the `toggle language' button of the window.");
1481 panel
->moreChk
[i
] = WMCreateSwitchButton(panel
->moreFrm
);
1482 WMMoveWidget(panel
->moreChk
[i
], 10, 20 * (i
+ 1));
1483 WMResizeWidget(panel
->moreChk
[i
], frame_width
- 15, 20);
1484 WMSetButtonSelected(panel
->moreChk
[i
], flag
);
1485 WMSetButtonText(panel
->moreChk
[i
], caption
);
1487 WMSetBalloonTextForView(descr
, WMWidgetView(panel
->moreChk
[i
]));
1491 static void create_tab_icon_workspace(WWindow
*wwin
, InspectorPanel
*panel
)
1495 /* miniwindow/workspace */
1496 panel
->iconFrm
= WMCreateFrame(panel
->win
);
1497 WMMoveWidget(panel
->iconFrm
, 15, 50);
1498 WMResizeWidget(panel
->iconFrm
, PWIDTH
- (2 * 15), 170);
1499 WMSetFrameTitle(panel
->iconFrm
, _("Miniwindow Image"));
1501 panel
->iconLbl
= WMCreateLabel(panel
->iconFrm
);
1502 WMMoveWidget(panel
->iconLbl
, PWIDTH
- (2 * 15) - 22 - 64, 20);
1503 WMResizeWidget(panel
->iconLbl
, 64, 64);
1504 WMSetLabelRelief(panel
->iconLbl
, WRGroove
);
1505 WMSetLabelImagePosition(panel
->iconLbl
, WIPImageOnly
);
1507 panel
->browseIconBtn
= WMCreateCommandButton(panel
->iconFrm
);
1508 WMSetButtonAction(panel
->browseIconBtn
, chooseIconCallback
, panel
);
1509 WMMoveWidget(panel
->browseIconBtn
, 22, 32);
1510 WMResizeWidget(panel
->browseIconBtn
, 120, 26);
1511 WMSetButtonText(panel
->browseIconBtn
, _("Browse..."));
1513 panel
->fileLbl
= WMCreateLabel(panel
->iconFrm
);
1514 WMMoveWidget(panel
->fileLbl
, 20, 85);
1515 WMResizeWidget(panel
->fileLbl
, PWIDTH
- (2 * 15) - (2 * 20), 14);
1516 WMSetLabelText(panel
->fileLbl
, _("Icon filename:"));
1518 panel
->fileText
= WMCreateTextField(panel
->iconFrm
);
1519 WMMoveWidget(panel
->fileText
, 20, 105);
1520 WMResizeWidget(panel
->fileText
, PWIDTH
- (2 * 20) - (2 * 15), 20);
1521 WMSetTextFieldText(panel
->fileText
, NULL
);
1522 WMAddNotificationObserver(textEditedObserver
, panel
, WMTextDidEndEditingNotification
, panel
->fileText
);
1524 panel
->alwChk
= WMCreateSwitchButton(panel
->iconFrm
);
1525 WMMoveWidget(panel
->alwChk
, 20, 130);
1526 WMResizeWidget(panel
->alwChk
, PWIDTH
- (2 * 15) - (2 * 15), 30);
1527 WMSetButtonText(panel
->alwChk
, _("Ignore client supplied icon"));
1528 WMSetButtonSelected(panel
->alwChk
, WFLAGP(wwin
, always_user_icon
));
1530 panel
->wsFrm
= WMCreateFrame(panel
->win
);
1531 WMMoveWidget(panel
->wsFrm
, 15, 225);
1532 WMResizeWidget(panel
->wsFrm
, PWIDTH
- (2 * 15), 70);
1533 WMSetFrameTitle(panel
->wsFrm
, _("Initial Workspace"));
1535 WMSetBalloonTextForView(_("The workspace to place the window when it's"
1536 "first shown."), WMWidgetView(panel
->wsFrm
));
1538 panel
->wsP
= WMCreatePopUpButton(panel
->wsFrm
);
1539 WMMoveWidget(panel
->wsP
, 20, 30);
1540 WMResizeWidget(panel
->wsP
, PWIDTH
- (2 * 15) - (2 * 20), 20);
1541 WMAddPopUpButtonItem(panel
->wsP
, _("Nowhere in particular"));
1543 for (i
= 0; i
< w_global
.workspace
.count
; i
++)
1544 WMAddPopUpButtonItem(panel
->wsP
, w_global
.workspace
.array
[i
]->name
);
1546 i
= wDefaultGetStartWorkspace(wwin
->wm_instance
, wwin
->wm_class
);
1547 if (i
>= 0 && i
<= w_global
.workspace
.count
)
1548 WMSetPopUpButtonSelectedItem(panel
->wsP
, i
+ 1);
1550 WMSetPopUpButtonSelectedItem(panel
->wsP
, 0);
1553 static void create_tab_app_specific(WWindow
*wwin
, InspectorPanel
*panel
, int frame_width
)
1555 WScreen
*scr
= wwin
->screen_ptr
;
1556 int i
= 0, flag
= 0, tmp
;
1557 char *caption
= NULL
, *descr
= NULL
;
1560 if (wwin
->main_window
!= None
) {
1561 WApplication
*wapp
= wApplicationOf(wwin
->main_window
);
1563 panel
->appFrm
= WMCreateFrame(panel
->win
);
1564 WMSetFrameTitle(panel
->appFrm
, _("Application Attributes"));
1565 WMMoveWidget(panel
->appFrm
, 15, 50);
1566 WMResizeWidget(panel
->appFrm
, frame_width
, 240);
1568 for (i
= 0; i
< (sizeof(panel
->appChk
) / sizeof(panel
->appChk
[0])); i
++) {
1571 caption
= _("Start hidden");
1572 flag
= WFLAGP(wapp
->main_window_desc
, start_hidden
);
1573 descr
= _("Automatically hide application when it's started.");
1576 caption
= _("No application icon");
1577 flag
= WFLAGP(wapp
->main_window_desc
, no_appicon
);
1578 descr
= _("Disable the application icon for the application.\n"
1579 "Note that you won't be able to dock it anymore,\n"
1580 "and any icons that are already docked will stop\n"
1581 "working correctly.");
1584 caption
= _("Shared application icon");
1585 flag
= WFLAGP(wapp
->main_window_desc
, shared_appicon
);
1586 descr
= _("Use a single shared application icon for all of\n"
1587 "the instances of this application.\n");
1590 panel
->appChk
[i
] = WMCreateSwitchButton(panel
->appFrm
);
1591 WMMoveWidget(panel
->appChk
[i
], 10, 20 * (i
+ 1));
1592 WMResizeWidget(panel
->appChk
[i
], 205, 20);
1593 WMSetButtonSelected(panel
->appChk
[i
], flag
);
1594 WMSetButtonText(panel
->appChk
[i
], caption
);
1595 WMSetBalloonTextForView(descr
, WMWidgetView(panel
->appChk
[i
]));
1598 if (WFLAGP(wwin
, emulate_appicon
)) {
1599 WMSetButtonEnabled(panel
->appChk
[1], False
);
1600 WMSetButtonEnabled(panel
->moreChk
[7], True
);
1602 WMSetButtonEnabled(panel
->appChk
[1], True
);
1603 WMSetButtonEnabled(panel
->moreChk
[7], False
);
1606 if ((wwin
->transient_for
!= None
&& wwin
->transient_for
!= scr
->root_win
)
1607 || !wwin
->wm_class
|| !wwin
->wm_instance
)
1612 WMSetButtonEnabled(panel
->moreChk
[7], tmp
);
1614 WMSetPopUpButtonItemEnabled(panel
->pagePopUp
, 4, False
);
1615 panel
->appFrm
= NULL
;