diff --git a/src/display.c b/src/display.c index a1cfb02..6f4c77a 100644 --- a/src/display.c +++ b/src/display.c @@ -406,6 +406,8 @@ myDisplayCreateCursor (DisplayInfo *display) XCreateFontCursor (display->dpy, XC_top_side); display->resize_cursor[CORNER_COUNT + SIDE_BOTTOM] = XCreateFontCursor (display->dpy, XC_bottom_side); + display->resize_cursor[CORNER_COUNT + TWM_GESTURE] = + XCreateFontCursor (display->dpy, XC_crosshair); } void @@ -455,7 +457,7 @@ Cursor myDisplayGetCursorResize (DisplayInfo *display, guint list) { g_return_val_if_fail (display, None); - g_return_val_if_fail (list < 8, None); + g_return_val_if_fail (list <= HANDLES_COUNT, None); return display->resize_cursor [list]; } diff --git a/src/display.h b/src/display.h index a2f8a9a..a5e7213 100644 --- a/src/display.h +++ b/src/display.h @@ -111,6 +111,7 @@ enum SIDE_RIGHT, SIDE_TOP, SIDE_BOTTOM, + TWM_GESTURE, SIDE_COUNT }; #define NO_HANDLE -1 diff --git a/src/events.c b/src/events.c index 50303b0..2439f72 100644 --- a/src/events.c +++ b/src/events.c @@ -791,10 +791,16 @@ titleButton (Client * c, guint state, XButtonEvent * ev) { XfwmButtonClickType tclick; + if (!(c->type & WINDOW_TYPE_DONT_FOCUS)) + { + clientSetFocus (screen_info, c, ev->time, NO_FOCUS_FLAG); + } + clientRaise (c, None); + tclick = typeOfClick (screen_info, c->window, (XEvent *) ev, FALSE); if (tclick == XFWM_BUTTON_DRAG) { - clientMove (c, (XEvent *) ev); + clientResize (c, CORNER_COUNT + TWM_GESTURE, (XEvent *) ev); } else if (tclick != XFWM_BUTTON_UNDEFINED) { diff --git a/src/moveresize.c b/src/moveresize.c index 411520d..c10562a 100644 --- a/src/moveresize.c +++ b/src/moveresize.c @@ -73,6 +73,7 @@ struct _MoveResizeData gboolean is_transient; gboolean move_resized; gboolean released; + gboolean twm_gesture; guint button; gint cancel_x, cancel_y; gint cancel_w, cancel_h; @@ -1380,6 +1381,7 @@ clientResizeEventFilter (XEvent * xevent, gpointer data) ScreenInfo *screen_info; DisplayInfo *display_info; Client *c; + Cursor cursor; GdkRectangle rect; MoveResizeData *passdata; eventFilterStatus status; @@ -1387,6 +1389,7 @@ clientResizeEventFilter (XEvent * xevent, gpointer data) int cx, cy; int move_top, move_bottom, move_left, move_right; gboolean resizing; + gboolean newcursor; int right_edge; /* -Cliff */ int bottom_edge; /* -Cliff */ @@ -1403,6 +1406,7 @@ clientResizeEventFilter (XEvent * xevent, gpointer data) * we use XFWM_FLAG_MOVING_RESIZING for that. */ resizing = FLAG_TEST (c->xfwm_flags, XFWM_FLAG_MOVING_RESIZING); + newcursor = FALSE; cx = frameExtentX (c) + (frameExtentWidth (c) / 2); cy = frameExtentY (c) + (frameExtentHeight (c) / 2); @@ -1566,6 +1570,34 @@ clientResizeEventFilter (XEvent * xevent, gpointer data) right_edge = c->x + c->width; bottom_edge = c->y + c->height; + if (!move_left && !move_right && passdata->twm_gesture) + { + if (xevent->xmotion.x_root >= c->x + c->width + frameExtentRight (c) - 1) + { + move_right = 1; + switch (passdata->handle) + { + case CORNER_COUNT + SIDE_TOP: passdata->handle = CORNER_TOP_RIGHT; break; + case CORNER_COUNT + SIDE_BOTTOM: passdata->handle = CORNER_BOTTOM_RIGHT; break; + case CORNER_COUNT + TWM_GESTURE: passdata->handle = CORNER_COUNT + SIDE_RIGHT; break; + } + newcursor = TRUE; + passdata->mx = c->x + c->width + frameExtentRight (c) - 1; + } + else if (xevent->xmotion.x_root <= c->x - frameExtentLeft(c)) + { + move_left = 1; + switch (passdata->handle) + { + case CORNER_COUNT + SIDE_TOP: passdata->handle = CORNER_TOP_LEFT; break; + case CORNER_COUNT + SIDE_BOTTOM: passdata->handle = CORNER_BOTTOM_LEFT; break; + case CORNER_COUNT + TWM_GESTURE: passdata->handle = CORNER_COUNT + SIDE_LEFT; break; + } + newcursor = TRUE; + passdata->mx = passdata->ox - frameExtentLeft(c); + } + } + if (move_left) { c->width = passdata->ow - (xevent->xmotion.x_root - passdata->mx); @@ -1585,6 +1617,34 @@ clientResizeEventFilter (XEvent * xevent, gpointer data) } if (!FLAG_TEST (c->flags, CLIENT_FLAG_SHADED)) { + if (!move_top && !move_bottom && passdata->twm_gesture) + { + if (xevent->xmotion.y_root <= c->y - frameExtentTop(c)) + { + move_top = 1; + switch (passdata->handle) + { + case CORNER_COUNT + SIDE_LEFT: passdata->handle = CORNER_TOP_LEFT; break; + case CORNER_COUNT + SIDE_RIGHT: passdata->handle = CORNER_TOP_RIGHT; break; + case CORNER_COUNT + TWM_GESTURE: passdata->handle = CORNER_COUNT + SIDE_TOP; break; + } + newcursor = TRUE; + passdata->my = passdata->oy - frameExtentTop(c); + } + else if (xevent->xmotion.y_root >= c->y + c->height + frameExtentBottom (c) - 1) + { + move_bottom = 1; + switch (passdata->handle) + { + case CORNER_COUNT + SIDE_LEFT: passdata->handle = CORNER_BOTTOM_LEFT; break; + case CORNER_COUNT + SIDE_RIGHT: passdata->handle = CORNER_BOTTOM_RIGHT; break; + case CORNER_COUNT + TWM_GESTURE: passdata->handle = CORNER_COUNT + SIDE_BOTTOM; break; + } + newcursor = TRUE; + passdata->my = c->y + c->height + frameExtentBottom (c) - 1; + } + } + if (move_top) { c->height = passdata->oh - (xevent->xmotion.y_root - passdata->my); @@ -1625,6 +1685,11 @@ clientResizeEventFilter (XEvent * xevent, gpointer data) c->y = bottom_edge - c->height; } + if (newcursor) + { + cursor = myDisplayGetCursorResize (display_info, passdata->handle); + myScreenChangeGrabPointer (screen_info, MOVERESIZE_EVENT_MASK, cursor, myDisplayGetCurrentTime (display_info)); + } if (passdata->poswin) { poswinSetPosition (passdata->poswin, c); @@ -1727,6 +1792,7 @@ clientResize (Client * c, int handle, XEvent * ev) passdata.use_keys = FALSE; passdata.grab = FALSE; passdata.released = FALSE; + passdata.twm_gesture = (handle == CORNER_COUNT + TWM_GESTURE); passdata.button = AnyButton; passdata.handle = handle; passdata.wireframe = NULL;