Compare commits

...

92 Commits

Author SHA1 Message Date
6e448a2711 ScreenShield: fix spacing of notifications and sources
Reduce padding around persistent sources, and ensure that spacing
around resident notifications is only applied once.
Also, add some padding to the clock.

https://bugzilla.gnome.org/show_bug.cgi?id=681143
2012-08-06 21:43:54 +02:00
1d484e2278 ScreenSheild: make notification view scrollable
Place a maximum height on the notification view, and show scrollbars
if the list of persistent sources would overflow.

https://bugzilla.gnome.org/show_bug.cgi?id=681143
2012-08-06 21:43:54 +02:00
0b7ca098ad ScreenShield: update the displayed title when the source changes
Notifications in the lock screen need to watch signals on source
and react accordingly.

https://bugzilla.gnome.org/show_bug.cgi?id=681143
2012-08-06 21:43:54 +02:00
5cb9aa9cf3 messageTray: Hook SourceActor up to source icon changes automatically
Instead of manually tracking source icon changes, or requiring a manual
call to _setSummaryIcon, add a way to emit a signal when we're guaranteed
the icon has been changed, and then the source actor will automatically
update the icon.
_setSummaryIcon is still available for sources such as the notification
daemon, that require special treatment for the summary icon (to be used
with tray icons)

https://bugzilla.gnome.org/show_bug.cgi?id=680426
2012-08-06 21:43:54 +02:00
0171e561f2 ScreenShield: bump the lock screen slightly when pressing a key
When pressing a key different from escape (one thus that has no
effect), bump the screen up, to indicate that it eats keyboard
input and it must be lifted up.

https://bugzilla.gnome.org/show_bug.cgi?id=681143
2012-08-06 21:43:54 +02:00
82f7431a28 ScreenShield: handle Escape on the stage, not on the lock screen
This allows to press esc to unlock even if the focus is not on
the lock screen (for example after dismissing the auth failure
notification).

https://bugzilla.gnome.org/show_bug.cgi?id=681143
2012-08-06 21:43:54 +02:00
29958df7e7 ScreenShield: when explicitly locking, tween the shield from the top
The curtain should appear to be an overlay on top of the system,
and since it is lifted by dragging up, it makes sense to slide it
down on lock.

https://bugzilla.gnome.org/show_bug.cgi?id=681143
2012-08-06 21:43:54 +02:00
2f990346df ScreenShield: blur and desaturate the screenshield background
The background is the same as the normal desktop, so we blur and
desaturate it to clearly show that it's not the normal system state.

Includes a noticeable slowdown due to GLSL shading and FBO redirection.

https://bugzilla.gnome.org/show_bug.cgi?id=681143
2012-08-06 21:43:54 +02:00
a29ceaa8ec ScreenShield: lower the autodrag threshold to 10%
The threshold is there just to ensure that the user is opening
the curtain on purpose. Requiring 40% is too much for that.

https://bugzilla.gnome.org/show_bug.cgi?id=681143
2012-08-06 21:43:54 +02:00
782e11b96c Remove markup from translated strings
Including the markup in the string makes the translators job
unnecessarily harder.

https://bugzilla.gnome.org/show_bug.cgi?id=681270
2012-08-06 11:59:14 -04:00
fd3be5b7de build: Fix distcheck
I knew it had to be something simple ...
2012-08-06 16:13:54 +02:00
0b9a5c3441 build: Add noise-texture.png 2012-08-06 16:13:37 +02:00
7431c4d611 magnifier: Using properly 'color-saturation'
As description of the setting says, color-saturation ranges from
0.0 (grayscale) to 1.0 (full color), but the real outcome was the
opposite. The reason is that clutter provides a desaturation effect,
and color-saturation was passed directly to that effect. This patch
renames the effect and compute the desaturation value.
2012-08-06 13:02:42 +02:00
ec78dd60fc magnifier: 'color-saturation' is a double not a boolean 2012-08-06 13:02:42 +02:00
b479eec758 Updated Persian translations 2012-08-05 00:12:35 +04:30
413ace2eb1 UnlockDialog: allow going back to the lock screen by pressing escape
https://bugzilla.gnome.org/show_bug.cgi?id=681143
2012-08-03 19:54:48 +02:00
d8390ef77f autorunManager: Remove line that sets summary icon
MessageTray does this automatically for us now.

https://bugzilla.gnome.org/show_bug.cgi?id=680426
2012-08-03 14:26:31 -03:00
e7e56e175a boxpointer: Cope with a missing -arrow-border-color when we have no border
https://bugzilla.gnome.org/show_bug.cgi?id=680426
2012-08-03 14:26:24 -03:00
e875b9cdca status: Clean up imports
https://bugzilla.gnome.org/show_bug.cgi?id=680426
2012-08-03 14:25:35 -03:00
66197b18b6 lookingGlass: Don't pass too many arguments to Clutter.ungrab_*
https://bugzilla.gnome.org/show_bug.cgi?id=680426
2012-08-03 14:25:35 -03:00
ed991f79b1 theme: Use the noise texture for the background of the screen shield
https://bugzilla.gnome.org/show_bug.cgi?id=681143
2012-08-03 14:00:48 -03:00
48b70f358d GdmUtil: don't call GetUserVerifier from the user session
GetUserVerifier can only be called from the greeter session,
and fails with AccessDenied in all other cases. Also, calling it
hides the real error from OpenReauthenticationChannel, which
instead should be logged.

https://bugzilla.gnome.org/show_bug.cgi?id=680750
2012-08-03 18:06:10 +02:00
56adbda2dc build: Add missing file to Makefile 2012-08-03 17:41:56 +02:00
7dbc78c95f st-theme-node: Add repeating backgrounds
Add support for the CSS "background-repeat" property. Currently, this
only supports on/off, rather than allowing tiling in each individual
dimension. It is supported for both the cogl and cairo rendering paths.

https://bugzilla.gnome.org/show_bug.cgi?id=680801
2012-08-03 12:27:20 -03:00
3ffa1e35e8 st-theme-node: Clean up
Replace some faulty indentation, group some booleans to reduce
a bit of memory usage

https://bugzilla.gnome.org/show_bug.cgi?id=680801
2012-08-03 12:27:20 -03:00
114fb4219b tests: Fix borders test
Bad merge

https://bugzilla.gnome.org/show_bug.cgi?id=680801
2012-08-03 12:27:20 -03:00
4d7d66bc1f polkit: Improve styling in polkit dialog
Center the "Password:" label, and add a bit more spacing
2012-08-03 12:22:32 -03:00
e134d2e5a5 theme: Reformat
Put braces on the same lines as the selectors
2012-08-03 12:22:32 -03:00
cca84761a5 theme: Improve legibility of date and time in the lock screen
Adjust the drop shadow to make the date and time easier to read.
2012-08-03 12:22:22 -03:00
c2a5d6f61b theme: Update the look of scrollbars
Make the scrollbars consistent with those in Gtk.
2012-08-03 12:22:12 -03:00
4449007bb4 theme: Common style for entries
This improves the style of the password entry fields and makes them
consistent with entry fields in the overview and chat notifications.
2012-08-03 12:22:08 -03:00
30cd1e84bc theme: Fix unlock button colors
The colors for the new button were far too brash. This makes them
consistent with the mockups.
2012-08-03 12:22:04 -03:00
dcf872b485 js: Remove StatusIconDispatcher
With IBus in the top panel, we don't need it any more

https://bugzilla.gnome.org/show_bug.cgi?id=680800
2012-08-03 11:51:53 -03:00
c9d51ca775 Assamese translation updated 2012-08-03 15:20:28 +05:30
96c9f8058b loginDialog: Indicate whether users are logged in
Unlike the fallback gdm UI, we do not indicate in the user list
whether a user already has an open session or not. This information
is useful, so use a spotlight effect similar to the running-app
indicator to mark logged in users.

https://bugzilla.gnome.org/show_bug.cgi?id=658185
2012-08-01 22:20:35 +02:00
a3f4bca14e loginDialog: Add an :expanded pseudo class to the user list
We want to style user list items differently depending on whether
the list is expanded or shrunk; instead of manually updating the
items' style, we can just expose the :expanded style on the list
itself and use that in the CSS.

https://bugzilla.gnome.org/show_bug.cgi?id=658185
2012-08-01 22:20:35 +02:00
e55f2dd3b9 Updated Russian translation 2012-08-01 23:58:25 +04:00
247566ca1d st-scroll-bar: Fix build warnings
Introduced by commit aa120e0902
2012-08-01 17:38:45 +02:00
aa120e0902 st-scroll-bar: Add support for :active
Add the :active pseudo class to the handle while it is dragged.

https://bugzilla.gnome.org/show_bug.cgi?id=680974
2012-08-01 14:53:48 +02:00
5c7992beef loginDialog: Tweak automatic scroll animation
The current animation time of two seconds may result in some
confusion, as the reason of the behavior only becomes apprent
when the auto-activating item becomes visible; make the animation
a lot faster and ease it out a bit.

https://bugzilla.gnome.org/show_bug.cgi?id=660913
2012-07-31 17:50:52 +02:00
6a615f30dc gdm: Adjust timed-login indicator
Until the recent style changes, the same element was used to indicate
both item focus and progress for timed logins. As focus is now indicated
by the item's background style, rename the indicator from focusBin to
timedLoginIndicator and make some minor adjustments to better fit the
new style:
  - move it next to the icon below the text
  - give it a white color and a shadow
  - update animation to grow from the left instead of the center

https://bugzilla.gnome.org/show_bug.cgi?id=660913
2012-07-31 17:50:52 +02:00
bfea41b771 loginDialog: Update user list style
Rather than changing the text color to indicate hover and an underline
to mark the focused item, use the same semi-transparent white background
as in the overview.

https://bugzilla.gnome.org/show_bug.cgi?id=660913
2012-07-31 17:50:52 +02:00
a2465e0670 bluetooth: Adapt to GnomeBluetooth API break 2012-07-30 19:15:23 +02:00
57044ea9a0 Updated gujarati file 2012-07-30 12:48:18 +05:30
1392be2952 Updated Galician translations 2012-07-30 03:16:49 +02:00
9e503aa69c Updated Slovenian translation 2012-07-29 14:36:50 +02:00
a004389f25 Updated Hungarian translation by Bence Lukacs <lukacs.bence1 at gmail dot com> 2012-07-29 10:27:18 +02:00
d474261912 Updated Spanish translation 2012-07-27 11:33:32 +02:00
144e959cab Updated Arabic translation 2012-07-26 22:35:00 +02:00
626488e659 Updated Telugu Translation 2012-07-27 00:05:10 +05:30
5bae5574f0 Updated Kazakh translation 2012-07-26 09:32:22 +06:00
ce14d6d9db Updated Norwegian bokmål translation 2012-07-25 13:16:51 +02:00
519addf6ac Updated Hebrew translation. 2012-07-24 22:27:31 +03:00
fd87468e36 util: Fix number of parameters passed to spawn_sync
We passed one too many

https://bugzilla.gnome.org/show_bug.cgi?id=680426
2012-07-24 06:11:21 -03:00
75e49610cb st-theme: Make the custom stylesheets have higher priority
https://bugzilla.gnome.org/show_bug.cgi?id=680426
2012-07-24 06:11:21 -03:00
414fe75d02 st-widget: Move reactivity tracking to StWidget, use "insensitive"
This lets use remove another few pieces of code that do the tracking
manually.

https://bugzilla.gnome.org/show_bug.cgi?id=680426
2012-07-24 06:11:21 -03:00
26031eb761 Updated Greek translation 2012-07-24 12:10:32 +03:00
be801dff5f gdm: Add a missing comma 2012-07-21 14:08:04 -04:00
5fd47ed742 Updated POTFILES.in 2012-07-21 19:13:55 +02:00
f7f2f50435 ShellDBus: export screensaver interface
gnome-session and gnome-settings-daemon rely on the screensaver
interface to know the locked state. Since gnome-screensaver is no
longer running, it's up to gnome-shell to provide it.

https://bugzilla.gnome.org/show_bug.cgi?id=619955
2012-07-21 15:40:29 +02:00
e0bb15e572 Login Dialogs: update styling to match mockups
Remove backgrounds, change button styling, reduce font sizes.

https://bugzilla.gnome.org/show_bug.cgi?id=619955
2012-07-21 15:40:29 +02:00
0e4171a87c Screen Shield: animate manual locking
When the screen shield is activated from the user menu, animate
it instead of showing it abruptly. Also, ensure that the animation
had time to finish before calling UPower to suspend, to avoid
showing it when resuming.

https://bugzilla.gnome.org/show_bug.cgi?id=619955
2012-07-21 15:40:28 +02:00
34cb92ff4c Don't track the status of the screensaver on DBus
We are the screensaver now, and internal objects can track the
locking status better themselves. And to do so, add two signals
to ScreenShield.

https://bugzilla.gnome.org/show_bug.cgi?id=619955
2012-07-21 15:40:28 +02:00
22eea750f3 ScreenShield: show notifications in the locked screen
Track screen lock status in the message tray, and filter banner
notifications. The message tray is completely hidden when the screen is
locked, but exceptions can be made for individual transient notifications,
such as shell messages and the on screen keyboard.
Non transient sources are shown in the middle of the lock screen. Resident
notifications (such as those from Rhythmbox) are shown in full, while
persistent ones are displayed as icon and message count.

https://bugzilla.gnome.org/show_bug.cgi?id=619955
2012-07-21 15:40:28 +02:00
c3afe1a83a Show the panel above the screenshield when locked
Track locked status and use it to provide a reduced version of
the panel in the locked screen. Accessibility, input sources and
volume menus are preserved, without the link to the control center.
Network, battery and user menu are reduced to pure indicators,
with no menu.
This is similar to the design but not exactly, because designers
in IRC said that network needs more analysis before exposing, and
because the design didn't account for a11y and IM (so the one menu
metaphor is not really appropriate).

https://bugzilla.gnome.org/show_bug.cgi?id=619955
2012-07-21 15:40:28 +02:00
904ceba6b2 Add a clock to the lock screen
Start implementing the lock screen design by adding a big white
clock in the middle.

https://bugzilla.gnome.org/show_bug.cgi?id=619955
2012-07-21 15:40:28 +02:00
a28d639c3b Consolidate creation of login and unlock dialog in the screenshield
The design calls for the curtain to appear in the gdm greeter too.
Implement this by having the screenshield manage the login dialog
(delegating its creation to SessionMode).

https://bugzilla.gnome.org/show_bug.cgi?id=619955
2012-07-21 15:40:28 +02:00
c0652bcd8f ScreenShield: implement curtain design
This separates the screen shield into two main screens. One is
the lock screen, and it is shown when coming back from idle status
and when failing authentication. The other is the actual unlock
dialog.
Moving from the first to the second is possible by pressing Escape
or by dragging an arrow on the bottom on the screen.

https://bugzilla.gnome.org/show_bug.cgi?id=619955
2012-07-21 15:40:28 +02:00
54dc0fd123 ScreenShield: use LayoutManager for creating the actor
This ensures that the screen shield is created at the right
stacking level, so the message tray is visible in the lock screen
(showing PAM messages, critical notifications and the on screen
keyboard)

https://bugzilla.gnome.org/show_bug.cgi?id=619955
2012-07-21 15:40:28 +02:00
c22a00afee ScreenShield: improve locking/modal policy
Ensure that the lightbox is above everything (including the screenlock
itself) when fading in - this allows for fading while showing the
unlock dialog. Also, don't pushModal again when already locked, or
we won't get out of it.

https://bugzilla.gnome.org/show_bug.cgi?id=619955
2012-07-21 15:40:28 +02:00
2c3ec7846f Add UnlockDialog for unlocking the screen shield
When the screenshield is deactivated, instead of going back to the
session immediately, prompt the user for authentication.
This essentially reinstates what used to be provided by gnome-screensaver.

https://bugzilla.gnome.org/show_bug.cgi?id=619955
2012-07-21 15:40:28 +02:00
46db9edacc Split some common code out of gdm/loginDialog
This will be reused by session unlocking.

https://bugzilla.gnome.org/show_bug.cgi?id=619955
2012-07-21 15:40:28 +02:00
4e6fa56c87 screenShield: add initial functionality
We are replacing the gnome-screensaver module with with a screen shield
that is part of gnome-shell.

This patch fades out the screen on idle and shows a shield with a background
image when there is activity again. The shield can be removed with a key or
button press.

https://bugzilla.gnome.org/show_bug.cgi?id=619955
2012-07-21 15:40:28 +02:00
8970e17911 ModalDialog: add 'default' pseudo-class to default button
Add 'default' parameter to setButtons, that controls the binding
of Return (unless overridden) and applies the 'default' pseudo-class.
Currently it has no effect, but it will start having after the
login dialog redesign.

https://bugzilla.gnome.org/show_bug.cgi?id=619955
2012-07-21 15:40:28 +02:00
ac6c808124 MessageTray: rework icon handling to split model and view
To allow more than one summary icon actor for a source we split
the model of the source icon (which is iconName, if the default
implementation is used, or a GIcon otherwise) and replace
createNotificationIcon() with a generic createIcon(size). Also,
the actual source actor is split into a separate class, that handles
the notification counter automatically.

https://bugzilla.gnome.org/show_bug.cgi?id=619955
2012-07-21 15:40:28 +02:00
26d3b1929e St: don't attempt to give focus to non reactive actors
Non reactive actors don't expect to be interacted with, and thus
should not get keyboard focus.

https://bugzilla.gnome.org/show_bug.cgi?id=619955
2012-07-21 15:40:28 +02:00
a29507e452 St: add :disabled pseudo class when a button is not reactive
The :reactive property is used on StButton to like the :sensitive
property on GtkWidgets, that is, to indicate that the user is not
(yet) expected to click the button, and therefore should affect
styling too.
This allows to remove some code at the JS layer.

https://bugzilla.gnome.org/show_bug.cgi?id=619955
2012-07-21 15:40:28 +02:00
2c073fb005 UserMenu: split user avatar into its own widget
This way, it can be reused in the lock screen without code duplication.

https://bugzilla.gnome.org/show_bug.cgi?id=619955
2012-07-21 15:40:28 +02:00
d9c3b83d1e Panel: fix finding leftmost and rightmost buttons
Previous code would access the array element before checking that
the index was within bounds, and therefore cause a TypeError.
It wasn't noticed earlier because at least one visible children
is in each panel box in all session modes.

https://bugzilla.gnome.org/show_bug.cgi?id=619955
2012-07-21 15:40:27 +02:00
f5e58c500f Modal stack: fix handling of destroyed actors
Destroyed modal actors should be completely removed from the modal
stack automatically, including leaving modality if needed.
This allows for destroying modal dialogs without calling close().

https://bugzilla.gnome.org/show_bug.cgi?id=619955
2012-07-21 15:40:27 +02:00
5e865f5bc4 LayoutManager: reverse the visibleInFullscreen flag
Change visibleInFullscreen to be trackFullscreen. If true, visibility
is fully bound to fullscreen status, if false, no change is made.
This allows to avoid set_skip_paint(), while not messing with
visibility of actors that are sometimes hidden for other reasons.
The flag was reversed because only the panel uses it, so false is
a more useful default.

https://bugzilla.gnome.org/show_bug.cgi?id=619955
2012-07-21 15:40:27 +02:00
01a1255967 ShellEntry: make isPassword param changeable at runtime
Make it possible to control the visibility of "Show/hide text" item
at runtime, to reuse the same entry for both password and non-password
prompts.

https://bugzilla.gnome.org/show_bug.cgi?id=619955
2012-07-21 15:40:27 +02:00
dd80f39049 js: Spurious fixes for cases where we pass extra arguments
https://bugzilla.gnome.org/show_bug.cgi?id=680216
2012-07-19 11:01:03 -04:00
19e4c953ef js: Don't pass extra arguments to add_actor
It's clear that this was supposed to be passed to our own 'add' monkey
patch, but we missed. Remove the ignored arguments.

https://bugzilla.gnome.org/show_bug.cgi?id=680216
2012-07-19 11:01:03 -04:00
ef218c95fc Updated Slovenian translation 2012-07-19 10:10:55 +02:00
eec9dba855 data: Enable translations for desktop files
We were never localizing .desktop files, apparently.

https://bugzilla.gnome.org/show_bug.cgi?id=677893
2012-07-18 20:09:04 -04:00
f46a165886 loginDialog: Scale focusBin instead of resizing it
When setting an explicit size as we do currently, rounding errors
(for instance introduced by padding not specified in pixels) may
affect the parent's size allocation, e.g. making it shrink or grow
each time the size is reset.
Rather than taking care of possible rounding errors, set up focusBin
to take up the available width and use scaling for the animation.

https://bugzilla.gnome.org/show_bug.cgi?id=675076
2012-07-18 23:56:54 +02:00
ec47bd1604 build: Require gsettings-desktop-schemas >= 3.5.4
org.gnome.desktop.a11y.magnifier.color-saturation was shipped in
gsettings-desktop-schemas >=3.5.4

https://bugzilla.gnome.org/show_bug.cgi?id=680170
2012-07-18 09:20:25 -04:00
bfd4016c1c boxpointer style updates
Style updates to match current mockups. Give panel menus a
opaque black background, remove the border from notification
boxpointers and give them a bigger pointer.
2012-07-17 23:04:54 +01:00
63cdb1848e improve calendar layout and legibitily
This fixes some alignment issues with the calendar
events pane. It also makes some legitibility improvements
by using bigger fonts and clearer colors.
2012-07-17 23:04:24 +01:00
10a0762fe7 extensionPrefs: Fix
We accidentally broke two things here when overhauling the
extensions system.

https://bugzilla.gnome.org/show_bug.cgi?id=680064
2012-07-17 12:14:02 -04:00
76472b86ed util: Remove unused imports
https://bugzilla.gnome.org/show_bug.cgi?id=679944
2012-07-17 12:14:02 -04:00
86 changed files with 6877 additions and 5429 deletions

View File

@ -120,7 +120,7 @@ PKG_CHECK_MODULES(GNOME_SHELL_JS, gio-2.0 gjs-internals-1.0 >= $GJS_MIN_VERSION)
PKG_CHECK_MODULES(ST, clutter-1.0 gtk+-3.0 libcroco-0.6 >= 0.6.2 x11)
PKG_CHECK_MODULES(TRAY, gtk+-3.0)
PKG_CHECK_MODULES(GVC, libpulse libpulse-mainloop-glib gobject-2.0)
PKG_CHECK_MODULES(DESKTOP_SCHEMAS, gsettings-desktop-schemas >= 3.5.1)
PKG_CHECK_MODULES(DESKTOP_SCHEMAS, gsettings-desktop-schemas >= 3.5.4)
AC_MSG_CHECKING([for bluetooth support])
PKG_CHECK_EXISTS([gnome-bluetooth-1.0 >= 3.1.0],

View File

@ -8,9 +8,7 @@ desktop_DATA = gnome-shell.desktop gnome-shell-extension-prefs.desktop
-e "s|@VERSION[@]|$(VERSION)|" \
$< > $@ || rm $@
# Placeholder until we add intltool
%.desktop:%.desktop.in
$(AM_V_GEN) sed s/^_// < $< > $@ || rm $@
@INTLTOOL_DESKTOP_RULE@
searchprovidersdir = $(pkgdatadir)/open-search-providers
dist_searchproviders_DATA = \
@ -36,15 +34,14 @@ dist_theme_DATA = \
theme/dash-placeholder.svg \
theme/filter-selected-ltr.svg \
theme/filter-selected-rtl.svg \
theme/gdm.css \
theme/gnome-shell.css \
theme/logged-in-indicator.svg \
theme/noise-texture.png \
theme/panel-button-border.svg \
theme/panel-button-highlight-narrow.svg \
theme/panel-button-highlight-wide.svg \
theme/process-working.svg \
theme/running-indicator.svg \
theme/scroll-hhandle.svg \
theme/scroll-vhandle.svg \
theme/source-button-border.svg \
theme/toggle-off-us.svg \
theme/toggle-off-intl.svg \

View File

@ -10,11 +10,11 @@
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="28"
height="25"
width="29"
height="29"
id="svg10621"
version="1.1"
inkscape:version="0.48.1 r9760"
inkscape:version="0.48.2 r9819"
sodipodi:docname="calendar-today.svg">
<defs
id="defs10623">
@ -118,6 +118,17 @@
fx="51"
fy="30"
r="42" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient34508-1-3"
id="radialGradient3113"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.72146227,0,0,0.27484277,14.205424,21.754717)"
cx="51"
cy="30"
fx="51"
fy="30"
r="42" />
</defs>
<sodipodi:namedview
id="base"
@ -127,20 +138,29 @@
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:zoom="15.839192"
inkscape:cx="8.3750933"
inkscape:cy="8.0837211"
inkscape:cx="20.652108"
inkscape:cy="11.839084"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
showgrid="true"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
inkscape:window-width="1440"
inkscape:window-height="843"
inkscape:window-width="1280"
inkscape:window-height="741"
inkscape:window-x="0"
inkscape:window-y="26"
inkscape:window-maximized="1" />
inkscape:window-y="27"
inkscape:window-maximized="1"
borderlayer="true">
<inkscape:grid
type="xygrid"
id="grid3109"
empspacing="5"
visible="true"
enabled="true"
snapvisiblegridlinesonly="true" />
</sodipodi:namedview>
<metadata
id="metadata10626">
<rdf:RDF>
@ -157,31 +177,28 @@
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-469.08263,-536.99307)">
<g
id="g3003">
<path
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="/home/jimmac/src/cvs/gnome/gnome-shell-design/mockups/motion/textures/panel.png"
transform="matrix(0.43692393,0,0,1.3783114,460.60467,517.48289)"
sodipodi:end="6.2831853"
sodipodi:start="3.1415927"
d="M 9,29.999999 C 9.0000011,21.163443 27.804042,14 51.000002,14 74.195961,14 93,21.163444 93,30 l -42,0 z"
sodipodi:ry="16"
sodipodi:rx="42"
sodipodi:cy="30"
sodipodi:cx="51"
id="path34506-3"
style="opacity:0.4625;color:#000000;fill:url(#radialGradient2997);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
sodipodi:type="arc" />
<rect
y="558.85046"
x="468.96878"
height="3.1425927"
width="28.149134"
id="rect2996"
style="fill:#ffffff;fill-opacity:0.50196078;stroke-width:0.43599999;stroke-miterlimit:4;stroke-dasharray:none" />
</g>
transform="translate(-469.08263,-532.99307)">
<path
sodipodi:type="arc"
style="opacity:0.4625;color:#000000;fill:url(#radialGradient3113);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="path34506-3"
sodipodi:cx="51"
sodipodi:cy="30"
sodipodi:rx="42"
sodipodi:ry="16"
d="M 9,29.999999 A 42,16 0 0 1 93,30 l -42,0 z"
sodipodi:start="3.1415927"
sodipodi:end="6.2831853"
transform="matrix(0.43692393,0,0,1.3783114,461.29951,517.6437)"
inkscape:export-filename="/home/jimmac/src/cvs/gnome/gnome-shell-design/mockups/motion/textures/panel.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
<rect
style="fill:#ffffff;fill-opacity:0.50196078;stroke-width:0.43599999;stroke-miterlimit:4;stroke-dasharray:none"
id="rect2996"
width="31"
height="3"
x="468.08264"
y="558.99304" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 5.7 KiB

After

Width:  |  Height:  |  Size: 6.1 KiB

View File

@ -1,188 +0,0 @@
/* Copyright 2011, Red Hat, Inc.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU Lesser General Public License,
* version 2.1, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
* more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
*/
/* Login Dialog */
.login-dialog-banner {
font-size: 10pt;
font-weight: bold;
text-align: center;
color: #666666;
padding-bottom: 1em;
}
.login-dialog-title {
font-size: 14pt;
font-weight: bold;
color: #666666;
padding-bottom: 2em;
}
.login-dialog {
border-radius: 16px;
min-height: 150px;
max-height: 700px;
min-width: 350px;
}
.login-dialog-prompt-fingerprint-message {
font-size: 10.5pt;
}
.login-dialog-user-list-view {
-st-vfade-offset: 1em;
}
.login-dialog-user-list {
spacing: 12px;
}
.login-dialog-user-list-item {
color: #666666;
}
.login-dialog-user-list-item:ltr {
padding-right: 1em;
}
.login-dialog-user-list-item:rtl {
padding-left: 1em;
}
.login-dialog-user-list-item .login-dialog-user-list-item-name {
font-size: 20pt;
padding-left: 1em;
color: #666666;
}
.login-dialog-user-list-item:hover .login-dialog-user-list-item-name {
color: white;
}
.login-dialog-user-list-item:focus .login-dialog-user-list-item-name {
color: white;
text-shadow: black 0px 2px 2px;
}
.login-dialog-user-list-item-vertical-layout {
spacing: 2px;
}
.login-dialog-user-list-item .login-dialog-user-list-item-focus-bin {
background-color: rgba(0,0,0,0.0);
height: 2px;
}
.login-dialog-user-list-item:focus .login-dialog-user-list-item-focus-bin {
background-color: #666666;
}
.login-dialog-user-list-item-icon {
border: 2px solid #8b8b8b;
border-radius: 8px;
width: 64px;
height: 64px;
}
.login-dialog-not-listed-button {
padding-top: 2em;
}
.login-dialog-not-listed-label {
font-size: 14pt;
font-weight: bold;
color: #666666;
}
.login-dialog-not-listed-button:hover .login-dialog-not-listed-label {
color: white;
}
.login-dialog-prompt-layout {
padding-bottom: 32px;
}
.login-dialog-prompt-label {
color: white;
font-size: 20pt;
}
.login-dialog-prompt-entry {
padding: 4px;
border-radius: 4px;
border: 2px solid #5656cc;
color: black;
background-color: white;
caret-color: black;
caret-size: 1px;
width: 15em;
}
.login-dialog-prompt-entry .capslock-warning {
icon-size: 16px;
warning-color: #999;
}
.login-dialog-prompt-entry:insensitive {
color: rgba(0,0,0,0.7);
border: 2px solid #565656;
}
.login-dialog-session-list {
color: #ffffff;
font-size: 10.5pt;
}
.login-dialog-session-list-button {
padding: 4px;
}
.login-dialog-session-list-button:focus {
background-color: #4c4c4c;
}
.login-dialog-session-list-button:active {
background-color: #4c4c4c;
}
.login-dialog-session-list-button:hover {
font-weight: bold;
}
.login-dialog-session-list-scroll-view {
background-gradient-start: rgba(80,80,80,0.3);
background-gradient-end: rgba(80,80,80,0.7);
background-gradient-direction: vertical;
box-shadow: inset 0px 2px 4px rgba(0,0,0,0.9);
border-radius: 8px;
border: 1px solid rgba(80,80,80,1.0);
padding: .5em;
}
.login-dialog-session-list-item:focus {
background-color: #666666;
}
.login-dialog-session-list-triangle {
padding-right: .5em;
}
.login-dialog-session-list-item-box {
spacing: .25em;
}
.login-dialog-session-list-item-dot {
width: .75em;
height: .75em;
}

View File

@ -58,54 +58,48 @@ stage {
/* Scroll Bars */
StScrollBar
{
StScrollBar {
padding: 0px;
}
StScrollView.vfade
{
StScrollView.vfade {
-st-vfade-offset: 68px;
}
StScrollView.hfade
{
StScrollView.hfade {
-st-hfade-offset: 68px;
}
StScrollView StScrollBar
{
min-width: 16px;
min-height: 16px;
StScrollView StScrollBar {
min-width: 14px;
min-height: 14px;
}
StScrollBar StBin#trough {
background-color: #080808;
border: 1px solid #2d2d2d;
background-color: rgba(0,0,0,0.3);
border-radius: 8px;
}
StScrollBar StButton#vhandle
{
background-image: url("scroll-vhandle.svg");
background-color: #252525;
border: 1px solid #080808;
StScrollBar StButton#vhandle {
background-color: #959797;
border: 2px solid #242424;
border-radius: 8px;
}
StScrollBar StButton#hhandle
{
background-image: url("scroll-hhandle.svg");
background-color: #252525;
border: 1px solid #080808;
StScrollBar StButton#hhandle {
background-color: #959797;
border: 2px solid #242424;
border-radius: 8px;
}
StScrollBar StButton#hhandle:hover,
StScrollBar StButton#vhandle:hover
{
background-color: #292929;
StScrollBar StButton#vhandle:hover {
background-color: #c2c3c3;
}
StScrollBar StButton#hhandle:active,
StScrollBar StButton#vhandle:active {
background-color: #729fcf;
}
/* Check Boxes */
@ -136,7 +130,7 @@ StScrollBar StButton#vhandle:hover
.popup-menu-boxpointer {
-arrow-border-radius: 8px;
-arrow-background-color: rgba(0,0,0,0.9);
-arrow-background-color: black;
-arrow-border-width: 2px;
-arrow-border-color: #a5a5a5;
-arrow-base: 24px;
@ -202,7 +196,7 @@ StScrollBar StButton#vhandle:hover
background-color: #4c4c4c;
}
.popup-menu-item:insensitive {
StButton.popup-menu-item:insensitive {
color: #9f9f9f;
}
@ -333,6 +327,79 @@ StScrollBar StButton#vhandle:hover
color: #9f9f9f;
}
/* Entries */
#searchEntry,
.notification StEntry,
.login-dialog-prompt-entry,
.prompt-dialog-password-entry {
color: rgb(64, 64, 64);
caret-color: rgb(64, 64, 64);
font-size: 12pt;
caret-size: 1px;
selected-color: black;
padding: 4px 12px;
}
#searchEntry,
.notification StEntry {
border: 2px solid rgba(245,245,245,0.2);
background-gradient-start: rgba(5,5,6,0.1);
background-gradient-end: rgba(254,254,254,0.1);
background-gradient-direction: vertical;
transition-duration: 300;
box-shadow: inset 0px 2px 4px rgba(0,0,0,0.6);
}
#searchEntry:focus,
#searchEntry:hover,
.notification StEntry:focus,
.login-dialog-prompt-entry,
.prompt-dialog-password-entry {
border: 2px solid rgb(136,138,133);
background-gradient-start: rgb(200,200,200);
background-gradient-end: white;
background-gradient-direction: vertical;
box-shadow: inset 0px 2px 4px rgba(0,0,0,0.6);
}
.notification StEntry:focus,
.prompt-dialog-password-entry:focus,
.login-dialog-prompt-entry:focus {
border: 2px solid #3465a4;
}
#searchEntry {
color: rgb(128, 128, 128);
caret-color: rgb(128, 128, 128);
}
#searchEntry:focus {
color: rgb(64, 64, 64);
caret-color: rgb(64, 64, 64);
font-weight: bold;
transition-duration: 0;
}
.notification StEntry,
.prompt-dialog-password-entry,
.login-dialog-prompt-entry {
border-radius: 5px;
padding: 4px 4px;
}
.prompt-dialog-password-entry .capslock-warning,
.login-dialog-prompt-entry .capslock-warning {
icon-size: 16px;
warning-color: #999;
padding: 0 4px;
}
.login-dialog-prompt-entry:insensitive {
color: rgba(0,0,0,0.7);
border: 2px solid #565656;
}
/* Panel */
#panel {
@ -460,6 +527,7 @@ StScrollBar StButton#vhandle:hover
border-radius: 5px;
width: 48pt;
height: 48pt;
background-size: contain;
}
.status-chooser-user-icon:hover {
@ -592,38 +660,8 @@ StScrollBar StButton#vhandle:hover
}
#searchEntry {
padding: 4px 12px;
border-radius: 17px;
font-size: 12pt;
color: rgb(128, 128, 128);
border: 2px solid rgba(245,245,245,0.2);
background-gradient-start: rgba(5,5,6,0.1);
background-gradient-end: rgba(254,254,254,0.1);
background-gradient-direction: vertical;
selected-color: black;
caret-color: rgb(128, 128, 128);
caret-size: 1px;
width: 250px;
transition-duration: 300;
box-shadow: inset 0px 2px 4px rgba(0,0,0,0.6);
}
#searchEntry:focus,
#searchEntry:hover {
border: 2px solid rgb(136,138,133);
background-gradient-start: rgb(200,200,200);
background-gradient-end: white;
background-gradient-direction: vertical;
}
#searchEntry:hover {
transition-duration: 300;
}
#searchEntry:focus {
color: rgb(64, 64, 64);
font-weight: bold;
transition-duration: 0;
}
.search-entry-icon {
@ -812,8 +850,7 @@ StScrollBar StButton#vhandle:hover
/* LookingGlass */
#LookingGlassDialog
{
#LookingGlassDialog {
background-color: rgba(0,0,0,0.80);
spacing: 4px;
padding: 4px;
@ -821,8 +858,7 @@ StScrollBar StButton#vhandle:hover
border-radius: 4px;
}
#LookingGlassDialog > #Toolbar
{
#LookingGlassDialog > #Toolbar {
border: 1px solid grey;
border-radius: 4px;
}
@ -858,53 +894,44 @@ StScrollBar StButton#vhandle:hover
padding-bottom: 8px;
}
.lg-dialog StEntry
{
.lg-dialog StEntry {
selection-background-color: #bbbbbb;
selected-color: #333333;
}
.lg-completions-text
{
.lg-completions-text {
font-size: .9em;
font-style: italic;
}
.lg-obj-inspector-title
{
.lg-obj-inspector-title {
spacing: 4px;
}
.lg-obj-inspector-button
{
.lg-obj-inspector-button {
border: 1px solid gray;
padding: 4px;
border-radius: 4px;
}
.lg-obj-inspector-button:hover
{
.lg-obj-inspector-button:hover {
border: 1px solid #ffffff;
}
.lg-dialog .shell-link
{
.lg-dialog .shell-link {
color: #999999;
}
.lg-dialog .shell-link:hover
{
.lg-dialog .shell-link:hover {
color: #dddddd;
}
#LookingGlassDialog StBoxLayout#EvalBox
{
#LookingGlassDialog StBoxLayout#EvalBox {
padding: 4px;
spacing: 4px;
}
#LookingGlassDialog StBoxLayout#ResultsArea
{
#LookingGlassDialog StBoxLayout#ResultsArea {
spacing: 4px;
}
@ -942,7 +969,7 @@ StScrollBar StButton#vhandle:hover
#calendarEventsArea {
/* this is the width of the second column of the popup */
min-width: 400px;
min-width: 320px;
}
.calendar-vertical-separator {
@ -951,29 +978,22 @@ StScrollBar StButton#vhandle:hover
width: 0.3em;
}
#calendarPopup {
border-radius: 5px;
background: rgba(0,0,0,0.9);
border: 1px solid rgba(128,128,128,0.45);
color: white;
}
#calendarPopup .calendar {
padding: 10px;
}
.calendar {
padding: .4em 1.75em;
padding: .4em 1.75em .8em 1.75em;
spacing-rows: 0px;
spacing-columns: 0px;
}
.calendar-month-label {
color: #666666;
font-size: 7.5pt;
color: #888a85;
font-size: 9.5pt;
font-weight: bold;
padding-bottom: 8px;
padding-top: 8px;
font-weight: bold;
}
.calendar-change-month-back {
@ -1013,14 +1033,14 @@ StScrollBar StButton#vhandle:hover
}
.datemenu-date-label {
padding: .4em 1.75em;
color: #cccccc;
padding: .4em 1.7em;
font-weight: bold;
text-align: center;
color: #eeeeec;
}
.calendar-day-base {
font-size: 7.5pt;
font-size: 9pt;
text-align: center;
width: 2.4em;
height: 2.4em;
@ -1028,33 +1048,37 @@ StScrollBar StButton#vhandle:hover
.calendar-day-base:hover {
background-color: #777777;
color: #fff;
}
.calendar-day-base:active {
font-size: 9pt;
background-color: #555555;
color: white;
}
.calendar-day-heading {
color: #666666;
padding-top: 1em;
color: #888a85;
padding-top: .2em;
height: 1.7em;
}
.calendar-week-number {
color: #666666;
color: #babdb6;
font-weight: bold;
}
/* Hack used in lieu of border-collapse - see calendar.js */
.calendar-day {
border: 1px solid #333333;
color: #888888;
border: 1px solid #505050;
color: #babdb6;
border-top-width: 0;
border-left-width: 0;
}
.calendar-day-top {
border-top-width: 1px;
}
.calendar-day-left {
border-left-width: 1px;
}
@ -1069,7 +1093,6 @@ StScrollBar StButton#vhandle:hover
.calendar-today {
background-image: url("calendar-today.svg");
text-shadow: black 0px 2px 2px;
color: #ffffff;
font-weight: bold;
}
@ -1079,38 +1102,33 @@ StScrollBar StButton#vhandle:hover
.calendar-day-with-events {
font-weight: bold;
color: #cccccc;
color: white;
}
.events-header-vbox {
spacing: 6pt;
padding-right: 1.75em;
padding-right: .5em;
}
.events-header-vbox:rtl {
padding-right: 0em;
padding-left: 1.75em;
padding-left: .5em;
}
.events-header-hbox {
padding: 0.3em;
padding: 0.3em 1.4em;
}
.events-day-header {
font-size: 9pt;
font-weight: bold;
color: rgba(153, 153, 153, 1.0);
padding-left: 1.8em;
padding-top: 0.8em;
color: #999999;
padding: 0.4em 1.4em 0em 1.4em;
}
.events-day-header:rtl {
padding-left: 0em;
padding-right: 0.3em;
padding: 0em 1.4em 0.4em 1.4em;
}
.events-day-dayname {
font-size: 9pt;
color: rgba(153, 153, 153, 1.0);
text-align: left;
}
@ -1120,7 +1138,6 @@ StScrollBar StButton#vhandle:hover
}
.events-day-time {
font-size: 9pt;
color: #fff;
text-align: right;
}
@ -1130,7 +1147,6 @@ StScrollBar StButton#vhandle:hover
}
.events-day-task {
font-size: 9pt;
color: rgba(153, 153, 153, 1.0);
}
@ -1139,13 +1155,13 @@ StScrollBar StButton#vhandle:hover
}
.events-time-box {
min-width: 53pt;
padding-right: 6pt;
min-width: 48pt;
padding-right: 12pt;
}
.events-time-box:rtl {
padding-right: 0px;
padding-left: 6pt;
padding-left: 12pt;
}
.events-event-box {
@ -1187,11 +1203,9 @@ StScrollBar StButton#vhandle:hover
.summary-boxpointer {
-arrow-border-radius: 8px;
-arrow-background-color: rgba(0,0,0,0.9);
-arrow-border-width: 2px;
-arrow-border-color: #a5a5a5;
-arrow-base: 24px;
-arrow-rise: 11px;
-arrow-background-color: rgba(0,0,0,0.8);
-arrow-base: 36px;
-arrow-rise: 18px;
color: white;
}
@ -1206,17 +1220,17 @@ StScrollBar StButton#vhandle:hover
padding-bottom: 12px;
}
#summary-notification-stack-scrollview {
.summary-notification-stack-scrollview {
max-height: 18em;
padding-top: 6px;
padding-bottom: 6px;
}
#summary-notification-stack-scrollview:ltr {
.summary-notification-stack-scrollview:ltr {
padding-right: 8px;
}
#summary-notification-stack-scrollview:rtl {
.summary-notification-stack-scrollview:rtl {
padding-left: 8px;
}
@ -1369,30 +1383,7 @@ StScrollBar StButton#vhandle:hover
}
.notification StEntry {
padding: 4px;
border-radius: 4px;
color: #a8a8a8;
selected-color: black;
border: 1px solid rgba(245,245,245,0.2);
background-gradient-direction: vertical;
background-gradient-start: rgb(200,200,200);
background-gradient-end: white;
transition-duration: 300;
box-shadow: inset 0px 2px 4px rgba(0,0,0,0.6);
caret-color: #a8a8a8;
caret-size: 1px;
}
.notification StEntry:focus {
border: 1px solid #8b8b8b;
color: #333333;
background-gradient-direction: vertical;
background-gradient-start: rgb(200,200,200);
background-gradient-end: white;
caret-color: #545454;
selection-background-color: #808080;
}
/* The spacing and padding on the summary is tricky; we want to keep
@ -1642,7 +1633,7 @@ StScrollBar StButton#vhandle:hover
padding: 4px 32px 5px;
}
.modal-dialog-button:disabled {
.modal-dialog-button:insensitive {
color: rgb(60, 60, 60);
}
@ -1674,7 +1665,7 @@ StScrollBar StButton#vhandle:hover
}
.lightbox {
background-color: rgba(0, 0, 0, 0.4);
background-color: black;
}
.flashspot {
@ -1868,32 +1859,8 @@ StScrollBar StButton#vhandle:hover
color: #666666;
}
.prompt-dialog-password-label:ltr {
padding-right: 0.5em;
}
.prompt-dialog-password-label:rtl {
padding-left: 0.5em;
}
.prompt-dialog-password-entry {
background-gradient-start: rgb(236,236,236);
background-gradient-end: white;
background-gradient-direction: vertical;
color: black;
selected-color: white;
border-radius: 5px;
border: 2px solid #555753;
}
.prompt-dialog-password-entry:focus {
border: 2px solid #3465a4;
}
.prompt-dialog-password-entry .capslock-warning {
icon-size: 16px;
warning-color: #999;
padding: 0 4px;
.prompt-dialog-password-box {
spacing: 1em;
}
.prompt-dialog-error-label {
@ -2020,3 +1987,281 @@ StScrollBar StButton#vhandle:hover
border-radius: 4px;
background-color: rgba(255,255,255,0.33);
}
/* Login Dialog */
.login-dialog-banner {
font-size: 10pt;
font-weight: bold;
text-align: center;
color: #666666;
padding-bottom: 1em;
}
.login-dialog-title {
font-size: 14pt;
font-weight: bold;
color: #666666;
padding-bottom: 2em;
}
.login-dialog {
/* Reset border and background */
border: none;
background-color: transparent;
border-radius: 16px;
min-height: 150px;
max-height: 700px;
min-width: 350px;
}
.login-dialog-prompt-fingerprint-message {
font-size: 10.5pt;
}
.login-dialog-user-list-view {
-st-vfade-offset: 1em;
}
.login-dialog-user-list {
spacing: 12px;
padding: .2em;
}
.login-dialog-user-list-item {
color: #666666;
border-radius: 10px;
padding: .2em;
}
.login-dialog-user-list-item:ltr {
padding-right: 1em;
}
.login-dialog-user-list-item:rtl {
padding-left: 1em;
}
.login-dialog-user-list-item .login-dialog-user-list-item-name {
font-size: 20pt;
padding-left: 1em;
}
.login-dialog-user-list-item:hover .login-dialog-user-list-item-name,
.login-dialog-user-list:expanded .login-dialog-user-list-item:focus .login-dialog-user-list-item-name,
.login-dialog-user-list:expanded .login-dialog-user-list-item:logged-in {
color: white;
text-shadow: black 0px 2px 2px;
}
.login-dialog-user-list-item:hover {
background-color: rgba(255,255,255,0.1);
}
.login-dialog-user-list:expanded .login-dialog-user-list-item:focus {
background-color: rgba(255,255,255,0.33);
}
.login-dialog-user-list:expanded .login-dialog-user-list-item:logged-in {
background-image: url("logged-in-indicator.svg");
background-size: contain;
}
.login-dialog-user-list-item-text-box {
padding: 0 0.5em;
}
.login-dialog-user-list-item .login-dialog-timed-login-indicator {
background-color: rgba(0,0,0,0.0);
height: 2px;
}
.login-dialog-user-list-item:focus .login-dialog-timed-login-indicator {
background-color: #8b8b8b;
}
.login-dialog-user-list-item-icon {
border: 2px solid #8b8b8b;
border-radius: 8px;
width: 64px;
height: 64px;
}
.login-dialog-not-listed-label {
font-size: 10.5pt;
font-weight: bold;
color: #666666;
}
.login-dialog-not-listed-button:hover .login-dialog-not-listed-label {
color: #E8E8E8;
}
.login-dialog-username {
font-size: 16pt;
font-weight: bold;
text-align: left;
padding-left: 15px;
text-shadow: black 4px 4px 3px 0px;
}
.login-dialog-prompt-layout {
padding-top: 24px;
padding-bottom: 12px;
spacing: 8px;
}
.login-dialog-prompt-label {
color: #eeeeee;
font-size: 14px;
}
.login-dialog-prompt-entry {
width: 15em;
}
.login-dialog-session-list {
color: #ffffff;
font-size: 10.5pt;
}
.login-dialog-session-list-button {
padding: 4px;
}
.login-dialog-session-list-button:focus {
background-color: #4c4c4c;
}
.login-dialog-session-list-button:active {
background-color: #4c4c4c;
}
.login-dialog-session-list-button:hover {
font-weight: bold;
}
.login-dialog-session-list-scroll-view {
background-gradient-start: rgba(80,80,80,0.3);
background-gradient-end: rgba(80,80,80,0.7);
background-gradient-direction: vertical;
box-shadow: inset 0px 2px 4px rgba(0,0,0,0.9);
border-radius: 8px;
border: 1px solid rgba(80,80,80,1.0);
padding: .5em;
}
.login-dialog-session-list-item:focus {
background-color: #666666;
}
.login-dialog-session-list-triangle {
padding-right: .5em;
}
.login-dialog-session-list-item-box {
spacing: .25em;
}
.login-dialog-session-list-item-dot {
width: .75em;
height: .75em;
}
.login-dialog .modal-dialog-button {
border: 1px solid white;
border-radius: 5px;
padding: 3px 18px;
}
.login-dialog .modal-dialog-button:default {
background-gradient-start: #6793c4;
background-gradient-end: #335d8f;
background-gradient-direction: vertical;
border: 2px solid #16335d;
}
.login-dialog .modal-dialog-button:hover {
background-gradient-start: #74a0d0;
background-gradient-end: #436d9f;
}
.login-dialog .modal-dialog-button:active,
.login-dialog .modal-dialog-button:pressed {
background-gradient-start: #436d9f;
background-gradient-end: #74a0d0;
}
.unlock-dialog-user-name-container {
spacing: .4em;
}
/* Screen shield */
#screenShieldGroup {
background: #2e3436 url(noise-texture.png);
background-repeat: repeat;
}
#screenShieldGroup .arrow {
color: #333333;
width: 100px;
height: 50px;
}
.screen-shield-clock {
color: white;
text-shadow: 0px 1px 2px rgba(0,0,0,0.6);
font-weight: bold;
text-align: center;
padding-bottom: 1.5em;
}
.screen-shield-clock-time {
font-size: 86px;
text-shadow: 0px 2px 2px rgba(0,0,0,0.4);
}
.screen-shield-clock-date {
font-size: 48px;
}
#screenShieldNotifications {
border-radius: 8px;
background-color: rgba(0.0, 0.0, 0.0, 0.9);
border: 2px solid #868686;
max-height: 500px;
padding: 12px 0;
}
.screen-shield-notifications-box {
spacing: 12px;
}
.screen-shield-notification-source {
padding: 0 24px;
spacing: 5px;
}
.screen-shield-notification-label {
font-size: 1.2em;
font-weight: bold;
}
/* Remove background from notifications, otherwise
opacity is doubled and they look darker
*/
.screen-shield-notifications-box .notification {
background-color: transparent;
}
/* Override padding on resident notifications, since
the notifications box has its own spacing
*/
.screen-shield-notifications-box .summary-notification-stack-scrollview {
padding-top: 0px;
padding-bottom: 0px;
}

View File

@ -0,0 +1,130 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="300"
height="80"
id="svg7355"
version="1.1"
inkscape:version="0.48.2 r9819"
sodipodi:docname="logged-in-indicator.svg">
<metadata
id="metadata4175">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<sodipodi:namedview
pagecolor="#2c1cff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="1"
inkscape:pageshadow="2"
inkscape:window-width="1440"
inkscape:window-height="843"
id="namedview4173"
showgrid="false"
inkscape:zoom="2.8760889"
inkscape:cx="106.00403"
inkscape:cy="80.68078"
inkscape:window-x="0"
inkscape:window-y="27"
inkscape:window-maximized="1"
inkscape:current-layer="g30864" />
<defs
id="defs7357">
<radialGradient
xlink:href="#linearGradient36429"
id="radialGradient7461"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(2.5919312,0,0,0.57582113,-20.687059,48.400487)"
cx="47.428951"
cy="167.16817"
fx="47.428951"
fy="167.16817"
r="37" />
<linearGradient
id="linearGradient36429">
<stop
id="stop36431"
offset="0"
style="stop-color:#ffffff;stop-opacity:1;" />
<stop
id="stop36433"
offset="1"
style="stop-color:#ffffff;stop-opacity:0;" />
</linearGradient>
<radialGradient
xlink:href="#linearGradient36471"
id="radialGradient7463"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.1891549,0,0,0.55513246,-9.281289,36.12653)"
cx="49.067139"
cy="242.50381"
fx="49.067139"
fy="242.50381"
r="37.00671" />
<linearGradient
id="linearGradient36471">
<stop
id="stop36473"
offset="0"
style="stop-color:#ffffff;stop-opacity:1;" />
<stop
id="stop36475"
offset="1"
style="stop-color:#ffffff;stop-opacity:0;" />
</linearGradient>
<radialGradient
r="37.00671"
fy="242.50381"
fx="49.067139"
cy="242.50381"
cx="49.067139"
gradientTransform="matrix(3.4218418,0,0,0.03365337,-61.309005,138.5071)"
gradientUnits="userSpaceOnUse"
id="radialGradient7488"
xlink:href="#linearGradient36471" />
</defs>
<g
id="layer1"
transform="matrix(1.6213276,0,0,1.6213276,-431.6347,-272.5745)">
<g
style="display:inline"
id="g30864"
transform="translate(255.223,70.118091)">
<rect
ry="3.4593496"
rx="8.8641119"
y="76.159348"
x="12.596948"
height="71.116341"
width="182.22595"
id="rect14000"
style="opacity:0.371875;fill:url(#radialGradient7461);fill-opacity:1;stroke:none" />
<path
id="rect34520"
d="m 194.80022,146.83551 -182.559919,0"
style="opacity:0.35;fill:none;stroke:url(#radialGradient7488);stroke-width:0.61184424;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
connector-curvature="0"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

View File

@ -1,64 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="10"
height="4"
id="svg2"
version="1.1"
inkscape:version="0.47 r22583"
sodipodi:docname="scroll-hhandle.svg">
<defs
id="defs4">
</defs>
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<rect
style="fill:#323232;fill-opacity:1;fill-rule:evenodd;stroke:none"
id="rect3592"
width="2"
height="4"
x="0"
y="0"
rx="0"
ry="0" />
<use
x="0"
y="0"
xlink:href="#rect3592"
id="use2825"
transform="translate(8,0)"
width="10"
height="4" />
<use
x="0"
y="0"
xlink:href="#use2825"
id="use2827"
transform="translate(-4,0)"
width="10"
height="4" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.6 KiB

View File

@ -1,62 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="4"
height="10"
id="svg2"
version="1.1"
inkscape:version="0.47 r22583"
sodipodi:docname="scroll-hhandle.svg">
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<rect
style="fill:#323232;fill-opacity:1;fill-rule:evenodd;stroke:none"
id="rect3592"
width="2"
height="4"
x="0"
y="-4"
rx="0"
ry="0"
transform="matrix(0,1,-1,0,0,0)" />
<use
x="0"
y="0"
xlink:href="#rect3592"
id="use3705"
transform="translate(0,4)"
width="4"
height="10" />
<use
x="0"
y="0"
xlink:href="#use3705"
id="use3707"
transform="translate(0,4)"
width="4"
height="10" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.6 KiB

View File

@ -22,6 +22,7 @@ nobase_dist_js_DATA = \
gdm/loginDialog.js \
gdm/powerMenu.js \
gdm/systemd.js \
gdm/util.js \
extensionPrefs/main.js \
misc/config.js \
misc/extensionUtils.js \
@ -31,7 +32,6 @@ nobase_dist_js_DATA = \
misc/jsParse.js \
misc/modemManager.js \
misc/params.js \
misc/screenSaver.js \
misc/util.js \
perf/core.js \
ui/altTab.js \
@ -76,11 +76,11 @@ nobase_dist_js_DATA = \
ui/popupMenu.js \
ui/remoteSearch.js \
ui/runDialog.js \
ui/screenShield.js \
ui/scripting.js \
ui/search.js \
ui/searchDisplay.js \
ui/shellDBus.js \
ui/statusIconDispatcher.js \
ui/status/accessibility.js \
ui/status/keyboard.js \
ui/status/network.js \
@ -89,6 +89,7 @@ nobase_dist_js_DATA = \
ui/status/bluetooth.js \
ui/telepathyClient.js \
ui/tweener.js \
ui/unlockDialog.js \
ui/userMenu.js \
ui/viewSelector.js \
ui/wanda.js \

View File

@ -13,8 +13,7 @@ const _ = Gettext.gettext;
const Config = imports.misc.config;
const ExtensionUtils = imports.misc.extensionUtils;
const GnomeShellIface = <interface name="org.gnome.Shell">
const GnomeShellIface = <interface name="org.gnome.Shell.Extensions">
<signal name="ExtensionStatusChanged">
<arg type="s" name="uuid"/>
<arg type="i" name="state"/>
@ -162,7 +161,7 @@ const Application = new Lang.Class({
vbox.add(toolbar);
let toolitem;
let label = new Gtk.Label({ label: _("<b>Extension</b>"),
let label = new Gtk.Label({ label: '<b>' + _("Extension") + '</b>',
use_markup: true });
toolitem = new Gtk.ToolItem({ child: label });
toolbar.add(toolitem);
@ -210,7 +209,7 @@ const Application = new Lang.Class({
_extensionFound: function(signals, extension) {
let iter = this._model.append();
this._model.set(iter, [0, 1], [extension.uuid, extension.metadata.name]);
this._extensionIters[uuid] = iter;
this._extensionIters[extension.uuid] = iter;
},

View File

@ -34,81 +34,19 @@ const Gdm = imports.gi.Gdm;
const Batch = imports.gdm.batch;
const Fprint = imports.gdm.fingerprint;
const GdmUtil = imports.gdm.util;
const Lightbox = imports.ui.lightbox;
const Main = imports.ui.main;
const ModalDialog = imports.ui.modalDialog;
const Tweener = imports.ui.tweener;
const _PASSWORD_SERVICE_NAME = 'gdm-password';
const _FINGERPRINT_SERVICE_NAME = 'gdm-fingerprint';
const _FADE_ANIMATION_TIME = 0.16;
const _RESIZE_ANIMATION_TIME = 0.25;
const _SCROLL_ANIMATION_TIME = 2.0;
const _SCROLL_ANIMATION_TIME = 0.5;
const _TIMED_LOGIN_IDLE_THRESHOLD = 5.0;
const _LOGO_ICON_NAME_SIZE = 48;
const _LOGIN_SCREEN_SCHEMA = 'org.gnome.login-screen';
const _FINGERPRINT_AUTHENTICATION_KEY = 'enable-fingerprint-authentication';
const _BANNER_MESSAGE_KEY = 'banner-message-enable';
const _BANNER_MESSAGE_TEXT_KEY = 'banner-message-text';
const _LOGO_KEY = 'logo';
let _loginDialog = null;
function _fadeInActor(actor) {
let hold = new Batch.Hold();
if (actor.opacity == 255 && actor.visible)
return null;
actor.show();
let [minHeight, naturalHeight] = actor.get_preferred_height(-1);
actor.opacity = 0;
actor.set_height(0);
Tweener.addTween(actor,
{ opacity: 255,
height: naturalHeight,
time: _FADE_ANIMATION_TIME,
transition: 'easeOutQuad',
onComplete: function() {
actor.set_height(-1);
hold.release();
},
onCompleteScope: this
});
return hold;
}
function _fadeOutActor(actor) {
let hold = new Batch.Hold();
if (!actor.visible) {
actor.opacity = 0;
return null;
}
if (actor.opacity == 0) {
actor.hide();
return null;
}
Tweener.addTween(actor,
{ opacity: 0,
height: 0,
time: _FADE_ANIMATION_TIME,
transition: 'easeOutQuad',
onComplete: function() {
actor.hide();
actor.set_height(-1);
hold.release();
},
onCompleteScope: this
});
return hold;
}
function _smoothlyResizeActor(actor, width, height) {
let finalWidth;
let finalHeight;
@ -150,43 +88,37 @@ const UserListItem = new Lang.Class({
this._userChangedId = this.user.connect('changed',
Lang.bind(this, this._onUserChanged));
this._verticalBox = new St.BoxLayout({ style_class: 'login-dialog-user-list-item-vertical-layout',
vertical: true });
let layout = new St.BoxLayout({ vertical: false });
this.actor = new St.Button({ style_class: 'login-dialog-user-list-item',
can_focus: true,
child: this._verticalBox,
child: layout,
reactive: true,
x_align: St.Align.START,
x_fill: true });
let layout = new St.BoxLayout({ vertical: false });
this._verticalBox.add(layout,
{ y_fill: true,
x_fill: true,
expand: true });
this._focusBin = new St.Bin({ style_class: 'login-dialog-user-list-item-focus-bin' });
this._verticalBox.add(this._focusBin,
{ x_fill: false,
x_align: St.Align.MIDDLE,
y_fill: false,
expand: true });
this._iconBin = new St.Bin();
layout.add(this._iconBin);
let textLayout = new St.BoxLayout({ style_class: 'login-dialog-user-list-item-text-box',
vertical: true });
layout.add(textLayout,
{ y_fill: false,
y_align: St.Align.MIDDLE,
expand: true });
layout.add(textLayout, { expand: true });
this._nameLabel = new St.Label({ text: this.user.get_real_name(),
style_class: 'login-dialog-user-list-item-name' });
textLayout.add(this._nameLabel);
textLayout.add(this._nameLabel,
{ y_fill: false,
y_align: St.Align.MIDDLE,
expand: true });
this._timedLoginIndicator = new St.Bin({ style_class: 'login-dialog-timed-login-indicator',
scale_x: 0 });
textLayout.add(this._timedLoginIndicator,
{ x_fill: true,
x_align: St.Align.MIDDLE,
y_fill: false,
y_align: St.Align.END });
this._updateIcon();
this._updateLoggedIn();
this.actor.connect('clicked', Lang.bind(this, this._onClicked));
},
@ -194,6 +126,7 @@ const UserListItem = new Lang.Class({
_onUserChanged: function() {
this._nameLabel.set_text(this.user.get_real_name());
this._updateIcon();
this._updateLoggedIn();
},
_setIconFromFile: function(iconFile, styleClass) {
@ -241,30 +174,40 @@ const UserListItem = new Lang.Class({
this._setIconFromName('avatar-default', 'login-dialog-user-list-item-icon');
},
syncStyleClasses: function() {
this._updateLoggedIn();
if (global.stage.get_key_focus() == this.actor)
this.actor.add_style_pseudo_class('focus');
else
this.actor.remove_style_pseudo_class('focus');
},
_updateLoggedIn: function() {
if (this.user.is_logged_in())
this.actor.add_style_pseudo_class('logged-in');
else
this.actor.remove_style_pseudo_class('logged-in');
},
_onClicked: function() {
this.emit('activate');
},
fadeOutName: function() {
return _fadeOutActor(this._nameLabel);
return GdmUtil.fadeOutActor(this._nameLabel);
},
fadeInName: function() {
return _fadeInActor(this._nameLabel);
return GdmUtil.fadeInActor(this._nameLabel);
},
showFocusAnimation: function(time) {
showTimedLoginIndicator: function(time) {
let hold = new Batch.Hold();
let node = this.actor.get_theme_node();
let padding = node.get_horizontal_padding();
let box = this._verticalBox.get_allocation_box();
Tweener.removeTweens(this._focusBin);
this._focusBin.width = 0;
Tweener.addTween(this._focusBin,
{ width: (box.x2 - box.x1 - padding),
this.hideTimedLoginIndicator();
Tweener.addTween(this._timedLoginIndicator,
{ scale_x: 1.,
time: time,
transition: 'linear',
onComplete: function() {
@ -273,6 +216,11 @@ const UserListItem = new Lang.Class({
onCompleteScope: this
});
return hold;
},
hideTimedLoginIndicator: function() {
Tweener.removeTweens(this._timedLoginIndicator);
this._timedLoginIndicator.scale_x = 0.;
}
});
Signals.addSignalMethods(UserListItem.prototype);
@ -286,13 +234,10 @@ const UserList = new Lang.Class({
Gtk.PolicyType.AUTOMATIC);
this._box = new St.BoxLayout({ vertical: true,
style_class: 'login-dialog-user-list' });
style_class: 'login-dialog-user-list',
pseudo_class: 'expanded' });
this.actor.add_actor(this._box,
{ x_fill: true,
y_fill: true,
x_align: St.Align.START,
y_align: St.Align.MIDDLE });
this.actor.add_actor(this._box);
this._items = {};
this.actor.connect('key-focus-in', Lang.bind(this, this._moveFocusToItems));
@ -312,7 +257,7 @@ const UserList = new Lang.Class({
_showItem: function(item) {
let tasks = [function() {
return _fadeInActor(item.actor);
return GdmUtil.fadeInActor(item.actor);
},
function() {
@ -369,17 +314,21 @@ const UserList = new Lang.Class({
for (let userName in this._items) {
let item = this._items[userName];
item.actor.set_hover(false);
item.actor.reactive = false;
item.actor.can_focus = false;
item._focusBin.width = 0;
item.syncStyleClasses();
item._timedLoginIndicator.scale_x = 0.;
if (item != exception)
tasks.push(function() {
return _fadeOutActor(item.actor);
return GdmUtil.fadeOutActor(item.actor);
});
}
this._box.remove_style_pseudo_class('expanded');
let batch = new Batch.ConsecutiveBatch(this,
[function() {
return _fadeOutActor(this.actor.vscroll);
return GdmUtil.fadeOutActor(this.actor.vscroll);
},
new Batch.ConcurrentBatch(this, tasks)
@ -423,12 +372,16 @@ const UserList = new Lang.Class({
for (let userName in this._items) {
let item = this._items[userName];
item.actor.sync_hover();
item.actor.reactive = true;
item.actor.can_focus = true;
item.syncStyleClasses();
tasks.push(function() {
return this._showItem(item);
});
}
this._box.add_style_pseudo_class('expanded');
let batch = new Batch.ConsecutiveBatch(this,
[function() {
this.takeOverWhitespace();
@ -446,7 +399,7 @@ const UserList = new Lang.Class({
},
function() {
return _fadeInActor(this.actor.vscroll);
return GdmUtil.fadeInActor(this.actor.vscroll);
}]);
return batch.run();
},
@ -461,7 +414,7 @@ const UserList = new Lang.Class({
Tweener.addTween (adjustment,
{ value: value,
time: _SCROLL_ANIMATION_TIME,
transition: 'linear' });
transition: 'easeOutQuad' });
},
jumpToItem: function(item) {
@ -513,7 +466,6 @@ const UserList = new Lang.Class({
Lang.bind(this,
function() {
this.scrollToItem(item);
item.showFocusAnimation(0);
}));
this._moveFocusToItems();
@ -555,10 +507,7 @@ const SessionListItem = new Lang.Class({
this._box = new St.BoxLayout({ style_class: 'login-dialog-session-list-item-box' });
this.actor.add_actor(this._box,
{ expand: true,
x_fill: true,
y_fill: true });
this.actor.add_actor(this._box);
this.actor.connect('clicked', Lang.bind(this, this._onClicked));
this._dot = new St.DrawingArea({ style_class: 'login-dialog-session-list-item-dot' });
@ -569,10 +518,7 @@ const SessionListItem = new Lang.Class({
let label = new St.Label({ style_class: 'login-dialog-session-list-item-label',
text: name });
this._box.add_actor(label,
{ expand: true,
x_fill: true,
y_fill: true });
this._box.add_actor(label);
},
setShowDot: function(show) {
@ -616,10 +562,7 @@ const SessionList = new Lang.Class({
x_fill: true,
y_fill: true });
let box = new St.BoxLayout();
this._button.add_actor(box,
{ x_fill: true,
y_fill: true,
expand: true });
this._button.add_actor(box);
this._triangle = new St.Label({ style_class: 'login-dialog-session-list-triangle',
text: '\u25B8' });
@ -627,30 +570,18 @@ const SessionList = new Lang.Class({
let label = new St.Label({ style_class: 'login-dialog-session-list-label',
text: _("Session...") });
box.add_actor(label,
{ x_fill: true,
y_fill: true,
expand: true });
box.add_actor(label);
this._button.connect('clicked',
Lang.bind(this, this._onClicked));
this._box.add_actor(this._button,
{ x_fill: true,
y_fill: true,
expand: true });
this._box.add_actor(this._button);
this._scrollView = new St.ScrollView({ style_class: 'login-dialog-session-list-scroll-view'});
this._scrollView.set_policy(Gtk.PolicyType.NEVER,
Gtk.PolicyType.AUTOMATIC);
this._box.add_actor(this._scrollView,
{ x_fill: true,
y_fill: true,
expand: true });
this._box.add_actor(this._scrollView);
this._itemList = new St.BoxLayout({ style_class: 'login-dialog-session-item-list',
vertical: true });
this._scrollView.add_actor(this._itemList,
{ x_fill: true,
y_fill: true,
expand: true });
this._scrollView.add_actor(this._itemList);
this._scrollView.hide();
this.isOpen = false;
this._populate();
@ -718,11 +649,7 @@ const SessionList = new Lang.Class({
let [sessionName, sessionDescription] = Gdm.get_session_name_and_description(ids[i]);
let item = new SessionListItem(ids[i], sessionName);
this._itemList.add_actor(item.actor,
{ x_align: St.Align.START,
y_align: St.Align.START,
x_fill: true,
y_fill: true });
this._itemList.add_actor(item.actor);
this._items[ids[i]] = item;
if (!this._activeSessionId)
@ -741,8 +668,11 @@ const LoginDialog = new Lang.Class({
Name: 'LoginDialog',
Extends: ModalDialog.ModalDialog,
_init: function() {
this.parent({ shellReactive: true, styleClass: 'login-dialog' });
_init: function(parentActor) {
this.parent({ shellReactive: true,
styleClass: 'login-dialog',
parentActor: parentActor
});
this.connect('destroy',
Lang.bind(this, this._onDestroy));
this.connect('opened',
@ -761,15 +691,21 @@ const LoginDialog = new Lang.Class({
this._greeter.connect('timed-login-requested',
Lang.bind(this, this._onTimedLoginRequested));
this._settings = new Gio.Settings({ schema: _LOGIN_SCREEN_SCHEMA });
this._userVerifier = new GdmUtil.ShellUserVerifier(this._greeterClient);
this._userVerifier.connect('ask-question', Lang.bind(this, this._askQuestion));
this._userVerifier.connect('verification-failed', Lang.bind(this, this._onVerificationFailed));
this._userVerifier.connect('reset', Lang.bind(this, this._onReset));
this._fprintManager = new Fprint.FprintManager();
this._checkForFingerprintReader();
this._settings.connect('changed::' + _LOGO_KEY,
this._userVerifier.connect('show-fingerprint-prompt', Lang.bind(this, this._showFingerprintPrompt));
this._userVerifier.connect('hide-fingerprint-prompt', Lang.bind(this, this._hideFingerprintPrompt));
this._settings = new Gio.Settings({ schema: GdmUtil.LOGIN_SCREEN_SCHEMA });
this._settings.connect('changed::' + GdmUtil.LOGO_KEY,
Lang.bind(this, this._updateLogo));
this._settings.connect('changed::' + _BANNER_MESSAGE_KEY,
this._settings.connect('changed::' + GdmUtil.BANNER_MESSAGE_KEY,
Lang.bind(this, this._updateBanner));
this._settings.connect('changed::' + _BANNER_MESSAGE_TEXT_KEY,
this._settings.connect('changed::' + GdmUtil.BANNER_MESSAGE_TEXT_KEY,
Lang.bind(this, this._updateBanner));
this._logoBox = new St.Bin({ style_class: 'login-dialog-logo-box' });
@ -883,22 +819,9 @@ const LoginDialog = new Lang.Class({
},
_checkForFingerprintReader: function() {
this._haveFingerprintReader = false;
if (!this._settings.get_boolean(_FINGERPRINT_AUTHENTICATION_KEY))
return;
this._fprintManager.GetDefaultDeviceRemote(Gio.DBusCallFlags.NONE, Lang.bind(this,
function(device, error) {
if (!error && device)
this._haveFingerprintReader = true;
}));
},
_updateLogo: function() {
this._logoBox.child = null;
let path = this._settings.get_string(_LOGO_KEY);
let path = this._settings.get_string(GdmUtil.LOGO_KEY);
if (path) {
let file = Gio.file_new_for_path(path);
@ -911,8 +834,8 @@ const LoginDialog = new Lang.Class({
},
_updateBanner: function() {
let enabled = this._settings.get_boolean(_BANNER_MESSAGE_KEY);
let text = this._settings.get_string(_BANNER_MESSAGE_TEXT_KEY);
let enabled = this._settings.get_boolean(GdmUtil.BANNER_MESSAGE_KEY);
let text = this._settings.get_string(GdmUtil.BANNER_MESSAGE_TEXT_KEY);
if (enabled && text) {
this._bannerLabel.set_text(text);
@ -923,10 +846,6 @@ const LoginDialog = new Lang.Class({
},
_onReset: function(client, serviceName) {
this._userVerifier = null;
this._checkForFingerprintReader();
let tasks = [this._hidePrompt,
new Batch.ConcurrentBatch(this, [this._fadeInTitleLabel,
@ -956,43 +875,25 @@ const LoginDialog = new Lang.Class({
this._sessionList.setActiveSession(sessionId);
},
_onInfo: function(client, serviceName, info) {
// We don't display fingerprint messages, because they
// have words like UPEK in them. Instead we use the messages
// as a cue to display our own message.
if (serviceName == _FINGERPRINT_SERVICE_NAME &&
this._haveFingerprintReader &&
(!this._promptFingerprintMessage.visible ||
this._promptFingerprintMessage.opacity != 255)) {
_fadeInActor(this._promptFingerprintMessage);
return;
}
if (serviceName != _PASSWORD_SERVICE_NAME)
return;
Main.notifyError(info);
_showFingerprintPrompt: function() {
GdmUtil.fadeInActor(this._promptFingerprintMessage);
},
_onProblem: function(client, serviceName, problem) {
// we don't want to show auth failed messages to
// users who haven't enrolled their fingerprint.
if (serviceName != _PASSWORD_SERVICE_NAME)
return;
Main.notifyError(problem);
_hideFingerprintPrompt: function() {
GdmUtil.fadeOutActor(this._promptFingerprintMessage);
},
_onCancel: function(client) {
this._userVerifier.call_cancel_sync(null);
cancel: function() {
this._userVerifier.cancel();
},
_fadeInPrompt: function() {
let tasks = [function() {
return _fadeInActor(this._promptLabel);
return GdmUtil.fadeInActor(this._promptLabel);
},
function() {
return _fadeInActor(this._promptEntry);
return GdmUtil.fadeInActor(this._promptEntry);
},
function() {
@ -1003,14 +904,14 @@ const LoginDialog = new Lang.Class({
},
function() {
return _fadeInActor(this._promptBox);
return GdmUtil.fadeInActor(this._promptBox);
},
function() {
if (this._user && this._user.is_logged_in())
return null;
return _fadeInActor(this._sessionList.actor);
return GdmUtil.fadeInActor(this._sessionList.actor);
},
function() {
@ -1025,13 +926,14 @@ const LoginDialog = new Lang.Class({
_showPrompt: function() {
let hold = new Batch.Hold();
let buttons = [{ action: Lang.bind(this, this._onCancel),
let buttons = [{ action: Lang.bind(this, this.cancel),
label: _("Cancel"),
key: Clutter.Escape },
{ action: Lang.bind(this, function() {
hold.release();
}),
label: C_("button", "Sign In") }];
label: C_("button", "Sign In"),
default: true }];
this._promptEntryActivateCallbackId = this._promptEntry.clutter_text.connect('activate',
Lang.bind(this, function() {
@ -1066,7 +968,7 @@ const LoginDialog = new Lang.Class({
this.setButtons([]);
let tasks = [function() {
return _fadeOutActor(this._promptBox);
return GdmUtil.fadeOutActor(this._promptBox);
},
function() {
@ -1081,40 +983,24 @@ const LoginDialog = new Lang.Class({
return batch.run();
},
_askQuestion: function(serviceName, question) {
_askQuestion: function(verifier, serviceName, question, passwordChar) {
this._promptLabel.set_text(question);
this._promptEntry.set_text('');
this._promptEntry.clutter_text.set_password_char(passwordChar);
let tasks = [this._showPrompt,
function() {
let _text = this._promptEntry.get_text();
this._promptEntry.reactive = false;
this._promptEntry.add_style_pseudo_class('insensitive');
this._userVerifier.call_answer_query_sync(serviceName, _text, null);
this._userVerifier.answerQuery(serviceName, _text);
}];
let batch = new Batch.ConsecutiveBatch(this, tasks);
return batch.run();
},
_onInfoQuery: function(client, serviceName, question) {
// We only expect questions to come from the main auth service
if (serviceName != _PASSWORD_SERVICE_NAME)
return;
this._promptEntry.set_text('');
this._promptEntry.clutter_text.set_password_char('');
this._askQuestion(serviceName, question);
},
_onSecretInfoQuery: function(client, serviceName, secretQuestion) {
// We only expect secret requests to come from the main auth service
if (serviceName != _PASSWORD_SERVICE_NAME)
return;
this._promptEntry.set_text('');
this._promptEntry.clutter_text.set_password_char('\u25cf');
this._askQuestion(serviceName, secretQuestion);
},
_onSessionOpened: function(client, serviceName) {
this._greeter.call_start_session_when_ready_sync(serviceName, true, null);
@ -1144,7 +1030,7 @@ const LoginDialog = new Lang.Class({
_showTimedLoginAnimation: function() {
this._timedLoginItem.actor.grab_key_focus();
return this._timedLoginItem.showFocusAnimation(this._timedLoginAnimationTime);
return this._timedLoginItem.showTimedLoginIndicator(this._timedLoginAnimationTime);
},
_blockTimedLoginUntilIdle: function() {
@ -1185,7 +1071,6 @@ const LoginDialog = new Lang.Class({
// item.
if (!this.is_loaded) {
this._userList.jumpToItem(this._timedLoginItem);
this._timedLoginItem.showFocusAnimation(0);
}
},
@ -1213,6 +1098,9 @@ const LoginDialog = new Lang.Class({
this._timedLoginBatch = null;
}
if (this._timedLoginItem)
this._timedLoginItem.hideTimedLoginIndicator();
let userName = this._timedLoginItem.user.get_user_name();
if (userName)
@ -1242,15 +1130,8 @@ const LoginDialog = new Lang.Class({
}));
},
_onConversationStopped: function(client, serviceName) {
// if the password service fails, then cancel everything.
// But if, e.g., fingerprint fails, still give
// password authentication a chance to succeed
if (serviceName == _PASSWORD_SERVICE_NAME) {
this._userVerifier.call_cancel_sync(null);
} else if (serviceName == _FINGERPRINT_SERVICE_NAME) {
_fadeOutActor(this._promptFingerprintMessage);
}
_onVerificationFailed: function() {
this._userVerifier.cancel();
},
_onNotListedClicked: function(user) {
@ -1273,13 +1154,7 @@ const LoginDialog = new Lang.Class({
function() {
let hold = new Batch.Hold();
this._userVerifier.call_begin_verification(_PASSWORD_SERVICE_NAME,
null,
Lang.bind(this, function (userVerifier, result) {
this._userVerifier.call_begin_verification_finish (result);
hold.release();
}));
this._userVerifier.begin(null, hold);
return hold;
}];
@ -1288,127 +1163,42 @@ const LoginDialog = new Lang.Class({
},
_fadeInLogo: function() {
return _fadeInActor(this._logoBox);
return GdmUtil.fadeInActor(this._logoBox);
},
_fadeOutLogo: function() {
return _fadeOutActor(this._logoBox);
return GdmUtil.fadeOutActor(this._logoBox);
},
_fadeInBanner: function() {
return _fadeInActor(this._bannerLabel);
return GdmUtil.fadeInActor(this._bannerLabel);
},
_fadeOutBanner: function() {
return _fadeOutActor(this._bannerLabel);
return GdmUtil.fadeOutActor(this._bannerLabel);
},
_fadeInTitleLabel: function() {
return _fadeInActor(this._titleLabel);
return GdmUtil.fadeInActor(this._titleLabel);
},
_fadeOutTitleLabel: function() {
return _fadeOutActor(this._titleLabel);
return GdmUtil.fadeOutActor(this._titleLabel);
},
_fadeInNotListedButton: function() {
return _fadeInActor(this._notListedButton);
return GdmUtil.fadeInActor(this._notListedButton);
},
_fadeOutNotListedButton: function() {
return _fadeOutActor(this._notListedButton);
},
_getUserVerifier: function(userName) {
let hold = new Batch.Hold();
this._userVerifier = null;
// If possible, reauthenticate an already running session,
// so any session specific credentials get updated appropriately
this._greeterClient.open_reauthentication_channel(userName,
null,
Lang.bind(this, function(client, result) {
try {
this._userVerifier = this._greeterClient.open_reauthentication_channel_finish(result);
hold.release();
} catch (e) {
// If there's no session running, or it otherwise fails, then fall back
// to performing verification from this login session
this._greeterClient.get_user_verifier(null,
Lang.bind(this, function(client, result) {
this._userVerifier = this._greeterClient.get_user_verifier_finish(result);
hold.release();
}));
}
}));
hold.connect('release', Lang.bind(this, function() {
if (this._userVerifier) {
let ids = [];
let id;
id = this._userVerifier.connect('info',
Lang.bind(this, this._onInfo));
ids.push(id);
id = this._userVerifier.connect('problem',
Lang.bind(this, this._onProblem));
ids.push(id);
id = this._userVerifier.connect('info-query',
Lang.bind(this, this._onInfoQuery));
ids.push(id);
id = this._userVerifier.connect('secret-info-query',
Lang.bind(this, this._onSecretInfoQuery));
ids.push(id);
id = this._userVerifier.connect('conversation-stopped',
Lang.bind(this, this._onConversationStopped));
ids.push(id);
id = this._userVerifier.connect('reset',
Lang.bind(this, function() {
for (let i = 0; i < ids.length; i++)
this._userVerifier.disconnect(ids[i]);
this._onReset();
}));
ids.push(id);
}
}));
return hold;
return GdmUtil.fadeOutActor(this._notListedButton);
},
_beginVerificationForUser: function(userName) {
let tasks = [function() {
let hold = new Batch.Hold();
this._userVerifier.call_begin_verification_for_user (_PASSWORD_SERVICE_NAME,
userName, null,
Lang.bind(this, function(userVerifier, result) {
this._userVerifier.call_begin_verification_for_user_finish (result);
hold.release();
}));
return hold;
},
let hold = new Batch.Hold();
function() {
let hold = new Batch.Hold();
if (this._haveFingerprintReader) {
this._userVerifier.call_begin_verification_for_user (_FINGERPRINT_SERVICE_NAME,
userName, null,
Lang.bind(this, function(userVerifier, result) {
this._userVerifier.call_begin_verification_for_user_finish (result);
hold.release();
}));
} else {
hold.release();
}
return hold;
}];
let batch = new Batch.ConsecutiveBatch(this, [this._getUserVerifier(userName),
new Batch.ConcurrentBatch(this, tasks)]);
return batch.run();
this._userVerifier.begin(userName, hold);
return hold;
},
_onUserListActivated: function(activatedItem) {

268
js/gdm/util.js Normal file
View File

@ -0,0 +1,268 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Gio = imports.gi.Gio;
const Lang = imports.lang;
const Signals = imports.signals;
const Batch = imports.gdm.batch;
const Fprint = imports.gdm.fingerprint;
const Main = imports.ui.main;
const Params = imports.misc.params;
const Tweener = imports.ui.tweener;
const PASSWORD_SERVICE_NAME = 'gdm-password';
const FINGERPRINT_SERVICE_NAME = 'gdm-fingerprint';
const FADE_ANIMATION_TIME = 0.16;
const LOGIN_SCREEN_SCHEMA = 'org.gnome.login-screen';
const FINGERPRINT_AUTHENTICATION_KEY = 'enable-fingerprint-authentication';
const BANNER_MESSAGE_KEY = 'banner-message-enable';
const BANNER_MESSAGE_TEXT_KEY = 'banner-message-text';
const LOGO_KEY = 'logo';
function fadeInActor(actor) {
if (actor.opacity == 255 && actor.visible)
return null;
let hold = new Batch.Hold();
actor.show();
let [minHeight, naturalHeight] = actor.get_preferred_height(-1);
actor.opacity = 0;
actor.set_height(0);
Tweener.addTween(actor,
{ opacity: 255,
height: naturalHeight,
time: FADE_ANIMATION_TIME,
transition: 'easeOutQuad',
onComplete: function() {
this.set_height(-1);
hold.release();
},
});
return hold;
}
function fadeOutActor(actor) {
if (!actor.visible || actor.opacity == 0) {
actor.opacity = 0;
actor.hide();
return null;
}
let hold = new Batch.Hold();
Tweener.addTween(actor,
{ opacity: 0,
height: 0,
time: FADE_ANIMATION_TIME,
transition: 'easeOutQuad',
onComplete: function() {
this.hide();
this.set_height(-1);
hold.release();
},
});
return hold;
}
const ShellUserVerifier = new Lang.Class({
Name: 'ShellUserVerifier',
_init: function(client, params) {
params = Params.parse(params, { reauthenticationOnly: false });
this._reauthOnly = params.reauthenticationOnly;
this._client = client;
this._settings = new Gio.Settings({ schema: LOGIN_SCREEN_SCHEMA });
this._cancellable = new Gio.Cancellable();
this._fprintManager = new Fprint.FprintManager();
this._checkForFingerprintReader();
},
begin: function(userName, hold) {
this._hold = hold;
this._userName = userName;
if (userName) {
// If possible, reauthenticate an already running session,
// so any session specific credentials get updated appropriately
this._client.open_reauthentication_channel(userName, this._cancellable,
Lang.bind(this, this._reauthenticationChannelOpened));
} else {
this._client.get_user_verifier(this._cancellable, Lang.bind(this, this._userVerifierGot));
}
},
cancel: function() {
this._cancellable.cancel();
if (this._userVerifier)
this._userVerifier.call_cancel_sync(null);
},
clear: function() {
this._cancellable.cancel();
if (this._userVerifier) {
this._userVerifier.run_dispose();
this._userVerifier = null;
}
},
answerQuery: function(serviceName, answer) {
this._userVerifier.call_answer_query(serviceName, answer, this._cancellable, null);
},
_checkForFingerprintReader: function() {
this._haveFingerprintReader = false;
if (!this._settings.get_boolean(FINGERPRINT_AUTHENTICATION_KEY))
return;
this._fprintManager.GetDefaultDeviceRemote(Gio.DBusCallFlags.NONE, this._cancellable, Lang.bind(this,
function(device, error) {
if (!error && device)
this._haveFingerprintReader = true;
}));
},
_reauthenticationChannelOpened: function(client, result) {
try {
this._userVerifier = client.open_reauthentication_channel_finish(result);
this._connectSignals();
this._beginVerification();
this._hold.release();
} catch (e) {
if (this._reauthOnly) {
logError(e, 'Failed to open reauthentication channel');
this._hold.release();
this.emit('verification-failed');
return;
}
// If there's no session running, or it otherwise fails, then fall back
// to performing verification from this login session
client.get_user_verifier(this._cancellable, Lang.bind(this, this._userVerifierGot));
}
},
_userVerifierGot: function(client, result) {
this._userVerifier = client.get_user_verifier_finish(result);
this._connectSignals();
this._beginVerification();
this._hold.release();
},
_connectSignals: function() {
this._userVerifier.connect('info', Lang.bind(this, this._onInfo));
this._userVerifier.connect('problem', Lang.bind(this, this._onProblem));
this._userVerifier.connect('info-query', Lang.bind(this, this._onInfoQuery));
this._userVerifier.connect('secret-info-query', Lang.bind(this, this._onSecretInfoQuery));
this._userVerifier.connect('conversation-stopped', Lang.bind(this, this._onConversationStopped));
this._userVerifier.connect('reset', Lang.bind(this, this._onReset));
this._userVerifier.connect('verification-complete', Lang.bind(this, this._onVerificationComplete));
},
_beginVerification: function() {
this._hold.acquire();
if (this._userName) {
this._userVerifier.call_begin_verification_for_user(PASSWORD_SERVICE_NAME,
this._userName,
this._cancellable,
Lang.bind(this, function(obj, result) {
obj.call_begin_verification_for_user_finish(result);
this._hold.release();
}));
if (this._haveFingerprintReader) {
this._hold.acquire();
this._userVerifier.call_begin_verification_for_user(FINGERPRINT_SERVICE_NAME,
this._userName,
this._cancellable,
Lang.bind(this, function(obj, result) {
obj.call_begin_verification_for_user_finish(result);
this._hold.release();
}));
}
} else {
this._userVerifier.call_begin_verification(PASSWORD_SERVICE_NAME,
this._cancellable,
Lang.bind(this, function(obj, result) {
obj.call_begin_verification_finish(result);
this._hold.release();
}));
}
},
_onInfo: function(client, serviceName, info) {
// We don't display fingerprint messages, because they
// have words like UPEK in them. Instead we use the messages
// as a cue to display our own message.
if (serviceName == FINGERPRINT_SERVICE_NAME &&
this._haveFingerprintReader) {
this.emit('show-fingerprint-prompt');
} else if (serviceName == PASSWORD_SERVICE_NAME) {
Main.notifyError(info);
}
},
_onProblem: function(client, serviceName, problem) {
// we don't want to show auth failed messages to
// users who haven't enrolled their fingerprint.
if (serviceName != PASSWORD_SERVICE_NAME)
return;
Main.notifyError(problem);
},
_onInfoQuery: function(client, serviceName, question) {
// We only expect questions to come from the main auth service
if (serviceName != PASSWORD_SERVICE_NAME)
return;
this.emit('ask-question', serviceName, question, '');
},
_onSecretInfoQuery: function(client, serviceName, secretQuestion) {
// We only expect secret requests to come from the main auth service
if (serviceName != PASSWORD_SERVICE_NAME)
return;
this.emit('ask-question', serviceName, secretQuestion, '\u25cf');
},
_onReset: function() {
this._userVerifier.run_dispose();
this._userVerifier = null;
this._checkForFingerprintReader();
this.emit('reset');
},
_onVerificationComplete: function() {
this.emit('verification-complete');
},
_onConversationStopped: function(client, serviceName) {
// if the password service fails, then cancel everything.
// But if, e.g., fingerprint fails, still give
// password authentication a chance to succeed
if (serviceName == PASSWORD_SERVICE_NAME) {
this.emit('verification-failed');
} else if (serviceName == FINGERPRINT_SERVICE_NAME) {
this.emit('hide-fingerprint-prompt');
}
},
});
Signals.addSignalMethods(ShellUserVerifier.prototype);

View File

@ -1,48 +0,0 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Gio = imports.gi.Gio;
const Lang = imports.lang;
const ScreenSaverIface = <interface name="org.gnome.ScreenSaver">
<method name="GetActive">
<arg type="b" direction="out" />
</method>
<method name="Lock" />
<method name="SetActive">
<arg type="b" direction="in" />
</method>
<signal name="ActiveChanged">
<arg type="b" direction="out" />
</signal>
</interface>;
const ScreenSaverInfo = Gio.DBusInterfaceInfo.new_for_xml(ScreenSaverIface);
function ScreenSaverProxy() {
var self = new Gio.DBusProxy({ g_connection: Gio.DBus.session,
g_interface_name: ScreenSaverInfo.name,
g_interface_info: ScreenSaverInfo,
g_name: 'org.gnome.ScreenSaver',
g_object_path: '/org/gnome/ScreenSaver',
g_flags: (Gio.DBusProxyFlags.DO_NOT_AUTO_START |
Gio.DBusProxyFlags.DO_NOT_LOAD_PROPERTIES) });
self.init(null);
self.screenSaverActive = false;
self.connectSignal('ActiveChanged', function(proxy, senderName, [isActive]) {
self.screenSaverActive = isActive;
});
self.connect('notify::g-name-owner', function() {
if (self.g_name_owner) {
self.GetActiveRemote(function(result, excp) {
if (result) {
let [isActive] = result;
self.screenSaverActive = isActive;
}
});
} else
self.screenSaverActive = false;
});
return self;
}

View File

@ -1,9 +1,6 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Gdk = imports.gi.Gdk;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const Shell = imports.gi.Shell;
const Main = imports.ui.main;
@ -153,7 +150,7 @@ function killall(processName) {
// whatever...
let argv = ['pkill', '-f', '^([^ ]*/)?' + processName + '($| )'];
GLib.spawn_sync(null, argv, null, GLib.SpawnFlags.SEARCH_PATH, null, null);
GLib.spawn_sync(null, argv, null, GLib.SpawnFlags.SEARCH_PATH, null);
// It might be useful to return success/failure, but we'd need
// a wrapper around WIFEXITED and WEXITSTATUS. Since none of
// the current callers care, we don't bother.

View File

@ -9,7 +9,6 @@ const Params = imports.misc.params;
const Shell = imports.gi.Shell;
const Main = imports.ui.main;
const ShellMountOperation = imports.ui.shellMountOperation;
const ScreenSaver = imports.misc.screenSaver;
const GnomeSession = imports.misc.gnomeSession;
const GNOME_SESSION_AUTOMOUNT_INHIBIT = 16;
@ -92,9 +91,7 @@ const AutomountManager = new Lang.Class({
if (!haveSystemd())
this.ckListener = new ConsoleKitManager();
this._ssProxy = new ScreenSaver.ScreenSaverProxy();
this._ssProxy.connectSignal('ActiveChanged',
Lang.bind(this, this._screenSaverActiveChanged));
Main.screenShield.connect('lock-status-changed', Lang.bind(this, this._lockStatusChanged));
this._volumeMonitor = Gio.VolumeMonitor.get();
@ -127,8 +124,8 @@ const AutomountManager = new Lang.Class({
}));
},
_screenSaverActiveChanged: function(object, senderName, [isActive]) {
if (!isActive) {
_lockStatusChanged: function(shield, locked) {
if (!locked) {
this._volumeQueue.forEach(Lang.bind(this, function(volume) {
this._checkAndMountVolume(volume);
}));
@ -166,7 +163,7 @@ const AutomountManager = new Lang.Class({
if (!this.isSessionActive())
return;
if (this._ssProxy.screenSaverActive)
if (Main.screenShield.locked)
return;
global.play_theme_sound(0, 'device-added-media');
@ -178,7 +175,7 @@ const AutomountManager = new Lang.Class({
if (!this.isSessionActive())
return;
if (this._ssProxy.screenSaverActive)
if (Main.screenShield.locked)
return;
global.play_theme_sound(0, 'device-removed-media');
@ -230,7 +227,7 @@ const AutomountManager = new Lang.Class({
if (!this.isSessionActive())
return;
if (this._ssProxy.screenSaverActive) {
if (Main.screenShield.locked) {
if (this._volumeQueue.indexOf(volume) == -1)
this._volumeQueue.push(volume);

View File

@ -495,16 +495,15 @@ const AutorunTransientSource = new Lang.Class({
this.parent(mount.get_name());
this._notification = new AutorunTransientNotification(this);
this._setSummaryIcon(this.createNotificationIcon());
// add ourselves as a source, and popup the notification
Main.messageTray.add(this);
this.notify(this._notification);
},
createNotificationIcon: function() {
createIcon: function(size) {
return new St.Icon({ gicon: this.mount.get_icon(),
icon_size: this.ICON_SIZE });
icon_size: size });
}
});

View File

@ -252,7 +252,6 @@ const BoxPointer = new Lang.Class({
let halfBorder = borderWidth / 2;
let halfBase = Math.floor(base/2);
let borderColor = themeNode.get_color('-arrow-border-color');
let backgroundColor = themeNode.get_color('-arrow-background-color');
let [width, height] = area.get_surface_size();
@ -263,7 +262,6 @@ const BoxPointer = new Lang.Class({
boxWidth -= rise;
}
let cr = area.get_context();
Clutter.cairo_set_source_color(cr, borderColor);
// Translate so that box goes from 0,0 to boxWidth,boxHeight,
// with the arrow poking out of that
@ -359,9 +357,13 @@ const BoxPointer = new Lang.Class({
Clutter.cairo_set_source_color(cr, backgroundColor);
cr.fillPreserve();
Clutter.cairo_set_source_color(cr, borderColor);
cr.setLineWidth(borderWidth);
cr.stroke();
if (borderWidth > 0) {
let borderColor = themeNode.get_color('-arrow-border-color');
Clutter.cairo_set_source_color(cr, borderColor);
cr.setLineWidth(borderWidth);
cr.stroke();
}
},
setPosition: function(sourceActor, alignment) {

View File

@ -279,11 +279,7 @@ const EndSessionDialog = new Lang.Class({
scrollView.hide();
this._applicationList = new St.BoxLayout({ vertical: true });
scrollView.add_actor(this._applicationList,
{ x_fill: true,
y_fill: true,
x_align: St.Align.START,
y_align: St.Align.MIDDLE });
scrollView.add_actor(this._applicationList);
this._applicationList.connect('actor-added',
Lang.bind(this, function() {

View File

@ -197,7 +197,8 @@ const InstallExtensionDialog = new Lang.Class({
key: Clutter.Escape
},
{ label: _("Install"),
action: Lang.bind(this, this._onInstallButtonPressed)
action: Lang.bind(this, this._onInstallButtonPressed),
default: true
}]);
let message = _("Download and install '%s' from extensions.gnome.org?").format(info.name);

View File

@ -93,7 +93,7 @@ const Key = new Lang.Class({
this._getExtendedKeys();
this.actor._extended_keys = this._extended_keyboard;
this._boxPointer.actor.hide();
Main.layoutManager.addChrome(this._boxPointer.actor, { visibleInFullscreen: true });
Main.layoutManager.addChrome(this._boxPointer.actor);
}
},

View File

@ -65,7 +65,8 @@ const KeyringDialog = new Lang.Class({
key: Clutter.Escape
},
{ label: '',
action: Lang.bind(this, this._onContinueButton)
action: Lang.bind(this, this._onContinueButton),
default: true
}]
this.setButtons(buttons);

View File

@ -11,7 +11,6 @@ const St = imports.gi.St;
const DND = imports.ui.dnd;
const Main = imports.ui.main;
const Params = imports.misc.params;
const ScreenSaver = imports.misc.screenSaver;
const Tweener = imports.ui.tweener;
const HOT_CORNER_ACTIVATION_TIMEOUT = 0.5;
@ -33,21 +32,28 @@ const LayoutManager = new Lang.Class({
this._chrome = new Chrome(this);
this.screenShieldGroup = new St.Widget({ name: 'screenShieldGroup',
visible: false,
clip_to_allocation: true,
});
this.addChrome(this.screenShieldGroup);
this.panelBox = new St.BoxLayout({ name: 'panelBox',
vertical: true });
this.addChrome(this.panelBox, { affectsStruts: true });
this.addChrome(this.panelBox, { affectsStruts: true,
trackFullscreen: true });
this.panelBox.connect('allocation-changed',
Lang.bind(this, this._updatePanelBarriers));
this.trayBox = new St.BoxLayout({ name: 'trayBox' });
this.addChrome(this.trayBox, { visibleInFullscreen: true });
this.addChrome(this.trayBox);
this.trayBox.connect('allocation-changed',
Lang.bind(this, this._updateTrayBarrier));
this.keyboardBox = new St.BoxLayout({ name: 'keyboardBox',
reactive: true,
track_hover: true });
this.addChrome(this.keyboardBox, { visibleInFullscreen: true });
this.addChrome(this.keyboardBox);
this._keyboardHeightNotifyId = 0;
global.screen.connect('monitors-changed',
@ -149,6 +155,9 @@ const LayoutManager = new Lang.Class({
},
_updateBoxes: function() {
this.screenShieldGroup.set_position(0, 0);
this.screenShieldGroup.set_size(global.screen_width, global.screen_height);
this.panelBox.set_position(this.primaryMonitor.x, this.primaryMonitor.y);
this.panelBox.set_size(this.primaryMonitor.width, -1);
@ -318,8 +327,10 @@ const LayoutManager = new Lang.Class({
// the window manager struts. Changes to @actor's visibility will
// NOT affect whether or not the strut is present, however.
//
// If %visibleInFullscreen in @params is %true, the actor will be
// visible even when a fullscreen window should be covering it.
// If %trackFullscreen in @params is %true, the actor's visibility
// will be bound to the presence of fullscreen windows on the same
// monitor (it will be hidden whenever a fullscreen window is visible,
// and shown otherwise)
addChrome: function(actor, params) {
this._chrome.addActor(actor, params);
},
@ -333,10 +344,8 @@ const LayoutManager = new Lang.Class({
// struts or input region to cover specific children.
//
// @params can have any of the same values as in addChrome(),
// though some possibilities don't make sense (eg, trying to have
// a %visibleInFullscreen child of a non-%visibleInFullscreen
// parent). By default, @actor has the same params as its chrome
// ancestor.
// though some possibilities don't make sense. By default, @actor has
// the same params as its chrome ancestor.
trackChrome: function(actor, params) {
this._chrome.trackActor(actor, params);
},
@ -542,7 +551,7 @@ const HotCorner = new Lang.Class({
// workspace content.
const defaultParams = {
visibleInFullscreen: false,
trackFullscreen: false,
affectsStruts: false,
affectsInputRegion: true
};
@ -555,6 +564,7 @@ const Chrome = new Lang.Class({
this._monitors = [];
this._inOverview = false;
this._isLocked = false;
this._updateRegionIdle = 0;
this._freezeUpdateCount = 0;
@ -569,16 +579,6 @@ const Chrome = new Lang.Class({
global.screen.connect('notify::n-workspaces',
Lang.bind(this, this._queueUpdateRegions));
this._screenSaverActive = false;
this._screenSaverProxy = new ScreenSaver.ScreenSaverProxy();
this._screenSaverProxy.connectSignal('ActiveChanged', Lang.bind(this, function(proxy, senderName, [isActive]) {
this._onScreenSaverActiveChanged(isActive);
}));
this._screenSaverProxy.GetActiveRemote(Lang.bind(this, function(result, err) {
if (!err)
this._onScreenSaverActiveChanged(result[0]);
}));
this._relayout();
},
@ -587,6 +587,8 @@ const Chrome = new Lang.Class({
Lang.bind(this, this._overviewShowing));
Main.overview.connect('hidden',
Lang.bind(this, this._overviewHidden));
Main.screenShield.connect('lock-status-changed',
Lang.bind(this, this._lockStatusChanged));
},
addActor: function(actor, params) {
@ -681,19 +683,18 @@ const Chrome = new Lang.Class({
_updateVisibility: function() {
for (let i = 0; i < this._trackedActors.length; i++) {
let actorData = this._trackedActors[i], visible;
if (!actorData.trackFullscreen)
continue;
if (!actorData.isToplevel)
continue;
if (this._screenSaverActive)
visible = false;
else if (this._inOverview)
if (this._inOverview || this._isLocked)
visible = true;
else if (!actorData.visibleInFullscreen &&
this.findMonitorForActor(actorData.actor).inFullscreen)
else if (this.findMonitorForActor(actorData.actor).inFullscreen)
visible = false;
else
visible = true;
Main.uiGroup.set_skip_paint(actorData.actor, !visible);
actorData.actor.visible = visible;
}
},
@ -709,6 +710,12 @@ const Chrome = new Lang.Class({
this._queueUpdateRegions();
},
_lockStatusChanged: function(shield, locked) {
this._isLocked = locked;
this._updateVisibility();
this._queueUpdateRegions();
},
_relayout: function() {
this._monitors = this._layoutManager.monitors;
this._primaryMonitor = this._layoutManager.primaryMonitor;
@ -718,12 +725,6 @@ const Chrome = new Lang.Class({
this._queueUpdateRegions();
},
_onScreenSaverActiveChanged: function(screenSaverActive) {
this._screenSaverActive = screenSaverActive;
this._updateVisibility();
this._queueUpdateRegions();
},
_findMonitorForRect: function(x, y, w, h) {
// First look at what monitor the center of the rectangle is at
let cx = x + w/2;

View File

@ -8,6 +8,8 @@ const St = imports.gi.St;
const Params = imports.misc.params;
const Tweener = imports.ui.tweener;
const DEFAULT_FADE_FACTOR = 0.4;
/**
* Lightbox:
* @container: parent Clutter.Container
@ -15,7 +17,8 @@ const Tweener = imports.ui.tweener;
* - inhibitEvents: whether to inhibit events for @container
* - width: shade actor width
* - height: shade actor height
* - fadeTime: seconds used to fade in/out
* - fadeInTime: seconds used to fade in
* - fadeOutTime: seconds used to fade out
*
* Lightbox creates a dark translucent "shade" actor to hide the
* contents of @container, and allows you to specify particular actors
@ -38,12 +41,16 @@ const Lightbox = new Lang.Class({
params = Params.parse(params, { inhibitEvents: false,
width: null,
height: null,
fadeTime: null
fadeInTime: null,
fadeOutTime: null,
fadeFactor: DEFAULT_FADE_FACTOR
});
this._container = container;
this._children = container.get_children();
this._fadeTime = params.fadeTime;
this._fadeInTime = params.fadeInTime;
this._fadeOutTime = params.fadeOutTime;
this._fadeFactor = params.fadeFactor;
this.actor = new St.Bin({ x: 0,
y: 0,
style_class: 'lightbox',
@ -52,6 +59,7 @@ const Lightbox = new Lang.Class({
container.add_actor(this.actor);
this.actor.raise_top();
this.actor.hide();
this.shown = false;
this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
@ -93,24 +101,30 @@ const Lightbox = new Lang.Class({
},
show: function() {
if (this._fadeTime) {
if (this._fadeInTime) {
this.shown = false;
this.actor.opacity = 0;
Tweener.addTween(this.actor,
{ opacity: 255,
time: this._fadeTime,
transition: 'easeOutQuad'
{ opacity: 255 * this._fadeFactor,
time: this._fadeInTime,
transition: 'easeOutQuad',
onComplete: Lang.bind(this, function() {
this.shown = true;
})
});
} else {
this.actor.opacity = 255;
this.actor.opacity = 255 * this._fadeFactor;
this.shown = true;
}
this.actor.show();
},
hide: function() {
if (this._fadeTime) {
this.shown = false;
if (this._fadeOutTime) {
Tweener.addTween(this.actor,
{ opacity: 0,
time: this._fadeTime,
time: this._fadeOutTime,
transition: 'easeOutQuad',
onComplete: Lang.bind(this, function() {
this.actor.hide();

View File

@ -555,8 +555,8 @@ const Inspector = new Lang.Class({
},
_close: function() {
Clutter.ungrab_pointer(this._eventHandler);
Clutter.ungrab_keyboard(this._eventHandler);
Clutter.ungrab_pointer();
Clutter.ungrab_keyboard();
this._eventHandler.destroy();
this._eventHandler = null;
this.emit('closed');

View File

@ -602,7 +602,7 @@ const Magnifier = new Lang.Class({
// Applies only to the first zoom region.
if (this._zoomRegions.length) {
this._zoomRegions[0].setColorSaturation(
this._settings.get_boolean(COLOR_SATURATION_KEY)
this._settings.get_double(COLOR_SATURATION_KEY)
);
}
},
@ -1641,14 +1641,14 @@ const MagShaderEffects = new Lang.Class({
_init: function(uiGroupClone) {
this._inverse = new Shell.InvertLightnessEffect();
this._brightnessContrast = new Clutter.BrightnessContrastEffect();
this._colorSaturation = new Clutter.DesaturateEffect();
this._colorDesaturation = new Clutter.DesaturateEffect();
this._inverse.set_enabled(false);
this._brightnessContrast.set_enabled(false);
this._magView = uiGroupClone;
this._magView.add_effect(this._inverse);
this._magView.add_effect(this._brightnessContrast);
this._magView.add_effect(this._colorSaturation);
this._magView.add_effect(this._colorDesaturation);
},
/**
@ -1659,7 +1659,7 @@ const MagShaderEffects = new Lang.Class({
*/
destroyEffects: function() {
this._magView.clear_effects();
this._colorSaturation = null;
this._colorDesaturation = null;
this._brightnessContrast = null;
this._inverse = null;
this._magView = null;
@ -1684,11 +1684,11 @@ const MagShaderEffects = new Lang.Class({
},
setColorSaturation: function(factor) {
this._colorSaturation.set_factor(factor);
this._colorDesaturation.set_factor(1.0 - factor);
},
getColorSaturation: function() {
return this._colorSaturation.get_factor();
return 1.0 - this._colorDesaturation.get_factor();
},
/**

View File

@ -30,15 +30,16 @@ const LookingGlass = imports.ui.lookingGlass;
const NetworkAgent = imports.ui.networkAgent;
const NotificationDaemon = imports.ui.notificationDaemon;
const WindowAttentionHandler = imports.ui.windowAttentionHandler;
const ScreenShield = imports.ui.screenShield;
const Scripting = imports.ui.scripting;
const SessionMode = imports.ui.sessionMode;
const ShellDBus = imports.ui.shellDBus;
const ShellMountOperation = imports.ui.shellMountOperation;
const TelepathyClient = imports.ui.telepathyClient;
const UnlockDialog = imports.ui.unlockDialog;
const WindowManager = imports.ui.windowManager;
const Magnifier = imports.ui.magnifier;
const XdndHandler = imports.ui.xdndHandler;
const StatusIconDispatcher = imports.ui.statusIconDispatcher;
const Util = imports.misc.util;
const OVERRIDES_SCHEMA = 'org.gnome.shell.overrides';
@ -54,6 +55,7 @@ let runDialog = null;
let lookingGlass = null;
let wm = null;
let messageTray = null;
let screenShield = null;
let notificationDaemon = null;
let windowAttentionHandler = null;
let telepathyClient = null;
@ -62,12 +64,12 @@ let recorder = null;
let sessionMode = null;
let shellDBusService = null;
let shellMountOpDBusService = null;
let screenSaverDBus = null;
let modalCount = 0;
let modalActorFocusStack = [];
let uiGroup = null;
let magnifier = null;
let xdndHandler = null;
let statusIconDispatcher = null;
let keyboard = null;
let layoutManager = null;
let networkAgent = null;
@ -92,14 +94,21 @@ function createUserSession() {
}
function createGDMSession() {
screenShield.showDialog();
}
function createGDMLoginDialog(parentActor) {
// We do this this here instead of at the top to prevent GDM
// related code from getting loaded in normal user sessions
const LoginDialog = imports.gdm.loginDialog;
let loginDialog = new LoginDialog.LoginDialog();
loginDialog.connect('loaded', function() {
loginDialog.open();
});
let loginDialog = new LoginDialog.LoginDialog(parentActor);
return [loginDialog, true];
}
function createSessionUnlockDialog(parentActor) {
let dialog = new UnlockDialog.UnlockDialog(parentActor);
return [dialog, false];
}
function createInitialSetupSession() {
@ -203,7 +212,8 @@ function start() {
ctrlAltTabManager = new CtrlAltTab.CtrlAltTabManager();
overview = new Overview.Overview();
magnifier = new Magnifier.Magnifier();
statusIconDispatcher = new StatusIconDispatcher.StatusIconDispatcher();
screenShield = new ScreenShield.ScreenShield();
screenSaverDBus = new ShellDBus.ScreenSaverDBus();
panel = new Panel.Panel();
wm = new WindowManager.WindowManager();
messageTray = new MessageTray.MessageTray();
@ -243,8 +253,6 @@ function start() {
Lang.bind(overview, overview.toggle));
}
statusIconDispatcher.start(messageTray.actor);
// Provide the bus object for gnome-session to
// initiate logouts.
EndSessionDialog.init();
@ -524,6 +532,7 @@ function notify(msg, details) {
messageTray.add(source);
let notification = new MessageTray.Notification(source, msg, details);
notification.setTransient(true);
notification.setShowWhenLocked(true);
source.notify(notification);
}
@ -642,6 +651,10 @@ function _findModal(actor) {
return -1;
}
function isInModalStack(actor) {
return _findModal(actor) != -1;
}
/**
* pushModal:
* @actor: #ClutterActor which will be given keyboard focus
@ -683,7 +696,7 @@ function pushModal(actor, timestamp, options) {
let actorDestroyId = actor.connect('destroy', function() {
let index = _findModal(actor);
if (index >= 0)
modalActorFocusStack.splice(index, 1);
popModal(actor);
});
let curFocus = global.stage.get_key_focus();
let curFocusDestroyId;

View File

@ -394,7 +394,7 @@ Signals.addSignalMethods(FocusGrabber.prototype);
// the content area (as with addBody()).
//
// By default, the icon shown is created by calling
// source.createNotificationIcon(). However, if @params contains an 'icon'
// source.createIcon(). However, if @params contains an 'icon'
// parameter, the passed in icon will be used.
//
// If @params contains a 'titleMarkup', 'bannerMarkup', or
@ -420,6 +420,7 @@ const Notification = new Lang.Class({
// 'transient' is a reserved keyword in JS, so we have to use an alternate variable name
this.isTransient = false;
this.expanded = false;
this.showWhenLocked = false;
this._destroyed = false;
this._useActionIcons = false;
this._customContent = false;
@ -539,7 +540,7 @@ const Notification = new Lang.Class({
this._table.remove_style_class_name('multi-line-notification');
if (!this._icon) {
this._icon = params.icon || this.source.createNotificationIcon();
this._icon = params.icon || this.source.createIcon(this.source.ICON_SIZE);
this._table.add(this._icon, { row: 0,
col: 0,
x_expand: false,
@ -798,10 +799,6 @@ const Notification = new Lang.Class({
return;
button.reactive = sensitive;
if (sensitive)
button.remove_style_pseudo_class('insensitive');
else
button.add_style_pseudo_class('insensitive');
},
setUrgency: function(urgency) {
@ -816,6 +813,14 @@ const Notification = new Lang.Class({
this.isTransient = isTransient;
},
setShowWhenLocked: function(show) {
if (show && !this.isTransient) {
throw new Error('ShowWhenLocked can only be set on a transient notification');
}
this.showWhenLocked = show;
},
setUseActionIcons: function(useIcons) {
this._useActionIcons = useIcons;
},
@ -1029,24 +1034,20 @@ const Notification = new Lang.Class({
});
Signals.addSignalMethods(Notification.prototype);
const Source = new Lang.Class({
Name: 'MessageTraySource',
const SourceActor = new Lang.Class({
Name: 'SourceActor',
ICON_SIZE: 24,
_init: function(title, iconName, iconType) {
this.title = title;
this.iconName = iconName;
this.iconType = iconType;
_init: function(source, size) {
this._source = source;
this._size = size;
this.actor = new Shell.GenericContainer();
this.actor.connect('get-preferred-width', Lang.bind(this, this._getPreferredWidth));
this.actor.connect('get-preferred-height', Lang.bind(this, this._getPreferredHeight));
this.actor.connect('allocate', Lang.bind(this, this._allocate));
this.actor.connect('destroy', Lang.bind(this,
function() {
this._actorDestroyed = true;
}));
this.actor.connect('destroy', Lang.bind(this, function() {
this._actorDestroyed = true;
}));
this._actorDestroyed = false;
this._counterLabel = new St.Label();
@ -1054,21 +1055,24 @@ const Source = new Lang.Class({
child: this._counterLabel });
this._counterBin.hide();
this._iconBin = new St.Bin({ width: this.ICON_SIZE,
height: this.ICON_SIZE,
this._iconBin = new St.Bin({ width: size,
height: size,
x_fill: true,
y_fill: true });
this.actor.add_actor(this._iconBin);
this.actor.add_actor(this._counterBin);
this.isTransient = false;
this.isChat = false;
this.isMuted = false;
this._source.connect('count-changed', Lang.bind(this, this._updateCount));
this._updateCount();
this.notifications = [];
this._source.connect('icon-updated', Lang.bind(this, this._updateIcon));
this._updateIcon();
},
this._setSummaryIcon(this.createNotificationIcon());
setIcon: function(icon) {
this._iconBin.child = icon;
this._iconSet = true;
},
_getPreferredWidth: function (actor, forHeight, alloc) {
@ -1106,15 +1110,51 @@ const Source = new Lang.Class({
this._counterBin.allocate(childBox, flags);
},
_updateIcon: function() {
if (this._actorDestroyed)
return;
if (!this._iconSet)
this._iconBin.child = this._source.createIcon(this._size);
},
_updateCount: function() {
if (this._actorDestroyed)
return;
this._counterBin.visible = this._source.countVisible;
this._counterLabel.set_text(this._source.count.toString());
}
});
const Source = new Lang.Class({
Name: 'MessageTraySource',
ICON_SIZE: 24,
_init: function(title, iconName, iconType) {
this.title = title;
this.iconName = iconName;
this.iconType = iconType;
this.count = 0;
this.isTransient = false;
this.isChat = false;
this.isMuted = false;
this.notifications = [];
this.mainIcon = new SourceActor(this, this.ICON_SIZE);
},
_setCount: function(count, visible) {
if (isNaN(parseInt(count)))
throw new Error("Invalid notification count: " + count);
if (this._actorDestroyed)
return;
this._counterBin.visible = visible;
this._counterLabel.set_text(count.toString());
this.count = count;
this.countVisible = visible;
this.emit('count-changed');
},
_updateCount: function() {
@ -1138,19 +1178,19 @@ const Source = new Lang.Class({
this.emit('muted-changed');
},
// Called to create a new icon actor (of size this.ICON_SIZE).
// Called to create a new icon actor.
// Provides a sane default implementation, override if you need
// something more fancy.
createNotificationIcon: function() {
createIcon: function(size) {
return new St.Icon({ icon_name: this.iconName,
icon_type: this.iconType,
icon_size: this.ICON_SIZE });
icon_size: size });
},
// Unlike createNotificationIcon, this always returns the same actor;
// Unlike createIcon, this always returns the same actor;
// there is only one summary icon actor for a Source.
getSummaryIcon: function() {
return this.actor;
return this.mainIcon.actor;
},
pushNotification: function(notification) {
@ -1194,11 +1234,14 @@ const Source = new Lang.Class({
return false;
},
iconUpdated: function() {
this.emit('icon-updated');
},
//// Protected methods ////
_setSummaryIcon: function(icon) {
if (this._iconBin.child)
this._iconBin.child.destroy();
this._iconBin.child = icon;
this.mainIcon.setIcon(icon);
this.iconUpdated();
},
open: function(notification) {
@ -1216,6 +1259,10 @@ const Source = new Lang.Class({
// Default implementation is to destroy this source, but subclasses can override
_lastNotificationRemoved: function() {
this.destroy();
},
hasResidentNotification: function() {
return this.notifications.some(function(n) { return n.resident; });
}
});
Signals.addSignalMethods(Source.prototype);
@ -1254,12 +1301,12 @@ const SummaryItem = new Lang.Class({
this._sourceBox.add(this._sourceTitleBin, { expand: true, y_fill: false });
this.actor.child = this._sourceBox;
this.notificationStackView = new St.ScrollView({ name: source.isChat ? '' : 'summary-notification-stack-scrollview',
this.notificationStackView = new St.ScrollView({ style_class: source.isChat ? '' : 'summary-notification-stack-scrollview',
vscrollbar_policy: source.isChat ? Gtk.PolicyType.NEVER : Gtk.PolicyType.AUTOMATIC,
hscrollbar_policy: Gtk.PolicyType.NEVER,
style_class: 'vfade' });
this.notificationStack = new St.BoxLayout({ name: 'summary-notification-stack',
vertical: true });
hscrollbar_policy: Gtk.PolicyType.NEVER });
this.notificationStackView.add_style_class_name('vfade');
this.notificationStack = new St.BoxLayout({ style_class: 'summary-notification-stack',
vertical: true });
this.notificationStackView.add_actor(this.notificationStack);
this._stackedNotifications = [];
@ -1457,7 +1504,7 @@ const MessageTray = new Lang.Class({
track_hover: true });
this._summaryBoxPointer.actor.style_class = 'summary-boxpointer';
this._summaryBoxPointer.actor.hide();
Main.layoutManager.addChrome(this._summaryBoxPointer.actor, { visibleInFullscreen: true });
Main.layoutManager.addChrome(this._summaryBoxPointer.actor);
this._summaryBoxPointerItem = null;
this._summaryBoxPointerContentUpdatedId = 0;
@ -1557,6 +1604,9 @@ const MessageTray = new Lang.Class({
}
}));
this._isScreenLocked = false;
Main.screenShield.connect('lock-status-changed', Lang.bind(this, this._onScreenLockStatusChanged));
this._summaryItems = [];
// We keep a list of new summary items that were added to the summary since the last
// time it was shown to the user. We automatically show the summary to the user if there
@ -1663,6 +1713,12 @@ const MessageTray = new Lang.Class({
// *first* and not show the summary item until after it hides.
// So postpone calling _updateState() a tiny bit.
Meta.later_add(Meta.LaterType.BEFORE_REDRAW, Lang.bind(this, function() { this._updateState(); return false; }));
this.emit('summary-item-added', summaryItem);
},
getSummaryItems: function() {
return this._summaryItems;
},
_onSourceDestroy: function(source) {
@ -1737,6 +1793,11 @@ const MessageTray = new Lang.Class({
this._notificationQueue.splice(index, 1);
},
_onScreenLockStatusChanged: function(screenShield, locked) {
this._isScreenLocked = locked;
this._updateState();
},
_lock: function() {
this._locked = true;
},
@ -2067,18 +2128,36 @@ const MessageTray = new Lang.Class({
// at the present time.
_updateState: function() {
// Notifications
let notificationUrgent = this._notificationQueue.length > 0 && this._notificationQueue[0].urgency == Urgency.CRITICAL;
let notificationsPending = this._notificationQueue.length > 0 && ((!this._busy && !this._inFullscreen) || notificationUrgent);
let notificationQueue = this._notificationQueue.filter(Lang.bind(this, function(notification) {
if (this._isScreenLocked)
return notification.showWhenLocked;
else
return true;
}));
let notificationUrgent = notificationQueue.length > 0 && notificationQueue[0].urgency == Urgency.CRITICAL;
// notificationsLimited is false when the screen is locked, because they go through
// different filtering, and we want to show non urgent messages at times
let notificationsLimited = (this._busy || this._inFullscreen) && !this._isScreenLocked;
let notificationsPending = notificationQueue.length > 0 && (!notificationsLimited || notificationUrgent);
let nextNotification = notificationQueue.length > 0 ? notificationQueue[0] : null;
let notificationPinned = this._pointerInTray && !this._pointerInSummary && !this._notificationRemoved;
let notificationExpanded = this._notificationBin.y < - this.actor.height;
let notificationExpired = (this._notificationTimeoutId == 0 && !(this._notification && this._notification.urgency == Urgency.CRITICAL) && !this._pointerInTray && !this._locked && !(this._pointerInKeyboard && notificationExpanded)) || this._notificationRemoved;
let notificationExpired = this._notificationTimeoutId == 0 &&
!(this._notification && this._notification.urgency == Urgency.CRITICAL) &&
!this._pointerInTray &&
!this._locked &&
!(this._pointerInKeyboard && notificationExpanded);
let notificationLockedOut = this._isScreenLocked && (this._notification && !this._notification.showWhenLocked);
let notificationMustClose = this._notificationRemoved || notificationLockedOut || notificationExpired;
let canShowNotification = notificationsPending && this._summaryState == State.HIDDEN;
if (this._notificationState == State.HIDDEN) {
if (canShowNotification)
this._showNotification();
if (canShowNotification) {
this._showNotification(nextNotification);
this._notificationQueue.splice(this._notificationQueue.indexOf(nextNotification), 1);
}
} else if (this._notificationState == State.SHOWN) {
if (notificationExpired)
if (notificationMustClose)
this._hideNotification();
else if (notificationPinned && !notificationExpanded)
this._expandNotification(false);
@ -2099,7 +2178,7 @@ const MessageTray = new Lang.Class({
let summaryOptionalInOverview = this._overviewVisible && !this._locked && !summaryHovered;
let mustHideSummary = (notificationsPending && (notificationUrgent || summaryOptionalInOverview))
|| notificationsVisible;
|| notificationsVisible || this._isScreenLocked;
if (this._summaryState == State.HIDDEN && !mustHideSummary) {
if (summarySummoned) {
@ -2216,8 +2295,8 @@ const MessageTray = new Lang.Class({
}
},
_showNotification: function() {
this._notification = this._notificationQueue.shift();
_showNotification: function(notification) {
this._notification = notification;
this._unseenNotifications.push(this._notification);
if (this._idleMonitorWatchId == 0)
this._idleMonitorWatchId = this.idleMonitor.add_watch(1000,
@ -2566,6 +2645,7 @@ const MessageTray = new Lang.Class({
this._updateState();
}
});
Signals.addSignalMethods(MessageTray.prototype);
const SystemNotificationSource = new Lang.Class({
Name: 'SystemNotificationSource',
@ -2573,6 +2653,7 @@ const SystemNotificationSource = new Lang.Class({
_init: function() {
this.parent(_("System Information"), 'dialog-information', St.IconType.SYMBOLIC);
this.setTransient(true);
},
open: function() {

View File

@ -35,7 +35,9 @@ const ModalDialog = new Lang.Class({
_init: function(params) {
params = Params.parse(params, { shellReactive: false,
styleClass: null });
styleClass: null,
parentActor: Main.uiGroup
});
this.state = State.CLOSED;
this._hasModal = false;
@ -45,7 +47,7 @@ const ModalDialog = new Lang.Class({
x: 0,
y: 0,
accessible_role: Atk.Role.DIALOG });
Main.uiGroup.add_actor(this._group);
params.parentActor.add_actor(this._group);
let constraint = new Clutter.BindConstraint({ source: global.stage,
coordinate: Clutter.BindCoordinate.ALL });
@ -54,7 +56,7 @@ const ModalDialog = new Lang.Class({
this._group.connect('destroy', Lang.bind(this, this._onGroupDestroy));
this._actionKeys = {};
this._group.connect('key-press-event', Lang.bind(this, this._onKeyPressEvent));
this._group.connect('key-release-event', Lang.bind(this, this._onKeyReleaseEvent));
this._backgroundBin = new St.Bin();
this._group.add_actor(this._backgroundBin);
@ -106,6 +108,10 @@ const ModalDialog = new Lang.Class({
this._group.destroy();
},
setActionKey: function(key, action) {
this._actionKeys[key] = action;
},
setButtons: function(buttons) {
let hadChildren = this._buttonLayout.get_children() > 0;
@ -119,11 +125,17 @@ const ModalDialog = new Lang.Class({
let label = buttonInfo['label'];
let action = buttonInfo['action'];
let key = buttonInfo['key'];
let isDefault = buttonInfo['default'];
if (isDefault && !key)
key = Clutter.KEY_Return;
buttonInfo.button = new St.Button({ style_class: 'modal-dialog-button',
reactive: true,
can_focus: true,
label: label });
if (isDefault)
buttonInfo.button.add_style_pseudo_class('default');
let x_alignment;
if (buttons.length == 1)
@ -167,12 +179,16 @@ const ModalDialog = new Lang.Class({
},
_onKeyPressEvent: function(object, keyPressEvent) {
let symbol = keyPressEvent.get_key_symbol();
_onKeyReleaseEvent: function(object, event) {
let symbol = event.get_key_symbol();
let action = this._actionKeys[symbol];
if (action)
if (action) {
action();
return true;
}
return false;
},
_onGroupDestroy: function() {

View File

@ -147,7 +147,7 @@ const NetworkSecretDialog = new Lang.Class({
this._okButton = { label: _("Connect"),
action: Lang.bind(this, this._onOk),
key: Clutter.KEY_Return,
default: true
};
this.setButtons([{ label: _("Cancel"),
@ -165,11 +165,6 @@ const NetworkSecretDialog = new Lang.Class({
}
this._okButton.button.reactive = valid;
this._okButton.button.can_focus = valid;
if (valid)
this._okButton.button.remove_style_pseudo_class('disabled');
else
this._okButton.button.add_style_pseudo_class('disabled');
},
_onOk: function() {

View File

@ -1,6 +1,7 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Clutter = imports.gi.Clutter;
const GdkPixbuf = imports.gi.GdkPixbuf;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const Lang = imports.lang;
@ -87,6 +88,21 @@ const rewriteRules = {
]
};
const STANDARD_TRAY_ICON_IMPLEMENTATIONS = {
'bluetooth-applet': 'bluetooth',
'gnome-volume-control-applet': 'volume', // renamed to gnome-sound-applet
// when moved to control center
'gnome-sound-applet': 'volume',
'nm-applet': 'network',
'gnome-power-manager': 'battery',
'keyboard': 'keyboard',
'a11y-keyboard': 'a11y',
'kbd-scrolllock': 'keyboard',
'kbd-numlock': 'keyboard',
'kbd-capslock': 'keyboard',
'ibus-ui-gtk': 'keyboard'
};
const NotificationDaemon = new Lang.Class({
Name: 'NotificationDaemon',
@ -99,18 +115,19 @@ const NotificationDaemon = new Lang.Class({
this._notifications = {};
this._busProxy = new Bus();
Main.statusIconDispatcher.connect('message-icon-added', Lang.bind(this, this._onTrayIconAdded));
Main.statusIconDispatcher.connect('message-icon-removed', Lang.bind(this, this._onTrayIconRemoved));
this._trayManager = new Shell.TrayManager();
this._trayManager.connect('tray-icon-added', Lang.bind(this, this._onTrayIconAdded));
this._trayManager.connect('tray-icon-removed', Lang.bind(this, this._onTrayIconRemoved));
Shell.WindowTracker.get_default().connect('notify::focus-app',
Lang.bind(this, this._onFocusAppChanged));
Main.overview.connect('hidden',
Lang.bind(this, this._onFocusAppChanged));
this._trayManager.manage_stage(global.stage, Main.messageTray.actor);
},
_iconForNotificationData: function(icon, hints, size) {
let textureCache = St.TextureCache.get_default();
_iconForNotificationData: function(icon, hints) {
// If an icon is not specified, we use 'image-data' or 'image-path' hint for an icon
// and don't show a large image. There are currently many applications that use
// notify_notification_set_icon_from_pixbuf() from libnotify, which in turn sets
@ -121,20 +138,18 @@ const NotificationDaemon = new Lang.Class({
// a large image.
if (icon) {
if (icon.substr(0, 7) == 'file://')
return textureCache.load_uri_async(icon, size, size);
return new Gio.FileIcon({ file: Gio.File.new_for_uri(icon) });
else if (icon[0] == '/') {
let uri = GLib.filename_to_uri(icon, null);
return textureCache.load_uri_async(uri, size, size);
return new Gio.FileIcon({ file: Gio.File.new_for_path(icon) });
} else
return new St.Icon({ icon_name: icon,
icon_type: St.IconType.FULLCOLOR,
icon_size: size });
return new Gio.ThemedIcon({ name: icon });
} else if (hints['image-data']) {
let [width, height, rowStride, hasAlpha,
bitsPerSample, nChannels, data] = hints['image-data'];
return textureCache.load_from_raw(data, hasAlpha, width, height, rowStride, size);
return Shell.util_create_pixbuf_from_data(data, GdkPixbuf.Colorspace.RGB, hasAlpha,
bitsPerSample, width, height, rowStride);
} else if (hints['image-path']) {
return textureCache.load_uri_async(GLib.filename_to_uri(hints['image-path'], null), size, size);
return new Gio.FileIcon({ file: Gio.File.new_for_path(hints['image-path']) });
} else {
let stockIcon;
switch (hints.urgency) {
@ -146,9 +161,7 @@ const NotificationDaemon = new Lang.Class({
stockIcon = 'gtk-dialog-error';
break;
}
return new St.Icon({ icon_name: stockIcon,
icon_type: St.IconType.FULLCOLOR,
icon_size: size });
return new Gio.ThemedIcon({ name: stockIcon });
}
},
@ -341,7 +354,10 @@ const NotificationDaemon = new Lang.Class({
[ndata.id, ndata.icon, ndata.summary, ndata.body,
ndata.actions, ndata.hints, ndata.notification];
let iconActor = this._iconForNotificationData(icon, hints, source.ICON_SIZE);
let gicon = this._iconForNotificationData(icon, hints);
let iconActor = new St.Icon({ gicon: gicon,
icon_type: St.IconType.FULLCOLOR,
icon_size: source.ICON_SIZE });
if (notification == null) {
notification = new MessageTray.Notification(source, summary, body,
@ -421,8 +437,8 @@ const NotificationDaemon = new Lang.Class({
// of the 'transient' hint with hints['transient'] rather than hints.transient
notification.setTransient(hints['transient'] == true);
let sourceIconActor = source.useNotificationIcon ? this._iconForNotificationData(icon, hints, source.ICON_SIZE) : null;
source.processNotification(notification, sourceIconActor);
let sourceGIcon = source.useNotificationIcon ? this._iconForNotificationData(icon, hints) : null;
source.processNotification(notification, sourceGIcon);
},
CloseNotification: function(id) {
@ -483,6 +499,10 @@ const NotificationDaemon = new Lang.Class({
},
_onTrayIconAdded: function(o, icon) {
let wmClass = icon.wm_class.toLowerCase();
if (STANDARD_TRAY_ICON_IMPLEMENTATIONS[wmClass] !== undefined)
return;
let source = this._getSource(icon.title || icon.wm_class || C_("program", "Unknown"), icon.pid, null, null, icon);
},
@ -534,11 +554,11 @@ const Source = new Lang.Class({
this.destroy();
},
processNotification: function(notification, icon) {
if (!this.app)
this._setApp();
if (!this.app && icon)
this._setSummaryIcon(icon);
processNotification: function(notification, gicon) {
if (gicon)
this._gicon = gicon;
if (!this.trayIcon)
this.iconUpdated();
let tracker = Shell.WindowTracker.get_default();
if (notification.resident && this.app && tracker.focus_app == this.app)
@ -606,7 +626,7 @@ const Source = new Lang.Class({
// notification-based icons (ie, not a trayicon) or if it was unset before
if (!this.trayIcon) {
this.useNotificationIcon = false;
this._setSummaryIcon(this.app.create_icon_texture (this.ICON_SIZE));
this.iconUpdated();
}
},
@ -640,8 +660,18 @@ const Source = new Lang.Class({
this.parent();
},
createNotificationIcon: function() {
// We set the summary icon ourselves.
return null;
createIcon: function(size) {
if (this.trayIcon) {
return new Clutter.Clone({ width: size,
height: size,
source: this.trayIcon });
} else if (this.app) {
return this.app.create_icon_texture(size);
} else if (this._gicon) {
return new St.Icon({ gicon: this._gicon,
icon_size: size });
} else {
return null;
}
}
});

View File

@ -75,6 +75,7 @@ const ShellInfo = new Lang.Class({
let notification = null;
if (this._source.notifications.length == 0) {
notification = new MessageTray.Notification(this._source, text, null);
notification.setShowWhenLocked(true);
} else {
notification = this._source.notifications[0];
notification.update(text, null, { clear: true });

View File

@ -467,6 +467,13 @@ const AppMenuButton = new Lang.Class({
this._sync();
},
setLockedState: function(locked) {
if (locked)
this.hide();
else
this._sync();
},
_sync: function() {
let tracker = Shell.WindowTracker.get_default();
let focusedApp = tracker.focus_app;
@ -753,10 +760,11 @@ const PanelCorner = new Lang.Class({
return null;
// Start at the back and work backward
let index = children.length - 1;
while (!children[index].visible && index >= 0)
index--;
let index;
for (index = children.length - 1; index >= 0; index--) {
if (children[index].visible)
break;
}
if (index < 0)
return null;
@ -777,10 +785,11 @@ const PanelCorner = new Lang.Class({
return null;
// Start at the front and work forward
let index = 0;
while (!children[index].visible && index < children.length)
index++;
let index;
for (index = 0; index < children.length; index++) {
if (children[index].visible)
break;
}
if (index == children.length)
return null;
@ -908,6 +917,8 @@ const Panel = new Lang.Class({
this.actor.remove_style_class_name('in-overview');
}));
Main.screenShield.connect('lock-status-changed', Lang.bind(this, this._onLockStateChanged));
this._menus = new PopupMenu.PopupMenuManager(this);
this._leftBox = new St.BoxLayout({ name: 'panelLeft' });
@ -956,10 +967,6 @@ const Panel = new Lang.Class({
this._centerBox.add(this._dateMenu.actor, { y_fill: true });
this._menus.addMenu(this._dateMenu.menu);
/* right */
Main.statusIconDispatcher.connect('status-icon-added', Lang.bind(this, this._onTrayIconAdded));
Main.statusIconDispatcher.connect('status-icon-removed', Lang.bind(this, this._onTrayIconRemoved));
Main.layoutManager.panelBox.add(this.actor);
Main.ctrlAltTabManager.addGroup(this.actor, _("Top Bar"), 'start-here',
{ sortGroup: CtrlAltTab.SortGroup.TOP });
@ -1133,34 +1140,22 @@ const Panel = new Lang.Class({
this._statusArea[role] = indicator;
let destroyId = indicator.connect('destroy', Lang.bind(this, function(emitter) {
this._statusArea[role] = null;
delete this._statusArea[role];
emitter.disconnect(destroyId);
}));
return indicator;
},
_onTrayIconAdded: function(o, icon, role) {
if (Main.sessionMode.statusArea.implementation[role]) {
// This icon is legacy, and replaced by a Shell version
// Hide it
return;
}
_onLockStateChanged: function(shield, locked) {
if (this._activitiesButton)
this._activitiesButton.setLockedState(locked);
if (this._appMenu)
this._appMenu.setLockedState(locked);
if (this._dateMenu)
this._dateMenu.setLockedState(locked);
if (Main.sessionMode.statusArea.order.indexOf(role) == -1)
return;
icon.height = PANEL_ICON_SIZE;
let buttonBox = new PanelMenu.ButtonBox();
let box = buttonBox.actor;
box.add_actor(icon);
this._insertStatusItem(box, Main.sessionMode.statusArea.order.indexOf(role));
},
_onTrayIconRemoved: function(o, icon) {
let box = icon.get_parent();
if (box && box._delegate instanceof PanelMenu.ButtonBox)
box.destroy();
for (let id in this._statusArea)
this._statusArea[id].setLockedState(locked);
},
});

View File

@ -145,6 +145,13 @@ const Button = new Lang.Class({
}
},
setLockedState: function(locked) {
// default behaviour is to hide completely
if (locked)
this.menu.close();
this.actor.visible = !locked;
},
_onButtonPress: function(actor, event) {
if (!this.menu)
return;

View File

@ -135,17 +135,17 @@ const AuthenticationDialog = new Lang.Class({
this._onUserChanged();
this._passwordBox = new St.BoxLayout({ vertical: false });
this._passwordBox = new St.BoxLayout({ vertical: false, style_class: 'prompt-dialog-password-box' });
messageBox.add(this._passwordBox);
this._passwordLabel = new St.Label(({ style_class: 'prompt-dialog-password-label' }));
this._passwordBox.add(this._passwordLabel);
this._passwordBox.add(this._passwordLabel, { y_fill: false, y_align: St.Align.MIDDLE });
this._passwordEntry = new St.Entry({ style_class: 'prompt-dialog-password-entry',
text: "",
can_focus: true});
ShellEntry.addContextMenu(this._passwordEntry, { isPassword: true });
this._passwordEntry.clutter_text.connect('activate', Lang.bind(this, this._onEntryActivate));
this._passwordBox.add(this._passwordEntry,
{expand: true });
{ expand: true });
this.setInitialKeyFocus(this._passwordEntry);
this._passwordBox.hide();
@ -178,7 +178,8 @@ const AuthenticationDialog = new Lang.Class({
key: Clutter.Escape
},
{ label: _("Authenticate"),
action: Lang.bind(this, this._onAuthenticateButtonPressed)
action: Lang.bind(this, this._onAuthenticateButtonPressed),
default: true
}]);
this._doneEmitted = false;

View File

@ -134,12 +134,7 @@ const PopupBaseMenuItem = new Lang.Class({
this.sensitive = sensitive;
this.actor.reactive = sensitive;
this.actor.can_focus = sensitive;
if (sensitive)
this.actor.remove_style_pseudo_class('insensitive');
else
this.actor.add_style_pseudo_class('insensitive');
this.emit('sensitive-changed', sensitive);
},
@ -773,12 +768,10 @@ const PopupSwitchMenuItem = new Lang.Class({
this._statusLabel.text = text;
this._statusBin.child = this._statusLabel;
this.actor.reactive = false;
this.actor.can_focus = false;
this.actor.accessible_role = Atk.Role.MENU_ITEM;
} else {
this._statusBin.child = this._switch.actor;
this.actor.reactive = true;
this.actor.can_focus = true;
this.actor.accessible_role = Atk.Role.CHECK_MENU_ITEM;
}
this.checkAccessibleState();
@ -875,6 +868,7 @@ const PopupMenuBase = new Lang.Class({
this._activeMenuItem = null;
this._childMenus = [];
this._settingsActions = { };
},
addAction: function(title, callback) {
@ -902,9 +896,19 @@ const PopupMenuBase = new Lang.Class({
Main.overview.hide();
app.activate();
});
this._settingsActions[desktopFile] = menuItem;
return menuItem;
},
setSettingsVisibility: function(visible) {
for (let id in this._settingsActions) {
let item = this._settingsActions[id];
item.actor.visible = visible;
}
},
isEmpty: function() {
return this.box.get_n_children() == 0;
},
@ -1891,11 +1895,7 @@ const RemoteMenu = new Lang.Class({
}));
}
item.actor.reactive = item.actor.can_focus = action.enabled;
if (action.enabled)
item.actor.remove_style_pseudo_class('insensitive');
else
item.actor.add_style_pseudo_class('insensitive');
item.actor.reactive = action.enabled;
destroyId = item.connect('destroy', Lang.bind(this, function() {
item.disconnect(destroyId);
@ -2027,12 +2027,7 @@ const RemoteMenu = new Lang.Class({
if (action.items.length) {
for (let i = 0; i < action.items.length; i++) {
let item = action.items[i];
item.actor.reactive = item.actor.can_focus = action.enabled;
if (action.enabled)
item.actor.remove_style_pseudo_class('insensitive');
else
item.actor.add_style_pseudo_class('insensitive');
item.actor.reactive = action.enabled;
}
}
}

616
js/ui/screenShield.js Normal file
View File

@ -0,0 +1,616 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Clutter = imports.gi.Clutter;
const Gio = imports.gi.Gio;
const GnomeDesktop = imports.gi.GnomeDesktop;
const Lang = imports.lang;
const Meta = imports.gi.Meta;
const Signals = imports.signals;
const St = imports.gi.St;
const GnomeSession = imports.misc.gnomeSession;
const Lightbox = imports.ui.lightbox;
const Main = imports.ui.main;
const MessageTray = imports.ui.messageTray;
const Tweener = imports.ui.tweener;
const SCREENSAVER_SCHEMA = 'org.gnome.desktop.screensaver';
const LOCK_ENABLED_KEY = 'lock-enabled';
const CURTAIN_SLIDE_TIME = 0.8;
// fraction of screen height the arrow must reach before completing
// the slide up automatically
const ARROW_DRAG_TRESHOLD = 0.1;
// The distance in px that the lock screen will move to when pressing
// a key that has no effect in the lock screen (bumping it)
const BUMP_SIZE = 25;
const BUMP_TIME = 0.3;
const SUMMARY_ICON_SIZE = 48;
// Lightbox fading times
// STANDARD_FADE_TIME is used when the session goes idle, while
// SHORT_FADE_TIME is used when requesting lock explicitly from the user menu
const STANDARD_FADE_TIME = 10;
const SHORT_FADE_TIME = 0.8;
const Clock = new Lang.Class({
Name: 'ScreenShieldClock',
CLOCK_FORMAT_KEY: 'clock-format',
CLOCK_SHOW_SECONDS_KEY: 'clock-show-seconds',
_init: function() {
this.actor = new St.BoxLayout({ style_class: 'screen-shield-clock',
vertical: true });
this._time = new St.Label({ style_class: 'screen-shield-clock-time' });
this._date = new St.Label({ style_class: 'screen-shield-clock-date' });
this.actor.add(this._time, { x_align: St.Align.MIDDLE });
this.actor.add(this._date, { x_align: St.Align.MIDDLE });
this._wallClock = new GnomeDesktop.WallClock({ time_only: true });
this._wallClock.connect('notify::clock', Lang.bind(this, this._updateClock));
this._updateClock();
},
_updateClock: function() {
this._time.text = this._wallClock.clock;
let date = new Date();
/* Translators: This is a time format for a date in
long format */
this._date.text = date.toLocaleFormat(_("%A, %B %d"));
},
destroy: function() {
this.actor.destroy();
this._wallClock.run_dispose();
}
});
const NotificationsBox = new Lang.Class({
Name: 'NotificationsBox',
_init: function() {
this.actor = new St.BoxLayout({ vertical: true,
name: 'screenShieldNotifications',
style_class: 'screen-shield-notifications-box' });
this._residentNotificationBox = new St.BoxLayout({ vertical: true,
style_class: 'screen-shield-notifications-box' });
let scrollView = new St.ScrollView({ x_fill: false, x_align: St.Align.MIDDLE });
this._persistentNotificationBox = new St.BoxLayout({ vertical: true,
style_class: 'screen-shield-notifications-box' });
scrollView.add_actor(this._persistentNotificationBox);
this.actor.add(this._residentNotificationBox, { x_fill: true });
this.actor.add(scrollView, { x_fill: true, x_align: St.Align.MIDDLE });
this._items = [];
Main.messageTray.getSummaryItems().forEach(Lang.bind(this, function(item) {
this._summaryItemAdded(Main.messageTray, item);
}));
this._summaryAddedId = Main.messageTray.connect('summary-item-added', Lang.bind(this, this._summaryItemAdded));
},
destroy: function() {
if (this._summaryAddedId) {
Main.messageTray.disconnect(this._summaryAddedId);
this._summaryAddedId = 0;
}
for (let i = 0; i < this._items.length; i++)
this._removeItem(this._items[i]);
this._items = [];
this.actor.destroy();
},
_updateVisibility: function() {
if (this._residentNotificationBox.get_n_children() > 0) {
this.actor.show();
return;
}
let children = this._persistentNotificationBox.get_children()
this.actor.visible = children.some(function(a) { return a.visible; });
},
_sourceIsResident: function(source) {
return source.hasResidentNotification() && !source.isChat;
},
_makeNotificationCountText: function(source) {
if (source.isChat)
return ngettext("%d new message", "%d new messages", source.count).format(source.count);
else
return ngettext("%d new notification", "%d new notifications", source.count).format(source.count);
},
_makeNotificationSource: function(source) {
let box = new St.BoxLayout({ style_class: 'screen-shield-notification-source' });
let sourceActor = new MessageTray.SourceActor(source, SUMMARY_ICON_SIZE);
box.add(sourceActor.actor, { y_fill: true });
let textBox = new St.BoxLayout({ vertical: true });
box.add(textBox);
let label = new St.Label({ text: source.title,
style_class: 'screen-shield-notification-label' });
textBox.add(label);
let countLabel = new St.Label({ text: this._makeNotificationCountText(source),
style_class: 'screen-shield-notification-count-text' });
textBox.add(countLabel);
box.visible = source.count != 0;
return [box, countLabel];
},
_summaryItemAdded: function(tray, item) {
// Ignore transient sources
if (item.source.isTransient)
return;
let obj = {
item: item,
source: item.source,
resident: this._sourceIsResident(item.source),
contentUpdatedId: 0,
sourceDestroyId: 0,
sourceBox: null,
countLabel: null,
};
if (obj.resident) {
item.prepareNotificationStackForShowing();
this._residentNotificationBox.add(item.notificationStackView);
} else {
[obj.sourceBox, obj.countLabel] = this._makeNotificationSource(item.source);
this._persistentNotificationBox.add(obj.sourceBox, { x_fill: false, x_align: St.Align.MIDDLE });
}
obj.contentUpdatedId = item.connect('content-updated', Lang.bind(this, this._onItemContentUpdated));
obj.sourceCountChangedId = item.source.connect('count-changed', Lang.bind(this, this._onSourceChanged));
obj.sourceTitleChangedId = item.source.connect('title-changed', Lang.bind(this, this._onSourceChanged));
obj.sourceDestroyId = item.source.connect('destroy', Lang.bind(this, this._onSourceDestroy));
this._items.push(obj);
this._updateVisibility();
},
_findSource: function(source) {
for (let i = 0; i < this._items.length; i++) {
if (this._items[i].source == source)
return i;
}
return -1;
},
_onItemContentUpdated: function(item) {
let obj = this._items[this._findSource(item.source)];
this._updateItem(obj);
},
_onSourceChanged: function(source) {
let obj = this._items[this._findSource(source)];
this._updateItem(obj);
},
_updateItem: function(obj) {
let itemShouldBeResident = this._sourceIsResident(obj.source);
if (itemShouldBeResident && obj.resident) {
// Nothing to do here, the actor is already updated
return;
}
if (obj.resident && !itemShouldBeResident) {
// make into a regular item
this._residentNotificationBox.remove_actor(obj.item.notificationStackView);
[obj.sourceBox, obj.countLabel] = this._makeNotificationSource(obj.source);
this._persistentNotificationBox.add(obj.sourceBox);
} else if (itemShouldBeResident && !obj.resident) {
// make into a resident item
obj.sourceBox.destroy();
obj.sourceBox = obj.countLabel = null;
obj.item.prepareNotificationStackForShowing();
this._residentNotificationBox.add(obj.item.notificationStackView);
} else {
// just update the counter
obj.countLabel.text = this._makeNotificationCountText(obj.item.source);
obj.sourceBox.visible = obj.source.count != 0;
}
this._updateVisibility();
},
_onSourceDestroy: function(source) {
let idx = this._findSource(source);
this._removeItem(this._items[idx]);
this._items.splice(idx, 1);
this._updateVisibility();
},
_removeItem: function(obj) {
if (obj.resident) {
this._residentNotificationBox.remove_actor(obj.item.notificationStackView);
obj.item.doneShowingNotificationStack();
} else {
obj.sourceBox.destroy();
}
obj.item.disconnect(obj.contentUpdatedId);
obj.source.disconnect(obj.sourceDestroyId);
obj.source.disconnect(obj.sourceCountChangedId);
},
});
/**
* To test screen shield, make sure to kill gnome-screensaver.
*
* If you are setting org.gnome.desktop.session.idle-delay directly in dconf,
* rather than through System Settings, you also need to set
* org.gnome.settings-daemon.plugins.power.sleep-display-ac and
* org.gnome.settings-daemon.plugins.power.sleep-display-battery to the same value.
* This will ensure that the screen blanks at the right time when it fades out.
* https://bugzilla.gnome.org/show_bug.cgi?id=668703 explains the dependance.
*/
const ScreenShield = new Lang.Class({
Name: 'ScreenShield',
_init: function() {
this.actor = Main.layoutManager.screenShieldGroup;
this._lockScreenGroup = new St.Widget({ x_expand: true,
y_expand: true,
reactive: true,
can_focus: true,
layout_manager: new Clutter.BinLayout()
});
this._background = Meta.BackgroundActor.new_for_screen(global.screen);
this._background.add_effect(new Clutter.BlurEffect());
this._background.add_effect(new Clutter.DesaturateEffect({ factor: 0.6 }));
this._lockScreenGroup.add_actor(this._background);
this._arrow = new St.DrawingArea({ style_class: 'arrow',
reactive: true,
x_align: Clutter.ActorAlign.CENTER,
y_align: Clutter.ActorAlign.END,
// HACK: without these, ClutterBinLayout
// ignores alignment properties on the actor
x_expand: true,
y_expand: true
});
this._arrow.connect('repaint', Lang.bind(this, this._drawArrow));
this._lockScreenGroup.add_actor(this._arrow);
let action = new Clutter.DragAction({ drag_axis: Clutter.DragAxis.Y_AXIS });
action.connect('drag-begin', Lang.bind(this, this._onDragBegin));
action.connect('drag-end', Lang.bind(this, this._onDragEnd));
this._lockScreenGroup.add_action(action);
this._lockDialogGroup = new St.Widget({ x_expand: true,
y_expand: true });
this.actor.add_actor(this._lockDialogGroup);
this.actor.add_actor(this._lockScreenGroup);
this._presence = new GnomeSession.Presence(Lang.bind(this, function(proxy, error) {
if (error) {
logError(error, 'Error while reading gnome-session presence');
return;
}
this._onStatusChanged(proxy.status);
}));
this._presence.connectSignal('StatusChanged', Lang.bind(this, function(proxy, senderName, [status]) {
this._onStatusChanged(status);
}));
this._settings = new Gio.Settings({ schema: SCREENSAVER_SCHEMA });
this._isModal = false;
this._isLocked = false;
this._hasLockScreen = false;
this._lightbox = new Lightbox.Lightbox(Main.uiGroup,
{ inhibitEvents: true,
fadeInTime: STANDARD_FADE_TIME,
fadeFactor: 1 });
},
_onStageKeyRelease: function(actor, event) {
if (!this._isLocked)
return false;
if (event.get_key_symbol() == Clutter.KEY_Escape) {
this._showUnlockDialog(true);
return true;
}
this._bumpLockScreen();
return true;
},
_drawArrow: function() {
let cr = this._arrow.get_context();
let [w, h] = this._arrow.get_surface_size();
let node = this._arrow.get_theme_node();
Clutter.cairo_set_source_color(cr, node.get_foreground_color());
cr.moveTo(0, h);
cr.lineTo(w/2, 0);
cr.lineTo(w, h);
cr.fill();
},
_onDragBegin: function() {
Tweener.removeTweens(this._lockScreenGroup);
},
_onDragEnd: function(action, actor, eventX, eventY, modifiers) {
if (this._lockScreenGroup.y < -(ARROW_DRAG_TRESHOLD * global.stage.height)) {
// Complete motion automatically
this._showUnlockDialog(true);
} else {
// restore the lock screen to its original place
// try to use the same speed as the normal animation
let h = global.stage.height;
let time = CURTAIN_SLIDE_TIME * (-this._lockScreenGroup.y) / h;
Tweener.removeTweens(this._lockScreenGroup);
Tweener.addTween(this._lockScreenGroup,
{ y: 0,
time: time,
transition: 'linear',
onComplete: function() {
this.fixed_position_set = false;
}
});
}
},
_onStatusChanged: function(status) {
if (status == GnomeSession.PresenceStatus.IDLE) {
if (this._dialog) {
this._dialog.cancel();
if (!this._keepDialog) {
this._dialog = null;
}
}
if (!this._isModal) {
Main.pushModal(this.actor);
this._isModal = true;
}
if (!this._isLocked)
this._lightbox.show();
} else {
let lightboxWasShown = this._lightbox.shown;
this._lightbox.hide();
let shouldLock = lightboxWasShown && this._settings.get_boolean(LOCK_ENABLED_KEY);
if (shouldLock || this._isLocked) {
this.lock(false);
} else if (this._isModal) {
this.unlock();
}
}
},
showDialog: function() {
this.lock(true);
this._showUnlockDialog(false);
},
_bumpLockScreen: function() {
Tweener.removeTweens(this._lockScreenGroup);
Tweener.addTween(this._lockScreenGroup,
{ y: -BUMP_SIZE,
time: BUMP_TIME / 2,
transition: 'easeOutQuad',
onComplete: function() {
Tweener.addTween(this,
{ y: 0,
time: BUMP_TIME / 2,
transition: 'easeInQuad' });
}
});
},
_showUnlockDialog: function(animate) {
if (animate) {
// Tween the lock screen out of screen
// try to use the same speed regardless of original position
let h = global.stage.height;
let time = CURTAIN_SLIDE_TIME * (h + this._lockScreenGroup.y) / h;
Tweener.removeTweens(this._lockScreenGroup);
Tweener.addTween(this._lockScreenGroup,
{ y: -h,
time: time,
transition: 'linear',
onComplete: Lang.bind(this, this._hideLockScreen),
});
} else {
this._hideLockScreen();
}
if (!this._dialog) {
[this._dialog, this._keepDialog] = Main.sessionMode.createUnlockDialog(this._lockDialogGroup);
if (!this._dialog) {
// This session mode has no locking capabilities
this.unlock();
return;
}
this._dialog.connect('loaded', Lang.bind(this, function() {
if (!this._dialog.open()) {
log('Could not open login dialog: failed to acquire grab');
this.unlock();
}
}));
this._dialog.connect('failed', Lang.bind(this, this._onUnlockFailed));
this._dialog.connect('unlocked', Lang.bind(this, this._onUnlockSucceded));
}
if (this._keepDialog) {
// Notify the other components that even though we are showing the
// screenshield, we're not in a locked state
// (this happens for the gdm greeter)
this._isLocked = false;
this.emit('lock-status-changed', false);
}
},
_onUnlockFailed: function() {
this._dialog.destroy();
this._dialog = null;
this._resetLockScreen(false);
},
_onUnlockSucceded: function() {
this.unlock();
},
_hideLockScreen: function() {
this._arrow.hide();
this._lockScreenGroup.hide();
},
_resetLockScreen: function(animate) {
this._lockScreenGroup.show();
this._arrow.show();
if (animate) {
this._lockScreenGroup.y = -global.screen_height;
Tweener.removeTweens(this._lockScreenGroup);
Tweener.addTween(this._lockScreenGroup,
{ y: 0,
time: SHORT_FADE_TIME,
transition: 'linear',
onComplete: function() {
this._lockScreenGroup.fixed_position_set = false;
this.emit('lock-screen-shown');
},
onCompleteScope: this
});
} else {
this._lockScreenGroup.fixed_position_set = false;
this.emit('lock-screen-shown');
}
if (!this._stageKeyHandler)
this._stageKeyHandler = global.stage.connect('key-release-event',
Lang.bind(this, this._onStageKeyRelease));
},
// Some of the actors in the lock screen are heavy in
// resources, so we only create them when needed
_prepareLockScreen: function() {
this._lockScreenContentsBox = new St.BoxLayout({ x_align: Clutter.ActorAlign.CENTER,
y_align: Clutter.ActorAlign.CENTER,
x_expand: true,
y_expand: true,
vertical: true });
this._clock = new Clock();
this._lockScreenContentsBox.add(this._clock.actor, { x_fill: true,
y_fill: true });
this._lockScreenGroup.add_actor(this._lockScreenContentsBox);
if (this._settings.get_boolean('show-notifications')) {
this._notificationsBox = new NotificationsBox();
this._lockScreenContentsBox.add(this._notificationsBox.actor, { x_fill: true,
y_fill: true,
expand: true });
}
this._hasLockScreen = true;
},
_clearLockScreen: function() {
this._clock.destroy();
this._clock = null;
if (this._notificationsBox) {
this._notificationsBox.destroy();
this._notificationsBox = null;
}
this._lockScreenContentsBox.destroy();
this._hasLockScreen = false;
},
get locked() {
return this._isLocked;
},
unlock: function() {
if (this._hasLockScreen)
this._clearLockScreen();
if (this._stageKeyHandler) {
global.stage.disconnect(this._stageKeyHandler);
this._stageKeyHandler = 0;
}
if (this._keepDialog) {
// The dialog must be kept alive,
// so immediately go back to it
// This will also reset _isLocked
this._showUnlockDialog(false);
return;
}
if (this._dialog) {
this._dialog.destroy();
this._dialog = null;
}
this._lightbox.hide();
Main.popModal(this.actor);
this.actor.hide();
this._isModal = false;
this._isLocked = false;
this.emit('lock-status-changed', false);
},
lock: function(animate) {
if (!this._hasLockScreen)
this._prepareLockScreen();
if (!this._isModal) {
Main.pushModal(this.actor);
this._isModal = true;
}
this._isLocked = true;
this.actor.show();
this._resetLockScreen(animate);
this.emit('lock-status-changed', true);
},
});
Signals.addSignalMethods(ScreenShield.prototype);

View File

@ -39,7 +39,8 @@ const _modes = {
hasRunDialog: false,
hasWorkspaces: false,
createSession: Main.createGDMSession,
extraStylesheet: global.datadir + '/theme/gdm.css',
createUnlockDialog: Main.createGDMLoginDialog,
extraStylesheet: null,
statusArea: {
order: [
'a11y', 'display', 'keyboard',
@ -86,6 +87,7 @@ const _modes = {
hasRunDialog: true,
hasWorkspaces: true,
createSession: Main.createUserSession,
createUnlockDialog: Main.createSessionUnlockDialog,
extraStylesheet: null,
statusArea: {
order: [
@ -113,6 +115,8 @@ const SessionMode = new Lang.Class({
this._createSession = params.createSession;
delete params.createSession;
this._createUnlockDialog = params.createUnlockDialog;
delete params.createUnlockDialog;
Lang.copyProperties(params, this);
},
@ -120,5 +124,12 @@ const SessionMode = new Lang.Class({
createSession: function() {
if (this._createSession)
this._createSession();
}
},
createUnlockDialog: function() {
if (this._createUnlockDialog)
return this._createUnlockDialog.apply(this, arguments);
else
return null;
},
});

View File

@ -50,6 +50,20 @@ const GnomeShellIface = <interface name="org.gnome.Shell">
<property name="ShellVersion" type="s" access="read" />
</interface>;
const ScreenSaverIface = <interface name="org.gnome.ScreenSaver">
<method name="Lock">
</method>
<method name="GetActive">
<arg name="active" direction="out" type="b" />
</method>
<method name="SetActive">
<arg name="value" direction="in" type="u" />
</method>
<signal name="ActiveChanged">
<arg name="new_value" type="b" />
</signal>
</interface>;
const GnomeShell = new Lang.Class({
Name: 'GnomeShellDBus',
@ -319,3 +333,33 @@ const GnomeShellExtensions = new Lang.Class({
GLib.Variant.new('(sis)', [newState.uuid, newState.state, newState.error]));
}
});
const ScreenSaverDBus = new Lang.Class({
Name: 'ScreenSaverDBus',
_init: function() {
this.parent();
Main.screenShield.connect('lock-status-changed', Lang.bind(this, function(shield, locked) {
this._dbusImpl.emit_signal('ActiveChanged', GLib.Variant.new('(b)', [locked]));
}));
this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(ScreenSaverIface, this);
this._dbusImpl.export(Gio.DBus.session, '/org/gnome/ScreenSaver');
},
Lock: function() {
Main.screenShield.lock(true);
},
SetActive: function(active) {
if (active)
Main.screenShield.lock(true);
else
Main.screenShield.unlock();
},
GetActive: function() {
return Main.screenShield.locked;
}
});

View File

@ -7,7 +7,7 @@ const Main = imports.ui.main;
const Params = imports.misc.params;
const PopupMenu = imports.ui.popupMenu;
const _EntryMenu = new Lang.Class({
const EntryMenu = new Lang.Class({
Name: 'ShellEntryMenu',
Extends: PopupMenu.PopupMenu,
@ -34,18 +34,37 @@ const _EntryMenu = new Lang.Class({
this._pasteItem = item;
this._passwordItem = null;
if (params.isPassword) {
item = new PopupMenu.PopupMenuItem('');
item.connect('activate', Lang.bind(this,
this._onPasswordActivated));
this.addMenuItem(item);
this._passwordItem = item;
}
if (params.isPassword)
this._makePasswordItem();
Main.uiGroup.add_actor(this.actor);
this.actor.hide();
},
_makePasswordItem: function() {
let item = new PopupMenu.PopupMenuItem('');
item.connect('activate', Lang.bind(this,
this._onPasswordActivated));
this.addMenuItem(item);
this._passwordItem = item;
},
get isPassword() {
return this._passwordItem != null;
},
set isPassword(v) {
if (v == this.isPassword)
return;
if (v)
this._makePasswordItem();
else {
this._passwordItem.destroy();
this._passwordItem = null;
}
},
open: function() {
this._updatePasteItem();
this._updateCopyItem();
@ -104,50 +123,50 @@ const _EntryMenu = new Lang.Class({
function _setMenuAlignment(entry, stageX) {
let [success, entryX, entryY] = entry.transform_stage_point(stageX, 0);
if (success)
entry._menu.setSourceAlignment(entryX / entry.width);
entry.menu.setSourceAlignment(entryX / entry.width);
};
function _onClicked(action, actor) {
let entry = actor._menu ? actor : actor.get_parent();
let entry = actor.menu ? actor : actor.get_parent();
if (entry._menu.isOpen) {
entry._menu.close();
if (entry.menu.isOpen) {
entry.menu.close();
} else if (action.get_button() == 3) {
let [stageX, stageY] = action.get_coords();
_setMenuAlignment(entry, stageX);
entry._menu.open();
entry.menu.open();
}
};
function _onLongPress(action, actor, state) {
let entry = actor._menu ? actor : actor.get_parent();
let entry = actor.menu ? actor : actor.get_parent();
if (state == Clutter.LongPressState.QUERY)
return action.get_button() == 1 && !entry._menu.isOpen;
return action.get_button() == 1 && !entry.menu.isOpen;
if (state == Clutter.LongPressState.ACTIVATE) {
let [stageX, stageY] = action.get_coords();
_setMenuAlignment(entry, stageX);
entry._menu.open();
entry.menu.open();
}
return false;
};
function _onPopup(actor) {
let entry = actor._menu ? actor : actor.get_parent();
let entry = actor.menu ? actor : actor.get_parent();
let [success, textX, textY, lineHeight] = entry.clutter_text.position_to_coords(-1);
if (success)
entry._menu.setSourceAlignment(textX / entry.width);
entry._menu.open();
entry.menu.setSourceAlignment(textX / entry.width);
entry.menu.open();
};
function addContextMenu(entry, params) {
if (entry._menu)
if (entry.menu)
return;
entry._menu = new _EntryMenu(entry, params);
entry.menu = new EntryMenu(entry, params);
entry._menuManager = new PopupMenu.PopupMenuManager({ actor: entry });
entry._menuManager.addMenu(entry._menu);
entry._menuManager.addMenu(entry.menu);
let clickAction;

View File

@ -398,7 +398,8 @@ const ShellMountPasswordDialog = new Lang.Class({
key: Clutter.Escape
},
{ label: _("Unlock"),
action: Lang.bind(this, this._onUnlockButton)
action: Lang.bind(this, this._onUnlockButton),
default: true
}];
this.setButtons(buttons);
@ -470,11 +471,7 @@ const ShellProcessesDialog = new Lang.Class({
scrollView.hide();
this._applicationList = new St.BoxLayout({ vertical: true });
scrollView.add_actor(this._applicationList,
{ x_fill: true,
y_fill: true,
x_align: St.Align.START,
y_align: St.Align.MIDDLE });
scrollView.add_actor(this._applicationList);
this._applicationList.connect('actor-added',
Lang.bind(this, function() {

View File

@ -1,18 +1,10 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const GDesktopEnums = imports.gi.GDesktopEnums;
const Gio = imports.gi.Gio;
const Gtk = imports.gi.Gtk;
const Lang = imports.lang;
const Mainloop = imports.mainloop;
const Shell = imports.gi.Shell;
const Signals = imports.signals;
const St = imports.gi.St;
const Main = imports.ui.main;
const PanelMenu = imports.ui.panelMenu;
const PopupMenu = imports.ui.popupMenu;
const Util = imports.misc.util;
const A11Y_SCHEMA = 'org.gnome.desktop.a11y.keyboard';
const KEY_STICKY_KEYS_ENABLED = 'stickykeys-enable';
@ -83,6 +75,10 @@ const ATIndicator = new Lang.Class({
this.menu.addSettingsAction(_("Universal Access Settings"), 'gnome-universal-access-panel.desktop');
},
setLockedState: function(locked) {
this.menu.setSettingsVisibility(!locked);
},
_buildItemExtended: function(string, initial_value, writable, on_set) {
let widget = new PopupMenu.PopupSwitchMenuItem(string, initial_value);
if (!writable)

View File

@ -1,15 +1,11 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Clutter = imports.gi.Clutter;
const Gdk = imports.gi.Gdk;
const GLib = imports.gi.GLib;
const Gio = imports.gi.Gio;
const GnomeBluetoothApplet = imports.gi.GnomeBluetoothApplet;
const Gtk = imports.gi.Gtk;
const GnomeBluetooth = imports.gi.GnomeBluetooth;
const Lang = imports.lang;
const Mainloop = imports.mainloop;
const St = imports.gi.St;
const Shell = imports.gi.Shell;
const Main = imports.ui.main;
const MessageTray = imports.ui.messageTray;
@ -36,11 +32,11 @@ const Indicator = new Lang.Class({
this._applet.connect('notify::killswitch-state', Lang.bind(this, this._updateKillswitch));
this._killswitch.connect('toggled', Lang.bind(this, function() {
let current_state = this._applet.killswitch_state;
if (current_state != GnomeBluetoothApplet.KillswitchState.HARD_BLOCKED &&
current_state != GnomeBluetoothApplet.KillswitchState.NO_ADAPTER) {
if (current_state != GnomeBluetooth.KillswitchState.HARD_BLOCKED &&
current_state != GnomeBluetooth.KillswitchState.NO_ADAPTER) {
this._applet.killswitch_state = this._killswitch.state ?
GnomeBluetoothApplet.KillswitchState.UNBLOCKED:
GnomeBluetoothApplet.KillswitchState.SOFT_BLOCKED;
GnomeBluetooth.KillswitchState.UNBLOCKED:
GnomeBluetooth.KillswitchState.SOFT_BLOCKED;
} else
this._killswitch.setToggleState(false);
}));
@ -92,12 +88,17 @@ const Indicator = new Lang.Class({
this._applet.connect('cancel-request', Lang.bind(this, this._cancelRequest));
},
setLockedState: function(locked) {
this._isLocked = locked;
this._updateKillswitch();
},
_updateKillswitch: function() {
let current_state = this._applet.killswitch_state;
let on = current_state == GnomeBluetoothApplet.KillswitchState.UNBLOCKED;
let has_adapter = current_state != GnomeBluetoothApplet.KillswitchState.NO_ADAPTER;
let can_toggle = current_state != GnomeBluetoothApplet.KillswitchState.NO_ADAPTER &&
current_state != GnomeBluetoothApplet.KillswitchState.HARD_BLOCKED;
let on = current_state == GnomeBluetooth.KillswitchState.UNBLOCKED;
let has_adapter = current_state != GnomeBluetooth.KillswitchState.NO_ADAPTER;
let can_toggle = current_state != GnomeBluetooth.KillswitchState.NO_ADAPTER &&
current_state != GnomeBluetooth.KillswitchState.HARD_BLOCKED;
this._killswitch.setToggleState(on);
if (can_toggle)
@ -106,7 +107,7 @@ const Indicator = new Lang.Class({
/* TRANSLATORS: this means that bluetooth was disabled by hardware rfkill */
this._killswitch.setStatus(_("hardware disabled"));
this.actor.visible = has_adapter;
this.actor.visible = !this._isLocked && has_adapter;
if (on) {
this._discoverable.actor.show();

View File

@ -1,12 +1,9 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Clutter = imports.gi.Clutter;
const GdkPixbuf = imports.gi.GdkPixbuf;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const GnomeDesktop = imports.gi.GnomeDesktop;
const Lang = imports.lang;
const Mainloop = imports.mainloop;
const Shell = imports.gi.Shell;
const St = imports.gi.St;
@ -175,11 +172,16 @@ const InputSourceIndicator = new Lang.Class({
// option if need arises.
if (Main.sessionMode.allowSettings) {
this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
this.menu.addAction(_("Show Keyboard Layout"), Lang.bind(this, this._showLayout));
this._showLayoutItem = this.menu.addAction(_("Show Keyboard Layout"), Lang.bind(this, this._showLayout));
}
this.menu.addSettingsAction(_("Region and Language Settings"), 'gnome-region-panel.desktop');
},
setLockedState: function(locked) {
this._showLayoutItem.actor.visible = !locked;
this.menu.setSettingsVisibility(!locked);
},
_currentInputSourceChanged: function() {
let nVisibleSources = Object.keys(this._layoutItems).length;
if (nVisibleSources < 2)

View File

@ -1,12 +1,9 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const ByteArray = imports.byteArray;
const GLib = imports.gi.GLib;
const GObject = imports.gi.GObject;
const Lang = imports.lang;
const Mainloop = imports.mainloop;
const NetworkManager = imports.gi.NetworkManager;
const NMClient = imports.gi.NMClient;
const Shell = imports.gi.Shell;
const Signals = imports.signals;
const St = imports.gi.St;
@ -1698,6 +1695,15 @@ const NMApplet = new Lang.Class({
this._primaryIcon.icon_name = iconName;
},
setLockedState: function(locked) {
// FIXME: more design discussion is needed before we can
// expose part of this menu
if (locked)
this.menu.close();
this.actor.reactive = !locked;
},
_ensureSource: function() {
if (!this._source) {
this._source = new MessageTray.Source(_("Network Manager"),

View File

@ -2,14 +2,10 @@
const Gio = imports.gi.Gio;
const Lang = imports.lang;
const Mainloop = imports.mainloop;
const Shell = imports.gi.Shell;
const St = imports.gi.St;
const Main = imports.ui.main;
const PanelMenu = imports.ui.panelMenu;
const PopupMenu = imports.ui.popupMenu;
const Util = imports.misc.util;
const BUS_NAME = 'org.gnome.SettingsDaemon';
const OBJECT_PATH = '/org/gnome/SettingsDaemon/Power';
@ -80,6 +76,12 @@ const Indicator = new Lang.Class({
this._devicesChanged();
},
setLockedState: function(locked) {
if (locked)
this.menu.close();
this.actor.reactive = !locked;
},
_readPrimaryDevice: function() {
this._proxy.GetPrimaryDeviceRemote(Lang.bind(this, function(result, error) {
if (error) {

View File

@ -2,16 +2,11 @@
const Clutter = imports.gi.Clutter;
const Lang = imports.lang;
const Mainloop = imports.mainloop;
const Shell = imports.gi.Shell;
const Gvc = imports.gi.Gvc;
const Signals = imports.signals;
const St = imports.gi.St;
const Main = imports.ui.main;
const PanelMenu = imports.ui.panelMenu;
const PopupMenu = imports.ui.popupMenu;
const Util = imports.misc.util;
const VOLUME_ADJUSTMENT_STEP = 0.05; /* Volume adjustment step in % */
@ -62,6 +57,10 @@ const Indicator = new Lang.Class({
this._control.open();
},
setLockedState: function(locked) {
this.menu.setSettingsVisibility(!locked);
},
_onScrollEvent: function(actor, event) {
let direction = event.get_scroll_direction();
let currentVolume = this._output.volume;

View File

@ -1,63 +0,0 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Lang = imports.lang;
const Shell = imports.gi.Shell;
const Signals = imports.signals;
const MessageTray = imports.ui.messageTray;
const NotificationDaemon = imports.ui.notificationDaemon;
const Util = imports.misc.util;
const STANDARD_TRAY_ICON_IMPLEMENTATIONS = {
'bluetooth-applet': 'bluetooth',
'gnome-volume-control-applet': 'volume', // renamed to gnome-sound-applet
// when moved to control center
'gnome-sound-applet': 'volume',
'nm-applet': 'network',
'gnome-power-manager': 'battery',
'keyboard': 'keyboard',
'a11y-keyboard': 'a11y',
'kbd-scrolllock': 'keyboard',
'kbd-numlock': 'keyboard',
'kbd-capslock': 'keyboard',
'ibus-ui-gtk': 'keyboard'
};
const StatusIconDispatcher = new Lang.Class({
Name: 'StatusIconDispatcher',
_init: function() {
this._traymanager = new Shell.TrayManager();
this._traymanager.connect('tray-icon-added', Lang.bind(this, this._onTrayIconAdded));
this._traymanager.connect('tray-icon-removed', Lang.bind(this, this._onTrayIconRemoved));
// Yet-another-Ubuntu-workaround - we have to kill their
// app-indicators, so that applications fall back to normal
// status icons
// http://bugzilla.gnome.org/show_bug.cgi=id=621382
Util.killall('indicator-application-service');
},
start: function(themeWidget) {
this._traymanager.manage_stage(global.stage, themeWidget);
},
_onTrayIconAdded: function(o, icon) {
let wmClass = (icon.wm_class || 'unknown').toLowerCase();
let role = STANDARD_TRAY_ICON_IMPLEMENTATIONS[wmClass];
if (role)
this.emit('status-icon-added', icon, role);
else
this.emit('message-icon-added', icon);
},
_onTrayIconRemoved: function(o, icon) {
let wmClass = (icon.wm_class || 'unknown').toLowerCase();
let role = STANDARD_TRAY_ICON_IMPLEMENTATIONS[wmClass];
if (role)
this.emit('status-icon-removed', icon);
else
this.emit('message-icon-removed', icon);
}
});
Signals.addSignalMethods(StatusIconDispatcher.prototype);

View File

@ -482,9 +482,9 @@ const ChatSource = new Lang.Class({
this._notification.appendAliasChange(oldAlias, newAlias);
},
createNotificationIcon: function() {
createIcon: function(size) {
this._iconBox = new St.Bin({ style_class: 'avatar-box' });
this._iconBox._size = this.ICON_SIZE;
this._iconBox._size = size;
let textureCache = St.TextureCache.get_default();
let file = this._contact.get_avatar_file();
@ -532,8 +532,8 @@ const ChatSource = new Lang.Class({
},
_updateAvatarIcon: function() {
this._setSummaryIcon(this.createNotificationIcon());
this._notification.update(this._notification.title, null, { customContent: true, icon: this.createNotificationIcon() });
this.iconUpdated();
this._notification.update(this._notification.title, null, { customContent: true });
},
open: function(notification) {
@ -1031,9 +1031,9 @@ const ApproverSource = new Lang.Class({
this.parent();
},
createNotificationIcon: function() {
createIcon: function(size) {
return new St.Icon({ gicon: this._gicon,
icon_size: this.ICON_SIZE });
icon_size: size });
}
});

227
js/ui/unlockDialog.js Normal file
View File

@ -0,0 +1,227 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const AccountsService = imports.gi.AccountsService;
const Clutter = imports.gi.Clutter;
const Gdm = imports.gi.Gdm;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const Gtk = imports.gi.Gtk;
const Lang = imports.lang;
const Signals = imports.signals;
const Shell = imports.gi.Shell;
const St = imports.gi.St;
const Main = imports.ui.main;
const ModalDialog = imports.ui.modalDialog;
const ShellEntry = imports.ui.shellEntry;
const Tweener = imports.ui.tweener;
const UserMenu = imports.ui.userMenu;
const Batch = imports.gdm.batch;
const GdmUtil = imports.gdm.util;
// A widget showing the user avatar and name
const UserWidget = new Lang.Class({
Name: 'UserWidget',
_init: function(user) {
this._user = user;
this.actor = new St.BoxLayout({ style_class: 'unlock-dialog-user-name-container',
vertical: false });
this._avatar = new UserMenu.UserAvatarWidget(user);
this.actor.add(this._avatar.actor,
{ x_fill: true, y_fill: true });
this._label = new St.Label({ style_class: 'login-dialog-username' });
this.actor.add(this._label,
{ expand: true,
x_fill: true,
y_align: St.Align.MIDDLE });
this._userLoadedId = this._user.connect('notify::is-loaded',
Lang.bind(this, this._updateUser));
this._userChangedId = this._user.connect('changed',
Lang.bind(this, this._updateUser));
if (this._user.is_loaded)
this._updateUser();
},
destroy: function() {
if (this._userLoadedId != 0) {
this._user.disconnect(this._userLoadedId);
this._userLoadedId = 0;
}
if (this._userChangedId != 0) {
this._user.disconnect(this._userChangedId);
this._userChangedId = 0;
}
this.actor.destroy();
},
_updateUser: function() {
if (this._user.is_loaded)
this._label.text = this._user.get_real_name();
else
this._label.text = '';
this._avatar.update();
}
});
const UnlockDialog = new Lang.Class({
Name: 'UnlockDialog',
Extends: ModalDialog.ModalDialog,
_init: function(parentActor) {
this.parent({ shellReactive: true,
styleClass: 'login-dialog',
parentActor: parentActor
});
this._userManager = AccountsService.UserManager.get_default();
this._userName = GLib.get_user_name();
this._user = this._userManager.get_user(this._userName);
this._greeterClient = new Gdm.Client();
this._userVerifier = new GdmUtil.ShellUserVerifier(this._greeterClient, { reauthenticationOnly: true });
this._userVerifier.connect('reset', Lang.bind(this, this._reset));
this._userVerifier.connect('ask-question', Lang.bind(this, this._onAskQuestion));
this._userVerifier.connect('verification-complete', Lang.bind(this, this._onVerificationComplete));
this._userVerifier.connect('verification-failed', Lang.bind(this, this._onVerificationFailed));
this._userVerifier.connect('show-fingerprint-prompt', Lang.bind(this, this._showFingerprintPrompt));
this._userVerifier.connect('hide-fingerprint-prompt', Lang.bind(this, this._hideFingerprintPrompt));
this._userWidget = new UserWidget(this._user);
this.contentLayout.add_actor(this._userWidget.actor);
this._promptLayout = new St.BoxLayout({ style_class: 'login-dialog-prompt-layout',
vertical: false });
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 });
ShellEntry.addContextMenu(this._promptEntry);
this.setInitialKeyFocus(this._promptEntry);
this._promptEntry.clutter_text.connect('activate', Lang.bind(this, this._doUnlock));
this._promptLayout.add(this._promptEntry,
{ expand: true,
x_fill: true });
this.contentLayout.add_actor(this._promptLayout);
// Translators: this message is shown below the password entry field
// to indicate the user can swipe their finger instead
this._promptFingerprintMessage = new St.Label({ text: _("(or swipe finger)"),
style_class: 'login-dialog-prompt-fingerprint-message' });
this._promptFingerprintMessage.hide();
this.contentLayout.add_actor(this._promptFingerprintMessage);
let otherUserLabel = new St.Label({ text: _("Login as another user"),
style_class: 'login-dialog-not-listed-label' });
this._otherUserButton = new St.Button({ style_class: 'login-dialog-not-listed-button',
can_focus: true,
child: otherUserLabel,
reactive: true,
x_align: St.Align.START,
x_fill: true });
this._otherUserButton.connect('clicked', Lang.bind(this, this._otherUserClicked));
this.contentLayout.add(this._otherUserButton,
{ x_align: St.Align.START,
x_fill: false });
this._okButton = { label: _("Unlock"),
action: Lang.bind(this, this._doUnlock),
default: true };
this.setButtons([this._okButton]);
this.setActionKey(Clutter.KEY_Escape, Lang.bind(this, this._escape));
this._updateOkButton(false);
this._reset();
GLib.idle_add(GLib.PRIORITY_DEFAULT, Lang.bind(this, function() {
this.emit('loaded');
return false;
}));
},
_updateOkButton: function(sensitive) {
this._okButton.button.reactive = sensitive;
},
_reset: function() {
this._userVerifier.begin(this._userName, new Batch.Hold());
},
_onAskQuestion: function(verifier, serviceName, question, passwordChar) {
this._promptLabel.text = question;
this._promptEntry.text = '';
this._promptEntry.clutter_text.set_password_char(passwordChar);
this._promptEntry.menu.isPassword = passwordChar != '';
this._currentQuery = serviceName;
this._updateOkButton(true);
},
_showFingerprintPrompt: function() {
GdmUtil.fadeInActor(this._promptFingerprintMessage);
},
_hideFingerprintPrompt: function() {
GdmUtil.fadeOutActor(this._promptFingerprintMessage);
},
_doUnlock: function() {
if (!this._currentQuery)
return;
let query = this._currentQuery;
this._currentQuery = null;
this._updateOkButton(false);
this._userVerifier.answerQuery(query, this._promptEntry.text);
},
_onVerificationComplete: function() {
this._userVerifier.clear();
this.emit('unlocked');
},
_onVerificationFailed: function() {
this._userVerifier.cancel();
this.emit('failed');
},
_escape: function() {
this._onVerificationFailed();
},
_otherUserClicked: function(button, event) {
this._userManager.goto_login_session();
this._userVerifier.cancel();
this.emit('failed');
},
destroy: function() {
this._userVerifier.clear();
this.parent();
},
cancel: function() {
this._userVerifier.cancel(null);
this.destroy();
},
});

View File

@ -16,7 +16,6 @@ const GnomeSession = imports.misc.gnomeSession;
const Main = imports.ui.main;
const PanelMenu = imports.ui.panelMenu;
const PopupMenu = imports.ui.popupMenu;
const ScreenSaver = imports.misc.screenSaver;
const Util = imports.misc.util;
const LOCKDOWN_SCHEMA = 'org.gnome.desktop.lockdown';
@ -41,6 +40,34 @@ const IMStatus = {
// Copyright (C) 2004-2005 James M. Cape <jcape@ignore-your.tv>.
// Copyright (C) 2008,2009 Red Hat, Inc.
const UserAvatarWidget = new Lang.Class({
Name: 'UserAvatarWidget',
_init: function(user) {
this._user = user;
this.actor = new St.Bin({ style_class: 'status-chooser-user-icon',
track_hover: true,
reactive: true });
},
update: function() {
let iconFile = this._user.get_icon_file();
if (!GLib.file_test(iconFile, GLib.FileTest.EXISTS))
iconFile = null;
if (iconFile) {
let file = Gio.File.new_for_path(iconFile);
this.actor.child = null;
this.actor.style = 'background-image: url("%s");'.format(iconFile);
} else {
this.actor.style = null;
this.actor.child = new St.Icon({ icon_name: 'avatar-default',
icon_type: St.IconType.SYMBOLIC,
icon_size: DIALOG_ICON_SIZE });
}
}
});
const IMStatusItem = new Lang.Class({
Name: 'IMStatusItem',
@ -108,7 +135,11 @@ const IMStatusChooserItem = new Lang.Class({
this.parent({ reactive: false,
style_class: 'status-chooser' });
this._iconBin = new St.Button({ style_class: 'status-chooser-user-icon' });
this._userManager = AccountsService.UserManager.get_default();
this._user = this._userManager.get_user(GLib.get_user_name());
this._avatar = new UserAvatarWidget(this._user);
this._iconBin = new St.Button({ child: this._avatar.actor });
this.addActor(this._iconBin);
this._iconBin.connect('clicked', Lang.bind(this,
@ -186,10 +217,6 @@ const IMStatusChooserItem = new Lang.Class({
}
}));
this._userManager = AccountsService.UserManager.get_default();
this._user = this._userManager.get_user(GLib.get_user_name());
this._userLoadedId = this._user.connect('notify::is-loaded',
Lang.bind(this,
this._updateUser));
@ -227,44 +254,12 @@ const IMStatusChooserItem = new Lang.Class({
},
_updateUser: function() {
let iconFile = null;
if (this._user.is_loaded) {
if (this._user.is_loaded)
this._name.label.set_text(this._user.get_real_name());
iconFile = this._user.get_icon_file();
if (!GLib.file_test(iconFile, GLib.FileTest.EXISTS))
iconFile = null;
} else {
this._name.label.set_text("");
}
if (iconFile)
this._setIconFromFile(iconFile);
else
this._setIconFromName('avatar-default');
},
this._name.label.set_text("");
_setIconFromFile: function(iconFile) {
this._iconBin.set_style('background-image: url("' + iconFile + '");' +
'background-size: contain;');
this._iconBin.child = null;
},
_setIconFromName: function(iconName) {
this._iconBin.set_style(null);
if (iconName != null) {
let textureCache = St.TextureCache.get_default();
let icon = textureCache.load_icon_name(this._iconBin.get_theme_node(),
iconName,
St.IconType.SYMBOLIC,
DIALOG_ICON_SIZE);
this._iconBin.child = icon;
this._iconBin.show();
} else {
this._iconBin.child = null;
this._iconBin.hide();
}
this._avatar.update();
},
_statusForPresence: function(presence) {
@ -455,7 +450,6 @@ const UserMenuButton = new Lang.Class({
this._accountMgr = Tp.AccountManager.dup();
this._upClient = new UPowerGlib.Client();
this._screenSaverProxy = new ScreenSaver.ScreenSaverProxy();
this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
this._iconBox = new St.Bin();
@ -542,6 +536,12 @@ const UserMenuButton = new Lang.Class({
this._upClient.connect('notify::can-suspend', Lang.bind(this, this._updateSuspendOrPowerOff));
},
setLockedState: function(locked) {
if (locked)
this.menu.close();
this.actor.reactive = !locked;
},
_onDestroy: function() {
this._user.disconnect(this._userLoadedId);
this._user.disconnect(this._userChangedId);
@ -767,16 +767,13 @@ const UserMenuButton = new Lang.Class({
_onLockScreenActivate: function() {
Main.overview.hide();
this._screenSaverProxy.LockRemote();
Main.screenShield.lock(true);
},
_onLoginScreenActivate: function() {
Main.overview.hide();
// Ensure we only move to GDM after the screensaver has activated; in some
// OS configurations, the X server may block event processing on VT switch
this._screenSaverProxy.SetActiveRemote(true, Lang.bind(this, function() {
this._userManager.goto_login_session();
}));
Main.screenShield.lock(false);
this._userManager.goto_login_session();
},
_onQuitSessionActivate: function() {
@ -798,10 +795,13 @@ const UserMenuButton = new Lang.Class({
this._suspendOrPowerOffItem.state == PopupMenu.PopupAlternatingMenuItemState.DEFAULT) {
this._session.ShutdownRemote();
} else {
// Ensure we only suspend after locking the screen
this._screenSaverProxy.LockRemote(Lang.bind(this, function() {
let tmpId = Main.screenShield.connect('lock-screen-shown', Lang.bind(this, function() {
Main.screenShield.disconnect(tmpId);
this._upClient.suspend_sync(null);
}));
Main.screenShield.lock(true);
}
}
});

View File

@ -73,8 +73,8 @@ const Source = new Lang.Class({
this.signalIDs = [];
},
createNotificationIcon : function() {
return this._app.create_icon_texture(this.ICON_SIZE);
createIcon : function(size) {
return this._app.create_icon_texture(size);
},
open : function(notification) {

View File

@ -301,7 +301,8 @@ const WindowClone = new Lang.Class({
if (!this._zoomLightbox)
this._zoomLightbox = new Lightbox.Lightbox(Main.uiGroup,
{ fadeTime: LIGHTBOX_FADE_TIME });
{ fadeInTime: LIGHTBOX_FADE_TIME,
fadeOutTime: LIGHTBOX_FADE_TIME });
this._zoomLightbox.show();
this._zoomLocalOrig = new ScaledPoint(this.actor.x, this.actor.y, this.actor.scale_x, this.actor.scale_y);

View File

@ -187,7 +187,7 @@ const WorkspacesView = new Lang.Class({
activeWorkspace.actor.raise_top();
this.actor.remove_clip(this._x, this._y, this._width, this._height);
this.actor.remove_clip();
for (let w = 0; w < this._workspaces.length; w++)
this._workspaces[w].zoomFromOverview();

View File

@ -37,6 +37,7 @@ js/ui/status/network.js
js/ui/status/power.js
js/ui/status/volume.js
js/ui/telepathyClient.js
js/ui/unlockDialog.js
js/ui/userMenu.js
js/ui/viewSelector.js
js/ui/wanda.js

View File

@ -1,4 +1,2 @@
data/gnome-shell.desktop.in
data/gnome-shell-extension-prefs.desktop.in
data/org.gnome.shell.evolution.calendar.gschema.xml.in
src/calendar-server/evolution-calendar.desktop.in

310
po/ar.po
View File

@ -7,8 +7,8 @@ msgid ""
msgstr ""
"Project-Id-Version: HEAD\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2012-07-09 21:45+0200\n"
"PO-Revision-Date: 2012-07-09 21:46+0200\n"
"POT-Creation-Date: 2012-07-26 22:31+0200\n"
"PO-Revision-Date: 2012-07-26 22:34+0200\n"
"Last-Translator: Khaled Hosny <khaledhosny@eglug.org>\n"
"Language-Team: Arabic <doc@arabeyes.org>\n"
"Language: ar\n"
@ -30,7 +30,7 @@ msgid "Window management and application launching"
msgstr "إدارة النوافذ وإطلاق التطبيقات"
#: ../data/gnome-shell-extension-prefs.desktop.in.in.h:1
#: ../js/extensionPrefs/main.js:153
#: ../js/extensionPrefs/main.js:152
msgid "GNOME Shell Extension Preferences"
msgstr "تفضيلات امتدادات صدفة جنوم"
@ -178,59 +178,59 @@ msgid ""
"a different container format."
msgstr ""
#: ../js/extensionPrefs/main.js:125
#: ../js/extensionPrefs/main.js:124
#, c-format
msgid "There was an error loading the preferences dialog for %s:"
msgstr "حدث خطأ أثناء تشغيل حوار تفضيلات %s:"
#: ../js/extensionPrefs/main.js:165
#: ../js/extensionPrefs/main.js:164
msgid "<b>Extension</b>"
msgstr "<b>الامتداد</b>"
#: ../js/extensionPrefs/main.js:189
#: ../js/extensionPrefs/main.js:188
msgid "Select an extension to configure using the combobox above."
msgstr "اختر امتدادا لضبطه من القائمة أعلاه."
#: ../js/gdm/loginDialog.js:629
#: ../js/gdm/loginDialog.js:550
msgid "Session..."
msgstr "الجلسة..."
#: ../js/gdm/loginDialog.js:800
#: ../js/gdm/loginDialog.js:699
msgctxt "title"
msgid "Sign In"
msgstr "ادخل"
#. Translators: this message is shown below the password entry field
#. to indicate the user can swipe their finger instead
#: ../js/gdm/loginDialog.js:845
#: ../js/gdm/loginDialog.js:744 ../js/ui/unlockDialog.js:124
msgid "(or swipe finger)"
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:866
#: ../js/gdm/loginDialog.js:765
msgid "Not listed?"
msgstr "غير مدرج؟"
#: ../js/gdm/loginDialog.js:1046 ../js/ui/endSessionDialog.js:410
#: ../js/ui/extensionDownloader.js:138 ../js/ui/networkAgent.js:153
#: ../js/gdm/loginDialog.js:908 ../js/ui/endSessionDialog.js:406
#: ../js/ui/extensionDownloader.js:195 ../js/ui/networkAgent.js:153
#: ../js/ui/polkitAuthenticationAgent.js:176
#: ../js/ui/shellMountOperation.js:339 ../js/ui/status/bluetooth.js:431
#: ../js/ui/shellMountOperation.js:396 ../js/ui/status/bluetooth.js:436
msgid "Cancel"
msgstr "ألغِ"
#: ../js/gdm/loginDialog.js:1051
#: ../js/gdm/loginDialog.js:913
msgctxt "button"
msgid "Sign In"
msgstr "ادخل"
#: ../js/gdm/loginDialog.js:1411
#: ../js/gdm/loginDialog.js:1256
msgid "Login Window"
msgstr "نافذة الولوج"
#: ../js/gdm/powerMenu.js:130 ../js/ui/userMenu.js:612
#: ../js/ui/userMenu.js:616 ../js/ui/userMenu.js:730
#: ../js/ui/userMenu.js:616 ../js/ui/userMenu.js:725
msgid "Suspend"
msgstr "علّق"
@ -239,21 +239,21 @@ msgid "Restart"
msgstr "أعِد التشغيل"
#: ../js/gdm/powerMenu.js:140 ../js/ui/userMenu.js:614
#: ../js/ui/userMenu.js:616 ../js/ui/userMenu.js:729
#: ../js/ui/userMenu.js:616 ../js/ui/userMenu.js:724
msgid "Power Off"
msgstr "أطفئ الحاسوب"
#: ../js/misc/util.js:95
#: ../js/misc/util.js:92
msgid "Command not found"
msgstr "لم يُعثَر على الأمر"
#. Replace "Error invoking GLib.shell_parse_argv: " with
#. something nicer
#: ../js/misc/util.js:128
#: ../js/misc/util.js:125
msgid "Could not parse command:"
msgstr "تعذّر تحليل الأمر:"
#: ../js/misc/util.js:136
#: ../js/misc/util.js:133
#, c-format
msgid "Execution of '%s' failed:"
msgstr "فشل تنفيذ '%s':"
@ -420,39 +420,39 @@ msgid "S"
msgstr "السبت"
#. Translators: Text to show if there are no events
#: ../js/ui/calendar.js:681
#: ../js/ui/calendar.js:685
msgid "Nothing Scheduled"
msgstr "الجدول خال"
#. Translators: Shown on calendar heading when selected day occurs on current year
#: ../js/ui/calendar.js:697
#: ../js/ui/calendar.js:701
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:700
#: ../js/ui/calendar.js:704
msgctxt "calendar heading"
msgid "%A, %B %d, %Y"
msgstr "%A %d %B %Y"
#: ../js/ui/calendar.js:710
#: ../js/ui/calendar.js:714
msgid "Today"
msgstr "اليوم"
#: ../js/ui/calendar.js:714
#: ../js/ui/calendar.js:718
msgid "Tomorrow"
msgstr "غدا"
#: ../js/ui/calendar.js:723
#: ../js/ui/calendar.js:727
msgid "This week"
msgstr "هذا الأسبوع"
#: ../js/ui/calendar.js:731
#: ../js/ui/calendar.js:735
msgid "Next week"
msgstr "الأسبوع القادم"
#: ../js/ui/dash.js:239 ../js/ui/messageTray.js:1287
#: ../js/ui/dash.js:238 ../js/ui/messageTray.js:1317
msgid "Remove"
msgstr "أزِل"
@ -575,11 +575,11 @@ msgstr[5] "سيُعاد تشغيل النظام تلقائيا بعد %d ثان
msgid "Restarting the system."
msgstr "يُعاد تشغيل النظام."
#: ../js/ui/extensionDownloader.js:142
#: ../js/ui/extensionDownloader.js:199
msgid "Install"
msgstr "ثبت"
#: ../js/ui/extensionDownloader.js:146
#: ../js/ui/extensionDownloader.js:204
#, c-format
msgid "Download and install '%s' from extensions.gnome.org?"
msgstr "هل تريد تنزيل وتثبيت '%s' من extensions.gnome.org؟"
@ -588,86 +588,86 @@ msgstr "هل تريد تنزيل وتثبيت '%s' من extensions.gnome.org؟"
msgid "tray"
msgstr "لوحة النظام"
#: ../js/ui/keyboard.js:545 ../js/ui/status/keyboard.js:42
#: ../js/ui/status/power.js:203
#: ../js/ui/keyboard.js:545 ../js/ui/status/keyboard.js:149
#: ../js/ui/status/power.js:209
msgid "Keyboard"
msgstr "لوحة المفاتيح"
#: ../js/ui/keyringPrompt.js:85 ../js/ui/polkitAuthenticationAgent.js:273
#: ../js/ui/keyringPrompt.js:86 ../js/ui/polkitAuthenticationAgent.js:274
msgid "Password:"
msgstr "كلمة السرّ:"
#: ../js/ui/keyringPrompt.js:101
#: ../js/ui/keyringPrompt.js:102
msgid "Type again:"
msgstr "أدخلها ثانية:"
#: ../js/ui/lookingGlass.js:696
#: ../js/ui/lookingGlass.js:695
msgid "No extensions installed"
msgstr "لا امتدادات مثبّتة"
#. Translators: argument is an extension UUID.
#: ../js/ui/lookingGlass.js:750
#: ../js/ui/lookingGlass.js:749
#, c-format
msgid "%s has not emitted any errors."
msgstr "لم يصدر %s أي خطأ."
#: ../js/ui/lookingGlass.js:756
#: ../js/ui/lookingGlass.js:755
msgid "Hide Errors"
msgstr "أخفِ الأخطاء"
#: ../js/ui/lookingGlass.js:760 ../js/ui/lookingGlass.js:811
#: ../js/ui/lookingGlass.js:759 ../js/ui/lookingGlass.js:819
msgid "Show Errors"
msgstr "اظهر الأخطاء"
#: ../js/ui/lookingGlass.js:769
#: ../js/ui/lookingGlass.js:768
msgid "Enabled"
msgstr "مفعّل"
#. translators:
#. * The device has been disabled
#: ../js/ui/lookingGlass.js:772 ../src/gvc/gvc-mixer-control.c:1082
#: ../js/ui/lookingGlass.js:771 ../src/gvc/gvc-mixer-control.c:1082
msgid "Disabled"
msgstr "معطّل"
#: ../js/ui/lookingGlass.js:774
#: ../js/ui/lookingGlass.js:773
msgid "Error"
msgstr "خطأ"
#: ../js/ui/lookingGlass.js:776
#: ../js/ui/lookingGlass.js:775
msgid "Out of date"
msgstr "قديم"
#: ../js/ui/lookingGlass.js:778
#: ../js/ui/lookingGlass.js:777
msgid "Downloading"
msgstr "ينزّل"
#: ../js/ui/lookingGlass.js:799
#: ../js/ui/lookingGlass.js:801
msgid "View Source"
msgstr "اعرض المصدر"
#: ../js/ui/lookingGlass.js:805
#: ../js/ui/lookingGlass.js:810
msgid "Web Page"
msgstr "صفحة الوب"
#. Translators: this is a filename used for screencast recording
#: ../js/ui/main.js:129
#: ../js/ui/main.js:140
#, no-c-format
msgid "Screencast from %d %t"
msgstr "تسجيل شاشة من %d %t"
#: ../js/ui/messageTray.js:1280
#: ../js/ui/messageTray.js:1310
msgid "Open"
msgstr "افتح"
#: ../js/ui/messageTray.js:1297
#: ../js/ui/messageTray.js:1327
msgid "Unmute"
msgstr "أطلِق الصوت"
#: ../js/ui/messageTray.js:1297
#: ../js/ui/messageTray.js:1327
msgid "Mute"
msgstr "أصمِت"
#: ../js/ui/messageTray.js:2575
#: ../js/ui/messageTray.js:2638
msgid "System Information"
msgstr "معلومات النظام"
@ -676,118 +676,118 @@ msgid "Connect"
msgstr "اتصل"
#. Cisco LEAP
#: ../js/ui/networkAgent.js:243 ../js/ui/networkAgent.js:255
#: ../js/ui/networkAgent.js:282 ../js/ui/networkAgent.js:302
#: ../js/ui/networkAgent.js:312
#: ../js/ui/networkAgent.js:238 ../js/ui/networkAgent.js:250
#: ../js/ui/networkAgent.js:277 ../js/ui/networkAgent.js:297
#: ../js/ui/networkAgent.js:307
msgid "Password: "
msgstr "كلمة السرّ: "
#. static WEP
#: ../js/ui/networkAgent.js:248
#: ../js/ui/networkAgent.js:243
msgid "Key: "
msgstr "المفتاح: "
#. TTLS and PEAP are actually much more complicated, but this complication
#. is not visible here since we only care about phase2 authentication
#. (and don't even care of which one)
#: ../js/ui/networkAgent.js:280 ../js/ui/networkAgent.js:298
#: ../js/ui/networkAgent.js:275 ../js/ui/networkAgent.js:293
msgid "Username: "
msgstr "اسم المستخدم: "
#: ../js/ui/networkAgent.js:286
#: ../js/ui/networkAgent.js:281
msgid "Identity: "
msgstr "التعريف: "
#: ../js/ui/networkAgent.js:288
#: ../js/ui/networkAgent.js:283
msgid "Private key password: "
msgstr "كلمة سرّ المفتاح الخاص: "
#: ../js/ui/networkAgent.js:300
#: ../js/ui/networkAgent.js:295
msgid "Service: "
msgstr "الخدمة: "
#: ../js/ui/networkAgent.js:329
#: ../js/ui/networkAgent.js:324
msgid "Authentication required by wireless network"
msgstr "تتطلب الشبكة اللاسلكية الاستيثاق"
#: ../js/ui/networkAgent.js:330
#: ../js/ui/networkAgent.js:325
#, c-format
msgid ""
"Passwords or encryption keys are required to access the wireless network "
"'%s'."
msgstr "كلمات السر أو مفاتيح التعمية مطلوبة للوصول إلى الشبكة اللاسلكية '%s'."
#: ../js/ui/networkAgent.js:334
#: ../js/ui/networkAgent.js:329
msgid "Wired 802.1X authentication"
msgstr "استيثاق 802.1X سلكي"
#: ../js/ui/networkAgent.js:336
#: ../js/ui/networkAgent.js:331
msgid "Network name: "
msgstr "اسم الشبكة: "
#: ../js/ui/networkAgent.js:341
#: ../js/ui/networkAgent.js:336
msgid "DSL authentication"
msgstr "استيثاق اتصال DSL"
#: ../js/ui/networkAgent.js:348
#: ../js/ui/networkAgent.js:343
msgid "PIN code required"
msgstr "رمز PIN مطلوب"
#: ../js/ui/networkAgent.js:349
#: ../js/ui/networkAgent.js:344
msgid "PIN code is needed for the mobile broadband device"
msgstr "جهاز شبكة الهاتف المحمول يتطلب رمز PIN"
#: ../js/ui/networkAgent.js:350
#: ../js/ui/networkAgent.js:345
msgid "PIN: "
msgstr "PIN: "
#: ../js/ui/networkAgent.js:356
#: ../js/ui/networkAgent.js:351
msgid "Mobile broadband network password"
msgstr "كلمة سرّ شبكة الهاتف المحمول"
#: ../js/ui/networkAgent.js:357
#: ../js/ui/networkAgent.js:352
#, c-format
msgid "A password is required to connect to '%s'."
msgstr "كلمة السرّ مطلوبة للاتصال ب‍ '%s'."
#: ../js/ui/notificationDaemon.js:486 ../src/shell-app.c:374
#: ../js/ui/notificationDaemon.js:484 ../src/shell-app.c:374
msgctxt "program"
msgid "Unknown"
msgstr "غير معروف"
#: ../js/ui/overview.js:88
#: ../js/ui/overview.js:89
msgid "Undo"
msgstr "تراجع"
#: ../js/ui/overview.js:128
#: ../js/ui/overview.js:129
msgid "Overview"
msgstr "نظرة عامة"
#: ../js/ui/overview.js:198
#: ../js/ui/overview.js:199
msgid "Windows"
msgstr "النوافذ"
#: ../js/ui/overview.js:201
#: ../js/ui/overview.js:202
msgid "Applications"
msgstr "التطبيقات"
#. Translators: this is the name of the dock/favorites area on
#. the left of the overview
#: ../js/ui/overview.js:226
#: ../js/ui/overview.js:227
msgid "Dash"
msgstr "الشريط"
#: ../js/ui/panel.js:564
#: ../js/ui/panel.js:573
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:596
#: ../js/ui/panel.js:605
msgid "Activities"
msgstr "الأنشطة"
#: ../js/ui/panel.js:962
#: ../js/ui/panel.js:975
msgid "Top Bar"
msgstr "الشريط العلوي"
@ -824,8 +824,8 @@ msgstr "استوثق"
#. * requested authentication was not gained; this can happen
#. * because of an authentication error (like invalid password),
#. * for instance.
#: ../js/ui/polkitAuthenticationAgent.js:261
#: ../js/ui/shellMountOperation.js:324
#: ../js/ui/polkitAuthenticationAgent.js:262
#: ../js/ui/shellMountOperation.js:381
msgid "Sorry, that didn't work. Please try again."
msgstr "للأسف لم يُفلح هذا. أعِد المحاولة."
@ -834,7 +834,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:728
#: ../js/ui/popupMenu.js:723
msgid "toggle-switch-us"
msgstr "toggle-switch-intl"
@ -858,23 +858,23 @@ msgstr "انسخ"
msgid "Paste"
msgstr "ألصق"
#: ../js/ui/shellEntry.js:77
#: ../js/ui/shellEntry.js:96
msgid "Show Text"
msgstr "أظهر النص"
#: ../js/ui/shellEntry.js:79
#: ../js/ui/shellEntry.js:98
msgid "Hide Text"
msgstr "أخفِ النص"
#: ../js/ui/shellMountOperation.js:311
#: ../js/ui/shellMountOperation.js:368
msgid "Passphrase"
msgstr "عبارة السر"
#: ../js/ui/shellMountOperation.js:332
#: ../js/ui/shellMountOperation.js:389
msgid "Remember Passphrase"
msgstr "تذكر عبارة السر"
#: ../js/ui/shellMountOperation.js:343
#: ../js/ui/shellMountOperation.js:400 ../js/ui/unlockDialog.js:142
msgid "Unlock"
msgstr "فك القفل"
@ -918,18 +918,18 @@ msgstr "مفاتيح الفأرة"
msgid "Universal Access Settings"
msgstr "إعدادات الإتاحة"
#: ../js/ui/status/accessibility.js:117
#: ../js/ui/status/accessibility.js:121
msgid "High Contrast"
msgstr "تباين عال"
#: ../js/ui/status/accessibility.js:154
#: ../js/ui/status/accessibility.js:158
msgid "Large Text"
msgstr "نص كبير"
#: ../js/ui/status/bluetooth.js:31 ../js/ui/status/bluetooth.js:35
#: ../js/ui/status/bluetooth.js:255 ../js/ui/status/bluetooth.js:308
#: ../js/ui/status/bluetooth.js:339 ../js/ui/status/bluetooth.js:375
#: ../js/ui/status/bluetooth.js:404 ../js/ui/status/network.js:844
#: ../js/ui/status/bluetooth.js:260 ../js/ui/status/bluetooth.js:313
#: ../js/ui/status/bluetooth.js:344 ../js/ui/status/bluetooth.js:380
#: ../js/ui/status/bluetooth.js:409 ../js/ui/status/network.js:844
msgid "Bluetooth"
msgstr "بلوتوث"
@ -950,115 +950,115 @@ msgid "Bluetooth Settings"
msgstr "إعدادات بلوتوث"
#. TRANSLATORS: this means that bluetooth was disabled by hardware rfkill
#: ../js/ui/status/bluetooth.js:107 ../js/ui/status/network.js:211
#: ../js/ui/status/bluetooth.js:112 ../js/ui/status/network.js:211
msgid "hardware disabled"
msgstr "العتاد مُعَطَّل"
#: ../js/ui/status/bluetooth.js:200
#: ../js/ui/status/bluetooth.js:205
msgid "Connection"
msgstr "الاتصال"
#: ../js/ui/status/bluetooth.js:211 ../js/ui/status/network.js:445
#: ../js/ui/status/bluetooth.js:216 ../js/ui/status/network.js:445
msgid "disconnecting..."
msgstr "يقطع الاتّصال..."
#: ../js/ui/status/bluetooth.js:224 ../js/ui/status/network.js:451
#: ../js/ui/status/bluetooth.js:229 ../js/ui/status/network.js:451
#: ../js/ui/status/network.js:911
msgid "connecting..."
msgstr "يتّصل..."
#: ../js/ui/status/bluetooth.js:242
#: ../js/ui/status/bluetooth.js:247
msgid "Send Files..."
msgstr "أرسل ملفات..."
#: ../js/ui/status/bluetooth.js:247
#: ../js/ui/status/bluetooth.js:252
msgid "Browse Files..."
msgstr "تصفح الملفات..."
#: ../js/ui/status/bluetooth.js:256
#: ../js/ui/status/bluetooth.js:261
msgid "Error browsing device"
msgstr "حدث عطل أثناء تصفّح الجهاز"
#: ../js/ui/status/bluetooth.js:257
#: ../js/ui/status/bluetooth.js:262
#, c-format
msgid "The requested device cannot be browsed, error is '%s'"
msgstr "تعذّر تصفح الجهاز، رسالة العطل '%s'"
#: ../js/ui/status/bluetooth.js:265
#: ../js/ui/status/bluetooth.js:270
msgid "Keyboard Settings"
msgstr "إعدادات لوحة المفاتيح"
#: ../js/ui/status/bluetooth.js:268
#: ../js/ui/status/bluetooth.js:273
msgid "Mouse Settings"
msgstr "إعدادات الفأرة"
#: ../js/ui/status/bluetooth.js:273 ../js/ui/status/volume.js:59
#: ../js/ui/status/bluetooth.js:278 ../js/ui/status/volume.js:59
msgid "Sound Settings"
msgstr "إعدادات الصوت"
#: ../js/ui/status/bluetooth.js:340
#: ../js/ui/status/bluetooth.js:345
#, c-format
msgid "Authorization request from %s"
msgstr "طلب تخويل من %s"
#: ../js/ui/status/bluetooth.js:346
#: ../js/ui/status/bluetooth.js:351
#, c-format
msgid "Device %s wants access to the service '%s'"
msgstr "يريد الجهاز %s صلاحية الوصول للخدمة '%s'"
#: ../js/ui/status/bluetooth.js:348
#: ../js/ui/status/bluetooth.js:353
msgid "Always grant access"
msgstr "امنح الصلاحية دائما"
#: ../js/ui/status/bluetooth.js:349
#: ../js/ui/status/bluetooth.js:354
msgid "Grant this time only"
msgstr "امنح هذه المرة فقط"
#: ../js/ui/status/bluetooth.js:350 ../js/ui/telepathyClient.js:1097
#: ../js/ui/status/bluetooth.js:355 ../js/ui/telepathyClient.js:1097
msgid "Reject"
msgstr "ارفض"
#: ../js/ui/status/bluetooth.js:376
#: ../js/ui/status/bluetooth.js:381
#, c-format
msgid "Pairing confirmation for %s"
msgstr "تأكيد مزاوجة %s"
#: ../js/ui/status/bluetooth.js:382 ../js/ui/status/bluetooth.js:412
#: ../js/ui/status/bluetooth.js:387 ../js/ui/status/bluetooth.js:417
#, c-format
msgid "Device %s wants to pair with this computer"
msgstr "يريد الجهاز %s المزاوجة مع هذا الحاسوب"
#: ../js/ui/status/bluetooth.js:383
#: ../js/ui/status/bluetooth.js:388
#, c-format
msgid "Please confirm whether the PIN '%06d' matches the one on the device."
msgstr "من فضلك أكد تطابق الرقم '%06d' مع الموجود على الجهاز."
#: ../js/ui/status/bluetooth.js:385
#: ../js/ui/status/bluetooth.js:390
msgid "Matches"
msgstr "مطابق"
#: ../js/ui/status/bluetooth.js:386
#: ../js/ui/status/bluetooth.js:391
msgid "Does not match"
msgstr "غير مطابق"
#: ../js/ui/status/bluetooth.js:405
#: ../js/ui/status/bluetooth.js:410
#, c-format
msgid "Pairing request for %s"
msgstr "طلب مزاوجة من %s"
#: ../js/ui/status/bluetooth.js:413
#: ../js/ui/status/bluetooth.js:418
msgid "Please enter the PIN mentioned on the device."
msgstr "من فضلك أدخل الرقم المذكور على الجهاز."
#: ../js/ui/status/bluetooth.js:430
#: ../js/ui/status/bluetooth.js:435
msgid "OK"
msgstr "حسنا"
#: ../js/ui/status/keyboard.js:69
#: ../js/ui/status/keyboard.js:178
msgid "Show Keyboard Layout"
msgstr "أظهر تخطيط لوحة المفاتيح"
#: ../js/ui/status/keyboard.js:71
#: ../js/ui/status/keyboard.js:180
msgid "Region and Language Settings"
msgstr "إعدادات الإقليم واللغة"
@ -1163,19 +1163,19 @@ msgstr "اتصالات VPN"
msgid "Network Settings"
msgstr "إعدادات الشّبكة"
#: ../js/ui/status/network.js:1703
#: ../js/ui/status/network.js:1712
msgid "Network Manager"
msgstr "مدير الشبكة"
#: ../js/ui/status/network.js:1796
#: ../js/ui/status/network.js:1805
msgid "Connection failed"
msgstr "فشل الاتصال"
#: ../js/ui/status/network.js:1797
#: ../js/ui/status/network.js:1806
msgid "Activation of network connection failed"
msgstr "فشل تفعيل اتصال الشبكة"
#: ../js/ui/status/network.js:2060
#: ../js/ui/status/network.js:2069
msgid "Networking is disabled"
msgstr "عُطّلت الشبكات"
@ -1189,11 +1189,11 @@ msgstr "إعدادات الطاقة"
#. 0 is reported when UPower does not have enough data
#. to estimate battery life
#: ../js/ui/status/power.js:98
#: ../js/ui/status/power.js:104
msgid "Estimating..."
msgstr "يَحسِب..."
#: ../js/ui/status/power.js:105
#: ../js/ui/status/power.js:111
#, c-format
msgid "%d hour remaining"
msgid_plural "%d hours remaining"
@ -1205,12 +1205,12 @@ msgstr[4] "بقيت %d ساعة"
msgstr[5] "بقيت %d ساعة"
#. TRANSLATORS: this is a time string, as in "%d hours %d minutes remaining"
#: ../js/ui/status/power.js:108
#: ../js/ui/status/power.js:114
#, c-format
msgid "%d %s %d %s remaining"
msgstr "بقي %d %s و%d %s"
#: ../js/ui/status/power.js:110
#: ../js/ui/status/power.js:116
msgid "hour"
msgid_plural "hours"
msgstr[0] "ساعة"
@ -1220,7 +1220,7 @@ msgstr[3] "ساعات"
msgstr[4] "ساعة"
msgstr[5] "ساعة"
#: ../js/ui/status/power.js:110
#: ../js/ui/status/power.js:116
msgid "minute"
msgid_plural "minutes"
msgstr[0] "دقيقة"
@ -1230,7 +1230,7 @@ msgstr[3] "دقائق"
msgstr[4] "دقيقة"
msgstr[5] "دقيقة"
#: ../js/ui/status/power.js:113
#: ../js/ui/status/power.js:119
#, c-format
msgid "%d minute remaining"
msgid_plural "%d minutes remaining"
@ -1241,53 +1241,53 @@ msgstr[3] "بقيت %d دقائق"
msgstr[4] "بقيت %d دقيقة"
msgstr[5] "بقيت %d دقيقة"
#: ../js/ui/status/power.js:116 ../js/ui/status/power.js:186
#: ../js/ui/status/power.js:122 ../js/ui/status/power.js:192
#, c-format
msgctxt "percent of battery remaining"
msgid "%d%%"
msgstr "%d%%"
#: ../js/ui/status/power.js:193
#: ../js/ui/status/power.js:199
msgid "AC adapter"
msgstr "مقبس طاقة"
#: ../js/ui/status/power.js:195
#: ../js/ui/status/power.js:201
msgid "Laptop battery"
msgstr "بطارية حاسوب محمول"
#: ../js/ui/status/power.js:197
#: ../js/ui/status/power.js:203
msgid "UPS"
msgstr "مزود طاقة لا منقطعة (UPS)"
#: ../js/ui/status/power.js:199
#: ../js/ui/status/power.js:205
msgid "Monitor"
msgstr "شاشة"
#: ../js/ui/status/power.js:201
#: ../js/ui/status/power.js:207
msgid "Mouse"
msgstr "فأرة"
#: ../js/ui/status/power.js:205
#: ../js/ui/status/power.js:211
msgid "PDA"
msgstr "مساعد رقمي (PDA)"
#: ../js/ui/status/power.js:207
#: ../js/ui/status/power.js:213
msgid "Cell phone"
msgstr "هاتف محمول"
#: ../js/ui/status/power.js:209
#: ../js/ui/status/power.js:215
msgid "Media player"
msgstr "مشغل وسائط"
#: ../js/ui/status/power.js:211
#: ../js/ui/status/power.js:217
msgid "Tablet"
msgstr "لوحي"
#: ../js/ui/status/power.js:213
#: ../js/ui/status/power.js:219
msgid "Computer"
msgstr "حاسوب"
#: ../js/ui/status/power.js:215
#: ../js/ui/status/power.js:221
msgctxt "device"
msgid "Unknown"
msgstr "غير معروف"
@ -1533,27 +1533,31 @@ msgstr "عدّل الحساب"
msgid "Unknown reason"
msgstr "السبب غير معروف"
#: ../js/ui/userMenu.js:130
#: ../js/ui/unlockDialog.js:129
msgid "Login as another user"
msgstr "لُج كمستخدم آخر"
#: ../js/ui/userMenu.js:161
msgid "Available"
msgstr "متفرّغ"
#: ../js/ui/userMenu.js:133
#: ../js/ui/userMenu.js:164
msgid "Busy"
msgstr "مشغول"
#: ../js/ui/userMenu.js:136
#: ../js/ui/userMenu.js:167
msgid "Invisible"
msgstr "خفي"
#: ../js/ui/userMenu.js:139
#: ../js/ui/userMenu.js:170
msgid "Away"
msgstr "غائب"
#: ../js/ui/userMenu.js:142
#: ../js/ui/userMenu.js:173
msgid "Idle"
msgstr "ساكن"
#: ../js/ui/userMenu.js:145
#: ../js/ui/userMenu.js:176
msgid "Unavailable"
msgstr "مشغول"
@ -1581,7 +1585,7 @@ msgstr "اخرج"
msgid "Lock"
msgstr "أوصِد"
#: ../js/ui/userMenu.js:724
#: ../js/ui/userMenu.js:731
msgid "Install Updates & Restart"
msgstr "ثبّت التحديثات وأعد التشغيل"
@ -1605,7 +1609,7 @@ msgstr ""
msgid "Type to search..."
msgstr "اكتب نصا للبحث عنه..."
#: ../js/ui/viewSelector.js:131 ../src/shell-util.c:253
#: ../js/ui/viewSelector.js:131 ../src/shell-util.c:254
msgid "Search"
msgstr "ابحث"
@ -1666,19 +1670,19 @@ msgstr[5] "%u مدخل"
msgid "System Sounds"
msgstr "أصوات النظام"
#: ../src/main.c:327
#: ../src/main.c:330
msgid "Print version"
msgstr "اطبع الإصدارة"
#: ../src/main.c:333
#: ../src/main.c:336
msgid "Mode used by GDM for login screen"
msgstr "الوضع الذي يستخدمه مدير ولوج جنوم لشاشة الولوج"
#: ../src/main.c:339
#: ../src/main.c:342
msgid "Use a specific mode, e.g. \"gdm\" for login screen"
msgstr "استخدم طورا معينا، مثلا: \"gdm\" لشاشة الولوج"
#: ../src/main.c:345
#: ../src/main.c:348
msgid "List possible modes"
msgstr "اسرد كل الأطوار الممكنة"
@ -1709,13 +1713,13 @@ msgstr "أغلق المستخدم مربع الاستيثاق الحِواري"
#. Translators: this is the same string as the one found in
#. * nautilus
#: ../src/shell-util.c:97
#: ../src/shell-util.c:98
msgid "Home"
msgstr "المنزل"
#. Translators: this is the same string as the one found in
#. * nautilus
#: ../src/shell-util.c:107
#: ../src/shell-util.c:108
msgid "File System"
msgstr "نظام الملفات"
@ -1724,7 +1728,7 @@ msgstr "نظام الملفات"
#. * example, "Trash: some-directory". It means that the
#. * directory called "some-directory" is in the trash.
#.
#: ../src/shell-util.c:303
#: ../src/shell-util.c:304
#, c-format
msgid "%1$s: %2$s"
msgstr "%1$s: %2$s"

310
po/as.po
View File

@ -9,8 +9,8 @@ msgstr ""
"Project-Id-Version: gnome-shell master\n"
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug."
"cgi?product=gnome-shell&keywords=I18N+L10N&component=general\n"
"POT-Creation-Date: 2012-07-07 16:23+0000\n"
"PO-Revision-Date: 2012-07-13 18:27+0530\n"
"POT-Creation-Date: 2012-07-21 17:14+0000\n"
"PO-Revision-Date: 2012-08-03 15:19+0530\n"
"Last-Translator: Nilamdyuti Goswami <ngoswami@redhat.com>\n"
"Language-Team: as_IN <kde-i18n-doc@kde.org>\n"
"Language: \n"
@ -29,7 +29,7 @@ msgid "Window management and application launching"
msgstr "উইন্ডো ব্যৱস্থাপনা আৰু অনুপ্ৰয়োগৰ লঞ্চ"
#: ../data/gnome-shell-extension-prefs.desktop.in.in.h:1
#: ../js/extensionPrefs/main.js:153
#: ../js/extensionPrefs/main.js:152
msgid "GNOME Shell Extension Preferences"
msgstr "GNOME শ্বেল সম্প্ৰসাৰন পছন্দসমূহ"
@ -207,59 +207,59 @@ msgstr ""
"অবিকল্প নথিপত্ৰ নাম হব, আৰু এই সম্প্ৰসাৰন ব্যৱহাৰ কৰিব। ইয়াক এটা ভিন্ন অন্তৰ্ভুক্তক "
"বিন্যাসত ৰেকৰ্ড কৰোতে পৰিৱৰ্তন কৰিব লাগিব।"
#: ../js/extensionPrefs/main.js:125
#: ../js/extensionPrefs/main.js:124
#, c-format
msgid "There was an error loading the preferences dialog for %s:"
msgstr "%s ৰ বাবে পছন্দসমূহ ডাইলগ ল'ড কৰোতে এটা ত্ৰুটি হৈছিল:"
#: ../js/extensionPrefs/main.js:165
#: ../js/extensionPrefs/main.js:164
msgid "<b>Extension</b>"
msgstr "<b>সম্প্ৰসাৰন</b>"
#: ../js/extensionPrefs/main.js:189
#: ../js/extensionPrefs/main.js:188
msgid "Select an extension to configure using the combobox above."
msgstr "উপৰত দিয়া কম্বোবাকচ ব্যৱহাৰ কৰি সংৰূপণ কৰিবলে এটা সম্প্ৰসাৰন বাছক।"
#: ../js/gdm/loginDialog.js:629
#: ../js/gdm/loginDialog.js:550
msgid "Session..."
msgstr "অধিবেশন..."
#: ../js/gdm/loginDialog.js:800
#: ../js/gdm/loginDialog.js:699
msgctxt "title"
msgid "Sign In"
msgstr "ছাইন ইন কৰক"
#. Translators: this message is shown below the password entry field
#. to indicate the user can swipe their finger instead
#: ../js/gdm/loginDialog.js:845
#: ../js/gdm/loginDialog.js:744 ../js/ui/unlockDialog.js:124
msgid "(or swipe finger)"
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:866
#: ../js/gdm/loginDialog.js:765
msgid "Not listed?"
msgstr "তালিকাভুক্ত নহয়?"
#: ../js/gdm/loginDialog.js:1046 ../js/ui/endSessionDialog.js:410
#: ../js/ui/extensionDownloader.js:138 ../js/ui/networkAgent.js:153
#: ../js/gdm/loginDialog.js:908 ../js/ui/endSessionDialog.js:406
#: ../js/ui/extensionDownloader.js:195 ../js/ui/networkAgent.js:153
#: ../js/ui/polkitAuthenticationAgent.js:176
#: ../js/ui/shellMountOperation.js:339 ../js/ui/status/bluetooth.js:431
#: ../js/ui/shellMountOperation.js:396 ../js/ui/status/bluetooth.js:436
msgid "Cancel"
msgstr "বাতিল কৰক"
#: ../js/gdm/loginDialog.js:1051
#: ../js/gdm/loginDialog.js:913
msgctxt "button"
msgid "Sign In"
msgstr "ছাইন ইন কৰক"
#: ../js/gdm/loginDialog.js:1411
#: ../js/gdm/loginDialog.js:1256
msgid "Login Window"
msgstr "লগিন উইন্ডো"
#: ../js/gdm/powerMenu.js:130 ../js/ui/userMenu.js:612
#: ../js/ui/userMenu.js:616 ../js/ui/userMenu.js:730
#: ../js/ui/userMenu.js:616 ../js/ui/userMenu.js:725
msgid "Suspend"
msgstr "বাতিল কৰক"
@ -268,21 +268,21 @@ msgid "Restart"
msgstr "পুনৰাম্ভ কৰক"
#: ../js/gdm/powerMenu.js:140 ../js/ui/userMenu.js:614
#: ../js/ui/userMenu.js:616 ../js/ui/userMenu.js:729
#: ../js/ui/userMenu.js:616 ../js/ui/userMenu.js:724
msgid "Power Off"
msgstr "পাৱাৰ অফ"
#: ../js/misc/util.js:95
#: ../js/misc/util.js:92
msgid "Command not found"
msgstr "কমান্ড পোৱা নগল"
#. Replace "Error invoking GLib.shell_parse_argv: " with
#. something nicer
#: ../js/misc/util.js:128
#: ../js/misc/util.js:125
msgid "Could not parse command:"
msgstr "কমান্ড বিশ্লেষন কৰিব নোৱাৰি:"
#: ../js/misc/util.js:136
#: ../js/misc/util.js:133
#, c-format
msgid "Execution of '%s' failed:"
msgstr "'%s' ৰ প্ৰেৰণ ব্যৰ্থ হল:"
@ -449,39 +449,39 @@ msgid "S"
msgstr "S"
#. Translators: Text to show if there are no events
#: ../js/ui/calendar.js:681
#: ../js/ui/calendar.js:685
msgid "Nothing Scheduled"
msgstr "একো অনুসূচীত কৰা হোৱা নাই"
#. Translators: Shown on calendar heading when selected day occurs on current year
#: ../js/ui/calendar.js:697
#: ../js/ui/calendar.js:701
msgctxt "calendar heading"
msgid "%A, %B %d"
msgstr "%A, %B %d"
#. Translators: Shown on calendar heading when selected day occurs on different year
#: ../js/ui/calendar.js:700
#: ../js/ui/calendar.js:704
msgctxt "calendar heading"
msgid "%A, %B %d, %Y"
msgstr "%A, %B %d, %Y"
#: ../js/ui/calendar.js:710
#: ../js/ui/calendar.js:714
msgid "Today"
msgstr "আজি"
#: ../js/ui/calendar.js:714
#: ../js/ui/calendar.js:718
msgid "Tomorrow"
msgstr "কালি"
#: ../js/ui/calendar.js:723
#: ../js/ui/calendar.js:727
msgid "This week"
msgstr "এই সপ্তাহ"
#: ../js/ui/calendar.js:731
#: ../js/ui/calendar.js:735
msgid "Next week"
msgstr "অহা সপ্তাহ"
#: ../js/ui/dash.js:239 ../js/ui/messageTray.js:1287
#: ../js/ui/dash.js:238 ../js/ui/messageTray.js:1321
msgid "Remove"
msgstr "আতৰাওক"
@ -588,11 +588,11 @@ msgstr[1] "চিস্টেম %d ছেকেণ্ডত স্বচাল
msgid "Restarting the system."
msgstr "চিস্টেম পুনৰাম্ভ কৰা হৈ আছে।"
#: ../js/ui/extensionDownloader.js:142
#: ../js/ui/extensionDownloader.js:199
msgid "Install"
msgstr "ইনস্টল কৰক"
#: ../js/ui/extensionDownloader.js:146
#: ../js/ui/extensionDownloader.js:204
#, c-format
msgid "Download and install '%s' from extensions.gnome.org?"
msgstr "extensions.gnome.org ৰ পৰা '%s' ক ডাউনল'ড আৰু ইনস্টল কৰিব নে?"
@ -601,86 +601,86 @@ msgstr "extensions.gnome.org ৰ পৰা '%s' ক ডাউনল'ড আৰ
msgid "tray"
msgstr "ট্ৰে"
#: ../js/ui/keyboard.js:545 ../js/ui/status/keyboard.js:42
#: ../js/ui/status/power.js:203
#: ../js/ui/keyboard.js:545 ../js/ui/status/keyboard.js:149
#: ../js/ui/status/power.js:209
msgid "Keyboard"
msgstr "কিবৰ্ড"
#: ../js/ui/keyringPrompt.js:85 ../js/ui/polkitAuthenticationAgent.js:273
#: ../js/ui/keyringPrompt.js:86 ../js/ui/polkitAuthenticationAgent.js:274
msgid "Password:"
msgstr "পাছৱাৰ্ড:"
#: ../js/ui/keyringPrompt.js:101
#: ../js/ui/keyringPrompt.js:102
msgid "Type again:"
msgstr "আকৌ টাইপ কৰক:"
#: ../js/ui/lookingGlass.js:696
#: ../js/ui/lookingGlass.js:695
msgid "No extensions installed"
msgstr "কোনো সম্প্ৰসাৰন ইনস্টল কৰা হোৱা নাই"
#. Translators: argument is an extension UUID.
#: ../js/ui/lookingGlass.js:750
#: ../js/ui/lookingGlass.js:749
#, c-format
msgid "%s has not emitted any errors."
msgstr "%s এ কোনো ত্ৰুটি প্ৰেৰণ কৰা নাই।"
#: ../js/ui/lookingGlass.js:756
#: ../js/ui/lookingGlass.js:755
msgid "Hide Errors"
msgstr "ত্ৰুটিসমূহ লুকুৱাওক"
#: ../js/ui/lookingGlass.js:760 ../js/ui/lookingGlass.js:811
#: ../js/ui/lookingGlass.js:759 ../js/ui/lookingGlass.js:819
msgid "Show Errors"
msgstr "ত্ৰুটিসমূহ দেখুৱাওক"
#: ../js/ui/lookingGlass.js:769
#: ../js/ui/lookingGlass.js:768
msgid "Enabled"
msgstr "সামৰ্থবান কৰা আছে"
#. translators:
#. * The device has been disabled
#: ../js/ui/lookingGlass.js:772 ../src/gvc/gvc-mixer-control.c:1082
#: ../js/ui/lookingGlass.js:771 ../src/gvc/gvc-mixer-control.c:1082
msgid "Disabled"
msgstr "অসামৰ্থবান কৰা আছে"
#: ../js/ui/lookingGlass.js:774
#: ../js/ui/lookingGlass.js:773
msgid "Error"
msgstr "ত্ৰুটি"
#: ../js/ui/lookingGlass.js:776
#: ../js/ui/lookingGlass.js:775
msgid "Out of date"
msgstr "পুৰনি"
#: ../js/ui/lookingGlass.js:778
#: ../js/ui/lookingGlass.js:777
msgid "Downloading"
msgstr "ডাউনল'ড কৰা হৈ আছে"
#: ../js/ui/lookingGlass.js:799
#: ../js/ui/lookingGlass.js:801
msgid "View Source"
msgstr "উৎস দৰ্শন কৰক"
#: ../js/ui/lookingGlass.js:805
#: ../js/ui/lookingGlass.js:810
msgid "Web Page"
msgstr "ৱেব পৃষ্ঠা"
#. Translators: this is a filename used for screencast recording
#: ../js/ui/main.js:129
#: ../js/ui/main.js:140
#, no-c-format
msgid "Screencast from %d %t"
msgstr "%d %t ৰ পৰা স্ক্ৰিনকাস্ট দেখুৱাওক"
#: ../js/ui/messageTray.js:1280
#: ../js/ui/messageTray.js:1314
msgid "Open"
msgstr "খোলক"
#: ../js/ui/messageTray.js:1297
#: ../js/ui/messageTray.js:1331
msgid "Unmute"
msgstr "অমৌন কৰক"
#: ../js/ui/messageTray.js:1297
#: ../js/ui/messageTray.js:1331
msgid "Mute"
msgstr "মোন কৰক"
#: ../js/ui/messageTray.js:2575
#: ../js/ui/messageTray.js:2642
msgid "System Information"
msgstr "চিস্টেম তথ্য"
@ -689,118 +689,118 @@ msgid "Connect"
msgstr "সংযোগ কৰক"
#. Cisco LEAP
#: ../js/ui/networkAgent.js:243 ../js/ui/networkAgent.js:255
#: ../js/ui/networkAgent.js:282 ../js/ui/networkAgent.js:302
#: ../js/ui/networkAgent.js:312
#: ../js/ui/networkAgent.js:238 ../js/ui/networkAgent.js:250
#: ../js/ui/networkAgent.js:277 ../js/ui/networkAgent.js:297
#: ../js/ui/networkAgent.js:307
msgid "Password: "
msgstr "পাছৱাৰ্ড: "
#. static WEP
#: ../js/ui/networkAgent.js:248
#: ../js/ui/networkAgent.js:243
msgid "Key: "
msgstr "কি': "
#. TTLS and PEAP are actually much more complicated, but this complication
#. is not visible here since we only care about phase2 authentication
#. (and don't even care of which one)
#: ../js/ui/networkAgent.js:280 ../js/ui/networkAgent.js:298
#: ../js/ui/networkAgent.js:275 ../js/ui/networkAgent.js:293
msgid "Username: "
msgstr "ব্যৱহাৰকাৰীৰ নাম: "
#: ../js/ui/networkAgent.js:286
#: ../js/ui/networkAgent.js:281
msgid "Identity: "
msgstr "পৰিচয়: "
#: ../js/ui/networkAgent.js:288
#: ../js/ui/networkAgent.js:283
msgid "Private key password: "
msgstr "ব্যক্তিগত কি' পাছৱাৰ্ড: "
#: ../js/ui/networkAgent.js:300
#: ../js/ui/networkAgent.js:295
msgid "Service: "
msgstr "সেৱা: "
#: ../js/ui/networkAgent.js:329
#: ../js/ui/networkAgent.js:324
msgid "Authentication required by wireless network"
msgstr "বেতাঁৰ নেটৱাৰ্কৰ দ্বাৰা প্ৰমাণীকৰণৰ প্ৰয়োজন"
#: ../js/ui/networkAgent.js:330
#: ../js/ui/networkAgent.js:325
#, c-format
msgid ""
"Passwords or encryption keys are required to access the wireless network "
"'%s'."
msgstr "বেতাঁৰ নেটৱাৰ্ক '%s' অভিগম কৰিবলে পাছৱাৰ্ডসমূহ অথবা ইনক্ৰিপষণ কি'সমূহৰ প্ৰয়োজন।"
#: ../js/ui/networkAgent.js:334
#: ../js/ui/networkAgent.js:329
msgid "Wired 802.1X authentication"
msgstr "তাঁৰযুক্ত 802.1X প্ৰমাণীকৰণ"
#: ../js/ui/networkAgent.js:336
#: ../js/ui/networkAgent.js:331
msgid "Network name: "
msgstr "নেটৱাৰ্কৰ নাম: "
#: ../js/ui/networkAgent.js:341
#: ../js/ui/networkAgent.js:336
msgid "DSL authentication"
msgstr "DSL প্ৰমাণীকৰণ"
#: ../js/ui/networkAgent.js:348
#: ../js/ui/networkAgent.js:343
msgid "PIN code required"
msgstr "PIN ক'ডৰ প্ৰয়োজন"
#: ../js/ui/networkAgent.js:349
#: ../js/ui/networkAgent.js:344
msgid "PIN code is needed for the mobile broadband device"
msgstr "মবাইল ব্ৰডবেণ্ড সেৱাৰ বাবে PIN ক'ডৰ প্ৰয়োজন"
#: ../js/ui/networkAgent.js:350
#: ../js/ui/networkAgent.js:345
msgid "PIN: "
msgstr "PIN: "
#: ../js/ui/networkAgent.js:356
#: ../js/ui/networkAgent.js:351
msgid "Mobile broadband network password"
msgstr "মবাইল ব্ৰডবেণ্ড নেটৱাৰ্ক পাছৱাৰ্ড"
#: ../js/ui/networkAgent.js:357
#: ../js/ui/networkAgent.js:352
#, c-format
msgid "A password is required to connect to '%s'."
msgstr "'%s' লে সংযোগ কৰিবলে এটা পাছৱাৰ্ডৰ প্ৰয়োজন।"
#: ../js/ui/notificationDaemon.js:486 ../src/shell-app.c:374
#: ../js/ui/notificationDaemon.js:484 ../src/shell-app.c:374
msgctxt "program"
msgid "Unknown"
msgstr "অজ্ঞাত"
#: ../js/ui/overview.js:88
#: ../js/ui/overview.js:89
msgid "Undo"
msgstr "কাৰ্য্য বাতিল কৰক"
#: ../js/ui/overview.js:128
#: ../js/ui/overview.js:129
msgid "Overview"
msgstr "অভাৰভিউ"
#: ../js/ui/overview.js:198
#: ../js/ui/overview.js:199
msgid "Windows"
msgstr "উইন্ডোসমূহ"
#: ../js/ui/overview.js:201
#: ../js/ui/overview.js:202
msgid "Applications"
msgstr "অনুপ্ৰয়োগসমূহ"
#. Translators: this is the name of the dock/favorites area on
#. the left of the overview
#: ../js/ui/overview.js:226
#: ../js/ui/overview.js:227
msgid "Dash"
msgstr "ডেশ"
#: ../js/ui/panel.js:564
#: ../js/ui/panel.js:573
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:596
#: ../js/ui/panel.js:605
msgid "Activities"
msgstr "কাৰ্য্যসমূহ"
#: ../js/ui/panel.js:962
#: ../js/ui/panel.js:975
msgid "Top Bar"
msgstr "উপৰৰ বাৰ"
@ -837,8 +837,8 @@ msgstr "প্ৰমাণীত কৰক"
#. * requested authentication was not gained; this can happen
#. * because of an authentication error (like invalid password),
#. * for instance.
#: ../js/ui/polkitAuthenticationAgent.js:261
#: ../js/ui/shellMountOperation.js:324
#: ../js/ui/polkitAuthenticationAgent.js:262
#: ../js/ui/shellMountOperation.js:381
msgid "Sorry, that didn't work. Please try again."
msgstr "ক্ষমা কৰিব, সেয়া কাম নকৰিলে। অনুগ্ৰহ কৰি পুনৰ চেষ্টা কৰক।"
@ -847,7 +847,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:728
#: ../js/ui/popupMenu.js:727
msgid "toggle-switch-us"
msgstr "toggle-switch-us"
@ -871,23 +871,23 @@ msgstr "কপি কৰক"
msgid "Paste"
msgstr "পেইস্ট কৰক"
#: ../js/ui/shellEntry.js:77
#: ../js/ui/shellEntry.js:96
msgid "Show Text"
msgstr "লিখনী দেখুৱাওক"
#: ../js/ui/shellEntry.js:79
#: ../js/ui/shellEntry.js:98
msgid "Hide Text"
msgstr "লিখনী লুকুৱাওক"
#: ../js/ui/shellMountOperation.js:311
#: ../js/ui/shellMountOperation.js:368
msgid "Passphrase"
msgstr "পাচফ্ৰেইছ"
#: ../js/ui/shellMountOperation.js:332
#: ../js/ui/shellMountOperation.js:389
msgid "Remember Passphrase"
msgstr "পাচফ্ৰেইছ মনত ৰাখক"
#: ../js/ui/shellMountOperation.js:343
#: ../js/ui/shellMountOperation.js:400 ../js/ui/unlockDialog.js:142
msgid "Unlock"
msgstr "আনলক কৰক"
@ -931,18 +931,18 @@ msgstr "মাউছ কি'সমূহ"
msgid "Universal Access Settings"
msgstr "সাৰ্বভৈমক অভিগম সংহতিসমূহ"
#: ../js/ui/status/accessibility.js:117
#: ../js/ui/status/accessibility.js:121
msgid "High Contrast"
msgstr "উচ্চ কন্ট্ৰাস্ট"
#: ../js/ui/status/accessibility.js:154
#: ../js/ui/status/accessibility.js:158
msgid "Large Text"
msgstr "ডাঙৰ লিখনী"
#: ../js/ui/status/bluetooth.js:31 ../js/ui/status/bluetooth.js:35
#: ../js/ui/status/bluetooth.js:255 ../js/ui/status/bluetooth.js:308
#: ../js/ui/status/bluetooth.js:339 ../js/ui/status/bluetooth.js:375
#: ../js/ui/status/bluetooth.js:404 ../js/ui/status/network.js:844
#: ../js/ui/status/bluetooth.js:260 ../js/ui/status/bluetooth.js:313
#: ../js/ui/status/bluetooth.js:344 ../js/ui/status/bluetooth.js:380
#: ../js/ui/status/bluetooth.js:409 ../js/ui/status/network.js:844
msgid "Bluetooth"
msgstr "ব্লুটুথ"
@ -963,115 +963,115 @@ msgid "Bluetooth Settings"
msgstr "ব্লুটুথ সংহতিসমূহ"
#. TRANSLATORS: this means that bluetooth was disabled by hardware rfkill
#: ../js/ui/status/bluetooth.js:107 ../js/ui/status/network.js:211
#: ../js/ui/status/bluetooth.js:112 ../js/ui/status/network.js:211
msgid "hardware disabled"
msgstr "হাৰ্ডৱেৰ অসামৰ্থবান কৰা আছে"
#: ../js/ui/status/bluetooth.js:200
#: ../js/ui/status/bluetooth.js:205
msgid "Connection"
msgstr "সংযোগ"
#: ../js/ui/status/bluetooth.js:211 ../js/ui/status/network.js:445
#: ../js/ui/status/bluetooth.js:216 ../js/ui/status/network.js:445
msgid "disconnecting..."
msgstr "বিচ্ছিনিত কৰা হৈ আছে..."
#: ../js/ui/status/bluetooth.js:224 ../js/ui/status/network.js:451
#: ../js/ui/status/bluetooth.js:229 ../js/ui/status/network.js:451
#: ../js/ui/status/network.js:911
msgid "connecting..."
msgstr "সংযোগ কৰা হৈ আছে..."
#: ../js/ui/status/bluetooth.js:242
#: ../js/ui/status/bluetooth.js:247
msgid "Send Files..."
msgstr "নথিপত্ৰসমূহ পঠাওক..."
#: ../js/ui/status/bluetooth.js:247
#: ../js/ui/status/bluetooth.js:252
msgid "Browse Files..."
msgstr "নথিপত্ৰসমূহ ব্ৰাউছ কৰক..."
#: ../js/ui/status/bluetooth.js:256
#: ../js/ui/status/bluetooth.js:261
msgid "Error browsing device"
msgstr "ডিভাইচ ব্ৰাউছ কৰোতে ত্ৰুটি"
#: ../js/ui/status/bluetooth.js:257
#: ../js/ui/status/bluetooth.js:262
#, c-format
msgid "The requested device cannot be browsed, error is '%s'"
msgstr "অনুৰোধিত ডিভাইচ ব্ৰাউছ কৰিব নোৱাৰি, ত্ৰুটি '%s'"
#: ../js/ui/status/bluetooth.js:265
#: ../js/ui/status/bluetooth.js:270
msgid "Keyboard Settings"
msgstr "কিবৰ্ড সংহতিসমূহ"
#: ../js/ui/status/bluetooth.js:268
#: ../js/ui/status/bluetooth.js:273
msgid "Mouse Settings"
msgstr "মাউছ আৰু টাচপেড সংহতিসমূহ"
#: ../js/ui/status/bluetooth.js:273 ../js/ui/status/volume.js:59
#: ../js/ui/status/bluetooth.js:278 ../js/ui/status/volume.js:59
msgid "Sound Settings"
msgstr "শব্দ সংহতিসমূহ"
#: ../js/ui/status/bluetooth.js:340
#: ../js/ui/status/bluetooth.js:345
#, c-format
msgid "Authorization request from %s"
msgstr "%s ৰ পৰা প্ৰমাণীকৰণ অনুৰোধ"
#: ../js/ui/status/bluetooth.js:346
#: ../js/ui/status/bluetooth.js:351
#, c-format
msgid "Device %s wants access to the service '%s'"
msgstr "ডিভাইচ %s এ সেৱা '%s' লে অভিগম বিচাৰে"
#: ../js/ui/status/bluetooth.js:348
#: ../js/ui/status/bluetooth.js:353
msgid "Always grant access"
msgstr "সদায় অভিগম প্ৰদান কৰক"
#: ../js/ui/status/bluetooth.js:349
#: ../js/ui/status/bluetooth.js:354
msgid "Grant this time only"
msgstr "কেৱল এইবাৰৰ কাৰণে প্ৰদান কৰক"
#: ../js/ui/status/bluetooth.js:350 ../js/ui/telepathyClient.js:1097
#: ../js/ui/status/bluetooth.js:355 ../js/ui/telepathyClient.js:1097
msgid "Reject"
msgstr "নাকচ কৰক"
#: ../js/ui/status/bluetooth.js:376
#: ../js/ui/status/bluetooth.js:381
#, c-format
msgid "Pairing confirmation for %s"
msgstr "%s ৰ কাৰণে যোৰ প্ৰতিশ্ৰুতি"
#: ../js/ui/status/bluetooth.js:382 ../js/ui/status/bluetooth.js:412
#: ../js/ui/status/bluetooth.js:387 ../js/ui/status/bluetooth.js:417
#, c-format
msgid "Device %s wants to pair with this computer"
msgstr "ডিভাইচ %s এ এই কমপিউটাৰৰ লগত সংযোগ কৰিব বিচাৰে"
#: ../js/ui/status/bluetooth.js:383
#: ../js/ui/status/bluetooth.js:388
#, c-format
msgid "Please confirm whether the PIN '%06d' matches the one on the device."
msgstr "অনুগ্ৰহ কৰি সুনিশ্চিত কৰক যে PIN '%06d' ডিভাইচত থকাটোৰ সৈতে মিল খায়।"
#: ../js/ui/status/bluetooth.js:385
#: ../js/ui/status/bluetooth.js:390
msgid "Matches"
msgstr "মিলসমূহ"
#: ../js/ui/status/bluetooth.js:386
#: ../js/ui/status/bluetooth.js:391
msgid "Does not match"
msgstr "মিল নাখায়"
#: ../js/ui/status/bluetooth.js:405
#: ../js/ui/status/bluetooth.js:410
#, c-format
msgid "Pairing request for %s"
msgstr "%s ৰ কাৰণে যোৰ অনুৰোধ"
#: ../js/ui/status/bluetooth.js:413
#: ../js/ui/status/bluetooth.js:418
msgid "Please enter the PIN mentioned on the device."
msgstr "অনুগ্ৰহ কৰি ডিভাইচত উল্লেখ কৰা PIN সুমুৱাওক।"
#: ../js/ui/status/bluetooth.js:430
#: ../js/ui/status/bluetooth.js:435
msgid "OK"
msgstr "ঠিক আছে"
#: ../js/ui/status/keyboard.js:69
#: ../js/ui/status/keyboard.js:178
msgid "Show Keyboard Layout"
msgstr "কিবৰ্ড বিন্যাস দেখুৱাওক"
#: ../js/ui/status/keyboard.js:71
#: ../js/ui/status/keyboard.js:180
msgid "Region and Language Settings"
msgstr "অঞ্চল আৰু ভাষা সংহতিসমূহ"
@ -1176,19 +1176,19 @@ msgstr "VPN সংযোগসমূহ"
msgid "Network Settings"
msgstr "নেটৱাৰ্ক সংহতিসমূহ"
#: ../js/ui/status/network.js:1703
#: ../js/ui/status/network.js:1712
msgid "Network Manager"
msgstr "নেটৱাৰ্ক ব্যৱস্থাপক"
#: ../js/ui/status/network.js:1796
#: ../js/ui/status/network.js:1805
msgid "Connection failed"
msgstr "সংযোগ ব্যৰ্থ"
#: ../js/ui/status/network.js:1797
#: ../js/ui/status/network.js:1806
msgid "Activation of network connection failed"
msgstr "নেটৱাৰ্ক সংযোগ সক্ৰিয়কৰণ ব্যৰ্থ হল"
#: ../js/ui/status/network.js:2060
#: ../js/ui/status/network.js:2069
msgid "Networking is disabled"
msgstr "নেটৱাৰ্কিং অসামৰ্থবান কৰা আছে"
@ -1202,11 +1202,11 @@ msgstr "শক্তি সংহতিসমূহ"
#. 0 is reported when UPower does not have enough data
#. to estimate battery life
#: ../js/ui/status/power.js:98
#: ../js/ui/status/power.js:104
msgid "Estimating..."
msgstr "অনুমান কৰা হৈ আছে..."
#: ../js/ui/status/power.js:105
#: ../js/ui/status/power.js:111
#, c-format
msgid "%d hour remaining"
msgid_plural "%d hours remaining"
@ -1214,77 +1214,77 @@ msgstr[0] "%d ঘন্টা অৱশিষ্ট"
msgstr[1] "%d ঘন্টা অৱশিষ্ট"
#. TRANSLATORS: this is a time string, as in "%d hours %d minutes remaining"
#: ../js/ui/status/power.js:108
#: ../js/ui/status/power.js:114
#, c-format
msgid "%d %s %d %s remaining"
msgstr "%d %s %d %s অৱশিষ্ট"
#: ../js/ui/status/power.js:110
#: ../js/ui/status/power.js:116
msgid "hour"
msgid_plural "hours"
msgstr[0] "ঘন্টা"
msgstr[1] "ঘন্টা"
#: ../js/ui/status/power.js:110
#: ../js/ui/status/power.js:116
msgid "minute"
msgid_plural "minutes"
msgstr[0] "মিনিট"
msgstr[1] "মিনিট"
#: ../js/ui/status/power.js:113
#: ../js/ui/status/power.js:119
#, c-format
msgid "%d minute remaining"
msgid_plural "%d minutes remaining"
msgstr[0] "%d মিনিট অৱশিষ্ট"
msgstr[1] "%d মিনিট অৱশিষ্ট"
#: ../js/ui/status/power.js:116 ../js/ui/status/power.js:186
#: ../js/ui/status/power.js:122 ../js/ui/status/power.js:192
#, c-format
msgctxt "percent of battery remaining"
msgid "%d%%"
msgstr "%d%%"
#: ../js/ui/status/power.js:193
#: ../js/ui/status/power.js:199
msgid "AC adapter"
msgstr "AC এডাপ্টাৰ"
#: ../js/ui/status/power.js:195
#: ../js/ui/status/power.js:201
msgid "Laptop battery"
msgstr "লেপটপ বেটাৰি"
#: ../js/ui/status/power.js:197
#: ../js/ui/status/power.js:203
msgid "UPS"
msgstr "UPS"
#: ../js/ui/status/power.js:199
#: ../js/ui/status/power.js:205
msgid "Monitor"
msgstr "মনিটৰ"
#: ../js/ui/status/power.js:201
#: ../js/ui/status/power.js:207
msgid "Mouse"
msgstr "মাউছ"
#: ../js/ui/status/power.js:205
#: ../js/ui/status/power.js:211
msgid "PDA"
msgstr "PDA"
#: ../js/ui/status/power.js:207
#: ../js/ui/status/power.js:213
msgid "Cell phone"
msgstr "চেল ফোন"
#: ../js/ui/status/power.js:209
#: ../js/ui/status/power.js:215
msgid "Media player"
msgstr "মিডিয়া প্লেয়াৰ"
#: ../js/ui/status/power.js:211
#: ../js/ui/status/power.js:217
msgid "Tablet"
msgstr "টেবলেট"
#: ../js/ui/status/power.js:213
#: ../js/ui/status/power.js:219
msgid "Computer"
msgstr "কমপিউটাৰ"
#: ../js/ui/status/power.js:215
#: ../js/ui/status/power.js:221
msgctxt "device"
msgid "Unknown"
msgstr "অজ্ঞাত"
@ -1529,27 +1529,31 @@ msgstr "একাওন্ট সম্পাদন কৰক"
msgid "Unknown reason"
msgstr "অজ্ঞাত কাৰণ"
#: ../js/ui/userMenu.js:130
#: ../js/ui/unlockDialog.js:129
msgid "Login as another user"
msgstr "অন্য ব্যৱহাৰকাৰী হিচাপে লগিন কৰক"
#: ../js/ui/userMenu.js:161
msgid "Available"
msgstr "উপলব্ধ"
#: ../js/ui/userMenu.js:133
#: ../js/ui/userMenu.js:164
msgid "Busy"
msgstr "ব্যস্থ"
#: ../js/ui/userMenu.js:136
#: ../js/ui/userMenu.js:167
msgid "Invisible"
msgstr "অদৃশ্য"
#: ../js/ui/userMenu.js:139
#: ../js/ui/userMenu.js:170
msgid "Away"
msgstr "আতৰত"
#: ../js/ui/userMenu.js:142
#: ../js/ui/userMenu.js:173
msgid "Idle"
msgstr "অলস"
#: ../js/ui/userMenu.js:145
#: ../js/ui/userMenu.js:176
msgid "Unavailable"
msgstr "উপলব্ধ নাই"
@ -1577,7 +1581,7 @@ msgstr "লগ আউট কৰক"
msgid "Lock"
msgstr "লক কৰক"
#: ../js/ui/userMenu.js:724
#: ../js/ui/userMenu.js:731
msgid "Install Updates & Restart"
msgstr "আপডেইটসমূহ ইনস্টল কৰক & পুনাৰম্ভ কৰক"
@ -1602,7 +1606,7 @@ msgstr ""
msgid "Type to search..."
msgstr "সন্ধান কৰিবলে টাইপ কৰক..."
#: ../js/ui/viewSelector.js:131 ../src/shell-util.c:253
#: ../js/ui/viewSelector.js:131 ../src/shell-util.c:254
msgid "Search"
msgstr "সন্ধান কৰক"
@ -1655,19 +1659,19 @@ msgstr[1] "%u ইনপুটসমূহ"
msgid "System Sounds"
msgstr "চিস্টেম শব্দসমূহ"
#: ../src/main.c:327
#: ../src/main.c:330
msgid "Print version"
msgstr "প্ৰিন্ট সংস্কৰণ"
#: ../src/main.c:333
#: ../src/main.c:336
msgid "Mode used by GDM for login screen"
msgstr "লগিন স্ক্ৰিনৰ বাবে GDM দ্বাৰা ব্যৱহাৰ কৰা অৱস্থা"
#: ../src/main.c:339
#: ../src/main.c:342
msgid "Use a specific mode, e.g. \"gdm\" for login screen"
msgstr "লগিন পৰ্দাৰ বাবে এটা বিশেষ অৱস্থা, উদাহৰণস্বৰূপ \"gdm\" ব্যৱহাৰ কৰক"
#: ../src/main.c:345
#: ../src/main.c:348
msgid "List possible modes"
msgstr "সম্ভাব্য অৱস্থাসমূহ তালিকাভুক্ত কৰক"
@ -1698,13 +1702,13 @@ msgstr "প্ৰমাণীকৰণ ডাইলগ ব্যৱহাৰক
#. Translators: this is the same string as the one found in
#. * nautilus
#: ../src/shell-util.c:97
#: ../src/shell-util.c:98
msgid "Home"
msgstr "ঘৰ"
#. Translators: this is the same string as the one found in
#. * nautilus
#: ../src/shell-util.c:107
#: ../src/shell-util.c:108
msgid "File System"
msgstr "নথিপত্ৰ প্ৰণালী"
@ -1713,7 +1717,7 @@ msgstr "নথিপত্ৰ প্ৰণালী"
#. * example, "Trash: some-directory". It means that the
#. * directory called "some-directory" is in the trash.
#.
#: ../src/shell-util.c:303
#: ../src/shell-util.c:304
#, c-format
msgid "%1$s: %2$s"
msgstr "%1$s: %2$s"

567
po/el.po

File diff suppressed because it is too large Load Diff

310
po/es.po
View File

@ -10,8 +10,8 @@ msgstr ""
"Project-Id-Version: gnome-shell.master\n"
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-"
"shell&keywords=I18N+L10N&component=general\n"
"POT-Creation-Date: 2012-07-07 16:23+0000\n"
"PO-Revision-Date: 2012-07-16 16:08+0200\n"
"POT-Creation-Date: 2012-07-21 17:14+0000\n"
"PO-Revision-Date: 2012-07-27 11:31+0200\n"
"Last-Translator: Daniel Mustieles <daniel.mustieles@gmail.com>\n"
"Language-Team: Español <gnome-es-list@gnome.org>\n"
"Language: \n"
@ -30,7 +30,7 @@ msgid "Window management and application launching"
msgstr "Gestión de ventanas e inicio de aplicaciones"
#: ../data/gnome-shell-extension-prefs.desktop.in.in.h:1
#: ../js/extensionPrefs/main.js:153
#: ../js/extensionPrefs/main.js:152
msgid "GNOME Shell Extension Preferences"
msgstr "Preferencias de las extensiones de GNOME Shell"
@ -214,60 +214,60 @@ msgstr ""
"basado en la fecha actual y usará esta extensión. Se debería cambiar al "
"grabar en otro formato contenedor diferente."
#: ../js/extensionPrefs/main.js:125
#: ../js/extensionPrefs/main.js:124
#, c-format
msgid "There was an error loading the preferences dialog for %s:"
msgstr "Hubo un error al lanzar el diálogo de preferencias para %s:"
#: ../js/extensionPrefs/main.js:165
#: ../js/extensionPrefs/main.js:164
msgid "<b>Extension</b>"
msgstr "<b>Extensión</b>"
#: ../js/extensionPrefs/main.js:189
#: ../js/extensionPrefs/main.js:188
msgid "Select an extension to configure using the combobox above."
msgstr ""
"Seleccione una extensión que configurar usando la caja combinada de arriba."
#: ../js/gdm/loginDialog.js:629
#: ../js/gdm/loginDialog.js:550
msgid "Session..."
msgstr "Sesión…"
#: ../js/gdm/loginDialog.js:800
#: ../js/gdm/loginDialog.js:699
msgctxt "title"
msgid "Sign In"
msgstr "Iniciar sesión"
#. Translators: this message is shown below the password entry field
#. to indicate the user can swipe their finger instead
#: ../js/gdm/loginDialog.js:845
#: ../js/gdm/loginDialog.js:744 ../js/ui/unlockDialog.js:124
msgid "(or swipe finger)"
msgstr "(o pase el dedo)"
#. 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:866
#: ../js/gdm/loginDialog.js:765
msgid "Not listed?"
msgstr "¿No está en la lista?"
#: ../js/gdm/loginDialog.js:1046 ../js/ui/endSessionDialog.js:410
#: ../js/ui/extensionDownloader.js:138 ../js/ui/networkAgent.js:153
#: ../js/gdm/loginDialog.js:908 ../js/ui/endSessionDialog.js:406
#: ../js/ui/extensionDownloader.js:195 ../js/ui/networkAgent.js:153
#: ../js/ui/polkitAuthenticationAgent.js:176
#: ../js/ui/shellMountOperation.js:339 ../js/ui/status/bluetooth.js:431
#: ../js/ui/shellMountOperation.js:396 ../js/ui/status/bluetooth.js:436
msgid "Cancel"
msgstr "Cancelar"
#: ../js/gdm/loginDialog.js:1051
#: ../js/gdm/loginDialog.js:913
msgctxt "button"
msgid "Sign In"
msgstr "Iniciar sesión"
#: ../js/gdm/loginDialog.js:1411
#: ../js/gdm/loginDialog.js:1256
msgid "Login Window"
msgstr "Ventana de inicio de sesión"
#: ../js/gdm/powerMenu.js:130 ../js/ui/userMenu.js:612
#: ../js/ui/userMenu.js:616 ../js/ui/userMenu.js:730
#: ../js/ui/userMenu.js:616 ../js/ui/userMenu.js:725
msgid "Suspend"
msgstr "Suspender"
@ -276,21 +276,21 @@ msgid "Restart"
msgstr "Reiniciar"
#: ../js/gdm/powerMenu.js:140 ../js/ui/userMenu.js:614
#: ../js/ui/userMenu.js:616 ../js/ui/userMenu.js:729
#: ../js/ui/userMenu.js:616 ../js/ui/userMenu.js:724
msgid "Power Off"
msgstr "Apagar"
#: ../js/misc/util.js:95
#: ../js/misc/util.js:92
msgid "Command not found"
msgstr "Comando no encontrado"
#. Replace "Error invoking GLib.shell_parse_argv: " with
#. something nicer
#: ../js/misc/util.js:128
#: ../js/misc/util.js:125
msgid "Could not parse command:"
msgstr "No se pudo analizar el comando:"
#: ../js/misc/util.js:136
#: ../js/misc/util.js:133
#, c-format
msgid "Execution of '%s' failed:"
msgstr "Falló la ejecución de «%s»:"
@ -457,39 +457,39 @@ msgid "S"
msgstr "S"
#. Translators: Text to show if there are no events
#: ../js/ui/calendar.js:681
#: ../js/ui/calendar.js:685
msgid "Nothing Scheduled"
msgstr "Nada programado"
#. Translators: Shown on calendar heading when selected day occurs on current year
#: ../js/ui/calendar.js:697
#: ../js/ui/calendar.js:701
msgctxt "calendar heading"
msgid "%A, %B %d"
msgstr "%A, %d de %B"
#. Translators: Shown on calendar heading when selected day occurs on different year
#: ../js/ui/calendar.js:700
#: ../js/ui/calendar.js:704
msgctxt "calendar heading"
msgid "%A, %B %d, %Y"
msgstr "%A, %d de %B de %Y"
#: ../js/ui/calendar.js:710
#: ../js/ui/calendar.js:714
msgid "Today"
msgstr "Hoy"
#: ../js/ui/calendar.js:714
#: ../js/ui/calendar.js:718
msgid "Tomorrow"
msgstr "Mañana"
#: ../js/ui/calendar.js:723
#: ../js/ui/calendar.js:727
msgid "This week"
msgstr "Esta semana"
#: ../js/ui/calendar.js:731
#: ../js/ui/calendar.js:735
msgid "Next week"
msgstr "La semana que viene"
#: ../js/ui/dash.js:239 ../js/ui/messageTray.js:1287
#: ../js/ui/dash.js:238 ../js/ui/messageTray.js:1321
msgid "Remove"
msgstr "Quitar"
@ -599,11 +599,11 @@ msgstr[1] "El sistema se reiniciará automáticamente en %d segundos."
msgid "Restarting the system."
msgstr "Reiniciando el sistema."
#: ../js/ui/extensionDownloader.js:142
#: ../js/ui/extensionDownloader.js:199
msgid "Install"
msgstr "Instalar"
#: ../js/ui/extensionDownloader.js:146
#: ../js/ui/extensionDownloader.js:204
#, c-format
msgid "Download and install '%s' from extensions.gnome.org?"
msgstr "¿Descargar e instalar «%s» desde extensions.gnome.org?"
@ -612,86 +612,86 @@ msgstr "¿Descargar e instalar «%s» desde extensions.gnome.org?"
msgid "tray"
msgstr "bandeja"
#: ../js/ui/keyboard.js:545 ../js/ui/status/keyboard.js:42
#: ../js/ui/status/power.js:203
#: ../js/ui/keyboard.js:545 ../js/ui/status/keyboard.js:149
#: ../js/ui/status/power.js:209
msgid "Keyboard"
msgstr "Teclado"
#: ../js/ui/keyringPrompt.js:85 ../js/ui/polkitAuthenticationAgent.js:273
#: ../js/ui/keyringPrompt.js:86 ../js/ui/polkitAuthenticationAgent.js:274
msgid "Password:"
msgstr "Contraseña:"
#: ../js/ui/keyringPrompt.js:101
#: ../js/ui/keyringPrompt.js:102
msgid "Type again:"
msgstr "Escriba de nuevo:"
#: ../js/ui/lookingGlass.js:696
#: ../js/ui/lookingGlass.js:695
msgid "No extensions installed"
msgstr "No hay extensiones instaladas"
#. Translators: argument is an extension UUID.
#: ../js/ui/lookingGlass.js:750
#: ../js/ui/lookingGlass.js:749
#, c-format
msgid "%s has not emitted any errors."
msgstr "%s no ha generado ningún error."
#: ../js/ui/lookingGlass.js:756
#: ../js/ui/lookingGlass.js:755
msgid "Hide Errors"
msgstr "Ocultar errores"
#: ../js/ui/lookingGlass.js:760 ../js/ui/lookingGlass.js:811
#: ../js/ui/lookingGlass.js:759 ../js/ui/lookingGlass.js:819
msgid "Show Errors"
msgstr "Mostrar errores"
#: ../js/ui/lookingGlass.js:769
#: ../js/ui/lookingGlass.js:768
msgid "Enabled"
msgstr "Activado"
#. translators:
#. * The device has been disabled
#: ../js/ui/lookingGlass.js:772 ../src/gvc/gvc-mixer-control.c:1082
#: ../js/ui/lookingGlass.js:771 ../src/gvc/gvc-mixer-control.c:1082
msgid "Disabled"
msgstr "Desactivado"
#: ../js/ui/lookingGlass.js:774
#: ../js/ui/lookingGlass.js:773
msgid "Error"
msgstr "Error"
#: ../js/ui/lookingGlass.js:776
#: ../js/ui/lookingGlass.js:775
msgid "Out of date"
msgstr "Caducado"
#: ../js/ui/lookingGlass.js:778
#: ../js/ui/lookingGlass.js:777
msgid "Downloading"
msgstr "Descargando"
#: ../js/ui/lookingGlass.js:799
#: ../js/ui/lookingGlass.js:801
msgid "View Source"
msgstr "Ver fuente"
#: ../js/ui/lookingGlass.js:805
#: ../js/ui/lookingGlass.js:810
msgid "Web Page"
msgstr "Página web"
#. Translators: this is a filename used for screencast recording
#: ../js/ui/main.js:129
#: ../js/ui/main.js:140
#, no-c-format
msgid "Screencast from %d %t"
msgstr "Screencast desde %d %t"
#: ../js/ui/messageTray.js:1280
#: ../js/ui/messageTray.js:1314
msgid "Open"
msgstr "Abrir"
#: ../js/ui/messageTray.js:1297
#: ../js/ui/messageTray.js:1331
msgid "Unmute"
msgstr "Dar voz"
#: ../js/ui/messageTray.js:1297
#: ../js/ui/messageTray.js:1331
msgid "Mute"
msgstr "Silenciar"
#: ../js/ui/messageTray.js:2575
#: ../js/ui/messageTray.js:2642
msgid "System Information"
msgstr "Información del sistema"
@ -700,41 +700,41 @@ msgid "Connect"
msgstr "Conectar"
#. Cisco LEAP
#: ../js/ui/networkAgent.js:243 ../js/ui/networkAgent.js:255
#: ../js/ui/networkAgent.js:282 ../js/ui/networkAgent.js:302
#: ../js/ui/networkAgent.js:312
#: ../js/ui/networkAgent.js:238 ../js/ui/networkAgent.js:250
#: ../js/ui/networkAgent.js:277 ../js/ui/networkAgent.js:297
#: ../js/ui/networkAgent.js:307
msgid "Password: "
msgstr "Contraseña: "
#. static WEP
#: ../js/ui/networkAgent.js:248
#: ../js/ui/networkAgent.js:243
msgid "Key: "
msgstr "Clave:"
#. 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/ui/networkAgent.js:280 ../js/ui/networkAgent.js:298
#: ../js/ui/networkAgent.js:275 ../js/ui/networkAgent.js:293
msgid "Username: "
msgstr "Nombre de usuario:"
#: ../js/ui/networkAgent.js:286
#: ../js/ui/networkAgent.js:281
msgid "Identity: "
msgstr "Identidad:"
#: ../js/ui/networkAgent.js:288
#: ../js/ui/networkAgent.js:283
msgid "Private key password: "
msgstr "Contraseña de la clave privada:"
#: ../js/ui/networkAgent.js:300
#: ../js/ui/networkAgent.js:295
msgid "Service: "
msgstr "Servicio:"
#: ../js/ui/networkAgent.js:329
#: ../js/ui/networkAgent.js:324
msgid "Authentication required by wireless network"
msgstr "La red inalámbrica requiere autenticación"
#: ../js/ui/networkAgent.js:330
#: ../js/ui/networkAgent.js:325
#, c-format
msgid ""
"Passwords or encryption keys are required to access the wireless network '%"
@ -743,77 +743,77 @@ msgstr ""
"Se necesitan contraseñas o claves de cifrado para acceder a la red "
"inalámbrica «%s»."
#: ../js/ui/networkAgent.js:334
#: ../js/ui/networkAgent.js:329
msgid "Wired 802.1X authentication"
msgstr "Autenticación 802.1X cableada"
#: ../js/ui/networkAgent.js:336
#: ../js/ui/networkAgent.js:331
msgid "Network name: "
msgstr "Nombre de la red"
#: ../js/ui/networkAgent.js:341
#: ../js/ui/networkAgent.js:336
msgid "DSL authentication"
msgstr "Autenticación DSL"
#: ../js/ui/networkAgent.js:348
#: ../js/ui/networkAgent.js:343
msgid "PIN code required"
msgstr "Código PIN requerido"
#: ../js/ui/networkAgent.js:349
#: ../js/ui/networkAgent.js:344
msgid "PIN code is needed for the mobile broadband device"
msgstr "Se necesita un código PIN para el dispositivo de banda ancha móvil"
#: ../js/ui/networkAgent.js:350
#: ../js/ui/networkAgent.js:345
msgid "PIN: "
msgstr "PIN: "
#: ../js/ui/networkAgent.js:356
#: ../js/ui/networkAgent.js:351
msgid "Mobile broadband network password"
msgstr "Contraseña de la red de banda ancha móvil"
#: ../js/ui/networkAgent.js:357
#: ../js/ui/networkAgent.js:352
#, c-format
msgid "A password is required to connect to '%s'."
msgstr "Se requiere una contraseña para conectar a «%s»."
#: ../js/ui/notificationDaemon.js:486 ../src/shell-app.c:374
#: ../js/ui/notificationDaemon.js:484 ../src/shell-app.c:374
msgctxt "program"
msgid "Unknown"
msgstr "Desconocido"
#: ../js/ui/overview.js:88
#: ../js/ui/overview.js:89
msgid "Undo"
msgstr "Deshacer"
#: ../js/ui/overview.js:128
#: ../js/ui/overview.js:129
msgid "Overview"
msgstr "Vista general"
#: ../js/ui/overview.js:198
#: ../js/ui/overview.js:199
msgid "Windows"
msgstr "Ventanas"
#: ../js/ui/overview.js:201
#: ../js/ui/overview.js:202
msgid "Applications"
msgstr "Aplicaciones"
#. Translators: this is the name of the dock/favorites area on
#. the left of the overview
#: ../js/ui/overview.js:226
#: ../js/ui/overview.js:227
msgid "Dash"
msgstr "Tablero"
#: ../js/ui/panel.js:564
#: ../js/ui/panel.js:573
msgid "Quit"
msgstr "Salir"
#. Translators: If there is no suitable word for "Activities"
#. in your language, you can use the word for "Overview".
#: ../js/ui/panel.js:596
#: ../js/ui/panel.js:605
msgid "Activities"
msgstr "Actividades"
#: ../js/ui/panel.js:962
#: ../js/ui/panel.js:975
msgid "Top Bar"
msgstr "Barra superior"
@ -850,8 +850,8 @@ msgstr "Autenticar"
#. * requested authentication was not gained; this can happen
#. * because of an authentication error (like invalid password),
#. * for instance.
#: ../js/ui/polkitAuthenticationAgent.js:261
#: ../js/ui/shellMountOperation.js:324
#: ../js/ui/polkitAuthenticationAgent.js:262
#: ../js/ui/shellMountOperation.js:381
msgid "Sorry, that didn't work. Please try again."
msgstr "Inténtelo de nuevo,"
@ -860,7 +860,7 @@ msgstr "Inténtelo de nuevo,"
#. "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:728
#: ../js/ui/popupMenu.js:727
msgid "toggle-switch-us"
msgstr "toggle-switch-intl"
@ -884,23 +884,23 @@ msgstr "Copiar"
msgid "Paste"
msgstr "Pegar"
#: ../js/ui/shellEntry.js:77
#: ../js/ui/shellEntry.js:96
msgid "Show Text"
msgstr "Mostrar texto"
#: ../js/ui/shellEntry.js:79
#: ../js/ui/shellEntry.js:98
msgid "Hide Text"
msgstr "Ocultar texto"
#: ../js/ui/shellMountOperation.js:311
#: ../js/ui/shellMountOperation.js:368
msgid "Passphrase"
msgstr "Contraseña"
#: ../js/ui/shellMountOperation.js:332
#: ../js/ui/shellMountOperation.js:389
msgid "Remember Passphrase"
msgstr "Recordar contraseña"
#: ../js/ui/shellMountOperation.js:343
#: ../js/ui/shellMountOperation.js:400 ../js/ui/unlockDialog.js:142
msgid "Unlock"
msgstr "Desbloquear"
@ -944,18 +944,18 @@ msgstr "Teclas del ratón"
msgid "Universal Access Settings"
msgstr "Configuración del acceso universal"
#: ../js/ui/status/accessibility.js:117
#: ../js/ui/status/accessibility.js:121
msgid "High Contrast"
msgstr "Contraste alto"
#: ../js/ui/status/accessibility.js:154
#: ../js/ui/status/accessibility.js:158
msgid "Large Text"
msgstr "Texto grande"
#: ../js/ui/status/bluetooth.js:31 ../js/ui/status/bluetooth.js:35
#: ../js/ui/status/bluetooth.js:255 ../js/ui/status/bluetooth.js:308
#: ../js/ui/status/bluetooth.js:339 ../js/ui/status/bluetooth.js:375
#: ../js/ui/status/bluetooth.js:404 ../js/ui/status/network.js:844
#: ../js/ui/status/bluetooth.js:260 ../js/ui/status/bluetooth.js:313
#: ../js/ui/status/bluetooth.js:344 ../js/ui/status/bluetooth.js:380
#: ../js/ui/status/bluetooth.js:409 ../js/ui/status/network.js:844
msgid "Bluetooth"
msgstr "Bluetooth"
@ -976,115 +976,115 @@ msgid "Bluetooth Settings"
msgstr "Configuración de Bluetooth"
#. TRANSLATORS: this means that bluetooth was disabled by hardware rfkill
#: ../js/ui/status/bluetooth.js:107 ../js/ui/status/network.js:211
#: ../js/ui/status/bluetooth.js:112 ../js/ui/status/network.js:211
msgid "hardware disabled"
msgstr "hardware desactivado"
#: ../js/ui/status/bluetooth.js:200
#: ../js/ui/status/bluetooth.js:205
msgid "Connection"
msgstr "Conexión"
#: ../js/ui/status/bluetooth.js:211 ../js/ui/status/network.js:445
#: ../js/ui/status/bluetooth.js:216 ../js/ui/status/network.js:445
msgid "disconnecting..."
msgstr "deconectando…"
#: ../js/ui/status/bluetooth.js:224 ../js/ui/status/network.js:451
#: ../js/ui/status/bluetooth.js:229 ../js/ui/status/network.js:451
#: ../js/ui/status/network.js:911
msgid "connecting..."
msgstr "conectando…"
#: ../js/ui/status/bluetooth.js:242
#: ../js/ui/status/bluetooth.js:247
msgid "Send Files..."
msgstr "Enviar archivos…"
#: ../js/ui/status/bluetooth.js:247
#: ../js/ui/status/bluetooth.js:252
msgid "Browse Files..."
msgstr "Examinar archivos…"
#: ../js/ui/status/bluetooth.js:256
#: ../js/ui/status/bluetooth.js:261
msgid "Error browsing device"
msgstr "Error al examinar el dispositivo"
#: ../js/ui/status/bluetooth.js:257
#: ../js/ui/status/bluetooth.js:262
#, c-format
msgid "The requested device cannot be browsed, error is '%s'"
msgstr "No se puede examinar el dispositivo solicitado, el error es «%s»"
#: ../js/ui/status/bluetooth.js:265
#: ../js/ui/status/bluetooth.js:270
msgid "Keyboard Settings"
msgstr "Configuración del teclado"
#: ../js/ui/status/bluetooth.js:268
#: ../js/ui/status/bluetooth.js:273
msgid "Mouse Settings"
msgstr "Ajustes del ratón…"
#: ../js/ui/status/bluetooth.js:273 ../js/ui/status/volume.js:59
#: ../js/ui/status/bluetooth.js:278 ../js/ui/status/volume.js:59
msgid "Sound Settings"
msgstr "Configuración del sonido"
#: ../js/ui/status/bluetooth.js:340
#: ../js/ui/status/bluetooth.js:345
#, c-format
msgid "Authorization request from %s"
msgstr "Solicitud de autorización de %s"
#: ../js/ui/status/bluetooth.js:346
#: ../js/ui/status/bluetooth.js:351
#, c-format
msgid "Device %s wants access to the service '%s'"
msgstr "El dispositivo %s quiere acceder al servicio «%s»"
#: ../js/ui/status/bluetooth.js:348
#: ../js/ui/status/bluetooth.js:353
msgid "Always grant access"
msgstr "Conceder acceso siempre"
#: ../js/ui/status/bluetooth.js:349
#: ../js/ui/status/bluetooth.js:354
msgid "Grant this time only"
msgstr "Conceder sólo esta vez"
#: ../js/ui/status/bluetooth.js:350 ../js/ui/telepathyClient.js:1097
#: ../js/ui/status/bluetooth.js:355 ../js/ui/telepathyClient.js:1097
msgid "Reject"
msgstr "Rechazar"
#: ../js/ui/status/bluetooth.js:376
#: ../js/ui/status/bluetooth.js:381
#, c-format
msgid "Pairing confirmation for %s"
msgstr "Confirmación de emparejamiento para «%s»"
#: ../js/ui/status/bluetooth.js:382 ../js/ui/status/bluetooth.js:412
#: ../js/ui/status/bluetooth.js:387 ../js/ui/status/bluetooth.js:417
#, c-format
msgid "Device %s wants to pair with this computer"
msgstr "El dispositivo «%s» quiere emparejarse con este equipo"
#: ../js/ui/status/bluetooth.js:383
#: ../js/ui/status/bluetooth.js:388
#, c-format
msgid "Please confirm whether the PIN '%06d' matches the one on the device."
msgstr "Confirme que el PIN mostrado en «%06d» coincide con el del dispositivo."
#: ../js/ui/status/bluetooth.js:385
#: ../js/ui/status/bluetooth.js:390
msgid "Matches"
msgstr "Coincide"
#: ../js/ui/status/bluetooth.js:386
#: ../js/ui/status/bluetooth.js:391
msgid "Does not match"
msgstr "No coincide"
#: ../js/ui/status/bluetooth.js:405
#: ../js/ui/status/bluetooth.js:410
#, c-format
msgid "Pairing request for %s"
msgstr "Solicitud de emparejamiento para «%s»"
#: ../js/ui/status/bluetooth.js:413
#: ../js/ui/status/bluetooth.js:418
msgid "Please enter the PIN mentioned on the device."
msgstr "Introduzca el PIN mencionado en el dispositivo."
#: ../js/ui/status/bluetooth.js:430
#: ../js/ui/status/bluetooth.js:435
msgid "OK"
msgstr "Aceptar"
#: ../js/ui/status/keyboard.js:69
#: ../js/ui/status/keyboard.js:178
msgid "Show Keyboard Layout"
msgstr "Mostrar la distribución del teclado"
#: ../js/ui/status/keyboard.js:71
#: ../js/ui/status/keyboard.js:180
msgid "Region and Language Settings"
msgstr "Configuración de región e idioma"
@ -1189,19 +1189,19 @@ msgstr "Conexiones VPN"
msgid "Network Settings"
msgstr "Configuración de la red"
#: ../js/ui/status/network.js:1703
#: ../js/ui/status/network.js:1712
msgid "Network Manager"
msgstr "Gestor de la red"
#: ../js/ui/status/network.js:1796
#: ../js/ui/status/network.js:1805
msgid "Connection failed"
msgstr "Falló la conexión"
#: ../js/ui/status/network.js:1797
#: ../js/ui/status/network.js:1806
msgid "Activation of network connection failed"
msgstr "Falló la activación de la conexión de red"
#: ../js/ui/status/network.js:2060
#: ../js/ui/status/network.js:2069
msgid "Networking is disabled"
msgstr "La red está desactivada"
@ -1215,11 +1215,11 @@ msgstr "Configuración de energía"
#. 0 is reported when UPower does not have enough data
#. to estimate battery life
#: ../js/ui/status/power.js:98
#: ../js/ui/status/power.js:104
msgid "Estimating..."
msgstr "Estimando…"
#: ../js/ui/status/power.js:105
#: ../js/ui/status/power.js:111
#, c-format
msgid "%d hour remaining"
msgid_plural "%d hours remaining"
@ -1227,77 +1227,77 @@ msgstr[0] "Queda %d hora"
msgstr[1] "Queda %d horas"
#. TRANSLATORS: this is a time string, as in "%d hours %d minutes remaining"
#: ../js/ui/status/power.js:108
#: ../js/ui/status/power.js:114
#, c-format
msgid "%d %s %d %s remaining"
msgstr "Quedan %d %s %d %s"
#: ../js/ui/status/power.js:110
#: ../js/ui/status/power.js:116
msgid "hour"
msgid_plural "hours"
msgstr[0] "hora"
msgstr[1] "horas"
#: ../js/ui/status/power.js:110
#: ../js/ui/status/power.js:116
msgid "minute"
msgid_plural "minutes"
msgstr[0] "minuto"
msgstr[1] "minutos"
#: ../js/ui/status/power.js:113
#: ../js/ui/status/power.js:119
#, c-format
msgid "%d minute remaining"
msgid_plural "%d minutes remaining"
msgstr[0] "Queda %d minuto"
msgstr[1] "Quedan %d minutos"
#: ../js/ui/status/power.js:116 ../js/ui/status/power.js:186
#: ../js/ui/status/power.js:122 ../js/ui/status/power.js:192
#, c-format
msgctxt "percent of battery remaining"
msgid "%d%%"
msgstr "%d%%"
#: ../js/ui/status/power.js:193
#: ../js/ui/status/power.js:199
msgid "AC adapter"
msgstr "Adaptador de corriente"
#: ../js/ui/status/power.js:195
#: ../js/ui/status/power.js:201
msgid "Laptop battery"
msgstr "Batería del portátil"
#: ../js/ui/status/power.js:197
#: ../js/ui/status/power.js:203
msgid "UPS"
msgstr "SAI"
#: ../js/ui/status/power.js:199
#: ../js/ui/status/power.js:205
msgid "Monitor"
msgstr "Monitor"
#: ../js/ui/status/power.js:201
#: ../js/ui/status/power.js:207
msgid "Mouse"
msgstr "Ratón"
#: ../js/ui/status/power.js:205
#: ../js/ui/status/power.js:211
msgid "PDA"
msgstr "PDA"
#: ../js/ui/status/power.js:207
#: ../js/ui/status/power.js:213
msgid "Cell phone"
msgstr "Teléfono móvil"
#: ../js/ui/status/power.js:209
#: ../js/ui/status/power.js:215
msgid "Media player"
msgstr "Reproductor multimedia"
#: ../js/ui/status/power.js:211
#: ../js/ui/status/power.js:217
msgid "Tablet"
msgstr "Tableta"
#: ../js/ui/status/power.js:213
#: ../js/ui/status/power.js:219
msgid "Computer"
msgstr "Equipo"
#: ../js/ui/status/power.js:215
#: ../js/ui/status/power.js:221
msgctxt "device"
msgid "Unknown"
msgstr "Desconocido"
@ -1548,27 +1548,31 @@ msgstr "Editar cuenta"
msgid "Unknown reason"
msgstr "Razón desconocida"
#: ../js/ui/userMenu.js:130
#: ../js/ui/unlockDialog.js:129
msgid "Login as another user"
msgstr "Iniciar sesión como otro usuario"
#: ../js/ui/userMenu.js:161
msgid "Available"
msgstr "Disponible"
#: ../js/ui/userMenu.js:133
#: ../js/ui/userMenu.js:164
msgid "Busy"
msgstr "Ocupado"
#: ../js/ui/userMenu.js:136
#: ../js/ui/userMenu.js:167
msgid "Invisible"
msgstr "Invisible"
#: ../js/ui/userMenu.js:139
#: ../js/ui/userMenu.js:170
msgid "Away"
msgstr "Ausente"
#: ../js/ui/userMenu.js:142
#: ../js/ui/userMenu.js:173
msgid "Idle"
msgstr "Inactivo"
#: ../js/ui/userMenu.js:145
#: ../js/ui/userMenu.js:176
msgid "Unavailable"
msgstr "No disponible"
@ -1596,7 +1600,7 @@ msgstr "Cerrar la sesión"
msgid "Lock"
msgstr "Bloquear"
#: ../js/ui/userMenu.js:724
#: ../js/ui/userMenu.js:731
msgid "Install Updates & Restart"
msgstr "Instalar actualizaciones y reiniciar"
@ -1621,7 +1625,7 @@ msgstr ""
msgid "Type to search..."
msgstr "Teclear para buscar…"
#: ../js/ui/viewSelector.js:131 ../src/shell-util.c:253
#: ../js/ui/viewSelector.js:131 ../src/shell-util.c:254
msgid "Search"
msgstr "Buscar"
@ -1674,21 +1678,21 @@ msgstr[1] "%u entradas"
msgid "System Sounds"
msgstr "Sonidos del sistema"
#: ../src/main.c:327
#: ../src/main.c:330
msgid "Print version"
msgstr "Imprimir versión"
#: ../src/main.c:333
#: ../src/main.c:336
msgid "Mode used by GDM for login screen"
msgstr "Modo usado por GDM para la pantalla de inicio"
#: ../src/main.c:339
#: ../src/main.c:342
msgid "Use a specific mode, e.g. \"gdm\" for login screen"
msgstr ""
"Usar un modo específico, por ejemplo, «gdm» para la pantalla de inicio de "
"sesión"
#: ../src/main.c:345
#: ../src/main.c:348
msgid "List possible modes"
msgstr "Listar los modos posibles"
@ -1719,13 +1723,13 @@ msgstr "El usuario rechazó el diálogo de autenticación"
#. Translators: this is the same string as the one found in
#. * nautilus
#: ../src/shell-util.c:97
#: ../src/shell-util.c:98
msgid "Home"
msgstr "Carpeta personal"
#. Translators: this is the same string as the one found in
#. * nautilus
#: ../src/shell-util.c:107
#: ../src/shell-util.c:108
msgid "File System"
msgstr "Sistema de archivos"
@ -1734,7 +1738,7 @@ msgstr "Sistema de archivos"
#. * example, "Trash: some-directory". It means that the
#. * directory called "some-directory" is in the trash.
#.
#: ../src/shell-util.c:303
#: ../src/shell-util.c:304
#, c-format
msgid "%1$s: %2$s"
msgstr "%1$s: %2$s"

941
po/fa.po

File diff suppressed because it is too large Load Diff

509
po/gl.po

File diff suppressed because it is too large Load Diff

881
po/gu.po

File diff suppressed because it is too large Load Diff

332
po/he.po
View File

@ -8,8 +8,8 @@ msgid ""
msgstr ""
"Project-Id-Version: gnome-shell master\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2012-07-10 23:08+0300\n"
"PO-Revision-Date: 2012-07-10 23:09+0200\n"
"POT-Creation-Date: 2012-07-24 22:27+0300\n"
"PO-Revision-Date: 2012-07-24 22:27+0200\n"
"Last-Translator: Yaron Shahrabani <sh.yaron@gmail.com>\n"
"Language-Team: Hebrew <sh.yaron@gmail.com>\n"
"Language: he\n"
@ -30,7 +30,7 @@ msgid "Window management and application launching"
msgstr "ניהול חלונות והרצת יישומים"
#: ../data/gnome-shell-extension-prefs.desktop.in.in.h:1
#: ../js/extensionPrefs/main.js:153
#: ../js/extensionPrefs/main.js:152
msgid "GNOME Shell Extension Preferences"
msgstr "העדפות ההרחבות של GNOME Shell"
@ -147,64 +147,65 @@ msgstr "File extension used for storing the screencast"
msgid "The filename for recorded screencasts will be a unique filename based on the current date, and use this extension. It should be changed when recording to a different container format."
msgstr "The filename for recorded screencasts will be a unique filename based on the current date, and use this extension. It should be changed when recording to a different container format."
#: ../js/extensionPrefs/main.js:125
#: ../js/extensionPrefs/main.js:124
#, c-format
msgid "There was an error loading the preferences dialog for %s:"
msgstr "אירעה שגיאה בעת טעינת דו־שיח ההעדפות עבור %s:"
#: ../js/extensionPrefs/main.js:165
#: ../js/extensionPrefs/main.js:164
msgid "<b>Extension</b>"
msgstr "<b>הרחבה</b>"
#: ../js/extensionPrefs/main.js:189
#: ../js/extensionPrefs/main.js:188
msgid "Select an extension to configure using the combobox above."
msgstr "יש לבחור את ההרחבה להגדרה באמצעות תיבת הבחירה המשולבת שלהלן."
#: ../js/gdm/loginDialog.js:629
#: ../js/gdm/loginDialog.js:550
msgid "Session..."
msgstr "הפעלה..."
#: ../js/gdm/loginDialog.js:800
#: ../js/gdm/loginDialog.js:699
msgctxt "title"
msgid "Sign In"
msgstr "כניסה"
#. Translators: this message is shown below the password entry field
#. to indicate the user can swipe their finger instead
#: ../js/gdm/loginDialog.js:845
#: ../js/gdm/loginDialog.js:744
#: ../js/ui/unlockDialog.js:124
msgid "(or swipe finger)"
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:866
#: ../js/gdm/loginDialog.js:765
msgid "Not listed?"
msgstr "לא רשום?"
#: ../js/gdm/loginDialog.js:1046
#: ../js/ui/endSessionDialog.js:410
#: ../js/gdm/loginDialog.js:908
#: ../js/ui/endSessionDialog.js:406
#: ../js/ui/extensionDownloader.js:195
#: ../js/ui/networkAgent.js:153
#: ../js/ui/polkitAuthenticationAgent.js:176
#: ../js/ui/shellMountOperation.js:339
#: ../js/ui/status/bluetooth.js:431
#: ../js/ui/shellMountOperation.js:396
#: ../js/ui/status/bluetooth.js:436
msgid "Cancel"
msgstr "ביטול"
#: ../js/gdm/loginDialog.js:1051
#: ../js/gdm/loginDialog.js:913
msgctxt "button"
msgid "Sign In"
msgstr "כניסה"
#: ../js/gdm/loginDialog.js:1411
#: ../js/gdm/loginDialog.js:1256
msgid "Login Window"
msgstr "חלון כניסה"
#: ../js/gdm/powerMenu.js:130
#: ../js/ui/userMenu.js:612
#: ../js/ui/userMenu.js:616
#: ../js/ui/userMenu.js:730
#: ../js/ui/userMenu.js:725
msgid "Suspend"
msgstr "השהיה"
@ -215,21 +216,21 @@ msgstr "הפעלה מחדש"
#: ../js/gdm/powerMenu.js:140
#: ../js/ui/userMenu.js:614
#: ../js/ui/userMenu.js:616
#: ../js/ui/userMenu.js:729
#: ../js/ui/userMenu.js:724
msgid "Power Off"
msgstr "כיבוי"
#: ../js/misc/util.js:95
#: ../js/misc/util.js:92
msgid "Command not found"
msgstr "הפקודה לא נמצאה"
#. Replace "Error invoking GLib.shell_parse_argv: " with
#. something nicer
#: ../js/misc/util.js:128
#: ../js/misc/util.js:125
msgid "Could not parse command:"
msgstr "לא ניתן לפענח את הפקודה:"
#: ../js/misc/util.js:136
#: ../js/misc/util.js:133
#, c-format
msgid "Execution of '%s' failed:"
msgstr "ההרצה של '%s' נכשלה:"
@ -396,40 +397,40 @@ msgid "S"
msgstr "ש׳"
#. Translators: Text to show if there are no events
#: ../js/ui/calendar.js:681
#: ../js/ui/calendar.js:685
msgid "Nothing Scheduled"
msgstr "היומן ריק"
#. Translators: Shown on calendar heading when selected day occurs on current year
#: ../js/ui/calendar.js:697
#: ../js/ui/calendar.js:701
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:700
#: ../js/ui/calendar.js:704
msgctxt "calendar heading"
msgid "%A, %B %d, %Y"
msgstr "%A, ה־%e ב%B, %Y"
#: ../js/ui/calendar.js:710
#: ../js/ui/calendar.js:714
msgid "Today"
msgstr "היום"
#: ../js/ui/calendar.js:714
#: ../js/ui/calendar.js:718
msgid "Tomorrow"
msgstr "מחר"
#: ../js/ui/calendar.js:723
#: ../js/ui/calendar.js:727
msgid "This week"
msgstr "השבוע"
#: ../js/ui/calendar.js:731
#: ../js/ui/calendar.js:735
msgid "Next week"
msgstr "בשבוע הבא"
#: ../js/ui/dash.js:239
#: ../js/ui/messageTray.js:1287
#: ../js/ui/dash.js:238
#: ../js/ui/messageTray.js:1317
msgid "Remove"
msgstr "הסרה"
@ -545,7 +546,7 @@ msgstr "המערכת מופעלת מחדש"
msgid "Install"
msgstr "התקנה"
#: ../js/ui/extensionDownloader.js:203
#: ../js/ui/extensionDownloader.js:204
#, c-format
msgid "Download and install '%s' from extensions.gnome.org?"
msgstr "הורדה והתקנה של '%s' מ־extensions.gnome.org?"
@ -555,89 +556,89 @@ msgid "tray"
msgstr "מגש מערכת"
#: ../js/ui/keyboard.js:545
#: ../js/ui/status/keyboard.js:42
#: ../js/ui/status/power.js:203
#: ../js/ui/status/keyboard.js:149
#: ../js/ui/status/power.js:209
msgid "Keyboard"
msgstr "מקלדת"
#: ../js/ui/keyringPrompt.js:85
#: ../js/ui/polkitAuthenticationAgent.js:273
#: ../js/ui/keyringPrompt.js:86
#: ../js/ui/polkitAuthenticationAgent.js:274
msgid "Password:"
msgstr "ססמה:"
#: ../js/ui/keyringPrompt.js:101
#: ../js/ui/keyringPrompt.js:102
msgid "Type again:"
msgstr "נא להקליד שוב:"
#: ../js/ui/lookingGlass.js:696
#: ../js/ui/lookingGlass.js:695
msgid "No extensions installed"
msgstr "לא מותקנות הרחבות"
#. Translators: argument is an extension UUID.
#: ../js/ui/lookingGlass.js:750
#: ../js/ui/lookingGlass.js:749
#, c-format
msgid "%s has not emitted any errors."
msgstr "%s לא העלה שגיאות כלשהן."
#: ../js/ui/lookingGlass.js:756
#: ../js/ui/lookingGlass.js:755
msgid "Hide Errors"
msgstr "הסתרת השגיאות"
#: ../js/ui/lookingGlass.js:760
#: ../js/ui/lookingGlass.js:811
#: ../js/ui/lookingGlass.js:759
#: ../js/ui/lookingGlass.js:819
msgid "Show Errors"
msgstr "הצגת השגיאות"
#: ../js/ui/lookingGlass.js:769
#: ../js/ui/lookingGlass.js:768
msgid "Enabled"
msgstr "פעיל"
#. translators:
#. * The device has been disabled
#: ../js/ui/lookingGlass.js:772
#: ../js/ui/lookingGlass.js:771
#: ../src/gvc/gvc-mixer-control.c:1082
msgid "Disabled"
msgstr "מנוטרל"
#: ../js/ui/lookingGlass.js:774
#: ../js/ui/lookingGlass.js:773
msgid "Error"
msgstr "שגיאה"
#: ../js/ui/lookingGlass.js:776
#: ../js/ui/lookingGlass.js:775
msgid "Out of date"
msgstr "לא בתוקף"
#: ../js/ui/lookingGlass.js:778
#: ../js/ui/lookingGlass.js:777
msgid "Downloading"
msgstr "בהורדה"
#: ../js/ui/lookingGlass.js:799
#: ../js/ui/lookingGlass.js:801
msgid "View Source"
msgstr "צפייה במקור"
#: ../js/ui/lookingGlass.js:805
#: ../js/ui/lookingGlass.js:810
msgid "Web Page"
msgstr "דף אינטרנט"
#. Translators: this is a filename used for screencast recording
#: ../js/ui/main.js:129
#: ../js/ui/main.js:140
#, no-c-format
msgid "Screencast from %d %t"
msgstr "צילום מסך מהקובץ %d %t"
#: ../js/ui/messageTray.js:1280
#: ../js/ui/messageTray.js:1310
msgid "Open"
msgstr "פתיחה"
#: ../js/ui/messageTray.js:1297
#: ../js/ui/messageTray.js:1327
msgid "Unmute"
msgstr "ביטול ההשתקה"
#: ../js/ui/messageTray.js:1297
#: ../js/ui/messageTray.js:1327
msgid "Mute"
msgstr "השתקה"
#: ../js/ui/messageTray.js:2575
#: ../js/ui/messageTray.js:2638
msgid "System Information"
msgstr "פרטי המערכת"
@ -646,120 +647,120 @@ msgid "Connect"
msgstr "התחברות"
#. Cisco LEAP
#: ../js/ui/networkAgent.js:243
#: ../js/ui/networkAgent.js:255
#: ../js/ui/networkAgent.js:282
#: ../js/ui/networkAgent.js:302
#: ../js/ui/networkAgent.js:312
#: ../js/ui/networkAgent.js:238
#: ../js/ui/networkAgent.js:250
#: ../js/ui/networkAgent.js:277
#: ../js/ui/networkAgent.js:297
#: ../js/ui/networkAgent.js:307
msgid "Password: "
msgstr "ססמה:"
#. static WEP
#: ../js/ui/networkAgent.js:248
#: ../js/ui/networkAgent.js:243
msgid "Key: "
msgstr "מפתח:"
#. TTLS and PEAP are actually much more complicated, but this complication
#. is not visible here since we only care about phase2 authentication
#. (and don't even care of which one)
#: ../js/ui/networkAgent.js:280
#: ../js/ui/networkAgent.js:298
#: ../js/ui/networkAgent.js:275
#: ../js/ui/networkAgent.js:293
msgid "Username: "
msgstr "שם משתמש:"
#: ../js/ui/networkAgent.js:286
#: ../js/ui/networkAgent.js:281
msgid "Identity: "
msgstr "זהות:"
#: ../js/ui/networkAgent.js:288
#: ../js/ui/networkAgent.js:283
msgid "Private key password: "
msgstr "ססמת מפתח פרטי:"
#: ../js/ui/networkAgent.js:300
#: ../js/ui/networkAgent.js:295
msgid "Service: "
msgstr "שירות:"
#: ../js/ui/networkAgent.js:329
#: ../js/ui/networkAgent.js:324
msgid "Authentication required by wireless network"
msgstr "הרשת האלחוטית דורשת אימות"
#: ../js/ui/networkAgent.js:330
#: ../js/ui/networkAgent.js:325
#, c-format
msgid "Passwords or encryption keys are required to access the wireless network '%s'."
msgstr "ססמאות או מפתחות הצפנה נדרשים כדי לגשת לרשת האלחוטית '%s'."
#: ../js/ui/networkAgent.js:334
#: ../js/ui/networkAgent.js:329
msgid "Wired 802.1X authentication"
msgstr "אימות Wired 802.1X"
#: ../js/ui/networkAgent.js:336
#: ../js/ui/networkAgent.js:331
msgid "Network name: "
msgstr "שם הרשת:"
#: ../js/ui/networkAgent.js:341
#: ../js/ui/networkAgent.js:336
msgid "DSL authentication"
msgstr "אימות DSL"
#: ../js/ui/networkAgent.js:348
#: ../js/ui/networkAgent.js:343
msgid "PIN code required"
msgstr "נדרש קוד PIN"
#: ../js/ui/networkAgent.js:349
#: ../js/ui/networkAgent.js:344
msgid "PIN code is needed for the mobile broadband device"
msgstr "נדרש קוד PIN עבור התקן החיבור האלחוטי בפס רחב"
#: ../js/ui/networkAgent.js:350
#: ../js/ui/networkAgent.js:345
msgid "PIN: "
msgstr "PIN: "
#: ../js/ui/networkAgent.js:356
#: ../js/ui/networkAgent.js:351
msgid "Mobile broadband network password"
msgstr "ססמת רשת הפס הרחב הניידת"
#: ../js/ui/networkAgent.js:357
#: ../js/ui/networkAgent.js:352
#, c-format
msgid "A password is required to connect to '%s'."
msgstr "נדרשת ססמה כדי להתחבר אל '%s'."
#: ../js/ui/notificationDaemon.js:486
#: ../js/ui/notificationDaemon.js:484
#: ../src/shell-app.c:374
msgctxt "program"
msgid "Unknown"
msgstr "לא ידוע"
#: ../js/ui/overview.js:88
#: ../js/ui/overview.js:89
msgid "Undo"
msgstr "ביטול"
#: ../js/ui/overview.js:128
#: ../js/ui/overview.js:129
msgid "Overview"
msgstr "סקירה"
#: ../js/ui/overview.js:198
#: ../js/ui/overview.js:199
msgid "Windows"
msgstr "חלונות"
#: ../js/ui/overview.js:201
#: ../js/ui/overview.js:202
msgid "Applications"
msgstr "יישומים"
#. Translators: this is the name of the dock/favorites area on
#. the left of the overview
#: ../js/ui/overview.js:226
#: ../js/ui/overview.js:227
msgid "Dash"
msgstr "חלונית"
#: ../js/ui/panel.js:564
#: ../js/ui/panel.js:573
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:596
#: ../js/ui/panel.js:605
msgid "Activities"
msgstr "פעילויות"
#: ../js/ui/panel.js:962
#: ../js/ui/panel.js:975
msgid "Top Bar"
msgstr "הסרגל העליון"
@ -796,8 +797,8 @@ msgstr "אימות"
#. * requested authentication was not gained; this can happen
#. * because of an authentication error (like invalid password),
#. * for instance.
#: ../js/ui/polkitAuthenticationAgent.js:261
#: ../js/ui/shellMountOperation.js:324
#: ../js/ui/polkitAuthenticationAgent.js:262
#: ../js/ui/shellMountOperation.js:381
msgid "Sorry, that didn't work. Please try again."
msgstr "פעולה זו לא הצליחה, נא לנסות שוב. עמך הסליחה."
@ -806,7 +807,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:728
#: ../js/ui/popupMenu.js:723
msgid "toggle-switch-us"
msgstr "toggle-switch-intl"
@ -830,23 +831,24 @@ msgstr "העתקה"
msgid "Paste"
msgstr "הדבקה"
#: ../js/ui/shellEntry.js:77
#: ../js/ui/shellEntry.js:96
msgid "Show Text"
msgstr "הצגת טקסט"
#: ../js/ui/shellEntry.js:79
#: ../js/ui/shellEntry.js:98
msgid "Hide Text"
msgstr "הסתרת טקסט"
#: ../js/ui/shellMountOperation.js:311
#: ../js/ui/shellMountOperation.js:368
msgid "Passphrase"
msgstr "מילת צופן"
#: ../js/ui/shellMountOperation.js:332
#: ../js/ui/shellMountOperation.js:389
msgid "Remember Passphrase"
msgstr "שמירת מילת הצופן"
#: ../js/ui/shellMountOperation.js:343
#: ../js/ui/shellMountOperation.js:400
#: ../js/ui/unlockDialog.js:142
msgid "Unlock"
msgstr "שחרור"
@ -890,21 +892,21 @@ msgstr "מקשי עכבר"
msgid "Universal Access Settings"
msgstr "הגדרות גישה אוניברסלית"
#: ../js/ui/status/accessibility.js:117
#: ../js/ui/status/accessibility.js:121
msgid "High Contrast"
msgstr "ניגודיות גבוהה"
#: ../js/ui/status/accessibility.js:154
#: ../js/ui/status/accessibility.js:158
msgid "Large Text"
msgstr "טקסט גדול"
#: ../js/ui/status/bluetooth.js:31
#: ../js/ui/status/bluetooth.js:35
#: ../js/ui/status/bluetooth.js:255
#: ../js/ui/status/bluetooth.js:308
#: ../js/ui/status/bluetooth.js:339
#: ../js/ui/status/bluetooth.js:375
#: ../js/ui/status/bluetooth.js:404
#: ../js/ui/status/bluetooth.js:260
#: ../js/ui/status/bluetooth.js:313
#: ../js/ui/status/bluetooth.js:344
#: ../js/ui/status/bluetooth.js:380
#: ../js/ui/status/bluetooth.js:409
#: ../js/ui/status/network.js:844
msgid "Bluetooth"
msgstr "Bluetooth"
@ -926,121 +928,121 @@ msgid "Bluetooth Settings"
msgstr "הגדרות Bluetooth"
#. TRANSLATORS: this means that bluetooth was disabled by hardware rfkill
#: ../js/ui/status/bluetooth.js:107
#: ../js/ui/status/bluetooth.js:112
#: ../js/ui/status/network.js:211
msgid "hardware disabled"
msgstr "מנוטרל חומרתית"
#: ../js/ui/status/bluetooth.js:200
#: ../js/ui/status/bluetooth.js:205
msgid "Connection"
msgstr "חיבור"
#: ../js/ui/status/bluetooth.js:211
#: ../js/ui/status/bluetooth.js:216
#: ../js/ui/status/network.js:445
msgid "disconnecting..."
msgstr "בהליכי ניתוק..."
#: ../js/ui/status/bluetooth.js:224
#: ../js/ui/status/bluetooth.js:229
#: ../js/ui/status/network.js:451
#: ../js/ui/status/network.js:911
msgid "connecting..."
msgstr "בהתחברות..."
#: ../js/ui/status/bluetooth.js:242
#: ../js/ui/status/bluetooth.js:247
msgid "Send Files..."
msgstr "שליחת קבצים..."
#: ../js/ui/status/bluetooth.js:247
#: ../js/ui/status/bluetooth.js:252
msgid "Browse Files..."
msgstr "עיון בקבצים..."
#: ../js/ui/status/bluetooth.js:256
#: ../js/ui/status/bluetooth.js:261
msgid "Error browsing device"
msgstr "שגיאה בעיון בהתקן"
#: ../js/ui/status/bluetooth.js:257
#: ../js/ui/status/bluetooth.js:262
#, c-format
msgid "The requested device cannot be browsed, error is '%s'"
msgstr "לא ניתן לעיין בהתקן הנבחר, השגיאה היא '%s'"
#: ../js/ui/status/bluetooth.js:265
#: ../js/ui/status/bluetooth.js:270
msgid "Keyboard Settings"
msgstr "הגדרות מקלדת"
#: ../js/ui/status/bluetooth.js:268
#: ../js/ui/status/bluetooth.js:273
msgid "Mouse Settings"
msgstr "הגדרות עכבר"
#: ../js/ui/status/bluetooth.js:273
#: ../js/ui/status/bluetooth.js:278
#: ../js/ui/status/volume.js:59
msgid "Sound Settings"
msgstr "הגדרות שמע"
#: ../js/ui/status/bluetooth.js:340
#: ../js/ui/status/bluetooth.js:345
#, c-format
msgid "Authorization request from %s"
msgstr "בקשת אישור מאת %s"
#: ../js/ui/status/bluetooth.js:346
#: ../js/ui/status/bluetooth.js:351
#, c-format
msgid "Device %s wants access to the service '%s'"
msgstr "ההתקן %s מעוניין לגשת אל השירות '%s'"
#: ../js/ui/status/bluetooth.js:348
#: ../js/ui/status/bluetooth.js:353
msgid "Always grant access"
msgstr "תמיד להעניק גישה"
#: ../js/ui/status/bluetooth.js:349
#: ../js/ui/status/bluetooth.js:354
msgid "Grant this time only"
msgstr "הענקת גישה הפעם בלבד"
#: ../js/ui/status/bluetooth.js:350
#: ../js/ui/status/bluetooth.js:355
#: ../js/ui/telepathyClient.js:1097
msgid "Reject"
msgstr "סירוב"
#: ../js/ui/status/bluetooth.js:376
#: ../js/ui/status/bluetooth.js:381
#, c-format
msgid "Pairing confirmation for %s"
msgstr "אישור צימוד עבור %s"
#: ../js/ui/status/bluetooth.js:382
#: ../js/ui/status/bluetooth.js:412
#: ../js/ui/status/bluetooth.js:387
#: ../js/ui/status/bluetooth.js:417
#, c-format
msgid "Device %s wants to pair with this computer"
msgstr "ההתקן %s מעוניין בצימוד עם מחשב זה"
#: ../js/ui/status/bluetooth.js:383
#: ../js/ui/status/bluetooth.js:388
#, c-format
msgid "Please confirm whether the PIN '%06d' matches the one on the device."
msgstr "נא לאשר האם קוד ה־PIN '%06d' תואם את זה שמופיע בהתקן."
#: ../js/ui/status/bluetooth.js:385
#: ../js/ui/status/bluetooth.js:390
msgid "Matches"
msgstr "התאמות"
#: ../js/ui/status/bluetooth.js:386
#: ../js/ui/status/bluetooth.js:391
msgid "Does not match"
msgstr "אינו תואם"
#: ../js/ui/status/bluetooth.js:405
#: ../js/ui/status/bluetooth.js:410
#, c-format
msgid "Pairing request for %s"
msgstr "בקשת צימוד עבור %s"
#: ../js/ui/status/bluetooth.js:413
#: ../js/ui/status/bluetooth.js:418
msgid "Please enter the PIN mentioned on the device."
msgstr "נא להזין את קוד ה־PIN המוזכר בהתקן."
#: ../js/ui/status/bluetooth.js:430
#: ../js/ui/status/bluetooth.js:435
msgid "OK"
msgstr "אישור"
#: ../js/ui/status/keyboard.js:69
#: ../js/ui/status/keyboard.js:178
msgid "Show Keyboard Layout"
msgstr "הצגת פריסת המקלדת"
#: ../js/ui/status/keyboard.js:71
#: ../js/ui/status/keyboard.js:180
msgid "Region and Language Settings"
msgstr "הגדרות אזור ושפה"
@ -1150,19 +1152,19 @@ msgstr "חיבורי VPN"
msgid "Network Settings"
msgstr "הגדרות הרשת"
#: ../js/ui/status/network.js:1703
#: ../js/ui/status/network.js:1712
msgid "Network Manager"
msgstr "מנהל הרשתות"
#: ../js/ui/status/network.js:1796
#: ../js/ui/status/network.js:1805
msgid "Connection failed"
msgstr "ההתחברות נכשל"
#: ../js/ui/status/network.js:1797
#: ../js/ui/status/network.js:1806
msgid "Activation of network connection failed"
msgstr "הפעלת חיבור הרשת נכשלה"
#: ../js/ui/status/network.js:2060
#: ../js/ui/status/network.js:2069
msgid "Networking is disabled"
msgstr "תכונת הרשת מנוטרלת"
@ -1176,11 +1178,11 @@ msgstr "הגדרות צריכת החשמל"
#. 0 is reported when UPower does not have enough data
#. to estimate battery life
#: ../js/ui/status/power.js:98
#: ../js/ui/status/power.js:104
msgid "Estimating..."
msgstr "מתבצע שיערוך..."
#: ../js/ui/status/power.js:105
#: ../js/ui/status/power.js:111
#, c-format
msgid "%d hour remaining"
msgid_plural "%d hours remaining"
@ -1189,26 +1191,26 @@ msgstr[1] "נותרו %d שעות"
msgstr[2] "נותרו שעתיים"
#. TRANSLATORS: this is a time string, as in "%d hours %d minutes remaining"
#: ../js/ui/status/power.js:108
#: ../js/ui/status/power.js:114
#, c-format
msgid "%d %s %d %s remaining"
msgstr "%d %s %d %s נותרו"
#: ../js/ui/status/power.js:110
#: ../js/ui/status/power.js:116
msgid "hour"
msgid_plural "hours"
msgstr[0] "שעה"
msgstr[1] "שעות"
msgstr[2] "שעתיים"
#: ../js/ui/status/power.js:110
#: ../js/ui/status/power.js:116
msgid "minute"
msgid_plural "minutes"
msgstr[0] "דקה"
msgstr[1] "דקות"
msgstr[2] "דקות"
#: ../js/ui/status/power.js:113
#: ../js/ui/status/power.js:119
#, c-format
msgid "%d minute remaining"
msgid_plural "%d minutes remaining"
@ -1216,54 +1218,54 @@ msgstr[0] "דקה אחת נותרה"
msgstr[1] "%d דקות נותרו"
msgstr[2] "שתי דקות נותרו"
#: ../js/ui/status/power.js:116
#: ../js/ui/status/power.js:186
#: ../js/ui/status/power.js:122
#: ../js/ui/status/power.js:192
#, c-format
msgctxt "percent of battery remaining"
msgid "%d%%"
msgstr "%d%%"
#: ../js/ui/status/power.js:193
#: ../js/ui/status/power.js:199
msgid "AC adapter"
msgstr "מתאם חשמל"
#: ../js/ui/status/power.js:195
#: ../js/ui/status/power.js:201
msgid "Laptop battery"
msgstr "סוללת נייד"
#: ../js/ui/status/power.js:197
#: ../js/ui/status/power.js:203
msgid "UPS"
msgstr "אל־פסק"
#: ../js/ui/status/power.js:199
#: ../js/ui/status/power.js:205
msgid "Monitor"
msgstr "צג"
#: ../js/ui/status/power.js:201
#: ../js/ui/status/power.js:207
msgid "Mouse"
msgstr "עכבר"
#: ../js/ui/status/power.js:205
#: ../js/ui/status/power.js:211
msgid "PDA"
msgstr "מחשב כף יד"
#: ../js/ui/status/power.js:207
#: ../js/ui/status/power.js:213
msgid "Cell phone"
msgstr "טלפון סלולרי"
#: ../js/ui/status/power.js:209
#: ../js/ui/status/power.js:215
msgid "Media player"
msgstr "נגן מדיה"
#: ../js/ui/status/power.js:211
#: ../js/ui/status/power.js:217
msgid "Tablet"
msgstr "טבלת שליטה"
#: ../js/ui/status/power.js:213
#: ../js/ui/status/power.js:219
msgid "Computer"
msgstr "מחשב"
#: ../js/ui/status/power.js:215
#: ../js/ui/status/power.js:221
msgctxt "device"
msgid "Unknown"
msgstr "לא ידוע"
@ -1506,27 +1508,31 @@ msgstr "עריכת חשבון"
msgid "Unknown reason"
msgstr "סיבה לא ידועה"
#: ../js/ui/userMenu.js:130
#: ../js/ui/unlockDialog.js:129
msgid "Login as another user"
msgstr "כניסה בתור משתמש אחר"
#: ../js/ui/userMenu.js:161
msgid "Available"
msgstr "זמין"
#: ../js/ui/userMenu.js:133
#: ../js/ui/userMenu.js:164
msgid "Busy"
msgstr "עסוק"
#: ../js/ui/userMenu.js:136
#: ../js/ui/userMenu.js:167
msgid "Invisible"
msgstr "בלתי נראה"
#: ../js/ui/userMenu.js:139
#: ../js/ui/userMenu.js:170
msgid "Away"
msgstr "מרוחק"
#: ../js/ui/userMenu.js:142
#: ../js/ui/userMenu.js:173
msgid "Idle"
msgstr "בהמתנה"
#: ../js/ui/userMenu.js:145
#: ../js/ui/userMenu.js:176
msgid "Unavailable"
msgstr "לא זמין"
@ -1555,7 +1561,7 @@ msgstr "ֹיציאה"
msgid "Lock"
msgstr "נעילה"
#: ../js/ui/userMenu.js:724
#: ../js/ui/userMenu.js:731
msgid "Install Updates & Restart"
msgstr "התקנת עדכונים והפעלה מחדש"
@ -1576,7 +1582,7 @@ msgid "Type to search..."
msgstr "יש להקליד כדי לחפש..."
#: ../js/ui/viewSelector.js:131
#: ../src/shell-util.c:253
#: ../src/shell-util.c:254
msgid "Search"
msgstr "חיפוש"
@ -1631,19 +1637,19 @@ msgstr[2] "2 קלטים"
msgid "System Sounds"
msgstr "צלילי מערכת"
#: ../src/main.c:327
#: ../src/main.c:330
msgid "Print version"
msgstr "Print version"
#: ../src/main.c:333
#: ../src/main.c:336
msgid "Mode used by GDM for login screen"
msgstr "המצב בו GDM יעשה שימוש לצורך מסך הכניסה"
#: ../src/main.c:339
#: ../src/main.c:342
msgid "Use a specific mode, e.g. \"gdm\" for login screen"
msgstr "שימוש במצב מסוים, לדוגמה: „gdm“ למסך הכניסה"
#: ../src/main.c:345
#: ../src/main.c:348
msgid "List possible modes"
msgstr "הצגת המצבים האפשריים"
@ -1674,13 +1680,13 @@ msgstr "המשתמש בחר להתעלם מתיבת דו־שיח האימות"
#. Translators: this is the same string as the one found in
#. * nautilus
#: ../src/shell-util.c:97
#: ../src/shell-util.c:98
msgid "Home"
msgstr "בית"
#. Translators: this is the same string as the one found in
#. * nautilus
#: ../src/shell-util.c:107
#: ../src/shell-util.c:108
msgid "File System"
msgstr "מערכת הקבצים"
@ -1689,7 +1695,7 @@ msgstr "מערכת הקבצים"
#. * example, "Trash: some-directory". It means that the
#. * directory called "some-directory" is in the trash.
#.
#: ../src/shell-util.c:303
#: ../src/shell-util.c:304
#, c-format
msgid "%1$s: %2$s"
msgstr "%1$s: %2$s"

1021
po/hu.po

File diff suppressed because it is too large Load Diff

968
po/kk.po

File diff suppressed because it is too large Load Diff

310
po/nb.po
View File

@ -8,8 +8,8 @@ msgid ""
msgstr ""
"Project-Id-Version: gnome-shell 3.5.x\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2012-07-10 08:31+0200\n"
"PO-Revision-Date: 2012-07-10 08:32+0200\n"
"POT-Creation-Date: 2012-07-25 13:16+0200\n"
"PO-Revision-Date: 2012-07-25 13:16+0200\n"
"Last-Translator: Kjartan Maraas <kmaraas@gnome.org>\n"
"Language-Team: Norwegian bokmål <i18n-nb@lister.ping.uio.no>\n"
"Language: \n"
@ -27,7 +27,7 @@ msgid "Window management and application launching"
msgstr "Vindushåndtering og oppstart av programmer"
#: ../data/gnome-shell-extension-prefs.desktop.in.in.h:1
#: ../js/extensionPrefs/main.js:153
#: ../js/extensionPrefs/main.js:152
msgid "GNOME Shell Extension Preferences"
msgstr "Brukervalg for GNOME Shell utvidelser"
@ -194,59 +194,59 @@ msgstr ""
"og bruke denne filendelsen. Den bør endres når du gjør opptak til et nytt "
"oppbevaringsformat."
#: ../js/extensionPrefs/main.js:125
#: ../js/extensionPrefs/main.js:124
#, c-format
msgid "There was an error loading the preferences dialog for %s:"
msgstr "Det oppsto en feil ved lasting av brukervalgdialog for %s:"
#: ../js/extensionPrefs/main.js:165
#: ../js/extensionPrefs/main.js:164
msgid "<b>Extension</b>"
msgstr "<b>Utvidelse</b>"
#: ../js/extensionPrefs/main.js:189
#: ../js/extensionPrefs/main.js:188
msgid "Select an extension to configure using the combobox above."
msgstr "Velg en utvidelse som skal konfigureres med komboboksen over."
#: ../js/gdm/loginDialog.js:629
#: ../js/gdm/loginDialog.js:550
msgid "Session..."
msgstr "Økt …"
#: ../js/gdm/loginDialog.js:800
#: ../js/gdm/loginDialog.js:699
msgctxt "title"
msgid "Sign In"
msgstr "Logg inn"
#. Translators: this message is shown below the password entry field
#. to indicate the user can swipe their finger instead
#: ../js/gdm/loginDialog.js:845
#: ../js/gdm/loginDialog.js:744 ../js/ui/unlockDialog.js:124
msgid "(or swipe finger)"
msgstr "(eller dra finger)"
#. 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:866
#: ../js/gdm/loginDialog.js:765
msgid "Not listed?"
msgstr "Ikke listet?"
#: ../js/gdm/loginDialog.js:1046 ../js/ui/endSessionDialog.js:410
#: ../js/ui/extensionDownloader.js:138 ../js/ui/networkAgent.js:153
#: ../js/gdm/loginDialog.js:908 ../js/ui/endSessionDialog.js:406
#: ../js/ui/extensionDownloader.js:195 ../js/ui/networkAgent.js:153
#: ../js/ui/polkitAuthenticationAgent.js:176
#: ../js/ui/shellMountOperation.js:339 ../js/ui/status/bluetooth.js:431
#: ../js/ui/shellMountOperation.js:396 ../js/ui/status/bluetooth.js:436
msgid "Cancel"
msgstr "Avbryt"
#: ../js/gdm/loginDialog.js:1051
#: ../js/gdm/loginDialog.js:913
msgctxt "button"
msgid "Sign In"
msgstr "Logg inn"
#: ../js/gdm/loginDialog.js:1411
#: ../js/gdm/loginDialog.js:1256
msgid "Login Window"
msgstr "Innloggingsvindu"
#: ../js/gdm/powerMenu.js:130 ../js/ui/userMenu.js:612
#: ../js/ui/userMenu.js:616 ../js/ui/userMenu.js:730
#: ../js/ui/userMenu.js:616 ../js/ui/userMenu.js:725
msgid "Suspend"
msgstr "Hvilemodus"
@ -255,21 +255,21 @@ msgid "Restart"
msgstr "Start på nytt"
#: ../js/gdm/powerMenu.js:140 ../js/ui/userMenu.js:614
#: ../js/ui/userMenu.js:616 ../js/ui/userMenu.js:729
#: ../js/ui/userMenu.js:616 ../js/ui/userMenu.js:724
msgid "Power Off"
msgstr "Slå av"
#: ../js/misc/util.js:95
#: ../js/misc/util.js:92
msgid "Command not found"
msgstr "Kommando ikke funnet"
#. Replace "Error invoking GLib.shell_parse_argv: " with
#. something nicer
#: ../js/misc/util.js:128
#: ../js/misc/util.js:125
msgid "Could not parse command:"
msgstr "Klarte ikke å lese kommando:"
#: ../js/misc/util.js:136
#: ../js/misc/util.js:133
#, c-format
msgid "Execution of '%s' failed:"
msgstr "Kjøring av «%s» feilet:"
@ -436,39 +436,39 @@ msgid "S"
msgstr "Lø"
#. Translators: Text to show if there are no events
#: ../js/ui/calendar.js:681
#: ../js/ui/calendar.js:685
msgid "Nothing Scheduled"
msgstr "Ingenting planlagt"
#. Translators: Shown on calendar heading when selected day occurs on current year
#: ../js/ui/calendar.js:697
#: ../js/ui/calendar.js:701
msgctxt "calendar heading"
msgid "%A, %B %d"
msgstr "%A %B %d"
#. Translators: Shown on calendar heading when selected day occurs on different year
#: ../js/ui/calendar.js:700
#: ../js/ui/calendar.js:704
msgctxt "calendar heading"
msgid "%A, %B %d, %Y"
msgstr "%A %B %d, %Y"
#: ../js/ui/calendar.js:710
#: ../js/ui/calendar.js:714
msgid "Today"
msgstr "I dag"
#: ../js/ui/calendar.js:714
#: ../js/ui/calendar.js:718
msgid "Tomorrow"
msgstr "I morgen"
#: ../js/ui/calendar.js:723
#: ../js/ui/calendar.js:727
msgid "This week"
msgstr "Denne uken"
#: ../js/ui/calendar.js:731
#: ../js/ui/calendar.js:735
msgid "Next week"
msgstr "Neste uke"
#: ../js/ui/dash.js:239 ../js/ui/messageTray.js:1287
#: ../js/ui/dash.js:238 ../js/ui/messageTray.js:1317
msgid "Remove"
msgstr "Fjern"
@ -579,11 +579,11 @@ msgstr[1] "Systemet vil starte på nytt automatisk om %d sekunder."
msgid "Restarting the system."
msgstr "Starter systemet på nytt."
#: ../js/ui/extensionDownloader.js:142
#: ../js/ui/extensionDownloader.js:199
msgid "Install"
msgstr "Installer"
#: ../js/ui/extensionDownloader.js:146
#: ../js/ui/extensionDownloader.js:204
#, c-format
msgid "Download and install '%s' from extensions.gnome.org?"
msgstr "Last ned og installer «%s» fra extensions.gnome.org?"
@ -592,86 +592,86 @@ msgstr "Last ned og installer «%s» fra extensions.gnome.org?"
msgid "tray"
msgstr "varslingsområde"
#: ../js/ui/keyboard.js:545 ../js/ui/status/keyboard.js:42
#: ../js/ui/status/power.js:203
#: ../js/ui/keyboard.js:545 ../js/ui/status/keyboard.js:149
#: ../js/ui/status/power.js:209
msgid "Keyboard"
msgstr "Tastatur"
#: ../js/ui/keyringPrompt.js:85 ../js/ui/polkitAuthenticationAgent.js:273
#: ../js/ui/keyringPrompt.js:86 ../js/ui/polkitAuthenticationAgent.js:274
msgid "Password:"
msgstr "Passord:"
#: ../js/ui/keyringPrompt.js:101
#: ../js/ui/keyringPrompt.js:102
msgid "Type again:"
msgstr "Skriv på nytt:"
#: ../js/ui/lookingGlass.js:696
#: ../js/ui/lookingGlass.js:695
msgid "No extensions installed"
msgstr "Ingen utvidelser installert"
#. Translators: argument is an extension UUID.
#: ../js/ui/lookingGlass.js:750
#: ../js/ui/lookingGlass.js:749
#, c-format
msgid "%s has not emitted any errors."
msgstr "%s har ikke avgitt noen feil."
#: ../js/ui/lookingGlass.js:756
#: ../js/ui/lookingGlass.js:755
msgid "Hide Errors"
msgstr "Skjul feil"
#: ../js/ui/lookingGlass.js:760 ../js/ui/lookingGlass.js:811
#: ../js/ui/lookingGlass.js:759 ../js/ui/lookingGlass.js:819
msgid "Show Errors"
msgstr "Vis feil"
#: ../js/ui/lookingGlass.js:769
#: ../js/ui/lookingGlass.js:768
msgid "Enabled"
msgstr "Aktivert"
#. translators:
#. * The device has been disabled
#: ../js/ui/lookingGlass.js:772 ../src/gvc/gvc-mixer-control.c:1082
#: ../js/ui/lookingGlass.js:771 ../src/gvc/gvc-mixer-control.c:1082
msgid "Disabled"
msgstr "Deaktivert"
#: ../js/ui/lookingGlass.js:774
#: ../js/ui/lookingGlass.js:773
msgid "Error"
msgstr "Feil"
#: ../js/ui/lookingGlass.js:776
#: ../js/ui/lookingGlass.js:775
msgid "Out of date"
msgstr "Utdatert"
#: ../js/ui/lookingGlass.js:778
#: ../js/ui/lookingGlass.js:777
msgid "Downloading"
msgstr "Laster ned"
#: ../js/ui/lookingGlass.js:799
#: ../js/ui/lookingGlass.js:801
msgid "View Source"
msgstr "Vis kildekode"
#: ../js/ui/lookingGlass.js:805
#: ../js/ui/lookingGlass.js:810
msgid "Web Page"
msgstr "Nettside"
#. Translators: this is a filename used for screencast recording
#: ../js/ui/main.js:129
#: ../js/ui/main.js:140
#, no-c-format
msgid "Screencast from %d %t"
msgstr "Skjermvideo fra %d %t"
#: ../js/ui/messageTray.js:1280
#: ../js/ui/messageTray.js:1310
msgid "Open"
msgstr "Åpne"
#: ../js/ui/messageTray.js:1297
#: ../js/ui/messageTray.js:1327
msgid "Unmute"
msgstr "Fjern demping"
#: ../js/ui/messageTray.js:1297
#: ../js/ui/messageTray.js:1327
msgid "Mute"
msgstr "Demp"
#: ../js/ui/messageTray.js:2575
#: ../js/ui/messageTray.js:2638
msgid "System Information"
msgstr "Systeminformasjon"
@ -680,41 +680,41 @@ msgid "Connect"
msgstr "Koble til"
#. Cisco LEAP
#: ../js/ui/networkAgent.js:243 ../js/ui/networkAgent.js:255
#: ../js/ui/networkAgent.js:282 ../js/ui/networkAgent.js:302
#: ../js/ui/networkAgent.js:312
#: ../js/ui/networkAgent.js:238 ../js/ui/networkAgent.js:250
#: ../js/ui/networkAgent.js:277 ../js/ui/networkAgent.js:297
#: ../js/ui/networkAgent.js:307
msgid "Password: "
msgstr "Passord: "
#. static WEP
#: ../js/ui/networkAgent.js:248
#: ../js/ui/networkAgent.js:243
msgid "Key: "
msgstr "Nøkkel: "
#. 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/ui/networkAgent.js:280 ../js/ui/networkAgent.js:298
#: ../js/ui/networkAgent.js:275 ../js/ui/networkAgent.js:293
msgid "Username: "
msgstr "Brukernavn: "
#: ../js/ui/networkAgent.js:286
#: ../js/ui/networkAgent.js:281
msgid "Identity: "
msgstr "Identitet: "
#: ../js/ui/networkAgent.js:288
#: ../js/ui/networkAgent.js:283
msgid "Private key password: "
msgstr "Passord for privat nøkkel: "
#: ../js/ui/networkAgent.js:300
#: ../js/ui/networkAgent.js:295
msgid "Service: "
msgstr "Tjeneste: "
#: ../js/ui/networkAgent.js:329
#: ../js/ui/networkAgent.js:324
msgid "Authentication required by wireless network"
msgstr "Autentisering kreves av trådløst nettverk"
#: ../js/ui/networkAgent.js:330
#: ../js/ui/networkAgent.js:325
#, c-format
msgid ""
"Passwords or encryption keys are required to access the wireless network "
@ -723,77 +723,77 @@ msgstr ""
"Passord eller krypteringsnøkler kreves for å koble til trådløst nettverk "
"«%s»."
#: ../js/ui/networkAgent.js:334
#: ../js/ui/networkAgent.js:329
msgid "Wired 802.1X authentication"
msgstr "802.1X autentisering for trådbundet nettverk"
#: ../js/ui/networkAgent.js:336
#: ../js/ui/networkAgent.js:331
msgid "Network name: "
msgstr "Navn på nettverk: "
#: ../js/ui/networkAgent.js:341
#: ../js/ui/networkAgent.js:336
msgid "DSL authentication"
msgstr "DSL-autentisering"
#: ../js/ui/networkAgent.js:348
#: ../js/ui/networkAgent.js:343
msgid "PIN code required"
msgstr "PIN-kode kreves"
#: ../js/ui/networkAgent.js:349
#: ../js/ui/networkAgent.js:344
msgid "PIN code is needed for the mobile broadband device"
msgstr "PIN-kode kreves for mobil bredbåndsenhet"
#: ../js/ui/networkAgent.js:350
#: ../js/ui/networkAgent.js:345
msgid "PIN: "
msgstr "PIN: "
#: ../js/ui/networkAgent.js:356
#: ../js/ui/networkAgent.js:351
msgid "Mobile broadband network password"
msgstr "Nettverkspassord for mobilt bredbånd"
#: ../js/ui/networkAgent.js:357
#: ../js/ui/networkAgent.js:352
#, c-format
msgid "A password is required to connect to '%s'."
msgstr "Et passord kreves for å koble til «%s»."
#: ../js/ui/notificationDaemon.js:486 ../src/shell-app.c:374
#: ../js/ui/notificationDaemon.js:484 ../src/shell-app.c:374
msgctxt "program"
msgid "Unknown"
msgstr "Ukjent"
#: ../js/ui/overview.js:88
#: ../js/ui/overview.js:89
msgid "Undo"
msgstr "Angre"
#: ../js/ui/overview.js:128
#: ../js/ui/overview.js:129
msgid "Overview"
msgstr "Oversikt"
#: ../js/ui/overview.js:198
#: ../js/ui/overview.js:199
msgid "Windows"
msgstr "Vinduer"
#: ../js/ui/overview.js:201
#: ../js/ui/overview.js:202
msgid "Applications"
msgstr "Programmer"
#. Translators: this is the name of the dock/favorites area on
#. the left of the overview
#: ../js/ui/overview.js:226
#: ../js/ui/overview.js:227
msgid "Dash"
msgstr "Favoritter"
#: ../js/ui/panel.js:564
#: ../js/ui/panel.js:573
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:596
#: ../js/ui/panel.js:605
msgid "Activities"
msgstr "Aktiviteter"
#: ../js/ui/panel.js:962
#: ../js/ui/panel.js:975
msgid "Top Bar"
msgstr "Topp-panel"
@ -830,8 +830,8 @@ msgstr "Autentiser"
#. * requested authentication was not gained; this can happen
#. * because of an authentication error (like invalid password),
#. * for instance.
#: ../js/ui/polkitAuthenticationAgent.js:261
#: ../js/ui/shellMountOperation.js:324
#: ../js/ui/polkitAuthenticationAgent.js:262
#: ../js/ui/shellMountOperation.js:381
msgid "Sorry, that didn't work. Please try again."
msgstr "Beklager, det virket ikke. Vennligst prøv igjen."
@ -840,7 +840,7 @@ msgstr "Beklager, det virket ikke. Vennligst prøv igjen."
#. "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:728
#: ../js/ui/popupMenu.js:723
msgid "toggle-switch-us"
msgstr "toggle-switch-intl"
@ -864,23 +864,23 @@ msgstr "Kopier"
msgid "Paste"
msgstr "Lim inn"
#: ../js/ui/shellEntry.js:77
#: ../js/ui/shellEntry.js:96
msgid "Show Text"
msgstr "Vis tekst"
#: ../js/ui/shellEntry.js:79
#: ../js/ui/shellEntry.js:98
msgid "Hide Text"
msgstr "Skjul tekst"
#: ../js/ui/shellMountOperation.js:311
#: ../js/ui/shellMountOperation.js:368
msgid "Passphrase"
msgstr "Passordfrase"
#: ../js/ui/shellMountOperation.js:332
#: ../js/ui/shellMountOperation.js:389
msgid "Remember Passphrase"
msgstr "Husk passordfrase"
#: ../js/ui/shellMountOperation.js:343
#: ../js/ui/shellMountOperation.js:400 ../js/ui/unlockDialog.js:142
msgid "Unlock"
msgstr "Lås opp"
@ -924,18 +924,18 @@ msgstr "Mustaster"
msgid "Universal Access Settings"
msgstr "Innstillinger for tilgjengelighet"
#: ../js/ui/status/accessibility.js:117
#: ../js/ui/status/accessibility.js:121
msgid "High Contrast"
msgstr "Høy kontrast"
#: ../js/ui/status/accessibility.js:154
#: ../js/ui/status/accessibility.js:158
msgid "Large Text"
msgstr "Stor tekst"
#: ../js/ui/status/bluetooth.js:31 ../js/ui/status/bluetooth.js:35
#: ../js/ui/status/bluetooth.js:255 ../js/ui/status/bluetooth.js:308
#: ../js/ui/status/bluetooth.js:339 ../js/ui/status/bluetooth.js:375
#: ../js/ui/status/bluetooth.js:404 ../js/ui/status/network.js:844
#: ../js/ui/status/bluetooth.js:260 ../js/ui/status/bluetooth.js:313
#: ../js/ui/status/bluetooth.js:344 ../js/ui/status/bluetooth.js:380
#: ../js/ui/status/bluetooth.js:409 ../js/ui/status/network.js:844
msgid "Bluetooth"
msgstr "Bluetooth"
@ -956,115 +956,115 @@ msgid "Bluetooth Settings"
msgstr "Innstillinger for Bluetooth"
#. TRANSLATORS: this means that bluetooth was disabled by hardware rfkill
#: ../js/ui/status/bluetooth.js:107 ../js/ui/status/network.js:211
#: ../js/ui/status/bluetooth.js:112 ../js/ui/status/network.js:211
msgid "hardware disabled"
msgstr "maskinvare slått av"
#: ../js/ui/status/bluetooth.js:200
#: ../js/ui/status/bluetooth.js:205
msgid "Connection"
msgstr "Tilkobling"
#: ../js/ui/status/bluetooth.js:211 ../js/ui/status/network.js:445
#: ../js/ui/status/bluetooth.js:216 ../js/ui/status/network.js:445
msgid "disconnecting..."
msgstr "kobler fra …"
#: ../js/ui/status/bluetooth.js:224 ../js/ui/status/network.js:451
#: ../js/ui/status/bluetooth.js:229 ../js/ui/status/network.js:451
#: ../js/ui/status/network.js:911
msgid "connecting..."
msgstr "kobler til …"
#: ../js/ui/status/bluetooth.js:242
#: ../js/ui/status/bluetooth.js:247
msgid "Send Files..."
msgstr "Send filer …"
#: ../js/ui/status/bluetooth.js:247
#: ../js/ui/status/bluetooth.js:252
msgid "Browse Files..."
msgstr "Bla gjennom filer …"
#: ../js/ui/status/bluetooth.js:256
#: ../js/ui/status/bluetooth.js:261
msgid "Error browsing device"
msgstr "Feil under lesing av enhet"
#: ../js/ui/status/bluetooth.js:257
#: ../js/ui/status/bluetooth.js:262
#, c-format
msgid "The requested device cannot be browsed, error is '%s'"
msgstr "Kan ikke bla gjennom forespurt enhet. Feilen er «%s»"
#: ../js/ui/status/bluetooth.js:265
#: ../js/ui/status/bluetooth.js:270
msgid "Keyboard Settings"
msgstr "Innstillinger for tastatur"
#: ../js/ui/status/bluetooth.js:268
#: ../js/ui/status/bluetooth.js:273
msgid "Mouse Settings"
msgstr "Innstillinger for mus"
#: ../js/ui/status/bluetooth.js:273 ../js/ui/status/volume.js:59
#: ../js/ui/status/bluetooth.js:278 ../js/ui/status/volume.js:59
msgid "Sound Settings"
msgstr "Innstillinger for lyd"
#: ../js/ui/status/bluetooth.js:340
#: ../js/ui/status/bluetooth.js:345
#, c-format
msgid "Authorization request from %s"
msgstr "Forespørsel om autorisering fra %s"
#: ../js/ui/status/bluetooth.js:346
#: ../js/ui/status/bluetooth.js:351
#, c-format
msgid "Device %s wants access to the service '%s'"
msgstr "Enhet %s vil ha tilgang til tjenesten «%s»"
#: ../js/ui/status/bluetooth.js:348
#: ../js/ui/status/bluetooth.js:353
msgid "Always grant access"
msgstr "Alltid gi tilgang"
#: ../js/ui/status/bluetooth.js:349
#: ../js/ui/status/bluetooth.js:354
msgid "Grant this time only"
msgstr "Gi tilgang kun denne ene gangen"
#: ../js/ui/status/bluetooth.js:350 ../js/ui/telepathyClient.js:1097
#: ../js/ui/status/bluetooth.js:355 ../js/ui/telepathyClient.js:1097
msgid "Reject"
msgstr "Avvis"
#: ../js/ui/status/bluetooth.js:376
#: ../js/ui/status/bluetooth.js:381
#, c-format
msgid "Pairing confirmation for %s"
msgstr "Bekreftelse for tilkobling for %s"
#: ../js/ui/status/bluetooth.js:382 ../js/ui/status/bluetooth.js:412
#: ../js/ui/status/bluetooth.js:387 ../js/ui/status/bluetooth.js:417
#, c-format
msgid "Device %s wants to pair with this computer"
msgstr "Enhet %s vil koble seg sammen med denne datamaskinen"
#: ../js/ui/status/bluetooth.js:383
#: ../js/ui/status/bluetooth.js:388
#, c-format
msgid "Please confirm whether the PIN '%06d' matches the one on the device."
msgstr "Vennligst bekreft om PIN «%06d» er lik den som brukes på enheten."
#: ../js/ui/status/bluetooth.js:385
#: ../js/ui/status/bluetooth.js:390
msgid "Matches"
msgstr "Stemmer overens"
#: ../js/ui/status/bluetooth.js:386
#: ../js/ui/status/bluetooth.js:391
msgid "Does not match"
msgstr "Stemmer ikke overens"
#: ../js/ui/status/bluetooth.js:405
#: ../js/ui/status/bluetooth.js:410
#, c-format
msgid "Pairing request for %s"
msgstr "Forespørsel om tilkobling for %s"
#: ../js/ui/status/bluetooth.js:413
#: ../js/ui/status/bluetooth.js:418
msgid "Please enter the PIN mentioned on the device."
msgstr "Vennligst oppgi PIN som oppgitt på enheten."
#: ../js/ui/status/bluetooth.js:430
#: ../js/ui/status/bluetooth.js:435
msgid "OK"
msgstr "OK"
#: ../js/ui/status/keyboard.js:69
#: ../js/ui/status/keyboard.js:178
msgid "Show Keyboard Layout"
msgstr "Vis tastaturutforming"
#: ../js/ui/status/keyboard.js:71
#: ../js/ui/status/keyboard.js:180
msgid "Region and Language Settings"
msgstr "Innstillinger for region og språk"
@ -1169,19 +1169,19 @@ msgstr "VPN-tilkoblinger"
msgid "Network Settings"
msgstr "Innstillinger for nettverk"
#: ../js/ui/status/network.js:1703
#: ../js/ui/status/network.js:1712
msgid "Network Manager"
msgstr "Nettverkshåndtering"
#: ../js/ui/status/network.js:1796
#: ../js/ui/status/network.js:1805
msgid "Connection failed"
msgstr "Tilkobling feilet"
#: ../js/ui/status/network.js:1797
#: ../js/ui/status/network.js:1806
msgid "Activation of network connection failed"
msgstr "Aktivering av nettverkstilkobling feilet"
#: ../js/ui/status/network.js:2060
#: ../js/ui/status/network.js:2069
msgid "Networking is disabled"
msgstr "Nettverk er slått av"
@ -1195,11 +1195,11 @@ msgstr "Innstillinger for strøm"
#. 0 is reported when UPower does not have enough data
#. to estimate battery life
#: ../js/ui/status/power.js:98
#: ../js/ui/status/power.js:104
msgid "Estimating..."
msgstr "Estimerer …"
#: ../js/ui/status/power.js:105
#: ../js/ui/status/power.js:111
#, c-format
msgid "%d hour remaining"
msgid_plural "%d hours remaining"
@ -1207,77 +1207,77 @@ msgstr[0] "%d time gjenstår"
msgstr[1] "%d timer gjenstår"
#. TRANSLATORS: this is a time string, as in "%d hours %d minutes remaining"
#: ../js/ui/status/power.js:108
#: ../js/ui/status/power.js:114
#, c-format
msgid "%d %s %d %s remaining"
msgstr "%d %s %d %s gjenstår"
#: ../js/ui/status/power.js:110
#: ../js/ui/status/power.js:116
msgid "hour"
msgid_plural "hours"
msgstr[0] "time"
msgstr[1] "timer"
#: ../js/ui/status/power.js:110
#: ../js/ui/status/power.js:116
msgid "minute"
msgid_plural "minutes"
msgstr[0] "minutt"
msgstr[1] "minutter"
#: ../js/ui/status/power.js:113
#: ../js/ui/status/power.js:119
#, c-format
msgid "%d minute remaining"
msgid_plural "%d minutes remaining"
msgstr[0] "%d minutt gjenstår"
msgstr[1] "%d minutter gjenstår"
#: ../js/ui/status/power.js:116 ../js/ui/status/power.js:186
#: ../js/ui/status/power.js:122 ../js/ui/status/power.js:192
#, c-format
msgctxt "percent of battery remaining"
msgid "%d%%"
msgstr "%d%%"
#: ../js/ui/status/power.js:193
#: ../js/ui/status/power.js:199
msgid "AC adapter"
msgstr "Strømadapter"
#: ../js/ui/status/power.js:195
#: ../js/ui/status/power.js:201
msgid "Laptop battery"
msgstr "Batteri på bærbar"
#: ../js/ui/status/power.js:197
#: ../js/ui/status/power.js:203
msgid "UPS"
msgstr "UPS"
#: ../js/ui/status/power.js:199
#: ../js/ui/status/power.js:205
msgid "Monitor"
msgstr "Skjerm"
#: ../js/ui/status/power.js:201
#: ../js/ui/status/power.js:207
msgid "Mouse"
msgstr "Mus"
#: ../js/ui/status/power.js:205
#: ../js/ui/status/power.js:211
msgid "PDA"
msgstr "PDA"
#: ../js/ui/status/power.js:207
#: ../js/ui/status/power.js:213
msgid "Cell phone"
msgstr "Mobiltelefon"
#: ../js/ui/status/power.js:209
#: ../js/ui/status/power.js:215
msgid "Media player"
msgstr "Medieavspiller"
#: ../js/ui/status/power.js:211
#: ../js/ui/status/power.js:217
msgid "Tablet"
msgstr "Nettbrett"
#: ../js/ui/status/power.js:213
#: ../js/ui/status/power.js:219
msgid "Computer"
msgstr "Datamaskin"
#: ../js/ui/status/power.js:215
#: ../js/ui/status/power.js:221
msgctxt "device"
msgid "Unknown"
msgstr "Ukjent"
@ -1525,27 +1525,31 @@ msgstr "Rediger konto"
msgid "Unknown reason"
msgstr "Ukjent årsak"
#: ../js/ui/userMenu.js:130
#: ../js/ui/unlockDialog.js:129
msgid "Login as another user"
msgstr "Logg inn som en annen bruker"
#: ../js/ui/userMenu.js:161
msgid "Available"
msgstr "Tilgjengelig"
#: ../js/ui/userMenu.js:133
#: ../js/ui/userMenu.js:164
msgid "Busy"
msgstr "Opptatt"
#: ../js/ui/userMenu.js:136
#: ../js/ui/userMenu.js:167
msgid "Invisible"
msgstr "Usynlig"
#: ../js/ui/userMenu.js:139
#: ../js/ui/userMenu.js:170
msgid "Away"
msgstr "Borte"
#: ../js/ui/userMenu.js:142
#: ../js/ui/userMenu.js:173
msgid "Idle"
msgstr "Ledig"
#: ../js/ui/userMenu.js:145
#: ../js/ui/userMenu.js:176
msgid "Unavailable"
msgstr "Ikke tilgjengelig"
@ -1573,7 +1577,7 @@ msgstr "Logg ut"
msgid "Lock"
msgstr "Lås"
#: ../js/ui/userMenu.js:724
#: ../js/ui/userMenu.js:731
msgid "Install Updates & Restart"
msgstr "Installer oppdateringer og start på nytt"
@ -1598,7 +1602,7 @@ msgstr ""
msgid "Type to search..."
msgstr "Skriv for å søke …"
#: ../js/ui/viewSelector.js:131 ../src/shell-util.c:253
#: ../js/ui/viewSelector.js:131 ../src/shell-util.c:254
msgid "Search"
msgstr "Søk"
@ -1651,19 +1655,19 @@ msgstr[1] "%u innganger"
msgid "System Sounds"
msgstr "Systemlyder"
#: ../src/main.c:327
#: ../src/main.c:330
msgid "Print version"
msgstr "Skriv ut versjon"
#: ../src/main.c:333
#: ../src/main.c:336
msgid "Mode used by GDM for login screen"
msgstr "Modus som brukes av GDM for innloggingsskjermen"
#: ../src/main.c:339
#: ../src/main.c:342
msgid "Use a specific mode, e.g. \"gdm\" for login screen"
msgstr "Bruk spesifikt modus, f.eks «gdm» for innloggingsskjerm"
#: ../src/main.c:345
#: ../src/main.c:348
msgid "List possible modes"
msgstr "Vis mulige modi"
@ -1694,13 +1698,13 @@ msgstr "Autentiseringsdialogen ble lukket av brukeren"
#. Translators: this is the same string as the one found in
#. * nautilus
#: ../src/shell-util.c:97
#: ../src/shell-util.c:98
msgid "Home"
msgstr "Hjem"
#. Translators: this is the same string as the one found in
#. * nautilus
#: ../src/shell-util.c:107
#: ../src/shell-util.c:108
msgid "File System"
msgstr "Filsystem"
@ -1709,7 +1713,7 @@ msgstr "Filsystem"
#. * example, "Trash: some-directory". It means that the
#. * directory called "some-directory" is in the trash.
#.
#: ../src/shell-util.c:303
#: ../src/shell-util.c:304
#, c-format
msgid "%1$s: %2$s"
msgstr "%1$s: %2$s"

803
po/ru.po

File diff suppressed because it is too large Load Diff

551
po/sl.po

File diff suppressed because it is too large Load Diff

472
po/te.po

File diff suppressed because it is too large Load Diff

View File

@ -33,5 +33,5 @@ EXTRA_DIST += \
calendar-server/org.gnome.Shell.CalendarServer.service.in \
$(NULL)
CLEANFILES = \
CLEANFILES += \
$(desktop_DATA)

View File

@ -34,6 +34,7 @@ extern GType gnome_shell_plugin_get_type (void);
#define SHELL_DBUS_SERVICE "org.gnome.Shell"
#define MAGNIFIER_DBUS_SERVICE "org.gnome.Magnifier"
#define SCREENSAVER_DBUS_SERVICE "org.gnome.ScreenSaver"
#define OVERRIDES_SCHEMA "org.gnome.shell.overrides"
@ -152,6 +153,8 @@ shell_dbus_init (gboolean replace)
MAGNIFIER_DBUS_SERVICE, FALSE,
/* ...and the org.freedesktop.Notifications service. */
"org.freedesktop.Notifications", FALSE,
/* ...and the org.gnome.ScreenSaver service. */
SCREENSAVER_DBUS_SERVICE, FALSE,
NULL);
/* ...and the on-screen keyboard service */
shell_dbus_acquire_name (bus,

View File

@ -8,6 +8,7 @@
#include "shell-util.h"
#include <glib/gi18n-lib.h>
#include <gtk/gtk.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
#ifdef HAVE__NL_TIME_FIRST_WEEKDAY
#include <langinfo.h>
@ -818,3 +819,33 @@ shell_util_wifexited (int status,
return ret;
}
/**
* shell_util_create_pixbuf_from_data:
* @data: (array length=len) (element-type guint8) (transfer full):
* @len:
* @colorspace:
* @has_alpha:
* @bits_per_sample:
* @width:
* @height:
* @rowstride:
*
* Workaround for non-introspectability of gdk_pixbuf_from_data().
*
* Returns: (transfer full):
*/
GdkPixbuf *
shell_util_create_pixbuf_from_data (const guchar *data,
gsize len,
GdkColorspace colorspace,
gboolean has_alpha,
int bits_per_sample,
int width,
int height,
int rowstride)
{
return gdk_pixbuf_new_from_data (data, colorspace, has_alpha,
bits_per_sample, width, height, rowstride,
(GdkPixbufDestroyNotify) g_free, NULL);
}

View File

@ -6,6 +6,7 @@
#include <gio/gio.h>
#include <clutter/clutter.h>
#include <libsoup/soup.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
G_BEGIN_DECLS
@ -44,6 +45,14 @@ gboolean shell_session_is_active_for_systemd (void);
gboolean shell_util_wifexited (int status,
int *exit);
GdkPixbuf *shell_util_create_pixbuf_from_data (const guchar *data,
gsize len,
GdkColorspace colorspace,
gboolean has_alpha,
int bits_per_sample,
int width,
int height,
int rowstride);
G_END_DECLS

View File

@ -195,7 +195,8 @@ st_bin_navigate_focus (StWidget *widget,
StBinPrivate *priv = ST_BIN (widget)->priv;
ClutterActor *bin_actor = CLUTTER_ACTOR (widget);
if (st_widget_get_can_focus (widget))
if (clutter_actor_get_reactive (bin_actor) &&
st_widget_get_can_focus (widget))
{
if (from && clutter_actor_contains (bin_actor, from))
return FALSE;

View File

@ -285,7 +285,8 @@ st_entry_navigate_focus (StWidget *widget,
if (from == priv->entry)
return FALSE;
else if (st_widget_get_can_focus (widget))
else if (clutter_actor_get_reactive (CLUTTER_ACTOR (widget)) &&
st_widget_get_can_focus (widget))
{
clutter_actor_grab_key_focus (priv->entry);
return TRUE;

View File

@ -591,6 +591,8 @@ stop_scrolling (StScrollBar *bar)
if (!bar->priv->capture_handler)
return;
st_widget_remove_style_pseudo_class (ST_WIDGET (bar->priv->handle), "active");
stage = CLUTTER_STAGE (clutter_actor_get_stage (bar->priv->trough));
g_signal_handler_disconnect (stage, bar->priv->capture_handler);
bar->priv->capture_handler = 0;
@ -651,6 +653,8 @@ handle_button_press_event_cb (ClutterActor *actor,
&priv->y_origin))
return FALSE;
st_widget_add_style_pseudo_class (ST_WIDGET (priv->handle), "active");
/* Account for the scrollbar-trough-handle nesting. */
priv->x_origin += clutter_actor_get_x (priv->trough);
priv->y_origin += clutter_actor_get_y (priv->trough);

View File

@ -457,11 +457,12 @@ get_background_coordinates (StThemeNode *node,
static void
get_background_position (StThemeNode *self,
const ClutterActorBox *allocation,
ClutterActorBox *result)
ClutterActorBox *result,
ClutterActorBox *texture_coords)
{
gdouble painting_area_width, painting_area_height;
gdouble background_image_width, background_image_height;
gdouble x, y;
gdouble x1, y1;
gdouble scale_w, scale_h;
/* get the background image size */
@ -484,13 +485,31 @@ get_background_position (StThemeNode *self,
get_background_coordinates (self,
painting_area_width, painting_area_height,
background_image_width, background_image_height,
&x, &y);
&x1, &y1);
/* place the background image */
result->x1 = x;
result->y1 = y;
result->x2 = result->x1 + background_image_width;
result->y2 = result->y1 + background_image_height;
if (self->background_repeat)
{
gdouble width = allocation->x2 - allocation->x1 + x1;
gdouble height = allocation->y2 - allocation->y1 + y1;
*result = *allocation;
/* reference image is at x1, y1 */
texture_coords->x1 = x1 / background_image_width;
texture_coords->y1 = y1 / background_image_height;
texture_coords->x2 = width / background_image_width;
texture_coords->y2 = height / background_image_height;
}
else
{
result->x1 = x1;
result->y1 = y1;
result->x2 = x1 + background_image_width;
result->y2 = y1 + background_image_height;
texture_coords->x1 = texture_coords->y1 = 0;
texture_coords->x2 = texture_coords->y2 = 1;
}
}
/* Use of this function marks code which doesn't support
@ -614,15 +633,21 @@ create_cairo_pattern_of_background_image (StThemeNode *node,
&x, &y);
cairo_matrix_translate (&matrix, -x, -y);
if (node->background_repeat)
cairo_pattern_set_extend (pattern, CAIRO_EXTEND_REPEAT);
/* If it's opaque, fills up the entire allocated
* area, then don't bother doing a background fill first
*/
if (content != CAIRO_CONTENT_COLOR_ALPHA
&& x >= 0
&& -x + background_image_width >= node->alloc_width
&& y >= 0
&& -y + background_image_height >= node->alloc_height)
*needs_background_fill = FALSE;
if (content != CAIRO_CONTENT_COLOR_ALPHA)
{
if (node->background_repeat ||
(x >= 0 &&
y >= 0 &&
background_image_width - x >= node->alloc_width &&
background_image_height -y >= node->alloc_height))
*needs_background_fill = FALSE;
}
cairo_pattern_set_matrix (pattern, &matrix);
@ -1444,6 +1469,9 @@ st_theme_node_render_resources (StThemeNode *node,
node->background_texture = st_texture_cache_load_file_to_cogl_texture (texture_cache, background_image);
node->background_material = _st_create_texture_material (node->background_texture);
if (node->background_repeat)
cogl_material_set_layer_wrap_mode (node->background_material, 0, COGL_MATERIAL_WRAP_MODE_REPEAT);
if (background_image_shadow_spec)
{
node->background_shadow_material = _st_create_shadow_material (background_image_shadow_spec,
@ -1464,20 +1492,25 @@ st_theme_node_render_resources (StThemeNode *node,
static void
paint_material_with_opacity (CoglHandle material,
ClutterActorBox *box,
ClutterActorBox *coords,
guint8 paint_opacity)
{
cogl_material_set_color4ub (material,
paint_opacity, paint_opacity, paint_opacity, paint_opacity);
cogl_set_source (material);
cogl_rectangle (box->x1, box->y1, box->x2, box->y2);
if (coords)
cogl_rectangle_with_texture_coords (box->x1, box->y1, box->x2, box->y2,
coords->x1, coords->y1, coords->x2, coords->y2);
else
cogl_rectangle (box->x1, box->y1, box->x2, box->y2);
}
static void
st_theme_node_paint_borders (StThemeNode *node,
const ClutterActorBox *box,
guint8 paint_opacity)
{
float width, height;
int border_width[4];
@ -1948,6 +1981,7 @@ st_theme_node_paint (StThemeNode *node,
paint_material_with_opacity (node->prerendered_material,
&paint_box,
NULL,
paint_opacity);
}
@ -1964,17 +1998,18 @@ st_theme_node_paint (StThemeNode *node,
if (node->background_texture != COGL_INVALID_HANDLE)
{
ClutterActorBox background_box;
ClutterActorBox texture_coords;
gboolean has_visible_outline;
/* If the background doesn't have a border or opaque background,
* then we let its background image shadows leak out, but other
* wise we clip it.
/* If the node doesn't have an opaque or repeating background or
* a border then we let its background image shadows leak out,
* but otherwise we clip it.
*/
has_visible_outline = st_theme_node_has_visible_outline (node);
get_background_position (node, &allocation, &background_box);
get_background_position (node, &allocation, &background_box, &texture_coords);
if (has_visible_outline)
if (has_visible_outline || node->background_repeat)
cogl_clip_push_rectangle (allocation.x1, allocation.y1, allocation.x2, allocation.y2);
/* CSS based drop shadows
@ -1996,9 +2031,12 @@ st_theme_node_paint (StThemeNode *node,
&background_box,
paint_opacity);
paint_material_with_opacity (node->background_material, &background_box, paint_opacity);
paint_material_with_opacity (node->background_material,
&background_box,
&texture_coords,
paint_opacity);
if (has_visible_outline)
if (has_visible_outline || node->background_repeat)
cogl_clip_pop ();
}
}

View File

@ -45,7 +45,7 @@ struct _StThemeNode {
int background_position_x;
int background_position_y;
gboolean background_position_set : 1;
StBackgroundSize background_size;
gint background_size_w;
gint background_size_h;
@ -87,6 +87,9 @@ struct _StThemeNode {
/* We hold onto these separately so we can destroy them on finalize */
CRDeclaration *inline_properties;
guint background_position_set : 1;
guint background_repeat : 1;
guint properties_computed : 1;
guint geometry_computed : 1;
guint background_computed : 1;

View File

@ -1569,6 +1569,7 @@ _st_theme_node_ensure_background (StThemeNode *node)
if (node->background_computed)
return;
node->background_repeat = FALSE;
node->background_computed = TRUE;
node->background_color = TRANSPARENT_COLOR;
node->background_gradient_type = ST_GRADIENT_NONE;
@ -1647,8 +1648,8 @@ _st_theme_node_ensure_background (StThemeNode *node)
}
else
node->background_position_set = TRUE;
result = get_length_from_term_int (node, decl->value->next, FALSE, &node->background_position_y);
result = get_length_from_term_int (node, decl->value->next, FALSE, &node->background_position_y);
if (result == VALUE_NOT_FOUND)
{
@ -1658,6 +1659,14 @@ _st_theme_node_ensure_background (StThemeNode *node)
else
node->background_position_set = TRUE;
}
else if (strcmp (property_name, "-repeat") == 0)
{
if (decl->value->type == TERM_IDENT)
{
if (strcmp (decl->value->content.str->stryng->str, "repeat") == 0)
node->background_repeat = TRUE;
}
}
else if (strcmp (property_name, "-size") == 0)
{
if (decl->value->type == TERM_IDENT)

View File

@ -176,6 +176,9 @@ parse_stylesheet (const char *filename,
return NULL;
}
/* Extension stylesheet */
stylesheet->app_data = GUINT_TO_POINTER (FALSE);
return stylesheet;
}
@ -230,6 +233,8 @@ st_theme_load_stylesheet (StTheme *theme,
if (!stylesheet)
return FALSE;
stylesheet->app_data = GUINT_TO_POINTER (TRUE);
insert_stylesheet (theme, path, stylesheet);
cr_stylesheet_ref (stylesheet);
theme->custom_stylesheets = g_slist_prepend (theme->custom_stylesheets, stylesheet);
@ -958,6 +963,7 @@ compare_declarations (gconstpointer a,
/* g_ptr_array_sort() is broooken */
CRDeclaration *decl_a = *(CRDeclaration **) a;
CRDeclaration *decl_b = *(CRDeclaration **) b;
gboolean a_is_extension_sheet, b_is_extension_sheet;
int origin_a = get_origin (decl_a);
int origin_b = get_origin (decl_b);
@ -968,6 +974,12 @@ compare_declarations (gconstpointer a,
if (decl_a->parent_statement->specificity != decl_b->parent_statement->specificity)
return decl_a->parent_statement->specificity - decl_b->parent_statement->specificity;
a_is_extension_sheet = GPOINTER_TO_UINT (decl_a->parent_statement->parent_sheet->app_data);
b_is_extension_sheet = GPOINTER_TO_UINT (decl_b->parent_statement->parent_sheet->app_data);
if (a_is_extension_sheet != b_is_extension_sheet)
return a_is_extension_sheet ? 1 : -1;
return 0;
}

View File

@ -1404,6 +1404,17 @@ st_widget_name_notify (StWidget *widget,
st_widget_style_changed (widget);
}
static void
st_widget_reactive_notify (StWidget *widget,
GParamSpec *pspec,
gpointer data)
{
if (clutter_actor_get_reactive (CLUTTER_ACTOR (widget)))
st_widget_remove_style_pseudo_class (widget, "insensitive");
else
st_widget_add_style_pseudo_class (widget, "insensitive");
}
static void
st_widget_first_child_notify (StWidget *widget,
GParamSpec *pspec,
@ -1466,6 +1477,7 @@ st_widget_init (StWidget *actor)
/* connect style changed */
g_signal_connect (actor, "notify::name", G_CALLBACK (st_widget_name_notify), NULL);
g_signal_connect (actor, "notify::reactive", G_CALLBACK (st_widget_reactive_notify), NULL);
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);
@ -1880,7 +1892,8 @@ st_widget_real_navigate_focus (StWidget *widget,
while (focus_child && clutter_actor_get_parent (focus_child) != widget_actor)
focus_child = clutter_actor_get_parent (focus_child);
if (widget->priv->can_focus)
if (clutter_actor_get_reactive (widget_actor) &&
widget->priv->can_focus)
{
if (!focus_child)
{

View File

@ -2,6 +2,7 @@ noinst_SCRIPTS = run-test.sh
EXTRA_DIST = run-test.sh.in
TEST_JS = \
interactive/background-repeat.js \
interactive/background-size.js \
interactive/borders.js \
interactive/border-radius.js \

View File

@ -0,0 +1,29 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Clutter = imports.gi.Clutter;
const St = imports.gi.St;
const UI = imports.testcommon.ui;
function test() {
let stage = new Clutter.Stage({ width: 640, height: 480 });
UI.init(stage);
let vbox = new St.BoxLayout({ width: stage.width,
height: stage.height,
style: 'background: #ffee88;' });
stage.add_actor(vbox);
let scroll = new St.ScrollView();
vbox.add(scroll, { expand: true });
let box = new St.BoxLayout({ vertical: true });
scroll.add_actor(box);
let contents = new St.Widget({ width: 1000, height: 1000,
style_class: 'background-image background-repeat' });
box.add_actor(contents);
UI.main(stage);
}
test();

View File

@ -84,7 +84,6 @@ function test() {
function addGradientCase(direction, borderWidth, borderRadius, extra) {
let gradientBox = new St.BoxLayout({ style_class: 'background-gradient',
style: 'border: ' + borderWidth + 'px solid #8b0000;'
>>>>>>> 2aff593... tests: Run each test in a function
+ 'border-radius: ' + borderRadius + 'px;'
+ 'background-gradient-direction: ' + direction + ';'
+ 'width: 32px;'

View File

@ -67,6 +67,10 @@ stage {
background-color: white;
}
.background-repeat {
background-repeat: repeat;
}
.push-button {
background: #eeddbb;
border: 1px solid black;