Compare commits

...

10 Commits

Author SHA1 Message Date
Florian Müllner
30d9d1968c Bump version to 3.37.3
Update NEWS.
2020-07-07 19:24:32 +02:00
Florian Müllner
65aa476414 tests/stage-view: Keep old stage views alive on hotplug
Otherwise we cannot reliably compare them to the new post-hotplug
views.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1357
2020-07-07 17:07:20 +00:00
Jonas Dreßler
03d177cf64 clutter/actor: Add position argument to allocate_preferred_size()
Make clutter_actor_allocate_preferred_size() convenient to use from
layout managers by not "automatically" honouring the fixed position of
the actor, but instead allowing to pass a position to allocate the
actor at.

This way we can move the handling of fixed positions to
ClutterFixedLayout, the layout manager which is responsible for
allocating actors using fixed positions.

This also makes clutter_actor_allocate_preferred_size() more similar to
clutter_actor_allocate_available_size().

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1310
2020-07-07 16:47:00 +00:00
Jonas Dreßler
dfa235aa5d clutter/actor: Add API to get fixed position
It's currently a bit hard to get the fixed position of an actor. It can
be either done by using g_object_get() with the "fixed-x"/"fixed-y"
properties or by calling clutter_actor_get_position().

Calling clutter_actor_get_position() can return the fixed position, but
it might also return the allocated position if the allocation is valid.
The latter is not the best behavior when querying the fixed position
during an allocation, so introduce a new function
clutter_actor_get_fixed_position() which always gets the fixed position
and returns FALSE in case no fixed position is set.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1310
2020-07-07 16:47:00 +00:00
Robert Mader
d722e59aac window-actor/wayland: Remove custom get_paint_volume() vfunc
It doesn't take all children - subsurfaces in this case - into
account, thus creating glitches if subsurfaces extend outside
of the toplevel surface.

Further more it doesn't seem to serve any special purpose - it was
added in f7315c9a36, a pretty big commit, and no discussion was
started about the code in question. So it was likely just overlooked
in the review process.

Closes https://gitlab.gnome.org/GNOME/mutter/-/issues/873
Closes https://gitlab.gnome.org/GNOME/mutter/-/issues/1316
2020-07-07 12:25:43 +00:00
Daniel van Vugt
32dbcd9352 background-content: Mipmap background texture rendering
gnome-shell displays workspace previews at one tenth scale. That's a
few binary orders of magnitude so even using a LINEAR filter was
resulting in visible jaggies. Now we apply mipmapping so they appear
smooth.

As an added bonus, the mipmaps used occupy roughly 1% the memory of
the original image (0.1 x 0.1 = 0.01) so they actually fit into GPU/CPU
caches now and rendering performance is improved. There's no need to
traverse the original texture which at 4K resolution occupies 33MB,
only a 331KB mipmap.

In my case this reduces the render time for the overview by ~10%.

Closes: https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/1416

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1347
2020-07-07 16:15:28 +08:00
Daniel van Vugt
3a474556b8 cogl-texture-2d: Flush the journal before mipmapping
In the case of indirect rendering like the first frame to use mutter's
background wallpaper:

  Texture_A -> FBO_B (Texture_B) -> FBO_C (screen)

we would be trying to render the contents of both FBO_B and FBO_C in
the same flush, before the contents of Texture_A had made it to FBO_B.
So when FBO_C wants to use mipmaps of Texture_B they didn't exist yet
and appeared all black. And the blackness would remain for subsequent
frames as cogl has now decided the mipmaps of FBO_B are no longer
"dirty" and don't need refreshing:

  FBO_B (Texture_B) (mipmaps_dirty==FALSE but black) -> FBO_C (screen)

We must flush FBO_B before referencing Texture_B for use in rendering
FBO_C. This only happens when Texture_A changes (e.g. when the user
changes their background wallpaper) so there's no ongoing performance
penalty from this flush.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1347
2020-07-07 16:15:24 +08:00
Jonas Dreßler
249274c677 clutter/actor: Pass stage as user_data when unrealizing
We can avoid having to get the stage again for every child of the
subtree we're unrealizing by getting the stage once and passing it as
user_data to the callbacks.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1356
2020-07-06 19:51:35 +00:00
Jonas Dreßler
ae83a61e67 clutter/actor: Remove actors from shallow relayout list when unrealizing
With the introduction of the shallow relayout mechanism another small
but severe regression sneaked into our layout machinery: We might
allocate an actor twice during the same allocation cycle, with one
allocation happening using the wrong parent.

