yay! gravity finally works right!

This commit is contained in:
Dana Jansens 2007-05-23 15:16:13 +00:00
parent 459449c7e1
commit 2fb7a6e478
5 changed files with 120 additions and 50 deletions

View file

@ -1538,7 +1538,6 @@ void client_update_normal_hints(ObClient *self)
{
XSizeHints size;
glong ret;
gint oldgravity = self->gravity;
/* defaults */
self->min_ratio = 0.0f;
@ -1555,19 +1554,8 @@ void client_update_normal_hints(ObClient *self)
*/
self->positioned = (size.flags & (PPosition|USPosition));
if (size.flags & PWinGravity) {
if (size.flags & PWinGravity)
self->gravity = size.win_gravity;
/* if the client has a frame, i.e. has already been mapped and
is changing its gravity */
if (self->frame && self->gravity != oldgravity) {
/* move our idea of the client's position based on its new
gravity */
client_convert_gravity(self, oldgravity,
&self->area.x, &self->area.y,
self->area.width, self->area.height);
}
}
if (size.flags & PAspect) {
if (size.min_aspect.y)
@ -2566,18 +2554,62 @@ static void client_apply_startup_state(ObClient *self)
*/
}
void client_convert_gravity(ObClient *self, gint gravity, gint *x, gint *y,
gint w, gint h)
void client_gravity_resize_w(ObClient *self, gint *x, gint oldw, gint neww)
{
gint oldg = self->gravity;
/* these should be the current values. this is for when you're not moving,
just resizing */
g_assert(*x == self->area.x);
g_assert(oldw == self->area.width);
/* get the frame's position from the requested stuff */
self->gravity = gravity;
frame_client_gravity(self->frame, x, y, w, h);
self->gravity = oldg;
/* horizontal */
switch (self->gravity) {
default:
case NorthWestGravity:
case WestGravity:
case SouthWestGravity:
case StaticGravity:
case ForgetGravity:
break;
case NorthGravity:
case CenterGravity:
case SouthGravity:
*x -= (neww - oldw) / 2;
break;
case NorthEastGravity:
case EastGravity:
case SouthEastGravity:
*x -= neww - oldw;
break;
}
}
/* get the client's position in its true gravity from that */
frame_frame_gravity(self->frame, x, y, w, h);
void client_gravity_resize_h(ObClient *self, gint *y, gint oldh, gint newh)
{
/* these should be the current values. this is for when you're not moving,
just resizing */
g_assert(*y == self->area.y);
g_assert(oldh == self->area.height);
/* vertical */
switch (self->gravity) {
default:
case NorthWestGravity:
case NorthGravity:
case NorthEastGravity:
case StaticGravity:
case ForgetGravity:
break;
case WestGravity:
case CenterGravity:
case EastGravity:
*y -= (newh - oldh) / 2;
break;
case SouthWestGravity:
case SouthGravity:
case SouthEastGravity:
*y -= newh - oldh;
break;
}
}
void client_try_configure(ObClient *self, gint *x, gint *y, gint *w, gint *h,

View file

@ -362,10 +362,24 @@ gboolean client_enter_focusable(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
/*! When the client is resized but not moved, figure out the new position
for it based on its gravity:
http://standards.freedesktop.org/wm-spec/wm-spec-1.4.html#id2512541
*/
void client_gravity_resize_w(ObClient *self, gint *x, gint oldw, gint neww);
/*! When the client is resized but not moved, figure out the new position
for it based on its gravity:
http://standards.freedesktop.org/wm-spec/wm-spec-1.4.html#id2512541
*/
void client_gravity_resize_h(ObClient *self, gint *y, gint oldh, gint newh);
/*! Convert a position/size from a given gravity to the client's true gravity,
when the client is only resizing (the reference point doesn't move)
*/
void client_convert_gravity(ObClient *self, gint gravity, gint *x, gint *y,
gint w, gint h);
void client_convert_gravity_resize(ObClient *self, gint gravity,
gint *x, gint *y,
gint w, gint h);
#define client_move(self, x, y) \
client_configure(self, x, y, self->area.width, self->area.height, TRUE, TRUE)

View file

@ -1035,38 +1035,43 @@ static void event_handle_client(ObClient *client, XEvent *e)
move = TRUE;
}
/* don't allow clients to move shaded windows (fvwm does this) */
if (client->shaded && (e->xconfigurerequest.value_mask & CWX ||
e->xconfigurerequest.value_mask & CWY))
{
e->xconfigurerequest.value_mask &= ~CWX;
e->xconfigurerequest.value_mask &= ~CWY;
/* if the client tried to move and we aren't letting it then a
synthetic event is needed */
move = TRUE;
}
if (e->xconfigurerequest.value_mask & CWX ||
e->xconfigurerequest.value_mask & CWY ||
e->xconfigurerequest.value_mask & CWWidth ||
e->xconfigurerequest.value_mask & CWHeight)
{
if (e->xconfigurerequest.value_mask & CWX) {
x = e->xconfigurerequest.x;
/* don't allow clients to move shaded windows (fvwm does this)
*/
if (!client->shaded)
x = e->xconfigurerequest.x;
move = TRUE;
}
if (e->xconfigurerequest.value_mask & CWY) {
y = e->xconfigurerequest.y;
/* don't allow clients to move shaded windows (fvwm does this)
*/
if (!client->shaded)
y = e->xconfigurerequest.y;
move = TRUE;
}
if (e->xconfigurerequest.value_mask & CWWidth) {
w = e->xconfigurerequest.width;
resize = TRUE;
/* if x was not given, then use gravity to figure out the new
x. the reference point should not be moved */
if (!(e->xconfigurerequest.value_mask & CWX))
client_gravity_resize_w(client, &x, client->area.width, w);
}
if (e->xconfigurerequest.value_mask & CWHeight) {
h = e->xconfigurerequest.height;
resize = TRUE;
/* if y was not given, then use gravity to figure out the new
y. the reference point should not be moved */
if (!(e->xconfigurerequest.value_mask & CWY))
client_gravity_resize_h(client, &y, client->area.height,h);
}
}
@ -1276,12 +1281,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 grav, x, y, w, h;
gint ograv, x, y, w, h;
ograv = client->gravity;
if (e->xclient.data.l[0] & 0xff)
grav = e->xclient.data.l[0] & 0xff;
else
grav = client->gravity;
client->gravity = e->xclient.data.l[0] & 0xff;
if (e->xclient.data.l[0] & 1 << 8)
x = e->xclient.data.l[1];
@ -1291,23 +1296,40 @@ static void event_handle_client(ObClient *client, XEvent *e)
y = e->xclient.data.l[2];
else
y = client->area.y;
if (e->xclient.data.l[0] & 1 << 10)
if (e->xclient.data.l[0] & 1 << 10) {
w = e->xclient.data.l[3];
/* if x was not given, then use gravity to figure out the new
x. the reference point should not be moved */
if (!(e->xclient.data.l[0] & 1 << 8))
client_gravity_resize_w(client, &x, client->area.width, w);
}
else
w = client->area.width;
if (e->xclient.data.l[0] & 1 << 11)
if (e->xclient.data.l[0] & 1 << 11) {
h = e->xclient.data.l[4];
/* if y was not given, then use gravity to figure out the new
y. the reference point should not be moved */
if (!(e->xclient.data.l[0] & 1 << 9))
client_gravity_resize_h(client, &y, client->area.height,h);
}
else
h = client->area.height;
ob_debug("MOVERESIZE x %d %d y %d %d\n",
ob_debug("MOVERESIZE x %d %d y %d %d (gravity %d)\n",
e->xclient.data.l[0] & 1 << 8, x,
e->xclient.data.l[0] & 1 << 9, y);
client_convert_gravity(client, grav, &x, &y, w, h);
e->xclient.data.l[0] & 1 << 9, y,
client->gravity);
client_find_onscreen(client, &x, &y, w, h, FALSE);
client_configure(client, x, y, w, h, FALSE, TRUE);
client->gravity = ograv;
/* ignore enter events caused by these like ob actions do */
event_ignore_all_queued_enters();
} else if (msgtype == prop_atoms.net_restack_window) {

View file

@ -1386,7 +1386,7 @@ void frame_frame_gravity(ObFrame *self, gint *x, gint *y, gint w, gint h)
case StaticGravity:
case ForgetGravity:
/* the client's position won't move */
*x -= self->size.left;
*x += self->size.left;
break;
}

View file

@ -50,7 +50,9 @@ int main () {
XFlush(display);
XMoveResizeWindow(display, win, 1172-600, 668-150, 600, 150);
/*XResizeWindow(display, win, 600, 150);*/
XFlush(display);
sleep(1);
XResizeWindow(display, win, 900, 275);
XSelectInput(display, win, ExposureMask | StructureNotifyMask);