Compare commits
15 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
dc75c7d297 | ||
![]() |
33c008b90a | ||
![]() |
98a0c5cb35 | ||
![]() |
b425f11536 | ||
![]() |
a1bc2e0adc | ||
![]() |
63fc71f05b | ||
![]() |
31307720bf | ||
![]() |
cb7ba2e90f | ||
![]() |
ba1f4221e9 | ||
![]() |
6e6183ec08 | ||
![]() |
493aeb65c8 | ||
![]() |
36f5a0a491 | ||
![]() |
3daf912449 | ||
![]() |
fadfca2e16 | ||
![]() |
b1df6d08a5 |
12
NEWS
12
NEWS
@@ -1,3 +1,15 @@
|
||||
3.36.3
|
||||
======
|
||||
* Broadcast clipboard/primary offers [Carlos; !1262]
|
||||
* Fix monitor screen cast on X11 [Jonas Å.; !1251]
|
||||
* Implement touch-mode detecation for the X11 backend [Carlos; !1278]
|
||||
* Drop external keyboard detection from touch-mode heuristics [Carlos; !1277]
|
||||
* Fix leaked DMA buffers in screencasts [Jonas; !1283]
|
||||
* Fixed crashes [Daniel, Carlos, Jonas D.; !1256, !1258, !1280]
|
||||
|
||||
Contributors:
|
||||
Carlos Garnacho, Daniel van Vugt, Jonas Ådahl
|
||||
|
||||
3.36.2
|
||||
======
|
||||
* Sync timelines to hardware vsync [Daniel; !724]
|
||||
|
@@ -2604,6 +2604,9 @@ clutter_actor_set_allocation_internal (ClutterActor *self,
|
||||
gboolean retval;
|
||||
ClutterActorBox old_alloc = { 0, };
|
||||
|
||||
g_return_val_if_fail (!isnan (box->x1) && !isnan (box->x2) &&
|
||||
!isnan (box->y1) && !isnan (box->y2), FALSE);
|
||||
|
||||
obj = G_OBJECT (self);
|
||||
|
||||
g_object_freeze_notify (obj);
|
||||
@@ -10366,6 +10369,11 @@ clutter_actor_allocate (ClutterActor *self,
|
||||
old_allocation = priv->allocation;
|
||||
real_allocation = *box;
|
||||
|
||||
g_return_if_fail (!isnan (real_allocation.x1) &&
|
||||
!isnan (real_allocation.x2) &&
|
||||
!isnan (real_allocation.y1) &&
|
||||
!isnan (real_allocation.y2));
|
||||
|
||||
/* constraints are allowed to modify the allocation only here; we do
|
||||
* this prior to all the other checks so that we can bail out if the
|
||||
* allocation did not change
|
||||
|
@@ -682,7 +682,6 @@ clutter_seat_warp_pointer (ClutterSeat *seat,
|
||||
* requirements are fulfilled:
|
||||
*
|
||||
* - A touchscreen is available
|
||||
* - No external keyboard is attached to the device
|
||||
* - A tablet mode switch, if present, is enabled
|
||||
*
|
||||
* Returns: %TRUE if the device is a tablet that doesn't have an external
|
||||
|
@@ -1,5 +1,5 @@
|
||||
project('mutter', 'c',
|
||||
version: '3.36.2',
|
||||
version: '3.36.3',
|
||||
meson_version: '>= 0.50.0',
|
||||
license: 'GPLv2+'
|
||||
)
|
||||
|
@@ -55,6 +55,7 @@ struct _MetaRemoteDesktopSession
|
||||
|
||||
MetaScreenCastSession *screen_cast_session;
|
||||
gulong screen_cast_session_closed_handler_id;
|
||||
guint started : 1;
|
||||
|
||||
ClutterVirtualInputDevice *virtual_pointer;
|
||||
ClutterVirtualInputDevice *virtual_keyboard;
|
||||
@@ -119,7 +120,7 @@ meta_remote_desktop_session_start (MetaRemoteDesktopSession *session,
|
||||
ClutterBackend *backend = clutter_get_default_backend ();
|
||||
ClutterSeat *seat = clutter_backend_get_default_seat (backend);
|
||||
|
||||
g_assert (!session->virtual_pointer && !session->virtual_keyboard);
|
||||
g_assert (!session->started);
|
||||
|
||||
if (session->screen_cast_session)
|
||||
{
|
||||
@@ -135,6 +136,7 @@ meta_remote_desktop_session_start (MetaRemoteDesktopSession *session,
|
||||
clutter_seat_create_virtual_device (seat, CLUTTER_TOUCHSCREEN_DEVICE);
|
||||
|
||||
init_remote_access_handle (session);
|
||||
session->started = TRUE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -145,6 +147,8 @@ meta_remote_desktop_session_close (MetaRemoteDesktopSession *session)
|
||||
MetaDBusRemoteDesktopSession *skeleton =
|
||||
META_DBUS_REMOTE_DESKTOP_SESSION (session);
|
||||
|
||||
session->started = FALSE;
|
||||
|
||||
if (session->screen_cast_session)
|
||||
{
|
||||
g_clear_signal_handler (&session->screen_cast_session_closed_handler_id,
|
||||
@@ -249,6 +253,37 @@ check_permission (MetaRemoteDesktopSession *session,
|
||||
g_dbus_method_invocation_get_sender (invocation)) == 0;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
meta_remote_desktop_session_check_can_notify (MetaRemoteDesktopSession *session,
|
||||
GDBusMethodInvocation *invocation)
|
||||
{
|
||||
if (!session->started)
|
||||
{
|
||||
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
|
||||
G_DBUS_ERROR_FAILED,
|
||||
"Session not started");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!check_permission (session, invocation))
|
||||
{
|
||||
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
|
||||
G_DBUS_ERROR_ACCESS_DENIED,
|
||||
"Permission denied");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!session->screen_cast_session)
|
||||
{
|
||||
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
|
||||
G_DBUS_ERROR_FAILED,
|
||||
"No screen cast active");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
handle_start (MetaDBusRemoteDesktopSession *skeleton,
|
||||
GDBusMethodInvocation *invocation)
|
||||
@@ -256,6 +291,14 @@ handle_start (MetaDBusRemoteDesktopSession *skeleton,
|
||||
MetaRemoteDesktopSession *session = META_REMOTE_DESKTOP_SESSION (skeleton);
|
||||
GError *error = NULL;
|
||||
|
||||
if (session->started)
|
||||
{
|
||||
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
|
||||
G_DBUS_ERROR_FAILED,
|
||||
"Already started");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (!check_permission (session, invocation))
|
||||
{
|
||||
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
|
||||
@@ -288,6 +331,14 @@ handle_stop (MetaDBusRemoteDesktopSession *skeleton,
|
||||
{
|
||||
MetaRemoteDesktopSession *session = META_REMOTE_DESKTOP_SESSION (skeleton);
|
||||
|
||||
if (!session->started)
|
||||
{
|
||||
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
|
||||
G_DBUS_ERROR_FAILED,
|
||||
"Session not started");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (!check_permission (session, invocation))
|
||||
{
|
||||
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
|
||||
@@ -312,13 +363,8 @@ handle_notify_keyboard_keycode (MetaDBusRemoteDesktopSession *skeleton,
|
||||
MetaRemoteDesktopSession *session = META_REMOTE_DESKTOP_SESSION (skeleton);
|
||||
ClutterKeyState state;
|
||||
|
||||
if (!check_permission (session, invocation))
|
||||
{
|
||||
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
|
||||
G_DBUS_ERROR_ACCESS_DENIED,
|
||||
"Permission denied");
|
||||
return TRUE;
|
||||
}
|
||||
if (!meta_remote_desktop_session_check_can_notify (session, invocation))
|
||||
return TRUE;
|
||||
|
||||
if (pressed)
|
||||
state = CLUTTER_KEY_STATE_PRESSED;
|
||||
@@ -344,13 +390,8 @@ handle_notify_keyboard_keysym (MetaDBusRemoteDesktopSession *skeleton,
|
||||
MetaRemoteDesktopSession *session = META_REMOTE_DESKTOP_SESSION (skeleton);
|
||||
ClutterKeyState state;
|
||||
|
||||
if (!check_permission (session, invocation))
|
||||
{
|
||||
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
|
||||
G_DBUS_ERROR_ACCESS_DENIED,
|
||||
"Permission denied");
|
||||
return TRUE;
|
||||
}
|
||||
if (!meta_remote_desktop_session_check_can_notify (session, invocation))
|
||||
return TRUE;
|
||||
|
||||
if (pressed)
|
||||
state = CLUTTER_KEY_STATE_PRESSED;
|
||||
@@ -398,13 +439,8 @@ handle_notify_pointer_button (MetaDBusRemoteDesktopSession *skeleton,
|
||||
uint32_t button;
|
||||
ClutterButtonState state;
|
||||
|
||||
if (!check_permission (session, invocation))
|
||||
{
|
||||
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
|
||||
G_DBUS_ERROR_ACCESS_DENIED,
|
||||
"Permission denied");
|
||||
return TRUE;
|
||||
}
|
||||
if (!meta_remote_desktop_session_check_can_notify (session, invocation))
|
||||
return TRUE;
|
||||
|
||||
button = translate_to_clutter_button (button_code);
|
||||
|
||||
@@ -434,13 +470,8 @@ handle_notify_pointer_axis (MetaDBusRemoteDesktopSession *skeleton,
|
||||
MetaRemoteDesktopSession *session = META_REMOTE_DESKTOP_SESSION (skeleton);
|
||||
ClutterScrollFinishFlags finish_flags = CLUTTER_SCROLL_FINISHED_NONE;
|
||||
|
||||
if (!check_permission (session, invocation))
|
||||
{
|
||||
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
|
||||
G_DBUS_ERROR_ACCESS_DENIED,
|
||||
"Permission denied");
|
||||
return TRUE;
|
||||
}
|
||||
if (!meta_remote_desktop_session_check_can_notify (session, invocation))
|
||||
return TRUE;
|
||||
|
||||
if (flags & META_REMOTE_DESKTOP_NOTIFY_AXIS_FLAGS_FINISH)
|
||||
{
|
||||
@@ -487,13 +518,8 @@ handle_notify_pointer_axis_discrete (MetaDBusRemoteDesktopSession *skeleton,
|
||||
ClutterScrollDirection direction;
|
||||
int step_count;
|
||||
|
||||
if (!check_permission (session, invocation))
|
||||
{
|
||||
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
|
||||
G_DBUS_ERROR_ACCESS_DENIED,
|
||||
"Permission denied");
|
||||
return TRUE;
|
||||
}
|
||||
if (!meta_remote_desktop_session_check_can_notify (session, invocation))
|
||||
return TRUE;
|
||||
|
||||
if (axis > 1)
|
||||
{
|
||||
@@ -538,13 +564,8 @@ handle_notify_pointer_motion_relative (MetaDBusRemoteDesktopSession *skeleton,
|
||||
{
|
||||
MetaRemoteDesktopSession *session = META_REMOTE_DESKTOP_SESSION (skeleton);
|
||||
|
||||
if (!check_permission (session, invocation))
|
||||
{
|
||||
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
|
||||
G_DBUS_ERROR_ACCESS_DENIED,
|
||||
"Permission denied");
|
||||
return TRUE;
|
||||
}
|
||||
if (!meta_remote_desktop_session_check_can_notify (session, invocation))
|
||||
return TRUE;
|
||||
|
||||
clutter_virtual_input_device_notify_relative_motion (session->virtual_pointer,
|
||||
CLUTTER_CURRENT_TIME,
|
||||
@@ -567,21 +588,8 @@ handle_notify_pointer_motion_absolute (MetaDBusRemoteDesktopSession *skeleton,
|
||||
MetaScreenCastStream *stream;
|
||||
double abs_x, abs_y;
|
||||
|
||||
if (!check_permission (session, invocation))
|
||||
{
|
||||
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
|
||||
G_DBUS_ERROR_ACCESS_DENIED,
|
||||
"Permission denied");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (!session->screen_cast_session)
|
||||
{
|
||||
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
|
||||
G_DBUS_ERROR_FAILED,
|
||||
"No screen cast active");
|
||||
return TRUE;
|
||||
}
|
||||
if (!meta_remote_desktop_session_check_can_notify (session, invocation))
|
||||
return TRUE;
|
||||
|
||||
stream = meta_screen_cast_session_get_stream (session->screen_cast_session,
|
||||
stream_path);
|
||||
@@ -617,21 +625,8 @@ handle_notify_touch_down (MetaDBusRemoteDesktopSession *skeleton,
|
||||
MetaScreenCastStream *stream;
|
||||
double abs_x, abs_y;
|
||||
|
||||
if (!check_permission (session, invocation))
|
||||
{
|
||||
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
|
||||
G_DBUS_ERROR_ACCESS_DENIED,
|
||||
"Permission denied");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (!session->screen_cast_session)
|
||||
{
|
||||
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
|
||||
G_DBUS_ERROR_FAILED,
|
||||
"No screen cast active");
|
||||
return TRUE;
|
||||
}
|
||||
if (!meta_remote_desktop_session_check_can_notify (session, invocation))
|
||||
return TRUE;
|
||||
|
||||
stream = meta_screen_cast_session_get_stream (session->screen_cast_session,
|
||||
stream_path);
|
||||
@@ -668,21 +663,8 @@ handle_notify_touch_motion (MetaDBusRemoteDesktopSession *skeleton,
|
||||
MetaScreenCastStream *stream;
|
||||
double abs_x, abs_y;
|
||||
|
||||
if (!check_permission (session, invocation))
|
||||
{
|
||||
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
|
||||
G_DBUS_ERROR_ACCESS_DENIED,
|
||||
"Permission denied");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (!session->screen_cast_session)
|
||||
{
|
||||
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
|
||||
G_DBUS_ERROR_FAILED,
|
||||
"No screen cast active");
|
||||
return TRUE;
|
||||
}
|
||||
if (!meta_remote_desktop_session_check_can_notify (session, invocation))
|
||||
return TRUE;
|
||||
|
||||
stream = meta_screen_cast_session_get_stream (session->screen_cast_session,
|
||||
stream_path);
|
||||
@@ -714,13 +696,8 @@ handle_notify_touch_up (MetaDBusRemoteDesktopSession *skeleton,
|
||||
{
|
||||
MetaRemoteDesktopSession *session = META_REMOTE_DESKTOP_SESSION (skeleton);
|
||||
|
||||
if (!check_permission (session, invocation))
|
||||
{
|
||||
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
|
||||
G_DBUS_ERROR_ACCESS_DENIED,
|
||||
"Permission denied");
|
||||
return TRUE;
|
||||
}
|
||||
if (!meta_remote_desktop_session_check_can_notify (session, invocation))
|
||||
return TRUE;
|
||||
|
||||
clutter_virtual_input_device_notify_touch_up (session->virtual_touchscreen,
|
||||
CLUTTER_CURRENT_TIME,
|
||||
|
@@ -160,14 +160,12 @@ meta_renderer_real_rebuild_views (MetaRenderer *renderer)
|
||||
}
|
||||
|
||||
void
|
||||
meta_renderer_set_legacy_view (MetaRenderer *renderer,
|
||||
MetaRendererView *legacy_view)
|
||||
meta_renderer_add_view (MetaRenderer *renderer,
|
||||
MetaRendererView *view)
|
||||
{
|
||||
MetaRendererPrivate *priv = meta_renderer_get_instance_private (renderer);
|
||||
|
||||
g_assert (!priv->views);
|
||||
|
||||
priv->views = g_list_append (priv->views, legacy_view);
|
||||
priv->views = g_list_append (priv->views, view);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -54,8 +54,8 @@ CoglRenderer * meta_renderer_create_cogl_renderer (MetaRenderer *renderer);
|
||||
|
||||
void meta_renderer_rebuild_views (MetaRenderer *renderer);
|
||||
|
||||
void meta_renderer_set_legacy_view (MetaRenderer *renderer,
|
||||
MetaRendererView *legacy_view);
|
||||
void meta_renderer_add_view (MetaRenderer *renderer,
|
||||
MetaRendererView *view);
|
||||
|
||||
META_EXPORT_TEST
|
||||
GList * meta_renderer_get_views (MetaRenderer *renderer);
|
||||
|
@@ -68,6 +68,7 @@ typedef struct _MetaPipeWireSource
|
||||
{
|
||||
GSource base;
|
||||
|
||||
MetaScreenCastStreamSrc *src;
|
||||
struct pw_loop *pipewire_loop;
|
||||
} MetaPipeWireSource;
|
||||
|
||||
@@ -81,6 +82,7 @@ typedef struct _MetaScreenCastStreamSrcPrivate
|
||||
struct spa_hook pipewire_core_listener;
|
||||
|
||||
gboolean is_enabled;
|
||||
gboolean emit_closed_after_dispatch;
|
||||
|
||||
struct pw_stream *pipewire_stream;
|
||||
struct spa_hook pipewire_stream_listener;
|
||||
@@ -445,7 +447,8 @@ meta_screen_cast_stream_src_maybe_record_frame (MetaScreenCastStreamSrc *src)
|
||||
uint64_t now_us;
|
||||
|
||||
now_us = g_get_monotonic_time ();
|
||||
if (priv->last_frame_timestamp_us != 0 &&
|
||||
if (priv->video_format.max_framerate.num > 0 &&
|
||||
priv->last_frame_timestamp_us != 0 &&
|
||||
(now_us - priv->last_frame_timestamp_us <
|
||||
((1000000 * priv->video_format.max_framerate.denom) /
|
||||
priv->video_format.max_framerate.num)))
|
||||
@@ -539,12 +542,6 @@ meta_screen_cast_stream_src_disable (MetaScreenCastStreamSrc *src)
|
||||
priv->is_enabled = FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_screen_cast_stream_src_notify_closed (MetaScreenCastStreamSrc *src)
|
||||
{
|
||||
g_signal_emit (src, signals[CLOSED], 0);
|
||||
}
|
||||
|
||||
static void
|
||||
on_stream_state_changed (void *data,
|
||||
enum pw_stream_state old,
|
||||
@@ -559,7 +556,9 @@ on_stream_state_changed (void *data,
|
||||
{
|
||||
case PW_STREAM_STATE_ERROR:
|
||||
g_warning ("pipewire stream error: %s", error_message);
|
||||
meta_screen_cast_stream_src_notify_closed (src);
|
||||
if (meta_screen_cast_stream_src_is_enabled (src))
|
||||
meta_screen_cast_stream_src_disable (src);
|
||||
priv->emit_closed_after_dispatch = TRUE;
|
||||
break;
|
||||
case PW_STREAM_STATE_PAUSED:
|
||||
if (priv->node_id == SPA_ID_INVALID && priv->pipewire_stream)
|
||||
@@ -827,11 +826,17 @@ on_core_error (void *data,
|
||||
const char *message)
|
||||
{
|
||||
MetaScreenCastStreamSrc *src = data;
|
||||
MetaScreenCastStreamSrcPrivate *priv =
|
||||
meta_screen_cast_stream_src_get_instance_private (src);
|
||||
|
||||
g_warning ("pipewire remote error: id:%u %s", id, message);
|
||||
|
||||
if (id == PW_ID_CORE && res == -EPIPE)
|
||||
meta_screen_cast_stream_src_notify_closed (src);
|
||||
{
|
||||
if (meta_screen_cast_stream_src_is_enabled (src))
|
||||
meta_screen_cast_stream_src_disable (src);
|
||||
priv->emit_closed_after_dispatch = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -848,12 +853,18 @@ pipewire_loop_source_dispatch (GSource *source,
|
||||
gpointer user_data)
|
||||
{
|
||||
MetaPipeWireSource *pipewire_source = (MetaPipeWireSource *) source;
|
||||
MetaScreenCastStreamSrc *src = pipewire_source->src;
|
||||
MetaScreenCastStreamSrcPrivate *priv =
|
||||
meta_screen_cast_stream_src_get_instance_private (src);
|
||||
int result;
|
||||
|
||||
result = pw_loop_iterate (pipewire_source->pipewire_loop, 0);
|
||||
if (result < 0)
|
||||
g_warning ("pipewire_loop_iterate failed: %s", spa_strerror (result));
|
||||
|
||||
if (priv->emit_closed_after_dispatch)
|
||||
g_signal_emit (src, signals[CLOSED], 0);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -875,13 +886,14 @@ static GSourceFuncs pipewire_source_funcs =
|
||||
};
|
||||
|
||||
static MetaPipeWireSource *
|
||||
create_pipewire_source (void)
|
||||
create_pipewire_source (MetaScreenCastStreamSrc *src)
|
||||
{
|
||||
MetaPipeWireSource *pipewire_source;
|
||||
|
||||
pipewire_source =
|
||||
(MetaPipeWireSource *) g_source_new (&pipewire_source_funcs,
|
||||
sizeof (MetaPipeWireSource));
|
||||
pipewire_source->src = src;
|
||||
pipewire_source->pipewire_loop = pw_loop_new (NULL);
|
||||
if (!pipewire_source->pipewire_loop)
|
||||
{
|
||||
@@ -913,7 +925,7 @@ meta_screen_cast_stream_src_initable_init (GInitable *initable,
|
||||
MetaScreenCastStreamSrcPrivate *priv =
|
||||
meta_screen_cast_stream_src_get_instance_private (src);
|
||||
|
||||
priv->pipewire_source = create_pipewire_source ();
|
||||
priv->pipewire_source = create_pipewire_source (src);
|
||||
if (!priv->pipewire_source)
|
||||
{
|
||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||
@@ -975,8 +987,8 @@ meta_screen_cast_stream_src_finalize (GObject *object)
|
||||
if (meta_screen_cast_stream_src_is_enabled (src))
|
||||
meta_screen_cast_stream_src_disable (src);
|
||||
|
||||
g_clear_pointer (&priv->dmabuf_handles, g_hash_table_destroy);
|
||||
g_clear_pointer (&priv->pipewire_stream, pw_stream_destroy);
|
||||
g_clear_pointer (&priv->dmabuf_handles, g_hash_table_destroy);
|
||||
g_clear_pointer (&priv->pipewire_core, pw_core_disconnect);
|
||||
g_clear_pointer (&priv->pipewire_context, pw_context_destroy);
|
||||
g_source_destroy (&priv->pipewire_source->base);
|
||||
|
@@ -1380,35 +1380,6 @@ has_touchscreen (MetaSeatNative *seat)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
has_external_keyboard (MetaSeatNative *seat)
|
||||
{
|
||||
GList *devices, *l;
|
||||
gboolean has_external = FALSE;
|
||||
|
||||
devices = g_udev_client_query_by_subsystem (seat->udev_client, "input");
|
||||
|
||||
for (l = devices; l; l = l->next)
|
||||
{
|
||||
if (!g_udev_device_has_property (l->data, "ID_INPUT_KEYBOARD"))
|
||||
continue;
|
||||
|
||||
/* May be "hid" or something else, we don't care. This property
|
||||
* will not be present in virtual "AT Translated Set 2 keyboard"
|
||||
* devices.
|
||||
*/
|
||||
if (!g_udev_device_has_property (l->data, "ID_TYPE"))
|
||||
break;
|
||||
|
||||
has_external = TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
g_list_free_full (devices, g_object_unref);
|
||||
|
||||
return has_external;
|
||||
}
|
||||
|
||||
static void
|
||||
update_touch_mode (MetaSeatNative *seat)
|
||||
{
|
||||
@@ -1421,10 +1392,10 @@ update_touch_mode (MetaSeatNative *seat)
|
||||
else if (seat->has_tablet_switch && !seat->tablet_mode_switch_state)
|
||||
touch_mode = FALSE;
|
||||
/* If tablet mode is enabled, or if there is no tablet mode switch
|
||||
* (eg. kiosk machines), check availability of external keyboards.
|
||||
* (eg. kiosk machines), assume touch-mode.
|
||||
*/
|
||||
else
|
||||
touch_mode = !seat->has_external_keyboard;
|
||||
touch_mode = TRUE;
|
||||
|
||||
if (seat->touch_mode != touch_mode)
|
||||
{
|
||||
@@ -1465,12 +1436,7 @@ evdev_add_device (MetaSeatNative *seat,
|
||||
|
||||
g_signal_emit_by_name (seat, "device-added", device);
|
||||
|
||||
if (type == CLUTTER_KEYBOARD_DEVICE)
|
||||
{
|
||||
seat->has_external_keyboard = has_external_keyboard (seat);
|
||||
check_touch_mode = TRUE;
|
||||
}
|
||||
else if (type == CLUTTER_TOUCHSCREEN_DEVICE)
|
||||
if (type == CLUTTER_TOUCHSCREEN_DEVICE)
|
||||
{
|
||||
seat->has_touchscreen = TRUE;
|
||||
check_touch_mode = TRUE;
|
||||
@@ -1503,12 +1469,7 @@ evdev_remove_device (MetaSeatNative *seat,
|
||||
|
||||
device_type = clutter_input_device_get_device_type (device);
|
||||
|
||||
if (device_type == CLUTTER_KEYBOARD_DEVICE)
|
||||
{
|
||||
seat->has_external_keyboard = has_external_keyboard (seat);
|
||||
update_touch_mode (seat);
|
||||
}
|
||||
else if (device_type == CLUTTER_TOUCHSCREEN_DEVICE)
|
||||
if (device_type == CLUTTER_TOUCHSCREEN_DEVICE)
|
||||
{
|
||||
seat->has_touchscreen = has_touchscreen (seat);
|
||||
update_touch_mode (seat);
|
||||
@@ -2553,7 +2514,6 @@ meta_seat_native_constructed (GObject *object)
|
||||
xkb_keymap_led_get_index (xkb_keymap, XKB_LED_NAME_SCROLL);
|
||||
}
|
||||
|
||||
seat->has_external_keyboard = has_external_keyboard (seat);
|
||||
seat->has_touchscreen = has_touchscreen (seat);
|
||||
update_touch_mode (seat);
|
||||
|
||||
|
@@ -120,7 +120,6 @@ struct _MetaSeatNative
|
||||
|
||||
GUdevClient *udev_client;
|
||||
guint tablet_mode_switch_state : 1;
|
||||
guint has_external_keyboard : 1;
|
||||
guint has_touchscreen : 1;
|
||||
guint has_tablet_switch : 1;
|
||||
guint touch_mode : 1;
|
||||
|
@@ -24,14 +24,75 @@
|
||||
|
||||
#include "backends/x11/cm/meta-renderer-x11-cm.h"
|
||||
|
||||
#include "backends/meta-renderer-view.h"
|
||||
|
||||
struct _MetaRendererX11Cm
|
||||
{
|
||||
MetaRendererX11 parent;
|
||||
|
||||
MetaRendererView *screen_view;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (MetaRendererX11Cm, meta_renderer_x11_cm,
|
||||
META_TYPE_RENDERER_X11)
|
||||
|
||||
void
|
||||
meta_renderer_x11_cm_ensure_screen_view (MetaRendererX11Cm *renderer_x11_cm,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
cairo_rectangle_int_t view_layout;
|
||||
|
||||
if (renderer_x11_cm->screen_view)
|
||||
return;
|
||||
|
||||
view_layout = (cairo_rectangle_int_t) {
|
||||
.width = width,
|
||||
.height = height,
|
||||
};
|
||||
renderer_x11_cm->screen_view = g_object_new (META_TYPE_RENDERER_VIEW,
|
||||
"layout", &view_layout,
|
||||
NULL);
|
||||
meta_renderer_add_view (META_RENDERER (renderer_x11_cm),
|
||||
renderer_x11_cm->screen_view);
|
||||
}
|
||||
|
||||
void
|
||||
meta_renderer_x11_cm_resize (MetaRendererX11Cm *renderer_x11_cm,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
cairo_rectangle_int_t view_layout;
|
||||
|
||||
view_layout = (cairo_rectangle_int_t) {
|
||||
.width = width,
|
||||
.height = height,
|
||||
};
|
||||
|
||||
g_object_set (G_OBJECT (renderer_x11_cm->screen_view),
|
||||
"layout", &view_layout,
|
||||
NULL);
|
||||
}
|
||||
|
||||
void
|
||||
meta_renderer_x11_cm_set_onscreen (MetaRendererX11Cm *renderer_x11_cm,
|
||||
CoglOnscreen *onscreen)
|
||||
{
|
||||
g_object_set (G_OBJECT (renderer_x11_cm->screen_view),
|
||||
"framebuffer", onscreen,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_renderer_x11_cm_rebuild_views (MetaRenderer *renderer)
|
||||
{
|
||||
MetaRendererX11Cm *renderer_x11_cm = META_RENDERER_X11_CM (renderer);
|
||||
|
||||
g_return_if_fail (!meta_renderer_get_views (renderer));
|
||||
|
||||
meta_renderer_add_view (renderer, renderer_x11_cm->screen_view);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_renderer_x11_cm_init (MetaRendererX11Cm *renderer_x11_cm)
|
||||
{
|
||||
@@ -40,4 +101,7 @@ meta_renderer_x11_cm_init (MetaRendererX11Cm *renderer_x11_cm)
|
||||
static void
|
||||
meta_renderer_x11_cm_class_init (MetaRendererX11CmClass *klass)
|
||||
{
|
||||
MetaRendererClass *renderer_class = META_RENDERER_CLASS (klass);
|
||||
|
||||
renderer_class->rebuild_views = meta_renderer_x11_cm_rebuild_views;
|
||||
}
|
||||
|
@@ -30,4 +30,15 @@ G_DECLARE_FINAL_TYPE (MetaRendererX11Cm, meta_renderer_x11_cm,
|
||||
META, RENDERER_X11_CM,
|
||||
MetaRendererX11)
|
||||
|
||||
void meta_renderer_x11_cm_ensure_screen_view (MetaRendererX11Cm *renderer_x11_cm,
|
||||
int width,
|
||||
int height);
|
||||
|
||||
void meta_renderer_x11_cm_resize (MetaRendererX11Cm *renderer_x11_cm,
|
||||
int width,
|
||||
int height);
|
||||
|
||||
void meta_renderer_x11_cm_set_onscreen (MetaRendererX11Cm *renderer_x11_cm,
|
||||
CoglOnscreen *onscreen);
|
||||
|
||||
#endif /* META_RENDERER_X11_CM_H */
|
||||
|
@@ -855,6 +855,7 @@ meta_backend_x11_class_init (MetaBackendX11Class *klass)
|
||||
static void
|
||||
meta_backend_x11_init (MetaBackendX11 *x11)
|
||||
{
|
||||
XInitThreads ();
|
||||
}
|
||||
|
||||
Display *
|
||||
|
@@ -38,7 +38,10 @@ enum
|
||||
PROP_OPCODE,
|
||||
PROP_POINTER_ID,
|
||||
PROP_KEYBOARD_ID,
|
||||
N_PROPS
|
||||
N_PROPS,
|
||||
|
||||
/* This property is overridden */
|
||||
PROP_TOUCH_MODE,
|
||||
};
|
||||
|
||||
struct _MetaSeatX11
|
||||
@@ -54,6 +57,8 @@ struct _MetaSeatX11
|
||||
int pointer_id;
|
||||
int keyboard_id;
|
||||
int opcode;
|
||||
guint has_touchscreens : 1;
|
||||
guint touch_mode : 1;
|
||||
};
|
||||
|
||||
static GParamSpec *props[N_PROPS] = { 0 };
|
||||
@@ -605,6 +610,20 @@ pad_passive_button_grab (ClutterInputDevice *device)
|
||||
g_free (xi_event_mask.mask);
|
||||
}
|
||||
|
||||
static void
|
||||
update_touch_mode (MetaSeatX11 *seat_x11)
|
||||
{
|
||||
gboolean touch_mode;
|
||||
|
||||
touch_mode = seat_x11->has_touchscreens;
|
||||
|
||||
if (seat_x11->touch_mode == touch_mode)
|
||||
return;
|
||||
|
||||
seat_x11->touch_mode = touch_mode;
|
||||
g_object_notify (G_OBJECT (seat_x11), "touch-mode");
|
||||
}
|
||||
|
||||
static ClutterInputDevice *
|
||||
add_device (MetaSeatX11 *seat_x11,
|
||||
ClutterBackend *backend,
|
||||
@@ -635,6 +654,8 @@ add_device (MetaSeatX11 *seat_x11,
|
||||
info->attachment == seat_x11->keyboard_id))
|
||||
{
|
||||
seat_x11->devices = g_list_prepend (seat_x11->devices, device);
|
||||
seat_x11->has_touchscreens |=
|
||||
clutter_input_device_get_device_type (device) == CLUTTER_TOUCHSCREEN_DEVICE;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -663,18 +684,38 @@ add_device (MetaSeatX11 *seat_x11,
|
||||
}
|
||||
}
|
||||
|
||||
update_touch_mode (seat_x11);
|
||||
|
||||
return device;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
has_touchscreens (MetaSeatX11 *seat_x11)
|
||||
{
|
||||
GList *l;
|
||||
|
||||
for (l = seat_x11->devices; l; l = l->next)
|
||||
{
|
||||
if (clutter_input_device_get_device_type (l->data) == CLUTTER_TOUCHSCREEN_DEVICE)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
remove_device (MetaSeatX11 *seat_x11,
|
||||
int device_id)
|
||||
{
|
||||
ClutterInputDevice *device;
|
||||
gboolean check_touchscreens = FALSE;
|
||||
|
||||
device = g_hash_table_lookup (seat_x11->devices_by_id,
|
||||
GINT_TO_POINTER (device_id));
|
||||
|
||||
if (clutter_input_device_get_device_type (device) == CLUTTER_TOUCHSCREEN_DEVICE)
|
||||
check_touchscreens = TRUE;
|
||||
|
||||
if (device != NULL)
|
||||
{
|
||||
if (seat_x11->core_pointer == device)
|
||||
@@ -695,6 +736,12 @@ remove_device (MetaSeatX11 *seat_x11,
|
||||
g_hash_table_remove (seat_x11->devices_by_id,
|
||||
GINT_TO_POINTER (device_id));
|
||||
}
|
||||
|
||||
if (check_touchscreens)
|
||||
{
|
||||
seat_x11->has_touchscreens = has_touchscreens (seat_x11);
|
||||
update_touch_mode (seat_x11);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1272,6 +1319,7 @@ meta_seat_x11_set_property (GObject *object,
|
||||
case PROP_KEYBOARD_ID:
|
||||
seat_x11->keyboard_id = g_value_get_int (value);
|
||||
break;
|
||||
case PROP_TOUCH_MODE:
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
@@ -1296,6 +1344,9 @@ meta_seat_x11_get_property (GObject *object,
|
||||
case PROP_KEYBOARD_ID:
|
||||
g_value_set_int (value, seat_x11->keyboard_id);
|
||||
break;
|
||||
case PROP_TOUCH_MODE:
|
||||
g_value_set_boolean (value, seat_x11->touch_mode);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
@@ -1547,6 +1598,9 @@ meta_seat_x11_class_init (MetaSeatX11Class *klass)
|
||||
G_PARAM_CONSTRUCT_ONLY);
|
||||
|
||||
g_object_class_install_properties (object_class, N_PROPS, props);
|
||||
|
||||
g_object_class_override_property (object_class, PROP_TOUCH_MODE,
|
||||
"touch-mode");
|
||||
}
|
||||
|
||||
static void
|
||||
|
@@ -26,15 +26,17 @@
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "backends/x11/cm/meta-backend-x11-cm.h"
|
||||
#include "backends/x11/cm/meta-renderer-x11-cm.h"
|
||||
#include "backends/x11/meta-backend-x11.h"
|
||||
#include "backends/x11/meta-seat-x11.h"
|
||||
#include "backends/x11/meta-stage-x11.h"
|
||||
#include "clutter/clutter-mutter.h"
|
||||
#include "clutter/x11/clutter-x11.h"
|
||||
#include "clutter/x11/clutter-backend-x11.h"
|
||||
#include "cogl/cogl.h"
|
||||
#include "core/display-private.h"
|
||||
#include "meta/meta-x11-errors.h"
|
||||
#include "meta-backend-x11.h"
|
||||
#include "meta-seat-x11.h"
|
||||
#include "meta-stage-x11.h"
|
||||
|
||||
#define STAGE_X11_IS_MAPPED(s) ((((MetaStageX11 *) (s))->wm_state & STAGE_X11_WITHDRAWN) == 0)
|
||||
|
||||
@@ -287,8 +289,6 @@ meta_stage_x11_unrealize (ClutterStageWindow *stage_window)
|
||||
|
||||
clutter_stage_window_parent_iface->unrealize (stage_window);
|
||||
|
||||
g_list_free (stage_x11->legacy_views);
|
||||
g_clear_object (&stage_x11->legacy_view);
|
||||
g_clear_pointer (&stage_x11->onscreen, cogl_object_unref);
|
||||
}
|
||||
|
||||
@@ -330,10 +330,13 @@ meta_stage_x11_realize (ClutterStageWindow *stage_window)
|
||||
stage_cogl,
|
||||
NULL);
|
||||
|
||||
if (stage_x11->legacy_view)
|
||||
g_object_set (G_OBJECT (stage_x11->legacy_view),
|
||||
"framebuffer", stage_x11->onscreen,
|
||||
NULL);
|
||||
if (META_IS_BACKEND_X11_CM (stage_x11->backend))
|
||||
{
|
||||
MetaRenderer *renderer = meta_backend_get_renderer (stage_x11->backend);
|
||||
MetaRendererX11Cm *renderer_x11_cm = META_RENDERER_X11_CM (renderer);
|
||||
|
||||
meta_renderer_x11_cm_set_onscreen (renderer_x11_cm, stage_x11->onscreen);
|
||||
}
|
||||
|
||||
/* We just created a window of the size of the actor. No need to fix
|
||||
the size of the stage, just update it. */
|
||||
@@ -522,34 +525,13 @@ meta_stage_x11_can_clip_redraws (ClutterStageWindow *stage_window)
|
||||
return stage_x11->clipped_redraws_cool_off == 0;
|
||||
}
|
||||
|
||||
static void
|
||||
ensure_legacy_view (ClutterStageWindow *stage_window)
|
||||
{
|
||||
MetaStageX11 *stage_x11 = META_STAGE_X11 (stage_window);
|
||||
cairo_rectangle_int_t view_layout;
|
||||
CoglFramebuffer *framebuffer;
|
||||
|
||||
if (stage_x11->legacy_view)
|
||||
return;
|
||||
|
||||
_clutter_stage_window_get_geometry (stage_window, &view_layout);
|
||||
framebuffer = COGL_FRAMEBUFFER (stage_x11->onscreen);
|
||||
stage_x11->legacy_view = g_object_new (CLUTTER_TYPE_STAGE_VIEW_COGL,
|
||||
"layout", &view_layout,
|
||||
"framebuffer", framebuffer,
|
||||
NULL);
|
||||
stage_x11->legacy_views = g_list_append (stage_x11->legacy_views,
|
||||
stage_x11->legacy_view);
|
||||
}
|
||||
|
||||
static GList *
|
||||
meta_stage_x11_get_views (ClutterStageWindow *stage_window)
|
||||
{
|
||||
MetaStageX11 *stage_x11 = META_STAGE_X11 (stage_window);
|
||||
MetaRenderer *renderer = meta_backend_get_renderer (stage_x11->backend);
|
||||
|
||||
ensure_legacy_view (stage_window);
|
||||
|
||||
return stage_x11->legacy_views;
|
||||
return meta_renderer_get_views (renderer);
|
||||
}
|
||||
|
||||
static int64_t
|
||||
@@ -581,6 +563,9 @@ meta_stage_x11_class_init (MetaStageX11Class *klass)
|
||||
static void
|
||||
meta_stage_x11_init (MetaStageX11 *stage)
|
||||
{
|
||||
MetaRenderer *renderer;
|
||||
MetaRendererX11Cm *renderer_x11_cm;
|
||||
|
||||
stage->xwin = None;
|
||||
stage->xwin_width = 640;
|
||||
stage->xwin_height = 480;
|
||||
@@ -591,6 +576,19 @@ meta_stage_x11_init (MetaStageX11 *stage)
|
||||
stage->accept_focus = TRUE;
|
||||
|
||||
stage->title = NULL;
|
||||
|
||||
stage->backend = meta_get_backend ();
|
||||
g_assert (stage->backend);
|
||||
|
||||
if (META_IS_BACKEND_X11_CM (stage->backend))
|
||||
{
|
||||
renderer = meta_backend_get_renderer (stage->backend);
|
||||
renderer_x11_cm = META_RENDERER_X11_CM (renderer);
|
||||
|
||||
meta_renderer_x11_cm_ensure_screen_view (renderer_x11_cm,
|
||||
stage->xwin_width,
|
||||
stage->xwin_height);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -778,16 +776,16 @@ meta_stage_x11_translate_event (MetaStageX11 *stage_x11,
|
||||
* X11 compositing manager, we need to reset the legacy
|
||||
* stage view, now that it has a new size.
|
||||
*/
|
||||
if (stage_x11->legacy_view)
|
||||
if (META_IS_BACKEND_X11_CM (stage_x11->backend))
|
||||
{
|
||||
cairo_rectangle_int_t view_layout = {
|
||||
.width = stage_width,
|
||||
.height = stage_height
|
||||
};
|
||||
MetaBackend *backend = stage_x11->backend;
|
||||
MetaRenderer *renderer = meta_backend_get_renderer (backend);
|
||||
MetaRendererX11Cm *renderer_x11_cm =
|
||||
META_RENDERER_X11_CM (renderer);
|
||||
|
||||
g_object_set (G_OBJECT (stage_x11->legacy_view),
|
||||
"layout", &view_layout,
|
||||
NULL);
|
||||
meta_renderer_x11_cm_resize (renderer_x11_cm,
|
||||
stage_width,
|
||||
stage_height);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -25,6 +25,7 @@
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xatom.h>
|
||||
|
||||
#include "backends/meta-backend-private.h"
|
||||
#include "clutter/clutter-mutter.h"
|
||||
#include "clutter/x11/clutter-x11.h"
|
||||
|
||||
@@ -51,14 +52,13 @@ struct _MetaStageX11
|
||||
{
|
||||
ClutterStageCogl parent_instance;
|
||||
|
||||
MetaBackend *backend;
|
||||
|
||||
CoglOnscreen *onscreen;
|
||||
Window xwin;
|
||||
gint xwin_width;
|
||||
gint xwin_height; /* FIXME target_width / height */
|
||||
|
||||
ClutterStageView *legacy_view;
|
||||
GList *legacy_views;
|
||||
|
||||
CoglFrameClosure *frame_closure;
|
||||
|
||||
gchar *title;
|
||||
|
@@ -167,7 +167,8 @@ meta_renderer_x11_nested_ensure_legacy_view (MetaRendererX11Nested *renderer_x11
|
||||
"framebuffer", COGL_FRAMEBUFFER (fake_onscreen),
|
||||
NULL);
|
||||
|
||||
meta_renderer_set_legacy_view (renderer, legacy_view);
|
||||
g_assert (!meta_renderer_get_views (renderer));
|
||||
meta_renderer_add_view (renderer, legacy_view);
|
||||
}
|
||||
|
||||
static MetaRendererView *
|
||||
|
@@ -108,6 +108,30 @@ static struct wl_resource * create_and_send_primary_offer (MetaWaylandDataDevi
|
||||
struct wl_resource *target);
|
||||
static struct wl_resource * meta_wayland_data_source_get_resource (MetaWaylandDataSource *source);
|
||||
|
||||
static void
|
||||
move_resources (struct wl_list *destination,
|
||||
struct wl_list *source)
|
||||
{
|
||||
wl_list_insert_list (destination, source);
|
||||
wl_list_init (source);
|
||||
}
|
||||
|
||||
static void
|
||||
move_resources_for_client (struct wl_list *destination,
|
||||
struct wl_list *source,
|
||||
struct wl_client *client)
|
||||
{
|
||||
struct wl_resource *resource, *tmp;
|
||||
wl_resource_for_each_safe (resource, tmp, source)
|
||||
{
|
||||
if (wl_resource_get_client (resource) == client)
|
||||
{
|
||||
wl_list_remove (wl_resource_get_link (resource));
|
||||
wl_list_insert (destination, wl_resource_get_link (resource));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
unbind_resource (struct wl_resource *resource)
|
||||
{
|
||||
@@ -901,6 +925,12 @@ meta_wayland_drag_grab_set_focus (MetaWaylandDragGrab *drag_grab,
|
||||
client = wl_resource_get_client (surface->resource);
|
||||
|
||||
data_device_resource = wl_resource_find_for_client (&seat->data_device.resource_list, client);
|
||||
if (!data_device_resource)
|
||||
{
|
||||
data_device_resource =
|
||||
wl_resource_find_for_client (&seat->data_device.focus_resource_list,
|
||||
client);
|
||||
}
|
||||
|
||||
if (source && data_device_resource)
|
||||
offer = create_and_send_dnd_offer (source, data_device_resource);
|
||||
@@ -1841,10 +1871,7 @@ owner_changed_cb (MetaSelection *selection,
|
||||
|
||||
if (selection_type == META_SELECTION_PRIMARY)
|
||||
{
|
||||
data_device_resource =
|
||||
wl_resource_find_for_client (&data_device->primary_resource_list,
|
||||
focus_client);
|
||||
if (data_device_resource)
|
||||
wl_resource_for_each (data_device_resource, &data_device->primary_focus_resource_list)
|
||||
{
|
||||
struct wl_resource *offer = NULL;
|
||||
|
||||
@@ -1860,10 +1887,7 @@ owner_changed_cb (MetaSelection *selection,
|
||||
}
|
||||
else if (selection_type == META_SELECTION_CLIPBOARD)
|
||||
{
|
||||
data_device_resource =
|
||||
wl_resource_find_for_client (&data_device->resource_list, focus_client);
|
||||
|
||||
if (data_device_resource)
|
||||
wl_resource_for_each (data_device_resource, &data_device->focus_resource_list)
|
||||
{
|
||||
struct wl_resource *offer = NULL;
|
||||
|
||||
@@ -1998,7 +2022,9 @@ void
|
||||
meta_wayland_data_device_init (MetaWaylandDataDevice *data_device)
|
||||
{
|
||||
wl_list_init (&data_device->resource_list);
|
||||
wl_list_init (&data_device->focus_resource_list);
|
||||
wl_list_init (&data_device->primary_resource_list);
|
||||
wl_list_init (&data_device->primary_focus_resource_list);
|
||||
}
|
||||
|
||||
static struct wl_resource *
|
||||
@@ -2080,22 +2106,34 @@ meta_wayland_data_device_set_keyboard_focus (MetaWaylandDataDevice *data_device)
|
||||
return;
|
||||
|
||||
data_device->focus_client = focus_client;
|
||||
move_resources (&data_device->resource_list,
|
||||
&data_device->focus_resource_list);
|
||||
move_resources (&data_device->primary_resource_list,
|
||||
&data_device->primary_focus_resource_list);
|
||||
|
||||
if (!focus_client)
|
||||
return;
|
||||
|
||||
data_device_resource = wl_resource_find_for_client (&data_device->resource_list, focus_client);
|
||||
if (data_device_resource)
|
||||
move_resources_for_client (&data_device->focus_resource_list,
|
||||
&data_device->resource_list,
|
||||
focus_client);
|
||||
|
||||
wl_resource_for_each (data_device_resource, &data_device->focus_resource_list)
|
||||
{
|
||||
struct wl_resource *offer;
|
||||
|
||||
offer = create_and_send_clipboard_offer (data_device, data_device_resource);
|
||||
wl_data_device_send_selection (data_device_resource, offer);
|
||||
}
|
||||
|
||||
data_device_resource = wl_resource_find_for_client (&data_device->primary_resource_list, focus_client);
|
||||
if (data_device_resource)
|
||||
move_resources_for_client (&data_device->primary_focus_resource_list,
|
||||
&data_device->primary_resource_list,
|
||||
focus_client);
|
||||
|
||||
wl_resource_for_each (data_device_resource, &data_device->primary_focus_resource_list)
|
||||
{
|
||||
struct wl_resource *offer;
|
||||
|
||||
offer = create_and_send_primary_offer (data_device, data_device_resource);
|
||||
gtk_primary_selection_device_send_selection (data_device_resource, offer);
|
||||
}
|
||||
|
@@ -63,7 +63,9 @@ struct _MetaWaylandDataDevice
|
||||
MetaWaylandDataSource *primary_data_source;
|
||||
struct wl_listener selection_data_source_listener;
|
||||
struct wl_list resource_list;
|
||||
struct wl_list focus_resource_list;
|
||||
struct wl_list primary_resource_list;
|
||||
struct wl_list primary_focus_resource_list;
|
||||
MetaWaylandDragGrab *current_grab;
|
||||
struct wl_client *focus_client;
|
||||
|
||||
|
Reference in New Issue
Block a user