Removed "Keep Attracted Icons" from Clip's menu.
[wmaker-crm.git] / src / winspector.c
blobdd864018138650755e2273f1539b6918dae81f7d
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;
77 #ifdef XKB_BUTTON_HINT
78 static proplist_t ANoLanguageButton;
79 #endif
81 static proplist_t AStartWorkspace;
83 static proplist_t AIcon;
85 /* application wide options */
86 static proplist_t AStartHidden;
89 static proplist_t AnyWindow;
90 static proplist_t EmptyString;
91 static proplist_t Yes, No;
94 #define PWIDTH 270
95 #define PHEIGHT 350
98 static void applySettings(WMButton *button, InspectorPanel *panel);
100 static void
101 make_keys()
103 if (ANoTitlebar!=NULL)
104 return;
106 AIcon = PLMakeString("Icon");
107 ANoTitlebar = PLMakeString("NoTitlebar");
108 ANoResizebar = PLMakeString("NoResizebar");
109 ANoMiniaturizeButton = PLMakeString("NoMiniaturizeButton");
110 ANoCloseButton = PLMakeString("NoCloseButton");
111 ANoHideOthers = PLMakeString("NoHideOthers");
112 ANoMouseBindings = PLMakeString("NoMouseBindings");
113 ANoKeyBindings = PLMakeString("NoKeyBindings");
114 ANoAppIcon = PLMakeString("NoAppIcon");
115 AKeepOnTop = PLMakeString("KeepOnTop");
116 AKeepOnBottom = PLMakeString("KeepOnBottom");
117 AOmnipresent = PLMakeString("Omnipresent");
118 ASkipWindowList = PLMakeString("SkipWindowList");
119 AKeepInsideScreen = PLMakeString("KeepInsideScreen");
120 AUnfocusable = PLMakeString("Unfocusable");
121 AAlwaysUserIcon = PLMakeString("AlwaysUserIcon");
122 AStartMiniaturized = PLMakeString("StartMiniaturized");
123 AStartMaximized = PLMakeString("StartMaximized");
124 AStartHidden = PLMakeString("StartHidden");
125 ADontSaveSession = PLMakeString("DontSaveSession");
126 AEmulateAppIcon = PLMakeString("EmulateAppIcon");
127 AFullMaximize = PLMakeString("FullMaximize");
128 #ifdef XKB_BUTTON_HINT
129 ANoLanguageButton = PLMakeString("NoLanguageButton");
130 #endif
132 AStartWorkspace = PLMakeString("StartWorkspace");
134 AnyWindow = PLMakeString("*");
135 EmptyString = PLMakeString("");
136 Yes = PLMakeString("Yes");
137 No = PLMakeString("No");
142 static void
143 freeInspector(InspectorPanel *panel)
145 panel->destroyed = 1;
146 if (panel->choosingIcon)
147 return;
149 WMDestroyWidget(panel->win);
151 XDestroyWindow(dpy, panel->parent);
153 free(panel);
157 static void
158 destroyInspector(WCoreWindow *foo, void *data, XEvent *event)
160 InspectorPanel *panel;
161 InspectorPanel *tmp;
163 panel = panelList;
164 while (panel->frame!=data)
165 panel = panel->nextPtr;
167 if (panelList == panel)
168 panelList = panel->nextPtr;
169 else {
170 tmp = panelList;
171 while (tmp->nextPtr!=panel) {
172 tmp = tmp->nextPtr;
174 tmp->nextPtr = panel->nextPtr;
176 panel->inspected->flags.inspector_open = 0;
177 panel->inspected->inspector = NULL;
179 WMRemoveNotificationObserver(panel);
181 wWindowUnmap(panel->frame);
182 wUnmanageWindow(panel->frame, True, False);
184 freeInspector(panel);
189 void
190 wDestroyInspectorPanels()
192 InspectorPanel *panel;
194 while (panelList != NULL) {
195 panel = panelList;
196 panelList = panelList->nextPtr;
197 wUnmanageWindow(panel->frame, False, False);
198 WMDestroyWidget(panel->win);
200 panel->inspected->flags.inspector_open = 0;
201 panel->inspected->inspector = NULL;
203 free(panel);
208 static void
209 changePage(WMPopUpButton *bPtr, InspectorPanel *panel)
211 int page;
213 page = WMGetPopUpButtonSelectedItem(bPtr);
215 if (page == 0) {
216 WMMapWidget(panel->specFrm);
217 WMMapWidget(panel->specLbl);
218 } else if (page == 1) {
219 WMMapWidget(panel->attrFrm);
220 } else if (page == 2) {
221 WMMapWidget(panel->moreFrm);
222 } else if (page == 3) {
223 WMMapWidget(panel->iconFrm);
224 WMMapWidget(panel->wsFrm);
225 } else {
226 WMMapWidget(panel->appFrm);
229 if (page != 0) {
230 WMUnmapWidget(panel->specFrm);
231 WMUnmapWidget(panel->specLbl);
233 if (page != 1)
234 WMUnmapWidget(panel->attrFrm);
235 if (page != 2)
236 WMUnmapWidget(panel->moreFrm);
237 if (page != 3) {
238 WMUnmapWidget(panel->iconFrm);
239 WMUnmapWidget(panel->wsFrm);
241 if (page != 4 && panel->appFrm)
242 WMUnmapWidget(panel->appFrm);
246 #define USE_TEXT_FIELD 1
247 #define UPDATE_TEXT_FIELD 2
248 #define REVERT_TO_DEFAULT 4
251 static int
252 showIconFor(WMScreen *scrPtr, InspectorPanel *panel,
253 char *wm_instance, char *wm_class, int flags)
255 WMPixmap *pixmap = (WMPixmap*) NULL;
256 char *file=NULL, *path=NULL;
257 char *db_icon=NULL;
259 if ((flags & USE_TEXT_FIELD) != 0) {
260 file = WMGetTextFieldText(panel->fileText);
261 if (file && file[0] == 0) {
262 free(file);
263 file = NULL;
265 } else {
266 db_icon = wDefaultGetIconFile(panel->inspected->screen_ptr,
267 wm_instance, wm_class, False);
268 if(db_icon != NULL)
269 file = wstrdup(db_icon);
271 if (db_icon!=NULL && (flags & REVERT_TO_DEFAULT)!=0) {
272 if (file)
273 file = wstrdup(db_icon);
274 flags |= UPDATE_TEXT_FIELD;
277 if ((flags & UPDATE_TEXT_FIELD) != 0) {
278 WMSetTextFieldText(panel->fileText, file);
281 if (file) {
282 path = FindImage(wPreferences.icon_path, file);
284 if (!path) {
285 char *buf;
287 buf = wmalloc(strlen(file)+80);
288 sprintf(buf, _("Could not find icon \"%s\" specified for this window"),
289 file);
290 wMessageDialog(panel->frame->screen_ptr, _("Error"), buf,
291 _("OK"), NULL, NULL);
292 free(buf);
293 free(file);
294 return -1;
297 pixmap = WMCreatePixmapFromFile(scrPtr, path);
298 free(path);
300 if (!pixmap) {
301 char *buf;
303 buf = wmalloc(strlen(file)+80);
304 sprintf(buf, _("Could not open specified icon \"%s\":%s"),
305 file, RMessageForError(RErrorCode));
306 wMessageDialog(panel->frame->screen_ptr, _("Error"), buf,
307 _("OK"), NULL, NULL);
308 free(buf);
309 free(file);
310 return -1;
312 free(file);
315 WMSetLabelImage(panel->iconLbl, pixmap);
316 if (pixmap)
317 WMReleasePixmap(pixmap);
319 return 0;
322 #if 0
323 static void
324 updateIcon(WMButton *button, InspectorPanel *panel)
326 showIconFor(WMWidgetScreen(button), panel, NULL, NULL, USE_TEXT_FIELD);
328 #endif
330 static int
331 getBool(proplist_t value)
333 char *val;
335 if (!PLIsString(value)) {
336 return 0;
338 if (!(val = PLGetString(value))) {
339 return 0;
342 if ((val[1]=='\0' && (val[0]=='y' || val[0]=='Y' || val[0]=='T'
343 || val[0]=='t' || val[0]=='1'))
344 || (strcasecmp(val, "YES")==0 || strcasecmp(val, "TRUE")==0)) {
346 return 1;
347 } else if ((val[1]=='\0'
348 && (val[0]=='n' || val[0]=='N' || val[0]=='F'
349 || val[0]=='f' || val[0]=='0'))
350 || (strcasecmp(val, "NO")==0 || strcasecmp(val, "FALSE")==0)) {
352 return 0;
353 } else {
354 wwarning(_("can't convert \"%s\" to boolean"), val);
355 return 0;
360 #define UPDATE_DEFAULTS 1
361 #define IS_BOOLEAN 2
365 * Will insert the attribute = value; pair in window's list,
366 * if it's different from the defaults.
367 * Defaults means either defaults database, or attributes saved
368 * for the default window "*". This is to let one revert options that are
369 * global because they were saved for all windows ("*").
374 static int
375 insertAttribute(proplist_t dict, proplist_t window, proplist_t attr,
376 proplist_t value, int flags)
378 proplist_t def_win, def_value=NULL;
379 int update = 0;
380 int modified = 0;
382 if (!(flags & UPDATE_DEFAULTS) && dict) {
383 if ((def_win = PLGetDictionaryEntry(dict, AnyWindow)) != NULL) {
384 def_value = PLGetDictionaryEntry(def_win, attr);
388 /* If we could not find defaults in database, fall to hardcoded values.
389 * Also this is true if we save defaults for all windows
391 if (!def_value)
392 def_value = ((flags & IS_BOOLEAN) != 0) ? No : EmptyString;
394 if ((flags & IS_BOOLEAN))
395 update = (getBool(value) != getBool(def_value));
396 else {
397 update = !PLIsEqual(value, def_value);
400 if (update) {
401 PLInsertDictionaryEntry(window, attr, value);
402 modified = 1;
405 return modified;
409 static void
410 saveSettings(WMButton *button, InspectorPanel *panel)
412 WWindow *wwin = panel->inspected;
413 WDDomain *db = WDWindowAttributes;
414 proplist_t dict = db->dictionary;
415 proplist_t winDic, value, key;
416 char *icon_file;
417 int flags = 0;
418 int different = 0;
420 /* Save will apply the changes and save them */
421 applySettings(panel->applyBtn, panel);
423 if (WMGetButtonSelected(panel->instRb) != 0)
424 key = PLMakeString(wwin->wm_instance);
425 else if (WMGetButtonSelected(panel->clsRb) != 0)
426 key = PLMakeString(wwin->wm_class);
427 else if (WMGetButtonSelected(panel->bothRb) != 0) {
428 char *buffer;
430 buffer = wmalloc(strlen(wwin->wm_instance)+strlen(wwin->wm_class)+4);
431 strcat(strcat(strcpy(buffer, wwin->wm_instance), "."), wwin->wm_class);
432 key = PLMakeString(buffer);
433 free(buffer);
434 } else if (WMGetButtonSelected(panel->defaultRb) != 0) {
435 key = PLRetain(AnyWindow);
436 flags = UPDATE_DEFAULTS;
437 } else
438 key = NULL;
440 if (!key)
441 return;
443 if (!dict) {
444 dict = PLMakeDictionaryFromEntries(NULL, NULL, NULL);
445 if (dict) {
446 db->dictionary = dict;
447 value = PLMakeString(db->path);
448 PLSetFilename(dict, value);
449 PLRelease(value);
451 else {
452 PLRelease(key);
453 return;
457 if (showIconFor(WMWidgetScreen(button), panel, NULL, NULL,
458 USE_TEXT_FIELD) < 0)
459 return;
461 PLSetStringCmpHook(NULL);
463 winDic = PLMakeDictionaryFromEntries(NULL, NULL, NULL);
465 /* Update icon for window */
466 icon_file = WMGetTextFieldText(panel->fileText);
467 if (icon_file) {
468 if (icon_file[0] != 0) {
469 value = PLMakeString(icon_file);
470 different |= insertAttribute(dict, winDic, AIcon, value, flags);
471 PLRelease(value);
473 free(icon_file);
477 int i = WMGetPopUpButtonSelectedItem(panel->wsP);
479 i--;
481 if (i>=0 && i < panel->frame->screen_ptr->workspace_count) {
482 value = PLMakeString(panel->frame->screen_ptr->workspaces[i]->name);
483 different |= insertAttribute(dict, winDic, AStartWorkspace, value,
484 flags);
485 PLRelease(value);
489 flags |= IS_BOOLEAN;
491 value = (WMGetButtonSelected(panel->alwChk)!=0) ? Yes : No;
492 different |= insertAttribute(dict, winDic, AAlwaysUserIcon, value, flags);
494 value = (WMGetButtonSelected(panel->attrChk[0])!=0) ? Yes : No;
495 different |= insertAttribute(dict, winDic, ANoTitlebar, value, flags);
497 value = (WMGetButtonSelected(panel->attrChk[1])!=0) ? Yes : No;
498 different |= insertAttribute(dict, winDic, ANoResizebar, value, flags);
500 value = (WMGetButtonSelected(panel->attrChk[2])!=0) ? Yes : No;
501 different |= insertAttribute(dict, winDic, ANoCloseButton, value, flags);
503 value = (WMGetButtonSelected(panel->attrChk[3])!=0) ? Yes : No;
504 different |= insertAttribute(dict, winDic, ANoMiniaturizeButton, value, flags);
506 value = (WMGetButtonSelected(panel->attrChk[4])!=0) ? Yes : No;
507 different |= insertAttribute(dict, winDic, AKeepOnTop, value, flags);
509 value = (WMGetButtonSelected(panel->attrChk[5])!=0) ? Yes : No;
510 different |= insertAttribute(dict, winDic, AKeepOnBottom, value, flags);
512 value = (WMGetButtonSelected(panel->attrChk[6])!=0) ? Yes : No;
513 different |= insertAttribute(dict, winDic, AOmnipresent, value, flags);
515 value = (WMGetButtonSelected(panel->attrChk[7])!=0) ? Yes : No;
516 different |= insertAttribute(dict, winDic, AStartMiniaturized, value, flags);
518 value = (WMGetButtonSelected(panel->attrChk[8])!=0) ? Yes : No;
519 different |= insertAttribute(dict, winDic, AStartMaximized, value, flags);
521 value = (WMGetButtonSelected(panel->attrChk[9])!=0) ? Yes : No;
522 different |= insertAttribute(dict, winDic, ASkipWindowList, value, flags);
525 value = (WMGetButtonSelected(panel->moreChk[0])!=0) ? Yes : No;
526 different |= insertAttribute(dict, winDic, ANoHideOthers, value, flags);
528 value = (WMGetButtonSelected(panel->moreChk[1])!=0) ? Yes : No;
529 different |= insertAttribute(dict, winDic, ANoKeyBindings, value, flags);
531 value = (WMGetButtonSelected(panel->moreChk[2])!=0) ? Yes : No;
532 different |= insertAttribute(dict, winDic, ANoMouseBindings, value, flags);
534 value = (WMGetButtonSelected(panel->moreChk[3])!=0) ? Yes : No;
535 different |= insertAttribute(dict, winDic, AKeepInsideScreen,value, flags);
537 value = (WMGetButtonSelected(panel->moreChk[4])!=0) ? Yes : No;
538 different |= insertAttribute(dict, winDic, AUnfocusable, value, flags);
540 value = (WMGetButtonSelected(panel->moreChk[5])!=0) ? Yes : No;
541 different |= insertAttribute(dict, winDic, ADontSaveSession, value, flags);
543 value = (WMGetButtonSelected(panel->moreChk[6])!=0) ? Yes : No;
544 different |= insertAttribute(dict, winDic, AEmulateAppIcon, value, flags);
546 value = (WMGetButtonSelected(panel->moreChk[7])!=0) ? Yes : No;
547 different |= insertAttribute(dict, winDic, AFullMaximize, value, flags);
549 #ifdef XKB_BUTTON_HINT
550 value = (WMGetButtonSelected(panel->moreChk[8])!=0) ? Yes : No;
551 different |= insertAttribute(dict, winDic, ANoLanguageButton, value, flags);
552 #endif
554 /* application wide settings for when */
555 /* the window is the leader, save the attribute with the others */
556 if (panel->inspected->main_window == panel->inspected->client_win) {
558 value = (WMGetButtonSelected(panel->appChk[0])!=0) ? Yes : No;
559 different |= insertAttribute(dict, winDic, AStartHidden, value, flags);
561 value = (WMGetButtonSelected(panel->appChk[1])!=0) ? Yes : No;
562 different |= insertAttribute(dict, winDic, ANoAppIcon, value, flags);
565 PLRemoveDictionaryEntry(dict, key);
566 if (different) {
567 PLInsertDictionaryEntry(dict, key, winDic);
570 PLRelease(key);
571 PLRelease(winDic);
573 different = 0;
575 /* application wide settings */
576 if (panel->inspected->main_window != panel->inspected->client_win
577 && !(flags & UPDATE_DEFAULTS)) {
578 WApplication *wapp;
579 proplist_t appDic;
581 wapp = wApplicationOf(panel->inspected->main_window);
582 if (wapp) {
583 char *iconFile;
584 char *buffer;
586 appDic = PLMakeDictionaryFromEntries(NULL, NULL, NULL);
588 assert(wapp->main_window_desc->wm_instance!=NULL);
589 assert(wapp->main_window_desc->wm_class!=NULL);
591 buffer = wmalloc(strlen(wapp->main_window_desc->wm_instance)
592 +strlen(wapp->main_window_desc->wm_class)+4);
593 strcat(strcpy(buffer, wapp->main_window_desc->wm_instance), ".");
594 strcat(buffer, wapp->main_window_desc->wm_class);
595 key = PLMakeString(buffer);
596 free(buffer);
598 iconFile = wDefaultGetIconFile(wwin->screen_ptr,
599 wapp->main_window_desc->wm_instance,
600 wapp->main_window_desc->wm_class,
601 False);
603 if (iconFile && iconFile[0]!=0) {
604 value = PLMakeString(iconFile);
605 different |= insertAttribute(dict, appDic, AIcon, value,
606 flags&~IS_BOOLEAN);
607 PLRelease(value);
610 value = (WMGetButtonSelected(panel->appChk[0])!=0) ? Yes : No;
611 different |= insertAttribute(dict, appDic, AStartHidden, value,
612 flags);
614 value = (WMGetButtonSelected(panel->appChk[1])!=0) ? Yes : No;
615 different |= insertAttribute(dict, appDic, ANoAppIcon, value,
616 flags);
618 PLRemoveDictionaryEntry(dict, key);
619 if (different) {
620 PLInsertDictionaryEntry(dict, key, appDic);
622 PLRelease(key);
623 PLRelease(appDic);
627 PLSave(dict, YES);
629 /* clean up */
630 PLSetStringCmpHook(StringCompareHook);
634 static void
635 makeAppIconFor(WApplication *wapp)
637 WScreen *scr = wapp->main_window_desc->screen_ptr;
639 if (wapp->app_icon)
640 return;
642 if (!WFLAGP(wapp->main_window_desc, no_appicon))
643 wapp->app_icon = wAppIconCreate(wapp->main_window_desc);
644 else
645 wapp->app_icon = NULL;
647 if (wapp->app_icon) {
648 WIcon *icon = wapp->app_icon->icon;
649 WDock *clip = scr->workspaces[scr->current_workspace]->clip;
650 int x=0, y=0;
652 wapp->app_icon->main_window = wapp->main_window;
654 if (clip && clip->attract_icons && wDockFindFreeSlot(clip, &x, &y)) {
655 wapp->app_icon->attracted = 1;
656 if (!wapp->app_icon->icon->shadowed) {
657 wapp->app_icon->icon->shadowed = 1;
658 wapp->app_icon->icon->force_paint = 1;
660 wDockAttachIcon(clip, wapp->app_icon, x, y);
661 } else {
662 PlaceIcon(scr, &x, &y);
663 wAppIconMove(wapp->app_icon, x, y);
665 if (!clip || !wapp->app_icon->attracted || !clip->collapsed)
666 XMapWindow(dpy, icon->core->window);
668 if (wPreferences.auto_arrange_icons && !wapp->app_icon->attracted)
669 wArrangeIcons(wapp->main_window_desc->screen_ptr, True);
674 static void
675 removeAppIconFor(WApplication *wapp)
677 if (!wapp->app_icon)
678 return;
680 if (wapp->app_icon->docked && !wapp->app_icon->attracted) {
681 wapp->app_icon->running = 0;
682 /* since we keep it, we don't care if it was attracted or not */
683 wapp->app_icon->attracted = 0;
684 wapp->app_icon->icon->shadowed = 0;
685 wapp->app_icon->main_window = None;
686 wapp->app_icon->pid = 0;
687 wapp->app_icon->icon->owner = NULL;
688 wapp->app_icon->icon->icon_win = None;
689 wapp->app_icon->icon->force_paint = 1;
690 wAppIconPaint(wapp->app_icon);
691 } else if (wapp->app_icon->docked) {
692 wapp->app_icon->running = 0;
693 wDockDetach(wapp->app_icon->dock, wapp->app_icon);
694 } else {
695 wAppIconDestroy(wapp->app_icon);
697 wapp->app_icon = NULL;
698 if (wPreferences.auto_arrange_icons)
699 wArrangeIcons(wapp->main_window_desc->screen_ptr, True);
703 static void
704 applySettings(WMButton *button, InspectorPanel *panel)
706 WWindow *wwin = panel->inspected;
707 WApplication *wapp = wApplicationOf(wwin->main_window);
708 int floating, sunken, skip_window_list;
709 int old_omnipresent;
710 int old_no_bind_keys;
711 int old_no_bind_mouse;
713 old_omnipresent = WFLAGP(wwin, omnipresent);
714 old_no_bind_keys = WFLAGP(wwin, no_bind_keys);
715 old_no_bind_mouse = WFLAGP(wwin, no_bind_mouse);
717 showIconFor(WMWidgetScreen(button), panel, NULL, NULL, USE_TEXT_FIELD);
719 WSETUFLAG(wwin, no_titlebar, WMGetButtonSelected(panel->attrChk[0]));
720 WSETUFLAG(wwin, no_resizebar, WMGetButtonSelected(panel->attrChk[1]));
721 WSETUFLAG(wwin, no_close_button, WMGetButtonSelected(panel->attrChk[2]));
722 WSETUFLAG(wwin, no_miniaturize_button, WMGetButtonSelected(panel->attrChk[3]));
723 floating = WMGetButtonSelected(panel->attrChk[4]);
724 sunken = WMGetButtonSelected(panel->attrChk[5]);
725 WSETUFLAG(wwin, omnipresent, WMGetButtonSelected(panel->attrChk[6]));
726 WSETUFLAG(wwin, start_miniaturized, WMGetButtonSelected(panel->attrChk[7]));
727 WSETUFLAG(wwin, start_maximized, WMGetButtonSelected(panel->attrChk[8]));
728 skip_window_list = WMGetButtonSelected(panel->attrChk[9]);
730 WSETUFLAG(wwin, no_hide_others, WMGetButtonSelected(panel->moreChk[0]));
731 WSETUFLAG(wwin, no_bind_keys, WMGetButtonSelected(panel->moreChk[1]));
732 WSETUFLAG(wwin, no_bind_mouse, WMGetButtonSelected(panel->moreChk[2]));
733 WSETUFLAG(wwin, dont_move_off, WMGetButtonSelected(panel->moreChk[3]));
734 WSETUFLAG(wwin, no_focusable, WMGetButtonSelected(panel->moreChk[4]));
735 WSETUFLAG(wwin, dont_save_session, WMGetButtonSelected(panel->moreChk[5]));
736 WSETUFLAG(wwin, emulate_appicon, WMGetButtonSelected(panel->moreChk[6]));
737 WSETUFLAG(wwin, full_maximize, WMGetButtonSelected(panel->moreChk[7]));
738 #ifdef XKB_BUTTON_HINT
739 WSETUFLAG(wwin, no_language_button, WMGetButtonSelected(panel->moreChk[8]));
740 #endif
741 WSETUFLAG(wwin, always_user_icon, WMGetButtonSelected(panel->alwChk));
743 if (WFLAGP(wwin, no_titlebar) && wwin->flags.shaded)
744 wUnshadeWindow(wwin);
746 WSETUFLAG(wwin, no_shadeable, WFLAGP(wwin, no_titlebar));
748 if (floating) {
749 if (!WFLAGP(wwin, floating))
750 ChangeStackingLevel(wwin->frame->core, WMFloatingLevel);
751 } else if (sunken) {
752 if (!WFLAGP(wwin, sunken))
753 ChangeStackingLevel(wwin->frame->core, WMSunkenLevel);
754 } else {
755 if (WFLAGP(wwin, floating) || WFLAGP(wwin, sunken))
756 ChangeStackingLevel(wwin->frame->core, WMNormalLevel);
759 WSETUFLAG(wwin, sunken, sunken);
760 WSETUFLAG(wwin, floating, floating);
761 wwin->flags.omnipresent = 0;
763 if (WFLAGP(wwin, skip_window_list) != skip_window_list) {
764 WSETUFLAG(wwin, skip_window_list, skip_window_list);
765 UpdateSwitchMenu(wwin->screen_ptr, wwin,
766 skip_window_list ? ACTION_REMOVE : ACTION_ADD);
767 } else {
768 if (WFLAGP(wwin, omnipresent) != old_omnipresent) {
769 UpdateSwitchMenu(wwin->screen_ptr, wwin, ACTION_CHANGE_WORKSPACE);
773 if (WFLAGP(wwin, no_bind_keys) != old_no_bind_keys) {
774 if (WFLAGP(wwin, no_bind_keys)) {
775 XUngrabKey(dpy, AnyKey, AnyModifier, wwin->frame->core->window);
776 } else {
777 wWindowSetKeyGrabs(wwin);
781 if (WFLAGP(wwin, no_bind_mouse) != old_no_bind_mouse) {
782 wWindowResetMouseGrabs(wwin);
785 wwin->frame->flags.need_texture_change = 1;
786 wWindowConfigureBorders(wwin);
787 wFrameWindowPaint(wwin->frame);
790 * Can't apply emulate_appicon because it will probably cause problems.
793 if (wapp) {
794 /* do application wide stuff */
795 WSETUFLAG(wapp->main_window_desc, start_hidden,
796 WMGetButtonSelected(panel->appChk[0]));
798 WSETUFLAG(wapp->main_window_desc, no_appicon,
799 WMGetButtonSelected(panel->appChk[1]));
801 if (WFLAGP(wapp->main_window_desc, no_appicon))
802 removeAppIconFor(wapp);
803 else
804 makeAppIconFor(wapp);
806 if (wapp->app_icon && wapp->main_window == wwin->client_win) {
807 char *file = WMGetTextFieldText(panel->fileText);
809 if (file[0] == 0) {
810 free(file);
811 file = NULL;
813 wIconChangeImageFile(wapp->app_icon->icon, file);
814 if (file)
815 free(file);
816 wAppIconPaint(wapp->app_icon);
824 static void
825 revertSettings(WMButton *button, InspectorPanel *panel)
827 WWindow *wwin = panel->inspected;
828 WApplication *wapp = wApplicationOf(wwin->main_window);
829 int i, n;
830 char *wm_instance = NULL;
831 char *wm_class = NULL;
832 int workspace, level;
834 if (panel->instRb && WMGetButtonSelected(panel->instRb) != 0)
835 wm_instance = wwin->wm_instance;
836 else if (panel->clsRb && WMGetButtonSelected(panel->clsRb) != 0)
837 wm_class = wwin->wm_class;
838 else if (panel->bothRb && WMGetButtonSelected(panel->bothRb) != 0) {
839 wm_instance = wwin->wm_instance;
840 wm_class = wwin->wm_class;
842 memset(&wwin->defined_user_flags, 0, sizeof(WWindowAttributes));
843 memset(&wwin->user_flags, 0, sizeof(WWindowAttributes));
844 memset(&wwin->client_flags, 0, sizeof(WWindowAttributes));
846 wWindowSetupInitialAttributes(wwin, &level, &workspace);
848 for (i=0; i < 10; i++) {
849 int flag = 0;
851 switch (i) {
852 case 0:
853 flag = WFLAGP(wwin, no_titlebar);
854 break;
855 case 1:
856 flag = WFLAGP(wwin, no_resizebar);
857 break;
858 case 2:
859 flag = WFLAGP(wwin, no_close_button);
860 break;
861 case 3:
862 flag = WFLAGP(wwin, no_miniaturize_button);
863 break;
864 case 4:
865 flag = WFLAGP(wwin, floating);
866 break;
867 case 5:
868 flag = WFLAGP(wwin, sunken);
869 break;
870 case 6:
871 flag = WFLAGP(wwin, omnipresent);
872 break;
873 case 7:
874 flag = WFLAGP(wwin, start_miniaturized);
875 break;
876 case 8:
877 flag = WFLAGP(wwin, start_maximized!=0);
878 break;
879 case 9:
880 flag = WFLAGP(wwin, skip_window_list);
881 break;
883 WMSetButtonSelected(panel->attrChk[i], flag);
885 for (i=0; i < 8; i++) {
886 int flag = 0;
888 switch (i) {
889 case 0:
890 flag = WFLAGP(wwin, no_hide_others);
891 break;
892 case 1:
893 flag = WFLAGP(wwin, no_bind_keys);
894 break;
895 case 2:
896 flag = WFLAGP(wwin, no_bind_mouse);
897 break;
898 case 3:
899 flag = WFLAGP(wwin, dont_move_off);
900 break;
901 case 4:
902 flag = WFLAGP(wwin, no_focusable);
903 break;
904 case 5:
905 flag = WFLAGP(wwin, dont_save_session);
906 break;
907 case 6:
908 flag = WFLAGP(wwin, emulate_appicon);
909 break;
910 case 7:
911 flag = WFLAGP(wwin, full_maximize);
912 break;
913 #ifdef XKB_BUTTON_HINT
914 case 8:
915 flag = WFLAGP(wwin, no_language_button);
916 break;
917 #endif
919 WMSetButtonSelected(panel->moreChk[i], flag);
921 if (panel->appFrm && wapp) {
922 for (i=0; i < 2; i++) {
923 int flag = 0;
925 switch (i) {
926 case 0:
927 flag = WFLAGP(wapp->main_window_desc, start_hidden);
928 break;
929 case 1:
930 flag = WFLAGP(wapp->main_window_desc, no_appicon);
931 break;
933 WMSetButtonSelected(panel->appChk[i], flag);
936 WMSetButtonSelected(panel->alwChk, WFLAGP(wwin, always_user_icon));
938 showIconFor(WMWidgetScreen(panel->alwChk), panel, wm_instance, wm_class,
939 REVERT_TO_DEFAULT);
941 n = wDefaultGetStartWorkspace(wwin->screen_ptr, wm_instance, wm_class);
943 if (n >= 0 && n < wwin->screen_ptr->workspace_count) {
944 WMSetPopUpButtonSelectedItem(panel->wsP, n+1);
945 } else {
946 WMSetPopUpButtonSelectedItem(panel->wsP, 0);
951 static void
952 chooseIconCallback(WMWidget *self, void *clientData)
954 char *file;
955 InspectorPanel *panel = (InspectorPanel*)clientData;
956 int result;
958 panel->choosingIcon = 1;
960 WMSetButtonEnabled(panel->browseIconBtn, False);
962 result = wIconChooserDialog(panel->frame->screen_ptr, &file,
963 panel->inspected->wm_instance,
964 panel->inspected->wm_class);
966 panel->choosingIcon = 0;
968 if (!panel->destroyed) { /* kluge */
969 if (result) {
970 WMSetTextFieldText(panel->fileText, file);
971 showIconFor(WMWidgetScreen(self), panel, NULL, NULL,
972 USE_TEXT_FIELD);
973 free(file);
975 WMSetButtonEnabled(panel->browseIconBtn, True);
976 } else {
977 freeInspector(panel);
982 static void
983 textEditedObserver(void *observerData, WMNotification *notification)
985 InspectorPanel *panel = (InspectorPanel*)observerData;
987 if ((long)WMGetNotificationClientData(notification) != WMReturnTextMovement)
988 return;
990 showIconFor(WMWidgetScreen(panel->win), panel, NULL, NULL,
991 USE_TEXT_FIELD);
993 WMPerformButtonClick(panel->updateIconBtn);
998 static void
999 selectSpecification(WMWidget *bPtr, void *data)
1001 InspectorPanel *panel = (InspectorPanel*)data;
1002 char *str;
1003 WWindow *wwin = panel->inspected;
1005 if (bPtr == panel->defaultRb) {
1006 WMSetButtonEnabled(panel->applyBtn, False);
1007 } else {
1008 WMSetButtonEnabled(panel->applyBtn, True);
1011 str = wmalloc(16 + strlen(wwin->wm_instance ? wwin->wm_instance : "?")
1012 + strlen(wwin->wm_class ? wwin->wm_class : "?"));
1014 sprintf(str, "Inspecting %s.%s",
1015 wwin->wm_instance ? wwin->wm_instance : "?",
1016 wwin->wm_class ? wwin->wm_class : "?");
1018 wFrameWindowChangeTitle(panel->frame->frame, str);
1020 free(str);
1024 static InspectorPanel*
1025 createInspectorForWindow(WWindow *wwin)
1027 WScreen *scr = wwin->screen_ptr;
1028 InspectorPanel *panel;
1029 Window parent;
1030 int i;
1031 int x, y;
1032 int btn_width, frame_width;
1033 WMButton *selectedBtn = NULL;
1034 #ifdef wrong_behaviour
1035 WMPixmap *pixmap;
1036 #endif
1039 panel = wmalloc(sizeof(InspectorPanel));
1040 memset(panel, 0, sizeof(InspectorPanel));
1042 panel->destroyed = 0;
1045 panel->inspected = wwin;
1047 panel->nextPtr = panelList;
1048 panelList = panel;
1051 panel->win = WMCreateWindow(scr->wmscreen, "windowInspector");
1052 WMResizeWidget(panel->win, PWIDTH, PHEIGHT);
1055 /**** create common stuff ****/
1057 /* command buttons */
1058 /* (PWIDTH - (left and right margin) - (btn interval)) / 3 */
1059 btn_width = (PWIDTH - (2 * 15) - (2 * 10)) / 3;
1060 panel->saveBtn = WMCreateCommandButton(panel->win);
1061 WMSetButtonAction(panel->saveBtn, (WMAction*)saveSettings, panel);
1062 WMMoveWidget(panel->saveBtn, (2 * (btn_width + 10)) + 15, 310);
1063 WMSetButtonText(panel->saveBtn, _("Save"));
1064 WMResizeWidget(panel->saveBtn, btn_width, 28);
1065 if (wPreferences.flags.noupdates || !(wwin->wm_class || wwin->wm_instance))
1066 WMSetButtonEnabled(panel->saveBtn, False);
1068 panel->applyBtn = WMCreateCommandButton(panel->win);
1069 WMSetButtonAction(panel->applyBtn, (WMAction*)applySettings, panel);
1070 WMMoveWidget(panel->applyBtn, btn_width + 10 + 15, 310);
1071 WMSetButtonText(panel->applyBtn, _("Apply"));
1072 WMResizeWidget(panel->applyBtn, btn_width, 28);
1074 panel->revertBtn = WMCreateCommandButton(panel->win);
1075 WMSetButtonAction(panel->revertBtn, (WMAction*)revertSettings, panel);
1076 WMMoveWidget(panel->revertBtn, 15, 310);
1077 WMSetButtonText(panel->revertBtn, _("Reload"));
1078 WMResizeWidget(panel->revertBtn, btn_width, 28);
1080 /* page selection popup button */
1081 panel->pagePopUp = WMCreatePopUpButton(panel->win);
1082 WMSetPopUpButtonAction(panel->pagePopUp, (WMAction*)changePage, panel);
1083 WMMoveWidget(panel->pagePopUp, 25, 15);
1084 WMResizeWidget(panel->pagePopUp, PWIDTH - 50, 20);
1086 WMAddPopUpButtonItem(panel->pagePopUp, _("Window Specification"));
1087 WMAddPopUpButtonItem(panel->pagePopUp, _("Window Attributes"));
1088 WMAddPopUpButtonItem(panel->pagePopUp, _("Advanced Options"));
1089 WMAddPopUpButtonItem(panel->pagePopUp, _("Icon and Initial Workspace"));
1090 WMAddPopUpButtonItem(panel->pagePopUp, _("Application Specific"));
1092 /**** window spec ****/
1093 frame_width = PWIDTH - (2 * 15);
1095 panel->specFrm = WMCreateFrame(panel->win);
1096 WMSetFrameTitle(panel->specFrm, _("Window Specification"));
1097 WMMoveWidget(panel->specFrm, 15, 65);
1098 WMResizeWidget(panel->specFrm, frame_width, 105);
1101 panel->defaultRb = WMCreateRadioButton(panel->specFrm);
1102 WMMoveWidget(panel->defaultRb, 10, 78);
1103 WMResizeWidget(panel->defaultRb, frame_width - (2 * 10), 20);
1104 WMSetButtonText(panel->defaultRb, _("Defaults for all windows"));
1105 WMSetButtonSelected(panel->defaultRb, False);
1106 WMSetButtonAction(panel->defaultRb, selectSpecification, panel);
1108 if (wwin->wm_class && wwin->wm_instance) {
1109 char *str, *tmp;
1111 tmp = wstrappend(wwin->wm_instance, ".");
1112 str = wstrappend(tmp, wwin->wm_class);
1114 panel->bothRb = WMCreateRadioButton(panel->specFrm);
1115 WMMoveWidget(panel->bothRb, 10, 18);
1116 WMResizeWidget(panel->bothRb, frame_width - (2 * 10), 20);
1117 WMSetButtonText(panel->bothRb, str);
1118 free(tmp);
1119 free(str);
1120 WMGroupButtons(panel->defaultRb, panel->bothRb);
1122 if (!selectedBtn)
1123 selectedBtn = panel->bothRb;
1125 WMSetButtonAction(panel->bothRb, selectSpecification, panel);
1128 if (wwin->wm_instance) {
1129 panel->instRb = WMCreateRadioButton(panel->specFrm);
1130 WMMoveWidget(panel->instRb, 10, 38);
1131 WMResizeWidget(panel->instRb, frame_width - (2 * 10), 20);
1132 WMSetButtonText(panel->instRb, wwin->wm_instance);
1133 WMGroupButtons(panel->defaultRb, panel->instRb);
1135 if (!selectedBtn)
1136 selectedBtn = panel->instRb;
1138 WMSetButtonAction(panel->instRb, selectSpecification, panel);
1141 if (wwin->wm_class) {
1142 panel->clsRb = WMCreateRadioButton(panel->specFrm);
1143 WMMoveWidget(panel->clsRb, 10, 58);
1144 WMResizeWidget(panel->clsRb, frame_width - (2 * 10), 20);
1145 WMSetButtonText(panel->clsRb, wwin->wm_class);
1146 WMGroupButtons(panel->defaultRb, panel->clsRb);
1148 if (!selectedBtn)
1149 selectedBtn = panel->clsRb;
1151 WMSetButtonAction(panel->clsRb, selectSpecification, panel);
1154 if (selectedBtn)
1155 WMSetButtonSelected(selectedBtn, True);
1157 panel->specLbl = WMCreateLabel(panel->win);
1158 WMMoveWidget(panel->specLbl, 15, 170);
1159 WMResizeWidget(panel->specLbl, frame_width, 100);
1160 WMSetLabelText(panel->specLbl,
1161 _("The configuration will apply to all\n"
1162 "windows that have their WM_CLASS property"
1163 " set to the above selected\nname, when saved."));
1164 WMSetLabelTextAlignment(panel->specLbl, WACenter);
1166 /**** attributes ****/
1167 panel->attrFrm = WMCreateFrame(panel->win);
1168 WMSetFrameTitle(panel->attrFrm, _("Attributes"));
1169 WMMoveWidget(panel->attrFrm, 15, 45);
1170 WMResizeWidget(panel->attrFrm, frame_width, 250);
1172 for (i=0; i < 10; i++) {
1173 char *caption = NULL;
1174 int flag = 0;
1175 char *descr = NULL;
1177 switch (i) {
1178 case 0:
1179 caption = _("Disable Titlebar");
1180 flag = WFLAGP(wwin, no_titlebar);
1181 descr = _("Remove the titlebar of this window.\n"
1182 "To access the window commands menu of a window\n"
1183 "without it's titlebar, press Control+Esc (or the\n"
1184 "equivalent shortcut, if you changed the default\n"
1185 "settings).");
1186 break;
1187 case 1:
1188 caption = _("Disable Resizebar");
1189 flag = WFLAGP(wwin, no_resizebar);
1190 descr = _("Remove the resizebar of this window.");
1191 break;
1192 case 2:
1193 caption = _("Disable Close Button");
1194 flag = WFLAGP(wwin, no_close_button);
1195 descr = _("Remove the `close window' button of this window.");
1196 break;
1197 case 3:
1198 caption = _("Disable Miniaturize Button");
1199 flag = WFLAGP(wwin, no_miniaturize_button);
1200 descr = _("Remove the `miniaturize window' button of the window.");
1201 break;
1202 case 4:
1203 caption = _("Keep on Top / Floating");
1204 flag = WFLAGP(wwin, floating);
1205 descr = _("Keep the window over other windows, not allowing\n"
1206 "them to covert it.");
1207 break;
1208 case 5:
1209 caption = _("Keep at Bottom / Sunken");
1210 flag = WFLAGP(wwin, sunken);
1211 descr = _("Keep the window under all other windows.");
1212 break;
1213 case 6:
1214 caption = _("Omnipresent");
1215 flag = WFLAGP(wwin, omnipresent);
1216 descr = _("Make window occupy all workspaces.");
1217 break;
1218 case 7:
1219 caption = _("Start Miniaturized");
1220 flag = WFLAGP(wwin, start_miniaturized);
1221 descr = _("Make the window be automatically miniaturized when it's\n"
1222 "first shown.");
1223 break;
1224 case 8:
1225 caption = _("Start Maximized");
1226 flag = WFLAGP(wwin, start_maximized!=0);
1227 descr = _("Make the window be automatically maximized when it's\n"
1228 "first shown.");
1229 break;
1230 case 9:
1231 caption = _("Skip Window List");
1232 flag = WFLAGP(wwin, skip_window_list);
1233 descr = _("Do not list the window in the window list menu.");
1234 break;
1236 panel->attrChk[i] = WMCreateSwitchButton(panel->attrFrm);
1237 WMMoveWidget(panel->attrChk[i], 10, 20*(i+1));
1238 WMResizeWidget(panel->attrChk[i], frame_width-15, 20);
1239 WMSetButtonSelected(panel->attrChk[i], flag);
1240 WMSetButtonText(panel->attrChk[i], caption);
1242 WMSetBalloonTextForView(descr, WMWidgetView(panel->attrChk[i]));
1246 /**** more attributes ****/
1247 panel->moreFrm = WMCreateFrame(panel->win);
1248 WMSetFrameTitle(panel->moreFrm, _("Advanced"));
1249 WMMoveWidget(panel->moreFrm, 15, 45);
1250 WMResizeWidget(panel->moreFrm, frame_width, 250);
1252 #ifdef XKB_BUTTON_HINT
1253 for (i=0; i < 9; i++) {
1254 #else
1255 for (i=0; i < 8; i++) {
1256 #endif
1257 char *caption = NULL;
1258 int flag = 0;
1259 char *descr = NULL;
1261 switch (i) {
1262 case 0:
1263 caption = _("Ignore HideOthers");
1264 flag = WFLAGP(wwin, no_hide_others);
1265 descr = _("Do not hide the window when issuing the\n"
1266 "`HideOthers' command.");
1267 break;
1268 case 1:
1269 caption = _("Don't Bind Keyboard Shortcuts");
1270 flag = WFLAGP(wwin, no_bind_keys);
1271 descr = _("Do not bind keyboard shortcuts from Window Maker\n"
1272 "when this window is focused. This will allow the\n"
1273 "window to receive all key combinations regardless\n"
1274 "of your shortcut configuration.");
1275 break;
1276 case 2:
1277 caption = _("Don't Bind Mouse Clicks");
1278 flag = WFLAGP(wwin, no_bind_mouse);
1279 descr = _("Do not bind mouse actions, such as `Alt'+drag\n"
1280 "in the window (when alt is the modifier you have"
1281 "configured).");
1282 break;
1283 case 3:
1284 caption = _("Keep Inside Screen");
1285 flag = WFLAGP(wwin, dont_move_off);
1286 descr = _("Do not allow the window to move itself completely\n"
1287 "outside the screen. For bug compatibility.\n");
1288 break;
1289 case 4:
1290 caption = _("Don't Let It Take Focus");
1291 flag = WFLAGP(wwin, no_focusable);
1292 descr = _("Do not let the window take keyboard focus when you\n"
1293 "click on it.");
1294 break;
1295 case 5:
1296 caption = _("Don't Save Session");
1297 flag = WFLAGP(wwin, dont_save_session);
1298 descr = _("Do not save the associated application in the\n"
1299 "session's state, so that it won't be restarted\n"
1300 "together with other applications when Window Maker\n"
1301 "starts.");
1302 break;
1303 case 6:
1304 caption = _("Emulate Application Icon");
1305 flag = WFLAGP(wwin, emulate_appicon);
1306 descr = _("Make this window act as an application that provides\n"
1307 "enough information to Window Maker for a dockable\n"
1308 "application icon to be created.");
1309 break;
1310 case 7:
1311 caption = _("Full Screen Maximization");
1312 flag = WFLAGP(wwin, full_maximize);
1313 descr = _("Make the window use the whole screen space when it's\n"
1314 "maximized. The titlebar and resizebar will be moved\n"
1315 "to outside the screen.");
1316 break;
1317 #ifdef XKB_BUTTON_HINT
1318 case 8:
1319 caption = _("Disable Language Button");
1320 flag = WFLAGP(wwin, no_language_button);
1321 descr = _("Remove the `toggle language' button of the window.");
1322 break;
1323 #endif
1325 panel->moreChk[i] = WMCreateSwitchButton(panel->moreFrm);
1326 WMMoveWidget(panel->moreChk[i], 10, 20*(i+1));
1327 WMResizeWidget(panel->moreChk[i], frame_width-15, 20);
1328 WMSetButtonSelected(panel->moreChk[i], flag);
1329 WMSetButtonText(panel->moreChk[i], caption);
1331 WMSetBalloonTextForView(descr, WMWidgetView(panel->moreChk[i]));
1334 /* miniwindow/workspace */
1335 panel->iconFrm = WMCreateFrame(panel->win);
1336 WMMoveWidget(panel->iconFrm, 15, 50);
1337 WMResizeWidget(panel->iconFrm, PWIDTH - (2 * 15), 170);
1338 WMSetFrameTitle(panel->iconFrm, _("Miniwindow Image"));
1340 panel->iconLbl = WMCreateLabel(panel->iconFrm);
1341 WMMoveWidget(panel->iconLbl, PWIDTH - (2 * 15) - 22 - 64, 30);
1342 WMResizeWidget(panel->iconLbl, 64, 64);
1343 WMSetLabelRelief(panel->iconLbl, WRGroove);
1344 WMSetLabelImagePosition(panel->iconLbl, WIPImageOnly);
1346 panel->browseIconBtn = WMCreateCommandButton(panel->iconFrm);
1347 WMSetButtonAction(panel->browseIconBtn, chooseIconCallback, panel);
1348 WMMoveWidget(panel->browseIconBtn, 22, 30);
1349 WMResizeWidget(panel->browseIconBtn, 100, 26);
1350 WMSetButtonText(panel->browseIconBtn, _("Browse..."));
1352 #if 0
1353 panel->updateIconBtn = WMCreateCommandButton(panel->iconFrm);
1354 WMSetButtonAction(panel->updateIconBtn, (WMAction*)updateIcon, panel);
1355 WMMoveWidget(panel->updateIconBtn, 22, 65);
1356 WMResizeWidget(panel->updateIconBtn, 100, 26);
1357 WMSetButtonText(panel->updateIconBtn, _("Update"));
1358 #endif
1359 #ifdef wrong_behaviour
1360 WMSetButtonImagePosition(panel->updateIconBtn, WIPRight);
1361 pixmap = WMGetSystemPixmap(scr->wmscreen, WSIReturnArrow);
1362 WMSetButtonImage(panel->updateIconBtn, pixmap);
1363 WMReleasePixmap(pixmap);
1364 pixmap = WMGetSystemPixmap(scr->wmscreen, WSIHighlightedReturnArrow);
1365 WMSetButtonAltImage(panel->updateIconBtn, pixmap);
1366 WMReleasePixmap(pixmap);
1367 #endif
1369 panel->fileLbl = WMCreateLabel(panel->iconFrm);
1370 WMMoveWidget(panel->fileLbl, 20, 95);
1371 WMResizeWidget(panel->fileLbl, PWIDTH - (2 * 15) - (2 * 20), 14);
1372 WMSetLabelText(panel->fileLbl, _("Icon File Name:"));
1374 panel->fileText = WMCreateTextField(panel->iconFrm);
1375 WMMoveWidget(panel->fileText, 20, 115);
1376 WMResizeWidget(panel->fileText, PWIDTH - (2 * 15) - (2 * 15), 20);
1377 WMSetTextFieldText(panel->fileText, NULL);
1378 WMAddNotificationObserver(textEditedObserver, panel,
1379 WMTextDidEndEditingNotification,
1380 panel->fileText);
1381 panel->alwChk = WMCreateSwitchButton(panel->iconFrm);
1382 WMMoveWidget(panel->alwChk, 20, 140);
1383 WMResizeWidget(panel->alwChk, PWIDTH - (2 * 15) - (2 * 15), 20);
1384 WMSetButtonText(panel->alwChk, _("Ignore client supplied icon"));
1385 WMSetButtonSelected(panel->alwChk, WFLAGP(wwin, always_user_icon));
1388 panel->wsFrm = WMCreateFrame(panel->win);
1389 WMMoveWidget(panel->wsFrm, 15, 225);
1390 WMResizeWidget(panel->wsFrm, PWIDTH - (2 * 15), 70);
1391 WMSetFrameTitle(panel->wsFrm, _("Initial Workspace"));
1393 WMSetBalloonTextForView(_("The workspace to place the window when it's"
1394 "first shown."), WMWidgetView(panel->wsFrm));
1396 panel->wsP = WMCreatePopUpButton(panel->wsFrm);
1397 WMMoveWidget(panel->wsP, 20, 30);
1398 WMResizeWidget(panel->wsP, PWIDTH - (2 * 15) - (2 * 20), 20);
1399 WMAddPopUpButtonItem(panel->wsP, _("Nowhere in particular"));
1400 for (i = 0; i < wwin->screen_ptr->workspace_count; i++) {
1401 WMAddPopUpButtonItem(panel->wsP, scr->workspaces[i]->name);
1404 i = wDefaultGetStartWorkspace(wwin->screen_ptr, wwin->wm_instance,
1405 wwin->wm_class);
1406 if (i >= 0 && i <= wwin->screen_ptr->workspace_count) {
1407 WMSetPopUpButtonSelectedItem(panel->wsP, i + 1);
1408 } else {
1409 WMSetPopUpButtonSelectedItem(panel->wsP, 0);
1412 /* application wide attributes */
1413 if (wwin->main_window != None) {
1414 WApplication *wapp = wApplicationOf(wwin->main_window);
1416 panel->appFrm = WMCreateFrame(panel->win);
1417 WMSetFrameTitle(panel->appFrm, _("Application Wide"));
1418 WMMoveWidget(panel->appFrm, 15, 50);
1419 WMResizeWidget(panel->appFrm, frame_width, 240);
1421 for (i=0; i < 2; i++) {
1422 char *caption = NULL;
1423 int flag = 0;
1424 char *descr = NULL;
1426 switch (i) {
1427 case 0:
1428 caption = _("Start Hidden");
1429 flag = WFLAGP(wapp->main_window_desc, start_hidden);
1430 descr = _("Automatically hide application when it's started.");
1431 break;
1432 case 1:
1433 caption = _("No Application Icon");
1434 flag = WFLAGP(wapp->main_window_desc, no_appicon);
1435 descr = _("Disable the application icon for the application.\n"
1436 "Note that you won't be able to dock it anymore,\n"
1437 "and any icons that are already docked will stop\n"
1438 "working correctly.");
1439 break;
1441 panel->appChk[i] = WMCreateSwitchButton(panel->appFrm);
1442 WMMoveWidget(panel->appChk[i], 10, 20*(i+1));
1443 WMResizeWidget(panel->appChk[i], 205, 20);
1444 WMSetButtonSelected(panel->appChk[i], flag);
1445 WMSetButtonText(panel->appChk[i], caption);
1447 WMSetBalloonTextForView(descr, WMWidgetView(panel->appChk[i]));
1450 if (WFLAGP(wwin, emulate_appicon)) {
1451 WMSetButtonEnabled(panel->appChk[1], False);
1452 WMSetButtonEnabled(panel->moreChk[6], True);
1453 } else {
1454 WMSetButtonEnabled(panel->appChk[1], True);
1455 WMSetButtonEnabled(panel->moreChk[6], False);
1457 } else {
1458 int tmp;
1460 if ((wwin->transient_for!=None && wwin->transient_for!=scr->root_win)
1461 || !wwin->wm_class || !wwin->wm_instance)
1462 tmp = False;
1463 else
1464 tmp = True;
1465 WMSetButtonEnabled(panel->moreChk[6], tmp);
1467 WMSetPopUpButtonItemEnabled(panel->pagePopUp, 4, False);
1468 panel->appFrm = NULL;
1471 /* if the window is a transient, don't let it have a miniaturize
1472 * button */
1473 if (wWindowFor(wwin->transient_for)!=NULL)
1474 WMSetButtonEnabled(panel->attrChk[3], False);
1475 else
1476 WMSetButtonEnabled(panel->attrChk[3], True);
1479 if (!wwin->wm_class && !wwin->wm_instance) {
1480 WMSetPopUpButtonItemEnabled(panel->pagePopUp, 0, False);
1484 WMRealizeWidget(panel->win);
1486 WMMapSubwidgets(panel->win);
1487 WMMapSubwidgets(panel->specFrm);
1488 WMMapSubwidgets(panel->attrFrm);
1489 WMMapSubwidgets(panel->moreFrm);
1490 WMMapSubwidgets(panel->iconFrm);
1491 WMMapSubwidgets(panel->wsFrm);
1492 if (panel->appFrm)
1493 WMMapSubwidgets(panel->appFrm);
1495 WMSetPopUpButtonSelectedItem(panel->pagePopUp, 1);
1496 changePage(panel->pagePopUp, panel);
1499 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, PWIDTH, PHEIGHT,
1500 0, 0, 0);
1501 XSelectInput(dpy, parent, KeyPressMask|KeyReleaseMask);
1502 panel->parent = parent;
1503 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
1505 WMMapWidget(panel->win);
1507 XSetTransientForHint(dpy, parent, wwin->client_win);
1509 x = wwin->frame_x+wwin->frame->core->width/2;
1510 y = wwin->frame_y+wwin->frame->top_width*2;
1511 if (y + PHEIGHT > scr->scr_height)
1512 y = scr->scr_height - PHEIGHT - 30;
1513 if (x + PWIDTH > scr->scr_width)
1514 x = scr->scr_width - PWIDTH;
1516 panel->frame = wManageInternalWindow(scr, parent, wwin->client_win,
1517 "Inspector", x, y, PWIDTH, PHEIGHT);
1519 if (!selectedBtn)
1520 selectedBtn = panel->defaultRb;
1522 WMSetButtonSelected(selectedBtn, True);
1524 selectSpecification(selectedBtn, panel);
1526 /* kluge to know who should get the key events */
1527 panel->frame->client_leader = WMWidgetXID(panel->win);
1529 WSETUFLAG(panel->frame, no_closable, 0);
1530 WSETUFLAG(panel->frame, no_close_button, 0);
1531 wWindowUpdateButtonImages(panel->frame);
1532 wFrameWindowShowButton(panel->frame->frame, WFF_RIGHT_BUTTON);
1533 panel->frame->frame->on_click_right = destroyInspector;
1535 wWindowMap(panel->frame);
1537 showIconFor(WMWidgetScreen(panel->alwChk), panel, wwin->wm_instance,
1538 wwin->wm_class, UPDATE_TEXT_FIELD);
1540 return panel;
1544 void
1545 wShowInspectorForWindow(WWindow *wwin)
1547 if (wwin->flags.inspector_open)
1548 return;
1550 WMSetBalloonEnabled(wwin->screen_ptr->wmscreen, wPreferences.help_balloon);
1552 make_keys();
1553 wwin->flags.inspector_open = 1;
1554 wwin->inspector = createInspectorForWindow(wwin);;