3
This program is free software; you can redistribute it and/or modify
4
it under the terms of the GNU General Public License as published by
5
the Free Software Foundation; either version 2, or (at your option)
8
This program is distributed in the hope that it will be useful,
9
but WITHOUT ANY WARRANTY; without even the implied warranty of
10
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
GNU General Public License for more details.
13
You should have received a copy of the GNU General Public License
14
along with this program; if not, write to the Free Software
15
Foundation, Inc., Inc., 51 Franklin Street, Fifth Floor, Boston,
19
oroborus - (c) 2001 Ken Lynch
20
xfwm4 - (c) 2002-2011 Olivier Fourdan
30
#include <X11/Xutil.h>
31
#include <X11/Xatom.h>
32
#include <X11/extensions/shape.h>
42
#include "moveresize.h"
43
#include "placement.h"
47
#include "transients.h"
48
#include "event_filter.h"
49
#include "workspaces.h"
52
#define MOVERESIZE_EVENT_MASK \
58
#define TILE_DISTANCE 2
60
typedef struct _MoveResizeData MoveResizeData;
61
struct _MoveResizeData
66
gboolean is_transient;
67
gboolean move_resized;
70
gint cancel_x, cancel_y;
71
gint cancel_w, cancel_h;
72
guint cancel_workspace;
74
gint px, py; /* pointer relative position */
83
clientSetSize (Client * c, int *size, int size_min, int size_max, int size_inc, gboolean source_is_application)
87
g_return_if_fail (c != NULL);
88
g_return_if_fail (size != NULL);
89
TRACE ("entering clientSetSize");
91
/* Bypass resize increment and max sizes for fullscreen */
92
if (!FLAG_TEST (c->flags, CLIENT_FLAG_FULLSCREEN)
93
&& !(FLAG_TEST_ALL (c->flags, CLIENT_FLAG_MAXIMIZED)
94
&& (c->screen_info->params->borderless_maximize)))
96
if (!source_is_application && (c->size->flags & PResizeInc) && (size_inc))
98
temp = (*size - size_min) / size_inc;
99
*size = size_min + (temp * size_inc);
101
if (c->size->flags & PMaxSize)
103
if (*size > size_max)
110
if (c->size->flags & PMinSize)
112
if (*size < size_min)
124
clientSetWidth (Client * c, int w, gboolean source_is_application)
128
g_return_if_fail (c != NULL);
129
TRACE ("entering clientSetWidth");
130
TRACE ("setting width %i for client \"%s\" (0x%lx)", w, c->name, c->window);
133
clientSetSize (c, &temp, c->size->min_width, c->size->max_width, c->size->width_inc, source_is_application);
138
clientSetHeight (Client * c, int h, gboolean source_is_application)
142
g_return_if_fail (c != NULL);
143
TRACE ("entering clientSetHeight");
144
TRACE ("setting height %i for client \"%s\" (0x%lx)", h, c->name, c->window);
147
clientSetSize (c, &temp, c->size->min_height, c->size->max_height, c->size->height_inc, source_is_application);
152
clientMovePointer (DisplayInfo *display_info, gint dx, gint dy, guint repeat)
155
for (i = 0; i < repeat; ++i)
157
XWarpPointer (display_info->dpy, None, None, 0, 0, 0, 0, dx, dy);
162
clientKeyPressIsModifier (XEvent *xevent)
164
int keysym = XLookupKeysym (&xevent->xkey, 0);
165
return (gboolean) IsModifierKey(keysym);
169
clientSetHandle(MoveResizeData *passdata, int handle)
171
ScreenInfo *screen_info;
172
DisplayInfo *display_info;
177
screen_info = c->screen_info;
178
display_info = screen_info->display_info;
182
case CORNER_BOTTOM_LEFT:
183
px = frameX (c) + frameLeft(c) / 2;
184
py = frameY (c) + frameHeight (c) - frameBottom(c) / 2;
186
case CORNER_BOTTOM_RIGHT:
187
px = frameX (c) + frameWidth (c) - frameRight(c) / 2;
188
py = frameY (c) + frameHeight (c) - frameBottom(c) / 2;
190
case CORNER_TOP_LEFT:
191
px = frameX (c) + frameLeft(c) / 2;
194
case CORNER_TOP_RIGHT:
195
px = frameX (c) + frameWidth (c) - frameRight(c) / 2;
198
case CORNER_COUNT + SIDE_LEFT:
199
px = frameX (c) + frameLeft(c) / 2;
200
py = frameY (c) + frameHeight (c) / 2;
202
case CORNER_COUNT + SIDE_RIGHT:
203
px = frameX (c) + frameWidth (c) - frameRight(c) / 2;
204
py = frameY (c) + frameHeight (c) / 2;
206
case CORNER_COUNT + SIDE_TOP:
207
px = frameX (c) + frameWidth (c) / 2;
210
case CORNER_COUNT + SIDE_BOTTOM:
211
px = frameX (c) + frameWidth (c) / 2;
212
py = frameY (c) + frameHeight (c) - frameBottom(c) / 2;
215
px = frameX (c) + frameWidth (c) / 2;
216
py = frameY (c) + frameHeight (c) / 2;
220
XWarpPointer (display_info->dpy, None, screen_info->xroot, 0, 0, 0, 0, px, py);
221
/* Update internal data */
222
passdata->handle = handle;
225
passdata->px = passdata->mx - frameX (c);
226
passdata->py = passdata->my - frameY (c);
229
passdata->ow = c->width;
230
passdata->oh = c->height;
233
/* clientConstrainRatio - adjust the given width and height to account for
234
the constraints imposed by size hints
236
The aspect ratio stuff, is borrowed from uwm's CheckConsistency routine.
239
#define MAKE_MULT(a,b) ((b==1) ? (a) : (((int)((a)/(b))) * (b)) )
241
clientConstrainRatio (Client * c, int handle)
244
g_return_if_fail (c != NULL);
245
TRACE ("entering clientConstrainRatio");
246
TRACE ("client \"%s\" (0x%lx)", c->name, c->window);
248
if (c->size->flags & PAspect)
250
int xinc, yinc, minx, miny, maxx, maxy, delta;
252
xinc = c->size->width_inc;
253
yinc = c->size->height_inc;
254
minx = c->size->min_aspect.x;
255
miny = c->size->min_aspect.y;
256
maxx = c->size->max_aspect.x;
257
maxy = c->size->max_aspect.y;
259
if ((minx * c->height > miny * c->width) && (miny) &&
260
((handle == CORNER_COUNT + SIDE_TOP) || (handle == CORNER_COUNT + SIDE_BOTTOM)))
262
/* Change width to match */
263
delta = MAKE_MULT (minx * c->height / miny - c->width, xinc);
264
if (!(c->size->flags & PMaxSize) ||
265
(c->width + delta <= c->size->max_width))
270
if ((minx * c->height > miny * c->width) && (minx))
272
delta = MAKE_MULT (c->height - c->width * miny / minx, yinc);
273
if (!(c->size->flags & PMinSize) ||
274
(c->height - delta >= c->size->min_height))
280
delta = MAKE_MULT (minx * c->height / miny - c->width, xinc);
281
if (!(c->size->flags & PMaxSize) ||
282
(c->width + delta <= c->size->max_width))
287
if ((maxx * c->height < maxy * c->width) && (maxx) &&
288
((handle == CORNER_COUNT + SIDE_LEFT) || (handle == CORNER_COUNT + SIDE_RIGHT)))
290
delta = MAKE_MULT (c->width * maxy / maxx - c->height, yinc);
291
if (!(c->size->flags & PMaxSize) ||
292
(c->height + delta <= c->size->max_height))
297
if ((maxx * c->height < maxy * c->width) && (maxy))
299
delta = MAKE_MULT (c->width - maxx * c->height / maxy, xinc);
300
if (!(c->size->flags & PMinSize) ||
301
(c->width - delta >= c->size->min_width))
307
delta = MAKE_MULT (c->width * maxy / maxx - c->height, yinc);
308
if (!(c->size->flags & PMaxSize) ||
309
(c->height + delta <= c->size->max_height))
319
clientDrawOutline (Client * c)
321
TRACE ("entering clientDrawOutline");
323
XDrawRectangle (clientGetXDisplay (c), c->screen_info->xroot, c->screen_info->box_gc, frameX (c), frameY (c),
324
frameWidth (c) - 1, frameHeight (c) - 1);
325
if (FLAG_TEST (c->xfwm_flags, XFWM_FLAG_HAS_BORDER)
326
&&!FLAG_TEST (c->flags, CLIENT_FLAG_FULLSCREEN | CLIENT_FLAG_SHADED))
328
XDrawRectangle (clientGetXDisplay (c), c->screen_info->xroot, c->screen_info->box_gc, c->x, c->y, c->width - 1,
334
clientCheckOverlap (int s1, int e1, int s2, int e2)
336
/* Simple overlap test for an arbitary axis. -Cliff */
337
if ((s1 >= s2 && s1 <= e2) ||
338
(e1 >= s2 && e1 <= e2) ||
339
(s2 >= s1 && s2 <= e1) ||
340
(e2 >= s1 && e2 <= e1))
348
clientFindClosestEdgeX (Client *c, int edge_pos)
350
/* Find the closest edge of anything that we can snap to, taking
351
frames into account, or just return the original value if nothing
352
is within the snapping range. -Cliff */
355
ScreenInfo *screen_info;
357
int snap_width, closest;
359
screen_info = c->screen_info;
360
snap_width = screen_info->params->snap_width;
361
closest = edge_pos + snap_width + 2; /* This only needs to be out of the snap range to work. -Cliff */
363
for (c2 = screen_info->clients, i = 0; i < screen_info->client_count; c2 = c2->next, i++)
365
if (FLAG_TEST (c2->xfwm_flags, XFWM_FLAG_VISIBLE) && (c2 != c) &&
366
(((screen_info->params->snap_to_windows) && (c2->win_layer == c->win_layer))
367
|| ((screen_info->params->snap_to_border)
368
&& FLAG_TEST (c2->flags, CLIENT_FLAG_HAS_STRUT)
369
&& FLAG_TEST (c2->xfwm_flags, XFWM_FLAG_VISIBLE))))
372
if (clientCheckOverlap (c->y - frameTop (c) - 1, c->y + c->height + frameBottom (c) + 1, c2->y - frameTop (c) - 1, c2->y + c2->height + frameBottom (c) + 1))
374
if (abs (c2->x - frameLeft (c2) - edge_pos) < abs (closest - edge_pos))
376
closest = c2->x - frameLeft (c2);
378
if (abs ((c2->x + c2->width) + frameRight (c2) - edge_pos) < abs (closest - edge_pos))
380
closest = (c2->x + c2->width) + frameRight (c2);
386
if (abs (closest - edge_pos) > snap_width)
395
clientFindClosestEdgeY (Client *c, int edge_pos)
397
/* This function is mostly identical to the one above, but swaps the
398
axes. If there's a better way to do it than this, I'd like to
402
ScreenInfo *screen_info;
404
int snap_width, closest;
406
screen_info = c->screen_info;
407
snap_width = screen_info->params->snap_width;
408
closest = edge_pos + snap_width + 1; /* This only needs to be out of the snap range to work. -Cliff */
410
for (c2 = screen_info->clients, i = 0; i < screen_info->client_count; c2 = c2->next, i++)
412
if (FLAG_TEST (c2->xfwm_flags, XFWM_FLAG_VISIBLE) && (c2 != c) &&
413
(((screen_info->params->snap_to_windows) && (c2->win_layer == c->win_layer))
414
|| ((screen_info->params->snap_to_border)
415
&& FLAG_TEST (c2->flags, CLIENT_FLAG_HAS_STRUT)
416
&& FLAG_TEST (c2->xfwm_flags, XFWM_FLAG_VISIBLE))))
419
if (clientCheckOverlap (c->x - frameLeft (c) - 1, c->x + c->width + frameRight (c) + 1, c2->x - frameLeft (c) - 1, c2->x + c2->width + frameRight (c) + 1))
421
if (abs (c2->y - frameTop(c2) - edge_pos) < abs (closest - edge_pos))
423
closest = c2->y - frameTop (c2);
425
if (abs ((c2->y + c2->height) + frameBottom (c2) - edge_pos) < abs (closest - edge_pos))
427
closest = (c2->y + c2->height) + frameBottom (c2);
433
if (abs (closest - edge_pos) > snap_width)
442
clientSnapPosition (Client * c, int prev_x, int prev_y)
444
ScreenInfo *screen_info;
448
int disp_x, disp_y, disp_max_x, disp_max_y;
449
int frame_x, frame_y, frame_height, frame_width;
450
int frame_top, frame_left;
451
int frame_x2, frame_y2;
452
int best_frame_x, best_frame_y;
453
int best_delta_x, best_delta_y;
454
int c_frame_x1, c_frame_x2, c_frame_y1, c_frame_y2;
457
g_return_if_fail (c != NULL);
458
TRACE ("entering clientSnapPosition");
459
TRACE ("Snapping client \"%s\" (0x%lx)", c->name, c->window);
461
screen_info = c->screen_info;
462
best_delta_x = screen_info->params->snap_width + 1;
463
best_delta_y = screen_info->params->snap_width + 1;
465
frame_x = frameX (c);
466
frame_y = frameY (c);
467
frame_height = frameHeight (c);
468
frame_width = frameWidth (c);
469
frame_top = frameTop (c);
470
frame_left = frameLeft (c);
472
cx = frame_x + (frame_width / 2);
473
cy = frame_y + (frame_height / 2);
475
frame_x2 = frame_x + frame_width;
476
frame_y2 = frame_y + frame_height;
477
best_frame_x = frame_x;
478
best_frame_y = frame_y;
480
myScreenFindMonitorAtPoint (screen_info, cx, cy, &rect);
484
disp_max_x = rect.x + rect.width;
485
disp_max_y = rect.y + rect.height;
487
if (screen_info->params->snap_to_border)
489
if (abs (disp_x - frame_x) < abs (disp_max_x - frame_x2))
491
if (!screen_info->params->snap_resist || ((frame_x <= disp_x) && (c->x < prev_x)))
493
best_delta_x = abs (disp_x - frame_x);
494
best_frame_x = disp_x;
499
if (!screen_info->params->snap_resist || ((frame_x2 >= disp_max_x) && (c->x > prev_x)))
501
best_delta_x = abs (disp_max_x - frame_x2);
502
best_frame_x = disp_max_x - frame_width;
506
if (abs (disp_y - frame_y) < abs (disp_max_y - frame_y2))
508
if (!screen_info->params->snap_resist || ((frame_y <= disp_y) && (c->y < prev_y)))
510
best_delta_y = abs (disp_y - frame_y);
511
best_frame_y = disp_y;
516
if (!screen_info->params->snap_resist || ((frame_y2 >= disp_max_y) && (c->y > prev_y)))
518
best_delta_y = abs (disp_max_y - frame_y2);
519
best_frame_y = disp_max_y - frame_height;
524
for (c2 = screen_info->clients, i = 0; i < screen_info->client_count; c2 = c2->next, i++)
526
if (FLAG_TEST (c2->xfwm_flags, XFWM_FLAG_VISIBLE) && (c2 != c) &&
527
(((screen_info->params->snap_to_windows) && (c2->win_layer == c->win_layer))
528
|| ((screen_info->params->snap_to_border)
529
&& FLAG_TEST (c2->flags, CLIENT_FLAG_HAS_STRUT)
530
&& FLAG_TEST (c2->xfwm_flags, XFWM_FLAG_VISIBLE))))
532
c_frame_x1 = frameX (c2);
533
c_frame_x2 = c_frame_x1 + frameWidth (c2);
534
c_frame_y1 = frameY (c2);
535
c_frame_y2 = c_frame_y1 + frameHeight (c2);
537
if ((c_frame_y1 <= frame_y2) && (c_frame_y2 >= frame_y))
539
delta = abs (c_frame_x2 - frame_x);
540
if (delta < best_delta_x)
542
if (!screen_info->params->snap_resist || ((frame_x <= c_frame_x2) && (c->x < prev_x)))
544
best_delta_x = delta;
545
best_frame_x = c_frame_x2;
549
delta = abs (c_frame_x1 - frame_x2);
550
if (delta < best_delta_x)
552
if (!screen_info->params->snap_resist || ((frame_x2 >= c_frame_x1) && (c->x > prev_x)))
554
best_delta_x = delta;
555
best_frame_x = c_frame_x1 - frame_width;
560
if ((c_frame_x1 <= frame_x2) && (c_frame_x2 >= frame_x))
562
delta = abs (c_frame_y2 - frame_y);
563
if (delta < best_delta_y)
565
if (!screen_info->params->snap_resist || ((frame_y <= c_frame_y2) && (c->y < prev_y)))
567
best_delta_y = delta;
568
best_frame_y = c_frame_y2;
572
delta = abs (c_frame_y1 - frame_y2);
573
if (delta < best_delta_y)
575
if (!screen_info->params->snap_resist || ((frame_y2 >= c_frame_y1) && (c->y > prev_y)))
577
best_delta_y = delta;
578
best_frame_y = c_frame_y1 - frame_height;
585
if (best_delta_x <= screen_info->params->snap_width)
587
c->x = best_frame_x + frame_left;
589
if (best_delta_y <= screen_info->params->snap_width)
591
c->y = best_frame_y + frame_top;
595
static eventFilterStatus
596
clientButtonReleaseFilter (XEvent * xevent, gpointer data)
598
MoveResizeData *passdata = (MoveResizeData *) data;
600
TRACE ("entering clientButtonReleaseFilter");
602
if ((xevent->type == ButtonRelease) &&
603
(xevent->xbutton.button == passdata->button))
606
return EVENT_FILTER_STOP;
609
return EVENT_FILTER_CONTINUE;
613
clientMoveWarp (Client * c, XMotionEvent *xevent)
615
static guint32 lastresist = 0;
616
static int edge_scroll_x = 0;
617
static int edge_scroll_y = 0;
618
ScreenInfo *screen_info;
619
DisplayInfo *display_info;
620
gboolean warp_pointer = FALSE;
621
int msx, msy, maxx, maxy;
624
g_return_if_fail (c != NULL);
625
TRACE ("entering clientMoveWarp");
627
screen_info = c->screen_info;
628
display_info = screen_info->display_info;
638
if ((screen_info->params->wrap_windows) && (screen_info->params->wrap_resistance))
641
msx = xevent->x_root;
642
msy = xevent->y_root;
643
maxx = screen_info->width - 1;
644
maxy = screen_info->height - 1;
647
warp_pointer = FALSE;
649
if ((msx == 0) || (msx == maxx))
651
if ((xevent->time - lastresist) > 250) /* ms */
668
lastresist = xevent->time;
670
if ((msy == 0) || (msy == maxy))
672
if ((xevent->time - lastresist) > 250) /* ms */
689
lastresist = xevent->time;
692
if (edge_scroll_x > screen_info->params->wrap_resistance)
695
if ((msx == 0) || (msx == maxx))
697
delta = MAX (9 * maxx / 10, maxx - 5 * screen_info->params->wrap_resistance);
700
if (workspaceMove (screen_info, 0, -1, c, xevent->time))
707
if (workspaceMove (screen_info, 0, 1, c, xevent->time))
716
if (edge_scroll_y > screen_info->params->wrap_resistance)
719
if ((msy == 0) || (msy == maxy))
721
delta = MAX (9 * maxy / 10, maxy - 5 * screen_info->params->wrap_resistance);
724
if (workspaceMove (screen_info, -1, 0, c, xevent->time))
731
if (workspaceMove (screen_info, 1, 0, c, xevent->time))
743
XWarpPointer (display_info->dpy, None, None, 0, 0, 0, 0, rx, ry);
748
xevent->x_root = msx;
749
xevent->y_root = msy;
754
clientMoveTile (Client *c, XMotionEvent *xevent)
756
ScreenInfo *screen_info;
758
int x, y, disp_x, disp_y, disp_max_x, disp_max_y, dist;
759
NetWmDesktopLayout layout;
761
screen_info = c->screen_info;
764
* Tiling when moving really relies on restore_on_move to work
765
* reliably so just don't do anything if any of the above requirement
766
* is not met (restore_on_move being disabled is from another time,
767
* we should really not have such an option, I must have been weaked
770
if (!(screen_info->params->tile_on_move && screen_info->params->restore_on_move))
778
myScreenFindMonitorAtPoint (screen_info, x, y, &rect);
781
disp_max_x = rect.x + rect.width;
782
disp_max_y = rect.y + rect.height;
784
layout = screen_info->desktop_layout;
785
dist = MIN (TILE_DISTANCE, frameDecorationTop (screen_info) / 2);
787
if (!screen_info->params->wrap_windows || layout.cols < 2)
789
if ((x >= disp_x - 1) && (x < disp_x + dist) &&
790
(y >= disp_y - 1) && (y < disp_max_y + 1))
792
return clientTile (c, x, y, TILE_LEFT, !screen_info->params->box_move);
795
if ((x >= disp_max_x - dist) && (x < disp_max_x + 1) &&
796
(y >= disp_y - 1) && (y < disp_max_y + 1))
798
return clientTile (c, x, y, TILE_RIGHT, !screen_info->params->box_move);
802
if (!screen_info->params->wrap_windows || layout.rows < 2)
804
if ((x >= disp_x - 1) && (x < disp_max_x + 1) &&
805
(y >= disp_y - 1) && (y < disp_y + dist))
807
return clientTile (c, x, y, TILE_UP, !screen_info->params->box_move);
810
if ((x >= disp_x - 1) && (x < disp_max_x + 1) &&
811
(y >= disp_max_y - dist) && (y < disp_max_y + 1))
813
return clientTile (c, x, y, TILE_DOWN, !screen_info->params->box_move);
820
static eventFilterStatus
821
clientMoveEventFilter (XEvent * xevent, gpointer data)
823
static gboolean toggled_maximize = FALSE;
824
unsigned long configure_flags;
825
ScreenInfo *screen_info;
826
DisplayInfo *display_info;
827
eventFilterStatus status = EVENT_FILTER_STOP;
828
MoveResizeData *passdata = (MoveResizeData *) data;
830
gboolean moving = TRUE;
834
TRACE ("entering clientMoveEventFilter");
839
screen_info = c->screen_info;
840
display_info = screen_info->display_info;
841
configure_flags = NO_CFG_FLAG;
843
/* Update the display time */
844
myDisplayUpdateCurrentTime (display_info, xevent);
846
if (xevent->type == KeyPress)
850
while (XCheckMaskEvent (display_info->dpy, KeyPressMask, xevent))
852
/* Update the display time */
853
myDisplayUpdateCurrentTime (display_info, xevent);
857
if ((screen_info->params->snap_to_border) || (screen_info->params->snap_to_windows))
859
key_move = MAX (key_move, screen_info->params->snap_width + 1);
861
if (xevent->xkey.keycode == screen_info->params->keys[KEY_LEFT].keycode)
863
clientMovePointer (display_info, -1, 0, key_move);
865
else if (xevent->xkey.keycode == screen_info->params->keys[KEY_RIGHT].keycode)
867
clientMovePointer (display_info, 1, 0, key_move);
869
else if (xevent->xkey.keycode == screen_info->params->keys[KEY_UP].keycode)
871
clientMovePointer (display_info, 0, -1, key_move);
873
else if (xevent->xkey.keycode == screen_info->params->keys[KEY_DOWN].keycode)
875
clientMovePointer (display_info, 0, 1, key_move);
877
else if (xevent->xkey.keycode == screen_info->params->keys[KEY_CANCEL].keycode)
880
passdata->released = passdata->use_keys;
882
if (screen_info->params->box_move)
884
clientDrawOutline (c);
887
c->x = passdata->cancel_x;
888
c->y = passdata->cancel_y;
890
if (screen_info->params->box_move)
892
clientDrawOutline (c);
898
clientConfigure (c, &wc, CWX | CWY, configure_flags);
900
if (screen_info->current_ws != passdata->cancel_workspace)
902
workspaceSwitch (screen_info, passdata->cancel_workspace, c, FALSE, xevent->xkey.time);
904
if (toggled_maximize)
906
toggled_maximize = FALSE;
907
if (clientToggleMaximized (c, CLIENT_FLAG_MAXIMIZED, FALSE))
909
configure_flags = CFG_FORCE_REDRAW;
910
passdata->move_resized = TRUE;
914
else if (passdata->use_keys)
916
moving = clientKeyPressIsModifier(xevent);
919
else if (xevent->type == ButtonRelease)
922
passdata->released = passdata->use_keys || (xevent->xbutton.button == passdata->button);
924
else if (xevent->type == MotionNotify)
926
while (XCheckMaskEvent (display_info->dpy, PointerMotionMask | ButtonMotionMask, xevent))
928
/* Update the display time */
929
myDisplayUpdateCurrentTime (display_info, xevent);
931
if (!passdata->grab && screen_info->params->box_move)
933
myDisplayGrabServer (display_info);
934
passdata->grab = TRUE;
935
clientDrawOutline (c);
937
if (screen_info->params->box_move)
939
clientDrawOutline (c);
941
if ((screen_info->workspace_count > 1) && !(passdata->is_transient))
943
clientMoveWarp (c, (XMotionEvent *) xevent);
946
if ((screen_info->params->restore_on_move) && FLAG_TEST (c->flags, CLIENT_FLAG_MAXIMIZED))
949
if ((ABS (xevent->xmotion.x_root - passdata->mx) > 15) ||
950
(ABS (xevent->xmotion.y_root - passdata->my) > 15))
952
/* to keep the distance from the edges of the window proportional. */
953
double xratio, yratio;
955
xratio = (xevent->xmotion.x_root - frameX (c)) / (double) frameWidth (c);
956
yratio = (xevent->xmotion.y_root - frameY (c)) / (double) frameHeight (c);
958
if (FLAG_TEST_ALL(c->flags, CLIENT_FLAG_MAXIMIZED))
960
toggled_maximize = TRUE;
962
if (clientToggleMaximized (c, c->flags & CLIENT_FLAG_MAXIMIZED, FALSE))
964
passdata->move_resized = TRUE;
967
passdata->mx = frameX (c) + passdata->px;
968
if ((passdata->mx < frameX (c)) || (passdata->mx > frameX (c) + frameWidth (c)))
970
passdata->mx = CLAMP(frameX (c) + frameWidth (c) * xratio, frameX (c), frameX (c) + frameWidth (c));
974
passdata->my = frameY (c) + passdata->py;
975
if ((passdata->my < frameY (c)) || (passdata->my > frameY (c) + frameHeight (c)))
977
passdata->my = CLAMP(frameY (c) + frameHeight (c) * yratio, frameY (c), frameY (c) + frameHeight (c));
980
configure_flags = CFG_FORCE_REDRAW;
985
xevent->xmotion.x_root = c->x - passdata->ox + passdata->mx;
986
xevent->xmotion.y_root = c->y - passdata->oy + passdata->my;
990
c->x = passdata->ox + (xevent->xmotion.x_root - passdata->mx);
991
c->y = passdata->oy + (xevent->xmotion.y_root - passdata->my);
993
clientSnapPosition (c, prev_x, prev_y);
994
if (screen_info->params->restore_on_move && toggled_maximize)
996
if ((clientConstrainPos (c, FALSE) & CLIENT_CONSTRAINED_TOP) &&
997
clientToggleMaximized (c, CLIENT_FLAG_MAXIMIZED, FALSE))
999
configure_flags = CFG_FORCE_REDRAW;
1000
toggled_maximize = FALSE;
1001
passdata->move_resized = TRUE;
1004
else if (!clientMoveTile (c, (XMotionEvent *) xevent))
1006
clientConstrainPos(c, FALSE);
1009
#ifdef SHOW_POSITION
1010
if (passdata->poswin)
1012
poswinSetPosition (passdata->poswin, c);
1014
#endif /* SHOW_POSITION */
1015
if (screen_info->params->box_move)
1017
clientDrawOutline (c);
1021
int changes = CWX | CWY;
1023
if (passdata->move_resized)
1025
wc.width = c->width;
1026
wc.height = c->height;
1027
changes |= CWWidth | CWHeight;
1028
passdata->move_resized = FALSE;
1033
clientConfigure (c, &wc, changes, configure_flags);
1036
else if ((xevent->type == UnmapNotify) && (xevent->xunmap.window == c->window))
1040
else if (xevent->type == EnterNotify)
1042
/* Ignore enter events */
1046
status = EVENT_FILTER_CONTINUE;
1049
TRACE ("leaving clientMoveEventFilter");
1053
TRACE ("event loop now finished");
1054
toggled_maximize = FALSE;
1055
clientMoveWarp (c, NULL);
1063
clientMove (Client * c, XEvent * ev)
1065
ScreenInfo *screen_info;
1066
DisplayInfo *display_info;
1068
MoveResizeData passdata;
1072
g_return_if_fail (c != NULL);
1073
TRACE ("entering clientDoMove");
1075
if (FLAG_TEST (c->xfwm_flags, XFWM_FLAG_MOVING_RESIZING) ||
1076
!FLAG_TEST (c->xfwm_flags, XFWM_FLAG_HAS_MOVE))
1081
if (FLAG_TEST (c->flags, CLIENT_FLAG_FULLSCREEN))
1086
TRACE ("moving client \"%s\" (0x%lx)", c->name, c->window);
1087
screen_info = c->screen_info;
1088
display_info = screen_info->display_info;
1090
changes = CWX | CWY;
1093
passdata.cancel_x = passdata.ox = c->x;
1094
passdata.cancel_y = passdata.oy = c->y;
1095
passdata.cancel_workspace = c->win_workspace;
1096
passdata.use_keys = FALSE;
1097
passdata.grab = FALSE;
1098
passdata.released = FALSE;
1099
passdata.button = 0;
1100
passdata.is_transient = clientIsValidTransientOrModal (c);
1101
passdata.move_resized = FALSE;
1103
clientSaveSizePos (c);
1105
if (ev && (ev->type == ButtonPress))
1107
passdata.button = ev->xbutton.button;
1108
passdata.mx = ev->xbutton.x_root;
1109
passdata.my = ev->xbutton.y_root;
1110
passdata.px = passdata.mx - frameX (c);
1111
passdata.py = passdata.my - frameY (c);
1115
clientSetHandle(&passdata, NO_HANDLE);
1116
passdata.released = passdata.use_keys = TRUE;
1119
g1 = myScreenGrabKeyboard (screen_info, myDisplayGetCurrentTime (display_info));
1120
g2 = myScreenGrabPointer (screen_info, MOVERESIZE_EVENT_MASK,
1121
myDisplayGetCursorMove (display_info),
1122
myDisplayGetCurrentTime (display_info));
1125
TRACE ("grab failed in clientMove");
1128
myScreenUngrabKeyboard (screen_info, myDisplayGetCurrentTime (display_info));
1129
myScreenUngrabPointer (screen_info, myDisplayGetCurrentTime (display_info));
1134
passdata.poswin = NULL;
1135
#ifdef SHOW_POSITION
1136
passdata.poswin = poswinCreate(screen_info->gscr);
1137
poswinSetPosition (passdata.poswin, c);
1138
poswinShow (passdata.poswin);
1139
#endif /* SHOW_POSITION */
1141
/* Set window translucent while moving */
1142
if ((screen_info->params->move_opacity < 100) &&
1143
!(screen_info->params->box_move) &&
1144
!FLAG_TEST (c->xfwm_flags, XFWM_FLAG_OPACITY_LOCKED))
1146
clientSetOpacity (c, c->opacity, OPACITY_MOVE, OPACITY_MOVE);
1150
* Need to remove the sidewalk windows while moving otherwise
1151
* the motion events aren't reported on screen edges
1153
placeSidewalks(screen_info, FALSE);
1155
/* Clear any previously saved pos flag from screen resize */
1156
FLAG_UNSET (c->xfwm_flags, XFWM_FLAG_SAVED_POS);
1158
FLAG_SET (c->xfwm_flags, XFWM_FLAG_MOVING_RESIZING);
1159
TRACE ("entering move loop");
1160
eventFilterPush (display_info->xfilter, clientMoveEventFilter, &passdata);
1162
eventFilterPop (display_info->xfilter);
1163
TRACE ("leaving move loop");
1164
FLAG_UNSET (c->xfwm_flags, XFWM_FLAG_MOVING_RESIZING);
1166
/* Put back the sidewalks as they ought to be */
1167
placeSidewalks (screen_info, screen_info->params->wrap_workspaces);
1169
#ifdef SHOW_POSITION
1170
if (passdata.poswin)
1172
poswinDestroy (passdata.poswin);
1174
#endif /* SHOW_POSITION */
1175
if (passdata.grab && screen_info->params->box_move)
1177
clientDrawOutline (c);
1179
/* Set window opacity to its original value */
1180
clientSetOpacity (c, c->opacity, OPACITY_MOVE, 0);
1184
if (passdata.move_resized)
1186
wc.width = c->width;
1187
wc.height = c->height;
1188
changes |= CWWidth | CWHeight;
1190
clientConfigure (c, &wc, changes, NO_CFG_FLAG);
1192
if (!passdata.released)
1194
/* If this is a drag-move, wait for the button to be released.
1195
* If we don't, we might get release events in the wrong place.
1197
eventFilterPush (display_info->xfilter, clientButtonReleaseFilter, &passdata);
1199
eventFilterPop (display_info->xfilter);
1202
myScreenUngrabKeyboard (screen_info, myDisplayGetCurrentTime (display_info));
1203
myScreenUngrabPointer (screen_info, myDisplayGetCurrentTime (display_info));
1205
if (passdata.grab && screen_info->params->box_move)
1207
myDisplayUngrabServer (display_info);
1212
clientChangeHandle(MoveResizeData *passdata, int handle)
1214
ScreenInfo *screen_info;
1215
DisplayInfo *display_info;
1221
screen_info = c->screen_info;
1222
display_info = screen_info->display_info;
1224
clientSetHandle(passdata, handle);
1225
if ((handle > NO_HANDLE) && (handle <= HANDLES_COUNT))
1227
cursor = myDisplayGetCursorResize (display_info, handle);
1231
cursor = myDisplayGetCursorMove (display_info);
1233
grab = myScreenChangeGrabPointer (screen_info, MOVERESIZE_EVENT_MASK,
1234
cursor, myDisplayGetCurrentTime (display_info));
1240
clientResizeConfigure (Client *c, int px, int py, int pw, int ph)
1242
ScreenInfo *screen_info;
1243
DisplayInfo *display_info;
1246
screen_info = c->screen_info;
1247
display_info = screen_info->display_info;
1250
if (c->xsync_waiting)
1256
if ((display_info->have_xsync) && (c->xsync_enabled) && (c->xsync_counter))
1258
clientXSyncRequest (c);
1260
#endif /* HAVE_XSYNC */
1263
wc.width = c->width;
1264
wc.height = c->height;
1265
clientConfigure (c, &wc, CWX | CWY | CWWidth | CWHeight, NO_CFG_FLAG);
1268
#endif /* HAVE_XSYNC */
1271
static eventFilterStatus
1272
clientResizeEventFilter (XEvent * xevent, gpointer data)
1274
ScreenInfo *screen_info;
1275
DisplayInfo *display_info;
1278
MoveResizeData *passdata;
1279
eventFilterStatus status;
1280
int prev_x, prev_y, prev_width, prev_height;
1281
int cx, cy, disp_x, disp_y, disp_max_x, disp_max_y;
1282
int frame_x, frame_y, frame_height, frame_width, frame_top;
1283
int move_top, move_bottom, move_left, move_right;
1287
int right_edge; /* -Cliff */
1288
int bottom_edge; /* -Cliff */
1290
TRACE ("entering clientResizeEventFilter");
1292
passdata = (MoveResizeData *) data;
1294
screen_info = c->screen_info;
1295
display_info = screen_info->display_info;
1296
status = EVENT_FILTER_STOP;
1299
frame_x = frameX (c);
1300
frame_y = frameY (c);
1301
frame_height = frameHeight (c);
1302
frame_width = frameWidth (c);
1303
frame_top = frameTop (c);
1304
min_visible = MAX (frame_top, CLIENT_MIN_VISIBLE);
1306
cx = frame_x + (frame_width / 2);
1307
cy = frame_y + (frame_height / 2);
1309
move_top = ((passdata->handle == CORNER_TOP_RIGHT)
1310
|| (passdata->handle == CORNER_TOP_LEFT)
1311
|| (passdata->handle == CORNER_COUNT + SIDE_TOP)) ?
1313
move_bottom = ((passdata->handle == CORNER_BOTTOM_RIGHT)
1314
|| (passdata->handle == CORNER_BOTTOM_LEFT)
1315
|| (passdata->handle == CORNER_COUNT + SIDE_BOTTOM)) ?
1317
move_right = ((passdata->handle == CORNER_TOP_RIGHT)
1318
|| (passdata->handle == CORNER_BOTTOM_RIGHT)
1319
|| (passdata->handle == CORNER_COUNT + SIDE_RIGHT)) ?
1321
move_left = ((passdata->handle == CORNER_TOP_LEFT)
1322
|| (passdata->handle == CORNER_BOTTOM_LEFT)
1323
|| (passdata->handle == CORNER_COUNT + SIDE_LEFT)) ?
1326
myScreenFindMonitorAtPoint (screen_info, cx, cy, &rect);
1330
disp_max_x = rect.x + rect.width;
1331
disp_max_y = rect.y + rect.height;
1333
/* Store previous values in case the resize puts the window title off bounds */
1336
prev_width = c->width;
1337
prev_height = c->height;
1339
/* Update the display time */
1340
myDisplayUpdateCurrentTime (display_info, xevent);
1342
if (xevent->type == KeyPress)
1344
int key_width_inc, key_height_inc;
1346
while (XCheckMaskEvent (display_info->dpy, KeyPressMask, xevent))
1348
/* Update the display time */
1349
myDisplayUpdateCurrentTime (display_info, xevent);
1352
key_width_inc = c->size->width_inc;
1353
key_height_inc = c->size->height_inc;
1355
if (key_width_inc < 10)
1357
key_width_inc = ((int) (10 / key_width_inc)) * key_width_inc;
1359
if (key_height_inc < 10)
1361
key_height_inc = ((int) (10 / key_height_inc)) * key_height_inc;
1364
if (xevent->xkey.keycode == screen_info->params->keys[KEY_UP].keycode)
1366
if ((passdata->handle == CORNER_COUNT + SIDE_BOTTOM) ||
1367
(passdata->handle == CORNER_COUNT + SIDE_TOP))
1369
clientMovePointer (display_info, 0, -1, key_height_inc);
1373
clientChangeHandle (passdata, CORNER_COUNT + SIDE_TOP);
1376
else if (xevent->xkey.keycode == screen_info->params->keys[KEY_DOWN].keycode)
1378
if ((passdata->handle == CORNER_COUNT + SIDE_BOTTOM) ||
1379
(passdata->handle == CORNER_COUNT + SIDE_TOP))
1381
clientMovePointer (display_info, 0, 1, key_height_inc);
1385
clientChangeHandle (passdata, CORNER_COUNT + SIDE_BOTTOM);
1388
else if (xevent->xkey.keycode == screen_info->params->keys[KEY_LEFT].keycode)
1390
if ((passdata->handle == CORNER_COUNT + SIDE_LEFT) ||
1391
(passdata->handle == CORNER_COUNT + SIDE_RIGHT))
1393
clientMovePointer (display_info, -1, 0, key_width_inc);
1397
clientChangeHandle (passdata, CORNER_COUNT + SIDE_LEFT);
1400
else if (xevent->xkey.keycode == screen_info->params->keys[KEY_RIGHT].keycode)
1402
if ((passdata->handle == CORNER_COUNT + SIDE_LEFT) ||
1403
(passdata->handle == CORNER_COUNT + SIDE_RIGHT))
1405
clientMovePointer (display_info, 1, 0, key_width_inc);
1409
clientChangeHandle (passdata, CORNER_COUNT + SIDE_RIGHT);
1412
else if (xevent->xkey.keycode == screen_info->params->keys[KEY_CANCEL].keycode)
1415
passdata->released = passdata->use_keys;
1417
if (screen_info->params->box_resize)
1419
clientDrawOutline (c);
1422
/* restore the pre-resize position & size */
1423
c->x = passdata->cancel_x;
1424
c->y = passdata->cancel_y;
1425
c->width = passdata->cancel_w;
1426
c->height = passdata->cancel_h;
1427
if (screen_info->params->box_resize)
1429
clientDrawOutline (c);
1433
clientResizeConfigure (c, prev_x, prev_y, prev_width, prev_height);
1436
else if (passdata->use_keys)
1438
resizing = clientKeyPressIsModifier(xevent);
1441
else if (xevent->type == MotionNotify)
1443
while (XCheckMaskEvent (display_info->dpy, ButtonMotionMask | PointerMotionMask, xevent))
1445
/* Update the display time */
1446
myDisplayUpdateCurrentTime (display_info, xevent);
1449
if (xevent->type == ButtonRelease)
1453
if (!passdata->grab && screen_info->params->box_resize)
1455
myDisplayGrabServer (display_info);
1456
passdata->grab = TRUE;
1457
clientDrawOutline (c);
1459
if (screen_info->params->box_resize)
1461
clientDrawOutline (c);
1463
passdata->oldw = c->width;
1464
passdata->oldh = c->height;
1468
c->width = passdata->ow - (xevent->xmotion.x_root - passdata->mx);
1470
else if (move_right)
1472
c->width = passdata->ow + (xevent->xmotion.x_root - passdata->mx);
1474
/* Attempt to snap the right edge to something. -Cliff */
1475
c->width = clientFindClosestEdgeX (c, c->x + c->width + frameRight (c)) - c->x - frameRight (c);
1478
if (!FLAG_TEST (c->flags, CLIENT_FLAG_SHADED))
1482
c->height = passdata->oh - (xevent->xmotion.y_root - passdata->my);
1484
else if (move_bottom)
1486
c->height = passdata->oh + (xevent->xmotion.y_root - passdata->my);
1488
/* Attempt to snap the bottom edge to something. -Cliff */
1489
c->height = clientFindClosestEdgeY (c, c->y + c->height + frameBottom (c)) - c->y - frameBottom (c);
1492
clientConstrainRatio (c, passdata->handle);
1494
clientSetWidth (c, c->width, FALSE);
1497
c->x = c->x - (c->width - passdata->oldw);
1499
/* Snap the left edge to something. -Cliff */
1500
right_edge = c->x + c->width;
1501
c->x = clientFindClosestEdgeX (c, c->x - frameLeft (c)) + frameLeft (c);
1502
c->width = right_edge - c->x;
1504
frame_x = frameX (c);
1507
clientSetHeight (c, c->height, FALSE);
1508
if (!FLAG_TEST (c->flags, CLIENT_FLAG_SHADED) && move_top)
1510
c->y = c->y - (c->height - passdata->oldh);
1512
/* Snap the top edge to something. -Cliff */
1513
bottom_edge = c->y + c->height;
1514
c->y = clientFindClosestEdgeY (c, c->y - frameTop (c)) + frameTop (c);
1515
c->height = bottom_edge - c->y;
1517
frame_y = frameY (c);
1522
if ((c->y > MAX (disp_max_y - min_visible, screen_info->height - screen_info->margins [STRUTS_BOTTOM] - min_visible))
1523
|| (!clientCkeckTitle (c) && (frame_y < screen_info->margins [STRUTS_TOP])))
1525
temp = c->y + c->height;
1526
c->y = CLAMP (c->y, screen_info->margins [STRUTS_TOP] + frame_top,
1527
MAX (disp_max_y - min_visible, screen_info->height - screen_info->margins [STRUTS_BOTTOM] - min_visible));
1528
clientSetHeight (c, temp - c->y, FALSE);
1529
c->y = temp - c->height;
1531
else if (frame_y < 0)
1533
temp = c->y + c->height;
1535
clientSetHeight (c, temp - c->y, FALSE);
1536
c->y = temp - c->height;
1539
else if (move_bottom)
1541
if (c->y + c->height < MAX (disp_y + min_visible, screen_info->margins [STRUTS_TOP] + min_visible))
1543
temp = MAX (disp_y + min_visible, screen_info->margins [STRUTS_TOP] + min_visible);
1544
clientSetHeight (c, temp - c->y, FALSE);
1549
if (c->x > MIN (disp_max_x - min_visible, screen_info->width - screen_info->margins [STRUTS_RIGHT] - min_visible))
1551
temp = c->x + c->width;
1552
c->x = MIN (disp_max_x - min_visible, screen_info->width - screen_info->margins [STRUTS_RIGHT] - min_visible);
1553
clientSetWidth (c, temp - c->x, FALSE);
1554
c->x = temp - c->width;
1557
else if (move_right)
1559
if (c->x + c->width < MAX (disp_x + min_visible, screen_info->margins [STRUTS_LEFT] + min_visible))
1561
temp = MAX (disp_x + min_visible, screen_info->margins [STRUTS_LEFT] + min_visible);
1562
clientSetWidth (c, temp - c->x, FALSE);
1566
if (passdata->poswin)
1568
poswinSetPosition (passdata->poswin, c);
1570
if (screen_info->params->box_resize)
1572
clientDrawOutline (c);
1576
clientResizeConfigure (c, prev_x, prev_y, prev_width, prev_height);
1579
else if (xevent->type == ButtonRelease)
1582
passdata->released = (passdata->use_keys || (xevent->xbutton.button == passdata->button));
1584
else if ((xevent->type == UnmapNotify) && (xevent->xunmap.window == c->window))
1588
else if (xevent->type == EnterNotify)
1590
/* Ignore enter events */
1594
status = EVENT_FILTER_CONTINUE;
1597
TRACE ("leaving clientResizeEventFilter");
1601
TRACE ("event loop now finished");
1609
clientResize (Client * c, int handle, XEvent * ev)
1611
ScreenInfo *screen_info;
1612
DisplayInfo *display_info;
1614
MoveResizeData passdata;
1619
g_return_if_fail (c != NULL);
1620
TRACE ("entering clientResize");
1622
if (FLAG_TEST (c->xfwm_flags, XFWM_FLAG_MOVING_RESIZING))
1627
if (!FLAG_TEST_ALL (c->xfwm_flags, XFWM_FLAG_HAS_RESIZE | XFWM_FLAG_IS_RESIZABLE))
1629
if (FLAG_TEST (c->xfwm_flags, XFWM_FLAG_HAS_MOVE))
1636
if (FLAG_TEST (c->flags, CLIENT_FLAG_FULLSCREEN))
1641
screen_info = c->screen_info;
1642
display_info = screen_info->display_info;
1644
if (FLAG_TEST_ALL (c->flags, CLIENT_FLAG_MAXIMIZED)
1645
&& (screen_info->params->borderless_maximize))
1650
TRACE ("resizing client \"%s\" (0x%lx)", c->name, c->window);
1653
passdata.cancel_x = passdata.ox = c->x;
1654
passdata.cancel_y = passdata.oy = c->y;
1655
passdata.cancel_w = passdata.ow = c->width;
1656
passdata.cancel_h = passdata.oh = c->height;
1657
passdata.use_keys = FALSE;
1658
passdata.grab = FALSE;
1659
passdata.released = FALSE;
1660
passdata.button = 0;
1661
passdata.handle = handle;
1665
if (ev && (ev->type == ButtonPress))
1667
passdata.button = ev->xbutton.button;
1668
passdata.mx = ev->xbutton.x_root;
1669
passdata.my = ev->xbutton.y_root;
1673
clientSetHandle (&passdata, handle);
1674
passdata.released = passdata.use_keys = TRUE;
1676
if ((handle > NO_HANDLE) && (handle <= HANDLES_COUNT))
1678
cursor = myDisplayGetCursorResize (display_info, passdata.handle);
1682
cursor = myDisplayGetCursorMove (display_info);
1685
g1 = myScreenGrabKeyboard (screen_info, myDisplayGetCurrentTime (display_info));
1686
g2 = myScreenGrabPointer (screen_info, MOVERESIZE_EVENT_MASK,
1687
cursor, myDisplayGetCurrentTime (display_info));
1691
TRACE ("grab failed in clientResize");
1694
myScreenUngrabKeyboard (screen_info, myDisplayGetCurrentTime (display_info));
1695
myScreenUngrabPointer (screen_info, myDisplayGetCurrentTime (display_info));
1700
passdata.poswin = NULL;
1701
#ifndef SHOW_POSITION
1702
if ((c->size->width_inc > 1) || (c->size->height_inc > 1))
1703
#endif /* SHOW_POSITION */
1705
passdata.poswin = poswinCreate(screen_info->gscr);
1706
poswinSetPosition (passdata.poswin, c);
1707
poswinShow (passdata.poswin);
1711
clientXSyncEnable (c);
1712
#endif /* HAVE_XSYNC */
1714
/* Set window translucent while resizing */
1715
if ((screen_info->params->resize_opacity < 100) &&
1716
!(screen_info->params->box_resize) &&
1717
!FLAG_TEST (c->xfwm_flags, XFWM_FLAG_OPACITY_LOCKED))
1719
clientSetOpacity (c, c->opacity, OPACITY_RESIZE, OPACITY_RESIZE);
1722
/* Clear any previously saved pos flag from screen resize */
1723
FLAG_UNSET (c->xfwm_flags, XFWM_FLAG_SAVED_POS);
1725
FLAG_SET (c->xfwm_flags, XFWM_FLAG_MOVING_RESIZING);
1726
TRACE ("entering resize loop");
1727
eventFilterPush (display_info->xfilter, clientResizeEventFilter, &passdata);
1729
eventFilterPop (display_info->xfilter);
1730
TRACE ("leaving resize loop");
1731
FLAG_UNSET (c->xfwm_flags, XFWM_FLAG_MOVING_RESIZING);
1733
if (passdata.poswin)
1735
poswinDestroy (passdata.poswin);
1737
if (passdata.grab && screen_info->params->box_resize)
1739
clientDrawOutline (c);
1741
/* Set window opacity to its original value */
1742
clientSetOpacity (c, c->opacity, OPACITY_RESIZE, 0);
1744
if (FLAG_TEST (c->flags, CLIENT_FLAG_MAXIMIZED) &&
1745
((w_orig != c->width) || (h_orig != c->height)))
1747
clientRemoveMaximizeFlag (c);
1752
wc.width = c->width;
1753
wc.height = c->height;
1754
clientConfigure (c, &wc, CWX | CWY | CWHeight | CWWidth, NO_CFG_FLAG);
1756
clientXSyncClearTimeout (c);
1757
c->xsync_waiting = FALSE;
1758
#endif /* HAVE_XSYNC */
1760
if (!passdata.released)
1762
/* If this is a drag-resize, wait for the button to be released.
1763
* If we don't, we might get release events in the wrong place.
1765
eventFilterPush (display_info->xfilter, clientButtonReleaseFilter, &passdata);
1767
eventFilterPop (display_info->xfilter);
1770
myScreenUngrabKeyboard (screen_info, myDisplayGetCurrentTime (display_info));
1771
myScreenUngrabPointer (screen_info, myDisplayGetCurrentTime (display_info));
1773
if (passdata.grab && screen_info->params->box_resize)
1775
myDisplayUngrabServer (display_info);