removed broken optiomized selection frame patch
[wmaker-crm.git] / src / winspector.c
blob4629ab573bab622260805d7c747047ddc6ebdc62
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[10];
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 ANoHideOthers;
140 static proplist_t ANoMouseBindings;
141 static proplist_t ANoKeyBindings;
142 static proplist_t ANoAppIcon;
143 static proplist_t AKeepOnTop;
144 static proplist_t AKeepOnBottom;
145 static proplist_t AOmnipresent;
146 static proplist_t ASkipWindowList;
147 static proplist_t AKeepInsideScreen;
148 static proplist_t AUnfocusable;
149 static proplist_t AAlwaysUserIcon;
150 static proplist_t AStartMiniaturized;
151 static proplist_t AStartMaximized;
152 static proplist_t ADontSaveSession;
153 static proplist_t AEmulateAppIcon;
154 static proplist_t AFullMaximize;
155 #ifdef XKB_BUTTON_HINT
156 static proplist_t ANoLanguageButton;
157 #endif
159 static proplist_t AStartWorkspace;
161 static proplist_t AIcon;
163 /* application wide options */
164 static proplist_t AStartHidden;
167 static proplist_t AnyWindow;
168 static proplist_t EmptyString;
169 static proplist_t Yes, No;
172 #define PWIDTH 270
173 #define PHEIGHT 350
178 static void applySettings(WMButton *button, InspectorPanel *panel);
183 #define UNDEFINED_POS 0xffffff
185 static InspectorPanel *createInspectorForWindow(WWindow *wwin,
186 int xpos, int ypos,
187 Bool showSelectPanel);
191 static void
192 make_keys()
194 if (ANoTitlebar!=NULL)
195 return;
197 AIcon = PLMakeString("Icon");
198 ANoTitlebar = PLMakeString("NoTitlebar");
199 ANoResizebar = PLMakeString("NoResizebar");
200 ANoMiniaturizeButton = PLMakeString("NoMiniaturizeButton");
201 ANoCloseButton = PLMakeString("NoCloseButton");
202 ANoHideOthers = PLMakeString("NoHideOthers");
203 ANoMouseBindings = PLMakeString("NoMouseBindings");
204 ANoKeyBindings = PLMakeString("NoKeyBindings");
205 ANoAppIcon = PLMakeString("NoAppIcon");
206 AKeepOnTop = PLMakeString("KeepOnTop");
207 AKeepOnBottom = PLMakeString("KeepOnBottom");
208 AOmnipresent = PLMakeString("Omnipresent");
209 ASkipWindowList = PLMakeString("SkipWindowList");
210 AKeepInsideScreen = PLMakeString("KeepInsideScreen");
211 AUnfocusable = PLMakeString("Unfocusable");
212 AAlwaysUserIcon = PLMakeString("AlwaysUserIcon");
213 AStartMiniaturized = PLMakeString("StartMiniaturized");
214 AStartMaximized = PLMakeString("StartMaximized");
215 AStartHidden = PLMakeString("StartHidden");
216 ADontSaveSession = PLMakeString("DontSaveSession");
217 AEmulateAppIcon = PLMakeString("EmulateAppIcon");
218 AFullMaximize = PLMakeString("FullMaximize");
219 #ifdef XKB_BUTTON_HINT
220 ANoLanguageButton = PLMakeString("NoLanguageButton");
221 #endif
223 AStartWorkspace = PLMakeString("StartWorkspace");
225 AnyWindow = PLMakeString("*");
226 EmptyString = PLMakeString("");
227 Yes = PLMakeString("Yes");
228 No = PLMakeString("No");
233 static void
234 freeInspector(InspectorPanel *panel)
236 panel->destroyed = 1;
237 if (panel->choosingIcon)
238 return;
240 WMDestroyWidget(panel->win);
242 XDestroyWindow(dpy, panel->parent);
244 free(panel);
248 static void
249 destroyInspector(WCoreWindow *foo, void *data, XEvent *event)
251 InspectorPanel *panel;
252 InspectorPanel *tmp;
254 panel = panelList;
255 while (panel->frame!=data)
256 panel = panel->nextPtr;
258 if (panelList == panel)
259 panelList = panel->nextPtr;
260 else {
261 tmp = panelList;
262 while (tmp->nextPtr!=panel) {
263 tmp = tmp->nextPtr;
265 tmp->nextPtr = panel->nextPtr;
267 panel->inspected->flags.inspector_open = 0;
268 panel->inspected->inspector = NULL;
270 WMRemoveNotificationObserver(panel);
272 wWindowUnmap(panel->frame);
273 wUnmanageWindow(panel->frame, True, False);
275 freeInspector(panel);
280 void
281 wDestroyInspectorPanels()
283 InspectorPanel *panel;
285 while (panelList != NULL) {
286 panel = panelList;
287 panelList = panelList->nextPtr;
288 wUnmanageWindow(panel->frame, False, False);
289 WMDestroyWidget(panel->win);
291 panel->inspected->flags.inspector_open = 0;
292 panel->inspected->inspector = NULL;
294 free(panel);
299 static void
300 changePage(WMPopUpButton *bPtr, InspectorPanel *panel)
302 int page;
304 page = WMGetPopUpButtonSelectedItem(bPtr);
306 if (page == 0) {
307 WMMapWidget(panel->specFrm);
308 WMMapWidget(panel->specLbl);
309 } else if (page == 1) {
310 WMMapWidget(panel->attrFrm);
311 } else if (page == 2) {
312 WMMapWidget(panel->moreFrm);
313 } else if (page == 3) {
314 WMMapWidget(panel->iconFrm);
315 WMMapWidget(panel->wsFrm);
316 } else {
317 WMMapWidget(panel->appFrm);
320 if (page != 0) {
321 WMUnmapWidget(panel->specFrm);
322 WMUnmapWidget(panel->specLbl);
324 if (page != 1)
325 WMUnmapWidget(panel->attrFrm);
326 if (page != 2)
327 WMUnmapWidget(panel->moreFrm);
328 if (page != 3) {
329 WMUnmapWidget(panel->iconFrm);
330 WMUnmapWidget(panel->wsFrm);
332 if (page != 4 && panel->appFrm)
333 WMUnmapWidget(panel->appFrm);
337 #define USE_TEXT_FIELD 1
338 #define UPDATE_TEXT_FIELD 2
339 #define REVERT_TO_DEFAULT 4
342 static int
343 showIconFor(WMScreen *scrPtr, InspectorPanel *panel,
344 char *wm_instance, char *wm_class, int flags)
346 WMPixmap *pixmap = (WMPixmap*) NULL;
347 char *file=NULL, *path=NULL;
348 char *db_icon=NULL;
350 if ((flags & USE_TEXT_FIELD) != 0) {
351 file = WMGetTextFieldText(panel->fileText);
352 if (file && file[0] == 0) {
353 free(file);
354 file = NULL;
356 } else {
357 db_icon = wDefaultGetIconFile(panel->inspected->screen_ptr,
358 wm_instance, wm_class, False);
359 if(db_icon != NULL)
360 file = wstrdup(db_icon);
362 if (db_icon!=NULL && (flags & REVERT_TO_DEFAULT)!=0) {
363 if (file)
364 file = wstrdup(db_icon);
365 flags |= UPDATE_TEXT_FIELD;
368 if ((flags & UPDATE_TEXT_FIELD) != 0) {
369 WMSetTextFieldText(panel->fileText, file);
372 if (file) {
373 path = FindImage(wPreferences.icon_path, file);
375 if (!path) {
376 char *buf;
378 buf = wmalloc(strlen(file)+80);
379 sprintf(buf, _("Could not find icon \"%s\" specified for this window"),
380 file);
381 wMessageDialog(panel->frame->screen_ptr, _("Error"), buf,
382 _("OK"), NULL, NULL);
383 free(buf);
384 free(file);
385 return -1;
388 pixmap = WMCreatePixmapFromFile(scrPtr, path);
389 free(path);
391 if (!pixmap) {
392 char *buf;
394 buf = wmalloc(strlen(file)+80);
395 sprintf(buf, _("Could not open specified icon \"%s\":%s"),
396 file, RMessageForError(RErrorCode));
397 wMessageDialog(panel->frame->screen_ptr, _("Error"), buf,
398 _("OK"), NULL, NULL);
399 free(buf);
400 free(file);
401 return -1;
403 free(file);
406 WMSetLabelImage(panel->iconLbl, pixmap);
407 if (pixmap)
408 WMReleasePixmap(pixmap);
410 return 0;
413 #if 0
414 static void
415 updateIcon(WMButton *button, InspectorPanel *panel)
417 showIconFor(WMWidgetScreen(button), panel, NULL, NULL, USE_TEXT_FIELD);
419 #endif
421 static int
422 getBool(proplist_t value)
424 char *val;
426 if (!PLIsString(value)) {
427 return 0;
429 if (!(val = PLGetString(value))) {
430 return 0;
433 if ((val[1]=='\0' && (val[0]=='y' || val[0]=='Y' || val[0]=='T'
434 || val[0]=='t' || val[0]=='1'))
435 || (strcasecmp(val, "YES")==0 || strcasecmp(val, "TRUE")==0)) {
437 return 1;
438 } else if ((val[1]=='\0'
439 && (val[0]=='n' || val[0]=='N' || val[0]=='F'
440 || val[0]=='f' || val[0]=='0'))
441 || (strcasecmp(val, "NO")==0 || strcasecmp(val, "FALSE")==0)) {
443 return 0;
444 } else {
445 wwarning(_("can't convert \"%s\" to boolean"), val);
446 return 0;
451 #define UPDATE_DEFAULTS 1
452 #define IS_BOOLEAN 2
456 * Will insert the attribute = value; pair in window's list,
457 * if it's different from the defaults.
458 * Defaults means either defaults database, or attributes saved
459 * for the default window "*". This is to let one revert options that are
460 * global because they were saved for all windows ("*").
465 static int
466 insertAttribute(proplist_t dict, proplist_t window, proplist_t attr,
467 proplist_t value, int flags)
469 proplist_t def_win, def_value=NULL;
470 int update = 0;
471 int modified = 0;
473 if (!(flags & UPDATE_DEFAULTS) && dict) {
474 if ((def_win = PLGetDictionaryEntry(dict, AnyWindow)) != NULL) {
475 def_value = PLGetDictionaryEntry(def_win, attr);
479 /* If we could not find defaults in database, fall to hardcoded values.
480 * Also this is true if we save defaults for all windows
482 if (!def_value)
483 def_value = ((flags & IS_BOOLEAN) != 0) ? No : EmptyString;
485 if ((flags & IS_BOOLEAN))
486 update = (getBool(value) != getBool(def_value));
487 else {
488 update = !PLIsEqual(value, def_value);
491 if (update) {
492 PLInsertDictionaryEntry(window, attr, value);
493 modified = 1;
496 return modified;
500 static void
501 saveSettings(WMButton *button, InspectorPanel *panel)
503 WWindow *wwin = panel->inspected;
504 WDDomain *db = WDWindowAttributes;
505 proplist_t dict = db->dictionary;
506 proplist_t winDic, value, key;
507 char *icon_file;
508 int flags = 0;
509 int different = 0;
511 /* Save will apply the changes and save them */
512 applySettings(panel->applyBtn, panel);
514 if (WMGetButtonSelected(panel->instRb) != 0)
515 key = PLMakeString(wwin->wm_instance);
516 else if (WMGetButtonSelected(panel->clsRb) != 0)
517 key = PLMakeString(wwin->wm_class);
518 else if (WMGetButtonSelected(panel->bothRb) != 0) {
519 char *buffer;
521 buffer = wmalloc(strlen(wwin->wm_instance)+strlen(wwin->wm_class)+4);
522 strcat(strcat(strcpy(buffer, wwin->wm_instance), "."), wwin->wm_class);
523 key = PLMakeString(buffer);
524 free(buffer);
525 } else if (WMGetButtonSelected(panel->defaultRb) != 0) {
526 key = PLRetain(AnyWindow);
527 flags = UPDATE_DEFAULTS;
528 } else
529 key = NULL;
531 if (!key)
532 return;
534 if (!dict) {
535 dict = PLMakeDictionaryFromEntries(NULL, NULL, NULL);
536 if (dict) {
537 db->dictionary = dict;
538 value = PLMakeString(db->path);
539 PLSetFilename(dict, value);
540 PLRelease(value);
542 else {
543 PLRelease(key);
544 return;
548 if (showIconFor(WMWidgetScreen(button), panel, NULL, NULL,
549 USE_TEXT_FIELD) < 0)
550 return;
552 PLSetStringCmpHook(NULL);
554 winDic = PLMakeDictionaryFromEntries(NULL, NULL, NULL);
556 /* Update icon for window */
557 icon_file = WMGetTextFieldText(panel->fileText);
558 if (icon_file) {
559 if (icon_file[0] != 0) {
560 value = PLMakeString(icon_file);
561 different |= insertAttribute(dict, winDic, AIcon, value, flags);
562 PLRelease(value);
564 free(icon_file);
568 int i = WMGetPopUpButtonSelectedItem(panel->wsP);
570 i--;
572 if (i>=0 && i < panel->frame->screen_ptr->workspace_count) {
573 value = PLMakeString(panel->frame->screen_ptr->workspaces[i]->name);
574 different |= insertAttribute(dict, winDic, AStartWorkspace, value,
575 flags);
576 PLRelease(value);
580 flags |= IS_BOOLEAN;
582 value = (WMGetButtonSelected(panel->alwChk)!=0) ? Yes : No;
583 different |= insertAttribute(dict, winDic, AAlwaysUserIcon, value, flags);
585 value = (WMGetButtonSelected(panel->attrChk[0])!=0) ? Yes : No;
586 different |= insertAttribute(dict, winDic, ANoTitlebar, value, flags);
588 value = (WMGetButtonSelected(panel->attrChk[1])!=0) ? Yes : No;
589 different |= insertAttribute(dict, winDic, ANoResizebar, value, flags);
591 value = (WMGetButtonSelected(panel->attrChk[2])!=0) ? Yes : No;
592 different |= insertAttribute(dict, winDic, ANoCloseButton, value, flags);
594 value = (WMGetButtonSelected(panel->attrChk[3])!=0) ? Yes : No;
595 different |= insertAttribute(dict, winDic, ANoMiniaturizeButton, value, flags);
597 value = (WMGetButtonSelected(panel->attrChk[4])!=0) ? Yes : No;
598 different |= insertAttribute(dict, winDic, AKeepOnTop, value, flags);
600 value = (WMGetButtonSelected(panel->attrChk[5])!=0) ? Yes : No;
601 different |= insertAttribute(dict, winDic, AKeepOnBottom, value, flags);
603 value = (WMGetButtonSelected(panel->attrChk[6])!=0) ? Yes : No;
604 different |= insertAttribute(dict, winDic, AOmnipresent, value, flags);
606 value = (WMGetButtonSelected(panel->attrChk[7])!=0) ? Yes : No;
607 different |= insertAttribute(dict, winDic, AStartMiniaturized, value, flags);
609 value = (WMGetButtonSelected(panel->attrChk[8])!=0) ? Yes : No;
610 different |= insertAttribute(dict, winDic, AStartMaximized, value, flags);
612 value = (WMGetButtonSelected(panel->attrChk[9])!=0) ? Yes : No;
613 different |= insertAttribute(dict, winDic, ASkipWindowList, value, flags);
616 value = (WMGetButtonSelected(panel->moreChk[0])!=0) ? Yes : No;
617 different |= insertAttribute(dict, winDic, ANoHideOthers, value, flags);
619 value = (WMGetButtonSelected(panel->moreChk[1])!=0) ? Yes : No;
620 different |= insertAttribute(dict, winDic, ANoKeyBindings, value, flags);
622 value = (WMGetButtonSelected(panel->moreChk[2])!=0) ? Yes : No;
623 different |= insertAttribute(dict, winDic, ANoMouseBindings, value, flags);
625 value = (WMGetButtonSelected(panel->moreChk[3])!=0) ? Yes : No;
626 different |= insertAttribute(dict, winDic, AKeepInsideScreen,value, flags);
628 value = (WMGetButtonSelected(panel->moreChk[4])!=0) ? Yes : No;
629 different |= insertAttribute(dict, winDic, AUnfocusable, value, flags);
631 value = (WMGetButtonSelected(panel->moreChk[5])!=0) ? Yes : No;
632 different |= insertAttribute(dict, winDic, ADontSaveSession, value, flags);
634 value = (WMGetButtonSelected(panel->moreChk[6])!=0) ? Yes : No;
635 different |= insertAttribute(dict, winDic, AEmulateAppIcon, value, flags);
637 value = (WMGetButtonSelected(panel->moreChk[7])!=0) ? Yes : No;
638 different |= insertAttribute(dict, winDic, AFullMaximize, value, flags);
640 #ifdef XKB_BUTTON_HINT
641 value = (WMGetButtonSelected(panel->moreChk[8])!=0) ? Yes : No;
642 different |= insertAttribute(dict, winDic, ANoLanguageButton, value, flags);
643 #endif
645 /* application wide settings for when */
646 /* the window is the leader, save the attribute with the others */
647 if (panel->inspected->main_window == panel->inspected->client_win) {
649 value = (WMGetButtonSelected(panel->appChk[0])!=0) ? Yes : No;
650 different |= insertAttribute(dict, winDic, AStartHidden, value, flags);
652 value = (WMGetButtonSelected(panel->appChk[1])!=0) ? Yes : No;
653 different |= insertAttribute(dict, winDic, ANoAppIcon, value, flags);
656 PLRemoveDictionaryEntry(dict, key);
657 if (different) {
658 PLInsertDictionaryEntry(dict, key, winDic);
661 PLRelease(key);
662 PLRelease(winDic);
664 different = 0;
666 /* application wide settings */
667 if (panel->inspected->main_window != panel->inspected->client_win
668 && !(flags & UPDATE_DEFAULTS)) {
669 WApplication *wapp;
670 proplist_t appDic;
672 wapp = wApplicationOf(panel->inspected->main_window);
673 if (wapp) {
674 char *iconFile;
675 char *buffer;
677 appDic = PLMakeDictionaryFromEntries(NULL, NULL, NULL);
679 assert(wapp->main_window_desc->wm_instance!=NULL);
680 assert(wapp->main_window_desc->wm_class!=NULL);
682 buffer = wmalloc(strlen(wapp->main_window_desc->wm_instance)
683 +strlen(wapp->main_window_desc->wm_class)+4);
684 strcat(strcpy(buffer, wapp->main_window_desc->wm_instance), ".");
685 strcat(buffer, wapp->main_window_desc->wm_class);
686 key = PLMakeString(buffer);
687 free(buffer);
689 iconFile = wDefaultGetIconFile(wwin->screen_ptr,
690 wapp->main_window_desc->wm_instance,
691 wapp->main_window_desc->wm_class,
692 False);
694 if (iconFile && iconFile[0]!=0) {
695 value = PLMakeString(iconFile);
696 different |= insertAttribute(dict, appDic, AIcon, value,
697 flags&~IS_BOOLEAN);
698 PLRelease(value);
701 value = (WMGetButtonSelected(panel->appChk[0])!=0) ? Yes : No;
702 different |= insertAttribute(dict, appDic, AStartHidden, value,
703 flags);
705 value = (WMGetButtonSelected(panel->appChk[1])!=0) ? Yes : No;
706 different |= insertAttribute(dict, appDic, ANoAppIcon, value,
707 flags);
709 PLRemoveDictionaryEntry(dict, key);
710 if (different) {
711 PLInsertDictionaryEntry(dict, key, appDic);
713 PLRelease(key);
714 PLRelease(appDic);
718 PLSave(dict, YES);
720 /* clean up */
721 PLSetStringCmpHook(StringCompareHook);
725 static void
726 makeAppIconFor(WApplication *wapp)
728 WScreen *scr = wapp->main_window_desc->screen_ptr;
730 if (wapp->app_icon)
731 return;
733 if (!WFLAGP(wapp->main_window_desc, no_appicon))
734 wapp->app_icon = wAppIconCreate(wapp->main_window_desc);
735 else
736 wapp->app_icon = NULL;
738 if (wapp->app_icon) {
739 WIcon *icon = wapp->app_icon->icon;
740 WDock *clip = scr->workspaces[scr->current_workspace]->clip;
741 int x=0, y=0;
743 wapp->app_icon->main_window = wapp->main_window;
745 if (clip && clip->attract_icons && wDockFindFreeSlot(clip, &x, &y)) {
746 wapp->app_icon->attracted = 1;
747 if (!wapp->app_icon->icon->shadowed) {
748 wapp->app_icon->icon->shadowed = 1;
749 wapp->app_icon->icon->force_paint = 1;
751 wDockAttachIcon(clip, wapp->app_icon, x, y);
752 } else {
753 PlaceIcon(scr, &x, &y);
754 wAppIconMove(wapp->app_icon, x, y);
756 if (!clip || !wapp->app_icon->attracted || !clip->collapsed)
757 XMapWindow(dpy, icon->core->window);
759 if (wPreferences.auto_arrange_icons && !wapp->app_icon->attracted)
760 wArrangeIcons(wapp->main_window_desc->screen_ptr, True);
765 static void
766 removeAppIconFor(WApplication *wapp)
768 if (!wapp->app_icon)
769 return;
771 if (wapp->app_icon->docked && !wapp->app_icon->attracted) {
772 wapp->app_icon->running = 0;
773 /* since we keep it, we don't care if it was attracted or not */
774 wapp->app_icon->attracted = 0;
775 wapp->app_icon->icon->shadowed = 0;
776 wapp->app_icon->main_window = None;
777 wapp->app_icon->pid = 0;
778 wapp->app_icon->icon->owner = NULL;
779 wapp->app_icon->icon->icon_win = None;
780 wapp->app_icon->icon->force_paint = 1;
781 wAppIconPaint(wapp->app_icon);
782 } else if (wapp->app_icon->docked) {
783 wapp->app_icon->running = 0;
784 wDockDetach(wapp->app_icon->dock, wapp->app_icon);
785 } else {
786 wAppIconDestroy(wapp->app_icon);
788 wapp->app_icon = NULL;
789 if (wPreferences.auto_arrange_icons)
790 wArrangeIcons(wapp->main_window_desc->screen_ptr, True);
794 static void
795 applySettings(WMButton *button, InspectorPanel *panel)
797 WWindow *wwin = panel->inspected;
798 WApplication *wapp = wApplicationOf(wwin->main_window);
799 int floating, sunken, skip_window_list;
800 int old_omnipresent;
801 int old_no_bind_keys;
802 int old_no_bind_mouse;
804 old_omnipresent = WFLAGP(wwin, omnipresent);
805 old_no_bind_keys = WFLAGP(wwin, no_bind_keys);
806 old_no_bind_mouse = WFLAGP(wwin, no_bind_mouse);
808 showIconFor(WMWidgetScreen(button), panel, NULL, NULL, USE_TEXT_FIELD);
810 WSETUFLAG(wwin, no_titlebar, WMGetButtonSelected(panel->attrChk[0]));
811 WSETUFLAG(wwin, no_resizebar, WMGetButtonSelected(panel->attrChk[1]));
812 WSETUFLAG(wwin, no_close_button, WMGetButtonSelected(panel->attrChk[2]));
813 WSETUFLAG(wwin, no_miniaturize_button, WMGetButtonSelected(panel->attrChk[3]));
814 floating = WMGetButtonSelected(panel->attrChk[4]);
815 sunken = WMGetButtonSelected(panel->attrChk[5]);
816 WSETUFLAG(wwin, omnipresent, WMGetButtonSelected(panel->attrChk[6]));
817 WSETUFLAG(wwin, start_miniaturized, WMGetButtonSelected(panel->attrChk[7]));
818 WSETUFLAG(wwin, start_maximized, WMGetButtonSelected(panel->attrChk[8]));
819 skip_window_list = WMGetButtonSelected(panel->attrChk[9]);
821 WSETUFLAG(wwin, no_hide_others, WMGetButtonSelected(panel->moreChk[0]));
822 WSETUFLAG(wwin, no_bind_keys, WMGetButtonSelected(panel->moreChk[1]));
823 WSETUFLAG(wwin, no_bind_mouse, WMGetButtonSelected(panel->moreChk[2]));
824 WSETUFLAG(wwin, dont_move_off, WMGetButtonSelected(panel->moreChk[3]));
825 WSETUFLAG(wwin, no_focusable, WMGetButtonSelected(panel->moreChk[4]));
826 WSETUFLAG(wwin, dont_save_session, WMGetButtonSelected(panel->moreChk[5]));
827 WSETUFLAG(wwin, emulate_appicon, WMGetButtonSelected(panel->moreChk[6]));
828 WSETUFLAG(wwin, full_maximize, WMGetButtonSelected(panel->moreChk[7]));
829 #ifdef XKB_BUTTON_HINT
830 WSETUFLAG(wwin, no_language_button, WMGetButtonSelected(panel->moreChk[8]));
831 #endif
832 WSETUFLAG(wwin, always_user_icon, WMGetButtonSelected(panel->alwChk));
834 if (WFLAGP(wwin, no_titlebar) && wwin->flags.shaded)
835 wUnshadeWindow(wwin);
837 WSETUFLAG(wwin, no_shadeable, WFLAGP(wwin, no_titlebar));
839 if (floating) {
840 if (!WFLAGP(wwin, floating))
841 ChangeStackingLevel(wwin->frame->core, WMFloatingLevel);
842 } else if (sunken) {
843 if (!WFLAGP(wwin, sunken))
844 ChangeStackingLevel(wwin->frame->core, WMSunkenLevel);
845 } else {
846 if (WFLAGP(wwin, floating) || WFLAGP(wwin, sunken))
847 ChangeStackingLevel(wwin->frame->core, WMNormalLevel);
850 WSETUFLAG(wwin, sunken, sunken);
851 WSETUFLAG(wwin, floating, floating);
852 wwin->flags.omnipresent = 0;
854 if (WFLAGP(wwin, skip_window_list) != skip_window_list) {
855 WSETUFLAG(wwin, skip_window_list, skip_window_list);
856 UpdateSwitchMenu(wwin->screen_ptr, wwin,
857 skip_window_list ? ACTION_REMOVE : ACTION_ADD);
858 } else {
859 if (WFLAGP(wwin, omnipresent) != old_omnipresent) {
860 UpdateSwitchMenu(wwin->screen_ptr, wwin, ACTION_CHANGE_WORKSPACE);
864 if (WFLAGP(wwin, no_bind_keys) != old_no_bind_keys) {
865 if (WFLAGP(wwin, no_bind_keys)) {
866 XUngrabKey(dpy, AnyKey, AnyModifier, wwin->frame->core->window);
867 } else {
868 wWindowSetKeyGrabs(wwin);
872 if (WFLAGP(wwin, no_bind_mouse) != old_no_bind_mouse) {
873 wWindowResetMouseGrabs(wwin);
876 wwin->frame->flags.need_texture_change = 1;
877 wWindowConfigureBorders(wwin);
878 wFrameWindowPaint(wwin->frame);
881 * Can't apply emulate_appicon because it will probably cause problems.
884 if (wapp) {
885 /* do application wide stuff */
886 WSETUFLAG(wapp->main_window_desc, start_hidden,
887 WMGetButtonSelected(panel->appChk[0]));
889 WSETUFLAG(wapp->main_window_desc, no_appicon,
890 WMGetButtonSelected(panel->appChk[1]));
892 if (WFLAGP(wapp->main_window_desc, no_appicon))
893 removeAppIconFor(wapp);
894 else
895 makeAppIconFor(wapp);
897 if (wapp->app_icon && wapp->main_window == wwin->client_win) {
898 char *file = WMGetTextFieldText(panel->fileText);
900 if (file[0] == 0) {
901 free(file);
902 file = NULL;
904 wIconChangeImageFile(wapp->app_icon->icon, file);
905 if (file)
906 free(file);
907 wAppIconPaint(wapp->app_icon);
915 static void
916 revertSettings(WMButton *button, InspectorPanel *panel)
918 WWindow *wwin = panel->inspected;
919 WApplication *wapp = wApplicationOf(wwin->main_window);
920 int i, n;
921 char *wm_instance = NULL;
922 char *wm_class = NULL;
923 int workspace, level;
925 if (panel->instRb && WMGetButtonSelected(panel->instRb) != 0)
926 wm_instance = wwin->wm_instance;
927 else if (panel->clsRb && WMGetButtonSelected(panel->clsRb) != 0)
928 wm_class = wwin->wm_class;
929 else if (panel->bothRb && WMGetButtonSelected(panel->bothRb) != 0) {
930 wm_instance = wwin->wm_instance;
931 wm_class = wwin->wm_class;
933 memset(&wwin->defined_user_flags, 0, sizeof(WWindowAttributes));
934 memset(&wwin->user_flags, 0, sizeof(WWindowAttributes));
935 memset(&wwin->client_flags, 0, sizeof(WWindowAttributes));
937 wWindowSetupInitialAttributes(wwin, &level, &workspace);
939 for (i=0; i < 10; i++) {
940 int flag = 0;
942 switch (i) {
943 case 0:
944 flag = WFLAGP(wwin, no_titlebar);
945 break;
946 case 1:
947 flag = WFLAGP(wwin, no_resizebar);
948 break;
949 case 2:
950 flag = WFLAGP(wwin, no_close_button);
951 break;
952 case 3:
953 flag = WFLAGP(wwin, no_miniaturize_button);
954 break;
955 case 4:
956 flag = WFLAGP(wwin, floating);
957 break;
958 case 5:
959 flag = WFLAGP(wwin, sunken);
960 break;
961 case 6:
962 flag = WFLAGP(wwin, omnipresent);
963 break;
964 case 7:
965 flag = WFLAGP(wwin, start_miniaturized);
966 break;
967 case 8:
968 flag = WFLAGP(wwin, start_maximized!=0);
969 break;
970 case 9:
971 flag = WFLAGP(wwin, skip_window_list);
972 break;
974 WMSetButtonSelected(panel->attrChk[i], flag);
976 for (i=0; i < 8; i++) {
977 int flag = 0;
979 switch (i) {
980 case 0:
981 flag = WFLAGP(wwin, no_hide_others);
982 break;
983 case 1:
984 flag = WFLAGP(wwin, no_bind_keys);
985 break;
986 case 2:
987 flag = WFLAGP(wwin, no_bind_mouse);
988 break;
989 case 3:
990 flag = WFLAGP(wwin, dont_move_off);
991 break;
992 case 4:
993 flag = WFLAGP(wwin, no_focusable);
994 break;
995 case 5:
996 flag = WFLAGP(wwin, dont_save_session);
997 break;
998 case 6:
999 flag = WFLAGP(wwin, emulate_appicon);
1000 break;
1001 case 7:
1002 flag = WFLAGP(wwin, full_maximize);
1003 break;
1004 #ifdef XKB_BUTTON_HINT
1005 case 8:
1006 flag = WFLAGP(wwin, no_language_button);
1007 break;
1008 #endif
1010 WMSetButtonSelected(panel->moreChk[i], flag);
1012 if (panel->appFrm && wapp) {
1013 for (i=0; i < 2; i++) {
1014 int flag = 0;
1016 switch (i) {
1017 case 0:
1018 flag = WFLAGP(wapp->main_window_desc, start_hidden);
1019 break;
1020 case 1:
1021 flag = WFLAGP(wapp->main_window_desc, no_appicon);
1022 break;
1024 WMSetButtonSelected(panel->appChk[i], flag);
1027 WMSetButtonSelected(panel->alwChk, WFLAGP(wwin, always_user_icon));
1029 showIconFor(WMWidgetScreen(panel->alwChk), panel, wm_instance, wm_class,
1030 REVERT_TO_DEFAULT);
1032 n = wDefaultGetStartWorkspace(wwin->screen_ptr, wm_instance, wm_class);
1034 if (n >= 0 && n < wwin->screen_ptr->workspace_count) {
1035 WMSetPopUpButtonSelectedItem(panel->wsP, n+1);
1036 } else {
1037 WMSetPopUpButtonSelectedItem(panel->wsP, 0);
1042 static void
1043 chooseIconCallback(WMWidget *self, void *clientData)
1045 char *file;
1046 InspectorPanel *panel = (InspectorPanel*)clientData;
1047 int result;
1049 panel->choosingIcon = 1;
1051 WMSetButtonEnabled(panel->browseIconBtn, False);
1053 result = wIconChooserDialog(panel->frame->screen_ptr, &file,
1054 panel->inspected->wm_instance,
1055 panel->inspected->wm_class);
1057 panel->choosingIcon = 0;
1059 if (!panel->destroyed) { /* kluge */
1060 if (result) {
1061 WMSetTextFieldText(panel->fileText, file);
1062 showIconFor(WMWidgetScreen(self), panel, NULL, NULL,
1063 USE_TEXT_FIELD);
1064 free(file);
1066 WMSetButtonEnabled(panel->browseIconBtn, True);
1067 } else {
1068 freeInspector(panel);
1073 static void
1074 textEditedObserver(void *observerData, WMNotification *notification)
1076 InspectorPanel *panel = (InspectorPanel*)observerData;
1078 if ((long)WMGetNotificationClientData(notification) != WMReturnTextMovement)
1079 return;
1081 showIconFor(WMWidgetScreen(panel->win), panel, NULL, NULL,
1082 USE_TEXT_FIELD);
1084 WMPerformButtonClick(panel->updateIconBtn);
1089 static void
1090 selectSpecification(WMWidget *bPtr, void *data)
1092 InspectorPanel *panel = (InspectorPanel*)data;
1093 char *str;
1094 WWindow *wwin = panel->inspected;
1096 if (bPtr == panel->defaultRb) {
1097 WMSetButtonEnabled(panel->applyBtn, False);
1098 } else {
1099 WMSetButtonEnabled(panel->applyBtn, True);
1102 str = wmalloc(16 + strlen(wwin->wm_instance ? wwin->wm_instance : "?")
1103 + strlen(wwin->wm_class ? wwin->wm_class : "?"));
1105 sprintf(str, "Inspecting %s.%s",
1106 wwin->wm_instance ? wwin->wm_instance : "?",
1107 wwin->wm_class ? wwin->wm_class : "?");
1109 wFrameWindowChangeTitle(panel->frame->frame, str);
1111 free(str);
1117 #define SPEC_TEXT "The configuration will apply to all\n"\
1118 "windows that have their WM_CLASS property"\
1119 " set to the above selected\nname, when saved."
1122 #define SELEC_TEXT "Click in the window you wish to inspect."
1126 static void
1127 selectWindow(WMWidget *bPtr, void *data)
1129 InspectorPanel *panel = (InspectorPanel*)data;
1130 WWindow *wwin = panel->inspected;
1131 WScreen *scr = wwin->screen_ptr;
1132 XEvent event;
1133 WWindow *iwin;
1135 if (XGrabPointer(dpy, scr->root_win, True,
1136 ButtonPressMask, GrabModeAsync, GrabModeAsync, None,
1137 wCursor[WCUR_SELECT], CurrentTime)!=GrabSuccess) {
1138 wwarning("could not grab mouse pointer");
1139 return;
1142 WMSetLabelText(panel->specLbl, _(SELEC_TEXT));
1144 WMMaskEvent(dpy, ButtonPressMask, &event);
1146 XUngrabPointer(dpy, CurrentTime);
1148 iwin = wWindowFor(event.xbutton.subwindow);
1150 if (iwin && !iwin->flags.internal_window && iwin != wwin
1151 && !iwin->flags.inspector_open) {
1153 iwin->flags.inspector_open = 1;
1154 iwin->inspector = createInspectorForWindow(iwin,
1155 panel->frame->frame_x,
1156 panel->frame->frame_y,
1157 True);
1158 wCloseInspectorForWindow(wwin);
1159 } else {
1160 WMSetLabelText(panel->specLbl, _(SPEC_TEXT));
1166 static InspectorPanel*
1167 createInspectorForWindow(WWindow *wwin, int xpos, int ypos,
1168 Bool showSelectPanel)
1170 WScreen *scr = wwin->screen_ptr;
1171 InspectorPanel *panel;
1172 Window parent;
1173 int i;
1174 int x, y;
1175 int btn_width, frame_width;
1176 WMButton *selectedBtn = NULL;
1177 #ifdef wrong_behaviour
1178 WMPixmap *pixmap;
1179 #endif
1182 panel = wmalloc(sizeof(InspectorPanel));
1183 memset(panel, 0, sizeof(InspectorPanel));
1185 panel->destroyed = 0;
1188 panel->inspected = wwin;
1190 panel->nextPtr = panelList;
1191 panelList = panel;
1194 panel->win = WMCreateWindow(scr->wmscreen, "windowInspector");
1195 WMResizeWidget(panel->win, PWIDTH, PHEIGHT);
1198 /**** create common stuff ****/
1200 /* command buttons */
1201 /* (PWIDTH - (left and right margin) - (btn interval)) / 3 */
1202 btn_width = (PWIDTH - (2 * 15) - (2 * 10)) / 3;
1203 panel->saveBtn = WMCreateCommandButton(panel->win);
1204 WMSetButtonAction(panel->saveBtn, (WMAction*)saveSettings, panel);
1205 WMMoveWidget(panel->saveBtn, (2 * (btn_width + 10)) + 15, 310);
1206 WMSetButtonText(panel->saveBtn, _("Save"));
1207 WMResizeWidget(panel->saveBtn, btn_width, 28);
1208 if (wPreferences.flags.noupdates || !(wwin->wm_class || wwin->wm_instance))
1209 WMSetButtonEnabled(panel->saveBtn, False);
1211 panel->applyBtn = WMCreateCommandButton(panel->win);
1212 WMSetButtonAction(panel->applyBtn, (WMAction*)applySettings, panel);
1213 WMMoveWidget(panel->applyBtn, btn_width + 10 + 15, 310);
1214 WMSetButtonText(panel->applyBtn, _("Apply"));
1215 WMResizeWidget(panel->applyBtn, btn_width, 28);
1217 panel->revertBtn = WMCreateCommandButton(panel->win);
1218 WMSetButtonAction(panel->revertBtn, (WMAction*)revertSettings, panel);
1219 WMMoveWidget(panel->revertBtn, 15, 310);
1220 WMSetButtonText(panel->revertBtn, _("Reload"));
1221 WMResizeWidget(panel->revertBtn, btn_width, 28);
1223 /* page selection popup button */
1224 panel->pagePopUp = WMCreatePopUpButton(panel->win);
1225 WMSetPopUpButtonAction(panel->pagePopUp, (WMAction*)changePage, panel);
1226 WMMoveWidget(panel->pagePopUp, 25, 15);
1227 WMResizeWidget(panel->pagePopUp, PWIDTH - 50, 20);
1229 WMAddPopUpButtonItem(panel->pagePopUp, _("Window Specification"));
1230 WMAddPopUpButtonItem(panel->pagePopUp, _("Window Attributes"));
1231 WMAddPopUpButtonItem(panel->pagePopUp, _("Advanced Options"));
1232 WMAddPopUpButtonItem(panel->pagePopUp, _("Icon and Initial Workspace"));
1233 WMAddPopUpButtonItem(panel->pagePopUp, _("Application Specific"));
1235 /**** window spec ****/
1236 frame_width = PWIDTH - (2 * 15);
1238 panel->specFrm = WMCreateFrame(panel->win);
1239 WMSetFrameTitle(panel->specFrm, _("Window Specification"));
1240 WMMoveWidget(panel->specFrm, 15, 65);
1241 WMResizeWidget(panel->specFrm, frame_width, 145);
1244 panel->defaultRb = WMCreateRadioButton(panel->specFrm);
1245 WMMoveWidget(panel->defaultRb, 10, 78);
1246 WMResizeWidget(panel->defaultRb, frame_width - (2 * 10), 20);
1247 WMSetButtonText(panel->defaultRb, _("Defaults for all windows"));
1248 WMSetButtonSelected(panel->defaultRb, False);
1249 WMSetButtonAction(panel->defaultRb, selectSpecification, panel);
1251 if (wwin->wm_class && wwin->wm_instance) {
1252 char *str, *tmp;
1254 tmp = wstrappend(wwin->wm_instance, ".");
1255 str = wstrappend(tmp, wwin->wm_class);
1257 panel->bothRb = WMCreateRadioButton(panel->specFrm);
1258 WMMoveWidget(panel->bothRb, 10, 18);
1259 WMResizeWidget(panel->bothRb, frame_width - (2 * 10), 20);
1260 WMSetButtonText(panel->bothRb, str);
1261 free(tmp);
1262 free(str);
1263 WMGroupButtons(panel->defaultRb, panel->bothRb);
1265 if (!selectedBtn)
1266 selectedBtn = panel->bothRb;
1268 WMSetButtonAction(panel->bothRb, selectSpecification, panel);
1271 if (wwin->wm_instance) {
1272 panel->instRb = WMCreateRadioButton(panel->specFrm);
1273 WMMoveWidget(panel->instRb, 10, 38);
1274 WMResizeWidget(panel->instRb, frame_width - (2 * 10), 20);
1275 WMSetButtonText(panel->instRb, wwin->wm_instance);
1276 WMGroupButtons(panel->defaultRb, panel->instRb);
1278 if (!selectedBtn)
1279 selectedBtn = panel->instRb;
1281 WMSetButtonAction(panel->instRb, selectSpecification, panel);
1284 if (wwin->wm_class) {
1285 panel->clsRb = WMCreateRadioButton(panel->specFrm);
1286 WMMoveWidget(panel->clsRb, 10, 58);
1287 WMResizeWidget(panel->clsRb, frame_width - (2 * 10), 20);
1288 WMSetButtonText(panel->clsRb, wwin->wm_class);
1289 WMGroupButtons(panel->defaultRb, panel->clsRb);
1291 if (!selectedBtn)
1292 selectedBtn = panel->clsRb;
1294 WMSetButtonAction(panel->clsRb, selectSpecification, panel);
1297 if (selectedBtn)
1298 WMSetButtonSelected(selectedBtn, True);
1301 panel->selWinB = WMCreateCommandButton(panel->specFrm);
1302 WMMoveWidget(panel->selWinB, 20, 145-24 - 10);
1303 WMResizeWidget(panel->selWinB, frame_width - 2*10 - 20, 24);
1304 WMSetButtonText(panel->selWinB, _("Select Window"));
1305 WMSetButtonAction(panel->selWinB, selectWindow, panel);
1308 panel->specLbl = WMCreateLabel(panel->win);
1309 WMMoveWidget(panel->specLbl, 15, 210);
1310 WMResizeWidget(panel->specLbl, frame_width, 100);
1311 WMSetLabelText(panel->specLbl, _(SPEC_TEXT));
1313 WMSetLabelTextAlignment(panel->specLbl, WACenter);
1315 /**** attributes ****/
1316 panel->attrFrm = WMCreateFrame(panel->win);
1317 WMSetFrameTitle(panel->attrFrm, _("Attributes"));
1318 WMMoveWidget(panel->attrFrm, 15, 45);
1319 WMResizeWidget(panel->attrFrm, frame_width, 250);
1321 for (i=0; i < 10; i++) {
1322 char *caption = NULL;
1323 int flag = 0;
1324 char *descr = NULL;
1326 switch (i) {
1327 case 0:
1328 caption = _("Disable Titlebar");
1329 flag = WFLAGP(wwin, no_titlebar);
1330 descr = _("Remove the titlebar of this window.\n"
1331 "To access the window commands menu of a window\n"
1332 "without it's titlebar, press Control+Esc (or the\n"
1333 "equivalent shortcut, if you changed the default\n"
1334 "settings).");
1335 break;
1336 case 1:
1337 caption = _("Disable Resizebar");
1338 flag = WFLAGP(wwin, no_resizebar);
1339 descr = _("Remove the resizebar of this window.");
1340 break;
1341 case 2:
1342 caption = _("Disable Close Button");
1343 flag = WFLAGP(wwin, no_close_button);
1344 descr = _("Remove the `close window' button of this window.");
1345 break;
1346 case 3:
1347 caption = _("Disable Miniaturize Button");
1348 flag = WFLAGP(wwin, no_miniaturize_button);
1349 descr = _("Remove the `miniaturize window' button of the window.");
1350 break;
1351 case 4:
1352 caption = _("Keep on Top / Floating");
1353 flag = WFLAGP(wwin, floating);
1354 descr = _("Keep the window over other windows, not allowing\n"
1355 "them to covert it.");
1356 break;
1357 case 5:
1358 caption = _("Keep at Bottom / Sunken");
1359 flag = WFLAGP(wwin, sunken);
1360 descr = _("Keep the window under all other windows.");
1361 break;
1362 case 6:
1363 caption = _("Omnipresent");
1364 flag = WFLAGP(wwin, omnipresent);
1365 descr = _("Make window occupy all workspaces.");
1366 break;
1367 case 7:
1368 caption = _("Start Miniaturized");
1369 flag = WFLAGP(wwin, start_miniaturized);
1370 descr = _("Make the window be automatically miniaturized when it's\n"
1371 "first shown.");
1372 break;
1373 case 8:
1374 caption = _("Start Maximized");
1375 flag = WFLAGP(wwin, start_maximized!=0);
1376 descr = _("Make the window be automatically maximized when it's\n"
1377 "first shown.");
1378 break;
1379 case 9:
1380 caption = _("Skip Window List");
1381 flag = WFLAGP(wwin, skip_window_list);
1382 descr = _("Do not list the window in the window list menu.");
1383 break;
1385 panel->attrChk[i] = WMCreateSwitchButton(panel->attrFrm);
1386 WMMoveWidget(panel->attrChk[i], 10, 20*(i+1));
1387 WMResizeWidget(panel->attrChk[i], frame_width-15, 20);
1388 WMSetButtonSelected(panel->attrChk[i], flag);
1389 WMSetButtonText(panel->attrChk[i], caption);
1391 WMSetBalloonTextForView(descr, WMWidgetView(panel->attrChk[i]));
1395 /**** more attributes ****/
1396 panel->moreFrm = WMCreateFrame(panel->win);
1397 WMSetFrameTitle(panel->moreFrm, _("Advanced"));
1398 WMMoveWidget(panel->moreFrm, 15, 45);
1399 WMResizeWidget(panel->moreFrm, frame_width, 250);
1401 for (i=0;
1402 #ifdef XKB_BUTTON_HINT
1403 i < 9;
1404 #else
1405 i < 8;
1406 #endif
1407 i++) {
1408 char *caption = NULL;
1409 int flag = 0;
1410 char *descr = NULL;
1412 switch (i) {
1413 case 0:
1414 caption = _("Ignore HideOthers");
1415 flag = WFLAGP(wwin, no_hide_others);
1416 descr = _("Do not hide the window when issuing the\n"
1417 "`HideOthers' command.");
1418 break;
1419 case 1:
1420 caption = _("Don't Bind Keyboard Shortcuts");
1421 flag = WFLAGP(wwin, no_bind_keys);
1422 descr = _("Do not bind keyboard shortcuts from Window Maker\n"
1423 "when this window is focused. This will allow the\n"
1424 "window to receive all key combinations regardless\n"
1425 "of your shortcut configuration.");
1426 break;
1427 case 2:
1428 caption = _("Don't Bind Mouse Clicks");
1429 flag = WFLAGP(wwin, no_bind_mouse);
1430 descr = _("Do not bind mouse actions, such as `Alt'+drag\n"
1431 "in the window (when alt is the modifier you have"
1432 "configured).");
1433 break;
1434 case 3:
1435 caption = _("Keep Inside Screen");
1436 flag = WFLAGP(wwin, dont_move_off);
1437 descr = _("Do not allow the window to move itself completely\n"
1438 "outside the screen. For bug compatibility.\n");
1439 break;
1440 case 4:
1441 caption = _("Don't Let It Take Focus");
1442 flag = WFLAGP(wwin, no_focusable);
1443 descr = _("Do not let the window take keyboard focus when you\n"
1444 "click on it.");
1445 break;
1446 case 5:
1447 caption = _("Don't Save Session");
1448 flag = WFLAGP(wwin, dont_save_session);
1449 descr = _("Do not save the associated application in the\n"
1450 "session's state, so that it won't be restarted\n"
1451 "together with other applications when Window Maker\n"
1452 "starts.");
1453 break;
1454 case 6:
1455 caption = _("Emulate Application Icon");
1456 flag = WFLAGP(wwin, emulate_appicon);
1457 descr = _("Make this window act as an application that provides\n"
1458 "enough information to Window Maker for a dockable\n"
1459 "application icon to be created.");
1460 break;
1461 case 7:
1462 caption = _("Full Screen Maximization");
1463 flag = WFLAGP(wwin, full_maximize);
1464 descr = _("Make the window use the whole screen space when it's\n"
1465 "maximized. The titlebar and resizebar will be moved\n"
1466 "to outside the screen.");
1467 break;
1468 #ifdef XKB_BUTTON_HINT
1469 case 8:
1470 caption = _("Disable Language Button");
1471 flag = WFLAGP(wwin, no_language_button);
1472 descr = _("Remove the `toggle language' button of the window.");
1473 break;
1474 #endif
1476 panel->moreChk[i] = WMCreateSwitchButton(panel->moreFrm);
1477 WMMoveWidget(panel->moreChk[i], 10, 20*(i+1));
1478 WMResizeWidget(panel->moreChk[i], frame_width-15, 20);
1479 WMSetButtonSelected(panel->moreChk[i], flag);
1480 WMSetButtonText(panel->moreChk[i], caption);
1482 WMSetBalloonTextForView(descr, WMWidgetView(panel->moreChk[i]));
1485 /* miniwindow/workspace */
1486 panel->iconFrm = WMCreateFrame(panel->win);
1487 WMMoveWidget(panel->iconFrm, 15, 50);
1488 WMResizeWidget(panel->iconFrm, PWIDTH - (2 * 15), 170);
1489 WMSetFrameTitle(panel->iconFrm, _("Miniwindow Image"));
1491 panel->iconLbl = WMCreateLabel(panel->iconFrm);
1492 WMMoveWidget(panel->iconLbl, PWIDTH - (2 * 15) - 22 - 64, 30);
1493 WMResizeWidget(panel->iconLbl, 64, 64);
1494 WMSetLabelRelief(panel->iconLbl, WRGroove);
1495 WMSetLabelImagePosition(panel->iconLbl, WIPImageOnly);
1497 panel->browseIconBtn = WMCreateCommandButton(panel->iconFrm);
1498 WMSetButtonAction(panel->browseIconBtn, chooseIconCallback, panel);
1499 WMMoveWidget(panel->browseIconBtn, 22, 30);
1500 WMResizeWidget(panel->browseIconBtn, 100, 26);
1501 WMSetButtonText(panel->browseIconBtn, _("Browse..."));
1503 #if 0
1504 panel->updateIconBtn = WMCreateCommandButton(panel->iconFrm);
1505 WMSetButtonAction(panel->updateIconBtn, (WMAction*)updateIcon, panel);
1506 WMMoveWidget(panel->updateIconBtn, 22, 65);
1507 WMResizeWidget(panel->updateIconBtn, 100, 26);
1508 WMSetButtonText(panel->updateIconBtn, _("Update"));
1509 #endif
1510 #ifdef wrong_behaviour
1511 WMSetButtonImagePosition(panel->updateIconBtn, WIPRight);
1512 pixmap = WMGetSystemPixmap(scr->wmscreen, WSIReturnArrow);
1513 WMSetButtonImage(panel->updateIconBtn, pixmap);
1514 WMReleasePixmap(pixmap);
1515 pixmap = WMGetSystemPixmap(scr->wmscreen, WSIHighlightedReturnArrow);
1516 WMSetButtonAltImage(panel->updateIconBtn, pixmap);
1517 WMReleasePixmap(pixmap);
1518 #endif
1520 panel->fileLbl = WMCreateLabel(panel->iconFrm);
1521 WMMoveWidget(panel->fileLbl, 20, 95);
1522 WMResizeWidget(panel->fileLbl, PWIDTH - (2 * 15) - (2 * 20), 14);
1523 WMSetLabelText(panel->fileLbl, _("Icon File Name:"));
1525 panel->fileText = WMCreateTextField(panel->iconFrm);
1526 WMMoveWidget(panel->fileText, 20, 115);
1527 WMResizeWidget(panel->fileText, PWIDTH - (2 * 15) - (2 * 15), 20);
1528 WMSetTextFieldText(panel->fileText, NULL);
1529 WMAddNotificationObserver(textEditedObserver, panel,
1530 WMTextDidEndEditingNotification,
1531 panel->fileText);
1532 panel->alwChk = WMCreateSwitchButton(panel->iconFrm);
1533 WMMoveWidget(panel->alwChk, 20, 140);
1534 WMResizeWidget(panel->alwChk, PWIDTH - (2 * 15) - (2 * 15), 20);
1535 WMSetButtonText(panel->alwChk, _("Ignore client supplied icon"));
1536 WMSetButtonSelected(panel->alwChk, WFLAGP(wwin, always_user_icon));
1539 panel->wsFrm = WMCreateFrame(panel->win);
1540 WMMoveWidget(panel->wsFrm, 15, 225);
1541 WMResizeWidget(panel->wsFrm, PWIDTH - (2 * 15), 70);
1542 WMSetFrameTitle(panel->wsFrm, _("Initial Workspace"));
1544 WMSetBalloonTextForView(_("The workspace to place the window when it's"
1545 "first shown."), WMWidgetView(panel->wsFrm));
1547 panel->wsP = WMCreatePopUpButton(panel->wsFrm);
1548 WMMoveWidget(panel->wsP, 20, 30);
1549 WMResizeWidget(panel->wsP, PWIDTH - (2 * 15) - (2 * 20), 20);
1550 WMAddPopUpButtonItem(panel->wsP, _("Nowhere in particular"));
1551 for (i = 0; i < wwin->screen_ptr->workspace_count; i++) {
1552 WMAddPopUpButtonItem(panel->wsP, scr->workspaces[i]->name);
1555 i = wDefaultGetStartWorkspace(wwin->screen_ptr, wwin->wm_instance,
1556 wwin->wm_class);
1557 if (i >= 0 && i <= wwin->screen_ptr->workspace_count) {
1558 WMSetPopUpButtonSelectedItem(panel->wsP, i + 1);
1559 } else {
1560 WMSetPopUpButtonSelectedItem(panel->wsP, 0);
1563 /* application wide attributes */
1564 if (wwin->main_window != None) {
1565 WApplication *wapp = wApplicationOf(wwin->main_window);
1567 panel->appFrm = WMCreateFrame(panel->win);
1568 WMSetFrameTitle(panel->appFrm, _("Application Wide"));
1569 WMMoveWidget(panel->appFrm, 15, 50);
1570 WMResizeWidget(panel->appFrm, frame_width, 240);
1572 for (i=0; i < 2; i++) {
1573 char *caption = NULL;
1574 int flag = 0;
1575 char *descr = NULL;
1577 switch (i) {
1578 case 0:
1579 caption = _("Start Hidden");
1580 flag = WFLAGP(wapp->main_window_desc, start_hidden);
1581 descr = _("Automatically hide application when it's started.");
1582 break;
1583 case 1:
1584 caption = _("No Application Icon");
1585 flag = WFLAGP(wapp->main_window_desc, no_appicon);
1586 descr = _("Disable the application icon for the application.\n"
1587 "Note that you won't be able to dock it anymore,\n"
1588 "and any icons that are already docked will stop\n"
1589 "working correctly.");
1590 break;
1592 panel->appChk[i] = WMCreateSwitchButton(panel->appFrm);
1593 WMMoveWidget(panel->appChk[i], 10, 20*(i+1));
1594 WMResizeWidget(panel->appChk[i], 205, 20);
1595 WMSetButtonSelected(panel->appChk[i], flag);
1596 WMSetButtonText(panel->appChk[i], caption);
1598 WMSetBalloonTextForView(descr, WMWidgetView(panel->appChk[i]));
1601 if (WFLAGP(wwin, emulate_appicon)) {
1602 WMSetButtonEnabled(panel->appChk[1], False);
1603 WMSetButtonEnabled(panel->moreChk[6], True);
1604 } else {
1605 WMSetButtonEnabled(panel->appChk[1], True);
1606 WMSetButtonEnabled(panel->moreChk[6], False);
1608 } else {
1609 int tmp;
1611 if ((wwin->transient_for!=None && wwin->transient_for!=scr->root_win)
1612 || !wwin->wm_class || !wwin->wm_instance)
1613 tmp = False;
1614 else
1615 tmp = True;
1616 WMSetButtonEnabled(panel->moreChk[6], tmp);
1618 WMSetPopUpButtonItemEnabled(panel->pagePopUp, 4, False);
1619 panel->appFrm = NULL;
1622 /* if the window is a transient, don't let it have a miniaturize
1623 * button */
1624 if (wWindowFor(wwin->transient_for)!=NULL)
1625 WMSetButtonEnabled(panel->attrChk[3], False);
1626 else
1627 WMSetButtonEnabled(panel->attrChk[3], True);
1630 if (!wwin->wm_class && !wwin->wm_instance) {
1631 WMSetPopUpButtonItemEnabled(panel->pagePopUp, 0, False);
1635 WMRealizeWidget(panel->win);
1637 WMMapSubwidgets(panel->win);
1638 WMMapSubwidgets(panel->specFrm);
1639 WMMapSubwidgets(panel->attrFrm);
1640 WMMapSubwidgets(panel->moreFrm);
1641 WMMapSubwidgets(panel->iconFrm);
1642 WMMapSubwidgets(panel->wsFrm);
1643 if (panel->appFrm)
1644 WMMapSubwidgets(panel->appFrm);
1646 if (showSelectPanel) {
1647 WMSetPopUpButtonSelectedItem(panel->pagePopUp, 0);
1648 changePage(panel->pagePopUp, panel);
1649 } else {
1650 WMSetPopUpButtonSelectedItem(panel->pagePopUp, 1);
1651 changePage(panel->pagePopUp, panel);
1655 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, PWIDTH, PHEIGHT,
1656 0, 0, 0);
1657 XSelectInput(dpy, parent, KeyPressMask|KeyReleaseMask);
1658 panel->parent = parent;
1659 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
1661 WMMapWidget(panel->win);
1663 XSetTransientForHint(dpy, parent, wwin->client_win);
1665 if (xpos == UNDEFINED_POS) {
1666 x = wwin->frame_x+wwin->frame->core->width/2;
1667 y = wwin->frame_y+wwin->frame->top_width*2;
1668 if (y + PHEIGHT > scr->scr_height)
1669 y = scr->scr_height - PHEIGHT - 30;
1670 if (x + PWIDTH > scr->scr_width)
1671 x = scr->scr_width - PWIDTH;
1672 } else {
1673 x = xpos;
1674 y = ypos;
1677 panel->frame = wManageInternalWindow(scr, parent, wwin->client_win,
1678 "Inspector", x, y, PWIDTH, PHEIGHT);
1680 if (!selectedBtn)
1681 selectedBtn = panel->defaultRb;
1683 WMSetButtonSelected(selectedBtn, True);
1685 selectSpecification(selectedBtn, panel);
1687 /* kluge to know who should get the key events */
1688 panel->frame->client_leader = WMWidgetXID(panel->win);
1690 WSETUFLAG(panel->frame, no_closable, 0);
1691 WSETUFLAG(panel->frame, no_close_button, 0);
1692 wWindowUpdateButtonImages(panel->frame);
1693 wFrameWindowShowButton(panel->frame->frame, WFF_RIGHT_BUTTON);
1694 panel->frame->frame->on_click_right = destroyInspector;
1696 wWindowMap(panel->frame);
1698 showIconFor(WMWidgetScreen(panel->alwChk), panel, wwin->wm_instance,
1699 wwin->wm_class, UPDATE_TEXT_FIELD);
1701 return panel;
1705 void
1706 wShowInspectorForWindow(WWindow *wwin)
1708 if (wwin->flags.inspector_open)
1709 return;
1711 WMSetBalloonEnabled(wwin->screen_ptr->wmscreen, wPreferences.help_balloon);
1713 make_keys();
1714 wwin->flags.inspector_open = 1;
1715 wwin->inspector = createInspectorForWindow(wwin, UNDEFINED_POS,
1716 UNDEFINED_POS, False);
1722 void
1723 wHideInspectorForWindow(WWindow *wwin)
1725 WWindow *pwin = wwin->inspector->frame;
1727 wWindowUnmap(pwin);
1728 pwin->flags.hidden = 1;
1730 wClientSetState(pwin, IconicState, None);
1735 void
1736 wUnhideInspectorForWindow(WWindow *wwin)
1738 WWindow *pwin = wwin->inspector->frame;
1740 pwin->flags.hidden = 0;
1741 pwin->flags.mapped = 1;
1742 XMapWindow(dpy, pwin->client_win);
1743 XMapWindow(dpy, pwin->frame->core->window);
1744 wClientSetState(pwin, NormalState, None);
1749 WWindow*
1750 wGetWindowOfInspectorForWindow(WWindow *wwin)
1752 if (wwin->inspector) {
1753 assert(wwin->flags.inspector_open != 0);
1755 return wwin->inspector->frame;
1756 } else
1757 return NULL;
1761 void
1762 wCloseInspectorForWindow(WWindow *wwin)
1764 WWindow *pwin = wwin->inspector->frame; /* the inspector window */
1766 (*pwin->frame->on_click_right)(NULL, pwin, NULL);