This issue happens when reparenting an actor from a NO_LAYOUT parent to
a non-NO_LAYOUT parent, in particular it triggered a bug in gnome-shell
when DND reparents a child from the NO_LAYOUT uiGroup to the overviews
Workspace actor after a drag ended. The reason the issue happens is the
following chain of events:

1. child of a NO_LAYOUT parent queues a relayout, this child is added to
the priv->pending_relayouts list maintained by ClutterStage

2. child is reparented to a different parent which doesn't have the
NO_LAYOUT flag set, another relayout is queued, this time a different
actor is added to the priv->pending_relayouts list

3. the relayout happens and we go through the pending_relayouts list
backwards, that means the correct relayout queued during 2. happens
first, then the old one happens and we simply call
clutter_actor_allocate_preferred_size() on the actor, that allocation
overrides the other, correct one.

So fix that issue by adding a method to ClutterStage which removes
actors from the pending_relayouts list again and call this method as
soon as an actor with a NO_LAYOUT parent is detached from the stage.

With that in place, we can also remove the check whether an actor is
still on stage while looping through pending_relayouts. In case
something else is going wrong and the actor is not on stage,
clutter_actor_allocate() will warn anyway.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1356
2020-07-06 19:51:35 +00:00
Andre Klapper
826573ccce Fix broken markup in Hausa UI translation 2020-07-06 19:32:08 +02:00
13 changed files with 153 additions and 63 deletions

27
NEWS
View File

