2
* Various operations done on windows.
10
#include "colormaps.h"
11
#include "decorations.h"
18
#include "win_iconify.h"
20
#include "win_utils.h"
24
* Update the visuals of a window (e.g., its own decorations and its
25
* representation in the icon manager) for having/losing focus.
30
SetFocusVisualAttributes(TwmWindow *tmp_win, bool focus)
36
if(focus == tmp_win->hasfocusvisible) {
39
if(tmp_win->highlight) {
40
if(Scr->use3Dborders) {
41
PaintBorders(tmp_win, 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);
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...
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);
69
if(tmp_win->lolite_wl) {
70
XUnmapWindow(dpy, tmp_win->lolite_wl);
72
if(tmp_win->lolite_wr) {
73
XUnmapWindow(dpy, tmp_win->lolite_wr);
75
if(tmp_win->hilite_wl) {
76
XMapWindow(dpy, tmp_win->hilite_wl);
79
if(tmp_win->hilite_wr) {
80
XMapWindow(dpy, tmp_win->hilite_wr);
83
if(hil && tmp_win->HiliteImage && tmp_win->HiliteImage->next) {
86
if(tmp_win->iconmanagerlist) {
87
ActiveIconManager(tmp_win->iconmanagerlist);
91
if(tmp_win->hilite_wl) {
92
XUnmapWindow(dpy, tmp_win->hilite_wl);
94
if(tmp_win->hilite_wr) {
95
XUnmapWindow(dpy, tmp_win->hilite_wr);
97
if(tmp_win->lolite_wl) {
98
XMapWindow(dpy, tmp_win->lolite_wl);
100
if(tmp_win->lolite_wr) {
101
XMapWindow(dpy, tmp_win->lolite_wr);
103
if(tmp_win->iconmanagerlist) {
104
NotActiveIconManager(tmp_win->iconmanagerlist);
107
if(Scr->use3Dtitles && Scr->SunkFocusWindowTitle && tmp_win->title_height) {
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);
117
tmp_win->hasfocusvisible = focus;
122
* Shift the focus to a given window, and do whatever subsidiary ops that
128
SetFocus(TwmWindow *tmp_win, Time tim)
130
Window w = (tmp_win ? tmp_win->w : PointerRoot);
131
bool f_iconmgr = false;
133
if(Scr->Focus && (Scr->Focus->isiconmgr)) {
136
if(Scr->SloppyFocus && (w == PointerRoot) && (!f_iconmgr)) {
140
XSetInputFocus(dpy, w, RevertToPointerRoot, tim);
142
EwmhSet_NET_ACTIVE_WINDOW(w);
144
if(Scr->Focus == tmp_win) {
149
if(Scr->Focus->AutoSqueeze && !Scr->Focus->squeezed) {
150
AutoSqueeze(Scr->Focus);
152
SetFocusVisualAttributes(Scr->Focus, false);
155
if(tmp_win->AutoSqueeze && tmp_win->squeezed) {
156
AutoSqueeze(tmp_win);
158
SetFocusVisualAttributes(tmp_win, true);
160
Scr->Focus = tmp_win;
165
* Move the focus straight to the root, with associated cleanup.
167
* Formerly in menus.c
169
void FocusOnRoot(void)
171
SetFocus(NULL, EventTime);
172
InstallColormaps(0, &Scr->RootColormaps);
173
if(! Scr->ClickToFocus) {
174
Scr->FocusRoot = true;
180
* Handle doing squeezing bits for AutoSqueeze{} windows.
182
* Formerly in menus.c
185
AutoSqueeze(TwmWindow *tmp_win)
187
if(tmp_win->isiconmgr) {
190
if(Scr->RaiseWhenAutoUnSqueeze && tmp_win->squeezed) {
191
OtpRaise(tmp_win, WinWin);
198
* Toggle a window's squeezed state.
200
* Formerly in menus.c
203
Squeeze(TwmWindow *tmp_win)
205
long fx, fy, savex, savey;
208
int grav = ((tmp_win->hints.flags & PWinGravity)
209
? tmp_win->hints.win_gravity : NorthWestGravity);
211
if(tmp_win->squeezed) {
212
tmp_win->squeezed = False;
214
EwmhSet_NET_WM_STATE(tmp_win, EWMH_STATE_SHADED);
216
if(!tmp_win->isicon) {
217
XMapWindow(dpy, tmp_win->w);
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);
225
newh = tmp_win->title_height + 2 * tmp_win->frame_bw3D;
231
case SouthWestGravity :
233
case SouthEastGravity :
240
if(tmp_win->title_height && !tmp_win->AlwaysSqueezeToGravity) {
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;
251
fy += tmp_win->frame_height - newh;
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);
258
eventMask = mask_out_event(tmp_win->w, StructureNotifyMask);
260
EwmhSet_NET_WM_STATE(tmp_win, EWMH_STATE_SHADED);
262
XUnmapWindow(dpy, tmp_win->w);
263
restore_mask(tmp_win->w, eventMask);
265
if(fx + neww >= Scr->rootw - Scr->BorderRight) {
266
fx = Scr->rootw - Scr->BorderRight - neww;
268
if(fy + newh >= Scr->rooth - Scr->BorderBottom) {
269
fy = Scr->rooth - Scr->BorderBottom - newh;
271
SetupWindow(tmp_win, fx, fy, neww, newh, -1);
272
tmp_win->actual_frame_x = savex;
273
tmp_win->actual_frame_y = savey;
275
/* Now make the group members disappear */
276
UnmapTransients(tmp_win, false, eventMask);
280
/***********************************************************************
283
* MoveOutline - move a window outline
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
294
***********************************************************************
297
MoveOutline(Window root, int x, int y, int width, int height, int bw, int th)
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;
307
XSegment outline[18];
310
if(x == lastx && y == lasty && width == lastWidth && height == lastHeight
311
&& lastBW == bw && th == lastTH) {
318
if (lastWidth || lastHeight) \
321
xr = lastx + lastWidth - 1; \
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; \
355
r->x1 = xinnerl + xthird; \
361
r->x1 = xinnerl + (2 * xthird); \
368
r->y1 = yinnert + ythird; \
374
r->y1 = yinnert + (2 * ythird); \
381
r->y1 = yt + lastTH; \
388
/* undraw the old one, if any */
398
/* draw the new one, if any */
405
XDrawSegments(dpy, root, Scr->DrawGC, outline, r - outline);