changed geometry display stuff
[wmaker-crm.git] / src / winspector.c
blobf9de05d3010c62fcb084d212a468b762c5c62ce8
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"
48 #include "client.h"
50 #include <proplist.h>
58 typedef struct InspectorPanel {
59 struct InspectorPanel *nextPtr;
61 WWindow *frame;
63 WWindow *inspected; /* the window that's being inspected */
65 WMWindow *win;
67 Window parent;
69 /* common stuff */
70 WMButton *revertBtn;
71 WMButton *applyBtn;
72 WMButton *saveBtn;
74 WMPopUpButton *pagePopUp;
76 /* first page. general stuff */
78 WMFrame *specFrm;
79 WMButton *instRb;
80 WMButton *clsRb;
81 WMButton *bothRb;
82 WMButton *defaultRb;
84 WMButton *selWinB;
86 WMLabel *specLbl;
88 /* second page. attributes */
90 WMFrame *attrFrm;
91 WMButton *attrChk[11];
93 /* 3rd page. more attributes */
94 WMFrame *moreFrm;
95 #ifdef XKB_BUTTON_HINT
96 WMButton *moreChk[9];
97 #else
98 WMButton *moreChk[8];
99 #endif
101 /* 4th page. icon and workspace */
102 WMFrame *iconFrm;
103 WMLabel *iconLbl;
104 WMLabel *fileLbl;
105 WMTextField *fileText;
106 WMButton *alwChk;
108 WMButton *updateIconBtn;
110 WMButton *browseIconBtn;
112 WMFrame *wsFrm;
113 WMPopUpButton *wsP;
115 /* 5th page. application wide attributes */
116 WMFrame *appFrm;
117 WMButton *appChk[2];
119 unsigned int done:1;
120 unsigned int destroyed:1;
121 unsigned int choosingIcon:1;
122 } InspectorPanel;
127 extern Cursor wCursor[WCUR_LAST];
129 extern WDDomain *WDWindowAttributes;
131 static InspectorPanel *panelList=NULL;
133 extern WPreferences wPreferences;
135 static proplist_t ANoTitlebar = NULL;
136 static proplist_t ANoResizebar;
137 static proplist_t ANoMiniaturizeButton;
138 static proplist_t ANoCloseButton;
139 static proplist_t ANoBorder;
140 static proplist_t ANoHideOthers;
141 static proplist_t ANoMouseBindings;
142 static proplist_t ANoKeyBindings;
143 static proplist_t ANoAppIcon;
144 static proplist_t AKeepOnTop;
145 static proplist_t AKeepOnBottom;
146 static proplist_t AOmnipresent;
147 static proplist_t ASkipWindowList;
148 static proplist_t AKeepInsideScreen;
149 static proplist_t AUnfocusable;
150 static proplist_t AAlwaysUserIcon;
151 static proplist_t AStartMiniaturized;
152 static proplist_t AStartMaximized;
153 static proplist_t ADontSaveSession;
154 static proplist_t AEmulateAppIcon;
155 static proplist_t AFullMaximize;
156 #ifdef XKB_BUTTON_HINT
157 static proplist_t ANoLanguageButton;
158 #endif
160 static proplist_t AStartWorkspace;
162 static proplist_t AIcon;
164 /* application wide options */
165 static proplist_t AStartHidden;
168 static proplist_t AnyWindow;
169 static proplist_t EmptyString;
170 static proplist_t Yes, No;
173 #define PWIDTH 270
174 #define PHEIGHT 350
179 static void applySettings(WMButton *button, InspectorPanel *panel);
184 #define UNDEFINED_POS 0xffffff
186 static InspectorPanel *createInspectorForWindow(WWindow *wwin,
187 int xpos, int ypos,
188 Bool showSelectPanel);
192 static void
193 make_keys()
195 if (ANoTitlebar!=NULL)
196 return;
198 AIcon = PLMakeString("Icon");
199 ANoTitlebar = PLMakeString("NoTitlebar");
200 ANoResizebar = PLMakeString("NoResizebar");
201 ANoMiniaturizeButton = PLMakeString("NoMiniaturizeButton");
202 ANoCloseButton = PLMakeString("NoCloseButton");
203 ANoBorder = PLMakeString("NoBorder");
204 ANoHideOthers = PLMakeString("NoHideOthers");
205 ANoMouseBindings = PLMakeString("NoMouseBindings");
206 ANoKeyBindings = PLMakeString("NoKeyBindings");
207 ANoAppIcon = PLMakeString("NoAppIcon");
208 AKeepOnTop = PLMakeString("KeepOnTop");
209 AKeepOnBottom = PLMakeString("KeepOnBottom");
210 AOmnipresent = PLMakeString("Omnipresent");
211 ASkipWindowList = PLMakeString("SkipWindowList");
212 AKeepInsideScreen = PLMakeString("KeepInsideScreen");
213 AUnfocusable = PLMakeString("Unfocusable");
214 AAlwaysUserIcon = PLMakeString("AlwaysUserIcon");
215 AStartMiniaturized = PLMakeString("StartMiniaturized");
216 AStartMaximized = PLMakeString("StartMaximized");
217 AStartHidden = PLMakeString("StartHidden");
218 ADontSaveSession = PLMakeString("DontSaveSession");
219 AEmulateAppIcon = PLMakeString("EmulateAppIcon");
220 AFullMaximize = PLMakeString("FullMaximize");
221 #ifdef XKB_BUTTON_HINT
222 ANoLanguageButton = PLMakeString("NoLanguageButton");
223 #endif
225 AStartWorkspace = PLMakeString("StartWorkspace");
227 AnyWindow = PLMakeString("*");
228 EmptyString = PLMakeString("");
229 Yes = PLMakeString("Yes");
230 No = PLMakeString("No");
235 static void
236 freeInspector(InspectorPanel *panel)
238 panel->destroyed = 1;
239 if (panel->choosingIcon)
240 return;
242 WMDestroyWidget(panel->win);
244 XDestroyWindow(dpy, panel->parent);
246 free(panel);
250 static void
251 destroyInspector(WCoreWindow *foo, void *data, XEvent *event)
253 InspectorPanel *panel;
254 InspectorPanel *tmp;
256 panel = panelList;
257 while (panel->frame!=data)
258 panel = panel->nextPtr;
260 if (panelList == panel)
261 panelList = panel->nextPtr;
262 else {
263 tmp = panelList;
264 while (tmp->nextPtr!=panel) {
265 tmp = tmp->nextPtr;
267 tmp->nextPtr = panel->nextPtr;
269 panel->inspected->flags.inspector_open = 0;
270 panel->inspected->inspector = NULL;
272 WMRemoveNotificationObserver(panel);
274 wWindowUnmap(panel->frame);
275 wUnmanageWindow(panel->frame, True, False);
277 freeInspector(panel);
282 void
283 wDestroyInspectorPanels()
285 InspectorPanel *panel;
287 while (panelList != NULL) {
288 panel = panelList;
289 panelList = panelList->nextPtr;
290 wUnmanageWindow(panel->frame, False, False);
291 WMDestroyWidget(panel->win);
293 panel->inspected->flags.inspector_open = 0;
294 panel->inspected->inspector = NULL;
296 free(panel);
301 static void
302 changePage(WMPopUpButton *bPtr, InspectorPanel *panel)
304 int page;
306 page = WMGetPopUpButtonSelectedItem(bPtr);
308 if (page == 0) {
309 WMMapWidget(panel->specFrm);
310 WMMapWidget(panel->specLbl);
311 } else if (page == 1) {
312 WMMapWidget(panel->attrFrm);
313 } else if (page == 2) {
314 WMMapWidget(panel->moreFrm);
315 } else if (page == 3) {
316 WMMapWidget(panel->iconFrm);
317 WMMapWidget(panel->wsFrm);
318 } else {
319 WMMapWidget(panel->appFrm);
322 if (page != 0) {
323 WMUnmapWidget(panel->specFrm);
324 WMUnmapWidget(panel->specLbl);
326 if (page != 1)
327 WMUnmapWidget(panel->attrFrm);
328 if (page != 2)
329 WMUnmapWidget(panel->moreFrm);
330 if (page != 3) {
331 WMUnmapWidget(panel->iconFrm);
332 WMUnmapWidget(panel->wsFrm);
334 if (page != 4 && panel->appFrm)
335 WMUnmapWidget(panel->appFrm);
339 #define USE_TEXT_FIELD 1
340 #define UPDATE_TEXT_FIELD 2
341 #define REVERT_TO_DEFAULT 4
344 static int
345 showIconFor(WMScreen *scrPtr, InspectorPanel *panel,
346 char *wm_instance, char *wm_class, int flags)
348 WMPixmap *pixmap = (WMPixmap*) NULL;
349 char *file=NULL, *path=NULL;
350 char *db_icon=NULL;
352 if ((flags & USE_TEXT_FIELD) != 0) {
353 file = WMGetTextFieldText(panel->fileText);
354 if (file && file[0] == 0) {
355 free(file);
356 file = NULL;
358 } else {
359 db_icon = wDefaultGetIconFile(panel->inspected->screen_ptr,
360 wm_instance, wm_class, False);
361 if(db_icon != NULL)
362 file = wstrdup(db_icon);
364 if (db_icon!=NULL && (flags & REVERT_TO_DEFAULT)!=0) {
365 if (file)
366 file = wstrdup(db_icon);
367 flags |= UPDATE_TEXT_FIELD;
370 if ((flags & UPDATE_TEXT_FIELD) != 0) {
371 WMSetTextFieldText(panel->fileText, file);
374 if (file) {
375 path = FindImage(wPreferences.icon_path, file);
377 if (!path) {
378 char *buf;
380 buf = wmalloc(strlen(file)+80);
381 sprintf(buf, _("Could not find icon \"%s\" specified for this window"),
382 file);
383 wMessageDialog(panel->frame->screen_ptr, _("Error"), buf,
384 _("OK"), NULL, NULL);
385 free(buf);
386 free(file);
387 return -1;
390 pixmap = WMCreatePixmapFromFile(scrPtr, path);
391 free(path);
393 if (!pixmap) {
394 char *buf;
396 buf = wmalloc(strlen(file)+80);
397 sprintf(buf, _("Could not open specified icon \"%s\":%s"),
398 file, RMessageForError(RErrorCode));
399 wMessageDialog(panel->frame->screen_ptr, _("Error"), buf,
400 _("OK"), NULL, NULL);
401 free(buf);
402 free(file);
403 return -1;
405 free(file);
408 WMSetLabelImage(panel->iconLbl, pixmap);
409 if (pixmap)
410 WMReleasePixmap(pixmap);
412 return 0;
415 #if 0
416 static void
417 updateIcon(WMButton *button, InspectorPanel *panel)
419 showIconFor(WMWidgetScreen(button), panel, NULL, NULL, USE_TEXT_FIELD);
421 #endif
423 static int
424 getBool(proplist_t value)
426 char *val;
428 if (!PLIsString(value)) {
429 return 0;
431 if (!(val = PLGetString(value))) {
432 return 0;
435 if ((val[1]=='\0' && (val[0]=='y' || val[0]=='Y' || val[0]=='T'
436 || val[0]=='t' || val[0]=='1'))
437 || (strcasecmp(val, "YES")==0 || strcasecmp(val, "TRUE")==0)) {
439 return 1;
440 } else if ((val[1]=='\0'
441 && (val[0]=='n' || val[0]=='N' || val[0]=='F'
442 || val[0]=='f' || val[0]=='0'))
443 || (strcasecmp(val, "NO")==0 || strcasecmp(val, "FALSE")==0)) {
445 return 0;
446 } else {
447 wwarning(_("can't convert \"%s\" to boolean"), val);
448 return 0;
453 #define UPDATE_DEFAULTS 1
454 #define IS_BOOLEAN 2
458 * Will insert the attribute = value; pair in window's list,
459 * if it's different from the defaults.
460 * Defaults means either defaults database, or attributes saved
461 * for the default window "*". This is to let one revert options that are
462 * global because they were saved for all windows ("*").
467 static int
468 insertAttribute(proplist_t dict, proplist_t window, proplist_t attr,
469 proplist_t value, int flags)
471 proplist_t def_win, def_value=NULL;
472 int update = 0;
473 int modified = 0;
475 if (!(flags & UPDATE_DEFAULTS) && dict) {
476 if ((def_win = PLGetDictionaryEntry(dict, AnyWindow)) != NULL) {
477 def_value = PLGetDictionaryEntry(def_win, attr);
481 /* If we could not find defaults in database, fall to hardcoded values.
482 * Also this is true if we save defaults for all windows
484 if (!def_value)
485 def_value = ((flags & IS_BOOLEAN) != 0) ? No : EmptyString;
487 if ((flags & IS_BOOLEAN))
488 update = (getBool(value) != getBool(def_value));
489 else {
490 update = !PLIsEqual(value, def_value);
493 if (update) {
494 PLInsertDictionaryEntry(window, attr, value);
495 modified = 1;
498 return modified;
502 static void
503 saveSettings(WMButton *button, InspectorPanel *panel)
505 WWindow *wwin = panel->inspected;
506 WDDomain *db = WDWindowAttributes;
507 proplist_t dict = db->dictionary;
508 proplist_t winDic, value, key;
509 char *icon_file;
510 int flags = 0;
511 int different = 0;
513 /* Save will apply the changes and save them */
514 applySettings(panel->applyBtn, panel);
516 if (WMGetButtonSelected(panel->instRb) != 0)
517 key = PLMakeString(wwin->wm_instance);
518 else if (WMGetButtonSelected(panel->clsRb) != 0)
519 key = PLMakeString(wwin->wm_class);
520 else if (WMGetButtonSelected(panel->bothRb) != 0) {
521 char *buffer;
523 buffer = wmalloc(strlen(wwin->wm_instance)+strlen(wwin->wm_class)+4);
524 strcat(strcat(strcpy(buffer, wwin->wm_instance), "."), wwin->wm_class);
525 key = PLMakeString(buffer);
526 free(buffer);
527 } else if (WMGetButtonSelected(panel->defaultRb) != 0) {
528 key = PLRetain(AnyWindow);
529 flags = UPDATE_DEFAULTS;
530 } else
531 key = NULL;
533 if (!key)
534 return;
536 if (!dict) {
537 dict = PLMakeDictionaryFromEntries(NULL, NULL, NULL);
538 if (dict) {
539 db->dictionary = dict;
540 value = PLMakeString(db->path);
541 PLSetFilename(dict, value);
542 PLRelease(value);
544 else {
545 PLRelease(key);
546 return;
550 if (showIconFor(WMWidgetScreen(button), panel, NULL, NULL,
551 USE_TEXT_FIELD) < 0)
552 return;
554 PLSetStringCmpHook(NULL);
556 winDic = PLMakeDictionaryFromEntries(NULL, NULL, NULL);
558 /* Update icon for window */
559 icon_file = WMGetTextFieldText(panel->fileText);
560 if (icon_file) {
561 if (icon_file[0] != 0) {
562 value = PLMakeString(icon_file);
563 different |= insertAttribute(dict, winDic, AIcon, value, flags);
564 PLRelease(value);
566 free(icon_file);
570 int i = WMGetPopUpButtonSelectedItem(panel->wsP);
572 i--;
574 if (i>=0 && i < panel->frame->screen_ptr->workspace_count) {
575 value = PLMakeString(panel->frame->screen_ptr->workspaces[i]->name);
576 different |= insertAttribute(dict, winDic, AStartWorkspace, value,
577 flags);
578 PLRelease(value);
582 flags |= IS_BOOLEAN;
584 value = (WMGetButtonSelected(panel->alwChk)!=0) ? Yes : No;
585 different |= insertAttribute(dict, winDic, AAlwaysUserIcon, value, flags);
587 value = (WMGetButtonSelected(panel->attrChk[0])!=0) ? Yes : No;
588 different |= insertAttribute(dict, winDic, ANoTitlebar, value, flags);
590 value = (WMGetButtonSelected(panel->attrChk[1])!=0) ? Yes : No;
591 different |= insertAttribute(dict, winDic, ANoResizebar, value, flags);
593 value = (WMGetButtonSelected(panel->attrChk[2])!=0) ? Yes : No;
594 different |= insertAttribute(dict, winDic, ANoCloseButton, value, flags);
596 value = (WMGetButtonSelected(panel->attrChk[3])!=0) ? Yes : No;
597 different |= insertAttribute(dict, winDic, ANoMiniaturizeButton, value, flags);
599 value = (WMGetButtonSelected(panel->attrChk[4])!=0) ? Yes : No;
600 different |= insertAttribute(dict, winDic, ANoBorder, value, flags);
602 value = (WMGetButtonSelected(panel->attrChk[5])!=0) ? Yes : No;
603 different |= insertAttribute(dict, winDic, AKeepOnTop, value, flags);
605 value = (WMGetButtonSelected(panel->attrChk[6])!=0) ? Yes : No;
606 different |= insertAttribute(dict, winDic, AKeepOnBottom, value, flags);
608 value = (WMGetButtonSelected(panel->attrChk[7])!=0) ? Yes : No;
609 different |= insertAttribute(dict, winDic, AOmnipresent, value, flags);
611 value = (WMGetButtonSelected(panel->attrChk[8])!=0) ? Yes : No;
612 different |= insertAttribute(dict, winDic, AStartMiniaturized, value, flags);
614 value = (WMGetButtonSelected(panel->attrChk[9])!=0) ? Yes : No;
615 different |= insertAttribute(dict, winDic, AStartMaximized, value, flags);
617 value = (WMGetButtonSelected(panel->attrChk[10])!=0) ? Yes : No;
618 different |= insertAttribute(dict, winDic, ASkipWindowList, value, flags);
621 value = (WMGetButtonSelected(panel->moreChk[0])!=0) ? Yes : No;
622 different |= insertAttribute(dict, winDic, ANoHideOthers, value, flags);
624 value = (WMGetButtonSelected(panel->moreChk[1])!=0) ? Yes : No;
625 different |= insertAttribute(dict, winDic, ANoKeyBindings, value, flags);
627 value = (WMGetButtonSelected(panel->moreChk[2])!=0) ? Yes : No;
628 different |= insertAttribute(dict, winDic, ANoMouseBindings, value, flags);
630 value = (WMGetButtonSelected(panel->moreChk[3])!=0) ? Yes : No;
631 different |= insertAttribute(dict, winDic, AKeepInsideScreen,value, flags);
633 value = (WMGetButtonSelected(panel->moreChk[4])!=0) ? Yes : No;
634 different |= insertAttribute(dict, winDic, AUnfocusable, value, flags);
636 value = (WMGetButtonSelected(panel->moreChk[5])!=0) ? Yes : No;
637 different |= insertAttribute(dict, winDic, ADontSaveSession, value, flags);
639 value = (WMGetButtonSelected(panel->moreChk[6])!=0) ? Yes : No;
640 different |= insertAttribute(dict, winDic, AEmulateAppIcon, value, flags);
642 value = (WMGetButtonSelected(panel->moreChk[7])!=0) ? Yes : No;
643 different |= insertAttribute(dict, winDic, AFullMaximize, value, flags);
645 #ifdef XKB_BUTTON_HINT
646 value = (WMGetButtonSelected(panel->moreChk[8])!=0) ? Yes : No;
647 different |= insertAttribute(dict, winDic, ANoLanguageButton, value, flags);
648 #endif
650 /* application wide settings for when */
651 /* the window is the leader, save the attribute with the others */
652 if (panel->inspected->main_window == panel->inspected->client_win) {
654 value = (WMGetButtonSelected(panel->appChk[0])!=0) ? Yes : No;
655 different |= insertAttribute(dict, winDic, AStartHidden, value, flags);
657 value = (WMGetButtonSelected(panel->appChk[1])!=0) ? Yes : No;
658 different |= insertAttribute(dict, winDic, ANoAppIcon, value, flags);
661 PLRemoveDictionaryEntry(dict, key);
662 if (different) {
663 PLInsertDictionaryEntry(dict, key, winDic);
666 PLRelease(key);
667 PLRelease(winDic);
669 different = 0;
671 /* application wide settings */
672 if (panel->inspected->main_window != panel->inspected->client_win
673 && !(flags & UPDATE_DEFAULTS)) {
674 WApplication *wapp;
675 proplist_t appDic;
677 wapp = wApplicationOf(panel->inspected->main_window);
678 if (wapp) {
679 char *iconFile;
680 char *buffer;
682 appDic = PLMakeDictionaryFromEntries(NULL, NULL, NULL);
684 assert(wapp->main_window_desc->wm_instance!=NULL);
685 assert(wapp->main_window_desc->wm_class!=NULL);
687 buffer = wmalloc(strlen(wapp->main_window_desc->wm_instance)
688 +strlen(wapp->main_window_desc->wm_class)+4);
689 strcat(strcpy(buffer, wapp->main_window_desc->wm_instance), ".");
690 strcat(buffer, wapp->main_window_desc->wm_class);
691 key = PLMakeString(buffer);
692 free(buffer);
694 iconFile = wDefaultGetIconFile(wwin->screen_ptr,
695 wapp->main_window_desc->wm_instance,
696 wapp->main_window_desc->wm_class,
697 False);
699 if (iconFile && iconFile[0]!=0) {
700 value = PLMakeString(iconFile);
701 different |= insertAttribute(dict, appDic, AIcon, value,
702 flags&~IS_BOOLEAN);
703 PLRelease(value);
706 value = (WMGetButtonSelected(panel->appChk[0])!=0) ? Yes : No;
707 different |= insertAttribute(dict, appDic, AStartHidden, value,
708 flags);
710 value = (WMGetButtonSelected(panel->appChk[1])!=0) ? Yes : No;
711 different |= insertAttribute(dict, appDic, ANoAppIcon, value,
712 flags);
714 PLRemoveDictionaryEntry(dict, key);
715 if (different) {
716 PLInsertDictionaryEntry(dict, key, appDic);
718 PLRelease(key);
719 PLRelease(appDic);
723 PLSave(dict, YES);
725 /* clean up */
726 PLSetStringCmpHook(StringCompareHook);
730 static void
731 makeAppIconFor(WApplication *wapp)
733 WScreen *scr = wapp->main_window_desc->screen_ptr;
735 if (wapp->app_icon)
736 return;
738 if (!WFLAGP(wapp->main_window_desc, no_appicon))
739 wapp->app_icon = wAppIconCreate(wapp->main_window_desc);
740 else
741 wapp->app_icon = NULL;
743 if (wapp->app_icon) {
744 WIcon *icon = wapp->app_icon->icon;
745 WDock *clip = scr->workspaces[scr->current_workspace]->clip;
746 int x=0, y=0;
748 wapp->app_icon->main_window = wapp->main_window;
750 if (clip && clip->attract_icons && wDockFindFreeSlot(clip, &x, &y)) {
751 wapp->app_icon->attracted = 1;
752 if (!wapp->app_icon->icon->shadowed) {
753 wapp->app_icon->icon->shadowed = 1;
754 wapp->app_icon->icon->force_paint = 1;
756 wDockAttachIcon(clip, wapp->app_icon, x, y);
757 } else {
758 PlaceIcon(scr, &x, &y);
759 wAppIconMove(wapp->app_icon, x, y);
761 if (!clip || !wapp->app_icon->attracted || !clip->collapsed)
762 XMapWindow(dpy, icon->core->window);
764 if (wPreferences.auto_arrange_icons && !wapp->app_icon->attracted)
765 wArrangeIcons(wapp->main_window_desc->screen_ptr, True);
770 static void
771 removeAppIconFor(WApplication *wapp)
773 if (!wapp->app_icon)
774 return;
776 if (wapp->app_icon->docked && !wapp->app_icon->attracted) {
777 wapp->app_icon->running = 0;
778 /* since we keep it, we don't care if it was attracted or not */
779 wapp->app_icon->attracted = 0;
780 wapp->app_icon->icon->shadowed = 0;
781 wapp->app_icon->main_window = None;
782 wapp->app_icon->pid = 0;
783 wapp->app_icon->icon->owner = NULL;
784 wapp->app_icon->icon->icon_win = None;
785 wapp->app_icon->icon->force_paint = 1;
786 wAppIconPaint(wapp->app_icon);
787 } else if (wapp->app_icon->docked) {
788 wapp->app_icon->running = 0;
789 wDockDetach(wapp->app_icon->dock, wapp->app_icon);
790 } else {
791 wAppIconDestroy(wapp->app_icon);
793 wapp->app_icon = NULL;
794 if (wPreferences.auto_arrange_icons)
795 wArrangeIcons(wapp->main_window_desc->screen_ptr, True);
799 static void
800 applySettings(WMButton *button, InspectorPanel *panel)
802 WWindow *wwin = panel->inspected;
803 WApplication *wapp = wApplicationOf(wwin->main_window);
804 int floating, sunken, skip_window_list;
805 int old_omnipresent;
806 int old_no_bind_keys;
807 int old_no_bind_mouse;
809 old_omnipresent = WFLAGP(wwin, omnipresent);
810 old_no_bind_keys = WFLAGP(wwin, no_bind_keys);
811 old_no_bind_mouse = WFLAGP(wwin, no_bind_mouse);
813 showIconFor(WMWidgetScreen(button), panel, NULL, NULL, USE_TEXT_FIELD);
815 WSETUFLAG(wwin, no_titlebar, WMGetButtonSelected(panel->attrChk[0]));
816 WSETUFLAG(wwin, no_resizebar, WMGetButtonSelected(panel->attrChk[1]));
817 WSETUFLAG(wwin, no_close_button, WMGetButtonSelected(panel->attrChk[2]));
818 WSETUFLAG(wwin, no_miniaturize_button, WMGetButtonSelected(panel->attrChk[3]));
819 WSETUFLAG(wwin, no_border, WMGetButtonSelected(panel->attrChk[4]));
820 floating = WMGetButtonSelected(panel->attrChk[5]);
821 sunken = WMGetButtonSelected(panel->attrChk[6]);
822 WSETUFLAG(wwin, omnipresent, WMGetButtonSelected(panel->attrChk[7]));
823 WSETUFLAG(wwin, start_miniaturized, WMGetButtonSelected(panel->attrChk[8]));
824 WSETUFLAG(wwin, start_maximized, WMGetButtonSelected(panel->attrChk[9]));
825 skip_window_list = WMGetButtonSelected(panel->attrChk[10]);
827 WSETUFLAG(wwin, no_hide_others, WMGetButtonSelected(panel->moreChk[0]));
828 WSETUFLAG(wwin, no_bind_keys, WMGetButtonSelected(panel->moreChk[1]));
829 WSETUFLAG(wwin, no_bind_mouse, WMGetButtonSelected(panel->moreChk[2]));
830 WSETUFLAG(wwin, dont_move_off, WMGetButtonSelected(panel->moreChk[3]));
831 WSETUFLAG(wwin, no_focusable, WMGetButtonSelected(panel->moreChk[4]));
832 WSETUFLAG(wwin, dont_save_session, WMGetButtonSelected(panel->moreChk[5]));
833 WSETUFLAG(wwin, emulate_appicon, WMGetButtonSelected(panel->moreChk[6]));
834 WSETUFLAG(wwin, full_maximize, WMGetButtonSelected(panel->moreChk[7]));
835 #ifdef XKB_BUTTON_HINT
836 WSETUFLAG(wwin, no_language_button, WMGetButtonSelected(panel->moreChk[8]));
837 #endif
838 WSETUFLAG(wwin, always_user_icon, WMGetButtonSelected(panel->alwChk));
840 if (WFLAGP(wwin, no_titlebar) && wwin->flags.shaded)
841 wUnshadeWindow(wwin);
843 WSETUFLAG(wwin, no_shadeable, WFLAGP(wwin, no_titlebar));
845 if (floating) {
846 if (!WFLAGP(wwin, floating))
847 ChangeStackingLevel(wwin->frame->core, WMFloatingLevel);
848 } else if (sunken) {
849 if (!WFLAGP(wwin, sunken))
850 ChangeStackingLevel(wwin->frame->core, WMSunkenLevel);
851 } else {
852 if (WFLAGP(wwin, floating) || WFLAGP(wwin, sunken))
853 ChangeStackingLevel(wwin->frame->core, WMNormalLevel);
856 WSETUFLAG(wwin, sunken, sunken);
857 WSETUFLAG(wwin, floating, floating);
858 wwin->flags.omnipresent = 0;
860 if (WFLAGP(wwin, skip_window_list) != skip_window_list) {
861 WSETUFLAG(wwin, skip_window_list, skip_window_list);
862 UpdateSwitchMenu(wwin->screen_ptr, wwin,
863 skip_window_list ? ACTION_REMOVE : ACTION_ADD);
864 } else {
865 if (WFLAGP(wwin, omnipresent) != old_omnipresent) {
866 UpdateSwitchMenu(wwin->screen_ptr, wwin, ACTION_CHANGE_WORKSPACE);
870 if (WFLAGP(wwin, no_bind_keys) != old_no_bind_keys) {
871 if (WFLAGP(wwin, no_bind_keys)) {
872 XUngrabKey(dpy, AnyKey, AnyModifier, wwin->frame->core->window);
873 } else {
874 wWindowSetKeyGrabs(wwin);
878 if (WFLAGP(wwin, no_bind_mouse) != old_no_bind_mouse) {
879 wWindowResetMouseGrabs(wwin);
882 wwin->frame->flags.need_texture_change = 1;
883 wWindowConfigureBorders(wwin);
884 wFrameWindowPaint(wwin->frame);
887 * Can't apply emulate_appicon because it will probably cause problems.
890 if (wapp) {
891 /* do application wide stuff */
892 WSETUFLAG(wapp->main_window_desc, start_hidden,
893 WMGetButtonSelected(panel->appChk[0]));
895 WSETUFLAG(wapp->main_window_desc, no_appicon,
896 WMGetButtonSelected(panel->appChk[1]));
898 if (WFLAGP(wapp->main_window_desc, no_appicon))
899 removeAppIconFor(wapp);
900 else
901 makeAppIconFor(wapp);
903 if (wapp->app_icon && wapp->main_window == wwin->client_win) {
904 char *file = WMGetTextFieldText(panel->fileText);
906 if (file[0] == 0) {
907 free(file);
908 file = NULL;
910 wIconChangeImageFile(wapp->app_icon->icon, file);
911 if (file)
912 free(file);
913 wAppIconPaint(wapp->app_icon);
921 static void
922 revertSettings(WMButton *button, InspectorPanel *panel)
924 WWindow *wwin = panel->inspected;
925 WApplication *wapp = wApplicationOf(wwin->main_window);
926 int i, n;
927 char *wm_instance = NULL;
928 char *wm_class = NULL;
929 int workspace, level;
931 if (panel->instRb && WMGetButtonSelected(panel->instRb) != 0)
932 wm_instance = wwin->wm_instance;
933 else if (panel->clsRb && WMGetButtonSelected(panel->clsRb) != 0)
934 wm_class = wwin->wm_class;
935 else if (panel->bothRb && WMGetButtonSelected(panel->bothRb) != 0) {
936 wm_instance = wwin->wm_instance;
937 wm_class = wwin->wm_class;
939 memset(&wwin->defined_user_flags, 0, sizeof(WWindowAttributes));
940 memset(&wwin->user_flags, 0, sizeof(WWindowAttributes));
941 memset(&wwin->client_flags, 0, sizeof(WWindowAttributes));
943 wWindowSetupInitialAttributes(wwin, &level, &workspace);
945 for (i=0; i < 11; i++) {
946 int flag = 0;
948 switch (i) {
949 case 0:
950 flag = WFLAGP(wwin, no_titlebar);
951 break;
952 case 1:
953 flag = WFLAGP(wwin, no_resizebar);
954 break;
955 case 2:
956 flag = WFLAGP(wwin, no_close_button);
957 break;
958 case 3:
959 flag = WFLAGP(wwin, no_miniaturize_button);
960 break;
961 case 4:
962 flag = WFLAGP(wwin, no_border);
963 break;
964 case 5:
965 flag = WFLAGP(wwin, floating);
966 break;
967 case 6:
968 flag = WFLAGP(wwin, sunken);
969 break;
970 case 7:
971 flag = WFLAGP(wwin, omnipresent);
972 break;
973 case 8:
974 flag = WFLAGP(wwin, start_miniaturized);
975 break;
976 case 9:
977 flag = WFLAGP(wwin, start_maximized!=0);
978 break;
979 case 10:
980 flag = WFLAGP(wwin, skip_window_list);
981 break;
983 WMSetButtonSelected(panel->attrChk[i], flag);
985 for (i=0; i < 8; i++) {
986 int flag = 0;
988 switch (i) {
989 case 0:
990 flag = WFLAGP(wwin, no_hide_others);
991 break;
992 case 1:
993 flag = WFLAGP(wwin, no_bind_keys);
994 break;
995 case 2:
996 flag = WFLAGP(wwin, no_bind_mouse);
997 break;
998 case 3:
999 flag = WFLAGP(wwin, dont_move_off);
1000 break;
1001 case 4:
1002 flag = WFLAGP(wwin, no_focusable);
1003 break;
1004 case 5:
1005 flag = WFLAGP(wwin, dont_save_session);
1006 break;
1007 case 6:
1008 flag = WFLAGP(wwin, emulate_appicon);
1009 break;
1010 case 7:
1011 flag = WFLAGP(wwin, full_maximize);
1012 break;
1013 #ifdef XKB_BUTTON_HINT
1014 case 8:
1015 flag = WFLAGP(wwin, no_language_button);
1016 break;
1017 #endif
1019 WMSetButtonSelected(panel->moreChk[i], flag);
1021 if (panel->appFrm && wapp) {
1022 for (i=0; i < 2; i++) {
1023 int flag = 0;
1025 switch (i) {
1026 case 0:
1027 flag = WFLAGP(wapp->main_window_desc, start_hidden);
1028 break;
1029 case 1:
1030 flag = WFLAGP(wapp->main_window_desc, no_appicon);
1031 break;
1033 WMSetButtonSelected(panel->appChk[i], flag);
1036 WMSetButtonSelected(panel->alwChk, WFLAGP(wwin, always_user_icon));
1038 showIconFor(WMWidgetScreen(panel->alwChk), panel, wm_instance, wm_class,
1039 REVERT_TO_DEFAULT);
1041 n = wDefaultGetStartWorkspace(wwin->screen_ptr, wm_instance, wm_class);
1043 if (n >= 0 && n < wwin->screen_ptr->workspace_count) {
1044 WMSetPopUpButtonSelectedItem(panel->wsP, n+1);
1045 } else {
1046 WMSetPopUpButtonSelectedItem(panel->wsP, 0);
1051 static void
1052 chooseIconCallback(WMWidget *self, void *clientData)
1054 char *file;
1055 InspectorPanel *panel = (InspectorPanel*)clientData;
1056 int result;
1058 panel->choosingIcon = 1;
1060 WMSetButtonEnabled(panel->browseIconBtn, False);
1062 result = wIconChooserDialog(panel->frame->screen_ptr, &file,
1063 panel->inspected->wm_instance,
1064 panel->inspected->wm_class);
1066 panel->choosingIcon = 0;
1068 if (!panel->destroyed) { /* kluge */
1069 if (result) {
1070 WMSetTextFieldText(panel->fileText, file);
1071 showIconFor(WMWidgetScreen(self), panel, NULL, NULL,
1072 USE_TEXT_FIELD);
1073 free(file);
1075 WMSetButtonEnabled(panel->browseIconBtn, True);
1076 } else {
1077 freeInspector(panel);
1082 static void
1083 textEditedObserver(void *observerData, WMNotification *notification)
1085 InspectorPanel *panel = (InspectorPanel*)observerData;
1087 if ((long)WMGetNotificationClientData(notification) != WMReturnTextMovement)
1088 return;
1090 showIconFor(WMWidgetScreen(panel->win), panel, NULL, NULL,
1091 USE_TEXT_FIELD);
1093 WMPerformButtonClick(panel->updateIconBtn);
1098 static void
1099 selectSpecification(WMWidget *bPtr, void *data)
1101 InspectorPanel *panel = (InspectorPanel*)data;
1102 char *str;
1103 WWindow *wwin = panel->inspected;
1105 if (bPtr == panel->defaultRb) {
1106 WMSetButtonEnabled(panel->applyBtn, False);
1107 } else {
1108 WMSetButtonEnabled(panel->applyBtn, True);
1111 str = wmalloc(16 + strlen(wwin->wm_instance ? wwin->wm_instance : "?")
1112 + strlen(wwin->wm_class ? wwin->wm_class : "?"));
1114 sprintf(str, "Inspecting %s.%s",
1115 wwin->wm_instance ? wwin->wm_instance : "?",
1116 wwin->wm_class ? wwin->wm_class : "?");
1118 wFrameWindowChangeTitle(panel->frame->frame, str);
1120 free(str);
1126 #define SPEC_TEXT "The configuration will apply to all\n"\
1127 "windows that have their WM_CLASS property"\
1128 " set to the above selected\nname, when saved."
1131 #define SELEC_TEXT "Click in the window you wish to inspect."
1135 static void
1136 selectWindow(WMWidget *bPtr, void *data)
1138 InspectorPanel *panel = (InspectorPanel*)data;
1139 WWindow *wwin = panel->inspected;
1140 WScreen *scr = wwin->screen_ptr;
1141 XEvent event;
1142 WWindow *iwin;
1144 if (XGrabPointer(dpy, scr->root_win, True,
1145 ButtonPressMask, GrabModeAsync, GrabModeAsync, None,
1146 wCursor[WCUR_SELECT], CurrentTime)!=GrabSuccess) {
1147 wwarning("could not grab mouse pointer");
1148 return;
1151 WMSetLabelText(panel->specLbl, _(SELEC_TEXT));
1153 WMMaskEvent(dpy, ButtonPressMask, &event);
1155 XUngrabPointer(dpy, CurrentTime);
1157 iwin = wWindowFor(event.xbutton.subwindow);
1159 if (iwin && !iwin->flags.internal_window && iwin != wwin
1160 && !iwin->flags.inspector_open) {
1162 iwin->flags.inspector_open = 1;
1163 iwin->inspector = createInspectorForWindow(iwin,
1164 panel->frame->frame_x,
1165 panel->frame->frame_y,
1166 True);
1167 wCloseInspectorForWindow(wwin);
1168 } else {
1169 WMSetLabelText(panel->specLbl, _(SPEC_TEXT));
1175 static InspectorPanel*
1176 createInspectorForWindow(WWindow *wwin, int xpos, int ypos,
1177 Bool showSelectPanel)
1179 WScreen *scr = wwin->screen_ptr;
1180 InspectorPanel *panel;
1181 Window parent;
1182 int i;
1183 int x, y;
1184 int btn_width, frame_width;
1185 WMButton *selectedBtn = NULL;
1186 #ifdef wrong_behaviour
1187 WMPixmap *pixmap;
1188 #endif
1191 panel = wmalloc(sizeof(InspectorPanel));
1192 memset(panel, 0, sizeof(InspectorPanel));
1194 panel->destroyed = 0;
1197 panel->inspected = wwin;
1199 panel->nextPtr = panelList;
1200 panelList = panel;
1203 panel->win = WMCreateWindow(scr->wmscreen, "windowInspector");
1204 WMResizeWidget(panel->win, PWIDTH, PHEIGHT);
1207 /**** create common stuff ****/
1209 /* command buttons */
1210 /* (PWIDTH - (left and right margin) - (btn interval)) / 3 */
1211 btn_width = (PWIDTH - (2 * 15) - (2 * 10)) / 3;
1212 panel->saveBtn = WMCreateCommandButton(panel->win);
1213 WMSetButtonAction(panel->saveBtn, (WMAction*)saveSettings, panel);
1214 WMMoveWidget(panel->saveBtn, (2 * (btn_width + 10)) + 15, 310);
1215 WMSetButtonText(panel->saveBtn, _("Save"));
1216 WMResizeWidget(panel->saveBtn, btn_width, 28);
1217 if (wPreferences.flags.noupdates || !(wwin->wm_class || wwin->wm_instance))
1218 WMSetButtonEnabled(panel->saveBtn, False);
1220 panel->applyBtn = WMCreateCommandButton(panel->win);
1221 WMSetButtonAction(panel->applyBtn, (WMAction*)applySettings, panel);
1222 WMMoveWidget(panel->applyBtn, btn_width + 10 + 15, 310);
1223 WMSetButtonText(panel->applyBtn, _("Apply"));
1224 WMResizeWidget(panel->applyBtn, btn_width, 28);
1226 panel->revertBtn = WMCreateCommandButton(panel->win);
1227 WMSetButtonAction(panel->revertBtn, (WMAction*)revertSettings, panel);
1228 WMMoveWidget(panel->revertBtn, 15, 310);
1229 WMSetButtonText(panel->revertBtn, _("Reload"));
1230 WMResizeWidget(panel->revertBtn, btn_width, 28);
1232 /* page selection popup button */
1233 panel->pagePopUp = WMCreatePopUpButton(panel->win);
1234 WMSetPopUpButtonAction(panel->pagePopUp, (WMAction*)changePage, panel);
1235 WMMoveWidget(panel->pagePopUp, 25, 15);
1236 WMResizeWidget(panel->pagePopUp, PWIDTH - 50, 20);
1238 WMAddPopUpButtonItem(panel->pagePopUp, _("Window Specification"));
1239 WMAddPopUpButtonItem(panel->pagePopUp, _("Window Attributes"));
1240 WMAddPopUpButtonItem(panel->pagePopUp, _("Advanced Options"));
1241 WMAddPopUpButtonItem(panel->pagePopUp, _("Icon and Initial Workspace"));
1242 WMAddPopUpButtonItem(panel->pagePopUp, _("Application Specific"));
1244 /**** window spec ****/
1245 frame_width = PWIDTH - (2 * 15);
1247 panel->specFrm = WMCreateFrame(panel->win);
1248 WMSetFrameTitle(panel->specFrm, _("Window Specification"));
1249 WMMoveWidget(panel->specFrm, 15, 65);
1250 WMResizeWidget(panel->specFrm, frame_width, 145);
1253 panel->defaultRb = WMCreateRadioButton(panel->specFrm);
1254 WMMoveWidget(panel->defaultRb, 10, 78);
1255 WMResizeWidget(panel->defaultRb, frame_width - (2 * 10), 20);
1256 WMSetButtonText(panel->defaultRb, _("Defaults for all windows"));
1257 WMSetButtonSelected(panel->defaultRb, False);
1258 WMSetButtonAction(panel->defaultRb, selectSpecification, panel);
1260 if (wwin->wm_class && wwin->wm_instance) {
1261 char *str, *tmp;
1263 tmp = wstrappend(wwin->wm_instance, ".");
1264 str = wstrappend(tmp, wwin->wm_class);
1266 panel->bothRb = WMCreateRadioButton(panel->specFrm);
1267 WMMoveWidget(panel->bothRb, 10, 18);
1268 WMResizeWidget(panel->bothRb, frame_width - (2 * 10), 20);
1269 WMSetButtonText(panel->bothRb, str);
1270 free(tmp);
1271 free(str);
1272 WMGroupButtons(panel->defaultRb, panel->bothRb);
1274 if (!selectedBtn)
1275 selectedBtn = panel->bothRb;
1277 WMSetButtonAction(panel->bothRb, selectSpecification, panel);
1280 if (wwin->wm_instance) {
1281 panel->instRb = WMCreateRadioButton(panel->specFrm);
1282 WMMoveWidget(panel->instRb, 10, 38);
1283 WMResizeWidget(panel->instRb, frame_width - (2 * 10), 20);
1284 WMSetButtonText(panel->instRb, wwin->wm_instance);
1285 WMGroupButtons(panel->defaultRb, panel->instRb);
1287 if (!selectedBtn)
1288 selectedBtn = panel->instRb;
1290 WMSetButtonAction(panel->instRb, selectSpecification, panel);
1293 if (wwin->wm_class) {
1294 panel->clsRb = WMCreateRadioButton(panel->specFrm);
1295 WMMoveWidget(panel->clsRb, 10, 58);
1296 WMResizeWidget(panel->clsRb, frame_width - (2 * 10), 20);
1297 WMSetButtonText(panel->clsRb, wwin->wm_class);
1298 WMGroupButtons(panel->defaultRb, panel->clsRb);
1300 if (!selectedBtn)
1301 selectedBtn = panel->clsRb;
1303 WMSetButtonAction(panel->clsRb, selectSpecification, panel);
1306 if (selectedBtn)
1307 WMSetButtonSelected(selectedBtn, True);
1310 panel->selWinB = WMCreateCommandButton(panel->specFrm);
1311 WMMoveWidget(panel->selWinB, 20, 145-24 - 10);
1312 WMResizeWidget(panel->selWinB, frame_width - 2*10 - 20, 24);
1313 WMSetButtonText(panel->selWinB, _("Select Window"));
1314 WMSetButtonAction(panel->selWinB, selectWindow, panel);
1317 panel->specLbl = WMCreateLabel(panel->win);
1318 WMMoveWidget(panel->specLbl, 15, 210);
1319 WMResizeWidget(panel->specLbl, frame_width, 100);
1320 WMSetLabelText(panel->specLbl, _(SPEC_TEXT));
1322 WMSetLabelTextAlignment(panel->specLbl, WACenter);
1324 /**** attributes ****/
1325 panel->attrFrm = WMCreateFrame(panel->win);
1326 WMSetFrameTitle(panel->attrFrm, _("Attributes"));
1327 WMMoveWidget(panel->attrFrm, 15, 45);
1328 WMResizeWidget(panel->attrFrm, frame_width, 250);
1330 for (i=0; i < 11; i++) {
1331 char *caption = NULL;
1332 int flag = 0;
1333 char *descr = NULL;
1335 switch (i) {
1336 case 0:
1337 caption = _("Disable Titlebar");
1338 flag = WFLAGP(wwin, no_titlebar);
1339 descr = _("Remove the titlebar of this window.\n"
1340 "To access the window commands menu of a window\n"
1341 "without it's titlebar, press Control+Esc (or the\n"
1342 "equivalent shortcut, if you changed the default\n"
1343 "settings).");
1344 break;
1345 case 1:
1346 caption = _("Disable Resizebar");
1347 flag = WFLAGP(wwin, no_resizebar);
1348 descr = _("Remove the resizebar of this window.");
1349 break;
1350 case 2:
1351 caption = _("Disable Close Button");
1352 flag = WFLAGP(wwin, no_close_button);
1353 descr = _("Remove the `close window' button of this window.");
1354 break;
1355 case 3:
1356 caption = _("Disable Miniaturize Button");
1357 flag = WFLAGP(wwin, no_miniaturize_button);
1358 descr = _("Remove the `miniaturize window' button of the window.");
1359 break;
1360 case 4:
1361 caption = _("Disable Border");
1362 flag = WFLAGP(wwin, no_border);
1363 descr = _("Remove the 1 pixel black border around the window.");
1364 break;
1365 case 5:
1366 caption = _("Keep on Top / Floating");
1367 flag = WFLAGP(wwin, floating);
1368 descr = _("Keep the window over other windows, not allowing\n"
1369 "them to covert it.");
1370 break;
1371 case 6:
1372 caption = _("Keep at Bottom / Sunken");
1373 flag = WFLAGP(wwin, sunken);
1374 descr = _("Keep the window under all other windows.");
1375 break;
1376 case 7:
1377 caption = _("Omnipresent");
1378 flag = WFLAGP(wwin, omnipresent);
1379 descr = _("Make window occupy all workspaces.");
1380 break;
1381 case 8:
1382 caption = _("Start Miniaturized");
1383 flag = WFLAGP(wwin, start_miniaturized);
1384 descr = _("Make the window be automatically miniaturized when it's\n"
1385 "first shown.");
1386 break;
1387 case 9:
1388 caption = _("Start Maximized");
1389 flag = WFLAGP(wwin, start_maximized!=0);
1390 descr = _("Make the window be automatically maximized when it's\n"
1391 "first shown.");
1392 break;
1393 case 10:
1394 caption = _("Skip Window List");
1395 flag = WFLAGP(wwin, skip_window_list);
1396 descr = _("Do not list the window in the window list menu.");
1397 break;
1399 panel->attrChk[i] = WMCreateSwitchButton(panel->attrFrm);
1400 WMMoveWidget(panel->attrChk[i], 10, 20*(i+1));
1401 WMResizeWidget(panel->attrChk[i], frame_width-15, 20);
1402 WMSetButtonSelected(panel->attrChk[i], flag);
1403 WMSetButtonText(panel->attrChk[i], caption);
1405 WMSetBalloonTextForView(descr, WMWidgetView(panel->attrChk[i]));
1409 /**** more attributes ****/
1410 panel->moreFrm = WMCreateFrame(panel->win);
1411 WMSetFrameTitle(panel->moreFrm, _("Advanced"));
1412 WMMoveWidget(panel->moreFrm, 15, 45);
1413 WMResizeWidget(panel->moreFrm, frame_width, 250);
1415 for (i=0;
1416 #ifdef XKB_BUTTON_HINT
1417 i < 9;
1418 #else
1419 i < 8;
1420 #endif
1421 i++) {
1422 char *caption = NULL;
1423 int flag = 0;
1424 char *descr = NULL;
1426 switch (i) {
1427 case 0:
1428 caption = _("Ignore HideOthers");
1429 flag = WFLAGP(wwin, no_hide_others);
1430 descr = _("Do not hide the window when issuing the\n"
1431 "`HideOthers' command.");
1432 break;
1433 case 1:
1434 caption = _("Don't Bind Keyboard Shortcuts");
1435 flag = WFLAGP(wwin, no_bind_keys);
1436 descr = _("Do not bind keyboard shortcuts from Window Maker\n"
1437 "when this window is focused. This will allow the\n"
1438 "window to receive all key combinations regardless\n"
1439 "of your shortcut configuration.");
1440 break;
1441 case 2:
1442 caption = _("Don't Bind Mouse Clicks");
1443 flag = WFLAGP(wwin, no_bind_mouse);
1444 descr = _("Do not bind mouse actions, such as `Alt'+drag\n"
1445 "in the window (when alt is the modifier you have"
1446 "configured).");
1447 break;
1448 case 3:
1449 caption = _("Keep Inside Screen");
1450 flag = WFLAGP(wwin, dont_move_off);
1451 descr = _("Do not allow the window to move itself completely\n"
1452 "outside the screen. For bug compatibility.\n");
1453 break;
1454 case 4:
1455 caption = _("Don't Let It Take Focus");
1456 flag = WFLAGP(wwin, no_focusable);
1457 descr = _("Do not let the window take keyboard focus when you\n"
1458 "click on it.");
1459 break;
1460 case 5:
1461 caption = _("Don't Save Session");
1462 flag = WFLAGP(wwin, dont_save_session);
1463 descr = _("Do not save the associated application in the\n"
1464 "session's state, so that it won't be restarted\n"
1465 "together with other applications when Window Maker\n"
1466 "starts.");
1467 break;
1468 case 6:
1469 caption = _("Emulate Application Icon");
1470 flag = WFLAGP(wwin, emulate_appicon);
1471 descr = _("Make this window act as an application that provides\n"
1472 "enough information to Window Maker for a dockable\n"
1473 "application icon to be created.");
1474 break;
1475 case 7:
1476 caption = _("Full Screen Maximization");
1477 flag = WFLAGP(wwin, full_maximize);
1478 descr = _("Make the window use the whole screen space when it's\n"
1479 "maximized. The titlebar and resizebar will be moved\n"
1480 "to outside the screen.");
1481 break;
1482 #ifdef XKB_BUTTON_HINT
1483 case 8:
1484 caption = _("Disable Language Button");
1485 flag = WFLAGP(wwin, no_language_button);
1486 descr = _("Remove the `toggle language' button of the window.");
1487 break;
1488 #endif
1490 panel->moreChk[i] = WMCreateSwitchButton(panel->moreFrm);
1491 WMMoveWidget(panel->moreChk[i], 10, 20*(i+1));
1492 WMResizeWidget(panel->moreChk[i], frame_width-15, 20);
1493 WMSetButtonSelected(panel->moreChk[i], flag);
1494 WMSetButtonText(panel->moreChk[i], caption);
1496 WMSetBalloonTextForView(descr, WMWidgetView(panel->moreChk[i]));
1499 /* miniwindow/workspace */
1500 panel->iconFrm = WMCreateFrame(panel->win);
1501 WMMoveWidget(panel->iconFrm, 15, 50);
1502 WMResizeWidget(panel->iconFrm, PWIDTH - (2 * 15), 170);
1503 WMSetFrameTitle(panel->iconFrm, _("Miniwindow Image"));
1505 panel->iconLbl = WMCreateLabel(panel->iconFrm);
1506 WMMoveWidget(panel->iconLbl, PWIDTH - (2 * 15) - 22 - 64, 30);
1507 WMResizeWidget(panel->iconLbl, 64, 64);
1508 WMSetLabelRelief(panel->iconLbl, WRGroove);
1509 WMSetLabelImagePosition(panel->iconLbl, WIPImageOnly);
1511 panel->browseIconBtn = WMCreateCommandButton(panel->iconFrm);
1512 WMSetButtonAction(panel->browseIconBtn, chooseIconCallback, panel);
1513 WMMoveWidget(panel->browseIconBtn, 22, 30);
1514 WMResizeWidget(panel->browseIconBtn, 100, 26);
1515 WMSetButtonText(panel->browseIconBtn, _("Browse..."));
1517 #if 0
1518 panel->updateIconBtn = WMCreateCommandButton(panel->iconFrm);
1519 WMSetButtonAction(panel->updateIconBtn, (WMAction*)updateIcon, panel);
1520 WMMoveWidget(panel->updateIconBtn, 22, 65);
1521 WMResizeWidget(panel->updateIconBtn, 100, 26);
1522 WMSetButtonText(panel->updateIconBtn, _("Update"));
1523 #endif
1524 #ifdef wrong_behaviour
1525 WMSetButtonImagePosition(panel->updateIconBtn, WIPRight);
1526 pixmap = WMGetSystemPixmap(scr->wmscreen, WSIReturnArrow);
1527 WMSetButtonImage(panel->updateIconBtn, pixmap);
1528 WMReleasePixmap(pixmap);
1529 pixmap = WMGetSystemPixmap(scr->wmscreen, WSIHighlightedReturnArrow);
1530 WMSetButtonAltImage(panel->updateIconBtn, pixmap);
1531 WMReleasePixmap(pixmap);
1532 #endif
1534 panel->fileLbl = WMCreateLabel(panel->iconFrm);
1535 WMMoveWidget(panel->fileLbl, 20, 95);
1536 WMResizeWidget(panel->fileLbl, PWIDTH - (2 * 15) - (2 * 20), 14);
1537 WMSetLabelText(panel->fileLbl, _("Icon File Name:"));
1539 panel->fileText = WMCreateTextField(panel->iconFrm);
1540 WMMoveWidget(panel->fileText, 20, 115);
1541 WMResizeWidget(panel->fileText, PWIDTH - (2 * 15) - (2 * 15), 20);
1542 WMSetTextFieldText(panel->fileText, NULL);
1543 WMAddNotificationObserver(textEditedObserver, panel,
1544 WMTextDidEndEditingNotification,
1545 panel->fileText);
1546 panel->alwChk = WMCreateSwitchButton(panel->iconFrm);
1547 WMMoveWidget(panel->alwChk, 20, 140);
1548 WMResizeWidget(panel->alwChk, PWIDTH - (2 * 15) - (2 * 15), 20);
1549 WMSetButtonText(panel->alwChk, _("Ignore client supplied icon"));
1550 WMSetButtonSelected(panel->alwChk, WFLAGP(wwin, always_user_icon));
1553 panel->wsFrm = WMCreateFrame(panel->win);
1554 WMMoveWidget(panel->wsFrm, 15, 225);
1555 WMResizeWidget(panel->wsFrm, PWIDTH - (2 * 15), 70);
1556 WMSetFrameTitle(panel->wsFrm, _("Initial Workspace"));
1558 WMSetBalloonTextForView(_("The workspace to place the window when it's"
1559 "first shown."), WMWidgetView(panel->wsFrm));
1561 panel->wsP = WMCreatePopUpButton(panel->wsFrm);
1562 WMMoveWidget(panel->wsP, 20, 30);
1563 WMResizeWidget(panel->wsP, PWIDTH - (2 * 15) - (2 * 20), 20);
1564 WMAddPopUpButtonItem(panel->wsP, _("Nowhere in particular"));
1565 for (i = 0; i < wwin->screen_ptr->workspace_count; i++) {
1566 WMAddPopUpButtonItem(panel->wsP, scr->workspaces[i]->name);
1569 i = wDefaultGetStartWorkspace(wwin->screen_ptr, wwin->wm_instance,
1570 wwin->wm_class);
1571 if (i >= 0 && i <= wwin->screen_ptr->workspace_count) {
1572 WMSetPopUpButtonSelectedItem(panel->wsP, i + 1);
1573 } else {
1574 WMSetPopUpButtonSelectedItem(panel->wsP, 0);
1577 /* application wide attributes */
1578 if (wwin->main_window != None) {
1579 WApplication *wapp = wApplicationOf(wwin->main_window);
1581 panel->appFrm = WMCreateFrame(panel->win);
1582 WMSetFrameTitle(panel->appFrm, _("Application Wide"));
1583 WMMoveWidget(panel->appFrm, 15, 50);
1584 WMResizeWidget(panel->appFrm, frame_width, 240);
1586 for (i=0; i < 2; i++) {
1587 char *caption = NULL;
1588 int flag = 0;
1589 char *descr = NULL;
1591 switch (i) {
1592 case 0:
1593 caption = _("Start Hidden");
1594 flag = WFLAGP(wapp->main_window_desc, start_hidden);
1595 descr = _("Automatically hide application when it's started.");
1596 break;
1597 case 1:
1598 caption = _("No Application Icon");
1599 flag = WFLAGP(wapp->main_window_desc, no_appicon);
1600 descr = _("Disable the application icon for the application.\n"
1601 "Note that you won't be able to dock it anymore,\n"
1602 "and any icons that are already docked will stop\n"
1603 "working correctly.");
1604 break;
1606 panel->appChk[i] = WMCreateSwitchButton(panel->appFrm);
1607 WMMoveWidget(panel->appChk[i], 10, 20*(i+1));
1608 WMResizeWidget(panel->appChk[i], 205, 20);
1609 WMSetButtonSelected(panel->appChk[i], flag);
1610 WMSetButtonText(panel->appChk[i], caption);
1612 WMSetBalloonTextForView(descr, WMWidgetView(panel->appChk[i]));
1615 if (WFLAGP(wwin, emulate_appicon)) {
1616 WMSetButtonEnabled(panel->appChk[1], False);
1617 WMSetButtonEnabled(panel->moreChk[6], True);
1618 } else {
1619 WMSetButtonEnabled(panel->appChk[1], True);
1620 WMSetButtonEnabled(panel->moreChk[6], False);
1622 } else {
1623 int tmp;
1625 if ((wwin->transient_for!=None && wwin->transient_for!=scr->root_win)
1626 || !wwin->wm_class || !wwin->wm_instance)
1627 tmp = False;
1628 else
1629 tmp = True;
1630 WMSetButtonEnabled(panel->moreChk[6], tmp);
1632 WMSetPopUpButtonItemEnabled(panel->pagePopUp, 4, False);
1633 panel->appFrm = NULL;
1636 /* if the window is a transient, don't let it have a miniaturize
1637 * button */
1638 if (wWindowFor(wwin->transient_for)!=NULL)
1639 WMSetButtonEnabled(panel->attrChk[3], False);
1640 else
1641 WMSetButtonEnabled(panel->attrChk[3], True);
1644 if (!wwin->wm_class && !wwin->wm_instance) {
1645 WMSetPopUpButtonItemEnabled(panel->pagePopUp, 0, False);
1649 WMRealizeWidget(panel->win);
1651 WMMapSubwidgets(panel->win);
1652 WMMapSubwidgets(panel->specFrm);
1653 WMMapSubwidgets(panel->attrFrm);
1654 WMMapSubwidgets(panel->moreFrm);
1655 WMMapSubwidgets(panel->iconFrm);
1656 WMMapSubwidgets(panel->wsFrm);
1657 if (panel->appFrm)
1658 WMMapSubwidgets(panel->appFrm);
1660 if (showSelectPanel) {
1661 WMSetPopUpButtonSelectedItem(panel->pagePopUp, 0);
1662 changePage(panel->pagePopUp, panel);
1663 } else {
1664 WMSetPopUpButtonSelectedItem(panel->pagePopUp, 1);
1665 changePage(panel->pagePopUp, panel);
1669 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, PWIDTH, PHEIGHT,
1670 0, 0, 0);
1671 XSelectInput(dpy, parent, KeyPressMask|KeyReleaseMask);
1672 panel->parent = parent;
1673 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
1675 WMMapWidget(panel->win);
1677 XSetTransientForHint(dpy, parent, wwin->client_win);
1679 if (xpos == UNDEFINED_POS) {
1680 x = wwin->frame_x+wwin->frame->core->width/2;
1681 y = wwin->frame_y+wwin->frame->top_width*2;
1682 if (y + PHEIGHT > scr->scr_height)
1683 y = scr->scr_height - PHEIGHT - 30;
1684 if (x + PWIDTH > scr->scr_width)
1685 x = scr->scr_width - PWIDTH;
1686 } else {
1687 x = xpos;
1688 y = ypos;
1691 panel->frame = wManageInternalWindow(scr, parent, wwin->client_win,
1692 "Inspector", x, y, PWIDTH, PHEIGHT);
1694 if (!selectedBtn)
1695 selectedBtn = panel->defaultRb;
1697 WMSetButtonSelected(selectedBtn, True);
1699 selectSpecification(selectedBtn, panel);
1701 /* kluge to know who should get the key events */
1702 panel->frame->client_leader = WMWidgetXID(panel->win);
1704 WSETUFLAG(panel->frame, no_closable, 0);
1705 WSETUFLAG(panel->frame, no_close_button, 0);
1706 wWindowUpdateButtonImages(panel->frame);
1707 wFrameWindowShowButton(panel->frame->frame, WFF_RIGHT_BUTTON);
1708 panel->frame->frame->on_click_right = destroyInspector;
1710 wWindowMap(panel->frame);
1712 showIconFor(WMWidgetScreen(panel->alwChk), panel, wwin->wm_instance,
1713 wwin->wm_class, UPDATE_TEXT_FIELD);
1715 return panel;
1719 void
1720 wShowInspectorForWindow(WWindow *wwin)
1722 if (wwin->flags.inspector_open)
1723 return;
1725 WMSetBalloonEnabled(wwin->screen_ptr->wmscreen, wPreferences.help_balloon);
1727 make_keys();
1728 wwin->flags.inspector_open = 1;
1729 wwin->inspector = createInspectorForWindow(wwin, UNDEFINED_POS,
1730 UNDEFINED_POS, False);
1736 void
1737 wHideInspectorForWindow(WWindow *wwin)
1739 WWindow *pwin = wwin->inspector->frame;
1741 wWindowUnmap(pwin);
1742 pwin->flags.hidden = 1;
1744 wClientSetState(pwin, IconicState, None);
1749 void
1750 wUnhideInspectorForWindow(WWindow *wwin)
1752 WWindow *pwin = wwin->inspector->frame;
1754 pwin->flags.hidden = 0;
1755 pwin->flags.mapped = 1;
1756 XMapWindow(dpy, pwin->client_win);
1757 XMapWindow(dpy, pwin->frame->core->window);
1758 wClientSetState(pwin, NormalState, None);
1763 WWindow*
1764 wGetWindowOfInspectorForWindow(WWindow *wwin)
1766 if (wwin->inspector) {
1767 assert(wwin->flags.inspector_open != 0);
1769 return wwin->inspector->frame;
1770 } else
1771 return NULL;
1775 void
1776 wCloseInspectorForWindow(WWindow *wwin)
1778 WWindow *pwin = wwin->inspector->frame; /* the inspector window */
1780 (*pwin->frame->on_click_right)(NULL, pwin, NULL);