Compare commits

..

144 Commits

Author SHA1 Message Date
e7a502e5c3 wip: Port extensions app/portal to GTK4 2020-08-01 04:00:16 +02:00
b689b35b7d data: Place the shell into session.slice when using systemd
This way we conform more to https://systemd.io/DESKTOP_ENVIRONMENTS

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/895
2020-07-31 13:53:31 +00:00
01a927f388 windowManager: Wait for X11 services using systemd
To do this, we now wait for the start/stop job to complete. We also have
two targets in gnome-session to ensure that everything is working as
expected.

In order to start the services, we simply request the
gnome-session-x11-services-ready.target unit, and wait for it to become
available. To stop, we use the gnome-session-x11-services.target unit
which should stop all services in a way that is entirely race free.

This requires both gnome-session and gnome-settings-daemon changes to
work (which are in the corresponding merge requests).

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/895
2020-07-31 13:53:31 +00:00
41d5b1455f data: Create generic org.gnome.Shell.target
Move the GNOME shell service file adapation for x11/wayland into the
target/service files. This means that the session definition can simply
pull in org.gnome.Shell.target, without having to care about whether it
is starting an X11 or wayland session.

Note that this currently requires fork'ing to do the test. This will
however not be needed in the long term when ConditionEnvironment becomes
available (see https://github.com/systemd/systemd/pull/15817).

We technically do not need to use template units. But doing so means
that the unit can be translated to the app id more easily (though it is
not yet completely clear how this should look like in the long term).

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/895
2020-07-31 13:53:31 +00:00
b710c6e275 data: Remove unused, commented and obsolete Conflicts lines
https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/895
2020-07-31 13:53:31 +00:00
4c9f42eea9 data: Use org.gnome.Shell prefix for systemd units
In general we want to move towards using reverse domain names for
systemd units. Doing this also means we have a consistent name between
desktop file and systemd unit, allowing us to create a generator that
pulls in the unit as defined in the sessions RequiredComponents.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/895
2020-07-31 13:53:31 +00:00
2b0731ab81 Move screencasting into a separate service process
Move the screencasting into a separate D-Bus service process, using
PipeWire instead of Clutter API. The service is implemented in
Javascript using the dbusService.js helper, and implements the same API
as was done by screencast.js and the corresponding C code.

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1372
2020-07-31 10:51:12 +02:00
a9b803f075 introspect: Introspect screen size
To be used by the screen cast service.

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1372
2020-07-31 10:51:12 +02:00
73436b5276 dbusService: Queue shutdown check on startup
If something started the service, but crashed before managing to make a
method call, we'd end up with the service running indefinitely. Fix this
by queueing a shutdown check immediately on startup.

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1372
2020-07-31 10:51:12 +02:00
20dcc8aa87 status/remote-access: Visualize recordings as screen recording
If a remote access is marked as a recording, visualize it the same way
as a built in recording. Also don't stop it if there is an actual screen
sharing going on, so that one can use a plain "recording" while still
disabling what is an actual screen sharing.

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1372
2020-07-31 10:51:12 +02:00
fdac0602db background: Mark pattern backgrounds as loaded
Otherwise we don't let GNOME Shell startup to proceed. Noticed
by accidentally running on the memory GSettings backend.

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1381
2020-07-30 11:48:13 +02:00
e5272c84d7 Update Turkish translation 2020-07-29 21:57:19 +00:00
1812db7aa8 panelMenu: Destroy menu before chaining up
This avoid some (harmless but annoying) warnings, and is closer to
the original code prior to commit fc342fe8c5 and 557b232c89.

https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/3022
2020-07-29 19:40:54 +00:00
260405a49e popupMenu: Ungrab when removing active menu
While we do have some handling for removing the active menu, it has
been a no-op for years. The bit that we really care about from the
PopupMenuManager's point of view is the existing grab though. Drop
that instead of calling _closeMenu() directly; ungrabbing will still
call the method indirectly, and it will still be a no-op :-)

https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/3022
2020-07-29 19:40:54 +00:00
71d37bffdf util: Remove shell_util_get_transformed_allocation
This helper function could be replaced with the new
clutter_actor_get_transformed_extents, that does the same.

See https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1386

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1380
2020-07-29 18:09:53 +02:00
95436a08b5 Updated Spanish translation 2020-07-29 12:42:11 +02:00
13137aad9d loginDialog: Reset auth prompt on vt switch before fade in
At the moment, if a user switches to the login screen vt,
the login screen fades in whatever was on screen prior, and
then does a reset.

It makes more sense to reset first, so we fade in what the
user is going to interact with instead of what they interacted
with before.

Fixes: https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/2997
2020-07-27 16:18:44 -04:00
71f55643b2 layout: Only show ripple animation when overview was toggled
On X11, clients can grab keyboard on pointer (for example for popup
menus), and as a result the pushModal() call when opening the overview
fails.

However when the hot corner was used to toggle the overview, we still
show the ripple animation in that case, which is confusing as the action
did not actually happen.

Fix this by only showing the ripples if the overview is animating after
calling toggle(), as that should be a reliable indication of whether
the call was successful.

https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/3005
2020-07-27 13:13:14 +00:00
5c550daecb backgroundManager: Always emit 'loaded' signal
As backgrounds are cached, it is possible that we never emit the
'loaded' signal added in commit f386103bc1. We are relying on the
signal though, so do the same as Background and emit the signal
from an idle if the background was already loaded.

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1371
2020-07-22 11:02:24 +00:00
4e0492c517 Update Catalan translation 2020-07-22 08:47:17 +02:00
f386103bc1 Delay login animation until after wallpaper has loaded
Currently, the login animation can occur before the user's wallpaper has
been loaded. When this happens, we wind up displaying a solid blue
background for half a second or so before the proper background is
displayed. This looks jarring and bad. It's great that we can start
GNOME quickly, but starting up before the wallpaper is ready is *too*
quickly.

I've been meaning to fix this since 2014. Better late than never! We can
just have BackgroundManager emit a loaded signal the first time it loads
its first background, and have the startup animation code wait for that
before proceeding.

Some of this code is by Florian, who helped with promisifying. Thanks!

https://bugzilla.gnome.org/show_bug.cgi?id=734996
2020-07-21 20:25:31 -05:00
26e66aa4fd popupMenu: Handle keypress if numlock is enabled
On Wayland, navigating menus with the keyboard would not open drop-down
menus when NumLock is enabled.

That's old issue (gnome-shell#550) that was not completely fixed with
commit 88556226 because the lock mask needs to be filtered out in
_onKeyPress() as well.

Closes: https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/550
2020-07-21 16:38:15 +02:00
4420f52080 Update Romanian translation 2020-07-21 07:08:22 +00:00
b4082063de Update Ukrainian translation 2020-07-21 05:43:54 +00:00
bde974087a appDisplay: Append new icons at the first available page after first
As per design discussion, the first page is a somewhat of a special
page where we really don't want to change anything unless necessary.

Append new icons at the first available slot after the first page.
Make the placeholder icon be appended to the first available page
as well, since it's always used when dragging from folder dialogs.

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1284
2020-07-20 16:13:20 +00:00
d93b51e135 appDisplay: Use a drag monitor to check for out-of-dialog drags
When the app folder dialog handles a drag hover, it starts a timeout
to popdown if dragging outside the "real" dialog area. However, when
dragging inside it, BaseAppView handles all drag hover events which
would disarm the popdown timeout. In cases like this, it's almost
impossible to prevent the timeout from triggering, which always pops
down the dialog.

Add a drag monitor when handling any drag hover (which only happens
when dragging outside the folder's icon grid); and eventually disarm
the popdown timeout from the monitor's motion event. Remove the drag
monitor when dragging over the folder dialog again.

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1284
2020-07-20 16:13:20 +00:00
730a68dffc appDisplay: Increase folder dialog popdown timeout
App folders are now customizable, and the way to move icons to
another page is by throwing the cursor to either the left or
the right of the grid.

However, doing that triggers the popdown timeout, wich is 600ms
as of now, which is considerably short for such interaction.

Increase this timeout to 1.5 seconds.

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1284
2020-07-20 16:13:20 +00:00
f06c257952 appDisplay: Allow reordering folders
Implement the methods to sort and query item positions
using the index in the GSettings key, and store the
updated positions when accepting the drop.

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1284
2020-07-20 16:13:20 +00:00
7afab2c28c appDisplay: Factor out folder loading code
We'll reuse this code to implement custom positioning in
folders.

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1284
2020-07-20 16:13:20 +00:00
16a18f2ae7 appDisplay: Only handle DnD when mapped
Now that the DnD code is shared between AppDisplay and
FolderView, we hit an unexpected problem: FolderView is
handling drag events even when the folder dialog is hidden.
As a side effect, this spams the journal with warnings.

Only handle drag events when mapped. On unmap, disable
the view's drag monitor, and disconnect from all drag
events.

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1284
2020-07-20 16:13:20 +00:00
704e08dc08 appDisplay: Move DnD code to BaseAppView
This code will be shared with FolderView in the next commit, so
avoid duplication already and move the to-be-shared code into the
base class.

Because BaseAppView can handle vertical and horizontal orientations,
adapt the drag overshoot code to also handle horizontal overshoot.

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1284
2020-07-20 16:13:20 +00:00
60311aa4d1 appDisplay: Fully hide icon when dragging
The partially visible icon causes more problems than
it solves, visually speaking. Fade it out completely
while dragging.

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1284
2020-07-20 16:13:20 +00:00
cceb74706a appDisplay: Ensure icons always are at the correct position
When redisplaying, we currently only remove and add icons, but
never adjust the position of already added icons. If the icon
position changed, it wouldn't be reflected on the icon grid.

Make sure to move already added icons.

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1284
2020-07-20 16:13:20 +00:00
578ae29ed2 appDisplay: Add placeholder when moving from folder dialog
When moving an icon from a folder dialog, the app grid doesn't
really have an icon to move around.

Add a placeholder icon and hijack it in the various places.

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1284
2020-07-20 16:13:20 +00:00
701d110493 appDisplay: Restore dragged item's position on drag cancel
Otherwise we end up with the grid in an inconsistent state.

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1284
2020-07-20 16:13:20 +00:00
d1cbf6c7a9 appDisplay: Allow overshooting any icon
Now that the icon being dragged can come from AppDisplay and also
a folder dialog, the check for when to overshoot is broken. Check
if the icon is a BaseAppView icon.

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1284
2020-07-20 16:13:20 +00:00
b64ce217e4 appDisplay: Create app folder where the drop happened
Create the app folder where the icon we drop at is located. This
ensures the folder icon doesn't go into the last page, hidden and
solitary.

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1284
2020-07-20 16:13:20 +00:00
783dbe2aa9 appDisplay: Don't resort folders when name changes
With a customizable app grid, we don't want folders to move
after renaming. Their position is fixed.

Remove the sort-after-rename code from AppDisplay.

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1284
2020-07-20 16:13:20 +00:00
f4ce1cf462 appDisplay: Make FolderIcon draggable
By making it a subclass of AppViewItem, it automagically inherits
the DnD code.

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1284
2020-07-20 16:13:20 +00:00
d04d6e069d appDisplay: Check 'app-picker-layout' to make icons draggable
Now we drag not only to the Dash, but also to the icon grid itself,
so make the app icon draggable only when either one or the other is
writable.

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1284
2020-07-20 16:13:20 +00:00
40de201056 appDisplay: Factor out draggable code into AppViewItem
This will be shared by the FolderIcon.

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1284
2020-07-20 16:13:20 +00:00
18234ea91a appDisplay: Use custom function to retrieve item page and position
It is important that '_loadApps()' return a sorted list -- adding the
same icons at the same positions but in different orders results in
a wrong icon grid.

Add support for using a custom positioning function, and implement it
in AppDisplay. Because FolderView doesn't implement a custom sorting
function, the items are still sorted alphabetically.

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1284
2020-07-20 16:13:20 +00:00
e3f3297cba appDisplay: Save pages after dropping
Save the icon grid layout after dropping, and only in
that moment.

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1284
2020-07-20 16:13:20 +00:00
e1ea1d2954 appDisplay: Introduce PageManager
The PageManager does the heavy lifting between reading the
'app-picker-layout' GSettings key, and saving the new pages.

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1284
2020-07-20 16:13:20 +00:00
8e23ff8111 gschema: Introduce the 'app-picker-layout' key
This is the key that will be used to store the pages and the icons in
each page. The idea is that we we store an a{sv} variant for each page.
This variant will contain <icon id> → array of properties, where we
can store arbitrary data for each icon. The expected output of this
key is:

[
  {
    'polari.desktop': <{ 'position': 0 }>,
    'epiphany.deskop': <{ 'position': 1 }>,
  },
  {
    'telegram.desktop': <{ 'position': 2 }>,
    'builder.desktop': <{ 'position': 0 }>,
    'gitg.desktop': <{ 'position': 1 }>,
  }
]

The toplevel array is sorted, and pages of the grid always show in the
order they are stored.

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1284
2020-07-20 16:13:20 +00:00
8a50a8e64c appDisplay: Allow incomplete pages
Allow incomplete pages in the main grid, but not on folders.

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1284
2020-07-20 16:13:19 +00:00
fae207811a appDisplay: Move icons when hovering the grid
Implement a minimal version of the reflow-on-hover behavior,
which gives a better sense of physicality to the grid.

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1284
2020-07-20 16:13:19 +00:00
1d86424942 appDisplay: Factor out item addition and removal methods
It'll be useful later.

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1284
2020-07-20 16:13:19 +00:00
2bc8175219 appDisplay: Accept dropping any kind of icon over it
The grid will be able to handle them. As of now, it doesn't
do anything with folder icons, or icons in folders.

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1284
2020-07-20 16:13:19 +00:00
1e31caf0b8 appDisplay: Introduce moveItem API
This is a simplistic API that basically removes the
icon from it's old location, and adds it to its new
location.

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1284
2020-07-20 16:13:19 +00:00
8e24ac6b26 appDisplay: Ignore dragging over leeways
The leeways are parts of the icon that ignore incoming drag
events. This is how IconGrid and IconGridLayout treat it, and
this is how the icons should treat themselves too.

Make AppIcon ignore dragging over the left and right leeways.

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1284
2020-07-20 16:13:19 +00:00
427b9ac75f iconGrid: Add drop target API
Add a new drop target API. The bulk of it is implemented by
IconGridLayout, since it's the layout manager that knows where
each icon is placed at.

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1284
2020-07-20 16:13:19 +00:00
f50205e9b4 calendar-server: Remove delay before event emission
The timeout seems to have been carried over from the old code that
relied on gnome-shell calling 'GetEvents' after every 'Changed' signal
where it was used to throttle the signal. In the new code where
calendar-server is sending the changes themselves via signals this is no
longer necessary and actually causes a delay when switching between
months.

Fixes https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/2992
2020-07-20 13:50:21 +02:00
168cfdd86b keyboard: Fix missing key icons in numeric level
Those were missed in commit 57669bca1b.

https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/2631
2020-07-20 01:24:16 +02:00
d339c94c18 keyboard: Move named icons into subdirectories
While GtkIconTheme does look up icons in the toplevel icons resource
path, it will only use them as ultimate fallback. That is, if the
icon theme (or the hicolor fallback) include a "keyboard" icon, it
will be used over the "keyboard-enter-symbolic" icon in the resource.

Moving the icons to appropriate subdirectories gives them higher
priority than the fallback names, and thus fixes the issue.

https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/2631
2020-07-20 01:08:25 +02:00
97509bf1d2 Update Brazilian Portuguese translation 2020-07-19 12:54:47 +00:00
4a9c2ee805 Update Brazilian Portuguese translation
(cherry picked from commit 222919cfc1)
2020-07-18 13:44:05 +00:00
51e1e6d15c Update Brazilian Portuguese translation
(cherry picked from commit db30fbe3e9)
2020-07-17 21:36:25 +00:00
f0d2509dc3 extensionDownloader: Fix check for updates with several extensions
When having several extensions installed checking for updates fails.
This is because we are using GET and query params and since we are
sending all the metadata of the extension the server returns 502
when the URL is too long. This error code is ignored safely.

It is only needed to send the version of the extension to check if it
has updates.

Fixes https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/2962
https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1363
2020-07-15 18:26:11 -06:00
95bb194356 layout: Remove redundant background refresh
When using the NVIDIA driver, textures tend to loose their pixels when
suspending. In the past we handled this by figuring out when the NVIDIA
driver was used, and reload the background whenever we noticed we
resumed from suspend.

This shouldn't be needed anymore after
https://gitlab.gnome.org/GNOME/mutter/merge_requests/600, as it should
handle this by listening to video-memory-purged signal. Thus remove our
special handling here.

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1358
2020-07-14 23:14:39 +00:00
de8b43a45d Update Greek translation 2020-07-14 20:43:58 +00:00
82be010fd8 workspace: Always set state at the end of overview transition
We don't change to the zoomed out state when fading to the overview,
however we should do that after the transition in case the user
switches to the window picker.

https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/2969
2020-07-13 17:24:43 +00:00
2a0c116757 workspace: Reset window opacity after overview transitions
When using the fade animation when transitioning to the overview instead
of zoom, we fade out all window previews to fully transparent. But after
commit 751189253a removed the old _updateWindowPositions() function,
nothing resets the opacity again, so when switching from the app- to the
window picker, all previews are hidden.

Fix this by always resetting the window preview opacity after showing
or hiding the overview.

https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/2969
2020-07-13 17:24:43 +00:00
6cdaec4001 workspace: Always use floating layout for fade transition
We don't animate size and position when fading, so we want all previews
to already be at their final position. However when the app picker is
opened from within the overview, window previews use the zoomed layout,
so that's the state we are then fading when leaving the overview from
the app picker.

Fix that by setting the correct state at the start of the fade transition.

(In the case of fadeToOverview(), the value should always be correct
already, but set it anyway for symmetry with fadeFromOverview())

https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/2969
2020-07-13 17:24:43 +00:00
ed4baec40f workspacesView: Really don't animate primary view when fading
In commit 9297d87775 we stopped syncing the primary view's actual
geometry at the start of the transition when doing a fade animation,
however the view animation may still be triggered by an allocation
change.

Prevent those unwanted size changes during fade by keeping track of
the fade state and explicitly skip syncing the geometry while a fade
is ongoing.

https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/2969
2020-07-13 17:24:43 +00:00
9e8883c922 workspacesView: Do not skip entire overview transition
Since commit af543daf1c, we skip the overview transition when the
actual geometry hasn't been set yet. However with the new layout
manager, the only bit that still needs the separate geometry is
the transition of the view, the workspaces can do their transition
just fine.

https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/2969
2020-07-13 17:24:42 +00:00
9bb64da895 Update Friulian translation 2020-07-12 16:08:10 +00:00
049f348e25 Update Chinese (China) translation 2020-07-12 02:35:34 +00:00
be190cc4d9 Update Chinese (China) translation 2020-07-12 02:14:16 +00:00
0893789b34 workspacesView: Update visibily when gesture drag begins
When dragging the workspaces through the swipe gesture, all
workspaces must be visible. WorkspacesView's _updateVisibility()
method special-cases this and ensures that.

However, this method is only called when (1) going to the active
workspace, and (2) when the gesture ends. That means, if there
is any workspace hidden by the time a gesture starts, it is never
shown!

Call _updateVisibility() on startTouchGesture() as well.

Related: https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/2969

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1360
2020-07-10 11:14:12 -03:00
7b5c6b657a Update German translation 2020-07-09 20:29:47 +00:00
9363fd3524 workspaceSwitcherPopup: Set offscreen redirect always
Because for most frames during a workspace switch it's not changing and
we can repaint it faster if it's cached on the GPU as a single texture.

This seems to reduce the render time for workspace switching by more
than 20%.

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1356
2020-07-09 11:49:59 +08:00
0ad242a81e shell/window-tracker: Tighten sandbox ID prefix check
Since commit b60836932 we only allow WM_CLASS matches for sandboxed
applications if the found app's ID is prefixed by the sandbox ID.

The existing check still has a hole in it though: "org.example.Foo"
and "org.example.FooDevel" are different applications, yet the former
is a prefix of the latter.

So tighten the check by including a trailing "." in the checked prefix;
this excludes cases like the above, while still working for the regular
case of a single .desktop file because our app IDs include the ".desktop"
suffix.

Spotted by wjt.

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1357
2020-07-08 12:23:10 +02:00
7031449f01 Bump version to 3.37.3
Update NEWS.
2020-07-07 19:01:21 +02:00
06df79286d windowPreview: Adapt to ClutterActor API changes
The API of clutter_actor_allocate_preferred_size() changed with
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1310, so adapt to
this change and pass the origin to the function.

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1322
2020-07-07 16:51:33 +00:00
9297d87775 workspacesView: Do not animate primary view geometry when fading
When going straight to the app picker, we fade in the overview instead
of doing the full-blown zoom transition. In order to keep windows at
their floating position, we must apply the same to the view itself
and not transition to the overview geometry when fading.

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1353
2020-07-07 13:41:54 +02:00
ef56b14553 workspacesView: Always sync geometry after showing overview
We don't always want to sync the geometry when entering the overview,
namely when the fade transition is used.

However we do want the correct geometry once we have entered the overview,
so that workspaces are at their place when switching from the app picker.

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1353
2020-07-07 13:41:54 +02:00
30ff76272e workspacesView: Decouple syncing geometry from updating views
This gives us more control over when the geometry is synced. We
will soon use that to keep the primary view at the work area
geometry while fading to the overview.

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1353
2020-07-07 13:41:54 +02:00
52a7481ba6 workspacesView: Only animate primary view
Non-primary views always use their monitor's work area for their
geometry, so there's nothing to animate when leaving the overview.

The animation is already limited to the primary view when entering
the overview, so this is also more consistent.

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1353
2020-07-07 13:41:54 +02:00
14cfd74f08 workspace: Always start in FLOATING state
It doesn't matter which animation we use to enter the overview,
we always want to start and end with the floating layout.

The simplest way to achieve that is by creating the state adjustment
with the correct value in the first place.

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1353
2020-07-07 13:41:54 +02:00
fa97f7141b workspace: Remove reserved slots
This is a pre-3.0 feature that was dropped before
the 3.0 release, but managed to find its way until
now, 11 years later.

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1352
2020-07-07 12:26:59 +02:00
03bcd4c05b unlockDialog: Small cleanup
It's silly to initialize a variable to 0 right before setting it
to its actual value.

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1352
2020-07-07 12:26:58 +02:00
89574abc83 windowPreview: Remove slotId property
We're no longer using that property, so clean up a bit and remove the
last occurences of it.

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1351
2020-07-07 11:22:20 +02:00
602078cbde workspacesView: Add back overview transition
The transition was temporarily removed when switching to the new
workspace layout manager. Now everything is in place to reimplement
it with a combination of the layout manager's state adjustment and
the view's allocation.

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1345
2020-07-07 00:09:29 +02:00
96f63b08c2 workspacesView: Properly allocate workspaces
So far we've been allocating workspaces in a stack, and relied on
translation to move them to the right position. And as the position
depends on both the workspace's index and the view's viewport, some
care is needed to prevent gestures/scrolling from interfering with
layout updates.

Clean that up by properly allocating workspaces in a row or column,
and use a translation to reflect the current scroll position.

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1345
2020-07-07 00:06:53 +02:00
d66cd0d206 workspacesView: Don't set full geometry
It's not used anymore.

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1345
2020-07-07 00:06:53 +02:00
ff13ad9e71 workspacesView: Stop using full geometry
Since the workspaces themselves stopped using it, there is little
reason for upholding the difference between "full" and "actual"
geometry.

Just base positioning/swiping on the view's allocation.

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1345
2020-07-07 00:06:53 +02:00
5e4b65d37e workspacesView: Use work area for default geometry
The workspace's layout manager keeps the workspace at the same ratio as
the work area, so it makes more sense to base the views' default geometry
on that as well than the monitor area we are using right now.

(It shouldn't matter much in practice, as this only affects views on
non-primary monitors where the work area usually matches the monitor area)

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1345
2020-07-07 00:06:53 +02:00
51fd0875d1 workspacesView: Simplify syncing actual geometry
We adjust the size and position of the primary view to match the workspaces
display, but views on other monitors are always set to fill their monitor.

Take that into account and create views with a fixed size and position, then
only sync the primary view to the new geometry.

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1345
2020-07-07 00:06:53 +02:00
75f8903c7e workspace: Use actual container allocation
We currently assume that the passed in Clutter.ActorBox matches
the container allocation, but in reality it is the container's
content area.

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1345
2020-07-07 00:06:53 +02:00
124eb1ca18 workspace: Account for window picker padding
Workspaces are supposed to request the work area as their preferred
size, however the widget will adjust the sizes returned by the
layout manager to account for borders and padding.

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1345
2020-07-07 00:06:53 +02:00
b5d925817f workspace: Disable preview overlays unless fully zoomed out
The overlays are only meant to be shown when the workspace is fully
zoomed out, not when using the floating layout or some in-between state.

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1345
2020-07-07 00:06:53 +02:00
c134091268 windowPreview: Allow to disable overlay
WindowPreviews now contain and manage overlaid elements like close
button or title label themselves. That's generally better, but right now
the only way to disable those overlays (for example during transitions)
is to prevent any hover or focus events from getting to the preview.

Instead, add some explicit API for enabling or disabling overlay support.

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1345
2020-07-07 00:06:49 +02:00
ff89693998 workspace: Handle minimized windows in layout
The new layout manager always uses the window's regular size and position
for the floating state, but the preview of minimized windows should be
hidden instead.

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1345
2020-07-07 00:05:36 +02:00
c26860dcb7 windowPreview: Ensure style as soon as preview is realized
For the windowPreview we need to ensure the style information of the
border and title is up-to-date when chromeWidths() or chromeHeights() is
called. Since the introduction of the WorkspaceLayout those functions
may be called during an allocation cycle, which means we should avoid
calling queuing relayouts inside them. Calling StWidgets ensure_style()
method will queue a relayout though in case the newly generated theme
node has a different geometry.

So avoid queueing a relayout during allocation cycles (and the warning
Clutter logs because of that) by ensuring the style of the border and
title earlier, as soon as the WindowPreview is attached to a stage.

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1305
2020-07-06 23:16:15 +02:00
6757c7d20a workspace: Animate opening new windows while in overview
Use the pivot point and scale to animate in new windows which are opened
while the overview is shown.

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1305
2020-07-06 23:16:15 +02:00
751189253a workspace: Use the new WorkspaceLayout for allocating window clones
Switch to the new WorkspaceLayout layout manager to allocate the window
clones of the overview properly using Clutters layouting mechanisms.

Since we now no longer make use of the fullGeometry, we can remove the
setFullGeometry() function from the Workspace class. Also we can stop
setting the actualGeometry on the Workspaces and WorkspaceViews and
instead just set the fixed position and size of the views to their
full or actual geometry. This also has the benefit that we no longer
have to set a custom clip, but can simply enable clip_to_allocation.

The geometry needs to be set inside a BEFORE_REDRAW later because
_updateWorkspacesActualGeometry() is called from a notify::allocation
handler.

This isn't doing any animations when showing/hiding the overview yet,
we'll add that in the next commit.

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1305
2020-07-06 23:16:15 +02:00
21187a4cec workspace: Introduce layout manager for allocating the Workspace
Add a new ClutterLayoutManager for layouting the workspaces of the
overview, WorkspaceLayout.

This layout manager integrates the existing LayoutStrategies used to
layout the window clones of the overview and supports freezing the
layout, animating between layout changes and adjusting the spacing for
the width and height of the window chrome. It also adds support for a
layout of the windows that looks the same as the actual workspace,
transitioning between that layout and the LayoutStrategy can be done by
setting the value of an StAdjustment, available using the
stateAdjustment getter function.

This will replace the current static-positioning based layouting of the
window clones in the next commit.

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1305
2020-07-06 23:16:15 +02:00
b7db56ca9b workspacesViews: Use translation for showing Workspaces
We're going to use fixed position for positioning workspaces when
they're allocated by their own layout manager, using those positions to
scroll between different workspaces interferes with that, so do that
using translations instead.

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1305
2020-07-06 23:16:15 +02:00
261d36ba72 keyboard: Request a bigger size in portrait orientation
In portrait orientation, we set the height to the preferred height
for the monitor width (or, if smaller, a third o the screen height).

However as the forWidth currently doesn't make a difference, the height
is effectively controlled by the natural height of the keys - which is
rather small.

Address this by making AspectContainer request an appropriate preferred
size based on the fixed ratio.

https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/2349
2020-07-06 15:16:35 +00:00
1e72874192 keyboard: Fix setting height in portrait orientation
get_preferred_height() returns both the minimum and natural height,
not a single size. Math.min() doesn't handle that and returns NaN,
whoops.

https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/2349
2020-07-06 15:16:35 +00:00
f29dbd1f18 shell/window-tracker: Match on WM_CLASS first
Currently our heuristics for matching a window to its app check
for the application ID before the WM_CLASS, as the ID is more
reliable in so far that it is outside the application's control
and so it cannot use it to spoof a different application.

However this also prevents applications with multiple .desktop
files like LibreOffice from matching any .desktop files other
than the one under the main ID.

Since we now no longer allow the WM_CLASS to match a .desktop
file that doesn't belong to the sandboxed application, we can
fix that issue by checking the WM_CLASS first, without opening
the door to spoofing.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/219
2020-07-06 14:59:51 +00:00
b60836932a shell/window-tracker: Enforce prefix for sandboxed applications
At least flatpak (no idea about snap, sorry) enforces that all .desktop
files exported by a sandboxed app use the application ID as prefix.

Add the same check when trying to find a match based on the WM_CLASS,
to prevent sandboxed apps from matching a .desktop file they do not
own.

At the moment this is unlikely as we check for a match on the
sandboxed app ID first, but we are about to change that.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/219
2020-07-06 14:59:51 +00:00
bf47d1b22d shell/window-tracker: Minor simplification
Switching to autocleanup gives us a better separation between the
app/no-app cases.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/219
2020-07-06 14:59:51 +00:00
4ea0fca4fc gdm: Introduce vmware credential manager for pre-authenticated logins
The previous commit implemented a new CredentialManager interface to
    facilitate adding additional providers for pre-authenticating the user
    at the login screen.

    This commit implements a new credential manager using that interface
    for vmware deployments.

    Closes: https://gitlab.gnome.org/GNOME/gnome-shell/issues/1983
2020-07-04 08:11:49 +08:00
809f820cd4 gdm: Refactor oVirt to a generic CredentialManager interface
Commit 4cda61a1 added support for pre-authenticated logins in
    oVirt environments. This feature prevents a user from having
    to type their password twice (once to the oVirt management machine,
    and then immediately again in the provisioned guest running gnome-shell).
    That feature is currently oVirt specific, but a similar feature would
    be useful in non-oVirt based virt farm environments.

    Toward that end, this commit generalizes the various aspects of the
    oVirt integration code, so that it can be reused in a subsequent
    commit for adding single sign on support in vmware deployments, too.

    Closes: https://gitlab.gnome.org/GNOME/gnome-shell/issues/1983
2020-07-04 08:11:49 +08:00
75235624b2 background: Use actor.content.background
Because actor.background no longer exists and emitted errors when
referenced.

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

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1343
2020-07-03 14:41:48 +08:00
5ea54426b9 st/adjustment: Add ::actor property
Will be used by transitions to set the timeline actor.

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1299
2020-07-02 20:50:03 +00:00
4aabcd9e7d shell/global: Adapt to after-paint signal type signature
A stage view parameter was added.

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1299
2020-07-02 20:50:03 +00:00
918b3eeb42 st/theme-node-transition: Pass actor when constructing timeline
Timelines now take an actor, to be able to derive an appropriate frame
clock, so pass the one of the actor we're transitioning on.

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1299
2020-07-02 20:50:03 +00:00
482c655590 messageTray: Remove SourceActorWithLabel class
https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1346
2020-07-01 20:20:26 -03:00
86b5a43008 shell/app: Add new get_icon() method
Now that we can always associate a GIcon with the app, add a method
to access it. While create_icon_texture() is still likely to be more
convenient in most cases, exposing the icon can still be useful, for
example to add it to a different kind of actor or to compare it with
other GIcons.

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1342
2020-07-01 12:42:57 +02:00
d7cb2eeebc st/texture-cache: Return a GIcon from bind_cairo_surface_property()
We still load the surface into an StImageContent, but instead of
adding the content to an actor we hand out, return the content
itself (as GIcon).

That means we lose the ability to specify an icon size, but as we
get the pixel data from a fixed-size surface anyway, that shouldn't
matter much in practice.

Not to mention that the function is only used for fallback X11 icons,
which are already shit more often than not.

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1342
2020-07-01 12:42:57 +02:00
770231c2d7 st/image-content: Implement GIcon interface
On the one hand, this is a bit of a stretch: StImageContent is what
we create from GIcons.

But on the other hand, there's some justification: StImageContent does
represent an image (and likely icon) after all, and there's some
precedent with GdkPixbuf.

In the end as we don't care about serialization or loading from other
API, we can go with a very crude implementation that allows us to
pass out a content as GIcon and use it directly when "loading" it.

We will use that soon to represent X11 window icons as GIcons, which
in turn will allow us to unify app icon handling.

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1342
2020-07-01 12:42:57 +02:00
ecdf62d63e st/viewport: Invalidate transform when it changes
Since ClutterActor now caches the whole transformation matrix for an
actor, we need to invalidate the cached transform if the matrix returned
by apply_transform() implementations changes.

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1308
2020-06-30 19:17:58 +02:00
d885486397 st/widget: Remove get_resource_scale function
ClutterActor provides the same function, but with a different return
value. So since we already switched to the ClutterActor implementation
in our C code, we can now safely remove st_widget_get_resource_scale()
and update the JS code that's still using the old API.

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1287
2020-06-30 13:42:18 +00:00
1524abc947 Switch to ClutterActors resource-scale-changed signal
Instead of using the "notify::resource-scale" signal and StWidgets
"resource-scale-changed" signal, use the new "resource-scale-changed"
signal of ClutterActor, which replaces its "resource-scale" property.

Since we'd now have two "resource-scale-changed" signals, one on
ClutterActor and one on StWidget, remove the StWidget one in favour of
the new one.

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1287
2020-06-30 13:42:18 +00:00
cb9842e4a4 Use new clutter_actor_get_resource_scale() API
Update the existing users of clutter_actor_get_resource_scale() to the
new API which doesn't return a boolean value.

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1287
2020-06-30 13:42:18 +00:00
140ab4dec1 unlockDialog: Fix scale-factor handling on multihead
The blur effect needs to take the scale-factor into account, so we
listen for scale changes. However we set up the signal handler when
creating a background, which is repeated for each monitor, and every
time the monitor configuration changes. But we only disconnect the
last handler that was connected, and only when we are destroyed,
not when recreating backgrounds.

Fix this by splitting out updating the effect parameters to a separate
method that iterates over all backgrounds, so we can simply set up the
handler from the constructor.

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1341
2020-06-30 13:12:08 +00:00
845122497b altTab: Remove down arrow when removing an app from switcher
The arrow of the removed app was still left in the list with the
visibility of the arrow still depending on the original list order. This
could either lead to apps with just one window now suddenly having a
down arrow or apps with multiple windows not having one. If the last
window in the list had a down arrow, it would have been displayed
outside the window switcher.

Fixes https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/2935

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1340
2020-06-29 22:51:41 +02:00
d51a622fc0 Update Latvian translation 2020-06-29 18:12:25 +00:00
e90466347a cleanup: Use Meta.Workspace.active property
https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1337
2020-06-29 17:09:38 +02:00
73f8c1c482 inhibitShortcutsDialog: Enable line wrapping for additional label
The inhibitShortcutsDialog can show an additional label which explains
how to restore shortcuts. This label is not managed by the
MessageDialogContent, so we need to enable line wrapping and disable
ellipsization ourselves.

Fixes https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/2616

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1336
2020-06-29 10:17:07 +00:00
0ff75941ea dialog: Return GLib.SOURCE_REMOVE instead of false
This is more readable than just returning false.

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1336
2020-06-29 10:17:07 +00:00
e4bb2037ca dialog: Check whether text changed when setting title or description
As usually with GObject setters, we should check whether the property
actually changed before setting the value and notifying the property. So
check whether the title or description text actually changed before
setting it.

This fixes a bug which makes the title flicker and change its size,
because when updating the title we remove the "leightweight" css class
and reapply it inside a later, which makes the title appear larger for
one frame.

Fixes https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/2574

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1336
2020-06-29 10:17:07 +00:00
481014ac9e st/viewport: Only extend child allocation when scrolled
When scrolled, the container's allocation is smaller than the allocation
of the content. To account for that, commit 2717ca9d08 added the
additional size reported by the layout manager to the content allocation.

However as it did so unconditionally, we now allow children to extend
outside the parent even when *not* scrolled, which breaks any constraints
set on the container (like "width" or "max-height").

Fix this by only extending the child allocation in scrollable dimensions.

https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/2491
2020-06-29 00:42:03 +02:00
6dbcb5f9da Update Kazakh translation 2020-06-27 18:29:23 +00:00
c1f06daf88 st/tests: Replace ClutterGroup by ClutterActor
ClutterGroup is deprecated and can be 1:1 replaced by ClutterActor,
so let's do it.

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1334
2020-06-26 21:03:57 +00:00
0717f76362 Replace anchor point by translation and pivot point
Anchor point is deprecated and will eventually be removed from
Mutter's Clutter. Replace them by a combination of pivot point
and translation.

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1334
2020-06-26 21:03:57 +00:00
da738988cd workspacesView: Small cleanup
scrollToActive() and friends are only used for handling the 'switch-workspace'
animation.

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1333
2020-06-26 16:19:57 +02:00
e86e88ea47 workspacesView: Don't make reactive
Since commit a11f417cd0, scroll events are handled by the SwipeTracker.
There's no other reason for the view to be reactive, so don't make it so.

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1333
2020-06-26 16:19:57 +02:00
ae338af1e8 st-label: Keep labels fully pre-rendered on the GPU
The performance of the icon grid was being hindered by a large number
of primitives (a few hundred) being copied from the CPU to the GPU on
each frame. This was first noticed in mutter#971 but we failed to
investigate all the issues at the time.

You can also see the high number using `COGL_DEBUG=batching` or
`COGL_DEBUG=disable-texturing`. So now it's obvious that high number is
every letter of every label being uploaded as a separate quad. Let's not
do that and instead treat the whole label as a single quad/texture.

Measured performance on an i7-7700 at UHD 3840x2160:

Journal entries per frame on the icon grid:
 * Before: 288 (18 KB copied from CPU to GPU)
 * After:   73 ( 4 KB copied from CPU to GPU)

Spring animation:
 * Before: 20-30 FPS, avg 22/peak 45 milliseconds per frame
 * After:  30-40 FPS, avg 14/peak 28 milliseconds per frame

Scrolling the icon grid:
 * Before: 15 FPS, 50 milliseconds per frame
 * After:  30 FPS, 28 milliseconds per frame

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1329
2020-06-25 09:09:36 +00:00
3f9cc0ed37 Update Kazakh translation
(cherry picked from commit d3384d29e4)
2020-06-25 04:34:40 +00:00
8f8ecdb983 appDisplay: Update folder dialog field before ungrabbing
Noticed while working on customizable folders. Calling GrabHelper.ungrab()
ends up calling FolderDialog.popdown(), but at this point the '_isOpen'
field isn't updated yet, so we end up calling popdown() twice.

Update the '_isOpen' field before ungrabbing.

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1332
2020-06-24 18:06:21 -03:00
8f547c9d5d iconGrid: Adjust animation delay
As per design feedback, adjust the animation delay to be shorter.

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1332
2020-06-24 18:06:21 -03:00
821f3e8ddf overview: Pass drag source on item-drag-* signals
Overview has signals to notify about starting, cancelling, and
finishing icon drags, but none of these signals pass the dragged
item to the callbacks.

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

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1332
2020-06-24 18:06:21 -03:00
81be25bbd6 Update Kazakh translation 2020-06-24 16:17:48 +00:00
26d27fdbf8 overview: Define ANIMATION_TIME earlier
Commit c7e597cf72 tried to improve the slide animations when entering
the overview by using the same time as the overall overview animation,
but in fact broke the animation most of the times.

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

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

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1331
2020-06-24 15:41:12 +02:00
c7e597cf72 overviewControls: Animate sidebars the same duration as windows
When you tap Super and see the sidebars and windows slide, it looks more
cohesive if those animations complete at the same time.

Previously there were 0.09 seconds difference between the two animations
which was enough to make it look slightly buggy. Now it doesn't.

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1289
2020-06-23 19:07:30 +00:00
e4db68a1da Revert "workspacesView: Work around spurious allocation changes"
We now found the underlying bug: The ControlsManager (which causes the
bad call to `_updateWorkspacesFullGeometry()`) is getting (re-)allocated
while we add the view to the overviewGroup actor because the
overviewGroup is already visible and the view is immediately getting
mapped by `clutter_actor_add_child_internal()`. That causes a
resource-scale calculation and that indirectly causes a call to
`_clutter_stage_maybe_relayout()` (explained more detailed in the last
commit).

So now that we got rid of the immediate relayout happening when mapping
the view, we can revert this fix.

This reverts commit 6cc19ee6f0.

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1315
2020-06-23 19:05:05 +00:00
980a90f8fb dateMenu: Do not ellipsize clock
This addresses the issue with ellipsized clock that occurs when using
extensions that move the clock from the middle to the side of the top
bar.

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1327

Signed-off-by: MOZGIII <mike-n@narod.ru>
2020-06-23 16:14:24 +00:00
87e4bf52b7 windowPreview: Fix a division by zero
When the bounding box size is 0 during allocation (which happens right
after creating a window for example), we're doing a division by zero and
end up with a NaN scale. This ends up making the childBox NaN, which
triggers an error in Clutters allocation machinery.

So fix that and fall back to a scale of 1 in case the bounding box is
empty.

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1320
2020-06-23 15:50:03 +00:00
a368df61ac volume: Update indicator when microphone volume changes
The current microphone indicator only indicates if the microphone is in
use. Users might be also interested if their microphone is recording
or is muted, this commit enables that without opening the pop-up
menu. The microphone icon changes itself, depending on the sensitivity
of the microphone. It behaves similar to the already existing volume
indicator.

https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/2902
2020-06-23 11:34:16 +02:00
5e66b104dc Updated Lithuanian translation 2020-06-21 22:18:03 +03:00
122 changed files with 7629 additions and 7691 deletions

35
NEWS
View File

@ -1,3 +1,38 @@
3.37.3
======
* Refactor and clean up window picker
[Jonas D., Florian; !1297, !1298, !1305, !1345, !1353]
* Move calendar events out of notifications list [Florian; !1282]
* Refine app folder dialogs [Georges; !1301]
* Hide switch-user button on lock screen if unsupported [Chingkai; #2687]
* Refactor and clean up app picker pagination [Georges; !1271]
* Add API to retrieve specified mimetypes from clipboards [Carlos; !1321]
* Support prepending workspace with horizontal layouts [Florian; #2916]
* Update microphone icon on input volume changes [fludixx; #2902]
* Cache labels on GPU [Daniel; !1329]
* Fix regressions in redesigned modal dialogs [Florian, Jonas D.; #2491, !1336]
* Use GIcon for all application icons [Florian; !1342]
* Support pre-authenticated logins in vmware environments [yun341; #1983]
* Better support sandboxed apps with multiple .desktop files [Florian; #219]
* Fix on-screen keyboard size in portrait orientation [Florian; #2349]
* Plugged leaks [Sebastian, Daniel, Florian; !1306, !1319, !1341]
* Misc. bug fixes and cleanups [Jonas D., Georges, Marco, Florian, Sebastian,
MOZGIII, Daniel, Mariana, Jonas Å.; !1296, !1295, #2643, !1300, !1309,
!1119, #2901, !1313, !1251, !1285, !1307, !1318, !1310, !1320, !1327, !1315,
!1289, !1331, !1332, !1333, !1334, !1340, !1287, !1308, !1346, !1299, !1343,
!1351, !1352, !1322]
Contributors:
Marco Trevisan (Treviño), Chingkai, Jonas Dreßler, Carlos Garnacho,
Sebastian Keller, MOZGIII, Florian Müllner, Georges Basile Stavracas Neto,
Mariana Picolo, Daniel van Vugt, fludixx, yun341, Jonas Ådahl
Translators:
Daniel Mustieles [es], Boyuan Yang [zh_CN], Yuri Chornoivan [uk],
Jordi Mas [ca], sicklylife [ja], Emin Tufan Çetin [tr],
Baurzhan Muftakhidinov [kk], Florentina Mușat [ro], Aurimas Černius [lt],
Rūdolfs Mazurs [lv]
3.37.2
======
* Add support for "PrefersNonDefaultGPU" desktop key [Bastien; !1226]

View File

@ -0,0 +1,191 @@
<!DOCTYPE node PUBLIC
'-//freedesktop//DTD D-BUS Object Introspection 1.0//EN'
'http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd'>
<node>
<!--
org.gnome.Mutter.ScreenCast:
@short_description: Screen cast interface
This API is private and not intended to be used outside of the integrated
system that uses libmutter. No compatibility between versions are
promised.
-->
<interface name="org.gnome.Mutter.ScreenCast">
<!--
CreateSession:
@properties: Properties
@session_path: Path to the new session object
* "remote-desktop-session-id" (s): The ID of a remote desktop session.
Remote desktop driven screen casts
are started and stopped by the remote
desktop session.
* "disable-animations" (b): Set to "true" if the screen cast application
would prefer animations to be globally
disabled, while the session is running. Default
is "false". Available since version 3.
-->
<method name="CreateSession">
<arg name="properties" type="a{sv}" direction="in" />
<arg name="session_path" type="o" direction="out" />
</method>
<!--
Version:
@short_description: API version
-->
<property name="Version" type="i" access="read" />
</interface>
<!--
org.gnome.Mutter.ScreenCast.Session:
@short_description: Screen cast session
-->
<interface name="org.gnome.Mutter.ScreenCast.Session">
<!--
Start:
Start the screen cast session
-->
<method name="Start" />
<!--
Stop:
Stop the screen cast session
-->
<method name="Stop" />
<!--
Closed:
The session has closed.
-->
<signal name="Closed" />
<!--
RecordMonitor:
@connector: Connector of the monitor to record
@properties: Properties
@stream_path: Path to the new stream object
Record a single monitor.
Available @properties include:
* "cursor-mode" (u): Cursor mode. Default: 'hidden' (see below)
Available since API version 2.
* "is-recording" (b): Whether this is a screen recording. May be
be used for choosing panel icon.
Default: false. Available since API version 4.
Available cursor mode values:
0: hidden - cursor is not included in the stream
1: embedded - cursor is included in the framebuffer
2: metadata - cursor is included as metadata in the PipeWire stream
-->
<method name="RecordMonitor">
<arg name="connector" type="s" direction="in" />
<arg name="properties" type="a{sv}" direction="in" />
<arg name="stream_path" type="o" direction="out" />
</method>
<!--
RecordWindow:
@properties: Properties used determining what window to select
@stream_path: Path to the new stream object
Supported since API version 2.
Record a single window. The cursor will not be included.
Available @properties include:
* "window-id" (t): Id of the window to record.
* "cursor-mode" (u): Cursor mode. Default: 'hidden' (see RecordMonitor).
* "is-recording" (b): Whether this is a screen recording. May be
be used for choosing panel icon.
Default: false. Available since API version 4.
-->
<method name="RecordWindow">
<arg name="properties" type="a{sv}" direction="in" />
<arg name="stream_path" type="o" direction="out" />
</method>
<!--
RecordArea:
@x: X position of the recorded area
@y: Y position of the recorded area
@width: width of the recorded area
@height: height of the recorded area
@properties: Properties
@stream_path: Path to the new stream object
Record an area of the stage. The coordinates are in stage coordinates.
The size of the stream does not necessarily match the size of the
recorded area, and will depend on DPI scale of the affected monitors.
Available @properties include:
* "cursor-mode" (u): Cursor mode. Default: 'hidden' (see below)
Available since API version 2.
* "is-recording" (b): Whether this is a screen recording. May be
be used for choosing panel icon.
Default: false. Available since API version 4.
Available cursor mode values:
0: hidden - cursor is not included in the stream
1: embedded - cursor is included in the framebuffer
2: metadata - cursor is included as metadata in the PipeWire stream
-->
<method name="RecordArea">
<arg name="x" type="i" direction="in" />
<arg name="y" type="i" direction="in" />
<arg name="width" type="i" direction="in" />
<arg name="height" type="i" direction="in" />
<arg name="properties" type="a{sv}" direction="in" />
<arg name="stream_path" type="o" direction="out" />
</method>
</interface>
<!--
org.gnome.Mutter.ScreenCast.Stream:
@short_description: Screen cast stream
-->
<interface name="org.gnome.Mutter.ScreenCast.Stream">
<!--
PipeWireStreamAdded:
@short_description: Pipewire stream added
A signal emitted when PipeWire stream for the screen cast stream has
been created. The @node_id corresponds to the PipeWire stream node.
-->
<signal name="PipeWireStreamAdded">
<annotation name="org.gtk.GDBus.C.Name" value="pipewire-stream-added"/>
<arg name="node_id" type="u" direction="out" />
</signal>
<!--
Parameters:
@short_description: Optional stream parameters
Available parameters include:
* "position" (ii): Position of the source of the stream in the
compositor coordinate space.
* "size" (ii): Size of the source of the stream in the compositor
coordinate space.
-->
<property name="Parameters" type="a{sv}" access="read" />
</interface>
</node>

View File

@ -70,6 +70,14 @@
-->
<property name="AnimationsEnabled" type="b" access="read"/>
<!--
ScreenSize:
@short_description: The size of the screen
Since: 3
-->
<property name="ScreenSize" type="(ii)" access="read"/>
<property name="version" type="u" access="read"/>
</interface>
</node>

View File

@ -28,6 +28,7 @@
<file preprocess="xml-stripblanks">org.freedesktop.UPower.xml</file>
<file preprocess="xml-stripblanks">org.gnome.Magnifier.xml</file>
<file preprocess="xml-stripblanks">org.gnome.Magnifier.ZoomRegion.xml</file>
<file preprocess="xml-stripblanks">org.gnome.Mutter.ScreenCast.xml</file>
<file preprocess="xml-stripblanks">org.gnome.ScreenSaver.xml</file>
<file preprocess="xml-stripblanks">org.gnome.SessionManager.EndSessionDialog.xml</file>
<file preprocess="xml-stripblanks">org.gnome.SessionManager.Inhibitor.xml</file>

View File

@ -6,25 +6,25 @@
<file>checkbox-off-focused.svg</file>
<file>checkbox-off.svg</file>
<file>checkbox.svg</file>
<file alias="icons/color-pick.svg">color-pick.svg</file>
<file alias="icons/scalable/actions/color-pick.svg">color-pick.svg</file>
<file>dash-placeholder.svg</file>
<file>gnome-shell.css</file>
<file>gnome-shell-high-contrast.css</file>
<file alias="icons/message-indicator-symbolic.svg">message-indicator-symbolic.svg</file>
<file alias="icons/scalable/status/message-indicator-symbolic.svg">message-indicator-symbolic.svg</file>
<file>no-events.svg</file>
<file>no-notifications.svg</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>
<file alias="icons/pointer-double-click-symbolic.svg">pointer-double-click-symbolic.svg</file>
<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 alias="icons/scalable/status/eye-open-negative-filled-symbolic.svg">eye-open-negative-filled-symbolic.svg</file>
<file alias="icons/scalable/status/eye-not-looking-symbolic.svg">eye-not-looking-symbolic.svg</file>
<file alias="icons/scalable/actions/pointer-double-click-symbolic.svg">pointer-double-click-symbolic.svg</file>
<file alias="icons/scalable/actions/pointer-drag-symbolic.svg">pointer-drag-symbolic.svg</file>
<file alias="icons/scalable/actions/pointer-primary-click-symbolic.svg">pointer-primary-click-symbolic.svg</file>
<file alias="icons/scalable/actions/pointer-secondary-click-symbolic.svg">pointer-secondary-click-symbolic.svg</file>
<file alias="icons/scalable/status/keyboard-caps-lock-filled-symbolic.svg">keyboard-caps-lock-filled-symbolic.svg</file>
<file alias="icons/scalable/status/keyboard-enter-symbolic.svg">keyboard-enter-symbolic.svg</file>
<file alias="icons/scalable/status/keyboard-hide-symbolic.svg">keyboard-hide-symbolic.svg</file>
<file alias="icons/scalable/status/keyboard-layout-filled-symbolic.svg">keyboard-layout-filled-symbolic.svg</file>
<file alias="icons/scalable/status/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>

View File

@ -1,10 +0,0 @@
[Unit]
Description=GNOME Shell on X11
DefaultDependencies=no
Requisite=gnome-session-initialized.target
PartOf=gnome-session-initialized.target
Before=gnome-session-initialized.target
Requires=gnome-shell-x11.service
After=gnome-shell-x11.service

View File

@ -101,22 +101,21 @@ if have_systemd
unitconf.set('bindir', bindir)
configure_file(
input: 'gnome-shell-x11.service.in',
output: 'gnome-shell-x11.service',
input: 'org.gnome.Shell@x11.service.in',
output: 'org.gnome.Shell@x11.service',
configuration: unitconf,
install_dir: systemduserunitdir
)
configure_file(
input: 'gnome-shell-wayland.service.in',
output: 'gnome-shell-wayland.service',
input: 'org.gnome.Shell@wayland.service.in',
output: 'org.gnome.Shell@wayland.service',
configuration: unitconf,
install_dir: systemduserunitdir
)
units = files('gnome-shell-x11.target',
'gnome-shell-wayland.target',
'gnome-shell-disable-extensions.service')
units = files('org.gnome.Shell.target',
'org.gnome.Shell-disable-extensions.service')
install_data(units, install_dir: systemduserunitdir)
endif

View File

@ -6,5 +6,5 @@ Requisite=gnome-session-initialized.target
PartOf=gnome-session-initialized.target
Before=gnome-session-initialized.target
Requires=gnome-shell-wayland.service
After=gnome-shell-wayland.service
Wants=org.gnome.Shell@wayland.service
Wants=org.gnome.Shell@x11.service

View File

@ -1,7 +1,7 @@
[Unit]
Description=GNOME Shell on Wayland
# On wayland, force a session shutdown
OnFailure=gnome-shell-disable-extensions.service gnome-session-shutdown.target
OnFailure=org.gnome.Shell-disable-extensions.service gnome-session-shutdown.target
OnFailureJobMode=replace-irreversibly
CollectMode=inactive-or-failed
RefuseManualStart=on
@ -13,18 +13,21 @@ Requisite=gnome-session-initialized.target
PartOf=gnome-session-initialized.target
Before=gnome-session-initialized.target
# The units already conflict because they use the same BusName
#Conflicts=gnome-shell-x11.service
[Service]
Slice=session.slice
Type=notify
# NOTE: This can be replaced with ConditionEnvironment=XDG_SESSION_TYPE=%I
# with systemd >= 245. Also, the current solution is kind of painful
# as systemd had a bug where it retries the condition.
# Only start if the template instance matches the session type.
ExecCondition=/bin/sh -c 'test "$XDG_SESSION_TYPE" = "%I" || exit 2'
ExecStart=@bindir@/gnome-shell
# Exit code 1 means we are probably *not* dealing with an extension failure
SuccessExitStatus=1
# unset some environment variables that were set by the shell and won't work now that the shell is gone
ExecStopPost=-systemctl --user unset-environment GNOME_SETUP_DISPLAY WAYLAND_DISPLAY DISPLAY XAUTHORITY
# Exit code 1 means we are probably *not* dealing with an extension failure
SuccessExitStatus=1
# On wayland we cannot restart
Restart=no
# Kill any stubborn child processes after this long

View File

@ -1,7 +1,7 @@
[Unit]
Description=GNOME Shell on X11
# On X11, try to show the GNOME Session Failed screen
OnFailure=gnome-shell-disable-extensions.service gnome-session-failed.target
OnFailure=org.gnome.Shell-disable-extensions.service gnome-session-failed.target
OnFailureJobMode=replace
CollectMode=inactive-or-failed
RefuseManualStart=on
@ -13,18 +13,24 @@ Requisite=gnome-session-initialized.target
PartOf=gnome-session-initialized.target
Before=gnome-session-initialized.target
# The units already conflict because they use the same BusName
#Conflicts=gnome-shell-wayland.service
# Limit startup frequency more than the default
StartLimitIntervalSec=15s
StartLimitBurst=3
[Service]
Slice=session.slice
Type=notify
# NOTE: This can be replaced with ConditionEnvironment=XDG_SESSION_TYPE=%I
# with systemd >= 245. Also, the current solution is kind of painful
# as systemd had a bug where it retries the condition.
# Only start if the template instance matches the session type.
ExecCondition=/bin/sh -c 'test "$XDG_SESSION_TYPE" = "%I" || exit 2'
ExecStart=@bindir@/gnome-shell
# Exit code 1 means we are probably *not* dealing with an extension failure
SuccessExitStatus=1
# On X11 we do not need to unset any variables
# On X11 we want to restart on-success (Alt+F2 + r) and on-failure.
Restart=always
# Do not wait before restarting the shell

View File

@ -109,6 +109,17 @@
the shell.
</description>
</key>
<key name="app-picker-layout" type="aa{sv}">
<default>[]</default>
<summary>Layout of the app picker</summary>
<description>
Layout of the app picker. Each entry in the array is a page. Pages are
stored in the order they appear in GNOME Shell. Each page contains an
“application id” → 'data' pair. Currently, the following values are
stored as 'data':
• “position”: the position of the application icon in the page
</description>
</key>
<child name="keybindings" schema="org.gnome.shell.keybindings"/>
</schema>

View File

@ -1,7 +1,7 @@
/* Window Picker */
$window_picker_spacing: $base_spacing * 2; // 16px
$window_picker_padding: $base_padding * 2; // 16px
$window_picker_spacing: $base_spacing; // 6px
$window_picker_padding: $base_padding * 2; // 12px
$window_thumbnail_border_color:transparentize($selected_fg_color, 0.65);
@ -13,8 +13,8 @@ $window_clone_border_size: 6px;
// Window picker
.window-picker {
// Space between window thumbnails
-horizontal-spacing: $window_picker_spacing;
-vertical-spacing: $window_picker_spacing;
spacing: $window_picker_spacing;
// Padding for container around window thumbnails
padding: $window_picker_padding;

View File

@ -3,13 +3,8 @@ private_headers = [
'gactionobservable.h',
'gactionobserver.h',
'shell-network-agent.h',
'shell-recorder-src.h'
]
if not enable_recorder
private_headers += 'shell-recorder.h'
endif
exclude_directories = [
'calendar-server',
'hotplug-sniffer',

View File

@ -25,6 +25,8 @@ var ServiceImplementation = class {
// subclasses may override this to disable automatic shutdown
this._autoShutdown = true;
this._queueShutdownCheck();
}
// subclasses may override this to own additional names

View File

@ -1,2 +1,6 @@
.expander-frame > * { border-top-width: 0; }
.expander-toolbar { border: 0 solid @borders; border-top-width: 1px; }
.expander-toolbar {
border: 0 solid @borders;
border-top-width: 1px;
padding: 3px;
}

View File

@ -128,7 +128,7 @@ var ExtensionsService = class extends ServiceImplementation {
externalWindow = Shew.ExternalWindow.new_from_handle(parentWindow);
if (externalWindow)
externalWindow.set_parent_of(window.window);
externalWindow.set_parent_of(window.get_surface());
if (options.modal)
window.modal = options.modal.get_boolean();
@ -156,7 +156,6 @@ var ExtensionPrefsDialog = GObject.registerClass({
GTypeName: 'ExtensionPrefsDialog',
Template: 'resource:///org/gnome/Shell/Extensions/ui/extension-prefs-dialog.ui',
InternalChildren: [
'headerBar',
'stack',
'expander',
'expanderArrow',
@ -165,24 +164,24 @@ var ExtensionPrefsDialog = GObject.registerClass({
],
}, class ExtensionPrefsDialog extends Gtk.Window {
_init(extension) {
super._init();
super._init({
title: extension.metadata.name,
});
this._uuid = extension.uuid;
this._url = extension.metadata.url || '';
this._headerBar.title = extension.metadata.name;
this._actionGroup = new Gio.SimpleActionGroup();
this.insert_action_group('win', this._actionGroup);
this._initActions();
this._addCustomStylesheet();
this._gesture = new Gtk.GestureMultiPress({
widget: this._expander,
this._gesture = new Gtk.GestureClick({
button: 0,
exclusive: true,
});
this._expander.add_controller(this._gesture);
this._gesture.connect('released', (gesture, nPress) => {
if (nPress === 1)
@ -205,7 +204,7 @@ var ExtensionPrefsDialog = GObject.registerClass({
prefsModule.init(extension.metadata);
const widget = prefsModule.buildPrefsWidget();
this._stack.add(widget);
this._stack.add_named(widget, 'prefs');
this._stack.visible_child = widget;
} catch (e) {
this._setError(e);
@ -267,7 +266,7 @@ var ExtensionPrefsDialog = GObject.registerClass({
} catch (e) {
logError(e, 'Failed to add application style');
}
Gtk.StyleContext.add_provider_for_screen(Gdk.Screen.get_default(),
Gtk.StyleContext.add_provider_for_display(Gdk.Display.get_default(),
provider,
Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION);
}

View File

@ -1,7 +1,7 @@
/* exported main */
imports.gi.versions.Gdk = '3.0';
imports.gi.versions.Gtk = '3.0';
imports.gi.versions.Gdk = '4.0';
imports.gi.versions.Gtk = '4.0';
const { Gtk } = imports.gi;
const pkg = imports.package;
@ -10,7 +10,7 @@ const { DBusService } = imports.dbusService;
const { ExtensionsService } = imports.extensionsService;
function main() {
Gtk.init(null);
Gtk.init();
pkg.initFormat();
const service = new DBusService(

View File

@ -1,38 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.1 -->
<interface>
<requires lib="gtk+" version="3.20"/>
<template class="ExtensionPrefsDialog" parent="GtkWindow">
<property name="default_width">600</property>
<property name="default_height">400</property>
<child type="titlebar">
<object class="GtkHeaderBar" id="headerBar">
<property name="visible">True</property>
<property name="show_close_button">True</property>
<object class="GtkHeaderBar">
<property name="show-title-buttons">True</property>
</object>
</child>
<child>
<object class="GtkStack" id="stack">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkScrolledWindow">
<property name="visible">True</property>
<property name="hscrollbar_policy">never</property>
<property name="propagate_natural_height">True</property>
<child>
<object class="GtkViewport">
<property name="visible">True</property>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="orientation">vertical</property>
<property name="margin">100</property>
<property name="margin_bottom">60</property>
<property name="margin-start">100</property>
<property name="margin-end">100</property>
<property name="margin-top">100</property>
<property name="margin-bottom">60</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"/> <!-- x-large -->
@ -44,44 +38,33 @@
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="label" translatable="yes">Were very sorry, but theres been a problem: the settings for this extension cant be displayed. We recommend that you report the issue to the extension authors.</property>
<property name="justify">center</property>
<property name="wrap">True</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
</object>
</child>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="orientation">vertical</property>
<property name="margin_top">12</property>
<property name="margin-top">12</property>
<child>
<object class="GtkFrame" id="expander">
<property name="visible">True</property>
<property name="hexpand">True</property>
<property name="shadow_type">in</property>
<child>
<object class="GtkEventBox">
<property name="visible">True</property>
<object class="GtkBox">
<property name="margin-start">12</property>
<property name="margin-end">12</property>
<property name="margin-top">12</property>
<property name="margin-bottom">12</property>
<property name="spacing">6</property>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="margin">12</property>
<property name="spacing">6</property>
<child>
<object class="GtkImage" id="expanderArrow">
<property name="visible">True</property>
<property name="icon_name">pan-end-symbolic</property>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="label" translatable="yes">Technical Details</property>
</object>
</child>
<object class="GtkImage" id="expanderArrow">
<property name="icon_name">pan-end-symbolic</property>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="label" translatable="yes">Technical Details</property>
</object>
</child>
</object>
@ -90,22 +73,16 @@
</child>
<child>
<object class="GtkRevealer" id="revealer">
<property name="visible">True</property>
<child>
<object class="GtkFrame">
<property name="visible">True</property>
<property name="shadow_type">in</property>
<style>
<class name="expander-frame"/>
</style>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkTextView" id="errorView">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="monospace">True</property>
<property name="editable">False</property>
<property name="wrap_mode">word</property>
@ -116,63 +93,34 @@
</object>
</child>
<child>
<object class="GtkToolbar">
<property name="visible">True</property>
<object class="GtkBox">
<style>
<class name="expander-toolbar"/>
</style>
<child>
<object class="GtkToolItem">
<property name="visible">True</property>
<child>
<object class="GtkButton">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="action_name">win.copy-error</property>
<style>
<class name="flat"/>
<class name="image-button"/>
</style>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="icon_name">edit-copy-symbolic</property>
</object>
</child>
</object>
</child>
<object class="GtkButton">
<property name="receives_default">True</property>
<property name="action_name">win.copy-error</property>
<property name="has-frame">False</property>
<property name="icon-name">edit-copy-symbolic</property>
</object>
</child>
<child>
<object class="GtkSeparatorToolItem">
<property name="visible">True</property>
<property name="draw">False</property>
<object class="GtkLabel">
<property name="hexpand">True</property>
</object>
<packing>
<property name="expand">True</property>
</packing>
</child>
<child>
<object class="GtkToolItem">
<property name="visible">True</property>
<child>
<object class="GtkButton" id="homeButton">
<property name="visible"
bind-source="homeButton"
bind-property="sensitive"
bind-flags="sync-create"/>
<property name="label" translatable="yes">Homepage</property>
<property name="tooltip_text" translatable="yes">Visit extension homepage</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="no_show_all">True</property>
<property name="action_name">win.show-url</property>
<style>
<class name="flat"/>
</style>
</object>
</child>
<object class="GtkButton" id="homeButton">
<property name="visible"
bind-source="homeButton"
bind-property="sensitive"
bind-flags="sync-create"/>
<property name="label" translatable="yes">Homepage</property>
<property name="tooltip_text" translatable="yes">Visit extension homepage</property>
<property name="receives_default">True</property>
<property name="has-frame">False</property>
<property name="action_name">win.show-url</property>
</object>
</child>
</object>

View File

@ -8,6 +8,12 @@ dbus_services = {
'org.gnome.Shell.Notifications': 'notifications',
}
if enable_recorder
dbus_services += {
'org.gnome.Shell.Screencast': 'screencast',
}
endif
config_dir = '@0@/..'.format(meson.current_build_dir())
foreach service, dir : dbus_services

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<gresources>
<gresource prefix="/org/gnome/Shell/Screencast/js">
<file>main.js</file>
<file>screencastService.js</file>
<file>dbusService.js</file>
<file>misc/config.js</file>
<file>misc/fileUtils.js</file>
</gresource>
</gresources>

View File

@ -0,0 +1,11 @@
/* exported main */
const { DBusService } = imports.dbusService;
const { ScreencastService } = imports.screencastService;
function main() {
const service = new DBusService(
'org.gnome.Shell.Screencast',
new ScreencastService());
service.run();
}

View File

@ -0,0 +1,458 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
/* exported ScreencastService */
const { Gio, GLib, Gst } = imports.gi;
const { loadInterfaceXML, loadSubInterfaceXML } = imports.misc.fileUtils;
const { ServiceImplementation } = imports.dbusService;
const ScreencastIface = loadInterfaceXML('org.gnome.Shell.Screencast');
const IntrospectIface = loadInterfaceXML('org.gnome.Shell.Introspect');
const IntrospectProxy = Gio.DBusProxy.makeProxyWrapper(IntrospectIface);
const ScreenCastIface = loadSubInterfaceXML(
'org.gnome.Mutter.ScreenCast', 'org.gnome.Mutter.ScreenCast');
const ScreenCastSessionIface = loadSubInterfaceXML(
'org.gnome.Mutter.ScreenCast.Session', 'org.gnome.Mutter.ScreenCast');
const ScreenCastStreamIface = loadSubInterfaceXML(
'org.gnome.Mutter.ScreenCast.Stream', 'org.gnome.Mutter.ScreenCast');
const ScreenCastProxy = Gio.DBusProxy.makeProxyWrapper(ScreenCastIface);
const ScreenCastSessionProxy = Gio.DBusProxy.makeProxyWrapper(ScreenCastSessionIface);
const ScreenCastStreamProxy = Gio.DBusProxy.makeProxyWrapper(ScreenCastStreamIface);
const DEFAULT_PIPELINE = 'vp8enc min_quantizer=13 max_quantizer=13 cpu-used=5 deadline=1000000 threads=%T ! queue ! webmmux';
const DEFAULT_FRAMERATE = 30;
const DEFAULT_DRAW_CURSOR = true;
const PipelineState = {
INIT: 0,
PLAYING: 1,
FLUSHING: 2,
STOPPED: 3,
};
const SessionState = {
INIT: 0,
ACTIVE: 1,
STOPPED: 2,
};
var Recorder = class {
constructor(sessionPath, x, y, width, height, filePath, options,
invocation,
onErrorCallback) {
this._startInvocation = invocation;
this._dbusConnection = invocation.get_connection();
this._onErrorCallback = onErrorCallback;
this._stopInvocation = null;
this._pipelineIsPlaying = false;
this._sessionIsActive = false;
this._x = x;
this._y = y;
this._width = width;
this._height = height;
this._filePath = filePath;
this._pipelineString = DEFAULT_PIPELINE;
this._framerate = DEFAULT_FRAMERATE;
this._drawCursor = DEFAULT_DRAW_CURSOR;
this._applyOptions(options);
this._watchSender(invocation.get_sender());
this._initSession(sessionPath);
}
_applyOptions(options) {
for (const option in options)
options[option] = options[option].deep_unpack();
if (options['pipeline'] !== undefined)
this._pipelineString = options['pipeline'];
if (options['framerate'] !== undefined)
this._framerate = options['framerate'];
if ('draw-cursor' in options)
this._drawCursor = options['draw-cursor'];
}
_watchSender(sender) {
this._nameWatchId = this._dbusConnection.watch_name(
sender,
Gio.BusNameWatcherFlags.NONE,
null,
this._senderVanished.bind(this));
}
_unwatchSender() {
if (this._nameWatchId !== 0) {
this._dbusConnection.unwatch_name(this._nameWatchId);
this._nameWatchId = 0;
}
}
_senderVanished() {
this._unwatchSender();
this.stopRecording(null);
}
_notifyStopped() {
this._unwatchSender();
if (this._onStartedCallback)
this._onStartedCallback(this, false);
else if (this._onStoppedCallback)
this._onStoppedCallback(this);
else
this._onErrorCallback(this);
}
_onSessionClosed() {
switch (this._pipelineState) {
case PipelineState.STOPPED:
break;
default:
this._pipeline.set_state(Gst.State.NULL);
log(`Unexpected pipeline state: ${this._pipelineState}`);
break;
}
this._notifyStopped();
}
_initSession(sessionPath) {
this._sessionProxy = new ScreenCastSessionProxy(Gio.DBus.session,
'org.gnome.Mutter.ScreenCast',
sessionPath);
this._sessionProxy.connectSignal('Closed', this._onSessionClosed.bind(this));
}
_startPipeline(nodeId) {
this._ensurePipeline(nodeId);
const bus = this._pipeline.get_bus();
bus.add_watch(bus, this._onBusMessage.bind(this));
this._pipeline.set_state(Gst.State.PLAYING);
this._pipelineState = PipelineState.PLAYING;
this._onStartedCallback(this, true);
this._onStartedCallback = null;
}
startRecording(onStartedCallback) {
this._onStartedCallback = onStartedCallback;
const [streamPath] = this._sessionProxy.RecordAreaSync(
this._x, this._y,
this._width, this._height,
{
'is-recording': GLib.Variant.new('b', true),
'cursor-mode': GLib.Variant.new('u', this._drawCursor ? 1 : 0),
});
this._streamProxy = new ScreenCastStreamProxy(Gio.DBus.session,
'org.gnome.ScreenCast.Stream',
streamPath);
this._streamProxy.connectSignal('PipeWireStreamAdded',
(proxy, sender, params) => {
const [nodeId] = params;
this._startPipeline(nodeId);
});
this._sessionProxy.StartSync();
this._sessionState = SessionState.ACTIVE;
}
stopRecording(onStoppedCallback) {
this._pipelineState = PipelineState.FLUSHING;
this._onStoppedCallback = onStoppedCallback;
this._pipeline.send_event(Gst.Event.new_eos());
}
_stopSession() {
this._sessionProxy.StopSync();
this._sessionState = SessionState.STOPPED;
}
_onBusMessage(bus, message, _) {
switch (message.type) {
case Gst.MessageType.EOS:
this._pipeline.set_state(Gst.State.NULL);
switch (this._pipelineState) {
case PipelineState.FLUSHING:
this._pipelineState = PipelineState.STOPPED;
break;
default:
break;
}
switch (this._sessionState) {
case SessionState.ACTIVE:
this._stopSession();
break;
case SessionState.STOPPED:
this._notifyStopped();
break;
default:
break;
}
break;
default:
break;
}
return true;
}
_substituteThreadCount(pipelineDescr) {
const numProcessors = GLib.get_num_processors();
const numThreads = Math.min(Math.max(1, numProcessors), 64);
return pipelineDescr.replace(/%T/, numThreads);
}
_ensurePipeline(nodeId) {
const framerate = this._framerate;
let fullPipeline = `
pipewiresrc path=${nodeId}
do-timestamp=true
keepalive-time=1000
resend-last=true !
video/x-raw,max-framerate=${framerate}/1 !
videoconvert !
${this._pipelineString} !
filesink location=${this._filePath}`;
fullPipeline = this._substituteThreadCount(fullPipeline);
this._pipeline = Gst.parse_launch_full(fullPipeline,
null,
Gst.ParseFlags.FATAL_ERRORS);
}
};
var ScreencastService = class extends ServiceImplementation {
constructor() {
super(ScreencastIface, '/org/gnome/Shell/Screencast');
Gst.init(null);
this._recorders = new Map();
this._senders = new Map();
this._lockdownSettings = new Gio.Settings({
schema_id: 'org.gnome.desktop.lockdown',
});
this._proxy = new ScreenCastProxy(Gio.DBus.session,
'org.gnome.Mutter.ScreenCast',
'/org/gnome/Mutter/ScreenCast');
this._introspectProxy = new IntrospectProxy(Gio.DBus.session,
'org.gnome.Shell.Introspect',
'/org/gnome/Shell/Introspect');
}
_removeRecorder(sender) {
this._recorders.delete(sender);
if (this._recorders.size === 0)
this.release();
}
_addRecorder(sender, recorder) {
this._recorders.set(sender, recorder);
if (this._recorders.size === 1)
this.hold();
}
_getAbsolutePath(filename) {
if (GLib.path_is_absolute(filename))
return filename;
let videoDir = GLib.get_user_special_dir(GLib.UserDirectory.DIRECTORY_VIDEOS);
if (!GLib.file_test(videoDir, GLib.FileTest.EXISTS))
videoDir = GLib.get_home_dir();
return GLib.build_filenamev([videoDir, filename]);
}
_generateFilePath(template) {
let filename = '';
let escape = false;
[...template].forEach(c => {
if (escape) {
switch (c) {
case '%':
filename += '%';
break;
case 'd': {
const datetime = GLib.DateTime.new_now_local();
const datestr = datetime.format('%0x');
const datestrEscaped = datestr.replace(/\//g, '-');
filename += datestrEscaped;
break;
}
case 't': {
const datetime = GLib.DateTime.new_now_local();
const datestr = datetime.format('%0X');
const datestrEscaped = datestr.replace(/\//g, ':');
filename += datestrEscaped;
break;
}
default:
log(`Warning: Unknown escape ${c}`);
}
escape = false;
} else if (c === '%') {
escape = true;
} else {
filename += c;
}
});
if (escape)
filename += '%';
return this._getAbsolutePath(filename);
}
ScreencastAsync(params, invocation) {
let returnValue = [false, ''];
if (this._lockdownSettings.get_boolean('disable-save-to-disk')) {
invocation.return_value(GLib.Variant.new('(bs)', returnValue));
return;
}
const sender = invocation.get_sender();
if (this._recorders.get(sender)) {
invocation.return_value(GLib.Variant.new('(bs)', returnValue));
return;
}
const [sessionPath] = this._proxy.CreateSessionSync({});
const [fileTemplate, options] = params;
const [screenWidth, screenHeight] = this._introspectProxy.ScreenSize;
const filePath = this._generateFilePath(fileTemplate);
let recorder;
try {
recorder = new Recorder(
sessionPath,
0, 0,
screenWidth, screenHeight,
fileTemplate,
options,
invocation,
_recorder => this._removeRecorder(sender));
} catch (error) {
log(`Failed to create recorder: ${error.message}`);
invocation.return_value(GLib.Variant.new('(bs)', returnValue));
return;
}
this._addRecorder(sender, recorder);
try {
recorder.startRecording(
(_, result) => {
if (result) {
returnValue = [true, filePath];
invocation.return_value(GLib.Variant.new('(bs)', returnValue));
} else {
this._removeRecorder(sender);
invocation.return_value(GLib.Variant.new('(bs)', returnValue));
}
});
} catch (error) {
log(`Failed to start recorder: ${error.message}`);
this._removeRecorder(sender);
invocation.return_value(GLib.Variant.new('(bs)', returnValue));
}
}
ScreencastAreaAsync(params, invocation) {
let returnValue = [false, ''];
if (this._lockdownSettings.get_boolean('disable-save-to-disk')) {
invocation.return_value(GLib.Variant.new('(bs)', returnValue));
return;
}
const sender = invocation.get_sender();
if (this._recorders.get(sender)) {
invocation.return_value(GLib.Variant.new('(bs)', returnValue));
return;
}
const [sessionPath] = this._proxy.CreateSessionSync({});
const [x, y, width, height, fileTemplate, options] = params;
const filePath = this._generateFilePath(fileTemplate);
let recorder;
try {
recorder = new Recorder(
sessionPath,
x, y,
width, height,
filePath,
options,
invocation,
_recorder => this._removeRecorder(sender));
} catch (error) {
log(`Failed to create recorder: ${error.message}`);
invocation.return_value(GLib.Variant.new('(bs)', returnValue));
return;
}
this._addRecorder(sender, recorder);
try {
recorder.startRecording(
(_, result) => {
if (result) {
returnValue = [true, filePath];
invocation.return_value(GLib.Variant.new('(bs)', returnValue));
} else {
this._removeRecorder(sender);
invocation.return_value(GLib.Variant.new('(bs)', returnValue));
}
});
} catch (error) {
log(`Failed to start recorder: ${error.message}`);
this._removeRecorder(sender);
invocation.return_value(GLib.Variant.new('(bs)', returnValue));
}
}
StopScreencastAsync(params, invocation) {
const sender = invocation.get_sender();
const recorder = this._recorders.get(sender);
if (!recorder) {
invocation.return_value(GLib.Variant.new('(b)', [false]));
return;
}
recorder.stopRecording(() => {
this._removeRecorder(sender);
invocation.return_value(GLib.Variant.new('(b)', [true]));
});
}
};

View File

@ -71,7 +71,7 @@ var AuthPrompt = GObject.registerClass({
this._userVerifier.connect('verification-complete', this._onVerificationComplete.bind(this));
this._userVerifier.connect('reset', this._onReset.bind(this));
this._userVerifier.connect('smartcard-status-changed', this._onSmartcardStatusChanged.bind(this));
this._userVerifier.connect('ovirt-user-authenticated', this._onOVirtUserAuthenticated.bind(this));
this._userVerifier.connect('credential-manager-authenticated', this._onCredentialManagerAuthenticated.bind(this));
this.smartcardDetected = this._userVerifier.smartcardDetected;
this.connect('destroy', this._onDestroy.bind(this));
@ -242,7 +242,7 @@ var AuthPrompt = GObject.registerClass({
this.emit('prompted');
}
_onOVirtUserAuthenticated() {
_onCredentialManagerAuthenticated() {
if (this.verificationStatus != AuthPromptStatus.VERIFICATION_SUCCEEDED)
this.reset();
}

View File

@ -0,0 +1,24 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
/* exported CredentialManager */
class CredentialManager {
constructor(service) {
this._token = null;
this._service = service;
this._authenticatedSignalId = null;
}
get token() {
return this._token;
}
set token(t) {
this._token = t;
if (this._token)
this.emit('user-authenticated', this._token);
}
get service() {
return this._service;
}
}

View File

@ -810,8 +810,8 @@ var LoginDialog = GObject.registerClass({
return;
this._logoBin.destroy_all_children();
const [valid, resourceScale] = this._logoBin.get_resource_scale();
if (this._logoFile && valid) {
const resourceScale = this._logoBin.get_resource_scale();
if (this._logoFile) {
let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor;
this._logoBin.add_child(this._textureCache.load_file_async(this._logoFile,
-1, -1,
@ -953,16 +953,15 @@ var LoginDialog = GObject.registerClass({
if (this.opacity == 255 && this._authPrompt.verificationStatus == AuthPrompt.AuthPromptStatus.NOT_VERIFYING)
return;
if (this._authPrompt.verificationStatus !== AuthPrompt.AuthPromptStatus.NOT_VERIFYING)
this._authPrompt.reset();
this._bindOpacity();
this.ease({
opacity: 255,
duration: _FADE_ANIMATION_TIME,
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
onComplete: () => {
if (this._authPrompt.verificationStatus != AuthPrompt.AuthPromptStatus.NOT_VERIFYING)
this._authPrompt.reset();
this._unbindOpacity();
},
onComplete: () => this._unbindOpacity(),
});
}

View File

@ -3,6 +3,9 @@
const Gio = imports.gi.Gio;
const Signals = imports.signals;
const Credential = imports.gdm.credentialManager;
var SERVICE_NAME = 'gdm-ovirtcred';
const OVirtCredentialsIface = `
<node>
@ -28,30 +31,14 @@ function OVirtCredentials() {
return self;
}
var OVirtCredentialsManager = class {
var OVirtCredentialsManager = class OVirtCredentialsManager extends Credential.CredentialManager {
constructor() {
this._token = null;
super(SERVICE_NAME);
this._credentials = new OVirtCredentials();
this._credentials.connectSignal('UserAuthenticated',
this._onUserAuthenticated.bind(this));
}
_onUserAuthenticated(proxy, sender, [token]) {
this._token = token;
this.emit('user-authenticated', token);
}
hasToken() {
return this._token != null;
}
getToken() {
return this._token;
}
resetToken() {
this._token = null;
(proxy, sender, [token]) => {
this.token = token;
});
}
};
Signals.addSignalMethods(OVirtCredentialsManager.prototype);

View File

@ -8,6 +8,7 @@ const Signals = imports.signals;
const Batch = imports.gdm.batch;
const Fprint = imports.gdm.fingerprint;
const OVirt = imports.gdm.oVirt;
const Vmware = imports.gdm.vmware;
const Main = imports.ui.main;
const Params = imports.misc.params;
const SmartcardManager = imports.misc.smartcardManager;
@ -24,7 +25,6 @@ Gio._promisify(Gdm.UserVerifierProxy.prototype,
var PASSWORD_SERVICE_NAME = 'gdm-password';
var FINGERPRINT_SERVICE_NAME = 'gdm-fingerprint';
var SMARTCARD_SERVICE_NAME = 'gdm-smartcard';
var OVIRT_SERVICE_NAME = 'gdm-ovirtcred';
var FADE_ANIMATION_TIME = 160;
var CLONE_FADE_ANIMATION_TIME = 250;
@ -160,13 +160,20 @@ var ShellUserVerifier = class {
this._failCounter = 0;
this._oVirtCredentialsManager = OVirt.getOVirtCredentialsManager();
this._credentialManagers = {};
this._credentialManagers[OVirt.SERVICE_NAME] = OVirt.getOVirtCredentialsManager();
this._credentialManagers[Vmware.SERVICE_NAME] = Vmware.getVmwareCredentialsManager();
if (this._oVirtCredentialsManager.hasToken())
this._oVirtUserAuthenticated(this._oVirtCredentialsManager.getToken());
for (let service in this._credentialManagers) {
if (this._credentialManagers[service].token) {
this._onCredentialManagerAuthenticated(this._credentialManagers[service],
this._credentialManagers[service].token);
}
this._oVirtUserAuthenticatedId = this._oVirtCredentialsManager.connect('user-authenticated',
this._oVirtUserAuthenticated.bind(this));
this._credentialManagers[service]._authenticatedSignalId =
this._credentialManagers[service].connect('user-authenticated',
this._onCredentialManagerAuthenticated.bind(this));
}
}
begin(userName, hold) {
@ -222,8 +229,11 @@ var ShellUserVerifier = class {
this._smartcardManager.disconnect(this._smartcardRemovedId);
this._smartcardManager = null;
this._oVirtCredentialsManager.disconnect(this._oVirtUserAuthenticatedId);
this._oVirtCredentialsManager = null;
for (let service in this._credentialManagers) {
let credentialManager = this._credentialManagers[service];
credentialManager.disconnect(credentialManager._authenticatedSignalId);
credentialManager = null;
}
}
answerQuery(serviceName, answer) {
@ -311,9 +321,9 @@ var ShellUserVerifier = class {
});
}
_oVirtUserAuthenticated(_token) {
this._preemptingService = OVIRT_SERVICE_NAME;
this.emit('ovirt-user-authenticated');
_onCredentialManagerAuthenticated(credentialManager, _token) {
this._preemptingService = credentialManager.service;
this.emit('credential-manager-authenticated');
}
_checkForSmartcard() {
@ -490,9 +500,12 @@ var ShellUserVerifier = class {
if (!this.serviceIsForeground(serviceName))
return;
if (serviceName == OVIRT_SERVICE_NAME) {
// The only question asked by this service is "Token?"
this.answerQuery(serviceName, this._oVirtCredentialsManager.getToken());
let token = null;
if (this._credentialManagers[serviceName])
token = this._credentialManagers[serviceName].token;
if (token) {
this.answerQuery(serviceName, token);
return;
}
@ -560,8 +573,10 @@ var ShellUserVerifier = class {
// If the login failed with the preauthenticated oVirt credentials
// then discard the credentials and revert to default authentication
// mechanism.
if (this.serviceIsForeground(OVIRT_SERVICE_NAME)) {
this._oVirtCredentialsManager.resetToken();
let foregroundService = Object.keys(this._credentialManagers).find(service =>
this.serviceIsForeground(service));
if (foregroundService) {
this._credentialManagers[foregroundService].token = null;
this._preemptingService = null;
this._verificationFailed(false);
return;

54
js/gdm/vmware.js Normal file
View File

@ -0,0 +1,54 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
/* exported getVmwareCredentialsManager */
const Gio = imports.gi.Gio;
const Signals = imports.signals;
const Credential = imports.gdm.credentialManager;
const dbusPath = '/org/vmware/viewagent/Credentials';
const dbusInterface = 'org.vmware.viewagent.Credentials';
var SERVICE_NAME = 'gdm-vmwcred';
const VmwareCredentialsIface = '<node> \
<interface name="' + dbusInterface + '"> \
<signal name="UserAuthenticated"> \
<arg type="s" name="token"/> \
</signal> \
</interface> \
</node>';
const VmwareCredentialsInfo = Gio.DBusInterfaceInfo.new_for_xml(VmwareCredentialsIface);
let _vmwareCredentialsManager = null;
function VmwareCredentials() {
var self = new Gio.DBusProxy({ g_connection: Gio.DBus.session,
g_interface_name: VmwareCredentialsInfo.name,
g_interface_info: VmwareCredentialsInfo,
g_name: dbusInterface,
g_object_path: dbusPath,
g_flags: Gio.DBusProxyFlags.DO_NOT_LOAD_PROPERTIES });
self.init(null);
return self;
}
var VmwareCredentialsManager = class VmwareCredentialsManager extends Credential.CredentialManager {
constructor() {
super(SERVICE_NAME);
this._credentials = new VmwareCredentials();
this._credentials.connectSignal('UserAuthenticated',
(proxy, sender, [token]) => {
this.token = token;
});
}
};
Signals.addSignalMethods(VmwareCredentialsManager.prototype);
function getVmwareCredentialsManager() {
if (!_vmwareCredentialsManager)
_vmwareCredentialsManager = new VmwareCredentialsManager();
return _vmwareCredentialsManager;
}

View File

@ -6,6 +6,8 @@
<file>gdm/fingerprint.js</file>
<file>gdm/loginDialog.js</file>
<file>gdm/oVirt.js</file>
<file>gdm/credentialManager.js</file>
<file>gdm/vmware.js</file>
<file>gdm/realmd.js</file>
<file>gdm/util.js</file>
@ -90,7 +92,6 @@
<file>ui/ripples.js</file>
<file>ui/runDialog.js</file>
<file>ui/screenShield.js</file>
<file>ui/screencast.js</file>
<file>ui/screenshot.js</file>
<file>ui/scripting.js</file>
<file>ui/search.js</file>
@ -135,7 +136,6 @@
<file>ui/status/volume.js</file>
<file>ui/status/bluetooth.js</file>
<file>ui/status/remoteAccess.js</file>
<file>ui/status/screencast.js</file>
<file>ui/status/system.js</file>
<file>ui/status/thunderbolt.js</file>
</gresource>

View File

@ -1,6 +1,6 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
/* exported collectFromDatadirs, recursivelyDeleteDir,
recursivelyMoveDir, loadInterfaceXML */
recursivelyMoveDir, loadInterfaceXML, loadSubInterfaceXML */
const { Gio, GLib } = imports.gi;
const Config = imports.misc.config;
@ -67,14 +67,19 @@ function recursivelyMoveDir(srcDir, destDir) {
}
let _ifaceResource = null;
function ensureIfaceResource() {
if (_ifaceResource)
return;
// don't use global.datadir so the method is usable from tests/tools
let dir = GLib.getenv('GNOME_SHELL_DATADIR') || Config.PKGDATADIR;
let path = `${dir}/gnome-shell-dbus-interfaces.gresource`;
_ifaceResource = Gio.Resource.load(path);
_ifaceResource._register();
}
function loadInterfaceXML(iface) {
if (!_ifaceResource) {
// don't use global.datadir so the method is usable from tests/tools
let dir = GLib.getenv('GNOME_SHELL_DATADIR') || Config.PKGDATADIR;
let path = `${dir}/gnome-shell-dbus-interfaces.gresource`;
_ifaceResource = Gio.Resource.load(path);
_ifaceResource._register();
}
ensureIfaceResource();
let uri = `resource:///org/gnome/shell/dbus-interfaces/${iface}.xml`;
let f = Gio.File.new_for_uri(uri);
@ -88,3 +93,25 @@ function loadInterfaceXML(iface) {
return null;
}
function loadSubInterfaceXML(iface, ifaceFile) {
let xml = loadInterfaceXML(ifaceFile);
if (!xml)
return null;
let ifaceStartTag = `<interface name="${iface}">`;
let ifaceStopTag = '</interface>';
let ifaceStartIndex = xml.indexOf(ifaceStartTag);
let ifaceEndIndex = xml.indexOf(ifaceStopTag, ifaceStartIndex + 1) + ifaceStopTag.length;
let xmlHeader = '<!DOCTYPE node PUBLIC\n' +
'\'-//freedesktop//DTD D-BUS Object Introspection 1.0//EN\'\n' +
'\'http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd\'>\n' +
'<node>\n';
let xmlFooter = '</node>';
return (
xmlHeader +
xml.substr(ifaceStartIndex, ifaceEndIndex - ifaceStartIndex) +
xmlFooter);
}

View File

@ -5,7 +5,7 @@ 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 INTROSPECT_DBUS_API_VERSION = 3;
const { loadInterfaceXML } = imports.misc.fileUtils;
@ -59,6 +59,11 @@ var IntrospectService = class {
this._settings.connect('notify::enable-animations',
this._syncAnimationsEnabled.bind(this));
this._syncAnimationsEnabled();
const monitorManager = Meta.MonitorManager.get();
monitorManager.connect('monitors-changed',
this._syncScreenSize.bind(this));
this._syncScreenSize();
}
_isStandaloneApp(app) {
@ -209,10 +214,28 @@ var IntrospectService = class {
}
}
_syncScreenSize() {
const oldScreenWidth = this._screenWidth;
const oldScreenHeight = this._screenHeight;
this._screenWidth = global.screen_width;
this._screenHeight = global.screen_height;
if (oldScreenWidth !== this._screenWidth ||
oldScreenHeight !== this._screenHeight) {
const variant = new GLib.Variant('(ii)',
[this._screenWidth, this._screenHeight]);
this._dbusImpl.emit_property_changed('ScreenSize', variant);
}
}
get AnimationsEnabled() {
return this._animationsEnabled;
}
get ScreenSize() {
return [this._screenWidth, this._screenHeight];
}
get version() {
return INTROSPECT_DBUS_API_VERSION;
}

View File

@ -852,6 +852,9 @@ class AppSwitcher extends SwitcherPopup.SwitcherList {
if (index === -1)
return;
this._arrows[index].destroy();
this._arrows.splice(index, 1);
this.icons.splice(index, 1);
this.removeItem(index);
}

View File

@ -60,7 +60,7 @@ class Animation extends St.Bin {
}
_loadFile(file, width, height) {
let [validResourceScale, resourceScale] = this.get_resource_scale();
const resourceScale = this.get_resource_scale();
let wasPlaying = this._isPlaying;
if (this._isPlaying)
@ -69,12 +69,6 @@ class Animation extends St.Bin {
this._isLoaded = false;
this.destroy_all_children();
if (!validResourceScale) {
if (wasPlaying)
this.play();
return;
}
let textureCache = St.TextureCache.get_default();
let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor;
this._animations = textureCache.load_sliced_image(file, width, height,

File diff suppressed because it is too large Load Diff

View File

@ -347,6 +347,8 @@ var Background = GObject.registerClass({
this.set_color(color);
else
this.set_gradient(shadingType, color, secondColor);
this._setLoaded();
}
_watchFile(file) {
@ -712,13 +714,18 @@ var BackgroundManager = class BackgroundManager {
}
let newBackgroundActor = this._createBackgroundActor();
newBackgroundActor.vignette_sharpness = this.backgroundActor.vignette_sharpness;
newBackgroundActor.brightness = this.backgroundActor.brightness;
const oldContent = this.backgroundActor.content;
const newContent = newBackgroundActor.content;
newContent.vignette_sharpness = oldContent.vignette_sharpness;
newContent.brightness = oldContent.brightness;
newBackgroundActor.visible = this.backgroundActor.visible;
this._newBackgroundActor = newBackgroundActor;
let background = newBackgroundActor.background;
const { background } = newBackgroundActor.content;
if (background.isLoaded) {
this._swapBackgroundActor();
@ -760,10 +767,27 @@ var BackgroundManager = class BackgroundManager {
this._updateBackgroundActor();
});
let loadedSignalId;
if (background.isLoaded) {
GLib.idle_add(GLib.PRIORITY_DEFAULT, () => {
this.emit('loaded');
return GLib.SOURCE_REMOVE;
});
} else {
loadedSignalId = background.connect('loaded', () => {
background.disconnect(loadedSignalId);
loadedSignalId = null;
this.emit('loaded');
});
}
backgroundActor.connect('destroy', () => {
if (changeSignalId)
background.disconnect(changeSignalId);
if (loadedSignalId)
background.disconnect(loadedSignalId);
if (backgroundActor.loadedSignalId)
background.disconnect(backgroundActor.loadedSignalId);
});

View File

@ -1,7 +1,7 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
/* exported BoxPointer */
const { Clutter, GObject, Shell, St } = imports.gi;
const { Clutter, GObject, St } = imports.gi;
const Main = imports.ui.main;
@ -453,15 +453,16 @@ var BoxPointer = GObject.registerClass({
let alignment = this._arrowAlignment;
let monitorIndex = Main.layoutManager.findIndexForActor(sourceActor);
this._sourceAllocation = Shell.util_get_transformed_allocation(sourceActor);
this._sourceExtents = sourceActor.get_transformed_extents();
this._workArea = Main.layoutManager.getWorkAreaForMonitor(monitorIndex);
// Position correctly relative to the sourceActor
let sourceNode = sourceActor.get_theme_node();
let sourceContentBox = sourceNode.get_content_box(sourceActor.get_allocation_box());
let sourceAllocation = this._sourceAllocation;
let sourceCenterX = sourceAllocation.x1 + sourceContentBox.x1 + (sourceContentBox.x2 - sourceContentBox.x1) * this._sourceAlignment;
let sourceCenterY = sourceAllocation.y1 + sourceContentBox.y1 + (sourceContentBox.y2 - sourceContentBox.y1) * this._sourceAlignment;
let sourceTopLeft = this._sourceExtents.get_top_left();
let sourceBottomRight = this._sourceExtents.get_bottom_right();
let sourceCenterX = sourceTopLeft.x + sourceContentBox.x1 + (sourceContentBox.x2 - sourceContentBox.x1) * this._sourceAlignment;
let sourceCenterY = sourceTopLeft.y + sourceContentBox.y1 + (sourceContentBox.y2 - sourceContentBox.y1) * this._sourceAlignment;
let [, , natWidth, natHeight] = this.get_preferred_size();
// We also want to keep it onscreen, and separated from the
@ -481,16 +482,16 @@ var BoxPointer = GObject.registerClass({
switch (this._arrowSide) {
case St.Side.TOP:
resY = sourceAllocation.y2 + gap;
resY = sourceBottomRight.y + gap;
break;
case St.Side.BOTTOM:
resY = sourceAllocation.y1 - natHeight - gap;
resY = sourceTopLeft.y - natHeight - gap;
break;
case St.Side.LEFT:
resX = sourceAllocation.x2 + gap;
resX = sourceBottomRight.x + gap;
break;
case St.Side.RIGHT:
resX = sourceAllocation.x1 - natWidth - gap;
resX = sourceTopLeft.x - natWidth - gap;
break;
}
@ -586,29 +587,30 @@ var BoxPointer = GObject.registerClass({
}
_calculateArrowSide(arrowSide) {
let sourceAllocation = this._sourceAllocation;
let sourceTopLeft = this._sourceExtents.get_top_left();
let sourceBottomRight = this._sourceExtents.get_bottom_right();
let [, , boxWidth, boxHeight] = this.get_preferred_size();
let workarea = this._workArea;
switch (arrowSide) {
case St.Side.TOP:
if (sourceAllocation.y2 + boxHeight > workarea.y + workarea.height &&
boxHeight < sourceAllocation.y1 - workarea.y)
if (sourceBottomRight.y + boxHeight > workarea.y + workarea.height &&
boxHeight < sourceTopLeft.y - workarea.y)
return St.Side.BOTTOM;
break;
case St.Side.BOTTOM:
if (sourceAllocation.y1 - boxHeight < workarea.y &&
boxHeight < workarea.y + workarea.height - sourceAllocation.y2)
if (sourceTopLeft.y - boxHeight < workarea.y &&
boxHeight < workarea.y + workarea.height - sourceBottomRight.y)
return St.Side.TOP;
break;
case St.Side.LEFT:
if (sourceAllocation.x2 + boxWidth > workarea.x + workarea.width &&
boxWidth < sourceAllocation.x1 - workarea.x)
if (sourceBottomRight.x + boxWidth > workarea.x + workarea.width &&
boxWidth < sourceTopLeft.x - workarea.x)
return St.Side.RIGHT;
break;
case St.Side.RIGHT:
if (sourceAllocation.x1 - boxWidth < workarea.x &&
boxWidth < workarea.x + workarea.width - sourceAllocation.x2)
if (sourceTopLeft.x - boxWidth < workarea.x &&
boxWidth < workarea.x + workarea.width - sourceBottomRight.x)
return St.Side.LEFT;
break;
}

View File

@ -784,6 +784,7 @@ class DateMenuButton extends PanelMenu.Button {
this._clockDisplay = new St.Label({ style_class: 'clock' });
this._clockDisplay.clutter_text.y_align = Clutter.ActorAlign.CENTER;
this._clockDisplay.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
this._indicator = new MessagesIndicator();

View File

@ -1,7 +1,7 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
/* exported Dialog, MessageDialogContent, ListSection, ListSectionItem */
const { Clutter, GObject, Meta, Pango, St } = imports.gi;
const { Clutter, GLib, GObject, Meta, Pango, St } = imports.gi;
function _setLabel(label, value) {
label.set({
@ -221,13 +221,16 @@ var MessageDialogContent = GObject.registerClass({
this._updateTitleStyleLater = Meta.later_add(Meta.LaterType.BEFORE_REDRAW, () => {
this._updateTitleStyleLater = 0;
this._title.add_style_class_name('leightweight');
return false;
return GLib.SOURCE_REMOVE;
});
}
}
set title(title) {
if (this._title.text === title)
return;
_setLabel(this._title, title);
this._title.remove_style_class_name('leightweight');
@ -237,6 +240,9 @@ var MessageDialogContent = GObject.registerClass({
}
set description(description) {
if (this._description.text === description)
return;
_setLabel(this._description, description);
this.notify('description');
}

View File

@ -388,17 +388,16 @@ var _Draggable = class _Draggable {
const [, newAllocatedWidth] = this._dragActor.get_preferred_width(-1);
const [, newAllocatedHeight] = this._dragActor.get_preferred_height(-1);
const transformedAllocation =
Shell.util_get_transformed_allocation(this._dragActor);
const transformedExtents = this._dragActor.get_transformed_extents();
// Set the actor's scale such that it will keep the same
// transformed size when it's reparented to the uiGroup
this._dragActor.set_scale(
transformedAllocation.get_width() / newAllocatedWidth,
transformedAllocation.get_height() / newAllocatedHeight);
transformedExtents.get_width() / newAllocatedWidth,
transformedExtents.get_height() / newAllocatedHeight);
this._dragOffsetX = transformedAllocation.x1 - this._dragStartX;
this._dragOffsetY = transformedAllocation.y1 - this._dragStartY;
this._dragOffsetX = transformedExtents.origin.x - this._dragStartX;
this._dragOffsetY = transformedExtents.origin.y - this._dragStartY;
this._dragOrigParent.remove_actor(this._dragActor);
Main.uiGroup.add_child(this._dragActor);

View File

@ -139,7 +139,9 @@ function checkForUpdates() {
return;
if (extension.hasUpdate)
return;
metadatas[uuid] = extension.metadata;
metadatas[uuid] = {
version: extension.metadata.version,
};
});
if (Object.keys(metadatas).length === 0)

View File

@ -31,7 +31,7 @@ var IconSize = {
var APPICON_ANIMATION_OUT_SCALE = 3;
var APPICON_ANIMATION_OUT_TIME = 250;
const ICON_POSITION_DELAY = 25;
const ICON_POSITION_DELAY = 10;
const defaultGridModes = [
{
@ -52,6 +52,17 @@ const defaultGridModes = [
},
];
var LEFT_DIVIDER_LEEWAY = 20;
var RIGHT_DIVIDER_LEEWAY = 20;
var DragLocation = {
INVALID: 0,
START_EDGE: 1,
ON_ICON: 2,
END_EDGE: 3,
EMPTY_SPACE: 4,
};
var BaseIcon = GObject.registerClass(
class BaseIcon extends St.Bin {
_init(label, params) {
@ -946,6 +957,99 @@ var IconGridLayout = GObject.registerClass({
}
}
/**
* getDropTarget:
* @param {int} x: position of the horizontal axis
* @param {int} y: position of the vertical axis
*
* Retrieves the item located at (@x, @y), as well as the drag location.
* Both @x and @y are relative to the grid.
*
* @returns {[Clutter.Actor, DragLocation]} the item and drag location
* under (@x, @y)
*/
getDropTarget(x, y) {
const childSize = this._getChildrenMaxSize();
const [leftEmptySpace, topEmptySpace, hSpacing, vSpacing] =
this._calculateSpacing(childSize);
const isRtl =
Clutter.get_default_text_direction() === Clutter.TextDirection.RTL;
let page = this._orientation === Clutter.Orientation.VERTICAL
? Math.floor(y / this._pageHeight)
: Math.floor(x / this._pageWidth);
// Out of bounds
if (page >= this._pages.length)
return [null, DragLocation.INVALID];
if (isRtl && this._orientation === Clutter.Orientation.HORIZONTAL)
page = swap(page, this._pages.length);
// Page-relative coordinates from now on
x %= this._pageWidth;
y %= this._pageHeight;
if (x < leftEmptySpace || y < topEmptySpace)
return [null, DragLocation.INVALID];
const gridWidth =
childSize * this._columnsPerPage +
hSpacing * (this._columnsPerPage - 1);
const gridHeight =
childSize * this._rowsPerPage +
vSpacing * (this._rowsPerPage - 1);
if (x > leftEmptySpace + gridWidth || y > topEmptySpace + gridHeight)
return [null, DragLocation.INVALID];
const halfHSpacing = hSpacing / 2;
const halfVSpacing = vSpacing / 2;
const visibleItems = this._getVisibleChildrenForPage(page);
for (const item of visibleItems) {
const childBox = item.allocation.copy();
// Page offset
switch (this._orientation) {
case Clutter.Orientation.HORIZONTAL:
childBox.set_origin(childBox.x1 % this._pageWidth, childBox.y1);
break;
case Clutter.Orientation.VERTICAL:
childBox.set_origin(childBox.x1, childBox.y1 % this._pageHeight);
break;
}
// Outside the icon boundaries
if (x < childBox.x1 - halfHSpacing ||
x > childBox.x2 + halfHSpacing ||
y < childBox.y1 - halfVSpacing ||
y > childBox.y2 + halfVSpacing)
continue;
let dragLocation;
if (x < childBox.x1 + LEFT_DIVIDER_LEEWAY)
dragLocation = DragLocation.START_EDGE;
else if (x > childBox.x2 - RIGHT_DIVIDER_LEEWAY)
dragLocation = DragLocation.END_EDGE;
else
dragLocation = DragLocation.ON_ICON;
if (isRtl) {
if (dragLocation === DragLocation.START_EDGE)
dragLocation = DragLocation.END_EDGE;
else if (dragLocation === DragLocation.END_EDGE)
dragLocation = DragLocation.START_EDGE;
}
return [item, dragLocation];
}
return [null, DragLocation.EMPTY_SPACE];
}
// eslint-disable-next-line camelcase
get allow_incomplete_pages() {
return this._allowIncompletePages;
@ -1559,6 +1663,11 @@ var IconGrid = GObject.registerClass({
this.queue_relayout();
}
getDropTarget(x, y) {
const layoutManager = this.layout_manager;
return layoutManager.getDropTarget(x, y, this._currentPage);
}
get itemsPerPage() {
const layoutManager = this.layout_manager;
return layoutManager.rows_per_page * layoutManager.columns_per_page;

View File

@ -1,5 +1,5 @@
/* exported InhibitShortcutsDialog */
const { Clutter, Gio, GLib, GObject, Gtk, Meta, Shell, St } = imports.gi;
const { Clutter, Gio, GLib, GObject, Gtk, Meta, Pango, Shell, St } = imports.gi;
const Dialog = imports.ui.dialog;
const ModalDialog = imports.ui.modalDialog;
@ -90,6 +90,8 @@ var InhibitShortcutsDialog = GObject.registerClass({
text: _('You can restore shortcuts by pressing %s.').format(restoreAccel),
style_class: 'message-dialog-description',
});
restoreLabel.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
restoreLabel.clutter_text.line_wrap = true;
content.add_child(restoreLabel);
}

View File

@ -42,7 +42,7 @@ const defaultKeysPost = [
[[{ 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 }],
[{ action: 'emoji', icon: 'face-smile-symbolic' }, { 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' }]],
[[{ 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 }],
@ -61,6 +61,24 @@ class AspectContainer extends St.Widget {
this.queue_relayout();
}
vfunc_get_preferred_width(forHeight) {
let [min, nat] = super.vfunc_get_preferred_width(forHeight);
if (forHeight > 0)
nat = forHeight * this._ratio;
return [min, nat];
}
vfunc_get_preferred_height(forWidth) {
let [min, nat] = super.vfunc_get_preferred_height(forWidth);
if (forWidth > 0)
nat = forWidth / this._ratio;
return [min, nat];
}
vfunc_allocate(box) {
if (box.get_width() > 0 && box.get_height() > 0) {
let sizeRatio = box.get_width() / box.get_height();
@ -1608,7 +1626,9 @@ class Keyboard extends St.BoxLayout {
* we allow the OSK being smaller than 1/3rd of the monitor height
* there.
*/
this.height = Math.min(maxHeight, this.get_preferred_height(monitor.width));
const forWidth = this.get_theme_node().adjust_for_width(monitor.width);
const [, natHeight] = this.get_preferred_height(forWidth);
this.height = Math.min(maxHeight, natHeight);
}
}

View File

@ -6,7 +6,6 @@ const Signals = imports.signals;
const Background = imports.ui.background;
const BackgroundMenu = imports.ui.backgroundMenu;
const LoginManager = imports.misc.loginManager;
const DND = imports.ui.dnd;
const Main = imports.ui.main;
@ -295,18 +294,6 @@ var LayoutManager = GObject.registerClass({
monitorManager.connect('monitors-changed',
this._monitorsChanged.bind(this));
this._monitorsChanged();
// NVIDIA drivers don't preserve FBO contents across
// suspend/resume, see
// https://bugzilla.gnome.org/show_bug.cgi?id=739178
if (Shell.util_need_background_refresh()) {
LoginManager.getLoginManager().connect('prepare-for-sleep',
(lm, suspending) => {
if (suspending)
return;
Meta.Background.refresh_all();
});
}
}
// This is called by Main after everything else is constructed
@ -470,6 +457,15 @@ var LayoutManager = GObject.registerClass({
}
}
_waitLoaded(bgManager) {
return new Promise(resolve => {
const id = bgManager.connect('loaded', () => {
bgManager.disconnect(id);
resolve();
});
});
}
_updateBackgrounds() {
for (let i = 0; i < this._bgManagers.length; i++)
this._bgManagers[i].destroy();
@ -477,7 +473,7 @@ var LayoutManager = GObject.registerClass({
this._bgManagers = [];
if (Main.sessionMode.isGreeter)
return;
return Promise.resolve();
for (let i = 0; i < this.monitors.length; i++) {
let bgManager = this._createBackgroundManager(i);
@ -486,6 +482,8 @@ var LayoutManager = GObject.registerClass({
if (i != this.primaryIndex && this._startingUp)
bgManager.backgroundActor.hide();
}
return Promise.all(this._bgManagers.map(this._waitLoaded));
}
_updateKeyboardBox() {
@ -644,7 +642,7 @@ var LayoutManager = GObject.registerClass({
// When starting a normal user session, we want to grow it out of the middle
// of the screen.
_prepareStartupAnimation() {
async _prepareStartupAnimation() {
// During the initial transition, add a simple actor to block all events,
// so they don't get delivered to X11 windows that have been transformed.
this._coverPane = new Clutter.Actor({ opacity: 0,
@ -661,8 +659,6 @@ var LayoutManager = GObject.registerClass({
} else if (Main.sessionMode.isGreeter) {
this.panelBox.translation_y = -this.panelBox.height;
} else {
this._updateBackgrounds();
// We need to force an update of the regions now before we scale
// the UI group to get the correct allocation for the struts.
this._updateRegions();
@ -678,6 +674,8 @@ var LayoutManager = GObject.registerClass({
this.uiGroup.scale_x = this.uiGroup.scale_y = 0.75;
this.uiGroup.opacity = 0;
global.window_group.set_clip(monitor.x, monitor.y, monitor.width, monitor.height);
await this._updateBackgrounds();
}
this.emit('startup-prepared');
@ -1204,7 +1202,8 @@ class HotCorner extends Clutter.Actor {
if (Clutter.get_default_text_direction() == Clutter.TextDirection.RTL) {
this._corner.set_position(this.width - this._corner.width, 0);
this.set_anchor_point_from_gravity(Clutter.Gravity.NORTH_EAST);
this.set_pivot_point(1.0, 0.0);
this.translation_x = -this.width;
} else {
this._corner.set_position(0, 0);
}
@ -1229,8 +1228,9 @@ class HotCorner extends Clutter.Actor {
return;
if (Main.overview.shouldToggleByCornerOrButton()) {
this._ripples.playAnimation(this._x, this._y);
Main.overview.toggle();
if (Main.overview.animationInProgress)
this._ripples.playAnimation(this._x, this._y);
}
}

View File

@ -489,7 +489,10 @@ var Magnifier = class Magnifier {
_updateMouseSprite() {
this._updateSpriteTexture();
let [xHot, yHot] = this._cursorTracker.get_hot();
this._mouseSprite.set_anchor_point(xHot, yHot);
this._mouseSprite.set({
translation_x: -xHot,
translation_y: -yHot,
});
}
_updateSpriteTexture() {

View File

@ -3,10 +3,10 @@
ctrlAltTabManager, padOsdService, osdWindowManager,
osdMonitorLabeler, shellMountOpDBusService, shellDBusService,
shellAccessDialogDBusService, shellAudioSelectionDBusService,
screenSaverDBus, screencastService, uiGroup, magnifier,
xdndHandler, keyboard, kbdA11yDialog, introspectService,
start, pushModal, popModal, activateWindow, createLookingGlass,
initializeDeferredWork, getThemeStylesheet, setThemeStylesheet */
screenSaverDBus, uiGroup, magnifier, xdndHandler, keyboard,
kbdA11yDialog, introspectService, start, pushModal, popModal,
activateWindow, createLookingGlass, initializeDeferredWork,
getThemeStylesheet, setThemeStylesheet */
const { Clutter, Gio, GLib, GObject, Meta, Shell, St } = imports.gi;
@ -34,7 +34,6 @@ const LoginManager = imports.misc.loginManager;
const LookingGlass = imports.ui.lookingGlass;
const NotificationDaemon = imports.ui.notificationDaemon;
const WindowAttentionHandler = imports.ui.windowAttentionHandler;
const Screencast = imports.ui.screencast;
const ScreenShield = imports.ui.screenShield;
const Scripting = imports.ui.scripting;
const SessionMode = imports.ui.sessionMode;
@ -74,7 +73,6 @@ var shellAudioSelectionDBusService = null;
var shellDBusService = null;
var shellMountOpDBusService = null;
var screenSaverDBus = null;
var screencastService = null;
var modalCount = 0;
var actionMode = Shell.ActionMode.NONE;
var modalActorFocusStack = [];
@ -200,7 +198,6 @@ function _initializeUI() {
uiGroup = layoutManager.uiGroup;
padOsdService = new PadOsd.PadOsdService();
screencastService = new Screencast.ScreencastService();
xdndHandler = new XdndHandler.XdndHandler();
ctrlAltTabManager = new CtrlAltTab.CtrlAltTabManager();
osdWindowManager = new OsdWindow.OsdWindowManager();

View File

@ -1,6 +1,6 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
/* exported NotificationPolicy, NotificationGenericPolicy,
NotificationApplicationPolicy, Source, SourceActor, SourceActorWithLabel,
NotificationApplicationPolicy, Source, SourceActor,
SystemNotificationSource, MessageTray */
const { Clutter, Gio, GLib, GObject, Meta, Shell, St } = imports.gi;
@ -655,77 +655,6 @@ class SourceActor extends St.Widget {
}
});
var SourceActorWithLabel = GObject.registerClass(
class SourceActorWithLabel extends SourceActor {
_init(source, size) {
super._init(source, size);
this._counterLabel = new St.Label({ x_align: Clutter.ActorAlign.CENTER,
x_expand: true,
y_align: Clutter.ActorAlign.CENTER,
y_expand: true });
this._counterBin = new St.Bin({ style_class: 'summary-source-counter',
child: this._counterLabel,
layout_manager: new Clutter.BinLayout() });
this._counterBin.hide();
this._counterBin.connect('style-changed', () => {
let themeNode = this._counterBin.get_theme_node();
this._counterBin.translation_x = themeNode.get_length('-shell-counter-overlap-x');
this._counterBin.translation_y = themeNode.get_length('-shell-counter-overlap-y');
});
this.add_actor(this._counterBin);
this._countUpdatedId = this._source.connect('notify::count', this._updateCount.bind(this));
this._updateCount();
this.connect('destroy', () => {
this._source.disconnect(this._countUpdatedId);
});
}
vfunc_allocate(box) {
super.vfunc_allocate(box);
let childBox = new Clutter.ActorBox();
let [, , naturalWidth, naturalHeight] = this._counterBin.get_preferred_size();
let direction = this.get_text_direction();
if (direction == Clutter.TextDirection.LTR) {
// allocate on the right in LTR
childBox.x1 = box.x2 - naturalWidth;
childBox.x2 = box.x2;
} else {
// allocate on the left in RTL
childBox.x1 = 0;
childBox.x2 = naturalWidth;
}
childBox.y1 = box.y2 - naturalHeight;
childBox.y2 = box.y2;
this._counterBin.allocate(childBox);
}
_updateCount() {
if (this._actorDestroyed)
return;
this._counterBin.visible = this._source.countVisible;
let text;
if (this._source.count < 100)
text = this._source.count.toString();
else
text = String.fromCharCode(0x22EF); // midline horizontal ellipsis
this._counterLabel.set_text(text);
}
});
var Source = GObject.registerClass({
Properties: {
'count': GObject.ParamSpec.int(

View File

@ -4,6 +4,10 @@
const { Clutter, GLib, GObject, Meta, Shell, St } = imports.gi;
const Signals = imports.signals;
// Time for initial animation going into Overview mode;
// this is defined here to make it available in imports.
var ANIMATION_TIME = 250;
const Background = imports.ui.background;
const DND = imports.ui.dnd;
const LayoutManager = imports.ui.layout;
@ -14,9 +18,6 @@ const OverviewControls = imports.ui.overviewControls;
const Params = imports.misc.params;
const WorkspaceThumbnail = imports.ui.workspaceThumbnail;
// Time for initial animation going into Overview mode
var ANIMATION_TIME = 250;
// Must be less than ANIMATION_TIME, since we switch to
// or from the overview completely after ANIMATION_TIME,
// and don't want the shading animation to get cut off
@ -439,19 +440,19 @@ var Overview = class {
this.emit('windows-restacked', stackIndices);
}
beginItemDrag(_source) {
this.emit('item-drag-begin');
beginItemDrag(source) {
this.emit('item-drag-begin', source);
this._inItemDrag = true;
}
cancelledItemDrag(_source) {
this.emit('item-drag-cancelled');
cancelledItemDrag(source) {
this.emit('item-drag-cancelled', source);
}
endItemDrag(_source) {
endItemDrag(source) {
if (!this._inItemDrag)
return;
this.emit('item-drag-end');
this.emit('item-drag-end', source);
this._inItemDrag = false;
}

View File

@ -8,8 +8,9 @@ const Main = imports.ui.main;
const Params = imports.misc.params;
const ViewSelector = imports.ui.viewSelector;
const WorkspaceThumbnail = imports.ui.workspaceThumbnail;
const Overview = imports.ui.overview;
var SIDE_CONTROLS_ANIMATION_TIME = 160;
var SIDE_CONTROLS_ANIMATION_TIME = Overview.ANIMATION_TIME;
function getRtlSlideDirection(direction, actor) {
let rtl = actor.text_direction == Clutter.TextDirection.RTL;
@ -422,6 +423,7 @@ class ControlsManager extends St.Widget {
let activeWorkspaceIndex = workspaceManager.get_active_workspace_index();
this._workspaceAdjustment = new St.Adjustment({
actor: this,
value: activeWorkspaceIndex,
lower: 0,
page_increment: 1,
@ -453,8 +455,6 @@ class ControlsManager extends St.Widget {
this._group.add_child(this.viewSelector);
this._group.add_actor(this._thumbnailsSlider);
layout.connect('allocation-changed', this._updateWorkspacesGeometry.bind(this));
Main.overview.connect('showing', this._updateSpacerVisibility.bind(this));
this.connect('destroy', this._onDestroy.bind(this));
@ -477,26 +477,6 @@ class ControlsManager extends St.Widget {
this._workspaceAdjustment.value = activeIndex;
}
_updateWorkspacesGeometry() {
let [x, y] = this.get_transformed_position();
let [width, height] = this.get_transformed_size();
let geometry = { x, y, width, height };
let spacing = this.get_theme_node().get_length('spacing');
let dashWidth = this._dashSlider.getVisibleWidth() + spacing;
let thumbnailsWidth = this._thumbnailsSlider.getNonExpandedWidth() + spacing;
geometry.width -= dashWidth;
geometry.width -= thumbnailsWidth;
if (this.get_text_direction() == Clutter.TextDirection.LTR)
geometry.x += dashWidth;
else
geometry.x += thumbnailsWidth;
this.viewSelector.setWorkspacesFullGeometry(geometry);
}
_setVisibility() {
// Ignore the case when we're leaving the overview, since
// actors will be made visible again when entering the overview

View File

@ -5,7 +5,6 @@ const { Atk, Clutter, Gio, GLib, GObject, Meta, Shell, St } = imports.gi;
const Cairo = imports.cairo;
const Animation = imports.ui.animation;
const AppDisplay = imports.ui.appDisplay;
const Config = imports.misc.config;
const CtrlAltTab = imports.ui.ctrlAltTab;
const DND = imports.ui.dnd;
@ -61,20 +60,69 @@ function _unpremultiply(color) {
return new Clutter.Color({ red, green, blue, alpha: color.alpha });
}
class AppMenu extends AppDisplay.BaseAppMenu {
class AppMenu extends PopupMenu.PopupMenu {
constructor(sourceActor) {
super(sourceActor, St.Side.TOP);
super(sourceActor, 0.5, St.Side.TOP);
this.actor.add_style_class_name('app-menu');
this._app = null;
this._appSystem = Shell.AppSystem.get_default();
this._windowsChangedId = 0;
/* Translators: This is the heading of a list of open windows */
this.addMenuItem(new PopupMenu.PopupSeparatorMenuItem(_("Open Windows")));
this._windowSection = new PopupMenu.PopupMenuSection();
this.addMenuItem(this._windowSection);
this.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
this._newWindowItem = this.addAction(_("New Window"), () => {
this._app.open_new_window(-1);
});
this.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
this._actionSection = new PopupMenu.PopupMenuSection();
this.addMenuItem(this._actionSection);
this.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
this._detailsItem = this.addAction(_('Show Details'), async () => {
let id = this._app.get_id();
let args = GLib.Variant.new('(ss)', [id, '']);
const bus = await Gio.DBus.get(Gio.BusType.SESSION, null);
bus.call(
'org.gnome.Software',
'/org/gnome/Software',
'org.gtk.Actions', 'Activate',
new GLib.Variant('(sava{sv})', ['details', [args], null]),
null, 0, -1, null);
});
this.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
this.addAction(_("Quit"), () => {
this._app.request_quit();
});
this._appSystem.connect('installed-changed', () => {
this._updateDetailsVisibility();
});
this._updateDetailsVisibility();
}
get app() {
return this._app;
_updateDetailsVisibility() {
let sw = this._appSystem.lookup_app('org.gnome.Software.desktop');
this._detailsItem.visible = sw != null;
}
isEmpty() {
if (!this._app)
return true;
return super.isEmpty();
}
setApp(app) {
@ -109,6 +157,25 @@ class AppMenu extends AppDisplay.BaseAppMenu {
this._newWindowItem.visible =
app && app.can_open_new_window() && !actions.includes('new-window');
}
_updateWindowsSection() {
this._windowSection.removeAll();
if (!this._app)
return;
let windows = this._app.get_windows();
windows.forEach(window => {
let title = window.title || this._app.get_name();
let item = this._windowSection.addAction(title, event => {
Main.activateWindow(window, event.get_time());
});
let id = window.connect('notify::title', () => {
item.label.text = window.title || this._app.get_name();
});
item.connect('destroy', () => window.disconnect(id));
});
}
}
/**
@ -608,7 +675,7 @@ class PanelCorner extends St.DrawingArea {
let borderWidth = node.get_length('-panel-corner-border-width');
this.set_size(cornerRadius, borderWidth + cornerRadius);
this.set_anchor_point(0, borderWidth);
this.translation_y = -borderWidth;
}
});
@ -669,13 +736,11 @@ class AggregateMenu extends PanelMenu.Button {
this._volume = new imports.ui.status.volume.Indicator();
this._brightness = new imports.ui.status.brightness.Indicator();
this._system = new imports.ui.status.system.Indicator();
this._screencast = new imports.ui.status.screencast.Indicator();
this._location = new imports.ui.status.location.Indicator();
this._nightLight = new imports.ui.status.nightLight.Indicator();
this._thunderbolt = new imports.ui.status.thunderbolt.Indicator();
this._indicators.add_child(this._thunderbolt);
this._indicators.add_child(this._screencast);
this._indicators.add_child(this._location);
this._indicators.add_child(this._nightLight);
if (this._network)

View File

@ -183,10 +183,9 @@ var Button = GObject.registerClass({
}
_onDestroy() {
super._onDestroy();
if (this.menu)
this.menu.destroy();
super._onDestroy();
}
});

View File

@ -881,9 +881,10 @@ var PopupMenu = class extends PopupMenuBase {
let state = event.get_state();
// if user has a modifier down (except capslock)
// if user has a modifier down (except capslock and numlock)
// then don't handle the key press here
state &= ~Clutter.ModifierType.LOCK_MASK;
state &= ~Clutter.ModifierType.MOD2_MASK;
state &= Clutter.ModifierType.MODIFIER_MASK;
if (state)
@ -1324,7 +1325,7 @@ var PopupMenuManager = class {
removeMenu(menu) {
if (menu == this.activeMenu)
this._closeMenu(false, menu);
this._grabHelper.ungrab({ actor: menu.actor });
let position = this._findMenu(menu);
if (position == -1) // not a menu we manage

View File

@ -1,146 +0,0 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const { Gio, GLib, Shell } = imports.gi;
const Signals = imports.signals;
const Main = imports.ui.main;
const { loadInterfaceXML } = imports.misc.fileUtils;
const ScreencastIface = loadInterfaceXML('org.gnome.Shell.Screencast');
var ScreencastService = class {
constructor() {
this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(ScreencastIface, this);
this._dbusImpl.export(Gio.DBus.session, '/org/gnome/Shell/Screencast');
Gio.DBus.session.own_name('org.gnome.Shell.Screencast', Gio.BusNameOwnerFlags.REPLACE, null, null);
this._recorders = new Map();
this._lockdownSettings = new Gio.Settings({ schema_id: 'org.gnome.desktop.lockdown' });
Main.sessionMode.connect('updated', this._sessionUpdated.bind(this));
}
get isRecording() {
return this._recorders.size > 0;
}
_ensureRecorderForSender(sender) {
let recorder = this._recorders.get(sender);
if (!recorder) {
recorder = new Shell.Recorder({ stage: global.stage,
display: global.display });
recorder._watchNameId =
Gio.bus_watch_name(Gio.BusType.SESSION, sender, 0, null,
this._onNameVanished.bind(this));
this._recorders.set(sender, recorder);
this.emit('updated');
}
return recorder;
}
_sessionUpdated() {
if (Main.sessionMode.allowScreencast)
return;
for (let sender of this._recorders.keys())
this._stopRecordingForSender(sender);
}
_onNameVanished(connection, name) {
this._stopRecordingForSender(name);
}
_stopRecordingForSender(sender) {
let recorder = this._recorders.get(sender);
if (!recorder)
return false;
Gio.bus_unwatch_name(recorder._watchNameId);
recorder.close();
this._recorders.delete(sender);
this.emit('updated');
return true;
}
_applyOptionalParameters(recorder, options) {
for (let option in options)
options[option] = options[option].deep_unpack();
if (options['pipeline'])
recorder.set_pipeline(options['pipeline']);
if (options['framerate'])
recorder.set_framerate(options['framerate']);
if ('draw-cursor' in options)
recorder.set_draw_cursor(options['draw-cursor']);
}
ScreencastAsync(params, invocation) {
let returnValue = [false, ''];
if (!Main.sessionMode.allowScreencast ||
this._lockdownSettings.get_boolean('disable-save-to-disk')) {
invocation.return_value(GLib.Variant.new('(bs)', returnValue));
return;
}
let sender = invocation.get_sender();
let recorder = this._ensureRecorderForSender(sender);
if (!recorder.is_recording()) {
let [fileTemplate, options] = params;
recorder.set_file_template(fileTemplate);
this._applyOptionalParameters(recorder, options);
let [success, fileName] = recorder.record();
returnValue = [success, fileName ? fileName : ''];
if (!success)
this._stopRecordingForSender(sender);
}
invocation.return_value(GLib.Variant.new('(bs)', returnValue));
}
ScreencastAreaAsync(params, invocation) {
let returnValue = [false, ''];
if (!Main.sessionMode.allowScreencast ||
this._lockdownSettings.get_boolean('disable-save-to-disk')) {
invocation.return_value(GLib.Variant.new('(bs)', returnValue));
return;
}
let sender = invocation.get_sender();
let recorder = this._ensureRecorderForSender(sender);
if (!recorder.is_recording()) {
let [x, y, width, height, fileTemplate, options] = params;
if (x < 0 || y < 0 ||
width <= 0 || height <= 0 ||
x + width > global.screen_width ||
y + height > global.screen_height) {
invocation.return_error_literal(Gio.IOErrorEnum,
Gio.IOErrorEnum.CANCELLED,
"Invalid params");
return;
}
recorder.set_file_template(fileTemplate);
recorder.set_area(x, y, width, height);
this._applyOptionalParameters(recorder, options);
let [success, fileName] = recorder.record();
returnValue = [success, fileName ? fileName : ''];
if (!success)
this._stopRecordingForSender(sender);
}
invocation.return_value(GLib.Variant.new('(bs)', returnValue));
}
StopScreencastAsync(params, invocation) {
let success = this._stopRecordingForSender(invocation.get_sender());
invocation.return_value(GLib.Variant.new('(b)', [success]));
}
};
Signals.addSignalMethods(ScreencastService.prototype);

View File

@ -24,7 +24,8 @@ class RemoteAccessApplet extends PanelMenu.SystemIndicator {
return;
this._handles = new Set();
this._indicator = null;
this._sharedIndicator = null;
this._recordingIndicator = null;
this._menuSection = null;
controller.connect('new-handle', (o, handle) => {
@ -33,32 +34,49 @@ class RemoteAccessApplet extends PanelMenu.SystemIndicator {
}
_ensureControls() {
if (this._indicator)
if (this._sharedIndicator && this._recordingIndicator)
return;
this._indicator = this._addIndicator();
this._indicator.icon_name = 'screen-shared-symbolic';
this._indicator.add_style_class_name('remote-access-indicator');
this._item =
this._sharedIndicator = this._addIndicator();
this._sharedIndicator.icon_name = 'screen-shared-symbolic';
this._sharedIndicator.add_style_class_name('remote-access-indicator');
this._sharedItem =
new PopupMenu.PopupSubMenuMenuItem(_("Screen is Being Shared"),
true);
this._item.menu.addAction(_("Turn off"),
() => {
for (let handle of this._handles)
handle.stop();
});
this._item.icon.icon_name = 'screen-shared-symbolic';
this.menu.addMenuItem(this._item);
this._sharedItem.menu.addAction(_("Turn off"),
() => {
for (let handle of this._handles) {
if (!handle.is_recording)
handle.stop();
}
});
this._sharedItem.icon.icon_name = 'screen-shared-symbolic';
this.menu.addMenuItem(this._sharedItem);
this._recordingIndicator = this._addIndicator();
this._recordingIndicator.icon_name = 'media-record-symbolic';
this._recordingIndicator.add_style_class_name('screencast-indicator');
}
_isScreenShared() {
return [...this._handles].some(handle => !handle.is_recording);
}
_isRecording() {
return [...this._handles].some(handle => handle.is_recording);
}
_sync() {
if (this._handles.size == 0) {
this._indicator.visible = false;
this._item.visible = false;
if (this._isScreenShared()) {
this._sharedIndicator.visible = true;
this._sharedItem.visible = true;
} else {
this._indicator.visible = true;
this._item.visible = true;
this._sharedIndicator.visible = false;
this._sharedItem.visible = false;
}
this._recordingIndicator.visible = this._isRecording();
}
_onStopped(handle) {
@ -70,9 +88,7 @@ class RemoteAccessApplet extends PanelMenu.SystemIndicator {
this._handles.add(handle);
handle.connect('stopped', this._onStopped.bind(this));
if (this._handles.size == 1) {
this._ensureControls();
this._sync();
}
this._ensureControls();
this._sync();
}
});

View File

@ -1,25 +0,0 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
/* exported Indicator */
const GObject = imports.gi.GObject;
const Main = imports.ui.main;
const PanelMenu = imports.ui.panelMenu;
var Indicator = GObject.registerClass(
class Indicator extends PanelMenu.SystemIndicator {
_init() {
super._init();
this._indicator = this._addIndicator();
this._indicator.icon_name = 'media-record-symbolic';
this._indicator.add_style_class_name('screencast-indicator');
this._sync();
Main.screencastService.connect('updated', this._sync.bind(this));
}
_sync() {
this._indicator.visible = Main.screencastService.isRecording;
}
});

View File

@ -62,6 +62,7 @@ var StreamSlider = class {
this._stream = null;
this._volumeCancellable = null;
this._icons = [];
}
get stream() {
@ -182,24 +183,15 @@ var StreamSlider = class {
if (!this._stream)
return null;
let icons = ["audio-volume-muted-symbolic",
"audio-volume-low-symbolic",
"audio-volume-medium-symbolic",
"audio-volume-high-symbolic",
"audio-volume-overamplified-symbolic"];
let volume = this._stream.volume;
let n;
if (this._stream.is_muted || volume <= 0) {
n = 0;
} else {
n = Math.ceil(3 * volume / this._control.get_vol_max_norm());
if (n < 1)
n = 1;
else if (n > 3)
n = 4;
n = Math.clamp(n, 1, this._icons.length - 1);
}
return icons[n];
return this._icons[n];
}
getLevel() {
@ -223,6 +215,13 @@ var OutputStreamSlider = class extends StreamSlider {
constructor(control) {
super(control);
this._slider.accessible_name = _("Volume");
this._icons = [
'audio-volume-muted-symbolic',
'audio-volume-low-symbolic',
'audio-volume-medium-symbolic',
'audio-volume-high-symbolic',
'audio-volume-overamplified-symbolic',
];
}
_connectStream(stream) {
@ -274,6 +273,12 @@ var InputStreamSlider = class extends StreamSlider {
this._control.connect('stream-added', this._maybeShowInput.bind(this));
this._control.connect('stream-removed', this._maybeShowInput.bind(this));
this._icon.icon_name = 'audio-input-microphone-symbolic';
this._icons = [
'microphone-sensitivity-muted-symbolic',
'microphone-sensitivity-low-symbolic',
'microphone-sensitivity-medium-symbolic',
'microphone-sensitivity-high-symbolic',
];
}
_connectStream(stream) {
@ -319,7 +324,7 @@ var VolumeMenu = class extends PopupMenu.PopupMenuSection {
this._output = new OutputStreamSlider(this._control);
this._output.connect('stream-updated', () => {
this.emit('icon-changed');
this.emit('output-icon-changed');
});
this.addMenuItem(this._output.item);
@ -327,6 +332,9 @@ var VolumeMenu = class extends PopupMenu.PopupMenuSection {
this._input.item.connect('notify::visible', () => {
this.emit('input-visible-changed');
});
this._input.connect('stream-updated', () => {
this.emit('input-icon-changed');
});
this.addMenuItem(this._input.item);
this.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
@ -343,7 +351,7 @@ var VolumeMenu = class extends PopupMenu.PopupMenuSection {
this._readInput();
this._readOutput();
} else {
this.emit('icon-changed');
this.emit('output-icon-changed');
}
}
@ -355,10 +363,14 @@ var VolumeMenu = class extends PopupMenu.PopupMenuSection {
this._input.stream = this._control.get_default_source();
}
getIcon() {
getOutputIcon() {
return this._output.getIcon();
}
getInputIcon() {
return this._input.getIcon();
}
getLevel() {
return this._output.getLevel();
}
@ -382,21 +394,24 @@ class Indicator extends PanelMenu.SystemIndicator {
this._control = getMixerControl();
this._volumeMenu = new VolumeMenu(this._control);
this._volumeMenu.connect('icon-changed', () => {
let icon = this._volumeMenu.getIcon();
this._volumeMenu.connect('output-icon-changed', () => {
let icon = this._volumeMenu.getOutputIcon();
if (icon != null)
this._primaryIndicator.icon_name = icon;
this._primaryIndicator.visible = icon !== null;
});
this._inputIndicator.set({
icon_name: 'audio-input-microphone-symbolic',
visible: this._volumeMenu.getInputVisible(),
});
this._inputIndicator.visible = this._volumeMenu.getInputVisible();
this._volumeMenu.connect('input-visible-changed', () => {
this._inputIndicator.visible = this._volumeMenu.getInputVisible();
});
this._volumeMenu.connect('input-icon-changed', () => {
let icon = this._volumeMenu.getInputIcon();
if (icon !== null)
this._inputIndicator.icon_name = icon;
});
this.menu.addMenuItem(this._volumeMenu);
}
@ -406,7 +421,7 @@ class Indicator extends PanelMenu.SystemIndicator {
if (result == Clutter.EVENT_PROPAGATE || this.menu.actor.mapped)
return result;
let gicon = new Gio.ThemedIcon({ name: this._volumeMenu.getIcon() });
let gicon = new Gio.ThemedIcon({ name: this._volumeMenu.getOutputIcon() });
let level = this._volumeMenu.getLevel();
let maxLevel = this._volumeMenu.getMaxLevel();
Main.osdWindowManager.show(-1, gicon, null, level, maxLevel);

View File

@ -485,6 +485,7 @@ var UnlockDialog = GObject.registerClass({
this._gdmClient = new Gdm.Client();
this._adjustment = new St.Adjustment({
actor: this,
lower: 0,
upper: 2,
page_size: 1,
@ -524,6 +525,10 @@ var UnlockDialog = GObject.registerClass({
this._bgManagers = [];
const themeContext = St.ThemeContext.get_for_stage(global.stage);
this._scaleChangedId = themeContext.connect('notify::scale-factor',
() => this._updateBackgroundEffects());
this._updateBackgrounds();
this._monitorsChangedId =
Main.layoutManager.connect('monitors-changed', this._updateBackgrounds.bind(this));
@ -568,11 +573,9 @@ var UnlockDialog = GObject.registerClass({
this._screenSaverSettings = new Gio.Settings({ schema_id: 'org.gnome.desktop.screensaver' });
this._userSwitchEnabledId = 0;
this._userSwitchEnabledId = this._screenSaverSettings.connect('changed::user-switch-enabled',
this._updateUserSwitchVisibility.bind(this));
this._userLoadedId = 0;
this._userLoadedId = this._user.connect('notify::is-loaded',
this._updateUserSwitchVisibility.bind(this));
@ -626,6 +629,7 @@ var UnlockDialog = GObject.registerClass({
y: monitor.y,
width: monitor.width,
height: monitor.height,
effect: new Shell.BlurEffect({ name: 'blur' }),
});
let bgManager = new Background.BackgroundManager({
@ -637,19 +641,17 @@ var UnlockDialog = GObject.registerClass({
this._bgManagers.push(bgManager);
this._backgroundGroup.add_child(widget);
}
_updateBackgroundEffects() {
const themeContext = St.ThemeContext.get_for_stage(global.stage);
let effect = new Shell.BlurEffect({
brightness: BLUR_BRIGHTNESS,
sigma: BLUR_SIGMA * themeContext.scale_factor,
});
this._scaleChangedId = themeContext.connect('notify::scale-factor', () => {
effect.sigma = BLUR_SIGMA * themeContext.scale_factor;
});
widget.add_effect(effect);
for (const widget of this._backgroundGroup) {
widget.get_effect('blur').set({
brightness: BLUR_BRIGHTNESS,
sigma: BLUR_SIGMA * themeContext.scale_factor,
});
}
}
_updateBackgrounds() {
@ -661,6 +663,7 @@ var UnlockDialog = GObject.registerClass({
for (let i = 0; i < Main.layoutManager.monitors.length; i++)
this._createBackground(i);
this._updateBackgroundEffects();
}
_ensureAuthPrompt() {

View File

@ -299,10 +299,6 @@ var ViewSelector = GObject.registerClass({
Main.overview.fadeInDesktop();
}
setWorkspacesFullGeometry(geom) {
this._workspacesDisplay.setWorkspacesFullGeometry(geom);
}
vfunc_hide() {
this.reset();
this._workspacesDisplay.hide();

View File

@ -42,6 +42,11 @@ const GsdWacomProxy = Gio.DBusProxy.makeProxyWrapper(GsdWacomIface);
const WINDOW_DIMMER_EFFECT_NAME = "gnome-shell-window-dimmer";
Gio._promisify(Shell,
'util_start_systemd_unit', 'util_start_systemd_unit_finish');
Gio._promisify(Shell,
'util_stop_systemd_unit', 'util_stop_systemd_unit_finish');
var DisplayChangeDialog = GObject.registerClass(
class DisplayChangeDialog extends ModalDialog.ModalDialog {
_init(wm) {
@ -901,46 +906,23 @@ var WindowManager = class {
global.display.connect('init-xserver', (display, task) => {
IBusManager.getIBusManager().restartDaemon(['--xim']);
try {
if (!Shell.util_start_systemd_unit('gsd-xsettings.target', 'fail'))
log('Not starting gsd-xsettings; waiting for gnome-session to do so');
/* Timeout waiting for start job completion after 5 seconds */
let cancellable = new Gio.Cancellable();
GLib.timeout_add_seconds(GLib.PRIORITY_DEFAULT, 5, () => {
cancellable.cancel();
return GLib.SOURCE_REMOVE;
});
/* Leave this watchdog timeout so don't block indefinitely here */
let timeoutId = GLib.timeout_add_seconds(GLib.PRIORITY_DEFAULT, 5, () => {
Gio.DBus.session.unwatch_name(watchId);
log('Warning: Failed to start gsd-xsettings');
task.return_boolean(true);
timeoutId = 0;
return GLib.SOURCE_REMOVE;
});
/* When gsd-xsettings daemon is started, we are good to resume */
let watchId = Gio.DBus.session.watch_name(
'org.gnome.SettingsDaemon.XSettings',
Gio.BusNameWatcherFlags.NONE,
() => {
Gio.DBus.session.unwatch_name(watchId);
if (timeoutId > 0) {
task.return_boolean(true);
GLib.source_remove(timeoutId);
}
},
null);
} catch (e) {
log('Error starting gsd-xsettings: %s'.format(e.message));
task.return_boolean(true);
}
this._startX11Services(task, cancellable);
return true;
});
global.display.connect('x11-display-closing', () => {
if (!Meta.is_wayland_compositor())
return;
try {
Shell.util_stop_systemd_unit('gsd-xsettings.target', 'fail');
} catch (e) {
log('Error stopping gsd-xsettings: %s'.format(e.message));
}
this._stopX11Services(null);
IBusManager.getIBusManager().restartDaemon();
});
@ -1008,6 +990,36 @@ var WindowManager = class {
global.stage.add_action(topDragAction);
}
async _startX11Services(task, cancellable) {
try {
await Shell.util_start_systemd_unit(
'gnome-session-x11-services-ready.target', 'fail', cancellable);
} catch (e) {
// Ignore NOT_SUPPORTED error, which indicates we are not systemd
// managed and gnome-session will have taken care of everything
// already.
// Note that we do log cancellation from here.
if (!e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.NOT_SUPPORTED))
log('Error starting X11 services: %s'.format(e.message));
} finally {
task.return_boolean(true);
}
}
async _stopX11Services(cancellable) {
try {
await Shell.util_stop_systemd_unit(
'gnome-session-x11-services.target', 'fail', cancellable);
} catch (e) {
// Ignore NOT_SUPPORTED error, which indicates we are not systemd
// managed and gnome-session will have taken care of everything
// already.
// Note that we do log cancellation from here.
if (!e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.NOT_SUPPORTED))
log('Error stopping X11 services: %s'.format(e.message));
}
}
_showPadOsd(display, device, settings, imagePath, editionMode, monitorIndex) {
this._currentPadOsd = new PadOsd.PadOsd(device, settings, imagePath, editionMode, monitorIndex);
this._currentPadOsd.connect('closed', () => (this._currentPadOsd = null));
@ -1800,8 +1812,7 @@ var WindowManager = class {
w.window.get_parent().remove_child(w.window);
w.parent.add_child(w.window);
if (w.window.get_meta_window().get_workspace() !=
global.workspace_manager.get_active_workspace())
if (!w.window.get_meta_window().get_workspace().active)
w.window.hide();
}
switchData.container.destroy();
@ -1985,7 +1996,7 @@ var WindowManager = class {
duration,
mode: Clutter.AnimationMode.EASE_OUT_CUBIC,
onComplete: () => {
if (newWs !== activeWorkspace)
if (!newWs.active)
this.actionMoveWorkspace(newWs);
this._finishWorkspaceSwitch(switchData);
},
@ -2185,10 +2196,7 @@ var WindowManager = class {
if (!Main.sessionMode.hasWorkspaces)
return;
let workspaceManager = global.workspace_manager;
let activeWorkspace = workspaceManager.get_active_workspace();
if (activeWorkspace != workspace)
if (!workspace.active)
workspace.activate(global.get_current_time());
}
@ -2196,10 +2204,7 @@ var WindowManager = class {
if (!Main.sessionMode.hasWorkspaces)
return;
let workspaceManager = global.workspace_manager;
let activeWorkspace = workspaceManager.get_active_workspace();
if (activeWorkspace != workspace) {
if (!workspace.active) {
// This won't have any effect for "always sticky" windows
// (like desktop windows or docks)

View File

@ -67,8 +67,12 @@ var WindowPreviewLayout = GObject.registerClass({
vfunc_allocate(container, box) {
// If the scale isn't 1, we weren't allocated our preferred size
// and have to scale the children allocations accordingly.
const scaleX = box.get_width() / this._boundingBox.get_width();
const scaleY = box.get_height() / this._boundingBox.get_height();
const scaleX = this._boundingBox.get_width() > 0
? box.get_width() / this._boundingBox.get_width()
: 1;
const scaleY = this._boundingBox.get_height() > 0
? box.get_height() / this._boundingBox.get_height()
: 1;
const childBox = new Clutter.ActorBox();
@ -93,7 +97,7 @@ var WindowPreviewLayout = GObject.registerClass({
child.allocate(childBox);
} else {
child.allocate_preferred_size();
child.allocate_preferred_size(0, 0);
}
}
}
@ -185,6 +189,12 @@ var WindowPreviewLayout = GObject.registerClass({
});
var WindowPreview = GObject.registerClass({
Properties: {
'overlay-enabled': GObject.ParamSpec.boolean(
'overlay-enabled', 'overlay-enabled', 'overlay-enabled',
GObject.ParamFlags.READWRITE,
true),
},
Signals: {
'drag-begin': {},
'drag-cancelled': {},
@ -219,7 +229,6 @@ var WindowPreview = GObject.registerClass({
this._delegate = this;
this.slotId = 0;
this._stackAbove = null;
this._windowContainer.layout_manager.connect(
@ -233,8 +242,6 @@ var WindowPreview = GObject.registerClass({
this._windowActor.connect('destroy', () => this.destroy());
this._updateAttachedDialogs();
this.x = this.boundingBox.x;
this.y = this.boundingBox.y;
let clickAction = new Clutter.ClickAction();
clickAction.connect('clicked', () => this._activate());
@ -253,6 +260,7 @@ var WindowPreview = GObject.registerClass({
this.inDrag = false;
this._selected = false;
this._overlayEnabled = true;
this._closeRequested = false;
this._idleHideOverlayId = 0;
@ -345,6 +353,14 @@ var WindowPreview = GObject.registerClass({
this.add_child(this._border);
this.add_child(this._title);
this.add_child(this._closeButton);
this.connect('notify::realized', () => {
if (!this.realized)
return;
this._border.ensure_style();
this._title.ensure_style();
});
}
vfunc_get_preferred_width(forHeight) {
@ -399,8 +415,6 @@ var WindowPreview = GObject.registerClass({
}
chromeHeights() {
this._border.ensure_style();
this._title.ensure_style();
const [, closeButtonHeight] = this._closeButton.get_preferred_height(-1);
const [, titleHeight] = this._title.get_preferred_height(-1);
@ -413,7 +427,6 @@ var WindowPreview = GObject.registerClass({
}
chromeWidths() {
this._border.ensure_style();
const [, closeButtonWidth] = this._closeButton.get_preferred_width(-1);
const leftOversize = this._closeButtonSide === St.Side.LEFT
@ -427,6 +440,9 @@ var WindowPreview = GObject.registerClass({
}
showOverlay(animate) {
if (!this._overlayEnabled)
return;
const ongoingTransition = this._border.get_transition('opacity');
// Don't do anything if we're fully visible already
@ -562,6 +578,25 @@ var WindowPreview = GObject.registerClass({
});
}
// eslint-disable-next-line camelcase
get overlay_enabled() {
return this._overlayEnabled;
}
// eslint-disable-next-line camelcase
set overlay_enabled(enabled) {
if (this._overlayEnabled === enabled)
return;
this._overlayEnabled = enabled;
this.notify('overlay-enabled');
if (!enabled)
this.hideOverlay(false);
else if (this['has-pointer'] || global.stage.key_focus === this)
this.showOverlay(true);
}
// Find the actor just below us, respecting reparenting done by DND code
_getActualStackAbove() {
if (this._stackAbove == null)

File diff suppressed because it is too large Load Diff

View File

@ -11,7 +11,10 @@ var DISPLAY_TIMEOUT = 600;
var WorkspaceSwitcherPopupList = GObject.registerClass(
class WorkspaceSwitcherPopupList extends St.Widget {
_init() {
super._init({ style_class: 'workspace-switcher' });
super._init({
style_class: 'workspace-switcher',
offscreen_redirect: Clutter.OffscreenRedirect.ALWAYS,
});
this._itemSpacing = 0;
this._childHeight = 0;

View File

@ -549,9 +549,7 @@ var WorkspaceThumbnail = GObject.registerClass({
return;
// a click on the already current workspace should go back to the main view
let workspaceManager = global.workspace_manager;
let activeWorkspace = workspaceManager.get_active_workspace();
if (this.metaWorkspace == activeWorkspace)
if (this.metaWorkspace.active)
Main.overview.hide();
else
this.metaWorkspace.activate(time);

View File

@ -7,6 +7,7 @@ const Main = imports.ui.main;
const SwipeTracker = imports.ui.swipeTracker;
const Workspace = imports.ui.workspace;
var { ANIMATION_TIME } = imports.ui.overview;
var WORKSPACE_SWITCH_TIME = 250;
var SCROLL_TIMEOUT_TIME = 150;
@ -21,18 +22,18 @@ var WorkspacesViewBase = GObject.registerClass({
GTypeFlags: GObject.TypeFlags.ABSTRACT,
}, class WorkspacesViewBase extends St.Widget {
_init(monitorIndex) {
super._init({ style_class: 'workspaces-view', reactive: true });
const { x, y, width, height } =
Main.layoutManager.getWorkAreaForMonitor(monitorIndex);
super._init({
style_class: 'workspaces-view',
x, y, width, height,
});
this.connect('destroy', this._onDestroy.bind(this));
global.focus_manager.add_group(this);
// The actor itself isn't a drop target, so we don't want to pick on its area
this.set_size(0, 0);
this._monitorIndex = monitorIndex;
this._fullGeometry = null;
this._actualGeometry = null;
this._inDrag = false;
this._windowDragBeginId = Main.overview.connect('window-drag-begin', this._dragBegin.bind(this));
this._windowDragEndId = Main.overview.connect('window-drag-end', this._dragEnd.bind(this));
@ -51,24 +52,19 @@ var WorkspacesViewBase = GObject.registerClass({
}
}
_dragBegin(overview, window) {
_dragBegin() {
this._inDrag = true;
this._setReservedSlot(window);
}
_dragEnd() {
this._inDrag = false;
this._setReservedSlot(null);
}
setFullGeometry(geom) {
this._fullGeometry = geom;
this._syncFullGeometry();
}
vfunc_allocate(box) {
this.set_allocation(box);
setActualGeometry(geom) {
this._actualGeometry = geom;
this._syncActualGeometry();
for (const child of this)
child.allocate_available_size(0, 0, box.get_width(), box.get_height());
}
});
@ -83,9 +79,8 @@ class WorkspacesView extends WorkspacesViewBase {
this._gestureActive = false; // touch(pad) gestures
this._scrollAdjustment = scrollAdjustment;
this._onScrollId =
this._scrollAdjustment.connect('notify::value',
this._onScroll.bind(this));
this._onScrollId = this._scrollAdjustment.connect('notify::value',
this._updateScrollPosition.bind(this));
this._workspaces = [];
this._updateWorkspaces();
@ -97,34 +92,42 @@ class WorkspacesView extends WorkspacesViewBase {
this._workspaces.sort((a, b) => {
return a.metaWorkspace.index() - b.metaWorkspace.index();
});
this._updateWorkspaceActors(false);
this._workspaces.forEach(
(ws, i) => this.set_child_at_index(ws, i));
});
this._overviewShownId =
Main.overview.connect('shown', () => {
this.set_clip(this._fullGeometry.x, this._fullGeometry.y,
this._fullGeometry.width, this._fullGeometry.height);
});
this._overviewShownId = Main.overview.connect('shown', () => {
this.clip_to_allocation = true;
});
this._switchWorkspaceNotifyId =
global.window_manager.connect('switch-workspace',
this._activeWorkspaceChanged.bind(this));
}
_setReservedSlot(window) {
for (let i = 0; i < this._workspaces.length; i++)
this._workspaces[i].setReservedSlot(window);
}
vfunc_allocate(box) {
this.set_allocation(box);
_syncFullGeometry() {
for (let i = 0; i < this._workspaces.length; i++)
this._workspaces[i].setFullGeometry(this._fullGeometry);
}
if (this.get_n_children() === 0)
return;
_syncActualGeometry() {
for (let i = 0; i < this._workspaces.length; i++)
this._workspaces[i].setActualGeometry(this._actualGeometry);
const { workspaceManager } = global;
const { nWorkspaces } = workspaceManager;
const vertical = workspaceManager.layout_rows === -1;
const rtl = this.text_direction === Clutter.TextDirection.RTL;
this._workspaces.forEach((child, index) => {
if (rtl && !vertical)
index = nWorkspaces - index - 1;
const x = vertical ? 0 : index * this.width;
const y = vertical ? index * this.height : 0;
child.allocate_available_size(x, y, box.get_width(), box.get_height());
});
this._updateScrollPosition();
}
getActiveWorkspace() {
@ -140,11 +143,11 @@ class WorkspacesView extends WorkspacesViewBase {
else
this._workspaces[w].fadeToOverview();
}
this._updateWorkspaceActors(false);
this._updateScrollPosition();
}
animateFromOverview(animationType) {
this.remove_clip();
this.clip_to_allocation = false;
for (let w = 0; w < this._workspaces.length; w++) {
if (animationType == AnimationType.ZOOM)
@ -159,49 +162,22 @@ class WorkspacesView extends WorkspacesViewBase {
this._workspaces[i].syncStacking(stackIndices);
}
// Update workspace actors parameters
// @showAnimation: iff %true, transition between states
_updateWorkspaceActors(showAnimation) {
let workspaceManager = global.workspace_manager;
let active = workspaceManager.get_active_workspace_index();
_scrollToActive() {
const { workspaceManager } = global;
const active = workspaceManager.get_active_workspace_index();
this._animating = showAnimation;
this._animating = true;
this._updateVisibility();
for (let w = 0; w < this._workspaces.length; w++) {
let workspace = this._workspaces[w];
workspace.remove_all_transitions();
let params = {};
if (workspaceManager.layout_rows == -1)
params.y = (w - active) * this._fullGeometry.height;
else if (this.text_direction == Clutter.TextDirection.RTL)
params.x = (active - w) * this._fullGeometry.width;
else
params.x = (w - active) * this._fullGeometry.width;
if (showAnimation) {
let easeParams = Object.assign(params, {
duration: WORKSPACE_SWITCH_TIME,
mode: Clutter.AnimationMode.EASE_OUT_CUBIC,
});
// we have to call _updateVisibility() once before the
// animation and once afterwards - it does not really
// matter which tween we use, so we pick the first one ...
if (w == 0) {
this._updateVisibility();
easeParams.onComplete = () => {
this._animating = false;
this._updateVisibility();
};
}
workspace.ease(easeParams);
} else {
workspace.set(params);
if (w == 0)
this._updateVisibility();
}
}
this._scrollAdjustment.remove_transition('value');
this._scrollAdjustment.ease(active, {
duration: WORKSPACE_SWITCH_TIME,
mode: Clutter.AnimationMode.EASE_OUT_CUBIC,
onComplete: () => {
this._animating = false;
this._updateVisibility();
},
});
}
_updateVisibility() {
@ -242,19 +218,14 @@ class WorkspacesView extends WorkspacesViewBase {
}
}
if (this._fullGeometry) {
this._updateWorkspaceActors(false);
this._syncFullGeometry();
}
if (this._actualGeometry)
this._syncActualGeometry();
this._updateScrollPosition();
}
_activeWorkspaceChanged(_wm, _from, _to, _direction) {
if (this._scrolling)
return;
this._updateWorkspaceActors(true);
this._scrollToActive();
}
_onDestroy() {
@ -270,27 +241,33 @@ class WorkspacesView extends WorkspacesViewBase {
startTouchGesture() {
this._gestureActive = true;
this._updateVisibility();
}
endTouchGesture() {
this._gestureActive = false;
// Make sure title captions etc are shown as necessary
this._updateWorkspaceActors(true);
this._scrollToActive();
this._updateVisibility();
}
// sync the workspaces' positions to the value of the scroll adjustment
// and change the active workspace if appropriate
_onScroll(adj) {
if (adj.get_transition('value') !== null && !this._gestureActive)
_updateScrollPosition() {
if (!this.has_allocation())
return;
const adj = this._scrollAdjustment;
const allowSwitch =
adj.get_transition('value') === null && !this._gestureActive;
let workspaceManager = global.workspace_manager;
let active = workspaceManager.get_active_workspace_index();
let current = Math.round(adj.value);
if (active != current && !this._gestureActive) {
if (allowSwitch && active !== current) {
if (!this._workspaces[current]) {
// The current workspace was destroyed. This could happen
// when you are on the last empty workspace, and consolidate
@ -307,36 +284,16 @@ class WorkspacesView extends WorkspacesViewBase {
if (adj.upper == 1)
return;
let last = this._workspaces.length - 1;
const vertical = workspaceManager.layout_rows === -1;
const rtl = this.text_direction === Clutter.TextDirection.RTL;
const progress = vertical || !rtl
? adj.value : adj.upper - adj.value;
if (workspaceManager.layout_rows == -1) {
let firstWorkspaceY = this._workspaces[0].y;
let lastWorkspaceY = this._workspaces[last].y;
let workspacesHeight = lastWorkspaceY - firstWorkspaceY;
let currentY = firstWorkspaceY;
let newY = -Math.round(adj.value / (adj.upper - 1) * workspacesHeight);
let dy = newY - currentY;
for (let i = 0; i < this._workspaces.length; i++) {
this._workspaces[i].visible = Math.abs(i - adj.value) <= 1;
this._workspaces[i].y += dy;
}
} else {
let firstWorkspaceX = this._workspaces[0].x;
let lastWorkspaceX = this._workspaces[last].x;
let workspacesWidth = lastWorkspaceX - firstWorkspaceX;
let currentX = firstWorkspaceX;
let newX = -Math.round(adj.value / (adj.upper - 1) * workspacesWidth);
let dx = newX - currentX;
for (let i = 0; i < this._workspaces.length; i++) {
this._workspaces[i].visible = Math.abs(i - adj.value) <= 1;
this._workspaces[i].x += dx;
}
for (const ws of this._workspaces) {
if (vertical)
ws.translation_y = -progress * this.height;
else
ws.translation_x = -progress * this.width;
}
}
});
@ -349,18 +306,6 @@ class ExtraWorkspaceView extends WorkspacesViewBase {
this.add_actor(this._workspace);
}
_setReservedSlot(window) {
this._workspace.setReservedSlot(window);
}
_syncFullGeometry() {
this._workspace.setFullGeometry(this._fullGeometry);
}
_syncActualGeometry() {
this._workspace.setActualGeometry(this._actualGeometry);
}
getActiveWorkspace() {
return this._workspace;
}
@ -438,6 +383,10 @@ class WorkspacesDisplay extends St.Widget {
this._windowDragEndId =
Main.overview.connect('window-drag-begin',
this._windowDragEnd.bind(this));
this._overviewShownId = Main.overview.connect('shown', () => {
this._inWindowFade = false;
this._syncWorkspacesActualGeometry();
});
this._primaryIndex = Main.layoutManager.primaryIndex;
this._workspacesViews = [];
@ -452,10 +401,11 @@ class WorkspacesDisplay extends St.Widget {
this._scrollEventId = 0;
this._keyPressEventId = 0;
this._scrollTimeoutId = 0;
this._syncActualGeometryLater = 0;
this._actualGeometry = null;
this._fullGeometry = null;
this._inWindowDrag = false;
this._inWindowFade = false;
this._gestureActive = false; // touch(pad) gestures
this._canScroll = true; // limiting scrolling speed
@ -476,6 +426,11 @@ class WorkspacesDisplay extends St.Widget {
this._parentSetLater = 0;
}
if (this._syncActualGeometryLater) {
Meta.later_remove(this._syncActualGeometryLater);
this._syncActualGeometryLater = 0;
}
if (this._scrollTimeoutId !== 0) {
GLib.source_remove(this._scrollTimeoutId);
this._scrollTimeoutId = 0;
@ -485,6 +440,7 @@ class WorkspacesDisplay extends St.Widget {
global.workspace_manager.disconnect(this._reorderWorkspacesdId);
Main.overview.disconnect(this._windowDragBeginId);
Main.overview.disconnect(this._windowDragEndId);
Main.overview.disconnect(this._overviewShownId);
}
_windowDragBegin() {
@ -508,25 +464,11 @@ class WorkspacesDisplay extends St.Widget {
workspaceManager.get_active_workspace_index();
}
_activeWorkspaceChanged(_wm, _from, _to, _direction) {
_activeWorkspaceChanged(_wm, _from, to, _direction) {
if (this._gestureActive)
return;
this._scrollToActive();
}
_scrollToActive() {
let workspaceManager = global.workspace_manager;
let active = workspaceManager.get_active_workspace_index();
this._updateScrollAdjustment(active);
}
_updateScrollAdjustment(index) {
if (this._gestureActive)
return;
this._scrollAdjustment.ease(index, {
this._scrollAdjustment.ease(to, {
mode: Clutter.AnimationMode.EASE_OUT_CUBIC,
duration: WORKSPACE_SWITCH_TIME,
});
@ -564,11 +506,8 @@ class WorkspacesDisplay extends St.Widget {
for (let i = 0; i < this._workspacesViews.length; i++)
this._workspacesViews[i].startTouchGesture();
let monitors = Main.layoutManager.monitors;
let geometry = monitor === this._primaryIndex
? this._fullGeometry : monitors[monitor];
let distance = global.workspace_manager.layout_rows === -1
? geometry.height : geometry.width;
? this.height : this.width;
let progress = adjustment.value / adjustment.page_size;
let points = Array.from(
@ -588,14 +527,13 @@ class WorkspacesDisplay extends St.Widget {
this._clickAction.release();
let workspaceManager = global.workspace_manager;
let activeWorkspace = workspaceManager.get_active_workspace();
let newWs = workspaceManager.get_workspace_by_index(endProgress);
this._scrollAdjustment.ease(endProgress, {
mode: Clutter.AnimationMode.EASE_OUT_CUBIC,
duration,
onComplete: () => {
if (newWs !== activeWorkspace)
if (!newWs.active)
newWs.activate(global.get_current_time());
this._endTouchGesture();
},
@ -616,17 +554,20 @@ class WorkspacesDisplay extends St.Widget {
this.show();
this._updateWorkspacesViews();
if (this._actualGeometry && this._fullGeometry) {
for (let i = 0; i < this._workspacesViews.length; i++) {
let animationType;
if (fadeOnPrimary && i == this._primaryIndex)
animationType = AnimationType.FADE;
else
animationType = AnimationType.ZOOM;
this._workspacesViews[i].animateToOverview(animationType);
}
for (let i = 0; i < this._workspacesViews.length; i++) {
let animationType;
if (fadeOnPrimary && i == this._primaryIndex)
animationType = AnimationType.FADE;
else
animationType = AnimationType.ZOOM;
this._workspacesViews[i].animateToOverview(animationType);
}
this._inWindowFade = fadeOnPrimary;
if (this._actualGeometry && !fadeOnPrimary)
this._syncWorkspacesActualGeometry();
this._restackedNotifyId =
Main.overview.connect('windows-restacked',
this._onRestacked.bind(this));
@ -646,6 +587,17 @@ class WorkspacesDisplay extends St.Widget {
animationType = AnimationType.ZOOM;
this._workspacesViews[i].animateFromOverview(animationType);
}
this._inWindowFade = fadeOnPrimary;
const { primaryIndex } = Main.layoutManager;
const { x, y, width, height } =
Main.layoutManager.getWorkAreaForMonitor(primaryIndex);
this._getPrimaryView().ease({
x, y, width, height,
duration: fadeOnPrimary ? 0 : ANIMATION_TIME,
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
});
}
vfunc_hide() {
@ -675,6 +627,7 @@ class WorkspacesDisplay extends St.Widget {
return;
this._updateWorkspacesViews();
this._syncWorkspacesActualGeometry();
}
_updateWorkspacesViews() {
@ -691,19 +644,9 @@ class WorkspacesDisplay extends St.Widget {
else
view = new WorkspacesView(i, this._scrollAdjustment);
// HACK: Avoid spurious allocation changes while updating views
view.hide();
this._workspacesViews.push(view);
Main.layoutManager.overviewGroup.add_actor(view);
}
this._workspacesViews.forEach(v => v.show());
if (this._fullGeometry)
this._syncWorkspacesFullGeometry();
if (this._actualGeometry)
this._syncWorkspacesActualGeometry();
}
_getMonitorIndexForEvent(event) {
@ -750,43 +693,35 @@ class WorkspacesDisplay extends St.Widget {
});
}
// This geometry should always be the fullest geometry
// the workspaces switcher can ever be allocated, as if
// the sliding controls were never slid in at all.
setWorkspacesFullGeometry(geom) {
this._fullGeometry = geom;
this._syncWorkspacesFullGeometry();
}
_syncWorkspacesFullGeometry() {
if (!this._workspacesViews.length)
return;
let monitors = Main.layoutManager.monitors;
for (let i = 0; i < monitors.length; i++) {
let geometry = i == this._primaryIndex ? this._fullGeometry : monitors[i];
this._workspacesViews[i].setFullGeometry(geometry);
}
}
_updateWorkspacesActualGeometry() {
const [x, y] = this.get_transformed_position();
const width = this.allocation.get_width();
const height = this.allocation.get_height();
this._actualGeometry = { x, y, width, height };
this._syncWorkspacesActualGeometry();
if (this._syncActualGeometryLater > 0)
return;
this._syncActualGeometryLater =
Meta.later_add(Meta.LaterType.BEFORE_REDRAW, () => {
this._syncWorkspacesActualGeometry();
this._syncActualGeometryLater = 0;
return GLib.SOURCE_REMOVE;
});
}
_syncWorkspacesActualGeometry() {
if (!this._workspacesViews.length)
const primaryView = this._getPrimaryView();
if (!primaryView || this._inWindowFade)
return;
let monitors = Main.layoutManager.monitors;
for (let i = 0; i < monitors.length; i++) {
let geometry = i === this._primaryIndex ? this._actualGeometry : monitors[i];
this._workspacesViews[i].setActualGeometry(geometry);
}
primaryView.ease({
...this._actualGeometry,
duration: Main.overview.animationInProgress ? ANIMATION_TIME : 0,
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
});
}
_onRestacked(overview, stackIndices) {

View File

@ -1,5 +1,5 @@
project('gnome-shell', 'c',
version: '3.37.2',
version: '3.37.3',
meson_version: '>= 0.53.0',
license: 'GPLv2+'
)
@ -25,7 +25,7 @@ gio_req = '>= 2.56.0'
gi_req = '>= 1.49.1'
gjs_req = '>= 1.65.1'
gtk_req = '>= 3.15.0'
mutter_req = '>= 3.37.2'
mutter_req = '>= 3.37.3'
polkit_req = '>= 0.100'
schemas_req = '>= 3.33.1'
startup_req = '>= 0.11'
@ -96,9 +96,10 @@ gnome_desktop_dep = dependency('gnome-desktop-3.0', version: gnome_desktop_req)
bt_dep = dependency('gnome-bluetooth-1.0', version: bt_req, required: false)
gst_dep = dependency('gstreamer-1.0', version: gst_req, required: false)
gst_base_dep = dependency('gstreamer-base-1.0', required: false)
pipewire_dep = dependency('libpipewire-0.3', required: false)
recorder_deps = []
enable_recorder = gst_dep.found() and gst_base_dep.found()
enable_recorder = gst_dep.found() and gst_base_dep.found() and pipewire_dep.found()
if enable_recorder
recorder_deps += [gst_dep, gst_base_dep, gtk_dep, x11_dep]
endif

1
mutter

Submodule mutter deleted from 1551b6d386

315
po/ca.po
View File

@ -10,7 +10,7 @@ msgid ""
msgstr ""
"Project-Id-Version: HEAD\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gnome-shell/issues\n"
"POT-Creation-Date: 2020-06-05 23:11+0000\n"
"POT-Creation-Date: 2020-07-22 01:49+0000\n"
"PO-Revision-Date: 2020-05-15 20:39+0200\n"
"Last-Translator: Robert Antoni Buj Gelonch <rbuj@fedoraproject.org>\n"
"Language-Team: Catalan <tradgnome@softcatala.org>\n"
@ -64,8 +64,8 @@ msgid ""
"Allows access to internal debugging and monitoring tools using the Alt-F2 "
"dialog."
msgstr ""
"Permet l'accés a les eines de depuració i de seguiment internes a través del "
"diàleg de l'Alt+F2."
"Permet l'accés a les eines de depuració i de seguiment internes a través del"
" diàleg de l'Alt+F2."
#: data/org.gnome.shell.gschema.xml.in:16
msgid "UUIDs of extensions to enable"
@ -74,9 +74,9 @@ msgstr ""
#: data/org.gnome.shell.gschema.xml.in:17
msgid ""
"GNOME Shell extensions have a UUID property; this key lists extensions which "
"should be loaded. Any extension that wants to be loaded needs to be in this "
"list. You can also manipulate this list with the EnableExtension and "
"GNOME Shell extensions have a UUID property; this key lists extensions which"
" should be loaded. Any extension that wants to be loaded needs to be in this"
" list. You can also manipulate this list with the EnableExtension and "
"DisableExtension D-Bus methods on org.gnome.Shell."
msgstr ""
"Les extensions del GNOME Shell tenen un identificador universal. Aquesta "
@ -92,18 +92,19 @@ msgstr ""
#: data/org.gnome.shell.gschema.xml.in:27
msgid ""
"GNOME Shell extensions have a UUID property; this key lists extensions which "
"should be disabled, even if loaded as part of the current mode. You can also "
"manipulate this list with the EnableExtension and DisableExtension D-Bus "
"methods on org.gnome.Shell. This key takes precedence over the “enabled-"
"extensions” setting."
"GNOME Shell extensions have a UUID property; this key lists extensions which"
" should be disabled, even if loaded as part of the current mode. You can "
"also manipulate this list with the EnableExtension and DisableExtension "
"D-Bus methods on org.gnome.Shell. This key takes precedence over the "
"“enabled-extensions” setting."
msgstr ""
"Les extensions del GNOME Shell tenen un identificador universal. Aquesta "
"clau conté una llista de les extensions que s'han de carregar. Qualsevol "
"extensió que s'hagi de carregar ha de ser a la llista. Podeu modificar "
"aquesta llista amb els mètodes de D-Bus «EnableExtension» (activa una "
"extensió) i «DisableExtension» (desactiva una extensió) a org.gnome.Shell."
"Aquesta clau té preferència sobre el paràmetre «enabled-extensions»."
"extensió) i «DisableExtension» (desactiva una extensió) a "
"org.gnome.Shell.Aquesta clau té preferència sobre el paràmetre «enabled-"
"extensions»."
#: data/org.gnome.shell.gschema.xml.in:37
msgid "Disable user extensions"
@ -127,20 +128,21 @@ msgid ""
"running version. Enabling this option will disable this check and try to "
"load all extensions regardless of the versions they claim to support."
msgstr ""
"El GNOME Shell només carregarà extensions que afirmin ser compatibles amb la "
"versió en execució. Si s'activa aquesta opció, es desactivarà la comprovació "
"i es provarà de carregar totes les extensions sense tenir en compte les "
"versions amb què afirmin ser compatibles."
"El GNOME Shell només carregarà extensions que afirmin ser compatibles amb la"
" versió en execució. Si s'activa aquesta opció, es desactivarà la "
"comprovació i es provarà de carregar totes les extensions sense tenir en "
"compte les versions amb què afirmin ser compatibles."
#: data/org.gnome.shell.gschema.xml.in:54
msgid "List of desktop file IDs for favorite applications"
msgstr ""
"Llista d'identificadors de fitxers d'escriptori de les aplicacions preferides"
"Llista d'identificadors de fitxers d'escriptori de les aplicacions "
"preferides"
#: data/org.gnome.shell.gschema.xml.in:55
msgid ""
"The applications corresponding to these identifiers will be displayed in the "
"favorites area."
"The applications corresponding to these identifiers will be displayed in the"
" favorites area."
msgstr ""
"Es mostraran, a l'àrea de preferits, les aplicacions que corresponguin a "
"aquests identificadors."
@ -158,7 +160,8 @@ msgstr ""
msgid "History for command (Alt-F2) dialog"
msgstr "Historial de les ordres utilitzades en el diàleg de l'Alt+F2"
#. Translators: looking glass is a debugger and inspector tool, see https://wiki.gnome.org/Projects/GnomeShell/LookingGlass
#. Translators: looking glass is a debugger and inspector tool, see
#. https://wiki.gnome.org/Projects/GnomeShell/LookingGlass
#: data/org.gnome.shell.gschema.xml.in:74
msgid "History for the looking glass dialog"
msgstr "Historial del depurador del GNOME Shell"
@ -169,8 +172,8 @@ msgstr "Mostra sempre l'element de menú «Surt» al menú d'usuari."
#: data/org.gnome.shell.gschema.xml.in:79
msgid ""
"This key overrides the automatic hiding of the “Log out” menu item in single-"
"user, single-session situations."
"This key overrides the automatic hiding of the “Log out” menu item in "
"single-user, single-session situations."
msgstr ""
"Aquesta clau sobreescriu l'ocultació automàtica de l'element de menú «Surt» "
"quan només hi ha un usuari i un sol tipus de sessió."
@ -179,7 +182,7 @@ msgstr ""
msgid ""
"Whether to remember password for mounting encrypted or remote filesystems"
msgstr ""
"Si s'han de recordar les contrasenyes dels punts de muntatge encriptats o "
"Si s'han de recordar les contrasenyes dels punts de muntatge xifrat o "
"els sistemes de fitxers remots"
#: data/org.gnome.shell.gschema.xml.in:87
@ -190,7 +193,7 @@ msgid ""
"state of the checkbox."
msgstr ""
"El GNOME Shell us demanarà la contrasenya quan es munti un dispositiu "
"encriptat o un sistema de fitxers remot. Si es pot desar la contrasenya per "
"xifrat o un sistema de fitxers remot. Si es pot desar la contrasenya per "
"a utilitzar-la en el futur, es mostrarà la casella de selecció «Recorda la "
"contrasenya». Aquesta clau estableix el valor per defecte d'aquesta casella "
"de selecció."
@ -226,93 +229,110 @@ msgstr ""
"Habilita una API D-BUS que permet la introspecció de l'estat de l'aplicació "
"del Shell."
#: data/org.gnome.shell.gschema.xml.in:119
#: data/org.gnome.shell.gschema.xml.in:114
msgid "Layout of the app picker"
msgstr "Disposició del selector d'aplicacions"
#: data/org.gnome.shell.gschema.xml.in:115
msgid ""
"Layout of the app picker. Each entry in the array is a page. Pages are "
"stored in the order they appear in GNOME Shell. Each page contains an "
"“application id” → 'data' pair. Currently, the following values are stored "
"as 'data': • “position”: the position of the application icon in the page"
msgstr ""
"Disposició del selector d'aplicacions. Cada entrada de la matriu és una "
"pàgina. Les pàgines s'emmagatzemen en l'ordre en què apareixen al GNOME "
"Shell. Cada pàgina conté un «id de l'aplicació» → parell de «dades». "
"Actualment els valors següents s'emmagatzemen com a «dades»: • «posició» la "
"posició de la icona de l'aplicació a la pàgina"
#: data/org.gnome.shell.gschema.xml.in:130
msgid "Keybinding to open the application menu"
msgstr "Vinculació per a obrir el menú d'aplicació"
#: data/org.gnome.shell.gschema.xml.in:120
#: data/org.gnome.shell.gschema.xml.in:131
msgid "Keybinding to open the application menu."
msgstr "La vinculació per a obrir el menú d'aplicació."
#: data/org.gnome.shell.gschema.xml.in:126
#: data/org.gnome.shell.gschema.xml.in:137
msgid "Keybinding to open the “Show Applications” view"
msgstr "Vinculació de tecles per a obrir la vista «Mostra les aplicacions»"
#: data/org.gnome.shell.gschema.xml.in:127
#: data/org.gnome.shell.gschema.xml.in:138
msgid ""
"Keybinding to open the “Show Applications” view of the Activities Overview."
msgstr ""
"Vinculació de tecles per a obrir la vista «Mostra les aplicacions» de les "
"activitats de la vista general."
#: data/org.gnome.shell.gschema.xml.in:134
#: data/org.gnome.shell.gschema.xml.in:145
msgid "Keybinding to open the overview"
msgstr "Vinculació per a obrir la vista general"
#: data/org.gnome.shell.gschema.xml.in:135
#: data/org.gnome.shell.gschema.xml.in:146
msgid "Keybinding to open the Activities Overview."
msgstr "Vinculació per a obrir la vista general d'activitats."
#: data/org.gnome.shell.gschema.xml.in:141
#: data/org.gnome.shell.gschema.xml.in:152
msgid "Keybinding to toggle the visibility of the notification list"
msgstr ""
"La vinculació per a commutar la visibilitat de la llista de notificacions"
#: data/org.gnome.shell.gschema.xml.in:142
#: data/org.gnome.shell.gschema.xml.in:153
msgid "Keybinding to toggle the visibility of the notification list."
msgstr ""
"La vinculació per a commutar la visibilitat de la llista de notificacions."
#: data/org.gnome.shell.gschema.xml.in:148
#: data/org.gnome.shell.gschema.xml.in:159
msgid "Keybinding to focus the active notification"
msgstr "Vinculació per a posar el focus a la notificació activa"
#: data/org.gnome.shell.gschema.xml.in:149
#: data/org.gnome.shell.gschema.xml.in:160
msgid "Keybinding to focus the active notification."
msgstr "Vinculació per a posar el focus a la notificació activa."
#: data/org.gnome.shell.gschema.xml.in:155
#: data/org.gnome.shell.gschema.xml.in:166
msgid "Switch to application 1"
msgstr "Commuta a l'aplicació 1"
#: data/org.gnome.shell.gschema.xml.in:159
#: data/org.gnome.shell.gschema.xml.in:170
msgid "Switch to application 2"
msgstr "Commuta a l'aplicació 2"
#: data/org.gnome.shell.gschema.xml.in:163
#: data/org.gnome.shell.gschema.xml.in:174
msgid "Switch to application 3"
msgstr "Commuta a l'aplicació 3"
#: data/org.gnome.shell.gschema.xml.in:167
#: data/org.gnome.shell.gschema.xml.in:178
msgid "Switch to application 4"
msgstr "Commuta a l'aplicació 4"
#: data/org.gnome.shell.gschema.xml.in:171
#: data/org.gnome.shell.gschema.xml.in:182
msgid "Switch to application 5"
msgstr "Commuta a l'aplicació 5"
#: data/org.gnome.shell.gschema.xml.in:175
#: data/org.gnome.shell.gschema.xml.in:186
msgid "Switch to application 6"
msgstr "Commuta a l'aplicació 6"
#: data/org.gnome.shell.gschema.xml.in:179
#: data/org.gnome.shell.gschema.xml.in:190
msgid "Switch to application 7"
msgstr "Commuta a l'aplicació 7"
#: data/org.gnome.shell.gschema.xml.in:183
#: data/org.gnome.shell.gschema.xml.in:194
msgid "Switch to application 8"
msgstr "Commuta a l'aplicació 8"
#: data/org.gnome.shell.gschema.xml.in:187
#: data/org.gnome.shell.gschema.xml.in:198
msgid "Switch to application 9"
msgstr "Commuta a l'aplicació 9"
#: data/org.gnome.shell.gschema.xml.in:196
#: data/org.gnome.shell.gschema.xml.in:223
#: data/org.gnome.shell.gschema.xml.in:207
#: data/org.gnome.shell.gschema.xml.in:234
msgid "Limit switcher to current workspace."
msgstr "Limita el canviador a l'espai de treball actual."
#: data/org.gnome.shell.gschema.xml.in:197
#: data/org.gnome.shell.gschema.xml.in:208
msgid ""
"If true, only applications that have windows on the current workspace are "
"shown in the switcher. Otherwise, all applications are included."
@ -321,21 +341,21 @@ msgstr ""
"de treball actual es mostren en el canviador. En cas contrari es mostren "
"totes les aplicacions."
#: data/org.gnome.shell.gschema.xml.in:214
#: data/org.gnome.shell.gschema.xml.in:225
msgid "The application icon mode."
msgstr "El mode d'icona de les aplicacions."
#: data/org.gnome.shell.gschema.xml.in:215
#: data/org.gnome.shell.gschema.xml.in:226
msgid ""
"Configures how the windows are shown in the switcher. Valid possibilities "
"are “thumbnail-only” (shows a thumbnail of the window), “app-icon-"
"only” (shows only the application icon) or “both”."
"are “thumbnail-only” (shows a thumbnail of the window), “app-icon-only” "
"(shows only the application icon) or “both”."
msgstr ""
"Configureu com es mostren les finestres en l'intercanviador. Els valors "
"possibles són: «thumbnail-only» (mostra una miniatura de la finestra), «app-"
"icon-only» (mostra la icona de l'aplicació) o «both» (ambdues coses)."
#: data/org.gnome.shell.gschema.xml.in:224
#: data/org.gnome.shell.gschema.xml.in:235
msgid ""
"If true, only windows from the current workspace are shown in the switcher. "
"Otherwise, all windows are included."
@ -343,60 +363,60 @@ msgstr ""
"Si és «true» (cert), només les finestres de l'espai de treball actual es "
"mostren en el canviador. En cas contrari, es mostren totes les finestres."
#: data/org.gnome.shell.gschema.xml.in:234
#: data/org.gnome.shell.gschema.xml.in:245
msgid "Locations"
msgstr "Ubicacions"
#: data/org.gnome.shell.gschema.xml.in:235
#: data/org.gnome.shell.gschema.xml.in:246
msgid "The locations to show in world clocks"
msgstr "Les ubicacions a mostrar en els rellotges del món"
#: data/org.gnome.shell.gschema.xml.in:245
#: data/org.gnome.shell.gschema.xml.in:256
msgid "Automatic location"
msgstr "Ubicació automàtica"
#: data/org.gnome.shell.gschema.xml.in:246
#: data/org.gnome.shell.gschema.xml.in:257
msgid "Whether to fetch the current location or not"
msgstr "Si s'ha d'obtenir la ubicació actual o no"
#: data/org.gnome.shell.gschema.xml.in:253
#: data/org.gnome.shell.gschema.xml.in:264
msgid "Location"
msgstr "Ubicació"
#: data/org.gnome.shell.gschema.xml.in:254
#: data/org.gnome.shell.gschema.xml.in:265
msgid "The location for which to show a forecast"
msgstr "La ubicació a mostrar la predicció del temps"
#: data/org.gnome.shell.gschema.xml.in:266
#: data/org.gnome.shell.gschema.xml.in:277
msgid "Attach modal dialog to the parent window"
msgstr "Adjunta el diàleg modal a la finestra pare"
#: data/org.gnome.shell.gschema.xml.in:267
#: data/org.gnome.shell.gschema.xml.in:276
#: data/org.gnome.shell.gschema.xml.in:284
#: data/org.gnome.shell.gschema.xml.in:292
#: data/org.gnome.shell.gschema.xml.in:300
#: data/org.gnome.shell.gschema.xml.in:278
#: data/org.gnome.shell.gschema.xml.in:287
#: data/org.gnome.shell.gschema.xml.in:295
#: data/org.gnome.shell.gschema.xml.in:303
#: data/org.gnome.shell.gschema.xml.in:311
msgid ""
"This key overrides the key in org.gnome.mutter when running GNOME Shell."
msgstr ""
"Si s'executa el GNOME Shell, aquesta clau sobreescriu la clau «org.gnome."
"mutter»."
"Si s'executa el GNOME Shell, aquesta clau sobreescriu la clau "
"«org.gnome.mutter»."
#: data/org.gnome.shell.gschema.xml.in:275
#: data/org.gnome.shell.gschema.xml.in:286
msgid "Enable edge tiling when dropping windows on screen edges"
msgstr ""
"Habilita el mosaic a les vores en deixar anar les finestres a les vores de "
"la pantalla"
#: data/org.gnome.shell.gschema.xml.in:283
#: data/org.gnome.shell.gschema.xml.in:294
msgid "Workspaces are managed dynamically"
msgstr "Els espais de treball es gestionen dinàmicament"
#: data/org.gnome.shell.gschema.xml.in:291
#: data/org.gnome.shell.gschema.xml.in:302
msgid "Workspaces only on primary monitor"
msgstr "Només en el monitor principal hi ha espais de treball"
#: data/org.gnome.shell.gschema.xml.in:299
#: data/org.gnome.shell.gschema.xml.in:310
msgid "Delay focus changes in mouse mode until the pointer stops moving"
msgstr ""
"Retarda el canvi del focus, quan s'està en mode ratolí, fins que el punter "
@ -434,7 +454,7 @@ msgstr "Visiteu la pàgina d'inici de l'extensió"
#: js/gdm/authPrompt.js:135 js/ui/audioDeviceSelection.js:57
#: js/ui/components/networkAgent.js:110 js/ui/components/polkitAgent.js:139
#: js/ui/endSessionDialog.js:369 js/ui/extensionDownloader.js:181
#: js/ui/endSessionDialog.js:369 js/ui/extensionDownloader.js:183
#: js/ui/shellMountOperation.js:376 js/ui/shellMountOperation.js:386
#: js/ui/status/network.js:916 subprojects/extensions-app/js/main.js:149
msgid "Cancel"
@ -476,7 +496,7 @@ msgstr "Nom d'usuari"
msgid "Login Window"
msgstr "Finestra d'entrada"
#: js/gdm/util.js:345
#: js/gdm/util.js:355
msgid "Authentication error"
msgstr "Error d'autenticació"
@ -485,7 +505,7 @@ msgstr "Error d'autenticació"
#. as a cue to display our own message.
#. Translators: this message is shown below the password entry field
#. to indicate the user can swipe their finger instead
#: js/gdm/util.js:471
#: js/gdm/util.js:481
msgid "(or swipe finger)"
msgstr "(o passeu el dit)"
@ -495,7 +515,8 @@ msgctxt "search-result"
msgid "Power Off"
msgstr "Apaga"
#. Translators: A list of keywords that match the power-off action, separated by semicolons
#. Translators: A list of keywords that match the power-off action, separated
#. by semicolons
#: js/misc/systemActions.js:96
msgid "power off;shutdown;reboot;restart;halt;stop"
msgstr "apaga;atura;reinicia"
@ -506,7 +527,8 @@ msgctxt "search-result"
msgid "Lock Screen"
msgstr "Bloqueja la pantalla"
#. Translators: A list of keywords that match the lock screen action, separated by semicolons
#. Translators: A list of keywords that match the lock screen action,
#. separated by semicolons
#: js/misc/systemActions.js:104
msgid "lock screen"
msgstr "bloca la pantalla"
@ -517,7 +539,8 @@ msgctxt "search-result"
msgid "Log Out"
msgstr "Surt"
#. Translators: A list of keywords that match the logout action, separated by semicolons
#. Translators: A list of keywords that match the logout action, separated by
#. semicolons
#: js/misc/systemActions.js:112
msgid "logout;log out;sign off"
msgstr "desconnecta;sortida;surt"
@ -528,7 +551,8 @@ msgctxt "search-result"
msgid "Suspend"
msgstr "Atura temporalment"
#. Translators: A list of keywords that match the suspend action, separated by semicolons
#. Translators: A list of keywords that match the suspend action, separated by
#. semicolons
#: js/misc/systemActions.js:120
msgid "suspend;sleep"
msgstr "atura temporalment;dorm"
@ -539,12 +563,14 @@ msgctxt "search-result"
msgid "Switch User"
msgstr "Canvia d'usuari"
#. Translators: A list of keywords that match the switch user action, separated by semicolons
#. Translators: A list of keywords that match the switch user action,
#. separated by semicolons
#: js/misc/systemActions.js:128
msgid "switch user"
msgstr "canvia d'usuari"
#. Translators: A list of keywords that match the lock orientation action, separated by semicolons
#. Translators: A list of keywords that match the lock orientation action,
#. separated by semicolons
#: js/misc/systemActions.js:135
msgid "lock orientation;unlock orientation;screen;rotation"
msgstr "bloqueja l'orientació;desbloqueja l'orientació;pantalla;rotació"
@ -720,36 +746,36 @@ msgstr "Denega l'accés"
msgid "Grant Access"
msgstr "Permet l'accés"
#: js/ui/appDisplay.js:956
#: js/ui/appDisplay.js:1297
msgid "Unnamed Folder"
msgstr "Carpeta sense nom"
#. Translators: This is the heading of a list of open windows
#: js/ui/appDisplay.js:2215 js/ui/panel.js:75
#: js/ui/appDisplay.js:2767 js/ui/panel.js:75
msgid "Open Windows"
msgstr "Obre finestres"
#: js/ui/appDisplay.js:2234 js/ui/panel.js:82
#: js/ui/appDisplay.js:2786 js/ui/panel.js:82
msgid "New Window"
msgstr "Finestra nova"
#: js/ui/appDisplay.js:2250
#: js/ui/appDisplay.js:2802
msgid "Launch using Integrated Graphics Card"
msgstr "Inicia usant una targeta gràfica integrada"
#: js/ui/appDisplay.js:2251
#: js/ui/appDisplay.js:2803
msgid "Launch using Discrete Graphics Card"
msgstr "Inicia usant una targeta gràfica discreta"
#: js/ui/appDisplay.js:2279 js/ui/dash.js:239
#: js/ui/appDisplay.js:2831 js/ui/dash.js:239
msgid "Remove from Favorites"
msgstr "Suprimeix dels preferits"
#: js/ui/appDisplay.js:2285
#: js/ui/appDisplay.js:2837
msgid "Add to Favorites"
msgstr "Afegeix als preferits"
#: js/ui/appDisplay.js:2295 js/ui/panel.js:93
#: js/ui/appDisplay.js:2847 js/ui/panel.js:93
msgid "Show Details"
msgstr "Mostra els detalls"
@ -779,7 +805,7 @@ msgstr "Auriculars"
msgid "Headset"
msgstr "Auriculars amb micròfon"
#: js/ui/audioDeviceSelection.js:68 js/ui/status/volume.js:273
#: js/ui/audioDeviceSelection.js:68 js/ui/status/volume.js:272
msgid "Microphone"
msgstr "Micròfon"
@ -795,7 +821,8 @@ msgstr "Paràmetres de la pantalla"
msgid "Settings"
msgstr "Paràmetres"
#. Translators: Enter 0-6 (Sunday-Saturday) for non-work days. Examples: "0" (Sunday) "6" (Saturday) "06" (Sunday and Saturday).
#. Translators: Enter 0-6 (Sunday-Saturday) for non-work days. Examples: "0"
#. (Sunday) "6" (Saturday) "06" (Sunday and Saturday).
#: js/ui/calendar.js:36
msgctxt "calendar-no-work"
msgid "06"
@ -805,7 +832,6 @@ msgstr "06"
#. *
#. * NOTE: These grid abbreviations are always shown together
#. * and in order, e.g. "S M T W T F S".
#.
#: js/ui/calendar.js:65
msgctxt "grid sunday"
msgid "S"
@ -852,7 +878,6 @@ msgstr "Ds"
#. * standalone, when this is a month of the current year.
#. * "%OB" is the new format specifier introduced in glibc 2.27,
#. * in most cases you should not change it.
#.
#: js/ui/calendar.js:392
msgid "%OB"
msgstr "%OB"
@ -865,7 +890,6 @@ msgstr "%OB"
#. * "%OB" is the new format specifier introduced in glibc 2.27,
#. * in most cases you should not use the old "%B" here unless you
#. * absolutely know what you are doing.
#.
#: js/ui/calendar.js:402
msgid "%OB %Y"
msgstr "%OB de %Y"
@ -947,7 +971,8 @@ msgstr "Obre amb %s"
#: js/ui/components/networkAgent.js:92
msgid ""
"Alternatively you can connect by pushing the “WPS” button on your router."
msgstr "També us podeu connectar prement el botó «WPS» del vostre encaminador."
msgstr ""
"També us podeu connectar prement el botó «WPS» del vostre encaminador."
#: js/ui/components/networkAgent.js:104 js/ui/status/network.js:227
#: js/ui/status/network.js:318 js/ui/status/network.js:919
@ -982,7 +1007,7 @@ msgid ""
"“%s”."
msgstr ""
"Per a accedir a la xarxa sense fil «%s» calen les contrasenyes o les claus "
"d'encriptació."
"de xifratge."
#: js/ui/components/networkAgent.js:318 js/ui/components/networkAgent.js:685
msgid "Wired 802.1X authentication"
@ -1043,7 +1068,8 @@ msgstr "Autentica"
msgid "Sorry, that didnt work. Please try again."
msgstr "No ha funcionat. Torneu-ho a provar."
#. Translators: this is the other person changing their old IM name to their new
#. Translators: this is the other person changing their old IM name to their
#. new
#. IM name.
#: js/ui/components/telepathyClient.js:822
#, javascript-format
@ -1068,7 +1094,6 @@ msgstr "Quadre d'aplicacions"
#. * shown - it is shown just below the time in the top bar (e.g.,
#. * "Tue 9:29 AM"). The string itself should become a full date, e.g.,
#. * "February 17 2015".
#.
#: js/ui/dateMenu.js:79
msgid "%B %-d %Y"
msgstr "%-d %B de %Y"
@ -1076,18 +1101,19 @@ msgstr "%-d %B de %Y"
#. Translators: This is the accessible name of the date button shown
#. * below the time in the shell; it should combine the weekday and the
#. * date, e.g. "Tuesday February 17 2015".
#.
#: js/ui/dateMenu.js:86
msgid "%A %B %e %Y"
msgstr "%A, %-e %B de %Y"
#. Translators: Shown on calendar heading when selected day occurs on current year
#. Translators: Shown on calendar heading when selected day occurs on current
#. year
#: js/ui/dateMenu.js:151
msgctxt "calendar heading"
msgid "%B %-d"
msgstr "%-d %B"
#. Translators: Shown on calendar heading when selected day occurs on different year
#. Translators: Shown on calendar heading when selected day occurs on
#. different year
#: js/ui/dateMenu.js:154
msgctxt "calendar heading"
msgid "%B %-d %Y"
@ -1103,7 +1129,6 @@ msgstr "Demà"
#. Translators: Shown in calendar event list for all day events
#. * Keep it short, best if you can use less then 10 characters
#.
#: js/ui/dateMenu.js:180
msgctxt "event list time"
msgid "All Day"
@ -1222,7 +1247,8 @@ msgstr "Reinicia i instal·la les actualitzacions"
#: js/ui/endSessionDialog.js:91
#, javascript-format
msgid "The system will automatically restart and install updates in %d second."
msgid ""
"The system will automatically restart and install updates in %d second."
msgid_plural ""
"The system will automatically restart and install updates in %d seconds."
msgstr[0] ""
@ -1293,15 +1319,15 @@ msgstr "%s (remot)"
msgid "%s (console)"
msgstr "%s (consola)"
#: js/ui/extensionDownloader.js:185
#: js/ui/extensionDownloader.js:187
msgid "Install"
msgstr "Instal·la"
#: js/ui/extensionDownloader.js:191
#: js/ui/extensionDownloader.js:193
msgid "Install Extension"
msgstr "Instal·la l'extensió"
#: js/ui/extensionDownloader.js:192
#: js/ui/extensionDownloader.js:194
#, javascript-format
msgid "Download and install “%s” from extensions.gnome.org?"
msgstr "Voleu baixar i instal·lar «%s» d'extensions.gnome.org?"
@ -1336,11 +1362,11 @@ msgstr "Una aplicació vol inhabilitar les dreceres"
msgid "You can restore shortcuts by pressing %s."
msgstr "Podeu restaurar les dreceres si premeu %s."
#: js/ui/inhibitShortcutsDialog.js:98
#: js/ui/inhibitShortcutsDialog.js:100
msgid "Deny"
msgstr "Denega"
#: js/ui/inhibitShortcutsDialog.js:105
#: js/ui/inhibitShortcutsDialog.js:107
msgid "Allow"
msgstr "Permet"
@ -1354,8 +1380,8 @@ msgstr "Tecles lentes inactives"
#: js/ui/kbdA11yDialog.js:34
msgid ""
"You just held down the Shift key for 8 seconds. This is the shortcut for the "
"Slow Keys feature, which affects the way your keyboard works."
"You just held down the Shift key for 8 seconds. This is the shortcut for the"
" Slow Keys feature, which affects the way your keyboard works."
msgstr ""
"Heu mantingut premuda la tecla de majúscules durant 8 segons. Aquesta és la "
"drecera per a la funcionalitat «tecles lentes», que afecta la forma de "
@ -1374,8 +1400,8 @@ msgid ""
"You just pressed the Shift key 5 times in a row. This is the shortcut for "
"the Sticky Keys feature, which affects the way your keyboard works."
msgstr ""
"Heu premut la tecla de majúscules 5 cops seguides. Aquesta és la drecera per "
"la funcionalitat de les tecles enganxoses, que afecta la manera en què "
"Heu premut la tecla de majúscules 5 cops seguides. Aquesta és la drecera per"
" la funcionalitat de les tecles enganxoses, que afecta la manera en què "
"funciona el teclat."
#: js/ui/kbdA11yDialog.js:46
@ -1409,7 +1435,7 @@ msgstr "Desactiva"
msgid "Leave Off"
msgstr "Deixa-ho desactivat"
#: js/ui/keyboard.js:207
#: js/ui/keyboard.js:225
msgid "Region & Language Settings"
msgstr "Configuració de regió i idioma"
@ -1471,8 +1497,8 @@ msgid ""
"Running a session as a privileged user should be avoided for security "
"reasons. If possible, you should log in as a normal user."
msgstr ""
"Cal evitar iniciar sessions com a usuari privilegiat per raons de seguretat. "
"Si és possible, entreu com a un usuari normal."
"Cal evitar iniciar sessions com a usuari privilegiat per raons de seguretat."
" Si és possible, entreu com a un usuari normal."
#: js/ui/main.js:337
msgid "Screen Lock disabled"
@ -1482,7 +1508,7 @@ msgstr "La pantalla de bloqueig està inhabilitada"
msgid "Screen Locking requires the GNOME display manager."
msgstr "El bloqueig de pantalla requereix el gestor de pantalla del GNOME."
#: js/ui/messageTray.js:1547
#: js/ui/messageTray.js:1476
msgid "System Information"
msgstr "Informació de l'ordinador"
@ -1494,13 +1520,13 @@ msgstr "Artista desconegut"
msgid "Unknown title"
msgstr "Títol desconegut"
#: js/ui/overview.js:73
#: js/ui/overview.js:74
msgid "Undo"
msgstr "Desfés"
#. Translators: This is the main view to select
#. activities. See also note for "Activities" string.
#: js/ui/overview.js:86
#: js/ui/overview.js:87
msgid "Overview"
msgstr "Vista general"
@ -1508,7 +1534,7 @@ msgstr "Vista general"
#. in the search entry when no search is
#. active; it should not exceed ~30
#. characters.
#: js/ui/overview.js:107
#: js/ui/overview.js:108
msgid "Type to search"
msgstr "Teclegeu per a cercar"
@ -1599,7 +1625,6 @@ msgstr "El GNOME necessita bloquejar la pantalla"
#. screenshield. The user is probably very upset at this
#. point, but any application using global grabs is broken
#. Just tell him to stop using this app
#.
#. XXX: another option is to kick the user into the gdm login
#. screen, where we're not affected by grabs
#: js/ui/screenShield.js:244 js/ui/screenShield.js:602
@ -1841,14 +1866,15 @@ msgstr "<desconegut>"
msgid "%s Off"
msgstr "%s apagat"
# N.T.: p. ex. Connectat amb fil
#. Translators: %s is a network identifier
# N.T.: p. ex. Connectat amb fil
#: js/ui/status/network.js:427
#, javascript-format
msgid "%s Connected"
msgstr "Connectat %s"
#. Translators: this is for network devices that are physically present but are not
#. Translators: this is for network devices that are physically present but
#. are not
#. under NetworkManager's control (and thus cannot be used in the menu);
#. %s is a network identifier
#: js/ui/status/network.js:432
@ -1868,20 +1894,23 @@ msgstr "%s s'està desconnectant"
msgid "%s Connecting"
msgstr "%s s'està connectant"
#. Translators: this is for network connections that require some kind of key or password; %s is a network identifier
#. Translators: this is for network connections that require some kind of key
#. or password; %s is a network identifier
#: js/ui/status/network.js:445
#, javascript-format
msgid "%s Requires Authentication"
msgstr "%s requereix autenticació"
#. Translators: this is for devices that require some kind of firmware or kernel
#. Translators: this is for devices that require some kind of firmware or
#. kernel
#. module, which is missing; %s is a network identifier
#: js/ui/status/network.js:453
#, javascript-format
msgid "Firmware Missing For %s"
msgstr "Manca el microprogramari per %s"
#. Translators: this is for a network device that cannot be activated (for example it
#. Translators: this is for a network device that cannot be activated (for
#. example it
#. is disabled by rfkill, or it has no coverage; %s is a network identifier
#: js/ui/status/network.js:457
#, javascript-format
@ -1984,7 +2013,8 @@ msgstr "%s no està connectat"
msgid "connecting…"
msgstr "s'està connectant..."
#. Translators: this is for network connections that require some kind of key or password
#. Translators: this is for network connections that require some kind of key
#. or password
#: js/ui/status/network.js:1423
msgid "authentication required"
msgstr "cal autenticació"
@ -2164,38 +2194,34 @@ msgstr "S'ha produït un error d'autorització a Thunderbolt"
msgid "Could not authorize the Thunderbolt device: %s"
msgstr "No s'ha pogut autoritzar el dispositiu Thunderbolt: %s"
#: js/ui/status/volume.js:154
#: js/ui/status/volume.js:155
msgid "Volume changed"
msgstr "S'ha canviat el volum"
#: js/ui/status/volume.js:225
#: js/ui/status/volume.js:217
msgid "Volume"
msgstr "Volum"
#. Translators: this is for display mirroring i.e. cloning.
#. * Try to keep it under around 15 characters.
#.
#: js/ui/switchMonitor.js:17
msgid "Mirror"
msgstr "Mirall"
#. Translators: this is for the desktop spanning displays.
#. * Try to keep it under around 15 characters.
#.
#: js/ui/switchMonitor.js:22
msgid "Join Displays"
msgstr "Uneix pantalles"
#. Translators: this is for using only an external display.
#. * Try to keep it under around 15 characters.
#.
#: js/ui/switchMonitor.js:27
msgid "External Only"
msgstr "Només extern"
#. Translators: this is for using only the laptop display.
#. * Try to keep it under around 15 characters.
#.
#: js/ui/switchMonitor.js:32
msgid "Built-in Only"
msgstr "Només l'integrat"
@ -2214,11 +2240,11 @@ msgstr "Llisqueu amunt per a desbloquejar"
msgid "Click or press a key to unlock"
msgstr "Feu clic o premeu una tecla per a desbloquejar"
#: js/ui/unlockDialog.js:550
#: js/ui/unlockDialog.js:555
msgid "Unlock Window"
msgstr "Desbloqueja la finestra"
#: js/ui/unlockDialog.js:559
#: js/ui/unlockDialog.js:564
msgid "Log in as another user"
msgstr "Entra amb un altre usuari"
@ -2242,7 +2268,6 @@ msgstr "Mantenir aquesta configuració de la pantalla?"
#. Translators: this and the following message should be limited in length,
#. to avoid ellipsizing the labels.
#.
#: js/ui/windowManager.js:64
msgid "Revert Settings"
msgstr "Descarta els canvis"
@ -2353,12 +2378,12 @@ msgstr "Utilitza un mode específic, p. ex. «gdm» per la pantalla d'entrada"
msgid "List possible modes"
msgstr "Llista els modes possibles"
#: src/shell-app.c:286
#: src/shell-app.c:268
msgctxt "program"
msgid "Unknown"
msgstr "Desconegut"
#: src/shell-app.c:537
#: src/shell-app.c:519
#, c-format
msgid "Failed to launch “%s”"
msgstr "No s'ha pogut iniciar «%s»"
@ -2414,8 +2439,8 @@ msgid ""
"If you remove the extension, you need to return to download it if you want "
"to enable it again"
msgstr ""
"Si suprimiu una extensió, us cal tornar-la a baixar si voleu habilitar-la de "
"nou"
"Si suprimiu una extensió, us cal tornar-la a baixar si voleu habilitar-la de"
" nou"
#: subprojects/extensions-app/js/main.js:150
msgid "Remove"
@ -2477,11 +2502,11 @@ msgstr "Quant a les extensions"
#: subprojects/extensions-app/data/ui/extensions-window.ui:27
msgid ""
"To find and add extensions, visit <a href=\"https://extensions.gnome.org"
"\">extensions.gnome.org</a>."
"To find and add extensions, visit <a "
"href=\"https://extensions.gnome.org\">extensions.gnome.org</a>."
msgstr ""
"Per a visitar i afegir extensions, visiteu <a href=\"https://extensions."
"gnome.org\">extensions.gnome.org</a>."
"Per a visitar i afegir extensions, visiteu <a "
"href=\"https://extensions.gnome.org\">extensions.gnome.org</a>."
#: subprojects/extensions-app/data/ui/extensions-window.ui:35
msgid "Warning"
@ -2514,8 +2539,8 @@ msgid ""
"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."
msgstr ""
"No s'ha pogut obtenir la llista d'extensions instal·lades. Assegureu-vos que "
"heu entrat al GNOME i torneu a provar-ho."
"No s'ha pogut obtenir la llista d'extensions instal·lades. Assegureu-vos que"
" heu entrat al GNOME i torneu a provar-ho."
#: subprojects/extensions-app/data/ui/extensions-window.ui:273
msgid "Extension Updates Ready"
@ -2557,8 +2582,7 @@ msgstr ""
#: subprojects/extensions-tool/src/command-create.c:339
msgid ""
"UUID is a globally-unique identifier for your extension.\n"
"This should be in the format of an email address (clicktofocus@janedoe."
"example.com)\n"
"This should be in the format of an email address (clicktofocus@janedoe.example.com)\n"
msgstr ""
"L'UUID és un identificador únic global per l'extensió\n"
"Ha de tenir el format d'una adreça de correu (exemple@softcatala.org)\n"
@ -2933,4 +2957,3 @@ msgstr[1] "%u entrades"
#: subprojects/gvc/gvc-mixer-control.c:2766
msgid "System Sounds"
msgstr "Sons del sistema"

742
po/de.po

File diff suppressed because it is too large Load Diff

1118
po/el.po

File diff suppressed because it is too large Load Diff

161
po/es.po
View File

@ -9,8 +9,8 @@ msgid ""
msgstr ""
"Project-Id-Version: gnome-shell.master\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gnome-shell/issues\n"
"POT-Creation-Date: 2020-06-05 23:11+0000\n"
"PO-Revision-Date: 2020-06-08 16:06+0200\n"
"POT-Creation-Date: 2020-07-27 06:59+0000\n"
"PO-Revision-Date: 2020-07-29 09:47+0200\n"
"Last-Translator: Daniel Mustieles <daniel.mustieles@gmail.com>\n"
"Language-Team: Spanish - Spain <gnome-es-list@gnome.org>\n"
"Language: es_ES\n"
@ -221,95 +221,112 @@ msgstr ""
"Activa una API de D-Bus que permite la introspección del estado de la "
"aplicación de la shell."
#: data/org.gnome.shell.gschema.xml.in:119
#: data/org.gnome.shell.gschema.xml.in:114
msgid "Layout of the app picker"
msgstr "Distribución del selector de aplicaciones"
#: data/org.gnome.shell.gschema.xml.in:115
msgid ""
"Layout of the app picker. Each entry in the array is a page. Pages are "
"stored in the order they appear in GNOME Shell. Each page contains an "
"“application id” → 'data' pair. Currently, the following values are stored "
"as 'data': • “position”: the position of the application icon in the page"
msgstr ""
"Distribución del selector de aplicaciones Cada entrada en el vector es una "
"página. Las páginas se guardan en el orden en que aparecen en GNOME Shell. "
"Cada página contiene una pareja “application id” → 'data'. Actualmente se "
"guardan los siguientes valores como 'data': • “position”:la posición del "
"icono de la aplicación en la página"
#: data/org.gnome.shell.gschema.xml.in:130
msgid "Keybinding to open the application menu"
msgstr "Asociación de teclas para abrir el menú de la aplicación"
#: data/org.gnome.shell.gschema.xml.in:120
#: data/org.gnome.shell.gschema.xml.in:131
msgid "Keybinding to open the application menu."
msgstr "Asociación de teclas para abrir el menú de la aplicación."
#: data/org.gnome.shell.gschema.xml.in:126
#: data/org.gnome.shell.gschema.xml.in:137
msgid "Keybinding to open the “Show Applications” view"
msgstr "Asociación de teclas para la vista «Mostrar aplicaciones»"
#: data/org.gnome.shell.gschema.xml.in:127
#: data/org.gnome.shell.gschema.xml.in:138
msgid ""
"Keybinding to open the “Show Applications” view of the Activities Overview."
msgstr ""
"Asociación de teclas para abrir la vista «Mostrar aplicaciones» de la vista "
"de actividades."
#: data/org.gnome.shell.gschema.xml.in:134
#: data/org.gnome.shell.gschema.xml.in:145
msgid "Keybinding to open the overview"
msgstr "Asociación de teclas para la vista general"
#: data/org.gnome.shell.gschema.xml.in:135
#: data/org.gnome.shell.gschema.xml.in:146
msgid "Keybinding to open the Activities Overview."
msgstr "Asociación de teclas para abrir la Vista de actividades."
#: data/org.gnome.shell.gschema.xml.in:141
#: data/org.gnome.shell.gschema.xml.in:152
msgid "Keybinding to toggle the visibility of the notification list"
msgstr ""
"Asociación de teclas para cambiar la visibilidad de la lista de "
"notificaciones"
#: data/org.gnome.shell.gschema.xml.in:142
#: data/org.gnome.shell.gschema.xml.in:153
msgid "Keybinding to toggle the visibility of the notification list."
msgstr ""
"Asociación de teclas para cambiar la visibilidad de la lista de "
"notificaciones."
#: data/org.gnome.shell.gschema.xml.in:148
#: data/org.gnome.shell.gschema.xml.in:159
msgid "Keybinding to focus the active notification"
msgstr "Asociación de teclas para dar el foco a la notificación activa"
#: data/org.gnome.shell.gschema.xml.in:149
#: data/org.gnome.shell.gschema.xml.in:160
msgid "Keybinding to focus the active notification."
msgstr "Asociación de teclas para dar el foco a la notificación activa."
#: data/org.gnome.shell.gschema.xml.in:155
#: data/org.gnome.shell.gschema.xml.in:166
msgid "Switch to application 1"
msgstr "Cambiar a la aplicación 1"
#: data/org.gnome.shell.gschema.xml.in:159
#: data/org.gnome.shell.gschema.xml.in:170
msgid "Switch to application 2"
msgstr "Cambiar a la aplicación 2"
#: data/org.gnome.shell.gschema.xml.in:163
#: data/org.gnome.shell.gschema.xml.in:174
msgid "Switch to application 3"
msgstr "Cambiar a la aplicación 3"
#: data/org.gnome.shell.gschema.xml.in:167
#: data/org.gnome.shell.gschema.xml.in:178
msgid "Switch to application 4"
msgstr "Cambiar a la aplicación 4"
#: data/org.gnome.shell.gschema.xml.in:171
#: data/org.gnome.shell.gschema.xml.in:182
msgid "Switch to application 5"
msgstr "Cambiar a la aplicación 5"
#: data/org.gnome.shell.gschema.xml.in:175
#: data/org.gnome.shell.gschema.xml.in:186
msgid "Switch to application 6"
msgstr "Cambiar a la aplicación 6"
#: data/org.gnome.shell.gschema.xml.in:179
#: data/org.gnome.shell.gschema.xml.in:190
msgid "Switch to application 7"
msgstr "Cambiar a la aplicación 7"
#: data/org.gnome.shell.gschema.xml.in:183
#: data/org.gnome.shell.gschema.xml.in:194
msgid "Switch to application 8"
msgstr "Cambiar a la aplicación 8"
#: data/org.gnome.shell.gschema.xml.in:187
#: data/org.gnome.shell.gschema.xml.in:198
msgid "Switch to application 9"
msgstr "Cambiar a la aplicación 9"
#: data/org.gnome.shell.gschema.xml.in:196
#: data/org.gnome.shell.gschema.xml.in:223
#: data/org.gnome.shell.gschema.xml.in:207
#: data/org.gnome.shell.gschema.xml.in:234
msgid "Limit switcher to current workspace."
msgstr "Limitar el intercambiador al área de trabajo actual."
#: data/org.gnome.shell.gschema.xml.in:197
#: data/org.gnome.shell.gschema.xml.in:208
msgid ""
"If true, only applications that have windows on the current workspace are "
"shown in the switcher. Otherwise, all applications are included."
@ -318,11 +335,11 @@ msgstr ""
"trabajo actual se muestran en el selector. Si no, se incluyen todas las "
"aplicaciones."
#: data/org.gnome.shell.gschema.xml.in:214
#: data/org.gnome.shell.gschema.xml.in:225
msgid "The application icon mode."
msgstr "El modo de icono de la aplicación."
#: data/org.gnome.shell.gschema.xml.in:215
#: data/org.gnome.shell.gschema.xml.in:226
msgid ""
"Configures how the windows are shown in the switcher. Valid possibilities "
"are “thumbnail-only” (shows a thumbnail of the window), “app-icon-"
@ -332,7 +349,7 @@ msgstr ""
"son «thumbnail-only» (muestra una miniatura de la ventana), «app-icon-"
"only» (sólo muestra el icono de la aplicación) «both»."
#: data/org.gnome.shell.gschema.xml.in:224
#: data/org.gnome.shell.gschema.xml.in:235
msgid ""
"If true, only windows from the current workspace are shown in the switcher. "
"Otherwise, all windows are included."
@ -340,59 +357,59 @@ msgstr ""
"Si es cierto, sólo se muestran en el selector las ventanas del área de "
"trabajo actual. Si no, se incluyen todas las ventanas."
#: data/org.gnome.shell.gschema.xml.in:234
#: data/org.gnome.shell.gschema.xml.in:245
msgid "Locations"
msgstr "Ubicaciones"
#: data/org.gnome.shell.gschema.xml.in:235
#: data/org.gnome.shell.gschema.xml.in:246
msgid "The locations to show in world clocks"
msgstr "Las ubicaciones que mostrar en los relojes del mundo"
#: data/org.gnome.shell.gschema.xml.in:245
#: data/org.gnome.shell.gschema.xml.in:256
msgid "Automatic location"
msgstr "Ubicación automática"
#: data/org.gnome.shell.gschema.xml.in:246
#: data/org.gnome.shell.gschema.xml.in:257
msgid "Whether to fetch the current location or not"
msgstr "Indica si se debe o no obtener la ubicación actual"
#: data/org.gnome.shell.gschema.xml.in:253
#: data/org.gnome.shell.gschema.xml.in:264
msgid "Location"
msgstr "Ubicación"
#: data/org.gnome.shell.gschema.xml.in:254
#: data/org.gnome.shell.gschema.xml.in:265
msgid "The location for which to show a forecast"
msgstr "La ubicación para la que mostrar la predicción"
#: data/org.gnome.shell.gschema.xml.in:266
#: data/org.gnome.shell.gschema.xml.in:277
msgid "Attach modal dialog to the parent window"
msgstr "Acoplar un diálogo modal a la ventana padre"
#: data/org.gnome.shell.gschema.xml.in:267
#: data/org.gnome.shell.gschema.xml.in:276
#: data/org.gnome.shell.gschema.xml.in:284
#: data/org.gnome.shell.gschema.xml.in:292
#: data/org.gnome.shell.gschema.xml.in:300
#: data/org.gnome.shell.gschema.xml.in:278
#: data/org.gnome.shell.gschema.xml.in:287
#: data/org.gnome.shell.gschema.xml.in:295
#: data/org.gnome.shell.gschema.xml.in:303
#: data/org.gnome.shell.gschema.xml.in:311
msgid ""
"This key overrides the key in org.gnome.mutter when running GNOME Shell."
msgstr ""
"Esta clave sobrescribe la clave en org.gnome.mutter al ejecutar GNOME Shell."
#: data/org.gnome.shell.gschema.xml.in:275
#: data/org.gnome.shell.gschema.xml.in:286
msgid "Enable edge tiling when dropping windows on screen edges"
msgstr ""
"Activar el mosaico en los bordes al arrastrar ventanas a los bordes de la "
"ventana"
#: data/org.gnome.shell.gschema.xml.in:283
#: data/org.gnome.shell.gschema.xml.in:294
msgid "Workspaces are managed dynamically"
msgstr "Las áreas de trabajo se gestionan dinámicamente"
#: data/org.gnome.shell.gschema.xml.in:291
#: data/org.gnome.shell.gschema.xml.in:302
msgid "Workspaces only on primary monitor"
msgstr "Áreas de trabajo solo en la pantalla principal"
#: data/org.gnome.shell.gschema.xml.in:299
#: data/org.gnome.shell.gschema.xml.in:310
msgid "Delay focus changes in mouse mode until the pointer stops moving"
msgstr ""
"Retardo al cambiar el foco del ratón hasta que el puntero deja de moverse"
@ -429,7 +446,7 @@ msgstr "Visitar la página web de la extensión"
#: js/gdm/authPrompt.js:135 js/ui/audioDeviceSelection.js:57
#: js/ui/components/networkAgent.js:110 js/ui/components/polkitAgent.js:139
#: js/ui/endSessionDialog.js:369 js/ui/extensionDownloader.js:181
#: js/ui/endSessionDialog.js:369 js/ui/extensionDownloader.js:183
#: js/ui/shellMountOperation.js:376 js/ui/shellMountOperation.js:386
#: js/ui/status/network.js:916 subprojects/extensions-app/js/main.js:149
msgid "Cancel"
@ -471,7 +488,7 @@ msgstr "Nombre de usuario"
msgid "Login Window"
msgstr "Ventana de inicio de sesión"
#: js/gdm/util.js:345
#: js/gdm/util.js:355
msgid "Authentication error"
msgstr "Error de autenticación"
@ -480,7 +497,7 @@ msgstr "Error de autenticación"
#. as a cue to display our own message.
#. Translators: this message is shown below the password entry field
#. to indicate the user can swipe their finger instead
#: js/gdm/util.js:471
#: js/gdm/util.js:481
msgid "(or swipe finger)"
msgstr "(o pase el dedo)"
@ -714,36 +731,36 @@ msgstr "Denegar acceso"
msgid "Grant Access"
msgstr "Conceder acceso"
#: js/ui/appDisplay.js:956
#: js/ui/appDisplay.js:1297
msgid "Unnamed Folder"
msgstr "Carpeta sin nombre"
#. Translators: This is the heading of a list of open windows
#: js/ui/appDisplay.js:2215 js/ui/panel.js:75
#: js/ui/appDisplay.js:2767 js/ui/panel.js:75
msgid "Open Windows"
msgstr "Ventanas abiertas"
#: js/ui/appDisplay.js:2234 js/ui/panel.js:82
#: js/ui/appDisplay.js:2786 js/ui/panel.js:82
msgid "New Window"
msgstr "Ventana nueva"
#: js/ui/appDisplay.js:2250
#: js/ui/appDisplay.js:2802
msgid "Launch using Integrated Graphics Card"
msgstr "Lanzar usando la tarjeta gráfica integrada"
#: js/ui/appDisplay.js:2251
#: js/ui/appDisplay.js:2803
msgid "Launch using Discrete Graphics Card"
msgstr "Lanzar usando la tarjeta gráfica discreta"
#: js/ui/appDisplay.js:2279 js/ui/dash.js:239
#: js/ui/appDisplay.js:2831 js/ui/dash.js:239
msgid "Remove from Favorites"
msgstr "Quitar de los favoritos"
#: js/ui/appDisplay.js:2285
#: js/ui/appDisplay.js:2837
msgid "Add to Favorites"
msgstr "Añadir a los favoritos"
#: js/ui/appDisplay.js:2295 js/ui/panel.js:93
#: js/ui/appDisplay.js:2847 js/ui/panel.js:93
msgid "Show Details"
msgstr "Mostrar detalles"
@ -773,7 +790,7 @@ msgstr "Auriculares"
msgid "Headset"
msgstr "Manos libres"
#: js/ui/audioDeviceSelection.js:68 js/ui/status/volume.js:273
#: js/ui/audioDeviceSelection.js:68 js/ui/status/volume.js:272
msgid "Microphone"
msgstr "Micrófono"
@ -1077,14 +1094,12 @@ msgstr "%A %e de %B de %Y"
#. Translators: Shown on calendar heading when selected day occurs on current year
#: js/ui/dateMenu.js:151
#| msgid "%B %-d %Y"
msgctxt "calendar heading"
msgid "%B %-d"
msgstr "%B %-d"
#. Translators: Shown on calendar heading when selected day occurs on different year
#: js/ui/dateMenu.js:154
#| msgid "%B %-d %Y"
msgctxt "calendar heading"
msgid "%B %-d %Y"
msgstr "%B %-d %Y"
@ -1286,15 +1301,15 @@ msgstr "%s (remoto)"
msgid "%s (console)"
msgstr "%s (consola)"
#: js/ui/extensionDownloader.js:185
#: js/ui/extensionDownloader.js:187
msgid "Install"
msgstr "Instalar"
#: js/ui/extensionDownloader.js:191
#: js/ui/extensionDownloader.js:193
msgid "Install Extension"
msgstr "Instalar extensión"
#: js/ui/extensionDownloader.js:192
#: js/ui/extensionDownloader.js:194
#, javascript-format
msgid "Download and install “%s” from extensions.gnome.org?"
msgstr "¿Descargar e instalar «%s» desde extensions.gnome.org?"
@ -1327,11 +1342,11 @@ msgstr "Una aplicación quiere inhibir los atajos"
msgid "You can restore shortcuts by pressing %s."
msgstr "Puede restaurar los atajos pulsando %s."
#: js/ui/inhibitShortcutsDialog.js:98
#: js/ui/inhibitShortcutsDialog.js:100
msgid "Deny"
msgstr "Denegar"
#: js/ui/inhibitShortcutsDialog.js:105
#: js/ui/inhibitShortcutsDialog.js:107
msgid "Allow"
msgstr "Permitir"
@ -1400,7 +1415,7 @@ msgstr "Apagar"
msgid "Leave Off"
msgstr "Dejar apagado"
#: js/ui/keyboard.js:207
#: js/ui/keyboard.js:225
msgid "Region & Language Settings"
msgstr "Configuración de región e idioma"
@ -1473,7 +1488,7 @@ msgstr "Pantalla de bloqueo desactivada"
msgid "Screen Locking requires the GNOME display manager."
msgstr "La pantalla de bloqueo necesita el gestor de pantallas de GNOME."
#: js/ui/messageTray.js:1547
#: js/ui/messageTray.js:1476
msgid "System Information"
msgstr "Información del sistema"
@ -1485,13 +1500,13 @@ msgstr "Artista desconocido"
msgid "Unknown title"
msgstr "Título desconocido"
#: js/ui/overview.js:73
#: js/ui/overview.js:74
msgid "Undo"
msgstr "Deshacer"
#. Translators: This is the main view to select
#. activities. See also note for "Activities" string.
#: js/ui/overview.js:86
#: js/ui/overview.js:87
msgid "Overview"
msgstr "Vista general"
@ -1499,7 +1514,7 @@ msgstr "Vista general"
#. in the search entry when no search is
#. active; it should not exceed ~30
#. characters.
#: js/ui/overview.js:107
#: js/ui/overview.js:108
msgid "Type to search"
msgstr "Escribir para buscar"
@ -2153,11 +2168,11 @@ msgstr "Error de autorización de Thunderbolt"
msgid "Could not authorize the Thunderbolt device: %s"
msgstr "No se pudo autorizar el dispositivo Thunderbolt: %s"
#: js/ui/status/volume.js:154
#: js/ui/status/volume.js:155
msgid "Volume changed"
msgstr "Volumen modificado"
#: js/ui/status/volume.js:225
#: js/ui/status/volume.js:217
msgid "Volume"
msgstr "Volumen"
@ -2203,11 +2218,11 @@ msgstr "Deslizar para desbloquear"
msgid "Click or press a key to unlock"
msgstr "Pulse con el ratón o una tecla para desbloquear"
#: js/ui/unlockDialog.js:550
#: js/ui/unlockDialog.js:555
msgid "Unlock Window"
msgstr "Desbloquear ventana"
#: js/ui/unlockDialog.js:559
#: js/ui/unlockDialog.js:564
msgid "Log in as another user"
msgstr "Iniciar sesión como otro usuario"
@ -2344,12 +2359,12 @@ msgstr ""
msgid "List possible modes"
msgstr "Listar los modos posibles"
#: src/shell-app.c:286
#: src/shell-app.c:268
msgctxt "program"
msgid "Unknown"
msgstr "Desconocido"
#: src/shell-app.c:537
#: src/shell-app.c:519
#, c-format
msgid "Failed to launch “%s”"
msgstr "Falló al lanzar «%s»"

483
po/fur.po

File diff suppressed because it is too large Load Diff

313
po/kk.po
View File

@ -1,14 +1,14 @@
# Kazakh translation for gnome-shell.
# Copyright (C) 2015 The gnome-shell authors.
# This file is distributed under the same license as the gnome-shell package.
# Baurzhan Muftakhidinov <baurthefirst@gmail.com>, 2012-2019.
# Baurzhan Muftakhidinov <baurthefirst@gmail.com>, 2012-2020.
#
msgid ""
msgstr ""
"Project-Id-Version: master\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gnome-shell/issues\n"
"POT-Creation-Date: 2020-06-05 23:11+0000\n"
"PO-Revision-Date: 2020-06-15 18:37+0500\n"
"POT-Creation-Date: 2020-06-25 04:35+0000\n"
"PO-Revision-Date: 2020-06-27 23:27+0500\n"
"Last-Translator: Baurzhan Muftakhidinov <baurthefirst@gmail.com>\n"
"Language-Team: Kazakh <kk_KZ@googlegroups.com>\n"
"Language: kk\n"
@ -81,16 +81,10 @@ msgstr ""
"DisableExtension DBus тәсілдерімен де өзгертуге болады."
#: data/org.gnome.shell.gschema.xml.in:26
#| msgid "UUIDs of extensions to enable"
msgid "UUIDs of extensions to force disabling"
msgstr ""
msgstr "Мәжбүрлі сөндіру үшін кеңейтулер UUID-лары"
#: data/org.gnome.shell.gschema.xml.in:27
#| msgid ""
#| "GNOME Shell extensions have a UUID property; this key lists extensions "
#| "which should be loaded. Any extension that wants to be loaded needs to be "
#| "in this list. You can also manipulate this list with the EnableExtension "
#| "and DisableExtension D-Bus methods on org.gnome.Shell."
msgid ""
"GNOME Shell extensions have a UUID property; this key lists extensions which "
"should be disabled, even if loaded as part of the current mode. You can also "
@ -98,6 +92,11 @@ msgid ""
"methods on org.gnome.Shell. This key takes precedence over the “enabled-"
"extensions” setting."
msgstr ""
"GNOME Shell кеңейтулерінде UUID қасиеті бар; бұл кілт сөндіру үшін "
"кеңейтулер тізімін сақтайды, олар қазіргі режимде іске қосылған болса да. "
"Сонымен қатар, бұл тізімді org.gnome.Shell EnableExtension және "
"DisableExtension D-Bus тәсілдері арқылы түзетуге болады. Бұл кілт \"enabled-"
"extensions\" баптауын үстінен басады."
#: data/org.gnome.shell.gschema.xml.in:37
msgid "Disable user extensions"
@ -333,19 +332,19 @@ msgstr ""
#: data/org.gnome.shell.gschema.xml.in:234
msgid "Locations"
msgstr "Орналасу"
msgstr "Орналасулар"
#: data/org.gnome.shell.gschema.xml.in:235
msgid "The locations to show in world clocks"
msgstr ""
msgstr "Дүниежүзілік сағаттарда көрсетілетін орналасулар"
#: data/org.gnome.shell.gschema.xml.in:245
msgid "Automatic location"
msgstr ""
msgstr "Автоматты орналасу"
#: data/org.gnome.shell.gschema.xml.in:246
msgid "Whether to fetch the current location or not"
msgstr ""
msgstr "Ағымдағы орналасуды алу керек пе, жоқ па"
#: data/org.gnome.shell.gschema.xml.in:253
msgid "Location"
@ -353,7 +352,7 @@ msgstr "Орналасу"
#: data/org.gnome.shell.gschema.xml.in:254
msgid "The location for which to show a forecast"
msgstr ""
msgstr "Ауа райы болжамын көрсету үшін орналасу"
#: data/org.gnome.shell.gschema.xml.in:266
msgid "Attach modal dialog to the parent window"
@ -532,23 +531,20 @@ msgstr "пайдаланушыны ауыстыру"
#. Translators: A list of keywords that match the lock orientation action, separated by semicolons
#: js/misc/systemActions.js:135
#| msgid "lock orientation;screen;rotation"
msgid "lock orientation;unlock orientation;screen;rotation"
msgstr ""
"lock orientation;unlock orientation;screen;rotation;бұрылуды құлыптау;экран "
"бұрылуы"
#: js/misc/systemActions.js:255
#| msgctxt "search-result"
#| msgid "Lock Orientation"
msgctxt "search-result"
msgid "Unlock Screen Rotation"
msgstr ""
msgstr "Экранды бұруды құлыптан босату"
#: js/misc/systemActions.js:256
#| msgctxt "search-result"
#| msgid "Lock Orientation"
msgctxt "search-result"
msgid "Lock Screen Rotation"
msgstr ""
msgstr "Экранды бұруды құлыптау"
#: js/misc/util.js:120
msgid "Command not found"
@ -705,38 +701,36 @@ msgstr "Тыйым салу"
msgid "Grant Access"
msgstr "Рұқсат ету"
#: js/ui/appDisplay.js:956
#: js/ui/appDisplay.js:903
msgid "Unnamed Folder"
msgstr "Атаусыз бума"
#. Translators: This is the heading of a list of open windows
#: js/ui/appDisplay.js:2215 js/ui/panel.js:75
#: js/ui/appDisplay.js:2225 js/ui/panel.js:75
msgid "Open Windows"
msgstr "Ашық терезелер"
#: js/ui/appDisplay.js:2234 js/ui/panel.js:82
#: js/ui/appDisplay.js:2244 js/ui/panel.js:82
msgid "New Window"
msgstr "Жаңа терезе"
#: js/ui/appDisplay.js:2250
#| msgid "Launch using Dedicated Graphics Card"
#: js/ui/appDisplay.js:2260
msgid "Launch using Integrated Graphics Card"
msgstr ""
msgstr "Құрамындағы графикалық картаны пайдаланып жөнелту"
#: js/ui/appDisplay.js:2251
#| msgid "Launch using Dedicated Graphics Card"
#: js/ui/appDisplay.js:2261
msgid "Launch using Discrete Graphics Card"
msgstr ""
msgstr "Бөлек графикалық картаны пайдаланып жөнелту"
#: js/ui/appDisplay.js:2279 js/ui/dash.js:239
#: js/ui/appDisplay.js:2289 js/ui/dash.js:239
msgid "Remove from Favorites"
msgstr "Таңдамалылардан өшіру"
#: js/ui/appDisplay.js:2285
#: js/ui/appDisplay.js:2295
msgid "Add to Favorites"
msgstr "Таңдамалыларға қосу"
#: js/ui/appDisplay.js:2295 js/ui/panel.js:93
#: js/ui/appDisplay.js:2305 js/ui/panel.js:93
msgid "Show Details"
msgstr "Деректерді көрсету"
@ -766,7 +760,7 @@ msgstr "Құлаққап"
msgid "Headset"
msgstr "Микрофонды құлаққап"
#: js/ui/audioDeviceSelection.js:68 js/ui/status/volume.js:273
#: js/ui/audioDeviceSelection.js:68 js/ui/status/volume.js:272
msgid "Microphone"
msgstr "Микрофон"
@ -918,9 +912,8 @@ msgid "External drive disconnected"
msgstr "Сыртқы диск алынды"
#: js/ui/components/automountManager.js:208
#| msgid "Unable to lock"
msgid "Unable to unlock volume"
msgstr ""
msgstr "Томды босату мүмкін емес"
#: js/ui/components/automountManager.js:209
msgid "The installed udisks version does not support the PIM setting"
@ -993,7 +986,6 @@ msgid "PIN code is needed for the mobile broadband device"
msgstr "Сымсыз кеңжолақты құрылғы үшін PIN коды керек"
#: js/ui/components/networkAgent.js:334
#| msgid "PIN: "
msgid "PIN"
msgstr "PIN"
@ -1129,9 +1121,8 @@ msgid "Weather"
msgstr "Ауа райы"
#: js/ui/dateMenu.js:653
#| msgid "Select a location…"
msgid "Select weather location…"
msgstr ""
msgstr "Ауа райы орнын таңдау…"
#: js/ui/endSessionDialog.js:37
#, javascript-format
@ -1251,9 +1242,10 @@ msgstr ""
"эл. желісіне жалғанып тұрғанына көз жеткізіңіз."
#: js/ui/endSessionDialog.js:259
#| msgid "Running on battery power: please plug in before installing updates."
msgid "Running on battery power: Please plug in before installing updates."
msgstr ""
"Батарея қорегінен жұмыс істеуде. Жаңартуларды орнату алдында эл. қорегі "
"желісіне жалғаңыз."
#: js/ui/endSessionDialog.js:268
msgid "Some applications are busy or have unsaved work"
@ -1289,30 +1281,26 @@ msgid "Download and install “%s” from extensions.gnome.org?"
msgstr "extensions.gnome.org адресінен \"%s\" жүктеп алып, орнату керек пе?"
#: js/ui/extensionSystem.js:252
#| msgid "No Extensions Installed"
msgid "Extension Updates Available"
msgstr ""
msgstr "Кеңейту жаңартулары дайын"
#: js/ui/extensionSystem.js:253
msgid "Extension updates are ready to be installed."
msgstr ""
msgstr "Кеңейту жаңартулары орнатылуға дайын."
#: js/ui/inhibitShortcutsDialog.js:79
#| msgid "%s wants to inhibit shortcuts"
msgid "Allow inhibiting shortcuts"
msgstr ""
msgstr "Пернелер жарлығын алмастыруды рұқсат ету"
#. Translators: %s is an application name like "Settings"
#: js/ui/inhibitShortcutsDialog.js:82
#, javascript-format
#| msgid "Application wants to inhibit shortcuts"
msgid "The application %s wants to inhibit shortcuts"
msgstr ""
msgstr "%s қолданбасы пернелер жарлығын алмастырғысы келеді"
#: js/ui/inhibitShortcutsDialog.js:83
#| msgid "Application wants to inhibit shortcuts"
msgid "An application wants to inhibit shortcuts"
msgstr ""
msgstr "Қолданба пернелер жарлығын алмастырғысы келеді"
#. Translators: %s is a keyboard shortcut like "Super+x"
#: js/ui/inhibitShortcutsDialog.js:90
@ -1445,23 +1433,25 @@ msgid "Web Page"
msgstr "Веб парағы"
#: js/ui/main.js:297
#| msgid "Log in as another user"
msgid "Logged in as a privileged user"
msgstr ""
msgstr "Привилегияланған пайдаланушы ретінде жүйеге кірген"
#: js/ui/main.js:298
msgid ""
"Running a session as a privileged user should be avoided for security "
"reasons. If possible, you should log in as a normal user."
msgstr ""
"Привилегияланған пайдаланушы ретінде сессияны орындаудан қауіпсіздік "
"салдарынан аулақ болу керек. Мүмкін болса, қалыпты пайдаланушы ретінде "
"жүйеге кіріңіз."
#: js/ui/main.js:337
msgid "Screen Lock disabled"
msgstr ""
msgstr "Экранды блоктау сөндірілген"
#: js/ui/main.js:338
msgid "Screen Locking requires the GNOME display manager."
msgstr ""
msgstr "Экранды блоктау GNOME дисплейлер басқарушысын талап етеді."
#: js/ui/messageTray.js:1547
msgid "System Information"
@ -1475,13 +1465,13 @@ msgstr "Белгісіз әртіс"
msgid "Unknown title"
msgstr "Белгісіз атауы"
#: js/ui/overview.js:73
#: js/ui/overview.js:74
msgid "Undo"
msgstr "Болдырмау"
#. Translators: This is the main view to select
#. activities. See also note for "Activities" string.
#: js/ui/overview.js:86
#: js/ui/overview.js:87
msgid "Overview"
msgstr "Шолу"
@ -1489,7 +1479,7 @@ msgstr "Шолу"
#. in the search entry when no search is
#. active; it should not exceed ~30
#. characters.
#: js/ui/overview.js:107
#: js/ui/overview.js:108
msgid "Type to search"
msgstr "Іздеу үшін теріңіз"
@ -1626,18 +1616,16 @@ msgid "Caps lock is on."
msgstr "Caps lock іске қосылған."
#: js/ui/shellMountOperation.js:285
#| msgid "Volume"
msgid "Hidden Volume"
msgstr ""
msgstr "Жасырын том"
#: js/ui/shellMountOperation.js:288
msgid "Windows System Volume"
msgstr ""
msgstr "Windows жүйелік томы"
#: js/ui/shellMountOperation.js:291
#| msgid "Mouse Keys"
msgid "Uses Keyfiles"
msgstr ""
msgstr "Кілт файлдарды қолданады"
#. Translators: %s is the Disks application
#: js/ui/shellMountOperation.js:298
@ -1645,6 +1633,7 @@ msgstr ""
msgid ""
"To unlock a volume that uses keyfiles, use the <i>%s</i> utility instead."
msgstr ""
"Кілт файлдарын қолданатын томды босату үшін, <i>%s</i> утилитасын қолданыңыз."
#: js/ui/shellMountOperation.js:306
msgid "PIM Number"
@ -1666,7 +1655,7 @@ msgstr "%s ашу"
#: js/ui/shellMountOperation.js:423
msgid "The PIM must be a number or empty."
msgstr ""
msgstr "PIM тек сандардан тұруы, немесе бос болуы тиіс."
#. Translators: %s is the Disks application
#: js/ui/shellMountOperation.js:465
@ -1678,7 +1667,7 @@ msgstr "%s іске қосу мүмкін емес"
#: js/ui/shellMountOperation.js:467
#, javascript-format
msgid "Couldnt find the %s application"
msgstr ""
msgstr "%s қолданбасы табылмады"
#: js/ui/status/accessibility.js:35
msgid "Accessibility"
@ -1733,14 +1722,12 @@ msgid "Bluetooth Settings"
msgstr "Bluetooth баптаулары"
#: js/ui/status/bluetooth.js:152
#| msgid "Bluetooth"
msgid "Bluetooth Off"
msgstr ""
msgstr "Bluetooth сөндірілген"
#: js/ui/status/bluetooth.js:154
#| msgid "Bluetooth"
msgid "Bluetooth On"
msgstr ""
msgstr "Bluetooth іске қосылған"
#: js/ui/status/brightness.js:39
msgid "Brightness"
@ -1748,7 +1735,7 @@ msgstr "Жарықтылығы"
#: js/ui/status/dwellClick.js:13
msgid "Single Click"
msgstr ""
msgstr "Дара шерту"
#: js/ui/status/dwellClick.js:18
msgid "Double Click"
@ -1760,11 +1747,11 @@ msgstr "Тартып апару"
#: js/ui/status/dwellClick.js:28
msgid "Secondary Click"
msgstr ""
msgstr "Екінші шерту"
#: js/ui/status/dwellClick.js:37
msgid "Dwell Click"
msgstr ""
msgstr "Пернеде кідіртуден кейінгі сол жақпен шерту"
#: js/ui/status/keyboard.js:826
msgid "Keyboard"
@ -1800,7 +1787,7 @@ msgstr "Іске қосу"
#: js/ui/status/location.js:350
msgid "Allow location access"
msgstr ""
msgstr "Орналасуға қатынауды рұқсат ету"
#. Translators: %s is an application name
#: js/ui/status/location.js:352
@ -2140,11 +2127,11 @@ msgstr "Thunderbolt авторизация қатесі"
msgid "Could not authorize the Thunderbolt device: %s"
msgstr "Thunderbolt құралғысын авторизациялау мүмкін емес: %s"
#: js/ui/status/volume.js:154
#: js/ui/status/volume.js:155
msgid "Volume changed"
msgstr "Дыбыс өзгертілді"
#: js/ui/status/volume.js:225
#: js/ui/status/volume.js:217
msgid "Volume"
msgstr "Дыбыс деңгейі"
@ -2179,18 +2166,16 @@ msgstr "Тек құрамындағы"
#. Translators: This is a time format for a date in
#. long format
#: js/ui/unlockDialog.js:371
#| msgctxt "calendar heading"
#| msgid "%A, %B %-d"
msgid "%A %B %-d"
msgstr "%A %B %-d"
#: js/ui/unlockDialog.js:377
msgid "Swipe up to unlock"
msgstr ""
msgstr "Босату үшін жоғары өткізіңіз"
#: js/ui/unlockDialog.js:378
msgid "Click or press a key to unlock"
msgstr ""
msgstr "Босату үшін шертіңіз немесе пернені басыңыз"
#: js/ui/unlockDialog.js:550
msgid "Unlock Window"
@ -2373,6 +2358,8 @@ msgid ""
"GNOME Extensions handles updating extensions, configuring extension "
"preferences and removing or disabling unwanted extensions."
msgstr ""
"GNOME кеңейтулері көмегімен кеңейтулерді жаңарту, баптау және оларды өшіру "
"немесе сөндіруге болады."
#: subprojects/extensions-app/data/org.gnome.Extensions.desktop.in.in:7
msgid "Configure GNOME Shell Extensions"
@ -2388,6 +2375,7 @@ msgid ""
"If you remove the extension, you need to return to download it if you want "
"to enable it again"
msgstr ""
"Кеңейтуді өшірсеңіз, оны қайта іске қосу үшін қайта жүктеп алу керек болады"
#: subprojects/extensions-app/js/main.js:150
msgid "Remove"
@ -2401,15 +2389,15 @@ msgstr "Baurzhan Muftakhidinov <baurthefirst@gmail.com>"
#, javascript-format
msgid "%d extension will be updated on next login."
msgid_plural "%d extensions will be updated on next login."
msgstr[0] ""
msgstr[0] "%d кеңейту жүйеге келесі рет кірген кезде жаңартылатын болады."
#: subprojects/extensions-app/js/main.js:461
msgid "The extension is incompatible with the current GNOME version"
msgstr ""
msgstr "Бұл кеңейту ағымдағы GNOME нұсқасымен үйлеспейді"
#: subprojects/extensions-app/js/main.js:464
msgid "The extension had an error"
msgstr ""
msgstr "Кеңейтуде қате болды"
#: subprojects/extensions-app/data/ui/extension-row.ui:109
#: subprojects/extensions-tool/src/command-create.c:325
@ -2428,7 +2416,7 @@ msgstr "Авторы"
#: subprojects/extensions-app/data/ui/extension-row.ui:216
msgid "Website"
msgstr "Веб-сайт"
msgstr "Веб сайт"
#: subprojects/extensions-app/data/ui/extension-row.ui:233
msgid "Remove…"
@ -2460,6 +2448,9 @@ msgid ""
"encounter problems with your system, it is recommended to disable all "
"extensions."
msgstr ""
"Кеңейтулер жүйелік мәселелерді, соның ішінде өнімділік мәселелерін туғызуы "
"мүмкін. Жүйелік мәселелерге тап болсаңыз, барлық кеңейтулерді сөндіру "
"ұсынылады."
#: subprojects/extensions-app/data/ui/extensions-window.ui:135
msgid "Manually Installed"
@ -2478,10 +2469,12 @@ msgid ""
"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."
msgstr ""
"Кешірім өтінеміз, барлық орнатылған кеңейтулер тізімін алу мүмкін болмады. "
"GNOME ішіне кіргеніңізді тексеріп, қайталап көріңіз."
#: subprojects/extensions-app/data/ui/extensions-window.ui:273
msgid "Extension Updates Ready"
msgstr ""
msgstr "Кеңейту жаңартулары дайын"
#: subprojects/extensions-app/data/ui/extensions-window.ui:289
msgid "Log Out…"
@ -2491,7 +2484,7 @@ msgstr "Жүйеден шығу…"
#: subprojects/extensions-tool/src/command-create.c:226
#, c-format
msgid "The new extension was successfully created in %s.\n"
msgstr ""
msgstr "Жаңа кеңейту %s ішінде сәтті жасалды.\n"
#: subprojects/extensions-tool/src/command-create.c:299
#, c-format
@ -2499,11 +2492,13 @@ msgid ""
"Name should be a very short (ideally descriptive) string.\n"
"Examples are: %s"
msgstr ""
"Атауы қысқа мәтіндік жол (сипаттайтын) болуы тиіс.\n"
"Мысалы: %s"
#: subprojects/extensions-tool/src/command-create.c:305
#: subprojects/extensions-tool/src/main.c:238
msgid "Name"
msgstr "Атауы"
msgstr "Аты"
#: subprojects/extensions-tool/src/command-create.c:319
#, c-format
@ -2511,6 +2506,9 @@ msgid ""
"Description is a single-sentence explanation of what your extension does.\n"
"Examples are: %s"
msgstr ""
"Сипаттамасы - бұл сіздің кеңейтуіңіз жасайтын әрекеттің бір сөйлемді "
"анықтамасы.\n"
"Мысалы: %s"
#: subprojects/extensions-tool/src/command-create.c:339
msgid ""
@ -2518,10 +2516,12 @@ msgid ""
"This should be in the format of an email address (clicktofocus@janedoe."
"example.com)\n"
msgstr ""
"UUID - бұл кеңейтуңіздің глобалды деңгейдегі бірегей идентификаторы.\n"
"Ол эл. пошта адресі пішімінде болуы тиіс (clicktofocus@janedoe.example.com)\n"
#: subprojects/extensions-tool/src/command-create.c:366
msgid "Choose one of the available templates:\n"
msgstr ""
msgstr "Қол жетімді үлгілердің бірін таңдаңыз:\n"
#: subprojects/extensions-tool/src/command-create.c:380
msgid "Template"
@ -2529,7 +2529,7 @@ msgstr "Үлгі"
#: subprojects/extensions-tool/src/command-create.c:435
msgid "The unique identifier of the new extension"
msgstr ""
msgstr "Жаңа кеңейтудің бірегей идентификаторы"
#: subprojects/extensions-tool/src/command-create.c:438
msgid "NAME"
@ -2537,7 +2537,7 @@ msgstr "АТАУЫ"
#: subprojects/extensions-tool/src/command-create.c:439
msgid "The user-visible name of the new extension"
msgstr ""
msgstr "Жаңа кеңейтудің пайдаланушыға көрінетін атауы"
#: subprojects/extensions-tool/src/command-create.c:441
msgid "DESCRIPTION"
@ -2545,7 +2545,7 @@ msgstr "СИПАТТАМАСЫ"
#: subprojects/extensions-tool/src/command-create.c:443
msgid "A short description of what the extension does"
msgstr ""
msgstr "Кеңейтудің қысқаша сипаттамасы"
#: subprojects/extensions-tool/src/command-create.c:446
msgid "TEMPLATE"
@ -2553,11 +2553,11 @@ msgstr "ҮЛГІ"
#: subprojects/extensions-tool/src/command-create.c:447
msgid "The template to use for the new extension"
msgstr ""
msgstr "Жаңа кеңейту үшін қолданылатын үлгі"
#: subprojects/extensions-tool/src/command-create.c:453
msgid "Enter extension information interactively"
msgstr ""
msgstr "Кеңейту ақпаратын интерактивті түрде енгізу"
#: subprojects/extensions-tool/src/command-create.c:461
msgid "Create a new extension"
@ -2570,20 +2570,20 @@ msgstr "Белгісіз аргументтер"
#: subprojects/extensions-tool/src/command-create.c:504
msgid "UUID, name and description are required"
msgstr ""
msgstr "UUID, аты және сипаттамасы керек"
#: subprojects/extensions-tool/src/command-disable.c:46
#: subprojects/extensions-tool/src/command-enable.c:46
#: subprojects/extensions-tool/src/command-info.c:50
#: subprojects/extensions-tool/src/command-list.c:64
msgid "Failed to connect to GNOME Shell\n"
msgstr "GNOME Shell-ға байланысты орнату мүмкін емес\n"
msgstr "GNOME Shell-ға байланысты орнату сәтсіз аяқталды\n"
#: subprojects/extensions-tool/src/command-disable.c:53
#: subprojects/extensions-tool/src/command-enable.c:53
#, c-format
msgid "Extension “%s” does not exist\n"
msgstr ""
msgstr "\"%s\" кеңейтуі жоқ\n"
#: subprojects/extensions-tool/src/command-disable.c:101
msgid "Disable an extension"
@ -2605,7 +2605,7 @@ msgstr "UUID көрсетілмеген"
#: subprojects/extensions-tool/src/command-reset.c:81
#: subprojects/extensions-tool/src/command-uninstall.c:109
msgid "More than one UUID given"
msgstr ""
msgstr "Бірден көп UUID көрсетілген"
#: subprojects/extensions-tool/src/command-enable.c:101
msgid "Enable an extension"
@ -2615,7 +2615,7 @@ msgstr "Кеңейтуді іске қосу"
#: subprojects/extensions-tool/src/main.c:155
#, c-format
msgid "Extension “%s” doesn't exist\n"
msgstr ""
msgstr "\"%s\" кеңейтуі жоқ\n"
#: subprojects/extensions-tool/src/command-info.c:85
msgid "Show extensions info"
@ -2623,60 +2623,51 @@ msgstr "Кеңейтулер ақпаратын көрсету"
#: subprojects/extensions-tool/src/command-install.c:173
msgid "Overwrite an existing extension"
msgstr ""
msgstr "Бар болып тұрған кеңейтуді үстінен жазу"
#: subprojects/extensions-tool/src/command-install.c:175
msgid "EXTENSION_BUNDLE"
msgstr ""
msgstr "КЕҢЕЙТУЕСТЕСІ"
#: subprojects/extensions-tool/src/command-install.c:184
#| msgid "UUIDs of extensions to enable"
msgid "Install an extension bundle"
msgstr ""
msgstr "Кеңейту дестесін орнату"
#: subprojects/extensions-tool/src/command-install.c:202
#| msgid "No extensions installed"
msgid "No extension bundle specified"
msgstr ""
msgstr "Кеңейту дестесі көрсетілмеген"
#: subprojects/extensions-tool/src/command-install.c:208
msgid "More than one extension bundle specified"
msgstr ""
msgstr "Бірден көп кеңейту дестесі көрсетілген"
#: subprojects/extensions-tool/src/command-list.c:128
#| msgid "Shell Extensions"
msgid "Show user-installed extensions"
msgstr ""
msgstr "Пайдаланушы орнатқан кеңейтулерді көрсету"
#: subprojects/extensions-tool/src/command-list.c:131
#| msgid "Shell Extensions"
msgid "Show system-installed extensions"
msgstr ""
msgstr "Жүйелік деңгейде орнатылған кеңейтулерді көрсету"
#: subprojects/extensions-tool/src/command-list.c:134
#| msgid "Shell Extensions"
msgid "Show enabled extensions"
msgstr ""
msgstr "Іске қосылған кеңейтулерді көрсету"
#: subprojects/extensions-tool/src/command-list.c:137
#| msgid "Disable user extensions"
msgid "Show disabled extensions"
msgstr ""
msgstr "Сөндірілген кеңейтулерді көрсету"
#: subprojects/extensions-tool/src/command-list.c:140
#| msgid "GNOME Shell Extension Preferences"
msgid "Show extensions with preferences"
msgstr ""
msgstr "Баптаулары бар кеңейтулерді көрсету"
#: subprojects/extensions-tool/src/command-list.c:143
#| msgid "No extensions installed"
msgid "Show extensions with updates"
msgstr ""
msgstr "Жаңартулары бар кеңейтулерді көрсету"
#: subprojects/extensions-tool/src/command-list.c:146
#| msgid "Visit extension homepage"
msgid "Print extension details"
msgstr ""
msgstr "Кеңейту ақпаратын басып шығару"
#: subprojects/extensions-tool/src/command-list.c:154
msgid "List installed extensions"
@ -2688,7 +2679,7 @@ msgstr "ФАЙЛ"
#: subprojects/extensions-tool/src/command-pack.c:451
msgid "Additional source to include in the bundle"
msgstr ""
msgstr "Дестеге қосылатын қосымша қайнар көз"
#: subprojects/extensions-tool/src/command-pack.c:454
msgid "SCHEMA"
@ -2696,7 +2687,7 @@ msgstr "СҰЛБА"
#: subprojects/extensions-tool/src/command-pack.c:455
msgid "A GSettings schema that should be included"
msgstr ""
msgstr "Құрамына енуі тиіс GSettings сұлбасы"
#: subprojects/extensions-tool/src/command-pack.c:457
#: subprojects/extensions-tool/src/command-pack.c:468
@ -2705,7 +2696,7 @@ msgstr "БУМА"
#: subprojects/extensions-tool/src/command-pack.c:459
msgid "The directory where translations are found"
msgstr ""
msgstr "Аудармалар орналасқан бума"
#: subprojects/extensions-tool/src/command-pack.c:461
msgid "DOMAIN"
@ -2713,37 +2704,37 @@ msgstr "ДОМЕН"
#: subprojects/extensions-tool/src/command-pack.c:463
msgid "The gettext domain to use for translations"
msgstr ""
msgstr "Аудармалар үшін қолданылуы тиіс gettext домені"
#: subprojects/extensions-tool/src/command-pack.c:466
msgid "Overwrite an existing pack"
msgstr ""
msgstr "Бар болып тұрған пакетті үстінен жазу"
#: subprojects/extensions-tool/src/command-pack.c:470
msgid "The directory where the pack should be created"
msgstr ""
msgstr "Десте жасалуы тиіс бума"
#: subprojects/extensions-tool/src/command-pack.c:472
msgid "SOURCE_DIRECTORY"
msgstr ""
msgstr "ҚАЙНАР_КӨЗУМАСЫ"
#: subprojects/extensions-tool/src/command-pack.c:481
msgid "Create an extension bundle"
msgstr ""
msgstr "Кеңейту дестесін жасау"
#: subprojects/extensions-tool/src/command-pack.c:501
msgid "More than one source directory specified"
msgstr ""
msgstr "Бірден көп қайнар көз бумасы көрсетілген"
#: subprojects/extensions-tool/src/command-prefs.c:47
#, c-format
#| msgid "Show extensions with preferences"
msgid "Extension “%s” doesn't have preferences\n"
msgstr ""
msgstr "\"%s\" кеңейтудің баптаулары жоқ\n"
#: subprojects/extensions-tool/src/command-prefs.c:79
#| msgid "GNOME Shell Extension Preferences"
msgid "Opens extension preferences"
msgstr ""
msgstr "Кеңейту баптауларын ашады"
#: subprojects/extensions-tool/src/command-reset.c:58
msgid "Reset an extension"
@ -2764,11 +2755,11 @@ msgstr "Кеңейтуді өшіру"
#: subprojects/extensions-tool/src/main.c:72
msgid "Do not print error messages"
msgstr ""
msgstr "Қате туралы хабарламаларды басып шығармау"
#: subprojects/extensions-tool/src/main.c:146
msgid "Failed to connect to GNOME Shell"
msgstr "GNOME Shell-ға байланысты орнату мүмкін емес"
msgstr "GNOME Shell-ға байланысты орнату сәтсіз аяқталды"
#: subprojects/extensions-tool/src/main.c:244
msgid "Path"
@ -2788,7 +2779,7 @@ msgstr "Қалып-күйі"
#: subprojects/extensions-tool/src/main.c:290
msgid "“version” takes no arguments"
msgstr ""
msgstr "“version” аргументтерді қабылдамайды"
#: subprojects/extensions-tool/src/main.c:292
#: subprojects/extensions-tool/src/main.c:312
@ -2860,11 +2851,11 @@ msgstr "Кеңейту дестесін орнату"
#: subprojects/extensions-tool/src/main.c:330
#, c-format
msgid "Use “%s” to get detailed help.\n"
msgstr ""
msgstr "Толық көмекті алу үшін \"%s\" пайдаланыңыз.\n"
#: subprojects/extensions-tool/src/templates/00-plain.desktop.in:4
msgid "Plain"
msgstr "Кәдімгі"
msgstr "Қалыпты"
#: subprojects/extensions-tool/src/templates/00-plain.desktop.in:5
msgid "An empty extension"
@ -2876,7 +2867,7 @@ msgstr "Индикатор"
#: subprojects/extensions-tool/src/templates/indicator.desktop.in:5
msgid "Add an icon to the top bar"
msgstr ""
msgstr "Жоғарғы панельге таңбашаны қосу"
#. translators:
#. * The number of sound outputs on a particular device
@ -2898,6 +2889,33 @@ msgstr[0] "%u кірісі"
msgid "System Sounds"
msgstr "Жүйелік дыбыстар"
#~ msgid "Frequently used applications will appear here"
#~ msgstr "Жиі қолданылатын қолданбалар осында көрінеді"
#~ msgid "Frequent"
#~ msgstr "Жиі қолданылатын"
#~ msgid "All"
#~ msgstr "Барлығы"
#~ msgctxt "calendar heading"
#~ msgid "%A, %B %-d"
#~ msgstr "%A, %B %-d"
#~ msgctxt "calendar heading"
#~ msgid "%A, %B %-d, %Y"
#~ msgstr "%A, %B %-d, %Y"
#~ msgid "%d Connected"
#~ msgid_plural "%d Connected"
#~ msgstr[0] "%d байланысқан"
#~ msgid "Off"
#~ msgstr "Сөнд."
#~ msgid "On"
#~ msgstr "Іске қос."
#~ msgid ""
#~ "Keybinding that pauses and resumes all running tweens, for debugging "
#~ "purposes"
@ -2927,21 +2945,6 @@ msgstr "Жүйелік дыбыстар"
#~ msgid "Sign In"
#~ msgstr "Кіру"
#~ msgid "Frequently used applications will appear here"
#~ msgstr "Жиі қолданылатын қолданбалар осында көрінеді"
#~ msgid "Frequent"
#~ msgstr "Жиі қолданылатын"
#~ msgid "All"
#~ msgstr "Барлығы"
#~| msgctxt "calendar heading"
#~| msgid "%A, %B %d, %Y"
#~ msgctxt "calendar heading"
#~ msgid "%A, %B %-d, %Y"
#~ msgstr "%A, %B %-d, %Y"
#~ msgid "Password:"
#~ msgstr "Пароль:"
@ -2971,16 +2974,6 @@ msgstr "Жүйелік дыбыстар"
#~ msgid_plural "%d new notifications"
#~ msgstr[0] "%d жаңа ескерту"
#~ msgid "%d Connected"
#~ msgid_plural "%d Connected"
#~ msgstr[0] "%d байланысқан"
#~ msgid "Off"
#~ msgstr "Сөнд."
#~ msgid "On"
#~ msgstr "Іске қос."
#~ msgid "Account Settings"
#~ msgstr "Тіркелгі баптаулары"

872
po/lt.po

File diff suppressed because it is too large Load Diff

941
po/lv.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

159
po/ro.po
View File

@ -10,8 +10,8 @@ msgid ""
msgstr ""
"Project-Id-Version: gnome-shell master\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gnome-shell/issues\n"
"POT-Creation-Date: 2020-06-09 19:41+0000\n"
"PO-Revision-Date: 2020-06-17 18:47+0300\n"
"POT-Creation-Date: 2020-07-21 05:44+0000\n"
"PO-Revision-Date: 2020-07-21 09:07+0200\n"
"Last-Translator: Florentina Mușat <florentina [dot] musat [dot] 28 [at] "
"gmail [dot] com>\n"
"Language-Team: Gnome Romanian Translation Team <gnomero-list@lists."
@ -224,95 +224,112 @@ msgid ""
msgstr ""
"Activează un API D-Bus care permite introspecția stării aplicației shell."
#: data/org.gnome.shell.gschema.xml.in:119
#: data/org.gnome.shell.gschema.xml.in:114
msgid "Layout of the app picker"
msgstr "Aspectul selectorului de aplicații"
#: data/org.gnome.shell.gschema.xml.in:115
msgid ""
"Layout of the app picker. Each entry in the array is a page. Pages are "
"stored in the order they appear in GNOME Shell. Each page contains an "
"“application id” → 'data' pair. Currently, the following values are stored "
"as 'data': • “position”: the position of the application icon in the page"
msgstr ""
"Aspectul selectorului de aplicații. Fiecare intrare din matrice este o "
"pagină. Paginile sunt stocate în ordinea în care apar în GNOME Shell. "
"Fiecare pagină conține o pereche de „id aplicație” → „date”. Momentan, "
"următoarele valori sunt stocate ca „data”: • „poziție”: poziția iconiței "
"aplicației în pagină."
#: data/org.gnome.shell.gschema.xml.in:130
msgid "Keybinding to open the application menu"
msgstr "Combinație de taste pentru deschiderea meniului aplicației"
#: data/org.gnome.shell.gschema.xml.in:120
#: data/org.gnome.shell.gschema.xml.in:131
msgid "Keybinding to open the application menu."
msgstr "Combinație de taste pentru deschiderea meniului aplicației."
#: data/org.gnome.shell.gschema.xml.in:126
#: data/org.gnome.shell.gschema.xml.in:137
msgid "Keybinding to open the “Show Applications” view"
msgstr ""
"Combinație de taste pentru deschiderea modului de afișare „Arată aplicațiile”"
#: data/org.gnome.shell.gschema.xml.in:127
#: data/org.gnome.shell.gschema.xml.in:138
msgid ""
"Keybinding to open the “Show Applications” view of the Activities Overview."
msgstr ""
"Combinație de taste pentru deschiderea modului de afișare „Arată "
"aplicațiile” a prezentării generale a activităților."
#: data/org.gnome.shell.gschema.xml.in:134
#: data/org.gnome.shell.gschema.xml.in:145
msgid "Keybinding to open the overview"
msgstr "Combinație de taste pentru deschiderea prezentării generale"
#: data/org.gnome.shell.gschema.xml.in:135
#: data/org.gnome.shell.gschema.xml.in:146
msgid "Keybinding to open the Activities Overview."
msgstr ""
"Combinație de taste pentru deschiderea prezentării generale a activităților."
#: data/org.gnome.shell.gschema.xml.in:141
#: data/org.gnome.shell.gschema.xml.in:152
msgid "Keybinding to toggle the visibility of the notification list"
msgstr ""
"Combinație de taste pentru comutarea vizibilității listei de notificare"
#: data/org.gnome.shell.gschema.xml.in:142
#: data/org.gnome.shell.gschema.xml.in:153
msgid "Keybinding to toggle the visibility of the notification list."
msgstr ""
"Combinație de taste pentru comutarea vizibilității listei de notificare."
#: data/org.gnome.shell.gschema.xml.in:148
#: data/org.gnome.shell.gschema.xml.in:159
msgid "Keybinding to focus the active notification"
msgstr "Combinație de taste pentru focalizarea notificării active"
#: data/org.gnome.shell.gschema.xml.in:149
#: data/org.gnome.shell.gschema.xml.in:160
msgid "Keybinding to focus the active notification."
msgstr "Combinație de taste pentru focalizarea notificării active."
#: data/org.gnome.shell.gschema.xml.in:155
#: data/org.gnome.shell.gschema.xml.in:166
msgid "Switch to application 1"
msgstr "Comută la aplicația 1"
#: data/org.gnome.shell.gschema.xml.in:159
#: data/org.gnome.shell.gschema.xml.in:170
msgid "Switch to application 2"
msgstr "Comută la aplicația 2"
#: data/org.gnome.shell.gschema.xml.in:163
#: data/org.gnome.shell.gschema.xml.in:174
msgid "Switch to application 3"
msgstr "Comută la aplicația 3"
#: data/org.gnome.shell.gschema.xml.in:167
#: data/org.gnome.shell.gschema.xml.in:178
msgid "Switch to application 4"
msgstr "Comută la aplicația 4"
#: data/org.gnome.shell.gschema.xml.in:171
#: data/org.gnome.shell.gschema.xml.in:182
msgid "Switch to application 5"
msgstr "Comută la aplicația 5"
#: data/org.gnome.shell.gschema.xml.in:175
#: data/org.gnome.shell.gschema.xml.in:186
msgid "Switch to application 6"
msgstr "Comută la aplicația 6"
#: data/org.gnome.shell.gschema.xml.in:179
#: data/org.gnome.shell.gschema.xml.in:190
msgid "Switch to application 7"
msgstr "Comută la aplicația 7"
#: data/org.gnome.shell.gschema.xml.in:183
#: data/org.gnome.shell.gschema.xml.in:194
msgid "Switch to application 8"
msgstr "Comută la aplicația 8"
#: data/org.gnome.shell.gschema.xml.in:187
#: data/org.gnome.shell.gschema.xml.in:198
msgid "Switch to application 9"
msgstr "Comută la aplicația 9"
#: data/org.gnome.shell.gschema.xml.in:196
#: data/org.gnome.shell.gschema.xml.in:223
#: data/org.gnome.shell.gschema.xml.in:207
#: data/org.gnome.shell.gschema.xml.in:234
msgid "Limit switcher to current workspace."
msgstr "Limitează comutatorul la spațiul de lucru curent."
#: data/org.gnome.shell.gschema.xml.in:197
#: data/org.gnome.shell.gschema.xml.in:208
msgid ""
"If true, only applications that have windows on the current workspace are "
"shown in the switcher. Otherwise, all applications are included."
@ -320,11 +337,11 @@ msgstr ""
"Dacă este activat, doar aplicațiile care au ferestre în spațiul de lucru "
"curent sunt arătate în comutator. Altfel, toate aplicațiile sunt incluse."
#: data/org.gnome.shell.gschema.xml.in:214
#: data/org.gnome.shell.gschema.xml.in:225
msgid "The application icon mode."
msgstr "Miniatură și pictograma aplicației."
#: data/org.gnome.shell.gschema.xml.in:215
#: data/org.gnome.shell.gschema.xml.in:226
msgid ""
"Configures how the windows are shown in the switcher. Valid possibilities "
"are “thumbnail-only” (shows a thumbnail of the window), “app-icon-"
@ -334,7 +351,7 @@ msgstr ""
"Posibilități valide sunt „mod miniatură” (arată o miniatură a ferestrei) "
"„mod iconiță” (arată doar iconița aplicației) sau „ambele”."
#: data/org.gnome.shell.gschema.xml.in:224
#: data/org.gnome.shell.gschema.xml.in:235
msgid ""
"If true, only windows from the current workspace are shown in the switcher. "
"Otherwise, all windows are included."
@ -342,59 +359,59 @@ msgstr ""
"Dacă este activat, doar ferestrele din spațiul de lucru curent sunt arătate "
"în comutator. Altfel, toate ferestrele sunt incluse."
#: data/org.gnome.shell.gschema.xml.in:234
#: data/org.gnome.shell.gschema.xml.in:245
msgid "Locations"
msgstr "Locații"
#: data/org.gnome.shell.gschema.xml.in:235
#: data/org.gnome.shell.gschema.xml.in:246
msgid "The locations to show in world clocks"
msgstr "Locațiile de arătat în ceasuri globale"
#: data/org.gnome.shell.gschema.xml.in:245
#: data/org.gnome.shell.gschema.xml.in:256
msgid "Automatic location"
msgstr "Locație automată"
#: data/org.gnome.shell.gschema.xml.in:246
#: data/org.gnome.shell.gschema.xml.in:257
msgid "Whether to fetch the current location or not"
msgstr "Dacă să se obțină locația curentă"
#: data/org.gnome.shell.gschema.xml.in:253
#: data/org.gnome.shell.gschema.xml.in:264
msgid "Location"
msgstr "Locație"
#: data/org.gnome.shell.gschema.xml.in:254
#: data/org.gnome.shell.gschema.xml.in:265
msgid "The location for which to show a forecast"
msgstr "Locația pentru care să se arate o prognoză"
#: data/org.gnome.shell.gschema.xml.in:266
#: data/org.gnome.shell.gschema.xml.in:277
msgid "Attach modal dialog to the parent window"
msgstr "Atașează dialogul modal la fereastra părinte"
#: data/org.gnome.shell.gschema.xml.in:267
#: data/org.gnome.shell.gschema.xml.in:276
#: data/org.gnome.shell.gschema.xml.in:284
#: data/org.gnome.shell.gschema.xml.in:292
#: data/org.gnome.shell.gschema.xml.in:300
#: data/org.gnome.shell.gschema.xml.in:278
#: data/org.gnome.shell.gschema.xml.in:287
#: data/org.gnome.shell.gschema.xml.in:295
#: data/org.gnome.shell.gschema.xml.in:303
#: data/org.gnome.shell.gschema.xml.in:311
msgid ""
"This key overrides the key in org.gnome.mutter when running GNOME Shell."
msgstr ""
"Această cheie suprascrie cheia corespondentă din org.gnome.mutter când "
"Vizualizatorul activităților GNOME rulează."
#: data/org.gnome.shell.gschema.xml.in:275
#: data/org.gnome.shell.gschema.xml.in:286
msgid "Enable edge tiling when dropping windows on screen edges"
msgstr ""
"Activează mozaic lateral la plasarea ferestrelor pe marginile ecranului"
#: data/org.gnome.shell.gschema.xml.in:283
#: data/org.gnome.shell.gschema.xml.in:294
msgid "Workspaces are managed dynamically"
msgstr "Spațiile de lucru sunt gestionate în mod dinamic"
#: data/org.gnome.shell.gschema.xml.in:291
#: data/org.gnome.shell.gschema.xml.in:302
msgid "Workspaces only on primary monitor"
msgstr "Spații de lucru doar pe monitorul principal"
#: data/org.gnome.shell.gschema.xml.in:299
#: data/org.gnome.shell.gschema.xml.in:310
msgid "Delay focus changes in mouse mode until the pointer stops moving"
msgstr ""
"Întârzie schimbările de focalizare în maus până când cursorul încetează să "
@ -433,7 +450,7 @@ msgstr "Vizitează pagina principală a extensiei"
#: js/gdm/authPrompt.js:135 js/ui/audioDeviceSelection.js:57
#: js/ui/components/networkAgent.js:110 js/ui/components/polkitAgent.js:139
#: js/ui/endSessionDialog.js:369 js/ui/extensionDownloader.js:181
#: js/ui/endSessionDialog.js:369 js/ui/extensionDownloader.js:183
#: js/ui/shellMountOperation.js:376 js/ui/shellMountOperation.js:386
#: js/ui/status/network.js:916 subprojects/extensions-app/js/main.js:149
msgid "Cancel"
@ -475,7 +492,7 @@ msgstr "Nume de utilizator"
msgid "Login Window"
msgstr "Fereastră de autentificare"
#: js/gdm/util.js:345
#: js/gdm/util.js:355
msgid "Authentication error"
msgstr "Eroare de autentificare"
@ -484,7 +501,7 @@ msgstr "Eroare de autentificare"
#. as a cue to display our own message.
#. Translators: this message is shown below the password entry field
#. to indicate the user can swipe their finger instead
#: js/gdm/util.js:471
#: js/gdm/util.js:481
msgid "(or swipe finger)"
msgstr "(sau treceți degetul peste)"
@ -727,36 +744,36 @@ msgstr "Refuză accesul"
msgid "Grant Access"
msgstr "Permite accesul"
#: js/ui/appDisplay.js:902
#: js/ui/appDisplay.js:1297
msgid "Unnamed Folder"
msgstr "Dosar nedenumit"
#. Translators: This is the heading of a list of open windows
#: js/ui/appDisplay.js:2241 js/ui/panel.js:75
#: js/ui/appDisplay.js:2767 js/ui/panel.js:75
msgid "Open Windows"
msgstr "Ferestre deschise"
#: js/ui/appDisplay.js:2260 js/ui/panel.js:82
#: js/ui/appDisplay.js:2786 js/ui/panel.js:82
msgid "New Window"
msgstr "Fereastră nouă"
#: js/ui/appDisplay.js:2276
#: js/ui/appDisplay.js:2802
msgid "Launch using Integrated Graphics Card"
msgstr "Lansează folosind placa grafică integrată"
#: js/ui/appDisplay.js:2277
#: js/ui/appDisplay.js:2803
msgid "Launch using Discrete Graphics Card"
msgstr "Lansează folosind placa grafică discretă"
#: js/ui/appDisplay.js:2305 js/ui/dash.js:239
#: js/ui/appDisplay.js:2831 js/ui/dash.js:239
msgid "Remove from Favorites"
msgstr "Elimină din favorite"
#: js/ui/appDisplay.js:2311
#: js/ui/appDisplay.js:2837
msgid "Add to Favorites"
msgstr "Adaugă la Favorite"
#: js/ui/appDisplay.js:2321 js/ui/panel.js:93
#: js/ui/appDisplay.js:2847 js/ui/panel.js:93
msgid "Show Details"
msgstr "Arată detaliile"
@ -786,7 +803,7 @@ msgstr "Căști auriculare"
msgid "Headset"
msgstr "Căști cu microfon"
#: js/ui/audioDeviceSelection.js:68 js/ui/status/volume.js:273
#: js/ui/audioDeviceSelection.js:68 js/ui/status/volume.js:272
msgid "Microphone"
msgstr "Microfon"
@ -1300,15 +1317,15 @@ msgstr "%s (la distanță)"
msgid "%s (console)"
msgstr "%s (consolă)"
#: js/ui/extensionDownloader.js:185
#: js/ui/extensionDownloader.js:187
msgid "Install"
msgstr "Instalează"
#: js/ui/extensionDownloader.js:191
#: js/ui/extensionDownloader.js:193
msgid "Install Extension"
msgstr "Instalează extensia"
#: js/ui/extensionDownloader.js:192
#: js/ui/extensionDownloader.js:194
#, javascript-format
msgid "Download and install “%s” from extensions.gnome.org?"
msgstr "Descărcați și instalați „%s” de la extensions.gnome.org?"
@ -1341,11 +1358,11 @@ msgstr "O aplicație vrea să inhibe scurtăturile"
msgid "You can restore shortcuts by pressing %s."
msgstr "Puteți restaura scurtăturile apăsând %s."
#: js/ui/inhibitShortcutsDialog.js:98
#: js/ui/inhibitShortcutsDialog.js:100
msgid "Deny"
msgstr "Refuză"
#: js/ui/inhibitShortcutsDialog.js:105
#: js/ui/inhibitShortcutsDialog.js:107
msgid "Allow"
msgstr "Permite"
@ -1414,7 +1431,7 @@ msgstr "Oprește"
msgid "Leave Off"
msgstr "Lasă oprit"
#: js/ui/keyboard.js:207
#: js/ui/keyboard.js:225
msgid "Region & Language Settings"
msgstr "Configurări de regiune și limbă"
@ -1488,7 +1505,7 @@ msgstr "Blocarea ecranului este dezactivată"
msgid "Screen Locking requires the GNOME display manager."
msgstr "Blocarea ecranului necesită administratorul de afișaj GNOME."
#: js/ui/messageTray.js:1547
#: js/ui/messageTray.js:1476
msgid "System Information"
msgstr "Informații despre sistem"
@ -1500,13 +1517,13 @@ msgstr "Artist necunoscut"
msgid "Unknown title"
msgstr "Titlu necunoscut"
#: js/ui/overview.js:73
#: js/ui/overview.js:74
msgid "Undo"
msgstr "Anulează"
#. Translators: This is the main view to select
#. activities. See also note for "Activities" string.
#: js/ui/overview.js:86
#: js/ui/overview.js:87
msgid "Overview"
msgstr "Prezentare generală"
@ -1514,7 +1531,7 @@ msgstr "Prezentare generală"
#. in the search entry when no search is
#. active; it should not exceed ~30
#. characters.
#: js/ui/overview.js:107
#: js/ui/overview.js:108
msgid "Type to search"
msgstr "Tastați pentru a căuta"
@ -2172,11 +2189,11 @@ msgstr "Eroare de autorizare Thunderbolt"
msgid "Could not authorize the Thunderbolt device: %s"
msgstr "Nu s-a putut autoriza dispozitivul Thunderbolt: %s"
#: js/ui/status/volume.js:154
#: js/ui/status/volume.js:155
msgid "Volume changed"
msgstr "Volumul a fost schimbat"
#: js/ui/status/volume.js:225
#: js/ui/status/volume.js:217
msgid "Volume"
msgstr "Volum"
@ -2222,11 +2239,11 @@ msgstr "Glisați în sus pentru a debloca"
msgid "Click or press a key to unlock"
msgstr "Apăsați clic sau o tastă pentru a debloca"
#: js/ui/unlockDialog.js:550
#: js/ui/unlockDialog.js:555
msgid "Unlock Window"
msgstr "Deblochează fereastră"
#: js/ui/unlockDialog.js:559
#: js/ui/unlockDialog.js:564
msgid "Log in as another user"
msgstr "Intră în sesiune ca utilizator diferit"
@ -2362,12 +2379,12 @@ msgstr "Utilizează un mod specific, de exemplu „gdm” pentru ecranul de loga
msgid "List possible modes"
msgstr "Enumeră câmpurile care pot fi afișate"
#: src/shell-app.c:286
#: src/shell-app.c:268
msgctxt "program"
msgid "Unknown"
msgstr "Necunoscut"
#: src/shell-app.c:537
#: src/shell-app.c:519
#, c-format
msgid "Failed to launch “%s”"
msgstr "Nu s-a putut lansa „%s”"

160
po/tr.po
View File

@ -17,8 +17,8 @@ msgid ""
msgstr ""
"Project-Id-Version: gnome-shell\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gnome-shell/issues\n"
"POT-Creation-Date: 2020-06-11 10:28+0000\n"
"PO-Revision-Date: 2020-05-16 12:12+0300\n"
"POT-Creation-Date: 2020-07-29 07:55+0000\n"
"PO-Revision-Date: 2020-07-30 00:49+0300\n"
"Last-Translator: Emin Tufan Çetin <etcetin@gmail.com>\n"
"Language-Team: Türkçe <gnome-turk@gnome.org>\n"
"Language: tr\n"
@ -225,91 +225,107 @@ msgstr ""
"Kabuğun uygulama durumunu gözden geçirmeyi sağlayan D-Bus APIʼsını "
"etkinleştirir."
#: data/org.gnome.shell.gschema.xml.in:119
#: data/org.gnome.shell.gschema.xml.in:114
msgid "Layout of the app picker"
msgstr "Uygulama seçicinin düzeni"
#: data/org.gnome.shell.gschema.xml.in:115
msgid ""
"Layout of the app picker. Each entry in the array is a page. Pages are "
"stored in the order they appear in GNOME Shell. Each page contains an "
"“application id” → 'data' pair. Currently, the following values are stored "
"as 'data': • “position”: the position of the application icon in the page"
msgstr ""
"Uygulama seçicinin düzeni. Dizideki her girdi bir sayfadır. Sayfalar "
"GNOME Kabuğunda göründüğü sırayla depolanır. Her sayfa bir “application id” "
"→ 'data' çifti içerir. Şimdilik şu değerler 'data' olarak depolanır: "
"• “position”: sayfadaki uygulama simgesinin konumu"
#: data/org.gnome.shell.gschema.xml.in:130
msgid "Keybinding to open the application menu"
msgstr "Uygulama menüsünü açmak için klavye kısayolu"
#: data/org.gnome.shell.gschema.xml.in:120
#: data/org.gnome.shell.gschema.xml.in:131
msgid "Keybinding to open the application menu."
msgstr "Uygulama menüsünü açmak için klavye kısayolu."
#: data/org.gnome.shell.gschema.xml.in:126
#: data/org.gnome.shell.gschema.xml.in:137
msgid "Keybinding to open the “Show Applications” view"
msgstr "“Uygulamaları Göster” görünümünü açmak için klavye kısayolu"
#: data/org.gnome.shell.gschema.xml.in:127
#: data/org.gnome.shell.gschema.xml.in:138
msgid ""
"Keybinding to open the “Show Applications” view of the Activities Overview."
msgstr ""
"Etkinlikler Genel Görünümünün “Uygulamaları Göster” görünümünü açmak için "
"klavye kısayolu."
#: data/org.gnome.shell.gschema.xml.in:134
#: data/org.gnome.shell.gschema.xml.in:145
msgid "Keybinding to open the overview"
msgstr "Genel görünümü açmak için klavye kısayolu"
#: data/org.gnome.shell.gschema.xml.in:135
#: data/org.gnome.shell.gschema.xml.in:146
msgid "Keybinding to open the Activities Overview."
msgstr "Etkinlikler Genel Görünümünü açmak için klavye kısayolu."
#: data/org.gnome.shell.gschema.xml.in:141
#: data/org.gnome.shell.gschema.xml.in:152
msgid "Keybinding to toggle the visibility of the notification list"
msgstr "Bildirim listesinin görünürlüğünü değiştirmek için klavye kısayolu"
#: data/org.gnome.shell.gschema.xml.in:142
#: data/org.gnome.shell.gschema.xml.in:153
msgid "Keybinding to toggle the visibility of the notification list."
msgstr "Bildirim listesinin görünürlüğünü değiştirmek için klavye kısayolu."
#: data/org.gnome.shell.gschema.xml.in:148
#: data/org.gnome.shell.gschema.xml.in:159
msgid "Keybinding to focus the active notification"
msgstr "Etkin bildirime odaklanmak için klavye kısayolu"
#: data/org.gnome.shell.gschema.xml.in:149
#: data/org.gnome.shell.gschema.xml.in:160
msgid "Keybinding to focus the active notification."
msgstr "Etkin bildirime odaklanmak için klavye kısayolu."
#: data/org.gnome.shell.gschema.xml.in:155
#: data/org.gnome.shell.gschema.xml.in:166
msgid "Switch to application 1"
msgstr "Uygulama 1ʼe geç"
#: data/org.gnome.shell.gschema.xml.in:159
#: data/org.gnome.shell.gschema.xml.in:170
msgid "Switch to application 2"
msgstr "Uygulama 2ʼye geç"
#: data/org.gnome.shell.gschema.xml.in:163
#: data/org.gnome.shell.gschema.xml.in:174
msgid "Switch to application 3"
msgstr "Uygulama 3ʼe geç"
#: data/org.gnome.shell.gschema.xml.in:167
#: data/org.gnome.shell.gschema.xml.in:178
msgid "Switch to application 4"
msgstr "Uygulama 4ʼe geç"
#: data/org.gnome.shell.gschema.xml.in:171
#: data/org.gnome.shell.gschema.xml.in:182
msgid "Switch to application 5"
msgstr "Uygulama 5ʼe geç"
#: data/org.gnome.shell.gschema.xml.in:175
#: data/org.gnome.shell.gschema.xml.in:186
msgid "Switch to application 6"
msgstr "Uygulama 6ʼya geç"
#: data/org.gnome.shell.gschema.xml.in:179
#: data/org.gnome.shell.gschema.xml.in:190
msgid "Switch to application 7"
msgstr "Uygulama 7ʼye geç"
#: data/org.gnome.shell.gschema.xml.in:183
#: data/org.gnome.shell.gschema.xml.in:194
msgid "Switch to application 8"
msgstr "Uygulama 8ʼe geç"
#: data/org.gnome.shell.gschema.xml.in:187
#: data/org.gnome.shell.gschema.xml.in:198
msgid "Switch to application 9"
msgstr "Uygulama 9ʼa geç"
#: data/org.gnome.shell.gschema.xml.in:196
#: data/org.gnome.shell.gschema.xml.in:223
#: data/org.gnome.shell.gschema.xml.in:207
#: data/org.gnome.shell.gschema.xml.in:234
msgid "Limit switcher to current workspace."
msgstr "Geçiş menüsünü geçerli çalışma alanıyla sınırla."
#: data/org.gnome.shell.gschema.xml.in:197
#: data/org.gnome.shell.gschema.xml.in:208
msgid ""
"If true, only applications that have windows on the current workspace are "
"shown in the switcher. Otherwise, all applications are included."
@ -318,11 +334,11 @@ msgstr ""
"uygulamalar geçiş menüsünde gösterilir. Aksi halde, tüm uygulamalar "
"görünecektir."
#: data/org.gnome.shell.gschema.xml.in:214
#: data/org.gnome.shell.gschema.xml.in:225
msgid "The application icon mode."
msgstr "Uygulama simge kipi."
#: data/org.gnome.shell.gschema.xml.in:215
#: data/org.gnome.shell.gschema.xml.in:226
msgid ""
"Configures how the windows are shown in the switcher. Valid possibilities "
"are “thumbnail-only” (shows a thumbnail of the window), “app-icon-"
@ -333,7 +349,7 @@ msgstr ""
"only” (yalnızca uygulama simgesini gösterir) ya da “both” (her ikisi) "
"değerleridir."
#: data/org.gnome.shell.gschema.xml.in:224
#: data/org.gnome.shell.gschema.xml.in:235
msgid ""
"If true, only windows from the current workspace are shown in the switcher. "
"Otherwise, all windows are included."
@ -341,59 +357,59 @@ msgstr ""
"Eğer bu seçenek etkinse, yalnızca geçerli çalışma alanındaki pencereler "
"geçiş menüsünde gösterilir. Aksi halde, tüm pencereler görünecektir."
#: data/org.gnome.shell.gschema.xml.in:234
#: data/org.gnome.shell.gschema.xml.in:245
msgid "Locations"
msgstr "Konumlar"
#: data/org.gnome.shell.gschema.xml.in:235
#: data/org.gnome.shell.gschema.xml.in:246
msgid "The locations to show in world clocks"
msgstr "Dünya saatlerinde gösterilecek konumlar"
#: data/org.gnome.shell.gschema.xml.in:245
#: data/org.gnome.shell.gschema.xml.in:256
msgid "Automatic location"
msgstr "Kendiliğinden konumlama"
#: data/org.gnome.shell.gschema.xml.in:246
#: data/org.gnome.shell.gschema.xml.in:257
msgid "Whether to fetch the current location or not"
msgstr "Geçerli konumun getirilip getirilmeyeceğini belirler"
#: data/org.gnome.shell.gschema.xml.in:253
#: data/org.gnome.shell.gschema.xml.in:264
msgid "Location"
msgstr "Konum"
#: data/org.gnome.shell.gschema.xml.in:254
#: data/org.gnome.shell.gschema.xml.in:265
msgid "The location for which to show a forecast"
msgstr "Hava durumunun gösterileceği konum"
#: data/org.gnome.shell.gschema.xml.in:266
#: data/org.gnome.shell.gschema.xml.in:277
msgid "Attach modal dialog to the parent window"
msgstr "Yardımcı iletişim penceresini üst pencereye iliştir"
#: data/org.gnome.shell.gschema.xml.in:267
#: data/org.gnome.shell.gschema.xml.in:276
#: data/org.gnome.shell.gschema.xml.in:284
#: data/org.gnome.shell.gschema.xml.in:292
#: data/org.gnome.shell.gschema.xml.in:300
#: data/org.gnome.shell.gschema.xml.in:278
#: data/org.gnome.shell.gschema.xml.in:287
#: data/org.gnome.shell.gschema.xml.in:295
#: data/org.gnome.shell.gschema.xml.in:303
#: data/org.gnome.shell.gschema.xml.in:311
msgid ""
"This key overrides the key in org.gnome.mutter when running GNOME Shell."
msgstr ""
"Bu anahtar, GNOME Shell çalışırken org.gnome.mutter içindeki anahtarı "
"geçersiz kılar."
#: data/org.gnome.shell.gschema.xml.in:275
#: data/org.gnome.shell.gschema.xml.in:286
msgid "Enable edge tiling when dropping windows on screen edges"
msgstr ""
"Pencereler ekran kenarlarında bırakıldığında kenar döşemeyi etkinleştir"
#: data/org.gnome.shell.gschema.xml.in:283
#: data/org.gnome.shell.gschema.xml.in:294
msgid "Workspaces are managed dynamically"
msgstr "Çalışma alanları dinamik olarak yönetilir"
#: data/org.gnome.shell.gschema.xml.in:291
#: data/org.gnome.shell.gschema.xml.in:302
msgid "Workspaces only on primary monitor"
msgstr "Çalışma alanları yalnızca birincil ekranda"
#: data/org.gnome.shell.gschema.xml.in:299
#: data/org.gnome.shell.gschema.xml.in:310
msgid "Delay focus changes in mouse mode until the pointer stops moving"
msgstr ""
"Fare kipinde odak değişikliklerini işaretçi hareketi durana kadar beklet"
@ -430,7 +446,7 @@ msgstr "Uzantı ana sayfasını ziyaret et"
#: js/gdm/authPrompt.js:135 js/ui/audioDeviceSelection.js:57
#: js/ui/components/networkAgent.js:110 js/ui/components/polkitAgent.js:139
#: js/ui/endSessionDialog.js:369 js/ui/extensionDownloader.js:181
#: js/ui/endSessionDialog.js:369 js/ui/extensionDownloader.js:183
#: js/ui/shellMountOperation.js:376 js/ui/shellMountOperation.js:386
#: js/ui/status/network.js:916 subprojects/extensions-app/js/main.js:149
msgid "Cancel"
@ -468,11 +484,11 @@ msgstr "(örneğin, kullanıcı veya %s)"
msgid "Username"
msgstr "Kullanıcı Adı"
#: js/gdm/loginDialog.js:1254
#: js/gdm/loginDialog.js:1253
msgid "Login Window"
msgstr "Oturum Açma Penceresi"
#: js/gdm/util.js:345
#: js/gdm/util.js:355
msgid "Authentication error"
msgstr "Kimlik doğrulama hatası"
@ -481,7 +497,7 @@ msgstr "Kimlik doğrulama hatası"
#. as a cue to display our own message.
#. Translators: this message is shown below the password entry field
#. to indicate the user can swipe their finger instead
#: js/gdm/util.js:471
#: js/gdm/util.js:481
msgid "(or swipe finger)"
msgstr "(ya da parmak izi okut)"
@ -710,36 +726,36 @@ msgstr "Erişimi Reddet"
msgid "Grant Access"
msgstr "Erişime İzin Ver"
#: js/ui/appDisplay.js:902
#: js/ui/appDisplay.js:1297
msgid "Unnamed Folder"
msgstr "Adsız Klasör"
#. Translators: This is the heading of a list of open windows
#: js/ui/appDisplay.js:2241 js/ui/panel.js:75
#: js/ui/appDisplay.js:2767 js/ui/panel.js:75
msgid "Open Windows"
msgstr "Açık Pencereler"
#: js/ui/appDisplay.js:2260 js/ui/panel.js:82
#: js/ui/appDisplay.js:2786 js/ui/panel.js:82
msgid "New Window"
msgstr "Yeni Pencere"
#: js/ui/appDisplay.js:2276
#: js/ui/appDisplay.js:2802
msgid "Launch using Integrated Graphics Card"
msgstr "Tümleşik Ekran Kartıyla Başlat"
#: js/ui/appDisplay.js:2277
#: js/ui/appDisplay.js:2803
msgid "Launch using Discrete Graphics Card"
msgstr "Ayrık Ekran Kartıyla Başlat"
#: js/ui/appDisplay.js:2305 js/ui/dash.js:239
#: js/ui/appDisplay.js:2831 js/ui/dash.js:239
msgid "Remove from Favorites"
msgstr "Sık Kullanılanlardan Çıkar"
#: js/ui/appDisplay.js:2311
#: js/ui/appDisplay.js:2837
msgid "Add to Favorites"
msgstr "Sık Kullanılanlara Ekle"
#: js/ui/appDisplay.js:2321 js/ui/panel.js:93
#: js/ui/appDisplay.js:2847 js/ui/panel.js:93
msgid "Show Details"
msgstr "Ayrıntıları Göster"
@ -769,7 +785,7 @@ msgstr "Kulaklıklar"
msgid "Headset"
msgstr "Kulaklıklı Mikrofon"
#: js/ui/audioDeviceSelection.js:68 js/ui/status/volume.js:273
#: js/ui/audioDeviceSelection.js:68 js/ui/status/volume.js:272
msgid "Microphone"
msgstr "Mikrofon"
@ -1273,15 +1289,15 @@ msgstr "%s (uzak)"
msgid "%s (console)"
msgstr "%s (uçbirim)"
#: js/ui/extensionDownloader.js:185
#: js/ui/extensionDownloader.js:187
msgid "Install"
msgstr "Kur"
#: js/ui/extensionDownloader.js:191
#: js/ui/extensionDownloader.js:193
msgid "Install Extension"
msgstr "Uzantı Yükle"
#: js/ui/extensionDownloader.js:192
#: js/ui/extensionDownloader.js:194
#, javascript-format
msgid "Download and install “%s” from extensions.gnome.org?"
msgstr "extensions.gnome.org üstünden “%s” uzantısı indirilip kurulsun mu?"
@ -1314,11 +1330,11 @@ msgstr "Bir uygulama, kısayolları baskılamak istiyor"
msgid "You can restore shortcuts by pressing %s."
msgstr "%s kısayoluyla, kısayolları geri yükleyebilirsiniz."
#: js/ui/inhibitShortcutsDialog.js:98
#: js/ui/inhibitShortcutsDialog.js:100
msgid "Deny"
msgstr "Reddet"
#: js/ui/inhibitShortcutsDialog.js:105
#: js/ui/inhibitShortcutsDialog.js:107
msgid "Allow"
msgstr "İzin ver"
@ -1384,7 +1400,7 @@ msgstr "Kapat"
msgid "Leave Off"
msgstr "Kapalı Bırak"
#: js/ui/keyboard.js:207
#: js/ui/keyboard.js:225
msgid "Region & Language Settings"
msgstr "Bölge ve Dil Ayarları"
@ -1457,7 +1473,7 @@ msgstr "Ekran Kilidi devre dışı"
msgid "Screen Locking requires the GNOME display manager."
msgstr "Ekran Kilitleme, GNOME ekran yöneticisi gerektirir."
#: js/ui/messageTray.js:1547
#: js/ui/messageTray.js:1476
msgid "System Information"
msgstr "Sistem Bilgisi"
@ -1469,13 +1485,13 @@ msgstr "Bilinmeyen sanatçı"
msgid "Unknown title"
msgstr "Bilinmeyen başlık"
#: js/ui/overview.js:73
#: js/ui/overview.js:74
msgid "Undo"
msgstr "Geri Al"
#. Translators: This is the main view to select
#. activities. See also note for "Activities" string.
#: js/ui/overview.js:86
#: js/ui/overview.js:87
msgid "Overview"
msgstr "Genel Görünüm"
@ -1483,7 +1499,7 @@ msgstr "Genel Görünüm"
#. in the search entry when no search is
#. active; it should not exceed ~30
#. characters.
#: js/ui/overview.js:107
#: js/ui/overview.js:108
msgid "Type to search"
msgstr "Aramak için yaz"
@ -2131,11 +2147,11 @@ msgstr "Thunderbolt yetkilendirme hatası"
msgid "Could not authorize the Thunderbolt device: %s"
msgstr "Thunderbolt aygıtı yetkilendirilemedi: %s"
#: js/ui/status/volume.js:154
#: js/ui/status/volume.js:155
msgid "Volume changed"
msgstr "Bölüm değişti"
#: js/ui/status/volume.js:225
#: js/ui/status/volume.js:217
msgid "Volume"
msgstr "Bölüm"
@ -2181,11 +2197,11 @@ msgstr "Kilidi açmak için yukarı kaydır"
msgid "Click or press a key to unlock"
msgstr "Kilidi açmak için tıklayın veya tuşa basın"
#: js/ui/unlockDialog.js:550
#: js/ui/unlockDialog.js:555
msgid "Unlock Window"
msgstr "Kilit Açma Penceresi"
#: js/ui/unlockDialog.js:559
#: js/ui/unlockDialog.js:564
msgid "Log in as another user"
msgstr "Başka kullanıcı olarak oturum aç"
@ -2319,12 +2335,12 @@ msgstr "Oturum açma ekranı için -“gdm” gibi- özel kip kullan"
msgid "List possible modes"
msgstr "Olası kipleri listele"
#: src/shell-app.c:286
#: src/shell-app.c:268
msgctxt "program"
msgid "Unknown"
msgstr "Bilinmeyen"
#: src/shell-app.c:537
#: src/shell-app.c:519
#, c-format
msgid "Failed to launch “%s”"
msgstr "“%s” başlatılamadı"

194
po/uk.po
View File

@ -10,8 +10,8 @@ msgid ""
msgstr ""
"Project-Id-Version: gnome-shell master\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gnome-shell/issues\n"
"POT-Creation-Date: 2020-06-05 23:11+0000\n"
"PO-Revision-Date: 2020-06-06 15:53+0300\n"
"POT-Creation-Date: 2020-07-20 16:18+0000\n"
"PO-Revision-Date: 2020-07-21 08:42+0300\n"
"Last-Translator: Yuri Chornoivan <yurchor@ukr.net>\n"
"Language-Team: Ukrainian <kde-i18n-uk@kde.org>\n"
"Language: uk\n"
@ -216,89 +216,106 @@ msgid ""
"shell."
msgstr "Вмикає D-Bus API для самоаналізу стану оболонки."
#: data/org.gnome.shell.gschema.xml.in:119
#: data/org.gnome.shell.gschema.xml.in:114
msgid "Layout of the app picker"
msgstr "Компонування засобу вибору програм"
#: data/org.gnome.shell.gschema.xml.in:115
msgid ""
"Layout of the app picker. Each entry in the array is a page. Pages are "
"stored in the order they appear in GNOME Shell. Each page contains an "
"“application id” → 'data' pair. Currently, the following values are stored "
"as 'data': • “position”: the position of the application icon in the page"
msgstr ""
"Компонування засобу вибору програм. Кожен запис у цьому масиві є сторінкою."
" Сторінки зберігаються у порядку, у якому їх буде показано у GNOME Shell."
" Кожна сторінка містить пану записів “ідентифікатор програми” → 'дані'. У"
" поточній версії як 'дані' може бути збережено такі значення: • “позиція”:"
" позиція піктограми програми на сторінці"
#: data/org.gnome.shell.gschema.xml.in:130
msgid "Keybinding to open the application menu"
msgstr "Комбінація клавіш, щоб відкрити меню програм"
#: data/org.gnome.shell.gschema.xml.in:120
#: data/org.gnome.shell.gschema.xml.in:131
msgid "Keybinding to open the application menu."
msgstr "Комбінація клавіш, щоб відкрити меню програм."
#: data/org.gnome.shell.gschema.xml.in:126
#: data/org.gnome.shell.gschema.xml.in:137
msgid "Keybinding to open the “Show Applications” view"
msgstr "Комбінація клавіш, щоб «Показати програми»"
#: data/org.gnome.shell.gschema.xml.in:127
#: data/org.gnome.shell.gschema.xml.in:138
msgid ""
"Keybinding to open the “Show Applications” view of the Activities Overview."
msgstr "Комбінація клавіш, щоб «Показати програми» в огляді діяльності."
#: data/org.gnome.shell.gschema.xml.in:134
#: data/org.gnome.shell.gschema.xml.in:145
msgid "Keybinding to open the overview"
msgstr "Комбінація клавіш, щоб відкрити огляд"
#: data/org.gnome.shell.gschema.xml.in:135
#: data/org.gnome.shell.gschema.xml.in:146
msgid "Keybinding to open the Activities Overview."
msgstr "Комбінація клавіш, щоб відкрити огляд діяльності."
#: data/org.gnome.shell.gschema.xml.in:141
#: data/org.gnome.shell.gschema.xml.in:152
msgid "Keybinding to toggle the visibility of the notification list"
msgstr "Комбінація клавіш, щоб змінювати видимість переліку сповіщень"
#: data/org.gnome.shell.gschema.xml.in:142
#: data/org.gnome.shell.gschema.xml.in:153
msgid "Keybinding to toggle the visibility of the notification list."
msgstr "Комбінація клавіш, щоб змінювати видимість переліку сповіщень."
#: data/org.gnome.shell.gschema.xml.in:148
#: data/org.gnome.shell.gschema.xml.in:159
msgid "Keybinding to focus the active notification"
msgstr "Комбінація клавіш, щоб перейти до активних сповіщень"
#: data/org.gnome.shell.gschema.xml.in:149
#: data/org.gnome.shell.gschema.xml.in:160
msgid "Keybinding to focus the active notification."
msgstr "Комбінація клавіш, щоб перейти до активних сповіщень."
#: data/org.gnome.shell.gschema.xml.in:155
#: data/org.gnome.shell.gschema.xml.in:166
msgid "Switch to application 1"
msgstr "Перемкнутися на програму 1"
#: data/org.gnome.shell.gschema.xml.in:159
#: data/org.gnome.shell.gschema.xml.in:170
msgid "Switch to application 2"
msgstr "Перемкнутися на програму 2"
#: data/org.gnome.shell.gschema.xml.in:163
#: data/org.gnome.shell.gschema.xml.in:174
msgid "Switch to application 3"
msgstr "Перемкнутися на програму 3"
#: data/org.gnome.shell.gschema.xml.in:167
#: data/org.gnome.shell.gschema.xml.in:178
msgid "Switch to application 4"
msgstr "Перемкнутися на програму 4"
#: data/org.gnome.shell.gschema.xml.in:171
#: data/org.gnome.shell.gschema.xml.in:182
msgid "Switch to application 5"
msgstr "Перемкнутися на програму 5"
#: data/org.gnome.shell.gschema.xml.in:175
#: data/org.gnome.shell.gschema.xml.in:186
msgid "Switch to application 6"
msgstr "Перемкнутися на програму 6"
#: data/org.gnome.shell.gschema.xml.in:179
#: data/org.gnome.shell.gschema.xml.in:190
msgid "Switch to application 7"
msgstr "Перемкнутися на програму 7"
#: data/org.gnome.shell.gschema.xml.in:183
#: data/org.gnome.shell.gschema.xml.in:194
msgid "Switch to application 8"
msgstr "Перемкнутися на програму 8"
#: data/org.gnome.shell.gschema.xml.in:187
#: data/org.gnome.shell.gschema.xml.in:198
msgid "Switch to application 9"
msgstr "Перемкнутися на програму 9"
#: data/org.gnome.shell.gschema.xml.in:196
#: data/org.gnome.shell.gschema.xml.in:223
#: data/org.gnome.shell.gschema.xml.in:207
#: data/org.gnome.shell.gschema.xml.in:234
msgid "Limit switcher to current workspace."
msgstr "Обмежити перемикач на поточний робочий простір."
#: data/org.gnome.shell.gschema.xml.in:197
#: data/org.gnome.shell.gschema.xml.in:208
msgid ""
"If true, only applications that have windows on the current workspace are "
"shown in the switcher. Otherwise, all applications are included."
@ -306,11 +323,11 @@ msgstr ""
"Якщо це вказано, то тільки програми з поточного робочого простору будуть "
"показані в перемикачі. Інакше — програми з усіх просторів."
#: data/org.gnome.shell.gschema.xml.in:214
#: data/org.gnome.shell.gschema.xml.in:225
msgid "The application icon mode."
msgstr "Режим піктограм для програм."
#: data/org.gnome.shell.gschema.xml.in:215
#: data/org.gnome.shell.gschema.xml.in:226
msgid ""
"Configures how the windows are shown in the switcher. Valid possibilities "
"are “thumbnail-only” (shows a thumbnail of the window), “app-icon-"
@ -320,7 +337,7 @@ msgstr ""
"«thumbnail-only» (показує мініатюру вікна), «app-icon-only» (показує тільки "
"піктограми програм) або «both» (обидва)."
#: data/org.gnome.shell.gschema.xml.in:224
#: data/org.gnome.shell.gschema.xml.in:235
msgid ""
"If true, only windows from the current workspace are shown in the switcher. "
"Otherwise, all windows are included."
@ -328,57 +345,57 @@ msgstr ""
"Якщо це вказано, то тільки вікна з поточного робочого простору будуть "
"показані в перемикачі. Інакше — вікна з усіх просторів."
#: data/org.gnome.shell.gschema.xml.in:234
#: data/org.gnome.shell.gschema.xml.in:245
msgid "Locations"
msgstr "Місцевості"
#: data/org.gnome.shell.gschema.xml.in:235
#: data/org.gnome.shell.gschema.xml.in:246
msgid "The locations to show in world clocks"
msgstr "Місцевість для світового годинника"
#: data/org.gnome.shell.gschema.xml.in:245
#: data/org.gnome.shell.gschema.xml.in:256
msgid "Automatic location"
msgstr "Автоматичне визначення місцевості"
#: data/org.gnome.shell.gschema.xml.in:246
#: data/org.gnome.shell.gschema.xml.in:257
msgid "Whether to fetch the current location or not"
msgstr "Чи одержувати поточну локацію"
#: data/org.gnome.shell.gschema.xml.in:253
#: data/org.gnome.shell.gschema.xml.in:264
msgid "Location"
msgstr "Місцевість"
#: data/org.gnome.shell.gschema.xml.in:254
#: data/org.gnome.shell.gschema.xml.in:265
msgid "The location for which to show a forecast"
msgstr "Місцевість для прогнозу погоди"
#: data/org.gnome.shell.gschema.xml.in:266
#: data/org.gnome.shell.gschema.xml.in:277
msgid "Attach modal dialog to the parent window"
msgstr "Приєднати модальне вікно до батьківського вікна"
#: data/org.gnome.shell.gschema.xml.in:267
#: data/org.gnome.shell.gschema.xml.in:276
#: data/org.gnome.shell.gschema.xml.in:284
#: data/org.gnome.shell.gschema.xml.in:292
#: data/org.gnome.shell.gschema.xml.in:300
#: data/org.gnome.shell.gschema.xml.in:278
#: data/org.gnome.shell.gschema.xml.in:287
#: data/org.gnome.shell.gschema.xml.in:295
#: data/org.gnome.shell.gschema.xml.in:303
#: data/org.gnome.shell.gschema.xml.in:311
msgid ""
"This key overrides the key in org.gnome.mutter when running GNOME Shell."
msgstr ""
"Цей ключ перевизначає ключ у org.gnome.mutter, коли запущено GNOME Shell."
#: data/org.gnome.shell.gschema.xml.in:275
#: data/org.gnome.shell.gschema.xml.in:286
msgid "Enable edge tiling when dropping windows on screen edges"
msgstr "Увімкнути розбиття країв, коли кладуться вікна на краї екрана"
#: data/org.gnome.shell.gschema.xml.in:283
#: data/org.gnome.shell.gschema.xml.in:294
msgid "Workspaces are managed dynamically"
msgstr "Робочі простори організовуються динамічно"
#: data/org.gnome.shell.gschema.xml.in:291
#: data/org.gnome.shell.gschema.xml.in:302
msgid "Workspaces only on primary monitor"
msgstr "Робочий простір лише на основному моніторі"
#: data/org.gnome.shell.gschema.xml.in:299
#: data/org.gnome.shell.gschema.xml.in:310
msgid "Delay focus changes in mouse mode until the pointer stops moving"
msgstr "Затримувати зміни фокусу миші, поки вказівник не перестане рухатись"
@ -414,7 +431,7 @@ msgstr "Відвідати сторінку розширення"
#: js/gdm/authPrompt.js:135 js/ui/audioDeviceSelection.js:57
#: js/ui/components/networkAgent.js:110 js/ui/components/polkitAgent.js:139
#: js/ui/endSessionDialog.js:369 js/ui/extensionDownloader.js:181
#: js/ui/endSessionDialog.js:369 js/ui/extensionDownloader.js:183
#: js/ui/shellMountOperation.js:376 js/ui/shellMountOperation.js:386
#: js/ui/status/network.js:916 subprojects/extensions-app/js/main.js:149
msgid "Cancel"
@ -456,7 +473,7 @@ msgstr "Користувач"
msgid "Login Window"
msgstr "Вікно входу"
#: js/gdm/util.js:345
#: js/gdm/util.js:355
msgid "Authentication error"
msgstr "Помилка розпізнавання"
@ -465,7 +482,7 @@ msgstr "Помилка розпізнавання"
#. as a cue to display our own message.
#. Translators: this message is shown below the password entry field
#. to indicate the user can swipe their finger instead
#: js/gdm/util.js:471
#: js/gdm/util.js:481
msgid "(or swipe finger)"
msgstr "(або проведіть пальцем)"
@ -713,36 +730,36 @@ msgstr "Заборонити доступ"
msgid "Grant Access"
msgstr "Надати доступ"
#: js/ui/appDisplay.js:956
#: js/ui/appDisplay.js:1297
msgid "Unnamed Folder"
msgstr "Неназвана тека"
#. Translators: This is the heading of a list of open windows
#: js/ui/appDisplay.js:2215 js/ui/panel.js:75
#: js/ui/appDisplay.js:2767 js/ui/panel.js:75
msgid "Open Windows"
msgstr "Відкрити вікна"
#: js/ui/appDisplay.js:2234 js/ui/panel.js:82
#: js/ui/appDisplay.js:2786 js/ui/panel.js:82
msgid "New Window"
msgstr "Нове вікно"
#: js/ui/appDisplay.js:2250
#: js/ui/appDisplay.js:2802
msgid "Launch using Integrated Graphics Card"
msgstr "Запустити через інтегровану графічну плату"
#: js/ui/appDisplay.js:2251
#: js/ui/appDisplay.js:2803
msgid "Launch using Discrete Graphics Card"
msgstr "Запустити через дискретну графічну плату"
#: js/ui/appDisplay.js:2279 js/ui/dash.js:239
#: js/ui/appDisplay.js:2831 js/ui/dash.js:239
msgid "Remove from Favorites"
msgstr "Вилучити з улюбленого"
#: js/ui/appDisplay.js:2285
#: js/ui/appDisplay.js:2837
msgid "Add to Favorites"
msgstr "Додати до улюбленого"
#: js/ui/appDisplay.js:2295 js/ui/panel.js:93
#: js/ui/appDisplay.js:2847 js/ui/panel.js:93
msgid "Show Details"
msgstr "Показати подробиці"
@ -772,7 +789,7 @@ msgstr "Навушники"
msgid "Headset"
msgstr "Гарнітура"
#: js/ui/audioDeviceSelection.js:68 js/ui/status/volume.js:273
#: js/ui/audioDeviceSelection.js:68 js/ui/status/volume.js:272
msgid "Microphone"
msgstr "Мікрофон"
@ -1073,14 +1090,12 @@ msgstr "%A %-d %B %Y"
#. Translators: Shown on calendar heading when selected day occurs on current year
#: js/ui/dateMenu.js:151
#| msgid "%B %-d %Y"
msgctxt "calendar heading"
msgid "%B %-d"
msgstr "%-d %B"
#. Translators: Shown on calendar heading when selected day occurs on different year
#: js/ui/dateMenu.js:154
#| msgid "%B %-d %Y"
msgctxt "calendar heading"
msgid "%B %-d %Y"
msgstr "%-d %B %Y"
@ -1293,15 +1308,15 @@ msgstr "%s (віддалено)"
msgid "%s (console)"
msgstr "%s (консоль)"
#: js/ui/extensionDownloader.js:185
#: js/ui/extensionDownloader.js:187
msgid "Install"
msgstr "Встановити"
#: js/ui/extensionDownloader.js:191
#: js/ui/extensionDownloader.js:193
msgid "Install Extension"
msgstr "Встановити розширення"
#: js/ui/extensionDownloader.js:192
#: js/ui/extensionDownloader.js:194
#, javascript-format
msgid "Download and install “%s” from extensions.gnome.org?"
msgstr "Звантажити і встановити «%s» з extensions.gnome.org?"
@ -1334,11 +1349,11 @@ msgstr "Програма бажає успадкувати скорочення"
msgid "You can restore shortcuts by pressing %s."
msgstr "Можна відновити скорочення, натиснувши %s."
#: js/ui/inhibitShortcutsDialog.js:98
#: js/ui/inhibitShortcutsDialog.js:100
msgid "Deny"
msgstr "Заборонити"
#: js/ui/inhibitShortcutsDialog.js:105
#: js/ui/inhibitShortcutsDialog.js:107
msgid "Allow"
msgstr "Дозволити"
@ -1404,7 +1419,7 @@ msgstr "Вимкнути"
msgid "Leave Off"
msgstr "Покинути"
#: js/ui/keyboard.js:207
#: js/ui/keyboard.js:225
msgid "Region & Language Settings"
msgstr "Параметри регіону та мови"
@ -1477,7 +1492,7 @@ msgstr "Блокування екрана вимкнено"
msgid "Screen Locking requires the GNOME display manager."
msgstr "Блокування екрана потребує керування входом GNOME."
#: js/ui/messageTray.js:1547
#: js/ui/messageTray.js:1476
msgid "System Information"
msgstr "Інформація про систему"
@ -1489,13 +1504,13 @@ msgstr "Невідомий виконавець"
msgid "Unknown title"
msgstr "Невідома назва"
#: js/ui/overview.js:73
#: js/ui/overview.js:74
msgid "Undo"
msgstr "Повернути"
#. Translators: This is the main view to select
#. activities. See also note for "Activities" string.
#: js/ui/overview.js:86
#: js/ui/overview.js:87
msgid "Overview"
msgstr "Огляд"
@ -1503,7 +1518,7 @@ msgstr "Огляд"
#. in the search entry when no search is
#. active; it should not exceed ~30
#. characters.
#: js/ui/overview.js:107
#: js/ui/overview.js:108
msgid "Type to search"
msgstr "Введіть текст для пошуку"
@ -2162,11 +2177,11 @@ msgstr "Помилка завірення Thunderbolt"
msgid "Could not authorize the Thunderbolt device: %s"
msgstr "Неможливо завірити пристрій Thunderbolt: %s"
#: js/ui/status/volume.js:154
#: js/ui/status/volume.js:155
msgid "Volume changed"
msgstr "Гучність змінено"
#: js/ui/status/volume.js:225
#: js/ui/status/volume.js:217
msgid "Volume"
msgstr "Гучність"
@ -2212,11 +2227,11 @@ msgstr "Проведіть вгору для розблокування"
msgid "Click or press a key to unlock"
msgstr "Клацніть або натисніть клавішу для розблокування"
#: js/ui/unlockDialog.js:550
#: js/ui/unlockDialog.js:555
msgid "Unlock Window"
msgstr "Розблокувати вікно"
#: js/ui/unlockDialog.js:559
#: js/ui/unlockDialog.js:564
msgid "Log in as another user"
msgstr "Увійти як інший користувач"
@ -2353,12 +2368,12 @@ msgstr "Використовувати вказаний режим, прикла
msgid "List possible modes"
msgstr "Перелік можливих режимів"
#: src/shell-app.c:286
#: src/shell-app.c:268
msgctxt "program"
msgid "Unknown"
msgstr "Невідомо"
#: src/shell-app.c:537
#: src/shell-app.c:519
#, c-format
msgid "Failed to launch “%s”"
msgstr "Не вдалося запустити «%s»"
@ -2938,36 +2953,3 @@ msgstr[3] "%u вхід"
#: subprojects/gvc/gvc-mixer-control.c:2766
msgid "System Sounds"
msgstr "Системні звуки"
#~ msgid "Frequently used applications will appear here"
#~ msgstr "Часто використовувані програми будуть з'являтись тут"
#~ msgid "Frequent"
#~ msgstr "Частовживане"
#~ msgid "All"
#~ msgstr "Усе"
#~ msgctxt "calendar heading"
#~ msgid "%A, %B %-d"
#~ msgstr "%A, %-d %B"
#~ msgctxt "calendar heading"
#~ msgid "%A, %B %-d, %Y"
#~ msgstr "%A, %-d %B, %Y"
#~ msgid "Copy Error"
#~ msgstr "Скопіювати помилку"
#~ msgid "%d Connected"
#~ msgid_plural "%d Connected"
#~ msgstr[0] "%d під'єднано"
#~ msgstr[1] "%d під'єднано"
#~ msgstr[2] "%d під'єднано"
#~ msgstr[3] "%d під'єднано"
#~ msgid "Off"
#~ msgstr "Вимкнено"
#~ msgid "On"
#~ msgstr "Увімкнено"

View File

@ -23,8 +23,8 @@ msgid ""
msgstr ""
"Project-Id-Version: gnome-shell master\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gnome-shell/issues\n"
"POT-Creation-Date: 2020-05-28 11:29+0000\n"
"PO-Revision-Date: 2020-05-29 09:03-0400\n"
"POT-Creation-Date: 2020-07-12 02:14+0000\n"
"PO-Revision-Date: 2020-07-11 22:32-0400\n"
"Last-Translator: Boyuan Yang <073plan@gmail.com>\n"
"Language-Team: Chinese (China) <i18n-zh@googlegroups.com>\n"
"Language: zh_CN\n"
@ -444,7 +444,7 @@ msgstr "用户名"
msgid "Login Window"
msgstr "登录窗口"
#: js/gdm/util.js:345
#: js/gdm/util.js:355
msgid "Authentication error"
msgstr "认证出错"
@ -453,7 +453,7 @@ msgstr "认证出错"
#. as a cue to display our own message.
#. Translators: this message is shown below the password entry field
#. to indicate the user can swipe their finger instead
#: js/gdm/util.js:471
#: js/gdm/util.js:481
msgid "(or swipe finger)"
msgstr "(或滑动手指)"
@ -559,7 +559,7 @@ msgid "%d hour ago"
msgid_plural "%d hours ago"
msgstr[0] "%d 小时前"
#: js/misc/util.js:191
#: js/misc/util.js:191 js/ui/dateMenu.js:162
msgid "Yesterday"
msgstr "昨天"
@ -672,44 +672,44 @@ msgstr "您到热点登录的连接不安全。您在此页面输入的密码或
#. No support for non-modal system dialogs, so ignore the option
#. let modal = options['modal'] || true;
#: js/ui/accessDialog.js:39 js/ui/status/location.js:374
#: js/ui/accessDialog.js:39 js/ui/status/location.js:369
msgid "Deny Access"
msgstr "拒绝访问"
#: js/ui/accessDialog.js:40 js/ui/status/location.js:377
#: js/ui/accessDialog.js:40 js/ui/status/location.js:372
msgid "Grant Access"
msgstr "允许访问"
#: js/ui/appDisplay.js:960
#: js/ui/appDisplay.js:903
msgid "Unnamed Folder"
msgstr "未命名文件夹"
#. Translators: This is the heading of a list of open windows
#: js/ui/appDisplay.js:2219 js/ui/panel.js:75
#: js/ui/appDisplay.js:2225 js/ui/panel.js:75
msgid "Open Windows"
msgstr "打开窗口"
#: js/ui/appDisplay.js:2238 js/ui/panel.js:82
#: js/ui/appDisplay.js:2244 js/ui/panel.js:82
msgid "New Window"
msgstr "新窗口"
#: js/ui/appDisplay.js:2254
#: js/ui/appDisplay.js:2260
msgid "Launch using Integrated Graphics Card"
msgstr "使用集成显卡启动"
#: js/ui/appDisplay.js:2255
#: js/ui/appDisplay.js:2261
msgid "Launch using Discrete Graphics Card"
msgstr "使用独立显卡启动"
#: js/ui/appDisplay.js:2283 js/ui/dash.js:239
#: js/ui/appDisplay.js:2289 js/ui/dash.js:239
msgid "Remove from Favorites"
msgstr "从收藏夹中移除"
#: js/ui/appDisplay.js:2289
#: js/ui/appDisplay.js:2295
msgid "Add to Favorites"
msgstr "添加到收藏夹"
#: js/ui/appDisplay.js:2299 js/ui/panel.js:93
#: js/ui/appDisplay.js:2305 js/ui/panel.js:93
msgid "Show Details"
msgstr "显示细节"
@ -739,7 +739,7 @@ msgstr "耳机"
msgid "Headset"
msgstr "耳麦"
#: js/ui/audioDeviceSelection.js:68 js/ui/status/volume.js:273
#: js/ui/audioDeviceSelection.js:68 js/ui/status/volume.js:272
msgid "Microphone"
msgstr "麦克风"
@ -756,7 +756,7 @@ msgid "Settings"
msgstr "设置"
#. Translators: Enter 0-6 (Sunday-Saturday) for non-work days. Examples: "0" (Sunday) "6" (Saturday) "06" (Sunday and Saturday).
#: js/ui/calendar.js:41
#: js/ui/calendar.js:36
msgctxt "calendar-no-work"
msgid "06"
msgstr "06"
@ -766,43 +766,43 @@ msgstr "06"
#. * NOTE: These grid abbreviations are always shown together
#. * and in order, e.g. "S M T W T F S".
#.
#: js/ui/calendar.js:70
#: js/ui/calendar.js:65
msgctxt "grid sunday"
msgid "S"
msgstr "日"
#. Translators: Calendar grid abbreviation for Monday
#: js/ui/calendar.js:72
#: js/ui/calendar.js:67
msgctxt "grid monday"
msgid "M"
msgstr "一"
#. Translators: Calendar grid abbreviation for Tuesday
#: js/ui/calendar.js:74
#: js/ui/calendar.js:69
msgctxt "grid tuesday"
msgid "T"
msgstr "二"
#. Translators: Calendar grid abbreviation for Wednesday
#: js/ui/calendar.js:76
#: js/ui/calendar.js:71
msgctxt "grid wednesday"
msgid "W"
msgstr "三"
#. Translators: Calendar grid abbreviation for Thursday
#: js/ui/calendar.js:78
#: js/ui/calendar.js:73
msgctxt "grid thursday"
msgid "T"
msgstr "四"
#. Translators: Calendar grid abbreviation for Friday
#: js/ui/calendar.js:80
#: js/ui/calendar.js:75
msgctxt "grid friday"
msgid "F"
msgstr "五"
#. Translators: Calendar grid abbreviation for Saturday
#: js/ui/calendar.js:82
#: js/ui/calendar.js:77
msgctxt "grid saturday"
msgid "S"
msgstr "六"
@ -813,7 +813,7 @@ msgstr "六"
#. * "%OB" is the new format specifier introduced in glibc 2.27,
#. * in most cases you should not change it.
#.
#: js/ui/calendar.js:397
#: js/ui/calendar.js:392
msgid "%OB"
msgstr "%OB"
@ -826,61 +826,37 @@ msgstr "%OB"
#. * in most cases you should not use the old "%B" here unless you
#. * absolutely know what you are doing.
#.
#: js/ui/calendar.js:407
#: js/ui/calendar.js:402
msgid "%OB %Y"
msgstr "%Y %OB"
#: js/ui/calendar.js:466
#: js/ui/calendar.js:461
msgid "Previous month"
msgstr "上个月"
#: js/ui/calendar.js:481
#: js/ui/calendar.js:476
msgid "Next month"
msgstr "下个月"
#: js/ui/calendar.js:631
#: js/ui/calendar.js:626
#, no-javascript-format
msgctxt "date day number format"
msgid "%d"
msgstr "%d"
#: js/ui/calendar.js:687
#: js/ui/calendar.js:682
msgid "Week %V"
msgstr "第 %V 个星期"
#. Translators: Shown in calendar event list for all day events
#. * Keep it short, best if you can use less then 10 characters
#.
#: js/ui/calendar.js:762
msgctxt "event list time"
msgid "All Day"
msgstr "全天"
#. Translators: Shown on calendar heading when selected day occurs on current year
#: js/ui/calendar.js:900
msgctxt "calendar heading"
msgid "%A, %B %-d"
msgstr "%-m月%-d日 %A"
#. Translators: Shown on calendar heading when selected day occurs on different year
#: js/ui/calendar.js:903
msgctxt "calendar heading"
msgid "%A, %B %-d, %Y"
msgstr "%Y年%-m月%-d日 %A"
#: js/ui/calendar.js:1133
#: js/ui/calendar.js:895
msgid "No Notifications"
msgstr "无通知"
#: js/ui/calendar.js:1136
msgid "No Events"
msgstr "无事件"
#: js/ui/calendar.js:1190
#: js/ui/calendar.js:949
msgid "Do Not Disturb"
msgstr "请勿打扰"
#: js/ui/calendar.js:1209
#: js/ui/calendar.js:968
msgid "Clear"
msgstr "清除"
@ -1030,7 +1006,7 @@ msgstr "抱歉,认证失败。请重试。"
msgid "%s is now known as %s"
msgstr "%s 现在叫做 %s"
#: js/ui/ctrlAltTab.js:21 js/ui/viewSelector.js:177
#: js/ui/ctrlAltTab.js:21 js/ui/viewSelector.js:178
msgid "Windows"
msgstr "窗口"
@ -1049,7 +1025,7 @@ msgstr "Dash"
#. * "Tue 9:29 AM"). The string itself should become a full date, e.g.,
#. * "February 17 2015".
#.
#: js/ui/dateMenu.js:75
#: js/ui/dateMenu.js:79
msgid "%B %-d %Y"
msgstr "%Y年%-m月%-d日"
@ -1057,35 +1033,67 @@ msgstr "%Y年%-m月%-d日"
#. * below the time in the shell; it should combine the weekday and the
#. * date, e.g. "Tuesday February 17 2015".
#.
#: js/ui/dateMenu.js:82
#: js/ui/dateMenu.js:86
msgid "%A %B %e %Y"
msgstr "%Y年%-m月%-d日 %A"
#: js/ui/dateMenu.js:162
#. Translators: Shown on calendar heading when selected day occurs on current year
#: js/ui/dateMenu.js:151
msgctxt "calendar heading"
msgid "%B %-d"
msgstr "%-m月%-d日"
#. Translators: Shown on calendar heading when selected day occurs on different year
#: js/ui/dateMenu.js:154
msgctxt "calendar heading"
msgid "%B %-d %Y"
msgstr "%Y年%-m月%-d日"
#: js/ui/dateMenu.js:160
msgid "Today"
msgstr "今天"
#: js/ui/dateMenu.js:164
msgid "Tomorrow"
msgstr "明天"
#. Translators: Shown in calendar event list for all day events
#. * Keep it short, best if you can use less then 10 characters
#.
#: js/ui/dateMenu.js:180
msgctxt "event list time"
msgid "All Day"
msgstr "全天"
#: js/ui/dateMenu.js:231
msgid "No Events"
msgstr "无事件"
#: js/ui/dateMenu.js:348
msgid "Add world clocks…"
msgstr "添加世界时钟…"
#: js/ui/dateMenu.js:163
#: js/ui/dateMenu.js:349
msgid "World Clocks"
msgstr "世界时钟"
#: js/ui/dateMenu.js:443
#: js/ui/dateMenu.js:629
msgid "Loading…"
msgstr "正在载入……"
#: js/ui/dateMenu.js:453
#: js/ui/dateMenu.js:639
msgid "Go online for weather information"
msgstr "通过互联网查看天气信息"
#: js/ui/dateMenu.js:455
#: js/ui/dateMenu.js:641
msgid "Weather information is currently unavailable"
msgstr "天气信息目前不可用"
#: js/ui/dateMenu.js:465
#: js/ui/dateMenu.js:651
msgid "Weather"
msgstr "天气"
#: js/ui/dateMenu.js:467
#: js/ui/dateMenu.js:653
msgid "Select weather location…"
msgstr "选择天气地点…"
@ -1268,11 +1276,11 @@ msgstr "某应用程序希望禁用快捷键"
msgid "You can restore shortcuts by pressing %s."
msgstr "按 %s 以恢复快捷键。"
#: js/ui/inhibitShortcutsDialog.js:98
#: js/ui/inhibitShortcutsDialog.js:100
msgid "Deny"
msgstr "拒绝"
#: js/ui/inhibitShortcutsDialog.js:105
#: js/ui/inhibitShortcutsDialog.js:107
msgid "Allow"
msgstr "允许"
@ -1337,7 +1345,7 @@ msgstr "关闭"
msgid "Leave Off"
msgstr "保持关闭"
#: js/ui/keyboard.js:207
#: js/ui/keyboard.js:225
msgid "Region & Language Settings"
msgstr "区域与语言设置"
@ -1410,25 +1418,25 @@ msgstr "屏幕锁定已禁用"
msgid "Screen Locking requires the GNOME display manager."
msgstr "屏幕锁定需要 GNOME 显示管理器。"
#: js/ui/messageTray.js:1547
#: js/ui/messageTray.js:1476
msgid "System Information"
msgstr "系统信息"
#: js/ui/mpris.js:204
#: js/ui/mpris.js:203
msgid "Unknown artist"
msgstr "未知艺人"
#: js/ui/mpris.js:214
#: js/ui/mpris.js:213
msgid "Unknown title"
msgstr "未知标题"
#: js/ui/overview.js:73
#: js/ui/overview.js:74
msgid "Undo"
msgstr "撤消"
#. Translators: This is the main view to select
#. activities. See also note for "Activities" string.
#: js/ui/overview.js:86
#: js/ui/overview.js:87
msgid "Overview"
msgstr "概览"
@ -1436,7 +1444,7 @@ msgstr "概览"
#. in the search entry when no search is
#. active; it should not exceed ~30
#. characters.
#: js/ui/overview.js:107
#: js/ui/overview.js:108
msgid "Type to search"
msgstr "输入以搜索"
@ -1464,23 +1472,23 @@ msgstr "分配按键"
msgid "Done"
msgstr "完成"
#: js/ui/padOsd.js:745
#: js/ui/padOsd.js:732
msgid "Edit…"
msgstr "编辑…"
#: js/ui/padOsd.js:787 js/ui/padOsd.js:910
#: js/ui/padOsd.js:774 js/ui/padOsd.js:891
msgid "None"
msgstr "无"
#: js/ui/padOsd.js:863
#: js/ui/padOsd.js:845
msgid "Press a button to configure"
msgstr "按下按键以配置"
#: js/ui/padOsd.js:864
#: js/ui/padOsd.js:846
msgid "Press Esc to exit"
msgstr "按 Esc 以退出"
#: js/ui/padOsd.js:867
#: js/ui/padOsd.js:849
msgid "Press any key to exit"
msgstr "按任意键退出"
@ -1570,7 +1578,7 @@ msgstr "隐藏文本"
#: js/ui/shellEntry.js:162
msgid "Caps lock is on."
msgstr "大写锁定已开启。"
msgstr "大写锁定已开启。"
#: js/ui/shellMountOperation.js:285
msgid "Hidden Volume"
@ -1742,17 +1750,17 @@ msgstr "定位服务已禁用"
msgid "Enable"
msgstr "启用"
#: js/ui/status/location.js:355
#: js/ui/status/location.js:350
msgid "Allow location access"
msgstr "允许获取位置信息"
#. Translators: %s is an application name
#: js/ui/status/location.js:357
#: js/ui/status/location.js:352
#, javascript-format
msgid "The app %s wants to access your location"
msgstr "应用 %s 想要获取您的位置信息"
#: js/ui/status/location.js:367
#: js/ui/status/location.js:362
msgid "Location access can be changed at any time from the privacy settings."
msgstr "位置访问权限可以随时在隐私设置里更改。"
@ -2081,11 +2089,11 @@ msgstr "Thunderbolt 授权错误"
msgid "Could not authorize the Thunderbolt device: %s"
msgstr "无法授权 Thunderbolt 设备:%s"
#: js/ui/status/volume.js:154
#: js/ui/status/volume.js:155
msgid "Volume changed"
msgstr "音量已变更"
#: js/ui/status/volume.js:225
#: js/ui/status/volume.js:217
msgid "Volume"
msgstr "音量"
@ -2131,19 +2139,19 @@ msgstr "向上滑动解锁"
msgid "Click or press a key to unlock"
msgstr "单击或按键解锁"
#: js/ui/unlockDialog.js:550
#: js/ui/unlockDialog.js:555
msgid "Unlock Window"
msgstr "解锁窗口"
#: js/ui/unlockDialog.js:559
#: js/ui/unlockDialog.js:564
msgid "Log in as another user"
msgstr "以另一个用户身份登录"
#: js/ui/viewSelector.js:181
#: js/ui/viewSelector.js:182
msgid "Applications"
msgstr "应用程序"
#: js/ui/viewSelector.js:185
#: js/ui/viewSelector.js:186
msgid "Search"
msgstr "搜索"
@ -2269,12 +2277,12 @@ msgstr "使用指定模式如“gdm”用于登录屏幕"
msgid "List possible modes"
msgstr "列出可用的模式"
#: src/shell-app.c:286
#: src/shell-app.c:268
msgctxt "program"
msgid "Unknown"
msgstr "未知"
#: src/shell-app.c:537
#: src/shell-app.c:519
#, c-format
msgid "Failed to launch “%s”"
msgstr "启动“%s”失败"
@ -2504,7 +2512,7 @@ msgstr "描述"
#: subprojects/extensions-tool/src/command-create.c:443
msgid "A short description of what the extension does"
msgstr "简短描述下扩展所做的事情"
msgstr "扩展功能的简短描述"
#: subprojects/extensions-tool/src/command-create.c:446
msgid "TEMPLATE"
@ -2847,6 +2855,14 @@ msgstr[0] "%u 个输入"
msgid "System Sounds"
msgstr "系统声音"
#~ msgctxt "calendar heading"
#~ msgid "%A, %B %-d"
#~ msgstr "%-m月%-d日 %A"
#~ msgctxt "calendar heading"
#~ msgid "%A, %B %-d, %Y"
#~ msgstr "%Y年%-m月%-d日 %A"
#~ msgid "Frequently used applications will appear here"
#~ msgstr "常用的应用程序会出现在这里"

View File

@ -346,8 +346,6 @@ struct _App
GSList *notify_appointments; /* CalendarAppointment *, for EventsAdded */
GSList *notify_ids; /* gchar *, for EventsRemoved */
guint events_added_timeout_id;
guint events_removed_timeout_id;
GSList *live_views;
};
@ -370,24 +368,19 @@ app_update_timezone (App *app)
}
}
static gboolean
on_app_schedule_events_added_cb (gpointer user_data)
static void
app_notify_events_added (App *app)
{
App *app = user_data;
GVariantBuilder builder, extras_builder;
GSList *events, *link;
if (g_source_is_destroyed (g_main_current_source ()))
return FALSE;
events = g_slist_reverse (app->notify_appointments);
app->notify_appointments = NULL;
app->events_added_timeout_id = 0;
print_debug ("Emitting EventsAddedOrUpdated with %d events", g_slist_length (events));
if (!events)
return FALSE;
return;
/* The a{sv} is used as an escape hatch in case we want to provide more
* information in the future without breaking ABI
@ -428,41 +421,21 @@ on_app_schedule_events_added_cb (gpointer user_data)
g_variant_builder_clear (&builder);
g_slist_free_full (events, calendar_appointment_free);
return FALSE;
}
static void
app_schedule_events_added (App *app)
app_notify_events_removed (App *app)
{
print_debug ("Scheduling EventsAddedOrUpdated");
if (app->events_added_timeout_id == 0)
{
app->events_added_timeout_id = g_timeout_add_seconds (2,
on_app_schedule_events_added_cb,
app);
g_source_set_name_by_id (app->events_added_timeout_id, "[gnome-shell] on_app_schedule_events_added_cb");
}
}
static gboolean
on_app_schedule_events_removed_cb (gpointer user_data)
{
App *app = user_data;
GVariantBuilder builder;
GSList *ids, *link;
if (g_source_is_destroyed (g_main_current_source ()))
return FALSE;
ids = app->notify_ids;
app->notify_ids = NULL;
app->events_removed_timeout_id = 0;
print_debug ("Emitting EventsRemoved with %d ids", g_slist_length (ids));
if (!ids)
return FALSE;
return;
g_variant_builder_init (&builder, G_VARIANT_TYPE ("as"));
for (link = ids; link; link = g_slist_next (link))
@ -483,20 +456,7 @@ on_app_schedule_events_removed_cb (gpointer user_data)
g_slist_free_full (ids, g_free);
return FALSE;
}
static void
app_schedule_events_removed (App *app)
{
print_debug ("Scheduling EventsRemoved");
if (app->events_removed_timeout_id == 0)
{
app->events_removed_timeout_id = g_timeout_add_seconds (2,
on_app_schedule_events_removed_cb,
app);
g_source_set_name_by_id (app->events_removed_timeout_id, "[gnome-shell] on_app_schedule_events_removed_cb");
}
return;
}
static void
@ -546,7 +506,7 @@ app_process_added_modified_objects (App *app,
g_clear_object (&cal_client);
if (app->notify_appointments)
app_schedule_events_added (app);
app_notify_events_added (app);
}
static void
@ -610,7 +570,7 @@ on_objects_removed (ECalClientView *view,
g_clear_object (&client);
if (app->notify_ids)
app_schedule_events_removed (app);
app_notify_events_removed (app);
}
static gboolean
@ -874,9 +834,6 @@ app_free (App *app)
{
GSList *ll;
g_clear_handle_id (&app->events_added_timeout_id, g_source_remove);
g_clear_handle_id (&app->events_removed_timeout_id, g_source_remove);
for (ll = app->live_views; ll != NULL; ll = g_slist_next (ll))
{
ECalClientView *view = E_CAL_CLIENT_VIEW (ll->data);

View File

@ -163,15 +163,6 @@ libshell_private_sources = [
'shell-app-cache.c',
]
if enable_recorder
libshell_sources += ['shell-recorder.c']
libshell_public_headers += ['shell-recorder.h']
libshell_private_sources += ['shell-recorder-src.c']
libshell_private_headers += ['shell-recorder-src.h']
endif
libshell_enums = gnome.mkenums_simple('shell-enum-types',
sources: libshell_public_headers
)

View File

@ -78,6 +78,7 @@ struct _ShellApp
* want (e.g. it will be of TYPE_NORMAL from
* the way shell-window-tracker.c works).
*/
GIcon *fallback_icon;
ShellAppRunningState *running_state;
@ -180,66 +181,47 @@ window_backed_app_get_window (ShellApp *app)
return NULL;
}
static ClutterActor *
window_backed_app_get_icon (ShellApp *app,
int size)
/**
* shell_app_get_icon:
*
* Look up the icon for this application
*
* Return value: (transfer none): A #GIcon
*/
GIcon *
shell_app_get_icon (ShellApp *app)
{
MetaWindow *window = NULL;
StWidget *widget;
int scale, scaled_size;
ShellGlobal *global;
StThemeContext *context;
global = shell_global_get ();
context = st_theme_context_get_for_stage (shell_global_get_stage (global));
g_object_get (context, "scale-factor", &scale, NULL);
g_return_val_if_fail (SHELL_IS_APP (app), NULL);
scaled_size = size * scale;
if (app->info)
return g_app_info_get_icon (G_APP_INFO (app->info));
if (app->fallback_icon)
return app->fallback_icon;
/* During a state transition from running to not-running for
* window-backend apps, it's possible we get a request for the icon.
* Avoid asserting here and just return an empty image.
* Avoid asserting here and just return a fallback icon
*/
if (app->running_state != NULL)
window = window_backed_app_get_window (app);
if (window == NULL)
if (window &&
meta_window_get_client_type (window) == META_WINDOW_CLIENT_TYPE_X11)
{
ClutterActor *actor;
actor = clutter_actor_new ();
g_object_set (actor,
"opacity", 0,
"width", (float) scaled_size,
"height", (float) scaled_size,
NULL);
return actor;
}
if (meta_window_get_client_type (window) == META_WINDOW_CLIENT_TYPE_X11)
{
StWidget *texture_actor;
texture_actor =
app->fallback_icon =
st_texture_cache_bind_cairo_surface_property (st_texture_cache_get_default (),
G_OBJECT (window),
"icon",
scaled_size);
widget = g_object_new (ST_TYPE_BIN,
"child", texture_actor,
NULL);
"icon");
}
else
{
widget = g_object_new (ST_TYPE_ICON,
"icon-size", size,
"icon-name", "application-x-executable",
NULL);
app->fallback_icon = g_themed_icon_new ("application-x-executable");
}
st_widget_add_style_class_name (widget, "fallback-app-icon");
return CLUTTER_ACTOR (widget);
return app->fallback_icon;
}
/**
@ -257,16 +239,16 @@ shell_app_create_icon_texture (ShellApp *app,
GIcon *icon;
ClutterActor *ret;
if (app->info == NULL)
return window_backed_app_get_icon (app, size);
ret = st_icon_new ();
st_icon_set_icon_size (ST_ICON (ret), size);
st_icon_set_fallback_icon_name (ST_ICON (ret), "application-x-executable");
icon = g_app_info_get_icon (G_APP_INFO (app->info));
icon = shell_app_get_icon (app);
st_icon_set_gicon (ST_ICON (ret), icon);
if (shell_app_is_window_backed (app))
st_widget_add_style_class_name (ST_WIDGET (ret), "fallback-app-icon");
return ret;
}
@ -1576,6 +1558,7 @@ shell_app_dispose (GObject *object)
ShellApp *app = SHELL_APP (object);
g_clear_object (&app->info);
g_clear_object (&app->fallback_icon);
while (app->running_state)
_shell_app_remove_window (app, app->running_state->windows->data);

View File

@ -29,6 +29,7 @@ const char *shell_app_get_id (ShellApp *app);
GDesktopAppInfo *shell_app_get_app_info (ShellApp *app);
ClutterActor *shell_app_create_icon_texture (ShellApp *app, int size);
GIcon *shell_app_get_icon (ShellApp *app);
const char *shell_app_get_name (ShellApp *app);
const char *shell_app_get_description (ShellApp *app);
gboolean shell_app_is_window_backed (ShellApp *app);

View File

@ -899,8 +899,9 @@ load_gl_symbol (const char *name,
}
static void
global_stage_after_paint (ClutterStage *stage,
ShellGlobal *global)
global_stage_after_paint (ClutterStage *stage,
ClutterStageView *stage_view,
ShellGlobal *global)
{
/* At this point, we've finished all layout and painting, but haven't
* actually flushed or swapped */

View File

@ -1,425 +0,0 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
#include "config.h"
#define GST_USE_UNSTABLE_API
#include <gst/base/gstpushsrc.h>
#include "shell-recorder-src.h"
struct _ShellRecorderSrc
{
GstPushSrc parent;
GMutex mutex;
GstCaps *caps;
GMutex queue_lock;
GCond queue_cond;
GQueue *queue;
gboolean eos;
gboolean flushing;
guint memory_used;
guint memory_used_update_idle;
};
struct _ShellRecorderSrcClass
{
GstPushSrcClass parent_class;
};
enum {
PROP_0,
PROP_CAPS,
PROP_MEMORY_USED
};
#define shell_recorder_src_parent_class parent_class
G_DEFINE_TYPE(ShellRecorderSrc, shell_recorder_src, GST_TYPE_PUSH_SRC);
static void
shell_recorder_src_init (ShellRecorderSrc *src)
{
gst_base_src_set_format (GST_BASE_SRC (src), GST_FORMAT_TIME);
gst_base_src_set_live (GST_BASE_SRC (src), TRUE);
src->queue = g_queue_new ();
g_mutex_init (&src->mutex);
g_mutex_init (&src->queue_lock);
g_cond_init (&src->queue_cond);
}
static gboolean
shell_recorder_src_memory_used_update_idle (gpointer data)
{
ShellRecorderSrc *src = data;
g_mutex_lock (&src->mutex);
src->memory_used_update_idle = 0;
g_mutex_unlock (&src->mutex);
g_object_notify (G_OBJECT (src), "memory-used");
return FALSE;
}
/* The memory_used property is used to monitor buffer usage,
* so we marshal notification back to the main loop thread.
*/
static void
shell_recorder_src_update_memory_used (ShellRecorderSrc *src,
int delta)
{
g_mutex_lock (&src->mutex);
src->memory_used += delta;
if (src->memory_used_update_idle == 0)
{
src->memory_used_update_idle = g_idle_add (shell_recorder_src_memory_used_update_idle, src);
g_source_set_name_by_id (src->memory_used_update_idle, "[gnome-shell] shell_recorder_src_memory_used_update_idle");
}
g_mutex_unlock (&src->mutex);
}
/* _negotiate() is called when we have to decide on a format. We
* use the configured format */
static gboolean
shell_recorder_src_negotiate (GstBaseSrc * base_src)
{
ShellRecorderSrc *src = SHELL_RECORDER_SRC (base_src);
gboolean result;
result = gst_base_src_set_caps (base_src, src->caps);
return result;
}
static gboolean
shell_recorder_src_unlock (GstBaseSrc * base_src)
{
ShellRecorderSrc *src = SHELL_RECORDER_SRC (base_src);
g_mutex_lock (&src->queue_lock);
src->flushing = TRUE;
g_cond_signal (&src->queue_cond);
g_mutex_unlock (&src->queue_lock);
return TRUE;
}
static gboolean
shell_recorder_src_unlock_stop (GstBaseSrc * base_src)
{
ShellRecorderSrc *src = SHELL_RECORDER_SRC (base_src);
g_mutex_lock (&src->queue_lock);
src->flushing = FALSE;
g_cond_signal (&src->queue_cond);
g_mutex_unlock (&src->queue_lock);
return TRUE;
}
static gboolean
shell_recorder_src_start (GstBaseSrc * base_src)
{
ShellRecorderSrc *src = SHELL_RECORDER_SRC (base_src);
g_mutex_lock (&src->queue_lock);
src->flushing = FALSE;
src->eos = FALSE;
g_cond_signal (&src->queue_cond);
g_mutex_unlock (&src->queue_lock);
return TRUE;
}
static gboolean
shell_recorder_src_stop (GstBaseSrc * base_src)
{
ShellRecorderSrc *src = SHELL_RECORDER_SRC (base_src);
g_mutex_lock (&src->queue_lock);
src->flushing = TRUE;
src->eos = FALSE;
g_queue_foreach (src->queue, (GFunc) gst_buffer_unref, NULL);
g_queue_clear (src->queue);
g_cond_signal (&src->queue_cond);
g_mutex_unlock (&src->queue_lock);
return TRUE;
}
static gboolean
shell_recorder_src_send_event (GstElement * element, GstEvent * event)
{
ShellRecorderSrc *src = SHELL_RECORDER_SRC (element);
gboolean res;
if (GST_EVENT_TYPE (event) == GST_EVENT_EOS)
{
shell_recorder_src_close (src);
gst_event_unref (event);
res = TRUE;
}
else
{
res = GST_CALL_PARENT_WITH_DEFAULT (GST_ELEMENT_CLASS, send_event, (element,
event), FALSE);
}
return res;
}
/* The create() virtual function is responsible for returning the next buffer.
* We just pop buffers off of the queue and block if necessary.
*/
static GstFlowReturn
shell_recorder_src_create (GstPushSrc *push_src,
GstBuffer **buffer_out)
{
ShellRecorderSrc *src = SHELL_RECORDER_SRC (push_src);
GstBuffer *buffer;
g_mutex_lock (&src->queue_lock);
while (TRUE) {
/* int the flushing state we just return FLUSHING */
if (src->flushing) {
g_mutex_unlock (&src->queue_lock);
return GST_FLOW_FLUSHING;
}
buffer = g_queue_pop_head (src->queue);
/* we have a buffer, exit the loop to handle it */
if (buffer != NULL)
break;
/* no buffer, check EOS */
if (src->eos) {
g_mutex_unlock (&src->queue_lock);
return GST_FLOW_EOS;
}
/* wait for something to happen and try again */
g_cond_wait (&src->queue_cond, &src->queue_lock);
}
g_mutex_unlock (&src->queue_lock);
shell_recorder_src_update_memory_used (src,
- (int)(gst_buffer_get_size(buffer) / 1024));
*buffer_out = buffer;
return GST_FLOW_OK;
}
static void
shell_recorder_src_set_caps (ShellRecorderSrc *src,
const GstCaps *caps)
{
if (caps == src->caps)
return;
if (src->caps != NULL)
{
gst_caps_unref (src->caps);
src->caps = NULL;
}
if (caps)
{
/* The capabilities will be negotated with the downstream element
* and set on the pad when the first buffer is pushed.
*/
src->caps = gst_caps_copy (caps);
}
else
src->caps = NULL;
}
static void
shell_recorder_src_finalize (GObject *object)
{
ShellRecorderSrc *src = SHELL_RECORDER_SRC (object);
g_clear_handle_id (&src->memory_used_update_idle, g_source_remove);
shell_recorder_src_set_caps (src, NULL);
g_queue_free_full (src->queue, (GDestroyNotify) gst_buffer_unref);
g_mutex_clear (&src->mutex);
g_mutex_clear (&src->queue_lock);
g_cond_clear (&src->queue_cond);
G_OBJECT_CLASS (shell_recorder_src_parent_class)->finalize (object);
}
static void
shell_recorder_src_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
ShellRecorderSrc *src = SHELL_RECORDER_SRC (object);
switch (prop_id)
{
case PROP_CAPS:
shell_recorder_src_set_caps (src, gst_value_get_caps (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
shell_recorder_src_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
ShellRecorderSrc *src = SHELL_RECORDER_SRC (object);
switch (prop_id)
{
case PROP_CAPS:
gst_value_set_caps (value, src->caps);
break;
case PROP_MEMORY_USED:
g_mutex_lock (&src->mutex);
g_value_set_uint (value, src->memory_used);
g_mutex_unlock (&src->mutex);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
shell_recorder_src_class_init (ShellRecorderSrcClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
GstBaseSrcClass *base_src_class = GST_BASE_SRC_CLASS (klass);
GstPushSrcClass *push_src_class = GST_PUSH_SRC_CLASS (klass);
static GstStaticPadTemplate src_template =
GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC,
GST_PAD_ALWAYS,
GST_STATIC_CAPS_ANY);
object_class->finalize = shell_recorder_src_finalize;
object_class->set_property = shell_recorder_src_set_property;
object_class->get_property = shell_recorder_src_get_property;
g_object_class_install_property (object_class,
PROP_CAPS,
g_param_spec_boxed ("caps",
"Caps",
"Fixed GstCaps for the source",
GST_TYPE_CAPS,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
g_object_class_install_property (object_class,
PROP_MEMORY_USED,
g_param_spec_uint ("memory-used",
"Memory Used",
"Memory currently used by the queue (in kB)",
0, G_MAXUINT, 0,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&src_template));
gst_element_class_set_details_simple (element_class,
"ShellRecorderSrc",
"Generic/Src",
"Feed screen capture data to a pipeline",
"Owen Taylor <otaylor@redhat.com>");
element_class->send_event = shell_recorder_src_send_event;
base_src_class->negotiate = shell_recorder_src_negotiate;
base_src_class->unlock = shell_recorder_src_unlock;
base_src_class->unlock_stop = shell_recorder_src_unlock_stop;
base_src_class->start = shell_recorder_src_start;
base_src_class->stop = shell_recorder_src_stop;
push_src_class->create = shell_recorder_src_create;
}
/**
* shell_recorder_src_add_buffer:
*
* Adds a buffer to the internal queue to be pushed out at the next opportunity.
* There is no flow control, so arbitrary amounts of memory may be used by
* the buffers on the queue. The buffer contents must match the #GstCaps
* set in the :caps property.
*/
void
shell_recorder_src_add_buffer (ShellRecorderSrc *src,
GstBuffer *buffer)
{
g_return_if_fail (SHELL_IS_RECORDER_SRC (src));
g_return_if_fail (src->caps != NULL);
shell_recorder_src_update_memory_used (src,
(int)(gst_buffer_get_size(buffer) / 1024));
g_mutex_lock (&src->queue_lock);
g_queue_push_tail (src->queue, gst_buffer_ref (buffer));
g_cond_signal (&src->queue_cond);
g_mutex_unlock (&src->queue_lock);
}
/**
* shell_recorder_src_close:
*
* Indicates the end of the input stream. Once all previously added buffers have
* been pushed out an end-of-stream message will be sent.
*/
void
shell_recorder_src_close (ShellRecorderSrc *src)
{
/* We can't send a message to the source immediately or buffers that haven't
* been pushed yet will be discarded. Instead mark ourselves EOS, which will
* make us send an event once everything has been pushed.
*/
g_mutex_lock (&src->queue_lock);
src->eos = TRUE;
g_cond_signal (&src->queue_cond);
g_mutex_unlock (&src->queue_lock);
}
static gboolean
plugin_init (GstPlugin *plugin)
{
gst_element_register(plugin, "shellrecordersrc", GST_RANK_NONE,
SHELL_TYPE_RECORDER_SRC);
return TRUE;
}
/**
* shell_recorder_src_register:
*
* Registers a plugin holding our single element to use privately in
* this application. Can safely be called multiple times.
*/
void
shell_recorder_src_register (void)
{
static gboolean registered = FALSE;
if (registered)
return;
gst_plugin_register_static (GST_VERSION_MAJOR, GST_VERSION_MINOR,
"shellrecorder",
"Plugin for ShellRecorder",
plugin_init,
"0.1",
"LGPL",
"gnome-shell", "gnome-shell", "http://live.gnome.org/GnomeShell");
registered = TRUE;
}

View File

@ -1,40 +0,0 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
#ifndef __SHELL_RECORDER_SRC_H__
#define __SHELL_RECORDER_SRC_H__
#include <gst/gst.h>
G_BEGIN_DECLS
/**
* ShellRecorderSrc:
*
* shellrecordersrc a custom source element is pretty much like a very
* simple version of the stander GStreamer 'appsrc' element, without
* any of the provisions for seeking, generating data on demand,
* etc. In both cases, the application supplies the buffers and the
* element pushes them into the pipeline. The main reason for not using
* appsrc is that it wasn't a supported element until gstreamer 0.10.22,
* and as of 2009-03, many systems still have 0.10.21.
*/
typedef struct _ShellRecorderSrc ShellRecorderSrc;
typedef struct _ShellRecorderSrcClass ShellRecorderSrcClass;
#define SHELL_TYPE_RECORDER_SRC (shell_recorder_src_get_type ())
#define SHELL_RECORDER_SRC(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), SHELL_TYPE_RECORDER_SRC, ShellRecorderSrc))
#define SHELL_RECORDER_SRC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SHELL_TYPE_RECORDER_SRC, ShellRecorderSrcClass))
#define SHELL_IS_RECORDER_SRC(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), SHELL_TYPE_RECORDER_SRC))
#define SHELL_IS_RECORDER_SRC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SHELL_TYPE_RECORDER_SRC))
#define SHELL_RECORDER_SRC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SHELL_TYPE_RECORDER_SRC, ShellRecorderSrcClass))
GType shell_recorder_src_get_type (void) G_GNUC_CONST;
void shell_recorder_src_register (void);
void shell_recorder_src_add_buffer (ShellRecorderSrc *src,
GstBuffer *buffer);
void shell_recorder_src_close (ShellRecorderSrc *src);
G_END_DECLS
#endif /* __SHELL_RECORDER_SRC_H__ */

File diff suppressed because it is too large Load Diff

View File

@ -1,45 +0,0 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
#ifndef __SHELL_RECORDER_H__
#define __SHELL_RECORDER_H__
#include <clutter/clutter.h>
G_BEGIN_DECLS
/**
* SECTION:shell-recorder
* @short_description: Record from a #ClutterStage
*
* The #ShellRecorder object is used to make recordings ("screencasts")
* of a #ClutterStage. Recording is done via #GStreamer. The default is
* to encode as a Theora movie and write it to a file in the current
* directory named after the date, but the encoding and output can
* be configured.
*/
#define SHELL_TYPE_RECORDER (shell_recorder_get_type ())
G_DECLARE_FINAL_TYPE (ShellRecorder, shell_recorder, SHELL, RECORDER, GObject)
ShellRecorder *shell_recorder_new (ClutterStage *stage);
void shell_recorder_set_framerate (ShellRecorder *recorder,
int framerate);
void shell_recorder_set_file_template (ShellRecorder *recorder,
const char *file_template);
void shell_recorder_set_pipeline (ShellRecorder *recorder,
const char *pipeline);
void shell_recorder_set_draw_cursor (ShellRecorder *recorder,
gboolean draw_cursor);
void shell_recorder_set_area (ShellRecorder *recorder,
int x,
int y,
int width,
int height);
gboolean shell_recorder_record (ShellRecorder *recorder,
char **filename_used);
void shell_recorder_close (ShellRecorder *recorder);
void shell_recorder_pause (ShellRecorder *recorder);
gboolean shell_recorder_is_recording (ShellRecorder *recorder);
G_END_DECLS
#endif /* __SHELL_RECORDER_H__ */

View File

@ -393,8 +393,7 @@ grab_window_screenshot (ClutterActor *stage,
if (meta_window_get_client_type (window) == META_WINDOW_CLIENT_TYPE_WAYLAND)
{
float resource_scale;
if (!clutter_actor_get_resource_scale (window_actor, &resource_scale))
resource_scale = 1.0f;
resource_scale = clutter_actor_get_resource_scale (window_actor);
cairo_surface_set_device_scale (priv->image, resource_scale, resource_scale);
}

View File

@ -77,61 +77,6 @@ shell_util_set_hidden_from_pick (ClutterActor *actor,
}
}
/**
* shell_util_get_transformed_allocation:
* @actor: a #ClutterActor
* @box: (out): location to store returned box in stage coordinates
*
* This function is similar to a combination of clutter_actor_get_transformed_position(),
* and clutter_actor_get_transformed_size(), but unlike
* clutter_actor_get_transformed_size(), it always returns a transform
* of the current allocation, while clutter_actor_get_transformed_size() returns
* bad values (the transform of the requested size) if a relayout has been
* queued.
*
* This function is more convenient to use than
* clutter_actor_get_abs_allocation_vertices() if no transformation is in effect
* and also works around limitations in the GJS binding of arrays.
*/
void
shell_util_get_transformed_allocation (ClutterActor *actor,
ClutterActorBox *box)
{
/* Code adapted from clutter-actor.c:
* Copyright 2006, 2007, 2008 OpenedHand Ltd
*/
graphene_point3d_t v[4];
gfloat x_min, x_max, y_min, y_max;
guint i;
g_return_if_fail (CLUTTER_IS_ACTOR (actor));
clutter_actor_get_abs_allocation_vertices (actor, v);
x_min = x_max = v[0].x;
y_min = y_max = v[0].y;
for (i = 1; i < G_N_ELEMENTS (v); ++i)
{
if (v[i].x < x_min)
x_min = v[i].x;
if (v[i].x > x_max)
x_max = v[i].x;
if (v[i].y < y_min)
y_min = v[i].y;
if (v[i].y > y_max)
y_max = v[i].y;
}
box->x1 = x_min;
box->y1 = y_min;
box->x2 = x_max;
box->y2 = y_max;
}
/**
* shell_util_get_week_start:
*
@ -409,34 +354,6 @@ shell_util_create_pixbuf_from_data (const guchar *data,
typedef const gchar *(*ShellGLGetString) (GLenum);
static const gchar *
get_gl_vendor (void)
{
static const gchar *vendor = NULL;
if (!vendor)
{
ShellGLGetString gl_get_string;
gl_get_string = (ShellGLGetString) cogl_get_proc_address ("glGetString");
if (gl_get_string)
vendor = gl_get_string (GL_VENDOR);
}
return vendor;
}
gboolean
shell_util_need_background_refresh (void)
{
if (!clutter_check_windowing_backend (CLUTTER_WINDOWING_X11))
return FALSE;
if (g_strcmp0 (get_gl_vendor (), "NVIDIA Corporation") == 0)
return TRUE;
return FALSE;
}
static gboolean
canvas_draw_cb (ClutterContent *content,
cairo_t *cr,
@ -653,6 +570,57 @@ shell_util_get_uid (void)
return getuid ();
}
typedef struct {
GDBusConnection *connection;
gchar *command;
GCancellable *cancellable;
gulong cancel_id;
guint job_watch;
gchar *job;
} SystemdCall;
static void
shell_util_systemd_call_data_free (SystemdCall *data)
{
if (data->job_watch)
{
g_dbus_connection_signal_unsubscribe (data->connection, data->job_watch);
data->job_watch = 0;
}
if (data->cancellable)
{
g_cancellable_disconnect (data->cancellable, data->cancel_id);
g_clear_object (&data->cancellable);
data->cancel_id = 0;
}
g_clear_object (&data->connection);
g_clear_pointer (&data->job, g_free);
g_clear_pointer (&data->command, g_free);
g_free (data);
}
static void
shell_util_systemd_call_cancelled_cb (GCancellable *cancellable,
GTask *task)
{
SystemdCall *data = g_task_get_task_data (task);
/* Task has returned, but data is not yet free'ed, ignore signal. */
if (g_task_get_completed (task))
return;
/* We are still in the DBus call; it will return the error. */
if (data->job == NULL)
return;
g_task_return_error_if_cancelled (task);
g_object_unref (task);
}
static void
on_systemd_call_cb (GObject *source,
GAsyncResult *res,
@ -660,46 +628,143 @@ on_systemd_call_cb (GObject *source,
{
g_autoptr (GVariant) reply = NULL;
g_autoptr (GError) error = NULL;
const gchar *command = user_data;
GTask *task = G_TASK (user_data);
SystemdCall *data;
reply = g_dbus_connection_call_finish (G_DBUS_CONNECTION (source),
res, &error);
if (error)
g_warning ("Could not issue '%s' systemd call", command);
data = g_task_get_task_data (task);
if (error) {
g_warning ("Could not issue '%s' systemd call", data->command);
g_task_return_error (task, g_steal_pointer (&error));
g_object_unref (task);
return;
}
g_assert (data->job == NULL);
g_variant_get (reply, "(o)", &data->job);
/* And we wait for the JobRemoved notification. */
}
static gboolean
shell_util_systemd_call (const char *command,
const char *unit,
const char *mode,
GError **error)
static void
on_systemd_job_removed_cb (GDBusConnection *connection,
const gchar *sender_name,
const gchar *object_path,
const gchar *interface_name,
const gchar *signal_name,
GVariant *parameters,
gpointer user_data)
{
GTask *task = G_TASK (user_data);
SystemdCall *data;
guint32 id;
const char *path, *unit, *result;
/* Task has returned, but data is not yet free'ed, ignore signal. */
if (g_task_get_completed (task))
return;
data = g_task_get_task_data (task);
/* No job information yet, ignore. */
if (data->job == NULL)
return;
g_variant_get (parameters, "(u&o&s&s)", &id, &path, &unit, &result);
/* Is it the job we are waiting for? */
if (g_strcmp0 (path, data->job) != 0)
return;
/* Task has completed; return the result of the job */
if (g_strcmp0 (result, "done") == 0)
g_task_return_boolean (task, TRUE);
else
g_task_return_new_error (task,
G_IO_ERROR,
G_IO_ERROR_FAILED,
"Systemd job completed with status \"%s\"",
result);
g_object_unref (task);
}
static void
shell_util_systemd_call (const char *command,
const char *unit,
const char *mode,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
{
g_autoptr (GTask) task = g_task_new (NULL, cancellable, callback, user_data);
#ifdef HAVE_SYSTEMD
g_autoptr (GDBusConnection) connection = NULL;
GError *error = NULL;
SystemdCall *data;
g_autofree char *self_unit = NULL;
int res;
connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
if (connection == NULL) {
g_task_return_error (task, error);
return;
}
/* We look up the systemd unit that our own process is running in here.
* This way we determine whether the session is managed using systemd.
*/
res = sd_pid_get_user_unit (getpid (), &self_unit);
if (res == -ENODATA)
{
g_debug ("Not systemd-managed, not doing '%s' on '%s'", mode, unit);
return FALSE;
g_task_return_new_error (task,
G_IO_ERROR,
G_IO_ERROR_NOT_SUPPORTED,
"Not systemd managed");
return;
}
else if (res < 0)
{
g_set_error (error,
G_IO_ERROR,
g_io_error_from_errno (-res),
"Error trying to start systemd unit '%s': %s",
unit, g_strerror (-res));
return FALSE;
g_task_return_new_error (task,
G_IO_ERROR,
g_io_error_from_errno (-res),
"Error fetching own systemd unit: %s",
g_strerror (-res));
return;
}
connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, error);
data = g_new0 (SystemdCall, 1);
data->command = g_strdup (command);
data->connection = g_object_ref (connection);
data->job_watch = g_dbus_connection_signal_subscribe (connection,
"org.freedesktop.systemd1",
"org.freedesktop.systemd1.Manager",
"JobRemoved",
"/org/freedesktop/systemd1",
NULL,
G_DBUS_SIGNAL_FLAGS_NONE,
on_systemd_job_removed_cb,
task,
NULL);
g_task_set_task_data (task,
data,
(GDestroyNotify) shell_util_systemd_call_data_free);
if (connection == NULL)
return FALSE;
if (cancellable)
{
data->cancellable = g_object_ref (cancellable);
data->cancel_id = g_cancellable_connect (cancellable,
G_CALLBACK (shell_util_systemd_call_cancelled_cb),
task,
NULL);
}
g_dbus_connection_call (connection,
"org.freedesktop.systemd1",
@ -708,31 +773,53 @@ shell_util_systemd_call (const char *command,
command,
g_variant_new ("(ss)",
unit, mode),
NULL,
G_VARIANT_TYPE ("(o)"),
G_DBUS_CALL_FLAGS_NONE,
-1, NULL,
-1, cancellable,
on_systemd_call_cb,
(gpointer) command);
return TRUE;
#endif /* HAVE_SYSTEMD */
g_steal_pointer (&task));
#else /* HAVE_SYSTEMD */
g_task_return_new_error (task,
G_IO_ERROR,
G_IO_ERROR_NOT_SUPPORTED,
"systemd not supported by gnome-shell");
#endif /* !HAVE_SYSTEMD */
}
return FALSE;
void
shell_util_start_systemd_unit (const char *unit,
const char *mode,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
{
shell_util_systemd_call ("StartUnit", unit, mode,
cancellable, callback, user_data);
}
gboolean
shell_util_start_systemd_unit (const char *unit,
const char *mode,
GError **error)
shell_util_start_systemd_unit_finish (GAsyncResult *res,
GError **error)
{
return shell_util_systemd_call ("StartUnit", unit, mode, error);
return g_task_propagate_boolean (G_TASK (res), error);
}
void
shell_util_stop_systemd_unit (const char *unit,
const char *mode,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
{
shell_util_systemd_call ("StopUnit", unit, mode,
cancellable, callback, user_data);
}
gboolean
shell_util_stop_systemd_unit (const char *unit,
const char *mode,
GError **error)
shell_util_stop_systemd_unit_finish (GAsyncResult *res,
GError **error)
{
return shell_util_systemd_call ("StopUnit", unit, mode, error);
return g_task_propagate_boolean (G_TASK (res), error);
}
void

View File

@ -14,9 +14,6 @@ G_BEGIN_DECLS
void shell_util_set_hidden_from_pick (ClutterActor *actor,
gboolean hidden);
void shell_util_get_transformed_allocation (ClutterActor *actor,
ClutterActorBox *box);
int shell_util_get_week_start (void);
const char *shell_util_translate_time_string (const char *str);
@ -49,8 +46,6 @@ GdkPixbuf *shell_util_create_pixbuf_from_data (const guchar *data,
int height,
int rowstride);
gboolean shell_util_need_background_refresh (void);
ClutterContent * shell_util_get_content_for_window_actor (MetaWindowActor *window_actor,
MetaRectangle *window_rect);
@ -64,12 +59,21 @@ cairo_surface_t * shell_util_composite_capture_images (ClutterCapture *captures
void shell_util_check_cloexec_fds (void);
gboolean shell_util_start_systemd_unit (const char *unit,
const char *mode,
GError **error);
gboolean shell_util_stop_systemd_unit (const char *unit,
const char *mode,
GError **error);
void shell_util_start_systemd_unit (const char *unit,
const char *mode,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
gboolean shell_util_start_systemd_unit_finish (GAsyncResult *res,
GError **error);
void shell_util_stop_systemd_unit (const char *unit,
const char *mode,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
gboolean shell_util_stop_systemd_unit_finish (GAsyncResult *res,
GError **error);
void shell_util_sd_notify (void);

View File

@ -119,6 +119,16 @@ shell_window_tracker_class_init (ShellWindowTrackerClass *klass)
G_TYPE_NONE, 0);
}
static gboolean
check_app_id_prefix (ShellApp *app,
const char *prefix)
{
if (prefix == NULL)
return TRUE;
return g_str_has_prefix (shell_app_get_id (app), prefix);
}
/*
* get_app_from_window_wmclass:
*
@ -135,9 +145,15 @@ get_app_from_window_wmclass (MetaWindow *window)
ShellAppSystem *appsys;
const char *wm_class;
const char *wm_instance;
const char *sandbox_id;
g_autofree char *app_prefix = NULL;
appsys = shell_app_system_get_default ();
sandbox_id = meta_window_get_sandboxed_app_id (window);
if (sandbox_id)
app_prefix = g_strdup_printf ("%s.", sandbox_id);
/* Notes on the heuristics used here:
much of the complexity here comes from the desire to support
Chrome apps.
@ -176,23 +192,23 @@ get_app_from_window_wmclass (MetaWindow *window)
/* first try a match from WM_CLASS (instance part) to StartupWMClass */
wm_instance = meta_window_get_wm_class_instance (window);
app = shell_app_system_lookup_startup_wmclass (appsys, wm_instance);
if (app != NULL)
if (app != NULL && check_app_id_prefix (app, app_prefix))
return g_object_ref (app);
/* then try a match from WM_CLASS to StartupWMClass */
wm_class = meta_window_get_wm_class (window);
app = shell_app_system_lookup_startup_wmclass (appsys, wm_class);
if (app != NULL)
if (app != NULL && check_app_id_prefix (app, app_prefix))
return g_object_ref (app);
/* then try a match from WM_CLASS (instance part) to .desktop */
app = shell_app_system_lookup_desktop_wmclass (appsys, wm_instance);
if (app != NULL)
if (app != NULL && check_app_id_prefix (app, app_prefix))
return g_object_ref (app);
/* finally, try a match from WM_CLASS to .desktop */
app = shell_app_system_lookup_desktop_wmclass (appsys, wm_class);
if (app != NULL)
if (app != NULL && check_app_id_prefix (app, app_prefix))
return g_object_ref (app);
return NULL;
@ -214,7 +230,7 @@ get_app_from_id (MetaWindow *window,
{
ShellApp *app;
ShellAppSystem *appsys;
char *desktop_file;
g_autofree char *desktop_file = NULL;
g_return_val_if_fail (id != NULL, NULL);
@ -223,10 +239,9 @@ get_app_from_id (MetaWindow *window,
desktop_file = g_strconcat (id, ".desktop", NULL);
app = shell_app_system_lookup_app (appsys, desktop_file);
if (app)
g_object_ref (app);
return g_object_ref (app);
g_free (desktop_file);
return app;
return NULL;
}
/*
@ -391,6 +406,13 @@ get_app_for_window (ShellWindowTracker *tracker,
if (meta_window_is_remote (window))
return _shell_app_new_for_window (window);
/* Check if the app's WM_CLASS specifies an app; this is
* canonical if it does.
*/
result = get_app_from_window_wmclass (window);
if (result != NULL)
return result;
/* Check if the window was opened from within a sandbox; if this
* is the case, a corresponding .desktop file is guaranteed to match;
*/
@ -405,13 +427,6 @@ get_app_for_window (ShellWindowTracker *tracker,
if (result != NULL)
return result;
/* Check if the app's WM_CLASS specifies an app; this is
* canonical if it does.
*/
result = get_app_from_window_wmclass (window);
if (result != NULL)
return result;
result = get_app_from_window_pid (tracker, window);
if (result != NULL)
return result;

View File

@ -41,6 +41,8 @@ typedef struct _StAdjustmentPrivate StAdjustmentPrivate;
struct _StAdjustmentPrivate
{
ClutterActor *actor;
/* Do not sanity-check values while constructing,
* not all properties may be set yet. */
guint is_constructing : 1;
@ -66,6 +68,7 @@ enum
{
PROP_0,
PROP_ACTOR,
PROP_LOWER,
PROP_UPPER,
PROP_VALUE,
@ -106,9 +109,21 @@ static gboolean st_adjustment_set_page_increment (StAdjustment *adjustment,
static gboolean st_adjustment_set_page_size (StAdjustment *adjustment,
gdouble size);
static ClutterActor *
st_adjustment_get_actor (ClutterAnimatable *animatable)
{
StAdjustment *adjustment = ST_ADJUSTMENT (animatable);
StAdjustmentPrivate *priv = st_adjustment_get_instance_private (adjustment);
g_warn_if_fail (priv->actor);
return priv->actor;
}
static void
animatable_iface_init (ClutterAnimatableInterface *iface)
{
iface->get_actor = st_adjustment_get_actor;
}
static void
@ -141,6 +156,10 @@ st_adjustment_get_property (GObject *gobject,
switch (prop_id)
{
case PROP_ACTOR:
g_value_set_object (value, priv->actor);
break;
case PROP_LOWER:
g_value_set_double (value, priv->lower);
break;
@ -171,6 +190,18 @@ st_adjustment_get_property (GObject *gobject,
}
}
static void
actor_destroyed (gpointer user_data,
GObject *where_the_object_was)
{
StAdjustment *adj = ST_ADJUSTMENT (user_data);
StAdjustmentPrivate *priv = st_adjustment_get_instance_private (adj);
priv->actor = NULL;
g_object_notify_by_pspec (G_OBJECT (adj), props[PROP_ACTOR]);
}
static void
st_adjustment_set_property (GObject *gobject,
guint prop_id,
@ -178,9 +209,20 @@ st_adjustment_set_property (GObject *gobject,
GParamSpec *pspec)
{
StAdjustment *adj = ST_ADJUSTMENT (gobject);
StAdjustmentPrivate *priv;
priv = st_adjustment_get_instance_private (ST_ADJUSTMENT (gobject));
switch (prop_id)
{
case PROP_ACTOR:
if (priv->actor)
g_object_weak_unref (G_OBJECT (priv->actor), actor_destroyed, adj);
priv->actor = g_value_get_object (value);
if (priv->actor)
g_object_weak_ref (G_OBJECT (priv->actor), actor_destroyed, adj);
break;
case PROP_LOWER:
st_adjustment_set_lower (adj, g_value_get_double (value));
break;
@ -217,6 +259,11 @@ st_adjustment_dispose (GObject *object)
StAdjustmentPrivate *priv;
priv = st_adjustment_get_instance_private (ST_ADJUSTMENT (object));
if (priv->actor)
{
g_object_weak_unref (G_OBJECT (priv->actor), actor_destroyed, object);
priv->actor = NULL;
}
g_clear_pointer (&priv->transitions, g_hash_table_unref);
G_OBJECT_CLASS (st_adjustment_parent_class)->dispose (object);
@ -232,6 +279,11 @@ st_adjustment_class_init (StAdjustmentClass *klass)
object_class->set_property = st_adjustment_set_property;
object_class->dispose = st_adjustment_dispose;
props[PROP_ACTOR] =
g_param_spec_object ("actor", "Actor", "Actor",
CLUTTER_TYPE_ACTOR,
ST_PARAM_READWRITE);
props[PROP_LOWER] =
g_param_spec_double ("lower", "Lower", "Lower bound",
-G_MAXDOUBLE, G_MAXDOUBLE, 0.0,
@ -299,7 +351,8 @@ st_adjustment_init (StAdjustment *self)
}
StAdjustment *
st_adjustment_new (gdouble value,
st_adjustment_new (ClutterActor *actor,
gdouble value,
gdouble lower,
gdouble upper,
gdouble step_increment,
@ -307,6 +360,7 @@ st_adjustment_new (gdouble value,
gdouble page_size)
{
return g_object_new (ST_TYPE_ADJUSTMENT,
"actor", actor,
"value", value,
"lower", lower,
"upper", upper,

View File

@ -48,7 +48,8 @@ struct _StAdjustmentClass
void (* changed) (StAdjustment *adjustment);
};
StAdjustment *st_adjustment_new (gdouble value,
StAdjustment *st_adjustment_new (ClutterActor *actor,
gdouble value,
gdouble lower,
gdouble upper,
gdouble step_increment,

View File

@ -85,12 +85,7 @@ st_drawing_area_allocate (ClutterActor *self,
int width, height;
float resource_scale;
if (!st_widget_get_resource_scale (ST_WIDGET (self), &resource_scale))
{
ClutterActorBox empty = CLUTTER_ACTOR_BOX_INIT_ZERO;
clutter_actor_set_allocation (self, &empty);
return;
}
resource_scale = clutter_actor_get_resource_scale (self);
clutter_actor_set_allocation (self, box);
st_theme_node_get_content_box (theme_node, box, &content_box);
@ -111,13 +106,16 @@ st_drawing_area_style_changed (StWidget *self)
}
static void
st_drawing_area_resource_scale_changed (StWidget *self)
st_drawing_area_resource_scale_changed (ClutterActor *self)
{
float resource_scale;
ClutterContent *content = clutter_actor_get_content (CLUTTER_ACTOR (self));
ClutterContent *content = clutter_actor_get_content (self);
if (st_widget_get_resource_scale (ST_WIDGET (self), &resource_scale))
clutter_canvas_set_scale_factor (CLUTTER_CANVAS (content), resource_scale);
resource_scale = clutter_actor_get_resource_scale (self);
clutter_canvas_set_scale_factor (CLUTTER_CANVAS (content), resource_scale);
if (CLUTTER_ACTOR_CLASS (st_drawing_area_parent_class)->resource_scale_changed)
CLUTTER_ACTOR_CLASS (st_drawing_area_parent_class)->resource_scale_changed (self);
}
static void
@ -128,7 +126,7 @@ st_drawing_area_class_init (StDrawingAreaClass *klass)
actor_class->allocate = st_drawing_area_allocate;
widget_class->style_changed = st_drawing_area_style_changed;
widget_class->resource_scale_changed = st_drawing_area_resource_scale_changed;
actor_class->resource_scale_changed = st_drawing_area_resource_scale_changed;
st_drawing_area_signals[REPAINT] =
g_signal_new ("repaint",
@ -215,15 +213,10 @@ st_drawing_area_get_surface_size (StDrawingArea *area,
content = clutter_actor_get_content (CLUTTER_ACTOR (area));
clutter_content_get_preferred_size (content, &w, &h);
if (st_widget_get_resource_scale (ST_WIDGET (area), &resource_scale))
{
w /= resource_scale;
h /= resource_scale;
}
else
{
w = h = 0.0f;
}
resource_scale = clutter_actor_get_resource_scale (CLUTTER_ACTOR (area));
w /= resource_scale;
h /= resource_scale;
if (width)
*width = ceilf (w);

View File

@ -231,9 +231,12 @@ st_icon_style_changed (StWidget *widget)
}
static void
st_icon_resource_scale_changed (StWidget *widget)
st_icon_resource_scale_changed (ClutterActor *actor)
{
st_icon_update (ST_ICON (widget));
st_icon_update (ST_ICON (actor));
if (CLUTTER_ACTOR_CLASS (st_icon_parent_class)->resource_scale_changed)
CLUTTER_ACTOR_CLASS (st_icon_parent_class)->resource_scale_changed (actor);
}
static void
@ -250,7 +253,7 @@ st_icon_class_init (StIconClass *klass)
actor_class->paint = st_icon_paint;
widget_class->style_changed = st_icon_style_changed;
widget_class->resource_scale_changed = st_icon_resource_scale_changed;
actor_class->resource_scale_changed = st_icon_resource_scale_changed;
props[PROP_GICON] =
g_param_spec_object ("gicon",
@ -425,8 +428,7 @@ st_icon_update (StIcon *icon)
return;
}
if (!st_widget_get_resource_scale (ST_WIDGET (icon), &resource_scale))
return;
resource_scale = clutter_actor_get_resource_scale (CLUTTER_ACTOR (icon));
theme_node = st_widget_peek_theme_node (ST_WIDGET (icon));
if (theme_node == NULL)

View File

@ -42,11 +42,17 @@ enum
};
static void clutter_content_interface_init (ClutterContentInterface *iface);
static void g_icon_interface_init (GIconIface *iface);
static void g_loadable_icon_interface_init (GLoadableIconIface *iface);
G_DEFINE_TYPE_WITH_CODE (StImageContent, st_image_content, CLUTTER_TYPE_IMAGE,
G_ADD_PRIVATE (StImageContent)
G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_CONTENT,
clutter_content_interface_init))
clutter_content_interface_init)
G_IMPLEMENT_INTERFACE (G_TYPE_ICON,
g_icon_interface_init)
G_IMPLEMENT_INTERFACE (G_TYPE_LOADABLE_ICON,
g_loadable_icon_interface_init))
static void
st_image_content_init (StImageContent *self)
@ -165,12 +171,157 @@ st_image_content_get_preferred_size (ClutterContent *content,
return TRUE;
}
static GdkPixbuf*
pixbuf_from_image (StImageContent *image)
{
CoglTexture *texture;
int width, height, rowstride;
uint8_t *data;
texture = clutter_image_get_texture (CLUTTER_IMAGE (image));
if (!texture || !cogl_texture_is_get_data_supported (texture))
return NULL;
width = cogl_texture_get_width (texture);
height = cogl_texture_get_width (texture);
rowstride = 4 * width;
data = g_new (uint8_t, rowstride * height);
cogl_texture_get_data (texture, COGL_PIXEL_FORMAT_RGBA_8888, rowstride, data);
return gdk_pixbuf_new_from_data ((const guchar *)data,
GDK_COLORSPACE_RGB,
TRUE, 8, width, height, rowstride,
(GdkPixbufDestroyNotify)g_free, NULL);
}
static void
clutter_content_interface_init (ClutterContentInterface *iface)
{
iface->get_preferred_size = st_image_content_get_preferred_size;
}
static guint
st_image_content_hash (GIcon *icon)
{
return g_direct_hash (icon);
}
static gboolean
st_image_content_equal (GIcon *icon1,
GIcon *icon2)
{
return g_direct_equal (icon1, icon2);
}
static GVariant *
st_image_content_serialize (GIcon *icon)
{
g_autoptr (GdkPixbuf) pixbuf = NULL;
pixbuf = pixbuf_from_image (ST_IMAGE_CONTENT (icon));
if (!pixbuf)
return NULL;
return g_icon_serialize (G_ICON (pixbuf));
}
static void
g_icon_interface_init (GIconIface *iface)
{
iface->hash = st_image_content_hash;
iface->equal = st_image_content_equal;
iface->serialize = st_image_content_serialize;
}
static GInputStream *
st_image_load (GLoadableIcon *icon,
int size,
char **type,
GCancellable *cancellable,
GError **error)
{
g_autoptr (GdkPixbuf) pixbuf = NULL;
pixbuf = pixbuf_from_image (ST_IMAGE_CONTENT (icon));
if (!pixbuf)
{
g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
"Failed to read texture");
return NULL;
}
return g_loadable_icon_load (G_LOADABLE_ICON (pixbuf),
size, type, cancellable, error);
}
static void
load_image_thread (GTask *task,
gpointer object,
gpointer task_data,
GCancellable *cancellable)
{
GInputStream *stream;
GError *error = NULL;
char *type;
stream = st_image_load (G_LOADABLE_ICON (object),
GPOINTER_TO_INT (task_data),
&type,
cancellable,
&error);
if (error)
{
g_task_return_error (task, error);
}
else
{
g_task_set_task_data (task, type, g_free);
g_task_return_pointer (task, stream, g_object_unref);
}
}
static void
st_image_load_async (GLoadableIcon *icon,
int size,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
{
g_autoptr (GTask) task = NULL;
task = g_task_new (icon, cancellable, callback, user_data);
g_task_set_task_data (task, GINT_TO_POINTER (size), NULL);
g_task_run_in_thread (task, load_image_thread);
}
static GInputStream *
st_image_load_finish (GLoadableIcon *icon,
GAsyncResult *res,
char **type,
GError **error)
{
GInputStream *stream;
stream = g_task_propagate_pointer (G_TASK (res), error);
if (!stream)
return NULL;
if (type)
*type = g_strdup (g_task_get_task_data (G_TASK (res)));
return stream;
}
static void
g_loadable_icon_interface_init (GLoadableIconIface *iface)
{
iface->load = st_image_load;
iface->load_async = st_image_load_async;
iface->load_finish = st_image_load_finish;
}
/**
* st_image_content_new_with_preferred_size:
* @width: The preferred width to be used when drawing the content

View File

@ -201,44 +201,42 @@ st_label_paint (ClutterActor *actor,
if (shadow_spec)
{
ClutterActorBox allocation;
float width, height;
float resource_scale;
if (clutter_actor_get_resource_scale (priv->label, &resource_scale))
clutter_actor_get_allocation_box (priv->label, &allocation);
clutter_actor_box_get_size (&allocation, &width, &height);
resource_scale = clutter_actor_get_resource_scale (priv->label);
width *= resource_scale;
height *= resource_scale;
if (priv->text_shadow_pipeline == NULL ||
width != priv->shadow_width ||
height != priv->shadow_height)
{
ClutterActorBox allocation;
float width, height;
g_clear_pointer (&priv->text_shadow_pipeline, cogl_object_unref);
clutter_actor_get_allocation_box (priv->label, &allocation);
clutter_actor_box_get_size (&allocation, &width, &height);
priv->shadow_width = width;
priv->shadow_height = height;
priv->text_shadow_pipeline =
_st_create_shadow_pipeline_from_actor (shadow_spec,
priv->label);
}
width *= resource_scale;
height *= resource_scale;
if (priv->text_shadow_pipeline != NULL)
{
CoglFramebuffer *framebuffer;
if (priv->text_shadow_pipeline == NULL ||
width != priv->shadow_width ||
height != priv->shadow_height)
{
g_clear_pointer (&priv->text_shadow_pipeline, cogl_object_unref);
priv->shadow_width = width;
priv->shadow_height = height;
priv->text_shadow_pipeline =
_st_create_shadow_pipeline_from_actor (shadow_spec,
priv->label);
}
if (priv->text_shadow_pipeline != NULL)
{
CoglFramebuffer *framebuffer;
framebuffer =
clutter_paint_context_get_framebuffer (paint_context);
_st_paint_shadow_with_opacity (shadow_spec,
framebuffer,
priv->text_shadow_pipeline,
&allocation,
clutter_actor_get_paint_opacity (priv->label));
}
framebuffer =
clutter_paint_context_get_framebuffer (paint_context);
_st_paint_shadow_with_opacity (shadow_spec,
framebuffer,
priv->text_shadow_pipeline,
&allocation,
clutter_actor_get_paint_opacity (priv->label));
}
}
@ -246,11 +244,14 @@ st_label_paint (ClutterActor *actor,
}
static void
st_label_resource_scale_changed (StWidget *widget)
st_label_resource_scale_changed (ClutterActor *actor)
{
StLabelPrivate *priv = ST_LABEL (widget)->priv;
StLabelPrivate *priv = ST_LABEL (actor)->priv;
g_clear_pointer (&priv->text_shadow_pipeline, cogl_object_unref);
if (CLUTTER_ACTOR_CLASS (st_label_parent_class)->resource_scale_changed)
CLUTTER_ACTOR_CLASS (st_label_parent_class)->resource_scale_changed (actor);
}
static void
@ -268,9 +269,9 @@ st_label_class_init (StLabelClass *klass)
actor_class->allocate = st_label_allocate;
actor_class->get_preferred_width = st_label_get_preferred_width;
actor_class->get_preferred_height = st_label_get_preferred_height;
actor_class->resource_scale_changed = st_label_resource_scale_changed;
widget_class->style_changed = st_label_style_changed;
widget_class->resource_scale_changed = st_label_resource_scale_changed;
widget_class->get_accessible_type = st_label_accessible_get_type;
props[PROP_CLUTTER_TEXT] =
@ -293,6 +294,7 @@ st_label_class_init (StLabelClass *klass)
static void
st_label_init (StLabel *label)
{
ClutterActor *actor = CLUTTER_ACTOR (label);
StLabelPrivate *priv;
label->priv = priv = st_label_get_instance_private (label);
@ -304,7 +306,10 @@ st_label_init (StLabel *label)
label->priv->shadow_width = -1.;
label->priv->shadow_height = -1.;
clutter_actor_add_child (CLUTTER_ACTOR (label), priv->label);
clutter_actor_add_child (actor, priv->label);
clutter_actor_set_offscreen_redirect (actor,
CLUTTER_OFFSCREEN_REDIRECT_ALWAYS);
}
/**

View File

@ -461,8 +461,7 @@ _st_create_shadow_pipeline_from_actor (StShadow *shadow_spec,
if (width == 0 || height == 0)
return NULL;
if (!clutter_actor_get_resource_scale (actor, &resource_scale))
return NULL;
resource_scale = clutter_actor_get_resource_scale (actor);
width = ceilf (width * resource_scale);
height = ceilf (height * resource_scale);

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