From 727e64dddffb8f1b4eadc8d91f3a7d4f59f379d0 Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Thu, 16 Jul 2020 16:41:02 +0200 Subject: [PATCH] backends: Use MetaViewportInfo to keep MetaSeatNative informed of layout Use this for the calculations to keep absolute motion properly constrained, and relative motion properly scaled. Part-of: --- src/backends/native/meta-backend-native.c | 29 +++++- src/backends/native/meta-seat-native.c | 114 ++++++++++++---------- src/backends/native/meta-seat-native.h | 6 ++ 3 files changed, 93 insertions(+), 56 deletions(-) diff --git a/src/backends/native/meta-backend-native.c b/src/backends/native/meta-backend-native.c index 5eeb14463..8ecc24e2a 100644 --- a/src/backends/native/meta-backend-native.c +++ b/src/backends/native/meta-backend-native.c @@ -145,6 +145,21 @@ maybe_disable_screen_cast_dma_bufs (MetaBackendNative *native) } #endif /* HAVE_REMOTE_DESKTOP */ +static void +update_viewports (MetaBackend *backend) +{ + MetaMonitorManager *monitor_manager = + meta_backend_get_monitor_manager (backend); + ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend); + MetaSeatNative *seat = + META_SEAT_NATIVE (clutter_backend_get_default_seat (clutter_backend)); + MetaViewportInfo *viewports; + + viewports = meta_monitor_manager_get_viewports (monitor_manager); + meta_seat_native_set_viewports (seat, viewports); + g_object_unref (viewports); +} + static void meta_backend_native_post_init (MetaBackend *backend) { @@ -170,6 +185,8 @@ meta_backend_native_post_init (MetaBackend *backend) maybe_disable_screen_cast_dma_bufs (META_BACKEND_NATIVE (backend)); #endif + update_viewports (backend); + #ifdef HAVE_WAYLAND meta_backend_init_wayland (backend); #endif @@ -179,9 +196,15 @@ static MetaMonitorManager * meta_backend_native_create_monitor_manager (MetaBackend *backend, GError **error) { - return g_initable_new (META_TYPE_MONITOR_MANAGER_KMS, NULL, error, - "backend", backend, - NULL); + MetaMonitorManager *manager; + + manager = g_initable_new (META_TYPE_MONITOR_MANAGER_KMS, NULL, error, + "backend", backend, + NULL); + g_signal_connect_swapped (manager, "monitors-changed-internal", + G_CALLBACK (update_viewports), backend); + + return manager; } static MetaCursorRenderer * diff --git a/src/backends/native/meta-seat-native.c b/src/backends/native/meta-seat-native.c index 45da429dc..93c15318f 100644 --- a/src/backends/native/meta-seat-native.c +++ b/src/backends/native/meta-seat-native.c @@ -877,29 +877,31 @@ constrain_to_barriers (MetaSeatNative *seat, static void constrain_all_screen_monitors (ClutterInputDevice *device, - MetaMonitorManager *monitor_manager, + MetaViewportInfo *viewports, float *x, float *y) { float cx, cy; - GList *logical_monitors, *l; + int i, n_views; meta_input_device_native_get_coords (META_INPUT_DEVICE_NATIVE (device), &cx, &cy); /* if we're trying to escape, clamp to the CRTC we're coming from */ - logical_monitors = - meta_monitor_manager_get_logical_monitors (monitor_manager); - for (l = logical_monitors; l; l = l->next) - { - MetaLogicalMonitor *logical_monitor = l->data; - int left, right, top, bottom; + n_views = meta_viewport_info_get_num_views (viewports); - left = logical_monitor->rect.x; - right = left + logical_monitor->rect.width; - top = logical_monitor->rect.y; - bottom = top + logical_monitor->rect.height; + for (i = 0; i < n_views; i++) + { + int left, right, top, bottom; + cairo_rectangle_int_t rect; + + meta_viewport_info_get_view_info (viewports, i, &rect, NULL); + + left = rect.x; + right = left + rect.width; + top = rect.y; + bottom = top + rect.height; if ((cx >= left) && (cx < right) && (cy >= top) && (cy < bottom)) { @@ -926,10 +928,6 @@ meta_seat_native_constrain_pointer (MetaSeatNative *seat, float *new_x, float *new_y) { - MetaBackend *backend = meta_get_backend (); - MetaMonitorManager *monitor_manager = - meta_backend_get_monitor_manager (backend); - constrain_to_barriers (seat, core_pointer, us2ms (time_us), new_x, new_y); @@ -944,53 +942,59 @@ meta_seat_native_constrain_pointer (MetaSeatNative *seat, new_x, new_y); } - /* if we're moving inside a monitor, we're fine */ - if (meta_monitor_manager_get_logical_monitor_at (monitor_manager, - *new_x, *new_y)) - return; + if (seat->viewports) + { + /* if we're moving inside a monitor, we're fine */ + if (meta_viewport_info_get_view_at (seat->viewports, *new_x, *new_y) >= 0) + return; - /* if we're trying to escape, clamp to the CRTC we're coming from */ - constrain_all_screen_monitors (core_pointer, monitor_manager, new_x, new_y); + /* if we're trying to escape, clamp to the CRTC we're coming from */ + constrain_all_screen_monitors (core_pointer, seat->viewports, new_x, new_y); + } } static void -relative_motion_across_outputs (MetaMonitorManager *monitor_manager, - MetaLogicalMonitor *current, +relative_motion_across_outputs (MetaViewportInfo *viewports, + int view, float cur_x, float cur_y, float *dx_inout, float *dy_inout) { - MetaLogicalMonitor *cur = current; + int cur_view = view; float x = cur_x, y = cur_y; float target_x = cur_x, target_y = cur_y; float dx = *dx_inout, dy = *dy_inout; MetaDisplayDirection direction = -1; - while (cur) + while (cur_view >= 0) { MetaLine2 left, right, top, bottom, motion; MetaVector2 intersection; + cairo_rectangle_int_t rect; + float scale; + + meta_viewport_info_get_view_info (viewports, cur_view, &rect, &scale); motion = (MetaLine2) { .a = { x, y }, - .b = { x + (dx * cur->scale), y + (dy * cur->scale) } + .b = { x + (dx * scale), y + (dy * scale) } }; left = (MetaLine2) { - { cur->rect.x, cur->rect.y }, - { cur->rect.x, cur->rect.y + cur->rect.height } + { rect.x, rect.y }, + { rect.x, rect.y + rect.height } }; right = (MetaLine2) { - { cur->rect.x + cur->rect.width, cur->rect.y }, - { cur->rect.x + cur->rect.width, cur->rect.y + cur->rect.height } + { rect.x + rect.width, rect.y }, + { rect.x + rect.width, rect.y + rect.height } }; top = (MetaLine2) { - { cur->rect.x, cur->rect.y }, - { cur->rect.x + cur->rect.width, cur->rect.y } + { rect.x, rect.y }, + { rect.x + rect.width, rect.y } }; bottom = (MetaLine2) { - { cur->rect.x, cur->rect.y + cur->rect.height }, - { cur->rect.x + cur->rect.width, cur->rect.y + cur->rect.height } + { rect.x, rect.y + rect.height }, + { rect.x + rect.width, rect.y + rect.height } }; target_x = motion.b.x; @@ -1017,8 +1021,8 @@ relative_motion_across_outputs (MetaMonitorManager *monitor_manager, dx -= intersection.x - motion.a.x; dy -= intersection.y - motion.a.y; - cur = meta_monitor_manager_get_logical_monitor_neighbor (monitor_manager, - cur, direction); + cur_view = meta_viewport_info_get_neighbor (viewports, cur_view, + direction); } *dx_inout = target_x - cur_x; @@ -1033,35 +1037,32 @@ meta_seat_native_filter_relative_motion (MetaSeatNative *seat, float *dx, float *dy) { - MetaBackend *backend = meta_get_backend (); - MetaMonitorManager *monitor_manager = - meta_backend_get_monitor_manager (backend); - MetaLogicalMonitor *logical_monitor, *dest_logical_monitor; - float new_dx, new_dy; + int view = -1, dest_view; + float new_dx, new_dy, scale; if (meta_is_stage_views_scaled ()) return; - logical_monitor = meta_monitor_manager_get_logical_monitor_at (monitor_manager, - x, y); - if (!logical_monitor) + if (seat->viewports) + view = meta_viewport_info_get_view_at (seat->viewports, x, y); + if (view < 0) return; - new_dx = (*dx) * logical_monitor->scale; - new_dy = (*dy) * logical_monitor->scale; + meta_viewport_info_get_view_info (seat->viewports, view, NULL, &scale); + new_dx = (*dx) * scale; + new_dy = (*dy) * scale; - dest_logical_monitor = meta_monitor_manager_get_logical_monitor_at (monitor_manager, - x + new_dx, - y + new_dy); - if (dest_logical_monitor && - dest_logical_monitor != logical_monitor) + dest_view = meta_viewport_info_get_view_at (seat->viewports, + x + new_dx, + y + new_dy); + if (dest_view >= 0 && dest_view != view) { /* If we are crossing monitors, attempt to bisect the distance on each * axis and apply the relative scale for each of them. */ new_dx = *dx; new_dy = *dy; - relative_motion_across_outputs (monitor_manager, logical_monitor, + relative_motion_across_outputs (seat->viewports, view, x, y, &new_dx, &new_dy); } @@ -3350,3 +3351,10 @@ meta_seat_native_maybe_ensure_cursor_renderer (MetaSeatNative *seat_native, return NULL; } + +void +meta_seat_native_set_viewports (MetaSeatNative *seat, + MetaViewportInfo *viewports) +{ + g_set_object (&seat->viewports, viewports); +} diff --git a/src/backends/native/meta-seat-native.h b/src/backends/native/meta-seat-native.h index 5fa0964b0..08095b240 100644 --- a/src/backends/native/meta-seat-native.h +++ b/src/backends/native/meta-seat-native.h @@ -27,6 +27,7 @@ #include #include +#include "backends/meta-viewport-info.h" #include "backends/native/meta-barrier-native.h" #include "backends/native/meta-cursor-renderer-native.h" #include "backends/native/meta-keymap-native.h" @@ -89,6 +90,8 @@ struct _MetaSeatNative MetaCursorRenderer *cursor_renderer; GHashTable *tablet_cursors; + MetaViewportInfo *viewports; + GUdevClient *udev_client; guint tablet_mode_switch_state : 1; guint has_touchscreen : 1; @@ -264,4 +267,7 @@ void meta_seat_native_set_pointer_constraint (MetaSeatNative *seat, MetaCursorRenderer * meta_seat_native_maybe_ensure_cursor_renderer (MetaSeatNative *seat, ClutterInputDevice *device); +void meta_seat_native_set_viewports (MetaSeatNative *seat, + MetaViewportInfo *viewports); + #endif /* META_SEAT_NATIVE_H */