~ctwm/ctwm/trunk

« back to all changes in this revision

Viewing changes to win_ops.c

  • Committer: Matthew Fuller
  • Date: 2016-09-20 20:22:19 UTC
  • mfrom: (523.1.26 cleanups)
  • Revision ID: fullermd@over-yonder.net-20160920202219-ykdjyr1whmip1e5u
Cleanup organization of some window handling code.

Especially move various window-handling bits ouf of menus.c and util.c,
where they have no business being.  Create win_ops and win_util files for
much of it, as well as moving some to other existing locations they
better fit.  Do a little light commenting.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Various operations done on windows.
 
3
 */
 
4
 
 
5
#include "ctwm.h"
 
6
 
 
7
#include <stdio.h>
 
8
 
 
9
#include "animate.h"
 
10
#include "colormaps.h"
 
11
#include "decorations.h"
 
12
#include "drawing.h"
 
13
#include "events.h"
 
14
#include "iconmgr.h"
 
15
#include "image.h"
 
16
#include "otp.h"
 
17
#include "screen.h"
 
18
#include "win_iconify.h"
 
19
#include "win_ops.h"
 
20
#include "win_utils.h"
 
21
 
 
22
 
 
23
/*
 
24
 * Update the visuals of a window (e.g., its own decorations and its
 
25
 * representation in the icon manager) for having/losing focus.
 
26
 *
 
27
 * Formerly in util.c
 
28
 */
 
29
void
 
30
SetFocusVisualAttributes(TwmWindow *tmp_win, bool focus)
 
31
{
 
32
        if(! tmp_win) {
 
33
                return;
 
34
        }
 
35
 
 
36
        if(focus == tmp_win->hasfocusvisible) {
 
37
                return;
 
38
        }
 
39
        if(tmp_win->highlight) {
 
40
                if(Scr->use3Dborders) {
 
41
                        PaintBorders(tmp_win, focus);
 
42
                }
 
43
                else {
 
44
                        if(focus) {
 
45
                                XSetWindowBorder(dpy, tmp_win->frame, tmp_win->borderC.back);
 
46
                                if(tmp_win->title_w) {
 
47
                                        XSetWindowBorder(dpy, tmp_win->title_w, tmp_win->borderC.back);
 
48
                                }
 
49
                        }
 
50
                        else {
 
51
                                /*
 
52
                                 * XXX It seems possible this could be replaced by a
 
53
                                 * single global 'gray' pixmap; I don't think it actually
 
54
                                 * varies per window, and I don't see any obvious reason
 
55
                                 * it can't be reused, so we may be able to save an
 
56
                                 * allocation for each window by doing so...
 
57
                                 */
 
58
                                XSetWindowBorderPixmap(dpy, tmp_win->frame, tmp_win->gray);
 
59
                                if(tmp_win->title_w) {
 
60
                                        XSetWindowBorderPixmap(dpy, tmp_win->title_w, tmp_win->gray);
 
61
                                }
 
62
                        }
 
63
                }
 
64
        }
 
65
 
 
66
        if(focus) {
 
67
                bool hil = false;
 
68
 
 
69
                if(tmp_win->lolite_wl) {
 
70
                        XUnmapWindow(dpy, tmp_win->lolite_wl);
 
71
                }
 
72
                if(tmp_win->lolite_wr) {
 
73
                        XUnmapWindow(dpy, tmp_win->lolite_wr);
 
74
                }
 
75
                if(tmp_win->hilite_wl) {
 
76
                        XMapWindow(dpy, tmp_win->hilite_wl);
 
77
                        hil = true;
 
78
                }
 
79
                if(tmp_win->hilite_wr) {
 
80
                        XMapWindow(dpy, tmp_win->hilite_wr);
 
81
                        hil = true;
 
82
                }
 
83
                if(hil && tmp_win->HiliteImage && tmp_win->HiliteImage->next) {
 
84
                        MaybeAnimate = true;
 
85
                }
 
86
                if(tmp_win->iconmanagerlist) {
 
87
                        ActiveIconManager(tmp_win->iconmanagerlist);
 
88
                }
 
89
        }
 
90
        else {
 
91
                if(tmp_win->hilite_wl) {
 
92
                        XUnmapWindow(dpy, tmp_win->hilite_wl);
 
93
                }
 
94
                if(tmp_win->hilite_wr) {
 
95
                        XUnmapWindow(dpy, tmp_win->hilite_wr);
 
96
                }
 
97
                if(tmp_win->lolite_wl) {
 
98
                        XMapWindow(dpy, tmp_win->lolite_wl);
 
99
                }
 
100
                if(tmp_win->lolite_wr) {
 
101
                        XMapWindow(dpy, tmp_win->lolite_wr);
 
102
                }
 
103
                if(tmp_win->iconmanagerlist) {
 
104
                        NotActiveIconManager(tmp_win->iconmanagerlist);
 
105
                }
 
106
        }
 
107
        if(Scr->use3Dtitles && Scr->SunkFocusWindowTitle && tmp_win->title_height) {
 
108
                ButtonState bs;
 
109
 
 
110
                bs = focus ? on : off;
 
111
                Draw3DBorder(tmp_win->title_w, Scr->TBInfo.titlex, 0,
 
112
                             tmp_win->title_width - Scr->TBInfo.titlex -
 
113
                             Scr->TBInfo.rightoff - Scr->TitlePadding,
 
114
                             Scr->TitleHeight, Scr->TitleShadowDepth,
 
115
                             tmp_win->title, bs, false, false);
 
116
        }
 
117
        tmp_win->hasfocusvisible = focus;
 
118
}
 
