Compare commits

...

22 Commits

Author SHA1 Message Date
Florian Müllner
34ff206604 Bump version to 3.35.1
Update NEWS.
2019-10-12 20:35:43 +02:00
Carlos Garnacho
5c1be2233d x11: Map mimetypes back to selection atoms
This may be seen as the missing half of
https://gitlab.gnome.org/GNOME/mutter/merge_requests/842. Now that we
translate some atoms to better known mimetypes, we should also translate
those mimetypes to the underlying atoms if we might have added them.

Fixes c&p from certain X11 clients.

Fixes: https://gitlab.gnome.org/GNOME/mutter/issues/854
2019-10-12 19:18:19 +02:00
Carlos Garnacho
e1751ad9ee wayland: Figure out better the right selection source for a wl_data_offer
We were just looking at DnD actions which might still be unset at that
point. Instead of doing these heuristics, store the selection type on
the data offer.

Fixes: https://gitlab.gnome.org/GNOME/mutter/issues/845
2019-10-12 01:19:48 +02:00
Carlos Garnacho
84cc89e19a wayland: Set dummy selection source on .set_selection(null)
Requesting a selection with a NULL data source means "unset the clipboard",
but internally we use an unset clipboard as the indication that the
clipboard manager should take over.

Moreover, this unset request may go unheard if the current owner is someone
else than the MetaWaylandDataDevice.

Instead, set a dummy data source with no mimetypes nor data, this both
prevents the clipboard manager from taking over and ensures the selection
is replaced with it.

The MetaSelectionSourceMemory was also added some checks to allow for this
dummy mode.

Fixes: https://gitlab.gnome.org/GNOME/mutter/issues/793
2019-10-11 23:04:01 +02:00
Carlos Garnacho
ea4665bf51 wayland: Simplify MetaSelectionSourceWayland
Instead of taking resource and send/cancel funcs, take a
MetaWaylandDataSource, which exposes all the vfuncs to do the same on the
internal resource.

This has the added side effect that only MetaWaylandDataSource has a
pointer to the wl_resource, which may be unset untimely.

Fixes: https://gitlab.gnome.org/GNOME/mutter/issues/842
2019-10-11 23:04:01 +02:00
Carlos Garnacho
227d272049 wayland: Check resource before emitting cancelled event
If a data source is destroyed we first unset the resource, and then try to
unref the related selection source. At this point the only event that might
be emitted by the internal selection machinery is .cancelled, so make sure
we avoid it on destroyed sources.

Fixes: https://gitlab.gnome.org/GNOME/mutter/issues/842
2019-10-11 23:01:44 +02:00
Carlos Garnacho
e53db92a7b wayland: Emit wl/primary offer after changing selection
We are still poking the mimetypes from the previous selection when creating
the new offer. This may come out wrong between changes of the copied
mimetypes.

Fixes: https://gitlab.gnome.org/GNOME/mutter/issues/789
2019-10-11 23:00:12 +02:00
Carlos Garnacho
dd2b1278a0 wayland: Chain up to the right finalize on MetaWaylandDataSourceWayland
This function was using the wrong parent class pointer, so it was mistakenly
skipping over MetaWaylandDataSource::finalize.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/848
2019-10-11 23:00:12 +02:00
Carlos Garnacho
f2e2fcf758 wayland: Drop field from MetaWaylandDataSourcePrimary
This is a subclass of MetaWaylandDataSourceWayland, so there's no need
for a duplicate wl_resource field. Make sure to reuse the parent struct
one.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/848
2019-10-11 23:00:12 +02:00
Carlos Garnacho
dfd44ff971 wayland: Plug MetaSelectionSourceWayland leaks
There was a dangling ref left on all of them, oops.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/848
2019-10-11 23:00:12 +02:00
Georges Basile Stavracas Neto
943b069996 clutter/shader-effect: Initialize shader-type properly
The default value of the ClutterShaderEffect:shader-type
property is CLUTTER_FRAGMENT_SHADER. However, because the
struct field is not actually initialized to it, it ends
up assuming the value 0, which is CLUTTER_VERTEX_SHADER.

Properly initialize ClutterShaderEffect's shader_type to
CLUTTER_FRAGMENT_SHADER.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/846
2019-10-11 10:53:33 -03:00
Jonas Ådahl
2a56de80a2 ci: Change the without-native-backend to not build with Wayland too
There are two common ways of building mutter: With both the native
backend and Wayland support (most common, used by most Linux distributions), and
without the native backend and Wayland support (as is done by some
BSD*s).

To catch compilation errors in both these common build configurations,
change the no-native-backend build phase to also not build with Wayland
support.

This also disables building mutter tests, as tests depend on Wayland to
run.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/837
2019-10-10 22:51:00 +00:00
Jonas Ådahl
69a0c1dc80 main: Warn instead of error in meta_test_init()
Otherwise we'll get the warning

