- Slovak .po file updates from (Jan Tomka <judas@linux.sk>)
[wmaker-crm.git] / src / winspector.c
blob1fbf985d2f04195ea5fb3af172526f70b36253fd
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"
51 #include <WINGs/WUtil.h>
59 typedef struct InspectorPanel {
60 struct InspectorPanel *nextPtr;
62 WWindow *frame;
64 WWindow *inspected; /* the window that's being inspected */
66 WMWindow *win;
68 Window parent;
70 /* common stuff */
71 WMButton *revertBtn;
72 WMButton *applyBtn;
73 WMButton *saveBtn;
75 WMPopUpButton *pagePopUp;
77 /* first page. general stuff */
79 WMFrame *specFrm;
80 WMButton *instRb;
81 WMButton *clsRb;
82 WMButton *bothRb;
83 WMButton *defaultRb;
85 WMButton *selWinB;
87 WMLabel *specLbl;
89 /* second page. attributes */
91 WMFrame *attrFrm;
92 WMButton *attrChk[11];
94 /* 3rd page. more attributes */
95 WMFrame *moreFrm;
96 #ifdef XKB_BUTTON_HINT
97 WMButton *moreChk[9];
98 #else
99 WMButton *moreChk[8];
100 #endif
102 /* 4th page. icon and workspace */
103 WMFrame *iconFrm;
104 WMLabel *iconLbl;
105 WMLabel *fileLbl;
106 WMTextField *fileText;
107 WMButton *alwChk;
109 WMButton *updateIconBtn;
111 WMButton *browseIconBtn;
113 WMFrame *wsFrm;
114 WMPopUpButton *wsP;
116 /* 5th page. application wide attributes */
117 WMFrame *appFrm;
118 WMButton *appChk[3];
120 unsigned int done:1;
121 unsigned int destroyed:1;
122 unsigned int choosingIcon:1;
123 } InspectorPanel;
128 extern Cursor wCursor[WCUR_LAST];
130 extern WDDomain *WDWindowAttributes;
132 static InspectorPanel *panelList=NULL;
134 extern WPreferences wPreferences;
136 static WMPropList *ANoTitlebar = NULL;
137 static WMPropList *ANoResizebar;
138 static WMPropList *ANoMiniaturizeButton;
139 static WMPropList *ANoCloseButton;
140 static WMPropList *ANoBorder;
141 static WMPropList *ANoHideOthers;
142 static WMPropList *ANoMouseBindings;
143 static WMPropList *ANoKeyBindings;
144 static WMPropList *ANoAppIcon;
145 static WMPropList *AKeepOnTop;
146 static WMPropList *AKeepOnBottom;
147 static WMPropList *AOmnipresent;
148 static WMPropList *ASkipWindowList;
149 static WMPropList *AKeepInsideScreen;
150 static WMPropList *AUnfocusable;
151 static WMPropList *AAlwaysUserIcon;
152 static WMPropList *AStartMiniaturized;
153 static WMPropList *AStartMaximized;
154 static WMPropList *ADontSaveSession;
155 static WMPropList *AEmulateAppIcon;
156 static WMPropList *AFullMaximize;
157 static WMPropList *ACollapseAppIcons;
158 #ifdef XKB_BUTTON_HINT
159 static WMPropList *ANoLanguageButton;
160 #endif
162 static WMPropList *AStartWorkspace;
164 static WMPropList *AIcon;
166 /* application wide options */
167 static WMPropList *AStartHidden;
170 static WMPropList *AnyWindow;
171 static WMPropList *EmptyString;
172 static WMPropList *Yes, *No;
175 #define PWIDTH 270
176 #define PHEIGHT 350
180 static char *spec_text;
183 static void applySettings(WMButton *button, InspectorPanel *panel);
188 #define UNDEFINED_POS 0xffffff
190 static InspectorPanel *createInspectorForWindow(WWindow *wwin,
191 int xpos, int ypos,
192 Bool showSelectPanel);
196 static void
197 make_keys()
199 if (ANoTitlebar!=NULL)
200 return;
202 AIcon = WMCreatePLString("Icon");
203 ANoTitlebar = WMCreatePLString("NoTitlebar");
204 ANoResizebar = WMCreatePLString("NoResizebar");
205 ANoMiniaturizeButton = WMCreatePLString("NoMiniaturizeButton");
206 ANoCloseButton = WMCreatePLString("NoCloseButton");
207 ANoBorder = WMCreatePLString("NoBorder");
208 ANoHideOthers = WMCreatePLString("NoHideOthers");
209 ANoMouseBindings = WMCreatePLString("NoMouseBindings");
210 ANoKeyBindings = WMCreatePLString("NoKeyBindings");
211 ANoAppIcon = WMCreatePLString("NoAppIcon");
212 AKeepOnTop = WMCreatePLString("KeepOnTop");
213 AKeepOnBottom = WMCreatePLString("KeepOnBottom");
214 AOmnipresent = WMCreatePLString("Omnipresent");
215 ASkipWindowList = WMCreatePLString("SkipWindowList");
216 AKeepInsideScreen = WMCreatePLString("KeepInsideScreen");
217 AUnfocusable = WMCreatePLString("Unfocusable");
218 AAlwaysUserIcon = WMCreatePLString("AlwaysUserIcon");
219 AStartMiniaturized = WMCreatePLString("StartMiniaturized");
220 AStartMaximized = WMCreatePLString("StartMaximized");
221 AStartHidden = WMCreatePLString("StartHidden");
222 ADontSaveSession = WMCreatePLString("DontSaveSession");
223 AEmulateAppIcon = WMCreatePLString("EmulateAppIcon");
224 AFullMaximize = WMCreatePLString("FullMaximize");
225 ACollapseAppIcons = WMCreatePLString("CollapseAppIcons");
226 #ifdef XKB_BUTTON_HINT
227 ANoLanguageButton = WMCreatePLString("NoLanguageButton");
228 #endif
230 AStartWorkspace = WMCreatePLString("StartWorkspace");
232 AnyWindow = WMCreatePLString("*");
233 EmptyString = WMCreatePLString("");
234 Yes = WMCreatePLString("Yes");
235 No = WMCreatePLString("No");
240 static void
241 freeInspector(InspectorPanel *panel)
243 panel->destroyed = 1;
244 if (panel->choosingIcon)
245 return;
247 WMDestroyWidget(panel->win);
249 XDestroyWindow(dpy, panel->parent);
251 wfree(panel);
255 static void
256 destroyInspector(WCoreWindow *foo, void *data, XEvent *event)
258 InspectorPanel *panel;
259 InspectorPanel *tmp;
261 panel = panelList;
262 while (panel->frame!=data)
263 panel = panel->nextPtr;
265 if (panelList == panel)
266 panelList = panel->nextPtr;
267 else {
268 tmp = panelList;
269 while (tmp->nextPtr!=panel) {
270 tmp = tmp->nextPtr;
272 tmp->nextPtr = panel->nextPtr;
274 panel->inspected->flags.inspector_open = 0;
275 panel->inspected->inspector = NULL;
277 WMRemoveNotificationObserver(panel);
279 wWindowUnmap(panel->frame);
280 wUnmanageWindow(panel->frame, True, False);
282 freeInspector(panel);
287 void
288 wDestroyInspectorPanels()
290 InspectorPanel *panel;
292 while (panelList != NULL) {
293 panel = panelList;
294 panelList = panelList->nextPtr;
295 wUnmanageWindow(panel->frame, False, False);
296 WMDestroyWidget(panel->win);
298 panel->inspected->flags.inspector_open = 0;
299 panel->inspected->inspector = NULL;
301 wfree(panel);
306 static void
307 changePage(WMPopUpButton *bPtr, InspectorPanel *panel)
309 int page;
311 page = WMGetPopUpButtonSelectedItem(bPtr);
313 if (page == 0) {
314 WMMapWidget(panel->specFrm);
315 WMMapWidget(panel->specLbl);
316 } else if (page == 1) {
317 WMMapWidget(panel->attrFrm);
318 } else if (page == 2) {
319 WMMapWidget(panel->moreFrm);
320 } else if (page == 3) {
321 WMMapWidget(panel->iconFrm);
322 WMMapWidget(panel->wsFrm);
323 } else {
324 WMMapWidget(panel->appFrm);
327 if (page != 0) {
328 WMUnmapWidget(panel->specFrm);
329 WMUnmapWidget(panel->specLbl);
331 if (page != 1)
332 WMUnmapWidget(panel->attrFrm);
333 if (page != 2)
334 WMUnmapWidget(panel->moreFrm);
335 if (page != 3) {
336 WMUnmapWidget(panel->iconFrm);
337 WMUnmapWidget(panel->wsFrm);
339 if (page != 4 && panel->appFrm)
340 WMUnmapWidget(panel->appFrm);
344 #define USE_TEXT_FIELD 1
345 #define UPDATE_TEXT_FIELD 2
346 #define REVERT_TO_DEFAULT 4
349 static int
350 showIconFor(WMScreen *scrPtr, InspectorPanel *panel,
351 char *wm_instance, char *wm_class, int flags)
353 WMPixmap *pixmap = (WMPixmap*) NULL;
354 char *file=NULL, *path=NULL;
355 char *db_icon=NULL;
357 if ((flags & USE_TEXT_FIELD) != 0) {
358 file = WMGetTextFieldText(panel->fileText);
359 if (file && file[0] == 0) {
360 wfree(file);
361 file = NULL;
363 } else {
364 db_icon = wDefaultGetIconFile(panel->inspected->screen_ptr,
365 wm_instance, wm_class, False);
366 if(db_icon != NULL)
367 file = wstrdup(db_icon);
369 if (db_icon!=NULL && (flags & REVERT_TO_DEFAULT)!=0) {
370 if (file)
371 file = wstrdup(db_icon);
372 flags |= UPDATE_TEXT_FIELD;
375 if ((flags & UPDATE_TEXT_FIELD) != 0) {
376 WMSetTextFieldText(panel->fileText, file);
379 if (file) {
380 path = FindImage(wPreferences.icon_path, file);
382 if (!path) {
383 char *buf;
384 int len = strlen(file)+80;
386 buf = wmalloc(len);
387 snprintf(buf, len, _("Could not find icon \"%s\" specified for this window"),
388 file);
389 wMessageDialog(panel->frame->screen_ptr, _("Error"), buf,
390 _("OK"), NULL, NULL);
391 wfree(buf);
392 wfree(file);
393 return -1;
396 pixmap = WMCreatePixmapFromFile(scrPtr, path);
397 wfree(path);
399 if (!pixmap) {
400 char *buf;
401 int len = strlen(file)+80;
403 buf = wmalloc(len);
404 snprintf(buf, len, _("Could not open specified icon \"%s\":%s"),
405 file, RMessageForError(RErrorCode));
406 wMessageDialog(panel->frame->screen_ptr, _("Error"), buf,
407 _("OK"), NULL, NULL);
408 wfree(buf);
409 wfree(file);
410 return -1;
412 wfree(file);
415 WMSetLabelImage(panel->iconLbl, pixmap);
416 if (pixmap)
417 WMReleasePixmap(pixmap);
419 return 0;
422 #if 0
423 static void
424 updateIcon(WMButton *button, InspectorPanel *panel)
426 showIconFor(WMWidgetScreen(button), panel, NULL, NULL, USE_TEXT_FIELD);
428 #endif
430 static int
431 getBool(WMPropList *value)
433 char *val;
435 if (!WMIsPLString(value)) {
436 return 0;
438 if (!(val = WMGetFromPLString(value))) {
439 return 0;
442 if ((val[1]=='\0' && (val[0]=='y' || val[0]=='Y' || val[0]=='T'
443 || val[0]=='t' || val[0]=='1'))
444 || (strcasecmp(val, "YES")==0 || strcasecmp(val, "TRUE")==0)) {
446 return 1;
447 } else if ((val[1]=='\0'
448 && (val[0]=='n' || val[0]=='N' || val[0]=='F'
449 || val[0]=='f' || val[0]=='0'))
450 || (strcasecmp(val, "NO")==0 || strcasecmp(val, "FALSE")==0)) {
452 return 0;
453 } else {
454 wwarning(_("can't convert \"%s\" to boolean"), val);
455 return 0;
460 #define UPDATE_DEFAULTS 1
461 #define IS_BOOLEAN 2
465 * Will insert the attribute = value; pair in window's list,
466 * if it's different from the defaults.
467 * Defaults means either defaults database, or attributes saved
468 * for the default window "*". This is to let one revert options that are
469 * global because they were saved for all windows ("*").
474 static int
475 insertAttribute(WMPropList *dict, WMPropList *window, WMPropList *attr,
476 WMPropList *value, int flags)
478 WMPropList *def_win, *def_value=NULL;
479 int update = 0;
480 int modified = 0;
482 if (!(flags & UPDATE_DEFAULTS) && dict) {
483 if ((def_win = WMGetFromPLDictionary(dict, AnyWindow)) != NULL) {
484 def_value = WMGetFromPLDictionary(def_win, attr);
488 /* If we could not find defaults in database, fall to hardcoded values.
489 * Also this is true if we save defaults for all windows
491 if (!def_value)
492 def_value = ((flags & IS_BOOLEAN) != 0) ? No : EmptyString;
494 if ((flags & IS_BOOLEAN))
495 update = (getBool(value) != getBool(def_value));
496 else {
497 update = !WMIsPropListEqualTo(value, def_value);
500 if (update) {
501 WMPutInPLDictionary(window, attr, value);
502 modified = 1;
505 return modified;
509 static void
510 saveSettings(WMButton *button, InspectorPanel *panel)
512 WWindow *wwin = panel->inspected;
513 WDDomain *db = WDWindowAttributes;
514 WMPropList *dict = db->dictionary;
515 WMPropList *winDic, *value, *key;
516 char *icon_file;
517 int flags = 0;
518 int different = 0;
520 /* Save will apply the changes and save them */
521 applySettings(panel->applyBtn, panel);
523 if (WMGetButtonSelected(panel->instRb) != 0)
524 key = WMCreatePLString(wwin->wm_instance);
525 else if (WMGetButtonSelected(panel->clsRb) != 0)
526 key = WMCreatePLString(wwin->wm_class);
527 else if (WMGetButtonSelected(panel->bothRb) != 0) {
528 char *buffer;
530 buffer = wmalloc(strlen(wwin->wm_instance)+strlen(wwin->wm_class)+2);
531 sprintf(buffer, "%s.%s", wwin->wm_instance, wwin->wm_class);
532 key = WMCreatePLString(buffer);
533 wfree(buffer);
534 } else if (WMGetButtonSelected(panel->defaultRb) != 0) {
535 key = WMRetainPropList(AnyWindow);
536 flags = UPDATE_DEFAULTS;
537 } else
538 key = NULL;
540 if (!key)
541 return;
543 if (!dict) {
544 dict = WMCreatePLDictionary(NULL, NULL, NULL);
545 if (dict) {
546 db->dictionary = dict;
547 } else {
548 WMReleasePropList(key);
549 return;
553 if (showIconFor(WMWidgetScreen(button), panel, NULL, NULL,
554 USE_TEXT_FIELD) < 0)
555 return;
557 WMPLSetCaseSensitive(True);
559 winDic = WMCreatePLDictionary(NULL, NULL, NULL);
561 /* Update icon for window */
562 icon_file = WMGetTextFieldText(panel->fileText);
563 if (icon_file) {
564 if (icon_file[0] != 0) {
565 value = WMCreatePLString(icon_file);
566 different |= insertAttribute(dict, winDic, AIcon, value, flags);
567 WMReleasePropList(value);
569 wfree(icon_file);
573 int i = WMGetPopUpButtonSelectedItem(panel->wsP);
575 i--;
577 if (i>=0 && i < panel->frame->screen_ptr->workspace_count) {
578 value = WMCreatePLString(panel->frame->screen_ptr->workspaces[i]->name);
579 different |= insertAttribute(dict, winDic, AStartWorkspace, value,
580 flags);
581 WMReleasePropList(value);
585 flags |= IS_BOOLEAN;
587 value = (WMGetButtonSelected(panel->alwChk)!=0) ? Yes : No;
588 different |= insertAttribute(dict, winDic, AAlwaysUserIcon, value, flags);
590 value = (WMGetButtonSelected(panel->attrChk[0])!=0) ? Yes : No;
591 different |= insertAttribute(dict, winDic, ANoTitlebar, value, flags);
593 value = (WMGetButtonSelected(panel->attrChk[1])!=0) ? Yes : No;
594 different |= insertAttribute(dict, winDic, ANoResizebar, value, flags);
596 value = (WMGetButtonSelected(panel->attrChk[2])!=0) ? Yes : No;
597 different |= insertAttribute(dict, winDic, ANoCloseButton, value, flags);
599 value = (WMGetButtonSelected(panel->attrChk[3])!=0) ? Yes : No;
600 different |= insertAttribute(dict, winDic, ANoMiniaturizeButton, value, flags);
602 value = (WMGetButtonSelected(panel->attrChk[4])!=0) ? Yes : No;
603 different |= insertAttribute(dict, winDic, ANoBorder, value, flags);
605 value = (WMGetButtonSelected(panel->attrChk[5])!=0) ? Yes : No;
606 different |= insertAttribute(dict, winDic, AKeepOnTop, value, flags);
608 value = (WMGetButtonSelected(panel->attrChk[6])!=0) ? Yes : No;
609 different |= insertAttribute(dict, winDic, AKeepOnBottom, value, flags);
611 value = (WMGetButtonSelected(panel->attrChk[7])!=0) ? Yes : No;
612 different |= insertAttribute(dict, winDic, AOmnipresent, value, flags);
614 value = (WMGetButtonSelected(panel->attrChk[8])!=0) ? Yes : No;
615 different |= insertAttribute(dict, winDic, AStartMiniaturized, value, flags);
617 value = (WMGetButtonSelected(panel->attrChk[9])!=0) ? Yes : No;
618 different |= insertAttribute(dict, winDic, AStartMaximized, value, flags);
620 value = (WMGetButtonSelected(panel->attrChk[10])!=0) ? Yes : No;
621 different |= insertAttribute(dict, winDic, AFullMaximize, value, flags);
624 value = (WMGetButtonSelected(panel->moreChk[0])!=0) ? Yes : No;
625 different |= insertAttribute(dict, winDic, ANoKeyBindings, value, flags);
627 value = (WMGetButtonSelected(panel->moreChk[1])!=0) ? Yes : No;
628 different |= insertAttribute(dict, winDic, ANoMouseBindings, value, flags);
630 value = (WMGetButtonSelected(panel->moreChk[2])!=0) ? Yes : No;
631 different |= insertAttribute(dict, winDic, ASkipWindowList, value, flags);
633 value = (WMGetButtonSelected(panel->moreChk[3])!=0) ? Yes : No;
634 different |= insertAttribute(dict, winDic, AUnfocusable, value, flags);
636 value = (WMGetButtonSelected(panel->moreChk[4])!=0) ? Yes : No;
637 different |= insertAttribute(dict, winDic, AKeepInsideScreen,value, flags);
639 value = (WMGetButtonSelected(panel->moreChk[5])!=0) ? Yes : No;
640 different |= insertAttribute(dict, winDic, ANoHideOthers, value, flags);
642 value = (WMGetButtonSelected(panel->moreChk[6])!=0) ? Yes : No;
643 different |= insertAttribute(dict, winDic, ADontSaveSession, value, flags);
645 value = (WMGetButtonSelected(panel->moreChk[7])!=0) ? Yes : No;
646 different |= insertAttribute(dict, winDic, AEmulateAppIcon, value, flags);
648 #ifdef XKB_BUTTON_HINT
649 value = (WMGetButtonSelected(panel->moreChk[8])!=0) ? Yes : No;
650 different |= insertAttribute(dict, winDic, ANoLanguageButton, value, flags);
651 #endif
653 /* application wide settings for when */
654 /* the window is the leader, save the attribute with the others */
655 if (panel->inspected->main_window == panel->inspected->client_win) {
657 value = (WMGetButtonSelected(panel->appChk[0])!=0) ? Yes : No;
658 different |= insertAttribute(dict, winDic, AStartHidden, value, flags);
660 value = (WMGetButtonSelected(panel->appChk[1])!=0) ? Yes : No;
661 different |= insertAttribute(dict, winDic, ANoAppIcon, value, flags);
663 value = (WMGetButtonSelected(panel->appChk[2])!=0) ? Yes : No;
664 different |= insertAttribute(dict, winDic, ACollapseAppIcons, value, flags);
667 WMRemoveFromPLDictionary(dict, key);
668 if (different) {
669 WMPutInPLDictionary(dict, key, winDic);
672 WMReleasePropList(key);
673 WMReleasePropList(winDic);
675 different = 0;
677 /* application wide settings */
678 if (panel->inspected->main_window != panel->inspected->client_win
679 && !(flags & UPDATE_DEFAULTS)) {
680 WApplication *wapp;
681 WMPropList *appDic;
683 wapp = wApplicationOf(panel->inspected->main_window);
684 if (wapp) {
685 char *instance = wapp->main_window_desc->wm_instance;
686 char *class = wapp->main_window_desc->wm_class;
687 char *iconFile, *buffer;
689 appDic = WMCreatePLDictionary(NULL, NULL, NULL);
691 assert(instance!=NULL);
692 assert(class!=NULL);
694 buffer = wmalloc(strlen(instance)+strlen(class)+2);
695 sprintf(buffer, "%s.%s", instance, class);
696 key = WMCreatePLString(buffer);
697 wfree(buffer);
699 iconFile = wDefaultGetIconFile(wwin->screen_ptr,
700 instance, class, False);
702 if (iconFile && iconFile[0]!=0) {
703 value = WMCreatePLString(iconFile);
704 different |= insertAttribute(dict, appDic, AIcon, value,
705 flags&~IS_BOOLEAN);
706 WMReleasePropList(value);
709 value = (WMGetButtonSelected(panel->appChk[0])!=0) ? Yes : No;
710 different |= insertAttribute(dict, appDic, AStartHidden, value,
711 flags);
713 value = (WMGetButtonSelected(panel->appChk[1])!=0) ? Yes : No;
714 different |= insertAttribute(dict, appDic, ANoAppIcon, value,
715 flags);
717 value = (WMGetButtonSelected(panel->appChk[2])!=0) ? Yes : No;
718 different |= insertAttribute(dict, appDic, ACollapseAppIcons, value,
719 flags);
721 WMRemoveFromPLDictionary(dict, key);
722 if (different) {
723 WMPutInPLDictionary(dict, key, appDic);
725 WMReleasePropList(key);
726 WMReleasePropList(appDic);
730 WMWritePropListToFile(dict, db->path, True);
732 /* clean up */
733 WMPLSetCaseSensitive(False);
737 static void
738 makeAppIconFor(WApplication *wapp)
740 WScreen *scr = wapp->main_window_desc->screen_ptr;
742 if (wapp->app_icon)
743 return;
745 if (!WFLAGP(wapp->main_window_desc, no_appicon))
746 wapp->app_icon = wAppIconCreate(wapp->main_window_desc);
747 else
748 wapp->app_icon = NULL;
750 if (wapp->app_icon) {
751 WIcon *icon = wapp->app_icon->icon;
752 WDock *clip = scr->workspaces[scr->current_workspace]->clip;
753 int x=0, y=0;
755 wapp->app_icon->main_window = wapp->main_window;
757 if (clip && clip->attract_icons && wDockFindFreeSlot(clip, &x, &y)) {
758 wapp->app_icon->attracted = 1;
759 if (!wapp->app_icon->icon->shadowed) {
760 wapp->app_icon->icon->shadowed = 1;
761 wapp->app_icon->icon->force_paint = 1;
763 wDockAttachIcon(clip, wapp->app_icon, x, y);
764 } else {
765 PlaceIcon(scr, &x, &y);
766 wAppIconMove(wapp->app_icon, x, y);
768 if (!clip || !wapp->app_icon->attracted || !clip->collapsed)
769 XMapWindow(dpy, icon->core->window);
771 if (wPreferences.auto_arrange_icons && !wapp->app_icon->attracted)
772 wArrangeIcons(wapp->main_window_desc->screen_ptr, True);
777 static void
778 removeAppIconFor(WApplication *wapp)
780 if (!wapp->app_icon)
781 return;
783 if (wapp->app_icon->docked && !wapp->app_icon->attracted) {
784 wapp->app_icon->running = 0;
785 /* since we keep it, we don't care if it was attracted or not */
786 wapp->app_icon->attracted = 0;
787 wapp->app_icon->icon->shadowed = 0;
788 wapp->app_icon->main_window = None;
789 wapp->app_icon->pid = 0;
790 wapp->app_icon->icon->owner = NULL;
791 wapp->app_icon->icon->icon_win = None;
792 wapp->app_icon->icon->force_paint = 1;
793 wAppIconPaint(wapp->app_icon);
794 } else if (wapp->app_icon->docked) {
795 wapp->app_icon->running = 0;
796 wDockDetach(wapp->app_icon->dock, wapp->app_icon);
797 } else {
798 wAppIconDestroy(wapp->app_icon);
800 wapp->app_icon = NULL;
801 if (wPreferences.auto_arrange_icons)
802 wArrangeIcons(wapp->main_window_desc->screen_ptr, True);
806 static void
807 applySettings(WMButton *button, InspectorPanel *panel)
809 WWindow *wwin = panel->inspected;
810 WApplication *wapp = wApplicationOf(wwin->main_window);
811 int floating, sunken, skip_window_list;
812 int old_omnipresent;
813 int old_no_bind_keys;
814 int old_no_bind_mouse;
816 old_omnipresent = WFLAGP(wwin, omnipresent);
817 old_no_bind_keys = WFLAGP(wwin, no_bind_keys);
818 old_no_bind_mouse = WFLAGP(wwin, no_bind_mouse);
820 showIconFor(WMWidgetScreen(button), panel, NULL, NULL, USE_TEXT_FIELD);
822 WSETUFLAG(wwin, no_titlebar, WMGetButtonSelected(panel->attrChk[0]));
823 WSETUFLAG(wwin, no_resizebar, WMGetButtonSelected(panel->attrChk[1]));
824 WSETUFLAG(wwin, no_close_button, WMGetButtonSelected(panel->attrChk[2]));
825 WSETUFLAG(wwin, no_miniaturize_button, WMGetButtonSelected(panel->attrChk[3]));
826 WSETUFLAG(wwin, no_border, WMGetButtonSelected(panel->attrChk[4]));
827 floating = WMGetButtonSelected(panel->attrChk[5]);
828 sunken = WMGetButtonSelected(panel->attrChk[6]);
829 WSETUFLAG(wwin, omnipresent, WMGetButtonSelected(panel->attrChk[7]));
830 WSETUFLAG(wwin, start_miniaturized, WMGetButtonSelected(panel->attrChk[8]));
831 WSETUFLAG(wwin, start_maximized, WMGetButtonSelected(panel->attrChk[9]));
832 WSETUFLAG(wwin, full_maximize, WMGetButtonSelected(panel->attrChk[10]));
834 WSETUFLAG(wwin, no_bind_keys, WMGetButtonSelected(panel->moreChk[0]));
835 WSETUFLAG(wwin, no_bind_mouse, WMGetButtonSelected(panel->moreChk[1]));
836 skip_window_list = WMGetButtonSelected(panel->moreChk[2]);
837 WSETUFLAG(wwin, no_focusable, WMGetButtonSelected(panel->moreChk[3]));
838 WSETUFLAG(wwin, dont_move_off, WMGetButtonSelected(panel->moreChk[4]));
839 WSETUFLAG(wwin, no_hide_others, WMGetButtonSelected(panel->moreChk[5]));
840 WSETUFLAG(wwin, dont_save_session, WMGetButtonSelected(panel->moreChk[6]));
841 WSETUFLAG(wwin, emulate_appicon, WMGetButtonSelected(panel->moreChk[7]));
842 #ifdef XKB_BUTTON_HINT
843 WSETUFLAG(wwin, no_language_button, WMGetButtonSelected(panel->moreChk[8]));
844 #endif
845 WSETUFLAG(wwin, always_user_icon, WMGetButtonSelected(panel->alwChk));
847 if (WFLAGP(wwin, no_titlebar) && wwin->flags.shaded)
848 wUnshadeWindow(wwin);
850 WSETUFLAG(wwin, no_shadeable, WFLAGP(wwin, no_titlebar));
852 if (floating) {
853 if (!WFLAGP(wwin, floating))
854 ChangeStackingLevel(wwin->frame->core, WMFloatingLevel);
855 } else if (sunken) {
856 if (!WFLAGP(wwin, sunken))
857 ChangeStackingLevel(wwin->frame->core, WMSunkenLevel);
858 } else {
859 if (WFLAGP(wwin, floating) || WFLAGP(wwin, sunken))
860 ChangeStackingLevel(wwin->frame->core, WMNormalLevel);
863 WSETUFLAG(wwin, sunken, sunken);
864 WSETUFLAG(wwin, floating, floating);
865 wwin->flags.omnipresent = 0;
867 if (WFLAGP(wwin, skip_window_list) != skip_window_list) {
868 WSETUFLAG(wwin, skip_window_list, skip_window_list);
869 UpdateSwitchMenu(wwin->screen_ptr, wwin,
870 skip_window_list ? ACTION_REMOVE : ACTION_ADD);
871 } else {
872 if (WFLAGP(wwin, omnipresent) != old_omnipresent) {
873 WMPostNotificationName(WMNChangedState, wwin, "omnipresent");
877 if (WFLAGP(wwin, no_bind_keys) != old_no_bind_keys) {
878 if (WFLAGP(wwin, no_bind_keys)) {
879 XUngrabKey(dpy, AnyKey, AnyModifier, wwin->frame->core->window);
880 } else {
881 wWindowSetKeyGrabs(wwin);
885 if (WFLAGP(wwin, no_bind_mouse) != old_no_bind_mouse) {
886 wWindowResetMouseGrabs(wwin);
889 wwin->frame->flags.need_texture_change = 1;
890 wWindowConfigureBorders(wwin);
891 wFrameWindowPaint(wwin->frame);
894 * Can't apply emulate_appicon because it will probably cause problems.
897 if (wapp) {
898 /* do application wide stuff */
899 WSETUFLAG(wapp->main_window_desc, start_hidden,
900 WMGetButtonSelected(panel->appChk[0]));
902 WSETUFLAG(wapp->main_window_desc, no_appicon,
903 WMGetButtonSelected(panel->appChk[1]));
905 WSETUFLAG(wapp->main_window_desc, collapse_appicons,
906 WMGetButtonSelected(panel->appChk[2]));
908 if (WFLAGP(wapp->main_window_desc, no_appicon))
909 removeAppIconFor(wapp);
910 else
911 makeAppIconFor(wapp);
913 if (wapp->app_icon && wapp->main_window == wwin->client_win) {
914 char *file = WMGetTextFieldText(panel->fileText);
916 if (file[0] == 0) {
917 wfree(file);
918 file = NULL;
920 wIconChangeImageFile(wapp->app_icon->icon, file);
921 if (file)
922 wfree(file);
923 wAppIconPaint(wapp->app_icon);
931 static void
932 revertSettings(WMButton *button, InspectorPanel *panel)
934 WWindow *wwin = panel->inspected;
935 WApplication *wapp = wApplicationOf(wwin->main_window);
936 int i, n;
937 char *wm_instance = NULL;
938 char *wm_class = NULL;
939 int workspace, level;
941 if (panel->instRb && WMGetButtonSelected(panel->instRb) != 0)
942 wm_instance = wwin->wm_instance;
943 else if (panel->clsRb && WMGetButtonSelected(panel->clsRb) != 0)
944 wm_class = wwin->wm_class;
945 else if (panel->bothRb && WMGetButtonSelected(panel->bothRb) != 0) {
946 wm_instance = wwin->wm_instance;
947 wm_class = wwin->wm_class;
949 memset(&wwin->defined_user_flags, 0, sizeof(WWindowAttributes));
950 memset(&wwin->user_flags, 0, sizeof(WWindowAttributes));
951 memset(&wwin->client_flags, 0, sizeof(WWindowAttributes));
953 wWindowSetupInitialAttributes(wwin, &level, &workspace);
955 for (i=0; i < 11; i++) {
956 int flag = 0;
958 switch (i) {
959 case 0:
960 flag = WFLAGP(wwin, no_titlebar);
961 break;
962 case 1:
963 flag = WFLAGP(wwin, no_resizebar);
964 break;
965 case 2:
966 flag = WFLAGP(wwin, no_close_button);
967 break;
968 case 3:
969 flag = WFLAGP(wwin, no_miniaturize_button);
970 break;
971 case 4:
972 flag = WFLAGP(wwin, no_border);
973 break;
974 case 5:
975 flag = WFLAGP(wwin, floating);
976 break;
977 case 6:
978 flag = WFLAGP(wwin, sunken);
979 break;
980 case 7:
981 flag = WFLAGP(wwin, omnipresent);
982 break;
983 case 8:
984 flag = WFLAGP(wwin, start_miniaturized);
985 break;
986 case 9:
987 flag = WFLAGP(wwin, start_maximized!=0);
988 break;
989 case 10:
990 flag = WFLAGP(wwin, full_maximize);
991 break;
993 WMSetButtonSelected(panel->attrChk[i], flag);
995 for (i=0; i < 8; i++) {
996 int flag = 0;
998 switch (i) {
999 case 0:
1000 flag = WFLAGP(wwin, no_bind_keys);
1001 break;
1002 case 1:
1003 flag = WFLAGP(wwin, no_bind_mouse);
1004 break;
1005 case 2:
1006 flag = WFLAGP(wwin, skip_window_list);
1007 break;
1008 case 3:
1009 flag = WFLAGP(wwin, no_focusable);
1010 break;
1011 case 4:
1012 flag = WFLAGP(wwin, dont_move_off);
1013 break;
1014 case 5:
1015 flag = WFLAGP(wwin, no_hide_others);
1016 break;
1017 case 6:
1018 flag = WFLAGP(wwin, dont_save_session);
1019 break;
1020 case 7:
1021 flag = WFLAGP(wwin, emulate_appicon);
1022 break;
1023 #ifdef XKB_BUTTON_HINT
1024 case 8:
1025 flag = WFLAGP(wwin, no_language_button);
1026 break;
1027 #endif
1029 WMSetButtonSelected(panel->moreChk[i], flag);
1031 if (panel->appFrm && wapp) {
1032 for (i=0; i < 2; i++) {
1033 int flag = 0;
1035 switch (i) {
1036 case 0:
1037 flag = WFLAGP(wapp->main_window_desc, start_hidden);
1038 break;
1039 case 1:
1040 flag = WFLAGP(wapp->main_window_desc, no_appicon);
1041 break;
1042 case 2:
1043 flag = WFLAGP(wapp->main_window_desc, collapse_appicons);
1044 break;
1046 WMSetButtonSelected(panel->appChk[i], flag);
1049 WMSetButtonSelected(panel->alwChk, WFLAGP(wwin, always_user_icon));
1051 showIconFor(WMWidgetScreen(panel->alwChk), panel, wm_instance, wm_class,
1052 REVERT_TO_DEFAULT);
1054 n = wDefaultGetStartWorkspace(wwin->screen_ptr, wm_instance, wm_class);
1056 if (n >= 0 && n < wwin->screen_ptr->workspace_count) {
1057 WMSetPopUpButtonSelectedItem(panel->wsP, n+1);
1058 } else {
1059 WMSetPopUpButtonSelectedItem(panel->wsP, 0);
1062 /* must auto apply, so that there wno't be internal
1063 * inconsistencies between the state in the flags and
1064 * the actual state of the window */
1065 applySettings(panel->applyBtn, panel);
1069 static void
1070 chooseIconCallback(WMWidget *self, void *clientData)
1072 char *file;
1073 InspectorPanel *panel = (InspectorPanel*)clientData;
1074 int result;
1076 panel->choosingIcon = 1;
1078 WMSetButtonEnabled(panel->browseIconBtn, False);
1080 result = wIconChooserDialog(panel->frame->screen_ptr, &file,
1081 panel->inspected->wm_instance,
1082 panel->inspected->wm_class);
1084 panel->choosingIcon = 0;
1086 if (!panel->destroyed) { /* kluge */
1087 if (result) {
1088 WMSetTextFieldText(panel->fileText, file);
1089 showIconFor(WMWidgetScreen(self), panel, NULL, NULL,
1090 USE_TEXT_FIELD);
1091 wfree(file);
1093 WMSetButtonEnabled(panel->browseIconBtn, True);
1094 } else {
1095 freeInspector(panel);
1100 static void
1101 textEditedObserver(void *observerData, WMNotification *notification)
1103 InspectorPanel *panel = (InspectorPanel*)observerData;
1105 if ((long)WMGetNotificationClientData(notification) != WMReturnTextMovement)
1106 return;
1108 showIconFor(WMWidgetScreen(panel->win), panel, NULL, NULL,
1109 USE_TEXT_FIELD);
1111 WMPerformButtonClick(panel->updateIconBtn);
1116 static void
1117 selectSpecification(WMWidget *bPtr, void *data)
1119 InspectorPanel *panel = (InspectorPanel*)data;
1120 char *str;
1121 WWindow *wwin = panel->inspected;
1122 int len;
1124 if (bPtr == panel->defaultRb && (wwin->wm_instance || wwin->wm_class)) {
1125 WMSetButtonEnabled(panel->applyBtn, False);
1126 } else {
1127 WMSetButtonEnabled(panel->applyBtn, True);
1130 len = 16 + strlen(wwin->wm_instance ? wwin->wm_instance : "?")
1131 + strlen(wwin->wm_class ? wwin->wm_class : "?");
1133 str = wmalloc(len);
1135 snprintf(str, len, _("Inspecting %s.%s"),
1136 wwin->wm_instance ? wwin->wm_instance : "?",
1137 wwin->wm_class ? wwin->wm_class : "?");
1139 wFrameWindowChangeTitle(panel->frame->frame, str);
1141 wfree(str);
1145 static void
1146 selectWindow(WMWidget *bPtr, void *data)
1148 InspectorPanel *panel = (InspectorPanel*)data;
1149 WWindow *wwin = panel->inspected;
1150 WScreen *scr = wwin->screen_ptr;
1151 XEvent event;
1152 WWindow *iwin;
1154 if (XGrabPointer(dpy, scr->root_win, True,
1155 ButtonPressMask, GrabModeAsync, GrabModeAsync, None,
1156 wCursor[WCUR_SELECT], CurrentTime)!=GrabSuccess) {
1157 wwarning("could not grab mouse pointer");
1158 return;
1161 WMSetLabelText(panel->specLbl, _("Click in the window you wish to inspect."));
1163 WMMaskEvent(dpy, ButtonPressMask, &event);
1165 XUngrabPointer(dpy, CurrentTime);
1167 iwin = wWindowFor(event.xbutton.subwindow);
1169 if (iwin && !iwin->flags.internal_window && iwin != wwin
1170 && !iwin->flags.inspector_open) {
1172 iwin->flags.inspector_open = 1;
1173 iwin->inspector = createInspectorForWindow(iwin,
1174 panel->frame->frame_x,
1175 panel->frame->frame_y,
1176 True);
1177 wCloseInspectorForWindow(wwin);
1178 } else {
1179 WMSetLabelText(panel->specLbl, spec_text);
1185 static InspectorPanel*
1186 createInspectorForWindow(WWindow *wwin, int xpos, int ypos,
1187 Bool showSelectPanel)
1189 WScreen *scr = wwin->screen_ptr;
1190 InspectorPanel *panel;
1191 Window parent;
1192 int i;
1193 int x, y;
1194 int btn_width, frame_width;
1195 WMButton *selectedBtn = NULL;
1196 #ifdef wrong_behaviour
1197 WMPixmap *pixmap;
1198 #endif
1200 spec_text = _("The configuration will apply to all\n"
1201 "windows that have their WM_CLASS\n"
1202 "property set to the above selected\n"
1203 "name, when saved.");
1205 panel = wmalloc(sizeof(InspectorPanel));
1206 memset(panel, 0, sizeof(InspectorPanel));
1208 panel->destroyed = 0;
1211 panel->inspected = wwin;
1213 panel->nextPtr = panelList;
1214 panelList = panel;
1217 panel->win = WMCreateWindow(scr->wmscreen, "windowInspector");
1218 WMResizeWidget(panel->win, PWIDTH, PHEIGHT);
1221 /**** create common stuff ****/
1223 /* command buttons */
1224 /* (PWIDTH - (left and right margin) - (btn interval)) / 3 */
1225 btn_width = (PWIDTH - (2 * 15) - (2 * 10)) / 3;
1226 panel->saveBtn = WMCreateCommandButton(panel->win);
1227 WMSetButtonAction(panel->saveBtn, (WMAction*)saveSettings, panel);
1228 WMMoveWidget(panel->saveBtn, (2 * (btn_width + 10)) + 15, 310);
1229 WMSetButtonText(panel->saveBtn, _("Save"));
1230 WMResizeWidget(panel->saveBtn, btn_width, 28);
1231 if (wPreferences.flags.noupdates || !(wwin->wm_class || wwin->wm_instance))
1232 WMSetButtonEnabled(panel->saveBtn, False);
1234 panel->applyBtn = WMCreateCommandButton(panel->win);
1235 WMSetButtonAction(panel->applyBtn, (WMAction*)applySettings, panel);
1236 WMMoveWidget(panel->applyBtn, btn_width + 10 + 15, 310);
1237 WMSetButtonText(panel->applyBtn, _("Apply"));
1238 WMResizeWidget(panel->applyBtn, btn_width, 28);
1240 panel->revertBtn = WMCreateCommandButton(panel->win);
1241 WMSetButtonAction(panel->revertBtn, (WMAction*)revertSettings, panel);
1242 WMMoveWidget(panel->revertBtn, 15, 310);
1243 WMSetButtonText(panel->revertBtn, _("Reload"));
1244 WMResizeWidget(panel->revertBtn, btn_width, 28);
1246 /* page selection popup button */
1247 panel->pagePopUp = WMCreatePopUpButton(panel->win);
1248 WMSetPopUpButtonAction(panel->pagePopUp, (WMAction*)changePage, panel);
1249 WMMoveWidget(panel->pagePopUp, 25, 15);
1250 WMResizeWidget(panel->pagePopUp, PWIDTH - 50, 20);
1252 WMAddPopUpButtonItem(panel->pagePopUp, _("Window Specification"));
1253 WMAddPopUpButtonItem(panel->pagePopUp, _("Window Attributes"));
1254 WMAddPopUpButtonItem(panel->pagePopUp, _("Advanced Options"));
1255 WMAddPopUpButtonItem(panel->pagePopUp, _("Icon and Initial Workspace"));
1256 WMAddPopUpButtonItem(panel->pagePopUp, _("Application Specific"));
1258 /**** window spec ****/
1259 frame_width = PWIDTH - (2 * 15);
1261 panel->specFrm = WMCreateFrame(panel->win);
1262 WMSetFrameTitle(panel->specFrm, _("Window Specification"));
1263 WMMoveWidget(panel->specFrm, 15, 65);
1264 WMResizeWidget(panel->specFrm, frame_width, 145);
1267 panel->defaultRb = WMCreateRadioButton(panel->specFrm);
1268 WMMoveWidget(panel->defaultRb, 10, 78);
1269 WMResizeWidget(panel->defaultRb, frame_width - (2 * 10), 20);
1270 WMSetButtonText(panel->defaultRb, _("Defaults for all windows"));
1271 WMSetButtonSelected(panel->defaultRb, False);
1272 WMSetButtonAction(panel->defaultRb, selectSpecification, panel);
1274 if (wwin->wm_class && wwin->wm_instance) {
1275 char *str, *tmp;
1277 tmp = wstrconcat(wwin->wm_instance, ".");
1278 str = wstrconcat(tmp, wwin->wm_class);
1280 panel->bothRb = WMCreateRadioButton(panel->specFrm);
1281 WMMoveWidget(panel->bothRb, 10, 18);
1282 WMResizeWidget(panel->bothRb, frame_width - (2 * 10), 20);
1283 WMSetButtonText(panel->bothRb, str);
1284 wfree(tmp);
1285 wfree(str);
1286 WMGroupButtons(panel->defaultRb, panel->bothRb);
1288 if (!selectedBtn)
1289 selectedBtn = panel->bothRb;
1291 WMSetButtonAction(panel->bothRb, selectSpecification, panel);
1294 if (wwin->wm_instance) {
1295 panel->instRb = WMCreateRadioButton(panel->specFrm);
1296 WMMoveWidget(panel->instRb, 10, 38);
1297 WMResizeWidget(panel->instRb, frame_width - (2 * 10), 20);
1298 WMSetButtonText(panel->instRb, wwin->wm_instance);
1299 WMGroupButtons(panel->defaultRb, panel->instRb);
1301 if (!selectedBtn)
1302 selectedBtn = panel->instRb;
1304 WMSetButtonAction(panel->instRb, selectSpecification, panel);
1307 if (wwin->wm_class) {
1308 panel->clsRb = WMCreateRadioButton(panel->specFrm);
1309 WMMoveWidget(panel->clsRb, 10, 58);
1310 WMResizeWidget(panel->clsRb, frame_width - (2 * 10), 20);
1311 WMSetButtonText(panel->clsRb, wwin->wm_class);
1312 WMGroupButtons(panel->defaultRb, panel->clsRb);
1314 if (!selectedBtn)
1315 selectedBtn = panel->clsRb;
1317 WMSetButtonAction(panel->clsRb, selectSpecification, panel);
1321 panel->selWinB = WMCreateCommandButton(panel->specFrm);
1322 WMMoveWidget(panel->selWinB, 20, 145-24 - 10);
1323 WMResizeWidget(panel->selWinB, frame_width - 2*10 - 20, 24);
1324 WMSetButtonText(panel->selWinB, _("Select window"));
1325 WMSetButtonAction(panel->selWinB, selectWindow, panel);
1328 panel->specLbl = WMCreateLabel(panel->win);
1329 WMMoveWidget(panel->specLbl, 15, 210);
1330 WMResizeWidget(panel->specLbl, frame_width, 100);
1331 WMSetLabelText(panel->specLbl, spec_text);
1332 WMSetLabelWraps(panel->specLbl, True);
1334 WMSetLabelTextAlignment(panel->specLbl, WALeft);
1336 /**** attributes ****/
1337 panel->attrFrm = WMCreateFrame(panel->win);
1338 WMSetFrameTitle(panel->attrFrm, _("Attributes"));
1339 WMMoveWidget(panel->attrFrm, 15, 45);
1340 WMResizeWidget(panel->attrFrm, frame_width, 250);
1342 for (i=0; i < 11; i++) {
1343 char *caption = NULL;
1344 int flag = 0;
1345 char *descr = NULL;
1347 switch (i) {
1348 case 0:
1349 caption = _("Disable titlebar");
1350 flag = WFLAGP(wwin, no_titlebar);
1351 descr = _("Remove the titlebar of this window.\n"
1352 "To access the window commands menu of a window\n"
1353 "without it's titlebar, press Control+Esc (or the\n"
1354 "equivalent shortcut, if you changed the default\n"
1355 "settings).");
1356 break;
1357 case 1:
1358 caption = _("Disable resizebar");
1359 flag = WFLAGP(wwin, no_resizebar);
1360 descr = _("Remove the resizebar of this window.");
1361 break;
1362 case 2:
1363 caption = _("Disable close button");
1364 flag = WFLAGP(wwin, no_close_button);
1365 descr = _("Remove the `close window' button of this window.");
1366 break;
1367 case 3:
1368 caption = _("Disable miniaturize button");
1369 flag = WFLAGP(wwin, no_miniaturize_button);
1370 descr = _("Remove the `miniaturize window' button of the window.");
1371 break;
1372 case 4:
1373 caption = _("Disable border");
1374 flag = WFLAGP(wwin, no_border);
1375 descr = _("Remove the 1 pixel black border around the window.");
1376 break;
1377 case 5:
1378 caption = _("Keep on top (floating)");
1379 flag = WFLAGP(wwin, floating);
1380 descr = _("Keep the window over other windows, not allowing\n"
1381 "them to cover it.");
1382 break;
1383 case 6:
1384 caption = _("Keep at bottom (sunken)");
1385 flag = WFLAGP(wwin, sunken);
1386 descr = _("Keep the window under all other windows.");
1387 break;
1388 case 7:
1389 caption = _("Omnipresent");
1390 flag = WFLAGP(wwin, omnipresent);
1391 descr = _("Make window present in all workspaces.");
1392 break;
1393 case 8:
1394 caption = _("Start miniaturized");
1395 flag = WFLAGP(wwin, start_miniaturized);
1396 descr = _("Make the window be automatically miniaturized when it's\n"
1397 "first shown.");
1398 break;
1399 case 9:
1400 caption = _("Start maximized");
1401 flag = WFLAGP(wwin, start_maximized!=0);
1402 descr = _("Make the window be automatically maximized when it's\n"
1403 "first shown.");
1404 break;
1405 case 10:
1406 caption = _("Full screen maximization");
1407 flag = WFLAGP(wwin, full_maximize);
1408 descr = _("Make the window use the whole screen space when it's\n"
1409 "maximized. The titlebar and resizebar will be moved\n"
1410 "to outside the screen.");
1411 break;
1413 panel->attrChk[i] = WMCreateSwitchButton(panel->attrFrm);
1414 WMMoveWidget(panel->attrChk[i], 10, 20*(i+1));
1415 WMResizeWidget(panel->attrChk[i], frame_width-15, 20);
1416 WMSetButtonSelected(panel->attrChk[i], flag);
1417 WMSetButtonText(panel->attrChk[i], caption);
1419 WMSetBalloonTextForView(descr, WMWidgetView(panel->attrChk[i]));
1423 /**** more attributes ****/
1424 panel->moreFrm = WMCreateFrame(panel->win);
1425 WMSetFrameTitle(panel->moreFrm, _("Advanced"));
1426 WMMoveWidget(panel->moreFrm, 15, 45);
1427 WMResizeWidget(panel->moreFrm, frame_width, 250);
1429 for (i=0;
1430 #ifdef XKB_BUTTON_HINT
1431 i < 9;
1432 #else
1433 i < 8;
1434 #endif
1435 i++) {
1436 char *caption = NULL;
1437 int flag = 0;
1438 char *descr = NULL;
1440 switch (i) {
1441 case 0:
1442 caption = _("Do not bind keyboard shortcuts");
1443 flag = WFLAGP(wwin, no_bind_keys);
1444 descr = _("Do not bind keyboard shortcuts from Window Maker\n"
1445 "when this window is focused. This will allow the\n"
1446 "window to receive all key combinations regardless\n"
1447 "of your shortcut configuration.");
1448 break;
1449 case 1:
1450 caption = _("Do not bind mouse clicks");
1451 flag = WFLAGP(wwin, no_bind_mouse);
1452 descr = _("Do not bind mouse actions, such as `Alt'+drag\n"
1453 "in the window (when alt is the modifier you have"
1454 "configured).");
1455 break;
1456 case 2:
1457 caption = _("Do not show in the window list");
1458 flag = WFLAGP(wwin, skip_window_list);
1459 descr = _("Do not list the window in the window list menu.");
1460 break;
1461 case 3:
1462 caption = _("Do not let it take focus");
1463 flag = WFLAGP(wwin, no_focusable);
1464 descr = _("Do not let the window take keyboard focus when you\n"
1465 "click on it.");
1466 break;
1467 case 4:
1468 caption = _("Keep inside screen");
1469 flag = WFLAGP(wwin, dont_move_off);
1470 descr = _("Do not allow the window to move itself completely\n"
1471 "outside the screen. For bug compatibility.\n");
1472 break;
1473 case 5:
1474 caption = _("Ignore 'Hide Others'");
1475 flag = WFLAGP(wwin, no_hide_others);
1476 descr = _("Do not hide the window when issuing the\n"
1477 "`HideOthers' command.");
1478 break;
1479 case 6:
1480 caption = _("Ignore 'Save Session'");
1481 flag = WFLAGP(wwin, dont_save_session);
1482 descr = _("Do not save the associated application in the\n"
1483 "session's state, so that it won't be restarted\n"
1484 "together with other applications when Window Maker\n"
1485 "starts.");
1486 break;
1487 case 7:
1488 caption = _("Emulate application icon");
1489 flag = WFLAGP(wwin, emulate_appicon);
1490 descr = _("Make this window act as an application that provides\n"
1491 "enough information to Window Maker for a dockable\n"
1492 "application icon to be created.");
1493 break;
1494 #ifdef XKB_BUTTON_HINT
1495 case 8:
1496 caption = _("Disable language button");
1497 flag = WFLAGP(wwin, no_language_button);
1498 descr = _("Remove the `toggle language' button of the window.");
1499 break;
1500 #endif
1502 panel->moreChk[i] = WMCreateSwitchButton(panel->moreFrm);
1503 WMMoveWidget(panel->moreChk[i], 10, 20*(i+1));
1504 WMResizeWidget(panel->moreChk[i], frame_width-15, 20);
1505 WMSetButtonSelected(panel->moreChk[i], flag);
1506 WMSetButtonText(panel->moreChk[i], caption);
1508 WMSetBalloonTextForView(descr, WMWidgetView(panel->moreChk[i]));
1511 /* miniwindow/workspace */
1512 panel->iconFrm = WMCreateFrame(panel->win);
1513 WMMoveWidget(panel->iconFrm, 15, 50);
1514 WMResizeWidget(panel->iconFrm, PWIDTH - (2 * 15), 170);
1515 WMSetFrameTitle(panel->iconFrm, _("Miniwindow Image"));
1517 panel->iconLbl = WMCreateLabel(panel->iconFrm);
1518 WMMoveWidget(panel->iconLbl, PWIDTH - (2 * 15) - 22 - 64, 20);
1519 WMResizeWidget(panel->iconLbl, 64, 64);
1520 WMSetLabelRelief(panel->iconLbl, WRGroove);
1521 WMSetLabelImagePosition(panel->iconLbl, WIPImageOnly);
1523 panel->browseIconBtn = WMCreateCommandButton(panel->iconFrm);
1524 WMSetButtonAction(panel->browseIconBtn, chooseIconCallback, panel);
1525 WMMoveWidget(panel->browseIconBtn, 22, 32);
1526 WMResizeWidget(panel->browseIconBtn, 120, 26);
1527 WMSetButtonText(panel->browseIconBtn, _("Browse..."));
1529 #ifdef wrong_behaviour
1530 WMSetButtonImagePosition(panel->updateIconBtn, WIPRight);
1531 pixmap = WMGetSystemPixmap(scr->wmscreen, WSIReturnArrow);
1532 WMSetButtonImage(panel->updateIconBtn, pixmap);
1533 WMReleasePixmap(pixmap);
1534 pixmap = WMGetSystemPixmap(scr->wmscreen, WSIHighlightedReturnArrow);
1535 WMSetButtonAltImage(panel->updateIconBtn, pixmap);
1536 WMReleasePixmap(pixmap);
1537 #endif
1539 panel->fileLbl = WMCreateLabel(panel->iconFrm);
1540 WMMoveWidget(panel->fileLbl, 20, 85);
1541 WMResizeWidget(panel->fileLbl, PWIDTH - (2 * 15) - (2 * 20), 14);
1542 WMSetLabelText(panel->fileLbl, _("Icon filename:"));
1544 panel->fileText = WMCreateTextField(panel->iconFrm);
1545 WMMoveWidget(panel->fileText, 20, 105);
1546 WMResizeWidget(panel->fileText, PWIDTH - (2 * 20) - (2 * 15), 20);
1547 WMSetTextFieldText(panel->fileText, NULL);
1548 WMAddNotificationObserver(textEditedObserver, panel,
1549 WMTextDidEndEditingNotification,
1550 panel->fileText);
1552 panel->alwChk = WMCreateSwitchButton(panel->iconFrm);
1553 WMMoveWidget(panel->alwChk, 20, 130);
1554 WMResizeWidget(panel->alwChk, PWIDTH - (2 * 15) - (2 * 15), 30);
1555 WMSetButtonText(panel->alwChk, _("Ignore client supplied icon"));
1556 WMSetButtonSelected(panel->alwChk, WFLAGP(wwin, always_user_icon));
1559 panel->wsFrm = WMCreateFrame(panel->win);
1560 WMMoveWidget(panel->wsFrm, 15, 225);
1561 WMResizeWidget(panel->wsFrm, PWIDTH - (2 * 15), 70);
1562 WMSetFrameTitle(panel->wsFrm, _("Initial Workspace"));
1564 WMSetBalloonTextForView(_("The workspace to place the window when it's"
1565 "first shown."), WMWidgetView(panel->wsFrm));
1567 panel->wsP = WMCreatePopUpButton(panel->wsFrm);
1568 WMMoveWidget(panel->wsP, 20, 30);
1569 WMResizeWidget(panel->wsP, PWIDTH - (2 * 15) - (2 * 20), 20);
1570 WMAddPopUpButtonItem(panel->wsP, _("Nowhere in particular"));
1571 for (i = 0; i < wwin->screen_ptr->workspace_count; i++) {
1572 WMAddPopUpButtonItem(panel->wsP, scr->workspaces[i]->name);
1575 i = wDefaultGetStartWorkspace(wwin->screen_ptr, wwin->wm_instance,
1576 wwin->wm_class);
1577 if (i >= 0 && i <= wwin->screen_ptr->workspace_count) {
1578 WMSetPopUpButtonSelectedItem(panel->wsP, i + 1);
1579 } else {
1580 WMSetPopUpButtonSelectedItem(panel->wsP, 0);
1583 /* application wide attributes */
1584 if (wwin->main_window != None) {
1585 WApplication *wapp = wApplicationOf(wwin->main_window);
1587 panel->appFrm = WMCreateFrame(panel->win);
1588 WMSetFrameTitle(panel->appFrm, _("Application Attributes"));
1589 WMMoveWidget(panel->appFrm, 15, 50);
1590 WMResizeWidget(panel->appFrm, frame_width, 240);
1592 for (i=0; i < 3; i++) {
1593 char *caption = NULL;
1594 int flag = 0;
1595 char *descr = NULL;
1597 switch (i) {
1598 case 0:
1599 caption = _("Start hidden");
1600 flag = WFLAGP(wapp->main_window_desc, start_hidden);
1601 descr = _("Automatically hide application when it's started.");
1602 break;
1603 case 1:
1604 caption = _("No application icon");
1605 flag = WFLAGP(wapp->main_window_desc, no_appicon);
1606 descr = _("Disable the application icon for the application.\n"
1607 "Note that you won't be able to dock it anymore,\n"
1608 "and any icons that are already docked will stop\n"
1609 "working correctly.");
1610 break;
1611 case 2:
1612 caption = _("Collapse application icons");
1613 flag = WFLAGP(wapp->main_window_desc, collapse_appicons);
1614 descr = _("Collapse application icons from other instances\n"
1615 "of this application into one.\n");
1616 break;
1618 panel->appChk[i] = WMCreateSwitchButton(panel->appFrm);
1619 WMMoveWidget(panel->appChk[i], 10, 20*(i+1));
1620 WMResizeWidget(panel->appChk[i], 205, 20);
1621 WMSetButtonSelected(panel->appChk[i], flag);
1622 WMSetButtonText(panel->appChk[i], caption);
1624 WMSetBalloonTextForView(descr, WMWidgetView(panel->appChk[i]));
1627 if (WFLAGP(wwin, emulate_appicon)) {
1628 WMSetButtonEnabled(panel->appChk[1], False);
1629 WMSetButtonEnabled(panel->moreChk[7], True);
1630 } else {
1631 WMSetButtonEnabled(panel->appChk[1], True);
1632 WMSetButtonEnabled(panel->moreChk[7], False);
1634 } else {
1635 int tmp;
1637 if ((wwin->transient_for!=None && wwin->transient_for!=scr->root_win)
1638 || !wwin->wm_class || !wwin->wm_instance)
1639 tmp = False;
1640 else
1641 tmp = True;
1642 WMSetButtonEnabled(panel->moreChk[7], tmp);
1644 WMSetPopUpButtonItemEnabled(panel->pagePopUp, 4, False);
1645 panel->appFrm = NULL;
1648 /* if the window is a transient, don't let it have a miniaturize
1649 * button */
1650 if (wWindowFor(wwin->transient_for)!=NULL)
1651 WMSetButtonEnabled(panel->attrChk[3], False);
1652 else
1653 WMSetButtonEnabled(panel->attrChk[3], True);
1656 if (!wwin->wm_class && !wwin->wm_instance) {
1657 WMSetPopUpButtonItemEnabled(panel->pagePopUp, 0, False);
1661 WMRealizeWidget(panel->win);
1663 WMMapSubwidgets(panel->win);
1664 WMMapSubwidgets(panel->specFrm);
1665 WMMapSubwidgets(panel->attrFrm);
1666 WMMapSubwidgets(panel->moreFrm);
1667 WMMapSubwidgets(panel->iconFrm);
1668 WMMapSubwidgets(panel->wsFrm);
1669 if (panel->appFrm)
1670 WMMapSubwidgets(panel->appFrm);
1672 if (showSelectPanel) {
1673 WMSetPopUpButtonSelectedItem(panel->pagePopUp, 0);
1674 changePage(panel->pagePopUp, panel);
1675 } else {
1676 WMSetPopUpButtonSelectedItem(panel->pagePopUp, 1);
1677 changePage(panel->pagePopUp, panel);
1681 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, PWIDTH, PHEIGHT,
1682 0, 0, 0);
1683 XSelectInput(dpy, parent, KeyPressMask|KeyReleaseMask);
1684 panel->parent = parent;
1685 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
1687 WMMapWidget(panel->win);
1689 XSetTransientForHint(dpy, parent, wwin->client_win);
1691 if (xpos == UNDEFINED_POS) {
1692 x = wwin->frame_x+wwin->frame->core->width/2;
1693 y = wwin->frame_y+wwin->frame->top_width*2;
1694 if (y + PHEIGHT > scr->scr_height)
1695 y = scr->scr_height - PHEIGHT - 30;
1696 if (x + PWIDTH > scr->scr_width)
1697 x = scr->scr_width - PWIDTH;
1698 } else {
1699 x = xpos;
1700 y = ypos;
1703 panel->frame = wManageInternalWindow(scr, parent, wwin->client_win,
1704 "Inspector", x, y, PWIDTH, PHEIGHT);
1706 if (!selectedBtn)
1707 selectedBtn = panel->defaultRb;
1709 WMSetButtonSelected(selectedBtn, True);
1711 selectSpecification(selectedBtn, panel);
1713 /* kluge to know who should get the key events */
1714 panel->frame->client_leader = WMWidgetXID(panel->win);
1716 WSETUFLAG(panel->frame, no_closable, 0);
1717 WSETUFLAG(panel->frame, no_close_button, 0);
1718 wWindowUpdateButtonImages(panel->frame);
1719 wFrameWindowShowButton(panel->frame->frame, WFF_RIGHT_BUTTON);
1720 panel->frame->frame->on_click_right = destroyInspector;
1722 wWindowMap(panel->frame);
1724 showIconFor(WMWidgetScreen(panel->alwChk), panel, wwin->wm_instance,
1725 wwin->wm_class, UPDATE_TEXT_FIELD);
1727 return panel;
1731 void
1732 wShowInspectorForWindow(WWindow *wwin)
1734 if (wwin->flags.inspector_open)
1735 return;
1737 WMSetBalloonEnabled(wwin->screen_ptr->wmscreen, wPreferences.help_balloon);
1739 make_keys();
1740 wwin->flags.inspector_open = 1;
1741 wwin->inspector = createInspectorForWindow(wwin, UNDEFINED_POS,
1742 UNDEFINED_POS, False);
1748 void
1749 wHideInspectorForWindow(WWindow *wwin)
1751 WWindow *pwin = wwin->inspector->frame;
1753 wWindowUnmap(pwin);
1754 pwin->flags.hidden = 1;
1756 wClientSetState(pwin, IconicState, None);
1761 void
1762 wUnhideInspectorForWindow(WWindow *wwin)
1764 WWindow *pwin = wwin->inspector->frame;
1766 pwin->flags.hidden = 0;
1767 pwin->flags.mapped = 1;
1768 XMapWindow(dpy, pwin->client_win);
1769 XMapWindow(dpy, pwin->frame->core->window);
1770 wClientSetState(pwin, NormalState, None);
1775 WWindow*
1776 wGetWindowOfInspectorForWindow(WWindow *wwin)
1778 if (wwin->inspector) {
1779 assert(wwin->flags.inspector_open != 0);
1781 return wwin->inspector->frame;
1782 } else
1783 return NULL;
1787 void
1788 wCloseInspectorForWindow(WWindow *wwin)
1790 WWindow *pwin = wwin->inspector->frame; /* the inspector window */
1792 (*pwin->frame->on_click_right)(NULL, pwin, NULL);