wl_desktop_shell: Fix issue of misplaced menus in client apps

The code used to position client application popup menus did not
account for other anchor positions and gravity values thus causing
menus to popup outside the client application. This patch fixes the
issue by accounting for the missing cases.

ref T7479
This commit is contained in:
Christopher Michael 2019-05-30 10:56:08 -04:00
parent a8deae5ed6
commit ed6f7b2903
2 changed files with 135 additions and 64 deletions

View File

@ -693,22 +693,40 @@ _apply_positioner_x(int x, Positioner *p, Eina_Bool invert)
grav = p->gravity;
}
/* left edge */
if (an == XDG_POSITIONER_ANCHOR_LEFT)
switch (an)
{
case XDG_POSITIONER_ANCHOR_LEFT:
case XDG_POSITIONER_ANCHOR_TOP_LEFT:
case XDG_POSITIONER_ANCHOR_BOTTOM_LEFT:
x += p->anchor_rect.x;
/* right edge */
else if (an == XDG_POSITIONER_ANCHOR_RIGHT)
break;
case XDG_POSITIONER_ANCHOR_RIGHT:
case XDG_POSITIONER_ANCHOR_TOP_RIGHT:
case XDG_POSITIONER_ANCHOR_BOTTOM_RIGHT:
x += p->anchor_rect.x + p->anchor_rect.w;
/* center */
else
break;
default:
x += p->anchor_rect.x + (p->anchor_rect.w / 2);
break;
}
/* flip left over anchor */
if (grav & XDG_POSITIONER_GRAVITY_LEFT)
switch (grav)
{
case XDG_POSITIONER_GRAVITY_LEFT:
case XDG_POSITIONER_GRAVITY_TOP_LEFT:
case XDG_POSITIONER_GRAVITY_BOTTOM_LEFT:
x -= p->size.w;
/* center on anchor */
else if (!(grav & XDG_POSITIONER_GRAVITY_RIGHT))
break;
case XDG_POSITIONER_GRAVITY_RIGHT:
case XDG_POSITIONER_GRAVITY_TOP_RIGHT:
case XDG_POSITIONER_GRAVITY_BOTTOM_RIGHT:
x = x;
break;
default:
x -= p->size.w / 2;
break;
}
return x;
}
@ -735,22 +753,39 @@ _apply_positioner_y(int y, Positioner *p, Eina_Bool invert)
grav = p->gravity;
}
/* up edge */
if (an == XDG_POSITIONER_ANCHOR_TOP)
switch (an)
{
case XDG_POSITIONER_ANCHOR_TOP:
case XDG_POSITIONER_ANCHOR_TOP_LEFT:
case XDG_POSITIONER_ANCHOR_TOP_RIGHT:
y += p->anchor_rect.y;
/* bottom edge */
else if (an == XDG_POSITIONER_ANCHOR_BOTTOM)
break;
case XDG_POSITIONER_ANCHOR_BOTTOM:
case XDG_POSITIONER_ANCHOR_BOTTOM_LEFT:
case XDG_POSITIONER_ANCHOR_BOTTOM_RIGHT:
y += p->anchor_rect.y + p->anchor_rect.h;
/* center */
else
break;
default:
y += p->anchor_rect.y + (p->anchor_rect.h / 2);
break;
}
/* flip up over anchor */
if (grav & XDG_POSITIONER_GRAVITY_TOP)
switch (grav)
{
case XDG_POSITIONER_GRAVITY_TOP:
case XDG_POSITIONER_GRAVITY_TOP_LEFT:
case XDG_POSITIONER_GRAVITY_TOP_RIGHT:
y -= p->size.h;
/* center on anchor */
else if (!(grav & XDG_POSITIONER_GRAVITY_BOTTOM))
y -= p->size.h / 2;
break;
case XDG_POSITIONER_GRAVITY_BOTTOM:
case XDG_POSITIONER_GRAVITY_BOTTOM_LEFT:
case XDG_POSITIONER_GRAVITY_BOTTOM_RIGHT:
y = y;
break;
default:
y -= (p->size.h / 2);
}
return y;
}
@ -810,6 +845,7 @@ _apply_positioner(E_Client *ec, Positioner *p)
{
int x, y;
int zx, zy, zw, zh;
/* apply base geometry:
* coords are relative to parent
*/
@ -827,8 +863,8 @@ _apply_positioner(E_Client *ec, Positioner *p)
- gravity (perform flips if gravity is not right|bottom)
- constrain (adjust if popup does not fit)
*/
ec->x = _apply_positioner_x(ec->x, p, 0);
ec->y = _apply_positioner_y(ec->y, p, 0);
ec->x = _apply_positioner_x(x, p, 0);
ec->y = _apply_positioner_y(y, p, 0);
e_zone_useful_geometry_get(ec->parent->zone, &zx, &zy, &zw, &zh);

View File

@ -675,22 +675,40 @@ _apply_positioner_x(int x, Positioner *p, Eina_Bool invert)
grav = p->gravity;
}
/* left edge */
if (an & ZXDG_POSITIONER_V6_ANCHOR_LEFT)
switch (an)
{
case XDG_POSITIONER_ANCHOR_LEFT:
case XDG_POSITIONER_ANCHOR_TOP_LEFT:
case XDG_POSITIONER_ANCHOR_BOTTOM_LEFT:
x += p->anchor_rect.x;
/* right edge */
else if (an & ZXDG_POSITIONER_V6_ANCHOR_RIGHT)
break;
case XDG_POSITIONER_ANCHOR_RIGHT:
case XDG_POSITIONER_ANCHOR_TOP_RIGHT:
case XDG_POSITIONER_ANCHOR_BOTTOM_RIGHT:
x += p->anchor_rect.x + p->anchor_rect.w;
/* center */
else
break;
default:
x += p->anchor_rect.x + (p->anchor_rect.w / 2);
break;
}
/* flip left over anchor */
if (grav & ZXDG_POSITIONER_V6_GRAVITY_LEFT)
switch (grav)
{
case XDG_POSITIONER_GRAVITY_LEFT:
case XDG_POSITIONER_GRAVITY_TOP_LEFT:
case XDG_POSITIONER_GRAVITY_BOTTOM_LEFT:
x -= p->size.w;
/* center on anchor */
else if (!(grav & ZXDG_POSITIONER_V6_GRAVITY_RIGHT))
break;
case XDG_POSITIONER_GRAVITY_RIGHT:
case XDG_POSITIONER_GRAVITY_TOP_RIGHT:
case XDG_POSITIONER_GRAVITY_BOTTOM_RIGHT:
x = x;
break;
default:
x -= p->size.w / 2;
break;
}
return x;
}
@ -717,22 +735,39 @@ _apply_positioner_y(int y, Positioner *p, Eina_Bool invert)
grav = p->gravity;
}
/* up edge */
if (an & ZXDG_POSITIONER_V6_ANCHOR_TOP)
switch (an)
{
case XDG_POSITIONER_ANCHOR_TOP:
case XDG_POSITIONER_ANCHOR_TOP_LEFT:
case XDG_POSITIONER_ANCHOR_TOP_RIGHT:
y += p->anchor_rect.y;
/* bottom edge */
else if (an & ZXDG_POSITIONER_V6_ANCHOR_BOTTOM)
break;
case XDG_POSITIONER_ANCHOR_BOTTOM:
case XDG_POSITIONER_ANCHOR_BOTTOM_LEFT:
case XDG_POSITIONER_ANCHOR_BOTTOM_RIGHT:
y += p->anchor_rect.y + p->anchor_rect.h;
/* center */
else
break;
default:
y += p->anchor_rect.y + (p->anchor_rect.h / 2);
break;
}
/* flip up over anchor */
if (grav & ZXDG_POSITIONER_V6_GRAVITY_TOP)
switch (grav)
{
case XDG_POSITIONER_GRAVITY_TOP:
case XDG_POSITIONER_GRAVITY_TOP_LEFT:
case XDG_POSITIONER_GRAVITY_TOP_RIGHT:
y -= p->size.h;
/* center on anchor */
else if (!(grav & ZXDG_POSITIONER_V6_GRAVITY_BOTTOM))
y -= p->size.h / 2;
break;
case XDG_POSITIONER_GRAVITY_BOTTOM:
case XDG_POSITIONER_GRAVITY_BOTTOM_LEFT:
case XDG_POSITIONER_GRAVITY_BOTTOM_RIGHT:
y = y;
break;
default:
y -= (p->size.h / 2);
}
return y;
}
@ -809,8 +844,8 @@ _apply_positioner(E_Client *ec, Positioner *p)
- gravity (perform flips if gravity is not right|bottom)
- constrain (adjust if popup does not fit)
*/
ec->x = _apply_positioner_x(ec->x, p, 0);
ec->y = _apply_positioner_y(ec->y, p, 0);
ec->x = _apply_positioner_x(x, p, 0);
ec->y = _apply_positioner_y(y, p, 0);
e_zone_useful_geometry_get(ec->parent->zone, &zx, &zy, &zw, &zh);