~profzoom/ubuntu/quantal/wmaker/bug-1079925

« back to all changes in this revision

Viewing changes to src/winspector.c

  • Committer: Bazaar Package Importer
  • Author(s): Marcelo E. Magallon
  • Date: 2004-11-10 14:05:30 UTC
  • Revision ID: james.westby@ubuntu.com-20041110140530-qpd66b5lm38x7apk
Tags: upstream-0.91.0
ImportĀ upstreamĀ versionĀ 0.91.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* winspector.c - window attribute inspector
 
2
 *
 
3
 *  Window Maker window manager
 
4
 *
 
5
 *  Copyright (c) 1997-2003 Alfredo K. Kojima
 
6
 *  Copyright (c) 1998-2003 Dan Pascu
 
7
 *
 
8
 *  This program is free software; you can redistribute it and/or modify
 
9
 *  it under the terms of the GNU General Public License as published by
 
10
 *  the Free Software Foundation; either version 2 of the License, or
 
11
 *  (at your option) any later version.
 
12
 *
 
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.
 
17
 *
 
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.
 
22
 */
 
23
 
 
24
#include "wconfig.h"
 
25
 
 
26
#include <X11/Xlib.h>
 
27
#include <X11/Xutil.h>
 
28
#include <stdlib.h>
 
29
#include <stdio.h>
 
30
#include <string.h>
 
31
 
 
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
 
 
50
#ifdef NETWM_HINTS
 
51
#include "wmspec.h"
 
52
#endif
 
53
 
 
54
#include "xinerama.h"
 
55
 
 
56
#include <WINGs/WUtil.h>
 
57
 
 
58
 
 
59
 
 
60
 
 
61
 
 
62
 
 
63
 
 
64
typedef struct InspectorPanel {
 
65
    struct InspectorPanel *nextPtr;
 
66
 
 
67
    WWindow *frame;
 
68
 
 
69
    WWindow *inspected;       /* the window that's being inspected */
 
70
 
 
71
    WMWindow *win;
 
72
 
 
73
    Window parent;
 
74
 
 
75
    /* common stuff */
 
76
    WMButton *revertBtn;
 
77
    WMButton *applyBtn;
 
78
    WMButton *saveBtn;
 
79
 
 
80
    WMPopUpButton *pagePopUp;
 
81
 
 
82
    /* first page. general stuff */
 
83
 
 
84
    WMFrame *specFrm;
 
85
    WMButton *instRb;
 
86
    WMButton *clsRb;
 
87
    WMButton *bothRb;
 
88
    WMButton *defaultRb;
 
89
 
 
90
    WMButton *selWinB;
 
91
 
 
92
    WMLabel *specLbl;
 
93
 
 
94
    /* second page. attributes */
 
95
 
 
96
    WMFrame *attrFrm;
 
97
    WMButton *attrChk[11];
 
98
 
 
99
    /* 3rd page. more attributes */
 
100
    WMFrame *moreFrm;
 
101
#ifdef XKB_BUTTON_HINT
 
102
    WMButton *moreChk[9];
 
103
#else
 
104
    WMButton *moreChk[8];
 
105
#endif
 
106
 
 
107
    /* 4th page. icon and workspace */
 
108
    WMFrame *iconFrm;
 
109
    WMLabel *iconLbl;
 
110
    WMLabel *fileLbl;
 
111
    WMTextField *fileText;
 
112
    WMButton *alwChk;
 
113
    /*
 
114
     WMButton *updateIconBtn;
 
115
     */
 
116
    WMButton *browseIconBtn;
 
117
 
 
118
    WMFrame *wsFrm;
 
119
    WMPopUpButton *wsP;
 
120
 
 
121
    /* 5th page. application wide attributes */
 
122
    WMFrame *appFrm;
 
123
    WMButton *appChk[3];
 
124
 
 
125
    unsigned int done:1;
 
126
    unsigned int destroyed:1;
 
127
    unsigned int choosingIcon:1;
 
128
} InspectorPanel;
 
129
 
 
130
 
 
131
 
 
132
 
 
133
extern Cursor wCursor[WCUR_LAST];
 
134
 
 
135
extern WDDomain *WDWindowAttributes;
 
136
 
 
137
static InspectorPanel *panelList=NULL;
 
138
 
 
139
extern WPreferences wPreferences;
 
140
 
 
141
static WMPropList *ANoTitlebar = NULL;
 
142
static WMPropList *ANoResizebar;
 
143
static WMPropList *ANoMiniaturizeButton;
 
144
static WMPropList *ANoCloseButton;
 
145
static WMPropList *ANoBorder;
 
146
static WMPropList *ANoHideOthers;
 
147
static WMPropList *ANoMouseBindings;
 
148
static WMPropList *ANoKeyBindings;
 
149
static WMPropList *ANoAppIcon;
 
150
static WMPropList *AKeepOnTop;
 
151
static WMPropList *AKeepOnBottom;
 
152
static WMPropList *AOmnipresent;
 
153
static WMPropList *ASkipWindowList;
 
154
static WMPropList *AKeepInsideScreen;
 
155
static WMPropList *AUnfocusable;
 
156
static WMPropList *AAlwaysUserIcon;
 
157
static WMPropList *AStartMiniaturized;
 
158
static WMPropList *AStartMaximized;
 
159
static WMPropList *ADontSaveSession;
 
160
static WMPropList *AEmulateAppIcon;
 
161
static WMPropList *AFullMaximize;
 
162
static WMPropList *ASharedAppIcon;
 
163
#ifdef XKB_BUTTON_HINT
 
164
static WMPropList *ANoLanguageButton;
 
165
#endif
 
166
 
 
167
static WMPropList *AStartWorkspace;
 
168
 
 
169
static WMPropList *AIcon;
 
170
 
 
171
/* application wide options */
 
172
static WMPropList *AStartHidden;
 
173
 
 
174
 
 
175
static WMPropList *AnyWindow;
 
176
static WMPropList *EmptyString;
 
177
static WMPropList *Yes, *No;
 
178
 
 
179
 
 
180
#define PWIDTH  270
 
181
#define PHEIGHT 350
 
182
 
 
183
 
 
184
 
 
185
static char *spec_text;
 
186
 
 
187
 
 
188
static void applySettings(WMButton *button, InspectorPanel *panel);
 
189
 
 
190
 
 
191
 
 
192
 
 
193
#define UNDEFINED_POS 0xffffff
 
194
 
 
195
static InspectorPanel *createInspectorForWindow(WWindow *wwin,
 
196
                                                int xpos, int ypos,
 
197
                                                Bool showSelectPanel);
 
198
 
 
199
 
 
200
 
 
201
static void
 
202
make_keys()
 
203
{
 
204
    if (ANoTitlebar!=NULL)
 
205
        return;
 
206
 
 
207
    AIcon = WMCreatePLString("Icon");
 
208
    ANoTitlebar = WMCreatePLString("NoTitlebar");
 
209
    ANoResizebar = WMCreatePLString("NoResizebar");
 
210
    ANoMiniaturizeButton = WMCreatePLString("NoMiniaturizeButton");
 
211
    ANoCloseButton = WMCreatePLString("NoCloseButton");
 
212
    ANoBorder = WMCreatePLString("NoBorder");
 
213
    ANoHideOthers = WMCreatePLString("NoHideOthers");
 
214
    ANoMouseBindings = WMCreatePLString("NoMouseBindings");
 
215
    ANoKeyBindings = WMCreatePLString("NoKeyBindings");
 
216
    ANoAppIcon = WMCreatePLString("NoAppIcon");
 
217
    AKeepOnTop = WMCreatePLString("KeepOnTop");
 
218
    AKeepOnBottom = WMCreatePLString("KeepOnBottom");
 
219
    AOmnipresent = WMCreatePLString("Omnipresent");
 
220
    ASkipWindowList = WMCreatePLString("SkipWindowList");
 
221
    AKeepInsideScreen = WMCreatePLString("KeepInsideScreen");
 
222
    AUnfocusable = WMCreatePLString("Unfocusable");
 
223
    AAlwaysUserIcon = WMCreatePLString("AlwaysUserIcon");
 
224
    AStartMiniaturized = WMCreatePLString("StartMiniaturized");
 
225
    AStartMaximized = WMCreatePLString("StartMaximized");
 
226
    AStartHidden = WMCreatePLString("StartHidden");
 
227
    ADontSaveSession = WMCreatePLString("DontSaveSession");
 
228
    AEmulateAppIcon = WMCreatePLString("EmulateAppIcon");
 
229
    AFullMaximize = WMCreatePLString("FullMaximize");
 
230
    ASharedAppIcon = WMCreatePLString("SharedAppIcon");
 
231
#ifdef XKB_BUTTON_HINT
 
232
    ANoLanguageButton = WMCreatePLString("NoLanguageButton");
 
233
#endif
 
234
 
 
235
    AStartWorkspace = WMCreatePLString("StartWorkspace");
 
236
 
 
237
    AnyWindow = WMCreatePLString("*");
 
238
    EmptyString = WMCreatePLString("");
 
239
    Yes = WMCreatePLString("Yes");
 
240
    No = WMCreatePLString("No");
 
241
}
 
242
 
 
243
 
 
244
 
 
245
static void
 
246
freeInspector(InspectorPanel *panel)
 
247
{
 
248
    panel->destroyed = 1;
 
249
    if (panel->choosingIcon)
 
250
        return;
 
251
 
 
252
    WMDestroyWidget(panel->win);
 
253
 
 
254
    XDestroyWindow(dpy, panel->parent);
 
255
 
 
256
    wfree(panel);
 
257
}
 
258
 
 
259
 
 
260
static void
 
261
destroyInspector(WCoreWindow *foo, void *data, XEvent *event)
 
262
{
 
263
    InspectorPanel *panel;
 
264
    InspectorPanel *tmp;
 
265
 
 
266
    panel = panelList;
 
267
    while (panel->frame!=data)
 
268
        panel = panel->nextPtr;
 
269
 
 
270
    if (panelList == panel)
 
271
        panelList = panel->nextPtr;
 
272
    else {
 
273
        tmp = panelList;
 
274
        while (tmp->nextPtr!=panel) {
 
275
            tmp = tmp->nextPtr;
 
276
        }
 
277
        tmp->nextPtr = panel->nextPtr;
 
278
    }
 
279
    panel->inspected->flags.inspector_open = 0;
 
280
    panel->inspected->inspector = NULL;
 
281
 
 
282
    WMRemoveNotificationObserver(panel);
 
283
 
 
284
    wWindowUnmap(panel->frame);
 
285
    wUnmanageWindow(panel->frame, True, False);
 
286
 
 
287
    freeInspector(panel);
 
288
}
 