../src/core/main.c: In function 'meta_test_init':
../src/core/main.c:755:1: error: function might be candidate for attribute 'noreturn' [-Werror=suggest-attribute=noreturn]
  755 | meta_test_init (void)
      | ^~~~~~~~~~~~~~

when building without Wayland.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/837
2019-10-10 22:51:00 +00:00
Jonas Ådahl
1b4709794e kms/crtc: Read gamma state when prediction failed
If we did a mode set, the gamma may have been changed by the kernel, and
if we didn't also update the gamma in the same transaction, we have no
way to predict the current gamma ramp state. In this case, read the
gamma state directly from KMS.

This should be relatively harmless regarding the race conditions the
state prediction was meant to solve, as the worst case is we get none or
out of date gamma ramps; and since this is for when gamma ramps are not
updated at mode setting time, we'd get intermediate gamma state to begin
with, so it's not worse than what we currently do anyway.

Fixes: https://gitlab.gnome.org/GNOME/mutter/issues/851

https://gitlab.gnome.org/GNOME/mutter/merge_requests/840
2019-10-10 14:46:32 +00:00
Jonas Ådahl
1cc249fe18 kms: Always predict state after processing update
Not only mode sets have state that should be predicted; changing gamma
currently happens with its own update, so we missed predicting that.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/840
2019-10-10 14:46:32 +00:00
Marco Trevisan (Treviño)
446bd04b6c clutter-backend-x11: Don't push keymap events to clutter
Xkb events should be handled by clutter backend but they are not translated
into an actual clutter event. However we're now handling them and also trying
to push an empty event to clutter queue, causing a critical error.

So in such case, just handle the native event but don't push the non-populated
clutter-event to the queue.

Fixes https://gitlab.gnome.org/GNOME/mutter/issues/750
https://gitlab.gnome.org/GNOME/mutter/merge_requests/764
2019-10-10 13:00:02 +00:00
Marco Trevisan (Treviño)
9234fcb624 event-x11: Use CLUTTER prefix for X11 filter docs
As per commit ad72fa46b clutter_x11_handle_event was renamed into
meta_x11_handle_event but the return type didn't change.

So, keep the doc-string to match the actual possible return values.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/764
2019-10-10 13:00:02 +00:00
Carlos Garnacho
59a697f773 x11: Translate well known selection atoms to mimetypes
Some antediluvian x11 clients only bother to set atoms like
UTF8_STRING/STRING/TEXT/... and no matching mimetypes. Cover for them
and add the well known mimetypes if they are missing.

Reported at https://bugzilla.redhat.com/show_bug.cgi?id=1758873

https://gitlab.gnome.org/GNOME/mutter/merge_requests/842
2019-10-10 12:13:46 +00:00
Jonas Ådahl
d49d10b14f wayland/actor-surface: Queue redraw for frame callback
A frame callback without damage is still expected to be responded to.
Implement this by simply queuing damage if there are any frame callbacks
requested and there is no damage yet. If there already is damage,
we'll be queued already, but with more correct damage. Without we simply
need to make sure we flush the callbacks if any area of surface is not
occluded.

Fixes: https://gitlab.gnome.org/GNOME/mutter/issues/457

https://gitlab.gnome.org/GNOME/mutter/merge_requests/839
2019-10-10 10:01:05 +00:00
Jonas Ådahl
4c15d32b55 wayland/surface: Some minor coding style clean up
Some very long lines that were split up.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/839
2019-10-10 10:01:05 +00:00
Daniel van Vugt
73eaf51770 cogl-pango/meson.build: Remove extraneous quoting
It wasn't necessary (see other instances of -DG_LOG_DOMAIN) and somewhere
along the line it was getting turned into forward slashes becoming a syntax
error:

```
/usr/include/glib-2.0/gobject/gobject.h:767: syntax error, unexpected '/' in
...
g_assertion_message (/"CoglPango/",
```

https://gitlab.gnome.org/GNOME/mutter/merge_requests/841
2019-10-10 17:29:44 +08:00
Tim Klocke
81ee8886ce backends: Update inhibited state for the monitor and respect that state
The inhibited state of the monitor was after the initializiation never
updated. meta_idle_monitor_reset_idletime didn't respect the inhibited
state, so it set timeouts if it shouldn't have.

Fixes: https://gitlab.gnome.org/GNOME/mutter/issues/573
2019-10-09 09:53:32 +00:00
21 changed files with 217 additions and 143 deletions

View File

@@ -28,10 +28,10 @@ build-mutter:
- merge_requests
- /^.*$/
build-without-native-backend:
build-without-native-backend-and-wayland:
stage: build
script:
- meson . build -Dbuildtype=debugoptimized -Dnative_backend=false -Dudev=false --werror --prefix /usr
- meson . build -Dbuildtype=debugoptimized -Dnative_backend=false -Dudev=false -Dwayland=false -Dcore_tests=false --werror --prefix /usr
- ninja -C build
- ninja -C build install
artifacts:

