From 55d2916c1e24e021d9b9692d2373dc4afff4c5c2 Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Tue, 1 May 2007 04:46:29 +0000 Subject: [PATCH] a whole lot of changes to the moving/resizing code. it was broken for non-northwest gravities. now it is not. at least, that is the idea. --- openbox/action.c | 6 ++-- openbox/client.c | 70 +++++++++++++++++++----------------------- openbox/client.h | 25 ++++++++------- openbox/event.c | 73 ++++++-------------------------------------- openbox/frame.c | 41 ++++++++++++------------- openbox/frame.h | 5 ++- openbox/moveresize.c | 73 +++++++++++++++++++++++++++++++++++--------- openbox/place.c | 3 +- 8 files changed, 138 insertions(+), 158 deletions(-) diff --git a/openbox/action.c b/openbox/action.c index 80b0a8f1..f57ab605 100644 --- a/openbox/action.c +++ b/openbox/action.c @@ -1394,7 +1394,7 @@ void action_resize_relative(union ActionData *data) h = oh + data->relative.deltay * c->size_inc.height + data->relative.deltayu * c->size_inc.height; - client_try_configure(c, OB_CORNER_TOPLEFT, &x, &y, &w, &h, &lw, &lh, TRUE); + client_try_configure(c, &x, &y, &w, &h, &lw, &lh, TRUE); client_move_resize(c, x + (ow - w), y + (oh - h), w, h); client_action_end(data); } @@ -1795,7 +1795,7 @@ void action_movetoedge(union ActionData *data) default: g_assert_not_reached(); } - frame_frame_gravity(c->frame, &x, &y); + frame_frame_gravity(c->frame, &x, &y, c->area.width, c->area.height); client_action_start(data); client_move(c, x, y); client_action_end(data); @@ -1859,9 +1859,9 @@ void action_growtoedge(union ActionData *data) default: g_assert_not_reached(); } - frame_frame_gravity(c->frame, &x, &y); width -= c->frame->size.left + c->frame->size.right; height -= c->frame->size.top + c->frame->size.bottom; + frame_frame_gravity(c->frame, &x, &y, width, height); client_action_start(data); client_move_resize(c, x, y, width, height); client_action_end(data); diff --git a/openbox/client.c b/openbox/client.c index 13e239d3..6b8635be 100644 --- a/openbox/client.c +++ b/openbox/client.c @@ -754,8 +754,10 @@ gboolean client_find_onscreen(ObClient *self, gint *x, gint *y, gint w, gint h, Rect *a; gint ox = *x, oy = *y; - frame_client_gravity(self->frame, x, y); /* get where the frame - would be */ + /* XXX figure out if it is on screen now, and be rude if it is */ + + /* get where the frame would be */ + frame_client_gravity(self->frame, x, y, w, h); /* XXX watch for xinerama dead areas */ /* This makes sure windows aren't entirely outside of the screen so you @@ -804,8 +806,8 @@ gboolean client_find_onscreen(ObClient *self, gint *x, gint *y, gint w, gint h, } } - frame_frame_gravity(self->frame, x, y); /* get where the client - should be */ + /* get where the client should be */ + frame_frame_gravity(self->frame, x, y, w, h); return ox != *x || oy != *y; } @@ -1351,9 +1353,9 @@ void client_update_normal_hints(ObClient *self) if (self->frame && self->gravity != oldgravity) { /* move our idea of the client's position based on its new gravity */ - self->area.x = self->frame->area.x; - self->area.y = self->frame->area.y; - frame_frame_gravity(self->frame, &self->area.x, &self->area.y); + client_convert_gravity(self, oldgravity, + &self->area.x, &self->area.y, + self->area.width, self->area.height); } } @@ -1572,7 +1574,7 @@ void client_reconfigure(ObClient *self) /* by making this pass FALSE for user, we avoid the emacs event storm where every configurenotify causes an update in its normal hints, i think this is generally what we want anyways... */ - client_configure(self, OB_CORNER_TOPLEFT, self->area.x, self->area.y, + client_configure(self, self->area.x, self->area.y, self->area.width, self->area.height, FALSE, TRUE); } @@ -2225,8 +2227,21 @@ static void client_apply_startup_state(ObClient *self, gint x, gint y) */ } -void client_try_configure(ObClient *self, ObCorner anchor, - gint *x, gint *y, gint *w, gint *h, +void client_convert_gravity(ObClient *self, gint gravity, gint *x, gint *y, + gint w, gint h) +{ + gint oldg = self->gravity; + + /* get the frame's position from the requested stuff */ + self->gravity = gravity; + frame_client_gravity(self->frame, x, y, w, h); + self->gravity = oldg; + + /* get the client's position in its true gravity from that */ + frame_frame_gravity(self->frame, x, y, w, h); +} + +void client_try_configure(ObClient *self, gint *x, gint *y, gint *w, gint *h, gint *logicalw, gint *logicalh, gboolean user) { @@ -2321,7 +2336,7 @@ void client_try_configure(ObClient *self, ObCorner anchor, } /* gets the frame's position */ - frame_client_gravity(self->frame, x, y); + frame_client_gravity(self->frame, x, y, *w, *h); /* these positions are frame positions, not client positions */ @@ -2362,7 +2377,7 @@ void client_try_configure(ObClient *self, ObCorner anchor, } /* gets the client's position */ - frame_frame_gravity(self->frame, x, y); + frame_frame_gravity(self->frame, x, y, *w, *h); /* these override the above states! if you cant move you can't move! */ if (user) { @@ -2378,26 +2393,10 @@ void client_try_configure(ObClient *self, ObCorner anchor, g_assert(*w > 0); g_assert(*h > 0); - - switch (anchor) { - case OB_CORNER_TOPLEFT: - break; - case OB_CORNER_TOPRIGHT: - *x -= *w - self->area.width; - break; - case OB_CORNER_BOTTOMLEFT: - *y -= *h - self->area.height; - break; - case OB_CORNER_BOTTOMRIGHT: - *x -= *w - self->area.width; - *y -= *h - self->area.height; - break; - } } -void client_configure_full(ObClient *self, ObCorner anchor, - gint x, gint y, gint w, gint h, +void client_configure_full(ObClient *self, gint x, gint y, gint w, gint h, gboolean user, gboolean final, gboolean force_reply) { @@ -2409,8 +2408,7 @@ void client_configure_full(ObClient *self, ObCorner anchor, gint logicalw, logicalh; /* find the new x, y, width, and height (and logical size) */ - client_try_configure(self, anchor, &x, &y, &w, &h, - &logicalw, &logicalh, user); + client_try_configure(self, &x, &y, &w, &h, &logicalw, &logicalh, user); /* set the logical size if things changed */ if (!(w == self->area.width && h == self->area.height)) @@ -2432,10 +2430,8 @@ void client_configure_full(ObClient *self, ObCorner anchor, (resized && config_resize_redraw)))); /* if the client is enlarging, then resize the client before the frame */ - if (send_resize_client && user && (w > oldw || h > oldh)) { + if (send_resize_client && user && (w > oldw || h > oldh)) XResizeWindow(ob_display, self->window, MAX(w, oldw), MAX(h, oldh)); - frame_adjust_client_area(self->frame); - } /* find the frame's dimensions and move/resize it */ if (self->decorations != fdecor || self->max_horz != fhorz) @@ -2481,10 +2477,8 @@ void client_configure_full(ObClient *self, ObCorner anchor, } /* if the client is shrinking, then resize the frame before the client */ - if (send_resize_client && (!user || (w <= oldw || h <= oldh))) { - frame_adjust_client_area(self->frame); + if (send_resize_client && (!user || (w <= oldw || h <= oldh))) XResizeWindow(ob_display, self->window, w, h); - } XFlush(ob_display); } @@ -3258,7 +3252,7 @@ void client_set_undecorated(ObClient *self, gboolean undecorated) * since 125 of these are sent per second when moving the window (with * user = FALSE) i doubt it matters much. */ - client_configure(self, OB_CORNER_TOPLEFT, self->area.x, self->area.y, + client_configure(self, self->area.x, self->area.y, self->area.width, self->area.height, TRUE, TRUE); client_change_state(self); /* reflect this in the state hints */ } diff --git a/openbox/client.h b/openbox/client.h index 69f5aa5f..5847c67f 100644 --- a/openbox/client.h +++ b/openbox/client.h @@ -348,25 +348,27 @@ gboolean client_normal(ObClient *self); /* Returns if the window is focused */ gboolean client_focused(ObClient *self); +/*! Convery a position/size from a given gravity to the client's true gravity + */ +void client_convert_gravity(ObClient *client, gint gravity, gint *x, gint *y, + gint w, gint h); + #define client_move(self, x, y) \ - client_configure(self, OB_CORNER_TOPLEFT, x, y, \ - self->area.width, self->area.height, \ + client_configure(self, x, y, self->area.width, self->area.height, \ TRUE, TRUE) #define client_resize(self, w, h) \ - client_configure(self, OB_CORNER_TOPLEFT, self->area.x, self->area.y, \ - w, h, TRUE, TRUE) + client_configure(self, self->area.x, self->area.y, w, h, TRUE, TRUE) #define client_move_resize(self, x, y, w, h) \ - client_configure(self, OB_CORNER_TOPLEFT, x, y, w, h, TRUE, TRUE) + client_configure(self, x, y, w, h, TRUE, TRUE) -#define client_configure(self, anchor, x, y, w, h, user, final) \ - client_configure_full(self, anchor, x, y, w, h, user, final, FALSE) +#define client_configure(self, x, y, w, h, user, final) \ + client_configure_full(self, x, y, w, h, user, final, FALSE) /*! Figure out where a window will end up and what size it will be if you told it to move/resize to these coordinates. These values are what client_configure_full will give the window. - @param anchor The corner to keep in the same position when resizing. @param x The x coordiante of the new position for the client. @param y The y coordiante of the new position for the client. @param w The width component of the new size for the client. @@ -381,14 +383,12 @@ gboolean client_focused(ObClient *self); program requested change. For program requested changes, the constraints are not checked. */ -void client_try_configure(ObClient *self, ObCorner anchor, - gint *x, gint *y, gint *w, gint *h, +void client_try_configure(ObClient *self, gint *x, gint *y, gint *w, gint *h, gint *logicalw, gint *logicalh, gboolean user); /*! Move and/or resize the window. This also maintains things like the client's minsize, and size increments. - @param anchor The corner to keep in the same position when resizing. @param x The x coordiante of the new position for the client. @param y The y coordiante of the new position for the client. @param w The width component of the new size for the client. @@ -403,8 +403,7 @@ void client_try_configure(ObClient *self, ObCorner anchor, @param force_reply Send a ConfigureNotify to the client regardless of if the position changed. */ -void client_configure_full(ObClient *self, ObCorner anchor, - gint x, gint y, gint w, gint h, +void client_configure_full(ObClient *self, gint x, gint y, gint w, gint h, gboolean user, gboolean final, gboolean force_reply); diff --git a/openbox/event.c b/openbox/event.c index 10b7816c..78768a62 100644 --- a/openbox/event.c +++ b/openbox/event.c @@ -873,7 +873,6 @@ static void event_handle_client(ObClient *client, XEvent *e) CWX | CWY | CWBorderWidth)) { gint x, y, w, h; - ObCorner corner; if (e->xconfigurerequest.value_mask & CWBorderWidth) client->border_width = e->xconfigurerequest.border_width; @@ -887,44 +886,8 @@ static void event_handle_client(ObClient *client, XEvent *e) h = (e->xconfigurerequest.value_mask & CWHeight) ? e->xconfigurerequest.height : client->area.height; - { - gint newx = x; - gint newy = y; - gint fw = w + - client->frame->size.left + client->frame->size.right; - gint fh = h + - client->frame->size.top + client->frame->size.bottom; - /* make this rude for size-only changes but not for position - changes.. */ - gboolean moving = ((e->xconfigurerequest.value_mask & CWX) || - (e->xconfigurerequest.value_mask & CWY)); - - client_find_onscreen(client, &newx, &newy, fw, fh, - !moving); - if (e->xconfigurerequest.value_mask & CWX) - x = newx; - if (e->xconfigurerequest.value_mask & CWY) - y = newy; - } - - switch (client->gravity) { - case NorthEastGravity: - case EastGravity: - corner = OB_CORNER_TOPRIGHT; - break; - case SouthWestGravity: - case SouthGravity: - corner = OB_CORNER_BOTTOMLEFT; - break; - case SouthEastGravity: - corner = OB_CORNER_BOTTOMRIGHT; - break; - default: /* NorthWest, Static, etc */ - corner = OB_CORNER_TOPLEFT; - } - - client_configure_full(client, corner, x, y, w, h, FALSE, TRUE, - TRUE); + client_find_onscreen(client, &x, &y, w, h, client_normal(client)); + client_configure_full(client, x, y, w, h, FALSE, TRUE, TRUE); } if (e->xconfigurerequest.value_mask & CWStackMode) { @@ -1086,13 +1049,12 @@ static void event_handle_client(ObClient *client, XEvent *e) prop_atoms.net_wm_moveresize_cancel) moveresize_end(TRUE); } else if (msgtype == prop_atoms.net_moveresize_window) { - gint oldg = client->gravity; - gint tmpg, x, y, w, h; + gint grav, x, y, w, h; if (e->xclient.data.l[0] & 0xff) - tmpg = e->xclient.data.l[0] & 0xff; - else - tmpg = oldg; + grav = e->xclient.data.l[0] & 0xff; + else + grav = client->gravity; if (e->xclient.data.l[0] & 1 << 8) x = e->xclient.data.l[1]; @@ -1110,27 +1072,10 @@ static void event_handle_client(ObClient *client, XEvent *e) h = e->xclient.data.l[4]; else h = client->area.height; - client->gravity = tmpg; - - { - gint newx = x; - gint newy = y; - gint fw = w + - client->frame->size.left + client->frame->size.right; - gint fh = h + - client->frame->size.top + client->frame->size.bottom; - client_find_onscreen(client, &newx, &newy, fw, fh, - client_normal(client)); - if (e->xclient.data.l[0] & 1 << 8) - x = newx; - if (e->xclient.data.l[0] & 1 << 9) - y = newy; - } - - client_configure(client, OB_CORNER_TOPLEFT, - x, y, w, h, FALSE, TRUE); - client->gravity = oldg; + client_convert_gravity(client, grav, &x, &y, w, h); + client_find_onscreen(client, &x, &y, w, h, client_normal(client)); + client_configure(client, x, y, w, h, FALSE, TRUE); } break; case PropertyNotify: diff --git a/openbox/frame.c b/openbox/frame.c index c1bacb67..f12dbfb2 100644 --- a/openbox/frame.c +++ b/openbox/frame.c @@ -442,9 +442,11 @@ void frame_adjust_area(ObFrame *self, gboolean moved, self->client->area.height + self->cbwidth_y * 2); - /* move the plate */ - XMoveWindow(ob_display, self->plate, - self->cbwidth_x, self->cbwidth_y); + /* move and resize the plate */ + XMoveResizeWindow(ob_display, self->plate, + self->cbwidth_x, self->cbwidth_y, + self->client->area.width, + self->client->area.height); /* when the client has StaticGravity, it likes to move around. */ XMoveWindow(ob_display, self->client->window, 0, 0); @@ -466,12 +468,14 @@ void frame_adjust_area(ObFrame *self, gboolean moved, self->client->area.height + self->size.top + self->size.bottom)); - if (moved) { + if (moved || resized) { /* find the new coordinates, done after setting the frame.size, for frame_client_gravity. */ self->area.x = self->client->area.x; self->area.y = self->client->area.y; - frame_client_gravity(self, &self->area.x, &self->area.y); + frame_client_gravity(self, &self->area.x, &self->area.y, + self->client->area.width, + self->client->area.height); } if (!fake) { @@ -519,13 +523,6 @@ void frame_adjust_focus(ObFrame *self, gboolean hilite) XFlush(ob_display); } -void frame_adjust_client_area(ObFrame *self) -{ - /* resize the plate */ - XResizeWindow(ob_display, self->plate, - self->client->area.width, self->client->area.height); -} - void frame_adjust_title(ObFrame *self) { framerender_frame(self); @@ -861,7 +858,7 @@ ObFrameContext frame_context(ObClient *client, Window win) return OB_FRAME_CONTEXT_NONE; } -void frame_client_gravity(ObFrame *self, gint *x, gint *y) +void frame_client_gravity(ObFrame *self, gint *x, gint *y, gint w, gint h) { /* horizontal */ switch (self->client->gravity) { @@ -874,13 +871,13 @@ void frame_client_gravity(ObFrame *self, gint *x, gint *y) case NorthGravity: case SouthGravity: case CenterGravity: - *x -= (self->size.left + self->size.right) / 2; + *x -= (self->size.left + w) / 2; break; case NorthEastGravity: case SouthEastGravity: case EastGravity: - *x -= self->size.left + self->size.right; + *x -= (self->size.left + self->size.right + w) - 1; break; case ForgetGravity: @@ -900,13 +897,13 @@ void frame_client_gravity(ObFrame *self, gint *x, gint *y) case CenterGravity: case EastGravity: case WestGravity: - *y -= (self->size.top + self->size.bottom) / 2; + *y -= (self->size.top + h) / 2; break; case SouthWestGravity: case SouthEastGravity: case SouthGravity: - *y -= self->size.top + self->size.bottom; + *y -= (self->size.top + self->size.bottom + h) - 1; break; case ForgetGravity: @@ -916,7 +913,7 @@ void frame_client_gravity(ObFrame *self, gint *x, gint *y) } } -void frame_frame_gravity(ObFrame *self, gint *x, gint *y) +void frame_frame_gravity(ObFrame *self, gint *x, gint *y, gint w, gint h) { /* horizontal */ switch (self->client->gravity) { @@ -928,12 +925,12 @@ void frame_frame_gravity(ObFrame *self, gint *x, gint *y) case NorthGravity: case CenterGravity: case SouthGravity: - *x += (self->size.left + self->size.right) / 2; + *x += (self->size.left + w) / 2; break; case NorthEastGravity: case EastGravity: case SouthEastGravity: - *x += self->size.left + self->size.right; + *x += (self->size.left + self->size.right + w) - 1; break; case StaticGravity: case ForgetGravity: @@ -951,12 +948,12 @@ void frame_frame_gravity(ObFrame *self, gint *x, gint *y) case WestGravity: case CenterGravity: case EastGravity: - *y += (self->size.top + self->size.bottom) / 2; + *y += (self->size.top + h) / 2; break; case SouthWestGravity: case SouthGravity: case SouthEastGravity: - *y += self->size.top + self->size.bottom; + *y += (self->size.top + self->size.bottom + h) - 1; break; case StaticGravity: case ForgetGravity: diff --git a/openbox/frame.h b/openbox/frame.h index b5372647..344c1530 100644 --- a/openbox/frame.h +++ b/openbox/frame.h @@ -151,7 +151,6 @@ void frame_adjust_theme(ObFrame *self); void frame_adjust_shape(ObFrame *self); void frame_adjust_area(ObFrame *self, gboolean moved, gboolean resized, gboolean fake); -void frame_adjust_client_area(ObFrame *self); void frame_adjust_state(ObFrame *self); void frame_adjust_focus(ObFrame *self, gboolean hilite); void frame_adjust_title(ObFrame *self); @@ -167,13 +166,13 @@ ObFrameContext frame_context(struct _ObClient *self, Window win); be positioned. @return The proper coordinates for the frame, based on the client. */ -void frame_client_gravity(ObFrame *self, gint *x, gint *y); +void frame_client_gravity(ObFrame *self, gint *x, gint *y, gint w, gint h); /*! Reversly applies gravity to the frame's position to find where the client should be positioned. @return The proper coordinates for the client, based on the frame. */ -void frame_frame_gravity(ObFrame *self, gint *x, gint *y); +void frame_frame_gravity(ObFrame *self, gint *x, gint *y, gint w, gint h); void frame_flash_start(ObFrame *self); void frame_flash_stop(ObFrame *self); diff --git a/openbox/moveresize.c b/openbox/moveresize.c index 6db822c3..b03aed95 100644 --- a/openbox/moveresize.c +++ b/openbox/moveresize.c @@ -82,6 +82,50 @@ void moveresize_shutdown(gboolean reconfig) popup = NULL; } +static void get_resize_position(gint *x, gint *y, gboolean cancel) +{ + gint dw, dh; + gint w, h, lw, lh; + + *x = moveresize_client->frame->area.x; + *y = moveresize_client->frame->area.y; + + if (cancel) { + w = start_cw; + h = start_ch; + } else { + w = cur_x; + h = cur_y; + } + + /* see how much it is actually going to resize */ + { + gint cx = x, cy = y; + frame_frame_gravity(moveresize_client->frame, &cx, &cy, w, h); + client_try_configure(moveresize_client, &cx, &cy, &w, &h, + &lw, &lh, TRUE); + } + dw = w - moveresize_client->area.width; + dh = h - moveresize_client->area.height; + + switch (lockcorner) { + case OB_CORNER_TOPLEFT: + break; + case OB_CORNER_TOPRIGHT: + *x -= dw; + break; + case OB_CORNER_BOTTOMLEFT: + *y -= dh; + break; + case OB_CORNER_BOTTOMRIGHT: + *x -= dw; + *y -= dh; + break; + } + + frame_frame_gravity(moveresize_client->frame, x, y, w, h); +} + static void popup_coords(ObClient *c, const gchar *format, gint a, gint b) { gchar *text; @@ -116,8 +160,8 @@ void moveresize_start(ObClient *c, gint x, gint y, guint b, guint32 cnr) return; moveresize_client = c; - start_cx = c->frame->area.x; - start_cy = c->frame->area.y; + start_cx = c->area.x; + start_cy = c->area.y; /* 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 @@ -220,6 +264,8 @@ void moveresize_start(ObClient *c, gint x, gint y, guint b, guint32 cnr) void moveresize_end(gboolean cancel) { + gint x, y; + grab_keyboard(FALSE); grab_pointer(FALSE, FALSE, OB_CURSOR_NONE); @@ -238,9 +284,8 @@ void moveresize_end(gboolean cancel) } #endif - client_configure(moveresize_client, lockcorner, - moveresize_client->area.x, - moveresize_client->area.y, + get_resize_position(&x, &y, cancel); + client_configure(moveresize_client, x, y, (cancel ? start_cw : cur_x), (cancel ? start_ch : cur_y), TRUE, TRUE); } @@ -256,9 +301,7 @@ static void do_move(gboolean resist) resist_move_monitors(moveresize_client, &cur_x, &cur_y); } - /* get where the client should be */ - frame_frame_gravity(moveresize_client->frame, &cur_x, &cur_y); - client_configure(moveresize_client, OB_CORNER_TOPLEFT, cur_x, cur_y, + client_configure(moveresize_client, cur_x, cur_y, moveresize_client->area.width, moveresize_client->area.height, TRUE, FALSE); if (config_resize_popup_show == 2) /* == "Always" */ @@ -282,11 +325,11 @@ static void do_resize() return; /* see if it is actually going to resize */ - x = moveresize_client->area.x; - y = moveresize_client->area.y; + x = 0; + y = 0; w = cur_x; h = cur_y; - client_try_configure(moveresize_client, lockcorner, &x, &y, &w, &h, + client_try_configure(moveresize_client, &x, &y, &w, &h, &lw, &lh, TRUE); if (w == moveresize_client->area.width && h == moveresize_client->area.height) @@ -316,9 +359,11 @@ static void do_resize() } #endif - client_configure(moveresize_client, lockcorner, - moveresize_client->area.x, moveresize_client->area.y, - cur_x, cur_y, TRUE, FALSE); + { + gint x, y; + get_resize_position(&x, &y, FALSE); + client_configure(moveresize_client, x, y, cur_x, cur_y, TRUE, FALSE); + } /* this would be better with a fixed width font ... XXX can do it better if there are 2 text boxes */ diff --git a/openbox/place.c b/openbox/place.c index 74aa7605..1ac295c0 100644 --- a/openbox/place.c +++ b/openbox/place.c @@ -489,6 +489,7 @@ gboolean place_client(ObClient *client, gint *x, gint *y, place_random(client, x, y)))) g_assert_not_reached(); /* the last one better succeed */ /* get where the client should be */ - frame_frame_gravity(client->frame, x, y); + frame_frame_gravity(client->frame, x, y, + client->area.width, client->area.height); return ret; } -- 2.39.2