X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=openbox%2Fmoveresize.c;h=9374f8b5f77930e96eb37828540a2d9daf2181ee;hb=74a746e55f8c7faea0d71e9744532bda462b23bd;hp=9ccfbd6a1620be389ffb220268b6ce818c79f85c;hpb=d755060a098513247e8132f2b9f69cc087be7174;p=chaz%2Fopenbox diff --git a/openbox/moveresize.c b/openbox/moveresize.c index 9ccfbd6a..9374f8b5 100644 --- a/openbox/moveresize.c +++ b/openbox/moveresize.c @@ -54,8 +54,8 @@ static gint start_x, start_y, start_cx, start_cy, start_cw, start_ch; static gint cur_x, cur_y, cur_w, cur_h; static guint button; static guint32 corner; -static ObCorner lockcorner; static ObDirection edge_warp_dir = -1; +static gboolean edge_warp_odd = FALSE; static ObDirection key_resize_edge = -1; #ifdef SYNC static gboolean waiting_for_sync; @@ -72,12 +72,12 @@ static gboolean sync_timeout_func(gpointer data); static void client_dest(ObClient *client, gpointer data) { if (moveresize_client == client) - moveresize_end(TRUE); + moveresize_end(TRUE); } void moveresize_startup(gboolean reconfig) { - popup = popup_new(FALSE); + popup = popup_new(); popup_set_text_align(popup, RR_JUSTIFY_CENTER); if (!reconfig) @@ -101,17 +101,66 @@ static void popup_coords(ObClient *c, const gchar *format, gint a, gint b) gchar *text; text = g_strdup_printf(format, a, b); - if (config_resize_popup_pos == 1) /* == "Top" */ + if (config_resize_popup_pos == OB_RESIZE_POS_TOP) popup_position(popup, SouthGravity, c->frame->area.x + c->frame->area.width/2, c->frame->area.y - ob_rr_theme->fbwidth); - else /* == "Center" */ + else if (config_resize_popup_pos == OB_RESIZE_POS_CENTER) popup_position(popup, CenterGravity, c->frame->area.x + c->frame->size.left + c->area.width / 2, c->frame->area.y + c->frame->size.top + c->area.height / 2); + else /* Fixed */ { + Rect *area = screen_physical_area_active(); + gint gravity, x, y; + + x = config_resize_popup_fixed.x.pos; + if (config_resize_popup_fixed.x.center) + x = area->x + area->width/2; + else if (config_resize_popup_fixed.x.opposite) + x = RECT_RIGHT(*area) - x; + else + x = area->x + x; + + y = config_resize_popup_fixed.y.pos; + if (config_resize_popup_fixed.y.center) + y = area->y + area->height/2; + else if (config_resize_popup_fixed.y.opposite) + y = RECT_RIGHT(*area) - y; + else + y = area->y + y; + + if (config_resize_popup_fixed.x.center) { + if (config_resize_popup_fixed.y.center) + gravity = CenterGravity; + else if (config_resize_popup_fixed.y.opposite) + gravity = SouthGravity; + else + gravity = NorthGravity; + } + else if (config_resize_popup_fixed.x.opposite) { + if (config_resize_popup_fixed.y.center) + gravity = EastGravity; + else if (config_resize_popup_fixed.y.opposite) + gravity = SouthEastGravity; + else + gravity = NorthEastGravity; + } + else { + if (config_resize_popup_fixed.y.center) + gravity = WestGravity; + else if (config_resize_popup_fixed.y.opposite) + gravity = SouthWestGravity; + else + gravity = NorthWestGravity; + } + + popup_position(popup, gravity, x, y); + + g_free(area); + } popup_show(popup, text); g_free(text); } @@ -121,6 +170,8 @@ void moveresize_start(ObClient *c, gint x, gint y, guint b, guint32 cnr) ObCursor cur; gboolean mv = (cnr == prop_atoms.net_wm_moveresize_move || cnr == prop_atoms.net_wm_moveresize_move_keyboard); + gint up = 1; + gint left = 1; if (moveresize_in_progress || !c->frame->visible || !(mv ? @@ -128,23 +179,28 @@ void moveresize_start(ObClient *c, gint x, gint y, guint b, guint32 cnr) (c->functions & OB_CLIENT_FUNC_RESIZE))) return; - if (cnr == prop_atoms.net_wm_moveresize_size_topleft) + if (cnr == prop_atoms.net_wm_moveresize_size_topleft) { cur = OB_CURSOR_NORTHWEST; - else if (cnr == prop_atoms.net_wm_moveresize_size_top) + up = left = -1; + } else if (cnr == prop_atoms.net_wm_moveresize_size_top) { cur = OB_CURSOR_NORTH; - else if (cnr == prop_atoms.net_wm_moveresize_size_topright) + up = -1; + } else if (cnr == prop_atoms.net_wm_moveresize_size_topright) { cur = OB_CURSOR_NORTHEAST; - else if (cnr == prop_atoms.net_wm_moveresize_size_right) + up = -1; + } else if (cnr == prop_atoms.net_wm_moveresize_size_right) cur = OB_CURSOR_EAST; else if (cnr == prop_atoms.net_wm_moveresize_size_bottomright) cur = OB_CURSOR_SOUTHEAST; else if (cnr == prop_atoms.net_wm_moveresize_size_bottom) cur = OB_CURSOR_SOUTH; - else if (cnr == prop_atoms.net_wm_moveresize_size_bottomleft) + else if (cnr == prop_atoms.net_wm_moveresize_size_bottomleft) { cur = OB_CURSOR_SOUTHWEST; - else if (cnr == prop_atoms.net_wm_moveresize_size_left) + left = -1; + } else if (cnr == prop_atoms.net_wm_moveresize_size_left) { cur = OB_CURSOR_WEST; - else if (cnr == prop_atoms.net_wm_moveresize_size_keyboard) + left = -1; + } else if (cnr == prop_atoms.net_wm_moveresize_size_keyboard) cur = OB_CURSOR_SOUTHEAST; else if (cnr == prop_atoms.net_wm_moveresize_move) cur = OB_CURSOR_MOVE; @@ -167,14 +223,14 @@ void moveresize_start(ObClient *c, gint x, gint y, guint b, guint32 cnr) moveresize_client = c; start_cx = c->area.x; start_cy = c->area.y; + start_cw = c->area.width; + start_ch = c->area.height; /* these adjustments for the size_inc make resizing a terminal more friendly. you essentially start the resize in the middle of the increment instead of at 0, so you have to move half an increment either way instead of a full increment one and 1 px the other. */ - start_cw = c->area.width + c->size_inc.width / 2; - start_ch = c->area.height + c->size_inc.height / 2; - start_x = x; - start_y = y; + start_x = x - (mv ? 0 : left * c->size_inc.width / 2); + start_y = y - (mv ? 0 : up * c->size_inc.height / 2); corner = cnr; button = b; key_resize_edge = -1; @@ -195,8 +251,9 @@ void moveresize_start(ObClient *c, gint x, gint y, guint b, guint32 cnr) moveresize_in_progress = TRUE; #ifdef SYNC - if (config_resize_redraw && !moving && extensions_shape && - moveresize_client->sync_request && moveresize_client->sync_counter) + if (config_resize_redraw && !moving && extensions_sync && + moveresize_client->sync_request && moveresize_client->sync_counter && + !moveresize_client->not_responding) { /* Initialize values for the resize syncing, and create an alarm for the client's xsync counter */ @@ -292,7 +349,7 @@ static void do_move(gboolean keyboard, gint keydist) } -static void do_resize() +static void do_resize(void) { gint x, y, w, h, lw, lh; @@ -311,7 +368,8 @@ static void do_resize() #ifdef SYNC if (config_resize_redraw && extensions_sync && - moveresize_client->sync_request && moveresize_client->sync_counter) + moveresize_client->sync_request && moveresize_client->sync_counter && + !moveresize_client->not_responding) { XEvent ce; XSyncValue val; @@ -341,7 +399,7 @@ static void do_resize() waiting_for_sync = TRUE; ob_main_loop_timeout_remove(ob_main_loop, sync_timeout_func); - ob_main_loop_timeout_add(ob_main_loop, G_USEC_PER_SEC / 2, + ob_main_loop_timeout_add(ob_main_loop, G_USEC_PER_SEC * 2, sync_timeout_func, NULL, NULL, NULL); } @@ -372,25 +430,102 @@ static gboolean sync_timeout_func(gpointer data) #endif static void calc_resize(gboolean keyboard, gint keydist, gint *dw, gint *dh, - ObCorner cor) + ObDirection dir) { - gint resist, ow, oh, nw, nh; + gint resist, x = 0, y = 0, lw, lh, ow, oh, nw, nh; + gint trydw, trydh; + + ow = cur_w; + oh = cur_h; + nw = ow + *dw; + nh = oh + *dh; + + if (!keyboard && + (moveresize_client->max_ratio || moveresize_client->min_ratio)) + { + switch (dir) { + case OB_DIRECTION_NORTH: + case OB_DIRECTION_SOUTH: + /* resize the width based on the height */ + if (moveresize_client->min_ratio) { + if (nh * moveresize_client->min_ratio > nw) + nw = (gint)(nh * moveresize_client->min_ratio); + } + if (moveresize_client->max_ratio) { + if (nh * moveresize_client->max_ratio < nw) + nw = (gint)(nh * moveresize_client->max_ratio); + } + break; + default: + /* resize the height based on the width */ + if (moveresize_client->min_ratio) { + if (nh * moveresize_client->min_ratio > nw) + nh = (gint)(nw / moveresize_client->min_ratio); + } + if (moveresize_client->max_ratio) { + if (nh * moveresize_client->max_ratio < nw) + nh = (gint)(nw / moveresize_client->max_ratio); + } + break; + } + + /* see its actual size (apply aspect ratios) */ + client_try_configure(moveresize_client, &x, &y, &nw, &nh, &lw, &lh, + TRUE); + trydw = nw - ow; + trydh = nh - oh; + } /* resist_size_* needs the frame size */ - ow = cur_w + - moveresize_client->frame->size.left + + nw += moveresize_client->frame->size.left + moveresize_client->frame->size.right; - oh = cur_h + - moveresize_client->frame->size.top + + nh += moveresize_client->frame->size.top + moveresize_client->frame->size.bottom; - nw = ow + *dw; - nh = oh + *dh; if (keyboard) resist = keydist - 1; /* resist for one key press */ else resist = config_resist_win; - resist_size_windows(moveresize_client, resist, &nw, &nh, cor); + resist_size_windows(moveresize_client, resist, &nw, &nh, dir); if (!keyboard) resist = config_resist_edge; - resist_size_monitors(moveresize_client, resist, &nw, &nh, cor); + resist_size_monitors(moveresize_client, resist, &nw, &nh, dir); + + nw -= moveresize_client->frame->size.left + + moveresize_client->frame->size.right; + nh -= moveresize_client->frame->size.top + + moveresize_client->frame->size.bottom; + + *dw = nw - ow; + *dh = nh - oh; + + /* take aspect ratios into account for resistance */ + if (!keyboard && + (moveresize_client->max_ratio || moveresize_client->min_ratio)) + { + if (*dh != trydh) { /* got resisted */ + /* resize the width based on the height */ + if (moveresize_client->min_ratio) { + if (nh * moveresize_client->min_ratio > nw) + nw = (gint)(nh * moveresize_client->min_ratio); + } + if (moveresize_client->max_ratio) { + if (nh * moveresize_client->max_ratio < nw) + nw = (gint)(nh * moveresize_client->max_ratio); + } + } + if (*dw != trydw) { /* got resisted */ + /* resize the height based on the width */ + if (moveresize_client->min_ratio) { + if (nh * moveresize_client->min_ratio > nw) + nh = (gint)(nw / moveresize_client->min_ratio); + } + if (moveresize_client->max_ratio) { + if (nh * moveresize_client->max_ratio < nw) + nh = (gint)(nw / moveresize_client->max_ratio); + } + } + } + + /* make sure it's all valid */ + client_try_configure(moveresize_client, &x, &y, &nw, &nh, &lw, &lh, TRUE); *dw = nw - ow; *dh = nh - oh; @@ -400,12 +535,15 @@ static gboolean edge_warp_delay_func(gpointer data) { guint d; - d = screen_find_desktop(screen_desktop, edge_warp_dir, TRUE, FALSE); - if (d != screen_desktop) screen_set_desktop(d, TRUE); - - edge_warp_dir = -1; + /* only fire every second time. so it's fast the first time, but slower + after that */ + if (edge_warp_odd) { + d = screen_find_desktop(screen_desktop, edge_warp_dir, TRUE, FALSE); + if (d != screen_desktop) screen_set_desktop(d, TRUE); + } + edge_warp_odd = !edge_warp_odd; - return FALSE; /* don't repeat */ + return TRUE; /* do repeat ! */ } static void do_edge_warp(gint x, gint y) @@ -439,18 +577,19 @@ static void do_edge_warp(gint x, gint y) } if (dir != edge_warp_dir) { - if (dir == (ObDirection)-1) - cancel_edge_warp(); - else + cancel_edge_warp(); + if (dir != (ObDirection)-1) { + edge_warp_odd = TRUE; /* switch on the first timeout */ ob_main_loop_timeout_add(ob_main_loop, config_mouse_screenedgetime * 1000, edge_warp_delay_func, NULL, NULL, NULL); + } edge_warp_dir = dir; } } -static void cancel_edge_warp() +static void cancel_edge_warp(void) { ob_main_loop_timeout_remove(ob_main_loop, edge_warp_delay_func); } @@ -520,9 +659,8 @@ static void move_with_keys(gint keycode, gint state) 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; + gint dist = 0, resist = 0; ObDirection dir; - ObCorner cor; /* pick the edge if it needs to move */ if (keycode == ob_keycode(OB_KEY_RIGHT)) { @@ -584,18 +722,30 @@ static void resize_with_keys(gint keycode, gint state) gint distw, disth; /* control means fine grained */ - if (moveresize_client->size_inc.width > 1) + if (moveresize_client->size_inc.width > 1) { distw = moveresize_client->size_inc.width; - else if (state & modkeys_key_to_mask(OB_MODKEY_KEY_CONTROL)) + resist = 1; + } + else if (state & modkeys_key_to_mask(OB_MODKEY_KEY_CONTROL)) { distw = 1; - else + resist = 1; + } + else { distw = KEY_DIST; - if (moveresize_client->size_inc.height > 1) + resist = KEY_DIST; + } + if (moveresize_client->size_inc.height > 1) { disth = moveresize_client->size_inc.height; - else if (state & modkeys_key_to_mask(OB_MODKEY_KEY_CONTROL)) + resist = 1; + } + else if (state & modkeys_key_to_mask(OB_MODKEY_KEY_CONTROL)) { disth = 1; - else + resist = 1; + } + else { disth = KEY_DIST; + resist = KEY_DIST; + } if (key_resize_edge == OB_DIRECTION_WEST) { if (dir == OB_DIRECTION_WEST) @@ -623,17 +773,7 @@ static void resize_with_keys(gint keycode, gint state) } } - /* which corner is locked, for resistance */ - if (key_resize_edge == OB_DIRECTION_WEST) - cor = OB_CORNER_TOPRIGHT; - else if (key_resize_edge == OB_DIRECTION_EAST) - cor = OB_CORNER_TOPLEFT; - else if (key_resize_edge == OB_DIRECTION_NORTH) - cor = OB_CORNER_BOTTOMLEFT; - else if (key_resize_edge == OB_DIRECTION_SOUTH) - cor = OB_CORNER_TOPLEFT; - - calc_resize(TRUE, dist, &dw, &dh, cor); + 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) @@ -650,7 +790,7 @@ static void resize_with_keys(gint keycode, gint state) 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 */ @@ -698,52 +838,53 @@ gboolean moveresize_event(XEvent *e) do_edge_warp(e->xmotion.x_root, e->xmotion.y_root); } else { gint dw, dh; + ObDirection dir; if (corner == prop_atoms.net_wm_moveresize_size_topleft) { dw = -(e->xmotion.x_root - start_x); dh = -(e->xmotion.y_root - start_y); - lockcorner = OB_CORNER_BOTTOMRIGHT; + dir = OB_DIRECTION_NORTHWEST; } else if (corner == prop_atoms.net_wm_moveresize_size_top) { dw = 0; - dh = (e->xmotion.y_root - start_y); - lockcorner = OB_CORNER_BOTTOMRIGHT; + dh = -(e->xmotion.y_root - start_y); + dir = OB_DIRECTION_NORTH; } else if (corner == prop_atoms.net_wm_moveresize_size_topright) { dw = (e->xmotion.x_root - start_x); dh = -(e->xmotion.y_root - start_y); - lockcorner = OB_CORNER_BOTTOMLEFT; - } else if (corner == prop_atoms.net_wm_moveresize_size_right) { + dir = OB_DIRECTION_NORTHEAST; + } else if (corner == prop_atoms.net_wm_moveresize_size_right) { dw = (e->xmotion.x_root - start_x); dh = 0; - lockcorner = OB_CORNER_BOTTOMLEFT; + dir = OB_DIRECTION_EAST; } else if (corner == prop_atoms.net_wm_moveresize_size_bottomright) { dw = (e->xmotion.x_root - start_x); dh = (e->xmotion.y_root - start_y); - lockcorner = OB_CORNER_TOPLEFT; + dir = OB_DIRECTION_SOUTHEAST; } else if (corner == prop_atoms.net_wm_moveresize_size_bottom) { dw = 0; dh = (e->xmotion.y_root - start_y); - lockcorner = OB_CORNER_TOPLEFT; + dir = OB_DIRECTION_SOUTH; } else if (corner == prop_atoms.net_wm_moveresize_size_bottomleft) { dw = -(e->xmotion.x_root - start_x); dh = (e->xmotion.y_root - start_y); - lockcorner = OB_CORNER_TOPRIGHT; + dir = OB_DIRECTION_SOUTHWEST; } else if (corner == prop_atoms.net_wm_moveresize_size_left) { dw = -(e->xmotion.x_root - start_x); dh = 0; - lockcorner = OB_CORNER_TOPRIGHT; + dir = OB_DIRECTION_WEST; } else if (corner == prop_atoms.net_wm_moveresize_size_keyboard) { dw = (e->xmotion.x_root - start_x); dh = (e->xmotion.y_root - start_y); - lockcorner = OB_CORNER_TOPLEFT; + dir = OB_DIRECTION_SOUTHEAST; } else g_assert_not_reached(); dw -= cur_w - start_cw; dh -= cur_h - start_ch; - calc_resize(FALSE, 0, &dw, &dh, lockcorner); + calc_resize(FALSE, 0, &dw, &dh, dir); cur_w += dw; cur_h += dh;