Commit Graph

26895 Commits

Author SHA1 Message Date
Georges Basile Stavracas Neto
ea20076bad clutter/offscreen-effect: Implement paint_node()
The paint node tree that ClutterOffscreenEffect generates is
simple:

  Root
    |------------+
    |            |
  Layer        Pipeline
    |
  Actor

Right now, both pre-paint and ClutterLayerNode push the offscreen
to the framebuffer stack. That's harmless, and will go away soon
anyway.

The actor node is created and added in a separate function because
it'll be reused by the next commit.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1355>
2020-12-15 11:48:28 -03:00
Georges Basile Stavracas Neto
26c1a5eedf clutter/offscreen-effect: Use paint nodes to paint target
Add a new ClutterPaintNode parameter to the paint_target() vfunc.
For now, create a temporary ClutterEffectNode that is passed to
paint_target() and immediately painted; next commits will move
this to upper layers.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1355>
2020-12-15 10:36:34 -03:00
Georges Basile Stavracas Neto
691d31748a clutter/desaturate-effect: Switch to create_pipeline vfunc
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1355>
2020-12-15 10:36:34 -03:00
Georges Basile Stavracas Neto
b3641e0833 clutter/colorize-effect: Switch to create_pipeline vfunc
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1355>
2020-12-15 10:36:34 -03:00
Georges Basile Stavracas Neto
5c628083b6 clutter/brightness-contrast-effect: Switch to create_pipeline vfunc
Pretty much the exact same steps and constraints of the previous
commit.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1355>
2020-12-15 10:36:34 -03:00
Georges Basile Stavracas Neto
5587c70c6a clutter/blur-effect: Switch to create_pipeline vfunc
The blur pipeline is still cached on ClutterBlurEffect, and we
simply update the uniforms when asked to create the pipeline.

Now that ClutterOffscreenEffect will use the blur pipeline, it
doesn't need to override the paint_target() vfunc anymore.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1355>
2020-12-15 10:36:34 -03:00
Georges Basile Stavracas Neto
5794871977 clutter/offscreen-effect: Add new create_pipeline() vfunc
The most annoying aspect of ClutterOffscreenEffect right now, and
the reason for all its subclasses to override pre-paint, is that
the pipeline creation isn't under subclasses' control. That means
all subclasses must ask ClutterOffscreenEffect to run pre-paint
and create the pipeline, then they all create their own pipelines
to paint.

To reduce this complexity, add a new create_pipeline() vfunc to
ClutterOffscreenEffect. Next commits will port effects to use this
new vfunc.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1355>
2020-12-15 10:36:34 -03:00
Georges Basile Stavracas Neto
6654053250 clutter/paint-nodes: Make ClutterLayerNode always push/pop
ClutterLayerNode currently skips pushing the offscreen framebuffer when
no operations are set. This was added at the time because pushing and
popping was a synchronization point in Cogl, slow enough to force the
layer node to have this protective measure. Nowadays, pushing and
popping on the paint context is free.

Make ClutterLayerNode always push and pop in pre and post paint.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1355>
2020-12-15 10:36:34 -03:00
Olivier Fourdan
533e6768da build: Use Xwayland pkg-config if available
Xwayland in its main development branch now provides a pkg-config file
which can be used to determine Xwayland installation path and various
options enabled at build time.

Change mutter build system to optionally use that mechanism if
available. If not (as with Xwayland from the current stable branch),
keep the fallback mechanisms (basically search for the Xwayland and parse
its command line options to determine if initfd is available).

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1635>
2020-12-15 09:30:37 +00:00
Daniel Mustieles
baff123af2 Updated Spanish translation 2020-12-15 10:28:59 +01:00
Georges Basile Stavracas Neto
15f5087135 Introduce ClutterBlurNode
ClutterBlurNode is a paint node based on ClutterLayerNode
that draws all children in an offscreen framebuffer, blurs
this framebuffer, and finally paints the blurred contents
according the the paint operations added.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1627>
2020-12-14 09:45:50 -03:00
Georges Basile Stavracas Neto
3440fbd358 clutter: Add private ClutterBlur
ClutterBlur is a small helper structure that implements
blurring a texture.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1627>
2020-12-14 09:43:08 -03:00
Georges Basile Stavracas Neto
3a3eaf5ad3 clutter/paint-nodes: Fix blit node oversights
Copy-paste error sneaked ClutterTransformNodeClass in
clutter_blit_node_class_init(). It wasn't problematic
because they both typedef to ClutterPaintNodeClass, but
fix it anyway.

