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.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1403
This commit is contained in:
Carlos Garnacho 2020-07-16 16:41:02 +02:00
parent bb62d9e4b0
commit 0c9bbbe90e
3 changed files with 94 additions and 57 deletions

View File

@ -106,6 +106,21 @@ meta_backend_native_create_clutter_backend (MetaBackend *backend)
return g_object_new (META_TYPE_CLUTTER_BACKEND_NATIVE, NULL); return g_object_new (META_TYPE_CLUTTER_BACKEND_NATIVE, NULL);
} }
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 static void
meta_backend_native_post_init (MetaBackend *backend) meta_backend_native_post_init (MetaBackend *backend)
{ {
@ -127,6 +142,8 @@ meta_backend_native_post_init (MetaBackend *backend)
g_warning ("Failed to set RT scheduler: %m"); g_warning ("Failed to set RT scheduler: %m");
} }
update_viewports (backend);
#ifdef HAVE_WAYLAND #ifdef HAVE_WAYLAND
meta_backend_init_wayland (backend); meta_backend_init_wayland (backend);
#endif #endif
@ -136,9 +153,15 @@ static MetaMonitorManager *
meta_backend_native_create_monitor_manager (MetaBackend *backend, meta_backend_native_create_monitor_manager (MetaBackend *backend,
GError **error) GError **error)
{ {
return g_initable_new (META_TYPE_MONITOR_MANAGER_KMS, NULL, error, MetaMonitorManager *manager;
manager = g_initable_new (META_TYPE_MONITOR_MANAGER_KMS, NULL, error,
"backend", backend, "backend", backend,
NULL); NULL);
g_signal_connect_swapped (manager, "monitors-changed-internal",
G_CALLBACK (update_viewports), backend);
return manager;
} }
static MetaCursorRenderer * static MetaCursorRenderer *

View File

