Previously we used a bunch of heuristics for this. We checked if velocity
was directed towards the nearest snap point and its value was larger than
a threshold. If it is, we completed the swipe, otherwise we cancelled it.
This was good enough at the time, because this code was originally written
for back/forward swipe. Since then, the swipe tracker was extended to
handle arbitrary snap points and not just 0 and 1, or -1 and 0, depending
on text direction. After that it was iterated on, but never significantly
redone.
This worked well enough, but had two problems:
1. In some cases, notably overview, it may be wanted to be able to swipe
through multiple pages at once. This wasn't really possible because we
always picked the adjacent snap point.
2. Since we can't do that well, we want to restrict swipes to one page at a
time. It was done in a rather hacky way by clamping the position into
[-1, 1] range from the place where we started the swipe. This works
if we start the swipe from idle position, but if an animation was
already going, the range would be clamped to arbitrary values, and very
likely containing only one snap point, which we already swiped past at
this point. In this case, finishing the swipe would cancel it regardless
of velocity. This means that if one tries to quickly move through
carousel pages via swiping, half of the swipes will be inexplicably
cancelled.
We'll use the deceleration formula from
https://medium.com/@esskeetit/how-uiscrollview-works-e418adc47060#10ce
to calculate then projection point, then pick the nearest snap point and
calculate the duration as we did before. It works well enough for short
distances, but has two problems:
1. It caps the maximum distance at a pretty low value - about 5 pages in my
testing.
2. With how we pick the nearest snap point, it's too easy to accidentally
cancel the swipe,
To combat the first problem, we can modify the curve: only use linear
function at small distances, and smoothly transition it to a parabola
further.
For the second problem we can add two special cases: first, if the swipe
ended up between the initial snap point and the next one, we always prefer
the latter. Second, a good old velocity threshold for cancelling.
We'll also use a slightly smaller deceleration value for touchpad: 0.997
instead of 0.998.
Now that we can pick any snap point, the [-1, 1] clamping doesn't make
sense anymore, so instead let's replace it with a more flexible
mechanism: if we're near a snap point, pick its adjacent snap points.
Otherwise, take the two nearest snap points, and take their adjacent
snap points. This way we have 3 snap points to choose from when
starting a swipe from an idle position, and 4 if we start during an
ongoing transition.
This way, if we've just swiped from snap point n to n+1, the transition
will pick snap points n-1, n, n+1, n+2 and if we swipe again, we will
likely land on n+2. During that transition, if we swipe again, it will
likely have already passed the snap point n+1, so this time the available
snap points will be n, n+1, n+2, n+3, so we can swipe again and it will
still complete, and so on.
This will make it easy to allow multi-page swipes as well, by just
removing the clamping.
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1647>
In some cases we may get anevent with very low delta at the end of the
swipe. While we can't completely ignore them, we can smooth them using a
scroll history, similarly to what GTK kinetic scrolling does: keep track
of the last 150ms of events, and sum their deltas when calculating the
velocity.
The logic is based on what GTK does in GtkGestureSwipe and
GtkEventControllerScroll.
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1647>
Let empty input result in an error, just like other invalid commands
(bad syntax, nonempty whitespace, etc.). GLib already has an error
message “Text was empty (or contained only whitespace)” which it shows
for whitespace-only input, so letting that message apply also to empty
input makes sense.
This requires some tweaks further down the file to avoid interpreting
empty input as an empty path (relative to the home directory) and then
opening the home directory.
Part of https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/3183.
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1442>
Resource icons are added to the fallback icon theme, so they won't
get used if a matching icon is found in the configured theme.
That includes fallback names, so Adwaita's "window-close-symbolic"
takes precedence over "window-close-24-symbolic" in hicolor.
Fix this by using a custom name for a custom icon.
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1640>
The Message class this is derived from unconditionally adds a close
button with 0 opacity that only gets shown on hover for messages that
can actually be closed. The MPRIS MediaMessage however can never be
closed and having a close button can cause the title to be cut short
unexpectedly.
Similarly the secondary text which other notifications use to display
the notification time is always left empty here as well.
https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/3664
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1632>
grabHelper is passing a boolean argument to onUngrab() callback function
and since commit 1acbdcc9b3 we'd end up adding it to to the callback list or
we'd try to invoke it:
(gnome-shell:3490851): Gjs-CRITICAL **: 17:19:20.460: JS ERROR:
TypeError: func is not a function
onComplete/<@/media/M2/GNOME/gnome-shell/js/ui/appDisplay.js:2407:56
onComplete@/media/M2/GNOME/gnome-shell/js/ui/appDisplay.js:2407:40
_makeEaseCallback/<@/media/M2/GNOME/gnome-shell/js/ui/environment.js:85:13
_easeActor/<@/media/M2/GNOME/gnome-shell/js/ui/environment.js:170:64
Use an arrow function so that we can control the parameters we pass
to popdown.
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1635>
This get's rid of the single-indicator introduced in one of the latest
commits. This was causing the accessibility pill in the top panel
to have different padding from the keyboard layout pill.
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1615>
So far, we couldn't allow workspace scrolling outside the overview
because scroll events were always sent to clients. However mutter
was changed recently to pass on scroll events when the mouse button
modifier (usually super) is pressed, which allows us to enable the
same workspace scrolling as in the overview now.
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1612>
The design now calls for super-scroll for workspace switching
in the session, however it is currently only possible for
SwipeTracker to either handle scroll events or not.
In order to support the new use case, add a new :scroll-modifiers
property that allows specifying modifiers for which scroll events
are handled.
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1612>
The code to update the actor position based on the cursor and current
scale was run in a 'new-frame' handler. This is working fine when
animations are enabled, but when they are turned off this does not work.
This is because the 'new-frame' signal is emitted before the changes for
that frame are applied. So with animations off the position was only
ever updated with the starting values. As a result the shrunk actor was
not being dragged by the position where it was clicked, but by where it
was clicked in the original size, which is likely not even on the shrunk
actor.
This change now also updates the position in the onComplete handler
which gets run with the final scale, even if the duration is 0.
Fixes https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/1699
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1627>
Next commit will bind the workspace state adjustment to the snap
adjustment in WorkspacesView, and we'll need the preparation
steps but not the easing of the state adjustment.
Split preparation steps from zoomFromOverview() into a new method
prepareToLeaveOverview().
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1613>
As per the latest mockups, then horizontally snapping, the active
workspace should be highlighted. Because WorkspacesView clips to
allocation, we cannot simply scale up the active one. Instead,
scale down the inactive ones.
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1613>
Synchronizing the actual geometry while animating from / to the overview can
break the animation. Let's prevent that. This code will go away soon anyway,
but to not lose bisectability, it's better not to leave it misbehaving until
then.
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1613>
When vertically snapping, WorkspacesView currently allocates workspaces
side-by-side, then applies an extra step of translation to center to
the active workspace. This extra step, however, gets in our way because
now we need tighter control of the workspaces positions in allocation,
in order to properly interpolate them.
Move the translation of workspaces to the allocation code itself, and
remove the extra translation step.
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1613>
Currently, WorkspacesView positions each workspace on a
per-page layout, each page with the allocated width and
height of WorkspaceView. This layout doesn't work well
with horizontal workspaces.
Layout workspaces side by side, instead of per page. The
layout is influenced by a "fit mode", which reflects the
different behaviors exposed in the mockup. This fit mode
represents whether a single or all workspaces will fit
available geometry.
The single fit mode is always used for now. Next commits
will make it switch to the all fit mode when in the app
grid state.
The translation_{x,y} also needed to reflect the switch to
a side-by-side layout, and use the geometry of the workspaces
to determine the offset. Notice that, when the fit mode is ALL,
there's no translation applied.
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1613>
Nowadays gjs allows to omit get/set accessors for read-write properties,
and will define reasonable defaults in that case. In many cases we don't
need anything more than the default handling, let gjs handle those props.
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1611>
The app grid itself now is horizontal, and is displayed beneath
workspaces, above the dash. This makes the indicator animations
out of place, as they're not coming from the edge anymore.
Use PageIndicators for both FolderView and AppDisplay.
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1629>
The new window preview overlay requires getting the app icon for a
window from the window tracker when it gets initialized. The window
tracker listens for the same 'window-added' signal on the MetaWorkspace
that the gnome-shell Workspace listens for to add the window preview.
The window tracker however reconnects all its signal handlers whenever
the number of workspaces changes, which means that its signal handlers
get called after the ones in Workspace ones. So by the time the
'window-added' handler in Workspace is called, the window tracker does
not have an app associated with the window.
To fix this ensure that all window related signal handlers in Workspace
are run after the ones in the window tracker.
Fixes https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/3656
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1625>
Currently, there's one animation for the whole canvas. While it looks fine
with just one screen, it causes windows to move between screens when
switching workspaces. Instead, have a separate animation on each screen,
and sync their progress so that at any given time the progress "fraction"
is the same between all screens. Clip all animations to their screens so
that the windows don't leak to other screens.
If a window is placed between every screen, can end up in multiple
animations, in that case each part is still animated separately.
Fixes https://gitlab.gnome.org/GNOME/gnome-shell/issues/1213
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1326>
Currently, the workspace swipe transition only has one workspace in each
direction. This works until you try to do multiple swipes in quick
succession. The second swipe would continue the existing transition, which
only has 2 or 3 workspaces in it, and will hit a wall.
To prevent this, take all workspaces and arrange them into a column or row,
depending on the layout, and use that as a transition.
For the transition that happens when focusing a window on another workspace
(for example, via Alt+Tab), still use only two workspaces instead of all of
them.
Since we don't support layouts other than single rows/columns anymore,
diagonal transitions aren't supported anymore, and will be shown as
horizontal or vertical instead.
Since nw alt-tab and gesture transitions are different, don't allow to do
both at once, that is, disable swipe tracker when a programmatic transition
is going. This will also conveniently cancel a gesture transition if a
programmatic one is initiated while a gesture is in progress.
Fixes https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/2612
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1326>
In future we will need to use window clones to better support multiple
monitors. To avoid having to hide every window, show wallpapers behind
the workspace transition: one per monitor.
Put the wallpaper into a separate class right away, later it will be
useful to make the animation per-monitor.
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1326>
Simplify the code a bit. The workspace group is relatively self-contained,
so split it from the general animation. Reimplement _syncStacking().
This will help a lot later, with workspace strip and multi-monitor support.
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1326>
We always request a natural width based on the maximum thumbnail scale,
but may very well use a smaller scale when allocating. This currently
results in thumbnails being off center, fix this by distributing any
extra space evenly before allocating thumbnails.
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1620>
Accessing GObject properties from JS has proven to be quite slow because
of the JS->C->JS roundtrip involved. With the WindowPreview this
actually has an impact since we're accessing those properties very often
while creating new layouts.
So cache the boundingBox and the windowCenter properties of the
WindowPreview using a this._cachedBoundingBox JS object. This might
speed up opening the overview with lots of open windows significantly.
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1617>
Make computeScaleAndSpace() return an array including scale and space so
we no longer have to access the layout object from outside.
With this we also no longer need to set layout.space, since only the
scale property is needed in computeWindowSlots().
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1617>
Start cleaning up the whole mess around the layout object a bit and
return a new object in the LayoutStrategies computeLayout()
implementation. This object is supposed to be opaque to the API user and
will only be passed to the layout strategy.
For now, keep setting a few things on that object from outside, we'll
clean that up later.
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1617>
Only keep computeLayout, computeWindowSlots, computeScaleAndSpace and
the contructor in the superclass, the rest is actually layout specific
and won't apply anymore when we introduce the new vertical layout
strategy.
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1617>
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>
When the original animation was implemented, workspaces would only
ever be added at the end. We therefore got away with not having a
separate EXPANDING stage corresponding to the existing COLLAPSING
one when animating out.
Since support for creating in-between workspaces via DND was added,
this is no longer the case. And now that the thumbnails are centered,
the jump is quite noticeable.
Address this by adding new transitional states, so that we can
expand new thumbnails before scaling them in.
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1609>
Make the slide property control the workspace scale, so that new workspaces
scale up, and destroyed workspaces scale down. The scale is done horizontally,
and only slightly vertically, as per design direction.
Rework the state tracking mechanism to remove the COLLAPSING state, since there's
no split between sliding out and collapsing anymore. Also remove the corresponding
'collapse-fraction' property from WorkspaceThumbnail.
Make ThumbnailsBox.vfunc_get_preferred_width() consider the slide-position property.
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1593>
There are situations where MetaWorkspaceManager and ThumbnailsBox disagree
on the number of workspaces, for example when animating them out. It's more
important to follow the visible number of workspaces while they're updated.
Make vfunc_get_preferred_width() and vfunc_get_preferred_height() use the
current number of workspace thumbnails to calculate their sizes, instead of
MetaWorkspaceManager's n-thumbnails property.
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1593>
ThumbnailsBox currently allocates each workspace thumbnail using their
porthole size, and scales them down using scale-x and scale-y. This is
slightly problematic since it doesn't allow for properly styling these
thumbnails through CSS.
Rework ThumbnailsBox to allocate workspace thumbnails at their actual
sizes, and scale down the '_contents' actor inside WorkspaceThumbnail.
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1593>
Allocate workspace thumbnails horizontally. This requires introducing code
to handle the RTL direction. Do a small rewrite of the DnD hover method to
be simultaneously simpler and easier to follow, and work correctly on RTL.
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1593>
This is now all centralized in the apps page, so move the workspaces
thumbnails to ViewSelector's apps page. This allows us to remove
all the slider controls too, since they're now unused.
The transition between showing the workspaces, and the app grid, is
based on the most recent mockups: scale and move it down, and fade it
out.
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1593>
Now that there's only a ACTIVITIES and a SEARCH page, the old method of handling
keyboard tabbing (extra parameters to ViewSelector._addPage()) limits what we can
do.
Manually set up the Ctrl+Alt+Tab support for each element.
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1593>
Add them both in a StBoxLayout subclass with a vertical layout. This
new ActivitiesContainer class already contains an adjustment controlling
the transition between workspaces and app grid states, and althought it
is internal to it, it'll be easy to integrate with gestures in the
future.
Notice that AppDisplay is added before WorkspacesDisplay. That's because
we want the paint order to paint WorkspacesDisplay on top of AppDisplay.
Switch the ViewsPage enum to call this page ACTIVITIES, and adjust the
only caller in OverviewControls to it. At last, rename '_appsPage' to
'_activitiesPage' to also reflect the name change.
The usefulness of organizing this code in pages is lost here, but this
is a transitional state, and pages will be removed in future changes.
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1593>
Only the area used by favorite apps can be used as drop targets, it
is not possible to add new favorites between the running apps at the
end. While that behavior makes sense, it is currently impossible to
distinguish the two areas with confusing results.
Address this by adding a visual separator between favorites and
running apps.
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1606>
WokspacesDisplay simply remaps the scroll direction into the next
workspace, but that doesn't account for the new horizontal layout.
Scroll horizontally on horizontal layouts when scroll direction is
on the vertical axis.
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1603>
The scroll adjustment's upper value corresponds to the number of
workspaces, not to the last workspace index. We want the latter
when mirroring the layout in RTL locales, so subtract 1.
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1598>
Now that apps either appear in the dash or the app grid, it makes
sense to allow DND between the two components to add and remove
favorites.
Currently this only works for adding items to the dash, update the
app grid code to also accept drops from the dash.
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1594>
We use a custom actor to make sure that the show-apps button remains
visible even when there's not enough space to show all icons.
We can achieve the same result with much less code, by using a custom
BoxLayout layout manager for the icons to override the minimum width.
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1592>
With the transparent top bar in the overview, constraining to the
primary monitor's workarea causes the (now visible) area beneath
the top bar to not have the darker background, which causes a visual
discontinuity in the layout.
Don't constrain to the primary monitor workarea.
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1590>
The code previously was using CSS to define row/column spacing and
padding which was combined with a subicon size computed in code relative
to the requested icon size.
In smaller icon sizes it was possible for the CSS spacing+padding + the
size of the two subicons to exceed the requested icon size. This then
would lead to the label being pushed down for app folders compared to
other icons.
Another more severe issue caused by this would happen if the first item
in an icon grid was an app folder. Then the calculation for the maximum
allowed icon size could be off, leading to all icons in the grid
becoming smaller than actually necessary.
This commit changes this to use homogeneous row and column layouts to
evenly distribute the remaining spacing instead of using a fixed CSS
value.
Fixes https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/3069
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1581>