diff -u xfwm4-4.6.2/src/client.c xfwm4-4.6.2/src/client.c --- xfwm4-4.6.2/src/client.c 2010-05-21 20:02:40.000000000 +0300 +++ xfwm4-4.6.2/src/client.c 2010-08-21 21:19:03.087370603 +0300 @@ -2136,6 +2136,14 @@ if ((attr.map_state == IsViewable) && (attr.root == screen_info->xroot)) { Client *c = clientFrame (display_info, wins[i], TRUE); + + // initial values for existing windows + if (c) + { + c->pretiling_height = -1; + c->pretiling_width = -1; + } + if ((c) && ((screen_info->params->raise_on_click) || (screen_info->params->click_to_focus))) { clientGrabMouseButton (c); @@ -3180,7 +3188,7 @@ wc->height = c->old_height; } -static void +void clientNewMaxSize (Client * c, XWindowChanges *wc) { ScreenInfo *screen_info; @@ -3207,7 +3215,7 @@ full_h = MIN (screen_info->height - screen_info->params->xfwm_margins[STRUTS_BOTTOM], rect.y + rect.height) - full_y; - if (FLAG_TEST_ALL (c->flags, CLIENT_FLAG_MAXIMIZED)) + if (FLAG_TEST_ALL (c->flags, CLIENT_FLAG_MAXIMIZED) || FLAG_TEST (c->flags, CLIENT_FLAG_TILED)) { /* Adjust size to the largest size available, not covering struts */ clientMaxSpace (screen_info, &full_x, &full_y, &full_w, &full_h); diff -u xfwm4-4.6.2/src/client.h xfwm4-4.6.2/src/client.h --- xfwm4-4.6.2/src/client.h 2010-05-21 20:02:40.000000000 +0300 +++ xfwm4-4.6.2/src/client.h 2010-08-21 18:55:30.993649383 +0300 @@ -160,6 +160,8 @@ #define CLIENT_FLAG_HAS_SHAPE (1L<<18) #define CLIENT_FLAG_FULLSCREN_MONITORS (1L<<19) +#define CLIENT_FLAG_TILED (1L<<20) + #define WM_FLAG_DELETE (1L<<0) #define WM_FLAG_INPUT (1L<<1) #define WM_FLAG_TAKEFOCUS (1L<<2) @@ -280,6 +282,8 @@ int old_y; int old_width; int old_height; + int pretiling_width; + int pretiling_height; int fullscreen_old_x; int fullscreen_old_y; int fullscreen_old_width; @@ -336,6 +340,9 @@ extern Client *clients; extern unsigned int client_count; +void clientNewMaxSize (Client * c, + XWindowChanges *wc); + Display *clientGetXDisplay (Client *); void clientClearLastOpTime (Client *); void clientUpdateWinState (Client *, diff -u xfwm4-4.6.2/src/moveresize.c xfwm4-4.6.2/src/moveresize.c --- xfwm4-4.6.2/src/moveresize.c 2010-05-21 20:02:40.000000000 +0300 +++ xfwm4-4.6.2/src/moveresize.c 2010-08-21 20:33:25.509632145 +0300 @@ -35,7 +35,8 @@ #include #include #include -# + +#include "moveresize.h" #include "client.h" #include "focus.h" #include "frame.h" @@ -809,6 +810,117 @@ c->x = passdata->ox + (xevent->xmotion.x_root - passdata->mx); c->y = passdata->oy + (xevent->xmotion.y_root - passdata->my); + // if window is not maximized + if (!FLAG_TEST_ALL(c->flags, CLIENT_FLAG_MAXIMIZED)) + { + // if user moved cursor to the edge of the screen + if (xevent->xmotion.x_root < TILING_EDGE + || xevent->xmotion.x_root > screen_info->width - TILING_EDGE + || xevent->xmotion.y_root < TILING_EDGE + || xevent->xmotion.y_root > screen_info->height - TILING_EDGE) + { + // save pretiling sizes for future restore + + // initial values for pretiling_width and pretiling_height + // are set in functions: + // placement.c => clientInitPosition - for new windows + // client.c => clientFrameAll - for existing windows + // P.S. maybe it's a dirty hack :-) + + if (c->pretiling_width == -1) + c->pretiling_width = c->width; + if (c->pretiling_height == -1) + c->pretiling_height = c->height; + + // get information about maximum available space + FLAG_SET (c->flags, CLIENT_FLAG_TILED); + XWindowChanges wc; + clientNewMaxSize(c, &wc); + + if (xevent->xmotion.x_root < TILING_EDGE) + { + // wc.x = avialable screen x + 1 x left frame's width + // wc.width = available screen width - 1 x left frame's width - 1 x right frame's width + + c->x = wc.x; + c->y = wc.y; + + // we need to substract another two (left, right) frames' width + // because of two windows we have + + c->width = (wc.width - frameRight(c) - frameLeft(c))/2; + c->height = wc.height; + } + else if (xevent->xmotion.x_root > screen_info->width - TILING_EDGE) + { + // see upper + c->width = (wc.width - frameRight(c) - frameLeft(c))/2; + c->height = wc.height; + + // c->width has to be first (left) window's width + // but two windows we have are equal, + // consequently we can use second windows's width + + // frameRight(c) + frameLeft(c) = width of frames between windows + + c->x = wc.x + c->width + frameRight(c) + frameLeft(c); + c->y = wc.y; + } + else if (xevent->xmotion.y_root < TILING_EDGE) + { + // see previous tilings' comments + c->x = wc.x; + c->y = wc.y; + c->width = wc.width; + c->height = (wc.height - frameBottom(c) - frameTop(c))/2; + } + else + { + // see previous tilings' comments + c->width = wc.width; + c->height = (wc.height - frameBottom(c) - frameTop(c))/2; + c->x = wc.x; + c->y = wc.y + c->height + frameBottom(c) + frameTop(c); + } + } + else + { + if (c->pretiling_width != -1) + { + // calculate x-resize ratio + double ratio_x = ((double) c->pretiling_width) / ((double) c->width); + + // restore pretiling size (by x) + c->width = c->pretiling_width; + c->pretiling_width = -1; + + // fix cursor position (by x) + passdata->mx *= ratio_x; + passdata->ox *= ratio_x; + } + + if (c->pretiling_height != -1) + { + // calculate y-resize ratio + double ratio_y = ((double) c->pretiling_height) / ((double) c->height); + + // restore pretiling size (by y) + c->height = c->pretiling_height; + c->pretiling_height = -1; + + // fix cursor position (by y) + passdata->my *= ratio_y; + passdata->oy *= ratio_y; + } + + FLAG_UNSET (c->flags, CLIENT_FLAG_TILED); + + } + + // we need it for our window to be not only moved, but resized too + passdata->move_resized = 1; + } + clientSnapPosition (c, prev_x, prev_y); if (screen_info->params->restore_on_move) { @@ -1123,6 +1235,13 @@ status = EVENT_FILTER_STOP; resizing = TRUE; + /* + if (xevent->xmotion.x_root > TILING_EDGE || xevent->xmotion.x_root < screen_info->width - TILING_EDGE) + { + c->pretiling_width = c->pretiling_height = -1; + } + */ + frame_x = frameX (c); frame_y = frameY (c); frame_height = frameHeight (c); diff -u xfwm4-4.6.2/src/moveresize.h xfwm4-4.6.2/src/moveresize.h --- xfwm4-4.6.2/src/moveresize.h 2010-05-21 20:02:40.000000000 +0300 +++ xfwm4-4.6.2/src/moveresize.h 2010-08-19 19:40:18.398519704 +0300 @@ -31,8 +31,11 @@ #include "screen.h" #include "client.h" +#define TILING_EDGE 10 + #ifndef INC_MOVERESIZE_H #define INC_MOVERESIZE_H + void clientSetWidth (Client *, int); void clientSetHeight (Client *, diff -u xfwm4-4.6.2/src/placement.c xfwm4-4.6.2/src/placement.c --- xfwm4-4.6.2/src/placement.c 2010-05-21 20:02:40.000000000 +0300 +++ xfwm4-4.6.2/src/placement.c 2010-08-21 20:32:41.004315310 +0300 @@ -740,6 +740,10 @@ { clientAutoMaximize (c, full_w, full_h); } + + // initial values for new windows + c->pretiling_width = -1; + c->pretiling_height = -1; }