Compare commits

...

62 Commits

Author SHA1 Message Date
Ray Strode
b19cef9dd5 unlockDialog: Use GdmUtil.AuthPrompt instead of ModalDialog
commit ea02380c15 made the login
screen stop using ModalDialog. It makes sense for the unlock
code to also stop using ModalDialog, too (for similar reasons).

Now that the login screen's auth prompt code has been separated
out, the unlock dialog can use it to get the buttons and spinners
etc, that it was previously getting from ModalDialog.

This commit drops the ModalDialog usage in the unlock dialog, and
makes the unlock dialog use GdmUtil.AuthPrompt instead.
2013-07-16 14:13:05 -04:00
Ray Strode
2d4473c35a loginDialog: factor auth prompt code out to utils
Right now there is a lot of duplicated code between the unlock
dialog and the login dialog.

This commit moves the login dialog's auth prompt to a separate
class, so that it can (in a subsequent commit) be used by the
unlock dialog.
2013-07-16 14:13:02 -04:00
Ray Strode
6d9fb50207 loginDialog: handle typing at screenshield
If the screenshield is up and the user starts typing, we need to
keep track of it and replay it later, otherwise what they type
will be ignored.

This is useful when the user has disable-user-list set to TRUE,
and will also be useful to bring feature parity between the
login screen and unlock screen.

https://bugzilla.gnome.org/show_bug.cgi?id=702308
2013-07-16 14:04:57 -04:00
Ray Strode
86b8885d96 theme: fix spacing for "Log in as another user" button
At some point the Not Listed? button was moved to align it better
in the login screen.  That nudging made the "Log in as another user"
button (which uses the same style class) align worse.

This commit removes the padding at the unlock screen.

https://bugzilla.gnome.org/show_bug.cgi?id=704318
2013-07-16 10:53:59 -04:00
Allan Day
cf7355e4d0 theme: change the lock screen notification background
The current look is too heavy and looks out of place. Simplify
the background in accordance with the latest mockups.

https://bugzilla.gnome.org/show_bug.cgi?id=702305
2013-07-15 19:09:56 +01:00
Jasper St. Pierre
dab8c5ea56 popupMenu: Fix bad syntax error 2013-07-15 12:57:51 -04:00
Jasper St. Pierre
4b889eac32 popupMenu: Ensure that submenus are properly hidden when insensitive
We don't actually propagate sensitivity information to submenus; we
simply make sure that they can never be open when the parent is
insensitive.

https://bugzilla.gnome.org/show_bug.cgi?id=702539
2013-07-15 12:34:23 -04:00
Jasper St. Pierre
86835db8f2 popupMenu: Propagate sensitivity to menu children
This way, if a parent is insensitive, all children will be, too.
Though PopupSubMenus will be forced closed, PopupMenuSection needs
the propagation.

https://bugzilla.gnome.org/show_bug.cgi?id=702539
2013-07-15 12:34:23 -04:00
Jasper St. Pierre
bc317bf3f2 popupMenu: Remove 'sensitive' input param
It's hard to implement properly, was broken, and unused. If somebody
really wants it, they can call setSensitive after constructing the item.

https://bugzilla.gnome.org/show_bug.cgi?id=702539
2013-07-15 12:34:22 -04:00
Jasper St. Pierre
5c036eadf9 popupMenu: Only allow one submenu to be open at a time
When the user opens another submenu, close the first one.

https://bugzilla.gnome.org/show_bug.cgi?id=702539
2013-07-15 12:34:22 -04:00
Jasper St. Pierre
263474705b popupMenu: Emit open-state-changed at the start of animating a submenu
Doing it at the end has confusing semantics, especially as there is
this point where isOpen is true, but the corresponding open-state-changed
has not been emitted.

https://bugzilla.gnome.org/show_bug.cgi?id=702539
2013-07-15 12:34:22 -04:00
Jasper St. Pierre
1e781ec78f popupMenu: Remove connectSubMenuSignals
The code here is a bit messy, as the signal disconnection is handled
in two different places. Share code in a better, different way.

https://bugzilla.gnome.org/show_bug.cgi?id=702539
2013-07-15 12:34:22 -04:00
Jasper St. Pierre
ef1eabf033 popupMenu: Ignore submenus when getting the column widths
The new designs don't want these to be aligned the same way.

https://bugzilla.gnome.org/show_bug.cgi?id=702539
2013-07-15 12:34:22 -04:00
Jasper St. Pierre
2fa40555e6 popupMenu: Simplify allocation code
Use ClutterActor.allocate_align_fill() so we don't have to do
this math ourselves. At the same time, clean up the RTL handling
so that it's easier to follow.

https://bugzilla.gnome.org/show_bug.cgi?id=702539
2013-07-15 12:34:22 -04:00
Jasper St. Pierre
2aae272d86 popupMenu: Don't close submenus when the toplevel container is closed
It seems this behavior at one time was intentional, but I (along with
the designers) think it looks ugly having the menu having its insides
shrinking and shifting around while fading out of existence.

There's two cases where we currently explicitly try to animate the
submenu closed -- when an item is clicked inside the submenu, and
when the toplevel closes. This removes both of those.

The user expectation is that submenus will be closed the next time the
toplevel is open even if they were open before, so force submenus closed
when the toplevel finishes fading out, without any animation.

https://bugzilla.gnome.org/show_bug.cgi?id=702539
2013-07-15 12:24:27 -04:00
Jasper St. Pierre
7db0900cc8 popupMenu: Introduce a way of closing toplevels from sections
As the aggregate menu will be built out of sections from each
of the menus, we need to ensure that activating an item in one
of these sections can close the main menu, even when it is not
a menu item. The new API also needs to be flexible enough to
ensure that animations can be controlled, like the buttons that
lock the screen or launch a new session.

Port the user menu to use this new API as well.

https://bugzilla.gnome.org/show_bug.cgi?id=702539
2013-07-15 12:01:07 -04:00
Jasper St. Pierre
c1e2d66abd popupMenu: Add a simple way to get the toplevel for a submenu / section
This will be used to avoid some nasty signal propagation when wanting to
rework how sections / submenus work.

https://bugzilla.gnome.org/show_bug.cgi?id=702539
2013-07-15 12:01:07 -04:00
Florian Müllner
78b1ba56ce calendar: Make the events-list a fixed width
Commit 929636ebd0 removed the fixed width of the calendar, while
commit cb45a38838 only added it back at max-width (resulting in
width changes of the calendar while browsing days).

https://bugzilla.gnome.org/show_bug.cgi?id=704200
2013-07-14 17:32:46 +02:00
Jiro Matsuzawa
5385205b8e l10n: Update Japanese translation 2013-07-14 23:57:58 +09:00
Dušan Kazik
5c8bbb511e Updated slovak translation 2013-07-14 14:37:21 +02:00
Lionel Landwerlin
fde01f0b71 st-theme-node: invalidate cached size when initializing paint state
https://bugzilla.gnome.org/show_bug.cgi?id=703997
2013-07-13 08:31:18 +01:00
Lionel Landwerlin
1c04ae3216 st-theme-node: fix obvious size comparison error
https://bugzilla.gnome.org/show_bug.cgi?id=703997
2013-07-13 08:31:14 +01:00
Ray Strode
35b4907e52 loginDialog: force user list and prompt to be the same width 2013-07-12 14:38:40 -04:00
Ray Strode
2431b8e021 loginDialog: make prompt entry wider
This makes it match mock ups better and looks more visually
pleasing.

https://bugzilla.gnome.org/show_bug.cgi?id=702308
2013-07-12 11:53:09 -04:00
Ray Strode
bd5c04b923 loginDialog: drop padding between buttons and entry
Now that we preallocate space for the prompt message there is
a lot of loose space between the entry and the buttons.

This commit helps tighten things up by getting rid
of the large top padding set above the login buttons.

https://bugzilla.gnome.org/show_bug.cgi?id=702308
2013-07-12 11:52:52 -04:00
Ray Strode
6e00b6e214 loginDialog: pre-allocate prompt message height
Right now things jump around if a message comes in.
This commit makes sure there's room for a message to start.

https://bugzilla.gnome.org/show_bug.cgi?id=702308
2013-07-12 11:52:39 -04:00
Emilio Pozuelo Monfort
c9b079cbb5 StWidget: use a handler id to disconnect the callback
g_signal_handlers_disconnect_by_func() is much more expensive
than g_signal_handler_disconnect(), so use the latter.

https://bugzilla.gnome.org/show_bug.cgi?id=704077
2013-07-12 13:38:47 +02:00
Victor Ibragimov
9163372786 Tajik translation updated 2013-07-12 16:06:48 +05:00
Florian Müllner
dabcd29fb6 panelMenu: Close menu when hiding the corresponding button
A PanelMenuButton added to the top bar might not be visible at all
times. If it is hidden while the corresponding menu is open, we
currently don't do anything at all, e.g. the menu remains open
pointing to an arbitrary location in the top bar.
Instead, close the menu automatically in that case.

https://bugzilla.gnome.org/show_bug.cgi?id=703540
2013-07-11 17:14:02 +02:00
eternalhui
d36e435801 update Simplified Chinese (zh_CN) translation 2013-07-11 18:11:52 +08:00
Lionel Landwerlin
a18fb27d0f st-theme-node: let paint states take weak ref on theme nodes
When the St theme is changed, the StThemeContext unrefs all the theme
nodes cached in it's internal hash table, then emits a signal to
notify all theme nodes that the current theme has changed.

The problem is that the first StWidget to catch a theme changed signal
will trigger a "style-changed" signal catched by its children first.
So the theme changed signal can't be processed properly to cleanup
StThemeNodePaintState before recomputing the theme.

This patch adds a weak ref to the StThemeNode in the
StThemeNodePaintState to ensure paint states are properly cleaned up
when the associated StThemeNode is freed.

https://bugzilla.gnome.org/show_bug.cgi?id=703859
2013-07-10 20:27:38 +01:00
Florian Müllner
2dbe511519 Bump version to 3.9.4
Update NEWS.
2013-07-10 19:50:29 +02:00
Florian Müllner
e031a5d28b st-theme-node: Update corner textures on allocation size changes
Commit 318283fc70 optimized box-shadow rendering by not recreating
shadow materials on every allocation change. Other handles cannot
be reused and are updated regularly, however the patch missed the
cached corner materials - while those can be reused, we still need
to ensure that the currently used paint state references them.

https://bugzilla.gnome.org/show_bug.cgi?id=703909
2013-07-10 17:35:11 +02:00
Florian Müllner
f9b32474b0 st-theme-node: Don't update resources on each paint
Up to commit 318283fc70, resources were only updated when
the allocated size had changed. There is no good reason to change
this for theme nodes without box shadows.

https://bugzilla.gnome.org/show_bug.cgi?id=703909
2013-07-10 17:35:11 +02:00
Florian Müllner
53d268a7ef st: Remove support for fixed positioning in BoxLayout
It is the job of layout containers to arrange their children; having
a hidden feature that *also* allows children to be positioned freely
outside the parent's allocation is just odd.
With the last user of the feature gone, kill it.

https://bugzilla.gnome.org/show_bug.cgi?id=703808
2013-07-09 23:19:20 +02:00
Florian Müllner
70da558802 overview: Add coverPane to stack instead of BoxLayout
The event catcher that covers the entire primary monitor during
transitions is currently inside a BoxLayout, relying in its
odd support for fixed position actors.
We already have a proper stack widget in place, move it there.

https://bugzilla.gnome.org/show_bug.cgi?id=703808
2013-07-09 23:19:20 +02:00
Florian Müllner
11215374ff lookingGlass: Use uiGroup as parent instead of panelBox
Currently lookingGlass relies on some odd BoxLayout behavior, which
allows children to use fixed positioning without affecting the parent's
size request. As this behavior is scheduled for removal, add the
looking glass dialog directly to Main.uiGroup.

https://bugzilla.gnome.org/show_bug.cgi?id=703808
2013-07-09 23:19:20 +02:00
Florian Müllner
cb45a38838 calendar: Fix line-wrapping of calendar events
Commit 929636ebd0 broke line-wrapping of longish calendar events,
add back the required CSS width.

https://bugzilla.gnome.org/show_bug.cgi?id=703893
2013-07-09 23:19:19 +02:00
Florian Müllner
bb4d430ebf style: Fix extension list style in looking glass
No idea how this got unnoticed since forever, but code and stylesheet
didn't quite agree on the same name ...

https://bugzilla.gnome.org/show_bug.cgi?id=703807
2013-07-09 22:06:13 +02:00
Florian Müllner
c17f84ca23 style: Fix focused app view controls
Moving from fixed width to horizontal padding for the app view control
buttons broke the focus style, in that buttons may change size on
keyboard focus changes. Fix this by using the correct horizontal padding
when focused.

https://bugzilla.gnome.org/show_bug.cgi?id=703807
2013-07-09 22:06:13 +02:00
Florian Müllner
0ae1f9ffc7 modalDialog: Minor coding style fix
https://bugzilla.gnome.org/show_bug.cgi?id=703807
2013-07-09 22:06:13 +02:00
Ray Strode
d15bcd9845 loginDialog: don't call nonexistent setInitialKeyFocus function
commit ea02380c15 changed the login
dialog to not use ModalDialog anymore.  There's still one lingering
setInitialKeyFocus method call in the source, which will cause an
exception to be thrown when users have their user list disabled.

This commit fixes that.

https://bugzilla.gnome.org/show_bug.cgi?id=703874
2013-07-09 12:52:18 -04:00
Lionel Landwerlin
f79a11d993 st-theme-node: init cached state properly 2013-07-09 11:25:28 +01:00
Lionel Landwerlin
9391d9d11b st-theme-node: reuse box-shadow materials between paint states when possible 2013-07-09 11:25:24 +01:00
Lionel Landwerlin
aee90a3116 st-theme-node: refactor calls to render css box 2013-07-09 11:24:26 +01:00
Lionel Landwerlin
ffac5279a7 tests: add animated box-shadow test to demo optimized painting 2013-07-09 11:24:26 +01:00
Lionel Landwerlin
318283fc70 st: optimize box-shadow rendering
Currently the box-shadow is rendering is done like this :

The first time we want to render a node that requires a box-shadow, St
creates an cogl offscreen surface of the size of the allocation and
renders the box into this offscreen buffer using modulation on the
alpha channel, this buffer is then blurred according to the CSS
parameters.

The problem with this method is that every time an StWidget is
resized, its box-shadow offscreen buffer has to be resized and
therefore rendered and blurred.

This patches propose an optimization for this use case by rendering
the box-shadow only once but at a size that is independent of the
StWidget's size. Then every time we need to paint this box-shadow, we
just render this offscreen buffer using a 9-slices.

This method only works when the allocation of the widget is bigger
than the minimum shadow size on which we can apply a 9-slices, that is
given my the radius of the corners. If the allocation is smaller than
this minimum size, we then fallback to the fully render/blur the
shadow (like before this patch).

https://bugzilla.gnome.org/show_bug.cgi?id=689858
2013-07-09 11:24:26 +01:00
Jasper St. Pierre
3582ba0c77 layout: Don't use the input mode to block events to windows
Instead, use the standard Clutter scene graph and our Chrome system.

This also removes our last use of the input mode, so remove that as
well.

https://bugzilla.gnome.org/show_bug.cgi?id=700735
2013-07-08 17:05:17 -04:00
Jasper St. Pierre
985d0c786c global: Automatically unshape the stage X window when we take a modal
This prevents the "client" from having to do it, and removes one part
of the FULLSCREEN input mode.

https://bugzilla.gnome.org/show_bug.cgi?id=700735
2013-07-08 17:05:17 -04:00
Jasper St. Pierre
9c8c282e08 global: Clean up the code that actually sets the shape on the stage
Instead of having "dummy" setters that do work, split out the parts
that do work into their own function.

https://bugzilla.gnome.org/show_bug.cgi?id=700735
2013-07-08 17:05:16 -04:00
Jasper St. Pierre
93dc7a51c0 Rework window / actor focus handling
The duality of the Clutter's key focus and mutter's window focus has long been
a problem for us in lots of case, and caused us to create large and complicated
hacks to get around the issue, including GrabHelper's focus grab model.

Instead of doing this, tie basic focus management into the core of gnome-shell,
instead of requiring complex "application-level" management to get it done
right.

Do this by making sure that only one of an actor or window can be focused at
the same time, and apply the appropriate logic to drop one or the other,
reactively.

Modals are considered a special case, as we grab all keyboard events, but at
the X level, the client window still has focus. Make sure to not do any input
synchronization when we have a modal.

At the same time, remove the FOCUSED input mode, as it's no longer necessary.

https://bugzilla.gnome.org/show_bug.cgi?id=700735
2013-07-08 17:05:16 -04:00
Jasper St. Pierre
393577ee78 grabHelper: Remove explicitly having to select modal
https://bugzilla.gnome.org/show_bug.cgi?id=700735
2013-07-08 16:51:51 -04:00
Jasper St. Pierre
eef593a34e messageTray: Don't use focus grabs
We can easily implement much of the same behavior ourselves by
keeping track of Clutter's focus events. Reintroduce heavily
modified FocusGrabber to do the work for us.

This will temporarily break when the user selects a window until
we can make gnome-shell automatically set the stage focus.

This also removes our only use of focus grabs, so remove those
as well.

https://bugzilla.gnome.org/show_bug.cgi?id=700735
2013-07-08 16:51:50 -04:00
Jasper St. Pierre
3790e924e9 grabHelper: Rewrite documentation for GrabHelper.grab()
The previous docs were badly maintained. This does not mention
grabFocus grabs, as they'll be removed shortly.

https://bugzilla.gnome.org/show_bug.cgi?id=700735
2013-07-08 16:17:01 -04:00
Trần Ngọc Quân
2f165aade8 Updated Vietnamese translation 2013-07-06 18:29:12 +07:00
Nguyễn Thái Ngọc Duy
2c502aec45 po/vi: import from Damned Lies 2013-07-06 18:24:32 +07:00
Benjamin Steinwender
6bbf246752 Updated German translation 2013-07-05 17:24:23 +02:00
Andika Triwidada
0b3e8e29cf Updated Indonesian translation 2013-07-05 10:23:35 +07:00
Giovanni Campagna
d509ab7779 ScreenShield: when the user goes idle, check for active before pushing a modal
We can't assume "isActive implies isModal", so there is a risk
of pushing a modal that nothing else will ever pop, because we
take the early return and don't activate the user active watch.

https://bugzilla.gnome.org/show_bug.cgi?id=700901
2013-07-04 15:16:27 +02:00
Kjartan Maraas
502a9aefdc Updated Norwegian bokmål translation 2013-07-04 11:09:57 +02:00
Jasper St. Pierre
ccba18aa8f network: Fix a recursion issue when updating VPN
_updateIcon should not attempt to sync any active connections, as the
icon-changed signal can be emitted in response to something done during
_syncActiveConnection. In the case of VPN, removeActiveConnection would
cause an icon-changed signal to be emitted immediately, but the state
would not be updated, causing us to call removeActiveConnection over and
over.

Explicitly sync all active connections when we know it needs to be done,
and simply make _updateIcon synchronize with the current device's icon.

https://bugzilla.gnome.org/show_bug.cgi?id=703565
2013-07-03 13:55:08 -04:00
Lionel Landwerlin
586ebcd5be background: fix asynchronous management of background loading operations
This fixes a blue background being drawn when switching the monitors
configuration using hardware keys
(clone/multimonitor/external/internal).

The problem is that the shell gather all background loading requests
under the same meta_background_load_file_async call using one
GCancellable (the first one to come). So when the shell receives a
batch of 12 or so XRandr events, it creates 12 new background managers
which end up trying to load 12 times the same background picture. All
of these requests are batched into the same
meta_background_load_file_async using the first GCancellable received
on the first request. Unfortunately, when the first request is
cancelled by the following event indicating a new monitor setup, all
of the background picture requests are dropped on the floor, and
nothing gets loaded (hence the blue screen background).

https://bugzilla.gnome.org/show_bug.cgi?id=703001
2013-07-03 17:03:02 +01:00
46 changed files with 3488 additions and 2763 deletions

29
NEWS
View File