289
 
 
290
 
 
291
 
 
292
void
 
293
wDestroyInspectorPanels()
 
294
{
 
295
    InspectorPanel *panel;
 
296
 
 
297
    while (panelList != NULL) {
 
298
        panel = panelList;
 
299
        panelList = panelList->nextPtr;
 
300
        wUnmanageWindow(panel->frame, False, False);
 
301
        WMDestroyWidget(panel->win);
 
302
 
 
303
        panel->inspected->flags.inspector_open = 0;
 
304
        panel->inspected->inspector = NULL;
 
305
 
 
306
        wfree(panel);
 
307
    }
 
308
}
 
309
 
 
310
 
 
311
static void
 
312
changePage(WMPopUpButton *bPtr, InspectorPanel *panel)
 
313
{
 
314
    int page;
 
315
 
 
316
    page = WMGetPopUpButtonSelectedItem(bPtr);
 
317
 
 
318
    if (page == 0) {
 
319
        WMMapWidget(panel->specFrm);
 
320
        WMMapWidget(panel->specLbl);
 
321
    } else if (page == 1) {
 
322
        WMMapWidget(panel->attrFrm);
 
323
    } else if (page == 2) {
 
324
        WMMapWidget(panel->moreFrm);
 
325
    } else if (page == 3) {
 
326
        WMMapWidget(panel->iconFrm);
 
327
        WMMapWidget(panel->wsFrm);
 
328
    } else {
 
329
        WMMapWidget(panel->appFrm);
 
330
    }
 
331
 
 
332
    if (page != 0) {
 
333
        WMUnmapWidget(panel->specFrm);
 
334
        WMUnmapWidget(panel->specLbl);
 
335
    }
 
336
    if (page != 1)
 
337
        WMUnmapWidget(panel->attrFrm);
 
338
    if (page != 2)
 
339
        WMUnmapWidget(panel->moreFrm);
 
340
    if (page != 3) {
 
341
        WMUnmapWidget(panel->iconFrm);
 
342
        WMUnmapWidget(panel->wsFrm);
 
343
    }
 
344
    if (page != 4 && panel->appFrm)
 
345
        WMUnmapWidget(panel->appFrm);
 
346
}
 
347
 
 
348
 
 
349
#define USE_TEXT_FIELD          1
 
350
#define UPDATE_TEXT_FIELD       2
 
351
#define REVERT_TO_DEFAULT       4
 
352
 
 
353
 
 
354
static int
 
355
showIconFor(WMScreen *scrPtr, InspectorPanel *panel,
 
356
            char *wm_instance, char *wm_class, int flags)
 
357
{
 
358
    WMPixmap *pixmap = (WMPixmap*) NULL;
 
359
    char *file=NULL, *path=NULL;
 
360
    char *db_icon=NULL;
 
361
 
 
362
    if ((flags & USE_TEXT_FIELD) != 0) {
 
363
        file = WMGetTextFieldText(panel->fileText);
 
364
        if (file && file[0] == 0) {
 
365
            wfree(file);
 
366
            file = NULL;
 
367
        }
 
368
    } else {
 
369
        db_icon = wDefaultGetIconFile(panel->inspected->screen_ptr,
 
370
                                      wm_instance, wm_class, False);
 
371
        if(db_icon != NULL)
 
372
            file = wstrdup(db_icon);
 
373
    }
 
374
    if (db_icon!=NULL && (flags & REVERT_TO_DEFAULT)!=0) {
 
375
        if (file)
 
376
            file = wstrdup(db_icon);
 
377
        flags |= UPDATE_TEXT_FIELD;
 
378
    }
 
379
 
 
380
    if ((flags & UPDATE_TEXT_FIELD) != 0) {
 
381
        WMSetTextFieldText(panel->fileText, file);
 
382
    }
 
383
 
 
384
    if (file) {
 
385
        path = FindImage(wPreferences.icon_path, file);
 
386
 
 
387
        if (!path) {
 
388
            char *buf;
 
389
            int len = strlen(file)+80;
 
390
 
 
391
            buf = wmalloc(len);
 
392
            snprintf(buf, len, _("Could not find icon \"%s\" specified for this window"),
 
393
                     file);
 
394
            wMessageDialog(panel->frame->screen_ptr, _("Error"), buf,
 
395
                           _("OK"), NULL, NULL);
 
396
            wfree(buf);
 
397
            wfree(file);
 
398
            return -1;
 
399
        }
 
400
 
 
401
        pixmap = WMCreatePixmapFromFile(scrPtr, path);
 
402
        wfree(path);
 
403
 
 
404
        if (!pixmap) {
 
405
            char *buf;
 
406
            int len = strlen(file)+80;
 
407
 
 
408
            buf = wmalloc(len);
 
409
            snprintf(buf, len, _("Could not open specified icon \"%s\":%s"),
 
410
                     file, RMessageForError(RErrorCode));
 
411
            wMessageDialog(panel->frame->screen_ptr, _("Error"), buf,
 
412
                           _("OK"), NULL, NULL);
 
413
            wfree(buf);
 
414
            wfree(file);
 
415
            return -1;
 
416
        }
 
417
        wfree(file);
 
418
    }
 
419
 
 
420
    WMSetLabelImage(panel->iconLbl, pixmap);
 
421
    if (pixmap)
 
422
        WMReleasePixmap(pixmap);
 
423
 
 
424
    return 0;
 
425
}
 
426
 
 
427
#if 0
 
428
static void
 
429
updateIcon(WMButton *button, InspectorPanel *panel)
 
430
{
 
431
    showIconFor(WMWidgetScreen(button), panel, NULL, NULL, USE_TEXT_FIELD);
 
432
}
 
433
#endif
 
434
 
 
435
static int
 
436
getBool(WMPropList *value)
 
437
{
 
438
    char *val;
 
439
 
 
440
    if (!WMIsPLString(value)) {
 
441
        return 0;
 
442
    }
 
443
    if (!(val = WMGetFromPLString(value))) {
 
444
        return 0;
 
445
    }
 
446
 
 
447
    if ((val[1]=='\0' && (val[0]=='y' || val[0]=='Y' || val[0]=='T'
 
448
                          || val[0]=='t' || val[0]=='1'))
 
449
        || (strcasecmp(val, "YES")==0 || strcasecmp(val, "TRUE")==0)) {
 
450
 
 
451
        return 1;
 
452
    } else if ((val[1]=='\0'
 
453
                && (val[0]=='n' || val[0]=='N' || val[0]=='F'
 
454
                    || val[0]=='f' || val[0]=='0'))
 
455
               || (strcasecmp(val, "NO")==0 || strcasecmp(val, "FALSE")==0)) {
 
456
 
 
457
        return 0;
 
458
    } else {
 
459
        wwarning(_("can't convert \"%s\" to boolean"), val);
 
460
        return 0;
 
461
    }
 
462
}
 
463
 
 
464
 
 
465
#define UPDATE_DEFAULTS    1
 
466
#define IS_BOOLEAN         2
 
467
 
 
468
 
 
469
/*
 
470
 *  Will insert the attribute = value; pair in window's list,
 
471
 * if it's different from the defaults.
 
472
 *  Defaults means either defaults database, or attributes saved
 
473
 * for the default window "*". This is to let one revert options that are
 
474
 * global because they were saved for all windows ("*").
 
475
 *
 
476
 */
 
477
 
 
478
 
 
479
static int
 
480
insertAttribute(WMPropList *dict, WMPropList *window, WMPropList *attr,
 
481
                WMPropList *value, int flags)
 
482
{
 
483
    WMPropList *def_win, *def_value=NULL;
 
484
    int update = 0;
 
485
    int modified = 0;
 
486
 
 
487
    if (!(flags & UPDATE_DEFAULTS) && dict) {
 
488
        if ((def_win = WMGetFromPLDictionary(dict, AnyWindow)) != NULL) {
 
489
            def_value = WMGetFromPLDictionary(def_win, attr);
 
490
        }
 
491
    }
 
492
 
 
493
    /* If we could not find defaults in database, fall to hardcoded values.
 
494
     * Also this is true if we save defaults for all windows
 
495
     */
 
496
    if (!def_value)
 
497
        def_value = ((flags & IS_BOOLEAN) != 0) ? No : EmptyString;
 
498
 
 
499
    if ((flags & IS_BOOLEAN))
 
500
        update = (getBool(value) != getBool(def_value));
 
501
    else {
 
502
        update = !WMIsPropListEqualTo(value, def_value);
 
503
    }
 
504
 
 
505
    if (update) {
 
506
        WMPutInPLDictionary(window, attr, value);
 
507
        modified = 1;
 
508
    }
 
509
 
 
510
    return modified;
 
511
}
 
512
 
 
513
 
 
514
static void
 
515
saveSettings(WMButton *button, InspectorPanel *panel)
 
