[mutter/wip/wayland-work: 5/13] wayland: constraint the pointer onto visible monitors when running on evdev
- From: Jasper St. Pierre <jstpierre src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter/wip/wayland-work: 5/13] wayland: constraint the pointer onto visible monitors when running on evdev
- Date: Tue, 3 Sep 2013 15:02:20 +0000 (UTC)
commit f4177dbd015fac18ccd7d143b69b6dbf95ca72c1
Author: Giovanni Campagna <gcampagn redhat com>
Date: Fri Aug 23 13:57:58 2013 +0200
wayland: constraint the pointer onto visible monitors when running on evdev
Use the new Clutter hook to make sure the pointer never enters
the dead area caused by the different monitor sizes.
You don't realize how much X is doing for you until you lose it...
https://bugzilla.gnome.org/show_bug.cgi?id=706655
src/wayland/meta-wayland-pointer.c | 123 ++++++++++++++++++++++++++++++++++-
src/wayland/meta-wayland-pointer.h | 5 +-
src/wayland/meta-wayland-seat.c | 2 +-
3 files changed, 123 insertions(+), 7 deletions(-)
---
diff --git a/src/wayland/meta-wayland-pointer.c b/src/wayland/meta-wayland-pointer.c
index aaa003e..8c74375 100644
--- a/src/wayland/meta-wayland-pointer.c
+++ b/src/wayland/meta-wayland-pointer.c
@@ -43,6 +43,9 @@
#include "config.h"
+#include <clutter/clutter.h>
+#include <clutter/evdev/clutter-evdev.h>
+
#include "meta-wayland-pointer.h"
#include "meta-wayland-private.h"
@@ -120,9 +123,114 @@ static const MetaWaylandPointerGrabInterface default_pointer_grab_interface = {
default_grab_button
};
+/*
+ * The pointer constrain code is mostly a rip-off of the XRandR code from Xorg.
+ * (from xserver/randr/rrcrtc.c, RRConstrainCursorHarder)
+ *
+ * Copyright © 2006 Keith Packard
+ * Copyright 2010 Red Hat, Inc
+ *
+ */
+
+static gboolean
+check_all_screen_monitors(MetaMonitorInfo *monitors,
+ unsigned n_monitors,
+ float x,
+ float y)
+{
+ unsigned int i;
+
+ for (i = 0; i < n_monitors; i++)
+ {
+ MetaMonitorInfo *monitor = &monitors[i];
+ int left, right, top, bottom;
+
+ left = monitor->rect.x;
+ right = left + monitor->rect.width;
+ top = monitor->rect.y;
+ bottom = left + monitor->rect.height;
+
+ if ((x >= left) && (x < right) && (y >= top) && (y < bottom))
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static void
+constrain_all_screen_monitors (ClutterInputDevice *device,
+ MetaMonitorInfo *monitors,
+ unsigned n_monitors,
+ float *x,
+ float *y)
+{
+ ClutterPoint current;
+ unsigned int i;
+
+ clutter_input_device_get_coords (device, NULL, ¤t);
+
+ /* if we're trying to escape, clamp to the CRTC we're coming from */
+ for (i = 0; i < n_monitors; i++)
+ {
+ MetaMonitorInfo *monitor = &monitors[i];
+ int left, right, top, bottom;
+ float nx, ny;
+
+ left = monitor->rect.x;
+ right = left + monitor->rect.width;
+ top = monitor->rect.y;
+ bottom = left + monitor->rect.height;
+
+ nx = current.x;
+ ny = current.y;
+
+ if ((nx >= left) && (nx < right) && (ny >= top) && (ny < bottom))
+ {
+ if (*x < left)
+ *x = left;
+ if (*x >= right)
+ *x = right - 1;
+ if (*y < top)
+ *y = top;
+ if (*y >= bottom)
+ *y = bottom - 1;
+
+ return;
+ }
+ }
+}
+
+static void
+pointer_constrain_callback (ClutterInputDevice *device,
+ float *new_x,
+ float *new_y,
+ gpointer user_data)
+{
+ MetaMonitorManager *monitor_manager;
+ MetaMonitorInfo *monitors;
+ unsigned int n_monitors;
+ gboolean ret;
+
+ monitor_manager = meta_monitor_manager_get ();
+ monitors = meta_monitor_manager_get_monitor_infos (monitor_manager, &n_monitors);
+
+ /* if we're moving inside a monitor, we're fine */
+ ret = check_all_screen_monitors(monitors, n_monitors, *new_x, *new_y);
+ if (ret == TRUE)
+ return;
+
+ /* if we're trying to escape, clamp to the CRTC we're coming from */
+ constrain_all_screen_monitors(device, monitors, n_monitors, new_x, new_y);
+}
+
void
-meta_wayland_pointer_init (MetaWaylandPointer *pointer)
+meta_wayland_pointer_init (MetaWaylandPointer *pointer,
+ gboolean is_native)
{
+ ClutterDeviceManager *manager;
+ ClutterInputDevice *device;
+ ClutterPoint current;
+
memset (pointer, 0, sizeof *pointer);
wl_list_init (&pointer->resource_list);
pointer->focus_listener.notify = lose_pointer_focus;
@@ -131,9 +239,16 @@ meta_wayland_pointer_init (MetaWaylandPointer *pointer)
pointer->grab = &pointer->default_grab;
wl_signal_init (&pointer->focus_signal);
- /* FIXME: Pick better co-ords. */
- pointer->x = wl_fixed_from_int (100);
- pointer->y = wl_fixed_from_int (100);
+ manager = clutter_device_manager_get_default ();
+ device = clutter_device_manager_get_core_device (manager, CLUTTER_POINTER_DEVICE);
+
+ if (is_native)
+ clutter_evdev_set_pointer_constrain_callback (manager, pointer_constrain_callback,
+ pointer, NULL);
+
+ clutter_input_device_get_coords (device, NULL, ¤t);
+ pointer->x = wl_fixed_from_double (current.x);
+ pointer->y = wl_fixed_from_double (current.y);
}
void
diff --git a/src/wayland/meta-wayland-pointer.h b/src/wayland/meta-wayland-pointer.h
index 7ab3bd3..4c4aaff 100644
--- a/src/wayland/meta-wayland-pointer.h
+++ b/src/wayland/meta-wayland-pointer.h
@@ -60,7 +60,7 @@ struct _MetaWaylandPointer
guint32 grab_serial;
guint32 grab_time;
- wl_fixed_t x, y;
+ wl_fixed_t x, y; /* TODO: remove, use ClutterInputDevice instead */
MetaWaylandSurface *current;
struct wl_listener current_listener;
wl_fixed_t current_x, current_y;
@@ -69,7 +69,8 @@ struct _MetaWaylandPointer
};
void
-meta_wayland_pointer_init (MetaWaylandPointer *pointer);
+meta_wayland_pointer_init (MetaWaylandPointer *pointer,
+ gboolean is_native);
void
meta_wayland_pointer_release (MetaWaylandPointer *pointer);
diff --git a/src/wayland/meta-wayland-seat.c b/src/wayland/meta-wayland-seat.c
index c577562..2442c78 100644
--- a/src/wayland/meta-wayland-seat.c
+++ b/src/wayland/meta-wayland-seat.c
@@ -284,7 +284,7 @@ meta_wayland_seat_new (struct wl_display *display,
wl_list_init (&seat->drag_resource_list);
wl_signal_init (&seat->drag_icon_signal);
- meta_wayland_pointer_init (&seat->pointer);
+ meta_wayland_pointer_init (&seat->pointer, is_native);
meta_wayland_keyboard_init (&seat->keyboard, display, is_native);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]