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(WMButton
*button
, InspectorPanel
*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
;
226 while (panel
->frame
!= data
)
227 panel
= panel
->nextPtr
;
229 if (panelList
== panel
) {
230 panelList
= panel
->nextPtr
;
233 while (tmp
->nextPtr
!= panel
)
236 tmp
->nextPtr
= panel
->nextPtr
;
238 panel
->inspected
->flags
.inspector_open
= 0;
239 panel
->inspected
->inspector
= NULL
;
241 WMRemoveNotificationObserver(panel
);
243 wWindowUnmap(panel
->frame
);
244 wUnmanageWindow(panel
->frame
, True
, False
);
246 freeInspector(panel
);
249 void wDestroyInspectorPanels(void)
251 InspectorPanel
*panel
;
253 while (panelList
!= NULL
) {
255 panelList
= panelList
->nextPtr
;
256 wUnmanageWindow(panel
->frame
, False
, False
);
257 WMDestroyWidget(panel
->win
);
259 panel
->inspected
->flags
.inspector_open
= 0;
260 panel
->inspected
->inspector
= NULL
;
266 static void changePage(WMPopUpButton
*bPtr
, InspectorPanel
*panel
)
270 page
= WMGetPopUpButtonSelectedItem(bPtr
);
273 WMMapWidget(panel
->specFrm
);
274 WMMapWidget(panel
->specLbl
);
275 } else if (page
== 1) {
276 WMMapWidget(panel
->attrFrm
);
277 } else if (page
== 2) {
278 WMMapWidget(panel
->moreFrm
);
279 } else if (page
== 3) {
280 WMMapWidget(panel
->iconFrm
);
281 WMMapWidget(panel
->wsFrm
);
283 WMMapWidget(panel
->appFrm
);
287 WMUnmapWidget(panel
->specFrm
);
288 WMUnmapWidget(panel
->specLbl
);
291 WMUnmapWidget(panel
->attrFrm
);
293 WMUnmapWidget(panel
->moreFrm
);
295 WMUnmapWidget(panel
->iconFrm
);
296 WMUnmapWidget(panel
->wsFrm
);
298 if (page
!= 4 && panel
->appFrm
)
299 WMUnmapWidget(panel
->appFrm
);
302 static int showIconFor(WMScreen
*scrPtr
, InspectorPanel
*panel
, const char *wm_instance
, const char *wm_class
, int flags
)
304 WMPixmap
*pixmap
= (WMPixmap
*) NULL
;
305 char *file
= NULL
, *path
= NULL
, *db_icon
= NULL
;
307 if ((flags
& USE_TEXT_FIELD
) != 0) {
308 file
= WMGetTextFieldText(panel
->fileText
);
309 if (file
&& file
[0] == 0) {
314 /* Get the application icon, default NOT included */
315 db_icon
= wDefaultGetIconFile(wm_instance
, wm_class
, False
);
317 file
= wstrdup(db_icon
);
319 if (db_icon
!= NULL
&& (flags
& REVERT_TO_DEFAULT
) != 0) {
321 file
= wstrdup(db_icon
);
322 flags
|= UPDATE_TEXT_FIELD
;
325 if ((flags
& UPDATE_TEXT_FIELD
) != 0)
326 WMSetTextFieldText(panel
->fileText
, file
);
329 path
= FindImage(wPreferences
.icon_path
, file
);
333 int len
= strlen(file
) + 80;
336 snprintf(buf
, len
, _("Could not find icon \"%s\" specified for this window"), file
);
337 wMessageDialog(panel
->frame
->screen_ptr
, _("Error"), buf
, _("OK"), NULL
, NULL
);
343 pixmap
= WMCreatePixmapFromFile(scrPtr
, path
);
348 int len
= strlen(file
) + 80;
351 snprintf(buf
, len
, _("Could not open specified icon \"%s\":%s"),
352 file
, RMessageForError(RErrorCode
));
353 wMessageDialog(panel
->frame
->screen_ptr
, _("Error"), buf
, _("OK"), NULL
, NULL
);
361 WMSetLabelImage(panel
->iconLbl
, pixmap
);
363 WMReleasePixmap(pixmap
);
368 static int getBool(WMPropList
*value
)
372 if (!WMIsPLString(value
))
375 if (!(val
= WMGetFromPLString(value
)))
378 if ((val
[1] == '\0' &&
379 (val
[0] == 'y' || val
[0] == 'Y' || val
[0] == 'T' ||
380 val
[0] == 't' || val
[0] == '1')) ||
381 (strcasecmp(val
, "YES") == 0 || strcasecmp(val
, "TRUE") == 0)) {
383 } else if ((val
[1] == '\0' &&
384 (val
[0] == 'n' || val
[0] == 'N' || val
[0] == 'F' ||
385 val
[0] == 'f' || val
[0] == '0')) ||
386 (strcasecmp(val
, "NO") == 0 || strcasecmp(val
, "FALSE") == 0)) {
389 wwarning(_("can't convert \"%s\" to boolean"), val
);
394 /* Will insert the attribute = value; pair in window's list,
395 * if it's different from the defaults.
396 * Defaults means either defaults database, or attributes saved
397 * for the default window "*". This is to let one revert options that are
398 * global because they were saved for all windows ("*"). */
400 insertAttribute(WMPropList
*dict
, WMPropList
*window
, WMPropList
*attr
, WMPropList
*value
, int flags
)
402 WMPropList
*def_win
, *def_value
= NULL
;
403 int update
= 0, modified
= 0;
405 if (!(flags
& UPDATE_DEFAULTS
) && dict
) {
406 if ((def_win
= WMGetFromPLDictionary(dict
, AnyWindow
)) != NULL
)
407 def_value
= WMGetFromPLDictionary(def_win
, attr
);
410 /* If we could not find defaults in database, fall to hardcoded values.
411 * Also this is true if we save defaults for all windows */
413 def_value
= ((flags
& IS_BOOLEAN
) != 0) ? No
: EmptyString
;
415 if (flags
& IS_BOOLEAN
)
416 update
= (getBool(value
) != getBool(def_value
));
418 update
= !WMIsPropListEqualTo(value
, def_value
);
421 WMPutInPLDictionary(window
, attr
, value
);
428 static void saveSettings(WMButton
*button
, InspectorPanel
*panel
)
430 WWindow
*wwin
= panel
->inspected
;
431 WDDomain
*db
= w_global
.domain
.window_attr
;
432 WMPropList
*dict
= NULL
;
433 WMPropList
*winDic
, *appDic
, *value
, *value1
, *key
= NULL
, *key2
;
434 char *icon_file
, *buf1
, *buf2
;
435 int flags
= 0, i
= 0, different
= 0, different2
= 0;
437 /* Save will apply the changes and save them */
438 applySettings(panel
->applyBtn
, panel
);
440 if (WMGetButtonSelected(panel
->instRb
) != 0) {
441 key
= WMCreatePLString(wwin
->wm_instance
);
442 } else if (WMGetButtonSelected(panel
->clsRb
) != 0) {
443 key
= WMCreatePLString(wwin
->wm_class
);
444 } else if (WMGetButtonSelected(panel
->bothRb
) != 0) {
445 buf1
= StrConcatDot(wwin
->wm_instance
, wwin
->wm_class
);
446 key
= WMCreatePLString(buf1
);
448 } else if (WMGetButtonSelected(panel
->defaultRb
) != 0) {
449 key
= WMRetainPropList(AnyWindow
);
450 flags
= UPDATE_DEFAULTS
;
456 dict
= db
->dictionary
;
458 dict
= WMCreatePLDictionary(NULL
, NULL
);
460 db
->dictionary
= dict
;
462 WMReleasePropList(key
);
467 if (showIconFor(WMWidgetScreen(button
), panel
, NULL
, NULL
, USE_TEXT_FIELD
) < 0)
470 WMPLSetCaseSensitive(True
);
472 winDic
= WMCreatePLDictionary(NULL
, NULL
);
473 appDic
= WMCreatePLDictionary(NULL
, NULL
);
475 /* Save the icon info */
476 /* The flag "Ignore client suplied icon is not selected" */
478 snprintf(buf1
, 4, "%s", (WMGetButtonSelected(panel
->alwChk
) != 0) ? "Yes" : "No");
479 value1
= WMCreatePLString(buf1
);
480 different
|= insertAttribute(dict
, winDic
, AAlwaysUserIcon
, value1
, flags
);
481 WMReleasePropList(value1
);
484 /* The icon filename (if exists) */
485 icon_file
= WMGetTextFieldText(panel
->fileText
);
486 if ((icon_file
) && (icon_file
[0] != 0)) {
487 value
= WMCreatePLString(icon_file
);
488 different
|= insertAttribute(dict
, winDic
, AIcon
, value
, flags
);
489 different2
|= insertAttribute(dict
, appDic
, AIcon
, value
, flags
);
490 WMReleasePropList(value
);
494 i
= WMGetPopUpButtonSelectedItem(panel
->wsP
) - 1;
495 if (i
>= 0 && i
< w_global
.workspace
.count
) {
496 value
= WMCreatePLString(w_global
.workspace
.array
[i
]->name
);
497 different
|= insertAttribute(dict
, winDic
, AStartWorkspace
, value
, flags
);
498 WMReleasePropList(value
);
503 value
= (WMGetButtonSelected(panel
->attrChk
[0]) != 0) ? Yes
: No
;
504 different
|= insertAttribute(dict
, winDic
, ANoTitlebar
, value
, flags
);
506 value
= (WMGetButtonSelected(panel
->attrChk
[1]) != 0) ? Yes
: No
;
507 different
|= insertAttribute(dict
, winDic
, ANoResizebar
, value
, flags
);
509 value
= (WMGetButtonSelected(panel
->attrChk
[2]) != 0) ? Yes
: No
;
510 different
|= insertAttribute(dict
, winDic
, ANoCloseButton
, value
, flags
);
512 value
= (WMGetButtonSelected(panel
->attrChk
[3]) != 0) ? Yes
: No
;
513 different
|= insertAttribute(dict
, winDic
, ANoMiniaturizeButton
, value
, flags
);
515 value
= (WMGetButtonSelected(panel
->attrChk
[4]) != 0) ? Yes
: No
;
516 different
|= insertAttribute(dict
, winDic
, ANoBorder
, value
, flags
);
518 value
= (WMGetButtonSelected(panel
->attrChk
[5]) != 0) ? Yes
: No
;
519 different
|= insertAttribute(dict
, winDic
, AKeepOnTop
, value
, flags
);
521 value
= (WMGetButtonSelected(panel
->attrChk
[6]) != 0) ? Yes
: No
;
522 different
|= insertAttribute(dict
, winDic
, AKeepOnBottom
, value
, flags
);
524 value
= (WMGetButtonSelected(panel
->attrChk
[7]) != 0) ? Yes
: No
;
525 different
|= insertAttribute(dict
, winDic
, AOmnipresent
, value
, flags
);
527 value
= (WMGetButtonSelected(panel
->attrChk
[8]) != 0) ? Yes
: No
;
528 different
|= insertAttribute(dict
, winDic
, AStartMiniaturized
, value
, flags
);
530 value
= (WMGetButtonSelected(panel
->attrChk
[9]) != 0) ? Yes
: No
;
531 different
|= insertAttribute(dict
, winDic
, AStartMaximized
, value
, flags
);
533 value
= (WMGetButtonSelected(panel
->attrChk
[10]) != 0) ? Yes
: No
;
534 different
|= insertAttribute(dict
, winDic
, AFullMaximize
, value
, flags
);
536 value
= (WMGetButtonSelected(panel
->moreChk
[0]) != 0) ? Yes
: No
;
537 different
|= insertAttribute(dict
, winDic
, ANoKeyBindings
, value
, flags
);
539 value
= (WMGetButtonSelected(panel
->moreChk
[1]) != 0) ? Yes
: No
;
540 different
|= insertAttribute(dict
, winDic
, ANoMouseBindings
, value
, flags
);
542 value
= (WMGetButtonSelected(panel
->moreChk
[2]) != 0) ? Yes
: No
;
543 different
|= insertAttribute(dict
, winDic
, ASkipWindowList
, value
, flags
);
545 value
= (WMGetButtonSelected(panel
->moreChk
[3]) != 0) ? Yes
: No
;
546 different
|= insertAttribute(dict
, winDic
, ASkipSwitchPanel
, value
, flags
);
548 value
= (WMGetButtonSelected(panel
->moreChk
[4]) != 0) ? Yes
: No
;
549 different
|= insertAttribute(dict
, winDic
, AUnfocusable
, value
, flags
);
551 value
= (WMGetButtonSelected(panel
->moreChk
[5]) != 0) ? Yes
: No
;
552 different
|= insertAttribute(dict
, winDic
, AKeepInsideScreen
, value
, flags
);
554 value
= (WMGetButtonSelected(panel
->moreChk
[6]) != 0) ? Yes
: No
;
555 different
|= insertAttribute(dict
, winDic
, ANoHideOthers
, value
, flags
);
557 value
= (WMGetButtonSelected(panel
->moreChk
[7]) != 0) ? Yes
: No
;
558 different
|= insertAttribute(dict
, winDic
, ADontSaveSession
, value
, flags
);
560 value
= (WMGetButtonSelected(panel
->moreChk
[8]) != 0) ? Yes
: No
;
561 different
|= insertAttribute(dict
, winDic
, AEmulateAppIcon
, value
, flags
);
563 value
= (WMGetButtonSelected(panel
->moreChk
[9]) != 0) ? Yes
: No
;
564 different
|= insertAttribute(dict
, winDic
, AFocusAcrossWorkspace
, value
, flags
);
566 value
= (WMGetButtonSelected(panel
->moreChk
[10]) != 0) ? Yes
: No
;
567 different
|= insertAttribute(dict
, winDic
, ANoMiniaturizable
, value
, flags
);
569 #ifdef XKB_BUTTON_HINT
570 value
= (WMGetButtonSelected(panel
->moreChk
[11]) != 0) ? Yes
: No
;
571 different
|= insertAttribute(dict
, winDic
, ANoLanguageButton
, value
, flags
);
574 if (wwin
->main_window
!= None
&& wApplicationOf(wwin
->main_window
) != NULL
) {
575 value
= (WMGetButtonSelected(panel
->appChk
[0]) != 0) ? Yes
: No
;
576 different2
|= insertAttribute(dict
, appDic
, AStartHidden
, value
, flags
);
578 value
= (WMGetButtonSelected(panel
->appChk
[1]) != 0) ? Yes
: No
;
579 different2
|= insertAttribute(dict
, appDic
, ANoAppIcon
, value
, flags
);
581 value
= (WMGetButtonSelected(panel
->appChk
[2]) != 0) ? Yes
: No
;
582 different2
|= insertAttribute(dict
, appDic
, ASharedAppIcon
, value
, flags
);
585 if (wwin
->fake_group
) {
586 key2
= WMCreatePLString(wwin
->fake_group
->identifier
);
587 if (WMIsPropListEqualTo(key
, key2
)) {
588 WMMergePLDictionaries(winDic
, appDic
, True
);
589 different
|= different2
;
591 WMRemoveFromPLDictionary(dict
, key2
);
593 WMPutInPLDictionary(dict
, key2
, appDic
);
595 WMReleasePropList(key2
);
596 WMReleasePropList(appDic
);
597 } else if (wwin
->main_window
!= wwin
->client_win
) {
598 WApplication
*wapp
= wApplicationOf(wwin
->main_window
);
601 buf2
= StrConcatDot(wapp
->main_window_desc
->wm_instance
,
602 wapp
->main_window_desc
->wm_class
);
603 key2
= WMCreatePLString(buf2
);
606 if (WMIsPropListEqualTo(key
, key2
)) {
607 WMMergePLDictionaries(winDic
, appDic
, True
);
608 different
|= different2
;
610 WMRemoveFromPLDictionary(dict
, key2
);
612 WMPutInPLDictionary(dict
, key2
, appDic
);
614 WMReleasePropList(key2
);
615 WMReleasePropList(appDic
);
618 WMMergePLDictionaries(winDic
, appDic
, True
);
619 different
|= different2
;
620 WMReleasePropList(appDic
);
623 WMRemoveFromPLDictionary(dict
, key
);
625 WMPutInPLDictionary(dict
, key
, winDic
);
627 WMReleasePropList(key
);
628 WMReleasePropList(winDic
);
630 UpdateDomainFile(db
);
633 WMPLSetCaseSensitive(False
);
636 static void applySettings(WMButton
*button
, InspectorPanel
*panel
)
638 WWindow
*wwin
= panel
->inspected
;
639 WApplication
*wapp
= wApplicationOf(wwin
->main_window
);
640 int floating
, sunken
, skip_window_list
;
641 int old_omnipresent
, old_no_bind_keys
, old_no_bind_mouse
;
643 old_omnipresent
= WFLAGP(wwin
, omnipresent
);
644 old_no_bind_keys
= WFLAGP(wwin
, no_bind_keys
);
645 old_no_bind_mouse
= WFLAGP(wwin
, no_bind_mouse
);
647 showIconFor(WMWidgetScreen(button
), panel
, NULL
, NULL
, USE_TEXT_FIELD
);
649 /* Attributes... --> Window Attributes */
650 WSETUFLAG(wwin
, no_titlebar
, WMGetButtonSelected(panel
->attrChk
[0]));
651 WSETUFLAG(wwin
, no_resizebar
, WMGetButtonSelected(panel
->attrChk
[1]));
652 WSETUFLAG(wwin
, no_close_button
, WMGetButtonSelected(panel
->attrChk
[2]));
653 WSETUFLAG(wwin
, no_miniaturize_button
, WMGetButtonSelected(panel
->attrChk
[3]));
654 WSETUFLAG(wwin
, no_border
, WMGetButtonSelected(panel
->attrChk
[4]));
655 floating
= WMGetButtonSelected(panel
->attrChk
[5]);
656 sunken
= WMGetButtonSelected(panel
->attrChk
[6]);
657 WSETUFLAG(wwin
, omnipresent
, WMGetButtonSelected(panel
->attrChk
[7]));
658 WSETUFLAG(wwin
, start_miniaturized
, WMGetButtonSelected(panel
->attrChk
[8]));
659 WSETUFLAG(wwin
, start_maximized
, WMGetButtonSelected(panel
->attrChk
[9]));
660 WSETUFLAG(wwin
, full_maximize
, WMGetButtonSelected(panel
->attrChk
[10]));
662 /* Attributes... --> Advanced Options */
663 WSETUFLAG(wwin
, no_bind_keys
, WMGetButtonSelected(panel
->moreChk
[0]));
664 WSETUFLAG(wwin
, no_bind_mouse
, WMGetButtonSelected(panel
->moreChk
[1]));
665 skip_window_list
= WMGetButtonSelected(panel
->moreChk
[2]);
666 WSETUFLAG(wwin
, skip_switchpanel
, WMGetButtonSelected(panel
->moreChk
[3]));
667 WSETUFLAG(wwin
, no_focusable
, WMGetButtonSelected(panel
->moreChk
[4]));
668 WSETUFLAG(wwin
, dont_move_off
, WMGetButtonSelected(panel
->moreChk
[5]));
669 WSETUFLAG(wwin
, no_hide_others
, WMGetButtonSelected(panel
->moreChk
[6]));
670 WSETUFLAG(wwin
, dont_save_session
, WMGetButtonSelected(panel
->moreChk
[7]));
671 WSETUFLAG(wwin
, emulate_appicon
, WMGetButtonSelected(panel
->moreChk
[8]));
672 WSETUFLAG(wwin
, focus_across_wksp
, WMGetButtonSelected(panel
->moreChk
[9]));
673 WSETUFLAG(wwin
, no_miniaturizable
, WMGetButtonSelected(panel
->moreChk
[10]));
674 #ifdef XKB_BUTTON_HINT
675 WSETUFLAG(wwin
, no_language_button
, WMGetButtonSelected(panel
->moreChk
[11]));
677 WSETUFLAG(wwin
, always_user_icon
, WMGetButtonSelected(panel
->alwChk
));
679 if (WFLAGP(wwin
, no_titlebar
) && wwin
->flags
.shaded
)
680 wUnshadeWindow(wwin
);
682 WSETUFLAG(wwin
, no_shadeable
, WFLAGP(wwin
, no_titlebar
));
685 if (!WFLAGP(wwin
, floating
))
686 ChangeStackingLevel(wwin
->frame
->core
, WMFloatingLevel
);
688 if (!WFLAGP(wwin
, sunken
))
689 ChangeStackingLevel(wwin
->frame
->core
, WMSunkenLevel
);
691 if (WFLAGP(wwin
, floating
) || WFLAGP(wwin
, sunken
))
692 ChangeStackingLevel(wwin
->frame
->core
, WMNormalLevel
);
695 WSETUFLAG(wwin
, sunken
, sunken
);
696 WSETUFLAG(wwin
, floating
, floating
);
697 wwin
->flags
.omnipresent
= 0;
699 if (WFLAGP(wwin
, skip_window_list
) != skip_window_list
) {
700 WSETUFLAG(wwin
, skip_window_list
, skip_window_list
);
701 UpdateSwitchMenu(wwin
->screen_ptr
, wwin
, skip_window_list
? ACTION_REMOVE
: ACTION_ADD
);
703 if (WFLAGP(wwin
, omnipresent
) != old_omnipresent
)
704 WMPostNotificationName(WMNChangedState
, wwin
, "omnipresent");
707 if (WFLAGP(wwin
, no_bind_keys
) != old_no_bind_keys
) {
708 if (WFLAGP(wwin
, no_bind_keys
))
709 XUngrabKey(dpy
, AnyKey
, AnyModifier
, wwin
->frame
->core
->window
);
711 wWindowSetKeyGrabs(wwin
);
714 if (WFLAGP(wwin
, no_bind_mouse
) != old_no_bind_mouse
)
715 wWindowResetMouseGrabs(wwin
);
717 wwin
->frame
->flags
.need_texture_change
= 1;
718 wWindowConfigureBorders(wwin
);
719 wFrameWindowPaint(wwin
->frame
);
720 wNETWMUpdateActions(wwin
, False
);
722 /* Can't apply emulate_appicon because it will probably cause problems. */
724 /* do application wide stuff */
725 WSETUFLAG(wapp
->main_window_desc
, start_hidden
, WMGetButtonSelected(panel
->appChk
[0]));
726 WSETUFLAG(wapp
->main_window_desc
, no_appicon
, WMGetButtonSelected(panel
->appChk
[1]));
727 WSETUFLAG(wapp
->main_window_desc
, shared_appicon
, WMGetButtonSelected(panel
->appChk
[2]));
729 if (WFLAGP(wapp
->main_window_desc
, no_appicon
))
730 unpaint_app_icon(wapp
);
732 paint_app_icon(wapp
);
734 char *file
= WMGetTextFieldText(panel
->fileText
);
740 /* If always_user_icon flag is set, but the user icon is not set
741 * we use client supplied icon and we unset the flag */
742 if ((WFLAGP(wwin
, always_user_icon
) && (!file
))) {
743 /* Show the warning */
748 snprintf(buf
, len
, _("Ignore client supplied icon is set, but icon filename textbox is empty. Using client supplied icon"));
749 wMessageDialog(panel
->frame
->screen_ptr
, _("Warning"), buf
, _("OK"), NULL
, NULL
);
753 /* Change the flags */
754 WSETUFLAG(wwin
, always_user_icon
, 0);
755 WMSetButtonSelected(panel
->alwChk
, 0);
758 /* After test the always_user_icon flag value before,
759 * the "else" block is used only if the flag is set and
760 * the icon text box has an icon path */
761 if (!WFLAGP(wwin
, always_user_icon
)) {
762 /* Change App Icon image, using the icon provided by the client */
763 if (wapp
->app_icon
) {
764 RImage
*image
= get_rimage_icon_from_wm_hints(wapp
->app_icon
->icon
);
766 set_icon_image_from_image(wapp
->app_icon
->icon
, image
);
767 update_icon_pixmap(wapp
->app_icon
->icon
);
769 wIconUpdate(wapp
->app_icon
->icon
);
773 /* Change icon image if the app is minimized,
774 * using the icon provided by the client */
776 RImage
*image
= get_rimage_icon_from_wm_hints(wwin
->icon
);
778 set_icon_image_from_image(wwin
->icon
, image
);
779 update_icon_pixmap(wwin
->icon
);
781 wIconUpdate(wwin
->icon
);
785 /* Change App Icon image */
787 wIconChangeImageFile(wapp
->app_icon
->icon
, file
);
789 /* Change icon image if the app is minimized */
791 wIconChangeImageFile(wwin
->icon
, file
);
798 wNETFrameExtents(wwin
);
801 static void revertSettings(WMButton
*button
, InspectorPanel
*panel
)
803 WWindow
*wwin
= panel
->inspected
;
804 WApplication
*wapp
= wApplicationOf(wwin
->main_window
);
805 int i
, n
, workspace
, level
;
806 char *wm_instance
= NULL
, *wm_class
= NULL
;
808 if (panel
->instRb
&& WMGetButtonSelected(panel
->instRb
) != 0)
809 wm_instance
= wwin
->wm_instance
;
810 else if (panel
->clsRb
&& WMGetButtonSelected(panel
->clsRb
) != 0)
811 wm_class
= wwin
->wm_class
;
812 else if (panel
->bothRb
&& WMGetButtonSelected(panel
->bothRb
) != 0) {
813 wm_instance
= wwin
->wm_instance
;
814 wm_class
= wwin
->wm_class
;
817 memset(&wwin
->defined_user_flags
, 0, sizeof(WWindowAttributes
));
818 memset(&wwin
->user_flags
, 0, sizeof(WWindowAttributes
));
819 memset(&wwin
->client_flags
, 0, sizeof(WWindowAttributes
));
821 wWindowSetupInitialAttributes(wwin
, &level
, &workspace
);
823 for (i
= 0; i
< (sizeof(panel
->attrChk
) / sizeof(panel
->attrChk
[0])); i
++) {
828 flag
= WFLAGP(wwin
, no_titlebar
);
831 flag
= WFLAGP(wwin
, no_resizebar
);
834 flag
= WFLAGP(wwin
, no_close_button
);
837 flag
= WFLAGP(wwin
, no_miniaturize_button
);
840 flag
= WFLAGP(wwin
, no_border
);
843 flag
= WFLAGP(wwin
, floating
);
846 flag
= WFLAGP(wwin
, sunken
);
849 flag
= WFLAGP(wwin
, omnipresent
);
852 flag
= WFLAGP(wwin
, start_miniaturized
);
855 flag
= WFLAGP(wwin
, start_maximized
!= 0);
858 flag
= WFLAGP(wwin
, full_maximize
);
861 WMSetButtonSelected(panel
->attrChk
[i
], flag
);
864 for (i
= 0; i
< (sizeof(panel
->moreChk
) / sizeof(panel
->moreChk
[0])); i
++) {
869 flag
= WFLAGP(wwin
, no_bind_keys
);
872 flag
= WFLAGP(wwin
, no_bind_mouse
);
875 flag
= WFLAGP(wwin
, skip_window_list
);
878 flag
= WFLAGP(wwin
, skip_switchpanel
);
881 flag
= WFLAGP(wwin
, no_focusable
);
884 flag
= WFLAGP(wwin
, dont_move_off
);
887 flag
= WFLAGP(wwin
, no_hide_others
);
890 flag
= WFLAGP(wwin
, dont_save_session
);
893 flag
= WFLAGP(wwin
, emulate_appicon
);
896 flag
= WFLAGP(wwin
, focus_across_wksp
);
899 flag
= WFLAGP(wwin
, no_miniaturizable
);
901 #ifdef XKB_BUTTON_HINT
903 flag
= WFLAGP(wwin
, no_language_button
);
907 WMSetButtonSelected(panel
->moreChk
[i
], flag
);
909 if (panel
->appFrm
&& wapp
) {
910 for (i
= 0; i
< (sizeof(panel
->appChk
) / sizeof(panel
->appChk
[0])); i
++) {
915 flag
= WFLAGP(wapp
->main_window_desc
, start_hidden
);
918 flag
= WFLAGP(wapp
->main_window_desc
, no_appicon
);
921 flag
= WFLAGP(wapp
->main_window_desc
, shared_appicon
);
924 WMSetButtonSelected(panel
->appChk
[i
], flag
);
927 WMSetButtonSelected(panel
->alwChk
, WFLAGP(wwin
, always_user_icon
));
929 showIconFor(WMWidgetScreen(panel
->alwChk
), panel
, wm_instance
, wm_class
, REVERT_TO_DEFAULT
);
931 n
= wDefaultGetStartWorkspace(wm_instance
, wm_class
);
933 if (n
>= 0 && n
< w_global
.workspace
.count
)
934 WMSetPopUpButtonSelectedItem(panel
->wsP
, n
+ 1);
936 WMSetPopUpButtonSelectedItem(panel
->wsP
, 0);
938 /* must auto apply, so that there wno't be internal
939 * inconsistencies between the state in the flags and
940 * the actual state of the window */
941 applySettings(panel
->applyBtn
, panel
);
944 static void chooseIconCallback(WMWidget
*self
, void *clientData
)
947 InspectorPanel
*panel
= (InspectorPanel
*) clientData
;
950 panel
->choosingIcon
= 1;
952 WMSetButtonEnabled(panel
->browseIconBtn
, False
);
954 result
= wIconChooserDialog(panel
->frame
->screen_ptr
, &file
,
955 panel
->inspected
->wm_instance
,
956 panel
->inspected
->wm_class
);
958 panel
->choosingIcon
= 0;
960 if (!panel
->destroyed
) { /* kluge */
962 WMSetTextFieldText(panel
->fileText
, file
);
963 showIconFor(WMWidgetScreen(self
), panel
, NULL
, NULL
, USE_TEXT_FIELD
);
966 WMSetButtonEnabled(panel
->browseIconBtn
, True
);
968 freeInspector(panel
);
972 static void textEditedObserver(void *observerData
, WMNotification
*notification
)
974 InspectorPanel
*panel
= (InspectorPanel
*) observerData
;
976 if ((long)WMGetNotificationClientData(notification
) != WMReturnTextMovement
)
979 showIconFor(WMWidgetScreen(panel
->win
), panel
, NULL
, NULL
, USE_TEXT_FIELD
);
982 static void selectSpecification(WMWidget
*bPtr
, void *data
)
984 InspectorPanel
*panel
= (InspectorPanel
*) data
;
986 WWindow
*wwin
= panel
->inspected
;
989 if (bPtr
== panel
->defaultRb
&& (wwin
->wm_instance
|| wwin
->wm_class
))
990 WMSetButtonEnabled(panel
->applyBtn
, False
);
992 WMSetButtonEnabled(panel
->applyBtn
, True
);
994 len
= 16 + strlen(wwin
->wm_instance
? wwin
->wm_instance
: "?")
995 + strlen(wwin
->wm_class
? wwin
->wm_class
: "?");
999 snprintf(str
, len
, _("Inspecting %s.%s"),
1000 wwin
->wm_instance
? wwin
->wm_instance
: "?", wwin
->wm_class
? wwin
->wm_class
: "?");
1002 wFrameWindowChangeTitle(panel
->frame
->frame
, str
);
1007 static void selectWindow(WMWidget
*bPtr
, void *data
)
1009 InspectorPanel
*panel
= (InspectorPanel
*) data
;
1010 WWindow
*wwin
= panel
->inspected
;
1011 WScreen
*scr
= wwin
->screen_ptr
;
1015 if (XGrabPointer(dpy
, scr
->root_win
, True
,
1016 ButtonPressMask
, GrabModeAsync
, GrabModeAsync
, None
,
1017 wPreferences
.cursor
[WCUR_SELECT
], CurrentTime
) != GrabSuccess
) {
1018 wwarning("could not grab mouse pointer");
1022 WMSetLabelText(panel
->specLbl
, _("Click in the window you wish to inspect."));
1023 WMMaskEvent(dpy
, ButtonPressMask
, &event
);
1024 XUngrabPointer(dpy
, CurrentTime
);
1026 iwin
= wWindowFor(event
.xbutton
.subwindow
);
1027 if (iwin
&& !iwin
->flags
.internal_window
&& iwin
!= wwin
&& !iwin
->flags
.inspector_open
) {
1028 iwin
->flags
.inspector_open
= 1;
1029 iwin
->inspector
= createInspectorForWindow(iwin
,
1030 panel
->frame
->frame_x
, panel
->frame
->frame_y
, True
);
1031 wCloseInspectorForWindow(wwin
);
1033 WMSetLabelText(panel
->specLbl
, spec_text
);
1037 static InspectorPanel
*createInspectorForWindow(WWindow
*wwin
, int xpos
, int ypos
, Bool showSelectPanel
)
1039 WScreen
*scr
= wwin
->screen_ptr
;
1040 InspectorPanel
*panel
;
1042 char *str
= NULL
, *tmp
= NULL
;
1043 int x
, y
, btn_width
, frame_width
;
1044 WMButton
*selectedBtn
= NULL
;
1046 spec_text
= _("The configuration will apply to all\n"
1047 "windows that have their WM_CLASS\n"
1048 "property set to the above selected\n" "name, when saved.");
1050 panel
= wmalloc(sizeof(InspectorPanel
));
1051 memset(panel
, 0, sizeof(InspectorPanel
));
1053 panel
->destroyed
= 0;
1054 panel
->inspected
= wwin
;
1055 panel
->nextPtr
= panelList
;
1057 panel
->win
= WMCreateWindow(scr
->wmscreen
, "windowInspector");
1058 WMResizeWidget(panel
->win
, PWIDTH
, PHEIGHT
);
1060 /**** create common stuff ****/
1061 /* command buttons */
1062 btn_width
= (PWIDTH
- (2 * 15) - (2 * 10)) / 3;
1063 panel
->saveBtn
= WMCreateCommandButton(panel
->win
);
1064 WMSetButtonAction(panel
->saveBtn
, (WMAction
*) saveSettings
, panel
);
1065 WMMoveWidget(panel
->saveBtn
, (2 * (btn_width
+ 10)) + 15, PHEIGHT
- 40);
1066 WMSetButtonText(panel
->saveBtn
, _("Save"));
1067 WMResizeWidget(panel
->saveBtn
, btn_width
, 28);
1068 if (wPreferences
.flags
.noupdates
|| !(wwin
->wm_class
|| wwin
->wm_instance
))
1069 WMSetButtonEnabled(panel
->saveBtn
, False
);
1071 panel
->applyBtn
= WMCreateCommandButton(panel
->win
);
1072 WMSetButtonAction(panel
->applyBtn
, (WMAction
*) applySettings
, panel
);
1073 WMMoveWidget(panel
->applyBtn
, btn_width
+ 10 + 15, PHEIGHT
- 40);
1074 WMSetButtonText(panel
->applyBtn
, _("Apply"));
1075 WMResizeWidget(panel
->applyBtn
, btn_width
, 28);
1077 panel
->revertBtn
= WMCreateCommandButton(panel
->win
);
1078 WMSetButtonAction(panel
->revertBtn
, (WMAction
*) revertSettings
, panel
);
1079 WMMoveWidget(panel
->revertBtn
, 15, PHEIGHT
- 40);
1080 WMSetButtonText(panel
->revertBtn
, _("Reload"));
1081 WMResizeWidget(panel
->revertBtn
, btn_width
, 28);
1083 /* page selection popup button */
1084 panel
->pagePopUp
= WMCreatePopUpButton(panel
->win
);
1085 WMSetPopUpButtonAction(panel
->pagePopUp
, (WMAction
*) changePage
, panel
);
1086 WMMoveWidget(panel
->pagePopUp
, 25, 15);
1087 WMResizeWidget(panel
->pagePopUp
, PWIDTH
- 50, 20);
1089 WMAddPopUpButtonItem(panel
->pagePopUp
, _("Window Specification"));
1090 WMAddPopUpButtonItem(panel
->pagePopUp
, _("Window Attributes"));
1091 WMAddPopUpButtonItem(panel
->pagePopUp
, _("Advanced Options"));
1092 WMAddPopUpButtonItem(panel
->pagePopUp
, _("Icon and Initial Workspace"));
1093 WMAddPopUpButtonItem(panel
->pagePopUp
, _("Application Specific"));
1095 /**** window spec ****/
1096 frame_width
= PWIDTH
- (2 * 15);
1098 panel
->specFrm
= WMCreateFrame(panel
->win
);
1099 WMSetFrameTitle(panel
->specFrm
, _("Window Specification"));
1100 WMMoveWidget(panel
->specFrm
, 15, 65);
1101 WMResizeWidget(panel
->specFrm
, frame_width
, 145);
1103 panel
->defaultRb
= WMCreateRadioButton(panel
->specFrm
);
1104 WMMoveWidget(panel
->defaultRb
, 10, 78);
1105 WMResizeWidget(panel
->defaultRb
, frame_width
- (2 * 10), 20);
1106 WMSetButtonText(panel
->defaultRb
, _("Defaults for all windows"));
1107 WMSetButtonSelected(panel
->defaultRb
, False
);
1108 WMSetButtonAction(panel
->defaultRb
, selectSpecification
, panel
);
1110 if (wwin
->wm_class
&& wwin
->wm_instance
) {
1111 tmp
= wstrconcat(wwin
->wm_instance
, ".");
1112 str
= wstrconcat(tmp
, wwin
->wm_class
);
1114 panel
->bothRb
= WMCreateRadioButton(panel
->specFrm
);
1115 WMMoveWidget(panel
->bothRb
, 10, 18);
1116 WMResizeWidget(panel
->bothRb
, frame_width
- (2 * 10), 20);
1117 WMSetButtonText(panel
->bothRb
, str
);
1120 WMGroupButtons(panel
->defaultRb
, panel
->bothRb
);
1123 selectedBtn
= panel
->bothRb
;
1125 WMSetButtonAction(panel
->bothRb
, selectSpecification
, panel
);
1128 if (wwin
->wm_instance
) {
1129 panel
->instRb
= WMCreateRadioButton(panel
->specFrm
);
1130 WMMoveWidget(panel
->instRb
, 10, 38);
1131 WMResizeWidget(panel
->instRb
, frame_width
- (2 * 10), 20);
1132 WMSetButtonText(panel
->instRb
, wwin
->wm_instance
);
1133 WMGroupButtons(panel
->defaultRb
, panel
->instRb
);
1136 selectedBtn
= panel
->instRb
;
1138 WMSetButtonAction(panel
->instRb
, selectSpecification
, panel
);
1141 if (wwin
->wm_class
) {
1142 panel
->clsRb
= WMCreateRadioButton(panel
->specFrm
);
1143 WMMoveWidget(panel
->clsRb
, 10, 58);
1144 WMResizeWidget(panel
->clsRb
, frame_width
- (2 * 10), 20);
1145 WMSetButtonText(panel
->clsRb
, wwin
->wm_class
);
1146 WMGroupButtons(panel
->defaultRb
, panel
->clsRb
);
1149 selectedBtn
= panel
->clsRb
;
1151 WMSetButtonAction(panel
->clsRb
, selectSpecification
, panel
);
1154 panel
->selWinB
= WMCreateCommandButton(panel
->specFrm
);
1155 WMMoveWidget(panel
->selWinB
, 20, 145 - 24 - 10);
1156 WMResizeWidget(panel
->selWinB
, frame_width
- 2 * 10 - 20, 24);
1157 WMSetButtonText(panel
->selWinB
, _("Select window"));
1158 WMSetButtonAction(panel
->selWinB
, selectWindow
, panel
);
1160 panel
->specLbl
= WMCreateLabel(panel
->win
);
1161 WMMoveWidget(panel
->specLbl
, 15, 210);
1162 WMResizeWidget(panel
->specLbl
, frame_width
, 100);
1163 WMSetLabelText(panel
->specLbl
, spec_text
);
1164 WMSetLabelWraps(panel
->specLbl
, True
);
1166 WMSetLabelTextAlignment(panel
->specLbl
, WALeft
);
1168 /**** attributes ****/
1169 create_tab_window_attributes(wwin
, panel
, frame_width
);
1170 create_tab_window_advanced(wwin
, panel
, frame_width
);
1171 create_tab_icon_workspace(wwin
, panel
);
1172 create_tab_app_specific(wwin
, panel
, frame_width
);
1174 /* if the window is a transient, don't let it have a miniaturize button */
1175 if (wwin
->transient_for
!= None
&& wwin
->transient_for
!= scr
->root_win
)
1176 WMSetButtonEnabled(panel
->attrChk
[3], False
);
1178 WMSetButtonEnabled(panel
->attrChk
[3], True
);
1180 if (!wwin
->wm_class
&& !wwin
->wm_instance
)
1181 WMSetPopUpButtonItemEnabled(panel
->pagePopUp
, 0, False
);
1183 WMRealizeWidget(panel
->win
);
1185 WMMapSubwidgets(panel
->win
);
1186 WMMapSubwidgets(panel
->specFrm
);
1187 WMMapSubwidgets(panel
->attrFrm
);
1188 WMMapSubwidgets(panel
->moreFrm
);
1189 WMMapSubwidgets(panel
->iconFrm
);
1190 WMMapSubwidgets(panel
->wsFrm
);
1192 WMMapSubwidgets(panel
->appFrm
);
1194 if (showSelectPanel
) {
1195 WMSetPopUpButtonSelectedItem(panel
->pagePopUp
, 0);
1196 changePage(panel
->pagePopUp
, panel
);
1198 WMSetPopUpButtonSelectedItem(panel
->pagePopUp
, 1);
1199 changePage(panel
->pagePopUp
, panel
);
1202 parent
= XCreateSimpleWindow(dpy
, scr
->root_win
, 0, 0, PWIDTH
, PHEIGHT
, 0, 0, 0);
1203 XSelectInput(dpy
, parent
, KeyPressMask
| KeyReleaseMask
);
1204 panel
->parent
= parent
;
1205 XReparentWindow(dpy
, WMWidgetXID(panel
->win
), parent
, 0, 0);
1207 WMMapWidget(panel
->win
);
1209 XSetTransientForHint(dpy
, parent
, wwin
->client_win
);
1211 if (xpos
== UNDEFINED_POS
) {
1212 x
= wwin
->frame_x
+ wwin
->frame
->core
->width
/ 2;
1213 y
= wwin
->frame_y
+ wwin
->frame
->top_width
* 2;
1214 if (y
+ PHEIGHT
> scr
->scr_height
)
1215 y
= scr
->scr_height
- PHEIGHT
- 30;
1216 if (x
+ PWIDTH
> scr
->scr_width
)
1217 x
= scr
->scr_width
- PWIDTH
;
1223 panel
->frame
= wManageInternalWindow(scr
, parent
, wwin
->client_win
, "Inspector", x
, y
, PWIDTH
, PHEIGHT
);
1226 selectedBtn
= panel
->defaultRb
;
1228 WMSetButtonSelected(selectedBtn
, True
);
1229 selectSpecification(selectedBtn
, panel
);
1231 /* kluge to know who should get the key events */
1232 panel
->frame
->client_leader
= WMWidgetXID(panel
->win
);
1234 WSETUFLAG(panel
->frame
, no_closable
, 0);
1235 WSETUFLAG(panel
->frame
, no_close_button
, 0);
1236 wWindowUpdateButtonImages(panel
->frame
);
1237 wFrameWindowShowButton(panel
->frame
->frame
, WFF_RIGHT_BUTTON
);
1238 panel
->frame
->frame
->on_click_right
= destroyInspector
;
1240 wWindowMap(panel
->frame
);
1242 showIconFor(WMWidgetScreen(panel
->alwChk
), panel
, wwin
->wm_instance
, wwin
->wm_class
, UPDATE_TEXT_FIELD
);
1247 void wShowInspectorForWindow(WWindow
*wwin
)
1249 if (wwin
->flags
.inspector_open
)
1252 WMSetBalloonEnabled(wwin
->screen_ptr
->wmscreen
, wPreferences
.help_balloon
);
1255 wwin
->flags
.inspector_open
= 1;
1256 wwin
->inspector
= createInspectorForWindow(wwin
, UNDEFINED_POS
, UNDEFINED_POS
, False
);
1259 void wHideInspectorForWindow(WWindow
*wwin
)
1261 WWindow
*pwin
= wwin
->inspector
->frame
;
1264 pwin
->flags
.hidden
= 1;
1266 wClientSetState(pwin
, IconicState
, None
);
1269 void wUnhideInspectorForWindow(WWindow
*wwin
)
1271 WWindow
*pwin
= wwin
->inspector
->frame
;
1273 pwin
->flags
.hidden
= 0;
1274 pwin
->flags
.mapped
= 1;
1275 XMapWindow(dpy
, pwin
->client_win
);
1276 XMapWindow(dpy
, pwin
->frame
->core
->window
);
1277 wClientSetState(pwin
, NormalState
, None
);
1280 WWindow
*wGetWindowOfInspectorForWindow(WWindow
*wwin
)
1282 if (!wwin
->inspector
)
1285 assert(wwin
->flags
.inspector_open
!= 0);
1286 return wwin
->inspector
->frame
;
1289 void wCloseInspectorForWindow(WWindow
*wwin
)
1291 WWindow
*pwin
= wwin
->inspector
->frame
; /* the inspector window */
1293 (*pwin
->frame
->on_click_right
) (NULL
, pwin
, NULL
);
1296 static void create_tab_window_attributes(WWindow
*wwin
, InspectorPanel
*panel
, int frame_width
)
1299 char *caption
= NULL
, *descr
= NULL
;
1302 panel
->attrFrm
= WMCreateFrame(panel
->win
);
1303 WMSetFrameTitle(panel
->attrFrm
, _("Attributes"));
1304 WMMoveWidget(panel
->attrFrm
, 15, 45);
1305 WMResizeWidget(panel
->attrFrm
, frame_width
, 250);
1307 for (i
= 0; i
< (sizeof(panel
->attrChk
) / sizeof(panel
->attrChk
[0])); i
++) {
1310 caption
= _("Disable titlebar");
1311 flag
= WFLAGP(wwin
, no_titlebar
);
1312 descr
= _("Remove the titlebar of this window.\n"
1313 "To access the window commands menu of a window\n"
1314 "without it's titlebar, press Control+Esc (or the\n"
1315 "equivalent shortcut, if you changed the default\n" "settings).");
1318 caption
= _("Disable resizebar");
1319 flag
= WFLAGP(wwin
, no_resizebar
);
1320 descr
= _("Remove the resizebar of this window.");
1323 caption
= _("Disable close button");
1324 flag
= WFLAGP(wwin
, no_close_button
);
1325 descr
= _("Remove the `close window' button of this window.");
1328 caption
= _("Disable miniaturize button");
1329 flag
= WFLAGP(wwin
, no_miniaturize_button
);
1330 descr
= _("Remove the `miniaturize window' button of the window.");
1333 caption
= _("Disable border");
1334 flag
= WFLAGP(wwin
, no_border
);
1335 descr
= _("Remove the 1 pixel black border around the window.");
1338 caption
= _("Keep on top (floating)");
1339 flag
= WFLAGP(wwin
, floating
);
1340 descr
= _("Keep the window over other windows, not allowing\n" "them to cover it.");
1343 caption
= _("Keep at bottom (sunken)");
1344 flag
= WFLAGP(wwin
, sunken
);
1345 descr
= _("Keep the window under all other windows.");
1348 caption
= _("Omnipresent");
1349 flag
= WFLAGP(wwin
, omnipresent
);
1350 descr
= _("Make window present in all workspaces.");
1353 caption
= _("Start miniaturized");
1354 flag
= WFLAGP(wwin
, start_miniaturized
);
1355 descr
= _("Make the window be automatically miniaturized when it's\n" "first shown.");
1358 caption
= _("Start maximized");
1359 flag
= WFLAGP(wwin
, start_maximized
!= 0);
1360 descr
= _("Make the window be automatically maximized when it's\n" "first shown.");
1363 caption
= _("Full screen maximization");
1364 flag
= WFLAGP(wwin
, full_maximize
);
1365 descr
= _("Make the window use the whole screen space when it's\n"
1366 "maximized. The titlebar and resizebar will be moved\n"
1367 "to outside the screen.");
1370 panel
->attrChk
[i
] = WMCreateSwitchButton(panel
->attrFrm
);
1371 WMMoveWidget(panel
->attrChk
[i
], 10, 20 * (i
+ 1));
1372 WMResizeWidget(panel
->attrChk
[i
], frame_width
- 15, 20);
1373 WMSetButtonSelected(panel
->attrChk
[i
], flag
);
1374 WMSetButtonText(panel
->attrChk
[i
], caption
);
1376 WMSetBalloonTextForView(descr
, WMWidgetView(panel
->attrChk
[i
]));
1380 static void create_tab_window_advanced(WWindow
*wwin
, InspectorPanel
*panel
, int frame_width
)
1383 char *caption
= NULL
, *descr
= NULL
;
1386 panel
->moreFrm
= WMCreateFrame(panel
->win
);
1387 WMSetFrameTitle(panel
->moreFrm
, _("Advanced"));
1388 WMMoveWidget(panel
->moreFrm
, 15, 45);
1389 WMResizeWidget(panel
->moreFrm
, frame_width
, 265);
1391 for (i
= 0; i
< (sizeof(panel
->moreChk
) / sizeof(panel
->moreChk
[0])); i
++) {
1394 caption
= _("Do not bind keyboard shortcuts");
1395 flag
= WFLAGP(wwin
, no_bind_keys
);
1396 descr
= _("Do not bind keyboard shortcuts from Window Maker\n"
1397 "when this window is focused. This will allow the\n"
1398 "window to receive all key combinations regardless\n"
1399 "of your shortcut configuration.");
1402 caption
= _("Do not bind mouse clicks");
1403 flag
= WFLAGP(wwin
, no_bind_mouse
);
1404 descr
= _("Do not bind mouse actions, such as `Alt'+drag\n"
1405 "in the window (when alt is the modifier you have\n" "configured).");
1408 caption
= _("Do not show in the window list");
1409 flag
= WFLAGP(wwin
, skip_window_list
);
1410 descr
= _("Do not list the window in the window list menu.");
1413 caption
= _("Do not show in the switch panel");
1414 flag
= WFLAGP(wwin
, skip_switchpanel
);
1415 descr
= _("Do not include in switchpanel while alternating windows.");
1418 caption
= _("Do not let it take focus");
1419 flag
= WFLAGP(wwin
, no_focusable
);
1420 descr
= _("Do not let the window take keyboard focus when you\n" "click on it.");
1423 caption
= _("Keep inside screen");
1424 flag
= WFLAGP(wwin
, dont_move_off
);
1425 descr
= _("Do not allow the window to move itself completely\n"
1426 "outside the screen. For bug compatibility.\n");
1429 caption
= _("Ignore 'Hide Others'");
1430 flag
= WFLAGP(wwin
, no_hide_others
);
1431 descr
= _("Do not hide the window when issuing the\n" "`HideOthers' command.");
1434 caption
= _("Ignore 'Save Session'");
1435 flag
= WFLAGP(wwin
, dont_save_session
);
1436 descr
= _("Do not save the associated application in the\n"
1437 "session's state, so that it won't be restarted\n"
1438 "together with other applications when Window Maker\n" "starts.");
1441 caption
= _("Emulate application icon");
1442 flag
= WFLAGP(wwin
, emulate_appicon
);
1443 descr
= _("Make this window act as an application that provides\n"
1444 "enough information to Window Maker for a dockable\n"
1445 "application icon to be created.");
1448 caption
= _("Focus across workspaces");
1449 flag
= WFLAGP(wwin
, focus_across_wksp
);
1450 descr
= _("Allow Window Maker to switch workspace to satisfy\n"
1451 "a focus request (annoying).");
1454 caption
= _("Do not let it be minimized");
1455 flag
= WFLAGP(wwin
, no_miniaturizable
);
1456 descr
= _("Do not let the window of this application be\n"
1459 #ifdef XKB_BUTTON_HINT
1461 caption
= _("Disable language button");
1462 flag
= WFLAGP(wwin
, no_language_button
);
1463 descr
= _("Remove the `toggle language' button of the window.");
1467 panel
->moreChk
[i
] = WMCreateSwitchButton(panel
->moreFrm
);
1468 WMMoveWidget(panel
->moreChk
[i
], 10, 20 * (i
+ 1));
1469 WMResizeWidget(panel
->moreChk
[i
], frame_width
- 15, 20);
1470 WMSetButtonSelected(panel
->moreChk
[i
], flag
);
1471 WMSetButtonText(panel
->moreChk
[i
], caption
);
1473 WMSetBalloonTextForView(descr
, WMWidgetView(panel
->moreChk
[i
]));
1477 static void create_tab_icon_workspace(WWindow
*wwin
, InspectorPanel
*panel
)
1481 /* miniwindow/workspace */
1482 panel
->iconFrm
= WMCreateFrame(panel
->win
);
1483 WMMoveWidget(panel
->iconFrm
, 15, 50);
1484 WMResizeWidget(panel
->iconFrm
, PWIDTH
- (2 * 15), 170);
1485 WMSetFrameTitle(panel
->iconFrm
, _("Miniwindow Image"));
1487 panel
->iconLbl
= WMCreateLabel(panel
->iconFrm
);
1488 WMMoveWidget(panel
->iconLbl
, PWIDTH
- (2 * 15) - 22 - 64, 20);
1489 WMResizeWidget(panel
->iconLbl
, 64, 64);
1490 WMSetLabelRelief(panel
->iconLbl
, WRGroove
);
1491 WMSetLabelImagePosition(panel
->iconLbl
, WIPImageOnly
);
1493 panel
->browseIconBtn
= WMCreateCommandButton(panel
->iconFrm
);
1494 WMSetButtonAction(panel
->browseIconBtn
, chooseIconCallback
, panel
);
1495 WMMoveWidget(panel
->browseIconBtn
, 22, 32);
1496 WMResizeWidget(panel
->browseIconBtn
, 120, 26);
1497 WMSetButtonText(panel
->browseIconBtn
, _("Browse..."));
1499 panel
->fileLbl
= WMCreateLabel(panel
->iconFrm
);
1500 WMMoveWidget(panel
->fileLbl
, 20, 85);
1501 WMResizeWidget(panel
->fileLbl
, PWIDTH
- (2 * 15) - (2 * 20), 14);
1502 WMSetLabelText(panel
->fileLbl
, _("Icon filename:"));
1504 panel
->fileText
= WMCreateTextField(panel
->iconFrm
);
1505 WMMoveWidget(panel
->fileText
, 20, 105);
1506 WMResizeWidget(panel
->fileText
, PWIDTH
- (2 * 20) - (2 * 15), 20);
1507 WMSetTextFieldText(panel
->fileText
, NULL
);
1508 WMAddNotificationObserver(textEditedObserver
, panel
, WMTextDidEndEditingNotification
, panel
->fileText
);
1510 panel
->alwChk
= WMCreateSwitchButton(panel
->iconFrm
);
1511 WMMoveWidget(panel
->alwChk
, 20, 130);
1512 WMResizeWidget(panel
->alwChk
, PWIDTH
- (2 * 15) - (2 * 15), 30);
1513 WMSetButtonText(panel
->alwChk
, _("Ignore client supplied icon"));
1514 WMSetButtonSelected(panel
->alwChk
, WFLAGP(wwin
, always_user_icon
));
1516 panel
->wsFrm
= WMCreateFrame(panel
->win
);
1517 WMMoveWidget(panel
->wsFrm
, 15, 225);
1518 WMResizeWidget(panel
->wsFrm
, PWIDTH
- (2 * 15), 70);
1519 WMSetFrameTitle(panel
->wsFrm
, _("Initial Workspace"));
1521 WMSetBalloonTextForView(_("The workspace to place the window when it's"
1522 "first shown."), WMWidgetView(panel
->wsFrm
));
1524 panel
->wsP
= WMCreatePopUpButton(panel
->wsFrm
);
1525 WMMoveWidget(panel
->wsP
, 20, 30);
1526 WMResizeWidget(panel
->wsP
, PWIDTH
- (2 * 15) - (2 * 20), 20);
1527 WMAddPopUpButtonItem(panel
->wsP
, _("Nowhere in particular"));
1529 for (i
= 0; i
< w_global
.workspace
.count
; i
++)
1530 WMAddPopUpButtonItem(panel
->wsP
, w_global
.workspace
.array
[i
]->name
);
1532 i
= wDefaultGetStartWorkspace(wwin
->wm_instance
, wwin
->wm_class
);
1533 if (i
>= 0 && i
<= w_global
.workspace
.count
)
1534 WMSetPopUpButtonSelectedItem(panel
->wsP
, i
+ 1);
1536 WMSetPopUpButtonSelectedItem(panel
->wsP
, 0);
1539 static void create_tab_app_specific(WWindow
*wwin
, InspectorPanel
*panel
, int frame_width
)
1541 WScreen
*scr
= wwin
->screen_ptr
;
1542 int i
= 0, flag
= 0, tmp
;
1543 char *caption
= NULL
, *descr
= NULL
;
1546 if (wwin
->main_window
!= None
) {
1547 WApplication
*wapp
= wApplicationOf(wwin
->main_window
);
1549 panel
->appFrm
= WMCreateFrame(panel
->win
);
1550 WMSetFrameTitle(panel
->appFrm
, _("Application Attributes"));
1551 WMMoveWidget(panel
->appFrm
, 15, 50);
1552 WMResizeWidget(panel
->appFrm
, frame_width
, 240);
1554 for (i
= 0; i
< (sizeof(panel
->appChk
) / sizeof(panel
->appChk
[0])); i
++) {
1557 caption
= _("Start hidden");
1558 flag
= WFLAGP(wapp
->main_window_desc
, start_hidden
);
1559 descr
= _("Automatically hide application when it's started.");
1562 caption
= _("No application icon");
1563 flag
= WFLAGP(wapp
->main_window_desc
, no_appicon
);
1564 descr
= _("Disable the application icon for the application.\n"
1565 "Note that you won't be able to dock it anymore,\n"
1566 "and any icons that are already docked will stop\n"
1567 "working correctly.");
1570 caption
= _("Shared application icon");
1571 flag
= WFLAGP(wapp
->main_window_desc
, shared_appicon
);
1572 descr
= _("Use a single shared application icon for all of\n"
1573 "the instances of this application.\n");
1576 panel
->appChk
[i
] = WMCreateSwitchButton(panel
->appFrm
);
1577 WMMoveWidget(panel
->appChk
[i
], 10, 20 * (i
+ 1));
1578 WMResizeWidget(panel
->appChk
[i
], 205, 20);
1579 WMSetButtonSelected(panel
->appChk
[i
], flag
);
1580 WMSetButtonText(panel
->appChk
[i
], caption
);
1581 WMSetBalloonTextForView(descr
, WMWidgetView(panel
->appChk
[i
]));
1584 if (WFLAGP(wwin
, emulate_appicon
)) {
1585 WMSetButtonEnabled(panel
->appChk
[1], False
);
1586 WMSetButtonEnabled(panel
->moreChk
[7], True
);
1588 WMSetButtonEnabled(panel
->appChk
[1], True
);
1589 WMSetButtonEnabled(panel
->moreChk
[7], False
);
1592 if ((wwin
->transient_for
!= None
&& wwin
->transient_for
!= scr
->root_win
)
1593 || !wwin
->wm_class
|| !wwin
->wm_instance
)
1598 WMSetButtonEnabled(panel
->moreChk
[7], tmp
);
1600 WMSetPopUpButtonItemEnabled(panel
->pagePopUp
, 4, False
);
1601 panel
->appFrm
= NULL
;