Compare commits

...

164 Commits

Author SHA1 Message Date
14cc9bfb1e Bump version to 3.29.91
Update NEWS.
2018-08-20 16:09:21 +02:00
ce4c485f34 windowManager: Ignore auto-repeat activation of toggle keybindigs
Use Meta.KeyBindingFlags.IGNORE_AUTOREPEAT for open-application-menu
and toggle-message-tray keybindings.

Fixes: https://gitlab.gnome.org/GNOME/gnome-shell/issues/373
2018-08-20 11:14:38 +00:00
1877a2e00a viewSelector: Ignore auto-repeat activation of toggle keybindigs
Use Meta.KeyBindingFlags.IGNORE_AUTOREPEAT for toggle-application-view
and toggle-application-view keybindings.

Fixes: https://gitlab.gnome.org/GNOME/gnome-shell/issues/373
2018-08-20 11:14:37 +00:00
b2fa7a6d8f Update British English translation 2018-08-19 16:42:07 +00:00
36c604d793 Update Romanian translation 2018-08-19 16:17:31 +00:00
9a5a4b2206 Revert "workspaceThumbnail: rebuild thumbnails if workareas size changed"
It is unclear what the change was supposed to be fixing, but it
broke animations of workspace additions and removals, as those
events trigger the ::workareas-changed signal.

This reverts commit c29bd46e7a.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/162
2018-08-19 12:41:08 +00:00
3ab9e9e8ad runDialog: Use ClutterText::activate for enter handling
Instead of consuming the event in front of the input method. Enter
is sometimes overriden by those, so it seems better to let the IM
handle the key event, and react later to it if it got propagated
anyway. That is what ::activate does, so use this signal.

This used to work before ClutterInputMethod/InputFocus because the
IM received the events directly from stage captured events. This
is not the case anymore.

Closes: #440
2018-08-17 18:37:32 +00:00
dd59212d3f st: Use ClutterClickAction on StEntry primary/secondary icons
This makes them work on touchscreens as well.

Closes: #116
2018-08-17 18:27:44 +00:00
2b654ec310 Update Catalan translation 2018-08-16 20:45:12 +02:00
764fbbe052 overview: Restore previous workspace switcher policy
We used to keep the workspace switcher slid out when the user made use
of workspaces. This was changed in commit 2d84975 to give more space
to window previews, but it turned out to make the switcher quite a lot
more difficult to interact with (rather than only being a question of
discoverability). So go back to the previous behavior.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/161
2018-08-14 17:34:57 +00:00
328c63bf64 overviewControls: Sync hover after drag operations
During global grabs, actors miss enter and leave events required
for correct hover tracking. This can cause the workspace switcher
to get stuck while slid out, so ensure the actor's hover state is
synced after drag operations.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/161
2018-08-14 17:34:57 +00:00
95788c9834 build: Use dedicated resources for helper programs
Using a single resource file for all JS sources saves a couple of
build system instructions, but has some serious downsides:

 - bundling the entire shell code with the tools blows
   up their size unnecessarily

 - the tools are rebuilt unnecessarily for any shell
   code change

Autotools was painful enough to let this slip, but with meson we
don't have any excuses - using the actual dependencies speeds up
the build a tiny bit and reduces the tools' sizes from over 2M
to about 50k.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/192
2018-08-14 17:28:04 +00:00
9cf571efbd build: Clean up tools' dependencies
Simply reusing the same dependencies as gnome-shell itself not only
means that we link tons of stuff unnecessarily, but also that we
have to do the whole mutter rpath dance for nothing. Just use the
dependencies those executables actually need for a nice cleanup.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/192
2018-08-14 17:28:03 +00:00
dc4128c78b build: Don't modify typelib search path in tools
We need this in the main gnome-shell executable in order to locate
the private Shell and St typelibs, but those aren't useful or even
usable in the extension-prefs/portal helper tools.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/192
2018-08-14 17:28:03 +00:00
73d8c82640 layout: Mark chrome container as NO_LAYOUT
Showing and hiding children does not affect the allocation of the uiGroup
nor its other children. We can avoid full relayout/redraw in those
situations.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/197
2018-08-14 19:13:30 +02:00
2f7377b250 Fix typo in Czech translation
https://bugzilla.gnome.org/show_bug.cgi?id=796829
2018-08-13 09:52:22 +02:00
804f23b179 Update German translation 2018-08-12 12:21:06 +00:00
2be6ddc54e Update Chinese (Taiwan) translation 2018-08-12 10:18:17 +00:00
dff4f0109e Update French translation 2018-08-09 17:52:20 +00:00
2e663b2a94 Update Friulian translation 2018-08-08 04:58:52 +00:00
9f4aa6ebf2 build: Fix build with meson >= 47.0
With meson >= 47.0, building gnome-shell will fail
when --rebuild-types is used as an option for gtk-doc,
so stop using that option and bump the meson requirement.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/191
2018-08-06 14:58:51 +02:00
afe5703710 networkAgent: Fix another ByteArray => Uint8Array instance
This was missed in commit 7ca418a79a. As we are dealing with
non-\0-terminated data here, go through GBytes this time.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/189
2018-08-06 12:16:59 +00:00
02d06bb1f3 overview: Use whole stage size for cover pane
We show a cover pane on top of the overview during transitions to
prevent issues caused by clicks and mouseover events when the overview
is not ready. Right now, this pane is only being shown on the primary
monitor, which obviosly allows interactions to happen before the
animations are finished on the secondary monitors.

To fix this, use the size of the whole stage for the cover pane.
2018-08-06 10:18:28 +02:00
3a78695bd9 Update Turkish translation 2018-08-06 07:16:17 +00:00
13e8c35d36 Updated Lithuanian translation 2018-08-05 23:22:14 +03:00
3b8dfd98dd Update Polish translation 2018-08-04 19:14:44 +02:00
6b610b26f8 keyboard: Refactor code resetting IM on window drags
When a window is dragged, the OSK should get hidden. Just
do this in a nicer way.
2018-08-03 17:02:20 +02:00
81956e9b84 keyboard: defer position-changed till we have a rect
Emitting it that soon results in JS warnings, as we don't have
everything in place yet. The position-changed signal will be
emitted from other locations as soon as we have it.

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

Closes: #464
2018-08-03 13:12:20 +02:00
6b41f82346 Updated Slovenian translation 2018-08-03 11:17:49 +02:00
1fca090374 tools: fix XDG desktop syntax in gnome-shell-overrides-migration
Reported by desktop-file-validate:
error: value "True" for boolean key "NoDisplay" in group "Desktop
Entry" contains invalid characters, boolean values must be "false" or
"true"
2018-08-03 00:49:49 +02:00
da2fc2c9d3 workspace: Simplify detecting added dialogs after closing a window
When trying to close a window in the overview by clicking the close
button and the window doesn't get closed but a dialog is added to the
window afterwards, we close the overview and show the dialog.

Instead of adding a separate listener for the window-added signal to the
WindowOverlay, let the WindowClones remember that the close button was
pressed and activate themselves if a dialog is added after that.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/180
2018-08-03 00:09:02 +02:00
52cbc299a7 workspace: Fix infinite loop when finding parent window of dialogs
When a dialog is added to a window while the overview is shown, we get
its parent using get_transient_for() so we can add it to the right
window clone.

If we have multiple layers of dialogs we have to do this recursively
until we find the root ancestor. This case currently results in an
infinite loop: Since parent is always set to the same window, the
while-condition will always be true.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/180
2018-08-03 00:09:02 +02:00
9f436ce373 data: Fix comment in schema 2018-08-01 20:04:53 +02:00
d908940ef3 showOSD: Fix handling of defined 'falsy' parameters
For the OSD, all parameters except for the icon are optional - if the
caller doesn't include the 'label' option, the OSD won't show a label
etc.

While this makes sense for an API, it means that we have to be careful
to correctly differentiate an option that was omitted and an option
that has a 'falsy' value like false or 0.

Unfortunately since commit ccaae5d3c we no longer do, with the result
that OSDs meant for the first monitor will show up on all, and a level
of 0 is presented as no level bar instead of an empty one, whoops.

https://bugzilla.gnome.org/show_bug.cgi?id=791669
2018-08-01 13:58:23 +02:00
eeda54f24d Update Brazilian Portuguese translation 2018-08-01 10:15:51 +00:00
b8b5da1e95 Bump version to 3.29.90
Update NEWS.
2018-08-01 03:43:50 +02:00
3a9ad5c577 Update POTFILES.in 2018-07-31 23:55:20 +02:00
d57dc94d9e tools: Migrate changed overrides settings
While the new per-desktop overrides in GIO are easier to use for
both developers and users, it is still inconvenient for everyone
who changed the defaults using the old overrides hack to lose
their settings. Address this by running a small script on startup
that migrates existing settings.

https://bugzilla.gnome.org/show_bug.cgi?id=786496
2018-07-31 18:36:26 +00:00
393d7246cc Replace custom override schema with per-desktop override
GSettings now recognizes per-desktop overrides that can be used
to change schemas' default values for a particular desktop. This
is not entirely unlike our existing custom override mechanism in
mutter, except that it is not limited to keys in org.gnome.mutter,
and it doesn't require a separate schema - the latter means that
we (and gnome-teak-tool) no longer have to figure out the correct
schema for the current login session and just use the original one.

https://bugzilla.gnome.org/show_bug.cgi?id=786496
2018-07-31 18:36:26 +00:00
6217c3b88d volume: Show overamplified icon when in overdrive
Show an overamplified volume icon if volume is louder the max normalized one.
Use a similar logic as gnome-settings-daemon to delimit values, restricted
to output.
The purpose is to help users remember that visiting some websites or
using some apps can get LOUD.

https://bugzilla.gnome.org/show_bug.cgi?id=790280.
2018-07-31 18:14:15 +00:00
ddd4fd9c24 barLevel: Add "overdrive" capability
Implement for barLevel an overdrive area. This is a zone represented via a
different styling to indicate that you are bypassing the normal zone of
a given level, without reaching yet the maximum limit.

https://bugzilla.gnome.org/show_bug.cgi?id=790280.
2018-07-31 18:14:14 +00:00
d2a97e7f1d volume: Allow volume above 100%
Depending on hardware and recorded volume level, turning up the speakers
to the maximum volume may not be enough and the user will want to amplify
the volume above 100%. Currently this requires opening the sound Settings
panel which gets cumbersome when required repeatedly.

To support this case better, allow raising the sound volume above 100%
directly from the system menu if the feature is enabled via the
`allow-volume-above-100-percent` key in `org.gnome.desktop.sound`.
2018-07-31 18:14:13 +00:00
aa75e89216 osdWindow: Allow levels above 100%
Allow osd representing levels that can be more than 100% by accepting
an optional parameter setting that maximum level.
gnome-settings-daemon will use this to indicate volume levels above 100%,
which our own volume indicator will soon support as well.
2018-07-31 18:14:11 +00:00
3f756dc608 barLevel: Support maxValue higher than 1
Ensure that both barLevel and slider can support a higher maxValue than 1
and computes various positions based on it.
It defaults to 1 if not set.

https://bugzilla.gnome.org/show_bug.cgi?id=790280.
2018-07-31 18:14:10 +00:00
ed8e89bc19 osdWindow: Reuse BarLevel drawing functionality
Reuse the BarLevel class to get similar drawing behavior as Slider.
Rename theme css impacted properties and ensure that the osdWindow
remains accessible.
Ensure we don't force setting a custom border color like on the OSD.

https://bugzilla.gnome.org/show_bug.cgi?id=790280.
2018-07-31 18:14:10 +00:00
c90a4e4849 levelBar: Factor out bar drawing
Split drawing logic from Slider to BarLevel subclass.
This changes part of the theme css from -slider- to -barlevel-.

https://bugzilla.gnome.org/show_bug.cgi?id=790280.
2018-07-31 18:14:09 +00:00
f433b12d6e system: Don't execute Settings
In a9ad91c831, a bug was introduced in the following code:

```c
            this._settingsAction.connect('clicked',
                                         this._onSettingsClicked().bind(this));
```

Notice that the callback is being executed! This commit
fixes that by removing the '()' from the callback.
2018-07-31 13:31:59 -03:00
7ca418a79a Explicitly convert raw data to strings
As strings are guaranteed to use UTF-8 in the GNOME platform, generic
file APIs like g_file_load_contents() return raw data instead. Since
gjs' recent update to mozjs60, this data is now returns as Uint8Array
which cannot simply be treated as string - its toString() method boils
down to arr.join(',') - so use gjs' new ByteArray module to explicitly
convert the data.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/179
2018-07-31 16:28:53 +00:00
a9ad91c831 system: Pick up Settings name and icon from app
The settings action button in the system menu simply launches
gnome-control-center, so we want its icon (and accessible name)
to always match the app. So instead of keeping the button in-sync
with Settings, just look up that information from the app itself.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/433
2018-07-31 16:52:47 +02:00
bd1c7774ee system: Enforce symbolic icons in action buttons
We can simply request the symbolic variant from CSS so that we don't
have to append '-symbolic' to all the names. This will always make
it easier to pick up that information from external sources (like
.desktop files).

https://gitlab.gnome.org/GNOME/gnome-shell/issues/433
2018-07-31 16:52:47 +02:00
91da3789bc windowManager: Fix switch animation between non-adjacent workspaces
Commit e5c95b910d refactored the workspace animation to also handle
animations that involve all surrounding workspaces, but due to an
ill-advised review comment (guess whose) it broke the animation
for non-neighboring workspaces.

Update the code to handle correctly whether in a given direction:
 - we have the target workspace of a given index
 - we have a neighboring workspace
 - we don't need to animate anything

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/182
2018-07-31 06:51:35 +02:00
2991f9f102 util: Fix code style
The C code introduced in 49d8ff38e did not follow
GNOME Shell's C code style. This commit adjusts it
to comply with the correct code style.
2018-07-30 21:23:28 -03:00
49d8ff38e7 Add check_cloexec_fds debug command
Add a debug command (to be executed manually via Alt+F2) to check
that all of gnome-shell's file descriptors have the CLOEXEC flag set.
This is important so that internal file descriptors do not get passed
to apps when they are launched.

It prints a warning message for every fd that does not have the flag set.

fdwalk() is used from the standard library if available (it is not
available in glibc), otherwise we use the same implementation as glib
has internally.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/132
2018-07-30 23:11:41 +00:00
4b522a02c3 shell-app: remove child_setup from app launching
When the amount of free memory on the system is somewhat low, gnome-shell
will sometimes fail to launch apps, reporting the error:
  fork(): Cannot allocate memory

fork() is failing here because while cloning the process virtual address
space, Linux worries that the thread being forked may end up COWing the
entire address space of the parent process (gnome-shell, which is
memory-hungry), and there is not enough free memory to permit that to
happen. This check is somewhat irrelevant because we are only forking
to immediately exec(), which will discard the whole virtual address
space anyway.

This issue can be avoided by using a new optimized gspawn codepath in
the latest glib development version, which uses posix_spawn() internally.

For the optimized codepath to be used, we must not pass a child_setup
function, so the the file descriptor management is reimplemented here
using new glib API to pass fds to the child process. The old API will
continue to be used on older glib versions.

We must also change the spawn flags for this code path to be hit.
I checked that gnome-shell's open file descriptors are all CLOEXEC
so using G_SPAWN_LEAVE_DESCRIPTORS_OPEN should be safe.

This will result in more resilient app launching when memory is low,
since the optimized spawn path avoids cloning the virtual address
space of the parent process (gnome-shell) and avoids the irrelevant
memory overcommit check.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/132
2018-07-30 23:11:41 +00:00
ebe6f59d7e windowManager: Make workspace switching gestures follow motion
When 4fg swipe motion happens, set up early the workspace switching
animation with all surrounding workspaces. This allows us to move
all content back and forth in any direction. This works on both
touchcreens and touchpads.

When the gesture is activated, the same data is reused to follow
up with the tween animation.

The threshold has been also doubled, it was fairly small to start
with, and feels better now that workspaces stick to fingers.

https://bugzilla.gnome.org/show_bug.cgi?id=788994
2018-07-30 21:20:52 +00:00
e5c95b910d windowManager: Refactor workspace switching animations
Besides the separation into distinct functions, the stored data has
been made able to generically store windows from all surrounding
workspaces. All while keeping a special mode to animate between two
workspaces (The usual till now), this is the only mode exercised so
far.

In order to ease animations, all window groups are now children of
a common container, which is then animated.
2018-07-30 21:20:50 +00:00
2f76951658 windowManager: Declare variables
Fixes warnings from GJS.
2018-07-30 21:20:49 +00:00
3efd296fc3 app: Consider "new-window" action for opening new windows
While can_open_new_window() uses some elaborate heuristics to predict
whether an application can open multiple windows, open_new_window()
will always simply relaunch the application. This is often the best
we can do, but when an application provides a "new-window" action in
its .desktop file or on the bus, it is much more likely to work as
expected than blindly activating the app and hoping for a particular
behavior.

https://bugzilla.gnome.org/show_bug.cgi?id=756844
2018-07-30 19:21:40 +00:00
6688610c23 screenshot: Add PickColor() method to Screenshot interface
Use the newly added API to implement a color picker method in the
screenshot interface, so that the desktop portal can expose it
to applications.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/286
2018-07-30 16:55:10 +00:00
d2c75801ea screenshot: Allow bypassing lockdown setting
The setting is only relevant when writing to disk is required. We
will soon expose a screenshot method that doesn't, so make it
possible to ignore it.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/286
2018-07-30 16:55:10 +00:00
be84a00022 screenshot: Add pick_color() method
Graphical applications like GIMP or GIMP allow picking colors from
any location on-screen. In order to keep supporting this feature
on wayland and in sandboxed apps, we will expose an appropriate
method in the Screenshot interface, so first add a corresponding
method to ShellScreenshot.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/286
2018-07-30 16:55:10 +00:00
da537cda43 screenshot: Adopt GIO's async pattern
A custom callback type is more convenient, but only as long as no
other callback type is required. We are about to add functionality
that does not return the filename to a screenshot saved on disk, so
prepare for that by moving to GIO's generic async callback pattern.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/286
2018-07-30 16:55:09 +00:00
304c667bca windowManager: Add top edge drag gesture to unmake fullscreen window
Fullscreen windows cannot be restored by touch device users unless the
application adds support for it.
As it is unlikely to change all application lets introduce a top edge
drag gesture which unmakes fullscreen windows.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/123
2018-07-28 12:11:41 +02:00
879a81abeb remoteAccess: Make indicator orange
Make the indicator for active remote access use the warning color, to
indicate the severity of allowing remote access.

This only makes the indicator icon orange; the icon in the system menu
is still white.
2018-07-27 18:10:35 +02:00
e68ca5adbd Updated Spanish translation 2018-07-27 13:38:45 +02:00
cf69fe4b18 gdm, util: Always allow to retry login in unlock mode
When in lockscreen mode there's no point of resetting the auth login as there's
no welcome screen, and that would just cause the UI to freeze, with no reason.
This could have been useful if we were stopping the user to login for a given
time after ALLOWED_FAILURES attempts, but this is not the case yet.
2018-07-25 20:32:42 +00:00
8f848925f6 authPrompt: Do not enable sensitivity if retries are disallowed
Set the sensitivity of the UI according to the canRetry parameter and thus
if no more logins are allowed don't take any input.

Fixes #311
2018-07-25 20:32:42 +00:00
d21657fe61 authPrompt: Unset preemptiveAnswer on reset
When we get a reset signal the preemptiveAnswer should be also unset or it will
be used next time the user authPrompt will be activated, even without any further
user interaction.

Fixes #311
2018-07-25 20:32:41 +00:00
ce3555382b workspaceThumbnail: Sync clone position changes with actor
We need to update the clone position if window actor (not the meta window)
position changed.

https://bugzilla.gnome.org/show_bug.cgi?id=776588
2018-07-24 11:08:25 +00:00
837a00c3f0 workspace: Recompute bounding box on window 'position-changed'
We need to update the clone position if window size changed
also, rename meta window 'size-changed' callback accordingly.

https://bugzilla.gnome.org/show_bug.cgi?id=792681
2018-07-24 11:08:25 +00:00
132c8e0cf8 icons: update to current metaphors
- sync with adwaita-icon-theme metaphors
2018-07-24 11:05:55 +02:00
9c62522419 Update POTFILES.in 2018-07-23 23:14:12 +02:00
0d5bae3844 Add remote access indication and control
Add an indicator for when there is something access the display server
remotely. This could be 1) remote desktop, 2) screen cast or 3) remote
control, but all effectively applications using
org.freedesktop.portal.ScreenCast or org.gnome.portal.RemoteDesktop as
well as gnome-remote-desktop using the corresponding org.gnome.Mutter
APIs directly.

As it is now, it'll simply show a single icon for when anything is
having an active session, and a single action "Turn off" that'll close
every active session.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/160
2018-07-23 14:03:26 +02:00
97f6a35b46 Update French translation 2018-07-20 09:00:03 +00:00
43e8dfacb4 build: Don't use libdir for systemd unit path
Some systems define it to /usr/lib64 on 64-bit systems, which is not
where systemd looks for unit files. Just hardcode 'lib' in the install
prefix until we get to use the pkg-config file.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/424
2018-07-18 23:03:30 +02:00
0221099e7e Bump version to 3.29.4
Update NEWS.
2018-07-18 17:46:36 +02:00
374caade47 inputMethod: Handle IBusInputContext::forward-key-press
The input method may hint that certain keycodes should be pressed/released
besides the textual information in ::commit. An example is hitting space
in some IMs to commit text, where both ::commit happens, and an space is
visibly inserted. In order to handle this properly, we must honor
::forward-key-press.

In order to cater for the case that a keypress is forwarded while handling
that same keypress in a physical keyboard, check the current event being
handled and just forward it as-is if it matches. This is necessary to
prevent state from being doubly set, and the second event silenced away.

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

Closes: #275
2018-07-17 23:27:24 +00:00
a5937d1d6d Add systemd units
So that we can be started by systemd --user, instead of gnome-session.

There are three units:

  - gnome-shell.service: Start gnome-shell itself.
  - gnome-shell-x11.target, gnome-shell-wayland.target: Sync points for
    units that need to care if x11 or wayland is in use.
    gnome-settings-daemon will use these, for example.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/138
2018-07-17 18:10:06 +00:00
e36ba874a8 Stop using conditional catch statements
It is a mozilla extension that is going away in SpiderMonkey 60.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/151
2018-07-17 17:02:39 +00:00
22392d1328 loginManager: Get the session ID from logind if XDG_SESSION_ID unset
If we're started by systemd, we won't be in the user's display session.
However, this is still the session that will get locked & unlocked. Ask
logind what the 'display' or 'greeter' session is, and watch for the
Unlock signal for that session to know when to unlock.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/137
2018-07-17 17:44:18 +02:00
0dee82fb9f keyboard: Handle no-window case in FocusTracker
For windows, the cursor location needs to be adjusted by the frame
offsets. However we cannot assume that there is a window, as the
shell itself can have the key focus.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/414
2018-07-17 01:44:18 +02:00
68f00f397f Update Russian translation 2018-07-16 21:27:25 +00:00
905801b178 panel: Allow restoring maximized/tiled windows by touch
Maximized and tiled windows can be restored with a drag gesture,
not only from their titlebars, but also from any non-reactive
parts of the top bar above the window. Currently this only works
for actual pointer devices, extend the behavior to handle touch
as well.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/112
2018-07-14 18:38:16 +00:00
4a7082bb0f switcherPopup: Cancel window cycling with Tab
If the Escape key is used for a window/app cycler/switcher shortcut
(such as "Switch windows directly"), then there is no way to cancel
the switching/cycling operation with the keyboard.

This change allows cancelling such an operation by pressing the Tab
key, but only if Tab is not already being used by the current
switcher/cycler shortcut.

Closes: https://gitlab.gnome.org/GNOME/gnome-shell/issues/315
2018-07-14 14:35:05 +00:00
2e90c5fa4b popupMenu: Don't handle key presses directly if there are modifiers
Key events involved in a keyboard shortcut are not completely consumed by
Mutter. That means that if the popupMenu is bound to a shortcut (e.g.
Alt<Space>) and the user keeps the keys pressed, the same key-event will be
delivered to the popupMenu. We can workaround this issue filtering out all the
events where a a modifier is down (except capslock).

Fixes: https://gitlab.gnome.org/GNOME/gnome-shell/issues/372
2018-07-14 14:04:18 +02:00
50e849a186 st-texture-cache: Obey cache policy in st_texture_cache_load
https://bugzilla.gnome.org/show_bug.cgi?id=663461
2018-07-13 20:50:08 +00:00
e7f2e92410 events: Re-use event messages where possible
Destroying and recreating the entire events list on every change is not only
wasteful, it also breaks the clear functionality as messages scheduled for
removal are replaced with "new" messages after the first message has been
removed.

Address both issues by keeping track of all messages and re-use them
whenever possible.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/325
2018-07-13 20:13:30 +00:00
b1b455ff1a st-adjustment: Mark all properties as EXPLICIT_NOTIFY
All adjustment setter functions take good care of avoiding emission of
notify:: when it's not needed. The set_property() implementation already
calls into the setter functions, so mark the properties as EXPLICITY_NOTIFY
in order to optimize notify:: emission away through g_object_set (rather
common from JS code).
2018-07-13 11:53:46 +00:00
ab4c72d758 st-box-layout: Queue relayout on adjustment changes
The actor allocation doesn't change per-se, but apply_transform()
will practically transform it. In order to have the paint volume
update accordingly, queue a relayout.
2018-07-13 11:53:46 +00:00
86a520b880 st: Clip StEntry to allocation
The default get_paint_volume() implementation will do the union
of children, and the child ClutterText paint volume may expand
beyond StEntry size when text overflows.

We actually want all content to be clipped to the StEntry, so
implement get_paint_volume() and tell it so.
2018-07-13 11:53:45 +00:00
4bf033a885 st: Make StScrollables' paint volume reflect the unconstrained view
And constrain it in StScrollView instead (instead of falling back to an
infinite paint volume, as the actor as paint/pick impls, but no
corresponding get_paint_volume one).

Fixes artifacts with the AppView (and possibly other places) when paint
volumes are aggressively cached.
2018-07-13 11:53:45 +00:00
e3ebc8d0c6 keyboard: Remove stale references to global.screen
(Re)introduced by the previous patch.
2018-07-11 18:46:49 +02:00
fc5ab44704 keyboard: Implement standalone FocusTracker
And stop using FocusCaretTracker for caret position purposes. This
new object uses 1) the text-input protocol in wayland and 2) Info
from IBusPanelService for X11 (which is meant to work for XIM too).

This drops the usage of AtspiEventListener for OSK purposes, which
is best to avoid.
2018-07-11 18:32:32 +02:00
d5e8f174d4 Bump version to 3.29.3
Update NEWS.
2018-07-09 19:05:55 +02:00
d9a1434ae9 workspaceThumbnail: Don't keep stale clones in list
If a clone gets destroyed before the corresponding MetaWindow is
removed from the workspace, we will still find it in the list of
clones and try to destroy it again. Avoid the resulting warnings
by updating the list of clones immediately when a clone is destroyed.

https://bugzilla.gnome.org/show_bug.cgi?id=791233
2018-07-09 13:00:35 +02:00
d0bdea3178 workspace: Don't keep stale clones in list
If a clone gets destroyed before the corresponding MetaWindow is
removed from the workspace, we will still find it in the list of
clones and try to destroy it again. Avoid the resulting warnings
by updating the list of clones immediately when a clone is destroyed.

https://bugzilla.gnome.org/show_bug.cgi?id=791233
2018-07-09 13:00:17 +02:00
ccadf6aca1 workspaceThumbnail: remove unused private win reference 2018-07-09 13:00:15 +02:00
266b0e9dd0 keyboard: remove global.screen
This is disabled code for now, but let's have it fixed once we'll use it
2018-07-08 17:43:15 +02:00
f7355f593d closeDialog: use {disable,enable}_unredirect_for_display
Remove leftover global.screen presency
2018-07-08 17:43:15 +02:00
a301820258 Update Catalan translation 2018-07-08 09:23:29 +02:00
47ea10b7c9 Remove usage of MetaScreen
Remove any usage of MetaScreen, as it has been removed from libmutter
in the API version 3. The corresponding functionality has been moved
into three different places: MetaDisplay, MetaX11Display (for X11
specific functionality) and MetaWorkspaceManager.

https://bugzilla.gnome.org/show_bug.cgi?id=759538
2018-07-06 19:56:19 +02:00
2c0376c150 workspaceThumbnail: Initialize signal handler ids to 0
They are used in conditions, so initialize them first.
2018-07-06 19:55:07 +02:00
ac58c4280b Update Occitan translation 2018-07-05 09:51:43 +00:00
e39d7152f2 st-private: Warn if creating shadow for unallocated actors 2018-06-29 11:00:25 +02:00
e522e2e804 st-icon: Create shadow pipeline only at paint
Don't try to allocate the shadow after allocation, just do it at paint
as it's done by other shadowed widgets
2018-06-29 10:43:12 +02:00
2ba26407f1 st-icon: Remove unused size values 2018-06-29 10:43:12 +02:00
996dd74157 layoutManager: Return null monitor if focusIndex is invalid
https://bugzilla.gnome.org/show_bug.cgi?id=788882
2018-06-28 17:05:30 +02:00
878946962d windowManager: Don't animate unmanaged windows on (un)minimization 2018-06-28 17:05:30 +02:00
84d2d3feb3 keyboard: Check monitor validity before deferencing it
Monitor could be invalid in headless mode.

https://bugzilla.gnome.org/show_bug.cgi?id=788882
2018-06-28 17:05:30 +02:00
19e864ed3b keyboard: Handle case where keyboardMonitor is unset
This may be the case where keyboardIndex is -1, which may be the
case where either the keyboard monitor hasn't been set yet, or
the keyboard is being unmanaged and meta_window_get_monitor
returns -1

https://bugzilla.gnome.org/show_bug.cgi?id=788882
2018-06-28 17:05:29 +02:00
c9bf72c5c4 windowMenu: Check if monitorIndex is valid before using it
Calling meta_window_get_monitor on an unmanaged window may return
-1, so we need to check the return value.

https://bugzilla.gnome.org/show_bug.cgi?id=788882
2018-06-28 16:29:07 +02:00
5fe349d5ba thunderbolt: Do not auto start boltd
The service is expected to be activated by systemd when a thunderbolt
device is plugged in, so no need to have it auto-started with the
session.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/54
2018-06-25 14:17:07 +00:00
1f03599d1c st-texture-cache: Save cairo surfaces to a different map
The default keyed_surface is meant to handle CoglTextures thus we can't
add cairo surfaces to it, as the DestroyNotify function won't handle them.

Then the quicker way is to just add another Hash table for handling
such types of textures, with proper destroy function.
2018-06-21 00:56:36 +02:00
a24999b7a3 st-texture-cache: Don't add NULL textures to cache
This might cause a crash when cleaning up the cache as the hash table has
cogl_object_unref as DestroyNotify function but that assumes that
the passed object is a valid CoglObject.

Fixes: #210
2018-06-21 00:48:54 +02:00
8237a1f6e0 Change "const" to "var"
These variables are in fact used from other modules, so gjs complains about them
being const.
2018-06-18 11:19:13 -04:00
f9dec475a1 Update Chinese (Taiwan) translation 2018-06-13 08:38:03 +00:00
68b01a8f56 theme: Use tabular figures where appropriate
In places where numbers appear in columns (like the calendar widget) or
where changing numbers would result in labels jiggling around due to
small width changes (like the clock), use the newly added
font-feature-settings support to request tabular figures.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/34
2018-06-08 13:27:57 -04:00
f56ba0877a st: Add support for font-feature-settings
Cantarell now supports tabular figures, which are useful in places
where digits should either align or not use different widths. In
order to allow elements to request the feature, add support for
the corresponding CSS property[0].

[0] https://www.w3.org/TR/css-fonts-3/#font-rend-desc

https://gitlab.gnome.org/GNOME/gnome-shell/issues/34
2018-06-08 18:45:07 +02:00
5ac6201d91 test-theme: Fix a comment 2018-06-08 17:39:13 +02:00
a21a22fdb5 appDisplay: Make middle-click like Ctrl+click
When middle-clicking an app icon on the Dash, it will always try to open
a new window of that app, even if the app doesn't support multiple
windows. Meanwhile, Ctrl+click on an app will only open a new window if
the app allows it.

This change prevents middle-clicks on app icons from opening new windows
for apps without multi-window support.

Closes: https://gitlab.gnome.org/GNOME/gnome-shell/issues/316
2018-06-07 17:49:36 +00:00
a0fa50ac31 Update Scottish Gaelic translation
(cherry picked from commit 0ac0f7e85b)
2018-06-01 10:36:57 +00:00
b1dd746443 network: Keep key focus in dialog when removing networks
When the actor that has the key focus is destroyed, Clutter moves
the focus to the stage. In case the destroyed actor was inside a
ModalDialog, this breaks any keyboard interaction: keynav is broken
because the stage isn't in any focus chain, and access keys like
Escape because they are handled on the dialog's parent.

The only dialog that may destroy a child without recreating the dialog
buttons (and thus moving the key focus there) is the WirelessDialog,
fix it by keeping the key focus within the dialog when removing networks
from the list.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/76
2018-05-31 11:42:14 +00:00
c15e163eb1 network: Handle networks with no access points
This avoids a couple of warnings when encountering such a network.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/76
2018-05-31 11:42:14 +00:00
7a3927c168 screenshot: Store creation time in metadata
It's useful information, even when we are not using JPEG/Exif - at
least nautilus will show it in its image properties.

https://bugzilla.gnome.org/show_bug.cgi?id=790481
2018-05-31 11:36:27 +00:00
6eed4e31d7 workspace: Fall back to app name in window caption
Just like we did for the window list in app icons' context menu,
provide a fallback for window captions in the window picker rather
than showing blank items to the user.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/26
2018-05-31 11:27:44 +00:00
f0557ea05c appDisplay: Fall back to app name in icon menu
The app icon's context menu contains a list of open windows,
identified by their title. As we currently don't handle the
case where the app didn't set a title, we end up with empty
menu items which looks clearly broken. Fall back to the app's
name in that case.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/26
2018-05-31 11:27:43 +00:00
44894262f4 st-label: Unset clutter text instance on disposal
The instance is owned by the actor (being its child), and thus when the
disposal happens for the parent the text is disposed too, thus it's just
safer to nullify its reference so that we won't try to access to invalid
objects later, and this might be the case since the JS objects could be kept
around until they aren't finalized.

https://bugzilla.gnome.org/show_bug.cgi?id=788931
2018-05-29 02:28:26 +03:00
b03bcc85aa closeDialog: Periodically check for window to become responsive again
The close dialog for non-responding windows is closed automatically
when we detect that the window is responding again. However as we
currently only ping the window in response to certain user actions
(like focusing the window or opening the window menu), this can
easily go undetected.

Address this by periodically pinging the window while the close
dialog is shown.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/298
2018-05-25 18:23:55 +02:00
70057c6a55 closeDialog: Disable unredirection while showing
The dialog won't be visible when unredirection is in place (for example
while a fullscreen window is focused), so disable unredirection while
the dialog is up.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/298
2018-05-25 14:05:29 +00:00
86bd5b281d Bump version to 3.29.2
Update NEWS.
2018-05-24 18:54:29 +02:00
ad3e9ab205 docs: Clarify where style changes should be done
After the move to Gitlab, the gnome-shell-sass repository is more
exposed than it used to; clarify that it is not the place where
style changes should happen, but rather the corresponding subtree
in the gnome-shell repository.
2018-05-23 19:03:01 +02:00
02bbf409ea docs: Use Markdown
Markdown produces nicer output where supported, so use that instead
of plain ASCII formatting.
2018-05-23 19:03:01 +02:00
f56e4e177e docs: Remove old style HACKING
The information is outdated, the relevant documentation is all in
[the README](data/theme/README) nowadays.
2018-05-23 19:01:10 +02:00
fc26559f2c docs: Remove obsolete files
The canonical maintainership information is tracked in the project's
.doap file as for any other GNOME project, and the empty AUTHORS
file only existed to make autotools happy.
2018-05-23 19:01:10 +02:00
fdaddbd1e0 Improve notification documentation
Ref: https://gitlab.gnome.org/GNOME/gnome-shell/issues/294
2018-05-22 18:39:19 +02:00
04f61567ba Update Chinese (China) translation 2018-05-21 14:27:23 +00:00
a0785cdbc1 Update Swedish translation 2018-05-20 17:28:17 +00:00
94101e8bb8 magnifier.js: Fix zoom juddering
Make Zoom respond to the mouse silky-smoothly.

It was previously hard-coded to: 1000/50 = 20 FPS.

https://bugzilla.gnome.org/show_bug.cgi?id=682013
https://launchpad.net/bugs/1691675
2018-05-17 11:42:20 +08:00
f13dbf2f26 Update Galician translation 2018-05-15 22:36:45 +00:00
bae6f06e4e Update Galician translation 2018-05-15 21:58:21 +00:00
d8b9e23502 network: Update the icon in the panel whenever NM's state changes
Similar to what it's done when the main connection changes, we need
to make sure that the icon in the panel gets updated before calling
_syncConnectivity(), so that the icon gets always updated if needed,
regardless of whether there's an active connection or not.

This is needed because there's at least one case when an icon should
be shown when the computer is not connected to any network: when a
hotspot has been enabled, which can be useful even if there's not
an internet connection to share (e.g. to easily allow connecting
other devices to the computer.

Closes: https://gitlab.gnome.org/GNOME/gnome-shell/issues/214
2018-05-15 09:15:43 +01:00
7d59eaa67e Update Indonesian translation 2018-05-12 03:59:42 +00:00
c0a453f64f networkAgent: Fix fallout from libnm port
While the libnm-glib version of the function returns a GByteArray*
that gjs can directly cast to the required gutf8*, the libnm function
returns GBytes* from which we need to explicitly fetch the data.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/136
2018-05-09 16:19:58 +02:00
5336175736 osdWindow: Fix blurriness at certain resolutions
The y position wasn't rounded, leading to some blurriness at vertical
resolutions that aren't a multiple of 4 (e.g. 1050).

https://bugzilla.gnome.org/show_bug.cgi?id=782011
2018-05-08 21:04:02 +02:00
2997e4950b keyboardManager: take group index into account when preserving keymap
commit 642107a2 attempts to avoid resetting the current keymap on
spurious input source changes.

It does this by checking if the current layout id is found in
the new list of layouts and resetting the current layout to the
associated match in the list. By not nullifying the current
layout, it won't get subsequently reset.

Unfortunately, if the order of the list changes, resetting the
current keymap is still necessary, since the order corresponds
with the index of the activated group.

This commit changes the code to nullify the current layout if
its group index changes.

https://bugzilla.redhat.com/show_bug.cgi?id=1573923
2018-05-08 17:54:37 +00:00
a49fb90d86 build: Include Cally in St introspection
CallyActor is exposed indirectly via StAccessible's parent type,
so add the dependency to shut up a gjs warning.

https://bugzilla.gnome.org/show_bug.cgi?id=781471
2018-05-07 21:10:40 +00:00
ffc0eb1de2 remoteSearch: Actually return icons
Since commit 3b1330880f, a remote search result's createIcon() method
no longer returns the created icon, whoops ...

https://gitlab.gnome.org/GNOME/gnome-shell/issues/249
2018-05-03 08:22:58 +00:00
853c81eb62 Update Brazilian Portuguese translation
(cherry picked from commit e909db5848)
2018-05-02 18:47:03 +00:00
594cc7cbef workspaceThumbnails: Avoid access to undefined variables
If thumbnails haven't been created, they don't need to be destroyed.

https://bugzilla.gnome.org/show_bug.cgi?id=787871
2018-05-02 20:04:42 +02:00
0932324d39 calendar-server: Update views only after the time range is set
The gnome-shell-calendar-server calls to refresh queries even when it
has no time range set, which results in:
  a) waste of resources (for example after login),
  b) many runtime warnings in the journalctl log, related to
     incorrect time range being used.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/244
2018-05-02 16:10:33 +02:00
2d6cf236c4 perf-tool: Fix default value for --extra-filter
While it is theoretically fine to run --perf=hwtest without passing --hwtest,
the test will hang in this case because it fails to start gedit. Always append
Gedit to the default value for --extra-filter when running the "hwtest" test
to make it work fine without --hwtest.
2018-04-29 16:15:16 +00:00
642107a28f keyboardManager: Preserve current keymap across reloads
The IM can pretty much update the input sources anytime (even if
to set the same ones). That ends up triggering rebuilding all user
defined keymaps, and losing modifier state if we are unfortunate
enough that this caught us while pressing one.

One common situation seems to be password entries, resulting in
the wrong character being printed if the first character happens
to require the shift key.

If the current keymap is not found in the newly loaded list,
this._current will end up null, with the same behavior as we get
currently (immediate keymap reload).

https://bugzilla.redhat.com/show_bug.cgi?id=1569211

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

Closes: #240
2018-04-29 17:46:31 +02:00
581b38ecf4 scripting: Fix argument list of createTestWindow()
Commit f285f2c6 changed Scripting.createTestWindow() to accept a parameter
object instead of a parameter list but forgot to remove the width and height
arguments. This breaks the "core" test as all windows are created with default
settings.
2018-04-25 23:47:06 +02:00
fbc03cc262 Bump version to 3.29.1
Update NEWS.
2018-04-25 20:34:05 +02:00
a6ff195893 Updated Spanish translation 2018-04-25 13:16:18 +02:00
f411724064 Updated Czech translation 2018-04-24 17:33:14 +02:00
39f43a4cd4 Update Friulian translation 2018-04-23 19:42:08 +00:00
c82cb918ae network: initialize the agent asynchronously
This also bumps the NM requirement. We actually already use API from
1.0, but regularly hit various NetworkManager bugs with versions prior
to 1.10.2. 1.10.4 fixes the asynchronous agent initialization.

https://bugzilla.gnome.org/show_bug.cgi?id=789811
https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/63
2018-04-23 10:45:20 +02:00
38cdaa6c20 Update Romanian translation 2018-04-22 16:48:18 +00:00
0327069e83 polkitAgent: Guard against repeated close() calls
We use the close() method to disconnect signal handlers set up in
init(), however the handler ID is only valid in the first call in
case the method is called more than once.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/221
2018-04-21 18:42:15 +02:00
7601b029c8 Updated Slovenian translation 2018-04-20 21:59:35 +02:00
fb509dfc25 thunderbolt: sync D-Bus API with bolt changes
bolt 0.3 deprecated all AUTHORIZED_XXX status flags, but added
a CONNECTING one. Also AuthFlags got renamed to AuthCtrl.
2018-04-20 11:36:37 +02:00
874a91968f thunderbolt: remove gdbus error prefix, if present
If we get an error during device enrollment, the message might be
prefixed to indicate that the error came from the remote peer. We
are presenting that message to the user so strip that prefix away
if it was there.
2018-04-20 11:36:37 +02:00
0963ccddba thunderbolt: fix enroll-failed signal args order
The devices emitted (device, error) while the connected handler
was expecting (error, device). The former is more consistent
with the rest of the code (so change it to device, error).
2018-04-20 11:27:11 +02:00
145 changed files with 7648 additions and 5316 deletions

View File

View File

@ -1,19 +1,16 @@
Coding guide
============
# Coding guide
Our goal is to have all JavaScript code in GNOME follow a consistent style. In
a dynamic language like JavaScript, it is essential to be rigorous about style
(and unit tests), or you rapidly end up with a spaghetti-code mess.
A quick note
------------
## A quick note
Life isn't fun if you can't break the rules. If a rule seems unnecessarily
restrictive while you're coding, ignore it, and let the patch reviewer decide
what to do.
Indentation and whitespace
--------------------------
## Indentation and whitespace
Use four-space indents. Braces are on the same line as their associated
statements. You should only omit braces if *both* sides of the statement are
@ -22,7 +19,7 @@ on one line.
* One space after the `function` keyword. No space between the function name
* in a declaration or a call. One space before the parens in the `if`
* statements, or `while`, or `for` loops.
```javascript
function foo(a, b) {
let bar;
@ -39,22 +36,20 @@ on one line.
print(20);
}
}
```
Semicolons
----------
## Semicolons
JavaScript allows omitting semicolons at the end of lines, but don't. Always
end statements with a semicolon.
js2-mode
--------
## js2-mode
If using Emacs, do not use js2-mode. It is outdated and hasn't worked for a
while. emacs now has a built-in JavaScript mode, js-mode, based on
espresso-mode. It is the de facto emacs mode for JavaScript.
File naming and creation
------------------------
## File naming and creation
For JavaScript files, use lowerCamelCase-style names, with a `.js` extension.
@ -67,14 +62,13 @@ library name followed by a dash, e.g. `shell-app-system.c`. Create a
`-private.h` header when you want to share code internally in the
library. These headers are not installed, distributed or introspected.
Imports
-------
## Imports
Use UpperCamelCase when importing modules to distinguish them from ordinary
variables, e.g.
```javascript
const GLib = imports.gi.GLib;
```
Imports should be categorized into one of two places. The top-most import block
should contain only "environment imports". These are either modules from
gobject-introspection or modules added by gjs itself.
@ -85,7 +79,7 @@ e.g. `imports.ui.popupMenu`.
Each import block should be sorted alphabetically. Don't import modules you
don't use.
```javascript
const GLib = imports.gi.GLib;
const Gio = imports.gi.Gio;
const Lang = imports.lang;
@ -95,23 +89,22 @@ don't use.
const Params = imports.misc.params;
const Tweener = imports.ui.tweener;
const Util = imports.misc.util;
```
The alphabetical ordering should be done independently of the location of the
location. Never reference `imports` in actual code.
Constants
---------
## Constants
We use CONSTANTS_CASE to define constants. All constants should be directly
under the imports:
```javascript
const MY_DBUS_INTERFACE = 'org.my.Interface';
```
Variable declaration
--------------------
## Variable declaration
Always use either `const` or `let` when defining a variable.
```javascript
// Iterating over an array
for (let i = 0; i < arr.length; ++i) {
let item = arr[i];
@ -121,17 +114,17 @@ Always use either `const` or `let` when defining a variable.
for (let prop in someobj) {
...
}
```
If you use "var" then the variable is added to function scope, not block scope.
See [What's new in JavaScript 1.7](https://developer.mozilla.org/en/JavaScript/New_in_JavaScript/1.7#Block_scope_with_let_%28Merge_into_let_Statement%29)
Classes
-------
## Classes
There are many approaches to classes in JavaScript. We use our own class framework
(sigh), which is built in gjs. The advantage is that it supports inheriting from
GObjects, although this feature isn't used very often in the Shell itself.
```javascript
var IconLabelMenuItem = new Lang.Class({
Name: 'IconLabelMenuItem',
Extends: PopupMenu.PopupMenuBaseItem,
@ -146,6 +139,7 @@ GObjects, although this feature isn't used very often in the Shell itself.
log("menu opened!");
}
});
```
* 'Name' is required. 'Extends' is optional. If you leave it out, you will
automatically inherit from Object.
@ -162,13 +156,12 @@ GObjects, although this feature isn't used very often in the Shell itself.
still a giant function call, even though it may resemble a more
conventional syntax.
GObject Introspection
---------------------
## GObject Introspection
GObject Introspection is a powerful feature that allows us to have native
bindings for almost any library built around GObject. If a library requires
you to inherit from a type to use it, you can do so:
```javascript
var MyClutterActor = new Lang.Class({
Name: 'MyClutterActor',
Extends: Clutter.Actor,
@ -188,9 +181,9 @@ you to inherit from a type to use it, you can do so:
alloc.x2, alloc.y2);
}
});
```
Translatable strings, `environment.js`
--------------------------------------
## Translatable strings, `environment.js`
We use gettext to translate the GNOME Shell into all the languages that GNOME
supports. The `gettext` function is aliased globally as `_`, you do not need to
@ -204,8 +197,7 @@ and "double quotes" for strings that the user may see. This allows us to
quickly find untranslated or mistranslated strings by grepping through the
sources for double quotes without a gettext call around them.
`actor` and `_delegate`
-----------------------
## `actor` and `_delegate`
gjs allows us to set so-called "expando properties" on introspected objects,
allowing us to treat them like any other. Because the Shell was built before
@ -214,7 +206,7 @@ that has a property called `actor`. We call this wrapper class the "delegate".
We sometimes use expando properties to set a property called `_delegate` on
the actor itself:
```javascript
var MyClass = new Lang.Class({
Name: 'MyClass',
@ -229,6 +221,7 @@ the actor itself:
actor.set_label("You clicked the button!");
}
});
```
The 'delegate' property is important for anything which trying to get the
delegate object from an associated actor. For instance, the drag and drop
@ -236,16 +229,14 @@ system calls the `handleDragOver` function on the delegate of a "drop target"
when the user drags an item over it. If you do not set the `_delegate`
property, your actor will not be able to be dropped onto.
Functional style
----------------
## Functional style
JavaScript Array objects offer a lot of common functional programming
capabilities such as forEach, map, filter and so on. You can use these when
they make sense, but please don't have a spaghetti mess of function programming
messed in a procedural style. Use your best judgment.
Closures
--------
## Closures
`this` will not be captured in a closure, it is relative to how the closure is
invoked, not to the value of this where the closure is created, because "this"
@ -254,15 +245,16 @@ variable that can be captured in closures.
All closures should be wrapped with Function.prototype.bind or use arrow
notation.
```javascript
const Lang = imports.lang;
let closure1 = () => { this._fnorbate(); };
let closure2 = this._fnorbate.bind(this);
```
A more realistic example would be connecting to a signal on a method of a
prototype:
```javascript
const Lang = imports.lang;
const FnorbLib = imports.fborbLib;
@ -276,19 +268,21 @@ prototype:
this._updateFnorb();
}
});
```
Object literal syntax
---------------------
## Object literal syntax
In JavaScript, these are equivalent:
```javascript
foo = { 'bar': 42 };
foo = { bar: 42 };
```
and so are these:
```javascript
var b = foo['bar'];
var b = foo.bar;
```
If your usage of an object is like an object, then you're defining "member
variables." For member variables, use the no-quotes no-brackets syntax: `{ bar:
@ -298,14 +292,13 @@ If your usage of an object is like a hash table (and thus conceptually the keys
can have special chars in them), don't use quotes, but use brackets: `{ bar: 42
}`, `foo['bar']`.
Getters, setters, and Tweener
-----------------------------
## Getters, setters, and Tweener
Getters and setters should be used when you are dealing with an API that is
designed around setting properties, like Tweener. If you want to animate an
arbitrary property, create a getter and setter, and use Tweener to animate the
property.
```javascript
var ANIMATION_TIME = 2000;
var MyClass = new Lang.Class({
@ -331,3 +324,4 @@ property.
{ position: 100,
time: ANIMATION_TIME,
transition: 'easeOutQuad' });
```

View File

@ -1,7 +0,0 @@
Owen Taylor
E-mail: otaylor@redhat.com
Userid: otaylor
Colin Walters
E-mail: walters@verbum.org
Userid: walters

103
NEWS
View File

@ -1,3 +1,106 @@
3.29.91
=======
* Fix handling of 0/false options in ShowOSD D-Bus API [Florian; #791669]
* overview: Fix handling of confirmation dialogs on wayland [verdre; !180]
* Avoid some full relayout/redraws [Carlos; !197]
* Keep workspace switcher slid out when workspaces are in use [Florian; !161]
* Ignore auto-repeat for some keybindings [Andrea; #373]
* Misc. bug fixes [Carlos, Florian, Pascal; #464, !189, !191, !192, !162]
Contributors:
Andrea Azzarone, Olivier Blin, Carlos Garnacho, Florian Müllner,
Pascal Nowack, verdre
Translators:
Bruno Lopes da Silva [pt_BR], Matej Urbančič [sl], Piotr Drąg [pl],
Aurimas Černius [lt], Emin Tufan Çetin [tr], Fabio Tomat [fur],
Alexandre Franke [fr], Yi-Jyun Pan [zh_TW], Bernd Homuth [de],
Andre Klapper [cs], Jordi Mas [ca], Daniel Șerbănescu [ro],
Bruce Cowan [en_GB]
3.29.90
=======
* Add remote access indication on wayland [Jonas; !160]
* Fix wrong window positions in overview on wayland [Marco; #776588]
* Add gesture to unfullscreen a window [Jan-Michael; !123]
* Add PickColor method to screenshot D-Bus interface [Florian; #286]
* Consider "new-window" action when opening new windows [Florian; #756844]
* Make workspace switching gestures follow motion [Carlos; #788994]
* Support audio volumes above 100% [Didier; #790280]
* Misc. bug fixes [Florian, Daniel; #424, !132, !182, #433, !179, #786496]
Contributors:
Jonas Ådahl, Jan-Michael Brummer, Piotr Drąg, Daniel Drake, Carlos Garnacho,
Florian Müllner, Georges Basile Stavracas Neto, Didier Roche, Jakub Steiner,
Marco Trevisan (Treviño)
Translators:
Charles Monzat [fr], Daniel Mustieles [es]
3.29.4
======
* Fix "Clear All" for calendar events [Florian; #325]
* Allow cancelling direct switch operations [Xavier; #315]
* Support being started by systemd --user [Iain; !137, !138]
* Support key event forwarding required by some input methods [Carlos; #275]
* Misc. bug fixes and cleanups [Jasper, Andrea, Florian; #663461, #372, !112,
#414, !151]
Contributors:
Andrea Azzarone, Carlos Garnacho, Xavier Johnson, Iain Lane, Florian Müllner,
Jasper St. Pierre
Translators:
Stas Solovey [ru]
3.29.3
======
* Save creation time in screenshot metadata [Florian; #790481]
* Improve consistency between ctrl- and middle-click on app icons [Xavier; #316]
* Add support for font-feature-settings CSS property [Ryan; #34]
* Adjust to MetaScreen removal [Jonas; #759538]
* Misc. bug fixes [Florian, Marco, Sam; #298, #788931, #26, #76, !54, #788882,
#791233]
Contributors:
Jonas Ådahl, Ryan Hendrickson, Xavier Johnson, Florian Müllner, Joe Rabinoff,
Sam Spilsbury, Marco Trevisan (Treviño)
Translators:
Gun Chleoc [gd], Yi-Jyun Pan [zh_TW], Cédric Valmary [oc], Jordi Mas [ca]
3.29.2
======
* Guard against untimely keyboard map changes [Carlos; #240]
* Fix icons in search provider results [Florian; #249]
* Fix blurriness of OSD under some resolutions [Silvère; #782011]
* Fix lagging pointer when zoomed [Daniel; #682013]
* Misc. bug fixes [Milan, Xiaoguang, Florian, Mario, Ole; #244, #787871,
#781471, #136, #214, #294]
Contributors:
Ole Jørgen Brønner, Milan Crha, Carlos Garnacho, Yussuf Khalil,
Silvère Latchurié, Florian Müllner, Mario Sanchez Prada, Ray Strode,
Daniel van Vugt, Xiaoguang Wang
Translators:
Rafael Fontenelle [pt_BR], Kukuh Syafaat [id], Marcos Lans [gl],
Anders Jonsson [sv], Mingcong Bai [zh_CN]
3.29.1
======
* Support icons in app-menu [Florian; #760985]
* Misc. bug fixes [Marco, Florian, Lubomir; #792687, #221, !63]
Contributors:
Piotr Drąg, Takao Fujiwara, Christian Kellner, Florian Müllner,
Mario Sanchez Prada, Lubomir Rintel, Didier Roche, Marco Trevisan (Treviño),
verdre
Translators:
gogo [hr], Stas Solovey [ru], Matej Urbančič [sl], Daniel Șerbănescu [ro],
Fabio Tomat [fur], Marek Cernocky [cs], Daniel Mustieles [es]
3.28.1
======
* Fix compose characters in shell entries [Carlos; #115]

View File

@ -1,3 +1,4 @@
# GNOME Shell
GNOME Shell provides core user interface functions for the GNOME 3 desktop,
like switching to windows and launching applications. GNOME Shell takes
advantage of the capabilities of modern graphics hardware and introduces
@ -6,15 +7,14 @@ easy to use experience.
For more information about GNOME Shell, including instructions on how
to build GNOME Shell from source and how to get involved with the project,
see:
see the [project wiki][wiki]
https://wiki.gnome.org/Projects/GnomeShell
Bugs should be reported to the GNOME [bug tracking system][bug-tracker].
Bugs should be reported at http://bugzilla.gnome.org against the 'gnome-shell'
product.
License
=======
## License
GNOME Shell is distributed under the terms of the GNU General Public License,
version 2 or later. See the COPYING file for details.
version 2 or later. See the [COPYING][license] file for details.
[project-wiki]: https://wiki.gnome.org/Projects/GnomeShell
[bug-tracker]: https://gitlab.gnome.org/GNOME/gnome-shell/issues
[license]: COPYING

View File

@ -4,14 +4,14 @@ the extensions repository to provide good integration, letting the website
know which extensions are enabled and disabled, and allowing the website to
enable, disable and install them.
Bugs should be reported at http://bugzilla.gnome.org against the 'gnome-shell'
product.
Bugs should be reported to the GNOME [bug tracking system][bug-tracker].
License
=======
## License
The GNOME Shell Browser Plugin, like GNOME Shell itself is distributed under
the GNU General Public License, version 2 or later. The plugin also contains
header files from the "NPAPI SDK" project, tri-licensed under MPL 1.1, GPL 2.0
and LGPL 2.1. These headers are third-party sources and can be retrieved from:
http://code.google.com/p/npapi-sdk/
[bug-tracker]: https://gitlab.gnome.org/GNOME/gnome-shell/issues

View File

@ -24,3 +24,9 @@
/* Define if _NL_TIME_FIRST_WEEKDATE is available */
#mesondefine HAVE__NL_TIME_FIRST_WEEKDAY
/* Define if you have the `g_desktop_app_info_launch_uris_as_manager_with_fds` function */
#mesondefine HAVE_GIO_DESKTOP_LAUNCH_URIS_WITH_FDS
/* Define if fdwalk is available in libc */
#mesondefine HAVE_FDWALK

View File

@ -0,0 +1,6 @@
[org.gnome.mutter:GNOME]
attach-modal-dialogs=true
edge-tiling=true
dynamic-workspaces=true
workspaces-only-on-primary=true
focus-change-on-pointer-rest=true

View File

@ -0,0 +1,5 @@
[Desktop Entry]
Type=Application
Name=GNOME settings overrides migration
NoDisplay=true
Exec=@libexecdir@/gnome-shell-overrides-migration.sh

View File

@ -0,0 +1,5 @@
[Unit]
Description=GNOME Shell (wayland sync point)
After=gnome-shell.service
BindsTo=gnome-shell.service
Conflicts=gnome-shell-x11.target

View File

@ -0,0 +1,5 @@
[Unit]
Description=GNOME Shell (x11 sync point)
After=gnome-shell.service
BindsTo=gnome-shell.service
Conflicts=gnome-shell-wayland.target

View File

@ -0,0 +1,11 @@
[Unit]
Description=GNOME Shell
Wants=gnome-session.service
After=graphical-session-pre.target gnome-session-bus.target
PartOf=graphical-session.target
[Service]
Type=dbus
ExecStart=@bindir@/gnome-shell
Restart=on-failure
BusName=org.gnome.Shell

View File

@ -92,6 +92,33 @@ schema = configure_file(
configuration: schemaconf,
install_dir: schemadir
)
install_data('00_org.gnome.shell.gschema.override', install_dir: schemadir)
overrides_migration_conf = configuration_data()
overrides_migration_conf.set('libexecdir', libexecdir)
overrides_migration = configure_file(
input: 'gnome-shell-overrides-migration.desktop.in',
output: 'gnome-shell-overrides-migration.desktop',
configuration: overrides_migration_conf,
install_dir: autostartdir
)
if have_systemd
unitconf = configuration_data()
unitconf.set('bindir', bindir)
unit = configure_file(
input: 'gnome-shell.service.in',
output: 'gnome-shell.service',
configuration: unitconf,
install_dir: systemduserunitdir
)
units = files('gnome-shell-wayland.target',
'gnome-shell-x11.target')
install_data(units, install_dir: systemduserunitdir)
endif
# for unit tests - gnome.compile_schemas() only looks in srcdir
custom_target('compile-schemas',

View File

@ -91,6 +91,23 @@
<arg type="s" direction="out" name="filename_used"/>
</method>
<!--
PickColor:
Picks a color and returns the result.
The @result vardict contains:
<variablelist>
<varlistentry>
<term>color (ddd)</term>
<listitem><para>The color, RGB values in the range [0,1].</para></listitem>
</varlistentry>
</variablelist>
-->
<method name="PickColor">
<arg type="a{sv}" direction="out" name="result"/>
</method>
<!--
FlashArea:
@x: the X coordinate of the area to flash

View File

@ -190,6 +190,7 @@
</key>
</schema>
<!-- unused, change 00_org.gnome.shell.gschema.override instead -->
<schema id="org.gnome.shell.overrides" path="/org/gnome/shell/overrides/"
gettext-domain="@GETTEXT_PACKAGE@">
<key name="attach-modal-dialogs" type="b">

View File

@ -1,3 +0,0 @@
To generate the css files, from the project directory:
sass --sourcemap=none --update .

View File

@ -1,31 +0,0 @@
Summary
-------
* Do not edit the CSS directly, edit the source SCSS files and the CSS files will be generated
automatically when building with meson + ninja and left inside the build directory to be
incorporated into the gresource XML (you'll need to have sassc installed).
How to tweak the theme
----------------------
Adwaita is a complex theme, so to keep it maintainable it's written and processed in SASS, the
generated CSS is then transformed into a gresource file during gtk build and used at runtime in a
non-legible or editable form.
It is very likely your change will happen in the _common.scss file. That's where all the widget
selectors are defined. Here's a rundown of the "supporting" stylesheets, that are unlikely to be the
right place for a drive by stylesheet fix:
_colors.scss - global color definitions. We keep the number of defined colors to a necessary minimum,
most colors are derived from a handful of basics. It is an exact copy of the gtk+
counterpart. Light theme is used for the classic theme and dark is for GNOME3 shell
default.
_drawing.scss - drawing helper mixings/functions to allow easier definition of widget drawing under
specific context. This is why Adwaita isn't 15000 LOC.
_common.scss - actual definitions of style for each widget. This is where you are likely to add/remove
your changes.
You can read about SASS at http://sass-lang.com/documentation/. Once you make your changes to the
_common.scss file, you can run ninja to generate the final CSS files.

32
data/theme/README.md Normal file
View File

@ -0,0 +1,32 @@
## Summary
Do not edit the CSS directly, edit the source SCSS files and the CSS files
will be generated automatically when building with meson + ninja and left
inside the build directory to be incorporated into the gresource XML (you'll
need to have sassc installed).
## How to tweak the theme
Adwaita is a complex theme, so to keep it maintainable it's written and
processed in SASS, the generated CSS is then transformed into a gresource
file during gtk build and used at runtime in a non-legible or editable form.
It is very likely your change will happen in the [_common.scss][common] file.
That's where all the widget selectors are defined. Here's a rundown of
the "supporting" stylesheets, that are unlikely to be the right place
for a drive by stylesheet fix:
| File | Description |
| ------------------------ | ----------------- |
| [_colors.scss][colors] | global color definitions. We keep the number of defined colors to a necessary minimum, most colors are derived from a handful of basics. It is an exact copy of the gtk+ counterpart. Light theme is used for the classic theme and dark is for GNOME3 shell default. |
| [_drawing.scss][drawing] | drawing helper mixings/functions to allow easier definition of widget drawing under specific context. This is why Adwaita isn't 15000 LOC. |
| [_common.scss][common] | actual definitions of style for each widget. This is where you are likely to add/remove your changes. |
You can read about SASS on its [web page][sass-web]. Once you make your
changes to the [_common.scss][common] file, you can run ninja to generate the
final CSS files.
[common]: data/theme/gnome-shell-sass/_common.scss
[colors]: data/theme/gnome-shell-sass/_colors.scss
[drawing]: data/theme/gnome-shell-sass/_drawing.scss
[sass-web]: http://sass-lang.com/documentation/

View File

@ -1,6 +0,0 @@
--- Generating the css file ---
You need sass to generate the css file.
To generate them run from a command line in the project directory:
sass --sourcemap=none --update ./

View File

@ -1,7 +0,0 @@
GNOME Shell Sass is a project intended to allow the sharing of the theme sources in sass between gnome-shell and other projects like gnome-shell-extensions.
License
=======
GNOME Shell Sass is distributed under the terms of the GNU General Public License,
version 2 or later. See the COPYING file for details.

View File

@ -0,0 +1,16 @@
# GNOME Shell Sass
GNOME Shell Sass is a project intended to allow the sharing of the
theme sources in sass between gnome-shell and other projects like
gnome-shell-extensions.
Any changes should be done in the [GNOME Shell subtree][shell-subtree]
and not the stand-alone [gnome-shell-sass repository][sass-repo]. They
will then be synchronized periodically before releases.
## License
GNOME Shell Sass is distributed under the terms of the GNU General Public
License, version 2 or later. See the [COPYING][license] file for details.
[shell-subtree]: https://gitlab.gnome.org/GNOME/gnome-shell/tree/master/data/theme/gnome-shell-sass
[sass-repo]: https://gitlab.gnome.org/GNOME/gnome-shell-sass
[license]: COPYING

View File

@ -128,12 +128,15 @@ StScrollBar {
.slider {
height: 1em;
-slider-height: 0.3em;
-slider-background-color: $insensitive_bg_color; //background of the trough
-slider-border-color: $borders_color; //trough border color
-slider-active-background-color: $selected_bg_color; //active trough fill
-slider-active-border-color: darken($selected_bg_color,10%); //active trough border
-slider-border-width: 1px;
-barlevel-height: 0.3em;
-barlevel-background-color: $insensitive_bg_color; //background of the trough
-barlevel-border-color: $borders_color; //trough border color
-barlevel-active-background-color: $selected_bg_color; //active trough fill
-barlevel-active-border-color: darken($selected_bg_color,10%); //active trough border
-barlevel-overdrive-color: $destructive_color;
-barlevel-overdrive-border-color: darken($destructive_color,10%);
-barlevel-overdrive-separator-width: 0.2em;
-barlevel-border-width: 1px;
-slider-handle-radius: 6px;
}
@ -585,13 +588,11 @@ StScrollBar {
.osd-monitor-label { font-size: 3em; }
.level {
height: 0.6em;
border-radius: 0.3em;
background-color: transparentize(darken($osd_bg_color,15%),0.5);
color: $osd_fg_color;
}
.level-bar {
background-color: $osd_fg_color;
border-radius: 0.3em;
-barlevel-height: 0.6em;
-barlevel-background-color: transparentize(darken($osd_bg_color,15%),0.5);
-barlevel-active-background-color: $osd_fg_color;
-barlevel-overdrive-color: $destructive_color;
-barlevel-overdrive-separator-width: 0.2em;
}
}
@ -733,6 +734,7 @@ StScrollBar {
transition-duration: 500ms;
font-weight: bold;
height: 1.86em;
font-feature-settings: "tnum";
&.unlock-screen,
&.login-screen,
@ -824,6 +826,8 @@ StScrollBar {
.screencast-indicator { color: $warning_color; }
.remote-access-indicator { color: $warning_color; }
&.solid {
background-color: black;
/* transition from transparent to solid */
@ -958,6 +962,7 @@ StScrollBar {
padding: 0.1em;
margin: 2px;
border-radius: 1.4em;
font-feature-settings: "tnum";
&:hover,&:focus { background-color: lighten($bg_color,5%); }
&:active,&:selected {
color: lighten($selected_fg_color,5%);
@ -1120,6 +1125,7 @@ StScrollBar {
}
.system-menu-action {
-st-icon-style: symbolic;
color: $fg_color;
border-radius: 32px; /* wish we could do 50% */
padding: 13px;
@ -1867,6 +1873,7 @@ StScrollBar {
.screen-shield-clock-time {
font-size: 72pt;
text-shadow: 0px 2px 2px rgba(0,0,0,0.4);
font-feature-settings: "tnum";
}
.screen-shield-clock-date {

View File

@ -14,7 +14,7 @@
id="svg7384"
height="32"
sodipodi:docname="key-layout.svg"
inkscape:version="0.92.2 (5c3e80d, 2017-08-06)">
inkscape:version="0.92.3 (2405546, 2018-03-11)">
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
@ -24,17 +24,21 @@
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1919"
inkscape:window-height="1011"
inkscape:window-width="3440"
inkscape:window-height="1376"
id="namedview19"
showgrid="false"
inkscape:zoom="14.75"
inkscape:cx="1.220339"
inkscape:cy="11.842802"
inkscape:zoom="1"
inkscape:cx="46.246852"
inkscape:cy="17.474578"
inkscape:window-x="0"
inkscape:window-y="55"
inkscape:window-maximized="0"
inkscape:current-layer="svg7384" />
inkscape:window-y="27"
inkscape:window-maximized="1"
inkscape:current-layer="svg7384">
<inkscape:grid
type="xygrid"
id="grid861" />
</sodipodi:namedview>
<metadata
id="metadata90">
<rdf:RDF>
@ -92,23 +96,34 @@
style="display:inline"
id="g4953" />
<g
style="stroke-width:0.5;enable-background:new"
id="g3561"
inkscape:label="preferences-desktop-locale"
id="g11728"
transform="matrix(2,0,0,2,-522.0004,-1086)"
style="display:inline;stroke-width:1">
<rect
style="fill:none;stroke:none;stroke-width:1"
id="rect11724"
width="16"
height="16"
x="20"
y="326"
transform="translate(241.0002,217)" />
transform="matrix(2,0,0,2,135.99464,-895.9793)">
<path
style="fill:#e5e5e5;fill-opacity:1;stroke:none;stroke-width:1"
d="m 265.69612,545.23396 c -3.58218,0 -4.66582,1.39975 -4.66582,1.39975 v 10.04946 c 0,0 1.08364,-1.07673 4.66582,-1.07673 2.9161,0 4.47225,1.07673 7.17818,1.07673 2.08923,0 3.19429,-1.39975 3.19429,-1.39975 v -10.04946 c 0,0 -1.14095,1.04084 -3.23018,1.04084 -3.3734,0 -3.97619,-1.04084 -7.14229,-1.04084 z m 2.93145,2.77148 c 1.32876,0 2.375,1.08037 2.375,2.4375 0,1.35713 -1.04624,2.46875 -2.375,2.46875 -1.32876,0 -2.40625,-1.11162 -2.40625,-2.46875 0,-1.35713 1.07749,-2.4375 2.40625,-2.4375 z m -4.5625,0.96875 0.96875,1.03125 -0.9375,-0.0312 0.9375,1 -0.96875,-0.0312 0.96875,1.03125 -1,-0.0312 0.0312,-1 h -0.0312 l 0.0312,-0.9688 h -0.0312 z m 4.5625,0 c -0.794,0 -1.46875,0.6578 -1.46875,1.46875 0,0.81095 0.67475,1.46875 1.46875,1.46875 0.79399,0 1.4375,-0.6578 1.4375,-1.46875 0,-0.81095 -0.64351,-1.46875 -1.4375,-1.46875 z m 4.375,0 v 1 l 0.0312,0.96875 h -0.0312 l 0.0312,1 -1,0.0312 0.96875,-1.03125 -0.96875,0.0312 0.9375,-1 -0.9375,0.0312 z m -7.9375,2.96875 0.96875,1.03125 -1,-0.0312 z m 6.9375,0 0.0312,1 -1,0.0312 z m -5.9375,1 0.96875,1.03125 -1,-0.0312 z m 4.9375,0 0.0312,1 -1,0.0312 z"
id="path11726"
sodipodi:nodetypes="cc"
inkscape:connector-curvature="0"
sodipodi:nodetypes="sccssccsssssssccccccccccccsssssccccccccccccccccccccccccccc" />
id="path3535"
d="m -65,450 v 12"
style="fill:#e5e5e5;fill-opacity:1;fill-rule:evenodd;stroke:#e5e5e5;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
sodipodi:nodetypes="ccccccccc"
inkscape:connector-curvature="0"
id="path3537"
d="m -65,456 h 4 l 1,2 h 5 v -6 h -4 l -1,-2 h -5 z"
style="fill:none;fill-rule:evenodd;stroke:#e5e5e5;stroke-width:1;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
style="opacity:1;vector-effect:none;fill:#e5e5e5;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
d="m -65,456 h 4 l 1,2 h 5 v -6 h -4 l -1,-2 h -5 z"
id="path3539"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccccccc" />
<rect
style="color:#bebebe;display:inline;overflow:visible;visibility:visible;fill:none;stroke:none;stroke-width:0.89050001;marker:none;enable-background:new"
id="rect3543"
y="448"
x="-68"
height="16"
width="16" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 4.3 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

View File

@ -13,10 +13,102 @@
height="64px"
id="svg3393"
version="1.1"
inkscape:version="0.48.5 r10040"
sodipodi:docname="New document 2">
inkscape:version="0.92.3 (2405546, 2018-03-11)"
sodipodi:docname="no-notifications.svg">
<defs
id="defs3395" />
id="defs3395">
<clipPath
id="clipPath6262-0"
clipPathUnits="userSpaceOnUse">
<rect
style="color:#bebebe;display:inline;overflow:visible;visibility:visible;fill:#bebebe;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none"
id="rect6264-6"
width="3.8250003"
height="6.3750005"
x="26.849981"
y="220.75" />
</clipPath>
<clipPath
id="clipPath6258-0"
clipPathUnits="userSpaceOnUse">
<rect
style="color:#bebebe;display:inline;overflow:visible;visibility:visible;fill:#bebebe;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none"
id="rect6260-6"
width="2.8977275"
height="5.3129687"
x="26.965673"
y="221.28162" />
</clipPath>
<clipPath
id="clipPath6254-6"
clipPathUnits="userSpaceOnUse">
<rect
style="color:#bebebe;display:inline;overflow:visible;visibility:visible;fill:#bebebe;fill-opacity:1;stroke:none;stroke-width:2;marker:none"
id="rect6256-6"
width="1.876245"
height="4.8783236"
x="26.998718"
y="221.50153" />
</clipPath>
<clipPath
id="clipPath8028-3"
clipPathUnits="userSpaceOnUse">
<path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m -73,-30 -7,-7 v -4.5 h 16.5 v 4.5 l -7.5,7 z"
id="path8030-6"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccccc" />
</clipPath>
<clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath6810-7-87-7">
<rect
style="color:#bebebe;display:inline;overflow:visible;visibility:visible;fill:none;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none"
id="rect6812-2-4-5"
width="14"
height="11"
x="21"
y="281" />
</clipPath>
<clipPath
id="clipPath6262"
clipPathUnits="userSpaceOnUse">
<rect
style="color:#bebebe;display:inline;overflow:visible;visibility:visible;fill:#bebebe;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none"
id="rect6264"
width="3.8250003"
height="6.3750005"
x="26.849981"
y="220.75" />
</clipPath>
<clipPath
id="clipPath6258"
clipPathUnits="userSpaceOnUse">
<rect
style="color:#bebebe;display:inline;overflow:visible;visibility:visible;fill:#bebebe;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none"
id="rect6260"
width="2.8977275"
height="5.3129687"
x="26.965673"
y="221.28162" />
</clipPath>
<clipPath
id="clipPath6254"
clipPathUnits="userSpaceOnUse">
<rect
style="color:#bebebe;display:inline;overflow:visible;visibility:visible;fill:#bebebe;fill-opacity:1;stroke:none;stroke-width:2;marker:none"
id="rect6256"
width="1.876245"
height="4.8783236"
x="26.998718"
y="221.50153" />
</clipPath>
<inkscape:path-effect
effect="spiro"
id="path-effect3951"
is_visible="true" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
@ -24,17 +116,17 @@
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="5.5"
inkscape:cx="32"
inkscape:cy="32"
inkscape:zoom="1"
inkscape:cx="125.08157"
inkscape:cy="-13.805087"
inkscape:current-layer="layer1"
showgrid="true"
inkscape:document-units="px"
inkscape:grid-bbox="true"
inkscape:window-width="697"
inkscape:window-height="613"
inkscape:window-x="100"
inkscape:window-y="77"
inkscape:window-width="1664"
inkscape:window-height="1034"
inkscape:window-x="1479"
inkscape:window-y="252"
inkscape:window-maximized="0" />
<metadata
id="metadata3398">
@ -54,7 +146,7 @@
inkscape:groupmode="layer">
<g
style="display:inline"
transform="matrix(4,0,0,4,0.29733827,-0.35415646)"
transform="matrix(4,0,0,4,-79.702662,-0.35415646)"
id="g19245">
<g
id="g19247"
@ -71,15 +163,15 @@
transform="translate(-323.02908,-649.02581)">
<path
inkscape:connector-curvature="0"
d="m 331.9377,653 c 0.0187,0.16677 0.0625,0.32822 0.0625,0.5 0,2.48528 -2.01472,4.5 -4.5,4.5 -0.11769,0 -0.22834,-0.0224 -0.34375,-0.0312 l 0,2.21875 c 0,1.00412 0.80838,1.8125 1.8125,1.8125 l 1.54511,-5e-5 2,2.04688 2.0625,-2.04688 1.61114,0 c 1.00413,0 1.8125,-0.80838 1.8125,-1.8125 l 0,-5.375 c 0,-1.00412 -0.80837,-1.8125 -1.8125,-1.8125 z"
d="m 331.9377,653 c 0.0187,0.16677 0.0625,0.32822 0.0625,0.5 0,2.48528 -2.01472,4.5 -4.5,4.5 -0.11769,0 -0.22834,-0.0224 -0.34375,-0.0312 v 2.21875 c 0,1.00412 0.80838,1.8125 1.8125,1.8125 l 1.54511,-5e-5 2,2.04688 2.0625,-2.04688 h 1.61114 c 1.00413,0 1.8125,-0.80838 1.8125,-1.8125 v -5.375 c 0,-1.00412 -0.80837,-1.8125 -1.8125,-1.8125 z"
id="path19253"
sodipodi:nodetypes="csscsscccssssc"
style="opacity:0.5;color:#000000;fill:#c3c3c3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:0.5;fill:#c3c3c3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;enable-background:accumulate" />
<path
inkscape:connector-curvature="0"
d="m 327.5002,650 c -1.933,0 -3.5,1.567 -3.5,3.5 0,1.933 1.567,3.5 3.5,3.5 1.933,0 3.5,-1.567 3.5,-3.5 0,-1.933 -1.567,-3.5 -3.5,-3.5 z m -0.53125,1 1.03125,0 -0.0625,1.375 a 0.19951718,0.19951718 0 0 0 0,0.0625 0.19951718,0.19951718 0 0 0 0,0.0312 0.19951718,0.19951718 0 0 0 0.125,0.125 0.19951718,0.19951718 0 0 0 0.0312,0 0.19951718,0.19951718 0 0 0 0.0625,0 0.19951718,0.19951718 0 0 0 0.0625,0 0.19951718,0.19951718 0 0 0 0.0312,-0.0312 l 1.15625,-0.75 0.5,0.90625 -1.21875,0.625 a 0.19951718,0.19951718 0 0 0 -0.0312,0 0.19951718,0.19951718 0 0 0 -0.0312,0.0312 0.19951718,0.19951718 0 0 0 -0.0312,0.0937 0.19951718,0.19951718 0 0 0 0,0.0625 0.19951718,0.19951718 0 0 0 0,0.0312 0.19951718,0.19951718 0 0 0 0.0312,0.0625 0.19951718,0.19951718 0 0 0 0.0312,0.0312 0.19951718,0.19951718 0 0 0 0.0312,0.0312 l 1.25,0.625 -0.53125,0.90625 -1.15625,-0.781 a 0.19951718,0.19951718 0 0 0 -0.0312,0 0.19951718,0.19951718 0 0 0 -0.0625,-0.0312 0.19951718,0.19951718 0 0 0 -0.0625,0 0.19951718,0.19951718 0 0 0 -0.125,0.0937 0.19951718,0.19951718 0 0 0 -0.0312,0.0312 0.19951718,0.19951718 0 0 0 0,0.0312 0.19951718,0.19951718 0 0 0 0,0.0625 l 0.0625,1.3751 -1.03125,0 0.0937,-1.375 a 0.19951718,0.19951718 0 0 0 -0.0312,-0.0937 0.19951718,0.19951718 0 0 0 -0.0312,-0.0625 0.19951718,0.19951718 0 0 0 -0.0625,-0.0312 0.19951718,0.19951718 0 0 0 -0.0625,-0.0312 0.19951718,0.19951718 0 0 0 -0.0312,0 0.19951718,0.19951718 0 0 0 -0.0937,0.0312 l -1.1875,0.78125 -0.5,-0.90625 1.25,-0.625 a 0.19951718,0.19951718 0 0 0 0.0312,-0.0312 0.19951718,0.19951718 0 0 0 0.0312,-0.0312 0.19951718,0.19951718 0 0 0 0.0312,-0.0625 0.19951718,0.19951718 0 0 0 0,-0.0312 0.19951718,0.19951718 0 0 0 0,-0.0625 0.19951718,0.19951718 0 0 0 0,-0.0312 0.19951718,0.19951718 0 0 0 -0.0312,-0.0625 0.19951718,0.19951718 0 0 0 -0.0312,-0.0312 0.19951718,0.19951718 0 0 0 -0.0312,0 l -1.25,-0.625 0.5,-0.90625 1.1875,0.75 a 0.19951718,0.19951718 0 0 0 0.0312,0.0312 0.19951718,0.19951718 0 0 0 0.0625,0 0.19951718,0.19951718 0 0 0 0.0625,0 0.19951718,0.19951718 0 0 0 0.0312,0 0.19951718,0.19951718 0 0 0 0.0312,-0.0312 0.19951718,0.19951718 0 0 0 0.0312,-0.0312 0.19951718,0.19951718 0 0 0 0.0312,-0.0312 0.19951718,0.19951718 0 0 0 0,-0.0312 0.19951718,0.19951718 0 0 0 0.0312,-0.0625 0.19951718,0.19951718 0 0 0 0,-0.0312 L 326.96895,651 z"
d="m 327.5002,650 c -1.933,0 -3.5,1.567 -3.5,3.5 0,1.933 1.567,3.5 3.5,3.5 1.933,0 3.5,-1.567 3.5,-3.5 0,-1.933 -1.567,-3.5 -3.5,-3.5 z m -0.53125,1 h 1.03125 l -0.0625,1.375 a 0.19951718,0.19951718 0 0 0 0,0.0625 0.19951718,0.19951718 0 0 0 0,0.0312 0.19951718,0.19951718 0 0 0 0.125,0.125 0.19951718,0.19951718 0 0 0 0.0312,0 0.19951718,0.19951718 0 0 0 0.0625,0 0.19951718,0.19951718 0 0 0 0.0625,0 0.19951718,0.19951718 0 0 0 0.0312,-0.0312 l 1.15625,-0.75 0.5,0.90625 -1.21875,0.625 a 0.19951718,0.19951718 0 0 0 -0.0312,0 0.19951718,0.19951718 0 0 0 -0.0312,0.0312 0.19951718,0.19951718 0 0 0 -0.0312,0.0937 0.19951718,0.19951718 0 0 0 0,0.0625 0.19951718,0.19951718 0 0 0 0,0.0312 0.19951718,0.19951718 0 0 0 0.0312,0.0625 0.19951718,0.19951718 0 0 0 0.0312,0.0312 0.19951718,0.19951718 0 0 0 0.0312,0.0312 l 1.25,0.625 -0.53125,0.90625 -1.15625,-0.781 a 0.19951718,0.19951718 0 0 0 -0.0312,0 0.19951718,0.19951718 0 0 0 -0.0625,-0.0312 0.19951718,0.19951718 0 0 0 -0.0625,0 0.19951718,0.19951718 0 0 0 -0.125,0.0937 0.19951718,0.19951718 0 0 0 -0.0312,0.0312 0.19951718,0.19951718 0 0 0 0,0.0312 0.19951718,0.19951718 0 0 0 0,0.0625 L 328.0002,656 h -1.03125 l 0.0937,-1.375 a 0.19951718,0.19951718 0 0 0 -0.0312,-0.0937 0.19951718,0.19951718 0 0 0 -0.0312,-0.0625 0.19951718,0.19951718 0 0 0 -0.0625,-0.0312 0.19951718,0.19951718 0 0 0 -0.0625,-0.0312 0.19951718,0.19951718 0 0 0 -0.0312,0 0.19951718,0.19951718 0 0 0 -0.0937,0.0312 l -1.1875,0.78125 -0.5,-0.90625 1.25,-0.625 a 0.19951718,0.19951718 0 0 0 0.0312,-0.0312 0.19951718,0.19951718 0 0 0 0.0312,-0.0312 0.19951718,0.19951718 0 0 0 0.0312,-0.0625 0.19951718,0.19951718 0 0 0 0,-0.0312 0.19951718,0.19951718 0 0 0 0,-0.0625 0.19951718,0.19951718 0 0 0 0,-0.0312 0.19951718,0.19951718 0 0 0 -0.0312,-0.0625 0.19951718,0.19951718 0 0 0 -0.0312,-0.0312 0.19951718,0.19951718 0 0 0 -0.0312,0 l -1.25,-0.625 0.5,-0.90625 1.1875,0.75 a 0.19951718,0.19951718 0 0 0 0.0312,0.0312 0.19951718,0.19951718 0 0 0 0.0625,0 0.19951718,0.19951718 0 0 0 0.0625,0 0.19951718,0.19951718 0 0 0 0.0312,0 0.19951718,0.19951718 0 0 0 0.0312,-0.0312 0.19951718,0.19951718 0 0 0 0.0312,-0.0312 0.19951718,0.19951718 0 0 0 0.0312,-0.0312 0.19951718,0.19951718 0 0 0 0,-0.0312 0.19951718,0.19951718 0 0 0 0.0312,-0.0625 0.19951718,0.19951718 0 0 0 0,-0.0312 z"
id="path19255"
style="color:#000000;fill:#bebebe;fill-opacity:1;fill-rule:nonzero;stroke:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#bebebe;fill-opacity:1;fill-rule:nonzero;stroke:none;marker:none;enable-background:accumulate" />
</g>
<g
id="g19257"
@ -110,5 +202,22 @@
style="display:inline"
transform="translate(-323.02908,-649.02581)" />
</g>
<g
style="opacity:1;vector-effect:none;fill:#bebebe;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:new"
inkscape:label="preferences-system-notifications"
id="g13967"
transform="matrix(4,0,0,4,-1044.0008,-2172)">
<path
inkscape:connector-curvature="0"
d="m 268.94244,544.94838 c -2.20914,0 -3.33013,1.5 -4,4 l -1,5 c -0.10831,0.54156 -0.44772,1 -1,1 v 1 h 12 v -1 c -0.55229,0 -0.89169,-0.45844 -1,-1 l -1,-5 c -0.53033,-2.5 -1.79086,-4 -4,-4 z"
id="path40220"
sodipodi:nodetypes="ccsccccscc"
style="opacity:1;vector-effect:none;fill:#bebebe;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;paint-order:normal" />
<path
inkscape:connector-curvature="0"
d="m 269.11822,556.94838 a 1.5,1.5 0 0 0 1.41211,1 1.5,1.5 0 0 0 1.41211,-1 z"
id="path40774"
style="opacity:1;vector-effect:none;fill:#bebebe;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;paint-order:normal" />
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 6.1 KiB

After

Width:  |  Height:  |  Size: 11 KiB

View File

@ -50,8 +50,7 @@ gnome.gtkdoc('shell',
join_paths(meson.build_root(), 'src')
],
scan_args: [
'--ignore-headers=' + ' '.join(private_headers + exclude_directories),
'--rebuild-types'
'--ignore-headers=' + ' '.join(private_headers + exclude_directories)
],
install: true
)

View File

@ -17,8 +17,7 @@ gnome.gtkdoc('st',
],
scan_args: [
'--ignore-headers=' + ' '.join(private_headers),
'--rebuild-sections',
'--rebuild-types'
'--rebuild-sections'
],
install: true
)

View File

@ -242,11 +242,11 @@ var AuthPrompt = new Lang.Class({
this.emit('prompted');
},
_onVerificationFailed() {
_onVerificationFailed(userVerifier, canRetry) {
this._queryingService = null;
this.clear();
this.updateSensitivity(true);
this.updateSensitivity(canRetry);
this.setActorInDefaultButtonWell(null);
this.verificationStatus = AuthPromptStatus.VERIFICATION_FAILED;
},
@ -439,6 +439,7 @@ var AuthPrompt = new Lang.Class({
this.verificationStatus = AuthPromptStatus.NOT_VERIFYING;
this.cancelButton.reactive = true;
this.nextButton.label = _("Next");
this._preemptiveAnswer = null;
if (this._userVerifier)
this._userVerifier.cancel();

View File

@ -350,16 +350,19 @@ var ShellUserVerifier = new Lang.Class({
try {
this._clearUserVerifier();
this._userVerifier = client.open_reauthentication_channel_finish(result);
} catch(e if e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED)) {
return;
} catch(e if e.matches(Gio.DBusError, Gio.DBusError.ACCESS_DENIED) &&
!this._reauthOnly) {
// Gdm emits org.freedesktop.DBus.Error.AccessDenied when there is
// no session to reauthenticate. Fall back to performing verification
// from this login session
client.get_user_verifier(this._cancellable, this._userVerifierGot.bind(this));
return;
} catch(e) {
if (e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED))
return;
if (e.matches(Gio.DBusError, Gio.DBusError.ACCESS_DENIED) &&
!this._reauthOnly) {
// Gdm emits org.freedesktop.DBus.Error.AccessDenied when there
// is no session to reauthenticate. Fall back to performing
// verification from this login session
client.get_user_verifier(this._cancellable,
this._userVerifierGot.bind(this));
return;
}
this._reportInitError('Failed to open reauthentication channel', e);
return;
}
@ -374,9 +377,9 @@ var ShellUserVerifier = new Lang.Class({
try {
this._clearUserVerifier();
this._userVerifier = client.get_user_verifier_finish(result);
} catch(e if e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED)) {
return;
} catch(e) {
if (e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED))
return;
this._reportInitError('Failed to obtain user verifier', e);
return;
}
@ -434,9 +437,9 @@ var ShellUserVerifier = new Lang.Class({
(obj, result) => {
try {
obj.call_begin_verification_for_user_finish(result);
} catch(e if e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED)) {
return;
} catch(e) {
if (e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED))
return;
this._reportInitError('Failed to start verification for user', e);
return;
}
@ -449,9 +452,9 @@ var ShellUserVerifier = new Lang.Class({
(obj, result) => {
try {
obj.call_begin_verification_finish(result);
} catch(e if e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED)) {
return;
} catch(e) {
if (e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED))
return;
this._reportInitError('Failed to start verification', e);
return;
}
@ -534,12 +537,13 @@ var ShellUserVerifier = new Lang.Class({
_verificationFailed(retry) {
// For Not Listed / enterprise logins, immediately reset
// the dialog
// Otherwise, we allow ALLOWED_FAILURES attempts. After that, we
// go back to the welcome screen.
// Otherwise, when in login mode we allow ALLOWED_FAILURES attempts.
// After that, we go back to the welcome screen.
this._failCounter++;
let canRetry = retry && this._userName &&
this._failCounter < this._settings.get_int(ALLOWED_FAILURES_KEY);
(this._reauthOnly ||
this._failCounter < this._settings.get_int(ALLOWED_FAILURES_KEY));
if (canRetry) {
if (!this.hasPendingMessages) {
@ -562,7 +566,7 @@ var ShellUserVerifier = new Lang.Class({
}
}
this.emit('verification-failed');
this.emit('verification-failed', canRetry);
},
_onConversationStopped(client, serviceName) {

View File

@ -9,8 +9,6 @@
<file>gdm/realmd.js</file>
<file>gdm/util.js</file>
<file>extensionPrefs/main.js</file>
<file>misc/config.js</file>
<file>misc/extensionUtils.js</file>
<file>misc/fileUtils.js</file>
@ -33,8 +31,6 @@
<file>perf/core.js</file>
<file>perf/hwtest.js</file>
<file>portalHelper/main.js</file>
<file>ui/accessDialog.js</file>
<file>ui/altTab.js</file>
<file>ui/animation.js</file>
@ -43,6 +39,7 @@
<file>ui/audioDeviceSelection.js</file>
<file>ui/backgroundMenu.js</file>
<file>ui/background.js</file>
<file>ui/barLevel.js</file>
<file>ui/boxpointer.js</file>
<file>ui/calendar.js</file>
<file>ui/checkBox.js</file>
@ -130,6 +127,7 @@
<file>ui/status/rfkill.js</file>
<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>

View File

@ -6,3 +6,17 @@ js_resources = gnome.compile_resources(
c_name: 'shell_js_resources',
dependencies: [config_js]
)
portal_resources = gnome.compile_resources(
'portal-resources', 'portal-resources.gresource.xml',
source_dir: ['.', meson.current_build_dir()],
c_name: 'portal_js_resources',
dependencies: [config_js]
)
prefs_resources = gnome.compile_resources(
'prefs-resources', 'prefs-resources.gresource.xml',
source_dir: ['.', meson.current_build_dir()],
c_name: 'prefs_js_resources',
dependencies: [config_js]
)

View File

@ -112,6 +112,8 @@ function createExtensionObject(uuid, dir, type) {
let metadataContents, success, tag;
try {
[success, metadataContents, tag] = metadataFile.load_contents(null);
if (metadataContents instanceof Uint8Array)
metadataContents = imports.byteArray.toString(metadataContents);
} catch (e) {
throw new Error('Failed to load metadata.json: ' + e);
}

View File

@ -115,6 +115,11 @@ var IBusManager = new Lang.Class({
object_path: IBus.PATH_PANEL });
this._candidatePopup.setPanelService(this._panelService);
this._panelService.connect('update-property', this._updateProperty.bind(this));
this._panelService.connect('set-cursor-location', (ps, x, y, w, h) => {
let cursorLocation = { x, y, width: w, height: h };
this.emit('set-cursor-location', cursorLocation);
});
try {
// IBus versions older than 1.5.10 have a bug which
// causes spurious set-content-type emissions when

View File

@ -15,6 +15,8 @@ var InputMethod = new Lang.Class({
this._purpose = 0;
this._enabled = true;
this._currentFocus = null;
this._currentEvent = null;
this._doForwardEvent = false;
this._ibus = IBus.Bus.new_async();
this._ibus.connect('connected', this._onConnected.bind(this));
this._ibus.connect('disconnected', this._clear.bind(this));
@ -25,6 +27,9 @@ var InputMethod = new Lang.Class({
this._onSourceChanged.bind(this));
this._currentSource = this._inputSourceManager.currentSource;
let deviceManager = Clutter.DeviceManager.get_default();
this._virtualDevice = deviceManager.create_virtual_device(Clutter.InputDeviceType.KEYBOARD_DEVICE);
if (this._ibus.is_connected())
this._onConnected();
},
@ -64,6 +69,7 @@ var InputMethod = new Lang.Class({
this._context.connect('commit-text', this._onCommitText.bind(this));
this._context.connect('delete-surrounding-text', this._onDeleteSurroundingText.bind(this));
this._context.connect('update-preedit-text', this._onUpdatePreeditText.bind(this));
this._context.connect('forward-key-event', this._onForwardKeyEvent.bind(this));
this._updateCapabilities();
},
@ -96,6 +102,24 @@ var InputMethod = new Lang.Class({
this.set_preedit_text(str, pos);
},
_onForwardKeyEvent(context, keyval, keycode, state) {
let press = (state & IBus.ModifierType.RELEASE_MASK) == 0;
if (this._currentEvent) {
// If we are handling this same event in filter_key_press(),
// just let it go through, sending the same event again will
// be silenced away because the key counts as pressed.
if (this._currentEvent.get_key_symbol() == keyval &&
(this._currentEvent.type() == Clutter.EventType.KEY_PRESS) == press) {
this._doForwardEvent = true;
return;
}
}
this._virtualDevice.notify_key(Clutter.get_current_event_time(), keycode,
press ? Clutter.KeyState.PRESSED : Clutter.KeyState.RELEASED);
},
vfunc_focus_in(focus) {
this._currentFocus = focus;
if (this._context) {
@ -197,13 +221,23 @@ var InputMethod = new Lang.Class({
if (event.type() == Clutter.EventType.KEY_RELEASE)
state |= IBus.ModifierType.RELEASE_MASK;
this._currentEvent = event;
this._doForwardEvent = false;
this._context.process_key_event_async(event.get_key_symbol(),
event.get_key_code() - 8, // Convert XKB keycodes to evcodes
state, -1, null,
(context, res) => {
try {
let retval = context.process_key_event_async_finish(res);
if (this._doForwardEvent)
retval = false;
this.notify_key_event(event, retval);
this._doForwardEvent = false;
this._currentEvent = null;
} catch (e) {
log('Error processing key on IM: ' + e.message);
}

View File

@ -89,6 +89,8 @@ var KeyboardManager = new Lang.Class({
},
setUserLayouts(ids) {
let currentId = this._current ? this._current.id : null;
let currentGroupIndex = this._current ? this._current.groupIndex : null;
this._current = null;
this._layoutInfos = {};
@ -115,6 +117,9 @@ var KeyboardManager = new Lang.Class({
info.group = group;
info.groupIndex = groupIndex;
if (currentId == id && currentGroupIndex == groupIndex)
this._current = info;
i += 1;
}
},

View File

@ -40,14 +40,24 @@ const SystemdLoginSessionIface = '<node> \
<signal name="Lock" /> \
<signal name="Unlock" /> \
<property name="Active" type="b" access="read" /> \
<property name="Class" type="s" access="read" /> \
<property name="Id" type="s" access="read" /> \
<method name="SetLockedHint"> \
<arg type="b" direction="in"/> \
</method> \
</interface> \
</node>';
const SystemdLoginUserIface = '<node> \
<interface name="org.freedesktop.login1.User"> \
<property name="Display" type="(so)" access="read" /> \
<property name="Sessions" type="a(so)" access="read" /> \
</interface> \
</node>';
const SystemdLoginManager = Gio.DBusProxy.makeProxyWrapper(SystemdLoginManagerIface);
const SystemdLoginSession = Gio.DBusProxy.makeProxyWrapper(SystemdLoginSessionIface);
const SystemdLoginUser = Gio.DBusProxy.makeProxyWrapper(SystemdLoginUserIface);
function haveSystemd() {
return GLib.access("/run/systemd/seats", 0) >= 0;
@ -109,6 +119,9 @@ var LoginManagerSystemd = new Lang.Class({
this._proxy = new SystemdLoginManager(Gio.DBus.system,
'org.freedesktop.login1',
'/org/freedesktop/login1');
this._userProxy = new SystemdLoginUser(Gio.DBus.system,
'org.freedesktop.login1',
'/org/freedesktop/login1/user/self');
this._proxy.connectSignal('PrepareForSleep',
this._prepareForSleep.bind(this));
},
@ -121,8 +134,31 @@ var LoginManagerSystemd = new Lang.Class({
let sessionId = GLib.getenv('XDG_SESSION_ID');
if (!sessionId) {
log('Unset XDG_SESSION_ID, getCurrentSessionProxy() called outside a user session.');
return;
log('Unset XDG_SESSION_ID, getCurrentSessionProxy() called outside a user session. Asking logind directly.');
let [session, objectPath] = this._userProxy.Display;
if (session) {
log(`Will monitor session ${session}`);
sessionId = session;
} else {
log('Failed to find "Display" session; are we the greeter?');
for (let [session, objectPath] of this._userProxy.Sessions) {
let sessionProxy = new SystemdLoginSession(Gio.DBus.system,
'org.freedesktop.login1',
objectPath);
log(`Considering ${session}, class=${sessionProxy.Class}`);
if (sessionProxy.Class == 'greeter') {
log(`Yes, will monitor session ${session}`);
sessionId = session;
break;
}
}
if (!sessionId) {
log('No, failed to get session from logind.');
return;
}
}
}
this._proxy.GetSessionRemote(sessionId, (result, error) => {

View File

@ -136,8 +136,7 @@ function run() {
global.frame_finish_timestamp = true;
for (let k = 0; k < 5; k++)
yield Scripting.createTestWindow(640, 480,
{ maximized: true });
yield Scripting.createTestWindow({ maximized: true });
yield Scripting.waitTestWindows();
yield Scripting.sleep(1000);
@ -158,8 +157,7 @@ function run() {
yield Scripting.destroyTestWindows();
Main.overview.hide();
yield Scripting.createTestWindow(640, 480,
{ maximized: true,
yield Scripting.createTestWindow({ maximized: true,
redraws: true});
yield Scripting.waitTestWindows();

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<gresources>
<gresource prefix="/org/gnome/shell">
<file>misc/config.js</file>
<file>portalHelper/main.js</file>
</gresource>
</gresources>

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<gresources>
<gresource prefix="/org/gnome/shell">
<file>extensionPrefs/main.js</file>
<file>misc/config.js</file>
<file>misc/extensionUtils.js</file>
<file>misc/fileUtils.js</file>
<file>misc/params.js</file>
</gresource>
</gresources>

View File

@ -502,7 +502,8 @@ var CyclerPopup = new Lang.Class({
_finish() {
let window = this._items[this._selectedIndex];
let ws = window.get_workspace();
let activeWs = global.screen.get_active_workspace();
let workspaceManager = global.workspace_manager;
let activeWs = workspaceManager.get_active_workspace();
if (window.minimized) {
Main.wm.skipNextEffect(window.get_compositor_private());
@ -572,7 +573,14 @@ var WindowSwitcherPopup = new Lang.Class({
},
_getWindowList() {
let workspace = this._settings.get_boolean('current-workspace-only') ? global.screen.get_active_workspace() : null;
let workspace = null;
if (this._settings.get_boolean('current-workspace-only')) {
let workspaceManager = global.workspace_manager;
workspace = workspaceManager.get_active_workspace();
}
return getWindows(workspace);
},
@ -620,7 +628,14 @@ var WindowCyclerPopup = new Lang.Class({
},
_getWindows() {
let workspace = this._settings.get_boolean('current-workspace-only') ? global.screen.get_active_workspace() : null;
let workspace = null;
if (this._settings.get_boolean('current-workspace-only')) {
let workspaceManager = global.workspace_manager;
workspace = workspaceManager.get_active_workspace();
}
return getWindows(workspace);
},
@ -669,8 +684,14 @@ var AppSwitcher = new Lang.Class({
let windowTracker = Shell.WindowTracker.get_default();
let settings = new Gio.Settings({ schema_id: 'org.gnome.shell.app-switcher' });
let workspace = settings.get_boolean('current-workspace-only') ? global.screen.get_active_workspace()
: null;
let workspace = null;
if (settings.get_boolean('current-workspace-only')) {
let workspaceManager = global.workspace_manager;
workspace = workspaceManager.get_active_workspace();
}
let allWindows = global.display.get_tab_list(Meta.TabList.NORMAL, workspace);
// Construct the AppIcons, add to the popup

View File

@ -1778,10 +1778,11 @@ var AppIcon = new Lang.Class({
activate(button) {
let event = Clutter.get_current_event();
let modifiers = event ? event.get_state() : 0;
let openNewWindow = this.app.can_open_new_window () &&
modifiers & Clutter.ModifierType.CONTROL_MASK &&
this.app.state == Shell.AppState.RUNNING ||
button && button == 2;
let isMiddleButton = button && button == Clutter.BUTTON_MIDDLE;
let isCtrlPressed = (modifiers & Clutter.ModifierType.CONTROL_MASK) != 0;
let openNewWindow = this.app.can_open_new_window() &&
this.app.state == Shell.AppState.RUNNING &&
(isCtrlPressed || isMiddleButton);
if (this.app.state == Shell.AppState.STOPPED || openNewWindow)
this.animateLaunch();
@ -1861,7 +1862,8 @@ var AppIconMenu = new Lang.Class({
// Display the app windows menu items and the separator between windows
// of the current desktop and other windows.
let activeWorkspace = global.screen.get_active_workspace();
let workspaceManager = global.workspace_manager;
let activeWorkspace = workspaceManager.get_active_workspace();
let separatorShown = windows.length > 0 && windows[0].get_workspace() != activeWorkspace;
for (let i = 0; i < windows.length; i++) {
@ -1870,7 +1872,9 @@ var AppIconMenu = new Lang.Class({
this._appendSeparator();
separatorShown = true;
}
let item = this._appendMenuItem(window.title);
let title = window.title ? window.title
: this._source.app.get_name();
let item = this._appendMenuItem(title);
item.connect('activate', () => {
this.emit('activate-window', window);
});

View File

@ -240,7 +240,7 @@ var Background = new Lang.Class({
file: null,
style: null });
this.background = new Meta.Background({ meta_screen: global.screen });
this.background = new Meta.Background({ meta_display: global.display });
this.background._delegate = this;
this._settings = params.settings;
@ -499,12 +499,12 @@ var SystemBackground = new Lang.Class({
let file = Gio.File.new_for_uri('resource:///org/gnome/shell/theme/noise-texture.png');
if (_systemBackground == null) {
_systemBackground = new Meta.Background({ meta_screen: global.screen });
_systemBackground = new Meta.Background({ meta_display: global.display });
_systemBackground.set_color(DEFAULT_BACKGROUND_COLOR);
_systemBackground.set_file(file, GDesktopEnums.BackgroundStyle.WALLPAPER);
}
this.actor = new Meta.BackgroundActor({ meta_screen: global.screen,
this.actor = new Meta.BackgroundActor({ meta_display: global.display,
monitor: 0,
background: _systemBackground });
@ -538,8 +538,10 @@ var BackgroundSource = new Lang.Class({
this._settings = new Gio.Settings({ schema_id: settingsSchema });
this._backgrounds = [];
this._monitorsChangedId = global.screen.connect('monitors-changed',
this._onMonitorsChanged.bind(this));
let monitorManager = Meta.MonitorManager.get();
this._monitorsChangedId =
monitorManager.connect('monitors-changed',
this._onMonitorsChanged.bind(this));
},
_onMonitorsChanged() {
@ -604,7 +606,8 @@ var BackgroundSource = new Lang.Class({
},
destroy() {
global.screen.disconnect(this._monitorsChangedId);
let monitorManager = Meta.MonitorManager.get();
monitorManager.disconnect(this._monitorsChangedId);
for (let monitorIndex in this._backgrounds) {
let background = this._backgrounds[monitorIndex];
@ -751,7 +754,7 @@ var BackgroundManager = new Lang.Class({
_createBackgroundActor() {
let background = this._backgroundSource.getBackground(this._monitorIndex);
let backgroundActor = new Meta.BackgroundActor({ meta_screen: global.screen,
let backgroundActor = new Meta.BackgroundActor({ meta_display: global.display,
monitor: this._monitorIndex,
background: background.background,
vignette: this._vignette,

210
js/ui/barLevel.js Normal file
View File

@ -0,0 +1,210 @@
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
const Atk = imports.gi.Atk;
const Cairo = imports.cairo;
const Clutter = imports.gi.Clutter;
const Lang = imports.lang;
const St = imports.gi.St;
const Signals = imports.signals;
var BarLevel = new Lang.Class({
Name: "BarLevel",
_init(value, params) {
if (isNaN(value))
// Avoid spreading NaNs around
throw TypeError('The bar level value must be a number');
this._maxValue = 1;
this._value = Math.max(Math.min(value, this._maxValue), 0);
this._overdriveStart = 1;
this._barLevelWidth = 0;
if (params == undefined)
params = {}
this.actor = new St.DrawingArea({ styleClass: params['styleClass'] || 'barlevel',
can_focus: params['canFocus'] || false,
reactive: params['reactive'] || false,
accessible_role: params['accessibleRole'] || Atk.Role.LEVEL_BAR });
this.actor.connect('repaint', this._barLevelRepaint.bind(this));
this.actor.connect('allocation-changed', (actor, box) => {
this._barLevelWidth = box.get_width();
});
this._customAccessible = St.GenericAccessible.new_for_actor(this.actor);
this.actor.set_accessible(this._customAccessible);
this._customAccessible.connect('get-current-value', this._getCurrentValue.bind(this));
this._customAccessible.connect('get-minimum-value', this._getMinimumValue.bind(this));
this._customAccessible.connect('get-maximum-value', this._getMaximumValue.bind(this));
this._customAccessible.connect('set-current-value', this._setCurrentValue.bind(this));
this.connect('value-changed', this._valueChanged.bind(this));
},
setValue(value) {
if (isNaN(value))
throw TypeError('The bar level value must be a number');
this._value = Math.max(Math.min(value, this._maxValue), 0);
this.actor.queue_repaint();
},
setMaximumValue(value) {
if (isNaN(value))
throw TypeError('The bar level max value must be a number');
this._maxValue = Math.max(value, 1);
this._overdriveStart = Math.min(this._overdriveStart, this._maxValue);
this.actor.queue_repaint();
},
setOverdriveStart(value) {
if (isNaN(value))
throw TypeError('The overdrive limit value must be a number');
if (value > this._maxValue)
throw new Error(`Tried to set overdrive value to ${value}, ` +
`which is a number greater than the maximum allowed value ${this._maxValue}`);
this._overdriveStart = value;
this._value = Math.max(Math.min(value, this._maxValue), 0);
this.actor.queue_repaint();
},
_barLevelRepaint(area) {
let cr = area.get_context();
let themeNode = area.get_theme_node();
let [width, height] = area.get_surface_size();
let barLevelHeight = themeNode.get_length('-barlevel-height');
let barLevelBorderRadius = Math.min(width, barLevelHeight) / 2;
let fgColor = themeNode.get_foreground_color();
let barLevelColor = themeNode.get_color('-barlevel-background-color');
let barLevelActiveColor = themeNode.get_color('-barlevel-active-background-color');
let barLevelOverdriveColor = themeNode.get_color('-barlevel-overdrive-color');
let barLevelBorderWidth = Math.min(themeNode.get_length('-barlevel-border-width'), 1);
let [hasBorderColor, barLevelBorderColor] =
themeNode.lookup_color('-barlevel-border-color', false);
if (!hasBorderColor)
barLevelBorderColor = barLevelColor;
let [hasActiveBorderColor, barLevelActiveBorderColor] =
themeNode.lookup_color('-barlevel-active-border-color', false);
if (!hasActiveBorderColor)
barLevelActiveBorderColor = barLevelActiveColor;
let [hasOverdriveBorderColor, barLevelOverdriveBorderColor] =
themeNode.lookup_color('-barlevel-overdrive-border-color', false);
if (!hasOverdriveBorderColor)
barLevelOverdriveBorderColor = barLevelOverdriveColor;
const TAU = Math.PI * 2;
let endX = 0;
if (this._maxValue > 0)
endX = barLevelBorderRadius + (width - 2 * barLevelBorderRadius) * this._value / this._maxValue;
let overdriveSeparatorX = barLevelBorderRadius + (width - 2 * barLevelBorderRadius) * this._overdriveStart / this._maxValue;
let overdriveActive = this._overdriveStart !== this._maxValue;
let overdriveSeparatorWidth = 0;
if (overdriveActive)
overdriveSeparatorWidth = themeNode.get_length('-barlevel-overdrive-separator-width');
/* background bar */
cr.arc(width - barLevelBorderRadius - barLevelBorderWidth, height / 2, barLevelBorderRadius, TAU * 3 / 4, TAU * 1 / 4);
cr.lineTo(endX, (height + barLevelHeight) / 2);
cr.lineTo(endX, (height - barLevelHeight) / 2);
cr.lineTo(width - barLevelBorderRadius - barLevelBorderWidth, (height - barLevelHeight) / 2);
Clutter.cairo_set_source_color(cr, barLevelColor);
cr.fillPreserve();
Clutter.cairo_set_source_color(cr, barLevelBorderColor);
cr.setLineWidth(barLevelBorderWidth);
cr.stroke();
/* normal progress bar */
let x = Math.min(endX, overdriveSeparatorX - overdriveSeparatorWidth / 2);
cr.arc(barLevelBorderRadius + barLevelBorderWidth, height / 2, barLevelBorderRadius, TAU * 1 / 4, TAU * 3 / 4);
cr.lineTo(x, (height - barLevelHeight) / 2);
cr.lineTo(x, (height + barLevelHeight) / 2);
cr.lineTo(barLevelBorderRadius + barLevelBorderWidth, (height + barLevelHeight) / 2);
Clutter.cairo_set_source_color(cr, barLevelActiveColor);
cr.fillPreserve();
Clutter.cairo_set_source_color(cr, barLevelActiveBorderColor);
cr.setLineWidth(barLevelBorderWidth);
cr.stroke();
/* overdrive progress barLevel */
x = Math.min(endX, overdriveSeparatorX) + overdriveSeparatorWidth / 2;
if (this._value > this._overdriveStart) {
cr.moveTo(x, (height - barLevelHeight) / 2);
cr.lineTo(endX, (height - barLevelHeight) / 2);
cr.lineTo(endX, (height + barLevelHeight) / 2);
cr.lineTo(x, (height + barLevelHeight) / 2);
cr.lineTo(x, (height - barLevelHeight) / 2);
Clutter.cairo_set_source_color(cr, barLevelOverdriveColor);
cr.fillPreserve();
Clutter.cairo_set_source_color(cr, barLevelOverdriveBorderColor);
cr.setLineWidth(barLevelBorderWidth);
cr.stroke();
}
/* end progress bar arc */
if (this._value <= this._overdriveStart)
Clutter.cairo_set_source_color(cr, barLevelActiveColor);
else
Clutter.cairo_set_source_color(cr, barLevelOverdriveColor);
cr.arc(endX, height / 2, barLevelBorderRadius, TAU * 3 / 4, TAU * 1 / 4);
cr.lineTo(Math.floor(endX), (height + barLevelHeight) / 2);
cr.lineTo(Math.floor(endX), (height - barLevelHeight) / 2);
cr.lineTo(endX, (height - barLevelHeight) / 2);
cr.fillPreserve();
cr.setLineWidth(barLevelBorderWidth);
cr.stroke();
/* draw overdrive separator */
if (overdriveActive) {
cr.moveTo(overdriveSeparatorX - overdriveSeparatorWidth / 2, (height - barLevelHeight) / 2);
cr.lineTo(overdriveSeparatorX + overdriveSeparatorWidth / 2, (height - barLevelHeight) / 2);
cr.lineTo(overdriveSeparatorX + overdriveSeparatorWidth / 2, (height + barLevelHeight) / 2);
cr.lineTo(overdriveSeparatorX - overdriveSeparatorWidth / 2, (height + barLevelHeight) / 2);
cr.lineTo(overdriveSeparatorX - overdriveSeparatorWidth / 2, (height - barLevelHeight) / 2);
if (this._value <= this._overdriveStart)
Clutter.cairo_set_source_color(cr, fgColor);
else
Clutter.cairo_set_source_color(cr, barLevelColor);
cr.fill();
}
cr.$dispose();
},
_getCurrentValue(actor) {
return this._value;
},
_getOverdriveStart(actor) {
return this._overdriveStart;
},
_getMinimumValue(actor) {
return 0;
},
_getMaximumValue(actor) {
return this._maxValue;
},
_setCurrentValue(actor, value) {
this._value = value;
},
_valueChanged(barLevel, value, property) {
this._customAccessible.notify("accessible-value");
},
get value() {
return this._value;
}
});
Signals.addSignalMethods(BarLevel.prototype);

View File

@ -821,6 +821,8 @@ var EventsSection = new Lang.Class({
this._desktopSettings.connect('changed', this._reloadEvents.bind(this));
this._eventSource = new EmptyEventSource();
this._messageById = new Map();
this.parent();
this._title = new St.Button({ style_class: 'events-section-title',
@ -875,20 +877,32 @@ var EventsSection = new Lang.Class({
this._reloading = true;
this._list.destroy_all_children();
let periodBegin = _getBeginningOfDay(this._date);
let periodEnd = _getEndOfDay(this._date);
let events = this._eventSource.getEvents(periodBegin, periodEnd);
let ids = events.map(e => e.id);
this._messageById.forEach((message, id) => {
if (ids.includes(id))
return;
this._messageById.delete(id);
this.removeMessage(message);
});
for (let i = 0; i < events.length; i++) {
let event = events[i];
let message = new EventMessage(event, this._date);
message.connect('close', () => {
this._ignoreEvent(event);
});
this.addMessage(message, false);
let message = this._messageById.get(event.id);
if (!message) {
message = new EventMessage(event, this._date);
message.connect('close', () => {
this._ignoreEvent(event);
});
this._messageById.set(event.id, message);
this.addMessage(message, false);
} else {
this.moveMessage(message, i, false);
}
}
this._reloading = false;

View File

@ -2,6 +2,7 @@
const Clutter = imports.gi.Clutter;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const GObject = imports.gi.GObject;
const Lang = imports.lang;
const Meta = imports.gi.Meta;
@ -13,6 +14,7 @@ const Tweener = imports.ui.tweener;
var FROZEN_WINDOW_BRIGHTNESS = -0.3
var DIALOG_TRANSITION_TIME = 0.15
var ALIVE_TIMEOUT = 5000;
var CloseDialog = new Lang.Class({
Name: 'CloseDialog',
@ -26,6 +28,7 @@ var CloseDialog = new Lang.Class({
this.parent();
this._window = window;
this._dialog = null;
this._timeoutId = 0;
},
get window() {
@ -97,6 +100,14 @@ var CloseDialog = new Lang.Class({
if (this._dialog != null)
return;
Meta.disable_unredirect_for_display(global.display);
this._timeoutId = GLib.timeout_add(GLib.PRIORITY_DEFAULT, ALIVE_TIMEOUT,
() => {
this._window.check_alive(global.display.get_current_time_roundtrip());
return GLib.SOURCE_CONTINUE;
});
this._addWindowEffect();
this._initDialog();
@ -117,6 +128,11 @@ var CloseDialog = new Lang.Class({
if (this._dialog == null)
return;
Meta.enable_unredirect_for_display(global.display);
GLib.source_remove(this._timeoutId);
this._timeoutId = 0;
let dialog = this._dialog;
this._dialog = null;
this._removeWindowEffect();

View File

@ -506,8 +506,12 @@ var VPNRequestHandler = new Lang.Class({
try {
data = this._dataStdout.peek_buffer();
keyfile.load_from_data(data.toString(), data.length,
GLib.KeyFileFlags.NONE);
if (data instanceof Uint8Array)
data = imports.byteArray.toGBytes(data);
else
data = data.toGBytes();
keyfile.load_from_bytes(data, GLib.KeyFileFlags.NONE);
if (keyfile.get_integer(VPN_UI_GROUP, 'Version') != 2)
throw new Error('Invalid plugin keyfile version, is %d');
@ -604,12 +608,17 @@ var NetworkAgent = new Lang.Class({
this._native.connect('new-request', this._newRequest.bind(this));
this._native.connect('cancel-request', this._cancelRequest.bind(this));
try {
this._native.init(null);
} catch(e) {
this._native = null;
logError(e, 'error initializing the NetworkManager Agent');
}
this._initialized = false;
this._native.init_async(GLib.PRIORITY_DEFAULT, null, (o, res) => {
try {
this._native.init_finish(res);
this._initialized = true;
} catch(e) {
this._native = null;
logError(e, 'error initializing the NetworkManager Agent');
}
});
},
enable() {
@ -617,7 +626,7 @@ var NetworkAgent = new Lang.Class({
return;
this._native.auto_register = true;
if (!this._native.registered)
if (this._initialized && !this._native.registered)
this._native.register_async(null, null);
},
@ -640,7 +649,7 @@ var NetworkAgent = new Lang.Class({
return;
this._native.auto_register = false;
if (this._native.registered)
if (this._initialized && this._native.registered)
this._native.unregister_async(null, null);
},
@ -655,7 +664,7 @@ var NetworkAgent = new Lang.Class({
switch (connectionType) {
case '802-11-wireless':
let wirelessSetting = connection.get_setting_wireless();
let ssid = NM.utils_ssid_to_utf8(wirelessSetting.get_ssid());
let ssid = NM.utils_ssid_to_utf8(wirelessSetting.get_ssid().get_data());
title = _("Authentication required by wireless network");
body = _("Passwords or encryption keys are required to access the wireless network “%s”.").format(ssid);
break;

View File

@ -201,7 +201,9 @@ var AuthenticationDialog = new Lang.Class({
close(timestamp) {
this.parent(timestamp);
Main.sessionMode.disconnect(this._sessionUpdatedId);
if (this._sessionUpdatedId)
Main.sessionMode.disconnect(this._sessionUpdatedId);
this._sessionUpdatedId = 0;
},
_ensureOpen() {

View File

@ -85,9 +85,11 @@ var CtrlAltTabManager = new Lang.Class({
// And add the windows metacity would show in its Ctrl-Alt-Tab list
if (Main.sessionMode.hasWindows && !Main.overview.visible) {
let screen = global.screen;
let display = screen.get_display();
let windows = display.get_tab_list(Meta.TabList.DOCKS, screen.get_active_workspace ());
let display = global.display;
let workspaceManager = global.workspace_manager;
let activeWorkspace = workspaceManager.get_active_workspace();
let windows = display.get_tab_list(Meta.TabList.DOCKS,
activeWorkspace);
let windowTracker = Shell.WindowTracker.get_default();
let textureCache = St.TextureCache.get_default();
for (let i = 0; i < windows.length; i++) {
@ -131,7 +133,7 @@ var CtrlAltTabManager = new Lang.Class({
},
_focusWindows(timestamp) {
global.screen.focus_default_window(timestamp);
global.display.focus_default_window(timestamp);
}
});

View File

@ -280,7 +280,7 @@ var _Draggable = new Lang.Class({
this._touchSequence = sequence;
this._grabEvents();
global.screen.set_cursor(Meta.Cursor.DND_IN_DRAG);
global.display.set_cursor(Meta.Cursor.DND_IN_DRAG);
this._dragX = this._dragStartX = stageX;
this._dragY = this._dragStartY = stageY;
@ -412,7 +412,7 @@ var _Draggable = new Lang.Class({
if (motionFunc) {
let result = motionFunc(dragEvent);
if (result != DragMotionResult.CONTINUE) {
global.screen.set_cursor(DRAG_CURSOR_MAP[result]);
global.display.set_cursor(DRAG_CURSOR_MAP[result]);
return GLib.SOURCE_REMOVE;
}
}
@ -430,13 +430,13 @@ var _Draggable = new Lang.Class({
targY,
0);
if (result != DragMotionResult.CONTINUE) {
global.screen.set_cursor(DRAG_CURSOR_MAP[result]);
global.display.set_cursor(DRAG_CURSOR_MAP[result]);
return GLib.SOURCE_REMOVE;
}
}
target = target.get_parent();
}
global.screen.set_cursor(Meta.Cursor.DND_IN_DRAG);
global.display.set_cursor(Meta.Cursor.DND_IN_DRAG);
return GLib.SOURCE_REMOVE;
},
@ -509,7 +509,7 @@ var _Draggable = new Lang.Class({
}
this._dragInProgress = false;
global.screen.set_cursor(Meta.Cursor.DEFAULT);
global.display.set_cursor(Meta.Cursor.DEFAULT);
this.emit('drag-end', event.get_time(), true);
this._dragComplete();
return true;
@ -561,7 +561,7 @@ var _Draggable = new Lang.Class({
let [snapBackX, snapBackY, snapBackScale] = this._getRestoreLocation();
if (this._actorDestroyed) {
global.screen.set_cursor(Meta.Cursor.DEFAULT);
global.display.set_cursor(Meta.Cursor.DEFAULT);
if (!this._buttonDown)
this._dragComplete();
this.emit('drag-end', eventTime, false);
@ -620,7 +620,7 @@ var _Draggable = new Lang.Class({
if (!this._buttonDown)
this._dragComplete();
global.screen.set_cursor(Meta.Cursor.DEFAULT);
global.display.set_cursor(Meta.Cursor.DEFAULT);
},
_onAnimationComplete(dragActor, eventTime) {

View File

@ -27,9 +27,9 @@ var EdgeDragAction = new Lang.Class({
_getMonitorRect(x, y) {
let rect = new Meta.Rectangle({ x: x - 1, y: y - 1, width: 1, height: 1 });
let monitorIndex = global.screen.get_monitor_index_for_rect(rect);
let monitorIndex = global.display.get_monitor_index_for_rect(rect);
return global.screen.get_monitor_geometry(monitorIndex);
return global.display.get_monitor_geometry(monitorIndex);
},
vfunc_gesture_prepare(action, actor) {

View File

@ -697,7 +697,14 @@ var EndSessionDialog = new Lang.Class({
if (proxy.State == 'closing')
continue;
if (proxy.Id == GLib.getenv('XDG_SESSION_ID'))
let sessionId = GLib.getenv('XDG_SESSION_ID');
if (!sessionId)
this._loginManager.getCurrentSessionProxy(currentSessionProxy => {
sessionId = currentSessionProxy.Id;
log(`endSessionDialog: No XDG_SESSION_ID, fetched from logind: ${sessionId}`);
});
if (proxy.Id == sessionId)
continue;
let session = { user: this._userManager.get_user(userName),

View File

@ -1,6 +1,5 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const FocusCaretTracker = imports.ui.focusCaretTracker;
const Atspi = imports.gi.Atspi;
const Clutter = imports.gi.Clutter;
const Gdk = imports.gi.Gdk;
@ -13,6 +12,7 @@ const Signals = imports.signals;
const St = imports.gi.St;
const InputSourceManager = imports.ui.status.keyboard;
const IBusManager = imports.misc.ibusManager;
const BoxPointer = imports.ui.boxpointer;
const Layout = imports.ui.layout;
const Main = imports.ui.main;
@ -261,6 +261,7 @@ var Key = new Lang.Class({
this._extended_keyboard = null;
this._pressTimeoutId = 0;
this._capturedPress = false;
this._capturedEventId = 0;
this._unmapId = 0;
this._longPress = false;
@ -471,6 +472,8 @@ var KeyboardModel = new Lang.Class({
_loadModel(groupName) {
let file = Gio.File.new_for_uri('resource:///org/gnome/shell/osk-layouts/%s.json'.format(groupName));
let [success, contents] = file.load_contents(null);
if (contents instanceof Uint8Array)
contents = imports.byteArray.toString(contents);
return JSON.parse(contents);
},
@ -484,6 +487,73 @@ var KeyboardModel = new Lang.Class({
}
});
var FocusTracker = new Lang.Class({
Name: 'FocusTracker',
_init() {
this._currentWindow = null;
global.display.connect('notify::focus-window', () => {
this._setCurrentWindow(global.display.focus_window);
this.emit('window-changed', this._currentWindow);
});
global.display.connect('grab-op-begin', (display, window, op) => {
if (window == this._currentWindow &&
(op == Meta.GrabOp.MOVING || op == Meta.GrabOp.KEYBOARD_MOVING))
this.emit('reset');
});
/* Valid for wayland clients */
Main.inputMethod.connect('cursor-location-changed', (o, rect) => {
let newRect = { x: rect.get_x(), y: rect.get_y(), width: rect.get_width(), height: rect.get_height() };
this._setCurrentRect(newRect);
});
this._ibusManager = IBusManager.getIBusManager();
this._ibusManager.connect('set-cursor-location', (manager, rect) => {
/* Valid for X11 clients only */
if (Main.inputMethod.currentFocus)
return;
this._setCurrentRect(rect);
});
},
get currentWindow() {
return this._currentWindow;
},
_setCurrentWindow(window) {
this._currentWindow = window;
},
_setCurrentRect(rect) {
if (this._currentWindow) {
let frameRect = this._currentWindow.get_frame_rect();
rect.x -= frameRect.x;
rect.y -= frameRect.y;
}
this._rect = rect;
this.emit('position-changed');
},
getCurrentRect() {
let rect = { x: this._rect.x, y: this._rect.y,
width: this._rect.width, height: this._rect.height };
if (this._currentWindow) {
let frameRect = this._currentWindow.get_frame_rect();
rect.x += frameRect.x;
rect.y += frameRect.y;
}
return rect;
}
});
Signals.addSignalMethods(FocusTracker.prototype);
var Keyboard = new Lang.Class({
Name: 'Keyboard',
@ -491,15 +561,10 @@ var Keyboard = new Lang.Class({
this.actor = null;
this._focusInExtendedKeys = false;
this._focusCaretTracker = new FocusCaretTracker.FocusCaretTracker();
this._focusCaretTracker.connect('focus-changed', this._onFocusChanged.bind(this));
this._focusCaretTracker.connect('caret-moved', this._onCaretMoved.bind(this));
this._languagePopup = null;
this._currentAccessible = null;
this._caretTrackingEnabled = false;
this._updateCaretPositionId = 0;
this._currentFocusWindow = null;
this._originalWindowY = null;
this._animFocusedWindow = null;
this._delayedAnimFocusWindow = null;
this._enableKeyboard = false; // a11y settings value
this._enabled = false; // enabled state (by setting or device type)
@ -510,6 +575,14 @@ var Keyboard = new Lang.Class({
this._lastDeviceId = null;
this._suggestions = null;
this._focusTracker = new FocusTracker();
this._focusTracker.connect('position-changed', this._onFocusPositionChanged.bind(this));
this._focusTracker.connect('reset', () => {
this._delayedAnimFocusWindow = null;
this._animFocusedWindow = null;
this._oskFocusWindow = null;
});
Meta.get_backend().connect('last-device-changed',
(backend, deviceId) => {
let manager = Clutter.DeviceManager.get_default();
@ -532,102 +605,15 @@ var Keyboard = new Lang.Class({
this._keyboardRestingId = 0;
Main.layoutManager.connect('monitors-changed', this._relayout.bind(this));
//Main.inputMethod.connect('cursor-location-changed', (o, rect) => {
// if (this._keyboardVisible) {
// let currentWindow = global.screen.get_display().focus_window;
// this.setCursorLocation(currentWindow, rect.get_x(), rect.get_y(),
// rect.get_width(), rect.get_height());
// }
//});
},
get visible() {
return this._keyboardVisible;
},
_setCaretTrackerEnabled(enabled) {
if (this._caretTrackingEnabled == enabled)
return;
this._caretTrackingEnabled = enabled;
if (enabled) {
this._focusCaretTracker.registerFocusListener();
this._focusCaretTracker.registerCaretListener();
} else {
this._focusCaretTracker.deregisterFocusListener();
this._focusCaretTracker.deregisterCaretListener();
}
},
_updateCaretPosition(accessible) {
if (this._updateCaretPositionId)
GLib.source_remove(this._updateCaretPositionId);
if (!this._keyboardRequested)
return;
this._updateCaretPositionId = GLib.idle_add(GLib.PRIORITY_DEFAULT_IDLE, () => {
this._updateCaretPositionId = 0;
let currentWindow = global.screen.get_display().focus_window;
if (!currentWindow) {
this.setCursorLocation(null);
return GLib.SOURCE_REMOVE;
}
let windowRect = currentWindow.get_frame_rect();
let text = accessible.get_text_iface();
let component = accessible.get_component_iface();
try {
let caretOffset = text.get_caret_offset();
let caretRect = text.get_character_extents(caretOffset, Atspi.CoordType.WINDOW);
let focusRect = component.get_extents(Atspi.CoordType.WINDOW);
if (caretRect.width == 0 && caretRect.height == 0)
caretRect = focusRect;
this.setCursorLocation(currentWindow, caretRect.x, caretRect.y, caretRect.width, caretRect.height);
} catch (e) {
log('Error updating caret position for OSK: ' + e.message);
}
return GLib.SOURCE_REMOVE;
});
GLib.Source.set_name_by_id(this._updateCaretPositionId, '[gnome-shell] this._updateCaretPosition');
},
_focusIsTextEntry(accessible) {
try {
let role = accessible.get_role();
let stateSet = accessible.get_state_set();
return stateSet.contains(Atspi.StateType.EDITABLE) || role == Atspi.Role.TERMINAL;
} catch (e) {
log('Error determining accessible role: ' + e.message);
return false;
}
},
_onFocusChanged(caretTracker, event) {
let accessible = event.source;
if (!this._focusIsTextEntry(accessible))
return;
let focused = event.detail1 != 0;
if (focused) {
this._currentAccessible = accessible;
this._updateCaretPosition(accessible);
this.show(Main.layoutManager.focusIndex);
} else if (this._currentAccessible == accessible) {
this._currentAccessible = null;
this.hide();
}
},
_onCaretMoved(caretTracker, event) {
let accessible = event.source;
if (this._currentAccessible == accessible)
this._updateCaretPosition(accessible);
_onFocusPositionChanged(focusTracker) {
let rect = focusTracker.getCurrentRect();
this.setCursorLocation(focusTracker.currentWindow, rect.x, rect.y, rect.width, rect.height);
},
_lastDeviceIsTouchscreen() {
@ -650,8 +636,6 @@ var Keyboard = new Lang.Class({
if (!this._enabled && !this._keyboardController)
return;
this._setCaretTrackerEnabled(this._enabled);
if (this._enabled && !this._keyboardController)
this._setupKeyboard();
else if (!this._enabled)
@ -936,9 +920,11 @@ var Keyboard = new Lang.Class({
},
_relayout() {
if (this.actor == null)
return;
let monitor = Main.layoutManager.keyboardMonitor;
if (this.actor == null || monitor == null)
return;
let maxHeight = monitor.height / 3;
this.actor.width = monitor.width;
this.actor.height = maxHeight;
@ -1027,11 +1013,14 @@ var Keyboard = new Lang.Class({
if (!this._keyboardRequested)
return;
if (this._currentAccessible)
this._updateCaretPosition(this._currentAccessible);
Main.layoutManager.keyboardIndex = monitor;
this._relayout();
Main.layoutManager.showKeyboard();
if (this._delayedAnimFocusWindow) {
this._setAnimationWindow(this._delayedAnimFocusWindow);
this._delayedAnimFocusWindow = null;
}
},
hide() {
@ -1102,8 +1091,9 @@ var Keyboard = new Lang.Class({
window.move_frame(true, frameRect.x, frameRect.y);
},
_animateWindow(window, show, deltaY) {
_animateWindow(window, show) {
let windowActor = window.get_compositor_private();
let deltaY = Main.layoutManager.keyboardBox.height;
if (!windowActor)
return;
@ -1124,35 +1114,39 @@ var Keyboard = new Lang.Class({
}
},
setCursorLocation(window, x, y , w, h) {
if (window == this._oskFocusWindow)
_setAnimationWindow(window) {
if (this._animFocusedWindow == window)
return;
if (this._oskFocusWindow) {
let display = global.screen.get_display();
if (this._animFocusedWindow)
this._animateWindow(this._animFocusedWindow, false);
if (window)
this._animateWindow(window, true);
if (display.get_grab_op() == Meta.GrabOp.NONE ||
display.get_focus_window() != this._oskFocusWindow)
this._animateWindow(this._oskFocusWindow, false, this._oskFocusWindowDelta);
this._animFocusedWindow = window;
},
this._oskFocusWindow = null;
this._oskFocusWindowDelta = null;
}
setCursorLocation(window, x, y , w, h) {
let monitor = Main.layoutManager.keyboardMonitor;
if (window) {
let monitor = Main.layoutManager.keyboardMonitor;
if (window && monitor) {
let keyboardHeight = Main.layoutManager.keyboardBox.height;
let frameRect = window.get_frame_rect();
let windowActor = window.get_compositor_private();
let delta = 0;
let focusObscured = false;
if (frameRect.y + y + h >= monitor.height - keyboardHeight)
delta = keyboardHeight;
this._animateWindow(window, true, delta);
this._oskFocusWindow = window;
this._oskFocusWindowDelta = delta;
if (y + h >= monitor.y + monitor.height - keyboardHeight) {
if (this._keyboardVisible)
this._setAnimationWindow(window);
else
this._delayedAnimFocusWindow = window;
} else if (y < keyboardHeight) {
this._delayedAnimFocusWindow = null;
this._setAnimationWindow(null);
}
} else {
this._setAnimationWindow(null);
}
this._oskFocusWindow = window;
},
});

View File

@ -109,7 +109,7 @@ var MonitorConstraint = new Lang.Class({
if (!this._workareasChangedId) {
this._workareasChangedId =
global.screen.connect('workareas-changed', () => {
global.display.connect('workareas-changed', () => {
if (this._workArea)
this.actor.queue_relayout();
});
@ -120,7 +120,7 @@ var MonitorConstraint = new Lang.Class({
this._monitorsChangedId = 0;
if (this._workareasChangedId)
global.screen.disconnect(this._workareasChangedId);
global.display.disconnect(this._workareasChangedId);
this._workareasChangedId = 0;
}
@ -142,7 +142,8 @@ var MonitorConstraint = new Lang.Class({
let rect;
if (this._workArea) {
let ws = global.screen.get_workspace_by_index(0);
let workspaceManager = global.workspace_manager;
let ws = workspaceManager.get_workspace_by_index(0);
rect = ws.get_work_area_for_monitor(index);
} else {
rect = Main.layoutManager.monitors[index];
@ -164,7 +165,7 @@ var Monitor = new Lang.Class({
},
get inFullscreen() {
return global.screen.get_monitor_in_fullscreen(this.index);
return global.display.get_monitor_in_fullscreen(this.index);
}
})
@ -203,6 +204,7 @@ var LayoutManager = new Lang.Class({
// Set up stage hierarchy to group all UI actors under one container.
this.uiGroup = new Shell.GenericContainer({ name: 'uiGroup' });
this.uiGroup.set_flags(Clutter.ActorFlags.NO_LAYOUT);
this.uiGroup.connect('allocate', (actor, box, flags) => {
let children = actor.get_children();
for (let i = 0; i < children.length; i++)
@ -259,7 +261,7 @@ var LayoutManager = new Lang.Class({
global.stage.remove_actor(global.top_window_group);
this.uiGroup.add_actor(global.top_window_group);
let feedbackGroup = Meta.get_feedback_group_for_screen(global.screen);
let feedbackGroup = Meta.get_feedback_group_for_display(global.display);
global.stage.remove_actor(feedbackGroup);
this.uiGroup.add_actor(feedbackGroup);
@ -269,14 +271,19 @@ var LayoutManager = new Lang.Class({
this._bgManagers = [];
// Need to update struts on new workspaces when they are added
global.screen.connect('notify::n-workspaces',
this._queueUpdateRegions.bind(this));
global.screen.connect('restacked',
this._windowsRestacked.bind(this));
global.screen.connect('monitors-changed',
this._monitorsChanged.bind(this));
global.screen.connect('in-fullscreen-changed',
this._updateFullscreen.bind(this));
let workspaceManager = global.workspace_manager;
workspaceManager.connect('notify::n-workspaces',
this._queueUpdateRegions.bind(this));
let display = global.display;
display.connect('restacked',
this._windowsRestacked.bind(this));
display.connect('in-fullscreen-changed',
this._updateFullscreen.bind(this));
let monitorManager = Meta.MonitorManager.get();
monitorManager.connect('monitors-changed',
this._monitorsChanged.bind(this));
this._monitorsChanged();
// NVIDIA drivers don't preserve FBO contents across
@ -319,12 +326,12 @@ var LayoutManager = new Lang.Class({
},
_updateMonitors() {
let screen = global.screen;
let display = global.display;
this.monitors = [];
let nMonitors = screen.get_n_monitors();
let nMonitors = display.get_n_monitors();
for (let i = 0; i < nMonitors; i++)
this.monitors.push(new Monitor(i, screen.get_monitor_geometry(i)));
this.monitors.push(new Monitor(i, display.get_monitor_geometry(i)));
if (nMonitors == 0) {
this.primaryIndex = this.bottomIndex = -1;
@ -333,7 +340,7 @@ var LayoutManager = new Lang.Class({
} else {
// If there are monitors below the primary, then we need
// to split primary from bottom.
this.primaryIndex = this.bottomIndex = screen.get_primary_monitor();
this.primaryIndex = this.bottomIndex = display.get_primary_monitor();
for (let i = 0; i < this.monitors.length; i++) {
let monitor = this.monitors[i];
if (this._isAboveOrBelowPrimary(monitor)) {
@ -538,7 +545,7 @@ var LayoutManager = new Lang.Class({
},
get currentMonitor() {
let index = global.screen.get_current_monitor();
let index = global.display.get_current_monitor();
return this.monitors[index];
},
@ -557,6 +564,8 @@ var LayoutManager = new Lang.Class({
},
get focusMonitor() {
if (this.focusIndex < 0)
return null;
return this.monitors[this.focusIndex];
},
@ -909,7 +918,8 @@ var LayoutManager = new Lang.Class({
getWorkAreaForMonitor(monitorIndex) {
// Assume that all workspaces will have the same
// struts and pick the first one.
let ws = global.screen.get_workspace_by_index(0);
let workspaceManager = global.workspace_manager;
let ws = workspaceManager.get_workspace_by_index(0);
return ws.get_work_area_for_monitor(monitorIndex);
},
@ -919,7 +929,7 @@ var LayoutManager = new Lang.Class({
let [x, y] = actor.get_transformed_position();
let [w, h] = actor.get_transformed_size();
let rect = new Meta.Rectangle({ x: x, y: y, width: w, height: h });
return global.screen.get_monitor_index_for_rect(rect);
return global.display.get_monitor_index_for_rect(rect);
},
findMonitorForActor(actor) {
@ -1052,9 +1062,9 @@ var LayoutManager = new Lang.Class({
global.set_stage_input_region(rects);
this._isPopupWindowVisible = isPopupMenuVisible;
let screen = global.screen;
for (let w = 0; w < screen.n_workspaces; w++) {
let workspace = screen.get_workspace_by_index(w);
let workspaceManager = global.workspace_manager;
for (let w = 0; w < workspaceManager.n_workspaces; w++) {
let workspace = workspaceManager.get_workspace_by_index(w);
workspace.set_builtin_struts(struts);
}

View File

@ -19,7 +19,6 @@ const MagnifierDBus = imports.ui.magnifierDBus;
const Params = imports.misc.params;
const PointerWatcher = imports.ui.pointerWatcher;
var MOUSE_POLL_FREQUENCY = 50;
var CROSSHAIRS_CLIP_SIZE = [100, 100];
var NO_CHANGE = 0.0;
@ -62,7 +61,7 @@ var Magnifier = new Lang.Class({
this._zoomRegions = [];
// Create small clutter tree for the magnified mouse.
let cursorTracker = Meta.CursorTracker.get_for_screen(global.screen);
let cursorTracker = Meta.CursorTracker.get_for_display(global.display);
this._mouseSprite = new Clutter.Texture();
Shell.util_cursor_tracker_to_clutter(cursorTracker, this._mouseSprite);
this._cursorRoot = new Clutter.Actor();
@ -117,10 +116,10 @@ var Magnifier = new Lang.Class({
if (isActive != activate) {
if (activate) {
Meta.disable_unredirect_for_screen(global.screen);
Meta.disable_unredirect_for_display(global.display);
this.startTrackingMouse();
} else {
Meta.enable_unredirect_for_screen(global.screen);
Meta.enable_unredirect_for_display(global.display);
this.stopTrackingMouse();
}
}
@ -152,8 +151,10 @@ var Magnifier = new Lang.Class({
* Turn on mouse tracking, if not already doing so.
*/
startTrackingMouse() {
if (!this._pointerWatch)
this._pointerWatch = PointerWatcher.getPointerWatcher().addWatch(MOUSE_POLL_FREQUENCY, this.scrollToMousePos.bind(this));
if (!this._pointerWatch) {
let interval = 1000 / Clutter.get_default_frame_rate();
this._pointerWatch = PointerWatcher.getPointerWatcher().addWatch(interval, this.scrollToMousePos.bind(this));
}
},
/**

View File

@ -429,7 +429,7 @@ function pushModal(actor, params) {
log('pushModal: invocation of begin_modal failed');
return false;
}
Meta.disable_unredirect_for_screen(global.screen);
Meta.disable_unredirect_for_display(global.display);
}
modalCount += 1;
@ -528,7 +528,7 @@ function popModal(actor, timestamp) {
layoutManager.modalEnded();
global.end_modal(timestamp);
Meta.enable_unredirect_for_screen(global.screen);
Meta.enable_unredirect_for_display(global.display);
actionMode = Shell.ActionMode.NORMAL;
}
@ -556,14 +556,15 @@ function openRunDialog() {
* and switching out of the overview if it's currently active
*/
function activateWindow(window, time, workspaceNum) {
let activeWorkspaceNum = global.screen.get_active_workspace_index();
let workspaceManager = global.workspace_manager;
let activeWorkspaceNum = workspaceManager.get_active_workspace_index();
let windowWorkspaceNum = (workspaceNum !== undefined) ? workspaceNum : window.get_workspace().index();
if (!time)
time = global.get_current_time();
if (windowWorkspaceNum != activeWorkspaceNum) {
let workspace = global.screen.get_workspace_by_index(windowWorkspaceNum);
let workspace = workspaceManager.get_workspace_by_index(windowWorkspaceNum);
workspace.activate_with_focus(window, time);
} else {
window.activate(time);

View File

@ -27,6 +27,7 @@ function _fixMarkup(text, allowMarkup) {
// Support <b>, <i>, and <u>, escape anything else
// so it displays as raw markup.
// Ref: https://developer.gnome.org/notification-spec/#markup
_text = _text.replace(/<(?!\/?[biu]>)/g, '&lt;');
try {
@ -95,10 +96,10 @@ var URLHighlighter = new Lang.Class({
let urlId = this._findUrlAtPos(event);
if (urlId != -1 && !this._cursorChanged) {
global.screen.set_cursor(Meta.Cursor.POINTING_HAND);
global.display.set_cursor(Meta.Cursor.POINTING_HAND);
this._cursorChanged = true;
} else if (urlId == -1) {
global.screen.set_cursor(Meta.Cursor.DEFAULT);
global.display.set_cursor(Meta.Cursor.DEFAULT);
this._cursorChanged = false;
}
return Clutter.EVENT_PROPAGATE;
@ -109,7 +110,7 @@ var URLHighlighter = new Lang.Class({
if (this._cursorChanged) {
this._cursorChanged = false;
global.screen.set_cursor(Meta.Cursor.DEFAULT);
global.display.set_cursor(Meta.Cursor.DEFAULT);
}
return Clutter.EVENT_PROPAGATE;
});

View File

@ -315,10 +315,10 @@ var NotificationApplicationPolicy = new Lang.Class({
// You can add a secondary icon to the banner with 'secondaryGIcon'. There
// is no fallback for this icon.
//
// If @params contains 'bannerMarkup', with the value %true, then
// the corresponding element is assumed to use pango markup. If the
// parameter is not present for an element, then anything that looks
// like markup in that element will appear literally in the output.
// If @params contains 'bannerMarkup', with the value %true, a subset (<b>,
// <i> and <u>) of the markup in [1] will be interpreted within @banner. If
// the parameter is not present, then anything that looks like markup
// in @banner will appear literally in the output.
//
// If @params contains a 'clear' parameter with the value %true, then
// the content and the action area of the notification will be cleared.
@ -328,6 +328,8 @@ var NotificationApplicationPolicy = new Lang.Class({
// If @params contains 'soundName' or 'soundFile', the corresponding
// event sound is played when the notification is shown (if the policy for
// @source allows playing sounds).
//
// [1] https://developer.gnome.org/notification-spec/#markup
var Notification = new Lang.Class({
Name: 'Notification',
@ -915,7 +917,7 @@ var MessageTray = new Lang.Class({
Main.layoutManager.addChrome(this.actor, { affectsInputRegion: false });
Main.layoutManager.trackChrome(this._bannerBin, { affectsInputRegion: true });
global.screen.connect('in-fullscreen-changed', this._updateState.bind(this));
global.display.connect('in-fullscreen-changed', this._updateState.bind(this));
Main.sessionMode.connect('updated', this._sessionUpdated.bind(this));

View File

@ -116,7 +116,7 @@ var ModalDialog = new Lang.Class({
if (onPrimary)
this._monitorConstraint.primary = true;
else
this._monitorConstraint.index = global.screen.get_current_monitor();
this._monitorConstraint.index = global.display.get_current_monitor();
this.state = State.OPENING;

View File

@ -831,8 +831,10 @@ var GtkNotificationDaemon = new Lang.Class({
let source;
try {
source = this._ensureAppSource(appId);
} catch(e if e instanceof InvalidAppError) {
return;
} catch(e) {
if (e instanceof InvalidAppError)
return;
throw e;
}
notifications.forEach(([notificationId, notification]) => {
@ -863,9 +865,12 @@ var GtkNotificationDaemon = new Lang.Class({
let source;
try {
source = this._ensureAppSource(appId);
} catch(e if e instanceof InvalidAppError) {
invocation.return_dbus_error('org.gtk.Notifications.InvalidApp', 'The app by ID "%s" could not be found'.format(appId));
return;
} catch(e) {
if (e instanceof InvalidAppError) {
invocation.return_dbus_error('org.gtk.Notifications.InvalidApp', 'The app by ID "%s" could not be found'.format(appId));
return;
}
throw e;
}
let timestamp = GLib.DateTime.new_now_local().to_unix();

View File

@ -32,7 +32,7 @@ var OsdMonitorLabel = new Lang.Class({
Main.uiGroup.set_child_above_sibling(this._actor, null);
this._position();
Meta.disable_unredirect_for_screen(global.screen);
Meta.disable_unredirect_for_display(global.display);
},
_position() {
@ -48,7 +48,7 @@ var OsdMonitorLabel = new Lang.Class({
destroy() {
this._actor.destroy();
Meta.enable_unredirect_for_screen(global.screen);
Meta.enable_unredirect_for_display(global.display);
}
});

View File

@ -4,6 +4,7 @@ const Clutter = imports.gi.Clutter;
const GLib = imports.gi.GLib;
const St = imports.gi.St;
const BarLevel = imports.ui.barLevel;
const Lang = imports.lang;
const Layout = imports.ui.layout;
const Main = imports.ui.main;
@ -17,16 +18,18 @@ var LEVEL_ANIMATION_TIME = 0.1;
var LevelBar = new Lang.Class({
Name: 'LevelBar',
Extends: BarLevel.BarLevel,
_init() {
this._level = 0;
this._maxLevel = 100;
this.actor = new St.Bin({ style_class: 'level',
x_align: St.Align.START,
y_fill: true });
this._bar = new St.Widget({ style_class: 'level-bar' });
let params = {
styleClass: 'level',
}
this.parent(this._level, params);
this.actor.set_child(this._bar);
this.actor.accessible_name = _("Volume");
this.actor.connect('notify::width', () => { this.level = this.level; });
},
@ -36,12 +39,19 @@ var LevelBar = new Lang.Class({
},
set level(value) {
this._level = Math.max(0, Math.min(value, 100));
this._level = Math.max(0, Math.min(value, this._maxLevel));
let alloc = this.actor.get_allocation_box();
let newWidth = Math.round((alloc.x2 - alloc.x1) * this._level / 100);
if (newWidth != this._bar.width)
this._bar.width = newWidth;
this.setValue(this._level / 100);
},
get maxLevel() {
return this._maxLevel;
},
set maxLevel(value) {
this._maxLevel = Math.max(100, value);
this.setMaximumValue(this._maxLevel / 100);
}
});
@ -140,12 +150,18 @@ var OsdWindow = new Lang.Class({
}
},
setMaxLevel(maxLevel) {
if (maxLevel === undefined)
maxLevel = 100;
this._level.maxLevel = maxLevel;
},
show() {
if (!this._icon.gicon)
return;
if (!this.actor.visible) {
Meta.disable_unredirect_for_screen(global.screen);
Meta.disable_unredirect_for_display(global.display);
this.actor.show();
this.actor.opacity = 0;
this.actor.get_parent().set_child_above_sibling(this.actor, null);
@ -179,7 +195,7 @@ var OsdWindow = new Lang.Class({
transition: 'easeOutQuad',
onComplete: () => {
this._reset();
Meta.enable_unredirect_for_screen(global.screen);
Meta.enable_unredirect_for_display(global.display);
}
});
return GLib.SOURCE_REMOVE;
@ -189,6 +205,7 @@ var OsdWindow = new Lang.Class({
this.actor.hide();
this.setLabel(null);
this.setLevel(null);
this.setMaxLevel(null);
},
_relayout() {
@ -204,7 +221,7 @@ var OsdWindow = new Lang.Class({
let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor;
this._icon.icon_size = popupSize / (2 * scaleFactor);
this._box.translation_y = monitor.height / 4;
this._box.translation_y = Math.round(monitor.height / 4);
this._boxConstraint.minSize = popupSize;
}
});
@ -233,24 +250,25 @@ var OsdWindowManager = new Lang.Class({
this._osdWindows.length = Main.layoutManager.monitors.length;
},
_showOsdWindow(monitorIndex, icon, label, level) {
_showOsdWindow(monitorIndex, icon, label, level, maxLevel) {
this._osdWindows[monitorIndex].setIcon(icon);
this._osdWindows[monitorIndex].setLabel(label);
this._osdWindows[monitorIndex].setLevel(level);
this._osdWindows[monitorIndex].setMaxLevel(maxLevel);
this._osdWindows[monitorIndex].show();
},
show(monitorIndex, icon, label, level) {
show(monitorIndex, icon, label, level, maxLevel) {
if (monitorIndex != -1) {
for (let i = 0; i < this._osdWindows.length; i++) {
if (i == monitorIndex)
this._showOsdWindow(i, icon, label, level);
this._showOsdWindow(i, icon, label, level, maxLevel);
else
this._osdWindows[i].cancel();
}
} else {
for (let i = 0; i < this._osdWindows.length; i++)
this._showOsdWindow(i, icon, label, level);
this._showOsdWindow(i, icon, label, level, maxLevel);
}
},

View File

@ -157,7 +157,7 @@ var Overview = new Lang.Class({
Main.xdndHandler.connect('drag-begin', this._onDragBegin.bind(this));
Main.xdndHandler.connect('drag-end', this._onDragEnd.bind(this));
global.screen.connect('restacked', this._onRestacked.bind(this));
global.display.connect('restacked', this._onRestacked.bind(this));
this._windowSwitchTimeoutId = 0;
this._windowSwitchTimestamp = 0;
@ -286,7 +286,8 @@ var Overview = new Lang.Class({
DND.addDragMonitor(this._dragMonitor);
// Remember the workspace we started from
this._lastActiveWorkspaceIndex = global.screen.get_active_workspace_index();
let workspaceManager = global.workspace_manager;
this._lastActiveWorkspaceIndex = workspaceManager.get_active_workspace_index();
},
_onDragEnd(time) {
@ -296,7 +297,8 @@ var Overview = new Lang.Class({
// we have to go back to where we started and hide
// the overview
if (this._shown) {
global.screen.get_workspace_by_index(this._lastActiveWorkspaceIndex).activate(time);
let workspaceManager = global.workspace_manager;
workspaceManager.get_workspace_by_index(this._lastActiveWorkspaceIndex).activate(time);
this.hide();
}
this._resetWindowSwitchTimeout();
@ -317,9 +319,9 @@ var Overview = new Lang.Class({
let display = Gdk.Display.get_default();
let deviceManager = display.get_device_manager();
let pointer = deviceManager.get_client_pointer();
let [screen, pointerX, pointerY] = pointer.get_position();
let [gdkScreen, pointerX, pointerY] = pointer.get_position();
pointer.warp(screen, pointerX, pointerY);
pointer.warp(gdkScreen, pointerX, pointerY);
},
_onDragMotion(dragEvent) {
@ -393,10 +395,8 @@ var Overview = new Lang.Class({
if (!Main.layoutManager.primaryMonitor)
return;
let workArea = Main.layoutManager.getWorkAreaForMonitor(Main.layoutManager.primaryIndex);
this._coverPane.set_position(0, workArea.y);
this._coverPane.set_size(workArea.width, workArea.height);
this._coverPane.set_position(0, 0);
this._coverPane.set_size(global.screen_width, global.screen_height);
this._updateBackgrounds();
},
@ -550,7 +550,7 @@ var Overview = new Lang.Class({
this.visibleTarget = true;
this._activationTime = GLib.get_monotonic_time() / GLib.USEC_PER_SEC;
Meta.disable_unredirect_for_screen(global.screen);
Meta.disable_unredirect_for_display(global.display);
this.viewSelector.show();
this._overview.opacity = 0;
@ -635,7 +635,7 @@ var Overview = new Lang.Class({
_hideDone() {
// Re-enable unredirection
Meta.enable_unredirect_for_screen(global.screen);
Meta.enable_unredirect_for_display(global.display);
this.viewSelector.hide();
this._desktopFade.hide();

View File

@ -253,13 +253,23 @@ var ThumbnailsSlider = new Lang.Class({
this.actor.add_actor(this._thumbnailsBox.actor);
Main.layoutManager.connect('monitors-changed', this._updateSlide.bind(this));
global.workspace_manager.connect('active-workspace-changed',
this._updateSlide.bind(this));
global.workspace_manager.connect('notify::n-workspaces',
this._updateSlide.bind(this));
this.actor.connect('notify::hover', this._updateSlide.bind(this));
this._thumbnailsBox.actor.bind_property('visible', this.actor, 'visible', GObject.BindingFlags.SYNC_CREATE);
},
_getAlwaysZoomOut() {
// Always show the pager on hover or during a drag
let alwaysZoomOut = this.actor.hover || this._inDrag;
// Always show the pager on hover, during a drag, or if workspaces are
// actually used, e.g. there are windows on any non-active workspace
let workspaceManager = global.workspace_manager;
let alwaysZoomOut = this.actor.hover ||
this._inDrag ||
!Meta.prefs_get_dynamic_workspaces() ||
workspaceManager.n_workspaces > 2 ||
workspaceManager.get_active_workspace_index() != 0;
if (!alwaysZoomOut) {
let monitors = Main.layoutManager.monitors;
@ -284,6 +294,11 @@ var ThumbnailsSlider = new Lang.Class({
return child.get_theme_node().get_length('visible-width');
},
_onDragEnd() {
this.actor.sync_hover();
this.parent();
},
_getSlide() {
if (!this._visible)
return 0;

View File

@ -313,6 +313,8 @@ var PadDiagram = new Lang.Class({
_init(params) {
let file = Gio.File.new_for_uri('resource:///org/gnome/shell/theme/pad-osd.css');
let [success, css, etag] = file.load_contents(null);
if (css instanceof Uint8Array)
css = imports.byteArray.toString(css);
this._curEdited = null;
this._prevEdited = null;
this._css = css;

View File

@ -265,7 +265,8 @@ var AppMenuButton = new Lang.Class({
},
_findTargetApp() {
let workspace = global.screen.get_active_workspace();
let workspaceManager = global.workspace_manager;
let workspace = workspaceManager.get_active_workspace();
let tracker = Shell.WindowTracker.get_default();
let focusedApp = tracker.focus_app;
if (focusedApp && focusedApp.is_on_workspace(workspace))
@ -709,6 +710,7 @@ var AggregateMenu = new Lang.Class({
this._bluetooth = null;
}
this._remoteAccess = new imports.ui.status.remoteAccess.RemoteAccessApplet();
this._power = new imports.ui.status.power.Indicator();
this._rfkill = new imports.ui.status.rfkill.Indicator();
this._volume = new imports.ui.status.volume.Indicator();
@ -729,6 +731,7 @@ var AggregateMenu = new Lang.Class({
if (this._bluetooth) {
this._indicators.add_child(this._bluetooth.indicators);
}
this._indicators.add_child(this._remoteAccess.indicators);
this._indicators.add_child(this._rfkill.indicators);
this._indicators.add_child(this._volume.indicators);
this._indicators.add_child(this._power.indicators);
@ -743,6 +746,7 @@ var AggregateMenu = new Lang.Class({
if (this._bluetooth) {
this.menu.addMenuItem(this._bluetooth.menu);
}
this.menu.addMenuItem(this._remoteAccess.menu);
this.menu.addMenuItem(this._location.menu);
this.menu.addMenuItem(this._rfkill.menu);
this.menu.addMenuItem(this._power.menu);
@ -796,6 +800,7 @@ var Panel = new Lang.Class({
this.actor.connect('get-preferred-height', this._getPreferredHeight.bind(this));
this.actor.connect('allocate', this._allocate.bind(this));
this.actor.connect('button-press-event', this._onButtonPress.bind(this));
this.actor.connect('touch-event', this._onButtonPress.bind(this));
this.actor.connect('key-press-event', this._onKeyPress.bind(this));
Main.overview.connect('showing', () => {
@ -818,7 +823,7 @@ var Panel = new Lang.Class({
global.window_group.connect('actor-removed', this._onWindowActorRemoved.bind(this));
global.window_manager.connect('switch-workspace', this._updateSolidStyle.bind(this));
global.screen.connect('workareas-changed', () => { this.actor.queue_relayout(); });
global.display.connect('workareas-changed', () => { this.actor.queue_relayout(); });
this._updatePanel();
},
@ -939,8 +944,13 @@ var Panel = new Lang.Class({
if (event.get_source() != actor)
return Clutter.EVENT_PROPAGATE;
let button = event.get_button();
if (button != 1)
let type = event.type();
let isPress = type == Clutter.EventType.BUTTON_PRESS;
if (!isPress && type != Clutter.EventType.TOUCH_BEGIN)
return Clutter.EVENT_PROPAGATE;
let button = isPress ? event.get_button() : -1;
if (isPress && button != 1)
return Clutter.EVENT_PROPAGATE;
let focusWindow = global.display.focus_window;
@ -961,8 +971,7 @@ var Panel = new Lang.Class({
if (!allowDrag)
return Clutter.EVENT_PROPAGATE;
global.display.begin_grab_op(global.screen,
dragWindow,
global.display.begin_grab_op(dragWindow,
Meta.GrabOp.MOVING,
false, /* pointer grab */
true, /* frame action */
@ -977,7 +986,7 @@ var Panel = new Lang.Class({
_onKeyPress(actor, event) {
let symbol = event.get_key_symbol();
if (symbol == Clutter.KEY_Escape) {
global.screen.focus_default_window(event.get_time());
global.display.focus_default_window(event.get_time());
return Clutter.EVENT_STOP;
}
@ -1075,7 +1084,8 @@ var Panel = new Lang.Class({
return;
/* Get all the windows in the active workspace that are in the primary monitor and visible */
let activeWorkspace = global.screen.get_active_workspace();
let workspaceManager = global.workspace_manager;
let activeWorkspace = workspaceManager.get_active_workspace();
let windows = activeWorkspace.list_windows().filter(metaWindow => {
return metaWindow.is_on_primary_monitor() &&
metaWindow.showing_on_its_workspace() &&

View File

@ -141,8 +141,17 @@ var PopupBaseMenuItem = new Lang.Class({
},
_onKeyPressEvent(actor, event) {
let symbol = event.get_key_symbol();
let state = event.get_state();
// if user has a modifier down (except capslock)
// then don't handle the key press here
state &= ~Clutter.ModifierType.LOCK_MASK;
state &= Clutter.ModifierType.MODIFIER_MASK;
if (state)
return Clutter.EVENT_PROPAGATE;
let symbol = event.get_key_symbol();
if (symbol == Clutter.KEY_space || symbol == Clutter.KEY_Return) {
this.activate(event);
return Clutter.EVENT_STOP;

View File

@ -295,7 +295,7 @@ var RemoteSearchProvider = new Lang.Class({
name: metas[i]['name'],
description: metas[i]['description'],
createIcon: size => {
this.createIcon(size, metas[i]);
return this.createIcon(size, metas[i]);
},
clipboardText: metas[i]['clipboardText'] });
}

View File

@ -62,7 +62,11 @@ var RunDialog = new Lang.Class({
'rt': () => {
Main.reloadThemeResource();
Main.loadTheme();
}
},
'check_cloexec_fds': () => {
Shell.util_check_cloexec_fds();
},
};
@ -114,18 +118,16 @@ var RunDialog = new Lang.Class({
this._history = new History.HistoryManager({ gsettingsKey: HISTORY_KEY,
entry: this._entryText });
this._entryText.connect('activate', (o) => {
this.popModal();
this._run(o.get_text(),
Clutter.get_current_event().get_state() & Clutter.ModifierType.CONTROL_MASK);
if (!this._commandError ||
!this.pushModal())
this.close();
});
this._entryText.connect('key-press-event', (o, e) => {
let symbol = e.get_key_symbol();
if (symbol == Clutter.Return || symbol == Clutter.KP_Enter) {
this.popModal();
this._run(o.get_text(),
e.get_state() & Clutter.ModifierType.CONTROL_MASK);
if (!this._commandError ||
!this.pushModal())
this.close();
return Clutter.EVENT_STOP;
}
if (symbol == Clutter.Tab) {
let text = o.get_text();
let prefix;
@ -172,9 +174,10 @@ var RunDialog = new Lang.Class({
if (name.slice(0, text.length) == text)
results.push(name);
}
} catch (e if (!e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.NOT_FOUND) &&
!e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.NOT_DIRECTORY))) {
log(e);
} catch (e) {
if (!e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.NOT_FOUND) &&
!e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.NOT_DIRECTORY))
log(e);
} finally {
return results;
}

View File

@ -570,7 +570,7 @@ var ScreenShield = new Lang.Class({
this._shortLightbox.connect('shown', this._onShortLightboxShown.bind(this));
this.idleMonitor = Meta.IdleMonitor.get_core();
this._cursorTracker = Meta.CursorTracker.get_for_screen(global.screen);
this._cursorTracker = Meta.CursorTracker.get_for_display(global.display);
this._syncInhibitor();
},

View File

@ -56,7 +56,7 @@ var ScreencastService = new Lang.Class({
let recorder = this._recorders.get(sender);
if (!recorder) {
recorder = new Shell.Recorder({ stage: global.stage,
screen: global.screen });
display: global.display });
recorder._watchNameId =
Gio.bus_watch_name(Gio.BusType.SESSION, sender, 0, null,
this._onNameVanished.bind(this));

View File

@ -55,6 +55,9 @@ const ScreenshotIface = '<node> \
<arg type="i" direction="in" name="width"/> \
<arg type="i" direction="in" name="height"/> \
</method> \
<method name="PickColor"> \
<arg type="a{sv}" direction="out" name="result"/> \
</method> \
</interface> \
</node>';
@ -72,10 +75,13 @@ var ScreenshotService = new Lang.Class({
Gio.DBus.session.own_name('org.gnome.Shell.Screenshot', Gio.BusNameOwnerFlags.REPLACE, null, null);
},
_createScreenshot(invocation) {
_createScreenshot(invocation, needsDisk=true) {
let lockedDown = false;
if (needsDisk)
lockedDown = this._lockdownSettings.get_boolean('disable-save-to-disk')
let sender = invocation.get_sender();
if (this._screenShooter.has(sender) ||
this._lockdownSettings.get_boolean('disable-save-to-disk')) {
if (this._screenShooter.has(sender) || lockedDown) {
invocation.return_value(GLib.Variant.new('(bs)', [false, '']));
return null;
}
@ -110,7 +116,7 @@ var ScreenshotService = new Lang.Class({
y + height <= global.screen_height;
},
_onScreenshotComplete(obj, result, area, filenameUsed, flash, invocation) {
_onScreenshotComplete(result, area, filenameUsed, flash, invocation) {
if (result) {
if (flash) {
let flashspot = new Flashspot(area);
@ -157,9 +163,15 @@ var ScreenshotService = new Lang.Class({
if (!screenshot)
return;
screenshot.screenshot_area (x, y, width, height, filename,
(obj, result, area, filenameUsed) => {
this._onScreenshotComplete(obj, result, area, filenameUsed,
flash, invocation);
(o, res) => {
try {
let [result, area, filenameUsed] =
screenshot.screenshot_area_finish(res);
this._onScreenshotComplete(result, area, filenameUsed,
flash, invocation);
} catch (e) {
invocation.return_gerror (e);
}
});
},
@ -169,9 +181,15 @@ var ScreenshotService = new Lang.Class({
if (!screenshot)
return;
screenshot.screenshot_window (include_frame, include_cursor, filename,
(obj, result, area, filenameUsed) => {
this._onScreenshotComplete(obj, result, area, filenameUsed,
flash, invocation);
(o, res) => {
try {
let [result, area, filenameUsed] =
screenshot.screenshot_window_finish(res);
this._onScreenshotComplete(result, area, filenameUsed,
flash, invocation);
} catch (e) {
invocation.return_gerror (e);
}
});
},
@ -181,9 +199,15 @@ var ScreenshotService = new Lang.Class({
if (!screenshot)
return;
screenshot.screenshot(include_cursor, filename,
(obj, result, area, filenameUsed) => {
this._onScreenshotComplete(obj, result, area, filenameUsed,
flash, invocation);
(o, res) => {
try {
let [result, area, filenameUsed] =
screenshot.screenshot_finish(res);
this._onScreenshotComplete(result, area, filenameUsed,
flash, invocation);
} catch (e) {
invocation.return_gerror (e);
}
});
},
@ -215,6 +239,34 @@ var ScreenshotService = new Lang.Class({
let flashspot = new Flashspot({ x : x, y : y, width: width, height: height});
flashspot.fire();
invocation.return_value(null);
},
PickColorAsync(params, invocation) {
let pickPixel = new PickPixel();
pickPixel.show();
pickPixel.connect('finished', (pickPixel, coords) => {
if (coords) {
let screenshot = this._createScreenshot(invocation, false);
if (!screenshot)
return;
screenshot.pick_color(...coords, (o, res) => {
let [success, color] = screenshot.pick_color_finish(res);
let { red, green, blue } = color;
let retval = GLib.Variant.new('(a{sv})', [{
color: GLib.Variant.new('(ddd)', [
red / 255.0,
green / 255.0,
blue / 255.0
])
}]);
this._removeShooterForSender(invocation.get_sender());
invocation.return_value(retval);
});
} else {
invocation.return_error_literal(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED,
"Operation was cancelled");
}
});
}
});
@ -261,7 +313,7 @@ var SelectArea = new Lang.Class({
onUngrab: this._onUngrab.bind(this) }))
return;
global.screen.set_cursor(Meta.Cursor.CROSSHAIR);
global.display.set_cursor(Meta.Cursor.CROSSHAIR);
Main.uiGroup.set_child_above_sibling(this._group, null);
this._group.visible = true;
},
@ -330,7 +382,7 @@ var SelectArea = new Lang.Class({
},
_onUngrab() {
global.screen.set_cursor(Meta.Cursor.DEFAULT);
global.display.set_cursor(Meta.Cursor.DEFAULT);
this.emit('finished', this._result);
GLib.idle_add(GLib.PRIORITY_DEFAULT, () => {
@ -341,6 +393,54 @@ var SelectArea = new Lang.Class({
});
Signals.addSignalMethods(SelectArea.prototype);
var PickPixel = new Lang.Class({
Name: 'PickPixel',
_init() {
this._result = null;
this._group = new St.Widget({ visible: false,
reactive: true });
Main.uiGroup.add_actor(this._group);
this._grabHelper = new GrabHelper.GrabHelper(this._group);
this._group.connect('button-release-event',
this._onButtonRelease.bind(this));
let constraint = new Clutter.BindConstraint({ source: global.stage,
coordinate: Clutter.BindCoordinate.ALL });
this._group.add_constraint(constraint);
},
show() {
if (!this._grabHelper.grab({ actor: this._group,
onUngrab: this._onUngrab.bind(this) }))
return;
global.display.set_cursor(Meta.Cursor.CROSSHAIR);
Main.uiGroup.set_child_above_sibling(this._group, null);
this._group.visible = true;
},
_onButtonRelease(actor, event) {
this._result = event.get_coords();
this._grabHelper.ungrab();
return Clutter.EVENT_PROPAGATE;
},
_onUngrab() {
global.display.set_cursor(Meta.Cursor.DEFAULT);
this.emit('finished', this._result);
GLib.idle_add(GLib.PRIORITY_DEFAULT, () => {
this._group.destroy();
return GLib.SOURCE_REMOVE;
});
}
});
Signals.addSignalMethods(PickPixel.prototype);
var FLASHSPOT_ANIMATION_OUT_TIME = 0.5; // seconds
var Flashspot = new Lang.Class({

View File

@ -133,7 +133,7 @@ function _callRemote(obj, method, ...args) {
* because of the normal X asynchronous mapping process, to actually wait
* until the window has been mapped and exposed, use waitTestWindows().
*/
function createTestWindow(width, height, params) {
function createTestWindow(params) {
params = Params.parse(params, { width: 640,
height: 480,
alpha: false,
@ -216,12 +216,14 @@ function _step(g, finish, onError) {
if (onError)
onError(err);
});
} catch (err if err instanceof StopIteration) {
if (finish)
finish();
} catch (err) {
if (onError)
onError(err);
if (err instanceof StopIteration) {
if (finish)
finish();
} else {
if (onError)
onError(err);
}
}
}

View File

@ -117,6 +117,8 @@ function _loadMode(file, info) {
let fileContent, success, tag, newMode;
try {
[success, fileContent, tag] = file.load_contents(null);
if (fileContent instanceof Uint8Array)
fileContent = imports.byteArray.toString(fileContent);
newMode = JSON.parse(fileContent);
} catch(e) {
return;

View File

@ -145,15 +145,20 @@ var GnomeShell = new Lang.Class({
for (let param in params)
params[param] = params[param].deep_unpack();
let monitorIndex = params['monitor'] || -1;
let label = params['label'] || undefined;
let level = params['level'] || undefined;
let { monitor: monitorIndex,
label,
level,
max_level: maxLevel,
icon: serializedIcon } = params;
if (monitorIndex === undefined)
monitorIndex = -1;
let icon = null;
if (params['icon'])
icon = Gio.Icon.new_for_string(params['icon']);
if (serializedIcon)
icon = Gio.Icon.new_for_string(serializedIcon);
Main.osdWindowManager.show(monitorIndex, icon, label, level);
Main.osdWindowManager.show(monitorIndex, icon, label, level, maxLevel);
},
FocusApp(id) {

View File

@ -7,55 +7,38 @@ const Lang = imports.lang;
const St = imports.gi.St;
const Signals = imports.signals;
const BarLevel = imports.ui.barLevel;
var SLIDER_SCROLL_STEP = 0.02; /* Slider scrolling step in % */
var Slider = new Lang.Class({
Name: "Slider",
Extends: BarLevel.BarLevel,
_init(value) {
if (isNaN(value))
// Avoid spreading NaNs around
throw TypeError('The slider value must be a number');
this._value = Math.max(Math.min(value, 1), 0);
this._sliderWidth = 0;
let params = {
styleClass: 'slider',
canFocus: true,
reactive: true,
accessibleRole: Atk.Role.SLIDER,
}
this.parent(value, params)
this.actor = new St.DrawingArea({ style_class: 'slider',
can_focus: true,
reactive: true,
accessible_role: Atk.Role.SLIDER });
this.actor.connect('repaint', this._sliderRepaint.bind(this));
this.actor.connect('button-press-event', this._startDragging.bind(this));
this.actor.connect('touch-event', this._touchDragging.bind(this));
this.actor.connect('scroll-event', this._onScrollEvent.bind(this));
this.actor.connect('key-press-event', this.onKeyPressEvent.bind(this));
this.actor.connect('allocation-changed', (actor, box) => {
this._sliderWidth = box.get_width();
});
this._releaseId = this._motionId = 0;
this._dragging = false;
this._customAccessible = St.GenericAccessible.new_for_actor(this.actor);
this.actor.set_accessible(this._customAccessible);
this._customAccessible.connect('get-current-value', this._getCurrentValue.bind(this));
this._customAccessible.connect('get-minimum-value', this._getMinimumValue.bind(this));
this._customAccessible.connect('get-maximum-value', this._getMaximumValue.bind(this));
this._customAccessible.connect('get-minimum-increment', this._getMinimumIncrement.bind(this));
this._customAccessible.connect('set-current-value', this._setCurrentValue.bind(this));
this.connect('value-changed', this._valueChanged.bind(this));
},
setValue(value) {
if (isNaN(value))
throw TypeError('The slider value must be a number');
_barLevelRepaint(area) {
this.parent(area);
this._value = Math.max(Math.min(value, 1), 0);
this.actor.queue_repaint();
},
_sliderRepaint(area) {
// Add handle
let cr = area.get_context();
let themeNode = area.get_theme_node();
let [width, height] = area.get_surface_size();
@ -66,41 +49,9 @@ var Slider = new Lang.Class({
let [hasHandleColor, handleBorderColor] =
themeNode.lookup_color('-slider-handle-border-color', false);
let sliderHeight = themeNode.get_length('-slider-height');
let sliderBorderWidth = themeNode.get_length('-slider-border-width');
let sliderBorderRadius = Math.min(width, sliderHeight) / 2;
let sliderBorderColor = themeNode.get_color('-slider-border-color');
let sliderColor = themeNode.get_color('-slider-background-color');
let sliderActiveBorderColor = themeNode.get_color('-slider-active-border-color');
let sliderActiveColor = themeNode.get_color('-slider-active-background-color');
const TAU = Math.PI * 2;
let handleX = handleRadius + (width - 2 * handleRadius) * this._value;
cr.arc(sliderBorderRadius + sliderBorderWidth, height / 2, sliderBorderRadius, TAU * 1/4, TAU * 3/4);
cr.lineTo(handleX, (height - sliderHeight) / 2);
cr.lineTo(handleX, (height + sliderHeight) / 2);
cr.lineTo(sliderBorderRadius + sliderBorderWidth, (height + sliderHeight) / 2);
Clutter.cairo_set_source_color(cr, sliderActiveColor);
cr.fillPreserve();
Clutter.cairo_set_source_color(cr, sliderActiveBorderColor);
cr.setLineWidth(sliderBorderWidth);
cr.stroke();
cr.arc(width - sliderBorderRadius - sliderBorderWidth, height / 2, sliderBorderRadius, TAU * 3/4, TAU * 1/4);
cr.lineTo(handleX, (height + sliderHeight) / 2);
cr.lineTo(handleX, (height - sliderHeight) / 2);
cr.lineTo(width - sliderBorderRadius - sliderBorderWidth, (height - sliderHeight) / 2);
Clutter.cairo_set_source_color(cr, sliderColor);
cr.fillPreserve();
Clutter.cairo_set_source_color(cr, sliderBorderColor);
cr.setLineWidth(sliderBorderWidth);
cr.stroke();
let handleX = handleRadius + (width - 2 * handleRadius) * this._value / this._maxValue;
let handleY = height / 2;
let color = themeNode.get_foreground_color();
@ -208,7 +159,7 @@ var Slider = new Lang.Class({
delta = -dy * SLIDER_SCROLL_STEP;
}
this._value = Math.min(Math.max(0, this._value + delta), 1);
this._value = Math.min(Math.max(0, this._value + delta), this._maxValue);
this.actor.queue_repaint();
this.emit('value-changed', this._value);
@ -230,7 +181,7 @@ var Slider = new Lang.Class({
let key = event.get_key_symbol();
if (key == Clutter.KEY_Right || key == Clutter.KEY_Left) {
let delta = key == Clutter.KEY_Right ? 0.1 : -0.1;
this._value = Math.max(0, Math.min(this._value + delta, 1));
this._value = Math.max(0, Math.min(this._value + delta, this._maxValue));
this.actor.queue_repaint();
this.emit('drag-begin');
this.emit('value-changed', this._value);
@ -246,7 +197,7 @@ var Slider = new Lang.Class({
relX = absX - sliderX;
relY = absY - sliderY;
let width = this._sliderWidth;
let width = this._barLevelWidth;
let handleRadius = this.actor.get_theme_node().get_length('-slider-handle-radius');
let newvalue;
@ -256,38 +207,14 @@ var Slider = new Lang.Class({
newvalue = 1;
else
newvalue = (relX - handleRadius) / (width - 2 * handleRadius);
this._value = newvalue;
this._value = newvalue * this._maxValue;
this.actor.queue_repaint();
this.emit('value-changed', this._value);
},
_getCurrentValue(actor) {
return this._value;
},
_getMinimumValue(actor) {
return 0;
},
_getMaximumValue(actor) {
return 1;
},
_getMinimumIncrement(actor) {
return 0.1;
},
_setCurrentValue(actor, value) {
this._value = value;
},
_valueChanged(slider, value, property) {
this._customAccessible.notify ("accessible-value");
},
get value() {
return this._value;
}
});
Signals.addSignalMethods(Slider.prototype);

View File

@ -398,7 +398,7 @@ var InputSourceManager = new Lang.Class({
return true;
},
_switchInputSource(display, screen, window, binding) {
_switchInputSource(display, window, binding) {
if (this._mruSources.length < 2)
return;

View File

@ -995,8 +995,16 @@ var NMWirelessDialog = new Lang.Class({
else if (!oneHasConnection && twoHasConnection)
return 1;
let oneStrength = one.accessPoints[0].strength;
let twoStrength = two.accessPoints[0].strength;
let oneAp = one.accessPoints[0] || null;
let twoAp = two.accessPoints[0] || null;
if (oneAp != null && twoAp == null)
return -1;
else if (oneAp == null && twoAp != null)
return 1;
let oneStrength = oneAp.strength;
let twoStrength = twoAp.strength;
// place stronger connections first
if (oneStrength != twoStrength)
@ -1156,6 +1164,11 @@ var NMWirelessDialog = new Lang.Class({
Util.ensureActorVisibleInScrollView(this._scrollView, network.item.actor);
this._selectNetwork(network);
});
network.item.actor.connect('destroy', () => {
let keyFocus = global.stage.key_focus;
if (keyFocus && keyFocus.contains(network.item.actor))
this._itemBox.grab_key_focus();
});
},
});
@ -1944,6 +1957,7 @@ var NMApplet = new Lang.Class({
this.indicators.visible = this._client.nm_running;
this.menu.actor.visible = this._client.networking_enabled;
this._updateIcon();
this._syncConnectivity();
},

View File

@ -0,0 +1,81 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Lang = imports.lang;
const Meta = imports.gi.Meta;
const PanelMenu = imports.ui.panelMenu;
const PopupMenu = imports.ui.popupMenu;
var RemoteAccessApplet = new Lang.Class({
Name: 'RemoteAccessApplet',
Extends: PanelMenu.SystemIndicator,
_init() {
this.parent();
let backend = Meta.get_backend();
let controller = backend.get_remote_access_controller();
if (!controller)
return;
// We can't possibly know about all types of screen sharing on X11, so
// showing these controls on X11 might give a false sense of security.
// Thus, only enable these controls when using Wayland, where we are
// in control of sharing.
if (!Meta.is_wayland_compositor())
return;
this._handles = new Set();
this._indicator = null;
this._menuSection = null;
controller.connect('new-handle', (controller, handle) => {
this._onNewHandle(handle);
});
},
_ensureControls() {
if (this._indicator)
return;
this._indicator = this._addIndicator();
this._indicator.icon_name = 'screen-shared-symbolic';
this._indicator.add_style_class_name('remote-access-indicator');
this._item =
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);
},
_sync() {
if (this._handles.size == 0) {
this._indicator.visible = false;
this._item.actor.visible = false;
} else {
this._indicator.visible = true;
this._item.actor.visible = true;
}
},
_onStopped(handle) {
this._handles.delete(handle);
this._sync();
},
_onNewHandle(handle) {
this._handles.add(handle);
handle.connect('stopped', this._onStopped.bind(this));
if (this._handles.size == 1) {
this._ensureControls();
this._sync();
}
},
});

View File

@ -261,8 +261,19 @@ var Indicator = new Lang.Class({
item = new PopupMenu.PopupBaseMenuItem({ reactive: false,
can_focus: false });
this._settingsAction = this._createActionButton('preferences-system-symbolic', _("Settings"));
this._settingsAction.connect('clicked', () => { this._onSettingsClicked(); });
let app = this._settingsApp = Shell.AppSystem.get_default().lookup_app(
'gnome-control-center.desktop'
);
if (app) {
let [icon, name] = [app.app_info.get_icon().names[0],
app.get_name()];
this._settingsAction = this._createActionButton(icon, name);
this._settingsAction.connect('clicked',
this._onSettingsClicked.bind(this));
} else {
log('Missing required core component Settings, expect trouble…');
this._settingsAction = new St.Widget();
}
item.actor.add(this._settingsAction, { expand: true, x_fill: false });
this._orientationLockAction = this._createActionButton('', _("Orientation Lock"));
@ -280,7 +291,7 @@ var Indicator = new Lang.Class({
'icon-name',
bindFlags);
this._lockScreenAction = this._createActionButton('changes-prevent-symbolic', _("Lock"));
this._lockScreenAction = this._createActionButton('changes-prevent', _("Lock"));
this._lockScreenAction.connect('clicked', () => {
this.menu.itemActivated(BoxPointer.PopupAnimation.NONE);
this._systemActions.activateLockScreen();
@ -291,7 +302,7 @@ var Indicator = new Lang.Class({
'visible',
bindFlags);
this._suspendAction = this._createActionButton('media-playback-pause-symbolic', _("Suspend"));
this._suspendAction = this._createActionButton('media-playback-pause', _("Suspend"));
this._suspendAction.connect('clicked', () => {
this.menu.itemActivated(BoxPointer.PopupAnimation.NONE);
this._systemActions.activateSuspend();
@ -301,7 +312,7 @@ var Indicator = new Lang.Class({
'visible',
bindFlags);
this._powerOffAction = this._createActionButton('system-shutdown-symbolic', _("Power Off"));
this._powerOffAction = this._createActionButton('system-shutdown', _("Power Off"));
this._powerOffAction.connect('clicked', () => {
this.menu.itemActivated(BoxPointer.PopupAnimation.NONE);
this._systemActions.activatePowerOff();
@ -330,8 +341,7 @@ var Indicator = new Lang.Class({
_onSettingsClicked() {
this.menu.itemActivated();
let app = Shell.AppSystem.get_default().lookup_app('gnome-control-center.desktop');
Main.overview.hide();
app.activate();
this._settingsApp.activate();
}
});

View File

@ -49,19 +49,17 @@ const BoltDeviceInterface = '<node> \
</interface> \
</node>';
const BoltClientProxy = Gio.DBusProxy.makeProxyWrapper(BoltClientInterface);
const BoltDeviceProxy = Gio.DBusProxy.makeProxyWrapper(BoltDeviceInterface);
/* */
var Status = {
DISCONNECTED: 'disconnected',
CONNECTING: 'connecting',
CONNECTED: 'connected',
AUTHORIZING: 'authorizing',
AUTH_ERROR: 'auth-error',
AUTHORIZED: 'authorized',
AUTHORIZED_SECURE: 'authorized-secure',
AUTHORIZED_NEWKEY: 'authorized-newkey'
AUTHORIZED: 'authorized'
};
var Policy = {
@ -70,7 +68,7 @@ var Policy = {
AUTO: 'auto'
};
var AuthFlags = {
var AuthCtrl = {
NONE: 'none',
};
@ -79,6 +77,7 @@ var AuthMode = {
ENABLED: 'enabled'
};
const BOLT_DBUS_CLIENT_IFACE = 'org.freedesktop.bolt1.Manager';
const BOLT_DBUS_NAME = 'org.freedesktop.bolt';
const BOLT_DBUS_PATH = '/org/freedesktop/bolt';
@ -88,22 +87,26 @@ var Client = new Lang.Class({
_init() {
this._proxy = null;
new BoltClientProxy(
Gio.DBus.system,
BOLT_DBUS_NAME,
BOLT_DBUS_PATH,
this._onProxyReady.bind(this)
);
let nodeInfo = Gio.DBusNodeInfo.new_for_xml(BoltClientInterface);
Gio.DBusProxy.new(Gio.DBus.system,
Gio.DBusProxyFlags.DO_NOT_AUTO_START,
nodeInfo.lookup_interface(BOLT_DBUS_CLIENT_IFACE),
BOLT_DBUS_NAME,
BOLT_DBUS_PATH,
BOLT_DBUS_CLIENT_IFACE,
null,
this._onProxyReady.bind(this));
this.probing = false;
},
_onProxyReady(proxy, error) {
if (error !== null) {
log('error creating bolt proxy: %s'.format(error.message));
return;
}
this._proxy = proxy;
_onProxyReady(o, res) {
try {
this._proxy = Gio.DBusProxy.new_finish(res);
} catch(e) {
log('error creating bolt proxy: %s'.format(e.message));
return;
}
this._propsChangedId = this._proxy.connect('g-properties-changed', this._onPropertiesChanged.bind(this));
this._deviceAddedId = this._proxy.connectSignal('DeviceAdded', this._onDeviceAdded.bind(this));
@ -141,9 +144,10 @@ var Client = new Lang.Class({
},
enrollDevice(id, policy, callback) {
this._proxy.EnrollDeviceRemote(id, policy, AuthFlags.NONE,
this._proxy.EnrollDeviceRemote(id, policy, AuthCtrl.NONE,
(res, error) => {
if (error) {
Gio.DBusError.strip_remote_error(error);
callback(null, error);
return;
}
@ -228,7 +232,7 @@ var AuthRobot = new Lang.Class({
_onEnrollDone(device, error) {
if (error)
this.emit('enroll-failed', error, device);
this.emit('enroll-failed', device, error);
/* TODO: scan the list of devices to be authorized for children
* of this device and remove them (and their children and

View File

@ -12,6 +12,8 @@ const PanelMenu = imports.ui.panelMenu;
const PopupMenu = imports.ui.popupMenu;
const Slider = imports.ui.slider;
const ALLOW_AMPLIFIED_VOLUME_KEY = 'allow-volume-above-100-percent';
var VOLUME_NOTIFY_ID = 1;
// Each Gvc.MixerControl is a connection to PulseAudio,
@ -36,6 +38,11 @@ var StreamSlider = new Lang.Class({
this.item = new PopupMenu.PopupBaseMenuItem({ activate: false });
this._slider = new Slider.Slider(0);
this._soundSettings = new Gio.Settings({ schema_id: 'org.gnome.desktop.sound' });
this._soundSettings.connect('changed::' + ALLOW_AMPLIFIED_VOLUME_KEY, this._amplifySettingsChanged.bind(this));
this._amplifySettingsChanged();
this._slider.connect('value-changed', this._sliderChanged.bind(this));
this._slider.connect('drag-end', this._notifyVolumeChange.bind(this));
@ -135,21 +142,40 @@ var StreamSlider = new Lang.Class({
this.emit('stream-updated');
},
_amplifySettingsChanged() {
this._allowAmplified = this._soundSettings.get_boolean(ALLOW_AMPLIFIED_VOLUME_KEY);
if (this._allowAmplified)
this._slider.setMaximumValue(this.getMaxLevel() / 100);
else
this._slider.setMaximumValue(1);
if (this._stream)
this._updateVolume();
},
getIcon() {
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) {
return 'audio-volume-muted-symbolic';
n = 0;
} else {
let n = Math.floor(3 * volume / this._control.get_vol_max_norm()) + 1;
if (n < 2)
return 'audio-volume-low-symbolic';
if (n >= 3)
return 'audio-volume-high-symbolic';
return 'audio-volume-medium-symbolic';
n = Math.ceil(3 * volume / this._control.get_vol_max_norm());
if (n < 1)
n = 1;
else if (n > 3)
n = 4;
}
return icons[n];
},
getLevel() {
@ -157,6 +183,14 @@ var StreamSlider = new Lang.Class({
return null;
return 100 * this._stream.volume / this._control.get_vol_max_norm();
},
getMaxLevel() {
let maxVolume = this._control.get_vol_max_norm();
if (this._allowAmplified)
maxVolume = this._control.get_vol_max_amplified();
return 100 * maxVolume / this._control.get_vol_max_norm();
}
});
Signals.addSignalMethods(StreamSlider.prototype);
@ -310,6 +344,10 @@ var VolumeMenu = new Lang.Class({
getLevel() {
return this._output.getLevel();
},
getMaxLevel() {
return this._output.getMaxLevel();
}
});
@ -346,8 +384,9 @@ var Indicator = new Lang.Class({
return result;
let gicon = new Gio.ThemedIcon({ name: this._volumeMenu.getIcon() });
let level = this._volumeMenu.getLevel();
Main.osdWindowManager.show(-1, gicon, null, level);
let level = parseInt(this._volumeMenu.getLevel());
let maxLevel = parseInt(this._volumeMenu.getMaxLevel());
Main.osdWindowManager.show(-1, gicon, null, level, maxLevel);
return result;
}
});

View File

@ -192,7 +192,9 @@ var SwitcherPopup = new Lang.Class({
if (this._keyPressHandler(keysym, action) != Clutter.EVENT_PROPAGATE)
return Clutter.EVENT_STOP;
if (keysym == Clutter.Escape)
// Note: pressing one of the below keys will destroy the popup only if
// that key is not used by the active popup's keyboard shortcut
if (keysym == Clutter.Escape || keysym == Clutter.Tab)
this.destroy();
return Clutter.EVENT_STOP;

View File

@ -230,14 +230,14 @@ var ViewSelector = new Lang.Class({
Main.wm.addKeybinding('toggle-application-view',
new Gio.Settings({ schema_id: SHELL_KEYBINDINGS_SCHEMA }),
Meta.KeyBindingFlags.NONE,
Meta.KeyBindingFlags.IGNORE_AUTOREPEAT,
Shell.ActionMode.NORMAL |
Shell.ActionMode.OVERVIEW,
this._toggleAppsPage.bind(this));
Main.wm.addKeybinding('toggle-overview',
new Gio.Settings({ schema_id: SHELL_KEYBINDINGS_SCHEMA }),
Meta.KeyBindingFlags.NONE,
Meta.KeyBindingFlags.IGNORE_AUTOREPEAT,
Shell.ActionMode.NORMAL |
Shell.ActionMode.OVERVIEW,
Main.overview.toggle.bind(Main.overview));

View File

@ -3,6 +3,7 @@
const Clutter = imports.gi.Clutter;
const GLib = imports.gi.GLib;
const Gio = imports.gi.Gio;
const GObject = imports.gi.GObject;
const Lang = imports.lang;
const Mainloop = imports.mainloop;
const Meta = imports.gi.Meta;
@ -24,7 +25,7 @@ const EdgeDragAction = imports.ui.edgeDragAction;
const CloseDialog = imports.ui.closeDialog;
const SwitchMonitor = imports.ui.switchMonitor;
const SHELL_KEYBINDINGS_SCHEMA = 'org.gnome.shell.keybindings';
var SHELL_KEYBINDINGS_SCHEMA = 'org.gnome.shell.keybindings';
var MINIMIZE_WINDOW_ANIMATION_TIME = 0.2;
var SHOW_WINDOW_ANIMATION_TIME = 0.15;
var DIALOG_SHOW_WINDOW_ANIMATION_TIME = 0.1;
@ -34,6 +35,7 @@ var WINDOW_ANIMATION_TIME = 0.25;
var DIM_BRIGHTNESS = -0.3;
var DIM_TIME = 0.500;
var UNDIM_TIME = 0.250;
var MOTION_THRESHOLD = 100;
var ONE_SECOND = 1000; // in ms
@ -200,27 +202,25 @@ var WorkspaceTracker = new Lang.Class({
let tracker = Shell.WindowTracker.get_default();
tracker.connect('startup-sequence-changed', this._queueCheckWorkspaces.bind(this));
global.screen.connect('notify::n-workspaces', this._nWorkspacesChanged.bind(this));
global.window_manager.connect('switch-workspace', this._queueCheckWorkspaces.bind(this));
let workspaceManager = global.workspace_manager;
workspaceManager.connect('notify::n-workspaces',
this._nWorkspacesChanged.bind(this));
global.window_manager.connect('switch-workspace',
this._queueCheckWorkspaces.bind(this));
global.screen.connect('window-entered-monitor', this._windowEnteredMonitor.bind(this));
global.screen.connect('window-left-monitor', this._windowLeftMonitor.bind(this));
global.screen.connect('restacked', this._windowsRestacked.bind(this));
global.display.connect('window-entered-monitor',
this._windowEnteredMonitor.bind(this));
global.display.connect('window-left-monitor',
this._windowLeftMonitor.bind(this));
global.display.connect('restacked',
this._windowsRestacked.bind(this));
this._workspaceSettings = this._getWorkspaceSettings();
this._workspaceSettings = new Gio.Settings({ schema_id: 'org.gnome.mutter' });
this._workspaceSettings.connect('changed::dynamic-workspaces', this._queueCheckWorkspaces.bind(this));
this._nWorkspacesChanged();
},
_getWorkspaceSettings() {
let settings = global.get_overrides_settings();
if (settings &&
settings.settings_schema.list_keys().indexOf('dynamic-workspaces') > -1)
return settings;
return new Gio.Settings({ schema_id: 'org.gnome.mutter' });
},
blockUpdates() {
this._pauseWorkspaceCheck = true;
},
@ -230,6 +230,7 @@ var WorkspaceTracker = new Lang.Class({
},
_checkWorkspaces() {
let workspaceManager = global.workspace_manager;
let i;
let emptyWorkspaces = [];
@ -257,7 +258,7 @@ var WorkspaceTracker = new Lang.Class({
let sequences = Shell.WindowTracker.get_default().get_startup_sequences();
for (i = 0; i < sequences.length; i++) {
let index = sequences[i].get_workspace();
if (index >= 0 && index <= global.screen.n_workspaces)
if (index >= 0 && index <= workspaceManager.n_workspaces)
emptyWorkspaces[index] = false;
}
@ -275,17 +276,17 @@ var WorkspaceTracker = new Lang.Class({
// If we don't have an empty workspace at the end, add one
if (!emptyWorkspaces[emptyWorkspaces.length -1]) {
global.screen.append_new_workspace(false, global.get_current_time());
workspaceManager.append_new_workspace(false, global.get_current_time());
emptyWorkspaces.push(false);
}
let activeWorkspaceIndex = global.screen.get_active_workspace_index();
let activeWorkspaceIndex = workspaceManager.get_active_workspace_index();
emptyWorkspaces[activeWorkspaceIndex] = false;
// Delete other empty workspaces; do it from the end to avoid index changes
for (i = emptyWorkspaces.length - 2; i >= 0; i--) {
if (emptyWorkspaces[i])
global.screen.remove_workspace(this._workspaces[i], global.get_current_time());
workspaceManager.remove_workspace(this._workspaces[i], global.get_current_time());
}
this._checkWorkspacesId = 0;
@ -317,14 +318,14 @@ var WorkspaceTracker = new Lang.Class({
GLib.Source.set_name_by_id(id, '[gnome-shell] this._queueCheckWorkspaces');
},
_windowLeftMonitor(metaScreen, monitorIndex, metaWin) {
_windowLeftMonitor(metaDisplay, monitorIndex, metaWin) {
// If the window left the primary monitor, that
// might make that workspace empty
if (monitorIndex == Main.layoutManager.primaryIndex)
this._queueCheckWorkspaces();
},
_windowEnteredMonitor(metaScreen, monitorIndex, metaWin) {
_windowEnteredMonitor(metaDisplay, monitorIndex, metaWin) {
// If the window entered the primary monitor, that
// might make that workspace non-empty
if (monitorIndex == Main.layoutManager.primaryIndex)
@ -344,8 +345,9 @@ var WorkspaceTracker = new Lang.Class({
},
_nWorkspacesChanged() {
let workspaceManager = global.workspace_manager;
let oldNumWorkspaces = this._workspaces.length;
let newNumWorkspaces = global.screen.n_workspaces;
let newNumWorkspaces = workspaceManager.n_workspaces;
if (oldNumWorkspaces == newNumWorkspaces)
return false;
@ -356,7 +358,7 @@ var WorkspaceTracker = new Lang.Class({
// Assume workspaces are only added at the end
for (w = oldNumWorkspaces; w < newNumWorkspaces; w++)
this._workspaces[w] = global.screen.get_workspace_by_index(w);
this._workspaces[w] = workspaceManager.get_workspace_by_index(w);
for (w = oldNumWorkspaces; w < newNumWorkspaces; w++) {
let workspace = this._workspaces[w];
@ -370,7 +372,7 @@ var WorkspaceTracker = new Lang.Class({
let removedIndex;
let removedNum = oldNumWorkspaces - newNumWorkspaces;
for (let w = 0; w < oldNumWorkspaces; w++) {
let workspace = global.screen.get_workspace_by_index(w);
let workspace = workspaceManager.get_workspace_by_index(w);
if (this._workspaces[w] != workspace) {
removedIndex = w;
break;
@ -487,13 +489,8 @@ var TouchpadWorkspaceSwitchAction = new Lang.Class({
},
_checkActivated() {
const MOTION_THRESHOLD = 50;
let allowedModes = Shell.ActionMode.NORMAL | Shell.ActionMode.OVERVIEW;
let dir;
if ((allowedModes & Main.actionMode) == 0)
return;
if (this._dy < -MOTION_THRESHOLD)
dir = Meta.MotionDirection.DOWN;
else if (this._dy > MOTION_THRESHOLD)
@ -503,26 +500,35 @@ var TouchpadWorkspaceSwitchAction = new Lang.Class({
else if (this._dx > MOTION_THRESHOLD)
dir = Meta.MotionDirection.LEFT;
else
return;
return false;
this.emit('activated', dir);
return true;
},
_handleEvent(actor, event) {
let allowedModes = Shell.ActionMode.NORMAL | Shell.ActionMode.OVERVIEW;
if (event.type() != Clutter.EventType.TOUCHPAD_SWIPE)
return Clutter.EVENT_PROPAGATE;
if (event.get_touchpad_gesture_finger_count() != 4)
return Clutter.EVENT_PROPAGATE;
if ((allowedModes & Main.actionMode) == 0)
return Clutter.EVENT_PROPAGATE;
if (event.get_gesture_phase() == Clutter.TouchpadGesturePhase.UPDATE) {
let [dx, dy] = event.get_gesture_motion_delta();
this._dx += dx;
this._dy += dy;
// Scale deltas up a bit to make it feel snappier
this._dx += dx * 2;
this._dy += dy * 2;
this.emit('motion', this._dx, this._dy);
} else {
if (event.get_gesture_phase() == Clutter.TouchpadGesturePhase.END)
this._checkActivated();
if ((event.get_gesture_phase() == Clutter.TouchpadGesturePhase.END && ! this._checkActivated()) ||
event.get_gesture_phase() == Clutter.TouchpadGesturePhase.CANCEL)
this.emit('cancel');
this._dx = 0;
this._dy = 0;
@ -536,14 +542,14 @@ Signals.addSignalMethods(TouchpadWorkspaceSwitchAction.prototype);
var WorkspaceSwitchAction = new Lang.Class({
Name: 'WorkspaceSwitchAction',
Extends: Clutter.SwipeAction,
Signals: { 'activated': { param_types: [Meta.MotionDirection.$gtype] } },
Signals: { 'activated': { param_types: [Meta.MotionDirection.$gtype] },
'motion': { param_types: [GObject.TYPE_DOUBLE, GObject.TYPE_DOUBLE] },
'cancel': { param_types: [] }},
_init() {
const MOTION_THRESHOLD = 50;
this.parent();
this.set_n_touch_points(4);
this.set_threshold_trigger_distance(MOTION_THRESHOLD, MOTION_THRESHOLD);
this._swept = false;
global.display.connect('grab-op-begin', () => {
this.cancel();
@ -553,13 +559,35 @@ var WorkspaceSwitchAction = new Lang.Class({
vfunc_gesture_prepare(actor) {
let allowedModes = Shell.ActionMode.NORMAL | Shell.ActionMode.OVERVIEW;
this._swept = false;
if (!this.parent(actor))
return false;
return (allowedModes & Main.actionMode);
},
vfunc_swept(actor, direction) {
vfunc_gesture_progress(actor) {
let [x, y] = this.get_motion_coords(0);
let [xPress, yPress] = this.get_press_coords(0);
this.emit('motion', x - xPress, y - yPress);
return true;
},
vfunc_gesture_cancel(actor) {
if (!this._swept)
this.emit('cancel');
},
vfunc_swipe(actor, direction) {
let [x, y] = this.get_motion_coords(0);
let [xPress, yPress] = this.get_press_coords(0);
if (Math.abs(x - xPress) < MOTION_THRESHOLD &&
Math.abs(y - yPress) < MOTION_THRESHOLD) {
this.emit('cancel');
return;
}
let dir;
if (direction & Clutter.SwipeDirection.UP)
@ -571,6 +599,7 @@ var WorkspaceSwitchAction = new Lang.Class({
else if (direction & Clutter.SwipeDirection.RIGHT)
dir = Meta.MotionDirection.LEFT;
this._swept = true;
this.emit('activated', dir);
}
});
@ -627,8 +656,8 @@ var AppSwitchAction = new Lang.Class({
if (this.get_n_current_points() == 3) {
for (let i = 0; i < this.get_n_current_points(); i++) {
[startX, startY] = this.get_press_coords(i);
[x, y] = this.get_motion_coords(i);
let [startX, startY] = this.get_press_coords(i);
let [x, y] = this.get_motion_coords(i);
if (Math.abs(x - startX) > MOTION_THRESHOLD ||
Math.abs(y - startY) > MOTION_THRESHOLD)
@ -692,7 +721,14 @@ var WindowManager = new Lang.Class({
this._isWorkspacePrepended = false;
this._switchData = null;
this._shellwm.connect('kill-switch-workspace', this._switchWorkspaceDone.bind(this));
this._shellwm.connect('kill-switch-workspace', (shellwm) => {
if (this._switchData) {
if (this._switchData.inProgress)
this._switchWorkspaceDone(shellwm);
else if (!this._switchData.gestureActivated)
this._finishWorkspaceSwitch(this._switchData);
}
});
this._shellwm.connect('kill-window-effects', (shellwm, actor) => {
this._minimizeWindowDone(shellwm, actor);
this._mapWindowDone(shellwm, actor);
@ -714,7 +750,7 @@ var WindowManager = new Lang.Class({
this._shellwm.connect('confirm-display-change', this._confirmDisplayChange.bind(this));
this._shellwm.connect('create-close-dialog', this._createCloseDialog.bind(this));
this._shellwm.connect('create-inhibit-shortcuts-dialog', this._createInhibitShortcutsDialog.bind(this));
global.screen.connect('restacked', this._syncStacking.bind(this));
global.display.connect('restacked', this._syncStacking.bind(this));
this._workspaceSwitcherPopup = null;
this._tilePreview = null;
@ -912,14 +948,14 @@ var WindowManager = new Lang.Class({
this.addKeybinding('open-application-menu',
new Gio.Settings({ schema_id: SHELL_KEYBINDINGS_SCHEMA }),
Meta.KeyBindingFlags.NONE,
Meta.KeyBindingFlags.IGNORE_AUTOREPEAT,
Shell.ActionMode.NORMAL |
Shell.ActionMode.POPUP,
this._toggleAppMenu.bind(this));
this.addKeybinding('toggle-message-tray',
new Gio.Settings({ schema_id: SHELL_KEYBINDINGS_SCHEMA }),
Meta.KeyBindingFlags.NONE,
Meta.KeyBindingFlags.IGNORE_AUTOREPEAT,
Shell.ActionMode.NORMAL |
Shell.ActionMode.OVERVIEW |
Shell.ActionMode.POPUP,
@ -970,16 +1006,20 @@ var WindowManager = new Lang.Class({
if (Main.sessionMode.hasWorkspaces)
this._workspaceTracker = new WorkspaceTracker(this);
global.screen.override_workspace_layout(Meta.ScreenCorner.TOPLEFT,
false, -1, 1);
global.workspace_manager.override_workspace_layout(Meta.DisplayCorner.TOPLEFT,
false, -1, 1);
let gesture = new WorkspaceSwitchAction();
gesture.connect('motion', this._switchWorkspaceMotion.bind(this));
gesture.connect('activated', this._actionSwitchWorkspace.bind(this));
gesture.connect('cancel', this._switchWorkspaceCancel.bind(this));
global.stage.add_action(gesture);
// This is not a normal Clutter.GestureAction, doesn't need add_action()
gesture = new TouchpadWorkspaceSwitchAction(global.stage);
gesture.connect('motion', this._switchWorkspaceMotion.bind(this));
gesture.connect('activated', this._actionSwitchWorkspace.bind(this));
gesture.connect('cancel', this._switchWorkspaceCancel.bind(this));
gesture = new AppSwitchAction();
gesture.connect('activated', this._switchApp.bind(this));
@ -991,6 +1031,14 @@ var WindowManager = new Lang.Class({
Main.keyboard.show(Main.layoutManager.bottomIndex);
});
global.stage.add_action(gesture);
gesture = new EdgeDragAction.EdgeDragAction(St.Side.TOP, mode);
gesture.connect('activated', () => {
let currentWindow = global.display.focus_window;
if (currentWindow)
currentWindow.unmake_fullscreen();
});
global.stage.add_action(gesture);
},
_showPadOsd(display, device, settings, imagePath, editionMode, monitorIndex) {
@ -1000,9 +1048,52 @@ var WindowManager = new Lang.Class({
return this._currentPadOsd.actor;
},
_switchWorkspaceMotion(action, xRel, yRel) {
let workspaceManager = global.workspace_manager;
let activeWorkspace = workspaceManager.get_active_workspace();
if (!this._switchData)
this._prepareWorkspaceSwitch(activeWorkspace.index(), -1);
if (yRel < 0 && !this._switchData.surroundings[Meta.MotionDirection.DOWN])
yRel = 0;
if (yRel > 0 && !this._switchData.surroundings[Meta.MotionDirection.UP])
yRel = 0;
if (xRel < 0 && !this._switchData.surroundings[Meta.MotionDirection.RIGHT])
xRel = 0;
if (xRel > 0 && !this._switchData.surroundings[Meta.MotionDirection.LEFT])
xRel = 0;
this._switchData.container.set_position(xRel, yRel);
},
_switchWorkspaceCancel() {
if (!this._switchData || this._switchData.inProgress)
return;
let switchData = this._switchData;
this._switchData = null;
Tweener.addTween(switchData.container,
{ x: 0,
y: 0,
time: WINDOW_ANIMATION_TIME,
transition: 'easeOutQuad',
onComplete: this._finishWorkspaceSwitch,
onCompleteScope: this,
onCompleteParams: [switchData],
});
},
_actionSwitchWorkspace(action, direction) {
let newWs = global.screen.get_active_workspace().get_neighbor(direction);
let workspaceManager = global.workspace_manager;
let activeWorkspace = workspaceManager.get_active_workspace();
let newWs = activeWorkspace.get_neighbor(direction);
if (newWs == activeWorkspace) {
this._switchWorkspaceCancel();
} else {
this._switchData.gestureActivated = true;
this.actionMoveWorkspace(newWs);
}
},
_lookupIndex(windows, metaWindow) {
@ -1017,8 +1108,10 @@ var WindowManager = new Lang.Class({
_switchApp() {
let windows = global.get_window_actors().filter(actor => {
let win = actor.metaWindow;
let workspaceManager = global.workspace_manager;
let activeWorkspace = workspaceManager.get_active_workspace();
return (!win.is_override_redirect() &&
win.located_on_workspace(global.screen.get_active_workspace()));
win.located_on_workspace(activeWorkspace));
});
if (windows.length == 0)
@ -1042,10 +1135,12 @@ var WindowManager = new Lang.Class({
},
insertWorkspace(pos) {
let workspaceManager = global.workspace_manager;
if (!Meta.prefs_get_dynamic_workspaces())
return;
global.screen.append_new_workspace(false, global.get_current_time());
workspaceManager.append_new_workspace(false, global.get_current_time());
let windows = global.get_window_actors().map(a => a.meta_window);
@ -1069,9 +1164,9 @@ var WindowManager = new Lang.Class({
// If the new workspace was inserted before the active workspace,
// activate the workspace to which its windows went
let activeIndex = global.screen.get_active_workspace_index();
let activeIndex = workspaceManager.get_active_workspace_index();
if (activeIndex >= pos) {
let newWs = global.screen.get_workspace_by_index(activeIndex + 1);
let newWs = workspaceManager.get_workspace_by_index(activeIndex + 1);
this._blockAnimations = true;
newWs.activate(global.get_current_time());
this._blockAnimations = false;
@ -1173,6 +1268,10 @@ var WindowManager = new Lang.Class({
yScale = geom.height / actor.height;
} else {
let monitor = Main.layoutManager.monitors[actor.meta_window.get_monitor()];
if (!monitor) {
this._minimizeWindowDone();
return;
}
xDest = monitor.x;
yDest = monitor.y;
if (Clutter.get_default_text_direction() == Clutter.TextDirection.RTL)
@ -1248,6 +1347,11 @@ var WindowManager = new Lang.Class({
geom.height / actor.height);
} else {
let monitor = Main.layoutManager.monitors[actor.meta_window.get_monitor()];
if (!monitor) {
actor.show();
this._unminimizeWindowDone();
return;
}
actor.set_position(monitor.x, monitor.y);
if (Clutter.get_default_text_direction() == Clutter.TextDirection.RTL)
actor.x += monitor.width;
@ -1669,63 +1773,104 @@ var WindowManager = new Lang.Class({
if (this._switchData == null)
return;
// Update stacking of windows in inGroup (aka the workspace we are
// switching to). Windows in outGroup are about to be hidden anyway,
// so we just ignore them here.
let windows = global.get_window_actors();
let sibling = null;
let lastCurSibling = null;
let lastDirSibling = [];
for (let i = 0; i < windows.length; i++) {
if (windows[i].get_parent() != this._switchData.inGroup)
continue;
if (windows[i].get_parent() == this._switchData.curGroup) {
this._switchData.curGroup.set_child_above_sibling(windows[i], lastCurSibling);
lastCurSibling = windows[i];
} else {
for (let dir of Object.values(Meta.MotionDirection)) {
let info = this._switchData.surroundings[dir];
if (!info || windows[i].get_parent() != info.actor)
continue;
this._switchData.inGroup.set_child_above_sibling(windows[i], sibling);
sibling = windows[i];
let sibling = lastDirSibling[dir];
if (sibling == undefined)
sibling = null;
info.actor.set_child_above_sibling(windows[i], sibling);
lastDirSibling[dir] = windows[i];
break;
}
}
}
},
_switchWorkspace(shellwm, from, to, direction) {
if (!Main.sessionMode.hasWorkspaces || !this._shouldAnimate()) {
shellwm.completed_switch_workspace();
return;
}
let windows = global.get_window_actors();
/* @direction is the direction that the "camera" moves, so the
* screen contents have to move one screen's worth in the
* opposite direction.
*/
_getPositionForDirection(direction) {
let xDest = 0, yDest = 0;
if (direction == Meta.MotionDirection.UP ||
direction == Meta.MotionDirection.UP_LEFT ||
direction == Meta.MotionDirection.UP_RIGHT)
yDest = global.screen_height - Main.panel.actor.height;
yDest = -global.screen_height + Main.panel.actor.height;
else if (direction == Meta.MotionDirection.DOWN ||
direction == Meta.MotionDirection.DOWN_LEFT ||
direction == Meta.MotionDirection.DOWN_RIGHT)
yDest = -global.screen_height + Main.panel.actor.height;
yDest = global.screen_height - Main.panel.actor.height;
if (direction == Meta.MotionDirection.LEFT ||
direction == Meta.MotionDirection.UP_LEFT ||
direction == Meta.MotionDirection.DOWN_LEFT)
xDest = global.screen_width;
xDest = -global.screen_width;
else if (direction == Meta.MotionDirection.RIGHT ||
direction == Meta.MotionDirection.UP_RIGHT ||
direction == Meta.MotionDirection.DOWN_RIGHT)
xDest = -global.screen_width;
xDest = global.screen_width;
let switchData = {};
this._switchData = switchData;
switchData.inGroup = new Clutter.Actor();
switchData.outGroup = new Clutter.Actor();
switchData.movingWindowBin = new Clutter.Actor();
switchData.windows = [];
return [xDest, yDest];
},
_prepareWorkspaceSwitch(from, to, direction) {
if (this._switchData)
return;
let wgroup = global.window_group;
wgroup.add_actor(switchData.inGroup);
wgroup.add_actor(switchData.outGroup);
let windows = global.get_window_actors();
let switchData = {};
this._switchData = switchData;
switchData.curGroup = new Clutter.Actor();
switchData.movingWindowBin = new Clutter.Actor();
switchData.windows = [];
switchData.surroundings = {};
switchData.gestureActivated = false;
switchData.inProgress = false;
switchData.container = new Clutter.Actor();
switchData.container.add_actor(switchData.curGroup);
wgroup.add_actor(switchData.movingWindowBin);
wgroup.add_actor(switchData.container);
let workspaceManager = global.workspace_manager;
let curWs = workspaceManager.get_workspace_by_index (from);
for (let dir of Object.values(Meta.MotionDirection)) {
let ws = null;
if (to < 0)
ws = curWs.get_neighbor(dir);
else if (dir == direction)
ws = workspaceManager.get_workspace_by_index(to);
if (ws == null || ws == curWs) {
switchData.surroundings[dir] = null;
continue;
}
let info = { index: ws.index(),
actor: new Clutter.Actor() };
switchData.surroundings[dir] = info;
switchData.container.add_actor(info.actor);
info.actor.raise_top();
let [x, y] = this._getPositionForDirection(dir);
info.actor.set_position(x, y);
}
switchData.movingWindowBin.raise_top();
for (let i = 0; i < windows.length; i++) {
let actor = windows[i];
@ -1746,20 +1891,70 @@ var WindowManager = new Lang.Class({
actor.reparent(switchData.movingWindowBin);
} else if (window.get_workspace().index() == from) {
switchData.windows.push(record);
actor.reparent(switchData.outGroup);
} else if (window.get_workspace().index() == to) {
switchData.windows.push(record);
actor.reparent(switchData.inGroup);
actor.show();
actor.reparent(switchData.curGroup);
} else {
let visible = false;
for (let dir of Object.values(Meta.MotionDirection)) {
let info = switchData.surroundings[dir];
if (!info || info.index != window.get_workspace().index())
continue;
switchData.windows.push(record);
actor.reparent(info.actor);
visible = true;
break;
}
actor.visible = visible;
}
}
},
switchData.inGroup.set_position(-xDest, -yDest);
switchData.inGroup.raise_top();
_finishWorkspaceSwitch(switchData) {
this._switchData = null;
switchData.movingWindowBin.raise_top();
for (let i = 0; i < switchData.windows.length; i++) {
let w = switchData.windows[i];
if (w.window.is_destroyed()) // Window gone
continue;
Tweener.addTween(switchData.outGroup,
w.window.reparent(w.parent);
if (w.window.get_meta_window().get_workspace() !=
global.workspace_manager.get_active_workspace())
w.window.hide();
}
Tweener.removeTweens(switchData.container);
switchData.container.destroy();
switchData.movingWindowBin.destroy();
this._movingWindow = null;
},
_switchWorkspace(shellwm, from, to, direction) {
if (!Main.sessionMode.hasWorkspaces || !this._shouldAnimate()) {
shellwm.completed_switch_workspace();
return;
}
// If we come from a gesture, switchData will already be set,
// and we don't want to overwrite it.
if (!this._switchData)
this._prepareWorkspaceSwitch(from, to, direction);
this._switchData.inProgress = true;
let [xDest, yDest] = this._getPositionForDirection(direction);
/* @direction is the direction that the "camera" moves, so the
* screen contents have to move one screen's worth in the
* opposite direction.
*/
xDest = -xDest;
yDest = -yDest;
Tweener.addTween(this._switchData.container,
{ x: xDest,
y: yDest,
time: WINDOW_ANIMATION_TIME,
@ -1768,39 +1963,10 @@ var WindowManager = new Lang.Class({
onCompleteScope: this,
onCompleteParams: [shellwm]
});
Tweener.addTween(switchData.inGroup,
{ x: 0,
y: 0,
time: WINDOW_ANIMATION_TIME,
transition: 'easeOutQuad'
});
},
_switchWorkspaceDone(shellwm) {
let switchData = this._switchData;
if (!switchData)
return;
this._switchData = null;
for (let i = 0; i < switchData.windows.length; i++) {
let w = switchData.windows[i];
if (w.window.is_destroyed()) // Window gone
continue;
if (w.window.get_parent() == switchData.outGroup) {
w.window.reparent(w.parent);
w.window.hide();
} else
w.window.reparent(w.parent);
}
Tweener.removeTweens(switchData.inGroup);
Tweener.removeTweens(switchData.outGroup);
switchData.inGroup.destroy();
switchData.outGroup.destroy();
switchData.movingWindowBin.destroy();
if (this._movingWindow)
this._movingWindow = null;
this._finishWorkspaceSwitch(this._switchData);
shellwm.completed_switch_workspace();
},
@ -1820,7 +1986,7 @@ var WindowManager = new Lang.Class({
this._windowMenuManager.showWindowMenuForWindow(window, menu, rect);
},
_startSwitcher(display, screen, window, binding) {
_startSwitcher(display, window, binding) {
let constructor = null;
switch (binding.get_name()) {
case 'switch-applications':
@ -1859,15 +2025,15 @@ var WindowManager = new Lang.Class({
tabPopup.destroy();
},
_startA11ySwitcher(display, screen, window, binding) {
_startA11ySwitcher(display, window, binding) {
Main.ctrlAltTabManager.popup(binding.is_reversed(), binding.get_name(), binding.get_mask());
},
_toggleAppMenu(display, screen, window, event, binding) {
_toggleAppMenu(display, window, event, binding) {
Main.panel.toggleAppMenu();
},
_toggleCalendar(display, screen, window, event, binding) {
_toggleCalendar(display, window, event, binding) {
Main.panel.toggleCalendar();
},
@ -1880,11 +2046,13 @@ var WindowManager = new Lang.Class({
OrigTweener.resumeAllTweens();
},
_showWorkspaceSwitcher(display, screen, window, binding) {
_showWorkspaceSwitcher(display, window, binding) {
let workspaceManager = display.get_workspace_manager();
if (!Main.sessionMode.hasWorkspaces)
return;
if (screen.n_workspaces == 1)
if (workspaceManager.n_workspaces == 1)
return;
let [action,,,target] = binding.get_name().split('-');
@ -1903,22 +2071,22 @@ var WindowManager = new Lang.Class({
if (target == 'last') {
direction = Meta.MotionDirection.DOWN;
newWs = screen.get_workspace_by_index(screen.n_workspaces - 1);
newWs = workspaceManager.get_workspace_by_index(workspaceManager.n_workspaces - 1);
} else if (isNaN(target)) {
// Prepend a new workspace dynamically
if (screen.get_active_workspace_index() == 0 &&
if (workspaceManager.get_active_workspace_index() == 0 &&
action == 'move' && target == 'up' && this._isWorkspacePrepended == false) {
this.insertWorkspace(0);
this._isWorkspacePrepended = true;
}
direction = Meta.MotionDirection[target.toUpperCase()];
newWs = screen.get_active_workspace().get_neighbor(direction);
newWs = workspaceManager.get_active_workspace().get_neighbor(direction);
} else if (target > 0) {
target--;
newWs = screen.get_workspace_by_index(target);
newWs = workspaceManager.get_workspace_by_index(target);
if (screen.get_active_workspace().index() > target)
if (workspaceManager.get_active_workspace().index() > target)
direction = Meta.MotionDirection.UP;
else
direction = Meta.MotionDirection.DOWN;
@ -1951,7 +2119,8 @@ var WindowManager = new Lang.Class({
if (!Main.sessionMode.hasWorkspaces)
return;
let activeWorkspace = global.screen.get_active_workspace();
let workspaceManager = global.workspace_manager;
let activeWorkspace = workspaceManager.get_active_workspace();
if (activeWorkspace != workspace)
workspace.activate(global.get_current_time());
@ -1961,7 +2130,8 @@ var WindowManager = new Lang.Class({
if (!Main.sessionMode.hasWorkspaces)
return;
let activeWorkspace = global.screen.get_active_workspace();
let workspaceManager = global.workspace_manager;
let activeWorkspace = workspaceManager.get_active_workspace();
if (activeWorkspace != workspace) {
// This won't have any effect for "always sticky" windows

View File

@ -126,16 +126,15 @@ var WindowMenu = new Lang.Class({
}
}
let screen = global.screen;
let nMonitors = screen.get_n_monitors();
if (nMonitors > 1) {
let display = global.display;
let nMonitors = display.get_n_monitors();
let monitorIndex = window.get_monitor();
if (nMonitors > 1 && monitorIndex >= 0) {
this.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
let monitorIndex = window.get_monitor();
let dir = Meta.ScreenDirection.UP;
let upMonitorIndex =
screen.get_monitor_neighbor_index(monitorIndex, dir);
display.get_monitor_neighbor_index(monitorIndex, dir);
if (upMonitorIndex != -1) {
this.addAction(_("Move to Monitor Up"), () => {
window.move_to_monitor(upMonitorIndex);
@ -144,7 +143,7 @@ var WindowMenu = new Lang.Class({
dir = Meta.ScreenDirection.DOWN;
let downMonitorIndex =
screen.get_monitor_neighbor_index(monitorIndex, dir);
display.get_monitor_neighbor_index(monitorIndex, dir);
if (downMonitorIndex != -1) {
this.addAction(_("Move to Monitor Down"), () => {
window.move_to_monitor(downMonitorIndex);
@ -153,7 +152,7 @@ var WindowMenu = new Lang.Class({
dir = Meta.ScreenDirection.LEFT;
let leftMonitorIndex =
screen.get_monitor_neighbor_index(monitorIndex, dir);
display.get_monitor_neighbor_index(monitorIndex, dir);
if (leftMonitorIndex != -1) {
this.addAction(_("Move to Monitor Left"), () => {
window.move_to_monitor(leftMonitorIndex);
@ -162,7 +161,7 @@ var WindowMenu = new Lang.Class({
dir = Meta.ScreenDirection.RIGHT;
let rightMonitorIndex =
screen.get_monitor_neighbor_index(monitorIndex, dir);
display.get_monitor_neighbor_index(monitorIndex, dir);
if (rightMonitorIndex != -1) {
this.addAction(_("Move to Monitor Right"), () => {
window.move_to_monitor(rightMonitorIndex);

View File

@ -137,8 +137,10 @@ var WindowClone = new Lang.Class({
this._dragSlot = [0, 0, 0, 0];
this._stackAbove = null;
this._windowClone._updateId = this.metaWindow.connect('size-changed',
this._onRealWindowSizeChanged.bind(this));
this._windowClone._sizeChangedId = this.metaWindow.connect('size-changed',
this._onMetaWindowSizeChanged.bind(this));
this._windowClone._posChangedId = this.metaWindow.connect('position-changed',
this._computeBoundingBox.bind(this));
this._windowClone._destroyId =
this.realWindow.connect('destroy', () => {
// First destroy the clone and then destroy everything
@ -177,6 +179,7 @@ var WindowClone = new Lang.Class({
this.inDrag = false;
this._selected = false;
this._closeRequested = false;
},
set slot(slot) {
@ -192,7 +195,6 @@ var WindowClone = new Lang.Class({
deleteAll() {
// Delete all windows, starting from the bottom-most (most-modal) one
let windows = this.actor.get_children();
for (let i = windows.length - 1; i >= 1; i--) {
let realWindow = windows[i].source;
@ -202,12 +204,24 @@ var WindowClone = new Lang.Class({
}
this.metaWindow.delete(global.get_current_time());
this._closeRequested = true;
},
addAttachedDialog(win) {
this._doAddAttachedDialog(win, win.get_compositor_private());
this._computeBoundingBox();
this.emit('size-changed');
addDialog(win) {
let parent = win.get_transient_for();
while (parent.is_attached_dialog())
parent = parent.get_transient_for();
// Display dialog if it is attached to our metaWindow
if (win.is_attached_dialog() && parent == this.metaWindow) {
this._doAddAttachedDialog(win, win.get_compositor_private());
this._onMetaWindowSizeChanged();
}
// The dialog popped up after the user tried to close the window,
// assume it's a close confirmation and leave the overview
if (this._closeRequested)
this._activate();
},
hasAttachedDialogs() {
@ -216,15 +230,14 @@ var WindowClone = new Lang.Class({
_doAddAttachedDialog(metaWin, realWin) {
let clone = new Clutter.Clone({ source: realWin });
clone._updateId = metaWin.connect('size-changed', () => {
this._computeBoundingBox();
this.emit('size-changed');
});
clone._sizeChangedId = metaWin.connect('size-changed',
this._onMetaWindowSizeChanged.bind(this));
clone._posChangedId = metaWin.connect('position-changed',
this._onMetaWindowSizeChanged.bind(this));
clone._destroyId = realWin.connect('destroy', () => {
clone.destroy();
this._computeBoundingBox();
this.emit('size-changed');
this._onMetaWindowSizeChanged();
});
this.actor.add_child(clone);
},
@ -321,12 +334,13 @@ var WindowClone = new Lang.Class({
else
realWindow = child.source;
realWindow.meta_window.disconnect(child._updateId);
realWindow.meta_window.disconnect(child._sizeChangedId);
realWindow.meta_window.disconnect(child._posChangedId);
realWindow.disconnect(child._destroyId);
});
},
_onRealWindowSizeChanged() {
_onMetaWindowSizeChanged() {
this._computeBoundingBox();
this.emit('size-changed');
},
@ -447,12 +461,13 @@ var WindowOverlay = new Lang.Class({
this.border = new St.Bin({ style_class: 'window-clone-border' });
let title = new St.Label({ style_class: 'window-caption',
text: metaWindow.title });
text: this._getCaption() });
title.clutter_text.ellipsize = Pango.EllipsizeMode.END;
windowClone.actor.label_actor = title;
this._updateCaptionId = metaWindow.connect('notify::title', w => {
this.title.text = w.title;
this.title.text = this._getCaption();
this.relayout(false);
});
@ -460,14 +475,12 @@ var WindowOverlay = new Lang.Class({
button._overlap = 0;
this._idleToggleCloseId = 0;
button.connect('clicked', this._closeWindow.bind(this));
button.connect('clicked', () => this._windowClone.deleteAll());
windowClone.actor.connect('destroy', this._onDestroy.bind(this));
windowClone.connect('show-chrome', this._onShowChrome.bind(this));
windowClone.connect('hide-chrome', this._onHideChrome.bind(this));
this._windowAddedId = 0;
button.hide();
title.hide();
@ -565,6 +578,16 @@ var WindowOverlay = new Lang.Class({
}
},
_getCaption() {
let metaWindow = this._windowClone.metaWindow;
if (metaWindow.title)
return metaWindow.title;
let tracker = Shell.WindowTracker.get_default();
let app = tracker.get_window_app(metaWindow);
return app.get_name();
},
_animateOverlayActor(actor, x, y, width, height) {
let params = { x: x,
y: y,
@ -578,43 +601,12 @@ var WindowOverlay = new Lang.Class({
Tweener.addTween(actor, params);
},
_closeWindow(actor) {
let metaWindow = this._windowClone.metaWindow;
this._workspace = metaWindow.get_workspace();
this._windowAddedId = this._workspace.connect('window-added',
this._onWindowAdded.bind(this));
this._windowClone.deleteAll();
},
_windowCanClose() {
return this._windowClone.metaWindow.can_close() &&
!this._windowClone.hasAttachedDialogs();
},
_onWindowAdded(workspace, win) {
let metaWindow = this._windowClone.metaWindow;
if (win.get_transient_for() == metaWindow) {
workspace.disconnect(this._windowAddedId);
this._windowAddedId = 0;
// use an idle handler to avoid mapping problems -
// see comment in Workspace._windowAdded
let id = Mainloop.idle_add(() => {
this._windowClone.emit('selected');
return GLib.SOURCE_REMOVE;
});
GLib.Source.set_name_by_id(id, '[gnome-shell] this._windowClone.emit');
}
},
_onDestroy() {
if (this._windowAddedId > 0) {
this._workspace.disconnect(this._windowAddedId);
this._windowAddedId = 0;
}
if (this._idleToggleCloseId > 0) {
Mainloop.source_remove(this._idleToggleCloseId);
this._idleToggleCloseId = 0;
@ -1145,10 +1137,10 @@ var Workspace = new Lang.Class({
this._windowRemovedId = this.metaWorkspace.connect('window-removed',
this._windowRemoved.bind(this));
}
this._windowEnteredMonitorId = global.screen.connect('window-entered-monitor',
this._windowEnteredMonitor.bind(this));
this._windowLeftMonitorId = global.screen.connect('window-left-monitor',
this._windowLeftMonitor.bind(this));
this._windowEnteredMonitorId = global.display.connect('window-entered-monitor',
this._windowEnteredMonitor.bind(this));
this._windowLeftMonitorId = global.display.connect('window-left-monitor',
this._windowLeftMonitor.bind(this));
this._repositionWindowsId = 0;
this.leavingOverview = false;
@ -1294,7 +1286,8 @@ var Workspace = new Lang.Class({
let area = padArea(this._actualGeometry, padding);
let slots = strategy.computeWindowSlots(layout, area);
let currentWorkspace = global.screen.get_active_workspace();
let workspaceManager = global.workspace_manager;
let currentWorkspace = workspaceManager.get_active_workspace();
let isOnCurrentWorkspace = this.metaWorkspace == null || this.metaWorkspace == currentWorkspace;
for (let i = 0; i < slots.length; i++) {
@ -1431,34 +1424,26 @@ var Workspace = new Lang.Class({
_doRemoveWindow(metaWin) {
let win = metaWin.get_compositor_private();
// find the position of the window in our list
let index = this._lookupIndex (metaWin);
let clone = this._removeWindowClone(metaWin);
if (index == -1)
return;
let clone = this._windows[index];
this._windows.splice(index, 1);
this._windowOverlays.splice(index, 1);
// If metaWin.get_compositor_private() returned non-NULL, that
// means the window still exists (and is just being moved to
// another workspace or something), so set its overviewHint
// accordingly. (If it returned NULL, then the window is being
// destroyed; we'd like to animate this, but it's too late at
// this point.)
if (win) {
let [stageX, stageY] = clone.actor.get_transformed_position();
let [stageWidth, stageHeight] = clone.actor.get_transformed_size();
win._overviewHint = {
x: stageX,
y: stageY,
scale: stageWidth / clone.actor.width
};
if (clone) {
// If metaWin.get_compositor_private() returned non-NULL, that
// means the window still exists (and is just being moved to
// another workspace or something), so set its overviewHint
// accordingly. (If it returned NULL, then the window is being
// destroyed; we'd like to animate this, but it's too late at
// this point.)
if (win) {
let [stageX, stageY] = clone.actor.get_transformed_position();
let [stageWidth, stageHeight] = clone.actor.get_transformed_size();
win._overviewHint = {
x: stageX,
y: stageY,
scale: stageWidth / clone.actor.width
};
}
clone.destroy();
}
clone.destroy();
// We need to reposition the windows; to avoid shuffling windows
// around while the user is interacting with the workspace, we delay
@ -1511,21 +1496,17 @@ var Workspace = new Lang.Class({
return;
if (!this._isOverviewWindow(win)) {
if (metaWin.is_attached_dialog()) {
let parent = metaWin.get_transient_for();
while (parent.is_attached_dialog())
parent = metaWin.get_transient_for();
if (metaWin.get_transient_for() == null)
return;
let idx = this._lookupIndex (parent);
if (idx < 0) {
// parent was not created yet, it will take care
// of the dialog when created
return;
}
// Let the top-most ancestor handle all transients
let parent = metaWin.find_root_ancestor();
let clone = this._windows.find(c => c.metaWindow == parent);
let clone = this._windows[idx];
clone.addAttachedDialog(metaWin);
}
// If no clone was found, the parent hasn't been created yet
// and will take care of the dialog when added
if (clone)
clone.addDialog(metaWin);
return;
}
@ -1557,13 +1538,13 @@ var Workspace = new Lang.Class({
this._doRemoveWindow(metaWin);
},
_windowEnteredMonitor(metaScreen, monitorIndex, metaWin) {
_windowEnteredMonitor(metaDisplay, monitorIndex, metaWin) {
if (monitorIndex == this.monitorIndex) {
this._doAddWindow(metaWin);
}
},
_windowLeftMonitor(metaScreen, monitorIndex, metaWin) {
_windowLeftMonitor(metaDisplay, monitorIndex, metaWin) {
if (monitorIndex == this.monitorIndex) {
this._doRemoveWindow(metaWin);
}
@ -1588,7 +1569,9 @@ var Workspace = new Lang.Class({
if (this._windows.length == 0)
return;
if (this.metaWorkspace != null && this.metaWorkspace != global.screen.get_active_workspace())
let workspaceManager = global.workspace_manager;
let activeWorkspace = workspaceManager.get_active_workspace();
if (this.metaWorkspace != null && this.metaWorkspace != activeWorkspace)
return;
// Special case maximized windows, since it doesn't make sense
@ -1644,7 +1627,9 @@ var Workspace = new Lang.Class({
this._repositionWindowsId = 0;
}
if (this.metaWorkspace != null && this.metaWorkspace != global.screen.get_active_workspace())
let workspaceManager = global.workspace_manager;
let activeWorkspace = workspaceManager.get_active_workspace();
if (this.metaWorkspace != null && this.metaWorkspace != activeWorkspace)
return;
// Special case maximized windows, since it doesn't make sense
@ -1714,7 +1699,8 @@ var Workspace = new Lang.Class({
},
zoomFromOverview() {
let currentWorkspace = global.screen.get_active_workspace();
let workspaceManager = global.workspace_manager;
let currentWorkspace = workspaceManager.get_active_workspace();
this.leavingOverview = true;
@ -1782,8 +1768,8 @@ var Workspace = new Lang.Class({
this.metaWorkspace.disconnect(this._windowAddedId);
this.metaWorkspace.disconnect(this._windowRemovedId);
}
global.screen.disconnect(this._windowEnteredMonitorId);
global.screen.disconnect(this._windowLeftMonitorId);
global.display.disconnect(this._windowEnteredMonitorId);
global.display.disconnect(this._windowLeftMonitorId);
if (this._repositionWindowsId > 0) {
Mainloop.source_remove(this._repositionWindowsId);
@ -1848,6 +1834,9 @@ var Workspace = new Lang.Class({
clone.connect('size-changed', () => {
this._recalculateWindowPositions(WindowPositionFlags.NONE);
});
clone.actor.connect('destroy', () => {
this._removeWindowClone(clone.metaWindow);
});
this.actor.add_actor(clone.actor);
@ -1869,6 +1858,17 @@ var Workspace = new Lang.Class({
return [clone, overlay];
},
_removeWindowClone(metaWin) {
// find the position of the window in our list
let index = this._lookupIndex (metaWin);
if (index == -1)
return null;
this._windowOverlays.splice(index, 1);
return this._windows.splice(index, 1).pop();
},
_onShowOverlayClose(windowOverlay) {
for (let i = 0; i < this._windowOverlays.length; i++) {
let overlay = this._windowOverlays[i];
@ -2004,7 +2004,8 @@ var Workspace = new Lang.Class({
if (metaWindow.get_monitor() != this.monitorIndex)
metaWindow.move_to_monitor(this.monitorIndex);
let index = this.metaWorkspace ? this.metaWorkspace.index() : global.screen.get_active_workspace_index();
let workspaceManager = global.workspace_manager;
let index = this.metaWorkspace ? this.metaWorkspace.index() : workspaceManager.get_active_workspace_index();
metaWindow.change_workspace_by_index(index, false);
return true;
} else if (source.shellWorkspaceLaunch) {

View File

@ -47,9 +47,12 @@ var WorkspaceSwitcherPopup = new Lang.Class({
this.actor.hide();
this._globalSignals = [];
this._globalSignals.push(global.screen.connect('workspace-added', this._redisplay.bind(this)));
this._globalSignals.push(global.screen.connect('workspace-removed', this._redisplay.bind(this)));
let workspaceManager = global.workspace_manager;
this._workspaceManagerSignals = [];
this._workspaceManagerSignals.push(workspaceManager.connect('workspace-added',
this._redisplay.bind(this)));
this._workspaceManagerSignals.push(workspaceManager.connect('workspace-removed',
this._redisplay.bind(this)));
},
_getPreferredHeight(actor, forWidth, alloc) {
@ -68,11 +71,12 @@ var WorkspaceSwitcherPopup = new Lang.Class({
height += childNaturalHeight * workArea.width / workArea.height;
}
let spacing = this._itemSpacing * (global.screen.n_workspaces - 1);
let workspaceManager = global.workspace_manager;
let spacing = this._itemSpacing * (workspaceManager.n_workspaces - 1);
height += spacing;
height = Math.min(height, availHeight);
this._childHeight = (height - spacing) / global.screen.n_workspaces;
this._childHeight = (height - spacing) / workspaceManager.n_workspaces;
alloc.min_size = height;
alloc.natural_size = height;
@ -104,9 +108,11 @@ var WorkspaceSwitcherPopup = new Lang.Class({
},
_redisplay() {
let workspaceManager = global.workspace_manager;
this._list.destroy_all_children();
for (let i = 0; i < global.screen.n_workspaces; i++) {
for (let i = 0; i < workspaceManager.n_workspaces; i++) {
let indicator = null;
if (i == this._activeWorkspaceIndex && this._direction == Meta.MotionDirection.UP)
@ -164,8 +170,9 @@ var WorkspaceSwitcherPopup = new Lang.Class({
Mainloop.source_remove(this._timeoutId);
this._timeoutId = 0;
for (let i = 0; i < this._globalSignals.length; i++)
global.screen.disconnect(this._globalSignals[i]);
let workspaceManager = global.workspace_manager;
for (let i = 0; i < this._workspaceManagerSignals.length; i++)
workspaceManager.disconnect(this._workspaceManagerSignals[i]);
this.actor.destroy();

View File

@ -31,7 +31,7 @@ var WORKSPACE_CUT_SIZE = 10;
var WORKSPACE_KEEP_ALIVE_TIME = 100;
const OVERRIDE_SCHEMA = 'org.gnome.shell.overrides';
var OVERRIDE_SCHEMA = 'org.gnome.shell.overrides';
/* A layout manager that requests size only for primary_actor, but then allocates
all using a fixed layout */
@ -68,7 +68,7 @@ var WindowClone = new Lang.Class({
this.realWindow = realWindow;
this.metaWindow = realWindow.meta_window;
this.clone._updateId = this.metaWindow.connect('position-changed',
this.clone._updateId = this.realWindow.connect('notify::position',
this._onPositionChanged.bind(this));
this.clone._destroyId = this.realWindow.connect('destroy', () => {
// First destroy the clone and then destroy everything
@ -153,7 +153,7 @@ var WindowClone = new Lang.Class({
let clone = new Clutter.Clone({ source: realDialog });
this._updateDialogPosition(realDialog, clone);
clone._updateId = metaDialog.connect('position-changed', dialog => {
clone._updateId = realDialog.connect('notify::position', dialog => {
this._updateDialogPosition(dialog, clone);
});
clone._destroyId = realDialog.connect('destroy', () => {
@ -171,7 +171,6 @@ var WindowClone = new Lang.Class({
},
_onPositionChanged() {
let rect = this.metaWindow.get_frame_rect();
this.actor.set_position(this.realWindow.x, this.realWindow.y);
},
@ -179,7 +178,7 @@ var WindowClone = new Lang.Class({
this.actor.get_children().forEach(child => {
let realWindow = child.source;
realWindow.meta_window.disconnect(child._updateId);
realWindow.disconnect(child._updateId);
realWindow.disconnect(child._destroyId);
});
},
@ -241,7 +240,7 @@ var WindowClone = new Lang.Class({
Signals.addSignalMethods(WindowClone.prototype);
const ThumbnailState = {
var ThumbnailState = {
NEW : 0,
ANIMATING_IN : 1,
NORMAL: 2,
@ -304,9 +303,9 @@ var WorkspaceThumbnail = new Lang.Class({
this._windowAdded.bind(this));
this._windowRemovedId = this.metaWorkspace.connect('window-removed',
this._windowRemoved.bind(this));
this._windowEnteredMonitorId = global.screen.connect('window-entered-monitor',
this._windowEnteredMonitor.bind(this));
this._windowLeftMonitorId = global.screen.connect('window-left-monitor',
this._windowEnteredMonitorId = global.display.connect('window-entered-monitor',
this._windowEnteredMonitor.bind(this));
this._windowLeftMonitorId = global.display.connect('window-left-monitor',
this._windowLeftMonitor.bind(this));
this.state = ThumbnailState.NORMAL;
@ -372,18 +371,9 @@ var WorkspaceThumbnail = new Lang.Class({
},
_doRemoveWindow(metaWin) {
let win = metaWin.get_compositor_private();
// find the position of the window in our list
let index = this._lookupIndex (metaWin);
if (index == -1)
return;
let clone = this._windows[index];
this._windows.splice(index, 1);
clone.destroy();
let clone = this._removeWindowClone(metaWin);
if (clone)
clone.destroy();
},
_doAddWindow(metaWin) {
@ -426,7 +416,7 @@ var WorkspaceThumbnail = new Lang.Class({
} else if (metaWin.is_attached_dialog()) {
let parent = metaWin.get_transient_for();
while (parent.is_attached_dialog())
parent = metaWin.get_transient_for();
parent = parent.get_transient_for();
let idx = this._lookupIndex (parent);
if (idx < 0) {
@ -455,13 +445,13 @@ var WorkspaceThumbnail = new Lang.Class({
this._doRemoveWindow(metaWin);
},
_windowEnteredMonitor(metaScreen, monitorIndex, metaWin) {
_windowEnteredMonitor(metaDisplay, monitorIndex, metaWin) {
if (monitorIndex == this.monitorIndex) {
this._doAddWindow(metaWin);
}
},
_windowLeftMonitor(metaScreen, monitorIndex, metaWin) {
_windowLeftMonitor(metaDisplay, monitorIndex, metaWin) {
if (monitorIndex == this.monitorIndex) {
this._doRemoveWindow(metaWin);
}
@ -487,8 +477,8 @@ var WorkspaceThumbnail = new Lang.Class({
this.metaWorkspace.disconnect(this._windowAddedId);
this.metaWorkspace.disconnect(this._windowRemovedId);
global.screen.disconnect(this._windowEnteredMonitorId);
global.screen.disconnect(this._windowLeftMonitorId);
global.display.disconnect(this._windowEnteredMonitorId);
global.display.disconnect(this._windowLeftMonitorId);
for (let i = 0; i < this._allWindows.length; i++)
this._allWindows[i].disconnect(this._minimizedChangedIds[i]);
@ -535,6 +525,9 @@ var WorkspaceThumbnail = new Lang.Class({
clone.connect('drag-end', () => {
Main.overview.endWindowDrag(clone.metaWindow);
});
clone.actor.connect('destroy', () => {
this._removeWindowClone(clone.metaWindow);
});
this._contents.add_actor(clone.actor);
if (this._windows.length == 0)
@ -547,12 +540,24 @@ var WorkspaceThumbnail = new Lang.Class({
return clone;
},
_removeWindowClone(metaWin) {
// find the position of the window in our list
let index = this._lookupIndex (metaWin);
if (index == -1)
return null;
return this._windows.splice(index, 1).pop();
},
activate(time) {
if (this.state > ThumbnailState.NORMAL)
return;
// a click on the already current workspace should go back to the main view
if (this.metaWorkspace == global.screen.get_active_workspace())
let workspaceManager = global.workspace_manager;
let activeWorkspace = workspaceManager.get_active_workspace();
if (this.metaWorkspace == activeWorkspace)
Main.overview.hide();
else
this.metaWorkspace.activate(time);
@ -673,13 +678,24 @@ var ThumbnailsBox = new Lang.Class({
this._settings.connect('changed::dynamic-workspaces',
this._updateSwitcherVisibility.bind(this));
Main.layoutManager.connect('monitors-changed', this._rebuildThumbnails.bind(this));
Main.layoutManager.connect('monitors-changed', () => {
this._destroyThumbnails();
if (Main.overview.visible)
this._createThumbnails();
});
this._switchWorkspaceNotifyId = 0;
this._nWorkspacesNotifyId = 0;
this._syncStackingId = 0;
this._workareasChangedId = 0;
},
_updateSwitcherVisibility() {
let workspaceManager = global.workspace_manager;
this.actor.visible =
this._settings.get_boolean('dynamic-workspaces') ||
global.screen.n_workspaces > 1;
workspaceManager.n_workspaces > 1;
},
_activateThumbnailAtPoint(stageX, stageY, time) {
@ -837,7 +853,8 @@ var ThumbnailsBox = new Lang.Class({
// to open its first window within some time, as tracked by Shell.WindowTracker.
// Here, we only add a very brief timeout to avoid the _immediate_ removal of the
// workspace while we wait for the startup sequence to load.
Main.wm.keepWorkspaceAlive(global.screen.get_workspace_by_index(newWorkspaceIndex),
let workspaceManager = global.workspace_manager;
Main.wm.keepWorkspaceAlive(workspaceManager.get_workspace_by_index(newWorkspaceIndex),
WORKSPACE_KEEP_ALIVE_TIME);
}
@ -856,19 +873,18 @@ var ThumbnailsBox = new Lang.Class({
},
_createThumbnails() {
let workspaceManager = global.workspace_manager;
this._switchWorkspaceNotifyId =
global.window_manager.connect('switch-workspace',
this._activeWorkspaceChanged.bind(this));
this._nWorkspacesNotifyId =
global.screen.connect('notify::n-workspaces',
this._workspacesChanged.bind(this));
workspaceManager.connect('notify::n-workspaces',
this._workspacesChanged.bind(this));
this._syncStackingId =
Main.overview.connect('windows-restacked',
this._syncStacking.bind(this));
this._workareasChangedId =
global.screen.connect('workareas-changed', this._rebuildThumbnails.bind(this));
this._targetScale = 0;
this._scale = 0;
this._pendingScaleUpdate = false;
@ -878,18 +894,22 @@ var ThumbnailsBox = new Lang.Class({
for (let key in ThumbnailState)
this._stateCounts[ThumbnailState[key]] = 0;
this.addThumbnails(0, global.screen.n_workspaces);
this.addThumbnails(0, workspaceManager.n_workspaces);
this._updateSwitcherVisibility();
},
_destroyThumbnails() {
if (this._thumbnails.length == 0)
return;
if (this._switchWorkspaceNotifyId > 0) {
global.window_manager.disconnect(this._switchWorkspaceNotifyId);
this._switchWorkspaceNotifyId = 0;
}
if (this._nWorkspacesNotifyId > 0) {
global.screen.disconnect(this._nWorkspacesNotifyId);
let workspaceManager = global.workspace_manager;
workspaceManager.disconnect(this._nWorkspacesNotifyId);
this._nWorkspacesNotifyId = 0;
}
@ -898,30 +918,19 @@ var ThumbnailsBox = new Lang.Class({
this._syncStackingId = 0;
}
if (this._workareasChangedId > 0) {
global.screen.disconnect(this._workareasChangedId);
this._workareasChangedId = 0;
}
for (let w = 0; w < this._thumbnails.length; w++)
this._thumbnails[w].destroy();
this._thumbnails = [];
this._porthole = null;
},
_rebuildThumbnails() {
this._destroyThumbnails();
if (Main.overview.visible)
this._createThumbnails();
},
_workspacesChanged() {
let validThumbnails =
this._thumbnails.filter(t => t.state <= ThumbnailState.NORMAL);
let workspaceManager = global.workspace_manager;
let oldNumWorkspaces = validThumbnails.length;
let newNumWorkspaces = global.screen.n_workspaces;
let active = global.screen.get_active_workspace_index();
let newNumWorkspaces = workspaceManager.n_workspaces;
let active = workspaceManager.get_active_workspace_index();
if (newNumWorkspaces > oldNumWorkspaces) {
this.addThumbnails(oldNumWorkspaces, newNumWorkspaces - oldNumWorkspaces);
@ -929,7 +938,7 @@ var ThumbnailsBox = new Lang.Class({
let removedIndex;
let removedNum = oldNumWorkspaces - newNumWorkspaces;
for (let w = 0; w < oldNumWorkspaces; w++) {
let metaWorkspace = global.screen.get_workspace_by_index(w);
let metaWorkspace = workspaceManager.get_workspace_by_index(w);
if (this._thumbnails[w].metaWorkspace != metaWorkspace) {
removedIndex = w;
break;
@ -943,10 +952,12 @@ var ThumbnailsBox = new Lang.Class({
},
addThumbnails(start, count) {
let workspaceManager = global.workspace_manager;
if (!this._ensurePorthole())
return;
for (let k = start; k < start + count; k++) {
let metaWorkspace = global.screen.get_workspace_by_index(k);
let metaWorkspace = workspaceManager.get_workspace_by_index(k);
let thumbnail = new WorkspaceThumbnail(metaWorkspace);
thumbnail.setPorthole(this._porthole.x, this._porthole.y,
this._porthole.width, this._porthole.height);
@ -1132,10 +1143,11 @@ var ThumbnailsBox = new Lang.Class({
return;
}
let workspaceManager = global.workspace_manager;
let themeNode = this.actor.get_theme_node();
let spacing = themeNode.get_length('spacing');
let nWorkspaces = global.screen.n_workspaces;
let nWorkspaces = workspaceManager.n_workspaces;
let totalSpacing = (nWorkspaces - 1) * spacing;
alloc.min_size = totalSpacing;
@ -1149,10 +1161,11 @@ var ThumbnailsBox = new Lang.Class({
return;
}
let workspaceManager = global.workspace_manager;
let themeNode = this.actor.get_theme_node();
let spacing = this.actor.get_theme_node().get_length('spacing');
let nWorkspaces = global.screen.n_workspaces;
let nWorkspaces = workspaceManager.n_workspaces;
let totalSpacing = (nWorkspaces - 1) * spacing;
let avail = forHeight - totalSpacing;
@ -1183,6 +1196,7 @@ var ThumbnailsBox = new Lang.Class({
if (this._thumbnails.length == 0) // not visible
return;
let workspaceManager = global.workspace_manager;
let themeNode = this.actor.get_theme_node();
let portholeWidth = this._porthole.width;
@ -1190,7 +1204,7 @@ var ThumbnailsBox = new Lang.Class({
let spacing = themeNode.get_length('spacing');
// Compute the scale we'll need once everything is updated
let nWorkspaces = global.screen.n_workspaces;
let nWorkspaces = workspaceManager.n_workspaces;
let totalSpacing = (nWorkspaces - 1) * spacing;
let avail = (box.y2 - box.y1) - totalSpacing;
@ -1224,7 +1238,8 @@ var ThumbnailsBox = new Lang.Class({
let indicatorY1 = this._indicatorY;
let indicatorY2;
// when not animating, the workspace position overrides this._indicatorY
let indicatorWorkspace = !this._animatingIndicator ? global.screen.get_active_workspace() : null;
let activeWorkspace = workspaceManager.get_active_workspace();
let indicatorWorkspace = !this._animatingIndicator ? activeWorkspace : null;
let indicatorThemeNode = this._indicator.get_theme_node();
let indicatorTopFullBorder = indicatorThemeNode.get_padding(St.Side.TOP) + indicatorThemeNode.get_border_width(St.Side.TOP);
@ -1315,7 +1330,8 @@ var ThumbnailsBox = new Lang.Class({
_activeWorkspaceChanged(wm, from, to, direction) {
let thumbnail;
let activeWorkspace = global.screen.get_active_workspace();
let workspaceManager = global.workspace_manager;
let activeWorkspace = workspaceManager.get_active_workspace();
for (let i = 0; i < this._thumbnails.length; i++) {
if (this._thumbnails[i].metaWorkspace == activeWorkspace) {
thumbnail = this._thumbnails[i];

View File

@ -91,25 +91,29 @@ var WorkspacesView = new Lang.Class({
Extends: WorkspacesViewBase,
_init(monitorIndex) {
let workspaceManager = global.workspace_manager;
this.parent(monitorIndex);
this._animating = false; // tweening
this._scrolling = false; // swipe-scrolling
this._animatingScroll = false; // programatically updating the adjustment
let activeWorkspaceIndex = global.screen.get_active_workspace_index();
let activeWorkspaceIndex = workspaceManager.get_active_workspace_index();
this.scrollAdjustment = new St.Adjustment({ value: activeWorkspaceIndex,
lower: 0,
page_increment: 1,
page_size: 1,
step_increment: 0,
upper: global.screen.n_workspaces });
upper: workspaceManager.n_workspaces });
this.scrollAdjustment.connect('notify::value',
this._onScroll.bind(this));
this._workspaces = [];
this._updateWorkspaces();
this._updateWorkspacesId = global.screen.connect('notify::n-workspaces', this._updateWorkspaces.bind(this));
this._updateWorkspacesId =
workspaceManager.connect('notify::n-workspaces',
this._updateWorkspaces.bind(this));
this._overviewShownId =
Main.overview.connect('shown', () => {
@ -138,7 +142,8 @@ var WorkspacesView = new Lang.Class({
},
getActiveWorkspace() {
let active = global.screen.get_active_workspace_index();
let workspaceManager = global.workspace_manager;
let active = workspaceManager.get_active_workspace_index();
return this._workspaces[active];
},
@ -169,7 +174,8 @@ var WorkspacesView = new Lang.Class({
},
_scrollToActive() {
let active = global.screen.get_active_workspace_index();
let workspaceManager = global.workspace_manager;
let active = workspaceManager.get_active_workspace_index();
this._updateWorkspaceActors(true);
this._updateScrollAdjustment(active);
@ -178,7 +184,8 @@ var WorkspacesView = new Lang.Class({
// Update workspace actors parameters
// @showAnimation: iff %true, transition between states
_updateWorkspaceActors(showAnimation) {
let active = global.screen.get_active_workspace_index();
let workspaceManager = global.workspace_manager;
let active = workspaceManager.get_active_workspace_index();
this._animating = showAnimation;
@ -214,7 +221,8 @@ var WorkspacesView = new Lang.Class({
},
_updateVisibility() {
let active = global.screen.get_active_workspace_index();
let workspaceManager = global.workspace_manager;
let active = workspaceManager.get_active_workspace_index();
for (let w = 0; w < this._workspaces.length; w++) {
let workspace = this._workspaces[w];
@ -246,13 +254,14 @@ var WorkspacesView = new Lang.Class({
},
_updateWorkspaces() {
let newNumWorkspaces = global.screen.n_workspaces;
let workspaceManager = global.workspace_manager;
let newNumWorkspaces = workspaceManager.n_workspaces;
this.scrollAdjustment.upper = newNumWorkspaces;
let needsUpdate = false;
for (let j = 0; j < newNumWorkspaces; j++) {
let metaWorkspace = global.screen.get_workspace_by_index(j);
let metaWorkspace = workspaceManager.get_workspace_by_index(j);
let workspace;
if (j >= this._workspaces.length) { /* added */
@ -290,7 +299,8 @@ var WorkspacesView = new Lang.Class({
this.scrollAdjustment.run_dispose();
Main.overview.disconnect(this._overviewShownId);
global.window_manager.disconnect(this._switchWorkspaceNotifyId);
global.screen.disconnect(this._updateWorkspacesId);
let workspaceManager = global.workspace_manager;
workspaceManager.disconnect(this._updateWorkspacesId);
},
startSwipeScroll() {
@ -311,7 +321,8 @@ var WorkspacesView = new Lang.Class({
if (this._animatingScroll)
return;
let active = global.screen.get_active_workspace_index();
let workspaceManager = global.workspace_manager;
let active = workspaceManager.get_active_workspace_index();
let current = Math.round(adj.value);
if (active != current) {
@ -593,7 +604,7 @@ var WorkspacesDisplay = new Lang.Class({
_getMonitorIndexForEvent(event) {
let [x, y] = event.get_coords();
let rect = new Meta.Rectangle({ x: x, y: y, width: 1, height: 1 });
return global.screen.get_monitor_index_for_rect(rect);
return global.display.get_monitor_index_for_rect(rect);
},
_getPrimaryView() {
@ -679,7 +690,8 @@ var WorkspacesDisplay = new Lang.Class({
this._getMonitorIndexForEvent(event) != this._primaryIndex)
return Clutter.EVENT_PROPAGATE;
let activeWs = global.screen.get_active_workspace();
let workspaceManager = global.workspace_manager;
let activeWs = workspaceManager.get_active_workspace();
let ws;
switch (event.get_scroll_direction()) {
case Clutter.ScrollDirection.UP:
@ -698,7 +710,8 @@ var WorkspacesDisplay = new Lang.Class({
_onKeyPressEvent(actor, event) {
if (!this.actor.mapped)
return Clutter.EVENT_PROPAGATE;
let activeWs = global.screen.get_active_workspace();
let workspaceManager = global.workspace_manager;
let activeWs = workspaceManager.get_active_workspace();
let ws;
switch (event.get_key_symbol()) {
case Clutter.KEY_Page_Up:

View File

@ -1,12 +1,12 @@
project('gnome-shell', 'c',
version: '3.28.1',
meson_version: '>= 0.42.0',
version: '3.29.91',
meson_version: '>= 0.47.0',
license: 'GPLv2+'
)
# We depend on a specific version of the libmutter API. The mutter variants of
# the Cogl and Clutter libraries also use this API version.
mutter_api_version = '2'
mutter_api_version = '3'
clutter_pc = 'mutter-clutter-' + mutter_api_version
cogl_pc = 'mutter-cogl-' + mutter_api_version
@ -23,15 +23,15 @@ gi_req = '>= 1.49.1'
gjs_req = '>= 1.47.0'
gtk_req = '>= 3.15.0'
json_glib_req = '>= 0.13.2'
mutter_req = '>= 3.28.0'
mutter_req = '>= 3.29.91'
polkit_req = '>= 0.100'
schemas_req = '>= 3.21.3'
schemas_req = '>= 3.27.90'
startup_req = '>= 0.11'
ibus_req = '>= 1.5.2'
bt_req = '>= 3.9.0'
gst_req = '>= 0.11.92'
nm_req = '>= 0.9.8'
nm_req = '>= 1.10.4'
secret_req = '>= 0.18'
gnome = import('gnome')
@ -44,10 +44,12 @@ datadir = join_paths(prefix, get_option('datadir'))
libdir = join_paths(prefix, get_option('libdir'))
libexecdir = join_paths(prefix, get_option('libexecdir'))
mandir = join_paths(prefix, get_option('mandir'))
sysconfdir = join_paths(prefix, get_option('sysconfdir'))
pkgdatadir = join_paths(datadir, meson.project_name())
pkglibdir = join_paths(libdir, meson.project_name())
autostartdir = join_paths(sysconfdir, 'xdg', 'autostart')
convertdir = join_paths(datadir, 'GConf', 'gsettings')
desktopdir = join_paths(datadir, 'applications')
ifacedir = join_paths(datadir, 'dbus-1', 'interfaces')
@ -59,6 +61,13 @@ servicedir = join_paths(datadir, 'dbus-1', 'services')
plugindir = get_variable('BROWSER_PLUGIN_DIR', mozplugindir)
# XXX: Once https://github.com/systemd/systemd/issues/9595 is fixed and we can
# depend on this version, replace with something like:
# systemduserunitdir = systemd_dep.get_pkgconfig_variable('systemduserunitdir',
# define_variable: ['prefix', prefix])
# and uncomment systemd_dep below
systemduserunitdir = join_paths(prefix, 'lib', 'systemd', 'user')
keybindings_dep = dependency('gnome-keybindings', required: false)
if keybindings_dep.found()
keysdir = keybindings_dep.get_pkgconfig_variable('keysdir')
@ -117,10 +126,12 @@ else
endif
if get_option('systemd')
systemd_dep = dependency('libsystemd')
have_systemd = systemd_dep.found()
libsystemd_dep = dependency('libsystemd')
# XXX: see systemduserunitdir
# systemd_dep = dependency('systemd')
have_systemd = true
else
systemd_dep = []
libsystemd_dep = []
have_systemd = false
endif
@ -152,6 +163,11 @@ cdata.set_quoted('PACKAGE_VERSION', meson.project_version())
cdata.set('HAVE_NETWORKMANAGER', have_networkmanager)
cdata.set('HAVE_SYSTEMD', have_systemd)
# New API added in glib-2.57.2
cdata.set('HAVE_GIO_DESKTOP_LAUNCH_URIS_WITH_FDS',
cc.has_function('g_desktop_app_info_launch_uris_as_manager_with_fds',
dependencies : gio_dep)
)
cdata.set('HAVE_FDWALK', cc.has_function('fdwalk'))
cdata.set('HAVE_MALLINFO', cc.has_function('mallinfo'))
cdata.set('HAVE_SYS_RESOURCE_H', cc.has_header('sys/resource.h'))
@ -159,6 +175,10 @@ cdata.set('HAVE__NL_TIME_FIRST_WEEKDAY',
cc.has_header_symbol('langinfo.h', '_NL_TIME_FIRST_WEEKDAY')
)
cdata.set('HAVE_FDWALK',
cc.has_function('fdwalk')
)
config_h = configure_file(
input: 'config.h.meson',
output: 'config.h',
@ -185,6 +205,7 @@ subdir('src')
subdir('po')
subdir('data')
subdir('tests')
subdir('tools')
if get_option('gtk_doc')
subdir('docs/reference')

View File

@ -40,6 +40,7 @@ js/ui/messageList.js
js/ui/messageTray.js
js/ui/mpris.js
js/ui/notificationDaemon.js
js/ui/osdWindow.js
js/ui/overviewControls.js
js/ui/overview.js
js/ui/padOsd.js
@ -58,6 +59,7 @@ js/ui/status/location.js
js/ui/status/network.js
js/ui/status/nightLight.js
js/ui/status/power.js
js/ui/status/remoteAccess.js
js/ui/status/rfkill.js
js/ui/status/system.js
js/ui/status/thunderbolt.js

265
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: 2018-03-10 12:32+0000\n"
"POT-Creation-Date: 2018-08-01 18:08+0000\n"
"PO-Revision-Date: 2018-03-10 21:24+0100\n"
"Last-Translator: Robert Antoni Buj Gelonch <rbuj@fedoraproject.org>\n"
"Language-Team: Catalan <tradgnome@softcatala.org>\n"
@ -299,36 +299,36 @@ 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:197
#: data/org.gnome.shell.gschema.xml.in:198
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:198
#: data/org.gnome.shell.gschema.xml.in:207
#: data/org.gnome.shell.gschema.xml.in:215
#: data/org.gnome.shell.gschema.xml.in:223
#: data/org.gnome.shell.gschema.xml.in:231
#: data/org.gnome.shell.gschema.xml.in:199
#: data/org.gnome.shell.gschema.xml.in:208
#: data/org.gnome.shell.gschema.xml.in:216
#: data/org.gnome.shell.gschema.xml.in:224
#: data/org.gnome.shell.gschema.xml.in:232
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»."
#: data/org.gnome.shell.gschema.xml.in:206
#: data/org.gnome.shell.gschema.xml.in:207
msgid "Enable edge tiling when dropping windows on screen edges"
msgstr ""
"Habilita el mòsaic a les vores en deixar anar les finestres a les vores de "
"la pantalla"
#: data/org.gnome.shell.gschema.xml.in:214
#: data/org.gnome.shell.gschema.xml.in:215
msgid "Workspaces are managed dynamically"
msgstr "Els espais de treball es gestionen dinàmicament"
#: data/org.gnome.shell.gschema.xml.in:222
#: data/org.gnome.shell.gschema.xml.in:223
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:230
#: data/org.gnome.shell.gschema.xml.in:231
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 "
@ -349,7 +349,7 @@ msgid "There was an error loading the preferences dialog for %s:"
msgstr "S'ha produït un error en carregar el diàleg de preferències de %s:"
#: js/gdm/authPrompt.js:147 js/ui/audioDeviceSelection.js:71
#: js/ui/components/networkAgent.js:117 js/ui/components/polkitAgent.js:148
#: js/ui/components/networkAgent.js:117 js/ui/components/polkitAgent.js:153
#: js/ui/endSessionDialog.js:482 js/ui/extensionDownloader.js:197
#: js/ui/shellMountOperation.js:343 js/ui/status/network.js:919
msgid "Cancel"
@ -369,20 +369,20 @@ msgctxt "button"
msgid "Sign In"
msgstr "Entra"
#: js/gdm/loginDialog.js:315
#: js/gdm/loginDialog.js:319
msgid "Choose Session"
msgstr "Trieu la sessió"
#. translators: this message is shown below the user list on the
#. login screen. It can be activated to reveal an entry for
#. manually entering the username.
#: js/gdm/loginDialog.js:458
#: js/gdm/loginDialog.js:462
msgid "Not listed?"
msgstr "No esteu llistat?"
#. Translators: this message is shown below the username entry field
#. to clue the user in on how to login to the local network realm
#: js/gdm/loginDialog.js:887
#: js/gdm/loginDialog.js:891
#, javascript-format
msgid "(e.g., user or %s)"
msgstr "(p. ex. l'usuari o %s)"
@ -390,12 +390,12 @@ msgstr "(p. ex. l'usuari o %s)"
#. TTLS and PEAP are actually much more complicated, but this complication
#. is not visible here since we only care about phase2 authentication
#. (and don't even care of which one)
#: js/gdm/loginDialog.js:892 js/ui/components/networkAgent.js:243
#: js/gdm/loginDialog.js:896 js/ui/components/networkAgent.js:243
#: js/ui/components/networkAgent.js:261
msgid "Username: "
msgstr "Nom d'usuari:"
#: js/gdm/loginDialog.js:1228
#: js/gdm/loginDialog.js:1234
msgid "Login Window"
msgstr "Finestra d'entrada"
@ -408,7 +408,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:482
#: js/gdm/util.js:485
msgid "(or swipe finger)"
msgstr "(o passeu el dit)"
@ -649,32 +649,32 @@ msgstr "Freqüent"
msgid "All"
msgstr "Totes"
#: js/ui/appDisplay.js:1886
#: js/ui/appDisplay.js:1890
msgid "New Window"
msgstr "Finestra nova"
#: js/ui/appDisplay.js:1900
#: js/ui/appDisplay.js:1904
msgid "Launch using Dedicated Graphics Card"
msgstr "Inicia usant una targeta gràfica dedicada"
#: js/ui/appDisplay.js:1927 js/ui/dash.js:285
#: js/ui/appDisplay.js:1931 js/ui/dash.js:285
msgid "Remove from Favorites"
msgstr "Suprimeix dels preferits"
#: js/ui/appDisplay.js:1933
#: js/ui/appDisplay.js:1937
msgid "Add to Favorites"
msgstr "Afegeix als preferits"
#: js/ui/appDisplay.js:1943
#: js/ui/appDisplay.js:1947
msgid "Show Details"
msgstr "Mostra els detalls"
#: js/ui/appFavorites.js:138
#: js/ui/appFavorites.js:140
#, javascript-format
msgid "%s has been added to your favorites."
msgstr "S'ha afegit %s als preferits."
#: js/ui/appFavorites.js:172
#: js/ui/appFavorites.js:174
#, javascript-format
msgid "%s has been removed from your favorites."
msgstr "S'ha suprimit %s dels preferits."
@ -695,7 +695,7 @@ msgstr "Auriculars"
msgid "Headset"
msgstr "Auriculars amb micròfon"
#: js/ui/audioDeviceSelection.js:82 js/ui/status/volume.js:221
#: js/ui/audioDeviceSelection.js:82 js/ui/status/volume.js:255
msgid "Microphone"
msgstr "Micròfon"
@ -707,7 +707,7 @@ msgstr "Canvia el fons de l'escriptori…"
msgid "Display Settings"
msgstr "Paràmetres de la pantalla"
#: js/ui/backgroundMenu.js:22 js/ui/status/system.js:264
#: js/ui/backgroundMenu.js:22
msgid "Settings"
msgstr "Paràmetres"
@ -812,35 +812,35 @@ msgctxt "event list time"
msgid "All Day"
msgstr "Tot el dia"
#: js/ui/calendar.js:864
#: js/ui/calendar.js:866
msgctxt "calendar heading"
msgid "%A, %B %d"
msgstr "%A %-d %B"
#: js/ui/calendar.js:868
#: js/ui/calendar.js:870
msgctxt "calendar heading"
msgid "%A, %B %d, %Y"
msgstr "%A %d %B de %Y"
#: js/ui/calendar.js:1086
#: js/ui/calendar.js:1100
msgid "No Notifications"
msgstr "Cap notificació"
#: js/ui/calendar.js:1089
#: js/ui/calendar.js:1103
msgid "No Events"
msgstr "Cap cita"
#: js/ui/calendar.js:1117
#: js/ui/calendar.js:1131
msgid "Clear All"
msgstr "Neteja-ho tot"
#. Translators: %s is an application name
#: js/ui/closeDialog.js:44
#: js/ui/closeDialog.js:47
#, javascript-format
msgid "“%s” is not responding."
msgstr "«%s» no està responent."
#: js/ui/closeDialog.js:45
#: js/ui/closeDialog.js:48
msgid ""
"You may choose to wait a short while for it to continue or force the "
"application to quit entirely."
@ -848,11 +848,11 @@ msgstr ""
"Podeu esperar un moment perquè continuï o podeu forçar-ne la sortida "
"completa."
#: js/ui/closeDialog.js:61
#: js/ui/closeDialog.js:64
msgid "Force Quit"
msgstr "Força la sortida"
#: js/ui/closeDialog.js:64
#: js/ui/closeDialog.js:67
msgid "Wait"
msgstr "Espera"
@ -869,7 +869,7 @@ msgstr "S'ha desconnectat un dispositiu extern"
msgid "Open with %s"
msgstr "Obre amb %s"
#: js/ui/components/keyring.js:107 js/ui/components/polkitAgent.js:284
#: js/ui/components/keyring.js:107 js/ui/components/polkitAgent.js:297
msgid "Password:"
msgstr "Contrasenya:"
@ -906,11 +906,11 @@ msgstr "Contrasenya de la clau privada:"
msgid "Service: "
msgstr "Servei:"
#: js/ui/components/networkAgent.js:292 js/ui/components/networkAgent.js:659
#: js/ui/components/networkAgent.js:292 js/ui/components/networkAgent.js:664
msgid "Authentication required by wireless network"
msgstr "La xarxa sense fil requereix autenticació"
#: js/ui/components/networkAgent.js:293 js/ui/components/networkAgent.js:660
#: js/ui/components/networkAgent.js:293 js/ui/components/networkAgent.js:665
#, javascript-format
msgid ""
"Passwords or encryption keys are required to access the wireless network "
@ -919,7 +919,7 @@ msgstr ""
"Per accedir a la xarxa sense fil «%s» calen les contrasenyes o les claus "
"d'encriptació."
#: js/ui/components/networkAgent.js:297 js/ui/components/networkAgent.js:663
#: js/ui/components/networkAgent.js:297 js/ui/components/networkAgent.js:668
msgid "Wired 802.1X authentication"
msgstr "Autenticació 802.1X amb fil"
@ -927,15 +927,15 @@ msgstr "Autenticació 802.1X amb fil"
msgid "Network name: "
msgstr "Nom de la xarxa: "
#: js/ui/components/networkAgent.js:304 js/ui/components/networkAgent.js:667
#: js/ui/components/networkAgent.js:304 js/ui/components/networkAgent.js:672
msgid "DSL authentication"
msgstr "Autenticació DSL"
#: js/ui/components/networkAgent.js:311 js/ui/components/networkAgent.js:673
#: js/ui/components/networkAgent.js:311 js/ui/components/networkAgent.js:678
msgid "PIN code required"
msgstr "Cal que introduïu el codi PIN"
#: js/ui/components/networkAgent.js:312 js/ui/components/networkAgent.js:674
#: js/ui/components/networkAgent.js:312 js/ui/components/networkAgent.js:679
msgid "PIN code is needed for the mobile broadband device"
msgstr "Cal que introduïu el codi PIN del dispositiu de banda ampla mòbil"
@ -943,29 +943,29 @@ msgstr "Cal que introduïu el codi PIN del dispositiu de banda ampla mòbil"
msgid "PIN: "
msgstr "PIN: "
#: js/ui/components/networkAgent.js:320 js/ui/components/networkAgent.js:680
#: js/ui/components/networkAgent.js:320 js/ui/components/networkAgent.js:685
msgid "Mobile broadband network password"
msgstr "Contrasenya de la xarxa de banda ampla mòbil"
#: js/ui/components/networkAgent.js:321 js/ui/components/networkAgent.js:664
#: js/ui/components/networkAgent.js:668 js/ui/components/networkAgent.js:681
#: js/ui/components/networkAgent.js:321 js/ui/components/networkAgent.js:669
#: js/ui/components/networkAgent.js:673 js/ui/components/networkAgent.js:686
#, javascript-format
msgid "A password is required to connect to “%s”."
msgstr "Cal introduir una contrasenya per connectar-vos a «%s»."
#: js/ui/components/networkAgent.js:648 js/ui/status/network.js:1691
#: js/ui/components/networkAgent.js:653 js/ui/status/network.js:1704
msgid "Network Manager"
msgstr "Gestor de connexions de xarxa"
#: js/ui/components/polkitAgent.js:43
#: js/ui/components/polkitAgent.js:48
msgid "Authentication Required"
msgstr "Cal autenticació"
#: js/ui/components/polkitAgent.js:71
#: js/ui/components/polkitAgent.js:76
msgid "Administrator"
msgstr "Administrador"
#: js/ui/components/polkitAgent.js:151
#: js/ui/components/polkitAgent.js:156
msgid "Authenticate"
msgstr "Autentica"
@ -973,7 +973,7 @@ msgstr "Autentica"
#. * requested authentication was not gained; this can happen
#. * because of an authentication error (like invalid password),
#. * for instance.
#: js/ui/components/polkitAgent.js:270 js/ui/shellMountOperation.js:327
#: js/ui/components/polkitAgent.js:283 js/ui/shellMountOperation.js:327
msgid "Sorry, that didnt work. Please try again."
msgstr "No ha funcionat. Torneu-ho a provar."
@ -1021,7 +1021,7 @@ msgstr "Afegeix rellotges del món…"
msgid "World Clocks"
msgstr "Rellotges del món"
#: js/ui/dateMenu.js:225
#: js/ui/dateMenu.js:227
msgid "Weather"
msgstr "El temps"
@ -1029,7 +1029,7 @@ msgstr "El temps"
#. libgweather for the possible condition strings. If at all
#. possible, the sentence should match the grammatical case etc. of
#. the inserted conditions.
#: js/ui/dateMenu.js:289
#: js/ui/dateMenu.js:291
#, javascript-format
msgid "%s all day."
msgstr "%s tot el dia."
@ -1038,7 +1038,7 @@ msgstr "%s tot el dia."
#. libgweather for the possible condition strings. If at all
#. possible, the sentence should match the grammatical case etc. of
#. the inserted conditions.
#: js/ui/dateMenu.js:295
#: js/ui/dateMenu.js:297
#, javascript-format
msgid "%s, then %s later."
msgstr "%s, llavors %s més tard."
@ -1047,30 +1047,30 @@ msgstr "%s, llavors %s més tard."
#. libgweather for the possible condition strings. If at all
#. possible, the sentence should match the grammatical case etc. of
#. the inserted conditions.
#: js/ui/dateMenu.js:301
#: js/ui/dateMenu.js:303
#, javascript-format
msgid "%s, then %s, followed by %s later."
msgstr "%s, llavors %s, seguit per %s més tard."
#: js/ui/dateMenu.js:312
#: js/ui/dateMenu.js:314
msgid "Select a location…"
msgstr "Trieu una ubicació…"
#: js/ui/dateMenu.js:315
#: js/ui/dateMenu.js:317
msgid "Loading…"
msgstr "S'està carregant…"
#. Translators: %s is a temperature with unit, e.g. "23℃"
#: js/ui/dateMenu.js:321
#: js/ui/dateMenu.js:323
#, javascript-format
msgid "Feels like %s."
msgstr "Sensació tèrmica de %s."
#: js/ui/dateMenu.js:324
#: js/ui/dateMenu.js:326
msgid "Go online for weather information"
msgstr "Vés en línia per a informació sobre el temps"
#: js/ui/dateMenu.js:326
#: js/ui/dateMenu.js:328
msgid "Weather information is currently unavailable"
msgstr "La informació sobre el temps no està disponible"
@ -1308,13 +1308,13 @@ msgid "Leave On"
msgstr "Deixa-ho actiu"
#: js/ui/kbdA11yDialog.js:59 js/ui/status/bluetooth.js:143
#: js/ui/status/network.js:1281
#: js/ui/status/network.js:1294
msgid "Turn On"
msgstr "Activa"
#: js/ui/kbdA11yDialog.js:67 js/ui/status/bluetooth.js:143
#: js/ui/status/network.js:154 js/ui/status/network.js:337
#: js/ui/status/network.js:1281 js/ui/status/network.js:1396
#: js/ui/status/network.js:1294 js/ui/status/network.js:1409
#: js/ui/status/nightLight.js:47 js/ui/status/rfkill.js:90
#: js/ui/status/rfkill.js:117
msgid "Turn Off"
@ -1376,7 +1376,7 @@ msgstr "Mostra el codi font"
msgid "Web Page"
msgstr "Pàgina web"
#: js/ui/messageTray.js:1493
#: js/ui/messageTray.js:1495
msgid "System Information"
msgstr "Informació de l'ordinador"
@ -1388,6 +1388,10 @@ msgstr "Artista desconegut"
msgid "Unknown title"
msgstr "Títol desconegut"
#: js/ui/osdWindow.js:32 js/ui/status/volume.js:204
msgid "Volume"
msgstr "Volum"
#: js/ui/overview.js:83
msgid "Undo"
msgstr "Desfés"
@ -1430,42 +1434,42 @@ msgstr "Assigna la pulsació de tecla"
msgid "Done"
msgstr "Fet"
#: js/ui/padOsd.js:740
#: js/ui/padOsd.js:742
msgid "Edit…"
msgstr "Edita…"
#: js/ui/padOsd.js:782 js/ui/padOsd.js:887
#: js/ui/padOsd.js:784 js/ui/padOsd.js:889
msgid "None"
msgstr "Cap"
#: js/ui/padOsd.js:841
#: js/ui/padOsd.js:843
msgid "Press a button to configure"
msgstr "Premeu un botó per a configurar"
#: js/ui/padOsd.js:842
#: js/ui/padOsd.js:844
msgid "Press Esc to exit"
msgstr "Premeu Esc per sortir"
#: js/ui/padOsd.js:845
#: js/ui/padOsd.js:847
msgid "Press any key to exit"
msgstr "Premeu qualsevol tecla per sortir"
#: js/ui/panel.js:355
#: js/ui/panel.js:356
msgid "Quit"
msgstr "Surt"
#. Translators: If there is no suitable word for "Activities"
#. in your language, you can use the word for "Overview".
#: js/ui/panel.js:411
#: js/ui/panel.js:412
msgid "Activities"
msgstr "Activitats"
#: js/ui/panel.js:692
#: js/ui/panel.js:693
msgctxt "System menu in the top bar"
msgid "System"
msgstr "Sistema"
#: js/ui/panel.js:811
#: js/ui/panel.js:816
msgid "Top Bar"
msgstr "Barra superior"
@ -1474,23 +1478,23 @@ msgstr "Barra superior"
#. "ON" and "OFF") or "toggle-switch-intl" (for toggle
#. switches containing "◯" and "|"). Other values will
#. simply result in invisible toggle switches.
#: js/ui/popupMenu.js:291
#: js/ui/popupMenu.js:300
msgid "toggle-switch-us"
msgstr "toggle-switch-intl"
#: js/ui/runDialog.js:70
#: js/ui/runDialog.js:74
msgid "Enter a Command"
msgstr "Introduïu una ordre"
#: js/ui/runDialog.js:110 js/ui/windowMenu.js:175
#: js/ui/runDialog.js:114 js/ui/windowMenu.js:174
msgid "Close"
msgstr "Tanca"
#: js/ui/runDialog.js:273
#: js/ui/runDialog.js:278
msgid "Restart is not available on Wayland"
msgstr "El reinici no està disponible en Wayland"
#: js/ui/runDialog.js:278
#: js/ui/runDialog.js:283
msgid "Restarting…"
msgstr "S'està reiniciant…"
@ -1514,7 +1518,7 @@ msgid_plural "%d new notifications"
msgstr[0] "%d notificació nova"
msgstr[1] "%d notificacions noves"
#: js/ui/screenShield.js:451 js/ui/status/system.js:283
#: js/ui/screenShield.js:451 js/ui/status/system.js:294
msgid "Lock"
msgstr "Bloqueja"
@ -1697,7 +1701,7 @@ msgid "<unknown>"
msgstr "<desconegut>"
#. Translators: %s is a network identifier
#: js/ui/status/network.js:441 js/ui/status/network.js:1310
#: js/ui/status/network.js:441 js/ui/status/network.js:1323
#, javascript-format
msgid "%s Off"
msgstr "%s apagat"
@ -1724,7 +1728,7 @@ msgid "%s Disconnecting"
msgstr "%s s'està desconnectant"
#. Translators: %s is a network identifier
#: js/ui/status/network.js:459 js/ui/status/network.js:1302
#: js/ui/status/network.js:459 js/ui/status/network.js:1315
#, javascript-format
msgid "%s Connecting"
msgstr "%s s'està connectant"
@ -1764,7 +1768,7 @@ msgid "Mobile Broadband Settings"
msgstr "Configuració de la xarxa de banda ampla mòbil"
#. Translators: %s is a network identifier
#: js/ui/status/network.js:578 js/ui/status/network.js:1307
#: js/ui/status/network.js:578 js/ui/status/network.js:1320
#, javascript-format
msgid "%s Hardware Disabled"
msgstr "%s maquinari inhabilitat"
@ -1820,81 +1824,81 @@ msgstr "Cap xarxa"
msgid "Use hardware switch to turn off"
msgstr "Utilitza l'interruptor de maquinari per desactivar-la"
#: js/ui/status/network.js:1173
#: js/ui/status/network.js:1186
msgid "Select Network"
msgstr "Trieu una xarxa"
#: js/ui/status/network.js:1179
#: js/ui/status/network.js:1192
msgid "Wi-Fi Settings"
msgstr "Paràmetres de la xarxa sense fil"
#. Translators: %s is a network identifier
#: js/ui/status/network.js:1298
#: js/ui/status/network.js:1311
#, javascript-format
msgid "%s Hotspot Active"
msgstr "Hostpot %s actiu"
#. Translators: %s is a network identifier
#: js/ui/status/network.js:1313
#: js/ui/status/network.js:1326
#, javascript-format
msgid "%s Not Connected"
msgstr "%s no està connectat"
#: js/ui/status/network.js:1413
#: js/ui/status/network.js:1426
msgid "connecting…"
msgstr "s'està connectant..."
#. Translators: this is for network connections that require some kind of key or password
#: js/ui/status/network.js:1416
#: js/ui/status/network.js:1429
msgid "authentication required"
msgstr "cal autenticació"
#: js/ui/status/network.js:1418
#: js/ui/status/network.js:1431
msgid "connection failed"
msgstr "ha fallat la connexió"
#: js/ui/status/network.js:1472
#: js/ui/status/network.js:1485
msgid "VPN Settings"
msgstr "Paràmetres de la VPN"
#: js/ui/status/network.js:1485
#: js/ui/status/network.js:1498
msgid "VPN"
msgstr "VPN"
#: js/ui/status/network.js:1495
#: js/ui/status/network.js:1508
msgid "VPN Off"
msgstr "VPN apagada"
#: js/ui/status/network.js:1559 js/ui/status/rfkill.js:93
#: js/ui/status/network.js:1572 js/ui/status/rfkill.js:93
msgid "Network Settings"
msgstr "Paràmetres de xarxa"
#: js/ui/status/network.js:1588
#: js/ui/status/network.js:1601
#, javascript-format
msgid "%s Wired Connection"
msgid_plural "%s Wired Connections"
msgstr[0] "%s connexió amb fil"
msgstr[1] "%s connexions amb fil"
#: js/ui/status/network.js:1592
#: js/ui/status/network.js:1605
#, javascript-format
msgid "%s Wi-Fi Connection"
msgid_plural "%s Wi-Fi Connections"
msgstr[0] "%s connexió Wifi"
msgstr[1] "%s connexions Wifi"
#: js/ui/status/network.js:1596
#: js/ui/status/network.js:1609
#, javascript-format
msgid "%s Modem Connection"
msgid_plural "%s Modem Connections"
msgstr[0] "%s connexió mòdem"
msgstr[1] "%s connexions mòdem"
#: js/ui/status/network.js:1728
#: js/ui/status/network.js:1741
msgid "Connection failed"
msgstr "Ha fallat la connexió"
#: js/ui/status/network.js:1729
#: js/ui/status/network.js:1742
msgid "Activation of network connection failed"
msgstr "Ha fallat l'activació de la connexió de xarxa"
@ -1945,6 +1949,14 @@ msgstr "%d%02d per completar la càrrega (%d %%)"
msgid "%d%%"
msgstr "%d%%"
#: js/ui/status/remoteAccess.js:46
msgid "Screen is Being Shared"
msgstr "Es comparteix la pantalla"
#: js/ui/status/remoteAccess.js:48
msgid "Turn off"
msgstr "Desactiva"
#. The menu only appears when airplane mode is on, so just
#. statically build it as if it was on, rather than dynamically
#. changing the menu contents.
@ -1964,51 +1976,48 @@ msgstr "Surt"
msgid "Account Settings"
msgstr "Paràmetres del compte"
#: js/ui/status/system.js:268
#: js/ui/status/system.js:279
msgid "Orientation Lock"
msgstr "Bloqueja l'orientació"
#: js/ui/status/system.js:294
#: js/ui/status/system.js:305
msgid "Suspend"
msgstr "Atura temporalment"
#: js/ui/status/system.js:304
#: js/ui/status/system.js:315
msgid "Power Off"
msgstr "Apaga"
#: js/ui/status/thunderbolt.js:294
#: js/ui/status/thunderbolt.js:298
msgid "Thunderbolt"
msgstr "Thunderbolt"
#. we are done
#: js/ui/status/thunderbolt.js:350
#: js/ui/status/thunderbolt.js:354
msgid "Unknown Thunderbolt device"
msgstr "Dispostiu Thunderbolt desconegut"
#: js/ui/status/thunderbolt.js:351
#: js/ui/status/thunderbolt.js:355
msgid ""
"New device has been detected while you were away. Please disconnect and "
"reconnect the device to start using it."
msgstr ""
"El nou dispositiu s'ha detectat mentre estàveu absents. Desconnecteu i torneu a connectar el dispositiu per a començar a utilitzar-lo."
"El nou dispositiu s'ha detectat mentre estàveu absents. Desconnecteu i "
"torneu a connectar el dispositiu per a començar a utilitzar-lo."
#: js/ui/status/thunderbolt.js:356
#: js/ui/status/thunderbolt.js:360
msgid "Thunderbolt authorization error"
msgstr "S'ha produït un error d'autorització a Thunderbolt"
#: js/ui/status/thunderbolt.js:357
#: js/ui/status/thunderbolt.js:361
#, javascript-format
msgid "Could not authorize the thunderbolt device: %s"
msgstr "No s'ha pogut autoritzar el dispositiu thunderbolt: %s"
msgid "Could not authorize the Thunderbolt device: %s"
msgstr "No s'ha pogut autoritzar el dispositiu Thunderbolt: %s"
#: js/ui/status/volume.js:128
#: js/ui/status/volume.js:135
msgid "Volume changed"
msgstr "S'ha canviat el volum"
#: js/ui/status/volume.js:170
msgid "Volume"
msgstr "Volum"
#. Translators: this is for display mirroring i.e. cloning.
#. * Try to keep it under around 15 characters.
#.
@ -2058,22 +2067,22 @@ msgstr "Cerca"
msgid "“%s” is ready"
msgstr "«%s» ja està a punt"
#: js/ui/windowManager.js:72
#: js/ui/windowManager.js:74
msgid "Do you want to keep these display settings?"
msgstr "Voleu mantenir aquesta configuració de la pantalla?"
#. Translators: this and the following message should be limited in lenght,
#. to avoid ellipsizing the labels.
#.
#: js/ui/windowManager.js:84
#: js/ui/windowManager.js:86
msgid "Revert Settings"
msgstr "Descarta els canvis"
#: js/ui/windowManager.js:87
#: js/ui/windowManager.js:89
msgid "Keep Changes"
msgstr "Mantén els canvis"
#: js/ui/windowManager.js:105
#: js/ui/windowManager.js:107
#, javascript-format
msgid "Settings changes will revert in %d second"
msgid_plural "Settings changes will revert in %d seconds"
@ -2082,7 +2091,7 @@ msgstr[1] "Es descartaran els canvis d'aquí %d segons"
#. Translators: This represents the size of a window. The first number is
#. * the width of the window and the second is the height.
#: js/ui/windowManager.js:660
#: js/ui/windowManager.js:689
#, javascript-format
msgid "%d × %d"
msgstr "%d × %d"
@ -2135,19 +2144,19 @@ msgstr "Mou a l'espai de treball superior"
msgid "Move to Workspace Down"
msgstr "Mou a l'espai de treball inferior"
#: js/ui/windowMenu.js:140
#: js/ui/windowMenu.js:139
msgid "Move to Monitor Up"
msgstr "Mou a la pantalla de dalt"
#: js/ui/windowMenu.js:149
#: js/ui/windowMenu.js:148
msgid "Move to Monitor Down"
msgstr "Mou a la pantalla de baix"
#: js/ui/windowMenu.js:158
#: js/ui/windowMenu.js:157
msgid "Move to Monitor Left"
msgstr "Mou a la pantalla de l'esquerra"
#: js/ui/windowMenu.js:167
#: js/ui/windowMenu.js:166
msgid "Move to Monitor Right"
msgstr "Mou a la pantalla de la dreta"
@ -2160,28 +2169,28 @@ msgstr "Calendari de l'Evolution"
msgid "evolution"
msgstr "evolution"
#: src/main.c:432
#: src/main.c:410
msgid "Print version"
msgstr "Mostra la versió"
#: src/main.c:438
#: src/main.c:416
msgid "Mode used by GDM for login screen"
msgstr "El mode que utilitzarà el GDM per a la pantalla d'entrada"
#: src/main.c:444
#: src/main.c:422
msgid "Use a specific mode, e.g. “gdm” for login screen"
msgstr "Utilitza un mode específic, p. ex. «gdm» per la pantalla d'entrada"
#: src/main.c:450
#: src/main.c:428
msgid "List possible modes"
msgstr "Llista els modes possibles"
#: src/shell-app.c:270
#: src/shell-app.c:272
msgctxt "program"
msgid "Unknown"
msgstr "Desconegut"
#: src/shell-app.c:511
#: src/shell-app.c:523
#, c-format
msgid "Failed to launch “%s”"
msgstr "No s'ha pogut iniciar «%s»"

View File

@ -11,8 +11,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: 2018-02-26 12:57+0000\n"
"PO-Revision-Date: 2018-02-26 17:57+0100\n"
"POT-Creation-Date: 2018-04-13 19:54+0000\n"
"PO-Revision-Date: 2018-04-24 17:32+0200\n"
"Last-Translator: Marek Černocký <marek@manet.cz>\n"
"Language-Team: čeština <gnome-cs-list@gnome.org>\n"
"Language: cs\n"
@ -332,7 +332,7 @@ msgstr ""
"Nastala chyba při načítání dialogového okna předvoleb pro rozšíření %s:"
#: js/gdm/authPrompt.js:147 js/ui/audioDeviceSelection.js:71
#: js/ui/components/networkAgent.js:117 js/ui/components/polkitAgent.js:148
#: js/ui/components/networkAgent.js:117 js/ui/components/polkitAgent.js:153
#: js/ui/endSessionDialog.js:482 js/ui/extensionDownloader.js:197
#: js/ui/shellMountOperation.js:343 js/ui/status/network.js:919
msgid "Cancel"
@ -667,12 +667,12 @@ msgstr "Přidat mezi oblíbené"
msgid "Show Details"
msgstr "Zobrazit podrobnosti"
#: js/ui/appFavorites.js:138
#: js/ui/appFavorites.js:140
#, javascript-format
msgid "%s has been added to your favorites."
msgstr "%s byl přidán mezi oblíbené."
#: js/ui/appFavorites.js:172
#: js/ui/appFavorites.js:174
#, javascript-format
msgid "%s has been removed from your favorites."
msgstr "%s byl odstraněn z oblíbených."
@ -867,7 +867,7 @@ msgstr "Externí svazek odpojen"
msgid "Open with %s"
msgstr "Otevřít pomocí %s"
#: js/ui/components/keyring.js:107 js/ui/components/polkitAgent.js:284
#: js/ui/components/keyring.js:107 js/ui/components/polkitAgent.js:295
msgid "Password:"
msgstr "Heslo:"
@ -955,15 +955,15 @@ msgstr "Pro připojení k „%s“ je vyžadováno heslo."
msgid "Network Manager"
msgstr "Network Manager"
#: js/ui/components/polkitAgent.js:43
#: js/ui/components/polkitAgent.js:48
msgid "Authentication Required"
msgstr "Je vyžadováno ověření"
#: js/ui/components/polkitAgent.js:71
#: js/ui/components/polkitAgent.js:76
msgid "Administrator"
msgstr "Správce"
#: js/ui/components/polkitAgent.js:151
#: js/ui/components/polkitAgent.js:156
msgid "Authenticate"
msgstr "Ověřit"
@ -971,7 +971,7 @@ msgstr "Ověřit"
#. * requested authentication was not gained; this can happen
#. * because of an authentication error (like invalid password),
#. * for instance.
#: js/ui/components/polkitAgent.js:270 js/ui/shellMountOperation.js:327
#: js/ui/components/polkitAgent.js:281 js/ui/shellMountOperation.js:327
msgid "Sorry, that didnt work. Please try again."
msgstr "Ověření bohužel nebylo úspěšné. Zkuste to prosím znovu."
@ -1021,7 +1021,7 @@ msgstr "Přidat světový čas…"
msgid "World Clocks"
msgstr "Světové hodiny"
#: js/ui/dateMenu.js:225
#: js/ui/dateMenu.js:227
msgid "Weather"
msgstr "Počasí"
@ -1029,7 +1029,7 @@ msgstr "Počasí"
#. libgweather for the possible condition strings. If at all
#. possible, the sentence should match the grammatical case etc. of
#. the inserted conditions.
#: js/ui/dateMenu.js:289
#: js/ui/dateMenu.js:291
#, javascript-format
msgid "%s all day."
msgstr "%s celý den."
@ -1038,7 +1038,7 @@ msgstr "%s celý den."
#. libgweather for the possible condition strings. If at all
#. possible, the sentence should match the grammatical case etc. of
#. the inserted conditions.
#: js/ui/dateMenu.js:295
#: js/ui/dateMenu.js:297
#, javascript-format
msgid "%s, then %s later."
msgstr "%s, později %s."
@ -1047,30 +1047,30 @@ msgstr "%s, později %s."
#. libgweather for the possible condition strings. If at all
#. possible, the sentence should match the grammatical case etc. of
#. the inserted conditions.
#: js/ui/dateMenu.js:301
#: js/ui/dateMenu.js:303
#, javascript-format
msgid "%s, then %s, followed by %s later."
msgstr "%s, pak %s a později %s."
#: js/ui/dateMenu.js:312
#: js/ui/dateMenu.js:314
msgid "Select a location…"
msgstr "Vybrat místo…"
#: js/ui/dateMenu.js:315
#: js/ui/dateMenu.js:317
msgid "Loading…"
msgstr "Načítá se…"
#. Translators: %s is a temperature with unit, e.g. "23℃"
#: js/ui/dateMenu.js:321
#: js/ui/dateMenu.js:323
#, javascript-format
msgid "Feels like %s."
msgstr "Pocitově jako %s."
#: js/ui/dateMenu.js:324
#: js/ui/dateMenu.js:326
msgid "Go online for weather information"
msgstr "Připojit se kvůli informacím o počasí"
#: js/ui/dateMenu.js:326
#: js/ui/dateMenu.js:328
msgid "Weather information is currently unavailable"
msgstr "Informace o počasí nejsou nyní dostupné"
@ -1408,7 +1408,7 @@ msgstr "Přehled"
#. characters.
#: js/ui/overview.js:239
msgid "Type to search…"
msgstr "vyhledávejte psaním…"
msgstr "Vyhledávejte psaním…"
#: js/ui/padOsd.js:105
msgid "New shortcut…"
@ -1986,16 +1986,16 @@ msgstr "Uspat do paměti"
msgid "Power Off"
msgstr "Vypnout"
#: js/ui/status/thunderbolt.js:272
#: js/ui/status/thunderbolt.js:294
msgid "Thunderbolt"
msgstr "Thunderbolt"
#. we are done
#: js/ui/status/thunderbolt.js:328
#: js/ui/status/thunderbolt.js:350
msgid "Unknown Thunderbolt device"
msgstr "Neznámé zařízení Thunderbolt"
#: js/ui/status/thunderbolt.js:329
#: js/ui/status/thunderbolt.js:351
msgid ""
"New device has been detected while you were away. Please disconnect and "
"reconnect the device to start using it."
@ -2003,13 +2003,13 @@ msgstr ""
"Zatímco jste byli pryč, bylo nalezeno nové zařízení. Odpojte jej prosím a "
"znovu připojte, abyste jej mohli používat."
#: js/ui/status/thunderbolt.js:334
#: js/ui/status/thunderbolt.js:356
msgid "Thunderbolt authorization error"
msgstr "Chyba ověření Thunderbolt"
#: js/ui/status/thunderbolt.js:335
#: js/ui/status/thunderbolt.js:357
#, javascript-format
msgid "Could not authorize the thunderbolt device: %s"
msgid "Could not authorize the Thunderbolt device: %s"
msgstr "Nezdařilo se provést ověření zařízení Thunderbolt: %s"
#: js/ui/status/volume.js:128
@ -2233,15 +2233,3 @@ msgstr[2] "%u vstupů"
#: subprojects/gvc/gvc-mixer-control.c:2738
msgid "System Sounds"
msgstr "Systémové zvuky"
#~ msgctxt "search-result"
#~ msgid "Power off"
#~ msgstr "Vypnout"
#~ msgctxt "search-result"
#~ msgid "Log out"
#~ msgstr "Odhlásit se"
#~ msgctxt "search-result"
#~ msgid "Switch user"
#~ msgstr "Přepnout uživatele"

460
po/de.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

195
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: 2018-02-22 09:24+0000\n"
"PO-Revision-Date: 2018-02-23 08:26+0100\n"
"POT-Creation-Date: 2018-07-24 18:34+0000\n"
"PO-Revision-Date: 2018-07-27 13:15+0200\n"
"Last-Translator: Daniel Mustieles <daniel.mustieles@gmail.com>\n"
"Language-Team: es <gnome-es-list@gnome.org>\n"
"Language: es\n"
@ -18,7 +18,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: Gtranslator 2.91.6\n"
"X-Generator: Gtranslator 2.91.7\n"
#: data/50-gnome-shell-system.xml:6
msgid "System"
@ -346,7 +346,7 @@ msgid "There was an error loading the preferences dialog for %s:"
msgstr "Hubo un error al lanzar el diálogo de preferencias para %s:"
#: js/gdm/authPrompt.js:147 js/ui/audioDeviceSelection.js:71
#: js/ui/components/networkAgent.js:117 js/ui/components/polkitAgent.js:148
#: js/ui/components/networkAgent.js:117 js/ui/components/polkitAgent.js:153
#: js/ui/endSessionDialog.js:482 js/ui/extensionDownloader.js:197
#: js/ui/shellMountOperation.js:343 js/ui/status/network.js:919
msgid "Cancel"
@ -366,20 +366,20 @@ msgctxt "button"
msgid "Sign In"
msgstr "Iniciar sesión"
#: js/gdm/loginDialog.js:315
#: js/gdm/loginDialog.js:319
msgid "Choose Session"
msgstr "Elegir sesión"
#. translators: this message is shown below the user list on the
#. login screen. It can be activated to reveal an entry for
#. manually entering the username.
#: js/gdm/loginDialog.js:458
#: js/gdm/loginDialog.js:462
msgid "Not listed?"
msgstr "¿No está en la lista?"
#. Translators: this message is shown below the username entry field
#. to clue the user in on how to login to the local network realm
#: js/gdm/loginDialog.js:887
#: js/gdm/loginDialog.js:891
#, javascript-format
msgid "(e.g., user or %s)"
msgstr "(ej., usuario o %s)"
@ -387,12 +387,12 @@ msgstr "(ej., usuario o %s)"
#. TTLS and PEAP are actually much more complicated, but this complication
#. is not visible here since we only care about phase2 authentication
#. (and don't even care of which one)
#: js/gdm/loginDialog.js:892 js/ui/components/networkAgent.js:243
#: js/gdm/loginDialog.js:896 js/ui/components/networkAgent.js:243
#: js/ui/components/networkAgent.js:261
msgid "Username: "
msgstr "Nombre de usuario:"
#: js/gdm/loginDialog.js:1228
#: js/gdm/loginDialog.js:1234
msgid "Login Window"
msgstr "Ventana de inicio de sesión"
@ -405,7 +405,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:482
#: js/gdm/util.js:485
msgid "(or swipe finger)"
msgstr "(o pase el dedo)"
@ -645,32 +645,32 @@ msgstr "Frecuentes"
msgid "All"
msgstr "Todas"
#: js/ui/appDisplay.js:1886
#: js/ui/appDisplay.js:1890
msgid "New Window"
msgstr "Ventana nueva"
#: js/ui/appDisplay.js:1900
#: js/ui/appDisplay.js:1904
msgid "Launch using Dedicated Graphics Card"
msgstr "Lanzar usando la tarjeta gráfica dedicada"
#: js/ui/appDisplay.js:1927 js/ui/dash.js:285
#: js/ui/appDisplay.js:1931 js/ui/dash.js:285
msgid "Remove from Favorites"
msgstr "Quitar de los favoritos"
#: js/ui/appDisplay.js:1933
#: js/ui/appDisplay.js:1937
msgid "Add to Favorites"
msgstr "Añadir a los favoritos"
#: js/ui/appDisplay.js:1943
#: js/ui/appDisplay.js:1947
msgid "Show Details"
msgstr "Mostrar detalles"
#: js/ui/appFavorites.js:138
#: js/ui/appFavorites.js:140
#, javascript-format
msgid "%s has been added to your favorites."
msgstr "Se ha añadido %s a sus favoritos."
#: js/ui/appFavorites.js:172
#: js/ui/appFavorites.js:174
#, javascript-format
msgid "%s has been removed from your favorites."
msgstr "Se ha quitado %s de sus favoritos."
@ -808,35 +808,35 @@ msgctxt "event list time"
msgid "All Day"
msgstr "Todo el día"
#: js/ui/calendar.js:864
#: js/ui/calendar.js:866
msgctxt "calendar heading"
msgid "%A, %B %d"
msgstr "%A, %d de %B"
#: js/ui/calendar.js:868
#: js/ui/calendar.js:870
msgctxt "calendar heading"
msgid "%A, %B %d, %Y"
msgstr "%A, %d de %B de %Y"
#: js/ui/calendar.js:1086
#: js/ui/calendar.js:1100
msgid "No Notifications"
msgstr "No hay notificaciones"
#: js/ui/calendar.js:1089
#: js/ui/calendar.js:1103
msgid "No Events"
msgstr "No hay eventos"
#: js/ui/calendar.js:1117
#: js/ui/calendar.js:1131
msgid "Clear All"
msgstr "Limpiar todo"
#. Translators: %s is an application name
#: js/ui/closeDialog.js:44
#: js/ui/closeDialog.js:47
#, javascript-format
msgid "“%s” is not responding."
msgstr "«%s» no responde."
#: js/ui/closeDialog.js:45
#: js/ui/closeDialog.js:48
msgid ""
"You may choose to wait a short while for it to continue or force the "
"application to quit entirely."
@ -844,11 +844,11 @@ msgstr ""
"Puede elegir esperar un momento para que continúe o forzar a la aplicación a "
"terminar."
#: js/ui/closeDialog.js:61
#: js/ui/closeDialog.js:64
msgid "Force Quit"
msgstr "Forzar la salida"
#: js/ui/closeDialog.js:64
#: js/ui/closeDialog.js:67
msgid "Wait"
msgstr "Esperar"
@ -865,7 +865,7 @@ msgstr "Dispositivo externo desconectado"
msgid "Open with %s"
msgstr "Abrir con %s"
#: js/ui/components/keyring.js:107 js/ui/components/polkitAgent.js:284
#: js/ui/components/keyring.js:107 js/ui/components/polkitAgent.js:297
msgid "Password:"
msgstr "Contraseña:"
@ -902,11 +902,11 @@ msgstr "Contraseña de la clave privada:"
msgid "Service: "
msgstr "Servicio:"
#: js/ui/components/networkAgent.js:292 js/ui/components/networkAgent.js:659
#: js/ui/components/networkAgent.js:292 js/ui/components/networkAgent.js:664
msgid "Authentication required by wireless network"
msgstr "La red inalámbrica requiere autenticación"
#: js/ui/components/networkAgent.js:293 js/ui/components/networkAgent.js:660
#: js/ui/components/networkAgent.js:293 js/ui/components/networkAgent.js:665
#, javascript-format
msgid ""
"Passwords or encryption keys are required to access the wireless network "
@ -915,7 +915,7 @@ msgstr ""
"Se necesitan contraseñas o claves de cifrado para acceder a la red "
"inalámbrica «%s»."
#: js/ui/components/networkAgent.js:297 js/ui/components/networkAgent.js:663
#: js/ui/components/networkAgent.js:297 js/ui/components/networkAgent.js:668
msgid "Wired 802.1X authentication"
msgstr "Autenticación 802.1X cableada"
@ -923,15 +923,15 @@ msgstr "Autenticación 802.1X cableada"
msgid "Network name: "
msgstr "Nombre de la red: "
#: js/ui/components/networkAgent.js:304 js/ui/components/networkAgent.js:667
#: js/ui/components/networkAgent.js:304 js/ui/components/networkAgent.js:672
msgid "DSL authentication"
msgstr "Autenticación DSL"
#: js/ui/components/networkAgent.js:311 js/ui/components/networkAgent.js:673
#: js/ui/components/networkAgent.js:311 js/ui/components/networkAgent.js:678
msgid "PIN code required"
msgstr "Código PIN requerido"
#: js/ui/components/networkAgent.js:312 js/ui/components/networkAgent.js:674
#: js/ui/components/networkAgent.js:312 js/ui/components/networkAgent.js:679
msgid "PIN code is needed for the mobile broadband device"
msgstr "Se necesita un código PIN para el dispositivo de banda ancha móvil"
@ -939,29 +939,29 @@ msgstr "Se necesita un código PIN para el dispositivo de banda ancha móvil"
msgid "PIN: "
msgstr "PIN: "
#: js/ui/components/networkAgent.js:320 js/ui/components/networkAgent.js:680
#: js/ui/components/networkAgent.js:320 js/ui/components/networkAgent.js:685
msgid "Mobile broadband network password"
msgstr "Contraseña de la red de banda ancha móvil"
#: js/ui/components/networkAgent.js:321 js/ui/components/networkAgent.js:664
#: js/ui/components/networkAgent.js:668 js/ui/components/networkAgent.js:681
#: js/ui/components/networkAgent.js:321 js/ui/components/networkAgent.js:669
#: js/ui/components/networkAgent.js:673 js/ui/components/networkAgent.js:686
#, javascript-format
msgid "A password is required to connect to “%s”."
msgstr "Se requiere una contraseña para conectarse a «%s»."
#: js/ui/components/networkAgent.js:648 js/ui/status/network.js:1691
#: js/ui/components/networkAgent.js:653 js/ui/status/network.js:1704
msgid "Network Manager"
msgstr "Gestor de la red"
#: js/ui/components/polkitAgent.js:43
#: js/ui/components/polkitAgent.js:48
msgid "Authentication Required"
msgstr "Se necesita autenticación"
#: js/ui/components/polkitAgent.js:71
#: js/ui/components/polkitAgent.js:76
msgid "Administrator"
msgstr "Administrador"
#: js/ui/components/polkitAgent.js:151
#: js/ui/components/polkitAgent.js:156
msgid "Authenticate"
msgstr "Autenticar"
@ -969,7 +969,7 @@ msgstr "Autenticar"
#. * requested authentication was not gained; this can happen
#. * because of an authentication error (like invalid password),
#. * for instance.
#: js/ui/components/polkitAgent.js:270 js/ui/shellMountOperation.js:327
#: js/ui/components/polkitAgent.js:283 js/ui/shellMountOperation.js:327
msgid "Sorry, that didnt work. Please try again."
msgstr "Eso no ha funcionado. Inténtelo de nuevo."
@ -1017,7 +1017,7 @@ msgstr "Añadir relojes del mundo…"
msgid "World Clocks"
msgstr "Relojes del mundo"
#: js/ui/dateMenu.js:225
#: js/ui/dateMenu.js:227
msgid "Weather"
msgstr "Meteorología"
@ -1025,7 +1025,7 @@ msgstr "Meteorología"
#. libgweather for the possible condition strings. If at all
#. possible, the sentence should match the grammatical case etc. of
#. the inserted conditions.
#: js/ui/dateMenu.js:289
#: js/ui/dateMenu.js:291
#, javascript-format
msgid "%s all day."
msgstr "%s todo el día."
@ -1034,7 +1034,7 @@ msgstr "%s todo el día."
#. libgweather for the possible condition strings. If at all
#. possible, the sentence should match the grammatical case etc. of
#. the inserted conditions.
#: js/ui/dateMenu.js:295
#: js/ui/dateMenu.js:297
#, javascript-format
msgid "%s, then %s later."
msgstr "%s, luego %s."
@ -1043,30 +1043,30 @@ msgstr "%s, luego %s."
#. libgweather for the possible condition strings. If at all
#. possible, the sentence should match the grammatical case etc. of
#. the inserted conditions.
#: js/ui/dateMenu.js:301
#: js/ui/dateMenu.js:303
#, javascript-format
msgid "%s, then %s, followed by %s later."
msgstr "%s, luego %s seguido de %s."
#: js/ui/dateMenu.js:312
#: js/ui/dateMenu.js:314
msgid "Select a location…"
msgstr "Seleccionar ubicación…"
#: js/ui/dateMenu.js:315
#: js/ui/dateMenu.js:317
msgid "Loading…"
msgstr "Cargando…"
#. Translators: %s is a temperature with unit, e.g. "23℃"
#: js/ui/dateMenu.js:321
#: js/ui/dateMenu.js:323
#, javascript-format
msgid "Feels like %s."
msgstr "Sensación térmica de %s."
#: js/ui/dateMenu.js:324
#: js/ui/dateMenu.js:326
msgid "Go online for weather information"
msgstr "Conectarse para obtener la información meteorológica"
#: js/ui/dateMenu.js:326
#: js/ui/dateMenu.js:328
msgid "Weather information is currently unavailable"
msgstr "La información meteorológica no está disponible actualmente."
@ -1301,13 +1301,13 @@ msgid "Leave On"
msgstr "Dejar activada"
#: js/ui/kbdA11yDialog.js:59 js/ui/status/bluetooth.js:143
#: js/ui/status/network.js:1281
#: js/ui/status/network.js:1294
msgid "Turn On"
msgstr "Encender"
#: js/ui/kbdA11yDialog.js:67 js/ui/status/bluetooth.js:143
#: js/ui/status/network.js:154 js/ui/status/network.js:337
#: js/ui/status/network.js:1281 js/ui/status/network.js:1396
#: js/ui/status/network.js:1294 js/ui/status/network.js:1409
#: js/ui/status/nightLight.js:47 js/ui/status/rfkill.js:90
#: js/ui/status/rfkill.js:117
msgid "Turn Off"
@ -1369,7 +1369,7 @@ msgstr "Ver fuente"
msgid "Web Page"
msgstr "Página web"
#: js/ui/messageTray.js:1493
#: js/ui/messageTray.js:1495
msgid "System Information"
msgstr "Información del sistema"
@ -1443,22 +1443,22 @@ msgstr "Pulse Esc para salir"
msgid "Press any key to exit"
msgstr "Pulse cualquier tecla para salir"
#: js/ui/panel.js:355
#: js/ui/panel.js:356
msgid "Quit"
msgstr "Salir"
#. Translators: If there is no suitable word for "Activities"
#. in your language, you can use the word for "Overview".
#: js/ui/panel.js:411
#: js/ui/panel.js:412
msgid "Activities"
msgstr "Actividades"
#: js/ui/panel.js:692
#: js/ui/panel.js:693
msgctxt "System menu in the top bar"
msgid "System"
msgstr "Sistema"
#: js/ui/panel.js:811
#: js/ui/panel.js:816
msgid "Top Bar"
msgstr "Barra superior"
@ -1467,7 +1467,7 @@ msgstr "Barra superior"
#. "ON" and "OFF") or "toggle-switch-intl" (for toggle
#. switches containing "◯" and "|"). Other values will
#. simply result in invisible toggle switches.
#: js/ui/popupMenu.js:291
#: js/ui/popupMenu.js:300
msgid "toggle-switch-us"
msgstr "toggle-switch-intl"
@ -1475,15 +1475,15 @@ msgstr "toggle-switch-intl"
msgid "Enter a Command"
msgstr "Introducir un comando"
#: js/ui/runDialog.js:110 js/ui/windowMenu.js:175
#: js/ui/runDialog.js:110 js/ui/windowMenu.js:174
msgid "Close"
msgstr "Cerrar"
#: js/ui/runDialog.js:273
#: js/ui/runDialog.js:274
msgid "Restart is not available on Wayland"
msgstr "Reiniciar si no está disponible en Wayland"
#: js/ui/runDialog.js:278
#: js/ui/runDialog.js:279
msgid "Restarting…"
msgstr "Reiniciando…"
@ -1690,7 +1690,7 @@ msgid "<unknown>"
msgstr "<desconocido>"
#. Translators: %s is a network identifier
#: js/ui/status/network.js:441 js/ui/status/network.js:1310
#: js/ui/status/network.js:441 js/ui/status/network.js:1323
#, javascript-format
msgid "%s Off"
msgstr "%s apagada"
@ -1716,7 +1716,7 @@ msgid "%s Disconnecting"
msgstr "Desconectando %s"
#. Translators: %s is a network identifier
#: js/ui/status/network.js:459 js/ui/status/network.js:1302
#: js/ui/status/network.js:459 js/ui/status/network.js:1315
#, javascript-format
msgid "%s Connecting"
msgstr "Conectando %s"
@ -1756,7 +1756,7 @@ msgid "Mobile Broadband Settings"
msgstr "Configuración de banda ancha móvil"
#. Translators: %s is a network identifier
#: js/ui/status/network.js:578 js/ui/status/network.js:1307
#: js/ui/status/network.js:578 js/ui/status/network.js:1320
#, javascript-format
msgid "%s Hardware Disabled"
msgstr "Hardware %s desactivado"
@ -1812,81 +1812,81 @@ msgstr "No hay redes"
msgid "Use hardware switch to turn off"
msgstr "Usar el interruptor hardware para apagar"
#: js/ui/status/network.js:1173
#: js/ui/status/network.js:1186
msgid "Select Network"
msgstr "Seleccionar red"
#: js/ui/status/network.js:1179
#: js/ui/status/network.js:1192
msgid "Wi-Fi Settings"
msgstr "Configuración de Wi-Fi"
#. Translators: %s is a network identifier
#: js/ui/status/network.js:1298
#: js/ui/status/network.js:1311
#, javascript-format
msgid "%s Hotspot Active"
msgstr "Punto de acceso %s activo"
#. Translators: %s is a network identifier
#: js/ui/status/network.js:1313
#: js/ui/status/network.js:1326
#, javascript-format
msgid "%s Not Connected"
msgstr "%s no conectado"
#: js/ui/status/network.js:1413
#: js/ui/status/network.js:1426
msgid "connecting…"
msgstr "conectando…"
#. Translators: this is for network connections that require some kind of key or password
#: js/ui/status/network.js:1416
#: js/ui/status/network.js:1429
msgid "authentication required"
msgstr "se necesita autenticación"
#: js/ui/status/network.js:1418
#: js/ui/status/network.js:1431
msgid "connection failed"
msgstr "falló la conexión"
#: js/ui/status/network.js:1472
#: js/ui/status/network.js:1485
msgid "VPN Settings"
msgstr "Configuración de VPN"
#: js/ui/status/network.js:1485
#: js/ui/status/network.js:1498
msgid "VPN"
msgstr "VPN"
#: js/ui/status/network.js:1495
#: js/ui/status/network.js:1508
msgid "VPN Off"
msgstr "VPN apagada"
#: js/ui/status/network.js:1559 js/ui/status/rfkill.js:93
#: js/ui/status/network.js:1572 js/ui/status/rfkill.js:93
msgid "Network Settings"
msgstr "Configuración de la red"
#: js/ui/status/network.js:1588
#: js/ui/status/network.js:1601
#, javascript-format
msgid "%s Wired Connection"
msgid_plural "%s Wired Connections"
msgstr[0] "%s conexión cableada"
msgstr[1] "%s conexiones cableadas"
#: js/ui/status/network.js:1592
#: js/ui/status/network.js:1605
#, javascript-format
msgid "%s Wi-Fi Connection"
msgid_plural "%s Wi-Fi Connections"
msgstr[0] "%s conexión inalámbrica"
msgstr[1] "%s conexiones inalámbricas"
#: js/ui/status/network.js:1596
#: js/ui/status/network.js:1609
#, javascript-format
msgid "%s Modem Connection"
msgid_plural "%s Modem Connections"
msgstr[0] "%s conexión por módem"
msgstr[1] "%s conexiones por módem"
#: js/ui/status/network.js:1728
#: js/ui/status/network.js:1741
msgid "Connection failed"
msgstr "Falló la conexión"
#: js/ui/status/network.js:1729
#: js/ui/status/network.js:1742
msgid "Activation of network connection failed"
msgstr "Falló la activación de la conexión de red"
@ -1937,6 +1937,15 @@ msgstr "%d%02d para la carga completa (%d%%)"
msgid "%d%%"
msgstr "%d%%"
#: js/ui/status/remoteAccess.js:45
msgid "Screen is Being Shared"
msgstr "Se está compartiendo la pantalla"
#: js/ui/status/remoteAccess.js:47
#| msgid "Turn Off"
msgid "Turn off"
msgstr "Apagar"
#. The menu only appears when airplane mode is on, so just
#. statically build it as if it was on, rather than dynamically
#. changing the menu contents.
@ -1968,16 +1977,16 @@ msgstr "Suspender"
msgid "Power Off"
msgstr "Apagar"
#: js/ui/status/thunderbolt.js:272
#: js/ui/status/thunderbolt.js:298
msgid "Thunderbolt"
msgstr "Thunderbolt"
#. we are done
#: js/ui/status/thunderbolt.js:328
#: js/ui/status/thunderbolt.js:354
msgid "Unknown Thunderbolt device"
msgstr "Dispositivo Thunderbolt desconocido"
#: js/ui/status/thunderbolt.js:329
#: js/ui/status/thunderbolt.js:355
msgid ""
"New device has been detected while you were away. Please disconnect and "
"reconnect the device to start using it."
@ -1985,13 +1994,13 @@ msgstr ""
"Se ha detectado un dispositivo nuevo mientras estaba fuera. Desconéctelo y "
"vuélvalo a conectar para empezar a usarlo."
#: js/ui/status/thunderbolt.js:334
#: js/ui/status/thunderbolt.js:360
msgid "Thunderbolt authorization error"
msgstr "Error de autorización de Thunderbolt"
#: js/ui/status/thunderbolt.js:335
#: js/ui/status/thunderbolt.js:361
#, javascript-format
msgid "Could not authorize the thunderbolt device: %s"
msgid "Could not authorize the Thunderbolt device: %s"
msgstr "No se pudo autorizar el dispositivo Thunderbolt: %s"
#: js/ui/status/volume.js:128
@ -2075,7 +2084,7 @@ msgstr[1] "La configuración se revertirá en %d segundos"
#. Translators: This represents the size of a window. The first number is
#. * the width of the window and the second is the height.
#: js/ui/windowManager.js:660
#: js/ui/windowManager.js:668
#, javascript-format
msgid "%d × %d"
msgstr "%d × %d"
@ -2128,19 +2137,19 @@ msgstr "Subir a un área de trabajo"
msgid "Move to Workspace Down"
msgstr "Bajar a un área de trabajo"
#: js/ui/windowMenu.js:140
#: js/ui/windowMenu.js:139
msgid "Move to Monitor Up"
msgstr "Mover a la pantalla de arriba"
#: js/ui/windowMenu.js:149
#: js/ui/windowMenu.js:148
msgid "Move to Monitor Down"
msgstr "Mover a la pantalla de abajo"
#: js/ui/windowMenu.js:158
#: js/ui/windowMenu.js:157
msgid "Move to Monitor Left"
msgstr "Mover a la pantalla de la izquierda"
#: js/ui/windowMenu.js:167
#: js/ui/windowMenu.js:166
msgid "Move to Monitor Right"
msgstr "Mover a la pantalla de la derecha"
@ -2171,12 +2180,12 @@ msgstr ""
msgid "List possible modes"
msgstr "Listar los modos posibles"
#: src/shell-app.c:270
#: src/shell-app.c:272
msgctxt "program"
msgid "Unknown"
msgstr "Desconocido"
#: src/shell-app.c:511
#: src/shell-app.c:523
#, c-format
msgid "Failed to launch “%s”"
msgstr "Falló al lanzar «%s»"

278
po/fr.po
View File

@ -14,22 +14,22 @@
# Alain Lojewski <allomervan@gmail.com>, 2014-2018.
# Erwan Georget <egeorget@opmbx.org>, 2016.
# Claude Paroz <claude@2xlibre.net>, 2010-2011, 2016.
# Charles Monzat <superboa@hotmail.fr>, 2016.
# Charles Monzat <superboa@hotmail.fr>, 2016, 2018.
#
msgid ""
msgstr ""
"Project-Id-Version: gnome-shell master fr\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gnome-shell/issues\n"
"POT-Creation-Date: 2018-03-03 10:22+0000\n"
"PO-Revision-Date: 2018-03-01 09:00+0100\n"
"Last-Translator: Alain Lojewski <allomervan@gmail.com>\n"
"POT-Creation-Date: 2018-08-01 18:08+0000\n"
"PO-Revision-Date: 2018-08-09 19:51+0200\n"
"Last-Translator: Charles Monzat <superboa@hotmail.fr>\n"
"Language-Team: français <gnomefr@traduc.org>\n"
"Language: fr\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
"X-Generator: Poedit 1.8.12\n"
"X-Generator: Gtranslator 2.91.7\n"
#: data/50-gnome-shell-system.xml:6
msgid "System"
@ -234,7 +234,7 @@ msgstr ""
#: data/org.gnome.shell.gschema.xml.in:116
msgid "Keybinding to open the overview"
msgstr "Combinaison de touches pour ouvrir la vue d'ensemble"
msgstr "Combinaison de touches pour ouvrir la vue densemble"
#: data/org.gnome.shell.gschema.xml.in:117
msgid "Keybinding to open the Activities Overview."
@ -312,34 +312,34 @@ msgstr ""
"Si vrai, seules les fenêtres de lespace de travail actuel sont affichées "
"dans le sélecteur. Sinon, toutes les fenêtres y sont incluses."
#: data/org.gnome.shell.gschema.xml.in:197
#: data/org.gnome.shell.gschema.xml.in:198
msgid "Attach modal dialog to the parent window"
msgstr "Attacher les dialogues modaux à leur fenêtre parente"
#: data/org.gnome.shell.gschema.xml.in:198
#: data/org.gnome.shell.gschema.xml.in:207
#: data/org.gnome.shell.gschema.xml.in:215
#: data/org.gnome.shell.gschema.xml.in:223
#: data/org.gnome.shell.gschema.xml.in:231
#: data/org.gnome.shell.gschema.xml.in:199
#: data/org.gnome.shell.gschema.xml.in:208
#: data/org.gnome.shell.gschema.xml.in:216
#: data/org.gnome.shell.gschema.xml.in:224
#: data/org.gnome.shell.gschema.xml.in:232
msgid ""
"This key overrides the key in org.gnome.mutter when running GNOME Shell."
msgstr ""
"Cette clé prend le pas sur la clé dans org.gnome.mutter lorsque GNOME Shell "
"est lancé."
#: data/org.gnome.shell.gschema.xml.in:206
#: data/org.gnome.shell.gschema.xml.in:207
msgid "Enable edge tiling when dropping windows on screen edges"
msgstr "Activer lempilage des fenêtres déposées sur les bords de l'écran"
msgstr "Activer lempilage des fenêtres déposées sur les bords de lécran"
#: data/org.gnome.shell.gschema.xml.in:214
#: data/org.gnome.shell.gschema.xml.in:215
msgid "Workspaces are managed dynamically"
msgstr "Les espaces de travail sont gérés dynamiquement"
#: data/org.gnome.shell.gschema.xml.in:222
#: data/org.gnome.shell.gschema.xml.in:223
msgid "Workspaces only on primary monitor"
msgstr "Les espaces de travail sont uniquement sur lécran principal"
#: data/org.gnome.shell.gschema.xml.in:230
#: data/org.gnome.shell.gschema.xml.in:231
msgid "Delay focus changes in mouse mode until the pointer stops moving"
msgstr ""
"Retarder les changements de focus en mode souris jusquà ce que le pointeur "
@ -362,7 +362,7 @@ msgstr ""
"préférences de %s :"
#: js/gdm/authPrompt.js:147 js/ui/audioDeviceSelection.js:71
#: js/ui/components/networkAgent.js:117 js/ui/components/polkitAgent.js:148
#: js/ui/components/networkAgent.js:117 js/ui/components/polkitAgent.js:153
#: js/ui/endSessionDialog.js:482 js/ui/extensionDownloader.js:197
#: js/ui/shellMountOperation.js:343 js/ui/status/network.js:919
msgid "Cancel"
@ -382,20 +382,20 @@ msgctxt "button"
msgid "Sign In"
msgstr "Se connecter"
#: js/gdm/loginDialog.js:315
#: js/gdm/loginDialog.js:319
msgid "Choose Session"
msgstr "Choisir une session"
#. translators: this message is shown below the user list on the
#. login screen. It can be activated to reveal an entry for
#. manually entering the username.
#: js/gdm/loginDialog.js:458
#: js/gdm/loginDialog.js:462
msgid "Not listed?"
msgstr "Absent de la liste ?"
#. Translators: this message is shown below the username entry field
#. to clue the user in on how to login to the local network realm
#: js/gdm/loginDialog.js:887
#: js/gdm/loginDialog.js:891
#, javascript-format
msgid "(e.g., user or %s)"
msgstr "(par ex. utilisateur ou %s)"
@ -403,12 +403,12 @@ msgstr "(par ex. utilisateur ou %s)"
#. TTLS and PEAP are actually much more complicated, but this complication
#. is not visible here since we only care about phase2 authentication
#. (and don't even care of which one)
#: js/gdm/loginDialog.js:892 js/ui/components/networkAgent.js:243
#: js/gdm/loginDialog.js:896 js/ui/components/networkAgent.js:243
#: js/ui/components/networkAgent.js:261
msgid "Username: "
msgstr "Nom dutilisateur : "
#: js/gdm/loginDialog.js:1228
#: js/gdm/loginDialog.js:1234
msgid "Login Window"
msgstr "Fenêtre de connexion"
@ -421,7 +421,7 @@ msgstr "Erreur dauthentification"
#. 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:482
#: js/gdm/util.js:485
msgid "(or swipe finger)"
msgstr "(ou faites glisser le doigt)"
@ -662,32 +662,32 @@ msgstr "Fréquemment utilisées"
msgid "All"
msgstr "Toutes"
#: js/ui/appDisplay.js:1886
#: js/ui/appDisplay.js:1890
msgid "New Window"
msgstr "Nouvelle fenêtre"
#: js/ui/appDisplay.js:1900
#: js/ui/appDisplay.js:1904
msgid "Launch using Dedicated Graphics Card"
msgstr "Démarrer en utilisant la carte graphique dédiée"
#: js/ui/appDisplay.js:1927 js/ui/dash.js:285
#: js/ui/appDisplay.js:1931 js/ui/dash.js:285
msgid "Remove from Favorites"
msgstr "Enlever des favoris"
#: js/ui/appDisplay.js:1933
#: js/ui/appDisplay.js:1937
msgid "Add to Favorites"
msgstr "Ajouter aux favoris"
#: js/ui/appDisplay.js:1943
#: js/ui/appDisplay.js:1947
msgid "Show Details"
msgstr "Afficher les détails"
#: js/ui/appFavorites.js:138
#: js/ui/appFavorites.js:140
#, javascript-format
msgid "%s has been added to your favorites."
msgstr "%s a été ajouté à vos favoris."
#: js/ui/appFavorites.js:172
#: js/ui/appFavorites.js:174
#, javascript-format
msgid "%s has been removed from your favorites."
msgstr "%s a été supprimé de vos favoris."
@ -708,7 +708,7 @@ msgstr "Casque audio"
msgid "Headset"
msgstr "Micro-casque"
#: js/ui/audioDeviceSelection.js:82 js/ui/status/volume.js:221
#: js/ui/audioDeviceSelection.js:82 js/ui/status/volume.js:255
msgid "Microphone"
msgstr "Microphone"
@ -720,7 +720,7 @@ msgstr "Modifier larrière-plan…"
msgid "Display Settings"
msgstr "Paramètres daffichage"
#: js/ui/backgroundMenu.js:22 js/ui/status/system.js:264
#: js/ui/backgroundMenu.js:22
msgid "Settings"
msgstr "Paramètres"
@ -840,35 +840,35 @@ msgctxt "event list time"
msgid "All Day"
msgstr "Journée"
#: js/ui/calendar.js:864
#: js/ui/calendar.js:866
msgctxt "calendar heading"
msgid "%A, %B %d"
msgstr "%A %d %B"
#: js/ui/calendar.js:868
#: js/ui/calendar.js:870
msgctxt "calendar heading"
msgid "%A, %B %d, %Y"
msgstr "%A %d %B, %Y"
#: js/ui/calendar.js:1086
#: js/ui/calendar.js:1100
msgid "No Notifications"
msgstr "Aucune notification"
#: js/ui/calendar.js:1089
#: js/ui/calendar.js:1103
msgid "No Events"
msgstr "Aucun évènement"
#: js/ui/calendar.js:1117
#: js/ui/calendar.js:1131
msgid "Clear All"
msgstr "Effacer tout"
#. Translators: %s is an application name
#: js/ui/closeDialog.js:44
#: js/ui/closeDialog.js:47
#, javascript-format
msgid "“%s” is not responding."
msgstr "« %s » ne répond pas."
#: js/ui/closeDialog.js:45
#: js/ui/closeDialog.js:48
msgid ""
"You may choose to wait a short while for it to continue or force the "
"application to quit entirely."
@ -876,11 +876,11 @@ msgstr ""
"Vous pouvez soit attendre un peu pour continuer, soit forcer lapplication à "
"quitter."
#: js/ui/closeDialog.js:61
#: js/ui/closeDialog.js:64
msgid "Force Quit"
msgstr "Forcer à quitter"
#: js/ui/closeDialog.js:64
#: js/ui/closeDialog.js:67
msgid "Wait"
msgstr "Attendre"
@ -897,7 +897,7 @@ msgstr "Disque externe déconnecté"
msgid "Open with %s"
msgstr "Ouvrir avec %s"
#: js/ui/components/keyring.js:107 js/ui/components/polkitAgent.js:284
#: js/ui/components/keyring.js:107 js/ui/components/polkitAgent.js:297
msgid "Password:"
msgstr "Mot de passe :"
@ -934,11 +934,11 @@ msgstr "Mot de passe de la clé privée : "
msgid "Service: "
msgstr "Service : "
#: js/ui/components/networkAgent.js:292 js/ui/components/networkAgent.js:659
#: js/ui/components/networkAgent.js:292 js/ui/components/networkAgent.js:664
msgid "Authentication required by wireless network"
msgstr "Lauthentification est requise par le réseau sans fil"
#: js/ui/components/networkAgent.js:293 js/ui/components/networkAgent.js:660
#: js/ui/components/networkAgent.js:293 js/ui/components/networkAgent.js:665
#, javascript-format
msgid ""
"Passwords or encryption keys are required to access the wireless network "
@ -947,7 +947,7 @@ msgstr ""
"Il faut un mot de passe ou une clé de chiffrement pour accéder au réseau "
"sans fil « %s »"
#: js/ui/components/networkAgent.js:297 js/ui/components/networkAgent.js:663
#: js/ui/components/networkAgent.js:297 js/ui/components/networkAgent.js:668
msgid "Wired 802.1X authentication"
msgstr "Authentification filaire 802.1X"
@ -955,15 +955,15 @@ msgstr "Authentification filaire 802.1X"
msgid "Network name: "
msgstr "Nom du réseau : "
#: js/ui/components/networkAgent.js:304 js/ui/components/networkAgent.js:667
#: js/ui/components/networkAgent.js:304 js/ui/components/networkAgent.js:672
msgid "DSL authentication"
msgstr "Authentification DSL"
#: js/ui/components/networkAgent.js:311 js/ui/components/networkAgent.js:673
#: js/ui/components/networkAgent.js:311 js/ui/components/networkAgent.js:678
msgid "PIN code required"
msgstr "Code PIN requis"
#: js/ui/components/networkAgent.js:312 js/ui/components/networkAgent.js:674
#: js/ui/components/networkAgent.js:312 js/ui/components/networkAgent.js:679
msgid "PIN code is needed for the mobile broadband device"
msgstr "Un code PIN est nécessaire pour les connexions mobiles"
@ -971,29 +971,29 @@ msgstr "Un code PIN est nécessaire pour les connexions mobiles"
msgid "PIN: "
msgstr "PIN : "
#: js/ui/components/networkAgent.js:320 js/ui/components/networkAgent.js:680
#: js/ui/components/networkAgent.js:320 js/ui/components/networkAgent.js:685
msgid "Mobile broadband network password"
msgstr "Mot de passe de la connexion mobile"
#: js/ui/components/networkAgent.js:321 js/ui/components/networkAgent.js:664
#: js/ui/components/networkAgent.js:668 js/ui/components/networkAgent.js:681
#: js/ui/components/networkAgent.js:321 js/ui/components/networkAgent.js:669
#: js/ui/components/networkAgent.js:673 js/ui/components/networkAgent.js:686
#, javascript-format
msgid "A password is required to connect to “%s”."
msgstr "Un mot de passe est requis pour se connecter à « %s »."
#: js/ui/components/networkAgent.js:648 js/ui/status/network.js:1691
#: js/ui/components/networkAgent.js:653 js/ui/status/network.js:1704
msgid "Network Manager"
msgstr "Gestionnaire de réseau"
#: js/ui/components/polkitAgent.js:43
#: js/ui/components/polkitAgent.js:48
msgid "Authentication Required"
msgstr "Authentification nécessaire"
#: js/ui/components/polkitAgent.js:71
#: js/ui/components/polkitAgent.js:76
msgid "Administrator"
msgstr "Administrateur"
#: js/ui/components/polkitAgent.js:151
#: js/ui/components/polkitAgent.js:156
msgid "Authenticate"
msgstr "Sauthentifier"
@ -1001,7 +1001,7 @@ msgstr "Sauthentifier"
#. * requested authentication was not gained; this can happen
#. * because of an authentication error (like invalid password),
#. * for instance.
#: js/ui/components/polkitAgent.js:270 js/ui/shellMountOperation.js:327
#: js/ui/components/polkitAgent.js:283 js/ui/shellMountOperation.js:327
msgid "Sorry, that didnt work. Please try again."
msgstr "Échec de lauthentification. Essayez à nouveau."
@ -1061,7 +1061,7 @@ msgstr "Ajouter des horloges locales…"
msgid "World Clocks"
msgstr "Horloges locales"
#: js/ui/dateMenu.js:225
#: js/ui/dateMenu.js:227
msgid "Weather"
msgstr "Météo"
@ -1069,7 +1069,7 @@ msgstr "Météo"
#. libgweather for the possible condition strings. If at all
#. possible, the sentence should match the grammatical case etc. of
#. the inserted conditions.
#: js/ui/dateMenu.js:289
#: js/ui/dateMenu.js:291
#, javascript-format
msgid "%s all day."
msgstr "%s toute la journée."
@ -1078,7 +1078,7 @@ msgstr "%s toute la journée."
#. libgweather for the possible condition strings. If at all
#. possible, the sentence should match the grammatical case etc. of
#. the inserted conditions.
#: js/ui/dateMenu.js:295
#: js/ui/dateMenu.js:297
#, javascript-format
msgid "%s, then %s later."
msgstr "%s, puis %s plus tard."
@ -1087,30 +1087,30 @@ msgstr "%s, puis %s plus tard."
#. libgweather for the possible condition strings. If at all
#. possible, the sentence should match the grammatical case etc. of
#. the inserted conditions.
#: js/ui/dateMenu.js:301
#: js/ui/dateMenu.js:303
#, javascript-format
msgid "%s, then %s, followed by %s later."
msgstr "%s, puis %s, suivi par %s plus tard."
#: js/ui/dateMenu.js:312
#: js/ui/dateMenu.js:314
msgid "Select a location…"
msgstr "Choisir un emplacement…"
#: js/ui/dateMenu.js:315
#: js/ui/dateMenu.js:317
msgid "Loading…"
msgstr "Chargement…"
#. Translators: %s is a temperature with unit, e.g. "23℃"
#: js/ui/dateMenu.js:321
#: js/ui/dateMenu.js:323
#, javascript-format
msgid "Feels like %s."
msgstr "Température ressentie : %s."
#: js/ui/dateMenu.js:324
#: js/ui/dateMenu.js:326
msgid "Go online for weather information"
msgstr "Chercher les informations météorologiques en ligne"
#: js/ui/dateMenu.js:326
#: js/ui/dateMenu.js:328
msgid "Weather information is currently unavailable"
msgstr "Les informations météorologiques ne sont pas disponibles actuellement"
@ -1344,13 +1344,13 @@ msgid "Leave On"
msgstr "Laisser activé"
#: js/ui/kbdA11yDialog.js:59 js/ui/status/bluetooth.js:143
#: js/ui/status/network.js:1281
#: js/ui/status/network.js:1294
msgid "Turn On"
msgstr "Activer"
#: js/ui/kbdA11yDialog.js:67 js/ui/status/bluetooth.js:143
#: js/ui/status/network.js:154 js/ui/status/network.js:337
#: js/ui/status/network.js:1281 js/ui/status/network.js:1396
#: js/ui/status/network.js:1294 js/ui/status/network.js:1409
#: js/ui/status/nightLight.js:47 js/ui/status/rfkill.js:90
#: js/ui/status/rfkill.js:117
msgid "Turn Off"
@ -1412,7 +1412,7 @@ msgstr "Afficher la source"
msgid "Web Page"
msgstr "Page Web"
#: js/ui/messageTray.js:1493
#: js/ui/messageTray.js:1495
msgid "System Information"
msgstr "Informations du système"
@ -1424,6 +1424,10 @@ msgstr "Artiste inconnu"
msgid "Unknown title"
msgstr "Titre inconnu"
#: js/ui/osdWindow.js:32 js/ui/status/volume.js:204
msgid "Volume"
msgstr "Volume"
#: js/ui/overview.js:83
msgid "Undo"
msgstr "Annuler"
@ -1466,42 +1470,42 @@ msgstr "Associer une touche"
msgid "Done"
msgstr "Terminé"
#: js/ui/padOsd.js:740
#: js/ui/padOsd.js:742
msgid "Edit…"
msgstr "Édition…"
#: js/ui/padOsd.js:782 js/ui/padOsd.js:887
#: js/ui/padOsd.js:784 js/ui/padOsd.js:889
msgid "None"
msgstr "Aucun"
#: js/ui/padOsd.js:841
#: js/ui/padOsd.js:843
msgid "Press a button to configure"
msgstr "Appuyez sur un bouton pour le configurer"
#: js/ui/padOsd.js:842
#: js/ui/padOsd.js:844
msgid "Press Esc to exit"
msgstr "Appuyez sur Échap. pour quitter"
#: js/ui/padOsd.js:845
#: js/ui/padOsd.js:847
msgid "Press any key to exit"
msgstr "Appuyez sur une touche pour quitter"
#: js/ui/panel.js:355
#: js/ui/panel.js:356
msgid "Quit"
msgstr "Quitter"
#. Translators: If there is no suitable word for "Activities"
#. in your language, you can use the word for "Overview".
#: js/ui/panel.js:411
#: js/ui/panel.js:412
msgid "Activities"
msgstr "Activités"
#: js/ui/panel.js:692
#: js/ui/panel.js:693
msgctxt "System menu in the top bar"
msgid "System"
msgstr "Système"
#: js/ui/panel.js:811
#: js/ui/panel.js:816
msgid "Top Bar"
msgstr "Barre supérieure"
@ -1510,23 +1514,23 @@ msgstr "Barre supérieure"
#. "ON" and "OFF") or "toggle-switch-intl" (for toggle
#. switches containing "◯" and "|"). Other values will
#. simply result in invisible toggle switches.
#: js/ui/popupMenu.js:291
#: js/ui/popupMenu.js:300
msgid "toggle-switch-us"
msgstr "toggle-switch-intl"
#: js/ui/runDialog.js:70
#: js/ui/runDialog.js:74
msgid "Enter a Command"
msgstr "Saisissez une commande"
#: js/ui/runDialog.js:110 js/ui/windowMenu.js:175
#: js/ui/runDialog.js:114 js/ui/windowMenu.js:174
msgid "Close"
msgstr "Fermer"
#: js/ui/runDialog.js:273
#: js/ui/runDialog.js:278
msgid "Restart is not available on Wayland"
msgstr "Le redémarrage nest pas disponible sur Wayland"
#: js/ui/runDialog.js:278
#: js/ui/runDialog.js:283
msgid "Restarting…"
msgstr "Redémarrage…"
@ -1550,7 +1554,7 @@ msgid_plural "%d new notifications"
msgstr[0] "%d nouvelle notification"
msgstr[1] "%d nouvelles notifications"
#: js/ui/screenShield.js:451 js/ui/status/system.js:283
#: js/ui/screenShield.js:451 js/ui/status/system.js:294
msgid "Lock"
msgstr "Verrouiller"
@ -1706,7 +1710,7 @@ msgstr "Paramètres de confidentialité"
#: js/ui/status/location.js:196
msgid "Location In Use"
msgstr "Localisation en cours d'utilisation"
msgstr "Localisation en cours dutilisation"
#: js/ui/status/location.js:200
msgid "Location Disabled"
@ -1733,7 +1737,7 @@ msgid "<unknown>"
msgstr "<inconnu>"
#. Translators: %s is a network identifier
#: js/ui/status/network.js:441 js/ui/status/network.js:1310
#: js/ui/status/network.js:441 js/ui/status/network.js:1323
#, javascript-format
msgid "%s Off"
msgstr "%s éteint"
@ -1759,7 +1763,7 @@ msgid "%s Disconnecting"
msgstr "Déconnexion de %s en cours"
#. Translators: %s is a network identifier
#: js/ui/status/network.js:459 js/ui/status/network.js:1302
#: js/ui/status/network.js:459 js/ui/status/network.js:1315
#, javascript-format
msgid "%s Connecting"
msgstr "Connexion de %s en cours"
@ -1799,7 +1803,7 @@ msgid "Mobile Broadband Settings"
msgstr "Paramètres connexion mobile"
#. Translators: %s is a network identifier
#: js/ui/status/network.js:578 js/ui/status/network.js:1307
#: js/ui/status/network.js:578 js/ui/status/network.js:1320
#, javascript-format
msgid "%s Hardware Disabled"
msgstr "Équipement %s désactivé"
@ -1855,81 +1859,81 @@ msgstr "Aucun réseau disponible"
msgid "Use hardware switch to turn off"
msgstr "Utiliser linterrupteur matériel pour éteindre"
#: js/ui/status/network.js:1173
#: js/ui/status/network.js:1186
msgid "Select Network"
msgstr "Sélectionner un réseau"
#: js/ui/status/network.js:1179
#: js/ui/status/network.js:1192
msgid "Wi-Fi Settings"
msgstr "Paramètres Wi-Fi"
#. Translators: %s is a network identifier
#: js/ui/status/network.js:1298
#: js/ui/status/network.js:1311
#, javascript-format
msgid "%s Hotspot Active"
msgstr "Point daccès %s actif"
#. Translators: %s is a network identifier
#: js/ui/status/network.js:1313
#: js/ui/status/network.js:1326
#, javascript-format
msgid "%s Not Connected"
msgstr "%s non connecté"
#: js/ui/status/network.js:1413
#: js/ui/status/network.js:1426
msgid "connecting…"
msgstr "connexion…"
#. Translators: this is for network connections that require some kind of key or password
#: js/ui/status/network.js:1416
#: js/ui/status/network.js:1429
msgid "authentication required"
msgstr "authentification nécessaire"
#: js/ui/status/network.js:1418
#: js/ui/status/network.js:1431
msgid "connection failed"
msgstr "échec de connexion"
#: js/ui/status/network.js:1472
#: js/ui/status/network.js:1485
msgid "VPN Settings"
msgstr "Paramètres VPN"
#: js/ui/status/network.js:1485
#: js/ui/status/network.js:1498
msgid "VPN"
msgstr "VPN"
#: js/ui/status/network.js:1495
#: js/ui/status/network.js:1508
msgid "VPN Off"
msgstr "VPN désactivé"
#: js/ui/status/network.js:1559 js/ui/status/rfkill.js:93
#: js/ui/status/network.js:1572 js/ui/status/rfkill.js:93
msgid "Network Settings"
msgstr "Paramètres du réseau"
#: js/ui/status/network.js:1588
#: js/ui/status/network.js:1601
#, javascript-format
msgid "%s Wired Connection"
msgid_plural "%s Wired Connections"
msgstr[0] "%s connexion filaire."
msgstr[1] "%s connexions filaires."
#: js/ui/status/network.js:1592
#: js/ui/status/network.js:1605
#, javascript-format
msgid "%s Wi-Fi Connection"
msgid_plural "%s Wi-Fi Connections"
msgstr[0] "%s connexion Wi-Fi."
msgstr[1] "%s connexions Wi-Fi."
#: js/ui/status/network.js:1596
#: js/ui/status/network.js:1609
#, javascript-format
msgid "%s Modem Connection"
msgid_plural "%s Modem Connections"
msgstr[0] "%s connexion à un modem."
msgstr[1] "%s connexions à des modem."
#: js/ui/status/network.js:1728
#: js/ui/status/network.js:1741
msgid "Connection failed"
msgstr "Échec de connexion"
#: js/ui/status/network.js:1729
#: js/ui/status/network.js:1742
msgid "Activation of network connection failed"
msgstr "Lactivation de la connexion réseau a échoué"
@ -1947,11 +1951,11 @@ msgstr "Reprendre"
#: js/ui/status/nightLight.js:71
msgid "Disable Until Tomorrow"
msgstr "Désactiver jusqu'à demain"
msgstr "Désactiver jusquà demain"
#: js/ui/status/power.js:61
msgid "Power Settings"
msgstr "Paramètres de gestion de l'énergie"
msgstr "Paramètres de gestion de lénergie"
#: js/ui/status/power.js:77
msgid "Fully Charged"
@ -1980,6 +1984,14 @@ msgstr "%d%02d avant chargement complet (%d %%)"
msgid "%d%%"
msgstr "%d%%"
#: js/ui/status/remoteAccess.js:46
msgid "Screen is Being Shared"
msgstr "Lécran est partagé"
#: js/ui/status/remoteAccess.js:48
msgid "Turn off"
msgstr "Éteindre"
#. The menu only appears when airplane mode is on, so just
#. statically build it as if it was on, rather than dynamically
#. changing the menu contents.
@ -1999,28 +2011,28 @@ msgstr "Fermer la session"
msgid "Account Settings"
msgstr "Paramètres du compte"
#: js/ui/status/system.js:268
#: js/ui/status/system.js:279
msgid "Orientation Lock"
msgstr "Verrouillage de lorientation "
#: js/ui/status/system.js:294
#: js/ui/status/system.js:305
msgid "Suspend"
msgstr "Mettre en veille"
#: js/ui/status/system.js:304
#: js/ui/status/system.js:315
msgid "Power Off"
msgstr "Éteindre"
#: js/ui/status/thunderbolt.js:272
#: js/ui/status/thunderbolt.js:298
msgid "Thunderbolt"
msgstr "Interface Thunderbolt"
#. we are done
#: js/ui/status/thunderbolt.js:328
#: js/ui/status/thunderbolt.js:354
msgid "Unknown Thunderbolt device"
msgstr "Périphérique Thunderbolt inconnu"
#: js/ui/status/thunderbolt.js:329
#: js/ui/status/thunderbolt.js:355
msgid ""
"New device has been detected while you were away. Please disconnect and "
"reconnect the device to start using it."
@ -2028,23 +2040,19 @@ msgstr ""
"Un nouveau périphérique a été détecté pendant votre absence. Veuillez le "
"débrancher et rebrancher avant de commencer à lutiliser"
#: js/ui/status/thunderbolt.js:334
#: js/ui/status/thunderbolt.js:360
msgid "Thunderbolt authorization error"
msgstr "Erreur dautorisation Thunderbolt"
#: js/ui/status/thunderbolt.js:335
#: js/ui/status/thunderbolt.js:361
#, javascript-format
msgid "Could not authorize the thunderbolt device: %s"
msgid "Could not authorize the Thunderbolt device: %s"
msgstr "Impossible dautoriser le périphérique Thunderbolt : %s"
#: js/ui/status/volume.js:128
#: js/ui/status/volume.js:135
msgid "Volume changed"
msgstr "Volume modifié"
#: js/ui/status/volume.js:170
msgid "Volume"
msgstr "Volume"
#. Translators: this is for display mirroring i.e. cloning.
#. * Try to keep it under around 15 characters.
#.
@ -2094,22 +2102,22 @@ msgstr "Recherche"
msgid "“%s” is ready"
msgstr "« %s » est prêt"
#: js/ui/windowManager.js:72
#: js/ui/windowManager.js:74
msgid "Do you want to keep these display settings?"
msgstr "Voulez-vous conserver ces paramètres daffichage ?"
#. Translators: this and the following message should be limited in lenght,
#. to avoid ellipsizing the labels.
#.
#: js/ui/windowManager.js:84
#: js/ui/windowManager.js:86
msgid "Revert Settings"
msgstr "Restaurer les paramètres"
#: js/ui/windowManager.js:87
#: js/ui/windowManager.js:89
msgid "Keep Changes"
msgstr "Conserver les modifications"
#: js/ui/windowManager.js:105
#: js/ui/windowManager.js:107
#, javascript-format
msgid "Settings changes will revert in %d second"
msgid_plural "Settings changes will revert in %d seconds"
@ -2118,7 +2126,7 @@ msgstr[1] "Les paramètres seront restaurés dans %d secondes"
#. Translators: This represents the size of a window. The first number is
#. * the width of the window and the second is the height.
#: js/ui/windowManager.js:660
#: js/ui/windowManager.js:689
#, javascript-format
msgid "%d × %d"
msgstr "%d × %d"
@ -2171,19 +2179,19 @@ msgstr "Déplacer vers lespace de travail supérieur"
msgid "Move to Workspace Down"
msgstr "Déplacer vers lespace de travail inférieur"
#: js/ui/windowMenu.js:140
#: js/ui/windowMenu.js:139
msgid "Move to Monitor Up"
msgstr "Déplacer vers lécran du haut"
#: js/ui/windowMenu.js:149
#: js/ui/windowMenu.js:148
msgid "Move to Monitor Down"
msgstr "Déplacer vers lécran du bas"
#: js/ui/windowMenu.js:158
#: js/ui/windowMenu.js:157
msgid "Move to Monitor Left"
msgstr "Déplacer vers lécran de gauche"
#: js/ui/windowMenu.js:167
#: js/ui/windowMenu.js:166
msgid "Move to Monitor Right"
msgstr "Déplacer vers lécran de droite"
@ -2196,29 +2204,29 @@ msgstr "Agenda dEvolution"
msgid "evolution"
msgstr "evolution"
#: src/main.c:432
#: src/main.c:410
msgid "Print version"
msgstr "Affiche la version"
#: src/main.c:438
#: src/main.c:416
msgid "Mode used by GDM for login screen"
msgstr "Mode utilisé par GDM pour lécran de connexion"
#: src/main.c:444
#: src/main.c:422
msgid "Use a specific mode, e.g. “gdm” for login screen"
msgstr ""
"Utiliser un mode particulier, par ex. « gdm » pour lécran de connexion"
#: src/main.c:450
#: src/main.c:428
msgid "List possible modes"
msgstr "Lister les modes possibles"
#: src/shell-app.c:270
#: src/shell-app.c:272
msgctxt "program"
msgid "Unknown"
msgstr "Inconnu"
#: src/shell-app.c:511
#: src/shell-app.c:523
#, c-format
msgid "Failed to launch “%s”"
msgstr "Impossible de lancer « %s »"

460
po/fur.po

File diff suppressed because it is too large Load Diff

757
po/gd.po

File diff suppressed because it is too large Load Diff

418
po/gl.po

File diff suppressed because it is too large Load Diff

368
po/id.po

File diff suppressed because it is too large Load Diff

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