516
{
 
517
    WWindow *wwin = panel->inspected;
 
518
    WDDomain *db = WDWindowAttributes;
 
519
    WMPropList *dict = db->dictionary;
 
520
    WMPropList *winDic, *appDic, *value, *key, *key2;
 
521
    char *icon_file;
 
522
    int flags = 0;
 
523
    int different = 0, different2 = 0;
 
524
 
 
525
    /* Save will apply the changes and save them */
 
526
    applySettings(panel->applyBtn, panel);
 
527
 
 
528
    if (WMGetButtonSelected(panel->instRb) != 0)
 
529
        key = WMCreatePLString(wwin->wm_instance);
 
530
    else if (WMGetButtonSelected(panel->clsRb) != 0)
 
531
        key = WMCreatePLString(wwin->wm_class);
 
532
    else if (WMGetButtonSelected(panel->bothRb) != 0) {
 
533
        char *buffer;
 
534
 
 
535
        buffer = StrConcatDot(wwin->wm_instance, wwin->wm_class);
 
536
        key = WMCreatePLString(buffer);
 
537
        wfree(buffer);
 
538
    } else if (WMGetButtonSelected(panel->defaultRb) != 0) {
 
539
        key = WMRetainPropList(AnyWindow);
 
540
        flags = UPDATE_DEFAULTS;
 
541
    } else
 
542
        key = NULL;
 
543
 
 
544
    if (!key)
 
545
        return;
 
546
 
 
547
    if (!dict) {
 
548
        dict = WMCreatePLDictionary(NULL, NULL);
 
549
        if (dict) {
 
550
            db->dictionary = dict;
 
551
        } else {
 
552
            WMReleasePropList(key);
 
553
            return;
 
554
        }
 
555
    }
 
556
 
 
557
    if (showIconFor(WMWidgetScreen(button), panel, NULL, NULL,
 
558
                    USE_TEXT_FIELD) < 0)
 
559
        return;
 
560
 
 
561
    WMPLSetCaseSensitive(True);
 
562
 
 
563
    winDic = WMCreatePLDictionary(NULL, NULL);
 
564
    appDic = WMCreatePLDictionary(NULL, NULL);
 
565
 
 
566
    /* Update icon for window */
 
567
    icon_file = WMGetTextFieldText(panel->fileText);
 
568
    if (icon_file) {
 
569
        if (icon_file[0] != 0) {
 
570
            value = WMCreatePLString(icon_file);
 
571
            different |= insertAttribute(dict, winDic, AIcon, value, flags);
 
572
            different2 |= insertAttribute(dict, appDic, AIcon, value, flags);
 
573
            WMReleasePropList(value);
 
574
        }
 
575
        wfree(icon_file);
 
576
    }
 
577
 
 
578
    {
 
579
        int i = WMGetPopUpButtonSelectedItem(panel->wsP);
 
580
 
 
581
        i--;
 
582
 
 
583
        if (i>=0 && i < panel->frame->screen_ptr->workspace_count) {
 
584
            value = WMCreatePLString(panel->frame->screen_ptr->workspaces[i]->name);
 
585
            different |= insertAttribute(dict, winDic, AStartWorkspace, value,
 
586
                                         flags);
 
587
            WMReleasePropList(value);
 
588
        }
 
589
    }
 
590
 
 
591
    flags |= IS_BOOLEAN;
 
592
 
 
593
    value = (WMGetButtonSelected(panel->alwChk)!=0) ? Yes : No;
 
594
    different |= insertAttribute(dict, winDic, AAlwaysUserIcon, value, flags);
 
595
 
 
596
    value = (WMGetButtonSelected(panel->attrChk[0])!=0) ? Yes : No;
 
597
    different |= insertAttribute(dict, winDic, ANoTitlebar,     value, flags);
 
598
 
 
599
    value = (WMGetButtonSelected(panel->attrChk[1])!=0) ? Yes : No;
 
600
    different |= insertAttribute(dict, winDic, ANoResizebar,     value, flags);
 
601
 
 
602
    value = (WMGetButtonSelected(panel->attrChk[2])!=0) ? Yes : No;
 
603
    different |= insertAttribute(dict, winDic, ANoCloseButton,   value, flags);
 
604
 
 
605
    value = (WMGetButtonSelected(panel->attrChk[3])!=0) ? Yes : No;
 
606
    different |= insertAttribute(dict, winDic, ANoMiniaturizeButton, value, flags);
 
607
 
 
608
    value = (WMGetButtonSelected(panel->attrChk[4])!=0) ? Yes : No;
 
609
    different |= insertAttribute(dict, winDic, ANoBorder, value, flags);
 
610
 
 
611
    value = (WMGetButtonSelected(panel->attrChk[5])!=0) ? Yes : No;
 
612
    different |= insertAttribute(dict, winDic, AKeepOnTop,       value, flags);
 
613
 
 
614
    value = (WMGetButtonSelected(panel->attrChk[6])!=0) ? Yes : No;
 
615
    different |= insertAttribute(dict, winDic, AKeepOnBottom,    value, flags);
 
616
 
 
617
    value = (WMGetButtonSelected(panel->attrChk[7])!=0) ? Yes : No;
 
618
    different |= insertAttribute(dict, winDic, AOmnipresent,     value, flags);
 
619
 
 
620
    value = (WMGetButtonSelected(panel->attrChk[8])!=0) ? Yes : No;
 
621
    different |= insertAttribute(dict, winDic, AStartMiniaturized, value, flags);
 
622
 
 
623
    value = (WMGetButtonSelected(panel->attrChk[9])!=0) ? Yes : No;
 
624
    different |= insertAttribute(dict, winDic, AStartMaximized,  value, flags);
 
625
 
 
626
    value = (WMGetButtonSelected(panel->attrChk[10])!=0) ? Yes : No;
 
627
    different |= insertAttribute(dict, winDic, AFullMaximize,  value, flags);
 
628
 
 
629
 
 
630
    value = (WMGetButtonSelected(panel->moreChk[0])!=0) ? Yes : No;
 
631
    different |= insertAttribute(dict, winDic, ANoKeyBindings,   value, flags);
 
632
 
 
633
    value = (WMGetButtonSelected(panel->moreChk[1])!=0) ? Yes : No;
 
634
    different |= insertAttribute(dict, winDic, ANoMouseBindings, value, flags);
 
635
 
 
636
    value = (WMGetButtonSelected(panel->moreChk[2])!=0) ? Yes : No;
 
637
    different |= insertAttribute(dict, winDic, ASkipWindowList, value, flags);
 
638
 
 
639
    value = (WMGetButtonSelected(panel->moreChk[3])!=0) ? Yes : No;
 
640
    different |= insertAttribute(dict, winDic, AUnfocusable, value, flags);
 
641
 
 
642
    value = (WMGetButtonSelected(panel->moreChk[4])!=0) ? Yes : No;
 
643
    different |= insertAttribute(dict, winDic, AKeepInsideScreen,value, flags);
 
644
 
 
645
    value = (WMGetButtonSelected(panel->moreChk[5])!=0) ? Yes : No;
 
646
    different |= insertAttribute(dict, winDic, ANoHideOthers,    value, flags);
 
647
 
 
648
    value = (WMGetButtonSelected(panel->moreChk[6])!=0) ? Yes : No;
 
649
    different |= insertAttribute(dict, winDic, ADontSaveSession, value, flags);
 
650
 
 
651
    value = (WMGetButtonSelected(panel->moreChk[7])!=0) ? Yes : No;
 
652
    different |= insertAttribute(dict, winDic, AEmulateAppIcon,  value, flags);
 
653
 
 
654
#ifdef XKB_BUTTON_HINT
 
655
    value = (WMGetButtonSelected(panel->moreChk[8])!=0) ? Yes : No;
 
656
    different |= insertAttribute(dict, winDic, ANoLanguageButton, value, flags);
 
657
#endif
 
658
 
 
659
    if (wwin->main_window!=None && wApplicationOf(wwin->main_window)!=NULL) {
 
660
        value = (WMGetButtonSelected(panel->appChk[0])!=0) ? Yes : No;
 
661
        different2 |= insertAttribute(dict, appDic, AStartHidden, value, flags);
 
662
 
 
663
        value = (WMGetButtonSelected(panel->appChk[1])!=0) ? Yes : No;
 
664
        different2 |= insertAttribute(dict, appDic, ANoAppIcon, value, flags);
 
665
 
 
666
        value = (WMGetButtonSelected(panel->appChk[2])!=0) ? Yes : No;
 
667
        different2 |= insertAttribute(dict, appDic, ASharedAppIcon, value, flags);
 
668
    }
 
669
 
 
670
    if (wwin->fake_group) {
 
671
        key2 = WMCreatePLString(wwin->fake_group->identifier);
 
672
        if (WMIsPropListEqualTo(key, key2)) {
 
673
            WMMergePLDictionaries(winDic, appDic, True);
 
674
            different |= different2;
 
675
        } else {
 
676
            WMRemoveFromPLDictionary(dict, key2);
 
677
            if (different2) {
 
678
                WMPutInPLDictionary(dict, key2, appDic);
 
679
            }
 
680
        }
 
681
        WMReleasePropList(key2);
 
682
        WMReleasePropList(appDic);
 
683
    } else if (wwin->main_window != wwin->client_win) {
 
684
        WApplication *wapp = wApplicationOf(wwin->main_window);
 
685
 
 
686
        if (wapp) {
 
687
            char *instance = wapp->main_window_desc->wm_instance;
 
688
            char *class = wapp->main_window_desc->wm_class;
 
689
            char *buffer;
 
690
 
 
691
            buffer = StrConcatDot(instance, class);
 
692
            key2 = WMCreatePLString(buffer);
 
693
            wfree(buffer);
 
694
 
 
695
            if (WMIsPropListEqualTo(key, key2)) {
 
696
                WMMergePLDictionaries(winDic, appDic, True);
 
697
                different |= different2;
 
698
            } else {
 
699
                WMRemoveFromPLDictionary(dict, key2);
 
700
                if (different2) {
 
701
                    WMPutInPLDictionary(dict, key2, appDic);
 
702
                }
 
703
            }
 
704
            WMReleasePropList(key2);
 
705
            WMReleasePropList(appDic);
 
706
        }
 
707
    } else {
 
708
        WMMergePLDictionaries(winDic, appDic, True);
 
709
        different |= different2;
 
710
        WMReleasePropList(appDic);
 
711
    }
 
712
 
 
713
    WMRemoveFromPLDictionary(dict, key);
 
714
    if (different) {
 
715
        WMPutInPLDictionary(dict, key, winDic);
 
716
    }
 
717
 
 
718
    WMReleasePropList(key);
 
719
    WMReleasePropList(winDic);
 
720
 
 
721
    UpdateDomainFile(db);
 
722
 
 
723
    /* clean up */
 
724
    WMPLSetCaseSensitive(False);
 
725
}
 
726
 
 
727
 
 
728
static void
 
729
makeAppIconFor(WApplication *wapp)
 
730
{
 
731
    WScreen *scr = wapp->main_window_desc->screen_ptr;
 
732
 
 
733
    if (wapp->app_icon)
 
734
        return;
 
735
 
 
736
    if (!WFLAGP(wapp->main_window_desc, no_appicon))
 
737
        wapp->app_icon = wAppIconCreate(wapp->main_window_desc);
 
738
    else
 
739
        wapp->app_icon = NULL;
 
740
 
 
741
    if (wapp->app_icon) {
 
742
        WIcon *icon = wapp->app_icon->icon;
 
743
        WDock *clip = scr->workspaces[scr->current_workspace]->clip;
 
744
        int x=0, y=0;
 
745
 
 
746
        wapp->app_icon->main_window = wapp->main_window;
 
747
 
 
748
        if (clip && clip->attract_icons && wDockFindFreeSlot(clip, &x, &y)) {
 
749
            wapp->app_icon->attracted = 1;
 
750
            if (!wapp->app_icon->icon->shadowed) {
 
751
                wapp->app_icon->icon->shadowed = 1;
 
752
                wapp->app_icon->icon->force_paint = 1;
 
753
            }
 
754
            wDockAttachIcon(clip, wapp->app_icon, x, y);
 
755
        } else {
 
756
            PlaceIcon(scr, &x, &y, wGetHeadForWindow(wapp->main_window_desc));
 
757
            wAppIconMove(wapp->app_icon, x, y);
 
758
        }
 
759
        if (!clip || !wapp->app_icon->attracted || !clip->collapsed)
 
760
            XMapWindow(dpy, icon->core->window);
 
761
 
 
762
        if (wPreferences.auto_arrange_icons && !wapp->app_icon->attracted)
 
763
            wArrangeIcons(wapp->main_window_desc->screen_ptr, True);
 
764
    }
 
765
}
 
