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
66 WWindowAttributes flag
;
68 const char *description
;
69 } window_attribute
[] = {
70 { "NoTitlebar", { .no_titlebar
= 1 }, N_("Disable titlebar"),
71 N_("Remove the titlebar of this window.\n"
72 "To access the window commands menu of a window\n"
73 "without it's titlebar, press Control+Esc (or the\n"
74 "equivalent shortcut, if you changed the default\n"
77 { "NoResizebar", { .no_resizebar
= 1 }, N_("Disable resizebar"),
78 N_("Remove the resizebar of this window.") },
80 { "NoCloseButton", { .no_close_button
= 1 }, N_("Disable close button"),
81 N_("Remove the `close window' button of this window.") },
83 { "NoMiniaturizeButton", { .no_miniaturize_button
= 1 }, N_("Disable miniaturize button"),
84 N_("Remove the `miniaturize window' button of the window.") },
86 { "NoBorder", { .no_border
= 1 }, N_("Disable border"),
87 N_("Remove the 1 pixel black border around the window.") },
89 { "KeepOnTop", { .floating
= 1 }, N_("Keep on top (floating)"),
90 N_("Keep the window over other windows, not allowing\n"
91 "them to cover it.") },
93 { "KeepOnBottom", { .sunken
= 1 }, N_("Keep at bottom (sunken)"),
94 N_("Keep the window under all other windows.") },
96 { "Omnipresent", { .omnipresent
= 1 }, N_("Omnipresent"),
97 N_("Make window present in all workspaces.") },
99 { "StartMiniaturized", { .start_miniaturized
= 1 }, N_("Start miniaturized"),
100 N_("Make the window be automatically miniaturized when it's\n"
103 { "StartMaximized", { .start_maximized
= 1 }, N_("Start maximized"),
104 N_("Make the window be automatically maximized when it's\n"
107 { "FullMaximize", { .full_maximize
= 1 }, N_("Full screen maximization"),
108 N_("Make the window use the whole screen space when it's\n"
109 "maximized. The titlebar and resizebar will be moved\n"
110 "to outside the screen.") }
112 }, advanced_option
[] = {
113 { "NoKeyBindings", { .no_bind_keys
= 1 }, N_("Do not bind keyboard shortcuts"),
114 N_("Do not bind keyboard shortcuts from Window Maker\n"
115 "when this window is focused. This will allow the\n"
116 "window to receive all key combinations regardless\n"
117 "of your shortcut configuration.") },
119 { "NoMouseBindings", { .no_bind_mouse
= 1 }, N_("Do not bind mouse clicks"),
120 N_("Do not bind mouse actions, such as `Alt'+drag\n"
121 "in the window (when Alt is the modifier you have\n"
124 { "SkipWindowList", { .skip_window_list
= 1 }, N_("Do not show in the window list"),
125 N_("Do not list the window in the window list menu.") },
127 { "SkipSwitchPanel", { .skip_switchpanel
= 1 }, N_("Do not show in the switch panel"),
128 N_("Do not include in switch panel while cycling windows.") },
130 { "Unfocusable", { .no_focusable
= 1 }, N_("Do not let it take focus"),
131 N_("Do not let the window take keyboard focus when you\n"
134 { "KeepInsideScreen", { .dont_move_off
= 1 }, N_("Keep inside screen"),
135 N_("Do not allow the window to move itself completely\n"
136 "outside the screen. For bug compatibility.\n") },
138 { "NoHideOthers", { .no_hide_others
= 1 }, N_("Ignore 'Hide Others'"),
139 N_("Do not hide the window when issuing the\n"
140 "`HideOthers' command.") },
142 { "DontSaveSession", { .dont_save_session
= 1 }, N_("Ignore 'Save Session'"),
143 N_("Do not save the associated application in the\n"
144 "session's state, so that it won't be restarted\n"
145 "together with other applications when Window Maker\n"
148 { "EmulateAppIcon", { .emulate_appicon
= 1 }, N_("Emulate application icon"),
149 N_("Make this window act as an application that provides\n"
150 "enough information to Window Maker for a dockable\n"
151 "application icon to be created.") },
153 { "FocusAcrossWorkspace", { .focus_across_wksp
= 1 }, N_("Focus across workspaces"),
154 N_("Allow Window Maker to switch workspace to satisfy\n"
155 "a focus request (annoying).") },
157 { "NoMiniaturizable", { .no_miniaturizable
= 1 }, N_("Do not let it be minimized"),
158 N_("Do not let the window of this application be\n"
161 #ifdef XKB_BUTTON_HINT
162 ,{ "NoLanguageButton", { .no_language_button
= 1 }, N_("Disable language button"),
163 N_("Remove the `toggle language' button of the window.") }
166 }, application_attr
[] = {
167 { "StartHidden", { .start_hidden
= 1 }, N_("Start hidden"),
168 N_("Automatically hide application when it's started.") },
170 { "NoAppIcon", { .no_appicon
= 1 }, N_("No application icon"),
171 N_("Disable the application icon for the application.\n"
172 "Note that you won't be able to dock it anymore,\n"
173 "and any icons that are already docked will stop\n"
174 "working correctly.") },
176 { "SharedAppIcon", { .shared_appicon
= 1 }, N_("Shared application icon"),
177 N_("Use a single shared application icon for all of\n"
178 "the instances of this application.\n") }
181 typedef struct InspectorPanel
{
182 struct InspectorPanel
*nextPtr
;
185 WWindow
*inspected
; /* the window that's being inspected */
193 WMPopUpButton
*pagePopUp
;
195 /* first page. general stuff */
204 /* second page. attributes */
206 WMButton
*attrChk
[sizeof(window_attribute
) / sizeof(window_attribute
[0])];
208 /* 3rd page. more attributes */
210 WMButton
*moreChk
[sizeof(advanced_option
) / sizeof(advanced_option
[0])];
212 /* 4th page. icon and workspace */
216 WMTextField
*fileText
;
218 WMButton
*browseIconBtn
;
222 /* 5th page. application wide attributes */
224 WMButton
*appChk
[sizeof(application_attr
) / sizeof(application_attr
[0])];
227 unsigned int destroyed
:1;
228 unsigned int choosingIcon
:1;
231 static InspectorPanel
*panelList
= NULL
;
234 * We are supposed to use the 'key_name' from the the 'window_attribute' structure when we want to
235 * save the user choice to the database, but as we will need to convert that name into a Property
236 * List, we use here a Cache of Property Lists, generated only once, which can be reused. It will
237 * also save on memory because of the re-use of the same storage space instead of allocating a new
240 static WMPropList
*pl_attribute
[sizeof(window_attribute
) / sizeof(window_attribute
[0])] = { [0] = NULL
};
241 static WMPropList
*pl_advoptions
[sizeof(advanced_option
) / sizeof(advanced_option
[0])];
242 static WMPropList
*pl_appattrib
[sizeof(application_attr
) / sizeof(application_attr
[0])];
244 static WMPropList
*AAlwaysUserIcon
;
245 static WMPropList
*AStartWorkspace
;
246 static WMPropList
*AIcon
;
248 /* application wide options */
249 static WMPropList
*AnyWindow
;
250 static WMPropList
*EmptyString
;
251 static WMPropList
*Yes
, *No
;
253 static char *spec_text
;
254 static void applySettings(WMWidget
*button
, void *panel
);
256 static InspectorPanel
*createInspectorForWindow(WWindow
*wwin
, int xpos
, int ypos
, Bool showSelectPanel
);
258 static void create_tab_window_attributes(WWindow
*wwin
, InspectorPanel
*panel
, int frame_width
);
259 static void create_tab_window_advanced(WWindow
*wwin
, InspectorPanel
*panel
, int frame_width
);
260 static void create_tab_icon_workspace(WWindow
*wwin
, InspectorPanel
*panel
);
261 static void create_tab_app_specific(WWindow
*wwin
, InspectorPanel
*panel
, int frame_width
);
264 * These 3 functions sets/clear/read a bit inside a bit-field in a generic manner;
265 * they uses binary operators to be as effiscient as possible, also counting on compiler's
266 * optimisations because the bit-field structure will fit in only 1 or 2 int but it is
267 * depending on the processor architecture.
269 static inline void set_attr_flag(WWindowAttributes
*target
, const WWindowAttributes
*flag
)
272 const unsigned char *src
;
275 src
= (const unsigned char *) flag
;
276 dst
= (unsigned char *) target
;
278 for (i
= 0; i
< sizeof(*flag
); i
++)
282 static inline void clear_attr_flag(WWindowAttributes
*target
, const WWindowAttributes
*flag
)
285 const unsigned char *src
;
288 src
= (const unsigned char *) flag
;
289 dst
= (unsigned char *) target
;
291 for (i
= 0; i
< sizeof(*flag
); i
++)
295 static inline int get_attr_flag(const WWindowAttributes
*from
, const WWindowAttributes
*flag
)
298 const unsigned char *xpect
, *field
;
300 field
= (const unsigned char *) from
;
301 xpect
= (const unsigned char *) flag
;
303 for (i
= 0; i
< sizeof(*flag
); i
++)
304 if (field
[i
] & xpect
[i
])
311 * This function is creating the Property List for the cache mentionned above
313 static void make_keys(void)
317 if (pl_attribute
[0] != NULL
)
320 for (i
= 0; i
< wlengthof(window_attribute
); i
++)
321 pl_attribute
[i
] = WMCreatePLString(window_attribute
[i
].key_name
);
323 for (i
= 0; i
< wlengthof(advanced_option
); i
++)
324 pl_advoptions
[i
] = WMCreatePLString(advanced_option
[i
].key_name
);
326 for (i
= 0; i
< wlengthof(application_attr
); i
++)
327 pl_appattrib
[i
] = WMCreatePLString(application_attr
[i
].key_name
);
329 AIcon
= WMCreatePLString("Icon");
330 AAlwaysUserIcon
= WMCreatePLString("AlwaysUserIcon");
332 AStartWorkspace
= WMCreatePLString("StartWorkspace");
334 AnyWindow
= WMCreatePLString("*");
335 EmptyString
= WMCreatePLString("");
336 Yes
= WMCreatePLString("Yes");
337 No
= WMCreatePLString("No");
340 static void freeInspector(InspectorPanel
*panel
)
342 panel
->destroyed
= 1;
344 if (panel
->choosingIcon
)
347 WMDestroyWidget(panel
->win
);
348 XDestroyWindow(dpy
, panel
->parent
);
352 static void destroyInspector(WCoreWindow
*foo
, void *data
, XEvent
*event
)
354 InspectorPanel
*panel
, *tmp
;
356 /* Parameter not used, but tell the compiler that it is ok */
361 while (panel
->frame
!= data
)
362 panel
= panel
->nextPtr
;
364 if (panelList
== panel
) {
365 panelList
= panel
->nextPtr
;
368 while (tmp
->nextPtr
!= panel
)
371 tmp
->nextPtr
= panel
->nextPtr
;
373 panel
->inspected
->flags
.inspector_open
= 0;
374 panel
->inspected
->inspector
= NULL
;
376 WMRemoveNotificationObserver(panel
);
378 wWindowUnmap(panel
->frame
);
379 wUnmanageWindow(panel
->frame
, True
, False
);
381 freeInspector(panel
);
384 void wDestroyInspectorPanels(void)
386 InspectorPanel
*panel
;
388 while (panelList
!= NULL
) {
390 panelList
= panelList
->nextPtr
;
391 wUnmanageWindow(panel
->frame
, False
, False
);
392 WMDestroyWidget(panel
->win
);
394 panel
->inspected
->flags
.inspector_open
= 0;
395 panel
->inspected
->inspector
= NULL
;
401 static void changePage(WMWidget
*bPtr
, void *client_data
)
403 InspectorPanel
*panel
= (InspectorPanel
*) client_data
;
406 page
= WMGetPopUpButtonSelectedItem(bPtr
);
409 WMMapWidget(panel
->specFrm
);
410 WMMapWidget(panel
->specLbl
);
411 } else if (page
== 1) {
412 WMMapWidget(panel
->attrFrm
);
413 } else if (page
== 2) {
414 WMMapWidget(panel
->moreFrm
);
415 } else if (page
== 3) {
416 WMMapWidget(panel
->iconFrm
);
417 WMMapWidget(panel
->wsFrm
);
419 WMMapWidget(panel
->appFrm
);
423 WMUnmapWidget(panel
->specFrm
);
424 WMUnmapWidget(panel
->specLbl
);
427 WMUnmapWidget(panel
->attrFrm
);
429 WMUnmapWidget(panel
->moreFrm
);
431 WMUnmapWidget(panel
->iconFrm
);
432 WMUnmapWidget(panel
->wsFrm
);
434 if (page
!= 4 && panel
->appFrm
)
435 WMUnmapWidget(panel
->appFrm
);
438 static int showIconFor(WMScreen
*scrPtr
, InspectorPanel
*panel
, const char *wm_instance
, const char *wm_class
, int flags
)
440 WMPixmap
*pixmap
= (WMPixmap
*) NULL
;
441 char *file
= NULL
, *path
= NULL
;
443 if ((flags
& USE_TEXT_FIELD
) != 0) {
444 file
= WMGetTextFieldText(panel
->fileText
);
445 if (file
&& file
[0] == 0) {
449 } else if (flags
& REVERT_TO_DEFAULT
) {
452 /* Get the application icon, default NOT included */
453 db_icon
= wDefaultGetIconFile(wm_instance
, wm_class
, False
);
454 if (db_icon
!= NULL
) {
455 file
= wstrdup(db_icon
);
456 flags
|= UPDATE_TEXT_FIELD
;
460 if ((flags
& UPDATE_TEXT_FIELD
) != 0)
461 WMSetTextFieldText(panel
->fileText
, file
);
464 path
= FindImage(wPreferences
.icon_path
, file
);
468 int len
= strlen(file
) + 80;
471 snprintf(buf
, len
, _("Could not find icon \"%s\" specified for this window"), file
);
472 wMessageDialog(panel
->frame
->screen_ptr
, _("Error"), buf
, _("OK"), NULL
, NULL
);
478 pixmap
= WMCreatePixmapFromFile(scrPtr
, path
);
483 int len
= strlen(file
) + 80;
486 snprintf(buf
, len
, _("Could not open specified icon \"%s\":%s"),
487 file
, RMessageForError(RErrorCode
));
488 wMessageDialog(panel
->frame
->screen_ptr
, _("Error"), buf
, _("OK"), NULL
, NULL
);
496 WMSetLabelImage(panel
->iconLbl
, pixmap
);
498 WMReleasePixmap(pixmap
);
503 static int getBool(WMPropList
*value
)
507 if (!WMIsPLString(value
))
510 val
= WMGetFromPLString(value
);
514 if ((val
[1] == '\0' &&
515 (val
[0] == 'y' || val
[0] == 'Y' || val
[0] == 'T' ||
516 val
[0] == 't' || val
[0] == '1')) ||
517 (strcasecmp(val
, "YES") == 0 || strcasecmp(val
, "TRUE") == 0)) {
519 } else if ((val
[1] == '\0' &&
520 (val
[0] == 'n' || val
[0] == 'N' || val
[0] == 'F' ||
521 val
[0] == 'f' || val
[0] == '0')) ||
522 (strcasecmp(val
, "NO") == 0 || strcasecmp(val
, "FALSE") == 0)) {
525 wwarning(_("can't convert \"%s\" to boolean"), val
);
530 /* Will insert the attribute = value; pair in window's list,
531 * if it's different from the defaults.
532 * Defaults means either defaults database, or attributes saved
533 * for the default window "*". This is to let one revert options that are
534 * global because they were saved for all windows ("*"). */
536 insertAttribute(WMPropList
*dict
, WMPropList
*window
, WMPropList
*attr
, WMPropList
*value
, int flags
)
538 WMPropList
*def_win
, *def_value
= NULL
;
539 int update
= 0, modified
= 0;
541 if (!(flags
& UPDATE_DEFAULTS
) && dict
) {
542 def_win
= WMGetFromPLDictionary(dict
, AnyWindow
);
544 def_value
= WMGetFromPLDictionary(def_win
, attr
);
547 /* If we could not find defaults in database, fall to hardcoded values.
548 * Also this is true if we save defaults for all windows */
550 def_value
= ((flags
& IS_BOOLEAN
) != 0) ? No
: EmptyString
;
552 if (flags
& IS_BOOLEAN
)
553 update
= (getBool(value
) != getBool(def_value
));
555 update
= !WMIsPropListEqualTo(value
, def_value
);
558 WMPutInPLDictionary(window
, attr
, value
);
565 static void saveSettings(WMWidget
*button
, void *client_data
)
567 InspectorPanel
*panel
= (InspectorPanel
*) client_data
;
568 WWindow
*wwin
= panel
->inspected
;
569 WDDomain
*db
= w_global
.domain
.window_attr
;
570 WMPropList
*dict
= NULL
;
571 WMPropList
*winDic
, *appDic
, *value
, *value1
, *key
= NULL
, *key2
;
572 char *icon_file
, *buf1
, *buf2
;
573 int flags
= 0, i
= 0, different
= 0, different2
= 0;
575 /* Save will apply the changes and save them */
576 applySettings(panel
->applyBtn
, panel
);
578 if (WMGetButtonSelected(panel
->instRb
) != 0) {
579 key
= WMCreatePLString(wwin
->wm_instance
);
580 } else if (WMGetButtonSelected(panel
->clsRb
) != 0) {
581 key
= WMCreatePLString(wwin
->wm_class
);
582 } else if (WMGetButtonSelected(panel
->bothRb
) != 0) {
583 buf1
= StrConcatDot(wwin
->wm_instance
, wwin
->wm_class
);
584 key
= WMCreatePLString(buf1
);
586 } else if (WMGetButtonSelected(panel
->defaultRb
) != 0) {
587 key
= WMRetainPropList(AnyWindow
);
588 flags
= UPDATE_DEFAULTS
;
594 dict
= db
->dictionary
;
596 dict
= WMCreatePLDictionary(NULL
, NULL
);
598 db
->dictionary
= dict
;
600 WMReleasePropList(key
);
605 if (showIconFor(WMWidgetScreen(button
), panel
, NULL
, NULL
, USE_TEXT_FIELD
) < 0)
608 WMPLSetCaseSensitive(True
);
610 winDic
= WMCreatePLDictionary(NULL
, NULL
);
611 appDic
= WMCreatePLDictionary(NULL
, NULL
);
613 /* Save the icon info */
614 /* The flag "Ignore client suplied icon is not selected" */
616 snprintf(buf1
, 4, "%s", (WMGetButtonSelected(panel
->alwChk
) != 0) ? "Yes" : "No");
617 value1
= WMCreatePLString(buf1
);
618 different
|= insertAttribute(dict
, winDic
, AAlwaysUserIcon
, value1
, flags
);
619 WMReleasePropList(value1
);
622 /* The icon filename (if exists) */
623 icon_file
= WMGetTextFieldText(panel
->fileText
);
624 if (icon_file
!= NULL
) {
625 if (icon_file
[0] != '\0') {
626 value
= WMCreatePLString(icon_file
);
627 different
|= insertAttribute(dict
, winDic
, AIcon
, value
, flags
);
628 different2
|= insertAttribute(dict
, appDic
, AIcon
, value
, flags
);
629 WMReleasePropList(value
);
634 i
= WMGetPopUpButtonSelectedItem(panel
->wsP
) - 1;
635 if (i
>= 0 && i
< panel
->frame
->screen_ptr
->workspace_count
) {
636 value
= WMCreatePLString(panel
->frame
->screen_ptr
->workspaces
[i
]->name
);
637 different
|= insertAttribute(dict
, winDic
, AStartWorkspace
, value
, flags
);
638 WMReleasePropList(value
);
643 /* Attributes... --> Window Attributes */
644 for (i
= 0; i
< wlengthof(window_attribute
); i
++) {
645 value
= (WMGetButtonSelected(panel
->attrChk
[i
]) != 0) ? Yes
: No
;
646 different
|= insertAttribute(dict
, winDic
, pl_attribute
[i
], value
, flags
);
649 /* Attributes... --> Advanced Options */
650 for (i
= 0; i
< wlengthof(advanced_option
); i
++) {
651 value
= (WMGetButtonSelected(panel
->moreChk
[i
]) != 0) ? Yes
: No
;
652 different
|= insertAttribute(dict
, winDic
, pl_advoptions
[i
], value
, flags
);
655 /* Attributes... --> Application Specific */
656 if (wwin
->main_window
!= None
&& wApplicationOf(wwin
->main_window
) != NULL
) {
657 for (i
= 0; i
< wlengthof(application_attr
); i
++) {
658 value
= (WMGetButtonSelected(panel
->appChk
[i
]) != 0) ? Yes
: No
;
659 different2
|= insertAttribute(dict
, appDic
, pl_appattrib
[i
], value
, flags
);
663 if (wwin
->fake_group
) {
664 key2
= WMCreatePLString(wwin
->fake_group
->identifier
);
665 if (WMIsPropListEqualTo(key
, key2
)) {
666 WMMergePLDictionaries(winDic
, appDic
, True
);
667 different
|= different2
;
669 WMRemoveFromPLDictionary(dict
, key2
);
671 WMPutInPLDictionary(dict
, key2
, appDic
);
673 WMReleasePropList(key2
);
674 } else if (wwin
->main_window
!= wwin
->client_win
) {
675 WApplication
*wapp
= wApplicationOf(wwin
->main_window
);
678 buf2
= StrConcatDot(wapp
->main_window_desc
->wm_instance
,
679 wapp
->main_window_desc
->wm_class
);
680 key2
= WMCreatePLString(buf2
);
683 if (WMIsPropListEqualTo(key
, key2
)) {
684 WMMergePLDictionaries(winDic
, appDic
, True
);
685 different
|= different2
;
687 WMRemoveFromPLDictionary(dict
, key2
);
689 WMPutInPLDictionary(dict
, key2
, appDic
);
691 WMReleasePropList(key2
);
694 WMMergePLDictionaries(winDic
, appDic
, True
);
695 different
|= different2
;
697 WMReleasePropList(appDic
);
699 WMRemoveFromPLDictionary(dict
, key
);
701 WMPutInPLDictionary(dict
, key
, winDic
);
703 WMReleasePropList(key
);
704 WMReleasePropList(winDic
);
706 UpdateDomainFile(db
);
709 WMPLSetCaseSensitive(False
);
712 static void applySettings(WMWidget
*button
, void *client_data
)
714 InspectorPanel
*panel
= (InspectorPanel
*) client_data
;
715 WWindow
*wwin
= panel
->inspected
;
716 WApplication
*wapp
= wApplicationOf(wwin
->main_window
);
717 int old_skip_window_list
, old_omnipresent
, old_no_bind_keys
, old_no_bind_mouse
;
720 old_skip_window_list
= WFLAGP(wwin
, skip_window_list
);
721 old_omnipresent
= WFLAGP(wwin
, omnipresent
);
722 old_no_bind_keys
= WFLAGP(wwin
, no_bind_keys
);
723 old_no_bind_mouse
= WFLAGP(wwin
, no_bind_mouse
);
725 showIconFor(WMWidgetScreen(button
), panel
, NULL
, NULL
, USE_TEXT_FIELD
);
727 /* Attributes... --> Window Attributes */
728 for (i
= 0; i
< wlengthof(window_attribute
); i
++) {
729 if (WMGetButtonSelected(panel
->attrChk
[i
]))
730 set_attr_flag(&wwin
->user_flags
, &window_attribute
[i
].flag
);
732 clear_attr_flag(&wwin
->user_flags
, &window_attribute
[i
].flag
);
734 set_attr_flag(&wwin
->defined_user_flags
, &window_attribute
[i
].flag
);
737 /* Attributes... --> Advanced Options */
738 for (i
= 0; i
< wlengthof(advanced_option
); i
++) {
739 if (WMGetButtonSelected(panel
->moreChk
[i
]))
740 set_attr_flag(&wwin
->user_flags
, &advanced_option
[i
].flag
);
742 clear_attr_flag(&wwin
->user_flags
, &advanced_option
[i
].flag
);
744 set_attr_flag(&wwin
->defined_user_flags
, &advanced_option
[i
].flag
);
747 WSETUFLAG(wwin
, always_user_icon
, WMGetButtonSelected(panel
->alwChk
));
749 if (WFLAGP(wwin
, no_titlebar
) && wwin
->flags
.shaded
)
750 wUnshadeWindow(wwin
);
752 WSETUFLAG(wwin
, no_shadeable
, WFLAGP(wwin
, no_titlebar
));
755 * Update the window level according to AlwaysOnTop/AlwaysOnBotton
756 * if the level did not change, ChangeStackingLevel will do nothing anyway
758 if (WFLAGP(wwin
, floating
))
759 ChangeStackingLevel(wwin
->frame
->core
, WMFloatingLevel
);
760 else if (WFLAGP(wwin
, sunken
))
761 ChangeStackingLevel(wwin
->frame
->core
, WMSunkenLevel
);
763 ChangeStackingLevel(wwin
->frame
->core
, WMNormalLevel
);
765 wwin
->flags
.omnipresent
= 0;
767 if (WFLAGP(wwin
, skip_window_list
) != old_skip_window_list
) {
768 UpdateSwitchMenu(wwin
->screen_ptr
, wwin
, WFLAGP(wwin
, skip_window_list
)?ACTION_REMOVE
:ACTION_ADD
);
770 if (WFLAGP(wwin
, omnipresent
) != old_omnipresent
)
771 WMPostNotificationName(WMNChangedState
, wwin
, "omnipresent");
774 if (WFLAGP(wwin
, no_bind_keys
) != old_no_bind_keys
) {
775 if (WFLAGP(wwin
, no_bind_keys
))
776 XUngrabKey(dpy
, AnyKey
, AnyModifier
, wwin
->frame
->core
->window
);
778 wWindowSetKeyGrabs(wwin
);
781 if (WFLAGP(wwin
, no_bind_mouse
) != old_no_bind_mouse
)
782 wWindowResetMouseGrabs(wwin
);
784 wwin
->frame
->flags
.need_texture_change
= 1;
785 wWindowConfigureBorders(wwin
);
786 wFrameWindowPaint(wwin
->frame
);
787 wNETWMUpdateActions(wwin
, False
);
789 /* Can't apply emulate_appicon because it will probably cause problems. */
791 /* do application wide stuff */
792 for (i
= 0; i
< wlengthof(application_attr
); i
++) {
793 if (WMGetButtonSelected(panel
->appChk
[i
]))
794 set_attr_flag(&wapp
->main_window_desc
->user_flags
, &application_attr
[i
].flag
);
796 clear_attr_flag(&wapp
->main_window_desc
->user_flags
, &application_attr
[i
].flag
);
798 set_attr_flag(&wapp
->main_window_desc
->defined_user_flags
, &application_attr
[i
].flag
);
801 if (WFLAGP(wapp
->main_window_desc
, no_appicon
))
802 unpaint_app_icon(wapp
);
804 paint_app_icon(wapp
);
806 char *file
= WMGetTextFieldText(panel
->fileText
);
812 /* If always_user_icon flag is set, but the user icon is not set
813 * we use client supplied icon and we unset the flag */
814 if ((WFLAGP(wwin
, always_user_icon
) && (!file
))) {
815 /* Show the warning */
820 snprintf(buf
, len
, _("Ignore client supplied icon is set, but icon filename textbox is empty. Using client supplied icon"));
821 wMessageDialog(panel
->frame
->screen_ptr
, _("Warning"), buf
, _("OK"), NULL
, NULL
);
825 /* Change the flags */
826 WSETUFLAG(wwin
, always_user_icon
, 0);
827 WMSetButtonSelected(panel
->alwChk
, 0);
830 /* After test the always_user_icon flag value before,
831 * the "else" block is used only if the flag is set and
832 * the icon text box has an icon path */
833 if (!WFLAGP(wwin
, always_user_icon
)) {
834 /* Change App Icon image, using the icon provided by the client */
835 if (wapp
->app_icon
) {
836 RImage
*image
= get_rimage_icon_from_wm_hints(wapp
->app_icon
->icon
);
838 set_icon_image_from_image(wapp
->app_icon
->icon
, image
);
839 update_icon_pixmap(wapp
->app_icon
->icon
);
841 wIconUpdate(wapp
->app_icon
->icon
);
845 /* Change icon image if the app is minimized,
846 * using the icon provided by the client */
848 RImage
*image
= get_rimage_icon_from_wm_hints(wwin
->icon
);
850 set_icon_image_from_image(wwin
->icon
, image
);
851 update_icon_pixmap(wwin
->icon
);
853 wIconUpdate(wwin
->icon
);
857 /* Change App Icon image */
859 wIconChangeImageFile(wapp
->app_icon
->icon
, file
);
861 /* Change icon image if the app is minimized */
863 wIconChangeImageFile(wwin
->icon
, file
);
870 wNETFrameExtents(wwin
);
873 static void revertSettings(WMWidget
*button
, void *client_data
)
875 InspectorPanel
*panel
= (InspectorPanel
*) client_data
;
876 WWindow
*wwin
= panel
->inspected
;
877 WApplication
*wapp
= wApplicationOf(wwin
->main_window
);
878 int i
, n
, workspace
, level
;
879 char *wm_instance
= NULL
, *wm_class
= NULL
;
881 /* Parameter not used, but tell the compiler that it is ok */
884 if (panel
->instRb
&& WMGetButtonSelected(panel
->instRb
) != 0)
885 wm_instance
= wwin
->wm_instance
;
886 else if (panel
->clsRb
&& WMGetButtonSelected(panel
->clsRb
) != 0)
887 wm_class
= wwin
->wm_class
;
888 else if (panel
->bothRb
&& WMGetButtonSelected(panel
->bothRb
) != 0) {
889 wm_instance
= wwin
->wm_instance
;
890 wm_class
= wwin
->wm_class
;
893 memset(&wwin
->defined_user_flags
, 0, sizeof(WWindowAttributes
));
894 memset(&wwin
->user_flags
, 0, sizeof(WWindowAttributes
));
895 memset(&wwin
->client_flags
, 0, sizeof(WWindowAttributes
));
897 wWindowSetupInitialAttributes(wwin
, &level
, &workspace
);
899 /* Attributes... --> Window Attributes */
900 for (i
= 0; i
< wlengthof(window_attribute
); i
++) {
901 int is_userdef
, flag
;
903 is_userdef
= get_attr_flag(&wwin
->defined_user_flags
, &window_attribute
[i
].flag
);
905 flag
= get_attr_flag(&wwin
->user_flags
, &window_attribute
[i
].flag
);
907 flag
= get_attr_flag(&wwin
->client_flags
, &window_attribute
[i
].flag
);
909 WMSetButtonSelected(panel
->attrChk
[i
], flag
);
912 /* Attributes... --> Advanced Options */
913 for (i
= 0; i
< wlengthof(advanced_option
); i
++) {
914 int is_userdef
, flag
;
916 is_userdef
= get_attr_flag(&wwin
->defined_user_flags
, &advanced_option
[i
].flag
);
918 flag
= get_attr_flag(&wwin
->user_flags
, &advanced_option
[i
].flag
);
920 flag
= get_attr_flag(&wwin
->client_flags
, &advanced_option
[i
].flag
);
922 WMSetButtonSelected(panel
->moreChk
[i
], flag
);
925 /* Attributes... --> Application Specific */
926 if (panel
->appFrm
&& wapp
) {
927 for (i
= 0; i
< wlengthof(application_attr
); i
++) {
928 int is_userdef
, flag
= 0;
930 is_userdef
= get_attr_flag(&wapp
->main_window_desc
->defined_user_flags
, &application_attr
[i
].flag
);
932 flag
= get_attr_flag(&wapp
->main_window_desc
->user_flags
, &application_attr
[i
].flag
);
934 flag
= get_attr_flag(&wapp
->main_window_desc
->client_flags
, &application_attr
[i
].flag
);
936 WMSetButtonSelected(panel
->appChk
[i
], flag
);
939 WMSetButtonSelected(panel
->alwChk
, WFLAGP(wwin
, always_user_icon
));
941 showIconFor(WMWidgetScreen(panel
->alwChk
), panel
, wm_instance
, wm_class
, REVERT_TO_DEFAULT
);
943 n
= wDefaultGetStartWorkspace(wwin
->screen_ptr
, wm_instance
, wm_class
);
945 if (n
>= 0 && n
< wwin
->screen_ptr
->workspace_count
)
946 WMSetPopUpButtonSelectedItem(panel
->wsP
, n
+ 1);
948 WMSetPopUpButtonSelectedItem(panel
->wsP
, 0);
950 /* must auto apply, so that there wno't be internal
951 * inconsistencies between the state in the flags and
952 * the actual state of the window */
953 applySettings(panel
->applyBtn
, panel
);
956 static void chooseIconCallback(WMWidget
*self
, void *clientData
)
959 InspectorPanel
*panel
= (InspectorPanel
*) clientData
;
962 panel
->choosingIcon
= 1;
964 WMSetButtonEnabled(panel
->browseIconBtn
, False
);
966 result
= wIconChooserDialog(panel
->frame
->screen_ptr
, &file
,
967 panel
->inspected
->wm_instance
,
968 panel
->inspected
->wm_class
);
970 panel
->choosingIcon
= 0;
972 if (!panel
->destroyed
) { /* kluge */
974 WMSetTextFieldText(panel
->fileText
, file
);
975 showIconFor(WMWidgetScreen(self
), panel
, NULL
, NULL
, USE_TEXT_FIELD
);
977 WMSetButtonEnabled(panel
->browseIconBtn
, True
);
979 freeInspector(panel
);
985 static void textEditedObserver(void *observerData
, WMNotification
*notification
)
987 InspectorPanel
*panel
= (InspectorPanel
*) observerData
;
989 if ((long)WMGetNotificationClientData(notification
) != WMReturnTextMovement
)
992 showIconFor(WMWidgetScreen(panel
->win
), panel
, NULL
, NULL
, USE_TEXT_FIELD
);
995 static void selectSpecification(WMWidget
*bPtr
, void *data
)
997 InspectorPanel
*panel
= (InspectorPanel
*) data
;
999 WWindow
*wwin
= panel
->inspected
;
1001 if (bPtr
== panel
->defaultRb
&& (wwin
->wm_instance
|| wwin
->wm_class
))
1002 WMSetButtonEnabled(panel
->applyBtn
, False
);
1004 WMSetButtonEnabled(panel
->applyBtn
, True
);
1006 snprintf(str
, sizeof(str
),
1007 _("Inspecting %s.%s"),
1008 wwin
->wm_instance
? wwin
->wm_instance
: "?",
1009 wwin
->wm_class
? wwin
->wm_class
: "?");
1011 wFrameWindowChangeTitle(panel
->frame
->frame
, str
);
1014 static void selectWindow(WMWidget
*bPtr
, void *data
)
1016 InspectorPanel
*panel
= (InspectorPanel
*) data
;
1017 WWindow
*wwin
= panel
->inspected
;
1018 WScreen
*scr
= wwin
->screen_ptr
;
1022 /* Parameter not used, but tell the compiler that it is ok */
1025 if (XGrabPointer(dpy
, scr
->root_win
, True
,
1026 ButtonPressMask
, GrabModeAsync
, GrabModeAsync
, None
,
1027 wPreferences
.cursor
[WCUR_SELECT
], CurrentTime
) != GrabSuccess
) {
1028 wwarning("could not grab mouse pointer");
1032 WMSetLabelText(panel
->specLbl
, _("Click in the window you wish to inspect."));
1033 WMMaskEvent(dpy
, ButtonPressMask
, &event
);
1034 XUngrabPointer(dpy
, CurrentTime
);
1036 iwin
= wWindowFor(event
.xbutton
.subwindow
);
1037 if (iwin
&& !iwin
->flags
.internal_window
&& iwin
!= wwin
&& !iwin
->flags
.inspector_open
) {
1038 iwin
->flags
.inspector_open
= 1;
1039 iwin
->inspector
= createInspectorForWindow(iwin
,
1040 panel
->frame
->frame_x
, panel
->frame
->frame_y
, True
);
1041 wCloseInspectorForWindow(wwin
);
1043 WMSetLabelText(panel
->specLbl
, spec_text
);
1047 static InspectorPanel
*createInspectorForWindow(WWindow
*wwin
, int xpos
, int ypos
, Bool showSelectPanel
)
1049 WScreen
*scr
= wwin
->screen_ptr
;
1050 InspectorPanel
*panel
;
1052 char *str
= NULL
, *tmp
= NULL
;
1053 int x
, y
, btn_width
, frame_width
;
1054 WMButton
*selectedBtn
= NULL
;
1056 spec_text
= _("The configuration will apply to all\n"
1057 "windows that have their WM_CLASS\n"
1058 "property set to the above selected\n" "name, when saved.");
1060 panel
= wmalloc(sizeof(InspectorPanel
));
1061 memset(panel
, 0, sizeof(InspectorPanel
));
1063 panel
->destroyed
= 0;
1064 panel
->inspected
= wwin
;
1065 panel
->nextPtr
= panelList
;
1067 panel
->win
= WMCreateWindow(scr
->wmscreen
, "windowInspector");
1068 WMResizeWidget(panel
->win
, PWIDTH
, PHEIGHT
);
1070 /**** create common stuff ****/
1071 /* command buttons */
1072 btn_width
= (PWIDTH
- (2 * 15) - (2 * 10)) / 3;
1073 panel
->saveBtn
= WMCreateCommandButton(panel
->win
);
1074 WMSetButtonAction(panel
->saveBtn
, saveSettings
, panel
);
1075 WMMoveWidget(panel
->saveBtn
, (2 * (btn_width
+ 10)) + 15, PHEIGHT
- 40);
1076 WMSetButtonText(panel
->saveBtn
, _("Save"));
1077 WMResizeWidget(panel
->saveBtn
, btn_width
, 28);
1078 if (wPreferences
.flags
.noupdates
|| !(wwin
->wm_class
|| wwin
->wm_instance
))
1079 WMSetButtonEnabled(panel
->saveBtn
, False
);
1081 panel
->applyBtn
= WMCreateCommandButton(panel
->win
);
1082 WMSetButtonAction(panel
->applyBtn
, applySettings
, panel
);
1083 WMMoveWidget(panel
->applyBtn
, btn_width
+ 10 + 15, PHEIGHT
- 40);
1084 WMSetButtonText(panel
->applyBtn
, _("Apply"));
1085 WMResizeWidget(panel
->applyBtn
, btn_width
, 28);
1087 panel
->revertBtn
= WMCreateCommandButton(panel
->win
);
1088 WMSetButtonAction(panel
->revertBtn
, revertSettings
, panel
);
1089 WMMoveWidget(panel
->revertBtn
, 15, PHEIGHT
- 40);
1090 WMSetButtonText(panel
->revertBtn
, _("Reload"));
1091 WMResizeWidget(panel
->revertBtn
, btn_width
, 28);
1093 /* page selection popup button */
1094 panel
->pagePopUp
= WMCreatePopUpButton(panel
->win
);
1095 WMSetPopUpButtonAction(panel
->pagePopUp
, changePage
, panel
);
1096 WMMoveWidget(panel
->pagePopUp
, 25, 15);
1097 WMResizeWidget(panel
->pagePopUp
, PWIDTH
- 50, 20);
1099 WMAddPopUpButtonItem(panel
->pagePopUp
, _("Window Specification"));
1100 WMAddPopUpButtonItem(panel
->pagePopUp
, _("Window Attributes"));
1101 WMAddPopUpButtonItem(panel
->pagePopUp
, _("Advanced Options"));
1102 WMAddPopUpButtonItem(panel
->pagePopUp
, _("Icon and Initial Workspace"));
1103 WMAddPopUpButtonItem(panel
->pagePopUp
, _("Application Specific"));
1105 /**** window spec ****/
1106 frame_width
= PWIDTH
- (2 * 15);
1108 panel
->specFrm
= WMCreateFrame(panel
->win
);
1109 WMSetFrameTitle(panel
->specFrm
, _("Window Specification"));
1110 WMMoveWidget(panel
->specFrm
, 15, 65);
1111 WMResizeWidget(panel
->specFrm
, frame_width
, 145);
1113 panel
->defaultRb
= WMCreateRadioButton(panel
->specFrm
);
1114 WMMoveWidget(panel
->defaultRb
, 10, 78);
1115 WMResizeWidget(panel
->defaultRb
, frame_width
- (2 * 10), 20);
1116 WMSetButtonText(panel
->defaultRb
, _("Defaults for all windows"));
1117 WMSetButtonSelected(panel
->defaultRb
, False
);
1118 WMSetButtonAction(panel
->defaultRb
, selectSpecification
, panel
);
1120 if (wwin
->wm_class
&& wwin
->wm_instance
) {
1121 tmp
= wstrconcat(wwin
->wm_instance
, ".");
1122 str
= wstrconcat(tmp
, wwin
->wm_class
);
1124 panel
->bothRb
= WMCreateRadioButton(panel
->specFrm
);
1125 WMMoveWidget(panel
->bothRb
, 10, 18);
1126 WMResizeWidget(panel
->bothRb
, frame_width
- (2 * 10), 20);
1127 WMSetButtonText(panel
->bothRb
, str
);
1130 WMGroupButtons(panel
->defaultRb
, panel
->bothRb
);
1133 selectedBtn
= panel
->bothRb
;
1135 WMSetButtonAction(panel
->bothRb
, selectSpecification
, panel
);
1138 if (wwin
->wm_instance
) {
1139 panel
->instRb
= WMCreateRadioButton(panel
->specFrm
);
1140 WMMoveWidget(panel
->instRb
, 10, 38);
1141 WMResizeWidget(panel
->instRb
, frame_width
- (2 * 10), 20);
1142 WMSetButtonText(panel
->instRb
, wwin
->wm_instance
);
1143 WMGroupButtons(panel
->defaultRb
, panel
->instRb
);
1146 selectedBtn
= panel
->instRb
;
1148 WMSetButtonAction(panel
->instRb
, selectSpecification
, panel
);
1151 if (wwin
->wm_class
) {
1152 panel
->clsRb
= WMCreateRadioButton(panel
->specFrm
);
1153 WMMoveWidget(panel
->clsRb
, 10, 58);
1154 WMResizeWidget(panel
->clsRb
, frame_width
- (2 * 10), 20);
1155 WMSetButtonText(panel
->clsRb
, wwin
->wm_class
);
1156 WMGroupButtons(panel
->defaultRb
, panel
->clsRb
);
1159 selectedBtn
= panel
->clsRb
;
1161 WMSetButtonAction(panel
->clsRb
, selectSpecification
, panel
);
1164 panel
->selWinB
= WMCreateCommandButton(panel
->specFrm
);
1165 WMMoveWidget(panel
->selWinB
, 20, 145 - 24 - 10);
1166 WMResizeWidget(panel
->selWinB
, frame_width
- 2 * 10 - 20, 24);
1167 WMSetButtonText(panel
->selWinB
, _("Select window"));
1168 WMSetButtonAction(panel
->selWinB
, selectWindow
, panel
);
1170 panel
->specLbl
= WMCreateLabel(panel
->win
);
1171 WMMoveWidget(panel
->specLbl
, 15, 210);
1172 WMResizeWidget(panel
->specLbl
, frame_width
, 100);
1173 WMSetLabelText(panel
->specLbl
, spec_text
);
1174 WMSetLabelWraps(panel
->specLbl
, True
);
1176 WMSetLabelTextAlignment(panel
->specLbl
, WALeft
);
1178 /**** attributes ****/
1179 create_tab_window_attributes(wwin
, panel
, frame_width
);
1180 create_tab_window_advanced(wwin
, panel
, frame_width
);
1181 create_tab_icon_workspace(wwin
, panel
);
1182 create_tab_app_specific(wwin
, panel
, frame_width
);
1184 /* if the window is a transient, don't let it have a miniaturize button */
1185 if (wwin
->transient_for
!= None
&& wwin
->transient_for
!= scr
->root_win
)
1186 WMSetButtonEnabled(panel
->attrChk
[3], False
);
1188 WMSetButtonEnabled(panel
->attrChk
[3], True
);
1190 if (!wwin
->wm_class
&& !wwin
->wm_instance
)
1191 WMSetPopUpButtonItemEnabled(panel
->pagePopUp
, 0, False
);
1193 WMRealizeWidget(panel
->win
);
1195 WMMapSubwidgets(panel
->win
);
1196 WMMapSubwidgets(panel
->specFrm
);
1197 WMMapSubwidgets(panel
->attrFrm
);
1198 WMMapSubwidgets(panel
->moreFrm
);
1199 WMMapSubwidgets(panel
->iconFrm
);
1200 WMMapSubwidgets(panel
->wsFrm
);
1202 WMMapSubwidgets(panel
->appFrm
);
1204 if (showSelectPanel
) {
1205 WMSetPopUpButtonSelectedItem(panel
->pagePopUp
, 0);
1206 changePage(panel
->pagePopUp
, panel
);
1208 WMSetPopUpButtonSelectedItem(panel
->pagePopUp
, 1);
1209 changePage(panel
->pagePopUp
, panel
);
1212 parent
= XCreateSimpleWindow(dpy
, scr
->root_win
, 0, 0, PWIDTH
, PHEIGHT
, 0, 0, 0);
1213 XSelectInput(dpy
, parent
, KeyPressMask
| KeyReleaseMask
);
1214 panel
->parent
= parent
;
1215 XReparentWindow(dpy
, WMWidgetXID(panel
->win
), parent
, 0, 0);
1217 WMMapWidget(panel
->win
);
1219 XSetTransientForHint(dpy
, parent
, wwin
->client_win
);
1221 if (xpos
== UNDEFINED_POS
) {
1222 x
= wwin
->frame_x
+ wwin
->frame
->core
->width
/ 2;
1223 y
= wwin
->frame_y
+ wwin
->frame
->top_width
* 2;
1224 if (y
+ PHEIGHT
> scr
->scr_height
)
1225 y
= scr
->scr_height
- PHEIGHT
- 30;
1226 if (x
+ PWIDTH
> scr
->scr_width
)
1227 x
= scr
->scr_width
- PWIDTH
;
1233 panel
->frame
= wManageInternalWindow(scr
, parent
, wwin
->client_win
, "Inspector", x
, y
, PWIDTH
, PHEIGHT
);
1236 selectedBtn
= panel
->defaultRb
;
1238 WMSetButtonSelected(selectedBtn
, True
);
1239 selectSpecification(selectedBtn
, panel
);
1241 /* kluge to know who should get the key events */
1242 panel
->frame
->client_leader
= WMWidgetXID(panel
->win
);
1244 panel
->frame
->client_flags
.no_closable
= 0;
1245 panel
->frame
->client_flags
.no_close_button
= 0;
1246 wWindowUpdateButtonImages(panel
->frame
);
1247 wFrameWindowShowButton(panel
->frame
->frame
, WFF_RIGHT_BUTTON
);
1248 panel
->frame
->frame
->on_click_right
= destroyInspector
;
1250 wWindowMap(panel
->frame
);
1252 showIconFor(WMWidgetScreen(panel
->alwChk
), panel
, wwin
->wm_instance
, wwin
->wm_class
, UPDATE_TEXT_FIELD
);
1257 void wShowInspectorForWindow(WWindow
*wwin
)
1259 if (wwin
->flags
.inspector_open
)
1262 WMSetBalloonEnabled(wwin
->screen_ptr
->wmscreen
, wPreferences
.help_balloon
);
1265 wwin
->flags
.inspector_open
= 1;
1266 wwin
->inspector
= createInspectorForWindow(wwin
, UNDEFINED_POS
, UNDEFINED_POS
, False
);
1269 void wHideInspectorForWindow(WWindow
*wwin
)
1271 WWindow
*pwin
= wwin
->inspector
->frame
;
1274 pwin
->flags
.hidden
= 1;
1276 wClientSetState(pwin
, IconicState
, None
);
1279 void wUnhideInspectorForWindow(WWindow
*wwin
)
1281 WWindow
*pwin
= wwin
->inspector
->frame
;
1283 pwin
->flags
.hidden
= 0;
1284 pwin
->flags
.mapped
= 1;
1285 XMapWindow(dpy
, pwin
->client_win
);
1286 XMapWindow(dpy
, pwin
->frame
->core
->window
);
1287 wClientSetState(pwin
, NormalState
, None
);
1290 WWindow
*wGetWindowOfInspectorForWindow(WWindow
*wwin
)
1292 if (!wwin
->inspector
)
1295 assert(wwin
->flags
.inspector_open
!= 0);
1296 return wwin
->inspector
->frame
;
1299 void wCloseInspectorForWindow(WWindow
*wwin
)
1301 WWindow
*pwin
= wwin
->inspector
->frame
; /* the inspector window */
1303 (*pwin
->frame
->on_click_right
) (NULL
, pwin
, NULL
);
1306 static void create_tab_window_attributes(WWindow
*wwin
, InspectorPanel
*panel
, int frame_width
)
1310 panel
->attrFrm
= WMCreateFrame(panel
->win
);
1311 WMSetFrameTitle(panel
->attrFrm
, _("Attributes"));
1312 WMMoveWidget(panel
->attrFrm
, 15, 45);
1313 WMResizeWidget(panel
->attrFrm
, frame_width
, 250);
1315 for (i
= 0; i
< wlengthof(window_attribute
); i
++) {
1316 int is_userdef
, flag
;
1318 is_userdef
= get_attr_flag(&wwin
->defined_user_flags
, &window_attribute
[i
].flag
);
1320 flag
= get_attr_flag(&wwin
->user_flags
, &window_attribute
[i
].flag
);
1322 flag
= get_attr_flag(&wwin
->client_flags
, &window_attribute
[i
].flag
);
1324 panel
->attrChk
[i
] = WMCreateSwitchButton(panel
->attrFrm
);
1325 WMMoveWidget(panel
->attrChk
[i
], 10, 20 * (i
+ 1));
1326 WMResizeWidget(panel
->attrChk
[i
], frame_width
- 15, 20);
1327 WMSetButtonSelected(panel
->attrChk
[i
], flag
);
1328 WMSetButtonText(panel
->attrChk
[i
], _(window_attribute
[i
].caption
));
1330 WMSetBalloonTextForView(_(window_attribute
[i
].description
), WMWidgetView(panel
->attrChk
[i
]));
1334 static void create_tab_window_advanced(WWindow
*wwin
, InspectorPanel
*panel
, int frame_width
)
1338 panel
->moreFrm
= WMCreateFrame(panel
->win
);
1339 WMSetFrameTitle(panel
->moreFrm
, _("Advanced"));
1340 WMMoveWidget(panel
->moreFrm
, 15, 45);
1341 WMResizeWidget(panel
->moreFrm
, frame_width
, 265);
1343 for (i
= 0; i
< wlengthof(advanced_option
); i
++) {
1344 int is_userdef
, flag
;
1346 is_userdef
= get_attr_flag(&wwin
->defined_user_flags
, &advanced_option
[i
].flag
);
1348 flag
= get_attr_flag(&wwin
->user_flags
, &advanced_option
[i
].flag
);
1350 flag
= get_attr_flag(&wwin
->client_flags
, &advanced_option
[i
].flag
);
1352 panel
->moreChk
[i
] = WMCreateSwitchButton(panel
->moreFrm
);
1353 WMMoveWidget(panel
->moreChk
[i
], 10, 20 * (i
+ 1) - 4);
1354 WMResizeWidget(panel
->moreChk
[i
], frame_width
- 15, 20);
1355 WMSetButtonSelected(panel
->moreChk
[i
], flag
);
1356 WMSetButtonText(panel
->moreChk
[i
], _(advanced_option
[i
].caption
));
1358 WMSetBalloonTextForView(_(advanced_option
[i
].description
), WMWidgetView(panel
->moreChk
[i
]));
1362 static void create_tab_icon_workspace(WWindow
*wwin
, InspectorPanel
*panel
)
1364 WScreen
*scr
= wwin
->screen_ptr
;
1367 /* miniwindow/workspace */
1368 panel
->iconFrm
= WMCreateFrame(panel
->win
);
1369 WMMoveWidget(panel
->iconFrm
, 15, 50);
1370 WMResizeWidget(panel
->iconFrm
, PWIDTH
- (2 * 15), 170);
1371 WMSetFrameTitle(panel
->iconFrm
, _("Miniwindow Image"));
1373 panel
->iconLbl
= WMCreateLabel(panel
->iconFrm
);
1374 WMMoveWidget(panel
->iconLbl
, PWIDTH
- (2 * 15) - 22 - 64, 20);
1375 WMResizeWidget(panel
->iconLbl
, 64, 64);
1376 WMSetLabelRelief(panel
->iconLbl
, WRGroove
);
1377 WMSetLabelImagePosition(panel
->iconLbl
, WIPImageOnly
);
1379 panel
->browseIconBtn
= WMCreateCommandButton(panel
->iconFrm
);
1380 WMSetButtonAction(panel
->browseIconBtn
, chooseIconCallback
, panel
);
1381 WMMoveWidget(panel
->browseIconBtn
, 22, 32);
1382 WMResizeWidget(panel
->browseIconBtn
, 120, 26);
1383 WMSetButtonText(panel
->browseIconBtn
, _("Browse..."));
1385 panel
->fileLbl
= WMCreateLabel(panel
->iconFrm
);
1386 WMMoveWidget(panel
->fileLbl
, 20, 85);
1387 WMResizeWidget(panel
->fileLbl
, PWIDTH
- (2 * 15) - (2 * 20), 14);
1388 WMSetLabelText(panel
->fileLbl
, _("Icon filename:"));
1390 panel
->fileText
= WMCreateTextField(panel
->iconFrm
);
1391 WMMoveWidget(panel
->fileText
, 20, 105);
1392 WMResizeWidget(panel
->fileText
, PWIDTH
- (2 * 20) - (2 * 15), 20);
1393 WMSetTextFieldText(panel
->fileText
, NULL
);
1394 WMAddNotificationObserver(textEditedObserver
, panel
, WMTextDidEndEditingNotification
, panel
->fileText
);
1396 panel
->alwChk
= WMCreateSwitchButton(panel
->iconFrm
);
1397 WMMoveWidget(panel
->alwChk
, 20, 130);
1398 WMResizeWidget(panel
->alwChk
, PWIDTH
- (2 * 15) - (2 * 15), 30);
1399 WMSetButtonText(panel
->alwChk
, _("Ignore client supplied icon"));
1400 WMSetButtonSelected(panel
->alwChk
, WFLAGP(wwin
, always_user_icon
));
1402 panel
->wsFrm
= WMCreateFrame(panel
->win
);
1403 WMMoveWidget(panel
->wsFrm
, 15, 225);
1404 WMResizeWidget(panel
->wsFrm
, PWIDTH
- (2 * 15), 70);
1405 WMSetFrameTitle(panel
->wsFrm
, _("Initial Workspace"));
1407 WMSetBalloonTextForView(_("The workspace to place the window when it's"
1408 " first shown."), WMWidgetView(panel
->wsFrm
));
1410 panel
->wsP
= WMCreatePopUpButton(panel
->wsFrm
);
1411 WMMoveWidget(panel
->wsP
, 20, 30);
1412 WMResizeWidget(panel
->wsP
, PWIDTH
- (2 * 15) - (2 * 20), 20);
1413 WMAddPopUpButtonItem(panel
->wsP
, _("Nowhere in particular"));
1415 for (i
= 0; i
< wwin
->screen_ptr
->workspace_count
; i
++)
1416 WMAddPopUpButtonItem(panel
->wsP
, scr
->workspaces
[i
]->name
);
1418 i
= wDefaultGetStartWorkspace(wwin
->screen_ptr
, wwin
->wm_instance
, wwin
->wm_class
);
1419 if (i
>= 0 && i
<= wwin
->screen_ptr
->workspace_count
)
1420 WMSetPopUpButtonSelectedItem(panel
->wsP
, i
+ 1);
1422 WMSetPopUpButtonSelectedItem(panel
->wsP
, 0);
1425 static void create_tab_app_specific(WWindow
*wwin
, InspectorPanel
*panel
, int frame_width
)
1427 WScreen
*scr
= wwin
->screen_ptr
;
1430 if (wwin
->main_window
!= None
) {
1431 WApplication
*wapp
= wApplicationOf(wwin
->main_window
);
1433 panel
->appFrm
= WMCreateFrame(panel
->win
);
1434 WMSetFrameTitle(panel
->appFrm
, _("Application Attributes"));
1435 WMMoveWidget(panel
->appFrm
, 15, 50);
1436 WMResizeWidget(panel
->appFrm
, frame_width
, 240);
1438 for (i
= 0; i
< wlengthof(application_attr
); i
++) {
1439 int is_userdef
, flag
;
1441 is_userdef
= get_attr_flag(&wapp
->main_window_desc
->defined_user_flags
, &application_attr
[i
].flag
);
1443 flag
= get_attr_flag(&wapp
->main_window_desc
->user_flags
, &application_attr
[i
].flag
);
1445 flag
= get_attr_flag(&wapp
->main_window_desc
->client_flags
, &application_attr
[i
].flag
);
1447 panel
->appChk
[i
] = WMCreateSwitchButton(panel
->appFrm
);
1448 WMMoveWidget(panel
->appChk
[i
], 10, 20 * (i
+ 1));
1449 WMResizeWidget(panel
->appChk
[i
], 205, 20);
1450 WMSetButtonSelected(panel
->appChk
[i
], flag
);
1451 WMSetButtonText(panel
->appChk
[i
], _(application_attr
[i
].caption
));
1453 WMSetBalloonTextForView(_(application_attr
[i
].description
),
1454 WMWidgetView(panel
->appChk
[i
]));
1457 if (WFLAGP(wwin
, emulate_appicon
)) {
1458 WMSetButtonEnabled(panel
->appChk
[1], False
);
1459 WMSetButtonEnabled(panel
->moreChk
[7], True
);
1461 WMSetButtonEnabled(panel
->appChk
[1], True
);
1462 WMSetButtonEnabled(panel
->moreChk
[7], False
);
1465 if ((wwin
->transient_for
!= None
&& wwin
->transient_for
!= scr
->root_win
)
1466 || !wwin
->wm_class
|| !wwin
->wm_instance
)
1471 WMSetButtonEnabled(panel
->moreChk
[7], tmp
);
1473 WMSetPopUpButtonItemEnabled(panel
->pagePopUp
, 4, False
);
1474 panel
->appFrm
= NULL
;