Commit Graph

324 Commits

Author SHA1 Message Date
Sebastian Keller
56478f21e6 overview: Hide when failing to take grab at end of startup animation
Otherwise keyboard input would be going to whatever window was
preventing us from taking the grab while it is obscured by the overview.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/2667>
2023-03-02 00:08:09 +00:00
Sebastian Keller
bb42973730 overview: Don't claim to be SHOWN when HIDDEN during startup animation
When the overview gets hidden during the startup animation, the callback
would still change the state to SHOWN, despite the overview not being
shown.

This can happen for example if a `monitors-changed` signal triggers a
relayout during startup.

See: https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/2514#note_1683525
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/2667>
2023-03-02 00:08:09 +00:00
Sebastian Keller
f5d793647b overview: Skip SHOWN to SHOWN when changing from app grid to overview
Switching between the app grid and the window picker in the overview via
gestures results in _gestureEnd() getting called with endProgress !== 0
in both cases, which leads to it calling _showDone(). This then
unconditionally changes the state to SHOWN, which in this situation is
already the current state. Since the previous commit this results in a
warning, so check if we are already in the SHOWN state.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/2514>
2023-02-12 16:31:04 +00:00
Sebastian Keller
a91b6439ba overview: Validate transitions of the shown state
There have been several bugs in the past that caused invalid transitions
of the `shown` state, such as going from `showing` to `showing`. These
cause consecutive emissions of the `showing` signal, which can confuse
other classes such as the search controller which connects to the stage
`key-press-event` on showing and disconnects again on `hiding`. Having
two consecutive `showing` signals will cause it to connect twice, and
only disconnect once when hiding the overview again. This will lead to
key presses getting repeated in the search until the session is
restarted. Because there is no obvious connection to how and when this
issue got triggered, this now adds some validation code that only allows
valid transitions and throws an error otherwise so we get a backtrace of
the code actually causing the problem.

This does not fix the issue(s) causing the invalid state transitions, it
only adds a way of tracking them down.

Related: https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/4651
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/2514>
2023-02-12 16:31:04 +00:00
Carlos Garnacho
238a17c6b5 overview: Port to Meta.Display.is_grabbed()
The get_grab_op() method is disappearing, replaced by this
new method.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/2526>
2023-01-30 12:19:22 +00:00
Alessandro Bono
cf47b4a347 overview: Start animation after setting coverPane initial state
Since commit 7bd98f3f5f the onComplete callback
is called right away when animations are disabled. As side effect, now
this._coverPane gets shown/hidden in the wrong order. Start the animation after
setting this._coverPane initial state, so that the animation callback can set the
this._coverPane final state without it being overwritten later.

Move the animation also after emitting the showing and hiding signals. So that the
order showing -> shown and hiding -> hidden is still preserved when animations are
disabled.

Closes: https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/6096
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/2532>
2022-11-25 15:19:37 +00:00
Alessandro Bono
f23ca85f79 overview: Make preparation to enter/leave overview explicit
This give us more control on when the preparation happens and will be
used in the subsequent commit.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/2532>
2022-11-25 15:19:37 +00:00
Florian Müllner
a4e2d708e5 overview: Don't block on wayland popovers
We don't allow entering the overview when there's an ongoing grab
operation, as they are generally incompatible with ClutterGrab.

The exception are wayland popups which are expected to work, and
don't conflict with ClutterGrabs.

https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/6092

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/2549>
2022-11-20 20:49:21 +00:00
Evan Welsh
a88e59c1a8 Adopt EventEmitter class instead of injecting Signal methods
Introduce a new class, EventEmitter, which implements signal
handling for pure JavaScript classes. EventEmitter still
utilizes GJS' addSignalMethods internally.

EventEmitter allows static typechecking to understand the
structure of event-emitting JS classes and makes creating
child classes simpler.

The name 'EventEmitter' mirrors a common name for this pattern
in Node and in JS libraries.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/2043>
2022-07-04 18:30:49 -04:00
Sebastian Keller
23b4eb459e Require both mouse and keyboard grabs for some grabs to be successful
Commit 7419674b changed some grabs from requiring both mouse and
keyboard grabs to be considered successful to only requiring either of
them.