766
 
 
767
 
 
768
static void
 
769
removeAppIconFor(WApplication *wapp)
 
770
{
 
771
    if (!wapp->app_icon)
 
772
        return;
 
773
 
 
774
    if (wapp->app_icon->docked && !wapp->app_icon->attracted) {
 
775
        wapp->app_icon->running = 0;
 
776
        /* since we keep it, we don't care if it was attracted or not */
 
777
        wapp->app_icon->attracted = 0;
 
778
        wapp->app_icon->icon->shadowed = 0;
 
779
        wapp->app_icon->main_window = None;
 
780
        wapp->app_icon->pid = 0;
 
781
        wapp->app_icon->icon->owner = NULL;
 
782
        wapp->app_icon->icon->icon_win = None;
 
783
        wapp->app_icon->icon->force_paint = 1;
 
784
        wAppIconPaint(wapp->app_icon);
 
785
    } else if (wapp->app_icon->docked) {
 
786
        wapp->app_icon->running = 0;
 
787
        wDockDetach(wapp->app_icon->dock, wapp->app_icon);
 
788
    } else {
 
789
        wAppIconDestroy(wapp->app_icon);
 
790
    }
 
791
    wapp->app_icon = NULL;
 
792
    if (wPreferences.auto_arrange_icons)
 
793
        wArrangeIcons(wapp->main_window_desc->screen_ptr, True);
 
794
}
 
795
 
 
796
 
 
797
static void
 
798
applySettings(WMButton *button, InspectorPanel *panel)
 
799
{
 
800
    WWindow *wwin = panel->inspected;
 
801
    WApplication *wapp = wApplicationOf(wwin->main_window);
 
802
    int floating, sunken, skip_window_list;
 
803
    int old_omnipresent;
 
804
    int old_no_bind_keys;
 
805
    int old_no_bind_mouse;
 
806
 
 
807
    old_omnipresent = WFLAGP(wwin, omnipresent);
 
808
    old_no_bind_keys = WFLAGP(wwin, no_bind_keys);
 
809
    old_no_bind_mouse = WFLAGP(wwin, no_bind_mouse);
 
810
 
 
811
    showIconFor(WMWidgetScreen(button), panel, NULL, NULL, USE_TEXT_FIELD);
 
812
 
 
813
    WSETUFLAG(wwin, no_titlebar, WMGetButtonSelected(panel->attrChk[0]));
 
814
    WSETUFLAG(wwin, no_resizebar, WMGetButtonSelected(panel->attrChk[1]));
 
815
    WSETUFLAG(wwin, no_close_button, WMGetButtonSelected(panel->attrChk[2]));
 
816
    WSETUFLAG(wwin, no_miniaturize_button, WMGetButtonSelected(panel->attrChk[3]));
 
817
    WSETUFLAG(wwin, no_border, WMGetButtonSelected(panel->attrChk[4]));
 
818
    floating = WMGetButtonSelected(panel->attrChk[5]);
 
819
    sunken   = WMGetButtonSelected(panel->attrChk[6]);
 
820
    WSETUFLAG(wwin, omnipresent, WMGetButtonSelected(panel->attrChk[7]));
 
821
    WSETUFLAG(wwin, start_miniaturized, WMGetButtonSelected(panel->attrChk[8]));
 
822
    WSETUFLAG(wwin, start_maximized, WMGetButtonSelected(panel->attrChk[9]));
 
823
    WSETUFLAG(wwin, full_maximize, WMGetButtonSelected(panel->attrChk[10]));
 
824
 
 
825
    WSETUFLAG(wwin, no_bind_keys, WMGetButtonSelected(panel->moreChk[0]));
 
826
    WSETUFLAG(wwin, no_bind_mouse, WMGetButtonSelected(panel->moreChk[1]));
 
827
    skip_window_list = WMGetButtonSelected(panel->moreChk[2]);
 
828
    WSETUFLAG(wwin, no_focusable, WMGetButtonSelected(panel->moreChk[3]));
 
829
    WSETUFLAG(wwin, dont_move_off, WMGetButtonSelected(panel->moreChk[4]));
 
830
    WSETUFLAG(wwin, no_hide_others, WMGetButtonSelected(panel->moreChk[5]));
 
831
    WSETUFLAG(wwin, dont_save_session, WMGetButtonSelected(panel->moreChk[6]));
 
832
    WSETUFLAG(wwin, emulate_appicon, WMGetButtonSelected(panel->moreChk[7]));
 
833
#ifdef XKB_BUTTON_HINT
 
834
    WSETUFLAG(wwin, no_language_button, WMGetButtonSelected(panel->moreChk[8]));
 
835
#endif
 
836
    WSETUFLAG(wwin, always_user_icon, WMGetButtonSelected(panel->alwChk));
 
837
 
 
838
    if (WFLAGP(wwin, no_titlebar) && wwin->flags.shaded)
 
839
        wUnshadeWindow(wwin);
 
840
 
 
841
    WSETUFLAG(wwin, no_shadeable, WFLAGP(wwin, no_titlebar));
 
842
 
 
843
    if (floating) {
 
844
        if (!WFLAGP(wwin, floating))
 
845
            ChangeStackingLevel(wwin->frame->core, WMFloatingLevel);
 
846
    } else if (sunken) {
 
847
        if (!WFLAGP(wwin, sunken))
 
848
            ChangeStackingLevel(wwin->frame->core, WMSunkenLevel);
 
849
    } else {
 
850
        if (WFLAGP(wwin, floating) || WFLAGP(wwin, sunken))
 
851
            ChangeStackingLevel(wwin->frame->core, WMNormalLevel);
 
852
    }
 
853
 
 
854
    WSETUFLAG(wwin, sunken, sunken);
 
855
    WSETUFLAG(wwin, floating, floating);
 
856
    wwin->flags.omnipresent = 0;
 
857
 
 
858
    if (WFLAGP(wwin, skip_window_list) != skip_window_list) {
 
859
        WSETUFLAG(wwin, skip_window_list, skip_window_list);
 
860
        UpdateSwitchMenu(wwin->screen_ptr, wwin,
 
861
                         skip_window_list ? ACTION_REMOVE : ACTION_ADD);
 
862
    } else {
 
863
        if (WFLAGP(wwin, omnipresent) != old_omnipresent) {
 
864
            WMPostNotificationName(WMNChangedState, wwin, "omnipresent");
 
865
        }
 
866
    }
 
867
 
 
868
    if (WFLAGP(wwin, no_bind_keys) != old_no_bind_keys) {
 
869
        if (WFLAGP(wwin, no_bind_keys)) {
 
870
            XUngrabKey(dpy, AnyKey, AnyModifier, wwin->frame->core->window);
 
871
        } else {
 
872
            wWindowSetKeyGrabs(wwin);
 
873
        }
 
874
    }
 
875
 
 
876
    if (WFLAGP(wwin, no_bind_mouse) != old_no_bind_mouse) {
 
877
        wWindowResetMouseGrabs(wwin);
 
878
    }
 
879
 
 
880
    wwin->frame->flags.need_texture_change = 1;
 
881
    wWindowConfigureBorders(wwin);
 
882
    wFrameWindowPaint(wwin->frame);
 
883
#ifdef NETWM_HINTS
 
884
    wNETWMUpdateActions(wwin, False);
 
885
#endif
 
886
 
 
887
    /*
 
888
     * Can't apply emulate_appicon because it will probably cause problems.
 
889
     */
 
890
 
 
891
    if (wapp) {
 
892
        /* do application wide stuff */
 
893
        WSETUFLAG(wapp->main_window_desc, start_hidden,
 
894
                  WMGetButtonSelected(panel->appChk[0]));
 
895
 
 
896
        WSETUFLAG(wapp->main_window_desc, no_appicon,
 
897
                  WMGetButtonSelected(panel->appChk[1]));
 
898
 
 
899
        WSETUFLAG(wapp->main_window_desc, shared_appicon,
 
900
                  WMGetButtonSelected(panel->appChk[2]));
 
901
 
 
902
        if (WFLAGP(wapp->main_window_desc, no_appicon))
 
903
            removeAppIconFor(wapp);
 
904
        else
 
905
            makeAppIconFor(wapp);
 
906
 
 
907
        if (wapp->app_icon && wapp->main_window == wwin->client_win) {
 
908
            char *file = WMGetTextFieldText(panel->fileText);
 
909
 
 
910
            if (file[0] == 0) {
 
911
                wfree(file);
 
912
                file = NULL;
 
913
            }
 
914
            wIconChangeImageFile(wapp->app_icon->icon, file);
 
915
            if (file)
 
916
                wfree(file);
 
917
            wAppIconPaint(wapp->app_icon);
 
918
        }
 
919
    }
 
920
}
 
921
 
 
922
 
 
923
 
 
924
 
 
925
static void
 
926
revertSettings(WMButton *button, InspectorPanel *panel)
 
