fixed many bugs, removed linked list
[wmaker-crm.git] / src / winspector.c
blob5109e629e3b1b57fe9b2b698da9e2a9932684da7
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(wwin->wm_class)+4);
593 strcat(strcpy(buffer, wapp->main_window_desc->wm_instance), ".");
594 strcat(buffer, wwin->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 (!clip->keep_attracted && !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 &&
681 (!wapp->app_icon->attracted || wapp->app_icon->dock->keep_attracted)) {
682 wapp->app_icon->running = 0;
683 /* since we keep it, we don't care if it was attracted or not */
684 wapp->app_icon->attracted = 0;
685 wapp->app_icon->icon->shadowed = 0;
686 wapp->app_icon->main_window = None;
687 wapp->app_icon->pid = 0;
688 wapp->app_icon->icon->owner = NULL;
689 wapp->app_icon->icon->icon_win = None;
690 wapp->app_icon->icon->force_paint = 1;
691 wAppIconPaint(wapp->app_icon);
692 } else if (wapp->app_icon->docked) {
693 wapp->app_icon->running = 0;
694 wDockDetach(wapp->app_icon->dock, wapp->app_icon);
695 } else {
696 wAppIconDestroy(wapp->app_icon);
698 wapp->app_icon = NULL;
699 if (wPreferences.auto_arrange_icons)
700 wArrangeIcons(wapp->main_window_desc->screen_ptr, True);
704 static void
705 applySettings(WMButton *button, InspectorPanel *panel)
707 WWindow *wwin = panel->inspected;
708 WApplication *wapp = wApplicationOf(wwin->main_window);
709 int floating, sunken, skip_window_list;
710 int old_omnipresent;
711 int old_no_bind_keys;
712 int old_no_bind_mouse;
714 old_omnipresent = WFLAGP(wwin, omnipresent);
715 old_no_bind_keys = WFLAGP(wwin, no_bind_keys);
716 old_no_bind_mouse = WFLAGP(wwin, no_bind_mouse);
718 showIconFor(WMWidgetScreen(button), panel, NULL, NULL, USE_TEXT_FIELD);
720 WSETUFLAG(wwin, no_titlebar, WMGetButtonSelected(panel->attrChk[0]));
721 WSETUFLAG(wwin, no_resizebar, WMGetButtonSelected(panel->attrChk[1]));
722 WSETUFLAG(wwin, no_close_button, WMGetButtonSelected(panel->attrChk[2]));
723 WSETUFLAG(wwin, no_miniaturize_button, WMGetButtonSelected(panel->attrChk[3]));
724 floating = WMGetButtonSelected(panel->attrChk[4]);
725 sunken = WMGetButtonSelected(panel->attrChk[5]);
726 WSETUFLAG(wwin, omnipresent, WMGetButtonSelected(panel->attrChk[6]));
727 WSETUFLAG(wwin, start_miniaturized, WMGetButtonSelected(panel->attrChk[7]));
728 WSETUFLAG(wwin, start_maximized, WMGetButtonSelected(panel->attrChk[8]));
729 skip_window_list = WMGetButtonSelected(panel->attrChk[9]);
731 WSETUFLAG(wwin, no_hide_others, WMGetButtonSelected(panel->moreChk[0]));
732 WSETUFLAG(wwin, no_bind_keys, WMGetButtonSelected(panel->moreChk[1]));
733 WSETUFLAG(wwin, no_bind_mouse, WMGetButtonSelected(panel->moreChk[2]));
734 WSETUFLAG(wwin, dont_move_off, WMGetButtonSelected(panel->moreChk[3]));
735 WSETUFLAG(wwin, no_focusable, WMGetButtonSelected(panel->moreChk[4]));
736 WSETUFLAG(wwin, dont_save_session, WMGetButtonSelected(panel->moreChk[5]));
737 WSETUFLAG(wwin, emulate_appicon, WMGetButtonSelected(panel->moreChk[6]));
738 WSETUFLAG(wwin, full_maximize, WMGetButtonSelected(panel->moreChk[7]));
739 #ifdef XKB_BUTTON_HINT
740 WSETUFLAG(wwin, no_language_button, WMGetButtonSelected(panel->moreChk[8]));
741 #endif
742 WSETUFLAG(wwin, always_user_icon, WMGetButtonSelected(panel->alwChk));
744 if (WFLAGP(wwin, no_titlebar) && wwin->flags.shaded)
745 wUnshadeWindow(wwin);
747 WSETUFLAG(wwin, no_shadeable, WFLAGP(wwin, no_titlebar));
749 if (floating) {
750 if (!WFLAGP(wwin, floating))
751 ChangeStackingLevel(wwin->frame->core, WMFloatingLevel);
752 } else if (sunken) {
753 if (!WFLAGP(wwin, sunken))
754 ChangeStackingLevel(wwin->frame->core, WMSunkenLevel);
755 } else {
756 if (WFLAGP(wwin, floating) || WFLAGP(wwin, sunken))
757 ChangeStackingLevel(wwin->frame->core, WMNormalLevel);
760 WSETUFLAG(wwin, sunken, sunken);
761 WSETUFLAG(wwin, floating, floating);
762 wwin->flags.omnipresent = 0;
764 if (WFLAGP(wwin, skip_window_list) != skip_window_list) {
765 WSETUFLAG(wwin, skip_window_list, skip_window_list);
766 UpdateSwitchMenu(wwin->screen_ptr, wwin,
767 skip_window_list ? ACTION_REMOVE : ACTION_ADD);
768 } else {
769 if (WFLAGP(wwin, omnipresent) != old_omnipresent) {
770 UpdateSwitchMenu(wwin->screen_ptr, wwin, ACTION_CHANGE_WORKSPACE);
774 if (WFLAGP(wwin, no_bind_keys) != old_no_bind_keys) {
775 if (WFLAGP(wwin, no_bind_keys)) {
776 XUngrabKey(dpy, AnyKey, AnyModifier, wwin->frame->core->window);
777 } else {
778 wWindowSetKeyGrabs(wwin);
782 if (WFLAGP(wwin, no_bind_mouse) != old_no_bind_mouse) {
783 wWindowResetMouseGrabs(wwin);
786 wwin->frame->flags.need_texture_change = 1;
787 wWindowConfigureBorders(wwin);
788 wFrameWindowPaint(wwin->frame);
791 * Can't apply emulate_appicon because it will probably cause problems.
794 if (wapp) {
795 /* do application wide stuff */
796 WSETUFLAG(wapp->main_window_desc, start_hidden,
797 WMGetButtonSelected(panel->appChk[0]));
799 WSETUFLAG(wapp->main_window_desc, no_appicon,
800 WMGetButtonSelected(panel->appChk[1]));
802 if (WFLAGP(wapp->main_window_desc, no_appicon))
803 removeAppIconFor(wapp);
804 else
805 makeAppIconFor(wapp);
807 if (wapp->app_icon && wapp->main_window == wwin->client_win) {
808 char *file = WMGetTextFieldText(panel->fileText);
810 if (file[0] == 0) {
811 free(file);
812 file = NULL;
814 wIconChangeImageFile(wapp->app_icon->icon, file);
815 if (file)
816 free(file);
817 wAppIconPaint(wapp->app_icon);
825 static void
826 revertSettings(WMButton *button, InspectorPanel *panel)
828 WWindow *wwin = panel->inspected;
829 WApplication *wapp = wApplicationOf(wwin->main_window);
830 int i, n;
831 char *wm_instance = NULL;
832 char *wm_class = NULL;
833 int workspace, level;
835 if (panel->instRb && WMGetButtonSelected(panel->instRb) != 0)
836 wm_instance = wwin->wm_instance;
837 else if (panel->clsRb && WMGetButtonSelected(panel->clsRb) != 0)
838 wm_class = wwin->wm_class;
839 else if (panel->bothRb && WMGetButtonSelected(panel->bothRb) != 0) {
840 wm_instance = wwin->wm_instance;
841 wm_class = wwin->wm_class;
843 memset(&wwin->defined_user_flags, 0, sizeof(WWindowAttributes));
844 memset(&wwin->user_flags, 0, sizeof(WWindowAttributes));
845 memset(&wwin->client_flags, 0, sizeof(WWindowAttributes));
847 wWindowSetupInitialAttributes(wwin, &level, &workspace);
849 for (i=0; i < 10; i++) {
850 int flag = 0;
852 switch (i) {
853 case 0:
854 flag = WFLAGP(wwin, no_titlebar);
855 break;
856 case 1:
857 flag = WFLAGP(wwin, no_resizebar);
858 break;
859 case 2:
860 flag = WFLAGP(wwin, no_close_button);
861 break;
862 case 3:
863 flag = WFLAGP(wwin, no_miniaturize_button);
864 break;
865 case 4:
866 flag = WFLAGP(wwin, floating);
867 break;
868 case 5:
869 flag = WFLAGP(wwin, sunken);
870 break;
871 case 6:
872 flag = WFLAGP(wwin, omnipresent);
873 break;
874 case 7:
875 flag = WFLAGP(wwin, start_miniaturized);
876 break;
877 case 8:
878 flag = WFLAGP(wwin, start_maximized!=0);
879 break;
880 case 9:
881 flag = WFLAGP(wwin, skip_window_list);
882 break;
884 WMSetButtonSelected(panel->attrChk[i], flag);
886 for (i=0; i < 8; i++) {
887 int flag = 0;
889 switch (i) {
890 case 0:
891 flag = WFLAGP(wwin, no_hide_others);
892 break;
893 case 1:
894 flag = WFLAGP(wwin, no_bind_keys);
895 break;
896 case 2:
897 flag = WFLAGP(wwin, no_bind_mouse);
898 break;
899 case 3:
900 flag = WFLAGP(wwin, dont_move_off);
901 break;
902 case 4:
903 flag = WFLAGP(wwin, no_focusable);
904 break;
905 case 5:
906 flag = WFLAGP(wwin, dont_save_session);
907 break;
908 case 6:
909 flag = WFLAGP(wwin, emulate_appicon);
910 break;
911 case 7:
912 flag = WFLAGP(wwin, full_maximize);
913 break;
914 #ifdef XKB_BUTTON_HINT
915 case 8:
916 flag = WFLAGP(wwin, no_language_button);
917 break;
918 #endif
920 WMSetButtonSelected(panel->moreChk[i], flag);
922 if (panel->appFrm && wapp) {
923 for (i=0; i < 2; i++) {
924 int flag = 0;
926 switch (i) {
927 case 0:
928 flag = WFLAGP(wapp->main_window_desc, start_hidden);
929 break;
930 case 1:
931 flag = WFLAGP(wapp->main_window_desc, no_appicon);
932 break;
934 WMSetButtonSelected(panel->appChk[i], flag);
937 WMSetButtonSelected(panel->alwChk, WFLAGP(wwin, always_user_icon));
939 showIconFor(WMWidgetScreen(panel->alwChk), panel, wm_instance, wm_class,
940 REVERT_TO_DEFAULT);
942 n = wDefaultGetStartWorkspace(wwin->screen_ptr, wm_instance, wm_class);
944 if (n >= 0 && n < wwin->screen_ptr->workspace_count) {
945 WMSetPopUpButtonSelectedItem(panel->wsP, n+1);
946 } else {
947 WMSetPopUpButtonSelectedItem(panel->wsP, 0);
952 static void
953 chooseIconCallback(WMWidget *self, void *clientData)
955 char *file;
956 InspectorPanel *panel = (InspectorPanel*)clientData;
957 int result;
959 panel->choosingIcon = 1;
961 WMSetButtonEnabled(panel->browseIconBtn, False);
963 result = wIconChooserDialog(panel->frame->screen_ptr, &file,
964 panel->inspected->wm_instance,
965 panel->inspected->wm_class);
967 panel->choosingIcon = 0;
969 if (!panel->destroyed) { /* kluge */
970 if (result) {
971 WMSetTextFieldText(panel->fileText, file);
972 showIconFor(WMWidgetScreen(self), panel, NULL, NULL,
973 USE_TEXT_FIELD);
974 free(file);
976 WMSetButtonEnabled(panel->browseIconBtn, True);
977 } else {
978 freeInspector(panel);
983 static void
984 textEditedObserver(void *observerData, WMNotification *notification)
986 InspectorPanel *panel = (InspectorPanel*)observerData;
988 if ((long)WMGetNotificationClientData(notification) != WMReturnTextMovement)
989 return;
991 showIconFor(WMWidgetScreen(panel->win), panel, NULL, NULL,
992 USE_TEXT_FIELD);
994 WMPerformButtonClick(panel->updateIconBtn);
999 static void
1000 selectSpecification(WMWidget *bPtr, void *data)
1002 InspectorPanel *panel = (InspectorPanel*)data;
1003 char *str;
1004 WWindow *wwin = panel->inspected;
1006 if (bPtr == panel->defaultRb) {
1007 WMSetButtonEnabled(panel->applyBtn, False);
1008 } else {
1009 WMSetButtonEnabled(panel->applyBtn, True);
1012 str = wmalloc(16 + strlen(wwin->wm_instance ? wwin->wm_instance : "?")
1013 + strlen(wwin->wm_class ? wwin->wm_class : "?"));
1015 sprintf(str, "Inspecting %s.%s",
1016 wwin->wm_instance ? wwin->wm_instance : "?",
1017 wwin->wm_class ? wwin->wm_class : "?");
1019 wFrameWindowChangeTitle(panel->frame->frame, str);
1021 free(str);
1025 static InspectorPanel*
1026 createInspectorForWindow(WWindow *wwin)
1028 WScreen *scr = wwin->screen_ptr;
1029 InspectorPanel *panel;
1030 Window parent;
1031 int i;
1032 int x, y;
1033 int btn_width, frame_width;
1034 WMButton *selectedBtn = NULL;
1035 #ifdef wrong_behaviour
1036 WMPixmap *pixmap;
1037 #endif
1040 panel = wmalloc(sizeof(InspectorPanel));
1041 memset(panel, 0, sizeof(InspectorPanel));
1043 panel->destroyed = 0;
1046 panel->inspected = wwin;
1048 panel->nextPtr = panelList;
1049 panelList = panel;
1052 panel->win = WMCreateWindow(scr->wmscreen, "windowInspector");
1053 WMResizeWidget(panel->win, PWIDTH, PHEIGHT);
1056 /**** create common stuff ****/
1058 /* command buttons */
1059 /* (PWIDTH - (left and right margin) - (btn interval)) / 3 */
1060 btn_width = (PWIDTH - (2 * 15) - (2 * 10)) / 3;
1061 panel->saveBtn = WMCreateCommandButton(panel->win);
1062 WMSetButtonAction(panel->saveBtn, (WMAction*)saveSettings, panel);
1063 WMMoveWidget(panel->saveBtn, (2 * (btn_width + 10)) + 15, 310);
1064 WMSetButtonText(panel->saveBtn, _("Save"));
1065 WMResizeWidget(panel->saveBtn, btn_width, 28);
1066 if (wPreferences.flags.noupdates || !(wwin->wm_class || wwin->wm_instance))
1067 WMSetButtonEnabled(panel->saveBtn, False);
1069 panel->applyBtn = WMCreateCommandButton(panel->win);
1070 WMSetButtonAction(panel->applyBtn, (WMAction*)applySettings, panel);
1071 WMMoveWidget(panel->applyBtn, btn_width + 10 + 15, 310);
1072 WMSetButtonText(panel->applyBtn, _("Apply"));
1073 WMResizeWidget(panel->applyBtn, btn_width, 28);
1075 panel->revertBtn = WMCreateCommandButton(panel->win);
1076 WMSetButtonAction(panel->revertBtn, (WMAction*)revertSettings, panel);
1077 WMMoveWidget(panel->revertBtn, 15, 310);
1078 WMSetButtonText(panel->revertBtn, _("Reload"));
1079 WMResizeWidget(panel->revertBtn, btn_width, 28);
1081 /* page selection popup button */
1082 panel->pagePopUp = WMCreatePopUpButton(panel->win);
1083 WMSetPopUpButtonAction(panel->pagePopUp, (WMAction*)changePage, panel);
1084 WMMoveWidget(panel->pagePopUp, 25, 15);
1085 WMResizeWidget(panel->pagePopUp, PWIDTH - 50, 20);
1087 WMAddPopUpButtonItem(panel->pagePopUp, _("Window Specification"));
1088 WMAddPopUpButtonItem(panel->pagePopUp, _("Window Attributes"));
1089 WMAddPopUpButtonItem(panel->pagePopUp, _("Advanced Options"));
1090 WMAddPopUpButtonItem(panel->pagePopUp, _("Icon and Initial Workspace"));
1091 WMAddPopUpButtonItem(panel->pagePopUp, _("Application Specific"));
1093 /**** window spec ****/
1094 frame_width = PWIDTH - (2 * 15);
1096 panel->specFrm = WMCreateFrame(panel->win);
1097 WMSetFrameTitle(panel->specFrm, _("Window Specification"));
1098 WMMoveWidget(panel->specFrm, 15, 65);
1099 WMResizeWidget(panel->specFrm, frame_width, 105);
1102 panel->defaultRb = WMCreateRadioButton(panel->specFrm);
1103 WMMoveWidget(panel->defaultRb, 10, 78);
1104 WMResizeWidget(panel->defaultRb, frame_width - (2 * 10), 20);
1105 WMSetButtonText(panel->defaultRb, _("Defaults for all windows"));
1106 WMSetButtonSelected(panel->defaultRb, False);
1107 WMSetButtonAction(panel->defaultRb, selectSpecification, panel);
1109 if (wwin->wm_class && wwin->wm_instance) {
1110 char *str, *tmp;
1112 tmp = wstrappend(wwin->wm_instance, ".");
1113 str = wstrappend(tmp, wwin->wm_class);
1115 panel->bothRb = WMCreateRadioButton(panel->specFrm);
1116 WMMoveWidget(panel->bothRb, 10, 18);
1117 WMResizeWidget(panel->bothRb, frame_width - (2 * 10), 20);
1118 WMSetButtonText(panel->bothRb, str);
1119 free(tmp);
1120 free(str);
1121 WMGroupButtons(panel->defaultRb, panel->bothRb);
1123 if (!selectedBtn)
1124 selectedBtn = panel->bothRb;
1126 WMSetButtonAction(panel->bothRb, selectSpecification, panel);
1129 if (wwin->wm_instance) {
1130 panel->instRb = WMCreateRadioButton(panel->specFrm);
1131 WMMoveWidget(panel->instRb, 10, 38);
1132 WMResizeWidget(panel->instRb, frame_width - (2 * 10), 20);
1133 WMSetButtonText(panel->instRb, wwin->wm_instance);
1134 WMGroupButtons(panel->defaultRb, panel->instRb);
1136 if (!selectedBtn)
1137 selectedBtn = panel->instRb;
1139 WMSetButtonAction(panel->instRb, selectSpecification, panel);
1142 if (wwin->wm_class) {
1143 panel->clsRb = WMCreateRadioButton(panel->specFrm);
1144 WMMoveWidget(panel->clsRb, 10, 58);
1145 WMResizeWidget(panel->clsRb, frame_width - (2 * 10), 20);
1146 WMSetButtonText(panel->clsRb, wwin->wm_class);
1147 WMGroupButtons(panel->defaultRb, panel->clsRb);
1149 if (!selectedBtn)
1150 selectedBtn = panel->clsRb;
1152 WMSetButtonAction(panel->clsRb, selectSpecification, panel);
1155 if (selectedBtn)
1156 WMSetButtonSelected(selectedBtn, True);
1158 panel->specLbl = WMCreateLabel(panel->win);
1159 WMMoveWidget(panel->specLbl, 15, 170);
1160 WMResizeWidget(panel->specLbl, frame_width, 100);
1161 WMSetLabelText(panel->specLbl,
1162 _("The configuration will apply to all\n"
1163 "windows that have their WM_CLASS property"
1164 " set to the above selected\nname, when saved."));
1165 WMSetLabelTextAlignment(panel->specLbl, WACenter);
1167 /**** attributes ****/
1168 panel->attrFrm = WMCreateFrame(panel->win);
1169 WMSetFrameTitle(panel->attrFrm, _("Attributes"));
1170 WMMoveWidget(panel->attrFrm, 15, 45);
1171 WMResizeWidget(panel->attrFrm, frame_width, 250);
1173 for (i=0; i < 10; i++) {
1174 char *caption = NULL;
1175 int flag = 0;
1176 char *descr = NULL;
1178 switch (i) {
1179 case 0:
1180 caption = _("Disable Titlebar");
1181 flag = WFLAGP(wwin, no_titlebar);
1182 descr = _("Remove the titlebar of this window.\n"
1183 "To access the window commands menu of a window\n"
1184 "without it's titlebar, press Control+Esc (or the\n"
1185 "equivalent shortcut, if you changed the default\n"
1186 "settings).");
1187 break;
1188 case 1:
1189 caption = _("Disable Resizebar");
1190 flag = WFLAGP(wwin, no_resizebar);
1191 descr = _("Remove the resizebar of this window.");
1192 break;
1193 case 2:
1194 caption = _("Disable Close Button");
1195 flag = WFLAGP(wwin, no_close_button);
1196 descr = _("Remove the `close window' button of this window.");
1197 break;
1198 case 3:
1199 caption = _("Disable Miniaturize Button");
1200 flag = WFLAGP(wwin, no_miniaturize_button);
1201 descr = _("Remove the `miniaturize window' button of the window.");
1202 break;
1203 case 4:
1204 caption = _("Keep on Top / Floating");
1205 flag = WFLAGP(wwin, floating);
1206 descr = _("Keep the window over other windows, not allowing\n"
1207 "them to covert it.");
1208 break;
1209 case 5:
1210 caption = _("Keep at Bottom / Sunken");
1211 flag = WFLAGP(wwin, sunken);
1212 descr = _("Keep the window under all other windows.");
1213 break;
1214 case 6:
1215 caption = _("Omnipresent");
1216 flag = WFLAGP(wwin, omnipresent);
1217 descr = _("Make window occupy all workspaces.");
1218 break;
1219 case 7:
1220 caption = _("Start Miniaturized");
1221 flag = WFLAGP(wwin, start_miniaturized);
1222 descr = _("Make the window be automatically miniaturized when it's\n"
1223 "first shown.");
1224 break;
1225 case 8:
1226 caption = _("Start Maximized");
1227 flag = WFLAGP(wwin, start_maximized!=0);
1228 descr = _("Make the window be automatically maximized when it's\n"
1229 "first shown.");
1230 break;
1231 case 9:
1232 caption = _("Skip Window List");
1233 flag = WFLAGP(wwin, skip_window_list);
1234 descr = _("Do not list the window in the window list menu.");
1235 break;
1237 panel->attrChk[i] = WMCreateSwitchButton(panel->attrFrm);
1238 WMMoveWidget(panel->attrChk[i], 10, 20*(i+1));
1239 WMResizeWidget(panel->attrChk[i], frame_width-15, 20);
1240 WMSetButtonSelected(panel->attrChk[i], flag);
1241 WMSetButtonText(panel->attrChk[i], caption);
1243 WMSetBalloonTextForView(descr, WMWidgetView(panel->attrChk[i]));
1247 /**** more attributes ****/
1248 panel->moreFrm = WMCreateFrame(panel->win);
1249 WMSetFrameTitle(panel->moreFrm, _("Advanced"));
1250 WMMoveWidget(panel->moreFrm, 15, 45);
1251 WMResizeWidget(panel->moreFrm, frame_width, 250);
1253 #ifdef XKB_BUTTON_HINT
1254 for (i=0; i < 9; i++) {
1255 #else
1256 for (i=0; i < 8; i++) {
1257 #endif
1258 char *caption = NULL;
1259 int flag = 0;
1260 char *descr = NULL;
1262 switch (i) {
1263 case 0:
1264 caption = _("Ignore HideOthers");
1265 flag = WFLAGP(wwin, no_hide_others);
1266 descr = _("Do not hide the window when issuing the\n"
1267 "`HideOthers' command.");
1268 break;
1269 case 1:
1270 caption = _("Don't Bind Keyboard Shortcuts");
1271 flag = WFLAGP(wwin, no_bind_keys);
1272 descr = _("Do not bind keyboard shortcuts from Window Maker\n"
1273 "when this window is focused. This will allow the\n"
1274 "window to receive all key combinations regardless\n"
1275 "of your shortcut configuration.");
1276 break;
1277 case 2:
1278 caption = _("Don't Bind Mouse Clicks");
1279 flag = WFLAGP(wwin, no_bind_mouse);
1280 descr = _("Do not bind mouse actions, such as `Alt'+drag\n"
1281 "in the window (when alt is the modifier you have"
1282 "configured).");
1283 break;
1284 case 3:
1285 caption = _("Keep Inside Screen");
1286 flag = WFLAGP(wwin, dont_move_off);
1287 descr = _("Do not allow the window to move itself completely\n"
1288 "outside the screen. For bug compatibility.\n");
1289 break;
1290 case 4:
1291 caption = _("Don't Let It Take Focus");
1292 flag = WFLAGP(wwin, no_focusable);
1293 descr = _("Do not let the window take keyboard focus when you\n"
1294 "click on it.");
1295 break;
1296 case 5:
1297 caption = _("Don't Save Session");
1298 flag = WFLAGP(wwin, dont_save_session);
1299 descr = _("Do not save the associated application in the\n"
1300 "session's state, so that it won't be restarted\n"
1301 "together with other applications when Window Maker\n"
1302 "starts.");
1303 break;
1304 case 6:
1305 caption = _("Emulate Application Icon");
1306 flag = WFLAGP(wwin, emulate_appicon);
1307 descr = _("Make this window act as an application that provides\n"
1308 "enough information to Window Maker for a dockable\n"
1309 "application icon to be created.");
1310 break;
1311 case 7:
1312 caption = _("Full Screen Maximization");
1313 flag = WFLAGP(wwin, full_maximize);
1314 descr = _("Make the window use the whole screen space when it's\n"
1315 "maximized. The titlebar and resizebar will be moved\n"
1316 "to outside the screen.");
1317 break;
1318 #ifdef XKB_BUTTON_HINT
1319 case 8:
1320 caption = _("Disable Language Button");
1321 flag = WFLAGP(wwin, no_language_button);
1322 descr = _("Remove the `toggle language' button of the window.");
1323 break;
1324 #endif
1326 panel->moreChk[i] = WMCreateSwitchButton(panel->moreFrm);
1327 WMMoveWidget(panel->moreChk[i], 10, 20*(i+1));
1328 WMResizeWidget(panel->moreChk[i], frame_width-15, 20);
1329 WMSetButtonSelected(panel->moreChk[i], flag);
1330 WMSetButtonText(panel->moreChk[i], caption);
1332 WMSetBalloonTextForView(descr, WMWidgetView(panel->moreChk[i]));
1335 /* miniwindow/workspace */
1336 panel->iconFrm = WMCreateFrame(panel->win);
1337 WMMoveWidget(panel->iconFrm, 15, 50);
1338 WMResizeWidget(panel->iconFrm, PWIDTH - (2 * 15), 170);
1339 WMSetFrameTitle(panel->iconFrm, _("Miniwindow Image"));
1341 panel->iconLbl = WMCreateLabel(panel->iconFrm);
1342 WMMoveWidget(panel->iconLbl, PWIDTH - (2 * 15) - 22 - 64, 30);
1343 WMResizeWidget(panel->iconLbl, 64, 64);
1344 WMSetLabelRelief(panel->iconLbl, WRGroove);
1345 WMSetLabelImagePosition(panel->iconLbl, WIPImageOnly);
1347 panel->browseIconBtn = WMCreateCommandButton(panel->iconFrm);
1348 WMSetButtonAction(panel->browseIconBtn, chooseIconCallback, panel);
1349 WMMoveWidget(panel->browseIconBtn, 22, 30);
1350 WMResizeWidget(panel->browseIconBtn, 100, 26);
1351 WMSetButtonText(panel->browseIconBtn, _("Browse..."));
1353 #if 0
1354 panel->updateIconBtn = WMCreateCommandButton(panel->iconFrm);
1355 WMSetButtonAction(panel->updateIconBtn, (WMAction*)updateIcon, panel);
1356 WMMoveWidget(panel->updateIconBtn, 22, 65);
1357 WMResizeWidget(panel->updateIconBtn, 100, 26);
1358 WMSetButtonText(panel->updateIconBtn, _("Update"));
1359 #endif
1360 #ifdef wrong_behaviour
1361 WMSetButtonImagePosition(panel->updateIconBtn, WIPRight);
1362 pixmap = WMGetSystemPixmap(scr->wmscreen, WSIReturnArrow);
1363 WMSetButtonImage(panel->updateIconBtn, pixmap);
1364 WMReleasePixmap(pixmap);
1365 pixmap = WMGetSystemPixmap(scr->wmscreen, WSIHighlightedReturnArrow);
1366 WMSetButtonAltImage(panel->updateIconBtn, pixmap);
1367 WMReleasePixmap(pixmap);
1368 #endif
1370 panel->fileLbl = WMCreateLabel(panel->iconFrm);
1371 WMMoveWidget(panel->fileLbl, 20, 95);
1372 WMResizeWidget(panel->fileLbl, PWIDTH - (2 * 15) - (2 * 20), 14);
1373 WMSetLabelText(panel->fileLbl, _("Icon File Name:"));
1375 panel->fileText = WMCreateTextField(panel->iconFrm);
1376 WMMoveWidget(panel->fileText, 20, 115);
1377 WMResizeWidget(panel->fileText, PWIDTH - (2 * 15) - (2 * 15), 20);
1378 WMSetTextFieldText(panel->fileText, NULL);
1379 WMAddNotificationObserver(textEditedObserver, panel,
1380 WMTextDidEndEditingNotification,
1381 panel->fileText);
1382 panel->alwChk = WMCreateSwitchButton(panel->iconFrm);
1383 WMMoveWidget(panel->alwChk, 20, 140);
1384 WMResizeWidget(panel->alwChk, PWIDTH - (2 * 15) - (2 * 15), 20);
1385 WMSetButtonText(panel->alwChk, _("Ignore client supplied icon"));
1386 WMSetButtonSelected(panel->alwChk, WFLAGP(wwin, always_user_icon));
1389 panel->wsFrm = WMCreateFrame(panel->win);
1390 WMMoveWidget(panel->wsFrm, 15, 225);
1391 WMResizeWidget(panel->wsFrm, PWIDTH - (2 * 15), 70);
1392 WMSetFrameTitle(panel->wsFrm, _("Initial Workspace"));
1394 WMSetBalloonTextForView(_("The workspace to place the window when it's"
1395 "first shown."), WMWidgetView(panel->wsFrm));
1397 panel->wsP = WMCreatePopUpButton(panel->wsFrm);
1398 WMMoveWidget(panel->wsP, 20, 30);
1399 WMResizeWidget(panel->wsP, PWIDTH - (2 * 15) - (2 * 20), 20);
1400 WMAddPopUpButtonItem(panel->wsP, _("Nowhere in particular"));
1401 for (i = 0; i < wwin->screen_ptr->workspace_count; i++) {
1402 WMAddPopUpButtonItem(panel->wsP, scr->workspaces[i]->name);
1405 i = wDefaultGetStartWorkspace(wwin->screen_ptr, wwin->wm_instance,
1406 wwin->wm_class);
1407 if (i >= 0 && i <= wwin->screen_ptr->workspace_count) {
1408 WMSetPopUpButtonSelectedItem(panel->wsP, i + 1);
1409 } else {
1410 WMSetPopUpButtonSelectedItem(panel->wsP, 0);
1413 /* application wide attributes */
1414 if (wwin->main_window != None) {
1415 WApplication *wapp = wApplicationOf(wwin->main_window);
1417 panel->appFrm = WMCreateFrame(panel->win);
1418 WMSetFrameTitle(panel->appFrm, _("Application Wide"));
1419 WMMoveWidget(panel->appFrm, 15, 50);
1420 WMResizeWidget(panel->appFrm, frame_width, 240);
1422 for (i=0; i < 2; i++) {
1423 char *caption = NULL;
1424 int flag = 0;
1425 char *descr = NULL;
1427 switch (i) {
1428 case 0:
1429 caption = _("Start Hidden");
1430 flag = WFLAGP(wapp->main_window_desc, start_hidden);
1431 descr = _("Automatically hide application when it's started.");
1432 break;
1433 case 1:
1434 caption = _("No Application Icon");
1435 flag = WFLAGP(wapp->main_window_desc, no_appicon);
1436 descr = _("Disable the application icon for the application.\n"
1437 "Note that you won't be able to dock it anymore,\n"
1438 "and any icons that are already docked will stop\n"
1439 "working correctly.");
1440 break;
1442 panel->appChk[i] = WMCreateSwitchButton(panel->appFrm);
1443 WMMoveWidget(panel->appChk[i], 10, 20*(i+1));
1444 WMResizeWidget(panel->appChk[i], 205, 20);
1445 WMSetButtonSelected(panel->appChk[i], flag);
1446 WMSetButtonText(panel->appChk[i], caption);
1448 WMSetBalloonTextForView(descr, WMWidgetView(panel->appChk[i]));
1451 if (WFLAGP(wwin, emulate_appicon)) {
1452 WMSetButtonEnabled(panel->appChk[1], False);
1453 WMSetButtonEnabled(panel->moreChk[6], True);
1454 } else {
1455 WMSetButtonEnabled(panel->appChk[1], True);
1456 WMSetButtonEnabled(panel->moreChk[6], False);
1458 } else {
1459 int tmp;
1461 if ((wwin->transient_for!=None && wwin->transient_for!=scr->root_win)
1462 || !wwin->wm_class || !wwin->wm_instance)
1463 tmp = False;
1464 else
1465 tmp = True;
1466 WMSetButtonEnabled(panel->moreChk[6], tmp);
1468 WMSetPopUpButtonItemEnabled(panel->pagePopUp, 4, False);
1469 panel->appFrm = NULL;
1472 /* if the window is a transient, don't let it have a miniaturize
1473 * button */
1474 if (wWindowFor(wwin->transient_for)!=NULL)
1475 WMSetButtonEnabled(panel->attrChk[3], False);
1476 else
1477 WMSetButtonEnabled(panel->attrChk[3], True);
1480 if (!wwin->wm_class && !wwin->wm_instance) {
1481 WMSetPopUpButtonItemEnabled(panel->pagePopUp, 0, False);
1485 WMRealizeWidget(panel->win);
1487 WMMapSubwidgets(panel->win);
1488 WMMapSubwidgets(panel->specFrm);
1489 WMMapSubwidgets(panel->attrFrm);
1490 WMMapSubwidgets(panel->moreFrm);
1491 WMMapSubwidgets(panel->iconFrm);
1492 WMMapSubwidgets(panel->wsFrm);
1493 if (panel->appFrm)
1494 WMMapSubwidgets(panel->appFrm);
1496 WMSetPopUpButtonSelectedItem(panel->pagePopUp, 1);
1497 changePage(panel->pagePopUp, panel);
1500 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, PWIDTH, PHEIGHT,
1501 0, 0, 0);
1502 XSelectInput(dpy, parent, KeyPressMask|KeyReleaseMask);
1503 panel->parent = parent;
1504 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
1506 WMMapWidget(panel->win);
1508 XSetTransientForHint(dpy, parent, wwin->client_win);
1510 x = wwin->frame_x+wwin->frame->core->width/2;
1511 y = wwin->frame_y+wwin->frame->top_width*2;
1512 if (y + PHEIGHT > scr->scr_height)
1513 y = scr->scr_height - PHEIGHT - 30;
1514 if (x + PWIDTH > scr->scr_width)
1515 x = scr->scr_width - PWIDTH;
1517 panel->frame = wManageInternalWindow(scr, parent, wwin->client_win,
1518 "Inspector", x, y, PWIDTH, PHEIGHT);
1520 if (!selectedBtn)
1521 selectedBtn = panel->defaultRb;
1523 WMSetButtonSelected(selectedBtn, True);
1525 selectSpecification(selectedBtn, panel);
1527 /* kluge to know who should get the key events */
1528 panel->frame->client_leader = WMWidgetXID(panel->win);
1530 WSETUFLAG(panel->frame, no_closable, 0);
1531 WSETUFLAG(panel->frame, no_close_button, 0);
1532 wWindowUpdateButtonImages(panel->frame);
1533 wFrameWindowShowButton(panel->frame->frame, WFF_RIGHT_BUTTON);
1534 panel->frame->frame->on_click_right = destroyInspector;
1536 wWindowMap(panel->frame);
1538 showIconFor(WMWidgetScreen(panel->alwChk), panel, wwin->wm_instance,
1539 wwin->wm_class, UPDATE_TEXT_FIELD);
1541 return panel;
1545 void
1546 wShowInspectorForWindow(WWindow *wwin)
1548 if (wwin->flags.inspector_open)
1549 return;
1551 WMSetBalloonEnabled(wwin->screen_ptr->wmscreen, wPreferences.help_balloon);
1553 make_keys();
1554 wwin->flags.inspector_open = 1;
1555 wwin->inspector = createInspectorForWindow(wwin);;