119
 
 
120
 
 
121
/*
 
122
 * Shift the focus to a given window, and do whatever subsidiary ops that
 
123
 * entails.
 
124
 *
 
125
 * Formerly in util.c
 
126
 */
 
127
void
 
128
SetFocus(TwmWindow *tmp_win, Time tim)
 
129
{
 
130
        Window w = (tmp_win ? tmp_win->w : PointerRoot);
 
131
        bool f_iconmgr = false;
 
132
 
 
133
        if(Scr->Focus && (Scr->Focus->isiconmgr)) {
 
134
                f_iconmgr = true;
 
135
        }
 
136
        if(Scr->SloppyFocus && (w == PointerRoot) && (!f_iconmgr)) {
 
137
                return;
 
138
        }
 
139
 
 
140
        XSetInputFocus(dpy, w, RevertToPointerRoot, tim);
 
141
#ifdef EWMH
 
142
        EwmhSet_NET_ACTIVE_WINDOW(w);
 
143
#endif
 
144
        if(Scr->Focus == tmp_win) {
 
145
                return;
 
146
        }
 
147
 
 
148
        if(Scr->Focus) {
 
149
                if(Scr->Focus->AutoSqueeze && !Scr->Focus->squeezed) {
 
150
                        AutoSqueeze(Scr->Focus);
 
151
                }
 
152
                SetFocusVisualAttributes(Scr->Focus, false);
 
153
        }
 
154
        if(tmp_win)    {
 
155
                if(tmp_win->AutoSqueeze && tmp_win->squeezed) {
 
156
                        AutoSqueeze(tmp_win);
 
157
                }
 
158
                SetFocusVisualAttributes(tmp_win, true);
 
159
        }
 
160
        Scr->Focus = tmp_win;
 
161
}
 
162
 
 
163
 
 
164
/*
 
165
 * Move the focus straight to the root, with associated cleanup.
 
166
 *
 
167
 * Formerly in menus.c
 
168
 */
 
169
void FocusOnRoot(void)
 
170
{
 
171
        SetFocus(NULL, EventTime);
 
172
        InstallColormaps(0, &Scr->RootColormaps);
 
173
        if(! Scr->ClickToFocus) {
 
174
                Scr->FocusRoot = true;
 
175
        }
 
176
}
 
177
 
 
178
 
 
179
/*
 
180
 * Handle doing squeezing bits for AutoSqueeze{} windows.
 
181
 *
 
182
 * Formerly in menus.c
 
183
 */
 
184
void
 
185
AutoSqueeze(TwmWindow *tmp_win)
 
186
{
 
187
        if(tmp_win->isiconmgr) {
 
188
                return;
 
189
        }
 
190
        if(Scr->RaiseWhenAutoUnSqueeze && tmp_win->squeezed) {
 
191
                OtpRaise(tmp_win, WinWin);
 
192
        }
 
193
        Squeeze(tmp_win);
 
194
}
 
195
 
 
196
 
 
197
/*
 
198
 * Toggle a window's squeezed state.
 
199
 *
 
200
 * Formerly in menus.c
 
201
 */
 
202
void
 
203
Squeeze(TwmWindow *tmp_win)
 
