2014-03-20 15:29:30 -04:00
|
|
|
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Copyright (C) 2001 Havoc Pennington
|
|
|
|
* Copyright (C) 2002, 2003, 2004 Red Hat, Inc.
|
|
|
|
* Copyright (C) 2003, 2004 Rob Adams
|
|
|
|
* Copyright (C) 2004-2006 Elijah Newren
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License as
|
|
|
|
* published by the Free Software Foundation; either version 2 of the
|
|
|
|
* License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful, but
|
|
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "config.h"
|
|
|
|
|
2018-07-10 04:36:24 -04:00
|
|
|
#include "core/events.h"
|
2014-08-05 08:11:59 -04:00
|
|
|
|
2014-10-09 04:40:26 -04:00
|
|
|
#include "backends/meta-cursor-tracker-private.h"
|
2022-02-23 10:09:28 -05:00
|
|
|
#include "backends/meta-dnd-private.h"
|
2021-04-19 09:22:57 -04:00
|
|
|
#include "backends/meta-idle-manager.h"
|
2021-11-17 17:31:11 -05:00
|
|
|
#include "compositor/compositor-private.h"
|
2019-06-13 14:18:27 -04:00
|
|
|
#include "compositor/meta-window-actor-private.h"
|
2018-07-10 04:36:24 -04:00
|
|
|
#include "core/display-private.h"
|
|
|
|
#include "core/window-private.h"
|
|
|
|
#include "meta/meta-backend.h"
|
2014-03-20 15:29:30 -04:00
|
|
|
|
2022-06-01 04:06:55 -04:00
|
|
|
#ifdef HAVE_X11_CLIENT
|
|
|
|
#include "backends/x11/meta-backend-x11.h"
|
|
|
|
#include "backends/x11/meta-input-device-x11.h"
|
|
|
|
#endif
|
|
|
|
|
2014-06-11 16:08:33 -04:00
|
|
|
#ifdef HAVE_NATIVE_BACKEND
|
|
|
|
#include "backends/native/meta-backend-native.h"
|
|
|
|
#endif
|
2014-03-20 15:54:16 -04:00
|
|
|
|
2014-08-13 20:19:35 -04:00
|
|
|
#ifdef HAVE_WAYLAND
|
2014-06-11 16:08:33 -04:00
|
|
|
#include "wayland/meta-wayland-private.h"
|
2014-08-13 20:19:35 -04:00
|
|
|
#endif
|
2014-03-20 15:29:30 -04:00
|
|
|
|
2023-08-04 06:29:27 -04:00
|
|
|
#define IS_GESTURE_EVENT(et) ((et) == CLUTTER_TOUCHPAD_SWIPE || \
|
|
|
|
(et) == CLUTTER_TOUCHPAD_PINCH || \
|
|
|
|
(et) == CLUTTER_TOUCHPAD_HOLD || \
|
|
|
|
(et) == CLUTTER_TOUCH_BEGIN || \
|
|
|
|
(et) == CLUTTER_TOUCH_UPDATE || \
|
|
|
|
(et) == CLUTTER_TOUCH_END || \
|
|
|
|
(et) == CLUTTER_TOUCH_CANCEL)
|
2015-07-01 09:49:33 -04:00
|
|
|
|
2023-08-04 06:29:27 -04:00
|
|
|
#define IS_KEY_EVENT(et) ((et) == CLUTTER_KEY_PRESS || \
|
|
|
|
(et) == CLUTTER_KEY_RELEASE)
|
2016-03-10 11:51:46 -05:00
|
|
|
|
2019-10-02 10:49:28 -04:00
|
|
|
typedef enum
|
|
|
|
{
|
|
|
|
EVENTS_UNFREEZE_SYNC,
|
|
|
|
EVENTS_UNFREEZE_REPLAY,
|
|
|
|
} EventsUnfreezeMethod;
|
|
|
|
|
2023-08-02 14:30:30 -04:00
|
|
|
static ClutterStage *
|
|
|
|
stage_from_display (MetaDisplay *display)
|
2016-03-10 11:51:46 -05:00
|
|
|
{
|
2022-04-27 06:12:33 -04:00
|
|
|
MetaContext *context = meta_display_get_context (display);
|
|
|
|
MetaBackend *backend = meta_context_get_backend (context);
|
2016-03-10 11:51:46 -05:00
|
|
|
|
2023-08-02 14:30:30 -04:00
|
|
|
return CLUTTER_STAGE (meta_backend_get_stage (backend));
|
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
stage_has_key_focus (MetaDisplay *display)
|
|
|
|
{
|
|
|
|
ClutterStage *stage = stage_from_display (display);
|
|
|
|
|
|
|
|
return clutter_stage_get_key_focus (stage) == CLUTTER_ACTOR (stage);
|
2016-03-10 11:51:46 -05:00
|
|
|
}
|
|
|
|
|
2021-11-17 17:31:11 -05:00
|
|
|
static gboolean
|
|
|
|
stage_has_grab (MetaDisplay *display)
|
|
|
|
{
|
2023-08-02 14:30:30 -04:00
|
|
|
ClutterStage *stage = stage_from_display (display);
|
2021-11-17 17:31:11 -05:00
|
|
|
|
2023-08-02 14:30:30 -04:00
|
|
|
return clutter_stage_get_grab_actor (stage) != NULL;
|
2021-11-17 17:31:11 -05:00
|
|
|
}
|
|
|
|
|
2014-06-11 16:08:33 -04:00
|
|
|
static MetaWindow *
|
|
|
|
get_window_for_event (MetaDisplay *display,
|
2022-03-05 17:46:24 -05:00
|
|
|
const ClutterEvent *event,
|
|
|
|
ClutterActor *event_actor)
|
2014-03-20 15:29:30 -04:00
|
|
|
{
|
2022-10-21 06:56:24 -04:00
|
|
|
MetaWindowActor *window_actor;
|
|
|
|
|
|
|
|
if (stage_has_grab (display))
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
/* Always use the key focused window for key events. */
|
2023-08-04 06:29:27 -04:00
|
|
|
if (IS_KEY_EVENT (clutter_event_type (event)))
|
2014-03-20 15:29:30 -04:00
|
|
|
{
|
2022-10-21 06:56:24 -04:00
|
|
|
return stage_has_key_focus (display) ? display->focus_window
|
|
|
|
: NULL;
|
2014-03-20 15:29:30 -04:00
|
|
|
}
|
2022-10-21 06:56:24 -04:00
|
|
|
|
|
|
|
window_actor = meta_window_actor_from_actor (event_actor);
|
|
|
|
if (window_actor)
|
|
|
|
return meta_window_actor_get_meta_window (window_actor);
|
|
|
|
else
|
|
|
|
return NULL;
|
2014-03-20 15:29:30 -04:00
|
|
|
}
|
|
|
|
|
2014-03-30 20:50:03 -04:00
|
|
|
static void
|
2022-04-27 06:12:33 -04:00
|
|
|
handle_idletime_for_event (MetaDisplay *display,
|
|
|
|
const ClutterEvent *event)
|
2014-03-30 20:50:03 -04:00
|
|
|
{
|
2022-04-27 06:12:33 -04:00
|
|
|
MetaContext *context = meta_display_get_context (display);
|
|
|
|
MetaBackend *backend = meta_context_get_backend (context);
|
2021-04-19 09:22:57 -04:00
|
|
|
MetaIdleManager *idle_manager;
|
2023-08-04 06:29:27 -04:00
|
|
|
ClutterEventType event_type;
|
|
|
|
ClutterEventFlags flags;
|
2014-03-30 20:50:03 -04:00
|
|
|
|
2020-02-05 10:42:26 -05:00
|
|
|
if (clutter_event_get_device (event) == NULL)
|
2018-03-20 05:59:04 -04:00
|
|
|
return;
|
2015-04-27 13:01:51 -04:00
|
|
|
|
2023-08-04 06:29:27 -04:00
|
|
|
flags = clutter_event_get_flags (event);
|
|
|
|
event_type = clutter_event_type (event);
|
|
|
|
|
|
|
|
if (flags & CLUTTER_EVENT_FLAG_SYNTHETIC ||
|
|
|
|
event_type == CLUTTER_ENTER ||
|
|
|
|
event_type == CLUTTER_LEAVE)
|
2018-03-20 05:59:04 -04:00
|
|
|
return;
|
2014-05-29 12:06:09 -04:00
|
|
|
|
2021-04-19 09:22:57 -04:00
|
|
|
idle_manager = meta_backend_get_idle_manager (backend);
|
|
|
|
meta_idle_manager_reset_idle_time (idle_manager);
|
2014-03-30 20:50:03 -04:00
|
|
|
}
|
|
|
|
|
2014-07-21 19:14:14 -04:00
|
|
|
static gboolean
|
|
|
|
sequence_is_pointer_emulated (MetaDisplay *display,
|
|
|
|
const ClutterEvent *event)
|
|
|
|
{
|
|
|
|
ClutterEventSequence *sequence;
|
|
|
|
|
|
|
|
sequence = clutter_event_get_event_sequence (event);
|
|
|
|
|
|
|
|
if (!sequence)
|
|
|
|
return FALSE;
|
|
|
|
|
2023-07-21 12:44:17 -04:00
|
|
|
if (clutter_event_get_flags (event) & CLUTTER_EVENT_FLAG_POINTER_EMULATED)
|
2014-07-21 19:14:14 -04:00
|
|
|
return TRUE;
|
|
|
|
|
2014-07-24 14:52:04 -04:00
|
|
|
#ifdef HAVE_NATIVE_BACKEND
|
2022-04-27 06:12:33 -04:00
|
|
|
MetaContext *context = meta_display_get_context (display);
|
|
|
|
MetaBackend *backend = meta_context_get_backend (context);
|
2014-07-21 19:14:14 -04:00
|
|
|
|
|
|
|
/* When using Clutter's native input backend there is no concept of
|
|
|
|
* pointer emulating sequence, we still must make up our own to be
|
|
|
|
* able to implement single-touch (hence pointer alike) behavior.
|
|
|
|
*
|
|
|
|
* This is implemented similarly to X11, where only the first touch
|
|
|
|
* on screen gets the "pointer emulated" flag, and it won't get assigned
|
|
|
|
* to another sequence until the next first touch on an idle touchscreen.
|
|
|
|
*/
|
|
|
|
if (META_IS_BACKEND_NATIVE (backend))
|
|
|
|
{
|
|
|
|
MetaGestureTracker *tracker;
|
|
|
|
|
|
|
|
tracker = meta_display_get_gesture_tracker (display);
|
|
|
|
|
2023-08-04 06:29:27 -04:00
|
|
|
if (clutter_event_type (event) == CLUTTER_TOUCH_BEGIN &&
|
2014-07-21 19:14:14 -04:00
|
|
|
meta_gesture_tracker_get_n_current_touches (tracker) == 0)
|
|
|
|
return TRUE;
|
|
|
|
}
|
2014-07-24 14:52:04 -04:00
|
|
|
#endif /* HAVE_NATIVE_BACKEND */
|
2014-07-21 19:14:14 -04:00
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2022-06-01 04:06:55 -04:00
|
|
|
#ifdef HAVE_X11_CLIENT
|
2019-10-02 10:49:28 -04:00
|
|
|
static void
|
|
|
|
maybe_unfreeze_pointer_events (MetaBackend *backend,
|
|
|
|
const ClutterEvent *event,
|
|
|
|
EventsUnfreezeMethod unfreeze_method)
|
|
|
|
{
|
2020-11-17 08:49:31 -05:00
|
|
|
ClutterInputDevice *device;
|
2019-10-02 10:49:28 -04:00
|
|
|
Display *xdisplay;
|
|
|
|
int event_mode;
|
|
|
|
int device_id;
|
2023-08-04 06:29:27 -04:00
|
|
|
uint32_t time_ms;
|
2019-10-02 10:49:28 -04:00
|
|
|
|
2023-08-04 06:29:27 -04:00
|
|
|
if (clutter_event_type (event) != CLUTTER_BUTTON_PRESS)
|
2019-10-02 10:49:28 -04:00
|
|
|
return;
|
|
|
|
|
|
|
|
if (!META_IS_BACKEND_X11 (backend))
|
|
|
|
return;
|
|
|
|
|
2020-11-17 08:49:31 -05:00
|
|
|
device = clutter_event_get_device (event);
|
2020-11-17 08:59:42 -05:00
|
|
|
device_id = meta_input_device_x11_get_device_id (device);
|
2023-08-04 06:29:27 -04:00
|
|
|
time_ms = clutter_event_get_time (event);
|
2019-10-02 10:49:28 -04:00
|
|
|
switch (unfreeze_method)
|
|
|
|
{
|
|
|
|
case EVENTS_UNFREEZE_SYNC:
|
|
|
|
event_mode = XISyncDevice;
|
2020-10-02 11:47:22 -04:00
|
|
|
meta_verbose ("Syncing events time %u device %i",
|
2023-08-04 06:29:27 -04:00
|
|
|
(unsigned int) time_ms, device_id);
|
2019-10-02 10:49:28 -04:00
|
|
|
break;
|
|
|
|
case EVENTS_UNFREEZE_REPLAY:
|
|
|
|
event_mode = XIReplayDevice;
|
2020-10-02 11:47:22 -04:00
|
|
|
meta_verbose ("Replaying events time %u device %i",
|
2023-08-04 06:29:27 -04:00
|
|
|
(unsigned int) time_ms, device_id);
|
2019-10-02 10:49:28 -04:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
g_assert_not_reached ();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
xdisplay = meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend));
|
2023-08-04 06:29:27 -04:00
|
|
|
XIAllowEvents (xdisplay, device_id, event_mode, time_ms);
|
2019-10-02 10:49:28 -04:00
|
|
|
}
|
2022-06-01 04:06:55 -04:00
|
|
|
#endif
|
2019-10-02 10:49:28 -04:00
|
|
|
|
2014-03-20 15:29:30 -04:00
|
|
|
static gboolean
|
|
|
|
meta_display_handle_event (MetaDisplay *display,
|
2022-03-05 17:43:29 -05:00
|
|
|
const ClutterEvent *event,
|
|
|
|
ClutterActor *event_actor)
|
2014-03-20 15:29:30 -04:00
|
|
|
{
|
2022-04-27 06:12:33 -04:00
|
|
|
MetaContext *context = meta_display_get_context (display);
|
|
|
|
MetaBackend *backend = meta_context_get_backend (context);
|
2022-10-21 06:56:24 -04:00
|
|
|
MetaCompositor *compositor = meta_display_get_compositor (display);
|
2022-04-27 06:12:33 -04:00
|
|
|
ClutterInputDevice *device;
|
2021-09-03 17:38:12 -04:00
|
|
|
MetaWindow *window = NULL;
|
2014-08-13 20:19:35 -04:00
|
|
|
gboolean bypass_clutter = FALSE;
|
|
|
|
G_GNUC_UNUSED gboolean bypass_wayland = FALSE;
|
2016-11-29 07:22:02 -05:00
|
|
|
MetaGestureTracker *gesture_tracker;
|
2014-10-13 10:20:28 -04:00
|
|
|
ClutterEventSequence *sequence;
|
2023-08-04 06:29:27 -04:00
|
|
|
ClutterEventType event_type;
|
2021-11-17 17:31:11 -05:00
|
|
|
gboolean has_grab;
|
2023-08-04 06:29:27 -04:00
|
|
|
uint32_t time_ms;
|
2022-05-27 16:27:07 -04:00
|
|
|
#ifdef HAVE_WAYLAND
|
|
|
|
MetaWaylandCompositor *wayland_compositor;
|
2023-06-07 06:58:36 -04:00
|
|
|
MetaWaylandTextInput *wayland_text_input = NULL;
|
2022-05-27 16:27:07 -04:00
|
|
|
#endif
|
2021-11-17 17:31:11 -05:00
|
|
|
|
2022-02-23 10:13:17 -05:00
|
|
|
#ifdef HAVE_WAYLAND
|
2022-05-27 16:27:07 -04:00
|
|
|
wayland_compositor = meta_context_get_wayland_compositor (context);
|
2023-06-07 06:58:36 -04:00
|
|
|
if (wayland_compositor)
|
|
|
|
{
|
|
|
|
wayland_text_input =
|
|
|
|
meta_wayland_compositor_get_text_input (wayland_compositor);
|
|
|
|
}
|
2022-02-23 10:13:17 -05:00
|
|
|
#endif
|
|
|
|
|
2022-12-20 05:28:06 -05:00
|
|
|
COGL_TRACE_BEGIN_SCOPED (MetaDisplayHandleEvent,
|
2023-11-15 23:28:23 -05:00
|
|
|
"Meta::Display::handle_event()");
|
2023-10-15 03:49:08 -04:00
|
|
|
COGL_TRACE_DESCRIBE (MetaDisplayHandleEvent,
|
|
|
|
clutter_event_get_name (event));
|
2022-12-20 05:28:06 -05:00
|
|
|
|
2021-11-17 17:31:11 -05:00
|
|
|
has_grab = stage_has_grab (display);
|
|
|
|
|
2023-08-04 06:29:27 -04:00
|
|
|
sequence = clutter_event_get_event_sequence (event);
|
|
|
|
event_type = clutter_event_type (event);
|
|
|
|
time_ms = clutter_event_get_time (event);
|
|
|
|
|
2022-04-27 04:50:43 -04:00
|
|
|
if (meta_display_process_captured_input (display, event))
|
|
|
|
{
|
|
|
|
bypass_clutter = TRUE;
|
|
|
|
bypass_wayland = TRUE;
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
2022-04-27 06:12:33 -04:00
|
|
|
device = clutter_event_get_device (event);
|
|
|
|
clutter_input_pointer_a11y_update (device, event);
|
|
|
|
|
2014-10-13 10:20:28 -04:00
|
|
|
/* Set the pointer emulating sequence on touch begin, if eligible */
|
2023-08-04 06:29:27 -04:00
|
|
|
if (event_type == CLUTTER_TOUCH_BEGIN)
|
2015-10-16 09:13:40 -04:00
|
|
|
{
|
|
|
|
if (sequence_is_pointer_emulated (display, event))
|
|
|
|
{
|
|
|
|
/* This is the new pointer emulating sequence */
|
|
|
|
display->pointer_emulating_sequence = sequence;
|
|
|
|
}
|
|
|
|
else if (display->pointer_emulating_sequence == sequence)
|
|
|
|
{
|
|
|
|
/* This sequence was "pointer emulating" in a prior incarnation,
|
|
|
|
* but now it isn't. We unset the pointer emulating sequence at
|
|
|
|
* this point so the current sequence is not mistaken as pointer
|
|
|
|
* emulating, while we've ensured that it's been deemed
|
|
|
|
* "pointer emulating" throughout all of the event processing
|
|
|
|
* of the previous incarnation.
|
|
|
|
*/
|
|
|
|
display->pointer_emulating_sequence = NULL;
|
|
|
|
}
|
|
|
|
}
|
2014-07-21 19:14:14 -04:00
|
|
|
|
2014-08-13 20:19:35 -04:00
|
|
|
#ifdef HAVE_WAYLAND
|
2023-06-07 06:58:36 -04:00
|
|
|
if (wayland_text_input &&
|
|
|
|
!has_grab &&
|
|
|
|
!meta_compositor_get_current_window_drag (compositor) &&
|
|
|
|
meta_wayland_text_input_update (wayland_text_input, event))
|
|
|
|
{
|
|
|
|
bypass_wayland = bypass_clutter = TRUE;
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
2022-02-23 10:13:17 -05:00
|
|
|
if (wayland_compositor)
|
|
|
|
meta_wayland_compositor_update (wayland_compositor, event);
|
2014-08-13 20:19:35 -04:00
|
|
|
#endif
|
2014-03-20 15:29:30 -04:00
|
|
|
|
2023-08-04 06:29:27 -04:00
|
|
|
if (event_type == CLUTTER_PAD_BUTTON_PRESS ||
|
|
|
|
event_type == CLUTTER_PAD_BUTTON_RELEASE ||
|
|
|
|
event_type == CLUTTER_PAD_RING ||
|
|
|
|
event_type == CLUTTER_PAD_STRIP)
|
2016-10-25 11:01:37 -04:00
|
|
|
{
|
2019-12-16 07:53:26 -05:00
|
|
|
gboolean handle_pad_event;
|
|
|
|
gboolean is_mode_switch = FALSE;
|
|
|
|
|
2023-08-04 06:29:27 -04:00
|
|
|
if (event_type == CLUTTER_PAD_BUTTON_PRESS ||
|
|
|
|
event_type == CLUTTER_PAD_BUTTON_RELEASE)
|
2019-12-16 07:53:26 -05:00
|
|
|
{
|
|
|
|
ClutterInputDevice *pad;
|
|
|
|
uint32_t button;
|
|
|
|
|
|
|
|
pad = clutter_event_get_source_device (event);
|
|
|
|
button = clutter_event_get_button (event);
|
|
|
|
|
|
|
|
is_mode_switch =
|
|
|
|
clutter_input_device_get_mode_switch_button_group (pad, button) >= 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
handle_pad_event = !display->current_pad_osd || is_mode_switch;
|
|
|
|
|
|
|
|
if (handle_pad_event &&
|
2020-07-15 16:38:00 -04:00
|
|
|
meta_pad_action_mapper_handle_event (display->pad_action_mapper, event))
|
2016-10-25 11:01:37 -04:00
|
|
|
{
|
|
|
|
bypass_wayland = bypass_clutter = TRUE;
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-08-04 06:29:27 -04:00
|
|
|
if (event_type != CLUTTER_DEVICE_ADDED &&
|
|
|
|
event_type != CLUTTER_DEVICE_REMOVED)
|
2022-04-27 06:12:33 -04:00
|
|
|
handle_idletime_for_event (display, event);
|
2023-11-07 07:21:39 -05:00
|
|
|
else
|
|
|
|
meta_pad_action_mapper_handle_event (display->pad_action_mapper, event);
|
2015-02-11 09:03:25 -05:00
|
|
|
|
2023-08-04 06:29:27 -04:00
|
|
|
if (event_type == CLUTTER_MOTION)
|
2014-08-21 16:57:27 -04:00
|
|
|
{
|
2020-07-13 08:09:44 -04:00
|
|
|
ClutterInputDevice *device;
|
2015-01-09 11:31:02 -05:00
|
|
|
|
2020-07-13 08:09:44 -04:00
|
|
|
device = clutter_event_get_device (event);
|
2022-09-15 04:02:08 -04:00
|
|
|
|
|
|
|
#ifdef HAVE_WAYLAND
|
|
|
|
if (wayland_compositor)
|
|
|
|
{
|
|
|
|
MetaCursorRenderer *cursor_renderer =
|
|
|
|
meta_backend_get_cursor_renderer_for_device (backend, device);
|
|
|
|
|
|
|
|
if (cursor_renderer)
|
|
|
|
meta_cursor_renderer_update_position (cursor_renderer);
|
|
|
|
}
|
|
|
|
#endif
|
2015-01-09 11:31:02 -05:00
|
|
|
|
2020-07-13 08:09:44 -04:00
|
|
|
if (device == clutter_seat_get_pointer (clutter_input_device_get_seat (device)))
|
2015-01-09 11:31:02 -05:00
|
|
|
{
|
2016-11-29 07:30:22 -05:00
|
|
|
MetaCursorTracker *cursor_tracker =
|
|
|
|
meta_backend_get_cursor_tracker (backend);
|
2016-11-29 07:22:02 -05:00
|
|
|
|
2020-07-13 08:09:44 -04:00
|
|
|
meta_cursor_tracker_invalidate_position (cursor_tracker);
|
2015-01-09 11:31:02 -05:00
|
|
|
}
|
2014-08-21 16:57:27 -04:00
|
|
|
}
|
|
|
|
|
2022-03-05 17:46:24 -05:00
|
|
|
window = get_window_for_event (display, event, event_actor);
|
2014-03-20 15:29:30 -04:00
|
|
|
|
2023-08-04 06:29:27 -04:00
|
|
|
display->current_time = time_ms;
|
2014-03-20 15:29:30 -04:00
|
|
|
|
|
|
|
if (window && !window->override_redirect &&
|
2023-08-04 06:29:27 -04:00
|
|
|
(event_type == CLUTTER_KEY_PRESS ||
|
|
|
|
event_type == CLUTTER_BUTTON_PRESS ||
|
|
|
|
event_type == CLUTTER_TOUCH_BEGIN))
|
2014-03-20 15:29:30 -04:00
|
|
|
{
|
2017-08-26 16:24:21 -04:00
|
|
|
if (META_CURRENT_TIME == display->current_time)
|
2014-03-20 15:29:30 -04:00
|
|
|
{
|
|
|
|
/* We can't use missing (i.e. invalid) timestamps to set user time,
|
|
|
|
* nor do we want to use them to sanity check other timestamps.
|
|
|
|
* See bug 313490 for more details.
|
|
|
|
*/
|
|
|
|
meta_warning ("Event has no timestamp! You may be using a broken "
|
|
|
|
"program such as xse. Please ask the authors of that "
|
2020-10-02 11:47:22 -04:00
|
|
|
"program to fix it.");
|
2014-03-20 15:29:30 -04:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
meta_window_set_user_time (window, display->current_time);
|
|
|
|
meta_display_sanity_check_timestamps (display, display->current_time);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-11-29 07:22:02 -05:00
|
|
|
gesture_tracker = meta_display_get_gesture_tracker (display);
|
2014-06-19 17:10:33 -04:00
|
|
|
|
2023-08-02 14:30:30 -04:00
|
|
|
if (meta_gesture_tracker_handle_event (gesture_tracker,
|
|
|
|
stage_from_display (display),
|
|
|
|
event))
|
2014-06-19 17:10:33 -04:00
|
|
|
{
|
2022-04-03 21:22:12 -04:00
|
|
|
bypass_wayland = TRUE;
|
|
|
|
bypass_clutter = FALSE;
|
2014-06-19 17:10:33 -04:00
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
2014-05-08 14:53:50 -04:00
|
|
|
/* For key events, it's important to enforce single-handling, or
|
|
|
|
* we can get into a confused state. So if a keybinding is
|
|
|
|
* handled (because it's one of our hot-keys, or because we are
|
|
|
|
* in a keyboard-grabbed mode like moving a window, we don't
|
|
|
|
* want to pass the key event to the compositor or Wayland at all.
|
|
|
|
*/
|
2022-10-21 06:56:24 -04:00
|
|
|
if (!meta_compositor_get_current_window_drag (compositor) &&
|
|
|
|
meta_keybindings_process_event (display, window, event))
|
2014-05-08 14:53:50 -04:00
|
|
|
{
|
|
|
|
bypass_clutter = TRUE;
|
|
|
|
bypass_wayland = TRUE;
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
2016-03-10 11:51:46 -05:00
|
|
|
/* Do not pass keyboard events to Wayland if key focus is not on the
|
|
|
|
* stage in normal mode (e.g. during keynav in the panel)
|
|
|
|
*/
|
2022-10-21 06:56:24 -04:00
|
|
|
if (!has_grab)
|
2016-03-10 11:51:46 -05:00
|
|
|
{
|
2023-08-04 06:29:27 -04:00
|
|
|
if (IS_KEY_EVENT (event_type) && !stage_has_key_focus (display))
|
2016-03-10 11:51:46 -05:00
|
|
|
{
|
|
|
|
bypass_wayland = TRUE;
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-07-07 16:40:33 -04:00
|
|
|
if (meta_is_wayland_compositor () &&
|
2023-08-04 06:29:27 -04:00
|
|
|
event_type == CLUTTER_SCROLL &&
|
2021-07-07 16:40:33 -04:00
|
|
|
meta_prefs_get_mouse_button_mods () > 0)
|
2021-01-30 06:25:26 -05:00
|
|
|
{
|
|
|
|
ClutterModifierType grab_mods;
|
|
|
|
|
|
|
|
grab_mods = meta_display_get_compositor_modifiers (display);
|
|
|
|
if ((clutter_event_get_state (event) & grab_mods) != 0)
|
|
|
|
{
|
|
|
|
bypass_wayland = TRUE;
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-06-29 07:51:55 -04:00
|
|
|
if (display->current_pad_osd)
|
|
|
|
{
|
|
|
|
bypass_wayland = TRUE;
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
2021-11-17 17:31:11 -05:00
|
|
|
if (stage_has_grab (display))
|
|
|
|
{
|
|
|
|
bypass_wayland = TRUE;
|
|
|
|
bypass_clutter = FALSE;
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
2014-05-08 15:12:58 -04:00
|
|
|
if (window)
|
2014-03-20 15:29:30 -04:00
|
|
|
{
|
2015-07-01 09:49:33 -04:00
|
|
|
/* Events that are likely to trigger compositor gestures should
|
|
|
|
* be known to clutter so they can propagate along the hierarchy.
|
|
|
|
* Gesture-wise, there's two groups of events we should be getting
|
|
|
|
* here:
|
|
|
|
* - CLUTTER_TOUCH_* with a touch sequence that's not yet accepted
|
|
|
|
* by the gesture tracker, these might trigger gesture actions
|
|
|
|
* into recognition. Already accepted touch sequences are handled
|
|
|
|
* directly by meta_gesture_tracker_handle_event().
|
|
|
|
* - CLUTTER_TOUCHPAD_* events over windows. These can likewise
|
|
|
|
* trigger ::captured-event handlers along the way.
|
|
|
|
*/
|
2023-08-04 06:29:27 -04:00
|
|
|
bypass_clutter = !IS_GESTURE_EVENT (event_type);
|
2022-09-28 08:03:05 -04:00
|
|
|
|
2023-11-17 17:35:41 -05:00
|
|
|
meta_window_handle_ungrabbed_event (window, event);
|
2014-08-15 08:29:16 -04:00
|
|
|
|
|
|
|
/* This might start a grab op. If it does, then filter out the
|
|
|
|
* event, and if it doesn't, replay the event to release our
|
|
|
|
* own sync grab. */
|
|
|
|
|
2022-10-21 06:56:24 -04:00
|
|
|
if (meta_compositor_get_current_window_drag (compositor))
|
2014-05-08 15:09:20 -04:00
|
|
|
{
|
2014-08-15 08:29:16 -04:00
|
|
|
bypass_clutter = TRUE;
|
2014-05-08 15:05:25 -04:00
|
|
|
bypass_wayland = TRUE;
|
2014-03-20 15:29:30 -04:00
|
|
|
}
|
2014-08-15 08:29:16 -04:00
|
|
|
else
|
2014-05-08 15:09:20 -04:00
|
|
|
{
|
2014-08-15 08:29:16 -04:00
|
|
|
/* Only replay button press events, since that's where we
|
|
|
|
* have the synchronous grab. */
|
2022-06-01 04:06:55 -04:00
|
|
|
#ifdef HAVE_X11_CLIENT
|
2019-10-02 10:49:28 -04:00
|
|
|
maybe_unfreeze_pointer_events (backend, event, EVENTS_UNFREEZE_REPLAY);
|
2022-06-01 04:06:55 -04:00
|
|
|
#endif
|
2017-05-27 12:42:39 -04:00
|
|
|
/* If the focus window has an active close dialog let clutter
|
|
|
|
* events go through, so fancy clutter dialogs can get to handle
|
|
|
|
* all events.
|
|
|
|
*/
|
|
|
|
if (window->close_dialog &&
|
|
|
|
meta_close_dialog_is_visible (window->close_dialog))
|
|
|
|
{
|
|
|
|
bypass_wayland = TRUE;
|
|
|
|
bypass_clutter = FALSE;
|
|
|
|
}
|
2014-05-08 15:09:20 -04:00
|
|
|
}
|
2014-05-08 15:12:58 -04:00
|
|
|
|
|
|
|
goto out;
|
2014-03-20 15:29:30 -04:00
|
|
|
}
|
2019-10-02 10:49:28 -04:00
|
|
|
else
|
|
|
|
{
|
|
|
|
/* We could not match the event with a window, make sure we sync
|
|
|
|
* the pointer to discard the sequence and don't keep events frozen.
|
|
|
|
*/
|
2022-06-01 04:06:55 -04:00
|
|
|
#ifdef HAVE_X11_CLIENT
|
|
|
|
maybe_unfreeze_pointer_events (backend, event, EVENTS_UNFREEZE_SYNC);
|
|
|
|
#endif
|
2019-10-02 10:49:28 -04:00
|
|
|
}
|
2014-03-20 15:29:30 -04:00
|
|
|
|
2014-04-21 11:21:19 -04:00
|
|
|
out:
|
2022-09-29 09:32:23 -04:00
|
|
|
#ifdef HAVE_WAYLAND
|
2022-02-23 10:13:17 -05:00
|
|
|
if (wayland_compositor && !bypass_wayland)
|
2014-03-20 15:29:30 -04:00
|
|
|
{
|
2023-08-04 06:29:27 -04:00
|
|
|
if (window && event_type == CLUTTER_MOTION &&
|
|
|
|
time_ms != CLUTTER_CURRENT_TIME)
|
|
|
|
meta_window_check_alive_on_event (window, time_ms);
|
2021-09-03 17:38:12 -04:00
|
|
|
|
2022-02-23 10:13:17 -05:00
|
|
|
if (meta_wayland_compositor_handle_event (wayland_compositor, event))
|
2014-03-20 15:29:30 -04:00
|
|
|
bypass_clutter = TRUE;
|
|
|
|
}
|
2014-08-13 20:19:35 -04:00
|
|
|
#endif
|
2014-03-20 15:29:30 -04:00
|
|
|
|
2017-08-26 16:24:21 -04:00
|
|
|
display->current_time = META_CURRENT_TIME;
|
2014-03-20 15:29:30 -04:00
|
|
|
return bypass_clutter;
|
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
event_callback (const ClutterEvent *event,
|
2022-03-05 17:43:29 -05:00
|
|
|
ClutterActor *event_actor,
|
2014-03-20 15:29:30 -04:00
|
|
|
gpointer data)
|
|
|
|
{
|
|
|
|
MetaDisplay *display = data;
|
|
|
|
|
2022-03-05 17:43:29 -05:00
|
|
|
return meta_display_handle_event (display, event, event_actor);
|
2014-03-20 15:29:30 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2014-08-15 13:47:57 -04:00
|
|
|
meta_display_init_events (MetaDisplay *display)
|
2014-03-20 15:29:30 -04:00
|
|
|
{
|
|
|
|
display->clutter_event_filter = clutter_event_add_filter (NULL,
|
|
|
|
event_callback,
|
|
|
|
NULL,
|
|
|
|
display);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
meta_display_free_events (MetaDisplay *display)
|
|
|
|
{
|
|
|
|
clutter_event_remove_filter (display->clutter_event_filter);
|
|
|
|
display->clutter_event_filter = 0;
|
|
|
|
}
|