GNOME mouseclickproxy thing fix
[wmaker-crm.git] / src / winspector.c
blob7da62320bc45ab41b4b75422ba7e570e38bab4be
1 /* winspector.c - window attribute inspector
2 *
3 * Window Maker window manager
4 *
5 * Copyright (c) 1997, 1998 Alfredo K. Kojima
6 * Copyright (c) 1998 Dan Pascu
7 *
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
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
21 * USA.
24 #include "wconfig.h"
26 #include <X11/Xlib.h>
27 #include <X11/Xutil.h>
28 #include <stdlib.h>
29 #include <stdio.h>
30 #include <string.h>
32 #include "WindowMaker.h"
33 #include "screen.h"
34 #include "wcore.h"
35 #include "framewin.h"
36 #include "window.h"
37 #include "workspace.h"
38 #include "funcs.h"
39 #include "defaults.h"
40 #include "dialog.h"
41 #include "icon.h"
42 #include "stacking.h"
43 #include "application.h"
44 #include "appicon.h"
45 #include "actions.h"
46 #include "winspector.h"
47 #include "dock.h"
49 #include <proplist.h>
51 extern WDDomain *WDWindowAttributes;
53 static InspectorPanel *panelList=NULL;
55 extern WPreferences wPreferences;
57 static proplist_t ANoTitlebar = NULL;
58 static proplist_t ANoResizebar;
59 static proplist_t ANoMiniaturizeButton;
60 static proplist_t ANoCloseButton;
61 static proplist_t ANoHideOthers;
62 static proplist_t ANoMouseBindings;
63 static proplist_t ANoKeyBindings;
64 static proplist_t ANoAppIcon;
65 static proplist_t AKeepOnTop;
66 static proplist_t AKeepOnBottom;
67 static proplist_t AOmnipresent;
68 static proplist_t ASkipWindowList;
69 static proplist_t AKeepInsideScreen;
70 static proplist_t AUnfocusable;
71 static proplist_t AAlwaysUserIcon;
72 static proplist_t AStartMiniaturized;
73 static proplist_t AStartMaximized;
74 static proplist_t ADontSaveSession;
75 static proplist_t AEmulateAppIcon;
76 static proplist_t AFullMaximize;
78 static proplist_t AStartWorkspace;
80 static proplist_t AIcon;
82 /* application wide options */
83 static proplist_t AStartHidden;
86 static proplist_t AnyWindow;
87 static proplist_t EmptyString;
88 static proplist_t Yes, No;
91 #define PWIDTH 270
92 #define PHEIGHT 350
95 static void applySettings(WMButton *button, InspectorPanel *panel);
97 static void
98 make_keys()
100 if (ANoTitlebar!=NULL)
101 return;
103 AIcon = PLMakeString("Icon");
104 ANoTitlebar = PLMakeString("NoTitlebar");
105 ANoResizebar = PLMakeString("NoResizebar");
106 ANoMiniaturizeButton = PLMakeString("NoMiniaturizeButton");
107 ANoCloseButton = PLMakeString("NoCloseButton");
108 ANoHideOthers = PLMakeString("NoHideOthers");
109 ANoMouseBindings = PLMakeString("NoMouseBindings");
110 ANoKeyBindings = PLMakeString("NoKeyBindings");
111 ANoAppIcon = PLMakeString("NoAppIcon");
112 AKeepOnTop = PLMakeString("KeepOnTop");
113 AKeepOnBottom = PLMakeString("KeepOnBottom");
114 AOmnipresent = PLMakeString("Omnipresent");
115 ASkipWindowList = PLMakeString("SkipWindowList");
116 AKeepInsideScreen = PLMakeString("KeepInsideScreen");
117 AUnfocusable = PLMakeString("Unfocusable");
118 AAlwaysUserIcon = PLMakeString("AlwaysUserIcon");
119 AStartMiniaturized = PLMakeString("StartMiniaturized");
120 AStartMaximized = PLMakeString("StartMaximized");
121 AStartHidden = PLMakeString("StartHidden");
122 ADontSaveSession = PLMakeString("DontSaveSession");
123 AEmulateAppIcon = PLMakeString("EmulateAppIcon");
124 AFullMaximize = PLMakeString("FullMaximize");
126 AStartWorkspace = PLMakeString("StartWorkspace");
128 AnyWindow = PLMakeString("*");
129 EmptyString = PLMakeString("");
130 Yes = PLMakeString("Yes");
131 No = PLMakeString("No");
136 static void
137 freeInspector(InspectorPanel *panel)
139 panel->destroyed = 1;
140 if (panel->choosingIcon)
141 return;
143 WMDestroyWidget(panel->win);
145 XDestroyWindow(dpy, panel->parent);
147 free(panel);
151 static void
152 destroyInspector(WCoreWindow *foo, void *data, XEvent *event)
154 InspectorPanel *panel;
155 InspectorPanel *tmp;
157 panel = panelList;
158 while (panel->frame!=data)
159 panel = panel->nextPtr;
161 if (panelList == panel)
162 panelList = panel->nextPtr;
163 else {
164 tmp = panelList;
165 while (tmp->nextPtr!=panel) {
166 tmp = tmp->nextPtr;
168 tmp->nextPtr = panel->nextPtr;
170 panel->inspected->flags.inspector_open = 0;
171 panel->inspected->inspector = NULL;
173 WMRemoveNotificationObserver(panel);
175 wWindowUnmap(panel->frame);
176 wUnmanageWindow(panel->frame, True, False);
178 freeInspector(panel);
183 void
184 wDestroyInspectorPanels()
186 InspectorPanel *panel;
188 while (panelList != NULL) {
189 panel = panelList;
190 panelList = panelList->nextPtr;
191 wUnmanageWindow(panel->frame, False, False);
192 WMDestroyWidget(panel->win);
194 panel->inspected->flags.inspector_open = 0;
195 panel->inspected->inspector = NULL;
197 free(panel);
202 static void
203 changePage(WMPopUpButton *bPtr, InspectorPanel *panel)
205 int page;
207 page = WMGetPopUpButtonSelectedItem(bPtr);
209 if (page == 0) {
210 WMMapWidget(panel->specFrm);
211 WMMapWidget(panel->specLbl);
212 } else if (page == 1) {
213 WMMapWidget(panel->attrFrm);
214 } else if (page == 2) {
215 WMMapWidget(panel->moreFrm);
216 } else if (page == 3) {
217 WMMapWidget(panel->iconFrm);
218 WMMapWidget(panel->wsFrm);
219 } else {
220 WMMapWidget(panel->appFrm);
223 if (page != 0) {
224 WMUnmapWidget(panel->specFrm);
225 WMUnmapWidget(panel->specLbl);
227 if (page != 1)
228 WMUnmapWidget(panel->attrFrm);
229 if (page != 2)
230 WMUnmapWidget(panel->moreFrm);
231 if (page != 3) {
232 WMUnmapWidget(panel->iconFrm);
233 WMUnmapWidget(panel->wsFrm);
235 if (page != 4 && panel->appFrm)
236 WMUnmapWidget(panel->appFrm);
240 #define USE_TEXT_FIELD 1
241 #define UPDATE_TEXT_FIELD 2
242 #define REVERT_TO_DEFAULT 4
245 static int
246 showIconFor(WMScreen *scrPtr, InspectorPanel *panel,
247 char *wm_instance, char *wm_class, int flags)
249 WMPixmap *pixmap = (WMPixmap*) NULL;
250 char *file=NULL, *path=NULL;
251 char *db_icon=NULL;
253 if ((flags & USE_TEXT_FIELD) != 0) {
254 file = WMGetTextFieldText(panel->fileText);
255 if (file && file[0] == 0) {
256 free(file);
257 file = NULL;
259 } else {
260 db_icon = wDefaultGetIconFile(panel->inspected->screen_ptr,
261 wm_instance, wm_class, False);
262 if(db_icon != NULL)
263 file = wstrdup(db_icon);
265 if (db_icon!=NULL && (flags & REVERT_TO_DEFAULT)!=0) {
266 if (file)
267 file = wstrdup(db_icon);
268 flags |= UPDATE_TEXT_FIELD;
271 if ((flags & UPDATE_TEXT_FIELD) != 0) {
272 WMSetTextFieldText(panel->fileText, file);
275 if (file) {
276 path = FindImage(wPreferences.icon_path, file);
278 if (!path) {
279 char *buf;
281 buf = wmalloc(strlen(file)+80);
282 sprintf(buf, _("Could not find icon \"%s\" specified for this window"),
283 file);
284 wMessageDialog(panel->frame->screen_ptr, _("Error"), buf,
285 _("OK"), NULL, NULL);
286 free(buf);
287 free(file);
288 return -1;
291 pixmap = WMCreatePixmapFromFile(scrPtr, path);
292 free(path);
294 if (!pixmap) {
295 char *buf;
297 buf = wmalloc(strlen(file)+80);
298 sprintf(buf, _("Could not open specified icon \"%s\":%s"),
299 file, RMessageForError(RErrorCode));
300 wMessageDialog(panel->frame->screen_ptr, _("Error"), buf,
301 _("OK"), NULL, NULL);
302 free(buf);
303 free(file);
304 return -1;
306 free(file);
309 WMSetLabelImage(panel->iconLbl, pixmap);
310 if (pixmap)
311 WMReleasePixmap(pixmap);
313 return 0;
316 #if 0
317 static void
318 updateIcon(WMButton *button, InspectorPanel *panel)
320 showIconFor(WMWidgetScreen(button), panel, NULL, NULL, USE_TEXT_FIELD);
322 #endif
324 static int
325 getBool(proplist_t value)
327 char *val;
329 if (!PLIsString(value)) {
330 return 0;
332 if (!(val = PLGetString(value))) {
333 return 0;
336 if ((val[1]=='\0' && (val[0]=='y' || val[0]=='Y' || val[0]=='T'
337 || val[0]=='t' || val[0]=='1'))
338 || (strcasecmp(val, "YES")==0 || strcasecmp(val, "TRUE")==0)) {
340 return 1;
341 } else if ((val[1]=='\0'
342 && (val[0]=='n' || val[0]=='N' || val[0]=='F'
343 || val[0]=='f' || val[0]=='0'))
344 || (strcasecmp(val, "NO")==0 || strcasecmp(val, "FALSE")==0)) {
346 return 0;
347 } else {
348 wwarning(_("can't convert \"%s\" to boolean"), val);
349 return 0;
354 #define UPDATE_DEFAULTS 1
355 #define IS_BOOLEAN 2
359 * Will insert the attribute = value; pair in window's list,
360 * if it's different from the defaults.
361 * Defaults means either defaults database, or attributes saved
362 * for the default window "*". This is to let one revert options that are
363 * global because they were saved for all windows ("*").
368 static void
369 insertAttribute(proplist_t dict, proplist_t window, proplist_t attr,
370 proplist_t value, int *modified, int flags)
372 proplist_t def_win, def_value=NULL;
373 int update = 0;
375 if (!(flags & UPDATE_DEFAULTS) && dict) {
376 if ((def_win = PLGetDictionaryEntry(dict, AnyWindow)) != NULL) {
377 def_value = PLGetDictionaryEntry(def_win, attr);
381 /* If we could not find defaults in database, fall to hardcoded values.
382 * Also this is true if we save defaults for all windows
384 if (!def_value)
385 def_value = ((flags & IS_BOOLEAN) != 0) ? No : EmptyString;
387 if ((flags & IS_BOOLEAN))
388 update = (getBool(value) != getBool(def_value));
389 else {
390 update = !PLIsEqual(value, def_value);
393 if (update) {
394 PLInsertDictionaryEntry(window, attr, value);
395 *modified = 1;
400 static void
401 saveSettings(WMButton *button, InspectorPanel *panel)
403 WWindow *wwin = panel->inspected;
404 WDDomain *db = WDWindowAttributes;
405 proplist_t dict = db->dictionary;
406 proplist_t winDic, value, key;
407 char buffer[256], *icon_file;
408 int flags = 0;
409 int different = 0;
411 /* Save will apply the changes and save them */
412 applySettings(panel->applyBtn, panel);
414 if (WMGetButtonSelected(panel->instRb) != 0)
415 key = PLMakeString(wwin->wm_instance);
416 else if (WMGetButtonSelected(panel->clsRb) != 0)
417 key = PLMakeString(wwin->wm_class);
418 else if (WMGetButtonSelected(panel->bothRb) != 0) {
419 strcat(strcat(strcpy(buffer, wwin->wm_instance), "."), wwin->wm_class);
420 key = PLMakeString(buffer);
422 else if (WMGetButtonSelected(panel->defaultRb) != 0) {
423 key = PLRetain(AnyWindow);
424 flags = UPDATE_DEFAULTS;
426 else
427 key = NULL;
429 if (!key)
430 return;
432 if (!dict) {
433 dict = PLMakeDictionaryFromEntries(NULL, NULL, NULL);
434 if (dict) {
435 db->dictionary = dict;
436 value = PLMakeString(db->path);
437 PLSetFilename(dict, value);
438 PLRelease(value);
440 else {
441 PLRelease(key);
442 return;
446 if (showIconFor(WMWidgetScreen(button), panel, NULL, NULL,
447 USE_TEXT_FIELD) < 0)
448 return;
450 PLSetStringCmpHook(NULL);
452 winDic = PLMakeDictionaryFromEntries(NULL, NULL, NULL);
454 /* Update icon for window */
455 icon_file = WMGetTextFieldText(panel->fileText);
456 if (icon_file) {
457 if (icon_file[0] != 0) {
458 value = PLMakeString(icon_file);
459 insertAttribute(dict, winDic, AIcon, value, &different, flags);
460 PLRelease(value);
462 free(icon_file);
466 int i = WMGetPopUpButtonSelectedItem(panel->wsP);
468 i--;
470 if (i>=0 && i < panel->frame->screen_ptr->workspace_count) {
471 value = PLMakeString(panel->frame->screen_ptr->workspaces[i]->name);
472 insertAttribute(dict, winDic, AStartWorkspace, value, &different, flags);
473 PLRelease(value);
477 flags |= IS_BOOLEAN;
479 value = (WMGetButtonSelected(panel->alwChk)!=0) ? Yes : No;
480 insertAttribute(dict, winDic, AAlwaysUserIcon, value, &different, flags);
482 value = (WMGetButtonSelected(panel->attrChk[0])!=0) ? Yes : No;
483 insertAttribute(dict, winDic, ANoTitlebar, value, &different, flags);
485 value = (WMGetButtonSelected(panel->attrChk[1])!=0) ? Yes : No;
486 insertAttribute(dict, winDic, ANoResizebar, value, &different, flags);
488 value = (WMGetButtonSelected(panel->attrChk[2])!=0) ? Yes : No;
489 insertAttribute(dict, winDic, ANoCloseButton, value, &different, flags);
491 value = (WMGetButtonSelected(panel->attrChk[3])!=0) ? Yes : No;
492 insertAttribute(dict, winDic, ANoMiniaturizeButton, value, &different, flags);
494 value = (WMGetButtonSelected(panel->attrChk[4])!=0) ? Yes : No;
495 insertAttribute(dict, winDic, AKeepOnTop, value, &different, flags);
497 value = (WMGetButtonSelected(panel->attrChk[5])!=0) ? Yes : No;
498 insertAttribute(dict, winDic, AKeepOnBottom, value, &different, flags);
500 value = (WMGetButtonSelected(panel->attrChk[6])!=0) ? Yes : No;
501 insertAttribute(dict, winDic, AOmnipresent, value, &different, flags);
503 value = (WMGetButtonSelected(panel->attrChk[7])!=0) ? Yes : No;
504 insertAttribute(dict, winDic, AStartMiniaturized, value, &different, flags);
506 value = (WMGetButtonSelected(panel->attrChk[8])!=0) ? Yes : No;
507 insertAttribute(dict, winDic, AStartMaximized, value, &different, flags);
509 value = (WMGetButtonSelected(panel->attrChk[9])!=0) ? Yes : No;
510 insertAttribute(dict, winDic, ASkipWindowList, value, &different, flags);
513 value = (WMGetButtonSelected(panel->moreChk[0])!=0) ? Yes : No;
514 insertAttribute(dict, winDic, ANoHideOthers, value, &different, flags);
516 value = (WMGetButtonSelected(panel->moreChk[1])!=0) ? Yes : No;
517 insertAttribute(dict, winDic, ANoKeyBindings, value, &different, flags);
519 value = (WMGetButtonSelected(panel->moreChk[2])!=0) ? Yes : No;
520 insertAttribute(dict, winDic, ANoMouseBindings, value, &different, flags);
522 value = (WMGetButtonSelected(panel->moreChk[3])!=0) ? Yes : No;
523 insertAttribute(dict, winDic, AKeepInsideScreen, value, &different, flags);
525 value = (WMGetButtonSelected(panel->moreChk[4])!=0) ? Yes : No;
526 insertAttribute(dict, winDic, AUnfocusable, value, &different, flags);
528 value = (WMGetButtonSelected(panel->moreChk[5])!=0) ? Yes : No;
529 insertAttribute(dict, winDic, ADontSaveSession, value, &different, flags);
531 value = (WMGetButtonSelected(panel->moreChk[6])!=0) ? Yes : No;
532 insertAttribute(dict, winDic, AEmulateAppIcon, value, &different, flags);
534 value = (WMGetButtonSelected(panel->moreChk[7])!=0) ? Yes : No;
535 insertAttribute(dict, winDic, AFullMaximize, value, &different, flags);
537 /* application wide settings for when */
538 /* the window is the leader, save the attribute with the others */
539 if (panel->inspected->main_window == panel->inspected->client_win) {
541 value = (WMGetButtonSelected(panel->appChk[0])!=0) ? Yes : No;
542 insertAttribute(dict, winDic, AStartHidden, value, &different, flags);
544 value = (WMGetButtonSelected(panel->appChk[1])!=0) ? Yes : No;
545 insertAttribute(dict, winDic, ANoAppIcon, value, &different, flags);
548 PLRemoveDictionaryEntry(dict, key);
549 if (different) {
550 PLInsertDictionaryEntry(dict, key, winDic);
553 PLRelease(key);
554 PLRelease(winDic);
556 different = 0;
558 /* application wide settings */
559 if (panel->inspected->main_window != panel->inspected->client_win
560 && !(flags & UPDATE_DEFAULTS)) {
561 WApplication *wapp;
562 proplist_t appDic;
564 wapp = wApplicationOf(panel->inspected->main_window);
565 if (wapp) {
566 char *iconFile;
568 appDic = PLMakeDictionaryFromEntries(NULL, NULL, NULL);
570 assert(wapp->main_window_desc->wm_instance!=NULL);
571 assert(wapp->main_window_desc->wm_class!=NULL);
573 strcat(strcpy(buffer, wapp->main_window_desc->wm_instance), ".");
574 strcat(buffer, wwin->wm_class);
575 key = PLMakeString(buffer);
577 iconFile = wDefaultGetIconFile(wwin->screen_ptr,
578 wapp->main_window_desc->wm_instance,
579 wapp->main_window_desc->wm_class,
580 False);
582 if (iconFile && iconFile[0]!=0) {
583 value = PLMakeString(iconFile);
584 insertAttribute(dict, appDic, AIcon, value, &different,
585 flags&~IS_BOOLEAN);
586 PLRelease(value);
589 value = (WMGetButtonSelected(panel->appChk[0])!=0) ? Yes : No;
590 insertAttribute(dict, appDic, AStartHidden, value, &different, flags);
592 value = (WMGetButtonSelected(panel->appChk[1])!=0) ? Yes : No;
593 insertAttribute(dict, appDic, ANoAppIcon, value, &different, flags);
595 PLRemoveDictionaryEntry(dict, key);
596 if (different) {
597 PLInsertDictionaryEntry(dict, key, appDic);
599 PLRelease(key);
600 PLRelease(appDic);
604 PLSave(dict, YES);
606 /* clean up */
607 PLSetStringCmpHook(StringCompareHook);
611 static void
612 makeAppIconFor(WApplication *wapp)
614 WScreen *scr = wapp->main_window_desc->screen_ptr;
616 if (wapp->app_icon)
617 return;
619 if (!WFLAGP(wapp->main_window_desc, no_appicon))
620 wapp->app_icon = wAppIconCreate(wapp->main_window_desc);
621 else
622 wapp->app_icon = NULL;
624 if (wapp->app_icon) {
625 WIcon *icon = wapp->app_icon->icon;
626 WDock *clip = scr->workspaces[scr->current_workspace]->clip;
627 int x=0, y=0;
629 wapp->app_icon->main_window = wapp->main_window;
631 if (clip && clip->attract_icons && wDockFindFreeSlot(clip, &x, &y)) {
632 wapp->app_icon->attracted = 1;
633 if (!clip->keep_attracted && !wapp->app_icon->icon->shadowed) {
634 wapp->app_icon->icon->shadowed = 1;
635 wapp->app_icon->icon->force_paint = 1;
637 wDockAttachIcon(clip, wapp->app_icon, x, y);
638 } else {
639 PlaceIcon(scr, &x, &y);
640 wAppIconMove(wapp->app_icon, x, y);
642 if (!clip || !wapp->app_icon->attracted || !clip->collapsed)
643 XMapWindow(dpy, icon->core->window);
645 if (wPreferences.auto_arrange_icons && !wapp->app_icon->attracted)
646 wArrangeIcons(wapp->main_window_desc->screen_ptr, True);
651 static void
652 removeAppIconFor(WApplication *wapp)
654 if (!wapp->app_icon)
655 return;
657 if (wapp->app_icon->docked &&
658 (!wapp->app_icon->attracted || wapp->app_icon->dock->keep_attracted)) {
659 wapp->app_icon->running = 0;
660 /* since we keep it, we don't care if it was attracted or not */
661 wapp->app_icon->attracted = 0;
662 wapp->app_icon->icon->shadowed = 0;
663 wapp->app_icon->main_window = None;
664 wapp->app_icon->pid = 0;
665 wapp->app_icon->icon->owner = NULL;
666 wapp->app_icon->icon->icon_win = None;
667 wapp->app_icon->icon->force_paint = 1;
668 wAppIconPaint(wapp->app_icon);
669 } else if (wapp->app_icon->docked) {
670 wapp->app_icon->running = 0;
671 wDockDetach(wapp->app_icon->dock, wapp->app_icon);
672 } else {
673 wAppIconDestroy(wapp->app_icon);
675 wapp->app_icon = NULL;
676 if (wPreferences.auto_arrange_icons)
677 wArrangeIcons(wapp->main_window_desc->screen_ptr, True);
681 static void
682 applySettings(WMButton *button, InspectorPanel *panel)
684 WWindow *wwin = panel->inspected;
685 WApplication *wapp = wApplicationOf(wwin->main_window);
686 int floating, sunken, skip_window_list;
687 int old_omnipresent;
688 int old_no_bind_keys;
689 int old_no_bind_mouse;
691 old_omnipresent = WFLAGP(wwin, omnipresent);
692 old_no_bind_keys = WFLAGP(wwin, no_bind_keys);
693 old_no_bind_mouse = WFLAGP(wwin, no_bind_mouse);
695 showIconFor(WMWidgetScreen(button), panel, NULL, NULL, USE_TEXT_FIELD);
697 WSETUFLAG(wwin, no_titlebar, WMGetButtonSelected(panel->attrChk[0]));
698 WSETUFLAG(wwin, no_resizebar, WMGetButtonSelected(panel->attrChk[1]));
699 WSETUFLAG(wwin, no_close_button, WMGetButtonSelected(panel->attrChk[2]));
700 WSETUFLAG(wwin, no_miniaturize_button, WMGetButtonSelected(panel->attrChk[3]));
701 floating = WMGetButtonSelected(panel->attrChk[4]);
702 sunken = WMGetButtonSelected(panel->attrChk[5]);
703 WSETUFLAG(wwin, omnipresent, WMGetButtonSelected(panel->attrChk[6]));
704 WSETUFLAG(wwin, start_miniaturized, WMGetButtonSelected(panel->attrChk[7]));
705 WSETUFLAG(wwin, start_maximized, WMGetButtonSelected(panel->attrChk[8]));
706 skip_window_list = WMGetButtonSelected(panel->attrChk[9]);
708 WSETUFLAG(wwin, no_hide_others, WMGetButtonSelected(panel->moreChk[0]));
709 WSETUFLAG(wwin, no_bind_keys, WMGetButtonSelected(panel->moreChk[1]));
710 WSETUFLAG(wwin, no_bind_mouse, WMGetButtonSelected(panel->moreChk[2]));
711 WSETUFLAG(wwin, dont_move_off, WMGetButtonSelected(panel->moreChk[3]));
712 WSETUFLAG(wwin, no_focusable, WMGetButtonSelected(panel->moreChk[4]));
713 WSETUFLAG(wwin, dont_save_session, WMGetButtonSelected(panel->moreChk[5]));
714 WSETUFLAG(wwin, emulate_appicon, WMGetButtonSelected(panel->moreChk[6]));
715 WSETUFLAG(wwin, full_maximize, WMGetButtonSelected(panel->moreChk[7]));
716 WSETUFLAG(wwin, always_user_icon, WMGetButtonSelected(panel->alwChk));
718 if (WFLAGP(wwin, no_titlebar) && wwin->flags.shaded)
719 wUnshadeWindow(wwin);
721 WSETUFLAG(wwin, no_shadeable, WFLAGP(wwin, no_titlebar));
723 if (floating) {
724 if (!WFLAGP(wwin, floating))
725 ChangeStackingLevel(wwin->frame->core, WMFloatingLevel);
726 } else if (sunken) {
727 if (!WFLAGP(wwin, sunken))
728 ChangeStackingLevel(wwin->frame->core, WMSunkenLevel);
729 } else {
730 if (WFLAGP(wwin, floating) || WFLAGP(wwin, sunken))
731 ChangeStackingLevel(wwin->frame->core, WMNormalLevel);
734 WSETUFLAG(wwin, sunken, sunken);
735 WSETUFLAG(wwin, floating, floating);
736 wwin->flags.omnipresent = 0;
738 if (WFLAGP(wwin, skip_window_list) != skip_window_list) {
739 WSETUFLAG(wwin, skip_window_list, skip_window_list);
740 UpdateSwitchMenu(wwin->screen_ptr, wwin,
741 skip_window_list ? ACTION_REMOVE : ACTION_ADD);
742 } else {
743 if (WFLAGP(wwin, omnipresent) != old_omnipresent) {
744 UpdateSwitchMenu(wwin->screen_ptr, wwin, ACTION_CHANGE_WORKSPACE);
748 if (WFLAGP(wwin, no_bind_keys) != old_no_bind_keys) {
749 if (WFLAGP(wwin, no_bind_keys)) {
750 XUngrabKey(dpy, AnyKey, AnyModifier, wwin->frame->core->window);
751 } else {
752 wWindowSetKeyGrabs(wwin);
756 if (WFLAGP(wwin, no_bind_mouse) != old_no_bind_mouse) {
757 wWindowResetMouseGrabs(wwin);
760 wwin->frame->flags.need_texture_change = 1;
761 wWindowConfigureBorders(wwin);
762 wFrameWindowPaint(wwin->frame);
765 * Can't apply emulate_appicon because it will probably cause problems.
768 if (wapp) {
769 /* do application wide stuff */
770 WSETUFLAG(wapp->main_window_desc, start_hidden,
771 WMGetButtonSelected(panel->appChk[0]));
773 WSETUFLAG(wapp->main_window_desc, no_appicon,
774 WMGetButtonSelected(panel->appChk[1]));
776 if (WFLAGP(wapp->main_window_desc, no_appicon))
777 removeAppIconFor(wapp);
778 else
779 makeAppIconFor(wapp);
781 if (wapp->app_icon && wapp->main_window == wwin->client_win) {
782 char *file = WMGetTextFieldText(panel->fileText);
784 if (file[0] == 0) {
785 free(file);
786 file = NULL;
788 wIconChangeImageFile(wapp->app_icon->icon, file);
789 if (file)
790 free(file);
791 wAppIconPaint(wapp->app_icon);
799 static void
800 revertSettings(WMButton *button, InspectorPanel *panel)
802 WWindow *wwin = panel->inspected;
803 WApplication *wapp = wApplicationOf(wwin->main_window);
804 int i, n;
805 char *wm_instance = NULL;
806 char *wm_class = NULL;
807 int workspace, level;
809 if (WMGetButtonSelected(panel->instRb) != 0)
810 wm_instance = wwin->wm_instance;
811 else if (WMGetButtonSelected(panel->clsRb) != 0)
812 wm_class = wwin->wm_class;
813 else if (WMGetButtonSelected(panel->bothRb) != 0) {
814 wm_instance = wwin->wm_instance;
815 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 < 10; i++) {
824 int flag = 0;
826 switch (i) {
827 case 0:
828 flag = WFLAGP(wwin, no_titlebar);
829 break;
830 case 1:
831 flag = WFLAGP(wwin, no_resizebar);
832 break;
833 case 2:
834 flag = WFLAGP(wwin, no_close_button);
835 break;
836 case 3:
837 flag = WFLAGP(wwin, no_miniaturize_button);
838 break;
839 case 4:
840 flag = WFLAGP(wwin, floating);
841 break;
842 case 5:
843 flag = WFLAGP(wwin, sunken);
844 break;
845 case 6:
846 flag = WFLAGP(wwin, omnipresent);
847 break;
848 case 7:
849 flag = WFLAGP(wwin, start_miniaturized);
850 break;
851 case 8:
852 flag = WFLAGP(wwin, start_maximized!=0);
853 break;
854 case 9:
855 flag = WFLAGP(wwin, skip_window_list);
856 break;
858 WMSetButtonSelected(panel->attrChk[i], flag);
860 for (i=0; i < 8; i++) {
861 int flag = 0;
863 switch (i) {
864 case 0:
865 flag = WFLAGP(wwin, no_hide_others);
866 break;
867 case 1:
868 flag = WFLAGP(wwin, no_bind_keys);
869 break;
870 case 2:
871 flag = WFLAGP(wwin, no_bind_mouse);
872 break;
873 case 3:
874 flag = WFLAGP(wwin, dont_move_off);
875 break;
876 case 4:
877 flag = WFLAGP(wwin, no_focusable);
878 break;
879 case 5:
880 flag = WFLAGP(wwin, dont_save_session);
881 break;
882 case 6:
883 flag = WFLAGP(wwin, emulate_appicon);
884 break;
885 case 7:
886 flag = WFLAGP(wwin, full_maximize);
887 break;
889 WMSetButtonSelected(panel->moreChk[i], flag);
891 if (panel->appFrm && wapp) {
892 for (i=0; i < 2; i++) {
893 int flag = 0;
895 switch (i) {
896 case 0:
897 flag = WFLAGP(wapp->main_window_desc, start_hidden);
898 break;
899 case 1:
900 flag = WFLAGP(wapp->main_window_desc, no_appicon);
901 break;
903 WMSetButtonSelected(panel->appChk[i], flag);
906 WMSetButtonSelected(panel->alwChk, WFLAGP(wwin, always_user_icon));
908 showIconFor(WMWidgetScreen(panel->alwChk), panel, wm_instance, wm_class,
909 REVERT_TO_DEFAULT);
911 n = wDefaultGetStartWorkspace(wwin->screen_ptr, wm_instance, wm_class);
913 if (n >= 0 && n < wwin->screen_ptr->workspace_count) {
914 WMSetPopUpButtonSelectedItem(panel->wsP, n+1);
915 } else {
916 WMSetPopUpButtonSelectedItem(panel->wsP, 0);
921 static void
922 chooseIconCallback(WMWidget *self, void *clientData)
924 char *file;
925 InspectorPanel *panel = (InspectorPanel*)clientData;
926 int result;
928 panel->choosingIcon = 1;
930 WMSetButtonEnabled(panel->browseIconBtn, False);
932 result = wIconChooserDialog(panel->frame->screen_ptr, &file,
933 panel->inspected->wm_instance,
934 panel->inspected->wm_class);
936 panel->choosingIcon = 0;
938 if (!panel->destroyed) { /* kluge */
939 if (result) {
940 WMSetTextFieldText(panel->fileText, file);
941 showIconFor(WMWidgetScreen(self), panel, NULL, NULL,
942 USE_TEXT_FIELD);
943 free(file);
945 WMSetButtonEnabled(panel->browseIconBtn, True);
946 } else {
947 freeInspector(panel);
952 static void
953 textEditedObserver(void *observerData, WMNotification *notification)
955 InspectorPanel *panel = (InspectorPanel*)observerData;
957 if ((long)WMGetNotificationClientData(notification) != WMReturnTextMovement)
958 return;
960 showIconFor(WMWidgetScreen(panel->win), panel, NULL, NULL,
961 USE_TEXT_FIELD);
963 WMPerformButtonClick(panel->updateIconBtn);
968 static void
969 selectSpecification(WMWidget *bPtr, void *data)
971 InspectorPanel *panel = (InspectorPanel*)data;
973 if (bPtr == panel->defaultRb) {
974 WMSetButtonEnabled(panel->applyBtn, False);
975 } else {
976 WMSetButtonEnabled(panel->applyBtn, True);
981 static InspectorPanel*
982 createInspectorForWindow(WWindow *wwin)
984 WScreen *scr = wwin->screen_ptr;
985 InspectorPanel *panel;
986 Window parent;
987 char charbuf[128];
988 int i;
989 int x, y;
990 int btn_width, frame_width;
991 #ifdef wrong_behaviour
992 WMPixmap *pixmap;
993 #endif
994 panel = wmalloc(sizeof(InspectorPanel));
995 memset(panel, 0, sizeof(InspectorPanel));
997 panel->destroyed = 0;
1000 panel->inspected = wwin;
1002 panel->nextPtr = panelList;
1003 panelList = panel;
1006 sprintf(charbuf, "Inspecting %s.%s",
1007 wwin->wm_instance ? wwin->wm_instance : "?",
1008 wwin->wm_class ? wwin->wm_class : "?");
1010 panel->win = WMCreateWindow(scr->wmscreen, "windowInspector");
1011 WMResizeWidget(panel->win, PWIDTH, PHEIGHT);
1014 /**** create common stuff ****/
1016 /* command buttons */
1017 /* (PWIDTH - (left and right margin) - (btn interval)) / 3 */
1018 btn_width = (PWIDTH - (2 * 15) - (2 * 10)) / 3;
1019 panel->saveBtn = WMCreateCommandButton(panel->win);
1020 WMSetButtonAction(panel->saveBtn, (WMAction*)saveSettings, panel);
1021 WMMoveWidget(panel->saveBtn, (2 * (btn_width + 10)) + 15, 310);
1022 WMSetButtonText(panel->saveBtn, _("Save"));
1023 WMResizeWidget(panel->saveBtn, btn_width, 28);
1024 if (wPreferences.flags.noupdates || !(wwin->wm_class || wwin->wm_instance))
1025 WMSetButtonEnabled(panel->saveBtn, False);
1027 panel->applyBtn = WMCreateCommandButton(panel->win);
1028 WMSetButtonAction(panel->applyBtn, (WMAction*)applySettings, panel);
1029 WMMoveWidget(panel->applyBtn, btn_width + 10 + 15, 310);
1030 WMSetButtonText(panel->applyBtn, _("Apply"));
1031 WMResizeWidget(panel->applyBtn, btn_width, 28);
1033 panel->revertBtn = WMCreateCommandButton(panel->win);
1034 WMSetButtonAction(panel->revertBtn, (WMAction*)revertSettings, panel);
1035 WMMoveWidget(panel->revertBtn, 15, 310);
1036 WMSetButtonText(panel->revertBtn, _("Reload"));
1037 WMResizeWidget(panel->revertBtn, btn_width, 28);
1039 /* page selection popup button */
1040 panel->pagePopUp = WMCreatePopUpButton(panel->win);
1041 WMSetPopUpButtonAction(panel->pagePopUp, (WMAction*)changePage, panel);
1042 WMMoveWidget(panel->pagePopUp, 25, 15);
1043 WMResizeWidget(panel->pagePopUp, PWIDTH - 50, 20);
1045 WMAddPopUpButtonItem(panel->pagePopUp, _("Window Specification"));
1046 WMAddPopUpButtonItem(panel->pagePopUp, _("Window Attributes"));
1047 WMAddPopUpButtonItem(panel->pagePopUp, _("Advanced Options"));
1048 WMAddPopUpButtonItem(panel->pagePopUp, _("Icon and Initial Workspace"));
1049 WMAddPopUpButtonItem(panel->pagePopUp, _("Application Specific"));
1051 /**** window spec ****/
1052 frame_width = PWIDTH - (2 * 15);
1054 panel->specFrm = WMCreateFrame(panel->win);
1055 WMSetFrameTitle(panel->specFrm, _("Window Specification"));
1056 WMMoveWidget(panel->specFrm, 15, 65);
1057 WMResizeWidget(panel->specFrm, frame_width, 105);
1060 panel->defaultRb = WMCreateRadioButton(panel->specFrm);
1061 WMMoveWidget(panel->defaultRb, 10, 78);
1062 WMResizeWidget(panel->defaultRb, frame_width - (2 * 10), 20);
1063 WMSetButtonText(panel->defaultRb, _("Defaults for all windows"));
1064 WMSetButtonSelected(panel->defaultRb, False);
1065 WMSetButtonAction(panel->defaultRb, selectSpecification, panel);
1068 if (wwin->wm_class && wwin->wm_instance) {
1069 sprintf(charbuf, "%s.%s", wwin->wm_instance, wwin->wm_class);
1070 panel->bothRb = WMCreateRadioButton(panel->specFrm);
1071 WMMoveWidget(panel->bothRb, 10, 18);
1072 WMResizeWidget(panel->bothRb, frame_width - (2 * 10), 20);
1073 WMSetButtonText(panel->bothRb, charbuf);
1074 WMSetButtonSelected(panel->bothRb, True);
1075 WMGroupButtons(panel->defaultRb, panel->bothRb);
1077 WMSetButtonAction(panel->bothRb, selectSpecification, panel);
1080 if (wwin->wm_instance) {
1081 panel->instRb = WMCreateRadioButton(panel->specFrm);
1082 WMMoveWidget(panel->instRb, 10, 38);
1083 WMResizeWidget(panel->instRb, frame_width - (2 * 10), 20);
1084 WMSetButtonText(panel->instRb, wwin->wm_instance);
1085 WMSetButtonSelected(panel->instRb, False);
1086 WMGroupButtons(panel->defaultRb, panel->instRb);
1088 WMSetButtonAction(panel->instRb, selectSpecification, panel);
1091 if (wwin->wm_class) {
1092 panel->clsRb = WMCreateRadioButton(panel->specFrm);
1093 WMMoveWidget(panel->clsRb, 10, 58);
1094 WMResizeWidget(panel->clsRb, frame_width - (2 * 10), 20);
1095 WMSetButtonText(panel->clsRb, wwin->wm_class);
1096 WMSetButtonSelected(panel->clsRb, False);
1097 WMGroupButtons(panel->defaultRb, panel->clsRb);
1099 WMSetButtonAction(panel->clsRb, selectSpecification, panel);
1102 panel->specLbl = WMCreateLabel(panel->win);
1103 WMMoveWidget(panel->specLbl, 15, 170);
1104 WMResizeWidget(panel->specLbl, frame_width, 100);
1105 WMSetLabelText(panel->specLbl,
1106 _("The configuration will apply to all\n"
1107 "windows that have their WM_CLASS property"
1108 " set to the above selected\nname, when saved."));
1109 WMSetLabelTextAlignment(panel->specLbl, WACenter);
1111 /**** attributes ****/
1112 panel->attrFrm = WMCreateFrame(panel->win);
1113 WMSetFrameTitle(panel->attrFrm, _("Attributes"));
1114 WMMoveWidget(panel->attrFrm, 15, 45);
1115 WMResizeWidget(panel->attrFrm, frame_width, 250);
1117 for (i=0; i < 10; i++) {
1118 char *caption = NULL;
1119 int flag = 0;
1120 char *descr = NULL;
1122 switch (i) {
1123 case 0:
1124 caption = _("Disable Titlebar");
1125 flag = WFLAGP(wwin, no_titlebar);
1126 descr = _("Remove the titlebar of this window.\n"
1127 "To access the window commands menu of a window\n"
1128 "without it's titlebar, press Control+Esc (or the\n"
1129 "equivalent shortcut, if you changed the default\n"
1130 "settings).");
1131 break;
1132 case 1:
1133 caption = _("Disable Resizebar");
1134 flag = WFLAGP(wwin, no_resizebar);
1135 descr = _("Remove the resizebar of this window.");
1136 break;
1137 case 2:
1138 caption = _("Disable Close Button");
1139 flag = WFLAGP(wwin, no_close_button);
1140 descr = _("Remove the `close window' button of this window.");
1141 break;
1142 case 3:
1143 caption = _("Disable Miniaturize Button");
1144 flag = WFLAGP(wwin, no_miniaturize_button);
1145 descr = _("Remove the `miniaturize window' button of the window.");
1146 break;
1147 case 4:
1148 caption = _("Keep on Top / Floating");
1149 flag = WFLAGP(wwin, floating);
1150 descr = _("Keep the window over other windows, not allowing\n"
1151 "them to covert it.");
1152 break;
1153 case 5:
1154 caption = _("Keep at Bottom / Sunken");
1155 flag = WFLAGP(wwin, sunken);
1156 descr = _("Keep the window under all other windows.");
1157 break;
1158 case 6:
1159 caption = _("Omnipresent");
1160 flag = WFLAGP(wwin, omnipresent);
1161 descr = _("Make window occupy all workspaces.");
1162 break;
1163 case 7:
1164 caption = _("Start Miniaturized");
1165 flag = WFLAGP(wwin, start_miniaturized);
1166 descr = _("Make the window be automatically miniaturized when it's\n"
1167 "first shown.");
1168 break;
1169 case 8:
1170 caption = _("Start Maximized");
1171 flag = WFLAGP(wwin, start_maximized!=0);
1172 descr = _("Make the window be automatically maximized when it's\n"
1173 "first shown.");
1174 break;
1175 case 9:
1176 caption = _("Skip Window List");
1177 flag = WFLAGP(wwin, skip_window_list);
1178 descr = _("Do not list the window in the window list menu.");
1179 break;
1181 panel->attrChk[i] = WMCreateSwitchButton(panel->attrFrm);
1182 WMMoveWidget(panel->attrChk[i], 10, 20*(i+1));
1183 WMResizeWidget(panel->attrChk[i], frame_width-15, 20);
1184 WMSetButtonSelected(panel->attrChk[i], flag);
1185 WMSetButtonText(panel->attrChk[i], caption);
1187 WMSetBalloonTextForView(descr, WMWidgetView(panel->attrChk[i]));
1191 /**** more attributes ****/
1192 panel->moreFrm = WMCreateFrame(panel->win);
1193 WMSetFrameTitle(panel->moreFrm, _("Advanced"));
1194 WMMoveWidget(panel->moreFrm, 15, 45);
1195 WMResizeWidget(panel->moreFrm, frame_width, 250);
1197 for (i=0; i < 8; i++) {
1198 char *caption = NULL;
1199 int flag = 0;
1200 char *descr = NULL;
1202 switch (i) {
1203 case 0:
1204 caption = _("Ignore HideOthers");
1205 flag = WFLAGP(wwin, no_hide_others);
1206 descr = _("Do not hide the window when issuing the\n"
1207 "`HideOthers' command.");
1208 break;
1209 case 1:
1210 caption = _("Don't Bind Keyboard Shortcuts");
1211 flag = WFLAGP(wwin, no_bind_keys);
1212 descr = _("Do not bind keyboard shortcuts from Window Maker\n"
1213 "when this window is focused. This will allow the\n"
1214 "window to receive all key combinations regardless\n"
1215 "of your shortcut configuration.");
1216 break;
1217 case 2:
1218 caption = _("Don't Bind Mouse Clicks");
1219 flag = WFLAGP(wwin, no_bind_mouse);
1220 descr = _("Do not bind mouse actions, such as `Alt'+drag\n"
1221 "in the window (when alt is the modifier you have"
1222 "configured).");
1223 break;
1224 case 3:
1225 caption = _("Keep Inside Screen");
1226 flag = WFLAGP(wwin, dont_move_off);
1227 descr = _("Do not allow the window to move itself completely\n"
1228 "outside the screen. For bug compatibility.\n");
1229 break;
1230 case 4:
1231 caption = _("Don't Let It Take Focus");
1232 flag = WFLAGP(wwin, no_focusable);
1233 descr = _("Do not let the window take keyboard focus when you\n"
1234 "click on it.");
1235 break;
1236 case 5:
1237 caption = _("Don't Save Session");
1238 flag = WFLAGP(wwin, dont_save_session);
1239 descr = _("Do not save the associated application in the\n"
1240 "session's state, so that it won't be restarted\n"
1241 "together with other applications when Window Maker\n"
1242 "starts.");
1243 break;
1244 case 6:
1245 caption = _("Emulate Application Icon");
1246 flag = WFLAGP(wwin, emulate_appicon);
1247 descr = _("Make this window act as an application that provides\n"
1248 "enough information to Window Maker for a dockable\n"
1249 "application icon to be created.");
1250 break;
1251 case 7:
1252 caption = _("Full Screen Maximization");
1253 flag = WFLAGP(wwin, full_maximize);
1254 descr = _("Make the window use the whole screen space when it's\n"
1255 "maximized. The titlebar and resizebar will be moved\n"
1256 "to outside the screen.");
1257 break;
1259 panel->moreChk[i] = WMCreateSwitchButton(panel->moreFrm);
1260 WMMoveWidget(panel->moreChk[i], 10, 20*(i+1));
1261 WMResizeWidget(panel->moreChk[i], frame_width-15, 20);
1262 WMSetButtonSelected(panel->moreChk[i], flag);
1263 WMSetButtonText(panel->moreChk[i], caption);
1265 WMSetBalloonTextForView(descr, WMWidgetView(panel->moreChk[i]));
1268 /* miniwindow/workspace */
1269 panel->iconFrm = WMCreateFrame(panel->win);
1270 WMMoveWidget(panel->iconFrm, 15, 50);
1271 WMResizeWidget(panel->iconFrm, PWIDTH - (2 * 15), 170);
1272 WMSetFrameTitle(panel->iconFrm, _("Miniwindow Image"));
1274 panel->iconLbl = WMCreateLabel(panel->iconFrm);
1275 WMMoveWidget(panel->iconLbl, PWIDTH - (2 * 15) - 22 - 64, 30);
1276 WMResizeWidget(panel->iconLbl, 64, 64);
1277 WMSetLabelRelief(panel->iconLbl, WRGroove);
1278 WMSetLabelImagePosition(panel->iconLbl, WIPImageOnly);
1280 panel->browseIconBtn = WMCreateCommandButton(panel->iconFrm);
1281 WMSetButtonAction(panel->browseIconBtn, chooseIconCallback, panel);
1282 WMMoveWidget(panel->browseIconBtn, 22, 30);
1283 WMResizeWidget(panel->browseIconBtn, 100, 26);
1284 WMSetButtonText(panel->browseIconBtn, _("Browse..."));
1286 #if 0
1287 panel->updateIconBtn = WMCreateCommandButton(panel->iconFrm);
1288 WMSetButtonAction(panel->updateIconBtn, (WMAction*)updateIcon, panel);
1289 WMMoveWidget(panel->updateIconBtn, 22, 65);
1290 WMResizeWidget(panel->updateIconBtn, 100, 26);
1291 WMSetButtonText(panel->updateIconBtn, _("Update"));
1292 #endif
1293 #ifdef wrong_behaviour
1294 WMSetButtonImagePosition(panel->updateIconBtn, WIPRight);
1295 pixmap = WMGetSystemPixmap(scr->wmscreen, WSIReturnArrow);
1296 WMSetButtonImage(panel->updateIconBtn, pixmap);
1297 WMReleasePixmap(pixmap);
1298 pixmap = WMGetSystemPixmap(scr->wmscreen, WSIHighlightedReturnArrow);
1299 WMSetButtonAltImage(panel->updateIconBtn, pixmap);
1300 WMReleasePixmap(pixmap);
1301 #endif
1303 panel->fileLbl = WMCreateLabel(panel->iconFrm);
1304 WMMoveWidget(panel->fileLbl, 20, 95);
1305 WMResizeWidget(panel->fileLbl, PWIDTH - (2 * 15) - (2 * 20), 14);
1306 WMSetLabelText(panel->fileLbl, _("Icon File Name:"));
1308 panel->fileText = WMCreateTextField(panel->iconFrm);
1309 WMMoveWidget(panel->fileText, 20, 115);
1310 WMResizeWidget(panel->fileText, PWIDTH - (2 * 15) - (2 * 15), 20);
1311 WMSetTextFieldText(panel->fileText, NULL);
1312 WMAddNotificationObserver(textEditedObserver, panel,
1313 WMTextDidEndEditingNotification,
1314 panel->fileText);
1315 panel->alwChk = WMCreateSwitchButton(panel->iconFrm);
1316 WMMoveWidget(panel->alwChk, 20, 140);
1317 WMResizeWidget(panel->alwChk, PWIDTH - (2 * 15) - (2 * 15), 20);
1318 WMSetButtonText(panel->alwChk, _("Ignore client supplied icon"));
1319 WMSetButtonSelected(panel->alwChk, WFLAGP(wwin, always_user_icon));
1322 panel->wsFrm = WMCreateFrame(panel->win);
1323 WMMoveWidget(panel->wsFrm, 15, 225);
1324 WMResizeWidget(panel->wsFrm, PWIDTH - (2 * 15), 70);
1325 WMSetFrameTitle(panel->wsFrm, _("Initial Workspace"));
1327 WMSetBalloonTextForView(_("The workspace to place the window when it's"
1328 "first shown."), WMWidgetView(panel->wsFrm));
1330 panel->wsP = WMCreatePopUpButton(panel->wsFrm);
1331 WMMoveWidget(panel->wsP, 20, 30);
1332 WMResizeWidget(panel->wsP, PWIDTH - (2 * 15) - (2 * 20), 20);
1333 WMAddPopUpButtonItem(panel->wsP, _("Nowhere in particular"));
1334 for (i = 0; i < wwin->screen_ptr->workspace_count; i++) {
1335 WMAddPopUpButtonItem(panel->wsP, scr->workspaces[i]->name);
1338 i = wDefaultGetStartWorkspace(wwin->screen_ptr, wwin->wm_instance,
1339 wwin->wm_class);
1340 if (i >= 0 && i <= wwin->screen_ptr->workspace_count) {
1341 WMSetPopUpButtonSelectedItem(panel->wsP, i + 1);
1342 } else {
1343 WMSetPopUpButtonSelectedItem(panel->wsP, 0);
1346 /* application wide attributes */
1347 if (wwin->main_window != None) {
1348 WApplication *wapp = wApplicationOf(wwin->main_window);
1350 panel->appFrm = WMCreateFrame(panel->win);
1351 WMSetFrameTitle(panel->appFrm, _("Application Wide"));
1352 WMMoveWidget(panel->appFrm, 15, 50);
1353 WMResizeWidget(panel->appFrm, frame_width, 240);
1355 for (i=0; i < 2; i++) {
1356 char *caption = NULL;
1357 int flag = 0;
1358 char *descr = NULL;
1360 switch (i) {
1361 case 0:
1362 caption = _("Start Hidden");
1363 flag = WFLAGP(wapp->main_window_desc, start_hidden);
1364 descr = _("Automatically hide application when it's started.");
1365 break;
1366 case 1:
1367 caption = _("No Application Icon");
1368 flag = WFLAGP(wapp->main_window_desc, no_appicon);
1369 descr = _("Disable the application icon for the application.\n"
1370 "Note that you won't be able to dock it anymore,\n"
1371 "and any icons that are already docked will stop\n"
1372 "working correctly.");
1373 break;
1375 panel->appChk[i] = WMCreateSwitchButton(panel->appFrm);
1376 WMMoveWidget(panel->appChk[i], 10, 20*(i+1));
1377 WMResizeWidget(panel->appChk[i], 205, 20);
1378 WMSetButtonSelected(panel->appChk[i], flag);
1379 WMSetButtonText(panel->appChk[i], caption);
1381 WMSetBalloonTextForView(descr, WMWidgetView(panel->appChk[i]));
1384 if (WFLAGP(wwin, emulate_appicon)) {
1385 WMSetButtonEnabled(panel->appChk[1], False);
1386 WMSetButtonEnabled(panel->moreChk[6], True);
1387 } else {
1388 WMSetButtonEnabled(panel->appChk[1], True);
1389 WMSetButtonEnabled(panel->moreChk[6], False);
1391 } else {
1392 int tmp;
1394 if ((wwin->transient_for!=None && wwin->transient_for!=scr->root_win)
1395 || !wwin->wm_class || !wwin->wm_instance)
1396 tmp = False;
1397 else
1398 tmp = True;
1399 WMSetButtonEnabled(panel->moreChk[6], tmp);
1401 WMSetPopUpButtonItemEnabled(panel->pagePopUp, 4, False);
1402 panel->appFrm = NULL;
1405 /* if the window is a transient, don't let it have a miniaturize
1406 * button */
1407 if (wWindowFor(wwin->transient_for)!=NULL)
1408 WMSetButtonEnabled(panel->attrChk[3], False);
1409 else
1410 WMSetButtonEnabled(panel->attrChk[3], True);
1413 if (!wwin->wm_class && !wwin->wm_instance) {
1414 WMSetPopUpButtonItemEnabled(panel->pagePopUp, 0, False);
1418 WMRealizeWidget(panel->win);
1420 WMMapSubwidgets(panel->win);
1421 WMMapSubwidgets(panel->specFrm);
1422 WMMapSubwidgets(panel->attrFrm);
1423 WMMapSubwidgets(panel->moreFrm);
1424 WMMapSubwidgets(panel->iconFrm);
1425 WMMapSubwidgets(panel->wsFrm);
1426 if (panel->appFrm)
1427 WMMapSubwidgets(panel->appFrm);
1429 WMSetPopUpButtonSelectedItem(panel->pagePopUp, 1);
1430 changePage(panel->pagePopUp, panel);
1433 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, PWIDTH, PHEIGHT,
1434 0, 0, 0);
1435 XSelectInput(dpy, parent, KeyPressMask|KeyReleaseMask);
1436 panel->parent = parent;
1437 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
1439 WMMapWidget(panel->win);
1441 XSetTransientForHint(dpy, parent, wwin->client_win);
1443 x = wwin->frame_x+wwin->frame->core->width/2;
1444 y = wwin->frame_y+wwin->frame->top_width*2;
1445 if (y + PHEIGHT > scr->scr_height)
1446 y = scr->scr_height - PHEIGHT - 30;
1447 if (x + PWIDTH > scr->scr_width)
1448 x = scr->scr_width - PWIDTH;
1449 panel->frame = wManageInternalWindow(scr, parent, wwin->client_win,
1450 charbuf, x, y, PWIDTH, PHEIGHT);
1452 /* kluge to know who should get the key events */
1453 panel->frame->client_leader = WMWidgetXID(panel->win);
1455 WSETUFLAG(panel->frame, no_closable, 0);
1456 WSETUFLAG(panel->frame, no_close_button, 0);
1457 wWindowUpdateButtonImages(panel->frame);
1458 wFrameWindowShowButton(panel->frame->frame, WFF_RIGHT_BUTTON);
1459 panel->frame->frame->on_click_right = destroyInspector;
1461 wWindowMap(panel->frame);
1463 showIconFor(WMWidgetScreen(panel->alwChk), panel, wwin->wm_instance,
1464 wwin->wm_class, UPDATE_TEXT_FIELD);
1466 return panel;
1470 void
1471 wShowInspectorForWindow(WWindow *wwin)
1473 if (wwin->flags.inspector_open)
1474 return;
1476 WMSetBalloonEnabled(wwin->screen_ptr->wmscreen, wPreferences.help_balloon);
1478 make_keys();
1479 wwin->flags.inspector_open = 1;
1480 wwin->inspector = createInspectorForWindow(wwin);;