204
{
 
205
        long fx, fy, savex, savey;
 
206
        int  neww, newh;
 
207
        bool south;
 
208
        int  grav = ((tmp_win->hints.flags & PWinGravity)
 
209
                     ? tmp_win->hints.win_gravity : NorthWestGravity);
 
210
        long eventMask;
 
211
        if(tmp_win->squeezed) {
 
212
                tmp_win->squeezed = False;
 
213
#ifdef EWMH
 
214
                EwmhSet_NET_WM_STATE(tmp_win, EWMH_STATE_SHADED);
 
215
#endif /* EWMH */
 
216
                if(!tmp_win->isicon) {
 
217
                        XMapWindow(dpy, tmp_win->w);
 
218
                }
 
219
                SetupWindow(tmp_win, tmp_win->actual_frame_x, tmp_win->actual_frame_y,
 
220
                            tmp_win->actual_frame_width, tmp_win->actual_frame_height, -1);
 
221
                ReMapTransients(tmp_win);
 
222
                return;
 
223
        }
 
224
 
 
225
        newh = tmp_win->title_height + 2 * tmp_win->frame_bw3D;
 
226
        if(newh < 3) {
 
227
                XBell(dpy, 0);
 
228
                return;
 
229
        }
 
230
        switch(grav) {
 
231
                case SouthWestGravity :
 
232
                case SouthGravity :
 
233
                case SouthEastGravity :
 
234
                        south = true;
 
235
                        break;
 
236
                default :
 
237
                        south = false;
 
238
                        break;
 
239
        }
 
240
        if(tmp_win->title_height && !tmp_win->AlwaysSqueezeToGravity) {
 
241
                south = false;
 
242
        }
 
243
 
 
244
        tmp_win->squeezed = true;
 
245
        tmp_win->actual_frame_width  = tmp_win->frame_width;
 
246
        tmp_win->actual_frame_height = tmp_win->frame_height;
 
247
        savex = fx = tmp_win->frame_x;
 
248
        savey = fy = tmp_win->frame_y;
 
249
        neww  = tmp_win->actual_frame_width;
 
250
        if(south) {
 
251
                fy += tmp_win->frame_height - newh;
 
252
        }
 
253
        if(tmp_win->squeeze_info) {
 
254
                fx  += tmp_win->title_x - tmp_win->frame_bw3D;
 
255
                neww = tmp_win->title_width + 2 * (tmp_win->frame_bw + tmp_win->frame_bw3D);
 
256
        }
 
257
 
 
258
        eventMask = mask_out_event(tmp_win->w, StructureNotifyMask);
 
259
#ifdef EWMH
 
260
        EwmhSet_NET_WM_STATE(tmp_win, EWMH_STATE_SHADED);
 
261
#endif /* EWMH */
 
262
        XUnmapWindow(dpy, tmp_win->w);
 
263
        restore_mask(tmp_win->w, eventMask);
 
264
 
 
265
        if(fx + neww >= Scr->rootw - Scr->BorderRight) {
 
266
                fx = Scr->rootw - Scr->BorderRight - neww;
 
267
        }
 
268
        if(fy + newh >= Scr->rooth - Scr->BorderBottom) {
 
269
                fy = Scr->rooth - Scr->BorderBottom - newh;
 
270
        }
 
271
        SetupWindow(tmp_win, fx, fy, neww, newh, -1);
 
272
        tmp_win->actual_frame_x = savex;
 
273
        tmp_win->actual_frame_y = savey;
 
274
 
 
275
        /* Now make the group members disappear */
 
276
        UnmapTransients(tmp_win, false, eventMask);
 
277
}
 
278
 
 
279
 
 
280
/***********************************************************************
 
281
 *
 
282
 *  Procedure:
 
283
 *      MoveOutline - move a window outline
 
284
 *
 
285
 *  Inputs:
 
286
 *      root        - the window we are outlining
 
287
 *      x           - upper left x coordinate
 
288
 *      y           - upper left y coordinate
 
289
 *      width       - the width of the rectangle
 
290
 *      height      - the height of the rectangle
 
291
 *      bw          - the border width of the frame
 
292
 *      th          - title height
 
293
 *
 
294
 ***********************************************************************
 
295
 */
 
296
void
 
297
MoveOutline(Window root, int x, int y, int width, int height, int bw, int th)
 
