compositor: Implement runtime output transform changes
Up to now we could set the transform only on output initialization. However, on certain situations(like tablets and convertible laptops), screen orientation can change while the compositor is running and thus the need for change of the output transform arises. When the transform changes, we must update the output geometry, output->region and output->previous_damage, as well as send this change to clients. We also have to check whether any of the pointers are inside the output which is being rotated. If this is the case, they are moved to the new center, because otherwise the pointer is stuck outside of the screen ans "lost" to the user. What is more, after calling this function compositors should check if any view is now outside of the screen and move it according to their wish. Signed-off-by: Ilia Bozhinov <iliyabo@hotmail.com> Reviewed-by: Derek Foreman <derekf@osg.samsung.com> Acked-by: Daniel Stone <daniels@collabora.com>
This commit is contained in:
parent
543d0a0bb6
commit
8564a0d109
@ -4679,9 +4679,6 @@ weston_output_set_scale(struct weston_output *output,
|
||||
* \param output The weston_output object that the transform is set for.
|
||||
* \param transform Transform value for the given output.
|
||||
*
|
||||
* It only supports setting transform for an output that is
|
||||
* not enabled and it can only be ran once.
|
||||
*
|
||||
* Refer to wl_output::transform section located at
|
||||
* https://wayland.freedesktop.org/docs/html/apa.html#protocol-spec-wl_output
|
||||
* for list of values that can be passed to this function.
|
||||
@ -4692,13 +4689,62 @@ WL_EXPORT void
|
||||
weston_output_set_transform(struct weston_output *output,
|
||||
uint32_t transform)
|
||||
{
|
||||
/* We can only set transform on a disabled output */
|
||||
assert(!output->enabled);
|
||||
struct weston_pointer_motion_event ev;
|
||||
struct wl_resource *resource;
|
||||
struct weston_seat *seat;
|
||||
pixman_region32_t old_region;
|
||||
int mid_x, mid_y;
|
||||
|
||||
/* We only want to set transform once */
|
||||
assert(output->transform == UINT32_MAX);
|
||||
if (!output->enabled && output->transform == UINT32_MAX) {
|
||||
output->transform = transform;
|
||||
return;
|
||||
}
|
||||
|
||||
output->transform = transform;
|
||||
weston_output_transform_scale_init(output, transform, output->scale);
|
||||
|
||||
pixman_region32_init(&old_region);
|
||||
pixman_region32_copy(&old_region, &output->region);
|
||||
|
||||
pixman_region32_fini(&output->region);
|
||||
pixman_region32_fini(&output->previous_damage);
|
||||
|
||||
weston_output_init_geometry(output, output->x, output->y);
|
||||
|
||||
output->dirty = 1;
|
||||
|
||||
/* Notify clients of the change for output transform. */
|
||||
wl_resource_for_each(resource, &output->resource_list) {
|
||||
wl_output_send_geometry(resource,
|
||||
output->x,
|
||||
output->y,
|
||||
output->mm_width,
|
||||
output->mm_height,
|
||||
output->subpixel,
|
||||
output->make,
|
||||
output->model,
|
||||
output->transform);
|
||||
|
||||
if (wl_resource_get_version(resource) >= WL_OUTPUT_DONE_SINCE_VERSION)
|
||||
wl_output_send_done(resource);
|
||||
}
|
||||
|
||||
/* we must ensure that pointers are inside output, otherwise they disappear */
|
||||
mid_x = output->x + output->width / 2;
|
||||
mid_y = output->y + output->height / 2;
|
||||
|
||||
ev.mask = WESTON_POINTER_MOTION_ABS;
|
||||
ev.x = wl_fixed_to_double(wl_fixed_from_int(mid_x));
|
||||
ev.y = wl_fixed_to_double(wl_fixed_from_int(mid_y));
|
||||
|
||||
wl_list_for_each(seat, &output->compositor->seat_list, link) {
|
||||
struct weston_pointer *pointer = weston_seat_get_pointer(seat);
|
||||
|
||||
if (pointer && pixman_region32_contains_point(&old_region,
|
||||
wl_fixed_to_int(pointer->x),
|
||||
wl_fixed_to_int(pointer->y),
|
||||
NULL))
|
||||
weston_pointer_move(pointer, &ev);
|
||||
}
|
||||
}
|
||||
|
||||
/** Initializes a weston_output object with enough data so
|
||||
|
Loading…
Reference in New Issue
Block a user