Also switch to g_object_ref() in clutter_blit_node_new().

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1627>
2020-12-14 09:21:30 -03:00
Georges Basile Stavracas Neto
d57bdb0b44 cogl/framebuffer: Add COGL_EXPORT to public function
An oversight of 038a3170bf.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1627>
2020-12-14 09:21:30 -03:00
Florentina Mușat
f48a86a88e Update Romanian translation 2020-12-12 20:01:39 +00:00
Florentina Mușat
b3a073fdd6 Update Romanian translation 2020-12-12 18:28:03 +00:00
Daniel van Vugt
ebf9f18080 clutter/text: Make update_cursor_location() operate in stage coordinates
Until now we would `clutter_input_focus_set_cursor_location` with
cursor-rectangle-in-physical-pixels + actor-location-in-stage-coordinates.
But those use different scaling factors so it only got the right answer
when the framebuffer scale was 1.0.

This directly determines the geometry of the invisible dummy cursor in
gnome-shell ibusCandidatePopup.js:

```
  panelService.connect('set-cursor-location', (ps, x, y, w, h) => {
      this._setDummyCursorGeometry(x, y, w, h);
  });
```

And because it's invisible it wasn't obvious that it was wrong until you
enable `CLUTTER_PAINT=damage-region` and you can see its ghost at the wrong
offset and scale.

So now we `clutter_input_focus_set_cursor_location` using purely unscaled
stage coordinates. And `CLUTTER_PAINT=damage-region` shows that
gnome-shell's `_dummyCursor` is placed precisely over the visible cursor.

Fixes: https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/3399
and probably other IBus issues that arise when using framebuffer scaling.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1576>
2020-12-12 08:18:49 +00:00
Daniel van Vugt
db30a4d7b4 clutter/text: Scale down clutter_text_get_cursor_rect to actor coordinates
`priv->cursor_rect` is stored in physical pixels, not local coordinates.
So unscale it before returning from `clutter_text_get_cursor_rect`, which
is explicitly documented as returning "actor-relative coordinates".

This went missed with fractional scaling support, and unnoticed as nobody
uses `clutter_text_get_cursor_rect` yet. But that will soon change.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1576>
2020-12-12 08:18:49 +00:00
Daniel van Vugt
0bace8dbde clutter/offscreen-effect: Use the paint volume origin as the FBO offset
Before now it was assumed that the only negative local coordinates would
be those introduced by `_clutter_actor_box_enlarge_for_effects`, and we
used the difference for `fbo_offset_x/y`. But that was misguided (of me)
because gnome-shell can give us paint volumes at negative coordinates too,
like when rendering `box-shadow` on the top or left edge of an actor.

The maximum extents of negative coordinates we might need to render are
in fact the (enlarged) left and top edges of the paint volume. So use
those as the FBO offset. This places the actor's local origin correctly
within the FBO and thus also ensures it's not over-clipped at the edges
of the FBO, which now line up with the enlarged extents of the paint
volume.

This fixes one third of
https://gitlab.gnome.org/GNOME/gnome-shell/issues/1090
The other fixes required are !1053 and gnome-shell!1417.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1538>
2020-12-12 00:27:46 +00:00
Jonas Dreßler
9693462f32 clutter/actor: Use different view list when picking frame clock of stage
Apparently it can happen that a timeline tries to pick a frame clock
from an actor that's on a stage, but the actor still doesn't find a
frame clock and returns NULL.

This probably is the case when starting a timeline right after attaching
an actor to a newly created stage, so before the first stage-update
cycle. In this case clutter_actor_update_stage_views() will not have run
and the stage-actor will have priv->stage_views set to NULL even though
there are stage views.

To prevent this from happening, use the complete list of stage views
maintained by the backend when picking a frame clock for the stage.

This doesn't fix any issue appearing on master, but is correct
nonetheless.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1631>
2020-12-11 22:51:44 +00:00
Florian Müllner
fbe1a16a6b ci: Only fetch history for branch tips
We don't need any history, so we can save a bit of bandwidth by
omitting it, and only fetch the refs we are actually interested in.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1630>
2020-12-11 16:56:41 +00:00
Florian Müllner
afced5b405 ci: Fix checking out gnome-shell for tag pipelines
$CI_COMMIT_REF_NAME can be a branch name or a tag, depending on the
pipeline, but our checkout script only deals with the former at the
moment.

