Marco Trevisan (Treviño) has proposed merging ~3v1n0/ubuntu/+source/mutter:ubuntu/master into ~ubuntu-desktop/ubuntu/+source/mutter:ubuntu/master.
Requested reviews: Ubuntu Desktop (ubuntu-desktop) For more details, see: https://code.launchpad.net/~3v1n0/ubuntu/+source/mutter/+git/mutter/+merge/374693 -- Your team Ubuntu Desktop is requested to review the proposed merge of ~3v1n0/ubuntu/+source/mutter:ubuntu/master into ~ubuntu-desktop/ubuntu/+source/mutter:ubuntu/master.
diff --git a/clutter/clutter/clutter-actor-private.h b/clutter/clutter/clutter-actor-private.h index 119ec42..fa2d4c3 100644 --- a/clutter/clutter/clutter-actor-private.h +++ b/clutter/clutter/clutter-actor-private.h @@ -274,6 +274,9 @@ void _clutter_actor_set_enable_paint_unmapped void _clutter_actor_set_has_pointer (ClutterActor *self, gboolean has_pointer); +void _clutter_actor_set_has_key_focus (ClutterActor *self, + gboolean has_key_focus); + void _clutter_actor_queue_redraw_with_clip (ClutterActor *self, ClutterRedrawFlags flags, const ClutterPaintVolume *clip_volume); diff --git a/clutter/clutter/clutter-actor.c b/clutter/clutter/clutter-actor.c index e763291..ecf9a59 100644 --- a/clutter/clutter/clutter-actor.c +++ b/clutter/clutter/clutter-actor.c @@ -835,6 +835,7 @@ struct _ClutterActorPrivate guint enable_model_view_transform : 1; guint enable_paint_unmapped : 1; guint has_pointer : 1; + guint has_key_focus : 1; guint propagated_one_redraw : 1; guint paint_volume_valid : 1; guint last_paint_volume_valid : 1; @@ -1692,6 +1693,20 @@ clutter_actor_is_mapped (ClutterActor *self) } static void +maybe_unset_key_focus (ClutterActor *self) +{ + ClutterActor *stage; + + if (!self->priv->has_key_focus) + return; + + stage = _clutter_actor_get_stage_internal (self); + + if (stage) + clutter_stage_set_key_focus (CLUTTER_STAGE (stage), NULL); +} + +static void clutter_actor_real_unmap (ClutterActor *self) { ClutterActorPrivate *priv = self->priv; @@ -1724,17 +1739,7 @@ clutter_actor_real_unmap (ClutterActor *self) /* relinquish keyboard focus if we were unmapped while owning it */ if (!CLUTTER_ACTOR_IS_TOPLEVEL (self)) - { - ClutterStage *stage; - - stage = CLUTTER_STAGE (_clutter_actor_get_stage_internal (self)); - - if (stage != NULL && - clutter_stage_get_key_focus (stage) == self) - { - clutter_stage_set_key_focus (stage, NULL); - } - } + maybe_unset_key_focus (self); } /** @@ -6064,6 +6069,8 @@ clutter_actor_dispose (GObject *object) object->ref_count, g_type_name (G_OBJECT_TYPE (self))); + maybe_unset_key_focus (self); + /* Stop the emission of any property change */ g_object_freeze_notify (object); @@ -15979,6 +15986,9 @@ clutter_actor_grab_key_focus (ClutterActor *self) g_return_if_fail (CLUTTER_IS_ACTOR (self)); + if (self->priv->has_key_focus) + return; + stage = _clutter_actor_get_stage_internal (self); if (stage != NULL) clutter_stage_set_key_focus (CLUTTER_STAGE (stage), self); @@ -16768,6 +16778,23 @@ _clutter_actor_set_has_pointer (ClutterActor *self, } } +void +_clutter_actor_set_has_key_focus (ClutterActor *self, + gboolean has_key_focus) +{ + ClutterActorPrivate *priv = self->priv; + + if (priv->has_key_focus != has_key_focus) + { + priv->has_key_focus = has_key_focus; + + if (has_key_focus) + g_signal_emit (self, actor_signals[KEY_FOCUS_IN], 0); + else + g_signal_emit (self, actor_signals[KEY_FOCUS_OUT], 0); + } +} + /** * clutter_actor_get_text_direction: * @self: a #ClutterActor @@ -17616,15 +17643,9 @@ clutter_actor_clear_effects (ClutterActor *self) gboolean clutter_actor_has_key_focus (ClutterActor *self) { - ClutterActor *stage; - g_return_val_if_fail (CLUTTER_IS_ACTOR (self), FALSE); - stage = _clutter_actor_get_stage_internal (self); - if (stage == NULL) - return FALSE; - - return clutter_stage_get_key_focus (CLUTTER_STAGE (stage)) == self; + return self->priv->has_key_focus; } static gboolean diff --git a/clutter/clutter/clutter-shader-effect.c b/clutter/clutter/clutter-shader-effect.c index a5ae1ee..c659dab 100644 --- a/clutter/clutter/clutter-shader-effect.c +++ b/clutter/clutter/clutter-shader-effect.c @@ -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; } /** diff --git a/clutter/clutter/clutter-stage.c b/clutter/clutter/clutter-stage.c index 245cb89..c4b88b3 100644 --- a/clutter/clutter/clutter-stage.c +++ b/clutter/clutter/clutter-stage.c @@ -1066,10 +1066,7 @@ clutter_stage_emit_key_focus_event (ClutterStage *stage, if (priv->key_focused_actor == NULL) return; - if (focus_in) - g_signal_emit_by_name (priv->key_focused_actor, "key-focus-in"); - else - g_signal_emit_by_name (priv->key_focused_actor, "key-focus-out"); + _clutter_actor_set_has_key_focus (CLUTTER_ACTOR (stage), focus_in); g_object_notify_by_pspec (G_OBJECT (stage), obj_props[PROP_KEY_FOCUS]); } @@ -3011,14 +3008,6 @@ clutter_stage_get_title (ClutterStage *stage) return stage->priv->title; } -static void -on_key_focus_destroy (ClutterActor *actor, - ClutterStage *stage) -{ - /* unset the key focus */ - clutter_stage_set_key_focus (stage, NULL); -} - /** * clutter_stage_set_key_focus: * @stage: the #ClutterStage @@ -3058,18 +3047,14 @@ clutter_stage_set_key_focus (ClutterStage *stage, old_focused_actor = priv->key_focused_actor; /* set key_focused_actor to NULL before emitting the signal or someone - * might hide the previously focused actor in the signal handler and we'd - * get re-entrant call and get glib critical from g_object_weak_unref + * might hide the previously focused actor in the signal handler */ - g_signal_handlers_disconnect_by_func (priv->key_focused_actor, - G_CALLBACK (on_key_focus_destroy), - stage); priv->key_focused_actor = NULL; - g_signal_emit_by_name (old_focused_actor, "key-focus-out"); + _clutter_actor_set_has_key_focus (old_focused_actor, FALSE); } else - g_signal_emit_by_name (stage, "key-focus-out"); + _clutter_actor_set_has_key_focus (CLUTTER_ACTOR (stage), FALSE); /* Note, if someone changes key focus in focus-out signal handler we'd be * overriding the latter call below moving the focus where it was originally @@ -3079,14 +3064,10 @@ clutter_stage_set_key_focus (ClutterStage *stage, if (actor != NULL) { priv->key_focused_actor = actor; - - g_signal_connect (actor, - "destroy", G_CALLBACK (on_key_focus_destroy), - stage); - g_signal_emit_by_name (priv->key_focused_actor, "key-focus-in"); + _clutter_actor_set_has_key_focus (actor, TRUE); } else - g_signal_emit_by_name (stage, "key-focus-in"); + _clutter_actor_set_has_key_focus (CLUTTER_ACTOR (stage), TRUE); g_object_notify_by_pspec (G_OBJECT (stage), obj_props[PROP_KEY_FOCUS]); } diff --git a/cogl/cogl-pango/meson.build b/cogl/cogl-pango/meson.build index 787ec01..06fba51 100644 --- a/cogl/cogl-pango/meson.build +++ b/cogl/cogl-pango/meson.build @@ -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, diff --git a/debian/changelog b/debian/changelog index 06847be..2515499 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,34 @@ +mutter (3.34.1+git20191022-1ubuntu19.10.1) UNRELEASED; urgency=medium + + * Merge with debian. Remaining changes: + + debian/control: + - Update VCS flags to point to launchpad + - Update maintainer to ubuntu + + debian/gbp.conf: update branch to point to ubuntu/master + + debian/patches/x11-Add-support-for-fractional-scaling-using-Randr.patch: + - X11: Add support for fractional scaling using Randr + + -- Marco Trevisan (Treviño) <ma...@ubuntu.com> Thu, 24 Oct 2019 03:28:30 +0200 + +mutter (3.34.1+git20191022-1) unstable; urgency=medium + + * New upstream snapshot release + + Fix night mode in wayland session (LP: #1847551) + + Don't emit key-focus-out events on destroyed actors (LP: #1848119) + + Fix an headers syntax error (LP: #1841709) + + backends: Update inhibited state for the monitor and respect that state + + clutter-backend-x11: Don't push keymap events to clutter + + Fix drag and drop for applications in wayland + + Avoid X11 roundtrips on underscanning checks + + -- Marco Trevisan (Treviño) <ma...@ubuntu.com> Wed, 23 Oct 2019 10:53:23 +0100 + +mutter (3.34.1-3) unstable; urgency=medium + + * Bump meson test timeout multiplier from 4 to 6 for armel + + -- Jeremy Bicha <jbi...@debian.org> Sun, 20 Oct 2019 22:48:29 -0400 + mutter (3.34.1-1ubuntu1) eoan; urgency=medium * Merge with debian. Remaining changes: diff --git a/debian/rules b/debian/rules index ce960f4..0a6150b 100755 --- a/debian/rules +++ b/debian/rules @@ -61,7 +61,7 @@ TEST_COMMAND_BASE=env \ XDG_RUNTIME_DIR=$(BUILDDIR)/XRD \ GSETTINGS_SCHEMA_DIR=$(BUILDDIR)/data \ dbus-run-session -- xvfb-run -s '+iglx -noreset' -a \ - meson test -C $(BUILDDIR) --no-rebuild --verbose --timeout-multiplier 4 \ + meson test -C $(BUILDDIR) --no-rebuild --verbose --timeout-multiplier 6 \ --no-stdsplit --print-errorlogs TEST_COMMAND=$(TEST_COMMAND_BASE) --no-suite flaky TEST_COMMAND_FLAKY=$(TEST_COMMAND_BASE) --suite flaky diff --git a/debian/watch b/debian/watch index 35b7b17..d8c6911 100644 --- a/debian/watch +++ b/debian/watch @@ -1,3 +1,3 @@ version=4 -https://download.gnome.org/sources/@PACKAGE@/([\d\.]+)/ \ - @PACKAGE@@ANY_VERSION@\.tar\.xz +https://download.gnome.org/sources/@PACKAGE@/([\d\.]+[02468])/ \ + @PACKAGE@@ANY_VERSION@@ARCHIVE_EXT@ diff --git a/src/backends/meta-dbus-session-watcher.c b/src/backends/meta-dbus-session-watcher.c index 22718e6..a885b42 100644 --- a/src/backends/meta-dbus-session-watcher.c +++ b/src/backends/meta-dbus-session-watcher.c @@ -214,6 +214,8 @@ meta_dbus_session_watcher_finalize (GObject *object) MetaDbusSessionWatcher *session_watcher = META_DBUS_SESSION_WATCHER (object); g_hash_table_destroy (session_watcher->clients); + + G_OBJECT_CLASS (meta_dbus_session_watcher_parent_class)->finalize (object); } static void diff --git a/src/backends/meta-idle-monitor.c b/src/backends/meta-idle-monitor.c index 9fa4817..2ff1602 100644 --- a/src/backends/meta-idle-monitor.c +++ b/src/backends/meta-idle-monitor.c @@ -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); + } } } diff --git a/src/backends/meta-monitor-manager.c b/src/backends/meta-monitor-manager.c index 41036ca..0210aee 100644 --- a/src/backends/meta-monitor-manager.c +++ b/src/backends/meta-monitor-manager.c @@ -1648,6 +1648,7 @@ create_monitor_config_from_variant (MetaMonitorManager *manager, MetaMonitorModeSpec *monitor_mode_spec; g_autoptr (GVariant) properties_variant = NULL; gboolean enable_underscanning = FALSE; + gboolean set_underscanning = FALSE; g_variant_get (monitor_config_variant, "(ss@a{sv})", &connector, @@ -1670,7 +1671,18 @@ create_monitor_config_from_variant (MetaMonitorManager *manager, return NULL; } - g_variant_lookup (properties_variant, "underscanning", "b", &enable_underscanning); + set_underscanning = + g_variant_lookup (properties_variant, "underscanning", "b", + &enable_underscanning); + if (set_underscanning) + { + if (enable_underscanning && !meta_monitor_supports_underscanning (monitor)) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Underscanning requested but unsupported"); + return NULL; + } + } monitor_spec = meta_monitor_spec_clone (meta_monitor_get_spec (monitor)); diff --git a/src/backends/native/meta-kms-crtc.c b/src/backends/native/meta-kms-crtc.c index 3610df9..da99a58 100644 --- a/src/backends/native/meta-kms-crtc.c +++ b/src/backends/native/meta-kms-crtc.c @@ -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); } diff --git a/src/backends/native/meta-kms-update-private.h b/src/backends/native/meta-kms-update-private.h index 88e2590..df7737c 100644 --- a/src/backends/native/meta-kms-update-private.h +++ b/src/backends/native/meta-kms-update-private.h @@ -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 */ diff --git a/src/backends/native/meta-kms-update.c b/src/backends/native/meta-kms-update.c index 2a4a05c..c946aa7 100644 --- a/src/backends/native/meta-kms-update.c +++ b/src/backends/native/meta-kms-update.c @@ -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) { diff --git a/src/backends/native/meta-kms.c b/src/backends/native/meta-kms.c index 9485bb4..804a1ad 100644 --- a/src/backends/native/meta-kms.c +++ b/src/backends/native/meta-kms.c @@ -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; } diff --git a/src/backends/x11/meta-clutter-backend-x11.c b/src/backends/x11/meta-clutter-backend-x11.c index 8d4b64b..b6334de 100644 --- a/src/backends/x11/meta-clutter-backend-x11.c +++ b/src/backends/x11/meta-clutter-backend-x11.c @@ -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)) diff --git a/src/backends/x11/meta-event-x11.c b/src/backends/x11/meta-event-x11.c index 8b4f4fc..19da223 100644 --- a/src/backends/x11/meta-event-x11.c +++ b/src/backends/x11/meta-event-x11.c @@ -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; diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c index db9ccec..fd99844 100644 --- a/src/compositor/meta-window-actor.c +++ b/src/compositor/meta-window-actor.c @@ -2183,21 +2183,25 @@ meta_window_actor_get_image (MetaWindowActor *self, if (clutter_actor_get_n_children (actor) == 1) { MetaShapedTexture *stex; - MetaRectangle surface_clip; - int geometry_scale; + MetaRectangle *surface_clip = NULL; - geometry_scale = - meta_window_actor_get_geometry_scale (self); + if (clip) + { - surface_clip = (MetaRectangle) { - .x = clip->x / geometry_scale, - .y = clip->y / geometry_scale, - .width = clip->width / geometry_scale, - .height = clip->height / geometry_scale, - }; + int geometry_scale; + + geometry_scale = + meta_window_actor_get_geometry_scale (self); + + surface_clip = g_alloca (sizeof (MetaRectangle)); + surface_clip->x = clip->x / geometry_scale, + surface_clip->y = clip->y / geometry_scale; + surface_clip->width = clip->width / geometry_scale; + surface_clip->height = clip->height / geometry_scale; + } stex = meta_surface_actor_get_texture (priv->surface); - return meta_shaped_texture_get_image (stex, &surface_clip); + return meta_shaped_texture_get_image (stex, surface_clip); } clutter_actor_get_size (actor, &width, &height); diff --git a/src/core/main.c b/src/core/main.c index 7f4f666..3935f35 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -766,6 +766,6 @@ meta_test_init (void) close (fd); #else - g_error ("Tests require wayland support"); + g_warning ("Tests require wayland support"); #endif } diff --git a/src/core/meta-selection-source-memory.c b/src/core/meta-selection-source-memory.c index 04b7f39..c8b0c83 100644 --- a/src/core/meta-selection-source-memory.c +++ b/src/core/meta-selection-source-memory.c @@ -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); diff --git a/src/wayland/meta-selection-source-wayland-private.h b/src/wayland/meta-selection-source-wayland-private.h index 6affc77..a6ada88 100644 --- a/src/wayland/meta-selection-source-wayland-private.h +++ b/src/wayland/meta-selection-source-wayland-private.h @@ -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 */ diff --git a/src/wayland/meta-selection-source-wayland.c b/src/wayland/meta-selection-source-wayland.c index 7031c91..4f6f0c3 100644 --- a/src/wayland/meta-selection-source-wayland.c +++ b/src/wayland/meta-selection-source-wayland.c @@ -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); } diff --git a/src/wayland/meta-wayland-actor-surface.c b/src/wayland/meta-wayland-actor-surface.c index f74bfc5..a61a80e 100644 --- a/src/wayland/meta-wayland-actor-surface.c +++ b/src/wayland/meta-wayland-actor-surface.c @@ -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); diff --git a/src/wayland/meta-wayland-data-device.c b/src/wayland/meta-wayland-data-device.c index 2ca77e8..38aa0f3 100644 --- a/src/wayland/meta-wayland-data-device.c +++ b/src/wayland/meta-wayland-data-device.c @@ -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,43 +1644,34 @@ meta_wayland_data_device_set_selection (MetaWaylandDataDevice *data_device, data_device->selection_data_source = source; data_device->selection_serial = serial; - focus_client = meta_wayland_keyboard_get_focus_client (seat->keyboard); - if (focus_client) - { - data_device_resource = wl_resource_find_for_client (&data_device->resource_list, focus_client); - if (data_device_resource) - { - struct wl_resource *offer; - offer = create_and_send_clipboard_offer (data_device, data_device_resource); - wl_data_device_send_selection (data_device_resource, offer); - } - } - 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); + selection_source = meta_selection_source_wayland_new (source); } else { - unset_selection_source (data_device, META_SELECTION_CLIPBOARD); + 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) + { + data_device_resource = wl_resource_find_for_client (&data_device->resource_list, focus_client); + if (data_device_resource) + { + struct wl_resource *offer; + offer = create_and_send_clipboard_offer (data_device, data_device_resource); + wl_data_device_send_selection (data_device_resource, offer); + } } 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,41 +1775,34 @@ meta_wayland_data_device_set_primary (MetaWaylandDataDevice *data_device, data_device->primary_data_source = source; data_device->primary_serial = serial; - focus_client = meta_wayland_keyboard_get_focus_client (seat->keyboard); - if (focus_client) - { - data_device_resource = wl_resource_find_for_client (&data_device->primary_resource_list, focus_client); - if (data_device_resource) - { - 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); - } - } - 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); + selection_source = meta_selection_source_wayland_new (source); } else { - unset_selection_source (data_device, META_SELECTION_PRIMARY); + 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) + { + data_device_resource = wl_resource_find_for_client (&data_device->primary_resource_list, focus_client); + if (data_device_resource) + { + 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); + } } 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), >k_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; diff --git a/src/wayland/meta-wayland-data-device.h b/src/wayland/meta-wayland-data-device.h index 729baac..efa5478 100644 --- a/src/wayland/meta-wayland-data-device.h +++ b/src/wayland/meta-wayland-data-device.h @@ -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); diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index 5def3c5..163b7c5 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -401,7 +401,7 @@ static void pending_buffer_resource_destroyed (MetaWaylandBuffer *buffer, MetaWaylandPendingState *pending) { - g_signal_handler_disconnect (buffer, pending->buffer_destroy_handler_id); + g_clear_signal_handler (&pending->buffer_destroy_handler_id, buffer); pending->buffer = NULL; } @@ -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); diff --git a/src/x11/meta-selection-source-x11.c b/src/x11/meta-selection-source-x11.c index 15a7636..55e5003 100644 --- a/src/x11/meta-selection-source-x11.c +++ b/src/x11/meta-selection-source-x11.c @@ -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; }
-- ubuntu-desktop mailing list ubuntu-desktop@lists.ubuntu.com https://lists.ubuntu.com/mailman/listinfo/ubuntu-desktop