Due to this it was possible for example to open the overview or the
screenshot UI with a client (such as Chrome when opening a menu) holding
the mouse grab. This then made it impossible to interact with the UI
using the mouse (or keyboard) and if attempted could result in an
unresponsive UI.

Fixes: https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/5414
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/2287>
2022-05-04 17:28:08 +00:00
Carlos Garnacho
378406e1f0 overview: Avoid entering in overview mode during display grab op
ClutterGrab and display grab operations are pretty much mutually
exclusive, but there's no mechanism to ensure a ClutterGrab does
not step on top of an existing grab operation.

This looks the only place that could trigger that (e.g. start
dragging window, then move pointer to top/left corner), so skip
over the situation here explicitly.

Fixes: https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/5397
Fixes: https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/5181
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/2281>
2022-04-26 13:32:31 +02:00
Daniel van Vugt
2127222b39 overview: Remove desktop fade logic
It existed to fade out/in `nautilus-desktop` for the overview, but it only
ever worked for X11 sessions (`Meta.WindowType.DESKTOP`) and
`nautilus-desktop` no longer exists anyway.

While I had suggested extending it in the past (!1395), that work was
never finished and since then the DING extension has implemented its
own visibility toggling. There seems little value in keeping the old
fade logic around in gnome-shell. Removing it actually fixes a bug with
DING (https://launchpad.net/bugs/1965072).

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/2244>
2022-03-20 21:57:51 +00:00
Jonas Dreßler
bb1ec88dfa overview: Don't expect time argument from drag-end signal
We actually don't get a time from the xdndHandler when it emits
drag-end, so we fail right now when calling
workspaceManager.get_workspace_by_index(time).

Fix it by getting the time ourselves instead.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/2211>
2022-02-23 17:58:36 +00:00
Florian Müllner
2b45a01517 cleanup: Use new indentation style for object literals
We have made good progress on object literals as well, although there
are still a lot that use the old style, given how ubiquitous object
literals are.

But the needed reindentation isn't overly intrusive, as changes are
limited to the object literals themselves (i.e. they don't affect
surrounding code).

And given that object literals account for quite a bit of the remaining
differences between regular and legacy rules, doing the transition now
is still worthwhile.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/2200>
2022-02-23 12:23:52 +00:00
Florian Müllner
a1dd1b25d8 js: Use templates for non-translatable strings
This reverts commit 9d941f8202 and replaces all additional
instances of .format() that have been added since.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/2160>
2022-02-12 12:29:52 +00:00
Carlos Garnacho
7419674bd3 js: Change main.pushModal to return the Clutter.Grab handle
All callers have been updated to keep this handle to identify their
own grab.

Also, optionally use the windowing state to determine whether
the grab is suitable for the specific uses. This removes the need
to trying to grab twice in the places where we settle for a keyboard
grab.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/2045>
2022-01-29 01:16:30 +01:00
Carlos Garnacho
05a6b35991 overview: Propagate crossing events in cover pane
When animating the overview we temporarily cover it with an actor that
ignores events. This actor should still allow crossing events to go through
as per Mutter requirements.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/2045>
2022-01-29 01:16:29 +01:00
Carlos Garnacho
35d293df6c overview: Grab on the stage
This is more in line with the places where we want events to be
handled (i.e. all). So make the overview take a grab on the
stage itself.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/2045>
2022-01-29 01:16:29 +01:00
Daniel van Vugt
956db078c3 overview: Emit 'hidden' after it's *really* hidden
Previously we would emit 'hidden' before the overview was fully hidden,
so any attempts to animate windows on that signal could still fail.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1440>
2021-08-19 15:44:34 +08:00
Daniel van Vugt
74d0b066e9 overview: Add a 'closing' getter
Which better communicates what we are checking for, and is a little more
elegant than repeatedly writing:
```
Main.overview.animationInProgress && Main.overview.visibleTarget == false
```

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1440>
2021-08-19 15:44:34 +08:00
Florian Müllner
6995c2fa9f shellInfo: Don't destroy source on undo
Destroying the source from an action callback will result in the
notification being destroyed twice:

 - source.destroy() destroys all its notifications

 - a notification destroys itself after an action
   was activated

This results in unwanted log spam when attempting to dispose the
notification for a second time.

There is actually no good reason for destroying the source explicitly,
as sources already self-destruct with their last notification.

https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/4457

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1908>
2021-07-13 12:38:51 +00:00
Florian Müllner
c90fb27a2f shellDBus: Fix FocusApp()
The appDisplay used to be accessible via the viewSelector, but
that is gone now. Commit c09c070b15 adjusted the code, but the
replacement uses a Main.overview.appDisplay accessor that never
existed, whoops.

Fix this by exposing a new selectApp() method directly on the
overview, so we don't have to shuffle the appDisplay through
controls → overviewActor → overview.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1891>
2021-06-17 21:03:58 +00:00
Jonas Dreßler
954131c1c8 overview: Sync grabs after running startup animation
In the nested session the startup animation sometimes fails, weirdly
that always happens to me when running a freshly built gnome-shell the
first time. The reason it fails is that mutter fails to aquire a pointer
grab from the xserver, XIGrabDevice() is unsuccessful.

A simple workaround for this race condition in the xserver is to just
grab the devices a bit later, that is after the startups animation
instead of before it.

This was also tested with disabled animations, and seems to work just as
well in that case.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1812>
2021-05-04 16:18:30 +00:00
Suryashankar Das
4bfb91c5cd overview: Pass state while calling _animateVisible()
Pass OverviewControls.ControlsState.WINDOW_PICKER to the _animateVisible
function in _hideDone().

Fixes: https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/3876
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1769>
2021-04-02 10:20:32 +00:00
Florian Müllner
3c221cea48 overview: Fix showApps() compatibility method
The method is unused in gnome-shell itself, but extensions may still
want to call it, so make sure it actually works.

https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/3873

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1766>
2021-03-14 12:47:42 +00:00
Jonas Dreßler
d49606bbaa overview: Get rid of panel ghost actor
Right now we use a ClutterClone ghost of the panel simply to add some
spacing to the top monitor edge.

We can remove the panelGhost by adjusting the allocations of all the
parts of the overview ourselves inside ControlsManagers vfunc_allocate,
this should also work with extensions that move the panel somewhere
else.

This makes the initial relayout of the overview significantly faster,
because we now no longer have to relayout the whole panel in the
process.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1755>
2021-03-13 22:13:25 +00:00
Alexander Mikhaylenko
df4c05f834 swipeTracker: Pass orientation in constructor
When this class was written, all swipes in the shell were vertical, so it
made sense to make the default orientation vertical. This isn't the case
anymore, thus pass make it mandatory to specify orientation when creating
a tracker.

Change the property default values to horizontal as well to match Clutter
instead of the old shell design.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1731>
2021-03-13 18:08:24 +00:00
Georges Basile Stavracas Neto
9bce2a02be overview: Don't show black panel on startup
The back → transparent transition gives it a very bad look when
booting and running the startup animation.

Use the same transition duration hack to ensure that the panel
starts completely transparent.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1678>
2021-03-02 23:14:07 +00:00
Georges Basile Stavracas Neto
c4e43efb1e overview: Implement startup animation
The new startup animation consists of rising the Dash from the bottom,
falling the search entry from the ceiling, and going from HIDDEN to
WINDOW_PICKER with an opacity applied.

One little trick from IconGridLayout was added to ControlsManagerLayout,
which is a promises-based wait for allocation. This is required to make
sure that the transformed position of the search entry is valid, which
is only the case right after an allocation.

This animation also ensures that the overview is shown right on startup.

For session modes that do not have an overview, continue using the same
fade + scale animation.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1678>
2021-03-02 23:14:07 +00:00
Florian Müllner
e2c1407153 overview: Unset visibleTarget on gesture end
The property describes the target visibility (that is, the visibility
that will be set after the ongoing transition), and is therefore updated
at the start of the transition rather than from hideDone().

The overview gesture currently misses resetting it at the end, so it
is only updated to the correct state the next time the overview is
entered.

https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/3798

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1726>
2021-03-01 13:38:42 +00:00
Carlos Garnacho
76836fe388 overview: Synchronize panel opacity with overview leave animation
Gestures leaving the overview from a short distance result in an
ugly effect with the panel opacity transitionhaving a fixed duration.
Make this transition have the same duration (although in a hackish
way) so we avoid the ugly effect.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1643>
2021-02-17 14:06:11 +01:00
Carlos Garnacho
f7f46ca9ac overview: Clean up dead code
These unused functions accessed undefined functions on a now undefined
variable/class. This vestigial code can go away.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1643>
2021-02-17 14:06:11 +01:00
Carlos Garnacho
cd506d45ef overview: Make 3fg vertical swipes bring overview and app grid
The gesture internally manipulates the main adjustment so one swipe
up brings up the overview, and a second swipe up brings the app
grid. The gesture also works in the other direction to get out of
the overview.

Internally, this is delegated on the OverviewControls, so the
adjustment is not leaked out of there. This however meant open
coding the gesture interaction so it can be directed from
overview.js code.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1643>
2021-02-17 14:06:11 +01:00
Carlos Garnacho
cbde13fc65 overview: Avoid sync_pointer after pop_modal()
This is only necessary for the X11 backend (as grabs triggered by other
clients leave GNOME Shell oblivious of the actual pointer position), but
is now handled inside Mutter.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1556>
2021-02-14 13:57:56 +00:00
Georges Basile Stavracas Neto
c09c070b15 overviewControls: Incorporate ActivitiesContainer
Move AppDisplay, WorkspacesDisplay, and ThumbnailsBox from ViewSelector to
ControlsManager. This allows to always allocate the correct size for AppDisplay,
and will enable for a plethora of further improvements. The end goal is to
completely remove ViewSelector, and let ControlsManager handle the layout of
everything that's visible in the overview.

For now, replace the apps page with a dummy actor in ViewSelector.

Adjust various callers around the codebase to not access the ViewSelector
directly from the overview anymore.

Bind the opacity of the primary workspace to WorkspaceDisplay's opacity. This
allows removing the parent opacity hack in place, which will be done by the
next commit.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1624>
2021-02-11 15:50:31 +00:00
Georges Basile Stavracas Neto
b32f414919 viewSelector: Remove showApps()
Now that Overview is able to ease into any state, be it window
picker or app grid, we can move this ViewSelector method to
Overview itself, which is its rightful place to live.

Remove ViewSelector.showApps(), and make all callers call
Main.overview.show(ControlsState.APP_GRID). Also make sure the
show apps button is correctly toggled.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1624>
2021-02-11 15:50:31 +00:00
Georges Basile Stavracas Neto
8089d7cbf7 overivew: Propagate target state when animating to overview
Next commits will requires ControlsManager to animate to different
states, depending on how Overview is called. Add a new 'state'
parameter to ControlsManager's, and OverviewActor's animateToOverview,
and Overview.show().

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1624>
2021-02-11 15:50:31 +00:00
Georges Basile Stavracas Neto
bce67a27cc viewSelector: Move 'toggle-overview' shortcut to overview
It is handled there already, there's no reason for it to continue
to be in ViewSelector.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1624>
2021-02-11 15:50:31 +00:00
Florian Müllner
741d6abb97 workspacesView: Add primary view to workspaces display
Boy, does this commit feel good.

While the workspaces view on the primary monitor *appears* as part of
the overall overview hierarchy, this hasn't actually been the case
until now. We synchronized its size and (stage) position to match
the workspaces display, but actually kept in a separate layer for
the transitions to and from the overview.

But now that the new layout manager slides out completely during the
overview transitions, the workspaces display starts out covering the
entire work area, which is exactly what we need for the transition.

So finally stop faking it, and actually make the primary workspaces
view a child of the workspaces display.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1624>
2021-02-11 15:50:31 +00:00
Georges Basile Stavracas Neto
1ad1db406e overview: Don't fade OverviewActor
Now that the workspace display is properly allocated for each frame,
we don't want to fade the entire overview anymore.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1624>
2021-02-11 15:50:31 +00:00
Georges Basile Stavracas Neto
0a8aeebd30 overview: Reorganize animateTo/FromOverview()
Instead of directly accessing ViewSelector and calling these methods
there, cascade the calls to OverviewActor, ControlsManager, and finally
ViewSelector. Also move the opacity transition to OverviewActor.

This commit has no functional change.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1624>
2021-02-11 15:50:31 +00:00
Georges Basile Stavracas Neto
301686ee5f overview: Move search entry to ControlsManager
Next commit will tie all these widgets up with a single
layout manager, and we need to control the search entry
position.

Move it to OverviewControls.ControlsManager.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1624>
2021-02-11 15:50:31 +00:00
Georges Basile Stavracas Neto
8eb81ae649 overview: Move background to Workspace
Move the background to the Workspace class by introducing a new container
called WorkspaceBackground, which handles clipping the background to the
workarea.

Move the click action from WorkspaceDisplay into each workspace.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1599>
2021-01-29 21:56:05 +00:00
Jonas Dreßler
87103374fd overview: Increase SHADE_ANIMATION_TIME a bit
The SHADE_ANIMATION_TIME variable sets the duration of the animation of
the background shading that is done when showing the overview. As
explained in the code-comment, that value must be smaller than the
animation time of the overview.

Now since we're going to start animating the background color of the
panel when showing the overview and we're going to use the overviews
animation time for that, we want to make sure the shading of the
background image and the animation of the panel are kept "in sync",
otherwise the transitions would look bad.

So slightly increase the value of SHADE_ANIMATION_TIME to 240 (the
overviews animation time is 250) to make sure those happen in the same
timeframe.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1397>
2021-01-13 23:06:48 +00:00
Florian Müllner
da36506ea5 workspacesView: Work around Clutter optimization
Clutter nowadays omits reallocations when only the stage position
changed, that is when the allocation relative to the parent changed.

As a result (apart from better performance of course), workspaces
in the overview may now end up with an outdated "actual geometry"
in case the overview moved to a new primary monitor (of equal size
as the previous one).

Work around that by emitting a signal from the overview on allocation
changes, and use that to update the cached geometry.

We can revert that change once workspaces become part of the regular
overview hierarchy.

https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/3211
2020-10-05 14:11:55 +02:00
Georges Basile Stavracas Neto
821f3e8ddf overview: Pass drag source on item-drag-* signals
Overview has signals to notify about starting, cancelling, and
finishing icon drags, but none of these signals pass the dragged
item to the callbacks.

Pass the dragged items to the 'item-drag-*' overview signals.

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1332
2020-06-24 18:06:21 -03:00
Florian Müllner
26d27fdbf8 overview: Define ANIMATION_TIME earlier
Commit c7e597cf72 tried to improve the slide animations when entering
the overview by using the same time as the overall overview animation,
but in fact broke the animation most of the times.

That is because the Overview imports OverviewControls before defining
the ANIMATION_TIME variable, so any javascript code that is evaluated
during that import will see the value as "undefined" (which is converted
to 0 for the animation).

Fix this by moving the ANIMATION_TIME variable before the imports instead
of the usual placement.

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1331
2020-06-24 15:41:12 +02:00
Georges Basile Stavracas Neto
0561af66e7 overview: Adapt to MetaBackgroundContent
The properties are now defined in MetaBackgroundContent.
Animate the ClutterContent properties.

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1309
2020-06-09 20:10:52 +00:00
Georges Basile Stavracas Neto
fc3bc7678d viewSelector: Rename show to animateToOverview
The same reasoning as the previous commits.

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1295
2020-06-03 12:55:45 -03:00
Florian Müllner
153b7d525d cleanup: Don't linebreak before closing parentheses
Otherwise recent versions of eslint want "dangling" commas,
which is at least ugly considering that most functions don't
allow adding arguments at leasure.

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1177
2020-04-28 09:04:49 +00:00