Skip to content
Commits on Source (29)
3.38.4
======
* Do not ping unmanaging windows [Florian; gnome-shell#2467]
* Handle monitor changes during screencasts [Jonas Å.; !1691]
* Improve freezes when switching workspace [Jonas Å.; !1616]
* Fix newly opened X11 windows being invisible in overview [Olivier; !1678]
* Fix drag cancel animation when using geometry scaling [Robert; !1683]
* Fix stuck icon in DND operation between X11 and wayland [Carlos; !1720]
* Fix restoring focus to windows using globally active input [Olivier; !1716]
* Disable double-buffered shadow buffering [Jonas Å.; !1743]
* Fix frame timings causing X11 clients to get stuck [Jonas Å.; !1754]
* Fix order in which subsurface placement operations are handled [Robert; !1768]
* Fixed crashes [Thomas, Jonas Å., Sebastian; !1694, !1719, !1748]
Contributors:
Jonas Ådahl, Olivier Fourdan, Carlos Garnacho, Sebastian Keller, Robert Mader,
Thomas Mühlbacher, Florian Müllner
3.38.3
======
* xwayland: Set xrandr primary output [Aleksandr; !1638]
......
......@@ -415,15 +415,19 @@ init_shadowfb (ClutterStageView *view)
height = cogl_framebuffer_get_height (priv->framebuffer);
cogl_context = cogl_framebuffer_get_context (priv->framebuffer);
if (init_dma_buf_shadowfbs (view, cogl_context, width, height, &error))
if (g_strcmp0 (g_getenv ("MUTTER_DEBUG_ENABLE_DOUBLE_SHADOWFB"), "1") == 0)
{
g_message ("Initialized double buffered shadow fb for %s", priv->name);
return;
}
if (init_dma_buf_shadowfbs (view, cogl_context, width, height, &error))
{
g_message ("Initialized double buffered shadow fb for %s",
priv->name);
return;
}
g_warning ("Failed to initialize double buffered shadow fb for %s: %s",
priv->name, error->message);
g_clear_error (&error);
g_warning ("Failed to initialize double buffered shadow fb for %s: %s",
priv->name, error->message);
g_clear_error (&error);
}
if (!init_fallback_shadowfb (view, cogl_context, width, height, &error))
{
......
......@@ -311,6 +311,7 @@ on_actor_destroyed (ClutterActor *actor,
{
ClutterTimelinePrivate *priv = timeline->priv;
g_clear_signal_handler (&priv->stage_stage_views_handler_id, priv->stage);
priv->actor = NULL;
}
......
project('mutter', 'c',
version: '3.38.3',
version: '3.38.4',
meson_version: '>= 0.51.0',
license: 'GPLv2+'
)
......
......@@ -1388,7 +1388,8 @@ meta_monitor_config_manager_class_init (MetaMonitorConfigManagerClass *klass)
void
meta_monitor_config_free (MetaMonitorConfig *monitor_config)
{
meta_monitor_spec_free (monitor_config->monitor_spec);
if (monitor_config->monitor_spec)
meta_monitor_spec_free (monitor_config->monitor_spec);
g_free (monitor_config->mode_spec);
g_free (monitor_config);
}
......
......@@ -1138,19 +1138,34 @@ append_monitor_spec (GString *buffer,
MetaMonitorSpec *monitor_spec,
const char *indentation)
{
char *escaped;
g_string_append_printf (buffer, "%s<monitorspec>\n", indentation);
escaped = g_markup_escape_text (monitor_spec->connector, -1);
g_string_append_printf (buffer, "%s <connector>%s</connector>\n",
indentation,
monitor_spec->connector);
escaped);
g_free (escaped);
escaped = g_markup_escape_text (monitor_spec->vendor, -1);
g_string_append_printf (buffer, "%s <vendor>%s</vendor>\n",
indentation,
monitor_spec->vendor);
escaped);
g_free (escaped);
escaped = g_markup_escape_text (monitor_spec->product, -1);
g_string_append_printf (buffer, "%s <product>%s</product>\n",
indentation,
monitor_spec->product);
escaped);
g_free (escaped);
escaped = g_markup_escape_text (monitor_spec->serial, -1);
g_string_append_printf (buffer, "%s <serial>%s</serial>\n",
indentation,
monitor_spec->serial);
escaped);
g_free (escaped);
g_string_append_printf (buffer, "%s</monitorspec>\n", indentation);
}
......
......@@ -316,12 +316,29 @@ add_view_painted_watches (MetaScreenCastAreaStreamSrc *area_src,
}
}
static void
on_monitors_changed (MetaMonitorManager *monitor_manager,
MetaScreenCastAreaStreamSrc *area_src)
{
MetaStage *stage = META_STAGE (get_stage (area_src));
GList *l;
for (l = area_src->watches; l; l = l->next)
meta_stage_remove_watch (stage, l->data);
g_clear_pointer (&area_src->watches, g_list_free);
add_view_painted_watches (area_src,
META_STAGE_WATCH_AFTER_ACTOR_PAINT);
}
static void
meta_screen_cast_area_stream_src_enable (MetaScreenCastStreamSrc *src)
{
MetaScreenCastAreaStreamSrc *area_src =
META_SCREEN_CAST_AREA_STREAM_SRC (src);
MetaBackend *backend = get_backend (area_src);
MetaMonitorManager *monitor_manager =
meta_backend_get_monitor_manager (backend);
MetaCursorTracker *cursor_tracker = meta_backend_get_cursor_tracker (backend);
ClutterStage *stage;
MetaScreenCastStream *stream;
......@@ -354,6 +371,10 @@ meta_screen_cast_area_stream_src_enable (MetaScreenCastStreamSrc *src)
break;
}
g_signal_connect_object (monitor_manager, "monitors-changed-internal",
G_CALLBACK (on_monitors_changed),
area_src, 0);
clutter_actor_queue_redraw (CLUTTER_ACTOR (stage));
}
......
......@@ -336,18 +336,59 @@ add_view_watches (MetaScreenCastMonitorStreamSrc *monitor_src,
}
}
static void
reattach_watches (MetaScreenCastMonitorStreamSrc *monitor_src)
{
MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (monitor_src);
MetaScreenCastStream *stream;
ClutterStage *stage;
GList *l;
stream = meta_screen_cast_stream_src_get_stream (src);
stage = get_stage (monitor_src);
for (l = monitor_src->watches; l; l = l->next)
meta_stage_remove_watch (META_STAGE (stage), l->data);
g_clear_pointer (&monitor_src->watches, g_list_free);
switch (meta_screen_cast_stream_get_cursor_mode (stream))
{
case META_SCREEN_CAST_CURSOR_MODE_METADATA:
case META_SCREEN_CAST_CURSOR_MODE_HIDDEN:
add_view_watches (monitor_src,
META_STAGE_WATCH_BEFORE_PAINT,
before_stage_painted);
add_view_watches (monitor_src,
META_STAGE_WATCH_AFTER_ACTOR_PAINT,
stage_painted);
break;
case META_SCREEN_CAST_CURSOR_MODE_EMBEDDED:
add_view_watches (monitor_src,
META_STAGE_WATCH_AFTER_PAINT,
stage_painted);
break;
}
}
static void
on_monitors_changed (MetaMonitorManager *monitor_manager,
MetaScreenCastMonitorStreamSrc *monitor_src)
{
reattach_watches (monitor_src);
}
static void
meta_screen_cast_monitor_stream_src_enable (MetaScreenCastStreamSrc *src)
{
MetaScreenCastMonitorStreamSrc *monitor_src =
META_SCREEN_CAST_MONITOR_STREAM_SRC (src);
MetaBackend *backend = get_backend (monitor_src);
MetaMonitorManager *monitor_manager =
meta_backend_get_monitor_manager (backend);
MetaCursorTracker *cursor_tracker = meta_backend_get_cursor_tracker (backend);
ClutterStage *stage;
MetaScreenCastStream *stream;
stream = meta_screen_cast_stream_src_get_stream (src);
stage = get_stage (monitor_src);
switch (meta_screen_cast_stream_get_cursor_mode (stream))
{
......@@ -361,25 +402,21 @@ meta_screen_cast_monitor_stream_src_enable (MetaScreenCastStreamSrc *src)
G_CALLBACK (cursor_changed),
monitor_src);
meta_cursor_tracker_track_position (cursor_tracker);
G_GNUC_FALLTHROUGH;
break;
case META_SCREEN_CAST_CURSOR_MODE_HIDDEN:
add_view_watches (monitor_src,
META_STAGE_WATCH_BEFORE_PAINT,
before_stage_painted);
add_view_watches (monitor_src,
META_STAGE_WATCH_AFTER_ACTOR_PAINT,
stage_painted);
break;
case META_SCREEN_CAST_CURSOR_MODE_EMBEDDED:
inhibit_hw_cursor (monitor_src);
meta_cursor_tracker_track_position (cursor_tracker);
add_view_watches (monitor_src,
META_STAGE_WATCH_AFTER_PAINT,
stage_painted);
break;
}
clutter_actor_queue_redraw (CLUTTER_ACTOR (stage));
reattach_watches (monitor_src);
g_signal_connect_object (monitor_manager, "monitors-changed-internal",
G_CALLBACK (on_monitors_changed),
monitor_src, 0);
clutter_actor_queue_redraw (CLUTTER_ACTOR (get_stage (monitor_src)));
}
static void
......
......@@ -168,6 +168,15 @@ meta_screen_cast_stream_get_object_path (MetaScreenCastStream *stream)
return priv->object_path;
}
MetaScreenCastStreamSrc *
meta_screen_cast_stream_get_src (MetaScreenCastStream *stream)
{
MetaScreenCastStreamPrivate *priv =
meta_screen_cast_stream_get_instance_private (stream);
return priv->src;
}
void
meta_screen_cast_stream_transform_position (MetaScreenCastStream *stream,
double stream_x,
......
......@@ -59,6 +59,8 @@ void meta_screen_cast_stream_close (MetaScreenCastStream *stream);
char * meta_screen_cast_stream_get_object_path (MetaScreenCastStream *stream);
MetaScreenCastStreamSrc * meta_screen_cast_stream_get_src (MetaScreenCastStream *stream);
void meta_screen_cast_stream_transform_position (MetaScreenCastStream *stream,
double stream_x,
double stream_y,
......
......@@ -40,6 +40,7 @@ struct _MetaCompositorX11
Window output;
gulong before_update_handler_id;
gulong after_update_handler_id;
gboolean frame_has_updated_xsurfaces;
gboolean have_x11_sync_object;
......@@ -363,35 +364,32 @@ on_before_update (ClutterStage *stage,
}
static void
meta_compositor_x11_before_paint (MetaCompositor *compositor,
ClutterStageView *stage_view)
on_after_update (ClutterStage *stage,
ClutterStageView *stage_view,
MetaCompositor *compositor)
{
MetaCompositorX11 *compositor_x11 = META_COMPOSITOR_X11 (compositor);
MetaCompositorClass *parent_class;
maybe_unredirect_top_window (compositor_x11);
if (compositor_x11->frame_has_updated_xsurfaces)
{
if (compositor_x11->have_x11_sync_object)
compositor_x11->have_x11_sync_object = meta_sync_ring_after_frame ();
parent_class = META_COMPOSITOR_CLASS (meta_compositor_x11_parent_class);
parent_class->before_paint (compositor, stage_view);
compositor_x11->frame_has_updated_xsurfaces = FALSE;
}
}
static void
meta_compositor_x11_after_paint (MetaCompositor *compositor,
ClutterStageView *stage_view)
meta_compositor_x11_before_paint (MetaCompositor *compositor,
ClutterStageView *stage_view)
{
MetaCompositorX11 *compositor_x11 = META_COMPOSITOR_X11 (compositor);
MetaCompositorClass *parent_class;
if (compositor_x11->frame_has_updated_xsurfaces)
{
if (compositor_x11->have_x11_sync_object)
compositor_x11->have_x11_sync_object = meta_sync_ring_after_frame ();
compositor_x11->frame_has_updated_xsurfaces = FALSE;
}
maybe_unredirect_top_window (compositor_x11);
parent_class = META_COMPOSITOR_CLASS (meta_compositor_x11_parent_class);
parent_class->after_paint (compositor, stage_view);
parent_class->before_paint (compositor, stage_view);
}
static void
......@@ -465,6 +463,9 @@ meta_compositor_x11_constructed (GObject *object)
compositor_x11->before_update_handler_id =
g_signal_connect (stage, "before-update",
G_CALLBACK (on_before_update), compositor);
compositor_x11->after_update_handler_id =
g_signal_connect (stage, "after-update",
G_CALLBACK (on_after_update), compositor);
G_OBJECT_CLASS (meta_compositor_x11_parent_class)->constructed (object);
}
......@@ -483,6 +484,7 @@ meta_compositor_x11_dispose (GObject *object)
}
g_clear_signal_handler (&compositor_x11->before_update_handler_id, stage);
g_clear_signal_handler (&compositor_x11->after_update_handler_id, stage);
G_OBJECT_CLASS (meta_compositor_x11_parent_class)->dispose (object);
}
......@@ -504,7 +506,6 @@ meta_compositor_x11_class_init (MetaCompositorX11Class *klass)
compositor_class->manage = meta_compositor_x11_manage;
compositor_class->unmanage = meta_compositor_x11_unmanage;
compositor_class->before_paint = meta_compositor_x11_before_paint;
compositor_class->after_paint = meta_compositor_x11_after_paint;
compositor_class->remove_window = meta_compositor_x11_remove_window;
compositor_class->monotonic_to_high_res_xserver_time =
meta_compositor_x11_monotonic_to_high_res_xserver_time;
......
......@@ -28,6 +28,7 @@
#include "config.h"
#include "compositor/meta-dnd-actor-private.h"
#include "compositor/meta-window-actor-private.h"
#include "clutter/clutter.h"
......@@ -206,16 +207,29 @@ meta_dnd_actor_drag_finish (MetaDnDActor *self,
if (CLUTTER_ACTOR_IS_VISIBLE (self->drag_origin))
{
MetaWindowActor *origin_actor;
float anchor_x, anchor_y;
graphene_point_t dest;
int origin_geometry_scale;
int feedback_geometry_scale;
clutter_actor_get_transformed_position (self->drag_origin,
&dest.x, &dest.y);
origin_actor = meta_window_actor_from_actor (self->drag_origin);
g_return_if_fail (origin_actor);
origin_geometry_scale =
meta_window_actor_get_geometry_scale (origin_actor);
meta_feedback_actor_get_anchor (META_FEEDBACK_ACTOR (self),
&anchor_x, &anchor_y);
feedback_geometry_scale =
meta_feedback_actor_get_geometry_scale (META_FEEDBACK_ACTOR (self));
dest.x += self->drag_start_x - anchor_x;
dest.y += self->drag_start_y - anchor_y;
dest.x += ((self->drag_start_x * origin_geometry_scale) -
(anchor_x * feedback_geometry_scale));
dest.y += ((self->drag_start_y * origin_geometry_scale) -
(anchor_y * feedback_geometry_scale));
clutter_actor_set_position (actor, dest.x, dest.y);
}
......
......@@ -62,4 +62,9 @@ void meta_feedback_actor_set_position (MetaFeedbackActor *self,
void meta_feedback_actor_update (MetaFeedbackActor *self,
const ClutterEvent *event);
void meta_feedback_actor_set_geometry_scale (MetaFeedbackActor *self,
int geometry_scale);
int meta_feedback_actor_get_geometry_scale (MetaFeedbackActor *self);
#endif /* META_FEEDBACK_ACTOR_PRIVATE_H */
......@@ -44,6 +44,8 @@ struct _MetaFeedbackActorPrivate
float anchor_y;
float pos_x;
float pos_y;
int geometry_scale;
};
G_DEFINE_TYPE_WITH_PRIVATE (MetaFeedbackActor, meta_feedback_actor, CLUTTER_TYPE_ACTOR)
......@@ -65,8 +67,10 @@ meta_feedback_actor_update_position (MetaFeedbackActor *self)
MetaFeedbackActorPrivate *priv = meta_feedback_actor_get_instance_private (self);
clutter_actor_set_position (CLUTTER_ACTOR (self),
priv->pos_x - priv->anchor_x,
priv->pos_y - priv->anchor_y);
priv->pos_x -
(priv->anchor_x * priv->geometry_scale),
priv->pos_y -
(priv->anchor_y * priv->geometry_scale));
}
static void
......@@ -249,3 +253,31 @@ meta_feedback_actor_update (MetaFeedbackActor *self,
clutter_event_get_position (event, &point);
meta_feedback_actor_set_position (self, point.x, point.y);
}
void
meta_feedback_actor_set_geometry_scale (MetaFeedbackActor *self,
int geometry_scale)
{
MetaFeedbackActorPrivate *priv =
meta_feedback_actor_get_instance_private (self);
CoglMatrix child_transform;
if (priv->geometry_scale == geometry_scale)
return;
priv->geometry_scale = geometry_scale;
cogl_matrix_init_identity (&child_transform);
cogl_matrix_scale (&child_transform, geometry_scale, geometry_scale, 1);
clutter_actor_set_child_transform (CLUTTER_ACTOR (self),
&child_transform);
}
int
meta_feedback_actor_get_geometry_scale (MetaFeedbackActor *self)
{
MetaFeedbackActorPrivate *priv =
meta_feedback_actor_get_instance_private (self);
return priv->geometry_scale;
}
......@@ -32,6 +32,7 @@ struct _MetaWindowActorClass
void (*set_frozen) (MetaWindowActor *actor,
gboolean frozen);
void (*update_regions) (MetaWindowActor *actor);
gboolean (*can_freeze_commits) (MetaWindowActor *actor);
};
typedef enum
......@@ -96,4 +97,6 @@ gboolean meta_window_actor_is_opaque (MetaWindowActor *self);
void meta_window_actor_update_regions (MetaWindowActor *self);
gboolean meta_window_actor_can_freeze_commits (MetaWindowActor *self);
#endif /* META_WINDOW_ACTOR_PRIVATE_H */
......@@ -146,6 +146,12 @@ meta_window_actor_wayland_update_regions (MetaWindowActor *actor)
{
}
static gboolean
meta_window_actor_wayland_can_freeze_commits (MetaWindowActor *actor)
{
return FALSE;
}
static void
meta_window_actor_wayland_class_init (MetaWindowActorWaylandClass *klass)
{
......@@ -159,6 +165,7 @@ meta_window_actor_wayland_class_init (MetaWindowActorWaylandClass *klass)
window_actor_class->queue_destroy = meta_window_actor_wayland_queue_destroy;
window_actor_class->set_frozen = meta_window_actor_wayland_set_frozen;
window_actor_class->update_regions = meta_window_actor_wayland_update_regions;
window_actor_class->can_freeze_commits = meta_window_actor_wayland_can_freeze_commits;
}
static void
......
......@@ -483,10 +483,12 @@ meta_window_actor_x11_queue_frame_drawn (MetaWindowActor *actor,
* damage or any unobscured, or while we had the window frozen
* (e.g. during an interactive resize.) We need to make sure that the
* before_paint/after_paint functions get called, enabling us to
* send a _NET_WM_FRAME_DRAWN. We do a 1-pixel redraw to get
* consistent timing with non-empty frames. If the window
* is completely obscured, or completely off screen we fire off the
* send_frame_messages timeout.
* send a _NET_WM_FRAME_DRAWN. We need to do full damage to ensure that
* the window is actually repainted, otherwise any subregion we would pass
* might end up being either outside of any stage view, or be occluded by
* something else, which could potentially result in no frame being drawn
* after all. If the window is completely obscured, or completely off
* screen we fire off the send_frame_messages timeout.
*/
if (is_obscured ||
!clutter_actor_peek_stage_views (CLUTTER_ACTOR (actor)))
......@@ -495,8 +497,7 @@ meta_window_actor_x11_queue_frame_drawn (MetaWindowActor *actor,
}
else if (surface)
{
const cairo_rectangle_int_t clip = { 0, 0, 1, 1 };
clutter_actor_queue_redraw_with_clip (CLUTTER_ACTOR (surface), &clip);
clutter_actor_queue_redraw (CLUTTER_ACTOR (surface));
actor_x11->repaint_scheduled = TRUE;
}
}
......@@ -1458,6 +1459,14 @@ meta_window_actor_x11_update_regions (MetaWindowActor *actor)
update_regions (META_WINDOW_ACTOR_X11 (actor));
}
static gboolean
meta_window_actor_x11_can_freeze_commits (MetaWindowActor *actor)
{
ClutterActor *clutter_actor = CLUTTER_ACTOR (actor);
return clutter_actor_is_mapped (clutter_actor);
}
static void
meta_window_actor_x11_set_property (GObject *object,
guint prop_id,
......@@ -1632,6 +1641,7 @@ meta_window_actor_x11_class_init (MetaWindowActorX11Class *klass)
window_actor_class->queue_destroy = meta_window_actor_x11_queue_destroy;
window_actor_class->set_frozen = meta_window_actor_x11_set_frozen;
window_actor_class->update_regions = meta_window_actor_x11_update_regions;
window_actor_class->can_freeze_commits = meta_window_actor_x11_can_freeze_commits;
actor_class->paint = meta_window_actor_x11_paint;
actor_class->get_paint_volume = meta_window_actor_x11_get_paint_volume;
......
......@@ -257,6 +257,14 @@ meta_window_actor_update_regions (MetaWindowActor *self)
META_WINDOW_ACTOR_GET_CLASS (self)->update_regions (self);
}
gboolean
meta_window_actor_can_freeze_commits (MetaWindowActor *self)
{
g_return_val_if_fail (META_IS_WINDOW_ACTOR (self), FALSE);
return META_WINDOW_ACTOR_GET_CLASS (self)->can_freeze_commits (self);
}
static void
meta_window_actor_set_frozen (MetaWindowActor *self,
gboolean frozen)
......
......@@ -602,6 +602,7 @@ struct _MetaWindowClass
gboolean (*is_stackable) (MetaWindow *window);
gboolean (*can_ping) (MetaWindow *window);
gboolean (*are_updates_frozen) (MetaWindow *window);
gboolean (*is_focus_async) (MetaWindow *window);
MetaStackLayer (*calculate_layer) (MetaWindow *window);
......@@ -872,4 +873,5 @@ void meta_window_force_restore_shortcuts (MetaWindow *window,
gboolean meta_window_shortcuts_inhibited (MetaWindow *window,
ClutterInputDevice *source);
gboolean meta_window_is_stackable (MetaWindow *window);
gboolean meta_window_is_focus_async (MetaWindow *window);
#endif
......@@ -1798,6 +1798,7 @@ stackcmp (gconstpointer a, gconstpointer b)
static gboolean
idle_calc_showing (gpointer data)
{
MetaDisplay *display = meta_get_display ();
GSList *tmp;
GSList *copy;
GSList *should_show;
......@@ -1868,6 +1869,8 @@ idle_calc_showing (gpointer data)
tmp = tmp->next;
}
meta_stack_freeze (display->stack);
tmp = should_show;
while (tmp != NULL)
{
......@@ -1892,6 +1895,8 @@ idle_calc_showing (gpointer data)
tmp = tmp->next;
}
meta_stack_thaw (display->stack);
tmp = copy;
while (tmp != NULL)
{
......@@ -8313,6 +8318,9 @@ meta_window_handle_ungrabbed_event (MetaWindow *window,
gfloat x, y;
guint button;
if (window->unmanaging)
return;
if (event->type != CLUTTER_BUTTON_PRESS &&
event->type != CLUTTER_TOUCH_BEGIN)
return;
......@@ -8570,6 +8578,8 @@ meta_window_is_focusable (MetaWindow *window)
gboolean
meta_window_can_ping (MetaWindow *window)
{
g_return_val_if_fail (!window->unmanaging, FALSE);
return META_WINDOW_GET_CLASS (window)->can_ping (window);
}
......@@ -8579,6 +8589,12 @@ meta_window_is_stackable (MetaWindow *window)
return META_WINDOW_GET_CLASS (window)->is_stackable (window);
}
gboolean
meta_window_is_focus_async (MetaWindow *window)
{
return META_WINDOW_GET_CLASS (window)->is_focus_async (window);
}
MetaStackLayer
meta_window_calculate_layer (MetaWindow *window)
{
......