backends: Center pointer on primary monitor on startup

This seems nicer/tidier than the current X11 (center on the span of all
monitors) or native (so close to the activities corner it's hard not
to trigger it) platform behaviors.

This code also takes over the native-specific pointer warping that
happens when the pointer was over a removed output.

https://bugzilla.gnome.org/show_bug.cgi?id=746896
This commit is contained in:
Carlos Garnacho 2015-03-27 15:50:59 +01:00
parent 8188cddcf7
commit c6e6ed87c5
2 changed files with 27 additions and 34 deletions

View File

@ -92,12 +92,37 @@ meta_backend_sync_screen_size (MetaBackend *backend)
META_BACKEND_GET_CLASS (backend)->update_screen_size (backend, width, height); META_BACKEND_GET_CLASS (backend)->update_screen_size (backend, width, height);
} }
static void
center_pointer (MetaBackend *backend)
{
MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
MetaMonitorInfo *monitors, *primary;
guint n_monitors;
monitors = meta_monitor_manager_get_monitor_infos (priv->monitor_manager, &n_monitors);
primary = &monitors[meta_monitor_manager_get_primary_index (priv->monitor_manager)];
meta_backend_warp_pointer (backend,
primary->rect.x + primary->rect.width / 2,
primary->rect.y + primary->rect.height / 2);
}
static void static void
on_monitors_changed (MetaMonitorManager *monitors, on_monitors_changed (MetaMonitorManager *monitors,
gpointer user_data) gpointer user_data)
{ {
MetaBackend *backend = META_BACKEND (user_data); MetaBackend *backend = META_BACKEND (user_data);
ClutterDeviceManager *manager = clutter_device_manager_get_default ();
ClutterInputDevice *device = clutter_device_manager_get_core_device (manager, CLUTTER_POINTER_DEVICE);
ClutterPoint point;
meta_backend_sync_screen_size (backend); meta_backend_sync_screen_size (backend);
if (clutter_input_device_get_coords (device, NULL, &point))
{
/* If we're outside all monitors, warp the pointer back inside */
if (meta_monitor_manager_get_monitor_at_point (monitors, point.x, point.y) < 0)
center_pointer (backend);
}
} }
static MetaIdleMonitor * static MetaIdleMonitor *
@ -283,6 +308,8 @@ meta_backend_real_post_init (MetaBackend *backend)
} }
priv->input_settings = meta_input_settings_create (); priv->input_settings = meta_input_settings_create ();
center_pointer (backend);
} }
static MetaCursorRenderer * static MetaCursorRenderer *

View File

@ -152,49 +152,15 @@ pointer_constrain_callback (ClutterInputDevice *device,
constrain_all_screen_monitors(device, monitors, n_monitors, new_x, new_y); constrain_all_screen_monitors(device, monitors, n_monitors, new_x, new_y);
} }
static void
on_monitors_changed (MetaMonitorManager *monitor_manager,
MetaBackend *backend)
{
ClutterDeviceManager *manager = clutter_device_manager_get_default ();
ClutterInputDevice *device = clutter_device_manager_get_core_device (manager, CLUTTER_POINTER_DEVICE);
MetaMonitorInfo *monitors, *primary;
unsigned int n_monitors;
ClutterPoint point;
if (!clutter_input_device_get_coords (device, NULL, &point))
return;
monitors = meta_monitor_manager_get_monitor_infos (monitor_manager, &n_monitors);
/* if we're inside a monitor, we're fine */
if (meta_monitor_manager_get_monitor_at_point (monitor_manager, point.x, point.y) >= 0)
return;
/* warp the pointer to the primary monitor so it isn't lost */
primary = &monitors[meta_monitor_manager_get_primary_index (monitor_manager)];
meta_backend_warp_pointer (backend,
primary->rect.x + primary->rect.width / 2,
primary->rect.y + primary->rect.height / 2);
}
static void static void
meta_backend_native_post_init (MetaBackend *backend) meta_backend_native_post_init (MetaBackend *backend)
{ {
MetaMonitorManager *monitor_manager;
ClutterDeviceManager *manager = clutter_device_manager_get_default (); ClutterDeviceManager *manager = clutter_device_manager_get_default ();
META_BACKEND_CLASS (meta_backend_native_parent_class)->post_init (backend); META_BACKEND_CLASS (meta_backend_native_parent_class)->post_init (backend);
clutter_evdev_set_pointer_constrain_callback (manager, pointer_constrain_callback, clutter_evdev_set_pointer_constrain_callback (manager, pointer_constrain_callback,
NULL, NULL); NULL, NULL);
monitor_manager = meta_backend_get_monitor_manager (backend);
g_signal_connect_object (monitor_manager, "monitors-changed",
G_CALLBACK (on_monitors_changed), backend, G_CONNECT_AFTER);
/* make sure the pointer is in the visible area after init */
on_monitors_changed (monitor_manager, backend);
} }
static MetaIdleMonitor * static MetaIdleMonitor *