Compare commits
35 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d03deb006c | ||
|
|
c2146b457e | ||
|
|
77dc3a5065 | ||
|
|
454875248a | ||
|
|
ae8acc9980 | ||
|
|
86d9cd1a66 | ||
|
|
3a70ba7ae2 | ||
|
|
36a6235f3a | ||
|
|
9b349cb25b | ||
|
|
a83d83f087 | ||
|
|
b8bd39793a | ||
|
|
70072c39dd | ||
|
|
bb4bd4b5c0 | ||
|
|
ef848f10d1 | ||
|
|
59cb259fdd | ||
|
|
76e4b5de7a | ||
|
|
9acb823603 | ||
|
|
d721750417 | ||
|
|
1ec91cc8ee | ||
|
|
5c7b5ef0d9 | ||
|
|
e98e1c13dd | ||
|
|
8b69e7902a | ||
|
|
b52a0be288 | ||
|
|
1eb0812f0a | ||
|
|
b98125a330 | ||
|
|
78248d8dd3 | ||
|
|
849d8dfae9 | ||
|
|
1f896c9735 | ||
|
|
cc617b059c | ||
|
|
44a3358125 | ||
|
|
81deb99435 | ||
|
|
f25417efcf | ||
|
|
ecc2b91016 | ||
|
|
b002343dca | ||
|
|
0d9ded403f |
20
NEWS
20
NEWS
@@ -1,3 +1,23 @@
|
|||||||
|
3.36.4
|
||||||
|
======
|
||||||
|
* Fix crash on area screenshots with fractional scaling [Sebastian; !1320]
|
||||||
|
* Do not paint textures of fully obscured windows [Robert; !1326]
|
||||||
|
* Turn off CRTCs as well when enabling DPMS [Michel; !1240]
|
||||||
|
* Improve selection support
|
||||||
|
[Robert, Carlos, Sebastian; !1330, !1193, !1253, !1255, !1293, !1350]
|
||||||
|
* Use a more appropriate combine function on opaque areas [Daniel; !1331]
|
||||||
|
* Fix remote desktop being broken without screencast session [Olivier; #1307]
|
||||||
|
* Fix popovers disappearing on wayland and HiDPI [Robert; #1312]
|
||||||
|
* Fixed crashes [Jonas Å.; !1317]
|
||||||
|
* Plugged memory leaks [Jonas Å.; !1283]
|
||||||
|
* Misc. bug fixes and cleanups
|
||||||
|
[Corentin, Sebastian, Jonas Å., Jonas D.; !1314, !1321, !1295, !1333]
|
||||||
|
|
||||||
|
Contributors:
|
||||||
|
Jonas Dreßler, Michel Dänzer, Olivier Fourdan, Carlos Garnacho,
|
||||||
|
Sebastian Keller, Robert Mader, Corentin Noël, Daniel van Vugt, Jonas Ådahl
|
||||||
|
|
||||||
|
|
||||||
3.36.3
|
3.36.3
|
||||||
======
|
======
|
||||||
* Broadcast clipboard/primary offers [Carlos; !1262]
|
* Broadcast clipboard/primary offers [Carlos; !1262]
|
||||||
|
|||||||
@@ -475,8 +475,10 @@ get_preferred_size_for_orientation (ClutterBoxLayout *self,
|
|||||||
ClutterActor *child;
|
ClutterActor *child;
|
||||||
gint n_children = 0;
|
gint n_children = 0;
|
||||||
gfloat minimum, natural;
|
gfloat minimum, natural;
|
||||||
|
float largest_min_size, largest_nat_size;
|
||||||
|
|
||||||
minimum = natural = 0;
|
minimum = natural = 0;
|
||||||
|
largest_min_size = largest_nat_size = 0;
|
||||||
|
|
||||||
clutter_actor_iter_init (&iter, container);
|
clutter_actor_iter_init (&iter, container);
|
||||||
while (clutter_actor_iter_next (&iter, &child))
|
while (clutter_actor_iter_next (&iter, &child))
|
||||||
@@ -491,8 +493,22 @@ get_preferred_size_for_orientation (ClutterBoxLayout *self,
|
|||||||
get_child_size (child, priv->orientation,
|
get_child_size (child, priv->orientation,
|
||||||
for_size, &child_min, &child_nat);
|
for_size, &child_min, &child_nat);
|
||||||
|
|
||||||
minimum += child_min;
|
if (priv->is_homogeneous)
|
||||||
natural += child_nat;
|
{
|
||||||
|
largest_min_size = MAX (largest_min_size, child_min);
|
||||||
|
largest_nat_size = MAX (largest_nat_size, child_nat);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
minimum += child_min;
|
||||||
|
natural += child_nat;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (priv->is_homogeneous)
|
||||||
|
{
|
||||||
|
minimum = largest_min_size * n_children;
|
||||||
|
natural = largest_nat_size * n_children;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (n_children > 1)
|
if (n_children > 1)
|
||||||
@@ -623,6 +639,8 @@ get_preferred_size_for_opposite_orientation (ClutterBoxLayout *self,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
size -= (nvis_children - 1) * priv->spacing;
|
||||||
|
|
||||||
/* Bring children up to size first */
|
/* Bring children up to size first */
|
||||||
if (isnormal (size) || size == 0)
|
if (isnormal (size) || size == 0)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ typedef enum _ClutterPaintFlag
|
|||||||
{
|
{
|
||||||
CLUTTER_PAINT_FLAG_NONE = 0,
|
CLUTTER_PAINT_FLAG_NONE = 0,
|
||||||
CLUTTER_PAINT_FLAG_NO_CURSORS = 1 << 0,
|
CLUTTER_PAINT_FLAG_NO_CURSORS = 1 << 0,
|
||||||
CLUTTER_PAINT_FLAG_NO_PAINT_SIGNAL = 1 << 0,
|
CLUTTER_PAINT_FLAG_NO_PAINT_SIGNAL = 1 << 1,
|
||||||
} ClutterPaintFlag;
|
} ClutterPaintFlag;
|
||||||
|
|
||||||
ClutterPaintContext * clutter_paint_context_new_for_view (ClutterStageView *view,
|
ClutterPaintContext * clutter_paint_context_new_for_view (ClutterStageView *view,
|
||||||
|
|||||||
@@ -4526,8 +4526,8 @@ clutter_stage_paint_to_buffer (ClutterStage *stage,
|
|||||||
CoglFramebuffer *framebuffer;
|
CoglFramebuffer *framebuffer;
|
||||||
CoglBitmap *bitmap;
|
CoglBitmap *bitmap;
|
||||||
|
|
||||||
texture_width = (int) ceilf (rect->width * scale);
|
texture_width = (int) roundf (rect->width * scale);
|
||||||
texture_height = (int) ceilf (rect->height * scale);
|
texture_height = (int) roundf (rect->height * scale);
|
||||||
texture = cogl_texture_2d_new_with_size (cogl_context,
|
texture = cogl_texture_2d_new_with_size (cogl_context,
|
||||||
texture_width,
|
texture_width,
|
||||||
texture_height);
|
texture_height);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
project('mutter', 'c',
|
project('mutter', 'c',
|
||||||
version: '3.36.3',
|
version: '3.36.4',
|
||||||
meson_version: '>= 0.50.0',
|
meson_version: '>= 0.50.0',
|
||||||
license: 'GPLv2+'
|
license: 'GPLv2+'
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -273,14 +273,6 @@ meta_remote_desktop_session_check_can_notify (MetaRemoteDesktopSession *session,
|
|||||||
return FALSE;
|
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;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -591,6 +583,15 @@ handle_notify_pointer_motion_absolute (MetaDBusRemoteDesktopSession *skeleton,
|
|||||||
if (!meta_remote_desktop_session_check_can_notify (session, invocation))
|
if (!meta_remote_desktop_session_check_can_notify (session, invocation))
|
||||||
return TRUE;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
stream = meta_screen_cast_session_get_stream (session->screen_cast_session,
|
stream = meta_screen_cast_session_get_stream (session->screen_cast_session,
|
||||||
stream_path);
|
stream_path);
|
||||||
if (!stream)
|
if (!stream)
|
||||||
@@ -628,6 +629,14 @@ handle_notify_touch_down (MetaDBusRemoteDesktopSession *skeleton,
|
|||||||
if (!meta_remote_desktop_session_check_can_notify (session, invocation))
|
if (!meta_remote_desktop_session_check_can_notify (session, invocation))
|
||||||
return TRUE;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
stream = meta_screen_cast_session_get_stream (session->screen_cast_session,
|
stream = meta_screen_cast_session_get_stream (session->screen_cast_session,
|
||||||
stream_path);
|
stream_path);
|
||||||
if (!stream)
|
if (!stream)
|
||||||
@@ -666,6 +675,15 @@ handle_notify_touch_motion (MetaDBusRemoteDesktopSession *skeleton,
|
|||||||
if (!meta_remote_desktop_session_check_can_notify (session, invocation))
|
if (!meta_remote_desktop_session_check_can_notify (session, invocation))
|
||||||
return TRUE;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
stream = meta_screen_cast_session_get_stream (session->screen_cast_session,
|
stream = meta_screen_cast_session_get_stream (session->screen_cast_session,
|
||||||
stream_path);
|
stream_path);
|
||||||
if (!stream)
|
if (!stream)
|
||||||
|
|||||||
@@ -232,14 +232,28 @@ meta_gpu_kms_set_power_save_mode (MetaGpuKms *gpu_kms,
|
|||||||
uint64_t state,
|
uint64_t state,
|
||||||
MetaKmsUpdate *kms_update)
|
MetaKmsUpdate *kms_update)
|
||||||
{
|
{
|
||||||
|
MetaGpu *gpu = META_GPU (gpu_kms);
|
||||||
GList *l;
|
GList *l;
|
||||||
|
|
||||||
for (l = meta_gpu_get_outputs (META_GPU (gpu_kms)); l; l = l->next)
|
for (l = meta_gpu_get_outputs (gpu); l; l = l->next)
|
||||||
{
|
{
|
||||||
MetaOutput *output = l->data;
|
MetaOutput *output = l->data;
|
||||||
|
|
||||||
meta_output_kms_set_power_save_mode (output, state, kms_update);
|
meta_output_kms_set_power_save_mode (output, state, kms_update);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (state != META_POWER_SAVE_ON)
|
||||||
|
{
|
||||||
|
/* Turn off CRTCs for DPMS */
|
||||||
|
for (l = meta_gpu_get_crtcs (gpu); l; l = l->next)
|
||||||
|
{
|
||||||
|
MetaCrtc *crtc = META_CRTC (l->data);
|
||||||
|
|
||||||
|
meta_kms_update_mode_set (kms_update,
|
||||||
|
meta_crtc_kms_get_kms_crtc (crtc),
|
||||||
|
NULL, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
|
|||||||
@@ -2146,6 +2146,7 @@ meta_renderer_native_create_dma_buf (CoglRenderer *cogl_renderer,
|
|||||||
case META_RENDERER_NATIVE_MODE_GBM:
|
case META_RENDERER_NATIVE_MODE_GBM:
|
||||||
{
|
{
|
||||||
CoglFramebuffer *dmabuf_fb;
|
CoglFramebuffer *dmabuf_fb;
|
||||||
|
CoglDmaBufHandle *dmabuf_handle;
|
||||||
struct gbm_bo *new_bo;
|
struct gbm_bo *new_bo;
|
||||||
int dmabuf_fd = -1;
|
int dmabuf_fd = -1;
|
||||||
|
|
||||||
@@ -2182,8 +2183,11 @@ meta_renderer_native_create_dma_buf (CoglRenderer *cogl_renderer,
|
|||||||
if (!dmabuf_fb)
|
if (!dmabuf_fb)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
return cogl_dma_buf_handle_new (dmabuf_fb, dmabuf_fd, new_bo,
|
dmabuf_handle =
|
||||||
(GDestroyNotify) gbm_bo_destroy);
|
cogl_dma_buf_handle_new (dmabuf_fb, dmabuf_fd, new_bo,
|
||||||
|
(GDestroyNotify) gbm_bo_destroy);
|
||||||
|
cogl_object_unref (dmabuf_fb);
|
||||||
|
return dmabuf_handle;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
#ifdef HAVE_EGL_DEVICE
|
#ifdef HAVE_EGL_DEVICE
|
||||||
|
|||||||
@@ -843,12 +843,16 @@ meta_stage_x11_translate_event (MetaStageX11 *stage_x11,
|
|||||||
g_debug ("Client message for stage, win:0x%x",
|
g_debug ("Client message for stage, win:0x%x",
|
||||||
(unsigned int) xevent->xany.window);
|
(unsigned int) xevent->xany.window);
|
||||||
|
|
||||||
if (handle_wm_protocols_event (backend_x11, stage_x11, xevent))
|
if (xevent->xclient.message_type == backend_x11->atom_WM_PROTOCOLS)
|
||||||
{
|
{
|
||||||
event->any.type = CLUTTER_DELETE;
|
if (handle_wm_protocols_event (backend_x11, stage_x11, xevent))
|
||||||
event->any.stage = stage;
|
{
|
||||||
res = TRUE;
|
event->any.type = CLUTTER_DELETE;
|
||||||
|
event->any.stage = stage;
|
||||||
|
res = TRUE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -66,4 +66,7 @@ gboolean meta_shaped_texture_update_area (MetaShapedTexture *stex,
|
|||||||
int meta_shaped_texture_get_width (MetaShapedTexture *stex);
|
int meta_shaped_texture_get_width (MetaShapedTexture *stex);
|
||||||
int meta_shaped_texture_get_height (MetaShapedTexture *stex);
|
int meta_shaped_texture_get_height (MetaShapedTexture *stex);
|
||||||
|
|
||||||
|
void meta_shaped_texture_set_clip_region (MetaShapedTexture *stex,
|
||||||
|
cairo_region_t *clip_region);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -87,6 +87,9 @@ struct _MetaShapedTexture
|
|||||||
/* The region containing only fully opaque pixels */
|
/* The region containing only fully opaque pixels */
|
||||||
cairo_region_t *opaque_region;
|
cairo_region_t *opaque_region;
|
||||||
|
|
||||||
|
/* MetaCullable regions, see that documentation for more details */
|
||||||
|
cairo_region_t *clip_region;
|
||||||
|
|
||||||
gboolean size_invalid;
|
gboolean size_invalid;
|
||||||
MetaMonitorTransform transform;
|
MetaMonitorTransform transform;
|
||||||
gboolean has_viewport_src_rect;
|
gboolean has_viewport_src_rect;
|
||||||
@@ -214,6 +217,15 @@ ensure_size_valid (MetaShapedTexture *stex)
|
|||||||
update_size (stex);
|
update_size (stex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_shaped_texture_set_clip_region (MetaShapedTexture *stex,
|
||||||
|
cairo_region_t *clip_region)
|
||||||
|
{
|
||||||
|
g_clear_pointer (&stex->clip_region, cairo_region_destroy);
|
||||||
|
if (clip_region)
|
||||||
|
stex->clip_region = cairo_region_reference (clip_region);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
meta_shaped_texture_reset_pipelines (MetaShapedTexture *stex)
|
meta_shaped_texture_reset_pipelines (MetaShapedTexture *stex)
|
||||||
{
|
{
|
||||||
@@ -239,6 +251,7 @@ meta_shaped_texture_dispose (GObject *object)
|
|||||||
meta_shaped_texture_reset_pipelines (stex);
|
meta_shaped_texture_reset_pipelines (stex);
|
||||||
|
|
||||||
g_clear_pointer (&stex->opaque_region, cairo_region_destroy);
|
g_clear_pointer (&stex->opaque_region, cairo_region_destroy);
|
||||||
|
g_clear_pointer (&stex->clip_region, cairo_region_destroy);
|
||||||
|
|
||||||
g_clear_pointer (&stex->snippet, cogl_object_unref);
|
g_clear_pointer (&stex->snippet, cogl_object_unref);
|
||||||
|
|
||||||
@@ -390,17 +403,14 @@ get_unblended_pipeline (MetaShapedTexture *stex,
|
|||||||
CoglContext *ctx)
|
CoglContext *ctx)
|
||||||
{
|
{
|
||||||
CoglPipeline *pipeline;
|
CoglPipeline *pipeline;
|
||||||
CoglColor color;
|
|
||||||
|
|
||||||
if (stex->unblended_pipeline)
|
if (stex->unblended_pipeline)
|
||||||
return stex->unblended_pipeline;
|
return stex->unblended_pipeline;
|
||||||
|
|
||||||
pipeline = cogl_pipeline_copy (get_base_pipeline (stex, ctx));
|
pipeline = cogl_pipeline_copy (get_base_pipeline (stex, ctx));
|
||||||
cogl_color_init_from_4ub (&color, 255, 255, 255, 255);
|
cogl_pipeline_set_layer_combine (pipeline, 0,
|
||||||
cogl_pipeline_set_blend (pipeline,
|
"RGBA = REPLACE (TEXTURE)",
|
||||||
"RGBA = ADD (SRC_COLOR, 0)",
|
NULL);
|
||||||
NULL);
|
|
||||||
cogl_pipeline_set_color (pipeline, &color);
|
|
||||||
|
|
||||||
stex->unblended_pipeline = pipeline;
|
stex->unblended_pipeline = pipeline;
|
||||||
|
|
||||||
@@ -585,12 +595,19 @@ do_paint_content (MetaShapedTexture *stex,
|
|||||||
|
|
||||||
if (use_opaque_region)
|
if (use_opaque_region)
|
||||||
{
|
{
|
||||||
blended_tex_region = cairo_region_create_rectangle (&content_rect);
|
if (stex->clip_region)
|
||||||
|
blended_tex_region = cairo_region_copy (stex->clip_region);
|
||||||
|
else
|
||||||
|
blended_tex_region = cairo_region_create_rectangle (&content_rect);
|
||||||
|
|
||||||
cairo_region_subtract (blended_tex_region, stex->opaque_region);
|
cairo_region_subtract (blended_tex_region, stex->opaque_region);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
blended_tex_region = NULL;
|
if (stex->clip_region)
|
||||||
|
blended_tex_region = cairo_region_reference (stex->clip_region);
|
||||||
|
else
|
||||||
|
blended_tex_region = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Limit to how many separate rectangles we'll draw; beyond this just
|
/* Limit to how many separate rectangles we'll draw; beyond this just
|
||||||
@@ -612,10 +629,21 @@ do_paint_content (MetaShapedTexture *stex,
|
|||||||
/* First, paint the unblended parts, which are part of the opaque region. */
|
/* First, paint the unblended parts, which are part of the opaque region. */
|
||||||
if (use_opaque_region)
|
if (use_opaque_region)
|
||||||
{
|
{
|
||||||
|
cairo_region_t *region;
|
||||||
int n_rects;
|
int n_rects;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (!cairo_region_is_empty (stex->opaque_region))
|
if (stex->clip_region)
|
||||||
|
{
|
||||||
|
region = cairo_region_copy (stex->clip_region);
|
||||||
|
cairo_region_intersect (region, stex->opaque_region);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
region = cairo_region_reference (stex->opaque_region);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!cairo_region_is_empty (region))
|
||||||
{
|
{
|
||||||
CoglPipeline *opaque_pipeline;
|
CoglPipeline *opaque_pipeline;
|
||||||
|
|
||||||
@@ -623,16 +651,18 @@ do_paint_content (MetaShapedTexture *stex,
|
|||||||
cogl_pipeline_set_layer_texture (opaque_pipeline, 0, paint_tex);
|
cogl_pipeline_set_layer_texture (opaque_pipeline, 0, paint_tex);
|
||||||
cogl_pipeline_set_layer_filters (opaque_pipeline, 0, filter, filter);
|
cogl_pipeline_set_layer_filters (opaque_pipeline, 0, filter, filter);
|
||||||
|
|
||||||
n_rects = cairo_region_num_rectangles (stex->opaque_region);
|
n_rects = cairo_region_num_rectangles (region);
|
||||||
for (i = 0; i < n_rects; i++)
|
for (i = 0; i < n_rects; i++)
|
||||||
{
|
{
|
||||||
cairo_rectangle_int_t rect;
|
cairo_rectangle_int_t rect;
|
||||||
cairo_region_get_rectangle (stex->opaque_region, i, &rect);
|
cairo_region_get_rectangle (region, i, &rect);
|
||||||
paint_clipped_rectangle_node (stex, root_node,
|
paint_clipped_rectangle_node (stex, root_node,
|
||||||
opaque_pipeline,
|
opaque_pipeline,
|
||||||
&rect, alloc);
|
&rect, alloc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cairo_region_destroy (region);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now, go ahead and paint the blended parts. */
|
/* Now, go ahead and paint the blended parts. */
|
||||||
@@ -757,6 +787,9 @@ meta_shaped_texture_paint_content (ClutterContent *content,
|
|||||||
CoglTexture *paint_tex = NULL;
|
CoglTexture *paint_tex = NULL;
|
||||||
uint8_t opacity;
|
uint8_t opacity;
|
||||||
|
|
||||||
|
if (stex->clip_region && cairo_region_is_empty (stex->clip_region))
|
||||||
|
return;
|
||||||
|
|
||||||
/* The GL EXT_texture_from_pixmap extension does allow for it to be
|
/* The GL EXT_texture_from_pixmap extension does allow for it to be
|
||||||
* used together with SGIS_generate_mipmap, however this is very
|
* used together with SGIS_generate_mipmap, however this is very
|
||||||
* rarely supported. Also, even when it is supported there
|
* rarely supported. Also, even when it is supported there
|
||||||
|
|||||||
@@ -34,7 +34,6 @@ typedef struct _MetaSurfaceActorPrivate
|
|||||||
cairo_region_t *input_region;
|
cairo_region_t *input_region;
|
||||||
|
|
||||||
/* MetaCullable regions, see that documentation for more details */
|
/* MetaCullable regions, see that documentation for more details */
|
||||||
cairo_region_t *clip_region;
|
|
||||||
cairo_region_t *unobscured_region;
|
cairo_region_t *unobscured_region;
|
||||||
|
|
||||||
/* Freeze/thaw accounting */
|
/* Freeze/thaw accounting */
|
||||||
@@ -58,6 +57,12 @@ enum
|
|||||||
|
|
||||||
static guint signals[LAST_SIGNAL];
|
static guint signals[LAST_SIGNAL];
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
IN_STAGE_PERSPECTIVE,
|
||||||
|
IN_ACTOR_PERSPECTIVE
|
||||||
|
} ScalePerspectiveType;
|
||||||
|
|
||||||
static cairo_region_t *
|
static cairo_region_t *
|
||||||
effective_unobscured_region (MetaSurfaceActor *surface_actor)
|
effective_unobscured_region (MetaSurfaceActor *surface_actor)
|
||||||
{
|
{
|
||||||
@@ -79,18 +84,39 @@ effective_unobscured_region (MetaSurfaceActor *surface_actor)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static cairo_region_t*
|
static cairo_region_t*
|
||||||
get_scaled_region (MetaSurfaceActor *surface_actor,
|
get_scaled_region (MetaSurfaceActor *surface_actor,
|
||||||
cairo_region_t *region)
|
cairo_region_t *region,
|
||||||
|
ScalePerspectiveType scale_perspective)
|
||||||
{
|
{
|
||||||
MetaWindowActor *window_actor;
|
MetaWindowActor *window_actor;
|
||||||
|
cairo_region_t *scaled_region;
|
||||||
int geometry_scale;
|
int geometry_scale;
|
||||||
|
float x, y;
|
||||||
|
|
||||||
window_actor = meta_window_actor_from_actor (CLUTTER_ACTOR (surface_actor));
|
window_actor = meta_window_actor_from_actor (CLUTTER_ACTOR (surface_actor));
|
||||||
geometry_scale = meta_window_actor_get_geometry_scale (window_actor);
|
geometry_scale = meta_window_actor_get_geometry_scale (window_actor);
|
||||||
|
|
||||||
return meta_region_scale_double (region,
|
clutter_actor_get_position (CLUTTER_ACTOR (surface_actor), &x, &y);
|
||||||
1.0 / geometry_scale,
|
cairo_region_translate (region, x, y);
|
||||||
META_ROUNDING_STRATEGY_GROW);
|
|
||||||
|
switch (scale_perspective)
|
||||||
|
{
|
||||||
|
case IN_STAGE_PERSPECTIVE:
|
||||||
|
scaled_region = meta_region_scale_double (region,
|
||||||
|
geometry_scale,
|
||||||
|
META_ROUNDING_STRATEGY_GROW);
|
||||||
|
break;
|
||||||
|
case IN_ACTOR_PERSPECTIVE:
|
||||||
|
scaled_region = meta_region_scale_double (region,
|
||||||
|
1.0 / geometry_scale,
|
||||||
|
META_ROUNDING_STRATEGY_GROW);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
cairo_region_translate (region, -x, -y);
|
||||||
|
cairo_region_translate (scaled_region, -x, -y);
|
||||||
|
|
||||||
|
return scaled_region;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -120,8 +146,9 @@ set_unobscured_region (MetaSurfaceActor *surface_actor,
|
|||||||
.height = height,
|
.height = height,
|
||||||
};
|
};
|
||||||
|
|
||||||
priv->unobscured_region =
|
priv->unobscured_region = get_scaled_region (surface_actor,
|
||||||
get_scaled_region (surface_actor, unobscured_region);
|
unobscured_region,
|
||||||
|
IN_ACTOR_PERSPECTIVE);
|
||||||
|
|
||||||
cairo_region_intersect_rectangle (priv->unobscured_region, &bounds);
|
cairo_region_intersect_rectangle (priv->unobscured_region, &bounds);
|
||||||
}
|
}
|
||||||
@@ -134,30 +161,23 @@ set_clip_region (MetaSurfaceActor *surface_actor,
|
|||||||
{
|
{
|
||||||
MetaSurfaceActorPrivate *priv =
|
MetaSurfaceActorPrivate *priv =
|
||||||
meta_surface_actor_get_instance_private (surface_actor);
|
meta_surface_actor_get_instance_private (surface_actor);
|
||||||
|
MetaShapedTexture *stex = priv->texture;
|
||||||
|
|
||||||
g_clear_pointer (&priv->clip_region, cairo_region_destroy);
|
if (clip_region && !cairo_region_is_empty (clip_region))
|
||||||
if (clip_region)
|
|
||||||
{
|
{
|
||||||
if (cairo_region_is_empty (clip_region))
|
cairo_region_t *region;
|
||||||
priv->clip_region = cairo_region_reference (clip_region);
|
|
||||||
else
|
region = get_scaled_region (surface_actor,
|
||||||
priv->clip_region = get_scaled_region (surface_actor, clip_region);
|
clip_region,
|
||||||
|
IN_ACTOR_PERSPECTIVE);
|
||||||
|
meta_shaped_texture_set_clip_region (stex, region);
|
||||||
|
|
||||||
|
cairo_region_destroy (region);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
meta_shaped_texture_set_clip_region (stex, clip_region);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
meta_surface_actor_paint (ClutterActor *actor,
|
|
||||||
ClutterPaintContext *paint_context)
|
|
||||||
{
|
|
||||||
MetaSurfaceActor *surface_actor = META_SURFACE_ACTOR (actor);
|
|
||||||
MetaSurfaceActorPrivate *priv =
|
|
||||||
meta_surface_actor_get_instance_private (surface_actor);
|
|
||||||
|
|
||||||
if (priv->clip_region && cairo_region_is_empty (priv->clip_region))
|
|
||||||
return;
|
|
||||||
|
|
||||||
CLUTTER_ACTOR_CLASS (meta_surface_actor_parent_class)->paint (actor,
|
|
||||||
paint_context);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -227,7 +247,6 @@ meta_surface_actor_dispose (GObject *object)
|
|||||||
g_clear_object (&priv->texture);
|
g_clear_object (&priv->texture);
|
||||||
|
|
||||||
set_unobscured_region (self, NULL);
|
set_unobscured_region (self, NULL);
|
||||||
set_clip_region (self, NULL);
|
|
||||||
|
|
||||||
G_OBJECT_CLASS (meta_surface_actor_parent_class)->dispose (object);
|
G_OBJECT_CLASS (meta_surface_actor_parent_class)->dispose (object);
|
||||||
}
|
}
|
||||||
@@ -239,7 +258,6 @@ meta_surface_actor_class_init (MetaSurfaceActorClass *klass)
|
|||||||
ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
|
ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
|
||||||
|
|
||||||
object_class->dispose = meta_surface_actor_dispose;
|
object_class->dispose = meta_surface_actor_dispose;
|
||||||
actor_class->paint = meta_surface_actor_paint;
|
|
||||||
actor_class->pick = meta_surface_actor_pick;
|
actor_class->pick = meta_surface_actor_pick;
|
||||||
actor_class->get_paint_volume = meta_surface_actor_get_paint_volume;
|
actor_class->get_paint_volume = meta_surface_actor_get_paint_volume;
|
||||||
|
|
||||||
@@ -279,11 +297,8 @@ meta_surface_actor_cull_out (MetaCullable *cullable,
|
|||||||
|
|
||||||
if (opacity == 0xff)
|
if (opacity == 0xff)
|
||||||
{
|
{
|
||||||
MetaWindowActor *window_actor;
|
|
||||||
cairo_region_t *scaled_opaque_region;
|
|
||||||
cairo_region_t *opaque_region;
|
cairo_region_t *opaque_region;
|
||||||
int geometry_scale;
|
cairo_region_t *scaled_opaque_region;
|
||||||
float x, y;
|
|
||||||
|
|
||||||
opaque_region = meta_shaped_texture_get_opaque_region (priv->texture);
|
opaque_region = meta_shaped_texture_get_opaque_region (priv->texture);
|
||||||
if (opaque_region)
|
if (opaque_region)
|
||||||
@@ -306,14 +321,9 @@ meta_surface_actor_cull_out (MetaCullable *cullable,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
window_actor = meta_window_actor_from_actor (CLUTTER_ACTOR (surface_actor));
|
scaled_opaque_region = get_scaled_region (surface_actor,
|
||||||
geometry_scale = meta_window_actor_get_geometry_scale (window_actor);
|
opaque_region,
|
||||||
clutter_actor_get_position (CLUTTER_ACTOR (surface_actor), &x, &y);
|
IN_STAGE_PERSPECTIVE);
|
||||||
|
|
||||||
cairo_region_translate (opaque_region, x, y);
|
|
||||||
scaled_opaque_region = meta_region_scale (opaque_region, geometry_scale);
|
|
||||||
cairo_region_translate (scaled_opaque_region, -x, -y);
|
|
||||||
cairo_region_translate (opaque_region, -x, -y);
|
|
||||||
|
|
||||||
if (unobscured_region)
|
if (unobscured_region)
|
||||||
cairo_region_subtract (unobscured_region, scaled_opaque_region);
|
cairo_region_subtract (unobscured_region, scaled_opaque_region);
|
||||||
|
|||||||
@@ -1630,8 +1630,8 @@ meta_window_actor_x11_init (MetaWindowActorX11 *self)
|
|||||||
|
|
||||||
self->shadow_factory = meta_shadow_factory_get_default ();
|
self->shadow_factory = meta_shadow_factory_get_default ();
|
||||||
self->shadow_factory_changed_handler_id =
|
self->shadow_factory_changed_handler_id =
|
||||||
g_signal_connect (self->shadow_factory,
|
g_signal_connect_swapped (self->shadow_factory,
|
||||||
"changed",
|
"changed",
|
||||||
G_CALLBACK (invalidate_shadow),
|
G_CALLBACK (invalidate_shadow),
|
||||||
self);
|
self);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -152,6 +152,7 @@ owner_changed_cb (MetaSelection *selection,
|
|||||||
display->saved_clipboard);
|
display->saved_clipboard);
|
||||||
g_set_object (&display->selection_source, new_owner);
|
g_set_object (&display->selection_source, new_owner);
|
||||||
meta_selection_set_owner (selection, selection_type, new_owner);
|
meta_selection_set_owner (selection, selection_type, new_owner);
|
||||||
|
g_object_unref (new_owner);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -170,6 +171,7 @@ meta_clipboard_manager_shutdown (MetaDisplay *display)
|
|||||||
{
|
{
|
||||||
MetaSelection *selection;
|
MetaSelection *selection;
|
||||||
|
|
||||||
|
g_clear_object (&display->selection_source);
|
||||||
g_clear_pointer (&display->saved_clipboard, g_bytes_unref);
|
g_clear_pointer (&display->saved_clipboard, g_bytes_unref);
|
||||||
g_clear_pointer (&display->saved_clipboard_mimetype, g_free);
|
g_clear_pointer (&display->saved_clipboard_mimetype, g_free);
|
||||||
selection = meta_display_get_selection (display);
|
selection = meta_display_get_selection (display);
|
||||||
|
|||||||
@@ -495,7 +495,22 @@ if have_wayland
|
|||||||
'wayland/meta-wayland-cursor-surface.h',
|
'wayland/meta-wayland-cursor-surface.h',
|
||||||
'wayland/meta-wayland-data-device.c',
|
'wayland/meta-wayland-data-device.c',
|
||||||
'wayland/meta-wayland-data-device.h',
|
'wayland/meta-wayland-data-device.h',
|
||||||
'wayland/meta-wayland-data-device-private.h',
|
'wayland/meta-wayland-data-device-primary.c',
|
||||||
|
'wayland/meta-wayland-data-device-primary.h',
|
||||||
|
'wayland/meta-wayland-data-device-primary-legacy.c',
|
||||||
|
'wayland/meta-wayland-data-device-primary-legacy.h',
|
||||||
|
'wayland/meta-wayland-data-offer.c',
|
||||||
|
'wayland/meta-wayland-data-offer.h',
|
||||||
|
'wayland/meta-wayland-data-offer-primary.c',
|
||||||
|
'wayland/meta-wayland-data-offer-primary.h',
|
||||||
|
'wayland/meta-wayland-data-offer-primary-legacy.c',
|
||||||
|
'wayland/meta-wayland-data-offer-primary-legacy.h',
|
||||||
|
'wayland/meta-wayland-data-source.c',
|
||||||
|
'wayland/meta-wayland-data-source.h',
|
||||||
|
'wayland/meta-wayland-data-source-primary.c',
|
||||||
|
'wayland/meta-wayland-data-source-primary.h',
|
||||||
|
'wayland/meta-wayland-data-source-primary-legacy.c',
|
||||||
|
'wayland/meta-wayland-data-source-primary-legacy.h',
|
||||||
'wayland/meta-wayland-dma-buf.c',
|
'wayland/meta-wayland-dma-buf.c',
|
||||||
'wayland/meta-wayland-dma-buf.h',
|
'wayland/meta-wayland-dma-buf.h',
|
||||||
'wayland/meta-wayland-dnd-surface.c',
|
'wayland/meta-wayland-dnd-surface.c',
|
||||||
@@ -790,6 +805,7 @@ if have_wayland
|
|||||||
['linux-dmabuf', 'unstable', 'v1', ],
|
['linux-dmabuf', 'unstable', 'v1', ],
|
||||||
['pointer-constraints', 'unstable', 'v1', ],
|
['pointer-constraints', 'unstable', 'v1', ],
|
||||||
['pointer-gestures', 'unstable', 'v1', ],
|
['pointer-gestures', 'unstable', 'v1', ],
|
||||||
|
['primary-selection', 'unstable', 'v1', ],
|
||||||
['relative-pointer', 'unstable', 'v1', ],
|
['relative-pointer', 'unstable', 'v1', ],
|
||||||
['tablet', 'unstable', 'v2', ],
|
['tablet', 'unstable', 'v2', ],
|
||||||
['text-input', 'unstable', 'v3', ],
|
['text-input', 'unstable', 'v3', ],
|
||||||
|
|||||||
@@ -26,7 +26,6 @@
|
|||||||
|
|
||||||
#include "meta/meta-selection-source.h"
|
#include "meta/meta-selection-source.h"
|
||||||
#include "wayland/meta-wayland-data-device.h"
|
#include "wayland/meta-wayland-data-device.h"
|
||||||
#include "wayland/meta-wayland-data-device-private.h"
|
|
||||||
|
|
||||||
#define META_TYPE_SELECTION_SOURCE_WAYLAND (meta_selection_source_wayland_get_type ())
|
#define META_TYPE_SELECTION_SOURCE_WAYLAND (meta_selection_source_wayland_get_type ())
|
||||||
|
|
||||||
|
|||||||
354
src/wayland/meta-wayland-data-device-primary-legacy.c
Normal file
354
src/wayland/meta-wayland-data-device-primary-legacy.c
Normal file
@@ -0,0 +1,354 @@
|
|||||||
|
/*
|
||||||
|
* Copyright © 2011 Kristian Høgsberg
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||||
|
* documentation for any purpose is hereby granted without fee, provided that
|
||||||
|
* the above copyright notice appear in all copies and that both that copyright
|
||||||
|
* notice and this permission notice appear in supporting documentation, and
|
||||||
|
* that the name of the copyright holders not be used in advertising or
|
||||||
|
* publicity pertaining to distribution of the software without specific,
|
||||||
|
* written prior permission. The copyright holders make no representations
|
||||||
|
* about the suitability of this software for any purpose. It is provided "as
|
||||||
|
* is" without express or implied warranty.
|
||||||
|
*
|
||||||
|
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||||
|
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||||
|
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||||
|
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||||
|
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||||
|
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
|
||||||
|
* OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* The file is based on src/data-device.c from Weston */
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include "wayland/meta-wayland-data-device-primary-legacy.h"
|
||||||
|
|
||||||
|
#include "compositor/meta-dnd-actor-private.h"
|
||||||
|
#include "meta/meta-selection-source-memory.h"
|
||||||
|
#include "wayland/meta-selection-source-wayland-private.h"
|
||||||
|
#include "wayland/meta-wayland-data-offer-primary-legacy.h"
|
||||||
|
#include "wayland/meta-wayland-data-source-primary-legacy.h"
|
||||||
|
#include "wayland/meta-wayland-dnd-surface.h"
|
||||||
|
#include "wayland/meta-wayland-pointer.h"
|
||||||
|
#include "wayland/meta-wayland-private.h"
|
||||||
|
#include "wayland/meta-wayland-seat.h"
|
||||||
|
|
||||||
|
#include "gtk-primary-selection-server-protocol.h"
|
||||||
|
|
||||||
|
static struct wl_resource * create_and_send_primary_offer (MetaWaylandDataDevicePrimaryLegacy *data_device,
|
||||||
|
struct wl_resource *target);
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
wl_list_remove (wl_resource_get_link (resource));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
default_destructor (struct wl_client *client,
|
||||||
|
struct wl_resource *resource)
|
||||||
|
{
|
||||||
|
wl_resource_destroy (resource);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
set_selection_source (MetaWaylandDataDevicePrimaryLegacy *data_device,
|
||||||
|
MetaSelectionSource *selection_source)
|
||||||
|
|
||||||
|
{
|
||||||
|
MetaDisplay *display = meta_get_display ();
|
||||||
|
|
||||||
|
meta_selection_set_owner (meta_display_get_selection (display),
|
||||||
|
META_SELECTION_PRIMARY,
|
||||||
|
selection_source);
|
||||||
|
g_set_object (&data_device->owner, selection_source);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
unset_selection_source (MetaWaylandDataDevicePrimaryLegacy *data_device)
|
||||||
|
{
|
||||||
|
MetaDisplay *display = meta_get_display ();
|
||||||
|
|
||||||
|
if (!data_device->owner)
|
||||||
|
return;
|
||||||
|
|
||||||
|
meta_selection_unset_owner (meta_display_get_selection (display),
|
||||||
|
META_SELECTION_PRIMARY,
|
||||||
|
data_device->owner);
|
||||||
|
g_clear_object (&data_device->owner);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
primary_source_destroyed (gpointer data,
|
||||||
|
GObject *object_was_here)
|
||||||
|
{
|
||||||
|
MetaWaylandDataDevicePrimaryLegacy *data_device = data;
|
||||||
|
|
||||||
|
data_device->data_source = NULL;
|
||||||
|
unset_selection_source (data_device);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_wayland_data_device_primary_legacy_set_selection (MetaWaylandDataDevicePrimaryLegacy *data_device,
|
||||||
|
MetaWaylandDataSource *source,
|
||||||
|
uint32_t serial)
|
||||||
|
{
|
||||||
|
MetaWaylandSeat *seat = wl_container_of (data_device, seat, primary_legacy_data_device);
|
||||||
|
MetaSelectionSource *selection_source;
|
||||||
|
|
||||||
|
g_assert (!source || META_IS_WAYLAND_DATA_SOURCE_PRIMARY_LEGACY (source));
|
||||||
|
|
||||||
|
if (data_device->data_source &&
|
||||||
|
data_device->serial - serial < UINT32_MAX / 2)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (data_device->data_source)
|
||||||
|
{
|
||||||
|
g_object_weak_unref (G_OBJECT (data_device->data_source),
|
||||||
|
primary_source_destroyed,
|
||||||
|
data_device);
|
||||||
|
}
|
||||||
|
|
||||||
|
data_device->data_source = source;
|
||||||
|
data_device->serial = serial;
|
||||||
|
|
||||||
|
if (source)
|
||||||
|
{
|
||||||
|
meta_wayland_data_source_set_seat (source, seat);
|
||||||
|
g_object_weak_ref (G_OBJECT (source),
|
||||||
|
primary_source_destroyed,
|
||||||
|
data_device);
|
||||||
|
|
||||||
|
selection_source = meta_selection_source_wayland_new (source);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
selection_source = g_object_new (META_TYPE_SELECTION_SOURCE_MEMORY, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
set_selection_source (data_device, selection_source);
|
||||||
|
g_object_unref (selection_source);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
primary_device_set_selection (struct wl_client *client,
|
||||||
|
struct wl_resource *resource,
|
||||||
|
struct wl_resource *source_resource,
|
||||||
|
uint32_t serial)
|
||||||
|
{
|
||||||
|
MetaWaylandDataDevicePrimaryLegacy *data_device = wl_resource_get_user_data (resource);
|
||||||
|
MetaWaylandSeat *seat = wl_container_of (data_device, seat, primary_legacy_data_device);
|
||||||
|
MetaWaylandDataSource *source = NULL;
|
||||||
|
|
||||||
|
if (source_resource)
|
||||||
|
source = wl_resource_get_user_data (source_resource);
|
||||||
|
|
||||||
|
if (wl_resource_get_client (resource) !=
|
||||||
|
meta_wayland_keyboard_get_focus_client (seat->keyboard))
|
||||||
|
return;
|
||||||
|
|
||||||
|
meta_wayland_data_device_primary_legacy_set_selection (data_device, source, serial);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct gtk_primary_selection_device_interface primary_device_interface = {
|
||||||
|
primary_device_set_selection,
|
||||||
|
default_destructor,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
owner_changed_cb (MetaSelection *selection,
|
||||||
|
MetaSelectionType selection_type,
|
||||||
|
MetaSelectionSource *new_owner,
|
||||||
|
MetaWaylandDataDevicePrimaryLegacy *data_device)
|
||||||
|
{
|
||||||
|
MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default ();
|
||||||
|
MetaWaylandSeat *seat = compositor->seat;
|
||||||
|
struct wl_resource *data_device_resource;
|
||||||
|
struct wl_client *focus_client;
|
||||||
|
|
||||||
|
focus_client = meta_wayland_keyboard_get_focus_client (seat->keyboard);
|
||||||
|
if (!focus_client)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (selection_type == META_SELECTION_PRIMARY)
|
||||||
|
{
|
||||||
|
wl_resource_for_each (data_device_resource, &data_device->focus_resource_list)
|
||||||
|
{
|
||||||
|
struct wl_resource *offer = NULL;
|
||||||
|
|
||||||
|
if (new_owner)
|
||||||
|
{
|
||||||
|
offer = create_and_send_primary_offer (data_device,
|
||||||
|
data_device_resource);
|
||||||
|
}
|
||||||
|
|
||||||
|
gtk_primary_selection_device_send_selection (data_device_resource,
|
||||||
|
offer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
ensure_owners_changed_handler_connected (MetaWaylandDataDevicePrimaryLegacy *data_device)
|
||||||
|
{
|
||||||
|
if (data_device->selection_owner_signal_id != 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
data_device->selection_owner_signal_id =
|
||||||
|
g_signal_connect (meta_display_get_selection (meta_get_display ()),
|
||||||
|
"owner-changed",
|
||||||
|
G_CALLBACK (owner_changed_cb), data_device);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
primary_device_manager_create_source (struct wl_client *client,
|
||||||
|
struct wl_resource *manager_resource,
|
||||||
|
guint32 id)
|
||||||
|
{
|
||||||
|
struct wl_resource *source_resource;
|
||||||
|
|
||||||
|
source_resource =
|
||||||
|
wl_resource_create (client, >k_primary_selection_source_interface,
|
||||||
|
wl_resource_get_version (manager_resource),
|
||||||
|
id);
|
||||||
|
meta_wayland_data_source_primary_legacy_new (source_resource);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
primary_device_manager_get_device (struct wl_client *client,
|
||||||
|
struct wl_resource *manager_resource,
|
||||||
|
guint32 id,
|
||||||
|
struct wl_resource *seat_resource)
|
||||||
|
{
|
||||||
|
MetaWaylandSeat *seat = wl_resource_get_user_data (seat_resource);
|
||||||
|
struct wl_resource *cr;
|
||||||
|
|
||||||
|
cr = wl_resource_create (client, >k_primary_selection_device_interface,
|
||||||
|
wl_resource_get_version (manager_resource), id);
|
||||||
|
wl_resource_set_implementation (cr, &primary_device_interface,
|
||||||
|
&seat->primary_legacy_data_device, unbind_resource);
|
||||||
|
wl_list_insert (&seat->primary_legacy_data_device.resource_list,
|
||||||
|
wl_resource_get_link (cr));
|
||||||
|
|
||||||
|
ensure_owners_changed_handler_connected (&seat->primary_legacy_data_device);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct gtk_primary_selection_device_manager_interface primary_manager_interface = {
|
||||||
|
primary_device_manager_create_source,
|
||||||
|
primary_device_manager_get_device,
|
||||||
|
default_destructor,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
bind_primary_manager (struct wl_client *client,
|
||||||
|
void *data,
|
||||||
|
uint32_t version,
|
||||||
|
uint32_t id)
|
||||||
|
{
|
||||||
|
struct wl_resource *resource;
|
||||||
|
|
||||||
|
resource = wl_resource_create (client, >k_primary_selection_device_manager_interface,
|
||||||
|
version, id);
|
||||||
|
wl_resource_set_implementation (resource, &primary_manager_interface, NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_wayland_data_device_primary_legacy_manager_init (MetaWaylandCompositor *compositor)
|
||||||
|
{
|
||||||
|
if (wl_global_create (compositor->wayland_display,
|
||||||
|
>k_primary_selection_device_manager_interface,
|
||||||
|
1, NULL, bind_primary_manager) == NULL)
|
||||||
|
g_error ("Could not create data_device");
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_wayland_data_device_primary_legacy_init (MetaWaylandDataDevicePrimaryLegacy *data_device)
|
||||||
|
{
|
||||||
|
wl_list_init (&data_device->resource_list);
|
||||||
|
wl_list_init (&data_device->focus_resource_list);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct wl_resource *
|
||||||
|
create_and_send_primary_offer (MetaWaylandDataDevicePrimaryLegacy *data_device,
|
||||||
|
struct wl_resource *target)
|
||||||
|
{
|
||||||
|
MetaWaylandDataOffer *offer;
|
||||||
|
MetaDisplay *display = meta_get_display ();
|
||||||
|
struct wl_resource *resource;
|
||||||
|
GList *mimetypes, *l;
|
||||||
|
|
||||||
|
mimetypes = meta_selection_get_mimetypes (meta_display_get_selection (display),
|
||||||
|
META_SELECTION_PRIMARY);
|
||||||
|
if (!mimetypes)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
offer = meta_wayland_data_offer_primary_legacy_new (target);
|
||||||
|
resource = meta_wayland_data_offer_get_resource (offer);
|
||||||
|
|
||||||
|
gtk_primary_selection_device_send_data_offer (target, resource);
|
||||||
|
|
||||||
|
for (l = mimetypes; l; l = l->next)
|
||||||
|
gtk_primary_selection_offer_send_offer (resource, l->data);
|
||||||
|
|
||||||
|
g_list_free_full (mimetypes, g_free);
|
||||||
|
|
||||||
|
return resource;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_wayland_data_device_primary_legacy_set_keyboard_focus (MetaWaylandDataDevicePrimaryLegacy *data_device)
|
||||||
|
{
|
||||||
|
MetaWaylandSeat *seat = wl_container_of (data_device, seat, primary_legacy_data_device);
|
||||||
|
struct wl_client *focus_client;
|
||||||
|
struct wl_resource *data_device_resource;
|
||||||
|
|
||||||
|
focus_client = meta_wayland_keyboard_get_focus_client (seat->keyboard);
|
||||||
|
|
||||||
|
if (focus_client == data_device->focus_client)
|
||||||
|
return;
|
||||||
|
|
||||||
|
data_device->focus_client = focus_client;
|
||||||
|
move_resources (&data_device->resource_list,
|
||||||
|
&data_device->focus_resource_list);
|
||||||
|
|
||||||
|
if (!focus_client)
|
||||||
|
return;
|
||||||
|
|
||||||
|
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_primary_offer (data_device, data_device_resource);
|
||||||
|
gtk_primary_selection_device_send_selection (data_device_resource, offer);
|
||||||
|
}
|
||||||
|
}
|
||||||
55
src/wayland/meta-wayland-data-device-primary-legacy.h
Normal file
55
src/wayland/meta-wayland-data-device-primary-legacy.h
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
/*
|
||||||
|
* Copyright © 2008 Kristian Høgsberg
|
||||||
|
* 2020 Red Hat Inc.
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||||
|
* documentation for any purpose is hereby granted without fee, provided that
|
||||||
|
* the above copyright notice appear in all copies and that both that copyright
|
||||||
|
* notice and this permission notice appear in supporting documentation, and
|
||||||
|
* that the name of the copyright holders not be used in advertising or
|
||||||
|
* publicity pertaining to distribution of the software without specific,
|
||||||
|
* written prior permission. The copyright holders make no representations
|
||||||
|
* about the suitability of this software for any purpose. It is provided "as
|
||||||
|
* is" without express or implied warranty.
|
||||||
|
*
|
||||||
|
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||||
|
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||||
|
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||||
|
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||||
|
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||||
|
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
|
||||||
|
* OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef META_WAYLAND_DATA_DEVICE_PRIMARY_LEGACY_H
|
||||||
|
#define META_WAYLAND_DATA_DEVICE_PRIMARY_LEGACY_H
|
||||||
|
|
||||||
|
#include <glib-object.h>
|
||||||
|
#include <wayland-server.h>
|
||||||
|
|
||||||
|
#include "clutter/clutter.h"
|
||||||
|
#include "meta/meta-selection-source.h"
|
||||||
|
#include "wayland/meta-wayland-data-offer.h"
|
||||||
|
#include "wayland/meta-wayland-data-source.h"
|
||||||
|
#include "wayland/meta-wayland-types.h"
|
||||||
|
|
||||||
|
struct _MetaWaylandDataDevicePrimaryLegacy
|
||||||
|
{
|
||||||
|
uint32_t serial;
|
||||||
|
MetaWaylandDataSource *data_source;
|
||||||
|
struct wl_list resource_list;
|
||||||
|
struct wl_list focus_resource_list;
|
||||||
|
struct wl_client *focus_client;
|
||||||
|
|
||||||
|
guint selection_owner_signal_id;
|
||||||
|
|
||||||
|
MetaSelectionSource *owner;
|
||||||
|
};
|
||||||
|
|
||||||
|
void meta_wayland_data_device_primary_legacy_manager_init (MetaWaylandCompositor *compositor);
|
||||||
|
|
||||||
|
void meta_wayland_data_device_primary_legacy_init (MetaWaylandDataDevicePrimaryLegacy *data_device);
|
||||||
|
|
||||||
|
void meta_wayland_data_device_primary_legacy_set_keyboard_focus (MetaWaylandDataDevicePrimaryLegacy *data_device);
|
||||||
|
|
||||||
|
#endif /* META_WAYLAND_DATA_DEVICE_PRIMARY_LEGACY_H */
|
||||||
353
src/wayland/meta-wayland-data-device-primary.c
Normal file
353
src/wayland/meta-wayland-data-device-primary.c
Normal file
@@ -0,0 +1,353 @@
|
|||||||
|
/*
|
||||||
|
* Copyright © 2011 Kristian Høgsberg
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||||
|
* documentation for any purpose is hereby granted without fee, provided that
|
||||||
|
* the above copyright notice appear in all copies and that both that copyright
|
||||||
|
* notice and this permission notice appear in supporting documentation, and
|
||||||
|
* that the name of the copyright holders not be used in advertising or
|
||||||
|
* publicity pertaining to distribution of the software without specific,
|
||||||
|
* written prior permission. The copyright holders make no representations
|
||||||
|
* about the suitability of this software for any purpose. It is provided "as
|
||||||
|
* is" without express or implied warranty.
|
||||||
|
*
|
||||||
|
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||||
|
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||||
|
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||||
|
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||||
|
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||||
|
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
|
||||||
|
* OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* The file is based on src/data-device.c from Weston */
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include "wayland/meta-wayland-data-device-primary.h"
|
||||||
|
|
||||||
|
#include "compositor/meta-dnd-actor-private.h"
|
||||||
|
#include "meta/meta-selection-source-memory.h"
|
||||||
|
#include "wayland/meta-selection-source-wayland-private.h"
|
||||||
|
#include "wayland/meta-wayland-data-offer-primary.h"
|
||||||
|
#include "wayland/meta-wayland-data-source-primary.h"
|
||||||
|
#include "wayland/meta-wayland-dnd-surface.h"
|
||||||
|
#include "wayland/meta-wayland-pointer.h"
|
||||||
|
#include "wayland/meta-wayland-private.h"
|
||||||
|
#include "wayland/meta-wayland-seat.h"
|
||||||
|
|
||||||
|
#include "primary-selection-unstable-v1-server-protocol.h"
|
||||||
|
|
||||||
|
static struct wl_resource * create_and_send_primary_offer (MetaWaylandDataDevicePrimary *data_device,
|
||||||
|
struct wl_resource *target);
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
wl_list_remove (wl_resource_get_link (resource));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
default_destructor (struct wl_client *client,
|
||||||
|
struct wl_resource *resource)
|
||||||
|
{
|
||||||
|
wl_resource_destroy (resource);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
set_selection_source (MetaWaylandDataDevicePrimary *data_device,
|
||||||
|
MetaSelectionSource *selection_source)
|
||||||
|
|
||||||
|
{
|
||||||
|
MetaDisplay *display = meta_get_display ();
|
||||||
|
|
||||||
|
meta_selection_set_owner (meta_display_get_selection (display),
|
||||||
|
META_SELECTION_PRIMARY,
|
||||||
|
selection_source);
|
||||||
|
g_set_object (&data_device->owner, selection_source);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
unset_selection_source (MetaWaylandDataDevicePrimary *data_device)
|
||||||
|
{
|
||||||
|
MetaDisplay *display = meta_get_display ();
|
||||||
|
|
||||||
|
if (!data_device->owner)
|
||||||
|
return;
|
||||||
|
|
||||||
|
meta_selection_unset_owner (meta_display_get_selection (display),
|
||||||
|
META_SELECTION_PRIMARY,
|
||||||
|
data_device->owner);
|
||||||
|
g_clear_object (&data_device->owner);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
primary_source_destroyed (gpointer data,
|
||||||
|
GObject *object_was_here)
|
||||||
|
{
|
||||||
|
MetaWaylandDataDevicePrimary *data_device = data;
|
||||||
|
|
||||||
|
data_device->data_source = NULL;
|
||||||
|
unset_selection_source (data_device);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_wayland_data_device_primary_set_selection (MetaWaylandDataDevicePrimary *data_device,
|
||||||
|
MetaWaylandDataSource *source,
|
||||||
|
uint32_t serial)
|
||||||
|
{
|
||||||
|
MetaWaylandSeat *seat = wl_container_of (data_device, seat, primary_data_device);
|
||||||
|
MetaSelectionSource *selection_source;
|
||||||
|
|
||||||
|
g_assert (!source || META_IS_WAYLAND_DATA_SOURCE_PRIMARY (source));
|
||||||
|
|
||||||
|
if (data_device->data_source &&
|
||||||
|
data_device->serial - serial < UINT32_MAX / 2)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (data_device->data_source)
|
||||||
|
{
|
||||||
|
g_object_weak_unref (G_OBJECT (data_device->data_source),
|
||||||
|
primary_source_destroyed,
|
||||||
|
data_device);
|
||||||
|
}
|
||||||
|
|
||||||
|
data_device->data_source = source;
|
||||||
|
data_device->serial = serial;
|
||||||
|
|
||||||
|
if (source)
|
||||||
|
{
|
||||||
|
meta_wayland_data_source_set_seat (source, seat);
|
||||||
|
g_object_weak_ref (G_OBJECT (source),
|
||||||
|
primary_source_destroyed,
|
||||||
|
data_device);
|
||||||
|
|
||||||
|
selection_source = meta_selection_source_wayland_new (source);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
selection_source = g_object_new (META_TYPE_SELECTION_SOURCE_MEMORY, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
set_selection_source (data_device, selection_source);
|
||||||
|
g_object_unref (selection_source);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
primary_device_set_selection (struct wl_client *client,
|
||||||
|
struct wl_resource *resource,
|
||||||
|
struct wl_resource *source_resource,
|
||||||
|
uint32_t serial)
|
||||||
|
{
|
||||||
|
MetaWaylandDataDevicePrimary *data_device = wl_resource_get_user_data (resource);
|
||||||
|
MetaWaylandSeat *seat = wl_container_of (data_device, seat, primary_data_device);
|
||||||
|
MetaWaylandDataSource *source = NULL;
|
||||||
|
|
||||||
|
if (source_resource)
|
||||||
|
source = wl_resource_get_user_data (source_resource);
|
||||||
|
|
||||||
|
if (wl_resource_get_client (resource) !=
|
||||||
|
meta_wayland_keyboard_get_focus_client (seat->keyboard))
|
||||||
|
return;
|
||||||
|
|
||||||
|
meta_wayland_data_device_primary_set_selection (data_device, source, serial);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct zwp_primary_selection_device_v1_interface primary_device_interface = {
|
||||||
|
primary_device_set_selection,
|
||||||
|
default_destructor,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
owner_changed_cb (MetaSelection *selection,
|
||||||
|
MetaSelectionType selection_type,
|
||||||
|
MetaSelectionSource *new_owner,
|
||||||
|
MetaWaylandDataDevicePrimary *data_device)
|
||||||
|
{
|
||||||
|
MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default ();
|
||||||
|
MetaWaylandSeat *seat = compositor->seat;
|
||||||
|
struct wl_resource *data_device_resource;
|
||||||
|
struct wl_client *focus_client;
|
||||||
|
|
||||||
|
focus_client = meta_wayland_keyboard_get_focus_client (seat->keyboard);
|
||||||
|
if (!focus_client)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (selection_type == META_SELECTION_PRIMARY)
|
||||||
|
{
|
||||||
|
wl_resource_for_each (data_device_resource, &data_device->focus_resource_list)
|
||||||
|
{
|
||||||
|
struct wl_resource *offer = NULL;
|
||||||
|
|
||||||
|
if (new_owner)
|
||||||
|
{
|
||||||
|
offer = create_and_send_primary_offer (data_device,
|
||||||
|
data_device_resource);
|
||||||
|
}
|
||||||
|
|
||||||
|
zwp_primary_selection_device_v1_send_selection (data_device_resource,
|
||||||
|
offer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
ensure_owners_changed_handler_connected (MetaWaylandDataDevicePrimary *data_device)
|
||||||
|
{
|
||||||
|
if (data_device->selection_owner_signal_id != 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
data_device->selection_owner_signal_id =
|
||||||
|
g_signal_connect (meta_display_get_selection (meta_get_display ()),
|
||||||
|
"owner-changed",
|
||||||
|
G_CALLBACK (owner_changed_cb), data_device);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
primary_device_manager_create_source (struct wl_client *client,
|
||||||
|
struct wl_resource *manager_resource,
|
||||||
|
guint32 id)
|
||||||
|
{
|
||||||
|
struct wl_resource *source_resource;
|
||||||
|
|
||||||
|
source_resource =
|
||||||
|
wl_resource_create (client, &zwp_primary_selection_source_v1_interface,
|
||||||
|
wl_resource_get_version (manager_resource),
|
||||||
|
id);
|
||||||
|
meta_wayland_data_source_primary_new (source_resource);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
primary_device_manager_get_device (struct wl_client *client,
|
||||||
|
struct wl_resource *manager_resource,
|
||||||
|
guint32 id,
|
||||||
|
struct wl_resource *seat_resource)
|
||||||
|
{
|
||||||
|
MetaWaylandSeat *seat = wl_resource_get_user_data (seat_resource);
|
||||||
|
struct wl_resource *cr;
|
||||||
|
|
||||||
|
cr = wl_resource_create (client, &zwp_primary_selection_device_v1_interface,
|
||||||
|
wl_resource_get_version (manager_resource), id);
|
||||||
|
wl_resource_set_implementation (cr, &primary_device_interface,
|
||||||
|
&seat->primary_data_device, unbind_resource);
|
||||||
|
wl_list_insert (&seat->primary_data_device.resource_list, wl_resource_get_link (cr));
|
||||||
|
|
||||||
|
ensure_owners_changed_handler_connected (&seat->primary_data_device);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct zwp_primary_selection_device_manager_v1_interface primary_manager_interface = {
|
||||||
|
primary_device_manager_create_source,
|
||||||
|
primary_device_manager_get_device,
|
||||||
|
default_destructor,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
bind_primary_manager (struct wl_client *client,
|
||||||
|
void *data,
|
||||||
|
uint32_t version,
|
||||||
|
uint32_t id)
|
||||||
|
{
|
||||||
|
struct wl_resource *resource;
|
||||||
|
|
||||||
|
resource = wl_resource_create (client, &zwp_primary_selection_device_manager_v1_interface,
|
||||||
|
version, id);
|
||||||
|
wl_resource_set_implementation (resource, &primary_manager_interface, NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_wayland_data_device_primary_manager_init (MetaWaylandCompositor *compositor)
|
||||||
|
{
|
||||||
|
if (wl_global_create (compositor->wayland_display,
|
||||||
|
&zwp_primary_selection_device_manager_v1_interface,
|
||||||
|
1, NULL, bind_primary_manager) == NULL)
|
||||||
|
g_error ("Could not create data_device");
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_wayland_data_device_primary_init (MetaWaylandDataDevicePrimary *data_device)
|
||||||
|
{
|
||||||
|
wl_list_init (&data_device->resource_list);
|
||||||
|
wl_list_init (&data_device->focus_resource_list);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct wl_resource *
|
||||||
|
create_and_send_primary_offer (MetaWaylandDataDevicePrimary *data_device,
|
||||||
|
struct wl_resource *target)
|
||||||
|
{
|
||||||
|
MetaWaylandDataOffer *offer;
|
||||||
|
MetaDisplay *display = meta_get_display ();
|
||||||
|
struct wl_resource *resource;
|
||||||
|
GList *mimetypes, *l;
|
||||||
|
|
||||||
|
mimetypes = meta_selection_get_mimetypes (meta_display_get_selection (display),
|
||||||
|
META_SELECTION_PRIMARY);
|
||||||
|
if (!mimetypes)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
offer = meta_wayland_data_offer_primary_new (target);
|
||||||
|
resource = meta_wayland_data_offer_get_resource (offer);
|
||||||
|
|
||||||
|
zwp_primary_selection_device_v1_send_data_offer (target, resource);
|
||||||
|
|
||||||
|
for (l = mimetypes; l; l = l->next)
|
||||||
|
zwp_primary_selection_offer_v1_send_offer (resource, l->data);
|
||||||
|
|
||||||
|
g_list_free_full (mimetypes, g_free);
|
||||||
|
|
||||||
|
return resource;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_wayland_data_device_primary_set_keyboard_focus (MetaWaylandDataDevicePrimary *data_device)
|
||||||
|
{
|
||||||
|
MetaWaylandSeat *seat = wl_container_of (data_device, seat, primary_data_device);
|
||||||
|
struct wl_client *focus_client;
|
||||||
|
struct wl_resource *data_device_resource;
|
||||||
|
|
||||||
|
focus_client = meta_wayland_keyboard_get_focus_client (seat->keyboard);
|
||||||
|
|
||||||
|
if (focus_client == data_device->focus_client)
|
||||||
|
return;
|
||||||
|
|
||||||
|
data_device->focus_client = focus_client;
|
||||||
|
move_resources (&data_device->resource_list,
|
||||||
|
&data_device->focus_resource_list);
|
||||||
|
|
||||||
|
if (!focus_client)
|
||||||
|
return;
|
||||||
|
|
||||||
|
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_primary_offer (data_device, data_device_resource);
|
||||||
|
zwp_primary_selection_device_v1_send_selection (data_device_resource, offer);
|
||||||
|
}
|
||||||
|
}
|
||||||
55
src/wayland/meta-wayland-data-device-primary.h
Normal file
55
src/wayland/meta-wayland-data-device-primary.h
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
/*
|
||||||
|
* Copyright © 2008 Kristian Høgsberg
|
||||||
|
* 2020 Red Hat Inc.
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||||
|
* documentation for any purpose is hereby granted without fee, provided that
|
||||||
|
* the above copyright notice appear in all copies and that both that copyright
|
||||||
|
* notice and this permission notice appear in supporting documentation, and
|
||||||
|
* that the name of the copyright holders not be used in advertising or
|
||||||
|
* publicity pertaining to distribution of the software without specific,
|
||||||
|
* written prior permission. The copyright holders make no representations
|
||||||
|
* about the suitability of this software for any purpose. It is provided "as
|
||||||
|
* is" without express or implied warranty.
|
||||||
|
*
|
||||||
|
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||||
|
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||||
|
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||||
|
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||||
|
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||||
|
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
|
||||||
|
* OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef META_WAYLAND_DATA_DEVICE_PRIMARY_H
|
||||||
|
#define META_WAYLAND_DATA_DEVICE_PRIMARY_H
|
||||||
|
|
||||||
|
#include <glib-object.h>
|
||||||
|
#include <wayland-server.h>
|
||||||
|
|
||||||
|
#include "clutter/clutter.h"
|
||||||
|
#include "meta/meta-selection-source.h"
|
||||||
|
#include "wayland/meta-wayland-data-offer.h"
|
||||||
|
#include "wayland/meta-wayland-data-source.h"
|
||||||
|
#include "wayland/meta-wayland-types.h"
|
||||||
|
|
||||||
|
struct _MetaWaylandDataDevicePrimary
|
||||||
|
{
|
||||||
|
uint32_t serial;
|
||||||
|
MetaWaylandDataSource *data_source;
|
||||||
|
struct wl_list resource_list;
|
||||||
|
struct wl_list focus_resource_list;
|
||||||
|
struct wl_client *focus_client;
|
||||||
|
|
||||||
|
guint selection_owner_signal_id;
|
||||||
|
|
||||||
|
MetaSelectionSource *owner;
|
||||||
|
};
|
||||||
|
|
||||||
|
void meta_wayland_data_device_primary_manager_init (MetaWaylandCompositor *compositor);
|
||||||
|
|
||||||
|
void meta_wayland_data_device_primary_init (MetaWaylandDataDevicePrimary *data_device);
|
||||||
|
|
||||||
|
void meta_wayland_data_device_primary_set_keyboard_focus (MetaWaylandDataDevicePrimary *data_device);
|
||||||
|
|
||||||
|
#endif /* META_WAYLAND_DATA_DEVICE_PRIMARY_H */
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright (C) 2015 Red Hat
|
|
||||||
*
|
|
||||||
* 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, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
|
||||||
* 02111-1307, USA.
|
|
||||||
*
|
|
||||||
* Written by:
|
|
||||||
* Jonas Ådahl <jadahl@gmail.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef META_WAYLAND_DATA_DEVICE_PRIVATE_H
|
|
||||||
#define META_WAYLAND_DATA_DEVICE_PRIVATE_H
|
|
||||||
|
|
||||||
#define META_TYPE_WAYLAND_DATA_SOURCE_PRIMARY (meta_wayland_data_source_primary_get_type ())
|
|
||||||
G_DECLARE_FINAL_TYPE (MetaWaylandDataSourcePrimary,
|
|
||||||
meta_wayland_data_source_primary,
|
|
||||||
META, WAYLAND_DATA_SOURCE_PRIMARY,
|
|
||||||
MetaWaylandDataSource);
|
|
||||||
|
|
||||||
#endif /* META_WAYLAND_DATA_DEVICE_PRIVATE_H */
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -28,44 +28,20 @@
|
|||||||
|
|
||||||
#include "clutter/clutter.h"
|
#include "clutter/clutter.h"
|
||||||
#include "meta/meta-selection-source.h"
|
#include "meta/meta-selection-source.h"
|
||||||
|
#include "wayland/meta-wayland-data-offer.h"
|
||||||
|
#include "wayland/meta-wayland-data-source.h"
|
||||||
#include "wayland/meta-wayland-types.h"
|
#include "wayland/meta-wayland-types.h"
|
||||||
|
|
||||||
typedef struct _MetaWaylandDragGrab MetaWaylandDragGrab;
|
typedef struct _MetaWaylandDragGrab MetaWaylandDragGrab;
|
||||||
typedef struct _MetaWaylandDataSourceFuncs MetaWaylandDataSourceFuncs;
|
typedef struct _MetaWaylandDataSourceFuncs MetaWaylandDataSourceFuncs;
|
||||||
|
|
||||||
#define META_TYPE_WAYLAND_DATA_SOURCE (meta_wayland_data_source_get_type ())
|
|
||||||
G_DECLARE_DERIVABLE_TYPE (MetaWaylandDataSource, meta_wayland_data_source,
|
|
||||||
META, WAYLAND_DATA_SOURCE, GObject);
|
|
||||||
|
|
||||||
struct _MetaWaylandDataSourceClass
|
|
||||||
{
|
|
||||||
GObjectClass parent_class;
|
|
||||||
|
|
||||||
void (* send) (MetaWaylandDataSource *source,
|
|
||||||
const gchar *mime_type,
|
|
||||||
gint fd);
|
|
||||||
void (* target) (MetaWaylandDataSource *source,
|
|
||||||
const gchar *mime_type);
|
|
||||||
void (* cancel) (MetaWaylandDataSource *source);
|
|
||||||
|
|
||||||
void (* action) (MetaWaylandDataSource *source,
|
|
||||||
uint32_t action);
|
|
||||||
void (* drop_performed) (MetaWaylandDataSource *source);
|
|
||||||
void (* drag_finished) (MetaWaylandDataSource *source);
|
|
||||||
};
|
|
||||||
|
|
||||||
struct _MetaWaylandDataDevice
|
struct _MetaWaylandDataDevice
|
||||||
{
|
{
|
||||||
uint32_t selection_serial;
|
uint32_t selection_serial;
|
||||||
uint32_t primary_serial;
|
|
||||||
MetaWaylandDataSource *selection_data_source;
|
MetaWaylandDataSource *selection_data_source;
|
||||||
MetaWaylandDataSource *dnd_data_source;
|
MetaWaylandDataSource *dnd_data_source;
|
||||||
MetaWaylandDataSource *primary_data_source;
|
|
||||||
struct wl_listener selection_data_source_listener;
|
|
||||||
struct wl_list resource_list;
|
struct wl_list resource_list;
|
||||||
struct wl_list focus_resource_list;
|
struct wl_list focus_resource_list;
|
||||||
struct wl_list primary_resource_list;
|
|
||||||
struct wl_list primary_focus_resource_list;
|
|
||||||
MetaWaylandDragGrab *current_grab;
|
MetaWaylandDragGrab *current_grab;
|
||||||
struct wl_client *focus_client;
|
struct wl_client *focus_client;
|
||||||
|
|
||||||
@@ -91,42 +67,7 @@ void meta_wayland_data_device_set_dnd_source (MetaWaylandDataDevice *data_de
|
|||||||
void meta_wayland_data_device_set_selection (MetaWaylandDataDevice *data_device,
|
void meta_wayland_data_device_set_selection (MetaWaylandDataDevice *data_device,
|
||||||
MetaWaylandDataSource *source,
|
MetaWaylandDataSource *source,
|
||||||
guint32 serial);
|
guint32 serial);
|
||||||
void meta_wayland_data_device_set_primary (MetaWaylandDataDevice *data_device,
|
void meta_wayland_data_device_unset_dnd_selection (MetaWaylandDataDevice *data_device);
|
||||||
MetaWaylandDataSource *source,
|
|
||||||
guint32 serial);
|
|
||||||
|
|
||||||
gboolean meta_wayland_data_source_add_mime_type (MetaWaylandDataSource *source,
|
|
||||||
const gchar *mime_type);
|
|
||||||
|
|
||||||
gboolean meta_wayland_data_source_has_mime_type (const MetaWaylandDataSource *source,
|
|
||||||
const gchar *mime_type);
|
|
||||||
|
|
||||||
struct wl_array *
|
|
||||||
meta_wayland_data_source_get_mime_types (const MetaWaylandDataSource *source);
|
|
||||||
|
|
||||||
gboolean meta_wayland_data_source_has_target (MetaWaylandDataSource *source);
|
|
||||||
|
|
||||||
void meta_wayland_data_source_set_has_target (MetaWaylandDataSource *source,
|
|
||||||
gboolean has_target);
|
|
||||||
|
|
||||||
void meta_wayland_data_source_cancel (MetaWaylandDataSource *source);
|
|
||||||
|
|
||||||
void meta_wayland_data_source_send (MetaWaylandDataSource *source,
|
|
||||||
const gchar *mime_type,
|
|
||||||
gint fd);
|
|
||||||
|
|
||||||
void meta_wayland_data_source_notify_finish (MetaWaylandDataSource *source);
|
|
||||||
|
|
||||||
uint32_t meta_wayland_data_source_get_actions (MetaWaylandDataSource *source);
|
|
||||||
uint32_t meta_wayland_data_source_get_user_action (MetaWaylandDataSource *source);
|
|
||||||
uint32_t meta_wayland_data_source_get_current_action (MetaWaylandDataSource *source);
|
|
||||||
|
|
||||||
void meta_wayland_data_source_set_actions (MetaWaylandDataSource *source,
|
|
||||||
uint32_t dnd_actions);
|
|
||||||
void meta_wayland_data_source_set_user_action (MetaWaylandDataSource *source,
|
|
||||||
uint32_t action);
|
|
||||||
void meta_wayland_data_source_set_current_action (MetaWaylandDataSource *source,
|
|
||||||
uint32_t action);
|
|
||||||
|
|
||||||
const MetaWaylandDragDestFuncs *
|
const MetaWaylandDragDestFuncs *
|
||||||
meta_wayland_data_device_get_drag_dest_funcs (void);
|
meta_wayland_data_device_get_drag_dest_funcs (void);
|
||||||
|
|||||||
139
src/wayland/meta-wayland-data-offer-primary-legacy.c
Normal file
139
src/wayland/meta-wayland-data-offer-primary-legacy.c
Normal file
@@ -0,0 +1,139 @@
|
|||||||
|
/*
|
||||||
|
* Copyright © 2011 Kristian Høgsberg
|
||||||
|
* 2020 Red Hat Inc.
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||||
|
* documentation for any purpose is hereby granted without fee, provided that
|
||||||
|
* the above copyright notice appear in all copies and that both that copyright
|
||||||
|
* notice and this permission notice appear in supporting documentation, and
|
||||||
|
* that the name of the copyright holders not be used in advertising or
|
||||||
|
* publicity pertaining to distribution of the software without specific,
|
||||||
|
* written prior permission. The copyright holders make no representations
|
||||||
|
* about the suitability of this software for any purpose. It is provided "as
|
||||||
|
* is" without express or implied warranty.
|
||||||
|
*
|
||||||
|
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||||
|
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||||
|
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||||
|
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||||
|
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||||
|
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
|
||||||
|
* OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include "meta-wayland-data-offer-primary-legacy.h"
|
||||||
|
|
||||||
|
#include <gio/gunixoutputstream.h>
|
||||||
|
#include <glib-unix.h>
|
||||||
|
#include <glib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "core/display-private.h"
|
||||||
|
#include "gtk-primary-selection-server-protocol.h"
|
||||||
|
#include "wayland/meta-wayland-data-offer.h"
|
||||||
|
|
||||||
|
static void
|
||||||
|
transfer_cb (MetaSelection *selection,
|
||||||
|
GAsyncResult *res,
|
||||||
|
GOutputStream *stream)
|
||||||
|
{
|
||||||
|
GError *error = NULL;
|
||||||
|
|
||||||
|
if (!meta_selection_transfer_finish (selection, res, &error))
|
||||||
|
{
|
||||||
|
g_warning ("Could not fetch selection data: %s", error->message);
|
||||||
|
g_error_free (error);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_output_stream_close (stream, NULL, NULL);
|
||||||
|
g_object_unref (stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
primary_offer_receive (struct wl_client *client,
|
||||||
|
struct wl_resource *resource,
|
||||||
|
const char *mime_type,
|
||||||
|
int32_t fd)
|
||||||
|
{
|
||||||
|
MetaDisplay *display = meta_get_display ();
|
||||||
|
GOutputStream *stream;
|
||||||
|
GList *mime_types;
|
||||||
|
gboolean found;
|
||||||
|
|
||||||
|
mime_types = meta_selection_get_mimetypes (meta_display_get_selection (display),
|
||||||
|
META_SELECTION_PRIMARY);
|
||||||
|
found = g_list_find_custom (mime_types, mime_type, (GCompareFunc) g_strcmp0) != NULL;
|
||||||
|
g_list_free_full (mime_types, g_free);
|
||||||
|
|
||||||
|
if (!found)
|
||||||
|
{
|
||||||
|
close (fd);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
stream = g_unix_output_stream_new (fd, TRUE);
|
||||||
|
meta_selection_transfer_async (meta_display_get_selection (display),
|
||||||
|
META_SELECTION_PRIMARY,
|
||||||
|
mime_type,
|
||||||
|
-1,
|
||||||
|
stream,
|
||||||
|
NULL,
|
||||||
|
(GAsyncReadyCallback) transfer_cb,
|
||||||
|
stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
primary_offer_destroy (struct wl_client *client,
|
||||||
|
struct wl_resource *resource)
|
||||||
|
{
|
||||||
|
wl_resource_destroy (resource);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct gtk_primary_selection_offer_interface primary_offer_interface = {
|
||||||
|
primary_offer_receive,
|
||||||
|
primary_offer_destroy,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
destroy_primary_offer (struct wl_resource *resource)
|
||||||
|
{
|
||||||
|
MetaWaylandDataOffer *offer = wl_resource_get_user_data (resource);
|
||||||
|
|
||||||
|
if (offer->source)
|
||||||
|
{
|
||||||
|
if (offer == meta_wayland_data_source_get_current_offer (offer->source))
|
||||||
|
{
|
||||||
|
meta_wayland_data_source_cancel (offer->source);
|
||||||
|
meta_wayland_data_source_set_current_offer (offer->source, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_object_remove_weak_pointer (G_OBJECT (offer->source),
|
||||||
|
(gpointer *)&offer->source);
|
||||||
|
offer->source = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
meta_display_sync_wayland_input_focus (meta_get_display ());
|
||||||
|
g_slice_free (MetaWaylandDataOffer, offer);
|
||||||
|
}
|
||||||
|
|
||||||
|
MetaWaylandDataOffer *
|
||||||
|
meta_wayland_data_offer_primary_legacy_new (struct wl_resource *target)
|
||||||
|
{
|
||||||
|
MetaWaylandDataOffer *offer;
|
||||||
|
|
||||||
|
offer = g_slice_new0 (MetaWaylandDataOffer);
|
||||||
|
offer->selection_type = META_SELECTION_PRIMARY;
|
||||||
|
offer->resource = wl_resource_create (wl_resource_get_client (target),
|
||||||
|
>k_primary_selection_offer_interface,
|
||||||
|
wl_resource_get_version (target), 0);
|
||||||
|
wl_resource_set_implementation (offer->resource,
|
||||||
|
&primary_offer_interface,
|
||||||
|
offer,
|
||||||
|
destroy_primary_offer);
|
||||||
|
return offer;
|
||||||
|
}
|
||||||
31
src/wayland/meta-wayland-data-offer-primary-legacy.h
Normal file
31
src/wayland/meta-wayland-data-offer-primary-legacy.h
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* Copyright © 2011 Kristian Høgsberg
|
||||||
|
* 2020 Red Hat Inc.
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||||
|
* documentation for any purpose is hereby granted without fee, provided that
|
||||||
|
* the above copyright notice appear in all copies and that both that copyright
|
||||||
|
* notice and this permission notice appear in supporting documentation, and
|
||||||
|
* that the name of the copyright holders not be used in advertising or
|
||||||
|
* publicity pertaining to distribution of the software without specific,
|
||||||
|
* written prior permission. The copyright holders make no representations
|
||||||
|
* about the suitability of this software for any purpose. It is provided "as
|
||||||
|
* is" without express or implied warranty.
|
||||||
|
*
|
||||||
|
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||||
|
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||||
|
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||||
|
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||||
|
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||||
|
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
|
||||||
|
* OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef META_WAYLAND_DATA_OFFER_PRIMARY_LEGACY_H
|
||||||
|
#define META_WAYLAND_DATA_OFFER_PRIMARY_LEGACY_H
|
||||||
|
|
||||||
|
#include "meta-wayland-data-offer.h"
|
||||||
|
|
||||||
|
MetaWaylandDataOffer * meta_wayland_data_offer_primary_legacy_new (struct wl_resource *target);
|
||||||
|
|
||||||
|
#endif /* META_WAYLAND_DATA_OFFER_PRIMARY_LEGACY_H */
|
||||||
139
src/wayland/meta-wayland-data-offer-primary.c
Normal file
139
src/wayland/meta-wayland-data-offer-primary.c
Normal file
@@ -0,0 +1,139 @@
|
|||||||
|
/*
|
||||||
|
* Copyright © 2011 Kristian Høgsberg
|
||||||
|
* 2020 Red Hat Inc.
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||||
|
* documentation for any purpose is hereby granted without fee, provided that
|
||||||
|
* the above copyright notice appear in all copies and that both that copyright
|
||||||
|
* notice and this permission notice appear in supporting documentation, and
|
||||||
|
* that the name of the copyright holders not be used in advertising or
|
||||||
|
* publicity pertaining to distribution of the software without specific,
|
||||||
|
* written prior permission. The copyright holders make no representations
|
||||||
|
* about the suitability of this software for any purpose. It is provided "as
|
||||||
|
* is" without express or implied warranty.
|
||||||
|
*
|
||||||
|
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||||
|
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||||
|
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||||
|
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||||
|
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||||
|
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
|
||||||
|
* OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include "meta-wayland-data-offer-primary.h"
|
||||||
|
|
||||||
|
#include <gio/gunixoutputstream.h>
|
||||||
|
#include <glib-unix.h>
|
||||||
|
#include <glib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "core/display-private.h"
|
||||||
|
#include "primary-selection-unstable-v1-server-protocol.h"
|
||||||
|
#include "wayland/meta-wayland-data-offer.h"
|
||||||
|
|
||||||
|
static void
|
||||||
|
transfer_cb (MetaSelection *selection,
|
||||||
|
GAsyncResult *res,
|
||||||
|
GOutputStream *stream)
|
||||||
|
{
|
||||||
|
GError *error = NULL;
|
||||||
|
|
||||||
|
if (!meta_selection_transfer_finish (selection, res, &error))
|
||||||
|
{
|
||||||
|
g_warning ("Could not fetch selection data: %s", error->message);
|
||||||
|
g_error_free (error);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_output_stream_close (stream, NULL, NULL);
|
||||||
|
g_object_unref (stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
primary_offer_receive (struct wl_client *client,
|
||||||
|
struct wl_resource *resource,
|
||||||
|
const char *mime_type,
|
||||||
|
int32_t fd)
|
||||||
|
{
|
||||||
|
MetaDisplay *display = meta_get_display ();
|
||||||
|
GOutputStream *stream;
|
||||||
|
GList *mime_types;
|
||||||
|
gboolean found;
|
||||||
|
|
||||||
|
mime_types = meta_selection_get_mimetypes (meta_display_get_selection (display),
|
||||||
|
META_SELECTION_PRIMARY);
|
||||||
|
found = g_list_find_custom (mime_types, mime_type, (GCompareFunc) g_strcmp0) != NULL;
|
||||||
|
g_list_free_full (mime_types, g_free);
|
||||||
|
|
||||||
|
if (!found)
|
||||||
|
{
|
||||||
|
close (fd);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
stream = g_unix_output_stream_new (fd, TRUE);
|
||||||
|
meta_selection_transfer_async (meta_display_get_selection (display),
|
||||||
|
META_SELECTION_PRIMARY,
|
||||||
|
mime_type,
|
||||||
|
-1,
|
||||||
|
stream,
|
||||||
|
NULL,
|
||||||
|
(GAsyncReadyCallback) transfer_cb,
|
||||||
|
stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
primary_offer_destroy (struct wl_client *client,
|
||||||
|
struct wl_resource *resource)
|
||||||
|
{
|
||||||
|
wl_resource_destroy (resource);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct zwp_primary_selection_offer_v1_interface primary_offer_interface = {
|
||||||
|
primary_offer_receive,
|
||||||
|
primary_offer_destroy,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
destroy_primary_offer (struct wl_resource *resource)
|
||||||
|
{
|
||||||
|
MetaWaylandDataOffer *offer = wl_resource_get_user_data (resource);
|
||||||
|
|
||||||
|
if (offer->source)
|
||||||
|
{
|
||||||
|
if (offer == meta_wayland_data_source_get_current_offer (offer->source))
|
||||||
|
{
|
||||||
|
meta_wayland_data_source_cancel (offer->source);
|
||||||
|
meta_wayland_data_source_set_current_offer (offer->source, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_object_remove_weak_pointer (G_OBJECT (offer->source),
|
||||||
|
(gpointer *)&offer->source);
|
||||||
|
offer->source = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
meta_display_sync_wayland_input_focus (meta_get_display ());
|
||||||
|
g_slice_free (MetaWaylandDataOffer, offer);
|
||||||
|
}
|
||||||
|
|
||||||
|
MetaWaylandDataOffer *
|
||||||
|
meta_wayland_data_offer_primary_new (struct wl_resource *target)
|
||||||
|
{
|
||||||
|
MetaWaylandDataOffer *offer;
|
||||||
|
|
||||||
|
offer = g_slice_new0 (MetaWaylandDataOffer);
|
||||||
|
offer->selection_type = META_SELECTION_PRIMARY;
|
||||||
|
offer->resource = wl_resource_create (wl_resource_get_client (target),
|
||||||
|
&zwp_primary_selection_offer_v1_interface,
|
||||||
|
wl_resource_get_version (target), 0);
|
||||||
|
wl_resource_set_implementation (offer->resource,
|
||||||
|
&primary_offer_interface,
|
||||||
|
offer,
|
||||||
|
destroy_primary_offer);
|
||||||
|
return offer;
|
||||||
|
}
|
||||||
31
src/wayland/meta-wayland-data-offer-primary.h
Normal file
31
src/wayland/meta-wayland-data-offer-primary.h
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* Copyright © 2011 Kristian Høgsberg
|
||||||
|
* 2020 Red Hat Inc.
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||||
|
* documentation for any purpose is hereby granted without fee, provided that
|
||||||
|
* the above copyright notice appear in all copies and that both that copyright
|
||||||
|
* notice and this permission notice appear in supporting documentation, and
|
||||||
|
* that the name of the copyright holders not be used in advertising or
|
||||||
|
* publicity pertaining to distribution of the software without specific,
|
||||||
|
* written prior permission. The copyright holders make no representations
|
||||||
|
* about the suitability of this software for any purpose. It is provided "as
|
||||||
|
* is" without express or implied warranty.
|
||||||
|
*
|
||||||
|
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||||
|
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||||
|
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||||
|
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||||
|
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||||
|
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
|
||||||
|
* OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef META_WAYLAND_DATA_OFFER_PRIMARY_H
|
||||||
|
#define META_WAYLAND_DATA_OFFER_PRIMARY_H
|
||||||
|
|
||||||
|
#include "meta-wayland-data-offer.h"
|
||||||
|
|
||||||
|
MetaWaylandDataOffer * meta_wayland_data_offer_primary_new (struct wl_resource *target);
|
||||||
|
|
||||||
|
#endif /* META_WAYLAND_DATA_OFFER_PRIMARY_H */
|
||||||
327
src/wayland/meta-wayland-data-offer.c
Normal file
327
src/wayland/meta-wayland-data-offer.c
Normal file
@@ -0,0 +1,327 @@
|
|||||||
|
/*
|
||||||
|
* Copyright © 2011 Kristian Høgsberg
|
||||||
|
* 2020 Red Hat Inc.
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||||
|
* documentation for any purpose is hereby granted without fee, provided that
|
||||||
|
* the above copyright notice appear in all copies and that both that copyright
|
||||||
|
* notice and this permission notice appear in supporting documentation, and
|
||||||
|
* that the name of the copyright holders not be used in advertising or
|
||||||
|
* publicity pertaining to distribution of the software without specific,
|
||||||
|
* written prior permission. The copyright holders make no representations
|
||||||
|
* about the suitability of this software for any purpose. It is provided "as
|
||||||
|
* is" without express or implied warranty.
|
||||||
|
*
|
||||||
|
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||||
|
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||||
|
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||||
|
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||||
|
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||||
|
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
|
||||||
|
* OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include <gio/gunixoutputstream.h>
|
||||||
|
#include <glib-unix.h>
|
||||||
|
#include <glib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "meta/meta-selection.h"
|
||||||
|
#include "wayland/meta-wayland-data-device.h"
|
||||||
|
#include "wayland/meta-wayland-private.h"
|
||||||
|
|
||||||
|
#include "meta-wayland-data-offer.h"
|
||||||
|
|
||||||
|
#define ALL_ACTIONS (WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY | \
|
||||||
|
WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE | \
|
||||||
|
WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK)
|
||||||
|
|
||||||
|
static void
|
||||||
|
data_offer_accept (struct wl_client *client,
|
||||||
|
struct wl_resource *resource,
|
||||||
|
guint32 serial,
|
||||||
|
const char *mime_type)
|
||||||
|
{
|
||||||
|
MetaWaylandDataOffer *offer = wl_resource_get_user_data (resource);
|
||||||
|
|
||||||
|
/* FIXME: Check that client is currently focused by the input
|
||||||
|
* device that is currently dragging this data source. Should
|
||||||
|
* this be a wl_data_device request? */
|
||||||
|
|
||||||
|
if (offer->source)
|
||||||
|
{
|
||||||
|
meta_wayland_data_source_target (offer->source, mime_type);
|
||||||
|
meta_wayland_data_source_set_has_target (offer->source,
|
||||||
|
mime_type != NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
offer->accepted = mime_type != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
transfer_cb (MetaSelection *selection,
|
||||||
|
GAsyncResult *res,
|
||||||
|
GOutputStream *stream)
|
||||||
|
{
|
||||||
|
GError *error = NULL;
|
||||||
|
|
||||||
|
if (!meta_selection_transfer_finish (selection, res, &error))
|
||||||
|
{
|
||||||
|
g_warning ("Could not fetch selection data: %s", error->message);
|
||||||
|
g_error_free (error);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_output_stream_close (stream, NULL, NULL);
|
||||||
|
g_object_unref (stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
data_offer_receive (struct wl_client *client, struct wl_resource *resource,
|
||||||
|
const char *mime_type, int32_t fd)
|
||||||
|
{
|
||||||
|
MetaWaylandDataOffer *offer = wl_resource_get_user_data (resource);
|
||||||
|
MetaDisplay *display = meta_get_display ();
|
||||||
|
MetaSelectionType selection_type;
|
||||||
|
GList *mime_types;
|
||||||
|
gboolean found;
|
||||||
|
|
||||||
|
selection_type = offer->selection_type;
|
||||||
|
mime_types = meta_selection_get_mimetypes (meta_display_get_selection (display),
|
||||||
|
selection_type);
|
||||||
|
found = g_list_find_custom (mime_types, mime_type, (GCompareFunc) g_strcmp0) != NULL;
|
||||||
|
g_list_free_full (mime_types, g_free);
|
||||||
|
|
||||||
|
if (found)
|
||||||
|
{
|
||||||
|
GOutputStream *stream;
|
||||||
|
|
||||||
|
stream = g_unix_output_stream_new (fd, TRUE);
|
||||||
|
meta_selection_transfer_async (meta_display_get_selection (display),
|
||||||
|
selection_type,
|
||||||
|
mime_type,
|
||||||
|
-1,
|
||||||
|
stream,
|
||||||
|
NULL,
|
||||||
|
(GAsyncReadyCallback) transfer_cb,
|
||||||
|
stream);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
close (fd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
data_offer_destroy (struct wl_client *client,
|
||||||
|
struct wl_resource *resource)
|
||||||
|
{
|
||||||
|
wl_resource_destroy (resource);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
data_offer_finish (struct wl_client *client,
|
||||||
|
struct wl_resource *resource)
|
||||||
|
{
|
||||||
|
MetaWaylandDataOffer *offer = wl_resource_get_user_data (resource);
|
||||||
|
enum wl_data_device_manager_dnd_action current_action;
|
||||||
|
|
||||||
|
if (!offer->source ||
|
||||||
|
offer != meta_wayland_data_source_get_current_offer (offer->source))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!offer->accepted || !offer->action_sent)
|
||||||
|
{
|
||||||
|
wl_resource_post_error (offer->resource,
|
||||||
|
WL_DATA_OFFER_ERROR_INVALID_FINISH,
|
||||||
|
"premature finish request");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
current_action = meta_wayland_data_source_get_current_action (offer->source);
|
||||||
|
|
||||||
|
if (current_action == WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE ||
|
||||||
|
current_action == WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK)
|
||||||
|
{
|
||||||
|
wl_resource_post_error (offer->resource,
|
||||||
|
WL_DATA_OFFER_ERROR_INVALID_OFFER,
|
||||||
|
"offer finished with an invalid action");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
meta_wayland_data_source_notify_finish (offer->source);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
data_offer_set_actions (struct wl_client *client,
|
||||||
|
struct wl_resource *resource,
|
||||||
|
uint32_t dnd_actions,
|
||||||
|
uint32_t preferred_action)
|
||||||
|
{
|
||||||
|
MetaWaylandDataOffer *offer = wl_resource_get_user_data (resource);
|
||||||
|
|
||||||
|
if (dnd_actions & ~(ALL_ACTIONS))
|
||||||
|
{
|
||||||
|
wl_resource_post_error (offer->resource,
|
||||||
|
WL_DATA_OFFER_ERROR_INVALID_ACTION_MASK,
|
||||||
|
"invalid actions mask %x", dnd_actions);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (preferred_action &&
|
||||||
|
(!(preferred_action & dnd_actions) ||
|
||||||
|
__builtin_popcount (preferred_action) > 1))
|
||||||
|
{
|
||||||
|
wl_resource_post_error (offer->resource,
|
||||||
|
WL_DATA_OFFER_ERROR_INVALID_ACTION,
|
||||||
|
"invalid action %x", preferred_action);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
offer->dnd_actions = dnd_actions;
|
||||||
|
offer->preferred_dnd_action = preferred_action;
|
||||||
|
|
||||||
|
meta_wayland_data_offer_update_action (offer);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct wl_data_offer_interface data_offer_interface = {
|
||||||
|
data_offer_accept,
|
||||||
|
data_offer_receive,
|
||||||
|
data_offer_destroy,
|
||||||
|
data_offer_finish,
|
||||||
|
data_offer_set_actions,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
destroy_data_offer (struct wl_resource *resource)
|
||||||
|
{
|
||||||
|
MetaWaylandDataOffer *offer = wl_resource_get_user_data (resource);
|
||||||
|
MetaWaylandSeat *seat;
|
||||||
|
|
||||||
|
if (offer->source)
|
||||||
|
{
|
||||||
|
seat = meta_wayland_data_source_get_seat (offer->source);
|
||||||
|
|
||||||
|
if (offer == meta_wayland_data_source_get_current_offer (offer->source))
|
||||||
|
{
|
||||||
|
if (seat->data_device.dnd_data_source == offer->source)
|
||||||
|
{
|
||||||
|
if (wl_resource_get_version (offer->resource) <
|
||||||
|
WL_DATA_OFFER_ACTION_SINCE_VERSION)
|
||||||
|
meta_wayland_data_source_notify_finish (offer->source);
|
||||||
|
else if (meta_wayland_data_source_get_drop_performed (offer->source))
|
||||||
|
meta_wayland_data_source_cancel (offer->source);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
meta_wayland_data_source_set_current_offer (offer->source, NULL);
|
||||||
|
meta_wayland_data_source_set_has_target (offer->source, FALSE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
g_object_remove_weak_pointer (G_OBJECT (offer->source),
|
||||||
|
(gpointer *)&offer->source);
|
||||||
|
offer->source = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
meta_display_sync_wayland_input_focus (meta_get_display ());
|
||||||
|
g_slice_free (MetaWaylandDataOffer, offer);
|
||||||
|
}
|
||||||
|
|
||||||
|
MetaWaylandDataOffer *
|
||||||
|
meta_wayland_data_offer_new (MetaSelectionType selection_type,
|
||||||
|
MetaWaylandDataSource *source,
|
||||||
|
struct wl_resource *target)
|
||||||
|
{
|
||||||
|
MetaWaylandDataOffer *offer;
|
||||||
|
|
||||||
|
offer = g_slice_new0 (MetaWaylandDataOffer);
|
||||||
|
offer->selection_type = selection_type;
|
||||||
|
offer->resource = wl_resource_create (wl_resource_get_client (target),
|
||||||
|
&wl_data_offer_interface,
|
||||||
|
wl_resource_get_version (target), 0);
|
||||||
|
wl_resource_set_implementation (offer->resource,
|
||||||
|
&data_offer_interface,
|
||||||
|
offer,
|
||||||
|
destroy_data_offer);
|
||||||
|
if (source)
|
||||||
|
{
|
||||||
|
offer->source = source;
|
||||||
|
g_object_add_weak_pointer (G_OBJECT (source), (gpointer *)&offer->source);
|
||||||
|
}
|
||||||
|
|
||||||
|
return offer;
|
||||||
|
}
|
||||||
|
|
||||||
|
static enum wl_data_device_manager_dnd_action
|
||||||
|
data_offer_choose_action (MetaWaylandDataOffer *offer)
|
||||||
|
{
|
||||||
|
MetaWaylandDataSource *source = offer->source;
|
||||||
|
uint32_t actions, user_action, available_actions;
|
||||||
|
|
||||||
|
if (wl_resource_get_version (offer->resource) <
|
||||||
|
WL_DATA_OFFER_ACTION_SINCE_VERSION)
|
||||||
|
return WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY;
|
||||||
|
|
||||||
|
meta_wayland_data_source_get_actions (source, &actions);
|
||||||
|
user_action = meta_wayland_data_source_get_user_action (source);
|
||||||
|
|
||||||
|
available_actions = actions & offer->dnd_actions;
|
||||||
|
|
||||||
|
if (!available_actions)
|
||||||
|
return WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE;
|
||||||
|
|
||||||
|
/* If the user is forcing an action, go for it */
|
||||||
|
if ((user_action & available_actions) != 0)
|
||||||
|
return user_action;
|
||||||
|
|
||||||
|
/* If the dest side has a preferred DnD action, use it */
|
||||||
|
if ((offer->preferred_dnd_action & available_actions) != 0)
|
||||||
|
return offer->preferred_dnd_action;
|
||||||
|
|
||||||
|
/* Use the first found action, in bit order */
|
||||||
|
return 1 << (ffs (available_actions) - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_wayland_data_offer_update_action (MetaWaylandDataOffer *offer)
|
||||||
|
{
|
||||||
|
enum wl_data_device_manager_dnd_action current_action, action;
|
||||||
|
MetaWaylandDataSource *source;
|
||||||
|
|
||||||
|
if (!offer->source)
|
||||||
|
return;
|
||||||
|
|
||||||
|
source = offer->source;
|
||||||
|
current_action = meta_wayland_data_source_get_current_action (source);
|
||||||
|
action = data_offer_choose_action (offer);
|
||||||
|
|
||||||
|
if (current_action == action)
|
||||||
|
return;
|
||||||
|
|
||||||
|
meta_wayland_data_source_set_current_action (source, action);
|
||||||
|
|
||||||
|
if (!meta_wayland_data_source_get_in_ask (source) &&
|
||||||
|
wl_resource_get_version (offer->resource) >=
|
||||||
|
WL_DATA_OFFER_ACTION_SINCE_VERSION)
|
||||||
|
{
|
||||||
|
wl_data_offer_send_action (offer->resource, action);
|
||||||
|
offer->action_sent = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct wl_resource *
|
||||||
|
meta_wayland_data_offer_get_resource (MetaWaylandDataOffer *offer)
|
||||||
|
{
|
||||||
|
return offer->resource;
|
||||||
|
}
|
||||||
|
|
||||||
|
MetaWaylandDataSource *
|
||||||
|
meta_wayland_data_offer_get_source (MetaWaylandDataOffer *offer)
|
||||||
|
{
|
||||||
|
return offer->source;
|
||||||
|
}
|
||||||
51
src/wayland/meta-wayland-data-offer.h
Normal file
51
src/wayland/meta-wayland-data-offer.h
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
/*
|
||||||
|
* Copyright © 2011 Kristian Høgsberg
|
||||||
|
* 2020 Red Hat Inc.
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||||
|
* documentation for any purpose is hereby granted without fee, provided that
|
||||||
|
* the above copyright notice appear in all copies and that both that copyright
|
||||||
|
* notice and this permission notice appear in supporting documentation, and
|
||||||
|
* that the name of the copyright holders not be used in advertising or
|
||||||
|
* publicity pertaining to distribution of the software without specific,
|
||||||
|
* written prior permission. The copyright holders make no representations
|
||||||
|
* about the suitability of this software for any purpose. It is provided "as
|
||||||
|
* is" without express or implied warranty.
|
||||||
|
*
|
||||||
|
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||||
|
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||||
|
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||||
|
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||||
|
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||||
|
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
|
||||||
|
* OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef META_WAYLAND_DATA_OFFER_H
|
||||||
|
#define META_WAYLAND_DATA_OFFER_H
|
||||||
|
|
||||||
|
#include "meta/meta-selection.h"
|
||||||
|
#include "wayland/meta-wayland-data-source.h"
|
||||||
|
|
||||||
|
struct _MetaWaylandDataOffer
|
||||||
|
{
|
||||||
|
struct wl_resource *resource;
|
||||||
|
MetaWaylandDataSource *source;
|
||||||
|
struct wl_listener source_destroy_listener;
|
||||||
|
gboolean accepted;
|
||||||
|
gboolean action_sent;
|
||||||
|
uint32_t dnd_actions;
|
||||||
|
enum wl_data_device_manager_dnd_action preferred_dnd_action;
|
||||||
|
MetaSelectionType selection_type;
|
||||||
|
};
|
||||||
|
|
||||||
|
MetaWaylandDataOffer * meta_wayland_data_offer_new (MetaSelectionType selection_type,
|
||||||
|
MetaWaylandDataSource *source,
|
||||||
|
struct wl_resource *resource);
|
||||||
|
|
||||||
|
void meta_wayland_data_offer_update_action (MetaWaylandDataOffer *offer);
|
||||||
|
|
||||||
|
struct wl_resource * meta_wayland_data_offer_get_resource (MetaWaylandDataOffer *offer);
|
||||||
|
MetaWaylandDataSource * meta_wayland_data_offer_get_source (MetaWaylandDataOffer *offer);
|
||||||
|
|
||||||
|
#endif /* META_WAYLAND_DATA_OFFER_H */
|
||||||
117
src/wayland/meta-wayland-data-source-primary-legacy.c
Normal file
117
src/wayland/meta-wayland-data-source-primary-legacy.c
Normal file
@@ -0,0 +1,117 @@
|
|||||||
|
/*
|
||||||
|
* Copyright © 2011 Kristian Høgsberg
|
||||||
|
* 2020 Red Hat Inc.
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||||
|
* documentation for any purpose is hereby granted without fee, provided that
|
||||||
|
* the above copyright notice appear in all copies and that both that copyright
|
||||||
|
* notice and this permission notice appear in supporting documentation, and
|
||||||
|
* that the name of the copyright holders not be used in advertising or
|
||||||
|
* publicity pertaining to distribution of the software without specific,
|
||||||
|
* written prior permission. The copyright holders make no representations
|
||||||
|
* about the suitability of this software for any purpose. It is provided "as
|
||||||
|
* is" without express or implied warranty.
|
||||||
|
*
|
||||||
|
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||||
|
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||||
|
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||||
|
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||||
|
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||||
|
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
|
||||||
|
* OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "gtk-primary-selection-server-protocol.h"
|
||||||
|
#include "wayland/meta-wayland-data-source-primary-legacy.h"
|
||||||
|
|
||||||
|
typedef struct _MetaWaylandDataSourcePrimaryLegacy
|
||||||
|
{
|
||||||
|
MetaWaylandDataSource parent;
|
||||||
|
} MetaWaylandDataSourcePrimaryLegacy;
|
||||||
|
|
||||||
|
G_DEFINE_TYPE (MetaWaylandDataSourcePrimaryLegacy, meta_wayland_data_source_primary_legacy,
|
||||||
|
META_TYPE_WAYLAND_DATA_SOURCE);
|
||||||
|
|
||||||
|
static void
|
||||||
|
primary_source_offer (struct wl_client *client,
|
||||||
|
struct wl_resource *resource,
|
||||||
|
const char *type)
|
||||||
|
{
|
||||||
|
MetaWaylandDataSource *source = wl_resource_get_user_data (resource);
|
||||||
|
|
||||||
|
if (!meta_wayland_data_source_add_mime_type (source, type))
|
||||||
|
wl_resource_post_no_memory (resource);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
primary_source_destroy (struct wl_client *client,
|
||||||
|
struct wl_resource *resource)
|
||||||
|
{
|
||||||
|
wl_resource_destroy (resource);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct gtk_primary_selection_source_interface primary_source_interface = {
|
||||||
|
primary_source_offer,
|
||||||
|
primary_source_destroy,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
destroy_primary_source (struct wl_resource *resource)
|
||||||
|
{
|
||||||
|
MetaWaylandDataSource *source = wl_resource_get_user_data (resource);
|
||||||
|
|
||||||
|
meta_wayland_data_source_set_resource (source, NULL);
|
||||||
|
g_object_unref (source);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_wayland_data_source_primary_legacy_send (MetaWaylandDataSource *source,
|
||||||
|
const gchar *mime_type,
|
||||||
|
gint fd)
|
||||||
|
{
|
||||||
|
struct wl_resource *resource = meta_wayland_data_source_get_resource (source);
|
||||||
|
|
||||||
|
gtk_primary_selection_source_send_send (resource, mime_type, fd);
|
||||||
|
close (fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_wayland_data_source_primary_legacy_cancel (MetaWaylandDataSource *source)
|
||||||
|
{
|
||||||
|
struct wl_resource *resource = meta_wayland_data_source_get_resource (source);
|
||||||
|
|
||||||
|
if (resource)
|
||||||
|
gtk_primary_selection_source_send_cancelled (resource);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_wayland_data_source_primary_legacy_init (MetaWaylandDataSourcePrimaryLegacy *source_primary)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_wayland_data_source_primary_legacy_class_init (MetaWaylandDataSourcePrimaryLegacyClass *klass)
|
||||||
|
{
|
||||||
|
MetaWaylandDataSourceClass *data_source_class =
|
||||||
|
META_WAYLAND_DATA_SOURCE_CLASS (klass);
|
||||||
|
|
||||||
|
data_source_class->send = meta_wayland_data_source_primary_legacy_send;
|
||||||
|
data_source_class->cancel = meta_wayland_data_source_primary_legacy_cancel;
|
||||||
|
}
|
||||||
|
|
||||||
|
MetaWaylandDataSource *
|
||||||
|
meta_wayland_data_source_primary_legacy_new (struct wl_resource *resource)
|
||||||
|
{
|
||||||
|
MetaWaylandDataSource *source_primary =
|
||||||
|
g_object_new (META_TYPE_WAYLAND_DATA_SOURCE_PRIMARY_LEGACY, NULL);
|
||||||
|
|
||||||
|
meta_wayland_data_source_set_resource (source_primary, resource);
|
||||||
|
wl_resource_set_implementation (resource, &primary_source_interface,
|
||||||
|
source_primary, destroy_primary_source);
|
||||||
|
|
||||||
|
return source_primary;
|
||||||
|
}
|
||||||
37
src/wayland/meta-wayland-data-source-primary-legacy.h
Normal file
37
src/wayland/meta-wayland-data-source-primary-legacy.h
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
* Copyright © 2011 Kristian Høgsberg
|
||||||
|
* 2020 Red Hat Inc.
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||||
|
* documentation for any purpose is hereby granted without fee, provided that
|
||||||
|
* the above copyright notice appear in all copies and that both that copyright
|
||||||
|
* notice and this permission notice appear in supporting documentation, and
|
||||||
|
* that the name of the copyright holders not be used in advertising or
|
||||||
|
* publicity pertaining to distribution of the software without specific,
|
||||||
|
* written prior permission. The copyright holders make no representations
|
||||||
|
* about the suitability of this software for any purpose. It is provided "as
|
||||||
|
* is" without express or implied warranty.
|
||||||
|
*
|
||||||
|
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||||
|
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||||
|
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||||
|
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||||
|
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||||
|
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
|
||||||
|
* OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef META_WAYLAND_DATA_SOURCE_PRIMARY_LEGACY_H
|
||||||
|
#define META_WAYLAND_DATA_SOURCE_PRIMARY_LEGACY_H
|
||||||
|
|
||||||
|
#include "meta-wayland-data-source.h"
|
||||||
|
|
||||||
|
#define META_TYPE_WAYLAND_DATA_SOURCE_PRIMARY_LEGACY (meta_wayland_data_source_primary_legacy_get_type ())
|
||||||
|
G_DECLARE_FINAL_TYPE (MetaWaylandDataSourcePrimaryLegacy,
|
||||||
|
meta_wayland_data_source_primary_legacy,
|
||||||
|
META, WAYLAND_DATA_SOURCE_PRIMARY_LEGACY,
|
||||||
|
MetaWaylandDataSource);
|
||||||
|
|
||||||
|
MetaWaylandDataSource * meta_wayland_data_source_primary_legacy_new (struct wl_resource *resource);
|
||||||
|
|
||||||
|
#endif /* META_WAYLAND_DATA_SOURCE_PRIMARY_LEGACY_H */
|
||||||
117
src/wayland/meta-wayland-data-source-primary.c
Normal file
117
src/wayland/meta-wayland-data-source-primary.c
Normal file
@@ -0,0 +1,117 @@
|
|||||||
|
/*
|
||||||
|
* Copyright © 2011 Kristian Høgsberg
|
||||||
|
* 2020 Red Hat Inc.
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||||
|
* documentation for any purpose is hereby granted without fee, provided that
|
||||||
|
* the above copyright notice appear in all copies and that both that copyright
|
||||||
|
* notice and this permission notice appear in supporting documentation, and
|
||||||
|
* that the name of the copyright holders not be used in advertising or
|
||||||
|
* publicity pertaining to distribution of the software without specific,
|
||||||
|
* written prior permission. The copyright holders make no representations
|
||||||
|
* about the suitability of this software for any purpose. It is provided "as
|
||||||
|
* is" without express or implied warranty.
|
||||||
|
*
|
||||||
|
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||||
|
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||||
|
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||||
|
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||||
|
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||||
|
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
|
||||||
|
* OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "primary-selection-unstable-v1-server-protocol.h"
|
||||||
|
#include "wayland/meta-wayland-data-source-primary.h"
|
||||||
|
|
||||||
|
typedef struct _MetaWaylandDataSourcePrimary
|
||||||
|
{
|
||||||
|
MetaWaylandDataSource parent;
|
||||||
|
} MetaWaylandDataSourcePrimary;
|
||||||
|
|
||||||
|
G_DEFINE_TYPE (MetaWaylandDataSourcePrimary, meta_wayland_data_source_primary,
|
||||||
|
META_TYPE_WAYLAND_DATA_SOURCE);
|
||||||
|
|
||||||
|
static void
|
||||||
|
primary_source_offer (struct wl_client *client,
|
||||||
|
struct wl_resource *resource,
|
||||||
|
const char *type)
|
||||||
|
{
|
||||||
|
MetaWaylandDataSource *source = wl_resource_get_user_data (resource);
|
||||||
|
|
||||||
|
if (!meta_wayland_data_source_add_mime_type (source, type))
|
||||||
|
wl_resource_post_no_memory (resource);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
primary_source_destroy (struct wl_client *client,
|
||||||
|
struct wl_resource *resource)
|
||||||
|
{
|
||||||
|
wl_resource_destroy (resource);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct zwp_primary_selection_source_v1_interface primary_source_interface = {
|
||||||
|
primary_source_offer,
|
||||||
|
primary_source_destroy,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
destroy_primary_source (struct wl_resource *resource)
|
||||||
|
{
|
||||||
|
MetaWaylandDataSource *source = wl_resource_get_user_data (resource);
|
||||||
|
|
||||||
|
meta_wayland_data_source_set_resource (source, NULL);
|
||||||
|
g_object_unref (source);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_wayland_data_source_primary_send (MetaWaylandDataSource *source,
|
||||||
|
const gchar *mime_type,
|
||||||
|
gint fd)
|
||||||
|
{
|
||||||
|
struct wl_resource *resource = meta_wayland_data_source_get_resource (source);
|
||||||
|
|
||||||
|
zwp_primary_selection_source_v1_send_send (resource, mime_type, fd);
|
||||||
|
close (fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_wayland_data_source_primary_cancel (MetaWaylandDataSource *source)
|
||||||
|
{
|
||||||
|
struct wl_resource *resource = meta_wayland_data_source_get_resource (source);
|
||||||
|
|
||||||
|
if (resource)
|
||||||
|
zwp_primary_selection_source_v1_send_cancelled (resource);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_wayland_data_source_primary_init (MetaWaylandDataSourcePrimary *source_primary)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_wayland_data_source_primary_class_init (MetaWaylandDataSourcePrimaryClass *klass)
|
||||||
|
{
|
||||||
|
MetaWaylandDataSourceClass *data_source_class =
|
||||||
|
META_WAYLAND_DATA_SOURCE_CLASS (klass);
|
||||||
|
|
||||||
|
data_source_class->send = meta_wayland_data_source_primary_send;
|
||||||
|
data_source_class->cancel = meta_wayland_data_source_primary_cancel;
|
||||||
|
}
|
||||||
|
|
||||||
|
MetaWaylandDataSource *
|
||||||
|
meta_wayland_data_source_primary_new (struct wl_resource *resource)
|
||||||
|
{
|
||||||
|
MetaWaylandDataSource *source_primary =
|
||||||
|
g_object_new (META_TYPE_WAYLAND_DATA_SOURCE_PRIMARY, NULL);
|
||||||
|
|
||||||
|
meta_wayland_data_source_set_resource (source_primary, resource);
|
||||||
|
wl_resource_set_implementation (resource, &primary_source_interface,
|
||||||
|
source_primary, destroy_primary_source);
|
||||||
|
|
||||||
|
return source_primary;
|
||||||
|
}
|
||||||
37
src/wayland/meta-wayland-data-source-primary.h
Normal file
37
src/wayland/meta-wayland-data-source-primary.h
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
* Copyright © 2011 Kristian Høgsberg
|
||||||
|
* 2020 Red Hat Inc.
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||||
|
* documentation for any purpose is hereby granted without fee, provided that
|
||||||
|
* the above copyright notice appear in all copies and that both that copyright
|
||||||
|
* notice and this permission notice appear in supporting documentation, and
|
||||||
|
* that the name of the copyright holders not be used in advertising or
|
||||||
|
* publicity pertaining to distribution of the software without specific,
|
||||||
|
* written prior permission. The copyright holders make no representations
|
||||||
|
* about the suitability of this software for any purpose. It is provided "as
|
||||||
|
* is" without express or implied warranty.
|
||||||
|
*
|
||||||
|
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||||
|
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||||
|
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||||
|
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||||
|
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||||
|
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
|
||||||
|
* OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef META_WAYLAND_DATA_SOURCE_PRIMARY_H
|
||||||
|
#define META_WAYLAND_DATA_SOURCE_PRIMARY_H
|
||||||
|
|
||||||
|
#include "meta-wayland-data-source.h"
|
||||||
|
|
||||||
|
#define META_TYPE_WAYLAND_DATA_SOURCE_PRIMARY (meta_wayland_data_source_primary_get_type ())
|
||||||
|
G_DECLARE_FINAL_TYPE (MetaWaylandDataSourcePrimary,
|
||||||
|
meta_wayland_data_source_primary,
|
||||||
|
META, WAYLAND_DATA_SOURCE_PRIMARY,
|
||||||
|
MetaWaylandDataSource);
|
||||||
|
|
||||||
|
MetaWaylandDataSource * meta_wayland_data_source_primary_new (struct wl_resource *resource);
|
||||||
|
|
||||||
|
#endif /* META_WAYLAND_DATA_SOURCE_PRIMARY_H */
|
||||||
523
src/wayland/meta-wayland-data-source.c
Normal file
523
src/wayland/meta-wayland-data-source.c
Normal file
@@ -0,0 +1,523 @@
|
|||||||
|
/*
|
||||||
|
* Copyright © 2011 Kristian Høgsberg
|
||||||
|
* 2020 Red Hat Inc.
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||||
|
* documentation for any purpose is hereby granted without fee, provided that
|
||||||
|
* the above copyright notice appear in all copies and that both that copyright
|
||||||
|
* notice and this permission notice appear in supporting documentation, and
|
||||||
|
* that the name of the copyright holders not be used in advertising or
|
||||||
|
* publicity pertaining to distribution of the software without specific,
|
||||||
|
* written prior permission. The copyright holders make no representations
|
||||||
|
* about the suitability of this software for any purpose. It is provided "as
|
||||||
|
* is" without express or implied warranty.
|
||||||
|
*
|
||||||
|
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||||
|
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||||
|
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||||
|
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||||
|
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||||
|
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
|
||||||
|
* OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "wayland/meta-wayland-data-source.h"
|
||||||
|
#include "wayland/meta-wayland-private.h"
|
||||||
|
|
||||||
|
#define ALL_ACTIONS (WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY | \
|
||||||
|
WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE | \
|
||||||
|
WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK)
|
||||||
|
|
||||||
|
typedef struct _MetaWaylandDataSourcePrivate
|
||||||
|
{
|
||||||
|
struct wl_resource *resource;
|
||||||
|
MetaWaylandDataOffer *offer;
|
||||||
|
struct wl_array mime_types;
|
||||||
|
gboolean has_target;
|
||||||
|
uint32_t dnd_actions;
|
||||||
|
enum wl_data_device_manager_dnd_action user_dnd_action;
|
||||||
|
enum wl_data_device_manager_dnd_action current_dnd_action;
|
||||||
|
MetaWaylandSeat *seat;
|
||||||
|
guint actions_set : 1;
|
||||||
|
guint in_ask : 1;
|
||||||
|
guint drop_performed : 1;
|
||||||
|
} MetaWaylandDataSourcePrivate;
|
||||||
|
|
||||||
|
G_DEFINE_TYPE_WITH_PRIVATE (MetaWaylandDataSource, meta_wayland_data_source,
|
||||||
|
G_TYPE_OBJECT);
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_wayland_data_source_real_send (MetaWaylandDataSource *source,
|
||||||
|
const gchar *mime_type,
|
||||||
|
gint fd)
|
||||||
|
{
|
||||||
|
MetaWaylandDataSourcePrivate *priv =
|
||||||
|
meta_wayland_data_source_get_instance_private (source);
|
||||||
|
|
||||||
|
wl_data_source_send_send (priv->resource, mime_type, fd);
|
||||||
|
close (fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_wayland_data_source_real_target (MetaWaylandDataSource *source,
|
||||||
|
const gchar *mime_type)
|
||||||
|
{
|
||||||
|
MetaWaylandDataSourcePrivate *priv =
|
||||||
|
meta_wayland_data_source_get_instance_private (source);
|
||||||
|
|
||||||
|
wl_data_source_send_target (priv->resource, mime_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_wayland_data_source_real_cancel (MetaWaylandDataSource *source)
|
||||||
|
{
|
||||||
|
MetaWaylandDataSourcePrivate *priv =
|
||||||
|
meta_wayland_data_source_get_instance_private (source);
|
||||||
|
|
||||||
|
if (!priv->resource)
|
||||||
|
return;
|
||||||
|
|
||||||
|
wl_data_source_send_cancelled (priv->resource);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_wayland_data_source_real_action (MetaWaylandDataSource *source,
|
||||||
|
enum wl_data_device_manager_dnd_action action)
|
||||||
|
{
|
||||||
|
MetaWaylandDataSourcePrivate *priv =
|
||||||
|
meta_wayland_data_source_get_instance_private (source);
|
||||||
|
|
||||||
|
if (wl_resource_get_version (priv->resource) >=
|
||||||
|
WL_DATA_SOURCE_ACTION_SINCE_VERSION)
|
||||||
|
wl_data_source_send_action (priv->resource, action);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_wayland_data_source_real_drop_performed (MetaWaylandDataSource *source)
|
||||||
|
{
|
||||||
|
MetaWaylandDataSourcePrivate *priv =
|
||||||
|
meta_wayland_data_source_get_instance_private (source);
|
||||||
|
|
||||||
|
if (wl_resource_get_version (priv->resource) >=
|
||||||
|
WL_DATA_SOURCE_DND_DROP_PERFORMED_SINCE_VERSION)
|
||||||
|
{
|
||||||
|
priv->drop_performed = TRUE;
|
||||||
|
wl_data_source_send_dnd_drop_performed (priv->resource);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_wayland_data_source_real_drag_finished (MetaWaylandDataSource *source)
|
||||||
|
{
|
||||||
|
MetaWaylandDataSourcePrivate *priv =
|
||||||
|
meta_wayland_data_source_get_instance_private (source);
|
||||||
|
enum wl_data_device_manager_dnd_action action;
|
||||||
|
|
||||||
|
if (meta_wayland_data_source_get_in_ask (source))
|
||||||
|
{
|
||||||
|
action = meta_wayland_data_source_get_current_action (source);
|
||||||
|
meta_wayland_data_source_real_action (source, action);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wl_resource_get_version (priv->resource) >=
|
||||||
|
WL_DATA_SOURCE_DND_FINISHED_SINCE_VERSION)
|
||||||
|
wl_data_source_send_dnd_finished (priv->resource);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_wayland_data_source_finalize (GObject *object)
|
||||||
|
{
|
||||||
|
MetaWaylandDataSource *source = META_WAYLAND_DATA_SOURCE (object);
|
||||||
|
MetaWaylandDataSourcePrivate *priv =
|
||||||
|
meta_wayland_data_source_get_instance_private (source);
|
||||||
|
char **pos;
|
||||||
|
|
||||||
|
wl_array_for_each (pos, &priv->mime_types)
|
||||||
|
g_free (*pos);
|
||||||
|
wl_array_release (&priv->mime_types);
|
||||||
|
|
||||||
|
G_OBJECT_CLASS (meta_wayland_data_source_parent_class)->finalize (object);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_wayland_data_source_init (MetaWaylandDataSource *source)
|
||||||
|
{
|
||||||
|
MetaWaylandDataSourcePrivate *priv =
|
||||||
|
meta_wayland_data_source_get_instance_private (source);
|
||||||
|
|
||||||
|
wl_array_init (&priv->mime_types);
|
||||||
|
priv->current_dnd_action = -1;
|
||||||
|
priv->drop_performed = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_wayland_data_source_class_init (MetaWaylandDataSourceClass *klass)
|
||||||
|
{
|
||||||
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||||
|
|
||||||
|
object_class->finalize = meta_wayland_data_source_finalize;
|
||||||
|
|
||||||
|
klass->send = meta_wayland_data_source_real_send;
|
||||||
|
klass->target = meta_wayland_data_source_real_target;
|
||||||
|
klass->cancel = meta_wayland_data_source_real_cancel;
|
||||||
|
klass->action = meta_wayland_data_source_real_action;
|
||||||
|
klass->drop_performed = meta_wayland_data_source_real_drop_performed;
|
||||||
|
klass->drag_finished = meta_wayland_data_source_real_drag_finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
data_source_offer (struct wl_client *client,
|
||||||
|
struct wl_resource *resource, const char *type)
|
||||||
|
{
|
||||||
|
MetaWaylandDataSource *source = wl_resource_get_user_data (resource);
|
||||||
|
|
||||||
|
if (!meta_wayland_data_source_add_mime_type (source, type))
|
||||||
|
wl_resource_post_no_memory (resource);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
data_source_destroy (struct wl_client *client,
|
||||||
|
struct wl_resource *resource)
|
||||||
|
{
|
||||||
|
wl_resource_destroy (resource);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
data_source_set_actions (struct wl_client *client,
|
||||||
|
struct wl_resource *resource,
|
||||||
|
uint32_t dnd_actions)
|
||||||
|
{
|
||||||
|
MetaWaylandDataSource *source = wl_resource_get_user_data (resource);
|
||||||
|
MetaWaylandDataSourcePrivate *priv =
|
||||||
|
meta_wayland_data_source_get_instance_private (source);
|
||||||
|
|
||||||
|
if (priv->actions_set)
|
||||||
|
{
|
||||||
|
wl_resource_post_error (priv->resource,
|
||||||
|
WL_DATA_SOURCE_ERROR_INVALID_ACTION_MASK,
|
||||||
|
"cannot set actions more than once");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dnd_actions & ~(ALL_ACTIONS))
|
||||||
|
{
|
||||||
|
wl_resource_post_error (priv->resource,
|
||||||
|
WL_DATA_SOURCE_ERROR_INVALID_ACTION_MASK,
|
||||||
|
"invalid actions mask %x", dnd_actions);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (meta_wayland_data_source_get_seat (source))
|
||||||
|
{
|
||||||
|
wl_resource_post_error (priv->resource,
|
||||||
|
WL_DATA_SOURCE_ERROR_INVALID_ACTION_MASK,
|
||||||
|
"invalid action change after "
|
||||||
|
"wl_data_device.start_drag");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
meta_wayland_data_source_set_actions (source, dnd_actions);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct wl_data_source_interface data_source_interface = {
|
||||||
|
data_source_offer,
|
||||||
|
data_source_destroy,
|
||||||
|
data_source_set_actions
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
destroy_data_source (struct wl_resource *resource)
|
||||||
|
{
|
||||||
|
MetaWaylandDataSource *source = wl_resource_get_user_data (resource);
|
||||||
|
|
||||||
|
meta_wayland_data_source_set_resource (source, NULL);
|
||||||
|
g_object_unref (source);
|
||||||
|
}
|
||||||
|
|
||||||
|
MetaWaylandDataSource *
|
||||||
|
meta_wayland_data_source_new (struct wl_resource *resource)
|
||||||
|
{
|
||||||
|
MetaWaylandDataSource *source =
|
||||||
|
g_object_new (META_TYPE_WAYLAND_DATA_SOURCE, NULL);
|
||||||
|
MetaWaylandDataSourcePrivate *priv =
|
||||||
|
meta_wayland_data_source_get_instance_private (source);
|
||||||
|
|
||||||
|
meta_wayland_data_source_set_resource (source, resource);
|
||||||
|
wl_resource_set_implementation (resource, &data_source_interface,
|
||||||
|
source, destroy_data_source);
|
||||||
|
|
||||||
|
if (wl_resource_get_version (resource) < WL_DATA_SOURCE_ACTION_SINCE_VERSION)
|
||||||
|
{
|
||||||
|
priv->dnd_actions = priv->user_dnd_action =
|
||||||
|
WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY;
|
||||||
|
}
|
||||||
|
|
||||||
|
return source;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct wl_resource *
|
||||||
|
meta_wayland_data_source_get_resource (MetaWaylandDataSource *source)
|
||||||
|
{
|
||||||
|
MetaWaylandDataSourcePrivate *priv =
|
||||||
|
meta_wayland_data_source_get_instance_private (source);
|
||||||
|
|
||||||
|
return priv->resource;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_wayland_data_source_set_resource (MetaWaylandDataSource *source,
|
||||||
|
struct wl_resource *resource)
|
||||||
|
{
|
||||||
|
MetaWaylandDataSourcePrivate *priv =
|
||||||
|
meta_wayland_data_source_get_instance_private (source);
|
||||||
|
|
||||||
|
priv->resource = resource;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
meta_wayland_data_source_get_in_ask (MetaWaylandDataSource *source)
|
||||||
|
{
|
||||||
|
MetaWaylandDataSourcePrivate *priv =
|
||||||
|
meta_wayland_data_source_get_instance_private (source);
|
||||||
|
|
||||||
|
return priv->in_ask;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_wayland_data_source_update_in_ask (MetaWaylandDataSource *source)
|
||||||
|
{
|
||||||
|
MetaWaylandDataSourcePrivate *priv =
|
||||||
|
meta_wayland_data_source_get_instance_private (source);
|
||||||
|
|
||||||
|
priv->in_ask =
|
||||||
|
priv->current_dnd_action == WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_wayland_data_source_target (MetaWaylandDataSource *source,
|
||||||
|
const char *mime_type)
|
||||||
|
{
|
||||||
|
if (META_WAYLAND_DATA_SOURCE_GET_CLASS (source)->target)
|
||||||
|
META_WAYLAND_DATA_SOURCE_GET_CLASS (source)->target (source, mime_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_wayland_data_source_send (MetaWaylandDataSource *source,
|
||||||
|
const char *mime_type,
|
||||||
|
int fd)
|
||||||
|
{
|
||||||
|
META_WAYLAND_DATA_SOURCE_GET_CLASS (source)->send (source, mime_type, fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
meta_wayland_data_source_has_target (MetaWaylandDataSource *source)
|
||||||
|
{
|
||||||
|
MetaWaylandDataSourcePrivate *priv =
|
||||||
|
meta_wayland_data_source_get_instance_private (source);
|
||||||
|
|
||||||
|
return priv->has_target;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_wayland_data_source_set_seat (MetaWaylandDataSource *source,
|
||||||
|
MetaWaylandSeat *seat)
|
||||||
|
{
|
||||||
|
MetaWaylandDataSourcePrivate *priv =
|
||||||
|
meta_wayland_data_source_get_instance_private (source);
|
||||||
|
|
||||||
|
priv->seat = seat;
|
||||||
|
}
|
||||||
|
|
||||||
|
MetaWaylandSeat *
|
||||||
|
meta_wayland_data_source_get_seat (MetaWaylandDataSource *source)
|
||||||
|
{
|
||||||
|
MetaWaylandDataSourcePrivate *priv =
|
||||||
|
meta_wayland_data_source_get_instance_private (source);
|
||||||
|
|
||||||
|
return priv->seat;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_wayland_data_source_set_has_target (MetaWaylandDataSource *source,
|
||||||
|
gboolean has_target)
|
||||||
|
{
|
||||||
|
MetaWaylandDataSourcePrivate *priv =
|
||||||
|
meta_wayland_data_source_get_instance_private (source);
|
||||||
|
|
||||||
|
priv->has_target = has_target;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct wl_array *
|
||||||
|
meta_wayland_data_source_get_mime_types (MetaWaylandDataSource *source)
|
||||||
|
{
|
||||||
|
MetaWaylandDataSourcePrivate *priv =
|
||||||
|
meta_wayland_data_source_get_instance_private ((MetaWaylandDataSource *)source);
|
||||||
|
|
||||||
|
return &priv->mime_types;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_wayland_data_source_cancel (MetaWaylandDataSource *source)
|
||||||
|
{
|
||||||
|
META_WAYLAND_DATA_SOURCE_GET_CLASS (source)->cancel (source);
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
meta_wayland_data_source_get_actions (MetaWaylandDataSource *source,
|
||||||
|
uint32_t *dnd_actions)
|
||||||
|
{
|
||||||
|
MetaWaylandDataSourcePrivate *priv =
|
||||||
|
meta_wayland_data_source_get_instance_private (source);
|
||||||
|
|
||||||
|
if (dnd_actions)
|
||||||
|
*dnd_actions = priv->dnd_actions;
|
||||||
|
|
||||||
|
return priv->actions_set;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum wl_data_device_manager_dnd_action
|
||||||
|
meta_wayland_data_source_get_user_action (MetaWaylandDataSource *source)
|
||||||
|
{
|
||||||
|
MetaWaylandDataSourcePrivate *priv =
|
||||||
|
meta_wayland_data_source_get_instance_private (source);
|
||||||
|
|
||||||
|
if (!priv->seat)
|
||||||
|
return WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE;
|
||||||
|
|
||||||
|
return priv->user_dnd_action;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum wl_data_device_manager_dnd_action
|
||||||
|
meta_wayland_data_source_get_current_action (MetaWaylandDataSource *source)
|
||||||
|
{
|
||||||
|
MetaWaylandDataSourcePrivate *priv =
|
||||||
|
meta_wayland_data_source_get_instance_private (source);
|
||||||
|
|
||||||
|
return priv->current_dnd_action;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_wayland_data_source_set_current_offer (MetaWaylandDataSource *source,
|
||||||
|
MetaWaylandDataOffer *offer)
|
||||||
|
{
|
||||||
|
MetaWaylandDataSourcePrivate *priv =
|
||||||
|
meta_wayland_data_source_get_instance_private (source);
|
||||||
|
|
||||||
|
priv->offer = offer;
|
||||||
|
}
|
||||||
|
|
||||||
|
MetaWaylandDataOffer *
|
||||||
|
meta_wayland_data_source_get_current_offer (MetaWaylandDataSource *source)
|
||||||
|
{
|
||||||
|
MetaWaylandDataSourcePrivate *priv =
|
||||||
|
meta_wayland_data_source_get_instance_private (source);
|
||||||
|
|
||||||
|
return priv->offer;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_wayland_data_source_set_current_action (MetaWaylandDataSource *source,
|
||||||
|
enum wl_data_device_manager_dnd_action action)
|
||||||
|
{
|
||||||
|
MetaWaylandDataSourcePrivate *priv =
|
||||||
|
meta_wayland_data_source_get_instance_private (source);
|
||||||
|
|
||||||
|
if (priv->current_dnd_action == action)
|
||||||
|
return;
|
||||||
|
|
||||||
|
priv->current_dnd_action = action;
|
||||||
|
|
||||||
|
if (!meta_wayland_data_source_get_in_ask (source))
|
||||||
|
META_WAYLAND_DATA_SOURCE_GET_CLASS (source)->action (source, action);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_wayland_data_source_set_actions (MetaWaylandDataSource *source,
|
||||||
|
uint32_t dnd_actions)
|
||||||
|
{
|
||||||
|
MetaWaylandDataSourcePrivate *priv =
|
||||||
|
meta_wayland_data_source_get_instance_private (source);
|
||||||
|
|
||||||
|
priv->dnd_actions = dnd_actions;
|
||||||
|
priv->actions_set = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_wayland_data_source_set_user_action (MetaWaylandDataSource *source,
|
||||||
|
uint32_t action)
|
||||||
|
{
|
||||||
|
MetaWaylandDataSourcePrivate *priv =
|
||||||
|
meta_wayland_data_source_get_instance_private (source);
|
||||||
|
MetaWaylandDataOffer *offer;
|
||||||
|
|
||||||
|
if (priv->user_dnd_action == action)
|
||||||
|
return;
|
||||||
|
|
||||||
|
priv->user_dnd_action = action;
|
||||||
|
offer = meta_wayland_data_source_get_current_offer (source);
|
||||||
|
|
||||||
|
if (offer)
|
||||||
|
meta_wayland_data_offer_update_action (offer);
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
meta_wayland_data_source_get_drop_performed (MetaWaylandDataSource *source)
|
||||||
|
{
|
||||||
|
MetaWaylandDataSourcePrivate *priv =
|
||||||
|
meta_wayland_data_source_get_instance_private (source);
|
||||||
|
|
||||||
|
return priv->drop_performed;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_wayland_data_source_notify_drop_performed (MetaWaylandDataSource *source)
|
||||||
|
{
|
||||||
|
META_WAYLAND_DATA_SOURCE_GET_CLASS (source)->drop_performed (source);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_wayland_data_source_notify_finish (MetaWaylandDataSource *source)
|
||||||
|
{
|
||||||
|
META_WAYLAND_DATA_SOURCE_GET_CLASS (source)->drag_finished (source);
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
meta_wayland_data_source_add_mime_type (MetaWaylandDataSource *source,
|
||||||
|
const char *mime_type)
|
||||||
|
{
|
||||||
|
MetaWaylandDataSourcePrivate *priv =
|
||||||
|
meta_wayland_data_source_get_instance_private (source);
|
||||||
|
char **pos;
|
||||||
|
|
||||||
|
pos = wl_array_add (&priv->mime_types, sizeof (*pos));
|
||||||
|
|
||||||
|
if (pos)
|
||||||
|
{
|
||||||
|
*pos = g_strdup (mime_type);
|
||||||
|
return *pos != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
meta_wayland_data_source_has_mime_type (MetaWaylandDataSource *source,
|
||||||
|
const char *mime_type)
|
||||||
|
{
|
||||||
|
MetaWaylandDataSourcePrivate *priv =
|
||||||
|
meta_wayland_data_source_get_instance_private (source);
|
||||||
|
char **p;
|
||||||
|
|
||||||
|
wl_array_for_each (p, &priv->mime_types)
|
||||||
|
{
|
||||||
|
if (g_strcmp0 (mime_type, *p) == 0)
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
112
src/wayland/meta-wayland-data-source.h
Normal file
112
src/wayland/meta-wayland-data-source.h
Normal file
@@ -0,0 +1,112 @@
|
|||||||
|
/*
|
||||||
|
* Copyright © 2011 Kristian Høgsberg
|
||||||
|
* 2020 Red Hat Inc.
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||||
|
* documentation for any purpose is hereby granted without fee, provided that
|
||||||
|
* the above copyright notice appear in all copies and that both that copyright
|
||||||
|
* notice and this permission notice appear in supporting documentation, and
|
||||||
|
* that the name of the copyright holders not be used in advertising or
|
||||||
|
* publicity pertaining to distribution of the software without specific,
|
||||||
|
* written prior permission. The copyright holders make no representations
|
||||||
|
* about the suitability of this software for any purpose. It is provided "as
|
||||||
|
* is" without express or implied warranty.
|
||||||
|
*
|
||||||
|
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||||
|
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||||
|
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||||
|
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||||
|
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||||
|
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
|
||||||
|
* OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef META_WAYLAND_DATA_SOURCE_H
|
||||||
|
#define META_WAYLAND_DATA_SOURCE_H
|
||||||
|
|
||||||
|
#include <glib-object.h>
|
||||||
|
#include <wayland-server.h>
|
||||||
|
|
||||||
|
#include "wayland/meta-wayland-types.h"
|
||||||
|
|
||||||
|
#define META_TYPE_WAYLAND_DATA_SOURCE (meta_wayland_data_source_get_type ())
|
||||||
|
G_DECLARE_DERIVABLE_TYPE (MetaWaylandDataSource,
|
||||||
|
meta_wayland_data_source,
|
||||||
|
META, WAYLAND_DATA_SOURCE,
|
||||||
|
GObject)
|
||||||
|
|
||||||
|
typedef struct _MetaWaylandDataSourceClass MetaWaylandDataSourceClass;
|
||||||
|
|
||||||
|
struct _MetaWaylandDataSourceClass
|
||||||
|
{
|
||||||
|
GObjectClass parent_class;
|
||||||
|
|
||||||
|
void (* send) (MetaWaylandDataSource *source,
|
||||||
|
const gchar *mime_type,
|
||||||
|
gint fd);
|
||||||
|
void (* target) (MetaWaylandDataSource *source,
|
||||||
|
const gchar *mime_type);
|
||||||
|
void (* cancel) (MetaWaylandDataSource *source);
|
||||||
|
|
||||||
|
void (* action) (MetaWaylandDataSource *source,
|
||||||
|
uint32_t action);
|
||||||
|
void (* drop_performed) (MetaWaylandDataSource *source);
|
||||||
|
void (* drag_finished) (MetaWaylandDataSource *source);
|
||||||
|
};
|
||||||
|
|
||||||
|
MetaWaylandDataSource * meta_wayland_data_source_new (struct wl_resource *resource);
|
||||||
|
|
||||||
|
struct wl_resource * meta_wayland_data_source_get_resource (MetaWaylandDataSource *source);
|
||||||
|
void meta_wayland_data_source_set_resource (MetaWaylandDataSource *source,
|
||||||
|
struct wl_resource *resource);
|
||||||
|
|
||||||
|
gboolean meta_wayland_data_source_get_in_ask (MetaWaylandDataSource *source);
|
||||||
|
void meta_wayland_data_source_update_in_ask (MetaWaylandDataSource *source);
|
||||||
|
|
||||||
|
void meta_wayland_data_source_target (MetaWaylandDataSource *source,
|
||||||
|
const char *mime_type);
|
||||||
|
void meta_wayland_data_source_send (MetaWaylandDataSource *source,
|
||||||
|
const char *mime_type,
|
||||||
|
int fd);
|
||||||
|
void meta_wayland_data_source_cancel (MetaWaylandDataSource *source);
|
||||||
|
|
||||||
|
gboolean meta_wayland_data_source_has_target (MetaWaylandDataSource *source);
|
||||||
|
|
||||||
|
void meta_wayland_data_source_set_seat (MetaWaylandDataSource *source,
|
||||||
|
MetaWaylandSeat *seat);
|
||||||
|
MetaWaylandSeat * meta_wayland_data_source_get_seat (MetaWaylandDataSource *source);
|
||||||
|
|
||||||
|
void meta_wayland_data_source_set_has_target (MetaWaylandDataSource *source,
|
||||||
|
gboolean has_target);
|
||||||
|
struct wl_array * meta_wayland_data_source_get_mime_types (MetaWaylandDataSource *source);
|
||||||
|
gboolean meta_wayland_data_source_add_mime_type (MetaWaylandDataSource *source,
|
||||||
|
const gchar *mime_type);
|
||||||
|
gboolean meta_wayland_data_source_has_mime_type (MetaWaylandDataSource *source,
|
||||||
|
const char *mime_type);
|
||||||
|
|
||||||
|
gboolean meta_wayland_data_source_get_actions (MetaWaylandDataSource *source,
|
||||||
|
uint32_t *dnd_actions);
|
||||||
|
void meta_wayland_data_source_set_actions (MetaWaylandDataSource *source,
|
||||||
|
uint32_t dnd_actions);
|
||||||
|
|
||||||
|
enum wl_data_device_manager_dnd_action
|
||||||
|
meta_wayland_data_source_get_current_action (MetaWaylandDataSource *source);
|
||||||
|
void meta_wayland_data_source_set_current_action (MetaWaylandDataSource *source,
|
||||||
|
enum wl_data_device_manager_dnd_action action);
|
||||||
|
|
||||||
|
enum wl_data_device_manager_dnd_action
|
||||||
|
meta_wayland_data_source_get_user_action (MetaWaylandDataSource *source);
|
||||||
|
void meta_wayland_data_source_set_user_action (MetaWaylandDataSource *source,
|
||||||
|
uint32_t action);
|
||||||
|
|
||||||
|
MetaWaylandDataOffer *
|
||||||
|
meta_wayland_data_source_get_current_offer (MetaWaylandDataSource *source);
|
||||||
|
void meta_wayland_data_source_set_current_offer (MetaWaylandDataSource *source,
|
||||||
|
MetaWaylandDataOffer *offer);
|
||||||
|
|
||||||
|
gboolean meta_wayland_data_source_get_drop_performed (MetaWaylandDataSource *source);
|
||||||
|
|
||||||
|
void meta_wayland_data_source_notify_drop_performed (MetaWaylandDataSource *source);
|
||||||
|
void meta_wayland_data_source_notify_finish (MetaWaylandDataSource *source);
|
||||||
|
|
||||||
|
#endif /* META_WAYLAND_DATA_SOURCE_H */
|
||||||
@@ -662,8 +662,6 @@ meta_wayland_zxdg_toplevel_v6_apply_state (MetaWaylandSurfaceRole *surface_role
|
|||||||
MetaWaylandSurface *surface =
|
MetaWaylandSurface *surface =
|
||||||
meta_wayland_surface_role_get_surface (surface_role);
|
meta_wayland_surface_role_get_surface (surface_role);
|
||||||
MetaWindow *window;
|
MetaWindow *window;
|
||||||
MetaRectangle old_geometry;
|
|
||||||
gboolean geometry_changed;
|
|
||||||
|
|
||||||
window = meta_wayland_surface_get_window (surface);
|
window = meta_wayland_surface_get_window (surface);
|
||||||
if (!window)
|
if (!window)
|
||||||
@@ -672,8 +670,6 @@ meta_wayland_zxdg_toplevel_v6_apply_state (MetaWaylandSurfaceRole *surface_role
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
old_geometry = xdg_surface_priv->geometry;
|
|
||||||
|
|
||||||
surface_role_class =
|
surface_role_class =
|
||||||
META_WAYLAND_SURFACE_ROLE_CLASS (meta_wayland_zxdg_toplevel_v6_parent_class);
|
META_WAYLAND_SURFACE_ROLE_CLASS (meta_wayland_zxdg_toplevel_v6_parent_class);
|
||||||
surface_role_class->apply_state (surface_role, pending);
|
surface_role_class->apply_state (surface_role, pending);
|
||||||
@@ -688,13 +684,37 @@ meta_wayland_zxdg_toplevel_v6_apply_state (MetaWaylandSurfaceRole *surface_role
|
|||||||
meta_wayland_window_configuration_free (configuration);
|
meta_wayland_window_configuration_free (configuration);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_wayland_zxdg_toplevel_v6_post_apply_state (MetaWaylandSurfaceRole *surface_role,
|
||||||
|
MetaWaylandSurfaceState *pending)
|
||||||
|
{
|
||||||
|
MetaWaylandZxdgToplevelV6 *xdg_toplevel =
|
||||||
|
META_WAYLAND_ZXDG_TOPLEVEL_V6 (surface_role);
|
||||||
|
MetaWaylandZxdgSurfaceV6 *xdg_surface =
|
||||||
|
META_WAYLAND_ZXDG_SURFACE_V6 (xdg_toplevel);
|
||||||
|
MetaWaylandZxdgSurfaceV6Private *xdg_surface_priv =
|
||||||
|
meta_wayland_zxdg_surface_v6_get_instance_private (xdg_surface);
|
||||||
|
MetaWaylandSurfaceRoleClass *surface_role_class;
|
||||||
|
MetaWaylandSurface *surface =
|
||||||
|
meta_wayland_surface_role_get_surface (surface_role);
|
||||||
|
MetaWindow *window;
|
||||||
|
MetaRectangle old_geometry;
|
||||||
|
gboolean geometry_changed;
|
||||||
|
|
||||||
|
window = meta_wayland_surface_get_window (surface);
|
||||||
|
if (!window)
|
||||||
|
return;
|
||||||
|
|
||||||
if (!pending->newly_attached)
|
if (!pending->newly_attached)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* If the window disappeared the surface is not coming back. */
|
old_geometry = xdg_surface_priv->geometry;
|
||||||
if (!window)
|
|
||||||
return;
|
surface_role_class =
|
||||||
|
META_WAYLAND_SURFACE_ROLE_CLASS (meta_wayland_zxdg_toplevel_v6_parent_class);
|
||||||
|
surface_role_class->post_apply_state (surface_role, pending);
|
||||||
|
|
||||||
geometry_changed = !meta_rectangle_equal (&old_geometry, &xdg_surface_priv->geometry);
|
geometry_changed = !meta_rectangle_equal (&old_geometry, &xdg_surface_priv->geometry);
|
||||||
|
|
||||||
@@ -734,7 +754,6 @@ meta_wayland_zxdg_toplevel_v6_apply_state (MetaWaylandSurfaceRole *surface_role
|
|||||||
wl_resource_post_error (surface->resource,
|
wl_resource_post_error (surface->resource,
|
||||||
ZXDG_SHELL_V6_ERROR_INVALID_SURFACE_STATE,
|
ZXDG_SHELL_V6_ERROR_INVALID_SURFACE_STATE,
|
||||||
"Invalid min/max size");
|
"Invalid min/max size");
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -832,6 +851,8 @@ meta_wayland_zxdg_toplevel_v6_class_init (MetaWaylandZxdgToplevelV6Class *klass)
|
|||||||
|
|
||||||
surface_role_class = META_WAYLAND_SURFACE_ROLE_CLASS (klass);
|
surface_role_class = META_WAYLAND_SURFACE_ROLE_CLASS (klass);
|
||||||
surface_role_class->apply_state = meta_wayland_zxdg_toplevel_v6_apply_state;
|
surface_role_class->apply_state = meta_wayland_zxdg_toplevel_v6_apply_state;
|
||||||
|
surface_role_class->post_apply_state =
|
||||||
|
meta_wayland_zxdg_toplevel_v6_post_apply_state;
|
||||||
surface_role_class->get_toplevel = meta_wayland_zxdg_toplevel_v6_get_toplevel;
|
surface_role_class->get_toplevel = meta_wayland_zxdg_toplevel_v6_get_toplevel;
|
||||||
|
|
||||||
shell_surface_class = META_WAYLAND_SHELL_SURFACE_CLASS (klass);
|
shell_surface_class = META_WAYLAND_SHELL_SURFACE_CLASS (klass);
|
||||||
@@ -964,12 +985,7 @@ meta_wayland_zxdg_popup_v6_apply_state (MetaWaylandSurfaceRole *surface_role,
|
|||||||
MetaWaylandSurfaceState *pending)
|
MetaWaylandSurfaceState *pending)
|
||||||
{
|
{
|
||||||
MetaWaylandZxdgPopupV6 *xdg_popup = META_WAYLAND_ZXDG_POPUP_V6 (surface_role);
|
MetaWaylandZxdgPopupV6 *xdg_popup = META_WAYLAND_ZXDG_POPUP_V6 (surface_role);
|
||||||
MetaWaylandZxdgSurfaceV6 *xdg_surface =
|
|
||||||
META_WAYLAND_ZXDG_SURFACE_V6 (surface_role);
|
|
||||||
MetaWaylandSurfaceRoleClass *surface_role_class;
|
MetaWaylandSurfaceRoleClass *surface_role_class;
|
||||||
MetaWaylandSurface *surface =
|
|
||||||
meta_wayland_surface_role_get_surface (surface_role);
|
|
||||||
MetaWindow *window;
|
|
||||||
|
|
||||||
if (xdg_popup->setup.parent_surface)
|
if (xdg_popup->setup.parent_surface)
|
||||||
finish_popup_setup (xdg_popup);
|
finish_popup_setup (xdg_popup);
|
||||||
@@ -977,12 +993,27 @@ meta_wayland_zxdg_popup_v6_apply_state (MetaWaylandSurfaceRole *surface_role,
|
|||||||
surface_role_class =
|
surface_role_class =
|
||||||
META_WAYLAND_SURFACE_ROLE_CLASS (meta_wayland_zxdg_popup_v6_parent_class);
|
META_WAYLAND_SURFACE_ROLE_CLASS (meta_wayland_zxdg_popup_v6_parent_class);
|
||||||
surface_role_class->apply_state (surface_role, pending);
|
surface_role_class->apply_state (surface_role, pending);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_wayland_zxdg_popup_v6_post_apply_state (MetaWaylandSurfaceRole *surface_role,
|
||||||
|
MetaWaylandSurfaceState *pending)
|
||||||
|
{
|
||||||
|
MetaWaylandZxdgSurfaceV6 *xdg_surface =
|
||||||
|
META_WAYLAND_ZXDG_SURFACE_V6 (surface_role);
|
||||||
|
MetaWaylandSurfaceRoleClass *surface_role_class;
|
||||||
|
MetaWaylandSurface *surface =
|
||||||
|
meta_wayland_surface_role_get_surface (surface_role);
|
||||||
|
MetaWindow *window;
|
||||||
|
|
||||||
/* If the window disappeared the surface is not coming back. */
|
|
||||||
window = meta_wayland_surface_get_window (surface);
|
window = meta_wayland_surface_get_window (surface);
|
||||||
if (!window)
|
if (!window)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
surface_role_class =
|
||||||
|
META_WAYLAND_SURFACE_ROLE_CLASS (meta_wayland_zxdg_popup_v6_parent_class);
|
||||||
|
surface_role_class->post_apply_state (surface_role, pending);
|
||||||
|
|
||||||
if (!pending->newly_attached)
|
if (!pending->newly_attached)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -1165,6 +1196,8 @@ meta_wayland_zxdg_popup_v6_class_init (MetaWaylandZxdgPopupV6Class *klass)
|
|||||||
|
|
||||||
surface_role_class = META_WAYLAND_SURFACE_ROLE_CLASS (klass);
|
surface_role_class = META_WAYLAND_SURFACE_ROLE_CLASS (klass);
|
||||||
surface_role_class->apply_state = meta_wayland_zxdg_popup_v6_apply_state;
|
surface_role_class->apply_state = meta_wayland_zxdg_popup_v6_apply_state;
|
||||||
|
surface_role_class->post_apply_state =
|
||||||
|
meta_wayland_zxdg_popup_v6_post_apply_state;
|
||||||
surface_role_class->get_toplevel = meta_wayland_zxdg_popup_v6_get_toplevel;
|
surface_role_class->get_toplevel = meta_wayland_zxdg_popup_v6_get_toplevel;
|
||||||
|
|
||||||
shell_surface_class = META_WAYLAND_SHELL_SURFACE_CLASS (klass);
|
shell_surface_class = META_WAYLAND_SHELL_SURFACE_CLASS (klass);
|
||||||
@@ -1331,8 +1364,6 @@ meta_wayland_zxdg_surface_v6_apply_state (MetaWaylandSurfaceRole *surface_role,
|
|||||||
{
|
{
|
||||||
MetaWaylandZxdgSurfaceV6 *xdg_surface =
|
MetaWaylandZxdgSurfaceV6 *xdg_surface =
|
||||||
META_WAYLAND_ZXDG_SURFACE_V6 (surface_role);
|
META_WAYLAND_ZXDG_SURFACE_V6 (surface_role);
|
||||||
MetaWaylandShellSurface *shell_surface =
|
|
||||||
META_WAYLAND_SHELL_SURFACE (xdg_surface);
|
|
||||||
MetaWaylandZxdgSurfaceV6Private *priv =
|
MetaWaylandZxdgSurfaceV6Private *priv =
|
||||||
meta_wayland_zxdg_surface_v6_get_instance_private (xdg_surface);
|
meta_wayland_zxdg_surface_v6_get_instance_private (xdg_surface);
|
||||||
MetaWaylandSurface *surface =
|
MetaWaylandSurface *surface =
|
||||||
@@ -1370,8 +1401,18 @@ meta_wayland_zxdg_surface_v6_apply_state (MetaWaylandSurfaceRole *surface_role,
|
|||||||
|
|
||||||
if (surface->buffer_ref.buffer)
|
if (surface->buffer_ref.buffer)
|
||||||
priv->first_buffer_attached = TRUE;
|
priv->first_buffer_attached = TRUE;
|
||||||
else
|
}
|
||||||
return;
|
|
||||||
|
static void
|
||||||
|
meta_wayland_zxdg_surface_v6_post_apply_state (MetaWaylandSurfaceRole *surface_role,
|
||||||
|
MetaWaylandSurfaceState *pending)
|
||||||
|
{
|
||||||
|
MetaWaylandZxdgSurfaceV6 *xdg_surface =
|
||||||
|
META_WAYLAND_ZXDG_SURFACE_V6 (surface_role);
|
||||||
|
MetaWaylandZxdgSurfaceV6Private *priv =
|
||||||
|
meta_wayland_zxdg_surface_v6_get_instance_private (xdg_surface);
|
||||||
|
MetaWaylandShellSurface *shell_surface =
|
||||||
|
META_WAYLAND_SHELL_SURFACE (xdg_surface);
|
||||||
|
|
||||||
if (pending->has_new_geometry)
|
if (pending->has_new_geometry)
|
||||||
{
|
{
|
||||||
@@ -1526,6 +1567,8 @@ meta_wayland_zxdg_surface_v6_class_init (MetaWaylandZxdgSurfaceV6Class *klass)
|
|||||||
|
|
||||||
surface_role_class = META_WAYLAND_SURFACE_ROLE_CLASS (klass);
|
surface_role_class = META_WAYLAND_SURFACE_ROLE_CLASS (klass);
|
||||||
surface_role_class->apply_state = meta_wayland_zxdg_surface_v6_apply_state;
|
surface_role_class->apply_state = meta_wayland_zxdg_surface_v6_apply_state;
|
||||||
|
surface_role_class->post_apply_state =
|
||||||
|
meta_wayland_zxdg_surface_v6_post_apply_state;
|
||||||
surface_role_class->assigned = meta_wayland_zxdg_surface_v6_assigned;
|
surface_role_class->assigned = meta_wayland_zxdg_surface_v6_assigned;
|
||||||
|
|
||||||
shell_surface_class = META_WAYLAND_SHELL_SURFACE_CLASS (klass);
|
shell_surface_class = META_WAYLAND_SHELL_SURFACE_CLASS (klass);
|
||||||
|
|||||||
@@ -24,6 +24,7 @@
|
|||||||
#include "wayland/meta-wayland-seat.h"
|
#include "wayland/meta-wayland-seat.h"
|
||||||
|
|
||||||
#include "wayland/meta-wayland-data-device.h"
|
#include "wayland/meta-wayland-data-device.h"
|
||||||
|
#include "wayland/meta-wayland-data-device-primary-legacy.h"
|
||||||
#include "wayland/meta-wayland-private.h"
|
#include "wayland/meta-wayland-private.h"
|
||||||
#include "wayland/meta-wayland-tablet-seat.h"
|
#include "wayland/meta-wayland-tablet-seat.h"
|
||||||
#include "wayland/meta-wayland-versions.h"
|
#include "wayland/meta-wayland-versions.h"
|
||||||
@@ -231,6 +232,8 @@ meta_wayland_seat_new (MetaWaylandCompositor *compositor,
|
|||||||
seat->gtk_text_input = meta_wayland_gtk_text_input_new (seat);
|
seat->gtk_text_input = meta_wayland_gtk_text_input_new (seat);
|
||||||
|
|
||||||
meta_wayland_data_device_init (&seat->data_device);
|
meta_wayland_data_device_init (&seat->data_device);
|
||||||
|
meta_wayland_data_device_primary_init (&seat->primary_data_device);
|
||||||
|
meta_wayland_data_device_primary_legacy_init (&seat->primary_legacy_data_device);
|
||||||
|
|
||||||
clutter_seat = clutter_backend_get_default_seat (clutter_get_default_backend ());
|
clutter_seat = clutter_backend_get_default_seat (clutter_get_default_backend ());
|
||||||
meta_wayland_seat_update_capabilities (seat, clutter_seat);
|
meta_wayland_seat_update_capabilities (seat, clutter_seat);
|
||||||
@@ -431,6 +434,8 @@ meta_wayland_seat_set_input_focus (MetaWaylandSeat *seat,
|
|||||||
{
|
{
|
||||||
meta_wayland_keyboard_set_focus (seat->keyboard, surface);
|
meta_wayland_keyboard_set_focus (seat->keyboard, surface);
|
||||||
meta_wayland_data_device_set_keyboard_focus (&seat->data_device);
|
meta_wayland_data_device_set_keyboard_focus (&seat->data_device);
|
||||||
|
meta_wayland_data_device_primary_set_keyboard_focus (&seat->primary_data_device);
|
||||||
|
meta_wayland_data_device_primary_legacy_set_keyboard_focus (&seat->primary_legacy_data_device);
|
||||||
}
|
}
|
||||||
|
|
||||||
tablet_seat = meta_wayland_tablet_manager_ensure_seat (compositor->tablet_manager, seat);
|
tablet_seat = meta_wayland_tablet_manager_ensure_seat (compositor->tablet_manager, seat);
|
||||||
|
|||||||
@@ -26,6 +26,8 @@
|
|||||||
|
|
||||||
#include "clutter/clutter.h"
|
#include "clutter/clutter.h"
|
||||||
#include "wayland/meta-wayland-data-device.h"
|
#include "wayland/meta-wayland-data-device.h"
|
||||||
|
#include "wayland/meta-wayland-data-device-primary.h"
|
||||||
|
#include "wayland/meta-wayland-data-device-primary-legacy.h"
|
||||||
#include "wayland/meta-wayland-input-device.h"
|
#include "wayland/meta-wayland-input-device.h"
|
||||||
#include "wayland/meta-wayland-keyboard.h"
|
#include "wayland/meta-wayland-keyboard.h"
|
||||||
#include "wayland/meta-wayland-pointer.h"
|
#include "wayland/meta-wayland-pointer.h"
|
||||||
@@ -45,6 +47,8 @@ struct _MetaWaylandSeat
|
|||||||
MetaWaylandTouch *touch;
|
MetaWaylandTouch *touch;
|
||||||
|
|
||||||
MetaWaylandDataDevice data_device;
|
MetaWaylandDataDevice data_device;
|
||||||
|
MetaWaylandDataDevicePrimary primary_data_device;
|
||||||
|
MetaWaylandDataDevicePrimaryLegacy primary_legacy_data_device;
|
||||||
|
|
||||||
MetaWaylandGtkTextInput *gtk_text_input;
|
MetaWaylandGtkTextInput *gtk_text_input;
|
||||||
MetaWaylandTextInput *text_input;
|
MetaWaylandTextInput *text_input;
|
||||||
|
|||||||
@@ -113,6 +113,10 @@ static void
|
|||||||
meta_wayland_surface_role_apply_state (MetaWaylandSurfaceRole *surface_role,
|
meta_wayland_surface_role_apply_state (MetaWaylandSurfaceRole *surface_role,
|
||||||
MetaWaylandSurfaceState *pending);
|
MetaWaylandSurfaceState *pending);
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_wayland_surface_role_post_apply_state (MetaWaylandSurfaceRole *surface_role,
|
||||||
|
MetaWaylandSurfaceState *pending);
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
meta_wayland_surface_role_is_on_logical_monitor (MetaWaylandSurfaceRole *surface_role,
|
meta_wayland_surface_role_is_on_logical_monitor (MetaWaylandSurfaceRole *surface_role,
|
||||||
MetaLogicalMonitor *logical_monitor);
|
MetaLogicalMonitor *logical_monitor);
|
||||||
@@ -757,8 +761,6 @@ cleanup:
|
|||||||
surface_state_signals[SURFACE_STATE_SIGNAL_APPLIED],
|
surface_state_signals[SURFACE_STATE_SIGNAL_APPLIED],
|
||||||
0);
|
0);
|
||||||
|
|
||||||
meta_wayland_surface_state_reset (state);
|
|
||||||
|
|
||||||
META_WAYLAND_SURFACE_FOREACH_SUBSURFACE (surface, subsurface_surface)
|
META_WAYLAND_SURFACE_FOREACH_SUBSURFACE (surface, subsurface_surface)
|
||||||
{
|
{
|
||||||
MetaWaylandSubsurface *subsurface;
|
MetaWaylandSubsurface *subsurface;
|
||||||
@@ -782,6 +784,11 @@ cleanup:
|
|||||||
meta_window_actor_notify_damaged (toplevel_window_actor);
|
meta_window_actor_notify_damaged (toplevel_window_actor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (surface->role)
|
||||||
|
meta_wayland_surface_role_post_apply_state (surface->role, state);
|
||||||
|
|
||||||
|
meta_wayland_surface_state_reset (state);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -1696,6 +1703,17 @@ meta_wayland_surface_role_pre_apply_state (MetaWaylandSurfaceRole *surface_role
|
|||||||
klass->pre_apply_state (surface_role, pending);
|
klass->pre_apply_state (surface_role, pending);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_wayland_surface_role_post_apply_state (MetaWaylandSurfaceRole *surface_role,
|
||||||
|
MetaWaylandSurfaceState *pending)
|
||||||
|
{
|
||||||
|
MetaWaylandSurfaceRoleClass *klass;
|
||||||
|
|
||||||
|
klass = META_WAYLAND_SURFACE_ROLE_GET_CLASS (surface_role);
|
||||||
|
if (klass->post_apply_state)
|
||||||
|
klass->post_apply_state (surface_role, pending);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
meta_wayland_surface_role_apply_state (MetaWaylandSurfaceRole *surface_role,
|
meta_wayland_surface_role_apply_state (MetaWaylandSurfaceRole *surface_role,
|
||||||
MetaWaylandSurfaceState *pending)
|
MetaWaylandSurfaceState *pending)
|
||||||
|
|||||||
@@ -58,6 +58,8 @@ struct _MetaWaylandSurfaceRoleClass
|
|||||||
MetaWaylandSurfaceState *pending);
|
MetaWaylandSurfaceState *pending);
|
||||||
void (*apply_state) (MetaWaylandSurfaceRole *surface_role,
|
void (*apply_state) (MetaWaylandSurfaceRole *surface_role,
|
||||||
MetaWaylandSurfaceState *pending);
|
MetaWaylandSurfaceState *pending);
|
||||||
|
void (*post_apply_state) (MetaWaylandSurfaceRole *surface_role,
|
||||||
|
MetaWaylandSurfaceState *pending);
|
||||||
gboolean (*is_on_logical_monitor) (MetaWaylandSurfaceRole *surface_role,
|
gboolean (*is_on_logical_monitor) (MetaWaylandSurfaceRole *surface_role,
|
||||||
MetaLogicalMonitor *logical_monitor);
|
MetaLogicalMonitor *logical_monitor);
|
||||||
MetaWaylandSurface * (*get_toplevel) (MetaWaylandSurfaceRole *surface_role);
|
MetaWaylandSurface * (*get_toplevel) (MetaWaylandSurfaceRole *surface_role);
|
||||||
|
|||||||
@@ -37,6 +37,8 @@ typedef struct _MetaWaylandTouch MetaWaylandTouch;
|
|||||||
typedef struct _MetaWaylandDragDestFuncs MetaWaylandDragDestFuncs;
|
typedef struct _MetaWaylandDragDestFuncs MetaWaylandDragDestFuncs;
|
||||||
typedef struct _MetaWaylandDataOffer MetaWaylandDataOffer;
|
typedef struct _MetaWaylandDataOffer MetaWaylandDataOffer;
|
||||||
typedef struct _MetaWaylandDataDevice MetaWaylandDataDevice;
|
typedef struct _MetaWaylandDataDevice MetaWaylandDataDevice;
|
||||||
|
typedef struct _MetaWaylandDataDevicePrimary MetaWaylandDataDevicePrimary;
|
||||||
|
typedef struct _MetaWaylandDataDevicePrimaryLegacy MetaWaylandDataDevicePrimaryLegacy;
|
||||||
|
|
||||||
typedef struct _MetaWaylandTabletManager MetaWaylandTabletManager;
|
typedef struct _MetaWaylandTabletManager MetaWaylandTabletManager;
|
||||||
typedef struct _MetaWaylandTabletSeat MetaWaylandTabletSeat;
|
typedef struct _MetaWaylandTabletSeat MetaWaylandTabletSeat;
|
||||||
|
|||||||
@@ -744,8 +744,6 @@ meta_wayland_xdg_toplevel_apply_state (MetaWaylandSurfaceRole *surface_role,
|
|||||||
MetaWaylandSurface *surface =
|
MetaWaylandSurface *surface =
|
||||||
meta_wayland_surface_role_get_surface (surface_role);
|
meta_wayland_surface_role_get_surface (surface_role);
|
||||||
MetaWindow *window;
|
MetaWindow *window;
|
||||||
MetaRectangle old_geometry;
|
|
||||||
gboolean geometry_changed;
|
|
||||||
|
|
||||||
window = meta_wayland_surface_get_window (surface);
|
window = meta_wayland_surface_get_window (surface);
|
||||||
if (!window)
|
if (!window)
|
||||||
@@ -765,8 +763,6 @@ meta_wayland_xdg_toplevel_apply_state (MetaWaylandSurfaceRole *surface_role,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
old_geometry = xdg_surface_priv->geometry;
|
|
||||||
|
|
||||||
surface_role_class =
|
surface_role_class =
|
||||||
META_WAYLAND_SURFACE_ROLE_CLASS (meta_wayland_xdg_toplevel_parent_class);
|
META_WAYLAND_SURFACE_ROLE_CLASS (meta_wayland_xdg_toplevel_parent_class);
|
||||||
surface_role_class->apply_state (surface_role, pending);
|
surface_role_class->apply_state (surface_role, pending);
|
||||||
@@ -780,17 +776,42 @@ meta_wayland_xdg_toplevel_apply_state (MetaWaylandSurfaceRole *surface_role,
|
|||||||
meta_wayland_window_configuration_free (configuration);
|
meta_wayland_window_configuration_free (configuration);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_wayland_xdg_toplevel_post_apply_state (MetaWaylandSurfaceRole *surface_role,
|
||||||
|
MetaWaylandSurfaceState *pending)
|
||||||
|
{
|
||||||
|
MetaWaylandXdgSurface *xdg_surface = META_WAYLAND_XDG_SURFACE (surface_role);
|
||||||
|
MetaWaylandXdgSurfacePrivate *xdg_surface_priv =
|
||||||
|
meta_wayland_xdg_surface_get_instance_private (xdg_surface);
|
||||||
|
MetaWaylandSurface *surface =
|
||||||
|
meta_wayland_surface_role_get_surface (surface_role);
|
||||||
|
MetaWaylandSurfaceRoleClass *surface_role_class;
|
||||||
|
MetaWindow *window;
|
||||||
|
MetaRectangle old_geometry;
|
||||||
|
MetaRectangle window_geometry;
|
||||||
|
|
||||||
|
gboolean geometry_changed;
|
||||||
|
|
||||||
|
window = meta_wayland_surface_get_window (surface);
|
||||||
|
if (!window)
|
||||||
|
return;
|
||||||
|
|
||||||
|
old_geometry = xdg_surface_priv->geometry;
|
||||||
|
|
||||||
|
surface_role_class =
|
||||||
|
META_WAYLAND_SURFACE_ROLE_CLASS (meta_wayland_xdg_toplevel_parent_class);
|
||||||
|
surface_role_class->post_apply_state (surface_role, pending);
|
||||||
|
|
||||||
if (!pending->newly_attached)
|
if (!pending->newly_attached)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
geometry_changed = !meta_rectangle_equal (&old_geometry, &xdg_surface_priv->geometry);
|
window_geometry = meta_wayland_xdg_surface_get_window_geometry (xdg_surface);
|
||||||
|
geometry_changed = !meta_rectangle_equal (&old_geometry, &window_geometry);
|
||||||
|
|
||||||
if (geometry_changed || pending->has_acked_configure_serial)
|
if (geometry_changed || pending->has_acked_configure_serial)
|
||||||
{
|
{
|
||||||
MetaRectangle window_geometry;
|
|
||||||
|
|
||||||
window_geometry = meta_wayland_xdg_surface_get_window_geometry (xdg_surface);
|
|
||||||
meta_window_wayland_finish_move_resize (window, window_geometry, pending);
|
meta_window_wayland_finish_move_resize (window, window_geometry, pending);
|
||||||
}
|
}
|
||||||
else if (pending->dx != 0 || pending->dy != 0)
|
else if (pending->dx != 0 || pending->dy != 0)
|
||||||
@@ -821,7 +842,6 @@ meta_wayland_xdg_toplevel_apply_state (MetaWaylandSurfaceRole *surface_role,
|
|||||||
wl_resource_post_error (surface->resource,
|
wl_resource_post_error (surface->resource,
|
||||||
XDG_WM_BASE_ERROR_INVALID_SURFACE_STATE,
|
XDG_WM_BASE_ERROR_INVALID_SURFACE_STATE,
|
||||||
"Invalid min/max size");
|
"Invalid min/max size");
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -940,6 +960,7 @@ meta_wayland_xdg_toplevel_class_init (MetaWaylandXdgToplevelClass *klass)
|
|||||||
|
|
||||||
surface_role_class = META_WAYLAND_SURFACE_ROLE_CLASS (klass);
|
surface_role_class = META_WAYLAND_SURFACE_ROLE_CLASS (klass);
|
||||||
surface_role_class->apply_state = meta_wayland_xdg_toplevel_apply_state;
|
surface_role_class->apply_state = meta_wayland_xdg_toplevel_apply_state;
|
||||||
|
surface_role_class->post_apply_state = meta_wayland_xdg_toplevel_post_apply_state;
|
||||||
surface_role_class->get_toplevel = meta_wayland_xdg_toplevel_get_toplevel;
|
surface_role_class->get_toplevel = meta_wayland_xdg_toplevel_get_toplevel;
|
||||||
|
|
||||||
shell_surface_class = META_WAYLAND_SHELL_SURFACE_CLASS (klass);
|
shell_surface_class = META_WAYLAND_SHELL_SURFACE_CLASS (klass);
|
||||||
@@ -1092,10 +1113,6 @@ meta_wayland_xdg_popup_apply_state (MetaWaylandSurfaceRole *surface_role,
|
|||||||
MetaWaylandSurfaceRoleClass *surface_role_class;
|
MetaWaylandSurfaceRoleClass *surface_role_class;
|
||||||
MetaWaylandSurface *surface =
|
MetaWaylandSurface *surface =
|
||||||
meta_wayland_surface_role_get_surface (surface_role);
|
meta_wayland_surface_role_get_surface (surface_role);
|
||||||
MetaWindow *window;
|
|
||||||
MetaRectangle buffer_rect;
|
|
||||||
MetaWindow *parent_window;
|
|
||||||
MetaRectangle parent_buffer_rect;
|
|
||||||
|
|
||||||
if (xdg_popup->setup.parent_surface)
|
if (xdg_popup->setup.parent_surface)
|
||||||
finish_popup_setup (xdg_popup);
|
finish_popup_setup (xdg_popup);
|
||||||
@@ -1118,8 +1135,23 @@ meta_wayland_xdg_popup_apply_state (MetaWaylandSurfaceRole *surface_role,
|
|||||||
"Can't commit buffer to dismissed popup");
|
"Can't commit buffer to dismissed popup");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_wayland_xdg_popup_post_apply_state (MetaWaylandSurfaceRole *surface_role,
|
||||||
|
MetaWaylandSurfaceState *pending)
|
||||||
|
{
|
||||||
|
MetaWaylandXdgPopup *xdg_popup = META_WAYLAND_XDG_POPUP (surface_role);
|
||||||
|
MetaWaylandXdgSurface *xdg_surface = META_WAYLAND_XDG_SURFACE (surface_role);
|
||||||
|
MetaWaylandSurface *surface =
|
||||||
|
meta_wayland_surface_role_get_surface (surface_role);
|
||||||
|
MetaWaylandSurfaceRoleClass *surface_role_class =
|
||||||
|
META_WAYLAND_SURFACE_ROLE_CLASS (meta_wayland_xdg_popup_parent_class);
|
||||||
|
MetaWindow *window;
|
||||||
|
MetaWindow *parent_window;
|
||||||
|
MetaRectangle buffer_rect;
|
||||||
|
MetaRectangle parent_buffer_rect;
|
||||||
|
|
||||||
/* If the window disappeared the surface is not coming back. */
|
|
||||||
window = meta_wayland_surface_get_window (surface);
|
window = meta_wayland_surface_get_window (surface);
|
||||||
if (!window)
|
if (!window)
|
||||||
return;
|
return;
|
||||||
@@ -1130,6 +1162,8 @@ meta_wayland_xdg_popup_apply_state (MetaWaylandSurfaceRole *surface_role,
|
|||||||
if (!surface->buffer_ref.buffer)
|
if (!surface->buffer_ref.buffer)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
surface_role_class->post_apply_state (surface_role, pending);
|
||||||
|
|
||||||
if (pending->has_acked_configure_serial)
|
if (pending->has_acked_configure_serial)
|
||||||
{
|
{
|
||||||
MetaRectangle window_geometry;
|
MetaRectangle window_geometry;
|
||||||
@@ -1326,6 +1360,7 @@ meta_wayland_xdg_popup_class_init (MetaWaylandXdgPopupClass *klass)
|
|||||||
|
|
||||||
surface_role_class = META_WAYLAND_SURFACE_ROLE_CLASS (klass);
|
surface_role_class = META_WAYLAND_SURFACE_ROLE_CLASS (klass);
|
||||||
surface_role_class->apply_state = meta_wayland_xdg_popup_apply_state;
|
surface_role_class->apply_state = meta_wayland_xdg_popup_apply_state;
|
||||||
|
surface_role_class->post_apply_state = meta_wayland_xdg_popup_post_apply_state;
|
||||||
surface_role_class->get_toplevel = meta_wayland_xdg_popup_get_toplevel;
|
surface_role_class->get_toplevel = meta_wayland_xdg_popup_get_toplevel;
|
||||||
|
|
||||||
shell_surface_class = META_WAYLAND_SHELL_SURFACE_CLASS (klass);
|
shell_surface_class = META_WAYLAND_SHELL_SURFACE_CLASS (klass);
|
||||||
@@ -1504,8 +1539,6 @@ meta_wayland_xdg_surface_apply_state (MetaWaylandSurfaceRole *surface_role,
|
|||||||
MetaWaylandSurfaceState *pending)
|
MetaWaylandSurfaceState *pending)
|
||||||
{
|
{
|
||||||
MetaWaylandXdgSurface *xdg_surface = META_WAYLAND_XDG_SURFACE (surface_role);
|
MetaWaylandXdgSurface *xdg_surface = META_WAYLAND_XDG_SURFACE (surface_role);
|
||||||
MetaWaylandShellSurface *shell_surface =
|
|
||||||
META_WAYLAND_SHELL_SURFACE (xdg_surface);
|
|
||||||
MetaWaylandXdgSurfacePrivate *priv =
|
MetaWaylandXdgSurfacePrivate *priv =
|
||||||
meta_wayland_xdg_surface_get_instance_private (xdg_surface);
|
meta_wayland_xdg_surface_get_instance_private (xdg_surface);
|
||||||
MetaWaylandSurface *surface =
|
MetaWaylandSurface *surface =
|
||||||
@@ -1526,8 +1559,17 @@ meta_wayland_xdg_surface_apply_state (MetaWaylandSurfaceRole *surface_role,
|
|||||||
|
|
||||||
if (surface->buffer_ref.buffer)
|
if (surface->buffer_ref.buffer)
|
||||||
priv->first_buffer_attached = TRUE;
|
priv->first_buffer_attached = TRUE;
|
||||||
else
|
}
|
||||||
return;
|
|
||||||
|
static void
|
||||||
|
meta_wayland_xdg_surface_post_apply_state (MetaWaylandSurfaceRole *surface_role,
|
||||||
|
MetaWaylandSurfaceState *pending)
|
||||||
|
{
|
||||||
|
MetaWaylandXdgSurface *xdg_surface = META_WAYLAND_XDG_SURFACE (surface_role);
|
||||||
|
MetaWaylandXdgSurfacePrivate *priv =
|
||||||
|
meta_wayland_xdg_surface_get_instance_private (xdg_surface);
|
||||||
|
MetaWaylandShellSurface *shell_surface =
|
||||||
|
META_WAYLAND_SHELL_SURFACE (surface_role);
|
||||||
|
|
||||||
if (pending->has_new_geometry)
|
if (pending->has_new_geometry)
|
||||||
{
|
{
|
||||||
@@ -1680,6 +1722,7 @@ meta_wayland_xdg_surface_class_init (MetaWaylandXdgSurfaceClass *klass)
|
|||||||
|
|
||||||
surface_role_class = META_WAYLAND_SURFACE_ROLE_CLASS (klass);
|
surface_role_class = META_WAYLAND_SURFACE_ROLE_CLASS (klass);
|
||||||
surface_role_class->apply_state = meta_wayland_xdg_surface_apply_state;
|
surface_role_class->apply_state = meta_wayland_xdg_surface_apply_state;
|
||||||
|
surface_role_class->post_apply_state = meta_wayland_xdg_surface_post_apply_state;
|
||||||
surface_role_class->assigned = meta_wayland_xdg_surface_assigned;
|
surface_role_class->assigned = meta_wayland_xdg_surface_assigned;
|
||||||
|
|
||||||
shell_surface_class = META_WAYLAND_SHELL_SURFACE_CLASS (klass);
|
shell_surface_class = META_WAYLAND_SHELL_SURFACE_CLASS (klass);
|
||||||
|
|||||||
@@ -395,6 +395,8 @@ meta_wayland_init (void)
|
|||||||
|
|
||||||
meta_wayland_outputs_init (compositor);
|
meta_wayland_outputs_init (compositor);
|
||||||
meta_wayland_data_device_manager_init (compositor);
|
meta_wayland_data_device_manager_init (compositor);
|
||||||
|
meta_wayland_data_device_primary_manager_init (compositor);
|
||||||
|
meta_wayland_data_device_primary_legacy_manager_init (compositor);
|
||||||
meta_wayland_subsurfaces_init (compositor);
|
meta_wayland_subsurfaces_init (compositor);
|
||||||
meta_wayland_shell_init (compositor);
|
meta_wayland_shell_init (compositor);
|
||||||
meta_wayland_pointer_gestures_init (compositor);
|
meta_wayland_pointer_gestures_init (compositor);
|
||||||
|
|||||||
@@ -230,7 +230,7 @@ xdnd_send_position (MetaXWaylandDnd *dnd,
|
|||||||
XEvent xev = { 0 };
|
XEvent xev = { 0 };
|
||||||
|
|
||||||
user_action = meta_wayland_data_source_get_user_action (source);
|
user_action = meta_wayland_data_source_get_user_action (source);
|
||||||
actions = meta_wayland_data_source_get_actions (source);
|
meta_wayland_data_source_get_actions (source, &actions);
|
||||||
|
|
||||||
if (user_action & actions)
|
if (user_action & actions)
|
||||||
action = user_action;
|
action = user_action;
|
||||||
@@ -367,6 +367,7 @@ transfer_cb (MetaSelection *selection,
|
|||||||
}
|
}
|
||||||
|
|
||||||
g_output_stream_close (stream, NULL, NULL);
|
g_output_stream_close (stream, NULL, NULL);
|
||||||
|
g_object_unref (stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|||||||
@@ -32,13 +32,6 @@
|
|||||||
#define UTF8_STRING_MIMETYPE "text/plain;charset=utf-8"
|
#define UTF8_STRING_MIMETYPE "text/plain;charset=utf-8"
|
||||||
#define STRING_MIMETYPE "text/plain"
|
#define STRING_MIMETYPE "text/plain"
|
||||||
|
|
||||||
/* Set an arbitrary (although generous) threshold to determine whether a
|
|
||||||
* XFixesSelectionNotify corresponds to a XSetSelectionOwner from another
|
|
||||||
* client. The selection timestamp is not updated if the owner client is
|
|
||||||
* closed.
|
|
||||||
*/
|
|
||||||
#define SELECTION_CLEARED_BY_CLIENT(e) (e->timestamp - e->selection_timestamp < 50)
|
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
atom_to_selection_type (Display *xdisplay,
|
atom_to_selection_type (Display *xdisplay,
|
||||||
Atom selection,
|
Atom selection,
|
||||||
@@ -342,7 +335,7 @@ meta_x11_selection_handle_xfixes_selection_notify (MetaX11Display *x11_display,
|
|||||||
|
|
||||||
if (event->owner == None && x11_display->selection.owners[selection_type])
|
if (event->owner == None && x11_display->selection.owners[selection_type])
|
||||||
{
|
{
|
||||||
if (SELECTION_CLEARED_BY_CLIENT (event))
|
if (event->subtype == XFixesSetSelectionOwnerNotify)
|
||||||
{
|
{
|
||||||
MetaSelectionSource *source;
|
MetaSelectionSource *source;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user