Compare commits

..

201 Commits

Author SHA1 Message Date
11bf65e2b4 status/keyboard: Disregard the backwards flag for the popup switcher
This seems to cause more harm than good. It puzzles users looking at
the shortcuts list in g-c-c and it prevents otherwise valid shortcuts
like Shift+Hangul from working.

https://bugzilla.gnome.org/show_bug.cgi?id=695823
2013-04-05 18:12:48 +02:00
a8b7e559aa status/keyboard: Allow switching input source in the message tray
We still can't show a popup switcher in the message tray but we can at
least degrade gracefully and advance to the next input source.

https://bugzilla.gnome.org/show_bug.cgi?id=697009
2013-04-05 18:12:48 +02:00
b733e30a4a status/keyboard: Switch input source on special modifiers accelerator
This simply mimics the X server's layout switching behavior by
advancing to the next input source and wrapping around.

https://bugzilla.gnome.org/show_bug.cgi?id=697008
2013-04-05 18:12:48 +02:00
b607958134 status/keyboard: Synchronize input source switching with key events
Currently we simply set the gsettings key when activating an input
source. This obviously introduces a time window, between the event that
activates the switch and when the switch is complete, under which key
events are being delivered to applications and interpreted according
to the previous input source.

The patches in bug 696996 introduce a DBus API in g-s-d that allows us
to know when an input source if effectively active. Using that and
freezing keyboard events in the X server until we hear back from g-s-d
we can ensure that events won't be misinterpreted after an input
source switch.

https://bugzilla.gnome.org/show_bug.cgi?id=697007
2013-04-05 18:12:47 +02:00
14189e6827 shellEntry: Destroy entry menus when the entry actors are destroyed
This ensures that a menu and manager aren't sticking around.

https://bugzilla.gnome.org/show_bug.cgi?id=697295
2013-04-04 15:04:14 -04:00
3dd6113a0a modalDialog: Destroy dialogs on close
It turns out that we never destroyed modal dialogs when closing
them, causing them to still linger in the scene graph even when
there were no references to them in the JS. The one case where
we don't want to destroy modal dialogs after being closed is
endSessionDialog, so provide a parameter that allows classes
to override this behavior.

https://bugzilla.gnome.org/show_bug.cgi?id=697295
2013-04-04 15:04:14 -04:00
ae5cdea5af Updated Norwegian bokmål translation 2013-04-03 13:31:44 +02:00
3c1f389e25 backgroundMenu: destroy menu when actor is destroyed
This fixes a leak.

https://bugzilla.gnome.org/show_bug.cgi?id=697119
2013-04-02 23:20:15 -04:00
284d821233 Updated Basque language 2013-04-02 21:59:27 +02:00
78272e5592 RemoteSearch: don't sort the last explicitly sorted provider last
It's a confusing semantic, and keeping it causes bugs in the control
center panels.

https://bugzilla.gnome.org/show_bug.cgi?id=694974
2013-04-02 21:49:57 +02:00
098bc41083 Updated Polish translation 2013-04-02 15:58:59 +02:00
c837090282 Update Simplified Chinese translation 2013-04-02 00:55:01 +08:00
cdc1678e6f Updated Belarusian translation. 2013-04-01 15:22:56 +03:00
2a3d76b0cc Update Arabic translation 2013-03-31 23:08:29 +02:00
29e89491de Updated British English translation 2013-03-29 16:07:45 +00:00
d63947aec4 Silly typo in calendar.js
https://bugzilla.gnome.org/show_bug.cgi?id=696436
2013-03-29 16:15:19 +01:00
512f0a67fb shellDBus: Fix SetActive(false) for ScreenSaver DBus API
Someone changed .unlock() to deactivate() for the obvious symmetry
with activate(), but forgot to update it here.

https://bugzilla.gnome.org/show_bug.cgi?id=696585
2013-03-29 10:13:24 -04:00
a7cd4657f5 loginManager.js: Check for logind, not for systemd
It is possible to build systemd without logind, in which case
/sys/fs/cgroup/systemd would still exist. Check for /run/systemd/seats instead,
as recommended by systemd upstream.

For details, see:
<https://mail.gnome.org/archives/desktop-devel-list/2013-March/msg00092.html>

https://bugzilla.gnome.org/show_bug.cgi?id=696252
2013-03-29 11:00:52 +01:00
bf02cde598 altTab: Move input focus to target window before dropping the grab
We chain up on _finish() to drop the grab and destroy the switcher
popup but we should activate the target window first because dropping
the grab results in the previously focused windows getting a focus in
event immediately followed by the focus out event from the target
window activation which we can easily avoid.

https://bugzilla.gnome.org/show_bug.cgi?id=696259
2013-03-28 16:17:07 +01:00
b7dbb35546 Updated Aragonese translation 2013-03-28 11:11:10 +01:00
6fd5f0e3de popupMenu: Fix another child popup regression
When switching menus, we need to make sure we close all existing
grabs, not just the first one.

https://bugzilla.gnome.org/show_bug.cgi?id=695859
2013-03-27 16:32:42 -04:00
e6469df065 popupMenu: Fix a missed rename
this._activeMenu was changed to this.activeMenu, but this wasn't
updated by accident.

https://bugzilla.gnome.org/show_bug.cgi?id=695859
2013-03-27 16:32:42 -04:00
d61fe357f6 layout: Clip the window group when doing the startup animation
This ensures that when we have windows that are already visible,
like desktop icons, they don't fly across the screen from what
seems to be hyperspace to get into view.

https://bugzilla.gnome.org/show_bug.cgi?id=696323
2013-03-27 16:30:00 -04:00
965dd2ab67 Bump version to 3.8.0.1
Update NEWS.
2013-03-27 12:28:56 -04:00
78e011d558 background: fix multimonitor background placement in overview
This is like the previous commit but for monitor index, instead
of effects.

https://bugzilla.gnome.org/show_bug.cgi?id=696712
2013-03-27 12:13:47 -04:00
76590d6c69 background: fix vignette in overview
We no longer apply background effects when loading backgrounds.

This commit fixes that.

https://bugzilla.gnome.org/show_bug.cgi?id=696712
2013-03-27 12:09:02 -04:00
16dc6ce41a Bump version to 3.8.0
Update NEWS.
2013-03-26 22:29:57 +01:00
1dadcee5c9 background: don't choke on huge slide show durations
if a slideshow file has a really large duration we'll currently
throw an exception.

This bug is aggravated by the fact that some versions of
gnome-desktop use UINT_MAX as a sentinel value to mean,
"don't ever update slide".

This commit treats durations that would overflow as infinitely
long.

https://bugzilla.gnome.org/show_bug.cgi?id=696157
2013-03-26 17:02:05 -04:00
bed3bb45f7 background: don't load the same image more than once concurrently
If a background gets requested from the cache while it's still
being loaded from an earlier call, then there will be two concurrent
loads of the same file.

That concurrency is mitigates the effectiveness of the cache and
also causes leaks.

This commit consolidates file loads so that concurrency doesn't
happen.

https://bugzilla.gnome.org/show_bug.cgi?id=696157
2013-03-26 17:02:05 -04:00
18d850d7d6 workspaceThumbnail: always destroy bgManager when destroyed
Right now we only destroy the bgManager object when the
workspaceThumbnail is explicitly destroy with its destroy()
method.

This commit makes sure bgManager gets destroyed when the
workspaceThumbnail actor is destroyed without calling
destroy().

https://bugzilla.gnome.org/show_bug.cgi?id=696157
2013-03-26 17:02:05 -04:00
f920fd8b6f background: properly disconnect background signals
BackgroundManager connects to the changed signal in
the backgrounds it manages.

The signal ids for the changed signal connectionss are stored
as state on the background manager object.

If the background being managed changes while the manager
is still loading the old background, then the signal id
variable can get out of sync with the background object being
managed.

This commit ties the signal id to the background objects themselves,
so there is no opportunity for them to desynchronize.

https://bugzilla.gnome.org/show_bug.cgi?id=696157
2013-03-26 17:02:05 -04:00
b9da6d9ef6 background: When updating actor content, evict old content from cache
Normally backgrounds get evicted from the cache when their actor is
destroyed.  If the actor changes content without destroying itself,
though, we should evict the old content from the cache, too.

https://bugzilla.gnome.org/show_bug.cgi?id=696157
2013-03-26 17:02:04 -04:00
3be489c69e background: always add content to cache
We currently only add the first instance of a background
to the cache.  This means if the actor associated with that
background is destroyed, the content will be evicted and
it will need to get reloaded, even if it's already loaded
on another actor.

This commit ensures every content gets added to the cache.

https://bugzilla.gnome.org/show_bug.cgi?id=696157
2013-03-26 17:02:04 -04:00
cab092aad7 Updated Telugu Translation 2013-03-26 18:53:24 +05:30
0451cba343 Updated LT translation 2013-03-26 12:40:32 +01:00
12334cd9ad Updated Odia Language along with FUEL implementation 2013-03-26 16:09:27 +05:30
9d18a2dff4 screenShield: Go back to a shorter animation when locking manually
Increasing it was mostly to paper over animation jerkiness which
shouldn't be a problem anymore since we removed the desaturate and
blur effects.

https://bugzilla.gnome.org/show_bug.cgi?id=696380
2013-03-26 09:27:24 +01:00
869e1dc241 loginManager: listen to the correct object path
Use GetSession() to get the valid object path for the current
XDG_SESSION_ID.

https://bugzilla.gnome.org/show_bug.cgi?id=696287
2013-03-25 20:53:13 -04:00
b878f3fc4a Restore visibility of windows in initial-setup mode
gnome-initial-setup runs a regular X window, so we need to show it.

https://bugzilla.gnome.org/show_bug.cgi?id=696235
2013-03-25 18:22:48 -04:00
2aeabcc38b Updated Telugu Translations 2013-03-25 21:53:19 +05:30
94778c0dac layout: Fix opening the overview for xdnd
In the (no barriers) fallback case handleDragOver has somehow
ended up being turned into a nop and thus breaking xdnd
overview opening.

Fix that by calling _toggleOverview() when a xdnd source triggers
it.

https://bugzilla.gnome.org/show_bug.cgi?id=696447
2013-03-25 14:43:22 +01:00
390491b37a dateMenu: Re-add special-casing of evolution-calendar
When commit 724a2bd7 changed the way to determine the default
calendar app, it dropped all special handling of evolution.
Unfortunately we still need it to not end up with the default
mail component, so add it back.

https://bugzilla.gnome.org/show_bug.cgi?id=696432
2013-03-25 10:43:30 +01:00
f8ea825577 grabHelper: Consider events that release the grab handled
Currently, if a button-press event results in releasing the last modal
grab (e.g. clicks outside the grabbed actors), we don't consider the
event handled and allow its emission to continue. If we consider
dismissing a grab as an action of its own, any additional action
triggered by the same event becomes an unexpected side effect.
Tweak the capture handler accordingly.

https://bugzilla.gnome.org/show_bug.cgi?id=696422
2013-03-25 10:43:29 +01:00
f77ad7d184 Completed for Malayalam 2013-03-25 14:58:55 +05:30
e467a53def Uploaded Ukranian 2013-03-25 08:00:49 +02:00
9cd2e12915 l10n: Update Japanese translation 2013-03-25 12:10:39 +09:00
627a6587b4 Update Danish translation 2013-03-24 14:57:24 +01:00
9b3b419f7a initial-setup: Add battery icon
There is no reason why there shouldn't be a battery icon in initial-setup,
knowing how much battery you have left is useful in during setup as well.

This also fixes an exception in the lock screen caused by the combined icon
not finding the battery one.

https://bugzilla.gnome.org/show_bug.cgi?id=696212
2013-03-24 09:39:34 +01:00
f37ed44837 Updated Dutch translation 2013-03-23 23:35:30 +01:00
dddc333407 Updated Belarusian translation. 2013-03-23 23:04:07 +03:00
75714fb784 Added slovak translation 2013-03-23 21:01:35 +01:00
5a6342a5fe Updated kn translations 2013-03-23 19:00:18 +05:30
e07379b406 Revert "Remove non-existing file to make intltool happy"
This reverts commit 54bfe34273.

see 8f1df14ae7
-> It very much exists. Do a 'git submodule init && git submodule update'.
2013-03-23 13:35:47 +01:00
54bfe34273 Remove non-existing file to make intltool happy 2013-03-23 12:49:36 +01:00
bef876e4b4 Updated kn translations 2013-03-23 14:44:25 +05:30
6ef9ab6a0b st-scroll-view-fade: Don't fade out gradient
The changes from commit b4f5f1e461 and b394d184cc increased the
instructions required for the fade fragment shader. This is over the limit
for some hardware (like intel gen3), which causes the driver to fallback
to software rendering for the shader. The result is that painting a scrollview
that has a fade effect takes around 30 (!!) seconds.

So lets go back to the old effect for 3.8 until we find a solution.

https://bugzilla.gnome.org/show_bug.cgi?id=696404
2013-03-22 19:56:13 +01:00
53ffdd8d68 Updated Russian translation 2013-03-22 21:03:27 +04:00
ba198034cb screenShield: Remove blur and desaturation from lock screen
There's large performance issues with both the blur and desaturation
that make the screen shield hard to use on slower computers, and this
has always been a temporary stopgap until the user can pick a different
image for the lock screen.

https://bugzilla.gnome.org/show_bug.cgi?id=696322
2013-03-22 12:36:43 -04:00
58e66b9e1b autorunManager: Mark the Removable Devices source as resident
This ensures that it can't be removed when we clear the message
tray.

https://bugzilla.gnome.org/show_bug.cgi?id=696199
2013-03-22 12:36:43 -04:00
ac7efcb43a hindi translation 2013-03-22 18:00:09 +05:30
b514b9ec7c Tamil Translations Updated 2013-03-22 17:23:06 +05:30
f69942eb35 Updated Odia Translation. 2013-03-21 18:18:27 +05:30
f28827f625 Updated Marathi Translations 2013-03-21 09:27:22 +05:30
f20a6b3635 Updated Hungarian translation 2013-03-20 16:40:57 +01:00
7f7ff3ce3e L10N: Updated Persian Translation 2013-03-20 09:22:41 +03:30
0abb0756ba [l10n] Added Tadjik translation 2013-03-19 20:43:49 +01:00
070ed9396c Update French translation 2013-03-19 11:43:32 +01:00
307004a455 Bump version to 3.7.92
Update NEWS.
2013-03-19 00:12:27 +01:00
d097327bd8 loginDialog,unlockDialog: Give user time to read messages
Right now, if multiple messages come in, they just sort of
clobber each other.

This commit sets up a message queue, and introduces pauses
long enough for the user to hopefully be able to read those
messages.

https://bugzilla.gnome.org/show_bug.cgi?id=694688
2013-03-18 19:01:30 -04:00
f72f501931 unlockDialog: ignore resets after success
GDM sends a reset signal after verification succeeds
so that a user-switched login screen can prepare for
the next time it's going to be used.

The unlock screen treats resets as failures, though.
This means, on success, we're emitting "failed" and
clearing any last second messages.

This commit changes the unlock code to ignore resets from
GDM after successful verification.

https://bugzilla.gnome.org/show_bug.cgi?id=694688
2013-03-18 19:01:30 -04:00
e9584cfcab gdm: don't clear user-verifier on reset automatically
Right, the common code between the login screen and
the unlock screen handles clearing the user verifier
when GDM sends a reset.

We don't actually always want to clear the messages on
reset in the unlock case, though, so doing it implicitly
is problematic.

This commit moves the clear() call from the common code
to the specific reset handlers.

https://bugzilla.gnome.org/show_bug.cgi?id=694688
2013-03-18 19:01:30 -04:00
aec0e75d73 grabHelper: Ensure we reset ignoreRelease when we drop our event handler
Since we drop our event handler, we won't see ever the release event
from the button press, so unset the flag so it doesn't muck with the
next time somebody takes a grab.

https://bugzilla.gnome.org/show_bug.cgi?id=696102
2013-03-18 16:49:12 -04:00
a6b4d49454 Use Mutter fullscreen window tracking for hiding chrome and auto-minimize
Getting fullscreen window tracking right in GNOME Shell turned out to
be very hard, because it depended on details both how Mutter handled
fullscreen windows and the exact timing of that. Fullscreen tracking
and auto-minimization of fullscreen windows that lose their fullscreen
status has thus been implemented in Mutter: use that.

https://bugzilla.gnome.org/show_bug.cgi?id=649748
2013-03-18 14:44:10 -04:00
1cc726593e runDialog: Ignore expected IO errors while enumerating $PATH
$PATH might contain non-existent or non-directory entries. Ignore
those error cases.

https://bugzilla.gnome.org/show_bug.cgi?id=696064
2013-03-18 18:00:12 +01:00
5001bd8810 Don't use ClutterX11TexturePixmap directly to embed docked windows
Previously when a client requests that a window should be docked the
shell would reparent the socket window onto the stage's window and
then use ClutterX11TexturePixmap to get a texture to represent the
window. This will not work if Clutter is no longer using the X11
winsys for example if it becomes its own display server. Instead this
patch leaves the socket window as a child of the root window and lets
mutter create a MetaWindow out of it. If Mutter is acting as a display
server then this mechanism will still work via the headless x server.

The ShellGtkEmbed instance now registers for notification of the
‘window-created’ signal of the display so that it can find the
MetaWindow that gets created to represent the socket window. When this
window is found it is prevented from being displayed on the screen by
setting the actor's opacity to 0. An input shape is then set on the
window to prevent it receiving any input.

Instead of being a subclass of ClutterX11TexturePixmap, ShellGtkEmbed
is now a subclass of ClutterClone. When the MetaWindow is found for
the socket window the clone's source is set to the invisible actor for
the window so it can be displayed in the panel as before.

The ShellEmbeddedWindow no longer needs to know what the stage is
because it no longer reparents the socket window. Therefore the
ShellTrayManager doesn't need to know the stage either so
shell_tray_manager_manage_stage has been replaced with just
shell_tray_manager_manage_screen.

https://bugzilla.gnome.org/show_bug.cgi?id=693438
2013-03-18 16:49:47 +00:00
46aa70aa09 searchDisplay: Add an accessible name to the provider icon
https://bugzilla.gnome.org/show_bug.cgi?id=696007
2013-03-18 12:12:40 -04:00
41cf447c45 searchDisplay: Label search result actors for accessibility
https://bugzilla.gnome.org/show_bug.cgi?id=696007
2013-03-18 12:12:40 -04:00
b328fd7aed layout: Move window_group visibility to the layout
This ensures that windows are hidden in the screen shield and in gdm.

https://bugzilla.gnome.org/show_bug.cgi?id=695747
2013-03-18 03:57:36 -04:00
917a24580b Updated gujarati file 2013-03-18 12:33:14 +05:30
af36182879 [l10n] Updated Catalan (Valencian) translation 2013-03-17 19:52:19 +01:00
160c721afc Revert "WorkspacesView: set the clip when setting the geometry"
This reverts commit d3ab367fcd.
Pushed by mistake.
2013-03-17 19:39:58 +01:00
ee0040ef1c WorkspaceThumbnails: animate the right workspace when creating by DND
To create a new workspace by dropping on the placeholder, we move all
the windows down one workspace and then wait for _checkWorkspaces() to
automatically create the empty one at the end.
This means that, from the implementation POV, the new workspace is not
the one created by DND but it's the last one, and this detail was exposed
in the UI because the animation was applied on that one.
Fix that by starting the animation manually from the DND code, and then
blocking the animation from happening when the new workspace is created
with a flag.

https://bugzilla.gnome.org/show_bug.cgi?id=685285
2013-03-17 19:35:15 +01:00
9e60a55dd7 WorkspacesView: don't fail when doing window DND from the last workspace
DND of windows has a lot of side effects, including the possibility of
current workspace disappering from under our feet. We need to account
for that when trying to activate it.

https://bugzilla.gnome.org/show_bug.cgi?id=685285
2013-03-17 19:35:14 +01:00
57f27572ae DND: don't cancel a drag if the actor is destroyed inside acceptDrop
This happens in the case of Workspace/WorkspaceThumbnail: they call
meta_window_change_workspace_by_index(), which fires window-removed
on the old workspace, thus destroying the window clone.

https://bugzilla.gnome.org/show_bug.cgi?id=685285
2013-03-17 19:26:13 +01:00
ceae032112 Workspace/WorkspaceThumbnail: fix Clutter warnings from stacking code
Windows can be restacked at any time, including when the stackAbove
property of the window clone is being dragged, and thus parented to
the uiGroup. To do stacking properly, we need to skip it for the duration
of the drag, and sync it again at the end (which is already done by
mutter because of the workspace change)

https://bugzilla.gnome.org/show_bug.cgi?id=685285
2013-03-17 19:26:13 +01:00
d3ab367fcd WorkspacesView: set the clip when setting the geometry
Fixes clipping the windows when you open the overview with the workspace
switcher expanded and then shrink it.

https://bugzilla.gnome.org/show_bug.cgi?id=694092
2013-03-17 19:26:12 +01:00
0ceefb48c8 Workspace: don't place new windows at random locations
Instead, have them grow from the center of their assigned slots.

https://bugzilla.gnome.org/show_bug.cgi?id=695582
2013-03-17 19:26:09 +01:00
a9815ae1e9 ScreenShield: don't animate arrows if the user is idle
If the user is idle, it is very likely the monitor is off too, so let's
save some power by avoiding animations noone is going to see.

https://bugzilla.gnome.org/show_bug.cgi?id=690857
2013-03-17 19:20:43 +01:00
79140fd132 Updated Belarusian translation. 2013-03-17 16:00:14 +03:00
6c0f48ce25 layout: Only emit fullscreen-changed if things actually changed
This prevents the message tray from doing a lot of work that
it doesn't need to.
2013-03-16 16:50:30 -04:00
da7ab7057d Updated Korean translation 2013-03-16 23:59:08 +09:00
499ae609dd appDisplay: Use a custom LayoutManager for the AllView stack
ClutterBinLayout uses the maximum width/height of all children in
size requests and positions children according to the expand/align
properties. This means that the vertical position of folder popups
is not considered in size requests, so if the main view is smaller
than a folder popup's height and offset, the popup will be truncated
and/or mispositioned. Fix those cases by using a custom LayoutManager
that behaves like ClutterFixedLayout for height requests and like
ClutterBinLayout otherwise.

https://bugzilla.gnome.org/show_bug.cgi?id=694371
2013-03-15 22:41:54 +01:00
e78b3644e4 login-dialog: Increase top/bottom padding
The login dialog has a maximum height set to prevent the user list
from growing indefinitively. However this approach fails if the
monitor height is smaller as said maximum, so add some additional
top/bottom padding to make sure there's some whitespace above/below
the user list in that case as well.

https://bugzilla.gnome.org/show_bug.cgi?id=685851
2013-03-15 19:35:18 +01:00
ce6b39bd1c Revert "doap: add myself to doap file"
I just added myself temporarily to work around
mango.

This reverts commit ec8dfb0cad.
2013-03-15 14:02:31 -04:00
603f528b47 theme: Adjust border-radius for focus indication to match hover
Commit 7b3a689aad changed the border-radius of the hover effect
to match the prelight effect, but not the focus indication, so
the focused item now changes corners on hover. Fix this by using
a consistent border-radius.

https://bugzilla.gnome.org/show_bug.cgi?id=691578
2013-03-15 00:04:03 +01:00
5fecd07045 background: Look at the duration per-step
We need to look at the duration of the current step of the slideshow
to determine when to next queue an event, rather than the full slideshow
duration.

https://bugzilla.gnome.org/show_bug.cgi?id=695882
2013-03-14 17:48:07 -04:00
8edd7ad32e background: Fix a bug with empty animations
Arrays always evaluate to true, even empty arrays,
so we need to check the length to make sure we have
no files.

https://bugzilla.gnome.org/show_bug.cgi?id=695882
2013-03-14 17:48:07 -04:00
3a27d0b849 background: Keep the state of key frame files on Animation
This gets us from a mix of pure getters and class state
to just class state.

https://bugzilla.gnome.org/show_bug.cgi?id=695882
2013-03-14 17:48:07 -04:00
b351536dee background: Rename animationUpdate to updateAnimation
This is more consistent.

https://bugzilla.gnome.org/show_bug.cgi?id=695882
2013-03-14 17:48:07 -04:00
eeea8559b6 background: Fix math to calculate the interval from the duration
The math here before was incorrect. This is still wrong, as we're
looking at the total duration of the animation rather than the next
step.

https://bugzilla.gnome.org/show_bug.cgi?id=695882
2013-03-14 17:48:07 -04:00
17591117c1 background: Fix updating existing images that need loading
Due to weird and strange JS scoping semantics, if we are in a
callback, "i" won't be captured and when the callback is called,
we'll have the wrong index, causing addImage to be called instead
of updateImage.

https://bugzilla.gnome.org/show_bug.cgi?id=695882
2013-03-14 17:48:07 -04:00
c4470fd1e6 background: Set the correct index on images
The pattern is underneath, so we need to add one. It turns out
that ClutterGroup doesn't care about that, but we need to do this
to remove deprecations in mutter.

https://bugzilla.gnome.org/show_bug.cgi?id=695882
2013-03-14 17:48:07 -04:00
45fc7ec01f st-scroll-view-fade: Don't use return in the shader
Returing from main() makes llvmpipe unhappy (produces black output color),
so rework the logic to avoid the return.

https://bugzilla.gnome.org/show_bug.cgi?id=695607
2013-03-14 22:43:14 +01:00
dc54472ca5 messageTray: Remove some dead positioning code
We don't modify the tray box's anchor position, so this shouldn't
ever get called.

https://bugzilla.gnome.org/show_bug.cgi?id=695800
2013-03-14 17:18:20 -04:00
4b3bf05aaf screenShield: Only release logind inhibitor on suspend
To make sure that the screen shield is shown before suspending, we
take a logind inhibitor and release it when the screen shield is
shown. As the screen shield is not only shown on suspend, we can end
up releasing the inhibitor independently from suspending (lock, idle),
in which case the screen might not be locked when we do suspend.
To fix, only release the inhibitor after showing the screen shield
when we are about to suspend.

https://bugzilla.gnome.org/show_bug.cgi?id=693708
2013-03-14 19:09:15 +01:00
ec014a7ecf main: Do not export DBus interfaces before initializing the UI
Since commit 7cdb75e7ce, initializing UI is deferred until the session
mode has been loaded. However DBus is still initialized immediately,
which means that for DBus methods that access properties in Main, there
is now a window between the method being exposed on the bus and the
method being ready to be called. At least g-s-d grabbing global keybindings
is likely to fall in this window on session startup, and almost guaranteed
when regrabbing bindings after a shell restart.
To fix, defer initializing DBus as well.

https://bugzilla.gnome.org/show_bug.cgi?id=694321
2013-03-14 17:28:31 +01:00
a8c87f3bab overview: Only keep ourselves in the overview on button events
This prevents using Control to quickly launch a new instance of
an app in search results or with keyboard navigation.

https://bugzilla.gnome.org/show_bug.cgi?id=695801
2013-03-14 12:05:42 -04:00
b39e76200a overview: Don't use a captured-event handler to detect the control key
captured-event handlers are easily messed up by an earlier event
handler capturing the event. Instead, use the current Clutter event
and check for the state of that.

https://bugzilla.gnome.org/show_bug.cgi?id=695161

https://bugzilla.gnome.org/show_bug.cgi?id=695801
2013-03-14 12:05:42 -04:00
01deb9ef7d status/keyboard: Check if this._currentSource is valid on activation
this._currentSource might be invalid so check for that to prevent an
exception and still switch to the newly activated source.

https://bugzilla.gnome.org/show_bug.cgi?id=695841
2013-03-14 14:56:28 +01:00
5c89568cca status/keyboard: Always hide the old source panel indicator label
When we switch into an invalid input source we hide the panel
indicator and return early but we were not hiding the previously
active source label and its menu item dot and thus when switching
again to a third input source we would end up showing 2 overlapping
labels in the panel and the menu would have 2 entries with a dot.

https://bugzilla.gnome.org/show_bug.cgi?id=695841
2013-03-14 14:56:27 +01:00
6119b44746 Improve tracking of fullscreen windows
It's possible in some corner cases for the status of the topwindow
to change and make it not fullscreen without ::restacked being
changed. One way that it could happen with the old code was if the
layer of the top window changed from NORMAL to FULLSCREEN.

Change the logic not to look at the layer, which is a function of
Mutter's *intended* stacking, rather than the *actual* stacking,
which is what ::restacked gives you. Instead, look at the top
portion of the stack, down to the first non-override-redirect
window, and see if their are any monitor-sized windows there.

Connect to changes on the top portion of the stack, so we know
if conditions change.

https://bugzilla.gnome.org/show_bug.cgi?id=649748
2013-03-14 08:06:08 -04:00
7af4a7bf88 Updated Czech translation 2013-03-14 12:58:19 +01:00
04e4d69662 IBus.Property's state needs to be kept in IBus.PropType.NORMAL
https://bugzilla.gnome.org/show_bug.cgi?id=695824
2013-03-14 09:41:58 +01:00
a87e0f028a screenShield: Also unlock on Return/Enter
Since that's what I always did before, having it ignore those is
driving me mad.

https://bugzilla.gnome.org/show_bug.cgi?id=686740
2013-03-13 13:27:34 -04:00
31774a7711 theme: Add :focus style for app-view-controls
https://bugzilla.gnome.org/show_bug.cgi?id=694951
2013-03-13 10:42:22 +01:00
a32f27a2aa ctrlAltTab: Fix external DOCK windows
We always add external DOCK windows to the ctrl-alt-tab switcher,
e.g. separate dock applications or nautilus' desktop windows.
Since commit 1f46a0dc26, all items in the switcher are expected
to set a proxy parameter, but the aforementioned code was not
updated accordingly.

https://bugzilla.gnome.org/show_bug.cgi?id=695395
2013-03-13 10:18:16 +01:00
805a409318 keyring: Don't replace an already running prompter
* Prompters have state, and cancelling an already prompter will
   cause prompts that are in progress to fail.
 * In addition allow replacement of our shell prompter for debugging
   purposes.

https://bugzilla.gnome.org/show_bug.cgi?id=695485
2013-03-13 07:57:16 +01:00
42d45bd14a searchDisplay: Scroll the search results when using keynav
This makes keynav for search results much more usable.

https://bugzilla.gnome.org/show_bug.cgi?id=689681
2013-03-12 19:29:48 -04:00
5870709fbc appDisplay: Move ensureIconVisible logic to util, make it more generic
In particular, make it work if we have multiple parents, like in the
search case.

https://bugzilla.gnome.org/show_bug.cgi?id=689681
2013-03-12 19:29:47 -04:00
0fdb7430ff Updated Portuguese translation 2013-03-12 22:38:14 +00:00
4771f80d6f messageTray: Remove the tray left timeout when showing a new notification
https://bugzilla.gnome.org/show_bug.cgi?id=695659
2013-03-12 11:58:53 -04:00
91405583fd messageTray: Fizzle out hover notifications where the values are the same
notify::* doesn't guarantee that the value has changed, only that it
may have been. We need to ensure that we track the old value to make sure
we don't do things like overwrite timeouts if they already exist.

https://bugzilla.gnome.org/show_bug.cgi?id=695659
2013-03-12 11:58:52 -04:00
f864303aac messageTray: Remove summary state management
Now that the tray is modal, the summary is tied to the tray,
and we don't need to have separate states for the tray and
summary. This also removes the nearly invisible opacity tween
on the summary items when opening the message tray.

https://bugzilla.gnome.org/show_bug.cgi?id=695659
2013-03-12 11:58:52 -04:00
e5ebf4a2b2 messageTray: Remove locking
The only way that locking happens is with when the summary box
pointer is active. As it can only happen if the summary state
is active, it's impossible for a notification to be expired,
or the summary to be hidden while it's showing.

https://bugzilla.gnome.org/show_bug.cgi?id=695659
2013-03-12 11:58:52 -04:00
725a36e37a messageTray: Use the bottom monitor's fullscreen state for rate limiting
It makes more sense to use the monitor the tray is on, rather than the
primary monitor. This also matches us with whether we can open the tray
from a barrier/dwell or not.

https://bugzilla.gnome.org/show_bug.cgi?id=695659
2013-03-12 11:58:51 -04:00
78dacfa865 messageTray: Fix idle tracking condition
The user is active if they have less than IDLETIME, not if
they have more than it.

This fixes an issue where notifications may never go away.

https://bugzilla.gnome.org/show_bug.cgi?id=695659
2013-03-12 11:58:51 -04:00
16547fb3c2 messageTray: Clean up code a tiny bit
Remove some duplication by reusing a method.

https://bugzilla.gnome.org/show_bug.cgi?id=695659
2013-03-12 11:58:51 -04:00
9eeabf79f9 messageTray: Fix style
https://bugzilla.gnome.org/show_bug.cgi?id=695659
2013-03-12 11:58:51 -04:00
81b71cc143 messageTray: Remove a few leftover variables
https://bugzilla.gnome.org/show_bug.cgi?id=695659
2013-03-12 11:58:50 -04:00
8301acd4d6 grabHelper: Use a round trip for focusing the default window
We may release the focus grab at any time, so it's not guaranteed
we'll be in event processing. In particular, hovering over and out
of a notification will cause this to happen, as the notification
is hidden on a timeout.

https://bugzilla.gnome.org/show_bug.cgi?id=695659
2013-03-12 11:58:50 -04:00
f80afb1755 [l10n] Updated Estonian translation 2013-03-12 17:53:56 +02:00
71c6b60054 [l10n] Updated Catalan translation 2013-03-11 23:02:08 +01:00
95a1b874d8 Update libgnome-volume-control to master
Pick a few fixes, including a memory leak fix.

https://bugzilla.gnome.org/show_bug.cgi?id=695656
2013-03-11 22:28:55 +01:00
07de96ede9 recorder: Disconnect stage signals when not recording
This causes unnecessary work, so only connect them when needed i.e
while recording.

https://bugzilla.gnome.org/show_bug.cgi?id=695650
2013-03-11 20:11:18 +01:00
209014b083 screenShield: Forward key presses to tne entry when raising the shield
https://bugzilla.gnome.org/show_bug.cgi?id=686740
2013-03-11 15:08:21 -04:00
127f10e7a8 screenShield: Don't wait until the dialog is loaded before opening it
If we wait asynchronously, key presses while the shield is opening
will be dropped in the void.

https://bugzilla.gnome.org/show_bug.cgi?id=686740
2013-03-11 15:08:21 -04:00
67615a0cbc screenShield: Remove bump on key press
Any key press of a character-emitting key will now raise the shell.
Note that the key press will not be forwarded to the entry yet.

https://bugzilla.gnome.org/show_bug.cgi?id=686740
2013-03-11 15:08:20 -04:00
dde20f0c76 screenShield: Move opening of screen shield to key press
This makes the screen shield much more responsive.

https://bugzilla.gnome.org/show_bug.cgi?id=686740
2013-03-11 15:08:20 -04:00
ddced79475 recorder: port to XInput2
Pointer tracking is broken when the pointer is over the stage input
area.  This is apparently fallout from mutter going to XInput2.

This commit changes the mouse event handling code to also use XInput2.

https://bugzilla.gnome.org/show_bug.cgi?id=695324
2013-03-11 13:11:08 -04:00
e80795b7f0 recorder: don't bother selecting for enter/leave/motion events
Mutter already handles that for us.

https://bugzilla.gnome.org/show_bug.cgi?id=695324
2013-03-11 12:35:38 -04:00
080337a4e8 Updated German translation 2013-03-11 14:25:21 +01:00
884af3c986 style: Prevent dash from overlapping content
In order to center the view selector, the dash has been moved to a
separate layer, which means that it will overlap the app picker and
search results if the available width is smaller than the maximum
width that the content will request. Fix this by adding enough
horizontal padding to account for the width the dash will have at
its largest icon size.

https://bugzilla.gnome.org/show_bug.cgi?id=695471
2013-03-11 13:33:05 +01:00
edc95b2cb7 Updated Indonesian translation 2013-03-11 16:47:37 +07:00
96239e95ec userMenu: Add translation comments
Seems like "console" vs. "remote" in the "other users" dialog  confuses some
translators so add a comments to clarify their meaning.

https://bugzilla.gnome.org/show_bug.cgi?id=695601
2013-03-11 10:35:42 +01:00
331ad76675 Updated German translation 2013-03-10 23:59:06 +01:00
29152d3022 layout: Disable the overview hotcorner when we have a full-screen window open
For the same reasons that we disable the tray barrier, we should
disable hot corners as well -- when users have a full-screen game
open, we shouldn't allow overview activation by the hotcorner.

https://bugzilla.gnome.org/show_bug.cgi?id=694997
2013-03-10 12:00:09 -04:00
73fa4b1cbd messageTray: Don't open by pressure when we have a full-screen window open
When we have a full-screen window open, we expect the app to get all of
the chrome, so we should disable the bottom barrier as well.

https://bugzilla.gnome.org/show_bug.cgi?id=694997
2013-03-10 12:00:09 -04:00
7766a91e8c Wanda: so long GNOME 2, and thanks for all the fish.
gnome-panel is going away in 3.8, so we can't rely on it to provide our
friendly and reliable companion. But no regret, because we can ship it
ourselves, and at the same time remove some unnecessary configuration.

https://bugzilla.gnome.org/show_bug.cgi?id=695526
2013-03-10 15:54:40 +01:00
b7bad765aa Updated Latvian translation 2013-03-10 14:56:32 +02:00
5af09a60e9 Main: close the looking glass when we don't have a run dialog
No run dialog means no looking glass either.

https://bugzilla.gnome.org/show_bug.cgi?id=695458
2013-03-08 23:18:31 +01:00
ef623cfbbd Updated Serbian translation 2013-03-08 20:28:31 +01:00
ce5faba185 osdWindow: bump down the OSD window size a bit
Matches what this commit did for g-s-d:
https://git.gnome.org/browse/gnome-settings-daemon/commit/plugins/media-keys?id=fbf3c5aa366ef7212f209e123d4aae315a1a2a8e

https://bugzilla.gnome.org/show_bug.cgi?id=695409
2013-03-07 17:02:41 -05:00
40d9ed535b runDialog: Remove the use of file monitors for file completion
Launching the run dialog to open the looking glass or something
like that shouldn't install a bunch of file monitors that monitor
every IO change to the home and system directories.

Instead, simply scan all the paths when trying to complete.

https://bugzilla.gnome.org/show_bug.cgi?id=695338
2013-03-07 16:35:37 -05:00
d5675765f3 runDialog: Remove tab-completion preloading
This is iffy anyway, since we don't wait for the correct signal.
Just make the user press tab again, like they would do anyway.

https://bugzilla.gnome.org/show_bug.cgi?id=695338
2013-03-07 16:35:37 -05:00
65067c24cc main: Show the greeter dialog when we're prepared
If we don't wait until the stage is mapped, pushing a modal
will fail with an X error.

https://bugzilla.gnome.org/show_bug.cgi?id=694321
2013-03-07 16:35:37 -05:00
e2463cb501 layout: Move showing the stage and the startup-prepared signal
Waiting until we're idle means nothing if we're constructing
complex actors.

https://bugzilla.gnome.org/show_bug.cgi?id=694321
2013-03-07 16:35:36 -05:00
de2f2d7ef1 main: Remove leftover hunk connection to sessionUpdated
We shouldn't connect to sessionUpdated twice.

https://bugzilla.gnome.org/show_bug.cgi?id=694321
2013-03-07 16:35:36 -05:00
7cdb75e7ce Defer initializing UI until after the global session has loaded
https://bugzilla.gnome.org/show_bug.cgi?id=694321
2013-03-07 16:35:36 -05:00
1502e308b8 Updated Slovenian translation 2013-03-07 20:51:04 +01:00
dd1fe68e5c Finnish translation update by Jiri Grönroos 2013-03-07 21:02:09 +02:00
85c1dc5a0c Updated Kazakh translation. 2013-03-07 20:19:30 +06:00
7b3a689aad theme: match the hover effect radius to the prelight effect
Application view: the radius of the corners on the hover effect
should match the radius of the prelight effect that is used for
running apps. Original fix from Bharath Thiruveedula.

https://bugzilla.gnome.org/show_bug.cgi?id=691578
2013-03-07 12:48:38 +00:00
2c28a12cca Updated Uyghur translation
Signed-off-by: Gheyret Kenji <gheyret@gmail.com>
2013-03-07 21:05:47 +09:00
324021fd64 Updated Russian translation 2013-03-07 09:36:24 +04:00
1dceae97c6 Revert "Defer initializing UI until after the global session has loaded"
This reverts commit 0bef925b51.

Just for now.  Jasper has plans to clean up start up eventually.

https://bugzilla.gnome.org/show_bug.cgi?id=694321
2013-03-06 17:26:15 -05:00
0bef925b51 Defer initializing UI until after the global session has loaded
https://bugzilla.gnome.org/show_bug.cgi?id=694321
2013-03-06 14:55:58 -05:00
0ba1f29e40 main: Merge two different session-mode-updated handlers
https://bugzilla.gnome.org/show_bug.cgi?id=694321
2013-03-06 14:34:59 -05:00
3b1e536822 screenShield: Drop fallback implementation
With fallback mode gone, we can no longer rely on gnome-screensaver
being installed. Rather than handling three different cases (GDM,
gnome-screensaver, no lock), disable the lock functionality when
not running under GDM.

https://bugzilla.gnome.org/show_bug.cgi?id=693403
2013-03-06 16:22:07 +01:00
9a83662a18 loginManager: Move UnlockDialog.isSupported() here
With fallback mode dropped, we can no longer rely on gnome-screensaver
to be installed, so we'll have cases where we are unable to lock the
screen. The user menu should not show the "Lock" item in this case,
but as UnlockDialog includes UserMenu, we cannot use the existing check
without creating a circular dependency; move the function to a more
generic place to fix.

https://bugzilla.gnome.org/show_bug.cgi?id=693403
2013-03-06 16:22:07 +01:00
5bcead5b5c build: Really remove build time dependency on tp-logger
Commit 00eb764880 removed the dependency from configure, but kept
the gir include. Remove that as well.

https://bugzilla.gnome.org/show_bug.cgi?id=695272
2013-03-06 16:22:06 +01:00
d8f9502ea2 Updated Traditional Chinese translation(Hong Kong and Taiwan) 2013-03-06 19:07:01 +08:00
020128b9ca background: don't use raise_top() since it's costly
We currently resync the stacking order of the two key frames
every iteration of the animation.  This is costly and unnecessary.

This commit ensures they're stacked properly up front and doesn't
touch them after that.

https://bugzilla.gnome.org/show_bug.cgi?id=694993
2013-03-05 16:03:12 -05:00
1566a4e607 unlockDialog, loginDialog: Connect to the activate signal on the entry
This is the recommended way to connect to an entry's activation binding --
event bubbling is not guaranteed by ClutterText.

https://bugzilla.gnome.org/show_bug.cgi?id=695154
2013-03-05 15:25:11 -05:00
fbd59631ee Assamese translation updated for gnome 3.8 2013-03-05 19:20:22 +05:30
6c36856499 layout: fix errors in fallback HotCorner function 2013-03-05 17:53:59 +11:00
f4cda49988 Bump version to 3.7.91
Update NEWS.
2013-03-05 00:42:25 +01:00
a6b49fe7d6 st-icon: Don't cause a redraw by replacing the icon with itself
Check if the two icons match before setting a new icon, if they
do don't do anything.

Based on patch from Owen Taylor <otaylor@fishsoup.net>

https://bugzilla.gnome.org/show_bug.cgi?id=694988
2013-03-05 00:03:29 +01:00
26966b2bf3 layout: Port the hot corner to pressure barriers
If the X server supports the new barrier features, we should
trigger the overview hot corner with a pressure barrier as well.

https://bugzilla.gnome.org/show_bug.cgi?id=663661
2013-03-04 17:47:48 -05:00
36a7429aa0 overview: Try to do the right thing related to XDnD
Rather than expose a dizzying array of methods related to managing
state that require infecting every user of the overview methods, try
to do the sensible and smart thing internally. Now, the overview
itself tracks when XDND drags start, and simply calling show, hide or
toggle while an XDnD drag is in effect will show the overview, and
will only take the grab until after the XDND drag ends.

https://bugzilla.gnome.org/show_bug.cgi?id=663661
2013-03-04 17:47:47 -05:00
7be1fe09f1 layout: Don't use the corner's position for positioning ripples
The corner may not be there in the future.

https://bugzilla.gnome.org/show_bug.cgi?id=663661
2013-03-04 17:03:24 -05:00
62bf08d323 layout: Put two barriers near every single hot corner
This will make the hot corner easier to hit on multi-monitor
scenarios, and also gives us a convenient set of barriers to
key pressure off of.

https://bugzilla.gnome.org/show_bug.cgi?id=663661
2013-03-04 17:03:24 -05:00
260c082c4e main: defer session update until startup animation
We currently call the session updated handler as soon as
the session modes are read.  This handler sets up keybindings
for leaving the overview (if a user session) and shows the
login dialog (if a gdm session).

We can't do the latter until the stage is mapped because it
takes a grab, and we don't need to do the former until the
user goes into the overview.

This commit defers processing session updates until the
the layout manager says start up is prepared.

It fixes a race condition at login screen startup now that
we don't show the stage right away.

https://bugzilla.gnome.org/show_bug.cgi?id=694321
2013-03-04 16:45:32 -05:00
5e0ff7fd56 main: don't explicitly hide the stage
It's hidden by default, so there's no point in hiding it explicitly.

https://bugzilla.gnome.org/show_bug.cgi?id=694321
2013-03-04 16:45:32 -05:00
aac312ca34 overviewControls: only show chat icon in messages indicator for chats
Only show the chat icon in the new messages indicator when at least one
among the outstanding notifications is a chat.
2013-03-04 16:25:50 -05:00
a90401454a layout: Pass the X/Y coordinates when constructing the corner
There's no guarantee that hot corners will have an actor in
the future -- they may be powered entirely by a barrier.

https://bugzilla.gnome.org/show_bug.cgi?id=663661
2013-03-04 15:50:45 -05:00
5679e6b3a9 layout: Construct the primary monitors's hot corner, too
This cleans up the code considerably, and makes it so that
one path creates all hot corners for all monitors. Why this
wasn't done originally, I have no clue...

The one complication is debouncing if the button and hot corner
are triggered in rapid succession, so we just move this tracking
to the overview.

https://bugzilla.gnome.org/show_bug.cgi?id=663661
2013-03-04 15:50:45 -05:00
194574bb0e layout: Allow multiple barriers to contribute to a PressureBarrier
For the HotCorner case, we want to have to barriers both contribute
to the hot corner pressure, so we can't simply wrap the pressure
barrier.
2013-03-04 15:50:44 -05:00
337d2da38a layout: Move tray-specific event filtration to the user of PressureBarrier
For the HotCorner, we want to have different logic for tossing out
specific events based on the grabbed state, etc. so make us have
to pass in an event filter callback.
2013-03-04 15:50:44 -05:00
df848aa084 layout: Move the keybinding mode to the user of PressureBarrier
For the hot corner case, we want to have the pressure apply both in
and outside of the overview, so we need to move this to the user. At
the same time, use keybinding mode math that's more like what's used
in filterKeybinding.

While it may seem like an abuse of the KeyBindingMode API, it may
become more reasonable if one thinks of the pressure barrier as a
binding of sorts, just applied to the mouse. If a ButtonBinding API
was added to mutter, I think we'd use the existing KeyBindingMode
infastructure there as well.
2013-03-04 15:50:44 -05:00
0cc1615252 layout: Debounce triggering barriers
Ensure that the pointer leaves the barrier before we trigger again.

For the message tray case, this doesn't matter much, as the trigger
won't have any effect after the grab is taken, but in the overview
HotCorner case, this ensures that we don't trigger the overview
transition many times simply by holding pressure against the hot
corner, which is easy to do accidentally.
2013-03-04 15:50:44 -05:00
d4259fa8aa layout: Prevent going into negatives with the pressure
We capped each event to 15px of travel, but we didn't do the same
cap when subtracting events that were too old.
2013-03-04 15:50:43 -05:00
157d7e2b59 Updated Lithuanian translation 2013-03-04 22:45:23 +02:00
ee50904147 Calendar: only show events when configured in Evolution
When no calendars are enabled, hide the events pane completely instead
of showing it empty.

https://bugzilla.gnome.org/show_bug.cgi?id=680083
2013-03-04 18:59:30 +01:00
ec39aa3890 Calendar: dim days from other months, even if they have events
Invert the order of the declarations, so those for calendar-other-month-day
take priority over those for calendar-day-with-events.

https://bugzilla.gnome.org/show_bug.cgi?id=641383
2013-03-04 18:59:30 +01:00
beb0fdf4b8 Calendar: clean up code by always having an event source
Instead of sometimes having an event source and sometimes not, use
the empty event source when the session mode says the calendar is
disabled. This way, the code can assume an event source object and
avoid checks.

https://bugzilla.gnome.org/show_bug.cgi?id=641383
2013-03-04 18:59:30 +01:00
443fe813c3 Calendar: freeze updates when the event source is loading
Check if the event source is currently doing an async call, and prevent
UI updates in that case. This avoids a flash of "No updates" when switching
months.

https://bugzilla.gnome.org/show_bug.cgi?id=641383
2013-03-04 18:59:30 +01:00
69cdc5a9b9 Calendar: force all months at the same height
Add one or two weeks from nearby months to avoid changing the menu height
when navigating it.

https://bugzilla.gnome.org/show_bug.cgi?id=641383
2013-03-04 18:59:30 +01:00
dac54a6019 Migrate from libgnome-keyring to libsecret
* See: https://live.gnome.org/GnomeGoals/LibsecretMigration

https://bugzilla.gnome.org/show_bug.cgi?id=679851
2013-03-04 18:47:52 +01:00
e5ca53e56c status/keyboard: Don't allow the switcher in the message tray
SwitcherPopup relies on being able to pushModal(), setting the stage
input mode to FULLSCREEN, and then doing regular event processing on
the actor it adds to uiGroup. But MessageTray uses GrabHelper which
sets up a 'captured-event' handler on the stage and thus gets all
events itself.

This, of course, breaks the switcher if it's brought up in the message
tray so, for now, we'll just prevent it from being used there.

https://bugzilla.gnome.org/show_bug.cgi?id=693907
2013-03-04 18:32:49 +01:00
7a79236bab theme: use standard styling for ibus candidate popups
This is more consistent and helps with legibility.

https://bugzilla.gnome.org/show_bug.cgi?id=694796
2013-03-04 17:03:31 +00:00
cd37e2908f main: don't hook up overview keybinding until after startup
Toggling the overview during the startup animation reportedly
causes stuck grab and other odd behavior.

There's no reason to handle toggling the overview during this
time anyway.

This commit defers that handling until after startup.

https://bugzilla.gnome.org/show_bug.cgi?id=694837
2013-03-04 11:58:39 -05:00
108 changed files with 25170 additions and 17156 deletions

102
NEWS
View File

@ -1,3 +1,105 @@
3.8.0.1
=======
* Background bug fixes [Ray; #696712]
3.8.0
=====
* Remove blur and desaturation from lock screen [Jasper; #696322]
* Remove scroll view fade near edges [Adel; #696404]
* dateMenu: Open calendar component when using Evolution [Florian; #696432]
* Fix unlocking on fast user switch [Cosimo; #696287]
* Tweak screen shield animation [Rui; #696380]
* Fix major memory leak when changing backgrounds [Ray; #696157]
* Miscellaneous bug fixes [Jasper, Adel, Florian; #696199, #696212, #696422,
#696447, #696235]
Contributors:
Giovanni Campagna, Cosimo Cecchi, Adel Gadllah, Rui Matos, Florian Müllner,
Jasper St. Pierre, Ray Strode
Translations:
Alexandre Franke [fr], Victor Ibragimov [tg], Arash Mousavi [fa],
Gabor Kelemen [hu], Sandeep Sheshrao Shedmake [mr], ManojKumar Giri [or],
Shantha kumar [ta], Rajesh Ranjan [hi], Stas Solovey [ru],
Shankar Prasad [kn], Dušan Kazik [sk], Ihar Hrachyshka [be],
Wouter Bolsterlee [nl], Kris Thomsen [da], Jiro Matsuzawa [ja],
Daniel Korostil [uk], Ani Peter [ml], Krishnababu Krothapalli [te],
Mantas Kriaučiūnas [lt], Praveen Illa [te]
3.7.92
======
* Drop fallback lock implementation [Florian; #693403]
* Don't let the user trigger message-tray when in fullscreen [Jasper; #694997]
* Scroll search results when using keynav [Jasper; #689681]
* Allow raising the shield by starting to type the password [Jasper; #686740]
* Improve tracking of fullscreen windows [Owen; #649748]
* Improve animation of new windows in overview [Giovanni; #695582]
* workspace switcher: Animate new workspaces created by DND [Giovanni; #685285]
* Give user time to read messages on login screen [Ray; #694688]
* Misc bug fixes and cleanups [Jasper, Ray, Florian, Cosimo, Giovanni, Adel,
Stef, Takao, Rui, Neil; #695154, #694993, #695272, #691578, #694321, #695338,
#695409, #695458, #695526, #695601, #695471, #695324, #695650, #695656,
#695659, #695485, #695395, #694951, #695824, #695841, #695801, #694321,
#693708, #695800, #695607, #695882, #691578, #685851, #694371, #690857,
#694092, #695747, #696007, #693438, #696064, #696102
Contributors:
Giovanni Campagna, Cosimo Cecchi, Allan Day, Takao Fujiwara, Adel Gadllah,
Tim Lunn, Rui Matos, Florian Müllner, Neil Roberts, Jasper St. Pierre,
Ray Strode, Stef Walter, Colin Walters, Owen W. Taylor
Translations:
Nilamdyuti Goswami [as], Chao-Hsiung Liao [zh_HK, zh_TW],
Yuri Myasoedov [ru], Gheyret Kenji [ug], Baurzhan Muftakhidinov [kk],
Ville-Pekka Vainio [fi], Matej Urbančič [sl],
Мирослав Николић [sr, sr@latin], Rūdolfs Mazurs [lv], Christian Kirbach [de],
Andika Triwidada [id], Gil Forcada [ca], Mattias Põldaru [et],
Duarte Loreto [pt], Adam Matoušek [cs], Changwoo Ryu [ko],
Ihar Hrachyshka [be], Carles Ferrando [ca@valencia], Sweta Kothari [gu]
3.7.91
======
* overview: Fade out controls during DND that are not targets [Cosimo; #686984]
* overview: Keep open when a Control key is held [Florian; #686984]
* Improve login screen => session transition [Ray; #694321]
* Center application grid horizontally [Florian; #694261]
* Fix hiding panel when fullscreen windows span multiple monitors [Adel; 646861]
* Tweak thresholds of pressure barrier [Jasper; #694467]
* Tweak window picker layout [Jasper; #694902]
* Expose key grab DBus API to gnome-settings-daemon [Florian; #643111]
* Don't always show message tray in overview, add message indicator
[Cosimo; #687787]
* Tweak startup animation [Ray; #694326]
* Add OSD popups and expose them to gnome-settings-daemon [Florian; #613543]
* Move loupe icon to the start of the search entry [Jasper; #695069]
* Don't show the input switcher with less than 2 items [Rui; 695000]
* Fix auto-completion of system modals immediately upon display [Stef; #692937]
* Ignore workspaces in alt-tab [Florian; #661156]
* Disable copying text from password entries [Florian; #695104]
* Use standard styling for ibus candidate popups [Allan; #694796]
* Fix calendar changing height on month changes [Giovanni; #641383]
* Port the hot corner to use pressure barriers [Jasper; #663661]
* Misc bug fixes and cleanups: [Hashem, Giovanni, Alban, Jasper, Cosimo,
Florian, Adel, Daniel, Matthias, Ray, Rui, Guillaume, Stef; #685849, #690643,
#694292, #693814, #694234, #694365, #694287, #694336, #694256, #694261,
#663601, #694441, #694284, #694463, #694475, #687248, #694394, #694320,
#694701, #694784, #694858, #694906, #694327, #694876, #694905, #694969,
#694970, #694988, #695006, #695001, #694998, #695023, #695002, #695073,
#695126, #687748, #694837, #693907, #679851, #694988]
Contributors:
Giovanni Campagna, Cosimo Cecchi, Matthias Clasen, Alban Crequy, Allan Day,
Guillaume Desmottes, Adel Gadllah, Rui Matos, Daniel Mustieles,
Hashem Nasarat, Jasper St. Pierre, Ray Strode, Stef Walter
Translations:
Yuri Myasoedov [ru], Adam Matoušek [cs], Piotr Drąg [pl], Matej Urbančič [sl],
Sweta Kothari [gu], Kjartan Maraas [nb], Nguyễn Thái Ngọc Duy [vi],
Chao-Hsiung Liao [zh_HK, zh_TW], Dimitris Spingos [el],
Inaki Larranaga Murgoitio [eu], Luca Ferretti [it], A S Alam [pa],
Gheyret Kenji [ug], Stas Solovey [ru], Enrico Nicoletto [pt_BR],
Fran Diéguez [gl], Daniel Mustieles [es], Aurimas Černius [lt]
3.7.90
======
* Let GNOME Shell work on EGL and GLES2 [Neil; #693225, #693438, #693339]

View File

@ -1,5 +1,5 @@
AC_PREREQ(2.63)
AC_INIT([gnome-shell],[3.7.90],[https://bugzilla.gnome.org/enter_bug.cgi?product=gnome-shell],[gnome-shell])
AC_INIT([gnome-shell],[3.8.0.1],[https://bugzilla.gnome.org/enter_bug.cgi?product=gnome-shell],[gnome-shell])
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_SRCDIR([src/shell-global.c])
@ -63,7 +63,7 @@ AM_CONDITIONAL(BUILD_RECORDER, $build_recorder)
CLUTTER_MIN_VERSION=1.13.4
GOBJECT_INTROSPECTION_MIN_VERSION=0.10.1
GJS_MIN_VERSION=1.35.4
MUTTER_MIN_VERSION=3.7.90
MUTTER_MIN_VERSION=3.8.0
GTK_MIN_VERSION=3.7.9
GIO_MIN_VERSION=2.35.0
LIBECAL_MIN_VERSION=3.5.3
@ -96,7 +96,7 @@ PKG_CHECK_MODULES(GNOME_SHELL, gio-unix-2.0 >= $GIO_MIN_VERSION
polkit-agent-1 >= $POLKIT_MIN_VERSION xfixes
libnm-glib libnm-util >= $NETWORKMANAGER_MIN_VERSION
libnm-gtk >= $NETWORKMANAGER_MIN_VERSION
gnome-keyring-1 gcr-3 >= $GCR_MIN_VERSION)
libsecret-unstable gcr-3 >= $GCR_MIN_VERSION)
PKG_CHECK_MODULES(GNOME_SHELL_JS, gio-2.0 gjs-internals-1.0 >= $GJS_MIN_VERSION)
PKG_CHECK_MODULES(ST, clutter-1.0 gtk+-3.0 libcroco-0.6 >= 0.6.8 x11)

View File

@ -1,3 +1,6 @@
wandadir = $(pkgdatadir)
dist_wanda_DATA = wanda.png
desktopdir=$(datadir)/applications
desktop_DATA = gnome-shell.desktop gnome-shell-extension-prefs.desktop

View File

@ -125,7 +125,8 @@ StScrollBar StButton#vhandle:active {
/* PopupMenu */
.popup-menu-boxpointer {
.popup-menu-boxpointer,
.candidate-popup-boxpointer {
-arrow-border-radius: 8px;
-arrow-background-color: rgba(0,0,0,0.9);
-arrow-border-width: 2px;
@ -315,10 +316,20 @@ StScrollBar StButton#vhandle:active {
.notification-button:focus,
.notification-icon-button:focus,
.hotplug-notification-item:focus,
.modal-dialog-button:focus {
.modal-dialog-button:focus,
.app-view-control:focus {
border-width: 2px;
}
.app-view-control:focus {
padding: 3px;
}
.app-view-control:first-child:ltr:focus,
.app-view-control:last-child:rtl:focus {
border-right-width: 1px;
}
.candidate-page-button:active,
.candidate-page-button:pressed,
.notification-button:active,
@ -886,8 +897,8 @@ StScrollBar StButton#vhandle:active {
.search-display > StBoxLayout,
.all-apps > StBoxLayout,
.frequent-apps > StBoxLayout {
/* horizontal padding to make sure the scrollbar doesn't overlap content */
padding: 0px 18px;
/* horizontal padding to make sure scrollbars or dash don't overlap content */
padding: 0px 88px;
}
.app-folder-icon {
@ -963,6 +974,10 @@ StScrollBar StButton#vhandle:active {
color:white;
}
.app-display .app-well-app > .overview-icon {
border-radius: 10px;
}
.list-search-result:hover .list-search-result-description {
text-shadow: rgba(0,0,0,0.8) 0px 1px 2px;
}
@ -1257,15 +1272,15 @@ StScrollBar StButton#vhandle:active {
font-weight: bold;
}
.calendar-other-month-day {
color: #333333;
}
.calendar-day-with-events {
font-weight: bold;
color: white;
}
.calendar-other-month-day {
color: #333333;
}
.events-header-vbox {
spacing: 6pt;
padding-right: .5em;
@ -2129,23 +2144,12 @@ StScrollBar StButton#vhandle:active {
}
/* IBus Candidate Popup */
.candidate-popup-boxpointer {
-arrow-border-radius: 8px;
-arrow-background-color: #707070;
-arrow-border-width: 0px;
-arrow-base: 24px;
-arrow-rise: 11px;
}
.candidate-popup-content {
padding: 0.5em;
spacing: 0.3em;
}
.candidate-popup-text {
font-size: 9pt;
}
.candidate-index {
padding: 0 0.5em 0 0;
color: #cccccc;
@ -2211,6 +2215,9 @@ StScrollBar StButton#vhandle:active {
border: none;
background-color: transparent;
padding-bottom: 80px;
padding-top: 80px;
border-radius: 16px;
min-height: 150px;
max-height: 700px;

BIN
data/wanda.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

View File

@ -66,11 +66,4 @@ its dependencies to build from tarballs.</description>
<gnome:userid>fmuellner</gnome:userid>
</foaf:Person>
</maintainer>
<maintainer>
<foaf:Person>
<foaf:name>Ray Strode</foaf:name>
<foaf:mbox rdf:resource="mailto:halfline@gmail.com" />
<gnome:userid>halfline</gnome:userid>
</foaf:Person>
</maintainer>
</Project>

View File

@ -594,6 +594,7 @@ const LoginDialog = new Lang.Class({
this._promptEntry = new St.Entry({ style_class: 'login-dialog-prompt-entry',
can_focus: true });
this._promptEntryTextChangedId = 0;
this._promptEntryActivateId = 0;
this._promptBox.add(this._promptEntry,
{ expand: true,
x_fill: true,
@ -690,6 +691,8 @@ const LoginDialog = new Lang.Class({
},
_reset: function() {
this._userVerifier.clear();
this._updateSensitivity(true);
this._promptMessage.hide();
this._user = null;
@ -811,6 +814,11 @@ const LoginDialog = new Lang.Class({
Lang.bind(this, function() {
this._updateSignInButtonSensitivity(this._promptEntry.text.length > 0);
}));
this._promptEntryActivateId =
this._promptEntry.clutter_text.connect('activate', function() {
hold.release();
});
},
_updateSensitivity: function(sensitive) {
@ -835,6 +843,11 @@ const LoginDialog = new Lang.Class({
this._promptEntryTextChangedId = 0;
}
if (this._promptEntryActivateId > 0) {
this._promptEntry.clutter_text.disconnect(this._promptEntryActivateId);
this._promptEntryActivateId = 0;
}
this._setWorking(false);
this._promptBox.hide();
this._promptLoginHint.hide();
@ -917,7 +930,7 @@ const LoginDialog = new Lang.Class({
return batch.run();
},
_onSessionOpened: function(client, serviceName) {
_startSession: function(serviceName) {
Tweener.addTween(this.dialogLayout,
{ opacity: 0,
time: _FADE_ANIMATION_TIME,
@ -940,6 +953,18 @@ const LoginDialog = new Lang.Class({
onCompleteScope: this });
},
_onSessionOpened: function(client, serviceName) {
if (!this._userVerifier.hasPendingMessages) {
this._startSession(serviceName);
} else {
let signalId = this._userVerifier.connect('no-more-messages',
Lang.bind(this, function() {
this._userVerifier.disconnect(signalId);
this._startSession(serviceName);
}));
}
},
_waitForItemForUser: function(userName) {
let item = this._userList.getItemFromUserName(userName);
@ -1003,7 +1028,7 @@ const LoginDialog = new Lang.Class({
function() {
// If we're just starting out, start on the right
// item.
if (!this.is_loaded) {
if (!this._userManager.is_loaded) {
this._userList.jumpToItem(this._timedLoginItem);
}
},
@ -1141,15 +1166,6 @@ const LoginDialog = new Lang.Class({
Lang.bind(this, function(userManager, user) {
this._userList.removeUser(user);
}));
// emitted in idle so caller doesn't have to explicitly check if
// it's loaded immediately after construction
// (since there's no way the caller could be listening for
// 'loaded' yet)
Mainloop.idle_add(Lang.bind(this, function() {
this.emit('loaded');
this.is_loaded = true;
}));
},
_onOpened: function() {
@ -1164,5 +1180,9 @@ const LoginDialog = new Lang.Class({
this.parent();
Main.ctrlAltTabManager.removeGroup(this.dialogLayout);
}
},
addCharacter: function(unichar) {
this._promptEntry.clutter_text.insert_unichar(unichar);
},
});

View File

@ -2,6 +2,7 @@
const Clutter = imports.gi.Clutter;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const Lang = imports.lang;
const Mainloop = imports.mainloop;
const Signals = imports.signals;
@ -27,6 +28,9 @@ const ALLOWED_FAILURES_KEY = 'allowed-failures';
const LOGO_KEY = 'logo';
const DISABLE_USER_LIST_KEY = 'disable-user-list';
// Give user 16ms to read each character of a PAM message
const USER_READ_TIME = 16
function fadeInActor(actor) {
if (actor.opacity == 255 && actor.visible)
return null;
@ -114,6 +118,9 @@ const ShellUserVerifier = new Lang.Class({
this._fprintManager = new Fprint.FprintManager();
this._realmManager = new Realmd.Manager();
this._messageQueue = [];
this._messageQueueTimeoutId = 0;
this.hasPendingMessages = false;
this._failCounter = 0;
},
@ -153,13 +160,73 @@ const ShellUserVerifier = new Lang.Class({
this._userVerifier.run_dispose();
this._userVerifier = null;
}
this._clearMessageQueue();
},
answerQuery: function(serviceName, answer) {
// Clear any previous message
this.emit('show-message', null, null);
if (!this._userVerifier.hasPendingMessages) {
this._userVerifier.call_answer_query(serviceName, answer, this._cancellable, null);
} else {
let signalId = this._userVerifier.connect('no-more-messages',
Lang.bind(this, function() {
this._userVerifier.disconnect(signalId);
this._userVerifier.call_answer_query(serviceName, answer, this._cancellable, null);
}));
}
},
this._userVerifier.call_answer_query(serviceName, answer, this._cancellable, null);
_getIntervalForMessage: function(message) {
// We probably could be smarter here
return message.length * USER_READ_TIME;
},
finishMessageQueue: function() {
if (!this.hasPendingMessages)
return;
this._messageQueue = [];
this.hasPendingMessages = false;
this.emit('no-more-messages');
},
_queueMessageTimeout: function() {
if (this._messageQueue.length == 0) {
this.finishMessageQueue();
return;
}
if (this._messageQueueTimeoutId != 0)
return;
let message = this._messageQueue.shift();
this.emit('show-message', message.text, message.iconName);
this._messageQueueTimeoutId = GLib.timeout_add(GLib.PRIORITY_DEFAULT,
message.interval,
Lang.bind(this, function() {
this._messageQueueTimeoutId = 0;
this._queueMessageTimeout();
}));
},
_queueMessage: function(message, iconName) {
let interval = this._getIntervalForMessage(message);
this.hasPendingMessages = true;
this._messageQueue.push({ text: message, interval: interval, iconName: iconName });
this._queueMessageTimeout();
},
_clearMessageQueue: function() {
this.finishMessageQueue();
if (this._messageQueueTimeoutId != 0) {
GLib.source_remove(this._messageQueueTimeoutId);
this._messageQueueTimeoutId = 0;
}
this.emit('show-message', null, null);
},
_checkForFingerprintReader: function() {
@ -179,7 +246,7 @@ const ShellUserVerifier = new Lang.Class({
logError(error, where);
this._hold.release();
this.emit('show-message', _("Authentication error"), 'login-dialog-message-warning');
this._queueMessage(_("Authentication error"), 'login-dialog-message-warning');
this._verificationFailed(false);
},
@ -298,7 +365,7 @@ const ShellUserVerifier = new Lang.Class({
// to indicate the user can swipe their finger instead
this.emit('show-login-hint', _("(or swipe finger)"));
} else if (serviceName == PASSWORD_SERVICE_NAME) {
this.emit('show-message', info, 'login-dialog-message-info');
this._queueMessage(info, 'login-dialog-message-info');
}
},
@ -307,7 +374,7 @@ const ShellUserVerifier = new Lang.Class({
// users who haven't enrolled their fingerprint.
if (serviceName != PASSWORD_SERVICE_NAME)
return;
this.emit('show-message', problem, 'login-dialog-message-warning');
this._queueMessage(problem, 'login-dialog-message-warning');
},
_showRealmLoginHint: function() {
@ -346,8 +413,6 @@ const ShellUserVerifier = new Lang.Class({
},
_onReset: function() {
this.clear();
// Clear previous attempts to authenticate
this._failCounter = 0;
@ -358,6 +423,15 @@ const ShellUserVerifier = new Lang.Class({
this.emit('verification-complete');
},
_cancelAndReset: function() {
this.cancel();
this._onReset();
},
_retry: function() {
this.begin(this._userName, new Batch.Hold());
},
_verificationFailed: function(retry) {
// For Not Listed / enterprise logins, immediately reset
// the dialog
@ -369,15 +443,25 @@ const ShellUserVerifier = new Lang.Class({
this._failCounter < this._settings.get_int(ALLOWED_FAILURES_KEY);
if (canRetry) {
this.clear();
this.begin(this._userName, new Batch.Hold());
if (!this._userVerifier.hasPendingMessages) {
this._retry();
} else {
let signalId = this._userVerifier.connect('no-more-messages',
Lang.bind(this, function() {
this._userVerifier.disconnect(signalId);
this._retry();
}));
}
} else {
// Allow some time to see the message, then reset everything
Mainloop.timeout_add(3000, Lang.bind(this, function() {
this.cancel();
this._onReset();
}));
if (!this._userVerifier.hasPendingMessages) {
this._cancelAndReset();
} else {
let signalId = this._userVerifier.connect('no-more-messages',
Lang.bind(this, function() {
this._userVerifier.disconnect(signalId);
this._cancelAndReset();
}));
}
}
this.emit('verification-failed');

View File

@ -33,6 +33,10 @@ const SystemdLoginManagerIface = <interface name='org.freedesktop.login1.Manager
<arg type='s' direction='in'/>
<arg type='h' direction='out'/>
</method>
<method name='GetSession'>
<arg type='s' direction='in'/>
<arg type='o' direction='out'/>
</method>
<method name='ListSessions'>
<arg name='sessions' type='a(susso)' direction='out'/>
</method>
@ -72,7 +76,36 @@ const ConsoleKitSession = Gio.DBusProxy.makeProxyWrapper(ConsoleKitSessionIface)
const ConsoleKitManager = Gio.DBusProxy.makeProxyWrapper(ConsoleKitManagerIface);
function haveSystemd() {
return GLib.access("/sys/fs/cgroup/systemd", 0) >= 0;
return GLib.access("/run/systemd/seats", 0) >= 0;
}
function versionCompare(required, reference) {
required = required.split('.');
reference = reference.split('.');
for (let i = 0; i < required.length; i++) {
if (required[i] != reference[i])
return required[i] < reference[i];
}
return true;
}
function canLock() {
try {
let params = GLib.Variant.new('(ss)', ['org.gnome.DisplayManager.Manager', 'Version']);
let result = Gio.DBus.system.call_sync('org.gnome.DisplayManager',
'/org/gnome/DisplayManager/Manager',
'org.freedesktop.DBus.Properties',
'Get', params, null,
Gio.DBusCallFlags.NONE,
-1, null);
let version = result.deep_unpack()[0].deep_unpack();
return versionCompare('3.5.91', version);
} catch(e) {
return false;
}
}
let _loginManager = null;
@ -107,15 +140,23 @@ const LoginManagerSystemd = new Lang.Class({
// Having this function is a bit of a hack since the Systemd and ConsoleKit
// session objects have different interfaces - but in both cases there are
// Lock/Unlock signals, and that's all we count upon at the moment.
getCurrentSessionProxy: function() {
if (!this._currentSession) {
this._currentSession = new SystemdLoginSession(Gio.DBus.system,
'org.freedesktop.login1',
'/org/freedesktop/login1/session/' +
GLib.getenv('XDG_SESSION_ID'));
getCurrentSessionProxy: function(callback) {
if (this._currentSession) {
callback (this._currentSession);
return;
}
return this._currentSession;
this._proxy.GetSessionRemote(GLib.getenv('XDG_SESSION_ID'), Lang.bind(this,
function(result, error) {
if (error) {
logError(error, 'Could not get a proxy for the current session');
} else {
this._currentSession = new SystemdLoginSession(Gio.DBus.system,
'org.freedesktop.login1',
result[0]);
callback(this._currentSession);
}
}));
},
canPowerOff: function(asyncCallback) {
@ -204,15 +245,23 @@ const LoginManagerConsoleKit = new Lang.Class({
// Having this function is a bit of a hack since the Systemd and ConsoleKit
// session objects have different interfaces - but in both cases there are
// Lock/Unlock signals, and that's all we count upon at the moment.
getCurrentSessionProxy: function() {
if (!this._currentSession) {
let [currentSessionId] = this._proxy.GetCurrentSessionSync();
this._currentSession = new ConsoleKitSession(Gio.DBus.system,
'org.freedesktop.ConsoleKit',
currentSessionId);
getCurrentSessionProxy: function(callback) {
if (this._currentSession) {
callback (this._currentSession);
return;
}
return this._currentSession;
this._proxy.GetCurrentSessionRemote(Lang.bind(this,
function(result, error) {
if (error) {
logError(error, 'Could not get a proxy for the current session');
} else {
this._currentSession = new ConsoleKitSession(Gio.DBus.system,
'org.freedesktop.ConsoleKit',
result[0]);
callback(this._currentSession);
}
}));
},
canPowerOff: function(asyncCallback) {

View File

@ -5,6 +5,9 @@ const GLib = imports.gi.GLib;
const St = imports.gi.St;
const Main = imports.ui.main;
const Tweener = imports.ui.tweener;
const SCROLL_TIME = 0.1;
// http://daringfireball.net/2010/07/improved_regex_for_matching_urls
const _balancedParens = '\\((?:[^\\s()<>]+|(?:\\(?:[^\\s()<>]+\\)))*\\)';
@ -234,3 +237,39 @@ function makeCloseButton() {
return closeButton;
}
function ensureActorVisibleInScrollView(scrollView, actor) {
let adjustment = scrollView.vscroll.adjustment;
let [value, lower, upper, stepIncrement, pageIncrement, pageSize] = adjustment.get_values();
let offset = 0;
let vfade = scrollView.get_effect("fade");
if (vfade)
offset = vfade.vfade_offset;
let box = actor.get_allocation_box();
let y1 = box.y1, y2 = box.y2;
let parent = actor.get_parent();
while (parent != scrollView) {
if (!parent)
throw new Error("actor not in scroll view");
let box = parent.get_allocation_box();
y1 += box.y1;
y2 += box.y1;
parent = parent.get_parent();
}
if (y1 < value + offset)
value = Math.max(0, y1 - offset);
else if (y2 > value + pageSize - offset)
value = Math.min(upper, y2 + offset - pageSize);
else
return;
Tweener.addTween(adjustment,
{ value: value,
time: SCROLL_TIME,
transition: 'easeOutQuad' });
}

View File

@ -232,11 +232,11 @@ const AppSwitcherPopup = new Lang.Class({
},
_finish : function(timestamp) {
this.parent();
let appIcon = this._items[this._selectedIndex];
let window = this._currentWindow > 0 ? this._currentWindow : 0;
appIcon.app.activate_window(appIcon.cachedWindows[window], timestamp);
this.parent();
},
_onDestroy : function() {
@ -395,9 +395,9 @@ const WindowSwitcherPopup = new Lang.Class({
},
_finish: function() {
this.parent();
Main.activateWindow(this._items[this._selectedIndex].window);
this.parent();
}
});

View File

@ -29,7 +29,6 @@ const Util = imports.misc.util;
const MAX_APPLICATION_WORK_MILLIS = 75;
const MENU_POPUP_TIMEOUT = 600;
const SCROLL_TIME = 0.1;
const MAX_COLUMNS = 6;
const INACTIVE_GRID_OPACITY = 77;
@ -157,6 +156,30 @@ const FolderView = new Lang.Class({
}
});
const AllViewLayout = new Lang.Class({
Name: 'AllViewLayout',
Extends: Clutter.BinLayout,
vfunc_get_preferred_height: function(container, forWidth) {
let minBottom = 0;
let naturalBottom = 0;
for (let child = container.get_first_child();
child;
child = child.get_next_sibling()) {
let childY = child.y;
let [childMin, childNatural] = child.get_preferred_height(forWidth);
if (childMin + childY > minBottom)
minBottom = childMin + childY;
if (childNatural + childY > naturalBottom)
naturalBottom = childNatural + childY;
}
return [minBottom, naturalBottom];
}
});
const AllView = new Lang.Class({
Name: 'AllView',
Extends: AlphabeticalView,
@ -165,7 +188,7 @@ const AllView = new Lang.Class({
this.parent();
let box = new St.BoxLayout({ vertical: true });
this._stack = new St.Widget({ layout_manager: new Clutter.BinLayout() });
this._stack = new St.Widget({ layout_manager: new AllViewLayout() });
this._stack.add_actor(this._grid.actor);
this._eventBlocker = new St.Widget({ x_expand: true, y_expand: true });
this._stack.add_actor(this._eventBlocker);
@ -259,29 +282,7 @@ const AllView = new Lang.Class({
},
_ensureIconVisible: function(icon) {
let adjustment = this.actor.vscroll.adjustment;
let [value, lower, upper, stepIncrement, pageIncrement, pageSize] = adjustment.get_values();
let offset = 0;
let vfade = this.actor.get_effect("fade");
if (vfade)
offset = vfade.vfade_offset;
// If this gets called as part of a right-click, the actor
// will be needs_allocation, and so "icon.y" would return 0
let box = icon.get_allocation_box();
if (box.y1 < value + offset)
value = Math.max(0, box.y1 - offset);
else if (box.y2 > value + pageSize - offset)
value = Math.min(upper, box.y2 + offset - pageSize);
else
return;
Tweener.addTween(adjustment,
{ value: value,
time: SCROLL_TIME,
transition: 'easeOutQuad' });
Util.ensureActorVisibleInScrollView(this.actor, icon);
},
_updateIconOpacities: function(folderOpen) {

View File

@ -38,6 +38,7 @@ const BackgroundCache = new Lang.Class({
_init: function() {
this._patterns = [];
this._images = [];
this._pendingFileLoads = [];
this._fileMonitors = {};
},
@ -84,10 +85,10 @@ const BackgroundCache = new Lang.Class({
} else {
content.load_gradient(params.shadingType, params.color, params.secondColor);
}
this._patterns.push(content);
}
this._patterns.push(content);
return content;
},
@ -128,6 +129,73 @@ const BackgroundCache = new Lang.Class({
this._removeContent(this._images, content);
},
_loadImageContent: function(params) {
params = Params.parse(params, { monitorIndex: 0,
style: null,
filename: null,
effects: Meta.BackgroundEffects.NONE,
cancellable: null,
onFinished: null });
for (let i = 0; i < this._pendingFileLoads.length; i++) {
if (this._pendingFileLoads[i].filename == params.filename &&
this._pendingFileLoads[i].style == params.style) {
this._pendingFileLoads[i].callers.push({ shouldCopy: true,
monitorIndex: params.monitorIndex,
effects: params.effects,
onFinished: params.onFinished });
return;
}
}
this._pendingFileLoads.push({ filename: params.filename,
style: params.style,
callers: [{ shouldCopy: false,
monitorIndex: params.monitorIndex,
effects: params.effects,
onFinished: params.onFinished }] });
let content = new Meta.Background({ meta_screen: global.screen,
monitor: params.monitorIndex,
effects: params.effects });
content.load_file_async(params.filename,
params.style,
params.cancellable,
Lang.bind(this,
function(object, result) {
try {
content.load_file_finish(result);
this._monitorFile(params.filename);
this._images.push(content);
} catch(e) {
content = null;
}
for (let i = 0; i < this._pendingFileLoads.length; i++) {
let pendingLoad = this._pendingFileLoads[i];
if (pendingLoad.filename != params.filename ||
pendingLoad.style != params.style)
continue;
for (let j = 0; j < pendingLoad.callers.length; j++) {
if (pendingLoad.callers[j].onFinished) {
if (content && pendingLoad.callers[j].shouldCopy) {
content = object.copy(pendingLoad.callers[j].monitorIndex,
pendingLoad.callers[j].effects);
}
pendingLoad.callers[j].onFinished(content);
}
}
this._pendingFileLoads.splice(i, 1);
}
}));
},
getImageContent: function(params) {
params = Params.parse(params, { monitorIndex: 0,
style: null,
@ -165,31 +233,19 @@ const BackgroundCache = new Lang.Class({
if (params.cancellable && params.cancellable.is_cancelled())
content = null;
else
this._images.push(content);
if (params.onFinished)
params.onFinished(content);
} else {
content = new Meta.Background({ meta_screen: global.screen,
monitor: params.monitorIndex,
effects: params.effects });
this._loadImageContent({ filename: params.filename,
style: params.style,
effects: params.effects,
monitorIndex: params.monitorIndex,
cancellable: params.cancellable,
onFinished: params.onFinished });
content.load_file_async(params.filename,
params.style,
params.cancellable,
Lang.bind(this,
function(object, result) {
try {
content.load_file_finish(result);
this._monitorFile(params.filename);
this._images.push(content);
} catch(e) {
content = null;
}
if (params.onFinished)
params.onFinished(content);
}));
}
},
@ -267,9 +323,9 @@ const Background = new Lang.Class({
_destroy: function() {
this._cancellable.cancel();
if (this._animationUpdateTimeoutId) {
GLib.source_remove (this._animationUpdateTimeoutId);
this._animationUpdateTimeoutId = 0
if (this._updateAnimationTimeoutId) {
GLib.source_remove (this._updateAnimationTimeoutId);
this._updateAnimationTimeoutId = 0;
}
let i;
@ -356,7 +412,10 @@ const Background = new Lang.Class({
let actor = new Meta.BackgroundActor();
actor.content = content;
this.actor.add_child(actor);
// The background pattern is the first actor in
// the group, and all images should be above that.
this.actor.insert_child_at_index(actor, index + 1);
this._images[index] = actor;
this._watchCacheFile(filename);
@ -367,27 +426,27 @@ const Background = new Lang.Class({
content.brightness = this._brightness;
content.vignette_sharpness = this._vignetteSharpness;
this._cache.removeImageContent(content);
this._images[index].content = content;
this._watchCacheFile(filename);
},
_updateAnimationProgress: function() {
if (this._images[1]) {
this._images[1].raise_top();
if (this._images[1])
this._images[1].opacity = this._animation.transitionProgress * 255;
}
this._queueAnimationUpdate();
this._queueUpdateAnimation();
},
_updateAnimation: function() {
this._animationUpdateTimeoutId = 0;
this._updateAnimationTimeoutId = 0;
let files = this._animation.getKeyFrameFiles(this._layoutManager.monitors[this._monitorIndex]);
this._animation.update(this._layoutManager.monitors[this._monitorIndex]);
let files = this._animation.keyFrameFiles;
if (!files) {
if (files.length == 0) {
this._setLoaded();
this._queueAnimationUpdate();
this._queueUpdateAnimation();
return;
}
@ -406,7 +465,7 @@ const Background = new Lang.Class({
style: this._style,
filename: files[i],
cancellable: this._cancellable,
onFinished: Lang.bind(this, function(content) {
onFinished: Lang.bind(this, function(content, i) {
numPendingImages--;
if (!content) {
@ -426,27 +485,34 @@ const Background = new Lang.Class({
this._setLoaded();
this._updateAnimationProgress();
}
})
}, i)
});
}
},
_queueAnimationUpdate: function() {
if (this._animationUpdateTimeoutId != 0)
_queueUpdateAnimation: function() {
if (this._updateAnimationTimeoutId != 0)
return;
if (!this._cancellable || this._cancellable.is_cancelled())
return;
if (!this._animation.duration)
if (!this._animation.transitionDuration)
return;
let nSteps = 255 / ANIMATION_OPACITY_STEP_INCREMENT;
let timePerStep = (this._animation.transitionDuration * 1000) / nSteps;
let interval = Math.max(ANIMATION_MIN_WAKEUP_INTERVAL * 1000,
ANIMATION_OPACITY_STEP_INCREMENT / this._animation.duration);
this._animationUpdateTimeoutId = GLib.timeout_add(GLib.PRIORITY_DEFAULT,
timePerStep);
if (interval > GLib.MAXUINT32)
return;
this._updateAnimationTimeoutId = GLib.timeout_add(GLib.PRIORITY_DEFAULT,
interval,
Lang.bind(this, function() {
this._animationUpdateTimeoutId = 0;
this._updateAnimationTimeoutId = 0;
this._updateAnimation();
return false;
}));
@ -585,9 +651,9 @@ const Animation = new Lang.Class({
params = Params.parse(params, { filename: null });
this.filename = params.filename;
this._keyFrames = [];
this.duration = 0.0;
this.keyFrameFiles = [];
this.transitionProgress = 0.0;
this.transitionDuration = 0.0;
this.loaded = false;
},
@ -599,33 +665,31 @@ const Animation = new Lang.Class({
this._show.load_async(null,
Lang.bind(this,
function(object, result) {
this.duration = this._show.get_total_duration();
this.loaded = true;
if (callback)
callback();
}));
},
getKeyFrameFiles: function(monitor) {
update: function(monitor) {
this.keyFrameFiles = [];
if (!this._show)
return null;
return;
if (this._show.get_num_slides() < 1)
return null;
return;
let [progress, duration, isFixed, file1, file2] = this._show.get_current_slide(monitor.width, monitor.height);
this.transitionDuration = duration;
this.transitionProgress = progress;
let files = [];
if (file1)
files.push(file1);
this.keyFrameFiles.push(file1);
if (file2)
files.push(file2);
return files;
this.keyFrameFiles.push(file2);
},
});
Signals.addSignalMethods(Animation.prototype);
@ -648,17 +712,9 @@ const BackgroundManager = new Lang.Class({
this.background = this._createBackground();
this._newBackground = null;
this._loadedSignalId = 0;
this._changedSignalId = 0;
},
destroy: function() {
if (this._loadedSignalId)
this._newBackground.disconnect(this._loadedSignalId);
if (this._changedSignalId)
this.background.disconnect(this._changedSignalId);
if (this._newBackground) {
this._newBackground.actor.destroy();
this._newBackground = null;
@ -677,22 +733,24 @@ const BackgroundManager = new Lang.Class({
newBackground.saturation = background.saturation;
newBackground.visible = background.visible;
let signalId = newBackground.connect('loaded',
newBackground.loadedSignalId = newBackground.connect('loaded',
Lang.bind(this, function() {
newBackground.disconnect(signalId);
newBackground.disconnect(newBackground.loadedSignalId);
newBackground.loadedSignalId = 0;
Tweener.addTween(background.actor,
{ opacity: 0,
time: FADE_ANIMATION_TIME,
transition: 'easeOutQuad',
onComplete: Lang.bind(this, function() {
this.background = newBackground;
this._newBackground = null;
background.actor.destroy();
if (this.background == background) {
this.background = newBackground;
this._newBackground = null;
background.actor.destroy();
}
this.emit('changed');
})
});
}));
this._loadedSignalId = signalId;
this._newBackground = newBackground;
},
@ -711,12 +769,19 @@ const BackgroundManager = new Lang.Class({
background.actor.lower_bottom();
}
let signalId = background.connect('changed', Lang.bind(this, function() {
background.disconnect(signalId);
background.changeSignalId = background.connect('changed', Lang.bind(this, function() {
background.disconnect(background.changeSignalId);
background.changeSignalId = 0;
this._updateBackground(background, this._monitorIndex);
}));
this._changedSignalId = signalId;
background.actor.connect('destroy', Lang.bind(this, function() {
if (background.changeSignalId)
background.disconnect(background.changeSignalId);
if (background.loadedSignalId)
background.disconnect(background.loadedSignalId);
}));
return background;
},

View File

@ -55,4 +55,10 @@ function addBackgroundMenu(actor) {
openMenu();
});
actor.add_action(clickAction);
actor.connect('destroy', function() {
actor._backgroundMenu.destroy();
actor._backgroundMenu = null;
actor._backgroundManager = null;
});
}

View File

@ -71,7 +71,7 @@ function _formatEventTime(event, clockFormat) {
default:
/* explicit fall-through */
case '12h':
/* Transators: Shown in calendar event list, if 12h format,
/* Translators: Shown in calendar event list, if 12h format,
\u2236 is a ratio character, similar to : and \u2009 is
a thin space */
ret = event.date.toLocaleFormat(C_("event list time", "%l\u2236%M\u2009%p"));
@ -168,6 +168,12 @@ const EmptyEventSource = new Lang.Class({
Name: 'EmptyEventSource',
_init: function() {
this.isLoading = false;
this.isDummy = true;
this.hasCalendars = false;
},
destroy: function() {
},
requestRange: function(begin, end) {
@ -191,6 +197,7 @@ const CalendarServerIface = <interface name="org.gnome.Shell.CalendarServer">
<arg type="b" direction="in" />
<arg type="a(sssbxxa{sv})" direction="out" />
</method>
<property name="HasCalendars" type="b" access="read" />
<signal name="Changed" />
</interface>;
@ -201,8 +208,7 @@ function CalendarServer() {
g_interface_name: CalendarServerInfo.name,
g_interface_info: CalendarServerInfo,
g_name: 'org.gnome.Shell.CalendarServer',
g_object_path: '/org/gnome/Shell/CalendarServer',
g_flags: Gio.DBusProxyFlags.DO_NOT_LOAD_PROPERTIES });
g_object_path: '/org/gnome/Shell/CalendarServer' });
}
function _datesEqual(a, b) {
@ -229,6 +235,8 @@ const DBusEventSource = new Lang.Class({
_init: function() {
this._resetCache();
this.isLoading = false;
this.isDummy = false;
this._initialized = false;
this._dbusProxy = new CalendarServer();
@ -249,11 +257,27 @@ const DBusEventSource = new Lang.Class({
this._onNameVanished();
}));
this._dbusProxy.connect('g-properties-changed', Lang.bind(this, function() {
this.emit('notify::has-calendars');
}));
this._initialized = true;
this.emit('notify::has-calendars');
this._onNameAppeared();
}));
},
destroy: function() {
this._dbusProxy.run_dispose();
},
get hasCalendars() {
if (this._initialized)
return this._dbusProxy.HasCalendars;
else
return false;
},
_resetCache: function() {
this._events = [];
this._lastRequestBegin = null;
@ -293,6 +317,7 @@ const DBusEventSource = new Lang.Class({
}
this._events = newEvents;
this.isLoading = false;
this.emit('changed');
},
@ -315,6 +340,7 @@ const DBusEventSource = new Lang.Class({
requestRange: function(begin, end, forceReload) {
if (forceReload || !(_datesEqual(begin, this._lastRequestBegin) && _datesEqual(end, this._lastRequestEnd))) {
this.isLoading = true;
this._lastRequestBegin = begin;
this._lastRequestEnd = end;
this._curRequestBegin = begin;
@ -389,19 +415,11 @@ const Calendar = new Lang.Class({
// @eventSource: is an object implementing the EventSource API, e.g. the
// requestRange(), getEvents(), hasEvents() methods and the ::changed signal.
setEventSource: function(eventSource) {
if (this._eventSource) {
this._eventSource.disconnect(this._eventSourceChangedId);
this._eventSource = null;
}
this._eventSource = eventSource;
if (this._eventSource) {
this._eventSourceChangedId = this._eventSource.connect('changed', Lang.bind(this, function() {
this._update(false);
}));
this._update(true);
}
this._eventSource.connect('changed', Lang.bind(this, function() {
this._update(false);
}));
this._update(true);
},
// Sets the calendar to show a specific date
@ -538,20 +556,44 @@ const Calendar = new Lang.Class({
children[i].destroy();
// Start at the beginning of the week before the start of the month
//
// We want to show always 6 weeks (to keep the calendar menu at the same
// height if there are no events), so we pad it according to the following
// policy:
//
// 1 - If a month has 6 weeks, we place no padding (example: Dec 2012)
// 2 - If a month has 5 weeks and it starts on week start, we pad one week
// before it (example: Apr 2012)
// 3 - If a month has 5 weeks and it starts on any other day, we pad one week
// after it (example: Nov 2012)
// 4 - If a month has 4 weeks, we pad one week before and one after it
// (example: Feb 2010)
//
// Actually computing the number of weeks is complex, but we know that the
// problematic categories (2 and 4) always start on week start, and that
// all months at the end have 6 weeks.
let beginDate = new Date(this._selectedDate);
beginDate.setDate(1);
beginDate.setSeconds(0);
beginDate.setHours(12);
let year = beginDate.getYear();
let daysToWeekStart = (7 + beginDate.getDay() - this._weekStart) % 7;
beginDate.setTime(beginDate.getTime() - daysToWeekStart * MSECS_IN_DAY);
let startsOnWeekStart = daysToWeekStart == 0;
let weekPadding = startsOnWeekStart ? 7 : 0;
beginDate.setTime(beginDate.getTime() - (weekPadding + daysToWeekStart) * MSECS_IN_DAY);
let iter = new Date(beginDate);
let row = 2;
while (true) {
// nRows here means 6 weeks + one header + one navbar
let nRows = 8;
while (row < 8) {
let button = new St.Button({ label: iter.getDate().toString() });
let rtl = button.get_text_direction() == Clutter.TextDirection.RTL;
if (!this._eventSource)
if (this._eventSource.isDummy)
button.reactive = false;
let iterStr = iter.toUTCString();
@ -560,8 +602,9 @@ const Calendar = new Lang.Class({
this.setDate(newlySelectedDate, false);
}));
let hasEvents = this._eventSource && this._eventSource.hasEvents(iter);
let hasEvents = this._eventSource.hasEvents(iter);
let styleClass = 'calendar-day-base calendar-day';
if (_isWorkDay(iter))
styleClass += ' calendar-work-day'
else
@ -601,17 +644,13 @@ const Calendar = new Lang.Class({
}
iter.setTime(iter.getTime() + MSECS_IN_DAY);
if (iter.getDay() == this._weekStart) {
// We stop on the first "first day of the week" after the month we are displaying
if (iter.getMonth() > this._selectedDate.getMonth() || iter.getYear() > this._selectedDate.getYear())
break;
if (iter.getDay() == this._weekStart)
row++;
}
}
// Signal to the event source that we are interested in events
// only from this date range
if (this._eventSource)
this._eventSource.requestRange(beginDate, iter, forceReload);
this._eventSource.requestRange(beginDate, iter, forceReload);
}
});
@ -629,16 +668,8 @@ const EventsList = new Lang.Class({
},
setEventSource: function(eventSource) {
if (this._eventSource) {
this._eventSource.disconnect(this._eventSourceChangedId);
this._eventSource = null;
}
this._eventSource = eventSource;
if (this._eventSource) {
this._eventSourceChangedId = this._eventSource.connect('changed', Lang.bind(this, this._update));
}
this._eventSource.connect('changed', Lang.bind(this, this._update));
},
_addEvent: function(dayNameBox, timeBox, eventTitleBox, includeDayName, day, time, desc) {
@ -655,9 +686,6 @@ const EventsList = new Lang.Class({
},
_addPeriod: function(header, begin, end, includeDayName, showNothingScheduled) {
if (!this._eventSource)
return;
let events = this._eventSource.getEvents(begin, end);
let clockFormat = this._desktopSettings.get_string(CLOCK_FORMAT_KEY);;
@ -754,6 +782,9 @@ const EventsList = new Lang.Class({
},
_update: function() {
if (this._eventSource.isLoading)
return;
let today = new Date();
if (_sameDay (this._date, today)) {
this._showToday();

View File

@ -292,6 +292,7 @@ const AutorunResidentSource = new Lang.Class({
_init: function(manager) {
this.parent(_("Removable Devices"), 'media-removable');
this.resident = true;
this._mounts = [];

View File

@ -222,7 +222,7 @@ const KeyringPrompter = new Lang.Class({
enable: function() {
this._prompter.register(Gio.DBus.session);
this._dbusId = Gio.DBus.session.own_name('org.gnome.keyring.SystemPrompter',
Gio.BusNameOwnerFlags.REPLACE, null, null);
Gio.BusNameOwnerFlags.ALLOW_REPLACEMENT, null, null);
},
disable: function() {

View File

@ -103,6 +103,11 @@ const CtrlAltTabManager = new Lang.Class({
else
icon = textureCache.bind_pixbuf_property(windows[i], 'icon');
items.push({ name: windows[i].title,
proxy: windows[i].get_compositor_private(),
focusCallback: Lang.bind(windows[i],
function(timestamp) {
Main.activateWindow(this, timestamp);
}),
iconActor: icon,
sortGroup: SortGroup.MIDDLE });
}

View File

@ -161,8 +161,10 @@ const DateMenuButton = new Lang.Class({
this._openClocksItem.actor.visible = app !== null;
},
_setEventsVisibility: function(visible) {
_updateEventsVisibility: function() {
let visible = this._eventSource.hasCalendars;
this._openCalendarItem.actor.visible = visible;
this._openClocksItem.actor.visible = visible;
this._separator.visible = visible;
if (visible) {
let alignment = 0.25;
@ -177,8 +179,16 @@ const DateMenuButton = new Lang.Class({
},
_setEventSource: function(eventSource) {
if (this._eventSource)
this._eventSource.destroy();
this._calendar.setEventSource(eventSource);
this._eventList.setEventSource(eventSource);
this._eventSource = eventSource;
this._eventSource.connect('notify::has-calendars', Lang.bind(this, function() {
this._updateEventsVisibility();
}));
},
_sessionUpdated: function() {
@ -187,10 +197,10 @@ const DateMenuButton = new Lang.Class({
if (showEvents) {
eventSource = new Calendar.DBusEventSource();
} else {
eventSource = null;
eventSource = new Calendar.EmptyEventSource();
}
this._setEventSource(eventSource);
this._setEventsVisibility(showEvents);
this._updateEventsVisibility();
// This needs to be handled manually, as the code to
// autohide separators doesn't work across the vbox
@ -211,6 +221,8 @@ const DateMenuButton = new Lang.Class({
this.menu.close();
let app = Gio.AppInfo.get_default_for_type('text/calendar', false);
if (app.get_id() == 'evolution')
app = Gio.DesktopAppInfo.new('evolution-calendar');
app.launch([], global.create_app_launch_context());
},

View File

@ -85,11 +85,13 @@ const _Draggable = new Lang.Class({
this.actor.connect('destroy', Lang.bind(this, function() {
this._actorDestroyed = true;
// If the drag actor is destroyed and we were going to fix
// up its hover state, fix up the parent hover state instead
if (this.actor == this._firstLeaveActor)
this._firstLeaveActor = this._dragOrigParent;
if (this._dragInProgress)
if (this._dragInProgress && this._dragCancellable)
this._cancelDrag(global.get_current_time());
this.disconnectAll();
}));
@ -102,6 +104,7 @@ const _Draggable = new Lang.Class({
this._buttonDown = false; // The mouse button has been pressed and has not yet been released.
this._dragInProgress = false; // The drag has been started, and has not been dropped or cancelled yet.
this._animationInProgress = false; // The drag is over and the item is in the process of animating to its original position (snapping back or reverting).
this._dragCancellable = true;
// During the drag, we eat enter/leave events so that actors don't prelight.
// But we remember the actors that we first left/last entered so we can
@ -439,6 +442,11 @@ const _Draggable = new Lang.Class({
}
}
// At this point it is too late to cancel a drag by destroying
// the actor, the fate of which is decided by acceptDrop and its
// side-effects
this._dragCancellable = false;
while (target) {
if (target._delegate && target._delegate.acceptDrop) {
let [r, targX, targY] = target.transform_stage_point(dropX, dropY);
@ -447,8 +455,6 @@ const _Draggable = new Lang.Class({
targX,
targY,
event.get_time())) {
if (this._actorDestroyed)
return true;
// If it accepted the drop without taking the actor,
// handle it ourselves.
if (this._dragActor.get_parent() == Main.uiGroup) {

View File

@ -225,7 +225,8 @@ const EndSessionDialog = new Lang.Class({
Extends: ModalDialog.ModalDialog,
_init: function() {
this.parent({ styleClass: 'end-session-dialog' });
this.parent({ styleClass: 'end-session-dialog',
destroyOnClose: false });
this._user = AccountsService.UserManager.get_default().get_user(GLib.get_user_name());

View File

@ -248,7 +248,7 @@ const GrabHelper = new Lang.Class({
global.set_stage_input_mode(Shell.StageInputMode.FOCUSED);
}
global.screen.focus_default_window(global.get_current_time());
global.screen.focus_default_window(global.display.get_current_time_roundtrip());
},
// ignoreRelease:
@ -308,6 +308,8 @@ const GrabHelper = new Lang.Class({
if (!this.grabbed && this._capturedEventId > 0) {
global.stage.disconnect(this._capturedEventId);
this._capturedEventId = 0;
this._ignoreRelease = false;
}
if (hadFocus) {
@ -353,6 +355,7 @@ const GrabHelper = new Lang.Class({
this._ignoreRelease = true;
let i = this._actorInGrabStack(event.get_source()) + 1;
this.ungrab({ actor: this._grabStack[i].actor, isUser: true });
return true;
}
return this._modalCount > 0;

View File

@ -18,7 +18,6 @@ const Main = imports.ui.main;
const Params = imports.misc.params;
const Tweener = imports.ui.tweener;
const HOT_CORNER_ACTIVATION_TIMEOUT = 0.5;
const STARTUP_ANIMATION_TIME = 0.5;
const KEYBOARD_ANIMATION_TIME = 0.15;
const BACKGROUND_FADE_ANIMATION_TIME = 1.0;
@ -29,6 +28,9 @@ const DEFAULT_BACKGROUND_COLOR = Clutter.Color.from_pixel(0x2e3436ff);
const MESSAGE_TRAY_PRESSURE_THRESHOLD = 250; // pixels
const MESSAGE_TRAY_PRESSURE_TIMEOUT = 1000; // ms
const HOT_CORNER_PRESSURE_THRESHOLD = 100; // pixels
const HOT_CORNER_PRESSURE_TIMEOUT = 1000; // ms
function isPopupMetaWindow(actor) {
switch(actor.meta_window.get_window_type()) {
case Meta.WindowType.DROPDOWN_MENU:
@ -130,9 +132,9 @@ const LayoutManager = new Lang.Class({
this.monitors = [];
this.primaryMonitor = null;
this.primaryIndex = -1;
this.hotCorners = [];
this._keyboardIndex = -1;
this._hotCorners = [];
this._leftPanelBarrier = null;
this._rightPanelBarrier = null;
this._trayBarrier = null;
@ -140,6 +142,7 @@ const LayoutManager = new Lang.Class({
this._updateRegionIdle = 0;
this._trackedActors = [];
this._topActors = [];
this._isPopupWindowVisible = false;
this._startingUp = true;
@ -191,6 +194,7 @@ const LayoutManager = new Lang.Class({
this.trayBox = new St.Widget({ name: 'trayBox',
layout_manager: new Clutter.BinLayout() });
this.addChrome(this.trayBox);
this._setupTrayPressure();
this.keyboardBox = new St.BoxLayout({ name: 'keyboardBox',
reactive: true,
@ -218,6 +222,8 @@ const LayoutManager = new Lang.Class({
Lang.bind(this, this._windowsRestacked));
global.screen.connect('monitors-changed',
Lang.bind(this, this._monitorsChanged));
global.screen.connect('in-fullscreen-changed',
Lang.bind(this, this._updateFullscreen));
this._monitorsChanged();
},
@ -228,6 +234,8 @@ const LayoutManager = new Lang.Class({
Main.overview.connect('showing', Lang.bind(this, this._overviewShowing));
Main.overview.connect('hidden', Lang.bind(this, this._overviewHidden));
Main.sessionMode.connect('updated', Lang.bind(this, this._sessionUpdated));
this._prepareStartupAnimation();
},
_overviewShowing: function() {
@ -275,56 +283,58 @@ const LayoutManager = new Lang.Class({
_updateHotCorners: function() {
// destroy old hot corners
for (let i = 0; i < this._hotCorners.length; i++)
this._hotCorners[i].destroy();
this._hotCorners = [];
for (let i = 0; i < this.hotCorners.length; i++)
this.hotCorners[i].destroy();
this.hotCorners = [];
let size = this.panelBox.height;
// build new hot corners
for (let i = 0; i < this.monitors.length; i++) {
if (i == this.primaryIndex)
continue;
let monitor = this.monitors[i];
let cornerX = this._rtl ? monitor.x + monitor.width : monitor.x;
let cornerY = monitor.y;
let haveTopLeftCorner = true;
if (i != this.primaryIndex) {
let haveTopLeftCorner = true;
// Check if we have a top left (right for RTL) corner.
// I.e. if there is no monitor directly above or to the left(right)
let besideX = this._rtl ? monitor.x + 1 : cornerX - 1;
let besideY = cornerY;
let aboveX = cornerX;
let aboveY = cornerY - 1;
// Check if we have a top left (right for RTL) corner.
// I.e. if there is no monitor directly above or to the left(right)
let besideX = this._rtl ? monitor.x + 1 : cornerX - 1;
let besideY = cornerY;
let aboveX = cornerX;
let aboveY = cornerY - 1;
for (let j = 0; j < this.monitors.length; j++) {
if (i == j)
for (let j = 0; j < this.monitors.length; j++) {
if (i == j)
continue;
let otherMonitor = this.monitors[j];
if (besideX >= otherMonitor.x &&
besideX < otherMonitor.x + otherMonitor.width &&
besideY >= otherMonitor.y &&
besideY < otherMonitor.y + otherMonitor.height) {
haveTopLeftCorner = false;
break;
}
if (aboveX >= otherMonitor.x &&
aboveX < otherMonitor.x + otherMonitor.width &&
aboveY >= otherMonitor.y &&
aboveY < otherMonitor.y + otherMonitor.height) {
haveTopLeftCorner = false;
break;
}
}
if (!haveTopLeftCorner)
continue;
let otherMonitor = this.monitors[j];
if (besideX >= otherMonitor.x &&
besideX < otherMonitor.x + otherMonitor.width &&
besideY >= otherMonitor.y &&
besideY < otherMonitor.y + otherMonitor.height) {
haveTopLeftCorner = false;
break;
}
if (aboveX >= otherMonitor.x &&
aboveX < otherMonitor.x + otherMonitor.width &&
aboveY >= otherMonitor.y &&
aboveY < otherMonitor.y + otherMonitor.height) {
haveTopLeftCorner = false;
break;
}
}
if (!haveTopLeftCorner)
continue;
let corner = new HotCorner(this);
this._hotCorners.push(corner);
corner.actor.set_position(cornerX, cornerY);
this.addChrome(corner.actor);
let corner = new HotCorner(this, monitor, cornerX, cornerY);
corner.setBarrierSize(size);
this.hotCorners.push(corner);
}
this.emit('hot-corners-changed');
},
_createBackground: function(monitorIndex) {
@ -394,16 +404,15 @@ const LayoutManager = new Lang.Class({
},
_panelBoxChanged: function() {
this.emit('panel-box-changed');
this._updatePanelBarriers();
this._updatePanelBarrier();
let size = this.panelBox.height;
this.hotCorners.forEach(function(corner) {
corner.setBarrierSize(size);
});
},
_updatePanelBarriers: function() {
if (this._leftPanelBarrier) {
this._leftPanelBarrier.destroy();
this._leftPanelBarrier = null;
}
_updatePanelBarrier: function() {
if (this._rightPanelBarrier) {
this._rightPanelBarrier.destroy();
this._rightPanelBarrier = null;
@ -412,10 +421,6 @@ const LayoutManager = new Lang.Class({
if (this.panelBox.height) {
let primary = this.primaryMonitor;
this._leftPanelBarrier = new Meta.Barrier({ display: global.display,
x1: primary.x, y1: primary.y,
x2: primary.x, y2: primary.y + this.panelBox.height,
directions: Meta.BarrierDirection.POSITIVE_X });
this._rightPanelBarrier = new Meta.Barrier({ display: global.display,
x1: primary.x + primary.width, y1: primary.y,
x2: primary.x + primary.width, y2: primary.y + this.panelBox.height,
@ -423,28 +428,44 @@ const LayoutManager = new Lang.Class({
}
},
_setupTrayPressure: function() {
this._trayPressure = new PressureBarrier(MESSAGE_TRAY_PRESSURE_THRESHOLD,
MESSAGE_TRAY_PRESSURE_TIMEOUT,
Shell.KeyBindingMode.NORMAL |
Shell.KeyBindingMode.OVERVIEW);
this._trayPressure.setEventFilter(this._trayBarrierEventFilter);
this._trayPressure.connect('trigger', function(barrier) {
if (Main.layoutManager.bottomMonitor.inFullscreen)
return;
Main.messageTray.openTray();
});
},
_updateTrayBarrier: function() {
let monitor = this.bottomMonitor;
if (this._trayBarrier) {
this._trayPressure.removeBarrier(this._trayBarrier);
this._trayBarrier.destroy();
this._trayBarrier = null;
}
if (this._trayPressure) {
this._trayPressure.destroy();
this._trayPressure = null;
}
this._trayBarrier = new Meta.Barrier({ display: global.display,
x1: monitor.x, x2: monitor.x + monitor.width,
y1: monitor.y + monitor.height, y2: monitor.y + monitor.height,
directions: Meta.BarrierDirection.NEGATIVE_Y });
this._trayPressure.addBarrier(this._trayBarrier);
},
this._trayPressure = new PressureBarrier(this._trayBarrier, MESSAGE_TRAY_PRESSURE_THRESHOLD, MESSAGE_TRAY_PRESSURE_TIMEOUT);
this._trayPressure.connect('trigger', function(barrier) {
Main.messageTray.openTray();
});
_trayBarrierEventFilter: function(event) {
// Throw out all events where the pointer was grabbed by another
// client, as the client that grabbed the pointer expects to have
// complete control over it
if (event.grabbed && Main.modalCount == 0)
return true;
return false;
},
_monitorsChanged: function() {
@ -534,7 +555,7 @@ const LayoutManager = new Lang.Class({
// MetaBackgroundActor inside global.window_group covers the entirety of the
// screen. So, we set no_clear_hint at the end of the animation.
prepareStartupAnimation: function() {
_prepareStartupAnimation: function() {
// Set ourselves to FULLSCREEN input mode while the animation is running
// so events don't get delivered to X11 windows (which are distorted by the animation)
global.stage_input_mode = Shell.StageInputMode.FULLSCREEN;
@ -557,6 +578,7 @@ const LayoutManager = new Lang.Class({
y / global.screen_height);
this.uiGroup.scale_x = this.uiGroup.scale_y = 0.5;
this.uiGroup.opacity = 0;
global.window_group.set_clip(monitor.x, monitor.y, monitor.width, monitor.height);
}
this._systemBackground = new Background.SystemBackground();
@ -572,25 +594,25 @@ const LayoutManager = new Lang.Class({
Lang.bind(this, function() {
this._systemBackground.disconnect(signalId);
this._systemBackground.actor.show();
global.stage.show();
this.emit('startup-prepared');
// We're mostly prepared for the startup animation
// now, but since a lot is going on asynchronously
// during startup, let's defer emission of the
// startup-prepared signal until the event loop is
// uncontended and idle. This helps to prevent us
// from running the animation when the system is
// bogged down
// during startup, let's defer the startup animation
// until the event loop is uncontended and idle.
// This helps to prevent us from running the animation
// when the system is bogged down
GLib.idle_add(GLib.PRIORITY_LOW,
Lang.bind(this, function() {
this.emit('startup-prepared');
return false;
}));
this._startupAnimation();
return false;
}));
}));
},
startupAnimation: function() {
global.stage.show();
_startupAnimation: function() {
if (Main.sessionMode.isGreeter)
this._startupAnimationGreeter();
else
@ -633,12 +655,14 @@ const LayoutManager = new Lang.Class({
this.trayBox.show();
this.keyboardBox.show();
if (!Main.sessionMode.isGreeter)
if (!Main.sessionMode.isGreeter) {
this._createSecondaryBackgrounds();
this.emit('panel-box-changed');
global.window_group.remove_clip();
}
this._queueUpdateRegions();
this.emit('startup-complete');
},
showKeyboard: function () {
@ -814,6 +838,11 @@ const LayoutManager = new Lang.Class({
},
_updateVisibility: function() {
let windowsVisible = Main.sessionMode.hasWindows && !this._inOverview;
global.window_group.visible = windowsVisible;
global.top_window_group.visible = windowsVisible;
for (let i = 0; i < this._trackedActors.length; i++) {
let actorData = this._trackedActors[i], visible;
if (!actorData.trackFullscreen)
@ -821,7 +850,7 @@ const LayoutManager = new Lang.Class({
if (!actorData.isToplevel)
continue;
if (this._inOverview || !Main.sessionMode.hasWindows)
if (!windowsVisible)
visible = true;
else if (this.findMonitorForActor(actorData.actor).inFullscreen)
visible = false;
@ -871,95 +900,25 @@ const LayoutManager = new Lang.Class({
},
_updateFullscreen: function() {
let windows = this._getWindowActorsForWorkspace(global.screen.get_active_workspace());
// Reset all monitors to not fullscreen
for (let i = 0; i < this.monitors.length; i++)
this.monitors[i].inFullscreen = false;
this.monitors[i].inFullscreen = global.screen.get_monitor_in_fullscreen (i);
// Ordinary chrome should be visible unless there is a window
// with layer FULLSCREEN, or a window with layer
// OVERRIDE_REDIRECT that covers the whole screen.
// ('override_redirect' is not actually a layer above all
// other windows, but this seems to be how mutter treats it
// currently...) If we wanted to be extra clever, we could
// figure out when an OVERRIDE_REDIRECT window was trying to
// partially overlap us, and then adjust the input region and
// our clip region accordingly...
this._updateVisibility();
this._queueUpdateRegions();
// @windows is sorted bottom to top.
for (let i = windows.length - 1; i > -1; i--) {
let window = windows[i];
let metaWindow = window.meta_window;
let layer = metaWindow.get_layer();
// Skip minimized windows
if (!metaWindow.showing_on_its_workspace())
continue;
if (layer == Meta.StackLayer.FULLSCREEN ||
(layer == Meta.StackLayer.OVERRIDE_REDIRECT && metaWindow.is_monitor_sized())) {
if (metaWindow.is_screen_sized()) {
for (let i = 0; i < this.monitors.length; i++)
this.monitors[i].inFullscreen = true;
} else {
let monitors = metaWindow.get_all_monitors();
for (let i = 0; i < monitors.length; i++) {
let index = monitors[i];
this.monitors[index].inFullscreen = true;
}
}
}
}
this.emit('fullscreen-changed');
},
_windowsRestacked: function() {
let wasInFullscreen = [];
for (let i = 0; i < this.monitors.length; i++)
wasInFullscreen[i] = this.monitors[i].inFullscreen;
let primaryWasInFullscreen = this.primaryMonitor.inFullscreen;
this._updateFullscreen();
let changed = false;
for (let i = 0; i < wasInFullscreen.length; i++) {
if (wasInFullscreen[i] != this.monitors[i].inFullscreen) {
changed = true;
break;
}
}
if (!changed && (this._isPopupWindowVisible != global.top_window_group.get_children().some(isPopupMetaWindow)))
if (this._isPopupWindowVisible != global.top_window_group.get_children().some(isPopupMetaWindow))
changed = true;
if (changed) {
this._updateVisibility();
this._queueUpdateRegions();
}
if (primaryWasInFullscreen != this.primaryMonitor.inFullscreen) {
let windows = this._getWindowActorsForWorkspace(global.screen.get_active_workspace());
for (let i = 0; i < windows.length; i++) {
let window = windows[i];
let metaWindow = window.meta_window;
// Skip minimized windows
if (!metaWindow.showing_on_its_workspace())
continue;
// Skip windows that aren't on the primary monitor
if (!metaWindow.is_on_primary_monitor())
continue;
// Minimize monitor sized windows that are not focused
if (metaWindow.is_monitor_sized() &&
!metaWindow.appears_focused)
metaWindow.minimize();
}
this.emit('primary-fullscreen-changed', this.primaryMonitor.inFullscreen);
}
},
_updateRegions: function() {
@ -1089,54 +1048,25 @@ Signals.addSignalMethods(LayoutManager.prototype);
const HotCorner = new Lang.Class({
Name: 'HotCorner',
_init : function(layoutManager) {
_init : function(layoutManager, monitor, x, y) {
// We use this flag to mark the case where the user has entered the
// hot corner and has not left both the hot corner and a surrounding
// guard area (the "environs"). This avoids triggering the hot corner
// multiple times due to an accidental jitter.
this._entered = false;
this.actor = new Clutter.Actor({ name: 'hot-corner-environs',
width: 3,
height: 3,
reactive: true });
this._monitor = monitor;
this._corner = new Clutter.Rectangle({ name: 'hot-corner',
width: 1,
height: 1,
opacity: 0,
reactive: true });
this._corner._delegate = this;
this._x = x;
this._y = y;
this.actor.add_child(this._corner);
this._setupFallbackCornerIfNeeded(layoutManager);
if (Clutter.get_default_text_direction() == Clutter.TextDirection.RTL) {
this._corner.set_position(this.actor.width - this._corner.width, 0);
this.actor.set_anchor_point_from_gravity(Clutter.Gravity.NORTH_EAST);
} else {
this._corner.set_position(0, 0);
}
this._activationTime = 0;
this.actor.connect('leave-event',
Lang.bind(this, this._onEnvironsLeft));
// Clicking on the hot corner environs should result in the
// same behavior as clicking on the hot corner.
this.actor.connect('button-release-event',
Lang.bind(this, this._onCornerClicked));
// In addition to being triggered by the mouse enter event,
// the hot corner can be triggered by clicking on it. This is
// useful if the user wants to undo the effect of triggering
// the hot corner once in the hot corner.
this._corner.connect('enter-event',
Lang.bind(this, this._onCornerEntered));
this._corner.connect('button-release-event',
Lang.bind(this, this._onCornerClicked));
this._corner.connect('leave-event',
Lang.bind(this, this._onCornerLeft));
this._pressureBarrier = new PressureBarrier(HOT_CORNER_PRESSURE_THRESHOLD,
HOT_CORNER_PRESSURE_TIMEOUT,
Shell.KeyBindingMode.NORMAL |
Shell.KeyBindingMode.OVERVIEW);
this._pressureBarrier.connect('trigger', Lang.bind(this, this._toggleOverview));
// Cache the three ripples instead of dynamically creating and destroying them.
this._ripple1 = new St.BoxLayout({ style_class: 'ripple-box', opacity: 0, visible: false });
@ -1148,8 +1078,74 @@ const HotCorner = new Lang.Class({
layoutManager.uiGroup.add_actor(this._ripple3);
},
setBarrierSize: function(size) {
if (this._verticalBarrier) {
this._pressureBarrier.removeBarrier(this._verticalBarrier);
this._verticalBarrier.destroy();
this._verticalBarrier = null;
}
if (this._horizontalBarrier) {
this._pressureBarrier.removeBarrier(this._horizontalBarrier);
this._horizontalBarrier.destroy();
this._horizontalBarrier = null;
}
if (size > 0) {
this._verticalBarrier = new Meta.Barrier({ display: global.display,
x1: this._x, x2: this._x, y1: this._y, y2: this._y + size,
directions: Meta.BarrierDirection.POSITIVE_X });
this._horizontalBarrier = new Meta.Barrier({ display: global.display,
x1: this._x, x2: this._x + size, y1: this._y, y2: this._y,
directions: Meta.BarrierDirection.POSITIVE_Y });
this._pressureBarrier.addBarrier(this._verticalBarrier);
this._pressureBarrier.addBarrier(this._horizontalBarrier);
}
},
_setupFallbackCornerIfNeeded: function(layoutManager) {
if (!global.display.supports_extended_barriers()) {
this.actor = new Clutter.Actor({ name: 'hot-corner-environs',
x: this._x, y: this._y,
width: 3,
height: 3,
reactive: true });
this._corner = new Clutter.Rectangle({ name: 'hot-corner',
width: 1,
height: 1,
opacity: 0,
reactive: true });
this._corner._delegate = this;
this.actor.add_child(this._corner);
layoutManager.addChrome(this.actor);
if (Clutter.get_default_text_direction() == Clutter.TextDirection.RTL) {
this._corner.set_position(this.actor.width - this._corner.width, 0);
this.actor.set_anchor_point_from_gravity(Clutter.Gravity.NORTH_EAST);
} else {
this._corner.set_position(0, 0);
}
this.actor.connect('leave-event',
Lang.bind(this, this._onEnvironsLeft));
this._corner.connect('enter-event',
Lang.bind(this, this._onCornerEntered));
this._corner.connect('leave-event',
Lang.bind(this, this._onCornerLeft));
}
},
destroy: function() {
this.actor.destroy();
this.setBarrierSize(0);
this._pressureBarrier.destroy();
this._pressureBarrier = null;
if (this.actor)
this.actor.destroy();
},
_animRipple : function(ripple, delay, time, startScale, startOpacity, finalScale) {
@ -1169,9 +1165,8 @@ const HotCorner = new Lang.Class({
ripple.opacity = 255 * Math.sqrt(startOpacity);
ripple.scale_x = ripple.scale_y = startScale;
let [x, y] = this._corner.get_transformed_position();
ripple.x = x;
ripple.y = y;
ripple.x = this._x;
ripple.y = this._y;
Tweener.addTween(ripple, { _opacity: 0,
scale_x: finalScale,
@ -1183,7 +1178,7 @@ const HotCorner = new Lang.Class({
onComplete: function() { ripple.visible = false; } });
},
rippleAnimation: function() {
_rippleAnimation: function() {
// Show three concentric ripples expanding outwards; the exact
// parameters were found by trial and error, so don't look
// for them to make perfect sense mathematically
@ -1194,14 +1189,21 @@ const HotCorner = new Lang.Class({
this._animRipple(this._ripple3, 0.35, 1.0, 0.0, 0.3, 1);
},
_toggleOverview: function() {
if (this._monitor.inFullscreen)
return;
if (Main.overview.shouldToggleByCornerOrButton()) {
this._rippleAnimation();
Main.overview.toggle();
}
},
handleDragOver: function(source, actor, x, y, time) {
if (source != Main.xdndHandler)
return DND.DragMotionResult.CONTINUE;
if (!Main.overview.visible && !Main.overview.animationInProgress) {
this.rippleAnimation();
Main.overview.showTemporarily();
}
this._toggleOverview();
return DND.DragMotionResult.CONTINUE;
},
@ -1209,22 +1211,11 @@ const HotCorner = new Lang.Class({
_onCornerEntered : function() {
if (!this._entered) {
this._entered = true;
if (!Main.overview.animationInProgress) {
this._activationTime = Date.now() / 1000;
this.rippleAnimation();
Main.overview.toggle();
}
this._toggleOverview();
}
return false;
},
_onCornerClicked : function() {
if (this.shouldToggleOverviewOnClick())
Main.overview.toggle();
return true;
},
_onCornerLeft : function(actor, event) {
if (event.get_related() != this.actor)
this._entered = false;
@ -1236,42 +1227,47 @@ const HotCorner = new Lang.Class({
if (event.get_related() != this._corner)
this._entered = false;
return false;
},
// Checks if the Activities button is currently sensitive to
// clicks. The first call to this function within the
// HOT_CORNER_ACTIVATION_TIMEOUT time of the hot corner being
// triggered will return false. This avoids opening and closing
// the overview if the user both triggered the hot corner and
// clicked the Activities button.
shouldToggleOverviewOnClick: function() {
if (Main.overview.animationInProgress)
return false;
if (this._activationTime == 0 || Date.now() / 1000 - this._activationTime > HOT_CORNER_ACTIVATION_TIMEOUT)
return true;
return false;
}
});
const PressureBarrier = new Lang.Class({
Name: 'PressureBarrier',
_init: function(barrier, threshold, timeout) {
this._barrier = barrier;
_init: function(threshold, timeout, keybindingMode) {
this._threshold = threshold;
this._timeout = timeout;
this._orientation = (barrier.y1 == barrier.y2) ? Clutter.Orientation.HORIZONTAL : Clutter.Orientation.VERTICAL;
this._keybindingMode = keybindingMode;
this._barriers = [];
this._eventFilter = null;
this._isTriggered = false;
this._reset();
},
this._barrierHitId = this._barrier.connect('hit', Lang.bind(this, this._onBarrierHit));
this._barrierLeftId = this._barrier.connect('left', Lang.bind(this, this._onBarrierLeft));
addBarrier: function(barrier) {
barrier._pressureHitId = barrier.connect('hit', Lang.bind(this, this._onBarrierHit));
barrier._pressureLeftId = barrier.connect('left', Lang.bind(this, this._onBarrierLeft));
this._barriers.push(barrier);
},
_disconnectBarrier: function(barrier) {
barrier.disconnect(barrier._pressureHitId);
barrier.disconnect(barrier._pressureLeftId);
},
removeBarrier: function(barrier) {
this._disconnectBarrier(barrier);
this._barriers.splice(this._barriers.indexOf(barrier), 1);
},
destroy: function() {
this._barrier.disconnect(this._barrierHitId);
this._barrier.disconnect(this._barrierLeftId);
this._barrier = null;
this._barriers.forEach(Lang.bind(this, this._disconnectBarrier));
this._barriers = [];
},
setEventFilter: function(filter) {
this._eventFilter = filter;
},
_reset: function() {
@ -1280,33 +1276,34 @@ const PressureBarrier = new Lang.Class({
this._lastTime = 0;
},
_getDistanceAcrossBarrier: function(event) {
if (this._orientation == Clutter.Orientation.HORIZONTAL)
_isHorizontal: function(barrier) {
return barrier.y1 == barrier.y2;
},
_getDistanceAcrossBarrier: function(barrier, event) {
if (this._isHorizontal(barrier))
return Math.abs(event.dy);
else
return Math.abs(event.dx);
},
_getDistanceAlongBarrier: function(event) {
if (this._orientation == Clutter.Orientation.HORIZONTAL)
_getDistanceAlongBarrier: function(barrier, event) {
if (this._isHorizontal(barrier))
return Math.abs(event.dx);
else
return Math.abs(event.dy);
},
_isBarrierEventTooOld: function(event) {
// Ignore all events older than this time
let threshold = this._lastTime - this._timeout;
return event.time < threshold;
},
_trimBarrierEvents: function() {
// Events are guaranteed to be sorted in time order from
// oldest to newest, so just look for the first old event,
// and then chop events after that off.
let i = 0;
let threshold = this._lastTime - this._timeout;
while (i < this._barrierEvents.length) {
if (!this._isBarrierEventTooOld(this._barrierEvents[i]))
let [time, distance] = this._barrierEvents[i];
if (time >= threshold)
break;
i++;
}
@ -1314,7 +1311,8 @@ const PressureBarrier = new Lang.Class({
let firstNewEvent = i;
for (i = 0; i < firstNewEvent; i++) {
this._currentPressure -= this._getDistanceAcrossBarrier(this._barrierEvents[i]);
let [time, distance] = this._barrierEvents[i];
this._currentPressure -= distance;
}
this._barrierEvents = this._barrierEvents.slice(firstNewEvent);
@ -1322,29 +1320,30 @@ const PressureBarrier = new Lang.Class({
_onBarrierLeft: function(barrier, event) {
this._reset();
this._isTriggered = false;
},
_trigger: function() {
this._isTriggered = true;
this.emit('trigger');
this._reset();
},
_onBarrierHit: function(barrier, event) {
// Throw out all events where the pointer was grabbed by another
// client, as the client that grabbed the pointer expects to have
// complete control over it
if (event.grabbed && Main.modalCount == 0)
// If we've triggered the barrier, wait until the pointer has the
// left the barrier hitbox until we trigger it again.
if (this._isTriggered)
return;
let isOverview = ((Main.keybindingMode & (Shell.KeyBindingMode.OVERVIEW)) != 0);
// Throw out events where the grab is taken by something that's
// not the overview (modal dialogs, etc.)
if (event.grabbed && !isOverview)
if (this._eventFilter && this._eventFilter(event))
return;
let slide = this._getDistanceAlongBarrier(event);
let distance = this._getDistanceAcrossBarrier(event);
// Throw out all events not in the proper keybinding mode
if (!(this._keybindingMode & Main.keybindingMode))
return;
let slide = this._getDistanceAlongBarrier(barrier, event);
let distance = this._getDistanceAcrossBarrier(barrier, event);
if (distance >= this._threshold) {
this._trigger();
@ -1360,8 +1359,10 @@ const PressureBarrier = new Lang.Class({
this._lastTime = event.time;
this._trimBarrierEvents();
this._barrierEvents.push(event);
this._currentPressure += Math.min(15, distance);
distance = Math.min(15, distance);
this._barrierEvents.push([event.time, distance]);
this._currentPressure += distance;
if (this._currentPressure >= this._threshold)
this._trigger();

View File

@ -24,6 +24,7 @@ const Panel = imports.ui.panel;
const Params = imports.misc.params;
const RunDialog = imports.ui.runDialog;
const Layout = imports.ui.layout;
const LoginManager = imports.misc.loginManager;
const LookingGlass = imports.ui.lookingGlass;
const NotificationDaemon = imports.ui.notificationDaemon;
const WindowAttentionHandler = imports.ui.windowAttentionHandler;
@ -32,7 +33,6 @@ const Scripting = imports.ui.scripting;
const SessionMode = imports.ui.sessionMode;
const ShellDBus = imports.ui.shellDBus;
const ShellMountOperation = imports.ui.shellMountOperation;
const UnlockDialog = imports.ui.unlockDialog;
const WindowManager = imports.ui.windowManager;
const Magnifier = imports.ui.magnifier;
const XdndHandler = imports.ui.xdndHandler;
@ -58,7 +58,7 @@ let shellDBusService = null;
let shellMountOpDBusService = null;
let screenSaverDBus = null;
let modalCount = 0;
let keybindingMode = Shell.KeyBindingMode.NORMAL;
let keybindingMode = Shell.KeyBindingMode.NONE;
let modalActorFocusStack = [];
let uiGroup = null;
let magnifier = null;
@ -71,6 +71,8 @@ let _cssStylesheet = null;
let _overridesSettings = null;
function _sessionUpdated() {
_loadDefaultStylesheet();
wm.setCustomKeybindingHandler('panel-main-menu',
Shell.KeyBindingMode.NORMAL |
Shell.KeyBindingMode.OVERVIEW,
@ -82,8 +84,9 @@ function _sessionUpdated() {
Shell.KeyBindingMode.NORMAL |
Shell.KeyBindingMode.OVERVIEW,
sessionMode.hasRunDialog ? openRunDialog : null);
if (sessionMode.isGreeter)
screenShield.showDialog();
if (!sessionMode.hasRunDialog && lookingGlass)
lookingGlass.close();
}
function start() {
@ -91,29 +94,27 @@ function start() {
global.logError = window.log;
global.log = window.log;
// Hide the stage until we're ready for it
global.stage.hide();
// Chain up async errors reported from C
global.connect('notify-error', function (global, msg, detail) { notifyError(msg, detail); });
Gio.DesktopAppInfo.set_desktop_env('GNOME');
sessionMode = new SessionMode.SessionMode();
// start session after we know what mode we're running in
let signalId = sessionMode.connect('updated', function() {
sessionMode.disconnect(signalId);
startSession();
});
sessionMode.connect('sessions-loaded', _sessionsLoaded);
sessionMode.init();
}
function startSession() {
sessionMode.connect('updated', _loadDefaultStylesheet);
function _sessionsLoaded() {
sessionMode.connect('updated', _sessionUpdated);
_initializeUI();
shellDBusService = new ShellDBus.GnomeShell();
shellMountOpDBusService = new ShellMountOperation.GnomeShellMountOpHandler();
_sessionUpdated();
}
function _initializeUI() {
// Ensure ShellWindowTracker and ShellAppUsage are initialized; this will
// also initialize ShellAppSystem first. ShellAppSystem
// needs to load all the .desktop files, and ShellWindowTracker
@ -143,13 +144,9 @@ function startSession() {
overview = new Overview.Overview();
wm = new WindowManager.WindowManager();
magnifier = new Magnifier.Magnifier();
if (UnlockDialog.isSupported())
if (LoginManager.canLock())
screenShield = new ScreenShield.ScreenShield();
else
screenShield = new ScreenShield.ScreenShieldFallback();
// The message tray relies on being constructed
// after the panel.
panel = new Panel.Panel();
messageTray = new MessageTray.MessageTray();
keyboard = new Keyboard.Keyboard();
@ -158,14 +155,11 @@ function startSession() {
componentManager = new Components.ComponentManager();
layoutManager.init();
layoutManager.prepareStartupAnimation();
overview.init();
global.screen.override_workspace_layout(Meta.ScreenCorner.TOPLEFT,
false, -1, 1);
global.display.connect('overlay-key', Lang.bind(overview, overview.toggle));
sessionMode.connect('updated', _sessionUpdated);
_sessionUpdated();
// Provide the bus object for gnome-session to
// initiate logouts.
@ -199,8 +193,16 @@ function startSession() {
ExtensionDownloader.init();
ExtensionSystem.init();
layoutManager.connect('startup-prepared', function() {
layoutManager.startupAnimation();
if (sessionMode.isGreeter && screenShield) {
layoutManager.connect('startup-prepared', function() {
screenShield.showDialog();
});
}
layoutManager.connect('startup-complete', function() {
if (keybindingMode == Shell.KeyBindingMode.NONE) {
keybindingMode = Shell.KeyBindingMode.NORMAL;
}
});
}

View File

@ -1591,17 +1591,13 @@ const MessageTray = new Lang.Class({
global.focus_manager.add_group(this.actor);
this._summary = new St.BoxLayout({ style_class: 'message-tray-summary',
reactive: true,
track_hover: true,
x_align: Clutter.ActorAlign.END,
x_expand: true,
y_align: Clutter.ActorAlign.CENTER,
y_expand: true });
this._summary.connect('notify::hover', Lang.bind(this, this._onSummaryHoverChanged));
this.actor.add_actor(this._summary);
this._summary.opacity = 0;
this._summaryMotionId = 0;
this._trayMotionId = 0;
this._summaryBoxPointer = new BoxPointer.BoxPointer(St.Side.BOTTOM,
{ reactive: true,
@ -1636,15 +1632,22 @@ const MessageTray = new Lang.Class({
Main.layoutManager.connect('keyboard-visible-changed', Lang.bind(this, this._onKeyboardVisibleChanged));
this._trayState = State.HIDDEN;
this._locked = false;
this._traySummoned = false;
this._useLongerTrayLeftTimeout = false;
this._trayLeftTimeoutId = 0;
// pointerInTray is sort of a misnomer -- it tracks whether
// a message tray notification should expand. The value is
// partially driven by the hover state of the tray, but has
// a lot of complex state related to timeouts and the current
// state of the pointer when a notification pops up.
this._pointerInTray = false;
this._pointerInKeyboard = false;
// This tracks this.actor.hover and is used to fizzle
// out non-changing hover notifications in onTrayHoverChanged.
this._trayHovered = false;
this._keyboardVisible = false;
this._summaryState = State.HIDDEN;
this._pointerInSummary = false;
this._notificationClosed = false;
this._notificationState = State.HIDDEN;
this._notificationTimeoutId = 0;
@ -1666,20 +1669,18 @@ const MessageTray = new Lang.Class({
});
Main.layoutManager.trayBox.add_actor(this.actor);
this.actor.y = 0;
Main.layoutManager.trackChrome(this.actor);
Main.layoutManager.trackChrome(this._notificationWidget);
Main.layoutManager.trackChrome(this._closeButton);
Main.layoutManager.connect('primary-fullscreen-changed', Lang.bind(this, this._onFullscreenChanged));
Main.layoutManager.connect('fullscreen-changed', Lang.bind(this, this._updateState));
Main.layoutManager.connect('hot-corners-changed', Lang.bind(this, this._hotCornersChanged));
// If the overview shows or hides while we're in
// the message tray, revert back to normal mode.
Main.overview.connect('showing', Lang.bind(this, this._escapeTray));
Main.overview.connect('hiding', Lang.bind(this, this._escapeTray));
// Track if we've added the activities button
this._activitiesButtonAdded = false;
Main.sessionMode.connect('updated', Lang.bind(this, this._sessionUpdated));
Main.wm.addKeybinding('toggle-message-tray',
@ -1703,6 +1704,7 @@ const MessageTray = new Lang.Class({
this._trayDwellTimeoutId = 0;
this._setupTrayDwellIfNeeded();
this._sessionUpdated();
this._hotCornersChanged();
this._noMessages = new St.Label({ text: _("No Messages"),
style_class: 'no-messages-label',
@ -1743,13 +1745,11 @@ const MessageTray = new Lang.Class({
_openContextMenu: function () {
let [x, y, mask] = global.get_pointer();
this._lock();
this._contextMenu.setPosition(Math.round(x), Math.round(y));
this._grabHelper.grab({ actor: this._contextMenu.actor,
grabFocus: true,
onUngrab: Lang.bind(this, function () {
this._contextMenu.close(BoxPointer.PopupAnimation.FULL);
this._unlock();
})
});
this._contextMenu.open(BoxPointer.PopupAnimation.FULL);
@ -1775,11 +1775,6 @@ const MessageTray = new Lang.Class({
},
_sessionUpdated: function() {
if (!this._activitiesButtonAdded && Main.panel.statusArea.activities) {
this._activitiesButtonAdded = true;
this._grabHelper.addActor(Main.panel.statusArea.activities.hotCorner.actor);
}
if ((Main.sessionMode.isLocked || Main.sessionMode.isGreeter) && this._inCtrlAltTab) {
Main.ctrlAltTabManager.removeGroup(this._summary);
this._inCtrlAltTab = false;
@ -1828,6 +1823,9 @@ const MessageTray = new Lang.Class({
_trayDwellTimeout: function() {
this._trayDwellTimeoutId = 0;
if (Main.layoutManager.bottomMonitor.inFullscreen)
return false;
// We don't want to open the tray when a modal dialog
// is up, so we check the modal count for that. When we are in the
// overview we have to take the overview's modal push into account
@ -1999,18 +1997,6 @@ const MessageTray = new Lang.Class({
this._notificationQueue.splice(index, 1);
},
_lock: function() {
this._locked = true;
},
_unlock: function() {
if (!this._locked)
return;
this._locked = false;
this._pointerInTray = this.actor.hover;
this._updateState();
},
openTray: function() {
if (Main.overview.animationInProgress)
return;
@ -2036,7 +2022,6 @@ const MessageTray = new Lang.Class({
hide: function() {
this._traySummoned = false;
this.actor.set_hover(false);
this._summary.set_hover(false);
this._updateState();
},
@ -2096,13 +2081,19 @@ const MessageTray = new Lang.Class({
this._updateState();
},
_onSummaryHoverChanged: function() {
this._pointerInSummary = this._summary.hover;
this._updateState();
_hotCornersChanged: function() {
let primary = Main.layoutManager.primaryIndex;
let corner = Main.layoutManager.hotCorners[primary];
if (corner && corner.actor)
this._grabHelper.addActor(corner.actor);
},
_onTrayHoverChanged: function() {
if (this.actor.hover) {
if (this.actor.hover == this._trayHovered)
return;
this._trayHovered = this.actor.hover;
if (this._trayHovered) {
// No dwell inside notifications at the bottom of the screen
this._cancelTrayDwell();
@ -2110,13 +2101,6 @@ const MessageTray = new Lang.Class({
if (this._trayState == State.HIDDEN && this._notificationState == State.HIDDEN)
return;
// Don't do anything if this._useLongerTrayLeftTimeout is true, meaning the notification originally
// popped up under the pointer, but this._trayLeftTimeoutId is 0, meaning the pointer didn't leave
// the tray yet. We need to check for this case because sometimes _onTrayHoverChanged() gets called
// multiple times while this.actor.hover is true.
if (this._useLongerTrayLeftTimeout && !this._trayLeftTimeoutId)
return;
this._useLongerTrayLeftTimeout = false;
if (this._trayLeftTimeoutId) {
Mainloop.source_remove(this._trayLeftTimeoutId);
@ -2165,11 +2149,6 @@ const MessageTray = new Lang.Class({
this._updateState();
},
_onFullscreenChanged: function(obj, state) {
this._inFullscreen = state;
this._updateState();
},
_onStatusChanged: function(status) {
if (status == GnomeSession.PresenceStatus.BUSY) {
// remove notification and allow the summary to be closed now
@ -2201,7 +2180,6 @@ const MessageTray = new Lang.Class({
this._trayLeftTimeoutId = 0;
this._useLongerTrayLeftTimeout = false;
this._pointerInTray = false;
this._pointerInSummary = false;
this._updateNotificationTimeout(0);
this._updateState();
}
@ -2209,9 +2187,7 @@ const MessageTray = new Lang.Class({
},
_escapeTray: function() {
this._unlock();
this._pointerInTray = false;
this._pointerInSummary = false;
this._traySummoned = false;
this._setClickedSummaryItem(null);
this._updateNotificationTimeout(0);
@ -2220,7 +2196,7 @@ const MessageTray = new Lang.Class({
// All of the logic for what happens when occurs here; the various
// event handlers merely update variables such as
// 'this._pointerInTray', 'this._summaryState', etc, and
// 'this._pointerInTray', 'this._traySummoned', etc, and
// _updateState() figures out what (if anything) needs to be done
// at the present time.
_updateState: function() {
@ -2228,25 +2204,22 @@ const MessageTray = new Lang.Class({
let notificationQueue = this._notificationQueue;
let notificationUrgent = notificationQueue.length > 0 && notificationQueue[0].urgency == Urgency.CRITICAL;
let notificationForFeedback = notificationQueue.length > 0 && notificationQueue[0].forFeedback;
let notificationsLimited = this._busy || this._inFullscreen;
let notificationsLimited = this._busy || Main.layoutManager.bottomMonitor.inFullscreen;
let notificationsPending = notificationQueue.length > 0 && (!notificationsLimited || notificationUrgent || notificationForFeedback) && Main.sessionMode.hasNotifications;
let nextNotification = notificationQueue.length > 0 ? notificationQueue[0] : null;
let notificationPinned = this._pointerInTray && !this._pointerInSummary && !this._notificationRemoved;
let notificationPinned = this._pointerInTray && !this._notificationRemoved;
let notificationExpanded = this._notification && this._notification.expanded;
let notificationExpired = this._notificationTimeoutId == 0 &&
!(this._notification && this._notification.urgency == Urgency.CRITICAL) &&
!(this._notification && this._notification.focused) &&
!this._pointerInTray &&
!this._locked &&
!(this._pointerInKeyboard && notificationExpanded);
!this._pointerInTray;
let notificationLockedOut = !Main.sessionMode.hasNotifications && this._notification;
let notificationMustClose = this._notificationRemoved || notificationLockedOut || (notificationExpired && this._userActiveWhileNotificationShown) || this._notificationClosed;
let canShowNotification = notificationsPending && this._summaryState == State.HIDDEN;
let canShowNotification = notificationsPending && this._trayState == State.HIDDEN;
if (this._notificationState == State.HIDDEN) {
if (canShowNotification) {
if (canShowNotification)
this._showNotification();
}
} else if (this._notificationState == State.SHOWN) {
if (notificationMustClose)
this._hideNotification();
@ -2256,27 +2229,17 @@ const MessageTray = new Lang.Class({
this._ensureNotificationFocused();
}
// Summary
let summarySummoned = this._pointerInSummary || this._traySummoned;
let summaryPinned = this._pointerInTray || summarySummoned || this._locked;
let summaryHovered = this._pointerInTray || this._pointerInSummary;
let notificationsVisible = this._notificationState != State.HIDDEN;
let notificationsDone = !notificationsVisible && !notificationsPending;
let mustHideSummary = ((notificationsPending && notificationUrgent)
|| notificationsVisible || !Main.sessionMode.hasNotifications);
if (this._summaryState == State.HIDDEN && !mustHideSummary && summarySummoned)
this._showSummary();
else if (this._summaryState == State.SHOWN && (!summaryPinned || mustHideSummary))
this._hideSummary();
let mustHideTray = ((notificationsPending && notificationUrgent)
|| notificationsVisible || !Main.sessionMode.hasNotifications);
// Summary notification
let haveClickedSummaryItem = this._clickedSummaryItem != null;
let summarySourceIsMainNotificationSource = (haveClickedSummaryItem && this._notification &&
this._clickedSummaryItem.source == this._notification.source);
let canShowSummaryBoxPointer = this._summaryState == State.SHOWN;
let canShowSummaryBoxPointer = this._trayState == State.SHOWN;
// We only have sources with empty notification stacks for legacy tray icons. Currently, we never attempt
// to show notifications for legacy tray icons, but this would be necessary if we did.
let requestedNotificationStackIsEmpty = (this._clickedSummaryItemMouseButton == 1 && this._clickedSummaryItem.source.notifications.length == 0);
@ -2291,7 +2254,7 @@ const MessageTray = new Lang.Class({
if (haveClickedSummaryItem && !summarySourceIsMainNotificationSource && canShowSummaryBoxPointer && !requestedNotificationStackIsEmpty)
this._showSummaryBoxPointer();
} else if (this._summaryBoxPointerState == State.SHOWN) {
if (!haveClickedSummaryItem || !canShowSummaryBoxPointer || wrongSummaryBoxPointer || mustHideSummary) {
if (!haveClickedSummaryItem || !canShowSummaryBoxPointer || wrongSummaryBoxPointer || mustHideTray) {
this._hideSummaryBoxPointer();
if (wrongSummaryBoxPointer)
this._showSummaryBoxPointer();
@ -2301,9 +2264,7 @@ const MessageTray = new Lang.Class({
// Tray itself
let trayIsVisible = (this._trayState == State.SHOWING ||
this._trayState == State.SHOWN);
let trayShouldBeVisible = (this._summaryState == State.SHOWING ||
this._summaryState == State.SHOWN) &&
!this._keyboardVisible;
let trayShouldBeVisible = this._traySummoned && !this._keyboardVisible && !mustHideTray;
if (!trayIsVisible && trayShouldBeVisible)
trayShouldBeVisible = this._showTray();
else if (trayIsVisible && !trayShouldBeVisible)
@ -2441,7 +2402,7 @@ const MessageTray = new Lang.Class({
_showNotification: function() {
this._notification = this._notificationQueue.shift();
this._userActiveWhileNotificationShown = this.idleMonitor.get_idletime() > IDLE_TIME;
this._userActiveWhileNotificationShown = this.idleMonitor.get_idletime() <= IDLE_TIME;
if (!this._userActiveWhileNotificationShown) {
// If the user isn't active, set up a watch to let us know
// when the user becomes active.
@ -2576,6 +2537,14 @@ const MessageTray = new Lang.Class({
this._notificationUnfocusedId = 0;
}
this._useLongerTrayLeftTimeout = false;
if (this._trayLeftTimeoutId) {
Mainloop.source_remove(this._trayLeftTimeoutId);
this._trayLeftTimeoutId = 0;
this._trayLeftMouseX = -1;
this._trayLeftMouseY = -1;
}
if (this._notificationRemoved) {
Tweener.removeTweens(this._notificationWidget);
this._notificationWidget.y = this.actor.height;
@ -2606,7 +2575,11 @@ const MessageTray = new Lang.Class({
this._notificationRemoved = false;
this._closeButton.hide();
this._pointerInTray = false;
this.actor.hover = false; // Clutter doesn't emit notify::hover when actors move
// Clutter will send a leave-event the next time the mouse
// moves, but we need to set this here now to update the
// state machine.
this.actor.hover = false;
this._notificationBin.child = null;
this._notificationWidget.hide();
},
@ -2619,10 +2592,9 @@ const MessageTray = new Lang.Class({
},
_expandNotification: function(autoExpanding) {
// Don't grab focus in notifications that are auto-expanded.
// Don't focus notifications that are auto-expanding.
if (!autoExpanding)
this._grabHelper.grab({ actor: this._notification.actor,
grabFocus: true });
this._ensureNotificationFocused();
if (!this._notificationExpandedId)
this._notificationExpandedId =
@ -2652,30 +2624,11 @@ const MessageTray = new Lang.Class({
}
},
// We use this function to grab focus when the user moves the pointer
// to a notification with CRITICAL urgency that was already auto-expanded.
_ensureNotificationFocused: function() {
this._grabHelper.grab({ actor: this._notification.actor,
grabFocus: true });
},
_showSummary: function() {
this._summary.opacity = 0;
this._tween(this._summary, '_summaryState', State.SHOWN,
{ opacity: 255,
time: ANIMATION_TIME,
transition: 'easeOutQuad',
});
},
_hideSummary: function() {
this._tween(this._summary, '_summaryState', State.HIDDEN,
{ opacity: 0,
time: ANIMATION_TIME,
transition: 'easeOutQuad',
});
},
_onSourceDoneDisplayingContent: function(source, closeTray) {
if (closeTray) {
this._escapeTray();
@ -2719,7 +2672,6 @@ const MessageTray = new Lang.Class({
this._grabHelper.grab({ actor: this._summaryBoxPointer.bin.child,
grabFocus: true,
onUngrab: Lang.bind(this, this._onSummaryBoxPointerUngrabbed) });
this._lock();
this._summaryBoxPointer.actor.opacity = 0;
this._summaryBoxPointer.actor.show();
@ -2754,10 +2706,8 @@ const MessageTray = new Lang.Class({
this._clickedSummaryItem.actor.remove_style_pseudo_class('selected');
this._clickedSummaryItem.actor.disconnect(this._clickedSummaryItemAllocationChangedId);
this._summary.disconnect(this._summaryMotionId);
Main.layoutManager.trayBox.disconnect(this._trayMotionId);
this._clickedSummaryItemAllocationChangedId = 0;
this._summaryMotionId = 0;
this._trayMotionId = 0;
}
this._clickedSummaryItem = item;
@ -2772,8 +2722,6 @@ const MessageTray = new Lang.Class({
// _clickedSummaryItem.actor can change absolute position without changing allocation
this._summaryMotionId = this._summary.connect('allocation-changed',
Lang.bind(this, this._adjustSummaryBoxPointerPosition));
this._trayMotionId = Main.layoutManager.trayBox.connect('notify::anchor-y',
Lang.bind(this, this._adjustSummaryBoxPointerPosition));
}
return true;
@ -2810,8 +2758,6 @@ const MessageTray = new Lang.Class({
this._sourceDoneDisplayingId = 0;
}
this._unlock();
if (this._summaryBoxPointerItem.source.notifications.length == 0) {
this._summaryBoxPointer.actor.hide();
this._hideSummaryBoxPointerCompleted();

View File

@ -38,13 +38,15 @@ const ModalDialog = new Lang.Class({
styleClass: null,
parentActor: Main.uiGroup,
keybindingMode: Shell.KeyBindingMode.SYSTEM_MODAL,
shouldFadeIn: true });
shouldFadeIn: true,
destroyOnClose: true });
this.state = State.CLOSED;
this._hasModal = false;
this._keybindingMode = params.keybindingMode;
this._shellReactive = params.shellReactive;
this._shouldFadeIn = params.shouldFadeIn;
this._destroyOnClose = params.destroyOnClose;
this._group = new St.Widget({ visible: false,
x: 0,
@ -277,6 +279,9 @@ const ModalDialog = new Lang.Class({
this.state = State.CLOSED;
this._group.hide();
this.emit('closed');
if (this._destroyOnClose)
this.destroy();
})
});
},

View File

@ -244,7 +244,7 @@ const NotificationDaemon = new Lang.Class({
Main.overview.connect('hidden',
Lang.bind(this, this._onFocusAppChanged));
this._trayManager.manage_stage(global.stage, Main.messageTray.actor);
this._trayManager.manage_screen(global.screen, Main.messageTray.actor);
},
_imageForNotificationData: function(hints) {

View File

@ -164,12 +164,12 @@ const OsdWindow = new Lang.Class({
},
_monitorsChanged: function() {
/* assume 130x130 on a 640x480 display and scale from there */
/* assume 110x110 on a 640x480 display and scale from there */
let monitor = Main.layoutManager.primaryMonitor;
let scalew = monitor.width / 640.0;
let scaleh = monitor.height / 480.0;
let scale = Math.min(scalew, scaleh);
let size = 130 * Math.max(1, scale);
let size = 110 * Math.max(1, scale);
this._box.set_size(size, size);
this._box.translation_y = monitor.height / 4;

View File

@ -33,6 +33,8 @@ const SHADE_ANIMATION_TIME = .20;
const DND_WINDOW_SWITCH_TIMEOUT = 1250;
const OVERVIEW_ACTIVATION_TIMEOUT = 0.5;
const ShellInfo = new Lang.Class({
Name: 'ShellInfo',
@ -93,9 +95,7 @@ const Overview = new Lang.Class({
_init: function() {
this._overviewCreated = false;
this._initCalled = false;
this._controlPressed = false;
global.stage.connect('captured-event', Lang.bind(this, this._capturedEvent));
Main.sessionMode.connect('updated', Lang.bind(this, this._sessionUpdated));
this._sessionUpdated();
},
@ -146,9 +146,10 @@ const Overview = new Lang.Class({
this._backgroundGroup.hide();
this._bgManagers = [];
this._activationTime = 0;
this.visible = false; // animating to overview, in overview, animating out
this._shown = false; // show() and not hide()
this._shownTemporarily = false; // showTemporarily() and not hideTemporarily()
this._modal = false; // have a modal grab
this.animationInProgress = false;
this.visibleTarget = false;
@ -238,20 +239,6 @@ const Overview = new Lang.Class({
}
},
_capturedEvent: function(actor, event) {
let type = event.type();
if (type != Clutter.EventType.KEY_PRESS &&
type != Clutter.EventType.KEY_RELEASE)
return false;
let symbol = event.get_key_symbol();
if (symbol == Clutter.KEY_Control_L ||
symbol == Clutter.KEY_Control_R)
this._controlPressed = type == Clutter.EventType.KEY_PRESS;
return false;
},
_sessionUpdated: function() {
this.isDummy = !Main.sessionMode.hasOverview;
this._createOverview();
@ -346,18 +333,22 @@ const Overview = new Lang.Class({
},
_onDragBegin: function() {
this._inXdndDrag = true;
DND.addDragMonitor(this._dragMonitor);
// Remember the workspace we started from
this._lastActiveWorkspaceIndex = global.screen.get_active_workspace_index();
},
_onDragEnd: function(time) {
this._inXdndDrag = false;
// In case the drag was canceled while in the overview
// we have to go back to where we started and hide
// the overview
if (this._shownTemporarily) {
if (this._shown) {
global.screen.get_workspace_by_index(this._lastActiveWorkspaceIndex).activate(time);
this.hideTemporarily();
this.hide();
}
this._resetWindowSwitchTimeout();
this._lastHoveredWindow = null;
@ -405,7 +396,7 @@ const Overview = new Lang.Class({
this._needsFakePointerEvent = true;
Main.activateWindow(dragEvent.targetActor._delegate.metaWindow,
this._windowSwitchTimestamp);
this.hideTemporarily();
this.hide();
this._lastHoveredWindow = null;
}));
}
@ -501,9 +492,10 @@ const Overview = new Lang.Class({
if (this._shown)
return;
this._shown = true;
this._syncInputMode();
if (!this._modal)
if (!this._syncInputMode())
return;
this._animateVisible();
},
@ -536,6 +528,7 @@ const Overview = new Lang.Class({
this.visible = true;
this.animationInProgress = true;
this.visibleTarget = true;
this._activationTime = Date.now() / 1000;
// All the the actors in the window group are completely obscured,
// hiding the group holding them while the Overview is displayed greatly
@ -547,8 +540,6 @@ const Overview = new Lang.Class({
//
// Disable unredirection while in the overview
Meta.disable_unredirect_for_screen(global.screen);
global.window_group.hide();
global.top_window_group.hide();
this._stack.show();
this._backgroundGroup.show();
this._viewSelector.show();
@ -568,24 +559,6 @@ const Overview = new Lang.Class({
this.emit('showing');
},
// showTemporarily:
//
// Animates the overview visible without grabbing mouse and keyboard input;
// if show() has already been called, this has no immediate effect, but
// will result in the overview not being hidden until hideTemporarily() is
// called.
showTemporarily: function() {
if (this.isDummy)
return;
if (this._shownTemporarily)
return;
this._syncInputMode();
this._animateVisible();
this._shownTemporarily = true;
},
// hide:
//
// Reverses the effect of show()
@ -596,33 +569,22 @@ const Overview = new Lang.Class({
if (!this._shown)
return;
if (this._controlPressed)
return;
let event = Clutter.get_current_event();
if (event) {
let type = event.type();
let button = (type == Clutter.EventType.BUTTON_PRESS ||
type == Clutter.EventType.BUTTON_RELEASE);
let ctrl = (event.get_state() & Clutter.ModifierType.CONTROL_MASK) != 0;
if (button && ctrl)
return;
}
if (!this._shownTemporarily)
this._animateNotVisible();
this._animateNotVisible();
this._shown = false;
this._syncInputMode();
},
// hideTemporarily:
//
// Reverses the effect of showTemporarily()
hideTemporarily: function() {
if (this.isDummy)
return;
if (!this._shownTemporarily)
return;
if (!this._shown)
this._animateNotVisible();
this._shownTemporarily = false;
this._syncInputMode();
},
toggle: function() {
if (this.isDummy)
return;
@ -633,6 +595,20 @@ const Overview = new Lang.Class({
this.show();
},
// Checks if the Activities button is currently sensitive to
// clicks. The first call to this function within the
// OVERVIEW_ACTIVATION_TIMEOUT time of the hot corner being
// triggered will return false. This avoids opening and closing
// the overview if the user both triggered the hot corner and
// clicked the Activities button.
shouldToggleByCornerOrButton: function() {
if (this.animationInProgress)
return false;
if (this._activationTime == 0 || Date.now() / 1000 - this._activationTime > OVERVIEW_ACTIVATION_TIMEOUT)
return true;
return false;
},
//// Private methods ////
_syncInputMode: function() {
@ -640,22 +616,23 @@ const Overview = new Lang.Class({
// overview we don't have a problem with the release of a press/release
// going to an application.
if (this.animationInProgress)
return;
return true;
if (this._shown) {
if (!this._modal) {
if (Main.pushModal(this._overview,
{ keybindingMode: Shell.KeyBindingMode.OVERVIEW }))
this._modal = true;
else
this.hide();
let shouldBeModal = !this._inXdndDrag;
if (shouldBeModal) {
if (!this._modal) {
if (Main.pushModal(this._overview,
{ keybindingMode: Shell.KeyBindingMode.OVERVIEW })) {
this._modal = true;
} else {
this.hide();
return false;
}
}
} else {
global.stage_input_mode = Shell.StageInputMode.FULLSCREEN;
}
} else if (this._shownTemporarily) {
if (this._modal) {
Main.popModal(this._overview);
this._modal = false;
}
global.stage_input_mode = Shell.StageInputMode.FULLSCREEN;
} else {
if (this._modal) {
Main.popModal(this._overview);
@ -664,6 +641,7 @@ const Overview = new Lang.Class({
else if (global.stage_input_mode == Shell.StageInputMode.FULLSCREEN)
global.stage_input_mode = Shell.StageInputMode.NORMAL;
}
return true;
},
_animateNotVisible: function() {
@ -697,7 +675,7 @@ const Overview = new Lang.Class({
this.emit('shown');
// Handle any calls to hide* while we were showing
if (!this._shown && !this._shownTemporarily)
if (!this._shown)
this._animateNotVisible();
this._syncInputMode();
@ -708,9 +686,6 @@ const Overview = new Lang.Class({
// Re-enable unredirection
Meta.enable_unredirect_for_screen(global.screen);
global.window_group.show();
global.top_window_group.show();
this._viewSelector.hide();
this._desktopFade.hide();
this._backgroundGroup.hide();
@ -723,7 +698,7 @@ const Overview = new Lang.Class({
this.emit('hidden');
// Handle any calls to show* while we were hiding
if (this._shown || this._shownTemporarily)
if (this._shown)
this._animateVisible();
this._syncInputMode();

View File

@ -452,9 +452,11 @@ const MessagesIndicator = new Lang.Class({
_updateCount: function() {
let count = 0;
let hasChats = false;
this._sources.forEach(Lang.bind(this,
function(source) {
count += source.indicatorCount;
hasChats |= source.isChat;
}));
this._count = count;
@ -462,6 +464,7 @@ const MessagesIndicator = new Lang.Class({
"%d new messages",
count).format(count);
this._icon.visible = hasChats;
this._updateVisibility();
},

View File

@ -18,7 +18,6 @@ const Atk = imports.gi.Atk;
const Config = imports.misc.config;
const CtrlAltTab = imports.ui.ctrlAltTab;
const DND = imports.ui.dnd;
const Layout = imports.ui.layout;
const Overview = imports.ui.overview;
const PopupMenu = imports.ui.popupMenu;
const PanelMenu = imports.ui.panelMenu;
@ -630,23 +629,15 @@ const ActivitiesButton = new Lang.Class({
this.parent(0.0, null, true);
this.actor.accessible_role = Atk.Role.TOGGLE_BUTTON;
let container = new Shell.GenericContainer();
container.connect('get-preferred-width', Lang.bind(this, this._containerGetPreferredWidth));
container.connect('get-preferred-height', Lang.bind(this, this._containerGetPreferredHeight));
container.connect('allocate', Lang.bind(this, this._containerAllocate));
this.actor.add_actor(container);
this.actor.name = 'panelActivities';
/* Translators: If there is no suitable word for "Activities"
in your language, you can use the word for "Overview". */
this._label = new St.Label({ text: _("Activities") });
container.add_actor(this._label);
this.actor.add_actor(this._label);
this.actor.label_actor = this._label;
this.hotCorner = new Layout.HotCorner(Main.layoutManager);
container.add_actor(this.hotCorner.actor);
this.actor.connect('captured-event', Lang.bind(this, this._onCapturedEvent));
this.actor.connect_after('button-release-event', Lang.bind(this, this._onButtonRelease));
this.actor.connect_after('key-release-event', Lang.bind(this, this._onKeyRelease));
@ -661,44 +652,6 @@ const ActivitiesButton = new Lang.Class({
}));
this._xdndTimeOut = 0;
// Since the hot corner uses stage coordinates, Clutter won't
// queue relayouts for us when the panel moves. Queue a relayout
// when that happens.
Main.layoutManager.connect('panel-box-changed', Lang.bind(this, function() {
container.queue_relayout();
}));
},
_containerGetPreferredWidth: function(actor, forHeight, alloc) {
[alloc.min_size, alloc.natural_size] = this._label.get_preferred_width(forHeight);
},
_containerGetPreferredHeight: function(actor, forWidth, alloc) {
[alloc.min_size, alloc.natural_size] = this._label.get_preferred_height(forWidth);
},
_containerAllocate: function(actor, box, flags) {
this._label.allocate(box, flags);
// The hot corner needs to be outside any padding/alignment
// that has been imposed on us
let primary = Main.layoutManager.primaryMonitor;
let hotBox = new Clutter.ActorBox();
let ok, x, y;
if (actor.get_text_direction() == Clutter.TextDirection.LTR) {
[ok, x, y] = actor.transform_stage_point(primary.x, primary.y)
} else {
[ok, x, y] = actor.transform_stage_point(primary.x + primary.width, primary.y);
// hotCorner.actor has northeast gravity, so we don't need
// to adjust x for its width
}
hotBox.x1 = Math.round(x);
hotBox.x2 = hotBox.x1 + this.hotCorner.actor.width;
hotBox.y1 = Math.round(y);
hotBox.y2 = hotBox.y1 + this.hotCorner.actor.height;
this.hotCorner.actor.allocate(hotBox, flags);
},
handleDragOver: function(source, actor, x, y, time) {
@ -708,14 +661,14 @@ const ActivitiesButton = new Lang.Class({
if (this._xdndTimeOut != 0)
Mainloop.source_remove(this._xdndTimeOut);
this._xdndTimeOut = Mainloop.timeout_add(BUTTON_DND_ACTIVATION_TIMEOUT,
Lang.bind(this, this._xdndShowOverview, actor));
Lang.bind(this, this._xdndToggleOverview, actor));
return DND.DragMotionResult.CONTINUE;
},
_onCapturedEvent: function(actor, event) {
if (event.type() == Clutter.EventType.BUTTON_PRESS) {
if (!this.hotCorner.shouldToggleOverviewOnClick())
if (!Main.overview.shouldToggleByCornerOrButton())
return true;
}
return false;
@ -732,15 +685,12 @@ const ActivitiesButton = new Lang.Class({
}
},
_xdndShowOverview: function(actor) {
_xdndToggleOverview: function(actor) {
let [x, y, mask] = global.get_pointer();
let pickedActor = global.stage.get_actor_at_pos(Clutter.PickMode.REACTIVE, x, y);
if (pickedActor == this.actor) {
if (!Main.overview.visible && !Main.overview.animationInProgress) {
Main.overview.showTemporarily();
}
}
if (pickedActor == this.actor && Main.overview.shouldToggleByCornerOrButton())
Main.overview.toggle();
Mainloop.source_remove(this._xdndTimeOut);
this._xdndTimeOut = 0;

View File

@ -2086,7 +2086,7 @@ const PopupMenuManager = new Lang.Class({
},
removeMenu: function(menu) {
if (menu == this._activeMenu)
if (menu == this.activeMenu)
this._closeMenu(menu);
let position = this._findMenu(menu);
@ -2110,9 +2110,9 @@ const PopupMenuManager = new Lang.Class({
},
get activeMenu() {
let actor = this._grabHelper.currentGrab.actor;
if (actor)
return actor._delegate;
let firstGrab = this._grabHelper.grabStack[0];
if (firstGrab)
return firstGrab.actor._delegate;
else
return null;
},

View File

@ -127,8 +127,6 @@ function remoteProvidersLoaded(loadState) {
// Special case gnome-control-center to be always active and always first
sortOrder.unshift('gnome-control-center.desktop');
let numSorted = sortOrder.length;
loadState.loadedProviders.sort(
function(providerA, providerB) {
let idxA, idxB;
@ -148,15 +146,6 @@ function remoteProvidersLoaded(loadState) {
return GLib.utf8_collate(nameA, nameB);
}
if (numSorted > 1) {
// if providerA is the last, it goes after everything
if ((idxA + 1) == numSorted)
return 1;
// if providerB is the last, it goes after everything
else if ((idxB + 1) == numSorted)
return -1;
}
// if providerA isn't found, it's sorted after providerB
if (idxA == -1)
return 1;

View File

@ -30,138 +30,6 @@ const EXEC_ARG_KEY = 'exec-arg';
const DIALOG_GROW_TIME = 0.1;
const CommandCompleter = new Lang.Class({
Name: 'CommandCompleter',
_init : function() {
this._changedCount = 0;
this._paths = GLib.getenv('PATH').split(':');
this._paths.push(GLib.get_home_dir());
this._valid = false;
this._updateInProgress = false;
this._childs = new Array(this._paths.length);
this._monitors = new Array(this._paths.length);
for (let i = 0; i < this._paths.length; i++) {
this._childs[i] = [];
let file = Gio.file_new_for_path(this._paths[i]);
let info;
try {
info = file.query_info(Gio.FILE_ATTRIBUTE_STANDARD_TYPE, Gio.FileQueryInfoFlags.NONE, null);
} catch (e) {
// FIXME catchall
this._paths[i] = null;
continue;
}
if (info.get_attribute_uint32(Gio.FILE_ATTRIBUTE_STANDARD_TYPE) != Gio.FileType.DIRECTORY)
continue;
this._paths[i] = file.get_path();
this._monitors[i] = file.monitor_directory(Gio.FileMonitorFlags.NONE, null);
if (this._monitors[i] != null) {
this._monitors[i].connect('changed', Lang.bind(this, this._onChanged));
}
}
this._paths = this._paths.filter(function(a) {
return a != null;
});
this._update(0);
},
update : function() {
if (this._valid)
return;
this._update(0);
},
_update : function(i) {
if (i == 0 && this._updateInProgress)
return;
this._updateInProgress = true;
this._changedCount = 0;
this._i = i;
if (i >= this._paths.length) {
this._valid = true;
this._updateInProgress = false;
return;
}
let file = Gio.file_new_for_path(this._paths[i]);
this._childs[this._i] = [];
FileUtils.listDirAsync(file, Lang.bind(this, function (files) {
for (let i = 0; i < files.length; i++) {
this._childs[this._i].push(files[i].get_name());
}
this._update(this._i + 1);
}));
},
_onChanged : function(m, f, of, type) {
if (!this._valid)
return;
let path = f.get_parent().get_path();
let k = undefined;
for (let i = 0; i < this._paths.length; i++) {
if (this._paths[i] == path)
k = i;
}
if (k === undefined) {
return;
}
if (type == Gio.FileMonitorEvent.CREATED) {
this._childs[k].push(f.get_basename());
}
if (type == Gio.FileMonitorEvent.DELETED) {
this._changedCount++;
if (this._changedCount > MAX_FILE_DELETED_BEFORE_INVALID) {
this._valid = false;
}
let name = f.get_basename();
this._childs[k] = this._childs[k].filter(function(e) {
return e != name;
});
}
if (type == Gio.FileMonitorEvent.UNMOUNTED) {
this._childs[k] = [];
}
},
getCompletion: function(text) {
let common = '';
let notInit = true;
if (!this._valid) {
this._update(0);
return common;
}
function _getCommon(s1, s2) {
let k = 0;
for (; k < s1.length && k < s2.length; k++) {
if (s1[k] != s2[k])
break;
}
if (k == 0)
return '';
return s1.substr(0, k);
}
function _hasPrefix(s1, prefix) {
return s1.indexOf(prefix) == 0;
}
for (let i = 0; i < this._childs.length; i++) {
for (let k = 0; k < this._childs[i].length; k++) {
if (!_hasPrefix(this._childs[i][k], text))
continue;
if (notInit) {
common = this._childs[i][k];
notInit = false;
}
common = _getCommon(common, this._childs[i][k]);
}
}
if (common.length)
return common.substr(text.length);
return common;
}
});
const RunDialog = new Lang.Class({
Name: 'RunDialog',
Extends: ModalDialog.ModalDialog,
@ -242,8 +110,6 @@ const RunDialog = new Lang.Class({
key: Clutter.Escape }]);
this._pathCompleter = new Gio.FilenameCompleter();
this._commandCompleter = new CommandCompleter();
this._group.connect('notify::visible', Lang.bind(this._commandCompleter, this._commandCompleter.update));
this._history = new History.HistoryManager({ gsettingsKey: HISTORY_KEY,
entry: this._entryText });
@ -259,18 +125,6 @@ const RunDialog = new Lang.Class({
return true;
}
if (symbol == Clutter.slash) {
// Need preload data before get completion. GFilenameCompleter load content of parent directory.
// Parent directory for /usr/include/ is /usr/. So need to add fake name('a').
let text = o.get_text().concat('/a');
let prefix;
if (text.lastIndexOf(' ') == -1)
prefix = text;
else
prefix = text.substr(text.lastIndexOf(' ') + 1);
this._getCompletion(prefix);
return false;
}
if (symbol == Clutter.Tab) {
let text = o.get_text();
let prefix;
@ -282,8 +136,6 @@ const RunDialog = new Lang.Class({
if (postfix != null && postfix.length > 0) {
o.insert_text(postfix, -1);
o.set_cursor_position(text.length + postfix.length);
if (postfix[postfix.length - 1] == '/')
this._getCompletion(text + postfix + 'a');
}
return true;
}
@ -291,11 +143,53 @@ const RunDialog = new Lang.Class({
}));
},
_getCommandCompletion: function(text) {
function _getCommon(s1, s2) {
if (s1 == null)
return s2;
let k = 0;
for (; k < s1.length && k < s2.length; k++) {
if (s1[k] != s2[k])
break;
}
if (k == 0)
return '';
return s1.substr(0, k);
}
let paths = GLib.getenv('PATH').split(':');
paths.push(GLib.get_home_dir());
let someResults = paths.map(function(path) {
let results = [];
try {
let file = Gio.File.new_for_path(path);
let fileEnum = file.enumerate_children('standard::name', Gio.FileQueryInfoFlags.NONE, null);
let info;
while ((info = fileEnum.next_file(null))) {
let name = info.get_name();
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);
} finally {
return results;
}
});
let results = someResults.reduce(function(a, b) {
return a.concat(b);
}, []);
let common = results.reduce(_getCommon, null);
return common.substr(text.length);
},
_getCompletion : function(text) {
if (text.indexOf('/') != -1) {
return this._pathCompleter.get_completion_suffix(text);
} else {
return this._commandCompleter.getCompletion(text);
return this._getCommandCompletion(text);
}
},

View File

@ -38,11 +38,7 @@ const ARROW_DRAG_THRESHOLD = 0.1;
const N_ARROWS = 3;
const ARROW_ANIMATION_TIME = 0.6;
const ARROW_ANIMATION_PEAK_OPACITY = 0.4;
// The distance in px that the lock screen will move to when pressing
// a key that has no effect in the lock screen (bumping it)
const BUMP_SIZE = 25;
const BUMP_TIME = 0.3;
const ARROW_IDLE_TIME = 30000; // ms
const SUMMARY_ICON_SIZE = 48;
@ -54,7 +50,7 @@ const SUMMARY_ICON_SIZE = 48;
// - CURTAIN_SLIDE_TIME is used when raising the shield before unlocking
// - INITIAL_FADE_IN_TIME is used for the initial fade in at startup
const STANDARD_FADE_TIME = 10;
const MANUAL_FADE_TIME = 0.8;
const MANUAL_FADE_TIME = 0.3;
const BACKGROUND_FADE_TIME = 1.0;
const CURTAIN_SLIDE_TIME = 0.3;
const INITIAL_FADE_IN_TIME = 0.25;
@ -435,8 +431,8 @@ const ScreenShield = new Lang.Class({
name: 'lockScreenGroup',
visible: false,
});
this._lockScreenGroup.connect('key-release-event',
Lang.bind(this, this._onLockScreenKeyRelease));
this._lockScreenGroup.connect('key-press-event',
Lang.bind(this, this._onLockScreenKeyPress));
this._lockScreenGroup.connect('scroll-event',
Lang.bind(this, this._onLockScreenScroll));
Main.ctrlAltTabManager.addGroup(this._lockScreenGroup, _("Lock"), 'changes-prevent-symbolic');
@ -456,6 +452,9 @@ const ScreenShield = new Lang.Class({
this._updateBackgrounds();
Main.layoutManager.connect('monitors-changed', Lang.bind(this, this._updateBackgrounds));
this._arrowAnimationId = 0;
this._arrowWatchId = 0;
this._arrowActiveWatchId = 0;
this._arrowContainer = new St.BoxLayout({ style_class: 'screen-shield-arrows',
vertical: true,
x_align: Clutter.ActorAlign.CENTER,
@ -507,14 +506,18 @@ const ScreenShield = new Lang.Class({
this._screenSaverDBus = new ShellDBus.ScreenSaverDBus(this);
this._inhibitor = null;
this._aboutToSuspend = false;
this._loginManager = LoginManager.getLoginManager();
this._loginManager.connect('prepare-for-sleep',
Lang.bind(this, this._prepareForSleep));
this._inhibitSuspend();
this._loginSession = this._loginManager.getCurrentSessionProxy();
this._loginSession.connectSignal('Lock', Lang.bind(this, function() { this.lock(false); }));
this._loginSession.connectSignal('Unlock', Lang.bind(this, function() { this.deactivate(false); }));
this._loginManager.getCurrentSessionProxy(Lang.bind(this,
function(sessionProxy) {
this._loginSession = sessionProxy;
this._loginSession.connectSignal('Lock', Lang.bind(this, function() { this.lock(false); }));
this._loginSession.connectSignal('Unlock', Lang.bind(this, function() { this.deactivate(false); }));
}));
this._settings = new Gio.Settings({ schema: SCREENSAVER_SCHEMA });
@ -547,9 +550,7 @@ const ScreenShield = new Lang.Class({
let bgManager = new Background.BackgroundManager({ container: widget,
monitorIndex: monitorIndex,
effects: Meta.BackgroundEffects.BLUR | Meta.BackgroundEffects.DESATURATE,
controlPosition: false });
bgManager.background.saturation = 0.6;
this._bgManagers.push(bgManager);
@ -590,28 +591,28 @@ const ScreenShield = new Lang.Class({
return this._isModal;
},
_onLockScreenKeyRelease: function(actor, event) {
_onLockScreenKeyPress: function(actor, event) {
let symbol = event.get_key_symbol();
let unichar = event.get_key_unicode();
// Do nothing if the lock screen is not fully shown.
// This avoids reusing the previous (and stale) unlock
// dialog if esc is pressed while the curtain is going
// down after cancel.
// Similarly, don't bump if the lock screen is not showing or is
// animating, as the bump overrides the animation and would
// remove any onComplete handler.
if (this._lockScreenState != MessageTray.State.SHOWN)
return false;
if (symbol == Clutter.KEY_Escape ||
symbol == Clutter.KEY_Return ||
symbol == Clutter.KEY_KP_Enter) {
this._liftShield(false, 0);
return true;
}
let isEnter = (symbol == Clutter.KEY_Return || symbol == Clutter.KEY_KP_Enter);
if (!isEnter && !(GLib.unichar_isprint(unichar) || symbol == Clutter.KEY_Escape))
return false;
this._bumpLockScreen();
this._ensureUnlockDialog(true, true);
if (GLib.unichar_isgraph(unichar))
this._dialog.addCharacter(unichar);
this._liftShield(true, 0);
return true;
},
@ -649,6 +650,8 @@ const ScreenShield = new Lang.Class({
},
_prepareForSleep: function(loginManager, aboutToSuspend) {
this._aboutToSuspend = aboutToSuspend;
if (aboutToSuspend) {
if (!this._settings.get_boolean(LOCK_ENABLED_KEY)) {
this._uninhibitSuspend();
@ -849,21 +852,6 @@ const ScreenShield = new Lang.Class({
this._hideLockScreen(false, 0);
},
_bumpLockScreen: function() {
Tweener.removeTweens(this._lockScreenGroup);
Tweener.addTween(this._lockScreenGroup,
{ y: -BUMP_SIZE,
time: BUMP_TIME / 2,
transition: 'easeOutQuad',
onComplete: function() {
Tweener.addTween(this,
{ y: 0,
time: BUMP_TIME / 2,
transition: 'easeInQuad' });
}
});
},
_hideLockScreenComplete: function() {
if (Main.sessionMode.currentMode == 'lock-screen')
Main.sessionMode.popMode('lock-screen');
@ -917,14 +905,12 @@ const ScreenShield = new Lang.Class({
let time = global.get_current_time();
this._dialog.connect('loaded', Lang.bind(this, function() {
if (!this._dialog.open(time, onPrimary)) {
// This is kind of an impossible error: we're already modal
// by the time we reach this...
log('Could not open login dialog: failed to acquire grab');
this.deactivate(true);
}
}));
if (!this._dialog.open(time, onPrimary)) {
// This is kind of an impossible error: we're already modal
// by the time we reach this...
log('Could not open login dialog: failed to acquire grab');
this.deactivate(true);
}
this._dialog.connect('failed', Lang.bind(this, this._onUnlockFailed));
this._dialog.connect('unlocked', Lang.bind(this, this._onUnlockSucceded));
@ -990,16 +976,60 @@ const ScreenShield = new Lang.Class({
Main.sessionMode.pushMode('lock-screen');
},
_startArrowAnimation: function() {
this._arrowActiveWatchId = 0;
if (!this._arrowAnimationId) {
this._arrowAnimationId = Mainloop.timeout_add(6000, Lang.bind(this, this._animateArrows));
this._animateArrows();
}
if (!this._arrowWatchId)
this._arrowWatchId = this.idleMonitor.add_idle_watch(ARROW_IDLE_TIME,
Lang.bind(this, this._pauseArrowAnimation));
},
_pauseArrowAnimation: function() {
if (this._arrowAnimationId) {
Mainloop.source_remove(this._arrowAnimationId);
this._arrowAnimationId = 0;
}
if (!this._arrowActiveWatchId)
this._arrowActiveWatchId = this.idleMonitor.add_user_active_watch(Lang.bind(this, this._startArrowAnimation));
},
_stopArrowAnimation: function() {
if (this._arrowAnimationId) {
Mainloop.source_remove(this._arrowAnimationId);
this._arrowAnimationId = 0;
}
if (this._arrowActiveWatchId) {
this.idleMonitor.remove_watch(this._arrowActiveWatchId);
this._arrowActiveWatchId = 0;
}
if (this._arrowWatchId) {
this.idleMonitor.remove_watch(this._arrowWatchId);
this._arrowWatchId = 0;
}
},
_checkArrowAnimation: function() {
let idleTime = this.idleMonitor.get_idletime();
if (idleTime < ARROW_IDLE_TIME)
this._startArrowAnimation();
else
this._pauseArrowAnimation();
},
_lockScreenShown: function() {
if (this._dialog && !this._isGreeter) {
this._dialog.destroy();
this._dialog = null;
}
if (this._arrowAnimationId)
Mainloop.source_remove(this._arrowAnimationId);
this._arrowAnimationId = Mainloop.timeout_add(6000, Lang.bind(this, this._animateArrows));
this._animateArrows();
this._checkArrowAnimation();
let motionId = global.stage.connect('captured-event', function(stage, event) {
if (event.type() == Clutter.EventType.MOTION) {
@ -1021,7 +1051,8 @@ const ScreenShield = new Lang.Class({
if (prevIsActive != this._isActive)
this.emit('active-changed');
this._uninhibitSuspend();
if (this._aboutToSuspend)
this._uninhibitSuspend();
this.emit('lock-screen-shown');
},
@ -1061,12 +1092,9 @@ const ScreenShield = new Lang.Class({
this._notificationsBox = null;
}
this._lockScreenContentsBox.destroy();
this._stopArrowAnimation();
if (this._arrowAnimationId) {
Mainloop.source_remove(this._arrowAnimationId);
this._arrowAnimationId = 0;
}
this._lockScreenContentsBox.destroy();
this._hasLockScreen = false;
},
@ -1178,62 +1206,3 @@ const ScreenShield = new Lang.Class({
},
});
Signals.addSignalMethods(ScreenShield.prototype);
/* Fallback code to handle session locking using gnome-screensaver,
in case the required GDM dependency is not there
*/
const ScreenShieldFallback = new Lang.Class({
Name: 'ScreenShieldFallback',
_init: function() {
Util.spawn(['gnome-screensaver']);
this._proxy = new Gio.DBusProxy({ g_connection: Gio.DBus.session,
g_name: 'org.gnome.ScreenSaver',
g_object_path: '/org/gnome/ScreenSaver',
g_interface_name: 'org.gnome.ScreenSaver',
g_flags: (Gio.DBusProxyFlags.DO_NOT_AUTO_START |
Gio.DBusProxyFlags.DO_NOT_LOAD_PROPERTIES),
});
this._proxy.init(null);
this._proxy.connect('g-signal', Lang.bind(this, this._onSignal));
this._proxy.connect('notify::g-name-owner', Lang.bind(this, this._onNameOwnerChanged));
},
_onNameOwnerChanged: function(object, pspec) {
if (this._proxy.g_name_owner)
[this._locked] = this._proxy.call_sync('GetActive', null,
Gio.DBusCallFlags.NONE, -1, null).deep_unpack();
else
this._locked = false;
this.emit('active-changed', this._locked);
},
_onSignal: function(proxy, senderName, signalName, params) {
if (signalName == 'ActiveChanged') {
[this._locked] = params.deep_unpack();
this.emit('active-changed', this._locked);
}
},
get locked() {
return this._locked;
},
lock: function() {
this._proxy.call('Lock', null, Gio.DBusCallFlags.NONE, -1, null,
Lang.bind(this, function(proxy, result) {
proxy.call_finish(result);
this.emit('lock-screen-shown');
}));
},
unlock: function() {
this._proxy.call('SetActive', GLib.Variant.new('(b)', false),
Gio.DBusCallFlags.NONE, -1, null, null);
},
});
Signals.addSignalMethods(ScreenShieldFallback.prototype);

View File

@ -4,6 +4,7 @@ const Clutter = imports.gi.Clutter;
const Lang = imports.lang;
const Gtk = imports.gi.Gtk;
const Meta = imports.gi.Meta;
const Signals = imports.signals;
const St = imports.gi.St;
const Atk = imports.gi.Atk;
@ -13,6 +14,7 @@ const Main = imports.ui.main;
const Overview = imports.ui.overview;
const Separator = imports.ui.separator;
const Search = imports.ui.search;
const Util = imports.misc.util;
const MAX_LIST_SEARCH_RESULTS_ROWS = 3;
const MAX_GRID_SEARCH_RESULTS_ROWS = 1;
@ -102,6 +104,7 @@ const ListSearchResult = new Lang.Class({
y_fill: false,
x_align: St.Align.START,
y_align: St.Align.START });
this.actor.label_actor = title;
if (this.metaInfo['description']) {
let description = new St.Label({ style_class: 'list-search-result-description' });
@ -139,6 +142,7 @@ const GridSearchResult = new Lang.Class({
}
this.actor.set_child(content);
this.actor.label_actor = content.label_actor;
let draggable = DND.makeDraggable(this.actor);
draggable.connect('drag-begin',
@ -227,9 +231,14 @@ const ListSearchResults = new Lang.Class({
this._pendingClear = true;
},
_keyFocusIn: function(icon) {
this.emit('key-focus-in', icon);
},
renderResults: function(metas) {
for (let i = 0; i < metas.length; i++) {
let display = new ListSearchResult(this.provider, metas[i], this._terms);
display.actor.connect('key-focus-in', Lang.bind(this, this._keyFocusIn));
this._content.add_actor(display.actor);
}
},
@ -246,6 +255,7 @@ const ListSearchResults = new Lang.Class({
return null;
}
});
Signals.addSignalMethods(ListSearchResults.prototype);
const GridSearchResults = new Lang.Class({
Name: 'GridSearchResults',
@ -288,9 +298,14 @@ const GridSearchResults = new Lang.Class({
this._pendingClear = true;
},
_keyFocusIn: function(icon) {
this.emit('key-focus-in', icon);
},
renderResults: function(metas) {
for (let i = 0; i < metas.length; i++) {
let display = new GridSearchResult(this.provider, metas[i], this._terms);
display.actor.connect('key-focus-in', Lang.bind(this, this._keyFocusIn));
this._grid.addItem(display.actor);
}
},
@ -307,6 +322,7 @@ const GridSearchResults = new Lang.Class({
return null;
}
});
Signals.addSignalMethods(GridSearchResults.prototype);
const SearchResults = new Lang.Class({
Name: 'SearchResults',
@ -366,6 +382,10 @@ const SearchResults = new Lang.Class({
return false;
},
_keyFocusIn: function(provider, icon) {
Util.ensureActorVisibleInScrollView(this._scrollView, icon);
},
createProviderMeta: function(provider) {
let providerBox = new St.BoxLayout({ style_class: 'search-section',
vertical: true });
@ -379,6 +399,8 @@ const SearchResults = new Lang.Class({
resultDisplay = new GridSearchResults(provider);
}
resultDisplay.connect('key-focus-in', Lang.bind(this, this._keyFocusIn));
let resultDisplayBin = new St.Bin({ child: resultDisplay.actor,
x_fill: true,
y_fill: true });
@ -557,6 +579,7 @@ const ProviderIcon = new Lang.Class({
this.parent({ style_class: 'search-provider-icon',
reactive: true,
can_focus: true,
accessible_name: provider.appInfo.get_name(),
track_hover: true });
this._content = new St.Widget({ layout_manager: new Clutter.BinLayout() });

View File

@ -79,12 +79,13 @@ const _modes = {
},
'initial-setup': {
hasWindows: true,
isPrimary: true,
components: ['keyring'],
panel: {
left: [],
center: ['dateMenu'],
right: ['a11yGreeter', 'keyboard', 'volume']
right: ['a11yGreeter', 'keyboard', 'volume', 'battery']
}
},
@ -158,12 +159,7 @@ function listModes() {
const SessionMode = new Lang.Class({
Name: 'SessionMode',
_init: function() {
global.connect('notify::session-mode', Lang.bind(this, this._sync));
this._modes = _modes;
this._modeStack = [DEFAULT_MODE];
this._sync();
init: function() {
_getModes(Lang.bind(this, function(modes) {
this._modes = modes;
let primary = modes[global.session_mode] &&
@ -171,6 +167,8 @@ const SessionMode = new Lang.Class({
let mode = primary ? global.session_mode : 'user';
this._modeStack = [mode];
this._sync();
this.emit('sessions-loaded');
}));
},

View File

@ -397,7 +397,7 @@ const ScreenSaverDBus = new Lang.Class({
if (active)
this._screenShield.activate(true);
else
this._screenShield.unlock(false);
this._screenShield.deactivate(false);
},
GetActive: function() {

View File

@ -171,4 +171,10 @@ function addContextMenu(entry, params) {
entry.connect('button-press-event', Lang.bind(null, _onButtonPressEvent, entry));
entry.connect('popup-menu', Lang.bind(null, _onPopup, entry));
entry.connect('destroy', function() {
entry.menu.destroy();
entry.menu = null;
entry._menuManager = null;
});
}

View File

@ -33,6 +33,36 @@ const KEY_INPUT_SOURCES = 'sources';
const INPUT_SOURCE_TYPE_XKB = 'xkb';
const INPUT_SOURCE_TYPE_IBUS = 'ibus';
// This is longest we'll keep the keyboard frozen until an input
// source is active.
const MAX_INPUT_SOURCE_ACTIVATION_TIME = 2000; // ms
const BUS_NAME = 'org.gnome.SettingsDaemon.Keyboard';
const OBJECT_PATH = '/org/gnome/SettingsDaemon/Keyboard';
const KeyboardManagerInterface =
<interface name="org.gnome.SettingsDaemon.Keyboard">
<method name="SetInputSource">
<arg type="u" direction="in" />
</method>
</interface>;
const KeyboardManagerProxy = Gio.DBusProxy.makeProxyWrapper(KeyboardManagerInterface);
function releaseKeyboard() {
if (Main.modalCount > 0)
global.display.unfreeze_keyboard(global.get_current_time());
else
global.display.ungrab_keyboard(global.get_current_time());
}
function holdKeyboard() {
if (Main.modalCount > 0)
global.display.freeze_keyboard(global.get_current_time());
else
global.display.grab_keyboard(global.get_current_time());
}
const IBusManager = new Lang.Class({
Name: 'IBusManager',
@ -230,6 +260,7 @@ const InputSource = new Lang.Class({
},
activate: function() {
holdKeyboard();
this.emit('activate');
},
});
@ -262,11 +293,11 @@ const InputSourcePopup = new Lang.Class({
this._select(this._selectedIndex);
},
_keyPressHandler: function(keysym, backwards, action) {
_keyPressHandler: function(keysym, _ignored, action) {
if (action == this._action)
this._select(backwards ? this._previous() : this._next());
this._select(this._next());
else if (action == this._actionBackward)
this._select(backwards ? this._next() : this._previous());
this._select(this._previous());
else if (keysym == Clutter.Left)
this._select(this._previous());
else if (keysym == Clutter.Right)
@ -336,14 +367,13 @@ const InputSourceIndicator = new Lang.Class({
this._keybindingAction =
Main.wm.addKeybinding('switch-input-source',
new Gio.Settings({ schema: "org.gnome.desktop.wm.keybindings" }),
Meta.KeyBindingFlags.REVERSES,
Meta.KeyBindingFlags.NONE,
Shell.KeyBindingMode.ALL,
Lang.bind(this, this._switchInputSource));
this._keybindingActionBackward =
Main.wm.addKeybinding('switch-input-source-backward',
new Gio.Settings({ schema: "org.gnome.desktop.wm.keybindings" }),
Meta.KeyBindingFlags.REVERSES |
Meta.KeyBindingFlags.REVERSED,
Meta.KeyBindingFlags.NONE,
Shell.KeyBindingMode.ALL,
Lang.bind(this, this._switchInputSource));
this._settings = new Gio.Settings({ schema: DESKTOP_INPUT_SOURCES_SCHEMA });
@ -364,6 +394,13 @@ const InputSourceIndicator = new Lang.Class({
this._ibusManager.connect('property-updated', Lang.bind(this, this._ibusPropertyUpdated));
this._inputSourcesChanged();
this._keyboardManager = new KeyboardManagerProxy(Gio.DBus.session, BUS_NAME, OBJECT_PATH,
function(proxy, error) {
if (error)
log(error.message);
});
global.display.connect('modifiers-accelerator-activated', Lang.bind(this, this._modifiersSwitcher));
this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
this._showLayoutItem = this.menu.addAction(_("Show Keyboard Layout"), Lang.bind(this, this._showLayout));
@ -397,13 +434,44 @@ const InputSourceIndicator = new Lang.Class({
this._inputSourcesChanged();
},
_modifiersSwitcher: function() {
let sourceIndexes = Object.keys(this._inputSources);
if (sourceIndexes.length == 0) {
releaseKeyboard();
return;
}
let is = this._currentSource;
if (!is)
is = this._inputSources[sourceIndexes[0]];
let nextIndex = is.index + 1;
if (nextIndex > sourceIndexes[sourceIndexes.length - 1])
nextIndex = 0;
while (!(is = this._inputSources[nextIndex]))
nextIndex += 1;
is.activate();
},
_switchInputSource: function(display, screen, window, binding) {
if (this._mruSources.length < 2)
return;
// HACK: Fall back on simple input source switching since we
// can't show a popup switcher while the message tray is up
// without considerable work to consolidate the usage of
// pushModal/popModal and grabHelper. See
// https://bugzilla.gnome.org/show_bug.cgi?id=695143 .
if (Main.keybindingMode == Shell.KeyBindingMode.MESSAGE_TRAY) {
this._modifiersSwitcher();
return;
}
let popup = new InputSourcePopup(this._mruSources, this._keybindingAction, this._keybindingActionBackward);
let modifiers = binding.get_modifiers();
let backwards = modifiers & Meta.VirtualModifier.SHIFT_MASK;
let backwards = false; // Not using this
if (!popup.show(backwards, binding.get_name(), binding.get_mask()))
popup.destroy();
},
@ -416,6 +484,11 @@ const InputSourceIndicator = new Lang.Class({
let oldSource;
[oldSource, this._currentSource] = [this._currentSource, newSource];
if (oldSource) {
oldSource.menuItem.setShowDot(false);
oldSource.indicatorLabel.hide();
}
if (!newSource || (nVisibleSources < 2 && !newSource.properties)) {
// This source index might be invalid if we weren't able
// to build a menu item for it, so we hide ourselves since
@ -430,11 +503,6 @@ const InputSourceIndicator = new Lang.Class({
this.actor.show();
if (oldSource) {
oldSource.menuItem.setShowDot(false);
oldSource.indicatorLabel.hide();
}
newSource.menuItem.setShowDot(true);
newSource.indicatorLabel.show();
@ -487,10 +555,10 @@ const InputSourceIndicator = new Lang.Class({
let is = new InputSource(type, id, displayName, shortName, i);
is.connect('activate', Lang.bind(this, function() {
if (this._currentSource.index == is.index)
return;
this._settings.set_value(KEY_CURRENT_INPUT_SOURCE,
GLib.Variant.new_uint32(is.index));
let inVariant = new GLib.Variant('(u)', [is.index]);
this._keyboardManager.call('SetInputSource', inVariant, 0,
MAX_INPUT_SOURCE_ACTIVATION_TIME,
null, releaseKeyboard);
}));
if (!(is.shortName in inputSourcesByShortName))
@ -703,7 +771,7 @@ const InputSourceIndicator = new Lang.Class({
item.prop = prop;
item.connect('activate', Lang.bind(this, function() {
this._ibusManager.activateProperty(item.prop.get_key(),
IBus.PropState.CHECKED);
item.prop.get_state());
}));
break;

View File

@ -27,35 +27,6 @@ const LoginDialog = imports.gdm.loginDialog;
// The timeout before going back automatically to the lock screen (in seconds)
const IDLE_TIMEOUT = 2 * 60;
function versionCompare(required, reference) {
required = required.split('.');
reference = reference.split('.');
for (let i = 0; i < required.length; i++) {
if (required[i] != reference[i])
return required[i] < reference[i];
}
return true;
}
function isSupported() {
try {
let params = GLib.Variant.new('(ss)', ['org.gnome.DisplayManager.Manager', 'Version']);
let result = Gio.DBus.system.call_sync('org.gnome.DisplayManager',
'/org/gnome/DisplayManager/Manager',
'org.freedesktop.DBus.Properties',
'Get', params, null,
Gio.DBusCallFlags.NONE,
-1, null);
let version = result.deep_unpack()[0].deep_unpack();
return versionCompare('3.5.91', version);
} catch(e) {
return false;
}
}
const UnlockDialog = new Lang.Class({
Name: 'UnlockDialog',
Extends: ModalDialog.ModalDialog,
@ -76,6 +47,7 @@ const UnlockDialog = new Lang.Class({
this._greeterClient = new Gdm.Client();
this._userVerifier = new GdmUtil.ShellUserVerifier(this._greeterClient, { reauthenticationOnly: true });
this._userVerified = false;
this._userVerifier.connect('ask-question', Lang.bind(this, this._onAskQuestion));
this._userVerifier.connect('show-message', Lang.bind(this, this._showMessage));
@ -98,6 +70,7 @@ const UnlockDialog = new Lang.Class({
this._promptEntry = new St.Entry({ style_class: 'login-dialog-prompt-entry',
can_focus: true });
this._promptEntry.clutter_text.connect('activate', Lang.bind(this, this._doUnlock));
this._promptEntry.clutter_text.set_password_char('\u25cf');
ShellEntry.addContextMenu(this._promptEntry, { isPassword: true });
this.setInitialKeyFocus(this._promptEntry);
@ -169,11 +142,6 @@ const UnlockDialog = new Lang.Class({
let batch = new Batch.Hold();
this._userVerifier.begin(this._userName, batch);
GLib.idle_add(GLib.PRIORITY_DEFAULT, Lang.bind(this, function() {
this.emit('loaded');
return false;
}));
Main.ctrlAltTabManager.addGroup(this.dialogLayout, _("Unlock Window"), 'dialog-password-symbolic');
this._idleMonitor = new GnomeDesktop.IdleMonitor();
@ -282,18 +250,35 @@ const UnlockDialog = new Lang.Class({
this._userVerifier.answerQuery(query, this._promptEntry.text);
},
_onVerificationComplete: function() {
_finishUnlock: function() {
this._userVerifier.clear();
this.emit('unlocked');
},
_onVerificationComplete: function() {
this._userVerified = true;
if (!this._userVerifier.hasPendingMessages) {
this._finishUnlock();
} else {
let signalId = this._userVerifier.connect('no-more-messages',
Lang.bind(this, function() {
this._userVerifier.disconnect(signalId);
this._finishUnlock();
}));
}
},
_onReset: function() {
this.emit('failed');
if (!this._userVerified) {
this._userVerifier.clear();
this.emit('failed');
}
},
_onVerificationFailed: function() {
this._currentQuery = null;
this._firstQuestion = true;
this._userVerified = false;
this._promptEntry.text = '';
this._promptEntry.clutter_text.set_password_char('\u25cf');
@ -333,4 +318,8 @@ const UnlockDialog = new Lang.Class({
this.destroy();
},
addCharacter: function(unichar) {
this._promptEntry.clutter_text.insert_unichar(unichar);
},
});

View File

@ -600,7 +600,8 @@ const UserMenuButton = new Lang.Class({
Lang.bind(this, this._updateHaveShutdown));
Main.sessionMode.connect('updated', Lang.bind(this, this._sessionUpdated));
Main.screenShield.connect('locked-changed', Lang.bind(this, this._updatePresenceIcon));
if (Main.screenShield)
Main.screenShield.connect('locked-changed', Lang.bind(this, this._updatePresenceIcon));
this._sessionUpdated();
},
@ -656,7 +657,7 @@ const UserMenuButton = new Lang.Class({
_updateLockScreen: function() {
let allowLockScreen = !this._lockdownSettings.get_boolean(DISABLE_LOCK_SCREEN_KEY);
this._lockScreenItem.actor.visible = allowLockScreen;
this._lockScreenItem.actor.visible = allowLockScreen && LoginManager.canLock();
},
_updateInstallUpdates: function() {
@ -864,7 +865,8 @@ const UserMenuButton = new Lang.Class({
_onLoginScreenActivate: function() {
this.menu.close(BoxPointer.PopupAnimation.NONE);
Main.overview.hide();
Main.screenShield.lock(false);
if (Main.screenShield)
Main.screenShield.lock(false);
Gdm.goto_login_session_sync(null);
},
@ -915,8 +917,10 @@ const UserMenuButton = new Lang.Class({
session.user.get_real_name() : session.username;
if (session.info.remote)
/* Translators: Remote here refers to a remote session, like a ssh login */
userLabelText = _("%s (remote)").format(userName);
else if (session.info.type == "tty")
/* Translators: Console here refers to a tty like a VT console */
userLabelText = _("%s (console)").format(userName);
else
userLabelText = userName;

View File

@ -11,12 +11,14 @@ const Layout = imports.ui.layout;
const Main = imports.ui.main;
const Panel = imports.ui.panel;
// we could make these gsettings
const FISH_NAME = 'wanda';
const FISH_FILENAME = 'wanda.png';
const FISH_SPEED = 300;
const FISH_COMMAND = 'fortune';
// The size of an individual frame in the animation
const FISH_HEIGHT = 22;
const FISH_WIDTH = 36;
const GNOME_PANEL_PIXMAPDIR = '../gnome-panel/fish';
const FISH_GROUP = 'Fish Animation';
const MAGIC_FISH_KEY = 'free the fish';
@ -26,33 +28,16 @@ const WandaIcon = new Lang.Class({
Extends: IconGrid.BaseIcon,
_init : function(fish, label, params) {
this._fish = fish;
let file = GLib.build_filenamev([global.datadir, GNOME_PANEL_PIXMAPDIR, fish + '.fish']);
if (GLib.file_test(file, GLib.FileTest.EXISTS)) {
this._keyfile = new GLib.KeyFile();
this._keyfile.load_from_file(file, GLib.KeyFileFlags.NONE);
this._imageFile = GLib.build_filenamev([global.datadir, GNOME_PANEL_PIXMAPDIR,
this._keyfile.get_string(FISH_GROUP, 'image')]);
let tmpPixbuf = GdkPixbuf.Pixbuf.new_from_file(this._imageFile);
this._imgHeight = tmpPixbuf.height;
this._imgWidth = tmpPixbuf.width / this._keyfile.get_integer(FISH_GROUP, 'frames');
} else {
this._imageFile = null;
}
this.parent(label, params);
this._fish = fish;
this._imageFile = GLib.build_filenamev([global.datadir, fish + '.png']);
this._imgHeight = FISH_HEIGHT;
this._imgWidth = FISH_WIDTH;
},
createIcon: function(iconSize) {
if (!this._imageFile) {
return new St.Icon({ icon_name: 'face-smile',
icon_size: iconSize });
}
this._animations = new Panel.Animation(this._imageFile, this._imgWidth, this._imgHeight, FISH_SPEED);
this._animations.play();
return this._animations.actor;

View File

@ -174,6 +174,15 @@ const WindowManager = new Lang.Class({
Meta.KeyBindingFlags.NONE,
Shell.KeyBindingMode.NORMAL,
Lang.bind(this, this._openAppMenu));
Main.overview.connect('showing', Lang.bind(this, function() {
for (let i = 0; i < this._dimmedWindows.length; i++)
this._undimWindow(this._dimmedWindows[i]);
}));
Main.overview.connect('hiding', Lang.bind(this, function() {
for (let i = 0; i < this._dimmedWindows.length; i++)
this._dimWindow(this._dimmedWindows[i]);
}));
},
setCustomKeybindingHandler: function(name, modes, handler) {
@ -333,13 +342,15 @@ const WindowManager = new Lang.Class({
if (shouldDim && !window._dimmed) {
window._dimmed = true;
this._dimmedWindows.push(window);
this._dimWindow(window);
if (!Main.overview.visible)
this._dimWindow(window);
} else if (!shouldDim && window._dimmed) {
window._dimmed = false;
this._dimmedWindows = this._dimmedWindows.filter(function(win) {
return win != window;
});
this._undimWindow(window);
if (!Main.overview.visible)
this._undimWindow(window);
}
},

View File

@ -15,7 +15,6 @@ const Main = imports.ui.main;
const Overview = imports.ui.overview;
const Panel = imports.ui.panel;
const Tweener = imports.ui.tweener;
const WindowManager = imports.ui.windowManager;
const FOCUS_ANIMATION_TIME = 0.15;
@ -42,68 +41,6 @@ function _interpolate(start, end, step) {
return start + (end - start) * step;
}
const WindowCloneLayout = new Lang.Class({
Name: 'WindowCloneLayout',
Extends: Clutter.LayoutManager,
_init: function(boundingBox) {
this.parent();
this._boundingBox = boundingBox;
},
get boundingBox() {
return this._boundingBox;
},
set boundingBox(b) {
this._boundingBox = b;
this.layout_changed();
},
_makeBoxForWindow: function(window) {
// We need to adjust the position of the actor because of the
// consequences of invisible borders -- in reality, the texture
// has an extra set of "padding" around it that we need to trim
// down.
// The outer rect (from which we compute the bounding box)
// paradoxically is the smaller rectangle, containing the positions
// of the visible frame. The input rect contains everything,
// including the invisible border padding.
let inputRect = window.get_input_rect();
let box = new Clutter.ActorBox();
box.set_origin(inputRect.x - this._boundingBox.x,
inputRect.y - this._boundingBox.y);
box.set_size(inputRect.width, inputRect.height);
return box;
},
vfunc_get_preferred_height: function(container, forWidth) {
return [this._boundingBox.height, this._boundingBox.height];
},
vfunc_get_preferred_width: function(container, forHeight) {
return [this._boundingBox.width, this._boundingBox.width];
},
vfunc_allocate: function(container, box, flags) {
let clone = container.get_children().forEach(function (child) {
let realWindow;
if (child == container._delegate._windowClone)
realWindow = container._delegate.realWindow;
else
realWindow = child.source;
child.allocate(this._makeBoxForWindow(realWindow.meta_window),
flags);
}, this);
},
});
const WindowClone = new Lang.Class({
Name: 'WindowClone',
@ -113,7 +50,10 @@ const WindowClone = new Lang.Class({
this.metaWindow._delegate = this;
this._workspace = workspace;
this._windowClone = new Clutter.Clone({ source: realWindow.get_texture() });
let [borderX, borderY] = this._getInvisibleBorderPadding();
this._windowClone = new Clutter.Clone({ source: realWindow.get_texture(),
x: -borderX,
y: -borderY });
// We expect this.actor to be used for all interaction rather than
// this._windowClone; as the former is reactive and the latter
// is not, this just works for most cases. However, for DND all
@ -121,15 +61,20 @@ const WindowClone = new Lang.Class({
// To avoid this, we hide it from pick.
Shell.util_set_hidden_from_pick(this._windowClone, true);
this.origX = realWindow.x + borderX;
this.origY = realWindow.y + borderY;
let outerRect = realWindow.meta_window.get_outer_rect();
// The MetaShapedTexture that we clone has a size that includes
// the invisible border; this is inconvenient; rather than trying
// to compensate all over the place we insert a custom container into
// to compensate all over the place we insert a ClutterActor into
// the hierarchy that is sized to only the visible portion.
// As usual, we cannot use a ShellGenericContainer or StWidget here,
// because Workspace plays dirty tricks with reparenting to do DNDs
// and scroll-to-zoom.
this.actor = new Clutter.Actor({ reactive: true,
layout_manager: new WindowCloneLayout() });
x: this.origX,
y: this.origY,
width: outerRect.width,
height: outerRect.height });
this.actor.add_child(this._windowClone);
@ -139,19 +84,10 @@ const WindowClone = new Lang.Class({
this._dragSlot = [0, 0, 0, 0];
this._stackAbove = null;
this._windowClone._updateId = this.realWindow.connect('size-changed',
this._sizeChangedId = this.realWindow.connect('size-changed',
Lang.bind(this, this._onRealWindowSizeChanged));
this._windowClone._destroyId = this.realWindow.connect('destroy', Lang.bind(this, function() {
// First destroy the clone and then destroy everything
// This will ensure that we never see it in the _disconnectSignals loop
this._windowClone.destroy();
this.destroy();
}));
this._updateAttachedDialogs();
this._computeBoundingBox();
this.actor.x = this._boundingBox.x;
this.actor.y = this._boundingBox.y;
this._realWindowDestroyId = this.realWindow.connect('destroy',
Lang.bind(this, this._disconnectRealWindowSignals));
let clickAction = new Clutter.ClickAction();
clickAction.connect('clicked', Lang.bind(this, this._onClicked));
@ -185,95 +121,20 @@ const WindowClone = new Lang.Class({
return this._slot;
},
deleteAll: function() {
// Delete all windows, starting from the bottom-most (most-modal) one
// Find the actor just below us, respecting reparenting done
// by DND code
getActualStackAbove: function() {
if (this._stackAbove == null)
return null;
let windows = this.actor.get_children();
for (let i = windows.length - 1; i >= 1; i--) {
let realWindow = windows[i].source;
let metaWindow = realWindow.meta_window;
metaWindow.delete(global.get_current_time());
}
this.metaWindow.delete(global.get_current_time());
},
addAttachedDialog: function(win) {
this._doAddAttachedDialog(win, win.get_compositor_private());
this._computeBoundingBox();
this._updateDimmer();
this.emit('size-changed');
},
_doAddAttachedDialog: function(metaWin, realWin) {
let clone = new Clutter.Clone({ source: realWin });
clone._updateId = realWin.connect('size-changed', Lang.bind(this, function() {
this._computeBoundingBox();
this.emit('size-changed');
}));
clone._destroyId = realWin.connect('destroy', Lang.bind(this, function() {
clone.destroy();
this._computeBoundingBox();
this._updateDimmer();
this.emit('size-changed');
}));
this.actor.add_child(clone);
},
_updateAttachedDialogs: function() {
let iter = Lang.bind(this, function(win) {
let actor = win.get_compositor_private();
if (!actor)
return false;
if (!win.is_attached_dialog())
return false;
this._doAddAttachedDialog(win, actor);
win.foreach_transient(iter);
return true;
});
this.metaWindow.foreach_transient(iter);
this._dimmer = new WindowManager.WindowDimmer(this._windowClone);
this._updateDimmer();
},
_updateDimmer: function() {
if (this.actor.get_n_children() > 1) {
this._dimmer.setEnabled(true);
this._dimmer.dimFactor = 1.0;
} else {
this._dimmer.setEnabled(false);
}
},
get boundingBox() {
return this._boundingBox;
},
getOriginalPosition: function() {
return [this._boundingBox.x, this._boundingBox.y];
},
_computeBoundingBox: function() {
let rect = this.metaWindow.get_outer_rect();
this.actor.get_children().forEach(function (child) {
let realWindow;
if (child == this._windowClone)
realWindow = this.realWindow;
if (this.inDrag || this._zooming) {
if (this._stackAbove._delegate)
return this._stackAbove._delegate.getActualStackAbove();
else
realWindow = child.source;
let metaWindow = realWindow.meta_window;
rect = rect.union(metaWindow.get_outer_rect());
}, this);
this._boundingBox = rect;
this.actor.layout_manager.boundingBox = rect;
return null;
} else {
return this._stackAbove;
}
},
setStackAbove: function (actor) {
@ -281,36 +142,56 @@ const WindowClone = new Lang.Class({
if (this.inDrag)
// We'll fix up the stack after the drag
return;
if (this._stackAbove == null)
let actualAbove = this.getActualStackAbove();
if (actualAbove == null)
this.actor.lower_bottom();
else
this.actor.raise(this._stackAbove);
this.actor.raise(actualAbove);
},
destroy: function () {
this.actor.destroy();
},
_disconnectSignals: function() {
this.actor.get_children().forEach(Lang.bind(this, function (child) {
let realWindow;
if (child == this._windowClone)
realWindow = this.realWindow;
else
realWindow = child.source;
_disconnectRealWindowSignals: function() {
if (this._sizeChangedId > 0)
this.realWindow.disconnect(this._sizeChangedId);
this._sizeChangedId = 0;
realWindow.disconnect(child._updateId);
realWindow.disconnect(child._destroyId);
}));
if (this._realWindowDestroyId > 0)
this.realWindow.disconnect(this._realWindowDestroyId);
this._realWindowDestroyId = 0;
},
_getInvisibleBorderPadding: function() {
// We need to adjust the position of the actor because of the
// consequences of invisible borders -- in reality, the texture
// has an extra set of "padding" around it that we need to trim
// down.
// The outer rect paradoxically is the smaller rectangle,
// containing the positions of the visible frame. The input
// rect contains everything, including the invisible border
// padding.
let outerRect = this.metaWindow.get_outer_rect();
let inputRect = this.metaWindow.get_input_rect();
let [borderX, borderY] = [outerRect.x - inputRect.x,
outerRect.y - inputRect.y];
return [borderX, borderY];
},
_onRealWindowSizeChanged: function() {
this._computeBoundingBox();
let [borderX, borderY] = this._getInvisibleBorderPadding();
let outerRect = this.metaWindow.get_outer_rect();
this.actor.set_size(outerRect.width, outerRect.height);
this._windowClone.set_position(-borderX, -borderY);
this.emit('size-changed');
},
_onDestroy: function() {
this._disconnectSignals();
this._disconnectRealWindowSignals();
this.metaWindow._delegate = null;
this.actor._delegate = null;
@ -569,7 +450,7 @@ const WindowOverlay = new Lang.Class({
Lang.bind(this,
this._onWindowAdded));
this._windowClone.deleteAll();
metaWindow.delete(global.get_current_time());
},
_onWindowAdded: function(workspace, win) {
@ -1045,7 +926,7 @@ const Workspace = new Lang.Class({
this._windowOverlays = [];
for (let i = 0; i < windows.length; i++) {
if (this._isOverviewWindow(windows[i])) {
this._addWindowClone(windows[i]);
this._addWindowClone(windows[i], true);
}
}
@ -1170,11 +1051,23 @@ const Workspace = new Lang.Class({
if (clone.inDrag)
continue;
clone.slot = [x, y, clone.actor.width * scale, clone.actor.height * scale];
let cloneWidth = clone.actor.width * scale;
let cloneHeight = clone.actor.height * scale;
clone.slot = [x, y, cloneWidth, cloneHeight];
if (overlay && initialPositioning)
if (overlay && (initialPositioning || !clone.positioned))
overlay.hide();
if (!clone.positioned) {
// This window appeared after the overview was already up
// Grow the clone from the center of the slot
clone.actor.x = x + cloneWidth / 2;
clone.actor.y = y + cloneHeight / 2;
clone.actor.scale_x = 0;
clone.actor.scale_y = 0;
clone.positioned = true;
}
if (animate && isOnCurrentWorkspace) {
if (!metaWindow.showing_on_its_workspace()) {
/* Hidden windows should fade in and grow
@ -1357,30 +1250,10 @@ const Workspace = new Lang.Class({
if (this._lookupIndex (metaWin) != -1)
return;
if (!this._isMyWindow(win))
if (!this._isMyWindow(win) || !this._isOverviewWindow(win))
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();
let idx = this._lookupIndex (parent);
if (idx < 0) {
// parent was not created yet, it will take care
// of the dialog when created
return;
}
let clone = this._windows[idx];
clone.addAttachedDialog(metaWin);
}
return;
}
let [clone, overlay] = this._addWindowClone(win);
let [clone, overlay] = this._addWindowClone(win, false);
if (win._overviewHint) {
let x = win._overviewHint.x - this.actor.x;
@ -1389,16 +1262,10 @@ const Workspace = new Lang.Class({
delete win._overviewHint;
clone.slot = [x, y, clone.actor.width * scale, clone.actor.height * scale];
clone.positioned = true;
clone.actor.set_position (x, y);
clone.actor.set_scale (scale, scale);
clone.overlay.relayout(false);
} else {
// Position new windows at the top corner of the workspace rather
// than where they were placed for real to avoid the window
// being clipped to the workspaceView. Its not really more
// natural for the window to suddenly appear in the overview
// on some seemingly random location anyway.
clone.actor.set_position (this._x, this._y);
}
this._currentLayout = null;
@ -1478,11 +1345,9 @@ const Workspace = new Lang.Class({
overlay.hide();
if (clone.metaWindow.showing_on_its_workspace()) {
let [origX, origY] = clone.getOriginalPosition();
Tweener.addTween(clone.actor,
{ x: origX,
y: origY,
{ x: clone.origX,
y: clone.origY,
scale_x: 1.0,
scale_y: 1.0,
time: Overview.ANIMATION_TIME,
@ -1547,10 +1412,11 @@ const Workspace = new Lang.Class({
},
// Create a clone of a (non-desktop) window and add it to the window list
_addWindowClone : function(win) {
_addWindowClone : function(win, positioned) {
let clone = new WindowClone(win, this);
let overlay = new WindowOverlay(clone, this._windowOverlaysGroup);
clone.overlay = overlay;
clone.positioned = positioned;
clone.connect('selected',
Lang.bind(this, this._onCloneSelected));

View File

@ -13,7 +13,6 @@ const Background = imports.ui.background;
const DND = imports.ui.dnd;
const Main = imports.ui.main;
const Tweener = imports.ui.tweener;
const WindowManager = imports.ui.windowManager;
const Workspace = imports.ui.workspace;
const WorkspacesView = imports.ui.workspacesView;
@ -32,49 +31,20 @@ const WORKSPACE_KEEP_ALIVE_TIME = 100;
const OVERRIDE_SCHEMA = 'org.gnome.shell.overrides';
/* A layout manager that requests size only for primary_actor, but then allocates
all using a fixed layout */
const PrimaryActorLayout = new Lang.Class({
Name: 'PrimaryActorLayout',
Extends: Clutter.FixedLayout,
_init: function(primaryActor) {
this.parent();
this.primaryActor = primaryActor;
},
vfunc_get_preferred_width: function(forHeight) {
return this.primaryActor.get_preferred_width(forHeight);
},
vfunc_get_preferred_height: function(forWidth) {
return this.primaryActor.get_preferred_height(forWidth);
},
});
const WindowClone = new Lang.Class({
Name: 'WindowClone',
_init : function(realWindow) {
this.clone = new Clutter.Clone({ source: realWindow });
/* Can't use a Shell.GenericContainer because of DND and reparenting... */
this.actor = new Clutter.Actor({ layout_manager: new PrimaryActorLayout(this.clone),
this.actor = new Clutter.Clone({ source: realWindow.get_texture(),
reactive: true });
this.actor._delegate = this;
this.actor.add_child(this.clone);
this.realWindow = realWindow;
this.metaWindow = realWindow.meta_window;
this.clone._updateId = this.realWindow.connect('position-changed',
Lang.bind(this, this._onPositionChanged));
this.clone._destroyId = this.realWindow.connect('destroy', Lang.bind(this, function() {
// First destroy the clone and then destroy everything
// This will ensure that we never see it in the _disconnectSignals loop
this.clone.destroy();
this.destroy();
}));
this._positionChangedId = this.realWindow.connect('position-changed',
Lang.bind(this, this._onPositionChanged));
this._realWindowDestroyedId = this.realWindow.connect('destroy',
Lang.bind(this, this._disconnectRealWindowSignals));
this._onPositionChanged();
this.actor.connect('button-release-event',
@ -90,89 +60,62 @@ const WindowClone = new Lang.Class({
this._draggable.connect('drag-cancelled', Lang.bind(this, this._onDragCancelled));
this._draggable.connect('drag-end', Lang.bind(this, this._onDragEnd));
this.inDrag = false;
},
let iter = Lang.bind(this, function(win) {
let actor = win.get_compositor_private();
// Find the actor just below us, respecting reparenting done
// by DND code
getActualStackAbove: function() {
if (this._stackAbove == null)
return null;
if (!actor)
return false;
if (!win.is_attached_dialog())
return false;
this._doAddAttachedDialog(win, actor);
win.foreach_transient(iter);
return true;
});
this.metaWindow.foreach_transient(iter);
this._dimmer = new WindowManager.WindowDimmer(this.clone);
this._updateDimmer();
if (this.inDrag) {
if (this._stackAbove._delegate)
return this._stackAbove._delegate.getActualStackAbove();
else
return null;
} else {
return this._stackAbove;
}
},
setStackAbove: function (actor) {
this._stackAbove = actor;
if (this._stackAbove == null)
// Don't apply the new stacking now, it will be applied
// when dragging ends and window are stacked again
if (actor.inDrag)
return;
let actualAbove = this.getActualStackAbove();
if (actualAbove == null)
this.actor.lower_bottom();
else
this.actor.raise(this._stackAbove);
this.actor.raise(actualAbove);
},
destroy: function () {
this.actor.destroy();
},
addAttachedDialog: function(win) {
this._doAddAttachedDialog(win, win.get_compositor_private());
this._updateDimmer();
},
_doAddAttachedDialog: function(metaDialog, realDialog) {
let clone = new Clutter.Clone({ source: realDialog });
this._updateDialogPosition(realDialog, clone);
clone._updateId = realDialog.connect('position-changed',
Lang.bind(this, this._updateDialogPosition, clone));
clone._destroyId = realDialog.connect('destroy', Lang.bind(this, function() {
clone.destroy();
this._updateDimmer();
}));
this.actor.add_child(clone);
},
_updateDimmer: function() {
if (this.actor.get_n_children() > 1) {
this._dimmer.setEnabled(true);
this._dimmer.dimFactor = 1.0;
} else {
this._dimmer.setEnabled(false);
}
},
_updateDialogPosition: function(realDialog, cloneDialog) {
let metaDialog = realDialog.meta_window;
let dialogRect = metaDialog.get_outer_rect();
let rect = this.metaWindow.get_outer_rect();
cloneDialog.set_position(dialogRect.x - rect.x, dialogRect.y - rect.y);
},
_onPositionChanged: function() {
let rect = this.metaWindow.get_outer_rect();
this.actor.set_position(this.realWindow.x, this.realWindow.y);
},
_disconnectSignals: function() {
this.actor.get_children().forEach(function(child) {
let realWindow = child.source;
_disconnectRealWindowSignals: function() {
if (this._positionChangedId != 0) {
this.realWindow.disconnect(this._positionChangedId);
this._positionChangedId = 0;
}
realWindow.disconnect(child._updateId);
realWindow.disconnect(child._destroyId);
});
if (this._realWindowDestroyedId != 0) {
this.realWindow.disconnect(this._realWindowDestroyedId);
this._realWindowDestroyedId = 0;
}
},
_onDestroy: function() {
this._disconnectSignals();
this._disconnectRealWindowSignals();
this.actor._delegate = null;
@ -400,26 +343,10 @@ const WorkspaceThumbnail = new Lang.Class({
if (this._lookupIndex (metaWin) != -1)
return;
if (!this._isMyWindow(win))
if (!this._isMyWindow(win) || !this._isOverviewWindow(win))
return;
if (this._isOverviewWindow(win)) {
this._addWindowClone(win);
} else if (metaWin.is_attached_dialog()) {
let parent = metaWin.get_transient_for();
while (parent.is_attached_dialog())
parent = metaWin.get_transient_for();
let idx = this._lookupIndex (parent);
if (idx < 0) {
// parent was not created yet, it will take care
// of the dialog when created
return;
}
let clone = this._windows[idx];
clone.addAttachedDialog(metaWin);
}
let clone = this._addWindowClone(win);
},
_windowAdded : function(metaWorkspace, metaWin) {
@ -457,9 +384,8 @@ const WorkspaceThumbnail = new Lang.Class({
},
destroy : function() {
this.actor.destroy();
this._bgManager.destroy();
this._bgManager = null;
if (this.actor)
this.actor.destroy();
},
workspaceRemoved : function() {
@ -480,6 +406,11 @@ const WorkspaceThumbnail = new Lang.Class({
_onDestroy: function(actor) {
this.workspaceRemoved();
if (this._bgManager) {
this._bgManager.destroy();
this._bgManager = null;
}
this._windows = [];
this.actor = null;
},
@ -631,6 +562,7 @@ const ThumbnailsBox = new Lang.Class({
this._dropPlaceholderPos = -1;
this._dropPlaceholder = new St.Bin({ style_class: 'placeholder' });
this.actor.add_actor(this._dropPlaceholder);
this._spliceIndex = -1;
this._targetScale = 0;
this._scale = 0;
@ -813,6 +745,8 @@ const ThumbnailsBox = new Lang.Class({
return win.get_workspace() >= newWorkspaceIndex;
});
this._spliceIndex = newWorkspaceIndex;
// ... move them down one.
windows.forEach(function(win) {
win.meta_window.change_workspace_by_index(win.get_workspace() + 1,
@ -834,6 +768,14 @@ const ThumbnailsBox = new Lang.Class({
WORKSPACE_KEEP_ALIVE_TIME);
}
// Start the animation on the workspace (which is actually
// an old one which just became empty)
let thumbnail = this._thumbnails[newWorkspaceIndex];
this._setThumbnailState(thumbnail, ThumbnailState.NEW);
thumbnail.slidePosition = 1;
this._queueUpdateStates();
return true;
} else {
return false;
@ -921,7 +863,8 @@ const ThumbnailsBox = new Lang.Class({
this._thumbnails.push(thumbnail);
this.actor.add_actor(thumbnail.actor);
if (start > 0) { // not the initial fill
if (start > 0 && this._spliceIndex == -1) {
// not the initial fill, and not splicing via DND
thumbnail.state = ThumbnailState.NEW;
thumbnail.slidePosition = 1; // start slid out
this._haveNewThumbnails = true;
@ -936,6 +879,9 @@ const ThumbnailsBox = new Lang.Class({
// The thumbnails indicator actually needs to be on top of the thumbnails
this._indicator.raise_top();
// Clear the splice index, we got the message
this._spliceIndex = -1;
},
removeThumbnails: function(start, count) {

View File

@ -386,6 +386,15 @@ const WorkspacesView = new Lang.Class({
let current = Math.round(adj.value);
if (active != current) {
if (!this._workspaces[current]) {
// The current workspace was destroyed. This could happen
// when you are on the last empty workspace, and consolidate
// windows using the thumbnail bar.
// In that case, the intended behavior is to stay on the empty
// workspace, which is the last one, so pick it.
current = this._workspaces.length - 1;
}
let metaWorkspace = this._workspaces[current].metaWorkspace;
metaWorkspace.activate(global.get_current_time());
}

View File

@ -60,6 +60,7 @@ sr@latin
sv
ta
te
tg
th
tr
ug

2226
po/an.po

File diff suppressed because it is too large Load Diff

895
po/ar.po

File diff suppressed because it is too large Load Diff

829
po/as.po

File diff suppressed because it is too large Load Diff

826
po/be.po

File diff suppressed because it is too large Load Diff

647
po/ca.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

559
po/cs.po

File diff suppressed because it is too large Load Diff

1091
po/da.po

File diff suppressed because it is too large Load Diff

903
po/de.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

275
po/et.po
View File

@ -13,8 +13,8 @@ msgstr ""
"Project-Id-Version: gnome-shell MASTER\n"
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-"
"shell&keywords=I18N+L10N&component=general\n"
"POT-Creation-Date: 2012-12-09 13:03+0000\n"
"PO-Revision-Date: 2012-12-19 16:47+0300\n"
"POT-Creation-Date: 2013-03-11 22:02+0000\n"
"PO-Revision-Date: 2013-03-12 16:28+0300\n"
"Last-Translator: Mattias Põldaru <mahfiaz@gmail.com>\n"
"Language-Team: Estonian <>\n"
"Language: et\n"
@ -104,6 +104,16 @@ msgid ""
"favorites area."
msgstr "Nendele tunnustele vastavaid rakendusi kuvatakse lemmikutes."
msgid "List of categories that should be displayed as folders"
msgstr "Kategooriad, mida tuleb kuvada kaustadena"
msgid ""
"Each category name in this list will be represented as folder in the "
"application view, rather than being displayed inline in the main view."
msgstr ""
"Kõiki selles loetelus olevaid kategooriaid kuvatakse rakenduste vaates "
"kaustadena, mitte peavaates teistega koos."
msgid "History for command (Alt-F2) dialog"
msgstr "Käsudialoogi (Alt-F2) ajalugu"
@ -135,12 +145,6 @@ msgstr ""
"See võti keelab automaatse 'Logi välja' menüükirje peitmise, kui arvutis on "
"üks kasutaja ning avatud üks seanss."
msgid "Show full name in the user menu"
msgstr "Kasutajamenüüs näidatakse kasutaja tervet nime"
msgid "Whether the users full name is shown in the user menu or not."
msgstr "Kas kasutajamenüüs näidatakse kasutaja kogu nime või mitte."
msgid ""
"Whether to remember password for mounting encrypted or remote filesystems"
msgstr ""
@ -299,12 +303,8 @@ msgstr "Laiendus"
msgid "Select an extension to configure using the combobox above."
msgstr "Vali seadistatav laiendus kasutades ülemist valikukasti."
msgid "Session..."
msgstr "Seanss..."
msgctxt "title"
msgid "Sign In"
msgstr "Sisselogimine"
msgid "Session"
msgstr "Seanss"
#. translators: this message is shown below the user list on the
#. login screen. It can be activated to reveal an entry for
@ -368,16 +368,12 @@ msgstr "Käsku pole võimalik analüüsida:"
msgid "Execution of '%s' failed:"
msgstr "'%s' käivitamine nurjus:"
#. Translators: Filter to display all applications
msgid "Frequent"
msgstr "Sage"
msgid "All"
msgstr "Kõik"
msgid "APPLICATIONS"
msgstr "RAKENDUSED"
msgid "SETTINGS"
msgstr "SEADED"
msgid "New Window"
msgstr "Uus aken"
@ -395,6 +391,12 @@ msgstr "%s lisati lemmikutesse."
msgid "%s has been removed from your favorites."
msgstr "%s eemaldati lemmikutest."
msgid "Settings"
msgstr "Sätted"
msgid "Change Background…"
msgstr "Muuda tausta…"
#. Translators: Shown in calendar event list for all day events
#. * Keep it short, best if you can use less then 10 characters
#.
@ -402,15 +404,18 @@ msgctxt "event list time"
msgid "All Day"
msgstr "Kogu päev"
#. Translators: Shown in calendar event list, if 24h format
#. Translators: Shown in calendar event list, if 24h format,
#. \u2236 is a ratio character, similar to :
msgctxt "event list time"
msgid "%H:%M"
msgstr "%H:%M"
msgid "%H\\u2236%M"
msgstr "%H\\u2236%M"
#. Transators: Shown in calendar event list, if 12h format
#. Transators: Shown in calendar event list, if 12h format,
#. \u2236 is a ratio character, similar to : and \u2009 is
#. a thin space
msgctxt "event list time"
msgid "%l:%M %p"
msgstr "%l:%M %p"
msgid "%l\\u2236%M\\u2009%p"
msgstr "%l\\u2236%M\\u2009%p"
#. Translators: Calendar grid abbreviation for Sunday.
#. *
@ -517,6 +522,12 @@ msgstr "Käesolev nädal"
msgid "Next week"
msgstr "Järgmine nädal"
msgid "External drive connected"
msgstr "Väline ketas ühendati"
msgid "External drive disconnected"
msgstr "Väline ketas eemaldati"
msgid "Removable Devices"
msgstr "Eemaldatavad seadmed"
@ -801,12 +812,20 @@ msgstr "Aknad"
msgid "Show Applications"
msgstr "Rakenduste kuvamine"
msgid "Date and Time Settings"
msgstr "Kuupäeva ja kellaaja sätted"
#. Translators: this is the name of the dock/favorites area on
#. the left of the overview
msgid "Dash"
msgstr "Dokk"
msgid "Open Calendar"
msgstr "Ava kalender"
msgid "Open Clocks"
msgstr "Ava kell"
msgid "Date & Time Settings"
msgstr "Kuupäeva ja kella sätted"
#. Translators: This is the date format to use when the calendar popup is
#. * shown - it is shown just below the time in the shell (e.g. "Tue 9:29 AM").
#.
@ -897,9 +916,6 @@ msgstr "Paigalda"
msgid "Download and install '%s' from extensions.gnome.org?"
msgstr "Kas laadida alla ja paigaldada '%s' aadressilt extensions.gnome.org?"
msgid "tray"
msgstr "salv"
msgid "Keyboard"
msgstr "Klaviatuur"
@ -920,6 +936,8 @@ msgstr "Näita vigu"
msgid "Enabled"
msgstr "Lubatud"
#. translators:
#. * The device has been disabled
msgid "Disabled"
msgstr "Keelatud"
@ -944,6 +962,12 @@ msgstr "Ava"
msgid "Remove"
msgstr "Eemalda"
msgid "Clear Messages"
msgstr "Kustuta teated"
msgid "Notification Settings"
msgstr "Märguannete sätted"
msgid "No Messages"
msgstr "Teateid pole"
@ -957,6 +981,12 @@ msgctxt "program"
msgid "Unknown"
msgstr "Tundmatu"
#, c-format
msgid "%d new message"
msgid_plural "%d new messages"
msgstr[0] "%d uus sõnum"
msgstr[1] "%d uut sõnumit"
msgid "Undo"
msgstr "Võta tagasi"
@ -967,13 +997,8 @@ msgstr "Ülevaade"
#. in the search entry when no search is
#. active; it should not exceed ~30
#. characters.
msgid "Type to search..."
msgstr "Otsing..."
#. Translators: this is the name of the dock/favorites area on
#. the left of the overview
msgid "Dash"
msgstr "Dokk"
msgid "Type to search"
msgstr "Otsing"
msgid "Quit"
msgstr "Sulge"
@ -1005,12 +1030,6 @@ msgstr "Sulge"
msgid "%A, %B %d"
msgstr "%A, %d. %B"
#, c-format
msgid "%d new message"
msgid_plural "%d new messages"
msgstr[0] "%d uus sõnum"
msgstr[1] "%d uut sõnumit"
#, c-format
msgid "%d new notification"
msgid_plural "%d new notifications"
@ -1020,8 +1039,24 @@ msgstr[1] "%d uut märguannet"
msgid "Lock"
msgstr "Lukusta"
msgid "Searching..."
msgstr "Otsimine..."
msgid "GNOME needs to lock the screen"
msgstr "GNOME peab ekraani lukustama"
#. We could not become modal, so we can't activate the
#. screenshield. The user is probably very upset at this
#. point, but any application using global grabs is broken
#. Just tell him to stop using this app
#.
#. XXX: another option is to kick the user into the gdm login
#. screen, where we're not affected by grabs
msgid "Unable to lock"
msgstr "Pole võimalik lukustada"
msgid "Lock was blocked by an application"
msgstr "Rakendus blokeeris lukustamise"
msgid "Searching…"
msgstr "Otsing…"
msgid "No results."
msgstr "Tulemused puuduvad."
@ -1089,11 +1124,11 @@ msgstr "Bluetooth"
msgid "Visibility"
msgstr "Nähtavus"
msgid "Send Files to Device..."
msgstr "Failide saatmine seadmesse..."
msgid "Send Files to Device"
msgstr "Failide saatmine seadmesse"
msgid "Set up a New Device..."
msgstr "Uue seadme häälestamine..."
msgid "Set Up a New Device"
msgstr "Uue seadme häälestamine"
msgid "Bluetooth Settings"
msgstr "Bluetoothi sätted"
@ -1111,8 +1146,8 @@ msgstr "ühenduse katkestamine..."
msgid "connecting..."
msgstr "ühendumine..."
msgid "Send Files..."
msgstr "Failide saatmine..."
msgid "Send Files"
msgstr "Failide saatmine"
msgid "Keyboard Settings"
msgstr "Klaviatuurisätted"
@ -1173,7 +1208,7 @@ msgstr "Olgu"
msgid "Show Keyboard Layout"
msgstr "Klaviatuuripaigutuse kuvamine"
msgid "Region and Language Settings"
msgid "Region & Language Settings"
msgstr "Asukoha ja keele sätted"
msgid "Volume, network, battery"
@ -1212,17 +1247,23 @@ msgstr "pole saadaval"
msgid "connection failed"
msgstr "ühendumine nurjus"
msgid "More..."
msgstr "Veel..."
msgid "More"
msgstr "Veel"
#. TRANSLATORS: this is the indication that a connection for another logged in user is active,
#. and we cannot access its settings (including the name)
msgid "Connected (private)"
msgstr "Ühendatud (privaatne)"
msgid "Wired"
msgstr "Juhtmega"
msgid "Auto Ethernet"
msgstr "Automaatne ethernet"
msgid "Mobile broadband"
msgstr "Mobiiliühendus"
msgid "Auto broadband"
msgstr "Automaatne lairibaühendus"
@ -1269,8 +1310,8 @@ msgstr "Toitesätted..."
#. 0 is reported when UPower does not have enough data
#. to estimate battery life
msgid "Estimating..."
msgstr "Andmete kogumine..."
msgid "Estimating"
msgstr "Andmete kogumine"
#, c-format
msgid "%d hour remaining"
@ -1304,10 +1345,10 @@ msgctxt "percent of battery remaining"
msgid "%d%%"
msgstr "%d%%"
msgid "AC adapter"
msgstr "Võrgutoite adapter"
msgid "AC Adapter"
msgstr "Laadija"
msgid "Laptop battery"
msgid "Laptop Battery"
msgstr "Sülearvuti aku"
msgid "UPS"
@ -1322,10 +1363,10 @@ msgstr "Hiir"
msgid "PDA"
msgstr "Elektronmärkmik"
msgid "Cell phone"
msgid "Cell Phone"
msgstr "Mobiiltelefon"
msgid "Media player"
msgid "Media Player"
msgstr "Meediaesitaja"
msgid "Tablet"
@ -1338,6 +1379,9 @@ msgctxt "device"
msgid "Unknown"
msgstr "Tundmatu"
msgid "Volume changed"
msgstr "Helivaljus muutus"
#. Translators: This is the label for audio volume
msgid "Volume"
msgstr "Helivaljus"
@ -1372,9 +1416,6 @@ msgstr "Ühendamata"
msgid "Notifications"
msgstr "Märguanded"
msgid "Settings"
msgstr "Sätted"
msgid "Switch User"
msgstr "Vaheta kasutajat"
@ -1394,6 +1435,22 @@ msgstr ""
"Märguanded on nüüd keelatud, sealhulgas vestlusteated. Sinu netiolekut "
"muudeti, et teised teaksid, et sa ei pruugi nende teateid näha."
msgid "Other users are logged in."
msgstr "Teised kasutajad on sisse logitud."
msgid "Shutting down might cause them to lose unsaved work."
msgstr "Väljalülitamine võib põhjustada salvestamata töö kaotsimineku."
#. Translators: Remote here refers to a remote session, like a ssh login
#, c-format
msgid "%s (remote)"
msgstr "%s (kaugühendus)"
#. Translators: Console here refers to a tty like a VT console
#, c-format
msgid "%s (console)"
msgstr "%s (konsool)"
msgid "Applications"
msgstr "Rakendused"
@ -1412,9 +1469,6 @@ msgstr ""
msgid "%s the Oracle says"
msgstr "Oraakel %s ütleb"
msgid "Your favorite Easter Egg"
msgstr "Sinu lemmiküllatusmuna"
#, c-format
msgid "'%s' is ready"
msgstr "'%s' on valmis"
@ -1422,6 +1476,25 @@ msgstr "'%s' on valmis"
msgid "Evolution Calendar"
msgstr "Evolutioni kalender"
#. translators:
#. * The number of sound outputs on a particular device
#, c-format
msgid "%u Output"
msgid_plural "%u Outputs"
msgstr[0] "%u väljund"
msgstr[1] "%u väljundit"
#. translators:
#. * The number of sound inputs on a particular device
#, c-format
msgid "%u Input"
msgid_plural "%u Inputs"
msgstr[0] "%u sisend"
msgstr[1] "%u sisendit"
msgid "System Sounds"
msgstr "Süsteemi helid"
msgid "Print version"
msgstr "Printimise versioon"
@ -1444,15 +1517,48 @@ msgstr "Paroolid ei kattu."
msgid "Password cannot be blank"
msgstr "Parool ei saa olla tühi"
msgid "United Kingdom"
msgstr "Suurbritannia"
msgid "Default"
msgstr "Vaikimisi"
msgid "Authentication dialog was dismissed by the user"
msgstr "Kasutaja katkestas autentimisdialoogi"
#~ msgid "Show full name in the user menu"
#~ msgstr "Kasutajamenüüs näidatakse kasutaja tervet nime"
#~ msgid "Whether the users full name is shown in the user menu or not."
#~ msgstr "Kas kasutajamenüüs näidatakse kasutaja kogu nime või mitte."
#~ msgctxt "title"
#~ msgid "Sign In"
#~ msgstr "Sisselogimine"
#~ msgid "APPLICATIONS"
#~ msgstr "RAKENDUSED"
#~ msgid "SETTINGS"
#~ msgstr "SEADED"
#~ msgctxt "event list time"
#~ msgid "%H:%M"
#~ msgstr "%H:%M"
#~ msgctxt "event list time"
#~ msgid "%l:%M %p"
#~ msgstr "%l:%M %p"
#~ msgid "tray"
#~ msgstr "salv"
#~ msgid "More..."
#~ msgstr "Veel..."
#~ msgid "Your favorite Easter Egg"
#~ msgstr "Sinu lemmiküllatusmuna"
#~ msgid "United Kingdom"
#~ msgstr "Suurbritannia"
#~ msgid "Default"
#~ msgstr "Vaikimisi"
#~ msgid "Subscription request"
#~ msgstr "Tellimuse päring"
@ -1471,28 +1577,9 @@ msgstr "Kasutaja katkestas autentimisdialoogi"
#~ msgid "Reconnect"
#~ msgstr "Ühendu uuesti"
#~ msgid "Wired"
#~ msgstr "Juhtmega"
#~ msgid "Wireless"
#~ msgstr "Juhtmeta"
#~ msgid "Mobile broadband"
#~ msgstr "Mobiiliühendus"
#~ msgid "%u Output"
#~ msgid_plural "%u Outputs"
#~ msgstr[0] "%u väljund"
#~ msgstr[1] "%u väljundit"
#~ msgid "%u Input"
#~ msgid_plural "%u Inputs"
#~ msgstr[0] "%u sisend"
#~ msgstr[1] "%u sisendit"
#~ msgid "System Sounds"
#~ msgstr "Süsteemi helid"
#~ msgid "disabled OpenSearch providers"
#~ msgstr "keelatud OpenSearch pakkujad"

611
po/eu.po

File diff suppressed because it is too large Load Diff

1102
po/fa.po

File diff suppressed because it is too large Load Diff

1102
po/fi.po

File diff suppressed because it is too large Load Diff

1095
po/fr.po

File diff suppressed because it is too large Load Diff

758
po/gu.po

File diff suppressed because it is too large Load Diff

1125
po/hi.po

File diff suppressed because it is too large Load Diff

900
po/hu.po

File diff suppressed because it is too large Load Diff

1019
po/id.po

File diff suppressed because it is too large Load Diff

763
po/ja.po

File diff suppressed because it is too large Load Diff

865
po/kk.po

File diff suppressed because it is too large Load Diff

1193
po/kn.po

File diff suppressed because it is too large Load Diff

1044
po/ko.po

File diff suppressed because it is too large Load Diff

664
po/lt.po

File diff suppressed because it is too large Load Diff

1104
po/lv.po

File diff suppressed because it is too large Load Diff

784
po/ml.po

File diff suppressed because it is too large Load Diff

1133
po/mr.po

File diff suppressed because it is too large Load Diff

157
po/nb.po
View File

@ -6,10 +6,10 @@
# Torstein Adolf Winterseth <kvikende@fsfe.org>, 2010.
msgid ""
msgstr ""
"Project-Id-Version: gnome-shell 3.7.x\n"
"Project-Id-Version: gnome-shell 3.8.x\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-03-04 14:14+0100\n"
"PO-Revision-Date: 2013-03-04 14:15+0100\n"
"POT-Creation-Date: 2013-04-03 13:31+0200\n"
"PO-Revision-Date: 2013-04-03 13:31+0200\n"
"Last-Translator: Kjartan Maraas <kmaraas@gnome.org>\n"
"Language-Team: Norwegian bokmål <i18n-nb@lister.ping.uio.no>\n"
"Language: \n"
@ -295,7 +295,8 @@ msgstr "Fest modal dialog til opphavsvinduet"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:43
msgid ""
"This key overrides the key in org.gnome.mutter when running GNOME Shell."
msgstr "Denne nøkkelen overstyrer nøkkelen i org.gnome.mutter når GNOME Shell kjøres."
msgstr ""
"Denne nøkkelen overstyrer nøkkelen i org.gnome.mutter når GNOME Shell kjøres."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:44
msgid "Arrangement of buttons on the titlebar"
@ -305,7 +306,9 @@ msgstr "Plassering av knappene på tittellinjen"
msgid ""
"This key overrides the key in org.gnome.desktop.wm.preferences when running "
"GNOME Shell."
msgstr "Denne nøkkelen overstyrer nøkkelen i org.gnome.desktop.wm.preferences når GNOME Shell kjøres."
msgstr ""
"Denne nøkkelen overstyrer nøkkelen i org.gnome.desktop.wm.preferences når "
"GNOME Shell kjøres."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:46
msgid "Enable edge tiling when dropping windows on screen edges"
@ -339,36 +342,36 @@ msgstr "Økt …"
#. 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:629
#: ../js/gdm/loginDialog.js:630
msgid "Not listed?"
msgstr "Ikke listet?"
#: ../js/gdm/loginDialog.js:783 ../js/ui/components/networkAgent.js:137
#: ../js/gdm/loginDialog.js:786 ../js/ui/components/networkAgent.js:137
#: ../js/ui/components/polkitAgent.js:162 ../js/ui/endSessionDialog.js:375
#: ../js/ui/extensionDownloader.js:195 ../js/ui/shellMountOperation.js:399
#: ../js/ui/status/bluetooth.js:415 ../js/ui/unlockDialog.js:126
#: ../js/ui/userMenu.js:934
#: ../js/ui/status/bluetooth.js:415 ../js/ui/unlockDialog.js:99
#: ../js/ui/userMenu.js:938
msgid "Cancel"
msgstr "Avbryt"
#: ../js/gdm/loginDialog.js:799
#: ../js/gdm/loginDialog.js:802
msgctxt "button"
msgid "Sign In"
msgstr "Logg inn"
#: ../js/gdm/loginDialog.js:799
#: ../js/gdm/loginDialog.js:802
msgid "Next"
msgstr "Neste"
#. 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:904 ../js/ui/components/networkAgent.js:260
#: ../js/gdm/loginDialog.js:917 ../js/ui/components/networkAgent.js:260
#: ../js/ui/components/networkAgent.js:278
msgid "Username: "
msgstr "Brukernavn: "
#: ../js/gdm/loginDialog.js:1157
#: ../js/gdm/loginDialog.js:1173
msgid "Login Window"
msgstr "Innloggingsvindu"
@ -377,8 +380,8 @@ msgstr "Innloggingsvindu"
msgid "Power"
msgstr "Strøm"
#: ../js/gdm/powerMenu.js:93 ../js/ui/userMenu.js:695 ../js/ui/userMenu.js:699
#: ../js/ui/userMenu.js:815
#: ../js/gdm/powerMenu.js:93 ../js/ui/userMenu.js:696 ../js/ui/userMenu.js:700
#: ../js/ui/userMenu.js:816
msgid "Suspend"
msgstr "Hvilemodus"
@ -386,58 +389,58 @@ msgstr "Hvilemodus"
msgid "Restart"
msgstr "Start på nytt"
#: ../js/gdm/powerMenu.js:103 ../js/ui/userMenu.js:697
#: ../js/ui/userMenu.js:699 ../js/ui/userMenu.js:814 ../js/ui/userMenu.js:938
#: ../js/gdm/powerMenu.js:103 ../js/ui/userMenu.js:698
#: ../js/ui/userMenu.js:700 ../js/ui/userMenu.js:815 ../js/ui/userMenu.js:942
msgid "Power Off"
msgstr "Slå av"
#: ../js/gdm/util.js:182
#: ../js/gdm/util.js:249
msgid "Authentication error"
msgstr "Autentiseringsfeil"
#. Translators: this message is shown below the password entry field
#. to indicate the user can swipe their finger instead
#: ../js/gdm/util.js:299
#: ../js/gdm/util.js:366
msgid "(or swipe finger)"
msgstr "(eller dra finger)"
#: ../js/gdm/util.js:324
#: ../js/gdm/util.js:391
#, c-format
msgid "(e.g., user or %s)"
msgstr "(f.eks. bruker eller %s)"
#: ../js/misc/util.js:94
#: ../js/misc/util.js:97
msgid "Command not found"
msgstr "Kommando ikke funnet"
#. Replace "Error invoking GLib.shell_parse_argv: " with
#. something nicer
#: ../js/misc/util.js:127
#: ../js/misc/util.js:130
msgid "Could not parse command:"
msgstr "Klarte ikke å lese kommando:"
#: ../js/misc/util.js:135
#: ../js/misc/util.js:138
#, c-format
msgid "Execution of '%s' failed:"
msgstr "Kjøring av «%s» feilet:"
#: ../js/ui/appDisplay.js:348
#: ../js/ui/appDisplay.js:349
msgid "Frequent"
msgstr "Ofte"
#: ../js/ui/appDisplay.js:355
#: ../js/ui/appDisplay.js:356
msgid "All"
msgstr "Alle"
#: ../js/ui/appDisplay.js:913
#: ../js/ui/appDisplay.js:914
msgid "New Window"
msgstr "Nytt vindu"
#: ../js/ui/appDisplay.js:916 ../js/ui/dash.js:284
#: ../js/ui/appDisplay.js:917 ../js/ui/dash.js:284
msgid "Remove from Favorites"
msgstr "Fjern fra favoritter"
#: ../js/ui/appDisplay.js:917
#: ../js/ui/appDisplay.js:918
msgid "Add to Favorites"
msgstr "Legg til i favoritter"
@ -451,7 +454,7 @@ msgstr "%s ble lagt til i dine favoritter."
msgid "%s has been removed from your favorites."
msgstr "%s ble fjernet fra dine favoritter."
#: ../js/ui/backgroundMenu.js:19 ../js/ui/userMenu.js:788
#: ../js/ui/backgroundMenu.js:19 ../js/ui/userMenu.js:789
msgid "Settings"
msgstr "Innstillinger"
@ -474,7 +477,7 @@ msgctxt "event list time"
msgid "%H\\u2236%M"
msgstr "%H\\u2336%M"
#. Transators: Shown in calendar event list, if 12h format,
#. Translators: Shown in calendar event list, if 12h format,
#. \u2236 is a ratio character, similar to : and \u2009 is
#. a thin space
#: ../js/ui/calendar.js:77
@ -576,35 +579,35 @@ msgid "S"
msgstr "Lø"
#. Translators: Text to show if there are no events
#: ../js/ui/calendar.js:692
#: ../js/ui/calendar.js:720
msgid "Nothing Scheduled"
msgstr "Ingenting planlagt"
#. Translators: Shown on calendar heading when selected day occurs on current year
#: ../js/ui/calendar.js:708
#: ../js/ui/calendar.js:736
msgctxt "calendar heading"
msgid "%A, %B %d"
msgstr "%A %B %d"
#. Translators: Shown on calendar heading when selected day occurs on different year
#: ../js/ui/calendar.js:711
#: ../js/ui/calendar.js:739
msgctxt "calendar heading"
msgid "%A, %B %d, %Y"
msgstr "%A %B %d, %Y"
#: ../js/ui/calendar.js:721
#: ../js/ui/calendar.js:749
msgid "Today"
msgstr "I dag"
#: ../js/ui/calendar.js:725
#: ../js/ui/calendar.js:753
msgid "Tomorrow"
msgstr "I morgen"
#: ../js/ui/calendar.js:736
#: ../js/ui/calendar.js:764
msgid "This week"
msgstr "Denne uken"
#: ../js/ui/calendar.js:744
#: ../js/ui/calendar.js:772
msgid "Next week"
msgstr "Neste uke"
@ -620,12 +623,12 @@ msgstr "Ekstern stasjon koblet fra"
msgid "Removable Devices"
msgstr "Avtagbare enheter"
#: ../js/ui/components/autorunManager.js:593
#: ../js/ui/components/autorunManager.js:594
#, c-format
msgid "Open with %s"
msgstr "Åpne med %s"
#: ../js/ui/components/autorunManager.js:619
#: ../js/ui/components/autorunManager.js:620
msgid "Eject"
msgstr "Løs ut"
@ -1007,7 +1010,7 @@ msgstr "Innstillinger for dato og klokkeslett"
#. Translators: This is the date format to use when the calendar popup is
#. * shown - it is shown just below the time in the shell (e.g. "Tue 9:29 AM").
#.
#: ../js/ui/dateMenu.js:205
#: ../js/ui/dateMenu.js:215
msgid "%A %B %e, %Y"
msgstr "%a %e %B, %Y"
@ -1181,15 +1184,15 @@ msgstr "Tøm meldinger"
msgid "Notification Settings"
msgstr "Innstillinger for varsling"
#: ../js/ui/messageTray.js:1707
#: ../js/ui/messageTray.js:1709
msgid "No Messages"
msgstr "Ingen meldinger"
#: ../js/ui/messageTray.js:1787
#: ../js/ui/messageTray.js:1782
msgid "Message Tray"
msgstr "Meldingstrau"
#: ../js/ui/messageTray.js:2864
#: ../js/ui/messageTray.js:2810
msgid "System Information"
msgstr "Systeminformasjon"
@ -1198,14 +1201,14 @@ msgctxt "program"
msgid "Unknown"
msgstr "Ukjent"
#: ../js/ui/overviewControls.js:460 ../js/ui/screenShield.js:153
#: ../js/ui/overviewControls.js:463 ../js/ui/screenShield.js:149
#, c-format
msgid "%d new message"
msgid_plural "%d new messages"
msgstr[0] "%d ny melding"
msgstr[1] "%d nye meldinger"
#: ../js/ui/overview.js:82
#: ../js/ui/overview.js:84
msgid "Undo"
msgstr "Angre"
@ -1217,21 +1220,21 @@ msgstr "Oversikt"
#. in the search entry when no search is
#. active; it should not exceed ~30
#. characters.
#: ../js/ui/overview.js:284
#: ../js/ui/overview.js:271
msgid "Type to search…"
msgstr "Skriv for å søke …"
#: ../js/ui/panel.js:613
#: ../js/ui/panel.js:612
msgid "Quit"
msgstr "Avslutt"
#. Translators: If there is no suitable word for "Activities"
#. in your language, you can use the word for "Overview".
#: ../js/ui/panel.js:642
#: ../js/ui/panel.js:636
msgid "Activities"
msgstr "Aktiviteter"
#: ../js/ui/panel.js:983
#: ../js/ui/panel.js:933
msgid "Top Bar"
msgstr "Topp-panel"
@ -1244,32 +1247,32 @@ msgstr "Topp-panel"
msgid "toggle-switch-us"
msgstr "toggle-switch-intl"
#: ../js/ui/runDialog.js:205
#: ../js/ui/runDialog.js:73
msgid "Enter a Command"
msgstr "Oppgi en kommando"
#: ../js/ui/runDialog.js:241
#: ../js/ui/runDialog.js:109
msgid "Close"
msgstr "Lukk"
#. Translators: This is a time format for a date in
#. long format
#: ../js/ui/screenShield.js:90
#: ../js/ui/screenShield.js:86
msgid "%A, %B %d"
msgstr "%A, %B %d"
#: ../js/ui/screenShield.js:155
#: ../js/ui/screenShield.js:151
#, c-format
msgid "%d new notification"
msgid_plural "%d new notifications"
msgstr[0] "%d ny varsling"
msgstr[1] "%d nye varslinger"
#: ../js/ui/screenShield.js:442 ../js/ui/userMenu.js:806
#: ../js/ui/screenShield.js:438 ../js/ui/userMenu.js:807
msgid "Lock"
msgstr "Lås"
#: ../js/ui/screenShield.js:639
#: ../js/ui/screenShield.js:640
msgid "GNOME needs to lock the screen"
msgstr "GNOME må låse skjermen"
@ -1280,19 +1283,19 @@ msgstr "GNOME må låse skjermen"
#.
#. XXX: another option is to kick the user into the gdm login
#. screen, where we're not affected by grabs
#: ../js/ui/screenShield.js:758 ../js/ui/screenShield.js:1169
#: ../js/ui/screenShield.js:761 ../js/ui/screenShield.js:1197
msgid "Unable to lock"
msgstr "Kan ikke låse"
#: ../js/ui/screenShield.js:759 ../js/ui/screenShield.js:1170
#: ../js/ui/screenShield.js:762 ../js/ui/screenShield.js:1198
msgid "Lock was blocked by an application"
msgstr "Låsing ble stoppet av et program"
#: ../js/ui/searchDisplay.js:431
#: ../js/ui/searchDisplay.js:453
msgid "Searching…"
msgstr "Søker …"
#: ../js/ui/searchDisplay.js:475
#: ../js/ui/searchDisplay.js:497
msgid "No results."
msgstr "Ingen resultater."
@ -1304,11 +1307,11 @@ msgstr "Kopier"
msgid "Paste"
msgstr "Lim inn"
#: ../js/ui/shellEntry.js:105
#: ../js/ui/shellEntry.js:106
msgid "Show Text"
msgstr "Vis tekst"
#: ../js/ui/shellEntry.js:107
#: ../js/ui/shellEntry.js:108
msgid "Hide Text"
msgstr "Skjul tekst"
@ -1320,7 +1323,7 @@ msgstr "Passord"
msgid "Remember Password"
msgstr "Husk passord"
#: ../js/ui/shellMountOperation.js:403 ../js/ui/unlockDialog.js:140
#: ../js/ui/shellMountOperation.js:403 ../js/ui/unlockDialog.js:113
msgid "Unlock"
msgstr "Lås opp"
@ -1725,11 +1728,11 @@ msgstr "Volum"
msgid "Microphone"
msgstr "Mikrofon"
#: ../js/ui/unlockDialog.js:151
#: ../js/ui/unlockDialog.js:124
msgid "Log in as another user"
msgstr "Logg inn som en annen bruker"
#: ../js/ui/unlockDialog.js:177
#: ../js/ui/unlockDialog.js:145
msgid "Unlock Window"
msgstr "Lås opp vindu"
@ -1757,27 +1760,27 @@ msgstr "Ledig"
msgid "Offline"
msgstr "Frakoblet"
#: ../js/ui/userMenu.js:780
#: ../js/ui/userMenu.js:781
msgid "Notifications"
msgstr "Varslinger"
#: ../js/ui/userMenu.js:796
#: ../js/ui/userMenu.js:797
msgid "Switch User"
msgstr "Bytt bruker"
#: ../js/ui/userMenu.js:801
#: ../js/ui/userMenu.js:802
msgid "Log Out"
msgstr "Logg ut"
#: ../js/ui/userMenu.js:821
#: ../js/ui/userMenu.js:822
msgid "Install Updates & Restart"
msgstr "Installer oppdateringer og start på nytt"
#: ../js/ui/userMenu.js:839
#: ../js/ui/userMenu.js:840
msgid "Your chat status will be set to busy"
msgstr "Din pratestatus vil bli satt til opptatt"
#: ../js/ui/userMenu.js:840
#: ../js/ui/userMenu.js:841
msgid ""
"Notifications are now disabled, including chat messages. Your online status "
"has been adjusted to let others know that you might not see their messages."
@ -1786,22 +1789,24 @@ msgstr ""
"tilkoblingsstatus er justert for å la andre vite at du kanskje ikke ser "
"deres meldinger."
#: ../js/ui/userMenu.js:886
#: ../js/ui/userMenu.js:888
msgid "Other users are logged in."
msgstr "Andre brukere er logget inn."
#: ../js/ui/userMenu.js:891
#: ../js/ui/userMenu.js:893
msgid "Shutting down might cause them to lose unsaved work."
msgstr ""
"Hvis du slår av vil dette kunne medføre at de mister arbeid som ikke er "
"lagret."
#: ../js/ui/userMenu.js:918
#. Translators: Remote here refers to a remote session, like a ssh login
#: ../js/ui/userMenu.js:921
#, c-format
msgid "%s (remote)"
msgstr "%s (ekstern)"
#: ../js/ui/userMenu.js:920
#. Translators: Console here refers to a tty like a VT console
#: ../js/ui/userMenu.js:924
#, c-format
msgid "%s (console)"
msgstr "%s (konsoll)"
@ -1814,7 +1819,7 @@ msgstr "Programmer"
msgid "Search"
msgstr "Søk"
#: ../js/ui/wanda.js:92
#: ../js/ui/wanda.js:77
#, c-format
msgid ""
"Sorry, no wisdom for you today:\n"
@ -1823,7 +1828,7 @@ msgstr ""
"Beklager, ingen visdom til deg i dag:\n"
"%s"
#: ../js/ui/wanda.js:96
#: ../js/ui/wanda.js:81
#, c-format
msgid "%s the Oracle says"
msgstr "Orakelet sier %s"

625
po/nl.po

File diff suppressed because it is too large Load Diff

1202
po/or.po

File diff suppressed because it is too large Load Diff

307
po/pl.po
View File

@ -6,14 +6,15 @@
# -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
# Piotr Drąg <piotrdrag@gmail.com>, 2009-2013.
# Tomasz Dominikowski <dominikowski@gmail.com>, 2009.
# Wojciech Szczęsny <wszczesny@aviary.pl>, 2013.
# Aviary.pl <gnomepl@aviary.pl>, 2009-2013.
msgid ""
msgstr ""
"Project-Id-Version: gnome-shell\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-02-24 01:52+0100\n"
"PO-Revision-Date: 2013-02-24 01:53+0100\n"
"Last-Translator: Piotr Drąg <piotrdrag@gmail.com>\n"
"POT-Creation-Date: 2013-04-02 15:54+0200\n"
"PO-Revision-Date: 2013-04-02 15:55+0200\n"
"Last-Translator: Wojciech Szczęsny <wszczesny@aviary.pl>\n"
"Language-Team: Polish <gnomepl@aviary.pl>\n"
"Language: pl\n"
"MIME-Version: 1.0\n"
@ -61,7 +62,7 @@ msgid "Window management and application launching"
msgstr "Zarządzanie oknami i uruchamianiem programów"
#: ../data/gnome-shell-extension-prefs.desktop.in.in.h:1
#: ../js/extensionPrefs/main.js:152
#: ../js/extensionPrefs/main.js:153
msgid "GNOME Shell Extension Preferences"
msgstr "Preferencje rozszerzenia powłoki GNOME"
@ -80,7 +81,7 @@ msgid ""
"Allows access to internal debugging and monitoring tools using the Alt-F2 "
"dialog."
msgstr ""
"Umożliwia dostęp do wewnętrznych narzędzi debugowania i monitorowania "
"Umożliwia dostęp do wewnętrznych narzędzi debugowania i monitorowania, "
"używając okna dialogowego Alt-F2."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:3
@ -96,9 +97,9 @@ msgid ""
msgstr ""
"Rozszerzenia powłoki GNOME posiadają własność UUID; ten klucz zawiera "
"rozszerzenia, które powinny zostać wczytane. Każde rozszerzenie, które ma "
"zostać wczytane musi znajdować się na tej liście. Można także manipulować "
"listą za pomocą metod EnableExtension i DisableExtension usługi D-Bus na org."
"gnome.Shell."
"zostać wczytane, musi znajdować się na tej liście. Można także manipulować "
"listą za pomocą metod EnableExtension i DisableExtension usługi D-Bus na "
"org.gnome.Shell."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:5
msgid "Whether to collect stats about applications usage"
@ -112,7 +113,7 @@ msgid ""
"remove already saved data."
msgstr ""
"Powłoka zwykle monitoruje aktywne programy, aby przedstawiać najczęściej "
"używane (np. aktywatory programów). Mimo, że te dane nie są publiczne, można "
"używane (np. aktywatory programów). Mimo że te dane nie są publiczne, można "
"wyłączyć je z powodu prywatności. Proszę zauważyć, że wyłączenie nie "
"spowoduje usunięcia już zapisanych danych."
@ -138,7 +139,7 @@ msgid ""
"application view, rather than being displayed inline in the main view."
msgstr ""
"Każda nazwa kategorii na tej liście będzie przedstawiana jako katalog w "
"widoku programów, zamiast wyświetlać ją bezpośrednio w głównym widoku."
"widoku programów, zamiast wyświetlania jej bezpośrednio w głównym widoku."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:11
msgid "History for command (Alt-F2) dialog"
@ -286,7 +287,7 @@ msgstr ""
"Ustawia potok biblioteki GStreamer używany do zakodowania nagrań. Używa "
"składni programu gst-launch. Potok powinien posiadać niepołączony odpływ, "
"gdzie jest nagrywane. Zwykle taki posiada, a wyjście będzie zapisywane do "
"pliku wyjściowego. Mimo, że potok może sam zająć się swoim wyjściem, można "
"pliku wyjściowego. Mimo że potok może sam zająć się swoim wyjściem, można "
"także wysłać wyjście do serwera icecast przez polecenie shout2send lub "
"podobne. Jeśli nie zostanie ustawione lub ustawione na pustą wartość, to "
"zostanie użyty domyślny potok. Jest nim obecnie \"vp8enc min_quantizer=13 "
@ -359,20 +360,20 @@ msgstr "Dynamiczne zarządzanie obszarami roboczymi"
msgid "Workspaces only on primary monitor"
msgstr "Obszary robocze tylko na pierwszym monitorze"
#: ../js/extensionPrefs/main.js:124
#: ../js/extensionPrefs/main.js:125
#, c-format
msgid "There was an error loading the preferences dialog for %s:"
msgstr ""
"Wystąpił błąd podczas wczytywania okna preferencji dla rozszerzenia %s:"
#: ../js/extensionPrefs/main.js:164
#: ../js/extensionPrefs/main.js:165
msgid "Extension"
msgstr "Rozszerzenie"
#: ../js/extensionPrefs/main.js:188
#: ../js/extensionPrefs/main.js:189
msgid "Select an extension to configure using the combobox above."
msgstr ""
"Proszę wybrać rozszerzenie do skonfigurowania używając powyższego pola "
"Proszę wybrać rozszerzenie do skonfigurowania, używając powyższego pola "
"wyboru."
#: ../js/gdm/loginDialog.js:405
@ -382,36 +383,36 @@ msgstr "Sesja…"
#. 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:629
#: ../js/gdm/loginDialog.js:630
msgid "Not listed?"
msgstr "Inny użytkownik?"
#: ../js/gdm/loginDialog.js:783 ../js/ui/components/networkAgent.js:137
#: ../js/gdm/loginDialog.js:786 ../js/ui/components/networkAgent.js:137
#: ../js/ui/components/polkitAgent.js:162 ../js/ui/endSessionDialog.js:375
#: ../js/ui/extensionDownloader.js:195 ../js/ui/shellMountOperation.js:399
#: ../js/ui/status/bluetooth.js:415 ../js/ui/unlockDialog.js:126
#: ../js/ui/userMenu.js:932
#: ../js/ui/status/bluetooth.js:415 ../js/ui/unlockDialog.js:99
#: ../js/ui/userMenu.js:938
msgid "Cancel"
msgstr "Anuluj"
#: ../js/gdm/loginDialog.js:799
#: ../js/gdm/loginDialog.js:802
msgctxt "button"
msgid "Sign In"
msgstr "Zaloguj"
#: ../js/gdm/loginDialog.js:799
#: ../js/gdm/loginDialog.js:802
msgid "Next"
msgstr "Dalej"
#. 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:904 ../js/ui/components/networkAgent.js:260
#: ../js/gdm/loginDialog.js:917 ../js/ui/components/networkAgent.js:260
#: ../js/ui/components/networkAgent.js:278
msgid "Username: "
msgstr "Nazwa użytkownika: "
#: ../js/gdm/loginDialog.js:1157
#: ../js/gdm/loginDialog.js:1173
msgid "Login Window"
msgstr "Okno logowania"
@ -420,8 +421,8 @@ msgstr "Okno logowania"
msgid "Power"
msgstr "Zasilanie"
#: ../js/gdm/powerMenu.js:93 ../js/ui/userMenu.js:694 ../js/ui/userMenu.js:698
#: ../js/ui/userMenu.js:814
#: ../js/gdm/powerMenu.js:93 ../js/ui/userMenu.js:696 ../js/ui/userMenu.js:700
#: ../js/ui/userMenu.js:816
msgid "Suspend"
msgstr "Uśpij"
@ -429,58 +430,58 @@ msgstr "Uśpij"
msgid "Restart"
msgstr "Uruchom ponownie"
#: ../js/gdm/powerMenu.js:103 ../js/ui/userMenu.js:696
#: ../js/ui/userMenu.js:698 ../js/ui/userMenu.js:813 ../js/ui/userMenu.js:936
#: ../js/gdm/powerMenu.js:103 ../js/ui/userMenu.js:698
#: ../js/ui/userMenu.js:700 ../js/ui/userMenu.js:815 ../js/ui/userMenu.js:942
msgid "Power Off"
msgstr "Wyłącz komputer"
#: ../js/gdm/util.js:182
#: ../js/gdm/util.js:249
msgid "Authentication error"
msgstr "Błąd uwierzytelniania"
#. Translators: this message is shown below the password entry field
#. to indicate the user can swipe their finger instead
#: ../js/gdm/util.js:299
#: ../js/gdm/util.js:366
msgid "(or swipe finger)"
msgstr "(lub przeciągnięcie palca)"
#: ../js/gdm/util.js:324
#: ../js/gdm/util.js:391
#, c-format
msgid "(e.g., user or %s)"
msgstr "(np. użytkownik lub %s)"
#: ../js/misc/util.js:94
#: ../js/misc/util.js:97
msgid "Command not found"
msgstr "Nie odnaleziono polecenia"
#. Replace "Error invoking GLib.shell_parse_argv: " with
#. something nicer
#: ../js/misc/util.js:127
#: ../js/misc/util.js:130
msgid "Could not parse command:"
msgstr "Nie można przetworzyć polecenia:"
#: ../js/misc/util.js:135
#: ../js/misc/util.js:138
#, c-format
msgid "Execution of '%s' failed:"
msgstr "Wykonanie polecenia \"%s\" się nie powiodło:"
#: ../js/ui/appDisplay.js:348
#: ../js/ui/appDisplay.js:349
msgid "Frequent"
msgstr "Często używane"
#: ../js/ui/appDisplay.js:355
#: ../js/ui/appDisplay.js:356
msgid "All"
msgstr "Wszystkie"
#: ../js/ui/appDisplay.js:913
#: ../js/ui/appDisplay.js:914
msgid "New Window"
msgstr "Nowe okno"
#: ../js/ui/appDisplay.js:916 ../js/ui/dash.js:284
#: ../js/ui/appDisplay.js:917 ../js/ui/dash.js:284
msgid "Remove from Favorites"
msgstr "Usuń z ulubionych"
#: ../js/ui/appDisplay.js:917
#: ../js/ui/appDisplay.js:918
msgid "Add to Favorites"
msgstr "Dodaj do ulubionych"
@ -494,7 +495,7 @@ msgstr "Program %s został dodany do ulubionych."
msgid "%s has been removed from your favorites."
msgstr "Program %s został usunięty z ulubionych."
#: ../js/ui/backgroundMenu.js:19 ../js/ui/userMenu.js:787
#: ../js/ui/backgroundMenu.js:19 ../js/ui/userMenu.js:789
msgid "Settings"
msgstr "Ustawienia"
@ -517,7 +518,7 @@ msgctxt "event list time"
msgid "%H\\u2236%M"
msgstr "%H\\u2236%M"
#. Transators: Shown in calendar event list, if 12h format,
#. Translators: Shown in calendar event list, if 12h format,
#. \u2236 is a ratio character, similar to : and \u2009 is
#. a thin space
#: ../js/ui/calendar.js:77
@ -619,35 +620,35 @@ msgid "S"
msgstr "S"
#. Translators: Text to show if there are no events
#: ../js/ui/calendar.js:692
#: ../js/ui/calendar.js:720
msgid "Nothing Scheduled"
msgstr "Nic nie zaplanowano"
#. Translators: Shown on calendar heading when selected day occurs on current year
#: ../js/ui/calendar.js:708
#: ../js/ui/calendar.js:736
msgctxt "calendar heading"
msgid "%A, %B %d"
msgstr "%A, %e %B"
#. Translators: Shown on calendar heading when selected day occurs on different year
#: ../js/ui/calendar.js:711
#: ../js/ui/calendar.js:739
msgctxt "calendar heading"
msgid "%A, %B %d, %Y"
msgstr "%A, %e %B %Y"
#: ../js/ui/calendar.js:721
#: ../js/ui/calendar.js:749
msgid "Today"
msgstr "Dzisiaj"
#: ../js/ui/calendar.js:725
#: ../js/ui/calendar.js:753
msgid "Tomorrow"
msgstr "Jutro"
#: ../js/ui/calendar.js:736
#: ../js/ui/calendar.js:764
msgid "This week"
msgstr "Ten tydzień"
#: ../js/ui/calendar.js:744
#: ../js/ui/calendar.js:772
msgid "Next week"
msgstr "Następny tydzień"
@ -663,12 +664,12 @@ msgstr "Odłączono dysk zewnętrzny"
msgid "Removable Devices"
msgstr "Urządzenia wymienne"
#: ../js/ui/components/autorunManager.js:593
#: ../js/ui/components/autorunManager.js:594
#, c-format
msgid "Open with %s"
msgstr "Otwórz za pomocą %s"
#: ../js/ui/components/autorunManager.js:619
#: ../js/ui/components/autorunManager.js:620
msgid "Eject"
msgstr "Wysuń"
@ -811,39 +812,39 @@ msgid "Mute"
msgstr "Wycisz"
#. Translators: this is the word "Yesterday" followed by a time string. i.e. "Yesterday, 14:30"
#: ../js/ui/components/telepathyClient.js:938
#: ../js/ui/components/telepathyClient.js:942
#, no-c-format
msgid "<b>Yesterday</b>, <b>%H:%M</b>"
msgstr "<b>Wczoraj</b> o <b>%H:%M</b>"
#. Translators: this is the week day name followed by a time string. i.e. "Monday, 14:30
#: ../js/ui/components/telepathyClient.js:944
#: ../js/ui/components/telepathyClient.js:948
#, no-c-format
msgid "<b>%A</b>, <b>%H:%M</b>"
msgstr "<b>%A</b> o <b>%H:%M</b>"
#. Translators: this is the month name and day number followed by a time string. i.e. "May 25, 14:30"
#: ../js/ui/components/telepathyClient.js:949
#: ../js/ui/components/telepathyClient.js:953
#, no-c-format
msgid "<b>%B</b> <b>%d</b>, <b>%H:%M</b>"
msgstr "<b>%d</b> <b>%B</b>, <b>%H:%M</b>"
#. Translators: this is the month name, day number, year number followed by a time string. i.e. "May 25 2012, 14:30"
#: ../js/ui/components/telepathyClient.js:953
#: ../js/ui/components/telepathyClient.js:957
#, no-c-format
msgid "<b>%B</b> <b>%d</b> <b>%Y</b>, <b>%H:%M</b> "
msgstr "<b>%d</b> <b>%B</b> <b>%Y</b>, <b>%H:%M</b> "
#. Translators: this is the other person changing their old IM name to their new
#. IM name.
#: ../js/ui/components/telepathyClient.js:981
#: ../js/ui/components/telepathyClient.js:985
#, c-format
msgid "%s is now known as %s"
msgstr "Użytkownik %s jest teraz znany jako %s"
#. translators: argument is a room name like
#. * room@jabber.org for example.
#: ../js/ui/components/telepathyClient.js:1084
#: ../js/ui/components/telepathyClient.js:1088
#, c-format
msgid "Invitation to %s"
msgstr "Zaproszenie do pokoju %s"
@ -851,38 +852,38 @@ msgstr "Zaproszenie do pokoju %s"
#. translators: first argument is the name of a contact and the second
#. * one the name of a room. "Alice is inviting you to join room@jabber.org
#. * for example.
#: ../js/ui/components/telepathyClient.js:1092
#: ../js/ui/components/telepathyClient.js:1096
#, c-format
msgid "%s is inviting you to join %s"
msgstr "Użytkownik %s zaprasza do dołączenia do pokoju %s"
#: ../js/ui/components/telepathyClient.js:1094
#: ../js/ui/components/telepathyClient.js:1133
#: ../js/ui/components/telepathyClient.js:1173
#: ../js/ui/components/telepathyClient.js:1236
#: ../js/ui/components/telepathyClient.js:1098
#: ../js/ui/components/telepathyClient.js:1137
#: ../js/ui/components/telepathyClient.js:1177
#: ../js/ui/components/telepathyClient.js:1240
msgid "Decline"
msgstr "Odmów"
#: ../js/ui/components/telepathyClient.js:1095
#: ../js/ui/components/telepathyClient.js:1174
#: ../js/ui/components/telepathyClient.js:1237
#: ../js/ui/components/telepathyClient.js:1099
#: ../js/ui/components/telepathyClient.js:1178
#: ../js/ui/components/telepathyClient.js:1241
msgid "Accept"
msgstr "Zaakceptuj"
#. translators: argument is a contact name like Alice for example.
#: ../js/ui/components/telepathyClient.js:1125
#: ../js/ui/components/telepathyClient.js:1129
#, c-format
msgid "Video call from %s"
msgstr "Wideorozmowa z użytkownikiem %s"
#. translators: argument is a contact name like Alice for example.
#: ../js/ui/components/telepathyClient.js:1128
#: ../js/ui/components/telepathyClient.js:1132
#, c-format
msgid "Call from %s"
msgstr "Rozmowa z użytkownikiem %s"
#. translators: this is a button label (verb), not a noun
#: ../js/ui/components/telepathyClient.js:1135
#: ../js/ui/components/telepathyClient.js:1139
msgid "Answer"
msgstr "Odbierz"
@ -891,111 +892,111 @@ msgstr "Odbierz"
#. * file name. The string will be something
#. * like: "Alice is sending you test.ogg"
#.
#: ../js/ui/components/telepathyClient.js:1167
#: ../js/ui/components/telepathyClient.js:1171
#, c-format
msgid "%s is sending you %s"
msgstr "Użytkownik %s przysyła plik %s"
#. To translators: The parameter is the contact's alias
#: ../js/ui/components/telepathyClient.js:1202
#: ../js/ui/components/telepathyClient.js:1206
#, c-format
msgid "%s would like permission to see when you are online"
msgstr "Użytkownik %s prosi o uprawnienie do wyświetlania stanu"
#: ../js/ui/components/telepathyClient.js:1294
#: ../js/ui/components/telepathyClient.js:1298
msgid "Network error"
msgstr "Błąd sieci"
#: ../js/ui/components/telepathyClient.js:1296
#: ../js/ui/components/telepathyClient.js:1300
msgid "Authentication failed"
msgstr "Uwierzytelnienie się nie powiodło"
#: ../js/ui/components/telepathyClient.js:1298
#: ../js/ui/components/telepathyClient.js:1302
msgid "Encryption error"
msgstr "Błąd szyfrowania"
#: ../js/ui/components/telepathyClient.js:1300
#: ../js/ui/components/telepathyClient.js:1304
msgid "Certificate not provided"
msgstr "Nie podano certyfikatu"
#: ../js/ui/components/telepathyClient.js:1302
#: ../js/ui/components/telepathyClient.js:1306
msgid "Certificate untrusted"
msgstr "Certyfikat jest niezaufany"
#: ../js/ui/components/telepathyClient.js:1304
#: ../js/ui/components/telepathyClient.js:1308
msgid "Certificate expired"
msgstr "Certyfikat wygasł"
#: ../js/ui/components/telepathyClient.js:1306
#: ../js/ui/components/telepathyClient.js:1310
msgid "Certificate not activated"
msgstr "Certyfikat nie został aktywowany"
#: ../js/ui/components/telepathyClient.js:1308
#: ../js/ui/components/telepathyClient.js:1312
msgid "Certificate hostname mismatch"
msgstr "Nazwa komputera certyfikatu się nie zgadza"
#: ../js/ui/components/telepathyClient.js:1310
#: ../js/ui/components/telepathyClient.js:1314
msgid "Certificate fingerprint mismatch"
msgstr "Odcisk palca certyfikatu się nie zgadza"
#: ../js/ui/components/telepathyClient.js:1312
#: ../js/ui/components/telepathyClient.js:1316
msgid "Certificate self-signed"
msgstr "Certyfikat został samodzielnie podpisany"
#: ../js/ui/components/telepathyClient.js:1314
#: ../js/ui/components/telepathyClient.js:1318
msgid "Status is set to offline"
msgstr "Stan jest ustawiony na offline"
#: ../js/ui/components/telepathyClient.js:1316
#: ../js/ui/components/telepathyClient.js:1320
msgid "Encryption is not available"
msgstr "Szyfrowanie jest niedostępne"
#: ../js/ui/components/telepathyClient.js:1318
#: ../js/ui/components/telepathyClient.js:1322
msgid "Certificate is invalid"
msgstr "Certyfikat jest nieprawidłowy"
#: ../js/ui/components/telepathyClient.js:1320
#: ../js/ui/components/telepathyClient.js:1324
msgid "Connection has been refused"
msgstr "Odrzucono połączenie"
#: ../js/ui/components/telepathyClient.js:1322
#: ../js/ui/components/telepathyClient.js:1326
msgid "Connection can't be established"
msgstr "Nie można nawiązać połączenia"
#: ../js/ui/components/telepathyClient.js:1324
#: ../js/ui/components/telepathyClient.js:1328
msgid "Connection has been lost"
msgstr "Utracono połączenie"
#: ../js/ui/components/telepathyClient.js:1326
#: ../js/ui/components/telepathyClient.js:1330
msgid "This account is already connected to the server"
msgstr "To konto jest już połączone z serwerem"
#: ../js/ui/components/telepathyClient.js:1328
#: ../js/ui/components/telepathyClient.js:1332
msgid ""
"Connection has been replaced by a new connection using the same resource"
msgstr ""
"Połączenie zostało zastąpione nowym z wykorzystaniem tego samego zasobu"
#: ../js/ui/components/telepathyClient.js:1330
#: ../js/ui/components/telepathyClient.js:1334
msgid "The account already exists on the server"
msgstr "Konto już istnieje na serwerze"
#: ../js/ui/components/telepathyClient.js:1332
#: ../js/ui/components/telepathyClient.js:1336
msgid "Server is currently too busy to handle the connection"
msgstr "Serwer jest obecnie zbyt zajęty, aby obsłużyć połączenie"
#: ../js/ui/components/telepathyClient.js:1334
#: ../js/ui/components/telepathyClient.js:1338
msgid "Certificate has been revoked"
msgstr "Certyfikat został unieważniony"
#: ../js/ui/components/telepathyClient.js:1336
#: ../js/ui/components/telepathyClient.js:1340
msgid ""
"Certificate uses an insecure cipher algorithm or is cryptographically weak"
msgstr ""
"Certyfikat używa niezabezpieczonego algorytmu szyfrowania lub jest "
"kryptograficznie słaby"
#: ../js/ui/components/telepathyClient.js:1338
#: ../js/ui/components/telepathyClient.js:1342
msgid ""
"The length of the server certificate, or the depth of the server certificate "
"chain, exceed the limits imposed by the cryptography library"
@ -1003,26 +1004,26 @@ msgstr ""
"Długość certyfikatu serwera lub głębokość jego łańcucha przekracza "
"ograniczenia nałożone przez bibliotekę kryptograficzną"
#: ../js/ui/components/telepathyClient.js:1340
#: ../js/ui/components/telepathyClient.js:1344
msgid "Internal error"
msgstr "Błąd wewnętrzny"
#. translators: argument is the account name, like
#. * name@jabber.org for example.
#: ../js/ui/components/telepathyClient.js:1350
#: ../js/ui/components/telepathyClient.js:1354
#, c-format
msgid "Unable to connect to %s"
msgstr "Nie można połączyć się z kontem %s"
#: ../js/ui/components/telepathyClient.js:1355
#: ../js/ui/components/telepathyClient.js:1359
msgid "View account"
msgstr "Wyświetl konto"
#: ../js/ui/components/telepathyClient.js:1394
#: ../js/ui/components/telepathyClient.js:1398
msgid "Unknown reason"
msgstr "Nieznana przyczyna"
#: ../js/ui/ctrlAltTab.js:29 ../js/ui/viewSelector.js:97
#: ../js/ui/ctrlAltTab.js:29 ../js/ui/viewSelector.js:96
msgid "Windows"
msgstr "Okna"
@ -1051,7 +1052,7 @@ msgstr "Ustawienia daty i czasu"
#. Translators: This is the date format to use when the calendar popup is
#. * shown - it is shown just below the time in the shell (e.g. "Tue 9:29 AM").
#.
#: ../js/ui/dateMenu.js:205
#: ../js/ui/dateMenu.js:215
msgid "%A %B %e, %Y"
msgstr "%A, %e %B %Y"
@ -1212,23 +1213,23 @@ msgstr "Wyświetl źródło"
msgid "Web Page"
msgstr "Strona WWW"
#: ../js/ui/messageTray.js:1177
#: ../js/ui/messageTray.js:1182
msgid "Open"
msgstr "Otwórz"
#: ../js/ui/messageTray.js:1184
#: ../js/ui/messageTray.js:1189
msgid "Remove"
msgstr "Usuń"
#: ../js/ui/messageTray.js:1496
#: ../js/ui/messageTray.js:1501
msgid "Clear Messages"
msgstr "Wyczyść wiadomości"
#: ../js/ui/messageTray.js:1523
#: ../js/ui/messageTray.js:1528
msgid "Notification Settings"
msgstr "Ustawienia powiadomień"
#: ../js/ui/messageTray.js:1702
#: ../js/ui/messageTray.js:1709
msgid "No Messages"
msgstr "Brak wiadomości"
@ -1236,7 +1237,7 @@ msgstr "Brak wiadomości"
msgid "Message Tray"
msgstr "Obszar powiadamiania"
#: ../js/ui/messageTray.js:2857
#: ../js/ui/messageTray.js:2810
msgid "System Information"
msgstr "Informacje systemowe"
@ -1245,11 +1246,19 @@ msgctxt "program"
msgid "Unknown"
msgstr "Nieznany"
#: ../js/ui/overview.js:81
#: ../js/ui/overviewControls.js:463 ../js/ui/screenShield.js:149
#, c-format
msgid "%d new message"
msgid_plural "%d new messages"
msgstr[0] "%d nowa wiadomość"
msgstr[1] "%d nowe wiadomości"
msgstr[2] "%d nowych wiadomości"
#: ../js/ui/overview.js:84
msgid "Undo"
msgstr "Cofnij"
#: ../js/ui/overview.js:124
#: ../js/ui/overview.js:129
msgid "Overview"
msgstr "Podgląd"
@ -1257,21 +1266,21 @@ msgstr "Podgląd"
#. in the search entry when no search is
#. active; it should not exceed ~30
#. characters.
#: ../js/ui/overview.js:272
#: ../js/ui/overview.js:271
msgid "Type to search…"
msgstr "Wyszukiwanie…"
#: ../js/ui/panel.js:613
#: ../js/ui/panel.js:612
msgid "Quit"
msgstr "Zakończ"
#. Translators: If there is no suitable word for "Activities"
#. in your language, you can use the word for "Overview".
#: ../js/ui/panel.js:642
#: ../js/ui/panel.js:636
msgid "Activities"
msgstr "Podgląd"
#: ../js/ui/panel.js:983
#: ../js/ui/panel.js:933
msgid "Top Bar"
msgstr "Górny pasek"
@ -1284,29 +1293,21 @@ msgstr "Górny pasek"
msgid "toggle-switch-us"
msgstr "toggle-switch-intl"
#: ../js/ui/runDialog.js:205
#: ../js/ui/runDialog.js:73
msgid "Enter a Command"
msgstr "Proszę wprowadzić polecenie"
#: ../js/ui/runDialog.js:241
#: ../js/ui/runDialog.js:109
msgid "Close"
msgstr "Zamknij"
#. Translators: This is a time format for a date in
#. long format
#: ../js/ui/screenShield.js:90
#: ../js/ui/screenShield.js:86
msgid "%A, %B %d"
msgstr "%A, %e %B"
#: ../js/ui/screenShield.js:153
#, c-format
msgid "%d new message"
msgid_plural "%d new messages"
msgstr[0] "%d nowa wiadomość"
msgstr[1] "%d nowe wiadomości"
msgstr[2] "%d nowych wiadomości"
#: ../js/ui/screenShield.js:155
#: ../js/ui/screenShield.js:151
#, c-format
msgid "%d new notification"
msgid_plural "%d new notifications"
@ -1314,11 +1315,11 @@ msgstr[0] "%d nowe powiadomienie"
msgstr[1] "%d nowe powiadomienia"
msgstr[2] "%d nowych powiadomień"
#: ../js/ui/screenShield.js:442 ../js/ui/userMenu.js:805
#: ../js/ui/screenShield.js:438 ../js/ui/userMenu.js:807
msgid "Lock"
msgstr "Zablokuj ekran"
#: ../js/ui/screenShield.js:638
#: ../js/ui/screenShield.js:640
msgid "GNOME needs to lock the screen"
msgstr "Środowisko GNOME musi zablokować ekran"
@ -1329,19 +1330,19 @@ msgstr "Środowisko GNOME musi zablokować ekran"
#.
#. XXX: another option is to kick the user into the gdm login
#. screen, where we're not affected by grabs
#: ../js/ui/screenShield.js:757 ../js/ui/screenShield.js:1168
#: ../js/ui/screenShield.js:761 ../js/ui/screenShield.js:1197
msgid "Unable to lock"
msgstr "Nie można zablokować"
#: ../js/ui/screenShield.js:758 ../js/ui/screenShield.js:1169
#: ../js/ui/screenShield.js:762 ../js/ui/screenShield.js:1198
msgid "Lock was blocked by an application"
msgstr "Blokowanie zostało zablokowane przez program"
#: ../js/ui/searchDisplay.js:431
#: ../js/ui/searchDisplay.js:453
msgid "Searching…"
msgstr "Wyszukiwanie…"
#: ../js/ui/searchDisplay.js:475
#: ../js/ui/searchDisplay.js:497
msgid "No results."
msgstr "Brak wyników."
@ -1353,11 +1354,11 @@ msgstr "Skopiuj"
msgid "Paste"
msgstr "Wklej"
#: ../js/ui/shellEntry.js:105
#: ../js/ui/shellEntry.js:106
msgid "Show Text"
msgstr "Wyświetl tekst"
#: ../js/ui/shellEntry.js:107
#: ../js/ui/shellEntry.js:108
msgid "Hide Text"
msgstr "Ukryj tekst"
@ -1369,7 +1370,7 @@ msgstr "Hasło"
msgid "Remember Password"
msgstr "Zapamiętanie hasła"
#: ../js/ui/shellMountOperation.js:403 ../js/ui/unlockDialog.js:140
#: ../js/ui/shellMountOperation.js:403 ../js/ui/unlockDialog.js:113
msgid "Unlock"
msgstr "Odblokuj"
@ -1778,59 +1779,59 @@ msgstr "Głośność"
msgid "Microphone"
msgstr "Mikrofon"
#: ../js/ui/unlockDialog.js:151
#: ../js/ui/unlockDialog.js:124
msgid "Log in as another user"
msgstr "Zaloguj jako inny użytkownik"
#: ../js/ui/unlockDialog.js:177
#: ../js/ui/unlockDialog.js:145
msgid "Unlock Window"
msgstr "Okno odblokowania"
#: ../js/ui/userMenu.js:192
#: ../js/ui/userMenu.js:193
msgid "Available"
msgstr "Dostępny"
#: ../js/ui/userMenu.js:195
#: ../js/ui/userMenu.js:196
msgid "Busy"
msgstr "Zajęty"
#: ../js/ui/userMenu.js:198
#: ../js/ui/userMenu.js:199
msgid "Invisible"
msgstr "Niewidoczny"
#: ../js/ui/userMenu.js:201
#: ../js/ui/userMenu.js:202
msgid "Away"
msgstr "Nieobecny"
#: ../js/ui/userMenu.js:204
#: ../js/ui/userMenu.js:205
msgid "Idle"
msgstr "Bezczynny"
#: ../js/ui/userMenu.js:207
#: ../js/ui/userMenu.js:208
msgid "Offline"
msgstr "Offline"
#: ../js/ui/userMenu.js:779
#: ../js/ui/userMenu.js:781
msgid "Notifications"
msgstr "Powiadomienia"
#: ../js/ui/userMenu.js:795
#: ../js/ui/userMenu.js:797
msgid "Switch User"
msgstr "Przełącz użytkownika"
#: ../js/ui/userMenu.js:800
#: ../js/ui/userMenu.js:802
msgid "Log Out"
msgstr "Wyloguj się"
#: ../js/ui/userMenu.js:820
#: ../js/ui/userMenu.js:822
msgid "Install Updates & Restart"
msgstr "Zaktualizuj i uruchom ponownie"
#: ../js/ui/userMenu.js:838
#: ../js/ui/userMenu.js:840
msgid "Your chat status will be set to busy"
msgstr "Stan komunikatora zostanie ustawiony na \"zajęty\""
#: ../js/ui/userMenu.js:839
#: ../js/ui/userMenu.js:841
msgid ""
"Notifications are now disabled, including chat messages. Your online status "
"has been adjusted to let others know that you might not see their messages."
@ -1840,33 +1841,35 @@ msgstr ""
"użytkownik tego komputera może nie zobaczyć przychodzących od nich "
"wiadomości."
#: ../js/ui/userMenu.js:885
#: ../js/ui/userMenu.js:888
msgid "Other users are logged in."
msgstr "Inni użytkownicy są zalogowani."
#: ../js/ui/userMenu.js:890
#: ../js/ui/userMenu.js:893
msgid "Shutting down might cause them to lose unsaved work."
msgstr "Wyłączenie komputera może spowodować utratę danych."
#: ../js/ui/userMenu.js:916
#. Translators: Remote here refers to a remote session, like a ssh login
#: ../js/ui/userMenu.js:921
#, c-format
msgid "%s (remote)"
msgstr "%s (zdalnie)"
#: ../js/ui/userMenu.js:918
#. Translators: Console here refers to a tty like a VT console
#: ../js/ui/userMenu.js:924
#, c-format
msgid "%s (console)"
msgstr "%s (konsola)"
#: ../js/ui/viewSelector.js:101
#: ../js/ui/viewSelector.js:100
msgid "Applications"
msgstr "Programy"
#: ../js/ui/viewSelector.js:105
#: ../js/ui/viewSelector.js:104
msgid "Search"
msgstr "Wyszukiwanie"
#: ../js/ui/wanda.js:92
#: ../js/ui/wanda.js:77
#, c-format
msgid ""
"Sorry, no wisdom for you today:\n"
@ -1875,7 +1878,7 @@ msgstr ""
"Nic mądrego na dzisiaj:\n"
"%s"
#: ../js/ui/wanda.js:96
#: ../js/ui/wanda.js:81
#, c-format
msgid "%s the Oracle says"
msgstr "Wyrocznia %s przemawia"

863
po/pt.po

File diff suppressed because it is too large Load Diff

193
po/ru.po
View File

@ -15,8 +15,8 @@ msgstr ""
"Project-Id-Version: gnome-shell\n"
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-"
"shell&keywords=I18N+L10N&component=general\n"
"POT-Creation-Date: 2013-03-03 12:52+0000\n"
"PO-Revision-Date: 2013-03-03 23:21+0400\n"
"POT-Creation-Date: 2013-03-14 18:11+0000\n"
"PO-Revision-Date: 2013-03-22 21:02+0400\n"
"Last-Translator: Yuri Myasoedov <omerta13@yandex.ru>\n"
"Language-Team: русский <gnome-cyr@gnome.org>\n"
"Language: ru\n"
@ -142,11 +142,11 @@ msgstr ""
#: ../data/org.gnome.shell.gschema.xml.in.in.h:11
msgid "History for command (Alt-F2) dialog"
msgstr "История команд диалога (Alt-F2)"
msgstr "История команд диалогового окна (Alt-F2)"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:12
msgid "History for the looking glass dialog"
msgstr "История просмотра прозрачного диалога"
msgstr "История просмотра прозрачного диалогового окна"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:13
msgid ""
@ -223,11 +223,11 @@ msgstr "Комбинация клавиш для перехода в режим
#: ../data/org.gnome.shell.gschema.xml.in.in.h:25
msgid "Keybinding to toggle the visibility of the message tray"
msgstr "Комбинация клавиш для показа и скрытия панели сообщений"
msgstr "Комбинация клавиш для отображения или скрытия панели сообщений"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:26
msgid "Keybinding to toggle the visibility of the message tray."
msgstr "Комбинация клавиш для показа и скрытия панели сообщений."
msgstr "Комбинация клавиш для отображения или скрытия панели сообщений."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:27
msgid "Keybinding to focus the active notification"
@ -239,12 +239,13 @@ msgstr "Комбинация клавиш для перевода фокуса
#: ../data/org.gnome.shell.gschema.xml.in.in.h:29
msgid "Keybinding to toggle the screen recorder"
msgstr "Комбинация клавиш для включения и выключения средства записи экрана"
msgstr "Комбинация клавиш для включения или выключения средства записи экрана"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:30
msgid "Keybinding to start/stop the builtin screen recorder."
msgstr ""
"Комбинация клавиш для запуска и останова встроенного средства записи экрана."
"Комбинация клавиш для запуска или остановки встроенного средства записи "
"экрана."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:31
msgid "Which keyboard to use"
@ -263,8 +264,8 @@ msgid ""
"The framerate of the resulting screencast recordered by GNOME Shell's "
"screencast recorder in frames-per-second."
msgstr ""
"Частота смены кадров в скринкасте, записанном с помощью GNOME Shell (кадров/"
"сек)."
"Частота смены кадров (кадров/сек) скринкаста, записанного с помощью GNOME "
"Shell."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:35
msgid "The gstreamer pipeline used to encode the screencast"
@ -299,7 +300,7 @@ msgstr ""
#: ../data/org.gnome.shell.gschema.xml.in.in.h:38
msgid "File extension used for storing the screencast"
msgstr "Расширение файла, использующееся для хранения скринкастов"
msgstr "Расширение файла, используемое при сохранении скринкастов"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:39
msgid ""
@ -307,9 +308,9 @@ msgid ""
"current date, and use this extension. It should be changed when recording to "
"a different container format."
msgstr ""
"Имя файла записанного скринкаста будет уникальным именем, основанным на "
"текущей дате, и использует это расширение. Оно должно быть изменено, если "
"запись выполняется в другой контейнерный формат."
"Имя файла записанного скринкаста будет уникальным, основанным на текущей "
"дате и используемом расширении. Оно должно быть изменено, если запись "
"выполняется в другой формат контейнера."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:40
msgid "The application icon mode."
@ -364,7 +365,7 @@ msgstr "Рабочие места только на основном монит
#: ../js/extensionPrefs/main.js:125
#, c-format
msgid "There was an error loading the preferences dialog for %s:"
msgstr "При загрузке диалога параметров для %s произошла ошибка:"
msgstr "При загрузке диалогового окна параметров для %s произошла ошибка:"
#: ../js/extensionPrefs/main.js:165
msgid "Extension"
@ -381,46 +382,46 @@ msgstr "Сеанс…"
#. 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:629
#: ../js/gdm/loginDialog.js:630
msgid "Not listed?"
msgstr "Нет в списке?"
#: ../js/gdm/loginDialog.js:783 ../js/ui/components/networkAgent.js:137
#: ../js/gdm/loginDialog.js:784 ../js/ui/components/networkAgent.js:137
#: ../js/ui/components/polkitAgent.js:162 ../js/ui/endSessionDialog.js:375
#: ../js/ui/extensionDownloader.js:195 ../js/ui/shellMountOperation.js:399
#: ../js/ui/status/bluetooth.js:415 ../js/ui/unlockDialog.js:126
#: ../js/ui/userMenu.js:934
#: ../js/ui/status/bluetooth.js:415 ../js/ui/unlockDialog.js:98
#: ../js/ui/userMenu.js:938
msgid "Cancel"
msgstr "Отмена"
#: ../js/gdm/loginDialog.js:799
#: ../js/gdm/loginDialog.js:800
msgctxt "button"
msgid "Sign In"
msgstr "Войти"
#: ../js/gdm/loginDialog.js:799
#: ../js/gdm/loginDialog.js:800
msgid "Next"
msgstr "Следующий"
msgstr "Далее"
#. 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:904 ../js/ui/components/networkAgent.js:260
#: ../js/gdm/loginDialog.js:915 ../js/ui/components/networkAgent.js:260
#: ../js/ui/components/networkAgent.js:278
msgid "Username: "
msgstr "Имя пользователя: "
#: ../js/gdm/loginDialog.js:1157
#: ../js/gdm/loginDialog.js:1159
msgid "Login Window"
msgstr "Окно входа в систему"
#. Translators: accessible name of the power menu in the login screen
#: ../js/gdm/powerMenu.js:36
msgid "Power"
msgstr "Питание"
msgstr "Электропитание"
#: ../js/gdm/powerMenu.js:93 ../js/ui/userMenu.js:695 ../js/ui/userMenu.js:699
#: ../js/ui/userMenu.js:815
#: ../js/gdm/powerMenu.js:93 ../js/ui/userMenu.js:696 ../js/ui/userMenu.js:700
#: ../js/ui/userMenu.js:816
msgid "Suspend"
msgstr "Ждущий режим"
@ -428,14 +429,14 @@ msgstr "Ждущий режим"
msgid "Restart"
msgstr "Перезапустить"
#: ../js/gdm/powerMenu.js:103 ../js/ui/userMenu.js:697
#: ../js/ui/userMenu.js:699 ../js/ui/userMenu.js:814 ../js/ui/userMenu.js:938
#: ../js/gdm/powerMenu.js:103 ../js/ui/userMenu.js:698
#: ../js/ui/userMenu.js:700 ../js/ui/userMenu.js:815 ../js/ui/userMenu.js:942
msgid "Power Off"
msgstr "Выключить"
#: ../js/gdm/util.js:182
msgid "Authentication error"
msgstr "Ошибка подтверждения подлинности"
msgstr "Ошибка проверки подлинности"
#. Translators: this message is shown below the password entry field
#. to indicate the user can swipe their finger instead
@ -448,38 +449,38 @@ msgstr "(или проведите пальцем по считывающему
msgid "(e.g., user or %s)"
msgstr "(например, пользователь или %s)"
#: ../js/misc/util.js:94
#: ../js/misc/util.js:97
msgid "Command not found"
msgstr "Команда не найдена"
#. Replace "Error invoking GLib.shell_parse_argv: " with
#. something nicer
#: ../js/misc/util.js:127
#: ../js/misc/util.js:130
msgid "Could not parse command:"
msgstr "Не удалось разобрать команду:"
#: ../js/misc/util.js:135
#: ../js/misc/util.js:138
#, c-format
msgid "Execution of '%s' failed:"
msgstr "Не удалось выполнить «%s»:"
#: ../js/ui/appDisplay.js:348
#: ../js/ui/appDisplay.js:325
msgid "Frequent"
msgstr "Часто используемые"
msgstr "Популярные"
#: ../js/ui/appDisplay.js:355
#: ../js/ui/appDisplay.js:332
msgid "All"
msgstr "Все"
#: ../js/ui/appDisplay.js:913
#: ../js/ui/appDisplay.js:890
msgid "New Window"
msgstr "Новое окно"
#: ../js/ui/appDisplay.js:916 ../js/ui/dash.js:284
#: ../js/ui/appDisplay.js:893 ../js/ui/dash.js:284
msgid "Remove from Favorites"
msgstr "Удалить из избранного"
#: ../js/ui/appDisplay.js:917
#: ../js/ui/appDisplay.js:894
msgid "Add to Favorites"
msgstr "Добавить в избранное"
@ -493,7 +494,7 @@ msgstr "Приложение %s добавлено в избранное."
msgid "%s has been removed from your favorites."
msgstr "Приложение %s удалено из избранного."
#: ../js/ui/backgroundMenu.js:19 ../js/ui/userMenu.js:788
#: ../js/ui/backgroundMenu.js:19 ../js/ui/userMenu.js:789
msgid "Settings"
msgstr "Параметры"
@ -618,35 +619,35 @@ msgid "S"
msgstr "Сб"
#. Translators: Text to show if there are no events
#: ../js/ui/calendar.js:692
#: ../js/ui/calendar.js:720
msgid "Nothing Scheduled"
msgstr "Нет событий"
#. Translators: Shown on calendar heading when selected day occurs on current year
#: ../js/ui/calendar.js:708
#: ../js/ui/calendar.js:736
msgctxt "calendar heading"
msgid "%A, %B %d"
msgstr "%A, %B %d"
#. Translators: Shown on calendar heading when selected day occurs on different year
#: ../js/ui/calendar.js:711
#: ../js/ui/calendar.js:739
msgctxt "calendar heading"
msgid "%A, %B %d, %Y"
msgstr "%A, %B %d, %Y"
#: ../js/ui/calendar.js:721
#: ../js/ui/calendar.js:749
msgid "Today"
msgstr "Сегодня"
#: ../js/ui/calendar.js:725
#: ../js/ui/calendar.js:753
msgid "Tomorrow"
msgstr "Завтра"
#: ../js/ui/calendar.js:736
#: ../js/ui/calendar.js:764
msgid "This week"
msgstr "Эта неделя"
#: ../js/ui/calendar.js:744
#: ../js/ui/calendar.js:772
msgid "Next week"
msgstr "Следующая неделя"
@ -743,7 +744,7 @@ msgstr "Для широкополосного мобильного устрой
#: ../js/ui/components/networkAgent.js:330
msgid "PIN: "
msgstr "PIN: "
msgstr "PIN-код: "
#: ../js/ui/components/networkAgent.js:336
msgid "Mobile broadband network password"
@ -772,7 +773,7 @@ msgstr "Подтвердить"
#. * for instance.
#: ../js/ui/components/polkitAgent.js:256 ../js/ui/shellMountOperation.js:383
msgid "Sorry, that didn't work. Please try again."
msgstr "Извините, это не сработало. Попробуйте снова."
msgstr "Не удалось подтвердить подлинность. Попробуйте снова."
#. Translators: this is a filename used for screencast recording
#: ../js/ui/components/recorder.js:48
@ -1020,7 +1021,7 @@ msgstr "Показать учётную запись"
msgid "Unknown reason"
msgstr "Неизвестная причина"
#: ../js/ui/ctrlAltTab.js:29 ../js/ui/viewSelector.js:97
#: ../js/ui/ctrlAltTab.js:29 ../js/ui/viewSelector.js:96
msgid "Windows"
msgstr "Окна"
@ -1049,7 +1050,7 @@ msgstr "Настроить дату и время"
#. Translators: This is the date format to use when the calendar popup is
#. * shown - it is shown just below the time in the shell (e.g. "Tue 9:29 AM").
#.
#: ../js/ui/dateMenu.js:205
#: ../js/ui/dateMenu.js:215
msgid "%A %B %e, %Y"
msgstr "%A, %e %B, %Y"
@ -1057,7 +1058,7 @@ msgstr "%A, %e %B, %Y"
#, c-format
msgctxt "title"
msgid "Log Out %s"
msgstr "Завершить сеанс пользователя %s"
msgstr "Завершение сеанса пользователя %s"
#: ../js/ui/endSessionDialog.js:64
msgctxt "title"
@ -1228,15 +1229,15 @@ msgstr "Очистить список сообщений"
msgid "Notification Settings"
msgstr "Параметры уведомлений"
#: ../js/ui/messageTray.js:1707
#: ../js/ui/messageTray.js:1711
msgid "No Messages"
msgstr "Нет сообщений"
#: ../js/ui/messageTray.js:1787
#: ../js/ui/messageTray.js:1784
msgid "Message Tray"
msgstr "Панель сообщений"
#: ../js/ui/messageTray.js:2864
#: ../js/ui/messageTray.js:2816
msgid "System Information"
msgstr "Системная информация"
@ -1245,7 +1246,7 @@ msgctxt "program"
msgid "Unknown"
msgstr "Неизвестно"
#: ../js/ui/overviewControls.js:460 ../js/ui/screenShield.js:153
#: ../js/ui/overviewControls.js:463 ../js/ui/screenShield.js:148
#, c-format
msgid "%d new message"
msgid_plural "%d new messages"
@ -1253,7 +1254,7 @@ msgstr[0] "%d новое сообщение"
msgstr[1] "%d новых сообщения"
msgstr[2] "%d новых сообщений"
#: ../js/ui/overview.js:82
#: ../js/ui/overview.js:84
msgid "Undo"
msgstr "Отменить"
@ -1265,21 +1266,21 @@ msgstr "Обзор"
#. in the search entry when no search is
#. active; it should not exceed ~30
#. characters.
#: ../js/ui/overview.js:284
#: ../js/ui/overview.js:271
msgid "Type to search…"
msgstr "Найти…"
#: ../js/ui/panel.js:613
#: ../js/ui/panel.js:612
msgid "Quit"
msgstr "Закрыть"
#. Translators: If there is no suitable word for "Activities"
#. in your language, you can use the word for "Overview".
#: ../js/ui/panel.js:642
#: ../js/ui/panel.js:636
msgid "Activities"
msgstr "Обзор"
#: ../js/ui/panel.js:983
#: ../js/ui/panel.js:933
msgid "Top Bar"
msgstr "Верхняя панель"
@ -1292,33 +1293,33 @@ msgstr "Верхняя панель"
msgid "toggle-switch-us"
msgstr "toggle-switch-intl"
#: ../js/ui/runDialog.js:205
#: ../js/ui/runDialog.js:73
msgid "Enter a Command"
msgstr "Введите команду"
#: ../js/ui/runDialog.js:241
#: ../js/ui/runDialog.js:109
msgid "Close"
msgstr "Закрыть"
#. Translators: This is a time format for a date in
#. long format
#: ../js/ui/screenShield.js:90
#: ../js/ui/screenShield.js:85
msgid "%A, %B %d"
msgstr "%d %B, %A"
#: ../js/ui/screenShield.js:155
#: ../js/ui/screenShield.js:150
#, c-format
msgid "%d new notification"
msgid_plural "%d new notifications"
msgstr[0] "%d новые уведомление"
msgstr[1] "%d новых уведомленя"
msgstr[0] "%d новое уведомление"
msgstr[1] "%d новых уведомления"
msgstr[2] "%d новых уведомлений"
#: ../js/ui/screenShield.js:442 ../js/ui/userMenu.js:806
#: ../js/ui/screenShield.js:437 ../js/ui/userMenu.js:807
msgid "Lock"
msgstr "Заблокировать"
#: ../js/ui/screenShield.js:639
#: ../js/ui/screenShield.js:635
msgid "GNOME needs to lock the screen"
msgstr "GNOME необходимо заблокировать экран"
@ -1329,19 +1330,19 @@ msgstr "GNOME необходимо заблокировать экран"
#.
#. XXX: another option is to kick the user into the gdm login
#. screen, where we're not affected by grabs
#: ../js/ui/screenShield.js:758 ../js/ui/screenShield.js:1169
#: ../js/ui/screenShield.js:756 ../js/ui/screenShield.js:1151
msgid "Unable to lock"
msgstr "Не удалось заблокировать"
#: ../js/ui/screenShield.js:759 ../js/ui/screenShield.js:1170
#: ../js/ui/screenShield.js:757 ../js/ui/screenShield.js:1152
msgid "Lock was blocked by an application"
msgstr "Блокировано помешало приложение"
msgstr "Блокировке помешало приложение"
#: ../js/ui/searchDisplay.js:431
#: ../js/ui/searchDisplay.js:451
msgid "Searching…"
msgstr "Поиск…"
#: ../js/ui/searchDisplay.js:475
#: ../js/ui/searchDisplay.js:495
msgid "No results."
msgstr "Нет результатов."
@ -1353,11 +1354,11 @@ msgstr "Копировать"
msgid "Paste"
msgstr "Вставить"
#: ../js/ui/shellEntry.js:105
#: ../js/ui/shellEntry.js:106
msgid "Show Text"
msgstr "Показать текст"
#: ../js/ui/shellEntry.js:107
#: ../js/ui/shellEntry.js:108
msgid "Hide Text"
msgstr "Скрыть текст"
@ -1369,7 +1370,7 @@ msgstr "Пароль"
msgid "Remember Password"
msgstr "Запомнить пароль"
#: ../js/ui/shellMountOperation.js:403 ../js/ui/unlockDialog.js:140
#: ../js/ui/shellMountOperation.js:403 ../js/ui/unlockDialog.js:112
msgid "Unlock"
msgstr "Разблокировать"
@ -1670,7 +1671,7 @@ msgstr "Батарея"
#: ../js/ui/status/power.js:81
msgid "Power Settings"
msgstr "Параметры питания"
msgstr "Параметры электропитания"
#. 0 is reported when UPower does not have enough data
#. to estimate battery life
@ -1778,11 +1779,11 @@ msgstr "Громкость"
msgid "Microphone"
msgstr "Микрофон"
#: ../js/ui/unlockDialog.js:151
#: ../js/ui/unlockDialog.js:123
msgid "Log in as another user"
msgstr "Войти от имени другого пользователя"
#: ../js/ui/unlockDialog.js:177
#: ../js/ui/unlockDialog.js:144
msgid "Unlock Window"
msgstr "Разблокировать окно"
@ -1810,27 +1811,27 @@ msgstr "Бездействует"
msgid "Offline"
msgstr "Не в сети"
#: ../js/ui/userMenu.js:780
#: ../js/ui/userMenu.js:781
msgid "Notifications"
msgstr "Уведомления"
#: ../js/ui/userMenu.js:796
#: ../js/ui/userMenu.js:797
msgid "Switch User"
msgstr "Сменить пользователя"
#: ../js/ui/userMenu.js:801
#: ../js/ui/userMenu.js:802
msgid "Log Out"
msgstr "Выйти из системы"
#: ../js/ui/userMenu.js:821
#: ../js/ui/userMenu.js:822
msgid "Install Updates & Restart"
msgstr "Установить обновления и выполнить перезагрузку"
#: ../js/ui/userMenu.js:839
#: ../js/ui/userMenu.js:840
msgid "Your chat status will be set to busy"
msgstr "Будет установлен статус «не беспокоить»"
#: ../js/ui/userMenu.js:840
#: ../js/ui/userMenu.js:841
msgid ""
"Notifications are now disabled, including chat messages. Your online status "
"has been adjusted to let others know that you might not see their messages."
@ -1838,33 +1839,35 @@ msgstr ""
"Уведомления отключены, включая сообщения в чате. Ваш статус доступности "
"изменён, чтобы другие знали, что вы возможно не видите их сообщения."
#: ../js/ui/userMenu.js:886
#: ../js/ui/userMenu.js:888
msgid "Other users are logged in."
msgstr "В системе имеются сеансы других пользователей."
msgstr "В системе имеются открытые сеансы других пользователей."
#: ../js/ui/userMenu.js:891
#: ../js/ui/userMenu.js:893
msgid "Shutting down might cause them to lose unsaved work."
msgstr "Завершение работы может привести к потере несохранённых изменений."
#: ../js/ui/userMenu.js:918
#. Translators: Remote here refers to a remote session, like a ssh login
#: ../js/ui/userMenu.js:921
#, c-format
msgid "%s (remote)"
msgstr "%s (удалённый)"
#: ../js/ui/userMenu.js:920
#. Translators: Console here refers to a tty like a VT console
#: ../js/ui/userMenu.js:924
#, c-format
msgid "%s (console)"
msgstr "%s (консоль)"
#: ../js/ui/viewSelector.js:101
#: ../js/ui/viewSelector.js:100
msgid "Applications"
msgstr "Приложения"
#: ../js/ui/viewSelector.js:105
#: ../js/ui/viewSelector.js:104
msgid "Search"
msgstr "Поиск"
#: ../js/ui/wanda.js:92
#: ../js/ui/wanda.js:77
#, c-format
msgid ""
"Sorry, no wisdom for you today:\n"
@ -1873,7 +1876,7 @@ msgstr ""
"Извините, на сегодня нет никаких советов:\n"
"%s"
#: ../js/ui/wanda.js:96
#: ../js/ui/wanda.js:81
#, c-format
msgid "%s the Oracle says"
msgstr "Оракул говорит: «%s»"

660
po/sk.po

File diff suppressed because it is too large Load Diff

574
po/sl.po

File diff suppressed because it is too large Load Diff

592
po/sr.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

1141
po/ta.po

File diff suppressed because it is too large Load Diff

1171
po/te.po

File diff suppressed because it is too large Load Diff

1888
po/tg.po Normal file

File diff suppressed because it is too large Load Diff

View File

@ -11,8 +11,8 @@ msgid ""
msgstr ""
"Project-Id-Version: gnome-shell\n"
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-shell&keywords=I18N+L10N&component=general\n"
"POT-Creation-Date: 2013-03-02 23:02+0000\n"
"PO-Revision-Date: 2013-03-03 15:57+0900\n"
"POT-Creation-Date: 2013-03-04 08:38+0000\n"
"PO-Revision-Date: 2013-03-07 21:01+0900\n"
"Last-Translator: Gheyret Kenji <gheyret@gmail.com>\n"
"Language-Team: Uyghur Computer Science Association <UKIJ@yahoogroups.com>\n"
"Language: \n"
@ -112,13 +112,13 @@ msgstr "مۇناسىپ پروگرامما بەلگىسى يىغقۇچ رايون
#: ../data/org.gnome.shell.gschema.xml.in.in.h:9
msgid "List of categories that should be displayed as folders"
msgstr ""
msgstr "قىسقۇچ سۈپىتىدە كۆرسىتىلىدىغان كاتېگورىيەلەرنىڭ تىزىمى"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:10
msgid ""
"Each category name in this list will be represented as folder in the "
"application view, rather than being displayed inline in the main view."
msgstr ""
msgstr "پروگرامما كۆرۈنۈشىدە ھەر بىر كاتېگورىيە ئاتى قىسقۇچ سۈپىتىدە ئىپادىلىنىدۇ، ئاساسىي كۆرۈنۈشتە كۆرسىتىلمەيدۇ."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:11
msgid "History for command (Alt-F2) dialog"
@ -316,7 +316,6 @@ msgid "Select an extension to configure using the combobox above."
msgstr "يۇقىرىدىكى combobox دىن سەپلەيدىغان كېڭەيتىلمىنى تاللاڭ."
#: ../js/gdm/loginDialog.js:405
#| msgid "Session..."
msgid "Session…"
msgstr "ئەڭگىمە…"
@ -331,7 +330,7 @@ msgstr "تىزىمدا يوقمۇ؟"
#: ../js/ui/components/polkitAgent.js:162 ../js/ui/endSessionDialog.js:375
#: ../js/ui/extensionDownloader.js:195 ../js/ui/shellMountOperation.js:399
#: ../js/ui/status/bluetooth.js:415 ../js/ui/unlockDialog.js:126
#: ../js/ui/userMenu.js:932
#: ../js/ui/userMenu.js:934
msgid "Cancel"
msgstr "ئەمەلدىن قالدۇر"
@ -361,8 +360,8 @@ msgstr "كىرىش كۆزنىكى"
msgid "Power"
msgstr "توك مەنبە"
#: ../js/gdm/powerMenu.js:93 ../js/ui/userMenu.js:694 ../js/ui/userMenu.js:698
#: ../js/ui/userMenu.js:814
#: ../js/gdm/powerMenu.js:93 ../js/ui/userMenu.js:695 ../js/ui/userMenu.js:699
#: ../js/ui/userMenu.js:815
msgid "Suspend"
msgstr "توڭلات"
@ -370,14 +369,14 @@ msgstr "توڭلات"
msgid "Restart"
msgstr "قايتا قوزغات"
#: ../js/gdm/powerMenu.js:103 ../js/ui/userMenu.js:696
#: ../js/ui/userMenu.js:698 ../js/ui/userMenu.js:813 ../js/ui/userMenu.js:936
#: ../js/gdm/powerMenu.js:103 ../js/ui/userMenu.js:697
#: ../js/ui/userMenu.js:699 ../js/ui/userMenu.js:814 ../js/ui/userMenu.js:938
msgid "Power Off"
msgstr "توكنى ئۈز"
#: ../js/gdm/util.js:182
msgid "Authentication error"
msgstr "سالاھىيەت دەلىللەش خاتالىقى"
msgstr "كىملىك دەلىللەش خاتالىقى"
#. Translators: this message is shown below the password entry field
#. to indicate the user can swipe their finger instead
@ -435,7 +434,7 @@ msgstr "%s يىغقۇچىڭىزغا قوشۇلدى."
msgid "%s has been removed from your favorites."
msgstr "%s يىغقۇچىڭىزدىن چىقىرىۋېتىلىدۇ."
#: ../js/ui/backgroundMenu.js:19 ../js/ui/userMenu.js:787
#: ../js/ui/backgroundMenu.js:19 ../js/ui/userMenu.js:788
msgid "Settings"
msgstr "تەڭشەكلەر"
@ -697,7 +696,7 @@ msgstr "%s كە باغلىنىش ئۈچۈن بىر ئىمغا ئېھتىي
#: ../js/ui/components/polkitAgent.js:55
msgid "Authentication Required"
msgstr "سالاھىيەت دەلىللەش زۆرۈر"
msgstr "كىملىك دەلىللەش زۆرۈر"
#: ../js/ui/components/polkitAgent.js:93
msgid "Administrator"
@ -847,7 +846,7 @@ msgstr "تور خاتالىقى"
#: ../js/ui/components/telepathyClient.js:1300
msgid "Authentication failed"
msgstr "سالاھىيەت دەلىللەش مەغلۇپ بولدى"
msgstr "كىملىك دەلىللەش مەغلۇپ بولدى"
#: ../js/ui/components/telepathyClient.js:1302
msgid "Encryption error"
@ -956,7 +955,7 @@ msgstr "ھېساباتنى كۆرۈش"
msgid "Unknown reason"
msgstr "نامەلۇم سەۋەب"
#: ../js/ui/ctrlAltTab.js:29 ../js/ui/viewSelector.js:97
#: ../js/ui/ctrlAltTab.js:29 ../js/ui/viewSelector.js:96
msgid "Windows"
msgstr "كۆزنەكلەر"
@ -1144,7 +1143,6 @@ msgid "Remove"
msgstr "چىقىرىۋەت"
#: ../js/ui/messageTray.js:1501
#| msgid "No Messages"
msgid "Clear Messages"
msgstr "ئۇچۇرنى تازىلا"
@ -1188,7 +1186,6 @@ msgstr "قىسقىچە بايان"
#. active; it should not exceed ~30
#. characters.
#: ../js/ui/overview.js:284
#| msgid "Type to search..."
msgid "Type to search…"
msgstr "ئىزدەيدىغاننى كىرگۈزۈڭ.…"
@ -1235,7 +1232,7 @@ msgid "%d new notification"
msgid_plural "%d new notifications"
msgstr[0] "%d دانە ئۇقتۇرۇش"
#: ../js/ui/screenShield.js:442 ../js/ui/userMenu.js:805
#: ../js/ui/screenShield.js:442 ../js/ui/userMenu.js:806
msgid "Lock"
msgstr "قۇلۇپلا"
@ -1251,7 +1248,6 @@ msgstr "گىنوم ئېكراننى قۇلۇپلىشى زۆرۈر"
#. XXX: another option is to kick the user into the gdm login
#. screen, where we're not affected by grabs
#: ../js/ui/screenShield.js:758 ../js/ui/screenShield.js:1169
#| msgid "Unable to connect to %s"
msgid "Unable to lock"
msgstr "قۇلۇپلىغىلى بولمىدى"
@ -1260,7 +1256,6 @@ msgid "Lock was blocked by an application"
msgstr "بىر پروگرامما قۇلۇپلاشنى توسۇپ قويغان"
#: ../js/ui/searchDisplay.js:431
#| msgid "Searching..."
msgid "Searching…"
msgstr "ئىزدەۋاتىدۇ…"
@ -1356,12 +1351,10 @@ msgid "Visibility"
msgstr "كۆرۈشچانلىقى"
#: ../js/ui/status/bluetooth.js:59
#| msgid "Send Files to Device..."
msgid "Send Files to Device…"
msgstr "ھۆججەتلەرنى ئۈسكۈنىگە ئەۋەتىش…"
#: ../js/ui/status/bluetooth.js:60
#| msgid "Set Up a New Device..."
msgid "Set Up a New Device…"
msgstr "يېڭى ئۈسكۈنە ئورنىتىش…"
@ -1388,7 +1381,6 @@ msgid "connecting..."
msgstr "باغلىنىۋاتىدۇ…"
#: ../js/ui/status/bluetooth.js:239
#| msgid "Send Files..."
msgid "Send Files…"
msgstr "ھۆججەت يوللاش…"
@ -1494,7 +1486,7 @@ msgstr "باشقۇرۇلمىغان"
#. Translators: this is for network connections that require some kind of key or password
#: ../js/ui/status/network.js:469 ../js/ui/status/network.js:1549
msgid "authentication required"
msgstr "سالاھىيەت دەلىللەش زۆرۈر"
msgstr "كىملىك دەلىللەش زۆرۈر"
#. Translators: this is for devices that require some kind of firmware or kernel
#. module, which is missing
@ -1601,7 +1593,6 @@ msgstr "توك مەنبە تەڭشىكى"
#. 0 is reported when UPower does not have enough data
#. to estimate battery life
#: ../js/ui/status/power.js:99
#| msgid "Estimating..."
msgid "Estimating…"
msgstr "مۆلچەرلەۋاتىدۇ…"
@ -1705,79 +1696,79 @@ msgstr "باشقا ئىشلەتكۈچى سۈپىتىدە كىر"
msgid "Unlock Window"
msgstr "كۆزنەكنى قۇلۇپلا"
#: ../js/ui/userMenu.js:192
#: ../js/ui/userMenu.js:193
msgid "Available"
msgstr "ئىشلەتكىلى بولىدۇ"
#: ../js/ui/userMenu.js:195
#: ../js/ui/userMenu.js:196
msgid "Busy"
msgstr "ئالدىراش"
#: ../js/ui/userMenu.js:198
#: ../js/ui/userMenu.js:199
msgid "Invisible"
msgstr "يوشۇرۇن"
#: ../js/ui/userMenu.js:201
#: ../js/ui/userMenu.js:202
msgid "Away"
msgstr "يوق"
#: ../js/ui/userMenu.js:204
#: ../js/ui/userMenu.js:205
msgid "Idle"
msgstr "بىكار"
#: ../js/ui/userMenu.js:207
#: ../js/ui/userMenu.js:208
msgid "Offline"
msgstr "توردا يوق"
#: ../js/ui/userMenu.js:779
#: ../js/ui/userMenu.js:780
msgid "Notifications"
msgstr "ئۇقتۇرۇشلار"
#: ../js/ui/userMenu.js:795
#: ../js/ui/userMenu.js:796
msgid "Switch User"
msgstr "ئىشلەتكۈچى ئالماشتۇرۇش"
#: ../js/ui/userMenu.js:800
#: ../js/ui/userMenu.js:801
msgid "Log Out"
msgstr "تىزىمدىن چىقىش"
#: ../js/ui/userMenu.js:820
#: ../js/ui/userMenu.js:821
msgid "Install Updates & Restart"
msgstr "يېڭىلانمىلارنى ئورنىتىپ قايتا قوزغات"
#: ../js/ui/userMenu.js:838
#: ../js/ui/userMenu.js:839
msgid "Your chat status will be set to busy"
msgstr "سىزنىڭ سۆھبەت ھالىتىڭىز ئالدىراش قىلىنىدۇ"
#: ../js/ui/userMenu.js:839
#: ../js/ui/userMenu.js:840
msgid ""
"Notifications are now disabled, including chat messages. Your online status "
"has been adjusted to let others know that you might not see their messages."
msgstr ""
#: ../js/ui/userMenu.js:885
#: ../js/ui/userMenu.js:886
msgid "Other users are logged in."
msgstr "باشقا ئىشلەتكۈچىلەر كىردى:"
#: ../js/ui/userMenu.js:890
#: ../js/ui/userMenu.js:891
msgid "Shutting down might cause them to lose unsaved work."
msgstr "تاقالسا ساقلانمىغان خىزمەتلەر يوقىلىشى مۇمكىن."
#: ../js/ui/userMenu.js:916
#: ../js/ui/userMenu.js:918
#, c-format
msgid "%s (remote)"
msgstr "%s (يىراق)"
#: ../js/ui/userMenu.js:918
#: ../js/ui/userMenu.js:920
#, c-format
msgid "%s (console)"
msgstr "%s (تىزگىن كۆزنەك)"
#: ../js/ui/viewSelector.js:101
#: ../js/ui/viewSelector.js:100
msgid "Applications"
msgstr "پروگراممىلار"
#: ../js/ui/viewSelector.js:105
#: ../js/ui/viewSelector.js:104
msgid "Search"
msgstr "ئىزدە"

1121
po/uk.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -287,7 +287,7 @@ libgnome_shell_la_LIBADD = \
libgnome_shell_la_CPPFLAGS = $(gnome_shell_cflags)
Shell-0.1.gir: libgnome-shell.la St-1.0.gir
Shell_0_1_gir_INCLUDES = Clutter-1.0 ClutterX11-1.0 Meta-3.0 TelepathyGLib-0.12 TelepathyLogger-0.2 Soup-2.4 GMenu-3.0 NetworkManager-1.0 NMClient-1.0
Shell_0_1_gir_INCLUDES = Clutter-1.0 ClutterX11-1.0 Meta-3.0 TelepathyGLib-0.12 Soup-2.4 GMenu-3.0 NetworkManager-1.0 NMClient-1.0
Shell_0_1_gir_CFLAGS = $(libgnome_shell_la_CPPFLAGS) -I $(srcdir)
Shell_0_1_gir_LIBS = libgnome-shell.la
Shell_0_1_gir_FILES = $(libgnome_shell_la_gir_sources)

View File

@ -490,6 +490,17 @@ calendar_sources_registry_source_removed_cb (ESourceRegistry *registry,
}
}
static void
ensure_appointment_sources (CalendarSources *sources)
{
if (!sources->priv->appointment_sources.loaded)
{
calendar_sources_load_esource_list (sources->priv->registry,
&sources->priv->appointment_sources);
sources->priv->appointment_sources.loaded = TRUE;
}
}
GList *
calendar_sources_get_appointment_clients (CalendarSources *sources)
{
@ -497,12 +508,7 @@ calendar_sources_get_appointment_clients (CalendarSources *sources)
g_return_val_if_fail (CALENDAR_IS_SOURCES (sources), NULL);
if (!sources->priv->appointment_sources.loaded)
{
calendar_sources_load_esource_list (sources->priv->registry,
&sources->priv->appointment_sources);
sources->priv->appointment_sources.loaded = TRUE;
}
ensure_appointment_sources (sources);
list = g_hash_table_get_values (sources->priv->appointment_sources.clients);
@ -512,6 +518,17 @@ calendar_sources_get_appointment_clients (CalendarSources *sources)
return list;
}
static void
ensure_task_sources (CalendarSources *sources)
{
if (!sources->priv->task_sources.loaded)
{
calendar_sources_load_esource_list (sources->priv->registry,
&sources->priv->task_sources);
sources->priv->task_sources.loaded = TRUE;
}
}
GList *
calendar_sources_get_task_clients (CalendarSources *sources)
{
@ -519,12 +536,7 @@ calendar_sources_get_task_clients (CalendarSources *sources)
g_return_val_if_fail (CALENDAR_IS_SOURCES (sources), NULL);
if (!sources->priv->task_sources.loaded)
{
calendar_sources_load_esource_list (sources->priv->registry,
&sources->priv->task_sources);
sources->priv->task_sources.loaded = TRUE;
}
ensure_task_sources (sources);
list = g_hash_table_get_values (sources->priv->task_sources.clients);
@ -533,3 +545,15 @@ calendar_sources_get_task_clients (CalendarSources *sources)
return list;
}
gboolean
calendar_sources_has_sources (CalendarSources *sources)
{
g_return_val_if_fail (CALENDAR_IS_SOURCES (sources), FALSE);
ensure_appointment_sources (sources);
ensure_task_sources (sources);
return g_hash_table_size (sources->priv->appointment_sources.clients) > 0 ||
g_hash_table_size (sources->priv->task_sources.clients) > 0;
}

View File

@ -61,6 +61,8 @@ CalendarSources *calendar_sources_get (void);
GList *calendar_sources_get_appointment_clients (CalendarSources *sources);
GList *calendar_sources_get_task_clients (CalendarSources *sources);
gboolean calendar_sources_has_sources (CalendarSources *sources);
G_END_DECLS
#endif /* __CALENDAR_SOURCES_H__ */

View File

@ -57,6 +57,7 @@ static const gchar introspection_xml[] =
" <signal name='Changed'/>"
" <property name='Since' type='x' access='read'/>"
" <property name='Until' type='x' access='read'/>"
" <property name='HasCalendars' type='b' access='read'/>"
" </interface>"
"</node>";
static GDBusNodeInfo *introspection_data = NULL;
@ -726,6 +727,12 @@ app_load_events (App *app)
app->cache_invalid = FALSE;
}
static gboolean
app_has_calendars (App *app)
{
return calendar_sources_has_sources (app->sources);
}
static void
on_appointment_sources_changed (CalendarSources *sources,
gpointer user_data)
@ -734,6 +741,26 @@ on_appointment_sources_changed (CalendarSources *sources,
print_debug ("Sources changed\n");
app_load_events (app);
/* Notify the HasCalendars property */
{
GVariantBuilder dict_builder;
g_variant_builder_init (&dict_builder, G_VARIANT_TYPE ("a{sv}"));
g_variant_builder_add (&dict_builder, "{sv}", "HasCalendars",
g_variant_new_boolean (app_has_calendars (app)));
g_dbus_connection_emit_signal (g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL),
NULL,
"/org/gnome/Shell/CalendarServer",
"org.freedesktop.DBus.Properties",
"PropertiesChanged",
g_variant_new ("(sa{sv}as)",
"org.gnome.Shell.CalendarServer",
&dict_builder,
NULL),
NULL);
}
}
static App *
@ -933,6 +960,10 @@ handle_get_property (GDBusConnection *connection,
{
ret = g_variant_new_int64 (app->until);
}
else if (g_strcmp0 (property_name, "HasCalendars") == 0)
{
ret = g_variant_new_boolean (app_has_calendars (app));
}
else
{
g_assert_not_reached ();

View File

@ -8,9 +8,7 @@
#include "shell-embedded-window-private.h"
/* This type is a subclass of GtkWindow that ties the window to a
* ShellGtkEmbed; the window is reparented into the stage
* window for the actor and the resizing logic is bound to the clutter
* logic.
* ShellGtkEmbed; the resizing logic is bound to the clutter logic.
*
* The typical usage we might expect is
*
@ -28,16 +26,13 @@
G_DEFINE_TYPE (ShellEmbeddedWindow, shell_embedded_window, GTK_TYPE_WINDOW);
enum {
PROP_0,
PROP_STAGE
PROP_0
};
struct _ShellEmbeddedWindowPrivate {
ShellGtkEmbed *actor;
GdkRectangle position;
Window stage_xwindow;
};
/*
@ -80,27 +75,6 @@ shell_embedded_window_hide (GtkWidget *widget)
GTK_WIDGET_CLASS (shell_embedded_window_parent_class)->hide (widget);
}
static void
shell_embedded_window_realize (GtkWidget *widget)
{
ShellEmbeddedWindow *window = SHELL_EMBEDDED_WINDOW (widget);
GTK_WIDGET_CLASS (shell_embedded_window_parent_class)->realize (widget);
/* Using XReparentWindow() is simpler than using gdk_window_reparent(),
* since it avoids maybe having to create a new foreign GDK window for
* the stage. However, GDK will be left thinking that the parent of
* window->window is the root window - it's not immediately clear
* to me whether that is more or less likely to cause problems than
* modifying the GDK hierarchy.
*/
XReparentWindow (GDK_DISPLAY_XDISPLAY (gtk_widget_get_display (widget)),
gdk_x11_window_get_xid (gtk_widget_get_window (widget)),
window->priv->stage_xwindow,
window->priv->position.x, window->priv->position.y);
}
static gboolean
shell_embedded_window_configure_event (GtkWidget *widget,
GdkEventConfigure *event)
@ -127,27 +101,6 @@ shell_embedded_window_check_resize (GtkContainer *container)
clutter_actor_queue_relayout (CLUTTER_ACTOR (window->priv->actor));
}
static void
shell_embedded_window_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
ShellEmbeddedWindow *window = SHELL_EMBEDDED_WINDOW (object);
switch (prop_id)
{
case PROP_STAGE:
window->priv->stage_xwindow =
clutter_x11_get_stage_window (g_value_get_object (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static GObject *
shell_embedded_window_constructor (GType gtype,
guint n_properties,
@ -182,23 +135,13 @@ shell_embedded_window_class_init (ShellEmbeddedWindowClass *klass)
g_type_class_add_private (klass, sizeof (ShellEmbeddedWindowPrivate));
object_class->set_property = shell_embedded_window_set_property;
object_class->constructor = shell_embedded_window_constructor;
widget_class->show = shell_embedded_window_show;
widget_class->hide = shell_embedded_window_hide;
widget_class->realize = shell_embedded_window_realize;
widget_class->configure_event = shell_embedded_window_configure_event;
container_class->check_resize = shell_embedded_window_check_resize;
g_object_class_install_property (object_class,
PROP_STAGE,
g_param_spec_object ("stage",
"Stage",
"ClutterStage to embed on",
CLUTTER_TYPE_STAGE,
G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
}
static void
@ -282,9 +225,8 @@ _shell_embedded_window_unmap (ShellEmbeddedWindow *window)
* Public API
*/
GtkWidget *
shell_embedded_window_new (ClutterStage *stage)
shell_embedded_window_new (void)
{
return g_object_new (SHELL_TYPE_EMBEDDED_WINDOW,
"stage", stage,
NULL);
}

View File

@ -30,6 +30,6 @@ struct _ShellEmbeddedWindowClass
};
GType shell_embedded_window_get_type (void) G_GNUC_CONST;
GtkWidget *shell_embedded_window_new (ClutterStage *stage);
GtkWidget *shell_embedded_window_new (void);
#endif /* __SHELL_EMBEDDED_WINDOW_H__ */

View File

@ -3,8 +3,11 @@
#include "config.h"
#include "shell-embedded-window-private.h"
#include "shell-global.h"
#include <gdk/gdkx.h>
#include <meta/display.h>
#include <meta/window.h>
enum {
PROP_0,
@ -15,9 +18,14 @@ enum {
struct _ShellGtkEmbedPrivate
{
ShellEmbeddedWindow *window;
ClutterActor *window_actor;
guint window_actor_destroyed_handler;
guint window_created_handler;
};
G_DEFINE_TYPE (ShellGtkEmbed, shell_gtk_embed, CLUTTER_X11_TYPE_TEXTURE_PIXMAP);
G_DEFINE_TYPE (ShellGtkEmbed, shell_gtk_embed, CLUTTER_TYPE_CLONE);
static void shell_gtk_embed_set_window (ShellGtkEmbed *embed,
ShellEmbeddedWindow *window);
@ -30,39 +38,106 @@ shell_gtk_embed_on_window_destroy (GtkWidget *object,
}
static void
shell_gtk_embed_on_window_realize (GtkWidget *widget,
shell_gtk_embed_remove_window_actor (ShellGtkEmbed *embed)
{
ShellGtkEmbedPrivate *priv = embed->priv;
if (priv->window_actor)
{
g_signal_handler_disconnect (priv->window_actor,
priv->window_actor_destroyed_handler);
priv->window_actor_destroyed_handler = 0;
g_object_unref (priv->window_actor);
priv->window_actor = NULL;
}
clutter_clone_set_source (CLUTTER_CLONE (embed), NULL);
}
static void
shell_gtk_embed_window_created_cb (MetaDisplay *display,
MetaWindow *window,
ShellGtkEmbed *embed)
{
/* Here automatic=FALSE means to use CompositeRedirectManual.
* That is, the X server shouldn't draw the window onto the
* screen.
*/
clutter_x11_texture_pixmap_set_window (CLUTTER_X11_TEXTURE_PIXMAP (embed),
gdk_x11_window_get_xid (gtk_widget_get_window (widget)),
FALSE);
ShellGtkEmbedPrivate *priv = embed->priv;
Window xwindow = meta_window_get_xwindow (window);
GdkWindow *gdk_window = gtk_widget_get_window (GTK_WIDGET (priv->window));
if (xwindow == gdk_x11_window_get_xid (gdk_window))
{
ClutterActor *window_actor =
CLUTTER_ACTOR (meta_window_get_compositor_private (window));
MetaDisplay *display = shell_global_get_display (shell_global_get ());
GCallback remove_cb = G_CALLBACK (shell_gtk_embed_remove_window_actor);
cairo_region_t *empty_region;
clutter_clone_set_source (CLUTTER_CLONE (embed), window_actor);
/* We want to explicitly clear the clone source when the window
actor is destroyed because otherwise we might end up keeping
it alive after it has been disposed. Otherwise this can cause
a crash if there is a paint after mutter notices that the top
level window has been destroyed, which causes it to dispose
the window, and before the tray manager notices that the
window is gone which would otherwise reset the window and
unref the clone */
priv->window_actor = g_object_ref (window_actor);
priv->window_actor_destroyed_handler =
g_signal_connect_swapped (window_actor,
"destroy",
remove_cb,
embed);
/* Hide the original actor otherwise it will appear in the scene
as a normal window */
clutter_actor_set_opacity (window_actor, 0);
/* Set an empty input shape on the window so that it can't get
any input. This probably isn't the ideal way to acheive this.
It would probably be better to force the window to go behind
Mutter's guard window, but this is quite difficult to do as
Mutter doesn't manage the stacking for override redirect
windows and the guard window is repeatedly lowered to the
bottom of the stack. */
empty_region = cairo_region_create ();
gdk_window_input_shape_combine_region (gdk_window,
empty_region,
0, 0 /* offset x/y */);
cairo_region_destroy (empty_region);
/* Now that we've found the window we don't need to listen for
new windows anymore */
g_signal_handler_disconnect (display,
priv->window_created_handler);
priv->window_created_handler = 0;
}
}
static void
shell_gtk_embed_set_window (ShellGtkEmbed *embed,
ShellEmbeddedWindow *window)
{
MetaDisplay *display = shell_global_get_display (shell_global_get ());
if (embed->priv->window)
{
if (embed->priv->window_created_handler)
{
g_signal_handler_disconnect (display,
embed->priv->window_created_handler);
embed->priv->window_created_handler = 0;
}
shell_gtk_embed_remove_window_actor (embed);
_shell_embedded_window_set_actor (embed->priv->window, NULL);
g_object_unref (embed->priv->window);
clutter_x11_texture_pixmap_set_window (CLUTTER_X11_TEXTURE_PIXMAP (embed),
None,
FALSE);
g_signal_handlers_disconnect_by_func (embed->priv->window,
(gpointer)shell_gtk_embed_on_window_destroy,
embed);
g_signal_handlers_disconnect_by_func (embed->priv->window,
(gpointer)shell_gtk_embed_on_window_realize,
embed);
}
embed->priv->window = window;
@ -75,11 +150,14 @@ shell_gtk_embed_set_window (ShellGtkEmbed *embed,
g_signal_connect (embed->priv->window, "destroy",
G_CALLBACK (shell_gtk_embed_on_window_destroy), embed);
g_signal_connect (embed->priv->window, "realize",
G_CALLBACK (shell_gtk_embed_on_window_realize), embed);
if (gtk_widget_get_realized (GTK_WIDGET (window)))
shell_gtk_embed_on_window_realize (GTK_WIDGET (embed->priv->window), embed);
/* Listen for new windows so we can detect when Mutter has
created a MutterWindow for this window */
embed->priv->window_created_handler =
g_signal_connect (display,
"window-created",
G_CALLBACK (shell_gtk_embed_window_created_cb),
embed);
}
clutter_actor_queue_relayout (CLUTTER_ACTOR (embed));
@ -260,11 +338,6 @@ shell_gtk_embed_init (ShellGtkEmbed *embed)
{
embed->priv = G_TYPE_INSTANCE_GET_PRIVATE (embed, SHELL_TYPE_GTK_EMBED,
ShellGtkEmbedPrivate);
/* automatic here means whether ClutterX11TexturePixmap should
* process damage update and refresh the pixmap itself.
*/
clutter_x11_texture_pixmap_set_automatic (CLUTTER_X11_TEXTURE_PIXMAP (embed), TRUE);
}
/*

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