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);
}
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);
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);
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
}
}
- 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;
}
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);
}
}
/* 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);
}
*/
}
-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)
{
}
/* 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 */
}
/* 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) {
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)
{
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))
(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)
}
/* 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);
}
* 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 */
}
/* 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.
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.
@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);
CWX | CWY |
CWBorderWidth)) {
gint x, y, w, h;
- ObCorner corner;
if (e->xconfigurerequest.value_mask & CWBorderWidth)
client->border_width = e->xconfigurerequest.border_width;
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) {
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];
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:
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);
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) {
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);
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) {
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:
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:
}
}
-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) {
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:
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:
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);
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);
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;
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
void moveresize_end(gboolean cancel)
{
+ gint x, y;
+
grab_keyboard(FALSE);
grab_pointer(FALSE, FALSE, OB_CURSOR_NONE);
}
#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);
}
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" */
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)
}
#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 */
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;
}