Address this by rather than looking for a remote branch name, just
try to fetch the ref like we do for merge request pipelines.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1630>
2020-12-11 16:56:41 +00:00
Florian Müllner
f335df56b6 ci: Improve checkout script output
We are currently not very good at communicating what's going in,
in particular for non-merge request pipelines where the output
is usually just "Using origin/master instead" (instead of what?).

Improve this by consistently communicate what we are looking for,
whether we found it, and what we end up doing.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1630>
2020-12-11 16:56:41 +00:00
Aleksandr Mezin
4f544b6362 xwayland: Set xrandr primary output
To find XWayland output that should be the primary one, iterate through all
XWayland outputs, and compare their geometry to the geometry of the primary
logical monitor.

To avoid possible race conditions (Mutter's monitor configuration already
updated, but Xrandr not yet), set the output both after Randr notifications and
after 'monitors-changed' signal.

https://gitlab.gnome.org/GNOME/mutter/-/issues/1407

Signed-off-by: Aleksandr Mezin <mezin.alexander@gmail.com>
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1558>
2020-12-11 13:44:45 +00:00
Jonas Ådahl
357f3250cb xwayland: Make sure /tmp/.X11-unix/ exists
When we're running under a polyinstantiated SELinux environment, we'll
likely start with an isolated and empty /tmp, meannig no /tmp/.X11-unix
directory to add things to. To make it possible to still function in
this kind of setup, make sure said directory exists.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1626>
2020-12-10 17:10:32 +01:00
Jonas Ådahl
d940911478 xwayland: Don't spew warnings when looking for X11 displays
It's not important, so only show it when doing MUTTER_DEBUG=wayland.
Instead report what display numbers were eventually found.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1625>
2020-12-10 15:00:53 +00:00
Jonas Ådahl
4ef34ed68f xwayland: Clean up error reporting
Instead of g_warning() everywhere, use GError.

This also removes the already unused 'fatal' boolean that was still
passed around.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1625>
2020-12-10 15:00:53 +00:00
Carlos Garnacho
e21929be82 clutter: Do not poke backend code for motion compression
We now have all info available in ClutterEvent, use it and stop poking
backend internals.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1623>
2020-12-08 15:37:38 +00:00
Carlos Garnacho
0842ac936f clutter: Drop infrastructure to copy/free platform event data
This is now unused, all information belongs to ClutterEvents.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1623>
2020-12-08 15:37:38 +00:00
Carlos Garnacho
64d5e8a9bd backends/native: Drop MetaEventNative
This doesn't really hold anything now, so we can stop trying to
copy these across events.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1623>
2020-12-08 15:37:38 +00:00
Carlos Garnacho
b88790554b clutter: Move relative motion information to ClutterEvent
Instead of using native backend platform data specifically, store
this info in ClutterMotionEvent. This includes time in usec since
it's just used for motion events, in the future it could make sense
to make these general to all events again, but it could make sense
to make ClutterEvent structs private before.

In order to express that a motion event has relative motion info,
the CLUTTER_EVENT_FLAG_RELATIVE_MOTION event flag has been added
for it.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1623>
2020-12-08 15:37:38 +00:00
Carlos Garnacho
4db5b95aac wayland: Drop HAVE_BACKEND_NATIVE checks in wl_touch implementation
This file doesn't really do anything much backend-dependent anymore, we
can drop these checks.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1623>
2020-12-08 15:37:38 +00:00
Carlos Garnacho
eaa04ecee5 backends: Unify touch sequence to slot conversion
We had code in both backends that sort of independently associated
sequences to slots. Make both transform slots to sequences the same
way, so they may share the implementation convert those back to slots.

This helper now lives in Clutter API.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1623>
2020-12-08 15:37:38 +00:00
Carlos Garnacho
9f5c453fc7 clutter: Move evdev evcode data to Clutter button/key events
We have this as platform-dependent data in the native backend, and
a bunch of fallback code done in place in the evcode users. Stop
making this platform-dependent data, and move it to the relevant
ClutterEvents.