927
{
 
928
    WWindow *wwin = panel->inspected;
 
929
    WApplication *wapp = wApplicationOf(wwin->main_window);
 
930
    int i, n;
 
931
    char *wm_instance = NULL;
 
932
    char *wm_class = NULL;
 
933
    int workspace, level;
 
934
 
 
935
    if (panel->instRb && WMGetButtonSelected(panel->instRb) != 0)
 
936
        wm_instance = wwin->wm_instance;
 
937
    else if (panel->clsRb && WMGetButtonSelected(panel->clsRb) != 0)
 
938
        wm_class = wwin->wm_class;
 
939
    else if (panel->bothRb && WMGetButtonSelected(panel->bothRb) != 0) {
 
940
        wm_instance = wwin->wm_instance;
 
941
        wm_class = wwin->wm_class;
 
942
    }
 
943
    memset(&wwin->defined_user_flags, 0, sizeof(WWindowAttributes));
 
944
    memset(&wwin->user_flags, 0, sizeof(WWindowAttributes));
 
945
    memset(&wwin->client_flags, 0, sizeof(WWindowAttributes));
 
946
 
 
947
    wWindowSetupInitialAttributes(wwin, &level, &workspace);
 
948
 
 
949
    for (i=0; i < 11; i++) {
 
950
        int flag = 0;
 
951
 
 
952
        switch (i) {
 
953
        case 0:
 
954
            flag = WFLAGP(wwin, no_titlebar);
 
955
            break;
 
956
        case 1:
 
957
            flag = WFLAGP(wwin, no_resizebar);
 
958
            break;
 
959
        case 2:
 
960
            flag = WFLAGP(wwin, no_close_button);
 
961
            break;
 
962
        case 3:
 
963
            flag = WFLAGP(wwin, no_miniaturize_button);
 
964
            break;
 
965
        case 4:
 
966
            flag = WFLAGP(wwin, no_border);
 
967
            break;
 
968
        case 5:
 
969
            flag = WFLAGP(wwin, floating);
 
970
            break;
 
971
        case 6:
 
972
            flag = WFLAGP(wwin, sunken);
 
973
            break;
 
974
        case 7:
 
975
            flag = WFLAGP(wwin, omnipresent);
 
976
            break;
 
977
        case 8:
 
978
            flag = WFLAGP(wwin, start_miniaturized);
 
979
            break;
 
980
        case 9:
 
981
            flag = WFLAGP(wwin, start_maximized!=0);
 
982
            break;
 
983
        case 10:
 
984
            flag = WFLAGP(wwin, full_maximize);
 
985
            break;
 
986
        }
 
987
        WMSetButtonSelected(panel->attrChk[i], flag);
 
988
    }
 
989
    for (i=0; i < 8; i++) {
 
990
        int flag = 0;
 
991
 
 
992
        switch (i) {
 
993
        case 0:
 
994
            flag = WFLAGP(wwin, no_bind_keys);
 
995
            break;
 
996
        case 1:
 
997
            flag = WFLAGP(wwin, no_bind_mouse);
 
998
            break;
 
999
        case 2:
 
1000
            flag = WFLAGP(wwin, skip_window_list);
 
1001
            break;
 
1002
        case 3:
 
1003
            flag = WFLAGP(wwin, no_focusable);
 
1004
            break;
 
1005
        case 4:
 
1006
            flag = WFLAGP(wwin, dont_move_off);
 
1007
            break;
 
1008
        case 5:
 
1009
            flag = WFLAGP(wwin, no_hide_others);
 
1010
            break;
 
1011
        case 6:
 
1012
            flag = WFLAGP(wwin, dont_save_session);
 
1013
            break;
 
1014
        case 7:
 
1015
            flag = WFLAGP(wwin, emulate_appicon);
 
1016
            break;
 
1017
#ifdef XKB_BUTTON_HINT
 
1018
        case 8:
 
1019
            flag = WFLAGP(wwin, no_language_button);
 
1020
            break;
 
1021
#endif
 
1022
        }
 
1023
        WMSetButtonSelected(panel->moreChk[i], flag);
 
1024
    }
 
1025
    if (panel->appFrm && wapp) {
 
1026
        for (i=0; i < 2; i++) {
 
1027
            int flag = 0;
 
1028
 
 
1029
            switch (i) {
 
1030
            case 0:
 
1031
                flag = WFLAGP(wapp->main_window_desc, start_hidden);
 
1032
                break;
 
1033
            case 1:
 
1034
                flag = WFLAGP(wapp->main_window_desc, no_appicon);
 
1035
                break;
 
1036
            case 2:
 
1037
                flag = WFLAGP(wapp->main_window_desc, shared_appicon);
 
1038
                break;
 
1039
            }
 
1040
            WMSetButtonSelected(panel->appChk[i], flag);
 
1041
        }
 
1042
    }
 
1043
    WMSetButtonSelected(panel->alwChk, WFLAGP(wwin, always_user_icon));
 
1044
 
 
1045
    showIconFor(WMWidgetScreen(panel->alwChk), panel, wm_instance, wm_class,
 
1046
                REVERT_TO_DEFAULT);
 
1047
 
 
1048
    n = wDefaultGetStartWorkspace(wwin->screen_ptr, wm_instance, wm_class);
 
1049
 
 
1050
    if (n >= 0 && n < wwin->screen_ptr->workspace_count) {
 
1051
        WMSetPopUpButtonSelectedItem(panel->wsP, n+1);
 
1052
    } else {
 
1053
        WMSetPopUpButtonSelectedItem(panel->wsP, 0);
 
1054
    }
 
1055
 
 
1056
    /* must auto apply, so that there wno't be internal
 
1057
     * inconsistencies between the state in the flags and
 
1058
     * the actual state of the window */
 
1059
    applySettings(panel->applyBtn, panel);
 
1060
}
 
1061
 
 
1062
 
 
1063
static void
 
1064
chooseIconCallback(WMWidget *self, void *clientData)
 
1065
{
 
1066
    char *file;
 
1067
    InspectorPanel *panel = (InspectorPanel*)clientData;
 
1068
    int result;
 
1069
 
 
1070
    panel->choosingIcon = 1;
 
1071
 
 
1072
    WMSetButtonEnabled(panel->browseIconBtn, False);
 
1073
 
 
1074
    result = wIconChooserDialog(panel->frame->screen_ptr, &file,
 
1075
                                panel->inspected->wm_instance,
 
1076
                                panel->inspected->wm_class);
 
1077
 
 
1078
    panel->choosingIcon = 0;
 
1079
 
 
1080
    if (!panel->destroyed) { /* kluge */
 
1081
        if (result) {
 
1082
            WMSetTextFieldText(panel->fileText, file);
 
1083
            showIconFor(WMWidgetScreen(self), panel, NULL, NULL,
 
1084
                        USE_TEXT_FIELD);
 
1085
            wfree(file);
 
1086
        }
 
1087
        WMSetButtonEnabled(panel->browseIconBtn, True);
 
1088
    } else {
 
1089
        freeInspector(panel);
 
1090
    }
 
1091
}
 
1092
 
 
1093
 
 
1094
static void
 
1095
textEditedObserver(void *observerData, WMNotification *notification)
 
1096
{
 
1097
    InspectorPanel *panel = (InspectorPanel*)observerData;
 
1098
 
 
1099
    if ((long)WMGetNotificationClientData(notification) != WMReturnTextMovement)
 
1100
        return;
 
1101
 
 
1102
    showIconFor(WMWidgetScreen(panel->win), panel, NULL, NULL,
 
1103
                USE_TEXT_FIELD);
 
1104
    /*
 
1105
     WMPerformButtonClick(panel->updateIconBtn);
 
1106
     */
 
1107
}
 
1108
 
 
1109
 
 
1110
static void
 
1111
selectSpecification(WMWidget *bPtr, void *data)
 
1112
{
 
1113
    InspectorPanel *panel = (InspectorPanel*)data;
 
1114
    char *str;
 
1115
    WWindow *wwin = panel->inspected;
 
1116
    int len;
 
1117
 
 
1118
    if (bPtr == panel->defaultRb && (wwin->wm_instance || wwin->wm_class)) {
 
1119
        WMSetButtonEnabled(panel->applyBtn, False);
 
1120
    } else {
 
1121
        WMSetButtonEnabled(panel->applyBtn, True);
 
1122
    }
 
1123
 
 
1124
    len = 16 + strlen(wwin->wm_instance ? wwin->wm_instance : "?")
 
1125
        + strlen(wwin->wm_class ? wwin->wm_class : "?");
 
1126
 
 
1127
    str = wmalloc(len);
 
1128
 
 
1129
    snprintf(str, len, _("Inspecting  %s.%s"),
 
1130
             wwin->wm_instance ? wwin->wm_instance : "?",
 
1131
             wwin->wm_class ? wwin->wm_class : "?");
 
1132
 
 
1133
    wFrameWindowChangeTitle(panel->frame->frame, str);
 
1134
 
 
1135
    wfree(str);
 
1136
}
 
1137
 
 
1138
 
 
1139
static void
 
1140
selectWindow(WMWidget *bPtr, void *data)
 
1141
{
 
1142
    InspectorPanel *panel = (InspectorPanel*)data;
 
1143
    WWindow *wwin = panel->inspected;
 
1144
    WScreen *scr = wwin->screen_ptr;
 
1145
    XEvent event;
 
1146
    WWindow *iwin;
 
1147
 
 
1148
    if (XGrabPointer(dpy, scr->root_win, True,
 
1149
                     ButtonPressMask, GrabModeAsync, GrabModeAsync, None,
 
1150
                     wCursor[WCUR_SELECT], CurrentTime)!=GrabSuccess) {
 
1151
        wwarning("could not grab mouse pointer");
 
1152
        return;
 
1153
    }
 
1154
 
 
1155
    WMSetLabelText(panel->specLbl, _("Click in the window you wish to inspect."));
 
1156
 
 
1157
    WMMaskEvent(dpy, ButtonPressMask, &event);
 
1158
 
 
1159
    XUngrabPointer(dpy, CurrentTime);
 
1160
 
 
1161
    iwin = wWindowFor(event.xbutton.subwindow);
 
1162
 
 
1163
    if (iwin && !iwin->flags.internal_window && iwin != wwin
 
1164
        && !iwin->flags.inspector_open) {
 
1165
 
 
1166
        iwin->flags.inspector_open = 1;
 
1167
        iwin->inspector = createInspectorForWindow(iwin,
 
1168
                                                   panel->frame->frame_x,
 
1169
                                                   panel->frame->frame_y,
 
1170
                                                   True);
 
1171
        wCloseInspectorForWindow(wwin);
 
1172
    } else {
 
1173
        WMSetLabelText(panel->specLbl, spec_text);
 
1174
    }
 
1175
}
 
1176
 
 
1177
 
 
1178
 
 
1179
static InspectorPanel*
 
1180
createInspectorForWindow(WWindow *wwin, int xpos, int ypos,
 
1181
                         Bool showSelectPanel)
 