@ -875,13 +875,13 @@ constrain_to_barriers (MetaSeatNative *seat,
static void static void
constrain_all_screen_monitors (ClutterInputDevice *device, constrain_all_screen_monitors (ClutterInputDevice *device,
MetaMonitorManager *monitor_manager, MetaViewportInfo *viewports,
float *x, float *x,
float *y) float *y)
{ {
graphene_point_t current; graphene_point_t current;
float cx, cy; float cx, cy;
GList *logical_monitors, *l; int i, n_views;
clutter_input_device_get_coords (device, NULL, &current); clutter_input_device_get_coords (device, NULL, &current);
@ -890,17 +890,19 @@ constrain_all_screen_monitors (ClutterInputDevice *device,
/* if we're trying to escape, clamp to the CRTC we're coming from */ /* if we're trying to escape, clamp to the CRTC we're coming from */
logical_monitors = n_views = meta_viewport_info_get_num_views (viewports);
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;
left = logical_monitor->rect.x; for (i = 0; i < n_views; i++)
right = left + logical_monitor->rect.width; {
top = logical_monitor->rect.y; int left, right, top, bottom;
bottom = top + logical_monitor->rect.height; cairo_rectangle_int_t rect;
meta_viewport_info_get_view (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)) if ((cx >= left) && (cx < right) && (cy >= top) && (cy < bottom))
{ {
@ -927,10 +929,6 @@ meta_seat_native_constrain_pointer (MetaSeatNative *seat,
float *new_x, float *new_x,
float *new_y) float *new_y)
{ {
MetaBackend *backend = meta_get_backend ();
MetaMonitorManager *monitor_manager =
meta_backend_get_monitor_manager (backend);
/* Constrain to barriers */ /* Constrain to barriers */
constrain_to_barriers (seat, core_pointer, constrain_to_barriers (seat, core_pointer,
us2ms (time_us), us2ms (time_us),
@ -946,53 +944,59 @@ meta_seat_native_constrain_pointer (MetaSeatNative *seat,
new_x, new_y); new_x, new_y);
} }
if (seat->viewports)
{
/* if we're moving inside a monitor, we're fine */ /* if we're moving inside a monitor, we're fine */
if (meta_monitor_manager_get_logical_monitor_at (monitor_manager, if (meta_viewport_info_get_view_at (seat->viewports, *new_x, *new_y) > 0)
*new_x, *new_y))
return; return;
/* if we're trying to escape, clamp to the CRTC we're coming from */ /* 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); constrain_all_screen_monitors (core_pointer, seat->viewports, new_x, new_y);
}
} }
static void static void
relative_motion_across_outputs (MetaMonitorManager *monitor_manager, relative_motion_across_outputs (MetaViewportInfo *viewports,
MetaLogicalMonitor *current, int view,
float cur_x, float cur_x,
float cur_y, float cur_y,
float *dx_inout, float *dx_inout,
float *dy_inout) float *dy_inout)
{ {
MetaLogicalMonitor *cur = current; int cur_view = view;
float x = cur_x, y = cur_y; float x = cur_x, y = cur_y;
float target_x = cur_x, target_y = cur_y; float target_x = cur_x, target_y = cur_y;
float dx = *dx_inout, dy = *dy_inout; float dx = *dx_inout, dy = *dy_inout;
MetaDisplayDirection direction = -1; MetaDisplayDirection direction = -1;
while (cur) while (cur_view >= 0)
{ {
MetaLine2 left, right, top, bottom, motion; MetaLine2 left, right, top, bottom, motion;
MetaVector2 intersection; MetaVector2 intersection;
cairo_rectangle_int_t rect;
float scale;
meta_viewport_info_get_view (viewports, cur_view, &rect, &scale);
motion = (MetaLine2) { motion = (MetaLine2) {
.a = { x, y }, .a = { x, y },
.b = { x + (dx * cur->scale), y + (dy * cur->scale) } .b = { x + (dx * scale), y + (dy * scale) }
}; };
left = (MetaLine2) { left = (MetaLine2) {
{ cur->rect.x, cur->rect.y }, { rect.x, rect.y },
{ cur->rect.x, cur->rect.y + cur->rect.height } { rect.x, rect.y + rect.height }
}; };
right = (MetaLine2) { right = (MetaLine2) {
{ cur->rect.x + cur->rect.width, cur->rect.y }, { rect.x + rect.width, rect.y },
{ cur->rect.x + cur->rect.width, cur->rect.y + cur->rect.height } { rect.x + rect.width, rect.y + rect.height }
}; };
top = (MetaLine2) { top = (MetaLine2) {
{ cur->rect.x, cur->rect.y }, { rect.x, rect.y },
{ cur->rect.x + cur->rect.width, cur->rect.y } { rect.x + rect.width, rect.y }
}; };
bottom = (MetaLine2) { bottom = (MetaLine2) {
{ cur->rect.x, cur->rect.y + cur->rect.height }, { rect.x, rect.y + rect.height },
{ cur->rect.x + cur->rect.width, cur->rect.y + cur->rect.height } { rect.x + rect.width, rect.y + rect.height }
}; };
target_x = motion.b.x; target_x = motion.b.x;
@ -1019,8 +1023,8 @@ relative_motion_across_outputs (MetaMonitorManager *monitor_manager,
dx -= intersection.x - motion.a.x; dx -= intersection.x - motion.a.x;
dy -= intersection.y - motion.a.y; dy -= intersection.y - motion.a.y;
cur = meta_monitor_manager_get_logical_monitor_neighbor (monitor_manager, cur_view = meta_viewport_info_get_neighbor (viewports, cur_view,
cur, direction); direction);
} }
*dx_inout = target_x - cur_x; *dx_inout = target_x - cur_x;
@ -1035,35 +1039,32 @@ meta_seat_native_filter_relative_motion (MetaSeatNative *seat,
float *dx, float *dx,
float *dy) float *dy)
{ {
MetaBackend *backend = meta_get_backend (); int view = -1, dest_view;
MetaMonitorManager *monitor_manager = float new_dx, new_dy, scale;
meta_backend_get_monitor_manager (backend);
MetaLogicalMonitor *logical_monitor, *dest_logical_monitor;
float new_dx, new_dy;
if (meta_is_stage_views_scaled ()) if (meta_is_stage_views_scaled ())
return; return;
logical_monitor = meta_monitor_manager_get_logical_monitor_at (monitor_manager, if (seat->viewports)
x, y); view = meta_viewport_info_get_view_at (seat->viewports, x, y);
if (!logical_monitor) if (view < 0)
return; return;
new_dx = (*dx) * logical_monitor->scale; meta_viewport_info_get_view (seat->viewports, view, NULL, &scale);
new_dy = (*dy) * logical_monitor->scale; new_dx = (*dx) * scale;
new_dy = (*dy) * scale;
dest_logical_monitor = meta_monitor_manager_get_logical_monitor_at (monitor_manager, dest_view = meta_viewport_info_get_view_at (seat->viewports,
x + new_dx, x + new_dx,
y + new_dy); y + new_dy);
if (dest_logical_monitor && if (dest_view >= 0 && dest_view != view)
dest_logical_monitor != logical_monitor)
{ {
/* If we are crossing monitors, attempt to bisect the distance on each /* If we are crossing monitors, attempt to bisect the distance on each
* axis and apply the relative scale for each of them. * axis and apply the relative scale for each of them.
*/ */
new_dx = *dx; new_dx = *dx;
new_dy = *dy; new_dy = *dy;
relative_motion_across_outputs (monitor_manager, logical_monitor, relative_motion_across_outputs (seat->viewports, view,
x, y, &new_dx, &new_dy); x, y, &new_dx, &new_dy);
} }
@ -3323,3 +3324,10 @@ meta_seat_native_get_cursor_renderer (MetaSeatNative *seat,
return NULL; return NULL;
} }
void
meta_seat_native_set_viewports (MetaSeatNative *seat,
MetaViewportInfo *viewports)
{
g_set_object (&seat->viewports, viewports);
}

View File

@ -27,6 +27,7 @@
#include <libinput.h> #include <libinput.h>
#include <linux/input-event-codes.h> #include <linux/input-event-codes.h>
#include "backends/meta-viewport-info.h"
#include "backends/native/meta-barrier-native.h" #include "backends/native/meta-barrier-native.h"
#include "backends/native/meta-cursor-renderer-native.h" #include "backends/native/meta-cursor-renderer-native.h"
#include "backends/native/meta-keymap-native.h" #include "backends/native/meta-keymap-native.h"
@ -88,6 +89,8 @@ struct _MetaSeatNative
MetaKmsCursorRenderer *kms_cursor_renderer; MetaKmsCursorRenderer *kms_cursor_renderer;
GHashTable *tablet_cursors; GHashTable *tablet_cursors;
MetaViewportInfo *viewports;
GUdevClient *udev_client; GUdevClient *udev_client;
guint tablet_mode_switch_state : 1; guint tablet_mode_switch_state : 1;
guint has_touchscreen : 1; guint has_touchscreen : 1;
@ -263,4 +266,7 @@ void meta_seat_native_set_pointer_constraint (MetaSeatNative *seat,
MetaCursorRenderer * meta_seat_native_get_cursor_renderer (MetaSeatNative *seat, MetaCursorRenderer * meta_seat_native_get_cursor_renderer (MetaSeatNative *seat,
ClutterInputDevice *device); ClutterInputDevice *device);
void meta_seat_native_set_viewports (MetaSeatNative *seat,
MetaViewportInfo *viewports);
#endif /* META_SEAT_NATIVE_H */ #endif /* META_SEAT_NATIVE_H */