The fallback code for the X11 backend case is about the same, but
now it is done directly by the X11 backend.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1623>
2020-12-08 15:37:38 +00:00
Carlos Garnacho
09b956997c backends/x11: Drop platform-specific event data
This is largely unused, for long probably. We want to avoid adding
platform data to events, so that's convenient.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1623>
2020-12-08 15:37:38 +00:00
Carlos Garnacho
4a0c56f928 clutter: Simplify stage state management
Making this an event is overly convoluted, accounting that we
emit the event, then convert it to a ClutterStage signal, then
its only consumer (a11y) sets the active ATK state.

Take the event out of the equation, unify activation/deactivation
of the stage in MetaStage, and use it from the X11 backend too.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1623>
2020-12-08 15:37:38 +00:00
Carlos Garnacho
96e320ba5a clutter: Drop CLUTTER_DESTROY_NOTIFY event
Stop propagating this as a Clutter event. DestroyNotify is only
relevant on nested X11 sessions, so handle it specifically in place.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1623>
2020-12-08 15:37:38 +00:00
Carlos Garnacho
49b3ac2f86 clutter: Drop CLUTTER_CLIENT_MESSAGE event
This is used nowhere and emitted nowhere. We can do without it.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1623>
2020-12-08 15:37:38 +00:00
Georges Basile Stavracas Neto
033423f6db Introduce ClutterBlitNode
It is not possible to express a blit operation using paint
nodes as of now. This is a requirement for GNOME Shell, e.g.,
to implement its blur effect.

Add a new ClutterBlitNode node that takes two framebuffers as
input, and blits the source framebuffer into the current one
according to added rectangles.

Because this paint node uses the rectangles in a different way
compared to all the other nodes, add an auxiliary method to
ensure all blit operations are valid.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1340>
2020-12-08 15:14:04 +00:00
Georges Basile Stavracas Neto
4c75389baa clutter/paint-nodes: Add serialization to layer node
It's useful to know which framebuffer the layer node is holding,
so serialize that too.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1340>
2020-12-08 15:14:04 +00:00
Georges Basile Stavracas Neto
63ea2dacc4 clutter/paint-nodes: Add new ClutterLayerNode API
ClutterLayerNode is the "offscreen framebuffer" node, that paints it's
child nodes in a separate framebuffer, and then copies that framebuffer
to the parent one.

It'll be useful to hand ClutterLayerNode which framebuffer and pipeline
to use, as this is a requirement for porting e.g. ClutterOffscreenEffect
and subclasses.

Add a new clutter_layer_node_new_to_framebuffer() API.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1340>
2020-12-08 15:14:04 +00:00
Georges Basile Stavracas Neto
89f9be0dd1 clutter/paint-nodes: Add opacity overriding to ClutterActorNode
Some effects, such as ShellBlurEffect and ClutterOffscreenEffect, need
to make sure the actor is painted fully opaque. With ClutterActorNode,
however, that is currently not possible.

Add a new 'opacity' parameter to clutter_actor_node_new(). It follows
the opacity override heuristic, where -1 means disable, and anything
else is clamped to [0, 255].

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1340>
2020-12-08 15:14:04 +00:00
Georges Basile Stavracas Neto
5c772a634e clutter/effect: Add paint_node vfunc
Introduce a new paint_node vfunc that, if implemented, allows
the effect to add nodes to a transient paint node that is
immediately painted. This is a transitional step until we
have fully delegated paint node rendering.

The most basic implementation of a ClutterEffect.paint_node
vfunc, and also the default implementation, is with an actor
node, as follows:

```
static void
foo_bar_paint_node (ClutterEffect           *effect,
                    ClutterPaintNode        *node,
                    ClutterPaintContext     *paint_context,
                    ClutterEffectPaintFlags  flags)
{
  g_autoptr (ClutterPaintNode) actor_node = NULL;

  actor_node = clutter_actor_node_new (effect->actor);
  clutter_paint_node_add_child (node, actor_node);
}
```