1182
{
 
1183
    WScreen *scr = wwin->screen_ptr;
 
1184
    InspectorPanel *panel;
 
1185
    Window parent;
 
1186
    int i;
 
1187
    int x, y;
 
1188
    int btn_width, frame_width;
 
1189
    WMButton *selectedBtn = NULL;
 
1190
#ifdef wrong_behaviour
 
1191
    WMPixmap *pixmap;
 
1192
#endif
 
1193
 
 
1194
    spec_text = _("The configuration will apply to all\n"
 
1195
                  "windows that have their WM_CLASS\n"
 
1196
                  "property set to the above selected\n"
 
1197
                  "name, when saved.");
 
1198
 
 
1199
    panel = wmalloc(sizeof(InspectorPanel));
 
1200
    memset(panel, 0, sizeof(InspectorPanel));
 
1201
 
 
1202
    panel->destroyed = 0;
 
1203
 
 
1204
 
 
1205
    panel->inspected = wwin;
 
1206
 
 
1207
    panel->nextPtr = panelList;
 
1208
    panelList = panel;
 
1209
 
 
1210
 
 
1211
    panel->win = WMCreateWindow(scr->wmscreen, "windowInspector");
 
1212
    WMResizeWidget(panel->win, PWIDTH, PHEIGHT);
 
1213
 
 
1214
 
 
1215
    /**** create common stuff ****/
 
1216
 
 
1217
    /* command buttons */
 
1218
    /* (PWIDTH - (left and right margin) - (btn interval)) / 3 */
 
1219
    btn_width = (PWIDTH - (2 * 15) - (2 * 10)) / 3;
 
1220
    panel->saveBtn = WMCreateCommandButton(panel->win);
 
1221
    WMSetButtonAction(panel->saveBtn, (WMAction*)saveSettings, panel);
 
1222
    WMMoveWidget(panel->saveBtn, (2 * (btn_width + 10)) + 15, 310);
 
1223
    WMSetButtonText(panel->saveBtn, _("Save"));
 
1224
    WMResizeWidget(panel->saveBtn, btn_width, 28);
 
1225
    if (wPreferences.flags.noupdates || !(wwin->wm_class || wwin->wm_instance))
 
1226
        WMSetButtonEnabled(panel->saveBtn, False);
 
1227
 
 
1228
    panel->applyBtn = WMCreateCommandButton(panel->win);
 
1229
    WMSetButtonAction(panel->applyBtn, (WMAction*)applySettings, panel);
 
1230
    WMMoveWidget(panel->applyBtn, btn_width + 10 + 15, 310);
 
1231
    WMSetButtonText(panel->applyBtn, _("Apply"));
 
1232
    WMResizeWidget(panel->applyBtn, btn_width, 28);
 
1233
 
 
1234
    panel->revertBtn = WMCreateCommandButton(panel->win);
 
1235
    WMSetButtonAction(panel->revertBtn, (WMAction*)revertSettings, panel);
 
1236
    WMMoveWidget(panel->revertBtn, 15, 310);
 
1237
    WMSetButtonText(panel->revertBtn, _("Reload"));
 
1238
    WMResizeWidget(panel->revertBtn, btn_width, 28);
 
1239
 
 
1240
    /* page selection popup button */
 
1241
    panel->pagePopUp = WMCreatePopUpButton(panel->win);
 
1242
    WMSetPopUpButtonAction(panel->pagePopUp, (WMAction*)changePage, panel);
 
1243
    WMMoveWidget(panel->pagePopUp, 25, 15);
 
1244
    WMResizeWidget(panel->pagePopUp, PWIDTH - 50, 20);
 
1245
 
 
1246
    WMAddPopUpButtonItem(panel->pagePopUp, _("Window Specification"));
 
1247
    WMAddPopUpButtonItem(panel->pagePopUp, _("Window Attributes"));
 
1248
    WMAddPopUpButtonItem(panel->pagePopUp, _("Advanced Options"));
 
1249
    WMAddPopUpButtonItem(panel->pagePopUp, _("Icon and Initial Workspace"));
 
1250
    WMAddPopUpButtonItem(panel->pagePopUp, _("Application Specific"));
 
1251
 
 
1252
    /**** window spec ****/
 
1253
    frame_width = PWIDTH - (2 * 15);
 
1254
 
 
1255
    panel->specFrm = WMCreateFrame(panel->win);
 
1256
    WMSetFrameTitle(panel->specFrm, _("Window Specification"));
 
1257
    WMMoveWidget(panel->specFrm, 15, 65);
 
1258
    WMResizeWidget(panel->specFrm, frame_width, 145);
 
1259
 
 
1260
 
 
1261
    panel->defaultRb = WMCreateRadioButton(panel->specFrm);
 
1262
    WMMoveWidget(panel->defaultRb, 10, 78);
 
1263
    WMResizeWidget(panel->defaultRb, frame_width - (2 * 10), 20);
 
1264
    WMSetButtonText(panel->defaultRb, _("Defaults for all windows"));
 
1265
    WMSetButtonSelected(panel->defaultRb, False);
 
1266
    WMSetButtonAction(panel->defaultRb, selectSpecification, panel);
 
1267
 
 
1268
    if (wwin->wm_class && wwin->wm_instance) {
 
1269
        char *str, *tmp;
 
1270
 
 
1271
        tmp = wstrconcat(wwin->wm_instance, ".");
 
1272
        str = wstrconcat(tmp, wwin->wm_class);
 
1273
 
 
1274
        panel->bothRb = WMCreateRadioButton(panel->specFrm);
 
1275
        WMMoveWidget(panel->bothRb, 10, 18);
 
1276
        WMResizeWidget(panel->bothRb, frame_width - (2 * 10), 20);
 
1277
        WMSetButtonText(panel->bothRb, str);
 
1278
        wfree(tmp);
 
1279
        wfree(str);
 
1280
        WMGroupButtons(panel->defaultRb, panel->bothRb);
 
1281
 
 
1282
        if (!selectedBtn)
 
1283
            selectedBtn = panel->bothRb;
 
1284
 
 
1285
        WMSetButtonAction(panel->bothRb, selectSpecification, panel);
 
1286
    }
 
1287
 
 
1288
    if (wwin->wm_instance) {
 
1289
        panel->instRb = WMCreateRadioButton(panel->specFrm);
 
1290
        WMMoveWidget(panel->instRb, 10, 38);
 
1291
        WMResizeWidget(panel->instRb, frame_width - (2 * 10), 20);
 
1292
        WMSetButtonText(panel->instRb, wwin->wm_instance);
 
1293
        WMGroupButtons(panel->defaultRb, panel->instRb);
 
1294
 
 
1295
        if (!selectedBtn)
 
1296
            selectedBtn = panel->instRb;
 
1297
 
 
1298
        WMSetButtonAction(panel->instRb, selectSpecification, panel);
 
1299
    }
 
1300
 
 
1301
    if (wwin->wm_class) {
 
1302
        panel->clsRb = WMCreateRadioButton(panel->specFrm);
 
1303
        WMMoveWidget(panel->clsRb, 10, 58);
 
1304
        WMResizeWidget(panel->clsRb, frame_width - (2 * 10), 20);
 
1305
        WMSetButtonText(panel->clsRb, wwin->wm_class);
 
1306
        WMGroupButtons(panel->defaultRb, panel->clsRb);
 
1307
 
 
1308
        if (!selectedBtn)
 
1309
            selectedBtn = panel->clsRb;
 
1310
 
 
1311
        WMSetButtonAction(panel->clsRb, selectSpecification, panel);
 
1312
    }
 
1313
 
 
1314
 
 
1315
    panel->selWinB = WMCreateCommandButton(panel->specFrm);
 
1316
    WMMoveWidget(panel->selWinB, 20, 145-24 - 10);
 
1317
    WMResizeWidget(panel->selWinB, frame_width - 2*10 - 20, 24);
 
1318
    WMSetButtonText(panel->selWinB, _("Select window"));
 
1319
    WMSetButtonAction(panel->selWinB, selectWindow, panel);
 
1320
 
 
1321
 
 
1322
    panel->specLbl = WMCreateLabel(panel->win);
 
1323
    WMMoveWidget(panel->specLbl, 15, 210);
 
1324
    WMResizeWidget(panel->specLbl, frame_width, 100);
 
1325
    WMSetLabelText(panel->specLbl, spec_text);
 
1326
    WMSetLabelWraps(panel->specLbl, True);
 
1327
 
 
1328
    WMSetLabelTextAlignment(panel->specLbl, WALeft);
 
1329
 
 
1330
    /**** attributes ****/
 
1331
    panel->attrFrm = WMCreateFrame(panel->win);
 
1332
    WMSetFrameTitle(panel->attrFrm, _("Attributes"));
 
1333
    WMMoveWidget(panel->attrFrm, 15, 45);
 
1334
    WMResizeWidget(panel->attrFrm, frame_width, 250);
 
1335
 
 
1336
    for (i=0; i < 11; i++) {
 
1337
        char *caption = NULL;
 
1338
        int flag = 0;
 
1339
        char *descr = NULL;
 
1340
 
 
1341
        switch (i) {
 
1342
        case 0:
 
1343
            caption = _("Disable titlebar");
 
1344
            flag = WFLAGP(wwin, no_titlebar);
 
1345
            descr = _("Remove the titlebar of this window.\n"
 
1346
                      "To access the window commands menu of a window\n"
 
1347
                      "without it's titlebar, press Control+Esc (or the\n"
 
1348
                      "equivalent shortcut, if you changed the default\n"
 
1349
                      "settings).");
 
1350
            break;
 
1351
        case 1:
 
1352
            caption = _("Disable resizebar");
 
1353
            flag = WFLAGP(wwin, no_resizebar);
 
1354
            descr = _("Remove the resizebar of this window.");
 
1355
            break;
 
1356
        case 2:
 
1357
            caption = _("Disable close button");
 
1358
            flag = WFLAGP(wwin, no_close_button);
 
1359
            descr = _("Remove the `close window' button of this window.");
 
1360
            break;
 
1361
        case 3:
 
1362
            caption = _("Disable miniaturize button");
 
1363
            flag = WFLAGP(wwin, no_miniaturize_button);
 
1364
            descr = _("Remove the `miniaturize window' button of the window.");
 
1365
            break;
 
1366
        case 4:
 
1367
            caption = _("Disable border");
 
1368
            flag = WFLAGP(wwin, no_border);
 
1369
            descr = _("Remove the 1 pixel black border around the window.");
 
1370
            break;
 
1371
        case 5:
 
1372
            caption = _("Keep on top (floating)");
 
1373
            flag = WFLAGP(wwin, floating);
 
1374
            descr = _("Keep the window over other windows, not allowing\n"
 
1375
                      "them to cover it.");
 
1376
            break;
 
1377
        case 6:
 
1378
            caption = _("Keep at bottom (sunken)");
 
1379
            flag = WFLAGP(wwin, sunken);
 
1380
            descr = _("Keep the window under all other windows.");
 
1381
            break;
 
1382
        case 7:
 
1383
            caption = _("Omnipresent");
 
1384
            flag = WFLAGP(wwin, omnipresent);
 
1385
            descr = _("Make window present in all workspaces.");
 
1386
            break;
 
1387
        case 8:
 
1388
            caption = _("Start miniaturized");
 
1389
            flag = WFLAGP(wwin, start_miniaturized);
 
1390
            descr = _("Make the window be automatically miniaturized when it's\n"
 
1391
                      "first shown.");
 
1392
            break;
 
1393
        case 9:
 
1394
            caption = _("Start maximized");
 
1395
            flag = WFLAGP(wwin, start_maximized!=0);
 
1396
            descr = _("Make the window be automatically maximized when it's\n"
 
1397
                      "first shown.");
 
1398
            break;
 
1399
        case 10:
 
1400
            caption = _("Full screen maximization");
 
1401
            flag = WFLAGP(wwin, full_maximize);
 
1402
            descr = _("Make the window use the whole screen space when it's\n"
 
1403
                      "maximized. The titlebar and resizebar will be moved\n"
 
1404
                      "to outside the screen.");
 
1405
            break;
 
1406
        }
 
1407
        panel->attrChk[i] = WMCreateSwitchButton(panel->attrFrm);
 
1408
        WMMoveWidget(panel->attrChk[i], 10, 20*(i+1));
 
1409
        WMResizeWidget(panel->attrChk[i], frame_width-15, 20);
 
1410
        WMSetButtonSelected(panel->attrChk[i], flag);
 
1411
        WMSetButtonText(panel->attrChk[i], caption);
 
1412
 
 
1413
        WMSetBalloonTextForView(descr, WMWidgetView(panel->attrChk[i]));
 
1414
    }
 
1415
 
 
1416
 
 
1417
    /**** more attributes ****/
 
1418
    panel->moreFrm = WMCreateFrame(panel->win);
 
1419
    WMSetFrameTitle(panel->moreFrm, _("Advanced"));
 
1420
    WMMoveWidget(panel->moreFrm, 15, 45);
 
1421
    WMResizeWidget(panel->moreFrm, frame_width, 250);
 
1422
 
 
1423
    for (i=0;
 
1424
#ifdef XKB_BUTTON_HINT
 
1425
         i < 9;
 
1426
#else
 
1427
         i < 8;
 
1428
#endif
 
1429
         i++) {
 
1430
        char *caption = NULL;
 
1431
        int flag = 0;
 
1432
        char *descr = NULL;
 
1433
 
 
1434
        switch (i) {
 
1435
        case 0:
 
1436
            caption = _("Do not bind keyboard shortcuts");
 
1437
            flag = WFLAGP(wwin, no_bind_keys);
 
1438
            descr = _("Do not bind keyboard shortcuts from Window Maker\n"
 
1439
                      "when this window is focused. This will allow the\n"
 
1440
                      "window to receive all key combinations regardless\n"
 
1441
                      "of your shortcut configuration.");
 
1442
            break;
 
1443
        case 1:
 
1444
            caption = _("Do not bind mouse clicks");
 
1445
            flag = WFLAGP(wwin, no_bind_mouse);
 
1446
            descr = _("Do not bind mouse actions, such as `Alt'+drag\n"
 
1447
                      "in the window (when alt is the modifier you have"
 
1448
                      "configured).");
 
1449
            break;
 
1450
        case 2:
 
1451
            caption = _("Do not show in the window list");
 
1452
            flag = WFLAGP(wwin, skip_window_list);
 
1453
            descr = _("Do not list the window in the window list menu.");
 
1454
            break;
 
1455
        case 3:
 
1456
            caption = _("Do not let it take focus");
 
1457
            flag = WFLAGP(wwin, no_focusable);
 
1458
            descr = _("Do not let the window take keyboard focus when you\n"
 
1459
                      "click on it.");
 
1460
            break;
 
1461
        case 4:
 
1462
            caption = _("Keep inside screen");
 
1463
            flag = WFLAGP(wwin, dont_move_off);
 
1464
            descr = _("Do not allow the window to move itself completely\n"
 
1465
                      "outside the screen. For bug compatibility.\n");
 
1466
            break;
 
1467
        case 5:
 
1468
            caption = _("Ignore 'Hide Others'");
 
1469
            flag = WFLAGP(wwin, no_hide_others);
 
1470
            descr = _("Do not hide the window when issuing the\n"
 
1471
                      "`HideOthers' command.");
 
1472
            break;
 
1473
        case 6:
 
1474
            caption = _("Ignore 'Save Session'");
 
1475
            flag = WFLAGP(wwin, dont_save_session);
 
1476
            descr = _("Do not save the associated application in the\n"
 
1477
                      "session's state, so that it won't be restarted\n"
 
1478
                      "together with other applications when Window Maker\n"
 
1479
                      "starts.");
 
1480
            break;
 
1481
        case 7:
 
1482
            caption = _("Emulate application icon");
 
1483
            flag = WFLAGP(wwin, emulate_appicon);
 
1484
            descr = _("Make this window act as an application that provides\n"
 
1485
                      "enough information to Window Maker for a dockable\n"
 
1486
                      "application icon to be created.");
 
1487
            break;
 
1488
#ifdef XKB_BUTTON_HINT
 
1489
        case 8:
 
1490
            caption = _("Disable language button");
 
1491
            flag = WFLAGP(wwin, no_language_button);
 
1492
            descr = _("Remove the `toggle language' button of the window.");
 
1493
            break;
 
1494
#endif
 
1495
        }
 
1496
        panel->moreChk[i] = WMCreateSwitchButton(panel->moreFrm);
 
1497
        WMMoveWidget(panel->moreChk[i], 10, 20*(i+1));
 
1498
        WMResizeWidget(panel->moreChk[i], frame_width-15, 20);
 
1499
        WMSetButtonSelected(panel->moreChk[i], flag);
 
1500
        WMSetButtonText(panel->moreChk[i], caption);
 
1501
 
 
1502
        WMSetBalloonTextForView(descr, WMWidgetView(panel->moreChk[i]));
 
1503
    }
 
1504
 
 
1505
    /* miniwindow/workspace */
 
1506
    panel->iconFrm = WMCreateFrame(panel->win);
 
1507
    WMMoveWidget(panel->iconFrm, 15, 50);
 
1508
    WMResizeWidget(panel->iconFrm,  PWIDTH - (2 * 15), 170);
 
1509
    WMSetFrameTitle(panel->iconFrm, _("Miniwindow Image"));
 
1510
 
 
1511
    panel->iconLbl = WMCreateLabel(panel->iconFrm);
 
1512
    WMMoveWidget(panel->iconLbl, PWIDTH - (2 * 15) - 22 - 64, 20);
 
1513
    WMResizeWidget(panel->iconLbl, 64, 64);
 
1514
    WMSetLabelRelief(panel->iconLbl, WRGroove);
 
1515
    WMSetLabelImagePosition(panel->iconLbl, WIPImageOnly);
 
1516
 
 
1517
    panel->browseIconBtn = WMCreateCommandButton(panel->iconFrm);
 
1518
    WMSetButtonAction(panel->browseIconBtn, chooseIconCallback, panel);
 
1519
    WMMoveWidget(panel->browseIconBtn, 22, 32);
 
1520
    WMResizeWidget(panel->browseIconBtn, 120, 26);
 
1521
    WMSetButtonText(panel->browseIconBtn, _("Browse..."));
 
1522
 
 
1523
#ifdef wrong_behaviour
 
1524
    WMSetButtonImagePosition(panel->updateIconBtn, WIPRight);
 
1525
    pixmap = WMGetSystemPixmap(scr->wmscreen, WSIReturnArrow);
 
1526
    WMSetButtonImage(panel->updateIconBtn, pixmap);
 
1527
    WMReleasePixmap(pixmap);
 
1528
    pixmap = WMGetSystemPixmap(scr->wmscreen, WSIHighlightedReturnArrow);
 
1529
    WMSetButtonAltImage(panel->updateIconBtn, pixmap);
 
1530
    WMReleasePixmap(pixmap);
 
1531
#endif
 
1532
 
 
1533
    panel->fileLbl = WMCreateLabel(panel->iconFrm);
 
1534
    WMMoveWidget(panel->fileLbl, 20, 85);
 
1535
    WMResizeWidget(panel->fileLbl, PWIDTH - (2 * 15) - (2 * 20), 14);
 
1536
    WMSetLabelText(panel->fileLbl, _("Icon filename:"));
 
1537
 
 
1538
    panel->fileText = WMCreateTextField(panel->iconFrm);
 
1539
    WMMoveWidget(panel->fileText, 20, 105);
 
1540
    WMResizeWidget(panel->fileText, PWIDTH - (2 * 20) - (2 * 15), 20);
 
1541
    WMSetTextFieldText(panel->fileText, NULL);
 
1542
    WMAddNotificationObserver(textEditedObserver, panel,
 
1543
                              WMTextDidEndEditingNotification,
 
1544
                              panel->fileText);
 
1545
 
 
1546
    panel->alwChk = WMCreateSwitchButton(panel->iconFrm);
 
1547
    WMMoveWidget(panel->alwChk, 20, 130);
 
1548
    WMResizeWidget(panel->alwChk, PWIDTH - (2 * 15) - (2 * 15), 30);
 
1549
    WMSetButtonText(panel->alwChk, _("Ignore client supplied icon"));
 
1550
    WMSetButtonSelected(panel->alwChk, WFLAGP(wwin, always_user_icon));
 
1551
 
 
1552
 
 
1553
    panel->wsFrm = WMCreateFrame(panel->win);
 
1554
    WMMoveWidget(panel->wsFrm, 15, 225);
 
1555
    WMResizeWidget(panel->wsFrm, PWIDTH - (2 * 15), 70);
 
1556
    WMSetFrameTitle(panel->wsFrm, _("Initial Workspace"));
 
1557
 
 
1558
    WMSetBalloonTextForView(_("The workspace to place the window when it's"
 
1559
                              "first shown."), WMWidgetView(panel->wsFrm));
 
1560
 
 
1561
    panel->wsP = WMCreatePopUpButton(panel->wsFrm);
 
1562
    WMMoveWidget(panel->wsP, 20, 30);
 
1563
    WMResizeWidget(panel->wsP, PWIDTH - (2 * 15) - (2 * 20), 20);
 
1564
    WMAddPopUpButtonItem(panel->wsP, _("Nowhere in particular"));
 
1565
    for (i = 0; i < wwin->screen_ptr->workspace_count; i++) {
 
1566
        WMAddPopUpButtonItem(panel->wsP, scr->workspaces[i]->name);
 
1567
    }
 
1568
 
 
1569
    i = wDefaultGetStartWorkspace(wwin->screen_ptr, wwin->wm_instance,
 
1570
                                  wwin->wm_class);
 
1571
    if (i >= 0 && i <= wwin->screen_ptr->workspace_count) {
 
1572
        WMSetPopUpButtonSelectedItem(panel->wsP, i + 1);
 
1573
    } else {
 
1574
        WMSetPopUpButtonSelectedItem(panel->wsP, 0);
 
1575
    }
 
1576
 
 
1577
    /* application wide attributes */
 
1578
    if (wwin->main_window != None) {
 
1579
        WApplication *wapp = wApplicationOf(wwin->main_window);
 
1580
 
 
1581
        panel->appFrm = WMCreateFrame(panel->win);
 
1582
        WMSetFrameTitle(panel->appFrm, _("Application Attributes"));
 
1583
        WMMoveWidget(panel->appFrm, 15, 50);
 
1584
        WMResizeWidget(panel->appFrm, frame_width, 240);
 
1585
 
 
1586
        for (i=0; i < 3; i++) {
 
1587
            char *caption = NULL;
 
1588
            int flag = 0;
 
1589
            char *descr = NULL;
 
1590
 
 
1591
            switch (i) {
 
1592
            case 0:
 
1593
                caption = _("Start hidden");
 
1594
                flag = WFLAGP(wapp->main_window_desc, start_hidden);
 
1595
                descr = _("Automatically hide application when it's started.");
 
1596
                break;
 
1597
            case 1:
 
1598
                caption = _("No application icon");
 
1599
                flag = WFLAGP(wapp->main_window_desc, no_appicon);
 
1600
                descr = _("Disable the application icon for the application.\n"
 
1601
                          "Note that you won't be able to dock it anymore,\n"
 
1602
                          "and any icons that are already docked will stop\n"
 
1603
                          "working correctly.");
 
1604
                break;
 
1605
            case 2:
 
1606
                caption = _("Shared application icon");
 
1607
                flag = WFLAGP(wapp->main_window_desc, shared_appicon);
 
1608
                descr = _("Use a single shared application icon for all of\n"
 
1609
                          "the instances of this application.\n");
 
1610
                break;
 
1611
            }
 
1612
            panel->appChk[i] = WMCreateSwitchButton(panel->appFrm);
 
1613
            WMMoveWidget(panel->appChk[i], 10, 20*(i+1));
 
1614
            WMResizeWidget(panel->appChk[i], 205, 20);
 
1615
            WMSetButtonSelected(panel->appChk[i], flag);
 
1616
            WMSetButtonText(panel->appChk[i], caption);
 
1617
 
 
1618
            WMSetBalloonTextForView(descr, WMWidgetView(panel->appChk[i]));
 
1619
        }
 
1620
 
 
1621
        if (WFLAGP(wwin, emulate_appicon)) {
 
1622
            WMSetButtonEnabled(panel->appChk[1], False);
 
1623
            WMSetButtonEnabled(panel->moreChk[7], True);
 
1624
        } else {
 
1625
            WMSetButtonEnabled(panel->appChk[1], True);
 
1626
            WMSetButtonEnabled(panel->moreChk[7], False);
 
1627
        }
 
1628
    } else {
 
1629
        int tmp;
 
1630
 
 
1631
        if ((wwin->transient_for!=None && wwin->transient_for!=scr->root_win)
 
1632
            || !wwin->wm_class || !wwin->wm_instance)
 
1633
            tmp = False;
 
1634
        else
 
1635
            tmp = True;
 
1636
        WMSetButtonEnabled(panel->moreChk[7], tmp);
 
1637
 
 
1638
        WMSetPopUpButtonItemEnabled(panel->pagePopUp, 4, False);
 
1639
        panel->appFrm = NULL;
 
1640
    }
 
1641
 
 
1642
    /* if the window is a transient, don't let it have a miniaturize
 
1643
     * button */
 
1644
    if (wwin->transient_for!=None && wwin->transient_for!=scr->root_win)
 
1645
        WMSetButtonEnabled(panel->attrChk[3], False);
 
1646
    else
 
1647
        WMSetButtonEnabled(panel->attrChk[3], True);
 
1648
 
 
1649
 
 
1650
    if (!wwin->wm_class && !wwin->wm_instance) {
 
1651
        WMSetPopUpButtonItemEnabled(panel->pagePopUp, 0, False);
 
1652
    }
 
1653
 
 
1654
 
 
1655
    WMRealizeWidget(panel->win);
 
1656
 
 
1657
    WMMapSubwidgets(panel->win);
 
1658
    WMMapSubwidgets(panel->specFrm);
 
1659
    WMMapSubwidgets(panel->attrFrm);
 
1660
    WMMapSubwidgets(panel->moreFrm);
 
1661
    WMMapSubwidgets(panel->iconFrm);
 
1662
    WMMapSubwidgets(panel->wsFrm);
 
1663
    if (panel->appFrm)
 
1664
        WMMapSubwidgets(panel->appFrm);
 
1665
 
 
1666
    if (showSelectPanel) {
 
1667
        WMSetPopUpButtonSelectedItem(panel->pagePopUp, 0);
 
1668
        changePage(panel->pagePopUp, panel);
 
1669
    } else {
 
1670
        WMSetPopUpButtonSelectedItem(panel->pagePopUp, 1);
 
1671
        changePage(panel->pagePopUp, panel);
 
1672
    }
 
1673
 
 
1674
 
 
1675
    parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, PWIDTH, PHEIGHT,
 
1676
                                 0, 0, 0);
 