@@ -1,3 +1,30 @@
3.37.3
======
* Support custom keyboard layouts in $XDG_CONFIG_HOME/xkb [Peter; !936]
* Optimize resource scale computation [Jonas D.; !1196, !1276, !1343]
* Allow animating ClutterActor's content property [Georges; !1301]
* Implement backgrounds as ClutterContent [Georges; !1302]
* Add ClutterAlignContraint:pivot-point property [Jonas D.; !737]
* Fix crash on area screenshots with fractional scaling [Sebastian; !1320]
* Do not paint textures of fully obscured windows [Robert; !1326]
* Use a more appropriate combine function on opaque areas [Daniel; !1331]
* Fix remote desktop being broken without screencast session [Olivier; #1307]
* Remove more long-deprecated Clutter APIs [Adam, Georges; !1194, !1332]
* Drive each monitor by its own frame clock [Jonas Å.; !1285]
* Fix copy/paste failures on X11 [Carlos; !1350]
* Mipmap background texture rendering [Daniel; !1347]
* Plugged memory leaks [Sebastian, Jonas D.; !1293, !1281, !1304]
* Misc. bug fixes and cleanups [Jonas Å., Jonas D., Daniel, Corentin, Carlos,
Sebastian, Michel, Robert, Florian; !1288, !1289, !1291, !1296, !1292, !1298,
!1300, !1303, !1290, !1287, !1306, !1305, !1308, !1313, !1250, !1314, !1267,
!1275, !1317, !1270, !1322, !1181, !1282, !1325, !1323, !1240, !1295, !1329,
!1333, !1334, !1336, !1341, #1312, !1345, !1349, !1356, #873, !1310, !1357]
Contributors:
Jonas Dreßler, Michel Dänzer, Olivier Fourdan, Carlos Garnacho,
Peter Hutterer, Adam Jackson, Sebastian Keller, Robert Mader, Florian Müllner,
Georges Basile Stavracas Neto, Corentin Noël, Daniel van Vugt, Jonas Ådahl
3.37.2
======
* Fix move-to-center keybinding with multiple monitors [Sergey; #1073]

View File

@@ -2201,11 +2201,19 @@ unrealize_actor_after_children_cb (ClutterActor *self,
int depth,
void *user_data)
{
ClutterActor *stage = user_data;
/* We want to unset the realized flag only _after_
* child actors are unrealized, to maintain invariants.
*/
CLUTTER_ACTOR_UNSET_FLAGS (self, CLUTTER_ACTOR_REALIZED);
g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_REALIZED]);
if (stage != NULL &&
self->priv->parent != NULL &&
self->priv->parent->flags & CLUTTER_ACTOR_NO_LAYOUT)
clutter_stage_dequeue_actor_relayout (CLUTTER_STAGE (stage), self);
return CLUTTER_ACTOR_TRAVERSE_VISIT_CONTINUE;
}
@@ -2236,11 +2244,13 @@ unrealize_actor_after_children_cb (ClutterActor *self,
static void
clutter_actor_unrealize_not_hiding (ClutterActor *self)
{
ClutterActor *stage = _clutter_actor_get_stage_internal (self);
_clutter_actor_traverse (self,
CLUTTER_ACTOR_TRAVERSE_DEPTH_FIRST,
unrealize_actor_before_children_cb,
unrealize_actor_after_children_cb,
NULL);
stage);
}
/*
@@ -10248,6 +10258,43 @@ clutter_actor_get_position (ClutterActor *self,
*y = clutter_actor_get_y (self);
}
/**
* clutter_actor_get_fixed_position:
* @self: a #ClutterActor
* @x: (out) (allow-none): return location for the X coordinate, or %NULL
* @y: (out) (allow-none): return location for the Y coordinate, or %NULL
*
* This function gets the fixed position of the actor, if set. If there
* is no fixed position set, this function returns %FALSE and doesn't set
* the x and y coordinates.
*
* Returns: %TRUE if the fixed position is set, %FALSE if it isn't
*/
gboolean
clutter_actor_get_fixed_position (ClutterActor *self,
float *x,
float *y)
{
g_return_val_if_fail (CLUTTER_IS_ACTOR (self), FALSE);
if (self->priv->position_set)
{
const ClutterLayoutInfo *info;
info = _clutter_actor_get_layout_info_or_defaults (self);
if (x)
*x = info->fixed_pos.x;
if (y)
*y = info->fixed_pos.y;
return TRUE;
}
return FALSE;
}
/**
* clutter_actor_get_transformed_position:
* @self: A #ClutterActor
@@ -13987,6 +14034,8 @@ clutter_actor_allocate_available_size (ClutterActor *self,
/**
* clutter_actor_allocate_preferred_size:
* @self: a #ClutterActor
* @x: the actor's X coordinate
* @y: the actor's Y coordinate
*
* Allocates the natural size of @self.
*
@@ -14004,37 +14053,22 @@ clutter_actor_allocate_available_size (ClutterActor *self,
* Since: 0.8
*/
void
clutter_actor_allocate_preferred_size (ClutterActor *self)
clutter_actor_allocate_preferred_size (ClutterActor *self,
float x,
float y)
{
gfloat actor_x, actor_y;
gfloat natural_width, natural_height;
ClutterActorBox actor_box;
ClutterActorPrivate *priv;
const ClutterLayoutInfo *info;
g_return_if_fail (CLUTTER_IS_ACTOR (self));
priv = self->priv;
if (priv->position_set)
{
info = _clutter_actor_get_layout_info_or_defaults (self);
actor_x = info->fixed_pos.x;
actor_y = info->fixed_pos.y;
}
else
{
actor_x = 0;
actor_y = 0;
}
clutter_actor_get_preferred_size (self,
NULL, NULL,
&natural_width,
&natural_height);
actor_box.x1 = actor_x;
actor_box.y1 = actor_y;
actor_box.x1 = x;
actor_box.y1 = y;
actor_box.x2 = actor_box.x1 + natural_width;
actor_box.y2 = actor_box.y1 + natural_height;

View File

@@ -419,7 +419,9 @@ CLUTTER_EXPORT
void clutter_actor_allocate (ClutterActor *self,
const ClutterActorBox *box);
CLUTTER_EXPORT
void clutter_actor_allocate_preferred_size (ClutterActor *self);
void clutter_actor_allocate_preferred_size (ClutterActor *self,
float x,
float y);
CLUTTER_EXPORT
void clutter_actor_allocate_available_size (ClutterActor *self,
gfloat x,
@@ -454,6 +456,10 @@ void clutter_actor_set_position
gfloat x,
gfloat y);
CLUTTER_EXPORT
gboolean clutter_actor_get_fixed_position (ClutterActor *self,
float *x,
float *y);
CLUTTER_EXPORT
void clutter_actor_get_position (ClutterActor *self,
gfloat *x,
gfloat *y);

View File

@@ -245,7 +245,13 @@ clutter_clone_allocate (ClutterActor *self,
*/
if (clutter_actor_get_parent (priv->clone_source) != NULL &&
!clutter_actor_has_allocation (priv->clone_source))
clutter_actor_allocate_preferred_size (priv->clone_source);
{
float x = 0.f;
float y = 0.f;
clutter_actor_get_fixed_position (priv->clone_source, &x, &y);
clutter_actor_allocate_preferred_size (priv->clone_source, x, y);
}
clutter_actor_get_allocation_box (priv->clone_source, &source_box);

View File

@@ -139,7 +139,11 @@ clutter_fixed_layout_allocate (ClutterLayoutManager *manager,
child != NULL;
child = clutter_actor_get_next_sibling (child))
{
clutter_actor_allocate_preferred_size (child);
float x = 0.f;
float y = 0.f;
clutter_actor_get_fixed_position (child, &x, &y);
clutter_actor_allocate_preferred_size (child, x, y);
}
}

View File

@@ -141,6 +141,9 @@ void clutter_stage_presented (ClutterStage *stag
void clutter_stage_queue_actor_relayout (ClutterStage *stage,
ClutterActor *actor);
void clutter_stage_dequeue_actor_relayout (ClutterStage *stage,
ClutterActor *actor);
GList * clutter_stage_get_views_for_rect (ClutterStage *stage,
const graphene_rect_t *rect);

View File

@@ -1202,6 +1202,28 @@ clutter_stage_queue_actor_relayout (ClutterStage *stage,
g_object_ref (actor));
}
void
clutter_stage_dequeue_actor_relayout (ClutterStage *stage,
ClutterActor *actor)
{
ClutterStagePrivate *priv = stage->priv;
GSList *l;
for (l = priv->pending_relayouts; l; l = l->next)
{
ClutterActor *relayout_actor = l->data;
if (relayout_actor == actor)
{
g_object_unref (relayout_actor);
priv->pending_relayouts =
g_slist_delete_link (priv->pending_relayouts, l);
return;
}
}
}
void
clutter_stage_maybe_relayout (ClutterActor *actor)
{
@@ -1223,14 +1245,12 @@ clutter_stage_maybe_relayout (ClutterActor *actor)
for (l = stolen_list; l; l = l->next)
{
g_autoptr (ClutterActor) queued_actor = l->data;
float x = 0.f;
float y = 0.f;
if (CLUTTER_ACTOR_IN_RELAYOUT (queued_actor)) /* avoid reentrancy */
continue;
/* An actor may have been destroyed or hidden between queuing and now */
if (clutter_actor_get_stage (queued_actor) != actor)
continue;
if (queued_actor == actor)
CLUTTER_NOTE (ACTOR, " Deep relayout of stage %s",
_clutter_actor_get_debug_name (queued_actor));
@@ -1240,7 +1260,8 @@ clutter_stage_maybe_relayout (ClutterActor *actor)
CLUTTER_SET_PRIVATE_FLAGS (queued_actor, CLUTTER_IN_RELAYOUT);
clutter_actor_allocate_preferred_size (queued_actor);
clutter_actor_get_fixed_position (queued_actor, &x, &y);
clutter_actor_allocate_preferred_size (queued_actor, x, y);
CLUTTER_UNSET_PRIVATE_FLAGS (queued_actor, CLUTTER_IN_RELAYOUT);

View File

@@ -402,6 +402,11 @@ _cogl_texture_2d_pre_paint (CoglTexture *tex, CoglTexturePrePaintFlags flags)
{
CoglContext *ctx = tex->context;
/* Since we are about to ask the GPU to generate mipmaps of tex, we
* better make sure tex is up-to-date.
*/
_cogl_texture_flush_journal_rendering (tex);
ctx->driver_vtable->texture_2d_generate_mipmap (tex_2d);
tex_2d->mipmaps_dirty = FALSE;

View File

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

View File

@@ -1813,7 +1813,7 @@ msgstr ""
msgid ""
"Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>"
msgstr ""
"Wanda ya ɓata <halin firam=\"%s\" sake girma=\"%s\" zura ido=\"%s\" salo="
"Wanda ya ɓata <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style="
"\"komene ne\"/>"
#: ../src/ui/theme.c:4704
@@ -1834,7 +1834,7 @@ msgid ""
"type=\"%s\" style_set=\"whatever\"/> element"
msgstr ""
"Babu salon firam da aka daidaita wa nau'in taga \"%s\" cikin jigon \"%s\", "
"ƙara wata ƙanshi na <nau'in taga=\"%s\" salon_daidaita=\"komene ne\"/>"
"ƙara wata ƙanshi na <window type=\"%s\" style_set=\"komene ne\"/>"
#: ../src/ui/theme.c:5295 ../src/ui/theme.c:5357 ../src/ui/theme.c:5420
#, c-format

View File

@@ -309,7 +309,7 @@ setup_pipeline (MetaBackgroundContent *self,
guint8 opacity;
float color_component;
CoglFramebuffer *fb;
CoglPipelineFilter filter;
CoglPipelineFilter min_filter, mag_filter;
opacity = clutter_actor_get_paint_opacity (actor);
if (opacity < 255)
@@ -408,11 +408,17 @@ setup_pipeline (MetaBackgroundContent *self,
actor_pixel_rect->width,
actor_pixel_rect->height,
NULL, NULL))
filter = COGL_PIPELINE_FILTER_NEAREST;
{
min_filter = COGL_PIPELINE_FILTER_NEAREST;
mag_filter = COGL_PIPELINE_FILTER_NEAREST;
}
else
filter = COGL_PIPELINE_FILTER_LINEAR;
{
min_filter = COGL_PIPELINE_FILTER_LINEAR_MIPMAP_NEAREST;
mag_filter = COGL_PIPELINE_FILTER_LINEAR;
}
cogl_pipeline_set_layer_filters (self->pipeline, 0, filter, filter);
cogl_pipeline_set_layer_filters (self->pipeline, 0, min_filter, mag_filter);
}
static void

View File

@@ -141,29 +141,6 @@ meta_window_actor_wayland_set_frozen (MetaWindowActor *actor,
{
}
static gboolean
meta_window_actor_wayland_get_paint_volume (ClutterActor *actor,
ClutterPaintVolume *volume)
{
MetaSurfaceActor *surface;
surface = meta_window_actor_get_surface (META_WINDOW_ACTOR (actor));
if (surface)
{
ClutterActor *surface_actor = CLUTTER_ACTOR (surface);
const ClutterPaintVolume *child_volume;
child_volume = clutter_actor_get_transformed_paint_volume (surface_actor,
actor);
if (!child_volume)
return FALSE;
clutter_paint_volume_union (volume, child_volume);
}
return TRUE;
}
static void
meta_window_actor_wayland_update_regions (MetaWindowActor *actor)
{
@@ -173,9 +150,6 @@ static void
meta_window_actor_wayland_class_init (MetaWindowActorWaylandClass *klass)
{
MetaWindowActorClass *window_actor_class = META_WINDOW_ACTOR_CLASS (klass);
ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
actor_class->get_paint_volume = meta_window_actor_wayland_get_paint_volume;
window_actor_class->assign_surface_actor = meta_window_actor_wayland_assign_surface_actor;
window_actor_class->frame_complete = meta_window_actor_wayland_frame_complete;

View File

@@ -561,11 +561,13 @@ meta_test_actor_stage_views_hot_plug (void)
is_on_stage_views (actor_1, 1, stage_views->data);
is_on_stage_views (actor_2, 1, stage_views->next->data);
prev_stage_views = g_list_copy_deep (stage_views,
(GCopyFunc) g_object_ref, NULL);
test_setup = create_monitor_test_setup (&hotplug_test_case_setup,
MONITOR_TEST_FLAG_NO_STORED);
meta_monitor_manager_test_emulate_hotplug (monitor_manager_test, test_setup);
prev_stage_views = stage_views;
stage_views = clutter_stage_peek_stage_views (CLUTTER_STAGE (stage));
g_assert (stage_views != prev_stage_views);
@@ -575,6 +577,8 @@ meta_test_actor_stage_views_hot_plug (void)
assert_is_stage_view (stage_views->data, 0, 0, 1024, 768);
assert_is_stage_view (stage_views->next->data, 1024, 0, 1024, 768);
g_list_free_full (prev_stage_views, (GDestroyNotify) g_object_unref);
is_on_stage_views (actor_1, 0);
is_on_stage_views (actor_2, 0);