@@ -1,3 +1,32 @@
3.9.4
=====
* Fix chat entries not being focused when expanded [Jasper; #698778]
* Fix alignment of "Not Listed?" label [Mathieu; #702307]
* Fix alignment of time stamps in chat notifications [Carlos; #687809]
* Round the ends of slider trough [Jasper; #702825]
* Add support for "box-shadow: none" [Cosimo; #702782]
* Keep chrome below popup windows [Florian; #702338]
* Move the session list to a popup menu [Ray; #702818]
* Fix autorun notifications for "non-native" volumes [Matthias; #703418]
* dnd: Speed up by not picking on each motion event [Jasper; #703443]
* Fix management of asynchronous background loading [Lionel; #703001]
* Rework focus handling [Jasper; #700735]
* Optimize box-shadow rendering [Lionel; #689858]
* Remove support for fixed positioning in BoxLayouts [Florian; #703808]
* Misc bug fixes and cleanups [Adel, Jasper, Florian, Ray, Lionel, Emilio;
#702849, #610279, #703132, #703105, #703160, #703126, #703304, #703403,
#698593, #703442, #703565, #700901, #703874, #703807, #703893, #703909]
Contributors:
Mathieu Bridon, Giovanni Campagna, Cosimo Cecchi, Matthias Clasen,
Fran Diéguez, Adel Gadllah, Lionel Landwerlin, Florian Müllner,
Emilio Pozuelo Monfort, Carlos Soriano, Jasper St. Pierre, Ray Strode
Translations:
Baurzhan Muftakhidinov [kk], Marek Černocký [cs], Daniel Mustieles [es],
Fran Diéguez [gl], Kjartan Maraas [nb], Andika Triwidada [id],
Benjamin Steinwender [de], Nguyễn Thái Ngọc Duy [vi], Trần Ngọc Quân [vi]
3.9.3
=====
* Don't push window thumbs when workspace switcher is hidden [Jasper; #701167]

View File

@@ -1,5 +1,5 @@
AC_PREREQ(2.63)
AC_INIT([gnome-shell],[3.9.3],[https://bugzilla.gnome.org/enter_bug.cgi?product=gnome-shell],[gnome-shell])
AC_INIT([gnome-shell],[3.9.4],[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.9.3
MUTTER_MIN_VERSION=3.9.4
GTK_MIN_VERSION=3.7.9
GIO_MIN_VERSION=2.37.0
LIBECAL_MIN_VERSION=3.5.3

View File

@@ -327,10 +327,6 @@ StScrollBar StButton#vhandle:active {
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;
@@ -474,10 +470,6 @@ StScrollBar StButton#vhandle:active {
height: 1.86em;
}
#panel.lock-screen {
background-color: rgba(0,0,0,0.3);
}
#panel.unlock-screen,
#panel.login-screen {
background-color: transparent;
@@ -911,6 +903,11 @@ StScrollBar StButton#vhandle:active {
padding: 4px 32px;
}
.app-view-control:focus {
padding: 3px 31px;
}
.search-display > StBoxLayout,
.all-apps > StBoxLayout,
.frequent-apps > StBoxLayout {
@@ -1132,7 +1129,7 @@ StScrollBar StButton#vhandle:active {
padding: 4px;
}
.lg-extension-list {
.lg-extensions-list {
padding: 4px;
spacing: 6px;
}
@@ -1297,7 +1294,7 @@ StScrollBar StButton#vhandle:active {
}
.events-table {
min-width: 320px;
width: 320px;
spacing-columns: 6pt;
padding: 0 1.4em;
}
@@ -2238,6 +2235,10 @@ StScrollBar StButton#vhandle:active {
min-width: 350px;
}
.login-dialog-button-box {
spacing: 5px;
}
.login-dialog-prompt-login-hint-message {
font-size: 10.5pt;
}
@@ -2319,6 +2320,9 @@ StScrollBar StButton#vhandle:active {
font-weight: bold;
color: #666666;
padding-top: 1em;
}
.login-dialog-user-selection-box .login-dialog-not-listed-label {
padding-left: 2px;
}
@@ -2347,7 +2351,7 @@ StScrollBar StButton#vhandle:active {
}
.login-dialog-prompt-entry {
width: 15em;
width: 20em;
}
.login-dialog-session-list-button StIcon {
@@ -2427,6 +2431,11 @@ StScrollBar StButton#vhandle:active {
/* Screen shield */
#panel.lock-screen,
#screenShieldNotifications {
background-color: rgba(0,0,0,0.3);
}
.screen-shield-background {
background: black;
box-shadow: 0px 4px 8px rgba(0,0,0,0.9);
@@ -2472,11 +2481,8 @@ StScrollBar StButton#vhandle:active {
#screenShieldNotifications {
border-radius: 8px;
background-color: rgba(0.0, 0.0, 0.0, 0.9);
border: 2px solid #868686;
max-height: 500px;
padding: 18px 0;
box-shadow: .5em .5em 20px rgba(0, 0, 0, 0.5);
}
.screen-shield-notifications-box {

View File

@@ -32,7 +32,6 @@ const Shell = imports.gi.Shell;
const Signals = imports.signals;
const St = imports.gi.St;
const Animation = imports.ui.animation;
const Batch = imports.gdm.batch;
const BoxPointer = imports.ui.boxpointer;
const CtrlAltTab = imports.ui.ctrlAltTab;
@@ -46,20 +45,11 @@ const UserWidget = imports.ui.userWidget;
const _FADE_ANIMATION_TIME = 0.25;
const _SCROLL_ANIMATION_TIME = 0.5;
const _DEFAULT_BUTTON_WELL_ICON_SIZE = 24;
const _DEFAULT_BUTTON_WELL_ANIMATION_DELAY = 1.0;
const _DEFAULT_BUTTON_WELL_ANIMATION_TIME = 0.3;
const _TIMED_LOGIN_IDLE_THRESHOLD = 5.0;
const _LOGO_ICON_HEIGHT = 48;
let _loginDialog = null;
const DefaultButtonWellMode = {
NONE: 0,
SESSION_MENU_BUTTON: 1,
SPINNER: 2
};
const UserListItem = new Lang.Class({
Name: 'UserListItem',
@@ -466,61 +456,19 @@ const LoginDialog = new Lang.Class({
x_fill: true,
y_fill: true });
this._promptBox = new St.BoxLayout({ style_class: 'login-dialog-prompt-layout',
vertical: true });
this._promptBox.connect('button-press-event',
Lang.bind(this, function(actor, event) {
if (event.get_key_symbol() == Clutter.KEY_Escape) {
this._authPrompt = new GdmUtil.AuthPrompt({ visible: false });
this._authPrompt.connect('cancel',
Lang.bind(this, function() {
this.cancel();
}
}));
this._promptBox.add_constraint(new Clutter.AlignConstraint({ source: this.actor,
align_axis: Clutter.AlignAxis.BOTH,
factor: 0.5 }));
this.actor.add_child(this._promptBox);
this._promptUser = new St.Bin({ x_fill: true,
x_align: St.Align.START });
this._promptBox.add(this._promptUser,
{ x_align: St.Align.START,
x_fill: true,
y_fill: true,
expand: true });
this._promptLabel = new St.Label({ style_class: 'login-dialog-prompt-label' });
this._authPrompt.actor.add_constraint(new Clutter.AlignConstraint({ source: this.actor,
align_axis: Clutter.AlignAxis.BOTH,
factor: 0.5 }));
this._promptBox.add(this._promptLabel,
{ expand: true,
x_fill: true,
y_fill: true,
x_align: St.Align.START });
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,
y_fill: false,
x_align: St.Align.START });
this._promptMessage = new St.Label({ visible: false });
this._promptBox.add(this._promptMessage, { x_fill: true });
this._promptLoginHint = new St.Label({ style_class: 'login-dialog-prompt-login-hint-message' });
this._promptLoginHint.hide();
this._promptBox.add(this._promptLoginHint);
this._buttonBox = new St.BoxLayout({ style_class: 'modal-dialog-button-box',
vertical: false });
this._promptBox.add(this._buttonBox,
{ expand: true,
x_align: St.Align.MIDDLE,
y_align: St.Align.END });
this._cancelButton = null;
this._signInButton = null;
this._promptBox.hide();
this.actor.add_child(this._authPrompt.actor);
this._userList.actor.add_constraint(new Clutter.BindConstraint({ source: this._authPrompt.actor,
coordinate: Clutter.BindCoordinate.WIDTH }));
// translators: this message is shown below the user list on the
// login screen. It can be activated to reveal an entry for
@@ -571,8 +519,6 @@ const LoginDialog = new Lang.Class({
this._onUserListActivated(item);
}));
this._defaultButtonWell = new St.Widget();
this._defaultButtonWellMode = DefaultButtonWellMode.NONE;
this._sessionMenuButton = new SessionMenuButton();
this._sessionMenuButton.connect('session-activated',
@@ -581,26 +527,13 @@ const LoginDialog = new Lang.Class({
}));
this._sessionMenuButton.actor.opacity = 0;
this._sessionMenuButton.actor.show();
this._defaultButtonWell.add_child(this._sessionMenuButton.actor);
this._authPrompt.addActorToDefaultButtonWell(this._sessionMenuButton.actor);
let spinnerIcon = global.datadir + '/theme/process-working.svg';
this._workSpinner = new Animation.AnimatedIcon(spinnerIcon, _DEFAULT_BUTTON_WELL_ICON_SIZE);
this._workSpinner.actor.opacity = 0;
this._workSpinner.actor.show();
this._defaultButtonWell.add_child(this._workSpinner.actor);
this._sessionMenuButton.actor.add_constraint(new Clutter.AlignConstraint({ source: this._workSpinner.actor,
align_axis: Clutter.AlignAxis.BOTH,
factor: 0.5 }));
},
_updateDisableUserList: function() {
let disableUserList = this._settings.get_boolean(GdmUtil.DISABLE_USER_LIST_KEY);
// If this is the first time around, set initial focus
if (this._disableUserList == undefined && disableUserList)
this.setInitialKeyFocus(this._promptEntry);
if (disableUserList != this._disableUserList) {
this._disableUserList = disableUserList;
@@ -643,7 +576,8 @@ const LoginDialog = new Lang.Class({
this._userVerifier.clear();
this._updateSensitivity(true);
this._promptMessage.hide();
this._authPrompt.reset();
this._user = null;
this._verifyingUser = false;
@@ -653,73 +587,11 @@ const LoginDialog = new Lang.Class({
this._showUserList();
},
_getActorForDefaultButtonWellMode: function(mode) {
let actor;
if (mode == DefaultButtonWellMode.NONE)
actor = null;
else if (mode == DefaultButtonWellMode.SPINNER)
actor = this._workSpinner.actor;
else if (mode == DefaultButtonWellMode.SESSION_MENU_BUTTON)
actor = this._sessionMenuButton.actor;
return actor;
},
_setDefaultButtonWellMode: function(mode, immediately) {
if (this._defaultButtonWellMode == DefaultButtonWellMode.NONE &&
mode == DefaultButtonWellMode.NONE)
return;
let oldActor = this._getActorForDefaultButtonWellMode(this._defaultButtonWellMode);
if (oldActor)
Tweener.removeTweens(oldActor);
let actor = this._getActorForDefaultButtonWellMode(mode);
if (this._defaultButtonWellMode != mode && oldActor) {
if (immediately)
oldActor.opacity = 0;
else
Tweener.addTween(oldActor,
{ opacity: 0,
time: _DEFAULT_BUTTON_WELL_ANIMATION_TIME,
delay: _DEFAULT_BUTTON_WELL_ANIMATION_DELAY,
transition: 'linear',
onCompleteScope: this,
onComplete: function() {
if (mode == DefaultButtonWellMode.SPINNER) {
if (this._workSpinner)
this._workSpinner.stop();
}
}
});
}
if (actor) {
if (mode == DefaultButtonWellMode.SPINNER)
this._workSpinner.play();
if (immediately)
actor.opacity = 255;
else
Tweener.addTween(actor,
{ opacity: 255,
time: _DEFAULT_BUTTON_WELL_ANIMATION_TIME,
delay: _DEFAULT_BUTTON_WELL_ANIMATION_DELAY,
transition: 'linear' });
}
this._defaultButtonWellMode = mode;
},
_verificationFailed: function() {
this._promptEntry.text = '';
this._authPrompt.clear();
this._updateSensitivity(true);
this._setDefaultButtonWellMode(DefaultButtonWellMode.NONE, true);
this._authPrompt.setActorInDefaultButtonWell(null, true);
},
_onDefaultSessionChanged: function(client, sessionId) {
@@ -727,24 +599,15 @@ const LoginDialog = new Lang.Class({
},
_showMessage: function(userVerifier, message, styleClass) {
if (message) {
this._promptMessage.text = message;
this._promptMessage.styleClass = styleClass;
this._promptMessage.show();
} else {
this._promptMessage.hide();
}
this._authPrompt.setMessage(message, styleClass);
},
_showLoginHint: function(verifier, message) {
this._promptLoginHint.set_text(message)
this._promptLoginHint.show();
this._promptLoginHint.opacity = 255;
this._authPrompt.setHint(message);
},
_hideLoginHint: function() {
this._promptLoginHint.hide();
this._promptLoginHint.set_text('');
this._authPrompt.setHint(null);
},
cancel: function() {
@@ -768,27 +631,16 @@ const LoginDialog = new Lang.Class({
},
_showPrompt: function(forSecret) {
this._promptLabel.show();
this._promptEntry.show();
this._promptLoginHint.opacity = 0;
this._promptLoginHint.show();
this._promptBox.opacity = 0;
this._promptBox.show();
Tweener.addTween(this._promptBox,
this._authPrompt.actor.opacity = 0;
this._authPrompt.actor.show();
Tweener.addTween(this._authPrompt.actor,
{ opacity: 255,
time: _FADE_ANIMATION_TIME,
transition: 'easeOutQuad' });
if (this._shouldShowSessionMenuButton())
this._setDefaultButtonWellMode(DefaultButtonWellMode.SESSION_MENU_BUTTON, true);
else
this._setDefaultButtonWellMode(DefaultButtonWellMode.NONE, true);
this._promptEntry.grab_key_focus();
let hold = new Batch.Hold();
let tasks = [function() {
this._prepareDialog(forSecret, hold);
this._preparePrompt(forSecret, hold);
},
hold];
@@ -798,122 +650,54 @@ const LoginDialog = new Lang.Class({
return batch.run();
},
_prepareDialog: function(forSecret, hold) {
this._buttonBox.visible = true;
this._buttonBox.remove_all_children();
_preparePrompt: function(forSecret, hold) {
let cancelLabel;
if (!this._disableUserList || this._verifyingUser) {
this._cancelButton = new St.Button({ style_class: 'modal-dialog-button',
button_mask: St.ButtonMask.ONE | St.ButtonMask.THREE,
reactive: true,
can_focus: true,
label: _("Cancel") });
this._cancelButton.connect('clicked',
Lang.bind(this, function() {
this.cancel();
}));
this._buttonBox.add(this._cancelButton,
{ expand: false,
x_fill: false,
y_fill: false,
x_align: St.Align.START,
y_align: St.Align.END });
cancelLabel = _("Cancel");
} else {
cancelLabel = null;
}
this._buttonBox.add(this._defaultButtonWell,
{ expand: true,
x_fill: false,
y_fill: false,
x_align: St.Align.END,
y_align: St.Align.MIDDLE });
this._signInButton = new St.Button({ style_class: 'modal-dialog-button',
button_mask: St.ButtonMask.ONE | St.ButtonMask.THREE,
reactive: true,
can_focus: true,
label: forSecret ? C_("button", "Sign In") : _("Next") });
this._signInButton.connect('clicked',
Lang.bind(this, function() {
hold.release();
}));
this._signInButton.add_style_pseudo_class('default');
this._buttonBox.add(this._signInButton,
{ expand: false,
x_fill: false,
y_fill: false,
x_align: St.Align.END,
y_align: St.Align.END });
let nextLabel;
if (forSecret) {
nextLabel = C_("button", "Sign In");
} else {
nextLabel = _("Next");
}
this._updateSignInButtonSensitivity(this._promptEntry.text.length > 0);
let signalId = this._authPrompt.connect('next', Lang.bind(this, function() {
this._authPrompt.disconnect(signalId);
hold.release();
}));
this._promptEntryTextChangedId =
this._promptEntry.clutter_text.connect('text-changed',
Lang.bind(this, function() {
this._updateSignInButtonSensitivity(this._promptEntry.text.length > 0);
}));
this._promptEntryActivateId =
this._promptEntry.clutter_text.connect('activate', function() {
hold.release();
});
this._authPrompt.resetButtons(cancelLabel, nextLabel);
},
_updateSensitivity: function(sensitive) {
this._promptEntry.reactive = sensitive;
this._promptEntry.clutter_text.editable = sensitive;
this._sessionMenuButton.updateSensitivity(sensitive);
this._updateSignInButtonSensitivity(sensitive);
},
_updateSignInButtonSensitivity: function(sensitive) {
if (this._signInButton) {
this._signInButton.reactive = sensitive;
this._signInButton.can_focus = sensitive;
}
},
_hidePrompt: function() {
if (this._promptEntryTextChangedId > 0) {
this._promptEntry.clutter_text.disconnect(this._promptEntryTextChangedId);
this._promptEntryTextChangedId = 0;
}
if (this._promptEntryActivateId > 0) {
this._promptEntry.clutter_text.disconnect(this._promptEntryActivateId);
this._promptEntryActivateId = 0;
}
this._setDefaultButtonWellMode(DefaultButtonWellMode.NONE, true);
this._promptBox.hide();
this._promptLoginHint.hide();
this._promptUser.set_child(null);
this._updateSensitivity(true);
this._promptEntry.set_text('');
this._sessionMenuButton.close();
this._promptLoginHint.hide();
this._buttonBox.remove_all_children();
this._signInButton = null;
this._cancelButton = null;
this._authPrompt.updateSensitivity(sensitive);
},
_askQuestion: function(verifier, serviceName, question, passwordChar) {
this._promptLabel.set_text(question);
this._authPrompt.setPasswordChar(passwordChar);
this._authPrompt.setQuestion(question);
this._updateSensitivity(true);
this._promptEntry.set_text('');
this._promptEntry.clutter_text.set_password_char(passwordChar);
if (this._shouldShowSessionMenuButton())
this._authPrompt.setActorInDefaultButtonWell(this._sessionMenuButton.actor, true);
else
this._authPrompt.setActorInDefaultButtonWell(null, true);
let tasks = [function() {
return this._showPrompt(!!passwordChar);
},
function() {
let text = this._promptEntry.get_text();
let text = this._authPrompt.getAnswer();
this._updateSensitivity(false);
this._setDefaultButtonWellMode(DefaultButtonWellMode.SPINNER, false);
this._authPrompt.startSpinning();
this._userVerifier.answerQuery(serviceName, text);
}];
@@ -935,9 +719,8 @@ const LoginDialog = new Lang.Class({
},
_askForUsernameAndLogIn: function() {
this._promptLabel.set_text(_("Username: "));
this._promptEntry.set_text('');
this._promptEntry.clutter_text.set_password_char('');
this._authPrompt.setPasswordChar('');
this._authPrompt.setQuestion(_("Username: "));
let realmManager = new Realmd.Manager();
let signalId = realmManager.connect('login-format-changed',
@@ -947,8 +730,8 @@ const LoginDialog = new Lang.Class({
let tasks = [this._showPrompt,
function() {
let userName = this._promptEntry.get_text();
this._promptEntry.reactive = false;
let userName = this._authPrompt.getAnswer();
this._authPrompt._entry.reactive = false;
return this._beginVerificationForUser(userName);
},
@@ -1132,7 +915,8 @@ const LoginDialog = new Lang.Class({
},
_showUserList: function() {
this._hidePrompt();
this._authPrompt.hide();
this._sessionMenuButton.close();
this._setUserListExpanded(true);
this._notListedButton.show();
this._userList.actor.grab_key_focus();
@@ -1147,8 +931,7 @@ const LoginDialog = new Lang.Class({
},
_beginVerificationForItem: function(item) {
let userWidget = new UserWidget.UserWidget(item.user);
this._promptUser.set_child(userWidget.actor);
this._authPrompt.setUser(item.user);
let tasks = [function() {
let userName = item.user.get_user_name();
@@ -1216,7 +999,7 @@ const LoginDialog = new Lang.Class({
},
addCharacter: function(unichar) {
this._promptEntry.clutter_text.insert_unichar(unichar);
this._authPrompt.addCharacter(unichar);
},
});
Signals.addSignalMethods(LoginDialog.prototype);

View File

@@ -6,12 +6,16 @@ const GLib = imports.gi.GLib;
const Lang = imports.lang;
const Mainloop = imports.mainloop;
const Signals = imports.signals;
const St = imports.gi.St;
const Animation = imports.ui.animation;
const Batch = imports.gdm.batch;
const Fprint = imports.gdm.fingerprint;
const Main = imports.ui.main;
const Params = imports.misc.params;
const ShellEntry = imports.ui.shellEntry;
const Tweener = imports.ui.tweener;
const UserWidget = imports.ui.userWidget;
const PASSWORD_SERVICE_NAME = 'gdm-password';
const FINGERPRINT_SERVICE_NAME = 'gdm-fingerprint';
@@ -30,6 +34,10 @@ const DISABLE_USER_LIST_KEY = 'disable-user-list';
// Give user 16ms to read each character of a PAM message
const USER_READ_TIME = 16
const DEFAULT_BUTTON_WELL_ICON_SIZE = 24;
const DEFAULT_BUTTON_WELL_ANIMATION_DELAY = 1.0;
const DEFAULT_BUTTON_WELL_ANIMATION_TIME = 0.3;
function fadeInActor(actor) {
if (actor.opacity == 255 && actor.visible)
return null;
@@ -459,3 +467,337 @@ const ShellUserVerifier = new Lang.Class({
},
});
Signals.addSignalMethods(ShellUserVerifier.prototype);
const AuthPrompt = new Lang.Class({
Name: 'AuthPrompt',
_init: function(params) {
params = Params.parse(params,
{ style_class: 'login-dialog-prompt-layout',
vertical: true }, true);
this.actor = new St.BoxLayout(params);
this.actor.connect('button-press-event',
Lang.bind(this, function(actor, event) {
if (event.get_key_symbol() == Clutter.KEY_Escape) {
this.emit('cancel');
}
}));
this._userWell = new St.Bin({ x_fill: true,
x_align: St.Align.START });
this.actor.add(this._userWell,
{ x_align: St.Align.START,
x_fill: true,
y_fill: true,
expand: true });
this._label = new St.Label({ style_class: 'login-dialog-prompt-label' });
this.actor.add(this._label,
{ expand: true,
x_fill: true,
y_fill: true,
x_align: St.Align.START });
this._entry = new St.Entry({ style_class: 'login-dialog-prompt-entry',
can_focus: true });
ShellEntry.addContextMenu(this._entry, { isPassword: true });
this._entryTextChangedId = 0;
this._entryActivateId = 0;
this.actor.add(this._entry,
{ expand: true,
x_fill: true,
y_fill: false,
x_align: St.Align.START });
this._entry.grab_key_focus();
this._message = new St.Label({ opacity: 0 });
this.actor.add(this._message, { x_fill: true });
this._loginHint = new St.Label({ style_class: 'login-dialog-prompt-login-hint-message' });
this.actor.add(this._loginHint);
this._buttonBox = new St.BoxLayout({ style_class: 'login-dialog-button-box',
vertical: false });
this.actor.add(this._buttonBox,
{ expand: true,
x_align: St.Align.MIDDLE,
y_align: St.Align.END });
this._cancelButton = null;
this._nextButton = null;
this._defaultButtonWell = new St.Widget();
this._defaultButtonWellActor = null;
let spinnerIcon = global.datadir + '/theme/process-working.svg';
this._spinner = new Animation.AnimatedIcon(spinnerIcon, DEFAULT_BUTTON_WELL_ICON_SIZE);
this._spinner.actor.opacity = 0;
this._spinner.actor.show();
this._defaultButtonWell.add_child(this._spinner.actor);
},
addActorToDefaultButtonWell: function(actor) {
this._defaultButtonWell.add_child(actor);
actor.add_constraint(new Clutter.AlignConstraint({ source: this._spinner.actor,
align_axis: Clutter.AlignAxis.BOTH,
factor: 0.5 }));
},
setActorInDefaultButtonWell: function(actor, immediately) {
if (!this._defaultButtonWellActor &&
!actor)
return;
let oldActor = this._defaultButtonWellActor;
if (oldActor)
Tweener.removeTweens(oldActor);
let isWorkSpinner;
if (actor == this._spinner.actor)
isWorkSpinner = true;
else
isWorkSpinner = false;
if (this._defaultButtonWellActor != actor && oldActor) {
if (immediately)
oldActor.opacity = 0;
else
Tweener.addTween(oldActor,
{ opacity: 0,
time: DEFAULT_BUTTON_WELL_ANIMATION_TIME,
delay: DEFAULT_BUTTON_WELL_ANIMATION_DELAY,
transition: 'linear',
onCompleteScope: this,
onComplete: function() {
if (isWorkSpinner) {
if (this._spinner)
this._spinner.stop();
}
}
});
}
if (actor) {
if (isWorkSpinner)
this._spinner.play();
if (immediately)
actor.opacity = 255;
else
Tweener.addTween(actor,
{ opacity: 255,
time: DEFAULT_BUTTON_WELL_ANIMATION_TIME,
delay: DEFAULT_BUTTON_WELL_ANIMATION_DELAY,
transition: 'linear' });
}
this._defaultButtonWellActor = actor;
},
startSpinning: function() {
this.setActorInDefaultButtonWell(this._spinner.actor, true);
},
stopSpinning: function() {
this.setActorInDefaultButtonWell(null, true);
},
clear: function() {
this._entry.text = '';
},
setPasswordChar: function(passwordChar) {
this._entry.clutter_text.set_password_char(passwordChar);
this._entry.menu.isPassword = passwordChar != '';
},
setQuestion: function(question) {
if (!this._initialAnswer) {
this.clear();
} else if (this._initialAnswer['activate-id']) {
this._entry.clutter_text.disconnect(this._initialAnswer['activate-id']);
delete this._initialAnswer['activate-id'];
}
this._label.set_text(question);
this._label.show();
this._entry.show();
this._loginHint.opacity = 0;
this._loginHint.show();
this._entry.grab_key_focus();
},
getAnswer: function() {
let text;
if (this._initialAnswer && this._initialAnswer['text']) {
text = this._initialAnswer['text'];
this._initialAnswer = null;
} else {
text = this._entry.get_text();
}
return text;
},
setMessage: function(message, styleClass) {
if (message) {
this._message.text = message;
this._message.styleClass = styleClass;
this._message.opacity = 255;
} else {
this._message.opacity = 0;
}
},
resetButtons: function(cancelLabel, nextLabel) {
if (this._initialAnswer && this._initialAnswer['text']) {
this.emit('next');
return;
}
this._buttonBox.visible = true;
this._buttonBox.remove_all_children();
if (cancelLabel) {
this._cancelButton = new St.Button({ style_class: 'modal-dialog-button',
button_mask: St.ButtonMask.ONE | St.ButtonMask.THREE,
reactive: true,
can_focus: true,
label: cancelLabel });
this._cancelButton.connect('clicked',
Lang.bind(this, function() {
this.emit('cancel');
}));
this._buttonBox.add(this._cancelButton,
{ expand: false,
x_fill: false,
y_fill: false,
x_align: St.Align.START,
y_align: St.Align.END });
}
this._buttonBox.add(this._defaultButtonWell,
{ expand: true,
x_fill: false,
y_fill: false,
x_align: St.Align.END,
y_align: St.Align.MIDDLE });
this._nextButton = new St.Button({ style_class: 'modal-dialog-button',
button_mask: St.ButtonMask.ONE | St.ButtonMask.THREE,
reactive: true,
can_focus: true,
label: nextLabel });
this._nextButton.connect('clicked',
Lang.bind(this, function() {
this.emit('next');
}));
this._nextButton.add_style_pseudo_class('default');
this._buttonBox.add(this._nextButton,
{ expand: false,
x_fill: false,
y_fill: false,
x_align: St.Align.END,
y_align: St.Align.END });
this._updateNextButtonSensitivity(this._entry.text.length > 0);
this._entryTextChangedId =
this._entry.clutter_text.connect('text-changed',
Lang.bind(this, function() {
this._updateNextButtonSensitivity(this._entry.text.length > 0);
}));
this._entryActivateId =
this._entry.clutter_text.connect('activate', Lang.bind(this, function() {
this.emit('next');
}));
},
_updateNextButtonSensitivity: function(sensitive) {
if (this._nextButton) {
this._nextButton.reactive = sensitive;
this._nextButton.can_focus = sensitive;
}
},
updateSensitivity: function(sensitive) {
this._updateNextButtonSensitivity(sensitive);
this._entry.reactive = sensitive;
this._entry.clutter_text.editable = sensitive;
},
hide: function() {
if (this._entryTextChangedId > 0) {
this._entry.clutter_text.disconnect(this._entryTextChangedId);
this._entryTextChangedId = 0;
}
if (this._entryActivateId > 0) {
this._entry.clutter_text.disconnect(this._entryActivateId);
this._entryActivateId = 0;
}
this.setActorInDefaultButtonWell(null, true);
this.actor.hide();
this._loginHint.opacity = 0;
this.setUser(null);
this.updateSensitivity(true);
this._entry.set_text('');
this._buttonBox.remove_all_children();
this._nextButton = null;
this._cancelButton = null;
},
setUser: function(user) {
if (user) {
let userWidget = new UserWidget.UserWidget(user);
this._userWell.set_child(userWidget.actor);
} else {
this._userWell.set_child(null);
}
},
setHint: function(message) {
if (message) {
this._loginHint.set_text(message)
this._loginHint.opacity = 255;
} else {
this._loginHint.opacity = 0;
this._loginHint.set_text('');
}
},
reset: function() {
this._message.opacity = 0;
this.setUser(null);
},
addCharacter: function(unichar) {
if (!this._entry.visible)
return;
if (!this._initialAnswer)
this._initialAnswer = {};
this._entry.grab_key_focus();
this._entry.clutter_text.insert_unichar(unichar);
if (!this._initialAnswer['activate-id'])
this._initialAnswer['activate-id'] =
this._entry.clutter_text.connect('activate', Lang.bind(this, function() {
this._entry.clutter_text.disconnect(this._initialAnswer['activate-id']);
delete this._initialAnswer['activate-id'];
this._initialAnswer['text'] = this._entry.get_text();
}));
}
});
Signals.addSignalMethods(AuthPrompt.prototype);

View File

@@ -142,23 +142,20 @@ const BackgroundCache = new Lang.Class({
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;
}
}
let fileLoad = { filename: params.filename,
style: params.style,
shouldCopy: false,
monitorIndex: params.monitorIndex,
effects: params.effects,
onFinished: params.onFinished,
cancellable: new Gio.Cancellable(), };
this._pendingFileLoads.push(fileLoad);
this._pendingFileLoads.push({ filename: params.filename,
style: params.style,
callers: [{ shouldCopy: false,
monitorIndex: params.monitorIndex,
effects: params.effects,
onFinished: params.onFinished }] });
if (params.cancellable) {
params.cancellable.connect(Lang.bind(this, function(c) {
fileLoad.cancellable.cancel();
}));
}
let content = new Meta.Background({ meta_screen: global.screen,
monitor: params.monitorIndex,
@@ -166,9 +163,19 @@ const BackgroundCache = new Lang.Class({
content.load_file_async(params.filename,
params.style,
params.cancellable,
fileLoad.cancellable,
Lang.bind(this,
function(object, result) {
if (fileLoad.cancellable.is_cancelled()) {
if (params.cancellable && params.cancellable.is_cancelled()) {
if (params.onFinished)
params.onFinished(null);
this._removePendingFileLoad(fileLoad);
return;
}
return;
}
try {
content.load_file_finish(result);
@@ -178,22 +185,25 @@ const BackgroundCache = new Lang.Class({
content = null;
}
let needsCopy = false;
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);
if (pendingLoad.cancellable.is_cancelled())
continue;
}
pendingLoad.callers[j].onFinished(content);
pendingLoad.cancellable.cancel();
if (pendingLoad.onFinished) {
if (content && needsCopy) {
content = object.copy(pendingLoad.monitorIndex,
pendingLoad.effects);
}
needsCopy = true;
pendingLoad.onFinished(content);
}
this._pendingFileLoads.splice(i, 1);
@@ -201,6 +211,15 @@ const BackgroundCache = new Lang.Class({
}));
},
_removePendingFileLoad: function(fileLoad) {
for (let i = 0; i < this._pendingFileLoads.length; i++) {
if (this._pendingFileLoads[i].cancellable == fileLoad.cancellable) {
this._pendingFileLoads.splice(i, 1);
break;
}
}
},
getImageContent: function(params) {
params = Params.parse(params, { monitorIndex: 0,
style: null,

View File

@@ -58,14 +58,10 @@ const CtrlAltTabManager = new Lang.Class({
},
focusGroup: function(item, timestamp) {
if (item.focusCallback) {
if (item.focusCallback)
item.focusCallback(timestamp);
} else {
if (global.stage_input_mode == Shell.StageInputMode.NORMAL)
global.set_stage_input_mode(Shell.StageInputMode.FOCUSED);
else
item.root.navigate_focus(null, Gtk.DirectionType.TAB_FORWARD, false);
}
},
// Sort the items into a consistent order; panel first, tray last,
@@ -136,8 +132,6 @@ const CtrlAltTabManager = new Lang.Class({
},
_focusWindows: function(timestamp) {
global.set_stage_input_mode(Shell.StageInputMode.NORMAL);
global.stage.key_focus = null;
global.screen.focus_default_window(timestamp);
}
});

View File

@@ -32,13 +32,9 @@ const GrabHelper = new Lang.Class({
this._actors = [];
this._capturedEventId = 0;
this._keyFocusNotifyId = 0;
this._focusWindowChangedId = 0;
this._ignoreRelease = false;
this._isUngrabbingCount = 0;
this._modalCount = 0;
this._grabFocusCount = 0;
},
// addActor:
@@ -118,38 +114,36 @@ const GrabHelper = new Lang.Class({
// grab:
// @params: A bunch of parameters, see below
//
// Grabs the mouse and keyboard, according to the GrabHelper's
// parameters. If @newFocus is not %null, then the keyboard focus
// is moved to the first #StWidget:can-focus widget inside it.
// The general effect of a "grab" is to ensure that the passed in actor
// and all actors inside the grab get exclusive control of the mouse and
// keyboard, with the grab automatically being dropped if the user tries
// to dismiss it. The actor is passed in through @params.actor.
//
// The grab will automatically be dropped if:
// - The user clicks outside the grabbed actors
// - The user types Escape
// - The keyboard focus is moved outside the grabbed actors
// - A window is focused
// grab() can be called multiple times, with the scope of the grab being
// changed to a different actor every time. A nested grab does not have
// to have its grabbed actor inside the parent grab actors.
//
// If @params.actor is not null, then it will be focused as the
// new actor. If you attempt to grab an already focused actor, the
// request to be focused will be ignored. The actor will not be
// added to the grab stack, so do not call a paired ungrab().
// Grabs can be automatically dropped if the user tries to dismiss it
// in one of two ways: the user clicking outside the currently grabbed
// actor, or the user typing the Escape key.
//
// If @params contains { modal: true }, then grab() will push a modal
// on the owner of the GrabHelper. As long as there is at least one
// { modal: true } actor on the grab stack, the grab will be kept.
// When the last { modal: true } actor is ungrabbed, then the modal
// will be dropped. A modal grab can fail if there is already a grab
// in effect from aother application; in this case the function returns
// false and nothing happens. Non-modal grabs can never fail.
// If the user clicks outside the grabbed actors, and the clicked on
// actor is part of a previous grab in the stack, grabs will be popped
// until that grab is active. However, the click event will not be
// replayed to the actor.
//
// If @params contains { grabFocus: true }, then if you call grab()
// while the shell is outside the overview, it will set the stage
// input mode to %Shell.StageInputMode.FOCUSED, and ungrab() will
// revert it back, and re-focus the previously-focused window (if
// another window hasn't been explicitly focused before then).
// If the user types the Escape key, one grab from the grab stack will
// be popped.
//
// When a grab is popped by user interacting as described above, if you
// pass a callback as @params.onUngrab, it will be called with %true.
//
// If @params.focus is not null, we'll set the key focus directly
// to that actor instead of navigating in @params.actor. This is for
// use cases like menus, where we want to grab the menu actor, but keep
// focus on the clicked on menu item.
grab: function(params) {
params = Params.parse(params, { actor: null,
modal: false,
grabFocus: false,
focus: null,
onUngrab: null });
@@ -162,24 +156,18 @@ const GrabHelper = new Lang.Class({
params.savedFocus = focus;
if (params.modal && !this._takeModalGrab())
return false;
if (params.grabFocus && !this._takeFocusGrab(hadFocus))
if (!this._takeModalGrab())
return false;
this._grabStack.push(params);
if (params.focus) {
params.focus.grab_key_focus();
} else if (newFocus && (hadFocus || params.grabFocus)) {
} else if (newFocus && hadFocus) {
if (!newFocus.navigate_focus(null, Gtk.DirectionType.TAB_FORWARD, false))
newFocus.grab_key_focus();
}
if ((params.grabFocus || params.modal) && !this._capturedEventId)
this._capturedEventId = global.stage.connect('captured-event', Lang.bind(this, this._onCapturedEvent));
return true;
},
@@ -188,6 +176,8 @@ const GrabHelper = new Lang.Class({
if (firstGrab) {
if (!Main.pushModal(this._owner, this._modalParams))
return false;
this._capturedEventId = global.stage.connect('captured-event', Lang.bind(this, this._onCapturedEvent));
}
this._modalCount++;
@@ -199,56 +189,15 @@ const GrabHelper = new Lang.Class({
if (this._modalCount > 0)
return;
global.stage.disconnect(this._capturedEventId);
this._capturedEventId = 0;
this._ignoreRelease = false;
Main.popModal(this._owner);
global.sync_pointer();
},
_takeFocusGrab: function(hadFocus) {
let firstGrab = (this._grabFocusCount == 0);
if (firstGrab) {
let metaDisplay = global.screen.get_display();
this._grabbedFromKeynav = hadFocus;
this._preGrabInputMode = global.stage_input_mode;
if (this._preGrabInputMode == Shell.StageInputMode.NORMAL)
global.set_stage_input_mode(Shell.StageInputMode.FOCUSED);
this._keyFocusNotifyId = global.stage.connect('notify::key-focus', Lang.bind(this, this._onKeyFocusChanged));
this._focusWindowChangedId = metaDisplay.connect('notify::focus-window', Lang.bind(this, this._focusWindowChanged));
}
this._grabFocusCount++;
return true;
},
_releaseFocusGrab: function() {
this._grabFocusCount--;
if (this._grabFocusCount > 0)
return;
if (this._keyFocusNotifyId > 0) {
global.stage.disconnect(this._keyFocusNotifyId);
this._keyFocusNotifyId = 0;
}
if (this._focusWindowChangedId > 0) {
let metaDisplay = global.screen.get_display();
metaDisplay.disconnect(this._focusWindowChangedId);
this._focusWindowChangedId = 0;
}
let prePopInputMode = global.stage_input_mode;
if (this._grabbedFromKeynav) {
if (this._preGrabInputMode == Shell.StageInputMode.FOCUSED &&
prePopInputMode != Shell.StageInputMode.FULLSCREEN)
global.set_stage_input_mode(Shell.StageInputMode.FOCUSED);
}
global.screen.focus_default_window(global.display.get_current_time_roundtrip());
},
// ignoreRelease:
//
// Make sure that the next button release event evaluated by the
@@ -262,10 +211,14 @@ const GrabHelper = new Lang.Class({
// ungrab:
// @params: The parameters for the grab; see below.
//
// Pops an actor from the grab stack, potentially dropping the grab.
// Pops @params.actor from the grab stack, potentially dropping
// the grab. If the actor is not on the grab stack, this call is
// ignored with no ill effects.
//
// If the actor that was popped from the grab stack was not the actor
// That was passed in, this call is ignored.
// If the actor is not at the top of the grab stack, grabs are
// popped until the grabbed actor is at the top of the grab stack.
// The onUngrab callback for every grab is called for every popped
// grab with the parameter %false.
ungrab: function(params) {
params = Params.parse(params, { actor: this.currentGrab.actor,
isUser: false });
@@ -274,14 +227,6 @@ const GrabHelper = new Lang.Class({
if (grabStackIndex < 0)
return;
// We may get key focus changes when calling onUngrab, which
// would cause an extra ungrab() on the next actor in the
// stack, which is wrong. Ignore key focus changes during the
// ungrab, and restore the saved key focus ourselves afterwards.
// We use a count as ungrab() may be re-entrant, as onUngrab()
// may ungrab additional actors.
this._isUngrabbingCount++;
let focus = global.stage.key_focus;
let hadFocus = focus && this._isWithinGrabbedActor(focus);
@@ -296,18 +241,7 @@ const GrabHelper = new Lang.Class({
if (poppedGrab.onUngrab)
poppedGrab.onUngrab(params.isUser);
if (poppedGrab.modal)
this._releaseModalGrab();
if (poppedGrab.grabFocus)
this._releaseFocusGrab();
}
if (!this.grabbed && this._capturedEventId > 0) {
global.stage.disconnect(this._capturedEventId);
this._capturedEventId = 0;
this._ignoreRelease = false;
this._releaseModalGrab();
}
if (hadFocus) {
@@ -315,8 +249,6 @@ const GrabHelper = new Lang.Class({
if (poppedGrab.savedFocus)
poppedGrab.savedFocus.grab_key_focus();
}
this._isUngrabbingCount--;
},
_onCapturedEvent: function(actor, event) {
@@ -337,9 +269,6 @@ const GrabHelper = new Lang.Class({
return true;
}
if (!button && this._modalCount == 0)
return false;
if (this._isWithinGrabbedActor(event.get_source()))
return false;
@@ -356,21 +285,6 @@ const GrabHelper = new Lang.Class({
return true;
}
return this._modalCount > 0;
return true;
},
_onKeyFocusChanged: function() {
if (this._isUngrabbingCount > 0)
return;
let focus = global.stage.key_focus;
if (!focus || !this._isWithinGrabbedActor(focus))
this.ungrab({ isUser: true });
},
_focusWindowChanged: function() {
let metaDisplay = global.screen.get_display();
if (metaDisplay.focus_window != null)
this.ungrab({ isUser: true });
}
});

View File

@@ -528,17 +528,10 @@ const LayoutManager = new Lang.Class({
get focusIndex() {
let i = Main.layoutManager.primaryIndex;
if (global.stage_input_mode == Shell.StageInputMode.FOCUSED ||
global.stage_input_mode == Shell.StageInputMode.FULLSCREEN) {
let focusActor = global.stage.key_focus;
if (focusActor)
i = this.findIndexForActor(focusActor);
} else {
let focusWindow = global.display.focus_window;
if (focusWindow)
i = focusWindow.get_monitor();
}
if (global.stage.key_focus != null)
i = this.findIndexForActor(global.stage.key_focus);
else if (global.display.focus_window != null)
i = global.display.focus_window.get_monitor();
return i;
},
@@ -596,9 +589,13 @@ const LayoutManager = new Lang.Class({
// screen. So, we set no_clear_hint at the end of the animation.
_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;
// During the initial transition, add a simple actor to block all events,
// so they don't get delivered to X11 windows that have been transformed.
this._coverPane = new Clutter.Actor({ opacity: 0,
width: global.screen_width,
height: global.screen_height,
reactive: true });
this.addChrome(this._coverPane);
if (Main.sessionMode.isGreeter) {
this.panelBox.translation_y = -this.panelBox.height;
@@ -668,7 +665,8 @@ const LayoutManager = new Lang.Class({
// we no longer need to clear the stage
global.stage.no_clear_hint = true;
global.stage_input_mode = Shell.StageInputMode.NORMAL;
this._coverPane.destroy();
this._coverPane = null;
this._systemBackground.actor.destroy();
this._systemBackground = null;

View File

@@ -849,8 +849,9 @@ const LookingGlass = new Lang.Class({
this._updateFont();
// We want it to appear to slide out from underneath the panel
Main.layoutManager.panelBox.add_actor(this.actor);
this.actor.lower_bottom();
Main.uiGroup.add_actor(this.actor);
Main.uiGroup.set_child_below_sibling(this.actor,
Main.layoutManager.panelBox);
Main.layoutManager.panelBox.connect('allocation-changed',
Lang.bind(this, this._queueResize));
Main.layoutManager.keyboardBox.connect('allocation-changed',
@@ -1072,7 +1073,7 @@ const LookingGlass = new Lang.Class({
let availableHeight = primary.height - Main.layoutManager.keyboardBox.height;
let myHeight = Math.min(primary.height * 0.7, availableHeight * 0.9);
this.actor.x = (primary.width - myWidth) / 2;
this._hiddenY = this.actor.get_parent().height - myHeight - 4; // -4 to hide the top corners
this._hiddenY = Main.layoutManager.panelBox.height - myHeight - 4; // -4 to hide the top corners
this._targetY = this._hiddenY + myHeight;
this.actor.y = this._hiddenY;
this.actor.width = myWidth;

View File

@@ -356,8 +356,6 @@ function pushModal(actor, params) {
Meta.disable_unredirect_for_screen(global.screen);
}
global.set_stage_input_mode(Shell.StageInputMode.FULLSCREEN);
modalCount += 1;
let actorDestroyId = actor.connect('destroy', function() {
let index = _findModal(actor);
@@ -406,7 +404,6 @@ function popModal(actor, timestamp) {
if (focusIndex < 0) {
global.stage.set_key_focus(null);
global.end_modal(timestamp);
global.set_stage_input_mode(Shell.StageInputMode.NORMAL);
keybindingMode = Shell.KeyBindingMode.NORMAL;
throw new Error('incorrect pop');
@@ -454,7 +451,6 @@ function popModal(actor, timestamp) {
return;
global.end_modal(timestamp);
global.set_stage_input_mode(Shell.StageInputMode.NORMAL);
Meta.enable_unredirect_for_screen(global.screen);
keybindingMode = Shell.KeyBindingMode.NORMAL;
}

View File

@@ -97,6 +97,65 @@ function _fixMarkup(text, allowMarkup) {
return GLib.markup_escape_text(text, -1);
}
const FocusGrabber = new Lang.Class({
Name: 'FocusGrabber',
_init: function(actor) {
this._actor = actor;
this._prevKeyFocusActor = null;
this._focusActorChangedId = 0;
this._focused = false;
},
grabFocus: function() {
if (this._focused)
return;
this._prevFocusedWindow = global.display.focus_window;
this._prevKeyFocusActor = global.stage.get_key_focus();
this._focusActorChangedId = global.stage.connect('notify::key-focus', Lang.bind(this, this._focusActorChanged));
if (!this._actor.navigate_focus(null, Gtk.DirectionType.TAB_FORWARD, false))
this._actor.grab_key_focus();
this._focused = true;
},
_focusUngrabbed: function() {
if (!this._focused)
return false;
if (this._focusActorChangedId > 0) {
global.stage.disconnect(this._focusActorChangedId);
this._focusActorChangedId = 0;
}
this._focused = false;
return true;
},
_focusActorChanged: function() {
let focusedActor = global.stage.get_key_focus();
if (!focusedActor || !this._actor.contains(focusedActor))
this._focusUngrabbed();
},
ungrabFocus: function() {
if (!this._focusUngrabbed())
return;
if (this._prevKeyFocusActor) {
global.stage.set_key_focus(this._prevKeyFocusActor);
this._prevKeyFocusActor = null;
} else {
let focusedActor = global.stage.get_key_focus();
if (focusedActor && this._actor.contains(focusedActor))
global.stage.set_key_focus(null);
}
}
});
const URLHighlighter = new Lang.Class({
Name: 'URLHighlighter',
@@ -1574,6 +1633,7 @@ const MessageTray = new Lang.Class({
this._notificationBin.set_y_align(Clutter.ActorAlign.START);
this._notificationWidget.add_actor(this._notificationBin);
this._notificationWidget.hide();
this._notificationFocusGrabber = new FocusGrabber(this._notificationWidget);
this._notificationQueue = [];
this._notification = null;
this._notificationClickedId = 0;
@@ -1623,7 +1683,6 @@ const MessageTray = new Lang.Class({
{ keybindingMode: Shell.KeyBindingMode.MESSAGE_TRAY });
this._grabHelper.addActor(this._summaryBoxPointer.actor);
this._grabHelper.addActor(this.actor);
this._grabHelper.addActor(this._notificationWidget);
Main.layoutManager.connect('keyboard-visible-changed', Lang.bind(this, this._onKeyboardVisibleChanged));
@@ -1749,7 +1808,6 @@ const MessageTray = new Lang.Class({
let [x, y, mask] = global.get_pointer();
this._contextMenu.setPosition(Math.round(x), Math.round(y));
this._grabHelper.grab({ actor: this._contextMenu.actor,
modal: true,
onUngrab: Lang.bind(this, function () {
this._contextMenu.close(BoxPointer.PopupAnimation.FULL);
})
@@ -2316,7 +2374,6 @@ const MessageTray = new Lang.Class({
_showTray: function() {
if (!this._grabHelper.grab({ actor: this.actor,
modal: true,
onUngrab: Lang.bind(this, this._escapeTray) })) {
this._traySummoned = false;
return false;
@@ -2520,19 +2577,7 @@ const MessageTray = new Lang.Class({
},
_hideNotification: function() {
// HACK!
// There seems to be a reentrancy issue in calling .ungrab() here,
// which causes _updateState to be called before _notificationState
// becomes HIDING. That hides the notification again, nullifying the
// object but not setting _notificationState (and that's the weird part)
// As then _notificationState is stuck into SHOWN but _notification
// is null, every new _updateState fails and the message tray is
// lost forever.
//
// See more at https://bugzilla.gnome.org/show_bug.cgi?id=683986
this._notificationState = State.HIDING;
this._grabHelper.ungrab({ actor: this._notification.actor });
this._notificationFocusGrabber.ungrabFocus();
if (this._notificationExpandedId) {
this._notification.disconnect(this._notificationExpandedId);
@@ -2630,8 +2675,7 @@ const MessageTray = new Lang.Class({
},
_ensureNotificationFocused: function() {
this._grabHelper.grab({ actor: this._notification.actor,
grabFocus: true });
this._notificationFocusGrabber.grabFocus();
},
_onSourceDoneDisplayingContent: function(source, closeTray) {
@@ -2674,7 +2718,6 @@ const MessageTray = new Lang.Class({
this._summaryBoxPointer.bin.child = child;
this._grabHelper.grab({ actor: this._summaryBoxPointer.bin.child,
modal: true,
onUngrab: Lang.bind(this, this._onSummaryBoxPointerUngrabbed) });
this._summaryBoxPointer.actor.opacity = 0;

View File

@@ -79,9 +79,8 @@ const ModalDialog = new Lang.Class({
this.dialogLayout = new St.BoxLayout({ style_class: 'modal-dialog',
vertical: true });
if (params.styleClass != null) {
if (params.styleClass != null)
this.dialogLayout.add_style_class_name(params.styleClass);
}
if (!this._shellReactive) {
this._lightbox = new Lightbox.Lightbox(this._group,
@@ -357,8 +356,9 @@ const ModalDialog = new Lang.Class({
if (this._savedKeyFocus) {
this._savedKeyFocus.grab_key_focus();
this._savedKeyFocus = null;
} else
} else {
this._initialKeyFocus.grab_key_focus();
}
if (!this._shellReactive)
this._eventBlocker.lower_bottom();

View File

@@ -148,7 +148,7 @@ const Overview = new Lang.Class({
// Dash elements, or mouseover handlers in the workspaces.
this._coverPane = new Clutter.Actor({ opacity: 0,
reactive: true });
this._overview.add_actor(this._coverPane);
this._stack.add_actor(this._coverPane);
this._coverPane.connect('event', Lang.bind(this, function (actor, event) { return true; }));
this._stack.add_actor(this._overview);

View File

@@ -449,7 +449,7 @@ const AppMenuButton = new Lang.Class({
// If the app has just lost focus to the panel, pretend
// nothing happened; otherwise you can't keynav to the
// app menu.
if (global.stage_input_mode == Shell.StageInputMode.FOCUSED)
if (global.stage.key_focus != null)
return;
}
this._sync();

View File

@@ -110,6 +110,7 @@ const Button = new Lang.Class({
this.actor.connect('button-press-event', Lang.bind(this, this._onButtonPress));
this.actor.connect('key-press-event', Lang.bind(this, this._onSourceKeyPress));
this.actor.connect('notify::visible', Lang.bind(this, this._onVisibilityChanged));
if (dontCreateMenu)
this.menu = new PopupMenu.PopupDummyMenu(this.actor);
@@ -183,6 +184,14 @@ const Button = new Lang.Class({
return false;
},
_onVisibilityChanged: function() {
if (!this.menu)
return;
if (!this.actor.visible)
this.menu.close();
},
_onMenuKeyPress: function(actor, event) {
if (global.focus_manager.navigate_from_event(event))
return true;

View File

@@ -42,7 +42,6 @@ const PopupBaseMenuItem = new Lang.Class({
params = Params.parse (params, { reactive: true,
activate: true,
hover: true,
sensitive: true,
style_class: null,
can_focus: true
});
@@ -65,9 +64,8 @@ const PopupBaseMenuItem = new Lang.Class({
this._spacing = 0;
this.active = false;
this._activatable = params.reactive && params.activate;
this.sensitive = this._activatable && params.sensitive;
this.setSensitive(this.sensitive);
this._sensitive = true;
this.parentSensitive = true;
if (!this._activatable)
this.actor.add_style_class_name('popup-inactive-menu-item');
@@ -137,17 +135,24 @@ const PopupBaseMenuItem = new Lang.Class({
}
},
setSensitive: function(sensitive) {
if (!this._activatable)
return;
if (this.sensitive == sensitive)
return;
this.sensitive = sensitive;
syncSensitive: function() {
let sensitive = this.getSensitive();
this.actor.reactive = sensitive;
this.actor.can_focus = sensitive;
this.emit('sensitive-changed');
return sensitive;
},
this.emit('sensitive-changed', sensitive);
getSensitive: function() {
return this._activatable && this._sensitive && this.parentSensitive;
},
setSensitive: function(sensitive) {
if (this._sensitive == sensitive)
return;
this._sensitive = sensitive;
this.syncSensitive();
},
destroy: function() {
@@ -268,6 +273,7 @@ const PopupBaseMenuItem = new Lang.Class({
},
_allocate: function(actor, box, flags) {
let width = box.x2 - box.x1;
let height = box.y2 - box.y1;
let direction = this.actor.get_text_direction();
@@ -290,86 +296,46 @@ const PopupBaseMenuItem = new Lang.Class({
this._ornamentLabel.allocate(ornamentBox, flags);
let x;
if (direction == Clutter.TextDirection.LTR)
x = box.x1;
else
x = box.x2;
// if direction is ltr, x is the right edge of the last added
// actor, and it's constantly increasing, whereas if rtl, x is
// the left edge and it decreases
let x = box.x1;
for (let i = 0, col = 0; i < this._children.length; i++) {
let child = this._children[i];
let childBox = new Clutter.ActorBox();
let [minWidth, naturalWidth] = child.actor.get_preferred_width(-1);
let availWidth, extraWidth;
if (this._columnWidths) {
if (child.span == -1) {
if (direction == Clutter.TextDirection.LTR)
availWidth = box.x2 - x;
else
availWidth = x - box.x1;
} else {
let availWidth;
if (child.span == -1) {
availWidth = box.x2 - x;
} else {
if (this._columnWidths) {
availWidth = 0;
for (let j = 0; j < child.span; j++)
availWidth += this._columnWidths[col++];
}
extraWidth = availWidth - naturalWidth;
} else {
if (child.span == -1) {
if (direction == Clutter.TextDirection.LTR)
availWidth = box.x2 - x;
else
availWidth = x - box.x1;
} else {
availWidth = naturalWidth;
}
extraWidth = 0;
}
if (direction == Clutter.TextDirection.LTR) {
if (child.expand) {
childBox.x1 = x;
childBox.x2 = x + availWidth;
} else if (child.align === St.Align.MIDDLE) {
childBox.x1 = x + Math.round(extraWidth / 2);
childBox.x2 = childBox.x1 + naturalWidth;
} else if (child.align === St.Align.END) {
childBox.x2 = x + availWidth;
childBox.x1 = childBox.x2 - naturalWidth;
} else {
childBox.x1 = x;
childBox.x2 = x + naturalWidth;
}
} else {
if (child.expand) {
childBox.x1 = x - availWidth;
childBox.x2 = x;
} else if (child.align === St.Align.MIDDLE) {
childBox.x1 = x - Math.round(extraWidth / 2);
childBox.x2 = childBox.x1 + naturalWidth;
} else if (child.align === St.Align.END) {
// align to the left
childBox.x1 = x - availWidth;
childBox.x2 = childBox.x1 + naturalWidth;
} else {
// align to the right
childBox.x2 = x;
childBox.x1 = x - naturalWidth;
}
}
if (direction == Clutter.TextDirection.RTL)
childBox.x1 = width - x - availWidth;
else
childBox.x1 = x;
childBox.x2 = childBox.x1 + availWidth;
let [minHeight, naturalHeight] = child.actor.get_preferred_height(childBox.x2 - childBox.x1);
childBox.y1 = Math.round(box.y1 + (height - naturalHeight) / 2);
childBox.y2 = childBox.y1 + naturalHeight;
child.actor.allocate(childBox, flags);
let [xAlign, yAlign] = St.get_align_factors(child.align,
St.Align.MIDDLE);
if (direction == Clutter.TextDirection.LTR)
x += availWidth + this._spacing;
else
x -= availWidth + this._spacing;
// It's called "expand", but it's really more like "fill"
let xFill = child.expand;
child.actor.allocate_align_fill(childBox,
xAlign, yAlign,
xFill, true,
flags);
x += availWidth + this._spacing;
}
}
});
@@ -672,6 +638,7 @@ const PopupMenuBase = new Lang.Class({
_init: function(sourceActor, styleClass) {
this.sourceActor = sourceActor;
this._parent = null;
if (styleClass !== undefined) {
this.box = new St.BoxLayout({ style_class: styleClass,
@@ -691,9 +658,28 @@ const PopupMenuBase = new Lang.Class({
this._activeMenuItem = null;
this._settingsActions = { };
this._sensitive = true;
this.parentSensitive = true;
this._sessionUpdatedId = Main.sessionMode.connect('updated', Lang.bind(this, this._sessionUpdated));
},
_getTopMenu: function() {
if (this._parent)
return this._parent._getTopMenu();
else
return this;
},
getSensitive: function() {
return this._sensitive && this.parentSensitive;
},
setSensitive: function(sensitive) {
this._sensitive = sensitive;
this.emit('sensitive-changed');
},
_sessionUpdated: function() {
this._setSettingsVisibility(Main.sessionMode.allowSettings);
},
@@ -746,25 +732,18 @@ const PopupMenuBase = new Lang.Class({
return false;
},
/**
* _connectSubMenuSignals:
* @object: a menu item, or a menu section
* @menu: a sub menu, or a menu section
*
* Connects to signals on @menu that are necessary for
* operating the submenu, and stores the ids on @object.
*/
_connectSubMenuSignals: function(object, menu) {
object._subMenuActivateId = menu.connect('activate', Lang.bind(this, function() {
this.emit('activate');
this.close(BoxPointer.PopupAnimation.FULL);
}));
object._subMenuActiveChangeId = menu.connect('active-changed', Lang.bind(this, function(submenu, submenuItem) {
if (this._activeMenuItem && this._activeMenuItem != submenuItem)
this._activeMenuItem.setActive(false);
this._activeMenuItem = submenuItem;
this.emit('active-changed', submenuItem);
}));
itemActivated: function(animate) {
if (animate == undefined)
animate = BoxPointer.PopupAnimation.FULL;
this._getTopMenu().close(animate);
},
_subMenuActiveChanged: function(submenu, submenuItem) {
if (this._activeMenuItem && this._activeMenuItem != submenuItem)
this._activeMenuItem.setActive(false);
this._activeMenuItem = submenuItem;
this.emit('active-changed', submenuItem);
},
_connectItemSignals: function(menuItem) {
@@ -779,7 +758,8 @@ const PopupMenuBase = new Lang.Class({
this.emit('active-changed', null);
}
}));
menuItem._sensitiveChangeId = menuItem.connect('sensitive-changed', Lang.bind(this, function(menuItem, sensitive) {
menuItem._sensitiveChangeId = menuItem.connect('sensitive-changed', Lang.bind(this, function() {
let sensitive = menuItem.getSensitive();
if (!sensitive && this._activeMenuItem == menuItem) {
if (!this.actor.navigate_focus(menuItem.actor,
Gtk.DirectionType.TAB_FORWARD,
@@ -792,8 +772,14 @@ const PopupMenuBase = new Lang.Class({
}));
menuItem._activateId = menuItem.connect('activate', Lang.bind(this, function (menuItem, event) {
this.emit('activate', menuItem);
this.close(BoxPointer.PopupAnimation.FULL);
this.itemActivated(BoxPointer.PopupAnimation.FULL);
}));
menuItem._parentSensitiveChangeId = this.connect('sensitive-changed', Lang.bind(this, function() {
menuItem.parentSensitive = this.getSensitive();
menuItem.syncSensitive();
}));
// the weird name is to avoid a conflict with some random property
// the menuItem may have, called destroyId
// (FIXME: in the future it may make sense to have container objects
@@ -803,11 +789,7 @@ const PopupMenuBase = new Lang.Class({
menuItem.disconnect(menuItem._activateId);
menuItem.disconnect(menuItem._activeChangeId);
menuItem.disconnect(menuItem._sensitiveChangeId);
if (menuItem.menu) {
menuItem.menu.disconnect(menuItem._subMenuActivateId);
menuItem.menu.disconnect(menuItem._subMenuActiveChangeId);
this.disconnect(menuItem._closingId);
}
this.disconnect(menuItem._parentSensitiveChangeId);
if (menuItem == this._activeMenuItem)
this._activeMenuItem = null;
}));
@@ -864,19 +846,31 @@ const PopupMenuBase = new Lang.Class({
}
if (menuItem instanceof PopupMenuSection) {
this._connectSubMenuSignals(menuItem, menuItem);
menuItem._parentOpenStateChangedId = this.connect('open-state-changed',
function(self, open) {
if (open)
menuItem.open();
else
menuItem.close();
});
menuItem.connect('destroy', Lang.bind(this, function() {
menuItem.disconnect(menuItem._subMenuActivateId);
menuItem.disconnect(menuItem._subMenuActiveChangeId);
this.disconnect(menuItem._parentOpenStateChangedId);
let activateId = menuItem.connect('activate', Lang.bind(this, function() {
this.emit('activate');
}));
let activeChangeId = menuItem.connect('active-changed', Lang.bind(this, this._subMenuActiveChanged));
let parentOpenStateChangedId = this.connect('open-state-changed', function(self, open) {
if (open)
menuItem.open();
else
menuItem.close();
});
let parentClosingId = this.connect('menu-closed', function() {
menuItem.emit('menu-closed');
});
let subMenuSensitiveChangedId = this.connect('sensitive-changed', Lang.bind(this, function() {
menuItem.parentSensitive = this.getSensitive();
menuItem.emit('sensitive-changed');
}));
menuItem.connect('destroy', Lang.bind(this, function() {
menuItem.disconnect(activateId);
menuItem.disconnect(activeChangeId);
this.disconnect(subMenuSensitiveChangedId);
this.disconnect(parentOpenStateChangedId);
this.disconnect(parentClosingId);
this.length--;
}));
} else if (menuItem instanceof PopupSubMenuMenuItem) {
@@ -884,12 +878,21 @@ const PopupMenuBase = new Lang.Class({
this.box.add(menuItem.menu.actor);
else
this.box.insert_child_below(menuItem.menu.actor, before_item);
this._connectSubMenuSignals(menuItem, menuItem.menu);
this._connectItemSignals(menuItem);
menuItem._closingId = this.connect('open-state-changed', function(self, open) {
if (!open)
menuItem.menu.close(BoxPointer.PopupAnimation.FADE);
let subMenuActivateId = menuItem.connect('activate', Lang.bind(this, function() {
this.emit('activate');
}));
let subMenuActiveChangeId = menuItem.menu.connect('active-changed', Lang.bind(this, this._subMenuActiveChanged));
let closingId = this.connect('menu-closed', function() {
menuItem.menu.close(BoxPointer.PopupAnimation.NONE);
});
menuItem.connect('destroy', Lang.bind(this, function() {
menuItem.menu.disconnect(subMenuActivateId);
menuItem.menu.disconnect(subMenuActiveChangeId);
this.disconnect(closingId);
}));
} else if (menuItem instanceof PopupSeparatorMenuItem) {
this._connectItemSignals(menuItem);
@@ -903,6 +906,8 @@ const PopupMenuBase = new Lang.Class({
else
throw TypeError("Invalid argument to PopupMenuBase.addMenuItem()");
menuItem._parent = this;
this.length++;
},
@@ -910,9 +915,12 @@ const PopupMenuBase = new Lang.Class({
let columnWidths = [];
let items = this.box.get_children();
for (let i = 0; i < items.length; i++) {
if (!items[i].visible &&
!(items[i]._delegate instanceof PopupSubMenu && items[i-1].visible))
if (!items[i].visible)
continue;
if (items[i]._delegate instanceof PopupSubMenu)
continue;
if (items[i]._delegate instanceof PopupBaseMenuItem || items[i]._delegate instanceof PopupMenuBase) {
let itemColumnWidths = items[i]._delegate.getColumnWidths();
for (let j = 0; j < itemColumnWidths.length; j++) {
@@ -927,6 +935,9 @@ const PopupMenuBase = new Lang.Class({
setColumnWidths: function(widths) {
let items = this.box.get_children();
for (let i = 0; i < items.length; i++) {
if (items[i]._delegate instanceof PopupSubMenu)
continue;
if (items[i]._delegate instanceof PopupBaseMenuItem || items[i]._delegate instanceof PopupMenuBase)
items[i]._delegate.setColumnWidths(widths);
}
@@ -1024,6 +1035,14 @@ const PopupMenu = new Lang.Class({
this.actor.reactive = true;
this._childMenus = [];
this._openedSubMenu = null;
},
_setOpenedSubMenu: function(submenu) {
if (this._openedSubMenu)
this._openedSubMenu.close(true);
this._openedSubMenu = submenu;
},
_boxGetPreferredWidth: function (actor, forHeight, alloc) {
@@ -1097,8 +1116,11 @@ const PopupMenu = new Lang.Class({
childMenu.close();
});
if (this._boxPointer.actor.visible)
this._boxPointer.hide(animate);
if (this._boxPointer.actor.visible) {
this._boxPointer.hide(animate, Lang.bind(this, function() {
this.emit('menu-closed');
}));
}
if (!this.isOpen)
return;
@@ -1121,6 +1143,10 @@ const PopupDummyMenu = new Lang.Class({
return false;
},
getSensitive: function() {
return true;
},
open: function() { this.emit('open-state-changed', true); },
close: function() { this.emit('open-state-changed', false); },
toggle: function() {},
@@ -1154,18 +1180,6 @@ const PopupSubMenu = new Lang.Class({
this.actor.hide();
},
_getTopMenu: function() {
let actor = this.actor.get_parent();
while (actor) {
if (actor._delegate && actor._delegate instanceof PopupMenu)
return actor._delegate;
actor = actor.get_parent();
}
return null;
},
_needsScrollbar: function() {
let topMenu = this._getTopMenu();
let [topMinHeight, topNaturalHeight] = topMenu.actor.get_preferred_height(-1);
@@ -1175,6 +1189,10 @@ const PopupSubMenu = new Lang.Class({
return topMaxHeight >= 0 && topNaturalHeight >= topMaxHeight;
},
getSensitive: function() {
return this._sensitive && this.sourceActor._delegate.getSensitive();
},
open: function(animate) {
if (this.isOpen)
return;
@@ -1183,6 +1201,7 @@ const PopupSubMenu = new Lang.Class({
return;
this.isOpen = true;
this.emit('open-state-changed', true);
this.actor.show();
@@ -1221,12 +1240,10 @@ const PopupSubMenu = new Lang.Class({
onCompleteScope: this,
onComplete: function() {
this.actor.set_height(-1);
this.emit('open-state-changed', true);
}
});
} else {
this._arrow.rotation_angle_z = 90;
this.emit('open-state-changed', true);
}
},
@@ -1235,6 +1252,7 @@ const PopupSubMenu = new Lang.Class({
return;
this.isOpen = false;
this.emit('open-state-changed', false);
if (this._activeMenuItem)
this._activeMenuItem.setActive(false);
@@ -1252,8 +1270,6 @@ const PopupSubMenu = new Lang.Class({
onComplete: function() {
this.actor.hide();
this.actor.set_height(-1);
this.emit('open-state-changed', false);
},
onUpdateScope: this,
onUpdate: function() {
@@ -1263,9 +1279,6 @@ const PopupSubMenu = new Lang.Class({
} else {
this._arrow.rotation_angle_z = 0;
this.actor.hide();
this.isOpen = false;
this.emit('open-state-changed', false);
}
},
@@ -1327,11 +1340,20 @@ const PopupSubMenuMenuItem = new Lang.Class({
this.menu.connect('open-state-changed', Lang.bind(this, this._subMenuOpenStateChanged));
},
syncSensitive: function() {
let sensitive = this.parent();
this._triangle.visible = sensitive;
if (!sensitive)
this.menu.close(false);
},
_subMenuOpenStateChanged: function(menu, open) {
if (open)
this.actor.add_style_pseudo_class('open');
else
this.actor.remove_style_pseudo_class('open');
this._getTopMenu()._setOpenedSubMenu(this.menu);
},
destroy: function() {
@@ -1701,7 +1723,7 @@ const PopupMenuManager = new Lang.Class({
if (open) {
if (this.activeMenu && !this.activeMenu.isChildMenu(menu))
this.activeMenu.close(BoxPointer.PopupAnimation.FADE);
this._grabHelper.grab({ actor: menu.actor, modal: true, focus: menu.sourceActor,
this._grabHelper.grab({ actor: menu.actor, focus: menu.sourceActor,
onUngrab: Lang.bind(this, this._closeMenu, menu) });
} else {
this._grabHelper.ungrab({ actor: menu.actor });

View File

@@ -764,19 +764,6 @@ const ScreenShield = new Lang.Class({
}
}
if (!this._becomeModal()) {
// 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
Main.notifyError(_("Unable to lock"),
_("Lock was blocked by an application"));
return;
}
if (this._lightbox.actor.visible ||
this._isActive) {
// We're either shown and active, or in the process of
@@ -790,6 +777,19 @@ const ScreenShield = new Lang.Class({
return;
}
if (!this._becomeModal()) {
// 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
Main.notifyError(_("Unable to lock"),
_("Lock was blocked by an application"));
return;
}
this._lightbox.show();
if (this._activationTime == 0)

View File

@@ -1528,7 +1528,7 @@ const NMApplet = new Lang.Class({
this._client.connect('notify::manager-running', Lang.bind(this, this._syncNMState));
this._client.connect('notify::networking-enabled', Lang.bind(this, this._syncNMState));
this._client.connect('notify::state', Lang.bind(this, this._syncNMState));
this._client.connect('notify::active-connections', Lang.bind(this, this._updateIcon));
this._client.connect('notify::active-connections', Lang.bind(this, this._syncActiveConnections));
this._client.connect('device-added', Lang.bind(this, this._deviceAdded));
this._client.connect('device-removed', Lang.bind(this, this._deviceRemoved));
this._settings.connect('new-connection', Lang.bind(this, this._newConnection));
@@ -1761,8 +1761,8 @@ const NMApplet = new Lang.Class({
let a = this._activeConnections[i];
if (!a._inited) {
a._notifyDefaultId = a.connect('notify::default', Lang.bind(this, this._updateIcon));
a._notifyDefault6Id = a.connect('notify::default6', Lang.bind(this, this._updateIcon));
a._notifyDefaultId = a.connect('notify::default', Lang.bind(this, this._syncActiveConnections));
a._notifyDefault6Id = a.connect('notify::default6', Lang.bind(this, this._syncActiveConnections));
a._notifyStateId = a.connect('notify::state', Lang.bind(this, this._notifyActivated));
a._inited = true;
@@ -1814,6 +1814,7 @@ const NMApplet = new Lang.Class({
if (this._mainConnection) {
let dev = this._mainConnection._primaryDevice;
this._mainConnectionIconChangedId = dev.connect('icon-changed', Lang.bind(this, this._updateIcon));
this._updateIcon();
}
},
@@ -1824,7 +1825,7 @@ const NMApplet = new Lang.Class({
activeConnection._primaryDevice._notification = null;
}
this._updateIcon();
this._syncActiveConnections();
},
_ignoreConnection: function(connection) {
@@ -1861,7 +1862,7 @@ const NMApplet = new Lang.Class({
_newConnection: function(settings, connection) {
this._addConnection(connection);
this._updateIcon();
this._syncActiveConnections();
},
_connectionRemoved: function(connection) {
@@ -1940,11 +1941,10 @@ const NMApplet = new Lang.Class({
}
this._showNormal();
this._updateIcon();
this._syncActiveConnections();
},
_updateIcon: function() {
this._syncActiveConnections();
let hasApIcon = false;
let hasMobileIcon = false;

View File

@@ -1,6 +1,7 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const AccountsService = imports.gi.AccountsService;
const Atk = imports.gi.Atk;
const Clutter = imports.gi.Clutter;
const Gdm = imports.gi.Gdm;
const Gio = imports.gi.Gio;
@@ -12,10 +13,9 @@ const Signals = imports.signals;
const Shell = imports.gi.Shell;
const St = imports.gi.St;
const Layout = imports.ui.layout;
const Main = imports.ui.main;
const ModalDialog = imports.ui.modalDialog;
const Panel = imports.ui.panel;
const ShellEntry = imports.ui.shellEntry;
const Tweener = imports.ui.tweener;
const UserWidget = imports.ui.userWidget;
@@ -28,21 +28,20 @@ const IDLE_TIMEOUT = 2 * 60;
const UnlockDialog = new Lang.Class({
Name: 'UnlockDialog',
Extends: ModalDialog.ModalDialog,
_init: function(parentActor) {
this.parent({ shellReactive: true,
styleClass: 'login-dialog',
keybindingMode: Shell.KeyBindingMode.UNLOCK_SCREEN,
parentActor: parentActor
});
this.actor = new St.Widget({ accessible_role: Atk.Role.WINDOW,
style_class: 'login-dialog',
visible: false });
this.actor.add_constraint(new Layout.MonitorConstraint({ primary: true }));
parentActor.add_child(this.actor);
this._userManager = AccountsService.UserManager.get_default();
this._userName = GLib.get_user_name();
this._user = this._userManager.get_user(this._userName);
this._failCounter = 0;
this._firstQuestion = true;
this._greeterClient = new Gdm.Client();
this._userVerifier = new GdmUtil.ShellUserVerifier(this._greeterClient, { reauthenticationOnly: true });
@@ -57,62 +56,21 @@ const UnlockDialog = new Lang.Class({
this._userVerifier.connect('show-login-hint', Lang.bind(this, this._showLoginHint));
this._userVerifier.connect('hide-login-hint', Lang.bind(this, this._hideLoginHint));
this._userWidget = new UserWidget.UserWidget(this._user);
this.contentLayout.add_actor(this._userWidget.actor);
this._promptBox = new St.BoxLayout({ vertical: true });
this.actor.add_child(this._promptBox);
this._promptBox.add_constraint(new Clutter.AlignConstraint({ source: this.actor,
align_axis: Clutter.AlignAxis.BOTH,
factor: 0.5 }));
this._promptLayout = new St.BoxLayout({ style_class: 'login-dialog-prompt-layout',
vertical: true });
this._promptLabel = new St.Label({ style_class: 'login-dialog-prompt-label' });
this._promptLayout.add(this._promptLabel,
{ x_align: St.Align.START });
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);
this._promptEntry.clutter_text.connect('text-changed', Lang.bind(this, function() {
this._updateOkButtonSensitivity(this._promptEntry.text.length > 0);
}));
this._promptLayout.add(this._promptEntry,
{ expand: true,
x_fill: true });
this.contentLayout.add_actor(this._promptLayout);
this._promptMessage = new St.Label({ visible: false });
this.contentLayout.add(this._promptMessage, { x_fill: true });
this._promptLoginHint = new St.Label({ style_class: 'login-dialog-prompt-login-hint' });
this._promptLoginHint.hide();
this.contentLayout.add_actor(this._promptLoginHint);
this._authPrompt = new GdmUtil.AuthPrompt({ style_class: 'login-dialog-prompt-layout',
vertical: true });
this._authPrompt.setUser(this._user);
this._authPrompt.setPasswordChar('\u25cf');
this._authPrompt.resetButtons(_("Cancel"), _("Unlock"));
this._authPrompt.connect('cancel', Lang.bind(this, this._escape));
this._promptBox.add_child(this._authPrompt.actor);
this.allowCancel = false;
this.buttonLayout.visible = true;
this.addButton({ label: _("Cancel"),
action: Lang.bind(this, this._escape),
key: Clutter.KEY_Escape },
{ expand: true,
x_fill: false,
y_fill: false,
x_align: St.Align.START,
y_align: St.Align.MIDDLE });
this.placeSpinner({ expand: false,
x_fill: false,
y_fill: false,
x_align: St.Align.END,
y_align: St.Align.MIDDLE });
this._okButton = this.addButton({ label: _("Unlock"),
action: Lang.bind(this, this._doUnlock),
default: true },
{ expand: false,
x_fill: false,
y_fill: false,
x_align: St.Align.END,
y_align: St.Align.MIDDLE });
let screenSaverSettings = new Gio.Settings({ schema: 'org.gnome.desktop.screensaver' });
if (screenSaverSettings.get_boolean('user-switch-enabled')) {
@@ -125,9 +83,7 @@ const UnlockDialog = new Lang.Class({
x_align: St.Align.START,
x_fill: true });
this._otherUserButton.connect('clicked', Lang.bind(this, this._otherUserClicked));
this.dialogLayout.add(this._otherUserButton,
{ x_align: St.Align.START,
x_fill: false });
this._promptBox.add_child(this._otherUserButton);
} else {
this._otherUserButton = null;
}
@@ -137,80 +93,49 @@ const UnlockDialog = new Lang.Class({
let batch = new Batch.Hold();
this._userVerifier.begin(this._userName, batch);
Main.ctrlAltTabManager.addGroup(this.dialogLayout, _("Unlock Window"), 'dialog-password-symbolic');
Main.ctrlAltTabManager.addGroup(this.actor, _("Unlock Window"), 'dialog-password-symbolic');
this._idleMonitor = new GnomeDesktop.IdleMonitor();
this._idleWatchId = this._idleMonitor.add_idle_watch(IDLE_TIMEOUT * 1000, Lang.bind(this, this._escape));
},
_updateSensitivity: function(sensitive) {
this._promptEntry.reactive = sensitive;
this._promptEntry.clutter_text.editable = sensitive;
this._updateOkButtonSensitivity(sensitive && this._promptEntry.text.length > 0);
this._authPrompt.updateSensitivity(sensitive);
if (this._otherUserButton) {
this._otherUserButton.reactive = sensitive;
this._otherUserButton.can_focus = sensitive;
}
},
_updateOkButtonSensitivity: function(sensitive) {
this._okButton.reactive = sensitive;
this._okButton.can_focus = sensitive;
},
_showMessage: function(userVerifier, message, styleClass) {
if (message) {
this._promptMessage.text = message;
this._promptMessage.styleClass = styleClass;
GdmUtil.fadeInActor(this._promptMessage);
} else {
GdmUtil.fadeOutActor(this._promptMessage);
}
this._authPrompt.setMessage(message, styleClass);
},
_onAskQuestion: function(verifier, serviceName, question, passwordChar) {
if (this._firstQuestion && this._firstQuestionAnswer) {
this._userVerifier.answerQuery(serviceName, this._firstQuestionAnswer);
this._firstQuestionAnswer = null;
this._firstQuestion = false;
return;
}
this._promptLabel.text = question;
if (!this._firstQuestion)
this._promptEntry.text = '';
else
this._firstQuestion = false;
this._promptEntry.clutter_text.set_password_char(passwordChar);
this._promptEntry.menu.isPassword = passwordChar != '';
this._currentQuery = serviceName;
this._authPrompt.setPasswordChar(passwordChar);
this._authPrompt.setQuestion(question);
let signalId = this._authPrompt.connect('next', Lang.bind(this, function() {
this._authPrompt.disconnect(signalId);
this._doUnlock();
}));
this._updateSensitivity(true);
this.setWorking(false);
this._authPrompt.stopSpinning();
},
_showLoginHint: function(verifier, message) {
this._promptLoginHint.set_text(message)
GdmUtil.fadeInActor(this._promptLoginHint);
this._authPrompt.setHint(message);
},
_hideLoginHint: function() {
GdmUtil.fadeOutActor(this._promptLoginHint);
this._authPrompt.setHint(null);
},
_doUnlock: function() {
if (this._firstQuestion) {
// we haven't received a query yet, so stash the answer
// and make ourself non-reactive
// the actual reply to GDM will be sent as soon as asked
this._firstQuestionAnswer = this._promptEntry.text;
this._updateSensitivity(false);
this.setWorking(true);
return;
}
if (!this._currentQuery)
return;
@@ -218,13 +143,16 @@ const UnlockDialog = new Lang.Class({
this._currentQuery = null;
this._updateSensitivity(false);
this.setWorking(true);
this._authPrompt.startSpinning();
this._userVerifier.answerQuery(query, this._promptEntry.text);
this._userVerifier.answerQuery(query, this._authPrompt.getAnswer());
},
_finishUnlock: function() {
this._userVerifier.clear();
this._authPrompt.clear();
this._authPrompt.stopSpinning();
this._updateSensitivity(true);
this.emit('unlocked');
},
@@ -253,12 +181,10 @@ const UnlockDialog = new Lang.Class({
this._firstQuestion = true;
this._userVerified = false;
this._promptEntry.text = '';
this._promptEntry.clutter_text.set_password_char('\u25cf');
this._promptEntry.menu.isPassword = true;
this._authPrompt.clear();
this._updateSensitivity(false);
this.setWorking(false);
this._authPrompt.stopSpinning();
},
_escape: function() {
@@ -282,8 +208,6 @@ const UnlockDialog = new Lang.Class({
this._idleMonitor.remove_watch(this._idleWatchId);
this._idleWatchId = 0;
}
this.parent();
},
cancel: function() {
@@ -293,6 +217,29 @@ const UnlockDialog = new Lang.Class({
},
addCharacter: function(unichar) {
this._promptEntry.clutter_text.insert_unichar(unichar);
this._authPrompt.addCharacter(unichar);
},
open: function(timestamp) {
this.actor.show();
if (this._isModal)
return true;
if (!Main.pushModal(this.actor, { timestamp: timestamp,
keybindingMode: Shell.KeyBindingMode.UNLOCK_SCREEN }))
return false;
this._isModal = true;
return true;
},
popModal: function(timestamp) {
if (this._isModal) {
Main.popModal(this.actor, timestamp);
this._isModal = false;
}
}
});
Signals.addSignalMethods(UnlockDialog.prototype);

View File

@@ -803,13 +803,13 @@ const UserMenuButton = new Lang.Class({
},
_onLockScreenActivate: function() {
this.menu.close(BoxPointer.PopupAnimation.NONE);
this.menu.itemActivated(BoxPointer.PopupAnimation.NONE);
Main.overview.hide();
Main.screenShield.lock(true);
},
_onLoginScreenActivate: function() {
this.menu.close(BoxPointer.PopupAnimation.NONE);
this.menu.itemActivated(BoxPointer.PopupAnimation.NONE);
Main.overview.hide();
if (Main.screenShield)
Main.screenShield.lock(false);
@@ -937,7 +937,7 @@ const UserMenuButton = new Lang.Class({
this._session.ShutdownRemote();
}));
} else {
this.menu.close(BoxPointer.PopupAnimation.NONE);
this.menu.itemActivated(BoxPointer.PopupAnimation.NONE);
this._loginManager.suspend();
}
}

370
po/de.po
View File

@@ -19,16 +19,16 @@ 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: 2013-05-31 22:35+0000\n"
"PO-Revision-Date: 2013-06-02 09:48+0100\n"
"Last-Translator: Christian Kirbach <christian.kirbach@gmail.com>\n"
"POT-Creation-Date: 2013-07-04 13:18+0000\n"
"PO-Revision-Date: 2013-07-02 06:35+0100\n"
"Last-Translator: Benjamin Steinwender <b@stbe.at>\n"
"Language-Team: Deutsch <gnome-de@gnome.org>\n"
"Language: de_DE\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: Poedit 1.5.4\n"
"X-Generator: Poedit 1.5.5\n"
#: ../data/50-gnome-shell-screenshot.xml.in.h:1
msgid "Screenshots"
@@ -387,37 +387,41 @@ msgstr "Erweiterung"
msgid "Select an extension to configure using the combobox above."
msgstr "Wählen Sie oben eine Erweiterung aus, die Sie konfigurieren wollen."
#: ../js/gdm/loginDialog.js:371
msgid "Session"
msgstr "Sitzung "
#: ../js/gdm/loginDialog.js:308
msgid "Choose Session"
msgstr "Sitzung wählen"
#: ../js/gdm/loginDialog.js:326
msgid "Session"
msgstr "Sitzung"
#. 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:601
#: ../js/gdm/loginDialog.js:528
msgid "Not listed?"
msgstr "Nicht aufgeführt?"
#: ../js/gdm/loginDialog.js:776 ../js/ui/components/networkAgent.js:137
#: ../js/gdm/loginDialog.js:810 ../js/ui/components/networkAgent.js:137
#: ../js/ui/components/polkitAgent.js:161 ../js/ui/endSessionDialog.js:376
#: ../js/ui/extensionDownloader.js:195 ../js/ui/shellMountOperation.js:399
#: ../js/ui/status/bluetooth.js:415 ../js/ui/unlockDialog.js:96
#: ../js/ui/userMenu.js:938
#: ../js/ui/status/bluetooth.js:449 ../js/ui/unlockDialog.js:95
#: ../js/ui/userMenu.js:884
msgid "Cancel"
msgstr "Abbrechen"
#: ../js/gdm/loginDialog.js:791
#: ../js/gdm/loginDialog.js:833
msgctxt "button"
msgid "Sign In"
msgstr "Anmelden"
#: ../js/gdm/loginDialog.js:791
#: ../js/gdm/loginDialog.js:833
msgid "Next"
msgstr "Nächstes"
#. Translators: this message is shown below the username entry field
#. to clue the user in on how to login to the local network realm
#: ../js/gdm/loginDialog.js:888
#: ../js/gdm/loginDialog.js:934
#, c-format
msgid "(e.g., user or %s)"
msgstr "(z.B. Benutzer oder %s)"
@@ -425,12 +429,12 @@ msgstr "(z.B. Benutzer oder %s)"
#. TTLS and PEAP are actually much more complicated, but this complication
#. is not visible here since we only care about phase2 authentication
#. (and don't even care of which one)
#: ../js/gdm/loginDialog.js:892 ../js/ui/components/networkAgent.js:260
#: ../js/gdm/loginDialog.js:938 ../js/ui/components/networkAgent.js:260
#: ../js/ui/components/networkAgent.js:278
msgid "Username: "
msgstr "Benutzername:"
#: ../js/gdm/loginDialog.js:1158
#: ../js/gdm/loginDialog.js:1205
msgid "Login Window"
msgstr "Anmeldefenster"
@@ -439,8 +443,8 @@ msgstr "Anmeldefenster"
msgid "Power"
msgstr "Ausschalten"
#: ../js/gdm/powerMenu.js:93 ../js/ui/userMenu.js:696 ../js/ui/userMenu.js:700
#: ../js/ui/userMenu.js:816
#: ../js/gdm/powerMenu.js:93 ../js/ui/userMenu.js:651 ../js/ui/userMenu.js:655
#: ../js/ui/userMenu.js:768
msgid "Suspend"
msgstr "Bereitschaft"
@@ -448,18 +452,18 @@ msgstr "Bereitschaft"
msgid "Restart"
msgstr "Neu starten"
#: ../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
#: ../js/gdm/powerMenu.js:103 ../js/ui/userMenu.js:653
#: ../js/ui/userMenu.js:655 ../js/ui/userMenu.js:767 ../js/ui/userMenu.js:888
msgid "Power Off"
msgstr "Ausschalten"
#: ../js/gdm/util.js:247
#: ../js/gdm/util.js:248
msgid "Authentication error"
msgstr "Legitimationsfehler"
#. Translators: this message is shown below the password entry field
#. to indicate the user can swipe their finger instead
#: ../js/gdm/util.js:364
#: ../js/gdm/util.js:365
msgid "(or swipe finger)"
msgstr "(oder benutzen Sie den Fingerabdruckleser)"
@@ -478,23 +482,23 @@ msgstr "Befehl konnte nicht verarbeitet werden:"
msgid "Execution of '%s' failed:"
msgstr "Ausführung von »%s« ist gescheitert:"
#: ../js/ui/appDisplay.js:361
#: ../js/ui/appDisplay.js:397
msgid "Frequent"
msgstr "Häufig"
#: ../js/ui/appDisplay.js:368
#: ../js/ui/appDisplay.js:404
msgid "All"
msgstr "Alle"
#: ../js/ui/appDisplay.js:960
#: ../js/ui/appDisplay.js:996
msgid "New Window"
msgstr "Neues Fenster"
#: ../js/ui/appDisplay.js:963 ../js/ui/dash.js:284
#: ../js/ui/appDisplay.js:999 ../js/ui/dash.js:284
msgid "Remove from Favorites"
msgstr "Aus Favoriten entfernen"
#: ../js/ui/appDisplay.js:964
#: ../js/ui/appDisplay.js:1000
msgid "Add to Favorites"
msgstr "Zu Favoriten hinzufügen"
@@ -508,7 +512,7 @@ msgstr "%s wurde zu Ihren Favoriten hinzugefügt"
msgid "%s has been removed from your favorites."
msgstr "%s wurde aus Ihren Favoriten entfernt"
#: ../js/ui/backgroundMenu.js:19 ../js/ui/userMenu.js:789
#: ../js/ui/backgroundMenu.js:19 ../js/ui/userMenu.js:744
msgid "Settings"
msgstr "Einstellungen"
@@ -636,35 +640,35 @@ msgid "S"
msgstr "Sa"
#. Translators: Text to show if there are no events
#: ../js/ui/calendar.js:735
#: ../js/ui/calendar.js:750
msgid "Nothing Scheduled"
msgstr "Nichts geplant"
#. Translators: Shown on calendar heading when selected day occurs on current year
#: ../js/ui/calendar.js:751
#: ../js/ui/calendar.js:768
msgctxt "calendar heading"
msgid "%A, %B %d"
msgstr "%A, %d. %B"
#. Translators: Shown on calendar heading when selected day occurs on different year
#: ../js/ui/calendar.js:754
#: ../js/ui/calendar.js:771
msgctxt "calendar heading"
msgid "%A, %B %d, %Y"
msgstr "%a, %d. %B %Y"
#: ../js/ui/calendar.js:764
#: ../js/ui/calendar.js:782
msgid "Today"
msgstr "Heute"
#: ../js/ui/calendar.js:768
#: ../js/ui/calendar.js:786
msgid "Tomorrow"
msgstr "Morgen"
#: ../js/ui/calendar.js:779
#: ../js/ui/calendar.js:797
msgid "This week"
msgstr "Diese Woche"
#: ../js/ui/calendar.js:787
#: ../js/ui/calendar.js:805
msgid "Next week"
msgstr "Nächste Woche"
@@ -853,14 +857,14 @@ 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:985
#: ../js/ui/components/telepathyClient.js:986
#, c-format
msgid "%s is now known as %s"
msgstr "%s heißt jetzt %s"
#. translators: argument is a room name like
#. * room@jabber.org for example.
#: ../js/ui/components/telepathyClient.js:1088
#: ../js/ui/components/telepathyClient.js:1089
#, c-format
msgid "Invitation to %s"
msgstr "Einladung zum Betreten von %s"
@@ -868,38 +872,38 @@ msgstr "Einladung zum Betreten von %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:1096
#: ../js/ui/components/telepathyClient.js:1097
#, c-format
msgid "%s is inviting you to join %s"
msgstr "%s lädt Sie ein, %s beizutreten"
#: ../js/ui/components/telepathyClient.js:1098
#: ../js/ui/components/telepathyClient.js:1137
#: ../js/ui/components/telepathyClient.js:1177
#: ../js/ui/components/telepathyClient.js:1240
#: ../js/ui/components/telepathyClient.js:1099
#: ../js/ui/components/telepathyClient.js:1138
#: ../js/ui/components/telepathyClient.js:1178
#: ../js/ui/components/telepathyClient.js:1241
msgid "Decline"
msgstr "Ablehnen"
#: ../js/ui/components/telepathyClient.js:1099
#: ../js/ui/components/telepathyClient.js:1178
#: ../js/ui/components/telepathyClient.js:1241
#: ../js/ui/components/telepathyClient.js:1100
#: ../js/ui/components/telepathyClient.js:1179
#: ../js/ui/components/telepathyClient.js:1242
msgid "Accept"
msgstr "Annehmen"
#. translators: argument is a contact name like Alice for example.
#: ../js/ui/components/telepathyClient.js:1129
#: ../js/ui/components/telepathyClient.js:1130
#, c-format
msgid "Video call from %s"
msgstr "Video-Anruf von %s"
#. translators: argument is a contact name like Alice for example.
#: ../js/ui/components/telepathyClient.js:1132
#: ../js/ui/components/telepathyClient.js:1133
#, c-format
msgid "Call from %s"
msgstr "Anruf von %s"
#. translators: this is a button label (verb), not a noun
#: ../js/ui/components/telepathyClient.js:1139
#: ../js/ui/components/telepathyClient.js:1140
msgid "Answer"
msgstr "Antworten"
@@ -908,113 +912,113 @@ msgstr "Antworten"
#. * file name. The string will be something
#. * like: "Alice is sending you test.ogg"
#.
#: ../js/ui/components/telepathyClient.js:1171
#: ../js/ui/components/telepathyClient.js:1172
#, c-format
msgid "%s is sending you %s"
msgstr "%s sendet Ihnen %s"
#. To translators: The parameter is the contact's alias
#: ../js/ui/components/telepathyClient.js:1206
#: ../js/ui/components/telepathyClient.js:1207
#, c-format
msgid "%s would like permission to see when you are online"
msgstr "%s bittet um das Recht, Ihre Online-Verfügbarkeit sehen zu dürfen"
#: ../js/ui/components/telepathyClient.js:1298
#: ../js/ui/components/telepathyClient.js:1299
msgid "Network error"
msgstr "Netzwerkfehler"
#: ../js/ui/components/telepathyClient.js:1300
#: ../js/ui/components/telepathyClient.js:1301
msgid "Authentication failed"
msgstr "Legitimierung fehlgeschlagen"
#: ../js/ui/components/telepathyClient.js:1302
#: ../js/ui/components/telepathyClient.js:1303
msgid "Encryption error"
msgstr "Verschlüsselungsfehler"
#: ../js/ui/components/telepathyClient.js:1304
#: ../js/ui/components/telepathyClient.js:1305
msgid "Certificate not provided"
msgstr "Zertifikat wurde nicht bereitgestellt"
#: ../js/ui/components/telepathyClient.js:1306
#: ../js/ui/components/telepathyClient.js:1307
msgid "Certificate untrusted"
msgstr "Zertifikat nicht vertrauenswürdig"
#: ../js/ui/components/telepathyClient.js:1308
#: ../js/ui/components/telepathyClient.js:1309
msgid "Certificate expired"
msgstr "Zertifikat abgelaufen"
#: ../js/ui/components/telepathyClient.js:1310
#: ../js/ui/components/telepathyClient.js:1311
msgid "Certificate not activated"
msgstr "Zertifikat nicht aktiviert"
#: ../js/ui/components/telepathyClient.js:1312
#: ../js/ui/components/telepathyClient.js:1313
msgid "Certificate hostname mismatch"
msgstr "Rechnername des Zertifikats stimmt nicht überein"
#: ../js/ui/components/telepathyClient.js:1314
#: ../js/ui/components/telepathyClient.js:1315
msgid "Certificate fingerprint mismatch"
msgstr "Fingerabdruck des Zertifikats stimmt nicht überein"
#: ../js/ui/components/telepathyClient.js:1316
#: ../js/ui/components/telepathyClient.js:1317
msgid "Certificate self-signed"
msgstr "Selbstsigniertes Zertifikat"
#: ../js/ui/components/telepathyClient.js:1318
#: ../js/ui/components/telepathyClient.js:1319
msgid "Status is set to offline"
msgstr "Der Status ist auf »Abgemeldet« gesetzt"
#: ../js/ui/components/telepathyClient.js:1320
#: ../js/ui/components/telepathyClient.js:1321
msgid "Encryption is not available"
msgstr "Verschlüsselung ist nicht verfügbar"
#: ../js/ui/components/telepathyClient.js:1322
#: ../js/ui/components/telepathyClient.js:1323
msgid "Certificate is invalid"
msgstr "Zertifikat ist ungültig"
#: ../js/ui/components/telepathyClient.js:1324
#: ../js/ui/components/telepathyClient.js:1325
msgid "Connection has been refused"
msgstr "Verbindungsaufbau wurde verweigert"
#: ../js/ui/components/telepathyClient.js:1326
#: ../js/ui/components/telepathyClient.js:1327
msgid "Connection can't be established"
msgstr "Verbindung kann nicht hergestellt werden"
#: ../js/ui/components/telepathyClient.js:1328
#: ../js/ui/components/telepathyClient.js:1329
msgid "Connection has been lost"
msgstr "Verbindung wurde unterbrochen"
#: ../js/ui/components/telepathyClient.js:1330
#: ../js/ui/components/telepathyClient.js:1331
msgid "This account is already connected to the server"
msgstr "Dieses Konto ist bereits mit dem Server verbunden"
#: ../js/ui/components/telepathyClient.js:1332
#: ../js/ui/components/telepathyClient.js:1333
msgid ""
"Connection has been replaced by a new connection using the same resource"
msgstr ""
"Die Verbindung wurde durch eine neue Verbindung mit der gleichen Ressource "
"ersetzt"
#: ../js/ui/components/telepathyClient.js:1334
#: ../js/ui/components/telepathyClient.js:1335
msgid "The account already exists on the server"
msgstr "Dieses Konto ist bereits auf dem Server vorhanden"
#: ../js/ui/components/telepathyClient.js:1336
#: ../js/ui/components/telepathyClient.js:1337
msgid "Server is currently too busy to handle the connection"
msgstr ""
"Der Server ist derzeit überlastet und kann die Verbindung nicht annehmen"
#: ../js/ui/components/telepathyClient.js:1338
#: ../js/ui/components/telepathyClient.js:1339
msgid "Certificate has been revoked"
msgstr "Zertifikat wurde zurückgezogen"
#: ../js/ui/components/telepathyClient.js:1340
#: ../js/ui/components/telepathyClient.js:1341
msgid ""
"Certificate uses an insecure cipher algorithm or is cryptographically weak"
msgstr ""
"Das Zertifikat verwendet einen unsicheren Chiffrier-Algorithmus oder ist "
"kryptografisch schwach"
#: ../js/ui/components/telepathyClient.js:1342
#: ../js/ui/components/telepathyClient.js:1343
msgid ""
"The length of the server certificate, or the depth of the server certificate "
"chain, exceed the limits imposed by the cryptography library"
@@ -1023,22 +1027,22 @@ msgstr ""
"überschreiten die durch die kryptografische Bibliothek gegebenen "
"Beschränkungen"
#: ../js/ui/components/telepathyClient.js:1344
#: ../js/ui/components/telepathyClient.js:1345
msgid "Internal error"
msgstr "Interner Fehler"
#. translators: argument is the account name, like
#. * name@jabber.org for example.
#: ../js/ui/components/telepathyClient.js:1354
#: ../js/ui/components/telepathyClient.js:1355
#, c-format
msgid "Unable to connect to %s"
msgstr "Verbindung zu %s fehlgeschlagen"
#: ../js/ui/components/telepathyClient.js:1359
#: ../js/ui/components/telepathyClient.js:1360
msgid "View account"
msgstr "Konto anzeigen"
#: ../js/ui/components/telepathyClient.js:1398
#: ../js/ui/components/telepathyClient.js:1399
msgid "Unknown reason"
msgstr "Unbekannter Grund"
@@ -1053,26 +1057,26 @@ msgstr "Anwendungen anzeigen"
# Würde ich so übernehmen, oder evtl. »Dock«.
#. Translators: this is the name of the dock/favorites area on
#. the left of the overview
#: ../js/ui/dash.js:429
#: ../js/ui/dash.js:439
msgid "Dash"
msgstr "Dash"
#: ../js/ui/dateMenu.js:86
#: ../js/ui/dateMenu.js:85
msgid "Open Calendar"
msgstr "Kalender öffnen"
#: ../js/ui/dateMenu.js:90
#: ../js/ui/dateMenu.js:89
msgid "Open Clocks"
msgstr "Uhren öffnen"
#: ../js/ui/dateMenu.js:97
#: ../js/ui/dateMenu.js:96
msgid "Date & Time Settings"
msgstr "Einstellungen für Datum und Uhrzeit"
#. 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:208
#: ../js/ui/dateMenu.js:201
msgid "%A %B %e, %Y"
msgstr "%A, %e. %B %Y"
@@ -1288,17 +1292,17 @@ msgstr "Übersicht"
msgid "Type to search…"
msgstr "Suchbegriff eingeben …"
#: ../js/ui/panel.js:642
#: ../js/ui/panel.js:567
msgid "Quit"
msgstr "Beenden"
#. Translators: If there is no suitable word for "Activities"
#. in your language, you can use the word for "Overview".
#: ../js/ui/panel.js:693
#: ../js/ui/panel.js:618
msgid "Activities"
msgstr "Aktivitäten"
#: ../js/ui/panel.js:989
#: ../js/ui/panel.js:914
msgid "Top Bar"
msgstr "Oberes Panel"
@@ -1307,7 +1311,7 @@ msgstr "Oberes Panel"
#. "ON" and "OFF") or "toggle-switch-intl" (for toggle
#. switches containing "◯" and "|"). Other values will
#. simply result in invisible toggle switches.
#: ../js/ui/popupMenu.js:738
#: ../js/ui/popupMenu.js:549
msgid "toggle-switch-us"
msgstr "toggle-switch-intl"
@@ -1335,7 +1339,7 @@ msgid_plural "%d new notifications"
msgstr[0] "%d neue Benachrichtigung"
msgstr[1] "%d neue Benachrichtigungen"
#: ../js/ui/screenShield.js:449 ../js/ui/userMenu.js:807
#: ../js/ui/screenShield.js:449 ../js/ui/userMenu.js:759
msgid "Lock"
msgstr "Sperren"
@@ -1350,11 +1354,11 @@ msgstr "GNOME muss den Bildschirm sperren"
#.
#. XXX: another option is to kick the user into the gdm login
#. screen, where we're not affected by grabs
#: ../js/ui/screenShield.js:773 ../js/ui/screenShield.js:1213
#: ../js/ui/screenShield.js:788 ../js/ui/screenShield.js:1215
msgid "Unable to lock"
msgstr "Sperrung fehlgeschlagen"
#: ../js/ui/screenShield.js:774 ../js/ui/screenShield.js:1214
#: ../js/ui/screenShield.js:789 ../js/ui/screenShield.js:1216
msgid "Lock was blocked by an application"
msgstr "Sperrung wurde von einer Anwendung blockiert"
@@ -1390,7 +1394,7 @@ msgstr "Passwort"
msgid "Remember Password"
msgstr "An Passwort erinnern"
#: ../js/ui/shellMountOperation.js:403 ../js/ui/unlockDialog.js:109
#: ../js/ui/shellMountOperation.js:403 ../js/ui/unlockDialog.js:108
msgid "Unlock"
msgstr "Entsperren"
@@ -1443,9 +1447,9 @@ msgid "Large Text"
msgstr "Große Schrift"
#: ../js/ui/status/bluetooth.js:28 ../js/ui/status/bluetooth.js:32
#: ../js/ui/status/bluetooth.js:289 ../js/ui/status/bluetooth.js:321
#: ../js/ui/status/bluetooth.js:357 ../js/ui/status/bluetooth.js:388
#: ../js/ui/status/network.js:739
#: ../js/ui/status/bluetooth.js:290 ../js/ui/status/bluetooth.js:327
#: ../js/ui/status/bluetooth.js:355 ../js/ui/status/bluetooth.js:391
#: ../js/ui/status/bluetooth.js:422 ../js/ui/status/network.js:713
msgid "Bluetooth"
msgstr "Bluetooth"
@@ -1466,73 +1470,82 @@ msgid "Bluetooth Settings"
msgstr "Bluetooth-Einstellungen"
#. TRANSLATORS: this means that bluetooth was disabled by hardware rfkill
#: ../js/ui/status/bluetooth.js:104 ../js/ui/status/network.js:142
#: ../js/ui/status/bluetooth.js:105 ../js/ui/status/network.js:140
msgid "hardware disabled"
msgstr "Hardware deaktiviert"
#: ../js/ui/status/bluetooth.js:197
#: ../js/ui/status/bluetooth.js:198
msgid "Connection"
msgstr "Verbindung"
#: ../js/ui/status/bluetooth.js:208 ../js/ui/status/network.js:404
#: ../js/ui/status/bluetooth.js:209 ../js/ui/status/network.js:399
msgid "disconnecting..."
msgstr "Verbindungsabbau …"
#: ../js/ui/status/bluetooth.js:221 ../js/ui/status/network.js:410
#: ../js/ui/status/network.js:1343
#: ../js/ui/status/bluetooth.js:222 ../js/ui/status/network.js:405
#: ../js/ui/status/network.js:1298
msgid "connecting..."
msgstr "Verbindungsaufbau …"
#: ../js/ui/status/bluetooth.js:239
#: ../js/ui/status/bluetooth.js:240
msgid "Send Files…"
msgstr "Dateien senden …"
#: ../js/ui/status/bluetooth.js:246
#: ../js/ui/status/bluetooth.js:247
msgid "Keyboard Settings"
msgstr "Tastatureinstellungen"
#: ../js/ui/status/bluetooth.js:249
#: ../js/ui/status/bluetooth.js:250
msgid "Mouse Settings"
msgstr "Maus-Einstellungen"
#: ../js/ui/status/bluetooth.js:254 ../js/ui/status/volume.js:316
#: ../js/ui/status/bluetooth.js:255 ../js/ui/status/volume.js:313
msgid "Sound Settings"
msgstr "Klangeinstellungen"
#: ../js/ui/status/bluetooth.js:322
#: ../js/ui/status/bluetooth.js:328 ../js/ui/status/bluetooth.js:356
#, c-format
msgid "Authorization request from %s"
msgstr "Legitimierungsanfrage von %s"
#: ../js/ui/status/bluetooth.js:328
#, c-format
msgid "Device %s wants access to the service '%s'"
msgstr "Gerät »%s« bittet um Zugriff auf den Dienst »%s«"
#: ../js/ui/status/bluetooth.js:330
msgid "Always grant access"
msgstr "Immer Zugriff gewähren"
#: ../js/ui/status/bluetooth.js:331
msgid "Grant this time only"
msgstr "Nur dieses Mal gewähren"
#: ../js/ui/status/bluetooth.js:332
msgid "Reject"
msgstr "Abweisen"
#. Translators: argument is the device short name
#: ../js/ui/status/bluetooth.js:359
#, c-format
msgid "Pairing confirmation for %s"
msgstr "Koppelungsbestätigung für %s"
#: ../js/ui/status/bluetooth.js:365 ../js/ui/status/bluetooth.js:396
#: ../js/ui/status/bluetooth.js:334 ../js/ui/status/bluetooth.js:399
#: ../js/ui/status/bluetooth.js:430
#, c-format
msgid "Device %s wants to pair with this computer"
msgstr "Gerät »%s« möchte mit diesem Rechner gekoppelt werden"
#: ../js/ui/status/bluetooth.js:336
msgid "Allow"
msgstr "Erlauben"
#: ../js/ui/status/bluetooth.js:337
msgid "Deny"
msgstr "Verweigern"
#: ../js/ui/status/bluetooth.js:362
#, c-format
msgid "Device %s wants access to the service '%s'"
msgstr "Gerät »%s« bittet um Zugriff auf den Dienst »%s«"
#: ../js/ui/status/bluetooth.js:364
msgid "Always grant access"
msgstr "Immer Zugriff gewähren"
#: ../js/ui/status/bluetooth.js:365
msgid "Grant this time only"
msgstr "Nur dieses Mal gewähren"
#: ../js/ui/status/bluetooth.js:366
msgid "Reject"
msgstr "Abweisen"
#. Translators: argument is the device short name
#: ../js/ui/status/bluetooth.js:393
#, c-format
msgid "Pairing confirmation for %s"
msgstr "Koppelungsbestätigung für %s"
#: ../js/ui/status/bluetooth.js:400
#, c-format
msgid ""
"Please confirm whether the Passkey '%06d' matches the one on the device."
@@ -1540,24 +1553,24 @@ msgstr ""
"Bitte bestätigen Sie, ob die PIN »%06d« mit der des Gerätes übereinstimmt."
#. Translators: this is the verb, not the noun
#: ../js/ui/status/bluetooth.js:369
#: ../js/ui/status/bluetooth.js:403
msgid "Matches"
msgstr "Stimmt überein"
#: ../js/ui/status/bluetooth.js:370
#: ../js/ui/status/bluetooth.js:404
msgid "Does not match"
msgstr "Stimmt nicht überein"
#: ../js/ui/status/bluetooth.js:389
#: ../js/ui/status/bluetooth.js:423
#, c-format
msgid "Pairing request for %s"
msgstr "Koppelungsanfrage für %s"
#: ../js/ui/status/bluetooth.js:397
#: ../js/ui/status/bluetooth.js:431
msgid "Please enter the PIN mentioned on the device."
msgstr "Bitte geben Sie die auf dem Gerät angezeigte PIN ein."
#: ../js/ui/status/bluetooth.js:414
#: ../js/ui/status/bluetooth.js:448
msgid "OK"
msgstr "OK"
@@ -1577,87 +1590,81 @@ msgstr "Lautstärke, Netzwerk, Batterie"
msgid "<unknown>"
msgstr "<Unbekannt>"
#: ../js/ui/status/network.js:127
#: ../js/ui/status/network.js:125
msgid "Wi-Fi"
msgstr "WLAN"
#. Translators: this indicates that wireless or wwan is disabled by hardware killswitch
#: ../js/ui/status/network.js:164
#: ../js/ui/status/network.js:162
msgid "disabled"
msgstr "Deaktiviert"
#. Translators: this is for network devices that are physically present but are not
#. under NetworkManager's control (and thus cannot be used in the menu)
#: ../js/ui/status/network.js:402
#: ../js/ui/status/network.js:397
msgid "unmanaged"
msgstr "nicht verwaltet"
#. Translators: this is for network connections that require some kind of key or password
#: ../js/ui/status/network.js:413 ../js/ui/status/network.js:1346
#: ../js/ui/status/network.js:408 ../js/ui/status/network.js:1301
msgid "authentication required"
msgstr "Legitimierung erforderlich"
#. Translators: this is for devices that require some kind of firmware or kernel
#. module, which is missing
#: ../js/ui/status/network.js:423
#: ../js/ui/status/network.js:419
msgid "firmware missing"
msgstr "Firmware fehlt"
#. Translators: this is for wired network devices that are physically disconnected
#: ../js/ui/status/network.js:430
msgid "cable unplugged"
msgstr "Kabel nicht angeschlossen"
#. Translators: this is for a network device that cannot be activated (for example it
#. is disabled by rfkill, or it has no coverage
#: ../js/ui/status/network.js:435
#: ../js/ui/status/network.js:423
msgid "unavailable"
msgstr "nicht verfügbar"
#: ../js/ui/status/network.js:437 ../js/ui/status/network.js:1348
#: ../js/ui/status/network.js:425 ../js/ui/status/network.js:1303
msgid "connection failed"
msgstr "Verbindung gescheitert"
#: ../js/ui/status/network.js:490 ../js/ui/status/network.js:1236
#: ../js/ui/status/network.js:1424
#: ../js/ui/status/network.js:478 ../js/ui/status/network.js:1190
msgid "More…"
msgstr "Mehr …"
#. TRANSLATORS: this is the indication that a connection for another logged in user is active,
#. and we cannot access its settings (including the name)
#: ../js/ui/status/network.js:518 ../js/ui/status/network.js:1191
#: ../js/ui/status/network.js:506 ../js/ui/status/network.js:1142
msgid "Connected (private)"
msgstr "Verbunden (privat)"
#: ../js/ui/status/network.js:597
#: ../js/ui/status/network.js:572
msgid "Wired"
msgstr "Kabelgebunden"
#: ../js/ui/status/network.js:611
#: ../js/ui/status/network.js:592
msgid "Mobile broadband"
msgstr "Mobiles Breitband"
#: ../js/ui/status/network.js:1522
#: ../js/ui/status/network.js:1474
msgid "Enable networking"
msgstr "Netzwerk aktivieren"
#: ../js/ui/status/network.js:1583
#: ../js/ui/status/network.js:1522
msgid "Network Settings"
msgstr "Netzwerkeinstellungen"
#: ../js/ui/status/network.js:1600
#: ../js/ui/status/network.js:1539
msgid "Network Manager"
msgstr "Netzwerk-Verwaltung"
#: ../js/ui/status/network.js:1690
#: ../js/ui/status/network.js:1623
msgid "Connection failed"
msgstr "Verbindung gescheitert"
#: ../js/ui/status/network.js:1691
#: ../js/ui/status/network.js:1624
msgid "Activation of network connection failed"
msgstr "Aktivierung der Netzwerkverbindung ist gescheitert"
#: ../js/ui/status/network.js:2047
#: ../js/ui/status/network.js:1938
msgid "Networking is disabled"
msgstr "Netzwerk ist deaktiviert"
@@ -1758,72 +1765,72 @@ msgctxt "device"
msgid "Unknown"
msgstr "Unbekannt"
#: ../js/ui/status/volume.js:124
#: ../js/ui/status/volume.js:121
msgid "Volume changed"
msgstr "Lautstärke geändert"
#. Translators: This is the label for audio volume
#: ../js/ui/status/volume.js:249 ../js/ui/status/volume.js:297
#: ../js/ui/status/volume.js:246 ../js/ui/status/volume.js:294
msgid "Volume"
msgstr "Lautstärke"
#: ../js/ui/status/volume.js:258
#: ../js/ui/status/volume.js:255
msgid "Microphone"
msgstr "Mikrofon"
#: ../js/ui/unlockDialog.js:120
#: ../js/ui/unlockDialog.js:119
msgid "Log in as another user"
msgstr "Als anderer Benutzer anmelden"
#: ../js/ui/unlockDialog.js:141
#: ../js/ui/unlockDialog.js:140
msgid "Unlock Window"
msgstr "Fenster entsperren"
#: ../js/ui/userMenu.js:193
#: ../js/ui/userMenu.js:149
msgid "Available"
msgstr "Verfügbar"
#: ../js/ui/userMenu.js:196
#: ../js/ui/userMenu.js:152
msgid "Busy"
msgstr "Beschäftigt"
#: ../js/ui/userMenu.js:199
#: ../js/ui/userMenu.js:155
msgid "Invisible"
msgstr "Unsichtbar"
#: ../js/ui/userMenu.js:202
#: ../js/ui/userMenu.js:158
msgid "Away"
msgstr "Abwesend"
#: ../js/ui/userMenu.js:205
#: ../js/ui/userMenu.js:161
msgid "Idle"
msgstr "Untätig"
#: ../js/ui/userMenu.js:208
#: ../js/ui/userMenu.js:164
msgid "Offline"
msgstr "Abgemeldet"
#: ../js/ui/userMenu.js:781
#: ../js/ui/userMenu.js:736
msgid "Notifications"
msgstr "Benachrichtigungen"
#: ../js/ui/userMenu.js:797
#: ../js/ui/userMenu.js:749
msgid "Switch User"
msgstr "Benutzer wechseln"
#: ../js/ui/userMenu.js:802
#: ../js/ui/userMenu.js:754
msgid "Log Out"
msgstr "Abmelden"
#: ../js/ui/userMenu.js:822
#: ../js/ui/userMenu.js:774
msgid "Install Updates & Restart"
msgstr "Aktualisierungen installieren und neustarten"
#: ../js/ui/userMenu.js:840
#: ../js/ui/userMenu.js:792
msgid "Your chat status will be set to busy"
msgstr "Ihr Anwesenheitsstatus wird auf »Beschäftigt« gesetzt"
#: ../js/ui/userMenu.js:841
#: ../js/ui/userMenu.js:793
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."
@@ -1832,22 +1839,22 @@ msgstr ""
"Ihr Anwesenheitsstatus wurde nun dahingehend geändert, dass andere darüber "
"informiert werden, dass Sie deren Nachrichten nicht sehen könnten."
#: ../js/ui/userMenu.js:888
#: ../js/ui/userMenu.js:834
msgid "Other users are logged in."
msgstr "Andere Benutzer sind angemeldet."
#: ../js/ui/userMenu.js:893
#: ../js/ui/userMenu.js:839
msgid "Shutting down might cause them to lose unsaved work."
msgstr "Herunterfahren könnte Datenverlust herbeiführen."
#. Translators: Remote here refers to a remote session, like a ssh login
#: ../js/ui/userMenu.js:921
#: ../js/ui/userMenu.js:867
#, c-format
msgid "%s (remote)"
msgstr "%s (Entfernt)"
#. Translators: Console here refers to a tty like a VT console
#: ../js/ui/userMenu.js:924
#: ../js/ui/userMenu.js:870
#, c-format
msgid "%s (console)"
msgstr "%s (Konsole)"
@@ -1905,20 +1912,20 @@ msgstr[1] "%u Eingänge"
msgid "System Sounds"
msgstr "Systemklänge"
#: ../src/main.c:372
#: ../src/main.c:353
msgid "Print version"
msgstr "Version ausgeben"
#: ../src/main.c:378
#: ../src/main.c:359
msgid "Mode used by GDM for login screen"
msgstr "Der durch GDM im Anmeldefenster verwendete Modus"
#: ../src/main.c:384
#: ../src/main.c:365
msgid "Use a specific mode, e.g. \"gdm\" for login screen"
msgstr ""
"Einen spezifischen Modus nutzen, wie z.B. »gdm« für den Anmeldebildschirm"
#: ../src/main.c:390
#: ../src/main.c:371
msgid "List possible modes"
msgstr "Die möglichen Modi auflisten"
@@ -1939,6 +1946,9 @@ msgstr "Das Passwort darf nicht leer sein"
msgid "Authentication dialog was dismissed by the user"
msgstr "Der Dialog zur Legitimierung wurde vom Benutzer geschlossen"
#~ msgid "cable unplugged"
#~ msgstr "Kabel nicht angeschlossen"
#~ msgid "Whether to collect stats about applications usage"
#~ msgstr ""
#~ "Legt fest, ob Statistiken über Anwendungsnutzung erfasst werden sollen"

616
po/id.po

File diff suppressed because it is too large Load Diff

599
po/ja.po

File diff suppressed because it is too large Load Diff

132
po/nb.po
View File

@@ -8,8 +8,8 @@ msgid ""
msgstr ""
"Project-Id-Version: gnome-shell 3.9.x\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-06-17 12:28+0200\n"
"PO-Revision-Date: 2013-06-17 12:29+0200\n"
"POT-Creation-Date: 2013-07-04 11:09+0200\n"
"PO-Revision-Date: 2013-07-04 11:09+0200\n"
"Last-Translator: Kjartan Maraas <kmaraas@gnome.org>\n"
"Language-Team: Norwegian bokmål <i18n-nb@lister.ping.uio.no>\n"
"Language: \n"
@@ -331,18 +331,22 @@ msgstr "Utvidelse"
msgid "Select an extension to configure using the combobox above."
msgstr "Velg en utvidelse som skal konfigureres med komboboksen over."
#: ../js/gdm/loginDialog.js:370
msgid "Session"
msgstr "Økt …"
#: ../js/gdm/loginDialog.js:308
msgid "Choose Session"
msgstr "Velg økt"
#: ../js/gdm/loginDialog.js:326
msgid "Session"
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:600
#: ../js/gdm/loginDialog.js:528
msgid "Not listed?"
msgstr "Ikke listet?"
#: ../js/gdm/loginDialog.js:775 ../js/ui/components/networkAgent.js:137
#: ../js/gdm/loginDialog.js:810 ../js/ui/components/networkAgent.js:137
#: ../js/ui/components/polkitAgent.js:161 ../js/ui/endSessionDialog.js:376
#: ../js/ui/extensionDownloader.js:195 ../js/ui/shellMountOperation.js:399
#: ../js/ui/status/bluetooth.js:449 ../js/ui/unlockDialog.js:95
@@ -350,18 +354,18 @@ msgstr "Ikke listet?"
msgid "Cancel"
msgstr "Avbryt"
#: ../js/gdm/loginDialog.js:790
#: ../js/gdm/loginDialog.js:833
msgctxt "button"
msgid "Sign In"
msgstr "Logg inn"
#: ../js/gdm/loginDialog.js:790
#: ../js/gdm/loginDialog.js:833
msgid "Next"
msgstr "Neste"
#. Translators: this message is shown below the username entry field
#. to clue the user in on how to login to the local network realm
#: ../js/gdm/loginDialog.js:887
#: ../js/gdm/loginDialog.js:934
#, c-format
msgid "(e.g., user or %s)"
msgstr "(f.eks. bruker eller %s)"
@@ -369,12 +373,12 @@ msgstr "(f.eks. bruker eller %s)"
#. TTLS and PEAP are actually much more complicated, but this complication
#. is not visible here since we only care about phase2 authentication
#. (and don't even care of which one)
#: ../js/gdm/loginDialog.js:891 ../js/ui/components/networkAgent.js:260
#: ../js/gdm/loginDialog.js:938 ../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:1205
msgid "Login Window"
msgstr "Innloggingsvindu"
@@ -397,13 +401,13 @@ msgstr "Start på nytt"
msgid "Power Off"
msgstr "Slå av"
#: ../js/gdm/util.js:247
#: ../js/gdm/util.js:248
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:364
#: ../js/gdm/util.js:365
msgid "(or swipe finger)"
msgstr "(eller dra finger)"
@@ -794,14 +798,14 @@ 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:985
#: ../js/ui/components/telepathyClient.js:986
#, c-format
msgid "%s is now known as %s"
msgstr "%s er nå kjent som %s"
#. translators: argument is a room name like
#. * room@jabber.org for example.
#: ../js/ui/components/telepathyClient.js:1088
#: ../js/ui/components/telepathyClient.js:1089
#, c-format
msgid "Invitation to %s"
msgstr "Invitasjon til %s"
@@ -809,38 +813,38 @@ msgstr "Invitasjon til %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:1096
#: ../js/ui/components/telepathyClient.js:1097
#, c-format
msgid "%s is inviting you to join %s"
msgstr "%s inviterer deg til å bli med i %s"
#: ../js/ui/components/telepathyClient.js:1098
#: ../js/ui/components/telepathyClient.js:1137
#: ../js/ui/components/telepathyClient.js:1177
#: ../js/ui/components/telepathyClient.js:1240
#: ../js/ui/components/telepathyClient.js:1099
#: ../js/ui/components/telepathyClient.js:1138
#: ../js/ui/components/telepathyClient.js:1178
#: ../js/ui/components/telepathyClient.js:1241
msgid "Decline"
msgstr "Avslå"
#: ../js/ui/components/telepathyClient.js:1099
#: ../js/ui/components/telepathyClient.js:1178
#: ../js/ui/components/telepathyClient.js:1241
#: ../js/ui/components/telepathyClient.js:1100
#: ../js/ui/components/telepathyClient.js:1179
#: ../js/ui/components/telepathyClient.js:1242
msgid "Accept"
msgstr "Godta"
#. translators: argument is a contact name like Alice for example.
#: ../js/ui/components/telepathyClient.js:1129
#: ../js/ui/components/telepathyClient.js:1130
#, c-format
msgid "Video call from %s"
msgstr "Videosamtale fra %s"
#. translators: argument is a contact name like Alice for example.
#: ../js/ui/components/telepathyClient.js:1132
#: ../js/ui/components/telepathyClient.js:1133
#, c-format
msgid "Call from %s"
msgstr "Samtale fra %s"
#. translators: this is a button label (verb), not a noun
#: ../js/ui/components/telepathyClient.js:1139
#: ../js/ui/components/telepathyClient.js:1140
msgid "Answer"
msgstr "Svar"
@@ -849,110 +853,110 @@ msgstr "Svar"
#. * file name. The string will be something
#. * like: "Alice is sending you test.ogg"
#.
#: ../js/ui/components/telepathyClient.js:1171
#: ../js/ui/components/telepathyClient.js:1172
#, c-format
msgid "%s is sending you %s"
msgstr "%s sender deg %s"
#. To translators: The parameter is the contact's alias
#: ../js/ui/components/telepathyClient.js:1206
#: ../js/ui/components/telepathyClient.js:1207
#, c-format
msgid "%s would like permission to see when you are online"
msgstr "%s vil ha rettigheter til å se når du er tilkoblet"
#: ../js/ui/components/telepathyClient.js:1298
#: ../js/ui/components/telepathyClient.js:1299
msgid "Network error"
msgstr "Nettverksfeil"
#: ../js/ui/components/telepathyClient.js:1300
#: ../js/ui/components/telepathyClient.js:1301
msgid "Authentication failed"
msgstr "Autentisering feilet"
#: ../js/ui/components/telepathyClient.js:1302
#: ../js/ui/components/telepathyClient.js:1303
msgid "Encryption error"
msgstr "Feil ved kryptering"
#: ../js/ui/components/telepathyClient.js:1304
#: ../js/ui/components/telepathyClient.js:1305
msgid "Certificate not provided"
msgstr "Sertifikat ikke oppgitt"
#: ../js/ui/components/telepathyClient.js:1306
#: ../js/ui/components/telepathyClient.js:1307
msgid "Certificate untrusted"
msgstr "Stoler ikke på sertifikatet"
#: ../js/ui/components/telepathyClient.js:1308
#: ../js/ui/components/telepathyClient.js:1309
msgid "Certificate expired"
msgstr "Sertifikatet er utløpt"
#: ../js/ui/components/telepathyClient.js:1310
#: ../js/ui/components/telepathyClient.js:1311
msgid "Certificate not activated"
msgstr "Sertifikatet er ikke aktivert"
#: ../js/ui/components/telepathyClient.js:1312
#: ../js/ui/components/telepathyClient.js:1313
msgid "Certificate hostname mismatch"
msgstr "Feil vertsnavn for sertifikat"
#: ../js/ui/components/telepathyClient.js:1314
#: ../js/ui/components/telepathyClient.js:1315
msgid "Certificate fingerprint mismatch"
msgstr "Feil fingeravtrykk for sertifikat"
#: ../js/ui/components/telepathyClient.js:1316
#: ../js/ui/components/telepathyClient.js:1317
msgid "Certificate self-signed"
msgstr "Sertifikatet er selvsignert"
#: ../js/ui/components/telepathyClient.js:1318
#: ../js/ui/components/telepathyClient.js:1319
msgid "Status is set to offline"
msgstr "Status er satt til frakoblet"
#: ../js/ui/components/telepathyClient.js:1320
#: ../js/ui/components/telepathyClient.js:1321
msgid "Encryption is not available"
msgstr "Kryptering er ikke tilgjengelig"
#: ../js/ui/components/telepathyClient.js:1322
#: ../js/ui/components/telepathyClient.js:1323
msgid "Certificate is invalid"
msgstr "Sertifikatet er ugyldig"
#: ../js/ui/components/telepathyClient.js:1324
#: ../js/ui/components/telepathyClient.js:1325
msgid "Connection has been refused"
msgstr "Tilkobling ble nektet"
#: ../js/ui/components/telepathyClient.js:1326
#: ../js/ui/components/telepathyClient.js:1327
msgid "Connection can't be established"
msgstr "Tilkobling kan ikke etableres"
#: ../js/ui/components/telepathyClient.js:1328
#: ../js/ui/components/telepathyClient.js:1329
msgid "Connection has been lost"
msgstr "Tilkobling tapt"
#: ../js/ui/components/telepathyClient.js:1330
#: ../js/ui/components/telepathyClient.js:1331
msgid "This account is already connected to the server"
msgstr "Denne kontoen er allerede koblet til tjeneren"
#: ../js/ui/components/telepathyClient.js:1332
#: ../js/ui/components/telepathyClient.js:1333
msgid ""
"Connection has been replaced by a new connection using the same resource"
msgstr ""
"Tilkoblingen har blitt erstattet av en ny tilkobling som bruker samme ressurs"
#: ../js/ui/components/telepathyClient.js:1334
#: ../js/ui/components/telepathyClient.js:1335
msgid "The account already exists on the server"
msgstr "Kontoen eksisterer allerede på tjeneren"
#: ../js/ui/components/telepathyClient.js:1336
#: ../js/ui/components/telepathyClient.js:1337
msgid "Server is currently too busy to handle the connection"
msgstr "Tjener er for opptatt til å håndtere tilkoblingen"
#: ../js/ui/components/telepathyClient.js:1338
#: ../js/ui/components/telepathyClient.js:1339
msgid "Certificate has been revoked"
msgstr "Sertifikatet er tilbaketrukket"
#: ../js/ui/components/telepathyClient.js:1340
#: ../js/ui/components/telepathyClient.js:1341
msgid ""
"Certificate uses an insecure cipher algorithm or is cryptographically weak"
msgstr ""
"Sertifikatet bruker en usikker sifferalgoritme eller er krytografisk svakt"
#: ../js/ui/components/telepathyClient.js:1342
#: ../js/ui/components/telepathyClient.js:1343
msgid ""
"The length of the server certificate, or the depth of the server certificate "
"chain, exceed the limits imposed by the cryptography library"
@@ -960,22 +964,22 @@ msgstr ""
"Lengden eller dybden på tjenersertifikatet oversteg grensen som er satt i "
"kryptografibiblioteket"
#: ../js/ui/components/telepathyClient.js:1344
#: ../js/ui/components/telepathyClient.js:1345
msgid "Internal error"
msgstr "Intern feil"
#. translators: argument is the account name, like
#. * name@jabber.org for example.
#: ../js/ui/components/telepathyClient.js:1354
#: ../js/ui/components/telepathyClient.js:1355
#, c-format
msgid "Unable to connect to %s"
msgstr "Kan ikke koble til %s"
#: ../js/ui/components/telepathyClient.js:1359
#: ../js/ui/components/telepathyClient.js:1360
msgid "View account"
msgstr "Vis konto"
#: ../js/ui/components/telepathyClient.js:1398
#: ../js/ui/components/telepathyClient.js:1399
msgid "Unknown reason"
msgstr "Ukjent årsak"
@@ -1008,7 +1012,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:202
#: ../js/ui/dateMenu.js:201
msgid "%A %B %e, %Y"
msgstr "%a %e %B, %Y"
@@ -1222,17 +1226,17 @@ msgstr "Oversikt"
msgid "Type to search…"
msgstr "Skriv for å søke …"
#: ../js/ui/panel.js:642
#: ../js/ui/panel.js:567
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:693
#: ../js/ui/panel.js:618
msgid "Activities"
msgstr "Aktiviteter"
#: ../js/ui/panel.js:989
#: ../js/ui/panel.js:914
msgid "Top Bar"
msgstr "Topp-panel"
@@ -1241,7 +1245,7 @@ msgstr "Topp-panel"
#. "ON" and "OFF") or "toggle-switch-intl" (for toggle
#. switches containing "◯" and "|"). Other values will
#. simply result in invisible toggle switches.
#: ../js/ui/popupMenu.js:545
#: ../js/ui/popupMenu.js:549
msgid "toggle-switch-us"
msgstr "toggle-switch-intl"
@@ -1281,11 +1285,11 @@ 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:773 ../js/ui/screenShield.js:1213
#: ../js/ui/screenShield.js:775 ../js/ui/screenShield.js:1215
msgid "Unable to lock"
msgstr "Kan ikke låse"
#: ../js/ui/screenShield.js:774 ../js/ui/screenShield.js:1214
#: ../js/ui/screenShield.js:776 ../js/ui/screenShield.js:1216
msgid "Lock was blocked by an application"
msgstr "Låsing ble stoppet av et program"
@@ -1590,7 +1594,7 @@ msgstr "Tilkobling feilet"
msgid "Activation of network connection failed"
msgstr "Aktivering av nettverkstilkobling feilet"
#: ../js/ui/status/network.js:1937
#: ../js/ui/status/network.js:1938
msgid "Networking is disabled"
msgstr "Nettverk er slått av"

395
po/sk.po
View File

@@ -10,8 +10,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-05-24 21:21+0000\n"
"PO-Revision-Date: 2013-05-24 23:24+0100\n"
"POT-Creation-Date: 2013-07-13 07:31+0000\n"
"PO-Revision-Date: 2013-07-13 20:32+0200\n"
"Last-Translator: Dušan Kazik <prescott66@gmail.com>\n"
"Language-Team: Slovak <gnome-sk-list@gnome.org>\n"
"Language: sk\n"
@@ -384,38 +384,43 @@ msgstr "Rozšírenie"
msgid "Select an extension to configure using the combobox above."
msgstr "Použitím ponuky vyberte rozšírenie na nastavenie"
#: ../js/gdm/loginDialog.js:371
msgid "Session…"
msgstr "Relácia…"
# button
#: ../js/gdm/loginDialog.js:308
msgid "Choose Session"
msgstr "Vybrať reláciu"
#: ../js/gdm/loginDialog.js:326
msgid "Session"
msgstr "Relácia"
# https://bugzilla.gnome.org/show_bug.cgi?id=659972
#. 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:601
#: ../js/gdm/loginDialog.js:533
msgid "Not listed?"
msgstr "Nie ste v zozname?"
#: ../js/gdm/loginDialog.js:776 ../js/ui/components/networkAgent.js:137
#: ../js/gdm/loginDialog.js:810 ../js/ui/components/networkAgent.js:137
#: ../js/ui/components/polkitAgent.js:161 ../js/ui/endSessionDialog.js:376
#: ../js/ui/extensionDownloader.js:195 ../js/ui/shellMountOperation.js:399
#: ../js/ui/status/bluetooth.js:415 ../js/ui/unlockDialog.js:96
#: ../js/ui/userMenu.js:938
#: ../js/ui/status/bluetooth.js:449 ../js/ui/unlockDialog.js:95
#: ../js/ui/userMenu.js:884
msgid "Cancel"
msgstr "Zrušiť"
#: ../js/gdm/loginDialog.js:791
#: ../js/gdm/loginDialog.js:833
msgctxt "button"
msgid "Sign In"
msgstr "Prihlásiť sa"
#: ../js/gdm/loginDialog.js:791
#: ../js/gdm/loginDialog.js:833
msgid "Next"
msgstr "Ďalej"
#. Translators: this message is shown below the username entry field
#. to clue the user in on how to login to the local network realm
#: ../js/gdm/loginDialog.js:888
#: ../js/gdm/loginDialog.js:934
#, c-format
msgid "(e.g., user or %s)"
msgstr "(napr., používateľ alebo %s)"
@@ -423,12 +428,12 @@ msgstr "(napr., používateľ alebo %s)"
#. TTLS and PEAP are actually much more complicated, but this complication
#. is not visible here since we only care about phase2 authentication
#. (and don't even care of which one)
#: ../js/gdm/loginDialog.js:892 ../js/ui/components/networkAgent.js:260
#: ../js/gdm/loginDialog.js:938 ../js/ui/components/networkAgent.js:260
#: ../js/ui/components/networkAgent.js:278
msgid "Username: "
msgstr "Používateľské meno: "
#: ../js/gdm/loginDialog.js:1158
#: ../js/gdm/loginDialog.js:1205
msgid "Login Window"
msgstr "Prihlasovacie okno"
@@ -437,8 +442,8 @@ msgstr "Prihlasovacie okno"
msgid "Power"
msgstr "Napájanie"
#: ../js/gdm/powerMenu.js:93 ../js/ui/userMenu.js:696 ../js/ui/userMenu.js:700
#: ../js/ui/userMenu.js:816
#: ../js/gdm/powerMenu.js:93 ../js/ui/userMenu.js:651 ../js/ui/userMenu.js:655
#: ../js/ui/userMenu.js:768
msgid "Suspend"
msgstr "Uspať"
@@ -446,18 +451,18 @@ msgstr "Uspať"
msgid "Restart"
msgstr "Reštartovať"
#: ../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
#: ../js/gdm/powerMenu.js:103 ../js/ui/userMenu.js:653
#: ../js/ui/userMenu.js:655 ../js/ui/userMenu.js:767 ../js/ui/userMenu.js:888
msgid "Power Off"
msgstr "Vypnúť"
#: ../js/gdm/util.js:247
#: ../js/gdm/util.js:248
msgid "Authentication error"
msgstr "Chyba pri overovaní totožnosti"
#. Translators: this message is shown below the password entry field
#. to indicate the user can swipe their finger instead
#: ../js/gdm/util.js:364
#: ../js/gdm/util.js:365
msgid "(or swipe finger)"
msgstr "(alebo prejdite prstom)"
@@ -476,23 +481,23 @@ msgstr "Nepodarilo sa analyzovať príkaz:"
msgid "Execution of '%s' failed:"
msgstr "Spustenie „%s“ zlyhalo:"
#: ../js/ui/appDisplay.js:361
#: ../js/ui/appDisplay.js:397
msgid "Frequent"
msgstr "Často používané"
#: ../js/ui/appDisplay.js:368
#: ../js/ui/appDisplay.js:404
msgid "All"
msgstr "Všetky"
#: ../js/ui/appDisplay.js:960
#: ../js/ui/appDisplay.js:996
msgid "New Window"
msgstr "Nové okno"
#: ../js/ui/appDisplay.js:963 ../js/ui/dash.js:284
#: ../js/ui/appDisplay.js:999 ../js/ui/dash.js:284
msgid "Remove from Favorites"
msgstr "Odstrániť z obľúbených"
#: ../js/ui/appDisplay.js:964
#: ../js/ui/appDisplay.js:1000
msgid "Add to Favorites"
msgstr "Pridať do obľúbených"
@@ -506,7 +511,7 @@ msgstr "Program %s bol pridaný medzi obľúbené."
msgid "%s has been removed from your favorites."
msgstr "Program %s bol odstránený z obľúbených."
#: ../js/ui/backgroundMenu.js:19 ../js/ui/userMenu.js:789
#: ../js/ui/backgroundMenu.js:19 ../js/ui/userMenu.js:744
msgid "Settings"
msgstr "Nastavenia"
@@ -631,35 +636,35 @@ msgid "S"
msgstr "So"
#. Translators: Text to show if there are no events
#: ../js/ui/calendar.js:735
#: ../js/ui/calendar.js:750
msgid "Nothing Scheduled"
msgstr "Žiadne naplánované udalosti"
#. Translators: Shown on calendar heading when selected day occurs on current year
#: ../js/ui/calendar.js:751
#: ../js/ui/calendar.js:768
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:754
#: ../js/ui/calendar.js:771
msgctxt "calendar heading"
msgid "%A, %B %d, %Y"
msgstr "%A, %e. %B %Y"
#: ../js/ui/calendar.js:764
#: ../js/ui/calendar.js:782
msgid "Today"
msgstr "Dnes"
#: ../js/ui/calendar.js:768
#: ../js/ui/calendar.js:786
msgid "Tomorrow"
msgstr "Zajtra"
#: ../js/ui/calendar.js:779
#: ../js/ui/calendar.js:797
msgid "This week"
msgstr "Tento týždeň"
#: ../js/ui/calendar.js:787
#: ../js/ui/calendar.js:805
msgid "Next week"
msgstr "Ďalší týždeň"
@@ -851,14 +856,14 @@ msgstr "<b>%e.</b> <b>%B</b> <b>%Y</b> o <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:985
#: ../js/ui/components/telepathyClient.js:986
#, c-format
msgid "%s is now known as %s"
msgstr "Kontakt %s odteraz vystupuje ako %s"
#. translators: argument is a room name like
#. * room@jabber.org for example.
#: ../js/ui/components/telepathyClient.js:1088
#: ../js/ui/components/telepathyClient.js:1089
#, c-format
msgid "Invitation to %s"
msgstr "Pozvánka do %s"
@@ -866,38 +871,38 @@ msgstr "Pozvánka do %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:1096
#: ../js/ui/components/telepathyClient.js:1097
#, c-format
msgid "%s is inviting you to join %s"
msgstr "Kontakt %s vás pozýva aby ste sa pridali do %s"
#: ../js/ui/components/telepathyClient.js:1098
#: ../js/ui/components/telepathyClient.js:1137
#: ../js/ui/components/telepathyClient.js:1177
#: ../js/ui/components/telepathyClient.js:1240
#: ../js/ui/components/telepathyClient.js:1099
#: ../js/ui/components/telepathyClient.js:1138
#: ../js/ui/components/telepathyClient.js:1178
#: ../js/ui/components/telepathyClient.js:1241
msgid "Decline"
msgstr "Odmietnuť"
#: ../js/ui/components/telepathyClient.js:1099
#: ../js/ui/components/telepathyClient.js:1178
#: ../js/ui/components/telepathyClient.js:1241
#: ../js/ui/components/telepathyClient.js:1100
#: ../js/ui/components/telepathyClient.js:1179
#: ../js/ui/components/telepathyClient.js:1242
msgid "Accept"
msgstr "Prijať"
#. translators: argument is a contact name like Alice for example.
#: ../js/ui/components/telepathyClient.js:1129
#: ../js/ui/components/telepathyClient.js:1130
#, c-format
msgid "Video call from %s"
msgstr "Videohovor od kontaktu %s"
#. translators: argument is a contact name like Alice for example.
#: ../js/ui/components/telepathyClient.js:1132
#: ../js/ui/components/telepathyClient.js:1133
#, c-format
msgid "Call from %s"
msgstr "Hovor od kontaktu %s"
#. translators: this is a button label (verb), not a noun
#: ../js/ui/components/telepathyClient.js:1139
#: ../js/ui/components/telepathyClient.js:1140
msgid "Answer"
msgstr "Prijať hovor"
@@ -906,110 +911,110 @@ msgstr "Prijať hovor"
#. * file name. The string will be something
#. * like: "Alice is sending you test.ogg"
#.
#: ../js/ui/components/telepathyClient.js:1171
#: ../js/ui/components/telepathyClient.js:1172
#, c-format
msgid "%s is sending you %s"
msgstr "Kontakt %s vám posiela %s"
#. To translators: The parameter is the contact's alias
#: ../js/ui/components/telepathyClient.js:1206
#: ../js/ui/components/telepathyClient.js:1207
#, c-format
msgid "%s would like permission to see when you are online"
msgstr "Kontakt %s by chcel získať oprávnenie vidieť, kedy ste pripojený"
#: ../js/ui/components/telepathyClient.js:1298
#: ../js/ui/components/telepathyClient.js:1299
msgid "Network error"
msgstr "Chyba siete"
#: ../js/ui/components/telepathyClient.js:1300
#: ../js/ui/components/telepathyClient.js:1301
msgid "Authentication failed"
msgstr "Overenie totožnosti zlyhalo"
#: ../js/ui/components/telepathyClient.js:1302
#: ../js/ui/components/telepathyClient.js:1303
msgid "Encryption error"
msgstr "Chyba šifrovania"
#: ../js/ui/components/telepathyClient.js:1304
#: ../js/ui/components/telepathyClient.js:1305
msgid "Certificate not provided"
msgstr "Neposkytnutý certifikát"
#: ../js/ui/components/telepathyClient.js:1306
#: ../js/ui/components/telepathyClient.js:1307
msgid "Certificate untrusted"
msgstr "Nedôveryhodný certifikát"
#: ../js/ui/components/telepathyClient.js:1308
#: ../js/ui/components/telepathyClient.js:1309
msgid "Certificate expired"
msgstr "Certifikát s ukončenou platnosťou"
#: ../js/ui/components/telepathyClient.js:1310
#: ../js/ui/components/telepathyClient.js:1311
msgid "Certificate not activated"
msgstr "Neaktivovaný certifikát"
#: ../js/ui/components/telepathyClient.js:1312
#: ../js/ui/components/telepathyClient.js:1313
msgid "Certificate hostname mismatch"
msgstr "Certifikát s nesúhlasným názvom hostiteľa"
#: ../js/ui/components/telepathyClient.js:1314
#: ../js/ui/components/telepathyClient.js:1315
msgid "Certificate fingerprint mismatch"
msgstr "Certifikát s nesúhlasným odtlačkom"
#: ../js/ui/components/telepathyClient.js:1316
#: ../js/ui/components/telepathyClient.js:1317
msgid "Certificate self-signed"
msgstr "Sebou podpísaný certifikát"
#: ../js/ui/components/telepathyClient.js:1318
#: ../js/ui/components/telepathyClient.js:1319
msgid "Status is set to offline"
msgstr "Stav je nastavený na odhlásený"
#: ../js/ui/components/telepathyClient.js:1320
#: ../js/ui/components/telepathyClient.js:1321
msgid "Encryption is not available"
msgstr "Šifrovanie nie je dostupné"
#: ../js/ui/components/telepathyClient.js:1322
#: ../js/ui/components/telepathyClient.js:1323
msgid "Certificate is invalid"
msgstr "Certifikát je neplatný"
#: ../js/ui/components/telepathyClient.js:1324
#: ../js/ui/components/telepathyClient.js:1325
msgid "Connection has been refused"
msgstr "Pripojenie bolo odmietnuté"
#: ../js/ui/components/telepathyClient.js:1326
#: ../js/ui/components/telepathyClient.js:1327
msgid "Connection can't be established"
msgstr "Nedá sa nadviazať spojenie"
#: ../js/ui/components/telepathyClient.js:1328
#: ../js/ui/components/telepathyClient.js:1329
msgid "Connection has been lost"
msgstr "Spojenie sa stratilo"
#: ../js/ui/components/telepathyClient.js:1330
#: ../js/ui/components/telepathyClient.js:1331
msgid "This account is already connected to the server"
msgstr "Tento účet je už pripojený k serveru"
#: ../js/ui/components/telepathyClient.js:1332
#: ../js/ui/components/telepathyClient.js:1333
msgid ""
"Connection has been replaced by a new connection using the same resource"
msgstr "Pripojenie bolo nahradené novým, ktoré používa rovnaký zdroj"
#: ../js/ui/components/telepathyClient.js:1334
#: ../js/ui/components/telepathyClient.js:1335
msgid "The account already exists on the server"
msgstr "Účet na serveri už existuje"
#: ../js/ui/components/telepathyClient.js:1336
#: ../js/ui/components/telepathyClient.js:1337
msgid "Server is currently too busy to handle the connection"
msgstr "Server je momentálne príliš zaneprázdnený na zvládnutie pripojenia"
#: ../js/ui/components/telepathyClient.js:1338
#: ../js/ui/components/telepathyClient.js:1339
msgid "Certificate has been revoked"
msgstr "Certifikát bol zrušený"
#: ../js/ui/components/telepathyClient.js:1340
#: ../js/ui/components/telepathyClient.js:1341
msgid ""
"Certificate uses an insecure cipher algorithm or is cryptographically weak"
msgstr ""
"Šifrovací algoritmus používaný certifikátom nie je bezpečný alebo je "
"kryptograficky slabý"
#: ../js/ui/components/telepathyClient.js:1342
#: ../js/ui/components/telepathyClient.js:1343
msgid ""
"The length of the server certificate, or the depth of the server certificate "
"chain, exceed the limits imposed by the cryptography library"
@@ -1017,22 +1022,22 @@ msgstr ""
"Dĺžka certifikátu servera, alebo hĺbka reťazca certifikátu servera presahuje "
"limit stanovený kryptografickou knižnicou."
#: ../js/ui/components/telepathyClient.js:1344
#: ../js/ui/components/telepathyClient.js:1345
msgid "Internal error"
msgstr "Vnútorná chyba"
#. translators: argument is the account name, like
#. * name@jabber.org for example.
#: ../js/ui/components/telepathyClient.js:1354
#: ../js/ui/components/telepathyClient.js:1355
#, c-format
msgid "Unable to connect to %s"
msgstr "Nepodarilo sa pripojiť účet %s"
#: ../js/ui/components/telepathyClient.js:1359
#: ../js/ui/components/telepathyClient.js:1360
msgid "View account"
msgstr "Zobraziť účet"
#: ../js/ui/components/telepathyClient.js:1398
#: ../js/ui/components/telepathyClient.js:1399
msgid "Unknown reason"
msgstr "Neznámy dôvod"
@@ -1047,26 +1052,26 @@ msgstr "Zobrazí aplikácie"
#. Translators: this is the name of the dock/favorites area on
#. the left of the overview
#: ../js/ui/dash.js:435
#: ../js/ui/dash.js:439
msgid "Dash"
msgstr "Dok"
#: ../js/ui/dateMenu.js:86
#: ../js/ui/dateMenu.js:85
msgid "Open Calendar"
msgstr "Otvoriť kalendár"
#: ../js/ui/dateMenu.js:90
#: ../js/ui/dateMenu.js:89
msgid "Open Clocks"
msgstr "Otvoriť hodiny"
#: ../js/ui/dateMenu.js:97
#: ../js/ui/dateMenu.js:96
msgid "Date & Time Settings"
msgstr "Nastavenia dátumu a času"
#. 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:208
#: ../js/ui/dateMenu.js:201
msgid "%A %B %e, %Y"
msgstr "%A, %e. %B %Y"
@@ -1175,7 +1180,7 @@ msgstr "Inštalovať"
msgid "Download and install '%s' from extensions.gnome.org?"
msgstr "Stiahnuť a nainštalovať „%s“ z extensions.gnome.org?"
#: ../js/ui/keyboard.js:619 ../js/ui/status/keyboard.js:314
#: ../js/ui/keyboard.js:619 ../js/ui/status/keyboard.js:333
#: ../js/ui/status/power.js:211
msgid "Keyboard"
msgstr "Klávesnica"
@@ -1229,33 +1234,33 @@ msgstr "Zobraziť zdroj"
msgid "Web Page"
msgstr "Webová stránka"
#: ../js/ui/messageTray.js:1182
#: ../js/ui/messageTray.js:1241
msgid "Open"
msgstr "Otvoriť"
#: ../js/ui/messageTray.js:1189
#: ../js/ui/messageTray.js:1248
msgid "Remove"
msgstr "Odstrániť"
#: ../js/ui/messageTray.js:1501
#: ../js/ui/messageTray.js:1560
msgid "Clear Messages"
msgstr "Vymazať správy"
#: ../js/ui/messageTray.js:1528
#: ../js/ui/messageTray.js:1587
msgid "Notification Settings"
msgstr "Nastavenia oznámení"
#: ../js/ui/messageTray.js:1707
#: ../js/ui/messageTray.js:1770
msgid "No Messages"
msgstr "Žiadne správy"
# DK: zvazoval som pouzit "Panel správ"
# neviem co bude vhodnejsie ako preklad "tray"
#: ../js/ui/messageTray.js:1780
#: ../js/ui/messageTray.js:1842
msgid "Message Tray"
msgstr "Lišta správ"
#: ../js/ui/messageTray.js:2800
#: ../js/ui/messageTray.js:2854
msgid "System Information"
msgstr "Informácie o systéme"
@@ -1264,7 +1269,7 @@ msgctxt "program"
msgid "Unknown"
msgstr "Neznámy"
#: ../js/ui/overviewControls.js:472 ../js/ui/screenShield.js:150
#: ../js/ui/overviewControls.js:474 ../js/ui/screenShield.js:150
#, c-format
msgid "%d new message"
msgid_plural "%d new messages"
@@ -1289,17 +1294,17 @@ msgstr "Prehľad"
msgid "Type to search…"
msgstr "Zadajte text na vyhľadanie…"
#: ../js/ui/panel.js:642
#: ../js/ui/panel.js:567
msgid "Quit"
msgstr "Ukončiť"
#. Translators: If there is no suitable word for "Activities"
#. in your language, you can use the word for "Overview".
#: ../js/ui/panel.js:693
#: ../js/ui/panel.js:618
msgid "Activities"
msgstr "Aktivity"
#: ../js/ui/panel.js:989
#: ../js/ui/panel.js:914
msgid "Top Bar"
msgstr "Horná lišta"
@@ -1308,7 +1313,7 @@ msgstr "Horná lišta"
#. "ON" and "OFF") or "toggle-switch-intl" (for toggle
#. switches containing "◯" and "|"). Other values will
#. simply result in invisible toggle switches.
#: ../js/ui/popupMenu.js:738
#: ../js/ui/popupMenu.js:549
msgid "toggle-switch-us"
msgstr "toggle-switch-intl"
@@ -1337,7 +1342,7 @@ msgstr[0] "%d nových oznámení"
msgstr[1] "%d nové oznámenie"
msgstr[2] "%d nové oznámenia"
#: ../js/ui/screenShield.js:449 ../js/ui/userMenu.js:807
#: ../js/ui/screenShield.js:449 ../js/ui/userMenu.js:759
msgid "Lock"
msgstr "Uzamknúť"
@@ -1352,19 +1357,19 @@ msgstr "Prostredie GNOME vyžaduje uzamknutie obrazovky"
#.
#. XXX: another option is to kick the user into the gdm login
#. screen, where we're not affected by grabs
#: ../js/ui/screenShield.js:773 ../js/ui/screenShield.js:1213
#: ../js/ui/screenShield.js:788 ../js/ui/screenShield.js:1215
msgid "Unable to lock"
msgstr "Nepodarilo sa uzamknúť obrazovku"
#: ../js/ui/screenShield.js:774 ../js/ui/screenShield.js:1214
#: ../js/ui/screenShield.js:789 ../js/ui/screenShield.js:1216
msgid "Lock was blocked by an application"
msgstr "Uzamknutie bolo zablokované aplikáciou"
#: ../js/ui/searchDisplay.js:453
#: ../js/ui/searchDisplay.js:445
msgid "Searching…"
msgstr "Hľadá sa…"
#: ../js/ui/searchDisplay.js:497
#: ../js/ui/searchDisplay.js:489
msgid "No results."
msgstr "Žiadne výsledky."
@@ -1392,7 +1397,7 @@ msgstr "Heslo"
msgid "Remember Password"
msgstr "Zapamätať heslo"
#: ../js/ui/shellMountOperation.js:403 ../js/ui/unlockDialog.js:109
#: ../js/ui/shellMountOperation.js:403 ../js/ui/unlockDialog.js:108
msgid "Unlock"
msgstr "Odblokovať"
@@ -1448,9 +1453,9 @@ msgid "Large Text"
msgstr "Veľký text"
#: ../js/ui/status/bluetooth.js:28 ../js/ui/status/bluetooth.js:32
#: ../js/ui/status/bluetooth.js:289 ../js/ui/status/bluetooth.js:321
#: ../js/ui/status/bluetooth.js:357 ../js/ui/status/bluetooth.js:388
#: ../js/ui/status/network.js:739
#: ../js/ui/status/bluetooth.js:290 ../js/ui/status/bluetooth.js:327
#: ../js/ui/status/bluetooth.js:355 ../js/ui/status/bluetooth.js:391
#: ../js/ui/status/bluetooth.js:422 ../js/ui/status/network.js:713
msgid "Bluetooth"
msgstr "Bluetooth"
@@ -1471,106 +1476,117 @@ msgid "Bluetooth Settings"
msgstr "Nastavenia Bluetooth"
#. TRANSLATORS: this means that bluetooth was disabled by hardware rfkill
#: ../js/ui/status/bluetooth.js:104 ../js/ui/status/network.js:142
#: ../js/ui/status/bluetooth.js:105 ../js/ui/status/network.js:140
msgid "hardware disabled"
msgstr "hardvér zakázaný"
#: ../js/ui/status/bluetooth.js:197
#: ../js/ui/status/bluetooth.js:198
msgid "Connection"
msgstr "Pripojenie"
#: ../js/ui/status/bluetooth.js:208 ../js/ui/status/network.js:404
#: ../js/ui/status/bluetooth.js:209 ../js/ui/status/network.js:399
msgid "disconnecting..."
msgstr "odpája sa…"
#: ../js/ui/status/bluetooth.js:221 ../js/ui/status/network.js:410
#: ../js/ui/status/network.js:1343
#: ../js/ui/status/bluetooth.js:222 ../js/ui/status/network.js:405
#: ../js/ui/status/network.js:1298
msgid "connecting..."
msgstr "pripája sa…"
# menu item
#: ../js/ui/status/bluetooth.js:239
#: ../js/ui/status/bluetooth.js:240
msgid "Send Files…"
msgstr "Odoslať súbory…"
#: ../js/ui/status/bluetooth.js:246
#: ../js/ui/status/bluetooth.js:247
msgid "Keyboard Settings"
msgstr "Nastavenia klávesnice"
#: ../js/ui/status/bluetooth.js:249
#: ../js/ui/status/bluetooth.js:250
msgid "Mouse Settings"
msgstr "Nastavenia myši"
#: ../js/ui/status/bluetooth.js:254 ../js/ui/status/volume.js:316
#: ../js/ui/status/bluetooth.js:255 ../js/ui/status/volume.js:313
msgid "Sound Settings"
msgstr "Nastavenia zvuku"
#: ../js/ui/status/bluetooth.js:322
#: ../js/ui/status/bluetooth.js:328 ../js/ui/status/bluetooth.js:356
#, c-format
msgid "Authorization request from %s"
msgstr "Žiadosť o potvrdenie prístupu od %s"
#: ../js/ui/status/bluetooth.js:328
#, c-format
msgid "Device %s wants access to the service '%s'"
msgstr "Zariadenie %s chce pristupovať k službe „%s“"
#: ../js/ui/status/bluetooth.js:330
msgid "Always grant access"
msgstr "Vždy povoliť prístup"
#: ../js/ui/status/bluetooth.js:331
msgid "Grant this time only"
msgstr "Povoliť iba teraz"
#: ../js/ui/status/bluetooth.js:332
msgid "Reject"
msgstr "Odmietnuť"
#. Translators: argument is the device short name
#: ../js/ui/status/bluetooth.js:359
#, c-format
msgid "Pairing confirmation for %s"
msgstr "Potvrdenie spárovania pre %s"
#: ../js/ui/status/bluetooth.js:365 ../js/ui/status/bluetooth.js:396
#: ../js/ui/status/bluetooth.js:334 ../js/ui/status/bluetooth.js:399
#: ../js/ui/status/bluetooth.js:430
#, c-format
msgid "Device %s wants to pair with this computer"
msgstr "Zariadenie %s sa chce spárovať s týmto počítačom"
# button
#: ../js/ui/status/bluetooth.js:336
msgid "Allow"
msgstr "Povoliť"
# button
#: ../js/ui/status/bluetooth.js:337
msgid "Deny"
msgstr "Zakázať"
#: ../js/ui/status/bluetooth.js:362
#, c-format
msgid "Device %s wants access to the service '%s'"
msgstr "Zariadenie %s chce pristupovať k službe „%s“"
#: ../js/ui/status/bluetooth.js:364
msgid "Always grant access"
msgstr "Vždy povoliť prístup"
#: ../js/ui/status/bluetooth.js:365
msgid "Grant this time only"
msgstr "Povoliť iba teraz"
#: ../js/ui/status/bluetooth.js:366
msgid "Reject"
msgstr "Odmietnuť"
#. Translators: argument is the device short name
#: ../js/ui/status/bluetooth.js:393
#, c-format
msgid "Pairing confirmation for %s"
msgstr "Potvrdenie spárovania pre %s"
#: ../js/ui/status/bluetooth.js:400
#, c-format
msgid ""
"Please confirm whether the Passkey '%06d' matches the one on the device."
msgstr "Prosím, potvrďte, či sa heslo „%06d“ zhoduje s tým na zariadení."
#. Translators: this is the verb, not the noun
#: ../js/ui/status/bluetooth.js:369
#: ../js/ui/status/bluetooth.js:403
msgid "Matches"
msgstr "Zhoduje sa"
#: ../js/ui/status/bluetooth.js:370
#: ../js/ui/status/bluetooth.js:404
msgid "Does not match"
msgstr "Nezhoduje sa"
#: ../js/ui/status/bluetooth.js:389
#: ../js/ui/status/bluetooth.js:423
#, c-format
msgid "Pairing request for %s"
msgstr "Požiadavka na spárovanie pre %s"
#: ../js/ui/status/bluetooth.js:397
#: ../js/ui/status/bluetooth.js:431
msgid "Please enter the PIN mentioned on the device."
msgstr "Zadajte PIN, ktoré je uvedené na zariadení."
#: ../js/ui/status/bluetooth.js:414
#: ../js/ui/status/bluetooth.js:448
msgid "OK"
msgstr "Ok"
#: ../js/ui/status/keyboard.js:368
#: ../js/ui/status/keyboard.js:396
msgid "Show Keyboard Layout"
msgstr "Zobraziť rozloženie klávesnice"
#: ../js/ui/status/keyboard.js:373
#: ../js/ui/status/keyboard.js:401
msgid "Region & Language Settings"
msgstr "Miestne a jazykové nastavenia"
@@ -1583,87 +1599,81 @@ msgstr "Hlasitosť, sieť, batéria"
msgid "<unknown>"
msgstr "<neznáme>"
#: ../js/ui/status/network.js:127
#: ../js/ui/status/network.js:125
msgid "Wi-Fi"
msgstr "Wi-Fi"
#. Translators: this indicates that wireless or wwan is disabled by hardware killswitch
#: ../js/ui/status/network.js:164
#: ../js/ui/status/network.js:162
msgid "disabled"
msgstr "zakázané"
#. Translators: this is for network devices that are physically present but are not
#. under NetworkManager's control (and thus cannot be used in the menu)
#: ../js/ui/status/network.js:402
#: ../js/ui/status/network.js:397
msgid "unmanaged"
msgstr "nespravované"
#. Translators: this is for network connections that require some kind of key or password
#: ../js/ui/status/network.js:413 ../js/ui/status/network.js:1346
#: ../js/ui/status/network.js:408 ../js/ui/status/network.js:1301
msgid "authentication required"
msgstr "požaduje sa overenie totožnosti"
#. Translators: this is for devices that require some kind of firmware or kernel
#. module, which is missing
#: ../js/ui/status/network.js:423
#: ../js/ui/status/network.js:419
msgid "firmware missing"
msgstr "chýba firmvér"
#. Translators: this is for wired network devices that are physically disconnected
#: ../js/ui/status/network.js:430
msgid "cable unplugged"
msgstr "kábel odpojený"
#. Translators: this is for a network device that cannot be activated (for example it
#. is disabled by rfkill, or it has no coverage
#: ../js/ui/status/network.js:435
#: ../js/ui/status/network.js:423
msgid "unavailable"
msgstr "nedostupné"
#: ../js/ui/status/network.js:437 ../js/ui/status/network.js:1348
#: ../js/ui/status/network.js:425 ../js/ui/status/network.js:1303
msgid "connection failed"
msgstr "pripojenie zlyhalo"
#: ../js/ui/status/network.js:490 ../js/ui/status/network.js:1236
#: ../js/ui/status/network.js:1424
#: ../js/ui/status/network.js:478 ../js/ui/status/network.js:1190
msgid "More…"
msgstr "Viac…"
#. TRANSLATORS: this is the indication that a connection for another logged in user is active,
#. and we cannot access its settings (including the name)
#: ../js/ui/status/network.js:518 ../js/ui/status/network.js:1191
#: ../js/ui/status/network.js:506 ../js/ui/status/network.js:1142
msgid "Connected (private)"
msgstr "Pripojené (súkromne)"
#: ../js/ui/status/network.js:597
#: ../js/ui/status/network.js:572
msgid "Wired"
msgstr "Drôtové pripojenie"
#: ../js/ui/status/network.js:611
#: ../js/ui/status/network.js:592
msgid "Mobile broadband"
msgstr "Širokopásmové pripojenie"
#: ../js/ui/status/network.js:1522
#: ../js/ui/status/network.js:1474
msgid "Enable networking"
msgstr "Povoliť sieť"
#: ../js/ui/status/network.js:1583
#: ../js/ui/status/network.js:1522
msgid "Network Settings"
msgstr "Nastavenia siete"
#: ../js/ui/status/network.js:1600
#: ../js/ui/status/network.js:1539
msgid "Network Manager"
msgstr "Správca siete"
#: ../js/ui/status/network.js:1690
#: ../js/ui/status/network.js:1623
msgid "Connection failed"
msgstr "Pripojenie zlyhalo"
#: ../js/ui/status/network.js:1691
#: ../js/ui/status/network.js:1624
msgid "Activation of network connection failed"
msgstr "Aktivácia pripojenia k sieti zlyhala"
#: ../js/ui/status/network.js:2047
#: ../js/ui/status/network.js:1938
msgid "Networking is disabled"
msgstr "Sieť je zakázaná"
@@ -1768,72 +1778,72 @@ msgctxt "device"
msgid "Unknown"
msgstr "Neznáme"
#: ../js/ui/status/volume.js:124
#: ../js/ui/status/volume.js:121
msgid "Volume changed"
msgstr "Hlasitosť bola zmenená"
#. Translators: This is the label for audio volume
#: ../js/ui/status/volume.js:249 ../js/ui/status/volume.js:297
#: ../js/ui/status/volume.js:246 ../js/ui/status/volume.js:294
msgid "Volume"
msgstr "Hlasitosť"
#: ../js/ui/status/volume.js:258
#: ../js/ui/status/volume.js:255
msgid "Microphone"
msgstr "Mikrofón"
#: ../js/ui/unlockDialog.js:120
#: ../js/ui/unlockDialog.js:119
msgid "Log in as another user"
msgstr "Prihlásiť ako iný používateľ"
#: ../js/ui/unlockDialog.js:141
#: ../js/ui/unlockDialog.js:140
msgid "Unlock Window"
msgstr "Odomykacie okno"
#: ../js/ui/userMenu.js:193
#: ../js/ui/userMenu.js:149
msgid "Available"
msgstr "Prítomný"
#: ../js/ui/userMenu.js:196
#: ../js/ui/userMenu.js:152
msgid "Busy"
msgstr "Zaneprázdnený"
#: ../js/ui/userMenu.js:199
#: ../js/ui/userMenu.js:155
msgid "Invisible"
msgstr "Neviditeľný"
#: ../js/ui/userMenu.js:202
#: ../js/ui/userMenu.js:158
msgid "Away"
msgstr "Neprítomný"
#: ../js/ui/userMenu.js:205
#: ../js/ui/userMenu.js:161
msgid "Idle"
msgstr "Nečinný"
#: ../js/ui/userMenu.js:208
#: ../js/ui/userMenu.js:164
msgid "Offline"
msgstr "Odhlásený"
#: ../js/ui/userMenu.js:781
#: ../js/ui/userMenu.js:736
msgid "Notifications"
msgstr "Upozornenia"
#: ../js/ui/userMenu.js:797
#: ../js/ui/userMenu.js:749
msgid "Switch User"
msgstr "Prepnúť používateľa"
#: ../js/ui/userMenu.js:802
#: ../js/ui/userMenu.js:754
msgid "Log Out"
msgstr "Odhlásiť sa"
#: ../js/ui/userMenu.js:822
#: ../js/ui/userMenu.js:774
msgid "Install Updates & Restart"
msgstr "Nainštalovať aktualizácie a reštartovať"
#: ../js/ui/userMenu.js:840
#: ../js/ui/userMenu.js:792
msgid "Your chat status will be set to busy"
msgstr "Váš stav bude nastavený na zaneprázdnený"
#: ../js/ui/userMenu.js:841
#: ../js/ui/userMenu.js:793
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."
@@ -1841,22 +1851,22 @@ msgstr ""
"Oznámenia, vrátane správ rozhovoru, sú teraz zakázané. Váš stav online bol "
"nastavený tak, aby ostatní vedeli, že nemusíte vidieť ich správy."
#: ../js/ui/userMenu.js:888
#: ../js/ui/userMenu.js:834
msgid "Other users are logged in."
msgstr "Sú prihlásení iní používatelia."
#: ../js/ui/userMenu.js:893
#: ../js/ui/userMenu.js:839
msgid "Shutting down might cause them to lose unsaved work."
msgstr "Vypnutie môže spôsobiť stratu neuloženej práce."
#. Translators: Remote here refers to a remote session, like a ssh login
#: ../js/ui/userMenu.js:921
#: ../js/ui/userMenu.js:867
#, c-format
msgid "%s (remote)"
msgstr "%s (vzdialená relácia)"
#. Translators: Console here refers to a tty like a VT console
#: ../js/ui/userMenu.js:924
#: ../js/ui/userMenu.js:870
#, c-format
msgid "%s (console)"
msgstr "%s (konzola)"
@@ -1918,19 +1928,19 @@ msgstr[2] "%u vstupy"
msgid "System Sounds"
msgstr "Systémové zvuky"
#: ../src/main.c:372
#: ../src/main.c:353
msgid "Print version"
msgstr "Verzia pre tlač"
#: ../src/main.c:378
#: ../src/main.c:359
msgid "Mode used by GDM for login screen"
msgstr "Režim používaný GDM pre prihlasovaciu obrazovku"
#: ../src/main.c:384
#: ../src/main.c:365
msgid "Use a specific mode, e.g. \"gdm\" for login screen"
msgstr "Použitie zvláštneho režimu, napr. „gdm“ pre prihlasovaciu obrazovku"
#: ../src/main.c:390
#: ../src/main.c:371
msgid "List possible modes"
msgstr "Zoznam možných režimov"
@@ -1952,6 +1962,9 @@ msgstr "Heslo nemôže byť prázdne"
msgid "Authentication dialog was dismissed by the user"
msgstr "Dialógové okno overenia totožnosti bolo zatvorené používateľom"
#~ msgid "cable unplugged"
#~ msgstr "kábel odpojený"
#~ msgid "Whether to collect stats about applications usage"
#~ msgstr "Či sa majú zhromažďovať štatistické údaje o používaní aplikácií"

133
po/tg.po
View File

@@ -8,8 +8,8 @@ msgstr ""
"Project-Id-Version: Tajik Gnome\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-06-14 18:16+0000\n"
"PO-Revision-Date: 2013-06-16 23:32+0500\n"
"POT-Creation-Date: 2013-07-03 17:55+0000\n"
"PO-Revision-Date: 2013-07-12 16:00+0500\n"
"Last-Translator: Victor Ibragimov <victor.ibragimov@gmail.com>\n"
"Language-Team: \n"
"Language: Tajik\n"
@@ -375,18 +375,23 @@ msgstr ""
"Пасвандеро интихоб кунед, то ин ки бо ҷаъбаи мураккаби боло онро "
"конфигуратсия кунед."
#: ../js/gdm/loginDialog.js:370
msgid "Session"
msgstr "Ҷаласа..."
#: ../js/gdm/loginDialog.js:308
msgid "Choose Session"
msgstr "Интихоби ҷаласа"
#: ../js/gdm/loginDialog.js:326
#| msgid "Session…"
msgid "Session"
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:600
#: ../js/gdm/loginDialog.js:528
msgid "Not listed?"
msgstr "Вуҷуд надора?"
#: ../js/gdm/loginDialog.js:775 ../js/ui/components/networkAgent.js:137
#: ../js/gdm/loginDialog.js:810 ../js/ui/components/networkAgent.js:137
#: ../js/ui/components/polkitAgent.js:161 ../js/ui/endSessionDialog.js:376
#: ../js/ui/extensionDownloader.js:195 ../js/ui/shellMountOperation.js:399
#: ../js/ui/status/bluetooth.js:449 ../js/ui/unlockDialog.js:95
@@ -394,18 +399,18 @@ msgstr "Вуҷуд надора?"
msgid "Cancel"
msgstr "Бекор кардан"
#: ../js/gdm/loginDialog.js:790
#: ../js/gdm/loginDialog.js:833
msgctxt "button"
msgid "Sign In"
msgstr "Ворид шудан"
#: ../js/gdm/loginDialog.js:790
#: ../js/gdm/loginDialog.js:833
msgid "Next"
msgstr "Навбатӣ"
#. Translators: this message is shown below the username entry field
#. to clue the user in on how to login to the local network realm
#: ../js/gdm/loginDialog.js:887
#: ../js/gdm/loginDialog.js:934
#, c-format
msgid "(e.g., user or %s)"
msgstr "(масалан, корбар ё %s)"
@@ -413,12 +418,12 @@ msgstr "(масалан, корбар ё %s)"
#. TTLS and PEAP are actually much more complicated, but this complication
#. is not visible here since we only care about phase2 authentication
#. (and don't even care of which one)
#: ../js/gdm/loginDialog.js:891 ../js/ui/components/networkAgent.js:260
#: ../js/gdm/loginDialog.js:938 ../js/ui/components/networkAgent.js:260
#: ../js/ui/components/networkAgent.js:278
msgid "Username: "
msgstr "Номи корбар:"
#: ../js/gdm/loginDialog.js:1157
#: ../js/gdm/loginDialog.js:1205
msgid "Login Window"
msgstr "Равзанаи воридшавӣ"
@@ -441,13 +446,13 @@ msgstr "Бозоғозидан"
msgid "Power Off"
msgstr "Хомӯш кардан"
#: ../js/gdm/util.js:247
#: ../js/gdm/util.js:248
msgid "Authentication error"
msgstr "Хатои санҷиши ҳаққоният"
#. Translators: this message is shown below the password entry field
#. to indicate the user can swipe their finger instead
#: ../js/gdm/util.js:364
#: ../js/gdm/util.js:365
msgid "(or swipe finger)"
msgstr "(ё бо ангут ламс кунед)"
@@ -838,14 +843,14 @@ msgstr "<b>%B</b> <b>%d</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:985
#: ../js/ui/components/telepathyClient.js:986
#, c-format
msgid "%s is now known as %s"
msgstr "%s аллакой бо номи %s номида мешавад"
#. translators: argument is a room name like
#. * room@jabber.org for example.
#: ../js/ui/components/telepathyClient.js:1088
#: ../js/ui/components/telepathyClient.js:1089
#, c-format
msgid "Invitation to %s"
msgstr "Даъватнома барои to %s"
@@ -853,38 +858,38 @@ msgstr "Даъватнома барои to %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:1096
#: ../js/ui/components/telepathyClient.js:1097
#, c-format
msgid "%s is inviting you to join %s"
msgstr "%s шуморо барои ҳамроҳ шудан ба %s даъват мекунад"
#: ../js/ui/components/telepathyClient.js:1098
#: ../js/ui/components/telepathyClient.js:1137
#: ../js/ui/components/telepathyClient.js:1177
#: ../js/ui/components/telepathyClient.js:1240
#: ../js/ui/components/telepathyClient.js:1099
#: ../js/ui/components/telepathyClient.js:1138
#: ../js/ui/components/telepathyClient.js:1178
#: ../js/ui/components/telepathyClient.js:1241
msgid "Decline"
msgstr "Рад кардан"
#: ../js/ui/components/telepathyClient.js:1099
#: ../js/ui/components/telepathyClient.js:1178
#: ../js/ui/components/telepathyClient.js:1241
#: ../js/ui/components/telepathyClient.js:1100
#: ../js/ui/components/telepathyClient.js:1179
#: ../js/ui/components/telepathyClient.js:1242
msgid "Accept"
msgstr "Қабул кардан"
#. translators: argument is a contact name like Alice for example.
#: ../js/ui/components/telepathyClient.js:1129
#: ../js/ui/components/telepathyClient.js:1130
#, c-format
msgid "Video call from %s"
msgstr "Занги видеоӣ аз %s"
#. translators: argument is a contact name like Alice for example.
#: ../js/ui/components/telepathyClient.js:1132
#: ../js/ui/components/telepathyClient.js:1133
#, c-format
msgid "Call from %s"
msgstr "Занг аз %s"
#. translators: this is a button label (verb), not a noun
#: ../js/ui/components/telepathyClient.js:1139
#: ../js/ui/components/telepathyClient.js:1140
msgid "Answer"
msgstr "Ҷавоб"
@@ -893,110 +898,110 @@ msgstr "Ҷавоб"
#. * file name. The string will be something
#. * like: "Alice is sending you test.ogg"
#.
#: ../js/ui/components/telepathyClient.js:1171
#: ../js/ui/components/telepathyClient.js:1172
#, c-format
msgid "%s is sending you %s"
msgstr "%s ба шумо %s-ро мефиристад"
#. To translators: The parameter is the contact's alias
#: ../js/ui/components/telepathyClient.js:1206
#: ../js/ui/components/telepathyClient.js:1207
#, c-format
msgid "%s would like permission to see when you are online"
msgstr "%s аз шумо иҷозат мепурсад, ки тавонад шуморо дар онлайн бинад"
#: ../js/ui/components/telepathyClient.js:1298
#: ../js/ui/components/telepathyClient.js:1299
msgid "Network error"
msgstr "Хатои шабака"
#: ../js/ui/components/telepathyClient.js:1300
#: ../js/ui/components/telepathyClient.js:1301
msgid "Authentication failed"
msgstr "Санҷиши ҳаққоният қатъ шудааст."
#: ../js/ui/components/telepathyClient.js:1302
#: ../js/ui/components/telepathyClient.js:1303
msgid "Encryption error"
msgstr "Хатои рамзгузорӣ"
#: ../js/ui/components/telepathyClient.js:1304
#: ../js/ui/components/telepathyClient.js:1305
msgid "Certificate not provided"
msgstr "Гувоҳинома таъмин нашудааст"
#: ../js/ui/components/telepathyClient.js:1306
#: ../js/ui/components/telepathyClient.js:1307
msgid "Certificate untrusted"
msgstr "Гувоҳиномаи беэътибор"
#: ../js/ui/components/telepathyClient.js:1308
#: ../js/ui/components/telepathyClient.js:1309
msgid "Certificate expired"
msgstr "Гувоҳинома аз мӯҳлаташ гузашт"
#: ../js/ui/components/telepathyClient.js:1310
#: ../js/ui/components/telepathyClient.js:1311
msgid "Certificate not activated"
msgstr "Гувоҳинома фаъол нашудааст"
#: ../js/ui/components/telepathyClient.js:1312
#: ../js/ui/components/telepathyClient.js:1313
msgid "Certificate hostname mismatch"
msgstr "Номувофиқати гувоҳиномаи номи мизоҷон"
#: ../js/ui/components/telepathyClient.js:1314
#: ../js/ui/components/telepathyClient.js:1315
msgid "Certificate fingerprint mismatch"
msgstr "Номувофиқати гувоҳиномаи нақши ангуштон"
#: ../js/ui/components/telepathyClient.js:1316
#: ../js/ui/components/telepathyClient.js:1317
msgid "Certificate self-signed"
msgstr "Гувоҳиномаи худимзошуда"
#: ../js/ui/components/telepathyClient.js:1318
#: ../js/ui/components/telepathyClient.js:1319
msgid "Status is set to offline"
msgstr "Вазъият ба \"офлайн\" гузаштааст"
#: ../js/ui/components/telepathyClient.js:1320
#: ../js/ui/components/telepathyClient.js:1321
msgid "Encryption is not available"
msgstr "Рамзгузорӣ дастрас нест"
#: ../js/ui/components/telepathyClient.js:1322
#: ../js/ui/components/telepathyClient.js:1323
msgid "Certificate is invalid"
msgstr "Гувоҳинома нодуруст аст"
#: ../js/ui/components/telepathyClient.js:1324
#: ../js/ui/components/telepathyClient.js:1325
msgid "Connection has been refused"
msgstr "Пайваст рад карда шудааст"
#: ../js/ui/components/telepathyClient.js:1326
#: ../js/ui/components/telepathyClient.js:1327
msgid "Connection can't be established"
msgstr "Пайвастшавӣ имконнопазир аст"
#: ../js/ui/components/telepathyClient.js:1328
#: ../js/ui/components/telepathyClient.js:1329
msgid "Connection has been lost"
msgstr "Пайваст гум шудааст"
#: ../js/ui/components/telepathyClient.js:1330
#: ../js/ui/components/telepathyClient.js:1331
msgid "This account is already connected to the server"
msgstr "Ин ҳисоб аллакай ба сервер пайваст шудааст"
#: ../js/ui/components/telepathyClient.js:1332
#: ../js/ui/components/telepathyClient.js:1333
msgid ""
"Connection has been replaced by a new connection using the same resource"
msgstr "Пайваст тавассути сарчашмаи якхела бо пайвасти нав ҷойиваз карда шуд"
#: ../js/ui/components/telepathyClient.js:1334
#: ../js/ui/components/telepathyClient.js:1335
msgid "The account already exists on the server"
msgstr "Ҳисоб дар сервер аллакай мавҷуд аст"
#: ../js/ui/components/telepathyClient.js:1336
#: ../js/ui/components/telepathyClient.js:1337
msgid "Server is currently too busy to handle the connection"
msgstr "Барои коркарди ин пайваст сервер дар айни ҳол хеле машғул мебошад"
#: ../js/ui/components/telepathyClient.js:1338
#: ../js/ui/components/telepathyClient.js:1339
msgid "Certificate has been revoked"
msgstr "Гувоҳинома лағв карда шуд"
#: ../js/ui/components/telepathyClient.js:1340
#: ../js/ui/components/telepathyClient.js:1341
msgid ""
"Certificate uses an insecure cipher algorithm or is cryptographically weak"
msgstr ""
"Гувоҳинома алгоритми хатарноки рамзро истифода мебарад, ё ки рамзгузории "
"суст дорад"
#: ../js/ui/components/telepathyClient.js:1342
#: ../js/ui/components/telepathyClient.js:1343
msgid ""
"The length of the server certificate, or the depth of the server certificate "
"chain, exceed the limits imposed by the cryptography library"
@@ -1004,22 +1009,22 @@ msgstr ""
"Дарозии гувоҳиномаи сервер, ё ки чуқурии занҷири гувоҳиномаи сервер, аз "
"маҳдудиятҳое, ки бо китобхонаи рамзгузорӣ таъин шудаанд, дарозтар мебошад"
#: ../js/ui/components/telepathyClient.js:1344
#: ../js/ui/components/telepathyClient.js:1345
msgid "Internal error"
msgstr "Хатогии дохилӣ"
#. translators: argument is the account name, like
#. * name@jabber.org for example.
#: ../js/ui/components/telepathyClient.js:1354
#: ../js/ui/components/telepathyClient.js:1355
#, c-format
msgid "Unable to connect to %s"
msgstr "Пайвастшавӣ ба %s имконнопазир аст"
#: ../js/ui/components/telepathyClient.js:1359
#: ../js/ui/components/telepathyClient.js:1360
msgid "View account"
msgstr "Намоиш додани ҳисоб"
#: ../js/ui/components/telepathyClient.js:1398
#: ../js/ui/components/telepathyClient.js:1399
msgid "Unknown reason"
msgstr "Сабаби номаълум"
@@ -1052,7 +1057,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:202
#: ../js/ui/dateMenu.js:201
msgid "%A %B %e, %Y"
msgstr "%A %B %e, %Y"
@@ -1263,17 +1268,17 @@ msgstr "Хулоса"
msgid "Type to search…"
msgstr "Ҷустуҷӯ кардан..."
#: ../js/ui/panel.js:642
#: ../js/ui/panel.js:567
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:693
#: ../js/ui/panel.js:618
msgid "Activities"
msgstr "Фаъолиятҳо"
#: ../js/ui/panel.js:989
#: ../js/ui/panel.js:914
msgid "Top Bar"
msgstr "Панели боло"
@@ -1282,7 +1287,7 @@ msgstr "Панели боло"
#. "ON" and "OFF") or "toggle-switch-intl" (for toggle
#. switches containing "◯" and "|"). Other values will
#. simply result in invisible toggle switches.
#: ../js/ui/popupMenu.js:545
#: ../js/ui/popupMenu.js:549
msgid "toggle-switch-us"
msgstr "toggle-switch-us"
@@ -1321,11 +1326,11 @@ 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:773 ../js/ui/screenShield.js:1213
#: ../js/ui/screenShield.js:775 ../js/ui/screenShield.js:1215
msgid "Unable to lock"
msgstr "Қулф карда намешавад"
#: ../js/ui/screenShield.js:774 ../js/ui/screenShield.js:1214
#: ../js/ui/screenShield.js:776 ../js/ui/screenShield.js:1216
msgid "Lock was blocked by an application"
msgstr "Қулф аз тарави барнома баста шудааст"
@@ -1632,7 +1637,7 @@ msgstr "Пайваст қатъ шудааст"
msgid "Activation of network connection failed"
msgstr "Фаъолсозии пайвасти шабака қатъ шудааст."
#: ../js/ui/status/network.js:1933
#: ../js/ui/status/network.js:1938
msgid "Networking is disabled"
msgstr "Шабака ғайрифаъол аст"

720
po/vi.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -70,7 +70,6 @@ struct _ShellGlobal {
GtkWindow *grab_notifier;
gboolean gtk_grab_active;
ShellStageInputMode input_mode;
XserverRegion input_region;
GjsContext *js_context;
@@ -94,6 +93,8 @@ struct _ShellGlobal {
guint32 xdnd_timestamp;
gint64 last_gc_end_time;
gboolean has_modal;
};
enum {
@@ -106,7 +107,6 @@ enum {
PROP_SCREEN_WIDTH,
PROP_SCREEN_HEIGHT,
PROP_STAGE,
PROP_STAGE_INPUT_MODE,
PROP_WINDOW_GROUP,
PROP_TOP_WINDOW_GROUP,
PROP_WINDOW_MANAGER,
@@ -141,9 +141,6 @@ shell_global_set_property(GObject *object,
switch (prop_id)
{
case PROP_STAGE_INPUT_MODE:
shell_global_set_stage_input_mode (global, g_value_get_enum (value));
break;
case PROP_SESSION_MODE:
g_clear_pointer (&global->session_mode, g_free);
global->session_mode = g_ascii_strdown (g_value_get_string (value), -1);
@@ -195,9 +192,6 @@ shell_global_get_property(GObject *object,
case PROP_STAGE:
g_value_set_object (value, global->stage);
break;
case PROP_STAGE_INPUT_MODE:
g_value_set_enum (value, global->input_mode);
break;
case PROP_WINDOW_GROUP:
g_value_set_object (value, meta_get_window_group_for_screen (global->meta_screen));
break;
@@ -278,8 +272,6 @@ shell_global_init (ShellGlobal *global)
g_signal_connect (global->grab_notifier, "grab-notify", G_CALLBACK (grab_notify), global);
global->gtk_grab_active = FALSE;
global->input_mode = SHELL_STAGE_INPUT_MODE_NORMAL;
global->sound_context = ca_gtk_context_get ();
ca_context_change_props (global->sound_context,
CA_PROP_APPLICATION_NAME, "GNOME Shell",
@@ -417,14 +409,6 @@ shell_global_class_init (ShellGlobalClass *klass)
"Stage holding the desktop scene graph",
CLUTTER_TYPE_ACTOR,
G_PARAM_READABLE));
g_object_class_install_property (gobject_class,
PROP_STAGE_INPUT_MODE,
g_param_spec_enum ("stage-input-mode",
"Stage input mode",
"The stage input mode",
SHELL_TYPE_STAGE_INPUT_MODE,
SHELL_STAGE_INPUT_MODE_NORMAL,
G_PARAM_READWRITE));
g_object_class_install_property (gobject_class,
PROP_WINDOW_GROUP,
g_param_spec_object ("window-group",
@@ -529,6 +513,18 @@ shell_global_get (void)
return the_object;
}
static guint32
get_current_time_maybe_roundtrip (ShellGlobal *global)
{
guint32 time;
time = shell_global_get_current_time (global);
if (time != CurrentTime)
return time;
return meta_display_get_current_time_roundtrip (global->meta_display);
}
static void
focus_window_changed (MetaDisplay *display,
GParamSpec *param,
@@ -536,58 +532,71 @@ focus_window_changed (MetaDisplay *display,
{
ShellGlobal *global = user_data;
if (global->input_mode == SHELL_STAGE_INPUT_MODE_FOCUSED &&
meta_display_get_focus_window (display) != NULL)
shell_global_set_stage_input_mode (global, SHELL_STAGE_INPUT_MODE_NORMAL);
if (global->has_modal)
return;
/* If the stage window became unfocused, drop the key focus
* on Clutter's side. */
if (!meta_stage_is_focused (global->meta_screen))
clutter_stage_set_key_focus (global->stage, NULL);
}
/**
* shell_global_set_stage_input_mode:
* @global: the #ShellGlobal
* @mode: the stage input mode
*
* Sets the input mode of the stage; when @mode is
* %SHELL_STAGE_INPUT_MODE_NORMAL, then the stage accepts clicks in
* the region defined by shell_global_set_stage_input_region() but
* passes through clicks outside that region. When it is
* %SHELL_STAGE_INPUT_MODE_FULLSCREEN, the stage absorbs all input.
*
* When the input mode is %SHELL_STAGE_INPUT_MODE_FOCUSED, the pointer
* is handled as with %SHELL_STAGE_INPUT_MODE_NORMAL, but additionally
* the stage window has the keyboard focus. If the stage loses the
* focus (eg, because the user clicked into a window) the input mode
* will revert to %SHELL_STAGE_INPUT_MODE_NORMAL.
*
* Note that whenever a mutter-internal Gtk widget has a pointer grab,
* the shell goes unresponsive and passes things to the underlying GTK+
* widget to ensure that the widget gets any clicks it is expecting.
*/
void
shell_global_set_stage_input_mode (ShellGlobal *global,
ShellStageInputMode mode)
static ClutterActor *
get_key_focused_actor (ShellGlobal *global)
{
MetaScreen *screen;
ClutterActor *actor;
g_return_if_fail (SHELL_IS_GLOBAL (global));
actor = clutter_stage_get_key_focus (global->stage);
screen = meta_plugin_get_screen (global->plugin);
/* If there's no explicit key focus, clutter_stage_get_key_focus()
* returns the stage. This is a terrible API. */
if (actor == CLUTTER_ACTOR (global->stage))
actor = NULL;
return actor;
}
static void
sync_stage_window_focus (ShellGlobal *global)
{
ClutterActor *actor;
if (global->has_modal)
return;
actor = get_key_focused_actor (global);
/* An actor got key focus and the stage needs to be focused. */
if (actor != NULL && !meta_stage_is_focused (global->meta_screen))
meta_focus_stage_window (global->meta_screen,
get_current_time_maybe_roundtrip (global));
/* An actor dropped key focus. Focus the default window. */
else if (actor == NULL && meta_stage_is_focused (global->meta_screen))
meta_screen_focus_default_window (global->meta_screen,
get_current_time_maybe_roundtrip (global));
}
static void
focus_actor_changed (ClutterStage *stage,
GParamSpec *param,
gpointer user_data)
{
ShellGlobal *global = user_data;
sync_stage_window_focus (global);
}
static void
sync_input_region (ShellGlobal *global)
{
MetaScreen *screen = global->meta_screen;
if (global->gtk_grab_active)
meta_empty_stage_input_region (screen);
else if (mode == SHELL_STAGE_INPUT_MODE_FULLSCREEN || !global->input_region)
else if (global->has_modal)
meta_set_stage_input_region (screen, None);
else
meta_set_stage_input_region (screen, global->input_region);
if (mode == SHELL_STAGE_INPUT_MODE_FOCUSED)
meta_focus_stage_window (global->meta_screen,
shell_global_get_current_time (global));
if (mode != global->input_mode)
{
global->input_mode = mode;
g_object_notify (G_OBJECT (global), "stage-input-mode");
}
}
/**
@@ -682,8 +691,7 @@ shell_global_unset_cursor (ShellGlobal *global)
* describing the input region.
*
* Sets the area of the stage that is responsive to mouse clicks when
* the stage mode is %SHELL_STAGE_INPUT_MODE_NORMAL (but does not change the
* current stage mode).
* we don't have a modal or grab.
*/
void
shell_global_set_stage_input_region (ShellGlobal *global,
@@ -713,10 +721,7 @@ shell_global_set_stage_input_region (ShellGlobal *global,
global->input_region = XFixesCreateRegion (global->xdisplay, rects, nrects);
g_free (rects);
/* set_stage_input_mode() will figure out whether or not we
* should actually change the input region right now.
*/
shell_global_set_stage_input_mode (global, global->input_mode);
sync_input_region (global);
}
/**
@@ -956,6 +961,8 @@ _shell_global_set_plugin (ShellGlobal *global,
"End of stage page repaint",
"");
g_signal_connect (global->stage, "notify::key-focus",
G_CALLBACK (focus_actor_changed), global);
g_signal_connect (global->meta_display, "notify::focus-window",
G_CALLBACK (focus_window_changed), global);
@@ -991,7 +998,14 @@ shell_global_begin_modal (ShellGlobal *global,
guint32 timestamp,
MetaModalOptions options)
{
return meta_plugin_begin_modal (global->plugin, global->stage_xwindow, None, options, timestamp);
/* Make it an error to call begin_modal while we already
* have a modal active. */
if (global->has_modal)
return FALSE;
global->has_modal = meta_plugin_begin_modal (global->plugin, global->stage_xwindow, None, options, timestamp);
sync_input_region (global);
return global->has_modal;
}
/**
@@ -1004,7 +1018,25 @@ void
shell_global_end_modal (ShellGlobal *global,
guint32 timestamp)
{
ClutterActor *actor;
if (!global->has_modal)
return;
meta_plugin_end_modal (global->plugin, timestamp);
global->has_modal = FALSE;
/* If the stage window is unfocused, ensure that there's no
* actor focused on Clutter's side. */
if (!meta_stage_is_focused (global->meta_screen))
clutter_stage_set_key_focus (global->stage, NULL);
/* An actor dropped key focus. Focus the default window. */
else if (get_key_focused_actor (global) && meta_stage_is_focused (global->meta_screen))
meta_screen_focus_default_window (global->meta_screen,
get_current_time_maybe_roundtrip (global));
sync_input_region (global);
}
void
@@ -1222,7 +1254,7 @@ grab_notify (GtkWidget *widget, gboolean was_grabbed, gpointer user_data)
global->gtk_grab_active = !was_grabbed;
/* Update for the new setting of gtk_grab_active */
shell_global_set_stage_input_mode (global, global->input_mode);
sync_input_region (global);
}
/**
@@ -1314,10 +1346,6 @@ shell_global_sync_pointer (ShellGlobal *global)
event.type = CLUTTER_MOTION;
event.time = shell_global_get_current_time (global);
event.flags = 0;
/* This is wrong: we should be setting event.stage to NULL if the
* pointer is not inside the bounds of the stage given the current
* stage_input_mode. For our current purposes however, this works.
*/
event.stage = global->stage;
event.x = x;
event.y = y;

View File

@@ -47,14 +47,6 @@ void shell_global_end_modal (ShellGlobal *global,
void shell_global_freeze_keyboard (ShellGlobal *global,
guint32 timestamp);
typedef enum {
SHELL_STAGE_INPUT_MODE_NORMAL,
SHELL_STAGE_INPUT_MODE_FOCUSED,
SHELL_STAGE_INPUT_MODE_FULLSCREEN
} ShellStageInputMode;
void shell_global_set_stage_input_mode (ShellGlobal *global,
ShellStageInputMode mode);
void shell_global_set_stage_input_region (ShellGlobal *global,
GSList *rectangles);

View File

@@ -104,8 +104,8 @@ shell_slicer_paint_child (ShellSlicer *self)
return;
st_bin_get_alignment (ST_BIN (self), &x_align, &y_align);
_st_get_align_factors (x_align, y_align,
&x_align_factor, &y_align_factor);
st_get_align_factors (x_align, y_align,
&x_align_factor, &y_align_factor);
clutter_actor_get_allocation_box (CLUTTER_ACTOR (self), &self_box);
clutter_actor_get_allocation_box (child, &child_box);

View File

@@ -108,8 +108,8 @@ st_bin_allocate (ClutterActor *self,
gdouble x_align_f, y_align_f;
st_theme_node_get_content_box (theme_node, box, &childbox);
_st_get_align_factors (priv->x_align, priv->y_align,
&x_align_f, &y_align_f);
st_get_align_factors (priv->x_align, priv->y_align,
&x_align_f, &y_align_f);
clutter_actor_allocate_align_fill (priv->child, &childbox,
x_align_f, y_align_f,
priv->x_fill, priv->y_fill,

View File

@@ -285,7 +285,6 @@ get_content_preferred_width (StBoxLayout *self,
{
StBoxLayoutPrivate *priv = self->priv;
gint n_children = 0;
gint n_fixed = 0;
gfloat min_width, natural_width;
ClutterActor *child;
@@ -304,12 +303,6 @@ get_content_preferred_width (StBoxLayout *self,
n_children++;
if (clutter_actor_get_fixed_position_set (child))
{
n_fixed++;
continue;
}
if (priv->is_vertical)
{
_st_actor_get_preferred_width (child, -1, FALSE,
@@ -329,10 +322,10 @@ get_content_preferred_width (StBoxLayout *self,
}
}
if (!priv->is_vertical && (n_children - n_fixed) > 1)
if (!priv->is_vertical && n_children > 1)
{
min_width += priv->spacing * (n_children - n_fixed - 1);
natural_width += priv->spacing * (n_children - n_fixed - 1);
min_width += priv->spacing * (n_children - 1);
natural_width += priv->spacing * (n_children - 1);
}
if (min_width_p)
@@ -367,7 +360,6 @@ get_content_preferred_height (StBoxLayout *self,
{
StBoxLayoutPrivate *priv = self->priv;
gint n_children = 0;
gint n_fixed = 0;
gfloat min_height, natural_height;
ClutterActor *child;
@@ -386,12 +378,6 @@ get_content_preferred_height (StBoxLayout *self,
n_children++;
if (clutter_actor_get_fixed_position_set (child))
{
n_fixed++;
continue;
}
if (priv->is_vertical)
{
clutter_container_child_get ((ClutterContainer*) self, child,
@@ -416,10 +402,10 @@ get_content_preferred_height (StBoxLayout *self,
}
}
if (priv->is_vertical && (n_children - n_fixed) > 1)
if (priv->is_vertical && n_children > 1)
{
min_height += priv->spacing * (n_children - n_fixed - 1);
natural_height += priv->spacing * (n_children - n_fixed - 1);
min_height += priv->spacing * (n_children - 1);
natural_height += priv->spacing * (n_children - 1);
}
if (min_height_p)
@@ -511,12 +497,9 @@ compute_shrinks (StBoxLayout *self,
{
gfloat child_min, child_nat;
gboolean child_fill;
gboolean fixed;
fixed = clutter_actor_get_fixed_position_set (child);
shrinks[i].child_index = i;
if (CLUTTER_ACTOR_IS_VISIBLE (child) && !fixed)
if (CLUTTER_ACTOR_IS_VISIBLE (child))
{
if (priv->is_vertical)
{
@@ -738,20 +721,13 @@ st_box_layout_allocate (ClutterActor *actor,
{
ClutterActorBox child_box;
gfloat child_min, child_nat, child_allocated;
gboolean xfill, yfill, expand, fixed;
gboolean xfill, yfill, expand;
StAlign xalign, yalign;
gdouble xalign_f, yalign_f;
if (!CLUTTER_ACTOR_IS_VISIBLE (child))
goto next_child;
fixed = clutter_actor_get_fixed_position_set (child);
if (fixed)
{
clutter_actor_allocate_preferred_size (child, flags);
goto next_child;
}
clutter_container_child_get ((ClutterContainer*) actor, child,
"x-fill", &xfill,
"y-fill", &yfill,
@@ -760,7 +736,7 @@ st_box_layout_allocate (ClutterActor *actor,
"expand", &expand,
NULL);
_st_get_align_factors (xalign, yalign, &xalign_f, &yalign_f);
st_get_align_factors (xalign, yalign, &xalign_f, &yalign_f);
if (priv->is_vertical)
{

View File

@@ -98,66 +98,6 @@ _st_actor_get_preferred_height (ClutterActor *actor,
clutter_actor_get_preferred_height (actor, for_width, min_height_p, natural_height_p);
}
/**
* _st_get_align_factors:
* @x_align: an #StAlign
* @y_align: an #StAlign
* @x_align_out: (out) (allow-none): @x_align as a #gdouble
* @y_align_out: (out) (allow-none): @y_align as a #gdouble
*
* Converts @x_align and @y_align to #gdouble values.
*/
void
_st_get_align_factors (StAlign x_align,
StAlign y_align,
gdouble *x_align_out,
gdouble *y_align_out)
{
if (x_align_out)
{
switch (x_align)
{
case ST_ALIGN_START:
*x_align_out = 0.0;
break;
case ST_ALIGN_MIDDLE:
*x_align_out = 0.5;
break;
case ST_ALIGN_END:
*x_align_out = 1.0;
break;
default:
g_warn_if_reached ();
break;
}
}
if (y_align_out)
{
switch (y_align)
{
case ST_ALIGN_START:
*y_align_out = 0.0;
break;
case ST_ALIGN_MIDDLE:
*y_align_out = 0.5;
break;
case ST_ALIGN_END:
*y_align_out = 1.0;
break;
default:
g_warn_if_reached ();
break;
}
}
}
/**
* _st_set_text_from_style:
* @text: Target #ClutterText

View File

@@ -45,11 +45,6 @@ G_END_DECLS
ClutterActor *_st_widget_get_dnd_clone (StWidget *widget);
void _st_get_align_factors (StAlign x_align,
StAlign y_align,
gdouble *x_align_out,
gdouble *y_align_out);
void _st_actor_get_preferred_width (ClutterActor *actor,
gfloat for_height,
gboolean y_fill,

View File

@@ -257,8 +257,8 @@ st_table_homogeneous_allocate (ClutterActor *self,
row_span = meta->row_span;
col_span = meta->col_span;
_st_get_align_factors (meta->x_align, meta->y_align,
&x_align_f, &y_align_f);
st_get_align_factors (meta->x_align, meta->y_align,
&x_align_f, &y_align_f);
if (ltr)
{
@@ -609,8 +609,8 @@ st_table_preferred_allocate (ClutterActor *self,
row_span = meta->row_span;
col_span = meta->col_span;
_st_get_align_factors (meta->x_align, meta->y_align,
&x_align_f, &y_align_f);
st_get_align_factors (meta->x_align, meta->y_align,
&x_align_f, &y_align_f);
/* initialise the width and height */
col_width = col_widths[col];

View File

@@ -1268,8 +1268,7 @@ st_theme_node_prerender_background (StThemeNode *node,
return texture;
}
static void st_theme_node_paint_borders (StThemeNode *node,
StThemeNodePaintState *state,
static void st_theme_node_paint_borders (StThemeNodePaintState *state,
const ClutterActorBox *box,
guint8 paint_opacity);
@@ -1370,9 +1369,11 @@ st_theme_node_load_background_image (StThemeNode *node)
return node->background_texture != COGL_INVALID_HANDLE;
}
static void st_theme_node_prerender_shadow (StThemeNodePaintState *state);
static void
st_theme_node_render_resources (StThemeNode *node,
StThemeNodePaintState *state,
st_theme_node_render_resources (StThemeNodePaintState *state,
StThemeNode *node,
float width,
float height)
{
@@ -1390,6 +1391,7 @@ st_theme_node_render_resources (StThemeNode *node,
*/
st_theme_node_paint_state_free (state);
st_theme_node_paint_state_set_node (state, node);
state->alloc_width = width;
state->alloc_height = height;
@@ -1474,40 +1476,82 @@ st_theme_node_render_resources (StThemeNode *node,
state->box_shadow_material = _st_create_shadow_material (box_shadow_spec,
state->prerendered_texture);
else if (node->background_color.alpha > 0 || has_border)
st_theme_node_prerender_shadow (state);
}
/* If we don't have cached textures yet, check whether we can cache
them. */
if (!node->cached_textures)
{
if (state->prerendered_material == COGL_INVALID_HANDLE &&
width >= node->box_shadow_min_width &&
height >= node->box_shadow_min_height)
{
CoglHandle buffer, offscreen;
int texture_width = ceil (width);
int texture_height = ceil (height);
buffer = cogl_texture_new_with_size (texture_width,
texture_height,
COGL_TEXTURE_NO_SLICING,
COGL_PIXEL_FORMAT_ANY);
offscreen = cogl_offscreen_new_to_texture (buffer);
if (offscreen != COGL_INVALID_HANDLE)
{
ClutterActorBox box = { 0, 0, width, height };
CoglColor clear_color;
cogl_push_framebuffer (offscreen);
cogl_ortho (0, width, height, 0, 0, 1.0);
cogl_color_set_from_4ub (&clear_color, 0, 0, 0, 0);
cogl_clear (&clear_color, COGL_BUFFER_BIT_COLOR);
st_theme_node_paint_borders (node, state, &box, 0xFF);
cogl_pop_framebuffer ();
cogl_handle_unref (offscreen);
state->box_shadow_material = _st_create_shadow_material (box_shadow_spec,
buffer);
}
cogl_handle_unref (buffer);
st_theme_node_paint_state_copy (&node->cached_state, state);
node->cached_textures = TRUE;
}
}
}
static void
st_theme_node_update_resources (StThemeNodePaintState *state,
StThemeNode *node,
float width,
float height)
{
gboolean had_prerendered_texture = FALSE;
gboolean had_box_shadow = FALSE;
StShadow *box_shadow_spec;
g_return_if_fail (width > 0 && height > 0);
/* Free handles we can't reuse */
if (state->prerendered_texture != COGL_INVALID_HANDLE)
{
cogl_handle_unref (state->prerendered_texture);
state->prerendered_texture = COGL_INVALID_HANDLE;
had_prerendered_texture = TRUE;
}
if (state->prerendered_material != COGL_INVALID_HANDLE)
{
cogl_handle_unref (state->prerendered_material);
state->prerendered_material = COGL_INVALID_HANDLE;
if (node->border_slices_texture == COGL_INVALID_HANDLE &&
state->box_shadow_material != COGL_INVALID_HANDLE)
{
cogl_handle_unref (state->box_shadow_material);
state->box_shadow_material = COGL_INVALID_HANDLE;
had_box_shadow = TRUE;
}
}
st_theme_node_paint_state_set_node (state, node);
state->alloc_width = width;
state->alloc_height = height;
box_shadow_spec = st_theme_node_get_box_shadow (node);
if (had_prerendered_texture)
{
state->prerendered_texture = st_theme_node_prerender_background (node, width, height);
state->prerendered_material = _st_create_texture_material (state->prerendered_texture);
}
else
{
int corner_id;
for (corner_id = 0; corner_id < 4; corner_id++)
if (state->corner_material[corner_id] == COGL_INVALID_HANDLE)
state->corner_material[corner_id] =
st_theme_node_lookup_corner (node, width, height, corner_id);
}
if (had_box_shadow)
state->box_shadow_material = _st_create_shadow_material (box_shadow_spec,
state->prerendered_texture);
}
static void
paint_material_with_opacity (CoglHandle material,
ClutterActorBox *box,
@@ -1527,11 +1571,11 @@ paint_material_with_opacity (CoglHandle material,
}
static void
st_theme_node_paint_borders (StThemeNode *node,
StThemeNodePaintState *state,
st_theme_node_paint_borders (StThemeNodePaintState *state,
const ClutterActorBox *box,
guint8 paint_opacity)
{
StThemeNode *node = state->node;
float width, height;
int border_width[4];
guint border_radius[4];
@@ -1792,6 +1836,353 @@ st_theme_node_paint_borders (StThemeNode *node,
}
}
static void
st_theme_node_paint_sliced_shadow (StThemeNodePaintState *state,
const ClutterActorBox *box,
guint8 paint_opacity)
{
StThemeNode *node = state->node;
guint border_radius[4];
CoglColor color;
StShadow *box_shadow_spec;
gfloat xoffset, yoffset;
gfloat width, height;
gfloat shadow_width, shadow_height;
gfloat xend, yend, top, bottom, left, right;
gfloat s_top, s_bottom, s_left, s_right;
gfloat shadow_blur_radius, x_spread_factor, y_spread_factor;
float rectangles[8 * 9];
gint idx;
if (paint_opacity == 0)
return;
st_theme_node_reduce_border_radius (node, box->x2 - box->x1, box->y2 - box->y1, border_radius);
box_shadow_spec = st_theme_node_get_box_shadow (node);
/* Compute input & output areas :
*
* yoffset ----------------------------
* | | | |
* | | | |
* | | | |
* top ----------------------------
* | | | |
* | | | |
* | | | |
* bottom ----------------------------
* | | | |
* | | | |
* | | | |
* yend ----------------------------
* xoffset left right xend
*
* s_top = top in offscreen's coordinates (0.0 - 1.0)
* s_bottom = bottom in offscreen's coordinates (0.0 - 1.0)
* s_left = left in offscreen's coordinates (0.0 - 1.0)
* s_right = right in offscreen's coordinates (0.0 - 1.0)
*/
if (box_shadow_spec->blur == 0)
shadow_blur_radius = 0;
else
shadow_blur_radius = (5 * (box_shadow_spec->blur / 2.0)) / 2;
shadow_width = state->box_shadow_width + 2 * shadow_blur_radius;
shadow_height = state->box_shadow_height + 2 * shadow_blur_radius;
/* Compute input regions parameters */
s_top = shadow_blur_radius + box_shadow_spec->blur +
MAX (node->border_radius[ST_CORNER_TOPLEFT],
node->border_radius[ST_CORNER_TOPRIGHT]);
s_bottom = shadow_blur_radius + box_shadow_spec->blur +
MAX (node->border_radius[ST_CORNER_BOTTOMLEFT],
node->border_radius[ST_CORNER_BOTTOMRIGHT]);
s_left = shadow_blur_radius + box_shadow_spec->blur +
MAX (node->border_radius[ST_CORNER_TOPLEFT],
node->border_radius[ST_CORNER_BOTTOMLEFT]);
s_right = shadow_blur_radius + box_shadow_spec->blur +
MAX (node->border_radius[ST_CORNER_TOPRIGHT],
node->border_radius[ST_CORNER_BOTTOMRIGHT]);
/* Compute output regions parameters */
xoffset = box->x1 + box_shadow_spec->xoffset - shadow_blur_radius - box_shadow_spec->spread;
yoffset = box->y1 + box_shadow_spec->yoffset - shadow_blur_radius - box_shadow_spec->spread;
width = box->x2 - box->x1 + 2 * shadow_blur_radius;
height = box->y2 - box->y1 + 2 * shadow_blur_radius;
x_spread_factor = (width + 2 * box_shadow_spec->spread) / width;
y_spread_factor = (height + 2 * box_shadow_spec->spread) / height;
width += 2 * box_shadow_spec->spread;
height += 2 * box_shadow_spec->spread;
xend = xoffset + width;
yend = yoffset + height;
top = s_top * y_spread_factor;
bottom = s_bottom * y_spread_factor;
left = s_left * x_spread_factor;
right = s_right * x_spread_factor;
bottom = height - bottom;
right = width - right;
/* Final adjustments */
s_top /= shadow_height;
s_bottom /= shadow_height;
s_left /= shadow_width;
s_right /= shadow_width;
s_bottom = 1.0 - s_bottom;
s_right = 1.0 - s_right;
top += yoffset;
bottom += yoffset;
left += xoffset;
right += xoffset;
/* Setup pipeline */
cogl_color_set_from_4ub (&color,
box_shadow_spec->color.red * paint_opacity / 255,
box_shadow_spec->color.green * paint_opacity / 255,
box_shadow_spec->color.blue * paint_opacity / 255,
box_shadow_spec->color.alpha * paint_opacity / 255);
cogl_color_premultiply (&color);
cogl_material_set_layer_combine_constant (state->box_shadow_material, 0, &color);
cogl_set_source (state->box_shadow_material);
idx = 0;
if (top > 0)
{
if (left > 0)
{
/* Top left corner */
rectangles[idx++] = xoffset;
rectangles[idx++] = yoffset;
rectangles[idx++] = left;
rectangles[idx++] = top;
rectangles[idx++] = 0;
rectangles[idx++] = 0;
rectangles[idx++] = s_left;
rectangles[idx++] = s_top;
}
/* Top middle */
rectangles[idx++] = left;
rectangles[idx++] = yoffset;
rectangles[idx++] = right;
rectangles[idx++] = top;
rectangles[idx++] = s_left;
rectangles[idx++] = 0;
rectangles[idx++] = s_right;
rectangles[idx++] = s_top;
if (right > 0)
{
/* Top right corner */
rectangles[idx++] = right;
rectangles[idx++] = yoffset;
rectangles[idx++] = xend;
rectangles[idx++] = top;
rectangles[idx++] = s_right;
rectangles[idx++] = 0;
rectangles[idx++] = 1;
rectangles[idx++] = s_top;
}
}
if (left > 0)
{
/* Left middle */
rectangles[idx++] = xoffset;
rectangles[idx++] = top;
rectangles[idx++] = left;
rectangles[idx++] = bottom;
rectangles[idx++] = 0;
rectangles[idx++] = s_top;
rectangles[idx++] = s_left;
rectangles[idx++] = s_bottom;
}
/* Center middle */
rectangles[idx++] = left;
rectangles[idx++] = top;
rectangles[idx++] = right;
rectangles[idx++] = bottom;
rectangles[idx++] = s_left;
rectangles[idx++] = s_top;
rectangles[idx++] = s_right;
rectangles[idx++] = s_bottom;
if (right > 0)
{
/* Right middle */
rectangles[idx++] = right;
rectangles[idx++] = top;
rectangles[idx++] = xend;
rectangles[idx++] = bottom;
rectangles[idx++] = s_right;
rectangles[idx++] = s_top;
rectangles[idx++] = 1;
rectangles[idx++] = s_bottom;
}
if (bottom > 0)
{
if (left > 0)
{
/* Bottom left corner */
rectangles[idx++] = xoffset;
rectangles[idx++] = bottom;
rectangles[idx++] = left;
rectangles[idx++] = yend;
rectangles[idx++] = 0;
rectangles[idx++] = s_bottom;
rectangles[idx++] = s_left;
rectangles[idx++] = 1;
}
/* Bottom middle */
rectangles[idx++] = left;
rectangles[idx++] = bottom;
rectangles[idx++] = right;
rectangles[idx++] = yend;
rectangles[idx++] = s_left;
rectangles[idx++] = s_bottom;
rectangles[idx++] = s_right;
rectangles[idx++] = 1;
if (right > 0)
{
/* Bottom right corner */
rectangles[idx++] = right;
rectangles[idx++] = bottom;
rectangles[idx++] = xend;
rectangles[idx++] = yend;
rectangles[idx++] = s_right;
rectangles[idx++] = s_bottom;
rectangles[idx++] = 1;
rectangles[idx++] = 1;
}
}
cogl_rectangles_with_texture_coords (rectangles, idx / 8);
#if 0
/* Visual feedback on shadow's 9-slice and orignal offscreen buffer,
for debug purposes */
cogl_rectangle (xend, yoffset, xend + shadow_width, yoffset + shadow_height);
cogl_set_source_color4ub (0xff, 0x0, 0x0, 0xff);
cogl_rectangle (xoffset, top, xend, top + 1);
cogl_rectangle (xoffset, bottom, xend, bottom + 1);
cogl_rectangle (left, yoffset, left + 1, yend);
cogl_rectangle (right, yoffset, right + 1, yend);
cogl_rectangle (xend, yoffset, xend + shadow_width, yoffset + 1);
cogl_rectangle (xend, yoffset + shadow_height, xend + shadow_width, yoffset + shadow_height + 1);
cogl_rectangle (xend, yoffset, xend + 1, yoffset + shadow_height);
cogl_rectangle (xend + shadow_width, yoffset, xend + shadow_width + 1, yoffset + shadow_height);
s_top *= shadow_height;
s_bottom *= shadow_height;
s_left *= shadow_width;
s_right *= shadow_width;
cogl_rectangle (xend, yoffset + s_top, xend + shadow_width, yoffset + s_top + 1);
cogl_rectangle (xend, yoffset + s_bottom, xend + shadow_width, yoffset + s_bottom + 1);
cogl_rectangle (xend + s_left, yoffset, xend + s_left + 1, yoffset + shadow_height);
cogl_rectangle (xend + s_right, yoffset, xend + s_right + 1, yoffset + shadow_height);
#endif
}
static void
st_theme_node_prerender_shadow (StThemeNodePaintState *state)
{
StThemeNode *node = state->node;
guint border_radius[4];
int max_borders[4];
int center_radius, corner_id;
CoglHandle buffer, offscreen;
/* Get infos from the node */
if (state->alloc_width < node->box_shadow_min_width ||
state->alloc_height < node->box_shadow_min_height)
st_theme_node_reduce_border_radius (node, state->alloc_width, state->alloc_height, border_radius);
else
for (corner_id = 0; corner_id < 4; corner_id++)
border_radius[corner_id] = node->border_radius[corner_id];
/* Compute maximum borders sizes */
max_borders[ST_SIDE_TOP] = MAX (node->border_radius[ST_CORNER_TOPLEFT],
node->border_radius[ST_CORNER_TOPRIGHT]);
max_borders[ST_SIDE_BOTTOM] = MAX (node->border_radius[ST_CORNER_BOTTOMLEFT],
node->border_radius[ST_CORNER_BOTTOMRIGHT]);
max_borders[ST_SIDE_LEFT] = MAX (node->border_radius[ST_CORNER_TOPLEFT],
node->border_radius[ST_CORNER_BOTTOMLEFT]);
max_borders[ST_SIDE_RIGHT] = MAX (node->border_radius[ST_CORNER_TOPRIGHT],
node->border_radius[ST_CORNER_BOTTOMRIGHT]);
center_radius = (node->box_shadow->blur > 0) ? (2 * node->box_shadow->blur + 1) : 1;
node->box_shadow_min_width = max_borders[ST_SIDE_LEFT] + max_borders[ST_SIDE_RIGHT] + center_radius;
node->box_shadow_min_height = max_borders[ST_SIDE_TOP] + max_borders[ST_SIDE_BOTTOM] + center_radius;
if (state->alloc_width < node->box_shadow_min_width ||
state->alloc_height < node->box_shadow_min_height)
{
state->box_shadow_width = state->alloc_width;
state->box_shadow_height = state->alloc_height;
}
else
{
state->box_shadow_width = node->box_shadow_min_width;
state->box_shadow_height = node->box_shadow_min_height;
}
/* Render offscreen */
buffer = cogl_texture_new_with_size (state->box_shadow_width,
state->box_shadow_height,
COGL_TEXTURE_NO_SLICING,
COGL_PIXEL_FORMAT_ANY);
offscreen = cogl_offscreen_new_to_texture (buffer);
if (offscreen != COGL_INVALID_HANDLE)
{
ClutterActorBox box = { 0, 0, state->box_shadow_width, state->box_shadow_height};
CoglColor clear_color;
cogl_push_framebuffer (offscreen);
cogl_ortho (0, state->box_shadow_width, state->box_shadow_height, 0, 0, 1.0);
cogl_color_set_from_4ub (&clear_color, 0, 0, 0, 0);
cogl_clear (&clear_color, COGL_BUFFER_BIT_COLOR);
st_theme_node_paint_borders (state, &box, 0xFF);
cogl_pop_framebuffer ();
cogl_handle_unref (offscreen);
state->box_shadow_material = _st_create_shadow_material (st_theme_node_get_box_shadow (node),
buffer);
}
cogl_handle_unref (buffer);
}
static void
st_theme_node_paint_sliced_border_image (StThemeNode *node,
float width,
@@ -1945,6 +2336,43 @@ st_theme_node_paint_outline (StThemeNode *node,
cogl_rectangles (rects, 4);
}
static gboolean
st_theme_node_needs_new_box_shadow_for_size (StThemeNodePaintState *state,
StThemeNode *node,
float width,
float height)
{
if (!node->rendered_once)
return TRUE;
/* The allocation hasn't changed, no need to recompute a new
box-shadow. */
if (state->alloc_width == width &&
state->alloc_height == height)
return FALSE;
/* If there is no shadow, no need to recompute a new box-shadow. */
if (node->box_shadow_min_width == 0 ||
node->box_shadow_min_height == 0)
return FALSE;
/* If the new size is inferior to the box-shadow minimum size (we
already know the size has changed), we need to recompute the
box-shadow. */
if (width < node->box_shadow_min_width ||
height < node->box_shadow_min_height)
return TRUE;
/* Now checking whether the size of the node has crossed the minimum
box-shadow size boundary, from below to above the minimum size .
If that's the case, we need to recompute the box-shadow */
if (state->alloc_width < node->box_shadow_min_width ||
state->alloc_height < node->box_shadow_min_height)
return TRUE;
return FALSE;
}
void
st_theme_node_paint (StThemeNode *node,
StThemeNodePaintState *state,
@@ -1964,11 +2392,22 @@ st_theme_node_paint (StThemeNode *node,
if (width <= 0 || height <= 0)
return;
if (state->alloc_width != width || state->alloc_height != height)
if (st_theme_node_needs_new_box_shadow_for_size (state, node, width, height))
{
state->node = node;
st_theme_node_render_resources (node, state, width, height);
/* If we had the ability to cache textures on the node, then we
can just copy them over to the paint state and avoid all
rendering. We end up sharing textures a cross different
widgets. */
if (node->rendered_once && node->cached_textures &&
width >= node->box_shadow_min_width && height >= node->box_shadow_min_height)
st_theme_node_paint_state_copy (state, &node->cached_state);
else
st_theme_node_render_resources (state, node, width, height);
node->rendered_once = TRUE;
}
else if (state->alloc_width != width || state->alloc_height != height)
st_theme_node_update_resources (state, node, width, height);
/* Rough notes about the relationship of borders and backgrounds in CSS3;
* see http://www.w3.org/TR/css3-background/ for more accurate details.
@@ -1997,10 +2436,18 @@ st_theme_node_paint (StThemeNode *node,
*/
if (state->box_shadow_material)
_st_paint_shadow_with_opacity (node->box_shadow,
state->box_shadow_material,
&allocation,
paint_opacity);
{
if (state->alloc_width < node->box_shadow_min_width ||
state->alloc_height < node->box_shadow_min_height)
_st_paint_shadow_with_opacity (node->box_shadow,
state->box_shadow_material,
&allocation,
paint_opacity);
else
st_theme_node_paint_sliced_shadow (state,
&allocation,
paint_opacity);
}
if (state->prerendered_material != COGL_INVALID_HANDLE ||
st_theme_node_load_border_image (node))
@@ -2024,7 +2471,7 @@ st_theme_node_paint (StThemeNode *node,
}
else
{
st_theme_node_paint_borders (node, state, box, paint_opacity);
st_theme_node_paint_borders (state, box, paint_opacity);
}
st_theme_node_paint_outline (node, box, paint_opacity);
@@ -2076,8 +2523,9 @@ st_theme_node_paint (StThemeNode *node,
}
}
void
st_theme_node_paint_state_free (StThemeNodePaintState *state)
static void
st_theme_node_paint_state_node_free_internal (StThemeNodePaintState *state,
gboolean unref_node)
{
int corner_id;
@@ -2092,14 +2540,46 @@ st_theme_node_paint_state_free (StThemeNodePaintState *state)
if (state->corner_material[corner_id] != COGL_INVALID_HANDLE)
cogl_handle_unref (state->corner_material[corner_id]);
if (unref_node)
st_theme_node_paint_state_set_node (state, NULL);
st_theme_node_paint_state_init (state);
}
static void
st_theme_node_paint_state_node_freed (StThemeNodePaintState *state)
{
st_theme_node_paint_state_node_free_internal (state, FALSE);
}
void
st_theme_node_paint_state_set_node (StThemeNodePaintState *state, StThemeNode *node)
{
if (state->node)
g_object_weak_unref (G_OBJECT (state->node),
(GWeakNotify) st_theme_node_paint_state_node_freed,
state);
state->node = node;
if (state->node)
g_object_weak_ref (G_OBJECT (state->node),
(GWeakNotify) st_theme_node_paint_state_node_freed,
state);
}
void
st_theme_node_paint_state_free (StThemeNodePaintState *state)
{
st_theme_node_paint_state_node_free_internal (state, TRUE);
}
void
st_theme_node_paint_state_init (StThemeNodePaintState *state)
{
int corner_id;
state->alloc_width = 0;
state->alloc_height = 0;
state->node = NULL;
state->box_shadow_material = COGL_INVALID_HANDLE;
state->prerendered_texture = COGL_INVALID_HANDLE;
@@ -2120,10 +2600,12 @@ st_theme_node_paint_state_copy (StThemeNodePaintState *state,
st_theme_node_paint_state_free (state);
state->node = other->node;
st_theme_node_paint_state_set_node (state, other->node);
state->alloc_width = other->alloc_width;
state->alloc_height = other->alloc_height;
state->box_shadow_width = other->box_shadow_width;
state->box_shadow_height = other->box_shadow_height;
if (other->box_shadow_material)
state->box_shadow_material = cogl_handle_ref (other->box_shadow_material);

View File

@@ -99,12 +99,19 @@ struct _StThemeNode {
guint background_image_shadow_computed : 1;
guint text_shadow_computed : 1;
guint link_type : 2;
guint rendered_once : 1;
guint cached_textures : 1;
int box_shadow_min_width;
int box_shadow_min_height;
CoglHandle border_slices_texture;
CoglHandle border_slices_material;
CoglHandle background_texture;
CoglHandle background_material;
CoglHandle background_shadow_material;
StThemeNodePaintState cached_state;
};
struct _StThemeNodeClass {

View File

@@ -54,6 +54,8 @@ st_theme_node_init (StThemeNode *node)
node->background_shadow_material = COGL_INVALID_HANDLE;
node->border_slices_texture = COGL_INVALID_HANDLE;
node->border_slices_material = COGL_INVALID_HANDLE;
st_theme_node_paint_state_init (&node->cached_state);
}
static void
@@ -101,6 +103,8 @@ st_theme_node_dispose (GObject *gobject)
g_signal_handlers_disconnect_by_func (node->theme,
on_custom_stylesheets_changed, node);
st_theme_node_paint_state_free (&node->cached_state);
g_clear_object (&node->theme);
G_OBJECT_CLASS (st_theme_node_parent_class)->dispose (gobject);

View File

@@ -102,6 +102,9 @@ struct _StThemeNodePaintState {
float alloc_width;
float alloc_height;
float box_shadow_width;
float box_shadow_height;
CoglHandle box_shadow_material;
CoglHandle prerendered_texture;
CoglHandle prerendered_material;
@@ -278,6 +281,8 @@ void st_theme_node_paint_state_free (StThemeNodePaintState *state);
void st_theme_node_paint_state_copy (StThemeNodePaintState *state,
StThemeNodePaintState *other);
void st_theme_node_paint_state_invalidate (StThemeNodePaintState *state);
void st_theme_node_paint_state_set_node (StThemeNodePaintState *state,
StThemeNode *node);
G_END_DECLS

View File

@@ -67,6 +67,8 @@ struct _StWidgetPrivate
gboolean hover : 1;
gboolean can_focus : 1;
gulong texture_file_changed_id;
AtkObject *accessible;
AtkRole accessible_role;
AtkStateSet *local_state_set;
@@ -362,9 +364,11 @@ st_widget_dispose (GObject *gobject)
priv->label_actor = NULL;
}
g_signal_handlers_disconnect_by_func (st_texture_cache_get_default (),
st_widget_texture_cache_changed,
actor);
if (priv->texture_file_changed_id != 0)
{
g_signal_handler_disconnect (st_texture_cache_get_default (), priv->texture_file_changed_id);
priv->texture_file_changed_id = 0;
}
g_clear_object (&priv->prev_first_child);
g_clear_object (&priv->prev_last_child);
@@ -1552,8 +1556,8 @@ st_widget_init (StWidget *actor)
g_signal_connect (actor, "notify::first-child", G_CALLBACK (st_widget_first_child_notify), NULL);
g_signal_connect (actor, "notify::last-child", G_CALLBACK (st_widget_last_child_notify), NULL);
g_signal_connect (st_texture_cache_get_default (), "texture-file-changed",
G_CALLBACK (st_widget_texture_cache_changed), actor);
priv->texture_file_changed_id = g_signal_connect (st_texture_cache_get_default (), "texture-file-changed",
G_CALLBACK (st_widget_texture_cache_changed), actor);
for (i = 0; i < G_N_ELEMENTS (priv->paint_states); i++)
st_theme_node_paint_state_init (&priv->paint_states[i]);
@@ -2881,3 +2885,63 @@ st_widget_get_focus_chain (StWidget *widget)
{
return ST_WIDGET_GET_CLASS (widget)->get_focus_chain (widget);
}
/**
* st_get_align_factors:
* @x_align: an #StAlign
* @y_align: an #StAlign
* @x_align_out: (out) (allow-none): @x_align as a #gdouble
* @y_align_out: (out) (allow-none): @y_align as a #gdouble
*
* Converts @x_align and @y_align to #gdouble values.
*/
void
st_get_align_factors (StAlign x_align,
StAlign y_align,
gdouble *x_align_out,
gdouble *y_align_out)
{
if (x_align_out)
{
switch (x_align)
{
case ST_ALIGN_START:
*x_align_out = 0.0;
break;
case ST_ALIGN_MIDDLE:
*x_align_out = 0.5;
break;
case ST_ALIGN_END:
*x_align_out = 1.0;
break;
default:
g_warn_if_reached ();
break;
}
}
if (y_align_out)
{
switch (y_align)
{
case ST_ALIGN_START:
*y_align_out = 0.0;
break;
case ST_ALIGN_MIDDLE:
*y_align_out = 0.5;
break;
case ST_ALIGN_END:
*y_align_out = 1.0;
break;
default:
g_warn_if_reached ();
break;
}
}
}

View File

@@ -151,7 +151,6 @@ StThemeNode * st_widget_peek_theme_node (StWidget *widg
GList * st_widget_get_focus_chain (StWidget *widget);
void st_widget_paint_background (StWidget *widget);
/* debug methods */
char *st_describe_actor (ClutterActor *actor);
void st_set_slow_down_factor (gfloat factor);
@@ -169,6 +168,12 @@ void st_widget_set_accessible_name (StWidget *widget,
const gchar *name);
const gchar * st_widget_get_accessible_name (StWidget *widget);
/* utility methods */
void st_get_align_factors (StAlign x_align,
StAlign y_align,
gdouble *x_align_out,
gdouble *y_align_out);
G_END_DECLS
#endif /* __ST_WIDGET_H__ */

View File

@@ -8,6 +8,7 @@ TEST_JS = \
interactive/border-radius.js \
interactive/border-width.js \
interactive/box-layout.js \
interactive/box-shadow-animated.js \
interactive/box-shadows.js \
interactive/calendar.js \
interactive/css-fonts.js \

View File

@@ -45,12 +45,6 @@ function test() {
style: 'border: 1px solid #aaaaaa; '
+ 'background: #cceeff' }));
b2.add(new St.Label({ x: 50,
y: 50,
text: "Fixed",
style: 'border: 1px solid #aaaaaa;'
+ 'background: #ffffcc' }));
////////////////////////////////////////////////////////////////////////////////
function createCollapsableBox(width) {

View File

@@ -0,0 +1,84 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Clutter = imports.gi.Clutter;
const St = imports.gi.St;
const Mainloop = imports.mainloop;
const GLib = imports.gi.GLib;
const Lang = imports.lang;
const UI = imports.testcommon.ui;
const DELAY = 2000;
function resize_animated(label) {
if (label.width == 100) {
label.save_easing_state();
label.set_easing_mode(Clutter.AnimationMode.EASE_OUT_QUAD);
label.set_easing_duration(DELAY - 50);
label.set_size(500, 500);
label.restore_easing_state();
} else {
label.save_easing_state();
label.set_easing_mode(Clutter.AnimationMode.EASE_OUT_QUAD);
label.set_easing_duration(DELAY - 50);
label.set_size(100, 100);
label.restore_easing_state();
}
}
function get_css_style(shadow_style)
{
return 'border: 20px solid black;' +
'border-radius: 20px;' +
'background-color: white; ' +
'padding: 5px;' + shadow_style;
}
function test() {
let stage = new Clutter.Stage({ width: 1000, height: 600 });
UI.init(stage);
let iter = 0;
let shadowStyles = [ 'box-shadow: 3px 50px 0px 4px rgba(0,0,0,0.5);',
'box-shadow: 3px 4px 10px 4px rgba(0,0,0,0.5);',
'box-shadow: 0px 50px 0px 0px rgba(0,0,0,0.5);',
'box-shadow: 100px 100px 20px 4px rgba(0,0,0,0.5);'];
let label1 = new St.Label({ style: get_css_style(shadowStyles[iter]),
text: shadowStyles[iter],
x: 20,
y: 20,
width: 100,
height: 100
});
stage.add_actor(label1);
let label2 = new St.Label({ style: get_css_style(shadowStyles[iter]),
text: shadowStyles[iter],
x: 500,
y: 20,
width: 100,
height: 100
});
stage.add_actor(label2);
resize_animated(label1);
resize_animated(label2);
Mainloop.timeout_add(DELAY, Lang.bind(this, function() {
log(label1 + label1.get_size());
resize_animated(label1);
resize_animated(label2);
return true;
}));
Mainloop.timeout_add(2 * DELAY, Lang.bind(this, function() {
iter += 1;
iter %= shadowStyles.length;
label1.set_style(get_css_style(shadowStyles[iter]));
label1.set_text(shadowStyles[iter]);
label2.set_style(get_css_style(shadowStyles[iter]));
label2.set_text(shadowStyles[iter]);
return true;
}));
UI.main(stage);
}
test();