1677
    XSelectInput(dpy, parent, KeyPressMask|KeyReleaseMask);
 
1678
    panel->parent = parent;
 
1679
    XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
 
1680
 
 
1681
    WMMapWidget(panel->win);
 
1682
 
 
1683
    XSetTransientForHint(dpy, parent, wwin->client_win);
 
1684
 
 
1685
    if (xpos == UNDEFINED_POS) {
 
1686
        x = wwin->frame_x+wwin->frame->core->width/2;
 
1687
        y = wwin->frame_y+wwin->frame->top_width*2;
 
1688
        if (y + PHEIGHT > scr->scr_height)
 
1689
            y = scr->scr_height - PHEIGHT - 30;
 
1690
        if (x + PWIDTH > scr->scr_width)
 
1691
            x = scr->scr_width - PWIDTH;
 
1692
    } else {
 
1693
        x = xpos;
 
1694
        y = ypos;
 
1695
    }
 
1696
 
 
1697
    panel->frame = wManageInternalWindow(scr, parent, wwin->client_win,
 
1698
                                         "Inspector", x, y, PWIDTH, PHEIGHT);
 
1699
 
 
1700
    if (!selectedBtn)
 
1701
        selectedBtn = panel->defaultRb;
 
1702
 
 
1703
    WMSetButtonSelected(selectedBtn, True);
 