This example gives the exact same behavior of simply calling
clutter_actor_continue_paint(). In the future, the paint node
itself will be a parameter of clutter_actor_continue_paint()
and we'll be able to simplify it event more.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1340>
2020-12-08 15:14:03 +00:00
Georges Basile Stavracas Neto
e45d1c6ea6 Introduce ClutterEffectNode
ClutterEffectNode is a private ClutterPaintNode implementation
that does effectively nothing, but helps organizing the paint
node tree. It also helps debugging, since it can output the
effect class and name to the JSON debugging routines.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1340>
2020-12-08 15:14:03 +00:00
Georges Basile Stavracas Neto
3c8bfc1482 clutter/paint-node: Walk up paint node tree to find framebuffer
The idea of having a paint node tree is that we don't really need
to retrieve the framebuffer from ClutterPaintContext. For example,
ClutterLayerNode draws into an offscreen framebuffer; if any child
of a layer node needs to retrieve a framebuffer to draw, the layer
node's offscreen framebuffer should be used.

However, clutter_paint_node_get_framebuffer() goes straight to the
root node of the tree, skipping any potential paint nodes with a
custom framebuffer.

Modify clutter_paint_node_get_framebuffer() to walk up the paint
node tree until a node with a custom framebuffer appears. In many
cases, this will end up either in dummy or layer node's custom
framebuffer implementations.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1340>
2020-12-08 15:14:03 +00:00
Carlos Garnacho
20ac791f4b backends/native: Avoid -Wmaybe-uninitialized warning
Ensure that color_ptr gets set, and avoid color_char usage too in
that case. Fixes:

  ../../../../Source/gnome/mutter/src/backends/native/meta-monitor-manager-kms.c: In function ‘meta_monitor_manager_kms_set_crtc_gamma’:
  ../../../../Source/gnome/mutter/src/backends/native/meta-monitor-manager-kms.c:370:7: warning: ‘color_char’ may be used uninitialized in this function [-Wmaybe-uninitialized]
    370 |       g_string_append_printf (string, " %c: ", color_char);
        |       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  ../../../../Source/gnome/mutter/src/backends/native/meta-monitor-manager-kms.c:351:12: note: ‘color_char’ was declared here
    351 |       char color_char;
        |            ^~~~~~~~~~
  ../../../../Source/gnome/mutter/src/backends/native/meta-monitor-manager-kms.c:391:36: warning: ‘color_ptr’ may be used uninitialized in this function [-Wmaybe-uninitialized]
    391 |                                   (*color_ptr)[i]);
        |                                   ~^~~~~~~~~~~
  ../../../../Source/gnome/mutter/src/backends/native/meta-monitor-manager-kms.c:350:24: note: ‘color_ptr’ was declared here
    350 |       unsigned short **color_ptr;
        |                        ^~~~~~~~~

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1624>
2020-12-08 13:35:50 +00:00
Carlos Garnacho
745ccc5b01 compositor: Fix warning with -Wmaybe-uninitialized
Assert that the region is created, thus we passed a valid enum value
to the get_scaled_region() function. Fixes:

  ../../../../Source/gnome/mutter/src/compositor/meta-surface-actor.c: In function ‘get_scaled_region’:
  ../../../../Source/gnome/mutter/src/compositor/meta-surface-actor.c:113:10: warning: ‘scaled_region’ may be used uninitialized in this function [-Wmaybe-uninitialized]
    113 |   return scaled_region;
        |          ^~~~~~~~~~~~~

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1624>
2020-12-08 13:35:50 +00:00
Carlos Garnacho
14ab90eeba clutter/actor: Initialize out variable
Fixes a compiler warning with -Wmaybe-uninitialized enabled:

  ../../../../Source/gnome/mutter/clutter/clutter/clutter-actor.c: In function ‘clutter_actor_paint’:
  ../../../../Source/gnome/mutter/clutter/clutter/clutter-actor.c:3808:50: warning: ‘result’ may be used uninitialized in this function [-Wmaybe-uninitialized]
   3808 |       else if (result == CLUTTER_CULL_RESULT_OUT && success)
        |                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~

Which might presumably happen in the unlikely case that there's no clip
frusta.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1624>
2020-12-08 13:35:50 +00:00
Juliano de Souza Camargo
517dc99dfd Update Portuguese translation
(cherry picked from commit 2d69e27a2251feb55b361a167463204196499437)
2020-12-07 21:25:37 +00:00
Kjartan Maraas
aa301c1df2 Update Norwegian Bokmål translation
(cherry picked from commit 87cb57f243998cde1a8ab152939d6e992ede9b6d)
2020-12-04 15:34:54 +00:00