Compare commits

...

346 Commits

Author SHA1 Message Date
Alexander Mikhaylenko
b1afb946b2 workspaceAnimation: Support multiple monitors
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

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/605
2020-02-26 10:36:10 +01:00
Alexander Mikhaylenko
46d5bccfc6 workspaceAnimation: Use window clones
Instead of reparenting windows, clone them. This will allow to properly
support multi-monitor setups in subsequent commits.

Block window mapping animation while the animation is running to prevent
new windows appearing during the animation from being visible at the same
time as their clones.

Fixes https://gitlab.gnome.org/GNOME/mutter/issues/929

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/605
2020-02-26 10:36:10 +01:00
Alexander Mikhaylenko
f0d498062d workspaceAnimation: Only create moving window bin when needed
https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/605
2020-02-26 10:36:10 +01:00
Alexander Mikhaylenko
eeac4a3b6d workspaceAnimation: Extract WorkspaceGroup
Reimplement _syncStacking().

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/605
2020-02-26 10:36:10 +01:00
Alexander Mikhaylenko
272cb4d523 workspaceAnimation: Extract WorkspaceAnimation
Simplify the logic a bit. Introduce WorkspaceAnimation class that reparents
the windows from current, surrounding and destination workspaces and manages
them. Expose 'progress' property and have WorkspaceAnimationController animate
it instead of animating everything separately.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/605
2020-02-26 10:36:10 +01:00
Alexander Mikhaylenko
6d5446e4a6 workspaceAnimation: Stop depending on shellwm
https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/605
2020-02-26 10:36:10 +01:00
Alexander Mikhaylenko
fa31bcaa7a workspaceAnimation: Split from WindowManager
It's already too complex, and will get more complex in future, split it
out.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/605
2020-02-26 10:36:10 +01:00
Daniel van Vugt
c773c8c162 Revert "js/ui: Use Clutter.OffscreenRedirect.ON_IDLE"
This reverts commit c0c027c608. Because for
some reason animating external opacity and position is still incurring
internal repaints, which disables offscreening and makes fading of
overlapping actors look wrong. `ON_IDLE` should be fixed in mutter before
it is used (in boxpointer at least) again.

Fixes https://gitlab.gnome.org/GNOME/gnome-shell/issues/2270
2020-02-26 11:54:54 +08:00
Florian Müllner
9a3ed0056e ci: Adjust URL check
While the old merge request URLs still work, gitlab recently started
including an additional /- for merge requests.

Adjust the regex to account for that, so that simply copying the URL
from gitlab works again.

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1048
2020-02-26 00:24:14 +01:00
Jonas Dreßler
b3999e4078 overview: Hide the overview on session mode hasOverview changes
If the sessionMode does not allow to show the overview, we should also
hide an already visible overview.

This fixes a bug where, if the lockscreen was shown while the overview
was visible, the Ctrl+Alt+Tab popup would allow navigating inside the
overview because the overview actor is still mapped.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/1043
2020-02-25 20:10:22 +01:00
Philippe Troin
d0a587d42f panel: Only consider St.Widgets for corner buttons
We cannot syncronize styles with plain Clutter.Actors, so don't return
them when looking for corner buttons.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/1047
2020-02-25 18:32:30 +00:00
Florian Müllner
2bb8e1be9b environment: Handle reversed transition with 0 duration
If a transition is reversed, the final property values will be the
same as before the transition. However this currently only works
correctly when we actually use a transition; to fix this with a
duration of 0, simply skip the set() call when the transition is
reversed.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/1042
2020-02-25 18:08:47 +00:00
Sam Hewitt
967a6ae44d sass: use relative values for user-icon
https://gitlab.gnome.org/GNOME/gnome-shell/issues/2242
2020-02-25 17:56:19 +01:00
Florian Müllner
89ca5e71d4 theme: Fix horizontal default user widget
Commit 6c6c89c634 added a pill around the default avatar, but
assumed the sizes from the vertical widget used on the lock screen.

In order to fix the horizontal widget on the login screen, move the
size-specific bits to the corresponding .horizontal and .vertical
sections, and half the sizes for the former (which corelates with
the icon sizes).

https://gitlab.gnome.org/GNOME/gnome-shell/issues/2242
2020-02-25 17:56:19 +01:00
Jonas Dreßler
4c4d23ed83 dateMenu: Sync initial state of the message indicator
While the unread messages indicator is updated when starting a new
session because we call _onSourceAdded() on existing sources, we should
also update the do-not-disturb setting which might still be enabled.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/1037
2020-02-25 16:47:29 +01:00
Jonas Dreßler
7173ec1df7 dateMenu: Remove an unnecessary change for RTL layouts
Calculating 1 - 0.5 is rather useless if the value was 0.5 before...

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/1037
2020-02-25 16:47:24 +01:00
Jonas Dreßler
bc465ab006 theme: Hide panel underline under the do not disturb icon
Hide the focused/active indicator of the panel underneath the
do-not-disturb icon.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/1037
2020-02-25 16:47:17 +01:00
Jonas Dreßler
fe4973b585 theme/message-list: Increase spacing for do-not-disturb enable-button
https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/1037
2020-02-25 16:47:12 +01:00
Jakub Steiner
0d0384ebb1 theme: sync toggle-off-dark with gtk
- improve contrast

Fixes https://gitlab.gnome.org/GNOME/gnome-shell/issues/2157
2020-02-25 13:47:01 +01:00
Balázs Úr
27ef8eb9a0 Update Hungarian translation 2020-02-25 06:26:27 +00:00
Christian Hergert
24a3fd4c4d st: implement ClutterActorClass.has_accessible()
Implement ClutterActorClass.has_accessible() to ensure that CallyActor does not
recreate accessibles during the removal/destruction of an actor.  This relies
on GNOME/mutter!1083 for the ClutterActorClass.has_accessible virtual function.

Running GNOME Shell for about 30 seconds results in a difference between
the two runs.

Before:

    ALLOCATED      TOTAL    FUNCTION
[   52.2 KiB] [   0.05%]    cally_actor_real_remove_actor
[   36.3 KiB] [   0.04%]      st_widget_get_accessible
[    9.8 KiB] [   0.01%]      atk_gobject_accessible_for_object
[    3.2 KiB] [   0.00%]      g_signal_emit_by_name
[    2.9 KiB] [   0.00%]      clutter_actor_get_children

After:

    ALLOCATED      TOTAL    FUNCTION
[    1.8 KiB] [   0.00%]    cally_actor_real_remove_actor
[    1.1 KiB] [   0.00%]      clutter_actor_get_children
[  659 bytes] [   0.00%]      g_signal_emit_by_name

Obviously 50KiB isn't a huge savings.

Although fixing things to avoid re-entrancy on destruction can be very useful
from a correctness standpoint.

Fixes https://gitlab.gnome.org/GNOME/gnome-shell/issues/2263
2020-02-24 22:20:26 +00:00
Alan Mortensen
d9f8e04478 Updated Danish translation 2020-02-24 22:40:32 +01:00
Emin Tufan Çetin
b9f6032ddd Update Turkish translation 2020-02-24 15:08:21 +00:00
Florian Müllner
d62391c8f1 unlockDialog: Set accessible name of icon-only buttons
We turned both the auth prompt's cancel button and the switch user
button into icon buttons now, which means they are completely cryptic
when using a screen reader.

Just use the previously used labels as accessible names, which has the
nice side effect of lowering the impact of the string freeze break.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/2210
2020-02-24 12:29:44 +00:00
Florian Müllner
ab24ee7a7e authPrompt: Don't focus hidden cancelButton
The button is hidden on the lock screen, so it shouldn't be allowed to
activate it, be it via click or keyboard. The latter is still possible
by keynaving to the button and hitting space/enter. Fix that by making
the button unfocusable when we make it unreactive.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/2210
2020-02-24 12:29:44 +00:00
Florian Müllner
c52fd9373c unlockDialog: Turn mainBox into an St.Widget
This is the container that contains the elements that are interesting
for keynav, so it must be aware of focus-chain and -navigation.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/2210
2020-02-24 12:29:44 +00:00
Florian Müllner
1249655d0a unlockDialog: Don't make dialog focusable
There is little point in focusing the dialog itself, we want keynav
to navigate inside instead and navigate between focusable children.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/2210
2020-02-24 12:29:44 +00:00
Florian Müllner
120b907c33 shell/stack: Ignore hidden children for focus navigation
ShellStack implements custom focus navigation, and will only ever
navigate into its top-most child. That kind of makes sense as long
as that child is actually visible, but not when it is hidden.

Descend into the stack to look for a focusable child instead.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/2210
2020-02-24 12:29:44 +00:00
Jonas Dreßler
3848513cf4 magnifier: Use inhibit-unfocus API to keep wayland focus while hidden
Since commit mutter/a2a8f0cda we force the focus surface of the
meta-wayland-pointer to NULL while the pointer is hidden. This
introduced an issue with the magnifier, where we use
`set_pointer_visible` to hide the real cursor and show our own cursor at
the correct position: Because the meta-wayland-pointer is still used to
communicate with Wayland clients, the UI of the windows will not respond
to mouse movement anymore as soon as the real cursor is hidden.

To fix this, use the newly added clutter_seat_inhibit_unfocus() API to
temporarily disable unsetting the focus-surface while the magnifier is
hiding the system cursor.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/993
2020-02-24 10:31:08 +00:00
Jonas Dreßler
725c72e020 magnifier: Use own showSystemCursor() instead of set_pointer_visible()
We already have our own function to show the system cursor, use it!

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/993
2020-02-24 10:31:08 +00:00
Bruce Cowan
0b113094b4 Update British English translation 2020-02-23 12:50:32 +00:00
Florian Müllner
3633e1feca shellEntry: Restore natural-height-set instead of forcing it
If we are transitioning the label from 0 to its natural height, we
must set natural-height-set again after querying the preferred height,
otherwise Clutter would skip the transition.

However when transitioning in the opposite direction, setting the
property to true can go horribly wrong:
If the actor hasn't been allocated before, it will store a fixed
natural height of 0. But as there is no fixed min-height, we can
end up with min-height > natural-height, which is a fatal error.

(This isn't an issue when *actually* setting a fixed height, as
that will set both natural and minimum height)

So instead of always setting natural-height-set to true, restore
its previous value to fix the issue.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/2255
2020-02-22 16:58:01 +00:00
Florian Müllner
4759197200 util: Don't wiggle when animations are disabled
repeatCount and autoReverse don't play well with animations disabled:
They cause password entries to wiggle themselves off-screen (by ending
up with some off-scale translation-x value).

While we should handle this more gracefully in the transition helpers,
it also makes sense to handle the case directly in wiggle(): As it
uses a chain of three transitions, we would still end up with a crude
one-frame-per-transition wiggle "animation".

Instead, do no animation at all as you would expect when animations are
disabled.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/2236
2020-02-22 16:38:43 +00:00
Jor Teron
1d39afabdc Update Karbi translation 2020-02-22 16:15:07 +00:00
Jiri Grönroos
483607311c Update Finnish translation 2020-02-22 15:35:39 +00:00
Charles Monzat
d90a79fe7a Update French translation 2020-02-22 14:12:42 +00:00
Changwoo Ryu
87ed0118d1 Update Korean translation 2020-02-22 10:46:09 +00:00
sicklylife
1f5eccbc70 Update Japanese translation 2020-02-21 22:13:34 +00:00
sicklylife
dac2274993 Update Japanese translation 2020-02-21 17:52:09 +00:00
sicklylife
39db86e755 Update Japanese translation 2020-02-21 17:49:02 +00:00
Jonas Dreßler
255627bd69 layout: Show and hide keyboard using translation_y
ClutterActors anchor-y property is deprecated, which means we get a
warning when animating it, so use the translation property instead to
show or hide the osk.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/1039
2020-02-21 12:59:21 +00:00
Florian Müllner
0afac36713 unlockDialog: Use "normal" background
Now that we apply a strong blur effect to the background, it doesn't
make too much sense to use a separate lock-screen background: It will
be mostly unrecognizable anyway.

The alternative would be to turn off the blur effect if a different
background is used (or have a hidden setting for that), but that would
then imply that we must keep the contents readable without blur.

Let's avoid that rabbit hole and just re-use the regular background.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/1001
2020-02-21 12:34:37 +00:00
Daniel van Vugt
c0c027c608 js/ui: Use Clutter.OffscreenRedirect.ON_IDLE
To bypass offscreening in cases where continuous animation is happening.
Offscreening is slower in such cases so this reduces the render time of
animations within offscreenable actors.

On an i7-7700 this reduces the render time of boxpointers for example by
25-30%.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/1025
2020-02-21 12:19:15 +00:00
Марко Костић
e938986a74 Update Serbian translation 2020-02-21 09:51:32 +00:00
Jonas Ådahl
32fa060a62 closeDialog: Make dialog inactive while fading out
Otherwise the user might click Kill, which would crash if the fade-out
was triggered because a Wayland window was closed.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/1032
2020-02-21 08:11:57 +00:00
Daniel van Vugt
38da479ee8 slider: Calculate handle position in whole pixel units
`-slider-handle-radius` is a floating point value and even in the default
theme it's not a whole number. Regardless of the fractional part that's
still going to occupy a whole extra pixel with antialiasing. So make room
for it. Otherwise it looks clipped, which it is by the Cairo context of
its `StDrawingArea`.

Fixes https://gitlab.gnome.org/GNOME/gnome-shell/issues/1569
2020-02-21 11:29:09 +08:00
Florian Müllner
574ab04e9f st/texture-cache: Heap-allocate saved scales
Otherwise we end up reading random junk later, with the result that
we fail to evict textures with scaled keys.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/2244
2020-02-20 23:06:58 +01:00
Florian Müllner
ee6635282c status/keyboard: Check for monkey-patched property before using it
This avoid another "reference to undefined property" warning.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/1035
2020-02-20 19:08:47 +00:00
Florian Müllner
ff39b3274b authPrompt: Initialize property in _init()
This avoid a "reference to undefined property" warning when using
it in a comparison.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/1035
2020-02-20 19:08:47 +00:00
sicklylife
2c1d654035 Update Japanese translation 2020-02-20 18:04:30 +00:00
sicklylife
1bdb065ffa Update Japanese translation 2020-02-20 18:01:09 +00:00
Carlos Garnacho
57669bca1b keyboard: Specify symbolic icons to use in default keys
The style classes are not removed yet, might make sense to do that
if they don't bring anything wrt theming.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/2214
2020-02-20 11:34:07 +00:00
Carlos Garnacho
e647ceb4d1 theme: Update theming of special OSK keys
The icons in those are no longer assets, but symbolic icons.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/2214
2020-02-20 11:34:07 +00:00
Carlos Garnacho
4d9e84f6f7 data: Add OSK assets as symbolic icons
Courtesy of jimmac/snwh

https://gitlab.gnome.org/GNOME/gnome-shell/issues/2214
2020-02-20 11:34:07 +00:00
Carlos Garnacho
5171bdd45f keyboard: Add support for setting OSK keys with icons
Unused at the moment, but add the plumbing so that default key
definitions may specify symbolic icons that will be shown instead
of the text.

This is intended to replace the use of CSS and background-image
to handle those buttons with an icon.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/2214
2020-02-20 11:34:07 +00:00
Jonas Ådahl
9ab0071aa5 introspect: Add AnimationsEnabled property
While the gsetting is available for all who needs it, the Shell might
override it given various hueristics. Expose the decision made by the
Shell via a new property.

Intended to be used by gsd-xsettings as well as xdg-desktop-portal-gtk.

This also add a version property to the API, so that semi external
services (xdg-desktop-portal-gtk) can detect what API is expected to be
present.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/757
2020-02-20 11:14:55 +00:00
Jonas Ådahl
cf39b2db87 introspect: Rename variable
It was too generic, and would conflict with a StSettings variable.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/757
2020-02-20 11:14:55 +00:00
Jonas Ådahl
8a1c0f3a42 main: Inhibit animations when there is a remote desktop session
If a remote desktop session asks for animations to be disabled, inhibit
animations while the session is active.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/757
2020-02-20 11:14:55 +00:00
Jonas Ådahl
4b42879a2c main: Inhibit animations if X server advertises VNC-EXTENSION
This was previously done by gsd-xsettings to disable animations when
running in Xvnc.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/757
2020-02-20 11:14:55 +00:00
Jonas Ådahl
394121f77d main: Inhibit animations when software rendered
This was previously decided by gsd-xsettings.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/757
2020-02-20 11:14:55 +00:00
Jonas Ådahl
f4f8982825 st/settings: Add API to inhibit animations
There may be situations where we shouldn't enable animations. Make it
possible for the Shell to decide when there are such situations and in
when needed inhibit animations.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/757
2020-02-20 11:14:55 +00:00
Jonas Ådahl
7220f6d25b shell-util: Add API to check for X11 extensions
Will be used to disable animations when running inside Xvnc. This was
done in gsd-xsettings before.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/757
2020-02-20 11:14:55 +00:00
Jonas Ådahl
059fb5c7cb introspect: Add helper to check method call permission
https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/757
2020-02-20 11:14:55 +00:00
Rafael Fontenelle
0057c19bfc Update Brazilian Portuguese translation 2020-02-20 10:54:02 +00:00
Asier Sarasua Garmendia
05409b949f Update Basque translation 2020-02-19 19:21:09 +00:00
Florian Müllner
affbec73ef extensionPrefs: Fix more fallout from un-templating strings
The version field in extension metadata is a number, so we cannot
just use it as a string.

('creator' should be fine, but change it as well for the symmetry)

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/1031
2020-02-19 19:29:21 +01:00
Daniel van Vugt
e781e1fdba iconGrid: Create icon clones in a separate loop
For reasons not yet fully understood, `Main.uiGroup.add_actor` takes around
10 milliseconds to complete.

Because of this, each `actor.opacity = 0` has a good chance of falling
on a different frame. And when it does, `_opacityChangedId` also lands
on multiple different frames each incurring a separate relayout cycle.
It is this excessive number of relayouts that causes stuttering in the
icon grid animation (#2065). But it is the slowness of `uiGroup.add_actor`
that causes the number to be excessive when it should be one.

By creating the clones and adding them to `uiGroup` early, we then enable
the existing loop starting the animation to complete within a single frame.
And by completing within a single frame all the opacity changes land within
the same frame interval, thus incurring only a single relayout instead of
many.

This issue went unnoticed until 004a5e1042 (!704), after which the slow
emissions of `notify::opacity` became a more visible performance problem.

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

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/1002
2020-02-19 15:39:21 +00:00
Jonas Dreßler
12de4e67f8 theme: Fix workspace switcher popup box size
This should be the last fallout from the theme refresh, make sure all
the boxes of the workspace switcher popup are the correct size.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/1022
2020-02-19 14:07:36 +00:00
Jonas Dreßler
9201701c95 theme: Make the focus state of buttons a bit more visible
This changed with the theme refactor was probably not intended, so make
the border on key-focused buttons a bit less transparent to make it
easier to see.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/1022
2020-02-19 14:07:36 +00:00
Florian Müllner
6e7344b837 dateMenu: Use BindConstraint for indicator pad
Now that Clutter.BindConstraint modifies the size request in addition to
the allocation, we can use it instead of the custom IndicatorPad widget.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/1026
2020-02-19 12:44:28 +00:00
Georges Basile Stavracas Neto
b8f8e1710b appDisplay: Remove unnecessary bind constraint
Now that the bind constraint changes the preferred size of
the actor, a major flaw in the AppDisplay code was exposed:
the folder dialog depends on the preferred size of a parent,
and the parent depends on the preferred size of the folder
dialog.

While we know this is not actually true, we shouldn't rely
on broken behavior to achieve this result. What's interesting
is that the bind constraint used by the folder dialog is a
relic of the development phase; we now control the position
and size of the dialog with a combination of CSS, and alignment.

Remove the unnecessary bind constraint.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/1027
2020-02-19 09:20:05 -03:00
Jonas Dreßler
8b0a67fe64 dateMenu: Hide overlay scrollbar in the notification popup
Since the design of the notification popup changed with the theme
refactor and there are now boxes around the world-clock and weather
sections, the overlay scrollbar that is shown above them looks rather
bad. So simply hide that scrollbar, we still have the vfade effect to
indicate the container is scrollable and we also depend on that in the
new popup app-folders.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/1013
2020-02-19 11:47:04 +00:00
Florian Müllner
1eb1b1be4e theme: Drop fixed auth prompt entry width
We already set a fixed width on the parent, so simply let the entry take
up the available space that isn't used by the surrounding elements.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/1021
2020-02-19 12:34:29 +01:00
Feichtmeier
de5a4a98c9 Style looking-glass $variant independant
- use osd colors
- also fix the toolbar buttons jumping on click
- adding better unchecked/hover/checkedifferences
- use $link_color for links
- remove the strong text-shadow

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/1023
2020-02-19 11:08:23 +00:00
Jonas Dreßler
26a49168ba lookingGlass: Also handle null objects in objectToString
Whoops, while ff4623454 fixed the handling of `undefined` objects,
`null` objects obviously still don't have a toString() method. So also
handle those and return 'null' in case the object is null.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/1024
2020-02-19 11:56:36 +01:00
Florian Müllner
ff4623454f lookingGlass: Handle undefined in objectToString()
Fallout from commit 9d941f8202: Template strings handle undefined
values just fine, the replacement does not. Fix that.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/1020
2020-02-19 11:17:17 +01:00
Jonas Dreßler
cf5204760d workspace: Ensure style of window-chrome titles before requesting width
Make sure the stylesheet properties of the window-chrome title are
updated before requesting the preferred width of the title to prevent
size changes of the title after we animated the width.

Fixes https://gitlab.gnome.org/GNOME/gnome-shell/issues/58
2020-02-19 10:09:20 +00:00
Chao-Hsiung Liao
46c13349fc Update Chinese (Taiwan) translation 2020-02-19 06:37:20 +00:00
Jonas Dreßler
2a3875775d userWidget: Always set actor size inside update()
We also want to ensure the Avatar StBin is sized correctly when an icon
child is used, so always set the actor size inside the `update()`
function.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/1018
2020-02-18 22:10:00 +00:00
Jonas Dreßler
38b38732d3 userWidget: Simplify icon size setting a bit
Remove the default icon size of -1 and always set the container StBin to
a real size. This fixes an error where the "width" and "height"
properties get set to -2 (which is -1 * scaleFactor) in the `_init`
function.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/1018
2020-02-18 22:10:00 +00:00
Florian Müllner
24c8f5bb70 authPrompt: Fix cancel button visibility
Grrr, this slipped in in 5cad5c20e9, and we don't have a compiler
to catch those kinds of bugs :-(

https://gitlab.gnome.org/GNOME/gnome-shell/issues/2228
2020-02-18 21:34:16 +00:00
Anders Jonsson
c02296a9b9 Update Swedish translation 2020-02-18 21:02:42 +00:00
Jordi Mas
4eb122ea8d Update Catalan translation 2020-02-18 20:48:36 +01:00
Piotr Drąg
90d5d16343 Update Polish translation 2020-02-18 19:11:08 +01:00
sicklylife
45c8f0b76c Update Japanese translation 2020-02-18 16:52:19 +00:00
sicklylife
236ee9e483 Update Japanese translation 2020-02-18 16:50:36 +00:00
Sabri Ünal
459b200cc0 Update Turkish translation 2020-02-18 16:18:59 +00:00
Jonas Dreßler
45bc8ae292 keyboard: Plug a leak of KeyboardControllers
To make sure the GC really disposes the KeyboardController object we
need to remove all references to the object, which means we have to
disconnect signals the object connects to, too.

This also fixes a bug where keys remain pressed forever and thus also
break that key on real keyboards. It happens if the OSK gets destroyed
during an OSK-key is being held so the StButton of the key is not
released. That means the key remains pressed in the
MetaVirtualInputDevice that we are now leaking because
KeyboardController isn't garbage collected.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/1015
2020-02-18 14:48:39 +00:00
Daniel Mustieles
fbfe5a1988 Updated Spanish translation 2020-02-18 13:19:54 +01:00
Efstathios Iosifidis
87a6dc1b95 Update Greek translation 2020-02-18 10:55:34 +00:00
Danial Behzadi
1b11f0673e Update Persian translation 2020-02-18 07:23:20 +00:00
Florian Müllner
3a4dd55c11 Bump version to 3.35.91
Update NEWS.
2020-02-18 00:14:32 +01:00
Balázs Úr
1219a304fb Update Hungarian translation 2020-02-17 23:11:43 +00:00
Florian Müllner
9d941f8202 js: Don't use templates in files with translations
xgettext gained some support for template strings, and no longer
fails when encountering '/' somewhere between backticks.

Unfortunately its support is still buggy as hell, and it is now
silently dropping translatable strings, yay. I hate making the
code worse, but until xgettext really gets its shit together,
the only viable way forward seems to be to not use template
strings in any files listed in POTFILES.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/1014
2020-02-17 23:20:40 +01:00
Balázs Úr
0c232876c3 Update Hungarian translation 2020-02-17 21:51:47 +00:00
Jonas Dreßler
dcbc7236a0 theme: Remove two unneeded css classes
https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/1012
2020-02-17 21:42:05 +00:00
Jonas Dreßler
80a869e768 dialogs: Use a smaller font-size if the title width exceeds the space
Since quite a few strings of dialogs provided by external programs are
not updated yet and the string freeze is already in effect, make sure we
don't break those dialogs by stripping aways large parts of the
headline.

To do that, detect if the title label is larger than the available width
and if it is, switch to a smaller font-size of 13pt. This makes sure we
still show about the same number of characters in the headline as we did
in previous releases.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/1012
2020-02-17 21:42:05 +00:00
Fran Dieguez
b7d874d36b Update Galician translation 2020-02-17 21:00:11 +00:00
Aurimas Černius
9f9f4a4cf6 Updated Lithuanian translation 2020-02-17 22:38:40 +02:00
Марко Костић
217a2f3216 Update Serbian translation 2020-02-17 20:03:11 +00:00
Charles Monzat
84e94db275 Update French translation 2020-02-17 17:44:38 +00:00
Piotr Drąg
5f2a6003e1 Update Polish translation 2020-02-17 17:23:04 +01:00
Daniel Mustieles
2876a8afe1 Updated Spanish translation 2020-02-17 14:55:24 +01:00
Florian Müllner
6f12864776 screenShield: Always deactivate when interrupting idle before lock
With the old screen shield, we were simply hiding the lightboxes to show
the shield when the user became active after activating the shield but
before locking the screen (that is, when using a lock-delay).

However now that the shield is gone, we end up showing the unlock dialog
even though we are not actually locked.

We probably don't want to add back a shield-like mode (that is, a way to
raise the unlock dialog without authentication when we aren't locked),
so just deactivate the whole shield when the user becomes active again
before the lock kicks in.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/2213
2020-02-17 11:13:34 +00:00
Florian Müllner
5934dc16d3 screenShield: Reset correct translation
When showing the lock dialog without animation, we currently reset the
translation of the wrong actor, leaving the unlock dialog off-screen.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/2213
2020-02-17 11:13:34 +00:00
Jonas Dreßler
bcc652632d authPrompt: Use the same hint text as the polkitDialog for the password
Be consistent and show the hint for the password entry that we already
show in the polkitDialog in the auth dialog.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/977
2020-02-17 11:03:07 +00:00
Jonas Dreßler
95ebbb9360 Update hint texts of all entries
The design team discussed the ellipses at the end of the hint text of
our entries and, even though they are present in most mockups, it turned
out they don't like them, so remove them.

It also turned out they don't like the prefixes like "Enter" before it,
so remove those, too.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/977
2020-02-17 11:03:07 +00:00
Jonas Dreßler
775c3345eb networkAgent: Update dialog entry descriptions for new design
With the new dialog design the descriptions of entries are now
implemented as hint-text of the StEntry. That means the colon at the end
of the descriptions no longer makes sense and should be removed.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/977
2020-02-17 11:03:07 +00:00
Jordi Mas
c8734b8f35 Update Catalan translation 2020-02-15 18:38:10 +01:00
Piotr Drąg
9f2dbfd463 Update Polish translation 2020-02-15 14:15:47 +01:00
Jakub Steiner
d6c0a53db9 theme: submenu separator size
- match width of the submenu separators to the parents

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/1004
2020-02-15 00:16:45 +00:00
Florian Müllner
9c7098816e popupMenu: Remove excess padding from separators
Currently separators get all the padding from regular menu items,
which is excessive for non-interactive elements.

Shuffle style classes around a bit to allow overriding the normal
padding for separators.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/1004
2020-02-15 00:16:45 +00:00
Florian Müllner
8834088f3b unlock: Don't show prompt on shifty key presses
Shift, caps-lock and friends change the capitalization of following
key presses. It is unexpected for those keys to have side-effects,
so don't switch to the prompt when they are pressed.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/2215
2020-02-14 21:57:03 +01:00
Florian Müllner
0d766dcf70 authPrompt: Use placeholder label to avoid layout changes
We don't want to show a caps-lock warning when showing a non-password
entry, but we also don't want the layout to jump when changing the
label's visibility.

Achieve that by inserting an empty placeholder label that we can
show whenever the caps-lock warning is hidden.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/2215
2020-02-14 21:57:03 +01:00
Florian Müllner
41da4b0681 Revert "authPrompt: Don't hide the caps lock warning label"
Using the opacity to control the label's visibility doesn't work
correctly, as CapsLockWarning itself changes the opacity when
the caps-lock state changes.

This reverts commit 9f5f6aa9b2.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/2215
2020-02-14 21:57:03 +01:00
Georges Basile Stavracas Neto
5cad5c20e9 authPrompt: Hide cancel button on unlock screen
As per the latest design review, hide the cancel button
on the unlock dialog.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/1006
2020-02-14 20:49:57 +00:00
Georges Basile Stavracas Neto
133b623204 unlockDialog: Iconize the switch user button
Make it look exactly the same as the login screen's session
selection button.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/1006
2020-02-14 20:49:57 +00:00
Georges Basile Stavracas Neto
d44a4a6a62 unlockDialog: Move switch user to the main dialog
Right now, it's still a label displayed following the same
layout algorithm of the cog button in the login screen. It'll
become a button later in the patchset.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/1006
2020-02-14 20:49:57 +00:00
Georges Basile Stavracas Neto
06565542e7 Revert "unlockDialog: Remove 'Login as another user' Label"
This reverts commit c6a79fafc. The back button doesn't really work
as a replacement for going back to the login screen.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/1006
2020-02-14 20:49:57 +00:00
sicklylife
ead73e5195 Update Japanese translation 2020-02-14 20:28:14 +00:00
sicklylife
c395a1d1cd Update Japanese translation 2020-02-14 20:20:28 +00:00
Fran Dieguez
4f1174ccbb Update Galician translation 2020-02-14 20:09:57 +00:00
Jakub Steiner
b78f09de78 theme: fix submenu separator contrast
Fixes https://gitlab.gnome.org/GNOME/gnome-shell/issues/2203
2020-02-14 17:31:57 +00:00
Jakub Steiner
9eff9adaae theme: Lock screen notification style tweaks
- use standard border radius for notifications
- negative space pills for counters
- no border, slightly less opaque background allowed
  by the massive blur radius for the wallpaper

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/998
2020-02-14 16:45:24 +00:00
Florian Müllner
41b4c51341 unlockDialog: Don't explicitly show prompt
The promptBox is initially fully opaque, so showing it before the
transition can result in a brief flash before fading in.

Just remove the show() call and let the transition handle the
visibility.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/2212
2020-02-14 14:56:25 +01:00
Марко Костић
9bada1f2fb Update Serbian translation 2020-02-14 12:02:49 +00:00
Georges Basile Stavracas Neto
7e27a2db3d authPrompt: Keep password entry on reset
Usually, logging in or unlocking the session is made asynchronously,
and AuthPrompt properly manages which entry is currently visible.
External code don't rely on any specific entry to be set, since it
is AuthPrompt's responsibility to select the correct one to be shown.

However, there's one specific case where AuthPrompt must preserve
the password entry: on reset. The reset code preserved whatever
entry was currently displayed, but after fe69dacaf1, it always
changes to the username entry.

Make sure to show the password entry on reset.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/999
2020-02-13 18:11:16 -03:00
Georges Basile Stavracas Neto
523eec521c unlockDialog: Only create GDM client once
We don't need to create a new one every time we create an
auth prompt.

Create only one GDM client.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/999
2020-02-13 18:11:09 -03:00
Georges Basile Stavracas Neto
77890c6000 loginDialog: Hide session menu button when showing the user list
In the past, the session menu button was part of the auth prompt widgetry,
so we didn't have to manually hide it when showing the user list. However,
now it is part of the login screen itself.

Hide the session menu button when the user list is shown.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/999
2020-02-13 18:11:05 -03:00
Anders Jonsson
40a50f77ea Update Swedish translation 2020-02-13 20:19:14 +00:00
Florian Müllner
ccc64e2621 unlockDialog: Only show count for multiple notifications
In the common case where we only have a single unread notification
from a particular app, the count doesn't add useful information.
Reduce clutter a bit by only showing the notification count if we
have at least two.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/997
2020-02-13 20:55:33 +01:00
Jakub Steiner
b58eaeb3e7 theme: revert OSD style to be $variant independent
- make OSD dark on bth dark and light variants
- make top bar black in both cases (classic has specific panel styling).

Fixes https://gitlab.gnome.org/GNOME/gnome-shell/issues/2194
2020-02-13 19:46:29 +00:00
nana-4
e206e3ba59 theme: Move .workspace-thumbnail* into _workspace-thumbnails.scss
While workspace switcher is an OSD, workspace pager is an overview
panel. So it makes more sense to separate them into different
stylesheets.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/938
2020-02-13 19:46:29 +00:00
nana-4
71ec81cff7 theme: Move .candidate-popup-boxpointer into _ibus-popup.scss
It's used only for ibus popup.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/938
2020-02-13 19:46:29 +00:00
nana-4
37adbf610d theme: Move .headline into _dialogs.scss
It's used only in dialogs so far.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/938
2020-02-13 19:46:29 +00:00
nana-4
6ed3d3d05d theme: Move .url-highlighter into _message-list.scss
It's used only in messages.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/938
2020-02-13 19:46:29 +00:00
nana-4
c023eba22c theme: Move switcher-related selectors into _switcher-popup.scss
https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/938
2020-02-13 19:46:29 +00:00
nana-4
c7fb61984b theme: Rename _app-switcher.scss to _switcher-popup.scss
Since the main classes in that file are not dedicated to the app
switcher, rename it to something more appropriate.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/938
2020-02-13 19:46:29 +00:00
nana-4
65b1e04f13 theme: Move accessibility-related selectors into _a11y.scss
Since we have several accessibility-related selectors, it makes sense
to collect them in one stylesheet.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/938
2020-02-13 19:46:29 +00:00
nana-4
90786509bb theme: Move basic selectors into _base.scss
.shell-link, .lowres-icon and .icon-dropshadow could be used globally.

For the icon shadow classes, they're used by officially supported
extensions.[1]

[1] https://gitlab.gnome.org/GNOME/gnome-shell-extensions/issues/168

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/938
2020-02-13 19:46:29 +00:00
nana-4
ebaf969a05 theme: Import widget stylesheets in a reasonable order
Instead of alphabetical ordering, sort the widget stylesheets
from more global to more local while grouping related things.

This helps reduce unintended behaviors and ugly overrides and
make styling and debugging easier.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/938
2020-02-13 19:46:29 +00:00
Emin Tufan Çetin
d2a62bcc7f Update Turkish translation 2020-02-13 19:07:53 +00:00
Ask Hjorth Larsen
66a8f2860d Updated Danish translation 2020-02-13 19:26:55 +01:00
Claude Paroz
d96131793a Update French translation 2020-02-13 17:34:04 +00:00
Jakub Steiner
6c6c89c634 theme: default avatar should remain being a pill
- force size due to the necessary whitespace/padding being added to the dimensions
- use osd FG color for background as it's $variant independednt

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/996
2020-02-13 15:51:46 +00:00
Florian Müllner
e57768e2e8 unlockDialog: Show unlock hint on inactivity
Inactivity on the unlock screen can be an indication that the user
doesn't know how to get to the auth prompt. Fade in a small hint
that points them in the right direction.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/972
2020-02-13 15:01:25 +00:00
Florian Müllner
d43401cc74 unlockDialog: Support clock/prompt switching via scrolling
SwipeTracker "only" handles touch gestures and smooth scrolling.
Scrolling still makes sense for regular mice as well though, so
add handling for that as well.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/972
2020-02-13 15:01:25 +00:00
Florian Müllner
9e5071849c unlockDialog: Add swipe gesture
Clicking or typing to reveal the auth prompt are good options for
mouse/keyboard workflows, but awkward on touch devices. Now that
we have SwipeTracker, adding corresponding gestures support is
easy, so do just that.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/972
2020-02-13 15:01:25 +00:00
Florian Müllner
55bfc4d820 unlockDialog: Use adjustment to control the transition
Tying the transition parameters to a single progress value represented
by an adjustment will enable us to implement stick-to-content swipe
gestures.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/972
2020-02-13 15:01:25 +00:00
Florian Müllner
6577a295da unlockDialog: Tweak transition animation
The current transition between clock and auth prompt uses a simple
crossfade.

"What kind of spatial model is that?!"
                                  T.B.

Root the transition a bit more by adding translation and scale to
the animation.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/972
2020-02-13 15:01:25 +00:00
Rafael Fontenelle
a0db95e00f Update Brazilian Portuguese translation 2020-02-13 14:10:25 +00:00
Daniel Mustieles
1562d6c63a Updated Spanish translation 2020-02-13 09:43:28 +01:00
Danial Behzadi
8d3277cb37 Update Persian translation 2020-02-13 01:13:40 +00:00
Jiri Grönroos
c65d820390 Update Finnish translation 2020-02-12 20:34:34 +00:00
Georges Basile Stavracas Neto
9f5f6aa9b2 authPrompt: Don't hide the caps lock warning label
Hiding the Caps lock warning label changes the layout of
Auth Prompt. This is specially noticeable when logging in
with unlisted users, where we change the visibility of this
label after typing a username, and the whole user widget
moves a bit.

Change the Cap lock label's opacity instead of hiding it.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/922
2020-02-12 19:29:48 +00:00
Georges Basile Stavracas Neto
261d6d35f5 userWidget: Add empty label when user is null
Currently, when a null user is passed, we don't add any
username label. That makes the layout of user and no-user
cases inconsistent.

Add a ghost label with no opacity to mimic the username
label.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/922
2020-02-12 19:29:48 +00:00
Georges Basile Stavracas Neto
0f34cbb658 authPrompt: Only spin on password entries
Spinning while typing the password is a bit off-putting, and
inconsistent with how regular authentication behaves.

Only spin the spinner after typing the password.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/922
2020-02-12 19:29:48 +00:00
Georges Basile Stavracas Neto
077a1d2309 authPrompt: Refactor 'next' signal
Currently, AuthPrompt is connecting to its own 'next' signal
signal to react to any of the entries being activated, and do
some actions like starting the spinner and answering the PAM
question.

Refactor this code into another method, and don't connect to
our own signal.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/922
2020-02-12 19:29:48 +00:00
Georges Basile Stavracas Neto
ea6b34de0f theme: Increase border-radius of user list items
To keep consistency with the radius of other elements.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/922
2020-02-12 19:29:48 +00:00
Georges Basile Stavracas Neto
66835c6e15 authPrompt: Remove colons from questions
Unfortunately, the question that is displayed comes directly
from PAM. It usually is just "Password:", which comes from
pam-unix, but other questions can be set, usually with the
colons, since they are crafted with a CLI workflow in mind.

Manually drop the colons from questions asked by PAM. This
is also done by the PolKit agent, which shows how the stack
is fragile, but it's what we have for now.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/922
2020-02-12 19:29:48 +00:00
Georges Basile Stavracas Neto
99e81b32f4 authPrompt: Keep buttonWell and cancel button sizes in sync
So that the entry is horizontally centralized at all times.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/922
2020-02-12 19:29:48 +00:00
Georges Basile Stavracas Neto
fe69dacaf1 loginDialog: Use text entry for username
https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/922
2020-02-12 19:29:48 +00:00
Georges Basile Stavracas Neto
6daeb048af authPrompt: Connect signals to both text and password entries
This is a regression from the transition to password entry. Both
entries need to be connected to the relevant signals, otherwise
username-based login won't ever work.

Connect both the text and the password entries.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/922
2020-02-12 19:29:48 +00:00
Georges Basile Stavracas Neto
db4dfd8fa5 authPrompt: Trivial style cleanup
https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/922
2020-02-12 19:29:48 +00:00
Georges Basile Stavracas Neto
0b150a17c5 loginDialog: Replace colon by ellipsis on username question
So it plays better as a hint text.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/922
2020-02-12 19:29:48 +00:00
Georges Basile Stavracas Neto
43a45c091d authPrompt: Use entry to show question texts
Currently, there is a dedicated label above the entry to
display the question text. According to the new mockups
for the lock screen, this label doesn't exist; instead,
the question is set inside the entry itself, as a hint
text.

Set the questions as hint texts of the entry, and remove
the now unused label.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/922
2020-02-12 19:29:48 +00:00
Georges Basile Stavracas Neto
f4e35a9e82 theme: Make AuthPrompt messages white
As per design review, it is more important to preserve the
legibility of the labels than their actual warning colors.

Make the login & unlock dialog message labels white.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/922
2020-02-12 19:29:48 +00:00
Georges Basile Stavracas Neto
cc5adcbeef loginDialog: Center align Caps Lock and authentication messages
https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/922
2020-02-12 19:29:48 +00:00
Georges Basile Stavracas Neto
848cc1bb19 loginDialog: Set null user when asking for username
When going through the username + password login flow, set
the username to 'null' to update the user avatar.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/922
2020-02-12 19:29:48 +00:00
Umang Jain
654093dc40 userWidget: Adapt if user is not mentioned for username login
If username-based login flow is followed, we need a default avatar
for the userWidget. Hence, check if the user passed to userWidget
is (null) which implies a username-based login flow.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/922
2020-02-12 19:29:48 +00:00
Umang Jain
aebea82474 loginDialog: Move and relayout sessionMenuButton to bottom right
https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/922
2020-02-12 19:29:48 +00:00
Umang Jain
a6b29d6501 loginDialog: Apply CSS to sessionMenuButton according to mockups
https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/922
2020-02-12 19:29:48 +00:00
Umang Jain
9766562062 theme: Add top padding to unlock-dialog-clock-time
The (imaginary) center line for clock time of unlock dialog and the
user avatar should be the same. Since the clock font is 64pt, we need
32pt padding (or 42px).

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/922
2020-02-12 19:29:48 +00:00
Umang Jain
c6a79fafc9 unlockDialog: Remove 'Login as another user' Label
According to the new mockups, logging in as another user
should be handled by the (<) button present on the lock-screen.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/922
2020-02-12 19:29:48 +00:00
Umang Jain
7fc4fe9a97 authPrompt: Iconize the cancel button
Replace the "Cancel" label in the cancel button
by an arrow icon, and adjust the theme to make
it circular.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/922
2020-02-12 19:29:48 +00:00
Umang Jain
ee0a36e6a3 authPrompt: Move cancel button, entry and spinner to a single row
https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/922
2020-02-12 19:29:48 +00:00
Umang Jain
a5972d2882 authPrompt: Remove Next button and its references
https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/922
2020-02-12 19:29:48 +00:00
Umang Jain
2fdc627257 userWidget: Allow vertical orientation for user avatars
Allow vertical orientation for the userWidget so that the user-avatar
can be centered and user's name can be placed below it. The plan
for 3.36 is to use this vertical userWidget layout for both lock
and login screen.

The userWidget is also used while creating the user-selection list
at the login, hence we still need to keep the horizontal layout
for userWidget in place.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/922
2020-02-12 19:29:48 +00:00
Florian Müllner
77f77b4305 theme: Make base icon size font-relative
Most icons are used along-side text, like the top bar or menus.
It therefore makes sense for them to adjust along-side the text
when the text-scaling changes.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/995
2020-02-12 19:48:58 +01:00
Emin Tufan Çetin
910a1aed96 Update Turkish translation 2020-02-12 17:42:05 +00:00
Jakub Steiner
bf0bd21757 icons: update Extensions app icon
- use more geometric shapes, no tilt
- everything tends to be blue, use green instead

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/994
2020-02-12 14:16:22 +00:00
Jonas Dreßler
e1be4ba434 unlockDialog: Multiply blur sigma value with the scale factor
Since the blur sigma decides how many pixels get factored in when
blurring and setting a scale factor increases the background texture by
that factor, the sigma value should also be multiplied by the scale
factor.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/991
2020-02-12 11:11:03 -03:00
Jonas Dreßler
7c8ed95330 blur-effect: Remove modify_paint_volume vfunc override
If we modify the paint volume to make it larger and include the blur
radius, we should also use the gained size and draw something there.
Since the framebuffers are only the size of the actor to blur, we're not
doing that right now anyway, so remove the vfunc override.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/991
2020-02-12 11:11:02 -03:00
Jonas Dreßler
f351cfa2f7 blur-effect: Use sigma value instead of blur radius
Almost all implementations, including CSS [1] of gaussian blurs use the
sigma/standard deviation value as the input parameter, even if they call
that value "radius". Since using sigma is more correct mathematically
and avoids confusion for people used to other blur implementations, use
that parameter here, too.

[1] https://www.w3.org/TR/filter-effects-1/#funcdef-filter-blur

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/991
2020-02-12 11:10:38 -03:00
Jonas Dreßler
d26bb38be9 blur-effect: Implement incremental calculation of gauss coefficient
Use the shader for linear sampling and incremental calculation of the
gaussian kernel values as it was implemented by Patrick Walton in
webrender.

The sigma value for the blur (the standard deviation) is calculated by
taking the blur radius and dividing it by 3, this value is used by most
implementations of gaussian blurs since it covers a high percentage of
the gaussian shape.

The linear sampling optimization is implemented by skipping every second
texel (i += 2) in the for-loop that's sampling adjacent texels.

https://github.com/servo/webrender/blob/master/webrender/res/cs_blur.glsl
38ec7db6f1

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/991
2020-02-12 11:07:55 -03:00
Jonas Dreßler
b75e61d5c8 blur-effect: Only apply paint opacity once when blurring actor
We don't want to apply the opacity multiple times, because this would
also multiply the opacity we're applying.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/991
2020-02-12 14:02:28 +00:00
Jonas Dreßler
ca35ae4364 blur-effect: Only apply paint opacity to actor blur
We don't want to apply the opacity of the actor when blurring the
background.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/991
2020-02-12 14:02:28 +00:00
Jonas Dreßler
f6fa08fa75 blur-effect: Don't paint background using actor opacity
The background should always be painted fully opaque, the opacity of the
actor does not change the one of the background.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/991
2020-02-12 14:02:28 +00:00
Jonas Dreßler
46f94241eb blur-effect: Use int for opacity override
The opacity override can be -1 if no override is set, so use the
appropriate datatype here.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/991
2020-02-12 14:02:28 +00:00
Jonas Dreßler
ea2ddaa9dd blur-effect: Floor downscaled frambuffer sizes
Floor the downscaled size of the new framebuffer to make sure we don't
initialize a framebuffer with a floating point value that might be
interpreted wrong by `cogl_texture_2d_new_with_size` and end up with a
slightly wrong aspect ratio of the framebuffer.

This fixes situations where the widths or heights of downscaled
framebuffers sometimes miss some pixels at the border.

While at it, remove the `downscale_factor` argument from
`setup_projection_matrix` since that function doesn't need the initial
size of the actor anyway.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/991
2020-02-12 14:02:28 +00:00
Jonas Dreßler
b4d491a4d2 blur-effect: Add some more documentation about performance
Explicitly mention that this effect works best for large blur radii and
can be slow if the blurred actor/image is large and not being scaled.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/991
2020-02-12 14:02:28 +00:00
Jonas Dreßler
463dcc6b93 blur-effect: Fix crash when switching to ACTOR mode
The `clear_framebuffer()` function takes a CoglFramebuffer, not a
FramebufferData object.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/991
2020-02-12 14:02:28 +00:00
Jakub Steiner
f755905c75 theme: revert window picker whitespace
- revert to the more compact overview, providing more space for the
  window thumbnails.

Fixes https://gitlab.gnome.org/GNOME/gnome-shell/issues/2187
2020-02-12 11:27:14 +00:00
sicklylife
b70fb5b69a Update Japanese translation 2020-02-11 17:48:15 +00:00
sicklylife
8b64d88091 Update Japanese translation 2020-02-11 17:43:06 +00:00
Jordi Mas
b66c8b1411 Update Catalan translation 2020-02-11 13:08:55 +01:00
Daniel Mustieles
d6a746dceb Updated Spanish translation 2020-02-11 12:18:16 +01:00
Florian Müllner
224ab2e543 extensions-tool: Add option to list updates
Now that we support extension updates, it may be useful to list
pending updates from the command line. It's easy enough to support,
so add a corresponding option to the list command.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/988
2020-02-10 22:43:00 +00:00
Georges Basile Stavracas Neto
dee738e24f background: Remove noise texture
Use the plain background color.

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

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/872
2020-02-10 22:30:52 +00:00
Georges Basile Stavracas Neto
84c7890917 screenShield: Remove lock screen group from Crtl-Alt-Tab manager
There is nothing else to be focused in the lock screen itself -- the
top bar is already handled elsewhere, and the dialog manages itself
now.

Remove the lock screen group from the Ctrl-Alt-Tab manager.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/872
2020-02-10 22:30:52 +00:00
Georges Basile Stavracas Neto
fd484099ae screenShield: Cleanup _ensureUnlockDialog
Just like on ScreenShield.activate(), we can just ensure the
unlock screen on ScreenShield.showDialog().

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/872
2020-02-10 22:30:52 +00:00
Georges Basile Stavracas Neto
727c84251d screenShield: Rework key focus management
Instead of always grabbing key focus for the screen lock
group, do that for the unlock dialog itself.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/872
2020-02-10 22:30:52 +00:00
Georges Basile Stavracas Neto
37e55df298 unlockDialog: Create auth prompt on demand
AuthPrompt is the set of actors that contain the user avatar,
the username, and the password entry. With the removal of the
screen shield, the unlock dialog (be it UnlockDialog or the
LoginDialog) is always created, and in the case of UnlockDialog,
so is the auth prompt.

This is problematic, though, since for passwordless accounts,
the simple act of creating AuthPrompt authenticates the user,
and lifts the lock screen.

Create the AuthPrompt on demand in UnlockDialog.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/872
2020-02-10 22:30:52 +00:00
Georges Basile Stavracas Neto
2644f62318 unlockDialog: Add .critical CSS class to critical notifications
As per the latest lock screen mockups, critical notifications must have
a more prominent, solid color.

Add a .critical style class to critical notification bubbles, and make
them darker.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/872
2020-02-10 22:30:52 +00:00
Georges Basile Stavracas Neto
893bde0ca1 theme: Adjust style of lock screen notifications
https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/872
2020-02-10 22:30:52 +00:00
Georges Basile Stavracas Neto
bd0bf3d3d0 unlockDialog: Line notification labels horizontally
https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/872
2020-02-10 22:30:52 +00:00
Georges Basile Stavracas Neto
05c918dc1a unlockDialog: Use just the counter to format notifications
https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/872
2020-02-10 22:30:52 +00:00
Georges Basile Stavracas Neto
3651cb2047 unlockDialog: Show clock when canceling or failing auth
There is still a problem of focus not going to the entry after the
first cancel, but it seems to work fine otherwise.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/872
2020-02-10 22:30:52 +00:00
Georges Basile Stavracas Neto
b9c7631a55 unlockDialog: Toggle between clock and auth prompt
Toggle between them when (1) tapping anythere on the screen, and
(2) pressing any key.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/872
2020-02-10 22:30:52 +00:00
Georges Basile Stavracas Neto
b59c9c6946 unlockDialog: Move auth prompt and clock to a ShellStack
We will toggle between each other in the next commit, so add
both to a ShellStack.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/872
2020-02-10 22:30:52 +00:00
Georges Basile Stavracas Neto
f02313c1c6 screenShield: Remove key press event handler
https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/872
2020-02-10 22:30:52 +00:00
Georges Basile Stavracas Neto
6493789bc9 unlockDialog: Introduce UnlockDialogLayout
This is the layout manager responsible for ensuring
that the clock is always at the third of the screen
height, and the notifications can push it to above.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/872
2020-02-10 22:30:52 +00:00
Georges Basile Stavracas Neto
4081b97462 theme: Adjust lock screen clock fonts
These values were decided during the GNOME Shell Hackfest, but
they're still subject to changes.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/872
2020-02-10 22:30:52 +00:00
Georges Basile Stavracas Neto
c20451c2e7 sessionMode: Remove lock-screen mode
Now that the screen shield is gone (at least, as it used to
be), the corresponding session mode is not necessary anymore
as well.

Remove the 'lock-screen' session mode, and the corresponding
CSS.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/872
2020-02-10 22:30:52 +00:00
Georges Basile Stavracas Neto
16dcb1ac15 screenShield: Move lock shield below dialog
Pretty much what the commit title says.

This gives the lock shield actor another role: instead of
being the interactive screen shield, make it the invisible
actor that prevents interacting with windows while the
unlock dialog is sliding down.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/872
2020-02-10 22:30:52 +00:00
Georges Basile Stavracas Neto
c1ee656c35 screenShield: Only animate the unlock dialog
Remove the slide-up-down animation from the lock shield.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/872
2020-02-10 22:30:52 +00:00
Georges Basile Stavracas Neto
cd09144069 screenShield: Rename _liftShield to _activateDialog
Lifting the shield is now what happens *after* successfully logging
in, not before. Now, what we do is activate the dialog before logging
in.

Rename the method to reflect that.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/872
2020-02-10 22:30:52 +00:00
Georges Basile Stavracas Neto
7851069d9c screenShield: Activate dialog when necessary
Activating a dialog is slightly different from opening it; the
former is about showing the user authentication widgetry, while
the latter is about creating it and pre-allocating the necessary
resources.

Activate the screen shield dialog when necessary.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/872
2020-02-10 22:30:52 +00:00
Georges Basile Stavracas Neto
e42700a308 screenShield: Lift the unlock dialog
Instead of scaling it, lift the unlock dialog when unlocking,
and vice-versa.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/872
2020-02-10 22:30:52 +00:00
Georges Basile Stavracas Neto
febc0690c1 screenShield: Remove scrolling
https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/872
2020-02-10 22:30:52 +00:00
Georges Basile Stavracas Neto
308b4f81b5 screenShield: Cleanup unused method arguments
The 'velocity' argument is not used anymore, since the only
caller passing a different value than 0 was the drag motion
callback.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/872
2020-02-10 22:30:52 +00:00
Georges Basile Stavracas Neto
66a3ad42da screenShield: Remove the drag action from the shield
This is start of the end of the screen shield; start by
removing the dragging action from it.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/872
2020-02-10 22:30:52 +00:00
Georges Basile Stavracas Neto
1b84a3ecb2 unlockDialog: Don't destroy on cancel
Otherwise there will be no way to recover it in the future. Also
remove an else condition that assumed the dialog would destroy
itself on cancel.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/872
2020-02-10 22:30:52 +00:00
Georges Basile Stavracas Neto
78fd9d9e4f screenShield: Always show session's unlock dialog
Instead of destroying the dialog when the screen shield is
visible, and creating it when lifting the shield, always show
the session's unlock dialog.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/872
2020-02-10 22:30:52 +00:00
Georges Basile Stavracas Neto
baa5bfcf49 screenShield: Remove _lockScreenContents and family
It is not used anymore, and together with it, we don't need the
_ensureLockScreen() / _clearLockScreen() pair anymore too.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/872
2020-02-10 22:30:52 +00:00
Georges Basile Stavracas Neto
5d88729fc1 unlockDialog: Blur background
Add a 200px blur with a 55% brightness to the unlock dialog
background.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/872
2020-02-10 22:30:51 +00:00
Georges Basile Stavracas Neto
15b59414d6 screenShield: Move background to Unlock Dialog
In addition to that, remove the ClutterBoxLayout that is set as
the layout manager of the Unlock Dialog, and apply the primary
monitor constraint to the child St.BoxLayout instead.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/872
2020-02-10 22:30:51 +00:00
Georges Basile Stavracas Neto
2b39d6e95a screenShield: Remove unused 'onPrimary' argument
The 'onPrimary' argument was being passed to dialog.open(). Turns out,
neither UnlockDialog nor LoginDialog use this parameter.

Remove the unnecessary 'onPrimary' parameter, and cleanup the related
code.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/872
2020-02-10 22:30:51 +00:00
Georges Basile Stavracas Neto
73eaf0df9f screenShield: Move notifications to Unlock Dialog
Also adjust the CSS style classes names to match the new owner.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/872
2020-02-10 22:30:51 +00:00
Georges Basile Stavracas Neto
54e2d3ceb7 unlockDialog, loginDialog: Add a 'wake-up-screen' signal
The signal is currently present in the notifications box, but next
commits will move the notifications box to the unlock dialog.

Add a 'wake-up-screen' signal to the dialogs.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/872
2020-02-10 22:30:51 +00:00
Georges Basile Stavracas Neto
d3cfb5801b unlockDialog: Adjust date format
As per design feedback at FOSDEM, adjust the time format to
not have a comma, nor padding.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/872
2020-02-10 22:30:51 +00:00
Georges Basile Stavracas Neto
143cda628e screenShield: Move clock to Unlock Dialog
Move the Screen Shield clock to Unlock Dialog. Also adjust
the CSS style classes names to match the new owner.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/872
2020-02-10 22:30:51 +00:00
Georges Basile Stavracas Neto
e90940ae10 screenShield: Remove arrows
They are not present anywhere in the new mockups.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/872
2020-02-10 22:30:51 +00:00
Carlos Garnacho
34207cc457 keyboard: Only enable automatically if ClutterSeat::touch-mode is enabled
This defers the policy on backends about whether it makes sense to show
the OSK.

Closes: https://gitlab.gnome.org/GNOME/gnome-shell/issues/872
2020-02-10 22:07:19 +00:00
Jiri Grönroos
cedcda0ccc Update Finnish translation 2020-02-10 21:31:42 +00:00
Emin Tufan Çetin
cfcf1d5192 Update Turkish translation 2020-02-10 20:24:58 +00:00
Kukuh Syafaat
8d9bc4bc4c Update Indonesian translation 2020-02-10 06:52:35 +00:00
Fran Dieguez
d456e938d2 Update Galician translation 2020-02-09 22:26:45 +00:00
sicklylife
f15208e26d Update Japanese translation 2020-02-08 20:44:46 +00:00
sicklylife
1999a359fa Update Japanese translation 2020-02-08 20:31:51 +00:00
Bruce Cowan
3c180bc8f7 Update British English translation 2020-02-08 13:03:04 +00:00
Aurimas Černius
8de42d1f63 Updated Lithuanian translation 2020-02-08 14:25:56 +02:00
Asier Sarasua Garmendia
1769a96362 Update Basque translation 2020-02-08 08:10:26 +00:00
Danial Behzadi
37a3d0d09a Update Persian translation 2020-02-07 22:06:14 +00:00
Carlos Garnacho
e16def0c43 magnifier: Make magnification factor changes animatable
So we can seamlessly change between them through eg. keybindings.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/984
2020-02-07 18:18:25 +01:00
Carlos Garnacho
83d083f189 magnifier: Implement pointer motion tracking differently
The use of the core idle monitor means that focus change events
are also delayed by keyboard interaction. Since the magnifier is
already in the business of pointer tracking, it's easy enough to
fire the pointer rest timeout from here, so focus changes are
accumulated and delayed.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/984
2020-02-07 18:18:25 +01:00
Carlos Garnacho
b1ea4f6c35 magnifier: Animate focus/caret position changes
https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/984
2020-02-07 18:18:25 +01:00
Carlos Garnacho
60c540e93a magnifier: Add support for animating "scroll" on focus changes
This is nice in that it provides a hint of the relative position of
the new focus area, as opposed to a sudden jump.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/984
2020-02-07 18:18:25 +01:00
Carlos Garnacho
f3b56e0eb1 magnifier: Transform a11y events' coordinates by scale factor
We get those events in logical coordinates, which we have to transform
into actual pixels.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/984
2020-02-07 18:18:25 +01:00
Carlos Garnacho
c8d02be14a magnifier: Ignore repeated a11y events
We may get several a11y events setting the caret on the same
coordinates it previously was. Make focus tracking ignore those,
as we're jumping to the same coordinates again during eg. mouse
operation.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/984
2020-02-07 18:18:25 +01:00
Carlos Garnacho
42b50051ac magnifier: Sanity check coordinates in scrollContentsTo
We may receive a11y events with bogus coordinates (eg. x/y = minint),
so ensure the coordinates are sane before scrolling there.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/984
2020-02-07 18:18:25 +01:00
Carlos Garnacho
bda18888c0 magnifier: Clip all crosshair lines at even distances
If the crosshair is clipped so it doesn't cover the pointer cursor,
the clip rectangle is skewed towards the bottom/right. This was
made so to accomodate the default pointer, but the unevenness stays
on other pointer cursors, and it makes the crosshair look odd on
short crosshair length.

Make all lines clip to an even distance from the center instead.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/984
2020-02-07 18:18:25 +01:00
Carlos Garnacho
c150fe95b9 magnifier: Apply color inversion to crosshairs/pointer
It is somewhat unexpected that crosshair color and pointer cursor colors
remain the same across changes in color inversion settings, and may lead
to contrast issues. Apply the effect on the common container, so it
applies to these all.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/984
2020-02-07 18:18:25 +01:00
Carlos Garnacho
8b4b9d396b magnifier: Apply scale factor to crosshair length
On hidpi displays the length is double as advertised, make it match
the advertised length.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/984
2020-02-07 18:18:25 +01:00
Anders Jonsson
9c0f069f86 Update Swedish translation 2020-02-07 15:02:26 +00:00
Daniel van Vugt
8929c89d1f workspace: Animate window clones using translation properties
Instead of position x/y properties. This reduces CPU-intensive relayouts
in JavaScript (`vfunc_allocate` etc).

Closes: https://gitlab.gnome.org/GNOME/gnome-shell/issues/1271
since the other fix required already landed in 4c4846e9.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/936
2020-02-07 14:43:56 +00:00
Daniel van Vugt
881eab7669 dnd: Make DND translation-property-aware
Previously DND only worked properly for actors with zero translation.
But it only requires a small tweak to `this._dragOffsetX/Y` to support
non-zero translation values.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/936
2020-02-07 14:43:56 +00:00
Danial Behzadi
141652b7ec Update Persian translation 2020-02-07 13:04:10 +00:00
Daniel van Vugt
b5651e38c7 iconGrid: Avoid animating the same icon twice
If the icon proper has opacity of zero then that's probably because a
clone of it is animating. So avoid animating the source actor too.

And if there's any other reason for the opacity being zero, still don't
animate it because we can't see it :)

Closes: https://gitlab.gnome.org/GNOME/gnome-shell/issues/2167
2020-02-07 11:31:20 +00:00
Daniel van Vugt
33ae220ad2 appDisplay: Call super.vfunc_unmap last
So as to guarantee the unmapped state sticks and doesn't get toggled
back to mapped before we return.

Being in a mapped state when `FolderIcon.vfunc_unmap()` returned was
causing an assertion failure in `clutter_actor_set_mapped` and crashed
the shell.

Closes: https://gitlab.gnome.org/GNOME/gnome-shell/issues/2170
2020-02-07 11:23:25 +00:00
Daniel Mustieles
6ec996e45b Updated Spanish translation 2020-02-07 11:54:07 +01:00
Daniel Mustieles
4f3e847897 Merge branch 'master' of gitlab.gnome.org:GNOME/gnome-shell 2020-02-07 11:54:07 +01:00
Rafael Fontenelle
07a1f107cc Update Brazilian Portuguese translation 2020-02-06 23:47:17 +00:00
Florian Müllner
e062f27edc Bump version to 3.35.90
Update NEWS.
2020-02-06 21:42:49 +01:00
nana-4
36c417e6d9 theme: Get back .weather-header-box styling
This introduced in f2df9f1a was lost in 9ea745bc.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/957
2020-02-06 20:31:42 +00:00
nana-4
87ca1e034f theme: Move .world-clocks-button before .weather-button
As per the layout.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/957
2020-02-06 20:31:42 +00:00
nana-4
dbf1ffc9d4 theme/calendar: Don't nest all card styles for code consistency
The inconsistent styling rules "some card styles are nested, but some
are not" and "some card styles are nested, but some of their descendant
styles are defined elsewhere" are very confusing.

This commit stops nesting all card styles to make the coding style
consistent and less confusing.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/957
2020-02-06 20:31:42 +00:00
nana-4
c5bed7e963 theme: Adjust calendar popover sizing
- Remove bottom blank space on the right column of the calendar popover
  so that the weather card is bottom-aligned with the clear button on
  the left column.
- Remove top blank space on the left column of the calendar popover so
  that the message list is top-aligned with the today button on the
  right column.
- Adjust .message-list-controls sizing to align with other card-styled
  elements.
- Use regular `spacing` instead of margin for some spacing.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/2088
Closes https://gitlab.gnome.org/GNOME/gnome-shell/issues/2120
2020-02-06 20:31:42 +00:00
nana-4
fa915ff7ea theme: Simplify .message styling
- Use fewer properties for layout.
- Use .message-body instead of .message-content to change the body
  color, and remove some color overrides.
- Fix border-radius for last .message-media-control, not only on hover.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/957
2020-02-06 20:31:42 +00:00
nana-4
cbced1ce28 theme: Reorder selectors in .message
The order was messed up when the recent Sass reorganization.
This reorders the selectors in .message to make sense again.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/957
2020-02-06 20:31:42 +00:00
nana-4
900d36d0ea theme/notifications: Remove some duplicate or pointless styling
Those styles are defined in .message and do not need to be overridden in
.notification-banner.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/957
2020-02-06 20:31:42 +00:00
nana-4
62441ebeb4 theme/notifications: Remove some unused style classes
https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/957
2020-02-06 20:31:42 +00:00
nana-4
051f081db7 theme: Apply spacing to .overview-icon-with-label correctly
- Remove margin-bottom for StIcon, which is not only ineffective, but
  also created a bug in app folders.
- Remove ">" which is invalid for overview icons that are not app
  folders.
- Apply spacing to the correct target "StBoxLayout", not the parent
  .overview-icon.overview-icon-with-label.

Fixes https://gitlab.gnome.org/GNOME/gnome-shell/issues/2129
2020-02-06 20:31:42 +00:00
nana-4
ddbc4ef42e theme/search-results: Use spacing instead of margin or padding
Those margin and padding broke spacing in RTL layout. We should use
regular `spacing` for them as before the refactoring.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/957
2020-02-06 20:31:42 +00:00
nana-4
fc4dfa11c3 theme: Simplify .search-section-content items styling
This reduces duplicate code in .search-provider-icon and
.list-search-result by using %search-section-content-item
to improve maintainability.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/957
2020-02-06 20:31:42 +00:00
nana-4
60f12da3cd theme: Simplify .overview-icon styling
This reduces duplicate code by using overview-icon() and %app-well-app
to improve maintainability.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/957
2020-02-06 20:31:42 +00:00
nana-4
40f7d61524 theme: Add interactive styling to .events-section-title again
Since it's an interactive element, interactive styling is still needed.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/2088
2020-02-06 20:31:42 +00:00
nana-4
1263f84c3f theme: Make %notification_bubble a mixin
And simplify .datemenu-today-button styling by using it.

This allows removing duplicate code for flat notification_bubble
styling.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/957
2020-02-06 20:31:42 +00:00
nana-4
9d91b586d8 theme: Remove unnecessary !important rules
Using !important is a bad practice and should be avoided wherever
possible to make styling and debugging easier. See:

https://developer.mozilla.org/en-US/docs/Web/CSS/Specificity#The_!important_exception

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/957
2020-02-06 20:31:42 +00:00
nana-4
ab8bce35f1 theme: Remove some unsupported CSS properties
CSS opacity and border-{top,bottom}-{left,right}-radius are not
supported by St.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/957
2020-02-06 20:31:42 +00:00
Sebastian Keller
7287ee3651 texture-cache: Fix invalid reads when storing used resource scales
The used_scales hash table uses g_double_hash and g_double_equal which
try to read a double from the passed pointers. The pointers however were
pointing to a float, leading to an invalid read.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/974
2020-02-06 19:47:24 +00:00
Florian Müllner
9d7a319721 extensionPrefs: Remove stray > in .ui file
This slipped through as GtkBuilder still accepts it, but let's
not rely on that and fix our XML.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/2180
2020-02-06 20:05:32 +01:00
Piotr Drąg
b7df1133b8 extensionPrefs: Make the Log Out button a proper verb
https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/981
2020-02-06 18:56:00 +00:00
Alexander Mikhaylenko
dfb8737007 appDisplay: Disable swipe tracker during swarm animation
Eensures it resets when an animation starts.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/2177
2020-02-06 17:36:05 +00:00
Alexander Mikhaylenko
a06a418ac1 swipeTracker: Reset scroll gesture state on disabling
Ensure that scrolling works correctly next time it's enabled.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/2177
2020-02-06 17:36:05 +00:00
Michael Catanzaro
35063c9e7c portalHelper: Enable WebKit sandbox if available
The portal helper is rather sensitive because potentially-hostile Wi-Fi
networks can decide to launch it whenever they want (by blocking the
user's connection to the nmcheck domain) and load whatever web content
they want into it. So having this unsandboxed is really extraordinarily
risky. Previously it was a risk we had to accept, because WebKit did not
have a web process sandbox, but now it does. So let's bubblewrap all the
things!

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/983
2020-02-06 18:28:40 +01:00
Jakub Steiner
ded4586781 theme: revert app grid button styling
- the plan was to drop the frequent/all view switcher, thus sam didn't
  pay too much attention to the button styling for those. Sadly the view
  switcher remains, so we should keep the old subtle styling intact.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/979
2020-02-06 16:41:04 +01:00
Daniel Mustieles
89790ac723 Updated Spanish translation 2020-02-06 11:40:07 +01:00
Daniel Mustieles
d253b0671b Updated Spanish translation 2020-02-06 11:39:36 +01:00
Aurimas Černius
e58dcd3040 Updated Lithuanian translation 2020-02-05 22:49:34 +02:00
Piotr Drąg
050a1898ab extensionPrefs: Add a translator comment to the .desktop file
So that Damned Lies filters out the Icon key from translation.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/980
2020-02-05 20:40:54 +01:00
Piotr Drąg
79a8fa2ede Update POTFILES.in 2020-02-05 20:31:50 +01:00
Anders Jonsson
7819f8f82e Update Swedish translation 2020-02-05 17:25:53 +00:00
Carlos Garnacho
5c570460cf magnifier: Use core idletime monitor
As it's getting the idletime monitor for the seat pointer, boils
down to about the same thing. We are moving away from per-device
idletime monitors though.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/978
2020-02-05 16:17:30 +00:00
Kukuh Syafaat
07882c4b6a Update Indonesian translation 2020-02-05 11:33:09 +00:00
Daniel Mustieles
f26eb304f5 Updated Spanish translation 2020-02-05 11:17:28 +01:00
Florian Müllner
7b33e240ed extensionPrefs: Fix typo
https://gitlab.gnome.org/GNOME/gnome-shell/issues/2176
2020-02-04 18:51:57 +01:00
Florian Müllner
a205f4e249 status/system: Fix session submenu visibility
Commit 147a743d8d moved the suspend and power-off actions into
the submenu that contains the log-out and switch-user actions,
but did not update the submenu visibility logic to account for
the additional actions.

As a result, the submenu is hidden when log-out and switch-user
are unavailable (like on the login screen), even if suspend and
power-off are enabled.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/2169
2020-02-04 14:40:44 +00:00
Daniel Mustieles
e16c64dbdd Updated Spanish translation 2020-02-04 12:32:50 +01:00
Dušan Kazik
404ae0a897 Update Slovak translation 2020-02-04 10:02:46 +00:00
Florian Müllner
9e00e8a0fb extensionPrefs: Schedule updates check on activate
While gnome-shell will now check for extension updates, the checks
are performed infrequently. Opening the Extensions app implies that
the user's current focus is on extensions, so it is an appropriate
time to schedule another updates check.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/1968
2020-02-03 19:33:14 +01:00
Florian Müllner
529829a561 extensionSystem: Periodically check for extension updates
Now that we can download, apply and display extension updates, it is time
to actually check for updates. Schedule an update check right on startup,
then every 24 hours.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/1968
2020-02-03 19:33:14 +01:00
Florian Müllner
ed84541050 extensionSystem: Show notification when updates are available
Now that the extensions app has the ability to handle updates, we
can use it as source of updates notifications.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/1968
2020-02-03 19:33:14 +01:00
Florian Müllner
075f4a5efc extensionPrefs: Support extension updates
Now that we have support for extension updates in the shell, we
need some place to display the updates to the user.

As we are establishing the Extensions app as the primary way for
managing extensions, it's a natural place for that functionality.

Show which extensions have updates available, and offer a log out
button (so gnome-shell can apply the updates when logging back in).

https://gitlab.gnome.org/GNOME/gnome-shell/issues/1968
2020-02-03 19:33:12 +01:00
Florian Müllner
f1bd94a367 extensionPrefs: Split user and system extensions
Until now, it didn't matter whether an extension was installed in the
user's home or system-wide. However with support for uninstallation,
there is now a significant different, as that action is only available
for user extensions.

Account for that by separating extensions by type, so that users don't
have to second-guess which extensions can be fully-managed and which
appear as part of the system.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/1968
2020-02-03 19:13:44 +01:00
Florian Müllner
db69ad876a extensionPrefs: Support uninstalling user extensions
This is functionality currently provided by GNOME Software, and
which the new Extensions app should (and easily can) provide.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/1968
2020-02-03 19:11:21 +01:00
Florian Müllner
c6f297e4e5 extensionPrefs: Include more extension details in expander
The newly added expander gives us a place where we can display
more details without cluttering the interface.

Take advantage of that by including the extension website, version
and author.

(Author is in the mockups, but will not actually be shown until
the extensions website is changed to include it in its metadata;
however best to have UI and string in place for the freezes)

https://gitlab.gnome.org/GNOME/gnome-shell/issues/1968
2020-02-03 19:11:21 +01:00
Florian Müllner
1067642300 extensionPrefs: Move description into a expander
The description can be useful information, but also increases the
visual complexity of the extensions list. Move it into a hidden
details area that can be expanded, which unclutters the interface
while keeping the information readily available.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/1968
2020-02-03 19:11:21 +01:00
Florian Müllner
059524b007 extensionPrefs: Use actions for row controls
Actions are another mean to separate state and interactions from
the UI. Start using them for the existing controls before adding
more in follow-up commits.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/1968
2020-02-03 19:11:21 +01:00
Florian Müllner
1d72f28a1c extensionPrefs: Use template for rows
Rows are already complex enough to justify a template, and we are
about to add more.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/1968
2020-02-03 19:11:21 +01:00
Florian Müllner
5b92e3a9a8 extensionPrefs: Use a single line for description
The current fixed two-line label requires a custom widget, which
make moving to a widget template harder.

As the description will soon move elsewhere anyway, just go back
to a single line with a standard label for now.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/1968
2020-02-03 19:11:21 +01:00
Florian Müllner
8795668c41 extensionPrefs: Rename to Extensions
... and make the application user-visible.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/1968
2020-02-03 19:03:19 +01:00
Florian Müllner
872c84a1c3 extensionPrefs: Add standard app elements
In order to turn the extensions-prefs tool into a proper GNOME app, it
should follow basic app patterns, so add a primary menu and about dialog.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/1968
2020-02-03 19:03:19 +01:00
Florian Müllner
b47879d0a7 extensionPrefs: Add info popover to headerbar
Extensions can have a major impact on stability and performance. Now that
the tool will become the main way for users to manage their extensions, it
is an appropriate place to warn the user of that risk.

Add a small info popover to the headerbar to display that warning, together
with the previously removed hint of where to go for finding new extensions.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/1968
2020-02-03 19:03:19 +01:00
Florian Müllner
679fc20765 extensionPrefs: Add application icon
We are about to make the tool a user-visible application, so we
need an icon. Add one (plus its symbolic variant).

https://gitlab.gnome.org/GNOME/gnome-shell/issues/1968
2020-02-03 19:03:19 +01:00
Florian Müllner
db85e7084c extensionPrefs: Scroll with key focus
Currently when the extensions list is scrolled, it is possible to
keynav out of view, as the scrolling doesn't follow the key focus.

Hook up the adjustment to fix that.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/1968
2020-02-03 19:03:19 +01:00
Florian Müllner
1afd2c6ad2 extensionPrefs: Don't fill view
Extension rows contain both name/description and controls to
open preferences and enable/disable the extension. Those
elements become disassociated when the row expands too much
horizontally, so instead of filling the entire view, switch
to the embedded list style[0].

[0] https://developer.gnome.org/hig/stable/lists.html.en

https://gitlab.gnome.org/GNOME/gnome-shell/issues/1968
2020-02-03 19:03:19 +01:00
Florian Müllner
a74a9f6443 extensionPrefs: Use template for ExtensionsWindow
As the window will become more complex, it makes sense to let GtkBuilder
construct the UI and focus on the actual implementation.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/1968
2020-02-03 19:03:19 +01:00
Florian Müllner
f49e20bbae extensionPrefs: Split out window class
Currently the main window is a plain Gtk.ApplicationWindow that is
built and managed from within the application.

As the application becomes more complex, it makes sense to decouple
the two and handle the window from a separate ExtensionsWindow class.

Not least this is a prerequisite of using a widget template for the
window.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/1968
2020-02-03 19:03:19 +01:00
Florian Müllner
9916989272 extensionPrefs: Simplify empty placeholder
GNOME Software will remove its extension support, so we should stop
referencing it in addition to extensions.gnome.org.

In fact, the placeholder is not the best place to hint at where new
extensions can be found, as the user will never see it in case the
distribution includes pre-installed extensions.

So remove the hint altogether, we will add it back in a more prominent
place later.

With the whole placeholder now being much lighter, we can stop dimming
the remaining elements.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/1968
2020-02-03 19:03:19 +01:00
Florian Müllner
1054f7533a theme: Tweak app folder style
- match dash border/radius
 - hide scrollbar
 - increase title padding

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/973
2020-02-03 14:24:23 +00:00
Goran Vidović
5f457f6ed2 Update Croatian translation 2020-02-03 14:03:08 +00:00
Daniel Mustieles
9df2edc87e Updated Spanish translation 2020-02-03 12:15:54 +01:00
Dušan Kazik
28eb94402e Update Slovak translation 2020-02-02 20:34:09 +00:00
Aurimas Černius
d2bf869c16 Updated Lithuanian translation 2020-02-02 22:10:30 +02:00
Anders Jonsson
05ea1bdac2 Update Swedish translation 2020-02-02 14:55:45 +00:00
Dušan Kazik
454e85f0a9 Update Slovak translation 2020-02-01 23:06:01 +00:00
Jonas Dreßler
45c5f21f6c dialogs: Hide caps lock warning if password entry is hidden
If all password entries in dialogs are hidden, there is either an entry
that has visible characters or no entry at all. That means we don't have
to show the caps lock warning at all, so hide it.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/942
2020-02-01 08:08:33 +01:00
Jonas Dreßler
59bd2dd1e3 windowManager: Use shorter string for dialog headline
Since the headlines of the dialogs now use a much larger font, the
strings need to be shorter so they won't be ellipsized.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/942
2020-02-01 08:08:33 +01:00
Jonas Dreßler
3c47923953 networkAgent: Use shorter title strings
Since the headlines of the dialogs now use a much larger font, the
strings need to be shorter so they won't be ellipsized. So use a shorter
strings for those titles and also adjust the title-strings of the
notifications sent by the NetworkAgent to be consistent.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/942
2020-02-01 08:08:33 +01:00
Jonas Dreßler
dbaf5687dd networkAgent: Implement new dialog design
Use a completely vertical layout instead of the ClutterGridLayout based
layout to implement the new design for dialogs in the shell:

- Center-align all the elements of the dialog
- Remove the work-spinner
- Show the entry-labels as hint text of the entry

See https://gitlab.gnome.org/GNOME/gnome-shell/issues/1343

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/942
2020-02-01 08:08:33 +01:00
Jonas Dreßler
20895c7791 windowManager: Cleanup dialog a bit
This doesn't have to be a prompt-dialog, so remove the css class, also
the MessageDialogContent doesn't need the x and y_expand properties, so
remove those, too.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/942
2020-02-01 08:08:33 +01:00
Jonas Dreßler
ddeb2fa05d shellMountOperation: Use wiggle effect to inform about wrong password
https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/942
2020-02-01 08:08:33 +01:00
Jonas Dreßler
7a1f4f9af3 shellMountOperation: Implement new dialog design
Update the layout of the ShellMountPasswordDialog dialog according to
the new dialog design:

- Center-align all the elements of the dialog
- Align the work-spinner to the right (or left with RTL layouts) of the
password entry
- Show the entry-labels as hint text of the entry

See https://gitlab.gnome.org/GNOME/gnome-shell/issues/1343

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/942
2020-02-01 08:08:33 +01:00
Jonas Dreßler
dc578a9e79 keyring: Use wiggle effect to inform about new warning message
https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/942
2020-02-01 08:08:30 +01:00
Jonas Dreßler
040c1638ea keyring: Implement new dialog design
Replace the ClutterGridLayout of the keyring dialog with a vertical
StBoxLayout based layout according to the new dialog design:

- Center-align all the elements of the dialog
- Remove the work-spinner because requests usually finish fast enough
- Show the entry-labels as hint text of the entry

See https://gitlab.gnome.org/GNOME/gnome-shell/issues/1343

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/942
2020-02-01 08:06:31 +01:00
Jonas Dreßler
ded8412a2a polkitAgent: Use wiggle effect to inform about wrong password or problem
https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/942
2020-02-01 08:06:31 +01:00
Jonas Dreßler
2f3738fae0 polkitAgent: Implement new design for polkit dialog
Implement the new design for the polkit according to the mockups in
https://gitlab.gnome.org/GNOME/gnome-shell/issues/1343:

- Center-align all the parts of the dialog
- Use a larger user avatar
- Remove the work-spinner because requests usually finish fast enough
- Show the entry-labels as hint text of the entry

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/942
2020-02-01 08:06:31 +01:00
Jonas Dreßler
a59da75830 theme/dialogs: Clean up css a bit
Remove some unused classes and "deduplicate" selectors.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/942
2020-02-01 08:06:31 +01:00
Jonas Dreßler
2b184a10d6 util: Move wiggle parameters to a common place
Since the wiggle effect will be used by the redesigned prompt-dialogs
and we always want to use the same parameters, move those as defaults
for the wiggle function to the util.js file.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/942
2020-02-01 08:06:31 +01:00
Florian Müllner
fc36837606 st/theme-node: Support "auto" in lengths
This allows resetting a fixed size to the default in a more specific
selector.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/971
2020-02-01 00:22:24 +01:00
Florian Müllner
4871845d01 portalHelper: Require GTK 3.0
When multiple versions of a typelib are available, GI will pick the
highest one unless an explicit version is requested. So as GTK 4.0
is becoming a thing, it's time to do that.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/970
2020-01-31 17:39:18 +01:00
Florian Müllner
53ac00eabb js: Initialize some properties
Otherwise those can result in the (harmless) "reference to undefined
property" warnings.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/970
2020-01-31 17:39:18 +01:00
Jor Teron
75905ebd3c Update Karbi translation 2020-01-31 10:50:28 +00:00
Jor Teron
12f033ee0f Update Karbi translation
(cherry picked from commit a8bb7c0a2a)
2020-01-31 10:34:46 +00:00
Georges Basile Stavracas Neto
964106513e shellEntry: Use seat to retrieve keymap
The backend does not handle the keymap anymore; this is now
handled by ClutterSeat.

Use ClutterSeat to retrieve the default keymap.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/968
2020-01-30 15:57:12 -03:00
159 changed files with 20939 additions and 16527 deletions

View File

@@ -19,7 +19,7 @@ fi
function commit_message_has_url() {
commit=$1
commit_message=$(git show -s --format='format:%b' $commit)
echo "$commit_message" | grep -qe "\($CI_MERGE_REQUEST_PROJECT_URL/\(issues\|merge_requests\)/[0-9]\+\|https://bugzilla.gnome.org/show_bug.cgi?id=[0-9]\+\)"
echo "$commit_message" | grep -qe "\($CI_MERGE_REQUEST_PROJECT_URL/\(-/\)\?\(issues\|merge_requests\)/[0-9]\+\|https://bugzilla.gnome.org/show_bug.cgi?id=[0-9]\+\)"
return $?
}

68
NEWS
View File

@@ -1,3 +1,71 @@
3.35.91
=======
* Improve magnifier [Carlos; !984]
* Only enable OSK automatically if touch-mode is enabled [Carlos; #872]
* Merge screen shield and unlock dialog to new lock screen [Georges; !872]
* Improve ShellBlur effect [Jonas; !991]
* Adapt user avatar for new lock screen [Umang, Georges; !922]
* Animate prompt transition on lock screen [Florian; !972]
* Reduce font-size in dialog titles if text doesn't fit [Jonas; !1012]
* Various lock screen improvements and bug fixes [Jakub, Florian, Georges;
!996, !997, !999, #2212, !998, !1006, #2215, #2213]
* Misc. bug fixes and cleanups [Daniel, Florian, Jakub, nana-4, Jonas; #2170,
#2167, !936, !988, #2187, !994, !995, !938, #2194, #2203, !1004, !977, !1014]
Contributors:
Jonas Dreßler, Carlos Garnacho, Umang Jain, Daniel Mustieles, Florian Müllner,
Georges Basile Stavracas Neto, Jakub Steiner, Daniel van Vugt, nana-4
Translators:
Daniel Mustieles [es, pt_BR], Rafael Fontenelle [pt_BR], Danial Behzadi [fa],
Anders Jonsson [sv], Asier Sarasua Garmendia [eu], Aurimas Černius [lt],
Bruce Cowan [en_GB], sicklylife [ja], Fran Dieguez [gl], Kukuh Syafaat [id],
Emin Tufan Çetin [tr], Jiri Grönroos [fi], Jordi Mas [ca], Claude Paroz [fr],
Ask Hjorth Larsen [da], Марко Костић [sr], Piotr Drąg [pl],
Charles Monzat [fr], Balázs Úr [hu]
3.35.90
=======
* Update default favorite apps [Michael; !907]
* Add Shell.Blur effect [Georges; !864, !924]
* Overhaul scroll/swipe gestures [Alexander; !821, !825, !826]
* Fix VPN connections when delaying request [Florian; #2008]
* Overhaul theme [Sam, Jakub, nana-4; !904, !931, !957]
* Improve visual appearance of Weather integration [Florian; #1143]
* Implement new system dialog designs [Jonas; #1343]
* Animate position changes of app icons [Georges; !882]
* Add St.Viewport [Georges; !929]
* Make app folders behave as dialogs [Georges; !896]
* Add do-not-disturb functionality to calendar popup [Florian; #239]
* Show hint actor in focused entries [Jonas; !944]
* Switch screen-recorder back to VP8 [Björn; #256]
* Allow to run perf-tool as wayland compositor [Olivier; !941]
* Handle extension updates [Florian; !945]
* Animate showing and hiding caps-lock warning [Jonas; !952]
* Support "auto" lengths in CSS [Florian; !971]
* Turn extension-prefs into the offical Extensions app [Florian; #1968]
* Sandbox the portal helper [Michael; !983]
* Misc. bug fixes and cleanups [Florian, Björn, Jakub, Alexander, Daniel V.,
Jonas, nana-4, Carlos, Sebastian, Daniel G., Georges, Piotr; !918, !917,
!919, !920, #763, #791659, !927, #2091, !930, !926, !888, !934, !168, #2133,
#682, #2142, #2131, !943, #2132, #1958, #2146, !951, #1779, #2130, !964,
!965, !948, #2151, #1746, !967, !760, !968, !970, !973, #2169, #2176, !978,
!980, !979, #2177, !981, #2180, !974]
Contributors:
Michael Catanzaro, Björn Daase, Jonas Dreßler, Piotr Drąg, Olivier Fourdan,
Carlos Garnacho, Sam Hewitt, Sebastian Keller, Andre Klapper,
Alexander Mikhaylenko, Daniel García Moreno, Florian Müllner,
Georges Basile Stavracas Neto, Jakub Steiner, Daniel van Vugt, nana-4
Translators:
Asier Sarasua Garmendia [eu], Daniel Mustieles [es], Andrej Shadura [sk],
Carmen Bianca BAKKER [eo], Sucipto [id], Dušan Kazik [sk], Goran Vidović [hr],
sicklylife [ja], Kukuh Syafaat [id], Yi-Jyun Pan [zh_TW],
Rafael Fontenelle [pt_BR], Jordi Mas [ca], Jiri Grönroos [fi],
Fabio Tomat [fur], Umarzuki Bin Mochlis Moktar [ms], Daniel Korostil [uk],
Jor Teron [mjw], Anders Jonsson [sv], Aurimas Černius [lt]
3.35.3
======
* Add discrete GPU support for NVidia drivers [Bastien; #1810]

View File

@@ -57,5 +57,19 @@
<method name="GetWindows">
<arg name="windows" direction="out" type="a{ta{sv}}" />
</method>
<!--
AnimationsEnabled:
@short_description: Whether the shell animations are enabled
By default determined by the org.gnome.desktop.interface enable-animations
gsetting, but may be overridden, e.g. if there is an active screen cast or
remote desktop session that asked for animations to be disabled.
Since: 2
-->
<property name="AnimationsEnabled" type="b" access="read"/>
<property name="version" type="u" access="read"/>
</interface>
</node>

View File

@@ -9,16 +9,9 @@
<file>dash-placeholder.svg</file>
<file>gnome-shell.css</file>
<file>gnome-shell-high-contrast.css</file>
<file>key-enter.svg</file>
<file>key-hide.svg</file>
<file>key-layout.svg</file>
<file>key-shift.svg</file>
<file>key-shift-uppercase.svg</file>
<file>key-shift-latched-uppercase.svg</file>
<file alias="icons/message-indicator-symbolic.svg">message-indicator-symbolic.svg</file>
<file>no-events.svg</file>
<file>no-notifications.svg</file>
<file>noise-texture.png</file>
<file>pad-osd.css</file>
<file alias="icons/eye-open-negative-filled-symbolic.svg">eye-open-negative-filled-symbolic.svg</file>
<file alias="icons/eye-not-looking-symbolic.svg">eye-not-looking-symbolic.svg</file>
@@ -26,6 +19,11 @@
<file alias="icons/pointer-drag-symbolic.svg">pointer-drag-symbolic.svg</file>
<file alias="icons/pointer-primary-click-symbolic.svg">pointer-primary-click-symbolic.svg</file>
<file alias="icons/pointer-secondary-click-symbolic.svg">pointer-secondary-click-symbolic.svg</file>
<file alias="icons/keyboard-caps-lock-filled-symbolic.svg">keyboard-caps-lock-filled-symbolic.svg</file>
<file alias="icons/keyboard-enter-symbolic.svg">keyboard-enter-symbolic.svg</file>
<file alias="icons/keyboard-hide-symbolic.svg">keyboard-hide-symbolic.svg</file>
<file alias="icons/keyboard-layout-filled-symbolic.svg">keyboard-layout-filled-symbolic.svg</file>
<file alias="icons/keyboard-shift-filled-symbolic.svg">keyboard-shift-filled-symbolic.svg</file>
<file>process-working.svg</file>
<file>toggle-off.svg</file>
<file>toggle-off-dark.svg</file>

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 13 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 6.1 KiB

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path d="M6.5 1.031c-.371 0-.742-.035-1.11.016-.367.05-.73.203-.972.476-.125.141-.215.309-.266.485-.047.18-.054.367-.02.55.032.184.102.356.192.516.09.164.203.309.317.457L5 4H2a1.8 1.8 0 00-.41.035.791.791 0 00-.36.195.791.791 0 00-.195.36C1 4.723 1 4.863 1 5v2.75l.77-.344c.265-.117.542-.23.832-.242.289-.016.586.074.812.254.227.18.383.441.465.723.082.277.101.57.121.859.02.316.04.637-.016.95-.058.312-.199.616-.43.831a1.264 1.264 0 01-.874.32c-.317-.007-.618-.128-.91-.257L1 10.5V14c0 .137.004.277.035.41a.791.791 0 00.195.36c.098.097.227.16.36.195.133.035.273.035.41.035h3l-.328-.68c-.14-.293-.274-.597-.29-.922-.015-.32.095-.652.31-.894.214-.242.523-.39.84-.453.316-.067.644-.059.968-.059.324 0 .652-.008.969.059.316.062.625.21.84.453.214.242.324.574.308.894-.015.325-.148.63-.289.922L8 15h3a1.8 1.8 0 00.41-.035.791.791 0 00.36-.195.791.791 0 00.195-.36C12 14.277 12 14.137 12 14v-3.563l.703.297c.29.125.59.239.902.246.313.004.63-.101.864-.308.238-.203.386-.496.46-.8C15 9.565 15 9.25 15 8.937c0-.313 0-.63-.07-.934-.075-.305-.223-.598-.461-.8a1.288 1.288 0 00-.864-.31c-.312.008-.613.122-.902.247L12 7.437V5a1.8 1.8 0 00-.035-.41.791.791 0 00-.195-.36.791.791 0 00-.36-.195C11.277 4 11.137 4 11 4H8l.36-.469c.113-.148.226-.293.316-.457.09-.16.16-.332.191-.515a1.248 1.248 0 00-.02-.551 1.256 1.256 0 00-.265-.485c-.242-.273-.605-.425-.973-.476-.367-.05-.738-.016-1.109-.016zm0 0" fill="#474747"/></svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

1
data/icons/meson.build Normal file
View File

@@ -0,0 +1 @@
install_subdir('hicolor', install_dir: icondir)

View File

@@ -1,6 +1,6 @@
desktop_files = [
'org.gnome.Shell.desktop',
'gnome-shell-extension-prefs.desktop'
'org.gnome.Extensions.desktop',
]
service_files = []
@@ -43,6 +43,7 @@ endforeach
subdir('dbus-interfaces')
subdir('icons')
subdir('theme')
data_resources = [

View File

@@ -1,8 +1,9 @@
[Desktop Entry]
Type=Application
Name=Shell Extensions
Name=Extensions
# Translators: Do NOT translate or transliterate this text (this is an icon file name)!
Icon=org.gnome.Extensions
Comment=Configure GNOME Shell Extensions
Exec=@bindir@/gnome-shell-extension-prefs %u
Categories=GNOME;GTK;
OnlyShowIn=GNOME;
NoDisplay=true

View File

@@ -19,13 +19,13 @@ $error_color: #ff8080;
$success_color: if($variant == 'light', #33d17a, darken(#33d17a, 10%));
$destructive_color: if($variant == 'light', #e01b24, darken(#e01b24, 10%));
$osd_fg_color: $fg_color;
$osd_text_color: if($variant == 'light', #000, #fff);
$osd_bg_color: if($variant == 'light', rgba(255,255,255,0.9), transparentize(darken(desaturate(#3d3846, 100%), 12%),0.04));
$osd_fg_color: #eeeeec;
$osd_text_color: white;
$osd_bg_color: transparentize(darken(desaturate(#3d3846, 100%), 12%),0.04);
$osd_insensitive_bg_color: transparentize(mix($osd_fg_color, opacify($osd_bg_color, 1), 10%), 0.5);
$osd_insensitive_fg_color: mix($osd_fg_color, opacify($osd_bg_color, 1), 50%);
$osd_borders_color: if($variant == 'light', rgba(255,255,255,0.1), rgba(0,0,0,0.7));
$osd_outer_borders_color: if($variant == 'light', rgba(0,0,0,0.1), lighten($osd_bg_color, 7%));
$osd_borders_color: transparentize(black, 0.3);
$osd_outer_borders_color: transparentize(white, 0.84);
$shadow_color: if($variant == 'light', rgba(0,0,0,0.1), rgba(0,0,0,0.2));
@@ -40,4 +40,4 @@ $backdrop_bg_color: $bg_color;
$backdrop_fg_color: mix($fg_color, $backdrop_bg_color, 80%);
$backdrop_insensitive_color: if($variant =='light', darken($backdrop_bg_color,15%), lighten($backdrop_bg_color,15%));
$backdrop_borders_color: mix($borders_color, $bg_color, 90%);
$backdrop_dark_fill: mix($backdrop_borders_color,$backdrop_bg_color, 35%);
$backdrop_dark_fill: mix($backdrop_borders_color,$backdrop_bg_color, 35%);

View File

@@ -54,8 +54,8 @@ $base_font_size: 11;
$text_shadow_color: if($variant == 'light', rgba(255,255,255,0.3), rgba(0,0,0,0.2));
// icons
// $base_icon_size: 1.09em;
$base_icon_size: 16px;
$base_icon_size: 1.09em;
// $base_icon_size: 16px;
// Stage
stage {
@@ -91,13 +91,9 @@ stage {
// icon tiles
%icon_tile {
background-color: transparent; // no background
color: $osd_fg_color;
border-radius: $base_border_radius + 4px;
padding: $base_padding;
border-width: 2px;
border-style: solid;
border-color: transparent;
border: 2px solid transparent;
transition-duration: 100ms;
text-align: center;
}
@@ -155,14 +151,17 @@ stage {
// notification styling
%notification_bubble {
@mixin notification_bubble($flat: false) {
border-width: 1px;
border-style: solid;
border-radius:$base_border_radius + 2px;
padding: 0;
border-radius: $base_border_radius + 2px;
margin: $base_margin;
@include button(normal);
@if $flat {
@include button(undecorated);
} @else {
@include button(normal);
}
&:focus {
@include button(focus);

View File

@@ -137,7 +137,7 @@
// normal button
@if $t==normal {
color: $tc;
background-color: lighten($c, 3%) !important;
background-color: lighten($c, 3%);
border-color: draw_border_color($c);
@include draw_shadows($button_shadow);
// box-shadow: 0 1px 1px 0 rgba(0,0,0,0.1);
@@ -150,14 +150,14 @@
color: $tc;
text-shadow: 0 1px $text_shadow_color;
icon-shadow: 0 1px $text_shadow_color;
box-shadow: inset 0 0 0 2px transparentize($selected_bg_color, 0.7);
box-shadow: inset 0 0 0 2px transparentize($selected_bg_color, 0.4);
//border-color: $selected_bg_color;
}
// hover button
@else if $t==hover {
color: $tc;
background-color: lighten($c, if($variant == 'light', 8%, 5%)) !important;
background-color: lighten($c, if($variant == 'light', 8%, 5%));
border-color: if($variant == 'light', draw_border_color(lighten($c, 7%)), draw_border_color($c));
@include draw_shadows($button_shadow);
text-shadow: 0 1px $text_shadow_color;
@@ -167,7 +167,7 @@
// active button
@else if $t==active {
color: $tc;
background-color: darken($c,3%) !important;
background-color: darken($c,3%);
border-color: draw_border_color(if($variant == 'light', $c, darken($c,7%)));
text-shadow: none;
icon-shadow: none;
@@ -178,7 +178,7 @@
@else if $t==insensitive {
color: $insensitive_fg_color;
border-color: $insensitive_borders_color;
background-color: $insensitive_bg_color !important;
background-color: $insensitive_bg_color;
box-shadow: none;
text-shadow: none;
icon-shadow: none;
@@ -194,3 +194,38 @@
icon-shadow: none;
}
}
// overview icons
@mixin overview-icon($color) {
.overview-icon {
@extend %icon_tile;
color: $color;
}
&:hover,
&:selected {
.overview-icon {
background-color: transparentize($color, .9);
}
}
&:focus {
.overview-icon {
background-color: transparentize($color, .7);
// border-color: $selected_bg_color;
}
}
&:drop {
.overview-icon {
background-color: transparentize($selected_bg_color, .15);
}
}
&:active,
&:checked {
.overview-icon {
background-color: transparentize(darken($osd_bg_color, 10%), .5);
}
}
}

View File

@@ -5,34 +5,47 @@
//
/* WIDGETS */
@import 'widgets/app-grid';
@import 'widgets/app-switcher';
@import 'widgets/buttons';
@import 'widgets/calendar';
@import 'widgets/check-box';
@import 'widgets/corner-ripple';
@import 'widgets/dash';
@import 'widgets/dialogs';
// Primary widgets
@import 'widgets/base';
@import 'widgets/entries';
@import 'widgets/hotplug';
@import 'widgets/ibus-popup';
@import 'widgets/keyboard';
@import 'widgets/login-dialog';
@import 'widgets/looking-glass';
@import 'widgets/message-list';
@import 'widgets/notifications';
@import 'widgets/misc';
@import 'widgets/network-dialog';
@import 'widgets/osd';
@import 'widgets/overview';
@import 'widgets/panel';
@import 'widgets/popovers';
@import 'widgets/screen-shield';
@import 'widgets/buttons';
@import 'widgets/check-box';
@import 'widgets/switches';
@import 'widgets/slider';
@import 'widgets/scrollbars';
// Popovers
@import 'widgets/popovers';
@import 'widgets/calendar';
@import 'widgets/message-list';
@import 'widgets/ibus-popup';
// Notifications
@import 'widgets/notifications';
@import 'widgets/hotplug';
// Dialogs
@import 'widgets/dialogs';
@import 'widgets/network-dialog';
// OSDs
@import 'widgets/osd';
@import 'widgets/switcher-popup';
@import 'widgets/workspace-switcher';
// Panel
@import 'widgets/panel';
@import 'widgets/corner-ripple';
// Overview
@import 'widgets/overview';
@import 'widgets/window-picker';
@import 'widgets/search-entry';
@import 'widgets/search-results';
@import 'widgets/slider';
@import 'widgets/switches';
@import 'widgets/app-grid';
@import 'widgets/dash';
@import 'widgets/workspace-thumbnails';
// A11y / misc
@import 'widgets/a11y';
@import 'widgets/misc';
@import 'widgets/tiled-previews';
@import 'widgets/window-picker';
@import 'widgets/workspace-switcher';
@import 'widgets/keyboard';
@import 'widgets/looking-glass';
// Lock / login screens
@import 'widgets/login-dialog';
@import 'widgets/screen-shield';

View File

@@ -0,0 +1,24 @@
// Pointer location
.ripple-pointer-location {
width: $ripple_size;
height: $ripple_size;
border-radius: $ripple_size * 0.5; // radius equals the size of the box to give us the curve
background-color: lighten(transparentize($selected_bg_color, 0.7), 30%);
box-shadow: 0 0 2px 2px lighten($selected_bg_color, 20%);
}
// Pointer accessibility notifications
.pie-timer {
width: 60px;
height: 60px;
-pie-border-width: 3px;
-pie-border-color: $selected_bg_color;
-pie-background-color: lighten(transparentize($selected_bg_color, 0.7), 40%);
}
// Screen zoom/Magnifier
.magnifier-zoom-region {
border: 2px solid $selected_bg_color;
&.full-screen { border-width: 0; }
}

View File

@@ -11,7 +11,6 @@ $app_icon_padding: 24px;
.overview-icon {
icon-size: $app_icon_size;
StIcon { margin-bottom: $base_margin; } // margin on icon so label isn't close
}
}
@@ -21,59 +20,16 @@ $app_icon_padding: 24px;
$app_grid_fg_color: #fff;
// Outline for low res icons
.lowres-icon {
icon-shadow: 0 1px 2px rgba(0,0,0,0.3);
}
// Dropshadow for large icons
.icon-dropshadow {
icon-shadow: 0 1px 2px rgba(0,0,0,0.4);
}
// Icon tiles in the app grid
.app-well-app,
.app-folder {
%app-well-app {
@include overview-icon($app_grid_fg_color);
.overview-icon {
@extend %icon_tile;
color: $app_grid_fg_color !important;
}
.overview-icon.overview-icon-with-label {
padding: 10px 8px 5px 8px;
&:selected {
.overview-icon {
background-color: transparentize($osd_bg_color,0.7);
color: $app_grid_fg_color;
}
}
&:hover,
&:focus,
&:selected {
.overview-icon {
background-color: transparentize($osd_fg_color,0.9);
color: $osd_fg_color;
}
}
&:focus {
.overview-icon {
background-color: transparentize($osd_fg_color,0.7 );
// border-color: $selected_bg_color;
color: $app_grid_fg_color;
}
}
&:drop {
.overview-icon {
background-color: transparentize($selected_bg_color,.15);
}
}
&:active,
&:checked {
.overview-icon {
background-color: transparentize(darken($osd_bg_color,10%), 0.5);
> StBoxLayout {
spacing: $base_spacing;
}
}
}
@@ -81,18 +37,18 @@ $app_grid_fg_color: #fff;
/* App Folders */
.app-folder {
.overview-icon {
@extend %icon_tile;
}
}
// expanded folder
.app-folder-dialog {
border-radius: 8px;
spacing: 24px;
border-radius: $modal_radius * 1.5;
border: 1px solid $osd_outer_borders_color;
spacing: 12px;
background-color: transparentize(darken($osd_bg_color,10%), 0.05);
& .folder-name-container {
padding: 12px 18px;
padding: 24px 36px 0;
spacing: 12px;
& .folder-name-label,
@@ -117,6 +73,10 @@ $app_grid_fg_color: #fff;
& > StIcon { icon-size: 16px }
}
}
& StButton#vhandle,
& StButton#vhandle:hover,
& StButton#vhandle:active { background-color: transparent; }
}
.app-folder-dialog-container {
padding: 12px;
@@ -173,11 +133,6 @@ $app_grid_fg_color: #fff;
padding: 0px 88px 10px 88px;
}
.app-well-app > .overview-icon.overview-icon-with-label {
padding: 10px 8px 5px 8px;
spacing: $base_spacing;
}
// Label when no frequent apps
.no-frequent-applications-label { @extend %status_text; }
@@ -197,41 +152,35 @@ $app_grid_fg_color: #fff;
}
// buttons
.app-view-control {
padding: $base_padding $base_padding*5;
margin: 0;
background-color: transparentize($osd_bg_color, 0.5);
border-width: 1px;
color: darken($osd_fg_color, 25%);
.app-view-control {
padding: 4px 32px;
margin: 0 4px;
&:hover {
background-color: transparentize($osd_bg_color, 0.5) !important;
box-shadow:none !important;
&, &:hover, &:checked {
@include button(undecorated);
color: darken($osd_fg_color, 25%);
}
&:hover {
color: $osd_fg_color;
box-shadow: inset 0 -2px darken($osd_fg_color, 25%);
}
&:active {
box-shadow: none;
background-color: $selected_bg_color !important;
&:hover {
background-color: lighten($selected_bg_color, 11%) !important;
}
box-shadow: inset 0 -2px $osd_fg_color;
}
&:checked {
background-color: $selected_bg_color !important;
color: $selected_fg_color;
box-shadow: none;
&:active { background-color: darken($selected_bg_color, 4%) !important; }
&:hover { background-color: lighten($selected_bg_color, 7%) !important; }
color: $osd_fg_color;
box-shadow: inset 0 -2px $selected_bg_color;
}
&:first-child {
border-right-width: 0 !important;
border-radius: $base_border_radius 0 0 $base_border_radius;
border-right-width: 0;
border-radius: 0;
}
&:last-child {
border-radius: 0 $base_border_radius $base_border_radius 0;
border-radius: 0;
}
}

View File

@@ -0,0 +1,18 @@
// Links
.shell-link {
color: $link_color;
&:hover {
color: lighten($link_color, 10%);
}
}
// Outline for low res icons
.lowres-icon {
icon-shadow: 0 1px 2px rgba(black, 0.3);
}
// Dropshadow for large icons
.icon-dropshadow {
icon-shadow: 0 1px 2px rgba(black, 0.4);
}

View File

@@ -1,87 +1,65 @@
/* Date/Time Menu */
.clock-display-box { spacing: $base_spacing; }
.clock-display-box {
spacing: $base_spacing / 2;
.clock {
padding-left: $base_padding;
padding-right: $base_padding;
}
}
// overall menu
#calendarArea {
padding:0;
margin:0;
}
// Calendar menu side column
.datemenu-calendar-column {
spacing: 0;
spacing: $base_spacing;
border: 0 solid $bubble_borders_color;
padding: $base_padding * 2;
padding-bottom: 3em; // account for the notifications clear button
padding-top:0;
padding: 0 $base_padding * 2;
&:ltr {margin-right: $base_margin * 2; border-left-width: 1px; }
&:rtl {margin-left: $base_margin * 2; border-right-width: 1px; }
// today button (the date)
.datemenu-today-button {
padding: $base_padding * 1.5;
margin: $base_margin;
border: 1px solid transparent;
border-radius: $base_border_radius + 2px;
&:hover { @include button(hover);}
&:focus { @include button(focus);}
&:active {
@include button(active);
}
// weekday label
.day-label {
@include fontsize($base_font_size+1);
font-weight: bold;
}
// date label
.date-label {
@include fontsize($base_font_size+7);
font-weight: 1000;
}
}
// calendar
.calendar {
@extend %notification_bubble;
margin:$base_margin !important;
margin-bottom: $base_padding + $base_margin !important;
padding:$base_padding !important;
// more below for sub-elements
}
.datemenu-displays-section {
margin:0;
}
.datemenu-displays-box {
spacing: $base_spacing;
margin:0;
// world clocks and weather
.world-clocks-button,
.weather-button {
@extend %notification_bubble;
padding:$base_padding !important;
}
}
}
.events-section-title {
@include notification_bubble($flat: true);
color: desaturate(darken($fg_color,40%), 10%);
font-weight: bold;
border-radius: 4px;
padding: .4em;
}
/* today button (the date) */
.datemenu-today-button {
@include notification_bubble($flat: true);
padding: $base_padding * 1.5;
// weekday label
.day-label {
@include fontsize($base_font_size+1);
font-weight: bold;
}
// date label
.date-label {
@include fontsize($base_font_size+7);
font-weight: 1000;
}
}
/* Calendar */
.calendar {
@include notification_bubble;
padding: $base_padding;
// month
.calendar-month-label {
@@ -132,6 +110,7 @@
@include fontsize($base_font_size - 4);
}
}
.calendar-day { //border collapse hack - see calendar.js
border-width: 0;
}
@@ -140,8 +119,12 @@
border-top-width: 1px;
}
.calendar-day-left { border-left-width: 1px; }
.calendar-day-left {
border-left-width: 1px;
}
.calendar-work-day {}
.calendar-nonwork-day {
color: $insensitive_fg_color;
}
@@ -161,13 +144,14 @@
&:active,&:selected {
background-color: $selected_bg_color;
color: $selected_fg_color;
&:hover,&:focus {
background-color:lighten($selected_bg_color, 3%);
color: $selected_fg_color;
}
}
}
.calendar-day-with-events {
color: lighten($fg_color,10%);
font-weight: bold;
@@ -176,7 +160,6 @@
.calendar-other-month-day {
color: transparentize($fg_color ,0.5);
opacity: 0.5;
}
.calendar-week-number {
@@ -192,51 +175,16 @@
}
}
/* World clocks */
.world-clocks-button {
@include notification_bubble;
padding: $base_padding * 2;
/* Weather */
.weather-box {
spacing: $base_spacing;
padding:$base_padding;
.weather-header {
color: desaturate(darken($fg_color,40%), 10%);
font-weight: bold;
&.location {
font-weight: normal;
@include fontsize($base_font_size - 1);
}
}
.weather-grid {
margin-top: $base_margin;
.world-clocks-grid {
spacing-rows: $base_spacing;
spacing-columns: $base_spacing * 2;
}
.weather-forecast-time {
color: darken($fg_color,30%);
font-feature-settings: "tnum";
@include fontsize($base_font_size - 2);
font-weight: normal;
padding-top: 0.2em;
padding-bottom: 0.4em;
}
.weather-forecast-icon {
icon-size: $base_icon_size * 2;
}
.weather-forecast-temp {
font-weight: bold;
}
}
/* World clocks */
.world-clocks-grid {
padding:$base_padding;
spacing-rows: $base_spacing;
spacing-columns: $base_spacing * 2;
// title
.world-clocks-header {
color: desaturate(darken($fg_color,40%), 10%);
@@ -266,3 +214,49 @@
@include fontsize($base_font_size - 1);
}
}
/* Weather */
.weather-button {
@include notification_bubble;
padding: $base_padding * 2;
.weather-box {
spacing: $base_spacing + $base_margin;
}
.weather-header-box {
spacing: $base_spacing;
}
.weather-header {
color: desaturate(darken($fg_color,40%), 10%);
font-weight: bold;
&.location {
font-weight: normal;
@include fontsize($base_font_size - 1);
}
}
.weather-grid {
spacing-rows: $base_spacing;
spacing-columns: $base_spacing * 2;
}
.weather-forecast-time {
color: darken($fg_color,30%);
font-feature-settings: "tnum";
@include fontsize($base_font_size - 2);
font-weight: normal;
padding-top: 0.2em;
padding-bottom: 0.4em;
}
.weather-forecast-icon {
icon-size: $base_icon_size * 2;
}
.weather-forecast-temp {
font-weight: bold;
}
}

View File

@@ -13,12 +13,3 @@ $ripple_size: 50px;
// just a simple change to the border radius position
&:rtl { border-radius: 0 0 0 $ripple_size + 2px; }
}
// Pointer location
.ripple-pointer-location {
width: $ripple_size;
height: $ripple_size;
border-radius: $ripple_size * 0.5; // radius equals the size of the box to give us the curve
background-color: lighten(transparentize($selected_bg_color, 0.7), 30%);
box-shadow: 0 0 2px 2px lighten($selected_bg_color, 20%);
}

View File

@@ -9,12 +9,11 @@ $dash_border_radius: $modal_radius * 1.5;
@include fontsize($base_font_size - 2);
padding: ($dash_spacing / 2) 0;
//fixme: can't have non uniform borders :(
border-radius: 0 $dash_border_radius $dash_border_radius 0;
border-left-width: 0 !important;
&:rtl {
border-left-width: 0;
&:rtl {
border-radius: $dash_border_radius 0 0 $dash_border_radius;
border-right-width: 0 !important;
border-right-width: 0;
}
.placeholder {
@@ -49,36 +48,13 @@ $dash_border_radius: $modal_radius * 1.5;
// Show apps button
.show-apps {
color: $osd_fg_color;
@include overview-icon($osd_fg_color);
& .overview-icon {
@extend %icon_tile;
color: $osd_fg_color;
}
&:hover,
&:focus,
&:selected {
.overview-icon {
background-color: transparentize($osd_fg_color,0.9);
color: $osd_fg_color;
}
}
&:drop .overview-icon {
background-color: transparentize($selected_bg_color,.15);
}
&:active, &:checked {
&:checked {
.overview-icon {
background-color: darken($osd_bg_color,10%);
}
}
&:checked, &:focus {
.show-apps-icon {
color: $fg_color;
transition-duration: 100ms;
}
}
}

View File

@@ -1,5 +1,9 @@
/* Modal Dialogs */
.headline {
@include fontsize($base_font_size + 1);
}
.modal-dialog {
border-radius: $modal_radius;
@extend %bubble_panel;
@@ -15,12 +19,7 @@
}
}
.mount-dialog-subject {
@include fontsize($base_font_size + 3);
}
/* End Session Dialog */
.end-session-dialog {
width: 30em;
@@ -38,6 +37,11 @@
text-align: center;
font-size: 18pt;
font-weight: 800;
&.leightweight {
font-size: 13pt;
font-weight: 800;
}
}
.message-dialog-description { text-align: center; }
}
@@ -84,76 +88,58 @@
/* Password or Authentication Dialog */
.prompt-dialog {
//this is the width of the entire modal popup
width: 34em;
width: 28em;
.message-dialog-content { spacing: $base_spacing * 4; }
.message-dialog-title { color: lighten($fg_color,15%); }
.modal-dialog-content-box {
margin-bottom: 24px;
}
}
.prompt-dialog-description:rtl {
text-align: right;
.prompt-dialog-password-grid {
spacing-rows: 8px;
spacing-columns: 4px;
.prompt-dialog-password-entry {
width: auto;
// 4px (spacing) + 16px (spinner-width)
&:ltr { margin-left: 20px; }
&:rtl { margin-right: 20px; }
}
}
.prompt-dialog-password-box {
spacing: 1em;
padding-bottom: 1em;
.prompt-dialog-password-layout {
spacing: 8px;
}
.prompt-dialog-password-entry {
width: 20em;
}
.prompt-dialog-error-label,
.prompt-dialog-info-label,
.prompt-dialog-null-label {
text-align: center;
@include fontsize($base_font_size - 1);
}
.prompt-dialog-error-label {
@include fontsize($base_font_size - 1);
color: $warning_color;
padding-bottom: 8px;
}
.prompt-dialog-info-label {
@include fontsize($base_font_size - 1);
padding-bottom: 8px;
}
.prompt-dialog-null-label {
@include fontsize($base_font_size - 1);
padding-bottom: 8px;
}
.prompt-dialog-pim-box {
spacing: 1em;
}
.prompt-dialog-grid {
spacing-rows: 15px;
spacing-columns: 1em;
}
.prompt-dialog-keyfiles-box {
spacing: 1em;
}
.prompt-dialog-button.button {
padding: 8px;
}
/* Polkit Dialog */
.polkit-dialog-user-layout {
padding-left: 10px;
spacing: 10px;
&:rtl {
padding-left: 0px;
padding-right: 10px;
text-align: center;
spacing: 8px;
margin-bottom: 6px;
.polkit-dialog-user-icon {
border-radius: 99px;
background-size: contain;
}
}
.polkit-dialog-user-root-label {
color: $warning_color;
}
.polkit-dialog-user-icon {
border-radius: 99px;
background-size: contain;
width: 48px;
height: 48px;
.polkit-dialog-user-root-label { color: $warning_color; }
}
/* Audio selection dialog */
@@ -180,20 +166,3 @@
.audio-selection-device-icon {
icon-size: $base_icon_size * 4;
}
/* Access Dialog */
.access-dialog {
spacing: 30px;
}
/* Network Agent Dialog */
.network-dialog-secret-table {
spacing-rows: 15px;
spacing-columns: 1em;
}
.keyring-dialog-control-table {
spacing-rows: 15px;
spacing-columns: 1em;
}

View File

@@ -1,4 +1,9 @@
// IBus Candidate Popup
.candidate-popup-boxpointer {
@extend .popup-menu-boxpointer;
}
.candidate-popup-content {
padding: 0.5em;
spacing: 0.3em;

View File

@@ -10,7 +10,7 @@ $default_key_bg_color: if($variant=='light', darken($osd_bg_color, 11%), lighten
// draw keys using button function
#keyboard {
background-color: transparentize(if($variant=='light', darken($bg_color, 5%), darken($bg_color, 8%)), 0.1);
box-shadow: inset 0 1px 0 0 $osd_outer_borders_color !important;
box-shadow: inset 0 1px 0 0 $osd_outer_borders_color;
.page-indicator {
padding: $base_padding;
@@ -52,10 +52,6 @@ $default_key_bg_color: if($variant=='light', darken($osd_bg_color, 11%), lighten
// non-character keys
&.default-key {
// size of the icon asset
background-size: 24px;
@include button(normal, $c:$default_key_bg_color);
&:hover, &:checked {@include button(hover, $c: $default_key_bg_color);}
&:active { @include button(active, $c: $default_key_bg_color);}
@@ -63,19 +59,14 @@ $default_key_bg_color: if($variant=='light', darken($osd_bg_color, 11%), lighten
// enter key is suggested-action
&.enter-key {
background-image: url("resource:///org/gnome/shell/theme/key-enter.svg");
@include button(normal, $c:$selected_bg_color, $tc:$selected_fg_color);
&:hover, &:checked { @include button(hover, $c: lighten($selected_bg_color, 3%));}
&:active {@include button(active, $c: darken($selected_bg_color, 2%));}
}
// key assets
&.shift-key-lowercase {background-image: url("resource:///org/gnome/shell/theme/key-shift.svg");}
&.shift-key-uppercase {background-image: url("resource:///org/gnome/shell/theme/key-shift-uppercase.svg");}
&.shift-key-uppercase:latched {background-image: url("resource:///org/gnome/shell/theme/key-shift-latched-uppercase.svg");}
&.hide-key {background-image: url("resource:///org/gnome/shell/theme/key-hide.svg");}
&.layout-key {background-image: url("resource:///org/gnome/shell/theme/key-layout.svg");}
&.shift-key-uppercase { color: $selected_bg_color }
StIcon { icon-size: 1.125em; }
}
// long press on a key popup
@@ -121,4 +112,4 @@ $default_key_bg_color: if($variant=='light', darken($osd_bg_color, 11%), lighten
@include fontsize($base_font_size + 3);
spacing: 12px;
min-height: 20pt;
}
}

View File

@@ -68,12 +68,30 @@
}
}
}
.cancel-button,
.switch-user-button,
.login-dialog-session-list-button {
padding: 0;
border-radius: 99px;
width: $base_icon_size * 2;
height: $base_icon_size * 2;
border-color: transparentize($bg_color,0.7);
background-color: transparentize($bg_color,0.7);
StIcon { icon-size: $base_icon_size; }
}
.caps-lock-warning-label,
.login-dialog-message-warning {
color: $osd_fg_color;
}
}
.login-dialog-logo-bin { padding: 24px 0px; }
.login-dialog-banner { color: darken($osd_fg_color,10%); }
.login-dialog-button-box { spacing: 5px; }
.login-dialog-message-warning { color: $warning_color; }
.login-dialog-button-box { width: 23em; spacing: 5px; }
.login-dialog-message { text-align: center; }
.login-dialog-message-hint { padding-top: 0; padding-bottom: 20px; }
.login-dialog-user-selection-box { padding: 100px 0px; }
.login-dialog-not-listed-label {
@@ -100,7 +118,7 @@
}
.login-dialog-user-list-item {
border-radius: 5px;
border-radius: $base_border_radius + 4px;
padding: 6px;
color: darken($osd_fg_color,30%);
&:ltr .user-widget { padding-right: 1em; }
@@ -113,20 +131,27 @@
&:focus .login-dialog-timed-login-indicator { background-color: $selected_fg_color; }
}
.login-dialog-username,
.user-widget-label {
color: $osd_fg_color;
}
.user-widget.horizontal .user-widget-label {
@include fontsize($base_font_size + 2);
font-weight: bold;
text-align: left;
padding-left: 15px;
}
.user-widget-label {
&:ltr { padding-left: 14px; }
&:rtl { padding-right: 14px; }
}
.user-widget.vertical .user-widget-label {
@include fontsize($base_font_size + 5);
text-align: center;
font-weight: normal;
padding-top: 16px;
}
.login-dialog-prompt-layout {
padding-top: 24px;
padding-bottom: 12px;
@@ -134,18 +159,12 @@
width: 23em;
}
.login-dialog-prompt-entry {
height: 1.5em;
}
.login-dialog-prompt-label {
color: darken($osd_fg_color, 20%);
@include fontsize($base_font_size + 1);
padding-top: 1em;
}
.login-dialog-session-list-button StIcon {
icon-size: 1.25em;
}
.login-dialog-session-list-button {
color: darken($osd_fg_color,30%);
&:hover,&:focus { color: $osd_fg_color; }
&:active { color: darken($osd_fg_color, 50%); }
}

View File

@@ -5,14 +5,14 @@
background-color: $osd_bg_color;
spacing: $base_spacing;
padding: 4px;
border: 2px solid transparentize($osd_fg_color, 0.8);
border-top-width:0;
border-radius: 0 0 $base_border_radius $base_border_radius;
border: 1px solid transparentize($osd_fg_color, 0.8);
border-radius: $base_border_radius;
color: $osd_fg_color;
& > #Toolbar {
border: none;
border-radius: $base_border_radius;
background-color: darken($osd_bg_color, 10%);
background-color: $osd_bg_color;
}
.labels { spacing: $base_spacing; }
@@ -20,19 +20,18 @@
-natural-hpadding: $base_padding * 2;
-minimum-hpadding: 6px;
font-weight: bold;
color: $fg_color;
color: darken($osd_fg_color, 15%);
transition-duration: 100ms;
padding-left: .3em;
padding-right: .3em;
border-bottom-width: 2px;
&:hover {
color: white;
text-shadow: black 0px 2px 2px;
color: $osd_fg_color;
}
&:selected {
border-bottom-width: 2px;
border-color: lighten($selected_bg_color,5%);
color: white;
text-shadow: black 0px 2px 2px;
box-shadow: inset 0 -2px 0 0 lighten($selected_bg_color, 5%);
color: $osd_fg_color;
}
}
StBoxLayout#EvalBox { padding: 4px; spacing: $base_spacing; }
@@ -41,12 +40,17 @@
.lg-dialog {
StEntry {
selection-background-color: #bbbbbb;
selected-color: $osd_bg_color;
background-color: transparentize(lighten($osd_bg_color, 5%), 0.4);
color: $osd_fg_color;
border-color: transparentize($osd_fg_color, 0.8);
min-height: 22px;
selection-background-color: $selected_bg_color;
selected-color: $selected_fg_color;
}
.shell-link {
color: #999999;
&:hover { color: #dddddd; }
color: $link_color;
&:hover { color: lighten($link_color, 10%); }
&:active { color: darken($link_color, 10%); }
}
}
@@ -60,7 +64,7 @@
}
.lg-obj-inspector-button {
border: 1px solid gray;
border: 1px solid $osd_borders_color;
padding: 4px;
border-radius: $base_border_radius;
&:hover { border: 1px solid #ffffff; }
@@ -75,7 +79,8 @@
}
.lg-extension {
border: 1px solid $osd_borders_color;
border: 1px solid lighten($osd_borders_color, 5%);
background-color: lighten($osd_bg_color, 5%);
border-radius: $base_border_radius;
padding: 4px;
}

View File

@@ -11,7 +11,7 @@
.message-list-sections {
spacing: $base_spacing;
margin: $base_margin * 4; // to account for scrollbar
margin: 0 $base_margin * 4; // to account for scrollbar
}
.message-list-section,
@@ -19,40 +19,61 @@
spacing: $base_spacing;
}
.message-list-section-list {
&:ltr {padding:0;}
&:rtl {padding:0;}
}
// do-not-disturb + clear button
.message-list-controls {
margin: $base_margin $base_margin*2;
spacing: $base_spacing;
margin: ($base_margin * 2) ($base_margin * 4) 0;
// NOTE: remove the padding if notification_bubble could remove margin for drop shadow
padding: $base_margin;
spacing: $base_spacing * 2;
}
// message bubbles
.message {
@extend %notification_bubble;
@include notification_bubble;
// title
.message-title {
color: $fg_color;
font-weight: bold;
margin-bottom:4px;
// icon container
.message-icon-bin {
padding: ($base_padding * 3) 0 ($base_padding * 3) ($base_padding * 2);
&:rtl {
padding: ($base_padding * 3) ($base_padding * 2) ($base_padding * 3) 0;
}
// icon size and color
> StIcon {
icon-size: $base_icon_size*2; // 32px
-st-icon-style: symbolic;
}
// fallback
> .fallback-app-icon {
width: $base_icon_size;
height: $base_icon_size;
}
}
// content
.message-content {
color: darken($fg_color, 10%);
padding: $base_padding 0;
margin:$base_margin * 2;
&:ltr {
margin-left: $base_margin;
padding-right:$base_padding;
}
&:rtl {
margin-right: $base_margin;
padding-left:$base_padding;
padding: $base_padding + $base_margin * 2;
spacing: 4px;
}
// title
.message-title {
font-weight: bold;
}
// secondary container in title box
.message-secondary-bin {
padding: 0 $base_margin * 2;
// notification time stamp
> .event-time {
color: transparentize($fg_color, 0.5);
@include fontsize($base_font_size - 2);
text-align: right;
/* HACK: the label should be baseline-aligned with a 1em label, fake this with some bottom padding */
padding-bottom: 0.13em;
}
}
@@ -63,48 +84,15 @@
&:active { color: if($variant=='light', lighten($fg_color, 40%), darken($fg_color, 20%)); }
}
// icon container
.message-icon-bin {
padding: $base_padding;
margin:$base_padding 0;
&:rtl {
// padding: $base_padding;
}
// icon size and color
> StIcon {
color: $fg_color;
icon-size: $base_icon_size*2; // 32px
-st-icon-style: symbolic;
padding:0;
margin:$base_padding;
}
// fallback
> .fallback-app-icon {
width: $base_icon_size;
height: $base_icon_size;
}
}
// secondary container in title box
.message-secondary-bin {
padding: 0;
// notification time stamp
> .event-time {
color: transparentize($fg_color, 0.5);
@include fontsize($base_font_size - 2);
text-align: right;
margin: 0 $base_margin * 2;
/* HACK: the label should be baseline-aligned with a 1em label, fake this with some bottom padding */
padding-bottom: $base_padding;
}
// body
.message-body {
color: darken($fg_color, 10%);
}
}
// URLs in messages
.url-highlighter {
link-color: $link_color;
}
/* Media Controls */
@@ -125,9 +113,9 @@
&:insensitive { color: darken($fg_color,40%); }
// fix border-radius for last button on hover
&:last-child:ltr { &:hover {border-radius: 0 $base_border_radius+2 $base_border_radius+2 0;} }
&:last-child:rtl { &:hover {border-radius: $base_border_radius+2 0 0 $base_border_radius+2;} }
// fix border-radius for last button
&:last-child:ltr { border-radius: 0 $base_border_radius+2 $base_border_radius+2 0; }
&:last-child:rtl { border-radius: $base_border_radius+2 0 0 $base_border_radius+2; }
}
// album-art
@@ -142,6 +130,5 @@
border: 1px solid transparent;
border-radius: $base_border_radius;
icon-size: $base_icon_size * 2 !important;
padding: $base_padding * 2;
}
}

View File

@@ -1,32 +1,9 @@
// Links/URLs
.shell-link {
color: $link_color;
&:hover { color: lighten($link_color,10%); }
}
.url-highlighter { link-color: $link_color; }
// Rubberband for select-area screenshots
.select-area-rubberband {
background-color: transparentize($selected_bg_color,0.7);
border: 1px solid $selected_bg_color;
}
// Pointer accessibility notifications
.pie-timer {
width: 60px;
height: 60px;
-pie-border-width: 3px;
-pie-border-color: $selected_bg_color;
-pie-background-color: lighten(transparentize($selected_bg_color, 0.7), 40%);
}
// Screen zoom/Magnifier
.magnifier-zoom-region {
border: 2px solid $selected_bg_color;
&.full-screen { border-width: 0; }
}
// User icon
.user-icon {
background-size: contain;
@@ -35,22 +12,33 @@
&:hover {
color: lighten($osd_fg_color,30%);
}
& StIcon {
background-color: transparentize($osd_fg_color,0.95);
border-radius: 99px;
}
}
// Input Source Switcher
.input-source-switcher-symbol {
font-size: 34pt;
width: 96px;
height: 96px;
.user-widget.vertical .user-icon {
icon-size: $base_icon_size * 6; // 128px
& StIcon {
padding: $base_padding * 3 + 2px; // 20px
padding-top: $base_padding * 3; // 18 px
padding-bottom: $base_padding * 3 + 4px; // 22px
width: $base_icon_size * 5.5; height: $base_icon_size * 5.5; // 88px;
}
}
// Window cycler highlight
.cycler-highlight {
border: 5px solid $selected_bg_color;
.user-widget.horizontal .user-icon {
icon-size: $base_icon_size * 4; // 64px
& StIcon {
padding: $base_padding * 2 ; // 12px
width: $base_icon_size * 2.5; height: $base_icon_size * 2.5; // 40px;
}
}
// Text
.headline { @include fontsize($base_font_size + 1); }
.lightbox { background-color: black; }
.flashspot { background-color: white; }
@@ -60,8 +48,8 @@
// Caps-lock warning
.caps-lock-warning-label {
text-align: center;
padding-bottom: 8px;
padding-left: 6.2em;
@include fontsize($base_font_size - 1);
color: $warning_color;
}

View File

@@ -7,39 +7,8 @@ $notification_banner_width: 34em;
.notification-banner {
min-height: $notification_banner_height;
width: $notification_banner_width;
@include fontsize($base_font_size);
margin: $base_margin;
border-radius: $modal_radius;
.message-title { color: $fg_color }
.message-content { color: $fg_color; }
&:hover { background: $bg_color; }
&, &:focus, &:active {
background-color: $bg_color;
.message-title { color: $fg_color }
.message-content { color: $fg_color; }
}
// icon
.message-icon-bin > StIcon {
icon-size: $base_icon_size * 2;
color: $fg_color;
}
.notification-icon {
padding: 5px;
}
.notification-content {
padding: 5px;
spacing: 5px;
}
.secondary-icon { icon-size: $base_icon_size; }
.notification-actions {
padding-top: 0;
spacing: 0;
}
@@ -63,8 +32,6 @@ $notification_banner_width: 34em;
border-radius: 0.9em; // should be 0.8 but whatever; wish I could do 50%;
}
.secondary-icon { icon-size: $base_icon_size; }
// chat bubbles
.chat-body { spacing: 5px; }
.chat-response { margin: 5px; }
@@ -87,4 +54,4 @@ $notification_banner_width: 34em;
font-weight: bold;
color: lighten($fg_color,18%);
&:rtl { padding-left: 0; padding-right: 4px; }
}
}

View File

@@ -2,8 +2,8 @@
// a.k.a. the panel
$panel_corner_radius: $base_border_radius+1;
$panel_bg_color: if($variant == 'light', rgba(0,0,0,0.9), #000);
$panel_fg_color: if($variant == 'light', darken($fg_color, 15%), darken($fg_color, 10%));
$panel_bg_color: #000;
$panel_fg_color: #ccc;
$panel_height: 1.86em;
@@ -15,8 +15,7 @@ $panel_height: 1.86em;
// transparent panel on lock & login screens
&.unlock-screen,
&.login-screen,
&.lock-screen {
&.login-screen {
background-color: transparent;
.panel-corner {
@@ -55,9 +54,6 @@ $panel_height: 1.86em;
}
&:active, &:overview, &:focus, &:checked {
background-color: $panel_bg_color; // Trick due to St limitations. It needs a background to draw a box-shadow
box-shadow: inset 0 -2px 0 0 lighten($selected_bg_color,5%);
color: lighten($panel_fg_color, 20%);
}
@@ -77,13 +73,32 @@ $panel_height: 1.86em;
// lock & login screen styles
.unlock-screen &,
.login-screen &,
.lock-screen & {
.login-screen & {
color: lighten($fg_color, 10%);
&:focus, &:hover, &:active { color: lighten($fg_color, 10%); }
}
}
.panel-button {
&:active, &:overview, &:focus, &:checked {
// Trick due to St limitations. It needs a background to draw a box-shadow
background-color: rgba(0, 0, 0, 0.01);
box-shadow: inset 0 -2px 0 0 lighten($selected_bg_color,5%);
}
}
.panel-button.clock-display {
// Move highlight from .panel-button to .clock
&:active, &:overview, &:focus, &:checked {
box-shadow: none;
.clock {
background-color: rgba(0, 0, 0, 0.01);
box-shadow: inset 0 -2px 0 0 lighten($selected_bg_color,5%);
}
}
}
.panel-status-indicators-box,
.panel-status-menu-box {
spacing: 2px;

View File

@@ -3,8 +3,7 @@
$popover_arrow_height: 12px;
//.the popover itself
.popup-menu-boxpointer,
.candidate-popup-boxpointer {
.popup-menu-boxpointer {
-arrow-border-radius: $base_border_radius+4;
-arrow-background-color: $bg_color;
-arrow-border-width: 1px;
@@ -83,11 +82,20 @@ $popover_arrow_height: 12px;
// separator
.popup-separator-menu-item {
//-margin-horizontal: 24px;
height: 1px; //not really the whole box
margin: 6px 64px;
background-color: lighten($borders_color, 2%);
border: none !important;
padding: 0;
.popup-separator-menu-item-separator {
//-margin-horizontal: 24px;
height: 1px; //not really the whole box
margin: 6px 64px;
background-color: lighten($borders_color, 2%);
.popup-sub-menu & { //submenu separators
margin: 0 64px 0 32px;
@if $variant == 'dark' {
background-color: lighten($bg_color,10%);
}
}
}
}
// desktop background menu
@@ -118,4 +126,4 @@ $popover_arrow_height: 12px;
margin-right: $base_icon_size;
}
}
}
}

View File

@@ -1,68 +1,64 @@
/* Screen Shield */
$_screenshield_shadow: 0px 0px 6px rgba(0, 0, 0, 0.726);
.screen-shield-arrows {
padding-bottom: 3em;
}
.screen-shield-arrows Gjs_Arrow {
.unlock-dialog-clock {
color: white;
width: 80px;
height: 48px;
-arrow-thickness: 12px;
-arrow-shadow: $_screenshield_shadow;
}
.screen-shield-clock {
color: white;
text-shadow: $_screenshield_shadow;
font-weight: bold;
font-weight: 300;
text-align: center;
padding-bottom: 1.5em;
spacing: 24px;
padding-bottom: 2.5em;
}
.screen-shield-clock-time {
font-size: 72pt;
text-shadow: $_screenshield_shadow;
.unlock-dialog-clock-time {
font-size: 64pt;
padding-top: 42px;
font-feature-settings: "tnum";
}
.screen-shield-clock-date {
font-size: 28pt;
.unlock-dialog-clock-date {
font-size: 16pt;
font-weight: normal;
}
.screen-shield-notifications-container {
.unlock-dialog-clock-hint {
font-weight: normal;
padding-top: 48px;
}
.unlock-dialog-notifications-container {
margin: 12px 0;
spacing: 6px;
width: 30em;
width: 23em;
background-color: transparent;
max-height: 500px;
.summary-notification-stack-scrollview {
padding-top: 0;
padding-bottom: 0;
}
.notification,
.screen-shield-notification-source {
.unlock-dialog-notification-source {
padding: 12px 6px;
border: 1px solid $osd_outer_borders_color;
background-color: transparentize($osd_bg_color,0.5);
border: none;
background-color: transparentize($osd_bg_color,0.7);
color: $osd_fg_color;
border-radius: 4px;
border-radius: $modal_radius;
&.critical { background-color: transparentize($osd_bg_color,0.1) }
}
.notification { margin-right: 15px; } //compensate for space allocated to the scrollbar
}
.screen-shield-notification-label {
font-weight: bold;
.unlock-dialog-notification-label {
padding: 0px 0px 0px 12px;
}
.screen-shield-notification-count-text { padding: 0px 0px 0px 12px; }
.unlock-dialog-notification-count-text {
weight: bold;
padding: 0 6px;
color: $osd_bg_color;
background-color: transparentize($osd_fg_color, 0.7);
border-radius: 99px;
margin-right: 12px;
#panel.lock-screen { background-color: transparentize($osd_bg_color, 0.5); }
}
.screen-shield-background { //just the shadow, really
background: black;
@@ -70,14 +66,13 @@ $_screenshield_shadow: 0px 0px 6px rgba(0, 0, 0, 0.726);
}
#lockDialogGroup {
background: lighten(#2e3436, 8%) url(resource:///org/gnome/shell/theme/noise-texture.png);
background-repeat: repeat;
background-color: lighten(#2e3436, 8%);
}
#screenShieldNotifications {
#unlockDialogNotifications {
StButton#vhandle, StButton#hhandle {
background-color: transparentize($bg_color,0.7);
&:hover, &:focus { background-color: transparentize($bg_color,0.5); }
&:active { background-color: transparentize($selected_bg_color,0.5); }
}
}
}

View File

@@ -3,19 +3,16 @@
// search overview container
#searchResultsContent {
max-width: 1024px;
spacing: $base_margin * 2;
}
// search results sections "the boxes"
.search-section {
// This should be equal to #searchResultsContent spacing
spacing: $base_margin * 2;
padding:0 !important;
margin:0 !important;
background-color:transparent;
box-shadow:none;
border:none;
// separator
.search-section-separator {
// margin-top: $base_padding * 2;
// height: 1px;
// background-color: $osd_outer_borders_color;
height: 0;
@@ -32,8 +29,24 @@
text-shadow: 0 1px if($variant == 'light', rgba(255,255,255,0.2), rgba(0,0,0,0.2));
color: $osd_fg_color;
padding: $base_padding * 3;
margin: $base_margin 0;
spacing: 0;
// This is the space between the provider icon and the results container
spacing: $base_margin * 2;
}
%search-section-content-item {
@extend %icon_tile;
&:focus,
&:hover,
&:selected {
background-color: transparentize($osd_fg_color, .9);
transition-duration: 200ms;
}
&:active,
&:checked {
background-color: transparentize(darken($osd_bg_color, 10%), .1);
}
}
// "no results" text
@@ -43,54 +56,12 @@
// Search results with icons
.grid-search-result {
> .overview-icon {
@extend %icon_tile;
color: $osd_fg_color;
}
> .overview-icon.overview-icon-with-label {
padding: 10px 8px 5px 8px;
spacing: $base_spacing;
}
&:hover,
&:focus,
&:selected {
.overview-icon {
background-color: transparentize($osd_bg_color,0.8);
color: $osd_fg_color;
}
}
&:drop .overview-icon {
background-color: transparentize($selected_bg_color,.15);
}
&:active .overview-icon,
&:checked .overview-icon {
background-color: transparentize(darken($osd_bg_color,10%), 0.5);
}
@extend %app-well-app;
}
// search result provider
.search-provider-icon {
@extend %icon_tile;
padding: $base_padding;
spacing: 0;
margin-right: $base_margin * 2;
&:focus,
&:selected,
&:hover {
background-color: transparentize($osd_fg_color,.9);
transition-duration: 200ms;
}
&:active,
&:checked {
background-color: transparentize(darken($osd_bg_color,10%),.1);
}
@extend %search-section-content-item;
// content
.list-search-provider-content {
@@ -113,34 +84,16 @@
// search result listitem
.list-search-result {
@extend %icon_tile;
spacing: 0;
padding: $base_padding;
color: $osd_fg_color;
border-radius: $base_border_radius + 2px !important;
&:focus,
&:selected,
&:hover {
background-color: transparentize($osd_fg_color,.9);
transition-duration: 200ms;
}
&:active,
&:checked {
background-color: transparentize(darken($osd_bg_color,10%),.1);
}
@extend %search-section-content-item;
// content
.list-search-result-content {
spacing: 0;
spacing: $base_padding;
}
// list item title
// list item title (with leading icon)
.list-search-result-title {
color: $osd_fg_color;
spacing: $base_spacing * 2;
padding-right: $base_padding;
// font-weight: bold;
}

View File

@@ -52,4 +52,16 @@
&:highlighted {
color: $fg_color;
}
}
}
// Input Source Switcher
.input-source-switcher-symbol {
font-size: 34pt;
width: 96px;
height: 96px;
}
// Window cycler highlight
.cycler-highlight {
border: 5px solid $selected_bg_color;
}

View File

@@ -1,7 +1,7 @@
/* Window Picker */
$window_picker_spacing: $base_spacing * 8; // 48px
$window_picker_padding: $base_padding * 10; // 60px
$window_picker_spacing: $base_spacing * 2; // 16px
$window_picker_padding: $base_padding * 2; // 16px
$window_thumbnail_border_color:transparentize($selected_fg_color, 0.65);
@@ -63,4 +63,4 @@ $window_close_button_padding: 3px;
&:active {
background-color: darken($selected_bg_color, 5%);
}
}
}

View File

@@ -16,7 +16,6 @@
}
.ws-switcher-box {
// background: transparent;
background: transparent;
height: 50px;
background-size: 32px;
@@ -29,44 +28,9 @@
.ws-switcher-active-down,
.ws-switcher-active-left,
.ws-switcher-active-right {
height: 52px;
background-color: $selected_bg_color;
border: 1px solid if($variant=='light', darken($selected_bg_color, 8%), lighten($selected_bg_color, 5%));
border-radius: $base_border_radius + 3px;
color: $selected_fg_color;
}
/* Workspace pager */
// thumbnails in overview
.workspace-thumbnails {
@extend %overview_panel;
visible-width: 32px; //amount visible before hover
spacing: $base_spacing;
padding: $base_padding;
border-radius: $modal_radius 0 0 $modal_radius;
border-right-width: 0 !important;
//fixme: can't have non uniform borders :(
border-top-left-radius:0 !important;
border-bottom-left-radius:0 !important;
&:rtl {
border-radius: 0 $modal_radius $modal_radius 0;
border-left-width: 0 !important;
}
// drag and drop indicator
.placeholder {
background-image: url("resource:///org/gnome/shell/theme/dash-placeholder.svg");
background-size: contain;
height: 24px;
}
}
// selected indicator
.workspace-thumbnail-indicator {
border: 3px solid $selected_bg_color;
border-radius: 3px;
padding: 0px;
// background-color: transparentize($selected_bg_color, 0.9);
}

View File

@@ -0,0 +1,32 @@
/* Workspace pager */
// thumbnails in overview
.workspace-thumbnails {
@extend %overview_panel;
visible-width: 32px; //amount visible before hover
spacing: $base_spacing;
padding: $base_padding;
border-radius: $modal_radius 0 0 $modal_radius;
border-right-width: 0;
&:rtl {
border-radius: 0 $modal_radius $modal_radius 0;
border-left-width: 0;
}
// drag and drop indicator
.placeholder {
background-image: url("resource:///org/gnome/shell/theme/dash-placeholder.svg");
background-size: contain;
height: 24px;
}
}
// selected indicator
.workspace-thumbnail-indicator {
border: 3px solid $selected_bg_color;
border-radius: 3px;
padding: 0px;
// background-color: transparentize($selected_bg_color, 0.9);
}

View File

@@ -1,4 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" class="keyboard-key" width="24" height="24">
<path overflow="visible" font-weight="400" style="line-height:normal;-inkscape-font-specification:'Bitstream Vera Sans';text-indent:0;text-align:start;text-decoration-line:none;text-transform:none;marker:none" d="M10 23H8.5c-.398 0-.796-.14-1.079-.422L.345 15.5l7.078-7.078C7.704 8.14 8.102 8 8.5 8H10v1.5c0 .398-.14.796-.422 1.079L4.657 15.5l4.921 4.922c.282.282.422.68.422 1.078z" color="#000" font-family="Bitstream Vera Sans" fill="#fff"/>
<path overflow="visible" d="M22 1.5v9a5 5 0 01-5 5H4" style="marker:none" color="#000" fill="none" stroke="#fff" stroke-width="3"/>
</svg>

Before

Width:  |  Height:  |  Size: 676 B

View File

@@ -1,3 +0,0 @@
<svg class="keyboard-key" xmlns="http://www.w3.org/2000/svg" width="24" height="24">
<path d="M12 20.875L.562 9.438C.171 9.046 0 8.51 0 8V6h2c.511 0 1.046.17 1.438.563L12 15.125l8.563-8.562C20.953 6.17 21.488 6 22 6h2v2c0 .511-.17 1.046-.563 1.438z" fill="#e5e5e5"/>
</svg>

Before

Width:  |  Height:  |  Size: 278 B

View File

@@ -1,5 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" class="keyboard-key" width="24" height="24">
<path d="M4.5 2v21" fill="#e5e5e5" fill-rule="evenodd" stroke="#e5e5e5" stroke-width="3"/>
<path d="M4 12h6l2 4h8V6h-6l-2-4H4z" fill="none" stroke="#e5e5e5" stroke-width="2" stroke-linejoin="round"/>
<path d="M4 12h6l2 4h8V6h-6l-2-4H4z" fill="#e5e5e5" fill-rule="evenodd"/>
</svg>

Before

Width:  |  Height:  |  Size: 378 B

View File

@@ -1,3 +0,0 @@
<svg class="keyboard-key" xmlns="http://www.w3.org/2000/svg" width="24" height="24">
<path style="marker:none" d="M12 0L2 12h6v6h8v-6h6zM8 21v3h8v-3z" color="#000" overflow="visible" fill="#3584e4"/>
</svg>

Before

Width:  |  Height:  |  Size: 211 B

View File

@@ -1,3 +0,0 @@
<svg class="keyboard-key" xmlns="http://www.w3.org/2000/svg" width="24" height="24">
<path d="M8 22v-8H2L12 2l10 12h-6v8z" style="marker:none" color="#000" overflow="visible" fill="#3584e4"/>
</svg>

Before

Width:  |  Height:  |  Size: 203 B

View File

@@ -1,3 +0,0 @@
<svg class="keyboard-key" xmlns="http://www.w3.org/2000/svg" width="24" height="24">
<path d="M8 22v-8H2L12 2l10 12h-6v8z" style="marker:none" color="#000" overflow="visible" fill="#bebebe"/>
</svg>

Before

Width:  |  Height:  |  Size: 203 B

View File

@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16">
<g fill="#2e3436">
<path d="M6 8H2.937l5.126-5.781L13.186 8H10v2H6z" style="marker:none" color="#000" overflow="visible"/>
<path d="M6 11h4v2H6z" style="marker:none"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 268 B

View File

@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16">
<g font-weight="400" fill="#2e3436">
<path d="M11.994 3v4.004c.002.666-.183.72-.445.852-.262.13-.555.144-.555.144H4v2h6.994s.71.014 1.45-.355c.738-.37 1.552-1.313 1.55-2.645V3z" style="line-height:normal;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000;text-transform:none;text-orientation:mixed;white-space:normal;shape-padding:0;isolation:auto;mix-blend-mode:normal;solid-color:#000;solid-opacity:1;marker:none" color="#000" font-family="sans-serif" overflow="visible"/>
<path d="M6 12v-1c0-.257-.13-.528-.313-.719l-1.28-1.303 1.28-1.26C5.87 7.529 6 7.258 6 7V6H5c-.31 0-.552.09-.75.281L1.594 8.978l2.656 2.74c.198.192.44.282.75.282z" style="line-height:normal;-inkscape-font-specification:'Bitstream Vera Sans';text-indent:0;text-align:start;text-decoration-line:none;text-transform:none;marker:none" color="#bebebe" font-family="Bitstream Vera Sans" overflow="visible"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@@ -0,0 +1,7 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16">
<g color="#000" fill="#2e3436">
<path d="M4.707 5.293L3.293 6.707 8 11.414l4.707-4.707-1.414-1.414L8 8.586z" style="line-height:normal;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000;text-transform:none;text-orientation:mixed;white-space:normal;shape-padding:0;isolation:auto;mix-blend-mode:normal;solid-color:#000;solid-opacity:1;marker:none" font-weight="400" font-family="sans-serif" overflow="visible"/>
<path d="M12 6V5h1v1zM3 6V5h1v1z" style="marker:none" overflow="visible"/>
<path d="M3 6c0-.554.446-1 1-1s1 .446 1 1-.446 1-1 1-1-.446-1-1zM11 6c0-.554.446-1 1-1s1 .446 1 1-.446 1-1 1-1-.446-1-1z" style="marker:none" overflow="visible"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 990 B

View File

@@ -0,0 +1,7 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16">
<g fill="#2e3436" fill-rule="evenodd">
<path d="M2 1v14h2V1z" style="line-height:normal;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000;text-transform:none;text-orientation:mixed;white-space:normal;shape-padding:0;isolation:auto;mix-blend-mode:normal;solid-color:#000;solid-opacity:1" color="#000" font-weight="400" font-family="sans-serif" overflow="visible"/>
<path d="M3 1a1 1 0 00-1 1v6a1 1 0 001 1h3.383l.722 1.447A1 1 0 008 11h5a1 1 0 001-1V4a1 1 0 00-1-1H9.617l-.722-1.447A1 1 0 008 1zm1 2h3.383l.722 1.447A1 1 0 009 5h3v4H8.617l-.722-1.447A1 1 0 007 7H4z" style="line-height:normal;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000;text-transform:none;text-orientation:mixed;white-space:normal;shape-padding:0;isolation:auto;mix-blend-mode:normal;solid-color:#000;solid-opacity:1" color="#000" font-weight="400" font-family="sans-serif" overflow="visible"/>
<path d="M3 8h4l1 2h5V4H9L8 2H3z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16">
<path d="M6 13V9H2.937l5.126-5.781L13.186 9H10v4z" style="marker:none" color="#000" overflow="visible" fill="#2e3436"/>
</svg>

After

Width:  |  Height:  |  Size: 195 B

View File

@@ -6,8 +6,9 @@ theme_sources = files([
'gnome-shell-sass/_drawing.scss',
'gnome-shell-sass/_high-contrast-colors.scss',
'gnome-shell-sass/_widgets.scss',
'gnome-shell-sass/widgets/_a11y.scss',
'gnome-shell-sass/widgets/_app-grid.scss',
'gnome-shell-sass/widgets/_app-switcher.scss',
'gnome-shell-sass/widgets/_base.scss',
'gnome-shell-sass/widgets/_buttons.scss',
'gnome-shell-sass/widgets/_calendar.scss',
'gnome-shell-sass/widgets/_check-box.scss',
@@ -33,10 +34,12 @@ theme_sources = files([
'gnome-shell-sass/widgets/_search-entry.scss',
'gnome-shell-sass/widgets/_search-results.scss',
'gnome-shell-sass/widgets/_slider.scss',
'gnome-shell-sass/widgets/_switcher-popup.scss',
'gnome-shell-sass/widgets/_switches.scss',
'gnome-shell-sass/widgets/_tiled-previews.scss',
'gnome-shell-sass/widgets/_window-picker.scss',
'gnome-shell-sass/widgets/_workspace-switcher.scss'
'gnome-shell-sass/widgets/_workspace-switcher.scss',
'gnome-shell-sass/widgets/_workspace-thumbnails.scss'
])
styles = [

Binary file not shown.

Before

Width:  |  Height:  |  Size: 78 KiB

View File

@@ -1 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="46" height="22"><defs><linearGradient id="a"><stop offset="0" stop-color="#39393a"/><stop offset="1" stop-color="#302f30"/></linearGradient><linearGradient xlink:href="#a" id="b" x1="53" y1="294.429" x2="53" y2="309.804" gradientUnits="userSpaceOnUse" gradientTransform="translate(-42.76)"/></defs><g transform="translate(0 -291.18)" stroke-width="1.085"><rect style="marker:none" width="44.446" height="20.911" x=".625" y="291.715" rx="10.455" ry="10.073" fill="#323233" stroke="#272728"/><rect ry="10.455" rx="10.455" y="291.715" x=".543" height="20.911" width="21.143" style="marker:none" fill="url(#b)" stroke="#151515"/></g></svg>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="46" height="22"><defs><linearGradient id="a"><stop offset="0" stop-color="#39393a"/><stop offset="1" stop-color="#302f30"/></linearGradient><linearGradient xlink:href="#a" id="b" x1="53" y1="294.429" x2="53" y2="309.804" gradientUnits="userSpaceOnUse" gradientTransform="translate(-42.76)"/></defs><g transform="translate(0 -291.18)" stroke-width="1.085" stroke="#151515"><rect style="marker:none" width="44.446" height="20.911" x=".625" y="291.715" rx="10.455" ry="10.073" fill="#282828"/><rect ry="10.455" rx="10.455" y="291.715" x=".543" height="20.911" width="21.143" style="marker:none" fill="url(#b)"/></g></svg>

Before

Width:  |  Height:  |  Size: 725 B

After

Width:  |  Height:  |  Size: 708 B

View File

@@ -0,0 +1,11 @@
.details-button image {
transition: 250ms;
}
.details-button.expanded:dir(ltr) image {
-gtk-icon-transform: rotate(0.25turn);
}
.details-button.expanded:dir(rtl) image {
-gtk-icon-transform: rotate(-0.25turn);
}
image.warning { color: @warning_color; }

View File

@@ -3,15 +3,16 @@ imports.gi.versions.Gdk = '3.0';
imports.gi.versions.Gtk = '3.0';
const Gettext = imports.gettext;
const { Gdk, GLib, Gio, GObject, Gtk, Pango } = imports.gi;
const { Gdk, GLib, Gio, GObject, Gtk } = imports.gi;
const Format = imports.format;
const _ = Gettext.gettext;
const Config = imports.misc.config;
const ExtensionUtils = imports.misc.extensionUtils;
const { loadInterfaceXML } = imports.misc.fileUtils;
const { ExtensionState } = ExtensionUtils;
const { ExtensionState, ExtensionType } = ExtensionUtils;
const GnomeShellIface = loadInterfaceXML('org.gnome.Shell.Extensions');
const GnomeShellProxy = Gio.DBusProxy.makeProxyWrapper(GnomeShellIface);
@@ -27,26 +28,144 @@ class Application extends Gtk.Application {
_init() {
GLib.set_prgname('gnome-shell-extension-prefs');
super._init({
application_id: 'org.gnome.shell.ExtensionPrefs',
application_id: 'org.gnome.Extensions',
flags: Gio.ApplicationFlags.HANDLES_COMMAND_LINE,
});
this._startupUuid = null;
this._loaded = false;
this._skipMainWindow = false;
this._shellProxy = null;
}
get shellProxy() {
return this._shellProxy;
}
_showPrefs(uuid) {
let row = this._extensionSelector.get_children().find(c => {
return c.uuid === uuid && c.hasPrefs;
vfunc_activate() {
this._shellProxy.CheckForUpdatesRemote();
this._window.present();
}
vfunc_startup() {
super.vfunc_startup();
let provider = new Gtk.CssProvider();
let uri = 'resource:///org/gnome/shell/css/application.css';
try {
provider.load_from_file(Gio.File.new_for_uri(uri));
} catch (e) {
logError(e, 'Failed to add application style');
}
Gtk.StyleContext.add_provider_for_screen(Gdk.Screen.get_default(),
provider,
Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION);
this._shellProxy = new GnomeShellProxy(Gio.DBus.session, 'org.gnome.Shell', '/org/gnome/Shell');
this._window = new ExtensionsWindow({ application: this });
}
vfunc_command_line(commandLine) {
let args = commandLine.get_arguments();
if (args.length) {
let uuid = args[0];
// Strip off "extension:///" prefix which fakes a URI, if it exists
uuid = stripPrefix(uuid, 'extension:///');
this._window.openPrefs(uuid);
} else {
this.activate();
}
return 0;
}
});
var ExtensionsWindow = GObject.registerClass({
GTypeName: 'ExtensionsWindow',
Template: 'resource:///org/gnome/shell/ui/extensions-window.ui',
InternalChildren: [
'userList',
'systemList',
'killSwitch',
'mainBox',
'mainStack',
'scrolledWindow',
'updatesBar',
'updatesLabel',
],
}, class ExtensionsWindow extends Gtk.ApplicationWindow {
_init(params) {
super._init(params);
this._startupUuid = null;
this._loaded = false;
this._prefsDialog = null;
this._updatesCheckId = 0;
this._mainBox.set_focus_vadjustment(this._scrolledWindow.vadjustment);
let action;
action = new Gio.SimpleAction({ name: 'show-about' });
action.connect('activate', this._showAbout.bind(this));
this.add_action(action);
action = new Gio.SimpleAction({ name: 'logout' });
action.connect('activate', this._logout.bind(this));
this.add_action(action);
this._settings = new Gio.Settings({ schema_id: 'org.gnome.shell' });
this._settings.bind('disable-user-extensions',
this._killSwitch, 'active',
Gio.SettingsBindFlags.DEFAULT | Gio.SettingsBindFlags.INVERT_BOOLEAN);
this._userList.set_sort_func(this._sortList.bind(this));
this._userList.set_header_func(this._updateHeader.bind(this));
this._systemList.set_sort_func(this._sortList.bind(this));
this._systemList.set_header_func(this._updateHeader.bind(this));
this._shellProxy.connectSignal('ExtensionStateChanged',
this._onExtensionStateChanged.bind(this));
this._scanExtensions();
}
get _shellProxy() {
return this.application.shellProxy;
}
uninstall(uuid) {
let row = this._findExtensionRow(uuid);
let dialog = new Gtk.MessageDialog({
transient_for: this,
modal: true,
text: _('Remove “%s”?').format(row.name),
secondary_text: _('If you remove the extension, you need to return to download it if you want to enable it again'),
});
if (!row)
dialog.add_button(_('Cancel'), Gtk.ResponseType.CANCEL);
dialog.add_button(_('Remove'), Gtk.ResponseType.ACCEPT)
.get_style_context().add_class('destructive-action');
dialog.connect('response', (dlg, response) => {
if (response === Gtk.ResponseType.ACCEPT)
this._shellProxy.UninstallExtensionRemote(uuid);
dialog.destroy();
});
dialog.present();
}
openPrefs(uuid) {
if (!this._loaded)
this._startupUuid = uuid;
else if (!this._showPrefs(uuid))
this.present();
}
_showPrefs(uuid) {
if (this._prefsDialog)
return false;
let row = this._findExtensionRow(uuid);
if (!row || !row.hasPrefs)
return false;
let widget;
@@ -57,33 +176,73 @@ class Application extends Gtk.Application {
widget = this._buildErrorUI(row, e);
}
let dialog = new Gtk.Window({
modal: !this._skipMainWindow,
this._prefsDialog = new Gtk.Window({
application: this.application,
default_width: 600,
default_height: 400,
modal: this.visible,
type_hint: Gdk.WindowTypeHint.DIALOG,
window_position: Gtk.WindowPosition.CENTER,
});
dialog.set_titlebar(new Gtk.HeaderBar({
this._prefsDialog.set_titlebar(new Gtk.HeaderBar({
show_close_button: true,
title: row.name,
visible: true,
}));
if (this._skipMainWindow) {
this.add_window(dialog);
if (this._window)
this._window.destroy();
this._window = dialog;
this._window.window_position = Gtk.WindowPosition.CENTER;
} else {
dialog.transient_for = this._window;
}
if (this.visible)
this._prefsDialog.transient_for = this;
dialog.set_default_size(600, 400);
dialog.add(widget);
dialog.show();
this._prefsDialog.connect('destroy', () => {
this._prefsDialog = null;
if (!this.visible)
this.destroy();
});
this._prefsDialog.add(widget);
this._prefsDialog.show();
return true;
}
_showAbout() {
let aboutDialog = new Gtk.AboutDialog({
authors: [
'Florian Müllner <fmuellner@gnome.org>',
'Jasper St. Pierre <jstpierre@mecheye.net>',
'Didier Roche <didrocks@ubuntu.com>',
],
translator_credits: _('translator-credits'),
program_name: _('Extensions'),
comments: _('Manage your GNOME Extensions'),
license_type: Gtk.License.GPL_2_0,
logo_icon_name: 'org.gnome.Extensions',
version: Config.PACKAGE_VERSION,
transient_for: this,
modal: true,
});
aboutDialog.present();
}
_logout() {
this.application.get_dbus_connection().call(
'org.gnome.SessionManager',
'/org/gnome/SessionManager',
'org.gnome.SessionManager',
'Logout',
new GLib.Variant('(u)', [0]),
null,
Gio.DBusCallFlags.NONE,
-1,
null,
(o, res) => {
o.call_finish(res);
});
}
_buildErrorUI(row, exc) {
let scroll = new Gtk.ScrolledWindow({
hscrollbar_policy: Gtk.PolicyType.NEVER,
@@ -118,10 +277,10 @@ class Application extends Gtk.Application {
});
box.add(expander);
let errortext = `${exc}\n\nStack trace:\n${
// Indent stack trace.
exc.stack.split('\n').map(line => ` ${line}`).join('\n')
}`;
let errortext = '%s\n\nStack trace:\n'.format(exc);
// Indent stack trace.
errortext +=
exc.stack.split('\n').map(line => ' %s'.format(line)).join('\n');
let buffer = new Gtk.TextBuffer({ text: errortext });
let textview = new Gtk.TextView({
@@ -156,9 +315,9 @@ class Application extends Gtk.Application {
let clipboard = Gtk.Clipboard.get_default(w.get_display());
// markdown for pasting in gitlab issues
let lines = [
`The settings of extension ${row.uuid} had an error:`,
'The settings of extension %s had an error:'.format(row.uuid),
'```', // '`' (xgettext throws up on odd number of backticks)
`${exc}`,
exc.toString(),
'```', // '`'
'',
'Stack trace:',
@@ -178,7 +337,7 @@ class Application extends Gtk.Application {
label: _("Homepage"),
tooltip_text: _("Visit extension homepage"),
no_show_all: true,
visible: row.url != null,
visible: row.url !== '',
});
toolbar.add(urlButton);
@@ -199,47 +358,6 @@ class Application extends Gtk.Application {
return scroll;
}
_buildUI() {
this._window = new Gtk.ApplicationWindow({ application: this,
window_position: Gtk.WindowPosition.CENTER });
this._window.set_default_size(800, 500);
this._titlebar = new Gtk.HeaderBar({ show_close_button: true,
title: _("Shell Extensions") });
this._window.set_titlebar(this._titlebar);
let killSwitch = new Gtk.Switch({ valign: Gtk.Align.CENTER });
this._titlebar.pack_end(killSwitch);
this._settings = new Gio.Settings({ schema_id: 'org.gnome.shell' });
this._settings.bind('disable-user-extensions', killSwitch, 'active',
Gio.SettingsBindFlags.DEFAULT |
Gio.SettingsBindFlags.INVERT_BOOLEAN);
this._mainStack = new Gtk.Stack({
transition_type: Gtk.StackTransitionType.CROSSFADE,
});
this._window.add(this._mainStack);
let scroll = new Gtk.ScrolledWindow({ hscrollbar_policy: Gtk.PolicyType.NEVER });
this._extensionSelector = new Gtk.ListBox({ selection_mode: Gtk.SelectionMode.NONE });
this._extensionSelector.set_sort_func(this._sortList.bind(this));
this._extensionSelector.set_header_func(this._updateHeader.bind(this));
scroll.add(this._extensionSelector);
this._mainStack.add_named(scroll, 'listing');
this._mainStack.add_named(new EmptyPlaceholder(), 'placeholder');
this._shellProxy = new GnomeShellProxy(Gio.DBus.session, 'org.gnome.Shell', '/org/gnome/Shell');
this._shellProxy.connectSignal('ExtensionStateChanged',
this._onExtensionStateChanged.bind(this));
this._window.show_all();
}
_sortList(row1, row2) {
return row1.name.localeCompare(row2.name);
}
@@ -253,13 +371,26 @@ class Application extends Gtk.Application {
}
_findExtensionRow(uuid) {
return this._extensionSelector.get_children().find(c => c.uuid === uuid);
return [
...this._userList.get_children(),
...this._systemList.get_children(),
].find(c => c.uuid === uuid);
}
_onExtensionStateChanged(proxy, senderName, [uuid, newState]) {
let extension = ExtensionUtils.deserializeExtension(newState);
let row = this._findExtensionRow(uuid);
this._queueUpdatesCheck();
// the extension's type changed; remove the corresponding row
// and reset the variable to null so that we create a new row
// below and add it to the appropriate list
if (row && row.type !== extension.type) {
row.destroy();
row = null;
}
if (row) {
if (extension.state === ExtensionState.UNINSTALLED)
row.destroy();
@@ -272,8 +403,7 @@ class Application extends Gtk.Application {
this._shellProxy.ListExtensionsRemote(([extensionsMap], e) => {
if (e) {
if (e instanceof Gio.DBusError) {
log(`Failed to connect to shell proxy: ${e}`);
this._mainStack.add_named(new NoShellPlaceholder(), 'noshell');
log('Failed to connect to shell proxy: %s'.format(e.toString()));
this._mainStack.visible_child_name = 'noshell';
} else {
throw e;
@@ -291,58 +421,53 @@ class Application extends Gtk.Application {
_addExtensionRow(extension) {
let row = new ExtensionRow(extension);
row.prefsButton.connect('clicked', () => {
this._showPrefs(row.uuid);
});
row.show_all();
this._extensionSelector.add(row);
if (row.type === ExtensionType.PER_USER)
this._userList.add(row);
else
this._systemList.add(row);
}
_queueUpdatesCheck() {
if (this._updatesCheckId)
return;
this._updatesCheckId = GLib.timeout_add_seconds(
GLib.PRIORITY_DEFAULT, 1, () => {
this._checkUpdates();
this._updatesCheckId = 0;
return GLib.SOURCE_REMOVE;
});
}
_checkUpdates() {
let nUpdates = this._userList.get_children().filter(c => c.hasUpdate).length;
this._updatesLabel.label = Gettext.ngettext(
'%d extension will be updated on next login.',
'%d extensions will be updated on next login.',
nUpdates).format(nUpdates);
this._updatesBar.visible = nUpdates > 0;
}
_extensionsLoaded() {
if (this._extensionSelector.get_children().length > 0)
this._mainStack.visible_child_name = 'listing';
this._userList.visible = this._userList.get_children().length > 0;
this._systemList.visible = this._systemList.get_children().length > 0;
if (this._userList.visible || this._systemList.visible)
this._mainStack.visible_child_name = 'main';
else
this._mainStack.visible_child_name = 'placeholder';
this._checkUpdates();
if (this._startupUuid)
this._showPrefs(this._startupUuid);
this._startupUuid = null;
this._skipMainWindow = false;
this._loaded = true;
}
vfunc_activate() {
this._window.present();
}
vfunc_startup() {
super.vfunc_startup();
this._buildUI();
this._scanExtensions();
}
vfunc_command_line(commandLine) {
this.activate();
let args = commandLine.get_arguments();
if (args.length) {
let uuid = args[0];
this._skipMainWindow = true;
// Strip off "extension:///" prefix which fakes a URI, if it exists
uuid = stripPrefix(uuid, "extension:///");
if (!this._loaded)
this._startupUuid = uuid;
else if (!this._showPrefs(uuid))
this._skipMainWindow = false;
}
return 0;
}
});
var Expander = GObject.registerClass({
@@ -444,113 +569,19 @@ var Expander = GObject.registerClass({
}
});
var EmptyPlaceholder = GObject.registerClass(
class EmptyPlaceholder extends Gtk.Box {
_init() {
super._init({
orientation: Gtk.Orientation.VERTICAL,
spacing: 6,
margin: 32,
});
let image = new Gtk.Image({
icon_name: 'application-x-addon-symbolic',
pixel_size: 96,
visible: true,
vexpand: true,
valign: Gtk.Align.END,
});
image.get_style_context().add_class(Gtk.STYLE_CLASS_DIM_LABEL);
this.add(image);
let label = new Gtk.Label({
label: `<b><span size="x-large">${_("No Extensions Installed")}</span></b>`,
use_markup: true,
visible: true,
});
label.get_style_context().add_class(Gtk.STYLE_CLASS_DIM_LABEL);
this.add(label);
let appInfo = Gio.DesktopAppInfo.new('org.gnome.Software.desktop');
let desc = new Gtk.Label({
label: _("Extensions can be installed through Software or <a href=\"https://extensions.gnome.org\">extensions.gnome.org</a>."),
use_markup: true,
wrap: true,
justify: Gtk.Justification.CENTER,
visible: true,
max_width_chars: 50,
hexpand: true,
vexpand: appInfo == null,
halign: Gtk.Align.CENTER,
valign: Gtk.Align.START,
});
this.add(desc);
if (appInfo) {
let button = new Gtk.Button({
label: _("Browse in Software"),
image: new Gtk.Image({
icon_name: "org.gnome.Software-symbolic",
}),
always_show_image: true,
margin_top: 12,
visible: true,
halign: Gtk.Align.CENTER,
valign: Gtk.Align.START,
vexpand: true,
});
this.add(button);
button.connect('clicked', w => {
let context = w.get_display().get_app_launch_context();
appInfo.launch([], context);
});
}
}
});
var NoShellPlaceholder = GObject.registerClass(
class NoShellPlaceholder extends Gtk.Box {
_init() {
super._init({
orientation: Gtk.Orientation.VERTICAL,
spacing: 12,
margin: 100,
margin_bottom: 60,
});
let label = new Gtk.Label({
label: '<span size="x-large">%s</span>'.format(
_("Somethings gone wrong")),
use_markup: true,
});
label.get_style_context().add_class(Gtk.STYLE_CLASS_DIM_LABEL);
this.add(label);
label = new Gtk.Label({
label: _("Were very sorry, but it was not possible to get the list of installed extensions. Make sure you are logged into GNOME and try again."),
justify: Gtk.Justification.CENTER,
wrap: true,
});
this.add(label);
this.show_all();
}
});
var DescriptionLabel = GObject.registerClass(
class DescriptionLabel extends Gtk.Label {
vfunc_get_preferred_height_for_width(width) {
// Hack: Request the maximum height allowed by the line limit
if (this.lines > 0)
return super.vfunc_get_preferred_height_for_width(0);
return super.vfunc_get_preferred_height_for_width(width);
}
});
var ExtensionRow = GObject.registerClass(
class ExtensionRow extends Gtk.ListBoxRow {
var ExtensionRow = GObject.registerClass({
GTypeName: 'ExtensionRow',
Template: 'resource:///org/gnome/shell/ui/extension-row.ui',
InternalChildren: [
'nameLabel',
'descriptionLabel',
'versionLabel',
'authorLabel',
'updatesIcon',
'revealButton',
'revealer',
],
}, class ExtensionRow extends Gtk.ListBoxRow {
_init(extension) {
super._init();
@@ -558,9 +589,67 @@ class ExtensionRow extends Gtk.ListBoxRow {
this._extension = extension;
this._prefsModule = null;
this.connect('destroy', this._onDestroy.bind(this));
this._actionGroup = new Gio.SimpleActionGroup();
this.insert_action_group('row', this._actionGroup);
this._buildUI();
let action;
action = new Gio.SimpleAction({
name: 'show-prefs',
enabled: this.hasPrefs,
});
action.connect('activate', () => this.get_toplevel().openPrefs(this.uuid));
this._actionGroup.add_action(action);
action = new Gio.SimpleAction({
name: 'show-url',
enabled: this.url !== '',
});
action.connect('activate', () => {
Gio.AppInfo.launch_default_for_uri(
this.url, this.get_display().get_app_launch_context());
});
this._actionGroup.add_action(action);
action = new Gio.SimpleAction({
name: 'uninstall',
enabled: this.type === ExtensionType.PER_USER,
});
action.connect('activate', () => this.get_toplevel().uninstall(this.uuid));
this._actionGroup.add_action(action);
action = new Gio.SimpleAction({
name: 'enabled',
state: new GLib.Variant('b', false),
});
action.connect('activate', () => {
let state = action.get_state();
action.change_state(new GLib.Variant('b', !state.get_boolean()));
});
action.connect('change-state', (a, state) => {
if (state.get_boolean())
this._app.shellProxy.EnableExtensionRemote(this.uuid);
else
this._app.shellProxy.DisableExtensionRemote(this.uuid);
});
this._actionGroup.add_action(action);
let name = GLib.markup_escape_text(this.name, -1);
this._nameLabel.label = name;
let desc = this._extension.metadata.description.split('\n')[0];
this._descriptionLabel.label = desc;
this._revealButton.connect('clicked', () => {
this._revealer.reveal_child = !this._revealer.reveal_child;
});
this._revealer.connect('notify::reveal-child', () => {
if (this._revealer.reveal_child)
this._revealButton.get_style_context().add_class('expanded');
else
this._revealButton.get_style_context().remove_class('expanded');
});
this.connect('destroy', this._onDestroy.bind(this));
this._extensionStateChangedId = this._app.shellProxy.connectSignal(
'ExtensionStateChanged', (p, sender, [uuid, newState]) => {
@@ -568,14 +657,9 @@ class ExtensionRow extends Gtk.ListBoxRow {
return;
this._extension = ExtensionUtils.deserializeExtension(newState);
let state = this._extension.state == ExtensionState.ENABLED;
this._switch.block_signal_handler(this._notifyActiveId);
this._switch.state = state;
this._switch.unblock_signal_handler(this._notifyActiveId);
this._switch.sensitive = this._canToggle();
this._updateState();
});
this._updateState();
}
get uuid() {
@@ -590,8 +674,40 @@ class ExtensionRow extends Gtk.ListBoxRow {
return this._extension.hasPrefs;
}
get hasUpdate() {
return this._extension.hasUpdate || false;
}
get type() {
return this._extension.type;
}
get creator() {
return this._extension.metadata.creator || '';
}
get url() {
return this._extension.metadata.url;
return this._extension.metadata.url || '';
}
get version() {
return this._extension.metadata.version || '';
}
_updateState() {
let state = this._extension.state === ExtensionState.ENABLED;
let action = this._actionGroup.lookup('enabled');
action.set_state(new GLib.Variant('b', state));
action.enabled = this._canToggle();
this._updatesIcon.visible = this.hasUpdate;
this._versionLabel.label = this.version.toString();
this._versionLabel.visible = this.version !== '';
this._authorLabel.label = this.creator.toString();
this._authorLabel.visible = this.creator !== '';
}
_onDestroy() {
@@ -603,54 +719,6 @@ class ExtensionRow extends Gtk.ListBoxRow {
this._extensionStateChangedId = 0;
}
_buildUI() {
let hbox = new Gtk.Box({ orientation: Gtk.Orientation.HORIZONTAL,
hexpand: true, margin_end: 24, spacing: 24,
margin: 12 });
this.add(hbox);
let vbox = new Gtk.Box({ orientation: Gtk.Orientation.VERTICAL,
spacing: 6, hexpand: true });
hbox.add(vbox);
let name = GLib.markup_escape_text(this.name, -1);
let label = new Gtk.Label({ label: '<b>' + name + '</b>',
use_markup: true,
halign: Gtk.Align.START });
vbox.add(label);
let desc = this._extension.metadata.description.split('\n')[0];
label = new DescriptionLabel({ label: desc, wrap: true, lines: 2,
ellipsize: Pango.EllipsizeMode.END,
xalign: 0, yalign: 0 });
vbox.add(label);
let button = new Gtk.Button({ valign: Gtk.Align.CENTER,
visible: this.hasPrefs,
no_show_all: true });
button.set_image(new Gtk.Image({ icon_name: 'emblem-system-symbolic',
icon_size: Gtk.IconSize.BUTTON,
visible: true }));
button.get_style_context().add_class('circular');
hbox.add(button);
this.prefsButton = button;
this._switch = new Gtk.Switch({
valign: Gtk.Align.CENTER,
sensitive: this._canToggle(),
state: this._extension.state === ExtensionState.ENABLED,
});
this._notifyActiveId = this._switch.connect('notify::active', () => {
if (this._switch.active)
this._app.shellProxy.EnableExtensionRemote(this.uuid);
else
this._app.shellProxy.DisableExtensionRemote(this.uuid);
});
this._switch.connect('state-set', () => true);
hbox.add(this._switch);
}
_canToggle() {
return this._extension.canChange;
}
@@ -679,7 +747,7 @@ function initEnvironment() {
},
logError(s) {
log(`ERROR: ${s}`);
log('ERROR: %s'.format(s));
},
userdatadir: GLib.build_filenamev([GLib.get_user_data_dir(), 'gnome-shell']),

View File

@@ -0,0 +1,218 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.0 -->
<interface>
<requires lib="gtk+" version="3.20"/>
<template class="ExtensionRow" parent="GtkListBoxRow">
<property name="visible">True</property>
<property name="activatable">False</property>
<child>
<object class="GtkGrid">
<property name="visible">True</property>
<property name="margin">12</property>
<property name="column_spacing">12</property>
<child>
<object class="GtkLabel" id="nameLabel">
<property name="visible">True</property>
</object>
</child>
<child>
<object class="GtkImage" id="updatesIcon">
<property name="no_show_all">True</property>
<property name="icon_name">software-update-available-symbolic</property>
<style>
<class name="warning"/>>
</style>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="hexpand">True</property>
</object>
</child>
<child>
<object class="GtkButton" id="prefsButton">
<property name="no_show_all">True</property>
<property name="visible"
bind-source="prefsButton"
bind-property="sensitive"
bind-flags="sync-create"/>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="valign">center</property>
<property name="action-name">row.show-prefs</property>
<style>
<class name="circular"/>>
<class name="image-button"/>>
</style>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="icon_name">emblem-system-symbolic</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkSwitch">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="valign">center</property>
<property name="action-name">row.enabled</property>
</object>
</child>
<child>
<object class="GtkSeparator">
<property name="visible">True</property>
</object>
</child>
<child>
<object class="GtkButton" id="revealButton">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="valign">center</property>
<style>
<class name="details-button"/>
<class name="image-button"/>
<class name="flat"/>
</style>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="icon_name">pan-end-symbolic</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkRevealer" id="revealer">
<property name="visible">True</property>
<child>
<object class="GtkGrid">
<property name="visible">True</property>
<property name="margin_top">12</property>
<property name="row_spacing">6</property>
<property name="column_spacing">12</property>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="label" translatable="yes">Description</property>
<property name="xalign">0</property>
<style>
<class name="dim-label"/>
</style>
</object>
</child>
<child>
<object class="GtkLabel" id="descriptionLabel">
<property name="visible">True</property>
<property name="ellipsize">end</property>
<property name="max_width_chars">60</property>
<property name="xalign">0</property>
<property name="yalign">0</property>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="visible"
bind-source="versionLabel"
bind-property="visible"
bind-flags="sync-create"/>
<property name="no_show_all">True</property>
<property name="label" translatable="yes">Version</property>
<property name="xalign">0</property>
<style>
<class name="dim-label"/>
</style>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="versionLabel">
<property name="no_show_all">True</property>
<property name="xalign">0</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">1</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="visible"
bind-source="authorLabel"
bind-property="visible"
bind-flags="sync-create"/>
<property name="no_show_all">True</property>
<property name="label" translatable="yes">Author</property>
<property name="xalign">0</property>
<style>
<class name="dim-label"/>
</style>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">2</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="authorLabel">
<property name="no_show_all">True</property>
<property name="xalign">0</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">2</property>
</packing>
</child>
<child>
<object class="GtkButton">
<property name="visible">True</property>
<property name="label" translatable="yes">Website</property>
<property name="action_name">row.show-url</property>
<property name="valign">end</property>
<property name="margin-top">12</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">3</property>
</packing>
</child>
<child>
<object class="GtkButton" id="removeButton">
<property name="visible"
bind-source="removeButton"
bind-property="sensitive"
bind-flags="sync-create"/>
<property name="no_show_all">True</property>
<property name="label" translatable="yes">Remove…</property>
<property name="action_name">row.uninstall</property>
<property name="hexpand">True</property>
<property name="halign">end</property>
<property name="valign">end</property>
<style>
<class name="destructive-action"/>
</style>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">3</property>
</packing>
</child>
</object>
</child>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">1</property>
<property name="width">7</property>
</packing>
</child>
</object>
</child>
</template>
</interface>

View File

@@ -0,0 +1,305 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.0 -->
<interface>
<requires lib="gtk+" version="3.20"/>
<menu id="primary-menu">
<section>
<item>
<attribute name="label" translatable="yes">Help</attribute>
<attribute name="action">win.show-help</attribute>
</item>
<item>
<attribute name="label" translatable="yes">About Extensions</attribute>
<attribute name="action">win.show-about</attribute>
</item>
</section>
</menu>
<object class="GtkPopover" id="infoPopover">
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="orientation">vertical</property>
<property name="margin">12</property>
<property name="spacing">6</property>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="label" translatable="yes">To find and add extensions, visit &lt;a href="https://extensions.gnome.org"&gt;extensions.gnome.org&lt;/a&gt;.</property>
<property name="use_markup">True</property>
<property name="xalign">0</property>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="label" translatable="yes">Warning</property>
<property name="xalign">0</property>
<property name="margin_top">6</property>
<attributes>
<attribute name="weight" value="bold"/>
</attributes>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="label" translatable="yes">Extensions can cause system issues, including performance problems. If you encounter problems with your system, it is recommended to disable all extensions.</property>
<property name="wrap">True</property>
<property name="max_width_chars">40</property>
<property name="xalign">0</property>
</object>
</child>
</object>
</child>
</object>
<template class="ExtensionsWindow" parent="GtkApplicationWindow">
<property name="default_width">800</property>
<property name="default_height">500</property>
<child type="titlebar">
<object class="GtkHeaderBar">
<property name="visible">True</property>
<property name="title" translatable="yes">Extensions</property>
<property name="show_close_button">True</property>
<child>
<object class="GtkMenuButton">
<property name="visible">True</property>
<property name="popover">infoPopover</property>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="icon_name">dialog-information-symbolic</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkMenuButton" id="menuButton">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="menu_model">primary-menu</property>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="icon_name">open-menu-symbolic</property>
</object>
</child>
</object>
<packing>
<property name="pack_type">end</property>
</packing>
</child>
<child>
<object class="GtkSwitch" id="killSwitch">
<property name="visible">True</property>
</object>
<packing>
<property name="pack_type">end</property>
</packing>
</child>
</object>
</child>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkStack" id="mainStack">
<property name="visible">True</property>
<property name="transition_type">crossfade</property>
<property name="vexpand">True</property>
<child>
<object class="GtkScrolledWindow" id="scrolledWindow">
<property name="visible">True</property>
<property name="hscrollbar_policy">never</property>
<child>
<object class="GtkViewport">
<property name="visible">True</property>
<child>
<object class="GtkBox" id="mainBox">
<property name="visible">True</property>
<property name="orientation">vertical</property>
<property name="halign">center</property>
<property name="margin">36</property>
<property name="spacing">12</property>
<child>
<object class="GtkLabel">
<property name="visible"
bind-source="userList"
bind-property="visible"
bind-flags="sync-create"/>
<property name="halign">start</property>
<property name="hexpand">True</property>
<property name="label" translatable="yes">Manually Installed</property>
<attributes>
<attribute name="weight" value="bold"/>
</attributes>
</object>
</child>
<child>
<object class="GtkListBox" id="userList">
<property name="visible">True</property>
<property name="selection_mode">none</property>
<property name="margin_bottom">24</property>
<style>
<class name="frame"/>
</style>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="visible"
bind-source="systemList"
bind-property="visible"
bind-flags="sync-create"/>
<property name="halign">start</property>
<property name="hexpand">True</property>
<property name="label" translatable="yes">Built-In</property>
<attributes>
<attribute name="weight" value="bold"/>
</attributes>
</object>
</child>
<child>
<object class="GtkListBox" id="systemList">
<property name="visible">True</property>
<property name="selection_mode">none</property>
<style>
<class name="frame"/>
</style>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
<packing>
<property name="name">main</property>
</packing>
</child>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="orientation">vertical</property>
<property name="margin">32</property>
<property name="spacing">6</property>
<property name="valign">center</property>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="pixel_size">96</property>
<property name="icon_name">org.gnome.Extensions-symbolic</property>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="label" translatable="yes">No Installed Extensions</property>
<attributes>
<attribute name="weight" value="bold"/>
<attribute name="scale" value="1.44"/>
</attributes>
</object>
</child>
</object>
<packing>
<property name="name">placeholder</property>
</packing>
</child>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="margin_left">100</property>
<property name="margin_right">100</property>
<property name="margin_top">100</property>
<property name="margin_bottom">60</property>
<property name="orientation">vertical</property>
<property name="spacing">12</property>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="label" translatable="yes">Somethings gone wrong</property>
<attributes>
<attribute name="scale" value="1.44"/>
</attributes>
<style>
<class name="dim-label"/>
</style>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="label" translatable="yes">Were very sorry, but it was not possible to get the list of installed extensions. Make sure you are logged into GNOME and try again.</property>
<property name="justify">center</property>
<property name="wrap">True</property>
<style>
<class name="dim-label"/>
</style>
</object>
</child>
</object>
<packing>
<property name="name">noshell</property>
</packing>
</child>
</object>
</child>
<child>
<object class="GtkActionBar" id="updatesBar">
<property name="no_show_all">True</property>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="pixel-size">24</property>
<property name="margin">6</property>
<property name="icon_name">software-update-available-symbolic</property>
<style>
<class name="warning"/>
</style>
</object>
</child>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="halign">start</property>
<property name="label">Extension Updates Ready</property>
<attributes>
<attribute name="weight" value="bold"/>
</attributes>
</object>
</child>
<child>
<object class="GtkLabel" id="updatesLabel">
<property name="visible">True</property>
<property name="halign">start</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkButton">
<property name="label" translatable="yes">Log Out…</property>
<property name="visible">True</property>
<property name="valign">center</property>
<property name="action-name">win.logout</property>
<property name="receives_default">True</property>
<style>
<class name="suggested-action"/>
</style>
</object>
<packing>
<property name="pack_type">end</property>
</packing>
</child>
</object>
</child>
</object>
</child>
</template>
</interface>

View File

@@ -17,10 +17,6 @@ var DEFAULT_BUTTON_WELL_ANIMATION_TIME = 300;
var MESSAGE_FADE_OUT_ANIMATION_TIME = 500;
const WIGGLE_OFFSET = 6;
const WIGGLE_DURATION = 65;
const N_WIGGLES = 3;
var AuthPromptMode = {
UNLOCK_ONLY: 0,
UNLOCK_OR_LOG_IN: 1,
@@ -51,12 +47,15 @@ var AuthPrompt = GObject.registerClass({
super._init({
style_class: 'login-dialog-prompt-layout',
vertical: true,
x_expand: true,
x_align: Clutter.ActorAlign.CENTER,
});
this.verificationStatus = AuthPromptStatus.NOT_VERIFYING;
this._gdmClient = gdmClient;
this._mode = mode;
this._defaultButtonWellActor = null;
let reauthenticationOnly;
if (this._mode == AuthPromptMode.UNLOCK_ONLY)
@@ -75,15 +74,6 @@ var AuthPrompt = GObject.registerClass({
this._userVerifier.connect('ovirt-user-authenticated', this._onOVirtUserAuthenticated.bind(this));
this.smartcardDetected = this._userVerifier.smartcardDetected;
this.connect('next', () => {
this.updateSensitivity(false);
this.startSpinning();
if (this._queryingService)
this._userVerifier.answerQuery(this._queryingService, this._entry.text);
else
this._preemptiveAnswer = this._entry.text;
});
this.connect('destroy', this._onDestroy.bind(this));
this._userWell = new St.Bin({
@@ -91,67 +81,35 @@ var AuthPrompt = GObject.registerClass({
y_expand: true,
});
this.add_child(this._userWell);
this._label = new St.Label({
style_class: 'login-dialog-prompt-label',
x_expand: false,
y_expand: true,
this._hasCancelButton = this._mode === AuthPromptMode.UNLOCK_OR_LOG_IN;
this._initEntryRow();
let capsLockPlaceholder = new St.Label();
this.add_child(capsLockPlaceholder);
this._capsLockWarningLabel = new ShellEntry.CapsLockWarning({
x_expand: true,
x_align: Clutter.ActorAlign.CENTER,
});
this.add_child(this._label);
let entryParams = {
style_class: 'login-dialog-prompt-entry',
can_focus: true,
x_expand: false,
y_expand: true,
};
this._entry = null;
this._textEntry = new St.Entry(entryParams);
ShellEntry.addContextMenu(this._textEntry, { actionMode: Shell.ActionMode.NONE });
this._passwordEntry = new St.PasswordEntry(entryParams);
ShellEntry.addContextMenu(this._passwordEntry, { actionMode: Shell.ActionMode.NONE });
this._entry = this._passwordEntry;
this.add_child(this._entry);
this._entry.grab_key_focus();
this._capsLockWarningLabel = new ShellEntry.CapsLockWarning();
this.add_child(this._capsLockWarningLabel);
this._capsLockWarningLabel.bind_property('visible',
capsLockPlaceholder, 'visible',
GObject.BindingFlags.SYNC_CREATE | GObject.BindingFlags.INVERT_BOOLEAN);
this._message = new St.Label({
opacity: 0,
styleClass: 'login-dialog-message',
x_expand: false,
y_expand: true,
x_expand: true,
y_align: Clutter.ActorAlign.START,
x_align: Clutter.ActorAlign.CENTER,
});
this._message.clutter_text.line_wrap = true;
this._message.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
this.add_child(this._message);
this._buttonBox = new St.BoxLayout({
style_class: 'login-dialog-button-box',
vertical: false,
y_align: Clutter.ActorAlign.END,
});
this.add_child(this._buttonBox);
this._defaultButtonWell = new St.Widget({
layout_manager: new Clutter.BinLayout(),
x_align: Clutter.ActorAlign.END,
y_align: Clutter.ActorAlign.CENTER,
});
this._initButtons();
this._spinner = new Animation.Spinner(DEFAULT_BUTTON_WELL_ICON_SIZE);
this._spinner.opacity = 0;
this._spinner.show();
this._defaultButtonWell.add_child(this._spinner);
}
_onDestroy() {
@@ -165,54 +123,95 @@ var AuthPrompt = GObject.registerClass({
return Clutter.EVENT_PROPAGATE;
}
_initButtons() {
_initEntryRow() {
this._mainBox = new St.BoxLayout({
style_class: 'login-dialog-button-box',
vertical: false,
});
this.add_child(this._mainBox);
this.cancelButton = new St.Button({
style_class: 'modal-dialog-button button',
style_class: 'modal-dialog-button button cancel-button',
accessible_name: _('Cancel'),
button_mask: St.ButtonMask.ONE | St.ButtonMask.THREE,
reactive: true,
can_focus: true,
label: _("Cancel"),
x_expand: true,
reactive: this._hasCancelButton,
can_focus: this._hasCancelButton,
x_align: Clutter.ActorAlign.START,
y_align: Clutter.ActorAlign.END,
y_align: Clutter.ActorAlign.CENTER,
child: new St.Icon({ icon_name: 'go-previous-symbolic' }),
});
this.cancelButton.connect('clicked', () => this.cancel());
this._buttonBox.add_child(this.cancelButton);
if (this._hasCancelButton)
this.cancelButton.connect('clicked', () => this.cancel());
else
this.cancelButton.opacity = 0;
this._mainBox.add_child(this.cancelButton);
this._buttonBox.add_child(this._defaultButtonWell);
this.nextButton = new St.Button({
style_class: 'modal-dialog-button button',
button_mask: St.ButtonMask.ONE | St.ButtonMask.THREE,
reactive: true,
let entryParams = {
style_class: 'login-dialog-prompt-entry',
can_focus: true,
label: _("Next"),
x_expand: true,
};
this._entry = null;
this._textEntry = new St.Entry(entryParams);
ShellEntry.addContextMenu(this._textEntry, { actionMode: Shell.ActionMode.NONE });
this._passwordEntry = new St.PasswordEntry(entryParams);
ShellEntry.addContextMenu(this._passwordEntry, { actionMode: Shell.ActionMode.NONE });
this._entry = this._passwordEntry;
this._mainBox.add_child(this._entry);
this._entry.grab_key_focus();
[this._textEntry, this._passwordEntry].forEach(entry => {
entry.clutter_text.connect('text-changed', () => {
if (!this._userVerifier.hasPendingMessages)
this._fadeOutMessage();
});
entry.clutter_text.connect('activate', () => {
let shouldSpin = entry === this._passwordEntry;
if (entry.reactive)
this._activateNext(shouldSpin);
});
});
this._defaultButtonWell = new St.Widget({
layout_manager: new Clutter.BinLayout(),
x_align: Clutter.ActorAlign.END,
y_align: Clutter.ActorAlign.END,
y_align: Clutter.ActorAlign.CENTER,
});
this.nextButton.connect('clicked', () => this.emit('next'));
this.nextButton.add_style_pseudo_class('default');
this._buttonBox.add_child(this.nextButton);
this._defaultButtonWell.add_constraint(new Clutter.BindConstraint({
source: this.cancelButton,
coordinate: Clutter.BindCoordinate.SIZE,
}));
this._mainBox.add_child(this._defaultButtonWell);
this._updateNextButtonSensitivity(this._entry.text.length > 0);
this._spinner = new Animation.Spinner(DEFAULT_BUTTON_WELL_ICON_SIZE);
this._defaultButtonWell.add_child(this._spinner);
}
this._entry.clutter_text.connect('text-changed', () => {
if (!this._userVerifier.hasPendingMessages)
this._fadeOutMessage();
_activateNext(shouldSpin) {
this.updateSensitivity(false);
this._updateNextButtonSensitivity(this._entry.text.length > 0 || this.verificationStatus == AuthPromptStatus.VERIFYING);
});
this._entry.clutter_text.connect('activate', () => {
if (this.nextButton.reactive)
this.emit('next');
});
if (shouldSpin)
this.startSpinning();
if (this._queryingService)
this._userVerifier.answerQuery(this._queryingService, this._entry.text);
else
this._preemptiveAnswer = this._entry.text;
this.emit('next');
}
_updateEntry(secret) {
if (secret && (this._entry != this._passwordEntry)) {
this.replace_child(this._entry, this._passwordEntry);
if (secret && this._entry !== this._passwordEntry) {
this._mainBox.replace_child(this._entry, this._passwordEntry);
this._entry = this._passwordEntry;
} else if (!secret && (this._entry != this._textEntry)) {
this.replace_child(this._entry, this._textEntry);
} else if (!secret && this._entry !== this._textEntry) {
this._mainBox.replace_child(this._entry, this._textEntry);
this._entry = this._textEntry;
}
this._capsLockWarningLabel.visible = secret;
@@ -230,16 +229,14 @@ var AuthPrompt = GObject.registerClass({
}
this._updateEntry(secret);
this.setQuestion(question);
if (secret) {
if (this._userVerifier.reauthenticating)
this.nextButton.label = _("Unlock");
else
this.nextButton.label = C_("button", "Sign In");
} else {
this.nextButton.label = _("Next");
}
// Hack: The question string comes directly from PAM, if it's "Password:"
// we replace it with our own to allow localization, if it's something
// else we remove the last colon and any trailing or leading spaces.
if (question === 'Password:' || question === 'Password: ')
this.setQuestion(_('Password'));
else
this.setQuestion(question.replace(/: *$/, '').trim());
this.updateSensitivity(true);
this.emit('prompted');
@@ -282,17 +279,14 @@ var AuthPrompt = GObject.registerClass({
this.setActorInDefaultButtonWell(null);
this.verificationStatus = AuthPromptStatus.VERIFICATION_FAILED;
Util.wiggle(this._entry, {
offset: WIGGLE_OFFSET,
duration: WIGGLE_DURATION,
wiggleCount: N_WIGGLES,
});
Util.wiggle(this._entry);
}
_onVerificationComplete() {
this.setActorInDefaultButtonWell(null);
this.verificationStatus = AuthPromptStatus.VERIFICATION_SUCCEEDED;
this.cancelButton.reactive = false;
this.cancelButton.can_focus = false;
}
_onReset() {
@@ -300,10 +294,6 @@ var AuthPrompt = GObject.registerClass({
this.reset();
}
addActorToDefaultButtonWell(actor) {
this._defaultButtonWell.add_child(actor);
}
setActorInDefaultButtonWell(actor, animate) {
if (!this._defaultButtonWellActor &&
!actor)
@@ -383,11 +373,9 @@ var AuthPrompt = GObject.registerClass({
}
setQuestion(question) {
this._label.set_text(question);
this._entry.hint_text = question;
this._label.show();
this._entry.show();
this._entry.grab_key_focus();
}
@@ -435,13 +423,7 @@ var AuthPrompt = GObject.registerClass({
}
}
_updateNextButtonSensitivity(sensitive) {
this.nextButton.reactive = sensitive;
this.nextButton.can_focus = sensitive;
}
updateSensitivity(sensitive) {
this._updateNextButtonSensitivity(sensitive && (this._entry.text.length > 0 || this.verificationStatus == AuthPromptStatus.VERIFYING));
this._entry.reactive = sensitive;
this._entry.clutter_text.editable = sensitive;
}
@@ -462,18 +444,18 @@ var AuthPrompt = GObject.registerClass({
if (oldChild)
oldChild.destroy();
if (user) {
let userWidget = new UserWidget.UserWidget(user);
userWidget.x_align = Clutter.ActorAlign.START;
this._userWell.set_child(userWidget);
}
let userWidget = new UserWidget.UserWidget(user, Clutter.Orientation.VERTICAL);
this._userWell.set_child(userWidget);
if (!user)
this._updateEntry(false);
}
reset() {
let oldStatus = this.verificationStatus;
this.verificationStatus = AuthPromptStatus.NOT_VERIFYING;
this.cancelButton.reactive = true;
this.nextButton.label = _("Next");
this.cancelButton.reactive = this._hasCancelButton;
this.cancelButton.can_focus = this._hasCancelButton;
this._preemptiveAnswer = null;
if (this._userVerifier)
@@ -483,6 +465,7 @@ var AuthPrompt = GObject.registerClass({
this.clear();
this._message.opacity = 0;
this.setUser(null);
this._updateEntry(true);
this.stopSpinning();
if (oldStatus == AuthPromptStatus.VERIFICATION_FAILED)

View File

@@ -36,7 +36,6 @@ const _FADE_ANIMATION_TIME = 250;
const _SCROLL_ANIMATION_TIME = 500;
const _TIMED_LOGIN_IDLE_THRESHOLD = 5.0;
const _LOGO_ICON_HEIGHT = 48;
const _MAX_BOTTOM_MENU_ITEMS = 5;
var UserListItem = GObject.registerClass({
Signals: { 'activate': {} },
@@ -312,28 +311,21 @@ var SessionMenuButton = GObject.registerClass({
_init() {
let gearIcon = new St.Icon({ icon_name: 'emblem-system-symbolic' });
let button = new St.Button({
style_class: 'login-dialog-session-list-button',
style_class: 'modal-dialog-button button login-dialog-session-list-button',
reactive: true,
track_hover: true,
can_focus: true,
accessible_name: _("Choose Session"),
accessible_role: Atk.Role.MENU,
x_align: Clutter.ActorAlign.CENTER,
y_align: Clutter.ActorAlign.CENTER,
child: gearIcon,
});
super._init({ child: button });
this._button = button;
let side = St.Side.TOP;
let align = 0;
if (Gdm.get_session_ids().length > _MAX_BOTTOM_MENU_ITEMS) {
if (this.text_direction == Clutter.TextDirection.RTL)
side = St.Side.RIGHT;
else
side = St.Side.LEFT;
align = 0.5;
}
this._menu = new PopupMenu.PopupMenu(this._button, align, side);
this._menu = new PopupMenu.PopupMenu(this._button, 0, St.Side.BOTTOM);
Main.uiGroup.add_actor(this._menu.actor);
this._menu.actor.hide();
@@ -358,6 +350,7 @@ var SessionMenuButton = GObject.registerClass({
updateSensitivity(sensitive) {
this._button.reactive = sensitive;
this._button.can_focus = sensitive;
this.opacity = sensitive ? 255 : 0;
this._menu.close(BoxPointer.PopupAnimation.NONE);
}
@@ -409,7 +402,10 @@ var SessionMenuButton = GObject.registerClass({
});
var LoginDialog = GObject.registerClass({
Signals: { 'failed': {} },
Signals: {
'failed': {},
'wake-up-screen': {},
},
}, class LoginDialog extends St.Widget {
_init(parentActor) {
super._init({ style_class: 'login-dialog', visible: false });
@@ -425,13 +421,13 @@ var LoginDialog = GObject.registerClass({
this._settings = new Gio.Settings({ schema_id: GdmUtil.LOGIN_SCREEN_SCHEMA });
this._settings.connect(`changed::${GdmUtil.BANNER_MESSAGE_KEY}`,
this._settings.connect('changed::%s'.format(GdmUtil.BANNER_MESSAGE_KEY),
this._updateBanner.bind(this));
this._settings.connect(`changed::${GdmUtil.BANNER_MESSAGE_TEXT_KEY}`,
this._settings.connect('changed::%s'.format(GdmUtil.BANNER_MESSAGE_TEXT_KEY),
this._updateBanner.bind(this));
this._settings.connect(`changed::${GdmUtil.DISABLE_USER_LIST_KEY}`,
this._settings.connect('changed::%s'.format(GdmUtil.DISABLE_USER_LIST_KEY),
this._updateDisableUserList.bind(this));
this._settings.connect(`changed::${GdmUtil.LOGO_KEY}`,
this._settings.connect('changed::%s'.format(GdmUtil.LOGO_KEY),
this._updateLogo.bind(this));
this._textureCache = St.TextureCache.get_default();
@@ -492,6 +488,15 @@ var LoginDialog = GObject.registerClass({
bannerBox.add_child(this._bannerLabel);
this._updateBanner();
this._sessionMenuButton = new SessionMenuButton();
this._sessionMenuButton.connect('session-activated',
(list, sessionId) => {
this._greeter.call_select_session_sync(sessionId, null);
});
this._sessionMenuButton.opacity = 0;
this._sessionMenuButton.show();
this.add_child(this._sessionMenuButton);
this._logoBin = new St.Widget({ style_class: 'login-dialog-logo-bin',
x_align: Clutter.ActorAlign.CENTER,
y_align: Clutter.ActorAlign.END });
@@ -505,16 +510,6 @@ var LoginDialog = GObject.registerClass({
this._onUserListActivated(item);
});
this._sessionMenuButton = new SessionMenuButton();
this._sessionMenuButton.connect('session-activated',
(list, sessionId) => {
this._greeter.call_select_session_sync(sessionId, null);
});
this._sessionMenuButton.opacity = 0;
this._sessionMenuButton.show();
this._authPrompt.addActorToDefaultButtonWell(this._sessionMenuButton);
this._disableUserList = undefined;
this._userListLoaded = false;
@@ -559,6 +554,23 @@ var LoginDialog = GObject.registerClass({
return actorBox;
}
_getSessionMenuButtonAllocation(dialogBox) {
let actorBox = new Clutter.ActorBox();
let [, , natWidth, natHeight] = this._sessionMenuButton.get_preferred_size();
if (this.get_text_direction() === Clutter.TextDirection.RTL)
actorBox.x1 = dialogBox.x1 + natWidth;
else
actorBox.x1 = dialogBox.x2 - (natWidth * 2);
actorBox.y1 = dialogBox.y2 - (natHeight * 2);
actorBox.x2 = actorBox.x1 + natWidth;
actorBox.y2 = actorBox.y1 + natHeight;
return actorBox;
}
_getCenterActorAllocation(dialogBox, actor) {
let actorBox = new Clutter.ActorBox();
@@ -615,6 +627,10 @@ var LoginDialog = GObject.registerClass({
logoHeight = logoAllocation.y2 - logoAllocation.y1;
}
let sessionMenuButtonAllocation = null;
if (this._sessionMenuButton.visible)
sessionMenuButtonAllocation = this._getSessionMenuButtonAllocation(dialogBox);
// Then figure out if we're overly constrained and need to
// try a different layout, or if we have what extra space we
// can hand out
@@ -713,6 +729,9 @@ var LoginDialog = GObject.registerClass({
if (logoAllocation)
this._logoBin.allocate(logoAllocation, flags);
if (sessionMenuButtonAllocation)
this._sessionMenuButton.allocate(sessionMenuButtonAllocation, flags);
}
_ensureUserListLoaded() {
@@ -808,12 +827,10 @@ var LoginDialog = GObject.registerClass({
}
_onPrompted() {
if (this._shouldShowSessionMenuButton()) {
this._sessionMenuButton.updateSensitivity(true);
this._authPrompt.setActorInDefaultButtonWell(this._sessionMenuButton);
} else {
this._sessionMenuButton.updateSensitivity(false);
}
const showSessionMenu = this._shouldShowSessionMenuButton();
this._sessionMenuButton.updateSensitivity(showSessionMenu);
this._sessionMenuButton.visible = showSessionMenu;
this._showPrompt();
}
@@ -896,7 +913,8 @@ var LoginDialog = GObject.registerClass({
}
_askForUsernameAndBeginVerification() {
this._authPrompt.setQuestion(_("Username: "));
this._authPrompt.setUser(null);
this._authPrompt.setQuestion(_('Username'));
this._showRealmLoginHint(this._realmManager.loginFormat);
@@ -910,7 +928,6 @@ var LoginDialog = GObject.registerClass({
let answer = this._authPrompt.getAnswer();
this._user = this._userManager.get_user(answer);
this._authPrompt.clear();
this._authPrompt.startSpinning();
this._authPrompt.begin({ userName: answer });
this._updateCancelButton();
});
@@ -1122,6 +1139,7 @@ var LoginDialog = GObject.registerClass({
this._authPrompt.hide();
this._hideBannerView();
this._sessionMenuButton.close();
this._sessionMenuButton.hide();
this._setUserListExpanded(true);
this._notListedButton.show();
this._userList.grab_key_focus();
@@ -1225,13 +1243,18 @@ var LoginDialog = GObject.registerClass({
return GLib.SOURCE_REMOVE;
}
activate() {
this._userList.grab_key_focus();
this.show();
}
open() {
Main.ctrlAltTabManager.addGroup(this,
_("Login Window"),
'dialog-password-symbolic',
{ sortGroup: CtrlAltTab.SortGroup.MIDDLE });
this._userList.grab_key_focus();
this.show();
this.activate();
this.opacity = 0;
Main.pushModal(this, { actionMode: Shell.ActionMode.LOGIN_SCREEN });

View File

@@ -109,6 +109,7 @@
<file>ui/windowMenu.js</file>
<file>ui/windowManager.js</file>
<file>ui/workspace.js</file>
<file>ui/workspaceAnimation.js</file>
<file>ui/workspaceSwitcherPopup.js</file>
<file>ui/workspaceThumbnail.js</file>
<file>ui/workspacesView.js</file>

View File

@@ -1,10 +1,12 @@
/* exported IntrospectService */
const { Gio, GLib, Meta, Shell } = imports.gi;
const { Gio, GLib, Meta, Shell, St } = imports.gi;
const INTROSPECT_SCHEMA = 'org.gnome.shell';
const INTROSPECT_KEY = 'introspect';
const APP_WHITELIST = ['org.freedesktop.impl.portal.desktop.gtk'];
const INTROSPECT_DBUS_API_VERSION = 2;
const { loadInterfaceXML } = imports.misc.fileUtils;
const IntrospectDBusIface = loadInterfaceXML('org.gnome.Shell.Introspect');
@@ -22,6 +24,7 @@ var IntrospectService = class {
this._runningApplicationsDirty = true;
this._activeApplication = null;
this._activeApplicationDirty = true;
this._animationsEnabled = true;
this._appSystem = Shell.AppSystem.get_default();
this._appSystem.connect('app-state-changed',
@@ -30,7 +33,9 @@ var IntrospectService = class {
this._syncRunningApplications();
});
this._settings = new Gio.Settings({ schema_id: INTROSPECT_SCHEMA });
this._introspectSettings = new Gio.Settings({
schema_id: INTROSPECT_SCHEMA,
});
let tracker = Shell.WindowTracker.get_default();
tracker.connect('notify::focus-app',
@@ -49,6 +54,11 @@ var IntrospectService = class {
(conn, name, owner) => this._whitelistMap.set(name, owner),
(conn, name) => this._whitelistMap.delete(name));
});
this._settings = St.Settings.get();
this._settings.connect('notify::enable-animations',
this._syncAnimationsEnabled.bind(this));
this._syncAnimationsEnabled();
}
_isStandaloneApp(app) {
@@ -56,7 +66,7 @@ var IntrospectService = class {
}
_isIntrospectEnabled() {
return this._settings.get_boolean(INTROSPECT_KEY);
return this._introspectSettings.get_boolean(INTROSPECT_KEY);
}
_isSenderWhitelisted(sender) {
@@ -119,9 +129,18 @@ var IntrospectService = class {
type == Meta.WindowType.UTILITY;
}
_isInvocationAllowed(invocation) {
if (this._isIntrospectEnabled())
return true;
if (this._isSenderWhitelisted(invocation.get_sender()))
return true;
return false;
}
GetRunningApplicationsAsync(params, invocation) {
if (!this._isIntrospectEnabled() &&
!this._isSenderWhitelisted(invocation.get_sender())) {
if (!this._isInvocationAllowed(invocation)) {
invocation.return_error_literal(Gio.DBusError,
Gio.DBusError.ACCESS_DENIED,
'App introspection not allowed');
@@ -136,8 +155,7 @@ var IntrospectService = class {
let apps = this._appSystem.get_running();
let windowsList = {};
if (!this._isIntrospectEnabled() &&
!this._isSenderWhitelisted(invocation.get_sender())) {
if (!this._isInvocationAllowed(invocation)) {
invocation.return_error_literal(Gio.DBusError,
Gio.DBusError.ACCESS_DENIED,
'App introspection not allowed');
@@ -181,4 +199,21 @@ var IntrospectService = class {
}
invocation.return_value(new GLib.Variant('(a{ta{sv}})', [windowsList]));
}
_syncAnimationsEnabled() {
let wasAnimationsEnabled = this._animationsEnabled;
this._animationsEnabled = this._settings.enable_animations;
if (wasAnimationsEnabled !== this._animationsEnabled) {
let variant = new GLib.Variant('b', this._animationsEnabled);
this._dbusImpl.emit_property_changed('AnimationsEnabled', variant);
}
}
get AnimationsEnabled() {
return this._animationsEnabled;
}
get version() {
return INTROSPECT_DBUS_API_VERSION;
}
};

View File

@@ -151,17 +151,17 @@ const SystemActions = GObject.registerClass({
this._userManager.connect('user-removed',
() => this._updateMultiUser());
this._lockdownSettings.connect(`changed::${DISABLE_USER_SWITCH_KEY}`,
this._lockdownSettings.connect('changed::%s'.format(DISABLE_USER_SWITCH_KEY),
() => this._updateSwitchUser());
this._lockdownSettings.connect(`changed::${DISABLE_LOG_OUT_KEY}`,
this._lockdownSettings.connect('changed::%s'.format(DISABLE_LOG_OUT_KEY),
() => this._updateLogout());
global.settings.connect(`changed::${ALWAYS_SHOW_LOG_OUT_KEY}`,
global.settings.connect('changed::%s'.format(ALWAYS_SHOW_LOG_OUT_KEY),
() => this._updateLogout());
this._lockdownSettings.connect(`changed::${DISABLE_LOCK_SCREEN_KEY}`,
this._lockdownSettings.connect('changed::%s'.format(DISABLE_LOCK_SCREEN_KEY),
() => this._updateLockScreen());
this._lockdownSettings.connect(`changed::${DISABLE_LOG_OUT_KEY}`,
this._lockdownSettings.connect('changed::%s'.format(DISABLE_LOG_OUT_KEY),
() => this._updateHaveShutdown());
this.forceUpdate();

View File

@@ -11,13 +11,17 @@ const Params = imports.misc.params;
var SCROLL_TIME = 100;
const WIGGLE_OFFSET = 6;
const WIGGLE_DURATION = 65;
const N_WIGGLES = 3;
// http://daringfireball.net/2010/07/improved_regex_for_matching_urls
const _balancedParens = '\\([^\\s()<>]+\\)';
const _leadingJunk = '[\\s`(\\[{\'\\"<\u00AB\u201C\u2018]';
const _notTrailingJunk = '[^\\s`!()\\[\\]{};:\'\\".,<>?\u00AB\u00BB\u200E\u200F\u201C\u201D\u2018\u2019\u202A\u202C]';
const _urlRegexp = new RegExp(
`(^|${_leadingJunk})` +
'(^|%s)'.format(_leadingJunk) +
'(' +
'(?:' +
'(?:http|https|ftp)://' + // scheme://
@@ -29,12 +33,12 @@ const _urlRegexp = new RegExp(
'(?:' + // one or more:
'[^\\s()<>]+' + // run of non-space non-()
'|' + // or
`${_balancedParens}` + // balanced parens
'%s'.format(_balancedParens) + // balanced parens
')+' +
'(?:' + // end with:
`${_balancedParens}` + // balanced parens
'%s'.format(_balancedParens) + // balanced parens
'|' + // or
`${_notTrailingJunk}` + // last non-junk char
'%s'.format(_notTrailingJunk) + // last non-junk char
')' +
')', 'gi');
@@ -149,7 +153,7 @@ function trySpawnCommandLine(commandLine) {
} catch (err) {
// Replace "Error invoking GLib.shell_parse_argv: " with
// something nicer
err.message = err.message.replace(/[^:]*: /, `${_("Could not parse command:")}\n`);
err.message = err.message.replace(/[^:]*: /, '%s\n'.format(_('Could not parse command:')));
throw err;
}
@@ -441,10 +445,13 @@ function ensureActorVisibleInScrollView(scrollView, actor) {
}
function wiggle(actor, params) {
if (!St.Settings.get().enable_animations)
return;
params = Params.parse(params, {
offset: 0,
duration: 0,
wiggleCount: 0,
offset: WIGGLE_OFFSET,
duration: WIGGLE_DURATION,
wiggleCount: N_WIGGLES,
});
actor.translation_x = 0;

View File

@@ -1,4 +1,6 @@
/* exported main */
imports.gi.versions.Gtk = '3.0';
const Format = imports.format;
const Gettext = imports.gettext;
const { Gio, GLib, GObject, Gtk, Pango, Soup, WebKit2: WebKit } = imports.gi;
@@ -21,7 +23,6 @@ const PortalHelperSecurityLevel = {
};
const CONNECTIVITY_CHECK_HOST = 'nmcheck.gnome.org';
const CONNECTIVITY_CHECK_URI = `http://${CONNECTIVITY_CHECK_HOST}`;
const CONNECTIVITY_RECHECK_RATELIMIT_TIMEOUT = 30 * GLib.USEC_PER_SEC;
const HelperDBusInterface = loadInterfaceXML('org.gnome.Shell.PortalHelper');
@@ -101,7 +102,7 @@ class PortalWindow extends Gtk.ApplicationWindow {
this._headerBar.show();
if (!url) {
url = CONNECTIVITY_CHECK_URI;
url = 'http://%s'.format(CONNECTIVITY_CHECK_HOST);
this._originalUrlWasGnome = true;
} else {
this._originalUrlWasGnome = false;
@@ -116,6 +117,10 @@ class PortalWindow extends Gtk.ApplicationWindow {
this._webContext = WebKit.WebContext.new_ephemeral();
this._webContext.set_cache_model(WebKit.CacheModel.DOCUMENT_VIEWER);
this._webContext.set_network_proxy_settings(WebKit.NetworkProxyMode.NO_PROXY, null);
if (this._webContext.set_sandbox_enabled) {
// We have WebKitGTK 2.26 or newer.
this._webContext.set_sandbox_enabled(true);
}
this._webView = WebKit.WebView.new_with_context(this._webContext);
this._webView.connect('decide-policy', this._onDecidePolicy.bind(this));

View File

@@ -7,5 +7,10 @@
<file>misc/extensionUtils.js</file>
<file>misc/fileUtils.js</file>
<file>misc/params.js</file>
<file alias="css/application.css">extensionPrefs/css/application.css</file>
<file alias="ui/extension-row.ui">extensionPrefs/ui/extension-row.ui</file>
<file alias="ui/extensions-window.ui">extensionPrefs/ui/extensions-window.ui</file>
</gresource>
</gresources>

View File

@@ -138,7 +138,7 @@ var AccessDialogDBus = class {
let [handle, appId, parentWindow_, title, description, body, options] = params;
// We probably want to use parentWindow and global.display.focus_window
// for this check in the future
if (appId && `${appId}.desktop` != this._windowTracker.focus_app.id) {
if (appId && '%s.desktop'.format(appId) != this._windowTracker.focus_app.id) {
invocation.return_error_literal(Gio.DBusError,
Gio.DBusError.ACCESS_DENIED,
'Only the focused app is allowed to show a system access dialog');

View File

@@ -72,7 +72,7 @@ function _getFolderName(folder) {
if (folder.get_boolean('translate')) {
let keyfile = new GLib.KeyFile();
let path = `desktop-directories/${name}`;
let path = 'desktop-directories/%s'.format(name);
try {
keyfile.load_from_data_dirs(path, GLib.KeyFileFlags.NONE);
@@ -219,7 +219,7 @@ var BaseAppView = GObject.registerClass({
if (this._items.has(id))
this._items.get(id).navigate_focus(null, St.DirectionType.TAB_FORWARD, false);
else
log(`No such application ${id}`);
log('No such application %s'.format(id));
}
selectApp(id) {
@@ -293,7 +293,7 @@ var BaseAppView = GObject.registerClass({
}
adaptToSize(_width, _height) {
throw new GObject.NotImplementedError(`adaptToSize in ${this.constructor.name}`);
throw new GObject.NotImplementedError('adaptToSize in %s'.format(this.constructor.name));
}
});
@@ -492,7 +492,7 @@ var AllView = GObject.registerClass({
let folders = this._folderSettings.get_strv('folder-children');
folders.forEach(id => {
let path = `${this._folderSettings.path}folders/${id}/`;
let path = '%sfolders/%s/'.format(this._folderSettings.path, id);
let icon = this._items.get(id);
if (!icon) {
icon = new FolderIcon(id, path, this);
@@ -530,8 +530,10 @@ var AllView = GObject.registerClass({
// Overridden from BaseAppView
animate(animationDirection, onComplete) {
this._scrollView.reactive = false;
this._swipeTracker.enabled = false;
let completionFunc = () => {
this._scrollView.reactive = true;
this._swipeTracker.enabled = this.mapped;
if (onComplete)
onComplete();
};
@@ -1523,10 +1525,10 @@ var FolderIcon = GObject.registerClass({
}
vfunc_unmap() {
super.vfunc_unmap();
if (this._dialog)
this._dialog.popdown();
super.vfunc_unmap();
}
open() {
@@ -1655,10 +1657,6 @@ var AppFolderDialog = GObject.registerClass({
x_align: Clutter.ActorAlign.CENTER,
y_align: Clutter.ActorAlign.CENTER,
});
this.add_constraint(new Clutter.BindConstraint({
source: Main.overview.viewSelector,
coordinate: Clutter.BindCoordinate.ALL,
}));
this._source = source;
this._folder = folder;
@@ -2276,7 +2274,7 @@ var AppIcon = GObject.registerClass({
shellWorkspaceLaunch(params) {
let { stack } = new Error();
log(`shellWorkspaceLaunch is deprecated, use app.open_new_window() instead\n${stack}`);
log('shellWorkspaceLaunch is deprecated, use app.open_new_window() instead\n%s'.format(stack));
params = Params.parse(params, { workspace: -1,
timestamp: 0 });

View File

@@ -66,7 +66,7 @@ class AppFavorites {
constructor() {
this.FAVORITE_APPS_KEY = 'favorite-apps';
this._favorites = {};
global.settings.connect(`changed::${this.FAVORITE_APPS_KEY}`, this._onFavsChanged.bind(this));
global.settings.connect('changed::%s'.format(this.FAVORITE_APPS_KEY), this._onFavsChanged.bind(this));
this.reload();
}

View File

@@ -120,7 +120,7 @@ var AudioDeviceSelectionDialog = GObject.registerClass({
let app = Shell.AppSystem.get_default().lookup_app(desktopFile);
if (!app) {
log(`Settings panel for desktop file ${desktopFile} could not be loaded!`);
log('Settings panel for desktop file %s could not be loaded!'.format(desktopFile));
return;
}

View File

@@ -504,12 +504,9 @@ var SystemBackground = GObject.registerClass({
Signals: { 'loaded': {} },
}, class SystemBackground extends Meta.BackgroundActor {
_init() {
let file = Gio.File.new_for_uri('resource:///org/gnome/shell/theme/noise-texture.png');
if (_systemBackground == null) {
_systemBackground = new Meta.Background({ meta_display: global.display });
_systemBackground.set_color(DEFAULT_BACKGROUND_COLOR);
_systemBackground.set_file(file, GDesktopEnums.BackgroundStyle.WALLPAPER);
}
super._init({
@@ -518,22 +515,11 @@ var SystemBackground = GObject.registerClass({
background: _systemBackground,
});
let cache = Meta.BackgroundImageCache.get_default();
let image = cache.load(file);
if (image.is_loaded()) {
image = null;
let id = GLib.idle_add(GLib.PRIORITY_DEFAULT, () => {
this.emit('loaded');
return GLib.SOURCE_REMOVE;
});
GLib.Source.set_name_by_id(id, '[gnome-shell] SystemBackground.loaded');
} else {
let id = image.connect('loaded', () => {
this.emit('loaded');
image.disconnect(id);
image = null;
});
}
let id = GLib.idle_add(GLib.PRIORITY_DEFAULT, () => {
this.emit('loaded');
return GLib.SOURCE_REMOVE;
});
GLib.Source.set_name_by_id(id, '[gnome-shell] SystemBackground.loaded');
}
});

View File

@@ -18,7 +18,7 @@ var ELLIPSIS_CHAR = '\u2026';
var MESSAGE_ICON_SIZE = -1; // pick up from CSS
var NC_ = (context, str) => `${context}\u0004${str}`;
var NC_ = (context, str) => '%s\u0004%s'.format(context, str);
function sameYear(dateA, dateB) {
return dateA.getYear() == dateB.getYear();
@@ -114,26 +114,26 @@ var EventSourceBase = GObject.registerClass({
Signals: { 'changed': {} },
}, class EventSourceBase extends GObject.Object {
get isLoading() {
throw new GObject.NotImplementedError(`isLoading in ${this.constructor.name}`);
throw new GObject.NotImplementedError('isLoading in %s'.format(this.constructor.name));
}
get hasCalendars() {
throw new GObject.NotImplementedError(`hasCalendars in ${this.constructor.name}`);
throw new GObject.NotImplementedError('hasCalendars in %s'.format(this.constructor.name));
}
destroy() {
}
requestRange(_begin, _end) {
throw new GObject.NotImplementedError(`requestRange in ${this.constructor.name}`);
throw new GObject.NotImplementedError('requestRange in %s'.format(this.constructor.name));
}
getEvents(_begin, _end) {
throw new GObject.NotImplementedError(`getEvents in ${this.constructor.name}`);
throw new GObject.NotImplementedError('getEvents in %s'.format(this.constructor.name));
}
hasEvents(_day) {
throw new GObject.NotImplementedError(`hasEvents in ${this.constructor.name}`);
throw new GObject.NotImplementedError('hasEvents in %s'.format(this.constructor.name));
}
});
@@ -215,7 +215,7 @@ class DBusEventSource extends EventSourceBase {
// about the HasCalendars property and would cause an exception trying
// to read it)
} else {
log(`Error loading calendars: ${e.message}`);
log('Error loading calendars: %s'.format(e.message));
return;
}
}
@@ -359,7 +359,7 @@ var Calendar = GObject.registerClass({
this._weekStart = Shell.util_get_week_start();
this._settings = new Gio.Settings({ schema_id: 'org.gnome.desktop.calendar' });
this._settings.connect(`changed::${SHOW_WEEKDATE_KEY}`, this._onSettingsChange.bind(this));
this._settings.connect('changed::%s'.format(SHOW_WEEKDATE_KEY), this._onSettingsChange.bind(this));
this._useWeekdate = this._settings.get_boolean(SHOW_WEEKDATE_KEY);
/**
@@ -626,13 +626,13 @@ var Calendar = GObject.registerClass({
// Hack used in lieu of border-collapse - see gnome-shell.css
if (row == 2)
styleClass = `calendar-day-top ${styleClass}`;
styleClass = 'calendar-day-top %s'.format(styleClass);
let leftMost = rtl
? iter.getDay() == (this._weekStart + 6) % 7
: iter.getDay() == this._weekStart;
if (leftMost)
styleClass = `calendar-day-left ${styleClass}`;
styleClass = 'calendar-day-left %s'.format(styleClass);
if (sameDay(now, iter))
styleClass += ' calendar-today';
@@ -738,15 +738,15 @@ class EventMessage extends MessageList.Message {
let rtl = Clutter.get_default_text_direction() == Clutter.TextDirection.RTL;
if (this._event.date < periodBegin && !this._event.allDay) {
if (rtl)
title = `${title}${ELLIPSIS_CHAR}`;
title = '%s%s'.format(title, ELLIPSIS_CHAR);
else
title = `${ELLIPSIS_CHAR}${title}`;
title = '%s%s'.format(ELLIPSIS_CHAR, title);
}
if (this._event.end > periodEnd && !this._event.allDay) {
if (rtl)
title = `${ELLIPSIS_CHAR}${title}`;
title = '%s%s'.format(ELLIPSIS_CHAR, title);
else
title = `${title}${ELLIPSIS_CHAR}`;
title = '%s%s'.format(title, ELLIPSIS_CHAR);
}
return title;
}
@@ -1204,7 +1204,7 @@ class CalendarMessageList extends St.Widget {
for (let prop of ['visible', 'empty', 'can-clear']) {
connectionsIds.push(
section.connect(`notify::${prop}`, this._sync.bind(this)));
section.connect('notify::%s'.format(prop), this._sync.bind(this)));
}
connectionsIds.push(section.connect('message-focused', (_s, messageActor) => {
Util.ensureActorVisibleInScrollView(this._scrollView, messageActor);

View File

@@ -192,6 +192,7 @@ var CloseDialog = GObject.registerClass({
this._dialog = null;
this._removeWindowEffect();
dialog.makeInactive();
dialog._dialog.ease({
scale_y: 0,
mode: Clutter.AnimationMode.LINEAR,

View File

@@ -113,7 +113,7 @@ var AutomountManager = class {
try {
drive.stop_finish(res);
} catch (e) {
log(`Unable to stop the drive after drive-eject-button ${e.toString()}`);
log('Unable to stop the drive after drive-eject-button %s'.format(e.toString()));
}
});
} else if (drive.can_eject()) {
@@ -122,7 +122,7 @@ var AutomountManager = class {
try {
drive.eject_with_operation_finish(res);
} catch (e) {
log(`Unable to eject the drive after drive-eject-button ${e.toString()}`);
log('Unable to eject the drive after drive-eject-button %s'.format(e.toString()));
}
});
}
@@ -210,7 +210,7 @@ var AutomountManager = class {
}
if (!e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.FAILED_HANDLED))
log(`Unable to mount volume ${volume.get_name()}: ${e.toString()}`);
log('Unable to mount volume %s: %s'.format(volume.get_name(), e.toString()));
this._closeOperation(volume);
}
}

View File

@@ -66,7 +66,7 @@ function startAppForMount(app, mount) {
retval = app.launch(files,
global.create_app_launch_context(0, -1));
} catch (e) {
log(`Unable to launch the application ${app.get_name()}: ${e}`);
log('Unable to launch the application %s: %s'.format(app.get_name(), e.toString()));
}
return retval;
@@ -105,7 +105,7 @@ var ContentTypeDiscoverer = class {
try {
contentTypes = mount.guess_content_type_finish(res);
} catch (e) {
log(`Unable to guess content types on added mount ${mount.get_name()}: ${e}`);
log('Unable to guess content types on added mount %s: %s'.format(mount.get_name(), e.toString()));
}
if (contentTypes.length) {

View File

@@ -3,13 +3,11 @@
const { Clutter, Gcr, Gio, GObject, Pango, Shell, St } = imports.gi;
const Animation = imports.ui.animation;
const Dialog = imports.ui.dialog;
const ModalDialog = imports.ui.modalDialog;
const ShellEntry = imports.ui.shellEntry;
const CheckBox = imports.ui.checkBox;
var WORK_SPINNER_ICON_SIZE = 16;
const Util = imports.misc.util;
var KeyringDialog = GObject.registerClass(
class KeyringDialog extends ModalDialog.ModalDialog {
@@ -21,141 +19,97 @@ class KeyringDialog extends ModalDialog.ModalDialog {
this.prompt.connect('show-confirm', this._onShowConfirm.bind(this));
this.prompt.connect('prompt-close', this._onHidePrompt.bind(this));
this._content = new Dialog.MessageDialogContent();
this.contentLayout.add(this._content);
let content = new Dialog.MessageDialogContent();
this.prompt.bind_property('message', this._content, 'title', GObject.BindingFlags.SYNC_CREATE);
this.prompt.bind_property('description', this._content, 'description', GObject.BindingFlags.SYNC_CREATE);
this.prompt.bind_property('message',
content, 'title', GObject.BindingFlags.SYNC_CREATE);
this.prompt.bind_property('description',
content, 'description', GObject.BindingFlags.SYNC_CREATE);
this._workSpinner = null;
this._controlTable = null;
let passwordBox = new St.BoxLayout({
style_class: 'prompt-dialog-password-layout',
vertical: true,
});
this._cancelButton = this.addButton({ label: '',
action: this._onCancelButton.bind(this),
key: Clutter.KEY_Escape });
this._continueButton = this.addButton({ label: '',
action: this._onContinueButton.bind(this),
default: true });
this._passwordEntry = new St.PasswordEntry({
style_class: 'prompt-dialog-password-entry',
can_focus: true,
x_align: Clutter.ActorAlign.CENTER,
});
ShellEntry.addContextMenu(this._passwordEntry);
this._passwordEntry.clutter_text.connect('activate', this._onPasswordActivate.bind(this));
this.prompt.bind_property('password-visible',
this._passwordEntry, 'visible', GObject.BindingFlags.SYNC_CREATE);
passwordBox.add_child(this._passwordEntry);
this._confirmEntry = new St.PasswordEntry({
style_class: 'prompt-dialog-password-entry',
can_focus: true,
x_align: Clutter.ActorAlign.CENTER,
});
ShellEntry.addContextMenu(this._confirmEntry);
this._confirmEntry.clutter_text.connect('activate', this._onConfirmActivate.bind(this));
this.prompt.bind_property('confirm-visible',
this._confirmEntry, 'visible', GObject.BindingFlags.SYNC_CREATE);
passwordBox.add_child(this._confirmEntry);
this.prompt.set_password_actor(this._passwordEntry.clutter_text);
this.prompt.set_confirm_actor(this._confirmEntry.clutter_text);
let warningBox = new St.BoxLayout({ vertical: true });
let capsLockWarning = new ShellEntry.CapsLockWarning();
let syncCapsLockWarningVisibility = () => {
capsLockWarning.visible =
this.prompt.password_visible || this.prompt.confirm_visible;
};
this.prompt.connect('notify::password-visible', syncCapsLockWarningVisibility);
this.prompt.connect('notify::confirm-visible', syncCapsLockWarningVisibility);
warningBox.add_child(capsLockWarning);
let warning = new St.Label({ style_class: 'prompt-dialog-error-label' });
warning.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
warning.clutter_text.line_wrap = true;
this.prompt.bind_property('warning',
warning, 'text', GObject.BindingFlags.SYNC_CREATE);
this.prompt.connect('notify::warning-visible', () => {
warning.opacity = this.prompt.warning_visible ? 255 : 0;
});
this.prompt.connect('notify::warning', () => {
if (this._passwordEntry && warning !== '')
Util.wiggle(this._passwordEntry);
});
warningBox.add_child(warning);
passwordBox.add_child(warningBox);
content.add_child(passwordBox);
this._choice = new CheckBox.CheckBox();
this.prompt.bind_property('choice-label', this._choice.getLabelActor(),
'text', GObject.BindingFlags.SYNC_CREATE);
this.prompt.bind_property('choice-chosen', this._choice,
'checked', GObject.BindingFlags.SYNC_CREATE | GObject.BindingFlags.BIDIRECTIONAL);
this.prompt.bind_property('choice-visible', this._choice,
'visible', GObject.BindingFlags.SYNC_CREATE);
content.add_child(this._choice);
this.contentLayout.add_child(content);
this._cancelButton = this.addButton({
label: '',
action: this._onCancelButton.bind(this),
key: Clutter.KEY_Escape,
});
this._continueButton = this.addButton({
label: '',
action: this._onContinueButton.bind(this),
default: true,
});
this.prompt.bind_property('cancel-label', this._cancelButton, 'label', GObject.BindingFlags.SYNC_CREATE);
this.prompt.bind_property('continue-label', this._continueButton, 'label', GObject.BindingFlags.SYNC_CREATE);
}
_setWorking(working) {
if (!this._workSpinner)
return;
if (working)
this._workSpinner.play();
else
this._workSpinner.stop();
}
_buildControlTable() {
let layout = new Clutter.GridLayout({ orientation: Clutter.Orientation.VERTICAL });
let table = new St.Widget({
style_class: 'keyring-dialog-control-table',
layout_manager: layout,
x_expand: true,
y_expand: true,
});
layout.hookup_style(table);
let rtl = table.get_text_direction() == Clutter.TextDirection.RTL;
let row = 0;
if (this.prompt.password_visible) {
let label = new St.Label({ style_class: 'prompt-dialog-password-label',
x_align: Clutter.ActorAlign.START,
y_align: Clutter.ActorAlign.CENTER });
label.set_text(_("Password:"));
label.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
this._passwordEntry = new St.PasswordEntry({
style_class: 'prompt-dialog-password-entry',
text: '',
can_focus: true,
x_expand: true,
});
ShellEntry.addContextMenu(this._passwordEntry);
this._passwordEntry.clutter_text.connect('activate', this._onPasswordActivate.bind(this));
this._workSpinner = new Animation.Spinner(WORK_SPINNER_ICON_SIZE, {
animate: true,
});
if (rtl) {
layout.attach(this._workSpinner, 0, row, 1, 1);
layout.attach(this._passwordEntry, 1, row, 1, 1);
layout.attach(label, 2, row, 1, 1);
} else {
layout.attach(label, 0, row, 1, 1);
layout.attach(this._passwordEntry, 1, row, 1, 1);
layout.attach(this._workSpinner, 2, row, 1, 1);
}
row++;
} else {
this._workSpinner = null;
this._passwordEntry = null;
}
if (this.prompt.confirm_visible) {
var label = new St.Label({ style_class: 'prompt-dialog-password-label',
x_align: Clutter.ActorAlign.START,
y_align: Clutter.ActorAlign.CENTER });
label.set_text(_("Type again:"));
this._confirmEntry = new St.PasswordEntry({
style_class: 'prompt-dialog-password-entry',
text: '',
can_focus: true,
x_expand: true,
});
ShellEntry.addContextMenu(this._confirmEntry);
this._confirmEntry.clutter_text.connect('activate', this._onConfirmActivate.bind(this));
if (rtl) {
layout.attach(this._confirmEntry, 0, row, 1, 1);
layout.attach(label, 1, row, 1, 1);
} else {
layout.attach(label, 0, row, 1, 1);
layout.attach(this._confirmEntry, 1, row, 1, 1);
}
row++;
} else {
this._confirmEntry = null;
}
this.prompt.set_password_actor(this._passwordEntry ? this._passwordEntry.clutter_text : null);
this.prompt.set_confirm_actor(this._confirmEntry ? this._confirmEntry.clutter_text : null);
if (this._passwordEntry || this._confirmEntry) {
this._capsLockWarningLabel = new ShellEntry.CapsLockWarning();
layout.attach(this._capsLockWarningLabel, 1, row, 1, 1);
row++;
}
if (this.prompt.choice_visible) {
let choice = new CheckBox.CheckBox();
this.prompt.bind_property('choice-label', choice.getLabelActor(), 'text', GObject.BindingFlags.SYNC_CREATE);
this.prompt.bind_property('choice-chosen', choice, 'checked', GObject.BindingFlags.SYNC_CREATE | GObject.BindingFlags.BIDIRECTIONAL);
layout.attach(choice, rtl ? 0 : 1, row, 1, 1);
row++;
}
let warning = new St.Label({ style_class: 'prompt-dialog-error-label',
x_align: Clutter.ActorAlign.START });
warning.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
warning.clutter_text.line_wrap = true;
layout.attach(warning, rtl ? 0 : 1, row, 1, 1);
this.prompt.bind_property('warning-visible', warning, 'visible', GObject.BindingFlags.SYNC_CREATE);
this.prompt.bind_property('warning', warning, 'text', GObject.BindingFlags.SYNC_CREATE);
if (this._controlTable) {
this._controlTable.destroy_all_children();
this._controlTable.destroy();
}
this._controlTable = table;
this._content.add_child(table);
}
_updateSensitivity(sensitive) {
if (this._passwordEntry) {
this._passwordEntry.reactive = sensitive;
@@ -169,7 +123,6 @@ class KeyringDialog extends ModalDialog.ModalDialog {
this._continueButton.can_focus = sensitive;
this._continueButton.reactive = sensitive;
this._setWorking(!sensitive);
}
_ensureOpen() {
@@ -191,16 +144,16 @@ class KeyringDialog extends ModalDialog.ModalDialog {
}
_onShowPassword() {
this._buildControlTable();
this._ensureOpen();
this._updateSensitivity(true);
this._passwordEntry.text = '';
this._passwordEntry.grab_key_focus();
}
_onShowConfirm() {
this._buildControlTable();
this._ensureOpen();
this._updateSensitivity(true);
this._confirmEntry.text = '';
this._continueButton.grab_key_focus();
}

View File

@@ -33,38 +33,26 @@ class NetworkSecretDialog extends ModalDialog.ModalDialog {
title: this._content.title,
description: this._content.message,
});
this.contentLayout.add_actor(contentBox);
let layout = new Clutter.GridLayout({ orientation: Clutter.Orientation.VERTICAL });
let secretTable = new St.Widget({ style_class: 'network-dialog-secret-table',
layout_manager: layout });
layout.hookup_style(secretTable);
let rtl = secretTable.get_text_direction() == Clutter.TextDirection.RTL;
let initialFocusSet = false;
let pos = 0;
for (let i = 0; i < this._content.secrets.length; i++) {
let secret = this._content.secrets[i];
let label = new St.Label({ style_class: 'prompt-dialog-password-label',
text: secret.label,
x_align: Clutter.ActorAlign.START,
y_align: Clutter.ActorAlign.CENTER });
label.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
let reactive = secret.key != null;
let entryParams = {
style_class: 'prompt-dialog-password-entry',
hint_text: secret.label,
text: secret.value,
can_focus: reactive,
reactive,
x_expand: true,
x_align: Clutter.ActorAlign.CENTER,
};
if (secret.password)
secret.entry = new St.PasswordEntry(entryParams);
else
secret.entry = new St.Entry(entryParams);
ShellEntry.addContextMenu(secret.entry);
contentBox.add_child(secret.entry);
if (secret.validate)
secret.valid = secret.validate(secret);
@@ -89,36 +77,26 @@ class NetworkSecretDialog extends ModalDialog.ModalDialog {
} else {
secret.valid = true;
}
if (rtl) {
layout.attach(secret.entry, 0, pos, 1, 1);
layout.attach(label, 1, pos, 1, 1);
} else {
layout.attach(label, 0, pos, 1, 1);
layout.attach(secret.entry, 1, pos, 1, 1);
}
pos++;
}
if (this._content.secrets.some(s => s.password)) {
this._capsLockWarningLabel = new ShellEntry.CapsLockWarning();
if (rtl)
layout.attach(this._capsLockWarningLabel, 0, pos, 1, 1);
else
layout.attach(this._capsLockWarningLabel, 1, pos, 1, 1);
let capsLockWarning = new ShellEntry.CapsLockWarning();
contentBox.add_child(capsLockWarning);
}
contentBox.add_child(secretTable);
if (flags & NM.SecretAgentGetSecretsFlags.WPS_PBC_ACTIVE) {
let descriptionLabel = new St.Label({ style_class: 'prompt-dialog-description',
text: _("Alternatively you can connect by pushing the “WPS” button on your router.") });
let descriptionLabel = new St.Label({
text: _('Alternatively you can connect by pushing the “WPS” button on your router.'),
style_class: 'message-dialog-description',
});
descriptionLabel.clutter_text.line_wrap = true;
descriptionLabel.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
contentBox.add_child(descriptionLabel);
}
this.contentLayout.add_child(contentBox);
this._okButton = {
label: _("Connect"),
action: this._onOk.bind(this),
@@ -221,19 +199,23 @@ class NetworkSecretDialog extends ModalDialog.ModalDialog {
case 'wpa-none':
case 'wpa-psk':
case 'sae':
secrets.push({ label: _("Password: "), key: 'psk',
secrets.push({ label: _('Password'), key: 'psk',
value: wirelessSecuritySetting.psk || '',
validate: this._validateWpaPsk, password: true });
break;
case 'none': // static WEP
secrets.push({ label: _("Key: "), key: `wep-key${wirelessSecuritySetting.wep_tx_keyidx}`,
value: wirelessSecuritySetting.get_wep_key(wirelessSecuritySetting.wep_tx_keyidx) || '',
wep_key_type: wirelessSecuritySetting.wep_key_type,
validate: this._validateStaticWep, password: true });
secrets.push({
label: _('Key'),
key: 'wep-key%s'.format(wirelessSecuritySetting.wep_tx_keyidx),
value: wirelessSecuritySetting.get_wep_key(wirelessSecuritySetting.wep_tx_keyidx) || '',
wep_key_type: wirelessSecuritySetting.wep_key_type,
validate: this._validateStaticWep,
password: true,
});
break;
case 'ieee8021x':
if (wirelessSecuritySetting.auth_alg == 'leap') { // Cisco LEAP
secrets.push({ label: _("Password: "), key: 'leap-password',
secrets.push({ label: _('Password'), key: 'leap-password',
value: wirelessSecuritySetting.leap_password || '', password: true });
} else { // Dynamic (IEEE 802.1x) WEP
this._get8021xSecrets(secrets);
@@ -243,7 +225,7 @@ class NetworkSecretDialog extends ModalDialog.ModalDialog {
this._get8021xSecrets(secrets);
break;
default:
log(`Invalid wireless key management: ${wirelessSecuritySetting.key_mgmt}`);
log('Invalid wireless key management: %s'.format(wirelessSecuritySetting.key_mgmt));
}
}
@@ -253,15 +235,15 @@ class NetworkSecretDialog extends ModalDialog.ModalDialog {
/* If hints were given we know exactly what we need to ask */
if (this._settingName == "802-1x" && this._hints.length) {
if (this._hints.includes('identity')) {
secrets.push({ label: _("Username: "), key: 'identity',
secrets.push({ label: _('Username'), key: 'identity',
value: ieee8021xSetting.identity || '', password: false });
}
if (this._hints.includes('password')) {
secrets.push({ label: _("Password: "), key: 'password',
secrets.push({ label: _('Password'), key: 'password',
value: ieee8021xSetting.password || '', password: true });
}
if (this._hints.includes('private-key-password')) {
secrets.push({ label: _("Private key password: "), key: 'private-key-password',
secrets.push({ label: _('Private key password'), key: 'private-key-password',
value: ieee8021xSetting.private_key_password || '', password: true });
}
return;
@@ -276,29 +258,29 @@ class NetworkSecretDialog extends ModalDialog.ModalDialog {
// TTLS and PEAP are actually much more complicated, but this complication
// is not visible here since we only care about phase2 authentication
// (and don't even care of which one)
secrets.push({ label: _("Username: "), key: null,
secrets.push({ label: _('Username'), key: null,
value: ieee8021xSetting.identity || '', password: false });
secrets.push({ label: _("Password: "), key: 'password',
secrets.push({ label: _('Password'), key: 'password',
value: ieee8021xSetting.password || '', password: true });
break;
case 'tls':
secrets.push({ label: _("Identity: "), key: null,
secrets.push({ label: _('Identity'), key: null,
value: ieee8021xSetting.identity || '', password: false });
secrets.push({ label: _("Private key password: "), key: 'private-key-password',
secrets.push({ label: _('Private key password'), key: 'private-key-password',
value: ieee8021xSetting.private_key_password || '', password: true });
break;
default:
log(`Invalid EAP/IEEE802.1x method: ${ieee8021xSetting.get_eap_method(0)}`);
log('Invalid EAP/IEEE802.1x method: %s'.format(ieee8021xSetting.get_eap_method(0)));
}
}
_getPPPoESecrets(secrets) {
let pppoeSetting = this._connection.get_setting_pppoe();
secrets.push({ label: _("Username: "), key: 'username',
secrets.push({ label: _('Username'), key: 'username',
value: pppoeSetting.username || '', password: false });
secrets.push({ label: _("Service: "), key: 'service',
secrets.push({ label: _('Service'), key: 'service',
value: pppoeSetting.service || '', password: false });
secrets.push({ label: _("Password: "), key: 'password',
secrets.push({ label: _('Password'), key: 'password',
value: pppoeSetting.password || '', password: true });
}
@@ -308,7 +290,7 @@ class NetworkSecretDialog extends ModalDialog.ModalDialog {
setting = this._connection.get_setting_cdma() || this._connection.get_setting_gsm();
else
setting = this._connection.get_setting_by_name(connectionType);
secrets.push({ label: _("Password: "), key: 'password',
secrets.push({ label: _('Password'), key: 'password',
value: setting.value || '', password: true });
}
@@ -325,14 +307,14 @@ class NetworkSecretDialog extends ModalDialog.ModalDialog {
case '802-11-wireless':
wirelessSetting = this._connection.get_setting_wireless();
ssid = NM.utils_ssid_to_utf8(wirelessSetting.get_ssid().get_data());
content.title = _("Authentication required by wireless network");
content.title = _('Authentication required');
content.message = _("Passwords or encryption keys are required to access the wireless network “%s”.").format(ssid);
this._getWirelessSecrets(content.secrets, wirelessSetting);
break;
case '802-3-ethernet':
content.title = _("Wired 802.1X authentication");
content.message = null;
content.secrets.push({ label: _("Network name: "), key: null,
content.secrets.push({ label: _('Network name'), key: null,
value: connectionSetting.get_id(), password: false });
this._get8021xSecrets(content.secrets);
break;
@@ -346,19 +328,19 @@ class NetworkSecretDialog extends ModalDialog.ModalDialog {
let gsmSetting = this._connection.get_setting_gsm();
content.title = _("PIN code required");
content.message = _("PIN code is needed for the mobile broadband device");
content.secrets.push({ label: _("PIN: "), key: 'pin',
content.secrets.push({ label: _('PIN'), key: 'pin',
value: gsmSetting.pin || '', password: true });
break;
}
// fall through
case 'cdma':
case 'bluetooth':
content.title = _("Mobile broadband network password");
content.title = _('Authentication required');
content.message = _("A password is required to connect to “%s”.").format(connectionSetting.get_id());
this._getMobileSecrets(content.secrets, connectionType);
break;
default:
log(`Invalid connection type: ${connectionType}`);
log('Invalid connection type: %s'.format(connectionType));
}
return content;
@@ -603,12 +585,12 @@ var VPNRequestHandler = class {
try {
vpnSetting.foreach_data_item((key, value) => {
this._stdin.write(`DATA_KEY=${key}\n`, null);
this._stdin.write(`DATA_VAL=${value || ''}\n\n`, null);
this._stdin.write('DATA_KEY=%s\n'.format(key), null);
this._stdin.write('DATA_VAL=%s\n\n'.format(value || ''), null);
});
vpnSetting.foreach_secret((key, value) => {
this._stdin.write(`SECRET_KEY=${key}\n`, null);
this._stdin.write(`SECRET_VAL=${value || ''}\n\n`, null);
this._stdin.write('SECRET_KEY=%s\n'.format(key), null);
this._stdin.write('SECRET_VAL=%s\n\n'.format(value || ''), null);
});
this._stdin.write('DONE\n\n', null);
} catch (e) {
@@ -638,7 +620,7 @@ var NetworkAgent = class {
let monitor = this._pluginDir.monitor(Gio.FileMonitorFlags.NONE, null);
monitor.connect('changed', () => (this._vpnCacheBuilt = false));
} catch (e) {
log(`Failed to create monitor for VPN plugin dir: ${e.message}`);
log('Failed to create monitor for VPN plugin dir: %s'.format(e.message));
}
this._native.connect('new-request', this._newRequest.bind(this));
@@ -700,7 +682,7 @@ var NetworkAgent = class {
case '802-11-wireless': {
let wirelessSetting = connection.get_setting_wireless();
let ssid = NM.utils_ssid_to_utf8(wirelessSetting.get_ssid().get_data());
title = _("Authentication required by wireless network");
title = _('Authentication required');
body = _("Passwords or encryption keys are required to access the wireless network “%s”.").format(ssid);
break;
}
@@ -721,7 +703,7 @@ var NetworkAgent = class {
// fall through
case 'cdma':
case 'bluetooth':
title = _("Mobile broadband network password");
title = _('Authentication required');
body = _("A password is required to connect to “%s”.").format(connectionSetting.get_id());
break;
case 'vpn':
@@ -729,7 +711,7 @@ var NetworkAgent = class {
body = _("A password is required to connect to “%s”.").format(connectionSetting.get_id());
break;
default:
log(`Invalid connection type: ${connectionType}`);
log('Invalid connection type: %s'.format(connectionType));
this._native.respond(requestId, Shell.NetworkAgentResponse.INTERNAL_ERROR);
return;
}

View File

@@ -4,21 +4,19 @@
const { AccountsService, Clutter, GLib,
GObject, Pango, PolkitAgent, Polkit, Shell, St } = imports.gi;
const Animation = imports.ui.animation;
const Dialog = imports.ui.dialog;
const Main = imports.ui.main;
const ModalDialog = imports.ui.modalDialog;
const ShellEntry = imports.ui.shellEntry;
const UserWidget = imports.ui.userWidget;
const Util = imports.misc.util;
const DialogMode = {
AUTH: 0,
CONFIRM: 1,
};
var DIALOG_ICON_SIZE = 48;
var WORK_SPINNER_ICON_SIZE = 16;
const DIALOG_ICON_SIZE = 64;
const DELAYED_RESET_TIMEOUT = 200;
@@ -40,11 +38,13 @@ var AuthenticationDialog = GObject.registerClass({
let title = _("Authentication Required");
let content = new Dialog.MessageDialogContent({ title, description });
this.contentLayout.add_actor(content);
let headerContent = new Dialog.MessageDialogContent({ title, description });
this.contentLayout.add_child(headerContent);
let bodyContent = new Dialog.MessageDialogContent();
if (userNames.length > 1) {
log(`polkitAuthenticationAgent: Received ${userNames.length} ` +
log('polkitAuthenticationAgent: Received %d'.format(userNames.length) +
'identities that can be used for authentication. Only ' +
'considering one.');
}
@@ -59,22 +59,21 @@ var AuthenticationDialog = GObject.registerClass({
let userBox = new St.BoxLayout({
style_class: 'polkit-dialog-user-layout',
vertical: false,
vertical: true,
});
content.add_child(userBox);
bodyContent.add_child(userBox);
this._userAvatar = new UserWidget.Avatar(this._user, {
iconSize: DIALOG_ICON_SIZE,
styleClass: 'polkit-dialog-user-icon',
});
this._userAvatar.x_align = Clutter.ActorAlign.CENTER;
userBox.add_child(this._userAvatar);
this._userLabel = new St.Label({
style_class: userName === 'root'
? 'polkit-dialog-user-root-label'
: 'polkit-dialog-user-label',
x_expand: true,
y_align: Clutter.ActorAlign.CENTER,
});
if (userName === 'root')
@@ -82,58 +81,60 @@ var AuthenticationDialog = GObject.registerClass({
userBox.add_child(this._userLabel);
this._passwordBox = new St.BoxLayout({ vertical: false, style_class: 'prompt-dialog-password-box' });
content.add_child(this._passwordBox);
this._passwordLabel = new St.Label({
style_class: 'prompt-dialog-password-label',
y_align: Clutter.ActorAlign.CENTER,
let passwordBox = new St.BoxLayout({
style_class: 'prompt-dialog-password-layout',
vertical: true,
});
this._passwordBox.add_child(this._passwordLabel);
this._passwordEntry = new St.PasswordEntry({
style_class: 'prompt-dialog-password-entry',
text: "",
can_focus: true,
x_expand: true,
visible: false,
x_align: Clutter.ActorAlign.CENTER,
});
ShellEntry.addContextMenu(this._passwordEntry);
this._passwordEntry.clutter_text.connect('activate', this._onEntryActivate.bind(this));
this._passwordEntry.bind_property('reactive',
this._passwordEntry.clutter_text, 'editable',
GObject.BindingFlags.SYNC_CREATE);
this._passwordBox.add_child(this._passwordEntry);
passwordBox.add_child(this._passwordEntry);
this._workSpinner = new Animation.Spinner(WORK_SPINNER_ICON_SIZE, {
animate: true,
});
this._passwordBox.add(this._workSpinner);
let warningBox = new St.BoxLayout({ vertical: true });
this._passwordBox.hide();
let capsLockWarning = new ShellEntry.CapsLockWarning();
content.add_child(capsLockWarning);
this._passwordEntry.bind_property('visible',
capsLockWarning, 'visible',
GObject.BindingFlags.SYNC_CREATE);
warningBox.add_child(capsLockWarning);
this._errorMessageLabel = new St.Label({ style_class: 'prompt-dialog-error-label' });
this._errorMessageLabel = new St.Label({
style_class: 'prompt-dialog-error-label',
visible: false,
});
this._errorMessageLabel.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
this._errorMessageLabel.clutter_text.line_wrap = true;
content.add_child(this._errorMessageLabel);
this._errorMessageLabel.hide();
warningBox.add_child(this._errorMessageLabel);
this._infoMessageLabel = new St.Label({ style_class: 'prompt-dialog-info-label' });
this._infoMessageLabel = new St.Label({
style_class: 'prompt-dialog-info-label',
visible: false,
});
this._infoMessageLabel.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
this._infoMessageLabel.clutter_text.line_wrap = true;
content.add_child(this._infoMessageLabel);
this._infoMessageLabel.hide();
warningBox.add_child(this._infoMessageLabel);
/* text is intentionally non-blank otherwise the height is not the same as for
* infoMessage and errorMessageLabel - but it is still invisible because
* gnome-shell.css sets the color to be transparent
*/
this._nullMessageLabel = new St.Label({ style_class: 'prompt-dialog-null-label',
text: 'abc' });
this._nullMessageLabel.add_style_class_name('hidden');
this._nullMessageLabel = new St.Label({ style_class: 'prompt-dialog-null-label' });
this._nullMessageLabel.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
this._nullMessageLabel.clutter_text.line_wrap = true;
content.add_child(this._nullMessageLabel);
this._nullMessageLabel.show();
warningBox.add_child(this._nullMessageLabel);
passwordBox.add_child(warningBox);
bodyContent.add_child(passwordBox);
this._cancelButton = this.addButton({ label: _("Cancel"),
action: this.cancel.bind(this),
@@ -149,6 +150,8 @@ var AuthenticationDialog = GObject.registerClass({
this._okButton.reactive = text.get_text().length > 0;
});
this.contentLayout.add_child(bodyContent);
this._doneEmitted = false;
this._mode = -1;
@@ -163,13 +166,6 @@ var AuthenticationDialog = GObject.registerClass({
this._onUserChanged();
}
_setWorking(working) {
if (working)
this._workSpinner.play();
else
this._workSpinner.stop();
}
_initiateSession() {
this._destroySession(DELAYED_RESET_TIMEOUT);
@@ -198,8 +194,8 @@ var AuthenticationDialog = GObject.registerClass({
// We could add retrying if this turns out to be a problem
log('polkitAuthenticationAgent: Failed to show modal dialog. ' +
`Dismissing authentication request for action-id ${this.actionId} ` +
`cookie ${this._cookie}`);
'Dismissing authentication request for action-id %s '.format(this.actionId) +
'cookie %s'.format(this._cookie));
this._emitDone(true);
}
}
@@ -218,7 +214,6 @@ var AuthenticationDialog = GObject.registerClass({
this._passwordEntry.reactive = false;
this._okButton.reactive = false;
this._setWorking(true);
this._session.response(response);
// When the user responds, dismiss already shown info and
@@ -260,6 +255,8 @@ var AuthenticationDialog = GObject.registerClass({
this._errorMessageLabel.show();
this._infoMessageLabel.hide();
this._nullMessageLabel.hide();
Util.wiggle(this._passwordEntry);
}
/* Try and authenticate again */
@@ -273,19 +270,20 @@ var AuthenticationDialog = GObject.registerClass({
this._sessionRequestTimeoutId = 0;
}
// Cheap localization trick
if (request == 'Password:' || request == 'Password: ')
this._passwordLabel.set_text(_("Password:"));
// Hack: The request string comes directly from PAM, if it's "Password:"
// we replace it with our own to allow localization, if it's something
// else we remove the last colon and any trailing or leading spaces.
if (request === 'Password:' || request === 'Password: ')
this._passwordEntry.hint_text = _('Password');
else
this._passwordLabel.set_text(request);
this._passwordEntry.hint_text = request.replace(/: *$/, '').trim();
this._passwordEntry.password_visible = echoOn;
this._passwordBox.show();
this._passwordEntry.show();
this._passwordEntry.set_text('');
this._passwordEntry.reactive = true;
this._okButton.reactive = false;
this._setWorking(false);
this._ensureOpen();
this._passwordEntry.grab_key_focus();
@@ -332,7 +330,7 @@ var AuthenticationDialog = GObject.registerClass({
if (this.state != ModalDialog.State.OPENED)
return;
this._passwordBox.hide();
this._passwordEntry.hide();
this._cancelButton.grab_key_focus();
this._okButton.reactive = false;
};

View File

@@ -87,7 +87,7 @@ var TelepathyComponent = class {
try {
this._client.register();
} catch (e) {
throw new Error(`Could not register Telepathy client. Error: ${e}`);
throw new Error('Could not register Telepathy client. Error: %s'.format(e.toString()));
}
if (!this._client.account_manager.is_prepared(Tp.AccountManager.get_feature_quark_core()))
@@ -254,7 +254,7 @@ class TelepathyClient extends Tp.BaseClient {
dispatchOp.claim_with_finish(result);
this._handlingChannels(account, conn, [channel], false);
} catch (err) {
log(`Failed to Claim channel: ${err}`);
log('Failed to Claim channel: %s'.format(err.toString()));
}
});

View File

@@ -230,7 +230,7 @@ class WorldClocksSection extends St.Button {
_onProxyReady(proxy, error) {
if (error) {
log(`Failed to create GNOME Clocks proxy: ${error}`);
log('Failed to create GNOME Clocks proxy: %s'.format(error));
return;
}
@@ -454,6 +454,8 @@ class MessagesIndicator extends St.Icon {
let sources = Main.messageTray.getSources();
sources.forEach(source => this._onSourceAdded(null, source));
this._sync();
this.connect('destroy', () => {
this._settings.run_dispose();
this._settings = null;
@@ -488,26 +490,6 @@ class MessagesIndicator extends St.Icon {
}
});
var IndicatorPad = GObject.registerClass(
class IndicatorPad extends St.Widget {
_init(actor) {
this._source = actor;
this._source.connect('notify::size', () => this.queue_relayout());
super._init();
this._source.bind_property('visible',
this, 'visible',
GObject.BindingFlags.SYNC_CREATE);
}
vfunc_get_preferred_width(forHeight) {
return this._source.get_preferred_width(forHeight);
}
vfunc_get_preferred_height(forWidth) {
return this._source.get_preferred_height(forWidth);
}
});
var FreezableBinLayout = GObject.registerClass(
class FreezableBinLayout extends Clutter.BinLayout {
_init() {
@@ -568,16 +550,24 @@ class DateMenuButton extends PanelMenu.Button {
let hbox;
let vbox;
let menuAlignment = 0.5;
if (Clutter.get_default_text_direction() == Clutter.TextDirection.RTL)
menuAlignment = 1.0 - menuAlignment;
super._init(menuAlignment);
super._init(0.5);
this._clockDisplay = new St.Label({ style_class: 'clock' });
this._clockDisplay.clutter_text.y_align = Clutter.ActorAlign.CENTER;
this._clockDisplay = new St.Label({ y_align: Clutter.ActorAlign.CENTER });
this._indicator = new MessagesIndicator();
const indicatorPad = new St.Widget();
this._indicator.bind_property('visible',
indicatorPad, 'visible',
GObject.BindingFlags.SYNC_CREATE);
indicatorPad.add_constraint(new Clutter.BindConstraint({
source: this._indicator,
coordinate: Clutter.BindCoordinate.SIZE,
}));
let box = new St.BoxLayout({ style_class: 'clock-display-box' });
box.add_actor(new IndicatorPad(this._indicator));
box.add_actor(indicatorPad);
box.add_actor(this._clockDisplay);
box.add_actor(this._indicator);
@@ -630,7 +620,7 @@ class DateMenuButton extends PanelMenu.Button {
this._displaysSection = new St.ScrollView({ style_class: 'datemenu-displays-section vfade',
x_expand: true,
overlay_scrollbars: true });
this._displaysSection.set_policy(St.PolicyType.NEVER, St.PolicyType.AUTOMATIC);
this._displaysSection.set_policy(St.PolicyType.NEVER, St.PolicyType.EXTERNAL);
vbox.add_actor(this._displaysSection);
let displaysBox = new St.BoxLayout({ vertical: true,

View File

@@ -1,7 +1,7 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
/* exported Dialog, MessageDialogContent, ListSection, ListSectionItem */
const { Clutter, GObject, Pango, St } = imports.gi;
const { Clutter, GObject, Meta, Pango, St } = imports.gi;
function _setLabel(label, value) {
label.set({
@@ -58,10 +58,16 @@ class Dialog extends St.Widget {
this._dialog.add_child(this.buttonLayout);
}
_onDestroy() {
makeInactive() {
if (this._eventId != 0)
this._parentActor.disconnect(this._eventId);
this._eventId = 0;
this.buttonLayout.get_children().forEach(c => c.set_reactive(false));
}
_onDestroy() {
this.makeInactive();
}
_modalEventHandler(actor, event) {
@@ -179,10 +185,20 @@ var MessageDialogContent = GObject.registerClass({
};
super._init(Object.assign(defaultParams, params));
this.connect('notify::size', this._updateTitleStyle.bind(this));
this.connect('destroy', this._onDestroy.bind(this));
this.add_child(this._title);
this.add_child(this._description);
}
_onDestroy() {
if (this._updateTitleStyleLater) {
Meta.later_remove(this._updateTitleStyleLater);
delete this._updateTitleStyleLater;
}
}
get title() {
return this._title.text;
}
@@ -191,8 +207,32 @@ var MessageDialogContent = GObject.registerClass({
return this._description.text;
}
_updateTitleStyle() {
if (!this._title.mapped)
return;
this._title.ensure_style();
const [, titleNatWidth] = this._title.get_preferred_width(-1);
if (titleNatWidth > this.width) {
if (this._updateTitleStyleLater)
return;
this._updateTitleStyleLater = Meta.later_add(Meta.LaterType.BEFORE_REDRAW, () => {
this._updateTitleStyleLater = 0;
this._title.add_style_class_name('leightweight');
return false;
});
}
}
set title(title) {
_setLabel(this._title, title);
this._title.remove_style_class_name('leightweight');
this._updateTitleStyle();
this.notify('title');
}

View File

@@ -411,14 +411,18 @@ var _Draggable = class _Draggable {
this._snapBackY = this._dragStartY + this._dragOffsetY;
this._snapBackScale = this._dragActor.scale_x;
let origDragOffsetX = this._dragOffsetX;
let origDragOffsetY = this._dragOffsetY;
let [transX, transY] = this._dragActor.get_translation();
this._dragOffsetX -= transX;
this._dragOffsetY -= transY;
if (this._dragActorMaxSize != undefined) {
let [scaledWidth, scaledHeight] = this._dragActor.get_transformed_size();
let currentSize = Math.max(scaledWidth, scaledHeight);
if (currentSize > this._dragActorMaxSize) {
let scale = this._dragActorMaxSize / currentSize;
let origScale = this._dragActor.scale_x;
let origDragOffsetX = this._dragOffsetX;
let origDragOffsetY = this._dragOffsetY;
// The position of the actor changes as we scale
// around the drag position, but we can't just tween
@@ -435,8 +439,8 @@ var _Draggable = class _Draggable {
this._dragActor.get_transition('scale-x').connect('new-frame', () => {
let currentScale = this._dragActor.scale_x / origScale;
this._dragOffsetX = currentScale * origDragOffsetX;
this._dragOffsetY = currentScale * origDragOffsetY;
this._dragOffsetX = currentScale * origDragOffsetX - transX;
this._dragOffsetY = currentScale * origDragOffsetY - transY;
this._dragActor.set_position(
this._dragX + this._dragOffsetX,
this._dragY + this._dragOffsetY);

View File

@@ -299,7 +299,7 @@ class EndSessionDialog extends ModalDialog.ModalDialog {
try {
this._updatesPermission = Polkit.Permission.new_finish(res);
} catch (e) {
log(`No permission to trigger offline updates: ${e}`);
log('No permission to trigger offline updates: %s'.format(e.toString()));
}
});
}
@@ -563,7 +563,7 @@ class EndSessionDialog extends ModalDialog.ModalDialog {
if (!sessionId) {
this._loginManager.getCurrentSessionProxy(currentSessionProxy => {
sessionId = currentSessionProxy.Id;
log(`endSessionDialog: No XDG_SESSION_ID, fetched from logind: ${sessionId}`);
log('endSessionDialog: No XDG_SESSION_ID, fetched from logind: %d'.format(sessionId));
});
}

View File

@@ -111,6 +111,11 @@ function _easeActor(actor, params) {
autoReverse = params.autoReverse;
delete params.autoReverse;
// repeatCount doesn't include the initial iteration
const numIterations = repeatCount + 1;
// whether the transition should finish where it started
const isReversed = autoReverse && numIterations % 2 === 0;
if (params.mode != undefined)
actor.set_easing_mode(params.mode);
delete params.mode;
@@ -122,7 +127,8 @@ function _easeActor(actor, params) {
let animatedProps = Object.keys(params).map(p => p.replace('_', '-', 'g'));
animatedProps.forEach(p => actor.remove_transition(p));
actor.set(params);
if (actor.get_easing_duration() > 0 || !isReversed)
actor.set(params);
actor.restore_easing_state();
let transition = animatedProps.map(p => actor.get_transition(p))
@@ -161,6 +167,11 @@ function _easeActorProperty(actor, propName, target, params) {
autoReverse = params.autoReverse;
delete params.autoReverse;
// repeatCount doesn't include the initial iteration
const numIterations = repeatCount + 1;
// whether the transition should finish where it started
const isReversed = autoReverse && numIterations % 2 === 0;
// Copy Clutter's behavior for implicit animations, see
// should_skip_implicit_transition()
if (actor instanceof Clutter.Actor && !actor.mapped)
@@ -174,7 +185,9 @@ function _easeActorProperty(actor, propName, target, params) {
if (duration == 0) {
let [obj, prop] = _getPropertyTarget(actor, propName);
obj[prop] = target;
if (!isReversed)
obj[prop] = target;
Meta.disable_unredirect_for_display(global.display);
callback(true);

View File

@@ -10,10 +10,9 @@ const FileUtils = imports.misc.fileUtils;
const Main = imports.ui.main;
const ModalDialog = imports.ui.modalDialog;
var REPOSITORY_URL_BASE = 'https://extensions.gnome.org';
var REPOSITORY_URL_DOWNLOAD = `${REPOSITORY_URL_BASE}/download-extension/%s.shell-extension.zip`;
var REPOSITORY_URL_INFO = `${REPOSITORY_URL_BASE}/extension-info/`;
var REPOSITORY_URL_UPDATE = `${REPOSITORY_URL_BASE}/update-info/`;
var REPOSITORY_URL_DOWNLOAD = 'https://extensions.gnome.org/download-extension/%s.shell-extension.zip';
var REPOSITORY_URL_INFO = 'https://extensions.gnome.org/extension-info/';
var REPOSITORY_URL_UPDATE = 'https://extensions.gnome.org/update-info/';
let _httpSession;
@@ -25,7 +24,7 @@ function installExtension(uuid, invocation) {
_httpSession.queue_message(message, () => {
if (message.status_code != Soup.KnownStatusCode.OK) {
Main.extensionManager.logExtensionError(uuid, `downloading info: ${message.status_code}`);
Main.extensionManager.logExtensionError(uuid, 'downloading info: %d'.format(message.status_code));
invocation.return_dbus_error('org.gnome.Shell.DownloadInfoError', message.status_code.toString());
return;
}
@@ -34,7 +33,7 @@ function installExtension(uuid, invocation) {
try {
info = JSON.parse(message.response_body.data);
} catch (e) {
Main.extensionManager.logExtensionError(uuid, `parsing info: ${e}`);
Main.extensionManager.logExtensionError(uuid, 'parsing info: %s'.format(e.toString()));
invocation.return_dbus_error('org.gnome.Shell.ParseInfoError', e.toString());
return;
}
@@ -112,7 +111,7 @@ function downloadExtensionUpdate(uuid) {
gotExtensionZipFile(session, message, uuid, dir, () => {
Main.extensionManager.notifyExtensionUpdate(uuid);
}, (code, msg) => {
log(`Error while downloading update for extension ${uuid}: ${code} (${msg})`);
log('Error while downloading update for extension %s: %s (%s)'.format(uuid, code, msg));
});
});
}
@@ -133,7 +132,7 @@ function checkForUpdates() {
let params = {
shell_version: Config.PACKAGE_VERSION,
installed: JSON.stringify(metadatas),
disable_version_validation: `${versionCheck}`,
disable_version_validation: versionCheck.toString(),
};
let url = REPOSITORY_URL_UPDATE;
@@ -195,8 +194,8 @@ class InstallExtensionDialog extends ModalDialog.ModalDialog {
let dir = Gio.File.new_for_path(GLib.build_filenamev([global.userdatadir, 'extensions', uuid]));
let invocation = this._invocation;
function errback(code, msg) {
log(`Error while installing ${uuid}: ${code} (${msg})`);
invocation.return_dbus_error(`org.gnome.Shell.${code}`, msg || '');
log('Error while installing %s: %s (%s)'.format(uuid, code, msg));
invocation.return_dbus_error('org.gnome.Shell.%s'.format(code), msg || '');
}
function callback() {
@@ -204,7 +203,7 @@ class InstallExtensionDialog extends ModalDialog.ModalDialog {
let extension = Main.extensionManager.createExtensionObject(uuid, dir, ExtensionUtils.ExtensionType.PER_USER);
Main.extensionManager.loadExtension(extension);
if (!Main.extensionManager.enableExtension(uuid))
throw new Error(`Cannot add ${uuid} to enabled extensions gsettings key`);
throw new Error('Cannot add %s to enabled extensions gsettings key'.format(uuid));
} catch (e) {
uninstallExtension(uuid);
errback('LoadExtensionError', e);

View File

@@ -1,12 +1,14 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
/* exported init connect disconnect */
const { GLib, Gio, St } = imports.gi;
const { GLib, Gio, GObject, Shell, St } = imports.gi;
const Signals = imports.signals;
const ExtensionDownloader = imports.ui.extensionDownloader;
const ExtensionUtils = imports.misc.extensionUtils;
const FileUtils = imports.misc.fileUtils;
const Main = imports.ui.main;
const MessageTray = imports.ui.messageTray;
const { ExtensionState, ExtensionType } = ExtensionUtils;
@@ -15,10 +17,13 @@ const DISABLED_EXTENSIONS_KEY = 'disabled-extensions';
const DISABLE_USER_EXTENSIONS_KEY = 'disable-user-extensions';
const EXTENSION_DISABLE_VERSION_CHECK_KEY = 'disable-extension-version-validation';
const UPDATE_CHECK_TIMEOUT = 24 * 60 * 60; // 1 day in seconds
var ExtensionManager = class {
constructor() {
this._initialized = false;
this._enabled = false;
this._updateNotified = false;
this._extensions = new Map();
this._enabledExtensions = [];
@@ -37,7 +42,7 @@ var ExtensionManager = class {
try {
disableFile.create(Gio.FileCreateFlags.REPLACE_DESTINATION, null);
} catch (e) {
log(`Failed to create file ${disableFilename}: ${e.message}`);
log('Failed to create file %s: %s'.format(disableFilename, e.message));
}
GLib.timeout_add_seconds(GLib.PRIORITY_DEFAULT, 60, () => {
@@ -47,6 +52,12 @@ var ExtensionManager = class {
this._installExtensionUpdates();
this._sessionUpdated();
GLib.timeout_add_seconds(GLib.PRIORITY_DEFAULT, UPDATE_CHECK_TIMEOUT, () => {
ExtensionDownloader.checkForUpdates();
return GLib.SOURCE_CONTINUE;
});
ExtensionDownloader.checkForUpdates();
}
lookup(uuid) {
@@ -129,7 +140,7 @@ var ExtensionManager = class {
if (extension.state != ExtensionState.DISABLED)
return;
let stylesheetNames = [`${global.session_mode}.css`, 'stylesheet.css'];
let stylesheetNames = ['%s.css'.format(global.session_mode), 'stylesheet.css'];
let theme = St.ThemeContext.get_for_stage(global.stage).get_theme();
for (let i = 0; i < stylesheetNames.length; i++) {
try {
@@ -206,6 +217,18 @@ var ExtensionManager = class {
extension.hasUpdate = true;
this.emit('extension-state-changed', extension);
if (!this._updateNotified) {
this._updateNotified = true;
let source = new ExtensionUpdateSource();
Main.messageTray.add(source);
let notification = new MessageTray.Notification(source,
_('Extension Updates Available'),
_('Extension updates are ready to be installed.'));
source.showNotification(notification);
}
}
logExtensionError(uuid, error) {
@@ -213,7 +236,7 @@ var ExtensionManager = class {
if (!extension)
return;
let message = `${error}`;
let message = error.toString();
extension.error = message;
extension.state = ExtensionState.ERROR;
@@ -221,7 +244,7 @@ var ExtensionManager = class {
extension.errors = [];
extension.errors.push(message);
logError(error, `Extension ${uuid}`);
logError(error, 'Extension %s'.format(uuid));
this.emit('extension-state-changed', extension);
}
@@ -236,24 +259,24 @@ var ExtensionManager = class {
if (metadataContents instanceof Uint8Array)
metadataContents = imports.byteArray.toString(metadataContents);
} catch (e) {
throw new Error(`Failed to load metadata.json: ${e}`);
throw new Error('Failed to load metadata.json: %s'.format(e.toString()));
}
let meta;
try {
meta = JSON.parse(metadataContents);
} catch (e) {
throw new Error(`Failed to parse metadata.json: ${e}`);
throw new Error('Failed to parse metadata.json: %s'.format(e.toString()));
}
let requiredProperties = ['uuid', 'name', 'description', 'shell-version'];
for (let i = 0; i < requiredProperties.length; i++) {
let prop = requiredProperties[i];
if (!meta[prop])
throw new Error(`missing "${prop}" property in metadata.json`);
throw new Error('missing "%s" property in metadata.json'.format(prop));
}
if (uuid != meta.uuid)
throw new Error(`uuid "${meta.uuid}" from metadata.json does not match directory name "${uuid}"`);
throw new Error('uuid "%s" from metadata.json does not match directory name "%s"'.format(meta.uuid, uuid));
let extension = {
metadata: meta,
@@ -473,17 +496,17 @@ var ExtensionManager = class {
}
_loadExtensions() {
global.settings.connect(`changed::${ENABLED_EXTENSIONS_KEY}`,
global.settings.connect('changed::%s'.format(ENABLED_EXTENSIONS_KEY),
this._onEnabledExtensionsChanged.bind(this));
global.settings.connect(`changed::${DISABLED_EXTENSIONS_KEY}`,
global.settings.connect('changed::%s'.format(DISABLED_EXTENSIONS_KEY),
this._onEnabledExtensionsChanged.bind(this));
global.settings.connect(`changed::${DISABLE_USER_EXTENSIONS_KEY}`,
global.settings.connect('changed::%s'.format(DISABLE_USER_EXTENSIONS_KEY),
this._onUserExtensionsEnabledChanged.bind(this));
global.settings.connect(`changed::${EXTENSION_DISABLE_VERSION_CHECK_KEY}`,
global.settings.connect('changed::%s'.format(EXTENSION_DISABLE_VERSION_CHECK_KEY),
this._onVersionValidationChanged.bind(this));
global.settings.connect(`writable-changed::${ENABLED_EXTENSIONS_KEY}`,
global.settings.connect('writable-changed::%s'.format(ENABLED_EXTENSIONS_KEY),
this._onSettingsWritableChanged.bind(this));
global.settings.connect(`writable-changed::${DISABLED_EXTENSIONS_KEY}`,
global.settings.connect('writable-changed::%s'.format(DISABLED_EXTENSIONS_KEY),
this._onSettingsWritableChanged.bind(this));
this._enabledExtensions = this._getEnabledExtensions();
@@ -496,7 +519,7 @@ var ExtensionManager = class {
let uuid = info.get_name();
let existing = this.lookup(uuid);
if (existing) {
log(`Extension ${uuid} already installed in ${existing.path}. ${dir.get_path()} will not be loaded`);
log('Extension %s already installed in %s. %s will not be loaded'.format(uuid, existing.path, dir.get_path()));
return;
}
@@ -507,7 +530,7 @@ var ExtensionManager = class {
try {
extension = this.createExtensionObject(uuid, dir, type);
} catch (e) {
logError(e, `Could not load extension ${uuid}`);
logError(e, 'Could not load extension %s'.format(uuid));
return;
}
this.loadExtension(extension);
@@ -557,3 +580,27 @@ var ExtensionManager = class {
}
};
Signals.addSignalMethods(ExtensionManager.prototype);
const ExtensionUpdateSource = GObject.registerClass(
class ExtensionUpdateSource extends MessageTray.Source {
_init() {
let appSys = Shell.AppSystem.get_default();
this._app = appSys.lookup_app('org.gnome.Extensions.desktop');
super._init(this._app.get_name());
}
getIcon() {
return this._app.app_info.get_icon();
}
_createPolicy() {
return new MessageTray.NotificationApplicationPolicy(this._app.id);
}
open() {
this._app.activate();
Main.overview.hide();
Main.panel.closeCalendar();
}
});

View File

@@ -195,7 +195,7 @@ function zoomOutActorAtPos(actor, x, y) {
}
function animateIconPosition(icon, box, flags, nChangedIcons) {
if (!icon.has_allocation() || icon.allocation.equal(box)) {
if (!icon.has_allocation() || icon.allocation.equal(box) || icon.opacity === 0) {
icon.allocate(box, flags);
return false;
}
@@ -556,15 +556,25 @@ var IconGrid = GObject.registerClass({
}, Infinity);
let normalization = maxDist - minDist;
for (let index = 0; index < actors.length; index++) {
let actor = actors[index];
actors.forEach(actor => {
let clone = new Clutter.Clone({ source: actor });
this._clonesAnimating.push(clone);
Main.uiGroup.add_actor(clone);
});
/*
* ^
* | These need to be separate loops because Main.uiGroup.add_actor
* | is excessively slow if done inside the below loop and we want the
* | below loop to complete within one frame interval (#2065, !1002).
* v
*/
this._clonesAnimating.forEach(actorClone => {
let actor = actorClone.source;
actor.opacity = 0;
actor.reactive = false;
let actorClone = new Clutter.Clone({ source: actor });
this._clonesAnimating.push(actorClone);
Main.uiGroup.add_actor(actorClone);
let [width, height] = this._getAllocatedChildSizeAndSpacing(actor);
actorClone.set_size(width, height);
let scaleX = sourceScaledWidth / width;
@@ -631,7 +641,7 @@ var IconGrid = GObject.registerClass({
actorClone.ease(movementParams);
actorClone.ease(fadeParams);
}
});
}
_getAllocatedChildSizeAndSpacing(child) {

View File

@@ -24,29 +24,29 @@ const SHOW_KEYBOARD = 'screen-keyboard-enabled';
const KEY_SIZE = 2;
const defaultKeysPre = [
[[], [], [{ width: 1.5, level: 1, extraClassName: 'shift-key-lowercase' }], [{ label: '?123', width: 1.5, level: 2 }]],
[[], [], [{ width: 1.5, level: 0, extraClassName: 'shift-key-uppercase' }], [{ label: '?123', width: 1.5, level: 2 }]],
[[], [], [{ width: 1.5, level: 1, extraClassName: 'shift-key-lowercase', icon: 'keyboard-shift-filled-symbolic' }], [{ label: '?123', width: 1.5, level: 2 }]],
[[], [], [{ width: 1.5, level: 0, extraClassName: 'shift-key-uppercase', icon: 'keyboard-shift-filled-symbolic' }], [{ label: '?123', width: 1.5, level: 2 }]],
[[], [], [{ label: '=/<', width: 1.5, level: 3 }], [{ label: 'ABC', width: 1.5, level: 0 }]],
[[], [], [{ label: '?123', width: 1.5, level: 2 }], [{ label: 'ABC', width: 1.5, level: 0 }]],
];
const defaultKeysPost = [
[[{ label: '⌫', width: 1.5, keyval: Clutter.KEY_BackSpace }],
[{ width: 2, keyval: Clutter.KEY_Return, extraClassName: 'enter-key' }],
[{ width: 3, level: 1, right: true, extraClassName: 'shift-key-lowercase' }],
[{ label: '', action: 'emoji' }, { action: 'languageMenu', extraClassName: 'layout-key' }, { action: 'hide', extraClassName: 'hide-key' }]],
[[{ label: '⌫', width: 1.5, keyval: Clutter.KEY_BackSpace }],
[{ width: 2, keyval: Clutter.KEY_Return, extraClassName: 'enter-key' }],
[{ width: 3, level: 0, right: true, extraClassName: 'shift-key-uppercase' }],
[{ label: '', action: 'emoji' }, { action: 'languageMenu', extraClassName: 'layout-key' }, { action: 'hide', extraClassName: 'hide-key' }]],
[[{ label: '⌫', width: 1.5, keyval: Clutter.KEY_BackSpace }],
[{ width: 2, keyval: Clutter.KEY_Return, extraClassName: 'enter-key' }],
[[{ width: 1.5, keyval: Clutter.KEY_BackSpace, icon: 'edit-clear-symbolic' }],
[{ width: 2, keyval: Clutter.KEY_Return, extraClassName: 'enter-key', icon: 'keyboard-enter-symbolic' }],
[{ width: 3, level: 1, right: true, extraClassName: 'shift-key-lowercase', icon: 'keyboard-shift-filled-symbolic' }],
[{ action: 'emoji', icon: 'face-smile-symbolic' }, { action: 'languageMenu', extraClassName: 'layout-key', icon: 'keyboard-layout-filled-symbolic' }, { action: 'hide', extraClassName: 'hide-key', icon: 'go-down-symbolic' }]],
[[{ width: 1.5, keyval: Clutter.KEY_BackSpace, icon: 'edit-clear-symbolic' }],
[{ width: 2, keyval: Clutter.KEY_Return, extraClassName: 'enter-key', icon: 'keyboard-enter-symbolic' }],
[{ width: 3, level: 0, right: true, extraClassName: 'shift-key-uppercase', icon: 'keyboard-shift-filled-symbolic' }],
[{ action: 'emoji', icon: 'face-smile-symbolic' }, { action: 'languageMenu', extraClassName: 'layout-key', icon: 'keyboard-layout-filled-symbolic' }, { action: 'hide', extraClassName: 'hide-key', icon: 'go-down-symbolic' }]],
[[{ width: 1.5, keyval: Clutter.KEY_BackSpace, icon: 'edit-clear-symbolic' }],
[{ width: 2, keyval: Clutter.KEY_Return, extraClassName: 'enter-key', icon: 'keyboard-enter-symbolic' }],
[{ label: '=/<', width: 3, level: 3, right: true }],
[{ label: '', action: 'emoji' }, { action: 'languageMenu', extraClassName: 'layout-key' }, { action: 'hide', extraClassName: 'hide-key' }]],
[[{ label: '⌫', width: 1.5, keyval: Clutter.KEY_BackSpace }],
[{ width: 2, keyval: Clutter.KEY_Return, extraClassName: 'enter-key' }],
[{ action: 'emoji', icon: 'face-smile-symbolic' }, { action: 'languageMenu', extraClassName: 'layout-key' }, { action: 'hide', extraClassName: 'hide-key' }]],
[[{ width: 1.5, keyval: Clutter.KEY_BackSpace, icon: 'edit-clear-symbolic' }],
[{ width: 2, keyval: Clutter.KEY_Return, extraClassName: 'enter-key', icon: 'keyboard-enter-symbolic' }],
[{ label: '?123', width: 3, level: 2, right: true }],
[{ label: '', action: 'emoji' }, { action: 'languageMenu', extraClassName: 'layout-key' }, { action: 'hide', extraClassName: 'hide-key' }]],
[{ action: 'emoji', icon: 'face-smile-symbolic' }, { action: 'languageMenu', extraClassName: 'layout-key', icon: 'keyboard-layout-filled-symbolic' }, { action: 'hide', extraClassName: 'hide-key', icon: 'go-down-symbolic' }]],
];
var AspectContainer = GObject.registerClass(
@@ -257,11 +257,11 @@ var Key = GObject.registerClass({
'released': { param_types: [GObject.TYPE_UINT, GObject.TYPE_STRING] },
},
}, class Key extends St.BoxLayout {
_init(key, extendedKeys) {
_init(key, extendedKeys, icon = null) {
super._init({ style_class: 'key-container' });
this.key = key || "";
this.keyButton = this._makeKey(this.key);
this.keyButton = this._makeKey(this.key, icon);
/* Add the key in a container, so keys can be padded without losing
* logical proportions between those.
@@ -404,14 +404,21 @@ var Key = GObject.registerClass({
this._capturedPress = false;
}
_makeKey(key) {
let label = GLib.markup_escape_text(key, -1);
_makeKey(key, icon) {
let button = new St.Button({
label,
style_class: 'keyboard-key',
x_expand: true,
});
if (icon) {
let child = new St.Icon({ icon_name: icon });
button.set_child(child);
this._icon = child;
} else {
let label = GLib.markup_escape_text(key, -1);
button.set_label(label);
}
button.keyWidth = 1;
button.connect('button-press-event', () => {
this._press(key);
@@ -475,10 +482,16 @@ var Key = GObject.registerClass({
}
setLatched(latched) {
if (latched)
if (!this._icon)
return;
if (latched) {
this.keyButton.add_style_pseudo_class('latched');
else
this._icon.icon_name = 'keyboard-caps-lock-filled-symbolic';
} else {
this.keyButton.remove_style_pseudo_class('latched');
this._icon.icon_name = 'keyboard-shift-filled-symbolic';
}
}
});
@@ -1022,7 +1035,7 @@ var EmojiSelection = GObject.registerClass({
section.button = key;
}
key = new Key(null, []);
key = new Key(null, [], 'go-down-symbolic');
key.keyButton.add_style_class_name('default-key');
key.keyButton.add_style_class_name('hide-key');
key.connect('released', () => {
@@ -1102,6 +1115,9 @@ var KeyboardManager = class KeyBoardManager {
this._a11yApplicationsSettings = new Gio.Settings({ schema_id: A11Y_APPLICATIONS_SCHEMA });
this._a11yApplicationsSettings.connect('changed', this._syncEnabled.bind(this));
this._seat = Clutter.get_default_backend().get_default_seat();
this._seat.connect('notify::touch-mode', this._syncEnabled.bind(this));
this._lastDevice = null;
Meta.get_backend().connect('last-device-changed', (backend, device) => {
if (device.get_device_name().indexOf('XTEST') < 0) {
@@ -1122,7 +1138,9 @@ var KeyboardManager = class KeyBoardManager {
_syncEnabled() {
let enableKeyboard = this._a11yApplicationsSettings.get_boolean(SHOW_KEYBOARD);
let enabled = enableKeyboard || this._lastDeviceIsTouchscreen();
let autoEnabled = this._seat.get_touch_mode() && this._lastDeviceIsTouchscreen();
let enabled = enableKeyboard || autoEnabled;
if (!enabled && !this._keyboard)
return;
@@ -1250,11 +1268,7 @@ class Keyboard extends St.BoxLayout {
this._clearShowIdle();
this._keyboardController = null;
this._suggestions = null;
this._aspectContainer = null;
this._emojiSelection = null;
this._keypad = null;
this._keyboardController.destroy();
Main.layoutManager.untrackChrome(this);
Main.layoutManager.keyboardBox.remove_actor(this);
@@ -1434,12 +1448,13 @@ class Keyboard extends St.BoxLayout {
let keyval = key.keyval;
let switchToLevel = key.level;
let action = key.action;
let icon = key.icon;
/* Skip emoji button if necessary */
if (!this._emojiKeyVisible && action == 'emoji')
continue;
extraButton = new Key(key.label || '', []);
extraButton = new Key(key.label || '', [], icon);
extraButton.keyButton.add_style_class_name('default-key');
if (key.extraClassName != null)
@@ -1839,13 +1854,20 @@ var KeyboardController = class {
this._onSourcesModified.bind(this));
this._currentSource = this._inputSourceManager.currentSource;
Main.inputMethod.connect('notify::content-purpose',
this._onContentPurposeHintsChanged.bind(this));
Main.inputMethod.connect('notify::content-hints',
this._onContentPurposeHintsChanged.bind(this));
Main.inputMethod.connect('input-panel-state', (o, state) => {
this.emit('panel-state', state);
});
this._notifyContentPurposeId = Main.inputMethod.connect(
'notify::content-purpose', this._onContentPurposeHintsChanged.bind(this));
this._notifyContentHintsId = Main.inputMethod.connect(
'notify::content-hints', this._onContentPurposeHintsChanged.bind(this));
this._notifyInputPanelStateId = Main.inputMethod.connect(
'input-panel-state', (o, state) => this.emit('panel-state', state));
}
destroy() {
this._inputSourceManager.disconnect(this._sourceChangedId);
this._inputSourceManager.disconnect(this._sourcesModifiedId);
Main.inputMethod.disconnect(this._notifyContentPurposeId);
Main.inputMethod.disconnect(this._notifyContentHintsId);
Main.inputMethod.disconnect(this._notifyInputPanelStateId);
}
_onSourcesModified() {

View File

@@ -738,7 +738,7 @@ var LayoutManager = GObject.registerClass({
showKeyboard() {
this.keyboardBox.show();
this.keyboardBox.ease({
anchor_y: this.keyboardBox.height,
translation_y: -this.keyboardBox.height,
opacity: 255,
duration: KEYBOARD_ANIMATION_TIME,
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
@@ -755,7 +755,7 @@ var LayoutManager = GObject.registerClass({
this._updateRegions();
this._keyboardHeightNotifyId = this.keyboardBox.connect('notify::height', () => {
this.keyboardBox.anchor_y = this.keyboardBox.height;
this.keyboardBox.translation_y = -this.keyboardBox.height;
});
}
@@ -765,7 +765,7 @@ var LayoutManager = GObject.registerClass({
this._keyboardHeightNotifyId = 0;
}
this.keyboardBox.ease({
anchor_y: 0,
translation_y: this.keyboardBox.height,
opacity: 0,
duration: immediate ? 0 : KEYBOARD_ANIMATION_TIME,
mode: Clutter.AnimationMode.EASE_IN_QUAD,

View File

@@ -244,7 +244,13 @@ function objectToString(o) {
// special case this since the default is way, way too verbose
return '<js function>';
} else {
return `${o}`;
if (o === undefined)
return 'undefined';
if (o === null)
return 'null';
return o.toString();
}
}
@@ -291,7 +297,7 @@ class Result extends St.BoxLayout {
this.add(cmdTxt);
let box = new St.BoxLayout({});
this.add(box);
let resultTxt = new St.Label({ text: `r(${index}) = ` });
let resultTxt = new St.Label({ text: 'r(%d) = '.format(index) });
resultTxt.clutter_text.ellipsize = Pango.EllipsizeMode.END;
box.add(resultTxt);
let objLink = new ObjLink(this._lookingGlass, o);
@@ -331,7 +337,7 @@ var WindowList = GObject.registerClass({
box.add_child(windowLink);
let propsBox = new St.BoxLayout({ vertical: true, style: 'padding-left: 6px;' });
box.add(propsBox);
propsBox.add(new St.Label({ text: `wmclass: ${metaWindow.get_wm_class()}` }));
propsBox.add(new St.Label({ text: 'wmclass: %s'.format(metaWindow.get_wm_class()) }));
let app = tracker.get_window_app(metaWindow);
if (app != null && !app.is_window_backed()) {
let icon = app.create_icon_texture(22);
@@ -424,7 +430,7 @@ class ObjInspector extends St.ScrollView {
link = new St.Label({ text: '<error>' });
}
let box = new St.BoxLayout();
box.add(new St.Label({ text: `${propName}: ` }));
box.add(new St.Label({ text: '%s: '.format(propName) }));
box.add(link);
this._container.add_actor(box);
}
@@ -641,9 +647,9 @@ var Inspector = GObject.registerClass({
this._target = target;
this._pointerTarget = target;
let position = `[inspect x: ${stageX} y: ${stageY}]`;
let position = '[inspect x: %d y: %d]'.format(stageX, stageY);
this._displayText.text = '';
this._displayText.text = `${position} ${this._target}`;
this._displayText.text = '%s %s'.format(position, this._target);
this._lookingGlass.setBorderPaintTarget(this._target);
}
@@ -846,7 +852,7 @@ class LookingGlass extends St.BoxLayout {
inspectIcon.connect('button-press-event', () => {
let inspector = new Inspector(this);
inspector.connect('target', (i, target, stageX, stageY) => {
this._pushResult(`inspect(${Math.round(stageX)}, ${Math.round(stageY)})`, target);
this._pushResult('inspect(%d, %d)'.format(Math.round(stageX), Math.round(stageY)), target);
});
inspector.connect('closed', () => {
this.show();
@@ -952,9 +958,8 @@ class LookingGlass extends St.BoxLayout {
// monospace font to be bold/oblique/etc. Could easily be added here.
let size = fontDesc.get_size() / 1024.;
let unit = fontDesc.get_size_is_absolute() ? 'px' : 'pt';
this.style = `
font-size: ${size}${unit};
font-family: "${fontDesc.get_family()}";`;
this.style = 'font-size: %d%s; font-family: "%s";'.format(
size, unit, fontDesc.get_family());
}
setBorderPaintTarget(obj) {
@@ -1035,7 +1040,7 @@ class LookingGlass extends St.BoxLayout {
this._history.addItem(command);
let lines = command.split(';');
lines.push(`return ${lines.pop()}`);
lines.push('return %s'.format(lines.pop()));
let fullCmd = commandHeader + lines.join(';');
@@ -1043,7 +1048,7 @@ class LookingGlass extends St.BoxLayout {
try {
resultObj = Function(fullCmd)();
} catch (e) {
resultObj = `<exception ${e}>`;
resultObj = '<exception %s>'.format(e.toString());
}
this._pushResult(command, resultObj);
@@ -1062,7 +1067,7 @@ class LookingGlass extends St.BoxLayout {
try {
return this._resultsArea.get_child_at_index(idx - this._offset).o;
} catch (e) {
throw new Error(`Unknown result at index ${idx}`);
throw new Error('Unknown result at index %d'.format(idx));
}
}

View File

@@ -127,6 +127,10 @@ var Magnifier = class Magnifier {
* Show the system mouse pointer.
*/
showSystemCursor() {
const seat = Clutter.get_default_backend().get_default_seat();
if (seat.is_unfocus_inhibited())
seat.uninhibit_unfocus();
this._cursorTracker.set_pointer_visible(true);
}
@@ -135,6 +139,10 @@ var Magnifier = class Magnifier {
* Hide the system mouse pointer.
*/
hideSystemCursor() {
const seat = Clutter.get_default_backend().get_default_seat();
if (!seat.is_unfocus_inhibited())
seat.inhibit_unfocus();
this._cursorTracker.set_pointer_visible(false);
}
@@ -169,7 +177,7 @@ var Magnifier = class Magnifier {
// Make sure system mouse pointer is shown when all zoom regions are
// invisible.
if (!activate)
this._cursorTracker.set_pointer_visible(true);
this.showSystemCursor();
// Notify interested parties of this change
this.emit('active-changed', activate);
@@ -430,8 +438,10 @@ var Magnifier = class Magnifier {
* lines making up the crosshairs.
*/
setCrosshairsLength(length) {
if (this._crossHairs)
this._crossHairs.setLength(length);
if (this._crossHairs) {
let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor;
this._crossHairs.setLength(length / scaleFactor);
}
}
/**
@@ -745,8 +755,7 @@ var ZoomRegion = class ZoomRegion {
this._xCaret = 0;
this._yCaret = 0;
let seat = Clutter.get_default_backend().get_default_seat();
this._pointerIdleMonitor = Meta.IdleMonitor.get_for_device(seat.get_pointer());
this._pointerIdleMonitor = Meta.IdleMonitor.get_core();
this._scrollContentsTimerId = 0;
}
@@ -798,9 +807,14 @@ var ZoomRegion = class ZoomRegion {
return;
}
[this._xFocus, this._yFocus] = [extents.x + (extents.width / 2),
extents.y + (extents.height / 2)];
this._centerFromFocusPosition();
let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor;
let [xFocus, yFocus] = [(extents.x + (extents.width / 2)) * scaleFactor,
(extents.y + (extents.height / 2)) * scaleFactor];
if (this._xFocus !== xFocus || this._yFocus !== yFocus) {
[this._xFocus, this._yFocus] = [xFocus, yFocus];
this._centerFromFocusPosition();
}
}
_updateCaret(caller, event) {
@@ -815,8 +829,13 @@ var ZoomRegion = class ZoomRegion {
return;
}
[this._xCaret, this._yCaret] = [extents.x, extents.y];
this._centerFromCaretPosition();
let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor;
let [xCaret, yCaret] = [extents.x * scaleFactor, extents.y * scaleFactor];
if (this._xCaret !== xCaret || this._yCaret !== yCaret) {
[this._xCaret, this._yCaret] = [xCaret, yCaret];
this._centerFromCaretPosition();
}
}
/**
@@ -864,7 +883,8 @@ var ZoomRegion = class ZoomRegion {
setMagFactor(xMagFactor, yMagFactor) {
this._changeROI({ xMagFactor,
yMagFactor,
redoCursorTracking: this._followingCursor });
redoCursorTracking: this._followingCursor,
animate: true });
}
/**
@@ -1122,6 +1142,13 @@ var ZoomRegion = class ZoomRegion {
return this._screenPosition;
}
_clearScrollContentsTimer() {
if (this._scrollContentsTimerId !== 0) {
GLib.source_remove(this._scrollContentsTimerId);
this._scrollContentsTimerId = 0;
}
}
/**
* scrollToMousePos:
* Set the region of interest based on the position of the system pointer.
@@ -1135,28 +1162,29 @@ var ZoomRegion = class ZoomRegion {
else
this._updateMousePosition();
this._clearScrollContentsTimer();
this._scrollContentsTimerId = GLib.timeout_add(GLib.PRIORITY_DEFAULT, POINTER_REST_TIME, () => {
this._followingCursor = false;
if (this._xDelayed !== null && this._yDelayed !== null) {
this._scrollContentsToDelayed(this._xDelayed, this._yDelayed);
this._xDelayed = null;
this._yDelayed = null;
}
return GLib.SOURCE_REMOVE;
});
// Determine whether the system mouse pointer is over this zoom region.
return this._isMouseOverRegion();
}
_clearScrollContentsTimer() {
if (this._scrollContentsTimerId != 0) {
GLib.source_remove(this._scrollContentsTimerId);
this._scrollContentsTimerId = 0;
}
}
_scrollContentsToDelayed(x, y) {
if (this._pointerIdleMonitor.get_idletime() >= POINTER_REST_TIME) {
if (this._followingCursor) {
this._xDelayed = x;
this._yDelayed = y;
} else {
this.scrollContentsTo(x, y);
return;
}
this._clearScrollContentsTimer();
this._scrollContentsTimerId = GLib.timeout_add(GLib.PRIORITY_DEFAULT, POINTER_REST_TIME, () => {
this._scrollContentsToDelayed(x, y);
return GLib.SOURCE_REMOVE;
});
}
/**
@@ -1167,11 +1195,16 @@ var ZoomRegion = class ZoomRegion {
* @param {number} y: The y-coord of the point to center on.
*/
scrollContentsTo(x, y) {
if (x < 0 || x > global.screen_width ||
y < 0 || y > global.screen_height)
return;
this._clearScrollContentsTimer();
this._followingCursor = false;
this._changeROI({ xCenter: x,
yCenter: y });
yCenter: y,
animate: true });
}
/**
@@ -1323,7 +1356,7 @@ var ZoomRegion = class ZoomRegion {
this._crossHairsActor = null;
// Contrast and brightness effects.
this._magShaderEffects = new MagShaderEffects(this._uiGroupClone);
this._magShaderEffects = new MagShaderEffects(mainGroup);
this._magShaderEffects.setColorSaturation(this._colorSaturation);
this._magShaderEffects.setInvertLightness(this._invertLightness);
this._magShaderEffects.setBrightness(this._brightness);
@@ -1380,7 +1413,8 @@ var ZoomRegion = class ZoomRegion {
yMagFactor: this._yMagFactor,
xCenter: this._xCenter,
yCenter: this._yCenter,
redoCursorTracking: false });
redoCursorTracking: false,
animate: false });
if (params.xMagFactor <= 0)
params.xMagFactor = this._xMagFactor;
@@ -1419,8 +1453,7 @@ var ZoomRegion = class ZoomRegion {
height: this._viewPortHeight }, true);
}
this._updateCloneGeometry();
this._updateMousePosition();
this._updateCloneGeometry(params.animate);
}
_isMouseOverRegion() {
@@ -1558,38 +1591,64 @@ var ZoomRegion = class ZoomRegion {
this._magView.set_position(this._viewPortX, this._viewPortY);
}
_updateCloneGeometry() {
_updateCloneGeometry(animate = false) {
if (!this.isActive())
return;
this._uiGroupClone.set_scale(this._xMagFactor, this._yMagFactor);
this._mouseActor.set_scale(this._xMagFactor, this._yMagFactor);
let [x, y] = this._screenToViewPort(0, 0);
this._uiGroupClone.set_position(Math.round(x), Math.round(y));
this._uiGroupClone.ease({
x: Math.round(x),
y: Math.round(y),
scale_x: this._xMagFactor,
scale_y: this._yMagFactor,
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
duration: animate ? 100 : 0,
});
this._updateMousePosition();
let [mouseX, mouseY] = this._getMousePosition();
this._mouseActor.ease({
x: mouseX,
y: mouseY,
scale_x: this._xMagFactor,
scale_y: this._yMagFactor,
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
duration: animate ? 100 : 0,
});
if (this._crossHairsActor) {
let [crossX, crossY] = this._getCrossHairsPosition();
this._crossHairsActor.ease({
x: crossX,
y: crossY,
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
duration: animate ? 100 : 0,
});
}
}
_updateMousePosition() {
if (!this.isActive())
return;
let [xMagMouse, yMagMouse] = this._screenToViewPort(this._magnifier.xMouse,
this._magnifier.yMouse);
xMagMouse = Math.round(xMagMouse);
yMagMouse = Math.round(yMagMouse);
let [xMagMouse, yMagMouse] = this._getMousePosition();
this._mouseActor.set_position(xMagMouse, yMagMouse);
if (this._crossHairsActor) {
let [groupWidth, groupHeight] = this._crossHairsActor.get_size();
this._crossHairsActor.set_position(xMagMouse - groupWidth / 2,
yMagMouse - groupHeight / 2);
let [crossX, crossY] = this._getCrossHairsPosition();
this._crossHairsActor.set_position(crossX, crossY);
}
}
_getMousePosition() {
let [xMagMouse, yMagMouse] = this._screenToViewPort(
this._magnifier.xMouse, this._magnifier.yMouse);
return [Math.round(xMagMouse), Math.round(yMagMouse)];
}
_getCrossHairsPosition() {
let [xMagMouse, yMagMouse] = this._getMousePosition();
let [groupWidth, groupHeight] = this._crossHairsActor.get_size();
return [xMagMouse - groupWidth / 2, yMagMouse - groupHeight / 2];
}
_monitorsChanged() {
this._background.set_size(global.screen_width, global.screen_height);
this._updateScreenPosition();
@@ -1808,12 +1867,10 @@ class Crosshairs extends Clutter.Actor {
let clipWidth = this._clipSize[0];
let clipHeight = this._clipSize[1];
// Note that clip, if present, is not centred on the cross hair
// intersection, but biased towards the top left.
let left = groupWidth / 2 - clipWidth * 0.25 - leftLength;
let right = groupWidth / 2 + clipWidth * 0.75;
let top = groupHeight / 2 - clipHeight * 0.25 - topLength - thickness / 2;
let bottom = groupHeight / 2 + clipHeight * 0.75 + thickness / 2;
let left = groupWidth / 2 - clipWidth / 2 - leftLength - thickness / 2;
let right = groupWidth / 2 + clipWidth / 2 + thickness / 2;
let top = groupHeight / 2 - clipHeight / 2 - topLength - thickness / 2;
let bottom = groupHeight / 2 + clipHeight / 2 + thickness / 2;
this._horizLeftHair.set_position(left, (groupHeight - thickness) / 2);
this._horizRightHair.set_position(right, (groupHeight - thickness) / 2);
this._vertTopHair.set_position((groupWidth - thickness) / 2, top);

View File

@@ -161,6 +161,8 @@ function _initializeUI() {
_loadOskLayouts();
_loadDefaultStylesheet();
new AnimationsSettings();
// Setup the stage hierarchy early
layoutManager = new Layout.LayoutManager();
@@ -257,7 +259,7 @@ function _initializeUI() {
if (sessionMode.currentMode != 'gdm' &&
sessionMode.currentMode != 'initial-setup') {
GLib.log_structured(LOG_DOMAIN, GLib.LogLevelFlags.LEVEL_MESSAGE, {
'MESSAGE': `GNOME Shell started at ${_startDate}`,
'MESSAGE': 'GNOME Shell started at %s'.format(_startDate),
'MESSAGE_ID': GNOMESHELL_STARTED_MESSAGE_ID,
});
}
@@ -280,7 +282,7 @@ function _initializeUI() {
let perfModuleName = GLib.getenv("SHELL_PERF_MODULE");
if (perfModuleName) {
let perfOutput = GLib.getenv("SHELL_PERF_OUTPUT");
let module = eval(`imports.perf.${perfModuleName};`);
let module = eval('imports.perf.%s;'.format(perfModuleName));
Scripting.runPerfScript(module, perfOutput);
}
});
@@ -289,7 +291,7 @@ function _initializeUI() {
function _getStylesheet(name) {
let stylesheet;
stylesheet = Gio.File.new_for_uri(`resource:///org/gnome/shell/theme/${name}`);
stylesheet = Gio.File.new_for_uri('resource:///org/gnome/shell/theme/%s'.format(name));
if (stylesheet.query_exists(null))
return stylesheet;
@@ -301,7 +303,7 @@ function _getStylesheet(name) {
return stylesheet;
}
stylesheet = Gio.File.new_for_path(`${global.datadir}/theme/${name}`);
stylesheet = Gio.File.new_for_path('%s/theme/%s'.format(global.datadir, name));
if (stylesheet.query_exists(null))
return stylesheet;
@@ -359,12 +361,12 @@ function reloadThemeResource() {
if (_themeResource)
_themeResource._unregister();
_themeResource = Gio.Resource.load(`${global.datadir}/gnome-shell-theme.gresource`);
_themeResource = Gio.Resource.load('%s/gnome-shell-theme.gresource'.format(global.datadir));
_themeResource._register();
}
function _loadOskLayouts() {
_oskResource = Gio.Resource.load(`${global.datadir}/gnome-shell-osk-layouts.gresource`);
_oskResource = Gio.Resource.load('%s/gnome-shell-osk-layouts.gresource'.format(global.datadir));
_oskResource._register();
}
@@ -418,9 +420,9 @@ function notify(msg, details) {
function notifyError(msg, details) {
// Also print to stderr so it's logged somewhere
if (details)
log(`error: ${msg}: ${details}`);
log('error: %s: %s'.format(msg, details));
else
log(`error: ${msg}`);
log('error: %s'.format(msg));
notify(msg, details);
}
@@ -687,7 +689,7 @@ function _queueBeforeRedraw(workId) {
*/
function initializeDeferredWork(actor, callback) {
// Turn into a string so we can use as an object property
let workId = `${++_deferredWorkSequence}`;
let workId = (++_deferredWorkSequence).toString();
_deferredWorkData[workId] = { actor,
callback };
actor.connect('notify::mapped', () => {
@@ -758,3 +760,46 @@ function showRestartMessage(message) {
let restartMessage = new RestartMessage(message);
restartMessage.open();
}
var AnimationsSettings = class {
constructor() {
let backend = Meta.get_backend();
if (!backend.is_rendering_hardware_accelerated()) {
St.Settings.get().inhibit_animations();
return;
}
let isXvnc = Shell.util_has_x11_display_extension(
global.display, 'VNC-EXTENSION');
if (isXvnc) {
St.Settings.get().inhibit_animations();
return;
}
let remoteAccessController = backend.get_remote_access_controller();
if (!remoteAccessController)
return;
this._handles = new Set();
remoteAccessController.connect('new-handle',
(_, handle) => this._onNewRemoteAccessHandle(handle));
}
_onRemoteAccessHandleStopped(handle) {
let settings = St.Settings.get();
settings.uninhibit_animations();
this._handles.delete(handle);
}
_onNewRemoteAccessHandle(handle) {
if (!handle.get_disable_animations())
return;
let settings = St.Settings.get();
settings.inhibit_animations();
this._handles.add(handle);
handle.connect('stopped', this._onRemoteAccessHandleStopped.bind(this));
}
};

View File

@@ -79,7 +79,7 @@ class URLHighlighter extends St.Label {
if (urlId != -1) {
let url = this._urls[urlId].url;
if (!url.includes(':'))
url = `http://${url}`;
url = 'http://%s'.format(url);
Gio.app_info_launch_default_for_uri(
url, global.create_app_launch_context(0, -1));
@@ -132,7 +132,7 @@ class URLHighlighter extends St.Label {
for (let i = 0; i < urls.length; i++) {
let url = urls[i];
let str = this._text.substr(pos, url.pos - pos);
markup += `${str}<span foreground="${this._linkColor}"><u>${url.url}</u></span>`;
markup += '%s<span foreground="%s"><u>%s</u></span>'.format(str, this._linkColor, url.url);
pos = url.pos + url.url.length;
}
markup += this._text.substr(pos);

View File

@@ -229,15 +229,17 @@ var NotificationApplicationPolicy = GObject.registerClass({
this._canonicalId = this._canonicalizeId(id);
this._masterSettings = new Gio.Settings({ schema_id: 'org.gnome.desktop.notifications' });
this._settings = new Gio.Settings({ schema_id: 'org.gnome.desktop.notifications.application',
path: `/org/gnome/desktop/notifications/application/${this._canonicalId}/` });
this._settings = new Gio.Settings({
schema_id: 'org.gnome.desktop.notifications.application',
path: '/org/gnome/desktop/notifications/application/%s/'.format(this._canonicalId),
});
this._masterSettings.connect('changed', this._changed.bind(this));
this._settings.connect('changed', this._changed.bind(this));
}
store() {
this._settings.set_string('application-id', `${this.id}.desktop`);
this._settings.set_string('application-id', '%s.desktop'.format(this.id));
let apps = this._masterSettings.get_strv('application-children');
if (!apps.includes(this._canonicalId)) {
@@ -1077,7 +1079,7 @@ var MessageTray = GObject.registerClass({
add(source) {
if (this.contains(source)) {
log(`Trying to re-add source ${source.title}`);
log('Trying to re-add source %s'.format(source.title));
return;
}

View File

@@ -147,7 +147,7 @@ var MprisPlayer = class MprisPlayer {
// so prefer activating the app via .desktop file if possible
let app = null;
if (this._mprisProxy.DesktopEntry) {
let desktopId = `${this._mprisProxy.DesktopEntry}.desktop`;
let desktopId = '%s.desktop'.format(this._mprisProxy.DesktopEntry);
app = Shell.AppSystem.get_default().lookup_app(desktopId);
}
@@ -192,9 +192,9 @@ var MprisPlayer = class MprisPlayer {
if (!Array.isArray(this._trackArtists) ||
!this._trackArtists.every(artist => typeof artist === 'string')) {
if (typeof this._trackArtists !== 'undefined') {
log(`Received faulty track artist metadata from ${
this._busName}; expected an array of strings, got ${
this._trackArtists} (${typeof this._trackArtists})`);
log(('Received faulty track artist metadata from %s; ' +
'expected an array of strings, got %s (%s)').format(
this._busName, this._trackArtists, typeof this._trackArtists));
}
this._trackArtists = [_("Unknown artist")];
}
@@ -202,9 +202,9 @@ var MprisPlayer = class MprisPlayer {
this._trackTitle = metadata['xesam:title'];
if (typeof this._trackTitle !== 'string') {
if (typeof this._trackTitle !== 'undefined') {
log(`Received faulty track title metadata from ${
this._busName}; expected a string, got ${
this._trackTitle} (${typeof this._trackTitle})`);
log(('Received faulty track title metadata from %s; ' +
'expected a string, got %s (%s)').format(
this._busName, this._trackTitle, typeof this._trackTitle));
}
this._trackTitle = _("Unknown title");
}
@@ -212,9 +212,9 @@ var MprisPlayer = class MprisPlayer {
this._trackCoverUrl = metadata['mpris:artUrl'];
if (typeof this._trackCoverUrl !== 'string') {
if (typeof this._trackCoverUrl !== 'undefined') {
log(`Received faulty track cover art metadata from ${
this._busName}; expected a string, got ${
this._trackCoverUrl} (${typeof this._trackCoverUrl})`);
log(('Received faulty track cover art metadata from %s; ' +
'expected a string, got %s (%s)').format(
this._busName, this._trackCoverUrl, typeof this._trackCoverUrl));
}
this._trackCoverUrl = '';
}

View File

@@ -477,7 +477,7 @@ class FdoNotificationDaemonSource extends MessageTray.Source {
return app;
if (appId) {
app = Shell.AppSystem.get_default().lookup_app(`${appId}.desktop`);
app = Shell.AppSystem.get_default().lookup_app('%s.desktop'.format(appId));
if (app != null)
return app;
}
@@ -614,7 +614,7 @@ function objectPathFromAppId(appId) {
}
function getPlatformData() {
let startupId = GLib.Variant.new('s', `_TIME${global.get_current_time()}`);
let startupId = GLib.Variant.new('s', '_TIME%s'.format(global.get_current_time()));
return { "desktop-startup-id": startupId };
}
@@ -627,7 +627,7 @@ class GtkNotificationDaemonAppSource extends MessageTray.Source {
if (!GLib.Variant.is_object_path(objectPath))
throw new InvalidAppError();
let app = Shell.AppSystem.get_default().lookup_app(`${appId}.desktop`);
let app = Shell.AppSystem.get_default().lookup_app('%s.desktop'.format(appId));
if (!app)
throw new InvalidAppError();

View File

@@ -104,7 +104,7 @@ class OverviewActor extends St.BoxLayout {
in the search entry when no search is
active; it should not exceed ~30
characters. */
hint_text: _("Type to search…"),
hint_text: _('Type to search'),
track_hover: true,
can_focus: true,
});
@@ -137,6 +137,7 @@ class OverviewActor extends St.BoxLayout {
var Overview = class {
constructor() {
this._initCalled = false;
this._visible = false;
Main.sessionMode.connect('updated', this._sessionUpdated.bind(this));
this._sessionUpdated();
@@ -269,7 +270,11 @@ var Overview = class {
}
_sessionUpdated() {
this.isDummy = !Main.sessionMode.hasOverview;
const { hasOverview } = Main.sessionMode;
if (!hasOverview)
this.hide();
this.isDummy = !hasOverview;
this._createOverview();
}

View File

@@ -127,7 +127,7 @@ class SlidingControl extends St.Widget {
}
_getSlide() {
throw new GObject.NotImplementedError(`_getSlide in ${this.constructor.name}`);
throw new GObject.NotImplementedError('_getSlide in %s'.format(this.constructor.name));
}
_updateSlide() {

View File

@@ -347,9 +347,7 @@ var PadDiagram = GObject.registerClass({
return '<?xml version="1.0" encoding="UTF-8" standalone="no"?>' +
'<svg version="1.1" xmlns="http://www.w3.org/2000/svg" ' +
'xmlns:xi="http://www.w3.org/2001/XInclude" ' +
`width="${ // " (give xgettext the paired quotes it expects)
this._imageWidth
}" height="${this._imageHeight}"> ` + // "
'width="%d" height="%d">'.format(this._imageWidth, this._imageHeight) +
'<style type="text/css">';
}
@@ -364,10 +362,10 @@ var PadDiagram = GObject.registerClass({
for (let i = 0; i < this._activeButtons.length; i++) {
let ch = String.fromCharCode('A'.charCodeAt() + this._activeButtons[i]);
css += `.${ch} {
stroke: ${ACTIVE_COLOR} !important;
fill: ${ACTIVE_COLOR} !important;
}`;
css += '.%s {'.format(ch);
css += ' stroke: %s !important;'.format(ACTIVE_COLOR);
css += ' fill: %s !important;'.format(ACTIVE_COLOR);
css += '}';
}
return css;
@@ -477,12 +475,12 @@ var PadDiagram = GObject.registerClass({
let leaderPos, leaderSize, pos;
let found, direction;
[found, pos] = this._handle.get_position_sub(`#${labelName}`);
[found, pos] = this._handle.get_position_sub('#%s'.format(labelName));
if (!found)
return [false];
[found, leaderPos] = this._handle.get_position_sub(`#${leaderName}`);
[found, leaderSize] = this._handle.get_dimensions_sub(`#${leaderName}`);
[found, leaderPos] = this._handle.get_position_sub('#%s'.format(leaderName));
[found, leaderSize] = this._handle.get_dimensions_sub('#%s'.format(leaderName));
if (!found)
return [false];
@@ -504,8 +502,8 @@ var PadDiagram = GObject.registerClass({
getButtonLabelCoords(button) {
let ch = String.fromCharCode('A'.charCodeAt() + button);
let labelName = `Label${ch}`;
let leaderName = `Leader${ch}`;
let labelName = 'Label%s'.format(ch);
let leaderName = 'Leader%s'.format(ch);
return this._getItemLabelCoords(labelName, leaderName);
}
@@ -513,8 +511,8 @@ var PadDiagram = GObject.registerClass({
getRingLabelCoords(number, dir) {
let numStr = number > 0 ? (number + 1).toString() : '';
let dirStr = dir == CW ? 'CW' : 'CCW';
let labelName = `LabelRing${numStr}${dirStr}`;
let leaderName = `LeaderRing${numStr}${dirStr}`;
let labelName = 'LabelRing%s%s'.format(numStr, dirStr);
let leaderName = 'LeaderRing%s%s'.format(numStr, dirStr);
return this._getItemLabelCoords(labelName, leaderName);
}
@@ -522,8 +520,8 @@ var PadDiagram = GObject.registerClass({
getStripLabelCoords(number, dir) {
let numStr = number > 0 ? (number + 1).toString() : '';
let dirStr = dir == UP ? 'Up' : 'Down';
let labelName = `LabelStrip${numStr}${dirStr}`;
let leaderName = `LeaderStrip${numStr}${dirStr}`;
let labelName = 'LabelStrip%s%s'.format(numStr, dirStr);
let leaderName = 'LeaderStrip%s%s'.format(numStr, dirStr);
return this._getItemLabelCoords(labelName, leaderName);
}
@@ -870,7 +868,7 @@ var PadOsd = GObject.registerClass({
}
this._titleLabel.clutter_text.set_markup(
`<span size="larger"><b>${title}</b></span>`);
'<span size="larger"><b>%s</b></span>'.format(title));
}
_isEditedAction(type, number, dir) {
@@ -932,7 +930,7 @@ var PadOsd = GObject.registerClass({
_startButtonActionEdition(button) {
let ch = String.fromCharCode('A'.charCodeAt() + button);
let key = `button${ch}`;
let key = 'button%s'.format(ch);
this._startActionEdition(key, Meta.PadActionType.BUTTON, button);
}

View File

@@ -533,6 +533,9 @@ class PanelCorner extends St.DrawingArea {
if (index < 0)
return null;
if (!(children[index] instanceof St.Widget))
return null;
if (!children[index].has_style_class_name('panel-menu') &&
!children[index].has_style_class_name('panel-button'))
return this._findRightmostButton(children[index]);
@@ -558,6 +561,9 @@ class PanelCorner extends St.DrawingArea {
if (index == children.length)
return null;
if (!(children[index] instanceof St.Widget))
return null;
if (!children[index].has_style_class_name('panel-menu') &&
!children[index].has_style_class_name('panel-button'))
return this._findLeftmostButton(children[index]);
@@ -1099,7 +1105,7 @@ class Panel extends St.Widget {
addToStatusArea(role, indicator, position, box) {
if (this.statusArea[role])
throw new Error(`Extension point conflict: there is already a status indicator for role ${role}`);
throw new Error('Extension point conflict: there is already a status indicator for role %s'.format(role));
if (!(indicator instanceof PanelMenu.Button))
throw new TypeError('Status indicator must be an instance of PanelMenu.Button');

View File

@@ -282,8 +282,11 @@ class PopupMenuItem extends PopupBaseMenuItem {
var PopupSeparatorMenuItem = GObject.registerClass(
class PopupSeparatorMenuItem extends PopupBaseMenuItem {
_init(text) {
super._init({ reactive: false,
can_focus: false });
super._init({
style_class: 'popup-separator-menu-item',
reactive: false,
can_focus: false,
});
this.label = new St.Label({ text: text || '' });
this.add(this.label);
@@ -293,10 +296,12 @@ class PopupSeparatorMenuItem extends PopupBaseMenuItem {
this._syncVisibility.bind(this));
this._syncVisibility();
this._separator = new St.Widget({ style_class: 'popup-separator-menu-item',
x_expand: true,
y_expand: true,
y_align: Clutter.ActorAlign.CENTER });
this._separator = new St.Widget({
style_class: 'popup-separator-menu-item-separator',
x_expand: true,
y_expand: true,
y_align: Clutter.ActorAlign.CENTER,
});
this.add_child(this._separator);
}
@@ -457,7 +462,7 @@ class PopupImageMenuItem extends PopupBaseMenuItem {
var PopupMenuBase = class {
constructor(sourceActor, styleClass) {
if (this.constructor === PopupMenuBase)
throw new TypeError(`Cannot instantiate abstract class ${this.constructor.name}`);
throw new TypeError('Cannot instantiate abstract class %s'.format(this.constructor.name));
this.sourceActor = sourceActor;
this.focusActor = sourceActor;
@@ -541,7 +546,7 @@ var PopupMenuBase = class {
let app = Shell.AppSystem.get_default().lookup_app(desktopFile);
if (!app) {
log(`Settings panel for desktop file ${desktopFile} could not be loaded!`);
log('Settings panel for desktop file %s could not be loaded!'.format(desktopFile));
return;
}

View File

@@ -194,7 +194,7 @@ class RunDialog extends ModalDialog.ModalDialog {
if (inTerminal) {
let exec = this._terminalSettings.get_string(EXEC_KEY);
let execArg = this._terminalSettings.get_string(EXEC_ARG_KEY);
command = `${exec} ${execArg} ${input}`;
command = '%s %s %s'.format(exec, execArg, input);
}
Util.trySpawnCommandLine(command);
} catch (e) {
@@ -205,7 +205,7 @@ class RunDialog extends ModalDialog.ModalDialog {
} else {
if (input.charAt(0) == '~')
input = input.slice(1);
path = `${GLib.get_home_dir()}/${input}`;
path = '%s/%s'.format(GLib.get_home_dir(), input);
}
if (GLib.file_test(path, GLib.FileTest.EXISTS)) {

View File

@@ -1,13 +1,10 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const { AccountsService, Clutter, Gio, GLib,
GnomeDesktop, GObject, Graphene, Meta, Shell, St } = imports.gi;
const Cairo = imports.cairo;
const { AccountsService, Clutter, Gio,
GLib, Graphene, Meta, Shell, St } = imports.gi;
const Signals = imports.signals;
const Background = imports.ui.background;
const GnomeSession = imports.misc.gnomeSession;
const Layout = imports.ui.layout;
const OVirt = imports.gdm.oVirt;
const LoginManager = imports.misc.loginManager;
const Lightbox = imports.ui.lightbox;
@@ -27,17 +24,6 @@ const LOCKDOWN_SCHEMA = 'org.gnome.desktop.lockdown';
const DISABLE_LOCK_KEY = 'disable-lock-screen';
const LOCKED_STATE_STR = 'screenShield.locked';
// fraction of screen height the arrow must reach before completing
// the slide up automatically
var ARROW_DRAG_THRESHOLD = 0.1;
// Parameters for the arrow animation
var N_ARROWS = 3;
var ARROW_ANIMATION_TIME = 600;
var ARROW_ANIMATION_PEAK_OPACITY = 0.4;
var ARROW_IDLE_TIME = 30000; // ms
var SUMMARY_ICON_SIZE = 48;
// ScreenShield animation time
// - STANDARD_FADE_TIME is used when the session goes idle
@@ -48,384 +34,6 @@ var STANDARD_FADE_TIME = 10000;
var MANUAL_FADE_TIME = 300;
var CURTAIN_SLIDE_TIME = 300;
var Clock = GObject.registerClass(
class ScreenShieldClock extends St.BoxLayout {
_init() {
super._init({ style_class: 'screen-shield-clock', vertical: true });
this._time = new St.Label({
style_class: 'screen-shield-clock-time',
x_align: Clutter.ActorAlign.CENTER,
});
this._date = new St.Label({
style_class: 'screen-shield-clock-date',
x_align: Clutter.ActorAlign.CENTER,
});
this.add_child(this._time);
this.add_child(this._date);
this._wallClock = new GnomeDesktop.WallClock({ time_only: true });
this._wallClock.connect('notify::clock', this._updateClock.bind(this));
this._updateClock();
this.connect('destroy', this._onDestroy.bind(this));
}
_updateClock() {
this._time.text = this._wallClock.clock;
let date = new Date();
/* Translators: This is a time format for a date in
long format */
let dateFormat = Shell.util_translate_time_string(N_("%A, %B %d"));
this._date.text = date.toLocaleFormat(dateFormat);
}
_onDestroy() {
this._wallClock.run_dispose();
}
});
var NotificationsBox = GObject.registerClass({
Signals: { 'wake-up-screen': {} },
}, class NotificationsBox extends St.BoxLayout {
_init() {
super._init({
vertical: true,
name: 'screenShieldNotifications',
style_class: 'screen-shield-notifications-container',
});
this._scrollView = new St.ScrollView({ hscrollbar_policy: St.PolicyType.NEVER });
this._notificationBox = new St.BoxLayout({ vertical: true,
style_class: 'screen-shield-notifications-container' });
this._scrollView.add_actor(this._notificationBox);
this.add_child(this._scrollView);
this._sources = new Map();
Main.messageTray.getSources().forEach(source => {
this._sourceAdded(Main.messageTray, source, true);
});
this._updateVisibility();
this._sourceAddedId = Main.messageTray.connect('source-added', this._sourceAdded.bind(this));
this.connect('destroy', this._onDestroy.bind(this));
}
_onDestroy() {
if (this._sourceAddedId) {
Main.messageTray.disconnect(this._sourceAddedId);
this._sourceAddedId = 0;
}
let items = this._sources.entries();
for (let [source, obj] of items)
this._removeSource(source, obj);
}
_updateVisibility() {
this._notificationBox.visible =
this._notificationBox.get_children().some(a => a.visible);
this.visible = this._notificationBox.visible;
}
_makeNotificationCountText(count, isChat) {
if (isChat)
return ngettext("%d new message", "%d new messages", count).format(count);
else
return ngettext("%d new notification", "%d new notifications", count).format(count);
}
_makeNotificationSource(source, box) {
let sourceActor = new MessageTray.SourceActor(source, SUMMARY_ICON_SIZE);
box.add_child(sourceActor);
let textBox = new St.BoxLayout({ vertical: true });
box.add_child(textBox);
let title = new St.Label({ text: source.title,
style_class: 'screen-shield-notification-label' });
textBox.add(title);
let count = source.unseenCount;
let countLabel = new St.Label({ text: this._makeNotificationCountText(count, source.isChat),
style_class: 'screen-shield-notification-count-text' });
textBox.add(countLabel);
box.visible = count != 0;
return [title, countLabel];
}
_makeNotificationDetailedSource(source, box) {
let sourceActor = new MessageTray.SourceActor(source, SUMMARY_ICON_SIZE);
let sourceBin = new St.Bin({ child: sourceActor });
box.add(sourceBin);
let textBox = new St.BoxLayout({ vertical: true });
box.add_child(textBox);
let title = new St.Label({ text: source.title,
style_class: 'screen-shield-notification-label' });
textBox.add(title);
let visible = false;
for (let i = 0; i < source.notifications.length; i++) {
let n = source.notifications[i];
if (n.acknowledged)
continue;
let body = '';
if (n.bannerBodyText) {
body = n.bannerBodyMarkup
? n.bannerBodyText
: GLib.markup_escape_text(n.bannerBodyText, -1);
}
let label = new St.Label({ style_class: 'screen-shield-notification-count-text' });
label.clutter_text.set_markup(`<b>${n.title}</b> ${body}`);
textBox.add(label);
visible = true;
}
box.visible = visible;
return [title, null];
}
_shouldShowDetails(source) {
return source.policy.detailsInLockScreen ||
source.narrowestPrivacyScope == MessageTray.PrivacyScope.SYSTEM;
}
_showSource(source, obj, box) {
if (obj.detailed)
[obj.titleLabel, obj.countLabel] = this._makeNotificationDetailedSource(source, box);
else
[obj.titleLabel, obj.countLabel] = this._makeNotificationSource(source, box);
box.visible = obj.visible && (source.unseenCount > 0);
}
_sourceAdded(tray, source, initial) {
let obj = {
visible: source.policy.showInLockScreen,
detailed: this._shouldShowDetails(source),
sourceDestroyId: 0,
sourceCountChangedId: 0,
sourceTitleChangedId: 0,
sourceUpdatedId: 0,
sourceBox: null,
titleLabel: null,
countLabel: null,
};
obj.sourceBox = new St.BoxLayout({ style_class: 'screen-shield-notification-source',
x_expand: true });
this._showSource(source, obj, obj.sourceBox);
this._notificationBox.add_child(obj.sourceBox);
obj.sourceCountChangedId = source.connect('notify::count', () => {
this._countChanged(source, obj);
});
obj.sourceTitleChangedId = source.connect('notify::title', () => {
this._titleChanged(source, obj);
});
obj.policyChangedId = source.policy.connect('notify', (policy, pspec) => {
if (pspec.name == 'show-in-lock-screen')
this._visibleChanged(source, obj);
else
this._detailedChanged(source, obj);
});
obj.sourceDestroyId = source.connect('destroy', () => {
this._onSourceDestroy(source, obj);
});
this._sources.set(source, obj);
if (!initial) {
// block scrollbars while animating, if they're not needed now
let boxHeight = this._notificationBox.height;
if (this._scrollView.height >= boxHeight)
this._scrollView.vscrollbar_policy = St.PolicyType.NEVER;
let widget = obj.sourceBox;
let [, natHeight] = widget.get_preferred_height(-1);
widget.height = 0;
widget.ease({
height: natHeight,
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
duration: 250,
onComplete: () => {
this._scrollView.vscrollbar_policy = St.PolicyType.AUTOMATIC;
widget.set_height(-1);
},
});
this._updateVisibility();
if (obj.sourceBox.visible)
this.emit('wake-up-screen');
}
}
_titleChanged(source, obj) {
obj.titleLabel.text = source.title;
}
_countChanged(source, obj) {
// A change in the number of notifications may change whether we show
// details.
let newDetailed = this._shouldShowDetails(source);
let oldDetailed = obj.detailed;
obj.detailed = newDetailed;
if (obj.detailed || oldDetailed != newDetailed) {
// A new notification was pushed, or a previous notification was destroyed.
// Give up, and build the list again.
obj.sourceBox.destroy_all_children();
obj.titleLabel = obj.countLabel = null;
this._showSource(source, obj, obj.sourceBox);
} else {
let count = source.unseenCount;
obj.countLabel.text = this._makeNotificationCountText(count, source.isChat);
}
obj.sourceBox.visible = obj.visible && (source.unseenCount > 0);
this._updateVisibility();
if (obj.sourceBox.visible)
this.emit('wake-up-screen');
}
_visibleChanged(source, obj) {
if (obj.visible == source.policy.showInLockScreen)
return;
obj.visible = source.policy.showInLockScreen;
obj.sourceBox.visible = obj.visible && source.unseenCount > 0;
this._updateVisibility();
if (obj.sourceBox.visible)
this.emit('wake-up-screen');
}
_detailedChanged(source, obj) {
let newDetailed = this._shouldShowDetails(source);
if (obj.detailed == newDetailed)
return;
obj.detailed = newDetailed;
obj.sourceBox.destroy_all_children();
obj.titleLabel = obj.countLabel = null;
this._showSource(source, obj, obj.sourceBox);
}
_onSourceDestroy(source, obj) {
this._removeSource(source, obj);
this._updateVisibility();
}
_removeSource(source, obj) {
obj.sourceBox.destroy();
obj.sourceBox = obj.titleLabel = obj.countLabel = null;
source.disconnect(obj.sourceDestroyId);
source.disconnect(obj.sourceCountChangedId);
source.disconnect(obj.sourceTitleChangedId);
source.policy.disconnect(obj.policyChangedId);
this._sources.delete(source);
}
});
var Arrow = GObject.registerClass(
class ScreenShieldArrow extends St.Bin {
_init(params) {
super._init(params);
this._drawingArea = new St.DrawingArea({
x_expand: true,
y_expand: true,
});
this._drawingArea.connect('repaint', this._drawArrow.bind(this));
this.child = this._drawingArea;
this._shadowHelper = null;
this._shadowWidth = this._shadowHeight = 0;
}
_drawArrow(arrow) {
let cr = arrow.get_context();
let [w, h] = arrow.get_surface_size();
let node = this.get_theme_node();
let thickness = node.get_length('-arrow-thickness');
Clutter.cairo_set_source_color(cr, node.get_foreground_color());
cr.setLineCap(Cairo.LineCap.ROUND);
cr.setLineWidth(thickness);
cr.moveTo(thickness / 2, h - thickness / 2);
cr.lineTo(w / 2, thickness);
cr.lineTo(w - thickness / 2, h - thickness / 2);
cr.stroke();
cr.$dispose();
}
vfunc_get_paint_volume(volume) {
if (!super.vfunc_get_paint_volume(volume))
return false;
if (!this._shadow)
return true;
let shadowBox = new Clutter.ActorBox();
this._shadow.get_box(this._drawingArea.get_allocation_box(), shadowBox);
volume.set_width(Math.max(shadowBox.x2 - shadowBox.x1, volume.get_width()));
volume.set_height(Math.max(shadowBox.y2 - shadowBox.y1, volume.get_height()));
return true;
}
vfunc_style_changed() {
let node = this.get_theme_node();
this._shadow = node.get_shadow('-arrow-shadow');
if (this._shadow)
this._shadowHelper = St.ShadowHelper.new(this._shadow);
else
this._shadowHelper = null;
super.vfunc_style_changed();
}
vfunc_paint(paintContext) {
if (this._shadowHelper) {
this._shadowHelper.update(this._drawingArea);
let allocation = this._drawingArea.get_allocation_box();
let paintOpacity = this._drawingArea.get_paint_opacity();
let framebuffer = paintContext.get_framebuffer();
this._shadowHelper.paint(framebuffer, allocation, paintOpacity);
}
this._drawingArea.paint(paintContext);
}
});
function clamp(value, min, max) {
return Math.max(min, Math.min(max, value));
}
/**
* If you are setting org.gnome.desktop.session.idle-delay directly in dconf,
* rather than through System Settings, you also need to set
@@ -447,59 +55,18 @@ var ScreenShield = class {
name: 'lockScreenGroup',
visible: false,
});
this._lockScreenGroup.connect('key-press-event',
this._onLockScreenKeyPress.bind(this));
this._lockScreenGroup.connect('scroll-event',
this._onLockScreenScroll.bind(this));
Main.ctrlAltTabManager.addGroup(this._lockScreenGroup, _("Lock"), 'changes-prevent-symbolic');
this._lockScreenContents = new St.Widget({ layout_manager: new Clutter.BinLayout(),
name: 'lockScreenContents' });
this._lockScreenContents.add_constraint(new Layout.MonitorConstraint({ primary: true }));
this._lockDialogGroup = new St.Widget({
x_expand: true,
y_expand: true,
reactive: true,
can_focus: true,
pivot_point: new Graphene.Point({ x: 0.5, y: 0.5 }),
name: 'lockDialogGroup',
});
this._lockScreenGroup.add_actor(this._lockScreenContents);
this._backgroundGroup = new Clutter.Actor();
this._lockScreenGroup.add_actor(this._backgroundGroup);
this._lockScreenGroup.set_child_below_sibling(this._backgroundGroup, null);
this._bgManagers = [];
this._updateBackgrounds();
Main.layoutManager.connect('monitors-changed', this._updateBackgrounds.bind(this));
this._arrowAnimationId = 0;
this._arrowWatchId = 0;
this._arrowActiveWatchId = 0;
this._arrowContainer = new St.BoxLayout({ style_class: 'screen-shield-arrows',
vertical: true,
x_align: Clutter.ActorAlign.CENTER,
y_align: Clutter.ActorAlign.END,
// HACK: without these, ClutterBinLayout
// ignores alignment properties on the actor
x_expand: true,
y_expand: true });
for (let i = 0; i < N_ARROWS; i++) {
let arrow = new Arrow({ opacity: 0 });
this._arrowContainer.add_actor(arrow);
}
this._lockScreenContents.add_actor(this._arrowContainer);
this._dragAction = new Clutter.GestureAction();
this._dragAction.connect('gesture-begin', this._onDragBegin.bind(this));
this._dragAction.connect('gesture-progress', this._onDragMotion.bind(this));
this._dragAction.connect('gesture-end', this._onDragEnd.bind(this));
this._lockScreenGroup.add_action(this._dragAction);
this._lockDialogGroup = new St.Widget({ x_expand: true,
y_expand: true,
reactive: true,
pivot_point: new Graphene.Point({ x: 0.5, y: 0.5 }),
name: 'lockDialogGroup' });
this.actor.add_actor(this._lockDialogGroup);
this.actor.add_actor(this._lockScreenGroup);
this.actor.add_actor(this._lockDialogGroup);
this._presence = new GnomeSession.Presence((proxy, error) => {
if (error) {
@@ -519,14 +86,14 @@ var ScreenShield = class {
this._smartcardManager.connect('smartcard-inserted',
(manager, token) => {
if (this._isLocked && token.UsedToLogin)
this._liftShield(true, 0);
this._activateDialog();
});
this._oVirtCredentialsManager = OVirt.getOVirtCredentialsManager();
this._oVirtCredentialsManager.connect('user-authenticated',
() => {
if (this._isLocked)
this._liftShield(true, 0);
this._activateDialog();
});
this._loginManager = LoginManager.getLoginManager();
@@ -545,13 +112,12 @@ var ScreenShield = class {
});
this._settings = new Gio.Settings({ schema_id: SCREENSAVER_SCHEMA });
this._settings.connect(`changed::${LOCK_ENABLED_KEY}`, this._syncInhibitor.bind(this));
this._settings.connect('changed::%s'.format(LOCK_ENABLED_KEY), this._syncInhibitor.bind(this));
this._lockSettings = new Gio.Settings({ schema_id: LOCKDOWN_SCHEMA });
this._lockSettings.connect(`changed::${DISABLE_LOCK_KEY}`, this._syncInhibitor.bind(this));
this._lockSettings.connect('changed::%s'.format(DISABLE_LOCK_KEY), this._syncInhibitor.bind(this));
this._isModal = false;
this._hasLockScreen = false;
this._isGreeter = false;
this._isActive = false;
this._isLocked = false;
@@ -591,39 +157,10 @@ var ScreenShield = class {
this._syncInhibitor();
}
_createBackground(monitorIndex) {
let monitor = Main.layoutManager.monitors[monitorIndex];
let widget = new St.Widget({ style_class: 'screen-shield-background',
x: monitor.x,
y: monitor.y,
width: monitor.width,
height: monitor.height });
let bgManager = new Background.BackgroundManager({ container: widget,
monitorIndex,
controlPosition: false,
settingsSchema: SCREENSAVER_SCHEMA });
this._bgManagers.push(bgManager);
this._backgroundGroup.add_child(widget);
}
_updateBackgrounds() {
for (let i = 0; i < this._bgManagers.length; i++)
this._bgManagers[i].destroy();
this._bgManagers = [];
this._backgroundGroup.destroy_all_children();
for (let i = 0; i < Main.layoutManager.monitors.length; i++)
this._createBackground(i);
}
_liftShield(onPrimary, velocity) {
_activateDialog() {
if (this._isLocked) {
if (this._ensureUnlockDialog(onPrimary, true /* allowCancel */))
this._hideLockScreen(true /* animate */, velocity);
this._ensureUnlockDialog(true /* allowCancel */);
this._dialog.activate();
} else {
this.deactivate(true /* animate */);
}
@@ -638,9 +175,7 @@ var ScreenShield = class {
// LoginDialog.cancel() will grab the key focus
// on its own, so ensure it stays on lock screen
// instead
this._lockScreenGroup.grab_key_focus();
} else {
this._dialog = null;
this._dialog.grab_key_focus();
}
}
@@ -659,55 +194,6 @@ var ScreenShield = class {
return this._isModal;
}
_onLockScreenKeyPress(actor, event) {
let symbol = event.get_key_symbol();
let unichar = event.get_key_unicode();
// Do nothing if the lock screen is not fully shown.
// This avoids reusing the previous (and stale) unlock
// dialog if esc is pressed while the curtain is going
// down after cancel.
if (this._lockScreenState != MessageTray.State.SHOWN)
return Clutter.EVENT_PROPAGATE;
let isEnter = symbol == Clutter.KEY_Return ||
symbol == Clutter.KEY_KP_Enter ||
symbol == Clutter.KEY_ISO_Enter;
let isEscape = symbol == Clutter.KEY_Escape;
let isLiftChar = GLib.unichar_isprint(unichar) &&
(this._isLocked || !GLib.unichar_isgraph(unichar));
if (!isEnter && !isEscape && !isLiftChar)
return Clutter.EVENT_PROPAGATE;
if (this._isLocked &&
this._ensureUnlockDialog(true, true) &&
GLib.unichar_isgraph(unichar))
this._dialog.addCharacter(unichar);
this._liftShield(true, 0);
return Clutter.EVENT_STOP;
}
_onLockScreenScroll(actor, event) {
if (this._lockScreenState != MessageTray.State.SHOWN)
return Clutter.EVENT_PROPAGATE;
let delta = 0;
if (event.get_scroll_direction() == Clutter.ScrollDirection.SMOOTH)
delta = Math.abs(event.get_scroll_delta()[0]);
else
delta = 5;
this._lockScreenScrollCounter += delta;
// 7 standard scrolls to lift up
if (this._lockScreenScrollCounter > 35)
this._liftShield(true, 0);
return Clutter.EVENT_STOP;
}
_syncInhibitor() {
let lockEnabled = this._settings.get_boolean(LOCK_ENABLED_KEY);
let lockLocked = this._lockSettings.get_boolean(DISABLE_LOCK_KEY);
@@ -736,78 +222,6 @@ var ScreenShield = class {
}
}
_animateArrows() {
let arrows = this._arrowContainer.get_children();
let unitaryDelay = ARROW_ANIMATION_TIME / (arrows.length + 1);
let maxOpacity = 255 * ARROW_ANIMATION_PEAK_OPACITY;
for (let i = 0; i < arrows.length; i++) {
arrows[i].opacity = 0;
arrows[i].ease({
opacity: maxOpacity,
delay: unitaryDelay * (N_ARROWS - (i + 1)),
duration: ARROW_ANIMATION_TIME / 2,
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
onComplete: () => {
arrows[i].ease({
opacity: 0,
duration: ARROW_ANIMATION_TIME / 2,
mode: Clutter.AnimationMode.EASE_IN_QUAD,
});
},
});
}
return GLib.SOURCE_CONTINUE;
}
_onDragBegin() {
this._lockScreenGroup.remove_all_transitions();
this._lockScreenState = MessageTray.State.HIDING;
if (this._isLocked)
this._ensureUnlockDialog(false, false);
return true;
}
_onDragMotion() {
let [, origY] = this._dragAction.get_press_coords(0);
let [, currentY] = this._dragAction.get_motion_coords(0);
let newY = currentY - origY;
newY = clamp(newY, -global.stage.height, 0);
this._lockScreenGroup.translation_y = newY;
return true;
}
_onDragEnd(_action, _actor, _eventX, _eventY, _modifiers) {
if (this._lockScreenState != MessageTray.State.HIDING)
return;
if (this._lockScreenGroup.translation_y < -(ARROW_DRAG_THRESHOLD * global.stage.height)) {
// Complete motion automatically
let [velocity_, velocityX_, velocityY] = this._dragAction.get_velocity(0);
this._liftShield(true, -velocityY);
} else {
// restore the lock screen to its original place
// try to use the same speed as the normal animation
let h = global.stage.height;
let duration = MANUAL_FADE_TIME * -this._lockScreenGroup.translation_y / h;
this._lockScreenGroup.remove_all_transitions();
this._lockScreenGroup.ease({
translation_y: 0,
duration,
mode: Clutter.AnimationMode.EASE_IN_QUAD,
onComplete: () => {
this._lockScreenState = MessageTray.State.SHOWN;
},
});
this._maybeCancelDialog();
}
}
_onStatusChanged(status) {
if (status != GnomeSession.PresenceStatus.IDLE)
return;
@@ -867,11 +281,7 @@ var ScreenShield = class {
// This function gets called here when the user becomes active
// after we activated a lightbox
// There are two possibilities here:
// - we're called when already locked/active; isLocked or isActive is true,
// we just go back to the lock screen curtain
// (isActive == isLocked == true: normal case
// isActive == false, isLocked == true: during the fade for manual locking
// isActive == true, isLocked == false: after session idle, before lock-delay)
// - we're called when already locked; we just go back to the lock screen curtain
// - we're called because the session is IDLE but before the lightbox
// is fully shown; at this point isActive is false, so we just hide
// the lightbox, reset the activationTime and go back to the unlocked
@@ -885,7 +295,7 @@ var ScreenShield = class {
this.idleMonitor.remove_watch(this._becameActiveId);
this._becameActiveId = 0;
if (this._isActive || this._isLocked) {
if (this._isLocked) {
this._longLightbox.lightOff();
this._shortLightbox.lightOff();
} else {
@@ -913,14 +323,10 @@ var ScreenShield = class {
this.actor.show();
this._isGreeter = Main.sessionMode.isGreeter;
this._isLocked = true;
if (this._ensureUnlockDialog(true, true))
this._hideLockScreen(false, 0);
this._ensureUnlockDialog(true);
}
_hideLockScreenComplete() {
if (Main.sessionMode.currentMode == 'lock-screen')
Main.sessionMode.popMode('lock-screen');
this._lockScreenState = MessageTray.State.HIDDEN;
this._lockScreenGroup.hide();
@@ -930,13 +336,13 @@ var ScreenShield = class {
}
}
_hideLockScreen(animate, velocity) {
_hideLockScreen(animate) {
if (this._lockScreenState == MessageTray.State.HIDDEN)
return;
this._lockScreenState = MessageTray.State.HIDING;
this._lockScreenGroup.remove_all_transitions();
this._lockDialogGroup.remove_all_transitions();
if (animate) {
// Tween the lock screen out of screen
@@ -944,16 +350,14 @@ var ScreenShield = class {
// use the same speed regardless of original position
// if velocity is specified, it's in pixels per milliseconds
let h = global.stage.height;
let delta = h + this._lockScreenGroup.translation_y;
let minVelocity = global.stage.height / CURTAIN_SLIDE_TIME;
velocity = Math.max(minVelocity, velocity);
let delta = h + this._lockDialogGroup.translation_y;
let velocity = global.stage.height / CURTAIN_SLIDE_TIME;
let duration = delta / velocity;
this._lockScreenGroup.ease({
this._lockDialogGroup.ease({
translation_y: -h,
duration,
mode: Clutter.AnimationMode.EASE_IN_QUAD,
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
onComplete: () => this._hideLockScreenComplete(),
});
} else {
@@ -963,7 +367,7 @@ var ScreenShield = class {
this._cursorTracker.set_pointer_visible(true);
}
_ensureUnlockDialog(onPrimary, allowCancel) {
_ensureUnlockDialog(allowCancel) {
if (!this._dialog) {
let constructor = Main.sessionMode.unlockDialog;
if (!constructor) {
@@ -975,7 +379,7 @@ var ScreenShield = class {
this._dialog = new constructor(this._lockDialogGroup);
let time = global.get_current_time();
if (!this._dialog.open(time, onPrimary)) {
if (!this._dialog.open(time)) {
// This is kind of an impossible error: we're already modal
// by the time we reach this...
log('Could not open login dialog: failed to acquire grab');
@@ -984,9 +388,12 @@ var ScreenShield = class {
}
this._dialog.connect('failed', this._onUnlockFailed.bind(this));
this._wakeUpScreenId = this._dialog.connect(
'wake-up-screen', this._wakeUpScreen.bind(this));
}
this._dialog.allowCancel = allowCancel;
this._dialog.grab_key_focus();
return true;
}
@@ -1003,94 +410,31 @@ var ScreenShield = class {
if (this._lockScreenState != MessageTray.State.HIDDEN)
return;
this._ensureLockScreen();
this._lockDialogGroup.scale_x = 1;
this._lockDialogGroup.scale_y = 1;
this._lockScreenGroup.show();
this._lockScreenState = MessageTray.State.SHOWING;
let fadeToBlack = params.fadeToBlack;
if (params.animateLockScreen) {
this._lockScreenGroup.translation_y = -global.screen_height;
this._lockScreenGroup.remove_all_transitions();
this._lockScreenGroup.ease({
this._lockDialogGroup.translation_y = -global.screen_height;
this._lockDialogGroup.remove_all_transitions();
this._lockDialogGroup.ease({
translation_y: 0,
duration: MANUAL_FADE_TIME,
duration: Overview.ANIMATION_TIME,
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
onComplete: () => {
this._lockScreenShown({ fadeToBlack, animateFade: true });
},
});
} else {
this._lockScreenGroup.translation_y = 0;
this._lockDialogGroup.translation_y = 0;
this._lockScreenShown({ fadeToBlack, animateFade: false });
}
this._lockScreenGroup.grab_key_focus();
if (Main.sessionMode.currentMode != 'lock-screen')
Main.sessionMode.pushMode('lock-screen');
}
_startArrowAnimation() {
this._arrowActiveWatchId = 0;
if (!this._arrowAnimationId) {
this._arrowAnimationId = GLib.timeout_add(GLib.PRIORITY_DEFAULT, 6000, this._animateArrows.bind(this));
GLib.Source.set_name_by_id(this._arrowAnimationId, '[gnome-shell] this._animateArrows');
this._animateArrows();
}
if (!this._arrowWatchId) {
this._arrowWatchId = this.idleMonitor.add_idle_watch(ARROW_IDLE_TIME,
this._pauseArrowAnimation.bind(this));
}
}
_pauseArrowAnimation() {
if (this._arrowAnimationId) {
GLib.source_remove(this._arrowAnimationId);
this._arrowAnimationId = 0;
}
if (!this._arrowActiveWatchId)
this._arrowActiveWatchId = this.idleMonitor.add_user_active_watch(this._startArrowAnimation.bind(this));
}
_stopArrowAnimation() {
if (this._arrowAnimationId) {
GLib.source_remove(this._arrowAnimationId);
this._arrowAnimationId = 0;
}
if (this._arrowActiveWatchId) {
this.idleMonitor.remove_watch(this._arrowActiveWatchId);
this._arrowActiveWatchId = 0;
}
if (this._arrowWatchId) {
this.idleMonitor.remove_watch(this._arrowWatchId);
this._arrowWatchId = 0;
}
}
_checkArrowAnimation() {
let idleTime = this.idleMonitor.get_idletime();
if (idleTime < ARROW_IDLE_TIME)
this._startArrowAnimation();
else
this._pauseArrowAnimation();
this._dialog.grab_key_focus();
}
_lockScreenShown(params) {
if (this._dialog && !this._isGreeter) {
this._dialog.destroy();
this._dialog = null;
}
this._checkArrowAnimation();
let motionId = global.stage.connect('captured-event', (stage, event) => {
if (event.type() == Clutter.EventType.MOTION) {
this._cursorTracker.set_pointer_visible(true);
@@ -1102,7 +446,6 @@ var ScreenShield = class {
this._cursorTracker.set_pointer_visible(false);
this._lockScreenState = MessageTray.State.SHOWN;
this._lockScreenScrollCounter = 0;
if (params.fadeToBlack && params.animateFade) {
// Take a beat
@@ -1125,52 +468,11 @@ var ScreenShield = class {
this.emit('lock-screen-shown');
}
// Some of the actors in the lock screen are heavy in
// resources, so we only create them when needed
_ensureLockScreen() {
if (this._hasLockScreen)
return;
this._lockScreenContentsBox = new St.BoxLayout({ x_align: Clutter.ActorAlign.CENTER,
y_align: Clutter.ActorAlign.CENTER,
x_expand: true,
y_expand: true,
vertical: true,
style_class: 'screen-shield-contents-box' });
this._clock = new Clock();
this._lockScreenContentsBox.add_child(this._clock);
this._lockScreenContents.add_actor(this._lockScreenContentsBox);
this._notificationsBox = new NotificationsBox();
this._wakeUpScreenId = this._notificationsBox.connect('wake-up-screen', this._wakeUpScreen.bind(this));
this._lockScreenContentsBox.add_child(this._notificationsBox);
this._hasLockScreen = true;
}
_wakeUpScreen() {
this._onUserBecameActive();
this.emit('wake-up-screen');
}
_clearLockScreen() {
this._clock.destroy();
this._clock = null;
if (this._notificationsBox) {
this._notificationsBox.disconnect(this._wakeUpScreenId);
this._notificationsBox.destroy();
this._notificationsBox = null;
}
this._stopArrowAnimation();
this._lockScreenContentsBox.destroy();
this._hasLockScreen = false;
}
get locked() {
return this._isLocked;
}
@@ -1191,13 +493,8 @@ var ScreenShield = class {
}
_continueDeactivate(animate) {
this._hideLockScreen(animate, 0);
this._hideLockScreen(animate);
if (this._hasLockScreen)
this._clearLockScreen();
if (Main.sessionMode.currentMode == 'lock-screen')
Main.sessionMode.popMode('lock-screen');
if (Main.sessionMode.currentMode == 'unlock-dialog')
Main.sessionMode.popMode('unlock-dialog');
@@ -1223,9 +520,8 @@ var ScreenShield = class {
}
this._lockDialogGroup.ease({
scale_x: 0,
scale_y: 0,
duration: animate ? Overview.ANIMATION_TIME : 0,
translation_y: -global.screen_height,
duration: Overview.ANIMATION_TIME,
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
onComplete: () => this._completeDeactivate(),
});
@@ -1262,10 +558,11 @@ var ScreenShield = class {
if (this._activationTime == 0)
this._activationTime = GLib.get_monotonic_time();
this._ensureUnlockDialog(true);
this.actor.show();
if (Main.sessionMode.currentMode != 'unlock-dialog' &&
Main.sessionMode.currentMode != 'lock-screen') {
if (Main.sessionMode.currentMode !== 'unlock-dialog') {
this._isGreeter = Main.sessionMode.isGreeter;
if (!this._isGreeter)
Main.sessionMode.pushMode('unlock-dialog');

View File

@@ -231,18 +231,18 @@ var SearchResultsBase = GObject.registerClass({
this.provider.getResultMetas(metasNeeded, metas => {
if (this._cancellable.is_cancelled()) {
if (metas.length > 0)
log(`Search provider ${this.provider.id} returned results after the request was canceled`);
log('Search provider %s returned results after the request was canceled'.format(this.provider.id));
callback(false);
return;
}
if (metas.length != metasNeeded.length) {
log(`Wrong number of result metas returned by search provider ${this.provider.id}: ` +
`expected ${metasNeeded.length} but got ${metas.length}`);
log('Wrong number of result metas returned by search provider %s: '.format(this.provider.id) +
'expected %d but got %d'.format(metasNeeded.length, metas.length));
callback(false);
return;
}
if (metas.some(meta => !meta.name || !meta.id)) {
log(`Invalid result meta returned from search provider ${this.provider.id}`);
log('Invalid result meta returned from search provider %s'.format(this.provider.id));
callback(false);
return;
}
@@ -609,7 +609,7 @@ var SearchResultsView = GObject.registerClass({
this._searchTimeoutId = GLib.timeout_add(GLib.PRIORITY_DEFAULT, 150, this._onSearchTimeout.bind(this));
let escapedTerms = this._terms.map(term => Shell.util_regex_escape(term));
this._highlightRegex = new RegExp(`(${escapedTerms.join('|')})`, 'gi');
this._highlightRegex = new RegExp('(%s)'.format(escapedTerms.join('|')), 'gi');
this.emit('terms-changed');
}

Some files were not shown because too many files have changed in this diff Show More