1704
 
 
1705
    selectSpecification(selectedBtn, panel);
 
1706
 
 
1707
    /* kluge to know who should get the key events */
 
1708
    panel->frame->client_leader = WMWidgetXID(panel->win);
 
1709
 
 
1710
    WSETUFLAG(panel->frame, no_closable, 0);
 
1711
    WSETUFLAG(panel->frame, no_close_button, 0);
 
1712
    wWindowUpdateButtonImages(panel->frame);
 
1713
    wFrameWindowShowButton(panel->frame->frame, WFF_RIGHT_BUTTON);
 
1714
    panel->frame->frame->on_click_right = destroyInspector;
 
1715
 
 
1716
    wWindowMap(panel->frame);
 
1717
 
 
1718
    showIconFor(WMWidgetScreen(panel->alwChk), panel, wwin->wm_instance,
 
1719
                wwin->wm_class, UPDATE_TEXT_FIELD);
 
1720
 
 
1721
    return panel;
 
1722
}
 
1723
 
 
1724
 
 
1725
void
 
1726
wShowInspectorForWindow(WWindow *wwin)
 
1727
{
 
1728
    if (wwin->flags.inspector_open)
 
1729
        return;
 
1730
 
 
1731
    WMSetBalloonEnabled(wwin->screen_ptr->wmscreen, wPreferences.help_balloon);
 
1732
 
 
1733
    make_keys();
 
1734
    wwin->flags.inspector_open = 1;
 
1735
    wwin->inspector = createInspectorForWindow(wwin, UNDEFINED_POS,
 
1736
                                               UNDEFINED_POS, False);
 
1737
}
 
1738
 
 
1739
 
 
1740
 
 
1741
 
 
1742
void
 
1743
wHideInspectorForWindow(WWindow *wwin)
 
1744
{
 
1745
    WWindow *pwin = wwin->inspector->frame;
 
1746
 
 
1747
    wWindowUnmap(pwin);
 
1748
    pwin->flags.hidden = 1;
 
1749
 
 
1750
    wClientSetState(pwin, IconicState, None);
 
1751
}
 
1752
 
 
1753
 
 
1754
 
 
1755
void
 
1756
wUnhideInspectorForWindow(WWindow *wwin)
 
1757
{
 
1758
    WWindow *pwin = wwin->inspector->frame;
 
1759
 
 
1760
    pwin->flags.hidden = 0;
 
1761
    pwin->flags.mapped = 1;
 
1762
    XMapWindow(dpy, pwin->client_win);
 
1763
    XMapWindow(dpy, pwin->frame->core->window);
 
1764
    wClientSetState(pwin, NormalState, None);
 
1765
}
 
1766
 
 
1767
 
 
1768
 
 
1769
WWindow*
 
1770
wGetWindowOfInspectorForWindow(WWindow *wwin)
 
1771
{
 
1772
    if (wwin->inspector) {
 
1773
        assert(wwin->flags.inspector_open != 0);
 
1774
 
 
1775
        return wwin->inspector->frame;
 
1776
    } else
 
1777
        return NULL;
 
1778
}
 
1779
 
 
1780
 
 
1781
void
 
1782
wCloseInspectorForWindow(WWindow *wwin)
 
1783
{
 
1784
    WWindow *pwin = wwin->inspector->frame; /* the inspector window */
 
1785
 
 
1786
    (*pwin->frame->on_click_right)(NULL, pwin, NULL);
 
1787
}
 
1788
 
 
1789