- a = screen_area_monitor(self->desktop, client_monitor(self));
- if (RECT_CONTAINS_RECT(*a, self->area))
- rude = TRUE;
- }
-
- /* This here doesn't let windows even a pixel outside the screen,
- * when called from client_manage, programs placing themselves are
- * forced completely onscreen, while things like
- * xterm -geometry resolution-width/2 will work fine. Trying to
- * place it completely offscreen will be handled in the above code.
- * Sorry for this confused comment, i am tired. */
- if (rude) {
- /* avoid the xinerama monitor divide while we're at it,
- * remember to fix the placement stuff to avoid it also and
- * then remove this XXX */
- a = screen_area_monitor(self->desktop, client_monitor(self));
- /* dont let windows map into the strut unless they
- are bigger than the available area */
- if (w <= a->width) {
- if (!self->strut.left && *x < a->x) *x = a->x;
- if (!self->strut.right && *x + w > a->x + a->width)
- *x = a->x + a->width - w;
- }
- if (h <= a->height) {
- if (!self->strut.top && *y < a->y) *y = a->y;
- if (!self->strut.bottom && *y + h > a->y + a->height)
- *y = a->y + a->height - h;
+ Point oldtl, oldtr, oldbl, oldbr;
+ Point newtl, newtr, newbl, newbr;
+ gboolean stationary_l, stationary_r, stationary_t, stationary_b;
+
+ POINT_SET(oldtl, self->frame->area.x, self->frame->area.y);
+ POINT_SET(oldbr, self->frame->area.x + self->frame->area.width - 1,
+ self->frame->area.y + self->frame->area.height - 1);
+ POINT_SET(oldtr, oldbr.x, oldtl.y);
+ POINT_SET(oldbl, oldtl.x, oldbr.y);
+
+ POINT_SET(newtl, *x, *y);
+ POINT_SET(newbr, *x + fw - 1, *y + fh - 1);
+ POINT_SET(newtr, newbr.x, newtl.y);
+ POINT_SET(newbl, newtl.x, newbr.y);
+
+ /* is it moving or just resizing from some corner? */
+ stationary_l = oldtl.x == newtl.x;
+ stationary_r = oldtr.x == newtr.x;
+ stationary_t = oldtl.y == newtl.y;
+ stationary_b = oldbl.y == newbl.y;
+
+ /* if left edge is growing and didnt move right edge */
+ if (stationary_r && newtl.x < oldtl.x)
+ rudel = TRUE;
+ /* if right edge is growing and didnt move left edge */
+ if (stationary_l && newtr.x > oldtr.x)
+ ruder = TRUE;
+ /* if top edge is growing and didnt move bottom edge */
+ if (stationary_b && newtl.y < oldtl.y)
+ rudet = TRUE;
+ /* if bottom edge is growing and didnt move top edge */
+ if (stationary_t && newbl.y > oldbl.y)
+ rudeb = TRUE;
+ }
+
+ for (i = 0; i < screen_num_monitors; ++i) {
+ Rect *a;
+
+ if (!screen_physical_area_monitor_contains(i, &desired)) {
+ if (i < screen_num_monitors - 1)
+ continue;
+
+ /* the window is not inside any monitor! so just use the first
+ one */
+ a = screen_area(self->desktop, 0, NULL);
+ } else
+ a = screen_area(self->desktop, SCREEN_AREA_ONE_MONITOR, &desired);
+
+ /* This makes sure windows aren't entirely outside of the screen so you
+ can't see them at all.
+ It makes sure 10% of the window is on the screen at least. At don't
+ let it move itself off the top of the screen, which would hide the
+ titlebar on you. (The user can still do this if they want too, it's
+ only limiting the application.
+ */
+ if (client_normal(self)) {
+ if (!self->strut.right && *x + fw/10 >= a->x + a->width - 1)
+ *x = a->x + a->width - fw/10;
+ if (!self->strut.bottom && *y + fh/10 >= a->y + a->height - 1)
+ *y = a->y + a->height - fh/10;
+ if (!self->strut.left && *x + fw*9/10 - 1 < a->x)
+ *x = a->x - fw*9/10;
+ if (!self->strut.top && *y + fh*9/10 - 1 < a->y)
+ *y = a->y - fh*9/10;