+ gint dx = 0, dy = 0, ox = cur_x, oy = cur_y;
+ gint opx, px, opy, py;
+ gint dist = 0;
+
+ /* shift means jump to edge */
+ if (state & modkeys_key_to_mask(OB_MODKEY_KEY_SHIFT)) {
+ gint x, y;
+ ObDirection dir;
+
+ if (ob_keycode_match(keycode, OB_KEY_RIGHT))
+ dir = OB_DIRECTION_EAST;
+ else if (ob_keycode_match(keycode, OB_KEY_LEFT))
+ dir = OB_DIRECTION_WEST;
+ else if (ob_keycode_match(keycode, OB_KEY_DOWN))
+ dir = OB_DIRECTION_SOUTH;
+ else /* if (ob_keycode_match(keycode, OB_KEY_UP)) */
+ dir = OB_DIRECTION_NORTH;
+
+ client_find_move_directional(moveresize_client, dir, &x, &y);
+ dx = x - moveresize_client->area.x;
+ dy = y - moveresize_client->area.y;
+ } else {
+ /* control means fine grained */
+ if (state & modkeys_key_to_mask(OB_MODKEY_KEY_CONTROL))
+ dist = 1;
+ else
+ dist = KEY_DIST;
+
+ if (ob_keycode_match(keycode, OB_KEY_RIGHT))
+ dx = dist;
+ else if (ob_keycode_match(keycode, OB_KEY_LEFT))
+ dx = -dist;
+ else if (ob_keycode_match(keycode, OB_KEY_DOWN))
+ dy = dist;
+ else /* if (ob_keycode_match(keycode, OB_KEY_UP)) */
+ dy = -dist;
+ }
+
+ screen_pointer_pos(&opx, &opy);
+ XWarpPointer(ob_display, None, None, 0, 0, 0, 0, dx, dy);
+ /* steal the motion events this causes */
+ XSync(ob_display, FALSE);
+ {
+ XEvent ce;
+ while (XCheckTypedEvent(ob_display, MotionNotify, &ce));
+ }
+ screen_pointer_pos(&px, &py);
+
+ cur_x += dx;
+ cur_y += dy;
+ do_move(TRUE, dist);
+
+ /* because the cursor moves even though the window does
+ not nessesarily (resistance), this adjusts where the curor
+ thinks it started so that it keeps up with where the window
+ actually is */
+ start_x += (px - opx) - (cur_x - ox);
+ start_y += (py - opy) - (cur_y - oy);
+}
+
+static void resize_with_keys(gint keycode, gint state)
+{
+ gint dw = 0, dh = 0, pdx = 0, pdy = 0, opx, opy, px, py;
+ gint dist = 0, resist = 0;
+ ObDirection dir;
+
+ /* pick the edge if it needs to move */
+ if (ob_keycode_match(keycode, OB_KEY_RIGHT)) {
+ dir = OB_DIRECTION_EAST;
+ if (key_resize_edge != OB_DIRECTION_WEST &&
+ key_resize_edge != OB_DIRECTION_EAST)
+ {
+ key_resize_edge = OB_DIRECTION_EAST;
+ return;
+ }
+ }
+ if (ob_keycode_match(keycode, OB_KEY_LEFT)) {
+ dir = OB_DIRECTION_WEST;
+ if (key_resize_edge != OB_DIRECTION_WEST &&
+ key_resize_edge != OB_DIRECTION_EAST)
+ {
+ key_resize_edge = OB_DIRECTION_WEST;
+ return;
+ }
+ }
+ if (ob_keycode_match(keycode, OB_KEY_UP)) {
+ dir = OB_DIRECTION_NORTH;
+ if (key_resize_edge != OB_DIRECTION_NORTH &&
+ key_resize_edge != OB_DIRECTION_SOUTH)
+ {
+ key_resize_edge = OB_DIRECTION_NORTH;
+ return;
+ }
+ }
+ if (ob_keycode_match(keycode, OB_KEY_DOWN)) {
+ dir = OB_DIRECTION_SOUTH;
+ if (key_resize_edge != OB_DIRECTION_NORTH &&
+ key_resize_edge != OB_DIRECTION_SOUTH)
+ {
+ key_resize_edge = OB_DIRECTION_SOUTH;
+ return;
+ }
+ }
+
+ /* shift means jump to edge */
+ if (state & modkeys_key_to_mask(OB_MODKEY_KEY_SHIFT)) {
+ gint x, y, w, h;
+
+ if (ob_keycode_match(keycode, OB_KEY_RIGHT))
+ dir = OB_DIRECTION_EAST;
+ else if (ob_keycode_match(keycode, OB_KEY_LEFT))
+ dir = OB_DIRECTION_WEST;
+ else if (ob_keycode_match(keycode, OB_KEY_DOWN))
+ dir = OB_DIRECTION_SOUTH;
+ else /* if (ob_keycode_match(keycode, OB_KEY_UP)) */
+ dir = OB_DIRECTION_NORTH;
+
+ client_find_resize_directional(moveresize_client, key_resize_edge,
+ key_resize_edge == dir,
+ &x, &y, &w, &h);
+ dw = w - moveresize_client->area.width;
+ dh = h - moveresize_client->area.height;
+ } else {
+ gint distw, disth;
+
+ /* control means fine grained */
+ if (moveresize_client->size_inc.width > 1) {
+ distw = moveresize_client->size_inc.width;
+ resist = 1;
+ }
+ else if (state & modkeys_key_to_mask(OB_MODKEY_KEY_CONTROL)) {
+ distw = 1;
+ resist = 1;
+ }
+ else {
+ distw = KEY_DIST;
+ resist = KEY_DIST;
+ }
+ if (moveresize_client->size_inc.height > 1) {
+ disth = moveresize_client->size_inc.height;
+ resist = 1;
+ }
+ else if (state & modkeys_key_to_mask(OB_MODKEY_KEY_CONTROL)) {
+ disth = 1;
+ resist = 1;
+ }
+ else {
+ disth = KEY_DIST;
+ resist = KEY_DIST;
+ }
+
+ if (key_resize_edge == OB_DIRECTION_WEST) {
+ if (dir == OB_DIRECTION_WEST)
+ dw = (dist = distw);
+ else
+ dw = -(dist = distw);
+ }
+ else if (key_resize_edge == OB_DIRECTION_EAST) {
+ if (dir == OB_DIRECTION_EAST)
+ dw = (dist = distw);
+ else
+ dw = -(dist = distw);
+ }
+ else if (key_resize_edge == OB_DIRECTION_NORTH) {
+ if (dir == OB_DIRECTION_NORTH)
+ dh = (dist = disth);
+ else
+ dh = -(dist = disth);
+ }
+ else /*if (key_resize_edge == OB_DIRECTION_SOUTH)*/ {
+ if (dir == OB_DIRECTION_SOUTH)
+ dh = (dist = disth);
+ else
+ dh = -(dist = disth);
+ }
+ }
+
+ calc_resize(TRUE, resist, &dw, &dh, dir);
+ if (key_resize_edge == OB_DIRECTION_WEST)
+ cur_x -= dw;
+ else if (key_resize_edge == OB_DIRECTION_NORTH)
+ cur_y -= dh;
+ cur_w += dw;
+ cur_h += dh;
+
+ /* how to move the pointer to keep up with the change */
+ if (key_resize_edge == OB_DIRECTION_WEST)
+ pdx = -dw;
+ else if (key_resize_edge == OB_DIRECTION_EAST)
+ pdx = dw;
+ else if (key_resize_edge == OB_DIRECTION_NORTH)
+ pdy = -dh;
+ else if (key_resize_edge == OB_DIRECTION_SOUTH)
+ pdy = dh;
+
+ screen_pointer_pos(&opx, &opy);
+ XWarpPointer(ob_display, None, None, 0, 0, 0, 0, pdx, pdy);
+ /* steal the motion events this causes */
+ XSync(ob_display, FALSE);
+ {
+ XEvent ce;
+ while (XCheckTypedEvent(ob_display, MotionNotify, &ce));
+ }
+ screen_pointer_pos(&px, &py);
+
+ do_resize();
+
+ /* because the cursor moves even though the window does
+ not nessesarily (resistance), this adjusts where the cursor
+ thinks it started so that it keeps up with where the window
+ actually is */
+ start_x += (px - opx) - dw;
+ start_y += (py - opy) - dh;
+
+}
+
+gboolean moveresize_event(XEvent *e)
+{
+ gboolean used = FALSE;
+
+ if (!moveresize_in_progress) return FALSE;