summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarlos Garnacho <carlosg@gnome.org>2016-05-10 17:29:57 +0200
committerCarlos Garnacho <carlosg@gnome.org>2016-07-20 19:26:31 +0200
commitde704e591bd973d43aae01cac4f69bf23ad120ba (patch)
treee618f05bbc7ab36b54ebd313443aca09c8bcd204
parenta14f0edcaed5c267f938225b911a486c5576855b (diff)
downloadmutter-de704e591bd973d43aae01cac4f69bf23ad120ba.tar.gz
wayland: Add focus management to pads
All pads will share the same focus than the keyboard, so this means that: - The focus changes in-sync for keyboard and all pad devices, and - Newly plugged pads will be immediately focused on that same surface
-rw-r--r--src/wayland/meta-wayland-seat.c15
-rw-r--r--src/wayland/meta-wayland-tablet-pad.c66
-rw-r--r--src/wayland/meta-wayland-tablet-seat.c35
-rw-r--r--src/wayland/meta-wayland-tablet-seat.h3
4 files changed, 115 insertions, 4 deletions
diff --git a/src/wayland/meta-wayland-seat.c b/src/wayland/meta-wayland-seat.c
index 9a7fa2e92..a235a81ec 100644
--- a/src/wayland/meta-wayland-seat.c
+++ b/src/wayland/meta-wayland-seat.c
@@ -26,6 +26,7 @@
#include "meta-wayland-private.h"
#include "meta-wayland-versions.h"
#include "meta-wayland-data-device.h"
+#include "meta-wayland-tablet-seat.h"
#define CAPABILITY_ENABLED(prev, cur, capability) ((cur & (capability)) && !(prev & (capability)))
#define CAPABILITY_DISABLED(prev, cur, capability) ((prev & (capability)) && !(cur & (capability)))
@@ -369,11 +370,17 @@ void
meta_wayland_seat_set_input_focus (MetaWaylandSeat *seat,
MetaWaylandSurface *surface)
{
- if ((seat->capabilities & WL_SEAT_CAPABILITY_KEYBOARD) == 0)
- return;
+ MetaWaylandTabletSeat *tablet_seat;
+ MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default ();
+
+ if ((seat->capabilities & WL_SEAT_CAPABILITY_KEYBOARD) != 0)
+ {
+ meta_wayland_keyboard_set_focus (&seat->keyboard, surface);
+ meta_wayland_data_device_set_keyboard_focus (&seat->data_device);
+ }
- meta_wayland_keyboard_set_focus (&seat->keyboard, surface);
- meta_wayland_data_device_set_keyboard_focus (&seat->data_device);
+ tablet_seat = meta_wayland_tablet_manager_ensure_seat (compositor->tablet_manager, seat);
+ meta_wayland_tablet_seat_set_pad_focus (tablet_seat, surface);
}
gboolean
diff --git a/src/wayland/meta-wayland-tablet-pad.c b/src/wayland/meta-wayland-tablet-pad.c
index 4c62f48a8..3e06434b8 100644
--- a/src/wayland/meta-wayland-tablet-pad.c
+++ b/src/wayland/meta-wayland-tablet-pad.c
@@ -32,6 +32,8 @@
#include "meta-surface-actor-wayland.h"
#include "meta-wayland-private.h"
+#include "meta-wayland-tablet-seat.h"
+#include "meta-wayland-tablet.h"
#include "meta-wayland-tablet-pad.h"
#include "meta-wayland-tablet-pad-group.h"
#include "meta-wayland-tablet-pad-ring.h"
@@ -301,4 +303,68 @@ void
meta_wayland_tablet_pad_set_focus (MetaWaylandTabletPad *pad,
MetaWaylandSurface *surface)
{
+ MetaWaylandTablet *tablet;
+
+ if (pad->focus_surface == surface)
+ return;
+
+ g_hash_table_remove_all (pad->feedback);
+
+ if (pad->focus_surface != NULL)
+ {
+ struct wl_resource *resource;
+ struct wl_list *l = &pad->focus_resource_list;
+
+ if (!wl_list_empty (l))
+ {
+ struct wl_client *client = wl_resource_get_client (pad->focus_surface->resource);
+ struct wl_display *display = wl_client_get_display (client);
+ uint32_t serial = wl_display_next_serial (display);
+
+ wl_resource_for_each (resource, l)
+ {
+ zwp_tablet_pad_v2_send_leave (resource, serial, pad->focus_surface->resource);
+ }
+
+ move_resources (&pad->resource_list, &pad->focus_resource_list);
+ }
+
+ wl_list_remove (&pad->focus_surface_listener.link);
+ pad->focus_surface = NULL;
+ }
+
+ tablet = meta_wayland_tablet_seat_lookup_paired_tablet (pad->tablet_seat, pad);
+
+ if (tablet != NULL && surface != NULL)
+ {
+ struct wl_resource *resource;
+ struct wl_list *l;
+
+ pad->focus_surface = surface;
+ wl_resource_add_destroy_listener (pad->focus_surface->resource, &pad->focus_surface_listener);
+
+ move_resources_for_client (&pad->focus_resource_list,
+ &pad->resource_list,
+ wl_resource_get_client (pad->focus_surface->resource));
+
+ l = &pad->focus_resource_list;
+ if (!wl_list_empty (l))
+ {
+ struct wl_client *client = wl_resource_get_client (pad->focus_surface->resource);
+ struct wl_display *display = wl_client_get_display (client);
+ struct wl_resource *tablet_resource =
+ meta_wayland_tablet_lookup_resource (tablet, client);
+
+ pad->focus_serial = wl_display_next_serial (display);
+
+ wl_resource_for_each (resource, l)
+ {
+ zwp_tablet_pad_v2_send_enter (resource, pad->focus_serial,
+ tablet_resource,
+ pad->focus_surface->resource);
+ }
+ }
+ }
+
+ meta_wayland_tablet_pad_update_groups_focus (pad);
}
diff --git a/src/wayland/meta-wayland-tablet-seat.c b/src/wayland/meta-wayland-tablet-seat.c
index b69ce336b..26ba99c02 100644
--- a/src/wayland/meta-wayland-tablet-seat.c
+++ b/src/wayland/meta-wayland-tablet-seat.c
@@ -36,6 +36,11 @@
#include "meta-wayland-tablet-tool.h"
#include "meta-wayland-tablet-pad.h"
+#ifdef HAVE_NATIVE_BACKEND
+#include <clutter/evdev/clutter-evdev.h>
+#include "backends/native/meta-backend-native.h"
+#endif
+
static void
unbind_resource (struct wl_resource *resource)
{
@@ -198,13 +203,28 @@ static void
meta_wayland_tablet_seat_device_added (MetaWaylandTabletSeat *tablet_seat,
ClutterInputDevice *device)
{
+ MetaWaylandSurface *pad_focus = tablet_seat->seat->keyboard.focus_surface;
+
if (is_tablet_device (device))
{
MetaWaylandTablet *tablet;
+ GList *pads, *l;
tablet = meta_wayland_tablet_new (device, tablet_seat);
g_hash_table_insert (tablet_seat->tablets, device, tablet);
broadcast_tablet_added (tablet_seat, device);
+
+ /* Because the insertion order is undefined, there might be already
+ * pads that are logically paired to this tablet. Look those up and
+ * refocus them.
+ */
+ pads = meta_wayland_tablet_seat_lookup_paired_pads (tablet_seat,
+ tablet);
+
+ for (l = pads; l; l = l->next)
+ meta_wayland_tablet_pad_set_focus (l->data, pad_focus);
+
+ g_list_free (pads);
}
else if (is_pad_device (device))
{
@@ -213,6 +233,8 @@ meta_wayland_tablet_seat_device_added (MetaWaylandTabletSeat *tablet_seat,
pad = meta_wayland_tablet_pad_new (device, tablet_seat);
g_hash_table_insert (tablet_seat->pads, device, pad);
broadcast_pad_added (tablet_seat, device);
+
+ meta_wayland_tablet_pad_set_focus (pad, pad_focus);
}
}
@@ -511,3 +533,16 @@ meta_wayland_tablet_seat_lookup_paired_pads (MetaWaylandTabletSeat *tablet_seat,
return pads;
}
+
+void
+meta_wayland_tablet_seat_set_pad_focus (MetaWaylandTabletSeat *tablet_seat,
+ MetaWaylandSurface *surface)
+{
+ MetaWaylandTabletPad *pad;
+ GHashTableIter iter;
+
+ g_hash_table_iter_init (&iter, tablet_seat->pads);
+
+ while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &pad))
+ meta_wayland_tablet_pad_set_focus (pad, surface);
+}
diff --git a/src/wayland/meta-wayland-tablet-seat.h b/src/wayland/meta-wayland-tablet-seat.h
index 98ce4a956..e923f936e 100644
--- a/src/wayland/meta-wayland-tablet-seat.h
+++ b/src/wayland/meta-wayland-tablet-seat.h
@@ -69,6 +69,9 @@ void meta_wayland_tablet_seat_notify_tool (MetaWayland
MetaWaylandTabletTool *tool,
struct wl_client *client);
+void meta_wayland_tablet_seat_set_pad_focus (MetaWaylandTabletSeat *tablet_seat,
+ MetaWaylandSurface *surface);
+
MetaWaylandTablet *meta_wayland_tablet_seat_lookup_paired_tablet (MetaWaylandTabletSeat *tablet_seat,
MetaWaylandTabletPad *pad);
GList *meta_wayland_tablet_seat_lookup_paired_pads (MetaWaylandTabletSeat *tablet_seat,