Initial revision
[wmaker-crm.git] / src / winspector.c
blobff374305d757739dc1d679d4a00da5562247a8ef
1 /* winspector.c - window attribute inspector
2 *
3 * WindowMaker window manager
4 *
5 * Copyright (c) 1997, 1998 Alfredo K. Kojima
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
20 * USA.
23 #include "wconfig.h"
25 #include <X11/Xlib.h>
26 #include <X11/Xutil.h>
27 #include <stdlib.h>
28 #include <stdio.h>
29 #include <string.h>
31 #include "WindowMaker.h"
32 #include "screen.h"
33 #include "wcore.h"
34 #include "framewin.h"
35 #include "window.h"
36 #include "workspace.h"
37 #include "funcs.h"
38 #include "defaults.h"
39 #include "dialog.h"
40 #include "icon.h"
41 #include "stacking.h"
42 #include "application.h"
43 #include "appicon.h"
44 #include "actions.h"
45 #include "winspector.h"
46 #include "dock.h"
48 #include <proplist.h>
50 extern WDDomain *WDWindowAttributes;
52 static InspectorPanel *panelList=NULL;
54 extern WPreferences wPreferences;
56 static proplist_t ANoTitlebar = NULL;
57 static proplist_t ANoResizebar;
58 static proplist_t ANoMiniaturizeButton;
59 static proplist_t ANoCloseButton;
60 static proplist_t ANoHideOthers;
61 static proplist_t ANoMouseBindings;
62 static proplist_t ANoKeyBindings;
63 static proplist_t ANoAppIcon;
64 static proplist_t AKeepOnTop;
65 static proplist_t AOmnipresent;
66 static proplist_t ASkipWindowList;
67 static proplist_t AKeepInsideScreen;
68 static proplist_t AUnfocusable;
69 static proplist_t AAlwaysUserIcon;
70 static proplist_t AStartMiniaturized;
71 static proplist_t ADontSaveSession;
72 static proplist_t AEmulateAppIcon;
74 static proplist_t AStartWorkspace;
76 static proplist_t AIcon;
78 /* application wide options */
79 static proplist_t AStartHidden;
82 static proplist_t AnyWindow;
83 static proplist_t EmptyString;
84 static proplist_t Yes, No;
87 #define PWIDTH 270
88 #define PHEIGHT 350
91 static void applySettings(WMButton *button, InspectorPanel *panel);
93 static void
94 make_keys()
96 if (ANoTitlebar!=NULL)
97 return;
99 AIcon = PLMakeString("Icon");
100 ANoTitlebar = PLMakeString("NoTitlebar");
101 ANoResizebar = PLMakeString("NoResizebar");
102 ANoMiniaturizeButton = PLMakeString("NoMiniaturizeButton");
103 ANoCloseButton = PLMakeString("NoCloseButton");
104 ANoHideOthers = PLMakeString("NoHideOthers");
105 ANoMouseBindings = PLMakeString("NoMouseBindings");
106 ANoKeyBindings = PLMakeString("NoKeyBindings");
107 ANoAppIcon = PLMakeString("NoAppIcon");
108 AKeepOnTop = PLMakeString("KeepOnTop");
109 AOmnipresent = PLMakeString("Omnipresent");
110 ASkipWindowList = PLMakeString("SkipWindowList");
111 AKeepInsideScreen = PLMakeString("KeepInsideScreen");
112 AUnfocusable = PLMakeString("Unfocusable");
113 AAlwaysUserIcon = PLMakeString("AlwaysUserIcon");
114 AStartMiniaturized = PLMakeString("StartMiniaturized");
115 AStartHidden = PLMakeString("StartHidden");
116 ADontSaveSession = PLMakeString("DontSaveSession");
117 AEmulateAppIcon = PLMakeString("EmulateAppIcon");
119 AStartWorkspace = PLMakeString("StartWorkspace");
121 AnyWindow = PLMakeString("*");
122 EmptyString = PLMakeString("");
123 Yes = PLMakeString("Yes");
124 No = PLMakeString("No");
129 static void
130 freeInspector(InspectorPanel *panel)
132 panel->destroyed = 1;
133 if (panel->choosingIcon)
134 return;
136 WMDestroyWidget(panel->win);
138 XDestroyWindow(dpy, panel->parent);
140 free(panel);
144 static void
145 destroyInspector(WCoreWindow *foo, void *data, XEvent *event)
147 InspectorPanel *panel;
148 InspectorPanel *tmp;
150 panel = panelList;
151 while (panel->frame!=data)
152 panel = panel->nextPtr;
154 if (panelList == panel)
155 panelList = panel->nextPtr;
156 else {
157 tmp = panelList;
158 while (tmp->nextPtr!=panel) {
159 tmp = tmp->nextPtr;
161 tmp->nextPtr = panel->nextPtr;
163 panel->inspected->flags.inspector_open = 0;
164 panel->inspected->inspector = NULL;
166 WMRemoveNotificationObserver(panel);
168 XUnmapWindow(dpy, panel->parent);
169 XReparentWindow(dpy, panel->parent, panel->frame->screen_ptr->root_win,
170 0, 0);
171 wUnmanageWindow(panel->frame, False);
173 freeInspector(panel);
178 void
179 wDestroyInspectorPanels()
181 InspectorPanel *panel;
183 while (panelList != NULL) {
184 panel = panelList;
185 panelList = panelList->nextPtr;
186 WMDestroyWidget(panel->win);
187 wUnmanageWindow(panel->frame, False);
189 panel->inspected->flags.inspector_open = 0;
190 panel->inspected->inspector = NULL;
192 free(panel);
197 static void
198 changePage(WMPopUpButton *bPtr, InspectorPanel *panel)
200 int page;
202 page = WMGetPopUpButtonSelectedItem(bPtr);
204 if (page == 0) {
205 WMMapWidget(panel->specFrm);
206 WMMapWidget(panel->specLbl);
207 } else if (page == 1) {
208 WMMapWidget(panel->attrFrm);
209 } else if (page == 2) {
210 WMMapWidget(panel->moreFrm);
211 } else if (page == 3) {
212 WMMapWidget(panel->iconFrm);
213 WMMapWidget(panel->wsFrm);
214 } else {
215 WMMapWidget(panel->appFrm);
218 if (page != 0) {
219 WMUnmapWidget(panel->specFrm);
220 WMUnmapWidget(panel->specLbl);
222 if (page != 1)
223 WMUnmapWidget(panel->attrFrm);
224 if (page != 2)
225 WMUnmapWidget(panel->moreFrm);
226 if (page != 3) {
227 WMUnmapWidget(panel->iconFrm);
228 WMUnmapWidget(panel->wsFrm);
230 if (page != 4 && panel->appFrm)
231 WMUnmapWidget(panel->appFrm);
235 #define USE_TEXT_FIELD 1
236 #define UPDATE_TEXT_FIELD 2
237 #define REVERT_TO_DEFAULT 4
240 static int
241 showIconFor(WMScreen *scrPtr, InspectorPanel *panel,
242 char *wm_instance, char *wm_class, int flags)
244 WMPixmap *pixmap = (WMPixmap*) NULL;
245 char *file=NULL, *path=NULL;
246 char *db_icon=NULL;
248 if ((flags & USE_TEXT_FIELD) != 0) {
249 file = WMGetTextFieldText(panel->fileText);
250 if (file && file[0] == 0) {
251 free(file);
252 file = NULL;
254 } else {
255 db_icon = wDefaultGetIconFile(panel->inspected->screen_ptr,
256 wm_instance, wm_class, False);
257 if(db_icon != NULL)
258 file = wstrdup(db_icon);
260 if (db_icon!=NULL && (flags & REVERT_TO_DEFAULT)!=0) {
261 if (file)
262 file = wstrdup(db_icon);
263 flags |= UPDATE_TEXT_FIELD;
266 if ((flags & UPDATE_TEXT_FIELD) != 0) {
267 WMSetTextFieldText(panel->fileText, file);
270 if (file) {
271 path = FindImage(wPreferences.icon_path, file);
273 if (!path) {
274 char *buf;
276 buf = wmalloc(strlen(file)+80);
277 sprintf(buf, _("Could not find icon \"%s\" specified for this window"),
278 file);
279 wMessageDialog(panel->frame->screen_ptr, _("Error"), buf,
280 _("OK"), NULL, NULL);
281 free(buf);
282 free(file);
283 return -1;
286 pixmap = WMCreatePixmapFromFile(scrPtr, path);
287 free(path);
289 if (!pixmap) {
290 char *buf;
292 buf = wmalloc(strlen(file)+80);
293 sprintf(buf, _("Could not open specified icon \"%s\":%s"),
294 file, RErrorString);
295 wMessageDialog(panel->frame->screen_ptr, _("Error"), buf,
296 _("OK"), NULL, NULL);
297 free(buf);
298 free(file);
299 return -1;
301 free(file);
304 WMSetLabelImage(panel->iconLbl, pixmap);
305 if (pixmap)
306 WMReleasePixmap(pixmap);
308 return 0;
311 #if 0
312 static void
313 updateIcon(WMButton *button, InspectorPanel *panel)
315 showIconFor(WMWidgetScreen(button), panel, NULL, NULL, USE_TEXT_FIELD);
317 #endif
319 static int
320 getBool(proplist_t value)
322 char *val;
324 if (!PLIsString(value)) {
325 return 0;
327 if (!(val = PLGetString(value))) {
328 return 0;
331 if ((val[1]=='\0' && (val[0]=='y' || val[0]=='Y' || val[0]=='T'
332 || val[0]=='t' || val[0]=='1'))
333 || (strcasecmp(val, "YES")==0 || strcasecmp(val, "TRUE")==0)) {
335 return 1;
336 } else if ((val[1]=='\0'
337 && (val[0]=='n' || val[0]=='N' || val[0]=='F'
338 || val[0]=='f' || val[0]=='0'))
339 || (strcasecmp(val, "NO")==0 || strcasecmp(val, "FALSE")==0)) {
341 return 0;
342 } else {
343 wwarning(_("can't convert \"%s\" to boolean"), val);
344 return 0;
349 #define UPDATE_DEFAULTS 1
350 #define IS_BOOLEAN 2
354 * Will insert the attribute = value; pair in window's list,
355 * if it's different from the defaults.
356 * Defaults means either defaults database, or attributes saved
357 * for the default window "*". This is to let one revert options that are
358 * global because they were saved for all windows ("*").
363 static void
364 insertAttribute(proplist_t dict, proplist_t window, proplist_t attr,
365 proplist_t value, int *modified, int flags)
367 proplist_t def_win, def_value=NULL;
368 int update = 0;
370 if (!(flags & UPDATE_DEFAULTS) && dict) {
371 if ((def_win = PLGetDictionaryEntry(dict, AnyWindow)) != NULL) {
372 def_value = PLGetDictionaryEntry(def_win, attr);
376 /* If we could not find defaults in database, fall to hardcoded values.
377 * Also this is true if we save defaults for all windows
379 if (!def_value)
380 def_value = ((flags & IS_BOOLEAN) != 0) ? No : EmptyString;
382 if ((flags & IS_BOOLEAN))
383 update = (getBool(value) != getBool(def_value));
384 else {
385 update = !PLIsEqual(value, def_value);
388 if (update) {
389 PLInsertDictionaryEntry(window, attr, value);
390 *modified = 1;
395 static void
396 saveSettings(WMButton *button, InspectorPanel *panel)
398 WWindow *wwin = panel->inspected;
399 WDDomain *db = WDWindowAttributes;
400 proplist_t dict = db->dictionary;
401 proplist_t winDic, value, key;
402 char buffer[256], *icon_file;
403 int flags = 0;
404 int different = 0;
406 /* Save will apply the changes and save them */
407 applySettings(panel->applyBtn, panel);
409 if (WMGetButtonSelected(panel->instRb) != 0)
410 key = PLMakeString(wwin->wm_instance);
411 else if (WMGetButtonSelected(panel->clsRb) != 0)
412 key = PLMakeString(wwin->wm_class);
413 else if (WMGetButtonSelected(panel->bothRb) != 0) {
414 strcat(strcat(strcpy(buffer, wwin->wm_instance), "."), wwin->wm_class);
415 key = PLMakeString(buffer);
417 else if (WMGetButtonSelected(panel->defaultRb) != 0) {
418 key = PLRetain(AnyWindow);
419 flags = UPDATE_DEFAULTS;
421 else
422 key = NULL;
424 if (!key)
425 return;
427 if (!dict) {
428 dict = PLMakeDictionaryFromEntries(NULL, NULL, NULL);
429 if (dict) {
430 db->dictionary = dict;
431 value = PLMakeString(db->path);
432 PLSetFilename(dict, value);
433 PLRelease(value);
435 else {
436 PLRelease(key);
437 return;
441 if (showIconFor(WMWidgetScreen(button), panel, NULL, NULL,
442 USE_TEXT_FIELD) < 0)
443 return;
445 PLSetStringCmpHook(NULL);
447 winDic = PLMakeDictionaryFromEntries(NULL, NULL, NULL);
449 /* Update icon for window */
450 icon_file = WMGetTextFieldText(panel->fileText);
451 if (icon_file) {
452 if (icon_file[0] != 0) {
453 value = PLMakeString(icon_file);
454 insertAttribute(dict, winDic, AIcon, value, &different, flags);
455 PLRelease(value);
457 free(icon_file);
460 if (WMGetButtonSelected(panel->curRb) != 0) {
461 value = PLMakeString("");
462 insertAttribute(dict, winDic, AStartWorkspace, value, &different, flags);
463 PLRelease(value);
464 } else if (WMGetButtonSelected(panel->setRb) != 0) {
465 char *ws_name = WMGetTextFieldText(panel->wsText);
466 if (ws_name) {
467 if (ws_name[0] != 0) {
468 value = PLMakeString(ws_name);
469 insertAttribute(dict, winDic, AStartWorkspace, value, &different, flags);
470 PLRelease(value);
472 free(ws_name);
476 flags |= IS_BOOLEAN;
478 value = (WMGetButtonSelected(panel->alwChk)!=0) ? Yes : No;
479 insertAttribute(dict, winDic, AAlwaysUserIcon, value, &different, flags);
481 value = (WMGetButtonSelected(panel->attrChk[0])!=0) ? Yes : No;
482 insertAttribute(dict, winDic, ANoTitlebar, value, &different, flags);
484 value = (WMGetButtonSelected(panel->attrChk[1])!=0) ? Yes : No;
485 insertAttribute(dict, winDic, ANoResizebar, value, &different, flags);
487 value = (WMGetButtonSelected(panel->attrChk[2])!=0) ? Yes : No;
488 insertAttribute(dict, winDic, ANoCloseButton, value, &different, flags);
490 value = (WMGetButtonSelected(panel->attrChk[3])!=0) ? Yes : No;
491 insertAttribute(dict, winDic, ANoMiniaturizeButton, value, &different, flags);
493 value = (WMGetButtonSelected(panel->attrChk[4])!=0) ? Yes : No;
494 insertAttribute(dict, winDic, AKeepOnTop, value, &different, flags);
496 value = (WMGetButtonSelected(panel->attrChk[5])!=0) ? Yes : No;
497 insertAttribute(dict, winDic, AOmnipresent, value, &different, flags);
499 value = (WMGetButtonSelected(panel->attrChk[6])!=0) ? Yes : No;
500 insertAttribute(dict, winDic, AStartMiniaturized, value, &different, flags);
502 value = (WMGetButtonSelected(panel->attrChk[7])!=0) ? Yes : No;
503 insertAttribute(dict, winDic, ASkipWindowList, value, &different, flags);
506 value = (WMGetButtonSelected(panel->moreChk[0])!=0) ? Yes : No;
507 insertAttribute(dict, winDic, ANoHideOthers, value, &different, flags);
509 value = (WMGetButtonSelected(panel->moreChk[1])!=0) ? Yes : No;
510 insertAttribute(dict, winDic, ANoKeyBindings, value, &different, flags);
512 value = (WMGetButtonSelected(panel->moreChk[2])!=0) ? Yes : No;
513 insertAttribute(dict, winDic, ANoMouseBindings, value, &different, flags);
515 value = (WMGetButtonSelected(panel->moreChk[3])!=0) ? Yes : No;
516 insertAttribute(dict, winDic, AKeepInsideScreen, value, &different, flags);
518 value = (WMGetButtonSelected(panel->moreChk[4])!=0) ? Yes : No;
519 insertAttribute(dict, winDic, AUnfocusable, value, &different, flags);
521 value = (WMGetButtonSelected(panel->moreChk[5])!=0) ? Yes : No;
522 insertAttribute(dict, winDic, ADontSaveSession, value, &different, flags);
524 value = (WMGetButtonSelected(panel->moreChk[6])!=0) ? Yes : No;
525 insertAttribute(dict, winDic, AEmulateAppIcon, value, &different, flags);
527 /* application wide settings for when */
528 /* the window is the leader, save the attribute with the others */
529 if (panel->inspected->main_window == panel->inspected->client_win) {
531 value = (WMGetButtonSelected(panel->appChk[0])!=0) ? Yes : No;
532 insertAttribute(dict, winDic, AStartHidden, value, &different, flags);
534 value = (WMGetButtonSelected(panel->appChk[1])!=0) ? Yes : No;
535 insertAttribute(dict, winDic, ANoAppIcon, value, &different, flags);
538 PLRemoveDictionaryEntry(dict, key);
539 if (different) {
540 PLInsertDictionaryEntry(dict, key, winDic);
542 PLRelease(key);
543 PLRelease(winDic);
545 different = 0;
547 /* application wide settings */
548 if (panel->inspected->main_window != panel->inspected->client_win
549 && !(flags & UPDATE_DEFAULTS)) {
550 WApplication *wapp;
551 proplist_t appDic;
553 wapp = wApplicationOf(panel->inspected->main_window);
554 if (wapp) {
555 char *iconFile;
557 appDic = PLMakeDictionaryFromEntries(NULL, NULL, NULL);
559 assert(wapp->main_window_desc->wm_instance!=NULL);
560 assert(wapp->main_window_desc->wm_class!=NULL);
562 strcat(strcpy(buffer, wapp->main_window_desc->wm_instance), ".");
563 strcat(buffer, wwin->wm_class);
564 key = PLMakeString(buffer);
566 iconFile = wDefaultGetIconFile(wwin->screen_ptr,
567 wapp->main_window_desc->wm_instance,
568 wapp->main_window_desc->wm_class,
569 False);
571 if (iconFile && iconFile[0]!=0) {
572 value = PLMakeString(iconFile);
573 insertAttribute(dict, appDic, AIcon, value, &different,
574 flags&~IS_BOOLEAN);
575 PLRelease(value);
578 value = (WMGetButtonSelected(panel->appChk[0])!=0) ? Yes : No;
579 insertAttribute(dict, appDic, AStartHidden, value, &different, flags);
581 value = (WMGetButtonSelected(panel->appChk[1])!=0) ? Yes : No;
582 insertAttribute(dict, appDic, ANoAppIcon, value, &different, flags);
584 PLRemoveDictionaryEntry(dict, key);
585 if (different) {
586 PLInsertDictionaryEntry(dict, key, appDic);
588 PLRelease(key);
589 PLRelease(appDic);
593 PLSave(dict, YES);
595 /* clean up */
596 PLSetStringCmpHook(StringCompareHook);
600 static void
601 makeAppIconFor(WApplication *wapp)
603 WScreen *scr = wapp->main_window_desc->screen_ptr;
605 if (wapp->app_icon)
606 return;
608 if (!wapp->main_window_desc->window_flags.no_appicon)
609 wapp->app_icon = wAppIconCreate(wapp->main_window_desc);
610 else
611 wapp->app_icon = NULL;
613 if (wapp->app_icon) {
614 WIcon *icon = wapp->app_icon->icon;
615 WDock *clip = scr->workspaces[scr->current_workspace]->clip;
616 int x=0, y=0;
618 wapp->app_icon->main_window = wapp->main_window;
620 if (clip && clip->attract_icons && wDockFindFreeSlot(clip, &x, &y)) {
621 wapp->app_icon->attracted = 1;
622 if (!clip->keep_attracted && !wapp->app_icon->icon->shadowed) {
623 wapp->app_icon->icon->shadowed = 1;
624 wapp->app_icon->icon->force_paint = 1;
626 wDockAttachIcon(clip, wapp->app_icon, x, y);
627 } else {
628 PlaceIcon(scr, &x, &y);
629 wAppIconMove(wapp->app_icon, x, y);
630 #ifndef STRICTNS
631 wLowerFrame(icon->core);
632 #endif
634 if (!clip || !wapp->app_icon->attracted || !clip->collapsed)
635 XMapWindow(dpy, icon->core->window);
637 if (wPreferences.auto_arrange_icons && !wapp->app_icon->attracted)
638 wArrangeIcons(wapp->main_window_desc->screen_ptr, True);
643 static void
644 removeAppIconFor(WApplication *wapp)
646 if (!wapp->app_icon)
647 return;
649 if (wapp->app_icon->docked &&
650 (!wapp->app_icon->attracted || wapp->app_icon->dock->keep_attracted)) {
651 wapp->app_icon->running = 0;
652 /* since we keep it, we don't care if it was attracted or not */
653 wapp->app_icon->attracted = 0;
654 wapp->app_icon->icon->shadowed = 0;
655 wapp->app_icon->main_window = None;
656 wapp->app_icon->pid = 0;
657 wapp->app_icon->icon->owner = NULL;
658 wapp->app_icon->icon->icon_win = None;
659 wapp->app_icon->icon->force_paint = 1;
660 wAppIconPaint(wapp->app_icon);
661 } else if (wapp->app_icon->docked) {
662 wapp->app_icon->running = 0;
663 wDockDetach(wapp->app_icon->dock, wapp->app_icon);
664 } else {
665 wAppIconDestroy(wapp->app_icon);
667 wapp->app_icon = NULL;
668 if (wPreferences.auto_arrange_icons)
669 wArrangeIcons(wapp->main_window_desc->screen_ptr, True);
673 static void
674 applySettings(WMButton *button, InspectorPanel *panel)
676 WWindow *wwin = panel->inspected;
677 WWindowAttributes *wflags = &wwin->window_flags;
678 WWindowAttributes oldFlags = *wflags;
679 WApplication *wapp = wApplicationOf(wwin->main_window);
680 int floating, skip_window_list;
682 showIconFor(WMWidgetScreen(button), panel, NULL, NULL, USE_TEXT_FIELD);
684 wflags->no_titlebar = WMGetButtonSelected(panel->attrChk[0]);
685 wflags->no_resizebar = WMGetButtonSelected(panel->attrChk[1]);
686 wflags->no_close_button = WMGetButtonSelected(panel->attrChk[2]);
687 wflags->no_miniaturize_button = WMGetButtonSelected(panel->attrChk[3]);
688 floating = WMGetButtonSelected(panel->attrChk[4]);
689 wflags->omnipresent = WMGetButtonSelected(panel->attrChk[5]);
690 wflags->start_miniaturized = WMGetButtonSelected(panel->attrChk[6]);
691 skip_window_list = WMGetButtonSelected(panel->attrChk[7]);
692 wflags->no_hide_others = WMGetButtonSelected(panel->moreChk[0]);
693 wflags->no_bind_keys = WMGetButtonSelected(panel->moreChk[1]);
694 wflags->no_bind_mouse = WMGetButtonSelected(panel->moreChk[2]);
695 wflags->dont_move_off = WMGetButtonSelected(panel->moreChk[3]);
696 wflags->no_focusable = WMGetButtonSelected(panel->moreChk[4]);
697 wflags->dont_save_session = WMGetButtonSelected(panel->moreChk[5]);
698 wflags->emulate_appicon = WMGetButtonSelected(panel->moreChk[6]);
699 wflags->always_user_icon = WMGetButtonSelected(panel->alwChk);
701 if (wflags->no_titlebar && wwin->flags.shaded)
702 wUnshadeWindow(wwin);
703 wflags->no_shadeable = wflags->no_titlebar;
705 if (wflags->floating != floating) {
706 int wlevel = ((wflags->floating = floating))
707 ? WMFloatingWindowLevel : WMNormalWindowLevel;
708 ChangeStackingLevel(wwin->frame->core, wlevel);
711 if (wflags->skip_window_list != skip_window_list) {
712 int action = ((wflags->skip_window_list = skip_window_list))
713 ? ACTION_REMOVE : ACTION_ADD;
714 UpdateSwitchMenu(wwin->screen_ptr, wwin, action);
717 if (wflags->no_bind_keys != oldFlags.no_bind_keys) {
718 if (!wflags->no_bind_keys) {
719 XUngrabKey(dpy, AnyKey, AnyModifier, wwin->frame->core->window);
720 } else {
721 wWindowSetKeyGrabs(wwin);
725 if (wflags->no_bind_mouse != oldFlags.no_bind_mouse) {
726 wWindowResetMouseGrabs(wwin);
729 wwin->frame->flags.need_texture_change = 1;
730 wWindowConfigureBorders(wwin);
731 wFrameWindowPaint(wwin->frame);
734 * Can't apply emulate_appicon because it will probably cause problems.
737 if (wapp) {
738 /* do application wide stuff */
739 wflags = &wapp->main_window_desc->window_flags;
741 wflags->start_hidden = WMGetButtonSelected(panel->appChk[0]);
742 wflags->no_appicon = WMGetButtonSelected(panel->appChk[1]);
744 if (wflags->no_appicon)
745 removeAppIconFor(wapp);
746 else
747 makeAppIconFor(wapp);
749 if (wapp->app_icon && wapp->main_window == wwin->client_win) {
750 char *file = WMGetTextFieldText(panel->fileText);
752 if (file[0] == 0) {
753 free(file);
754 file = NULL;
756 wIconChangeImageFile(wapp->app_icon->icon, file);
757 if (file)
758 free(file);
759 wAppIconPaint(wapp->app_icon);
765 static void
766 revertSettings(WMButton *button, InspectorPanel *panel)
768 WWindow *wwin = panel->inspected;
769 WApplication *wapp = wApplicationOf(wwin->main_window);
770 int i, n, floating, skip_window_list;
771 char *wm_instance = NULL;
772 char *wm_class = NULL;
774 if (WMGetButtonSelected(panel->instRb) != 0)
775 wm_instance = wwin->wm_instance;
776 else if (WMGetButtonSelected(panel->clsRb) != 0)
777 wm_class = wwin->wm_class;
778 else if (WMGetButtonSelected(panel->bothRb) != 0) {
779 wm_instance = wwin->wm_instance;
780 wm_class = wwin->wm_class;
782 memset(&wwin->window_flags, 0, sizeof(WWindowAttributes));
783 wDefaultFillAttributes(wwin->screen_ptr, wm_instance, wm_class,
784 &wwin->window_flags, True);
786 wWindowCheckAttributeSanity(wwin, &wwin->window_flags);
788 wwin->window_flags.kill_close = (wwin->protocols.DELETE_WINDOW) ? 0 : 1;
789 /* transients can't be iconified or maximized */
790 if (wwin->window_flags.no_miniaturizable) {
791 wwin->window_flags.no_miniaturize_button = 1;
793 /* if the window can't be resized, remove the resizebar */
794 if (wwin->window_flags.no_resizable) {
795 wwin->window_flags.no_resizebar = 1;
798 wwin->window_flags.no_shadeable = wwin->window_flags.no_titlebar;
800 for (i=0; i < 8; i++) {
801 int flag = 0;
803 switch (i) {
804 case 0:
805 flag = wwin->window_flags.no_titlebar;
806 break;
807 case 1:
808 flag = wwin->window_flags.no_resizebar;
809 break;
810 case 2:
811 flag = wwin->window_flags.no_close_button;
812 break;
813 case 3:
814 flag = wwin->window_flags.no_miniaturize_button;
815 break;
816 case 4:
817 floating = WMGetButtonSelected(panel->attrChk[4]);
818 if (wwin->window_flags.floating != floating) {
819 int wlevel = (wwin->window_flags.floating != 0)
820 ? WMFloatingWindowLevel : WMNormalWindowLevel;
821 ChangeStackingLevel(wwin->frame->core, wlevel);
823 flag = wwin->window_flags.floating;
824 break;
825 case 5:
826 flag = wwin->window_flags.omnipresent;
827 break;
828 case 6:
829 flag = wwin->window_flags.no_focusable;
830 break;
831 case 7:
832 skip_window_list = WMGetButtonSelected(panel->attrChk[7]);
833 if (wwin->window_flags.skip_window_list != skip_window_list) {
834 int action = (wwin->window_flags.skip_window_list != 0)
835 ? ACTION_REMOVE : ACTION_ADD;
836 UpdateSwitchMenu(wwin->screen_ptr, wwin, action);
838 flag = wwin->window_flags.skip_window_list;
839 break;
841 WMSetButtonSelected(panel->attrChk[i], flag);
843 for (i=0; i < 7; i++) {
844 int flag = 0;
846 switch (i) {
847 case 0:
848 flag = wwin->window_flags.no_hide_others;
849 break;
850 case 1:
851 flag = wwin->window_flags.no_bind_keys;
852 break;
853 case 2:
854 flag = wwin->window_flags.no_bind_mouse;
855 break;
856 case 3:
857 flag = wwin->window_flags.dont_move_off;
858 break;
859 case 4:
860 flag = wwin->window_flags.start_miniaturized;
861 break;
862 case 5:
863 flag = wwin->window_flags.dont_save_session;
864 break;
865 case 6:
866 flag = wwin->window_flags.emulate_appicon;
867 break;
869 WMSetButtonSelected(panel->moreChk[i], flag);
871 if (panel->appFrm && wapp) {
872 for (i=0; i < 2; i++) {
873 int flag = 0;
875 switch (i) {
876 case 0:
877 flag = wapp->main_window_desc->window_flags.start_hidden;
878 break;
879 case 1:
880 flag = wapp->main_window_desc->window_flags.no_appicon;
881 break;
883 WMSetButtonSelected(panel->appChk[i], flag);
886 WMSetButtonSelected(panel->alwChk, wwin->window_flags.always_user_icon);
888 showIconFor(WMWidgetScreen(panel->alwChk), panel, wm_instance, wm_class,
889 REVERT_TO_DEFAULT);
891 n = wDefaultGetStartWorkspace(wwin->screen_ptr, wm_instance, wm_class);
893 if (n >= 0 && n <= wwin->screen_ptr->workspace_count) {
894 WMPerformButtonClick(panel->setRb);
895 WMSetTextFieldText(panel->wsText, wwin->screen_ptr->workspaces[n]->name);
896 } else {
897 WMPerformButtonClick(panel->curRb);
902 static void
903 chooseIconCallback(WMWidget *self, void *clientData)
905 char *file;
906 InspectorPanel *panel = (InspectorPanel*)clientData;
907 int result;
909 panel->choosingIcon = 1;
911 WMSetButtonEnabled(panel->browseIconBtn, False);
913 result = wIconChooserDialog(panel->frame->screen_ptr, &file);
915 panel->choosingIcon = 0;
917 if (!panel->destroyed) { /* kluge */
918 if (result) {
919 WMSetTextFieldText(panel->fileText, file);
920 showIconFor(WMWidgetScreen(self), panel, NULL, NULL,
921 USE_TEXT_FIELD);
922 free(file);
924 WMSetButtonEnabled(panel->browseIconBtn, True);
925 } else {
926 freeInspector(panel);
931 static void
932 textEditedObserver(void *observerData, WMNotification *notification)
934 InspectorPanel *panel = (InspectorPanel*)observerData;
936 if ((int)WMGetNotificationClientData(notification) != WMReturnTextMovement)
937 return;
939 showIconFor(WMWidgetScreen(panel->win), panel, NULL, NULL, USE_TEXT_FIELD);
941 WMPerformButtonClick(panel->updateIconBtn);
945 static InspectorPanel*
946 createInspectorForWindow(WWindow *wwin)
948 WScreen *scr = wwin->screen_ptr;
949 InspectorPanel *panel;
950 Window parent;
951 char charbuf[128];
952 int i;
953 int x, y;
954 int btn_width, frame_width;
955 #ifdef wrong_behaviour
956 WMPixmap *pixmap;
957 #endif
958 panel = wmalloc(sizeof(InspectorPanel));
960 panel->destroyed = 0;
963 panel->inspected = wwin;
965 panel->nextPtr = panelList;
966 panelList = panel;
969 sprintf(charbuf, "Inspecting %s.%s",
970 wwin->wm_instance ? wwin->wm_instance : "?",
971 wwin->wm_class ? wwin->wm_class : "?");
973 panel->win = WMCreateWindow(scr->wmscreen, "windowInspector");
974 WMResizeWidget(panel->win, PWIDTH, PHEIGHT);
977 /**** create common stuff ****/
979 /* command buttons */
980 /* (PWIDTH - (left and right margin) - (btn interval)) / 3 */
981 btn_width = (PWIDTH - (2 * 15) - (2 * 10)) / 3;
982 panel->saveBtn = WMCreateCommandButton(panel->win);
983 WMSetButtonAction(panel->saveBtn, (WMAction*)saveSettings, panel);
984 WMMoveWidget(panel->saveBtn, 15, 310);
985 WMSetButtonText(panel->saveBtn, _("Save"));
986 WMResizeWidget(panel->saveBtn, btn_width, 28);
988 panel->applyBtn = WMCreateCommandButton(panel->win);
989 WMSetButtonAction(panel->applyBtn, (WMAction*)applySettings, panel);
990 WMMoveWidget(panel->applyBtn, btn_width + 10 + 15, 310);
991 WMSetButtonText(panel->applyBtn, _("Apply"));
992 WMResizeWidget(panel->applyBtn, btn_width, 28);
994 panel->revertBtn = WMCreateCommandButton(panel->win);
995 WMSetButtonAction(panel->revertBtn, (WMAction*)revertSettings, panel);
996 WMMoveWidget(panel->revertBtn, (2 * (btn_width + 10)) + 15, 310);
997 WMSetButtonText(panel->revertBtn, _("Revert"));
998 WMResizeWidget(panel->revertBtn, btn_width, 28);
1000 /* page selection popup button */
1001 panel->pagePopUp = WMCreatePopUpButton(panel->win);
1002 WMSetPopUpButtonAction(panel->pagePopUp, (WMAction*)changePage, panel);
1003 WMMoveWidget(panel->pagePopUp, 25, 15);
1004 WMResizeWidget(panel->pagePopUp, PWIDTH - 50, 20);
1006 WMAddPopUpButtonItem(panel->pagePopUp, _("Window Specification"));
1007 WMAddPopUpButtonItem(panel->pagePopUp, _("Window Attributes"));
1008 WMAddPopUpButtonItem(panel->pagePopUp, _("Advanced Options"));
1009 WMAddPopUpButtonItem(panel->pagePopUp, _("Icon and Initial Workspace"));
1010 WMAddPopUpButtonItem(panel->pagePopUp, _("Application Specific"));
1012 /**** window spec ****/
1013 frame_width = PWIDTH - (2 * 15);
1015 panel->specFrm = WMCreateFrame(panel->win);
1016 WMSetFrameTitle(panel->specFrm, _("Window Specification"));
1017 WMMoveWidget(panel->specFrm, 15, 65);
1018 WMResizeWidget(panel->specFrm, frame_width, 105);
1021 panel->defaultRb = WMCreateRadioButton(panel->specFrm);
1022 WMMoveWidget(panel->defaultRb, 10, 78);
1023 WMResizeWidget(panel->defaultRb, frame_width - (2 * 10), 20);
1024 WMSetButtonText(panel->defaultRb, _("Defaults for all windows"));
1025 WMSetButtonSelected(panel->defaultRb, False);
1028 if (wwin->wm_class && wwin->wm_instance) {
1029 sprintf(charbuf, "%s.%s", wwin->wm_instance, wwin->wm_class);
1030 panel->bothRb = WMCreateRadioButton(panel->specFrm);
1031 WMMoveWidget(panel->bothRb, 10, 18);
1032 WMResizeWidget(panel->bothRb, frame_width - (2 * 10), 20);
1033 WMSetButtonText(panel->bothRb, charbuf);
1034 WMSetButtonSelected(panel->bothRb, True);
1035 WMGroupButtons(panel->defaultRb, panel->bothRb);
1038 if (wwin->wm_instance) {
1039 panel->instRb = WMCreateRadioButton(panel->specFrm);
1040 WMMoveWidget(panel->instRb, 10, 38);
1041 WMResizeWidget(panel->instRb, frame_width - (2 * 10), 20);
1042 WMSetButtonText(panel->instRb, wwin->wm_instance);
1043 WMSetButtonSelected(panel->instRb, False);
1044 WMGroupButtons(panel->defaultRb, panel->instRb);
1047 if (wwin->wm_class) {
1048 panel->clsRb = WMCreateRadioButton(panel->specFrm);
1049 WMMoveWidget(panel->clsRb, 10, 58);
1050 WMResizeWidget(panel->clsRb, frame_width - (2 * 10), 20);
1051 WMSetButtonText(panel->clsRb, wwin->wm_class);
1052 WMSetButtonSelected(panel->clsRb, False);
1053 WMGroupButtons(panel->defaultRb, panel->clsRb);
1056 panel->specLbl = WMCreateLabel(panel->win);
1057 WMMoveWidget(panel->specLbl, 15, 170);
1058 WMResizeWidget(panel->specLbl, frame_width, 100);
1059 WMSetLabelText(panel->specLbl,
1060 _("The configuration will apply to all\n"
1061 "windows that have their WM_CLASS property"
1062 " set to the above selected\nname, when saved."));
1063 WMSetLabelTextAlignment(panel->specLbl, WACenter);
1065 /**** attributes ****/
1066 panel->attrFrm = WMCreateFrame(panel->win);
1067 WMSetFrameTitle(panel->attrFrm, _("Attributes"));
1068 WMMoveWidget(panel->attrFrm, 15, 50);
1069 WMResizeWidget(panel->attrFrm, frame_width, 240);
1071 for (i=0; i < 8; i++) {
1072 char *caption = NULL;
1073 int flag = 0;
1075 switch (i) {
1076 case 0:
1077 caption = _("Disable titlebar");
1078 flag = wwin->window_flags.no_titlebar;
1079 break;
1080 case 1:
1081 caption = _("Disable resizebar");
1082 flag = wwin->window_flags.no_resizebar;
1083 break;
1084 case 2:
1085 caption = _("Disable close button");
1086 flag = wwin->window_flags.no_close_button;
1087 break;
1088 case 3:
1089 caption = _("Disable miniaturize button");
1090 flag = wwin->window_flags.no_miniaturize_button;
1091 break;
1092 case 4:
1093 caption = _("Keep on top");
1094 flag = wwin->window_flags.floating;
1095 break;
1096 case 5:
1097 caption = _("Omnipresent");
1098 flag = wwin->window_flags.omnipresent;
1099 break;
1100 case 6:
1101 caption = _("Start Miniaturized");
1102 flag = wwin->window_flags.start_miniaturized;
1103 break;
1104 case 7:
1105 caption = _("Skip window list");
1106 flag = wwin->window_flags.skip_window_list;
1107 break;
1109 panel->attrChk[i] = WMCreateSwitchButton(panel->attrFrm);
1110 WMMoveWidget(panel->attrChk[i], 10, 20*(i+1));
1111 WMResizeWidget(panel->attrChk[i], frame_width-15, 20);
1112 WMSetButtonSelected(panel->attrChk[i], flag);
1113 WMSetButtonText(panel->attrChk[i], caption);
1117 /**** more attributes ****/
1118 panel->moreFrm = WMCreateFrame(panel->win);
1119 WMSetFrameTitle(panel->moreFrm, _("Advanced"));
1120 WMMoveWidget(panel->moreFrm, 15, 50);
1121 WMResizeWidget(panel->moreFrm, frame_width, 240);
1123 for (i=0; i < 7; i++) {
1124 char *caption = NULL;
1125 int flag = 0;
1127 switch (i) {
1128 case 0:
1129 caption = _("Ignore HideOthers");
1130 flag = wwin->window_flags.no_hide_others;
1131 break;
1132 case 1:
1133 caption = _("Don't bind keyboard shortcuts");
1134 flag = wwin->window_flags.no_bind_keys;
1135 break;
1136 case 2:
1137 caption = _("Don't bind mouse clicks");
1138 flag = wwin->window_flags.no_bind_mouse;
1139 break;
1140 case 3:
1141 caption = _("Keep inside screen");
1142 flag = wwin->window_flags.dont_move_off;
1143 break;
1144 case 4:
1145 caption = _("Don't let it take focus");
1146 flag = wwin->window_flags.no_focusable;
1147 break;
1148 case 5:
1149 caption = _("Don't Save Session");
1150 flag = wwin->window_flags.dont_save_session;
1151 break;
1152 case 6:
1153 caption = _("Emulate Application Icon");
1154 flag = wwin->window_flags.emulate_appicon;
1155 break;
1157 panel->moreChk[i] = WMCreateSwitchButton(panel->moreFrm);
1158 WMMoveWidget(panel->moreChk[i], 10, 20*(i+1));
1159 WMResizeWidget(panel->moreChk[i], frame_width-15, 20);
1160 WMSetButtonSelected(panel->moreChk[i], flag);
1161 WMSetButtonText(panel->moreChk[i], caption);
1164 panel->moreLbl = WMCreateLabel(panel->moreFrm);
1165 WMResizeWidget(panel->moreLbl, frame_width - (2 * 5), 60);
1166 WMMoveWidget(panel->moreLbl, 5, 160);
1167 WMSetLabelText(panel->moreLbl,
1168 _("Enable the \"Don't bind...\" options to allow the "
1169 "application to receive all mouse or keyboard events."));
1171 /* miniwindow/workspace */
1172 panel->iconFrm = WMCreateFrame(panel->win);
1173 WMMoveWidget(panel->iconFrm, 15, 50);
1174 WMResizeWidget(panel->iconFrm, PWIDTH - (2 * 15), 170);
1175 WMSetFrameTitle(panel->iconFrm, _("Miniwindow Image"));
1177 panel->iconLbl = WMCreateLabel(panel->iconFrm);
1178 WMMoveWidget(panel->iconLbl, PWIDTH - (2 * 15) - 22 - 64, 30);
1179 WMResizeWidget(panel->iconLbl, 64, 64);
1180 WMSetLabelRelief(panel->iconLbl, WRRaised);
1181 WMSetLabelImagePosition(panel->iconLbl, WIPImageOnly);
1183 panel->browseIconBtn = WMCreateCommandButton(panel->iconFrm);
1184 WMSetButtonAction(panel->browseIconBtn, chooseIconCallback, panel);
1185 WMMoveWidget(panel->browseIconBtn, 22, 30);
1186 WMResizeWidget(panel->browseIconBtn, 100, 26);
1187 WMSetButtonText(panel->browseIconBtn, _("Browse..."));
1189 #if 0
1190 panel->updateIconBtn = WMCreateCommandButton(panel->iconFrm);
1191 WMSetButtonAction(panel->updateIconBtn, (WMAction*)updateIcon, panel);
1192 WMMoveWidget(panel->updateIconBtn, 22, 65);
1193 WMResizeWidget(panel->updateIconBtn, 100, 26);
1194 WMSetButtonText(panel->updateIconBtn, _("Update"));
1195 #endif
1196 #ifdef wrong_behaviour
1197 WMSetButtonImagePosition(panel->updateIconBtn, WIPRight);
1198 pixmap = WMGetSystemPixmap(scr->wmscreen, WSIReturnArrow);
1199 WMSetButtonImage(panel->updateIconBtn, pixmap);
1200 WMReleasePixmap(pixmap);
1201 pixmap = WMGetSystemPixmap(scr->wmscreen, WSIHighlightedReturnArrow);
1202 WMSetButtonAltImage(panel->updateIconBtn, pixmap);
1203 WMReleasePixmap(pixmap);
1204 #endif
1206 panel->fileLbl = WMCreateLabel(panel->iconFrm);
1207 WMMoveWidget(panel->fileLbl, 20, 95);
1208 WMResizeWidget(panel->fileLbl, PWIDTH - (2 * 15) - (2 * 20), 14);
1209 WMSetLabelText(panel->fileLbl, _("Icon file name:"));
1211 panel->fileText = WMCreateTextField(panel->iconFrm);
1212 WMMoveWidget(panel->fileText, 20, 115);
1213 WMResizeWidget(panel->fileText, PWIDTH - (2 * 15) - (2 * 15), 20);
1214 WMSetTextFieldText(panel->fileText, NULL);
1215 WMAddNotificationObserver(textEditedObserver, panel,
1216 WMTextDidEndEditingNotification,
1217 panel->fileText);
1218 panel->alwChk = WMCreateSwitchButton(panel->iconFrm);
1219 WMMoveWidget(panel->alwChk, 20, 140);
1220 WMResizeWidget(panel->alwChk, PWIDTH - (2 * 15) - (2 * 15), 20);
1221 WMSetButtonText(panel->alwChk, _("Ignore client supplied icon"));
1222 WMSetButtonSelected(panel->alwChk, wwin->window_flags.always_user_icon);
1225 panel->wsFrm = WMCreateFrame(panel->win);
1226 WMMoveWidget(panel->wsFrm, 15, 225);
1227 WMResizeWidget(panel->wsFrm, PWIDTH - (2 * 15), 70);
1228 WMSetFrameTitle(panel->wsFrm, _("Initial Workspace"));
1230 panel->curRb = WMCreateRadioButton(panel->wsFrm);
1231 WMMoveWidget(panel->curRb, 10, 15);
1232 WMResizeWidget(panel->curRb, frame_width - (2 * 10), 20);
1233 WMSetButtonText(panel->curRb, _("Nowhere in particular"));
1236 panel->setRb = WMCreateRadioButton(panel->wsFrm);
1237 WMMoveWidget(panel->setRb, 10, 40);
1238 WMResizeWidget(panel->setRb, 25, 20);
1239 WMGroupButtons(panel->curRb, panel->setRb);
1240 WMSetButtonText(panel->setRb, NULL);
1242 panel->wsText = WMCreateTextField(panel->wsFrm);
1243 WMMoveWidget(panel->wsText, 30, 40);
1244 WMResizeWidget(panel->wsText, PWIDTH - (2 * 15) - 25 - 10 - (2 * 5), 20);
1247 i = wDefaultGetStartWorkspace(wwin->screen_ptr, wwin->wm_instance,
1248 wwin->wm_class);
1249 if (i >= 0 && i <= wwin->screen_ptr->workspace_count) {
1250 WMSetButtonSelected(panel->curRb, False);
1251 WMSetButtonSelected(panel->setRb, True);
1252 WMSetTextFieldText(panel->wsText,
1253 wwin->screen_ptr->workspaces[i]->name);
1254 } else {
1255 WMSetButtonSelected(panel->curRb, True);
1256 WMSetButtonSelected(panel->setRb, False);
1259 /* application wide attributes */
1260 if (wwin->main_window != None) {
1261 WApplication *wapp = wApplicationOf(wwin->main_window);
1263 panel->appFrm = WMCreateFrame(panel->win);
1264 WMSetFrameTitle(panel->appFrm, _("Application Wide"));
1265 WMMoveWidget(panel->appFrm, 15, 50);
1266 WMResizeWidget(panel->appFrm, frame_width, 240);
1268 for (i=0; i < 2; i++) {
1269 char *caption = NULL;
1270 int flag = 0;
1272 switch (i) {
1273 case 0:
1274 caption = _("Start Hidden");
1275 flag = wapp->main_window_desc->window_flags.start_hidden;
1276 break;
1277 case 1:
1278 caption = _("No application icon");
1279 flag = wapp->main_window_desc->window_flags.no_appicon;
1280 break;
1282 panel->appChk[i] = WMCreateSwitchButton(panel->appFrm);
1283 WMMoveWidget(panel->appChk[i], 10, 20*(i+1));
1284 WMResizeWidget(panel->appChk[i], 205, 20);
1285 WMSetButtonSelected(panel->appChk[i], flag);
1286 WMSetButtonText(panel->appChk[i], caption);
1289 if (wwin->window_flags.emulate_appicon) {
1290 WMSetButtonEnabled(panel->appChk[1], False);
1291 WMSetButtonEnabled(panel->moreChk[6], True);
1292 } else {
1293 WMSetButtonEnabled(panel->appChk[1], True);
1294 WMSetButtonEnabled(panel->moreChk[6], False);
1296 } else {
1297 int tmp;
1299 if (wwin->transient_for!=None
1300 && wwin->transient_for!=scr->root_win)
1301 tmp = False;
1302 else
1303 tmp = True;
1304 WMSetButtonEnabled(panel->moreChk[6], tmp);
1306 WMSetPopUpButtonItemEnabled(panel->pagePopUp, 4, False);
1307 panel->appFrm = NULL;
1310 WMRealizeWidget(panel->win);
1312 WMMapSubwidgets(panel->win);
1313 WMMapSubwidgets(panel->specFrm);
1314 WMMapSubwidgets(panel->attrFrm);
1315 WMMapSubwidgets(panel->moreFrm);
1316 WMMapSubwidgets(panel->iconFrm);
1317 WMMapSubwidgets(panel->wsFrm);
1318 if (panel->appFrm)
1319 WMMapSubwidgets(panel->appFrm);
1321 WMSetPopUpButtonSelectedItem(panel->pagePopUp, 0);
1322 changePage(panel->pagePopUp, panel);
1325 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, PWIDTH, PHEIGHT,
1326 0, 0, 0);
1327 XSelectInput(dpy, parent, KeyPressMask|KeyReleaseMask);
1328 panel->parent = parent;
1329 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
1331 WMMapWidget(panel->win);
1333 XSetTransientForHint(dpy, parent, wwin->client_win);
1335 x = wwin->frame_x+wwin->frame->core->width/2;
1336 y = wwin->frame_y+wwin->frame->top_width*2;
1337 if (y + PHEIGHT > scr->scr_height)
1338 y = scr->scr_height - PHEIGHT - 30;
1339 panel->frame = wManageInternalWindow(scr, parent, wwin->client_win,
1340 charbuf, x, y, PWIDTH, PHEIGHT);
1342 /* kluge to know who should get the key events */
1343 panel->frame->client_leader = WMWidgetXID(panel->win);
1345 panel->frame->window_flags.no_closable = 0;
1346 panel->frame->window_flags.no_close_button = 0;
1347 wWindowUpdateButtonImages(panel->frame);
1348 wFrameWindowShowButton(panel->frame->frame, WFF_RIGHT_BUTTON);
1349 panel->frame->frame->on_click_right = destroyInspector;
1351 wWindowMap(panel->frame);
1353 showIconFor(WMWidgetScreen(panel->alwChk), panel, wwin->wm_instance,
1354 wwin->wm_class, UPDATE_TEXT_FIELD);
1355 return panel;
1359 void
1360 wShowInspectorForWindow(WWindow *wwin)
1362 if (wwin->flags.inspector_open)
1363 return;
1365 make_keys();
1366 wwin->flags.inspector_open = 1;
1367 wwin->inspector = createInspectorForWindow(wwin);;