Remove warnings
[wmaker-crm.git] / src / winspector.c
blob8b14094841b40cbb7f0a830d6132aa9d34668564
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 along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23 #include "wconfig.h"
25 #include <X11/Xlib.h>
26 #include <X11/Xutil.h>
27 #include <stdlib.h>
28 #include <stdio.h>
29 #include <string.h>
30 #include <strings.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[11];
93 #else
94 WMButton *moreChk[10];
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];
121 extern WDDomain *WDWindowAttributes;
122 extern WPreferences wPreferences;
124 static InspectorPanel *panelList = NULL;
125 static WMPropList *ANoTitlebar = NULL;
126 static WMPropList *ANoResizebar;
127 static WMPropList *ANoMiniaturizeButton;
128 static WMPropList *ANoCloseButton;
129 static WMPropList *ANoBorder;
130 static WMPropList *ANoHideOthers;
131 static WMPropList *ANoMouseBindings;
132 static WMPropList *ANoKeyBindings;
133 static WMPropList *ANoAppIcon;
134 static WMPropList *AKeepOnTop;
135 static WMPropList *AKeepOnBottom;
136 static WMPropList *AOmnipresent;
137 static WMPropList *ASkipWindowList;
138 static WMPropList *ASkipSwitchPanel;
139 static WMPropList *AKeepInsideScreen;
140 static WMPropList *AUnfocusable;
141 static WMPropList *ADontFocusAcrossWorkspace;
142 static WMPropList *AAlwaysUserIcon;
143 static WMPropList *AStartMiniaturized;
144 static WMPropList *AStartMaximized;
145 static WMPropList *ADontSaveSession;
146 static WMPropList *AEmulateAppIcon;
147 static WMPropList *AFullMaximize;
148 static WMPropList *ASharedAppIcon;
149 #ifdef XKB_BUTTON_HINT
150 static WMPropList *ANoLanguageButton;
151 #endif
152 static WMPropList *AStartWorkspace;
153 static WMPropList *AIcon;
155 /* application wide options */
156 static WMPropList *AStartHidden;
157 static WMPropList *AnyWindow;
158 static WMPropList *EmptyString;
159 static WMPropList *Yes, *No;
161 #define PWIDTH 270
162 #define PHEIGHT 350
164 static char *spec_text;
165 static void applySettings(WMButton * button, InspectorPanel * panel);
167 #define UNDEFINED_POS 0xffffff
169 static InspectorPanel *createInspectorForWindow(WWindow * wwin, int xpos, int ypos, Bool showSelectPanel);
171 static void make_keys(void)
173 if (ANoTitlebar != NULL)
174 return;
176 AIcon = WMCreatePLString("Icon");
177 ANoTitlebar = WMCreatePLString("NoTitlebar");
178 ANoResizebar = WMCreatePLString("NoResizebar");
179 ANoMiniaturizeButton = WMCreatePLString("NoMiniaturizeButton");
180 ANoCloseButton = WMCreatePLString("NoCloseButton");
181 ANoBorder = WMCreatePLString("NoBorder");
182 ANoHideOthers = WMCreatePLString("NoHideOthers");
183 ANoMouseBindings = WMCreatePLString("NoMouseBindings");
184 ANoKeyBindings = WMCreatePLString("NoKeyBindings");
185 ANoAppIcon = WMCreatePLString("NoAppIcon");
186 AKeepOnTop = WMCreatePLString("KeepOnTop");
187 AKeepOnBottom = WMCreatePLString("KeepOnBottom");
188 AOmnipresent = WMCreatePLString("Omnipresent");
189 ASkipWindowList = WMCreatePLString("SkipWindowList");
190 ASkipSwitchPanel = WMCreatePLString("SkipSwitchPanel");
191 AKeepInsideScreen = WMCreatePLString("KeepInsideScreen");
192 AUnfocusable = WMCreatePLString("Unfocusable");
193 ADontFocusAcrossWorkspace = WMCreatePLString("DontFocusAcrossWorkspace");
194 AAlwaysUserIcon = WMCreatePLString("AlwaysUserIcon");
195 AStartMiniaturized = WMCreatePLString("StartMiniaturized");
196 AStartMaximized = WMCreatePLString("StartMaximized");
197 AStartHidden = WMCreatePLString("StartHidden");
198 ADontSaveSession = WMCreatePLString("DontSaveSession");
199 AEmulateAppIcon = WMCreatePLString("EmulateAppIcon");
200 AFullMaximize = WMCreatePLString("FullMaximize");
201 ASharedAppIcon = WMCreatePLString("SharedAppIcon");
202 #ifdef XKB_BUTTON_HINT
203 ANoLanguageButton = WMCreatePLString("NoLanguageButton");
204 #endif
206 AStartWorkspace = WMCreatePLString("StartWorkspace");
208 AnyWindow = WMCreatePLString("*");
209 EmptyString = WMCreatePLString("");
210 Yes = WMCreatePLString("Yes");
211 No = WMCreatePLString("No");
214 static void freeInspector(InspectorPanel * panel)
216 panel->destroyed = 1;
217 if (panel->choosingIcon)
218 return;
220 WMDestroyWidget(panel->win);
222 XDestroyWindow(dpy, panel->parent);
224 wfree(panel);
227 static void destroyInspector(WCoreWindow * foo, void *data, XEvent * event)
229 InspectorPanel *panel;
230 InspectorPanel *tmp;
232 panel = panelList;
233 while (panel->frame != data)
234 panel = panel->nextPtr;
236 if (panelList == panel)
237 panelList = panel->nextPtr;
238 else {
239 tmp = panelList;
240 while (tmp->nextPtr != panel) {
241 tmp = tmp->nextPtr;
243 tmp->nextPtr = panel->nextPtr;
245 panel->inspected->flags.inspector_open = 0;
246 panel->inspected->inspector = NULL;
248 WMRemoveNotificationObserver(panel);
250 wWindowUnmap(panel->frame);
251 wUnmanageWindow(panel->frame, True, False);
253 freeInspector(panel);
256 void wDestroyInspectorPanels(void)
258 InspectorPanel *panel;
260 while (panelList != NULL) {
261 panel = panelList;
262 panelList = panelList->nextPtr;
263 wUnmanageWindow(panel->frame, False, False);
264 WMDestroyWidget(panel->win);
266 panel->inspected->flags.inspector_open = 0;
267 panel->inspected->inspector = NULL;
269 wfree(panel);
273 static void changePage(WMPopUpButton * bPtr, InspectorPanel * panel)
275 int page;
277 page = WMGetPopUpButtonSelectedItem(bPtr);
279 if (page == 0) {
280 WMMapWidget(panel->specFrm);
281 WMMapWidget(panel->specLbl);
282 } else if (page == 1) {
283 WMMapWidget(panel->attrFrm);
284 } else if (page == 2) {
285 WMMapWidget(panel->moreFrm);
286 } else if (page == 3) {
287 WMMapWidget(panel->iconFrm);
288 WMMapWidget(panel->wsFrm);
289 } else {
290 WMMapWidget(panel->appFrm);
293 if (page != 0) {
294 WMUnmapWidget(panel->specFrm);
295 WMUnmapWidget(panel->specLbl);
297 if (page != 1)
298 WMUnmapWidget(panel->attrFrm);
299 if (page != 2)
300 WMUnmapWidget(panel->moreFrm);
301 if (page != 3) {
302 WMUnmapWidget(panel->iconFrm);
303 WMUnmapWidget(panel->wsFrm);
305 if (page != 4 && panel->appFrm)
306 WMUnmapWidget(panel->appFrm);
309 #define USE_TEXT_FIELD 1
310 #define UPDATE_TEXT_FIELD 2
311 #define REVERT_TO_DEFAULT 4
313 static int showIconFor(WMScreen * scrPtr, InspectorPanel * panel, char *wm_instance, char *wm_class, int flags)
315 WMPixmap *pixmap = (WMPixmap *) NULL;
316 char *file = NULL, *path = NULL;
317 char *db_icon = NULL;
319 if ((flags & USE_TEXT_FIELD) != 0) {
320 file = WMGetTextFieldText(panel->fileText);
321 if (file && file[0] == 0) {
322 wfree(file);
323 file = NULL;
325 } else {
326 db_icon = wDefaultGetIconFile(panel->inspected->screen_ptr, wm_instance, wm_class, False);
327 if (db_icon != NULL)
328 file = wstrdup(db_icon);
330 if (db_icon != NULL && (flags & REVERT_TO_DEFAULT) != 0) {
331 if (file)
332 file = wstrdup(db_icon);
333 flags |= UPDATE_TEXT_FIELD;
336 if ((flags & UPDATE_TEXT_FIELD) != 0) {
337 WMSetTextFieldText(panel->fileText, file);
340 if (file) {
341 path = FindImage(wPreferences.icon_path, file);
343 if (!path) {
344 char *buf;
345 int len = strlen(file) + 80;
347 buf = wmalloc(len);
348 snprintf(buf, len, _("Could not find icon \"%s\" specified for this window"), file);
349 wMessageDialog(panel->frame->screen_ptr, _("Error"), buf, _("OK"), NULL, NULL);
350 wfree(buf);
351 wfree(file);
352 return -1;
355 pixmap = WMCreatePixmapFromFile(scrPtr, path);
356 wfree(path);
358 if (!pixmap) {
359 char *buf;
360 int len = strlen(file) + 80;
362 buf = wmalloc(len);
363 snprintf(buf, len, _("Could not open specified icon \"%s\":%s"),
364 file, RMessageForError(RErrorCode));
365 wMessageDialog(panel->frame->screen_ptr, _("Error"), buf, _("OK"), NULL, NULL);
366 wfree(buf);
367 wfree(file);
368 return -1;
370 wfree(file);
373 WMSetLabelImage(panel->iconLbl, pixmap);
374 if (pixmap)
375 WMReleasePixmap(pixmap);
377 return 0;
380 #if 0
381 static void updateIcon(WMButton * button, InspectorPanel * panel)
383 showIconFor(WMWidgetScreen(button), panel, NULL, NULL, USE_TEXT_FIELD);
385 #endif
387 static int getBool(WMPropList * value)
389 char *val;
391 if (!WMIsPLString(value)) {
392 return 0;
394 if (!(val = WMGetFromPLString(value))) {
395 return 0;
398 if ((val[1] == '\0' && (val[0] == 'y' || val[0] == 'Y' || val[0] == 'T' || val[0] == 't' || val[0] == '1'))
399 || (strcasecmp(val, "YES") == 0 || strcasecmp(val, "TRUE") == 0)) {
401 return 1;
402 } else if ((val[1] == '\0'
403 && (val[0] == 'n' || val[0] == 'N' || val[0] == 'F' || val[0] == 'f' || val[0] == '0'))
404 || (strcasecmp(val, "NO") == 0 || strcasecmp(val, "FALSE") == 0)) {
406 return 0;
407 } else {
408 wwarning(_("can't convert \"%s\" to boolean"), val);
409 return 0;
413 #define UPDATE_DEFAULTS 1
414 #define IS_BOOLEAN 2
417 * Will insert the attribute = value; pair in window's list,
418 * if it's different from the defaults.
419 * Defaults means either defaults database, or attributes saved
420 * for the default window "*". This is to let one revert options that are
421 * global because they were saved for all windows ("*").
425 static int
426 insertAttribute(WMPropList * dict, WMPropList * window, WMPropList * attr, WMPropList * value, int flags)
428 WMPropList *def_win, *def_value = NULL;
429 int update = 0;
430 int modified = 0;
432 if (!(flags & UPDATE_DEFAULTS) && dict) {
433 if ((def_win = WMGetFromPLDictionary(dict, AnyWindow)) != NULL) {
434 def_value = WMGetFromPLDictionary(def_win, attr);
438 /* If we could not find defaults in database, fall to hardcoded values.
439 * Also this is true if we save defaults for all windows
441 if (!def_value)
442 def_value = ((flags & IS_BOOLEAN) != 0) ? No : EmptyString;
444 if ((flags & IS_BOOLEAN))
445 update = (getBool(value) != getBool(def_value));
446 else {
447 update = !WMIsPropListEqualTo(value, def_value);
450 if (update) {
451 WMPutInPLDictionary(window, attr, value);
452 modified = 1;
455 return modified;
458 static void saveSettings(WMButton * button, InspectorPanel * panel)
460 WWindow *wwin = panel->inspected;
461 WDDomain *db = WDWindowAttributes;
462 WMPropList *dict = db->dictionary;
463 WMPropList *winDic, *appDic, *value, *key, *key2;
464 char *icon_file;
465 int flags = 0;
466 int different = 0, different2 = 0;
468 /* Save will apply the changes and save them */
469 applySettings(panel->applyBtn, panel);
471 if (WMGetButtonSelected(panel->instRb) != 0)
472 key = WMCreatePLString(wwin->wm_instance);
473 else if (WMGetButtonSelected(panel->clsRb) != 0)
474 key = WMCreatePLString(wwin->wm_class);
475 else if (WMGetButtonSelected(panel->bothRb) != 0) {
476 char *buffer;
478 buffer = StrConcatDot(wwin->wm_instance, wwin->wm_class);
479 key = WMCreatePLString(buffer);
480 wfree(buffer);
481 } else if (WMGetButtonSelected(panel->defaultRb) != 0) {
482 key = WMRetainPropList(AnyWindow);
483 flags = UPDATE_DEFAULTS;
484 } else
485 key = NULL;
487 if (!key)
488 return;
490 if (!dict) {
491 dict = WMCreatePLDictionary(NULL, NULL);
492 if (dict) {
493 db->dictionary = dict;
494 } else {
495 WMReleasePropList(key);
496 return;
500 if (showIconFor(WMWidgetScreen(button), panel, NULL, NULL, USE_TEXT_FIELD) < 0)
501 return;
503 WMPLSetCaseSensitive(True);
505 winDic = WMCreatePLDictionary(NULL, NULL);
506 appDic = WMCreatePLDictionary(NULL, NULL);
508 /* Update icon for window */
509 icon_file = WMGetTextFieldText(panel->fileText);
510 if (icon_file) {
511 if (icon_file[0] != 0) {
512 value = WMCreatePLString(icon_file);
513 different |= insertAttribute(dict, winDic, AIcon, value, flags);
514 different2 |= insertAttribute(dict, appDic, AIcon, value, flags);
515 WMReleasePropList(value);
517 wfree(icon_file);
521 int i = WMGetPopUpButtonSelectedItem(panel->wsP);
523 i--;
525 if (i >= 0 && i < panel->frame->screen_ptr->workspace_count) {
526 value = WMCreatePLString(panel->frame->screen_ptr->workspaces[i]->name);
527 different |= insertAttribute(dict, winDic, AStartWorkspace, value, flags);
528 WMReleasePropList(value);
532 flags |= IS_BOOLEAN;
534 value = (WMGetButtonSelected(panel->alwChk) != 0) ? Yes : No;
535 different |= insertAttribute(dict, winDic, AAlwaysUserIcon, value, flags);
537 value = (WMGetButtonSelected(panel->attrChk[0]) != 0) ? Yes : No;
538 different |= insertAttribute(dict, winDic, ANoTitlebar, value, flags);
540 value = (WMGetButtonSelected(panel->attrChk[1]) != 0) ? Yes : No;
541 different |= insertAttribute(dict, winDic, ANoResizebar, value, flags);
543 value = (WMGetButtonSelected(panel->attrChk[2]) != 0) ? Yes : No;
544 different |= insertAttribute(dict, winDic, ANoCloseButton, value, flags);
546 value = (WMGetButtonSelected(panel->attrChk[3]) != 0) ? Yes : No;
547 different |= insertAttribute(dict, winDic, ANoMiniaturizeButton, value, flags);
549 value = (WMGetButtonSelected(panel->attrChk[4]) != 0) ? Yes : No;
550 different |= insertAttribute(dict, winDic, ANoBorder, value, flags);
552 value = (WMGetButtonSelected(panel->attrChk[5]) != 0) ? Yes : No;
553 different |= insertAttribute(dict, winDic, AKeepOnTop, value, flags);
555 value = (WMGetButtonSelected(panel->attrChk[6]) != 0) ? Yes : No;
556 different |= insertAttribute(dict, winDic, AKeepOnBottom, value, flags);
558 value = (WMGetButtonSelected(panel->attrChk[7]) != 0) ? Yes : No;
559 different |= insertAttribute(dict, winDic, AOmnipresent, value, flags);
561 value = (WMGetButtonSelected(panel->attrChk[8]) != 0) ? Yes : No;
562 different |= insertAttribute(dict, winDic, AStartMiniaturized, value, flags);
564 value = (WMGetButtonSelected(panel->attrChk[9]) != 0) ? Yes : No;
565 different |= insertAttribute(dict, winDic, AStartMaximized, value, flags);
567 value = (WMGetButtonSelected(panel->attrChk[10]) != 0) ? Yes : No;
568 different |= insertAttribute(dict, winDic, AFullMaximize, value, flags);
570 value = (WMGetButtonSelected(panel->moreChk[0]) != 0) ? Yes : No;
571 different |= insertAttribute(dict, winDic, ANoKeyBindings, value, flags);
573 value = (WMGetButtonSelected(panel->moreChk[1]) != 0) ? Yes : No;
574 different |= insertAttribute(dict, winDic, ANoMouseBindings, value, flags);
576 value = (WMGetButtonSelected(panel->moreChk[2]) != 0) ? Yes : No;
577 different |= insertAttribute(dict, winDic, ASkipWindowList, value, flags);
579 value = (WMGetButtonSelected(panel->moreChk[3]) != 0) ? Yes : No;
580 different |= insertAttribute(dict, winDic, ASkipSwitchPanel, value, flags);
582 value = (WMGetButtonSelected(panel->moreChk[4]) != 0) ? Yes : No;
583 different |= insertAttribute(dict, winDic, AUnfocusable, value, flags);
585 value = (WMGetButtonSelected(panel->moreChk[5]) != 0) ? Yes : No;
586 different |= insertAttribute(dict, winDic, AKeepInsideScreen, value, flags);
588 value = (WMGetButtonSelected(panel->moreChk[6]) != 0) ? Yes : No;
589 different |= insertAttribute(dict, winDic, ANoHideOthers, value, flags);
591 value = (WMGetButtonSelected(panel->moreChk[7]) != 0) ? Yes : No;
592 different |= insertAttribute(dict, winDic, ADontSaveSession, value, flags);
594 value = (WMGetButtonSelected(panel->moreChk[8]) != 0) ? Yes : No;
595 different |= insertAttribute(dict, winDic, AEmulateAppIcon, value, flags);
597 value = (WMGetButtonSelected(panel->moreChk[9]) != 0) ? Yes : No;
598 different |= insertAttribute(dict, winDic, ADontFocusAcrossWorkspace, value, flags);
600 #ifdef XKB_BUTTON_HINT
601 value = (WMGetButtonSelected(panel->moreChk[10]) != 0) ? Yes : No;
602 different |= insertAttribute(dict, winDic, ANoLanguageButton, value, flags);
603 #endif
605 if (wwin->main_window != None && wApplicationOf(wwin->main_window) != NULL) {
606 value = (WMGetButtonSelected(panel->appChk[0]) != 0) ? Yes : No;
607 different2 |= insertAttribute(dict, appDic, AStartHidden, value, flags);
609 value = (WMGetButtonSelected(panel->appChk[1]) != 0) ? Yes : No;
610 different2 |= insertAttribute(dict, appDic, ANoAppIcon, value, flags);
612 value = (WMGetButtonSelected(panel->appChk[2]) != 0) ? Yes : No;
613 different2 |= insertAttribute(dict, appDic, ASharedAppIcon, value, flags);
616 if (wwin->fake_group) {
617 key2 = WMCreatePLString(wwin->fake_group->identifier);
618 if (WMIsPropListEqualTo(key, key2)) {
619 WMMergePLDictionaries(winDic, appDic, True);
620 different |= different2;
621 } else {
622 WMRemoveFromPLDictionary(dict, key2);
623 if (different2) {
624 WMPutInPLDictionary(dict, key2, appDic);
627 WMReleasePropList(key2);
628 WMReleasePropList(appDic);
629 } else if (wwin->main_window != wwin->client_win) {
630 WApplication *wapp = wApplicationOf(wwin->main_window);
632 if (wapp) {
633 char *instance = wapp->main_window_desc->wm_instance;
634 char *class = wapp->main_window_desc->wm_class;
635 char *buffer;
637 buffer = StrConcatDot(instance, class);
638 key2 = WMCreatePLString(buffer);
639 wfree(buffer);
641 if (WMIsPropListEqualTo(key, key2)) {
642 WMMergePLDictionaries(winDic, appDic, True);
643 different |= different2;
644 } else {
645 WMRemoveFromPLDictionary(dict, key2);
646 if (different2) {
647 WMPutInPLDictionary(dict, key2, appDic);
650 WMReleasePropList(key2);
651 WMReleasePropList(appDic);
653 } else {
654 WMMergePLDictionaries(winDic, appDic, True);
655 different |= different2;
656 WMReleasePropList(appDic);
659 WMRemoveFromPLDictionary(dict, key);
660 if (different) {
661 WMPutInPLDictionary(dict, key, winDic);
664 WMReleasePropList(key);
665 WMReleasePropList(winDic);
667 UpdateDomainFile(db);
669 /* clean up */
670 WMPLSetCaseSensitive(False);
673 static void makeAppIconFor(WApplication * wapp)
675 WScreen *scr = wapp->main_window_desc->screen_ptr;
677 if (wapp->app_icon)
678 return;
680 if (!WFLAGP(wapp->main_window_desc, no_appicon))
681 wapp->app_icon = wAppIconCreate(wapp->main_window_desc);
682 else
683 wapp->app_icon = NULL;
685 if (wapp->app_icon) {
686 WIcon *icon = wapp->app_icon->icon;
687 WDock *clip = scr->workspaces[scr->current_workspace]->clip;
688 int x = 0, y = 0;
690 wapp->app_icon->main_window = wapp->main_window;
692 if (clip && clip->attract_icons && wDockFindFreeSlot(clip, &x, &y)) {
693 wapp->app_icon->attracted = 1;
694 if (!wapp->app_icon->icon->shadowed) {
695 wapp->app_icon->icon->shadowed = 1;
696 wapp->app_icon->icon->force_paint = 1;
698 wDockAttachIcon(clip, wapp->app_icon, x, y);
699 } else {
700 PlaceIcon(scr, &x, &y, wGetHeadForWindow(wapp->main_window_desc));
701 wAppIconMove(wapp->app_icon, x, y);
703 if (!clip || !wapp->app_icon->attracted || !clip->collapsed)
704 XMapWindow(dpy, icon->core->window);
706 if (wPreferences.auto_arrange_icons && !wapp->app_icon->attracted)
707 wArrangeIcons(wapp->main_window_desc->screen_ptr, True);
711 static void removeAppIconFor(WApplication * wapp)
713 if (!wapp->app_icon)
714 return;
716 if (wapp->app_icon->docked && !wapp->app_icon->attracted) {
717 wapp->app_icon->running = 0;
718 /* since we keep it, we don't care if it was attracted or not */
719 wapp->app_icon->attracted = 0;
720 wapp->app_icon->icon->shadowed = 0;
721 wapp->app_icon->main_window = None;
722 wapp->app_icon->pid = 0;
723 wapp->app_icon->icon->owner = NULL;
724 wapp->app_icon->icon->icon_win = None;
725 wapp->app_icon->icon->force_paint = 1;
726 wAppIconPaint(wapp->app_icon);
727 } else if (wapp->app_icon->docked) {
728 wapp->app_icon->running = 0;
729 wDockDetach(wapp->app_icon->dock, wapp->app_icon);
730 } else {
731 wAppIconDestroy(wapp->app_icon);
733 wapp->app_icon = NULL;
734 if (wPreferences.auto_arrange_icons)
735 wArrangeIcons(wapp->main_window_desc->screen_ptr, True);
738 static void applySettings(WMButton * button, InspectorPanel * panel)
740 WWindow *wwin = panel->inspected;
741 WApplication *wapp = wApplicationOf(wwin->main_window);
742 int floating, sunken, skip_window_list;
743 int old_omnipresent;
744 int old_no_bind_keys;
745 int old_no_bind_mouse;
747 old_omnipresent = WFLAGP(wwin, omnipresent);
748 old_no_bind_keys = WFLAGP(wwin, no_bind_keys);
749 old_no_bind_mouse = WFLAGP(wwin, no_bind_mouse);
751 showIconFor(WMWidgetScreen(button), panel, NULL, NULL, USE_TEXT_FIELD);
753 /* Attributes... --> Window Attributes */
754 WSETUFLAG(wwin, no_titlebar, WMGetButtonSelected(panel->attrChk[0]));
755 WSETUFLAG(wwin, no_resizebar, WMGetButtonSelected(panel->attrChk[1]));
756 WSETUFLAG(wwin, no_close_button, WMGetButtonSelected(panel->attrChk[2]));
757 WSETUFLAG(wwin, no_miniaturize_button, WMGetButtonSelected(panel->attrChk[3]));
758 WSETUFLAG(wwin, no_border, WMGetButtonSelected(panel->attrChk[4]));
759 floating = WMGetButtonSelected(panel->attrChk[5]);
760 sunken = WMGetButtonSelected(panel->attrChk[6]);
761 WSETUFLAG(wwin, omnipresent, WMGetButtonSelected(panel->attrChk[7]));
762 WSETUFLAG(wwin, start_miniaturized, WMGetButtonSelected(panel->attrChk[8]));
763 WSETUFLAG(wwin, start_maximized, WMGetButtonSelected(panel->attrChk[9]));
764 WSETUFLAG(wwin, full_maximize, WMGetButtonSelected(panel->attrChk[10]));
766 /* Attributes... --> Advanced Options */
767 WSETUFLAG(wwin, no_bind_keys, WMGetButtonSelected(panel->moreChk[0]));
768 WSETUFLAG(wwin, no_bind_mouse, WMGetButtonSelected(panel->moreChk[1]));
769 skip_window_list = WMGetButtonSelected(panel->moreChk[2]);
770 WSETUFLAG(wwin, skip_switchpanel, WMGetButtonSelected(panel->moreChk[3]));
771 WSETUFLAG(wwin, no_focusable, WMGetButtonSelected(panel->moreChk[4]));
772 WSETUFLAG(wwin, dont_move_off, WMGetButtonSelected(panel->moreChk[5]));
773 WSETUFLAG(wwin, no_hide_others, WMGetButtonSelected(panel->moreChk[6]));
774 WSETUFLAG(wwin, dont_save_session, WMGetButtonSelected(panel->moreChk[7]));
775 WSETUFLAG(wwin, emulate_appicon, WMGetButtonSelected(panel->moreChk[8]));
776 WSETUFLAG(wwin, dont_focus_across_wksp, WMGetButtonSelected(panel->moreChk[9]));
777 #ifdef XKB_BUTTON_HINT
778 WSETUFLAG(wwin, no_language_button, WMGetButtonSelected(panel->moreChk[10]));
779 #endif
780 WSETUFLAG(wwin, always_user_icon, WMGetButtonSelected(panel->alwChk));
782 if (WFLAGP(wwin, no_titlebar) && wwin->flags.shaded)
783 wUnshadeWindow(wwin);
785 WSETUFLAG(wwin, no_shadeable, WFLAGP(wwin, no_titlebar));
787 if (floating) {
788 if (!WFLAGP(wwin, floating))
789 ChangeStackingLevel(wwin->frame->core, WMFloatingLevel);
790 } else if (sunken) {
791 if (!WFLAGP(wwin, sunken))
792 ChangeStackingLevel(wwin->frame->core, WMSunkenLevel);
793 } else {
794 if (WFLAGP(wwin, floating) || WFLAGP(wwin, sunken))
795 ChangeStackingLevel(wwin->frame->core, WMNormalLevel);
798 WSETUFLAG(wwin, sunken, sunken);
799 WSETUFLAG(wwin, floating, floating);
800 wwin->flags.omnipresent = 0;
802 if (WFLAGP(wwin, skip_window_list) != skip_window_list) {
803 WSETUFLAG(wwin, skip_window_list, skip_window_list);
804 UpdateSwitchMenu(wwin->screen_ptr, wwin, skip_window_list ? ACTION_REMOVE : ACTION_ADD);
805 } else {
806 if (WFLAGP(wwin, omnipresent) != old_omnipresent) {
807 WMPostNotificationName(WMNChangedState, wwin, "omnipresent");
811 if (WFLAGP(wwin, no_bind_keys) != old_no_bind_keys) {
812 if (WFLAGP(wwin, no_bind_keys)) {
813 XUngrabKey(dpy, AnyKey, AnyModifier, wwin->frame->core->window);
814 } else {
815 wWindowSetKeyGrabs(wwin);
819 if (WFLAGP(wwin, no_bind_mouse) != old_no_bind_mouse) {
820 wWindowResetMouseGrabs(wwin);
823 wwin->frame->flags.need_texture_change = 1;
824 wWindowConfigureBorders(wwin);
825 wFrameWindowPaint(wwin->frame);
826 wNETWMUpdateActions(wwin, False);
829 * Can't apply emulate_appicon because it will probably cause problems.
831 if (wapp) {
832 /* do application wide stuff */
833 WSETUFLAG(wapp->main_window_desc, start_hidden, WMGetButtonSelected(panel->appChk[0]));
835 WSETUFLAG(wapp->main_window_desc, no_appicon, WMGetButtonSelected(panel->appChk[1]));
837 WSETUFLAG(wapp->main_window_desc, shared_appicon, WMGetButtonSelected(panel->appChk[2]));
839 if (WFLAGP(wapp->main_window_desc, no_appicon))
840 removeAppIconFor(wapp);
841 else
842 makeAppIconFor(wapp);
844 if (wapp->app_icon && wapp->main_window == wwin->client_win) {
845 char *file = WMGetTextFieldText(panel->fileText);
847 if (file[0] == 0) {
848 wfree(file);
849 file = NULL;
851 wIconChangeImageFile(wapp->app_icon->icon, file);
852 if (file)
853 wfree(file);
854 wAppIconPaint(wapp->app_icon);
859 static void revertSettings(WMButton * button, InspectorPanel * panel)
861 WWindow *wwin = panel->inspected;
862 WApplication *wapp = wApplicationOf(wwin->main_window);
863 int i, n;
864 char *wm_instance = NULL;
865 char *wm_class = NULL;
866 int workspace, level;
868 if (panel->instRb && WMGetButtonSelected(panel->instRb) != 0)
869 wm_instance = wwin->wm_instance;
870 else if (panel->clsRb && WMGetButtonSelected(panel->clsRb) != 0)
871 wm_class = wwin->wm_class;
872 else if (panel->bothRb && WMGetButtonSelected(panel->bothRb) != 0) {
873 wm_instance = wwin->wm_instance;
874 wm_class = wwin->wm_class;
876 memset(&wwin->defined_user_flags, 0, sizeof(WWindowAttributes));
877 memset(&wwin->user_flags, 0, sizeof(WWindowAttributes));
878 memset(&wwin->client_flags, 0, sizeof(WWindowAttributes));
880 wWindowSetupInitialAttributes(wwin, &level, &workspace);
882 for (i = 0; i < 11; i++) {
883 int flag = 0;
885 switch (i) {
886 case 0:
887 flag = WFLAGP(wwin, no_titlebar);
888 break;
889 case 1:
890 flag = WFLAGP(wwin, no_resizebar);
891 break;
892 case 2:
893 flag = WFLAGP(wwin, no_close_button);
894 break;
895 case 3:
896 flag = WFLAGP(wwin, no_miniaturize_button);
897 break;
898 case 4:
899 flag = WFLAGP(wwin, no_border);
900 break;
901 case 5:
902 flag = WFLAGP(wwin, floating);
903 break;
904 case 6:
905 flag = WFLAGP(wwin, sunken);
906 break;
907 case 7:
908 flag = WFLAGP(wwin, omnipresent);
909 break;
910 case 8:
911 flag = WFLAGP(wwin, start_miniaturized);
912 break;
913 case 9:
914 flag = WFLAGP(wwin, start_maximized != 0);
915 break;
916 case 10:
917 flag = WFLAGP(wwin, full_maximize);
918 break;
920 WMSetButtonSelected(panel->attrChk[i], flag);
922 for (i = 0; i < 11; i++) {
923 int flag = 0;
925 switch (i) {
926 case 0:
927 flag = WFLAGP(wwin, no_bind_keys);
928 break;
929 case 1:
930 flag = WFLAGP(wwin, no_bind_mouse);
931 break;
932 case 2:
933 flag = WFLAGP(wwin, skip_window_list);
934 break;
935 case 3:
936 flag = WFLAGP(wwin, skip_switchpanel);
937 break;
938 case 4:
939 flag = WFLAGP(wwin, no_focusable);
940 break;
941 case 5:
942 flag = WFLAGP(wwin, dont_move_off);
943 break;
944 case 6:
945 flag = WFLAGP(wwin, no_hide_others);
946 break;
947 case 7:
948 flag = WFLAGP(wwin, dont_save_session);
949 break;
950 case 8:
951 flag = WFLAGP(wwin, emulate_appicon);
952 break;
953 case 9:
954 flag = WFLAGP(wwin, dont_focus_across_wksp);
955 break;
956 #ifdef XKB_BUTTON_HINT
957 case 10:
958 flag = WFLAGP(wwin, no_language_button);
959 break;
960 #endif
962 WMSetButtonSelected(panel->moreChk[i], flag);
964 if (panel->appFrm && wapp) {
965 for (i = 0; i < 3; i++) {
966 int flag = 0;
968 switch (i) {
969 case 0:
970 flag = WFLAGP(wapp->main_window_desc, start_hidden);
971 break;
972 case 1:
973 flag = WFLAGP(wapp->main_window_desc, no_appicon);
974 break;
975 case 2:
976 flag = WFLAGP(wapp->main_window_desc, shared_appicon);
977 break;
979 WMSetButtonSelected(panel->appChk[i], flag);
982 WMSetButtonSelected(panel->alwChk, WFLAGP(wwin, always_user_icon));
984 showIconFor(WMWidgetScreen(panel->alwChk), panel, wm_instance, wm_class, REVERT_TO_DEFAULT);
986 n = wDefaultGetStartWorkspace(wwin->screen_ptr, wm_instance, wm_class);
988 if (n >= 0 && n < wwin->screen_ptr->workspace_count) {
989 WMSetPopUpButtonSelectedItem(panel->wsP, n + 1);
990 } else {
991 WMSetPopUpButtonSelectedItem(panel->wsP, 0);
994 /* must auto apply, so that there wno't be internal
995 * inconsistencies between the state in the flags and
996 * the actual state of the window */
997 applySettings(panel->applyBtn, panel);
1000 static void chooseIconCallback(WMWidget * self, void *clientData)
1002 char *file;
1003 InspectorPanel *panel = (InspectorPanel *) clientData;
1004 int result;
1006 panel->choosingIcon = 1;
1008 WMSetButtonEnabled(panel->browseIconBtn, False);
1010 result = wIconChooserDialog(panel->frame->screen_ptr, &file,
1011 panel->inspected->wm_instance, panel->inspected->wm_class);
1013 panel->choosingIcon = 0;
1015 if (!panel->destroyed) { /* kluge */
1016 if (result) {
1017 WMSetTextFieldText(panel->fileText, file);
1018 showIconFor(WMWidgetScreen(self), panel, NULL, NULL, USE_TEXT_FIELD);
1019 wfree(file);
1021 WMSetButtonEnabled(panel->browseIconBtn, True);
1022 } else {
1023 freeInspector(panel);
1027 static void textEditedObserver(void *observerData, WMNotification * notification)
1029 InspectorPanel *panel = (InspectorPanel *) observerData;
1031 if ((long)WMGetNotificationClientData(notification) != WMReturnTextMovement)
1032 return;
1034 showIconFor(WMWidgetScreen(panel->win), panel, NULL, NULL, USE_TEXT_FIELD);
1036 WMPerformButtonClick(panel->updateIconBtn);
1040 static void selectSpecification(WMWidget * bPtr, void *data)
1042 InspectorPanel *panel = (InspectorPanel *) data;
1043 char *str;
1044 WWindow *wwin = panel->inspected;
1045 int len;
1047 if (bPtr == panel->defaultRb && (wwin->wm_instance || wwin->wm_class)) {
1048 WMSetButtonEnabled(panel->applyBtn, False);
1049 } else {
1050 WMSetButtonEnabled(panel->applyBtn, True);
1053 len = 16 + strlen(wwin->wm_instance ? wwin->wm_instance : "?")
1054 + strlen(wwin->wm_class ? wwin->wm_class : "?");
1056 str = wmalloc(len);
1058 snprintf(str, len, _("Inspecting %s.%s"),
1059 wwin->wm_instance ? wwin->wm_instance : "?", wwin->wm_class ? wwin->wm_class : "?");
1061 wFrameWindowChangeTitle(panel->frame->frame, str);
1063 wfree(str);
1066 static void selectWindow(WMWidget * bPtr, void *data)
1068 InspectorPanel *panel = (InspectorPanel *) data;
1069 WWindow *wwin = panel->inspected;
1070 WScreen *scr = wwin->screen_ptr;
1071 XEvent event;
1072 WWindow *iwin;
1074 if (XGrabPointer(dpy, scr->root_win, True,
1075 ButtonPressMask, GrabModeAsync, GrabModeAsync, None,
1076 wCursor[WCUR_SELECT], CurrentTime) != GrabSuccess) {
1077 wwarning("could not grab mouse pointer");
1078 return;
1081 WMSetLabelText(panel->specLbl, _("Click in the window you wish to inspect."));
1083 WMMaskEvent(dpy, ButtonPressMask, &event);
1085 XUngrabPointer(dpy, CurrentTime);
1087 iwin = wWindowFor(event.xbutton.subwindow);
1089 if (iwin && !iwin->flags.internal_window && iwin != wwin && !iwin->flags.inspector_open) {
1091 iwin->flags.inspector_open = 1;
1092 iwin->inspector = createInspectorForWindow(iwin,
1093 panel->frame->frame_x, panel->frame->frame_y, True);
1094 wCloseInspectorForWindow(wwin);
1095 } else {
1096 WMSetLabelText(panel->specLbl, spec_text);
1100 static InspectorPanel *createInspectorForWindow(WWindow * wwin, int xpos, int ypos, Bool showSelectPanel)
1102 WScreen *scr = wwin->screen_ptr;
1103 InspectorPanel *panel;
1104 Window parent;
1105 int i;
1106 int x, y;
1107 int btn_width, frame_width;
1108 WMButton *selectedBtn = NULL;
1109 #ifdef wrong_behaviour
1110 WMPixmap *pixmap;
1111 #endif
1113 spec_text = _("The configuration will apply to all\n"
1114 "windows that have their WM_CLASS\n"
1115 "property set to the above selected\n" "name, when saved.");
1117 panel = wmalloc(sizeof(InspectorPanel));
1118 memset(panel, 0, sizeof(InspectorPanel));
1120 panel->destroyed = 0;
1122 panel->inspected = wwin;
1124 panel->nextPtr = panelList;
1125 panelList = panel;
1127 panel->win = WMCreateWindow(scr->wmscreen, "windowInspector");
1128 WMResizeWidget(panel->win, PWIDTH, PHEIGHT);
1130 /**** create common stuff ****/
1132 /* command buttons */
1133 /* (PWIDTH - (left and right margin) - (btn interval)) / 3 */
1134 btn_width = (PWIDTH - (2 * 15) - (2 * 10)) / 3;
1135 panel->saveBtn = WMCreateCommandButton(panel->win);
1136 WMSetButtonAction(panel->saveBtn, (WMAction *) saveSettings, panel);
1137 WMMoveWidget(panel->saveBtn, (2 * (btn_width + 10)) + 15, 310);
1138 WMSetButtonText(panel->saveBtn, _("Save"));
1139 WMResizeWidget(panel->saveBtn, btn_width, 28);
1140 if (wPreferences.flags.noupdates || !(wwin->wm_class || wwin->wm_instance))
1141 WMSetButtonEnabled(panel->saveBtn, False);
1143 panel->applyBtn = WMCreateCommandButton(panel->win);
1144 WMSetButtonAction(panel->applyBtn, (WMAction *) applySettings, panel);
1145 WMMoveWidget(panel->applyBtn, btn_width + 10 + 15, 310);
1146 WMSetButtonText(panel->applyBtn, _("Apply"));
1147 WMResizeWidget(panel->applyBtn, btn_width, 28);
1149 panel->revertBtn = WMCreateCommandButton(panel->win);
1150 WMSetButtonAction(panel->revertBtn, (WMAction *) revertSettings, panel);
1151 WMMoveWidget(panel->revertBtn, 15, 310);
1152 WMSetButtonText(panel->revertBtn, _("Reload"));
1153 WMResizeWidget(panel->revertBtn, btn_width, 28);
1155 /* page selection popup button */
1156 panel->pagePopUp = WMCreatePopUpButton(panel->win);
1157 WMSetPopUpButtonAction(panel->pagePopUp, (WMAction *) changePage, panel);
1158 WMMoveWidget(panel->pagePopUp, 25, 15);
1159 WMResizeWidget(panel->pagePopUp, PWIDTH - 50, 20);
1161 WMAddPopUpButtonItem(panel->pagePopUp, _("Window Specification"));
1162 WMAddPopUpButtonItem(panel->pagePopUp, _("Window Attributes"));
1163 WMAddPopUpButtonItem(panel->pagePopUp, _("Advanced Options"));
1164 WMAddPopUpButtonItem(panel->pagePopUp, _("Icon and Initial Workspace"));
1165 WMAddPopUpButtonItem(panel->pagePopUp, _("Application Specific"));
1167 /**** window spec ****/
1168 frame_width = PWIDTH - (2 * 15);
1170 panel->specFrm = WMCreateFrame(panel->win);
1171 WMSetFrameTitle(panel->specFrm, _("Window Specification"));
1172 WMMoveWidget(panel->specFrm, 15, 65);
1173 WMResizeWidget(panel->specFrm, frame_width, 145);
1175 panel->defaultRb = WMCreateRadioButton(panel->specFrm);
1176 WMMoveWidget(panel->defaultRb, 10, 78);
1177 WMResizeWidget(panel->defaultRb, frame_width - (2 * 10), 20);
1178 WMSetButtonText(panel->defaultRb, _("Defaults for all windows"));
1179 WMSetButtonSelected(panel->defaultRb, False);
1180 WMSetButtonAction(panel->defaultRb, selectSpecification, panel);
1182 if (wwin->wm_class && wwin->wm_instance) {
1183 char *str, *tmp;
1185 tmp = wstrconcat(wwin->wm_instance, ".");
1186 str = wstrconcat(tmp, wwin->wm_class);
1188 panel->bothRb = WMCreateRadioButton(panel->specFrm);
1189 WMMoveWidget(panel->bothRb, 10, 18);
1190 WMResizeWidget(panel->bothRb, frame_width - (2 * 10), 20);
1191 WMSetButtonText(panel->bothRb, str);
1192 wfree(tmp);
1193 wfree(str);
1194 WMGroupButtons(panel->defaultRb, panel->bothRb);
1196 if (!selectedBtn)
1197 selectedBtn = panel->bothRb;
1199 WMSetButtonAction(panel->bothRb, selectSpecification, panel);
1202 if (wwin->wm_instance) {
1203 panel->instRb = WMCreateRadioButton(panel->specFrm);
1204 WMMoveWidget(panel->instRb, 10, 38);
1205 WMResizeWidget(panel->instRb, frame_width - (2 * 10), 20);
1206 WMSetButtonText(panel->instRb, wwin->wm_instance);
1207 WMGroupButtons(panel->defaultRb, panel->instRb);
1209 if (!selectedBtn)
1210 selectedBtn = panel->instRb;
1212 WMSetButtonAction(panel->instRb, selectSpecification, panel);
1215 if (wwin->wm_class) {
1216 panel->clsRb = WMCreateRadioButton(panel->specFrm);
1217 WMMoveWidget(panel->clsRb, 10, 58);
1218 WMResizeWidget(panel->clsRb, frame_width - (2 * 10), 20);
1219 WMSetButtonText(panel->clsRb, wwin->wm_class);
1220 WMGroupButtons(panel->defaultRb, panel->clsRb);
1222 if (!selectedBtn)
1223 selectedBtn = panel->clsRb;
1225 WMSetButtonAction(panel->clsRb, selectSpecification, panel);
1228 panel->selWinB = WMCreateCommandButton(panel->specFrm);
1229 WMMoveWidget(panel->selWinB, 20, 145 - 24 - 10);
1230 WMResizeWidget(panel->selWinB, frame_width - 2 * 10 - 20, 24);
1231 WMSetButtonText(panel->selWinB, _("Select window"));
1232 WMSetButtonAction(panel->selWinB, selectWindow, panel);
1234 panel->specLbl = WMCreateLabel(panel->win);
1235 WMMoveWidget(panel->specLbl, 15, 210);
1236 WMResizeWidget(panel->specLbl, frame_width, 100);
1237 WMSetLabelText(panel->specLbl, spec_text);
1238 WMSetLabelWraps(panel->specLbl, True);
1240 WMSetLabelTextAlignment(panel->specLbl, WALeft);
1242 /**** attributes ****/
1243 panel->attrFrm = WMCreateFrame(panel->win);
1244 WMSetFrameTitle(panel->attrFrm, _("Attributes"));
1245 WMMoveWidget(panel->attrFrm, 15, 45);
1246 WMResizeWidget(panel->attrFrm, frame_width, 250);
1248 for (i = 0; i < 11; i++) {
1249 char *caption = NULL;
1250 int flag = 0;
1251 char *descr = NULL;
1253 switch (i) {
1254 case 0:
1255 caption = _("Disable titlebar");
1256 flag = WFLAGP(wwin, no_titlebar);
1257 descr = _("Remove the titlebar of this window.\n"
1258 "To access the window commands menu of a window\n"
1259 "without it's titlebar, press Control+Esc (or the\n"
1260 "equivalent shortcut, if you changed the default\n" "settings).");
1261 break;
1262 case 1:
1263 caption = _("Disable resizebar");
1264 flag = WFLAGP(wwin, no_resizebar);
1265 descr = _("Remove the resizebar of this window.");
1266 break;
1267 case 2:
1268 caption = _("Disable close button");
1269 flag = WFLAGP(wwin, no_close_button);
1270 descr = _("Remove the `close window' button of this window.");
1271 break;
1272 case 3:
1273 caption = _("Disable miniaturize button");
1274 flag = WFLAGP(wwin, no_miniaturize_button);
1275 descr = _("Remove the `miniaturize window' button of the window.");
1276 break;
1277 case 4:
1278 caption = _("Disable border");
1279 flag = WFLAGP(wwin, no_border);
1280 descr = _("Remove the 1 pixel black border around the window.");
1281 break;
1282 case 5:
1283 caption = _("Keep on top (floating)");
1284 flag = WFLAGP(wwin, floating);
1285 descr = _("Keep the window over other windows, not allowing\n" "them to cover it.");
1286 break;
1287 case 6:
1288 caption = _("Keep at bottom (sunken)");
1289 flag = WFLAGP(wwin, sunken);
1290 descr = _("Keep the window under all other windows.");
1291 break;
1292 case 7:
1293 caption = _("Omnipresent");
1294 flag = WFLAGP(wwin, omnipresent);
1295 descr = _("Make window present in all workspaces.");
1296 break;
1297 case 8:
1298 caption = _("Start miniaturized");
1299 flag = WFLAGP(wwin, start_miniaturized);
1300 descr = _("Make the window be automatically miniaturized when it's\n" "first shown.");
1301 break;
1302 case 9:
1303 caption = _("Start maximized");
1304 flag = WFLAGP(wwin, start_maximized != 0);
1305 descr = _("Make the window be automatically maximized when it's\n" "first shown.");
1306 break;
1307 case 10:
1308 caption = _("Full screen maximization");
1309 flag = WFLAGP(wwin, full_maximize);
1310 descr = _("Make the window use the whole screen space when it's\n"
1311 "maximized. The titlebar and resizebar will be moved\n"
1312 "to outside the screen.");
1313 break;
1315 panel->attrChk[i] = WMCreateSwitchButton(panel->attrFrm);
1316 WMMoveWidget(panel->attrChk[i], 10, 20 * (i + 1));
1317 WMResizeWidget(panel->attrChk[i], frame_width - 15, 20);
1318 WMSetButtonSelected(panel->attrChk[i], flag);
1319 WMSetButtonText(panel->attrChk[i], caption);
1321 WMSetBalloonTextForView(descr, WMWidgetView(panel->attrChk[i]));
1324 /**** more attributes ****/
1325 panel->moreFrm = WMCreateFrame(panel->win);
1326 WMSetFrameTitle(panel->moreFrm, _("Advanced"));
1327 WMMoveWidget(panel->moreFrm, 15, 45);
1328 WMResizeWidget(panel->moreFrm, frame_width, 250);
1330 for (i = 0;
1331 #ifdef XKB_BUTTON_HINT
1332 i < 11;
1333 #else
1334 i < 10;
1335 #endif
1336 i++) {
1337 char *caption = NULL;
1338 int flag = 0;
1339 char *descr = NULL;
1341 switch (i) {
1342 case 0:
1343 caption = _("Do not bind keyboard shortcuts");
1344 flag = WFLAGP(wwin, no_bind_keys);
1345 descr = _("Do not bind keyboard shortcuts from Window Maker\n"
1346 "when this window is focused. This will allow the\n"
1347 "window to receive all key combinations regardless\n"
1348 "of your shortcut configuration.");
1349 break;
1350 case 1:
1351 caption = _("Do not bind mouse clicks");
1352 flag = WFLAGP(wwin, no_bind_mouse);
1353 descr = _("Do not bind mouse actions, such as `Alt'+drag\n"
1354 "in the window (when alt is the modifier you have\n" "configured).");
1355 break;
1356 case 2:
1357 caption = _("Do not show in the window list");
1358 flag = WFLAGP(wwin, skip_window_list);
1359 descr = _("Do not list the window in the window list menu.");
1360 break;
1361 case 3:
1362 caption = _("Do not show in the switch panel");
1363 flag = WFLAGP(wwin, skip_switchpanel);
1364 descr = _("Do not include in switchpanel while alternating windows.");
1365 break;
1366 case 4:
1367 caption = _("Do not let it take focus");
1368 flag = WFLAGP(wwin, no_focusable);
1369 descr = _("Do not let the window take keyboard focus when you\n" "click on it.");
1370 break;
1371 case 5:
1372 caption = _("Keep inside screen");
1373 flag = WFLAGP(wwin, dont_move_off);
1374 descr = _("Do not allow the window to move itself completely\n"
1375 "outside the screen. For bug compatibility.\n");
1376 break;
1377 case 6:
1378 caption = _("Ignore 'Hide Others'");
1379 flag = WFLAGP(wwin, no_hide_others);
1380 descr = _("Do not hide the window when issuing the\n" "`HideOthers' command.");
1381 break;
1382 case 7:
1383 caption = _("Ignore 'Save Session'");
1384 flag = WFLAGP(wwin, dont_save_session);
1385 descr = _("Do not save the associated application in the\n"
1386 "session's state, so that it won't be restarted\n"
1387 "together with other applications when Window Maker\n" "starts.");
1388 break;
1389 case 8:
1390 caption = _("Emulate application icon");
1391 flag = WFLAGP(wwin, emulate_appicon);
1392 descr = _("Make this window act as an application that provides\n"
1393 "enough information to Window Maker for a dockable\n"
1394 "application icon to be created.");
1395 break;
1396 case 9:
1397 caption = _("Don't focus across workspaces");
1398 flag = WFLAGP(wwin, dont_focus_across_wksp);
1399 descr = _("Do not allow Window Maker to switch workspace to satisfy\n"
1400 "a focus request (useful e.g. in the case of a multiple-tab\n"
1401 "firefox opening in a different workspace).");
1402 break;
1403 #ifdef XKB_BUTTON_HINT
1404 case 10:
1405 caption = _("Disable language button");
1406 flag = WFLAGP(wwin, no_language_button);
1407 descr = _("Remove the `toggle language' button of the window.");
1408 break;
1409 #endif
1411 panel->moreChk[i] = WMCreateSwitchButton(panel->moreFrm);
1412 WMMoveWidget(panel->moreChk[i], 10, 20 * (i + 1));
1413 WMResizeWidget(panel->moreChk[i], frame_width - 15, 20);
1414 WMSetButtonSelected(panel->moreChk[i], flag);
1415 WMSetButtonText(panel->moreChk[i], caption);
1417 WMSetBalloonTextForView(descr, WMWidgetView(panel->moreChk[i]));
1420 /* miniwindow/workspace */
1421 panel->iconFrm = WMCreateFrame(panel->win);
1422 WMMoveWidget(panel->iconFrm, 15, 50);
1423 WMResizeWidget(panel->iconFrm, PWIDTH - (2 * 15), 170);
1424 WMSetFrameTitle(panel->iconFrm, _("Miniwindow Image"));
1426 panel->iconLbl = WMCreateLabel(panel->iconFrm);
1427 WMMoveWidget(panel->iconLbl, PWIDTH - (2 * 15) - 22 - 64, 20);
1428 WMResizeWidget(panel->iconLbl, 64, 64);
1429 WMSetLabelRelief(panel->iconLbl, WRGroove);
1430 WMSetLabelImagePosition(panel->iconLbl, WIPImageOnly);
1432 panel->browseIconBtn = WMCreateCommandButton(panel->iconFrm);
1433 WMSetButtonAction(panel->browseIconBtn, chooseIconCallback, panel);
1434 WMMoveWidget(panel->browseIconBtn, 22, 32);
1435 WMResizeWidget(panel->browseIconBtn, 120, 26);
1436 WMSetButtonText(panel->browseIconBtn, _("Browse..."));
1438 #ifdef wrong_behaviour
1439 WMSetButtonImagePosition(panel->updateIconBtn, WIPRight);
1440 pixmap = WMGetSystemPixmap(scr->wmscreen, WSIReturnArrow);
1441 WMSetButtonImage(panel->updateIconBtn, pixmap);
1442 WMReleasePixmap(pixmap);
1443 pixmap = WMGetSystemPixmap(scr->wmscreen, WSIHighlightedReturnArrow);
1444 WMSetButtonAltImage(panel->updateIconBtn, pixmap);
1445 WMReleasePixmap(pixmap);
1446 #endif
1448 panel->fileLbl = WMCreateLabel(panel->iconFrm);
1449 WMMoveWidget(panel->fileLbl, 20, 85);
1450 WMResizeWidget(panel->fileLbl, PWIDTH - (2 * 15) - (2 * 20), 14);
1451 WMSetLabelText(panel->fileLbl, _("Icon filename:"));
1453 panel->fileText = WMCreateTextField(panel->iconFrm);
1454 WMMoveWidget(panel->fileText, 20, 105);
1455 WMResizeWidget(panel->fileText, PWIDTH - (2 * 20) - (2 * 15), 20);
1456 WMSetTextFieldText(panel->fileText, NULL);
1457 WMAddNotificationObserver(textEditedObserver, panel, WMTextDidEndEditingNotification, panel->fileText);
1459 panel->alwChk = WMCreateSwitchButton(panel->iconFrm);
1460 WMMoveWidget(panel->alwChk, 20, 130);
1461 WMResizeWidget(panel->alwChk, PWIDTH - (2 * 15) - (2 * 15), 30);
1462 WMSetButtonText(panel->alwChk, _("Ignore client supplied icon"));
1463 WMSetButtonSelected(panel->alwChk, WFLAGP(wwin, always_user_icon));
1465 panel->wsFrm = WMCreateFrame(panel->win);
1466 WMMoveWidget(panel->wsFrm, 15, 225);
1467 WMResizeWidget(panel->wsFrm, PWIDTH - (2 * 15), 70);
1468 WMSetFrameTitle(panel->wsFrm, _("Initial Workspace"));
1470 WMSetBalloonTextForView(_("The workspace to place the window when it's"
1471 "first shown."), WMWidgetView(panel->wsFrm));
1473 panel->wsP = WMCreatePopUpButton(panel->wsFrm);
1474 WMMoveWidget(panel->wsP, 20, 30);
1475 WMResizeWidget(panel->wsP, PWIDTH - (2 * 15) - (2 * 20), 20);
1476 WMAddPopUpButtonItem(panel->wsP, _("Nowhere in particular"));
1477 for (i = 0; i < wwin->screen_ptr->workspace_count; i++) {
1478 WMAddPopUpButtonItem(panel->wsP, scr->workspaces[i]->name);
1481 i = wDefaultGetStartWorkspace(wwin->screen_ptr, wwin->wm_instance, wwin->wm_class);
1482 if (i >= 0 && i <= wwin->screen_ptr->workspace_count) {
1483 WMSetPopUpButtonSelectedItem(panel->wsP, i + 1);
1484 } else {
1485 WMSetPopUpButtonSelectedItem(panel->wsP, 0);
1488 /* application wide attributes */
1489 if (wwin->main_window != None) {
1490 WApplication *wapp = wApplicationOf(wwin->main_window);
1492 panel->appFrm = WMCreateFrame(panel->win);
1493 WMSetFrameTitle(panel->appFrm, _("Application Attributes"));
1494 WMMoveWidget(panel->appFrm, 15, 50);
1495 WMResizeWidget(panel->appFrm, frame_width, 240);
1497 for (i = 0; i < 3; i++) {
1498 char *caption = NULL;
1499 int flag = 0;
1500 char *descr = NULL;
1502 switch (i) {
1503 case 0:
1504 caption = _("Start hidden");
1505 flag = WFLAGP(wapp->main_window_desc, start_hidden);
1506 descr = _("Automatically hide application when it's started.");
1507 break;
1508 case 1:
1509 caption = _("No application icon");
1510 flag = WFLAGP(wapp->main_window_desc, no_appicon);
1511 descr = _("Disable the application icon for the application.\n"
1512 "Note that you won't be able to dock it anymore,\n"
1513 "and any icons that are already docked will stop\n"
1514 "working correctly.");
1515 break;
1516 case 2:
1517 caption = _("Shared application icon");
1518 flag = WFLAGP(wapp->main_window_desc, shared_appicon);
1519 descr = _("Use a single shared application icon for all of\n"
1520 "the instances of this application.\n");
1521 break;
1523 panel->appChk[i] = WMCreateSwitchButton(panel->appFrm);
1524 WMMoveWidget(panel->appChk[i], 10, 20 * (i + 1));
1525 WMResizeWidget(panel->appChk[i], 205, 20);
1526 WMSetButtonSelected(panel->appChk[i], flag);
1527 WMSetButtonText(panel->appChk[i], caption);
1529 WMSetBalloonTextForView(descr, WMWidgetView(panel->appChk[i]));
1532 if (WFLAGP(wwin, emulate_appicon)) {
1533 WMSetButtonEnabled(panel->appChk[1], False);
1534 WMSetButtonEnabled(panel->moreChk[7], True);
1535 } else {
1536 WMSetButtonEnabled(panel->appChk[1], True);
1537 WMSetButtonEnabled(panel->moreChk[7], False);
1539 } else {
1540 int tmp;
1542 if ((wwin->transient_for != None && wwin->transient_for != scr->root_win)
1543 || !wwin->wm_class || !wwin->wm_instance)
1544 tmp = False;
1545 else
1546 tmp = True;
1547 WMSetButtonEnabled(panel->moreChk[7], tmp);
1549 WMSetPopUpButtonItemEnabled(panel->pagePopUp, 4, False);
1550 panel->appFrm = NULL;
1553 /* if the window is a transient, don't let it have a miniaturize
1554 * button */
1555 if (wwin->transient_for != None && wwin->transient_for != scr->root_win)
1556 WMSetButtonEnabled(panel->attrChk[3], False);
1557 else
1558 WMSetButtonEnabled(panel->attrChk[3], True);
1560 if (!wwin->wm_class && !wwin->wm_instance) {
1561 WMSetPopUpButtonItemEnabled(panel->pagePopUp, 0, False);
1564 WMRealizeWidget(panel->win);
1566 WMMapSubwidgets(panel->win);
1567 WMMapSubwidgets(panel->specFrm);
1568 WMMapSubwidgets(panel->attrFrm);
1569 WMMapSubwidgets(panel->moreFrm);
1570 WMMapSubwidgets(panel->iconFrm);
1571 WMMapSubwidgets(panel->wsFrm);
1572 if (panel->appFrm)
1573 WMMapSubwidgets(panel->appFrm);
1575 if (showSelectPanel) {
1576 WMSetPopUpButtonSelectedItem(panel->pagePopUp, 0);
1577 changePage(panel->pagePopUp, panel);
1578 } else {
1579 WMSetPopUpButtonSelectedItem(panel->pagePopUp, 1);
1580 changePage(panel->pagePopUp, panel);
1583 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, PWIDTH, PHEIGHT, 0, 0, 0);
1584 XSelectInput(dpy, parent, KeyPressMask | KeyReleaseMask);
1585 panel->parent = parent;
1586 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
1588 WMMapWidget(panel->win);
1590 XSetTransientForHint(dpy, parent, wwin->client_win);
1592 if (xpos == UNDEFINED_POS) {
1593 x = wwin->frame_x + wwin->frame->core->width / 2;
1594 y = wwin->frame_y + wwin->frame->top_width * 2;
1595 if (y + PHEIGHT > scr->scr_height)
1596 y = scr->scr_height - PHEIGHT - 30;
1597 if (x + PWIDTH > scr->scr_width)
1598 x = scr->scr_width - PWIDTH;
1599 } else {
1600 x = xpos;
1601 y = ypos;
1604 panel->frame = wManageInternalWindow(scr, parent, wwin->client_win, "Inspector", x, y, PWIDTH, PHEIGHT);
1606 if (!selectedBtn)
1607 selectedBtn = panel->defaultRb;
1609 WMSetButtonSelected(selectedBtn, True);
1611 selectSpecification(selectedBtn, panel);
1613 /* kluge to know who should get the key events */
1614 panel->frame->client_leader = WMWidgetXID(panel->win);
1616 WSETUFLAG(panel->frame, no_closable, 0);
1617 WSETUFLAG(panel->frame, no_close_button, 0);
1618 wWindowUpdateButtonImages(panel->frame);
1619 wFrameWindowShowButton(panel->frame->frame, WFF_RIGHT_BUTTON);
1620 panel->frame->frame->on_click_right = destroyInspector;
1622 wWindowMap(panel->frame);
1624 showIconFor(WMWidgetScreen(panel->alwChk), panel, wwin->wm_instance, wwin->wm_class, UPDATE_TEXT_FIELD);
1626 return panel;
1629 void wShowInspectorForWindow(WWindow * wwin)
1631 if (wwin->flags.inspector_open)
1632 return;
1634 WMSetBalloonEnabled(wwin->screen_ptr->wmscreen, wPreferences.help_balloon);
1636 make_keys();
1637 wwin->flags.inspector_open = 1;
1638 wwin->inspector = createInspectorForWindow(wwin, UNDEFINED_POS, UNDEFINED_POS, False);
1641 void wHideInspectorForWindow(WWindow * wwin)
1643 WWindow *pwin = wwin->inspector->frame;
1645 wWindowUnmap(pwin);
1646 pwin->flags.hidden = 1;
1648 wClientSetState(pwin, IconicState, None);
1651 void wUnhideInspectorForWindow(WWindow * wwin)
1653 WWindow *pwin = wwin->inspector->frame;
1655 pwin->flags.hidden = 0;
1656 pwin->flags.mapped = 1;
1657 XMapWindow(dpy, pwin->client_win);
1658 XMapWindow(dpy, pwin->frame->core->window);
1659 wClientSetState(pwin, NormalState, None);
1662 WWindow *wGetWindowOfInspectorForWindow(WWindow * wwin)
1664 if (wwin->inspector) {
1665 assert(wwin->flags.inspector_open != 0);
1667 return wwin->inspector->frame;
1668 } else
1669 return NULL;
1672 void wCloseInspectorForWindow(WWindow * wwin)
1674 WWindow *pwin = wwin->inspector->frame; /* the inspector window */
1676 (*pwin->frame->on_click_right) (NULL, pwin, NULL);