298
{
 
299
        static int  lastx = 0;
 
300
        static int  lasty = 0;
 
301
        static int  lastWidth = 0;
 
302
        static int  lastHeight = 0;
 
303
        static int  lastBW = 0;
 
304
        static int  lastTH = 0;
 
305
        int         xl, xr, yt, yb, xinnerl, xinnerr, yinnert, yinnerb;
 
306
        int         xthird, ythird;
 
307
        XSegment    outline[18];
 
308
        XSegment   *r;
 
309
 
 
310
        if(x == lastx && y == lasty && width == lastWidth && height == lastHeight
 
311
                        && lastBW == bw && th == lastTH) {
 
312
                return;
 
313
        }
 
314
 
 
315
        r = outline;
 
316
 
 
317
#define DRAWIT() \
 
318
    if (lastWidth || lastHeight)                        \
 
319
    {                                                   \
 
320
        xl = lastx;                                     \
 
321
        xr = lastx + lastWidth - 1;                     \
 
322
        yt = lasty;                                     \
 
323
        yb = lasty + lastHeight - 1;                    \
 
324
        xinnerl = xl + lastBW;                          \
 
325
        xinnerr = xr - lastBW;                          \
 
326
        yinnert = yt + lastTH + lastBW;                 \
 
327
        yinnerb = yb - lastBW;                          \
 
328
        xthird = (xinnerr - xinnerl) / 3;               \
 
329
        ythird = (yinnerb - yinnert) / 3;               \
 
330
                                                        \
 
331
        r->x1 = xl;                                     \
 
332
        r->y1 = yt;                                     \
 
333
        r->x2 = xr;                                     \
 
334
        r->y2 = yt;                                     \
 
335
        r++;                                            \
 
336
                                                        \
 
337
        r->x1 = xl;                                     \
 
338
        r->y1 = yb;                                     \
 
339
        r->x2 = xr;                                     \
 
340
        r->y2 = yb;                                     \
 
341
        r++;                                            \
 
342
                                                        \
 
343
        r->x1 = xl;                                     \
 
344
        r->y1 = yt;                                     \
 
345
        r->x2 = xl;                                     \
 
346
        r->y2 = yb;                                     \
 
347
        r++;                                            \
 
348
                                                        \
 
349
        r->x1 = xr;                                     \
 
350
        r->y1 = yt;                                     \
 
351
        r->x2 = xr;                                     \
 
352
        r->y2 = yb;                                     \
 
353
        r++;                                            \
 
354
                                                        \
 
355
        r->x1 = xinnerl + xthird;                       \
 
356
        r->y1 = yinnert;                                \
 
357
        r->x2 = r->x1;                                  \
 
358
        r->y2 = yinnerb;                                \
 
359
        r++;                                            \
 
360
                                                        \
 
361
        r->x1 = xinnerl + (2 * xthird);                 \
 
362
        r->y1 = yinnert;                                \
 
363
        r->x2 = r->x1;                                  \
 
364
        r->y2 = yinnerb;                                \
 
365
        r++;                                            \
 
366
                                                        \
 
367
        r->x1 = xinnerl;                                \
 
368
        r->y1 = yinnert + ythird;                       \
 
369
        r->x2 = xinnerr;                                \
 
370
        r->y2 = r->y1;                                  \
 
371
        r++;                                            \
 
372
                                                        \
 
373
        r->x1 = xinnerl;                                \
 
374
        r->y1 = yinnert + (2 * ythird);                 \
 
375
        r->x2 = xinnerr;                                \
 
376
        r->y2 = r->y1;                                  \
 
377
        r++;                                            \
 
378
                                                        \
 
379
        if (lastTH != 0) {                              \
 
380
            r->x1 = xl;                                 \
 
381
            r->y1 = yt + lastTH;                        \
 
382
            r->x2 = xr;                                 \
 
383
            r->y2 = r->y1;                              \
 
384
            r++;                                        \
 
385
        }                                               \
 
386
    }
 
387
 
 
388
        /* undraw the old one, if any */
 
389
        DRAWIT();
 
390
 
 
391
        lastx = x;
 
392
        lasty = y;
 
393
        lastWidth = width;
 
394
        lastHeight = height;
 
395
        lastBW = bw;
 
396
        lastTH = th;
 
397
 
 
398
        /* draw the new one, if any */
 
399
        DRAWIT();
 
400
 
 
401
#undef DRAWIT
 
402
 
 
403
 
 
404
        if(r != outline) {
 
405
                XDrawSegments(dpy, root, Scr->DrawGC, outline, r - outline);
 
406
        }
 
407
}