Remove network support from WINGs
[wmaker-crm.git] / src / winspector.c
blob06328cc011cfa452cb8a07e5f3d7cb42cc205b5c
1 /* winspector.c - window attribute inspector
3 * Window Maker window manager
5 * Copyright (c) 1997-2003 Alfredo K. Kojima
6 * Copyright (c) 1998-2003 Dan Pascu
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"
49 #include "wmspec.h"
50 #include "xinerama.h"
52 #include <WINGs/WUtil.h>
54 typedef struct InspectorPanel {
55 struct InspectorPanel *nextPtr;
57 WWindow *frame;
59 WWindow *inspected; /* the window that's being inspected */
61 WMWindow *win;
63 Window parent;
65 /* common stuff */
66 WMButton *revertBtn;
67 WMButton *applyBtn;
68 WMButton *saveBtn;
70 WMPopUpButton *pagePopUp;
72 /* first page. general stuff */
74 WMFrame *specFrm;
75 WMButton *instRb;
76 WMButton *clsRb;
77 WMButton *bothRb;
78 WMButton *defaultRb;
80 WMButton *selWinB;
82 WMLabel *specLbl;
84 /* second page. attributes */
86 WMFrame *attrFrm;
87 WMButton *attrChk[11];
89 /* 3rd page. more attributes */
90 WMFrame *moreFrm;
91 #ifdef XKB_BUTTON_HINT
92 WMButton *moreChk[10];
93 #else
94 WMButton *moreChk[9];
95 #endif
97 /* 4th page. icon and workspace */
98 WMFrame *iconFrm;
99 WMLabel *iconLbl;
100 WMLabel *fileLbl;
101 WMTextField *fileText;
102 WMButton *alwChk;
104 WMButton *updateIconBtn;
106 WMButton *browseIconBtn;
108 WMFrame *wsFrm;
109 WMPopUpButton *wsP;
111 /* 5th page. application wide attributes */
112 WMFrame *appFrm;
113 WMButton *appChk[3];
115 unsigned int done:1;
116 unsigned int destroyed:1;
117 unsigned int choosingIcon:1;
118 } InspectorPanel;
120 extern Cursor wCursor[WCUR_LAST];
122 extern WDDomain *WDWindowAttributes;
124 static InspectorPanel *panelList = NULL;
126 extern WPreferences wPreferences;
128 static WMPropList *ANoTitlebar = NULL;
129 static WMPropList *ANoResizebar;
130 static WMPropList *ANoMiniaturizeButton;
131 static WMPropList *ANoCloseButton;
132 static WMPropList *ANoBorder;
133 static WMPropList *ANoHideOthers;
134 static WMPropList *ANoMouseBindings;
135 static WMPropList *ANoKeyBindings;
136 static WMPropList *ANoAppIcon;
137 static WMPropList *AKeepOnTop;
138 static WMPropList *AKeepOnBottom;
139 static WMPropList *AOmnipresent;
140 static WMPropList *ASkipWindowList;
141 static WMPropList *AKeepInsideScreen;
142 static WMPropList *AUnfocusable;
143 static WMPropList *ADontFocusAcrossWorkspace;
144 static WMPropList *AAlwaysUserIcon;
145 static WMPropList *AStartMiniaturized;
146 static WMPropList *AStartMaximized;
147 static WMPropList *ADontSaveSession;
148 static WMPropList *AEmulateAppIcon;
149 static WMPropList *AFullMaximize;
150 static WMPropList *ASharedAppIcon;
151 #ifdef XKB_BUTTON_HINT
152 static WMPropList *ANoLanguageButton;
153 #endif
155 static WMPropList *AStartWorkspace;
157 static WMPropList *AIcon;
159 /* application wide options */
160 static WMPropList *AStartHidden;
162 static WMPropList *AnyWindow;
163 static WMPropList *EmptyString;
164 static WMPropList *Yes, *No;
166 #define PWIDTH 270
167 #define PHEIGHT 350
169 static char *spec_text;
171 static void applySettings(WMButton * button, InspectorPanel * panel);
173 #define UNDEFINED_POS 0xffffff
175 static InspectorPanel *createInspectorForWindow(WWindow * wwin, int xpos, int ypos, Bool showSelectPanel);
177 static void make_keys()
179 if (ANoTitlebar != NULL)
180 return;
182 AIcon = WMCreatePLString("Icon");
183 ANoTitlebar = WMCreatePLString("NoTitlebar");
184 ANoResizebar = WMCreatePLString("NoResizebar");
185 ANoMiniaturizeButton = WMCreatePLString("NoMiniaturizeButton");
186 ANoCloseButton = WMCreatePLString("NoCloseButton");
187 ANoBorder = WMCreatePLString("NoBorder");
188 ANoHideOthers = WMCreatePLString("NoHideOthers");
189 ANoMouseBindings = WMCreatePLString("NoMouseBindings");
190 ANoKeyBindings = WMCreatePLString("NoKeyBindings");
191 ANoAppIcon = WMCreatePLString("NoAppIcon");
192 AKeepOnTop = WMCreatePLString("KeepOnTop");
193 AKeepOnBottom = WMCreatePLString("KeepOnBottom");
194 AOmnipresent = WMCreatePLString("Omnipresent");
195 ASkipWindowList = WMCreatePLString("SkipWindowList");
196 AKeepInsideScreen = WMCreatePLString("KeepInsideScreen");
197 AUnfocusable = WMCreatePLString("Unfocusable");
198 ADontFocusAcrossWorkspace = WMCreatePLString("DontFocusAcrossWorkspace");
199 AAlwaysUserIcon = WMCreatePLString("AlwaysUserIcon");
200 AStartMiniaturized = WMCreatePLString("StartMiniaturized");
201 AStartMaximized = WMCreatePLString("StartMaximized");
202 AStartHidden = WMCreatePLString("StartHidden");
203 ADontSaveSession = WMCreatePLString("DontSaveSession");
204 AEmulateAppIcon = WMCreatePLString("EmulateAppIcon");
205 AFullMaximize = WMCreatePLString("FullMaximize");
206 ASharedAppIcon = WMCreatePLString("SharedAppIcon");
207 #ifdef XKB_BUTTON_HINT
208 ANoLanguageButton = WMCreatePLString("NoLanguageButton");
209 #endif
211 AStartWorkspace = WMCreatePLString("StartWorkspace");
213 AnyWindow = WMCreatePLString("*");
214 EmptyString = WMCreatePLString("");
215 Yes = WMCreatePLString("Yes");
216 No = WMCreatePLString("No");
219 static void freeInspector(InspectorPanel * panel)
221 panel->destroyed = 1;
222 if (panel->choosingIcon)
223 return;
225 WMDestroyWidget(panel->win);
227 XDestroyWindow(dpy, panel->parent);
229 wfree(panel);
232 static void destroyInspector(WCoreWindow * foo, void *data, XEvent * event)
234 InspectorPanel *panel;
235 InspectorPanel *tmp;
237 panel = panelList;
238 while (panel->frame != data)
239 panel = panel->nextPtr;
241 if (panelList == panel)
242 panelList = panel->nextPtr;
243 else {
244 tmp = panelList;
245 while (tmp->nextPtr != panel) {
246 tmp = tmp->nextPtr;
248 tmp->nextPtr = panel->nextPtr;
250 panel->inspected->flags.inspector_open = 0;
251 panel->inspected->inspector = NULL;
253 WMRemoveNotificationObserver(panel);
255 wWindowUnmap(panel->frame);
256 wUnmanageWindow(panel->frame, True, False);
258 freeInspector(panel);
261 void wDestroyInspectorPanels()
263 InspectorPanel *panel;
265 while (panelList != NULL) {
266 panel = panelList;
267 panelList = panelList->nextPtr;
268 wUnmanageWindow(panel->frame, False, False);
269 WMDestroyWidget(panel->win);
271 panel->inspected->flags.inspector_open = 0;
272 panel->inspected->inspector = NULL;
274 wfree(panel);
278 static void changePage(WMPopUpButton * bPtr, InspectorPanel * panel)
280 int page;
282 page = WMGetPopUpButtonSelectedItem(bPtr);
284 if (page == 0) {
285 WMMapWidget(panel->specFrm);
286 WMMapWidget(panel->specLbl);
287 } else if (page == 1) {
288 WMMapWidget(panel->attrFrm);
289 } else if (page == 2) {
290 WMMapWidget(panel->moreFrm);
291 } else if (page == 3) {
292 WMMapWidget(panel->iconFrm);
293 WMMapWidget(panel->wsFrm);
294 } else {
295 WMMapWidget(panel->appFrm);
298 if (page != 0) {
299 WMUnmapWidget(panel->specFrm);
300 WMUnmapWidget(panel->specLbl);
302 if (page != 1)
303 WMUnmapWidget(panel->attrFrm);
304 if (page != 2)
305 WMUnmapWidget(panel->moreFrm);
306 if (page != 3) {
307 WMUnmapWidget(panel->iconFrm);
308 WMUnmapWidget(panel->wsFrm);
310 if (page != 4 && panel->appFrm)
311 WMUnmapWidget(panel->appFrm);
314 #define USE_TEXT_FIELD 1
315 #define UPDATE_TEXT_FIELD 2
316 #define REVERT_TO_DEFAULT 4
318 static int showIconFor(WMScreen * scrPtr, InspectorPanel * panel, char *wm_instance, char *wm_class, int flags)
320 WMPixmap *pixmap = (WMPixmap *) NULL;
321 char *file = NULL, *path = NULL;
322 char *db_icon = NULL;
324 if ((flags & USE_TEXT_FIELD) != 0) {
325 file = WMGetTextFieldText(panel->fileText);
326 if (file && file[0] == 0) {
327 wfree(file);
328 file = NULL;
330 } else {
331 db_icon = wDefaultGetIconFile(panel->inspected->screen_ptr, wm_instance, wm_class, False);
332 if (db_icon != NULL)
333 file = wstrdup(db_icon);
335 if (db_icon != NULL && (flags & REVERT_TO_DEFAULT) != 0) {
336 if (file)
337 file = wstrdup(db_icon);
338 flags |= UPDATE_TEXT_FIELD;
341 if ((flags & UPDATE_TEXT_FIELD) != 0) {
342 WMSetTextFieldText(panel->fileText, file);
345 if (file) {
346 path = FindImage(wPreferences.icon_path, file);
348 if (!path) {
349 char *buf;
350 int len = strlen(file) + 80;
352 buf = wmalloc(len);
353 snprintf(buf, len, _("Could not find icon \"%s\" specified for this window"), file);
354 wMessageDialog(panel->frame->screen_ptr, _("Error"), buf, _("OK"), NULL, NULL);
355 wfree(buf);
356 wfree(file);
357 return -1;
360 pixmap = WMCreatePixmapFromFile(scrPtr, path);
361 wfree(path);
363 if (!pixmap) {
364 char *buf;
365 int len = strlen(file) + 80;
367 buf = wmalloc(len);
368 snprintf(buf, len, _("Could not open specified icon \"%s\":%s"),
369 file, RMessageForError(RErrorCode));
370 wMessageDialog(panel->frame->screen_ptr, _("Error"), buf, _("OK"), NULL, NULL);
371 wfree(buf);
372 wfree(file);
373 return -1;
375 wfree(file);
378 WMSetLabelImage(panel->iconLbl, pixmap);
379 if (pixmap)
380 WMReleasePixmap(pixmap);
382 return 0;
385 #if 0
386 static void updateIcon(WMButton * button, InspectorPanel * panel)
388 showIconFor(WMWidgetScreen(button), panel, NULL, NULL, USE_TEXT_FIELD);
390 #endif
392 static int getBool(WMPropList * value)
394 char *val;
396 if (!WMIsPLString(value)) {
397 return 0;
399 if (!(val = WMGetFromPLString(value))) {
400 return 0;
403 if ((val[1] == '\0' && (val[0] == 'y' || val[0] == 'Y' || val[0] == 'T' || val[0] == 't' || val[0] == '1'))
404 || (strcasecmp(val, "YES") == 0 || strcasecmp(val, "TRUE") == 0)) {
406 return 1;
407 } else if ((val[1] == '\0'
408 && (val[0] == 'n' || val[0] == 'N' || val[0] == 'F' || val[0] == 'f' || val[0] == '0'))
409 || (strcasecmp(val, "NO") == 0 || strcasecmp(val, "FALSE") == 0)) {
411 return 0;
412 } else {
413 wwarning(_("can't convert \"%s\" to boolean"), val);
414 return 0;
418 #define UPDATE_DEFAULTS 1
419 #define IS_BOOLEAN 2
422 * Will insert the attribute = value; pair in window's list,
423 * if it's different from the defaults.
424 * Defaults means either defaults database, or attributes saved
425 * for the default window "*". This is to let one revert options that are
426 * global because they were saved for all windows ("*").
430 static int
431 insertAttribute(WMPropList * dict, WMPropList * window, WMPropList * attr, WMPropList * value, int flags)
433 WMPropList *def_win, *def_value = NULL;
434 int update = 0;
435 int modified = 0;
437 if (!(flags & UPDATE_DEFAULTS) && dict) {
438 if ((def_win = WMGetFromPLDictionary(dict, AnyWindow)) != NULL) {
439 def_value = WMGetFromPLDictionary(def_win, attr);
443 /* If we could not find defaults in database, fall to hardcoded values.
444 * Also this is true if we save defaults for all windows
446 if (!def_value)
447 def_value = ((flags & IS_BOOLEAN) != 0) ? No : EmptyString;
449 if ((flags & IS_BOOLEAN))
450 update = (getBool(value) != getBool(def_value));
451 else {
452 update = !WMIsPropListEqualTo(value, def_value);
455 if (update) {
456 WMPutInPLDictionary(window, attr, value);
457 modified = 1;
460 return modified;
463 static void saveSettings(WMButton * button, InspectorPanel * panel)
465 WWindow *wwin = panel->inspected;
466 WDDomain *db = WDWindowAttributes;
467 WMPropList *dict = db->dictionary;
468 WMPropList *winDic, *appDic, *value, *key, *key2;
469 char *icon_file;
470 int flags = 0;
471 int different = 0, different2 = 0;
473 /* Save will apply the changes and save them */
474 applySettings(panel->applyBtn, panel);
476 if (WMGetButtonSelected(panel->instRb) != 0)
477 key = WMCreatePLString(wwin->wm_instance);
478 else if (WMGetButtonSelected(panel->clsRb) != 0)
479 key = WMCreatePLString(wwin->wm_class);
480 else if (WMGetButtonSelected(panel->bothRb) != 0) {
481 char *buffer;
483 buffer = StrConcatDot(wwin->wm_instance, wwin->wm_class);
484 key = WMCreatePLString(buffer);
485 wfree(buffer);
486 } else if (WMGetButtonSelected(panel->defaultRb) != 0) {
487 key = WMRetainPropList(AnyWindow);
488 flags = UPDATE_DEFAULTS;
489 } else
490 key = NULL;
492 if (!key)
493 return;
495 if (!dict) {
496 dict = WMCreatePLDictionary(NULL, NULL);
497 if (dict) {
498 db->dictionary = dict;
499 } else {
500 WMReleasePropList(key);
501 return;
505 if (showIconFor(WMWidgetScreen(button), panel, NULL, NULL, USE_TEXT_FIELD) < 0)
506 return;
508 WMPLSetCaseSensitive(True);
510 winDic = WMCreatePLDictionary(NULL, NULL);
511 appDic = WMCreatePLDictionary(NULL, NULL);
513 /* Update icon for window */
514 icon_file = WMGetTextFieldText(panel->fileText);
515 if (icon_file) {
516 if (icon_file[0] != 0) {
517 value = WMCreatePLString(icon_file);
518 different |= insertAttribute(dict, winDic, AIcon, value, flags);
519 different2 |= insertAttribute(dict, appDic, AIcon, value, flags);
520 WMReleasePropList(value);
522 wfree(icon_file);
526 int i = WMGetPopUpButtonSelectedItem(panel->wsP);
528 i--;
530 if (i >= 0 && i < panel->frame->screen_ptr->workspace_count) {
531 value = WMCreatePLString(panel->frame->screen_ptr->workspaces[i]->name);
532 different |= insertAttribute(dict, winDic, AStartWorkspace, value, flags);
533 WMReleasePropList(value);
537 flags |= IS_BOOLEAN;
539 value = (WMGetButtonSelected(panel->alwChk) != 0) ? Yes : No;
540 different |= insertAttribute(dict, winDic, AAlwaysUserIcon, value, flags);
542 value = (WMGetButtonSelected(panel->attrChk[0]) != 0) ? Yes : No;
543 different |= insertAttribute(dict, winDic, ANoTitlebar, value, flags);
545 value = (WMGetButtonSelected(panel->attrChk[1]) != 0) ? Yes : No;
546 different |= insertAttribute(dict, winDic, ANoResizebar, value, flags);
548 value = (WMGetButtonSelected(panel->attrChk[2]) != 0) ? Yes : No;
549 different |= insertAttribute(dict, winDic, ANoCloseButton, value, flags);
551 value = (WMGetButtonSelected(panel->attrChk[3]) != 0) ? Yes : No;
552 different |= insertAttribute(dict, winDic, ANoMiniaturizeButton, value, flags);
554 value = (WMGetButtonSelected(panel->attrChk[4]) != 0) ? Yes : No;
555 different |= insertAttribute(dict, winDic, ANoBorder, value, flags);
557 value = (WMGetButtonSelected(panel->attrChk[5]) != 0) ? Yes : No;
558 different |= insertAttribute(dict, winDic, AKeepOnTop, value, flags);
560 value = (WMGetButtonSelected(panel->attrChk[6]) != 0) ? Yes : No;
561 different |= insertAttribute(dict, winDic, AKeepOnBottom, value, flags);
563 value = (WMGetButtonSelected(panel->attrChk[7]) != 0) ? Yes : No;
564 different |= insertAttribute(dict, winDic, AOmnipresent, value, flags);
566 value = (WMGetButtonSelected(panel->attrChk[8]) != 0) ? Yes : No;
567 different |= insertAttribute(dict, winDic, AStartMiniaturized, value, flags);
569 value = (WMGetButtonSelected(panel->attrChk[9]) != 0) ? Yes : No;
570 different |= insertAttribute(dict, winDic, AStartMaximized, value, flags);
572 value = (WMGetButtonSelected(panel->attrChk[10]) != 0) ? Yes : No;
573 different |= insertAttribute(dict, winDic, AFullMaximize, value, flags);
575 value = (WMGetButtonSelected(panel->moreChk[0]) != 0) ? Yes : No;
576 different |= insertAttribute(dict, winDic, ANoKeyBindings, value, flags);
578 value = (WMGetButtonSelected(panel->moreChk[1]) != 0) ? Yes : No;
579 different |= insertAttribute(dict, winDic, ANoMouseBindings, value, flags);
581 value = (WMGetButtonSelected(panel->moreChk[2]) != 0) ? Yes : No;
582 different |= insertAttribute(dict, winDic, ASkipWindowList, value, flags);
584 value = (WMGetButtonSelected(panel->moreChk[3]) != 0) ? Yes : No;
585 different |= insertAttribute(dict, winDic, AUnfocusable, value, flags);
587 value = (WMGetButtonSelected(panel->moreChk[4]) != 0) ? Yes : No;
588 different |= insertAttribute(dict, winDic, AKeepInsideScreen, value, flags);
590 value = (WMGetButtonSelected(panel->moreChk[5]) != 0) ? Yes : No;
591 different |= insertAttribute(dict, winDic, ANoHideOthers, value, flags);
593 value = (WMGetButtonSelected(panel->moreChk[6]) != 0) ? Yes : No;
594 different |= insertAttribute(dict, winDic, ADontSaveSession, value, flags);
596 value = (WMGetButtonSelected(panel->moreChk[7]) != 0) ? Yes : No;
597 different |= insertAttribute(dict, winDic, AEmulateAppIcon, value, flags);
599 value = (WMGetButtonSelected(panel->moreChk[8]) != 0) ? Yes : No;
600 different |= insertAttribute(dict, winDic, ADontFocusAcrossWorkspace, value, flags);
602 #ifdef XKB_BUTTON_HINT
603 value = (WMGetButtonSelected(panel->moreChk[9]) != 0) ? Yes : No;
604 different |= insertAttribute(dict, winDic, ANoLanguageButton, value, flags);
605 #endif
607 if (wwin->main_window != None && wApplicationOf(wwin->main_window) != NULL) {
608 value = (WMGetButtonSelected(panel->appChk[0]) != 0) ? Yes : No;
609 different2 |= insertAttribute(dict, appDic, AStartHidden, value, flags);
611 value = (WMGetButtonSelected(panel->appChk[1]) != 0) ? Yes : No;
612 different2 |= insertAttribute(dict, appDic, ANoAppIcon, value, flags);
614 value = (WMGetButtonSelected(panel->appChk[2]) != 0) ? Yes : No;
615 different2 |= insertAttribute(dict, appDic, ASharedAppIcon, value, flags);
618 if (wwin->fake_group) {
619 key2 = WMCreatePLString(wwin->fake_group->identifier);
620 if (WMIsPropListEqualTo(key, key2)) {
621 WMMergePLDictionaries(winDic, appDic, True);
622 different |= different2;
623 } else {
624 WMRemoveFromPLDictionary(dict, key2);
625 if (different2) {
626 WMPutInPLDictionary(dict, key2, appDic);
629 WMReleasePropList(key2);
630 WMReleasePropList(appDic);
631 } else if (wwin->main_window != wwin->client_win) {
632 WApplication *wapp = wApplicationOf(wwin->main_window);
634 if (wapp) {
635 char *instance = wapp->main_window_desc->wm_instance;
636 char *class = wapp->main_window_desc->wm_class;
637 char *buffer;
639 buffer = StrConcatDot(instance, class);
640 key2 = WMCreatePLString(buffer);
641 wfree(buffer);
643 if (WMIsPropListEqualTo(key, key2)) {
644 WMMergePLDictionaries(winDic, appDic, True);
645 different |= different2;
646 } else {
647 WMRemoveFromPLDictionary(dict, key2);
648 if (different2) {
649 WMPutInPLDictionary(dict, key2, appDic);
652 WMReleasePropList(key2);
653 WMReleasePropList(appDic);
655 } else {
656 WMMergePLDictionaries(winDic, appDic, True);
657 different |= different2;
658 WMReleasePropList(appDic);
661 WMRemoveFromPLDictionary(dict, key);
662 if (different) {
663 WMPutInPLDictionary(dict, key, winDic);
666 WMReleasePropList(key);
667 WMReleasePropList(winDic);
669 UpdateDomainFile(db);
671 /* clean up */
672 WMPLSetCaseSensitive(False);
675 static void makeAppIconFor(WApplication * wapp)
677 WScreen *scr = wapp->main_window_desc->screen_ptr;
679 if (wapp->app_icon)
680 return;
682 if (!WFLAGP(wapp->main_window_desc, no_appicon))
683 wapp->app_icon = wAppIconCreate(wapp->main_window_desc);
684 else
685 wapp->app_icon = NULL;
687 if (wapp->app_icon) {
688 WIcon *icon = wapp->app_icon->icon;
689 WDock *clip = scr->workspaces[scr->current_workspace]->clip;
690 int x = 0, y = 0;
692 wapp->app_icon->main_window = wapp->main_window;
694 if (clip && clip->attract_icons && wDockFindFreeSlot(clip, &x, &y)) {
695 wapp->app_icon->attracted = 1;
696 if (!wapp->app_icon->icon->shadowed) {
697 wapp->app_icon->icon->shadowed = 1;
698 wapp->app_icon->icon->force_paint = 1;
700 wDockAttachIcon(clip, wapp->app_icon, x, y);
701 } else {
702 PlaceIcon(scr, &x, &y, wGetHeadForWindow(wapp->main_window_desc));
703 wAppIconMove(wapp->app_icon, x, y);
705 if (!clip || !wapp->app_icon->attracted || !clip->collapsed)
706 XMapWindow(dpy, icon->core->window);
708 if (wPreferences.auto_arrange_icons && !wapp->app_icon->attracted)
709 wArrangeIcons(wapp->main_window_desc->screen_ptr, True);
713 static void removeAppIconFor(WApplication * wapp)
715 if (!wapp->app_icon)
716 return;
718 if (wapp->app_icon->docked && !wapp->app_icon->attracted) {
719 wapp->app_icon->running = 0;
720 /* since we keep it, we don't care if it was attracted or not */
721 wapp->app_icon->attracted = 0;
722 wapp->app_icon->icon->shadowed = 0;
723 wapp->app_icon->main_window = None;
724 wapp->app_icon->pid = 0;
725 wapp->app_icon->icon->owner = NULL;
726 wapp->app_icon->icon->icon_win = None;
727 wapp->app_icon->icon->force_paint = 1;
728 wAppIconPaint(wapp->app_icon);
729 } else if (wapp->app_icon->docked) {
730 wapp->app_icon->running = 0;
731 wDockDetach(wapp->app_icon->dock, wapp->app_icon);
732 } else {
733 wAppIconDestroy(wapp->app_icon);
735 wapp->app_icon = NULL;
736 if (wPreferences.auto_arrange_icons)
737 wArrangeIcons(wapp->main_window_desc->screen_ptr, True);
740 static void applySettings(WMButton * button, InspectorPanel * panel)
742 WWindow *wwin = panel->inspected;
743 WApplication *wapp = wApplicationOf(wwin->main_window);
744 int floating, sunken, skip_window_list;
745 int old_omnipresent;
746 int old_no_bind_keys;
747 int old_no_bind_mouse;
749 old_omnipresent = WFLAGP(wwin, omnipresent);
750 old_no_bind_keys = WFLAGP(wwin, no_bind_keys);
751 old_no_bind_mouse = WFLAGP(wwin, no_bind_mouse);
753 showIconFor(WMWidgetScreen(button), panel, NULL, NULL, USE_TEXT_FIELD);
755 /* Attributes... --> Window Attributes */
756 WSETUFLAG(wwin, no_titlebar, WMGetButtonSelected(panel->attrChk[0]));
757 WSETUFLAG(wwin, no_resizebar, WMGetButtonSelected(panel->attrChk[1]));
758 WSETUFLAG(wwin, no_close_button, WMGetButtonSelected(panel->attrChk[2]));
759 WSETUFLAG(wwin, no_miniaturize_button, WMGetButtonSelected(panel->attrChk[3]));
760 WSETUFLAG(wwin, no_border, WMGetButtonSelected(panel->attrChk[4]));
761 floating = WMGetButtonSelected(panel->attrChk[5]);
762 sunken = WMGetButtonSelected(panel->attrChk[6]);
763 WSETUFLAG(wwin, omnipresent, WMGetButtonSelected(panel->attrChk[7]));
764 WSETUFLAG(wwin, start_miniaturized, WMGetButtonSelected(panel->attrChk[8]));
765 WSETUFLAG(wwin, start_maximized, WMGetButtonSelected(panel->attrChk[9]));
766 WSETUFLAG(wwin, full_maximize, WMGetButtonSelected(panel->attrChk[10]));
768 /* Attributes... --> Advanced Options */
769 WSETUFLAG(wwin, no_bind_keys, WMGetButtonSelected(panel->moreChk[0]));
770 WSETUFLAG(wwin, no_bind_mouse, WMGetButtonSelected(panel->moreChk[1]));
771 skip_window_list = WMGetButtonSelected(panel->moreChk[2]);
772 WSETUFLAG(wwin, no_focusable, WMGetButtonSelected(panel->moreChk[3]));
773 WSETUFLAG(wwin, dont_move_off, WMGetButtonSelected(panel->moreChk[4]));
774 WSETUFLAG(wwin, no_hide_others, WMGetButtonSelected(panel->moreChk[5]));
775 WSETUFLAG(wwin, dont_save_session, WMGetButtonSelected(panel->moreChk[6]));
776 WSETUFLAG(wwin, emulate_appicon, WMGetButtonSelected(panel->moreChk[7]));
777 WSETUFLAG(wwin, dont_focus_across_wksp, WMGetButtonSelected(panel->moreChk[8]));
778 #ifdef XKB_BUTTON_HINT
779 WSETUFLAG(wwin, no_language_button, WMGetButtonSelected(panel->moreChk[9]));
780 #endif
781 WSETUFLAG(wwin, always_user_icon, WMGetButtonSelected(panel->alwChk));
783 if (WFLAGP(wwin, no_titlebar) && wwin->flags.shaded)
784 wUnshadeWindow(wwin);
786 WSETUFLAG(wwin, no_shadeable, WFLAGP(wwin, no_titlebar));
788 if (floating) {
789 if (!WFLAGP(wwin, floating))
790 ChangeStackingLevel(wwin->frame->core, WMFloatingLevel);
791 } else if (sunken) {
792 if (!WFLAGP(wwin, sunken))
793 ChangeStackingLevel(wwin->frame->core, WMSunkenLevel);
794 } else {
795 if (WFLAGP(wwin, floating) || WFLAGP(wwin, sunken))
796 ChangeStackingLevel(wwin->frame->core, WMNormalLevel);
799 WSETUFLAG(wwin, sunken, sunken);
800 WSETUFLAG(wwin, floating, floating);
801 wwin->flags.omnipresent = 0;
803 if (WFLAGP(wwin, skip_window_list) != skip_window_list) {
804 WSETUFLAG(wwin, skip_window_list, skip_window_list);
805 UpdateSwitchMenu(wwin->screen_ptr, wwin, skip_window_list ? ACTION_REMOVE : ACTION_ADD);
806 } else {
807 if (WFLAGP(wwin, omnipresent) != old_omnipresent) {
808 WMPostNotificationName(WMNChangedState, wwin, "omnipresent");
812 if (WFLAGP(wwin, no_bind_keys) != old_no_bind_keys) {
813 if (WFLAGP(wwin, no_bind_keys)) {
814 XUngrabKey(dpy, AnyKey, AnyModifier, wwin->frame->core->window);
815 } else {
816 wWindowSetKeyGrabs(wwin);
820 if (WFLAGP(wwin, no_bind_mouse) != old_no_bind_mouse) {
821 wWindowResetMouseGrabs(wwin);
824 wwin->frame->flags.need_texture_change = 1;
825 wWindowConfigureBorders(wwin);
826 wFrameWindowPaint(wwin->frame);
827 wNETWMUpdateActions(wwin, False);
830 * Can't apply emulate_appicon because it will probably cause problems.
832 if (wapp) {
833 /* do application wide stuff */
834 WSETUFLAG(wapp->main_window_desc, start_hidden, WMGetButtonSelected(panel->appChk[0]));
836 WSETUFLAG(wapp->main_window_desc, no_appicon, WMGetButtonSelected(panel->appChk[1]));
838 WSETUFLAG(wapp->main_window_desc, shared_appicon, WMGetButtonSelected(panel->appChk[2]));
840 if (WFLAGP(wapp->main_window_desc, no_appicon))
841 removeAppIconFor(wapp);
842 else
843 makeAppIconFor(wapp);
845 if (wapp->app_icon && wapp->main_window == wwin->client_win) {
846 char *file = WMGetTextFieldText(panel->fileText);
848 if (file[0] == 0) {
849 wfree(file);
850 file = NULL;
852 wIconChangeImageFile(wapp->app_icon->icon, file);
853 if (file)
854 wfree(file);
855 wAppIconPaint(wapp->app_icon);
860 static void revertSettings(WMButton * button, InspectorPanel * panel)
862 WWindow *wwin = panel->inspected;
863 WApplication *wapp = wApplicationOf(wwin->main_window);
864 int i, n;
865 char *wm_instance = NULL;
866 char *wm_class = NULL;
867 int workspace, level;
869 if (panel->instRb && WMGetButtonSelected(panel->instRb) != 0)
870 wm_instance = wwin->wm_instance;
871 else if (panel->clsRb && WMGetButtonSelected(panel->clsRb) != 0)
872 wm_class = wwin->wm_class;
873 else if (panel->bothRb && WMGetButtonSelected(panel->bothRb) != 0) {
874 wm_instance = wwin->wm_instance;
875 wm_class = wwin->wm_class;
877 memset(&wwin->defined_user_flags, 0, sizeof(WWindowAttributes));
878 memset(&wwin->user_flags, 0, sizeof(WWindowAttributes));
879 memset(&wwin->client_flags, 0, sizeof(WWindowAttributes));
881 wWindowSetupInitialAttributes(wwin, &level, &workspace);
883 for (i = 0; i < 11; i++) {
884 int flag = 0;
886 switch (i) {
887 case 0:
888 flag = WFLAGP(wwin, no_titlebar);
889 break;
890 case 1:
891 flag = WFLAGP(wwin, no_resizebar);
892 break;
893 case 2:
894 flag = WFLAGP(wwin, no_close_button);
895 break;
896 case 3:
897 flag = WFLAGP(wwin, no_miniaturize_button);
898 break;
899 case 4:
900 flag = WFLAGP(wwin, no_border);
901 break;
902 case 5:
903 flag = WFLAGP(wwin, floating);
904 break;
905 case 6:
906 flag = WFLAGP(wwin, sunken);
907 break;
908 case 7:
909 flag = WFLAGP(wwin, omnipresent);
910 break;
911 case 8:
912 flag = WFLAGP(wwin, start_miniaturized);
913 break;
914 case 9:
915 flag = WFLAGP(wwin, start_maximized != 0);
916 break;
917 case 10:
918 flag = WFLAGP(wwin, full_maximize);
919 break;
921 WMSetButtonSelected(panel->attrChk[i], flag);
923 for (i = 0; i < 9; i++) {
924 int flag = 0;
926 switch (i) {
927 case 0:
928 flag = WFLAGP(wwin, no_bind_keys);
929 break;
930 case 1:
931 flag = WFLAGP(wwin, no_bind_mouse);
932 break;
933 case 2:
934 flag = WFLAGP(wwin, skip_window_list);
935 break;
936 case 3:
937 flag = WFLAGP(wwin, no_focusable);
938 break;
939 case 4:
940 flag = WFLAGP(wwin, dont_move_off);
941 break;
942 case 5:
943 flag = WFLAGP(wwin, no_hide_others);
944 break;
945 case 6:
946 flag = WFLAGP(wwin, dont_save_session);
947 break;
948 case 7:
949 flag = WFLAGP(wwin, emulate_appicon);
950 break;
951 case 8:
952 flag = WFLAGP(wwin, dont_focus_across_wksp);
953 break;
954 #ifdef XKB_BUTTON_HINT
955 case 9:
956 flag = WFLAGP(wwin, no_language_button);
957 break;
958 #endif
960 WMSetButtonSelected(panel->moreChk[i], flag);
962 if (panel->appFrm && wapp) {
963 for (i = 0; i < 2; i++) {
964 int flag = 0;
966 switch (i) {
967 case 0:
968 flag = WFLAGP(wapp->main_window_desc, start_hidden);
969 break;
970 case 1:
971 flag = WFLAGP(wapp->main_window_desc, no_appicon);
972 break;
973 case 2:
974 flag = WFLAGP(wapp->main_window_desc, shared_appicon);
975 break;
977 WMSetButtonSelected(panel->appChk[i], flag);
980 WMSetButtonSelected(panel->alwChk, WFLAGP(wwin, always_user_icon));
982 showIconFor(WMWidgetScreen(panel->alwChk), panel, wm_instance, wm_class, REVERT_TO_DEFAULT);
984 n = wDefaultGetStartWorkspace(wwin->screen_ptr, wm_instance, wm_class);
986 if (n >= 0 && n < wwin->screen_ptr->workspace_count) {
987 WMSetPopUpButtonSelectedItem(panel->wsP, n + 1);
988 } else {
989 WMSetPopUpButtonSelectedItem(panel->wsP, 0);
992 /* must auto apply, so that there wno't be internal
993 * inconsistencies between the state in the flags and
994 * the actual state of the window */
995 applySettings(panel->applyBtn, panel);
998 static void chooseIconCallback(WMWidget * self, void *clientData)
1000 char *file;
1001 InspectorPanel *panel = (InspectorPanel *) clientData;
1002 int result;
1004 panel->choosingIcon = 1;
1006 WMSetButtonEnabled(panel->browseIconBtn, False);
1008 result = wIconChooserDialog(panel->frame->screen_ptr, &file,
1009 panel->inspected->wm_instance, panel->inspected->wm_class);
1011 panel->choosingIcon = 0;
1013 if (!panel->destroyed) { /* kluge */
1014 if (result) {
1015 WMSetTextFieldText(panel->fileText, file);
1016 showIconFor(WMWidgetScreen(self), panel, NULL, NULL, USE_TEXT_FIELD);
1017 wfree(file);
1019 WMSetButtonEnabled(panel->browseIconBtn, True);
1020 } else {
1021 freeInspector(panel);
1025 static void textEditedObserver(void *observerData, WMNotification * notification)
1027 InspectorPanel *panel = (InspectorPanel *) observerData;
1029 if ((long)WMGetNotificationClientData(notification) != WMReturnTextMovement)
1030 return;
1032 showIconFor(WMWidgetScreen(panel->win), panel, NULL, NULL, USE_TEXT_FIELD);
1034 WMPerformButtonClick(panel->updateIconBtn);
1038 static void selectSpecification(WMWidget * bPtr, void *data)
1040 InspectorPanel *panel = (InspectorPanel *) data;
1041 char *str;
1042 WWindow *wwin = panel->inspected;
1043 int len;
1045 if (bPtr == panel->defaultRb && (wwin->wm_instance || wwin->wm_class)) {
1046 WMSetButtonEnabled(panel->applyBtn, False);
1047 } else {
1048 WMSetButtonEnabled(panel->applyBtn, True);
1051 len = 16 + strlen(wwin->wm_instance ? wwin->wm_instance : "?")
1052 + strlen(wwin->wm_class ? wwin->wm_class : "?");
1054 str = wmalloc(len);
1056 snprintf(str, len, _("Inspecting %s.%s"),
1057 wwin->wm_instance ? wwin->wm_instance : "?", wwin->wm_class ? wwin->wm_class : "?");
1059 wFrameWindowChangeTitle(panel->frame->frame, str);
1061 wfree(str);
1064 static void selectWindow(WMWidget * bPtr, void *data)
1066 InspectorPanel *panel = (InspectorPanel *) data;
1067 WWindow *wwin = panel->inspected;
1068 WScreen *scr = wwin->screen_ptr;
1069 XEvent event;
1070 WWindow *iwin;
1072 if (XGrabPointer(dpy, scr->root_win, True,
1073 ButtonPressMask, GrabModeAsync, GrabModeAsync, None,
1074 wCursor[WCUR_SELECT], CurrentTime) != GrabSuccess) {
1075 wwarning("could not grab mouse pointer");
1076 return;
1079 WMSetLabelText(panel->specLbl, _("Click in the window you wish to inspect."));
1081 WMMaskEvent(dpy, ButtonPressMask, &event);
1083 XUngrabPointer(dpy, CurrentTime);
1085 iwin = wWindowFor(event.xbutton.subwindow);
1087 if (iwin && !iwin->flags.internal_window && iwin != wwin && !iwin->flags.inspector_open) {
1089 iwin->flags.inspector_open = 1;
1090 iwin->inspector = createInspectorForWindow(iwin,
1091 panel->frame->frame_x, panel->frame->frame_y, True);
1092 wCloseInspectorForWindow(wwin);
1093 } else {
1094 WMSetLabelText(panel->specLbl, spec_text);
1098 static InspectorPanel *createInspectorForWindow(WWindow * wwin, int xpos, int ypos, Bool showSelectPanel)
1100 WScreen *scr = wwin->screen_ptr;
1101 InspectorPanel *panel;
1102 Window parent;
1103 int i;
1104 int x, y;
1105 int btn_width, frame_width;
1106 WMButton *selectedBtn = NULL;
1107 #ifdef wrong_behaviour
1108 WMPixmap *pixmap;
1109 #endif
1111 spec_text = _("The configuration will apply to all\n"
1112 "windows that have their WM_CLASS\n"
1113 "property set to the above selected\n" "name, when saved.");
1115 panel = wmalloc(sizeof(InspectorPanel));
1116 memset(panel, 0, sizeof(InspectorPanel));
1118 panel->destroyed = 0;
1120 panel->inspected = wwin;
1122 panel->nextPtr = panelList;
1123 panelList = panel;
1125 panel->win = WMCreateWindow(scr->wmscreen, "windowInspector");
1126 WMResizeWidget(panel->win, PWIDTH, PHEIGHT);
1128 /**** create common stuff ****/
1130 /* command buttons */
1131 /* (PWIDTH - (left and right margin) - (btn interval)) / 3 */
1132 btn_width = (PWIDTH - (2 * 15) - (2 * 10)) / 3;
1133 panel->saveBtn = WMCreateCommandButton(panel->win);
1134 WMSetButtonAction(panel->saveBtn, (WMAction *) saveSettings, panel);
1135 WMMoveWidget(panel->saveBtn, (2 * (btn_width + 10)) + 15, 310);
1136 WMSetButtonText(panel->saveBtn, _("Save"));
1137 WMResizeWidget(panel->saveBtn, btn_width, 28);
1138 if (wPreferences.flags.noupdates || !(wwin->wm_class || wwin->wm_instance))
1139 WMSetButtonEnabled(panel->saveBtn, False);
1141 panel->applyBtn = WMCreateCommandButton(panel->win);
1142 WMSetButtonAction(panel->applyBtn, (WMAction *) applySettings, panel);
1143 WMMoveWidget(panel->applyBtn, btn_width + 10 + 15, 310);
1144 WMSetButtonText(panel->applyBtn, _("Apply"));
1145 WMResizeWidget(panel->applyBtn, btn_width, 28);
1147 panel->revertBtn = WMCreateCommandButton(panel->win);
1148 WMSetButtonAction(panel->revertBtn, (WMAction *) revertSettings, panel);
1149 WMMoveWidget(panel->revertBtn, 15, 310);
1150 WMSetButtonText(panel->revertBtn, _("Reload"));
1151 WMResizeWidget(panel->revertBtn, btn_width, 28);
1153 /* page selection popup button */
1154 panel->pagePopUp = WMCreatePopUpButton(panel->win);
1155 WMSetPopUpButtonAction(panel->pagePopUp, (WMAction *) changePage, panel);
1156 WMMoveWidget(panel->pagePopUp, 25, 15);
1157 WMResizeWidget(panel->pagePopUp, PWIDTH - 50, 20);
1159 WMAddPopUpButtonItem(panel->pagePopUp, _("Window Specification"));
1160 WMAddPopUpButtonItem(panel->pagePopUp, _("Window Attributes"));
1161 WMAddPopUpButtonItem(panel->pagePopUp, _("Advanced Options"));
1162 WMAddPopUpButtonItem(panel->pagePopUp, _("Icon and Initial Workspace"));
1163 WMAddPopUpButtonItem(panel->pagePopUp, _("Application Specific"));
1165 /**** window spec ****/
1166 frame_width = PWIDTH - (2 * 15);
1168 panel->specFrm = WMCreateFrame(panel->win);
1169 WMSetFrameTitle(panel->specFrm, _("Window Specification"));
1170 WMMoveWidget(panel->specFrm, 15, 65);
1171 WMResizeWidget(panel->specFrm, frame_width, 145);
1173 panel->defaultRb = WMCreateRadioButton(panel->specFrm);
1174 WMMoveWidget(panel->defaultRb, 10, 78);
1175 WMResizeWidget(panel->defaultRb, frame_width - (2 * 10), 20);
1176 WMSetButtonText(panel->defaultRb, _("Defaults for all windows"));
1177 WMSetButtonSelected(panel->defaultRb, False);
1178 WMSetButtonAction(panel->defaultRb, selectSpecification, panel);
1180 if (wwin->wm_class && wwin->wm_instance) {
1181 char *str, *tmp;
1183 tmp = wstrconcat(wwin->wm_instance, ".");
1184 str = wstrconcat(tmp, wwin->wm_class);
1186 panel->bothRb = WMCreateRadioButton(panel->specFrm);
1187 WMMoveWidget(panel->bothRb, 10, 18);
1188 WMResizeWidget(panel->bothRb, frame_width - (2 * 10), 20);
1189 WMSetButtonText(panel->bothRb, str);
1190 wfree(tmp);
1191 wfree(str);
1192 WMGroupButtons(panel->defaultRb, panel->bothRb);
1194 if (!selectedBtn)
1195 selectedBtn = panel->bothRb;
1197 WMSetButtonAction(panel->bothRb, selectSpecification, panel);
1200 if (wwin->wm_instance) {
1201 panel->instRb = WMCreateRadioButton(panel->specFrm);
1202 WMMoveWidget(panel->instRb, 10, 38);
1203 WMResizeWidget(panel->instRb, frame_width - (2 * 10), 20);
1204 WMSetButtonText(panel->instRb, wwin->wm_instance);
1205 WMGroupButtons(panel->defaultRb, panel->instRb);
1207 if (!selectedBtn)
1208 selectedBtn = panel->instRb;
1210 WMSetButtonAction(panel->instRb, selectSpecification, panel);
1213 if (wwin->wm_class) {
1214 panel->clsRb = WMCreateRadioButton(panel->specFrm);
1215 WMMoveWidget(panel->clsRb, 10, 58);
1216 WMResizeWidget(panel->clsRb, frame_width - (2 * 10), 20);
1217 WMSetButtonText(panel->clsRb, wwin->wm_class);
1218 WMGroupButtons(panel->defaultRb, panel->clsRb);
1220 if (!selectedBtn)
1221 selectedBtn = panel->clsRb;
1223 WMSetButtonAction(panel->clsRb, selectSpecification, panel);
1226 panel->selWinB = WMCreateCommandButton(panel->specFrm);
1227 WMMoveWidget(panel->selWinB, 20, 145 - 24 - 10);
1228 WMResizeWidget(panel->selWinB, frame_width - 2 * 10 - 20, 24);
1229 WMSetButtonText(panel->selWinB, _("Select window"));
1230 WMSetButtonAction(panel->selWinB, selectWindow, panel);
1232 panel->specLbl = WMCreateLabel(panel->win);
1233 WMMoveWidget(panel->specLbl, 15, 210);
1234 WMResizeWidget(panel->specLbl, frame_width, 100);
1235 WMSetLabelText(panel->specLbl, spec_text);
1236 WMSetLabelWraps(panel->specLbl, True);
1238 WMSetLabelTextAlignment(panel->specLbl, WALeft);
1240 /**** attributes ****/
1241 panel->attrFrm = WMCreateFrame(panel->win);
1242 WMSetFrameTitle(panel->attrFrm, _("Attributes"));
1243 WMMoveWidget(panel->attrFrm, 15, 45);
1244 WMResizeWidget(panel->attrFrm, frame_width, 250);
1246 for (i = 0; i < 11; i++) {
1247 char *caption = NULL;
1248 int flag = 0;
1249 char *descr = NULL;
1251 switch (i) {
1252 case 0:
1253 caption = _("Disable titlebar");
1254 flag = WFLAGP(wwin, no_titlebar);
1255 descr = _("Remove the titlebar of this window.\n"
1256 "To access the window commands menu of a window\n"
1257 "without it's titlebar, press Control+Esc (or the\n"
1258 "equivalent shortcut, if you changed the default\n" "settings).");
1259 break;
1260 case 1:
1261 caption = _("Disable resizebar");
1262 flag = WFLAGP(wwin, no_resizebar);
1263 descr = _("Remove the resizebar of this window.");
1264 break;
1265 case 2:
1266 caption = _("Disable close button");
1267 flag = WFLAGP(wwin, no_close_button);
1268 descr = _("Remove the `close window' button of this window.");
1269 break;
1270 case 3:
1271 caption = _("Disable miniaturize button");
1272 flag = WFLAGP(wwin, no_miniaturize_button);
1273 descr = _("Remove the `miniaturize window' button of the window.");
1274 break;
1275 case 4:
1276 caption = _("Disable border");
1277 flag = WFLAGP(wwin, no_border);
1278 descr = _("Remove the 1 pixel black border around the window.");
1279 break;
1280 case 5:
1281 caption = _("Keep on top (floating)");
1282 flag = WFLAGP(wwin, floating);
1283 descr = _("Keep the window over other windows, not allowing\n" "them to cover it.");
1284 break;
1285 case 6:
1286 caption = _("Keep at bottom (sunken)");
1287 flag = WFLAGP(wwin, sunken);
1288 descr = _("Keep the window under all other windows.");
1289 break;
1290 case 7:
1291 caption = _("Omnipresent");
1292 flag = WFLAGP(wwin, omnipresent);
1293 descr = _("Make window present in all workspaces.");
1294 break;
1295 case 8:
1296 caption = _("Start miniaturized");
1297 flag = WFLAGP(wwin, start_miniaturized);
1298 descr = _("Make the window be automatically miniaturized when it's\n" "first shown.");
1299 break;
1300 case 9:
1301 caption = _("Start maximized");
1302 flag = WFLAGP(wwin, start_maximized != 0);
1303 descr = _("Make the window be automatically maximized when it's\n" "first shown.");
1304 break;
1305 case 10:
1306 caption = _("Full screen maximization");
1307 flag = WFLAGP(wwin, full_maximize);
1308 descr = _("Make the window use the whole screen space when it's\n"
1309 "maximized. The titlebar and resizebar will be moved\n"
1310 "to outside the screen.");
1311 break;
1313 panel->attrChk[i] = WMCreateSwitchButton(panel->attrFrm);
1314 WMMoveWidget(panel->attrChk[i], 10, 20 * (i + 1));
1315 WMResizeWidget(panel->attrChk[i], frame_width - 15, 20);
1316 WMSetButtonSelected(panel->attrChk[i], flag);
1317 WMSetButtonText(panel->attrChk[i], caption);
1319 WMSetBalloonTextForView(descr, WMWidgetView(panel->attrChk[i]));
1322 /**** more attributes ****/
1323 panel->moreFrm = WMCreateFrame(panel->win);
1324 WMSetFrameTitle(panel->moreFrm, _("Advanced"));
1325 WMMoveWidget(panel->moreFrm, 15, 45);
1326 WMResizeWidget(panel->moreFrm, frame_width, 250);
1328 for (i = 0;
1329 #ifdef XKB_BUTTON_HINT
1330 i < 10;
1331 #else
1332 i < 9;
1333 #endif
1334 i++) {
1335 char *caption = NULL;
1336 int flag = 0;
1337 char *descr = NULL;
1339 switch (i) {
1340 case 0:
1341 caption = _("Do not bind keyboard shortcuts");
1342 flag = WFLAGP(wwin, no_bind_keys);
1343 descr = _("Do not bind keyboard shortcuts from Window Maker\n"
1344 "when this window is focused. This will allow the\n"
1345 "window to receive all key combinations regardless\n"
1346 "of your shortcut configuration.");
1347 break;
1348 case 1:
1349 caption = _("Do not bind mouse clicks");
1350 flag = WFLAGP(wwin, no_bind_mouse);
1351 descr = _("Do not bind mouse actions, such as `Alt'+drag\n"
1352 "in the window (when alt is the modifier you have\n" "configured).");
1353 break;
1354 case 2:
1355 caption = _("Do not show in the window list");
1356 flag = WFLAGP(wwin, skip_window_list);
1357 descr = _("Do not list the window in the window list menu.");
1358 break;
1359 case 3:
1360 caption = _("Do not let it take focus");
1361 flag = WFLAGP(wwin, no_focusable);
1362 descr = _("Do not let the window take keyboard focus when you\n" "click on it.");
1363 break;
1364 case 4:
1365 caption = _("Keep inside screen");
1366 flag = WFLAGP(wwin, dont_move_off);
1367 descr = _("Do not allow the window to move itself completely\n"
1368 "outside the screen. For bug compatibility.\n");
1369 break;
1370 case 5:
1371 caption = _("Ignore 'Hide Others'");
1372 flag = WFLAGP(wwin, no_hide_others);
1373 descr = _("Do not hide the window when issuing the\n" "`HideOthers' command.");
1374 break;
1375 case 6:
1376 caption = _("Ignore 'Save Session'");
1377 flag = WFLAGP(wwin, dont_save_session);
1378 descr = _("Do not save the associated application in the\n"
1379 "session's state, so that it won't be restarted\n"
1380 "together with other applications when Window Maker\n" "starts.");
1381 break;
1382 case 7:
1383 caption = _("Emulate application icon");
1384 flag = WFLAGP(wwin, emulate_appicon);
1385 descr = _("Make this window act as an application that provides\n"
1386 "enough information to Window Maker for a dockable\n"
1387 "application icon to be created.");
1388 break;
1389 case 8:
1390 caption = _("Don't focus across workspaces");
1391 flag = WFLAGP(wwin, dont_focus_across_wksp);
1392 descr = _("Do not allow Window Maker to switch workspace to satisfy\n"
1393 "a focus request (useful e.g. in the case of a multiple-tab\n"
1394 "firefox opening in a different workspace).");
1395 break;
1396 #ifdef XKB_BUTTON_HINT
1397 case 9:
1398 caption = _("Disable language button");
1399 flag = WFLAGP(wwin, no_language_button);
1400 descr = _("Remove the `toggle language' button of the window.");
1401 break;
1402 #endif
1404 panel->moreChk[i] = WMCreateSwitchButton(panel->moreFrm);
1405 WMMoveWidget(panel->moreChk[i], 10, 20 * (i + 1));
1406 WMResizeWidget(panel->moreChk[i], frame_width - 15, 20);
1407 WMSetButtonSelected(panel->moreChk[i], flag);
1408 WMSetButtonText(panel->moreChk[i], caption);
1410 WMSetBalloonTextForView(descr, WMWidgetView(panel->moreChk[i]));
1413 /* miniwindow/workspace */
1414 panel->iconFrm = WMCreateFrame(panel->win);
1415 WMMoveWidget(panel->iconFrm, 15, 50);
1416 WMResizeWidget(panel->iconFrm, PWIDTH - (2 * 15), 170);
1417 WMSetFrameTitle(panel->iconFrm, _("Miniwindow Image"));
1419 panel->iconLbl = WMCreateLabel(panel->iconFrm);
1420 WMMoveWidget(panel->iconLbl, PWIDTH - (2 * 15) - 22 - 64, 20);
1421 WMResizeWidget(panel->iconLbl, 64, 64);
1422 WMSetLabelRelief(panel->iconLbl, WRGroove);
1423 WMSetLabelImagePosition(panel->iconLbl, WIPImageOnly);
1425 panel->browseIconBtn = WMCreateCommandButton(panel->iconFrm);
1426 WMSetButtonAction(panel->browseIconBtn, chooseIconCallback, panel);
1427 WMMoveWidget(panel->browseIconBtn, 22, 32);
1428 WMResizeWidget(panel->browseIconBtn, 120, 26);
1429 WMSetButtonText(panel->browseIconBtn, _("Browse..."));
1431 #ifdef wrong_behaviour
1432 WMSetButtonImagePosition(panel->updateIconBtn, WIPRight);
1433 pixmap = WMGetSystemPixmap(scr->wmscreen, WSIReturnArrow);
1434 WMSetButtonImage(panel->updateIconBtn, pixmap);
1435 WMReleasePixmap(pixmap);
1436 pixmap = WMGetSystemPixmap(scr->wmscreen, WSIHighlightedReturnArrow);
1437 WMSetButtonAltImage(panel->updateIconBtn, pixmap);
1438 WMReleasePixmap(pixmap);
1439 #endif
1441 panel->fileLbl = WMCreateLabel(panel->iconFrm);
1442 WMMoveWidget(panel->fileLbl, 20, 85);
1443 WMResizeWidget(panel->fileLbl, PWIDTH - (2 * 15) - (2 * 20), 14);
1444 WMSetLabelText(panel->fileLbl, _("Icon filename:"));
1446 panel->fileText = WMCreateTextField(panel->iconFrm);
1447 WMMoveWidget(panel->fileText, 20, 105);
1448 WMResizeWidget(panel->fileText, PWIDTH - (2 * 20) - (2 * 15), 20);
1449 WMSetTextFieldText(panel->fileText, NULL);
1450 WMAddNotificationObserver(textEditedObserver, panel, WMTextDidEndEditingNotification, panel->fileText);
1452 panel->alwChk = WMCreateSwitchButton(panel->iconFrm);
1453 WMMoveWidget(panel->alwChk, 20, 130);
1454 WMResizeWidget(panel->alwChk, PWIDTH - (2 * 15) - (2 * 15), 30);
1455 WMSetButtonText(panel->alwChk, _("Ignore client supplied icon"));
1456 WMSetButtonSelected(panel->alwChk, WFLAGP(wwin, always_user_icon));
1458 panel->wsFrm = WMCreateFrame(panel->win);
1459 WMMoveWidget(panel->wsFrm, 15, 225);
1460 WMResizeWidget(panel->wsFrm, PWIDTH - (2 * 15), 70);
1461 WMSetFrameTitle(panel->wsFrm, _("Initial Workspace"));
1463 WMSetBalloonTextForView(_("The workspace to place the window when it's"
1464 "first shown."), WMWidgetView(panel->wsFrm));
1466 panel->wsP = WMCreatePopUpButton(panel->wsFrm);
1467 WMMoveWidget(panel->wsP, 20, 30);
1468 WMResizeWidget(panel->wsP, PWIDTH - (2 * 15) - (2 * 20), 20);
1469 WMAddPopUpButtonItem(panel->wsP, _("Nowhere in particular"));
1470 for (i = 0; i < wwin->screen_ptr->workspace_count; i++) {
1471 WMAddPopUpButtonItem(panel->wsP, scr->workspaces[i]->name);
1474 i = wDefaultGetStartWorkspace(wwin->screen_ptr, wwin->wm_instance, wwin->wm_class);
1475 if (i >= 0 && i <= wwin->screen_ptr->workspace_count) {
1476 WMSetPopUpButtonSelectedItem(panel->wsP, i + 1);
1477 } else {
1478 WMSetPopUpButtonSelectedItem(panel->wsP, 0);
1481 /* application wide attributes */
1482 if (wwin->main_window != None) {
1483 WApplication *wapp = wApplicationOf(wwin->main_window);
1485 panel->appFrm = WMCreateFrame(panel->win);
1486 WMSetFrameTitle(panel->appFrm, _("Application Attributes"));
1487 WMMoveWidget(panel->appFrm, 15, 50);
1488 WMResizeWidget(panel->appFrm, frame_width, 240);
1490 for (i = 0; i < 3; i++) {
1491 char *caption = NULL;
1492 int flag = 0;
1493 char *descr = NULL;
1495 switch (i) {
1496 case 0:
1497 caption = _("Start hidden");
1498 flag = WFLAGP(wapp->main_window_desc, start_hidden);
1499 descr = _("Automatically hide application when it's started.");
1500 break;
1501 case 1:
1502 caption = _("No application icon");
1503 flag = WFLAGP(wapp->main_window_desc, no_appicon);
1504 descr = _("Disable the application icon for the application.\n"
1505 "Note that you won't be able to dock it anymore,\n"
1506 "and any icons that are already docked will stop\n"
1507 "working correctly.");
1508 break;
1509 case 2:
1510 caption = _("Shared application icon");
1511 flag = WFLAGP(wapp->main_window_desc, shared_appicon);
1512 descr = _("Use a single shared application icon for all of\n"
1513 "the instances of this application.\n");
1514 break;
1516 panel->appChk[i] = WMCreateSwitchButton(panel->appFrm);
1517 WMMoveWidget(panel->appChk[i], 10, 20 * (i + 1));
1518 WMResizeWidget(panel->appChk[i], 205, 20);
1519 WMSetButtonSelected(panel->appChk[i], flag);
1520 WMSetButtonText(panel->appChk[i], caption);
1522 WMSetBalloonTextForView(descr, WMWidgetView(panel->appChk[i]));
1525 if (WFLAGP(wwin, emulate_appicon)) {
1526 WMSetButtonEnabled(panel->appChk[1], False);
1527 WMSetButtonEnabled(panel->moreChk[7], True);
1528 } else {
1529 WMSetButtonEnabled(panel->appChk[1], True);
1530 WMSetButtonEnabled(panel->moreChk[7], False);
1532 } else {
1533 int tmp;
1535 if ((wwin->transient_for != None && wwin->transient_for != scr->root_win)
1536 || !wwin->wm_class || !wwin->wm_instance)
1537 tmp = False;
1538 else
1539 tmp = True;
1540 WMSetButtonEnabled(panel->moreChk[7], tmp);
1542 WMSetPopUpButtonItemEnabled(panel->pagePopUp, 4, False);
1543 panel->appFrm = NULL;
1546 /* if the window is a transient, don't let it have a miniaturize
1547 * button */
1548 if (wwin->transient_for != None && wwin->transient_for != scr->root_win)
1549 WMSetButtonEnabled(panel->attrChk[3], False);
1550 else
1551 WMSetButtonEnabled(panel->attrChk[3], True);
1553 if (!wwin->wm_class && !wwin->wm_instance) {
1554 WMSetPopUpButtonItemEnabled(panel->pagePopUp, 0, False);
1557 WMRealizeWidget(panel->win);
1559 WMMapSubwidgets(panel->win);
1560 WMMapSubwidgets(panel->specFrm);
1561 WMMapSubwidgets(panel->attrFrm);
1562 WMMapSubwidgets(panel->moreFrm);
1563 WMMapSubwidgets(panel->iconFrm);
1564 WMMapSubwidgets(panel->wsFrm);
1565 if (panel->appFrm)
1566 WMMapSubwidgets(panel->appFrm);
1568 if (showSelectPanel) {
1569 WMSetPopUpButtonSelectedItem(panel->pagePopUp, 0);
1570 changePage(panel->pagePopUp, panel);
1571 } else {
1572 WMSetPopUpButtonSelectedItem(panel->pagePopUp, 1);
1573 changePage(panel->pagePopUp, panel);
1576 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, PWIDTH, PHEIGHT, 0, 0, 0);
1577 XSelectInput(dpy, parent, KeyPressMask | KeyReleaseMask);
1578 panel->parent = parent;
1579 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
1581 WMMapWidget(panel->win);
1583 XSetTransientForHint(dpy, parent, wwin->client_win);
1585 if (xpos == UNDEFINED_POS) {
1586 x = wwin->frame_x + wwin->frame->core->width / 2;
1587 y = wwin->frame_y + wwin->frame->top_width * 2;
1588 if (y + PHEIGHT > scr->scr_height)
1589 y = scr->scr_height - PHEIGHT - 30;
1590 if (x + PWIDTH > scr->scr_width)
1591 x = scr->scr_width - PWIDTH;
1592 } else {
1593 x = xpos;
1594 y = ypos;
1597 panel->frame = wManageInternalWindow(scr, parent, wwin->client_win, "Inspector", x, y, PWIDTH, PHEIGHT);
1599 if (!selectedBtn)
1600 selectedBtn = panel->defaultRb;
1602 WMSetButtonSelected(selectedBtn, True);
1604 selectSpecification(selectedBtn, panel);
1606 /* kluge to know who should get the key events */
1607 panel->frame->client_leader = WMWidgetXID(panel->win);
1609 WSETUFLAG(panel->frame, no_closable, 0);
1610 WSETUFLAG(panel->frame, no_close_button, 0);
1611 wWindowUpdateButtonImages(panel->frame);
1612 wFrameWindowShowButton(panel->frame->frame, WFF_RIGHT_BUTTON);
1613 panel->frame->frame->on_click_right = destroyInspector;
1615 wWindowMap(panel->frame);
1617 showIconFor(WMWidgetScreen(panel->alwChk), panel, wwin->wm_instance, wwin->wm_class, UPDATE_TEXT_FIELD);
1619 return panel;
1622 void wShowInspectorForWindow(WWindow * wwin)
1624 if (wwin->flags.inspector_open)
1625 return;
1627 WMSetBalloonEnabled(wwin->screen_ptr->wmscreen, wPreferences.help_balloon);
1629 make_keys();
1630 wwin->flags.inspector_open = 1;
1631 wwin->inspector = createInspectorForWindow(wwin, UNDEFINED_POS, UNDEFINED_POS, False);
1634 void wHideInspectorForWindow(WWindow * wwin)
1636 WWindow *pwin = wwin->inspector->frame;
1638 wWindowUnmap(pwin);
1639 pwin->flags.hidden = 1;
1641 wClientSetState(pwin, IconicState, None);
1644 void wUnhideInspectorForWindow(WWindow * wwin)
1646 WWindow *pwin = wwin->inspector->frame;
1648 pwin->flags.hidden = 0;
1649 pwin->flags.mapped = 1;
1650 XMapWindow(dpy, pwin->client_win);
1651 XMapWindow(dpy, pwin->frame->core->window);
1652 wClientSetState(pwin, NormalState, None);
1655 WWindow *wGetWindowOfInspectorForWindow(WWindow * wwin)
1657 if (wwin->inspector) {
1658 assert(wwin->flags.inspector_open != 0);
1660 return wwin->inspector->frame;
1661 } else
1662 return NULL;
1665 void wCloseInspectorForWindow(WWindow * wwin)
1667 WWindow *pwin = wwin->inspector->frame; /* the inspector window */
1669 (*pwin->frame->on_click_right) (NULL, pwin, NULL);