libweston: Add weston_view_set_position_with_offset

There are many times when we want to set a global position with a surface
offset added.

It's a fairly nasty operation, and most places in the code currently do
it naively, ignoring the painful existence of freeform window rotations
and other complex transforms that could be in play (but probably aren't)

Add a helper for this and convert existing usage.

Signed-off-by: Derek Foreman <derek.foreman@collabora.com>
This commit is contained in:
Derek Foreman 2023-08-02 11:38:30 -05:00 committed by Marius Vlad
parent 49ccd7f786
commit 8eed64c7df
6 changed files with 76 additions and 52 deletions

View file

@ -2263,28 +2263,31 @@ set_maximized_position(struct desktop_shell *shell,
pixman_rectangle32_t area;
struct weston_geometry geometry;
struct weston_coord_global pos;
struct weston_coord_surface offset;
get_output_work_area(shell, shsurf->output, &area);
geometry = weston_desktop_surface_get_geometry(shsurf->desktop_surface);
pos.c = weston_coord(area.x - geometry.x,
area.y - geometry.y);
weston_view_set_position(shsurf->view, pos);
pos.c = weston_coord(area.x, area.y);
offset = weston_coord_surface(-geometry.x, -geometry.y, shsurf->view->surface);
weston_view_set_position_with_offset(shsurf->view, pos, offset);
}
static void
set_position_from_xwayland(struct shell_surface *shsurf)
{
struct weston_geometry geometry;
struct weston_coord_global pos;
struct weston_coord_surface offs;
assert(shsurf->xwayland.is_set);
geometry = weston_desktop_surface_get_geometry(shsurf->desktop_surface);
pos.c = weston_coord(geometry.x, geometry.y);
pos.c = weston_coord_sub(shsurf->xwayland.pos.c, pos.c);
offs = weston_coord_surface(-geometry.x, -geometry.y,
shsurf->view->surface);
weston_view_set_position(shsurf->view, pos);
weston_view_set_position_with_offset(shsurf->view,
shsurf->xwayland.pos,
offs);
#ifdef WM_DEBUG
weston_log("%s: XWM %d, %d; geometry %d, %d; view %f, %f\n",
@ -2429,11 +2432,8 @@ desktop_surface_committed(struct weston_desktop_surface *desktop_surface,
set_maximized_position(shell, shsurf);
surface->output = shsurf->output;
} else {
struct weston_coord_surface from_s, to_s;
struct weston_coord_global to_g, from_g;
struct weston_coord_global offset, pos;
from_s = weston_coord_surface(0, 0, view->surface);
struct weston_coord_surface offset;
struct weston_coord_global pos;
if (shsurf->resize_edges) {
sx = 0;
@ -2445,17 +2445,10 @@ desktop_surface_committed(struct weston_desktop_surface *desktop_surface,
if (shsurf->resize_edges & WESTON_DESKTOP_SURFACE_EDGE_TOP)
sy = shsurf->last_height - surface->height;
to_s = weston_coord_surface(sx, sy, view->surface);
offset = weston_coord_surface(sx, sy, view->surface);
from_g = weston_coord_surface_to_global(view, from_s);
to_g = weston_coord_surface_to_global(view, to_s);
offset = weston_coord_global_sub(to_g, from_g);
pos = weston_coord_global_add(
weston_view_get_pos_offset_global(view),
offset);
weston_view_set_position(shsurf->view, pos);
pos = weston_view_get_pos_offset_global(view);
weston_view_set_position_with_offset(shsurf->view, pos, offset);
}
shsurf->last_width = surface->width;

View file

@ -2208,6 +2208,11 @@ void
weston_view_set_position(struct weston_view *view,
struct weston_coord_global pos);
void
weston_view_set_position_with_offset(struct weston_view *view,
struct weston_coord_global pos,
struct weston_coord_surface offset);
struct weston_coord_surface
weston_view_get_pos_offset_rel(struct weston_view *view);

View file

@ -1820,6 +1820,32 @@ weston_view_set_position(struct weston_view *view,
weston_view_geometry_dirty(view);
}
WL_EXPORT void
weston_view_set_position_with_offset(struct weston_view *view,
struct weston_coord_global pos,
struct weston_coord_surface offset)
{
struct weston_coord_global global_offset;
struct weston_coord_surface origin_s;
struct weston_coord_global origin_g, newpos;
assert(view->surface->committed != subsurface_committed);
assert(!view->geometry.parent);
/* We need up to date transform matrices */
weston_view_set_position(view, pos);
weston_view_update_transform(view);
origin_s = weston_coord_surface(0, 0, view->surface);
origin_g = weston_coord_surface_to_global(view, origin_s);
global_offset = weston_coord_surface_to_global(view, offset);
global_offset = weston_coord_global_sub(global_offset, origin_g);
newpos = weston_coord_global_add(weston_view_get_pos_offset_global(view),
global_offset);
weston_view_set_position(view, newpos);
}
WL_EXPORT struct weston_coord_surface
weston_view_get_pos_offset_rel(struct weston_view *view)
{

View file

@ -446,8 +446,7 @@ drag_surface_configure(struct weston_drag *drag,
else if (touch)
pos = touch->grab_pos;
pos.c = weston_coord_add(pos.c, drag->offset.c);
weston_view_set_position(drag->icon, pos);
weston_view_set_position_with_offset(drag->icon, pos, drag->offset);
}
static int
@ -621,10 +620,9 @@ drag_grab_motion(struct weston_pointer_grab *grab,
weston_pointer_move(pointer, event);
if (drag->base.icon) {
struct weston_coord_global pos;
pos.c = weston_coord_add(pointer->pos.c, drag->base.offset.c);
weston_view_set_position(drag->base.icon, pos);
weston_view_set_position_with_offset(drag->base.icon,
pointer->pos,
drag->base.offset);
}
if (drag->base.focus_resource) {
@ -814,13 +812,10 @@ drag_grab_touch_motion(struct weston_touch_grab *grab,
return;
drag_grab_touch_focus(touch_drag);
if (touch_drag->base.icon) {
struct weston_coord_global pos;
pos.c = weston_coord_add(touch_drag->base.offset.c,
touch->grab_pos.c);
weston_view_set_position(touch_drag->base.icon, pos);
}
if (touch_drag->base.icon)
weston_view_set_position_with_offset(touch_drag->base.icon,
touch->grab_pos,
touch_drag->base.offset);
if (touch_drag->base.focus_resource) {
struct weston_coord_surface surf_pos;

View file

@ -1863,10 +1863,11 @@ weston_tablet_tool_cursor_move(struct weston_tablet_tool *tool,
tool->pos = pos;
if (tool->sprite) {
struct weston_coord_global hotspot;
struct weston_coord_surface hotspot_inv;
hotspot.c = weston_coord_sub(pos.c, tool->hotspot.c);
weston_view_set_position(tool->sprite, hotspot);
hotspot_inv = weston_coord_surface_invert(tool->hotspot);
weston_view_set_position_with_offset(tool->sprite,
pos, hotspot_inv);
}
}
@ -2197,9 +2198,11 @@ weston_pointer_move_to(struct weston_pointer *pointer,
pointer->pos = pos;
if (pointer->sprite) {
pos.c = weston_coord_sub(pointer->pos.c,
pointer->hotspot.c);
weston_view_set_position(pointer->sprite, pos);
struct weston_coord_surface hotspot_inv;
hotspot_inv = weston_coord_surface_invert(pointer->hotspot);
weston_view_set_position_with_offset(pointer->sprite,
pos, hotspot_inv);
}
pointer->grab->interface->focus(pointer->grab);
@ -3231,7 +3234,7 @@ tablet_tool_cursor_surface_committed(struct weston_surface *es,
struct weston_coord_surface new_origin)
{
struct weston_tablet_tool *tool = es->committed_private;
struct weston_coord_global pos;
struct weston_coord_surface hotspot_inv;
if (es->width == 0)
return;
@ -3239,9 +3242,9 @@ tablet_tool_cursor_surface_committed(struct weston_surface *es,
assert(es == tool->sprite->surface);
tool->hotspot.c = weston_coord_sub(tool->hotspot.c, new_origin.c);
pos.c = weston_coord_sub(tool->pos.c, tool->hotspot.c);
weston_view_set_position(tool->sprite, pos);
hotspot_inv = weston_coord_surface_invert(tool->hotspot);
weston_view_set_position_with_offset(tool->sprite,
tool->pos, hotspot_inv);
empty_region(&es->pending.input);
empty_region(&es->input);
@ -3526,7 +3529,7 @@ pointer_cursor_surface_committed(struct weston_surface *es,
struct weston_coord_surface new_origin)
{
struct weston_pointer *pointer = es->committed_private;
struct weston_coord_global pos;
struct weston_coord_surface hotspot_inv;
if (es->width == 0)
return;
@ -3535,9 +3538,9 @@ pointer_cursor_surface_committed(struct weston_surface *es,
pointer->hotspot.c = weston_coord_sub(pointer->hotspot.c,
new_origin.c);
pos.c = weston_coord_sub(pointer->pos.c, pointer->hotspot.c);
weston_view_set_position(pointer->sprite, pos);
hotspot_inv = weston_coord_surface_invert(pointer->hotspot);
weston_view_set_position_with_offset(pointer->sprite,
pointer->pos, hotspot_inv);
empty_region(&es->pending.input);
empty_region(&es->input);

View file

@ -88,6 +88,7 @@ desktop_surface_committed(struct weston_desktop_surface *desktop_surface,
struct weston_geometry geometry =
weston_desktop_surface_get_geometry(desktop_surface);
struct weston_coord_global pos;
struct weston_coord_surface offset;
assert(dts->view);
@ -96,9 +97,10 @@ desktop_surface_committed(struct weston_desktop_surface *desktop_surface,
weston_surface_map(surface);
pos.c = weston_coord(0, 0);
pos.c.x -= geometry.x;
pos.c.y -= geometry.y;
weston_view_set_position(dts->view, pos);
offset = weston_coord_surface(geometry.x, geometry.y,
dts->view->surface);
offset = weston_coord_surface_invert(offset);
weston_view_set_position_with_offset(dts->view, pos, offset);
weston_layer_entry_insert(&dts->layer.view_list, &dts->view->layer_link);
weston_view_move_to_layer(dts->view, &dts->layer.view_list);
}