wayland: Add default event interface handling seat events

This is implemented at the MetaWaylandSeat level, and it governs
focus and event delivery for all devices, falling through each
of the MetaWaylandPointer/MetaWaylandKeyboard/etc components.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3420>
This commit is contained in:
Carlos Garnacho 2023-11-16 14:09:55 +01:00 committed by Robert Mader
parent a2c11f0e87
commit 80ed79a0d3
4 changed files with 178 additions and 8 deletions

View File

@ -303,6 +303,9 @@ sync_focus_surface (MetaWaylandPointer *pointer)
{
MetaBackend *backend = backend_from_pointer (pointer);
ClutterStage *stage = CLUTTER_STAGE (meta_backend_get_stage (backend));
MetaWaylandInputDevice *input_device = META_WAYLAND_INPUT_DEVICE (pointer);
MetaWaylandSeat *seat = meta_wayland_input_device_get_seat (input_device);
MetaWaylandInput *input;
if (clutter_stage_get_grab_actor (stage) != NULL)
{
@ -310,8 +313,8 @@ sync_focus_surface (MetaWaylandPointer *pointer)
return;
}
const MetaWaylandPointerGrabInterface *interface = pointer->grab->interface;
interface->focus (pointer->grab, pointer->current);
input = meta_wayland_seat_get_input (seat);
meta_wayland_input_invalidate_focus (input, pointer->device, NULL);
}
static void
@ -460,9 +463,6 @@ default_grab_focus (MetaWaylandPointerGrab *grab,
if (clutter_stage_get_grab_actor (stage) != NULL)
return;
if (pointer->button_count > 0)
return;
if (surface)
{
MetaWindow *window = NULL;
@ -1550,3 +1550,12 @@ meta_wayland_pointer_get_current_surface (MetaWaylandPointer *pointer)
{
return pointer->current;
}
MetaWaylandSurface *
meta_wayland_pointer_get_implicit_grab_surface (MetaWaylandPointer *pointer)
{
if (pointer->button_count > 0)
return pointer->focus_surface;
return NULL;
}

View File

@ -164,3 +164,5 @@ MetaWaylandSurface * meta_wayland_pointer_get_current_surface (MetaWaylandPointe
void meta_wayland_pointer_focus_surface (MetaWaylandPointer *pointer,
MetaWaylandSurface *surface);
MetaWaylandSurface * meta_wayland_pointer_get_implicit_grab_surface (MetaWaylandPointer *pointer);

View File

@ -26,6 +26,9 @@
#include "wayland/meta-wayland-tablet-seat.h"
#include "wayland/meta-wayland-versions.h"
static gboolean meta_wayland_seat_handle_event_internal (MetaWaylandSeat *seat,
const ClutterEvent *event);
#define CAPABILITY_ENABLED(prev, cur, capability) ((cur & (capability)) && !(prev & (capability)))
#define CAPABILITY_DISABLED(prev, cur, capability) ((prev & (capability)) && !(cur & (capability)))
@ -189,6 +192,79 @@ meta_wayland_seat_devices_updated (ClutterSeat *clutter_seat,
meta_wayland_seat_update_capabilities (seat, clutter_seat);
}
static MetaWaylandSurface *
default_get_focus_surface (MetaWaylandEventHandler *handler,
ClutterInputDevice *device,
ClutterEventSequence *sequence,
gpointer user_data)
{
MetaWaylandSeat *seat = user_data;
return meta_wayland_seat_get_current_surface (seat,
device,
sequence);
}
static void
default_focus (MetaWaylandEventHandler *handler,
ClutterInputDevice *device,
ClutterEventSequence *sequence,
MetaWaylandSurface *surface,
gpointer user_data)
{
MetaWaylandSeat *seat = user_data;
ClutterInputCapabilities caps;
caps = clutter_input_device_get_capabilities (device);
if (caps &
(CLUTTER_INPUT_CAPABILITY_KEYBOARD |
CLUTTER_INPUT_CAPABILITY_TABLET_PAD))
{
if (meta_wayland_seat_has_keyboard (seat))
meta_wayland_keyboard_set_focus (seat->keyboard, surface);
meta_wayland_data_device_set_keyboard_focus (&seat->data_device);
meta_wayland_data_device_primary_set_keyboard_focus (&seat->primary_data_device);
meta_wayland_tablet_seat_set_pad_focus (seat->tablet_seat, surface);
meta_wayland_text_input_set_focus (seat->text_input, surface);
}
if (caps & CLUTTER_INPUT_CAPABILITY_TABLET_TOOL)
{
meta_wayland_tablet_seat_focus_surface (seat->tablet_seat,
device,
surface);
}
if (caps &
(CLUTTER_INPUT_CAPABILITY_POINTER |
CLUTTER_INPUT_CAPABILITY_TOUCHPAD |
CLUTTER_INPUT_CAPABILITY_TRACKBALL |
CLUTTER_INPUT_CAPABILITY_TRACKPOINT))
meta_wayland_pointer_focus_surface (seat->pointer, surface);
}
static gboolean
default_handle_event (MetaWaylandEventHandler *handler,
const ClutterEvent *event,
gpointer user_data)
{
MetaWaylandSeat *seat = user_data;
return meta_wayland_seat_handle_event_internal (seat, event);
}
static const MetaWaylandEventInterface default_event_interface = {
.get_focus_surface = default_get_focus_surface,
.focus = default_focus,
.motion = default_handle_event,
.press = default_handle_event,
.release = default_handle_event,
.key = default_handle_event,
.other = default_handle_event,
};
static MetaWaylandSeat *
meta_wayland_seat_new (MetaWaylandCompositor *compositor,
struct wl_display *display)
@ -229,6 +305,11 @@ meta_wayland_seat_new (MetaWaylandCompositor *compositor,
seat->tablet_seat =
meta_wayland_tablet_manager_ensure_seat (compositor->tablet_manager, seat);
seat->input_handler = meta_wayland_input_new (seat);
seat->default_handler =
meta_wayland_input_attach_event_handler (seat->input_handler,
&default_event_interface, seat);
return seat;
}
@ -244,6 +325,8 @@ meta_wayland_seat_free (MetaWaylandSeat *seat)
{
ClutterSeat *clutter_seat;
g_clear_object (&seat->input_handler);
clutter_seat = clutter_backend_get_default_seat (clutter_get_default_backend ());
g_signal_handlers_disconnect_by_data (clutter_seat, seat);
meta_wayland_seat_set_capabilities (seat, 0);
@ -375,8 +458,8 @@ meta_wayland_seat_update (MetaWaylandSeat *seat,
}
}
gboolean
meta_wayland_seat_handle_event (MetaWaylandSeat *seat,
static gboolean
meta_wayland_seat_handle_event_internal (MetaWaylandSeat *seat,
const ClutterEvent *event)
{
ClutterEventType event_type;
@ -590,5 +673,71 @@ meta_wayland_seat_is_grabbed (MetaWaylandSeat *seat)
meta_wayland_keyboard_is_grabbed (seat->keyboard))
return TRUE;
if (!meta_wayland_input_is_current_handler (seat->input_handler,
seat->default_handler))
return TRUE;
return FALSE;
}
gboolean
meta_wayland_seat_handle_event (MetaWaylandSeat *seat,
const ClutterEvent *event)
{
return meta_wayland_input_handle_event (seat->input_handler, event);
}
MetaWaylandInput *
meta_wayland_seat_get_input (MetaWaylandSeat *seat)
{
return seat->input_handler;
}
MetaWaylandSurface *
meta_wayland_seat_get_current_surface (MetaWaylandSeat *seat,
ClutterInputDevice *device,
ClutterEventSequence *sequence)
{
if (sequence)
{
return meta_wayland_touch_get_surface (seat->touch, sequence);
}
else
{
ClutterInputCapabilities caps;
caps = clutter_input_device_get_capabilities (device);
if (caps &
(CLUTTER_INPUT_CAPABILITY_KEYBOARD |
CLUTTER_INPUT_CAPABILITY_TABLET_PAD))
return seat->input_focus;
if (caps & CLUTTER_INPUT_CAPABILITY_TABLET_TOOL)
{
return meta_wayland_tablet_seat_get_current_surface (seat->tablet_seat,
device);
}
if (caps &
(CLUTTER_INPUT_CAPABILITY_POINTER |
CLUTTER_INPUT_CAPABILITY_TOUCHPAD |
CLUTTER_INPUT_CAPABILITY_TRACKBALL |
CLUTTER_INPUT_CAPABILITY_TRACKPOINT))
{
MetaWaylandSurface *implicit_grab_surface;
implicit_grab_surface =
meta_wayland_pointer_get_implicit_grab_surface (seat->pointer);
if (implicit_grab_surface &&
meta_wayland_input_is_current_handler (seat->input_handler,
seat->default_handler))
return implicit_grab_surface;
else
return meta_wayland_pointer_get_current_surface (seat->pointer);
}
}
return NULL;
}

View File

@ -24,6 +24,7 @@
#include "clutter/clutter.h"
#include "wayland/meta-wayland-data-device.h"
#include "wayland/meta-wayland-data-device-primary.h"
#include "wayland/meta-wayland-input.h"
#include "wayland/meta-wayland-input-device.h"
#include "wayland/meta-wayland-keyboard.h"
#include "wayland/meta-wayland-pointer.h"
@ -49,6 +50,9 @@ struct _MetaWaylandSeat
MetaWaylandTextInput *text_input;
MetaWaylandInput *input_handler;
MetaWaylandEventHandler *default_handler;
MetaWaylandSurface *input_focus;
gulong input_focus_destroy_id;
@ -88,3 +92,9 @@ gboolean meta_wayland_seat_has_touch (MetaWaylandSeat *seat);
MetaWaylandCompositor * meta_wayland_seat_get_compositor (MetaWaylandSeat *seat);
gboolean meta_wayland_seat_is_grabbed (MetaWaylandSeat *seat);
MetaWaylandInput * meta_wayland_seat_get_input (MetaWaylandSeat *seat);
MetaWaylandSurface * meta_wayland_seat_get_current_surface (MetaWaylandSeat *seat,
ClutterInputDevice *device,
ClutterEventSequence *sequence);