15
NEWS
View File

@@ -1,3 +1,18 @@
3.35.1
======
* Fix immediate screen blank after releaseing inhibitor [Tim; #573]
* Respond to frame callbacks regardless of damage [Jonas; !839]
* selection [Carlos; !842]
* Fix Night Light on wayland [Jonas; !840]
* Fix various copy+paste/DND regressions [Carlos; !848, #789, #842,
#793, #845, #854]
* Misc. bug fixes and cleanups [Daniel, Marco, Jonas, Georges;
!841, !764, !837, !846]
Contributors:
Marco Trevisan (Treviño), Carlos Garnacho, Tim Klocke,
Georges Basile Stavracas Neto, Daniel van Vugt, Jonas Ådahl
3.34.1
======
* Fix startup of X11 session services on wayland [Carlos; #771]

View File

@@ -500,6 +500,7 @@ static void
clutter_shader_effect_init (ClutterShaderEffect *effect)
{
effect->priv = clutter_shader_effect_get_instance_private (effect);
effect->priv->shader_type = CLUTTER_FRAGMENT_SHADER;
}
/**

View File

@@ -62,7 +62,7 @@ if have_introspection
],
extra_args: introspection_args + [
'-UCOGL_COMPILATION',
'-DG_LOG_DOMAIN=\"CoglPango\"',
'-DG_LOG_DOMAIN="CoglPango"',
],
install_dir_gir: pkglibdir,
install_dir_typelib: pkglibdir,

View File

@@ -1,5 +1,5 @@
project('mutter', 'c',
version: '3.34.1',
version: '3.35.1',
meson_version: '>= 0.50.0',
license: 'GPLv2+'
)

View File

@@ -207,6 +207,8 @@ update_inhibited (MetaIdleMonitor *monitor,
if (inhibited == monitor->inhibited)
return;
monitor->inhibited = inhibited;
g_hash_table_foreach (monitor->watches,
update_inhibited_watch,
monitor);
@@ -516,9 +518,16 @@ meta_idle_monitor_reset_idletime (MetaIdleMonitor *monitor)
}
else
{
g_source_set_ready_time (watch->timeout_source,
monitor->last_event_time +
watch->timeout_msec * 1000);
if (monitor->inhibited)
{
g_source_set_ready_time (watch->timeout_source, -1);
}
else
{
g_source_set_ready_time (watch->timeout_source,
monitor->last_event_time +
watch->timeout_msec * 1000);
}
}
}

View File

@@ -143,14 +143,26 @@ meta_kms_crtc_update_state (MetaKmsCrtc *crtc)
drmModeFreeCrtc (drm_crtc);
}
static void
clear_gamma_state (MetaKmsCrtc *crtc)
{
crtc->current_state.gamma.size = 0;
g_clear_pointer (&crtc->current_state.gamma.red, g_free);
g_clear_pointer (&crtc->current_state.gamma.green, g_free);
g_clear_pointer (&crtc->current_state.gamma.blue, g_free);
}
void
meta_kms_crtc_predict_state (MetaKmsCrtc *crtc,
MetaKmsUpdate *update)
{
gboolean is_gamma_valid;
GList *mode_sets;
GList *crtc_gammas;
GList *l;
is_gamma_valid = TRUE;
mode_sets = meta_kms_update_get_mode_sets (update);
for (l = mode_sets; l; l = l->next)
{
@@ -178,6 +190,8 @@ meta_kms_crtc_predict_state (MetaKmsCrtc *crtc,
crtc->current_state.drm_mode = (drmModeModeInfo) { 0 };
}
is_gamma_valid = FALSE;
break;
}
@@ -196,8 +210,36 @@ meta_kms_crtc_predict_state (MetaKmsCrtc *crtc,
g_memdup (gamma->green, gamma->size * sizeof (uint16_t));
crtc->current_state.gamma.blue =
g_memdup (gamma->blue, gamma->size * sizeof (uint16_t));
is_gamma_valid = TRUE;
break;
}
if (!is_gamma_valid)
{
if (crtc->current_state.is_drm_mode_valid)
{
MetaKmsImplDevice *impl_device;
drmModeCrtc *drm_crtc;
impl_device = meta_kms_device_get_impl_device (crtc->device);
drm_crtc = drmModeGetCrtc (meta_kms_impl_device_get_fd (impl_device),
crtc->id);
if (drm_crtc)
{
read_gamma_state (crtc, impl_device, drm_crtc);
drmModeFreeCrtc (drm_crtc);
}
else
{
clear_gamma_state (crtc);
}
}
else
{
clear_gamma_state (crtc);
}
}
}
MetaKmsCrtc *
@@ -220,9 +262,7 @@ meta_kms_crtc_finalize (GObject *object)
{
MetaKmsCrtc *crtc = META_KMS_CRTC (object);
g_clear_pointer (&crtc->current_state.gamma.red, g_free);
g_clear_pointer (&crtc->current_state.gamma.green, g_free);
g_clear_pointer (&crtc->current_state.gamma.blue, g_free);
clear_gamma_state (crtc);
G_OBJECT_CLASS (meta_kms_crtc_parent_class)->finalize (object);
}

View File

@@ -110,6 +110,4 @@ GList * meta_kms_update_get_connector_properties (MetaKmsUpdate *update);
GList * meta_kms_update_get_crtc_gammas (MetaKmsUpdate *update);
gboolean meta_kms_update_has_mode_set (MetaKmsUpdate *update);
#endif /* META_KMS_UPDATE_PRIVATE_H */

View File

@@ -282,12 +282,6 @@ meta_kms_update_get_crtc_gammas (MetaKmsUpdate *update)
return update->crtc_gammas;
}
gboolean
meta_kms_update_has_mode_set (MetaKmsUpdate *update)
{
return !!update->mode_sets;
}
void
meta_kms_update_seal (MetaKmsUpdate *update)
{

View File

@@ -211,8 +211,7 @@ meta_kms_update_process_in_impl (MetaKmsImpl *impl,
ret = meta_kms_impl_process_update (impl, update, error);
if (meta_kms_update_has_mode_set (update))
meta_kms_predict_states_in_impl (meta_kms_impl_get_kms (impl), update);
meta_kms_predict_states_in_impl (meta_kms_impl_get_kms (impl), update);
return ret;
}

View File

@@ -129,7 +129,7 @@ meta_clutter_backend_x11_translate_event (ClutterBackend *backend,
return TRUE;
if (meta_keymap_x11_handle_event (backend_x11->keymap, native))
return TRUE;
return FALSE;
stage_x11 = META_STAGE_X11 (clutter_backend_get_stage_window (backend));
if (meta_stage_x11_translate_event (stage_x11, native, event))

View File

@@ -82,12 +82,12 @@ meta_x11_handle_event (XEvent *xevent)
gboolean allocated_event;
/* The return values here are someone approximate; we return
* META_X11_FILTER_REMOVE if a clutter event is
* CLUTTER_X11_FILTER_REMOVE if a clutter event is
* generated for the event. This mostly, but not entirely,
* corresponds to whether other event processing should be
* excluded. As long as the stage window is not shared with another
* toolkit it should be safe, and never return
* %META_X11_FILTER_REMOVE when more processing is needed.
* %CLUTTER_X11_FILTER_REMOVE when more processing is needed.
*/
result = CLUTTER_X11_FILTER_CONTINUE;

View File

@@ -766,6 +766,6 @@ meta_test_init (void)
close (fd);
#else
g_error ("Tests require wayland support");
g_warning ("Tests require wayland support");
#endif
}

View File

@@ -76,6 +76,9 @@ meta_selection_source_memory_get_mimetypes (MetaSelectionSource *source)
{
MetaSelectionSourceMemory *source_mem = META_SELECTION_SOURCE_MEMORY (source);
if (!source_mem->mimetype)
return NULL;
return g_list_prepend (NULL, g_strdup (source_mem->mimetype));
}
@@ -84,7 +87,7 @@ meta_selection_source_memory_finalize (GObject *object)
{
MetaSelectionSourceMemory *source_mem = META_SELECTION_SOURCE_MEMORY (object);
g_bytes_unref (source_mem->content);
g_clear_pointer (&source_mem->content, g_bytes_unref);
g_free (source_mem->mimetype);
G_OBJECT_CLASS (meta_selection_source_memory_parent_class)->finalize (object);

View File

@@ -25,6 +25,8 @@
#include <wayland-server.h>
#include "meta/meta-selection-source.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 ())
@@ -33,14 +35,6 @@ G_DECLARE_FINAL_TYPE (MetaSelectionSourceWayland,
META, SELECTION_SOURCE_WAYLAND,
MetaSelectionSource)
typedef void (* MetaWaylandSendFunc) (struct wl_resource *resource,
const char *mimetype,
int fd);
typedef void (* MetaWaylandCancelFunc) (struct wl_resource *resource);
MetaSelectionSource * meta_selection_source_wayland_new (struct wl_resource *resource,
GList *mime_types,
MetaWaylandSendFunc send_func,
MetaWaylandCancelFunc cancel_func);
MetaSelectionSource * meta_selection_source_wayland_new (MetaWaylandDataSource *source);
#endif /* META_SELECTION_SOURCE_WAYLAND_H */

View File

@@ -29,10 +29,8 @@
struct _MetaSelectionSourceWayland
{
MetaSelectionSource parent_instance;
MetaWaylandDataSource *data_source;
GList *mimetypes;
MetaWaylandSendFunc send_func;
MetaWaylandCancelFunc cancel_func;
struct wl_resource *resource;
};
G_DEFINE_TYPE (MetaSelectionSourceWayland, meta_selection_source_wayland,
@@ -85,7 +83,8 @@ meta_selection_source_wayland_read_async (MetaSelectionSource *source,
g_task_set_source_tag (task, meta_selection_source_wayland_read_async);
stream = g_unix_input_stream_new (pipe_fds[0], TRUE);
source_wayland->send_func (source_wayland->resource, mimetype, pipe_fds[1]);
meta_wayland_data_source_send (source_wayland->data_source,
mimetype, pipe_fds[1]);
close (pipe_fds[1]);
g_task_return_pointer (task, stream, g_object_unref);
@@ -119,7 +118,7 @@ meta_selection_source_wayland_deactivated (MetaSelectionSource *source)
MetaSelectionSourceWayland *source_wayland =
META_SELECTION_SOURCE_WAYLAND (source);
source_wayland->cancel_func (source_wayland->resource);
meta_wayland_data_source_cancel (source_wayland->data_source);
META_SELECTION_SOURCE_CLASS (meta_selection_source_wayland_parent_class)->deactivated (source);
}
@@ -143,20 +142,29 @@ meta_selection_source_wayland_init (MetaSelectionSourceWayland *source)
{
}
static GList *
copy_string_array_to_list (struct wl_array *array)
{
GList *l = NULL;
char **p;
wl_array_for_each (p, array)
l = g_list_prepend (l, g_strdup (*p));
return l;
}
MetaSelectionSource *
meta_selection_source_wayland_new (struct wl_resource *resource,
GList *mime_types,
MetaWaylandSendFunc send_func,
MetaWaylandCancelFunc cancel_func)
meta_selection_source_wayland_new (MetaWaylandDataSource *data_source)
{
MetaSelectionSourceWayland *source_wayland;
struct wl_array *mimetypes;
source_wayland = g_object_new (META_TYPE_SELECTION_SOURCE_WAYLAND, NULL);
source_wayland->mimetypes = g_list_copy_deep (mime_types,
(GCopyFunc) g_strdup, NULL);
source_wayland->send_func = send_func;
source_wayland->cancel_func = cancel_func;
source_wayland->resource = resource;
source_wayland->data_source = data_source;
mimetypes = meta_wayland_data_source_get_mime_types (data_source);
source_wayland->mimetypes = copy_string_array_to_list (mimetypes);
return META_SELECTION_SOURCE (source_wayland);
}

View File

@@ -241,6 +241,11 @@ meta_wayland_actor_surface_commit (MetaWaylandSurfaceRole *surface_role,
if (!priv->actor)
return;
if (!wl_list_empty (&pending->frame_callback_list) &&
cairo_region_is_empty (pending->surface_damage) &&
cairo_region_is_empty (pending->buffer_damage))
clutter_actor_queue_redraw (CLUTTER_ACTOR (priv->actor));
meta_wayland_actor_surface_queue_frame_callbacks (actor_surface, pending);
meta_wayland_actor_surface_sync_actor_state (actor_surface);

View File

@@ -36,6 +36,7 @@
#include <unistd.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-dnd-surface.h"
#include "wayland/meta-wayland-pointer.h"
@@ -59,6 +60,7 @@ struct _MetaWaylandDataOffer
gboolean action_sent;
uint32_t dnd_actions;
enum wl_data_device_manager_dnd_action preferred_dnd_action;
MetaSelectionType selection_type;
};
typedef struct _MetaWaylandDataSourcePrivate
@@ -84,8 +86,6 @@ typedef struct _MetaWaylandDataSourceWayland
typedef struct _MetaWaylandDataSourcePrimary
{
MetaWaylandDataSourceWayland parent;
struct wl_resource *resource;
} MetaWaylandDataSourcePrimary;
G_DEFINE_TYPE_WITH_PRIVATE (MetaWaylandDataSource, meta_wayland_data_source,
@@ -252,7 +252,7 @@ meta_wayland_data_source_get_mime_types (const MetaWaylandDataSource *source)
return &priv->mime_types;
}
static void
void
meta_wayland_data_source_cancel (MetaWaylandDataSource *source)
{
META_WAYLAND_DATA_SOURCE_GET_CLASS (source)->cancel (source);
@@ -400,11 +400,7 @@ data_offer_receive (struct wl_client *client, struct wl_resource *resource,
GList *mime_types;
gboolean found;
if (offer->dnd_actions != 0)
selection_type = META_SELECTION_DND;
else
selection_type = META_SELECTION_CLIPBOARD;
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;
@@ -623,6 +619,7 @@ create_and_send_dnd_offer (MetaWaylandDataSource *source,
MetaWaylandDataOffer *offer = g_slice_new0 (MetaWaylandDataOffer);
char **p;
offer->selection_type = META_SELECTION_DND;
offer->source = source;
g_object_add_weak_pointer (G_OBJECT (source), (gpointer *)&offer->source);
offer->resource = wl_resource_create (wl_resource_get_client (target),
@@ -1154,18 +1151,6 @@ destroy_data_device_icon (struct wl_listener *listener, void *data)
clutter_actor_remove_all_children (drag_grab->feedback_actor);
}
static GList *
copy_string_array_to_list (struct wl_array *array)
{
GList *l = NULL;
char **p;
wl_array_for_each (p, array)
l = g_list_prepend (l, g_strdup (*p));
return l;
}
void
meta_wayland_data_device_start_drag (MetaWaylandDataDevice *data_device,
struct wl_client *client,
@@ -1265,7 +1250,6 @@ data_device_start_drag (struct wl_client *client,
MetaWaylandSurface *surface = NULL, *icon_surface = NULL;
MetaWaylandDataSource *drag_source = NULL;
MetaSelectionSource *selection_source;
GList *mimetypes;
if (origin_resource)
surface = wl_resource_get_user_data (origin_resource);
@@ -1301,14 +1285,10 @@ data_device_start_drag (struct wl_client *client,
return;
}
mimetypes = copy_string_array_to_list (meta_wayland_data_source_get_mime_types (drag_source));
selection_source = meta_selection_source_wayland_new (source_resource,
mimetypes,
wl_data_source_send_send,
wl_data_source_send_cancelled);
g_list_free_full (mimetypes, g_free);
selection_source = meta_selection_source_wayland_new (drag_source);
set_selection_source (data_device, META_SELECTION_DND,
selection_source);
g_object_unref (selection_source);
meta_wayland_pointer_set_focus (seat->pointer, NULL);
meta_wayland_data_device_start_drag (data_device, client,
@@ -1370,7 +1350,8 @@ meta_wayland_source_cancel (MetaWaylandDataSource *source)
MetaWaylandDataSourceWayland *source_wayland =
META_WAYLAND_DATA_SOURCE_WAYLAND (source);
wl_data_source_send_cancelled (source_wayland->resource);
if (source_wayland->resource)
wl_data_source_send_cancelled (source_wayland->resource);
}
static void
@@ -1421,7 +1402,7 @@ meta_wayland_source_drag_finished (MetaWaylandDataSource *source)
static void
meta_wayland_source_finalize (GObject *object)
{
G_OBJECT_CLASS (meta_wayland_data_source_parent_class)->finalize (object);
G_OBJECT_CLASS (meta_wayland_data_source_wayland_parent_class)->finalize (object);
}
static void
@@ -1451,10 +1432,10 @@ meta_wayland_data_source_primary_send (MetaWaylandDataSource *source,
const gchar *mime_type,
gint fd)
{
MetaWaylandDataSourcePrimary *source_primary;
MetaWaylandDataSourceWayland *source_wayland;
source_primary = META_WAYLAND_DATA_SOURCE_PRIMARY (source);
gtk_primary_selection_source_send_send (source_primary->resource,
source_wayland = META_WAYLAND_DATA_SOURCE_WAYLAND (source);
gtk_primary_selection_source_send_send (source_wayland->resource,
mime_type, fd);
close (fd);
}
@@ -1462,10 +1443,11 @@ meta_wayland_data_source_primary_send (MetaWaylandDataSource *source,
static void
meta_wayland_data_source_primary_cancel (MetaWaylandDataSource *source)
{
MetaWaylandDataSourcePrimary *source_primary;
MetaWaylandDataSourceWayland *source_wayland;
source_primary = META_WAYLAND_DATA_SOURCE_PRIMARY (source);
gtk_primary_selection_source_send_cancelled (source_primary->resource);
source_wayland = META_WAYLAND_DATA_SOURCE_WAYLAND (source);
if (source_wayland->resource)
gtk_primary_selection_source_send_cancelled (source_wayland->resource);
}
static void
@@ -1644,6 +1626,7 @@ meta_wayland_data_device_set_selection (MetaWaylandDataDevice *data_device,
MetaWaylandSeat *seat = wl_container_of (data_device, seat, data_device);
struct wl_resource *data_device_resource;
struct wl_client *focus_client;
MetaSelectionSource *selection_source;
if (data_device->selection_data_source &&
data_device->selection_serial - serial < UINT32_MAX / 2)
@@ -1661,6 +1644,24 @@ meta_wayland_data_device_set_selection (MetaWaylandDataDevice *data_device,
data_device->selection_data_source = source;
data_device->selection_serial = serial;
if (source)
{
meta_wayland_data_source_set_seat (source, seat);
g_object_weak_ref (G_OBJECT (source),
selection_data_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, META_SELECTION_CLIPBOARD,
selection_source);
g_object_unref (selection_source);
focus_client = meta_wayland_keyboard_get_focus_client (seat->keyboard);
if (focus_client)
{
@@ -1673,33 +1674,6 @@ meta_wayland_data_device_set_selection (MetaWaylandDataDevice *data_device,
}
}
if (source)
{
MetaWaylandDataSourceWayland *source_wayland =
META_WAYLAND_DATA_SOURCE_WAYLAND (source);
MetaSelectionSource *selection_source;
GList *mimetypes;
meta_wayland_data_source_set_seat (source, seat);
g_object_weak_ref (G_OBJECT (source),
selection_data_source_destroyed,
data_device);
mimetypes = copy_string_array_to_list (meta_wayland_data_source_get_mime_types (source));
selection_source = meta_selection_source_wayland_new (source_wayland->resource,
mimetypes,
wl_data_source_send_send,
wl_data_source_send_cancelled);
g_list_free_full (mimetypes, g_free);
set_selection_source (data_device, META_SELECTION_CLIPBOARD,
selection_source);
}
else
{
unset_selection_source (data_device, META_SELECTION_CLIPBOARD);
}
wl_signal_emit (&data_device->selection_ownership_signal, source);
}
@@ -1773,12 +1747,13 @@ meta_wayland_data_device_set_primary (MetaWaylandDataDevice *data_device,
MetaWaylandSeat *seat = wl_container_of (data_device, seat, data_device);
struct wl_resource *data_device_resource;
struct wl_client *focus_client;
MetaSelectionSource *selection_source;
if (META_IS_WAYLAND_DATA_SOURCE_PRIMARY (source))
{
struct wl_resource *resource;
resource = META_WAYLAND_DATA_SOURCE_PRIMARY (source)->resource;
resource = META_WAYLAND_DATA_SOURCE_WAYLAND (source)->resource;
if (wl_resource_get_client (resource) !=
meta_wayland_keyboard_get_focus_client (seat->keyboard))
@@ -1800,6 +1775,24 @@ meta_wayland_data_device_set_primary (MetaWaylandDataDevice *data_device,
data_device->primary_data_source = source;
data_device->primary_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, META_SELECTION_PRIMARY,
selection_source);
g_object_unref (selection_source);
focus_client = meta_wayland_keyboard_get_focus_client (seat->keyboard);
if (focus_client)
{
@@ -1812,31 +1805,6 @@ meta_wayland_data_device_set_primary (MetaWaylandDataDevice *data_device,
}
}
if (source)
{
MetaSelectionSource *selection_source;
GList *mimetypes;
meta_wayland_data_source_set_seat (source, seat);
g_object_weak_ref (G_OBJECT (source),
primary_source_destroyed,
data_device);
mimetypes = copy_string_array_to_list (meta_wayland_data_source_get_mime_types (source));
selection_source = meta_selection_source_wayland_new (META_WAYLAND_DATA_SOURCE_PRIMARY (source)->resource,
mimetypes,
gtk_primary_selection_source_send_send,
gtk_primary_selection_source_send_cancelled);
g_list_free_full (mimetypes, g_free);
set_selection_source (data_device, META_SELECTION_PRIMARY,
selection_source);
}
else
{
unset_selection_source (data_device, META_SELECTION_PRIMARY);
}
wl_signal_emit (&data_device->primary_ownership_signal, source);
}
@@ -1968,7 +1936,7 @@ static const struct wl_data_device_manager_interface manager_interface = {
static void
destroy_primary_source (struct wl_resource *resource)
{
MetaWaylandDataSourcePrimary *source = wl_resource_get_user_data (resource);
MetaWaylandDataSourceWayland *source = wl_resource_get_user_data (resource);
source->resource = NULL;
g_object_unref (source);
@@ -2073,6 +2041,7 @@ create_and_send_clipboard_offer (MetaWaylandDataDevice *data_device,
return NULL;
offer = g_slice_new0 (MetaWaylandDataOffer);
offer->selection_type = META_SELECTION_CLIPBOARD;
offer->resource = wl_resource_create (wl_resource_get_client (target),
&wl_data_offer_interface,
wl_resource_get_version (target), 0);
@@ -2105,6 +2074,7 @@ create_and_send_primary_offer (MetaWaylandDataDevice *data_device,
return NULL;
offer = g_slice_new0 (MetaWaylandDataOffer);
offer->selection_type = META_SELECTION_PRIMARY;
offer->resource = wl_resource_create (wl_resource_get_client (target),
&gtk_primary_selection_offer_interface,
wl_resource_get_version (target), 0);
@@ -2204,7 +2174,7 @@ meta_wayland_data_source_wayland_new (struct wl_resource *resource)
static MetaWaylandDataSource *
meta_wayland_data_source_primary_new (struct wl_resource *resource)
{
MetaWaylandDataSourcePrimary *source_primary =
MetaWaylandDataSourceWayland *source_primary =
g_object_new (META_TYPE_WAYLAND_DATA_SOURCE_PRIMARY, NULL);
source_primary->resource = resource;

View File

@@ -111,6 +111,8 @@ 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);

View File

@@ -972,8 +972,12 @@ wl_surface_frame (struct wl_client *client,
callback = g_slice_new0 (MetaWaylandFrameCallback);
callback->surface = surface;
callback->resource = wl_resource_create (client, &wl_callback_interface, META_WL_CALLBACK_VERSION, callback_id);
wl_resource_set_implementation (callback->resource, NULL, callback, destroy_frame_callback);
callback->resource = wl_resource_create (client,
&wl_callback_interface,
META_WL_CALLBACK_VERSION,
callback_id);
wl_resource_set_implementation (callback->resource, NULL, callback,
destroy_frame_callback);
wl_list_insert (surface->pending->frame_callback_list.prev, &callback->link);
}
@@ -1370,7 +1374,9 @@ wl_surface_destructor (struct wl_resource *resource)
meta_wayland_compositor_destroy_frame_callbacks (compositor, surface);
g_hash_table_foreach (surface->outputs_to_destroy_notify_id, surface_output_disconnect_signal, surface);
g_hash_table_foreach (surface->outputs_to_destroy_notify_id,
surface_output_disconnect_signal,
surface);
g_hash_table_unref (surface->outputs_to_destroy_notify_id);
wl_list_for_each_safe (cb, next, &surface->pending_frame_callback_list, link)
@@ -1419,12 +1425,20 @@ meta_wayland_surface_create (MetaWaylandCompositor *compositor,
guint32 id)
{
MetaWaylandSurface *surface = g_object_new (META_TYPE_WAYLAND_SURFACE, NULL);
int surface_version;
surface->compositor = compositor;
surface->scale = 1;
surface->resource = wl_resource_create (client, &wl_surface_interface, wl_resource_get_version (compositor_resource), id);
wl_resource_set_implementation (surface->resource, &meta_wayland_wl_surface_interface, surface, wl_surface_destructor);
surface_version = wl_resource_get_version (compositor_resource);
surface->resource = wl_resource_create (client,
&wl_surface_interface,
surface_version,
id);
wl_resource_set_implementation (surface->resource,
&meta_wayland_wl_surface_interface,
surface,
wl_surface_destructor);
wl_list_init (&surface->pending_frame_callback_list);

View File

@@ -82,6 +82,15 @@ meta_selection_source_x11_read_async (MetaSelectionSource *source,
task = g_task_new (source, cancellable, callback, user_data);
g_task_set_source_tag (task, meta_selection_source_x11_read_async);
if (strcmp (mimetype, "text/plain") == 0 &&
g_list_find_custom (source_x11->mimetypes, "STRING",
(GCompareFunc) g_strcmp0))
mimetype = "STRING";
else if (strcmp (mimetype, "text/plain;charset=utf-8") == 0 &&
g_list_find_custom (source_x11->mimetypes, "UTF8_STRING",
(GCompareFunc) g_strcmp0))
mimetype = "UTF8_STRING";
meta_x11_selection_input_stream_new_async (source_x11->x11_display,
source_x11->x11_display->selection.xwindow,
gdk_x11_get_xatom_name (source_x11->xselection),
@@ -139,6 +148,8 @@ atoms_to_mimetypes (MetaX11Display *display,
const Atom *atoms;
gsize size;
guint i, n_atoms;
gboolean utf8_string_found = FALSE, utf8_text_plain_found = FALSE;
gboolean string_found = FALSE, text_plain_found = FALSE;
atoms = g_bytes_get_data (bytes, &size);
n_atoms = size / sizeof (Atom);
@@ -149,8 +160,19 @@ atoms_to_mimetypes (MetaX11Display *display,
mimetype = gdk_x11_get_xatom_name (atoms[i]);
mimetypes = g_list_prepend (mimetypes, g_strdup (mimetype));
utf8_text_plain_found |= strcmp (mimetype, "text/plain;charset=utf-8") == 0;
text_plain_found |= strcmp (mimetype, "text/plain") == 0;
utf8_string_found |= strcmp (mimetype, "UTF8_STRING") == 0;
string_found |= strcmp (mimetype, "STRING") == 0;
}
/* Ensure non-x11 clients get well-known mimetypes */
if (string_found && !text_plain_found)
mimetypes = g_list_prepend (mimetypes, g_strdup ("text/plain"));
if (utf8_string_found && !utf8_text_plain_found)
mimetypes = g_list_prepend (mimetypes, g_strdup ("text/plain;charset=utf-8"));
return mimetypes;
}