Compare commits

..

4 Commits

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

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

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

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

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

https://bugzilla.gnome.org/show_bug.cgi?id=697007
2013-04-05 18:12:47 +02:00
142 changed files with 7426 additions and 13102 deletions

105
NEWS
View File

@ -1,108 +1,3 @@
3.9.2
=====
* Use a symbolic icon for DESKTOP windows [Matthias; #697914]
* Move paint state cache into StWidget [Jasper; #697274]
* gdm: Fix regression where domain login hint not shown [Stef; #698200]
* Make calendar keyboard navigable [Tanner; #667434]
* Hide "Open Calendar" item when no calendar app is installed [Lionel; #697725]
* Update how branding appears on login screen [Florian; #694912, #699877]
* Allow OSD popups to grow if necessary [Marta; #696523]
* Fix offset of shadow offscreen rendering [Lionel; #698301]
* Fix insensitive button preventing empty keyring password [Stef; #696304]
* Allow cancelling keyring dialog between prompts [Stef; #682830]
* modalDialog: Show spinner while working [Stef; #684438]
* overview: Only show close buttons for windows that may close [Jasper; #699269]
* Add input purpose and hints to StEntry and StIMText [Daiki; #691392]
* Set input-purpose property for password entries [Rui; #700043]
* Provide a DBus API for screencasting [Florian; #696247]
* overview: Disable hotcorner during DND [Jasper; #698484]
* polkitAgent: Allow retrying after mistyped passwords [Stef; #684431]
* Add a way to get backtraces from criticals and warnings [Giovanni; #700262]
* Allow switch-to-workspace-n keybindings in overview [Florian; #649977]
* Update man page [Matthias; #700339]
* Add FocusSearch DBus method [Florian; #700536]
* Hide frequent view when app monitoring is disabled [Florian; #699714]
* Show switcher popup for switch-to-workspace-n keybindings [Elad; #659288]
* gdm: Update the session chooser style [Allan; #695742]
* Fix some app folders getting truncated at the top [Florian; #694371]
* Don't block the message tray while a notification is showing [Jasper; #700639]
* popupMenu: Allow for an optional border for slider handle [Florian; #697917]
* Re-lock screen when restarted after a crash [Colin; #691987]
* Synchronize input source switching with key events [Rui; #697007]
* Switch input source on modifiers-only accelerator [Rui; #697008]
* Allow input source switching in message tray [Rui; #697009]
* Misc bug fixes and cleanups [Alban, Jasper, Giovanni, Florian, Rui, Tomeu,
Stef, Gustavo; #698863, #699799, #699800, #676285, #699975, #700097, #698812,
#698486, #700194, #695314, #700257, #699678, #700356, #700322, #700394,
#700409, #700595, #700625, #691746, #700620, #700807, #659288, #700784,
#700842, #700847, #700488, #700735, #696159, #700900, #700853, #700923,
#700944, #697661, #700854, #700190, #699189, #701097]
Contributors:
Elad Alfassa, Alban Browaeys, Giovanni Campagna, Matthias Clasen, Allan Day,
Tanner Doshier, Lionel Landwerlin, Rui Matos, Simon McVittie,
Marta Milakovic, Florian Müllner, Gustavo Padovan, Jasper St. Pierre,
Daiki Ueno, Tomeu Vizoso, Stef Walter, Colin Walters
Translations:
Matej Urbančič [sl], Kjartan Maraas [nb], Victor Ibragimov [tg],
Dušan Kazik [sk], Gil Forcada [ca], Daniel Mustieles [es]
3.9.1
=====
* Add additional toggle-overview keybinding [Matthias; #698251]
* Disable <super> shortcut when sticky keys are enabled [Matthias; #685974]
* Disable tray context menu while a notification displays [Jasper; #695800]
* Watch GApplication busy state [Cosimo; #697207]
* Disable style transitions if animations are disabled [Jasper; #698391]
* Filter out hidden applications from "Frequent" view [Giovanni; #696949]
* Fix window previews swapping place randomly [Jasper; #694469, #698776]
* Add support for serialized GIcons in remote search providers [Cosimo; #698761]
* Fix hotcorner regression in RTL locales [Jasper; #698884]
* Allow some keybindings to work while a top bar menu is open [Florian; #698938]
* Make open-app-menu keybinding a toggle action [Florian; #686756]
* Only recognize common URL schemes in notification messages [Monica; #661225]
* Misc fixes and cleanups [Tim, Jasper, Florian, Giovanni, Owen; #698531,
#698622, #698427, #698483, #698513, #697203, #698959, #698918, #699029,
#699075, #696720, #649748]
Contributors:
Giovanni Campagna, Cosimo Cecchi, Monica Chelliah, Matthias Clasen, Tim Lunn,
Florian Müllner, Jasper St. Pierre, Michael Wood, Owen W. Taylor
Translations:
Fran Diéguez [gl], Muhammet Kara [tr], Daniel Mustieles [es],
Gil Forcada [ia], Anish A [ml], Dimitris Spingos [el], Marek Černocký [cs],
Žygimantas Beručka [lt]
3.8.1
=====
* Clip window group during startup animation [Jasper; #696323]
* Check for logind rather than systemd [Martin; #696252]
* Don't special-case last remote search provider position [Giovanni; #694974]
* Fix memory leaks [Ray, Jasper; ##697119, #697295, #697300, #697395]
* AppSwitcherPopup: Activate only the selected window if any [Rui; #697480]
* Enable screen recorder keybinding in all modes [Florian; #696200]
* Remove box-shadow from screen shield for performance reasons [Adel; #697274]
* Add support for -st-natural-width/height CSS properties [Giovanni; #664411]
* Remove excessive padding from notification buttons [Allan; #664411]
* Fix thumbnail dragging in overview [Jasper; #697504]
* theme-node: Add get_url()/lookup_url() methods [Florian; #693688]
* Misc bug fixes and cleanups [Jasper, Rui, Colin, David, Ray, Matthias:
#695859, #696259, #696585, #696436, #697432, #697435, #697560, #697722,
#697709]
Contributors:
Giovanni Campagna, Matthias Clasen, Allan Day, Adel Gadllah, David Gumberg,
Rui Matos, Florian Müllner, Martin Pitt, Jasper St. Pierre, Ray Strode,
Colin Walters
Translations:
Daniel Martinez [an], Bruce Cowan [en_GB], Khaled Hosny [ar],
Ihar Hrachyshka [be], Aron Xu [zh_CN], Wojciech Szczęsny [pl],
Inaki Larranaga Murgoitio [eu], Kjartan Maraas [nb],
Милош Поповић [sr, sr@latin], Trần Ngọc Quân [vi]
3.8.0.1 3.8.0.1
======= =======
* Background bug fixes [Ray; #696712] * Background bug fixes [Ray; #696712]

View File

@ -1,5 +1,5 @@
AC_PREREQ(2.63) AC_PREREQ(2.63)
AC_INIT([gnome-shell],[3.9.2],[https://bugzilla.gnome.org/enter_bug.cgi?product=gnome-shell],[gnome-shell]) AC_INIT([gnome-shell],[3.8.0.1],[https://bugzilla.gnome.org/enter_bug.cgi?product=gnome-shell],[gnome-shell])
AC_CONFIG_HEADERS([config.h]) AC_CONFIG_HEADERS([config.h])
AC_CONFIG_SRCDIR([src/shell-global.c]) AC_CONFIG_SRCDIR([src/shell-global.c])
@ -63,9 +63,9 @@ AM_CONDITIONAL(BUILD_RECORDER, $build_recorder)
CLUTTER_MIN_VERSION=1.13.4 CLUTTER_MIN_VERSION=1.13.4
GOBJECT_INTROSPECTION_MIN_VERSION=0.10.1 GOBJECT_INTROSPECTION_MIN_VERSION=0.10.1
GJS_MIN_VERSION=1.35.4 GJS_MIN_VERSION=1.35.4
MUTTER_MIN_VERSION=3.9.2 MUTTER_MIN_VERSION=3.8.0
GTK_MIN_VERSION=3.7.9 GTK_MIN_VERSION=3.7.9
GIO_MIN_VERSION=2.37.0 GIO_MIN_VERSION=2.35.0
LIBECAL_MIN_VERSION=3.5.3 LIBECAL_MIN_VERSION=3.5.3
LIBEDATASERVER_MIN_VERSION=3.5.3 LIBEDATASERVER_MIN_VERSION=3.5.3
TELEPATHY_GLIB_MIN_VERSION=0.17.5 TELEPATHY_GLIB_MIN_VERSION=0.17.5
@ -74,7 +74,7 @@ STARTUP_NOTIFICATION_MIN_VERSION=0.11
GCR_MIN_VERSION=3.3.90 GCR_MIN_VERSION=3.3.90
GNOME_DESKTOP_REQUIRED_VERSION=3.7.90 GNOME_DESKTOP_REQUIRED_VERSION=3.7.90
GNOME_MENUS_REQUIRED_VERSION=3.5.3 GNOME_MENUS_REQUIRED_VERSION=3.5.3
NETWORKMANAGER_MIN_VERSION=0.9.8 NETWORKMANAGER_MIN_VERSION=0.9.6
PULSE_MIN_VERS=2.0 PULSE_MIN_VERS=2.0
# Collect more than 20 libraries for a prize! # Collect more than 20 libraries for a prize!
@ -96,7 +96,7 @@ PKG_CHECK_MODULES(GNOME_SHELL, gio-unix-2.0 >= $GIO_MIN_VERSION
polkit-agent-1 >= $POLKIT_MIN_VERSION xfixes polkit-agent-1 >= $POLKIT_MIN_VERSION xfixes
libnm-glib libnm-util >= $NETWORKMANAGER_MIN_VERSION libnm-glib libnm-util >= $NETWORKMANAGER_MIN_VERSION
libnm-gtk >= $NETWORKMANAGER_MIN_VERSION libnm-gtk >= $NETWORKMANAGER_MIN_VERSION
libsecret-unstable gcr-base-3 >= $GCR_MIN_VERSION) libsecret-unstable gcr-3 >= $GCR_MIN_VERSION)
PKG_CHECK_MODULES(GNOME_SHELL_JS, gio-2.0 gjs-internals-1.0 >= $GJS_MIN_VERSION) PKG_CHECK_MODULES(GNOME_SHELL_JS, gio-2.0 gjs-internals-1.0 >= $GJS_MIN_VERSION)
PKG_CHECK_MODULES(ST, clutter-1.0 gtk+-3.0 libcroco-0.6 >= 0.6.8 x11) PKG_CHECK_MODULES(ST, clutter-1.0 gtk+-3.0 libcroco-0.6 >= 0.6.8 x11)

View File

@ -11,9 +11,6 @@
<KeyListEntry name="focus-active-notification" <KeyListEntry name="focus-active-notification"
_description="Focus the active notification"/> _description="Focus the active notification"/>
<KeyListEntry name="toggle-overview"
_description="Show the overview"/>
<KeyListEntry name="toggle-application-view" <KeyListEntry name="toggle-application-view"
_description="Show all applications"/> _description="Show all applications"/>

View File

@ -15,7 +15,6 @@ desktop_DATA = gnome-shell.desktop gnome-shell-extension-prefs.desktop
introspectiondir = $(datadir)/dbus-1/interfaces introspectiondir = $(datadir)/dbus-1/interfaces
introspection_DATA = \ introspection_DATA = \
org.gnome.Shell.Screencast.xml \
org.gnome.Shell.Screenshot.xml \ org.gnome.Shell.Screenshot.xml \
org.gnome.ShellSearchProvider.xml \ org.gnome.ShellSearchProvider.xml \
org.gnome.ShellSearchProvider2.xml org.gnome.ShellSearchProvider2.xml

View File

@ -1,96 +0,0 @@
<!DOCTYPE node PUBLIC
'-//freedesktop//DTD D-BUS Object Introspection 1.0//EN'
'http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd'>
<node>
<!--
org.gnome.Shell.Screencast:
@short_description: Screencast interface
The interface used to record screen contents.
-->
<interface name="org.gnome.Shell.Screencast">
<!--
Screencast:
@file_template: the template for the filename to use
@options: a dictionary of optional parameters
@success: whether the screencast was started successfully
@filename_used: the file where the screencast is being saved
Records a screencast of the whole screen and saves it
(by default) as webm video under a filename derived from
@file_template. The template is either a relative or absolute
filename which may contain some escape sequences - %d and %t
will be replaced by the start date and time of the recording.
If a relative name is used, the screencast will be saved in the
$XDG_VIDEOS_DIR if it exists, or the home directory otherwise.
The actual filename of the saved video is returned in @filename_used.
The set of optional parameters in @options currently consists of:
'draw-cursor'(b): whether the cursor should be included in the
recording (true)
'framerate'(i): the number of frames per second that should be
recorded if possible (30)
'pipeline'(s): the GStreamer pipeline used to encode recordings
in gst-launch format; if not specified, the
recorder will produce vp8 (webm) video (unset)
-->
<method name="Screencast">
<arg type="s" direction="in" name="file_template"/>
<arg type="a{sv}" direction="in" name="options"/>
<arg type="b" direction="in" name="flash"/>
<arg type="b" direction="out" name="success"/>
<arg type="s" direction="out" name="filename_used"/>
</method>
<!--
ScreencastArea:
@x: the X coordinate of the area to capture
@y: the Y coordinate of the area to capture
@width: the width of the area to capture
@height: the height of the area to capture
@file_template: the template for the filename to use
@options: a dictionary of optional parameters
@success: whether the screencast was started successfully
@filename_used: the file where the screencast is being saved
Records a screencast of the passed in area and saves it
(by default) as webm video under a filename derived from
@file_template. The template is either a relative or absolute
filename which may contain some escape sequences - %d and %t
will be replaced by the start date and time of the recording.
If a relative name is used, the screencast will be saved in the
$XDG_VIDEOS_DIR if it exists, or the home directory otherwise.
The actual filename of the saved video is returned in @filename_used.
The set of optional parameters in @options currently consists of:
'draw-cursor'(b): whether the cursor should be included in the
recording (true)
'framerate'(i): the number of frames per second that should be
recorded if possible (30)
'pipeline'(s): the GStreamer pipeline used to encode recordings
in gst-launch format; if not specified, the
recorder will produce vp8 (webm) video (unset)
-->
<method name="ScreencastArea">
<arg type="i" direction="in" name="x"/>
<arg type="i" direction="in" name="y"/>
<arg type="i" direction="in" name="width"/>
<arg type="i" direction="in" name="height"/>
<arg type="s" direction="in" name="file_template"/>
<arg type="a{sv}" direction="in" name="options"/>
<arg type="b" direction="out" name="success"/>
<arg type="s" direction="out" name="filename_used"/>
</method>
<!--
StopScreencast:
@success: whether stopping the recording was successful
Stop the recording started by either Screencast or ScreencastArea.
-->
<method name="StopScreencast">
<arg type="b" direction="out" name="success"/>
</method>
</interface>
</node>

View File

@ -46,7 +46,7 @@
<!-- <!--
GetResultMetas: GetResultMetas:
@identifiers: An array of result identifiers as returned by GetInitialResultSet() or GetSubsearchResultSet() @identifiers: An array of result identifiers as returned by GetInitialResultSet() or GetSubsearchResultSet()
@metas: A dictionary describing the given search result, containing a human-readable 'name' (string), along with the result identifier this meta is for, 'id' (string). Optionally, 'icon' (a serialized GIcon as obtained by g_icon_serialize) can be specified if the result can be better served with a thumbnail of the content (such as with images). 'gicon' (a serialized GIcon as obtained by g_icon_to_string) or 'icon-data' (raw image data as (iiibiiay) - width, height, rowstride, has-alpha, bits per sample, channels, data) are deprecated values that can also be used for that purpose. A 'description' field (string) may also be specified if more context would help the user find the desired result. @metas: A dictionary describing the given search result, containing a human-readable 'name' (string), along with the result identifier this meta is for, 'id' (string). Optionally, either 'gicon' (a serialized GIcon) or 'icon-data' (raw image data as (iiibiiay) - width, height, rowstride, has-alpha, bits per sample, channels, data) can be specified if the result can be better served with a thumbnail of the content (such as with images). A 'description' field (string) may also be specified if more context would help the user find the desired result.
Return an array of meta data used to display each given result Return an array of meta data used to display each given result
--> -->

View File

@ -21,6 +21,16 @@
EnableExtension and DisableExtension DBus methods on org.gnome.Shell. EnableExtension and DisableExtension DBus methods on org.gnome.Shell.
</_description> </_description>
</key> </key>
<key name="enable-app-monitoring" type="b">
<default>true</default>
<_summary>Whether to collect stats about applications usage</_summary>
<_description>
The shell normally monitors active applications in order to present
the most used ones (e.g. in launchers). While this data will be
kept private, you may want to disable this for privacy reasons.
Please note that doing so won't remove already saved data.
</_description>
</key>
<key name="favorite-apps" type="as"> <key name="favorite-apps" type="as">
<default>[ 'epiphany.desktop', 'evolution.desktop', 'empathy.desktop', 'rhythmbox.desktop', 'shotwell.desktop', 'libreoffice-writer.desktop', 'nautilus.desktop', 'gnome-documents.desktop' ]</default> <default>[ 'epiphany.desktop', 'evolution.desktop', 'empathy.desktop', 'rhythmbox.desktop', 'shotwell.desktop', 'libreoffice-writer.desktop', 'nautilus.desktop', 'gnome-documents.desktop' ]</default>
<_summary>List of desktop file IDs for favorite applications</_summary> <_summary>List of desktop file IDs for favorite applications</_summary>
@ -107,13 +117,6 @@ value here is from the GsmPresenceStatus enumeration.</_summary>
Overview. Overview.
</_description> </_description>
</key> </key>
<key name="toggle-overview" type="as">
<default>["&lt;Super&gt;s"]</default>
<_summary>Keybinding to open the overview</_summary>
<_description>
Keybinding to open the Activities Overview.
</_description>
</key>
<key name="toggle-message-tray" type="as"> <key name="toggle-message-tray" type="as">
<default>["&lt;Super&gt;m"]</default> <default>["&lt;Super&gt;m"]</default>
<_summary>Keybinding to toggle the visibility of the message tray</_summary> <_summary>Keybinding to toggle the visibility of the message tray</_summary>

View File

@ -125,10 +125,6 @@ StScrollBar StButton#vhandle:active {
/* PopupMenu */ /* PopupMenu */
.popup-menu-ornament {
text-align: center;
}
.popup-menu-boxpointer, .popup-menu-boxpointer,
.candidate-popup-boxpointer { .candidate-popup-boxpointer {
-arrow-border-radius: 8px; -arrow-border-radius: 8px;
@ -381,7 +377,6 @@ StScrollBar StButton#vhandle:active {
/* Entries */ /* Entries */
#searchEntry, #searchEntry,
.login-dialog StEntry,
.notification StEntry, .notification StEntry,
.modal-dialog StEntry { .modal-dialog StEntry {
color: rgb(64, 64, 64); color: rgb(64, 64, 64);
@ -393,7 +388,6 @@ StScrollBar StButton#vhandle:active {
} }
#searchEntry, #searchEntry,
.login-dialog StEntry,
.run-dialog-entry, .run-dialog-entry,
.notification StEntry { .notification StEntry {
border: 2px solid rgba(245,245,245,0.2); border: 2px solid rgba(245,245,245,0.2);
@ -406,7 +400,6 @@ StScrollBar StButton#vhandle:active {
#searchEntry:focus, #searchEntry:focus,
#searchEntry:hover, #searchEntry:hover,
.login-dialog StEntry:focus,
.notification StEntry:focus, .notification StEntry:focus,
.modal-dialog StEntry { .modal-dialog StEntry {
border: 2px solid rgb(136,138,133); border: 2px solid rgb(136,138,133);
@ -416,7 +409,6 @@ StScrollBar StButton#vhandle:active {
box-shadow: inset 0px 2px 4px rgba(0,0,0,0.6); box-shadow: inset 0px 2px 4px rgba(0,0,0,0.6);
} }
.login-dialog StEntry:focus,
.notification StEntry:focus, .notification StEntry:focus,
.modal-dialog StEntry:focus { .modal-dialog StEntry:focus {
border: 2px solid #3465a4; border: 2px solid #3465a4;
@ -440,7 +432,6 @@ StScrollBar StButton#vhandle:active {
transition-duration: 0ms; transition-duration: 0ms;
} }
.login-dialog StEntry,
.notification StEntry, .notification StEntry,
.modal-dialog StEntry { .modal-dialog StEntry {
border-radius: 5px; border-radius: 5px;
@ -454,7 +445,6 @@ StScrollBar StButton#vhandle:active {
padding: 0 4px; padding: 0 4px;
} }
.login-dialog StEntry:insensitive,
.modal-dialog StEntry:insensitive { .modal-dialog StEntry:insensitive {
border-color: #666666; border-color: #666666;
color: #9f9f9f; color: #9f9f9f;
@ -522,7 +512,6 @@ StScrollBar StButton#vhandle:active {
} }
#appMenu { #appMenu {
spinner-image: url("process-working.svg");
spacing: 4px; spacing: 4px;
} }
@ -1194,8 +1183,7 @@ StScrollBar StButton#vhandle:active {
background-image: url("calendar-arrow-right.svg"); background-image: url("calendar-arrow-right.svg");
} }
.calendar-change-month-back:hover, .calendar-change-month-back:hover {
.calendar-change-month-back:focus {
background-color: #999999; background-color: #999999;
} }
.calendar-change-month-back:active { .calendar-change-month-back:active {
@ -1213,8 +1201,7 @@ StScrollBar StButton#vhandle:active {
background-image: url("calendar-arrow-left.svg"); background-image: url("calendar-arrow-left.svg");
} }
.calendar-change-month-forward:hover, .calendar-change-month-forward:hover {
.calendar-change-month-forward:focus {
background-color: #999999; background-color: #999999;
} }
.calendar-change-month-forward:active { .calendar-change-month-forward:active {
@ -1235,8 +1222,7 @@ StScrollBar StButton#vhandle:active {
height: 2.4em; height: 2.4em;
} }
.calendar-day-base:hover, .calendar-day-base:hover {
.calendar-day-base:focus {
background-color: #777777; background-color: #777777;
} }
@ -1467,13 +1453,11 @@ StScrollBar StButton#vhandle:active {
} }
.notification-button { .notification-button {
-st-natural-width: 140px; padding: 4px 42px 5px;
padding: 4px 4px 5px;
} }
.notification-button:focus { .notification-button:focus {
-st-natural-width: 138px; padding: 3px 41px 4px;
padding: 3px 4px 4px;
} }
.notification-icon-button { .notification-icon-button {
@ -2240,13 +2224,8 @@ StScrollBar StButton#vhandle:active {
min-width: 350px; min-width: 350px;
} }
.login-dialog-button-box {
spacing: 21px;
}
.login-dialog-prompt-login-hint-message { .login-dialog-prompt-login-hint-message {
font-size: 10.5pt; font-size: 10.5pt;
min-width: 480px;
} }
.login-dialog-user-list-view { .login-dialog-user-list-view {
@ -2353,50 +2332,55 @@ StScrollBar StButton#vhandle:active {
} }
.login-dialog-prompt-entry { .login-dialog-prompt-entry {
width: 480px; width: 15em;
} }
.login-dialog-session-list, .login-dialog-session-list {
.login-dialog-session-list-item { color: #ffffff;
color: #babdb6; font-size: 10.5pt;
}
.login-dialog-session-list-button:focus,
.login-dialog-session-list-button:active,
.login-dialog-session-list-button:hover,
.login-dialog-session-list-item:focus,
.login-dialog-session-list-item:hover {
color: white;
} }
.login-dialog-session-list-button { .login-dialog-session-list-button {
padding: 4px; padding: 4px;
} }
.login-dialog-session-list-scroll-view { .login-dialog-session-list-button:focus {
padding: 6px; background-color: #4c4c4c;
} }
.login-dialog-session-list-item { .login-dialog-session-list-button:active {
padding-bottom: 6px; 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 { .login-dialog-session-list-triangle {
padding-right: 6px; padding-right: .5em;
} }
.login-dialog-session-list-item-box { .login-dialog-session-list-item-box {
padding-left: 6px; spacing: .25em;
spacing: 6px;
} }
.login-dialog-session-list-item-dot { .login-dialog-session-list-item-dot {
width: 10px; width: .75em;
height: 10px; height: .75em;
}
.login-dialog-logo-bin {
padding: 24px 0px;
} }
.login-dialog .modal-dialog-button-box { .login-dialog .modal-dialog-button-box {

View File

@ -46,7 +46,6 @@
<xi:include href="doc-gen-org.gnome.Shell.SearchProvider.xml"/> <xi:include href="doc-gen-org.gnome.Shell.SearchProvider.xml"/>
<xi:include href="doc-gen-org.gnome.Shell.SearchProvider2.xml"/> <xi:include href="doc-gen-org.gnome.Shell.SearchProvider2.xml"/>
<xi:include href="xml/shell-global.xml"/> <xi:include href="xml/shell-global.xml"/>
<xi:include href="xml/shell-keybinding-modes.xml"/>
<xi:include href="xml/shell-wm.xml"/> <xi:include href="xml/shell-wm.xml"/>
<xi:include href="xml/shell-xfixes-cursor.xml"/> <xi:include href="xml/shell-xfixes-cursor.xml"/>
<xi:include href="xml/shell-util.xml"/> <xi:include href="xml/shell-util.xml"/>

View File

@ -17,8 +17,13 @@ misc/config.js: misc/config.js.in Makefile
jsdir = $(pkgdatadir)/js jsdir = $(pkgdatadir)/js
nobase_dist_js_DATA = \ nobase_dist_js_DATA = \
gdm/batch.js \
gdm/fingerprint.js \
gdm/loginDialog.js \
gdm/powerMenu.js \
gdm/realmd.js \
gdm/util.js \
extensionPrefs/main.js \ extensionPrefs/main.js \
misc/batch.js \
misc/config.js \ misc/config.js \
misc/extensionUtils.js \ misc/extensionUtils.js \
misc/fileUtils.js \ misc/fileUtils.js \
@ -32,7 +37,6 @@ nobase_dist_js_DATA = \
misc/util.js \ misc/util.js \
perf/core.js \ perf/core.js \
ui/altTab.js \ ui/altTab.js \
ui/animation.js \
ui/appDisplay.js \ ui/appDisplay.js \
ui/appFavorites.js \ ui/appFavorites.js \
ui/backgroundMenu.js \ ui/backgroundMenu.js \
@ -73,9 +77,7 @@ nobase_dist_js_DATA = \
ui/pointerWatcher.js \ ui/pointerWatcher.js \
ui/popupMenu.js \ ui/popupMenu.js \
ui/remoteSearch.js \ ui/remoteSearch.js \
ui/remoteMenu.js \
ui/runDialog.js \ ui/runDialog.js \
ui/screencast.js \
ui/screenshot.js \ ui/screenshot.js \
ui/screenShield.js \ ui/screenShield.js \
ui/scripting.js \ ui/scripting.js \
@ -91,7 +93,7 @@ nobase_dist_js_DATA = \
ui/status/bluetooth.js \ ui/status/bluetooth.js \
ui/switcherPopup.js \ ui/switcherPopup.js \
ui/tweener.js \ ui/tweener.js \
ui/userAvatar.js \ ui/unlockDialog.js \
ui/userMenu.js \ ui/userMenu.js \
ui/userWidget.js \ ui/userWidget.js \
ui/viewSelector.js \ ui/viewSelector.js \
@ -103,14 +105,6 @@ nobase_dist_js_DATA = \
ui/workspacesView.js \ ui/workspacesView.js \
ui/workspaceSwitcherPopup.js \ ui/workspaceSwitcherPopup.js \
ui/xdndHandler.js \ ui/xdndHandler.js \
ui/auth/fingerprint.js \
ui/auth/loginDialog.js \
ui/auth/powerMenu.js \
ui/auth/realmd.js \
ui/auth/sessionList.js \
ui/auth/unlockDialog.js \
ui/auth/userList.js \
ui/auth/util.js \
ui/components/__init__.js \ ui/components/__init__.js \
ui/components/autorunManager.js \ ui/components/autorunManager.js \
ui/components/automountManager.js \ ui/components/automountManager.js \

File diff suppressed because it is too large Load Diff

View File

@ -23,7 +23,7 @@ const Lang = imports.lang;
const LoginManager = imports.misc.loginManager; const LoginManager = imports.misc.loginManager;
const AuthUtil = imports.ui.auth.util; const GdmUtil = imports.gdm.util;
const PanelMenu = imports.ui.panelMenu; const PanelMenu = imports.ui.panelMenu;
const PopupMenu = imports.ui.popupMenu; const PopupMenu = imports.ui.popupMenu;
@ -37,7 +37,7 @@ const PowerMenuButton = new Lang.Class({
this._loginManager = LoginManager.getLoginManager(); this._loginManager = LoginManager.getLoginManager();
this._settings = new Gio.Settings({ schema: AuthUtil.LOGIN_SCREEN_SCHEMA }); this._settings = new Gio.Settings({ schema: GdmUtil.LOGIN_SCREEN_SCHEMA });
this._settings.connect('changed::disable-restart-buttons', this._settings.connect('changed::disable-restart-buttons',
Lang.bind(this, this._updateVisibility)); Lang.bind(this, this._updateVisibility));

View File

@ -63,7 +63,7 @@ const Manager = new Lang.Class({
Lang.bind(this, this._reloadRealms)) Lang.bind(this, this._reloadRealms))
this._realms = {}; this._realms = {};
this._signalId = this._aggregateProvider.connect('g-properties-changed', this._aggregateProvider.connect('g-properties-changed',
Lang.bind(this, function(proxy, properties) { Lang.bind(this, function(proxy, properties) {
if ('Realms' in properties.deep_unpack()) if ('Realms' in properties.deep_unpack())
this._reloadRealms(); this._reloadRealms();
@ -106,7 +106,7 @@ const Manager = new Lang.Class({
realm.connect('g-properties-changed', realm.connect('g-properties-changed',
Lang.bind(this, function(proxy, properties) { Lang.bind(this, function(proxy, properties) {
if ('Configured' in properties.deep_unpack()) if ('Configured' in properties.deep_unpack())
this._reloadRealm(realm); this._reloadRealm();
})); }));
}, },
@ -134,18 +134,6 @@ const Manager = new Lang.Class({
this._updateLoginFormat(); this._updateLoginFormat();
return this._loginFormat; return this._loginFormat;
},
release: function() {
Service(Gio.DBus.system,
'org.freedesktop.realmd',
'/org/freedesktop/realmd',
function(service) {
service.ReleaseRemote();
});
this._aggregateProvider.disconnect(this._signalId);
this._realms = { };
this._updateLoginFormat();
} }
}); });
Signals.addSignalMethods(Manager.prototype) Signals.addSignalMethods(Manager.prototype)

View File

@ -7,8 +7,9 @@ const Lang = imports.lang;
const Mainloop = imports.mainloop; const Mainloop = imports.mainloop;
const Signals = imports.signals; const Signals = imports.signals;
const Batch = imports.misc.batch; const Batch = imports.gdm.batch;
const Fprint = imports.ui.auth.fingerprint; const Fprint = imports.gdm.fingerprint;
const Realmd = imports.gdm.realmd;
const Main = imports.ui.main; const Main = imports.ui.main;
const Params = imports.misc.params; const Params = imports.misc.params;
const Tweener = imports.ui.tweener; const Tweener = imports.ui.tweener;
@ -116,6 +117,7 @@ const ShellUserVerifier = new Lang.Class({
this._settings = new Gio.Settings({ schema: LOGIN_SCREEN_SCHEMA }); this._settings = new Gio.Settings({ schema: LOGIN_SCREEN_SCHEMA });
this._fprintManager = new Fprint.FprintManager(); this._fprintManager = new Fprint.FprintManager();
this._realmManager = new Realmd.Manager();
this._messageQueue = []; this._messageQueue = [];
this._messageQueueTimeoutId = 0; this._messageQueueTimeoutId = 0;
this.hasPendingMessages = false; this.hasPendingMessages = false;
@ -375,11 +377,30 @@ const ShellUserVerifier = new Lang.Class({
this._queueMessage(problem, 'login-dialog-message-warning'); this._queueMessage(problem, 'login-dialog-message-warning');
}, },
_showRealmLoginHint: function() {
if (this._realmManager.loginFormat) {
let hint = this._realmManager.loginFormat;
hint = hint.replace(/%U/g, 'user');
hint = hint.replace(/%D/g, 'DOMAIN');
hint = hint.replace(/%[^UD]/g, '');
// Translators: this message is shown below the username entry field
// to clue the user in on how to login to the local network realm
this.emit('show-login-hint',
_("(e.g., user or %s)").format(hint));
}
},
_onInfoQuery: function(client, serviceName, question) { _onInfoQuery: function(client, serviceName, question) {
// We only expect questions to come from the main auth service // We only expect questions to come from the main auth service
if (serviceName != PASSWORD_SERVICE_NAME) if (serviceName != PASSWORD_SERVICE_NAME)
return; return;
this._showRealmLoginHint();
this._realmLoginHintSignalId = this._realmManager.connect('login-format-changed',
Lang.bind(this, this._showRealmLoginHint));
this.emit('ask-question', serviceName, question, ''); this.emit('ask-question', serviceName, question, '');
}, },
@ -455,6 +476,11 @@ const ShellUserVerifier = new Lang.Class({
} }
this.emit('hide-login-hint'); this.emit('hide-login-hint');
if (this._realmLoginHintSignalId) {
this._realmManager.disconnect(this._realmLoginHintSignalId);
this._realmLoginHintSignalId = 0;
}
}, },
}); });
Signals.addSignalMethods(ShellUserVerifier.prototype); Signals.addSignalMethods(ShellUserVerifier.prototype);

View File

@ -58,7 +58,6 @@ const Map = new Lang.Class({
_init: function(iterable) { _init: function(iterable) {
this._pool = { }; this._pool = { };
this._size = 0;
if (iterable) { if (iterable) {
for (let i = 0; i < iterable.length; i++) { for (let i = 0; i < iterable.length; i++) {
@ -100,7 +99,6 @@ const Map = new Lang.Class({
node.value = value; node.value = value;
} else { } else {
this._pool[hash] = { key: key, value: value }; this._pool[hash] = { key: key, value: value };
this._size++;
} }
}, },
@ -110,7 +108,6 @@ const Map = new Lang.Class({
if (node && _sameValue(node.key, key)) { if (node && _sameValue(node.key, key)) {
delete this._pool[hash]; delete this._pool[hash];
this._size--;
return [node.key, node.value]; return [node.key, node.value];
} else { } else {
return [null, null]; return [null, null];
@ -139,6 +136,6 @@ const Map = new Lang.Class({
}, },
size: function() { size: function() {
return this._size; return Object.getOwnPropertyNames(this._pool).length;
}, },
}); });

View File

@ -18,7 +18,7 @@ const _urlRegexp = new RegExp(
'(^|' + _leadingJunk + ')' + '(^|' + _leadingJunk + ')' +
'(' + '(' +
'(?:' + '(?:' +
'(?:http|https|ftp)://' + // scheme:// '[a-z][\\w-]+://' + // scheme://
'|' + '|' +
'www\\d{0,3}[.]' + // www. 'www\\d{0,3}[.]' + // www.
'|' + '|' +

View File

@ -233,10 +233,8 @@ const AppSwitcherPopup = new Lang.Class({
_finish : function(timestamp) { _finish : function(timestamp) {
let appIcon = this._items[this._selectedIndex]; let appIcon = this._items[this._selectedIndex];
if (this._currentWindow < 0) let window = this._currentWindow > 0 ? this._currentWindow : 0;
appIcon.app.activate_window(appIcon.cachedWindows[0], timestamp); appIcon.app.activate_window(appIcon.cachedWindows[window], timestamp);
else
Main.activateWindow(appIcon.cachedWindows[this._currentWindow], timestamp);
this.parent(); this.parent();
}, },

View File

@ -1,84 +0,0 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Lang = imports.lang;
const Mainloop = imports.mainloop;
const St = imports.gi.St;
const Signals = imports.signals;
const Atk = imports.gi.Atk;
const ANIMATED_ICON_UPDATE_TIMEOUT = 100;
const Animation = new Lang.Class({
Name: 'Animation',
_init: function(filename, width, height, speed) {
this.actor = new St.Bin();
this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
this._speed = speed;
this._isLoaded = false;
this._isPlaying = false;
this._timeoutId = 0;
this._frame = 0;
this._animations = St.TextureCache.get_default().load_sliced_image (filename, width, height,
Lang.bind(this, this._animationsLoaded));
this.actor.set_child(this._animations);
},
play: function() {
if (this._isLoaded && this._timeoutId == 0) {
if (this._frame == 0)
this._showFrame(0);
this._timeoutId = Mainloop.timeout_add(this._speed, Lang.bind(this, this._update));
}
this._isPlaying = true;
},
stop: function() {
if (this._timeoutId > 0) {
Mainloop.source_remove(this._timeoutId);
this._timeoutId = 0;
}
this._isPlaying = false;
},
_showFrame: function(frame) {
let oldFrameActor = this._animations.get_child_at_index(this._frame);
if (oldFrameActor)
oldFrameActor.hide();
this._frame = (frame % this._animations.get_n_children());
let newFrameActor = this._animations.get_child_at_index(this._frame);
if (newFrameActor)
newFrameActor.show();
},
_update: function() {
this._showFrame(this._frame + 1);
return true;
},
_animationsLoaded: function() {
this._isLoaded = true;
if (this._isPlaying)
this.play();
},
_onDestroy: function() {
this.stop();
}
});
const AnimatedIcon = new Lang.Class({
Name: 'AnimatedIcon',
Extends: Animation,
_init: function(filename, size) {
this.parent(filename, size, size, ANIMATED_ICON_UPDATE_TIMEOUT);
}
});

View File

@ -187,9 +187,6 @@ const AllView = new Lang.Class({
_init: function() { _init: function() {
this.parent(); this.parent();
this._grid.actor.y_align = Clutter.ActorAlign.START;
this._grid.actor.y_expand = true;
let box = new St.BoxLayout({ vertical: true }); let box = new St.BoxLayout({ vertical: true });
this._stack = new St.Widget({ layout_manager: new AllViewLayout() }); this._stack = new St.Widget({ layout_manager: new AllViewLayout() });
this._stack.add_actor(this._grid.actor); this._stack.add_actor(this._grid.actor);
@ -279,12 +276,8 @@ const AllView = new Lang.Class({
this._eventBlocker.reactive = isOpen; this._eventBlocker.reactive = isOpen;
this._currentPopup = isOpen ? popup : null; this._currentPopup = isOpen ? popup : null;
this._updateIconOpacities(isOpen); this._updateIconOpacities(isOpen);
if (isOpen) { if (isOpen)
this._ensureIconVisible(popup.actor); this._ensureIconVisible(popup.actor);
this._grid.actor.y = popup.parentOffset;
} else {
this._grid.actor.y = 0;
}
})); }));
}, },
@ -323,8 +316,6 @@ const FrequentView = new Lang.Class({
loadApps: function() { loadApps: function() {
let mostUsed = this._usage.get_most_used (""); let mostUsed = this._usage.get_most_used ("");
for (let i = 0; i < mostUsed.length; i++) { for (let i = 0; i < mostUsed.length; i++) {
if (!mostUsed[i].get_app_info().should_show())
continue;
let appIcon = new AppIcon(mostUsed[i]); let appIcon = new AppIcon(mostUsed[i]);
this._grid.addItem(appIcon.actor, -1); this._grid.addItem(appIcon.actor, -1);
} }
@ -350,9 +341,6 @@ const AppDisplay = new Lang.Class({
global.settings.connect('changed::app-folder-categories', Lang.bind(this, function() { global.settings.connect('changed::app-folder-categories', Lang.bind(this, function() {
Main.queueDeferredWork(this._allAppsWorkId); Main.queueDeferredWork(this._allAppsWorkId);
})); }));
this._privacySettings = new Gio.Settings({ schema: 'org.gnome.desktop.privacy' });
this._privacySettings.connect('changed::remember-app-usage',
Lang.bind(this, this._updateFrequentVisibility));
this._views = []; this._views = [];
@ -396,7 +384,6 @@ const AppDisplay = new Lang.Class({
})); }));
} }
this._showView(Views.FREQUENT); this._showView(Views.FREQUENT);
this._updateFrequentVisibility();
// We need a dummy actor to catch the keyboard focus if the // We need a dummy actor to catch the keyboard focus if the
// user Ctrl-Alt-Tabs here before the deferred work creates // user Ctrl-Alt-Tabs here before the deferred work creates
@ -426,19 +413,6 @@ const AppDisplay = new Lang.Class({
} }
}, },
_updateFrequentVisibility: function() {
let enabled = this._privacySettings.get_boolean('remember-app-usage');
this._views[Views.FREQUENT].control.visible = enabled;
let visibleViews = this._views.filter(function(v) {
return v.control.visible;
});
this._controls.visible = visibleViews.length > 1;
if (!enabled && this._views[Views.FREQUENT].view.actor.visible)
this._showView(Views.ALL);
},
_redisplay: function() { _redisplay: function() {
this._redisplayFrequentApps(); this._redisplayFrequentApps();
this._redisplayAllApps(); this._redisplayAllApps();
@ -509,11 +483,11 @@ const AppSearchProvider = new Lang.Class({
}, },
getInitialResultSet: function(terms) { getInitialResultSet: function(terms) {
this.searchSystem.setResults(this, this._appSys.initial_search(terms)); this.searchSystem.pushResults(this, this._appSys.initial_search(terms));
}, },
getSubsearchResultSet: function(previousResults, terms) { getSubsearchResultSet: function(previousResults, terms) {
this.searchSystem.setResults(this, this._appSys.subsearch(previousResults, terms)); this.searchSystem.pushResults(this, this._appSys.subsearch(previousResults, terms));
}, },
activateResult: function(app) { activateResult: function(app) {
@ -598,11 +572,7 @@ const FolderIcon = new Lang.Class({
// Position the popup above or below the source icon // Position the popup above or below the source icon
if (side == St.Side.BOTTOM) { if (side == St.Side.BOTTOM) {
this._popup.actor.show(); this._popup.actor.show();
let closeButtonOffset = -this._popup.closeButton.translation_y; this._popup.actor.y = this.actor.y - this._popup.actor.height;
let y = this.actor.y - this._popup.actor.height;
let yWithButton = y - closeButtonOffset;
this._popup.parentOffset = yWithButton < 0 ? -yWithButton : 0;
this._popup.actor.y = Math.max(y, closeButtonOffset);
this._popup.actor.hide(); this._popup.actor.hide();
} else { } else {
this._popup.actor.y = this.actor.y + this.actor.height; this._popup.actor.y = this.actor.y + this.actor.height;
@ -625,7 +595,6 @@ const AppFolderPopup = new Lang.Class({
this._arrowSide = side; this._arrowSide = side;
this._isOpen = false; this._isOpen = false;
this.parentOffset = 0;
this.actor = new St.Widget({ layout_manager: new Clutter.BinLayout(), this.actor = new St.Widget({ layout_manager: new Clutter.BinLayout(),
visible: false, visible: false,
@ -649,31 +618,17 @@ const AppFolderPopup = new Lang.Class({
this.actor.add_actor(this._boxPointer.actor); this.actor.add_actor(this._boxPointer.actor);
this._boxPointer.bin.set_child(this._view.actor); this._boxPointer.bin.set_child(this._view.actor);
this.closeButton = Util.makeCloseButton(); let closeButton = Util.makeCloseButton();
this.closeButton.connect('clicked', Lang.bind(this, this.popdown)); closeButton.connect('clicked', Lang.bind(this, this.popdown));
this.actor.add_actor(this.closeButton); this.actor.add_actor(closeButton);
this._boxPointer.actor.bind_property('opacity', this.closeButton, 'opacity', this._boxPointer.actor.bind_property('opacity', closeButton, 'opacity',
GObject.BindingFlags.SYNC_CREATE); GObject.BindingFlags.SYNC_CREATE);
global.focus_manager.add_group(this.actor);
source.actor.connect('destroy', Lang.bind(this, source.actor.connect('destroy', Lang.bind(this,
function() { function() {
this.actor.destroy(); this.actor.destroy();
})); }));
this.actor.connect('key-press-event', Lang.bind(this, this._onKeyPress));
},
_onKeyPress: function(actor, event) {
if (!this._isOpen)
return false;
if (event.get_key_symbol() != Clutter.KEY_Escape)
return false;
this.popdown();
return true;
}, },
toggle: function() { toggle: function() {
@ -688,7 +643,6 @@ const AppFolderPopup = new Lang.Class({
return; return;
this.actor.show(); this.actor.show();
this.actor.navigate_focus(null, Gtk.DirectionType.TAB_FORWARD, false);
this._boxPointer.setArrowActor(this._source.actor); this._boxPointer.setArrowActor(this._source.actor);
this._boxPointer.show(BoxPointer.PopupAnimation.FADE | this._boxPointer.show(BoxPointer.PopupAnimation.FADE |

View File

@ -1,230 +0,0 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
/*
* Copyright 2011 Red Hat, Inc
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
const Gtk = imports.gi.Gtk;
const Lang = imports.lang;
const Signals = imports.signals;
const St = imports.gi.St;
const Gdm = imports.gi.Gdm;
const SessionListItem = new Lang.Class({
Name: 'SessionListItem',
_init: function(id, name) {
this.id = id;
this.actor = new St.Button({ style_class: 'login-dialog-session-list-item',
button_mask: St.ButtonMask.ONE | St.ButtonMask.THREE,
can_focus: true,
reactive: true,
x_fill: true,
x_align: St.Align.START });
this._box = new St.BoxLayout({ style_class: 'login-dialog-session-list-item-box' });
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' });
this._dot.connect('repaint', Lang.bind(this, this._onRepaintDot));
this._box.add_actor(this._dot);
this.setShowDot(false);
let label = new St.Label({ style_class: 'login-dialog-session-list-item-label',
text: name });
this.actor.label_actor = label;
this._box.add_actor(label);
},
setShowDot: function(show) {
if (show)
this._dot.opacity = 255;
else
this._dot.opacity = 0;
},
_onRepaintDot: function(area) {
let cr = area.get_context();
let [width, height] = area.get_surface_size();
let color = area.get_theme_node().get_foreground_color();
cr.setSourceRGBA (color.red / 255,
color.green / 255,
color.blue / 255,
color.alpha / 255);
cr.arc(width / 2, height / 2, width / 3, 0, 2 * Math.PI);
cr.fill();
cr.$dispose();
},
_onClicked: function() {
this.emit('activate');
}
});
Signals.addSignalMethods(SessionListItem.prototype);
const SessionList = new Lang.Class({
Name: 'SessionList',
_init: function() {
this.actor = new St.Bin();
this._box = new St.BoxLayout({ style_class: 'login-dialog-session-list',
vertical: true});
this.actor.child = this._box;
this._button = new St.Button({ style_class: 'login-dialog-session-list-button',
button_mask: St.ButtonMask.ONE | St.ButtonMask.THREE,
can_focus: true,
x_fill: true,
y_fill: true });
let box = new St.BoxLayout();
this._button.add_actor(box);
this._triangle = new St.Label({ style_class: 'login-dialog-session-list-triangle',
text: '\u25B8' });
box.add_actor(this._triangle);
let label = new St.Label({ style_class: 'login-dialog-session-list-label',
text: _("Session…") });
box.add_actor(label);
this._button.connect('clicked',
Lang.bind(this, this._onClicked));
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);
this._itemList = new St.BoxLayout({ style_class: 'login-dialog-session-item-list',
vertical: true });
this._scrollView.add_actor(this._itemList);
this._hideSessions();
this.isOpen = false;
this._populate();
},
_hideSessions: function() {
this._itemList.can_focus = false;
this._itemList.reactive = false;
this._scrollView.opacity = 0;
},
_showSessions: function() {
this._scrollView.opacity = 255;
this._itemList.reactive = true;
this._itemList.can_focus = true;
},
open: function() {
if (this.isOpen)
return;
this._button.add_style_pseudo_class('open');
this._showSessions();
this._triangle.set_text('\u25BE');
this.isOpen = true;
},
close: function() {
if (!this.isOpen)
return;
this._button.remove_style_pseudo_class('open');
this._hideSessions();
this._triangle.set_text('\u25B8');
this.isOpen = false;
},
_onClicked: function() {
if (!this.isOpen)
this.open();
else
this.close();
},
updateSensitivity: function(sensitive) {
this._button.reactive = sensitive;
this._button.can_focus = sensitive;
for (let id in this._items)
this._items[id].actor.reactive = sensitive;
},
setActiveSession: function(sessionId) {
if (sessionId == this._activeSessionId)
return;
if (this._activeSessionId)
this._items[this._activeSessionId].setShowDot(false);
this._items[sessionId].setShowDot(true);
this._activeSessionId = sessionId;
this.emit('session-activated', this._activeSessionId);
},
_populate: function() {
this._itemList.destroy_all_children();
this._activeSessionId = null;
this._items = {};
let ids = Gdm.get_session_ids();
ids.sort();
if (ids.length <= 1) {
this._box.hide();
this._button.hide();
} else {
this._button.show();
this._box.show();
}
for (let i = 0; i < ids.length; i++) {
let [sessionName, sessionDescription] = Gdm.get_session_name_and_description(ids[i]);
let item = new SessionListItem(ids[i], sessionName);
this._itemList.add_actor(item.actor);
this._items[ids[i]] = item;
if (!this._activeSessionId)
this.setActiveSession(ids[i]);
item.connect('activate',
Lang.bind(this, function() {
this.setActiveSession(item.id);
}));
item.actor.can_focus = this._itemList.can_focus;
let signalId = this._itemList.connect('notify::can-focus',
Lang.bind(this, function() {
item.actor.can_focus = this._itemList.can_focus;
}));
item.actor.connect('destroy',
Lang.bind(this, function() {
this._itemList.disconnect(signalId);
}));
}
}
});
Signals.addSignalMethods(SessionList.prototype);

View File

@ -1,251 +0,0 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const AccountsService = imports.gi.AccountsService;
const Gtk = imports.gi.Gtk;
const Meta = imports.gi.Meta;
const Lang = imports.lang;
const Signals = imports.signals;
const St = imports.gi.St;
const Gdm = imports.gi.Gdm;
const Batch = imports.misc.batch;
const Tweener = imports.ui.tweener;
const UserAvatar = imports.ui.userAvatar;
const _SCROLL_ANIMATION_TIME = 0.5;
const UserListItem = new Lang.Class({
Name: 'UserListItem',
_init: function(user) {
this.user = user;
this._userChangedId = this.user.connect('changed',
Lang.bind(this, this._onUserChanged));
let layout = new St.BoxLayout({ vertical: false });
this.actor = new St.Button({ style_class: 'login-dialog-user-list-item',
button_mask: St.ButtonMask.ONE | St.ButtonMask.THREE,
can_focus: true,
child: layout,
reactive: true,
x_align: St.Align.START,
x_fill: true });
this._userAvatar = new UserAvatar.UserAvatar(this.user,
{ styleClass: 'login-dialog-user-list-item-icon' });
layout.add(this._userAvatar.actor);
let textLayout = new St.BoxLayout({ style_class: 'login-dialog-user-list-item-text-box',
vertical: true });
layout.add(textLayout, { expand: true });
this._nameLabel = new St.Label({ style_class: 'login-dialog-user-list-item-name' });
this.actor.label_actor = 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.actor.connect('clicked', Lang.bind(this, this._onClicked));
this._onUserChanged();
},
_onUserChanged: function() {
this._nameLabel.set_text(this.user.get_real_name());
this._userAvatar.update();
this._updateLoggedIn();
},
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');
},
showTimedLoginIndicator: function(time) {
let hold = new Batch.Hold();
this.hideTimedLoginIndicator();
Tweener.addTween(this._timedLoginIndicator,
{ scale_x: 1.,
time: time,
transition: 'linear',
onComplete: function() {
hold.release();
},
onCompleteScope: this
});
return hold;
},
hideTimedLoginIndicator: function() {
Tweener.removeTweens(this._timedLoginIndicator);
this._timedLoginIndicator.scale_x = 0.;
}
});
Signals.addSignalMethods(UserListItem.prototype);
const UserList = new Lang.Class({
Name: 'UserList',
_init: function() {
this.actor = new St.ScrollView({ style_class: 'login-dialog-user-list-view'});
this.actor.set_policy(Gtk.PolicyType.NEVER,
Gtk.PolicyType.AUTOMATIC);
this._box = new St.BoxLayout({ vertical: true,
style_class: 'login-dialog-user-list',
pseudo_class: 'expanded' });
this.actor.add_actor(this._box);
this._items = {};
this.actor.connect('key-focus-in', Lang.bind(this, this._moveFocusToItems));
},
_moveFocusToItems: function() {
let hasItems = Object.keys(this._items).length > 0;
if (!hasItems)
return;
if (global.stage.get_key_focus() != this.actor)
return;
let focusSet = this.actor.navigate_focus(null, Gtk.DirectionType.TAB_FORWARD, false);
if (!focusSet) {
Meta.later_add(Meta.LaterType.BEFORE_REDRAW, Lang.bind(this, function() {
this._moveFocusToItems();
return false;
}));
}
},
_onItemActivated: function(activatedItem) {
this.emit('activate', activatedItem);
},
updateStyle: function(isExpanded) {
let tasks = [];
if (isExpanded)
this._box.add_style_pseudo_class('expanded');
else
this._box.remove_style_pseudo_class('expanded');
for (let userName in this._items) {
let item = this._items[userName];
item.actor.sync_hover();
item.syncStyleClasses();
}
},
scrollToItem: function(item) {
let box = item.actor.get_allocation_box();
let adjustment = this.actor.get_vscroll_bar().get_adjustment();
let value = (box.y1 + adjustment.step_increment / 2.0) - (adjustment.page_size / 2.0);
Tweener.removeTweens(adjustment);
Tweener.addTween (adjustment,
{ value: value,
time: _SCROLL_ANIMATION_TIME,
transition: 'easeOutQuad' });
},
jumpToItem: function(item) {
let box = item.actor.get_allocation_box();
let adjustment = this.actor.get_vscroll_bar().get_adjustment();
let value = (box.y1 + adjustment.step_increment / 2.0) - (adjustment.page_size / 2.0);
adjustment.set_value(value);
},
getItemFromUserName: function(userName) {
let item = this._items[userName];
if (!item)
return null;
return item;
},
addUser: function(user) {
if (!user.is_loaded)
return;
if (user.is_system_account())
return;
if (user.locked)
return;
let userName = user.get_user_name();
if (!userName)
return;
this.removeUser(user);
let item = new UserListItem(user);
this._box.add(item.actor, { x_fill: true });
this._items[userName] = item;
item.connect('activate',
Lang.bind(this, this._onItemActivated));
// Try to keep the focused item front-and-center
item.actor.connect('key-focus-in',
Lang.bind(this,
function() {
this.scrollToItem(item);
}));
this._moveFocusToItems();
this.emit('item-added', item);
},
removeUser: function(user) {
if (!user.is_loaded)
return;
let userName = user.get_user_name();
if (!userName)
return;
let item = this._items[userName];
if (!item)
return;
item.actor.destroy();
delete this._items[userName];
}
});
Signals.addSignalMethods(UserList.prototype);

View File

@ -126,11 +126,6 @@ const BackgroundCache = new Lang.Class({
}, },
removeImageContent: function(content) { removeImageContent: function(content) {
let filename = content.get_filename();
if (filename && this._fileMonitors[filename])
delete this._fileMonitors[filename];
this._removeContent(this._images, content); this._removeContent(this._images, content);
}, },
@ -431,7 +426,7 @@ const Background = new Lang.Class({
content.brightness = this._brightness; content.brightness = this._brightness;
content.vignette_sharpness = this._vignetteSharpness; content.vignette_sharpness = this._vignetteSharpness;
this._cache.removeImageContent(this._images[index].content); this._cache.removeImageContent(content);
this._images[index].content = content; this._images[index].content = content;
this._watchCacheFile(filename); this._watchCacheFile(filename);
}, },
@ -747,15 +742,11 @@ const BackgroundManager = new Lang.Class({
time: FADE_ANIMATION_TIME, time: FADE_ANIMATION_TIME,
transition: 'easeOutQuad', transition: 'easeOutQuad',
onComplete: Lang.bind(this, function() { onComplete: Lang.bind(this, function() {
if (this._newBackground == newBackground) { if (this.background == background) {
this.background = newBackground; this.background = newBackground;
this._newBackground = null; this._newBackground = null;
} else { background.actor.destroy();
newBackground.actor.destroy();
} }
background.actor.destroy();
this.emit('changed'); this.emit('changed');
}) })
}); });

View File

@ -46,10 +46,8 @@ function addBackgroundMenu(actor) {
clickAction.connect('long-press', function(action, actor, state) { clickAction.connect('long-press', function(action, actor, state) {
if (state == Clutter.LongPressState.QUERY) if (state == Clutter.LongPressState.QUERY)
return action.get_button() == 1 && !actor._backgroundMenu.isOpen; return action.get_button() == 1 && !actor._backgroundMenu.isOpen;
if (state == Clutter.LongPressState.ACTIVATE) { if (state == Clutter.LongPressState.ACTIVATE)
openMenu(); openMenu();
actor._backgroundManager.ignoreRelease();
}
return true; return true;
}); });
clickAction.connect('clicked', function(action) { clickAction.connect('clicked', function(action) {
@ -62,7 +60,5 @@ function addBackgroundMenu(actor) {
actor._backgroundMenu.destroy(); actor._backgroundMenu.destroy();
actor._backgroundMenu = null; actor._backgroundMenu = null;
actor._backgroundManager = null; actor._backgroundManager = null;
cursor.destroy();
}); });
} }

View File

@ -443,18 +443,16 @@ const Calendar = new Lang.Class({
this.actor.add(this._topBox, this.actor.add(this._topBox,
{ row: 0, col: 0, col_span: offsetCols + 7 }); { row: 0, col: 0, col_span: offsetCols + 7 });
this._backButton = new St.Button({ style_class: 'calendar-change-month-back', let back = new St.Button({ style_class: 'calendar-change-month-back' });
can_focus: true }); this._topBox.add(back);
this._topBox.add(this._backButton); back.connect('clicked', Lang.bind(this, this._onPrevMonthButtonClicked));
this._backButton.connect('clicked', Lang.bind(this, this._onPrevMonthButtonClicked));
this._monthLabel = new St.Label({style_class: 'calendar-month-label'}); this._monthLabel = new St.Label({style_class: 'calendar-month-label'});
this._topBox.add(this._monthLabel, { expand: true, x_fill: false, x_align: St.Align.MIDDLE }); this._topBox.add(this._monthLabel, { expand: true, x_fill: false, x_align: St.Align.MIDDLE });
this._forwardButton = new St.Button({ style_class: 'calendar-change-month-forward', let forward = new St.Button({ style_class: 'calendar-change-month-forward' });
can_focus: true }); this._topBox.add(forward);
this._topBox.add(this._forwardButton); forward.connect('clicked', Lang.bind(this, this._onNextMonthButtonClicked));
this._forwardButton.connect('clicked', Lang.bind(this, this._onNextMonthButtonClicked));
// Add weekday labels... // Add weekday labels...
// //
@ -513,12 +511,10 @@ const Calendar = new Lang.Class({
} }
} }
this._backButton.grab_key_focus();
this.setDate(newDate, false); this.setDate(newDate, false);
}, },
_onNextMonthButtonClicked: function() { _onNextMonthButtonClicked: function() {
let newDate = new Date(this._selectedDate); let newDate = new Date(this._selectedDate);
let oldMonth = newDate.getMonth(); let oldMonth = newDate.getMonth();
if (oldMonth == 11) { if (oldMonth == 11) {
@ -537,9 +533,7 @@ const Calendar = new Lang.Class({
} }
} }
this._forwardButton.grab_key_focus(); this.setDate(newDate, false);
this.setDate(newDate, false);
}, },
_onSettingsChange: function() { _onSettingsChange: function() {
@ -596,8 +590,7 @@ const Calendar = new Lang.Class({
// nRows here means 6 weeks + one header + one navbar // nRows here means 6 weeks + one header + one navbar
let nRows = 8; let nRows = 8;
while (row < 8) { while (row < 8) {
let button = new St.Button({ label: iter.getDate().toString(), let button = new St.Button({ label: iter.getDate().toString() });
can_focus: true });
let rtl = button.get_text_direction() == Clutter.TextDirection.RTL; let rtl = button.get_text_direction() == Clutter.TextDirection.RTL;
if (this._eventSource.isDummy) if (this._eventSource.isDummy)
@ -605,12 +598,8 @@ const Calendar = new Lang.Class({
let iterStr = iter.toUTCString(); let iterStr = iter.toUTCString();
button.connect('clicked', Lang.bind(this, function() { button.connect('clicked', Lang.bind(this, function() {
this._shouldDateGrabFocus = true;
let newlySelectedDate = new Date(iterStr); let newlySelectedDate = new Date(iterStr);
this.setDate(newlySelectedDate, false); this.setDate(newlySelectedDate, false);
this._shouldDateGrabFocus = false;
})); }));
let hasEvents = this._eventSource.hasEvents(iter); let hasEvents = this._eventSource.hasEvents(iter);
@ -635,6 +624,9 @@ const Calendar = new Lang.Class({
else if (iter.getMonth() != this._selectedDate.getMonth()) else if (iter.getMonth() != this._selectedDate.getMonth())
styleClass += ' calendar-other-month-day'; styleClass += ' calendar-other-month-day';
if (_sameDay(this._selectedDate, iter))
button.add_style_pseudo_class('active');
if (hasEvents) if (hasEvents)
styleClass += ' calendar-day-with-events' styleClass += ' calendar-day-with-events'
@ -644,13 +636,6 @@ const Calendar = new Lang.Class({
this.actor.add(button, this.actor.add(button,
{ row: row, col: offsetCols + (7 + iter.getDay() - this._weekStart) % 7 }); { row: row, col: offsetCols + (7 + iter.getDay() - this._weekStart) % 7 });
if (_sameDay(this._selectedDate, iter)) {
button.add_style_pseudo_class('active');
if (this._shouldDateGrabFocus)
button.grab_key_focus();
}
if (this._useWeekdate && iter.getDay() == 4) { if (this._useWeekdate && iter.getDay() == 4) {
let label = new St.Label({ text: _getCalendarWeekForDate(iter).toString(), let label = new St.Label({ text: _getCalendarWeekForDate(iter).toString(),
style_class: 'calendar-day-base calendar-week-number'}); style_class: 'calendar-day-base calendar-week-number'});

View File

@ -25,7 +25,7 @@ const KeyringDialog = new Lang.Class({
this.prompt = new Shell.KeyringPrompt(); this.prompt = new Shell.KeyringPrompt();
this.prompt.connect('show-password', Lang.bind(this, this._onShowPassword)); this.prompt.connect('show-password', Lang.bind(this, this._onShowPassword));
this.prompt.connect('show-confirm', Lang.bind(this, this._onShowConfirm)); this.prompt.connect('show-confirm', Lang.bind(this, this._onShowConfirm));
this.prompt.connect('prompt-close', Lang.bind(this, this._onHidePrompt)); this.prompt.connect('hide-prompt', Lang.bind(this, this._onHidePrompt));
let mainContentBox = new St.BoxLayout({ style_class: 'prompt-dialog-main-layout', let mainContentBox = new St.BoxLayout({ style_class: 'prompt-dialog-main-layout',
vertical: false }); vertical: false });
@ -63,17 +63,11 @@ const KeyringDialog = new Lang.Class({
this._cancelButton = this.addButton({ label: '', this._cancelButton = this.addButton({ label: '',
action: Lang.bind(this, this._onCancelButton), action: Lang.bind(this, this._onCancelButton),
key: Clutter.Escape }, key: Clutter.Escape });
{ expand: true, x_fill: false, x_align: St.Align.START });
this.placeSpinner({ expand: false,
x_fill: false,
y_fill: false,
x_align: St.Align.END,
y_align: St.Align.MIDDLE });
this._continueButton = this.addButton({ label: '', this._continueButton = this.addButton({ label: '',
action: Lang.bind(this, this._onContinueButton), action: Lang.bind(this, this._onContinueButton),
default: true }, default: true },
{ expand: false, x_fill: false, x_align: St.Align.END }); { expand: true, x_fill: false, x_align: St.Align.END });
this.prompt.bind_property('cancel-label', this._cancelButton, 'label', GObject.BindingFlags.SYNC_CREATE); this.prompt.bind_property('cancel-label', this._cancelButton, 'label', GObject.BindingFlags.SYNC_CREATE);
this.prompt.bind_property('continue-label', this._continueButton, 'label', GObject.BindingFlags.SYNC_CREATE); this.prompt.bind_property('continue-label', this._continueButton, 'label', GObject.BindingFlags.SYNC_CREATE);
@ -149,19 +143,11 @@ const KeyringDialog = new Lang.Class({
}, },
_updateSensitivity: function(sensitive) { _updateSensitivity: function(sensitive) {
if (this._passwordEntry) { this._passwordEntry.reactive = sensitive;
this._passwordEntry.reactive = sensitive; this._passwordEntry.clutter_text.editable = sensitive;
this._passwordEntry.clutter_text.editable = sensitive;
}
if (this._confirmEntry) {
this._confirmEntry.reactive = sensitive;
this._confirmEntry.clutter_text.editable = sensitive;
}
this._continueButton.can_focus = sensitive; this._continueButton.can_focus = sensitive;
this._continueButton.reactive = sensitive; this._continueButton.reactive = sensitive;
this.setWorking(!sensitive);
}, },
_ensureOpen: function() { _ensureOpen: function() {

View File

@ -16,7 +16,7 @@ const PolkitAgent = imports.gi.PolkitAgent;
const Components = imports.ui.components; const Components = imports.ui.components;
const ModalDialog = imports.ui.modalDialog; const ModalDialog = imports.ui.modalDialog;
const ShellEntry = imports.ui.shellEntry; const ShellEntry = imports.ui.shellEntry;
const UserAvatar = imports.ui.userAvatar; const UserMenu = imports.ui.userMenu;
const DIALOG_ICON_SIZE = 48; const DIALOG_ICON_SIZE = 48;
@ -31,6 +31,7 @@ const AuthenticationDialog = new Lang.Class({
this.message = message; this.message = message;
this.userNames = userNames; this.userNames = userNames;
this._wasDismissed = false; this._wasDismissed = false;
this._completed = false;
let mainContentBox = new St.BoxLayout({ style_class: 'prompt-dialog-main-layout', let mainContentBox = new St.BoxLayout({ style_class: 'prompt-dialog-main-layout',
vertical: false }); vertical: false });
@ -100,9 +101,9 @@ const AuthenticationDialog = new Lang.Class({
let userBox = new St.BoxLayout({ style_class: 'polkit-dialog-user-layout', let userBox = new St.BoxLayout({ style_class: 'polkit-dialog-user-layout',
vertical: false }); vertical: false });
messageBox.add(userBox); messageBox.add(userBox);
this._userAvatar = new UserAvatar.UserAvatar(this._user, this._userAvatar = new UserMenu.UserAvatarWidget(this._user,
{ iconSize: DIALOG_ICON_SIZE, { iconSize: DIALOG_ICON_SIZE,
styleClass: 'polkit-dialog-user-icon' }); styleClass: 'polkit-dialog-user-icon' });
this._userAvatar.actor.hide(); this._userAvatar.actor.hide();
userBox.add(this._userAvatar.actor, userBox.add(this._userAvatar.actor,
{ x_fill: true, { x_fill: true,
@ -160,32 +161,26 @@ const AuthenticationDialog = new Lang.Class({
this._cancelButton = this.addButton({ label: _("Cancel"), this._cancelButton = this.addButton({ label: _("Cancel"),
action: Lang.bind(this, this.cancel), action: Lang.bind(this, this.cancel),
key: Clutter.Escape }, key: Clutter.Escape });
{ expand: true, x_fill: false, x_align: St.Align.START });
this.placeSpinner({ expand: false,
x_fill: false,
y_fill: false,
x_align: St.Align.END,
y_align: St.Align.MIDDLE });
this._okButton = this.addButton({ label: _("Authenticate"), this._okButton = this.addButton({ label: _("Authenticate"),
action: Lang.bind(this, this._onAuthenticateButtonPressed), action: Lang.bind(this, this._onAuthenticateButtonPressed),
default: true }, default: true },
{ expand: false, x_fill: false, x_align: St.Align.END }); { expand: true, x_fill: false, x_align: St.Align.END });
this._doneEmitted = false; this._doneEmitted = false;
this._identityToAuth = Polkit.UnixUser.new_for_name(userName); this._identityToAuth = Polkit.UnixUser.new_for_name(userName);
this._cookie = cookie; this._cookie = cookie;
},
performAuthentication: function() {
this.destroySession();
this._session = new PolkitAgent.Session({ identity: this._identityToAuth, this._session = new PolkitAgent.Session({ identity: this._identityToAuth,
cookie: this._cookie }); cookie: this._cookie });
this._session.connect('completed', Lang.bind(this, this._onSessionCompleted)); this._session.connect('completed', Lang.bind(this, this._onSessionCompleted));
this._session.connect('request', Lang.bind(this, this._onSessionRequest)); this._session.connect('request', Lang.bind(this, this._onSessionRequest));
this._session.connect('show-error', Lang.bind(this, this._onSessionShowError)); this._session.connect('show-error', Lang.bind(this, this._onSessionShowError));
this._session.connect('show-info', Lang.bind(this, this._onSessionShowInfo)); this._session.connect('show-info', Lang.bind(this, this._onSessionShowInfo));
},
startAuthentication: function() {
this._session.initiate(); this._session.initiate();
}, },
@ -207,14 +202,14 @@ const AuthenticationDialog = new Lang.Class({
log('polkitAuthenticationAgent: Failed to show modal dialog.' + log('polkitAuthenticationAgent: Failed to show modal dialog.' +
' Dismissing authentication request for action-id ' + this.actionId + ' Dismissing authentication request for action-id ' + this.actionId +
' cookie ' + this._cookie); ' cookie ' + this._cookie);
this._emitDone(true); this._emitDone(false, true);
} }
}, },
_emitDone: function(dismissed) { _emitDone: function(keepVisible, dismissed) {
if (!this._doneEmitted) { if (!this._doneEmitted) {
this._doneEmitted = true; this._doneEmitted = true;
this.emit('done', dismissed); this.emit('done', keepVisible, dismissed);
} }
}, },
@ -224,7 +219,6 @@ const AuthenticationDialog = new Lang.Class({
this._okButton.can_focus = sensitive; this._okButton.can_focus = sensitive;
this._okButton.reactive = sensitive; this._okButton.reactive = sensitive;
this.setWorking(!sensitive);
}, },
_onEntryActivate: function() { _onEntryActivate: function() {
@ -243,16 +237,12 @@ const AuthenticationDialog = new Lang.Class({
}, },
_onSessionCompleted: function(session, gainedAuthorization) { _onSessionCompleted: function(session, gainedAuthorization) {
if (this._completed || this._doneEmitted) if (this._completed)
return; return;
this._completed = true; this._completed = true;
/* Yay, all done */ if (!gainedAuthorization) {
if (gainedAuthorization) {
this._emitDone(false);
} else {
/* Unless we are showing an existing error message from the PAM /* Unless we are showing an existing error message from the PAM
* module (the PAM module could be reporting the authentication * module (the PAM module could be reporting the authentication
* error providing authentication-method specific information), * error providing authentication-method specific information),
@ -268,10 +258,8 @@ const AuthenticationDialog = new Lang.Class({
this._infoMessageLabel.hide(); this._infoMessageLabel.hide();
this._nullMessageLabel.hide(); this._nullMessageLabel.hide();
} }
/* Try and authenticate again */
this.performAuthentication();
} }
this._emitDone(!gainedAuthorization, false);
}, },
_onSessionRequest: function(session, request, echo_on) { _onSessionRequest: function(session, request, echo_on) {
@ -315,7 +303,6 @@ const AuthenticationDialog = new Lang.Class({
if (this._session) { if (this._session) {
if (!this._completed) if (!this._completed)
this._session.cancel(); this._session.cancel();
this._completed = false;
this._session = null; this._session = null;
} }
}, },
@ -330,7 +317,7 @@ const AuthenticationDialog = new Lang.Class({
cancel: function() { cancel: function() {
this._wasDismissed = true; this._wasDismissed = true;
this.close(global.get_current_time()); this.close(global.get_current_time());
this._emitDone(true); this._emitDone(false, true);
}, },
}); });
Signals.addSignalMethods(AuthenticationDialog.prototype); Signals.addSignalMethods(AuthenticationDialog.prototype);
@ -340,6 +327,7 @@ const AuthenticationAgent = new Lang.Class({
_init: function() { _init: function() {
this._currentDialog = null; this._currentDialog = null;
this._isCompleting = false;
this._handle = null; this._handle = null;
this._native = new Shell.PolkitAuthenticationAgent(); this._native = new Shell.PolkitAuthenticationAgent();
this._native.connect('initiate', Lang.bind(this, this._onInitiate)); this._native.connect('initiate', Lang.bind(this, this._onInitiate));
@ -376,24 +364,45 @@ const AuthenticationAgent = new Lang.Class({
// discussion. // discussion.
this._currentDialog.connect('done', Lang.bind(this, this._onDialogDone)); this._currentDialog.connect('done', Lang.bind(this, this._onDialogDone));
this._currentDialog.performAuthentication(); this._currentDialog.startAuthentication();
}, },
_onCancel: function(nativeAgent) { _onCancel: function(nativeAgent) {
this._completeRequest(false); this._completeRequest(false, false);
}, },
_onDialogDone: function(dialog, dismissed) { _onDialogDone: function(dialog, keepVisible, dismissed) {
this._completeRequest(dismissed); this._completeRequest(keepVisible, dismissed);
}, },
_completeRequest: function(dismissed) { _reallyCompleteRequest: function(dismissed) {
this._currentDialog.close(); this._currentDialog.close();
this._currentDialog.destroySession(); this._currentDialog.destroySession();
this._currentDialog = null; this._currentDialog = null;
this._isCompleting = false;
this._native.complete(dismissed); this._native.complete(dismissed)
}, },
_completeRequest: function(keepVisible, wasDismissed) {
if (this._isCompleting)
return;
this._isCompleting = true;
if (keepVisible) {
// Give the user 2 seconds to read 'Authentication Failure' before
// dismissing the dialog
Mainloop.timeout_add(2000,
Lang.bind(this,
function() {
this._reallyCompleteRequest(wasDismissed);
return false;
}));
} else {
this._reallyCompleteRequest(wasDismissed);
}
}
}); });
const Component = AuthenticationAgent; const Component = AuthenticationAgent;

View File

@ -20,7 +20,8 @@ const Recorder = new Lang.Class({
Main.wm.addKeybinding('toggle-recording', Main.wm.addKeybinding('toggle-recording',
this._bindingSettings, this._bindingSettings,
Meta.KeyBindingFlags.NONE, Meta.KeyBindingFlags.NONE,
Shell.KeyBindingMode.ALL, Shell.KeyBindingMode.NORMAL |
Shell.KeyBindingMode.OVERVIEW,
Lang.bind(this, this._toggleRecorder)); Lang.bind(this, this._toggleRecorder));
}, },

View File

@ -61,7 +61,8 @@ const CtrlAltTabManager = new Lang.Class({
if (item.focusCallback) { if (item.focusCallback) {
item.focusCallback(timestamp); item.focusCallback(timestamp);
} else { } else {
if (global.stage_input_mode == Shell.StageInputMode.NORMAL) if (global.stage_input_mode == Shell.StageInputMode.NONREACTIVE ||
global.stage_input_mode == Shell.StageInputMode.NORMAL)
global.set_stage_input_mode(Shell.StageInputMode.FOCUSED); global.set_stage_input_mode(Shell.StageInputMode.FOCUSED);
item.root.navigate_focus(null, Gtk.DirectionType.TAB_FORWARD, false); item.root.navigate_focus(null, Gtk.DirectionType.TAB_FORWARD, false);
@ -88,25 +89,19 @@ const CtrlAltTabManager = new Lang.Class({
let items = this._items.filter(function (item) { return item.proxy.mapped; }); let items = this._items.filter(function (item) { return item.proxy.mapped; });
// And add the windows metacity would show in its Ctrl-Alt-Tab list // And add the windows metacity would show in its Ctrl-Alt-Tab list
if (Main.sessionMode.hasWindows && !Main.overview.visible) { if (!Main.overview.visible) {
let screen = global.screen; let screen = global.screen;
let display = screen.get_display(); let display = screen.get_display();
let windows = display.get_tab_list(Meta.TabList.DOCKS, screen, screen.get_active_workspace ()); let windows = display.get_tab_list(Meta.TabList.DOCKS, screen, screen.get_active_workspace ());
let windowTracker = Shell.WindowTracker.get_default(); let windowTracker = Shell.WindowTracker.get_default();
let textureCache = St.TextureCache.get_default(); let textureCache = St.TextureCache.get_default();
for (let i = 0; i < windows.length; i++) { for (let i = 0; i < windows.length; i++) {
let icon = null; let icon;
let iconName = null; let app = windowTracker.get_window_app(windows[i]);
if (windows[i].get_window_type () == Meta.WindowType.DESKTOP) { if (app)
iconName = 'video-display-symbolic'; icon = app.create_icon_texture(POPUP_APPICON_SIZE);
} else { else
let app = windowTracker.get_window_app(windows[i]); icon = textureCache.bind_pixbuf_property(windows[i], 'icon');
if (app)
icon = app.create_icon_texture(POPUP_APPICON_SIZE);
else
icon = textureCache.bind_pixbuf_property(windows[i], 'icon');
}
items.push({ name: windows[i].title, items.push({ name: windows[i].title,
proxy: windows[i].get_compositor_private(), proxy: windows[i].get_compositor_private(),
focusCallback: Lang.bind(windows[i], focusCallback: Lang.bind(windows[i],
@ -114,7 +109,6 @@ const CtrlAltTabManager = new Lang.Class({
Main.activateWindow(this, timestamp); Main.activateWindow(this, timestamp);
}), }),
iconActor: icon, iconActor: icon,
iconName: iconName,
sortGroup: SortGroup.MIDDLE }); sortGroup: SortGroup.MIDDLE });
} }
} }

View File

@ -49,6 +49,11 @@ const DateMenuButton = new Lang.Class({
menuAlignment = 1.0 - menuAlignment; menuAlignment = 1.0 - menuAlignment;
this.parent(menuAlignment); this.parent(menuAlignment);
// At this moment calendar menu is not keyboard navigable at
// all (so not accessible), so it doesn't make sense to set as
// role ATK_ROLE_MENU like other elements of the panel.
this.actor.accessible_role = Atk.Role.LABEL;
this._clockDisplay = new St.Label(); this._clockDisplay = new St.Label();
this.actor.add_actor(this._clockDisplay); this.actor.add_actor(this._clockDisplay);
@ -85,18 +90,22 @@ const DateMenuButton = new Lang.Class({
this._openCalendarItem = new PopupMenu.PopupMenuItem(_("Open Calendar")); this._openCalendarItem = new PopupMenu.PopupMenuItem(_("Open Calendar"));
this._openCalendarItem.connect('activate', Lang.bind(this, this._onOpenCalendarActivate)); this._openCalendarItem.connect('activate', Lang.bind(this, this._onOpenCalendarActivate));
this._openCalendarItem.actor.can_focus = false;
vbox.add(this._openCalendarItem.actor, {y_align: St.Align.END, expand: true, y_fill: false}); vbox.add(this._openCalendarItem.actor, {y_align: St.Align.END, expand: true, y_fill: false});
this._openClocksItem = new PopupMenu.PopupMenuItem(_("Open Clocks")); this._openClocksItem = new PopupMenu.PopupMenuItem(_("Open Clocks"));
this._openClocksItem.connect('activate', Lang.bind(this, this._onOpenClocksActivate)); this._openClocksItem.connect('activate', Lang.bind(this, this._onOpenClocksActivate));
this._openClocksItem.actor.can_focus = false;
vbox.add(this._openClocksItem.actor, {y_align: St.Align.END, expand: true, y_fill: false}); vbox.add(this._openClocksItem.actor, {y_align: St.Align.END, expand: true, y_fill: false});
Shell.AppSystem.get_default().connect('installed-changed', Shell.AppSystem.get_default().connect('installed-changed',
Lang.bind(this, this._appInstalledChanged)); Lang.bind(this, this._appInstalledChanged));
this._appInstalledChanged();
item = this.menu.addSettingsAction(_("Date & Time Settings"), 'gnome-datetime-panel.desktop'); item = this.menu.addSettingsAction(_("Date & Time Settings"), 'gnome-datetime-panel.desktop');
if (item) { if (item) {
item.actor.show_on_set_parent = false; item.actor.show_on_set_parent = false;
item.actor.can_focus = false;
item.actor.reparent(vbox); item.actor.reparent(vbox);
this._dateAndTimeSeparator = separator; this._dateAndTimeSeparator = separator;
} }
@ -148,16 +157,14 @@ const DateMenuButton = new Lang.Class({
}, },
_appInstalledChanged: function() { _appInstalledChanged: function() {
this._calendarApp = undefined; let app = Shell.AppSystem.get_default().lookup_app('gnome-clocks.desktop');
this._updateEventsVisibility(); this._openClocksItem.actor.visible = app !== null;
}, },
_updateEventsVisibility: function() { _updateEventsVisibility: function() {
let visible = this._eventSource.hasCalendars; let visible = this._eventSource.hasCalendars;
this._openCalendarItem.actor.visible = visible && this._openCalendarItem.actor.visible = visible;
(this._getCalendarApp() != null); this._openClocksItem.actor.visible = visible;
this._openClocksItem.actor.visible = visible &&
(this._getClockApp() != null);
this._separator.visible = visible; this._separator.visible = visible;
if (visible) { if (visible) {
let alignment = 0.25; let alignment = 0.25;
@ -210,34 +217,18 @@ const DateMenuButton = new Lang.Class({
this._date.set_text(displayDate.toLocaleFormat(dateFormat)); this._date.set_text(displayDate.toLocaleFormat(dateFormat));
}, },
_getCalendarApp: function() {
if (this._calendarApp !== undefined)
return this._calendarApp;
let apps = Gio.AppInfo.get_recommended_for_type('text/calendar');
if (apps && (apps.length > 0))
this._calendarApp = apps[0];
else
this._calendarApp = null;
return this._calendarApp;
},
_getClockApp: function() {
return Shell.AppSystem.get_default().lookup_app('gnome-clocks.desktop');
},
_onOpenCalendarActivate: function() { _onOpenCalendarActivate: function() {
this.menu.close(); this.menu.close();
let app = this._getCalendarApp(); let app = Gio.AppInfo.get_default_for_type('text/calendar', false);
if (app.get_id() == 'evolution.desktop') if (app.get_id() == 'evolution')
app = Gio.DesktopAppInfo.new('evolution-calendar.desktop'); app = Gio.DesktopAppInfo.new('evolution-calendar');
app.launch([], global.create_app_launch_context()); app.launch([], global.create_app_launch_context());
}, },
_onOpenClocksActivate: function() { _onOpenClocksActivate: function() {
this.menu.close(); this.menu.close();
let app = this._getClockApp(); let app = Shell.AppSystem.get_default().lookup_app('gnome-clocks.desktop');
app.activate(); app.activate();
} }
}); });

View File

@ -43,7 +43,9 @@ let dragMonitors = [];
function _getEventHandlerActor() { function _getEventHandlerActor() {
if (!eventHandlerActor) { if (!eventHandlerActor) {
eventHandlerActor = new Clutter.Actor({ width: 0, height: 0 }); eventHandlerActor = new Clutter.Rectangle();
eventHandlerActor.width = 0;
eventHandlerActor.height = 0;
Main.uiGroup.add_actor(eventHandlerActor); Main.uiGroup.add_actor(eventHandlerActor);
// We connect to 'event' rather than 'captured-event' because the capturing phase doesn't happen // We connect to 'event' rather than 'captured-event' because the capturing phase doesn't happen
// when you've grabbed the pointer. // when you've grabbed the pointer.
@ -289,19 +291,19 @@ const _Draggable = new Lang.Class({
this._dragOrigY = this._dragActor.y; this._dragOrigY = this._dragActor.y;
this._dragOrigScale = this._dragActor.scale_x; this._dragOrigScale = this._dragActor.scale_x;
// Set the actor's scale such that it will keep the same this._dragActor.reparent(Main.uiGroup);
// transformed size when it's reparented to the uiGroup this._dragActor.raise_top();
let [scaledWidth, scaledHeight] = this.actor.get_transformed_size(); Shell.util_set_hidden_from_pick(this._dragActor, true);
this._dragActor.set_scale(scaledWidth / this.actor.width,
scaledHeight / this.actor.height);
let [actorStageX, actorStageY] = this.actor.get_transformed_position(); let [actorStageX, actorStageY] = this.actor.get_transformed_position();
this._dragOffsetX = actorStageX - this._dragStartX; this._dragOffsetX = actorStageX - this._dragStartX;
this._dragOffsetY = actorStageY - this._dragStartY; this._dragOffsetY = actorStageY - this._dragStartY;
this._dragActor.reparent(Main.uiGroup); // Set the actor's scale such that it will keep the same
this._dragActor.raise_top(); // transformed size when it's reparented to the uiGroup
Shell.util_set_hidden_from_pick(this._dragActor, true); let [scaledWidth, scaledHeight] = this.actor.get_transformed_size();
this.actor.set_scale(scaledWidth / this.actor.width,
scaledHeight / this.actor.height);
} }
this._dragOrigOpacity = this._dragActor.opacity; this._dragOrigOpacity = this._dragActor.opacity;

View File

@ -35,7 +35,7 @@ const GnomeSession = imports.misc.gnomeSession;
const Main = imports.ui.main; const Main = imports.ui.main;
const ModalDialog = imports.ui.modalDialog; const ModalDialog = imports.ui.modalDialog;
const Tweener = imports.ui.tweener; const Tweener = imports.ui.tweener;
const UserAvatar = imports.ui.userAvatar; const UserMenu = imports.ui.userMenu;
let _endSessionDialog = null; let _endSessionDialog = null;
@ -360,9 +360,9 @@ const EndSessionDialog = new Lang.Class({
icon_size: _DIALOG_ICON_SIZE, icon_size: _DIALOG_ICON_SIZE,
style_class: dialogContent.iconStyleClass }); style_class: dialogContent.iconStyleClass });
} else { } else {
let avatarWidget = new UserAvatar.UserAvatar(this._user, let avatarWidget = new UserMenu.UserAvatarWidget(this._user,
{ iconSize: _DIALOG_ICON_SIZE, { iconSize: _DIALOG_ICON_SIZE,
styleClass: dialogContent.iconStyleClass }); styleClass: dialogContent.iconStyleClass });
this._iconBin.child = avatarWidget.actor; this._iconBin.child = avatarWidget.actor;
avatarWidget.update(); avatarWidget.update();
} }

View File

@ -292,7 +292,7 @@ function disableAllExtensions() {
return; return;
if (initted) { if (initted) {
extensionOrder.slice().reverse().forEach(function(uuid) { enabledExtensions.forEach(function(uuid) {
disableExtension(uuid); disableExtension(uuid);
}); });
} }

View File

@ -211,8 +211,10 @@ const GrabHelper = new Lang.Class({
this._grabbedFromKeynav = hadFocus; this._grabbedFromKeynav = hadFocus;
this._preGrabInputMode = global.stage_input_mode; this._preGrabInputMode = global.stage_input_mode;
if (this._preGrabInputMode == Shell.StageInputMode.NORMAL) if (this._preGrabInputMode == Shell.StageInputMode.NONREACTIVE ||
this._preGrabInputMode == Shell.StageInputMode.NORMAL) {
global.set_stage_input_mode(Shell.StageInputMode.FOCUSED); global.set_stage_input_mode(Shell.StageInputMode.FOCUSED);
}
this._keyFocusNotifyId = global.stage.connect('notify::key-focus', Lang.bind(this, this._onKeyFocusChanged)); this._keyFocusNotifyId = global.stage.connect('notify::key-focus', Lang.bind(this, this._onKeyFocusChanged));
this._focusWindowChangedId = metaDisplay.connect('notify::focus-window', Lang.bind(this, this._focusWindowChanged)); this._focusWindowChangedId = metaDisplay.connect('notify::focus-window', Lang.bind(this, this._focusWindowChanged));

View File

@ -118,25 +118,10 @@ const MonitorConstraint = new Lang.Class({
} }
}); });
const Monitor = new Lang.Class({
Name: 'Monitor',
_init: function(index, geometry) {
this.index = index;
this.x = geometry.x;
this.y = geometry.y;
this.width = geometry.width;
this.height = geometry.height;
},
get inFullscreen() {
return global.screen.get_monitor_in_fullscreen(this.index);
}
})
const defaultParams = { const defaultParams = {
trackFullscreen: false, trackFullscreen: false,
affectsStruts: false, affectsStruts: false,
affectsInputRegion: true
}; };
const LayoutManager = new Lang.Class({ const LayoutManager = new Lang.Class({
@ -188,12 +173,10 @@ const LayoutManager = new Lang.Class({
global.stage.remove_actor(global.window_group); global.stage.remove_actor(global.window_group);
this.uiGroup.add_actor(global.window_group); this.uiGroup.add_actor(global.window_group);
global.stage.remove_actor(global.overlay_group);
this.uiGroup.add_actor(global.overlay_group);
global.stage.add_child(this.uiGroup); global.stage.add_child(this.uiGroup);
this.overviewGroup = new St.Widget({ name: 'overviewGroup',
visible: false });
this.addChrome(this.overviewGroup);
this.screenShieldGroup = new St.Widget({ name: 'screenShieldGroup', this.screenShieldGroup = new St.Widget({ name: 'screenShieldGroup',
visible: false, visible: false,
clip_to_allocation: true, clip_to_allocation: true,
@ -244,24 +227,24 @@ const LayoutManager = new Lang.Class({
this._monitorsChanged(); this._monitorsChanged();
}, },
// This is called by Main after everything else is constructed // This is called by Main after everything else is constructed;
// it needs access to Main.overview, which didn't exist
// yet when the LayoutManager was constructed.
init: function() { init: function() {
Main.overview.connect('showing', Lang.bind(this, this._overviewShowing));
Main.overview.connect('hidden', Lang.bind(this, this._overviewHidden));
Main.sessionMode.connect('updated', Lang.bind(this, this._sessionUpdated)); Main.sessionMode.connect('updated', Lang.bind(this, this._sessionUpdated));
this._loadBackground(); this._prepareStartupAnimation();
}, },
showOverview: function() { _overviewShowing: function() {
this.overviewGroup.show();
this._inOverview = true; this._inOverview = true;
this._updateVisibility(); this._updateVisibility();
this._queueUpdateRegions(); this._queueUpdateRegions();
}, },
hideOverview: function() { _overviewHidden: function() {
this.overviewGroup.hide();
this._inOverview = false; this._inOverview = false;
this._updateVisibility(); this._updateVisibility();
this._queueUpdateRegions(); this._queueUpdateRegions();
@ -278,7 +261,7 @@ const LayoutManager = new Lang.Class({
this.monitors = []; this.monitors = [];
let nMonitors = screen.get_n_monitors(); let nMonitors = screen.get_n_monitors();
for (let i = 0; i < nMonitors; i++) for (let i = 0; i < nMonitors; i++)
this.monitors.push(new Monitor(i, screen.get_monitor_geometry(i))); this.monitors.push(screen.get_monitor_geometry(i));
if (nMonitors == 1) { if (nMonitors == 1) {
this.primaryIndex = this.bottomIndex = 0; this.primaryIndex = this.bottomIndex = 0;
@ -300,10 +283,8 @@ const LayoutManager = new Lang.Class({
_updateHotCorners: function() { _updateHotCorners: function() {
// destroy old hot corners // destroy old hot corners
this.hotCorners.forEach(function(corner) { for (let i = 0; i < this.hotCorners.length; i++)
if (corner) this.hotCorners[i].destroy();
corner.destroy();
});
this.hotCorners = []; this.hotCorners = [];
let size = this.panelBox.height; let size = this.panelBox.height;
@ -314,9 +295,9 @@ const LayoutManager = new Lang.Class({
let cornerX = this._rtl ? monitor.x + monitor.width : monitor.x; let cornerX = this._rtl ? monitor.x + monitor.width : monitor.x;
let cornerY = monitor.y; let cornerY = monitor.y;
let haveTopLeftCorner = true;
if (i != this.primaryIndex) { if (i != this.primaryIndex) {
let haveTopLeftCorner = true;
// Check if we have a top left (right for RTL) corner. // Check if we have a top left (right for RTL) corner.
// I.e. if there is no monitor directly above or to the left(right) // I.e. if there is no monitor directly above or to the left(right)
let besideX = this._rtl ? monitor.x + 1 : cornerX - 1; let besideX = this._rtl ? monitor.x + 1 : cornerX - 1;
@ -343,15 +324,14 @@ const LayoutManager = new Lang.Class({
break; break;
} }
} }
if (!haveTopLeftCorner)
continue;
} }
if (haveTopLeftCorner) { let corner = new HotCorner(this, monitor, cornerX, cornerY);
let corner = new HotCorner(this, monitor, cornerX, cornerY); corner.setBarrierSize(size);
corner.setBarrierSize(size); this.hotCorners.push(corner);
this.hotCorners.push(corner);
} else {
this.hotCorners.push(null);
}
} }
this.emit('hot-corners-changed'); this.emit('hot-corners-changed');
@ -428,8 +408,7 @@ const LayoutManager = new Lang.Class({
let size = this.panelBox.height; let size = this.panelBox.height;
this.hotCorners.forEach(function(corner) { this.hotCorners.forEach(function(corner) {
if (corner) corner.setBarrierSize(size);
corner.setBarrierSize(size);
}); });
}, },
@ -557,25 +536,6 @@ const LayoutManager = new Lang.Class({
return this._keyboardIndex; return this._keyboardIndex;
}, },
_loadBackground: function() {
this._systemBackground = new Background.SystemBackground();
this._systemBackground.actor.hide();
global.stage.insert_child_below(this._systemBackground.actor, null);
let constraint = new Clutter.BindConstraint({ source: global.stage,
coordinate: Clutter.BindCoordinate.ALL });
this._systemBackground.actor.add_constraint(constraint);
let signalId = this._systemBackground.connect('loaded', Lang.bind(this, function() {
this._systemBackground.disconnect(signalId);
this._systemBackground.actor.show();
global.stage.show();
this._prepareStartupAnimation();
}));
},
// Startup Animations // Startup Animations
// //
// We have two different animations, depending on whether we're a greeter // We have two different animations, depending on whether we're a greeter
@ -621,18 +581,35 @@ const LayoutManager = new Lang.Class({
global.window_group.set_clip(monitor.x, monitor.y, monitor.width, monitor.height); global.window_group.set_clip(monitor.x, monitor.y, monitor.width, monitor.height);
} }
this.emit('startup-prepared'); this._systemBackground = new Background.SystemBackground();
this._systemBackground.actor.hide();
// We're mostly prepared for the startup animation global.stage.insert_child_below(this._systemBackground.actor, null);
// now, but since a lot is going on asynchronously
// during startup, let's defer the startup animation let constraint = new Clutter.BindConstraint({ source: global.stage,
// until the event loop is uncontended and idle. coordinate: Clutter.BindCoordinate.ALL });
// This helps to prevent us from running the animation this._systemBackground.actor.add_constraint(constraint);
// when the system is bogged down
GLib.idle_add(GLib.PRIORITY_LOW, Lang.bind(this, function() { let signalId = this._systemBackground.connect('loaded',
this._startupAnimation(); Lang.bind(this, function() {
return false; this._systemBackground.disconnect(signalId);
})); this._systemBackground.actor.show();
global.stage.show();
this.emit('startup-prepared');
// We're mostly prepared for the startup animation
// now, but since a lot is going on asynchronously
// during startup, let's defer the startup animation
// until the event loop is uncontended and idle.
// This helps to prevent us from running the animation
// when the system is bogged down
GLib.idle_add(GLib.PRIORITY_LOW,
Lang.bind(this, function() {
this._startupAnimation();
return false;
}));
}));
}, },
_startupAnimation: function() { _startupAnimation: function() {
@ -689,6 +666,7 @@ const LayoutManager = new Lang.Class({
}, },
showKeyboard: function () { showKeyboard: function () {
this.keyboardBox.raise_top();
Tweener.addTween(this.keyboardBox, Tweener.addTween(this.keyboardBox,
{ anchor_y: this.keyboardBox.height, { anchor_y: this.keyboardBox.height,
time: KEYBOARD_ANIMATION_TIME, time: KEYBOARD_ANIMATION_TIME,
@ -733,10 +711,11 @@ const LayoutManager = new Lang.Class({
// @actor: an actor to add to the chrome // @actor: an actor to add to the chrome
// @params: (optional) additional params // @params: (optional) additional params
// //
// Adds @actor to the chrome, and extends the input region // Adds @actor to the chrome, and (unless %affectsInputRegion in
// to include it. Changes in @actor's size, position, and // @params is %false) extends the input region to include it.
// visibility will automatically result in appropriate changes // Changes in @actor's size, position, and visibility will
// to the input region. // automatically result in appropriate changes to the input
// region.
// //
// If %affectsStruts in @params is %true (and @actor is along a // If %affectsStruts in @params is %true (and @actor is along a
// screen edge), then @actor's size and position will also affect // screen edge), then @actor's size and position will also affect
@ -921,8 +900,13 @@ const LayoutManager = new Lang.Class({
}, },
_updateFullscreen: function() { _updateFullscreen: function() {
for (let i = 0; i < this.monitors.length; i++)
this.monitors[i].inFullscreen = global.screen.get_monitor_in_fullscreen (i);
this._updateVisibility(); this._updateVisibility();
this._queueUpdateRegions(); this._queueUpdateRegions();
this.emit('fullscreen-changed');
}, },
_windowsRestacked: function() { _windowsRestacked: function() {
@ -950,7 +934,7 @@ const LayoutManager = new Lang.Class({
for (i = 0; i < this._trackedActors.length; i++) { for (i = 0; i < this._trackedActors.length; i++) {
let actorData = this._trackedActors[i]; let actorData = this._trackedActors[i];
if (!wantsInputRegion && !actorData.affectsStruts) if (!(actorData.affectsInputRegion && wantsInputRegion) && !actorData.affectsStruts)
continue; continue;
let [x, y] = actorData.actor.get_transformed_position(); let [x, y] = actorData.actor.get_transformed_position();
@ -960,8 +944,13 @@ const LayoutManager = new Lang.Class({
w = Math.round(w); w = Math.round(w);
h = Math.round(h); h = Math.round(h);
if (wantsInputRegion && actorData.actor.get_paint_visibility()) if (actorData.affectsInputRegion && wantsInputRegion) {
rects.push(new Meta.Rectangle({ x: x, y: y, width: w, height: h })); let rect = new Meta.Rectangle({ x: x, y: y, width: w, height: h});
if (actorData.actor.get_paint_visibility() &&
!this.uiGroup.get_skip_paint(actorData.actor))
rects.push(rect);
}
if (actorData.affectsStruts) { if (actorData.affectsStruts) {
// Limit struts to the size of the screen // Limit struts to the size of the screen
@ -1103,21 +1092,12 @@ const HotCorner = new Lang.Class({
} }
if (size > 0) { if (size > 0) {
if (Clutter.get_default_text_direction() == Clutter.TextDirection.RTL) { this._verticalBarrier = new Meta.Barrier({ display: global.display,
this._verticalBarrier = new Meta.Barrier({ display: global.display, x1: this._x, x2: this._x, y1: this._y, y2: this._y + size,
x1: this._x, x2: this._x, y1: this._y, y2: this._y + size, directions: Meta.BarrierDirection.POSITIVE_X });
directions: Meta.BarrierDirection.NEGATIVE_X }); this._horizontalBarrier = new Meta.Barrier({ display: global.display,
this._horizontalBarrier = new Meta.Barrier({ display: global.display, x1: this._x, x2: this._x + size, y1: this._y, y2: this._y,
x1: this._x - size, x2: this._x, y1: this._y, y2: this._y, directions: Meta.BarrierDirection.POSITIVE_Y });
directions: Meta.BarrierDirection.POSITIVE_Y });
} else {
this._verticalBarrier = new Meta.Barrier({ display: global.display,
x1: this._x, x2: this._x, y1: this._y, y2: this._y + size,
directions: Meta.BarrierDirection.POSITIVE_X });
this._horizontalBarrier = new Meta.Barrier({ display: global.display,
x1: this._x, x2: this._x + size, y1: this._y, y2: this._y,
directions: Meta.BarrierDirection.POSITIVE_Y });
}
this._pressureBarrier.addBarrier(this._verticalBarrier); this._pressureBarrier.addBarrier(this._verticalBarrier);
this._pressureBarrier.addBarrier(this._horizontalBarrier); this._pressureBarrier.addBarrier(this._horizontalBarrier);
@ -1132,11 +1112,11 @@ const HotCorner = new Lang.Class({
height: 3, height: 3,
reactive: true }); reactive: true });
this._corner = new Clutter.Actor({ name: 'hot-corner', this._corner = new Clutter.Rectangle({ name: 'hot-corner',
width: 1, width: 1,
height: 1, height: 1,
opacity: 0, opacity: 0,
reactive: true }); reactive: true });
this._corner._delegate = this; this._corner._delegate = this;
this.actor.add_child(this._corner); this.actor.add_child(this._corner);

View File

@ -308,6 +308,10 @@ const Result = new Lang.Class({
box.add(resultTxt); box.add(resultTxt);
let objLink = new ObjLink(this._lookingGlass, o); let objLink = new ObjLink(this._lookingGlass, o);
box.add(objLink.actor); box.add(objLink.actor);
let line = new Clutter.Rectangle({ name: 'Separator' });
let padBin = new St.Bin({ name: 'Separator', x_fill: true, y_fill: true });
padBin.add_actor(line);
this.actor.add(padBin);
} }
}); });
@ -985,18 +989,28 @@ const LookingGlass = new Lang.Class({
_showCompletions: function(completions) { _showCompletions: function(completions) {
if (!this._completionActor) { if (!this._completionActor) {
this._completionActor = new St.Label({ name: 'LookingGlassAutoCompletionText', style_class: 'lg-completions-text' }); let actor = new St.BoxLayout({ vertical: true });
this._completionActor.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
this._completionActor.clutter_text.line_wrap = true; this._completionText = new St.Label({ name: 'LookingGlassAutoCompletionText', style_class: 'lg-completions-text' });
this._completionText.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
this._completionText.clutter_text.line_wrap = true;
actor.add(this._completionText);
let line = new Clutter.Rectangle();
let padBin = new St.Bin({ x_fill: true, y_fill: true });
padBin.add_actor(line);
actor.add(padBin);
this._completionActor = actor;
this._evalBox.insert_child_below(this._completionActor, this._entryArea); this._evalBox.insert_child_below(this._completionActor, this._entryArea);
} }
this._completionActor.set_text(completions.join(', ')); this._completionText.set_text(completions.join(', '));
// Setting the height to -1 allows us to get its actual preferred height rather than // Setting the height to -1 allows us to get its actual preferred height rather than
// whatever was last given in set_height by Tweener. // whatever was last given in set_height by Tweener.
this._completionActor.set_height(-1); this._completionActor.set_height(-1);
let [minHeight, naturalHeight] = this._completionActor.get_preferred_height(this._resultsArea.get_width()); let [minHeight, naturalHeight] = this._completionText.get_preferred_height(this._resultsArea.get_width());
// Don't reanimate if we are already visible // Don't reanimate if we are already visible
if (this._completionActor.visible) { if (this._completionActor.visible) {

View File

@ -38,11 +38,9 @@ const Magnifier = imports.ui.magnifier;
const XdndHandler = imports.ui.xdndHandler; const XdndHandler = imports.ui.xdndHandler;
const Util = imports.misc.util; const Util = imports.misc.util;
const OVERRIDES_SCHEMA = 'org.gnome.shell.overrides';
const DEFAULT_BACKGROUND_COLOR = Clutter.Color.from_pixel(0x2e3436ff); const DEFAULT_BACKGROUND_COLOR = Clutter.Color.from_pixel(0x2e3436ff);
const A11Y_SCHEMA = 'org.gnome.desktop.a11y.keyboard';
const STICKY_KEYS_ENABLE = 'stickykeys-enable';
let componentManager = null; let componentManager = null;
let panel = null; let panel = null;
let overview = null; let overview = null;
@ -70,7 +68,7 @@ let layoutManager = null;
let _startDate; let _startDate;
let _defaultCssStylesheet = null; let _defaultCssStylesheet = null;
let _cssStylesheet = null; let _cssStylesheet = null;
let _a11ySettings = null; let _overridesSettings = null;
function _sessionUpdated() { function _sessionUpdated() {
_loadDefaultStylesheet(); _loadDefaultStylesheet();
@ -125,9 +123,11 @@ function _initializeUI() {
// and recalculate application associations, so to avoid // and recalculate application associations, so to avoid
// races for now we initialize it here. It's better to // races for now we initialize it here. It's better to
// be predictable anyways. // be predictable anyways.
Shell.WindowTracker.get_default(); let tracker = Shell.WindowTracker.get_default();
Shell.AppUsage.get_default(); Shell.AppUsage.get_default();
tracker.connect('startup-sequence-changed', _queueCheckWorkspaces);
_loadDefaultStylesheet(); _loadDefaultStylesheet();
// Setup the stage hierarchy early // Setup the stage hierarchy early
@ -157,12 +157,9 @@ function _initializeUI() {
layoutManager.init(); layoutManager.init();
overview.init(); overview.init();
_a11ySettings = new Gio.Settings({ schema: A11Y_SCHEMA }); global.screen.override_workspace_layout(Meta.ScreenCorner.TOPLEFT,
false, -1, 1);
global.display.connect('overlay-key', Lang.bind(overview, function () { global.display.connect('overlay-key', Lang.bind(overview, overview.toggle));
if (!_a11ySettings.get_boolean (STICKY_KEYS_ENABLE))
overview.toggle();
}));
// Provide the bus object for gnome-session to // Provide the bus object for gnome-session to
// initiate logouts. // initiate logouts.
@ -182,6 +179,17 @@ function _initializeUI() {
Scripting.runPerfScript(module, perfOutput); Scripting.runPerfScript(module, perfOutput);
} }
_overridesSettings = new Gio.Settings({ schema: OVERRIDES_SCHEMA });
_overridesSettings.connect('changed::dynamic-workspaces', _queueCheckWorkspaces);
global.screen.connect('notify::n-workspaces', _nWorkspacesChanged);
global.screen.connect('window-entered-monitor', _windowEnteredMonitor);
global.screen.connect('window-left-monitor', _windowLeftMonitor);
global.screen.connect('restacked', _windowsRestacked);
_nWorkspacesChanged();
ExtensionDownloader.init(); ExtensionDownloader.init();
ExtensionSystem.init(); ExtensionSystem.init();
@ -195,12 +203,190 @@ function _initializeUI() {
if (keybindingMode == Shell.KeyBindingMode.NONE) { if (keybindingMode == Shell.KeyBindingMode.NONE) {
keybindingMode = Shell.KeyBindingMode.NORMAL; keybindingMode = Shell.KeyBindingMode.NORMAL;
} }
if (screenShield) {
screenShield.lockIfWasLocked();
}
}); });
} }
let _workspaces = [];
let _checkWorkspacesId = 0;
/*
* When the last window closed on a workspace is a dialog or splash
* screen, we assume that it might be an initial window shown before
* the main window of an application, and give the app a grace period
* where it can map another window before we remove the workspace.
*/
const LAST_WINDOW_GRACE_TIME = 1000;
function _checkWorkspaces() {
let i;
let emptyWorkspaces = [];
if (!Meta.prefs_get_dynamic_workspaces()) {
_checkWorkspacesId = 0;
return false;
}
for (i = 0; i < _workspaces.length; i++) {
let lastRemoved = _workspaces[i]._lastRemovedWindow;
if ((lastRemoved &&
(lastRemoved.get_window_type() == Meta.WindowType.SPLASHSCREEN ||
lastRemoved.get_window_type() == Meta.WindowType.DIALOG ||
lastRemoved.get_window_type() == Meta.WindowType.MODAL_DIALOG)) ||
_workspaces[i]._keepAliveId)
emptyWorkspaces[i] = false;
else
emptyWorkspaces[i] = true;
}
let sequences = Shell.WindowTracker.get_default().get_startup_sequences();
for (i = 0; i < sequences.length; i++) {
let index = sequences[i].get_workspace();
if (index >= 0 && index <= global.screen.n_workspaces)
emptyWorkspaces[index] = false;
}
let windows = global.get_window_actors();
for (i = 0; i < windows.length; i++) {
let win = windows[i];
if (win.get_meta_window().is_on_all_workspaces())
continue;
let workspaceIndex = win.get_workspace();
emptyWorkspaces[workspaceIndex] = false;
}
// If we don't have an empty workspace at the end, add one
if (!emptyWorkspaces[emptyWorkspaces.length -1]) {
global.screen.append_new_workspace(false, global.get_current_time());
emptyWorkspaces.push(false);
}
let activeWorkspaceIndex = global.screen.get_active_workspace_index();
let removingCurrentWorkspace = (emptyWorkspaces[activeWorkspaceIndex] &&
activeWorkspaceIndex < emptyWorkspaces.length - 1);
// Don't enter the overview when removing multiple empty workspaces at startup
let showOverview = (removingCurrentWorkspace &&
!emptyWorkspaces.every(function(x) { return x; }));
if (removingCurrentWorkspace) {
// "Merge" the empty workspace we are removing with the one at the end
wm.blockAnimations();
}
// Delete other empty workspaces; do it from the end to avoid index changes
for (i = emptyWorkspaces.length - 2; i >= 0; i--) {
if (emptyWorkspaces[i])
global.screen.remove_workspace(_workspaces[i], global.get_current_time());
}
if (removingCurrentWorkspace) {
global.screen.get_workspace_by_index(global.screen.n_workspaces - 1).activate(global.get_current_time());
wm.unblockAnimations();
if (!overview.visible && showOverview)
overview.show();
}
_checkWorkspacesId = 0;
return false;
}
function keepWorkspaceAlive(workspace, duration) {
if (workspace._keepAliveId)
Mainloop.source_remove(workspace._keepAliveId);
workspace._keepAliveId = Mainloop.timeout_add(duration, function() {
workspace._keepAliveId = 0;
_queueCheckWorkspaces();
return false;
});
}
function _windowRemoved(workspace, window) {
workspace._lastRemovedWindow = window;
_queueCheckWorkspaces();
Mainloop.timeout_add(LAST_WINDOW_GRACE_TIME, function() {
if (workspace._lastRemovedWindow == window) {
workspace._lastRemovedWindow = null;
_queueCheckWorkspaces();
}
return false;
});
}
function _windowLeftMonitor(metaScreen, monitorIndex, metaWin) {
// If the window left the primary monitor, that
// might make that workspace empty
if (monitorIndex == layoutManager.primaryIndex)
_queueCheckWorkspaces();
}
function _windowEnteredMonitor(metaScreen, monitorIndex, metaWin) {
// If the window entered the primary monitor, that
// might make that workspace non-empty
if (monitorIndex == layoutManager.primaryIndex)
_queueCheckWorkspaces();
}
function _windowsRestacked() {
// Figure out where the pointer is in case we lost track of
// it during a grab. (In particular, if a trayicon popup menu
// is dismissed, see if we need to close the message tray.)
global.sync_pointer();
}
function _queueCheckWorkspaces() {
if (_checkWorkspacesId == 0)
_checkWorkspacesId = Meta.later_add(Meta.LaterType.BEFORE_REDRAW, _checkWorkspaces);
}
function _nWorkspacesChanged() {
let oldNumWorkspaces = _workspaces.length;
let newNumWorkspaces = global.screen.n_workspaces;
if (oldNumWorkspaces == newNumWorkspaces)
return false;
let lostWorkspaces = [];
if (newNumWorkspaces > oldNumWorkspaces) {
let w;
// Assume workspaces are only added at the end
for (w = oldNumWorkspaces; w < newNumWorkspaces; w++)
_workspaces[w] = global.screen.get_workspace_by_index(w);
for (w = oldNumWorkspaces; w < newNumWorkspaces; w++) {
let workspace = _workspaces[w];
workspace._windowAddedId = workspace.connect('window-added', _queueCheckWorkspaces);
workspace._windowRemovedId = workspace.connect('window-removed', _windowRemoved);
}
} else {
// Assume workspaces are only removed sequentially
// (e.g. 2,3,4 - not 2,4,7)
let removedIndex;
let removedNum = oldNumWorkspaces - newNumWorkspaces;
for (let w = 0; w < oldNumWorkspaces; w++) {
let workspace = global.screen.get_workspace_by_index(w);
if (_workspaces[w] != workspace) {
removedIndex = w;
break;
}
}
let lostWorkspaces = _workspaces.splice(removedIndex, removedNum);
lostWorkspaces.forEach(function(workspace) {
workspace.disconnect(workspace._windowAddedId);
workspace.disconnect(workspace._windowRemovedId);
});
}
_queueCheckWorkspaces();
return false;
}
function _loadDefaultStylesheet() { function _loadDefaultStylesheet() {
if (!sessionMode.isPrimary) if (!sessionMode.isPrimary)
return; return;
@ -251,8 +437,7 @@ function loadTheme() {
if (_cssStylesheet != null) if (_cssStylesheet != null)
cssStylesheet = _cssStylesheet; cssStylesheet = _cssStylesheet;
let theme = new St.Theme ({ application_stylesheet: cssStylesheet, let theme = new St.Theme ({ application_stylesheet: cssStylesheet });
default_stylesheet: _defaultCssStylesheet });
if (previousTheme) { if (previousTheme) {
let customStylesheets = previousTheme.get_custom_stylesheets(); let customStylesheets = previousTheme.get_custom_stylesheets();

View File

@ -1530,7 +1530,11 @@ const MessageTrayContextMenu = new Lang.Class({
}, },
_updateClearSensitivity: function() { _updateClearSensitivity: function() {
this._clearItem.setSensitive(this._tray.clearableCount > 0); let sources = this._tray.getSources();
sources = sources.filter(function(source) {
return !source.trayIcon && !source.isChat && !source.resident;
});
this._clearItem.setSensitive(sources.length > 0);
}, },
setPosition: function(x, y) { setPosition: function(x, y) {
@ -1553,22 +1557,23 @@ const MessageTray = new Lang.Class({
this.actor = new St.Widget({ name: 'message-tray', this.actor = new St.Widget({ name: 'message-tray',
reactive: true, reactive: true,
track_hover: true,
layout_manager: new Clutter.BinLayout(), layout_manager: new Clutter.BinLayout(),
x_expand: true, x_expand: true,
y_expand: true, y_expand: true,
y_align: Clutter.ActorAlign.START, y_align: Clutter.ActorAlign.START,
}); });
this.actor.connect('notify::hover', Lang.bind(this, this._onTrayHoverChanged));
this._notificationWidget = new St.Widget({ name: 'notification-container', this._notificationWidget = new St.Widget({ name: 'notification-container',
reactive: true,
track_hover: true,
y_align: Clutter.ActorAlign.START, y_align: Clutter.ActorAlign.START,
x_align: Clutter.ActorAlign.CENTER, x_align: Clutter.ActorAlign.CENTER,
y_expand: true, y_expand: true,
x_expand: true, x_expand: true,
layout_manager: new Clutter.BinLayout() }); layout_manager: new Clutter.BinLayout() });
this._notificationWidget.connect('key-release-event', Lang.bind(this, this._onNotificationKeyRelease)); this._notificationWidget.connect('key-release-event', Lang.bind(this, this._onNotificationKeyRelease));
this._notificationWidget.connect('notify::hover', Lang.bind(this, this._onNotificationHoverChanged));
this.actor.add_actor(this._notificationWidget);
this._notificationBin = new St.Bin({ y_expand: true }); this._notificationBin = new St.Bin({ y_expand: true });
this._notificationBin.set_y_align(Clutter.ActorAlign.START); this._notificationBin.set_y_align(Clutter.ActorAlign.START);
@ -1623,25 +1628,24 @@ const MessageTray = new Lang.Class({
{ keybindingMode: Shell.KeyBindingMode.MESSAGE_TRAY }); { keybindingMode: Shell.KeyBindingMode.MESSAGE_TRAY });
this._grabHelper.addActor(this._summaryBoxPointer.actor); this._grabHelper.addActor(this._summaryBoxPointer.actor);
this._grabHelper.addActor(this.actor); this._grabHelper.addActor(this.actor);
this._grabHelper.addActor(this._notificationWidget);
Main.layoutManager.connect('keyboard-visible-changed', Lang.bind(this, this._onKeyboardVisibleChanged)); Main.layoutManager.connect('keyboard-visible-changed', Lang.bind(this, this._onKeyboardVisibleChanged));
this._trayState = State.HIDDEN; this._trayState = State.HIDDEN;
this._traySummoned = false; this._traySummoned = false;
this._useLongerNotificationLeftTimeout = false; this._useLongerTrayLeftTimeout = false;
this._trayLeftTimeoutId = 0; this._trayLeftTimeoutId = 0;
// pointerInNotification is sort of a misnomer -- it tracks whether // pointerInTray is sort of a misnomer -- it tracks whether
// a message tray notification should expand. The value is // a message tray notification should expand. The value is
// partially driven by the hover state of the notification, but has // partially driven by the hover state of the tray, but has
// a lot of complex state related to timeouts and the current // a lot of complex state related to timeouts and the current
// state of the pointer when a notification pops up. // state of the pointer when a notification pops up.
this._pointerInNotification = false; this._pointerInTray = false;
// This tracks this._notificationWidget.hover and is used to fizzle // This tracks this.actor.hover and is used to fizzle
// out non-changing hover notifications in onNotificationHoverChanged. // out non-changing hover notifications in onTrayHoverChanged.
this._notificationHovered = false; this._trayHovered = false;
this._keyboardVisible = false; this._keyboardVisible = false;
this._notificationClosed = false; this._notificationClosed = false;
@ -1653,29 +1657,23 @@ const MessageTray = new Lang.Class({
this._desktopCloneState = State.HIDDEN; this._desktopCloneState = State.HIDDEN;
this._notificationRemoved = false; this._notificationRemoved = false;
this._reNotifyAfterHideNotification = null; this._reNotifyAfterHideNotification = null;
this._inFullscreen = false;
this._desktopClone = null; this._desktopClone = null;
this._inCtrlAltTab = false; this._inCtrlAltTab = false;
this.clearableCount = 0; this._lightbox = new Lightbox.Lightbox(global.overlay_group,
{ inhibitEvents: true,
this._lightboxes = []; fadeInTime: ANIMATION_TIME,
let lightboxContainers = [global.window_group, fadeOutTime: ANIMATION_TIME,
Main.layoutManager.overviewGroup]; fadeFactor: 0.2
for (let i = 0; i < lightboxContainers.length; i++) });
this._lightboxes.push(new Lightbox.Lightbox(lightboxContainers[i],
{ inhibitEvents: true,
fadeInTime: ANIMATION_TIME,
fadeOutTime: ANIMATION_TIME,
fadeFactor: 0.2
}));
Main.layoutManager.trayBox.add_actor(this.actor); Main.layoutManager.trayBox.add_actor(this.actor);
Main.layoutManager.trayBox.add_actor(this._notificationWidget);
Main.layoutManager.trackChrome(this.actor); Main.layoutManager.trackChrome(this.actor);
Main.layoutManager.trackChrome(this._notificationWidget); Main.layoutManager.trackChrome(this._notificationWidget);
Main.layoutManager.trackChrome(this._closeButton); Main.layoutManager.trackChrome(this._closeButton);
global.screen.connect('in-fullscreen-changed', Lang.bind(this, this._updateState)); Main.layoutManager.connect('fullscreen-changed', Lang.bind(this, this._updateState));
Main.layoutManager.connect('hot-corners-changed', Lang.bind(this, this._hotCornersChanged)); Main.layoutManager.connect('hot-corners-changed', Lang.bind(this, this._hotCornersChanged));
// If the overview shows or hides while we're in // If the overview shows or hides while we're in
@ -1749,7 +1747,7 @@ const MessageTray = new Lang.Class({
let [x, y, mask] = global.get_pointer(); let [x, y, mask] = global.get_pointer();
this._contextMenu.setPosition(Math.round(x), Math.round(y)); this._contextMenu.setPosition(Math.round(x), Math.round(y));
this._grabHelper.grab({ actor: this._contextMenu.actor, this._grabHelper.grab({ actor: this._contextMenu.actor,
modal: true, grabFocus: true,
onUngrab: Lang.bind(this, function () { onUngrab: Lang.bind(this, function () {
this._contextMenu.close(BoxPointer.PopupAnimation.FULL); this._contextMenu.close(BoxPointer.PopupAnimation.FULL);
}) })
@ -1795,12 +1793,12 @@ const MessageTray = new Lang.Class({
y == monitor.y + monitor.height - 1); y == monitor.y + monitor.height - 1);
if (shouldDwell) { if (shouldDwell) {
// We only set up dwell timeout when the user is not hovering over the tray // We only set up dwell timeout when the user is not hovering over the tray
// (!this._notificationHovered). This avoids bringing up the message tray after the // (!this.actor.hover). This avoids bringing up the message tray after the
// user clicks on a notification with the pointer on the bottom pixel // user clicks on a notification with the pointer on the bottom pixel
// of the monitor. The _trayDwelling variable is used so that we only try to // of the monitor. The _trayDwelling variable is used so that we only try to
// fire off one tray dwell - if it fails (because, say, the user has the mouse down), // fire off one tray dwell - if it fails (because, say, the user has the mouse down),
// we don't try again until the user moves the mouse up and down again. // we don't try again until the user moves the mouse up and down again.
if (!this._trayDwelling && !this._notificationHovered && this._trayDwellTimeoutId == 0) { if (!this._trayDwelling && !this.actor.hover && this._trayDwellTimeoutId == 0) {
// Save the interaction timestamp so we can detect user input // Save the interaction timestamp so we can detect user input
let focusWindow = global.display.focus_window; let focusWindow = global.display.focus_window;
this._trayDwellUserTime = focusWindow ? focusWindow.user_time : 0; this._trayDwellUserTime = focusWindow ? focusWindow.user_time : 0;
@ -1898,9 +1896,6 @@ const MessageTray = new Lang.Class({
this._summary.insert_child_at_index(summaryItem.actor, this._chatSummaryItemsCount); this._summary.insert_child_at_index(summaryItem.actor, this._chatSummaryItemsCount);
} }
if (!source.trayIcon && !source.isChat && !source.resident)
this.clearableCount++;
this._sources.set(source, obj); this._sources.set(source, obj);
obj.notifyId = source.connect('notify', Lang.bind(this, this._onNotify)); obj.notifyId = source.connect('notify', Lang.bind(this, this._onNotify));
@ -1942,9 +1937,6 @@ const MessageTray = new Lang.Class({
if (source.isChat) if (source.isChat)
this._chatSummaryItemsCount--; this._chatSummaryItemsCount--;
if (!source.trayIcon && !source.isChat && !source.resident)
this.clearableCount--;
source.disconnect(obj.notifyId); source.disconnect(obj.notifyId);
source.disconnect(obj.destroyId); source.disconnect(obj.destroyId);
source.disconnect(obj.mutedChangedId); source.disconnect(obj.mutedChangedId);
@ -2000,6 +1992,7 @@ const MessageTray = new Lang.Class({
} }
let index = this._notificationQueue.indexOf(notification); let index = this._notificationQueue.indexOf(notification);
notification.destroy();
if (index != -1) if (index != -1)
this._notificationQueue.splice(index, 1); this._notificationQueue.splice(index, 1);
}, },
@ -2028,6 +2021,7 @@ const MessageTray = new Lang.Class({
hide: function() { hide: function() {
this._traySummoned = false; this._traySummoned = false;
this.actor.set_hover(false);
this._updateState(); this._updateState();
}, },
@ -2094,21 +2088,25 @@ const MessageTray = new Lang.Class({
this._grabHelper.addActor(corner.actor); this._grabHelper.addActor(corner.actor);
}, },
_onNotificationHoverChanged: function() { _onTrayHoverChanged: function() {
if (this._notificationWidget.hover == this._notificationHovered) if (this.actor.hover == this._trayHovered)
return; return;
this._notificationHovered = this._notificationWidget.hover; this._trayHovered = this.actor.hover;
if (this._notificationHovered) { if (this._trayHovered) {
// No dwell inside notifications at the bottom of the screen // No dwell inside notifications at the bottom of the screen
this._cancelTrayDwell(); this._cancelTrayDwell();
this._useLongerNotificationLeftTimeout = false; // Don't do anything if the one pixel area at the bottom is hovered over while the tray is hidden.
if (this._notificationLeftTimeoutId) { if (this._trayState == State.HIDDEN && this._notificationState == State.HIDDEN)
Mainloop.source_remove(this._notificationLeftTimeoutId); return;
this._notificationLeftTimeoutId = 0;
this._notificationLeftMouseX = -1; this._useLongerTrayLeftTimeout = false;
this._notificationLeftMouseY = -1; if (this._trayLeftTimeoutId) {
Mainloop.source_remove(this._trayLeftTimeoutId);
this._trayLeftTimeoutId = 0;
this._trayLeftMouseX = -1;
this._trayLeftMouseY = -1;
return; return;
} }
@ -2117,32 +2115,32 @@ const MessageTray = new Lang.Class({
global.stage.get_actor_at_pos(Clutter.PickMode.ALL, this._showNotificationMouseX, this._showNotificationMouseY); global.stage.get_actor_at_pos(Clutter.PickMode.ALL, this._showNotificationMouseX, this._showNotificationMouseY);
this._showNotificationMouseX = -1; this._showNotificationMouseX = -1;
this._showNotificationMouseY = -1; this._showNotificationMouseY = -1;
// Don't set this._pointerInNotification to true if the pointer was initially in the area where the notification // Don't set this._pointerInTray to true if the pointer was initially in the area where the notification
// popped up. That way we will not be expanding notifications that happen to pop up over the pointer // popped up. That way we will not be expanding notifications that happen to pop up over the pointer
// automatically. Instead, the user is able to expand the notification by mousing away from it and then // automatically. Instead, the user is able to expand the notification by mousing away from it and then
// mousing back in. Because this is an expected action, we set the boolean flag that indicates that a longer // mousing back in. Because this is an expected action, we set the boolean flag that indicates that a longer
// timeout should be used before popping down the notification. // timeout should be used before popping down the notification.
if (this.actor.contains(actorAtShowNotificationPosition)) { if (this.actor.contains(actorAtShowNotificationPosition)) {
this._useLongerNotificationLeftTimeout = true; this._useLongerTrayLeftTimeout = true;
return; return;
} }
} }
this._pointerInNotification = true; this._pointerInTray = true;
this._updateState(); this._updateState();
} else { } else {
// We record the position of the mouse the moment it leaves the tray. These coordinates are used in // We record the position of the mouse the moment it leaves the tray. These coordinates are used in
// this._onNotificationLeftTimeout() to determine if the mouse has moved far enough during the initial timeout for us // this._onTrayLeftTimeout() to determine if the mouse has moved far enough during the initial timeout for us
// to consider that the user intended to leave the tray and therefore hide the tray. If the mouse is still // to consider that the user intended to leave the tray and therefore hide the tray. If the mouse is still
// close to its previous position, we extend the timeout once. // close to its previous position, we extend the timeout once.
let [x, y, mods] = global.get_pointer(); let [x, y, mods] = global.get_pointer();
this._notificationLeftMouseX = x; this._trayLeftMouseX = x;
this._notificationLeftMouseY = y; this._trayLeftMouseY = y;
// We wait just a little before hiding the message tray in case the user quickly moves the mouse back into it. // We wait just a little before hiding the message tray in case the user quickly moves the mouse back into it.
// We wait for a longer period if the notification popped up where the mouse pointer was already positioned. // We wait for a longer period if the notification popped up where the mouse pointer was already positioned.
// That gives the user more time to mouse away from the notification and mouse back in in order to expand it. // That gives the user more time to mouse away from the notification and mouse back in in order to expand it.
let timeout = this._useLongerNotificationLeftTimeout ? LONGER_HIDE_TIMEOUT * 1000 : HIDE_TIMEOUT * 1000; let timeout = this._useLongerTrayLeftTimeout ? LONGER_HIDE_TIMEOUT * 1000 : HIDE_TIMEOUT * 1000;
this._notificationLeftTimeoutId = Mainloop.timeout_add(timeout, Lang.bind(this, this._onNotificationLeftTimeout)); this._trayLeftTimeoutId = Mainloop.timeout_add(timeout, Lang.bind(this, this._onTrayLeftTimeout));
} }
}, },
@ -2166,22 +2164,22 @@ const MessageTray = new Lang.Class({
this._updateState(); this._updateState();
}, },
_onNotificationLeftTimeout: function() { _onTrayLeftTimeout: function() {
let [x, y, mods] = global.get_pointer(); let [x, y, mods] = global.get_pointer();
// We extend the timeout once if the mouse moved no further than MOUSE_LEFT_ACTOR_THRESHOLD to either side or up. // We extend the timeout once if the mouse moved no further than MOUSE_LEFT_ACTOR_THRESHOLD to either side or up.
// We don't check how far down the mouse moved because any point above the tray, but below the exit coordinate, // We don't check how far down the mouse moved because any point above the tray, but below the exit coordinate,
// is close to the tray. // is close to the tray.
if (this._notificationLeftMouseX > -1 && if (this._trayLeftMouseX > -1 &&
y > this._notificationLeftMouseY - MOUSE_LEFT_ACTOR_THRESHOLD && y > this._trayLeftMouseY - MOUSE_LEFT_ACTOR_THRESHOLD &&
x < this._notificationLeftMouseX + MOUSE_LEFT_ACTOR_THRESHOLD && x < this._trayLeftMouseX + MOUSE_LEFT_ACTOR_THRESHOLD &&
x > this._notificationLeftMouseX - MOUSE_LEFT_ACTOR_THRESHOLD) { x > this._trayLeftMouseX - MOUSE_LEFT_ACTOR_THRESHOLD) {
this._notificationLeftMouseX = -1; this._trayLeftMouseX = -1;
this._notificationLeftTimeoutId = Mainloop.timeout_add(LONGER_HIDE_TIMEOUT * 1000, this._trayLeftTimeoutId = Mainloop.timeout_add(LONGER_HIDE_TIMEOUT * 1000,
Lang.bind(this, this._onNotificationLeftTimeout)); Lang.bind(this, this._onTrayLeftTimeout));
} else { } else {
this._notificationLeftTimeoutId = 0; this._trayLeftTimeoutId = 0;
this._useLongerNotificationLeftTimeout = false; this._useLongerTrayLeftTimeout = false;
this._pointerInNotification = false; this._pointerInTray = false;
this._updateNotificationTimeout(0); this._updateNotificationTimeout(0);
this._updateState(); this._updateState();
} }
@ -2189,7 +2187,7 @@ const MessageTray = new Lang.Class({
}, },
_escapeTray: function() { _escapeTray: function() {
this._pointerInNotification = false; this._pointerInTray = false;
this._traySummoned = false; this._traySummoned = false;
this._setClickedSummaryItem(null); this._setClickedSummaryItem(null);
this._updateNotificationTimeout(0); this._updateNotificationTimeout(0);
@ -2198,33 +2196,26 @@ const MessageTray = new Lang.Class({
// All of the logic for what happens when occurs here; the various // All of the logic for what happens when occurs here; the various
// event handlers merely update variables such as // event handlers merely update variables such as
// 'this._pointerInNotification', 'this._traySummoned', etc, and // 'this._pointerInTray', 'this._traySummoned', etc, and
// _updateState() figures out what (if anything) needs to be done // _updateState() figures out what (if anything) needs to be done
// at the present time. // at the present time.
_updateState: function() { _updateState: function() {
// Notifications // Notifications
let notificationQueue = this._notificationQueue.filter(function(n) { let notificationQueue = this._notificationQueue;
return !n.acknowledged;
});
let hasNotifications = Main.sessionMode.hasNotifications;
this._notificationQueue = notificationQueue;
let notificationUrgent = notificationQueue.length > 0 && notificationQueue[0].urgency == Urgency.CRITICAL; let notificationUrgent = notificationQueue.length > 0 && notificationQueue[0].urgency == Urgency.CRITICAL;
let notificationForFeedback = notificationQueue.length > 0 && notificationQueue[0].forFeedback; let notificationForFeedback = notificationQueue.length > 0 && notificationQueue[0].forFeedback;
let notificationsLimited = this._busy || Main.layoutManager.bottomMonitor.inFullscreen; let notificationsLimited = this._busy || Main.layoutManager.bottomMonitor.inFullscreen;
let notificationsPending = notificationQueue.length > 0 && (!notificationsLimited || notificationUrgent || notificationForFeedback) && hasNotifications; let notificationsPending = notificationQueue.length > 0 && (!notificationsLimited || notificationUrgent || notificationForFeedback) && Main.sessionMode.hasNotifications;
let nextNotification = notificationQueue.length > 0 ? notificationQueue[0] : null; let nextNotification = notificationQueue.length > 0 ? notificationQueue[0] : null;
let notificationPinned = this._pointerInNotification && !this._notificationRemoved; let notificationPinned = this._pointerInTray && !this._notificationRemoved;
let notificationExpanded = this._notification && this._notification.expanded; let notificationExpanded = this._notification && this._notification.expanded;
let notificationExpired = this._notificationTimeoutId == 0 && let notificationExpired = this._notificationTimeoutId == 0 &&
!(this._notification && this._notification.urgency == Urgency.CRITICAL) && !(this._notification && this._notification.urgency == Urgency.CRITICAL) &&
!(this._notification && this._notification.focused) && !(this._notification && this._notification.focused) &&
!this._pointerInNotification; !this._pointerInTray;
let notificationLockedOut = !hasNotifications && this._notification; let notificationLockedOut = !Main.sessionMode.hasNotifications && this._notification;
let notificationMustClose = (this._notificationRemoved || notificationLockedOut || let notificationMustClose = this._notificationRemoved || notificationLockedOut || (notificationExpired && this._userActiveWhileNotificationShown) || this._notificationClosed;
(notificationExpired && this._userActiveWhileNotificationShown) || let canShowNotification = notificationsPending && this._trayState == State.HIDDEN;
this._notificationClosed || this._traySummoned);
let canShowNotification = notificationsPending && this._trayState == State.HIDDEN && !this._traySummoned;
if (this._notificationState == State.HIDDEN) { if (this._notificationState == State.HIDDEN) {
if (canShowNotification) if (canShowNotification)
@ -2238,6 +2229,12 @@ const MessageTray = new Lang.Class({
this._ensureNotificationFocused(); this._ensureNotificationFocused();
} }
let notificationsVisible = this._notificationState != State.HIDDEN;
let notificationsDone = !notificationsVisible && !notificationsPending;
let mustHideTray = ((notificationsPending && notificationUrgent)
|| notificationsVisible || !Main.sessionMode.hasNotifications);
// Summary notification // Summary notification
let haveClickedSummaryItem = this._clickedSummaryItem != null; let haveClickedSummaryItem = this._clickedSummaryItem != null;
let summarySourceIsMainNotificationSource = (haveClickedSummaryItem && this._notification && let summarySourceIsMainNotificationSource = (haveClickedSummaryItem && this._notification &&
@ -2245,15 +2242,10 @@ const MessageTray = new Lang.Class({
let canShowSummaryBoxPointer = this._trayState == State.SHOWN; let canShowSummaryBoxPointer = this._trayState == State.SHOWN;
// We only have sources with empty notification stacks for legacy tray icons. Currently, we never attempt // We only have sources with empty notification stacks for legacy tray icons. Currently, we never attempt
// to show notifications for legacy tray icons, but this would be necessary if we did. // to show notifications for legacy tray icons, but this would be necessary if we did.
let requestedNotificationStackIsEmpty = (haveClickedSummaryItem && let requestedNotificationStackIsEmpty = (this._clickedSummaryItemMouseButton == 1 && this._clickedSummaryItem.source.notifications.length == 0);
this._clickedSummaryItemMouseButton == 1 && let wrongSummaryNotificationStack = (this._clickedSummaryItemMouseButton == 1 &&
this._clickedSummaryItem.source.notifications.length == 0);
let wrongSummaryNotificationStack = (haveClickedSummaryItem &&
this._clickedSummaryItemMouseButton == 1 &&
this._summaryBoxPointer.bin.child != this._clickedSummaryItem.notificationStackWidget); this._summaryBoxPointer.bin.child != this._clickedSummaryItem.notificationStackWidget);
let wrongSummaryRightClickMenu = (haveClickedSummaryItem && let wrongSummaryRightClickMenu = (this._clickedSummaryItemMouseButton == 3 &&
this._clickedSummaryItemMouseButton == 3 &&
this._clickedSummaryItem.rightClickMenu != null &&
this._summaryBoxPointer.bin.child != this._clickedSummaryItem.rightClickMenu); this._summaryBoxPointer.bin.child != this._clickedSummaryItem.rightClickMenu);
let wrongSummaryBoxPointer = (haveClickedSummaryItem && let wrongSummaryBoxPointer = (haveClickedSummaryItem &&
(wrongSummaryNotificationStack || wrongSummaryRightClickMenu)); (wrongSummaryNotificationStack || wrongSummaryRightClickMenu));
@ -2262,7 +2254,7 @@ const MessageTray = new Lang.Class({
if (haveClickedSummaryItem && !summarySourceIsMainNotificationSource && canShowSummaryBoxPointer && !requestedNotificationStackIsEmpty) if (haveClickedSummaryItem && !summarySourceIsMainNotificationSource && canShowSummaryBoxPointer && !requestedNotificationStackIsEmpty)
this._showSummaryBoxPointer(); this._showSummaryBoxPointer();
} else if (this._summaryBoxPointerState == State.SHOWN) { } else if (this._summaryBoxPointerState == State.SHOWN) {
if (!haveClickedSummaryItem || !canShowSummaryBoxPointer || wrongSummaryBoxPointer || !hasNotifications) { if (!haveClickedSummaryItem || !canShowSummaryBoxPointer || wrongSummaryBoxPointer || mustHideTray) {
this._hideSummaryBoxPointer(); this._hideSummaryBoxPointer();
if (wrongSummaryBoxPointer) if (wrongSummaryBoxPointer)
this._showSummaryBoxPointer(); this._showSummaryBoxPointer();
@ -2272,7 +2264,7 @@ const MessageTray = new Lang.Class({
// Tray itself // Tray itself
let trayIsVisible = (this._trayState == State.SHOWING || let trayIsVisible = (this._trayState == State.SHOWING ||
this._trayState == State.SHOWN); this._trayState == State.SHOWN);
let trayShouldBeVisible = this._traySummoned && !this._keyboardVisible && hasNotifications; let trayShouldBeVisible = this._traySummoned && !this._keyboardVisible && !mustHideTray;
if (!trayIsVisible && trayShouldBeVisible) if (!trayIsVisible && trayShouldBeVisible)
trayShouldBeVisible = this._showTray(); trayShouldBeVisible = this._showTray();
else if (trayIsVisible && !trayShouldBeVisible) else if (trayIsVisible && !trayShouldBeVisible)
@ -2329,8 +2321,7 @@ const MessageTray = new Lang.Class({
transition: 'easeOutQuad' transition: 'easeOutQuad'
}); });
for (let i = 0; i < this._lightboxes.length; i++) this._lightbox.show();
this._lightboxes[i].show();
return true; return true;
}, },
@ -2353,7 +2344,7 @@ const MessageTray = new Lang.Class({
if (this._desktopClone) if (this._desktopClone)
this._desktopClone.destroy(); this._desktopClone.destroy();
let cloneSource = Main.overview.visible ? Main.layoutManager.overviewGroup : global.window_group; let cloneSource = Main.overview.visible ? global.overlay_group : global.window_group;
this._desktopClone = new Clutter.Clone({ source: cloneSource, this._desktopClone = new Clutter.Clone({ source: cloneSource,
clip: new Clutter.Geometry(this._bottomMonitorGeometry) }); clip: new Clutter.Geometry(this._bottomMonitorGeometry) });
Main.uiGroup.insert_child_above(this._desktopClone, cloneSource); Main.uiGroup.insert_child_above(this._desktopClone, cloneSource);
@ -2385,8 +2376,7 @@ const MessageTray = new Lang.Class({
// which would happen if GrabHelper ungrabbed for us. // which would happen if GrabHelper ungrabbed for us.
// This is a no-op in that case. // This is a no-op in that case.
this._grabHelper.ungrab({ actor: this.actor }); this._grabHelper.ungrab({ actor: this.actor });
for (let i = 0; i < this._lightboxes.length; i++) this._lightbox.hide();
this._lightboxes[i].hide();
}, },
_hideDesktopClone: function() { _hideDesktopClone: function() {
@ -2435,7 +2425,7 @@ const MessageTray = new Lang.Class({
let [x, y, mods] = global.get_pointer(); let [x, y, mods] = global.get_pointer();
// We save the position of the mouse at the time when we started showing the notification // We save the position of the mouse at the time when we started showing the notification
// in order to determine if the notification popped up under it. We make that check if // in order to determine if the notification popped up under it. We make that check if
// the user starts moving the mouse and _onNotificationHoverChanged() gets called. We don't // the user starts moving the mouse and _onTrayHoverChanged() gets called. We don't
// expand the notification if it just happened to pop up under the mouse unless the user // expand the notification if it just happened to pop up under the mouse unless the user
// explicitly mouses away from it and then mouses back in. // explicitly mouses away from it and then mouses back in.
this._showNotificationMouseX = x; this._showNotificationMouseX = x;
@ -2497,13 +2487,13 @@ const MessageTray = new Lang.Class({
_notificationTimeout: function() { _notificationTimeout: function() {
let [x, y, mods] = global.get_pointer(); let [x, y, mods] = global.get_pointer();
if (y > this._lastSeenMouseY + 10 && !this._notificationHovered) { if (y > this._lastSeenMouseY + 10 && !this.actor.hover) {
// The mouse is moving towards the notification, so don't // The mouse is moving towards the notification, so don't
// hide it yet. (We just create a new timeout (and destroy // hide it yet. (We just create a new timeout (and destroy
// the old one) each time because the bookkeeping is // the old one) each time because the bookkeeping is
// simpler.) // simpler.)
this._updateNotificationTimeout(1000); this._updateNotificationTimeout(1000);
} else if (this._useLongerNotificationLeftTimeout && !this._notificationLeftTimeoutId && } else if (this._useLongerTrayLeftTimeout && !this._trayLeftTimeoutId &&
(x != this._lastSeenMouseX || y != this._lastSeenMouseY)) { (x != this._lastSeenMouseX || y != this._lastSeenMouseY)) {
// Refresh the timeout if the notification originally // Refresh the timeout if the notification originally
// popped up under the pointer, and the pointer is hovering // popped up under the pointer, and the pointer is hovering
@ -2547,12 +2537,12 @@ const MessageTray = new Lang.Class({
this._notificationUnfocusedId = 0; this._notificationUnfocusedId = 0;
} }
this._useLongerNotificationLeftTimeout = false; this._useLongerTrayLeftTimeout = false;
if (this._notificationLeftTimeoutId) { if (this._trayLeftTimeoutId) {
Mainloop.source_remove(this._notificationLeftTimeoutId); Mainloop.source_remove(this._trayLeftTimeoutId);
this._notificationLeftTimeoutId = 0; this._trayLeftTimeoutId = 0;
this._notificationLeftMouseX = -1; this._trayLeftMouseX = -1;
this._notificationLeftMouseY = -1; this._trayLeftMouseY = -1;
} }
if (this._notificationRemoved) { if (this._notificationRemoved) {
@ -2582,9 +2572,14 @@ const MessageTray = new Lang.Class({
if (notification.isTransient) if (notification.isTransient)
notification.destroy(NotificationDestroyedReason.EXPIRED); notification.destroy(NotificationDestroyedReason.EXPIRED);
this._closeButton.hide();
this._pointerInNotification = false;
this._notificationRemoved = false; this._notificationRemoved = false;
this._closeButton.hide();
this._pointerInTray = false;
// Clutter will send a leave-event the next time the mouse
// moves, but we need to set this here now to update the
// state machine.
this.actor.hover = false;
this._notificationBin.child = null; this._notificationBin.child = null;
this._notificationWidget.hide(); this._notificationWidget.hide();
}, },
@ -2644,37 +2639,38 @@ const MessageTray = new Lang.Class({
}, },
_showSummaryBoxPointer: function() { _showSummaryBoxPointer: function() {
let child; this._summaryBoxPointerItem = this._clickedSummaryItem;
let summaryItem = this._clickedSummaryItem;
if (this._clickedSummaryItemMouseButton == 1) {
// Acknowledge all our notifications
summaryItem.source.notifications.forEach(function(n) { n.acknowledged = true; });
child = summaryItem.notificationStackWidget;
let closeButton = summaryItem.closeButton;
closeButton.show();
this._summaryBoxPointerCloseClickedId = closeButton.connect('clicked', Lang.bind(this, this._hideSummaryBoxPointer));
summaryItem.prepareNotificationStackForShowing();
} else if (this._clickedSummaryItemMouseButton == 3) {
child = summaryItem.rightClickMenu;
this._summaryBoxPointerCloseClickedId = 0;
}
// If the user clicked the middle mouse button, or the item
// doesn't have a right-click menu, do nothing.
if (!child)
return;
this._summaryBoxPointerItem = summaryItem;
this._summaryBoxPointerContentUpdatedId = this._summaryBoxPointerItem.connect('content-updated', this._summaryBoxPointerContentUpdatedId = this._summaryBoxPointerItem.connect('content-updated',
Lang.bind(this, this._onSummaryBoxPointerContentUpdated)); Lang.bind(this, this._onSummaryBoxPointerContentUpdated));
this._sourceDoneDisplayingId = this._summaryBoxPointerItem.source.connect('done-displaying-content', this._sourceDoneDisplayingId = this._summaryBoxPointerItem.source.connect('done-displaying-content',
Lang.bind(this, this._onSourceDoneDisplayingContent)); Lang.bind(this, this._onSourceDoneDisplayingContent));
this._summaryBoxPointer.bin.child = child; let hasRightClickMenu = this._summaryBoxPointerItem.rightClickMenu != null;
if (this._clickedSummaryItemMouseButton == 1 || !hasRightClickMenu) {
let newQueue = [];
for (let i = 0; i < this._notificationQueue.length; i++) {
let notification = this._notificationQueue[i];
let sameSource = this._summaryBoxPointerItem.source == notification.source;
if (sameSource)
notification.acknowledged = true;
else
newQueue.push(notification);
}
this._notificationQueue = newQueue;
this._summaryBoxPointer.bin.child = this._summaryBoxPointerItem.notificationStackWidget;
let closeButton = this._summaryBoxPointerItem.closeButton;
closeButton.show();
this._summaryBoxPointerCloseClickedId = closeButton.connect('clicked', Lang.bind(this, this._hideSummaryBoxPointer));
this._summaryBoxPointerItem.prepareNotificationStackForShowing();
} else if (this._clickedSummaryItemMouseButton == 3) {
this._summaryBoxPointer.bin.child = this._clickedSummaryItem.rightClickMenu;
this._summaryBoxPointerCloseClickedId = 0;
}
this._grabHelper.grab({ actor: this._summaryBoxPointer.bin.child, this._grabHelper.grab({ actor: this._summaryBoxPointer.bin.child,
modal: true, grabFocus: true,
onUngrab: Lang.bind(this, this._onSummaryBoxPointerUngrabbed) }); onUngrab: Lang.bind(this, this._onSummaryBoxPointerUngrabbed) });
this._summaryBoxPointer.actor.opacity = 0; this._summaryBoxPointer.actor.opacity = 0;
@ -2783,14 +2779,17 @@ const MessageTray = new Lang.Class({
this._summaryBoxPointerState = State.HIDDEN; this._summaryBoxPointerState = State.HIDDEN;
this._summaryBoxPointer.bin.child = null; this._summaryBoxPointer.bin.child = null;
let sourceNotificationStackDoneShowing = null;
if (doneShowingNotificationStack) { if (doneShowingNotificationStack) {
let source = this._summaryBoxPointerItem.source;
this._summaryBoxPointerItem.doneShowingNotificationStack(); this._summaryBoxPointerItem.doneShowingNotificationStack();
this._summaryBoxPointerItem = null; sourceNotificationStackDoneShowing = this._summaryBoxPointerItem.source;
}
if (source.isTransient && !this._reNotifyAfterHideNotification) this._summaryBoxPointerItem = null;
source.destroy(NotificationDestroyedReason.EXPIRED);
if (sourceNotificationStackDoneShowing) {
if (sourceNotificationStackDoneShowing.isTransient && !this._reNotifyAfterHideNotification)
sourceNotificationStackDoneShowing.destroy(NotificationDestroyedReason.EXPIRED);
if (this._reNotifyAfterHideNotification) { if (this._reNotifyAfterHideNotification) {
this._onNotify(this._reNotifyAfterHideNotification.source, this._reNotifyAfterHideNotification); this._onNotify(this._reNotifyAfterHideNotification.source, this._reNotifyAfterHideNotification);
this._reNotifyAfterHideNotification = null; this._reNotifyAfterHideNotification = null;

View File

@ -14,7 +14,6 @@ const Atk = imports.gi.Atk;
const Params = imports.misc.params; const Params = imports.misc.params;
const Animation = imports.ui.animation;
const Layout = imports.ui.layout; const Layout = imports.ui.layout;
const Lightbox = imports.ui.lightbox; const Lightbox = imports.ui.lightbox;
const Main = imports.ui.main; const Main = imports.ui.main;
@ -23,10 +22,6 @@ const Tweener = imports.ui.tweener;
const OPEN_AND_CLOSE_TIME = 0.1; const OPEN_AND_CLOSE_TIME = 0.1;
const FADE_OUT_DIALOG_TIME = 1.0; const FADE_OUT_DIALOG_TIME = 1.0;
const WORK_SPINNER_ICON_SIZE = 24;
const WORK_SPINNER_ANIMATION_DELAY = 1.0;
const WORK_SPINNER_ANIMATION_TIME = 0.3;
const State = { const State = {
OPENED: 0, OPENED: 0,
CLOSED: 1, CLOSED: 1,
@ -70,9 +65,7 @@ const ModalDialog = new Lang.Class({
this._group.connect('key-press-event', Lang.bind(this, this._onKeyPressEvent)); this._group.connect('key-press-event', Lang.bind(this, this._onKeyPressEvent));
this._group.connect('key-release-event', Lang.bind(this, this._onKeyReleaseEvent)); this._group.connect('key-release-event', Lang.bind(this, this._onKeyReleaseEvent));
this.backgroundStack = new St.Widget({ layout_manager: new Clutter.BinLayout() }); this._backgroundBin = new St.Bin();
this._backgroundBin = new St.Bin({ child: this.backgroundStack,
x_fill: true, y_fill: true });
this._monitorConstraint = new Layout.MonitorConstraint(); this._monitorConstraint = new Layout.MonitorConstraint();
this._backgroundBin.add_constraint(this._monitorConstraint); this._backgroundBin.add_constraint(this._monitorConstraint);
this._group.add_actor(this._backgroundBin); this._group.add_actor(this._backgroundBin);
@ -88,10 +81,15 @@ const ModalDialog = new Lang.Class({
{ inhibitEvents: true }); { inhibitEvents: true });
this._lightbox.highlight(this._backgroundBin); this._lightbox.highlight(this._backgroundBin);
let stack = new Shell.Stack();
this._backgroundBin.child = stack;
this._eventBlocker = new Clutter.Actor({ reactive: true }); this._eventBlocker = new Clutter.Actor({ reactive: true });
this.backgroundStack.add_actor(this._eventBlocker); stack.add_actor(this._eventBlocker);
stack.add_actor(this.dialogLayout);
} else {
this._backgroundBin.child = this.dialogLayout;
} }
this.backgroundStack.add_actor(this.dialogLayout);
this.contentLayout = new St.BoxLayout({ vertical: true }); this.contentLayout = new St.BoxLayout({ vertical: true });
@ -112,8 +110,6 @@ const ModalDialog = new Lang.Class({
this._initialKeyFocus = this.dialogLayout; this._initialKeyFocus = this.dialogLayout;
this._initialKeyFocusDestroyId = 0; this._initialKeyFocusDestroyId = 0;
this._savedKeyFocus = null; this._savedKeyFocus = null;
this._workSpinner = null;
}, },
destroy: function() { destroy: function() {
@ -187,42 +183,6 @@ const ModalDialog = new Lang.Class({
return button; return button;
}, },
placeSpinner: function(layoutInfo) {
let spinnerIcon = global.datadir + '/theme/process-working.svg';
this._workSpinner = new Animation.AnimatedIcon(spinnerIcon, WORK_SPINNER_ICON_SIZE);
this._workSpinner.actor.opacity = 0;
this._workSpinner.actor.show();
this.buttonLayout.add(this._workSpinner.actor, layoutInfo);
},
setWorking: function(working) {
if (!this._workSpinner)
return;
Tweener.removeTweens(this._workSpinner.actor);
if (working) {
this._workSpinner.play();
Tweener.addTween(this._workSpinner.actor,
{ opacity: 255,
delay: WORK_SPINNER_ANIMATION_DELAY,
time: WORK_SPINNER_ANIMATION_TIME,
transition: 'linear'
});
} else {
Tweener.addTween(this._workSpinner.actor,
{ opacity: 0,
time: WORK_SPINNER_ANIMATION_TIME,
transition: 'linear',
onCompleteScope: this,
onComplete: function() {
if (this._workSpinner)
this._workSpinner.stop();
}
});
}
},
_onKeyPressEvent: function(object, event) { _onKeyPressEvent: function(object, event) {
this._pressedKey = event.get_key_symbol(); this._pressedKey = event.get_key_symbol();
}, },

View File

@ -8,7 +8,6 @@ const Layout = imports.ui.layout;
const Main = imports.ui.main; const Main = imports.ui.main;
const Mainloop = imports.mainloop; const Mainloop = imports.mainloop;
const Tweener = imports.ui.tweener; const Tweener = imports.ui.tweener;
const Meta = imports.gi.Meta;
const HIDE_TIMEOUT = 1500; const HIDE_TIMEOUT = 1500;
const FADE_TIME = 0.1; const FADE_TIME = 0.1;
@ -72,7 +71,6 @@ const OsdWindow = new Lang.Class({
Name: 'OsdWindow', Name: 'OsdWindow',
_init: function() { _init: function() {
this._popupSize = 0;
this.actor = new St.Widget({ x_expand: true, this.actor = new St.Widget({ x_expand: true,
y_expand: true, y_expand: true,
x_align: Clutter.ActorAlign.CENTER, x_align: Clutter.ActorAlign.CENTER,
@ -82,15 +80,6 @@ const OsdWindow = new Lang.Class({
vertical: true }); vertical: true });
this.actor.add_actor(this._box); this.actor.add_actor(this._box);
this._box.connect('style-changed', Lang.bind(this, this._onStyleChanged));
this._box.connect('notify::height', Lang.bind(this,
function() {
Meta.later_add(Meta.LaterType.BEFORE_REDRAW, Lang.bind(this,
function() {
this._box.width = this._box.height;
}));
}));
this._icon = new St.Icon(); this._icon = new St.Icon();
this._box.add(this._icon, { expand: true }); this._box.add(this._icon, { expand: true });
@ -107,7 +96,7 @@ const OsdWindow = new Lang.Class({
Lang.bind(this, this._monitorsChanged)); Lang.bind(this, this._monitorsChanged));
this._monitorsChanged(); this._monitorsChanged();
Main.uiGroup.add_child(this.actor); Main.layoutManager.addChrome(this.actor, { affectsInputRegion: false });
}, },
setIcon: function(icon) { setIcon: function(icon) {
@ -180,25 +169,11 @@ const OsdWindow = new Lang.Class({
let scalew = monitor.width / 640.0; let scalew = monitor.width / 640.0;
let scaleh = monitor.height / 480.0; let scaleh = monitor.height / 480.0;
let scale = Math.min(scalew, scaleh); let scale = Math.min(scalew, scaleh);
this._popupSize = 110 * Math.max(1, scale); let size = 110 * Math.max(1, scale);
this._box.set_size(size, size);
this._box.translation_y = monitor.height / 4; this._box.translation_y = monitor.height / 4;
this._icon.icon_size = this._popupSize / 2;
this._box.style_changed();
},
_onStyleChanged: function() { this._icon.icon_size = size / 2;
let themeNode = this._box.get_theme_node();
let horizontalPadding = themeNode.get_horizontal_padding();
let verticalPadding = themeNode.get_vertical_padding();
let topBorder = themeNode.get_border_width(St.Side.TOP);
let bottomBorder = themeNode.get_border_width(St.Side.BOTTOM);
let leftBorder = themeNode.get_border_width(St.Side.LEFT);
let rightBorder = themeNode.get_border_width(St.Side.RIGHT);
let minWidth = this._popupSize - verticalPadding - leftBorder - rightBorder;
let minHeight = this._popupSize - horizontalPadding - topBorder - bottomBorder;
this._box.style = 'min-height: %dpx;'.format(Math.max(minWidth, minHeight));
} }
}); });

View File

@ -11,6 +11,7 @@ const Shell = imports.gi.Shell;
const Gdk = imports.gi.Gdk; const Gdk = imports.gi.Gdk;
const Background = imports.ui.background; const Background = imports.ui.background;
const Dash = imports.ui.dash;
const DND = imports.ui.dnd; const DND = imports.ui.dnd;
const LayoutManager = imports.ui.layout; const LayoutManager = imports.ui.layout;
const Main = imports.ui.main; const Main = imports.ui.main;
@ -19,6 +20,7 @@ const OverviewControls = imports.ui.overviewControls;
const Panel = imports.ui.panel; const Panel = imports.ui.panel;
const Params = imports.misc.params; const Params = imports.misc.params;
const Tweener = imports.ui.tweener; const Tweener = imports.ui.tweener;
const ViewSelector = imports.ui.viewSelector;
const WorkspaceThumbnail = imports.ui.workspaceThumbnail; const WorkspaceThumbnail = imports.ui.workspaceThumbnail;
// Time for initial animation going into Overview mode // Time for initial animation going into Overview mode
@ -29,7 +31,7 @@ const ANIMATION_TIME = 0.25;
// and don't want the shading animation to get cut off // and don't want the shading animation to get cut off
const SHADE_ANIMATION_TIME = .20; const SHADE_ANIMATION_TIME = .20;
const DND_WINDOW_SWITCH_TIMEOUT = 750; const DND_WINDOW_SWITCH_TIMEOUT = 1250;
const OVERVIEW_ACTIVATION_TIMEOUT = 0.5; const OVERVIEW_ACTIVATION_TIMEOUT = 0.5;
@ -115,7 +117,7 @@ const Overview = new Lang.Class({
let monitor = Main.layoutManager.primaryMonitor; let monitor = Main.layoutManager.primaryMonitor;
this._desktopFade = new St.Bin(); this._desktopFade = new St.Bin();
Main.layoutManager.overviewGroup.add_child(this._desktopFade); global.overlay_group.add_actor(this._desktopFade);
let layout = new Clutter.BinLayout(); let layout = new Clutter.BinLayout();
this._stack = new Clutter.Actor({ layout_manager: layout }); this._stack = new Clutter.Actor({ layout_manager: layout });
@ -131,8 +133,17 @@ const Overview = new Lang.Class({
y_expand: true }); y_expand: true });
this._overview._delegate = this; this._overview._delegate = this;
this._groupStack = new St.Widget({ layout_manager: new Clutter.BinLayout(),
x_expand: true, y_expand: true,
clip_to_allocation: true });
this._group = new St.BoxLayout({ name: 'overview-group',
reactive: true,
x_expand: true, y_expand: true });
this._groupStack.add_actor(this._group);
this._backgroundGroup = new Meta.BackgroundGroup(); this._backgroundGroup = new Meta.BackgroundGroup();
Main.layoutManager.overviewGroup.add_child(this._backgroundGroup); global.overlay_group.add_child(this._backgroundGroup);
this._backgroundGroup.hide();
this._bgManagers = []; this._bgManagers = [];
this._activationTime = 0; this._activationTime = 0;
@ -146,13 +157,14 @@ const Overview = new Lang.Class({
// During transitions, we raise this to the top to avoid having the overview // During transitions, we raise this to the top to avoid having the overview
// area be reactive; it causes too many issues such as double clicks on // area be reactive; it causes too many issues such as double clicks on
// Dash elements, or mouseover handlers in the workspaces. // Dash elements, or mouseover handlers in the workspaces.
this._coverPane = new Clutter.Actor({ opacity: 0, this._coverPane = new Clutter.Rectangle({ opacity: 0,
reactive: true }); reactive: true });
this._overview.add_actor(this._coverPane); this._overview.add_actor(this._coverPane);
this._coverPane.connect('event', Lang.bind(this, function (actor, event) { return true; })); this._coverPane.connect('event', Lang.bind(this, function (actor, event) { return true; }));
this._stack.hide();
this._stack.add_actor(this._overview); this._stack.add_actor(this._overview);
Main.layoutManager.overviewGroup.add_child(this._stack); global.overlay_group.add_actor(this._stack);
this._coverPane.hide(); this._coverPane.hide();
@ -165,6 +177,7 @@ const Overview = new Lang.Class({
Main.xdndHandler.connect('drag-end', Lang.bind(this, this._onDragEnd)); Main.xdndHandler.connect('drag-end', Lang.bind(this, this._onDragEnd));
global.screen.connect('restacked', Lang.bind(this, this._onRestacked)); global.screen.connect('restacked', Lang.bind(this, this._onRestacked));
this._group.connect('scroll-event', Lang.bind(this, this._onScrollEvent));
this._windowSwitchTimeoutId = 0; this._windowSwitchTimeoutId = 0;
this._windowSwitchTimestamp = 0; this._windowSwitchTimestamp = 0;
@ -263,13 +276,28 @@ const Overview = new Lang.Class({
this._overview.add_actor(this._searchEntryBin); this._overview.add_actor(this._searchEntryBin);
// Create controls // Create controls
this._controls = new OverviewControls.ControlsManager(this._searchEntry); this._dash = new Dash.Dash();
this._dash = this._controls.dash; this._viewSelector = new ViewSelector.ViewSelector(this._searchEntry,
this._viewSelector = this._controls.viewSelector; this._dash.showAppsButton);
this._thumbnailsBox = new WorkspaceThumbnail.ThumbnailsBox();
this._controls = new OverviewControls.ControlsManager(this._dash,
this._thumbnailsBox,
this._viewSelector);
this._controls.dashActor.x_align = Clutter.ActorAlign.START;
this._controls.dashActor.y_expand = true;
// Put the dash in a separate layer to allow content to be centered
this._groupStack.add_actor(this._controls.dashActor);
// Pack all the actors into the group
this._group.add_actor(this._controls.dashSpacer);
this._group.add(this._viewSelector.actor, { x_fill: true,
expand: true });
this._group.add_actor(this._controls.thumbnailsActor);
// Add our same-line elements after the search entry // Add our same-line elements after the search entry
this._overview.add(this._controls.actor, { y_fill: true, expand: true }); this._overview.add(this._groupStack, { y_fill: true, expand: true });
this._controls.actor.connect('scroll-event', Lang.bind(this, this._onScrollEvent));
this._stack.add_actor(this._controls.indicatorActor); this._stack.add_actor(this._controls.indicatorActor);
@ -433,7 +461,6 @@ const Overview = new Lang.Class({
beginItemDrag: function(source) { beginItemDrag: function(source) {
this.emit('item-drag-begin'); this.emit('item-drag-begin');
this._inDrag = true;
}, },
cancelledItemDrag: function(source) { cancelledItemDrag: function(source) {
@ -442,12 +469,10 @@ const Overview = new Lang.Class({
endItemDrag: function(source) { endItemDrag: function(source) {
this.emit('item-drag-end'); this.emit('item-drag-end');
this._inDrag = false;
}, },
beginWindowDrag: function(source) { beginWindowDrag: function(source) {
this.emit('window-drag-begin'); this.emit('window-drag-begin');
this._inDrag = true;
}, },
cancelledWindowDrag: function(source) { cancelledWindowDrag: function(source) {
@ -456,31 +481,24 @@ const Overview = new Lang.Class({
endWindowDrag: function(source) { endWindowDrag: function(source) {
this.emit('window-drag-end'); this.emit('window-drag-end');
this._inDrag = false;
}, },
// show: // show:
// //
// Animates the overview visible and grabs mouse and keyboard input // Animates the overview visible and grabs mouse and keyboard input
show: function() { show : function() {
if (this.isDummy) if (this.isDummy)
return; return;
if (this._shown) if (this._shown)
return; return;
this._shown = true; this._shown = true;
if (!this._syncGrab()) if (!this._syncInputMode())
return; return;
Main.layoutManager.showOverview();
this._animateVisible(); this._animateVisible();
}, },
focusSearch: function() {
this.show();
this._searchEntry.grab_key_focus();
},
fadeInDesktop: function() { fadeInDesktop: function() {
this._desktopFade.opacity = 0; this._desktopFade.opacity = 0;
this._desktopFade.show(); this._desktopFade.show();
@ -522,6 +540,8 @@ const Overview = new Lang.Class({
// //
// Disable unredirection while in the overview // Disable unredirection while in the overview
Meta.disable_unredirect_for_screen(global.screen); Meta.disable_unredirect_for_screen(global.screen);
this._stack.show();
this._backgroundGroup.show();
this._viewSelector.show(); this._viewSelector.show();
this._stack.opacity = 0; this._stack.opacity = 0;
@ -562,7 +582,7 @@ const Overview = new Lang.Class({
this._animateNotVisible(); this._animateNotVisible();
this._shown = false; this._shown = false;
this._syncGrab(); this._syncInputMode();
}, },
toggle: function() { toggle: function() {
@ -584,8 +604,6 @@ const Overview = new Lang.Class({
shouldToggleByCornerOrButton: function() { shouldToggleByCornerOrButton: function() {
if (this.animationInProgress) if (this.animationInProgress)
return false; return false;
if (this._inDrag)
return false;
if (this._activationTime == 0 || Date.now() / 1000 - this._activationTime > OVERVIEW_ACTIVATION_TIMEOUT) if (this._activationTime == 0 || Date.now() / 1000 - this._activationTime > OVERVIEW_ACTIVATION_TIMEOUT)
return true; return true;
return false; return false;
@ -593,8 +611,8 @@ const Overview = new Lang.Class({
//// Private methods //// //// Private methods ////
_syncGrab: function() { _syncInputMode: function() {
// We delay grab changes during animation so that when removing the // We delay input mode changes during animation so that when removing the
// overview we don't have a problem with the release of a press/release // overview we don't have a problem with the release of a press/release
// going to an application. // going to an application.
if (this.animationInProgress) if (this.animationInProgress)
@ -612,12 +630,16 @@ const Overview = new Lang.Class({
return false; return false;
} }
} }
} else {
global.stage_input_mode = Shell.StageInputMode.FULLSCREEN;
} }
} else { } else {
if (this._modal) { if (this._modal) {
Main.popModal(this._overview); Main.popModal(this._overview);
this._modal = false; this._modal = false;
} }
else if (global.stage_input_mode == Shell.StageInputMode.FULLSCREEN)
global.stage_input_mode = Shell.StageInputMode.NORMAL;
} }
return true; return true;
}, },
@ -656,7 +678,7 @@ const Overview = new Lang.Class({
if (!this._shown) if (!this._shown)
this._animateNotVisible(); this._animateNotVisible();
this._syncGrab(); this._syncInputMode();
global.sync_pointer(); global.sync_pointer();
}, },
@ -666,19 +688,20 @@ const Overview = new Lang.Class({
this._viewSelector.hide(); this._viewSelector.hide();
this._desktopFade.hide(); this._desktopFade.hide();
this._coverPane.hide(); this._backgroundGroup.hide();
this._stack.hide();
this.visible = false; this.visible = false;
this.animationInProgress = false; this.animationInProgress = false;
this._coverPane.hide();
this.emit('hidden'); this.emit('hidden');
// Handle any calls to show* while we were hiding // Handle any calls to show* while we were hiding
if (this._shown) if (this._shown)
this._animateVisible(); this._animateVisible();
else
Main.layoutManager.hideOverview();
this._syncGrab(); this._syncInputMode();
// Fake a pointer event if requested // Fake a pointer event if requested
if (this._needsFakePointerEvent) { if (this._needsFakePointerEvent) {

View File

@ -1,18 +1,15 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const GObject = imports.gi.GObject;
const Clutter = imports.gi.Clutter; const Clutter = imports.gi.Clutter;
const Lang = imports.lang; const Lang = imports.lang;
const Meta = imports.gi.Meta; const Meta = imports.gi.Meta;
const St = imports.gi.St; const St = imports.gi.St;
const Shell = imports.gi.Shell; const Shell = imports.gi.Shell;
const Dash = imports.ui.dash;
const Main = imports.ui.main; const Main = imports.ui.main;
const Params = imports.misc.params; const Params = imports.misc.params;
const Tweener = imports.ui.tweener; const Tweener = imports.ui.tweener;
const ViewSelector = imports.ui.viewSelector; const ViewSelector = imports.ui.viewSelector;
const WorkspaceThumbnail = imports.ui.workspaceThumbnail;
const SIDE_CONTROLS_ANIMATION_TIME = 0.16; const SIDE_CONTROLS_ANIMATION_TIME = 0.16;
@ -247,7 +244,6 @@ const ThumbnailsSlider = new Lang.Class({
Main.layoutManager.connect('monitors-changed', Lang.bind(this, this.updateSlide)); Main.layoutManager.connect('monitors-changed', Lang.bind(this, this.updateSlide));
this.actor.connect('notify::hover', Lang.bind(this, this.updateSlide)); this.actor.connect('notify::hover', Lang.bind(this, this.updateSlide));
this._thumbnailsBox.actor.bind_property('visible', this.actor, 'visible', GObject.BindingFlags.SYNC_CREATE);
}, },
_getAlwaysZoomOut: function() { _getAlwaysZoomOut: function() {
@ -273,11 +269,6 @@ const ThumbnailsSlider = new Lang.Class({
return alwaysZoomOut; return alwaysZoomOut;
}, },
getNonExpandedWidth: function() {
let child = this.actor.get_first_child();
return child.get_theme_node().get_length('visible-width');
},
getSlide: function() { getSlide: function() {
if (!this.visible) if (!this.visible)
return 0; return 0;
@ -289,16 +280,18 @@ const ThumbnailsSlider = new Lang.Class({
let child = this.actor.get_first_child(); let child = this.actor.get_first_child();
let preferredHeight = child.get_preferred_height(-1)[1]; let preferredHeight = child.get_preferred_height(-1)[1];
let expandedWidth = child.get_preferred_width(preferredHeight)[1]; let expandedWidth = child.get_preferred_width(preferredHeight)[1];
let visibleWidth = child.get_theme_node().get_length('visible-width');
return this.getNonExpandedWidth() / expandedWidth; return visibleWidth / expandedWidth;
}, },
getVisibleWidth: function() { getVisibleWidth: function() {
let alwaysZoomOut = this._getAlwaysZoomOut(); let alwaysZoomOut = this._getAlwaysZoomOut();
if (alwaysZoomOut) if (alwaysZoomOut)
return this.parent(); return this.parent();
else
return this.getNonExpandedWidth(); let child = this.actor.get_first_child();
return child.get_theme_node().get_length('visible-width');
} }
}); });
@ -316,10 +309,6 @@ const DashSlider = new Lang.Class({
// available allocation // available allocation
this._dash.actor.x_expand = true; this._dash.actor.x_expand = true;
this._dash.actor.y_expand = true; this._dash.actor.y_expand = true;
this.actor.x_align = Clutter.ActorAlign.START;
this.actor.y_expand = true;
this.actor.add_actor(this._dash.actor); this.actor.add_actor(this._dash.actor);
this._dash.connect('icon-size-changed', Lang.bind(this, this.updateSlide)); this._dash.connect('icon-size-changed', Lang.bind(this, this.updateSlide));
@ -490,77 +479,39 @@ const MessagesIndicator = new Lang.Class({
const ControlsManager = new Lang.Class({ const ControlsManager = new Lang.Class({
Name: 'ControlsManager', Name: 'ControlsManager',
_init: function(searchEntry) { _init: function(dash, thumbnails, viewSelector) {
this.dash = new Dash.Dash(); this._dashSlider = new DashSlider(dash);
this._dashSlider = new DashSlider(this.dash); this.dashActor = this._dashSlider.actor;
this._dashSpacer = new DashSpacer(); this.dashSpacer = new DashSpacer();
this._dashSpacer.setDashActor(this._dashSlider.actor); this.dashSpacer.setDashActor(this.dashActor);
this._thumbnailsBox = new WorkspaceThumbnail.ThumbnailsBox(); this._thumbnailsSlider = new ThumbnailsSlider(thumbnails);
this._thumbnailsSlider = new ThumbnailsSlider(this._thumbnailsBox); this.thumbnailsActor = this._thumbnailsSlider.actor;
this.viewSelector = new ViewSelector.ViewSelector(searchEntry, this._indicator = new MessagesIndicator(viewSelector);
this.dash.showAppsButton);
this.viewSelector.connect('page-changed', Lang.bind(this, this._setVisibility));
this.viewSelector.connect('page-empty', Lang.bind(this, this._onPageEmpty));
this._indicator = new MessagesIndicator(this.viewSelector);
this.indicatorActor = this._indicator.actor; this.indicatorActor = this._indicator.actor;
this.actor = new St.Widget({ layout_manager: new Clutter.BinLayout(), this._viewSelector = viewSelector;
reactive: true, this._viewSelector.connect('page-changed', Lang.bind(this, this._setVisibility));
x_expand: true, y_expand: true, this._viewSelector.connect('page-empty', Lang.bind(this, this._onPageEmpty));
clip_to_allocation: true });
this._group = new St.BoxLayout({ name: 'overview-group',
x_expand: true, y_expand: true });
this.actor.add_actor(this._group);
this.actor.add_actor(this._dashSlider.actor);
this._group.add_actor(this._dashSpacer);
this._group.add(this.viewSelector.actor, { x_fill: true,
expand: true });
this._group.add_actor(this._thumbnailsSlider.actor);
this._group.connect('notify::allocation', Lang.bind(this, this._updateWorkspacesGeometry));
Main.overview.connect('showing', Lang.bind(this, this._updateSpacerVisibility)); Main.overview.connect('showing', Lang.bind(this, this._updateSpacerVisibility));
Main.overview.connect('item-drag-begin', Lang.bind(this, Main.overview.connect('item-drag-begin', Lang.bind(this,
function() { function() {
let activePage = this.viewSelector.getActivePage(); let activePage = this._viewSelector.getActivePage();
if (activePage != ViewSelector.ViewPage.WINDOWS) if (activePage != ViewSelector.ViewPage.WINDOWS)
this.viewSelector.fadeHalf(); this._viewSelector.fadeHalf();
})); }));
Main.overview.connect('item-drag-end', Lang.bind(this, Main.overview.connect('item-drag-end', Lang.bind(this,
function() { function() {
this.viewSelector.fadeIn(); this._viewSelector.fadeIn();
})); }));
Main.overview.connect('item-drag-cancelled', Lang.bind(this, Main.overview.connect('item-drag-cancelled', Lang.bind(this,
function() { function() {
this.viewSelector.fadeIn(); this._viewSelector.fadeIn();
})); }));
}, },
_updateWorkspacesGeometry: function() {
let [x, y] = this.actor.get_transformed_position();
let [width, height] = this.actor.get_transformed_size();
let geometry = { x: x, y: y, width: width, height: height };
let spacing = this.actor.get_theme_node().get_length('spacing');
let dashWidth = this._dashSlider.getVisibleWidth() + spacing;
let thumbnailsWidth = this._thumbnailsSlider.getNonExpandedWidth() + spacing;
geometry.width -= dashWidth;
geometry.width -= thumbnailsWidth;
if (this.actor.get_text_direction() == Clutter.TextDirection.LTR)
geometry.x += dashWidth;
else
geometry.x += thumbnailsWidth;
this.viewSelector.setWorkspacesFullGeometry(geometry);
},
_setVisibility: function() { _setVisibility: function() {
// Ignore the case when we're leaving the overview, since // Ignore the case when we're leaving the overview, since
// actors will be made visible again when entering the overview // actors will be made visible again when entering the overview
@ -570,7 +521,7 @@ const ControlsManager = new Lang.Class({
(Main.overview.animationInProgress && !Main.overview.visibleTarget)) (Main.overview.animationInProgress && !Main.overview.visibleTarget))
return; return;
let activePage = this.viewSelector.getActivePage(); let activePage = this._viewSelector.getActivePage();
let dashVisible = (activePage == ViewSelector.ViewPage.WINDOWS || let dashVisible = (activePage == ViewSelector.ViewPage.WINDOWS ||
activePage == ViewSelector.ViewPage.APPS); activePage == ViewSelector.ViewPage.APPS);
let thumbnailsVisible = (activePage == ViewSelector.ViewPage.WINDOWS); let thumbnailsVisible = (activePage == ViewSelector.ViewPage.WINDOWS);
@ -590,8 +541,8 @@ const ControlsManager = new Lang.Class({
if (Main.overview.animationInProgress && !Main.overview.visibleTarget) if (Main.overview.animationInProgress && !Main.overview.visibleTarget)
return; return;
let activePage = this.viewSelector.getActivePage(); let activePage = this._viewSelector.getActivePage();
this._dashSpacer.visible = (activePage == ViewSelector.ViewPage.WINDOWS); this.dashSpacer.visible = (activePage == ViewSelector.ViewPage.WINDOWS);
}, },
_onPageEmpty: function() { _onPageEmpty: function() {

View File

@ -15,14 +15,12 @@ const Signals = imports.signals;
const Atk = imports.gi.Atk; const Atk = imports.gi.Atk;
const Animation = imports.ui.animation;
const Config = imports.misc.config; const Config = imports.misc.config;
const CtrlAltTab = imports.ui.ctrlAltTab; const CtrlAltTab = imports.ui.ctrlAltTab;
const DND = imports.ui.dnd; const DND = imports.ui.dnd;
const Overview = imports.ui.overview; const Overview = imports.ui.overview;
const PopupMenu = imports.ui.popupMenu; const PopupMenu = imports.ui.popupMenu;
const PanelMenu = imports.ui.panelMenu; const PanelMenu = imports.ui.panelMenu;
const RemoteMenu = imports.ui.remoteMenu;
const Main = imports.ui.main; const Main = imports.ui.main;
const Tweener = imports.ui.tweener; const Tweener = imports.ui.tweener;
@ -30,6 +28,7 @@ const PANEL_ICON_SIZE = 24;
const BUTTON_DND_ACTIVATION_TIMEOUT = 250; const BUTTON_DND_ACTIVATION_TIMEOUT = 250;
const ANIMATED_ICON_UPDATE_TIMEOUT = 100;
const SPINNER_ANIMATION_TIME = 0.2; const SPINNER_ANIMATION_TIME = 0.2;
// To make sure the panel corners blend nicely with the panel, // To make sure the panel corners blend nicely with the panel,
@ -75,6 +74,81 @@ function _unpremultiply(color) {
blue: blue, alpha: color.alpha }); blue: blue, alpha: color.alpha });
}; };
const Animation = new Lang.Class({
Name: 'Animation',
_init: function(filename, width, height, speed) {
this.actor = new St.Bin();
this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
this._speed = speed;
this._isLoaded = false;
this._isPlaying = false;
this._timeoutId = 0;
this._frame = 0;
this._animations = St.TextureCache.get_default().load_sliced_image (filename, width, height,
Lang.bind(this, this._animationsLoaded));
this.actor.set_child(this._animations);
},
play: function() {
if (this._isLoaded && this._timeoutId == 0) {
if (this._frame == 0)
this._showFrame(0);
this._timeoutId = Mainloop.timeout_add(this._speed, Lang.bind(this, this._update));
}
this._isPlaying = true;
},
stop: function() {
if (this._timeoutId > 0) {
Mainloop.source_remove(this._timeoutId);
this._timeoutId = 0;
}
this._isPlaying = false;
},
_showFrame: function(frame) {
let oldFrameActor = this._animations.get_child_at_index(this._frame);
if (oldFrameActor)
oldFrameActor.hide();
this._frame = (frame % this._animations.get_n_children());
let newFrameActor = this._animations.get_child_at_index(this._frame);
if (newFrameActor)
newFrameActor.show();
},
_update: function() {
this._showFrame(this._frame + 1);
return true;
},
_animationsLoaded: function() {
this._isLoaded = true;
if (this._isPlaying)
this.play();
},
_onDestroy: function() {
this.stop();
}
});
const AnimatedIcon = new Lang.Class({
Name: 'AnimatedIcon',
Extends: Animation,
_init: function(name, size) {
this.parent(global.datadir + '/theme/' + name, size, size, ANIMATED_ICON_UPDATE_TIMEOUT);
}
});
const TextShadower = new Lang.Class({ const TextShadower = new Lang.Class({
Name: 'TextShadower', Name: 'TextShadower',
@ -184,7 +258,6 @@ const AppMenuButton = new Lang.Class({
this._actionGroupNotifyId = 0; this._actionGroupNotifyId = 0;
let bin = new St.Bin({ name: 'appMenu' }); let bin = new St.Bin({ name: 'appMenu' });
bin.connect('style-changed', Lang.bind(this, this._onStyleChanged));
this.actor.add_actor(bin); this.actor.add_actor(bin);
this.actor.bind_property("reactive", this.actor, "can-focus", 0); this.actor.bind_property("reactive", this.actor, "can-focus", 0);
@ -215,25 +288,27 @@ const AppMenuButton = new Lang.Class({
this._visible = !Main.overview.visible; this._visible = !Main.overview.visible;
if (!this._visible) if (!this._visible)
this.actor.hide(); this.actor.hide();
this._overviewHidingId = Main.overview.connect('hiding', Lang.bind(this, function () { Main.overview.connect('hiding', Lang.bind(this, function () {
this.show(); this.show();
})); }));
this._overviewShowingId = Main.overview.connect('showing', Lang.bind(this, function () { Main.overview.connect('showing', Lang.bind(this, function () {
this.hide(); this.hide();
})); }));
this._stop = true; this._stop = true;
this._spinner = null; this._spinner = new AnimatedIcon('process-working.svg',
PANEL_ICON_SIZE);
this._container.add_actor(this._spinner.actor);
this._spinner.actor.hide();
this._spinner.actor.lower_bottom();
let tracker = Shell.WindowTracker.get_default(); let tracker = Shell.WindowTracker.get_default();
let appSys = Shell.AppSystem.get_default(); let appSys = Shell.AppSystem.get_default();
this._focusAppNotifyId = tracker.connect('notify::focus-app', Lang.bind(this, this._focusAppChanged));
tracker.connect('notify::focus-app', Lang.bind(this, this._focusAppChanged)); appSys.connect('app-state-changed', Lang.bind(this, this._onAppStateChanged));
this._appStateChangedSignalId =
appSys.connect('app-state-changed', Lang.bind(this, this._onAppStateChanged)); global.window_manager.connect('switch-workspace', Lang.bind(this, this._sync));
this._switchWorkspaceNotifyId =
global.window_manager.connect('switch-workspace', Lang.bind(this, this._sync));
this._sync(); this._sync();
}, },
@ -279,18 +354,6 @@ const AppMenuButton = new Lang.Class({
onCompleteScope: this }); onCompleteScope: this });
}, },
_onStyleChanged: function(actor) {
let node = actor.get_theme_node();
let [success, icon] = node.lookup_url('spinner-image', false);
if (!success || this._spinnerIcon == icon)
return;
this._spinnerIcon = icon;
this._spinner = new Animation.AnimatedIcon(this._spinnerIcon, PANEL_ICON_SIZE);
this._container.add_actor(this._spinner.actor);
this._spinner.actor.hide();
this._spinner.actor.lower_bottom();
},
_onIconBoxStyleChanged: function() { _onIconBoxStyleChanged: function() {
let node = this._iconBox.get_theme_node(); let node = this._iconBox.get_theme_node();
this._iconBottomClip = node.get_length('app-icon-bottom-clip'); this._iconBottomClip = node.get_length('app-icon-bottom-clip');
@ -322,10 +385,6 @@ const AppMenuButton = new Lang.Class({
this._stop = true; this._stop = true;
this.actor.reactive = true; this.actor.reactive = true;
if (this._spinner == null)
return;
Tweener.addTween(this._spinner.actor, Tweener.addTween(this._spinner.actor,
{ opacity: 0, { opacity: 0,
time: SPINNER_ANIMATION_TIME, time: SPINNER_ANIMATION_TIME,
@ -342,10 +401,6 @@ const AppMenuButton = new Lang.Class({
startAnimation: function() { startAnimation: function() {
this._stop = false; this._stop = false;
this.actor.reactive = false; this.actor.reactive = false;
if (this._spinner == null)
return;
this._spinner.play(); this._spinner.play();
this._spinner.actor.show(); this._spinner.actor.show();
}, },
@ -408,9 +463,6 @@ const AppMenuButton = new Lang.Class({
} }
this._label.actor.allocate(childBox, flags); this._label.actor.allocate(childBox, flags);
if (this._spinner == null)
return;
if (direction == Clutter.TextDirection.LTR) { if (direction == Clutter.TextDirection.LTR) {
childBox.x1 = Math.floor(iconWidth / 2) + this._label.actor.width; childBox.x1 = Math.floor(iconWidth / 2) + this._label.actor.width;
childBox.x2 = childBox.x1 + this._spinner.actor.width; childBox.x2 = childBox.x1 + this._spinner.actor.width;
@ -494,20 +546,14 @@ const AppMenuButton = new Lang.Class({
} }
if (targetApp == this._targetApp) { if (targetApp == this._targetApp) {
if (targetApp && if (targetApp && targetApp.get_state() != Shell.AppState.STARTING) {
targetApp.get_state() != Shell.AppState.STARTING &&
targetApp.get_state() != Shell.AppState.BUSY) {
this.stopAnimation(); this.stopAnimation();
this._maybeSetMenu(); this._maybeSetMenu();
} else if (targetApp &&
targetApp.get_state() == Shell.AppState.BUSY) {
this.startAnimation();
} }
return; return;
} }
if (this._spinner) this._spinner.actor.hide();
this._spinner.actor.hide();
if (this._iconBox.child != null) if (this._iconBox.child != null)
this._iconBox.child.destroy(); this._iconBox.child.destroy();
this._iconBox.hide(); this._iconBox.hide();
@ -534,8 +580,7 @@ const AppMenuButton = new Lang.Class({
this._iconBox.set_child(icon); this._iconBox.set_child(icon);
this._iconBox.show(); this._iconBox.show();
if (targetApp.get_state() == Shell.AppState.STARTING || if (targetApp.get_state() == Shell.AppState.STARTING)
targetApp.get_state() == Shell.AppState.BUSY)
this.startAnimation(); this.startAnimation();
else else
this._maybeSetMenu(); this._maybeSetMenu();
@ -547,11 +592,11 @@ const AppMenuButton = new Lang.Class({
let menu; let menu;
if (this._targetApp.action_group && this._targetApp.menu) { if (this._targetApp.action_group && this._targetApp.menu) {
if (this.menu instanceof RemoteMenu.RemoteMenu && if (this.menu instanceof PopupMenu.RemoteMenu &&
this.menu.actionGroup == this._targetApp.action_group) this.menu.actionGroup == this._targetApp.action_group)
return; return;
menu = new RemoteMenu.RemoteMenu(this.actor, this._targetApp.menu, this._targetApp.action_group); menu = new PopupMenu.RemoteMenu(this.actor, this._targetApp.menu, this._targetApp.action_group);
menu.connect('activate', Lang.bind(this, function() { menu.connect('activate', Lang.bind(this, function() {
let win = this._targetApp.get_windows()[0]; let win = this._targetApp.get_windows()[0];
win.check_alive(global.get_current_time()); win.check_alive(global.get_current_time());
@ -571,33 +616,6 @@ const AppMenuButton = new Lang.Class({
this.setMenu(menu); this.setMenu(menu);
this._menuManager.addMenu(menu); this._menuManager.addMenu(menu);
},
destroy: function() {
if (this._appStateChangedSignalId > 0) {
let appSys = Shell.AppSystem.get_default();
appSys.disconnect(this._appStateChangedSignalId);
this._appStateChangedSignalId = 0;
}
if (this._focusAppNotifyId > 0) {
let tracker = Shell.WindowTracker.get_default();
tracker.disconnect(this._focusAppNotifyId);
this._focusAppNotifyId = 0;
}
if (this._overviewHidingId > 0) {
Main.overview.disconnect(this._overviewHidingId);
this._overviewHidingId = 0;
}
if (this._overviewShowingId > 0) {
Main.overview.disconnect(this._overviewShowingId);
this._overviewShowingId = 0;
}
if (this._switchWorkspaceNotifyId > 0) {
global.window_manager.disconnect(this._switchWorkspaceNotifyId);
this._switchWorkspaceNotifyId = 0;
}
this.parent();
} }
}); });
@ -855,8 +873,9 @@ const PANEL_ITEM_IMPLEMENTATIONS = {
'volume': imports.ui.status.volume.Indicator, 'volume': imports.ui.status.volume.Indicator,
'battery': imports.ui.status.power.Indicator, 'battery': imports.ui.status.power.Indicator,
'lockScreen': imports.ui.status.lockScreenMenu.Indicator, 'lockScreen': imports.ui.status.lockScreenMenu.Indicator,
'logo': imports.gdm.loginDialog.LogoMenuButton,
'keyboard': imports.ui.status.keyboard.InputSourceIndicator, 'keyboard': imports.ui.status.keyboard.InputSourceIndicator,
'powerMenu': imports.ui.auth.powerMenu.PowerMenuButton, 'powerMenu': imports.gdm.powerMenu.PowerMenuButton,
'userMenu': imports.ui.userMenu.UserMenuButton 'userMenu': imports.ui.userMenu.UserMenuButton
}; };
@ -883,7 +902,7 @@ const Panel = new Lang.Class({
this.statusArea = {}; this.statusArea = {};
this.menuManager = new PopupMenu.PopupMenuManager(this, { keybindingMode: Shell.KeyBindingMode.TOPBAR_POPUP }); this.menuManager = new PopupMenu.PopupMenuManager(this);
this._leftBox = new St.BoxLayout({ name: 'panelLeft' }); this._leftBox = new St.BoxLayout({ name: 'panelLeft' });
this.actor.add_actor(this._leftBox); this.actor.add_actor(this._leftBox);
@ -1037,18 +1056,17 @@ const Panel = new Lang.Class({
return true; return true;
}, },
toggleAppMenu: function() { openAppMenu: function() {
let indicator = this.statusArea.appMenu; let indicator = this.statusArea.appMenu;
if (!indicator) // appMenu not supported by current session mode if (!indicator) // appMenu not supported by current session mode
return; return;
let menu = indicator.menu; let menu = indicator.menu;
if (!indicator.actor.reactive) if (!indicator.actor.reactive || menu.isOpen)
return; return;
menu.toggle(); menu.open();
if (menu.isOpen) menu.actor.navigate_focus(null, Gtk.DirectionType.TAB_FORWARD, false);
menu.actor.navigate_focus(null, Gtk.DirectionType.TAB_FORWARD, false);
}, },
set boxOpacity(value) { set boxOpacity(value) {

View File

@ -184,9 +184,6 @@ const Button = new Lang.Class({
}, },
_onMenuKeyPress: function(actor, event) { _onMenuKeyPress: function(actor, event) {
if (global.focus_manager.navigate_from_event(event))
return true;
let symbol = event.get_key_symbol(); let symbol = event.get_key_symbol();
if (symbol == Clutter.KEY_Left || symbol == Clutter.KEY_Right) { if (symbol == Clutter.KEY_Left || symbol == Clutter.KEY_Right) {
let group = global.focus_manager.get_group(this.actor); let group = global.focus_manager.get_group(this.actor);

View File

@ -19,12 +19,6 @@ const Tweener = imports.ui.tweener;
const SLIDER_SCROLL_STEP = 0.05; /* Slider scrolling step in % */ const SLIDER_SCROLL_STEP = 0.05; /* Slider scrolling step in % */
const Ornament = {
NONE: 0,
DOT: 1,
CHECK: 2,
};
function _ensureStyle(actor) { function _ensureStyle(actor) {
if (actor.get_children) { if (actor.get_children) {
let children = actor.get_children(); let children = actor.get_children();
@ -59,9 +53,7 @@ const PopupBaseMenuItem = new Lang.Class({
this.actor._delegate = this; this.actor._delegate = this;
this._children = []; this._children = [];
this._ornament = Ornament.NONE; this._dot = null;
this._ornamentLabel = new St.Label({ style_class: 'popup-menu-ornament' });
this.actor.add_actor(this._ornamentLabel);
this._columnWidths = null; this._columnWidths = null;
this._spacing = 0; this._spacing = 0;
this.active = false; this.active = false;
@ -184,24 +176,40 @@ const PopupBaseMenuItem = new Lang.Class({
this._removeChild(child); this._removeChild(child);
}, },
setOrnament: function(ornament) { setShowDot: function(show) {
if (ornament == this._ornament) if (show) {
return; if (this._dot)
return;
this._ornament = ornament; this._dot = new St.DrawingArea({ style_class: 'popup-menu-item-dot' });
this._dot.connect('repaint', Lang.bind(this, this._onRepaintDot));
this.actor.add_actor(this._dot);
this.actor.add_accessible_state (Atk.StateType.CHECKED);
} else {
if (!this._dot)
return;
if (ornament == Ornament.DOT) { this._dot.destroy();
this._ornamentLabel.text = '\u2022'; this._dot = null;
this.actor.add_accessible_state(Atk.StateType.CHECKED); this.actor.remove_accessible_state (Atk.StateType.CHECKED);
} else if (ornament == Ornament.CHECK) {
this._ornamentLabel.text = '\u2713';
this.actor.add_accessible_state(Atk.StateType.CHECKED);
} else if (ornament == Ornament.NONE) {
this._ornamentLabel.text = '';
this.actor.remove_accessible_state(Atk.StateType.CHECKED);
} }
}, },
_onRepaintDot: function(area) {
let cr = area.get_context();
let [width, height] = area.get_surface_size();
let color = area.get_theme_node().get_foreground_color();
cr.setSourceRGBA (
color.red / 255,
color.green / 255,
color.blue / 255,
color.alpha / 255);
cr.arc(width / 2, height / 2, width / 3, 0, 2 * Math.PI);
cr.fill();
cr.$dispose();
},
// This returns column widths in logical order (i.e. from the dot // This returns column widths in logical order (i.e. from the dot
// to the image), not in visual order (left to right) // to the image), not in visual order (left to right)
getColumnWidths: function() { getColumnWidths: function() {
@ -272,25 +280,26 @@ const PopupBaseMenuItem = new Lang.Class({
let height = box.y2 - box.y1; let height = box.y2 - box.y1;
let direction = this.actor.get_text_direction(); let direction = this.actor.get_text_direction();
// The ornament is placed outside box if (this._dot) {
// one quarter of padding from the border of the container // The dot is placed outside box
// (so 3/4 from the inner border) // one quarter of padding from the border of the container
// (padding is box.x1) // (so 3/4 from the inner border)
let ornamentBox = new Clutter.ActorBox(); // (padding is box.x1)
let ornamentWidth = box.x1; let dotBox = new Clutter.ActorBox();
let dotWidth = Math.round(box.x1 / 2);
ornamentBox.x1 = 0; if (direction == Clutter.TextDirection.LTR) {
ornamentBox.x2 = ornamentWidth; dotBox.x1 = Math.round(box.x1 / 4);
ornamentBox.y1 = box.y1; dotBox.x2 = dotBox.x1 + dotWidth;
ornamentBox.y2 = box.y2; } else {
dotBox.x2 = box.x2 + 3 * Math.round(box.x1 / 4);
if (direction == Clutter.TextDirection.RTL) { dotBox.x1 = dotBox.x2 - dotWidth;
ornamentBox.x1 += box.x2; }
ornamentBox.x2 += box.x2; dotBox.y1 = Math.round(box.y1 + (height - dotWidth) / 2);
dotBox.y2 = dotBox.y1 + dotWidth;
this._dot.allocate(dotBox, flags);
} }
this._ornamentLabel.allocate(ornamentBox, flags);
let x; let x;
if (direction == Clutter.TextDirection.LTR) if (direction == Clutter.TextDirection.LTR)
x = box.x1; x = box.x1;
@ -393,19 +402,12 @@ const PopupSeparatorMenuItem = new Lang.Class({
Name: 'PopupSeparatorMenuItem', Name: 'PopupSeparatorMenuItem',
Extends: PopupBaseMenuItem, Extends: PopupBaseMenuItem,
_init: function (text) { _init: function () {
this.parent({ reactive: false, this.parent({ reactive: false,
can_focus: false}); can_focus: false});
this._box = new St.BoxLayout();
this.addActor(this._box, { span: -1, expand: true });
this.label = new St.Label({ text: text || '' });
this._box.add(this.label);
this.actor.label_actor = this.label;
this._separator = new Separator.HorizontalSeparator({ style_class: 'popup-separator-menu-item' }); this._separator = new Separator.HorizontalSeparator({ style_class: 'popup-separator-menu-item' });
this._box.add(this._separator.actor, { expand: true }); this.addActor(this._separator.actor, { span: -1, expand: true });
} }
}); });
@ -551,10 +553,6 @@ const PopupSliderMenuItem = new Lang.Class({
let handleRadius = themeNode.get_length('-slider-handle-radius'); let handleRadius = themeNode.get_length('-slider-handle-radius');
let handleBorderWidth = themeNode.get_length('-slider-handle-border-width');
let [hasHandleColor, handleBorderColor] =
themeNode.lookup_color('-slider-handle-border-color', false);
let sliderWidth = width - 2 * handleRadius; let sliderWidth = width - 2 * handleRadius;
let sliderHeight = themeNode.get_length('-slider-height'); let sliderHeight = themeNode.get_length('-slider-height');
@ -606,16 +604,7 @@ const PopupSliderMenuItem = new Lang.Class({
color.blue / 255, color.blue / 255,
color.alpha / 255); color.alpha / 255);
cr.arc(handleX, handleY, handleRadius, 0, 2 * Math.PI); cr.arc(handleX, handleY, handleRadius, 0, 2 * Math.PI);
cr.fillPreserve(); cr.fill();
if (hasHandleColor && handleBorderWidth) {
cr.setSourceRGBA(
handleBorderColor.red / 255,
handleBorderColor.green / 255,
handleBorderColor.blue / 255,
handleBorderColor.alpha / 255);
cr.setLineWidth(handleBorderWidth);
cr.stroke();
}
cr.$dispose(); cr.$dispose();
}, },
@ -1003,9 +992,6 @@ const PopupMenuBase = new Lang.Class({
}, },
_updateSeparatorVisibility: function(menuItem) { _updateSeparatorVisibility: function(menuItem) {
if (menuItem.label.text)
return;
let children = this.box.get_children(); let children = this.box.get_children();
let index = children.indexOf(menuItem.actor); let index = children.indexOf(menuItem.actor);
@ -1171,7 +1157,6 @@ const PopupMenuBase = new Lang.Class({
}, },
destroy: function() { destroy: function() {
this.close();
this.removeAll(); this.removeAll();
this.actor.destroy(); this.actor.destroy();
@ -1489,12 +1474,23 @@ const PopupMenuSection = new Lang.Class({
this.actor = this.box; this.actor = this.box;
this.actor._delegate = this; this.actor._delegate = this;
this.isOpen = true; this.isOpen = true;
// an array of externally managed separators
this.separators = [];
}, },
// deliberately ignore any attempt to open() or close(), but emit the // deliberately ignore any attempt to open() or close(), but emit the
// corresponding signal so children can still pick it up // corresponding signal so children can still pick it up
open: function() { this.emit('open-state-changed', true); }, open: function() { this.emit('open-state-changed', true); },
close: function() { this.emit('open-state-changed', false); }, close: function() { this.emit('open-state-changed', false); },
destroy: function() {
for (let i = 0; i < this.separators.length; i++)
this.separators[i].destroy();
this.separators = [];
this.parent();
}
}); });
const PopupSubMenuMenuItem = new Lang.Class({ const PopupSubMenuMenuItem = new Lang.Class({
@ -1529,30 +1525,15 @@ const PopupSubMenuMenuItem = new Lang.Class({
this.parent(); this.parent();
}, },
setSubmenuShown: function(open) {
if (open)
this.menu.open(BoxPointer.PopupAnimation.FULL);
else
this.menu.close(BoxPointer.PopupAnimation.FULL);
},
_setOpenState: function(open) {
this.setSubmenuShown(open);
},
_getOpenState: function() {
return this.menu.isOpen;
},
_onKeyPressEvent: function(actor, event) { _onKeyPressEvent: function(actor, event) {
let symbol = event.get_key_symbol(); let symbol = event.get_key_symbol();
if (symbol == Clutter.KEY_Right) { if (symbol == Clutter.KEY_Right) {
this._setOpenState(true); this.menu.open(BoxPointer.PopupAnimation.FULL);
this.menu.actor.navigate_focus(null, Gtk.DirectionType.DOWN, false); this.menu.actor.navigate_focus(null, Gtk.DirectionType.DOWN, false);
return true; return true;
} else if (symbol == Clutter.KEY_Left && this._getOpenState()) { } else if (symbol == Clutter.KEY_Left && this.menu.isOpen) {
this._setOpenState(false); this.menu.close();
return true; return true;
} }
@ -1560,11 +1541,11 @@ const PopupSubMenuMenuItem = new Lang.Class({
}, },
activate: function(event) { activate: function(event) {
this._setOpenState(true); this.menu.open(BoxPointer.PopupAnimation.FULL);
}, },
_onButtonReleaseEvent: function(actor) { _onButtonReleaseEvent: function(actor) {
this._setOpenState(!this._getOpenState()); this.menu.toggle();
} }
}); });
@ -1810,15 +1791,269 @@ const PopupComboBoxMenuItem = new Lang.Class({
} }
}); });
/**
* RemoteMenu:
*
* A PopupMenu that tracks a GMenuModel and shows its actions
* (exposed by GApplication/GActionGroup)
*/
const RemoteMenu = new Lang.Class({
Name: 'RemoteMenu',
Extends: PopupMenu,
_init: function(sourceActor, model, actionGroup) {
this.parent(sourceActor, 0.0, St.Side.TOP);
this.model = model;
this.actionGroup = actionGroup;
this._actions = { };
this._modelChanged(this.model, 0, 0, this.model.get_n_items(), this);
this._actionStateChangeId = this.actionGroup.connect('action-state-changed', Lang.bind(this, this._actionStateChanged));
this._actionEnableChangeId = this.actionGroup.connect('action-enabled-changed', Lang.bind(this, this._actionEnabledChanged));
},
destroy: function() {
if (this._actionStateChangeId) {
this.actionGroup.disconnect(this._actionStateChangeId);
this._actionStateChangeId = 0;
}
if (this._actionEnableChangeId) {
this.actionGroup.disconnect(this._actionEnableChangeId);
this._actionEnableChangeId = 0;
}
this.parent();
},
_createMenuItem: function(model, index) {
let labelValue = model.get_item_attribute_value(index, Gio.MENU_ATTRIBUTE_LABEL, null);
let label = labelValue ? labelValue.deep_unpack() : '';
// remove all underscores that are not followed by another underscore
label = label.replace(/_([^_])/, '$1');
let section_link = model.get_item_link(index, Gio.MENU_LINK_SECTION);
if (section_link) {
let item = new PopupMenuSection();
if (label) {
let title = new PopupMenuItem(label, { reactive: false,
style_class: 'popup-subtitle-menu-item' });
item._titleMenuItem = title;
title._ignored = true;
item.addMenuItem(title);
}
this._modelChanged(section_link, 0, 0, section_link.get_n_items(), item);
return [item, true, ''];
}
let submenu_link = model.get_item_link(index, Gio.MENU_LINK_SUBMENU);
if (submenu_link) {
let item = new PopupSubMenuMenuItem(label);
this._modelChanged(submenu_link, 0, 0, submenu_link.get_n_items(), item.menu);
return [item, false, ''];
}
let action_id = model.get_item_attribute_value(index, Gio.MENU_ATTRIBUTE_ACTION, null).deep_unpack();
if (!this.actionGroup.has_action(action_id)) {
// the action may not be there yet, wait for action-added
return [null, false, 'action-added'];
}
if (!this._actions[action_id])
this._actions[action_id] = { enabled: this.actionGroup.get_action_enabled(action_id),
state: this.actionGroup.get_action_state(action_id),
items: [ ],
};
let action = this._actions[action_id];
let item, target, destroyId, specificSignalId;
if (action.state) {
// Docs have get_state_hint(), except that the DBus protocol
// has no provision for it (so ShellApp does not implement it,
// and neither GApplication), and g_action_get_state_hint()
// always returns null
// Funny :)
switch (String.fromCharCode(action.state.classify())) {
case 'b':
item = new PopupSwitchMenuItem(label, action.state.get_boolean());
action.items.push(item);
specificSignalId = item.connect('toggled', Lang.bind(this, function(item) {
this.actionGroup.activate_action(action_id, null);
}));
break;
case 's':
item = new PopupMenuItem(label);
item._remoteTarget = model.get_item_attribute_value(index, Gio.MENU_ATTRIBUTE_TARGET, null).deep_unpack();
action.items.push(item);
item.setShowDot(action.state.deep_unpack() == item._remoteTarget);
specificSignalId = item.connect('activate', Lang.bind(this, function(item) {
this.actionGroup.activate_action(action_id, GLib.Variant.new_string(item._remoteTarget));
}));
break;
default:
log('Action "%s" has state of type %s, which is not supported'.format(action_id, action.state.get_type_string()));
return [null, false, 'action-state-changed'];
}
} else {
target = model.get_item_attribute_value(index, Gio.MENU_ATTRIBUTE_TARGET, null);
item = new PopupMenuItem(label);
action.items.push(item);
specificSignalId = item.connect('activate', Lang.bind(this, function() {
this.actionGroup.activate_action(action_id, target);
}));
}
item.actor.reactive = item.actor.can_focus = action.enabled;
destroyId = item.connect('destroy', Lang.bind(this, function() {
item.disconnect(destroyId);
item.disconnect(specificSignalId);
let pos = action.items.indexOf(item);
if (pos != -1)
action.items.splice(pos, 1);
}));
return [item, false, ''];
},
_modelChanged: function(model, position, removed, added, target) {
let j, k;
let j0, k0;
let currentItems = target._getMenuItems();
k0 = 0;
// skip ignored items at the beginning
while (k0 < currentItems.length && currentItems[k0]._ignored)
k0++;
// find the right menu item matching the model item
for (j0 = 0; k0 < currentItems.length && j0 < position; j0++, k0++) {
if (currentItems[k0]._ignored)
k0++;
}
if (removed == -1) {
// special flag to indicate we should destroy everything
for (k = k0; k < currentItems.length; k++)
currentItems[k].destroy();
} else {
for (j = j0, k = k0; k < currentItems.length && j < j0 + removed; j++, k++) {
currentItems[k].destroy();
if (currentItems[k]._ignored)
j--;
}
}
for (j = j0, k = k0; j < j0 + added; j++, k++) {
let [item, addSeparator, changeSignal] = this._createMenuItem(model, j);
if (item) {
// separators must be added in the parent to make autohiding work
if (addSeparator) {
let separator = new PopupSeparatorMenuItem();
item.separators.push(separator);
separator._ignored = true;
target.addMenuItem(separator, k+1);
k++;
}
target.addMenuItem(item, k);
if (addSeparator) {
let separator = new PopupSeparatorMenuItem();
item.separators.push(separator);
separator._ignored = true;
target.addMenuItem(separator, k+1);
k++;
}
} else if (changeSignal) {
let signalId = this.actionGroup.connect(changeSignal, Lang.bind(this, function(actionGroup, actionName) {
actionGroup.disconnect(signalId);
if (this._actions[actionName]) return;
// force a full update
this._modelChanged(model, 0, -1, model.get_n_items(), target);
}));
}
}
if (!model._changedId) {
model._changedId = model.connect('items-changed', Lang.bind(this, this._modelChanged, target));
model._destroyId = target.connect('destroy', function() {
if (model._changedId)
model.disconnect(model._changedId);
if (model._destroyId)
target.disconnect(model._destroyId);
model._changedId = 0;
model._destroyId = 0;
});
}
if (target instanceof PopupMenuSection) {
if (target._titleMenuItem)
target.actor.visible = target.numMenuItems != 1;
else
target.actor.visible = target.numMenuItems != 0;
} else {
let sourceItem = target.sourceActor._delegate;
if (sourceItem instanceof PopupSubMenuMenuItem)
sourceItem.actor.visible = target.numMenuItems != 0;
}
},
_actionStateChanged: function(actionGroup, action_id) {
let action = this._actions[action_id];
if (!action)
return;
action.state = actionGroup.get_action_state(action_id);
if (action.items.length) {
switch (String.fromCharCode(action.state.classify())) {
case 'b':
for (let i = 0; i < action.items.length; i++)
action.items[i].setToggleState(action.state.get_boolean());
break;
case 'd':
for (let i = 0; i < action.items.length; i++)
action.items[i].setValue(action.state.get_double());
break;
case 's':
for (let i = 0; i < action.items.length; i++)
action.items[i].setShowDot(action.items[i]._remoteTarget == action.state.deep_unpack());
}
}
},
_actionEnabledChanged: function(actionGroup, action_id) {
let action = this._actions[action_id];
if (!action)
return;
action.enabled = actionGroup.get_action_enabled(action_id);
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;
}
}
}
});
/* Basic implementation of a menu manager. /* Basic implementation of a menu manager.
* Call addMenu to add menus * Call addMenu to add menus
*/ */
const PopupMenuManager = new Lang.Class({ const PopupMenuManager = new Lang.Class({
Name: 'PopupMenuManager', Name: 'PopupMenuManager',
_init: function(owner, grabParams) { _init: function(owner) {
this._owner = owner; this._owner = owner;
this._grabHelper = new GrabHelper.GrabHelper(owner.actor, grabParams); this._grabHelper = new GrabHelper.GrabHelper(owner.actor);
this._menus = []; this._menus = [];
}, },
@ -1888,8 +2123,6 @@ const PopupMenuManager = new Lang.Class({
_onMenuOpenState: function(menu, open) { _onMenuOpenState: function(menu, open) {
if (open) { if (open) {
if (this.activeMenu && !this.activeMenu.isChildMenu(menu))
this.activeMenu.close(BoxPointer.PopupAnimation.FADE);
this._grabHelper.grab({ actor: menu.actor, modal: true, focus: menu.sourceActor, this._grabHelper.grab({ actor: menu.actor, modal: true, focus: menu.sourceActor,
onUngrab: Lang.bind(this, this._closeMenu, menu) }); onUngrab: Lang.bind(this, this._closeMenu, menu) });
} else { } else {
@ -1906,8 +2139,13 @@ const PopupMenuManager = new Lang.Class({
}, },
_changeMenu: function(newMenu) { _changeMenu: function(newMenu) {
newMenu.open(this.activeMenu ? BoxPointer.PopupAnimation.FADE let oldMenu = this.activeMenu;
: BoxPointer.PopupAnimation.FULL); if (oldMenu) {
oldMenu.close(BoxPointer.PopupAnimation.FADE);
newMenu.open(BoxPointer.PopupAnimation.FADE);
} else {
newMenu.open(BoxPointer.PopupAnimation.FULL);
}
}, },
_onMenuSourceEnter: function(menu) { _onMenuSourceEnter: function(menu) {

View File

@ -1,199 +0,0 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Atk = imports.gi.Atk;
const GLib = imports.gi.GLib;
const GObject = imports.gi.GObject;
const Gio = imports.gi.Gio;
const Lang = imports.lang;
const Shell = imports.gi.Shell;
const ShellMenu = imports.gi.ShellMenu;
const St = imports.gi.St;
const PopupMenu = imports.ui.popupMenu;
function stripMnemonics(label) {
if (!label)
return '';
// remove all underscores that are not followed by another underscore
return label.replace(/_([^_])/, '$1');
}
function _insertItem(menu, trackerItem, position) {
let mapper;
if (trackerItem.get_is_separator())
mapper = new RemoteMenuSeparatorItemMapper(trackerItem);
else if (trackerItem.get_has_submenu())
mapper = new RemoteMenuSubmenuItemMapper(trackerItem);
else
mapper = new RemoteMenuItemMapper(trackerItem);
let item = mapper.menuItem;
menu.addMenuItem(item, position);
}
function _removeItem(menu, position) {
let items = menu._getMenuItems();
items[position].destroy();
}
const RemoteMenuSeparatorItemMapper = new Lang.Class({
Name: 'RemoteMenuSeparatorItemMapper',
_init: function(trackerItem) {
this._trackerItem = trackerItem;
this.menuItem = new PopupMenu.PopupSeparatorMenuItem();
this._trackerItem.connect('notify::label', Lang.bind(this, this._updateLabel));
this._updateLabel();
this.menuItem.connect('destroy', function() {
trackerItem.run_dispose();
});
},
_updateLabel: function() {
this.menuItem.label.text = stripMnemonics(this._trackerItem.label);
},
});
const RequestSubMenu = new Lang.Class({
Name: 'RequestSubMenu',
Extends: PopupMenu.PopupSubMenuMenuItem,
_init: function() {
this.parent('');
this._requestOpen = false;
},
_setOpenState: function(open) {
this.emit('request-open', open);
this._requestOpen = open;
},
_getOpenState: function() {
return this._requestOpen;
},
});
const RemoteMenuSubmenuItemMapper = new Lang.Class({
Name: 'RemoteMenuSubmenuItemMapper',
_init: function(trackerItem) {
this._trackerItem = trackerItem;
this.menuItem = new RequestSubMenu();
this._trackerItem.connect('notify::label', Lang.bind(this, this._updateLabel));
this._updateLabel();
this._tracker = Shell.MenuTracker.new_for_item_submenu(this._trackerItem,
_insertItem.bind(null, this.menuItem.menu),
_removeItem.bind(null, this.menuItem.menu));
this.menuItem.connect('request-open', Lang.bind(this, function(menu, open) {
this._trackerItem.request_submenu_shown(open);
}));
this._trackerItem.connect('notify::submenu-shown', Lang.bind(this, function() {
this.menuItem.setSubmenuShown(this._trackerItem.get_submenu_shown());
}));
this.menuItem.connect('destroy', function() {
trackerItem.run_dispose();
});
},
destroy: function() {
this._tracker.destroy();
this.parent();
},
_updateLabel: function() {
this.menuItem.label.text = stripMnemonics(this._trackerItem.label);
},
});
const RemoteMenuItemMapper = new Lang.Class({
Name: 'RemoteMenuItemMapper',
_init: function(trackerItem) {
this._trackerItem = trackerItem;
this.menuItem = new PopupMenu.PopupBaseMenuItem();
this._label = new St.Label();
this.menuItem.addActor(this._label);
this.menuItem.actor.label_actor = this._label;
this.menuItem.connect('activate', Lang.bind(this, function() {
this._trackerItem.activated();
}));
this._trackerItem.bind_property('visible', this.menuItem.actor, 'visible', GObject.BindingFlags.SYNC_CREATE);
this._trackerItem.connect('notify::label', Lang.bind(this, this._updateLabel));
this._trackerItem.connect('notify::sensitive', Lang.bind(this, this._updateSensitivity));
this._trackerItem.connect('notify::role', Lang.bind(this, this._updateRole));
this._trackerItem.connect('notify::toggled', Lang.bind(this, this._updateDecoration));
this._updateLabel();
this._updateSensitivity();
this._updateRole();
this.menuItem.connect('destroy', function() {
trackerItem.run_dispose();
});
},
_updateLabel: function() {
this._label.text = stripMnemonics(this._trackerItem.label);
},
_updateSensitivity: function() {
this.menuItem.setSensitive(this._trackerItem.sensitive);
},
_updateDecoration: function() {
let ornamentForRole = {};
ornamentForRole[ShellMenu.MenuTrackerItemRole.RADIO] = PopupMenu.Ornament.DOT;
ornamentForRole[ShellMenu.MenuTrackerItemRole.CHECK] = PopupMenu.Ornament.CHECK;
let ornament = PopupMenu.Ornament.NONE;
if (this._trackerItem.toggled)
ornament = ornamentForRole[this._trackerItem.role];
this.menuItem.setOrnament(ornament);
},
_updateRole: function() {
let a11yRoles = {};
a11yRoles[ShellMenu.MenuTrackerItemRole.NORMAL] = Atk.Role.MENU_ITEM;
a11yRoles[ShellMenu.MenuTrackerItemRole.RADIO] = Atk.Role.RADIO_MENU_ITEM;
a11yRoles[ShellMenu.MenuTrackerItemRole.CHECK] = Atk.Role.CHECK_MENU_ITEM;
let a11yRole = a11yRoles[this._trackerItem.role];
this.menuItem.actor.accessible_role = a11yRole;
this._updateDecoration();
},
});
const RemoteMenu = new Lang.Class({
Name: 'RemoteMenu',
Extends: PopupMenu.PopupMenu,
_init: function(sourceActor, model, actionGroup) {
this.parent(sourceActor, 0.0, St.Side.TOP);
this._model = model;
this._actionGroup = actionGroup;
this._tracker = Shell.MenuTracker.new(this._actionGroup,
this._model,
null, /* action namespace */
_insertItem.bind(null, this),
_removeItem.bind(null, this));
},
destroy: function() {
this._tracker.destroy();
this.parent();
},
});

View File

@ -187,9 +187,7 @@ const RemoteSearchProvider = new Lang.Class({
createIcon: function(size, meta) { createIcon: function(size, meta) {
let gicon; let gicon;
if (meta['icon']) { if (meta['gicon']) {
gicon = Gio.icon_deserialize(meta['icon']);
} else if (meta['gicon']) {
gicon = Gio.icon_new_for_string(meta['gicon']); gicon = Gio.icon_new_for_string(meta['gicon']);
} else if (meta['icon-data']) { } else if (meta['icon-data']) {
let [width, height, rowStride, hasAlpha, let [width, height, rowStride, hasAlpha,
@ -205,7 +203,7 @@ const RemoteSearchProvider = new Lang.Class({
_getResultsFinished: function(results, error) { _getResultsFinished: function(results, error) {
if (error) if (error)
return; return;
this.searchSystem.setResults(this, results[0]); this.searchSystem.pushResults(this, results[0]);
}, },
getInitialResultSet: function(terms) { getInitialResultSet: function(terms) {
@ -217,7 +215,7 @@ const RemoteSearchProvider = new Lang.Class({
this._cancellable); this._cancellable);
} catch(e) { } catch(e) {
log('Error calling GetInitialResultSet for provider %s: %s'.format(this.id, e.toString())); log('Error calling GetInitialResultSet for provider %s: %s'.format(this.id, e.toString()));
this.searchSystem.setResults(this, []); this.searchSystem.pushResults(this, []);
} }
}, },
@ -230,7 +228,7 @@ const RemoteSearchProvider = new Lang.Class({
this._cancellable); this._cancellable);
} catch(e) { } catch(e) {
log('Error calling GetSubsearchResultSet for provider %s: %s'.format(this.id, e.toString())); log('Error calling GetSubsearchResultSet for provider %s: %s'.format(this.id, e.toString()));
this.searchSystem.setResults(this, []); this.searchSystem.pushResults(this, []);
} }
}, },
@ -242,12 +240,8 @@ const RemoteSearchProvider = new Lang.Class({
let metas = results[0]; let metas = results[0];
let resultMetas = []; let resultMetas = [];
for (let i = 0; i < metas.length; i++) { for (let i = 0; i < metas.length; i++) {
for (let prop in metas[i]) { for (let prop in metas[i])
// we can use the serialized icon variant directly metas[i][prop] = metas[i][prop].deep_unpack();
if (prop != 'icon')
metas[i][prop] = metas[i][prop].deep_unpack();
}
resultMetas.push({ id: metas[i]['id'], resultMetas.push({ id: metas[i]['id'],
name: metas[i]['name'], name: metas[i]['name'],
description: metas[i]['description'], description: metas[i]['description'],

View File

@ -35,8 +35,7 @@ const RunDialog = new Lang.Class({
Extends: ModalDialog.ModalDialog, Extends: ModalDialog.ModalDialog,
_init : function() { _init : function() {
this.parent({ styleClass: 'run-dialog', this.parent({ styleClass: 'run-dialog' });
destroyOnClose: false });
this._lockdownSettings = new Gio.Settings({ schema: LOCKDOWN_SCHEMA }); this._lockdownSettings = new Gio.Settings({ schema: LOCKDOWN_SCHEMA });
this._terminalSettings = new Gio.Settings({ schema: TERMINAL_SCHEMA }); this._terminalSettings = new Gio.Settings({ schema: TERMINAL_SCHEMA });

View File

@ -30,7 +30,6 @@ const SCREENSAVER_SCHEMA = 'org.gnome.desktop.screensaver';
const LOCK_ENABLED_KEY = 'lock-enabled'; const LOCK_ENABLED_KEY = 'lock-enabled';
const LOCK_DELAY_KEY = 'lock-delay'; const LOCK_DELAY_KEY = 'lock-delay';
const LOCKED_STATE_STR = 'screenShield.locked';
// fraction of screen height the arrow must reach before completing // fraction of screen height the arrow must reach before completing
// the slide up automatically // the slide up automatically
const ARROW_DRAG_THRESHOLD = 0.1; const ARROW_DRAG_THRESHOLD = 0.1;
@ -215,7 +214,6 @@ const NotificationsBox = new Lang.Class({
if (musicNotification != null && if (musicNotification != null &&
this._musicBin.child == null) { this._musicBin.child == null) {
musicNotification.acknowledged = true;
if (musicNotification.actor.get_parent() != null) if (musicNotification.actor.get_parent() != null)
musicNotification.actor.get_parent().remove_actor(musicNotification.actor); musicNotification.actor.get_parent().remove_actor(musicNotification.actor);
this._musicBin.child = musicNotification.actor; this._musicBin.child = musicNotification.actor;
@ -248,7 +246,6 @@ const NotificationsBox = new Lang.Class({
sourceCountChangedId: 0, sourceCountChangedId: 0,
sourceTitleChangedId: 0, sourceTitleChangedId: 0,
sourceUpdatedId: 0, sourceUpdatedId: 0,
sourceNotifyId: 0,
musicNotification: null, musicNotification: null,
sourceBox: null, sourceBox: null,
titleLabel: null, titleLabel: null,
@ -259,12 +256,6 @@ const NotificationsBox = new Lang.Class({
this._showSource(source, obj, obj.sourceBox); this._showSource(source, obj, obj.sourceBox);
this._notificationBox.add(obj.sourceBox, { x_fill: false, x_align: St.Align.START }); this._notificationBox.add(obj.sourceBox, { x_fill: false, x_align: St.Align.START });
if (obj.musicNotification) {
obj.sourceNotifyId = source.connect('notify', Lang.bind(this, function(source, notification) {
notification.acknowledged = true;
}));
}
obj.sourceCountChangedId = source.connect('count-updated', Lang.bind(this, function(source) { obj.sourceCountChangedId = source.connect('count-updated', Lang.bind(this, function(source) {
this._countChanged(source, obj); this._countChanged(source, obj);
})); }));
@ -345,8 +336,6 @@ const NotificationsBox = new Lang.Class({
if (obj.musicNotification) { if (obj.musicNotification) {
this._musicBin.child = null; this._musicBin.child = null;
obj.musicNotification = null; obj.musicNotification = null;
source.disconnect(obj.sourceNotifyId);
} }
source.disconnect(obj.sourceDestroyId); source.disconnect(obj.sourceDestroyId);
@ -573,7 +562,6 @@ const ScreenShield = new Lang.Class({
this._bgManagers[i].destroy(); this._bgManagers[i].destroy();
this._bgManagers = []; this._bgManagers = [];
this._backgroundGroup.destroy_all_children();
for (let i = 0; i < Main.layoutManager.monitors.length; i++) for (let i = 0; i < Main.layoutManager.monitors.length; i++)
this._createBackground(i); this._createBackground(i);
@ -1126,22 +1114,11 @@ const ScreenShield = new Lang.Class({
deactivate: function(animate) { deactivate: function(animate) {
this._hideLockScreen(animate, 0); this._hideLockScreen(animate, 0);
if (this._hasLockScreen)
this._clearLockScreen();
if (Main.sessionMode.currentMode == 'lock-screen') if (Main.sessionMode.currentMode == 'lock-screen')
Main.sessionMode.popMode('lock-screen'); Main.sessionMode.popMode('lock-screen');
if (Main.sessionMode.currentMode == 'unlock-dialog') if (Main.sessionMode.currentMode == 'unlock-dialog')
Main.sessionMode.popMode('unlock-dialog'); Main.sessionMode.popMode('unlock-dialog');
if (this._dialog && !this._isGreeter)
this._dialog.popModal();
if (this._isModal) {
Main.popModal(this.actor);
this._isModal = false;
}
Tweener.addTween(this._lockDialogGroup, { Tweener.addTween(this._lockDialogGroup, {
scale_x: 0, scale_x: 0,
scale_y: 0, scale_y: 0,
@ -1153,12 +1130,21 @@ const ScreenShield = new Lang.Class({
}, },
_completeDeactivate: function() { _completeDeactivate: function() {
if (this._hasLockScreen)
this._clearLockScreen();
if (this._dialog && !this._isGreeter) { if (this._dialog && !this._isGreeter) {
this._dialog.destroy(); this._dialog.destroy();
this._dialog = null; this._dialog = null;
} }
this._lightbox.hide(); this._lightbox.hide();
if (this._isModal) {
Main.popModal(this.actor);
this._isModal = false;
}
this.actor.hide(); this.actor.hide();
if (this._becameActiveId != 0) { if (this._becameActiveId != 0) {
@ -1176,7 +1162,6 @@ const ScreenShield = new Lang.Class({
this._isLocked = false; this._isLocked = false;
this.emit('active-changed'); this.emit('active-changed');
this.emit('locked-changed'); this.emit('locked-changed');
global.set_runtime_state(LOCKED_STATE_STR, null);
}, },
activate: function(animate) { activate: function(animate) {
@ -1193,7 +1178,6 @@ const ScreenShield = new Lang.Class({
} }
this._resetLockScreen(animate, animate); this._resetLockScreen(animate, animate);
global.set_runtime_state(LOCKED_STATE_STR, GLib.Variant.new('b', true));
// We used to set isActive and emit active-changed here, // We used to set isActive and emit active-changed here,
// but now we do that from lockScreenShown, which means // but now we do that from lockScreenShown, which means
@ -1220,15 +1204,5 @@ const ScreenShield = new Lang.Class({
this.emit('locked-changed'); this.emit('locked-changed');
}, },
// If the previous shell crashed, and gnome-session restarted us, then re-lock
lockIfWasLocked: function() {
let wasLocked = global.get_runtime_state('b', LOCKED_STATE_STR);
if (wasLocked === null)
return;
Meta.later_add(Meta.LaterType.BEFORE_REDRAW, Lang.bind(this, function() {
this.lock(false);
}));
}
}); });
Signals.addSignalMethods(ScreenShield.prototype); Signals.addSignalMethods(ScreenShield.prototype);

View File

@ -1,140 +0,0 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const Lang = imports.lang;
const Shell = imports.gi.Shell;
const Hash = imports.misc.hash;
const Main = imports.ui.main;
const ScreencastIface = <interface name="org.gnome.Shell.Screencast">
<method name="Screencast">
<arg type="s" direction="in" name="file_template"/>
<arg type="a{sv}" direction="in" name="options"/>
<arg type="b" direction="out" name="success"/>
<arg type="s" direction="out" name="filename_used"/>
</method>
<method name="ScreencastArea">
<arg type="i" direction="in" name="x"/>
<arg type="i" direction="in" name="y"/>
<arg type="i" direction="in" name="width"/>
<arg type="i" direction="in" name="height"/>
<arg type="s" direction="in" name="file_template"/>
<arg type="a{sv}" direction="in" name="options"/>
<arg type="b" direction="out" name="success"/>
<arg type="s" direction="out" name="filename_used"/>
</method>
<method name="StopScreencast">
<arg type="b" direction="out" name="success"/>
</method>
</interface>;
const ScreencastService = new Lang.Class({
Name: 'ScreencastService',
_init: function() {
this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(ScreencastIface, this);
this._dbusImpl.export(Gio.DBus.session, '/org/gnome/Shell/Screencast');
Gio.DBus.session.own_name('org.gnome.Shell.Screencast', Gio.BusNameOwnerFlags.REPLACE, null, null);
this._recorders = new Hash.Map();
Main.sessionMode.connect('updated',
Lang.bind(this, this._sessionModeChanged));
},
_ensureRecorderForSender: function(sender) {
let recorder = this._recorders.get(sender);
if (!recorder) {
recorder = new Shell.Recorder({ stage: global.stage });
recorder._watchNameId =
Gio.bus_watch_name(Gio.BusType.SESSION, sender, 0, null,
Lang.bind(this, this._onNameVanished));
this._recorders.set(sender, recorder);
}
return recorder;
},
_sessionModeChanged: function() {
if (Main.sessionMode.allowScreencast)
return;
for (let sender in this._recorders.keys())
this._recorders.delete(sender);
},
_onNameVanished: function(connection, name) {
this._stopRecordingForSender(name);
},
_stopRecordingForSender: function(sender) {
let recorder = this._recorders.get(sender);
if (!recorder)
return false;
Gio.bus_unwatch_name(recorder._watchNameId);
recorder.close();
this._recorders.delete(sender);
return true;
},
_applyOptionalParameters: function(recorder, options) {
for (let option in options)
options[option] = options[option].deep_unpack();
if (options['pipeline'])
recorder.set_pipeline(options['pipeline']);
if (options['framerate'])
recorder.set_framerate(options['framerate']);
if (options['draw-cursor'])
recorder.set_draw_cursor(options['draw-cursor']);
},
ScreencastAsync: function(params, invocation) {
let returnValue = [false, ''];
if (!Main.sessionMode.allowScreencast)
invocation.return_value(GLib.Variant.new('(bs)', returnValue));
let sender = invocation.get_sender();
let recorder = this._ensureRecorderForSender(sender);
if (!recorder.is_recording()) {
let [fileTemplate, options] = params;
recorder.set_file_template(fileTemplate);
this._applyOptionalParameters(recorder, options);
let [success, fileName] = recorder.record();
returnValue = [success, fileName ? fileName : ''];
}
invocation.return_value(GLib.Variant.new('(bs)', returnValue));
},
ScreencastAreaAsync: function(params, invocation) {
let returnValue = [false, ''];
if (!Main.sessionMode.allowScreencast)
invocation.return_value(GLib.Variant.new('(bs)', returnValue));
let sender = invocation.get_sender();
let recorder = this._ensureRecorderForSender(sender);
if (!recorder.is_recording()) {
let [x, y, width, height, fileTemplate, options] = params;
recorder.set_file_template(fileTemplate);
recorder.set_area(x, y, width, height);
this._applyOptionalParameters(recorder, options);
let [success, fileName] = recorder.record();
returnValue = [success, fileName ? fileName : ''];
}
invocation.return_value(GLib.Variant.new('(bs)', returnValue));
},
StopScreencastAsync: function(params, invocation) {
let success = this._stopRecordingForSender(invocation.get_sender());
invocation.return_value(GLib.Variant.new('(b)', [success]));
}
});

View File

@ -51,7 +51,7 @@ const SearchSystem = new Lang.Class({
this._previousResults = []; this._previousResults = [];
}, },
setResults: function(provider, results) { pushResults: function(provider, results) {
let i = this._providers.indexOf(provider); let i = this._providers.indexOf(provider);
if (i == -1) if (i == -1)
return; return;

View File

@ -180,82 +180,13 @@ const GridSearchResult = new Lang.Class({
} }
}); });
const SearchResultsBase = new Lang.Class({ const ListSearchResults = new Lang.Class({
Name: 'SearchResultsBase', Name: 'ListSearchResults',
_init: function(provider) { _init: function(provider) {
this.provider = provider; this.provider = provider;
this._terms = []; this.actor = new St.BoxLayout({ style_class: 'search-section-content' });
this.actor = new St.BoxLayout({ style_class: 'search-section',
vertical: true });
this._resultDisplayBin = new St.Bin({ x_fill: true,
y_fill: true });
this.actor.add(this._resultDisplayBin, { expand: true });
let separator = new Separator.HorizontalSeparator({ style_class: 'search-section-separator' });
this.actor.add(separator.actor);
},
destroy: function() {
this.actor.destroy();
this._terms = [];
},
_clearResultDisplay: function() {
},
clear: function() {
this._clearResultDisplay();
this.actor.hide();
},
_keyFocusIn: function(icon) {
this.emit('key-focus-in', icon);
},
_setMoreIconVisible: function(visible) {
},
updateSearch: function(providerResults, terms, callback) {
this._terms = terms;
if (providerResults.length == 0) {
this._clearResultDisplay();
this.actor.hide();
callback();
} else {
let maxResults = this._getMaxDisplayedResults();
let results = providerResults.slice(0, maxResults);
let hasMoreResults = results.length < providerResults.length;
this.provider.getResultMetas(results, Lang.bind(this, function(metas) {
this.clear();
// To avoid CSS transitions causing flickering when
// the first search result stays the same, we hide the
// content while filling in the results.
this.actor.hide();
this._clearResultDisplay();
this._renderResults(metas);
this._setMoreIconVisible(hasMoreResults && this.provider.canLaunchSearch);
this.actor.show();
callback();
}));
}
}
});
const ListSearchResults = new Lang.Class({
Name: 'ListSearchResults',
Extends: SearchResultsBase,
_init: function(provider) {
this.parent(provider);
this._container = new St.BoxLayout({ style_class: 'search-section-content' });
this.providerIcon = new ProviderIcon(provider); this.providerIcon = new ProviderIcon(provider);
this.providerIcon.connect('clicked', Lang.bind(this, this.providerIcon.connect('clicked', Lang.bind(this,
function() { function() {
@ -263,27 +194,48 @@ const ListSearchResults = new Lang.Class({
Main.overview.toggle(); Main.overview.toggle();
})); }));
this._container.add(this.providerIcon, { x_fill: false, this.actor.add(this.providerIcon, { x_fill: false,
y_fill: false, y_fill: false,
x_align: St.Align.START, x_align: St.Align.START,
y_align: St.Align.START }); y_align: St.Align.START });
this._content = new St.BoxLayout({ style_class: 'list-search-results', this._content = new St.BoxLayout({ style_class: 'list-search-results',
vertical: true }); vertical: true });
this._container.add(this._content, { expand: true }); this.actor.add(this._content, { expand: true });
this._resultDisplayBin.set_child(this._container); this._notDisplayedResult = [];
this._terms = [];
this._pendingClear = false;
}, },
_setMoreIconVisible: function(visible) { getResultsForDisplay: function() {
this.providerIcon.moreIcon.visible = true; let alreadyVisible = this._pendingClear ? 0 : this.getVisibleResultCount();
let canDisplay = MAX_LIST_SEARCH_RESULTS_ROWS - alreadyVisible;
let newResults = this._notDisplayedResult.splice(0, canDisplay);
return newResults;
}, },
_getMaxDisplayedResults: function() { getVisibleResultCount: function() {
return MAX_LIST_SEARCH_RESULTS_ROWS; return this._content.get_n_children();
}, },
_renderResults: function(metas) { hasMoreResults: function() {
return this._notDisplayedResult.length > 0;
},
setResults: function(results, terms) {
// copy the lists
this._notDisplayedResult = results.slice(0);
this._terms = terms.slice(0);
this._pendingClear = true;
},
_keyFocusIn: function(icon) {
this.emit('key-focus-in', icon);
},
renderResults: function(metas) {
for (let i = 0; i < metas.length; i++) { for (let i = 0; i < metas.length; i++) {
let display = new ListSearchResult(this.provider, metas[i], this._terms); let display = new ListSearchResult(this.provider, metas[i], this._terms);
display.actor.connect('key-focus-in', Lang.bind(this, this._keyFocusIn)); display.actor.connect('key-focus-in', Lang.bind(this, this._keyFocusIn));
@ -291,12 +243,13 @@ const ListSearchResults = new Lang.Class({
} }
}, },
_clearResultDisplay: function () { clear: function () {
this._content.destroy_all_children(); this._content.destroy_all_children();
this._pendingClear = false;
}, },
getFirstResult: function() { getFirstResult: function() {
if (this._content.get_n_children() > 0) if (this.getVisibleResultCount() > 0)
return this._content.get_child_at_index(0)._delegate; return this._content.get_child_at_index(0)._delegate;
else else
return null; return null;
@ -306,24 +259,50 @@ Signals.addSignalMethods(ListSearchResults.prototype);
const GridSearchResults = new Lang.Class({ const GridSearchResults = new Lang.Class({
Name: 'GridSearchResults', Name: 'GridSearchResults',
Extends: SearchResultsBase,
_init: function(provider) { _init: function(provider) {
this.parent(provider); this.provider = provider;
this._grid = new IconGrid.IconGrid({ rowLimit: MAX_GRID_SEARCH_RESULTS_ROWS, this._grid = new IconGrid.IconGrid({ rowLimit: MAX_GRID_SEARCH_RESULTS_ROWS,
xAlign: St.Align.START }); xAlign: St.Align.START });
this._bin = new St.Bin({ x_align: St.Align.MIDDLE }); this.actor = new St.Bin({ x_align: St.Align.MIDDLE });
this._bin.set_child(this._grid.actor);
this._resultDisplayBin.set_child(this._bin); this.actor.set_child(this._grid.actor);
this._notDisplayedResult = [];
this._terms = [];
this._pendingClear = false;
}, },
_getMaxDisplayedResults: function() { getResultsForDisplay: function() {
return this._grid.childrenInRow(this._bin.width) * this._grid.getRowLimit(); let alreadyVisible = this._pendingClear ? 0 : this._grid.visibleItemsCount();
let canDisplay = this._grid.childrenInRow(this.actor.width) * this._grid.getRowLimit()
- alreadyVisible;
let newResults = this._notDisplayedResult.splice(0, canDisplay);
return newResults;
}, },
_renderResults: function(metas) { getVisibleResultCount: function() {
return this._grid.visibleItemsCount();
},
hasMoreResults: function() {
return this._notDisplayedResult.length > 0;
},
setResults: function(results, terms) {
// copy the lists
this._notDisplayedResult = results.slice(0);
this._terms = terms.slice(0);
this._pendingClear = true;
},
_keyFocusIn: function(icon) {
this.emit('key-focus-in', icon);
},
renderResults: function(metas) {
for (let i = 0; i < metas.length; i++) { for (let i = 0; i < metas.length; i++) {
let display = new GridSearchResult(this.provider, metas[i], this._terms); let display = new GridSearchResult(this.provider, metas[i], this._terms);
display.actor.connect('key-focus-in', Lang.bind(this, this._keyFocusIn)); display.actor.connect('key-focus-in', Lang.bind(this, this._keyFocusIn));
@ -331,12 +310,13 @@ const GridSearchResults = new Lang.Class({
} }
}, },
_clearResultDisplay: function () { clear: function () {
this._grid.removeAll(); this._grid.removeAll();
this._pendingClear = false;
}, },
getFirstResult: function() { getFirstResult: function() {
if (this._grid.visibleItemsCount() > 0) if (this.getVisibleResultCount() > 0)
return this._grid.getItemAtIndex(0)._delegate; return this._grid.getItemAtIndex(0)._delegate;
else else
return null; return null;
@ -386,9 +366,9 @@ const SearchResults = new Lang.Class({
this._content.add(this._statusBin, { expand: true }); this._content.add(this._statusBin, { expand: true });
this._statusBin.add_actor(this._statusText); this._statusBin.add_actor(this._statusText);
this._providers = this._searchSystem.getProviders(); this._providers = this._searchSystem.getProviders();
this._providerDisplays = {}; this._providerMeta = [];
for (let i = 0; i < this._providers.length; i++) { for (let i = 0; i < this._providers.length; i++) {
this.createProviderDisplay(this._providers[i]); this.createProviderMeta(this._providers[i]);
} }
this._highlightDefault = false; this._highlightDefault = false;
@ -406,33 +386,61 @@ const SearchResults = new Lang.Class({
Util.ensureActorVisibleInScrollView(this._scrollView, icon); Util.ensureActorVisibleInScrollView(this._scrollView, icon);
}, },
createProviderDisplay: function(provider) { createProviderMeta: function(provider) {
let providerDisplay = null; let providerBox = new St.BoxLayout({ style_class: 'search-section',
vertical: true });
let providerIcon = null;
let resultDisplay = null;
if (provider.appInfo) { if (provider.appInfo) {
providerDisplay = new ListSearchResults(provider); resultDisplay = new ListSearchResults(provider);
providerIcon = resultDisplay.providerIcon;
} else { } else {
providerDisplay = new GridSearchResults(provider); resultDisplay = new GridSearchResults(provider);
} }
providerDisplay.connect('key-focus-in', Lang.bind(this, this._keyFocusIn)); resultDisplay.connect('key-focus-in', Lang.bind(this, this._keyFocusIn));
this._providerDisplays[provider.id] = providerDisplay;
this._content.add(providerDisplay.actor); let resultDisplayBin = new St.Bin({ child: resultDisplay.actor,
x_fill: true,
y_fill: true });
providerBox.add(resultDisplayBin, { expand: true });
let separator = new Separator.HorizontalSeparator({ style_class: 'search-section-separator' });
providerBox.add(separator.actor);
this._providerMeta.push({ provider: provider,
actor: providerBox,
icon: providerIcon,
resultDisplay: resultDisplay });
this._content.add(providerBox);
}, },
destroyProviderDisplay: function(provider) { destroyProviderMeta: function(provider) {
this._providerDisplays[provider.id].destroy(); for (let i=0; i < this._providerMeta.length; i++) {
delete this._providerDisplays[provider.id]; let meta = this._providerMeta[i];
if (meta.provider == provider) {
meta.actor.destroy();
this._providerMeta.splice(i, 1);
break;
}
}
}, },
_clearDisplay: function() { _clearDisplay: function() {
for (let i = 0; i < this._providers.length; i++) { for (let i = 0; i < this._providerMeta.length; i++) {
let provider = this._providers[i]; let meta = this._providerMeta[i];
let providerDisplay = this._providerDisplays[provider.id]; meta.resultDisplay.clear();
providerDisplay.clear(); meta.actor.hide();
} }
}, },
_clearDisplayForProvider: function(provider) {
let meta = this._metaForProvider(provider);
meta.resultDisplay.clear();
meta.actor.hide();
},
reset: function() { reset: function() {
this._searchSystem.reset(); this._searchSystem.reset();
this._statusBin.hide(); this._statusBin.hide();
@ -446,17 +454,20 @@ const SearchResults = new Lang.Class({
this._statusBin.show(); this._statusBin.show();
}, },
_metaForProvider: function(provider) {
return this._providerMeta[this._providers.indexOf(provider)];
},
_maybeSetInitialSelection: function() { _maybeSetInitialSelection: function() {
let newDefaultResult = null; let newDefaultResult = null;
for (let i = 0; i < this._providers.length; i++) { for (let i = 0; i < this._providerMeta.length; i++) {
let provider = this._providers[i]; let meta = this._providerMeta[i];
let display = this._providerDisplays[provider.id];
if (!display.actor.visible) if (!meta.actor.visible)
continue; continue;
let firstResult = display.getFirstResult(); let firstResult = meta.resultDisplay.getFirstResult();
if (firstResult) { if (firstResult) {
newDefaultResult = firstResult; newDefaultResult = firstResult;
break; // select this one! break; // select this one!
@ -476,14 +487,11 @@ const SearchResults = new Lang.Class({
_updateStatusText: function () { _updateStatusText: function () {
let haveResults = false; let haveResults = false;
for (let i = 0; i < this._providers.length; i++) { for (let i = 0; i < this._providerMeta.length; ++i)
let provider = this._providers[i]; if (this._providerMeta[i].resultDisplay.getFirstResult()) {
let display = this._providerDisplays[provider.id];
if (display.getFirstResult()) {
haveResults = true; haveResults = true;
break; break;
} }
}
if (!haveResults) { if (!haveResults) {
this._statusText.set_text(_("No results.")); this._statusText.set_text(_("No results."));
@ -496,12 +504,42 @@ const SearchResults = new Lang.Class({
_updateResults: function(searchSystem, results) { _updateResults: function(searchSystem, results) {
let terms = searchSystem.getTerms(); let terms = searchSystem.getTerms();
let [provider, providerResults] = results; let [provider, providerResults] = results;
let display = this._providerDisplays[provider.id]; let meta = this._metaForProvider(provider);
display.updateSearch(providerResults, terms, Lang.bind(this, function() { if (providerResults.length == 0) {
this._clearDisplayForProvider(provider);
meta.resultDisplay.setResults([], []);
this._maybeSetInitialSelection(); this._maybeSetInitialSelection();
this._updateStatusText(); this._updateStatusText();
})); } else {
meta.resultDisplay.setResults(providerResults, terms);
let results = meta.resultDisplay.getResultsForDisplay();
if (meta.icon)
meta.icon.moreIcon.visible =
meta.resultDisplay.hasMoreResults() &&
provider.canLaunchSearch;
provider.getResultMetas(results, Lang.bind(this, function(metas) {
this._clearDisplayForProvider(provider);
meta.actor.show();
// Hiding drops the key focus if we have it
let focus = global.stage.get_key_focus();
// To avoid CSS transitions causing flickering when
// the first search result stays the same, we hide the
// content while filling in the results.
this._content.hide();
meta.resultDisplay.renderResults(metas);
this._maybeSetInitialSelection();
this._updateStatusText();
this._content.show();
if (this._content.contains(focus))
global.stage.set_key_focus(focus);
}));
}
}, },
activateDefault: function() { activateDefault: function() {

View File

@ -42,10 +42,10 @@ const _modes = {
hasNotifications: true, hasNotifications: true,
isGreeter: true, isGreeter: true,
isPrimary: true, isPrimary: true,
unlockDialog: imports.ui.auth.loginDialog.LoginDialog, unlockDialog: imports.gdm.loginDialog.LoginDialog,
components: ['polkitAgent'], components: ['polkitAgent'],
panel: { panel: {
left: [], left: ['logo'],
center: ['dateMenu'], center: ['dateMenu'],
right: ['a11yGreeter', 'display', 'keyboard', right: ['a11yGreeter', 'display', 'keyboard',
'volume', 'battery', 'powerMenu'] 'volume', 'battery', 'powerMenu']
@ -78,6 +78,17 @@ const _modes = {
panelStyle: 'unlock-screen' panelStyle: 'unlock-screen'
}, },
'initial-setup': {
hasWindows: true,
isPrimary: true,
components: ['keyring'],
panel: {
left: [],
center: ['dateMenu'],
right: ['a11yGreeter', 'keyboard', 'volume', 'battery']
}
},
'user': { 'user': {
hasOverview: true, hasOverview: true,
showCalendarEvents: true, showCalendarEvents: true,
@ -89,7 +100,7 @@ const _modes = {
hasNotifications: true, hasNotifications: true,
isLocked: false, isLocked: false,
isPrimary: true, isPrimary: true,
unlockDialog: imports.ui.auth.unlockDialog.UnlockDialog, unlockDialog: imports.ui.unlockDialog.UnlockDialog,
components: ['networkAgent', 'polkitAgent', 'telepathyClient', components: ['networkAgent', 'polkitAgent', 'telepathyClient',
'keyring', 'recorder', 'autorunManager', 'automountManager'], 'keyring', 'recorder', 'autorunManager', 'automountManager'],
panel: { panel: {
@ -184,10 +195,6 @@ const SessionMode = new Lang.Class({
return this._modeStack[this._modeStack.length - 1]; return this._modeStack[this._modeStack.length - 1];
}, },
get allowScreencast() {
return this.components.indexOf('recorder') != -1;
},
_sync: function() { _sync: function() {
let params = this._modes[this.currentMode]; let params = this._modes[this.currentMode];
let defaults; let defaults;

View File

@ -12,7 +12,6 @@ const ExtensionDownloader = imports.ui.extensionDownloader;
const ExtensionUtils = imports.misc.extensionUtils; const ExtensionUtils = imports.misc.extensionUtils;
const Hash = imports.misc.hash; const Hash = imports.misc.hash;
const Main = imports.ui.main; const Main = imports.ui.main;
const Screencast = imports.ui.screencast;
const Screenshot = imports.ui.screenshot; const Screenshot = imports.ui.screenshot;
const GnomeShellIface = <interface name="org.gnome.Shell"> const GnomeShellIface = <interface name="org.gnome.Shell">
@ -21,7 +20,6 @@ const GnomeShellIface = <interface name="org.gnome.Shell">
<arg type="b" direction="out" name="success" /> <arg type="b" direction="out" name="success" />
<arg type="s" direction="out" name="result" /> <arg type="s" direction="out" name="result" />
</method> </method>
<method name="FocusSearch"/>
<method name="ShowOSD"> <method name="ShowOSD">
<arg type="a{sv}" direction="in" name="params"/> <arg type="a{sv}" direction="in" name="params"/>
</method> </method>
@ -72,7 +70,6 @@ const GnomeShell = new Lang.Class({
this._dbusImpl.export(Gio.DBus.session, '/org/gnome/Shell'); this._dbusImpl.export(Gio.DBus.session, '/org/gnome/Shell');
this._extensionsService = new GnomeShellExtensions(); this._extensionsService = new GnomeShellExtensions();
this._screencastService = new Screencast.ScreencastService();
this._screenshotService = new Screenshot.ScreenshotService(); this._screenshotService = new Screenshot.ScreenshotService();
this._grabbedAccelerators = new Hash.Map(); this._grabbedAccelerators = new Hash.Map();
@ -100,7 +97,7 @@ const GnomeShell = new Lang.Class({
*/ */
Eval: function(code) { Eval: function(code) {
if (!global.settings.get_boolean('development-tools')) if (!global.settings.get_boolean('development-tools'))
return [false, '']; return [false, null];
let returnValue; let returnValue;
let success; let success;
@ -117,10 +114,6 @@ const GnomeShell = new Lang.Class({
return [success, returnValue]; return [success, returnValue];
}, },
FocusSearch: function() {
Main.overview.focusSearch();
},
ShowOSD: function(params) { ShowOSD: function(params) {
for (let param in params) for (let param in params)
params[param] = params[param].deep_unpack(); params[param] = params[param].deep_unpack();

View File

@ -14,7 +14,9 @@ const EntryMenu = new Lang.Class({
Name: 'ShellEntryMenu', Name: 'ShellEntryMenu',
Extends: PopupMenu.PopupMenu, Extends: PopupMenu.PopupMenu,
_init: function(entry) { _init: function(entry, params) {
params = Params.parse (params, { isPassword: false });
this.parent(entry, 0, St.Side.TOP); this.parent(entry, 0, St.Side.TOP);
this.actor.add_style_class_name('entry-context-menu'); this.actor.add_style_class_name('entry-context-menu');
@ -35,6 +37,8 @@ const EntryMenu = new Lang.Class({
this._pasteItem = item; this._pasteItem = item;
this._passwordItem = null; this._passwordItem = null;
if (params.isPassword)
this._makePasswordItem();
Main.uiGroup.add_actor(this.actor); Main.uiGroup.add_actor(this.actor);
this.actor.hide(); this.actor.hide();
@ -49,21 +53,19 @@ const EntryMenu = new Lang.Class({
}, },
get isPassword() { get isPassword() {
return this._passwordItem != null; return this._passwordItem != null;
}, },
set isPassword(v) { set isPassword(v) {
if (v == this.isPassword) if (v == this.isPassword)
return; return;
if (v) { if (v)
this._makePasswordItem(); this._makePasswordItem();
this._entry.input_purpose = Gtk.InputPurpose.PASSWORD; else {
} else { this._passwordItem.destroy();
this._passwordItem.destroy(); this._passwordItem = null;
this._passwordItem = null; }
this._entry.input_purpose = Gtk.InputPurpose.FREE_FORM;
}
}, },
open: function(animate) { open: function(animate) {
@ -80,6 +82,11 @@ const EntryMenu = new Lang.Class({
this.actor.grab_key_focus(); this.actor.grab_key_focus();
}, },
close: function(animate) {
this._entry.grab_key_focus();
this.parent(animate);
},
_updateCopyItem: function() { _updateCopyItem: function() {
let selection = this._entry.clutter_text.get_selection(); let selection = this._entry.clutter_text.get_selection();
this._copyItem.setSensitive(!this._entry.clutter_text.password_char && this._copyItem.setSensitive(!this._entry.clutter_text.password_char &&
@ -153,10 +160,7 @@ function addContextMenu(entry, params) {
if (entry.menu) if (entry.menu)
return; return;
params = Params.parse (params, { isPassword: false }); entry.menu = new EntryMenu(entry, params);
entry.menu = new EntryMenu(entry);
entry.menu.isPassword = params.isPassword;
entry._menuManager = new PopupMenu.PopupMenuManager({ actor: entry }); entry._menuManager = new PopupMenu.PopupMenuManager({ actor: entry });
entry._menuManager.addMenu(entry.menu); entry._menuManager.addMenu(entry.menu);

View File

@ -363,7 +363,7 @@ const ConfirmNotification = new Lang.Class({
this._applet = applet; this._applet = applet;
this._devicePath = device_path; this._devicePath = device_path;
this.addBody(_("Device %s wants to pair with this computer").format(long_name)); this.addBody(_("Device %s wants to pair with this computer").format(long_name));
this.addBody(_("Please confirm whether the Passkey '%06d' matches the one on the device.").format(pin)); this.addBody(_("Please confirm whether the PIN '%06d' matches the one on the device.").format(pin));
/* Translators: this is the verb, not the noun */ /* Translators: this is the verb, not the noun */
this.addButton('matches', _("Matches")); this.addButton('matches', _("Matches"));

View File

@ -33,9 +33,9 @@ const KEY_INPUT_SOURCES = 'sources';
const INPUT_SOURCE_TYPE_XKB = 'xkb'; const INPUT_SOURCE_TYPE_XKB = 'xkb';
const INPUT_SOURCE_TYPE_IBUS = 'ibus'; const INPUT_SOURCE_TYPE_IBUS = 'ibus';
// This is the longest we'll keep the keyboard frozen until an input // This is longest we'll keep the keyboard frozen until an input
// source is active. // source is active.
const MAX_INPUT_SOURCE_ACTIVATION_TIME = 4000; // ms const MAX_INPUT_SOURCE_ACTIVATION_TIME = 2000; // ms
const BUS_NAME = 'org.gnome.SettingsDaemon.Keyboard'; const BUS_NAME = 'org.gnome.SettingsDaemon.Keyboard';
const OBJECT_PATH = '/org/gnome/SettingsDaemon/Keyboard'; const OBJECT_PATH = '/org/gnome/SettingsDaemon/Keyboard';
@ -57,7 +57,10 @@ function releaseKeyboard() {
} }
function holdKeyboard() { function holdKeyboard() {
global.freeze_keyboard(global.get_current_time()); if (Main.modalCount > 0)
global.display.freeze_keyboard(global.get_current_time());
else
global.display.grab_keyboard(global.get_current_time());
} }
const IBusManager = new Lang.Class({ const IBusManager = new Lang.Class({
@ -72,24 +75,26 @@ const IBusManager = new Lang.Class({
this._readyCallback = readyCallback; this._readyCallback = readyCallback;
this._candidatePopup = new IBusCandidatePopup.CandidatePopup(); this._candidatePopup = new IBusCandidatePopup.CandidatePopup();
this._ibus = null;
this._panelService = null; this._panelService = null;
this._engines = {}; this._engines = {};
this._ready = false; this._ready = false;
this._registerPropertiesId = 0; this._registerPropertiesId = 0;
this._currentEngineName = null; this._currentEngineName = null;
this._ibus = IBus.Bus.new_async(); this._nameWatcherId = Gio.DBus.session.watch_name(IBus.SERVICE_IBUS,
this._ibus.connect('connected', Lang.bind(this, this._onConnected)); Gio.BusNameWatcherFlags.NONE,
this._ibus.connect('disconnected', Lang.bind(this, this._clear)); Lang.bind(this, this._onNameAppeared),
// Need to set this to get 'global-engine-changed' emitions Lang.bind(this, this._clear));
this._ibus.set_watch_ibus_signal(true);
this._ibus.connect('global-engine-changed', Lang.bind(this, this._engineChanged));
}, },
_clear: function() { _clear: function() {
if (this._panelService) if (this._panelService)
this._panelService.destroy(); this._panelService.destroy();
if (this._ibus)
this._ibus.destroy();
this._ibus = null;
this._panelService = null; this._panelService = null;
this._candidatePopup.setPanelService(null); this._candidatePopup.setPanelService(null);
this._engines = {}; this._engines = {};
@ -101,12 +106,18 @@ const IBusManager = new Lang.Class({
this._readyCallback(false); this._readyCallback(false);
}, },
_onNameAppeared: function() {
this._ibus = IBus.Bus.new_async();
this._ibus.connect('connected', Lang.bind(this, this._onConnected));
},
_onConnected: function() { _onConnected: function() {
this._ibus.list_engines_async(-1, null, Lang.bind(this, this._initEngines)); this._ibus.list_engines_async(-1, null, Lang.bind(this, this._initEngines));
this._ibus.request_name_async(IBus.SERVICE_PANEL, this._ibus.request_name_async(IBus.SERVICE_PANEL,
IBus.BusNameFlag.REPLACE_EXISTING, IBus.BusNameFlag.REPLACE_EXISTING,
-1, null, -1, null,
Lang.bind(this, this._initPanelService)); Lang.bind(this, this._initPanelService));
this._ibus.connect('disconnected', Lang.bind(this, this._clear));
}, },
_initEngines: function(ibus, result) { _initEngines: function(ibus, result) {
@ -128,6 +139,9 @@ const IBusManager = new Lang.Class({
this._panelService = new IBus.PanelService({ connection: this._ibus.get_connection(), this._panelService = new IBus.PanelService({ connection: this._ibus.get_connection(),
object_path: IBus.PATH_PANEL }); object_path: IBus.PATH_PANEL });
this._candidatePopup.setPanelService(this._panelService); this._candidatePopup.setPanelService(this._panelService);
// Need to set this to get 'global-engine-changed' emitions
this._ibus.set_watch_ibus_signal(true);
this._ibus.connect('global-engine-changed', Lang.bind(this, this._engineChanged));
this._panelService.connect('update-property', Lang.bind(this, this._updateProperty)); this._panelService.connect('update-property', Lang.bind(this, this._updateProperty));
// If an engine is already active we need to get its properties // If an engine is already active we need to get its properties
this._ibus.get_global_engine_async(-1, null, Lang.bind(this, function(i, result) { this._ibus.get_global_engine_async(-1, null, Lang.bind(this, function(i, result) {
@ -156,9 +170,6 @@ const IBusManager = new Lang.Class({
}, },
_engineChanged: function(bus, engineName) { _engineChanged: function(bus, engineName) {
if (!this._ready)
return;
this._currentEngineName = engineName; this._currentEngineName = engineName;
if (this._registerPropertiesId != 0) if (this._registerPropertiesId != 0)
@ -249,6 +260,7 @@ const InputSource = new Lang.Class({
}, },
activate: function() { activate: function() {
holdKeyboard();
this.emit('activate'); this.emit('activate');
}, },
}); });
@ -281,11 +293,11 @@ const InputSourcePopup = new Lang.Class({
this._select(this._selectedIndex); this._select(this._selectedIndex);
}, },
_keyPressHandler: function(keysym, backwards, action) { _keyPressHandler: function(keysym, _ignored, action) {
if (action == this._action) if (action == this._action)
this._select(backwards ? this._previous() : this._next()); this._select(this._next());
else if (action == this._actionBackward) else if (action == this._actionBackward)
this._select(backwards ? this._next() : this._previous()); this._select(this._previous());
else if (keysym == Clutter.Left) else if (keysym == Clutter.Left)
this._select(this._previous()); this._select(this._previous());
else if (keysym == Clutter.Right) else if (keysym == Clutter.Right)
@ -355,14 +367,13 @@ const InputSourceIndicator = new Lang.Class({
this._keybindingAction = this._keybindingAction =
Main.wm.addKeybinding('switch-input-source', Main.wm.addKeybinding('switch-input-source',
new Gio.Settings({ schema: "org.gnome.desktop.wm.keybindings" }), new Gio.Settings({ schema: "org.gnome.desktop.wm.keybindings" }),
Meta.KeyBindingFlags.REVERSES, Meta.KeyBindingFlags.NONE,
Shell.KeyBindingMode.ALL, Shell.KeyBindingMode.ALL,
Lang.bind(this, this._switchInputSource)); Lang.bind(this, this._switchInputSource));
this._keybindingActionBackward = this._keybindingActionBackward =
Main.wm.addKeybinding('switch-input-source-backward', Main.wm.addKeybinding('switch-input-source-backward',
new Gio.Settings({ schema: "org.gnome.desktop.wm.keybindings" }), new Gio.Settings({ schema: "org.gnome.desktop.wm.keybindings" }),
Meta.KeyBindingFlags.REVERSES | Meta.KeyBindingFlags.NONE,
Meta.KeyBindingFlags.REVERSED,
Shell.KeyBindingMode.ALL, Shell.KeyBindingMode.ALL,
Lang.bind(this, this._switchInputSource)); Lang.bind(this, this._switchInputSource));
this._settings = new Gio.Settings({ schema: DESKTOP_INPUT_SOURCES_SCHEMA }); this._settings = new Gio.Settings({ schema: DESKTOP_INPUT_SOURCES_SCHEMA });
@ -388,8 +399,6 @@ const InputSourceIndicator = new Lang.Class({
if (error) if (error)
log(error.message); log(error.message);
}); });
this._keyboardManager.g_default_timeout = MAX_INPUT_SOURCE_ACTIVATION_TIME;
global.display.connect('modifiers-accelerator-activated', Lang.bind(this, this._modifiersSwitcher)); global.display.connect('modifiers-accelerator-activated', Lang.bind(this, this._modifiersSwitcher));
this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem()); this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
@ -429,7 +438,7 @@ const InputSourceIndicator = new Lang.Class({
let sourceIndexes = Object.keys(this._inputSources); let sourceIndexes = Object.keys(this._inputSources);
if (sourceIndexes.length == 0) { if (sourceIndexes.length == 0) {
releaseKeyboard(); releaseKeyboard();
return true; return;
} }
let is = this._currentSource; let is = this._currentSource;
@ -444,7 +453,6 @@ const InputSourceIndicator = new Lang.Class({
nextIndex += 1; nextIndex += 1;
is.activate(); is.activate();
return true;
}, },
_switchInputSource: function(display, screen, window, binding) { _switchInputSource: function(display, screen, window, binding) {
@ -452,19 +460,18 @@ const InputSourceIndicator = new Lang.Class({
return; return;
// HACK: Fall back on simple input source switching since we // HACK: Fall back on simple input source switching since we
// can't show a popup switcher while a GrabHelper grab is in // can't show a popup switcher while the message tray is up
// effect without considerable work to consolidate the usage // without considerable work to consolidate the usage of
// of pushModal/popModal and grabHelper. See // pushModal/popModal and grabHelper. See
// https://bugzilla.gnome.org/show_bug.cgi?id=695143 . // https://bugzilla.gnome.org/show_bug.cgi?id=695143 .
if (Main.keybindingMode == Shell.KeyBindingMode.MESSAGE_TRAY || if (Main.keybindingMode == Shell.KeyBindingMode.MESSAGE_TRAY) {
Main.keybindingMode == Shell.KeyBindingMode.TOPBAR_POPUP) {
this._modifiersSwitcher(); this._modifiersSwitcher();
return; return;
} }
let popup = new InputSourcePopup(this._mruSources, this._keybindingAction, this._keybindingActionBackward); let popup = new InputSourcePopup(this._mruSources, this._keybindingAction, this._keybindingActionBackward);
let modifiers = binding.get_modifiers(); let modifiers = binding.get_modifiers();
let backwards = modifiers & Meta.VirtualModifier.SHIFT_MASK; let backwards = false; // Not using this
if (!popup.show(backwards, binding.get_name(), binding.get_mask())) if (!popup.show(backwards, binding.get_name(), binding.get_mask()))
popup.destroy(); popup.destroy();
}, },
@ -478,7 +485,7 @@ const InputSourceIndicator = new Lang.Class({
[oldSource, this._currentSource] = [this._currentSource, newSource]; [oldSource, this._currentSource] = [this._currentSource, newSource];
if (oldSource) { if (oldSource) {
oldSource.menuItem.setOrnament(PopupMenu.Ornament.NONE); oldSource.menuItem.setShowDot(false);
oldSource.indicatorLabel.hide(); oldSource.indicatorLabel.hide();
} }
@ -496,7 +503,7 @@ const InputSourceIndicator = new Lang.Class({
this.actor.show(); this.actor.show();
newSource.menuItem.setOrnament(PopupMenu.Ornament.DOT); newSource.menuItem.setShowDot(true);
newSource.indicatorLabel.show(); newSource.indicatorLabel.show();
this._buildPropSection(newSource.properties); this._buildPropSection(newSource.properties);
@ -520,7 +527,6 @@ const InputSourceIndicator = new Lang.Class({
this._inputSources = {}; this._inputSources = {};
this._ibusSources = {}; this._ibusSources = {};
this._currentSource = null;
let inputSourcesByShortName = {}; let inputSourcesByShortName = {};
@ -549,8 +555,10 @@ const InputSourceIndicator = new Lang.Class({
let is = new InputSource(type, id, displayName, shortName, i); let is = new InputSource(type, id, displayName, shortName, i);
is.connect('activate', Lang.bind(this, function() { is.connect('activate', Lang.bind(this, function() {
holdKeyboard(); let inVariant = new GLib.Variant('(u)', [is.index]);
this._keyboardManager.SetInputSourceRemote(is.index, releaseKeyboard); this._keyboardManager.call('SetInputSource', inVariant, 0,
MAX_INPUT_SOURCE_ACTIVATION_TIME,
null, releaseKeyboard);
})); }));
if (!(is.shortName in inputSourcesByShortName)) if (!(is.shortName in inputSourcesByShortName))
@ -720,8 +728,7 @@ const InputSourceIndicator = new Lang.Class({
item.prop = prop; item.prop = prop;
radioGroup.push(item); radioGroup.push(item);
item.radioGroup = radioGroup; item.radioGroup = radioGroup;
item.setOrnament(prop.get_state() == IBus.PropState.CHECKED ? item.setShowDot(prop.get_state() == IBus.PropState.CHECKED);
PopupMenu.Ornament.DOT : PopupMenu.Ornament.NONE);
item.connect('activate', Lang.bind(this, function() { item.connect('activate', Lang.bind(this, function() {
if (item.prop.get_state() == IBus.PropState.CHECKED) if (item.prop.get_state() == IBus.PropState.CHECKED)
return; return;
@ -729,12 +736,12 @@ const InputSourceIndicator = new Lang.Class({
let group = item.radioGroup; let group = item.radioGroup;
for (let i = 0; i < group.length; ++i) { for (let i = 0; i < group.length; ++i) {
if (group[i] == item) { if (group[i] == item) {
item.setOrnament(PopupMenu.Ornament.DOT); item.setShowDot(true);
item.prop.set_state(IBus.PropState.CHECKED); item.prop.set_state(IBus.PropState.CHECKED);
this._ibusManager.activateProperty(item.prop.get_key(), this._ibusManager.activateProperty(item.prop.get_key(),
IBus.PropState.CHECKED); IBus.PropState.CHECKED);
} else { } else {
group[i].setOrnament(PopupMenu.Ornament.NONE); group[i].setShowDot(false);
group[i].prop.set_state(IBus.PropState.UNCHECKED); group[i].prop.set_state(IBus.PropState.UNCHECKED);
this._ibusManager.activateProperty(group[i].prop.get_key(), this._ibusManager.activateProperty(group[i].prop.get_key(),
IBus.PropState.UNCHECKED); IBus.PropState.UNCHECKED);

View File

@ -5,10 +5,17 @@ const Gio = imports.gi.Gio;
const Lang = imports.lang; const Lang = imports.lang;
const NetworkManager = imports.gi.NetworkManager; const NetworkManager = imports.gi.NetworkManager;
const NMClient = imports.gi.NMClient; const NMClient = imports.gi.NMClient;
const NMGtk = imports.gi.NMGtk;
const Signals = imports.signals; const Signals = imports.signals;
const St = imports.gi.St; const St = imports.gi.St;
// Some of the new code depends on as-yet-unreleased NM
var NMGtk;
try {
NMGtk = imports.gi.NMGtk;
} catch(e) {
NMGtk = null;
}
const Main = imports.ui.main; const Main = imports.ui.main;
const PanelMenu = imports.ui.panelMenu; const PanelMenu = imports.ui.panelMenu;
const PopupMenu = imports.ui.popupMenu; const PopupMenu = imports.ui.popupMenu;
@ -27,6 +34,7 @@ const NMConnectionCategory = {
}; };
const NMAccessPointSecurity = { const NMAccessPointSecurity = {
UNKNOWN: 0,
NONE: 1, NONE: 1,
WEP: 2, WEP: 2,
WPA_PSK: 3, WPA_PSK: 3,
@ -44,6 +52,20 @@ const NM80211ApSecurityFlags = NetworkManager['80211ApSecurityFlags'];
// (the remaining are placed into More…) // (the remaining are placed into More…)
const NUM_VISIBLE_NETWORKS = 5; const NUM_VISIBLE_NETWORKS = 5;
function macToArray(string) {
return string.split(':').map(function(el) {
return parseInt(el, 16);
});
}
function macCompare(one, two) {
for (let i = 0; i < 6; i++) {
if (one[i] != two[i])
return false;
}
return true;
}
function ssidCompare(one, two) { function ssidCompare(one, two) {
if (!one || !two) if (!one || !two)
return false; return false;
@ -69,6 +91,13 @@ function signalToIcon(value) {
return 'none'; return 'none';
} }
// shared between NMNetworkMenuItem and NMDeviceWireless
function sortAccessPoints(accessPoints) {
return accessPoints.sort(function (one, two) {
return two.strength - one.strength;
});
}
function ssidToLabel(ssid) { function ssidToLabel(ssid) {
let label = NetworkManager.utils_ssid_to_utf8(ssid); let label = NetworkManager.utils_ssid_to_utf8(ssid);
if (!label) if (!label)
@ -101,7 +130,8 @@ const NMNetworkMenuItem = new Lang.Class({
this._icons.add_actor(this._signalIcon); this._icons.add_actor(this._signalIcon);
this._secureIcon = new St.Icon({ style_class: 'popup-menu-icon' }); this._secureIcon = new St.Icon({ style_class: 'popup-menu-icon' });
if (this.bestAP._secType != NMAccessPointSecurity.NONE) if (this.bestAP._secType != NMAccessPointSecurity.UNKNOWN &&
this.bestAP._secType != NMAccessPointSecurity.NONE)
this._secureIcon.icon_name = 'network-wireless-encrypted-symbolic'; this._secureIcon.icon_name = 'network-wireless-encrypted-symbolic';
this._icons.add_actor(this._secureIcon); this._icons.add_actor(this._secureIcon);
}, },
@ -123,12 +153,18 @@ const NMWirelessSectionTitleMenuItem = new Lang.Class({
Name: 'NMWirelessSectionTitleMenuItem', Name: 'NMWirelessSectionTitleMenuItem',
Extends: PopupMenu.PopupSwitchMenuItem, Extends: PopupMenu.PopupSwitchMenuItem,
_init: function(client) { _init: function(client, property, title, params) {
this.parent(_("Wi-Fi"), false, { style_class: 'popup-subtitle-menu-item' }); params = params || { };
params.style_class = 'popup-subtitle-menu-item';
this.parent(title, false, params);
this._client = client; this._client = client;
this._client.connect('notify::wireless-enabled', Lang.bind(this, this._propertyChanged)); this._property = property + '_enabled';
this._client.connect('notify::wireless-hardware-enabled', Lang.bind(this, this._propertyChanged)); this._propertyHardware = property + '_hardware_enabled';
this._setEnabledFunc = property + '_set_enabled';
this._client.connect('notify::' + property + '-enabled', Lang.bind(this, this._propertyChanged));
this._client.connect('notify::' + property + '-hardware-enabled', Lang.bind(this, this._propertyChanged));
this._propertyChanged(); this._propertyChanged();
}, },
@ -150,12 +186,12 @@ const NMWirelessSectionTitleMenuItem = new Lang.Class({
activate: function(event) { activate: function(event) {
this.parent(event); this.parent(event);
this._client.wireless_set_enabled(this._switch.state); this._client[this._setEnabledFunc](this._switch.state);
}, },
_propertyChanged: function() { _propertyChanged: function() {
this._softwareEnabled = this._client.wireless_enabled; this._softwareEnabled = this._client[this._property];
this._hardwareEnabled = this._client.wireless_hardware_enabled; this._hardwareEnabled = this._client[this._propertyHardware];
let enabled = this._softwareEnabled && this._hardwareEnabled; let enabled = this._softwareEnabled && this._hardwareEnabled;
this.setToggleState(enabled); this.setToggleState(enabled);
@ -173,7 +209,22 @@ const NMConnectionBased = new Lang.Class({
_init: function(connections) { _init: function(connections) {
this._connections = [ ]; this._connections = [ ];
connections.forEach(Lang.bind(this, this.checkConnection)); for (let i = 0; i < connections.length; i++) {
if (!connections[i].get_uuid())
continue;
if (!this.connectionValid(connections[i]))
continue;
// record the connection
let obj = {
connection: connections[i],
name: connections[i].get_id(),
uuid: connections[i].get_uuid(),
timestamp: connections[i]._timestamp,
item: null,
};
this._connections.push(obj);
}
this._connections.sort(this._connectionSortFunction);
}, },
checkConnection: function(connection) { checkConnection: function(connection) {
@ -264,6 +315,7 @@ const NMDevice = new Lang.Class({
this._activeConnection = null; this._activeConnection = null;
this._activeConnectionItem = null; this._activeConnectionItem = null;
this._autoConnectionItem = null;
this._overflowItem = null; this._overflowItem = null;
this.statusItem = new PopupMenu.PopupSwitchMenuItem('', this.connected, { style_class: 'popup-subtitle-menu-item' }); this.statusItem = new PopupMenu.PopupSwitchMenuItem('', this.connected, { style_class: 'popup-subtitle-menu-item' });
@ -350,9 +402,13 @@ const NMDevice = new Lang.Class({
}, },
_activateAutomaticConnection: function() { _activateAutomaticConnection: function() {
let connection = new NetworkManager.Connection(); let connection = this._createAutomaticConnection();
this._client.add_and_activate_connection(connection, this.device, null, null); if (connection) {
return true; this._client.add_and_activate_connection(connection, this.device, null, null);
return true;
}
return false;
}, },
get connected() { get connected() {
@ -446,6 +502,11 @@ const NMDevice = new Lang.Class({
this.statusItem.label.text = this.device._description; this.statusItem.label.text = this.device._description;
}, },
// protected
_createAutomaticConnection: function() {
throw new TypeError('Invoking pure virtual function NMDevice.createAutomaticConnection');
},
_queueCreateSection: function() { _queueCreateSection: function() {
if (this._deferredWorkId) { if (this._deferredWorkId) {
this._clearSection(); this._clearSection();
@ -456,6 +517,7 @@ const NMDevice = new Lang.Class({
_clearSection: function() { _clearSection: function() {
// Clear everything // Clear everything
this.section.removeAll(); this.section.removeAll();
this._autoConnectionItem = null;
this._activeConnectionItem = null; this._activeConnectionItem = null;
this._overflowItem = null; this._overflowItem = null;
for (let i = 0; i < this._connections.length; i++) { for (let i = 0; i < this._connections.length; i++) {
@ -494,6 +556,14 @@ const NMDevice = new Lang.Class({
} else } else
this.section.addMenuItem(obj.item); this.section.addMenuItem(obj.item);
} }
} else if (this._autoConnectionName) {
this._autoConnectionItem = new PopupMenu.PopupMenuItem(this._autoConnectionName);
this._autoConnectionItem.connect('activate', Lang.bind(this, function() {
let connection = this._createAutomaticConnection();
if (connection)
this._client.add_and_activate_connection(connection, this.device, null, null);
}));
this.section.addMenuItem(this._autoConnectionItem);
} }
}, },
@ -518,7 +588,7 @@ const NMDevice = new Lang.Class({
title = _("Connected (private)"); title = _("Connected (private)");
} }
this._activeConnectionItem = new PopupMenu.PopupMenuItem(title, { reactive: false }); this._activeConnectionItem = new PopupMenu.PopupMenuItem(title, { reactive: false });
this._activeConnectionItem.setOrnament(PopupMenu.Ornament.DOT); this._activeConnectionItem.setShowDot(true);
}, },
_deviceStateChanged: function(device, newstate, oldstate, reason) { _deviceStateChanged: function(device, newstate, oldstate, reason) {
@ -595,10 +665,24 @@ const NMDeviceWired = new Lang.Class({
_init: function(client, device, connections) { _init: function(client, device, connections) {
device._description = _("Wired"); device._description = _("Wired");
this._autoConnectionName = _("Auto Ethernet");
this.category = NMConnectionCategory.WIRED; this.category = NMConnectionCategory.WIRED;
this.parent(client, device, connections); this.parent(client, device, connections);
}, },
_createAutomaticConnection: function() {
let connection = new NetworkManager.Connection();
let uuid = NetworkManager.utils_uuid_generate();
connection.add_setting(new NetworkManager.SettingWired());
connection.add_setting(new NetworkManager.SettingConnection({
uuid: uuid,
id: this._autoConnectionName,
type: NetworkManager.SETTING_WIRED_SETTING_NAME,
autoconnect: true
}));
return connection;
}
}); });
const NMDeviceModem = new Lang.Class({ const NMDeviceModem = new Lang.Class({
@ -639,10 +723,13 @@ const NMDeviceModem = new Lang.Class({
this._connectionType = NetworkManager.SETTING_GSM_SETTING_NAME; this._connectionType = NetworkManager.SETTING_GSM_SETTING_NAME;
} }
if (is_wwan) if (is_wwan) {
this.category = NMConnectionCategory.WWAN; this.category = NMConnectionCategory.WWAN;
else this._autoConnectionName = _("Auto broadband");
} else {
this.category = NMConnectionCategory.WIRED; this.category = NMConnectionCategory.WIRED;
this._autoConnectionName = _("Auto dial-up");
}
if (this.mobileDevice) { if (this.mobileDevice) {
this._operatorNameId = this.mobileDevice.connect('notify::operator-name', Lang.bind(this, function() { this._operatorNameId = this.mobileDevice.connect('notify::operator-name', Lang.bind(this, function() {
@ -737,20 +824,50 @@ const NMDeviceBluetooth = new Lang.Class({
_init: function(client, device, connections) { _init: function(client, device, connections) {
device._description = _("Bluetooth"); device._description = _("Bluetooth");
this._autoConnectionName = this._makeConnectionName(device);
device.connect('notify::name', Lang.bind(this, this._updateAutoConnectionName));
this.category = NMConnectionCategory.WWAN; this.category = NMConnectionCategory.WWAN;
this.parent(client, device, connections); this.parent(client, device, connections);
}, },
_createAutomaticConnection: function() {
let connection = new NetworkManager.Connection;
let uuid = NetworkManager.utils_uuid_generate();
connection.add_setting(new NetworkManager.SettingBluetooth);
connection.add_setting(new NetworkManager.SettingConnection({
uuid: uuid,
id: this._autoConnectionName,
type: NetworkManager.SETTING_BLUETOOTH_SETTING_NAME,
autoconnect: false
}));
return connection;
},
_activateAutomaticConnection: function() { _activateAutomaticConnection: function() {
// FIXME: DUN devices are configured like modems, so // FIXME: DUN devices are configured like modems, so
// We need to spawn the mobile wizard // we need to spawn the mobile wizard
// but the network panel doesn't support bluetooth at the moment // but the network panel doesn't support bluetooth at the moment
// so we just create an empty connection and hope // so we just create an empty connection and hope
// that this phone supports PAN // that this phone supports PAN
return this.parent(); return this.parent();
},
_makeConnectionName: function(device) {
let name = device.name;
if (name)
return _("Auto %s").format(name);
else
return _("Auto bluetooth");
},
_updateAutoConnectionName: function() {
this._autoConnectionName = this._makeConnectionName(this.device);
this._queueCreateSection();
this._updateStatusItem();
} }
}); });
@ -764,19 +881,76 @@ const NMDeviceWireless = new Lang.Class({
this._overflowItem = null; this._overflowItem = null;
this._networks = [ ]; this._networks = [ ];
this.parent(client, device, connections); // breaking the layers with this, but cannot call
// this.connectionValid until I have a device
this.device = device;
let accessPoints = device.get_access_points() || [ ]; let validConnections = connections.filter(Lang.bind(this, function(connection) {
accessPoints.forEach(Lang.bind(this, function(ap) { return this.connectionValid(connection);
this._accessPointAdded(this.device, ap);
})); }));
let accessPoints = device.get_access_points() || [ ];
for (let i = 0; i < accessPoints.length; i++) {
// Access points are grouped by network
let ap = accessPoints[i];
this._activeApChanged(); if (ap.get_ssid() == null) {
// hidden access point cannot be added, we need to know
// the SSID and security details to connect
// nevertheless, the access point can acquire a SSID when
// NetworkManager connects to it (via nmcli or the control-center)
ap._notifySsidId = ap.connect('notify::ssid', Lang.bind(this, this._notifySsidCb));
continue;
}
let pos = this._findNetwork(ap);
let obj;
if (pos != -1) {
obj = this._networks[pos];
obj.accessPoints.push(ap);
} else {
obj = { ssid: ap.get_ssid(),
mode: ap.mode,
security: this._getApSecurityType(ap),
connections: [ ],
item: null,
accessPoints: [ ap ]
};
obj.ssidText = ssidToLabel(obj.ssid);
this._networks.push(obj);
}
ap._updateId = ap.connect('notify::strength', Lang.bind(this, this._onApStrengthChanged));
// Check if some connection is valid for this AP
for (let j = 0; j < validConnections.length; j++) {
let connection = validConnections[j];
if (ap.connection_valid(connection) &&
obj.connections.indexOf(connection) == -1) {
obj.connections.push(connection);
}
}
}
// Sort APs within each network by strength
for (let i = 0; i < this._networks.length; i++)
sortAccessPoints(this._networks[i].accessPoints);
if (this.device.active_access_point) {
let networkPos = this._findNetwork(this.device.active_access_point);
if (networkPos == -1) // the connected access point is invisible
this._activeNetwork = null;
else
this._activeNetwork = this._networks[networkPos];
} else {
this._activeNetwork = null;
}
this._networks.sort(this._networkSortFunction); this._networks.sort(this._networkSortFunction);
this._apChangedId = device.connect('notify::active-access-point', Lang.bind(this, this._activeApChanged)); this._apChangedId = device.connect('notify::active-access-point', Lang.bind(this, this._activeApChanged));
this._apAddedId = device.connect('access-point-added', Lang.bind(this, this._accessPointAdded)); this._apAddedId = device.connect('access-point-added', Lang.bind(this, this._accessPointAdded));
this._apRemovedId = device.connect('access-point-removed', Lang.bind(this, this._accessPointRemoved)); this._apRemovedId = device.connect('access-point-removed', Lang.bind(this, this._accessPointRemoved));
this.parent(client, device, validConnections);
}, },
destroy: function() { destroy: function() {
@ -916,9 +1090,9 @@ const NMDeviceWireless = new Lang.Class({
_findExistingNetwork: function(accessPoint) { _findExistingNetwork: function(accessPoint) {
for (let i = 0; i < this._networks.length; i++) { for (let i = 0; i < this._networks.length; i++) {
let network = this._networks[i]; let apObj = this._networks[i];
for (let j = 0; j < network.accessPoints.length; j++) { for (let j = 0; j < apObj.accessPoints.length; j++) {
if (network.accessPoints[j] == accessPoint) if (apObj.accessPoints[j] == accessPoint)
return { network: i, ap: j }; return { network: i, ap: j };
} }
} }
@ -966,30 +1140,30 @@ const NMDeviceWireless = new Lang.Class({
} }
let pos = this._findNetwork(accessPoint); let pos = this._findNetwork(accessPoint);
let network; let apObj;
let needsupdate = false; let needsupdate = false;
if (pos != -1) { if (pos != -1) {
network = this._networks[pos]; apObj = this._networks[pos];
if (network.accessPoints.indexOf(accessPoint) != -1) { if (apObj.accessPoints.indexOf(accessPoint) != -1) {
log('Access point was already seen, not adding again'); log('Access point was already seen, not adding again');
return; return;
} }
Util.insertSorted(network.accessPoints, accessPoint, function(one, two) { Util.insertSorted(apObj.accessPoints, accessPoint, function(one, two) {
return two.strength - one.strength; return two.strength - one.strength;
}); });
if (network.item) if (apObj.item)
network.item.updateBestAP(network.accessPoints[0]); apObj.item.updateBestAP(apObj.accessPoints[0]);
} else { } else {
network = { ssid: accessPoint.get_ssid(), apObj = { ssid: accessPoint.get_ssid(),
mode: accessPoint.mode, mode: accessPoint.mode,
security: this._getApSecurityType(accessPoint), security: this._getApSecurityType(accessPoint),
connections: [ ], connections: [ ],
item: null, item: null,
accessPoints: [ accessPoint ] accessPoints: [ accessPoint ]
}; };
network.ssidText = ssidToLabel(network.ssid); apObj.ssidText = ssidToLabel(apObj.ssid);
} }
accessPoint._updateId = accessPoint.connect('notify::strength', Lang.bind(this, this._onApStrengthChanged)); accessPoint._updateId = accessPoint.connect('notify::strength', Lang.bind(this, this._onApStrengthChanged));
@ -997,14 +1171,14 @@ const NMDeviceWireless = new Lang.Class({
for (let i = 0; i < this._connections.length; i++) { for (let i = 0; i < this._connections.length; i++) {
let connection = this._connections[i].connection; let connection = this._connections[i].connection;
if (accessPoint.connection_valid(connection) && if (accessPoint.connection_valid(connection) &&
network.connections.indexOf(connection) == -1) { apObj.connections.indexOf(connection) == -1) {
network.connections.push(connection); apObj.connections.push(connection);
} }
} }
if (pos != -1) if (pos != -1)
this._networks.splice(pos, 1); this._networks.splice(pos, 1);
let newPos = Util.insertSorted(this._networks, network, this._networkSortFunction); let newPos = Util.insertSorted(this._networks, apObj, this._networkSortFunction);
// Queue an update of the UI if we changed the order // Queue an update of the UI if we changed the order
if (newPos != pos) if (newPos != pos)
@ -1024,28 +1198,28 @@ const NMDeviceWireless = new Lang.Class({
return; return;
} }
let network = this._networks[res.network]; let apObj = this._networks[res.network];
network.accessPoints.splice(res.ap, 1); apObj.accessPoints.splice(res.ap, 1);
if (network.accessPoints.length == 0) { if (apObj.accessPoints.length == 0) {
if (this._activeNetwork == network) if (this._activeNetwork == apObj)
this._activeNetwork = null; this._activeNetwork = null;
if (network.item) if (apObj.item)
network.item.destroy(); apObj.item.destroy();
if (this._overflowItem) { if (this._overflowItem) {
if (!network.isMore) { if (!apObj.isMore) {
// we removed an item in the main menu, and we have a more submenu // we removed an item in the main menu, and we have a more submenu
// we need to extract the first item in more and move it to the submenu // we need to extract the first item in more and move it to the submenu
let item = this._overflowItem.menu.firstMenuItem; let item = this._overflowItem.menu.firstMenuItem;
if (item && item._network) { if (item && item._apObj) {
item.destroy(); item.destroy();
// clear the cycle, and allow the construction of the new item // clear the cycle, and allow the construction of the new item
item._network.item = null; item._apObj.item = null;
this._createNetworkItem(item._network, NUM_VISIBLE_NETWORKS-1); this._createNetworkItem(item._apObj, NUM_VISIBLE_NETWORKS-1);
} else { } else {
log('The more... menu was existing and empty! This should not happen'); log('The more... menu was existing and empty! This should not happen');
} }
@ -1064,14 +1238,14 @@ const NMDeviceWireless = new Lang.Class({
let okPrev = true, okNext = true; let okPrev = true, okNext = true;
if (res.network > 0) if (res.network > 0)
okPrev = this._networkSortFunction(this._networks[res.network - 1], network) >= 0; okPrev = this._networkSortFunction(this._networks[res.network - 1], apObj) >= 0;
if (res.network < this._networks.length-1) if (res.network < this._networks.length-1)
okNext = this._networkSortFunction(this._networks[res.network + 1], network) <= 0; okNext = this._networkSortFunction(this._networks[res.network + 1], apObj) <= 0;
if (!okPrev || !okNext) if (!okPrev || !okNext)
this._queueCreateSection(); this._queueCreateSection();
else if (network.item) else if (apObj.item)
network.item.updateBestAP(network.accessPoints[0]); apObj.item.updateBestAP(apObj.accessPoints[0]);
} }
}, },
@ -1110,20 +1284,20 @@ const NMDeviceWireless = new Lang.Class({
let forceupdate = false; let forceupdate = false;
for (let i = 0; i < this._networks.length; i++) { for (let i = 0; i < this._networks.length; i++) {
let network = this._networks[i]; let apObj = this._networks[i];
let connections = network.connections; let connections = apObj.connections;
for (let k = 0; k < connections.length; k++) { for (let k = 0; k < connections.length; k++) {
if (connections[k].get_uuid() == connection.get_uuid()) { if (connections[k].get_uuid() == connection.get_uuid()) {
// remove the connection from the access point group // remove the connection from the access point group
connections.splice(k, 1); connections.splice(k);
forceupdate = forceupdate || connections.length == 0; forceupdate = forceupdate || connections.length == 0;
if (forceupdate) if (forceupdate)
break; break;
if (network.item) { if (apObj.item) {
if (network.item instanceof PopupMenu.PopupSubMenuMenuItem) { if (apObj.item instanceof PopupMenu.PopupSubMenuMenuItem) {
let items = network.item.menu._getMenuItems(); let items = apObj.item.menu._getMenuItems();
if (items.length == 2) { if (items.length == 2) {
// we need to update the connection list to convert this to a normal item // we need to update the connection list to convert this to a normal item
forceupdate = true; forceupdate = true;
@ -1136,8 +1310,8 @@ const NMDeviceWireless = new Lang.Class({
} }
} }
} else { } else {
network.item.destroy(); apObj.item.destroy();
network.item = null; apObj.item = null;
} }
} }
break; break;
@ -1163,13 +1337,13 @@ const NMDeviceWireless = new Lang.Class({
// find an appropriate access point // find an appropriate access point
let forceupdate = false; let forceupdate = false;
for (let i = 0; i < this._networks.length; i++) { for (let i = 0; i < this._networks.length; i++) {
let network = this._networks[i]; let apObj = this._networks[i];
// Check if connection is valid for any of these access points // Check if connection is valid for any of these access points
for (let k = 0; k < network.accessPoints.length; k++) { for (let k = 0; k < apObj.accessPoints.length; k++) {
let ap = network.accessPoints[k]; let ap = apObj.accessPoints[k];
if (ap.connection_valid(connection)) { if (ap.connection_valid(connection)) {
network.connections.push(connection); apObj.connections.push(connection);
// this potentially changes the sorting order // this potentially changes the sorting order
forceupdate = true; forceupdate = true;
break; break;
@ -1190,30 +1364,55 @@ const NMDeviceWireless = new Lang.Class({
else else
title = _("Connected (private)"); title = _("Connected (private)");
this._activeConnectionItem = new NMNetworkMenuItem(this.device.active_access_point, undefined, if (this._activeNetwork)
{ reactive: false }); this._activeConnectionItem = new NMNetworkMenuItem(this.device.active_access_point, undefined,
this._activeConnectionItem.setOrnament(PopupMenu.Ornament.DOT); { reactive: false });
else
this._activeConnectionItem = new PopupMenu.PopupImageMenuItem(title,
'network-wireless-connected-symbolic',
{ reactive: false });
this._activeConnectionItem.setShowDot(true);
}, },
_createNetworkItem: function(network, position) { _createAutomaticConnection: function(apObj) {
if(!network.accessPoints || network.accessPoints.length == 0) { let name;
let ssid = NetworkManager.utils_ssid_to_utf8(apObj.ssid);
if (ssid) {
/* TRANSLATORS: this the automatic wireless connection name (including the network name) */
name = _("Auto %s").format(ssid);
} else
name = _("Auto wireless");
let connection = new NetworkManager.Connection();
connection.add_setting(new NetworkManager.SettingWireless());
connection.add_setting(new NetworkManager.SettingConnection({
id: name,
autoconnect: true, // NetworkManager will know to ignore this if appropriate
uuid: NetworkManager.utils_uuid_generate(),
type: NetworkManager.SETTING_WIRELESS_SETTING_NAME
}));
return connection;
},
_createNetworkItem: function(apObj, position) {
if(!apObj.accessPoints || apObj.accessPoints.length == 0) {
// this should not happen, but I have no idea why it happens // this should not happen, but I have no idea why it happens
return; return;
} }
if(network.connections.length > 0) { if(apObj.connections.length > 0) {
if (network.connections.length == 1) { if (apObj.connections.length == 1) {
network.item = this._createAPItem(network.connections[0], network, false); apObj.item = this._createAPItem(apObj.connections[0], apObj, false);
} else { } else {
let title = network.ssidText; let title = apObj.ssidText;
network.item = new PopupMenu.PopupSubMenuMenuItem(title); apObj.item = new PopupMenu.PopupSubMenuMenuItem(title);
for (let i = 0; i < network.connections.length; i++) for (let i = 0; i < apObj.connections.length; i++)
network.item.menu.addMenuItem(this._createAPItem(network.connections[i], network, true)); apObj.item.menu.addMenuItem(this._createAPItem(apObj.connections[i], apObj, true));
} }
} else { } else {
network.item = new NMNetworkMenuItem(network.accessPoints[0]); apObj.item = new NMNetworkMenuItem(apObj.accessPoints[0]);
network.item.connect('activate', Lang.bind(this, function() { apObj.item.connect('activate', Lang.bind(this, function() {
let accessPoints = network.accessPoints; let accessPoints = apObj.accessPoints;
if ( (accessPoints[0]._secType == NMAccessPointSecurity.WPA2_ENT) if ( (accessPoints[0]._secType == NMAccessPointSecurity.WPA2_ENT)
|| (accessPoints[0]._secType == NMAccessPointSecurity.WPA_ENT)) { || (accessPoints[0]._secType == NMAccessPointSecurity.WPA_ENT)) {
// 802.1x-enabled APs require further configuration, so they're // 802.1x-enabled APs require further configuration, so they're
@ -1221,23 +1420,23 @@ const NMDeviceWireless = new Lang.Class({
Util.spawn(['gnome-control-center', 'network', 'connect-8021x-wifi', Util.spawn(['gnome-control-center', 'network', 'connect-8021x-wifi',
this.device.get_path(), accessPoints[0].dbus_path]); this.device.get_path(), accessPoints[0].dbus_path]);
} else { } else {
let connection = new NetworkManager.Connection(); let connection = this._createAutomaticConnection(apObj);
this._client.add_and_activate_connection(connection, this.device, accessPoints[0].dbus_path, null) this._client.add_and_activate_connection(connection, this.device, accessPoints[0].dbus_path, null)
} }
})); }));
} }
network.item._network = network; apObj.item._apObj = apObj;
if (position < NUM_VISIBLE_NETWORKS) { if (position < NUM_VISIBLE_NETWORKS) {
network.isMore = false; apObj.isMore = false;
this.section.addMenuItem(network.item, position); this.section.addMenuItem(apObj.item, position);
} else { } else {
if (!this._overflowItem) { if (!this._overflowItem) {
this._overflowItem = new PopupMenu.PopupSubMenuMenuItem(_("More…")); this._overflowItem = new PopupMenu.PopupSubMenuMenuItem(_("More…"));
this.section.addMenuItem(this._overflowItem); this.section.addMenuItem(this._overflowItem);
} }
this._overflowItem.menu.addMenuItem(network.item, position - NUM_VISIBLE_NETWORKS); this._overflowItem.menu.addMenuItem(apObj.item, position - NUM_VISIBLE_NETWORKS);
network.isMore = true; apObj.isMore = true;
} }
}, },
@ -1253,13 +1452,13 @@ const NMDeviceWireless = new Lang.Class({
let activeOffset = this._activeConnectionItem ? 1 : 0; let activeOffset = this._activeConnectionItem ? 1 : 0;
for(let j = 0; j < this._networks.length; j++) { for(let j = 0; j < this._networks.length; j++) {
let network = this._networks[j]; let apObj = this._networks[j];
if (network == this._activeNetwork) { if (apObj == this._activeNetwork) {
activeOffset--; activeOffset--;
continue; continue;
} }
this._createNetworkItem(network, j + activeOffset); this._createNetworkItem(apObj, j + activeOffset);
} }
}, },
}); });
@ -1319,14 +1518,18 @@ const NMVPNSection = new Lang.Class({
Extends: NMConnectionBased, Extends: NMConnectionBased,
category: NMConnectionCategory.VPN, category: NMConnectionCategory.VPN,
_init: function(client) { _init: function(client, connections) {
this.parent([]); this.parent(connections);
this._client = client; this._client = client;
this.section = new PopupMenu.PopupMenuSection(); this.section = new PopupMenu.PopupMenuSection();
this._deferredWorkId = Main.initializeDeferredWork(this.section.actor, Lang.bind(this, this._createSection)); this._deferredWorkId = Main.initializeDeferredWork(this.section.actor, Lang.bind(this, this._createSection));
}, },
get empty() {
return this._connections.length == 0;
},
connectionValid: function(connection) { connectionValid: function(connection) {
// filtering is done by NMApplet code // filtering is done by NMApplet code
return true; return true;
@ -1477,9 +1680,11 @@ const NMApplet = new Lang.Class({
// Virtual device types // Virtual device types
this._vtypes = { }; this._vtypes = { };
this._vtypes[NetworkManager.SETTING_VLAN_SETTING_NAME] = NMDeviceVirtual; if (NMGtk) {
this._vtypes[NetworkManager.SETTING_BOND_SETTING_NAME] = NMDeviceVirtual; this._vtypes[NetworkManager.SETTING_VLAN_SETTING_NAME] = NMDeviceVirtual;
this._vtypes[NetworkManager.SETTING_BRIDGE_SETTING_NAME] = NMDeviceVirtual; this._vtypes[NetworkManager.SETTING_BOND_SETTING_NAME] = NMDeviceVirtual;
this._vtypes[NetworkManager.SETTING_BRIDGE_SETTING_NAME] = NMDeviceVirtual;
}
// Connection types // Connection types
this._ctypes = { }; this._ctypes = { };
@ -1491,9 +1696,11 @@ const NMApplet = new Lang.Class({
this._ctypes[NetworkManager.SETTING_CDMA_SETTING_NAME] = NMConnectionCategory.WWAN; this._ctypes[NetworkManager.SETTING_CDMA_SETTING_NAME] = NMConnectionCategory.WWAN;
this._ctypes[NetworkManager.SETTING_GSM_SETTING_NAME] = NMConnectionCategory.WWAN; this._ctypes[NetworkManager.SETTING_GSM_SETTING_NAME] = NMConnectionCategory.WWAN;
this._ctypes[NetworkManager.SETTING_INFINIBAND_SETTING_NAME] = NMConnectionCategory.WIRED; this._ctypes[NetworkManager.SETTING_INFINIBAND_SETTING_NAME] = NMConnectionCategory.WIRED;
this._ctypes[NetworkManager.SETTING_VLAN_SETTING_NAME] = NMConnectionCategory.VIRTUAL; if (NMGtk) {
this._ctypes[NetworkManager.SETTING_BOND_SETTING_NAME] = NMConnectionCategory.VIRTUAL; this._ctypes[NetworkManager.SETTING_VLAN_SETTING_NAME] = NMConnectionCategory.VIRTUAL;
this._ctypes[NetworkManager.SETTING_BRIDGE_SETTING_NAME] = NMConnectionCategory.VIRTUAL; this._ctypes[NetworkManager.SETTING_BOND_SETTING_NAME] = NMConnectionCategory.VIRTUAL;
this._ctypes[NetworkManager.SETTING_BRIDGE_SETTING_NAME] = NMConnectionCategory.VIRTUAL;
}
this._ctypes[NetworkManager.SETTING_VPN_SETTING_NAME] = NMConnectionCategory.VPN; this._ctypes[NetworkManager.SETTING_VPN_SETTING_NAME] = NMConnectionCategory.VPN;
NMClient.Client.new_async(null, Lang.bind(this, this._clientGot)); NMClient.Client.new_async(null, Lang.bind(this, this._clientGot));
@ -1561,7 +1768,7 @@ const NMApplet = new Lang.Class({
this._devices.wireless = { this._devices.wireless = {
section: new PopupMenu.PopupMenuSection(), section: new PopupMenu.PopupMenuSection(),
devices: [ ], devices: [ ],
item: this._makeWirelessToggle() item: this._makeToggleItem('wireless', _("Wi-Fi"))
}; };
this._devices.wireless.section.addMenuItem(this._devices.wireless.item); this._devices.wireless.section.addMenuItem(this._devices.wireless.item);
this._devices.wireless.section.actor.hide(); this._devices.wireless.section.actor.hide();
@ -1576,7 +1783,7 @@ const NMApplet = new Lang.Class({
this.menu.addMenuItem(this._devices.wwan.section); this.menu.addMenuItem(this._devices.wwan.section);
this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem()); this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
this._vpnSection = new NMVPNSection(this._client); this._vpnSection = new NMVPNSection(this._client, this._connections);
this._vpnSection.connect('activation-failed', Lang.bind(this, this._onActivationFailed)); this._vpnSection.connect('activation-failed', Lang.bind(this, this._onActivationFailed));
this.menu.addMenuItem(this._vpnSection.section); this.menu.addMenuItem(this._vpnSection.section);
this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem()); this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
@ -1608,14 +1815,14 @@ const NMApplet = new Lang.Class({
} }
}, },
_makeWirelessToggle: function() { _makeToggleItem: function(type, title) {
let item = new NMWirelessSectionTitleMenuItem(this._client); let item = new NMWirelessSectionTitleMenuItem(this._client, type, title);
item.connect('enabled-changed', Lang.bind(this, function(item, enabled) { item.connect('enabled-changed', Lang.bind(this, function(item, enabled) {
let devices = this._devices.wireless.devices; let devices = this._devices[type].devices;
devices.forEach(function(dev) { devices.forEach(function(dev) {
dev.setEnabled(enabled); dev.setEnabled(enabled);
}); });
this._syncSectionTitle('wireless'); this._syncSectionTitle(type);
})); }));
return item; return item;
}, },
@ -1693,12 +1900,19 @@ const NMApplet = new Lang.Class({
}, },
_syncDeviceNames: function() { _syncDeviceNames: function() {
let names = NMGtk.utils_disambiguate_device_names(this._nmDevices); if (NMGtk) {
for (let i = 0; i < this._nmDevices.length; i++) { let names = NMGtk.utils_disambiguate_device_names(this._nmDevices);
let device = this._nmDevices[i]; for (let i = 0; i < this._nmDevices.length; i++) {
device._description = names[i]; let device = this._nmDevices[i];
if (device._delegate) device._description = names[i];
if (device._delegate)
device._delegate.syncDescription();
}
} else {
for (let i = 0; i < this._nmDevices.length; i++) {
let device = this._nmDevices[i];
device._delegate.syncDescription(); device._delegate.syncDescription();
}
} }
}, },
@ -1734,6 +1948,11 @@ const NMApplet = new Lang.Class({
wrapper._deviceStateChangedId = wrapper.connect('state-changed', Lang.bind(this, function(dev) { wrapper._deviceStateChangedId = wrapper.connect('state-changed', Lang.bind(this, function(dev) {
this._syncSectionTitle(dev.category); this._syncSectionTitle(dev.category);
})); }));
wrapper._destroyId = wrapper.connect('destroy', function(wrapper) {
wrapper.disconnect(wrapper._activationFailedId);
wrapper.disconnect(wrapper._deviceStateChangedId);
wrapper.disconnect(wrapper._destroyId);
});
let section = this._devices[wrapper.category].section; let section = this._devices[wrapper.category].section;
section.addMenuItem(wrapper.statusItem); section.addMenuItem(wrapper.statusItem);
@ -1765,8 +1984,6 @@ const NMApplet = new Lang.Class({
}, },
_removeDeviceWrapper: function(wrapper) { _removeDeviceWrapper: function(wrapper) {
wrapper.disconnect(wrapper._activationFailedId);
wrapper.disconnect(wrapper._deviceStateChangedId);
wrapper.destroy(); wrapper.destroy();
let devices = this._devices[wrapper.category].devices; let devices = this._devices[wrapper.category].devices;
@ -1830,7 +2047,6 @@ const NMApplet = new Lang.Class({
let default_ip4 = null; let default_ip4 = null;
let default_ip6 = null; let default_ip6 = null;
let active_vpn = null; let active_vpn = null;
let active_any = null;
for (let i = 0; i < this._activeConnections.length; i++) { for (let i = 0; i < this._activeConnections.length; i++) {
let a = this._activeConnections[i]; let a = this._activeConnections[i];
@ -1861,21 +2077,24 @@ const NMApplet = new Lang.Class({
if (a.default6) if (a.default6)
default_ip6 = a; default_ip6 = a;
if (a.state == NetworkManager.ActiveConnectionState.ACTIVATING) if (a._type == 'vpn')
activating = a;
else if (a.state == NetworkManager.ActiveConnectionState.ACTIVATED)
active_any = a;
if (a._type == 'vpn' &&
(a.state == NetworkManager.ActiveConnectionState.ACTIVATING ||
a.state == NetworkManager.ActiveConnectionState.ACTIVATED))
active_vpn = a; active_vpn = a;
else if (a.state == NetworkManager.ActiveConnectionState.ACTIVATING)
activating = a;
if (!a._primaryDevice) { if (!a._primaryDevice) {
if (a._type != NetworkManager.SETTING_VPN_SETTING_NAME) if (a._type != NetworkManager.SETTING_VPN_SETTING_NAME) {
// This list is guaranteed to have one device in it. // find a good device to be considered primary
a._primaryDevice = a.get_devices()[0]._delegate; a._primaryDevice = null;
else let devices = a.get_devices() || [];
for (let j = 0; j < devices.length; j++) {
let d = devices[j];
if (d._delegate) {
a._primaryDevice = d._delegate;
break;
}
}
} else
a._primaryDevice = this._vpnSection; a._primaryDevice = this._vpnSection;
if (a._primaryDevice) if (a._primaryDevice)
@ -1889,7 +2108,7 @@ const NMApplet = new Lang.Class({
} }
} }
this._mainConnection = activating || default_ip4 || default_ip6 || active_any || null; this._mainConnection = activating || default_ip4 || default_ip6 || this._activeConnections[0] || null;
this._vpnConnection = active_vpn; this._vpnConnection = active_vpn;
}, },
@ -1915,7 +2134,25 @@ const NMApplet = new Lang.Class({
return false; return false;
}, },
_addConnection: function(connection) { _readConnections: function() {
let connections = this._settings.list_connections();
for (let i = 0; i < connections.length; i++) {
let connection = connections[i];
if (this._ignoreConnection(connection))
continue;
if (connection._updatedId) {
// connection was already seen (for example because NetworkManager was restarted)
continue;
}
connection._removedId = connection.connect('removed', Lang.bind(this, this._connectionRemoved));
connection._updatedId = connection.connect('updated', Lang.bind(this, this._updateConnection));
this._updateConnection(connection);
this._connections.push(connection);
}
},
_newConnection: function(settings, connection) {
if (this._ignoreConnection(connection)) if (this._ignoreConnection(connection))
return; return;
if (connection._updatedId) { if (connection._updatedId) {
@ -1928,22 +2165,14 @@ const NMApplet = new Lang.Class({
this._updateConnection(connection); this._updateConnection(connection);
this._connections.push(connection); this._connections.push(connection);
},
_readConnections: function() {
let connections = this._settings.list_connections();
connections.forEach(Lang.bind(this, this._addConnection));
},
_newConnection: function(settings, connection) {
this._addConnection(connection);
this._updateIcon(); this._updateIcon();
}, },
_connectionRemoved: function(connection) { _connectionRemoved: function(connection) {
let pos = this._connections.indexOf(connection); let pos = this._connections.indexOf(connection);
if (pos != -1) if (pos != -1)
this._connections.splice(connection, 1); this._connections.splice(connection);
let section = connection._section; let section = connection._section;

View File

@ -307,7 +307,7 @@ const Indicator = new Lang.Class({
this._headphoneIcon.visible = value; this._headphoneIcon.visible = value;
})); }));
this._headphoneIcon = this.addIcon(new Gio.ThemedIcon({ name: 'audio-headphones-symbolic' })); this._headphoneIcon = this.addIcon(new Gio.ThemedIcon({ name: 'headphones-symbolic' }));
this._headphoneIcon.visible = false; this._headphoneIcon.visible = false;
this.menu.addMenuItem(this._volumeMenu); this.menu.addMenuItem(this._volumeMenu);

View File

@ -6,17 +6,23 @@ const Gdm = imports.gi.Gdm;
const Gio = imports.gi.Gio; const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib; const GLib = imports.gi.GLib;
const GnomeDesktop = imports.gi.GnomeDesktop; const GnomeDesktop = imports.gi.GnomeDesktop;
const Gtk = imports.gi.Gtk;
const Lang = imports.lang; const Lang = imports.lang;
const Signals = imports.signals;
const Shell = imports.gi.Shell; const Shell = imports.gi.Shell;
const St = imports.gi.St; const St = imports.gi.St;
const Main = imports.ui.main; const Main = imports.ui.main;
const ModalDialog = imports.ui.modalDialog; const ModalDialog = imports.ui.modalDialog;
const Panel = imports.ui.panel;
const ShellEntry = imports.ui.shellEntry; const ShellEntry = imports.ui.shellEntry;
const Tweener = imports.ui.tweener;
const UserMenu = imports.ui.userMenu;
const UserWidget = imports.ui.userWidget; const UserWidget = imports.ui.userWidget;
const AuthUtil = imports.ui.auth.util; const Batch = imports.gdm.batch;
const Batch = imports.misc.batch; const GdmUtil = imports.gdm.util;
const LoginDialog = imports.gdm.loginDialog;
// The timeout before going back automatically to the lock screen (in seconds) // The timeout before going back automatically to the lock screen (in seconds)
const IDLE_TIMEOUT = 2 * 60; const IDLE_TIMEOUT = 2 * 60;
@ -40,7 +46,7 @@ const UnlockDialog = new Lang.Class({
this._firstQuestion = true; this._firstQuestion = true;
this._greeterClient = new Gdm.Client(); this._greeterClient = new Gdm.Client();
this._userVerifier = new AuthUtil.ShellUserVerifier(this._greeterClient, { reauthenticationOnly: true }); this._userVerifier = new GdmUtil.ShellUserVerifier(this._greeterClient, { reauthenticationOnly: true });
this._userVerified = false; this._userVerified = false;
this._userVerifier.connect('ask-question', Lang.bind(this, this._onAskQuestion)); this._userVerifier.connect('ask-question', Lang.bind(this, this._onAskQuestion));
@ -85,6 +91,9 @@ const UnlockDialog = new Lang.Class({
this._promptLoginHint.hide(); this._promptLoginHint.hide();
this.contentLayout.add_actor(this._promptLoginHint); this.contentLayout.add_actor(this._promptLoginHint);
this._workSpinner = new Panel.AnimatedIcon('process-working.svg', LoginDialog.WORK_SPINNER_ICON_SIZE);
this._workSpinner.actor.opacity = 0;
this.allowCancel = false; this.allowCancel = false;
this.buttonLayout.visible = true; this.buttonLayout.visible = true;
this.addButton({ label: _("Cancel"), this.addButton({ label: _("Cancel"),
@ -95,11 +104,12 @@ const UnlockDialog = new Lang.Class({
y_fill: false, y_fill: false,
x_align: St.Align.START, x_align: St.Align.START,
y_align: St.Align.MIDDLE }); y_align: St.Align.MIDDLE });
this.placeSpinner({ expand: false, this.buttonLayout.add(this._workSpinner.actor,
x_fill: false, { expand: false,
y_fill: false, x_fill: false,
x_align: St.Align.END, y_fill: false,
y_align: St.Align.MIDDLE }); x_align: St.Align.END,
y_align: St.Align.MIDDLE });
this._okButton = this.addButton({ label: _("Unlock"), this._okButton = this.addButton({ label: _("Unlock"),
action: Lang.bind(this, this._doUnlock), action: Lang.bind(this, this._doUnlock),
default: true }, default: true },
@ -153,13 +163,35 @@ const UnlockDialog = new Lang.Class({
this._okButton.can_focus = sensitive; this._okButton.can_focus = sensitive;
}, },
_setWorking: function(working) {
if (working) {
this._workSpinner.play();
Tweener.addTween(this._workSpinner.actor,
{ opacity: 255,
delay: LoginDialog.WORK_SPINNER_ANIMATION_DELAY,
time: LoginDialog.WORK_SPINNER_ANIMATION_TIME,
transition: 'linear'
});
} else {
Tweener.addTween(this._workSpinner.actor,
{ opacity: 0,
time: LoginDialog.WORK_SPINNER_ANIMATION_TIME,
transition: 'linear',
onCompleteScope: this,
onComplete: function() {
this._workSpinner.stop();
}
});
}
},
_showMessage: function(userVerifier, message, styleClass) { _showMessage: function(userVerifier, message, styleClass) {
if (message) { if (message) {
this._promptMessage.text = message; this._promptMessage.text = message;
this._promptMessage.styleClass = styleClass; this._promptMessage.styleClass = styleClass;
AuthUtil.fadeInActor(this._promptMessage); GdmUtil.fadeInActor(this._promptMessage);
} else { } else {
AuthUtil.fadeOutActor(this._promptMessage); GdmUtil.fadeOutActor(this._promptMessage);
} }
}, },
@ -183,16 +215,16 @@ const UnlockDialog = new Lang.Class({
this._currentQuery = serviceName; this._currentQuery = serviceName;
this._updateSensitivity(true); this._updateSensitivity(true);
this.setWorking(false); this._setWorking(false);
}, },
_showLoginHint: function(verifier, message) { _showLoginHint: function(verifier, message) {
this._promptLoginHint.set_text(message) this._promptLoginHint.set_text(message)
AuthUtil.fadeInActor(this._promptLoginHint); GdmUtil.fadeInActor(this._promptLoginHint);
}, },
_hideLoginHint: function() { _hideLoginHint: function() {
AuthUtil.fadeOutActor(this._promptLoginHint); GdmUtil.fadeOutActor(this._promptLoginHint);
}, },
_doUnlock: function() { _doUnlock: function() {
@ -202,7 +234,7 @@ const UnlockDialog = new Lang.Class({
// the actual reply to GDM will be sent as soon as asked // the actual reply to GDM will be sent as soon as asked
this._firstQuestionAnswer = this._promptEntry.text; this._firstQuestionAnswer = this._promptEntry.text;
this._updateSensitivity(false); this._updateSensitivity(false);
this.setWorking(true); this._setWorking(true);
return; return;
} }
@ -213,7 +245,7 @@ const UnlockDialog = new Lang.Class({
this._currentQuery = null; this._currentQuery = null;
this._updateSensitivity(false); this._updateSensitivity(false);
this.setWorking(true); this._setWorking(true);
this._userVerifier.answerQuery(query, this._promptEntry.text); this._userVerifier.answerQuery(query, this._promptEntry.text);
}, },
@ -253,7 +285,7 @@ const UnlockDialog = new Lang.Class({
this._promptEntry.menu.isPassword = true; this._promptEntry.menu.isPassword = true;
this._updateSensitivity(false); this._updateSensitivity(false);
this.setWorking(false); this._setWorking(false);
}, },
_escape: function() { _escape: function() {

View File

@ -1,52 +0,0 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const Lang = imports.lang;
const St = imports.gi.St;
const Params = imports.misc.params;
const DIALOG_ICON_SIZE = 64;
// Adapted from gdm/gui/user-switch-applet/applet.c
//
// Copyright (C) 2004-2005 James M. Cape <jcape@ignore-your.tv>.
// Copyright (C) 2008,2009 Red Hat, Inc.
const UserAvatar = new Lang.Class({
Name: 'UserAvatar',
_init: function(user, params) {
this._user = user;
params = Params.parse(params, { reactive: false,
iconSize: DIALOG_ICON_SIZE,
styleClass: 'status-chooser-user-icon' });
this._iconSize = params.iconSize;
this.actor = new St.Bin({ style_class: params.styleClass,
track_hover: params.reactive,
reactive: params.reactive });
},
setSensitive: function(sensitive) {
this.actor.can_focus = sensitive;
this.actor.reactive = sensitive;
},
update: function() {
let iconFile = this._user.get_icon_file();
if (iconFile && !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-symbolic',
icon_size: this._iconSize });
}
}
});

View File

@ -21,7 +21,6 @@ const ModalDialog = imports.ui.modalDialog;
const PanelMenu = imports.ui.panelMenu; const PanelMenu = imports.ui.panelMenu;
const PopupMenu = imports.ui.popupMenu; const PopupMenu = imports.ui.popupMenu;
const Params = imports.misc.params; const Params = imports.misc.params;
const UserAvatar = imports.ui.userAvatar;
const Util = imports.misc.util; const Util = imports.misc.util;
const LOCKDOWN_SCHEMA = 'org.gnome.desktop.lockdown'; const LOCKDOWN_SCHEMA = 'org.gnome.desktop.lockdown';
@ -58,6 +57,48 @@ const SystemdLoginSessionIface = <interface name='org.freedesktop.login1.Session
const SystemdLoginSession = Gio.DBusProxy.makeProxyWrapper(SystemdLoginSessionIface); const SystemdLoginSession = Gio.DBusProxy.makeProxyWrapper(SystemdLoginSessionIface);
// Adapted from gdm/gui/user-switch-applet/applet.c
//
// 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, params) {
this._user = user;
params = Params.parse(params, { reactive: false,
iconSize: DIALOG_ICON_SIZE,
styleClass: 'status-chooser-user-icon' });
this._iconSize = params.iconSize;
this.actor = new St.Bin({ style_class: params.styleClass,
track_hover: params.reactive,
reactive: params.reactive });
},
setSensitive: function(sensitive) {
this.actor.can_focus = sensitive;
this.actor.reactive = sensitive;
},
update: function() {
let iconFile = this._user.get_icon_file();
if (iconFile && !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-symbolic',
icon_size: this._iconSize });
}
}
});
const IMStatusItem = new Lang.Class({ const IMStatusItem = new Lang.Class({
Name: 'IMStatusItem', Name: 'IMStatusItem',
Extends: PopupMenu.PopupBaseMenuItem, Extends: PopupMenu.PopupBaseMenuItem,
@ -129,7 +170,7 @@ const IMStatusChooserItem = new Lang.Class({
this._userManager = AccountsService.UserManager.get_default(); this._userManager = AccountsService.UserManager.get_default();
this._user = this._userManager.get_user(GLib.get_user_name()); this._user = this._userManager.get_user(GLib.get_user_name());
this._avatar = new UserAvatar.UserAvatar(this._user, { reactive: true }); this._avatar = new UserAvatarWidget(this._user, { reactive: true });
this._iconBin = new St.Button({ child: this._avatar.actor }); this._iconBin = new St.Button({ child: this._avatar.actor });
this.addActor(this._iconBin); this.addActor(this._iconBin);
@ -867,7 +908,7 @@ const UserMenuButton = new Lang.Class({
let session = sessions[i]; let session = sessions[i];
let userEntry = new St.BoxLayout({ style_class: 'login-dialog-user-list-item', let userEntry = new St.BoxLayout({ style_class: 'login-dialog-user-list-item',
vertical: false }); vertical: false });
let avatar = new UserAvatar.UserAvatar(session.user); let avatar = new UserAvatarWidget(session.user);
avatar.update(); avatar.update();
userEntry.add(avatar.actor); userEntry.add(avatar.actor);

View File

@ -6,7 +6,7 @@ const AccountsService = imports.gi.AccountsService;
const Lang = imports.lang; const Lang = imports.lang;
const St = imports.gi.St; const St = imports.gi.St;
const UserAvatar = imports.ui.userAvatar; const UserMenu = imports.ui.userMenu;
const UserWidget = new Lang.Class({ const UserWidget = new Lang.Class({
Name: 'UserWidget', Name: 'UserWidget',
@ -16,9 +16,8 @@ const UserWidget = new Lang.Class({
this.actor = new St.BoxLayout({ style_class: 'user-widget', this.actor = new St.BoxLayout({ style_class: 'user-widget',
vertical: false }); vertical: false });
this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
this._avatar = new UserAvatar.UserAvatar(user); this._avatar = new UserMenu.UserAvatarWidget(user);
this.actor.add(this._avatar.actor, this.actor.add(this._avatar.actor,
{ x_fill: true, y_fill: true }); { x_fill: true, y_fill: true });
@ -37,7 +36,7 @@ const UserWidget = new Lang.Class({
this._updateUser(); this._updateUser();
}, },
_onDestroy: function() { destroy: function() {
if (this._userLoadedId != 0) { if (this._userLoadedId != 0) {
this._user.disconnect(this._userLoadedId); this._user.disconnect(this._userLoadedId);
this._userLoadedId = 0; this._userLoadedId = 0;
@ -47,6 +46,8 @@ const UserWidget = new Lang.Class({
this._user.disconnect(this._userChangedId); this._user.disconnect(this._userChangedId);
this._userChangedId = 0; this._userChangedId = 0;
} }
this.actor.destroy();
}, },
_updateUser: function() { _updateUser: function() {

View File

@ -150,14 +150,6 @@ const ViewSelector = new Lang.Class({
Shell.KeyBindingMode.NORMAL | Shell.KeyBindingMode.NORMAL |
Shell.KeyBindingMode.OVERVIEW, Shell.KeyBindingMode.OVERVIEW,
Lang.bind(this, this._toggleAppsPage)); Lang.bind(this, this._toggleAppsPage));
Main.wm.addKeybinding('toggle-overview',
new Gio.Settings({ schema: SHELL_KEYBINDINGS_SCHEMA }),
Meta.KeyBindingFlags.NONE,
Shell.KeyBindingMode.NORMAL |
Shell.KeyBindingMode.OVERVIEW,
Lang.bind(Main.overview, Main.overview.toggle));
}, },
_toggleAppsPage: function() { _toggleAppsPage: function() {
@ -186,10 +178,6 @@ const ViewSelector = new Lang.Class({
Main.overview.fadeInDesktop(); Main.overview.fadeInDesktop();
}, },
setWorkspacesFullGeometry: function(geom) {
this._workspacesDisplay.setWorkspacesFullGeometry(geom);
},
hide: function() { hide: function() {
this._workspacesDisplay.hide(); this._workspacesDisplay.hide();
}, },
@ -508,12 +496,12 @@ const ViewSelector = new Lang.Class({
return; return;
this._searchSystem.registerProvider(provider); this._searchSystem.registerProvider(provider);
this._searchResults.createProviderDisplay(provider); this._searchResults.createProviderMeta(provider);
}, },
removeSearchProvider: function(provider) { removeSearchProvider: function(provider) {
this._searchSystem.unregisterProvider(provider); this._searchSystem.unregisterProvider(provider);
this._searchResults.destroyProviderDisplay(provider); this._searchResults.destroyProviderMeta(provider);
}, },
getActivePage: function() { getActivePage: function() {

View File

@ -134,9 +134,9 @@ const WandaSearchProvider = new Lang.Class({
getInitialResultSet: function(terms) { getInitialResultSet: function(terms) {
if (terms.join(' ') == MAGIC_FISH_KEY) { if (terms.join(' ') == MAGIC_FISH_KEY) {
this.searchSystem.setResults(this, [ FISH_NAME ]); this.searchSystem.pushResults(this, [ FISH_NAME ]);
} else { } else {
this.searchSystem.setResults(this, []); this.searchSystem.pushResults(this, []);
} }
}, },

View File

@ -4,7 +4,6 @@ const Clutter = imports.gi.Clutter;
const GLib = imports.gi.GLib; const GLib = imports.gi.GLib;
const Gio = imports.gi.Gio; const Gio = imports.gi.Gio;
const Lang = imports.lang; const Lang = imports.lang;
const Mainloop = imports.mainloop;
const Meta = imports.gi.Meta; const Meta = imports.gi.Meta;
const St = imports.gi.St; const St = imports.gi.St;
const Shell = imports.gi.Shell; const Shell = imports.gi.Shell;
@ -67,209 +66,6 @@ function getWindowDimmer(actor) {
} }
} }
/*
* When the last window closed on a workspace is a dialog or splash
* screen, we assume that it might be an initial window shown before
* the main window of an application, and give the app a grace period
* where it can map another window before we remove the workspace.
*/
const LAST_WINDOW_GRACE_TIME = 1000;
const WorkspaceTracker = new Lang.Class({
Name: 'WorkspaceTracker',
_init: function(wm) {
this._wm = wm;
this._workspaces = [];
this._checkWorkspacesId = 0;
let tracker = Shell.WindowTracker.get_default();
tracker.connect('startup-sequence-changed', Lang.bind(this, this._queueCheckWorkspaces));
global.screen.connect('notify::n-workspaces', Lang.bind(this, this._nWorkspacesChanged));
global.screen.connect('window-entered-monitor', Lang.bind(this, this._windowEnteredMonitor));
global.screen.connect('window-left-monitor', Lang.bind(this, this._windowLeftMonitor));
global.screen.connect('restacked', Lang.bind(this, this._windowsRestacked));
this._overrideSettings = new Gio.Settings({ schema: 'org.gnome.shell.overrides' });
this._overrideSettings.connect('changed::dynamic-workspaces', Lang.bind(this, this._queueCheckWorkspaces));
this._nWorkspacesChanged();
},
_checkWorkspaces: function() {
let i;
let emptyWorkspaces = [];
if (!Meta.prefs_get_dynamic_workspaces()) {
this._checkWorkspacesId = 0;
return false;
}
for (i = 0; i < this._workspaces.length; i++) {
let lastRemoved = this._workspaces[i]._lastRemovedWindow;
if ((lastRemoved &&
(lastRemoved.get_window_type() == Meta.WindowType.SPLASHSCREEN ||
lastRemoved.get_window_type() == Meta.WindowType.DIALOG ||
lastRemoved.get_window_type() == Meta.WindowType.MODAL_DIALOG)) ||
this._workspaces[i]._keepAliveId)
emptyWorkspaces[i] = false;
else
emptyWorkspaces[i] = true;
}
let sequences = Shell.WindowTracker.get_default().get_startup_sequences();
for (i = 0; i < sequences.length; i++) {
let index = sequences[i].get_workspace();
if (index >= 0 && index <= global.screen.n_workspaces)
emptyWorkspaces[index] = false;
}
let windows = global.get_window_actors();
for (i = 0; i < windows.length; i++) {
let win = windows[i];
if (win.get_meta_window().is_on_all_workspaces())
continue;
let workspaceIndex = win.get_workspace();
emptyWorkspaces[workspaceIndex] = false;
}
// If we don't have an empty workspace at the end, add one
if (!emptyWorkspaces[emptyWorkspaces.length -1]) {
global.screen.append_new_workspace(false, global.get_current_time());
emptyWorkspaces.push(false);
}
let activeWorkspaceIndex = global.screen.get_active_workspace_index();
let removingCurrentWorkspace = (emptyWorkspaces[activeWorkspaceIndex] &&
activeWorkspaceIndex < emptyWorkspaces.length - 1);
// Don't enter the overview when removing multiple empty workspaces at startup
let showOverview = (removingCurrentWorkspace &&
!emptyWorkspaces.every(function(x) { return x; }));
if (removingCurrentWorkspace) {
// "Merge" the empty workspace we are removing with the one at the end
this._wm.blockAnimations();
}
// Delete other empty workspaces; do it from the end to avoid index changes
for (i = emptyWorkspaces.length - 2; i >= 0; i--) {
if (emptyWorkspaces[i])
global.screen.remove_workspace(this._workspaces[i], global.get_current_time());
}
if (removingCurrentWorkspace) {
global.screen.get_workspace_by_index(global.screen.n_workspaces - 1).activate(global.get_current_time());
this._wm.unblockAnimations();
if (!Main.overview.visible && showOverview)
Main.overview.show();
}
this._checkWorkspacesId = 0;
return false;
},
keepWorkspaceAlive: function(workspace, duration) {
if (workspace._keepAliveId)
Mainloop.source_remove(workspace._keepAliveId);
workspace._keepAliveId = Mainloop.timeout_add(duration, Lang.bind(this, function() {
workspace._keepAliveId = 0;
this._queueCheckWorkspaces();
return false;
}));
},
_windowRemoved: function(workspace, window) {
workspace._lastRemovedWindow = window;
this._queueCheckWorkspaces();
Mainloop.timeout_add(LAST_WINDOW_GRACE_TIME, Lang.bind(this, function() {
if (workspace._lastRemovedWindow == window) {
workspace._lastRemovedWindow = null;
this._queueCheckWorkspaces();
}
return false;
}));
},
_windowLeftMonitor: function(metaScreen, monitorIndex, metaWin) {
// If the window left the primary monitor, that
// might make that workspace empty
if (monitorIndex == Main.layoutManager.primaryIndex)
this._queueCheckWorkspaces();
},
_windowEnteredMonitor: function(metaScreen, monitorIndex, metaWin) {
// If the window entered the primary monitor, that
// might make that workspace non-empty
if (monitorIndex == Main.layoutManager.primaryIndex)
this._queueCheckWorkspaces();
},
_windowsRestacked: function() {
// Figure out where the pointer is in case we lost track of
// it during a grab. (In particular, if a trayicon popup menu
// is dismissed, see if we need to close the message tray.)
global.sync_pointer();
},
_queueCheckWorkspaces: function() {
if (this._checkWorkspacesId == 0)
this._checkWorkspacesId = Meta.later_add(Meta.LaterType.BEFORE_REDRAW, Lang.bind(this, this._checkWorkspaces));
},
_nWorkspacesChanged: function() {
let oldNumWorkspaces = this._workspaces.length;
let newNumWorkspaces = global.screen.n_workspaces;
if (oldNumWorkspaces == newNumWorkspaces)
return false;
let lostWorkspaces = [];
if (newNumWorkspaces > oldNumWorkspaces) {
let w;
// Assume workspaces are only added at the end
for (w = oldNumWorkspaces; w < newNumWorkspaces; w++)
this._workspaces[w] = global.screen.get_workspace_by_index(w);
for (w = oldNumWorkspaces; w < newNumWorkspaces; w++) {
let workspace = this._workspaces[w];
workspace._windowAddedId = workspace.connect('window-added', Lang.bind(this, this._queueCheckWorkspaces));
workspace._windowRemovedId = workspace.connect('window-removed', Lang.bind(this, this._windowRemoved));
}
} else {
// Assume workspaces are only removed sequentially
// (e.g. 2,3,4 - not 2,4,7)
let removedIndex;
let removedNum = oldNumWorkspaces - newNumWorkspaces;
for (let w = 0; w < oldNumWorkspaces; w++) {
let workspace = global.screen.get_workspace_by_index(w);
if (this._workspaces[w] != workspace) {
removedIndex = w;
break;
}
}
let lostWorkspaces = this._workspaces.splice(removedIndex, removedNum);
lostWorkspaces.forEach(function(workspace) {
workspace.disconnect(workspace._windowAddedId);
workspace.disconnect(workspace._windowRemovedId);
});
}
this._queueCheckWorkspaces();
return false;
}
});
const WindowManager = new Lang.Class({ const WindowManager = new Lang.Class({
Name: 'WindowManager', Name: 'WindowManager',
@ -340,90 +136,6 @@ const WindowManager = new Lang.Class({
Shell.KeyBindingMode.NORMAL | Shell.KeyBindingMode.NORMAL |
Shell.KeyBindingMode.OVERVIEW, Shell.KeyBindingMode.OVERVIEW,
Lang.bind(this, this._showWorkspaceSwitcher)); Lang.bind(this, this._showWorkspaceSwitcher));
this.setCustomKeybindingHandler('switch-to-workspace-1',
Shell.KeyBindingMode.NORMAL |
Shell.KeyBindingMode.OVERVIEW,
Lang.bind(this, this._showWorkspaceSwitcher));
this.setCustomKeybindingHandler('switch-to-workspace-2',
Shell.KeyBindingMode.NORMAL |
Shell.KeyBindingMode.OVERVIEW,
Lang.bind(this, this._showWorkspaceSwitcher));
this.setCustomKeybindingHandler('switch-to-workspace-3',
Shell.KeyBindingMode.NORMAL |
Shell.KeyBindingMode.OVERVIEW,
Lang.bind(this, this._showWorkspaceSwitcher));
this.setCustomKeybindingHandler('switch-to-workspace-4',
Shell.KeyBindingMode.NORMAL |
Shell.KeyBindingMode.OVERVIEW,
Lang.bind(this, this._showWorkspaceSwitcher));
this.setCustomKeybindingHandler('switch-to-workspace-5',
Shell.KeyBindingMode.NORMAL |
Shell.KeyBindingMode.OVERVIEW,
Lang.bind(this, this._showWorkspaceSwitcher));
this.setCustomKeybindingHandler('switch-to-workspace-6',
Shell.KeyBindingMode.NORMAL |
Shell.KeyBindingMode.OVERVIEW,
Lang.bind(this, this._showWorkspaceSwitcher));
this.setCustomKeybindingHandler('switch-to-workspace-7',
Shell.KeyBindingMode.NORMAL |
Shell.KeyBindingMode.OVERVIEW,
Lang.bind(this, this._showWorkspaceSwitcher));
this.setCustomKeybindingHandler('switch-to-workspace-8',
Shell.KeyBindingMode.NORMAL |
Shell.KeyBindingMode.OVERVIEW,
Lang.bind(this, this._showWorkspaceSwitcher));
this.setCustomKeybindingHandler('switch-to-workspace-9',
Shell.KeyBindingMode.NORMAL |
Shell.KeyBindingMode.OVERVIEW,
Lang.bind(this, this._showWorkspaceSwitcher));
this.setCustomKeybindingHandler('switch-to-workspace-10',
Shell.KeyBindingMode.NORMAL |
Shell.KeyBindingMode.OVERVIEW,
Lang.bind(this, this._showWorkspaceSwitcher));
this.setCustomKeybindingHandler('switch-to-workspace-11',
Shell.KeyBindingMode.NORMAL |
Shell.KeyBindingMode.OVERVIEW,
Lang.bind(this, this._showWorkspaceSwitcher));
this.setCustomKeybindingHandler('switch-to-workspace-12',
Shell.KeyBindingMode.NORMAL |
Shell.KeyBindingMode.OVERVIEW,
Lang.bind(this, this._showWorkspaceSwitcher));
this.setCustomKeybindingHandler('move-to-workspace-1',
Shell.KeyBindingMode.NORMAL,
Lang.bind(this, this._showWorkspaceSwitcher));
this.setCustomKeybindingHandler('move-to-workspace-2',
Shell.KeyBindingMode.NORMAL,
Lang.bind(this, this._showWorkspaceSwitcher));
this.setCustomKeybindingHandler('move-to-workspace-3',
Shell.KeyBindingMode.NORMAL,
Lang.bind(this, this._showWorkspaceSwitcher));
this.setCustomKeybindingHandler('move-to-workspace-4',
Shell.KeyBindingMode.NORMAL,
Lang.bind(this, this._showWorkspaceSwitcher));
this.setCustomKeybindingHandler('move-to-workspace-5',
Shell.KeyBindingMode.NORMAL,
Lang.bind(this, this._showWorkspaceSwitcher));
this.setCustomKeybindingHandler('move-to-workspace-6',
Shell.KeyBindingMode.NORMAL,
Lang.bind(this, this._showWorkspaceSwitcher));
this.setCustomKeybindingHandler('move-to-workspace-7',
Shell.KeyBindingMode.NORMAL,
Lang.bind(this, this._showWorkspaceSwitcher));
this.setCustomKeybindingHandler('move-to-workspace-8',
Shell.KeyBindingMode.NORMAL,
Lang.bind(this, this._showWorkspaceSwitcher));
this.setCustomKeybindingHandler('move-to-workspace-9',
Shell.KeyBindingMode.NORMAL,
Lang.bind(this, this._showWorkspaceSwitcher));
this.setCustomKeybindingHandler('move-to-workspace-10',
Shell.KeyBindingMode.NORMAL,
Lang.bind(this, this._showWorkspaceSwitcher));
this.setCustomKeybindingHandler('move-to-workspace-11',
Shell.KeyBindingMode.NORMAL,
Lang.bind(this, this._showWorkspaceSwitcher));
this.setCustomKeybindingHandler('move-to-workspace-12',
Shell.KeyBindingMode.NORMAL,
Lang.bind(this, this._showWorkspaceSwitcher));
this.setCustomKeybindingHandler('switch-applications', this.setCustomKeybindingHandler('switch-applications',
Shell.KeyBindingMode.NORMAL, Shell.KeyBindingMode.NORMAL,
Lang.bind(this, this._startAppSwitcher)); Lang.bind(this, this._startAppSwitcher));
@ -460,9 +172,8 @@ const WindowManager = new Lang.Class({
this.addKeybinding('open-application-menu', this.addKeybinding('open-application-menu',
new Gio.Settings({ schema: SHELL_KEYBINDINGS_SCHEMA }), new Gio.Settings({ schema: SHELL_KEYBINDINGS_SCHEMA }),
Meta.KeyBindingFlags.NONE, Meta.KeyBindingFlags.NONE,
Shell.KeyBindingMode.NORMAL | Shell.KeyBindingMode.NORMAL,
Shell.KeyBindingMode.TOPBAR_POPUP, Lang.bind(this, this._openAppMenu));
Lang.bind(this, this._toggleAppMenu));
Main.overview.connect('showing', Lang.bind(this, function() { Main.overview.connect('showing', Lang.bind(this, function() {
for (let i = 0; i < this._dimmedWindows.length; i++) for (let i = 0; i < this._dimmedWindows.length; i++)
@ -472,11 +183,6 @@ const WindowManager = new Lang.Class({
for (let i = 0; i < this._dimmedWindows.length; i++) for (let i = 0; i < this._dimmedWindows.length; i++)
this._dimWindow(this._dimmedWindows[i]); this._dimWindow(this._dimmedWindows[i]);
})); }));
this._workspaceTracker = new WorkspaceTracker(this);
global.screen.override_workspace_layout(Meta.ScreenCorner.TOPLEFT,
false, -1, 1);
}, },
setCustomKeybindingHandler: function(name, modes, handler) { setCustomKeybindingHandler: function(name, modes, handler) {
@ -973,39 +679,27 @@ const WindowManager = new Lang.Class({
Main.ctrlAltTabManager.popup(backwards, binding.get_name(), binding.get_mask()); Main.ctrlAltTabManager.popup(backwards, binding.get_name(), binding.get_mask());
}, },
_toggleAppMenu : function(display, screen, window, event, binding) { _openAppMenu : function(display, screen, window, event, binding) {
Main.panel.toggleAppMenu(); Main.panel.openAppMenu();
}, },
_showWorkspaceSwitcher : function(display, screen, window, binding) { _showWorkspaceSwitcher : function(display, screen, window, binding) {
if (screen.n_workspaces == 1) if (screen.n_workspaces == 1)
return; return;
let [action,,,target] = binding.get_name().split('-'); let [action,,,direction] = binding.get_name().split('-');
let direction = Meta.MotionDirection[direction.toUpperCase()];
let newWs; let newWs;
let direction;
if (isNaN(target)) {
direction = Meta.MotionDirection[target.toUpperCase()];
newWs = screen.get_active_workspace().get_neighbor(direction);
} else if (target > 0) {
target--;
newWs = screen.get_workspace_by_index(target);
if (screen.get_active_workspace().index() > target)
direction = Meta.MotionDirection.UP;
else
direction = Meta.MotionDirection.DOWN;
}
if (direction != Meta.MotionDirection.UP && if (direction != Meta.MotionDirection.UP &&
direction != Meta.MotionDirection.DOWN) direction != Meta.MotionDirection.DOWN)
return; return;
if (action == 'switch') if (action == 'switch')
this.actionMoveWorkspace(newWs); newWs = this.actionMoveWorkspace(direction);
else else
this.actionMoveWindow(window, newWs); newWs = this.actionMoveWindow(window, direction);
if (!Main.overview.visible) { if (!Main.overview.visible) {
if (this._workspaceSwitcherPopup == null) { if (this._workspaceSwitcherPopup == null) {
@ -1018,27 +712,31 @@ const WindowManager = new Lang.Class({
} }
}, },
actionMoveWorkspace: function(workspace) { actionMoveWorkspace: function(direction) {
let activeWorkspace = global.screen.get_active_workspace(); let activeWorkspace = global.screen.get_active_workspace();
let toActivate = activeWorkspace.get_neighbor(direction);
if (activeWorkspace != workspace) if (activeWorkspace != toActivate)
workspace.activate(global.get_current_time()); toActivate.activate(global.get_current_time());
return toActivate;
}, },
actionMoveWindow: function(window, workspace) { actionMoveWindow: function(window, direction) {
let activeWorkspace = global.screen.get_active_workspace(); let activeWorkspace = global.screen.get_active_workspace();
let toActivate = activeWorkspace.get_neighbor(direction);
if (activeWorkspace != workspace) { if (activeWorkspace != toActivate) {
// This won't have any effect for "always sticky" windows // This won't have any effect for "always sticky" windows
// (like desktop windows or docks) // (like desktop windows or docks)
this._movingWindow = window; this._movingWindow = window;
window.change_workspace(workspace); window.change_workspace(toActivate);
global.display.clear_mouse_mode(); global.display.clear_mouse_mode();
workspace.activate_with_focus (window, global.get_current_time()); toActivate.activate_with_focus (window, global.get_current_time());
} }
return toActivate;
}, },
}); });

View File

@ -453,10 +453,6 @@ const WindowOverlay = new Lang.Class({
metaWindow.delete(global.get_current_time()); metaWindow.delete(global.get_current_time());
}, },
_windowCanClose: function() {
return this._windowClone.metaWindow.can_close();
},
_onWindowAdded: function(workspace, win) { _onWindowAdded: function(workspace, win) {
let metaWindow = this._windowClone.metaWindow; let metaWindow = this._windowClone.metaWindow;
@ -492,14 +488,12 @@ const WindowOverlay = new Lang.Class({
_animateVisible: function() { _animateVisible: function() {
this._parentActor.raise_top(); this._parentActor.raise_top();
if (this._windowCanClose()) { this.closeButton.show();
this.closeButton.show(); this.closeButton.opacity = 0;
this.closeButton.opacity = 0; Tweener.addTween(this.closeButton,
Tweener.addTween(this.closeButton, { opacity: 255,
{ opacity: 255, time: CLOSE_BUTTON_FADE_TIME,
time: CLOSE_BUTTON_FADE_TIME, transition: 'easeOutQuad' });
transition: 'easeOutQuad' });
}
this.border.show(); this.border.show();
this.border.opacity = 0; this.border.opacity = 0;
@ -759,6 +753,13 @@ const LayoutStrategy = new Lang.Class({
layout.space = space; layout.space = space;
}, },
_getDistance: function (row, actor) {
let dist_x = actor.x - row.x;
let dist_y = actor.y - row.y;
return Math.sqrt(Math.pow(dist_x, 2) + Math.pow(dist_y, 2));
},
computeWindowSlots: function(layout, area) { computeWindowSlots: function(layout, area) {
this._computeRowSizes(layout); this._computeRowSizes(layout);
@ -766,36 +767,28 @@ const LayoutStrategy = new Lang.Class({
let slots = []; let slots = [];
// Do this in three parts.
let height = 0;
for (let i = 0; i < rows.length; i++) {
let row = rows[i];
height += row.height + this._rowSpacing;
}
height -= this._rowSpacing;
let y = 0; let y = 0;
for (let i = 0; i < rows.length; i++) { for (let i = 0; i < rows.length; i++) {
let row = rows[i]; let row = rows[i];
row.x = area.x + (area.width - row.width) / 2;
// If this window layout row doesn't fit in the actual row.y = area.y + y;
// geometry, then apply an additional scale to it.
row.additionalScale = Math.min(1, area.width / row.width, area.height / height);
row.x = area.x + (Math.max(area.width - row.width, 0) / 2) * row.additionalScale;
row.y = area.y + (y + Math.max(area.height - height, 0) / 2) * row.additionalScale;
y += row.height + this._rowSpacing; y += row.height + this._rowSpacing;
row.windows.sort(Lang.bind(this, function(a, b) {
return this._getDistance(row, a.realWindow) - this._getDistance(row, b.realWindow);
}));
} }
let height = y - this._rowSpacing;
let baseY = (area.height - height) / 2;
for (let i = 0; i < rows.length; i++) { for (let i = 0; i < rows.length; i++) {
let row = rows[i]; let row = rows[i];
row.y += baseY;
let x = row.x; let x = row.x;
for (let j = 0; j < row.windows.length; j++) { for (let j = 0; j < row.windows.length; j++) {
let window = row.windows[j]; let window = row.windows[j];
let s = scale * this._computeWindowScale(window) * row.additionalScale; let s = scale * this._computeWindowScale(window);
let cellWidth = window.actor.width * s; let cellWidth = window.actor.width * s;
let cellHeight = window.actor.height * s; let cellHeight = window.actor.height * s;
@ -839,13 +832,6 @@ const UnalignedLayoutStrategy = new Lang.Class({
return false; return false;
}, },
_sortRow: function(row) {
// Sort windows horizontally to minimize travel distance
row.windows.sort(function(a, b) {
return a.realWindow.x - b.realWindow.x;
});
},
computeLayout: function(windows, layout) { computeLayout: function(windows, layout) {
let numRows = layout.numRows; let numRows = layout.numRows;
@ -876,7 +862,6 @@ const UnalignedLayoutStrategy = new Lang.Class({
row.windows.push(window); row.windows.push(window);
row.fullWidth += width; row.fullWidth += width;
} else { } else {
this._sortRow(row);
break; break;
} }
} }
@ -898,14 +883,6 @@ const UnalignedLayoutStrategy = new Lang.Class({
} }
}); });
function padArea(area, padding) {
return {
x: area.x + padding.left,
y: area.y + padding.top,
width: area.width - padding.left - padding.right,
height: area.height - padding.top - padding.bottom,
};
}
/** /**
* @metaWorkspace: a #Meta.Workspace, or null * @metaWorkspace: a #Meta.Workspace, or null
@ -917,19 +894,10 @@ const Workspace = new Lang.Class({
// When dragging a window, we use this slot for reserve space. // When dragging a window, we use this slot for reserve space.
this._reservedSlot = null; this._reservedSlot = null;
this.metaWorkspace = metaWorkspace; this.metaWorkspace = metaWorkspace;
this._x = 0;
// The full geometry is the geometry we should try and position this._y = 0;
// windows for. The actual geometry we allocate may be less than this._width = 0;
// this, like if the workspace switcher is slid out. this._height = 0;
this._fullGeometry = null;
// The actual geometry is the geometry we need to arrange windows
// in. If this is a smaller area than the full geometry, we'll
// do some simple aspect ratio like math to fit the layout calculated
// for the full geometry into this area.
this._actualGeometry = null;
this._currentLayout = null;
this.monitorIndex = monitorIndex; this.monitorIndex = monitorIndex;
this._monitor = Main.layoutManager.monitors[this.monitorIndex]; this._monitor = Main.layoutManager.monitors[this.monitorIndex];
@ -942,7 +910,7 @@ const Workspace = new Lang.Class({
this.actor.add_style_class_name('external-monitor'); this.actor.add_style_class_name('external-monitor');
this.actor.set_size(0, 0); this.actor.set_size(0, 0);
this._dropRect = new Clutter.Actor({ opacity: 0 }); this._dropRect = new Clutter.Rectangle({ opacity: 0 });
this._dropRect._delegate = this; this._dropRect._delegate = this;
this.actor.add_actor(this._dropRect); this.actor.add_actor(this._dropRect);
@ -979,29 +947,23 @@ const Workspace = new Lang.Class({
this._positionWindowsFlags = 0; this._positionWindowsFlags = 0;
this._positionWindowsId = 0; this._positionWindowsId = 0;
this._currentLayout = null;
}, },
setFullGeometry: function(geom) { setGeometry: function(x, y, width, height) {
this._fullGeometry = geom; this._x = x;
this._recalculateWindowPositions(WindowPositionFlags.NONE); this._y = y;
}, this._width = width;
this._height = height;
setActualGeometry: function(geom) { Meta.later_add(Meta.LaterType.BEFORE_REDRAW, Lang.bind(this, function() {
this._actualGeometry = geom; this._dropRect.set_position(x, y);
this._dropRect.set_size(width, height);
if (this._actualGeometryLater)
return;
this._actualGeometryLater = Meta.later_add(Meta.LaterType.BEFORE_REDRAW, Lang.bind(this, function() {
let geom = this._actualGeometry;
this._dropRect.set_position(geom.x, geom.y);
this._dropRect.set_size(geom.width, geom.height);
this._updateWindowPositions(WindowPositionFlags.NONE);
this._actualGeometryLater = 0;
return false; return false;
})); }));
this.positionWindows(WindowPositionFlags.NONE);
}, },
_lookupIndex: function (metaWindow) { _lookupIndex: function (metaWindow) {
@ -1029,32 +991,37 @@ const Workspace = new Lang.Class({
clone = null; clone = null;
this._reservedSlot = clone; this._reservedSlot = clone;
this._recalculateWindowPositions(WindowPositionFlags.ANIMATE); this._currentLayout = null;
this.positionWindows(WindowPositionFlags.ANIMATE);
}, },
_recalculateWindowPositions: function(flags) { /**
* positionWindows:
* @flags:
* INITIAL - this is the initial positioning of the windows.
* ANIMATE - Indicates that we need animate changing position.
*/
positionWindows: function(flags) {
this._positionWindowsFlags |= flags; this._positionWindowsFlags |= flags;
if (this._positionWindowsId > 0) if (this._positionWindowsId > 0)
return; return;
this._positionWindowsId = Meta.later_add(Meta.LaterType.BEFORE_REDRAW, Lang.bind(this, function() { this._positionWindowsId = Meta.later_add(Meta.LaterType.BEFORE_REDRAW, Lang.bind(this, function() {
this._realRecalculateWindowPositions(this._positionWindowsFlags); this._realPositionWindows(this._positionWindowsFlags);
this._positionWindowsFlags = 0; this._positionWindowsFlags = 0;
this._positionWindowsId = 0; this._positionWindowsId = 0;
return false; return false;
})); }));
}, },
_realRecalculateWindowPositions: function(flags) { _realPositionWindows : function(flags) {
if (this._repositionWindowsId > 0) { if (this._repositionWindowsId > 0) {
Mainloop.source_remove(this._repositionWindowsId); Mainloop.source_remove(this._repositionWindowsId);
this._repositionWindowsId = 0; this._repositionWindowsId = 0;
} }
let clones = this._windows.slice(); let clones = this._windows.slice();
if (clones.length == 0)
return;
clones.sort(function(a, b) { clones.sort(function(a, b) {
return a.metaWindow.get_stable_sequence() - b.metaWindow.get_stable_sequence(); return a.metaWindow.get_stable_sequence() - b.metaWindow.get_stable_sequence();
@ -1063,25 +1030,11 @@ const Workspace = new Lang.Class({
if (this._reservedSlot) if (this._reservedSlot)
clones.push(this._reservedSlot); clones.push(this._reservedSlot);
this._currentLayout = this._computeLayout(clones);
this._updateWindowPositions(flags);
},
_updateWindowPositions: function(flags) {
if (this._currentLayout == null) {
this._recalculateWindowPositions(flags);
return;
}
let initialPositioning = flags & WindowPositionFlags.INITIAL; let initialPositioning = flags & WindowPositionFlags.INITIAL;
let animate = flags & WindowPositionFlags.ANIMATE; let animate = flags & WindowPositionFlags.ANIMATE;
let layout = this._currentLayout; // Start the animations
let strategy = layout.strategy; let slots = this._computeAllWindowSlots(clones);
let [, , padding] = this._getSpacingAndPadding();
let area = padArea(this._actualGeometry, padding);
let slots = strategy.computeWindowSlots(layout, area);
let currentWorkspace = global.screen.get_active_workspace(); let currentWorkspace = global.screen.get_active_workspace();
let isOnCurrentWorkspace = this.metaWorkspace == null || this.metaWorkspace == currentWorkspace; let isOnCurrentWorkspace = this.metaWorkspace == null || this.metaWorkspace == currentWorkspace;
@ -1195,8 +1148,8 @@ const Workspace = new Lang.Class({
let [x, y, mask] = global.get_pointer(); let [x, y, mask] = global.get_pointer();
let pointerHasMoved = (this._cursorX != x && this._cursorY != y); let pointerHasMoved = (this._cursorX != x && this._cursorY != y);
let inWorkspace = (this._fullGeometry.x < x && x < this._fullGeometry.x + this._fullGeometry.width && let inWorkspace = (this._x < x && x < this._x + this._width &&
this._fullGeometry.y < y && y < this._fullGeometry.y + this._fullGeometry.height); this._y < y && y < this._y + this._height);
if (pointerHasMoved && inWorkspace) { if (pointerHasMoved && inWorkspace) {
// store current cursor position // store current cursor position
@ -1211,7 +1164,7 @@ const Workspace = new Lang.Class({
return true; return true;
} }
this._recalculateWindowPositions(WindowPositionFlags.ANIMATE); this.positionWindows(WindowPositionFlags.ANIMATE);
return false; return false;
}, },
@ -1316,7 +1269,7 @@ const Workspace = new Lang.Class({
} }
this._currentLayout = null; this._currentLayout = null;
this._recalculateWindowPositions(WindowPositionFlags.ANIMATE); this.positionWindows(WindowPositionFlags.ANIMATE);
}, },
_windowAdded : function(metaWorkspace, metaWin) { _windowAdded : function(metaWorkspace, metaWin) {
@ -1353,8 +1306,13 @@ const Workspace = new Lang.Class({
// Animate the full-screen to Overview transition. // Animate the full-screen to Overview transition.
zoomToOverview : function() { zoomToOverview : function() {
this._currentLayout = null;
// Position and scale the windows. // Position and scale the windows.
this._recalculateWindowPositions(WindowPositionFlags.ANIMATE | WindowPositionFlags.INITIAL); if (Main.overview.animationInProgress)
this.positionWindows(WindowPositionFlags.ANIMATE | WindowPositionFlags.INITIAL);
else
this.positionWindows(WindowPositionFlags.INITIAL);
}, },
// Animates the return from Overview mode // Animates the return from Overview mode
@ -1478,7 +1436,7 @@ const Workspace = new Lang.Class({
})); }));
clone.connect('size-changed', clone.connect('size-changed',
Lang.bind(this, function() { Lang.bind(this, function() {
this._recalculateWindowPositions(WindowPositionFlags.NONE); this.positionWindows(0);
})); }));
this.actor.add_actor(clone.actor); this.actor.add_actor(clone.actor);
@ -1527,14 +1485,12 @@ const Workspace = new Lang.Class({
} }
}, },
_getBestLayout: function(windows, area, rowSpacing, columnSpacing) { _computeLayout: function(windows, area, rowSpacing, columnSpacing) {
// We look for the largest scale that allows us to fit the // We look for the largest scale that allows us to fit the
// largest row/tallest column on the workspace. // largest row/tallest column on the workspace.
let lastLayout = {}; let lastLayout = {};
let strategy = new UnalignedLayoutStrategy(this._monitor, rowSpacing, columnSpacing);
for (let numRows = 1; ; numRows++) { for (let numRows = 1; ; numRows++) {
let numColumns = Math.ceil(windows.length / numRows); let numColumns = Math.ceil(windows.length / numRows);
@ -1544,6 +1500,8 @@ const Workspace = new Lang.Class({
if (numColumns == lastLayout.numColumns) if (numColumns == lastLayout.numColumns)
break; break;
let strategy = new UnalignedLayoutStrategy(this._monitor, rowSpacing, columnSpacing);
let layout = { area: area, strategy: strategy, numRows: numRows, numColumns: numColumns }; let layout = { area: area, strategy: strategy, numRows: numRows, numColumns: numColumns };
strategy.computeLayout(windows, layout); strategy.computeLayout(windows, layout);
strategy.computeScaleAndSpace(layout); strategy.computeScaleAndSpace(layout);
@ -1557,7 +1515,18 @@ const Workspace = new Lang.Class({
return lastLayout; return lastLayout;
}, },
_getSpacingAndPadding: function() { _rectEqual: function(one, two) {
if (one == two)
return true;
return (one.x == two.x &&
one.y == two.y &&
one.width == two.width &&
one.height == two.height);
},
_computeAllWindowSlots: function(windows) {
let totalWindows = windows.length;
let node = this.actor.get_theme_node(); let node = this.actor.get_theme_node();
// Window grid spacing // Window grid spacing
@ -1570,14 +1539,21 @@ const Workspace = new Lang.Class({
right: node.get_padding(St.Side.RIGHT), right: node.get_padding(St.Side.RIGHT),
}; };
if (!totalWindows)
return [];
let closeButtonHeight, captionHeight; let closeButtonHeight, captionHeight;
let leftBorder, rightBorder; let leftBorder, rightBorder;
if (this._windowOverlays.length) {
// All of the overlays have the same chrome sizes, // All of the overlays have the same chrome sizes,
// so just pick the first one. // so just pick the first one.
let overlay = this._windowOverlays[0]; let overlay = this._windowOverlays[0];
[closeButtonHeight, captionHeight] = overlay.chromeHeights(); [closeButtonHeight, captionHeight] = overlay.chromeHeights();
[leftBorder, rightBorder] = overlay.chromeWidths(); [leftBorder, rightBorder] = overlay.chromeWidths();
} else {
[closeButtonHeight, captionHeight] = [0, 0];
[leftBorder, rightBorder] = [0, 0];
}
rowSpacing += captionHeight; rowSpacing += captionHeight;
columnSpacing += (rightBorder + leftBorder) / 2; columnSpacing += (rightBorder + leftBorder) / 2;
@ -1586,13 +1562,25 @@ const Workspace = new Lang.Class({
padding.left += leftBorder; padding.left += leftBorder;
padding.right += rightBorder; padding.right += rightBorder;
return [rowSpacing, columnSpacing, padding]; let area = {
}, x: this._x + padding.left,
y: this._y + padding.top,
width: this._width - padding.left - padding.right,
height: this._height - padding.top - padding.bottom,
};
_computeLayout: function(windows) { if (!this._currentLayout)
let [rowSpacing, columnSpacing, padding] = this._getSpacingAndPadding(); this._currentLayout = this._computeLayout(windows, area, rowSpacing, columnSpacing);
let area = padArea(this._fullGeometry, padding);
return this._getBestLayout(windows, area, rowSpacing, columnSpacing); let layout = this._currentLayout;
let strategy = layout.strategy;
if (!this._rectEqual(area, layout.area)) {
layout.area = area;
strategy.computeScaleAndSpace(layout);
}
return strategy.computeWindowSlots(layout, area);
}, },
_onCloneSelected : function (clone, time) { _onCloneSelected : function (clone, time) {

View File

@ -23,18 +23,6 @@ const MAX_WORKSPACES = 16;
const OVERRIDE_SCHEMA = 'org.gnome.shell.overrides'; const OVERRIDE_SCHEMA = 'org.gnome.shell.overrides';
function rectEqual(one, two) {
if (one == two)
return true;
if (!one || !two)
return false;
return (one.x == two.x &&
one.y == two.y &&
one.width == two.width &&
one.height == two.height);
}
const WorkspacesView = new Lang.Class({ const WorkspacesView = new Lang.Class({
Name: 'WorkspacesView', Name: 'WorkspacesView',
@ -55,9 +43,10 @@ const WorkspacesView = new Lang.Class({
this._updateWorkspaceActors(false); this._updateWorkspaceActors(false);
})); }));
this._fullGeometry = null; this._width = 0;
this._actualGeometry = null; this._height = 0;
this._x = 0;
this._y = 0;
this._spacing = 0; this._spacing = 0;
this._animating = false; // tweening this._animating = false; // tweening
this._scrolling = false; // swipe-scrolling this._scrolling = false; // swipe-scrolling
@ -96,8 +85,8 @@ const WorkspacesView = new Lang.Class({
this._overviewShownId = this._overviewShownId =
Main.overview.connect('shown', Main.overview.connect('shown',
Lang.bind(this, function() { Lang.bind(this, function() {
this.actor.set_clip(this._fullGeometry.x, this._fullGeometry.y, this.actor.set_clip(this._x, this._y,
this._fullGeometry.width, this._fullGeometry.height); this._width, this._height);
})); }));
this.scrollAdjustment = new St.Adjustment({ value: activeWorkspaceIndex, this.scrollAdjustment = new St.Adjustment({ value: activeWorkspaceIndex,
@ -135,9 +124,11 @@ const WorkspacesView = new Lang.Class({
continue; continue;
let ws = new Workspace.Workspace(null, i); let ws = new Workspace.Workspace(null, i);
ws.setFullGeometry(monitors[i]); ws.setGeometry(monitors[i].x,
ws.setActualGeometry(monitors[i]); monitors[i].y,
Main.layoutManager.overviewGroup.add_actor(ws.actor); monitors[i].width,
monitors[i].height);
global.overlay_group.add_actor(ws.actor);
this._extraWorkspaces.push(ws); this._extraWorkspaces.push(ws);
} }
}, },
@ -148,24 +139,18 @@ const WorkspacesView = new Lang.Class({
this._extraWorkspaces = []; this._extraWorkspaces = [];
}, },
setFullGeometry: function(geom) { setGeometry: function(x, y, width, height) {
if (rectEqual(this._fullGeometry, geom)) if (this._x == x && this._y == y &&
return; this._width == width && this._height == height)
return;
this._fullGeometry = geom; this._width = width;
this._height = height;
this._x = x;
this._y = y;
for (let i = 0; i < this._workspaces.length; i++) for (let i = 0; i < this._workspaces.length; i++)
this._workspaces[i].setFullGeometry(geom); this._workspaces[i].setGeometry(x, y, width, height);
},
setActualGeometry: function(geom) {
if (rectEqual(this._actualGeometry, geom))
return;
this._actualGeometry = geom;
for (let i = 0; i < this._workspaces.length; i++)
this._workspaces[i].setActualGeometry(geom);
}, },
_lookupWorkspaceForMetaWindow: function (metaWindow) { _lookupWorkspaceForMetaWindow: function (metaWindow) {
@ -225,7 +210,7 @@ const WorkspacesView = new Lang.Class({
Tweener.removeTweens(workspace.actor); Tweener.removeTweens(workspace.actor);
let y = (w - active) * (this._fullGeometry.height + this._spacing); let y = (w - active) * (this._height + this._spacing);
if (showAnimation) { if (showAnimation) {
let params = { y: y, let params = { y: y,
@ -296,9 +281,8 @@ const WorkspacesView = new Lang.Class({
if (newNumWorkspaces > oldNumWorkspaces) { if (newNumWorkspaces > oldNumWorkspaces) {
for (let w = oldNumWorkspaces; w < newNumWorkspaces; w++) { for (let w = oldNumWorkspaces; w < newNumWorkspaces; w++) {
this._workspaces[w].setFullGeometry(this._fullGeometry); this._workspaces[w].setGeometry(this._x, this._y,
if (this._actualGeometry) this._width, this._height);
this._workspaces[w].setActualGeometry(this._actualGeometry);
this.actor.add_actor(this._workspaces[w].actor); this.actor.add_actor(this._workspaces[w].actor);
} }
@ -446,7 +430,7 @@ const WorkspacesDisplay = new Lang.Class({
_init: function() { _init: function() {
this.actor = new St.Widget({ clip_to_allocation: true }); this.actor = new St.Widget({ clip_to_allocation: true });
this.actor.connect('notify::allocation', Lang.bind(this, this._updateWorkspacesActualGeometry)); this.actor.connect('notify::allocation', Lang.bind(this, this._updateWorkspacesGeometry));
this.actor.connect('parent-set', Lang.bind(this, this._parentSet)); this.actor.connect('parent-set', Lang.bind(this, this._parentSet));
let clickAction = new Clutter.ClickAction() let clickAction = new Clutter.ClickAction()
@ -500,8 +484,6 @@ const WorkspacesDisplay = new Lang.Class({
this._notifyOpacityId = 0; this._notifyOpacityId = 0;
this._scrollEventId = 0; this._scrollEventId = 0;
this._fullGeometry = null;
}, },
_onPan: function(action) { _onPan: function(action) {
@ -590,11 +572,10 @@ const WorkspacesDisplay = new Lang.Class({
this._workspacesViews.push(view); this._workspacesViews.push(view);
} }
this._updateWorkspacesFullGeometry(); this._updateWorkspacesGeometry();
this._updateWorkspacesActualGeometry();
for (let i = 0; i < this._workspacesViews.length; i++) for (let i = 0; i < this._workspacesViews.length; i++)
Main.layoutManager.overviewGroup.add_actor(this._workspacesViews[i].actor); global.overlay_group.add_actor(this._workspacesViews[i].actor);
}, },
_scrollValueChanged: function() { _scrollValueChanged: function() {
@ -638,7 +619,7 @@ const WorkspacesDisplay = new Lang.Class({
// This is kinda hackish - we want the primary view to // This is kinda hackish - we want the primary view to
// appear as parent of this.actor, though in reality it // appear as parent of this.actor, though in reality it
// is added directly to Main.layoutManager.overviewGroup // is added directly to overlay_group
this._notifyOpacityId = newParent.connect('notify::opacity', this._notifyOpacityId = newParent.connect('notify::opacity',
Lang.bind(this, function() { Lang.bind(this, function() {
let opacity = this.actor.get_parent().opacity; let opacity = this.actor.get_parent().opacity;
@ -651,48 +632,31 @@ const WorkspacesDisplay = new Lang.Class({
})); }));
}, },
// This geometry should always be the fullest geometry _updateWorkspacesGeometry: function() {
// the workspaces switcher can ever be allocated, as if
// the sliding controls were never slid in at all.
setWorkspacesFullGeometry: function(geom) {
this._fullGeometry = geom;
this._updateWorkspacesFullGeometry();
},
_updateWorkspacesFullGeometry: function() {
if (!this._workspacesViews.length) if (!this._workspacesViews.length)
return; return;
let monitors = Main.layoutManager.monitors; let fullWidth = this.actor.allocation.x2 - this.actor.allocation.x1;
let m = 0; let fullHeight = this.actor.allocation.y2 - this.actor.allocation.y1;
for (let i = 0; i < monitors.length; i++) {
if (i == this._primaryIndex) {
this._workspacesViews[m].setFullGeometry(this._fullGeometry);
m++;
} else if (!this._workspacesOnlyOnPrimary) {
this._workspacesViews[m].setFullGeometry(monitors[i]);
m++;
}
}
},
_updateWorkspacesActualGeometry: function() { let width = fullWidth;
if (!this._workspacesViews.length) let height = fullHeight;
return;
let [x, y] = this.actor.get_transformed_position(); let [x, y] = this.actor.get_transformed_position();
let width = this.actor.allocation.x2 - this.actor.allocation.x1;
let height = this.actor.allocation.y2 - this.actor.allocation.y1; let rtl = (Clutter.get_default_text_direction () == Clutter.TextDirection.RTL);
let geometry = { x: x, y: y, width: width, height: height };
let monitors = Main.layoutManager.monitors; let monitors = Main.layoutManager.monitors;
let m = 0; let m = 0;
for (let i = 0; i < monitors.length; i++) { for (let i = 0; i < monitors.length; i++) {
if (i == this._primaryIndex) { if (i == this._primaryIndex) {
this._workspacesViews[m].setActualGeometry(geometry); this._workspacesViews[m].setGeometry(x, y, width, height);
m++; m++;
} else if (!this._workspacesOnlyOnPrimary) { } else if (!this._workspacesOnlyOnPrimary) {
this._workspacesViews[m].setActualGeometry(monitors[i]); this._workspacesViews[m].setGeometry(monitors[i].x,
monitors[i].y,
monitors[i].width,
monitors[i].height);
m++; m++;
} }
} }
@ -760,20 +724,15 @@ const WorkspacesDisplay = new Lang.Class({
_onScrollEvent: function(actor, event) { _onScrollEvent: function(actor, event) {
if (!this.actor.mapped) if (!this.actor.mapped)
return false; return false;
let activeWs = global.screen.get_active_workspace();
let ws;
switch (event.get_scroll_direction()) { switch (event.get_scroll_direction()) {
case Clutter.ScrollDirection.UP: case Clutter.ScrollDirection.UP:
ws = activeWs.get_neighbor(Meta.MotionDirection.UP); Main.wm.actionMoveWorkspace(Meta.MotionDirection.UP);
break; return true;
case Clutter.ScrollDirection.DOWN: case Clutter.ScrollDirection.DOWN:
ws = activeWs.get_neighbor(Meta.MotionDirection.DOWN); Main.wm.actionMoveWorkspace(Meta.MotionDirection.DOWN);
break; return true;
default:
return false;
} }
Main.wm.actionMoveWorkspace(ws); return false;
return true;
} }
}); });
Signals.addSignalMethods(WorkspacesDisplay.prototype); Signals.addSignalMethods(WorkspacesDisplay.prototype);

View File

@ -16,7 +16,7 @@ const XdndHandler = new Lang.Class({
this._cursorWindowClone = null; this._cursorWindowClone = null;
// Used as a drag actor in case we don't have a cursor window clone // Used as a drag actor in case we don't have a cursor window clone
this._dummy = new Clutter.Actor({ width: 1, height: 1, opacity: 0 }); this._dummy = new Clutter.Rectangle({ width: 1, height: 1, opacity: 0 });
Main.uiGroup.add_actor(this._dummy); Main.uiGroup.add_actor(this._dummy);
Shell.util_set_hidden_from_pick(this._dummy, true); Shell.util_set_hidden_from_pick(this._dummy, true);
this._dummy.hide(); this._dummy.hide();

View File

@ -125,12 +125,6 @@
<listitem><para>List possible modes and exit</para></listitem> <listitem><para>List possible modes and exit</para></listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term><option>--clutter-display=<replaceable>DISPLAY</replaceable></option></term>
<listitem><para>Clutter the option display (otherwise ignored)</para></listitem>
</varlistentry>
</variablelist> </variablelist>
</refsect1> </refsect1>

View File

@ -28,7 +28,6 @@ gu
he he
hi hi
hu hu
ia
id id
it it
ja ja

View File

@ -55,7 +55,6 @@ js/ui/viewSelector.js
js/ui/wanda.js js/ui/wanda.js
js/ui/windowAttentionHandler.js js/ui/windowAttentionHandler.js
src/calendar-server/evolution-calendar.desktop.in.in src/calendar-server/evolution-calendar.desktop.in.in
# Please do not remove this file from POTFILES.in. Run "git submodule init && git submodule update" to get it.
src/gvc/gvc-mixer-control.c src/gvc/gvc-mixer-control.c
src/main.c src/main.c
src/shell-app.c src/shell-app.c

View File

@ -11,7 +11,7 @@ msgstr ""
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-" "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-"
"shell&keywords=I18N+L10N&component=general\n" "shell&keywords=I18N+L10N&component=general\n"
"POT-Creation-Date: 2013-03-11 21:29+0000\n" "POT-Creation-Date: 2013-03-11 21:29+0000\n"
"PO-Revision-Date: 2013-05-26 08:21+0200\n" "PO-Revision-Date: 2013-03-11 00:03+0100\n"
"Last-Translator: Gil Forcada <gilforcada@guifi.net>\n" "Last-Translator: Gil Forcada <gilforcada@guifi.net>\n"
"Language-Team: Catalan <tradgnome@softcatala.org>\n" "Language-Team: Catalan <tradgnome@softcatala.org>\n"
"Language: ca\n" "Language: ca\n"
@ -1048,7 +1048,7 @@ msgstr "Obre els rellotges"
#: ../js/ui/dateMenu.js:105 #: ../js/ui/dateMenu.js:105
msgid "Date & Time Settings" msgid "Date & Time Settings"
msgstr "Configuració de la data i de l'hora" msgstr "Configuració de la data i l'hora"
#. Translators: This is the date format to use when the calendar popup is #. Translators: This is the date format to use when the calendar popup is
#. * shown - it is shown just below the time in the shell (e.g. "Tue 9:29 AM"). #. * shown - it is shown just below the time in the shell (e.g. "Tue 9:29 AM").

397
po/cs.po

File diff suppressed because it is too large Load Diff

239
po/el.po
View File

@ -5,8 +5,8 @@ msgstr ""
"Project-Id-Version: gnome-shell.po.master\n" "Project-Id-Version: gnome-shell.po.master\n"
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-" "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-"
"shell&keywords=I18N+L10N&component=general\n" "shell&keywords=I18N+L10N&component=general\n"
"POT-Creation-Date: 2013-04-19 02:48+0000\n" "POT-Creation-Date: 2013-03-02 23:02+0000\n"
"PO-Revision-Date: 2013-04-25 08:11+0300\n" "PO-Revision-Date: 2013-03-03 13:22+0300\n"
"Last-Translator: Dimitris Spingos (Δημήτρης Σπίγγος) <dmtrs32@gmail.com>\n" "Last-Translator: Dimitris Spingos (Δημήτρης Σπίγγος) <dmtrs32@gmail.com>\n"
"Language-Team: team@gnome.gr\n" "Language-Team: team@gnome.gr\n"
"Language: el\n" "Language: el\n"
@ -40,14 +40,10 @@ msgid "Focus the active notification"
msgstr "Εστίαση στην ενεργή ειδοποίηση" msgstr "Εστίαση στην ενεργή ειδοποίηση"
#: ../data/50-gnome-shell-system.xml.in.h:4 #: ../data/50-gnome-shell-system.xml.in.h:4
msgid "Show the overview"
msgstr "Εμφάνιση της επισκόπησης"
#: ../data/50-gnome-shell-system.xml.in.h:5
msgid "Show all applications" msgid "Show all applications"
msgstr "Προβολή όλων των εφαρμογών" msgstr "Προβολή όλων των εφαρμογών"
#: ../data/50-gnome-shell-system.xml.in.h:6 #: ../data/50-gnome-shell-system.xml.in.h:5
msgid "Open the application menu" msgid "Open the application menu"
msgstr "Άνοιγμα του μενού εφαρμογών" msgstr "Άνοιγμα του μενού εφαρμογών"
@ -227,55 +223,45 @@ msgstr ""
"επισκόπησης ενεργειών." "επισκόπησης ενεργειών."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:25 #: ../data/org.gnome.shell.gschema.xml.in.in.h:25
#| msgid "Keybinding to open the \"Show Applications\" view"
msgid "Keybinding to open the overview"
msgstr "Συνδυασμός πλήκτρων για το άνοιγμα της επισκόπησης"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:26
#| msgid "Keybinding to open the \"Show Applications\" view"
msgid "Keybinding to open the Activities Overview."
msgstr "Συνδυασμός πλήκτρων για το άνοιγμα της προβολής ενέργειες."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:27
msgid "Keybinding to toggle the visibility of the message tray" msgid "Keybinding to toggle the visibility of the message tray"
msgstr "Συνδυασμός πλήκτρων για την ορατότητα της περιοχής ειδοποιήσεων" msgstr "Συνδυασμός πλήκτρων για την ορατότητα της περιοχής ειδοποιήσεων"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:28 #: ../data/org.gnome.shell.gschema.xml.in.in.h:26
msgid "Keybinding to toggle the visibility of the message tray." msgid "Keybinding to toggle the visibility of the message tray."
msgstr "Συνδυασμός πλήκτρων για την ορατότητα της περιοχής ειδοποιήσεων." msgstr "Συνδυασμός πλήκτρων για την ορατότητα της περιοχής ειδοποιήσεων."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:29 #: ../data/org.gnome.shell.gschema.xml.in.in.h:27
msgid "Keybinding to focus the active notification" msgid "Keybinding to focus the active notification"
msgstr "Ο συνδυασμός πλήκτρων για εστίαση της ενεργής ειδοποίησης" msgstr "Ο συνδυασμός πλήκτρων για εστίαση της ενεργής ειδοποίησης"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:30 #: ../data/org.gnome.shell.gschema.xml.in.in.h:28
msgid "Keybinding to focus the active notification." msgid "Keybinding to focus the active notification."
msgstr "Ο συνδυασμός πλήκτρων για εστίαση της ενεργής ειδοποίησης." msgstr "Ο συνδυασμός πλήκτρων για εστίαση της ενεργής ειδοποίησης."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:31 #: ../data/org.gnome.shell.gschema.xml.in.in.h:29
msgid "Keybinding to toggle the screen recorder" msgid "Keybinding to toggle the screen recorder"
msgstr "Συνδυασμός πλήκτρων για την εναλλαγή της μαγνητοσκόπησης οθόνης" msgstr "Συνδυασμός πλήκτρων για την εναλλαγή της μαγνητοσκόπησης οθόνης"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:32 #: ../data/org.gnome.shell.gschema.xml.in.in.h:30
msgid "Keybinding to start/stop the builtin screen recorder." msgid "Keybinding to start/stop the builtin screen recorder."
msgstr "" msgstr ""
"Συνδυασμός πλήκτρων για το άνοιγμα/κλείσιμο της ενσωματωμένης " "Συνδυασμός πλήκτρων για το άνοιγμα/κλείσιμο της ενσωματωμένης "
"μαγνητοσκόπησης οθόνης." "μαγνητοσκόπησης οθόνης."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:33 #: ../data/org.gnome.shell.gschema.xml.in.in.h:31
msgid "Which keyboard to use" msgid "Which keyboard to use"
msgstr "Ποιο πληκτρολόγιο θα χρησιμοποιηθεί" msgstr "Ποιο πληκτρολόγιο θα χρησιμοποιηθεί"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:34 #: ../data/org.gnome.shell.gschema.xml.in.in.h:32
msgid "The type of keyboard to use." msgid "The type of keyboard to use."
msgstr "Ο τύπος του πληκτρολογίου που θα χρησιμοποιηθεί." msgstr "Ο τύπος του πληκτρολογίου που θα χρησιμοποιηθεί."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:35 #: ../data/org.gnome.shell.gschema.xml.in.in.h:33
msgid "Framerate used for recording screencasts." msgid "Framerate used for recording screencasts."
msgstr "" msgstr ""
"Ο ρυθμός καρέ που θα χρησιμοποιηθεί για την καταγραφή του βίντεο οθόνης." "Ο ρυθμός καρέ που θα χρησιμοποιηθεί για την καταγραφή του βίντεο οθόνης."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:36 #: ../data/org.gnome.shell.gschema.xml.in.in.h:34
msgid "" msgid ""
"The framerate of the resulting screencast recordered by GNOME Shell's " "The framerate of the resulting screencast recordered by GNOME Shell's "
"screencast recorder in frames-per-second." "screencast recorder in frames-per-second."
@ -283,13 +269,13 @@ msgstr ""
"Ο ρυθμός καρέ του στιγμιότυπου που παράγεται από τον εγγραφέα βίντεο οθόνης " "Ο ρυθμός καρέ του στιγμιότυπου που παράγεται από τον εγγραφέα βίντεο οθόνης "
"του GNOME Shell σε καρέ ανά δευτερόλεπτο." "του GNOME Shell σε καρέ ανά δευτερόλεπτο."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:37 #: ../data/org.gnome.shell.gschema.xml.in.in.h:35
msgid "The gstreamer pipeline used to encode the screencast" msgid "The gstreamer pipeline used to encode the screencast"
msgstr "" msgstr ""
"Ο δίαυλος του gstreamer που χρησιμοποιήθηκε για την κωδικοποίηση του βίντεο " "Ο δίαυλος του gstreamer που χρησιμοποιήθηκε για την κωδικοποίηση του βίντεο "
"οθόνης" "οθόνης"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:39 #: ../data/org.gnome.shell.gschema.xml.in.in.h:37
#, no-c-format #, no-c-format
msgid "" msgid ""
"Sets the GStreamer pipeline used to encode recordings. It follows the syntax " "Sets the GStreamer pipeline used to encode recordings. It follows the syntax "
@ -317,12 +303,12 @@ msgstr ""
"χρησιμοποιείται ως παράδειγμα για το πιθανό βέλτιστο αριθμό πυρήνων του " "χρησιμοποιείται ως παράδειγμα για το πιθανό βέλτιστο αριθμό πυρήνων του "
"συστήματος." "συστήματος."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:40 #: ../data/org.gnome.shell.gschema.xml.in.in.h:38
msgid "File extension used for storing the screencast" msgid "File extension used for storing the screencast"
msgstr "" msgstr ""
"Επέκταση αρχείου που θα χρησιμοποιηθεί για την αποθήκευση του βίντεο οθόνης" "Επέκταση αρχείου που θα χρησιμοποιηθεί για την αποθήκευση του βίντεο οθόνης"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:41 #: ../data/org.gnome.shell.gschema.xml.in.in.h:39
msgid "" msgid ""
"The filename for recorded screencasts will be a unique filename based on the " "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 " "current date, and use this extension. It should be changed when recording to "
@ -332,11 +318,11 @@ msgstr ""
"βασισμένο στην τρέχουσα ημερομηνία και θα χρησιμοποιεί αυτή την επέκταση. Θα " "βασισμένο στην τρέχουσα ημερομηνία και θα χρησιμοποιεί αυτή την επέκταση. Θα "
"πρέπει να αλλάζει όταν γίνεται εγγραφή σε διαφορετικό πρότυπο περιέκτη." "πρέπει να αλλάζει όταν γίνεται εγγραφή σε διαφορετικό πρότυπο περιέκτη."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:42 #: ../data/org.gnome.shell.gschema.xml.in.in.h:40
msgid "The application icon mode." msgid "The application icon mode."
msgstr "Η κατάσταση εικονιδίου εφαρμογής." msgstr "Η κατάσταση εικονιδίου εφαρμογής."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:43 #: ../data/org.gnome.shell.gschema.xml.in.in.h:41
msgid "" msgid ""
"Configures how the windows are shown in the switcher. Valid possibilities " "Configures how the windows are shown in the switcher. Valid possibilities "
"are 'thumbnail-only' (shows a thumbnail of the window), 'app-icon-" "are 'thumbnail-only' (shows a thumbnail of the window), 'app-icon-"
@ -347,22 +333,22 @@ msgstr ""
"παραθύρου), 'app-icon-only' (εμφανίζει μόνο το εικονίδιο της εφαρμογής) ή " "παραθύρου), 'app-icon-only' (εμφανίζει μόνο το εικονίδιο της εφαρμογής) ή "
"'both' - και τα δύο." "'both' - και τα δύο."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:44 #: ../data/org.gnome.shell.gschema.xml.in.in.h:42
msgid "Attach modal dialog to the parent window" msgid "Attach modal dialog to the parent window"
msgstr "Προσάρτηση αναγκαστικού διαλόγου στο γονικό παράθυρο" msgstr "Προσάρτηση αναγκαστικού διαλόγου στο γονικό παράθυρο"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:45 #: ../data/org.gnome.shell.gschema.xml.in.in.h:43
msgid "" msgid ""
"This key overrides the key in org.gnome.mutter when running GNOME Shell." "This key overrides the key in org.gnome.mutter when running GNOME Shell."
msgstr "" msgstr ""
"Αυτό το κλειδί υπερισχύει του κλειδιού στο org.gnome.mutter όταν εκτελείται " "Αυτό το κλειδί υπερισχύει του κλειδιού στο org.gnome.mutter όταν εκτελείται "
"το κέλυφος GNOME." "το κέλυφος GNOME."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:46 #: ../data/org.gnome.shell.gschema.xml.in.in.h:44
msgid "Arrangement of buttons on the titlebar" msgid "Arrangement of buttons on the titlebar"
msgstr "Διάταξη των κουμπιών στη γραμμή τίτλου" msgstr "Διάταξη των κουμπιών στη γραμμή τίτλου"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:47 #: ../data/org.gnome.shell.gschema.xml.in.in.h:45
msgid "" msgid ""
"This key overrides the key in org.gnome.desktop.wm.preferences when running " "This key overrides the key in org.gnome.desktop.wm.preferences when running "
"GNOME Shell." "GNOME Shell."
@ -370,17 +356,17 @@ msgstr ""
"Αυτό το κλειδί υπερισχύει του κλειδιού στο org.gnome.desktop.wm.preferences " "Αυτό το κλειδί υπερισχύει του κλειδιού στο org.gnome.desktop.wm.preferences "
"όταν εκτελείται το κέλυφος GNOME." "όταν εκτελείται το κέλυφος GNOME."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:48 #: ../data/org.gnome.shell.gschema.xml.in.in.h:46
msgid "Enable edge tiling when dropping windows on screen edges" msgid "Enable edge tiling when dropping windows on screen edges"
msgstr "" msgstr ""
"Ενεργοποίηση της παράθεσης άκρων όταν αποθέτετε παράθυρα στις άκρες της " "Ενεργοποίηση της παράθεσης άκρων όταν αποθέτετε παράθυρα στις άκρες της "
"οθόνης" "οθόνης"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:49 #: ../data/org.gnome.shell.gschema.xml.in.in.h:47
msgid "Workspaces are managed dynamically" msgid "Workspaces are managed dynamically"
msgstr "Οι χώροι εργασίας διαχειρίζονται δυναμικά" msgstr "Οι χώροι εργασίας διαχειρίζονται δυναμικά"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:50 #: ../data/org.gnome.shell.gschema.xml.in.in.h:48
msgid "Workspaces only on primary monitor" msgid "Workspaces only on primary monitor"
msgstr "Χώροι εργασίας μόνο στην κύρια οθόνη" msgstr "Χώροι εργασίας μόνο στην κύρια οθόνη"
@ -402,42 +388,43 @@ msgstr ""
"πολλαπλών επιλογών." "πολλαπλών επιλογών."
#: ../js/gdm/loginDialog.js:405 #: ../js/gdm/loginDialog.js:405
#| msgid "Session..."
msgid "Session…" msgid "Session…"
msgstr "Συνεδρία…" msgstr "Συνεδρία…"
#. translators: this message is shown below the user list on the #. translators: this message is shown below the user list on the
#. login screen. It can be activated to reveal an entry for #. login screen. It can be activated to reveal an entry for
#. manually entering the username. #. manually entering the username.
#: ../js/gdm/loginDialog.js:630 #: ../js/gdm/loginDialog.js:629
msgid "Not listed?" msgid "Not listed?"
msgstr "Δεν είστε στη λίστα;" msgstr "Δεν είστε στη λίστα;"
#: ../js/gdm/loginDialog.js:787 ../js/ui/components/networkAgent.js:137 #: ../js/gdm/loginDialog.js:783 ../js/ui/components/networkAgent.js:137
#: ../js/ui/components/polkitAgent.js:162 ../js/ui/endSessionDialog.js:376 #: ../js/ui/components/polkitAgent.js:162 ../js/ui/endSessionDialog.js:375
#: ../js/ui/extensionDownloader.js:195 ../js/ui/shellMountOperation.js:399 #: ../js/ui/extensionDownloader.js:195 ../js/ui/shellMountOperation.js:399
#: ../js/ui/status/bluetooth.js:415 ../js/ui/unlockDialog.js:100 #: ../js/ui/status/bluetooth.js:415 ../js/ui/unlockDialog.js:126
#: ../js/ui/userMenu.js:938 #: ../js/ui/userMenu.js:932
msgid "Cancel" msgid "Cancel"
msgstr "Ακύρωση" msgstr "Ακύρωση"
#: ../js/gdm/loginDialog.js:803 #: ../js/gdm/loginDialog.js:799
msgctxt "button" msgctxt "button"
msgid "Sign In" msgid "Sign In"
msgstr "Σύνδεση" msgstr "Σύνδεση"
#: ../js/gdm/loginDialog.js:803 #: ../js/gdm/loginDialog.js:799
msgid "Next" msgid "Next"
msgstr "Επόμενο" msgstr "Επόμενο"
#. TTLS and PEAP are actually much more complicated, but this complication #. TTLS and PEAP are actually much more complicated, but this complication
#. is not visible here since we only care about phase2 authentication #. is not visible here since we only care about phase2 authentication
#. (and don't even care of which one) #. (and don't even care of which one)
#: ../js/gdm/loginDialog.js:918 ../js/ui/components/networkAgent.js:260 #: ../js/gdm/loginDialog.js:904 ../js/ui/components/networkAgent.js:260
#: ../js/ui/components/networkAgent.js:278 #: ../js/ui/components/networkAgent.js:278
msgid "Username: " msgid "Username: "
msgstr "Όνομα χρήστη: " msgstr "Όνομα χρήστη: "
#: ../js/gdm/loginDialog.js:1174 #: ../js/gdm/loginDialog.js:1157
msgid "Login Window" msgid "Login Window"
msgstr "Παράθυρο σύνδεσης" msgstr "Παράθυρο σύνδεσης"
@ -446,8 +433,8 @@ msgstr "Παράθυρο σύνδεσης"
msgid "Power" msgid "Power"
msgstr "Ενέργεια" msgstr "Ενέργεια"
#: ../js/gdm/powerMenu.js:93 ../js/ui/userMenu.js:696 ../js/ui/userMenu.js:700 #: ../js/gdm/powerMenu.js:93 ../js/ui/userMenu.js:694 ../js/ui/userMenu.js:698
#: ../js/ui/userMenu.js:816 #: ../js/ui/userMenu.js:814
msgid "Suspend" msgid "Suspend"
msgstr "Αναστολή" msgstr "Αναστολή"
@ -455,58 +442,58 @@ msgstr "Αναστολή"
msgid "Restart" msgid "Restart"
msgstr "Επανεκκίνηση" msgstr "Επανεκκίνηση"
#: ../js/gdm/powerMenu.js:103 ../js/ui/userMenu.js:698 #: ../js/gdm/powerMenu.js:103 ../js/ui/userMenu.js:696
#: ../js/ui/userMenu.js:700 ../js/ui/userMenu.js:815 ../js/ui/userMenu.js:942 #: ../js/ui/userMenu.js:698 ../js/ui/userMenu.js:813 ../js/ui/userMenu.js:936
msgid "Power Off" msgid "Power Off"
msgstr "Απενεργοποίηση" msgstr "Απενεργοποίηση"
#: ../js/gdm/util.js:249 #: ../js/gdm/util.js:182
msgid "Authentication error" msgid "Authentication error"
msgstr "Σφάλμα πιστοποίησης" msgstr "Σφάλμα πιστοποίησης"
#. Translators: this message is shown below the password entry field #. Translators: this message is shown below the password entry field
#. to indicate the user can swipe their finger instead #. to indicate the user can swipe their finger instead
#: ../js/gdm/util.js:366 #: ../js/gdm/util.js:299
msgid "(or swipe finger)" msgid "(or swipe finger)"
msgstr "(ή περάστε το δάκτυλο σας)" msgstr "(ή περάστε το δάκτυλο σας)"
#: ../js/gdm/util.js:391 #: ../js/gdm/util.js:324
#, c-format #, c-format
msgid "(e.g., user or %s)" msgid "(e.g., user or %s)"
msgstr "(π.χ χρήστης ή %s)" msgstr "(π.χ χρήστης ή %s)"
#: ../js/misc/util.js:97 #: ../js/misc/util.js:94
msgid "Command not found" msgid "Command not found"
msgstr "Δε βρέθηκε η εντολή" msgstr "Δε βρέθηκε η εντολή"
#. Replace "Error invoking GLib.shell_parse_argv: " with #. Replace "Error invoking GLib.shell_parse_argv: " with
#. something nicer #. something nicer
#: ../js/misc/util.js:130 #: ../js/misc/util.js:127
msgid "Could not parse command:" msgid "Could not parse command:"
msgstr "Δεν ήταν δυνατό να επεξεργαστεί η εντολή:" msgstr "Δεν ήταν δυνατό να επεξεργαστεί η εντολή:"
#: ../js/misc/util.js:138 #: ../js/misc/util.js:135
#, c-format #, c-format
msgid "Execution of '%s' failed:" msgid "Execution of '%s' failed:"
msgstr "Η εκτέλεση του '%s' απέτυχε:" msgstr "Η εκτέλεση του '%s' απέτυχε:"
#: ../js/ui/appDisplay.js:349 #: ../js/ui/appDisplay.js:348
msgid "Frequent" msgid "Frequent"
msgstr "Συχνό" msgstr "Συχνό"
#: ../js/ui/appDisplay.js:356 #: ../js/ui/appDisplay.js:355
msgid "All" msgid "All"
msgstr "Όλα" msgstr "Όλα"
#: ../js/ui/appDisplay.js:914 #: ../js/ui/appDisplay.js:913
msgid "New Window" msgid "New Window"
msgstr "Νέο παράθυρο" msgstr "Νέο παράθυρο"
#: ../js/ui/appDisplay.js:917 ../js/ui/dash.js:284 #: ../js/ui/appDisplay.js:916 ../js/ui/dash.js:284
msgid "Remove from Favorites" msgid "Remove from Favorites"
msgstr "Αφαίρεση από τα αγαπημένα" msgstr "Αφαίρεση από τα αγαπημένα"
#: ../js/ui/appDisplay.js:918 #: ../js/ui/appDisplay.js:917
msgid "Add to Favorites" msgid "Add to Favorites"
msgstr "Προσθήκη στα αγαπημένα" msgstr "Προσθήκη στα αγαπημένα"
@ -520,7 +507,7 @@ msgstr "Tο %s προστέθηκε στα αγαπημένα σας."
msgid "%s has been removed from your favorites." msgid "%s has been removed from your favorites."
msgstr "Tο %s αφαιρέθηκε από τα αγαπημένα σας." msgstr "Tο %s αφαιρέθηκε από τα αγαπημένα σας."
#: ../js/ui/backgroundMenu.js:19 ../js/ui/userMenu.js:789 #: ../js/ui/backgroundMenu.js:19 ../js/ui/userMenu.js:787
msgid "Settings" msgid "Settings"
msgstr "Ρυθμίσεις" msgstr "Ρυθμίσεις"
@ -543,7 +530,7 @@ msgctxt "event list time"
msgid "%H\\u2236%M" msgid "%H\\u2236%M"
msgstr "%Ω\\u2236%Λ" msgstr "%Ω\\u2236%Λ"
#. Translators: Shown in calendar event list, if 12h format, #. Transators: Shown in calendar event list, if 12h format,
#. \u2236 is a ratio character, similar to : and \u2009 is #. \u2236 is a ratio character, similar to : and \u2009 is
#. a thin space #. a thin space
#: ../js/ui/calendar.js:77 #: ../js/ui/calendar.js:77
@ -645,35 +632,35 @@ msgid "S"
msgstr "Σ" msgstr "Σ"
#. Translators: Text to show if there are no events #. Translators: Text to show if there are no events
#: ../js/ui/calendar.js:720 #: ../js/ui/calendar.js:692
msgid "Nothing Scheduled" msgid "Nothing Scheduled"
msgstr "Τίποτα προγραμματισμένο" msgstr "Τίποτα προγραμματισμένο"
#. Translators: Shown on calendar heading when selected day occurs on current year #. Translators: Shown on calendar heading when selected day occurs on current year
#: ../js/ui/calendar.js:736 #: ../js/ui/calendar.js:708
msgctxt "calendar heading" msgctxt "calendar heading"
msgid "%A, %B %d" msgid "%A, %B %d"
msgstr "%A, %B %d" msgstr "%A, %B %d"
#. Translators: Shown on calendar heading when selected day occurs on different year #. Translators: Shown on calendar heading when selected day occurs on different year
#: ../js/ui/calendar.js:739 #: ../js/ui/calendar.js:711
msgctxt "calendar heading" msgctxt "calendar heading"
msgid "%A, %B %d, %Y" msgid "%A, %B %d, %Y"
msgstr "%A, %B %d, %Y" msgstr "%A, %B %d, %Y"
#: ../js/ui/calendar.js:749 #: ../js/ui/calendar.js:721
msgid "Today" msgid "Today"
msgstr "Σήμερα" msgstr "Σήμερα"
#: ../js/ui/calendar.js:753 #: ../js/ui/calendar.js:725
msgid "Tomorrow" msgid "Tomorrow"
msgstr "Αύριο" msgstr "Αύριο"
#: ../js/ui/calendar.js:764 #: ../js/ui/calendar.js:736
msgid "This week" msgid "This week"
msgstr "Αυτή η εβδομάδα" msgstr "Αυτή η εβδομάδα"
#: ../js/ui/calendar.js:772 #: ../js/ui/calendar.js:744
msgid "Next week" msgid "Next week"
msgstr "Επόμενη εβδομάδα" msgstr "Επόμενη εβδομάδα"
@ -689,12 +676,12 @@ msgstr "Αποσυνδέθηκε εξωτερικός δίσκος"
msgid "Removable Devices" msgid "Removable Devices"
msgstr "Αφαιρούμενες συσκευές" msgstr "Αφαιρούμενες συσκευές"
#: ../js/ui/components/autorunManager.js:594 #: ../js/ui/components/autorunManager.js:593
#, c-format #, c-format
msgid "Open with %s" msgid "Open with %s"
msgstr "Άνοιγμα με %s" msgstr "Άνοιγμα με %s"
#: ../js/ui/components/autorunManager.js:620 #: ../js/ui/components/autorunManager.js:619
msgid "Eject" msgid "Eject"
msgstr "Εξαγωγή" msgstr "Εξαγωγή"
@ -803,7 +790,7 @@ msgid "Sorry, that didn't work. Please try again."
msgstr "Συγνώμη, αυτό δεν λειτούργησε. Παρακαλώ προσπαθήστε ξανά." msgstr "Συγνώμη, αυτό δεν λειτούργησε. Παρακαλώ προσπαθήστε ξανά."
#. Translators: this is a filename used for screencast recording #. Translators: this is a filename used for screencast recording
#: ../js/ui/components/recorder.js:47 #: ../js/ui/components/recorder.js:48
#, no-c-format #, no-c-format
msgid "Screencast from %d %t" msgid "Screencast from %d %t"
msgstr "Βίντεο οθόνης από %d %t" msgstr "Βίντεο οθόνης από %d %t"
@ -1050,7 +1037,7 @@ msgstr "Προβολή λογαριασμού"
msgid "Unknown reason" msgid "Unknown reason"
msgstr "Άγνωστος λόγος" msgstr "Άγνωστος λόγος"
#: ../js/ui/ctrlAltTab.js:29 ../js/ui/viewSelector.js:96 #: ../js/ui/ctrlAltTab.js:29 ../js/ui/viewSelector.js:97
msgid "Windows" msgid "Windows"
msgstr "Παράθυρα" msgstr "Παράθυρα"
@ -1079,7 +1066,7 @@ msgstr "Ρυθμίσεις ημερομηνίας & ώρας"
#. Translators: This is the date format to use when the calendar popup is #. Translators: This is the date format to use when the calendar popup is
#. * shown - it is shown just below the time in the shell (e.g. "Tue 9:29 AM"). #. * shown - it is shown just below the time in the shell (e.g. "Tue 9:29 AM").
#. #.
#: ../js/ui/dateMenu.js:215 #: ../js/ui/dateMenu.js:205
msgid "%A %B %e, %Y" msgid "%A %B %e, %Y"
msgstr "%A %B %e, %Y" msgstr "%A %B %e, %Y"
@ -1248,6 +1235,7 @@ msgid "Remove"
msgstr "Αφαίρεση" msgstr "Αφαίρεση"
#: ../js/ui/messageTray.js:1501 #: ../js/ui/messageTray.js:1501
#| msgid "No Messages"
msgid "Clear Messages" msgid "Clear Messages"
msgstr "Καθαρισμός μηνυμάτων" msgstr "Καθαρισμός μηνυμάτων"
@ -1255,15 +1243,15 @@ msgstr "Καθαρισμός μηνυμάτων"
msgid "Notification Settings" msgid "Notification Settings"
msgstr "Ρυθμίσεις ειδοποιήσεων" msgstr "Ρυθμίσεις ειδοποιήσεων"
#: ../js/ui/messageTray.js:1709 #: ../js/ui/messageTray.js:1707
msgid "No Messages" msgid "No Messages"
msgstr "Κανένα μήνυμα" msgstr "Κανένα μήνυμα"
#: ../js/ui/messageTray.js:1785 #: ../js/ui/messageTray.js:1787
msgid "Message Tray" msgid "Message Tray"
msgstr "Περιοχή ειδοποιήσεων" msgstr "Περιοχή ειδοποιήσεων"
#: ../js/ui/messageTray.js:2813 #: ../js/ui/messageTray.js:2864
msgid "System Information" msgid "System Information"
msgstr "Πληροφορίες συστήματος" msgstr "Πληροφορίες συστήματος"
@ -1272,14 +1260,14 @@ msgctxt "program"
msgid "Unknown" msgid "Unknown"
msgstr "Άγνωστο" msgstr "Άγνωστο"
#: ../js/ui/overviewControls.js:463 ../js/ui/screenShield.js:149 #: ../js/ui/overviewControls.js:460 ../js/ui/screenShield.js:153
#, c-format #, c-format
msgid "%d new message" msgid "%d new message"
msgid_plural "%d new messages" msgid_plural "%d new messages"
msgstr[0] "%d νέο μήνυμα" msgstr[0] "%d νέο μήνυμα"
msgstr[1] "%d νέα μηνύματα" msgstr[1] "%d νέα μηνύματα"
#: ../js/ui/overview.js:84 #: ../js/ui/overview.js:82
msgid "Undo" msgid "Undo"
msgstr "Αναίρεση" msgstr "Αναίρεση"
@ -1291,21 +1279,22 @@ msgstr "Επισκόπηση"
#. in the search entry when no search is #. in the search entry when no search is
#. active; it should not exceed ~30 #. active; it should not exceed ~30
#. characters. #. characters.
#: ../js/ui/overview.js:271 #: ../js/ui/overview.js:284
#| msgid "Type to search..."
msgid "Type to search…" msgid "Type to search…"
msgstr "Πληκτρολογήστε για αναζήτηση…" msgstr "Πληκτρολογήστε για αναζήτηση…"
#: ../js/ui/panel.js:633 #: ../js/ui/panel.js:613
msgid "Quit" msgid "Quit"
msgstr "Έξοδος" msgstr "Έξοδος"
#. Translators: If there is no suitable word for "Activities" #. Translators: If there is no suitable word for "Activities"
#. in your language, you can use the word for "Overview". #. in your language, you can use the word for "Overview".
#: ../js/ui/panel.js:657 #: ../js/ui/panel.js:642
msgid "Activities" msgid "Activities"
msgstr "Δραστηριότητες" msgstr "Δραστηριότητες"
#: ../js/ui/panel.js:954 #: ../js/ui/panel.js:983
msgid "Top Bar" msgid "Top Bar"
msgstr "Πάνω μπάρα" msgstr "Πάνω μπάρα"
@ -1318,32 +1307,32 @@ msgstr "Πάνω μπάρα"
msgid "toggle-switch-us" msgid "toggle-switch-us"
msgstr "toggle-switch-intl" msgstr "toggle-switch-intl"
#: ../js/ui/runDialog.js:74 #: ../js/ui/runDialog.js:205
msgid "Enter a Command" msgid "Enter a Command"
msgstr "Εισαγωγή εντολής" msgstr "Εισαγωγή εντολής"
#: ../js/ui/runDialog.js:110 #: ../js/ui/runDialog.js:241
msgid "Close" msgid "Close"
msgstr "Κλείσιμο" msgstr "Κλείσιμο"
#. Translators: This is a time format for a date in #. Translators: This is a time format for a date in
#. long format #. long format
#: ../js/ui/screenShield.js:86 #: ../js/ui/screenShield.js:90
msgid "%A, %B %d" msgid "%A, %B %d"
msgstr "%A, %B %d" msgstr "%A, %B %d"
#: ../js/ui/screenShield.js:151 #: ../js/ui/screenShield.js:155
#, c-format #, c-format
msgid "%d new notification" msgid "%d new notification"
msgid_plural "%d new notifications" msgid_plural "%d new notifications"
msgstr[0] "%d νέα ειδοποίηση" msgstr[0] "%d νέα ειδοποίηση"
msgstr[1] "%d νέες ειδοποιήσεις" msgstr[1] "%d νέες ειδοποιήσεις"
#: ../js/ui/screenShield.js:438 ../js/ui/userMenu.js:807 #: ../js/ui/screenShield.js:442 ../js/ui/userMenu.js:805
msgid "Lock" msgid "Lock"
msgstr "Κλείδωμα" msgstr "Κλείδωμα"
#: ../js/ui/screenShield.js:641 #: ../js/ui/screenShield.js:639
msgid "GNOME needs to lock the screen" msgid "GNOME needs to lock the screen"
msgstr "Το GNOME χρειάζεται να κλειδώσει την οθόνη" msgstr "Το GNOME χρειάζεται να κλειδώσει την οθόνη"
@ -1354,19 +1343,21 @@ msgstr "Το GNOME χρειάζεται να κλειδώσει την οθόν
#. #.
#. XXX: another option is to kick the user into the gdm login #. XXX: another option is to kick the user into the gdm login
#. screen, where we're not affected by grabs #. screen, where we're not affected by grabs
#: ../js/ui/screenShield.js:762 ../js/ui/screenShield.js:1198 #: ../js/ui/screenShield.js:758 ../js/ui/screenShield.js:1169
#| msgid "Unable to connect to %s"
msgid "Unable to lock" msgid "Unable to lock"
msgstr "Αδυναμία κλειδώματος" msgstr "Αδυναμία κλειδώματος"
#: ../js/ui/screenShield.js:763 ../js/ui/screenShield.js:1199 #: ../js/ui/screenShield.js:759 ../js/ui/screenShield.js:1170
msgid "Lock was blocked by an application" msgid "Lock was blocked by an application"
msgstr "Το κλείδωμα εμποδίστηκε από μια εφαρμογή" msgstr "Το κλείδωμα εμποδίστηκε από μια εφαρμογή"
#: ../js/ui/searchDisplay.js:453 #: ../js/ui/searchDisplay.js:431
#| msgid "Searching..."
msgid "Searching…" msgid "Searching…"
msgstr "Αναζήτηση…" msgstr "Αναζήτηση…"
#: ../js/ui/searchDisplay.js:497 #: ../js/ui/searchDisplay.js:475
msgid "No results." msgid "No results."
msgstr "Δε βρέθηκαν αποτελέσματα." msgstr "Δε βρέθηκαν αποτελέσματα."
@ -1378,11 +1369,11 @@ msgstr "Αντιγραφή"
msgid "Paste" msgid "Paste"
msgstr "Επικόλληση" msgstr "Επικόλληση"
#: ../js/ui/shellEntry.js:101 #: ../js/ui/shellEntry.js:105
msgid "Show Text" msgid "Show Text"
msgstr "Εμφάνιση κειμένου" msgstr "Εμφάνιση κειμένου"
#: ../js/ui/shellEntry.js:103 #: ../js/ui/shellEntry.js:107
msgid "Hide Text" msgid "Hide Text"
msgstr "Απόκρυψη κειμένου" msgstr "Απόκρυψη κειμένου"
@ -1394,7 +1385,7 @@ msgstr "Κωδικός"
msgid "Remember Password" msgid "Remember Password"
msgstr "Απομνημόνευση κωδικού" msgstr "Απομνημόνευση κωδικού"
#: ../js/ui/shellMountOperation.js:403 ../js/ui/unlockDialog.js:114 #: ../js/ui/shellMountOperation.js:403 ../js/ui/unlockDialog.js:140
msgid "Unlock" msgid "Unlock"
msgstr "Ξεκλείδωμα" msgstr "Ξεκλείδωμα"
@ -1458,10 +1449,12 @@ msgid "Visibility"
msgstr "Ορατότητα" msgstr "Ορατότητα"
#: ../js/ui/status/bluetooth.js:59 #: ../js/ui/status/bluetooth.js:59
#| msgid "Send Files to Device..."
msgid "Send Files to Device…" msgid "Send Files to Device…"
msgstr "Αποστολή αρχείων σε συσκευή…" msgstr "Αποστολή αρχείων σε συσκευή…"
#: ../js/ui/status/bluetooth.js:60 #: ../js/ui/status/bluetooth.js:60
#| msgid "Set Up a New Device..."
msgid "Set Up a New Device…" msgid "Set Up a New Device…"
msgstr "Ρύθμιση νέας συσκευής…" msgstr "Ρύθμιση νέας συσκευής…"
@ -1488,6 +1481,7 @@ msgid "connecting..."
msgstr "σύνδεση..." msgstr "σύνδεση..."
#: ../js/ui/status/bluetooth.js:239 #: ../js/ui/status/bluetooth.js:239
#| msgid "Send Files..."
msgid "Send Files…" msgid "Send Files…"
msgstr "Αποστολή αρχείων…" msgstr "Αποστολή αρχείων…"
@ -1700,6 +1694,7 @@ msgstr "Ρυθμίσεις τροφοδοσίας"
#. 0 is reported when UPower does not have enough data #. 0 is reported when UPower does not have enough data
#. to estimate battery life #. to estimate battery life
#: ../js/ui/status/power.js:99 #: ../js/ui/status/power.js:99
#| msgid "Estimating..."
msgid "Estimating…" msgid "Estimating…"
msgstr "Υπολογισμός…" msgstr "Υπολογισμός…"
@ -1799,59 +1794,59 @@ msgstr "Ένταση ήχου"
msgid "Microphone" msgid "Microphone"
msgstr "Μικρόφωνο" msgstr "Μικρόφωνο"
#: ../js/ui/unlockDialog.js:125 #: ../js/ui/unlockDialog.js:151
msgid "Log in as another user" msgid "Log in as another user"
msgstr "Είσοδος ως άλλος χρήστης" msgstr "Είσοδος ως άλλος χρήστης"
#: ../js/ui/unlockDialog.js:146 #: ../js/ui/unlockDialog.js:177
msgid "Unlock Window" msgid "Unlock Window"
msgstr "Ξεκλείδωμα παραθύρου" msgstr "Ξεκλείδωμα παραθύρου"
#: ../js/ui/userMenu.js:193 #: ../js/ui/userMenu.js:192
msgid "Available" msgid "Available"
msgstr "Διαθέσιμος-η" msgstr "Διαθέσιμος-η"
#: ../js/ui/userMenu.js:196 #: ../js/ui/userMenu.js:195
msgid "Busy" msgid "Busy"
msgstr "Απασχολημένος-η" msgstr "Απασχολημένος-η"
#: ../js/ui/userMenu.js:199 #: ../js/ui/userMenu.js:198
msgid "Invisible" msgid "Invisible"
msgstr "Αόρατος-η" msgstr "Αόρατος-η"
#: ../js/ui/userMenu.js:202 #: ../js/ui/userMenu.js:201
msgid "Away" msgid "Away"
msgstr "Απουσιάζει" msgstr "Απουσιάζει"
#: ../js/ui/userMenu.js:205 #: ../js/ui/userMenu.js:204
msgid "Idle" msgid "Idle"
msgstr "Αδρανής" msgstr "Αδρανής"
#: ../js/ui/userMenu.js:208 #: ../js/ui/userMenu.js:207
msgid "Offline" msgid "Offline"
msgstr "Εκτός σύνδεσης" msgstr "Εκτός σύνδεσης"
#: ../js/ui/userMenu.js:781 #: ../js/ui/userMenu.js:779
msgid "Notifications" msgid "Notifications"
msgstr "Ειδοποιήσεις" msgstr "Ειδοποιήσεις"
#: ../js/ui/userMenu.js:797 #: ../js/ui/userMenu.js:795
msgid "Switch User" msgid "Switch User"
msgstr "Αλλαγή χρήστη" msgstr "Αλλαγή χρήστη"
#: ../js/ui/userMenu.js:802 #: ../js/ui/userMenu.js:800
msgid "Log Out" msgid "Log Out"
msgstr "Αποσύνδεση" msgstr "Αποσύνδεση"
#: ../js/ui/userMenu.js:822 #: ../js/ui/userMenu.js:820
msgid "Install Updates & Restart" msgid "Install Updates & Restart"
msgstr "Εγκατάσταση ενημερώσεων & επανεκκίνηση" msgstr "Εγκατάσταση ενημερώσεων & επανεκκίνηση"
#: ../js/ui/userMenu.js:840 #: ../js/ui/userMenu.js:838
msgid "Your chat status will be set to busy" msgid "Your chat status will be set to busy"
msgstr "Η κατάσταση συνομιλίας σας θα ορισθεί σε απασχολημένος" msgstr "Η κατάσταση συνομιλίας σας θα ορισθεί σε απασχολημένος"
#: ../js/ui/userMenu.js:841 #: ../js/ui/userMenu.js:839
msgid "" msgid ""
"Notifications are now disabled, including chat messages. Your online status " "Notifications are now disabled, including chat messages. Your online status "
"has been adjusted to let others know that you might not see their messages." "has been adjusted to let others know that you might not see their messages."
@ -1860,36 +1855,34 @@ msgstr ""
"κατάσταση σας έχει ορισθεί έτσι ώστε να γίνεται γνωστό ότι πιθανόν να μην " "κατάσταση σας έχει ορισθεί έτσι ώστε να γίνεται γνωστό ότι πιθανόν να μην "
"δείτε τα μηνύματα τους." "δείτε τα μηνύματα τους."
#: ../js/ui/userMenu.js:888 #: ../js/ui/userMenu.js:885
msgid "Other users are logged in." msgid "Other users are logged in."
msgstr "Και άλλοι χρήστες είναι συνδεμένοι." msgstr "Και άλλοι χρήστες είναι συνδεμένοι."
#: ../js/ui/userMenu.js:893 #: ../js/ui/userMenu.js:890
msgid "Shutting down might cause them to lose unsaved work." msgid "Shutting down might cause them to lose unsaved work."
msgstr "" msgstr ""
"Κλείνοντας μπορεί να τους προκαλέσετε την απώλεια αναποθήκευτης εργασίας." "Κλείνοντας μπορεί να τους προκαλέσετε την απώλεια αναποθήκευτης εργασίας."
#. Translators: Remote here refers to a remote session, like a ssh login #: ../js/ui/userMenu.js:916
#: ../js/ui/userMenu.js:921
#, c-format #, c-format
msgid "%s (remote)" msgid "%s (remote)"
msgstr "%s (απομακρυσμένο)" msgstr "%s (απομακρυσμένο)"
#. Translators: Console here refers to a tty like a VT console #: ../js/ui/userMenu.js:918
#: ../js/ui/userMenu.js:924
#, c-format #, c-format
msgid "%s (console)" msgid "%s (console)"
msgstr "%s (κονσόλα)" msgstr "%s (κονσόλα)"
#: ../js/ui/viewSelector.js:100 #: ../js/ui/viewSelector.js:101
msgid "Applications" msgid "Applications"
msgstr "Εφαρμογές" msgstr "Εφαρμογές"
#: ../js/ui/viewSelector.js:104 #: ../js/ui/viewSelector.js:105
msgid "Search" msgid "Search"
msgstr "Αναζήτηση" msgstr "Αναζήτηση"
#: ../js/ui/wanda.js:77 #: ../js/ui/wanda.js:92
#, c-format #, c-format
msgid "" msgid ""
"Sorry, no wisdom for you today:\n" "Sorry, no wisdom for you today:\n"
@ -1898,7 +1891,7 @@ msgstr ""
"Συγγνώμη, κανένα απόφθεγμα για εσάς σήμερα:\n" "Συγγνώμη, κανένα απόφθεγμα για εσάς σήμερα:\n"
"%s" "%s"
#: ../js/ui/wanda.js:81 #: ../js/ui/wanda.js:96
#, c-format #, c-format
msgid "%s the Oracle says" msgid "%s the Oracle says"
msgstr "%s ο Προφήτης λέει" msgstr "%s ο Προφήτης λέει"

442
po/es.po

File diff suppressed because it is too large Load Diff

219
po/gl.po
View File

@ -10,9 +10,10 @@
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: gnome-shell master\n" "Project-Id-Version: gnome-shell master\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-"
"POT-Creation-Date: 2013-04-18 01:27+0200\n" "shell&keywords=I18N+L10N&component=general\n"
"PO-Revision-Date: 2013-04-18 01:42+0200\n" "POT-Creation-Date: 2013-03-02 23:02+0000\n"
"PO-Revision-Date: 2013-03-04 12:40+0200\n"
"Last-Translator: Fran Dieguez <frandieguez@gnome.org>\n" "Last-Translator: Fran Dieguez <frandieguez@gnome.org>\n"
"Language-Team: gnome-l10n-gl@gnome.org\n" "Language-Team: gnome-l10n-gl@gnome.org\n"
"Language: gl\n" "Language: gl\n"
@ -29,7 +30,7 @@ msgstr "Capturas de pantalla"
#: ../data/50-gnome-shell-screenshot.xml.in.h:2 #: ../data/50-gnome-shell-screenshot.xml.in.h:2
msgid "Record a screencast" msgid "Record a screencast"
msgstr "Facer unha gravación da pantalla" msgstr "Gravar unha gravación de pantalla"
#: ../data/50-gnome-shell-system.xml.in.h:1 #: ../data/50-gnome-shell-system.xml.in.h:1
msgid "System" msgid "System"
@ -62,16 +63,16 @@ msgstr "Xestor de xanelas e inicio de aplicativos"
#: ../data/gnome-shell-extension-prefs.desktop.in.in.h:1 #: ../data/gnome-shell-extension-prefs.desktop.in.in.h:1
#: ../js/extensionPrefs/main.js:153 #: ../js/extensionPrefs/main.js:153
msgid "GNOME Shell Extension Preferences" msgid "GNOME Shell Extension Preferences"
msgstr "Preferencias das extensións de GNOME Shell" msgstr "Preferencias de extensións de GNOME Shell"
#: ../data/gnome-shell-extension-prefs.desktop.in.in.h:2 #: ../data/gnome-shell-extension-prefs.desktop.in.in.h:2
msgid "Configure GNOME Shell Extensions" msgid "Configure GNOME Shell Extensions"
msgstr "Configure as extensións de GNOME Shell" msgstr "Configurar as extensións de GNOME Shell"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:1 #: ../data/org.gnome.shell.gschema.xml.in.in.h:1
msgid "Enable internal tools useful for developers and testers from Alt-F2" msgid "Enable internal tools useful for developers and testers from Alt-F2"
msgstr "" msgstr ""
"Activar as ferramentas internas útiles para os desenvolvedores e probadores " "Activar as ferramentas internas útiles para os desenvolvedores e probadores, "
"usando Alt-F2" "usando Alt-F2"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:2 #: ../data/org.gnome.shell.gschema.xml.in.in.h:2
@ -84,7 +85,7 @@ msgstr ""
#: ../data/org.gnome.shell.gschema.xml.in.in.h:3 #: ../data/org.gnome.shell.gschema.xml.in.in.h:3
msgid "Uuids of extensions to enable" msgid "Uuids of extensions to enable"
msgstr "UUIDs das extensións a activar" msgstr "Uuid das extensións que activar"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:4 #: ../data/org.gnome.shell.gschema.xml.in.in.h:4
msgid "" msgid ""
@ -374,42 +375,43 @@ msgstr ""
"Seleccione unha extensión que configurar usando a caixa combinada de arriba." "Seleccione unha extensión que configurar usando a caixa combinada de arriba."
#: ../js/gdm/loginDialog.js:405 #: ../js/gdm/loginDialog.js:405
#| msgid "Session..."
msgid "Session…" msgid "Session…"
msgstr "Sesión…" msgstr "Sesión…"
#. translators: this message is shown below the user list on the #. translators: this message is shown below the user list on the
#. login screen. It can be activated to reveal an entry for #. login screen. It can be activated to reveal an entry for
#. manually entering the username. #. manually entering the username.
#: ../js/gdm/loginDialog.js:630 #: ../js/gdm/loginDialog.js:629
msgid "Not listed?" msgid "Not listed?"
msgstr "Non está na lista?" msgstr "Non está na lista?"
#: ../js/gdm/loginDialog.js:787 ../js/ui/components/networkAgent.js:137 #: ../js/gdm/loginDialog.js:783 ../js/ui/components/networkAgent.js:137
#: ../js/ui/components/polkitAgent.js:162 ../js/ui/endSessionDialog.js:376 #: ../js/ui/components/polkitAgent.js:162 ../js/ui/endSessionDialog.js:375
#: ../js/ui/extensionDownloader.js:195 ../js/ui/shellMountOperation.js:399 #: ../js/ui/extensionDownloader.js:195 ../js/ui/shellMountOperation.js:399
#: ../js/ui/status/bluetooth.js:415 ../js/ui/unlockDialog.js:100 #: ../js/ui/status/bluetooth.js:415 ../js/ui/unlockDialog.js:126
#: ../js/ui/userMenu.js:938 #: ../js/ui/userMenu.js:932
msgid "Cancel" msgid "Cancel"
msgstr "Cancelar" msgstr "Cancelar"
#: ../js/gdm/loginDialog.js:803 #: ../js/gdm/loginDialog.js:799
msgctxt "button" msgctxt "button"
msgid "Sign In" msgid "Sign In"
msgstr "Iniciar sesión" msgstr "Iniciar sesión"
#: ../js/gdm/loginDialog.js:803 #: ../js/gdm/loginDialog.js:799
msgid "Next" msgid "Next"
msgstr "Seguinte" msgstr "Seguinte"
#. TTLS and PEAP are actually much more complicated, but this complication #. TTLS and PEAP are actually much more complicated, but this complication
#. is not visible here since we only care about phase2 authentication #. is not visible here since we only care about phase2 authentication
#. (and don't even care of which one) #. (and don't even care of which one)
#: ../js/gdm/loginDialog.js:918 ../js/ui/components/networkAgent.js:260 #: ../js/gdm/loginDialog.js:904 ../js/ui/components/networkAgent.js:260
#: ../js/ui/components/networkAgent.js:278 #: ../js/ui/components/networkAgent.js:278
msgid "Username: " msgid "Username: "
msgstr "Nome de usuario: " msgstr "Nome de usuario: "
#: ../js/gdm/loginDialog.js:1174 #: ../js/gdm/loginDialog.js:1157
msgid "Login Window" msgid "Login Window"
msgstr "Xanela de inicio de sesión" msgstr "Xanela de inicio de sesión"
@ -418,8 +420,8 @@ msgstr "Xanela de inicio de sesión"
msgid "Power" msgid "Power"
msgstr "Apagar" msgstr "Apagar"
#: ../js/gdm/powerMenu.js:93 ../js/ui/userMenu.js:696 ../js/ui/userMenu.js:700 #: ../js/gdm/powerMenu.js:93 ../js/ui/userMenu.js:694 ../js/ui/userMenu.js:698
#: ../js/ui/userMenu.js:816 #: ../js/ui/userMenu.js:814
msgid "Suspend" msgid "Suspend"
msgstr "Suspender" msgstr "Suspender"
@ -427,58 +429,58 @@ msgstr "Suspender"
msgid "Restart" msgid "Restart"
msgstr "Reiniciar" msgstr "Reiniciar"
#: ../js/gdm/powerMenu.js:103 ../js/ui/userMenu.js:698 #: ../js/gdm/powerMenu.js:103 ../js/ui/userMenu.js:696
#: ../js/ui/userMenu.js:700 ../js/ui/userMenu.js:815 ../js/ui/userMenu.js:942 #: ../js/ui/userMenu.js:698 ../js/ui/userMenu.js:813 ../js/ui/userMenu.js:936
msgid "Power Off" msgid "Power Off"
msgstr "Apagar" msgstr "Apagar"
#: ../js/gdm/util.js:249 #: ../js/gdm/util.js:182
msgid "Authentication error" msgid "Authentication error"
msgstr "Erro de autenticación" msgstr "Erro de autenticación"
#. Translators: this message is shown below the password entry field #. Translators: this message is shown below the password entry field
#. to indicate the user can swipe their finger instead #. to indicate the user can swipe their finger instead
#: ../js/gdm/util.js:366 #: ../js/gdm/util.js:299
msgid "(or swipe finger)" msgid "(or swipe finger)"
msgstr "(ou pase o dedo)" msgstr "(ou pase o dedo)"
#: ../js/gdm/util.js:391 #: ../js/gdm/util.js:324
#, c-format #, c-format
msgid "(e.g., user or %s)" msgid "(e.g., user or %s)"
msgstr "(p.ex., usuario ou %s)" msgstr "(p.ex., usuario ou %s)"
#: ../js/misc/util.js:97 #: ../js/misc/util.js:94
msgid "Command not found" msgid "Command not found"
msgstr "Orde non atopada" msgstr "Orde non atopada"
#. Replace "Error invoking GLib.shell_parse_argv: " with #. Replace "Error invoking GLib.shell_parse_argv: " with
#. something nicer #. something nicer
#: ../js/misc/util.js:130 #: ../js/misc/util.js:127
msgid "Could not parse command:" msgid "Could not parse command:"
msgstr "Non foi posíbel analizar a orde:" msgstr "Non foi posíbel analizar a orde:"
#: ../js/misc/util.js:138 #: ../js/misc/util.js:135
#, c-format #, c-format
msgid "Execution of '%s' failed:" msgid "Execution of '%s' failed:"
msgstr "Produciuse un fallo na execución de «%s»:" msgstr "Produciuse un fallo na execución de «%s»:"
#: ../js/ui/appDisplay.js:349 #: ../js/ui/appDisplay.js:348
msgid "Frequent" msgid "Frequent"
msgstr "Frecuentes" msgstr "Frecuentes"
#: ../js/ui/appDisplay.js:356 #: ../js/ui/appDisplay.js:355
msgid "All" msgid "All"
msgstr "Todos" msgstr "Todos"
#: ../js/ui/appDisplay.js:914 #: ../js/ui/appDisplay.js:913
msgid "New Window" msgid "New Window"
msgstr "Xanela nova" msgstr "Xanela nova"
#: ../js/ui/appDisplay.js:917 ../js/ui/dash.js:284 #: ../js/ui/appDisplay.js:916 ../js/ui/dash.js:284
msgid "Remove from Favorites" msgid "Remove from Favorites"
msgstr "Retirar dos marcadores" msgstr "Retirar dos marcadores"
#: ../js/ui/appDisplay.js:918 #: ../js/ui/appDisplay.js:917
msgid "Add to Favorites" msgid "Add to Favorites"
msgstr "Engadir aos favoritos" msgstr "Engadir aos favoritos"
@ -492,7 +494,7 @@ msgstr "%s foi engadido aos seus favoritos."
msgid "%s has been removed from your favorites." msgid "%s has been removed from your favorites."
msgstr "%s retirouse dos seus marcadores." msgstr "%s retirouse dos seus marcadores."
#: ../js/ui/backgroundMenu.js:19 ../js/ui/userMenu.js:789 #: ../js/ui/backgroundMenu.js:19 ../js/ui/userMenu.js:787
msgid "Settings" msgid "Settings"
msgstr "Preferencias" msgstr "Preferencias"
@ -515,7 +517,7 @@ msgctxt "event list time"
msgid "%H\\u2236%M" msgid "%H\\u2236%M"
msgstr "%H\\u2236%M" msgstr "%H\\u2236%M"
#. Translators: Shown in calendar event list, if 12h format, #. Transators: Shown in calendar event list, if 12h format,
#. \u2236 is a ratio character, similar to : and \u2009 is #. \u2236 is a ratio character, similar to : and \u2009 is
#. a thin space #. a thin space
#: ../js/ui/calendar.js:77 #: ../js/ui/calendar.js:77
@ -617,35 +619,35 @@ msgid "S"
msgstr "S" msgstr "S"
#. Translators: Text to show if there are no events #. Translators: Text to show if there are no events
#: ../js/ui/calendar.js:720 #: ../js/ui/calendar.js:692
msgid "Nothing Scheduled" msgid "Nothing Scheduled"
msgstr "Nada programado" msgstr "Nada programado"
#. Translators: Shown on calendar heading when selected day occurs on current year #. Translators: Shown on calendar heading when selected day occurs on current year
#: ../js/ui/calendar.js:736 #: ../js/ui/calendar.js:708
msgctxt "calendar heading" msgctxt "calendar heading"
msgid "%A, %B %d" msgid "%A, %B %d"
msgstr "%A, %d de %B" msgstr "%A, %d de %B"
#. Translators: Shown on calendar heading when selected day occurs on different year #. Translators: Shown on calendar heading when selected day occurs on different year
#: ../js/ui/calendar.js:739 #: ../js/ui/calendar.js:711
msgctxt "calendar heading" msgctxt "calendar heading"
msgid "%A, %B %d, %Y" msgid "%A, %B %d, %Y"
msgstr "%A, %d de %B de %Y" msgstr "%A, %d de %B de %Y"
#: ../js/ui/calendar.js:749 #: ../js/ui/calendar.js:721
msgid "Today" msgid "Today"
msgstr "Hoxe" msgstr "Hoxe"
#: ../js/ui/calendar.js:753 #: ../js/ui/calendar.js:725
msgid "Tomorrow" msgid "Tomorrow"
msgstr "Mañá" msgstr "Mañá"
#: ../js/ui/calendar.js:764 #: ../js/ui/calendar.js:736
msgid "This week" msgid "This week"
msgstr "Esta semana" msgstr "Esta semana"
#: ../js/ui/calendar.js:772 #: ../js/ui/calendar.js:744
msgid "Next week" msgid "Next week"
msgstr "A vindeira semana" msgstr "A vindeira semana"
@ -661,12 +663,12 @@ msgstr "Unidade externa desconectada"
msgid "Removable Devices" msgid "Removable Devices"
msgstr "Dispositivos extraíbeis" msgstr "Dispositivos extraíbeis"
#: ../js/ui/components/autorunManager.js:594 #: ../js/ui/components/autorunManager.js:593
#, c-format #, c-format
msgid "Open with %s" msgid "Open with %s"
msgstr "Abrir con %s" msgstr "Abrir con %s"
#: ../js/ui/components/autorunManager.js:620 #: ../js/ui/components/autorunManager.js:619
msgid "Eject" msgid "Eject"
msgstr "Expulsar" msgstr "Expulsar"
@ -775,7 +777,7 @@ msgid "Sorry, that didn't work. Please try again."
msgstr "Desculpe, iso non funcionou. Ténteo de novo." msgstr "Desculpe, iso non funcionou. Ténteo de novo."
#. Translators: this is a filename used for screencast recording #. Translators: this is a filename used for screencast recording
#: ../js/ui/components/recorder.js:47 #: ../js/ui/components/recorder.js:48
#, no-c-format #, no-c-format
msgid "Screencast from %d %t" msgid "Screencast from %d %t"
msgstr "Screencast desde %d %t" msgstr "Screencast desde %d %t"
@ -1022,7 +1024,7 @@ msgstr "Ver conta"
msgid "Unknown reason" msgid "Unknown reason"
msgstr "Razón descoñecida" msgstr "Razón descoñecida"
#: ../js/ui/ctrlAltTab.js:29 ../js/ui/viewSelector.js:96 #: ../js/ui/ctrlAltTab.js:29 ../js/ui/viewSelector.js:97
msgid "Windows" msgid "Windows"
msgstr "Xanelas" msgstr "Xanelas"
@ -1038,7 +1040,7 @@ msgstr "Taboleiro"
#: ../js/ui/dateMenu.js:91 #: ../js/ui/dateMenu.js:91
msgid "Open Calendar" msgid "Open Calendar"
msgstr "Abrir Calendario" msgstr "Abrir o calendario"
#: ../js/ui/dateMenu.js:96 #: ../js/ui/dateMenu.js:96
msgid "Open Clocks" msgid "Open Clocks"
@ -1051,7 +1053,7 @@ msgstr "Preferencias de data e hora"
#. Translators: This is the date format to use when the calendar popup is #. Translators: This is the date format to use when the calendar popup is
#. * shown - it is shown just below the time in the shell (e.g. "Tue 9:29 AM"). #. * shown - it is shown just below the time in the shell (e.g. "Tue 9:29 AM").
#. #.
#: ../js/ui/dateMenu.js:215 #: ../js/ui/dateMenu.js:205
msgid "%A %B %e, %Y" msgid "%A %B %e, %Y"
msgstr "%a, %e de %B, %Y" msgstr "%a, %e de %B, %Y"
@ -1069,7 +1071,7 @@ msgstr "Saír da sesión"
#: ../js/ui/endSessionDialog.js:65 #: ../js/ui/endSessionDialog.js:65
msgid "Click Log Out to quit these applications and log out of the system." msgid "Click Log Out to quit these applications and log out of the system."
msgstr "" msgstr ""
"Prema en «Saír da sesión» para pechar estes aplicativos e saír da sesión do " "Prema sobre «Saír da sesión» para saír deses aplicativos e saír da sesión do "
"sistema." "sistema."
#: ../js/ui/endSessionDialog.js:67 #: ../js/ui/endSessionDialog.js:67
@ -1088,7 +1090,7 @@ msgstr[1] "A súa sesión pecharase automaticamente en %d segundos."
#: ../js/ui/endSessionDialog.js:76 #: ../js/ui/endSessionDialog.js:76
msgid "Logging out of the system." msgid "Logging out of the system."
msgstr "Saíndo da sesión do sistema." msgstr "Saíndo da sesión."
#: ../js/ui/endSessionDialog.js:78 #: ../js/ui/endSessionDialog.js:78
msgctxt "button" msgctxt "button"
@ -1102,7 +1104,7 @@ msgstr "Apagar"
#: ../js/ui/endSessionDialog.js:84 #: ../js/ui/endSessionDialog.js:84
msgid "Click Power Off to quit these applications and power off the system." msgid "Click Power Off to quit these applications and power off the system."
msgstr "Prema sobre «Apagar» para pechar estes aplicativos e apagar o sistema." msgstr "Prema sobre «Apagar» para saír deses aplicativos e apagar o sistema."
#: ../js/ui/endSessionDialog.js:86 #: ../js/ui/endSessionDialog.js:86
#, c-format #, c-format
@ -1132,7 +1134,7 @@ msgstr "Reiniciar"
#: ../js/ui/endSessionDialog.js:101 #: ../js/ui/endSessionDialog.js:101
msgid "Click Restart to quit these applications and restart the system." msgid "Click Restart to quit these applications and restart the system."
msgstr "Prema «Reiniciar» para pechar estes aplicativos e reiniciar o sistema." msgstr "Prema «Reiniciar» para saír deses aplicativos e reiniciar o sistema."
#: ../js/ui/endSessionDialog.js:103 #: ../js/ui/endSessionDialog.js:103
#, c-format #, c-format
@ -1167,7 +1169,7 @@ msgstr "Non hai ningunha extensión instalada"
#: ../js/ui/lookingGlass.js:747 #: ../js/ui/lookingGlass.js:747
#, c-format #, c-format
msgid "%s has not emitted any errors." msgid "%s has not emitted any errors."
msgstr "%s non emitiu ningún erro." msgstr "%s non xerou ningún erro."
#: ../js/ui/lookingGlass.js:753 #: ../js/ui/lookingGlass.js:753
msgid "Hide Errors" msgid "Hide Errors"
@ -1193,7 +1195,7 @@ msgstr "Erro"
#: ../js/ui/lookingGlass.js:773 #: ../js/ui/lookingGlass.js:773
msgid "Out of date" msgid "Out of date"
msgstr "Obsoleto" msgstr "Caducado"
#: ../js/ui/lookingGlass.js:775 #: ../js/ui/lookingGlass.js:775
msgid "Downloading" msgid "Downloading"
@ -1216,6 +1218,7 @@ msgid "Remove"
msgstr "Retirar" msgstr "Retirar"
#: ../js/ui/messageTray.js:1501 #: ../js/ui/messageTray.js:1501
#| msgid "No Messages"
msgid "Clear Messages" msgid "Clear Messages"
msgstr "Limpar mensaxes" msgstr "Limpar mensaxes"
@ -1223,15 +1226,15 @@ msgstr "Limpar mensaxes"
msgid "Notification Settings" msgid "Notification Settings"
msgstr "Preferencias das notificacións" msgstr "Preferencias das notificacións"
#: ../js/ui/messageTray.js:1709 #: ../js/ui/messageTray.js:1707
msgid "No Messages" msgid "No Messages"
msgstr "Non hai mensaxes" msgstr "Non hai mensaxes"
#: ../js/ui/messageTray.js:1785 #: ../js/ui/messageTray.js:1787
msgid "Message Tray" msgid "Message Tray"
msgstr "Bandexa de mensaxes" msgstr "Bandexa de mensaxes"
#: ../js/ui/messageTray.js:2813 #: ../js/ui/messageTray.js:2864
msgid "System Information" msgid "System Information"
msgstr "Información do sistema" msgstr "Información do sistema"
@ -1240,14 +1243,14 @@ msgctxt "program"
msgid "Unknown" msgid "Unknown"
msgstr "Descoñecido" msgstr "Descoñecido"
#: ../js/ui/overviewControls.js:463 ../js/ui/screenShield.js:149 #: ../js/ui/overviewControls.js:460 ../js/ui/screenShield.js:153
#, c-format #, c-format
msgid "%d new message" msgid "%d new message"
msgid_plural "%d new messages" msgid_plural "%d new messages"
msgstr[0] "%d mensaxe nova" msgstr[0] "%d mensaxe nova"
msgstr[1] "%d mensaxes novas" msgstr[1] "%d mensaxes novas"
#: ../js/ui/overview.js:84 #: ../js/ui/overview.js:82
msgid "Undo" msgid "Undo"
msgstr "Desfacer" msgstr "Desfacer"
@ -1259,21 +1262,22 @@ msgstr "Vista xeral"
#. in the search entry when no search is #. in the search entry when no search is
#. active; it should not exceed ~30 #. active; it should not exceed ~30
#. characters. #. characters.
#: ../js/ui/overview.js:271 #: ../js/ui/overview.js:284
#| msgid "Type to search..."
msgid "Type to search…" msgid "Type to search…"
msgstr "Escriba para buscar…" msgstr "Escriba para buscar…"
#: ../js/ui/panel.js:633 #: ../js/ui/panel.js:613
msgid "Quit" msgid "Quit"
msgstr "Saír" msgstr "Saír"
#. Translators: If there is no suitable word for "Activities" #. Translators: If there is no suitable word for "Activities"
#. in your language, you can use the word for "Overview". #. in your language, you can use the word for "Overview".
#: ../js/ui/panel.js:657 #: ../js/ui/panel.js:642
msgid "Activities" msgid "Activities"
msgstr "Actividades" msgstr "Actividades"
#: ../js/ui/panel.js:954 #: ../js/ui/panel.js:983
msgid "Top Bar" msgid "Top Bar"
msgstr "Barra superior" msgstr "Barra superior"
@ -1286,34 +1290,34 @@ msgstr "Barra superior"
msgid "toggle-switch-us" msgid "toggle-switch-us"
msgstr "toggle-switch-intl" msgstr "toggle-switch-intl"
#: ../js/ui/runDialog.js:74 #: ../js/ui/runDialog.js:205
msgid "Enter a Command" msgid "Enter a Command"
msgstr "Escriba unha orde" msgstr "Escriba unha orde"
#: ../js/ui/runDialog.js:110 #: ../js/ui/runDialog.js:241
msgid "Close" msgid "Close"
msgstr "Pechar" msgstr "Pechar"
#. Translators: This is a time format for a date in #. Translators: This is a time format for a date in
#. long format #. long format
#: ../js/ui/screenShield.js:86 #: ../js/ui/screenShield.js:90
msgid "%A, %B %d" msgid "%A, %B %d"
msgstr "%A, %d de %B" msgstr "%A, %d de %B"
#: ../js/ui/screenShield.js:151 #: ../js/ui/screenShield.js:155
#, c-format #, c-format
msgid "%d new notification" msgid "%d new notification"
msgid_plural "%d new notifications" msgid_plural "%d new notifications"
msgstr[0] "%d notificación nova" msgstr[0] "%d notificación nova"
msgstr[1] "%d notificacións novas" msgstr[1] "%d notificacións novas"
#: ../js/ui/screenShield.js:438 ../js/ui/userMenu.js:807 #: ../js/ui/screenShield.js:442 ../js/ui/userMenu.js:805
msgid "Lock" msgid "Lock"
msgstr "Bloquear" msgstr "Bloquear"
#: ../js/ui/screenShield.js:641 #: ../js/ui/screenShield.js:639
msgid "GNOME needs to lock the screen" msgid "GNOME needs to lock the screen"
msgstr "GNOME precisa bloquear a pantalla" msgstr "GNOME debe bloquear a pantalla"
#. We could not become modal, so we can't activate the #. We could not become modal, so we can't activate the
#. screenshield. The user is probably very upset at this #. screenshield. The user is probably very upset at this
@ -1322,19 +1326,22 @@ msgstr "GNOME precisa bloquear a pantalla"
#. #.
#. XXX: another option is to kick the user into the gdm login #. XXX: another option is to kick the user into the gdm login
#. screen, where we're not affected by grabs #. screen, where we're not affected by grabs
#: ../js/ui/screenShield.js:762 ../js/ui/screenShield.js:1198 #: ../js/ui/screenShield.js:758 ../js/ui/screenShield.js:1169
#| msgid "Unable to connect to %s"
msgid "Unable to lock" msgid "Unable to lock"
msgstr "Non foi posíbel bloquear" msgstr "Non foi posíbel bloquear"
#: ../js/ui/screenShield.js:763 ../js/ui/screenShield.js:1199 #: ../js/ui/screenShield.js:759 ../js/ui/screenShield.js:1170
#| msgid "No such application"
msgid "Lock was blocked by an application" msgid "Lock was blocked by an application"
msgstr "Un aplicativo impediu o bloqueo" msgstr "O bloqueo foi impedido por un aplicativo"
#: ../js/ui/searchDisplay.js:453 #: ../js/ui/searchDisplay.js:431
#| msgid "Searching..."
msgid "Searching…" msgid "Searching…"
msgstr "Buscando…" msgstr "Buscando…"
#: ../js/ui/searchDisplay.js:497 #: ../js/ui/searchDisplay.js:475
msgid "No results." msgid "No results."
msgstr "Sen resultados." msgstr "Sen resultados."
@ -1346,11 +1353,11 @@ msgstr "Copiar"
msgid "Paste" msgid "Paste"
msgstr "Pegar" msgstr "Pegar"
#: ../js/ui/shellEntry.js:101 #: ../js/ui/shellEntry.js:105
msgid "Show Text" msgid "Show Text"
msgstr "Mostrar texto" msgstr "Mostrar texto"
#: ../js/ui/shellEntry.js:103 #: ../js/ui/shellEntry.js:107
msgid "Hide Text" msgid "Hide Text"
msgstr "Ocultar texto" msgstr "Ocultar texto"
@ -1360,9 +1367,9 @@ msgstr "Contrasinal"
#: ../js/ui/shellMountOperation.js:391 #: ../js/ui/shellMountOperation.js:391
msgid "Remember Password" msgid "Remember Password"
msgstr "Lembrar contrasinal" msgstr "Lembrar o contrasinal"
#: ../js/ui/shellMountOperation.js:403 ../js/ui/unlockDialog.js:114 #: ../js/ui/shellMountOperation.js:403 ../js/ui/unlockDialog.js:140
msgid "Unlock" msgid "Unlock"
msgstr "Desbloquear" msgstr "Desbloquear"
@ -1426,10 +1433,12 @@ msgid "Visibility"
msgstr "Visibilidade" msgstr "Visibilidade"
#: ../js/ui/status/bluetooth.js:59 #: ../js/ui/status/bluetooth.js:59
#| msgid "Send Files to Device..."
msgid "Send Files to Device…" msgid "Send Files to Device…"
msgstr "Enviar ficheiros ao dispositivo…" msgstr "Enviar ficheiros ao dispositivo…"
#: ../js/ui/status/bluetooth.js:60 #: ../js/ui/status/bluetooth.js:60
#| msgid "Set Up a New Device..."
msgid "Set Up a New Device…" msgid "Set Up a New Device…"
msgstr "Configurar un dispositivo novo…" msgstr "Configurar un dispositivo novo…"
@ -1456,6 +1465,7 @@ msgid "connecting..."
msgstr "conectando…" msgstr "conectando…"
#: ../js/ui/status/bluetooth.js:239 #: ../js/ui/status/bluetooth.js:239
#| msgid "Send Files..."
msgid "Send Files…" msgid "Send Files…"
msgstr "Enviar ficheiros…" msgstr "Enviar ficheiros…"
@ -1537,7 +1547,7 @@ msgstr "Mostrar a distribución do teclado"
#: ../js/ui/status/keyboard.js:373 #: ../js/ui/status/keyboard.js:373
msgid "Region & Language Settings" msgid "Region & Language Settings"
msgstr "Preferencias de rexión e idioma" msgstr "Configuración rexional e de idioma"
#: ../js/ui/status/lockScreenMenu.js:43 #: ../js/ui/status/lockScreenMenu.js:43
msgid "Volume, network, battery" msgid "Volume, network, battery"
@ -1582,7 +1592,7 @@ msgstr "non dispoñíbel"
#: ../js/ui/status/network.js:493 ../js/ui/status/network.js:1551 #: ../js/ui/status/network.js:493 ../js/ui/status/network.js:1551
msgid "connection failed" msgid "connection failed"
msgstr "conexión fallada" msgstr "conexión fallida"
#: ../js/ui/status/network.js:552 ../js/ui/status/network.js:1435 #: ../js/ui/status/network.js:552 ../js/ui/status/network.js:1435
#: ../js/ui/status/network.js:1627 #: ../js/ui/status/network.js:1627
@ -1668,6 +1678,7 @@ msgstr "Preferencias de enerxía"
#. 0 is reported when UPower does not have enough data #. 0 is reported when UPower does not have enough data
#. to estimate battery life #. to estimate battery life
#: ../js/ui/status/power.js:99 #: ../js/ui/status/power.js:99
#| msgid "Estimating..."
msgid "Estimating…" msgid "Estimating…"
msgstr "Estimando…" msgstr "Estimando…"
@ -1767,59 +1778,59 @@ msgstr "Volume"
msgid "Microphone" msgid "Microphone"
msgstr "Micrófono" msgstr "Micrófono"
#: ../js/ui/unlockDialog.js:125 #: ../js/ui/unlockDialog.js:151
msgid "Log in as another user" msgid "Log in as another user"
msgstr "Iniciar sesión como outro usuario" msgstr "Iniciar sesión como outro usuario"
#: ../js/ui/unlockDialog.js:146 #: ../js/ui/unlockDialog.js:177
msgid "Unlock Window" msgid "Unlock Window"
msgstr "Desbloquear xanela" msgstr "Desbloquear xanela"
#: ../js/ui/userMenu.js:193 #: ../js/ui/userMenu.js:192
msgid "Available" msgid "Available"
msgstr "Dispoñíbel" msgstr "Dispoñíbel"
#: ../js/ui/userMenu.js:196 #: ../js/ui/userMenu.js:195
msgid "Busy" msgid "Busy"
msgstr "Ocupado" msgstr "Ocupado"
#: ../js/ui/userMenu.js:199 #: ../js/ui/userMenu.js:198
msgid "Invisible" msgid "Invisible"
msgstr "Invisíbel" msgstr "Invisíbel"
#: ../js/ui/userMenu.js:202 #: ../js/ui/userMenu.js:201
msgid "Away" msgid "Away"
msgstr "Ausente" msgstr "Ausente"
#: ../js/ui/userMenu.js:205 #: ../js/ui/userMenu.js:204
msgid "Idle" msgid "Idle"
msgstr "Inactivo" msgstr "Inactivo"
#: ../js/ui/userMenu.js:208 #: ../js/ui/userMenu.js:207
msgid "Offline" msgid "Offline"
msgstr "Desconectado" msgstr "Desconectado"
#: ../js/ui/userMenu.js:781 #: ../js/ui/userMenu.js:779
msgid "Notifications" msgid "Notifications"
msgstr "Notificacións" msgstr "Notificacións"
#: ../js/ui/userMenu.js:797 #: ../js/ui/userMenu.js:795
msgid "Switch User" msgid "Switch User"
msgstr "Cambiar de usuario" msgstr "Cambiar de usuario"
#: ../js/ui/userMenu.js:802 #: ../js/ui/userMenu.js:800
msgid "Log Out" msgid "Log Out"
msgstr "Saír da sesión" msgstr "Saír da sesión"
#: ../js/ui/userMenu.js:822 #: ../js/ui/userMenu.js:820
msgid "Install Updates & Restart" msgid "Install Updates & Restart"
msgstr "Instalar actualizacións e reiniciar" msgstr "Instalar actualizacións e reiniciar"
#: ../js/ui/userMenu.js:840 #: ../js/ui/userMenu.js:838
msgid "Your chat status will be set to busy" msgid "Your chat status will be set to busy"
msgstr "O seu estado de conversa estabelecerase a «ocupado»" msgstr "O seu estado de conversa definirase como «ocupado»"
#: ../js/ui/userMenu.js:841 #: ../js/ui/userMenu.js:839
msgid "" msgid ""
"Notifications are now disabled, including chat messages. Your online status " "Notifications are now disabled, including chat messages. Your online status "
"has been adjusted to let others know that you might not see their messages." "has been adjusted to let others know that you might not see their messages."
@ -1828,35 +1839,33 @@ msgstr ""
"conversa. O seu estado de conexión axustouse para que outros saiban que non " "conversa. O seu estado de conexión axustouse para que outros saiban que non "
"quere ver as súas mensaxes." "quere ver as súas mensaxes."
#: ../js/ui/userMenu.js:888 #: ../js/ui/userMenu.js:885
msgid "Other users are logged in." msgid "Other users are logged in."
msgstr "Hai outros usuarios conectados." msgstr "Hai outros usuarios conectados."
#: ../js/ui/userMenu.js:893 #: ../js/ui/userMenu.js:890
msgid "Shutting down might cause them to lose unsaved work." msgid "Shutting down might cause them to lose unsaved work."
msgstr "Se apaga o computador pode perder o traballo que non gardou." msgstr "Se apaga o computador pode perder o traballo que non gardou."
#. Translators: Remote here refers to a remote session, like a ssh login #: ../js/ui/userMenu.js:916
#: ../js/ui/userMenu.js:921
#, c-format #, c-format
msgid "%s (remote)" msgid "%s (remote)"
msgstr "%s (remoto)" msgstr "%s (remoto)"
#. Translators: Console here refers to a tty like a VT console #: ../js/ui/userMenu.js:918
#: ../js/ui/userMenu.js:924
#, c-format #, c-format
msgid "%s (console)" msgid "%s (console)"
msgstr "%s (consola)" msgstr "%s (consola)"
#: ../js/ui/viewSelector.js:100 #: ../js/ui/viewSelector.js:101
msgid "Applications" msgid "Applications"
msgstr "Aplicativos" msgstr "Aplicativos"
#: ../js/ui/viewSelector.js:104 #: ../js/ui/viewSelector.js:105
msgid "Search" msgid "Search"
msgstr "Buscar" msgstr "Buscar"
#: ../js/ui/wanda.js:77 #: ../js/ui/wanda.js:92
#, c-format #, c-format
msgid "" msgid ""
"Sorry, no wisdom for you today:\n" "Sorry, no wisdom for you today:\n"
@ -1865,7 +1874,7 @@ msgstr ""
"Hoxe non ten ningunha mensaxe:\n" "Hoxe non ten ningunha mensaxe:\n"
"%s" "%s"
#: ../js/ui/wanda.js:81 #: ../js/ui/wanda.js:96
#, c-format #, c-format
msgid "%s the Oracle says" msgid "%s the Oracle says"
msgstr "%s o oráculo dí" msgstr "%s o oráculo dí"

1950
po/ia.po

File diff suppressed because it is too large Load Diff

View File

@ -461,7 +461,7 @@ msgstr "Nepavyko įvykdyti „%s“:"
#: ../js/ui/appDisplay.js:349 #: ../js/ui/appDisplay.js:349
msgid "Frequent" msgid "Frequent"
msgstr "Dažnai naudojamos" msgstr "Dažniausios"
#: ../js/ui/appDisplay.js:356 #: ../js/ui/appDisplay.js:356
msgid "All" msgid "All"
@ -1262,7 +1262,7 @@ msgstr "Apžvalga"
#. characters. #. characters.
#: ../js/ui/overview.js:271 #: ../js/ui/overview.js:271
msgid "Type to search…" msgid "Type to search…"
msgstr "Rašykite, ko ieškote…" msgstr "Rašykite ko ieškote…"
#: ../js/ui/panel.js:612 #: ../js/ui/panel.js:612
msgid "Quit" msgid "Quit"
@ -1299,7 +1299,7 @@ msgstr "Užverti"
#. long format #. long format
#: ../js/ui/screenShield.js:86 #: ../js/ui/screenShield.js:86
msgid "%A, %B %d" msgid "%A, %B %d"
msgstr "%A, %B %d d." msgstr "%A, %B %d"
#: ../js/ui/screenShield.js:151 #: ../js/ui/screenShield.js:151
#, c-format #, c-format

320
po/ml.po
View File

@ -10,9 +10,9 @@ msgstr ""
"Project-Id-Version: gnome-shell master\n" "Project-Id-Version: gnome-shell master\n"
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-" "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-"
"shell&keywords=I18N+L10N&component=general\n" "shell&keywords=I18N+L10N&component=general\n"
"POT-Creation-Date: 2013-04-24 18:23+0000\n" "POT-Creation-Date: 2013-03-23 11:49+0000\n"
"PO-Revision-Date: 2013-04-25 00:32+0530\n" "PO-Revision-Date: 2013-03-25 14:57+0530\n"
"Last-Translator: Balasankar C <c.balasankar@gmail.com>\n" "Last-Translator: Ani Peter <peter.ani@gmail.com>\n"
"Language-Team: American English <kde-i18n-doc@kde.org>\n" "Language-Team: American English <kde-i18n-doc@kde.org>\n"
"Language: ml\n" "Language: ml\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
@ -44,14 +44,10 @@ msgid "Focus the active notification"
msgstr "സജീവമായ അറിയിപ്പിനെ കേന്ദ്രീകരിക്കുക" msgstr "സജീവമായ അറിയിപ്പിനെ കേന്ദ്രീകരിക്കുക"
#: ../data/50-gnome-shell-system.xml.in.h:4 #: ../data/50-gnome-shell-system.xml.in.h:4
msgid "Show the overview"
msgstr "പൊതുവായ അവലോകനം കാണിക്കുക"
#: ../data/50-gnome-shell-system.xml.in.h:5
msgid "Show all applications" msgid "Show all applications"
msgstr "എല്ലാ പ്രയോഗങ്ങളും കാണിയ്ക്കുക" msgstr "എല്ലാ പ്രയോഗങ്ങളും കാണിയ്ക്കുക"
#: ../data/50-gnome-shell-system.xml.in.h:6 #: ../data/50-gnome-shell-system.xml.in.h:5
msgid "Open the application menu" msgid "Open the application menu"
msgstr "പ്രയോഗത്തിന്റെ മെനു തുറക്കുക" msgstr "പ്രയോഗത്തിന്റെ മെനു തുറക്കുക"
@ -75,7 +71,8 @@ msgstr "ഗ്നോം ഷെല്‍ എക്സ്റ്റെന്‍ഷ
#: ../data/org.gnome.shell.gschema.xml.in.in.h:1 #: ../data/org.gnome.shell.gschema.xml.in.in.h:1
msgid "Enable internal tools useful for developers and testers from Alt-F2" msgid "Enable internal tools useful for developers and testers from Alt-F2"
msgstr "" msgstr ""
"Alt-F2-ല്‍ ഡവലപ്പര്‍മാര്‍ക്കും ടെസ്റ്റേര്‍സിനും പ്രയോജനകരമായ ആന്തരിക പ്രയോഗങ്ങള്‍ പ്രവര്‍ത്തന " "Alt-F2-ല്‍ ഡവലപ്പര്‍മാര്‍ക്കും ടെസ്റ്റേര്‍സിനും പ്രയോജനകരമായ ആന്തരിക "
"പ്രയോഗങ്ങള്‍ പ്രവര്‍ത്തന "
"സജ്ജമാക്കുന്നു" "സജ്ജമാക്കുന്നു"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:2 #: ../data/org.gnome.shell.gschema.xml.in.in.h:2
@ -83,7 +80,8 @@ msgid ""
"Allows access to internal debugging and monitoring tools using the Alt-F2 " "Allows access to internal debugging and monitoring tools using the Alt-F2 "
"dialog." "dialog."
msgstr "" msgstr ""
"Alt-F2 ഡയലോഗ് ഉപയോഗിച്ചു് ആന്തരിക ഡീബഗ്ഗിലേക്കും നീരീക്ഷണ പ്രയോഗങ്ങളിലേക്കും പ്രവേശനം " "Alt-F2 ഡയലോഗ് ഉപയോഗിച്ചു് ആന്തരിക ഡീബഗ്ഗിലേക്കും നീരീക്ഷണ പ്രയോഗങ്ങളിലേക്കും "
"പ്രവേശനം "
"അനുവദിയ്ക്കുക." "അനുവദിയ്ക്കുക."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:3 #: ../data/org.gnome.shell.gschema.xml.in.in.h:3
@ -97,14 +95,19 @@ msgid ""
"list. You can also manipulate this list with the EnableExtension and " "list. You can also manipulate this list with the EnableExtension and "
"DisableExtension DBus methods on org.gnome.Shell." "DisableExtension DBus methods on org.gnome.Shell."
msgstr "" msgstr ""
"ഗ്നോം ഷെല്‍ എക്സ്റ്റെന്‍ഷനുകള്‍ക്കു് ഒരു യുയുഐഡി വിശേഷതയുണ്ടു്; ലഭ്യമാക്കേണ്ട എക്സ്റ്റെന്‍ഷനുകള്‍ ഈ കീ പട്ടിക " "ഗ്നോം ഷെല്‍ എക്സ്റ്റെന്‍ഷനുകള്‍ക്കു് ഒരു യുയുഐഡി വിശേഷതയുണ്ടു്; ലഭ്യമാക്കേണ്ട "
"ലഭ്യമാക്കുന്നു. ലഭ്യമാക്കേണ്ട ഏതു് എക്സ്റ്റെന്‍ഷനും ഈ പട്ടികയിലുണ്ടാവണം. org.gnome.Shell-ല്‍ " "എക്സ്റ്റെന്‍ഷനുകള്‍ ഈ കീ പട്ടിക "
"നിങ്ങള്‍ക്കു് EnableExtension, DisableExtension എന്നീ ഡീബസ് രീതികളിലൂടെ ഈ പട്ടിക " "ലഭ്യമാക്കുന്നു. ലഭ്യമാക്കേണ്ട ഏതു് എക്സ്റ്റെന്‍ഷനും ഈ പട്ടികയിലുണ്ടാവണം. "
"org.gnome.Shell-ല്‍ "
"നിങ്ങള്‍ക്കു് EnableExtension, DisableExtension എന്നീ ഡീബസ് രീതികളിലൂടെ ഈ "
"പട്ടിക "
"കൈകാര്യം ചെയ്യുവാനും സാധിയ്ക്കുന്നു." "കൈകാര്യം ചെയ്യുവാനും സാധിയ്ക്കുന്നു."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:5 #: ../data/org.gnome.shell.gschema.xml.in.in.h:5
msgid "Whether to collect stats about applications usage" msgid "Whether to collect stats about applications usage"
msgstr "പ്രയോഗങ്ങളുടെ ഉപയോഗത്തെപ്പറ്റിയുള്ള സ്ഥിതിവിവരക്കണക്കുകള്‍ ശേഖരിയ്ക്കണമോ എന്നു്" msgstr ""
"പ്രയോഗങ്ങളുടെ ഉപയോഗത്തെപ്പറ്റിയുള്ള സ്ഥിതിവിവരക്കണക്കുകള്‍ ശേഖരിയ്ക്കണമോ "
"എന്നു്"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:6 #: ../data/org.gnome.shell.gschema.xml.in.in.h:6
msgid "" msgid ""
@ -113,9 +116,12 @@ msgid ""
"want to disable this for privacy reasons. Please note that doing so won't " "want to disable this for privacy reasons. Please note that doing so won't "
"remove already saved data." "remove already saved data."
msgstr "" msgstr ""
"ഏറ്റവും കൂടുതല്‍ തവണ ഉപയോഗിയ്ക്കുന്ന പ്രയോഗങ്ങള്‍ ലഭ്യമാക്കുന്നതിനായി ഷെല്‍ സാധാരണയായി സജീവമായ " "ഏറ്റവും കൂടുതല്‍ തവണ ഉപയോഗിയ്ക്കുന്ന പ്രയോഗങ്ങള്‍ ലഭ്യമാക്കുന്നതിനായി ഷെല്‍ "
"പ്രയോഗങ്ങളെ നിരീക്ഷിയ്ക്കുന്നു. (ഉദാഹരണത്തിനു്, ലോഞ്ചേര്‍സ്). ഈ ഡേറ്റാ സ്വകാര്യമായി " "സാധാരണയായി സജീവമായ "
"സൂക്ഷിയ്ക്കുന്നെങ്കിലും, ചില കാരണങ്ങളാല്‍ ഇതു് പ്രവര്‍ത്തന രഹിതമാക്കേണ്ടതുണ്ടു്. ഇങ്ങനെ ചെയ്യുന്നതു് " "പ്രയോഗങ്ങളെ നിരീക്ഷിയ്ക്കുന്നു. (ഉദാഹരണത്തിനു്, ലോഞ്ചേര്‍സ്). ഈ ഡേറ്റാ "
"സ്വകാര്യമായി "
"സൂക്ഷിയ്ക്കുന്നെങ്കിലും, ചില കാരണങ്ങളാല്‍ ഇതു് പ്രവര്‍ത്തന "
"രഹിതമാക്കേണ്ടതുണ്ടു്. ഇങ്ങനെ ചെയ്യുന്നതു് "
"നിങ്ങള്‍ സൂക്ഷിച്ച ഡേറ്റയെ ബാധിയ്ക്കുന്നതല്ല." "നിങ്ങള്‍ സൂക്ഷിച്ച ഡേറ്റയെ ബാധിയ്ക്കുന്നതല്ല."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:7 #: ../data/org.gnome.shell.gschema.xml.in.in.h:7
@ -126,7 +132,8 @@ msgstr "ഇഷ്ടമുള്ള പ്രയോഗങ്ങള്‍ക്
msgid "" msgid ""
"The applications corresponding to these identifiers will be displayed in the " "The applications corresponding to these identifiers will be displayed in the "
"favorites area." "favorites area."
msgstr "ഈ ഐഡന്റിഫയറുകള്‍ക്കുള്ള പ്രയോഗങ്ങള്‍ ഉചിതമായ സ്ഥലങ്ങളില്‍ കാണിയ്ക്കുന്നു." msgstr ""
"ഈ ഐഡന്റിഫയറുകള്‍ക്കുള്ള പ്രയോഗങ്ങള്‍ ഉചിതമായ സ്ഥലങ്ങളില്‍ കാണിയ്ക്കുന്നു."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:9 #: ../data/org.gnome.shell.gschema.xml.in.in.h:9
msgid "List of categories that should be displayed as folders" msgid "List of categories that should be displayed as folders"
@ -137,8 +144,8 @@ msgid ""
"Each category name in this list will be represented as folder in the " "Each category name in this list will be represented as folder in the "
"application view, rather than being displayed inline in the main view." "application view, rather than being displayed inline in the main view."
msgstr "" msgstr ""
"ഈ പട്ടികയിലുള്ള ഓരോ വിഭാഗത്തിന്റെ പേരും, പ്രധാന കാഴ്ചയില്‍ ഓരോ വരിയായി കാണിയ്ക്കുന്നതിനു് " "ഈ പട്ടികയിലുള്ള ഓരോ വിഭാഗത്തിന്റെ പേരും, പ്രധാന കാഴ്ചയില്‍ ഓരോ വരിയായി "
"പകരം പ്രയോഗങ്ങളുടെ കാഴ്ചയില്‍ ഫോള്‍ഡറായി കാണിയ്ക്കുന്നു. " "കാണിയ്ക്കുന്നതിനു് പകരം പ്രയോഗങ്ങളുടെ കാഴ്ചയില്‍ ഫോള്‍ഡറായി കാണിയ്ക്കുന്നു. "
#: ../data/org.gnome.shell.gschema.xml.in.in.h:11 #: ../data/org.gnome.shell.gschema.xml.in.in.h:11
msgid "History for command (Alt-F2) dialog" msgid "History for command (Alt-F2) dialog"
@ -153,7 +160,8 @@ msgid ""
"Internally used to store the last IM presence explicitly set by the user. " "Internally used to store the last IM presence explicitly set by the user. "
"The value here is from the TpConnectionPresenceType enumeration." "The value here is from the TpConnectionPresenceType enumeration."
msgstr "" msgstr ""
"ഉപയോക്താവു് സജ്ജമാക്കിയ അവസാന ഐഎം ആന്തരികമായി സൂക്ഷിയ്ക്കുന്നതിനു് ഉപയോഗിയ്ക്കുന്നു. മൂല്യം " "ഉപയോക്താവു് സജ്ജമാക്കിയ അവസാന ഐഎം ആന്തരികമായി സൂക്ഷിയ്ക്കുന്നതിനു് "
"ഉപയോഗിയ്ക്കുന്നു. മൂല്യം "
"TpConnectionPresenceType തരത്തിലുള്ളതാകുന്നു." "TpConnectionPresenceType തരത്തിലുള്ളതാകുന്നു."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:14 #: ../data/org.gnome.shell.gschema.xml.in.in.h:14
@ -161,7 +169,8 @@ msgid ""
"Internally used to store the last session presence status for the user. The " "Internally used to store the last session presence status for the user. The "
"value here is from the GsmPresenceStatus enumeration." "value here is from the GsmPresenceStatus enumeration."
msgstr "" msgstr ""
"ഉപയോക്താവിനുള്ള അവസാന സെഷന്‍ അവസ്ഥ ആന്തരികമായി സൂക്ഷിയ്ക്കുന്നതിനു് ഉപയോഗിയ്ക്കുന്നു. മൂല്യം " "ഉപയോക്താവിനുള്ള അവസാന സെഷന്‍ അവസ്ഥ ആന്തരികമായി സൂക്ഷിയ്ക്കുന്നതിനു് "
"ഉപയോഗിയ്ക്കുന്നു. മൂല്യം "
"GsmPresenceStatus തരത്തിലുള്ളതാകുന്നു." "GsmPresenceStatus തരത്തിലുള്ളതാകുന്നു."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:15 #: ../data/org.gnome.shell.gschema.xml.in.in.h:15
@ -173,13 +182,15 @@ msgid ""
"This key overrides the automatic hiding of the 'Log out' menuitem in single-" "This key overrides the automatic hiding of the 'Log out' menuitem in single-"
"user, single-session situations." "user, single-session situations."
msgstr "" msgstr ""
"സിംഗിള്‍ യൂസര്‍, സിംഗിള്‍ സെഷനില്‍ 'ലോഗൌട്ട്' മെനുവസ്തു അദൃശ്യമാക്കുന്നതിനായി ഈ കീ ഉപയോഗിയ്ക്കുന്നു" "സിംഗിള്‍ യൂസര്‍, സിംഗിള്‍ സെഷനില്‍ 'ലോഗൌട്ട്' മെനുവസ്തു അദൃശ്യമാക്കുന്നതിനായി "
"ഈ കീ ഉപയോഗിയ്ക്കുന്നു"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:17 #: ../data/org.gnome.shell.gschema.xml.in.in.h:17
msgid "" msgid ""
"Whether to remember password for mounting encrypted or remote filesystems" "Whether to remember password for mounting encrypted or remote filesystems"
msgstr "" msgstr ""
"എന്‍ക്രിപ്റ്റ് ചെയ്തതോ വിദൂരമോ ആയ ഫയല്‍സിസ്റ്റങ്ങള്‍ മൌണ്ട് ചെയ്യുമ്പോഴുള്ള രഹസ്യവാക്ക് ഓര്‍മ്മിക്കണോ എന്ന്" "എന്‍ക്രിപ്റ്റ് ചെയ്തതോ വിദൂരമോ ആയ ഫയല്‍സിസ്റ്റങ്ങള്‍ മൌണ്ട് ചെയ്യുമ്പോഴുള്ള "
"രഹസ്യവാക്ക് ഓര്‍മ്മിക്കണോ എന്ന്"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:18 #: ../data/org.gnome.shell.gschema.xml.in.in.h:18
msgid "" msgid ""
@ -188,9 +199,10 @@ msgid ""
"'Remember Password' checkbox will be present. This key sets the default " "'Remember Password' checkbox will be present. This key sets the default "
"state of the checkbox." "state of the checkbox."
msgstr "" msgstr ""
"ഒരു എന്‍ക്രിപ്റ്റ് ചെയ്ത ഡിവൈസ് അല്ലെങ്കില്‍ വിദൂര ഫയല്‍സിസ്റ്റം മൌണ്ട് ചെയ്യുമ്പോള്‍ ഷെല്‍ ഒരു രഹസ്യവാക്ക് " "ഒരു എന്‍ക്രിപ്റ്റ് ചെയ്ത ഡിവൈസ് അല്ലെങ്കില്‍ വിദൂര ഫയല്‍സിസ്റ്റം മൌണ്ട് "
"ആവശ്യപ്പെടുന്നു. രഹസ്യവാക്ക് സൂക്ഷിയ്ക്കുവാന്‍ സാധ്യമെങ്കില്‍, 'രഹസ്യവാക്ക് ഓര്‍ത്തു്വയ്ക്കുക' ചെക്ക്ബോക്സ് " "ചെയ്യുമ്പോള്‍ ഷെല്‍ ഒരു രഹസ്യവാക്ക് ആവശ്യപ്പെടുന്നു. രഹസ്യവാക്ക് "
"കാണാം. ഈ കീ ചെക്ക്ബോക്സിന്റെ സ്വതവേയുള്ള അവസ്ഥ സജ്ജമാക്കുന്നു." "സൂക്ഷിയ്ക്കുവാന്‍ സാധ്യമെങ്കില്‍, 'രഹസ്യവാക്ക് ഓര്‍ത്തു്വയ്ക്കുക' "
"ചെക്ക്ബോക്സ് കാണാം. ഈ കീ ചെക്ക്ബോക്സിന്റെ സ്വതവേയുള്ള അവസ്ഥ സജ്ജമാക്കുന്നു."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:19 #: ../data/org.gnome.shell.gschema.xml.in.in.h:19
msgid "Show the week date in the calendar" msgid "Show the week date in the calendar"
@ -216,65 +228,61 @@ msgstr "\"പ്രയോഗങ്ങള്‍ കാണിയ്ക്കുക
msgid "" msgid ""
"Keybinding to open the \"Show Applications\" view of the Activities Overview." "Keybinding to open the \"Show Applications\" view of the Activities Overview."
msgstr "" msgstr ""
"പ്രവര്‍ത്തികളുടെ അവലോകനത്തിന്റെ \"പ്രയോഗങ്ങള്‍ കാണിയ്ക്കുക\" എന്ന കാഴ്ച തുറക്കുന്നതിനുള്ള കീബൈന്‍ഡിങ്" "പ്രവര്‍ത്തികളുടെ അവലോകനത്തിന്റെ \"പ്രയോഗങ്ങള്‍ കാണിയ്ക്കുക\" എന്ന കാഴ്ച "
"തുറക്കുന്നതിനുള്ള കീബൈന്‍ഡിങ്"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:25 #: ../data/org.gnome.shell.gschema.xml.in.in.h:25
msgid "Keybinding to open the overview"
msgstr "പൊതുവായ അവലോകനം തുറക്കുന്നതിനുള്ള കീബൈന്‍ഡിങ്"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:26
msgid "Keybinding to open the Activities Overview."
msgstr "പ്രയോഗങ്ങളുടെ പൊതുവായ അവലോകനം എന്ന കാഴ്ച തുറക്കുന്നതിനുള്ള കീബൈന്‍ഡിങ്"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:27
msgid "Keybinding to toggle the visibility of the message tray" msgid "Keybinding to toggle the visibility of the message tray"
msgstr "സന്ദേശ ട്രേയുടെ ദൃശ്യത ടൊഗ്ഗിള്‍ ചെയ്യുന്നതിനുള്ള കീക്കൂട്ടം" msgstr "സന്ദേശ ട്രേയുടെ ദൃശ്യത ടൊഗ്ഗിള്‍ ചെയ്യുന്നതിനുള്ള കീക്കൂട്ടം"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:28 #: ../data/org.gnome.shell.gschema.xml.in.in.h:26
msgid "Keybinding to toggle the visibility of the message tray." msgid "Keybinding to toggle the visibility of the message tray."
msgstr "സന്ദേശ ട്രേയുടെ ദൃശ്യത ടൊഗ്ഗിള്‍ ചെയ്യുന്നതിനുള്ള കീക്കൂട്ടം." msgstr "സന്ദേശ ട്രേയുടെ ദൃശ്യത ടൊഗ്ഗിള്‍ ചെയ്യുന്നതിനുള്ള കീക്കൂട്ടം."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:29 #: ../data/org.gnome.shell.gschema.xml.in.in.h:27
msgid "Keybinding to focus the active notification" msgid "Keybinding to focus the active notification"
msgstr "സജീവമായ അറിയിപ്പിനുള്ള കീബൈന്‍ഡിങ്" msgstr "സജീവമായ അറിയിപ്പിനുള്ള കീബൈന്‍ഡിങ്"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:30 #: ../data/org.gnome.shell.gschema.xml.in.in.h:28
msgid "Keybinding to focus the active notification." msgid "Keybinding to focus the active notification."
msgstr "സജീവമായ അറിയിപ്പിനുള്ള കീബൈന്‍ഡിങ്." msgstr "സജീവമായ അറിയിപ്പിനുള്ള കീബൈന്‍ഡിങ്."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:31 #: ../data/org.gnome.shell.gschema.xml.in.in.h:29
msgid "Keybinding to toggle the screen recorder" msgid "Keybinding to toggle the screen recorder"
msgstr "സ്ക്രീന്‍ റിക്കോര്‍ഡര്‍ ടൊഗ്ഗിള്‍ ചെയ്യുന്നതിനുള്ള കീക്കൂട്ടം" msgstr "സ്ക്രീന്‍ റിക്കോര്‍ഡര്‍ ടൊഗ്ഗിള്‍ ചെയ്യുന്നതിനുള്ള കീക്കൂട്ടം"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:32 #: ../data/org.gnome.shell.gschema.xml.in.in.h:30
msgid "Keybinding to start/stop the builtin screen recorder." msgid "Keybinding to start/stop the builtin screen recorder."
msgstr "ബിള്‍ട്ടിന്‍ സ്ക്രീന്‍ റിക്കോര്‍ഡര്‍ തുടങ്ങുവാന്‍/നിര്‍ത്തുന്നതിനുള്ള കീക്കൂട്ടം." msgstr ""
"ബിള്‍ട്ടിന്‍ സ്ക്രീന്‍ റിക്കോര്‍ഡര്‍ തുടങ്ങുവാന്‍/നിര്‍ത്തുന്നതിനുള്ള "
"കീക്കൂട്ടം."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:33 #: ../data/org.gnome.shell.gschema.xml.in.in.h:31
msgid "Which keyboard to use" msgid "Which keyboard to use"
msgstr "ഏതു് കീബോര്‍ഡ് ഉപയോഗിയ്ക്കണം" msgstr "ഏതു് കീബോര്‍ഡ് ഉപയോഗിയ്ക്കണം"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:34 #: ../data/org.gnome.shell.gschema.xml.in.in.h:32
msgid "The type of keyboard to use." msgid "The type of keyboard to use."
msgstr "ഏതു് തരം കീബോര്‍ഡ് ഉപയോഗിയ്ക്കണം." msgstr "ഏതു് തരം കീബോര്‍ഡ് ഉപയോഗിയ്ക്കണം."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:35 #: ../data/org.gnome.shell.gschema.xml.in.in.h:33
msgid "Framerate used for recording screencasts." msgid "Framerate used for recording screencasts."
msgstr "സ്ക്രീന്‍കാസ്റ്റുകള്‍ റിക്കോര്‍ഡ് ചെയ്യുന്നതിനുള്ള ഫ്രെയിം റേറ്റ്." msgstr "സ്ക്രീന്‍കാസ്റ്റുകള്‍ റിക്കോര്‍ഡ് ചെയ്യുന്നതിനുള്ള ഫ്രെയിം റേറ്റ്."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:36 #: ../data/org.gnome.shell.gschema.xml.in.in.h:34
msgid "" msgid ""
"The framerate of the resulting screencast recordered by GNOME Shell's " "The framerate of the resulting screencast recordered by GNOME Shell's "
"screencast recorder in frames-per-second." "screencast recorder in frames-per-second."
msgstr "" msgstr ""
"ഗ്നോം ഷെല്ലിന്റെ സ്ക്രീന്‍കാസ്റ്റ് റിക്കോര്‍ഡര്‍ റീക്കോര്‍ഡ് ചെയ്തിട്ടുള്ള സ്ക്രീന്‍കാസ്റ്റിന്റെ " "ഗ്നോം ഷെല്ലിന്റെ സ്ക്രീന്‍കാസ്റ്റ് റിക്കോര്‍ഡര്‍ റീക്കോര്‍ഡ് ചെയ്തിട്ടുള്ള "
"സ്ക്രീന്‍കാസ്റ്റിന്റെ "
"ഫ്രെയിംറേറ്റ്, ഒരു സെക്കന്‍ഡില്‍ ഒരു ഫ്രെയിം." "ഫ്രെയിംറേറ്റ്, ഒരു സെക്കന്‍ഡില്‍ ഒരു ഫ്രെയിം."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:37 #: ../data/org.gnome.shell.gschema.xml.in.in.h:35
msgid "The gstreamer pipeline used to encode the screencast" msgid "The gstreamer pipeline used to encode the screencast"
msgstr "സ്ക്രീന്‍കാസ്റ്റ് എന്‍കോഡ് ചെയ്യുന്നതിനുള്ള gstreamer പൈപ്പ്‌ലൈന്‍" msgstr "സ്ക്രീന്‍കാസ്റ്റ് എന്‍കോഡ് ചെയ്യുന്നതിനുള്ള gstreamer പൈപ്പ്‌ലൈന്‍"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:39 #: ../data/org.gnome.shell.gschema.xml.in.in.h:37
#, no-c-format #, no-c-format
msgid "" msgid ""
"Sets the GStreamer pipeline used to encode recordings. It follows the syntax " "Sets the GStreamer pipeline used to encode recordings. It follows the syntax "
@ -288,68 +296,78 @@ msgid ""
"threads=%T ! queue ! webmmux' and records to WEBM using the VP8 codec. %T is " "threads=%T ! queue ! webmmux' and records to WEBM using the VP8 codec. %T is "
"used as a placeholder for a guess at the optimal thread count on the system." "used as a placeholder for a guess at the optimal thread count on the system."
msgstr "" msgstr ""
"റിക്കോര്‍ഡിങുകള്‍ എന്‍കോഡ് ചെയ്യുന്നതിനായി GStreamer പൈപ്പ് ലൈന്‍ ഉപയോഗിയ്ക്കുന്നു. gst-launch-" "റിക്കോര്‍ഡിങുകള്‍ എന്‍കോഡ് ചെയ്യുന്നതിനായി GStreamer പൈപ്പ് ലൈന്‍ "
"നുള്ള സിന്റാക്സ് ഉപയോഗിയ്ക്കുന്നു. കാലിയായി സജ്ജമാക്കുമ്പോള്‍ കാലിയാകുന്നു.ഇതു് നിലവില്‍ 'vp8enc " "ഉപയോഗിയ്ക്കുന്നു. gst-launch-"
"നുള്ള സിന്റാക്സ് ഉപയോഗിയ്ക്കുന്നു. കാലിയായി സജ്ജമാക്കുമ്പോള്‍ "
"കാലിയാകുന്നു.ഇതു് നിലവില്‍ 'vp8enc "
"min_quantizer=13 max_quantizer=13 cpu-used=5 deadline=1000000 threads=%T ! " "min_quantizer=13 max_quantizer=13 cpu-used=5 deadline=1000000 threads=%T ! "
"queue ! webmmux' ആകുന്നുസ WEBM VP8 കോഡ് ഉപയോഗിച്ചു് റിക്കോര്‍ഡ് ചെയ്യുന്നു." "queue ! webmmux' ആകുന്നുസ WEBM VP8 കോഡ് ഉപയോഗിച്ചു് റിക്കോര്‍ഡ് ചെയ്യുന്നു."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:40 #: ../data/org.gnome.shell.gschema.xml.in.in.h:38
msgid "File extension used for storing the screencast" msgid "File extension used for storing the screencast"
msgstr "സ്ക്രീന്‍കാസ്റ്റ് സൂക്ഷിയ്ക്കുന്നതിനുള്ള ഫയല്‍ എക്സ്റ്റെന്‍ഷന്‍" msgstr "സ്ക്രീന്‍കാസ്റ്റ് സൂക്ഷിയ്ക്കുന്നതിനുള്ള ഫയല്‍ എക്സ്റ്റെന്‍ഷന്‍"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:41 #: ../data/org.gnome.shell.gschema.xml.in.in.h:39
msgid "" msgid ""
"The filename for recorded screencasts will be a unique filename based on the " "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 " "current date, and use this extension. It should be changed when recording to "
"a different container format." "a different container format."
msgstr "" msgstr ""
"റിക്കോര്‍ഡ് ചെയ്ത സ്ക്രീന്‍കാസ്റ്റുകള്‍ക്കുള്ള ഫയല്‍നാമം നിലവിലുള്ള തീയതി, എക്സ്റ്റെന്‍ഷന്‍ എന്നിവ " "റിക്കോര്‍ഡ് ചെയ്ത സ്ക്രീന്‍കാസ്റ്റുകള്‍ക്കുള്ള ഫയല്‍നാമം നിലവിലുള്ള തീയതി, "
"അനുസരിച്ചാകുന്നു. മറ്റൊരു ശൈലിയിലേക്കു് റിക്കോര്‍ഡ് ചെയ്യുമ്പോള്‍ ഇതു് മാറ്റണം." "എക്സ്റ്റെന്‍ഷന്‍ എന്നിവ "
"അനുസരിച്ചാകുന്നു. മറ്റൊരു ശൈലിയിലേക്കു് റിക്കോര്‍ഡ് ചെയ്യുമ്പോള്‍ ഇതു് "
"മാറ്റണം."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:42 #: ../data/org.gnome.shell.gschema.xml.in.in.h:40
msgid "The application icon mode." msgid "The application icon mode."
msgstr "പ്രയോഗത്തിന്റെ ഐക്കണ്‍ മോഡ്." msgstr "പ്രയോഗത്തിന്റെ ഐക്കണ്‍ മോഡ്."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:43 #: ../data/org.gnome.shell.gschema.xml.in.in.h:41
msgid "" msgid ""
"Configures how the windows are shown in the switcher. Valid possibilities " "Configures how the windows are shown in the switcher. Valid possibilities "
"are 'thumbnail-only' (shows a thumbnail of the window), 'app-icon-" "are 'thumbnail-only' (shows a thumbnail of the window), 'app-icon-"
"only' (shows only the application icon) or 'both'." "only' (shows only the application icon) or 'both'."
msgstr "" msgstr ""
"സ്വിച്ചറില്‍ ജാലകങ്ങള്‍ എങ്ങനെ കാണിയ്ക്കുന്നു എന്നു് ക്രമീകരിയ്ക്കുന്നു. ശരിയായ സാധ്യതകള്‍: " "സ്വിച്ചറില്‍ ജാലകങ്ങള്‍ എങ്ങനെ കാണിയ്ക്കുന്നു എന്നു് ക്രമീകരിയ്ക്കുന്നു. "
"'thumbnail-only' (ജാലകത്തിന്റെ പ്രതിരൂപം കാണിയ്ക്കുന്നു), 'app-icon-" "ശരിയായ "
"സാധ്യതകള്‍: 'thumbnail-only' (ജാലകത്തിന്റെ പ്രതിരൂപം കാണിയ്ക്കുന്നു), "
"'app-icon-"
"only' (പ്രയോഗത്തിന്റെ പ്രതിരൂപം കാണിയ്ക്കുന്നു) അല്ലെങ്കില്‍ 'both'." "only' (പ്രയോഗത്തിന്റെ പ്രതിരൂപം കാണിയ്ക്കുന്നു) അല്ലെങ്കില്‍ 'both'."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:44 #: ../data/org.gnome.shell.gschema.xml.in.in.h:42
msgid "Attach modal dialog to the parent window" msgid "Attach modal dialog to the parent window"
msgstr "പേരന്റ് ജാലകത്തിലേക്കു് ഡയലോഗ് ചേര്‍ക്കുക" msgstr "പേരന്റ് ജാലകത്തിലേക്കു് ഡയലോഗ് ചേര്‍ക്കുക"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:45 #: ../data/org.gnome.shell.gschema.xml.in.in.h:43
msgid "" msgid ""
"This key overrides the key in org.gnome.mutter when running GNOME Shell." "This key overrides the key in org.gnome.mutter when running GNOME Shell."
msgstr "ഗ്നോം ഷെല്‍ പ്രവര്‍ത്തിയ്ക്കുമ്പോള്‍ org.gnome.mutter-ലുള്ള കീ ഈ കീ തിരുത്തിയെഴുതുന്നു." msgstr ""
"ഗ്നോം ഷെല്‍ പ്രവര്‍ത്തിയ്ക്കുമ്പോള്‍ org.gnome.mutter-ലുള്ള കീ ഈ കീ "
"തിരുത്തിയെഴുതുന്നു."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:46 #: ../data/org.gnome.shell.gschema.xml.in.in.h:44
msgid "Arrangement of buttons on the titlebar" msgid "Arrangement of buttons on the titlebar"
msgstr "തലക്കെട്ടിനുള്ള ബാറില്‍ ബട്ടണുകളുടെ ക്രമീകരണം" msgstr "തലക്കെട്ടിനുള്ള ബാറില്‍ ബട്ടണുകളുടെ ക്രമീകരണം"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:47 #: ../data/org.gnome.shell.gschema.xml.in.in.h:45
msgid "" msgid ""
"This key overrides the key in org.gnome.desktop.wm.preferences when running " "This key overrides the key in org.gnome.desktop.wm.preferences when running "
"GNOME Shell." "GNOME Shell."
msgstr "" msgstr ""
"ഗ്നോം ഷെല്‍ പ്രവര്‍ത്തിയ്ക്കുമ്പോള്‍ org.gnome.desktop.wm.preferences-ലുള്ള കീ ഈ കീ " "ഗ്നോം ഷെല്‍ പ്രവര്‍ത്തിയ്ക്കുമ്പോള്‍ org.gnome.desktop.wm.preferences-ലുള്ള "
"തിരുത്തിയെഴുതുന്നു." "കീ ഈ കീ തിരുത്തിയെഴുതുന്നു."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:48 #: ../data/org.gnome.shell.gschema.xml.in.in.h:46
msgid "Enable edge tiling when dropping windows on screen edges" msgid "Enable edge tiling when dropping windows on screen edges"
msgstr "സ്ക്രീന്‍ കോണുകളില്‍ ജാലകങ്ങള്‍ എത്തിയ്ക്കുമ്പോള്‍ കോണ്‍ ചരിയ്ക്കുന്നതിനായി പ്രവര്‍ത്തന സജ്ജമാക്കുക" msgstr ""
"സ്ക്രീന്‍ കോണുകളില്‍ ജാലകങ്ങള്‍ എത്തിയ്ക്കുമ്പോള്‍ കോണ്‍ ചരിയ്ക്കുന്നതിനായി "
"പ്രവര്‍ത്തന സജ്ജമാക്കുക"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:49 #: ../data/org.gnome.shell.gschema.xml.in.in.h:47
msgid "Workspaces are managed dynamically" msgid "Workspaces are managed dynamically"
msgstr "പണിയിടങ്ങള്‍ ഡയനാമിക്കായി കൈകാര്യം ചെയ്തിരിക്കുന്നു" msgstr "പണിയിടങ്ങള്‍ ഡയനാമിക്കായി കൈകാര്യം ചെയ്തിരിക്കുന്നു"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:50 #: ../data/org.gnome.shell.gschema.xml.in.in.h:48
msgid "Workspaces only on primary monitor" msgid "Workspaces only on primary monitor"
msgstr "പ്രധാന മോണിറ്ററില്‍ മാത്രം പണിയിടങ്ങള്‍" msgstr "പ്രധാന മോണിറ്ററില്‍ മാത്രം പണിയിടങ്ങള്‍"
@ -364,9 +382,12 @@ msgstr "എക്സ്റ്റെന്‍ഷന്‍"
#: ../js/extensionPrefs/main.js:189 #: ../js/extensionPrefs/main.js:189
msgid "Select an extension to configure using the combobox above." msgid "Select an extension to configure using the combobox above."
msgstr "മുകളിലുള്ള കോമ്പോ ബോക്സ് ഉപയോഗിച്ചു് ക്രമീകരിയ്ക്കുന്നതിനുള്ളൊരു എക്സ്റ്റെന്‍ഷന്‍ തെര‍ഞ്ഞെടുക്കുക." msgstr ""
"മുകളിലുള്ള കോമ്പോ ബോക്സ് ഉപയോഗിച്ചു് ക്രമീകരിയ്ക്കുന്നതിനുള്ളൊരു "
"എക്സ്റ്റെന്‍ഷന്‍ തെര‍ഞ്ഞെടുക്കുക."
#: ../js/gdm/loginDialog.js:405 #: ../js/gdm/loginDialog.js:405
#| msgid "Session..."
msgid "Session…" msgid "Session…"
msgstr "പ്രവര്‍ത്തനവേള..." msgstr "പ്രവര്‍ത്തനവേള..."
@ -377,32 +398,32 @@ msgstr "പ്രവര്‍ത്തനവേള..."
msgid "Not listed?" msgid "Not listed?"
msgstr "ലഭ്യമല്ലേ?" msgstr "ലഭ്യമല്ലേ?"
#: ../js/gdm/loginDialog.js:787 ../js/ui/components/networkAgent.js:137 #: ../js/gdm/loginDialog.js:786 ../js/ui/components/networkAgent.js:137
#: ../js/ui/components/polkitAgent.js:162 ../js/ui/endSessionDialog.js:376 #: ../js/ui/components/polkitAgent.js:162 ../js/ui/endSessionDialog.js:375
#: ../js/ui/extensionDownloader.js:195 ../js/ui/shellMountOperation.js:399 #: ../js/ui/extensionDownloader.js:195 ../js/ui/shellMountOperation.js:399
#: ../js/ui/status/bluetooth.js:415 ../js/ui/unlockDialog.js:100 #: ../js/ui/status/bluetooth.js:415 ../js/ui/unlockDialog.js:99
#: ../js/ui/userMenu.js:938 #: ../js/ui/userMenu.js:938
msgid "Cancel" msgid "Cancel"
msgstr "വേണ്ട" msgstr "വേണ്ട"
#: ../js/gdm/loginDialog.js:803 #: ../js/gdm/loginDialog.js:802
msgctxt "button" msgctxt "button"
msgid "Sign In" msgid "Sign In"
msgstr "അകത്തുകയറുക" msgstr "അകത്തുകയറുക"
#: ../js/gdm/loginDialog.js:803 #: ../js/gdm/loginDialog.js:802
msgid "Next" msgid "Next"
msgstr "അടുത്തത്" msgstr "അടുത്തത്"
#. TTLS and PEAP are actually much more complicated, but this complication #. TTLS and PEAP are actually much more complicated, but this complication
#. is not visible here since we only care about phase2 authentication #. is not visible here since we only care about phase2 authentication
#. (and don't even care of which one) #. (and don't even care of which one)
#: ../js/gdm/loginDialog.js:918 ../js/ui/components/networkAgent.js:260 #: ../js/gdm/loginDialog.js:917 ../js/ui/components/networkAgent.js:260
#: ../js/ui/components/networkAgent.js:278 #: ../js/ui/components/networkAgent.js:278
msgid "Username: " msgid "Username: "
msgstr "ഉപയോക്തൃ നാമം: " msgstr "ഉപയോക്തൃ നാമം: "
#: ../js/gdm/loginDialog.js:1174 #: ../js/gdm/loginDialog.js:1173
msgid "Login Window" msgid "Login Window"
msgstr "പ്രവേശന ജാലകം" msgstr "പ്രവേശന ജാലകം"
@ -455,23 +476,23 @@ msgstr "ആജ്ഞ പ്രാവര്‍ത്തികമാക്കാ
msgid "Execution of '%s' failed:" msgid "Execution of '%s' failed:"
msgstr "'%s' നടപ്പിലാക്കുന്നതില്‍ പരാജയപ്പെട്ടു:" msgstr "'%s' നടപ്പിലാക്കുന്നതില്‍ പരാജയപ്പെട്ടു:"
#: ../js/ui/appDisplay.js:351 #: ../js/ui/appDisplay.js:349
msgid "Frequent" msgid "Frequent"
msgstr "ഇടയ്ക്കിടെ" msgstr "ഇടയ്ക്കിടെ"
#: ../js/ui/appDisplay.js:358 #: ../js/ui/appDisplay.js:356
msgid "All" msgid "All"
msgstr "എല്ലാം" msgstr "എല്ലാം"
#: ../js/ui/appDisplay.js:916 #: ../js/ui/appDisplay.js:914
msgid "New Window" msgid "New Window"
msgstr "പുതിയ വിന്‍ഡോ" msgstr "പുതിയ വിന്‍ഡോ"
#: ../js/ui/appDisplay.js:919 ../js/ui/dash.js:284 #: ../js/ui/appDisplay.js:917 ../js/ui/dash.js:284
msgid "Remove from Favorites" msgid "Remove from Favorites"
msgstr "ഇഷ്ടപ്പെട്ടവയില്‍ നിന്നും നീക്കം ചെയ്യുക" msgstr "ഇഷ്ടപ്പെട്ടവയില്‍ നിന്നും നീക്കം ചെയ്യുക"
#: ../js/ui/appDisplay.js:920 #: ../js/ui/appDisplay.js:918
msgid "Add to Favorites" msgid "Add to Favorites"
msgstr "ഇഷ്ടപ്പെട്ടവയിലേക്ക് ചേര്‍ക്കുക" msgstr "ഇഷ്ടപ്പെട്ടവയിലേക്ക് ചേര്‍ക്കുക"
@ -508,7 +529,7 @@ msgctxt "event list time"
msgid "%H\\u2236%M" msgid "%H\\u2236%M"
msgstr "%H\\u2236%M" msgstr "%H\\u2236%M"
#. Translators: Shown in calendar event list, if 12h format, #. Transators: Shown in calendar event list, if 12h format,
#. \u2236 is a ratio character, similar to : and \u2009 is #. \u2236 is a ratio character, similar to : and \u2009 is
#. a thin space #. a thin space
#: ../js/ui/calendar.js:77 #: ../js/ui/calendar.js:77
@ -711,7 +732,8 @@ msgid ""
"Passwords or encryption keys are required to access the wireless network " "Passwords or encryption keys are required to access the wireless network "
"'%s'." "'%s'."
msgstr "" msgstr ""
"വയര്‍ലെസ് നെറ്റ്‌വര്‍ക്ക് '%s'-ലേക്ക് പ്രവേശിക്കുന്നതിനായി രഹസ്യവാക്കുകള്‍ അല്ലെങ്കില്‍ എന്‍ക്രിപ്ഷന്‍ കീകള്‍ " "വയര്‍ലെസ് നെറ്റ്‌വര്‍ക്ക് '%s'-ലേക്ക് പ്രവേശിക്കുന്നതിനായി രഹസ്യവാക്കുകള്‍ "
"അല്ലെങ്കില്‍ എന്‍ക്രിപ്ഷന്‍ കീകള്‍ "
"ആവശ്യമുണ്ടു്." "ആവശ്യമുണ്ടു്."
#: ../js/ui/components/networkAgent.js:314 #: ../js/ui/components/networkAgent.js:314
@ -768,7 +790,7 @@ msgid "Sorry, that didn't work. Please try again."
msgstr "ക്ഷമിക്കണം, അതു ശരിയല്ല. ദയവായി വീണ്ടും ശ്രമിക്കുക." msgstr "ക്ഷമിക്കണം, അതു ശരിയല്ല. ദയവായി വീണ്ടും ശ്രമിക്കുക."
#. Translators: this is a filename used for screencast recording #. Translators: this is a filename used for screencast recording
#: ../js/ui/components/recorder.js:47 #: ../js/ui/components/recorder.js:48
#, no-c-format #, no-c-format
msgid "Screencast from %d %t" msgid "Screencast from %d %t"
msgstr "%d-ല്‍ നിന്നുള്ള സ്ക്രീന്‍കാസ്റ്റ്, %t-ല്‍" msgstr "%d-ല്‍ നിന്നുള്ള സ്ക്രീന്‍കാസ്റ്റ്, %t-ല്‍"
@ -891,7 +913,8 @@ msgstr "%s നിങ്ങള്‍ക്കു് %s അയച്ചിരി
#: ../js/ui/components/telepathyClient.js:1206 #: ../js/ui/components/telepathyClient.js:1206
#, c-format #, c-format
msgid "%s would like permission to see when you are online" msgid "%s would like permission to see when you are online"
msgstr "നിങ്ങള്‍ ഓണ്‍ലൈന്‍ ആകുമ്പോള്‍ കാണുന്നതിനുള്ള അനുമതി %s-നു് ആവശ്യമുണ്ടു്" msgstr ""
"നിങ്ങള്‍ ഓണ്‍ലൈന്‍ ആകുമ്പോള്‍ കാണുന്നതിനുള്ള അനുമതി %s-നു് ആവശ്യമുണ്ടു്"
#: ../js/ui/components/telepathyClient.js:1298 #: ../js/ui/components/telepathyClient.js:1298
msgid "Network error" msgid "Network error"
@ -964,7 +987,9 @@ msgstr "ഈ അക്കൌണ്ട് നിലവില്‍ സര്‍വ
#: ../js/ui/components/telepathyClient.js:1332 #: ../js/ui/components/telepathyClient.js:1332
msgid "" msgid ""
"Connection has been replaced by a new connection using the same resource" "Connection has been replaced by a new connection using the same resource"
msgstr "അതേ ശ്രോതസ്സ് ഉപയോഗിച്ചു് ഒരു പുതിയ കണക്ഷന്‍ ഉപയോഗിച്ചു് ഈ കണക്ഷന്‍ മാറ്റിസ്ഥാപിയ്ക്കുന്നു" msgstr ""
"അതേ ശ്രോതസ്സ് ഉപയോഗിച്ചു് ഒരു പുതിയ കണക്ഷന്‍ ഉപയോഗിച്ചു് ഈ കണക്ഷന്‍ "
"മാറ്റിസ്ഥാപിയ്ക്കുന്നു"
#: ../js/ui/components/telepathyClient.js:1334 #: ../js/ui/components/telepathyClient.js:1334
msgid "The account already exists on the server" msgid "The account already exists on the server"
@ -981,14 +1006,17 @@ msgstr "സമ്മതപത്രം വീണ്ടും ആവശ്യപ
#: ../js/ui/components/telepathyClient.js:1340 #: ../js/ui/components/telepathyClient.js:1340
msgid "" msgid ""
"Certificate uses an insecure cipher algorithm or is cryptographically weak" "Certificate uses an insecure cipher algorithm or is cryptographically weak"
msgstr "സമ്മതപത്രം സുരക്ഷിതമല്ലാത്തൊരു സിഫര്‍ ആല്‍ഗോരിഥം ഉപയോഗിയ്ക്കുന്നു അല്ലെങ്കില്‍ ഉചിതമല്ല" msgstr ""
"സമ്മതപത്രം സുരക്ഷിതമല്ലാത്തൊരു സിഫര്‍ ആല്‍ഗോരിഥം ഉപയോഗിയ്ക്കുന്നു "
"അല്ലെങ്കില്‍ ഉചിതമല്ല"
#: ../js/ui/components/telepathyClient.js:1342 #: ../js/ui/components/telepathyClient.js:1342
msgid "" msgid ""
"The length of the server certificate, or the depth of the server certificate " "The length of the server certificate, or the depth of the server certificate "
"chain, exceed the limits imposed by the cryptography library" "chain, exceed the limits imposed by the cryptography library"
msgstr "" msgstr ""
"സര്‍വറിന്റെ സമ്മതപത്രത്തിന്റെ വ്യാപ്തി, അല്ലെങ്കില്‍ സര്‍വര്‍ സമ്മതപത്ര ചെയിന്റെ വ്യാപ്തി, എന്നിവ " "സര്‍വറിന്റെ സമ്മതപത്രത്തിന്റെ വ്യാപ്തി, അല്ലെങ്കില്‍ സര്‍വര്‍ സമ്മതപത്ര "
"ചെയിന്റെ വ്യാപ്തി, എന്നിവ "
"പരിധിയില്‍ കൂടുന്നു" "പരിധിയില്‍ കൂടുന്നു"
#: ../js/ui/components/telepathyClient.js:1344 #: ../js/ui/components/telepathyClient.js:1344
@ -1057,7 +1085,8 @@ msgstr "പുറത്ത് കടക്കുക"
#: ../js/ui/endSessionDialog.js:65 #: ../js/ui/endSessionDialog.js:65
msgid "Click Log Out to quit these applications and log out of the system." msgid "Click Log Out to quit these applications and log out of the system."
msgstr "" msgstr ""
"ഈ പ്രയോഗങ്ങളില്‍ നിന്നും പുറത്തു് കടക്കുന്നതിനായി പുറത്തു കടക്കുക ക്ലിക്ക് ചെയ്തു് സിസ്റ്റത്തില്‍ നിന്നും " "ഈ പ്രയോഗങ്ങളില്‍ നിന്നും പുറത്തു് കടക്കുന്നതിനായി പുറത്തു കടക്കുക ക്ലിക്ക് "
"ചെയ്തു് സിസ്റ്റത്തില്‍ നിന്നും "
"പുറത്തു് കടക്കുക." "പുറത്തു് കടക്കുക."
#: ../js/ui/endSessionDialog.js:67 #: ../js/ui/endSessionDialog.js:67
@ -1091,7 +1120,8 @@ msgstr "നിര്‍ത്തുക"
#: ../js/ui/endSessionDialog.js:84 #: ../js/ui/endSessionDialog.js:84
msgid "Click Power Off to quit these applications and power off the system." msgid "Click Power Off to quit these applications and power off the system."
msgstr "" msgstr ""
"ഈ പ്രയോഗങ്ങളില്‍ നിന്നും പുറത്തു് കടക്കുന്നതിനായി പവര്‍ ഓഫ് ചെയ്യുക ക്ലിക്ക് ചെയ്തു സിസ്റ്റിന്റെ പവര്‍ " "ഈ പ്രയോഗങ്ങളില്‍ നിന്നും പുറത്തു് കടക്കുന്നതിനായി പവര്‍ ഓഫ് ചെയ്യുക ക്ലിക്ക് "
"ചെയ്തു സിസ്റ്റിന്റെ പവര്‍ "
"ഓഫ് ചെയ്യുക." "ഓഫ് ചെയ്യുക."
#: ../js/ui/endSessionDialog.js:86 #: ../js/ui/endSessionDialog.js:86
@ -1122,7 +1152,8 @@ msgstr "പുനരാരംഭിക്കുക"
#: ../js/ui/endSessionDialog.js:101 #: ../js/ui/endSessionDialog.js:101
msgid "Click Restart to quit these applications and restart the system." msgid "Click Restart to quit these applications and restart the system."
msgstr "ഈ പ്രയോഗങ്ങള്‍ നിറുത്തി സിസ്റ്റം പുനരാരംഭിക്കുവാന്‍ പുനരാരംഭിക്കൂ അമര്‍ത്തുക" msgstr ""
"ഈ പ്രയോഗങ്ങള്‍ നിറുത്തി സിസ്റ്റം പുനരാരംഭിക്കുവാന്‍ പുനരാരംഭിക്കൂ അമര്‍ത്തുക"
#: ../js/ui/endSessionDialog.js:103 #: ../js/ui/endSessionDialog.js:103
#, c-format #, c-format
@ -1142,7 +1173,9 @@ msgstr "ഇന്‍സ്റ്റോള്‍"
#: ../js/ui/extensionDownloader.js:204 #: ../js/ui/extensionDownloader.js:204
#, c-format #, c-format
msgid "Download and install '%s' from extensions.gnome.org?" msgid "Download and install '%s' from extensions.gnome.org?"
msgstr "extensions.gnome.org ഇല്‍ നിന്നും '%s' ഡൗണ്‍ലോട് ചെയ്ത് ഇന്‍സ്റ്റോള്‍ ചെയ്യേണമോ?" msgstr ""
"extensions.gnome.org ഇല്‍ നിന്നും '%s' ഡൗണ്‍ലോട് ചെയ്ത് ഇന്‍സ്റ്റോള്‍ "
"ചെയ്യേണമോ?"
#: ../js/ui/keyboard.js:619 ../js/ui/status/keyboard.js:314 #: ../js/ui/keyboard.js:619 ../js/ui/status/keyboard.js:314
#: ../js/ui/status/power.js:211 #: ../js/ui/status/power.js:211
@ -1171,9 +1204,7 @@ msgstr "പിശകുകള്‍ കാണിക്കുക"
msgid "Enabled" msgid "Enabled"
msgstr "പ്രവര്‍ത്തനക്ഷമമാക്കി" msgstr "പ്രവര്‍ത്തനക്ഷമമാക്കി"
#. translators: #: ../js/ui/lookingGlass.js:769
#. * The device has been disabled
#: ../js/ui/lookingGlass.js:769 ../src/gvc/gvc-mixer-control.c:1830
msgid "Disabled" msgid "Disabled"
msgstr "പ്രവര്‍ത്തനരഹിതമാക്കി" msgstr "പ്രവര്‍ത്തനരഹിതമാക്കി"
@ -1206,6 +1237,7 @@ msgid "Remove"
msgstr "നീക്കം ചെയ്യുക" msgstr "നീക്കം ചെയ്യുക"
#: ../js/ui/messageTray.js:1501 #: ../js/ui/messageTray.js:1501
#| msgid "No Messages"
msgid "Clear Messages" msgid "Clear Messages"
msgstr "സന്ദേശങ്ങള്‍ വെടിപ്പാക്കുക" msgstr "സന്ദേശങ്ങള്‍ വെടിപ്പാക്കുക"
@ -1213,35 +1245,35 @@ msgstr "സന്ദേശങ്ങള്‍ വെടിപ്പാക്ക
msgid "Notification Settings" msgid "Notification Settings"
msgstr "അറിയിപ്പു് ക്രമീകരണങ്ങള്‍" msgstr "അറിയിപ്പു് ക്രമീകരണങ്ങള്‍"
#: ../js/ui/messageTray.js:1710 #: ../js/ui/messageTray.js:1709
msgid "No Messages" msgid "No Messages"
msgstr "സന്ദേശങ്ങളില്ല" msgstr "സന്ദേശങ്ങളില്ല"
#: ../js/ui/messageTray.js:1783 #: ../js/ui/messageTray.js:1782
msgid "Message Tray" msgid "Message Tray"
msgstr "സന്ദേശത്തിന്റെ ട്രേ" msgstr "സന്ദേശത്തിന്റെ ട്രേ"
#: ../js/ui/messageTray.js:2801 #: ../js/ui/messageTray.js:2810
msgid "System Information" msgid "System Information"
msgstr "സിസ്റ്റത്തെക്കുറിച്ചുള്ള വിവരം" msgstr "സിസ്റ്റത്തെക്കുറിച്ചുള്ള വിവരം"
#: ../js/ui/notificationDaemon.js:629 ../src/shell-app.c:378 #: ../js/ui/notificationDaemon.js:629 ../src/shell-app.c:374
msgctxt "program" msgctxt "program"
msgid "Unknown" msgid "Unknown"
msgstr "അജ്ഞാതം" msgstr "അജ്ഞാതം"
#: ../js/ui/overviewControls.js:472 ../js/ui/screenShield.js:149 #: ../js/ui/overviewControls.js:463 ../js/ui/screenShield.js:149
#, c-format #, c-format
msgid "%d new message" msgid "%d new message"
msgid_plural "%d new messages" msgid_plural "%d new messages"
msgstr[0] "%d പുതിയ സന്ദേശം" msgstr[0] "%d പുതിയ സന്ദേശം"
msgstr[1] "%d പുതിയ സന്ദേശങ്ങള്‍" msgstr[1] "%d പുതിയ സന്ദേശങ്ങള്‍"
#: ../js/ui/overview.js:82 #: ../js/ui/overview.js:84
msgid "Undo" msgid "Undo"
msgstr "വേണ്ട" msgstr "വേണ്ട"
#: ../js/ui/overview.js:127 #: ../js/ui/overview.js:129
msgid "Overview" msgid "Overview"
msgstr "അവലോകനം" msgstr "അവലോകനം"
@ -1249,21 +1281,22 @@ msgstr "അവലോകനം"
#. in the search entry when no search is #. in the search entry when no search is
#. active; it should not exceed ~30 #. active; it should not exceed ~30
#. characters. #. characters.
#: ../js/ui/overview.js:260 #: ../js/ui/overview.js:271
#| msgid "Type to search..."
msgid "Type to search…" msgid "Type to search…"
msgstr "തെരയുന്നതിനായി ടൈപ്പ് ചെയ്യുക..." msgstr "തെരയുന്നതിനായി ടൈപ്പ് ചെയ്യുക..."
#: ../js/ui/panel.js:641 #: ../js/ui/panel.js:612
msgid "Quit" msgid "Quit"
msgstr "നിര്‍ത്തുക" msgstr "നിര്‍ത്തുക"
#. Translators: If there is no suitable word for "Activities" #. Translators: If there is no suitable word for "Activities"
#. in your language, you can use the word for "Overview". #. in your language, you can use the word for "Overview".
#: ../js/ui/panel.js:692 #: ../js/ui/panel.js:636
msgid "Activities" msgid "Activities"
msgstr "പ്രവര്‍ത്തനങ്ങള്‍" msgstr "പ്രവര്‍ത്തനങ്ങള്‍"
#: ../js/ui/panel.js:989 #: ../js/ui/panel.js:933
msgid "Top Bar" msgid "Top Bar"
msgstr "മുകളിലുള്ള ബാര്‍" msgstr "മുകളിലുള്ള ബാര്‍"
@ -1272,15 +1305,15 @@ msgstr "മുകളിലുള്ള ബാര്‍"
#. "ON" and "OFF") or "toggle-switch-intl" (for toggle #. "ON" and "OFF") or "toggle-switch-intl" (for toggle
#. switches containing "◯" and "|"). Other values will #. switches containing "◯" and "|"). Other values will
#. simply result in invisible toggle switches. #. simply result in invisible toggle switches.
#: ../js/ui/popupMenu.js:718 #: ../js/ui/popupMenu.js:727
msgid "toggle-switch-us" msgid "toggle-switch-us"
msgstr "toggle-switch-us" msgstr "toggle-switch-us"
#: ../js/ui/runDialog.js:74 #: ../js/ui/runDialog.js:73
msgid "Enter a Command" msgid "Enter a Command"
msgstr "ഒരു കമാന്‍ഡ് നല്‍കുക" msgstr "ഒരു കമാന്‍ഡ് നല്‍കുക"
#: ../js/ui/runDialog.js:110 #: ../js/ui/runDialog.js:109
msgid "Close" msgid "Close"
msgstr "അടക്കുക" msgstr "അടക്കുക"
@ -1301,7 +1334,7 @@ msgstr[1] "%d പുതിയ അറിയിപ്പുകള്‍"
msgid "Lock" msgid "Lock"
msgstr "പൂട്ടുക" msgstr "പൂട്ടുക"
#: ../js/ui/screenShield.js:641 #: ../js/ui/screenShield.js:637
msgid "GNOME needs to lock the screen" msgid "GNOME needs to lock the screen"
msgstr "ഗ്നോമിന് സ്ക്രീന്‍ പൂട്ടണം" msgstr "ഗ്നോമിന് സ്ക്രീന്‍ പൂട്ടണം"
@ -1312,15 +1345,17 @@ msgstr "ഗ്നോമിന് സ്ക്രീന്‍ പൂട്ടണ
#. #.
#. XXX: another option is to kick the user into the gdm login #. XXX: another option is to kick the user into the gdm login
#. screen, where we're not affected by grabs #. screen, where we're not affected by grabs
#: ../js/ui/screenShield.js:762 ../js/ui/screenShield.js:1198 #: ../js/ui/screenShield.js:758 ../js/ui/screenShield.js:1194
#| msgid "Unable to connect to %s"
msgid "Unable to lock" msgid "Unable to lock"
msgstr "പൂട്ടുവാന്‍ സാധ്യമല്ല" msgstr "പൂട്ടുവാന്‍ സാധ്യമല്ല"
#: ../js/ui/screenShield.js:763 ../js/ui/screenShield.js:1199 #: ../js/ui/screenShield.js:759 ../js/ui/screenShield.js:1195
msgid "Lock was blocked by an application" msgid "Lock was blocked by an application"
msgstr "പൂട്ടുന്ന സംവിധാനം ഒരു പ്രയോഗം തടസ്സപ്പെടുത്തിയിരിയ്ക്കുന്നു" msgstr "പൂട്ടുന്ന സംവിധാനം ഒരു പ്രയോഗം തടസ്സപ്പെടുത്തിയിരിയ്ക്കുന്നു"
#: ../js/ui/searchDisplay.js:453 #: ../js/ui/searchDisplay.js:453
#| msgid "Searching..."
msgid "Searching…" msgid "Searching…"
msgstr "തെരയുന്നു..." msgstr "തെരയുന്നു..."
@ -1336,11 +1371,11 @@ msgstr "പകര്‍ത്തുക"
msgid "Paste" msgid "Paste"
msgstr "ഒട്ടിയ്ക്കുക" msgstr "ഒട്ടിയ്ക്കുക"
#: ../js/ui/shellEntry.js:101 #: ../js/ui/shellEntry.js:106
msgid "Show Text" msgid "Show Text"
msgstr "പദാവലി കാണിക്കുക" msgstr "പദാവലി കാണിക്കുക"
#: ../js/ui/shellEntry.js:103 #: ../js/ui/shellEntry.js:108
msgid "Hide Text" msgid "Hide Text"
msgstr "പദാവലി മറക്കുക" msgstr "പദാവലി മറക്കുക"
@ -1352,7 +1387,7 @@ msgstr "രഹസ്യവാക്ക്"
msgid "Remember Password" msgid "Remember Password"
msgstr "രഹസ്യവാക്ക് ഓര്‍ത്തു് വയ്ക്കുക" msgstr "രഹസ്യവാക്ക് ഓര്‍ത്തു് വയ്ക്കുക"
#: ../js/ui/shellMountOperation.js:403 ../js/ui/unlockDialog.js:114 #: ../js/ui/shellMountOperation.js:403 ../js/ui/unlockDialog.js:113
msgid "Unlock" msgid "Unlock"
msgstr "പൂട്ട് തുറക്കുക" msgstr "പൂട്ട് തുറക്കുക"
@ -1416,10 +1451,12 @@ msgid "Visibility"
msgstr "കാഴ്ച" msgstr "കാഴ്ച"
#: ../js/ui/status/bluetooth.js:59 #: ../js/ui/status/bluetooth.js:59
#| msgid "Send Files to Device..."
msgid "Send Files to Device…" msgid "Send Files to Device…"
msgstr "ഡിവൈസിലേക്കു് ഫയലുകള്‍ അയയ്ക്കുക..." msgstr "ഡിവൈസിലേക്കു് ഫയലുകള്‍ അയയ്ക്കുക..."
#: ../js/ui/status/bluetooth.js:60 #: ../js/ui/status/bluetooth.js:60
#| msgid "Set Up a New Device..."
msgid "Set Up a New Device…" msgid "Set Up a New Device…"
msgstr "പുതിയൊരു ഡിവൈസ് സജ്ജമാക്കുക..." msgstr "പുതിയൊരു ഡിവൈസ് സജ്ജമാക്കുക..."
@ -1446,6 +1483,7 @@ msgid "connecting..."
msgstr "ബന്ധിപ്പിയ്ക്കുന്നു...." msgstr "ബന്ധിപ്പിയ്ക്കുന്നു...."
#: ../js/ui/status/bluetooth.js:239 #: ../js/ui/status/bluetooth.js:239
#| msgid "Send Files..."
msgid "Send Files…" msgid "Send Files…"
msgstr "ഫയലുകള്‍ അയയ്ക്കുക..." msgstr "ഫയലുകള്‍ അയയ്ക്കുക..."
@ -1658,6 +1696,7 @@ msgstr "ഊര്‍ജ്ജ ക്രമീകരണങ്ങള്‍"
#. 0 is reported when UPower does not have enough data #. 0 is reported when UPower does not have enough data
#. to estimate battery life #. to estimate battery life
#: ../js/ui/status/power.js:99 #: ../js/ui/status/power.js:99
#| msgid "Estimating..."
msgid "Estimating…" msgid "Estimating…"
msgstr "കണക്കുകൂട്ടുന്നു..." msgstr "കണക്കുകൂട്ടുന്നു..."
@ -1757,11 +1796,11 @@ msgstr "ഒച്ച"
msgid "Microphone" msgid "Microphone"
msgstr "മൈക്രോഫോണ്‍" msgstr "മൈക്രോഫോണ്‍"
#: ../js/ui/unlockDialog.js:125 #: ../js/ui/unlockDialog.js:124
msgid "Log in as another user" msgid "Log in as another user"
msgstr "മറ്റൊരു ഉപയോക്താവായി പ്രവേശിയ്ക്കുക" msgstr "മറ്റൊരു ഉപയോക്താവായി പ്രവേശിയ്ക്കുക"
#: ../js/ui/unlockDialog.js:146 #: ../js/ui/unlockDialog.js:145
msgid "Unlock Window" msgid "Unlock Window"
msgstr "ജാലകത്തിന്റെ പൂട്ടു തുറക്കുക" msgstr "ജാലകത്തിന്റെ പൂട്ടു തുറക്കുക"
@ -1814,8 +1853,10 @@ msgid ""
"Notifications are now disabled, including chat messages. Your online status " "Notifications are now disabled, including chat messages. Your online status "
"has been adjusted to let others know that you might not see their messages." "has been adjusted to let others know that you might not see their messages."
msgstr "" msgstr ""
"ചാറ്റ് സന്ദേശങ്ങള്‍ എന്ന പോലെ അറിയിപ്പുകള്‍ പ്രവര്‍ത്തന രഹിതമാക്കുന്നു. മറ്റുള്ളവരുടെ ചാറ്റ് സന്ദേശങ്ങള്‍ " "ചാറ്റ് സന്ദേശങ്ങള്‍ എന്ന പോലെ അറിയിപ്പുകള്‍ പ്രവര്‍ത്തന രഹിതമാക്കുന്നു. "
"നിങ്ങള്‍ക്കു് കാണുവാന്‍ സാധ്യമല്ല എന്നു് നിങ്ങളുടെ ഓണ്‍ലൈന്‍ അവസ്ഥയില്‍ വ്യക്തമാക്കുന്നു." "മറ്റുള്ളവരുടെ ചാറ്റ് സന്ദേശങ്ങള്‍ "
"നിങ്ങള്‍ക്കു് കാണുവാന്‍ സാധ്യമല്ല എന്നു് നിങ്ങളുടെ ഓണ്‍ലൈന്‍ അവസ്ഥയില്‍ "
"വ്യക്തമാക്കുന്നു."
#: ../js/ui/userMenu.js:888 #: ../js/ui/userMenu.js:888
msgid "Other users are logged in." msgid "Other users are logged in."
@ -1868,28 +1909,6 @@ msgstr "'%s' തയ്യാറാണ്"
msgid "Evolution Calendar" msgid "Evolution Calendar"
msgstr "ഇവല്യൂഷന്‍ കലണ്ടര്‍" msgstr "ഇവല്യൂഷന്‍ കലണ്ടര്‍"
#. translators:
#. * The number of sound outputs on a particular device
#: ../src/gvc/gvc-mixer-control.c:1837
#, c-format
msgid "%u Output"
msgid_plural "%u Outputs"
msgstr[0] "%u ഔട്ട്പുട്ട്"
msgstr[1] "%u ഔട്ട്പുട്ടുകള്‍"
#. translators:
#. * The number of sound inputs on a particular device
#: ../src/gvc/gvc-mixer-control.c:1847
#, c-format
msgid "%u Input"
msgid_plural "%u Inputs"
msgstr[0] "%u ഇന്‍പുട്ട്"
msgstr[1] "%u ഇന്‍പുട്ടുകള്‍"
#: ../src/gvc/gvc-mixer-control.c:2371
msgid "System Sounds"
msgstr "സിസ്റ്റം ശബ്ദങ്ങള്‍"
#: ../src/main.c:347 #: ../src/main.c:347
msgid "Print version" msgid "Print version"
msgstr "പ്രിന്റ് ചെയ്യുവാന്‍ സാധിയ്ക്കുന്ന പതിപ്പു്" msgstr "പ്രിന്റ് ചെയ്യുവാന്‍ സാധിയ്ക്കുന്ന പതിപ്പു്"
@ -1906,7 +1925,7 @@ msgstr "ഒരു പ്രത്യേക മോഡ് ഉപയോഗിയ്
msgid "List possible modes" msgid "List possible modes"
msgstr "സാധ്യമായ മോഡുകള്‍ ലഭ്യമാക്കുക" msgstr "സാധ്യമായ മോഡുകള്‍ ലഭ്യമാക്കുക"
#: ../src/shell-app.c:626 #: ../src/shell-app.c:622
#, c-format #, c-format
msgid "Failed to launch '%s'" msgid "Failed to launch '%s'"
msgstr "'%s' ലഭ്യമാക്കുന്നതില്‍ പരാജയം" msgstr "'%s' ലഭ്യമാക്കുന്നതില്‍ പരാജയം"
@ -1936,6 +1955,19 @@ msgstr "ഉപയോക്താവു് ആധികാരികത ഉറപ
#~ msgid "More..." #~ msgid "More..."
#~ msgstr "കൂടുതല്‍..." #~ msgstr "കൂടുതല്‍..."
#~ msgid "%u Output"
#~ msgid_plural "%u Outputs"
#~ msgstr[0] "%u ഔട്ട്പുട്ട്"
#~ msgstr[1] "%u ഔട്ട്പുട്ടുകള്‍"
#~ msgid "%u Input"
#~ msgid_plural "%u Inputs"
#~ msgstr[0] "%u ഇന്‍പുട്ട്"
#~ msgstr[1] "%u ഇന്‍പുട്ടുകള്‍"
#~ msgid "System Sounds"
#~ msgstr "സിസ്റ്റം ശബ്ദങ്ങള്‍"
#~ msgctxt "event list time" #~ msgctxt "event list time"
#~ msgid "%H:%M" #~ msgid "%H:%M"
#~ msgstr "%H:%M" #~ msgstr "%H:%M"

335
po/nb.po
View File

@ -6,10 +6,10 @@
# Torstein Adolf Winterseth <kvikende@fsfe.org>, 2010. # Torstein Adolf Winterseth <kvikende@fsfe.org>, 2010.
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: gnome-shell 3.9.x\n" "Project-Id-Version: gnome-shell 3.8.x\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-05-28 09:43+0200\n" "POT-Creation-Date: 2013-04-03 13:31+0200\n"
"PO-Revision-Date: 2013-05-28 09:44+0200\n" "PO-Revision-Date: 2013-04-03 13:31+0200\n"
"Last-Translator: Kjartan Maraas <kmaraas@gnome.org>\n" "Last-Translator: Kjartan Maraas <kmaraas@gnome.org>\n"
"Language-Team: Norwegian bokmål <i18n-nb@lister.ping.uio.no>\n" "Language-Team: Norwegian bokmål <i18n-nb@lister.ping.uio.no>\n"
"Language: \n" "Language: \n"
@ -39,14 +39,10 @@ msgid "Focus the active notification"
msgstr "Fokuser aktiv varsling" msgstr "Fokuser aktiv varsling"
#: ../data/50-gnome-shell-system.xml.in.h:4 #: ../data/50-gnome-shell-system.xml.in.h:4
msgid "Show the overview"
msgstr "Vis oversikt"
#: ../data/50-gnome-shell-system.xml.in.h:5
msgid "Show all applications" msgid "Show all applications"
msgstr "Vis alle programmer" msgstr "Vis alle programmer"
#: ../data/50-gnome-shell-system.xml.in.h:6 #: ../data/50-gnome-shell-system.xml.in.h:5
msgid "Open the application menu" msgid "Open the application menu"
msgstr "Åpne programmenyen" msgstr "Åpne programmenyen"
@ -96,10 +92,26 @@ msgstr ""
"EnablExtension og DisableExtension på org.gnome.Shell." "EnablExtension og DisableExtension på org.gnome.Shell."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:5 #: ../data/org.gnome.shell.gschema.xml.in.in.h:5
msgid "Whether to collect stats about applications usage"
msgstr "Om det skal samles statistikk om bruk av programmer"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:6
msgid ""
"The shell normally monitors active applications in order to present the most "
"used ones (e.g. in launchers). While this data will be kept private, you may "
"want to disable this for privacy reasons. Please note that doing so won't "
"remove already saved data."
msgstr ""
"GNOME Shell vil normalt holde øye med åpne programmer for å kunne vise de "
"mest bruke (for eksempel i oppstartsmenyer). Denne informasjonen vil bli "
"holdt privat, men du kan deaktivere denne lagringen av personvernårsaker. "
"Hvis du slår det av, vil det ikke fjerne allerede lagret informasjon."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:7
msgid "List of desktop file IDs for favorite applications" msgid "List of desktop file IDs for favorite applications"
msgstr "Liste av skrivebordfil-ider for favorittprogrammer" msgstr "Liste av skrivebordfil-ider for favorittprogrammer"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:6 #: ../data/org.gnome.shell.gschema.xml.in.in.h:8
msgid "" msgid ""
"The applications corresponding to these identifiers will be displayed in the " "The applications corresponding to these identifiers will be displayed in the "
"favorites area." "favorites area."
@ -107,52 +119,52 @@ msgstr ""
"Programmene som passer til disse identifikatorene vil bli vist i " "Programmene som passer til disse identifikatorene vil bli vist i "
"favorittområdet." "favorittområdet."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:7 #: ../data/org.gnome.shell.gschema.xml.in.in.h:9
msgid "List of categories that should be displayed as folders" msgid "List of categories that should be displayed as folders"
msgstr "Liste med kategorier som skal vises som mapper" msgstr "Liste med kategorier som skal vises som mapper"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:8 #: ../data/org.gnome.shell.gschema.xml.in.in.h:10
msgid "" msgid ""
"Each category name in this list will be represented as folder in the " "Each category name in this list will be represented as folder in the "
"application view, rather than being displayed inline in the main view." "application view, rather than being displayed inline in the main view."
msgstr "" msgstr ""
#: ../data/org.gnome.shell.gschema.xml.in.in.h:9 #: ../data/org.gnome.shell.gschema.xml.in.in.h:11
msgid "History for command (Alt-F2) dialog" msgid "History for command (Alt-F2) dialog"
msgstr "Historikk for kommandodialog (Alt-F2)" msgstr "Historikk for kommandodialog (Alt-F2)"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:10 #: ../data/org.gnome.shell.gschema.xml.in.in.h:12
msgid "History for the looking glass dialog" msgid "History for the looking glass dialog"
msgstr "Historikk for forstørrelsesglass-dialogen" msgstr "Historikk for forstørrelsesglass-dialogen"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:11 #: ../data/org.gnome.shell.gschema.xml.in.in.h:13
msgid "" msgid ""
"Internally used to store the last IM presence explicitly set by the user. " "Internally used to store the last IM presence explicitly set by the user. "
"The value here is from the TpConnectionPresenceType enumeration." "The value here is from the TpConnectionPresenceType enumeration."
msgstr "" msgstr ""
#: ../data/org.gnome.shell.gschema.xml.in.in.h:12 #: ../data/org.gnome.shell.gschema.xml.in.in.h:14
msgid "" msgid ""
"Internally used to store the last session presence status for the user. The " "Internally used to store the last session presence status for the user. The "
"value here is from the GsmPresenceStatus enumeration." "value here is from the GsmPresenceStatus enumeration."
msgstr "" msgstr ""
#: ../data/org.gnome.shell.gschema.xml.in.in.h:13 #: ../data/org.gnome.shell.gschema.xml.in.in.h:15
msgid "Always show the 'Log out' menuitem in the user menu." msgid "Always show the 'Log out' menuitem in the user menu."
msgstr "Alltid vis menyoppføringen «Logg ut» i brukermenyen." msgstr "Alltid vis menyoppføringen «Logg ut» i brukermenyen."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:14 #: ../data/org.gnome.shell.gschema.xml.in.in.h:16
msgid "" msgid ""
"This key overrides the automatic hiding of the 'Log out' menuitem in single-" "This key overrides the automatic hiding of the 'Log out' menuitem in single-"
"user, single-session situations." "user, single-session situations."
msgstr "" msgstr ""
#: ../data/org.gnome.shell.gschema.xml.in.in.h:15 #: ../data/org.gnome.shell.gschema.xml.in.in.h:17
msgid "" msgid ""
"Whether to remember password for mounting encrypted or remote filesystems" "Whether to remember password for mounting encrypted or remote filesystems"
msgstr "" msgstr ""
#: ../data/org.gnome.shell.gschema.xml.in.in.h:16 #: ../data/org.gnome.shell.gschema.xml.in.in.h:18
msgid "" msgid ""
"The shell will request a password when an encrypted device or a remote " "The shell will request a password when an encrypted device or a remote "
"filesystem is mounted. If the password can be saved for future use a " "filesystem is mounted. If the password can be saved for future use a "
@ -160,40 +172,32 @@ msgid ""
"state of the checkbox." "state of the checkbox."
msgstr "" msgstr ""
#: ../data/org.gnome.shell.gschema.xml.in.in.h:17 #: ../data/org.gnome.shell.gschema.xml.in.in.h:19
msgid "Show the week date in the calendar" msgid "Show the week date in the calendar"
msgstr "Vis dato for uken i kalender" msgstr "Vis dato for uken i kalender"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:18 #: ../data/org.gnome.shell.gschema.xml.in.in.h:20
msgid "If true, display the ISO week date in the calendar." msgid "If true, display the ISO week date in the calendar."
msgstr "Viser ISO-ukedato i kalenderen hvis «true»." msgstr "Viser ISO-ukedato i kalenderen hvis «true»."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:19 #: ../data/org.gnome.shell.gschema.xml.in.in.h:21
msgid "Keybinding to open the application menu" msgid "Keybinding to open the application menu"
msgstr "Tastaturbinding som åpner programmenyen" msgstr "Tastaturbinding som åpner programmenyen"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:20 #: ../data/org.gnome.shell.gschema.xml.in.in.h:22
msgid "Keybinding to open the application menu." msgid "Keybinding to open the application menu."
msgstr "Tastaturbinding som åpner programmenyen." msgstr "Tastaturbinding som åpner programmenyen."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:21 #: ../data/org.gnome.shell.gschema.xml.in.in.h:23
msgid "Keybinding to open the \"Show Applications\" view" msgid "Keybinding to open the \"Show Applications\" view"
msgstr "Tastaturbinding som åpner visningen «Vis programmer»" msgstr "Tastaturbinding som åpner visningen «Vis programmer»"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:22 #: ../data/org.gnome.shell.gschema.xml.in.in.h:24
msgid "" msgid ""
"Keybinding to open the \"Show Applications\" view of the Activities Overview." "Keybinding to open the \"Show Applications\" view of the Activities Overview."
msgstr "" msgstr ""
"Tastaturbinding som åpner visningen «Vis programmer» i aktivitetsoversikten." "Tastaturbinding som åpner visningen «Vis programmer» i aktivitetsoversikten."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:23
msgid "Keybinding to open the overview"
msgstr "Tastaturbinding som åpner oversikten"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:24
msgid "Keybinding to open the Activities Overview."
msgstr "Tastaturbinding som åpner aktivitetsoversikten."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:25 #: ../data/org.gnome.shell.gschema.xml.in.in.h:25
msgid "Keybinding to toggle the visibility of the message tray" msgid "Keybinding to toggle the visibility of the message tray"
msgstr "Tastaturbinding som slår av/på synlighet for meldingstrau" msgstr "Tastaturbinding som slår av/på synlighet for meldingstrau"
@ -331,50 +335,43 @@ msgstr "Utvidelse"
msgid "Select an extension to configure using the combobox above." msgid "Select an extension to configure using the combobox above."
msgstr "Velg en utvidelse som skal konfigureres med komboboksen over." msgstr "Velg en utvidelse som skal konfigureres med komboboksen over."
#: ../js/gdm/loginDialog.js:371 #: ../js/gdm/loginDialog.js:405
msgid "Session…" msgid "Session…"
msgstr "Økt …" msgstr "Økt …"
#. translators: this message is shown below the user list on the #. translators: this message is shown below the user list on the
#. login screen. It can be activated to reveal an entry for #. login screen. It can be activated to reveal an entry for
#. manually entering the username. #. manually entering the username.
#: ../js/gdm/loginDialog.js:601 #: ../js/gdm/loginDialog.js:630
msgid "Not listed?" msgid "Not listed?"
msgstr "Ikke listet?" msgstr "Ikke listet?"
#: ../js/gdm/loginDialog.js:776 ../js/ui/components/networkAgent.js:137 #: ../js/gdm/loginDialog.js:786 ../js/ui/components/networkAgent.js:137
#: ../js/ui/components/polkitAgent.js:161 ../js/ui/endSessionDialog.js:376 #: ../js/ui/components/polkitAgent.js:162 ../js/ui/endSessionDialog.js:375
#: ../js/ui/extensionDownloader.js:195 ../js/ui/shellMountOperation.js:399 #: ../js/ui/extensionDownloader.js:195 ../js/ui/shellMountOperation.js:399
#: ../js/ui/status/bluetooth.js:415 ../js/ui/unlockDialog.js:96 #: ../js/ui/status/bluetooth.js:415 ../js/ui/unlockDialog.js:99
#: ../js/ui/userMenu.js:938 #: ../js/ui/userMenu.js:938
msgid "Cancel" msgid "Cancel"
msgstr "Avbryt" msgstr "Avbryt"
#: ../js/gdm/loginDialog.js:791 #: ../js/gdm/loginDialog.js:802
msgctxt "button" msgctxt "button"
msgid "Sign In" msgid "Sign In"
msgstr "Logg inn" msgstr "Logg inn"
#: ../js/gdm/loginDialog.js:791 #: ../js/gdm/loginDialog.js:802
msgid "Next" msgid "Next"
msgstr "Neste" msgstr "Neste"
#. Translators: this message is shown below the username entry field
#. to clue the user in on how to login to the local network realm
#: ../js/gdm/loginDialog.js:888
#, c-format
msgid "(e.g., user or %s)"
msgstr "(f.eks. bruker eller %s)"
#. TTLS and PEAP are actually much more complicated, but this complication #. TTLS and PEAP are actually much more complicated, but this complication
#. is not visible here since we only care about phase2 authentication #. is not visible here since we only care about phase2 authentication
#. (and don't even care of which one) #. (and don't even care of which one)
#: ../js/gdm/loginDialog.js:892 ../js/ui/components/networkAgent.js:260 #: ../js/gdm/loginDialog.js:917 ../js/ui/components/networkAgent.js:260
#: ../js/ui/components/networkAgent.js:278 #: ../js/ui/components/networkAgent.js:278
msgid "Username: " msgid "Username: "
msgstr "Brukernavn: " msgstr "Brukernavn: "
#: ../js/gdm/loginDialog.js:1158 #: ../js/gdm/loginDialog.js:1173
msgid "Login Window" msgid "Login Window"
msgstr "Innloggingsvindu" msgstr "Innloggingsvindu"
@ -397,16 +394,21 @@ msgstr "Start på nytt"
msgid "Power Off" msgid "Power Off"
msgstr "Slå av" msgstr "Slå av"
#: ../js/gdm/util.js:247 #: ../js/gdm/util.js:249
msgid "Authentication error" msgid "Authentication error"
msgstr "Autentiseringsfeil" msgstr "Autentiseringsfeil"
#. Translators: this message is shown below the password entry field #. Translators: this message is shown below the password entry field
#. to indicate the user can swipe their finger instead #. to indicate the user can swipe their finger instead
#: ../js/gdm/util.js:364 #: ../js/gdm/util.js:366
msgid "(or swipe finger)" msgid "(or swipe finger)"
msgstr "(eller dra finger)" msgstr "(eller dra finger)"
#: ../js/gdm/util.js:391
#, c-format
msgid "(e.g., user or %s)"
msgstr "(f.eks. bruker eller %s)"
#: ../js/misc/util.js:97 #: ../js/misc/util.js:97
msgid "Command not found" msgid "Command not found"
msgstr "Kommando ikke funnet" msgstr "Kommando ikke funnet"
@ -422,23 +424,23 @@ msgstr "Klarte ikke å lese kommando:"
msgid "Execution of '%s' failed:" msgid "Execution of '%s' failed:"
msgstr "Kjøring av «%s» feilet:" msgstr "Kjøring av «%s» feilet:"
#: ../js/ui/appDisplay.js:361 #: ../js/ui/appDisplay.js:349
msgid "Frequent" msgid "Frequent"
msgstr "Ofte" msgstr "Ofte"
#: ../js/ui/appDisplay.js:368 #: ../js/ui/appDisplay.js:356
msgid "All" msgid "All"
msgstr "Alle" msgstr "Alle"
#: ../js/ui/appDisplay.js:960 #: ../js/ui/appDisplay.js:914
msgid "New Window" msgid "New Window"
msgstr "Nytt vindu" msgstr "Nytt vindu"
#: ../js/ui/appDisplay.js:963 ../js/ui/dash.js:284 #: ../js/ui/appDisplay.js:917 ../js/ui/dash.js:284
msgid "Remove from Favorites" msgid "Remove from Favorites"
msgstr "Fjern fra favoritter" msgstr "Fjern fra favoritter"
#: ../js/ui/appDisplay.js:964 #: ../js/ui/appDisplay.js:918
msgid "Add to Favorites" msgid "Add to Favorites"
msgstr "Legg til i favoritter" msgstr "Legg til i favoritter"
@ -577,35 +579,35 @@ msgid "S"
msgstr "Lø" msgstr "Lø"
#. Translators: Text to show if there are no events #. Translators: Text to show if there are no events
#: ../js/ui/calendar.js:735 #: ../js/ui/calendar.js:720
msgid "Nothing Scheduled" msgid "Nothing Scheduled"
msgstr "Ingenting planlagt" msgstr "Ingenting planlagt"
#. Translators: Shown on calendar heading when selected day occurs on current year #. Translators: Shown on calendar heading when selected day occurs on current year
#: ../js/ui/calendar.js:751 #: ../js/ui/calendar.js:736
msgctxt "calendar heading" msgctxt "calendar heading"
msgid "%A, %B %d" msgid "%A, %B %d"
msgstr "%A %B %d" msgstr "%A %B %d"
#. Translators: Shown on calendar heading when selected day occurs on different year #. Translators: Shown on calendar heading when selected day occurs on different year
#: ../js/ui/calendar.js:754 #: ../js/ui/calendar.js:739
msgctxt "calendar heading" msgctxt "calendar heading"
msgid "%A, %B %d, %Y" msgid "%A, %B %d, %Y"
msgstr "%A %B %d, %Y" msgstr "%A %B %d, %Y"
#: ../js/ui/calendar.js:764 #: ../js/ui/calendar.js:749
msgid "Today" msgid "Today"
msgstr "I dag" msgstr "I dag"
#: ../js/ui/calendar.js:768 #: ../js/ui/calendar.js:753
msgid "Tomorrow" msgid "Tomorrow"
msgstr "I morgen" msgstr "I morgen"
#: ../js/ui/calendar.js:779 #: ../js/ui/calendar.js:764
msgid "This week" msgid "This week"
msgstr "Denne uken" msgstr "Denne uken"
#: ../js/ui/calendar.js:787 #: ../js/ui/calendar.js:772
msgid "Next week" msgid "Next week"
msgstr "Neste uke" msgstr "Neste uke"
@ -630,11 +632,11 @@ msgstr "Åpne med %s"
msgid "Eject" msgid "Eject"
msgstr "Løs ut" msgstr "Løs ut"
#: ../js/ui/components/keyring.js:88 ../js/ui/components/polkitAgent.js:280 #: ../js/ui/components/keyring.js:82 ../js/ui/components/polkitAgent.js:268
msgid "Password:" msgid "Password:"
msgstr "Passord:" msgstr "Passord:"
#: ../js/ui/components/keyring.js:107 #: ../js/ui/components/keyring.js:101
msgid "Type again:" msgid "Type again:"
msgstr "Skriv på nytt:" msgstr "Skriv på nytt:"
@ -714,15 +716,15 @@ msgstr "Nettverkspassord for mobilt bredbånd"
msgid "A password is required to connect to '%s'." msgid "A password is required to connect to '%s'."
msgstr "Et passord kreves for å koble til «%s»." msgstr "Et passord kreves for å koble til «%s»."
#: ../js/ui/components/polkitAgent.js:54 #: ../js/ui/components/polkitAgent.js:55
msgid "Authentication Required" msgid "Authentication Required"
msgstr "Autentisering kreves" msgstr "Autentisering kreves"
#: ../js/ui/components/polkitAgent.js:92 #: ../js/ui/components/polkitAgent.js:93
msgid "Administrator" msgid "Administrator"
msgstr "Administrator" msgstr "Administrator"
#: ../js/ui/components/polkitAgent.js:170 #: ../js/ui/components/polkitAgent.js:165
msgid "Authenticate" msgid "Authenticate"
msgstr "Autentiser" msgstr "Autentiser"
@ -730,12 +732,12 @@ msgstr "Autentiser"
#. * requested authentication was not gained; this can happen #. * requested authentication was not gained; this can happen
#. * because of an authentication error (like invalid password), #. * because of an authentication error (like invalid password),
#. * for instance. #. * for instance.
#: ../js/ui/components/polkitAgent.js:266 ../js/ui/shellMountOperation.js:383 #: ../js/ui/components/polkitAgent.js:256 ../js/ui/shellMountOperation.js:383
msgid "Sorry, that didn't work. Please try again." msgid "Sorry, that didn't work. Please try again."
msgstr "Beklager, det virket ikke. Vennligst prøv igjen." msgstr "Beklager, det virket ikke. Vennligst prøv igjen."
#. Translators: this is a filename used for screencast recording #. Translators: this is a filename used for screencast recording
#: ../js/ui/components/recorder.js:47 #: ../js/ui/components/recorder.js:48
#, no-c-format #, no-c-format
msgid "Screencast from %d %t" msgid "Screencast from %d %t"
msgstr "Skjermvideo fra %d %t" msgstr "Skjermvideo fra %d %t"
@ -993,22 +995,22 @@ msgstr "Vis programmer"
msgid "Dash" msgid "Dash"
msgstr "Favoritter" msgstr "Favoritter"
#: ../js/ui/dateMenu.js:86 #: ../js/ui/dateMenu.js:91
msgid "Open Calendar" msgid "Open Calendar"
msgstr "Åpne kalender" msgstr "Åpne kalender"
#: ../js/ui/dateMenu.js:90 #: ../js/ui/dateMenu.js:96
msgid "Open Clocks" msgid "Open Clocks"
msgstr "Åpne Klokker" msgstr "Åpne Klokker"
#: ../js/ui/dateMenu.js:97 #: ../js/ui/dateMenu.js:105
msgid "Date & Time Settings" msgid "Date & Time Settings"
msgstr "Innstillinger for dato og klokkeslett" msgstr "Innstillinger for dato og klokkeslett"
#. Translators: This is the date format to use when the calendar popup is #. Translators: This is the date format to use when the calendar popup is
#. * shown - it is shown just below the time in the shell (e.g. "Tue 9:29 AM"). #. * shown - it is shown just below the time in the shell (e.g. "Tue 9:29 AM").
#. #.
#: ../js/ui/dateMenu.js:208 #: ../js/ui/dateMenu.js:215
msgid "%A %B %e, %Y" msgid "%A %B %e, %Y"
msgstr "%a %e %B, %Y" msgstr "%a %e %B, %Y"
@ -1113,56 +1115,56 @@ msgstr "Installer"
msgid "Download and install '%s' from extensions.gnome.org?" msgid "Download and install '%s' from extensions.gnome.org?"
msgstr "Last ned og installer «%s» fra extensions.gnome.org?" msgstr "Last ned og installer «%s» fra extensions.gnome.org?"
#: ../js/ui/keyboard.js:619 ../js/ui/status/keyboard.js:333 #: ../js/ui/keyboard.js:619 ../js/ui/status/keyboard.js:314
#: ../js/ui/status/power.js:211 #: ../js/ui/status/power.js:211
msgid "Keyboard" msgid "Keyboard"
msgstr "Tastatur" msgstr "Tastatur"
#: ../js/ui/lookingGlass.js:689 #: ../js/ui/lookingGlass.js:693
msgid "No extensions installed" msgid "No extensions installed"
msgstr "Ingen utvidelser installert" msgstr "Ingen utvidelser installert"
#. Translators: argument is an extension UUID. #. Translators: argument is an extension UUID.
#: ../js/ui/lookingGlass.js:743 #: ../js/ui/lookingGlass.js:747
#, c-format #, c-format
msgid "%s has not emitted any errors." msgid "%s has not emitted any errors."
msgstr "%s har ikke avgitt noen feil." msgstr "%s har ikke avgitt noen feil."
#: ../js/ui/lookingGlass.js:749 #: ../js/ui/lookingGlass.js:753
msgid "Hide Errors" msgid "Hide Errors"
msgstr "Skjul feil" msgstr "Skjul feil"
#: ../js/ui/lookingGlass.js:753 ../js/ui/lookingGlass.js:813 #: ../js/ui/lookingGlass.js:757 ../js/ui/lookingGlass.js:817
msgid "Show Errors" msgid "Show Errors"
msgstr "Vis feil" msgstr "Vis feil"
#: ../js/ui/lookingGlass.js:762 #: ../js/ui/lookingGlass.js:766
msgid "Enabled" msgid "Enabled"
msgstr "Aktivert" msgstr "Aktivert"
#. translators: #. translators:
#. * The device has been disabled #. * The device has been disabled
#: ../js/ui/lookingGlass.js:765 ../src/gvc/gvc-mixer-control.c:1830 #: ../js/ui/lookingGlass.js:769 ../src/gvc/gvc-mixer-control.c:1830
msgid "Disabled" msgid "Disabled"
msgstr "Deaktivert" msgstr "Deaktivert"
#: ../js/ui/lookingGlass.js:767 #: ../js/ui/lookingGlass.js:771
msgid "Error" msgid "Error"
msgstr "Feil" msgstr "Feil"
#: ../js/ui/lookingGlass.js:769 #: ../js/ui/lookingGlass.js:773
msgid "Out of date" msgid "Out of date"
msgstr "Utdatert" msgstr "Utdatert"
#: ../js/ui/lookingGlass.js:771 #: ../js/ui/lookingGlass.js:775
msgid "Downloading" msgid "Downloading"
msgstr "Laster ned" msgstr "Laster ned"
#: ../js/ui/lookingGlass.js:795 #: ../js/ui/lookingGlass.js:799
msgid "View Source" msgid "View Source"
msgstr "Vis kildekode" msgstr "Vis kildekode"
#: ../js/ui/lookingGlass.js:804 #: ../js/ui/lookingGlass.js:808
msgid "Web Page" msgid "Web Page"
msgstr "Nettside" msgstr "Nettside"
@ -1182,35 +1184,35 @@ msgstr "Tøm meldinger"
msgid "Notification Settings" msgid "Notification Settings"
msgstr "Innstillinger for varsling" msgstr "Innstillinger for varsling"
#: ../js/ui/messageTray.js:1707 #: ../js/ui/messageTray.js:1709
msgid "No Messages" msgid "No Messages"
msgstr "Ingen meldinger" msgstr "Ingen meldinger"
#: ../js/ui/messageTray.js:1780 #: ../js/ui/messageTray.js:1782
msgid "Message Tray" msgid "Message Tray"
msgstr "Meldingstrau" msgstr "Meldingstrau"
#: ../js/ui/messageTray.js:2805 #: ../js/ui/messageTray.js:2810
msgid "System Information" msgid "System Information"
msgstr "Systeminformasjon" msgstr "Systeminformasjon"
#: ../js/ui/notificationDaemon.js:629 ../src/shell-app.c:378 #: ../js/ui/notificationDaemon.js:629 ../src/shell-app.c:374
msgctxt "program" msgctxt "program"
msgid "Unknown" msgid "Unknown"
msgstr "Ukjent" msgstr "Ukjent"
#: ../js/ui/overviewControls.js:472 ../js/ui/screenShield.js:150 #: ../js/ui/overviewControls.js:463 ../js/ui/screenShield.js:149
#, c-format #, c-format
msgid "%d new message" msgid "%d new message"
msgid_plural "%d new messages" msgid_plural "%d new messages"
msgstr[0] "%d ny melding" msgstr[0] "%d ny melding"
msgstr[1] "%d nye meldinger" msgstr[1] "%d nye meldinger"
#: ../js/ui/overview.js:82 #: ../js/ui/overview.js:84
msgid "Undo" msgid "Undo"
msgstr "Angre" msgstr "Angre"
#: ../js/ui/overview.js:127 #: ../js/ui/overview.js:129
msgid "Overview" msgid "Overview"
msgstr "Oversikt" msgstr "Oversikt"
@ -1218,21 +1220,21 @@ msgstr "Oversikt"
#. in the search entry when no search is #. in the search entry when no search is
#. active; it should not exceed ~30 #. active; it should not exceed ~30
#. characters. #. characters.
#: ../js/ui/overview.js:258 #: ../js/ui/overview.js:271
msgid "Type to search…" msgid "Type to search…"
msgstr "Skriv for å søke …" msgstr "Skriv for å søke …"
#: ../js/ui/panel.js:642 #: ../js/ui/panel.js:612
msgid "Quit" msgid "Quit"
msgstr "Avslutt" msgstr "Avslutt"
#. Translators: If there is no suitable word for "Activities" #. Translators: If there is no suitable word for "Activities"
#. in your language, you can use the word for "Overview". #. in your language, you can use the word for "Overview".
#: ../js/ui/panel.js:693 #: ../js/ui/panel.js:636
msgid "Activities" msgid "Activities"
msgstr "Aktiviteter" msgstr "Aktiviteter"
#: ../js/ui/panel.js:989 #: ../js/ui/panel.js:933
msgid "Top Bar" msgid "Top Bar"
msgstr "Topp-panel" msgstr "Topp-panel"
@ -1241,36 +1243,36 @@ msgstr "Topp-panel"
#. "ON" and "OFF") or "toggle-switch-intl" (for toggle #. "ON" and "OFF") or "toggle-switch-intl" (for toggle
#. switches containing "◯" and "|"). Other values will #. switches containing "◯" and "|"). Other values will
#. simply result in invisible toggle switches. #. simply result in invisible toggle switches.
#: ../js/ui/popupMenu.js:738 #: ../js/ui/popupMenu.js:727
msgid "toggle-switch-us" msgid "toggle-switch-us"
msgstr "toggle-switch-intl" msgstr "toggle-switch-intl"
#: ../js/ui/runDialog.js:74 #: ../js/ui/runDialog.js:73
msgid "Enter a Command" msgid "Enter a Command"
msgstr "Oppgi en kommando" msgstr "Oppgi en kommando"
#: ../js/ui/runDialog.js:110 #: ../js/ui/runDialog.js:109
msgid "Close" msgid "Close"
msgstr "Lukk" msgstr "Lukk"
#. Translators: This is a time format for a date in #. Translators: This is a time format for a date in
#. long format #. long format
#: ../js/ui/screenShield.js:87 #: ../js/ui/screenShield.js:86
msgid "%A, %B %d" msgid "%A, %B %d"
msgstr "%A, %B %d" msgstr "%A, %B %d"
#: ../js/ui/screenShield.js:152 #: ../js/ui/screenShield.js:151
#, c-format #, c-format
msgid "%d new notification" msgid "%d new notification"
msgid_plural "%d new notifications" msgid_plural "%d new notifications"
msgstr[0] "%d ny varsling" msgstr[0] "%d ny varsling"
msgstr[1] "%d nye varslinger" msgstr[1] "%d nye varslinger"
#: ../js/ui/screenShield.js:449 ../js/ui/userMenu.js:807 #: ../js/ui/screenShield.js:438 ../js/ui/userMenu.js:807
msgid "Lock" msgid "Lock"
msgstr "Lås" msgstr "Lås"
#: ../js/ui/screenShield.js:652 #: ../js/ui/screenShield.js:640
msgid "GNOME needs to lock the screen" msgid "GNOME needs to lock the screen"
msgstr "GNOME må låse skjermen" msgstr "GNOME må låse skjermen"
@ -1281,11 +1283,11 @@ msgstr "GNOME må låse skjermen"
#. #.
#. XXX: another option is to kick the user into the gdm login #. XXX: another option is to kick the user into the gdm login
#. screen, where we're not affected by grabs #. screen, where we're not affected by grabs
#: ../js/ui/screenShield.js:773 ../js/ui/screenShield.js:1213 #: ../js/ui/screenShield.js:761 ../js/ui/screenShield.js:1197
msgid "Unable to lock" msgid "Unable to lock"
msgstr "Kan ikke låse" msgstr "Kan ikke låse"
#: ../js/ui/screenShield.js:774 ../js/ui/screenShield.js:1214 #: ../js/ui/screenShield.js:762 ../js/ui/screenShield.js:1198
msgid "Lock was blocked by an application" msgid "Lock was blocked by an application"
msgstr "Låsing ble stoppet av et program" msgstr "Låsing ble stoppet av et program"
@ -1297,19 +1299,19 @@ msgstr "Søker …"
msgid "No results." msgid "No results."
msgstr "Ingen resultater." msgstr "Ingen resultater."
#: ../js/ui/shellEntry.js:27 #: ../js/ui/shellEntry.js:29
msgid "Copy" msgid "Copy"
msgstr "Kopier" msgstr "Kopier"
#: ../js/ui/shellEntry.js:32 #: ../js/ui/shellEntry.js:34
msgid "Paste" msgid "Paste"
msgstr "Lim inn" msgstr "Lim inn"
#: ../js/ui/shellEntry.js:99 #: ../js/ui/shellEntry.js:106
msgid "Show Text" msgid "Show Text"
msgstr "Vis tekst" msgstr "Vis tekst"
#: ../js/ui/shellEntry.js:101 #: ../js/ui/shellEntry.js:108
msgid "Hide Text" msgid "Hide Text"
msgstr "Skjul tekst" msgstr "Skjul tekst"
@ -1321,7 +1323,7 @@ msgstr "Passord"
msgid "Remember Password" msgid "Remember Password"
msgstr "Husk passord" msgstr "Husk passord"
#: ../js/ui/shellMountOperation.js:403 ../js/ui/unlockDialog.js:109 #: ../js/ui/shellMountOperation.js:403 ../js/ui/unlockDialog.js:113
msgid "Unlock" msgid "Unlock"
msgstr "Lås opp" msgstr "Lås opp"
@ -1376,7 +1378,7 @@ msgstr "Stor tekst"
#: ../js/ui/status/bluetooth.js:28 ../js/ui/status/bluetooth.js:32 #: ../js/ui/status/bluetooth.js:28 ../js/ui/status/bluetooth.js:32
#: ../js/ui/status/bluetooth.js:289 ../js/ui/status/bluetooth.js:321 #: ../js/ui/status/bluetooth.js:289 ../js/ui/status/bluetooth.js:321
#: ../js/ui/status/bluetooth.js:357 ../js/ui/status/bluetooth.js:388 #: ../js/ui/status/bluetooth.js:357 ../js/ui/status/bluetooth.js:388
#: ../js/ui/status/network.js:739 #: ../js/ui/status/network.js:826
msgid "Bluetooth" msgid "Bluetooth"
msgstr "Bluetooth" msgstr "Bluetooth"
@ -1397,7 +1399,7 @@ msgid "Bluetooth Settings"
msgstr "Innstillinger for Bluetooth" msgstr "Innstillinger for Bluetooth"
#. TRANSLATORS: this means that bluetooth was disabled by hardware rfkill #. TRANSLATORS: this means that bluetooth was disabled by hardware rfkill
#: ../js/ui/status/bluetooth.js:104 ../js/ui/status/network.js:142 #: ../js/ui/status/bluetooth.js:104 ../js/ui/status/network.js:178
msgid "hardware disabled" msgid "hardware disabled"
msgstr "maskinvare slått av" msgstr "maskinvare slått av"
@ -1405,12 +1407,12 @@ msgstr "maskinvare slått av"
msgid "Connection" msgid "Connection"
msgstr "Tilkobling" msgstr "Tilkobling"
#: ../js/ui/status/bluetooth.js:208 ../js/ui/status/network.js:404 #: ../js/ui/status/bluetooth.js:208 ../js/ui/status/network.js:460
msgid "disconnecting..." msgid "disconnecting..."
msgstr "kobler fra …" msgstr "kobler fra …"
#: ../js/ui/status/bluetooth.js:221 ../js/ui/status/network.js:410 #: ../js/ui/status/bluetooth.js:221 ../js/ui/status/network.js:466
#: ../js/ui/status/network.js:1343 #: ../js/ui/status/network.js:1546
msgid "connecting..." msgid "connecting..."
msgstr "kobler til …" msgstr "kobler til …"
@ -1465,9 +1467,8 @@ msgstr "Enhet %s vil koble seg sammen med denne datamaskinen"
#: ../js/ui/status/bluetooth.js:366 #: ../js/ui/status/bluetooth.js:366
#, c-format #, c-format
msgid "" msgid "Please confirm whether the PIN '%06d' matches the one on the device."
"Please confirm whether the Passkey '%06d' matches the one on the device." msgstr "Vennligst bekreft om PIN «%06d» er lik den som brukes på enheten."
msgstr "Vennligst bekreft om passord «%06d» er lik den som brukes på enheten."
#. Translators: this is the verb, not the noun #. Translators: this is the verb, not the noun
#: ../js/ui/status/bluetooth.js:369 #: ../js/ui/status/bluetooth.js:369
@ -1491,11 +1492,11 @@ msgstr "Vennligst oppgi PIN som oppgitt på enheten."
msgid "OK" msgid "OK"
msgstr "OK" msgstr "OK"
#: ../js/ui/status/keyboard.js:396 #: ../js/ui/status/keyboard.js:368
msgid "Show Keyboard Layout" msgid "Show Keyboard Layout"
msgstr "Vis tastaturutforming" msgstr "Vis tastaturutforming"
#: ../js/ui/status/keyboard.js:401 #: ../js/ui/status/keyboard.js:373
msgid "Region & Language Settings" msgid "Region & Language Settings"
msgstr "Innstillinger for region og språk" msgstr "Innstillinger for region og språk"
@ -1503,91 +1504,117 @@ msgstr "Innstillinger for region og språk"
msgid "Volume, network, battery" msgid "Volume, network, battery"
msgstr "Volum, nettverk, batteri" msgstr "Volum, nettverk, batteri"
#: ../js/ui/status/network.js:75 #: ../js/ui/status/network.js:104
msgid "<unknown>" msgid "<unknown>"
msgstr "<ukjent>" msgstr "<ukjent>"
#: ../js/ui/status/network.js:127
msgid "Wi-Fi"
msgstr "Wi-Fi"
#. Translators: this indicates that wireless or wwan is disabled by hardware killswitch #. Translators: this indicates that wireless or wwan is disabled by hardware killswitch
#: ../js/ui/status/network.js:164 #: ../js/ui/status/network.js:200
msgid "disabled" msgid "disabled"
msgstr "slått av" msgstr "slått av"
#. Translators: this is for network devices that are physically present but are not #. Translators: this is for network devices that are physically present but are not
#. under NetworkManager's control (and thus cannot be used in the menu) #. under NetworkManager's control (and thus cannot be used in the menu)
#: ../js/ui/status/network.js:402 #: ../js/ui/status/network.js:458
msgid "unmanaged" msgid "unmanaged"
msgstr "ikke håndtert" msgstr "ikke håndtert"
#. Translators: this is for network connections that require some kind of key or password #. Translators: this is for network connections that require some kind of key or password
#: ../js/ui/status/network.js:413 ../js/ui/status/network.js:1346 #: ../js/ui/status/network.js:469 ../js/ui/status/network.js:1549
msgid "authentication required" msgid "authentication required"
msgstr "autentisering kreves" msgstr "autentisering kreves"
#. Translators: this is for devices that require some kind of firmware or kernel #. Translators: this is for devices that require some kind of firmware or kernel
#. module, which is missing #. module, which is missing
#: ../js/ui/status/network.js:423 #: ../js/ui/status/network.js:479
msgid "firmware missing" msgid "firmware missing"
msgstr "fastvare mangler" msgstr "fastvare mangler"
#. Translators: this is for wired network devices that are physically disconnected #. Translators: this is for wired network devices that are physically disconnected
#: ../js/ui/status/network.js:430 #: ../js/ui/status/network.js:486
msgid "cable unplugged" msgid "cable unplugged"
msgstr "kabel koblet fra" msgstr "kabel koblet fra"
#. Translators: this is for a network device that cannot be activated (for example it #. Translators: this is for a network device that cannot be activated (for example it
#. is disabled by rfkill, or it has no coverage #. is disabled by rfkill, or it has no coverage
#: ../js/ui/status/network.js:435 #: ../js/ui/status/network.js:491
msgid "unavailable" msgid "unavailable"
msgstr "ikke tilgjengelig" msgstr "ikke tilgjengelig"
#: ../js/ui/status/network.js:437 ../js/ui/status/network.js:1348 #: ../js/ui/status/network.js:493 ../js/ui/status/network.js:1551
msgid "connection failed" msgid "connection failed"
msgstr "tilkobling feilet" msgstr "tilkobling feilet"
#: ../js/ui/status/network.js:490 ../js/ui/status/network.js:1236 #: ../js/ui/status/network.js:552 ../js/ui/status/network.js:1435
#: ../js/ui/status/network.js:1424 #: ../js/ui/status/network.js:1627
msgid "More…" msgid "More…"
msgstr "Mer …" msgstr "Mer …"
#. TRANSLATORS: this is the indication that a connection for another logged in user is active, #. TRANSLATORS: this is the indication that a connection for another logged in user is active,
#. and we cannot access its settings (including the name) #. and we cannot access its settings (including the name)
#: ../js/ui/status/network.js:518 ../js/ui/status/network.js:1191 #: ../js/ui/status/network.js:588 ../js/ui/status/network.js:1365
msgid "Connected (private)" msgid "Connected (private)"
msgstr "Tilkoblet (privat)" msgstr "Tilkoblet (privat)"
#: ../js/ui/status/network.js:597 #: ../js/ui/status/network.js:667
msgid "Wired" msgid "Wired"
msgstr "Kablet" msgstr "Kablet"
#: ../js/ui/status/network.js:611 #: ../js/ui/status/network.js:668
msgid "Auto Ethernet"
msgstr "Automatisk Ethernet"
#: ../js/ui/status/network.js:695
msgid "Mobile broadband" msgid "Mobile broadband"
msgstr "Mobilt bredbånd" msgstr "Mobilt bredbånd"
#: ../js/ui/status/network.js:1522 #: ../js/ui/status/network.js:728
msgid "Auto broadband"
msgstr "Automatisk bredbånd"
#: ../js/ui/status/network.js:731
msgid "Auto dial-up"
msgstr "Automatisk oppringt"
#. TRANSLATORS: this the automatic wireless connection name (including the network name)
#: ../js/ui/status/network.js:861 ../js/ui/status/network.js:1382
#, c-format
msgid "Auto %s"
msgstr "Automatisk %s"
#: ../js/ui/status/network.js:863
msgid "Auto bluetooth"
msgstr "Automatisk Bluetooth"
#: ../js/ui/status/network.js:1384
msgid "Auto wireless"
msgstr "Automatisk trådløst"
#: ../js/ui/status/network.js:1729
msgid "Enable networking" msgid "Enable networking"
msgstr "Slå på nettverk" msgstr "Slå på nettverk"
#: ../js/ui/status/network.js:1583 #: ../js/ui/status/network.js:1771
msgid "Wi-Fi"
msgstr "Wi-Fi"
#: ../js/ui/status/network.js:1790
msgid "Network Settings" msgid "Network Settings"
msgstr "Innstillinger for nettverk" msgstr "Innstillinger for nettverk"
#: ../js/ui/status/network.js:1600 #: ../js/ui/status/network.js:1807
msgid "Network Manager" msgid "Network Manager"
msgstr "Nettverkshåndtering" msgstr "Nettverkshåndtering"
#: ../js/ui/status/network.js:1690 #: ../js/ui/status/network.js:1897
msgid "Connection failed" msgid "Connection failed"
msgstr "Tilkobling feilet" msgstr "Tilkobling feilet"
#: ../js/ui/status/network.js:1691 #: ../js/ui/status/network.js:1898
msgid "Activation of network connection failed" msgid "Activation of network connection failed"
msgstr "Aktivering av nettverkstilkobling feilet" msgstr "Aktivering av nettverkstilkobling feilet"
#: ../js/ui/status/network.js:2047 #: ../js/ui/status/network.js:2276
msgid "Networking is disabled" msgid "Networking is disabled"
msgstr "Nettverk er slått av" msgstr "Nettverk er slått av"
@ -1701,11 +1728,11 @@ msgstr "Volum"
msgid "Microphone" msgid "Microphone"
msgstr "Mikrofon" msgstr "Mikrofon"
#: ../js/ui/unlockDialog.js:120 #: ../js/ui/unlockDialog.js:124
msgid "Log in as another user" msgid "Log in as another user"
msgstr "Logg inn som en annen bruker" msgstr "Logg inn som en annen bruker"
#: ../js/ui/unlockDialog.js:141 #: ../js/ui/unlockDialog.js:145
msgid "Unlock Window" msgid "Unlock Window"
msgstr "Lås opp vindu" msgstr "Lås opp vindu"
@ -1833,36 +1860,36 @@ msgid_plural "%u Inputs"
msgstr[0] "%u inngang" msgstr[0] "%u inngang"
msgstr[1] "%u innganger" msgstr[1] "%u innganger"
#: ../src/gvc/gvc-mixer-control.c:2373 #: ../src/gvc/gvc-mixer-control.c:2371
msgid "System Sounds" msgid "System Sounds"
msgstr "Systemlyder" msgstr "Systemlyder"
#: ../src/main.c:372 #: ../src/main.c:347
msgid "Print version" msgid "Print version"
msgstr "Skriv ut versjon" msgstr "Skriv ut versjon"
#: ../src/main.c:378 #: ../src/main.c:353
msgid "Mode used by GDM for login screen" msgid "Mode used by GDM for login screen"
msgstr "Modus som brukes av GDM for innloggingsskjermen" msgstr "Modus som brukes av GDM for innloggingsskjermen"
#: ../src/main.c:384 #: ../src/main.c:359
msgid "Use a specific mode, e.g. \"gdm\" for login screen" msgid "Use a specific mode, e.g. \"gdm\" for login screen"
msgstr "Bruk spesifikt modus, f.eks «gdm» for innloggingsskjerm" msgstr "Bruk spesifikt modus, f.eks «gdm» for innloggingsskjerm"
#: ../src/main.c:390 #: ../src/main.c:365
msgid "List possible modes" msgid "List possible modes"
msgstr "Vis mulige modi" msgstr "Vis mulige modi"
#: ../src/shell-app.c:626 #: ../src/shell-app.c:622
#, c-format #, c-format
msgid "Failed to launch '%s'" msgid "Failed to launch '%s'"
msgstr "Klarte ikke å starte «%s»" msgstr "Klarte ikke å starte «%s»"
#: ../src/shell-keyring-prompt.c:714 #: ../src/shell-keyring-prompt.c:708
msgid "Passwords do not match." msgid "Passwords do not match."
msgstr "Passordene er ikke like." msgstr "Passordene er ikke like."
#: ../src/shell-keyring-prompt.c:722 #: ../src/shell-keyring-prompt.c:716
msgid "Password cannot be blank" msgid "Password cannot be blank"
msgstr "Passordet kan ikke være tomt" msgstr "Passordet kan ikke være tomt"

401
po/sk.po
View File

@ -10,8 +10,8 @@ msgstr ""
"Project-Id-Version: gnome-shell\n" "Project-Id-Version: gnome-shell\n"
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-" "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-"
"shell&keywords=I18N+L10N&component=general\n" "shell&keywords=I18N+L10N&component=general\n"
"POT-Creation-Date: 2013-05-24 21:21+0000\n" "POT-Creation-Date: 2013-03-23 11:49+0000\n"
"PO-Revision-Date: 2013-05-24 23:24+0100\n" "PO-Revision-Date: 2013-03-23 16:21+0000\n"
"Last-Translator: Dušan Kazik <prescott66@gmail.com>\n" "Last-Translator: Dušan Kazik <prescott66@gmail.com>\n"
"Language-Team: Slovak <gnome-sk-list@gnome.org>\n" "Language-Team: Slovak <gnome-sk-list@gnome.org>\n"
"Language: sk\n" "Language: sk\n"
@ -34,30 +34,22 @@ msgstr "Zaznamenať dianie na obrazovke"
msgid "System" msgid "System"
msgstr "Systém" msgstr "Systém"
# nazov klavesovej skratky
#: ../data/50-gnome-shell-system.xml.in.h:2 #: ../data/50-gnome-shell-system.xml.in.h:2
msgid "Show the message tray" msgid "Show the message tray"
msgstr "Zobraz lištu správ" msgstr "Zobrazí lištu správ"
# nazov klavesovej skratky
#: ../data/50-gnome-shell-system.xml.in.h:3 #: ../data/50-gnome-shell-system.xml.in.h:3
msgid "Focus the active notification" msgid "Focus the active notification"
msgstr "Zamerať aktívne oznámenie" msgstr "Zamerať aktívne oznámenie"
# nazov klavesovej skratky # tooltip
#: ../data/50-gnome-shell-system.xml.in.h:4 #: ../data/50-gnome-shell-system.xml.in.h:4
msgid "Show the overview"
msgstr "Zobraziť prehľad"
# nazov klavesovej skratky
#: ../data/50-gnome-shell-system.xml.in.h:5
msgid "Show all applications" msgid "Show all applications"
msgstr "Zobraz všetky aplikácie" msgstr "Zobrazí všetky aplikácie"
# nazov klavesovej skratky #: ../data/50-gnome-shell-system.xml.in.h:5
#: ../data/50-gnome-shell-system.xml.in.h:6
msgid "Open the application menu" msgid "Open the application menu"
msgstr "Otvor ponuku aplikácií" msgstr "Otvorí ponuku aplikácií"
#: ../data/gnome-shell.desktop.in.in.h:1 #: ../data/gnome-shell.desktop.in.in.h:1
msgid "GNOME Shell" msgid "GNOME Shell"
@ -108,10 +100,26 @@ msgstr ""
"gnome.Shell." "gnome.Shell."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:5 #: ../data/org.gnome.shell.gschema.xml.in.in.h:5
msgid "Whether to collect stats about applications usage"
msgstr "Či sa majú zhromažďovať štatistické údaje o používaní aplikácií"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:6
msgid ""
"The shell normally monitors active applications in order to present the most "
"used ones (e.g. in launchers). While this data will be kept private, you may "
"want to disable this for privacy reasons. Please note that doing so won't "
"remove already saved data."
msgstr ""
"Prostredie shell obvykle sleduje aktívne aplikácie, aby mohlo ponúkať "
"najpoužívanejšie z nich (napr. v spúšťačoch). Aj keď sú tieto údaje "
"uchovávané v tajnosti, môžete ich kvôli lepšej ochrane súkromia zakázať. Ak "
"tak urobíte, údaje, ktoré už boli uložené, zostanú zachované."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:7
msgid "List of desktop file IDs for favorite applications" msgid "List of desktop file IDs for favorite applications"
msgstr "Zoznam identifikátorov súborov plochy pre obľúbené aplikácie" msgstr "Zoznam identifikátorov súborov plochy pre obľúbené aplikácie"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:6 #: ../data/org.gnome.shell.gschema.xml.in.in.h:8
msgid "" msgid ""
"The applications corresponding to these identifiers will be displayed in the " "The applications corresponding to these identifiers will be displayed in the "
"favorites area." "favorites area."
@ -120,29 +128,29 @@ msgstr ""
"obľúbenými aplikáciami." "obľúbenými aplikáciami."
# summary # summary
#: ../data/org.gnome.shell.gschema.xml.in.in.h:7 #: ../data/org.gnome.shell.gschema.xml.in.in.h:9
msgid "List of categories that should be displayed as folders" msgid "List of categories that should be displayed as folders"
msgstr "Zoznam kategórií, ktoré sa majú zobraziť ako priečinky" msgstr "Zoznam kategórií, ktoré sa majú zobraziť ako priečinky"
# description # description
#: ../data/org.gnome.shell.gschema.xml.in.in.h:8 #: ../data/org.gnome.shell.gschema.xml.in.in.h:10
msgid "" msgid ""
"Each category name in this list will be represented as folder in the " "Each category name in this list will be represented as folder in the "
"application view, rather than being displayed inline in the main view." "application view, rather than being displayed inline in the main view."
msgstr "" msgstr ""
"Každá z názvov kategórií v tomto zoznamu bude reprezentovaná ako priečinok v " "Každá z názvov kategórií v tomto zoznamu bude reprezentovaná ako priečinok v zobrazení aplikácií namiesto toho, aby sa zobrazila v hlavnom zobrazení."
"zobrazení aplikácií namiesto toho, aby sa zobrazila v hlavnom zobrazení."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:9 #: ../data/org.gnome.shell.gschema.xml.in.in.h:11
msgid "History for command (Alt-F2) dialog" msgid "History for command (Alt-F2) dialog"
msgstr "História dialógového okna príkazov (Alt-F2)" msgstr "História dialógového okna príkazov (Alt-F2)"
# * https://live.gnome.org/GnomeShell/LookingGlass # * https://live.gnome.org/GnomeShell/LookingGlass
#: ../data/org.gnome.shell.gschema.xml.in.in.h:10 #: ../data/org.gnome.shell.gschema.xml.in.in.h:12
msgid "History for the looking glass dialog" msgid "History for the looking glass dialog"
msgstr "História dialógového okna integrovaného odlaďovača" msgstr "História dialógového okna integrovaného odlaďovača"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:11 #: ../data/org.gnome.shell.gschema.xml.in.in.h:13
msgid "" msgid ""
"Internally used to store the last IM presence explicitly set by the user. " "Internally used to store the last IM presence explicitly set by the user. "
"The value here is from the TpConnectionPresenceType enumeration." "The value here is from the TpConnectionPresenceType enumeration."
@ -151,7 +159,7 @@ msgstr ""
"komunikátora výlučne nastavenej používateľom. Táto hodnota je z vymenovaných " "komunikátora výlučne nastavenej používateľom. Táto hodnota je z vymenovaných "
"hodnôt typu TpConnectionPresenceType." "hodnôt typu TpConnectionPresenceType."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:12 #: ../data/org.gnome.shell.gschema.xml.in.in.h:14
msgid "" msgid ""
"Internally used to store the last session presence status for the user. The " "Internally used to store the last session presence status for the user. The "
"value here is from the GsmPresenceStatus enumeration." "value here is from the GsmPresenceStatus enumeration."
@ -160,11 +168,11 @@ msgstr ""
"používateľa. Táto hodnota je z vymenovaných hodnôt typu " "používateľa. Táto hodnota je z vymenovaných hodnôt typu "
"GsmPresenceStatusType." "GsmPresenceStatusType."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:13 #: ../data/org.gnome.shell.gschema.xml.in.in.h:15
msgid "Always show the 'Log out' menuitem in the user menu." msgid "Always show the 'Log out' menuitem in the user menu."
msgstr "Vždy zobraziť položku „Odhlásiť sa“ v ponuke používateľa" msgstr "Vždy zobraziť položku „Odhlásiť sa“ v ponuke používateľa"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:14 #: ../data/org.gnome.shell.gschema.xml.in.in.h:16
msgid "" msgid ""
"This key overrides the automatic hiding of the 'Log out' menuitem in single-" "This key overrides the automatic hiding of the 'Log out' menuitem in single-"
"user, single-session situations." "user, single-session situations."
@ -173,7 +181,7 @@ msgstr ""
"s jedným používateľom alebo jednou reláciou." "s jedným používateľom alebo jednou reláciou."
# summary # summary
#: ../data/org.gnome.shell.gschema.xml.in.in.h:15 #: ../data/org.gnome.shell.gschema.xml.in.in.h:17
msgid "" msgid ""
"Whether to remember password for mounting encrypted or remote filesystems" "Whether to remember password for mounting encrypted or remote filesystems"
msgstr "" msgstr ""
@ -181,7 +189,7 @@ msgstr ""
"prenosných súborových systémov" "prenosných súborových systémov"
# description # description
#: ../data/org.gnome.shell.gschema.xml.in.in.h:16 #: ../data/org.gnome.shell.gschema.xml.in.in.h:18
msgid "" msgid ""
"The shell will request a password when an encrypted device or a remote " "The shell will request a password when an encrypted device or a remote "
"filesystem is mounted. If the password can be saved for future use a " "filesystem is mounted. If the password can be saved for future use a "
@ -193,42 +201,34 @@ msgstr ""
"zobrazí sa zaškrtávacie pole „Zapamätať heslo“. Tento kľúč nastaví " "zobrazí sa zaškrtávacie pole „Zapamätať heslo“. Tento kľúč nastaví "
"predvolený stav zaškrtávacieho poľa." "predvolený stav zaškrtávacieho poľa."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:17 #: ../data/org.gnome.shell.gschema.xml.in.in.h:19
msgid "Show the week date in the calendar" msgid "Show the week date in the calendar"
msgstr "Zobraziť čísla týždňov v kalendári" msgstr "Zobraziť čísla týždňov v kalendári"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:18 #: ../data/org.gnome.shell.gschema.xml.in.in.h:20
msgid "If true, display the ISO week date in the calendar." msgid "If true, display the ISO week date in the calendar."
msgstr "" msgstr ""
"Ak je true, zobrazí v kalendári poradie dní v týždni podľa štandardu ISO." "Ak je true, zobrazí v kalendári poradie dní v týždni podľa štandardu ISO."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:19 #: ../data/org.gnome.shell.gschema.xml.in.in.h:21
msgid "Keybinding to open the application menu" msgid "Keybinding to open the application menu"
msgstr "Klávesová skratka na otvorenie ponuky aplikácií" msgstr "Klávesová skratka na otvorenie ponuky aplikácií"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:20 #: ../data/org.gnome.shell.gschema.xml.in.in.h:22
msgid "Keybinding to open the application menu." msgid "Keybinding to open the application menu."
msgstr "Klávesová skratka na otvorenie ponuky aplikácií." msgstr "Klávesová skratka na otvorenie ponuky aplikácií."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:21 #: ../data/org.gnome.shell.gschema.xml.in.in.h:23
msgid "Keybinding to open the \"Show Applications\" view" msgid "Keybinding to open the \"Show Applications\" view"
msgstr "Klávesová skratka na otvorenie pohľadu „Zobraziť aplikácie“" msgstr "Klávesová skratka na otvorenie pohľadu „Zobraziť aplikácie“"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:22 #: ../data/org.gnome.shell.gschema.xml.in.in.h:24
msgid "" msgid ""
"Keybinding to open the \"Show Applications\" view of the Activities Overview." "Keybinding to open the \"Show Applications\" view of the Activities Overview."
msgstr "" msgstr ""
"Klávesová skratka na otvorenie pohľadu „Zobraziť aplikácie“ v prehľade " "Klávesová skratka na otvorenie pohľadu „Zobraziť aplikácie“ v prehľade "
"aktivít." "aktivít."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:23
msgid "Keybinding to open the overview"
msgstr "Klávesová skratka na otvorenie prehľadu"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:24
msgid "Keybinding to open the Activities Overview."
msgstr "Klávesová skratka na otvorenie prehľadu aktivít."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:25 #: ../data/org.gnome.shell.gschema.xml.in.in.h:25
msgid "Keybinding to toggle the visibility of the message tray" msgid "Keybinding to toggle the visibility of the message tray"
msgstr "Klávesová skratka na prepnutie viditeľnosti lišty správ" msgstr "Klávesová skratka na prepnutie viditeľnosti lišty správ"
@ -384,7 +384,7 @@ msgstr "Rozšírenie"
msgid "Select an extension to configure using the combobox above." msgid "Select an extension to configure using the combobox above."
msgstr "Použitím ponuky vyberte rozšírenie na nastavenie" msgstr "Použitím ponuky vyberte rozšírenie na nastavenie"
#: ../js/gdm/loginDialog.js:371 #: ../js/gdm/loginDialog.js:405
msgid "Session…" msgid "Session…"
msgstr "Relácia…" msgstr "Relácia…"
@ -392,43 +392,36 @@ msgstr "Relácia…"
#. translators: this message is shown below the user list on the #. translators: this message is shown below the user list on the
#. login screen. It can be activated to reveal an entry for #. login screen. It can be activated to reveal an entry for
#. manually entering the username. #. manually entering the username.
#: ../js/gdm/loginDialog.js:601 #: ../js/gdm/loginDialog.js:630
msgid "Not listed?" msgid "Not listed?"
msgstr "Nie ste v zozname?" msgstr "Nie ste v zozname?"
#: ../js/gdm/loginDialog.js:776 ../js/ui/components/networkAgent.js:137 #: ../js/gdm/loginDialog.js:786 ../js/ui/components/networkAgent.js:137
#: ../js/ui/components/polkitAgent.js:161 ../js/ui/endSessionDialog.js:376 #: ../js/ui/components/polkitAgent.js:162 ../js/ui/endSessionDialog.js:375
#: ../js/ui/extensionDownloader.js:195 ../js/ui/shellMountOperation.js:399 #: ../js/ui/extensionDownloader.js:195 ../js/ui/shellMountOperation.js:399
#: ../js/ui/status/bluetooth.js:415 ../js/ui/unlockDialog.js:96 #: ../js/ui/status/bluetooth.js:415 ../js/ui/unlockDialog.js:99
#: ../js/ui/userMenu.js:938 #: ../js/ui/userMenu.js:938
msgid "Cancel" msgid "Cancel"
msgstr "Zrušiť" msgstr "Zrušiť"
#: ../js/gdm/loginDialog.js:791 #: ../js/gdm/loginDialog.js:802
msgctxt "button" msgctxt "button"
msgid "Sign In" msgid "Sign In"
msgstr "Prihlásiť sa" msgstr "Prihlásiť sa"
#: ../js/gdm/loginDialog.js:791 #: ../js/gdm/loginDialog.js:802
msgid "Next" msgid "Next"
msgstr "Ďalej" msgstr "Ďalej"
#. Translators: this message is shown below the username entry field
#. to clue the user in on how to login to the local network realm
#: ../js/gdm/loginDialog.js:888
#, c-format
msgid "(e.g., user or %s)"
msgstr "(napr., používateľ alebo %s)"
#. TTLS and PEAP are actually much more complicated, but this complication #. TTLS and PEAP are actually much more complicated, but this complication
#. is not visible here since we only care about phase2 authentication #. is not visible here since we only care about phase2 authentication
#. (and don't even care of which one) #. (and don't even care of which one)
#: ../js/gdm/loginDialog.js:892 ../js/ui/components/networkAgent.js:260 #: ../js/gdm/loginDialog.js:917 ../js/ui/components/networkAgent.js:260
#: ../js/ui/components/networkAgent.js:278 #: ../js/ui/components/networkAgent.js:278
msgid "Username: " msgid "Username: "
msgstr "Používateľské meno: " msgstr "Používateľské meno: "
#: ../js/gdm/loginDialog.js:1158 #: ../js/gdm/loginDialog.js:1173
msgid "Login Window" msgid "Login Window"
msgstr "Prihlasovacie okno" msgstr "Prihlasovacie okno"
@ -451,16 +444,21 @@ msgstr "Reštartovať"
msgid "Power Off" msgid "Power Off"
msgstr "Vypnúť" msgstr "Vypnúť"
#: ../js/gdm/util.js:247 #: ../js/gdm/util.js:249
msgid "Authentication error" msgid "Authentication error"
msgstr "Chyba pri overovaní totožnosti" msgstr "Chyba pri overovaní totožnosti"
#. Translators: this message is shown below the password entry field #. Translators: this message is shown below the password entry field
#. to indicate the user can swipe their finger instead #. to indicate the user can swipe their finger instead
#: ../js/gdm/util.js:364 #: ../js/gdm/util.js:366
msgid "(or swipe finger)" msgid "(or swipe finger)"
msgstr "(alebo prejdite prstom)" msgstr "(alebo prejdite prstom)"
#: ../js/gdm/util.js:391
#, c-format
msgid "(e.g., user or %s)"
msgstr "(napr., používateľ alebo %s)"
#: ../js/misc/util.js:97 #: ../js/misc/util.js:97
msgid "Command not found" msgid "Command not found"
msgstr "Príkaz nebol nájdený" msgstr "Príkaz nebol nájdený"
@ -476,23 +474,23 @@ msgstr "Nepodarilo sa analyzovať príkaz:"
msgid "Execution of '%s' failed:" msgid "Execution of '%s' failed:"
msgstr "Spustenie „%s“ zlyhalo:" msgstr "Spustenie „%s“ zlyhalo:"
#: ../js/ui/appDisplay.js:361 #: ../js/ui/appDisplay.js:349
msgid "Frequent" msgid "Frequent"
msgstr "Často používané" msgstr "Často používané"
#: ../js/ui/appDisplay.js:368 #: ../js/ui/appDisplay.js:356
msgid "All" msgid "All"
msgstr "Všetky" msgstr "Všetky"
#: ../js/ui/appDisplay.js:960 #: ../js/ui/appDisplay.js:914
msgid "New Window" msgid "New Window"
msgstr "Nové okno" msgstr "Nové okno"
#: ../js/ui/appDisplay.js:963 ../js/ui/dash.js:284 #: ../js/ui/appDisplay.js:917 ../js/ui/dash.js:284
msgid "Remove from Favorites" msgid "Remove from Favorites"
msgstr "Odstrániť z obľúbených" msgstr "Odstrániť z obľúbených"
#: ../js/ui/appDisplay.js:964 #: ../js/ui/appDisplay.js:918
msgid "Add to Favorites" msgid "Add to Favorites"
msgstr "Pridať do obľúbených" msgstr "Pridať do obľúbených"
@ -529,7 +527,7 @@ msgctxt "event list time"
msgid "%H\\u2236%M" msgid "%H\\u2236%M"
msgstr "%H\\u2236%M" msgstr "%H\\u2236%M"
#. Translators: Shown in calendar event list, if 12h format, #. Transators: Shown in calendar event list, if 12h format,
#. \u2236 is a ratio character, similar to : and \u2009 is #. \u2236 is a ratio character, similar to : and \u2009 is
#. a thin space #. a thin space
#: ../js/ui/calendar.js:77 #: ../js/ui/calendar.js:77
@ -631,35 +629,35 @@ msgid "S"
msgstr "So" msgstr "So"
#. Translators: Text to show if there are no events #. Translators: Text to show if there are no events
#: ../js/ui/calendar.js:735 #: ../js/ui/calendar.js:720
msgid "Nothing Scheduled" msgid "Nothing Scheduled"
msgstr "Žiadne naplánované udalosti" msgstr "Žiadne naplánované udalosti"
#. Translators: Shown on calendar heading when selected day occurs on current year #. Translators: Shown on calendar heading when selected day occurs on current year
#: ../js/ui/calendar.js:751 #: ../js/ui/calendar.js:736
msgctxt "calendar heading" msgctxt "calendar heading"
msgid "%A, %B %d" msgid "%A, %B %d"
msgstr "%A, %e. %B" msgstr "%A, %e. %B"
#. Translators: Shown on calendar heading when selected day occurs on different year #. Translators: Shown on calendar heading when selected day occurs on different year
#: ../js/ui/calendar.js:754 #: ../js/ui/calendar.js:739
msgctxt "calendar heading" msgctxt "calendar heading"
msgid "%A, %B %d, %Y" msgid "%A, %B %d, %Y"
msgstr "%A, %e. %B %Y" msgstr "%A, %e. %B %Y"
#: ../js/ui/calendar.js:764 #: ../js/ui/calendar.js:749
msgid "Today" msgid "Today"
msgstr "Dnes" msgstr "Dnes"
#: ../js/ui/calendar.js:768 #: ../js/ui/calendar.js:753
msgid "Tomorrow" msgid "Tomorrow"
msgstr "Zajtra" msgstr "Zajtra"
#: ../js/ui/calendar.js:779 #: ../js/ui/calendar.js:764
msgid "This week" msgid "This week"
msgstr "Tento týždeň" msgstr "Tento týždeň"
#: ../js/ui/calendar.js:787 #: ../js/ui/calendar.js:772
msgid "Next week" msgid "Next week"
msgstr "Ďalší týždeň" msgstr "Ďalší týždeň"
@ -685,11 +683,11 @@ msgstr "Otvoriť pomocou programu %s"
msgid "Eject" msgid "Eject"
msgstr "Vysunúť" msgstr "Vysunúť"
#: ../js/ui/components/keyring.js:88 ../js/ui/components/polkitAgent.js:280 #: ../js/ui/components/keyring.js:82 ../js/ui/components/polkitAgent.js:268
msgid "Password:" msgid "Password:"
msgstr "Heslo:" msgstr "Heslo:"
#: ../js/ui/components/keyring.js:107 #: ../js/ui/components/keyring.js:101
msgid "Type again:" msgid "Type again:"
msgstr "Zadajte znovu:" msgstr "Zadajte znovu:"
@ -769,16 +767,16 @@ msgstr "Heslo k mobilnej sieti"
msgid "A password is required to connect to '%s'." msgid "A password is required to connect to '%s'."
msgstr "Na pripojenie k „%s“ sa požaduje heslo." msgstr "Na pripojenie k „%s“ sa požaduje heslo."
#: ../js/ui/components/polkitAgent.js:54 #: ../js/ui/components/polkitAgent.js:55
msgid "Authentication Required" msgid "Authentication Required"
msgstr "Požaduje sa overenie totožnosti" msgstr "Požaduje sa overenie totožnosti"
# PŠ: ináč toto je riadna hlúposť, keďže sa pýta heslo používateľa "root" # PŠ: ináč toto je riadna hlúposť, keďže sa pýta heslo používateľa "root"
#: ../js/ui/components/polkitAgent.js:92 #: ../js/ui/components/polkitAgent.js:93
msgid "Administrator" msgid "Administrator"
msgstr "Správca" msgstr "Správca"
#: ../js/ui/components/polkitAgent.js:170 #: ../js/ui/components/polkitAgent.js:165
msgid "Authenticate" msgid "Authenticate"
msgstr "Overiť totožnosť" msgstr "Overiť totožnosť"
@ -786,13 +784,13 @@ msgstr "Overiť totožnosť"
#. * requested authentication was not gained; this can happen #. * requested authentication was not gained; this can happen
#. * because of an authentication error (like invalid password), #. * because of an authentication error (like invalid password),
#. * for instance. #. * for instance.
#: ../js/ui/components/polkitAgent.js:266 ../js/ui/shellMountOperation.js:383 #: ../js/ui/components/polkitAgent.js:256 ../js/ui/shellMountOperation.js:383
msgid "Sorry, that didn't work. Please try again." msgid "Sorry, that didn't work. Please try again."
msgstr "Prepáčte, ale nezabralo to. Skúste to, prosím, znova." msgstr "Prepáčte, ale nezabralo to. Skúste to, prosím, znova."
# %d je datum, %t je cas # %d je datum, %t je cas
#. Translators: this is a filename used for screencast recording #. Translators: this is a filename used for screencast recording
#: ../js/ui/components/recorder.js:47 #: ../js/ui/components/recorder.js:48
#, no-c-format #, no-c-format
msgid "Screencast from %d %t" msgid "Screencast from %d %t"
msgstr "Záznam videa obrazovky dňa %d o %t" msgstr "Záznam videa obrazovky dňa %d o %t"
@ -1051,22 +1049,22 @@ msgstr "Zobrazí aplikácie"
msgid "Dash" msgid "Dash"
msgstr "Dok" msgstr "Dok"
#: ../js/ui/dateMenu.js:86 #: ../js/ui/dateMenu.js:91
msgid "Open Calendar" msgid "Open Calendar"
msgstr "Otvoriť kalendár" msgstr "Otvoriť kalendár"
#: ../js/ui/dateMenu.js:90 #: ../js/ui/dateMenu.js:96
msgid "Open Clocks" msgid "Open Clocks"
msgstr "Otvoriť hodiny" msgstr "Otvoriť hodiny"
#: ../js/ui/dateMenu.js:97 #: ../js/ui/dateMenu.js:105
msgid "Date & Time Settings" msgid "Date & Time Settings"
msgstr "Nastavenia dátumu a času" msgstr "Nastavenia dátumu a času"
#. Translators: This is the date format to use when the calendar popup is #. Translators: This is the date format to use when the calendar popup is
#. * shown - it is shown just below the time in the shell (e.g. "Tue 9:29 AM"). #. * shown - it is shown just below the time in the shell (e.g. "Tue 9:29 AM").
#. #.
#: ../js/ui/dateMenu.js:208 #: ../js/ui/dateMenu.js:215
msgid "%A %B %e, %Y" msgid "%A %B %e, %Y"
msgstr "%A, %e. %B %Y" msgstr "%A, %e. %B %Y"
@ -1180,52 +1178,50 @@ msgstr "Stiahnuť a nainštalovať „%s“ z extensions.gnome.org?"
msgid "Keyboard" msgid "Keyboard"
msgstr "Klávesnica" msgstr "Klávesnica"
#: ../js/ui/lookingGlass.js:689 #: ../js/ui/lookingGlass.js:693
msgid "No extensions installed" msgid "No extensions installed"
msgstr "Žiadne nainštalované rozšírenia" msgstr "Žiadne nainštalované rozšírenia"
#. Translators: argument is an extension UUID. #. Translators: argument is an extension UUID.
#: ../js/ui/lookingGlass.js:743 #: ../js/ui/lookingGlass.js:747
#, c-format #, c-format
msgid "%s has not emitted any errors." msgid "%s has not emitted any errors."
msgstr "%s nevyslal žiadnu chybu." msgstr "%s nevyslal žiadnu chybu."
#: ../js/ui/lookingGlass.js:749 #: ../js/ui/lookingGlass.js:753
msgid "Hide Errors" msgid "Hide Errors"
msgstr "Skryť chyby" msgstr "Skryť chyby"
#: ../js/ui/lookingGlass.js:753 ../js/ui/lookingGlass.js:813 #: ../js/ui/lookingGlass.js:757 ../js/ui/lookingGlass.js:817
msgid "Show Errors" msgid "Show Errors"
msgstr "Zobraziť chyby" msgstr "Zobraziť chyby"
#: ../js/ui/lookingGlass.js:762 #: ../js/ui/lookingGlass.js:766
msgid "Enabled" msgid "Enabled"
msgstr "Povolené" msgstr "Povolené"
#. translators: #: ../js/ui/lookingGlass.js:769
#. * The device has been disabled
#: ../js/ui/lookingGlass.js:765 ../src/gvc/gvc-mixer-control.c:1830
msgid "Disabled" msgid "Disabled"
msgstr "Zakázané" msgstr "Zakázané"
#: ../js/ui/lookingGlass.js:767 #: ../js/ui/lookingGlass.js:771
msgid "Error" msgid "Error"
msgstr "Chyba" msgstr "Chyba"
#: ../js/ui/lookingGlass.js:769 #: ../js/ui/lookingGlass.js:773
msgid "Out of date" msgid "Out of date"
msgstr "Neaktuálne" msgstr "Neaktuálne"
#: ../js/ui/lookingGlass.js:771 #: ../js/ui/lookingGlass.js:775
msgid "Downloading" msgid "Downloading"
msgstr "Sťahuje sa" msgstr "Sťahuje sa"
# PK: ide tu o zdrojovy kod? # PK: ide tu o zdrojovy kod?
#: ../js/ui/lookingGlass.js:795 #: ../js/ui/lookingGlass.js:799
msgid "View Source" msgid "View Source"
msgstr "Zobraziť zdroj" msgstr "Zobraziť zdroj"
#: ../js/ui/lookingGlass.js:804 #: ../js/ui/lookingGlass.js:808
msgid "Web Page" msgid "Web Page"
msgstr "Webová stránka" msgstr "Webová stránka"
@ -1245,26 +1241,26 @@ msgstr "Vymazať správy"
msgid "Notification Settings" msgid "Notification Settings"
msgstr "Nastavenia oznámení" msgstr "Nastavenia oznámení"
#: ../js/ui/messageTray.js:1707 #: ../js/ui/messageTray.js:1709
msgid "No Messages" msgid "No Messages"
msgstr "Žiadne správy" msgstr "Žiadne správy"
# DK: zvazoval som pouzit "Panel správ" # DK: zvazoval som pouzit "Panel správ"
# neviem co bude vhodnejsie ako preklad "tray" # neviem co bude vhodnejsie ako preklad "tray"
#: ../js/ui/messageTray.js:1780 #: ../js/ui/messageTray.js:1782
msgid "Message Tray" msgid "Message Tray"
msgstr "Lišta správ" msgstr "Lišta správ"
#: ../js/ui/messageTray.js:2800 #: ../js/ui/messageTray.js:2810
msgid "System Information" msgid "System Information"
msgstr "Informácie o systéme" msgstr "Informácie o systéme"
#: ../js/ui/notificationDaemon.js:629 ../src/shell-app.c:378 #: ../js/ui/notificationDaemon.js:629 ../src/shell-app.c:374
msgctxt "program" msgctxt "program"
msgid "Unknown" msgid "Unknown"
msgstr "Neznámy" msgstr "Neznámy"
#: ../js/ui/overviewControls.js:472 ../js/ui/screenShield.js:150 #: ../js/ui/overviewControls.js:463 ../js/ui/screenShield.js:149
#, c-format #, c-format
msgid "%d new message" msgid "%d new message"
msgid_plural "%d new messages" msgid_plural "%d new messages"
@ -1272,11 +1268,11 @@ msgstr[0] "%d nových správ"
msgstr[1] "%d nová správa" msgstr[1] "%d nová správa"
msgstr[2] "%d nové správy" msgstr[2] "%d nové správy"
#: ../js/ui/overview.js:82 #: ../js/ui/overview.js:84
msgid "Undo" msgid "Undo"
msgstr "Vrátiť" msgstr "Vrátiť"
#: ../js/ui/overview.js:127 #: ../js/ui/overview.js:129
msgid "Overview" msgid "Overview"
msgstr "Prehľad" msgstr "Prehľad"
@ -1285,21 +1281,21 @@ msgstr "Prehľad"
#. in the search entry when no search is #. in the search entry when no search is
#. active; it should not exceed ~30 #. active; it should not exceed ~30
#. characters. #. characters.
#: ../js/ui/overview.js:258 #: ../js/ui/overview.js:271
msgid "Type to search…" msgid "Type to search…"
msgstr "Zadajte text na vyhľadanie…" msgstr "Zadajte text na vyhľadanie…"
#: ../js/ui/panel.js:642 #: ../js/ui/panel.js:612
msgid "Quit" msgid "Quit"
msgstr "Ukončiť" msgstr "Ukončiť"
#. Translators: If there is no suitable word for "Activities" #. Translators: If there is no suitable word for "Activities"
#. in your language, you can use the word for "Overview". #. in your language, you can use the word for "Overview".
#: ../js/ui/panel.js:693 #: ../js/ui/panel.js:636
msgid "Activities" msgid "Activities"
msgstr "Aktivity" msgstr "Aktivity"
#: ../js/ui/panel.js:989 #: ../js/ui/panel.js:933
msgid "Top Bar" msgid "Top Bar"
msgstr "Horná lišta" msgstr "Horná lišta"
@ -1308,15 +1304,15 @@ msgstr "Horná lišta"
#. "ON" and "OFF") or "toggle-switch-intl" (for toggle #. "ON" and "OFF") or "toggle-switch-intl" (for toggle
#. switches containing "◯" and "|"). Other values will #. switches containing "◯" and "|"). Other values will
#. simply result in invisible toggle switches. #. simply result in invisible toggle switches.
#: ../js/ui/popupMenu.js:738 #: ../js/ui/popupMenu.js:727
msgid "toggle-switch-us" msgid "toggle-switch-us"
msgstr "toggle-switch-intl" msgstr "toggle-switch-intl"
#: ../js/ui/runDialog.js:74 #: ../js/ui/runDialog.js:73
msgid "Enter a Command" msgid "Enter a Command"
msgstr "Zadajte príkaz" msgstr "Zadajte príkaz"
#: ../js/ui/runDialog.js:110 #: ../js/ui/runDialog.js:109
msgid "Close" msgid "Close"
msgstr "Zavrieť" msgstr "Zavrieť"
@ -1325,11 +1321,11 @@ msgstr "Zavrieť"
# v ostatnych retazcoch je pouzite %e, tak to bude asi OK # v ostatnych retazcoch je pouzite %e, tak to bude asi OK
#. Translators: This is a time format for a date in #. Translators: This is a time format for a date in
#. long format #. long format
#: ../js/ui/screenShield.js:87 #: ../js/ui/screenShield.js:86
msgid "%A, %B %d" msgid "%A, %B %d"
msgstr "%A, %e. %B" msgstr "%A, %e. %B"
#: ../js/ui/screenShield.js:152 #: ../js/ui/screenShield.js:151
#, c-format #, c-format
msgid "%d new notification" msgid "%d new notification"
msgid_plural "%d new notifications" msgid_plural "%d new notifications"
@ -1337,11 +1333,11 @@ msgstr[0] "%d nových oznámení"
msgstr[1] "%d nové oznámenie" msgstr[1] "%d nové oznámenie"
msgstr[2] "%d nové oznámenia" msgstr[2] "%d nové oznámenia"
#: ../js/ui/screenShield.js:449 ../js/ui/userMenu.js:807 #: ../js/ui/screenShield.js:438 ../js/ui/userMenu.js:807
msgid "Lock" msgid "Lock"
msgstr "Uzamknúť" msgstr "Uzamknúť"
#: ../js/ui/screenShield.js:652 #: ../js/ui/screenShield.js:637
msgid "GNOME needs to lock the screen" msgid "GNOME needs to lock the screen"
msgstr "Prostredie GNOME vyžaduje uzamknutie obrazovky" msgstr "Prostredie GNOME vyžaduje uzamknutie obrazovky"
@ -1352,11 +1348,11 @@ msgstr "Prostredie GNOME vyžaduje uzamknutie obrazovky"
#. #.
#. XXX: another option is to kick the user into the gdm login #. XXX: another option is to kick the user into the gdm login
#. screen, where we're not affected by grabs #. screen, where we're not affected by grabs
#: ../js/ui/screenShield.js:773 ../js/ui/screenShield.js:1213 #: ../js/ui/screenShield.js:758 ../js/ui/screenShield.js:1194
msgid "Unable to lock" msgid "Unable to lock"
msgstr "Nepodarilo sa uzamknúť obrazovku" msgstr "Nepodarilo sa uzamknúť obrazovku"
#: ../js/ui/screenShield.js:774 ../js/ui/screenShield.js:1214 #: ../js/ui/screenShield.js:759 ../js/ui/screenShield.js:1195
msgid "Lock was blocked by an application" msgid "Lock was blocked by an application"
msgstr "Uzamknutie bolo zablokované aplikáciou" msgstr "Uzamknutie bolo zablokované aplikáciou"
@ -1368,19 +1364,19 @@ msgstr "Hľadá sa…"
msgid "No results." msgid "No results."
msgstr "Žiadne výsledky." msgstr "Žiadne výsledky."
#: ../js/ui/shellEntry.js:27 #: ../js/ui/shellEntry.js:29
msgid "Copy" msgid "Copy"
msgstr "Kopírovať" msgstr "Kopírovať"
#: ../js/ui/shellEntry.js:32 #: ../js/ui/shellEntry.js:34
msgid "Paste" msgid "Paste"
msgstr "Prilepiť" msgstr "Prilepiť"
#: ../js/ui/shellEntry.js:99 #: ../js/ui/shellEntry.js:106
msgid "Show Text" msgid "Show Text"
msgstr "Zobraziť text" msgstr "Zobraziť text"
#: ../js/ui/shellEntry.js:101 #: ../js/ui/shellEntry.js:108
msgid "Hide Text" msgid "Hide Text"
msgstr "Skryť text" msgstr "Skryť text"
@ -1392,7 +1388,7 @@ msgstr "Heslo"
msgid "Remember Password" msgid "Remember Password"
msgstr "Zapamätať heslo" msgstr "Zapamätať heslo"
#: ../js/ui/shellMountOperation.js:403 ../js/ui/unlockDialog.js:109 #: ../js/ui/shellMountOperation.js:403 ../js/ui/unlockDialog.js:113
msgid "Unlock" msgid "Unlock"
msgstr "Odblokovať" msgstr "Odblokovať"
@ -1450,7 +1446,7 @@ msgstr "Veľký text"
#: ../js/ui/status/bluetooth.js:28 ../js/ui/status/bluetooth.js:32 #: ../js/ui/status/bluetooth.js:28 ../js/ui/status/bluetooth.js:32
#: ../js/ui/status/bluetooth.js:289 ../js/ui/status/bluetooth.js:321 #: ../js/ui/status/bluetooth.js:289 ../js/ui/status/bluetooth.js:321
#: ../js/ui/status/bluetooth.js:357 ../js/ui/status/bluetooth.js:388 #: ../js/ui/status/bluetooth.js:357 ../js/ui/status/bluetooth.js:388
#: ../js/ui/status/network.js:739 #: ../js/ui/status/network.js:826
msgid "Bluetooth" msgid "Bluetooth"
msgstr "Bluetooth" msgstr "Bluetooth"
@ -1471,7 +1467,7 @@ msgid "Bluetooth Settings"
msgstr "Nastavenia Bluetooth" msgstr "Nastavenia Bluetooth"
#. TRANSLATORS: this means that bluetooth was disabled by hardware rfkill #. TRANSLATORS: this means that bluetooth was disabled by hardware rfkill
#: ../js/ui/status/bluetooth.js:104 ../js/ui/status/network.js:142 #: ../js/ui/status/bluetooth.js:104 ../js/ui/status/network.js:178
msgid "hardware disabled" msgid "hardware disabled"
msgstr "hardvér zakázaný" msgstr "hardvér zakázaný"
@ -1479,12 +1475,12 @@ msgstr "hardvér zakázaný"
msgid "Connection" msgid "Connection"
msgstr "Pripojenie" msgstr "Pripojenie"
#: ../js/ui/status/bluetooth.js:208 ../js/ui/status/network.js:404 #: ../js/ui/status/bluetooth.js:208 ../js/ui/status/network.js:460
msgid "disconnecting..." msgid "disconnecting..."
msgstr "odpája sa…" msgstr "odpája sa…"
#: ../js/ui/status/bluetooth.js:221 ../js/ui/status/network.js:410 #: ../js/ui/status/bluetooth.js:221 ../js/ui/status/network.js:466
#: ../js/ui/status/network.js:1343 #: ../js/ui/status/network.js:1546
msgid "connecting..." msgid "connecting..."
msgstr "pripája sa…" msgstr "pripája sa…"
@ -1540,9 +1536,8 @@ msgstr "Zariadenie %s sa chce spárovať s týmto počítačom"
#: ../js/ui/status/bluetooth.js:366 #: ../js/ui/status/bluetooth.js:366
#, c-format #, c-format
msgid "" msgid "Please confirm whether the PIN '%06d' matches the one on the device."
"Please confirm whether the Passkey '%06d' matches the one on the device." msgstr "Prosím, potvrďte, či sa PIN „%06d“ zhoduje s tým na zariadení."
msgstr "Prosím, potvrďte, či sa heslo „%06d“ zhoduje s tým na zariadení."
#. Translators: this is the verb, not the noun #. Translators: this is the verb, not the noun
#: ../js/ui/status/bluetooth.js:369 #: ../js/ui/status/bluetooth.js:369
@ -1579,91 +1574,117 @@ msgid "Volume, network, battery"
msgstr "Hlasitosť, sieť, batéria" msgstr "Hlasitosť, sieť, batéria"
# zariadenie # zariadenie
#: ../js/ui/status/network.js:75 #: ../js/ui/status/network.js:104
msgid "<unknown>" msgid "<unknown>"
msgstr "<neznáme>" msgstr "<neznáme>"
#: ../js/ui/status/network.js:127
msgid "Wi-Fi"
msgstr "Wi-Fi"
#. Translators: this indicates that wireless or wwan is disabled by hardware killswitch #. Translators: this indicates that wireless or wwan is disabled by hardware killswitch
#: ../js/ui/status/network.js:164 #: ../js/ui/status/network.js:200
msgid "disabled" msgid "disabled"
msgstr "zakázané" msgstr "zakázané"
#. Translators: this is for network devices that are physically present but are not #. Translators: this is for network devices that are physically present but are not
#. under NetworkManager's control (and thus cannot be used in the menu) #. under NetworkManager's control (and thus cannot be used in the menu)
#: ../js/ui/status/network.js:402 #: ../js/ui/status/network.js:458
msgid "unmanaged" msgid "unmanaged"
msgstr "nespravované" msgstr "nespravované"
#. Translators: this is for network connections that require some kind of key or password #. Translators: this is for network connections that require some kind of key or password
#: ../js/ui/status/network.js:413 ../js/ui/status/network.js:1346 #: ../js/ui/status/network.js:469 ../js/ui/status/network.js:1549
msgid "authentication required" msgid "authentication required"
msgstr "požaduje sa overenie totožnosti" msgstr "požaduje sa overenie totožnosti"
#. Translators: this is for devices that require some kind of firmware or kernel #. Translators: this is for devices that require some kind of firmware or kernel
#. module, which is missing #. module, which is missing
#: ../js/ui/status/network.js:423 #: ../js/ui/status/network.js:479
msgid "firmware missing" msgid "firmware missing"
msgstr "chýba firmvér" msgstr "chýba firmvér"
#. Translators: this is for wired network devices that are physically disconnected #. Translators: this is for wired network devices that are physically disconnected
#: ../js/ui/status/network.js:430 #: ../js/ui/status/network.js:486
msgid "cable unplugged" msgid "cable unplugged"
msgstr "kábel odpojený" msgstr "kábel odpojený"
#. Translators: this is for a network device that cannot be activated (for example it #. Translators: this is for a network device that cannot be activated (for example it
#. is disabled by rfkill, or it has no coverage #. is disabled by rfkill, or it has no coverage
#: ../js/ui/status/network.js:435 #: ../js/ui/status/network.js:491
msgid "unavailable" msgid "unavailable"
msgstr "nedostupné" msgstr "nedostupné"
#: ../js/ui/status/network.js:437 ../js/ui/status/network.js:1348 #: ../js/ui/status/network.js:493 ../js/ui/status/network.js:1551
msgid "connection failed" msgid "connection failed"
msgstr "pripojenie zlyhalo" msgstr "pripojenie zlyhalo"
#: ../js/ui/status/network.js:490 ../js/ui/status/network.js:1236 #: ../js/ui/status/network.js:552 ../js/ui/status/network.js:1435
#: ../js/ui/status/network.js:1424 #: ../js/ui/status/network.js:1627
msgid "More…" msgid "More…"
msgstr "Viac…" msgstr "Viac…"
#. TRANSLATORS: this is the indication that a connection for another logged in user is active, #. TRANSLATORS: this is the indication that a connection for another logged in user is active,
#. and we cannot access its settings (including the name) #. and we cannot access its settings (including the name)
#: ../js/ui/status/network.js:518 ../js/ui/status/network.js:1191 #: ../js/ui/status/network.js:588 ../js/ui/status/network.js:1365
msgid "Connected (private)" msgid "Connected (private)"
msgstr "Pripojené (súkromne)" msgstr "Pripojené (súkromne)"
#: ../js/ui/status/network.js:597 #: ../js/ui/status/network.js:667
msgid "Wired" msgid "Wired"
msgstr "Drôtové pripojenie" msgstr "Drôtové pripojenie"
#: ../js/ui/status/network.js:611 #: ../js/ui/status/network.js:668
msgid "Auto Ethernet"
msgstr "Automatický ethernet"
#: ../js/ui/status/network.js:695
msgid "Mobile broadband" msgid "Mobile broadband"
msgstr "Širokopásmové pripojenie" msgstr "Širokopásmové pripojenie"
#: ../js/ui/status/network.js:1522 #: ../js/ui/status/network.js:728
msgid "Auto broadband"
msgstr "Automatické širokopásmové pripojenie"
#: ../js/ui/status/network.js:731
msgid "Auto dial-up"
msgstr "Automatické vytáčané pripojenie"
#. TRANSLATORS: this the automatic wireless connection name (including the network name)
#: ../js/ui/status/network.js:861 ../js/ui/status/network.js:1382
#, c-format
msgid "Auto %s"
msgstr "Automatické pripojenie %s"
#: ../js/ui/status/network.js:863
msgid "Auto bluetooth"
msgstr "Automatický bluetooth"
#: ../js/ui/status/network.js:1384
msgid "Auto wireless"
msgstr "Automatická bezdrôtová sieť"
#: ../js/ui/status/network.js:1729
msgid "Enable networking" msgid "Enable networking"
msgstr "Povoliť sieť" msgstr "Povoliť sieť"
#: ../js/ui/status/network.js:1583 #: ../js/ui/status/network.js:1771
msgid "Wi-Fi"
msgstr "Wi-Fi"
#: ../js/ui/status/network.js:1790
msgid "Network Settings" msgid "Network Settings"
msgstr "Nastavenia siete" msgstr "Nastavenia siete"
#: ../js/ui/status/network.js:1600 #: ../js/ui/status/network.js:1807
msgid "Network Manager" msgid "Network Manager"
msgstr "Správca siete" msgstr "Správca siete"
#: ../js/ui/status/network.js:1690 #: ../js/ui/status/network.js:1897
msgid "Connection failed" msgid "Connection failed"
msgstr "Pripojenie zlyhalo" msgstr "Pripojenie zlyhalo"
#: ../js/ui/status/network.js:1691 #: ../js/ui/status/network.js:1898
msgid "Activation of network connection failed" msgid "Activation of network connection failed"
msgstr "Aktivácia pripojenia k sieti zlyhala" msgstr "Aktivácia pripojenia k sieti zlyhala"
#: ../js/ui/status/network.js:2047 #: ../js/ui/status/network.js:2276
msgid "Networking is disabled" msgid "Networking is disabled"
msgstr "Sieť je zakázaná" msgstr "Sieť je zakázaná"
@ -1781,11 +1802,11 @@ msgstr "Hlasitosť"
msgid "Microphone" msgid "Microphone"
msgstr "Mikrofón" msgstr "Mikrofón"
#: ../js/ui/unlockDialog.js:120 #: ../js/ui/unlockDialog.js:124
msgid "Log in as another user" msgid "Log in as another user"
msgstr "Prihlásiť ako iný používateľ" msgstr "Prihlásiť ako iný používateľ"
#: ../js/ui/unlockDialog.js:141 #: ../js/ui/unlockDialog.js:145
msgid "Unlock Window" msgid "Unlock Window"
msgstr "Odomykacie okno" msgstr "Odomykacie okno"
@ -1894,56 +1915,32 @@ msgstr "Program „%s“ je pripravený"
msgid "Evolution Calendar" msgid "Evolution Calendar"
msgstr "Kalendár Evolution" msgstr "Kalendár Evolution"
#. translators: #: ../src/main.c:347
#. * The number of sound outputs on a particular device
#: ../src/gvc/gvc-mixer-control.c:1837
#, c-format
msgid "%u Output"
msgid_plural "%u Outputs"
msgstr[0] "%u výstupov"
msgstr[1] "%u výstup"
msgstr[2] "%u výstupy"
#. translators:
#. * The number of sound inputs on a particular device
#: ../src/gvc/gvc-mixer-control.c:1847
#, c-format
msgid "%u Input"
msgid_plural "%u Inputs"
msgstr[0] "%u vstupov"
msgstr[1] "%u vstup"
msgstr[2] "%u vstupy"
#: ../src/gvc/gvc-mixer-control.c:2373
msgid "System Sounds"
msgstr "Systémové zvuky"
#: ../src/main.c:372
msgid "Print version" msgid "Print version"
msgstr "Verzia pre tlač" msgstr "Verzia pre tlač"
#: ../src/main.c:378 #: ../src/main.c:353
msgid "Mode used by GDM for login screen" msgid "Mode used by GDM for login screen"
msgstr "Režim používaný GDM pre prihlasovaciu obrazovku" msgstr "Režim používaný GDM pre prihlasovaciu obrazovku"
#: ../src/main.c:384 #: ../src/main.c:359
msgid "Use a specific mode, e.g. \"gdm\" for login screen" msgid "Use a specific mode, e.g. \"gdm\" for login screen"
msgstr "Použitie zvláštneho režimu, napr. „gdm“ pre prihlasovaciu obrazovku" msgstr "Použitie zvláštneho režimu, napr. „gdm“ pre prihlasovaciu obrazovku"
#: ../src/main.c:390 #: ../src/main.c:365
msgid "List possible modes" msgid "List possible modes"
msgstr "Zoznam možných režimov" msgstr "Zoznam možných režimov"
#: ../src/shell-app.c:626 #: ../src/shell-app.c:622
#, c-format #, c-format
msgid "Failed to launch '%s'" msgid "Failed to launch '%s'"
msgstr "Zlyhalo spustenie „%s“" msgstr "Zlyhalo spustenie „%s“"
#: ../src/shell-keyring-prompt.c:714 #: ../src/shell-keyring-prompt.c:708
msgid "Passwords do not match." msgid "Passwords do not match."
msgstr "Heslá sa nezhodujú." msgstr "Heslá sa nezhodujú."
#: ../src/shell-keyring-prompt.c:722 #: ../src/shell-keyring-prompt.c:716
msgid "Password cannot be blank" msgid "Password cannot be blank"
msgstr "Heslo nemôže byť prázdne" msgstr "Heslo nemôže byť prázdne"
@ -1951,35 +1948,3 @@ msgstr "Heslo nemôže byť prázdne"
#: ../src/shell-polkit-authentication-agent.c:343 #: ../src/shell-polkit-authentication-agent.c:343
msgid "Authentication dialog was dismissed by the user" msgid "Authentication dialog was dismissed by the user"
msgstr "Dialógové okno overenia totožnosti bolo zatvorené používateľom" msgstr "Dialógové okno overenia totožnosti bolo zatvorené používateľom"
#~ msgid "Whether to collect stats about applications usage"
#~ msgstr "Či sa majú zhromažďovať štatistické údaje o používaní aplikácií"
#~ msgid ""
#~ "The shell normally monitors active applications in order to present the "
#~ "most used ones (e.g. in launchers). While this data will be kept private, "
#~ "you may want to disable this for privacy reasons. Please note that doing "
#~ "so won't remove already saved data."
#~ msgstr ""
#~ "Prostredie shell obvykle sleduje aktívne aplikácie, aby mohlo ponúkať "
#~ "najpoužívanejšie z nich (napr. v spúšťačoch). Aj keď sú tieto údaje "
#~ "uchovávané v tajnosti, môžete ich kvôli lepšej ochrane súkromia zakázať. "
#~ "Ak tak urobíte, údaje, ktoré už boli uložené, zostanú zachované."
#~ msgid "Auto Ethernet"
#~ msgstr "Automatický ethernet"
#~ msgid "Auto broadband"
#~ msgstr "Automatické širokopásmové pripojenie"
#~ msgid "Auto dial-up"
#~ msgstr "Automatické vytáčané pripojenie"
#~ msgid "Auto %s"
#~ msgstr "Automatické pripojenie %s"
#~ msgid "Auto bluetooth"
#~ msgstr "Automatický bluetooth"
#~ msgid "Auto wireless"
#~ msgstr "Automatická bezdrôtová sieť"

407
po/sl.po

File diff suppressed because it is too large Load Diff

163
po/sr.po
View File

@ -8,7 +8,7 @@ msgstr ""
"Project-Id-Version: gnome-shell master\n" "Project-Id-Version: gnome-shell master\n"
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-" "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-"
"shell&keywords=I18N+L10N&component=general\n" "shell&keywords=I18N+L10N&component=general\n"
"POT-Creation-Date: 2013-03-31 01:48+0000\n" "POT-Creation-Date: 2013-03-04 08:38+0000\n"
"PO-Revision-Date: 2013-03-08 20:26+0200\n" "PO-Revision-Date: 2013-03-08 20:26+0200\n"
"Last-Translator: Мирослав Николић <miroslavnikolic@rocketmail.com>\n" "Last-Translator: Мирослав Николић <miroslavnikolic@rocketmail.com>\n"
"Language-Team: Serbian <gnom@prevod.org>\n" "Language-Team: Serbian <gnom@prevod.org>\n"
@ -16,8 +16,8 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=4; plural=n==1? 3 : n%10==1 && n%100!=11 ? 0 : n" "Plural-Forms: nplurals=4; plural=n==1? 3 : n%10==1 && n%100!=11 ? 0 : "
"%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" "n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
"X-Project-Style: gnome\n" "X-Project-Style: gnome\n"
#: ../data/50-gnome-shell-screenshot.xml.in.h:1 #: ../data/50-gnome-shell-screenshot.xml.in.h:1
@ -365,52 +365,53 @@ msgid "Select an extension to configure using the combobox above."
msgstr "Изаберите проширење за подешавање користећи прозорче за избор." msgstr "Изаберите проширење за подешавање користећи прозорче за избор."
#: ../js/gdm/loginDialog.js:405 #: ../js/gdm/loginDialog.js:405
#| msgid "Session..."
msgid "Session…" msgid "Session…"
msgstr "Сесија…" msgstr "Сесија…"
#. translators: this message is shown below the user list on the #. translators: this message is shown below the user list on the
#. login screen. It can be activated to reveal an entry for #. login screen. It can be activated to reveal an entry for
#. manually entering the username. #. manually entering the username.
#: ../js/gdm/loginDialog.js:630 #: ../js/gdm/loginDialog.js:629
msgid "Not listed?" msgid "Not listed?"
msgstr "Није на списку?" msgstr "Није на списку?"
#: ../js/gdm/loginDialog.js:786 ../js/ui/components/networkAgent.js:137 #: ../js/gdm/loginDialog.js:783 ../js/ui/components/networkAgent.js:137
#: ../js/ui/components/polkitAgent.js:162 ../js/ui/endSessionDialog.js:375 #: ../js/ui/components/polkitAgent.js:162 ../js/ui/endSessionDialog.js:375
#: ../js/ui/extensionDownloader.js:195 ../js/ui/shellMountOperation.js:399 #: ../js/ui/extensionDownloader.js:195 ../js/ui/shellMountOperation.js:399
#: ../js/ui/status/bluetooth.js:415 ../js/ui/unlockDialog.js:99 #: ../js/ui/status/bluetooth.js:415 ../js/ui/unlockDialog.js:126
#: ../js/ui/userMenu.js:938 #: ../js/ui/userMenu.js:934
msgid "Cancel" msgid "Cancel"
msgstr "Откажи" msgstr "Откажи"
#: ../js/gdm/loginDialog.js:802 #: ../js/gdm/loginDialog.js:799
msgctxt "button" msgctxt "button"
msgid "Sign In" msgid "Sign In"
msgstr "Пријави ме" msgstr "Пријави ме"
#: ../js/gdm/loginDialog.js:802 #: ../js/gdm/loginDialog.js:799
msgid "Next" msgid "Next"
msgstr "Даље" msgstr "Даље"
#. TTLS and PEAP are actually much more complicated, but this complication #. TTLS and PEAP are actually much more complicated, but this complication
#. is not visible here since we only care about phase2 authentication #. is not visible here since we only care about phase2 authentication
#. (and don't even care of which one) #. (and don't even care of which one)
#: ../js/gdm/loginDialog.js:917 ../js/ui/components/networkAgent.js:260 #: ../js/gdm/loginDialog.js:904 ../js/ui/components/networkAgent.js:260
#: ../js/ui/components/networkAgent.js:278 #: ../js/ui/components/networkAgent.js:278
msgid "Username: " msgid "Username: "
msgstr "Корисничко име: " msgstr "Корисничко име: "
#: ../js/gdm/loginDialog.js:1173 #: ../js/gdm/loginDialog.js:1157
msgid "Login Window" msgid "Login Window"
msgstr "Прозор за пријављивање" msgstr "Прозор за пријављивање"
#. Translators: accessible name of the power menu in the login screen #. Translators: accessible name of the power menu in the login screen
#: ../js/gdm/powerMenu.js:36 #: ../js/gdm/powerMenu.js:36
msgid "Power" msgid "Power"
msgstr "Напајање" msgstr "Угаси"
#: ../js/gdm/powerMenu.js:93 ../js/ui/userMenu.js:696 ../js/ui/userMenu.js:700 #: ../js/gdm/powerMenu.js:93 ../js/ui/userMenu.js:695 ../js/ui/userMenu.js:699
#: ../js/ui/userMenu.js:816 #: ../js/ui/userMenu.js:815
msgid "Suspend" msgid "Suspend"
msgstr "Обустави" msgstr "Обустави"
@ -418,58 +419,58 @@ msgstr "Обустави"
msgid "Restart" msgid "Restart"
msgstr "Поново покрени" msgstr "Поново покрени"
#: ../js/gdm/powerMenu.js:103 ../js/ui/userMenu.js:698 #: ../js/gdm/powerMenu.js:103 ../js/ui/userMenu.js:697
#: ../js/ui/userMenu.js:700 ../js/ui/userMenu.js:815 ../js/ui/userMenu.js:942 #: ../js/ui/userMenu.js:699 ../js/ui/userMenu.js:814 ../js/ui/userMenu.js:938
msgid "Power Off" msgid "Power Off"
msgstr "Искључи" msgstr "Угаси"
#: ../js/gdm/util.js:249 #: ../js/gdm/util.js:182
msgid "Authentication error" msgid "Authentication error"
msgstr "Грешка потврђивања идентитета" msgstr "Грешка потврђивања идентитета"
#. Translators: this message is shown below the password entry field #. Translators: this message is shown below the password entry field
#. to indicate the user can swipe their finger instead #. to indicate the user can swipe their finger instead
#: ../js/gdm/util.js:366 #: ../js/gdm/util.js:299
msgid "(or swipe finger)" msgid "(or swipe finger)"
msgstr "(или лупите прст)" msgstr "(или лупите прст)"
#: ../js/gdm/util.js:391 #: ../js/gdm/util.js:324
#, c-format #, c-format
msgid "(e.g., user or %s)" msgid "(e.g., user or %s)"
msgstr "(нпр., корисник или %s)" msgstr "(нпр., корисник или %s)"
#: ../js/misc/util.js:97 #: ../js/misc/util.js:94
msgid "Command not found" msgid "Command not found"
msgstr "Наредба није нађена" msgstr "Наредба није нађена"
#. Replace "Error invoking GLib.shell_parse_argv: " with #. Replace "Error invoking GLib.shell_parse_argv: " with
#. something nicer #. something nicer
#: ../js/misc/util.js:130 #: ../js/misc/util.js:127
msgid "Could not parse command:" msgid "Could not parse command:"
msgstr "Не могу да обрадим наредбу:" msgstr "Не могу да обрадим наредбу:"
#: ../js/misc/util.js:138 #: ../js/misc/util.js:135
#, c-format #, c-format
msgid "Execution of '%s' failed:" msgid "Execution of '%s' failed:"
msgstr "Није успело покретање „%s“:" msgstr "Није успело покретање „%s“:"
#: ../js/ui/appDisplay.js:349 #: ../js/ui/appDisplay.js:348
msgid "Frequent" msgid "Frequent"
msgstr "Често" msgstr "Често"
#: ../js/ui/appDisplay.js:356 #: ../js/ui/appDisplay.js:355
msgid "All" msgid "All"
msgstr "Све" msgstr "Све"
#: ../js/ui/appDisplay.js:914 #: ../js/ui/appDisplay.js:913
msgid "New Window" msgid "New Window"
msgstr "Нови прозор" msgstr "Нови прозор"
#: ../js/ui/appDisplay.js:917 ../js/ui/dash.js:284 #: ../js/ui/appDisplay.js:916 ../js/ui/dash.js:284
msgid "Remove from Favorites" msgid "Remove from Favorites"
msgstr "Уклони из омиљених" msgstr "Уклони из омиљених"
#: ../js/ui/appDisplay.js:918 #: ../js/ui/appDisplay.js:917
msgid "Add to Favorites" msgid "Add to Favorites"
msgstr "Додај у омиљене" msgstr "Додај у омиљене"
@ -483,7 +484,7 @@ msgstr "„%s“ је додат међу омиљене."
msgid "%s has been removed from your favorites." msgid "%s has been removed from your favorites."
msgstr "„%s“ је уклоњен из омиљених." msgstr "„%s“ је уклоњен из омиљених."
#: ../js/ui/backgroundMenu.js:19 ../js/ui/userMenu.js:789 #: ../js/ui/backgroundMenu.js:19 ../js/ui/userMenu.js:788
msgid "Settings" msgid "Settings"
msgstr "Подешавања" msgstr "Подешавања"
@ -506,7 +507,7 @@ msgctxt "event list time"
msgid "%H\\u2236%M" msgid "%H\\u2236%M"
msgstr "%H\\u2236%M" msgstr "%H\\u2236%M"
#. Translators: Shown in calendar event list, if 12h format, #. Transators: Shown in calendar event list, if 12h format,
#. \u2236 is a ratio character, similar to : and \u2009 is #. \u2236 is a ratio character, similar to : and \u2009 is
#. a thin space #. a thin space
#: ../js/ui/calendar.js:77 #: ../js/ui/calendar.js:77
@ -608,35 +609,35 @@ msgid "S"
msgstr "Суб" msgstr "Суб"
#. Translators: Text to show if there are no events #. Translators: Text to show if there are no events
#: ../js/ui/calendar.js:720 #: ../js/ui/calendar.js:692
msgid "Nothing Scheduled" msgid "Nothing Scheduled"
msgstr "Ништа планирано" msgstr "Ништа планирано"
#. Translators: Shown on calendar heading when selected day occurs on current year #. Translators: Shown on calendar heading when selected day occurs on current year
#: ../js/ui/calendar.js:736 #: ../js/ui/calendar.js:708
msgctxt "calendar heading" msgctxt "calendar heading"
msgid "%A, %B %d" msgid "%A, %B %d"
msgstr "%A, %B %d" msgstr "%A, %B %d"
#. Translators: Shown on calendar heading when selected day occurs on different year #. Translators: Shown on calendar heading when selected day occurs on different year
#: ../js/ui/calendar.js:739 #: ../js/ui/calendar.js:711
msgctxt "calendar heading" msgctxt "calendar heading"
msgid "%A, %B %d, %Y" msgid "%A, %B %d, %Y"
msgstr "%A, %B %d, %Y" msgstr "%A, %B %d, %Y"
#: ../js/ui/calendar.js:749 #: ../js/ui/calendar.js:721
msgid "Today" msgid "Today"
msgstr "Данас" msgstr "Данас"
#: ../js/ui/calendar.js:753 #: ../js/ui/calendar.js:725
msgid "Tomorrow" msgid "Tomorrow"
msgstr "Сутра" msgstr "Сутра"
#: ../js/ui/calendar.js:764 #: ../js/ui/calendar.js:736
msgid "This week" msgid "This week"
msgstr "Ове недеље" msgstr "Ове недеље"
#: ../js/ui/calendar.js:772 #: ../js/ui/calendar.js:744
msgid "Next week" msgid "Next week"
msgstr "Следеће недеље" msgstr "Следеће недеље"
@ -652,12 +653,12 @@ msgstr "Спољни уређај је искључен"
msgid "Removable Devices" msgid "Removable Devices"
msgstr "Уклоњиви уређаји" msgstr "Уклоњиви уређаји"
#: ../js/ui/components/autorunManager.js:594 #: ../js/ui/components/autorunManager.js:593
#, c-format #, c-format
msgid "Open with %s" msgid "Open with %s"
msgstr "Отвори програмом %s" msgstr "Отвори програмом %s"
#: ../js/ui/components/autorunManager.js:620 #: ../js/ui/components/autorunManager.js:619
msgid "Eject" msgid "Eject"
msgstr "Избаци" msgstr "Избаци"
@ -1037,7 +1038,7 @@ msgstr "Подешавања датума и времена"
#. Translators: This is the date format to use when the calendar popup is #. Translators: This is the date format to use when the calendar popup is
#. * shown - it is shown just below the time in the shell (e.g. "Tue 9:29 AM"). #. * shown - it is shown just below the time in the shell (e.g. "Tue 9:29 AM").
#. #.
#: ../js/ui/dateMenu.js:215 #: ../js/ui/dateMenu.js:205
msgid "%A %B %e, %Y" msgid "%A %B %e, %Y"
msgstr "%A, %e. %b., %R" msgstr "%A, %e. %b., %R"
@ -1212,6 +1213,7 @@ msgid "Remove"
msgstr "Уклони" msgstr "Уклони"
#: ../js/ui/messageTray.js:1501 #: ../js/ui/messageTray.js:1501
#| msgid "No Messages"
msgid "Clear Messages" msgid "Clear Messages"
msgstr "Очисти поруке" msgstr "Очисти поруке"
@ -1219,15 +1221,15 @@ msgstr "Очисти поруке"
msgid "Notification Settings" msgid "Notification Settings"
msgstr "Поставке обавештења" msgstr "Поставке обавештења"
#: ../js/ui/messageTray.js:1709 #: ../js/ui/messageTray.js:1707
msgid "No Messages" msgid "No Messages"
msgstr "Нема порука" msgstr "Нема порука"
#: ../js/ui/messageTray.js:1782 #: ../js/ui/messageTray.js:1787
msgid "Message Tray" msgid "Message Tray"
msgstr "Фиока порука" msgstr "Фиока порука"
#: ../js/ui/messageTray.js:2810 #: ../js/ui/messageTray.js:2864
msgid "System Information" msgid "System Information"
msgstr "Подаци о систему" msgstr "Подаци о систему"
@ -1236,7 +1238,7 @@ msgctxt "program"
msgid "Unknown" msgid "Unknown"
msgstr "Непознат" msgstr "Непознат"
#: ../js/ui/overviewControls.js:463 ../js/ui/screenShield.js:149 #: ../js/ui/overviewControls.js:460 ../js/ui/screenShield.js:153
#, c-format #, c-format
msgid "%d new message" msgid "%d new message"
msgid_plural "%d new messages" msgid_plural "%d new messages"
@ -1245,7 +1247,7 @@ msgstr[1] "%d нове поруке"
msgstr[2] "%d нових порука" msgstr[2] "%d нових порука"
msgstr[3] "Једна нова порука" msgstr[3] "Једна нова порука"
#: ../js/ui/overview.js:84 #: ../js/ui/overview.js:82
msgid "Undo" msgid "Undo"
msgstr "Опозови" msgstr "Опозови"
@ -1257,21 +1259,22 @@ msgstr "Преглед"
#. in the search entry when no search is #. in the search entry when no search is
#. active; it should not exceed ~30 #. active; it should not exceed ~30
#. characters. #. characters.
#: ../js/ui/overview.js:271 #: ../js/ui/overview.js:284
#| msgid "Type to search..."
msgid "Type to search…" msgid "Type to search…"
msgstr "Упишите текст за претрагу…" msgstr "Упишите текст за претрагу…"
#: ../js/ui/panel.js:612 #: ../js/ui/panel.js:613
msgid "Quit" msgid "Quit"
msgstr "Изађи" msgstr "Изађи"
#. Translators: If there is no suitable word for "Activities" #. Translators: If there is no suitable word for "Activities"
#. in your language, you can use the word for "Overview". #. in your language, you can use the word for "Overview".
#: ../js/ui/panel.js:636 #: ../js/ui/panel.js:642
msgid "Activities" msgid "Activities"
msgstr "Активности" msgstr "Активности"
#: ../js/ui/panel.js:933 #: ../js/ui/panel.js:983
msgid "Top Bar" msgid "Top Bar"
msgstr "Горња трака" msgstr "Горња трака"
@ -1284,21 +1287,21 @@ msgstr "Горња трака"
msgid "toggle-switch-us" msgid "toggle-switch-us"
msgstr "toggle-switch-intl" msgstr "toggle-switch-intl"
#: ../js/ui/runDialog.js:73 #: ../js/ui/runDialog.js:205
msgid "Enter a Command" msgid "Enter a Command"
msgstr "Унесите наредбу" msgstr "Унесите наредбу"
#: ../js/ui/runDialog.js:109 #: ../js/ui/runDialog.js:241
msgid "Close" msgid "Close"
msgstr "Затвори" msgstr "Затвори"
#. Translators: This is a time format for a date in #. Translators: This is a time format for a date in
#. long format #. long format
#: ../js/ui/screenShield.js:86 #: ../js/ui/screenShield.js:90
msgid "%A, %B %d" msgid "%A, %B %d"
msgstr "%A, %d. %B" msgstr "%A, %d. %B"
#: ../js/ui/screenShield.js:151 #: ../js/ui/screenShield.js:155
#, c-format #, c-format
msgid "%d new notification" msgid "%d new notification"
msgid_plural "%d new notifications" msgid_plural "%d new notifications"
@ -1307,11 +1310,11 @@ msgstr[1] "%d нова обавештења"
msgstr[2] "%d нових обавештења" msgstr[2] "%d нових обавештења"
msgstr[3] "Једно ново обавештење" msgstr[3] "Једно ново обавештење"
#: ../js/ui/screenShield.js:438 ../js/ui/userMenu.js:807 #: ../js/ui/screenShield.js:442 ../js/ui/userMenu.js:806
msgid "Lock" msgid "Lock"
msgstr "Закључај" msgstr "Закључај"
#: ../js/ui/screenShield.js:640 #: ../js/ui/screenShield.js:639
msgid "GNOME needs to lock the screen" msgid "GNOME needs to lock the screen"
msgstr "Гном мора да закључа екран" msgstr "Гном мора да закључа екран"
@ -1322,19 +1325,21 @@ msgstr "Гном мора да закључа екран"
#. #.
#. XXX: another option is to kick the user into the gdm login #. XXX: another option is to kick the user into the gdm login
#. screen, where we're not affected by grabs #. screen, where we're not affected by grabs
#: ../js/ui/screenShield.js:761 ../js/ui/screenShield.js:1197 #: ../js/ui/screenShield.js:758 ../js/ui/screenShield.js:1169
#| msgid "Unable to connect to %s"
msgid "Unable to lock" msgid "Unable to lock"
msgstr "Не могу да закључам" msgstr "Не могу да закључам"
#: ../js/ui/screenShield.js:762 ../js/ui/screenShield.js:1198 #: ../js/ui/screenShield.js:759 ../js/ui/screenShield.js:1170
msgid "Lock was blocked by an application" msgid "Lock was blocked by an application"
msgstr "Неки програм је блокирао закључавање" msgstr "Неки програм је блокирао закључавање"
#: ../js/ui/searchDisplay.js:453 #: ../js/ui/searchDisplay.js:431
#| msgid "Searching..."
msgid "Searching…" msgid "Searching…"
msgstr "Тражим…" msgstr "Тражим…"
#: ../js/ui/searchDisplay.js:497 #: ../js/ui/searchDisplay.js:475
msgid "No results." msgid "No results."
msgstr "Нема одговарајућих резултата." msgstr "Нема одговарајућих резултата."
@ -1346,11 +1351,11 @@ msgstr "Умножи"
msgid "Paste" msgid "Paste"
msgstr "Убаци" msgstr "Убаци"
#: ../js/ui/shellEntry.js:106 #: ../js/ui/shellEntry.js:105
msgid "Show Text" msgid "Show Text"
msgstr "Прикажи текст" msgstr "Прикажи текст"
#: ../js/ui/shellEntry.js:108 #: ../js/ui/shellEntry.js:107
msgid "Hide Text" msgid "Hide Text"
msgstr "Сакриј текст" msgstr "Сакриј текст"
@ -1362,7 +1367,7 @@ msgstr "Лозинка"
msgid "Remember Password" msgid "Remember Password"
msgstr "Запамти лозинку" msgstr "Запамти лозинку"
#: ../js/ui/shellMountOperation.js:403 ../js/ui/unlockDialog.js:113 #: ../js/ui/shellMountOperation.js:403 ../js/ui/unlockDialog.js:140
msgid "Unlock" msgid "Unlock"
msgstr "Откључај" msgstr "Откључај"
@ -1426,10 +1431,12 @@ msgid "Visibility"
msgstr "Видљивост" msgstr "Видљивост"
#: ../js/ui/status/bluetooth.js:59 #: ../js/ui/status/bluetooth.js:59
#| msgid "Send Files to Device..."
msgid "Send Files to Device…" msgid "Send Files to Device…"
msgstr "Пошаљи датотеке на уређај…" msgstr "Пошаљи датотеке на уређај…"
#: ../js/ui/status/bluetooth.js:60 #: ../js/ui/status/bluetooth.js:60
#| msgid "Set Up a New Device..."
msgid "Set Up a New Device…" msgid "Set Up a New Device…"
msgstr "Подеси нови уређај…" msgstr "Подеси нови уређај…"
@ -1456,6 +1463,7 @@ msgid "connecting..."
msgstr "повезујем се..." msgstr "повезујем се..."
#: ../js/ui/status/bluetooth.js:239 #: ../js/ui/status/bluetooth.js:239
#| msgid "Send Files..."
msgid "Send Files…" msgid "Send Files…"
msgstr "Пошаљи датотеке…" msgstr "Пошаљи датотеке…"
@ -1668,6 +1676,7 @@ msgstr "Подешавања напајања"
#. 0 is reported when UPower does not have enough data #. 0 is reported when UPower does not have enough data
#. to estimate battery life #. to estimate battery life
#: ../js/ui/status/power.js:99 #: ../js/ui/status/power.js:99
#| msgid "Estimating..."
msgid "Estimating…" msgid "Estimating…"
msgstr "Приближно…" msgstr "Приближно…"
@ -1775,11 +1784,11 @@ msgstr "Јачина звука"
msgid "Microphone" msgid "Microphone"
msgstr "Микрофон" msgstr "Микрофон"
#: ../js/ui/unlockDialog.js:124 #: ../js/ui/unlockDialog.js:151
msgid "Log in as another user" msgid "Log in as another user"
msgstr "Пријавите се као други корсник" msgstr "Пријавите се као други корсник"
#: ../js/ui/unlockDialog.js:145 #: ../js/ui/unlockDialog.js:177
msgid "Unlock Window" msgid "Unlock Window"
msgstr "Откључај прозор" msgstr "Откључај прозор"
@ -1807,27 +1816,27 @@ msgstr "Мирује"
msgid "Offline" msgid "Offline"
msgstr "Ван мреже" msgstr "Ван мреже"
#: ../js/ui/userMenu.js:781 #: ../js/ui/userMenu.js:780
msgid "Notifications" msgid "Notifications"
msgstr "Обавештења" msgstr "Обавештења"
#: ../js/ui/userMenu.js:797 #: ../js/ui/userMenu.js:796
msgid "Switch User" msgid "Switch User"
msgstr "Промени корисника" msgstr "Промени корисника"
#: ../js/ui/userMenu.js:802 #: ../js/ui/userMenu.js:801
msgid "Log Out" msgid "Log Out"
msgstr "Одјави ме" msgstr "Одјави ме"
#: ../js/ui/userMenu.js:822 #: ../js/ui/userMenu.js:821
msgid "Install Updates & Restart" msgid "Install Updates & Restart"
msgstr "Инсталирај ажурирања и поново покрени" msgstr "Инсталирај ажурирања и поново покрени"
#: ../js/ui/userMenu.js:840 #: ../js/ui/userMenu.js:839
msgid "Your chat status will be set to busy" msgid "Your chat status will be set to busy"
msgstr "Ваше стање ћаскања ће бити постављено на заузето" msgstr "Ваше стање ћаскања ће бити постављено на заузето"
#: ../js/ui/userMenu.js:841 #: ../js/ui/userMenu.js:840
msgid "" msgid ""
"Notifications are now disabled, including chat messages. Your online status " "Notifications are now disabled, including chat messages. Your online status "
"has been adjusted to let others know that you might not see their messages." "has been adjusted to let others know that you might not see their messages."
@ -1836,22 +1845,20 @@ msgstr ""
"мрежи је подешено тако да ће остали знати да ви не можете видети њихове " "мрежи је подешено тако да ће остали знати да ви не можете видети њихове "
"поруке." "поруке."
#: ../js/ui/userMenu.js:888 #: ../js/ui/userMenu.js:886
msgid "Other users are logged in." msgid "Other users are logged in."
msgstr "Други корисници су пријављени." msgstr "Други корисници су пријављени."
#: ../js/ui/userMenu.js:893 #: ../js/ui/userMenu.js:891
msgid "Shutting down might cause them to lose unsaved work." msgid "Shutting down might cause them to lose unsaved work."
msgstr "Искључивање може да доведе до тога да изгубе несачувани рад." msgstr "Искључивање може да доведе до тога да изгубе несачувани рад."
#. Translators: Remote here refers to a remote session, like a ssh login #: ../js/ui/userMenu.js:918
#: ../js/ui/userMenu.js:921
#, c-format #, c-format
msgid "%s (remote)" msgid "%s (remote)"
msgstr "%s (удаљено)" msgstr "%s (удаљено)"
#. Translators: Console here refers to a tty like a VT console #: ../js/ui/userMenu.js:920
#: ../js/ui/userMenu.js:924
#, c-format #, c-format
msgid "%s (console)" msgid "%s (console)"
msgstr "%s (љуска)" msgstr "%s (љуска)"
@ -1864,7 +1871,7 @@ msgstr "Програми"
msgid "Search" msgid "Search"
msgstr "Тражи" msgstr "Тражи"
#: ../js/ui/wanda.js:77 #: ../js/ui/wanda.js:92
#, c-format #, c-format
msgid "" msgid ""
"Sorry, no wisdom for you today:\n" "Sorry, no wisdom for you today:\n"
@ -1873,7 +1880,7 @@ msgstr ""
"Извините, данас за вас нема мудрости:\n" "Извините, данас за вас нема мудрости:\n"
"%s" "%s"
#: ../js/ui/wanda.js:81 #: ../js/ui/wanda.js:96
#, c-format #, c-format
msgid "%s the Oracle says" msgid "%s the Oracle says"
msgstr "Пророк је рекао %s" msgstr "Пророк је рекао %s"

View File

@ -8,7 +8,7 @@ msgstr ""
"Project-Id-Version: gnome-shell master\n" "Project-Id-Version: gnome-shell master\n"
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-" "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-"
"shell&keywords=I18N+L10N&component=general\n" "shell&keywords=I18N+L10N&component=general\n"
"POT-Creation-Date: 2013-03-31 01:48+0000\n" "POT-Creation-Date: 2013-03-04 08:38+0000\n"
"PO-Revision-Date: 2013-03-08 20:26+0200\n" "PO-Revision-Date: 2013-03-08 20:26+0200\n"
"Last-Translator: Miroslav Nikolić <miroslavnikolic@rocketmail.com>\n" "Last-Translator: Miroslav Nikolić <miroslavnikolic@rocketmail.com>\n"
"Language-Team: Serbian <gnom@prevod.org>\n" "Language-Team: Serbian <gnom@prevod.org>\n"
@ -16,8 +16,8 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=4; plural=n==1? 3 : n%10==1 && n%100!=11 ? 0 : n" "Plural-Forms: nplurals=4; plural=n==1? 3 : n%10==1 && n%100!=11 ? 0 : "
"%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" "n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
"X-Project-Style: gnome\n" "X-Project-Style: gnome\n"
#: ../data/50-gnome-shell-screenshot.xml.in.h:1 #: ../data/50-gnome-shell-screenshot.xml.in.h:1
@ -365,52 +365,53 @@ msgid "Select an extension to configure using the combobox above."
msgstr "Izaberite proširenje za podešavanje koristeći prozorče za izbor." msgstr "Izaberite proširenje za podešavanje koristeći prozorče za izbor."
#: ../js/gdm/loginDialog.js:405 #: ../js/gdm/loginDialog.js:405
#| msgid "Session..."
msgid "Session…" msgid "Session…"
msgstr "Sesija…" msgstr "Sesija…"
#. translators: this message is shown below the user list on the #. translators: this message is shown below the user list on the
#. login screen. It can be activated to reveal an entry for #. login screen. It can be activated to reveal an entry for
#. manually entering the username. #. manually entering the username.
#: ../js/gdm/loginDialog.js:630 #: ../js/gdm/loginDialog.js:629
msgid "Not listed?" msgid "Not listed?"
msgstr "Nije na spisku?" msgstr "Nije na spisku?"
#: ../js/gdm/loginDialog.js:786 ../js/ui/components/networkAgent.js:137 #: ../js/gdm/loginDialog.js:783 ../js/ui/components/networkAgent.js:137
#: ../js/ui/components/polkitAgent.js:162 ../js/ui/endSessionDialog.js:375 #: ../js/ui/components/polkitAgent.js:162 ../js/ui/endSessionDialog.js:375
#: ../js/ui/extensionDownloader.js:195 ../js/ui/shellMountOperation.js:399 #: ../js/ui/extensionDownloader.js:195 ../js/ui/shellMountOperation.js:399
#: ../js/ui/status/bluetooth.js:415 ../js/ui/unlockDialog.js:99 #: ../js/ui/status/bluetooth.js:415 ../js/ui/unlockDialog.js:126
#: ../js/ui/userMenu.js:938 #: ../js/ui/userMenu.js:934
msgid "Cancel" msgid "Cancel"
msgstr "Otkaži" msgstr "Otkaži"
#: ../js/gdm/loginDialog.js:802 #: ../js/gdm/loginDialog.js:799
msgctxt "button" msgctxt "button"
msgid "Sign In" msgid "Sign In"
msgstr "Prijavi me" msgstr "Prijavi me"
#: ../js/gdm/loginDialog.js:802 #: ../js/gdm/loginDialog.js:799
msgid "Next" msgid "Next"
msgstr "Dalje" msgstr "Dalje"
#. TTLS and PEAP are actually much more complicated, but this complication #. TTLS and PEAP are actually much more complicated, but this complication
#. is not visible here since we only care about phase2 authentication #. is not visible here since we only care about phase2 authentication
#. (and don't even care of which one) #. (and don't even care of which one)
#: ../js/gdm/loginDialog.js:917 ../js/ui/components/networkAgent.js:260 #: ../js/gdm/loginDialog.js:904 ../js/ui/components/networkAgent.js:260
#: ../js/ui/components/networkAgent.js:278 #: ../js/ui/components/networkAgent.js:278
msgid "Username: " msgid "Username: "
msgstr "Korisničko ime: " msgstr "Korisničko ime: "
#: ../js/gdm/loginDialog.js:1173 #: ../js/gdm/loginDialog.js:1157
msgid "Login Window" msgid "Login Window"
msgstr "Prozor za prijavljivanje" msgstr "Prozor za prijavljivanje"
#. Translators: accessible name of the power menu in the login screen #. Translators: accessible name of the power menu in the login screen
#: ../js/gdm/powerMenu.js:36 #: ../js/gdm/powerMenu.js:36
msgid "Power" msgid "Power"
msgstr "Napajanje" msgstr "Ugasi"
#: ../js/gdm/powerMenu.js:93 ../js/ui/userMenu.js:696 ../js/ui/userMenu.js:700 #: ../js/gdm/powerMenu.js:93 ../js/ui/userMenu.js:695 ../js/ui/userMenu.js:699
#: ../js/ui/userMenu.js:816 #: ../js/ui/userMenu.js:815
msgid "Suspend" msgid "Suspend"
msgstr "Obustavi" msgstr "Obustavi"
@ -418,58 +419,58 @@ msgstr "Obustavi"
msgid "Restart" msgid "Restart"
msgstr "Ponovo pokreni" msgstr "Ponovo pokreni"
#: ../js/gdm/powerMenu.js:103 ../js/ui/userMenu.js:698 #: ../js/gdm/powerMenu.js:103 ../js/ui/userMenu.js:697
#: ../js/ui/userMenu.js:700 ../js/ui/userMenu.js:815 ../js/ui/userMenu.js:942 #: ../js/ui/userMenu.js:699 ../js/ui/userMenu.js:814 ../js/ui/userMenu.js:938
msgid "Power Off" msgid "Power Off"
msgstr "Isključi" msgstr "Ugasi"
#: ../js/gdm/util.js:249 #: ../js/gdm/util.js:182
msgid "Authentication error" msgid "Authentication error"
msgstr "Greška potvrđivanja identiteta" msgstr "Greška potvrđivanja identiteta"
#. Translators: this message is shown below the password entry field #. Translators: this message is shown below the password entry field
#. to indicate the user can swipe their finger instead #. to indicate the user can swipe their finger instead
#: ../js/gdm/util.js:366 #: ../js/gdm/util.js:299
msgid "(or swipe finger)" msgid "(or swipe finger)"
msgstr "(ili lupite prst)" msgstr "(ili lupite prst)"
#: ../js/gdm/util.js:391 #: ../js/gdm/util.js:324
#, c-format #, c-format
msgid "(e.g., user or %s)" msgid "(e.g., user or %s)"
msgstr "(npr., korisnik ili %s)" msgstr "(npr., korisnik ili %s)"
#: ../js/misc/util.js:97 #: ../js/misc/util.js:94
msgid "Command not found" msgid "Command not found"
msgstr "Naredba nije nađena" msgstr "Naredba nije nađena"
#. Replace "Error invoking GLib.shell_parse_argv: " with #. Replace "Error invoking GLib.shell_parse_argv: " with
#. something nicer #. something nicer
#: ../js/misc/util.js:130 #: ../js/misc/util.js:127
msgid "Could not parse command:" msgid "Could not parse command:"
msgstr "Ne mogu da obradim naredbu:" msgstr "Ne mogu da obradim naredbu:"
#: ../js/misc/util.js:138 #: ../js/misc/util.js:135
#, c-format #, c-format
msgid "Execution of '%s' failed:" msgid "Execution of '%s' failed:"
msgstr "Nije uspelo pokretanje „%s“:" msgstr "Nije uspelo pokretanje „%s“:"
#: ../js/ui/appDisplay.js:349 #: ../js/ui/appDisplay.js:348
msgid "Frequent" msgid "Frequent"
msgstr "Često" msgstr "Često"
#: ../js/ui/appDisplay.js:356 #: ../js/ui/appDisplay.js:355
msgid "All" msgid "All"
msgstr "Sve" msgstr "Sve"
#: ../js/ui/appDisplay.js:914 #: ../js/ui/appDisplay.js:913
msgid "New Window" msgid "New Window"
msgstr "Novi prozor" msgstr "Novi prozor"
#: ../js/ui/appDisplay.js:917 ../js/ui/dash.js:284 #: ../js/ui/appDisplay.js:916 ../js/ui/dash.js:284
msgid "Remove from Favorites" msgid "Remove from Favorites"
msgstr "Ukloni iz omiljenih" msgstr "Ukloni iz omiljenih"
#: ../js/ui/appDisplay.js:918 #: ../js/ui/appDisplay.js:917
msgid "Add to Favorites" msgid "Add to Favorites"
msgstr "Dodaj u omiljene" msgstr "Dodaj u omiljene"
@ -483,7 +484,7 @@ msgstr "„%s“ je dodat među omiljene."
msgid "%s has been removed from your favorites." msgid "%s has been removed from your favorites."
msgstr "„%s“ je uklonjen iz omiljenih." msgstr "„%s“ je uklonjen iz omiljenih."
#: ../js/ui/backgroundMenu.js:19 ../js/ui/userMenu.js:789 #: ../js/ui/backgroundMenu.js:19 ../js/ui/userMenu.js:788
msgid "Settings" msgid "Settings"
msgstr "Podešavanja" msgstr "Podešavanja"
@ -506,7 +507,7 @@ msgctxt "event list time"
msgid "%H\\u2236%M" msgid "%H\\u2236%M"
msgstr "%H\\u2236%M" msgstr "%H\\u2236%M"
#. Translators: Shown in calendar event list, if 12h format, #. Transators: Shown in calendar event list, if 12h format,
#. \u2236 is a ratio character, similar to : and \u2009 is #. \u2236 is a ratio character, similar to : and \u2009 is
#. a thin space #. a thin space
#: ../js/ui/calendar.js:77 #: ../js/ui/calendar.js:77
@ -608,35 +609,35 @@ msgid "S"
msgstr "Sub" msgstr "Sub"
#. Translators: Text to show if there are no events #. Translators: Text to show if there are no events
#: ../js/ui/calendar.js:720 #: ../js/ui/calendar.js:692
msgid "Nothing Scheduled" msgid "Nothing Scheduled"
msgstr "Ništa planirano" msgstr "Ništa planirano"
#. Translators: Shown on calendar heading when selected day occurs on current year #. Translators: Shown on calendar heading when selected day occurs on current year
#: ../js/ui/calendar.js:736 #: ../js/ui/calendar.js:708
msgctxt "calendar heading" msgctxt "calendar heading"
msgid "%A, %B %d" msgid "%A, %B %d"
msgstr "%A, %B %d" msgstr "%A, %B %d"
#. Translators: Shown on calendar heading when selected day occurs on different year #. Translators: Shown on calendar heading when selected day occurs on different year
#: ../js/ui/calendar.js:739 #: ../js/ui/calendar.js:711
msgctxt "calendar heading" msgctxt "calendar heading"
msgid "%A, %B %d, %Y" msgid "%A, %B %d, %Y"
msgstr "%A, %B %d, %Y" msgstr "%A, %B %d, %Y"
#: ../js/ui/calendar.js:749 #: ../js/ui/calendar.js:721
msgid "Today" msgid "Today"
msgstr "Danas" msgstr "Danas"
#: ../js/ui/calendar.js:753 #: ../js/ui/calendar.js:725
msgid "Tomorrow" msgid "Tomorrow"
msgstr "Sutra" msgstr "Sutra"
#: ../js/ui/calendar.js:764 #: ../js/ui/calendar.js:736
msgid "This week" msgid "This week"
msgstr "Ove nedelje" msgstr "Ove nedelje"
#: ../js/ui/calendar.js:772 #: ../js/ui/calendar.js:744
msgid "Next week" msgid "Next week"
msgstr "Sledeće nedelje" msgstr "Sledeće nedelje"
@ -652,12 +653,12 @@ msgstr "Spoljni uređaj je isključen"
msgid "Removable Devices" msgid "Removable Devices"
msgstr "Uklonjivi uređaji" msgstr "Uklonjivi uređaji"
#: ../js/ui/components/autorunManager.js:594 #: ../js/ui/components/autorunManager.js:593
#, c-format #, c-format
msgid "Open with %s" msgid "Open with %s"
msgstr "Otvori programom %s" msgstr "Otvori programom %s"
#: ../js/ui/components/autorunManager.js:620 #: ../js/ui/components/autorunManager.js:619
msgid "Eject" msgid "Eject"
msgstr "Izbaci" msgstr "Izbaci"
@ -1037,7 +1038,7 @@ msgstr "Podešavanja datuma i vremena"
#. Translators: This is the date format to use when the calendar popup is #. Translators: This is the date format to use when the calendar popup is
#. * shown - it is shown just below the time in the shell (e.g. "Tue 9:29 AM"). #. * shown - it is shown just below the time in the shell (e.g. "Tue 9:29 AM").
#. #.
#: ../js/ui/dateMenu.js:215 #: ../js/ui/dateMenu.js:205
msgid "%A %B %e, %Y" msgid "%A %B %e, %Y"
msgstr "%A, %e. %b., %R" msgstr "%A, %e. %b., %R"
@ -1212,6 +1213,7 @@ msgid "Remove"
msgstr "Ukloni" msgstr "Ukloni"
#: ../js/ui/messageTray.js:1501 #: ../js/ui/messageTray.js:1501
#| msgid "No Messages"
msgid "Clear Messages" msgid "Clear Messages"
msgstr "Očisti poruke" msgstr "Očisti poruke"
@ -1219,15 +1221,15 @@ msgstr "Očisti poruke"
msgid "Notification Settings" msgid "Notification Settings"
msgstr "Postavke obaveštenja" msgstr "Postavke obaveštenja"
#: ../js/ui/messageTray.js:1709 #: ../js/ui/messageTray.js:1707
msgid "No Messages" msgid "No Messages"
msgstr "Nema poruka" msgstr "Nema poruka"
#: ../js/ui/messageTray.js:1782 #: ../js/ui/messageTray.js:1787
msgid "Message Tray" msgid "Message Tray"
msgstr "Fioka poruka" msgstr "Fioka poruka"
#: ../js/ui/messageTray.js:2810 #: ../js/ui/messageTray.js:2864
msgid "System Information" msgid "System Information"
msgstr "Podaci o sistemu" msgstr "Podaci o sistemu"
@ -1236,7 +1238,7 @@ msgctxt "program"
msgid "Unknown" msgid "Unknown"
msgstr "Nepoznat" msgstr "Nepoznat"
#: ../js/ui/overviewControls.js:463 ../js/ui/screenShield.js:149 #: ../js/ui/overviewControls.js:460 ../js/ui/screenShield.js:153
#, c-format #, c-format
msgid "%d new message" msgid "%d new message"
msgid_plural "%d new messages" msgid_plural "%d new messages"
@ -1245,7 +1247,7 @@ msgstr[1] "%d nove poruke"
msgstr[2] "%d novih poruka" msgstr[2] "%d novih poruka"
msgstr[3] "Jedna nova poruka" msgstr[3] "Jedna nova poruka"
#: ../js/ui/overview.js:84 #: ../js/ui/overview.js:82
msgid "Undo" msgid "Undo"
msgstr "Opozovi" msgstr "Opozovi"
@ -1257,21 +1259,22 @@ msgstr "Pregled"
#. in the search entry when no search is #. in the search entry when no search is
#. active; it should not exceed ~30 #. active; it should not exceed ~30
#. characters. #. characters.
#: ../js/ui/overview.js:271 #: ../js/ui/overview.js:284
#| msgid "Type to search..."
msgid "Type to search…" msgid "Type to search…"
msgstr "Upišite tekst za pretragu…" msgstr "Upišite tekst za pretragu…"
#: ../js/ui/panel.js:612 #: ../js/ui/panel.js:613
msgid "Quit" msgid "Quit"
msgstr "Izađi" msgstr "Izađi"
#. Translators: If there is no suitable word for "Activities" #. Translators: If there is no suitable word for "Activities"
#. in your language, you can use the word for "Overview". #. in your language, you can use the word for "Overview".
#: ../js/ui/panel.js:636 #: ../js/ui/panel.js:642
msgid "Activities" msgid "Activities"
msgstr "Aktivnosti" msgstr "Aktivnosti"
#: ../js/ui/panel.js:933 #: ../js/ui/panel.js:983
msgid "Top Bar" msgid "Top Bar"
msgstr "Gornja traka" msgstr "Gornja traka"
@ -1284,21 +1287,21 @@ msgstr "Gornja traka"
msgid "toggle-switch-us" msgid "toggle-switch-us"
msgstr "toggle-switch-intl" msgstr "toggle-switch-intl"
#: ../js/ui/runDialog.js:73 #: ../js/ui/runDialog.js:205
msgid "Enter a Command" msgid "Enter a Command"
msgstr "Unesite naredbu" msgstr "Unesite naredbu"
#: ../js/ui/runDialog.js:109 #: ../js/ui/runDialog.js:241
msgid "Close" msgid "Close"
msgstr "Zatvori" msgstr "Zatvori"
#. Translators: This is a time format for a date in #. Translators: This is a time format for a date in
#. long format #. long format
#: ../js/ui/screenShield.js:86 #: ../js/ui/screenShield.js:90
msgid "%A, %B %d" msgid "%A, %B %d"
msgstr "%A, %d. %B" msgstr "%A, %d. %B"
#: ../js/ui/screenShield.js:151 #: ../js/ui/screenShield.js:155
#, c-format #, c-format
msgid "%d new notification" msgid "%d new notification"
msgid_plural "%d new notifications" msgid_plural "%d new notifications"
@ -1307,11 +1310,11 @@ msgstr[1] "%d nova obaveštenja"
msgstr[2] "%d novih obaveštenja" msgstr[2] "%d novih obaveštenja"
msgstr[3] "Jedno novo obaveštenje" msgstr[3] "Jedno novo obaveštenje"
#: ../js/ui/screenShield.js:438 ../js/ui/userMenu.js:807 #: ../js/ui/screenShield.js:442 ../js/ui/userMenu.js:806
msgid "Lock" msgid "Lock"
msgstr "Zaključaj" msgstr "Zaključaj"
#: ../js/ui/screenShield.js:640 #: ../js/ui/screenShield.js:639
msgid "GNOME needs to lock the screen" msgid "GNOME needs to lock the screen"
msgstr "Gnom mora da zaključa ekran" msgstr "Gnom mora da zaključa ekran"
@ -1322,19 +1325,21 @@ msgstr "Gnom mora da zaključa ekran"
#. #.
#. XXX: another option is to kick the user into the gdm login #. XXX: another option is to kick the user into the gdm login
#. screen, where we're not affected by grabs #. screen, where we're not affected by grabs
#: ../js/ui/screenShield.js:761 ../js/ui/screenShield.js:1197 #: ../js/ui/screenShield.js:758 ../js/ui/screenShield.js:1169
#| msgid "Unable to connect to %s"
msgid "Unable to lock" msgid "Unable to lock"
msgstr "Ne mogu da zaključam" msgstr "Ne mogu da zaključam"
#: ../js/ui/screenShield.js:762 ../js/ui/screenShield.js:1198 #: ../js/ui/screenShield.js:759 ../js/ui/screenShield.js:1170
msgid "Lock was blocked by an application" msgid "Lock was blocked by an application"
msgstr "Neki program je blokirao zaključavanje" msgstr "Neki program je blokirao zaključavanje"
#: ../js/ui/searchDisplay.js:453 #: ../js/ui/searchDisplay.js:431
#| msgid "Searching..."
msgid "Searching…" msgid "Searching…"
msgstr "Tražim…" msgstr "Tražim…"
#: ../js/ui/searchDisplay.js:497 #: ../js/ui/searchDisplay.js:475
msgid "No results." msgid "No results."
msgstr "Nema odgovarajućih rezultata." msgstr "Nema odgovarajućih rezultata."
@ -1346,11 +1351,11 @@ msgstr "Umnoži"
msgid "Paste" msgid "Paste"
msgstr "Ubaci" msgstr "Ubaci"
#: ../js/ui/shellEntry.js:106 #: ../js/ui/shellEntry.js:105
msgid "Show Text" msgid "Show Text"
msgstr "Prikaži tekst" msgstr "Prikaži tekst"
#: ../js/ui/shellEntry.js:108 #: ../js/ui/shellEntry.js:107
msgid "Hide Text" msgid "Hide Text"
msgstr "Sakrij tekst" msgstr "Sakrij tekst"
@ -1362,7 +1367,7 @@ msgstr "Lozinka"
msgid "Remember Password" msgid "Remember Password"
msgstr "Zapamti lozinku" msgstr "Zapamti lozinku"
#: ../js/ui/shellMountOperation.js:403 ../js/ui/unlockDialog.js:113 #: ../js/ui/shellMountOperation.js:403 ../js/ui/unlockDialog.js:140
msgid "Unlock" msgid "Unlock"
msgstr "Otključaj" msgstr "Otključaj"
@ -1426,10 +1431,12 @@ msgid "Visibility"
msgstr "Vidljivost" msgstr "Vidljivost"
#: ../js/ui/status/bluetooth.js:59 #: ../js/ui/status/bluetooth.js:59
#| msgid "Send Files to Device..."
msgid "Send Files to Device…" msgid "Send Files to Device…"
msgstr "Pošalji datoteke na uređaj…" msgstr "Pošalji datoteke na uređaj…"
#: ../js/ui/status/bluetooth.js:60 #: ../js/ui/status/bluetooth.js:60
#| msgid "Set Up a New Device..."
msgid "Set Up a New Device…" msgid "Set Up a New Device…"
msgstr "Podesi novi uređaj…" msgstr "Podesi novi uređaj…"
@ -1456,6 +1463,7 @@ msgid "connecting..."
msgstr "povezujem se..." msgstr "povezujem se..."
#: ../js/ui/status/bluetooth.js:239 #: ../js/ui/status/bluetooth.js:239
#| msgid "Send Files..."
msgid "Send Files…" msgid "Send Files…"
msgstr "Pošalji datoteke…" msgstr "Pošalji datoteke…"
@ -1668,6 +1676,7 @@ msgstr "Podešavanja napajanja"
#. 0 is reported when UPower does not have enough data #. 0 is reported when UPower does not have enough data
#. to estimate battery life #. to estimate battery life
#: ../js/ui/status/power.js:99 #: ../js/ui/status/power.js:99
#| msgid "Estimating..."
msgid "Estimating…" msgid "Estimating…"
msgstr "Približno…" msgstr "Približno…"
@ -1775,11 +1784,11 @@ msgstr "Jačina zvuka"
msgid "Microphone" msgid "Microphone"
msgstr "Mikrofon" msgstr "Mikrofon"
#: ../js/ui/unlockDialog.js:124 #: ../js/ui/unlockDialog.js:151
msgid "Log in as another user" msgid "Log in as another user"
msgstr "Prijavite se kao drugi korsnik" msgstr "Prijavite se kao drugi korsnik"
#: ../js/ui/unlockDialog.js:145 #: ../js/ui/unlockDialog.js:177
msgid "Unlock Window" msgid "Unlock Window"
msgstr "Otključaj prozor" msgstr "Otključaj prozor"
@ -1807,27 +1816,27 @@ msgstr "Miruje"
msgid "Offline" msgid "Offline"
msgstr "Van mreže" msgstr "Van mreže"
#: ../js/ui/userMenu.js:781 #: ../js/ui/userMenu.js:780
msgid "Notifications" msgid "Notifications"
msgstr "Obaveštenja" msgstr "Obaveštenja"
#: ../js/ui/userMenu.js:797 #: ../js/ui/userMenu.js:796
msgid "Switch User" msgid "Switch User"
msgstr "Promeni korisnika" msgstr "Promeni korisnika"
#: ../js/ui/userMenu.js:802 #: ../js/ui/userMenu.js:801
msgid "Log Out" msgid "Log Out"
msgstr "Odjavi me" msgstr "Odjavi me"
#: ../js/ui/userMenu.js:822 #: ../js/ui/userMenu.js:821
msgid "Install Updates & Restart" msgid "Install Updates & Restart"
msgstr "Instaliraj ažuriranja i ponovo pokreni" msgstr "Instaliraj ažuriranja i ponovo pokreni"
#: ../js/ui/userMenu.js:840 #: ../js/ui/userMenu.js:839
msgid "Your chat status will be set to busy" msgid "Your chat status will be set to busy"
msgstr "Vaše stanje ćaskanja će biti postavljeno na zauzeto" msgstr "Vaše stanje ćaskanja će biti postavljeno na zauzeto"
#: ../js/ui/userMenu.js:841 #: ../js/ui/userMenu.js:840
msgid "" msgid ""
"Notifications are now disabled, including chat messages. Your online status " "Notifications are now disabled, including chat messages. Your online status "
"has been adjusted to let others know that you might not see their messages." "has been adjusted to let others know that you might not see their messages."
@ -1836,22 +1845,20 @@ msgstr ""
"mreži je podešeno tako da će ostali znati da vi ne možete videti njihove " "mreži je podešeno tako da će ostali znati da vi ne možete videti njihove "
"poruke." "poruke."
#: ../js/ui/userMenu.js:888 #: ../js/ui/userMenu.js:886
msgid "Other users are logged in." msgid "Other users are logged in."
msgstr "Drugi korisnici su prijavljeni." msgstr "Drugi korisnici su prijavljeni."
#: ../js/ui/userMenu.js:893 #: ../js/ui/userMenu.js:891
msgid "Shutting down might cause them to lose unsaved work." msgid "Shutting down might cause them to lose unsaved work."
msgstr "Isključivanje može da dovede do toga da izgube nesačuvani rad." msgstr "Isključivanje može da dovede do toga da izgube nesačuvani rad."
#. Translators: Remote here refers to a remote session, like a ssh login #: ../js/ui/userMenu.js:918
#: ../js/ui/userMenu.js:921
#, c-format #, c-format
msgid "%s (remote)" msgid "%s (remote)"
msgstr "%s (udaljeno)" msgstr "%s (udaljeno)"
#. Translators: Console here refers to a tty like a VT console #: ../js/ui/userMenu.js:920
#: ../js/ui/userMenu.js:924
#, c-format #, c-format
msgid "%s (console)" msgid "%s (console)"
msgstr "%s (ljuska)" msgstr "%s (ljuska)"
@ -1864,7 +1871,7 @@ msgstr "Programi"
msgid "Search" msgid "Search"
msgstr "Traži" msgstr "Traži"
#: ../js/ui/wanda.js:77 #: ../js/ui/wanda.js:92
#, c-format #, c-format
msgid "" msgid ""
"Sorry, no wisdom for you today:\n" "Sorry, no wisdom for you today:\n"
@ -1873,7 +1880,7 @@ msgstr ""
"Izvinite, danas za vas nema mudrosti:\n" "Izvinite, danas za vas nema mudrosti:\n"
"%s" "%s"
#: ../js/ui/wanda.js:81 #: ../js/ui/wanda.js:96
#, c-format #, c-format
msgid "%s the Oracle says" msgid "%s the Oracle says"
msgstr "Prorok je rekao %s" msgstr "Prorok je rekao %s"

942
po/tg.po

File diff suppressed because it is too large Load Diff

2590
po/tr.po

File diff suppressed because it is too large Load Diff

442
po/vi.po
View File

@ -1,19 +1,18 @@
# Vietnamese translation for gnome-shell. # Vietnamese translation for gnome-shell.
# Copyright (C) 2013 GNOME i18n Project for Vietnamese. # Copyright (C) 2010 GNOME i18n Project for Vietnamese.
# This file is distributed under the same license as the gnome-shell package. # This file is distributed under the same license as the gnome-shell package.
# Nguyễn Thái Ngọc Duy <pclouds@gmail.com>, 2010-2013. # Nguyễn Thái Ngọc Duy <pclouds@gmail.com>, 2010-2013.
# Ngô Chin <ndtrung4419@gmail.com>, 2011. # Ngô Chin <ndtrung4419@gmail.com>, 2011.
# Trần Ngọc Quân <vnwildman@gmail.com>, 2013.
# #
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: gnome-shell\n" "Project-Id-Version: gnome-shell\n"
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-" "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-"
"shell&keywords=I18N+L10N&component=general\n" "shell&keywords=I18N+L10N&component=general\n"
"POT-Creation-Date: 2013-03-23 11:49+0000\n" "POT-Creation-Date: 2013-03-02 23:02+0000\n"
"PO-Revision-Date: 2013-04-13 17:51+1000\n" "PO-Revision-Date: 2013-03-03 11:13+0700\n"
"Last-Translator: Trần Ngọc Quân <vnwildman@gmail.com>\n" "Last-Translator: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n"
"Language-Team: Vietnamese <translation-team-vi@lists.sourceforge.net>\n" "Language-Team: Vietnamese <vi-VN@googlegroups.com>\n"
"Language: vi\n" "Language: vi\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
@ -50,7 +49,7 @@ msgstr "Mở trình đơn ứng dụng"
#: ../data/gnome-shell.desktop.in.in.h:1 #: ../data/gnome-shell.desktop.in.in.h:1
msgid "GNOME Shell" msgid "GNOME Shell"
msgstr "Hệ vỏ GNOME" msgstr "GNOME Shell"
#: ../data/gnome-shell.desktop.in.in.h:2 #: ../data/gnome-shell.desktop.in.in.h:2
msgid "Window management and application launching" msgid "Window management and application launching"
@ -59,11 +58,11 @@ msgstr "Quản lý cửa sổ và chạy ứng dụng"
#: ../data/gnome-shell-extension-prefs.desktop.in.in.h:1 #: ../data/gnome-shell-extension-prefs.desktop.in.in.h:1
#: ../js/extensionPrefs/main.js:153 #: ../js/extensionPrefs/main.js:153
msgid "GNOME Shell Extension Preferences" msgid "GNOME Shell Extension Preferences"
msgstr "Cá nhân hóa phần mở rộng hệ vỏ GNOME" msgstr "Tuỳ thích phần mở rộng GNOME Shell"
#: ../data/gnome-shell-extension-prefs.desktop.in.in.h:2 #: ../data/gnome-shell-extension-prefs.desktop.in.in.h:2
msgid "Configure GNOME Shell Extensions" msgid "Configure GNOME Shell Extensions"
msgstr "Cấu hình phần mở rộng Hệ vỏ GNOME" msgstr "Cấu hình phần mở rộng GNOME Shell"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:1 #: ../data/org.gnome.shell.gschema.xml.in.in.h:1
msgid "Enable internal tools useful for developers and testers from Alt-F2" msgid "Enable internal tools useful for developers and testers from Alt-F2"
@ -88,7 +87,7 @@ msgid ""
"list. You can also manipulate this list with the EnableExtension and " "list. You can also manipulate this list with the EnableExtension and "
"DisableExtension DBus methods on org.gnome.Shell." "DisableExtension DBus methods on org.gnome.Shell."
msgstr "" msgstr ""
"Phần mở rộng Hệ vỏ GNOME có thuộc tính uuid; khóa này liệt kê danh sách phần " "Phần mở rộng GNOME Shell có thuộc tính uuid. Khoá này liệt kê danh sách phần "
"mở rộng nên nạp. Bất kỳ phần mở rộng nào muốn nạp phải nằm trong danh sách " "mở rộng nên nạp. Bất kỳ phần mở rộng nào muốn nạp phải nằm trong danh sách "
"này. Bạn có thể thao tác trên danh sách này với phương thức DBus " "này. Bạn có thể thao tác trên danh sách này với phương thức DBus "
"EnableExtension và DisableExtension trên org.gnome.Shell." "EnableExtension và DisableExtension trên org.gnome.Shell."
@ -121,15 +120,13 @@ msgstr ""
#: ../data/org.gnome.shell.gschema.xml.in.in.h:9 #: ../data/org.gnome.shell.gschema.xml.in.in.h:9
msgid "List of categories that should be displayed as folders" msgid "List of categories that should be displayed as folders"
msgstr "Liệt kê các các-ta-lốc mà nó có thể hiển thị như một thư mục" msgstr ""
#: ../data/org.gnome.shell.gschema.xml.in.in.h:10 #: ../data/org.gnome.shell.gschema.xml.in.in.h:10
msgid "" msgid ""
"Each category name in this list will be represented as folder in the " "Each category name in this list will be represented as folder in the "
"application view, rather than being displayed inline in the main view." "application view, rather than being displayed inline in the main view."
msgstr "" msgstr ""
"Mỗi tên các-ta-lốc trong danh sách này sẽ được xuất hiện như là một thư mục "
"trong trình bày ứng dụng, thay vì hiển thị cùng dòng trong trình bày chính. "
#: ../data/org.gnome.shell.gschema.xml.in.in.h:11 #: ../data/org.gnome.shell.gschema.xml.in.in.h:11
msgid "History for command (Alt-F2) dialog" msgid "History for command (Alt-F2) dialog"
@ -157,22 +154,18 @@ msgstr ""
#: ../data/org.gnome.shell.gschema.xml.in.in.h:15 #: ../data/org.gnome.shell.gschema.xml.in.in.h:15
msgid "Always show the 'Log out' menuitem in the user menu." msgid "Always show the 'Log out' menuitem in the user menu."
msgstr "Luôn hiện mục Đăng xuất trên trình đơn người dùng." msgstr "Luôn hiện mục \"Đăng xuất\" trên trình đơn người dùng."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:16 #: ../data/org.gnome.shell.gschema.xml.in.in.h:16
msgid "" msgid ""
"This key overrides the automatic hiding of the 'Log out' menuitem in single-" "This key overrides the automatic hiding of the 'Log out' menuitem in single-"
"user, single-session situations." "user, single-session situations."
msgstr "" msgstr ""
"Khóa này sẽ đè lên việc tự động ẩn trình đơn 'Đăng xuất' ở chế độ đơn-người-"
"dùng, đơn-phiên-làm-việc. "
#: ../data/org.gnome.shell.gschema.xml.in.in.h:17 #: ../data/org.gnome.shell.gschema.xml.in.in.h:17
msgid "" msgid ""
"Whether to remember password for mounting encrypted or remote filesystems" "Whether to remember password for mounting encrypted or remote filesystems"
msgstr "" msgstr ""
"Hoặc là ghi nhớ mật khẩu dành cho việc gắn hệ thống tập tin đã mã hóa hoặc "
"hệ thống tập tin trên máy chủ"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:18 #: ../data/org.gnome.shell.gschema.xml.in.in.h:18
msgid "" msgid ""
@ -181,10 +174,6 @@ msgid ""
"'Remember Password' checkbox will be present. This key sets the default " "'Remember Password' checkbox will be present. This key sets the default "
"state of the checkbox." "state of the checkbox."
msgstr "" msgstr ""
"Hệ vỏ sẽ yêu cầu mật khẩu khi có thư mục được mã hóa hay hệ thống tập tin "
"máy mạng được gắn. Nếu mật khẩu có thể ghi lại để dùng trong lần sau, hộp "
"dấu kiểm “Nhớ mật khẩu” sẽ xuất hiện. Khóa này đặt trạng thái mặc định cho "
"hộp dấu kiểm."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:19 #: ../data/org.gnome.shell.gschema.xml.in.in.h:19
msgid "Show the week date in the calendar" msgid "Show the week date in the calendar"
@ -237,27 +226,27 @@ msgstr "Phím chạy hoặc ngừng trình thu màn hình."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:31 #: ../data/org.gnome.shell.gschema.xml.in.in.h:31
msgid "Which keyboard to use" msgid "Which keyboard to use"
msgstr "Bàn phím cần dùng" msgstr "Loại bàn phím cần dùng"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:32 #: ../data/org.gnome.shell.gschema.xml.in.in.h:32
msgid "The type of keyboard to use." msgid "The type of keyboard to use."
msgstr "Kiểu bàn phím cần dùng." msgstr "Loại bàn phím cần dùng."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:33 #: ../data/org.gnome.shell.gschema.xml.in.in.h:33
msgid "Framerate used for recording screencasts." msgid "Framerate used for recording screencasts."
msgstr "Tốc độ khung hình sẽ dùng khi ghi screencast." msgstr "Tốc độ khung dùng lưu screencast."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:34 #: ../data/org.gnome.shell.gschema.xml.in.in.h:34
msgid "" msgid ""
"The framerate of the resulting screencast recordered by GNOME Shell's " "The framerate of the resulting screencast recordered by GNOME Shell's "
"screencast recorder in frames-per-second." "screencast recorder in frames-per-second."
msgstr "" msgstr ""
"Tốc độ khung hình của screencast được ghi bởi bộ thu Hệ vỏ GNOME tính theo " "Tốc độ khung của screencast lưu bởi bộ thu GNOME Shell theo số khung mỗi "
"số khung mỗi giây." "giây."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:35 #: ../data/org.gnome.shell.gschema.xml.in.in.h:35
msgid "The gstreamer pipeline used to encode the screencast" msgid "The gstreamer pipeline used to encode the screencast"
msgstr "Ống dẫn gstreamer dùng để thu screencast" msgstr "Ống dẫn gstreamer để thu screencast"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:37 #: ../data/org.gnome.shell.gschema.xml.in.in.h:37
#, no-c-format #, no-c-format
@ -278,9 +267,9 @@ msgstr ""
"source pad không kết nối; đầu ra từ pad sẽ được ghi vào tập tin kết quả. Tuy " "source pad không kết nối; đầu ra từ pad sẽ được ghi vào tập tin kết quả. Tuy "
"nhiên ống dẫn có thể tự lưu đầu ra riêng - có thể hữu dụng để gửi kết quả " "nhiên ống dẫn có thể tự lưu đầu ra riêng - có thể hữu dụng để gửi kết quả "
"đến máy chủ icecast thông qua shout2send hoặc tương tự. Nếu bỏ chọn hoặc đặt " "đến máy chủ icecast thông qua shout2send hoặc tương tự. Nếu bỏ chọn hoặc đặt "
"giá trị rỗng, ống dẫn mặc định sẽ được dùng, hiện thời là vp8enc " "giá trị rỗng, ống dẫn mặc định sẽ được dùng, hiện thời là 'vp8enc "
"min_quantizer=13 max_quantizer=13 cpu-used=5 deadline=1000000 threads=%T ! " "min_quantizer=13 max_quantizer=13 cpu-used=5 deadline=1000000 threads=%T ! "
"queue ! webmmux và lưu ở dạng WEBM dùng VP8 codec. %T được dùng để thế chỗ " "queue ! webmmux' và lưu ở dạng WEBM dùng VP8 codec. %T được dùng để thế chỗ "
"cho số thread dự đoán tối ưu cho hệ thống." "cho số thread dự đoán tối ưu cho hệ thống."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:38 #: ../data/org.gnome.shell.gschema.xml.in.in.h:38
@ -307,31 +296,25 @@ msgid ""
"are 'thumbnail-only' (shows a thumbnail of the window), 'app-icon-" "are 'thumbnail-only' (shows a thumbnail of the window), 'app-icon-"
"only' (shows only the application icon) or 'both'." "only' (shows only the application icon) or 'both'."
msgstr "" msgstr ""
"Cấu hình về cách hiển thị các cửa sổ ở bảng chuyển đổi. Các kiểu có thể là "
"'thumbnail-only' (hiển thị ảnh thu nhỏ của cửa sổ), 'app-icon-only' (chỉ "
"hiển thị biểu tượng của ứng dụng) hoặc 'both' (cả hai)."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:42 #: ../data/org.gnome.shell.gschema.xml.in.in.h:42
msgid "Attach modal dialog to the parent window" msgid "Attach modal dialog to the parent window"
msgstr "Gắn hộp thoại dạng modal vào cửa sổ mẹ" msgstr ""
#: ../data/org.gnome.shell.gschema.xml.in.in.h:43 #: ../data/org.gnome.shell.gschema.xml.in.in.h:43
msgid "" msgid ""
"This key overrides the key in org.gnome.mutter when running GNOME Shell." "This key overrides the key in org.gnome.mutter when running GNOME Shell."
msgstr "" msgstr ""
"Khóa này sẽ đè lên khóa có trong org.gnome.mutter khi chạy hệ vỏ GNOME."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:44 #: ../data/org.gnome.shell.gschema.xml.in.in.h:44
msgid "Arrangement of buttons on the titlebar" msgid "Arrangement of buttons on the titlebar"
msgstr "Sắp đặt các nút trên thanh tiêu đề" msgstr ""
#: ../data/org.gnome.shell.gschema.xml.in.in.h:45 #: ../data/org.gnome.shell.gschema.xml.in.in.h:45
msgid "" msgid ""
"This key overrides the key in org.gnome.desktop.wm.preferences when running " "This key overrides the key in org.gnome.desktop.wm.preferences when running "
"GNOME Shell." "GNOME Shell."
msgstr "" msgstr ""
"Khóa này đè lên khóa có trong org.gnome.desktop.wm.preferences khi chạy hệ "
"vỏ GNOME."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:46 #: ../data/org.gnome.shell.gschema.xml.in.in.h:46
msgid "Enable edge tiling when dropping windows on screen edges" msgid "Enable edge tiling when dropping windows on screen edges"
@ -365,46 +348,46 @@ msgstr "Phiên làm việc…"
#. translators: this message is shown below the user list on the #. translators: this message is shown below the user list on the
#. login screen. It can be activated to reveal an entry for #. login screen. It can be activated to reveal an entry for
#. manually entering the username. #. manually entering the username.
#: ../js/gdm/loginDialog.js:630 #: ../js/gdm/loginDialog.js:629
msgid "Not listed?" msgid "Not listed?"
msgstr "Không có trong danh sách?" msgstr "Không có trong danh sách?"
#: ../js/gdm/loginDialog.js:786 ../js/ui/components/networkAgent.js:137 #: ../js/gdm/loginDialog.js:783 ../js/ui/components/networkAgent.js:137
#: ../js/ui/components/polkitAgent.js:162 ../js/ui/endSessionDialog.js:375 #: ../js/ui/components/polkitAgent.js:162 ../js/ui/endSessionDialog.js:375
#: ../js/ui/extensionDownloader.js:195 ../js/ui/shellMountOperation.js:399 #: ../js/ui/extensionDownloader.js:195 ../js/ui/shellMountOperation.js:399
#: ../js/ui/status/bluetooth.js:415 ../js/ui/unlockDialog.js:99 #: ../js/ui/status/bluetooth.js:415 ../js/ui/unlockDialog.js:126
#: ../js/ui/userMenu.js:938 #: ../js/ui/userMenu.js:932
msgid "Cancel" msgid "Cancel"
msgstr "Thôi" msgstr "Thôi"
#: ../js/gdm/loginDialog.js:802 #: ../js/gdm/loginDialog.js:799
msgctxt "button" msgctxt "button"
msgid "Sign In" msgid "Sign In"
msgstr "Đăng nhập" msgstr "Đăng nhập"
#: ../js/gdm/loginDialog.js:802 #: ../js/gdm/loginDialog.js:799
msgid "Next" msgid "Next"
msgstr "Kế tiếp" msgstr "Tới"
#. TTLS and PEAP are actually much more complicated, but this complication #. TTLS and PEAP are actually much more complicated, but this complication
#. is not visible here since we only care about phase2 authentication #. is not visible here since we only care about phase2 authentication
#. (and don't even care of which one) #. (and don't even care of which one)
#: ../js/gdm/loginDialog.js:917 ../js/ui/components/networkAgent.js:260 #: ../js/gdm/loginDialog.js:904 ../js/ui/components/networkAgent.js:260
#: ../js/ui/components/networkAgent.js:278 #: ../js/ui/components/networkAgent.js:278
msgid "Username: " msgid "Username: "
msgstr "Tài khoản: " msgstr "Tên người dùng: "
#: ../js/gdm/loginDialog.js:1173 #: ../js/gdm/loginDialog.js:1157
msgid "Login Window" msgid "Login Window"
msgstr "Cửa sổ đăng nhập" msgstr "Cửa sổ đặt nhập"
#. Translators: accessible name of the power menu in the login screen #. Translators: accessible name of the power menu in the login screen
#: ../js/gdm/powerMenu.js:36 #: ../js/gdm/powerMenu.js:36
msgid "Power" msgid "Power"
msgstr "Nguồn" msgstr "Nguồn"
#: ../js/gdm/powerMenu.js:93 ../js/ui/userMenu.js:696 ../js/ui/userMenu.js:700 #: ../js/gdm/powerMenu.js:93 ../js/ui/userMenu.js:694 ../js/ui/userMenu.js:698
#: ../js/ui/userMenu.js:816 #: ../js/ui/userMenu.js:814
msgid "Suspend" msgid "Suspend"
msgstr "Ngưng" msgstr "Ngưng"
@ -412,58 +395,58 @@ msgstr "Ngưng"
msgid "Restart" msgid "Restart"
msgstr "Khởi động lại" msgstr "Khởi động lại"
#: ../js/gdm/powerMenu.js:103 ../js/ui/userMenu.js:698 #: ../js/gdm/powerMenu.js:103 ../js/ui/userMenu.js:696
#: ../js/ui/userMenu.js:700 ../js/ui/userMenu.js:815 ../js/ui/userMenu.js:942 #: ../js/ui/userMenu.js:698 ../js/ui/userMenu.js:813 ../js/ui/userMenu.js:936
msgid "Power Off" msgid "Power Off"
msgstr "Tắt máy" msgstr "Tắt máy"
#: ../js/gdm/util.js:249 #: ../js/gdm/util.js:182
msgid "Authentication error" msgid "Authentication error"
msgstr "Lỗi xác thực" msgstr "Lỗi xác thực"
#. Translators: this message is shown below the password entry field #. Translators: this message is shown below the password entry field
#. to indicate the user can swipe their finger instead #. to indicate the user can swipe their finger instead
#: ../js/gdm/util.js:366 #: ../js/gdm/util.js:299
msgid "(or swipe finger)" msgid "(or swipe finger)"
msgstr "(hoặc quẹt ngón tay)" msgstr "(hoặc quẹt ngón tay)"
#: ../js/gdm/util.js:391 #: ../js/gdm/util.js:324
#, c-format #, c-format
msgid "(e.g., user or %s)" msgid "(e.g., user or %s)"
msgstr "(ví dụ: tài khoản hoặc %s)" msgstr "(ví dụ người dùng hoặc %s)"
#: ../js/misc/util.js:97 #: ../js/misc/util.js:94
msgid "Command not found" msgid "Command not found"
msgstr "Không tìm thấy lệnh" msgstr "Không tìm thấy lệnh"
#. Replace "Error invoking GLib.shell_parse_argv: " with #. Replace "Error invoking GLib.shell_parse_argv: " with
#. something nicer #. something nicer
#: ../js/misc/util.js:130 #: ../js/misc/util.js:127
msgid "Could not parse command:" msgid "Could not parse command:"
msgstr "Không thể phân tích lệnh:" msgstr "Không thể phân tích lệnh:"
#: ../js/misc/util.js:138 #: ../js/misc/util.js:135
#, c-format #, c-format
msgid "Execution of '%s' failed:" msgid "Execution of '%s' failed:"
msgstr "Lỗi thực hiện %s:" msgstr "Lỗi thực hiện '%s':"
#: ../js/ui/appDisplay.js:349 #: ../js/ui/appDisplay.js:348
msgid "Frequent" msgid "Frequent"
msgstr "Thường dùng" msgstr "Thường dùng"
#: ../js/ui/appDisplay.js:356 #: ../js/ui/appDisplay.js:355
msgid "All" msgid "All"
msgstr "Tất cả" msgstr "Tất cả"
#: ../js/ui/appDisplay.js:914 #: ../js/ui/appDisplay.js:913
msgid "New Window" msgid "New Window"
msgstr "Cửa sổ mới" msgstr "Cửa sổ mới"
#: ../js/ui/appDisplay.js:917 ../js/ui/dash.js:284 #: ../js/ui/appDisplay.js:916 ../js/ui/dash.js:284
msgid "Remove from Favorites" msgid "Remove from Favorites"
msgstr "Bỏ đánh dấu ưa thích" msgstr "Bỏ đánh dấu ưa thích"
#: ../js/ui/appDisplay.js:918 #: ../js/ui/appDisplay.js:917
msgid "Add to Favorites" msgid "Add to Favorites"
msgstr "Đánh dấu ưa thích" msgstr "Đánh dấu ưa thích"
@ -477,13 +460,13 @@ msgstr "Đã được đánh dấu ưa thích cho %s."
msgid "%s has been removed from your favorites." msgid "%s has been removed from your favorites."
msgstr "Đã bỏ đánh dấu ưa thích cho %s" msgstr "Đã bỏ đánh dấu ưa thích cho %s"
#: ../js/ui/backgroundMenu.js:19 ../js/ui/userMenu.js:789 #: ../js/ui/backgroundMenu.js:19 ../js/ui/userMenu.js:787
msgid "Settings" msgid "Settings"
msgstr "Cài đặt" msgstr "Thiết lập"
#: ../js/ui/backgroundMenu.js:21 #: ../js/ui/backgroundMenu.js:21
msgid "Change Background…" msgid "Change Background…"
msgstr "Đổi ảnh nền…" msgstr "Thay đổi nền…"
#. Translators: Shown in calendar event list for all day events #. Translators: Shown in calendar event list for all day events
#. * Keep it short, best if you can use less then 10 characters #. * Keep it short, best if you can use less then 10 characters
@ -602,35 +585,35 @@ msgid "S"
msgstr "T7" msgstr "T7"
#. Translators: Text to show if there are no events #. Translators: Text to show if there are no events
#: ../js/ui/calendar.js:720 #: ../js/ui/calendar.js:692
msgid "Nothing Scheduled" msgid "Nothing Scheduled"
msgstr "Không có lịch hẹn" msgstr "Không có lịch hẹn"
#. Translators: Shown on calendar heading when selected day occurs on current year #. Translators: Shown on calendar heading when selected day occurs on current year
#: ../js/ui/calendar.js:736 #: ../js/ui/calendar.js:708
msgctxt "calendar heading" msgctxt "calendar heading"
msgid "%A, %B %d" msgid "%A, %B %d"
msgstr "%A, %d %B" msgstr "%A, %d %B"
#. Translators: Shown on calendar heading when selected day occurs on different year #. Translators: Shown on calendar heading when selected day occurs on different year
#: ../js/ui/calendar.js:739 #: ../js/ui/calendar.js:711
msgctxt "calendar heading" msgctxt "calendar heading"
msgid "%A, %B %d, %Y" msgid "%A, %B %d, %Y"
msgstr "%A, %d %B %Y" msgstr "%A, %d %B %Y"
#: ../js/ui/calendar.js:749 #: ../js/ui/calendar.js:721
msgid "Today" msgid "Today"
msgstr "Hôm nay" msgstr "Hôm nay"
#: ../js/ui/calendar.js:753 #: ../js/ui/calendar.js:725
msgid "Tomorrow" msgid "Tomorrow"
msgstr "Ngày mai" msgstr "Ngày mai"
#: ../js/ui/calendar.js:764 #: ../js/ui/calendar.js:736
msgid "This week" msgid "This week"
msgstr "Tuần này" msgstr "Tuần này"
#: ../js/ui/calendar.js:772 #: ../js/ui/calendar.js:744
msgid "Next week" msgid "Next week"
msgstr "Tuần tới" msgstr "Tuần tới"
@ -646,12 +629,12 @@ msgstr "Ổ ngoài đã ngắt kết nối"
msgid "Removable Devices" msgid "Removable Devices"
msgstr "Thiết bị di động" msgstr "Thiết bị di động"
#: ../js/ui/components/autorunManager.js:594 #: ../js/ui/components/autorunManager.js:593
#, c-format #, c-format
msgid "Open with %s" msgid "Open with %s"
msgstr "Mở bằng %s" msgstr "Mở bằng %s"
#: ../js/ui/components/autorunManager.js:620 #: ../js/ui/components/autorunManager.js:619
msgid "Eject" msgid "Eject"
msgstr "Đẩy ra" msgstr "Đẩy ra"
@ -702,7 +685,7 @@ msgstr "Mạng không dây cần xác thực"
msgid "" msgid ""
"Passwords or encryption keys are required to access the wireless network " "Passwords or encryption keys are required to access the wireless network "
"'%s'." "'%s'."
msgstr "Cần mật mã hoặc khoá mã để truy cập mạng không dây %s" msgstr "Cần mật mã hoặc khoá mã để truy cập mạng không dây '%s'"
#: ../js/ui/components/networkAgent.js:314 #: ../js/ui/components/networkAgent.js:314
msgid "Wired 802.1X authentication" msgid "Wired 802.1X authentication"
@ -735,7 +718,7 @@ msgstr "Mật khẩu mạng băng thông rộng"
#: ../js/ui/components/networkAgent.js:337 #: ../js/ui/components/networkAgent.js:337
#, c-format #, c-format
msgid "A password is required to connect to '%s'." msgid "A password is required to connect to '%s'."
msgstr "Cần mật khẩu để kết nối đến %s." msgstr "Cần mật khẩu để kết nối đến '%s'."
#: ../js/ui/components/polkitAgent.js:55 #: ../js/ui/components/polkitAgent.js:55
msgid "Authentication Required" msgid "Authentication Required"
@ -789,7 +772,7 @@ msgstr "Ngừng im lặng"
#: ../js/ui/components/telepathyClient.js:480 #: ../js/ui/components/telepathyClient.js:480
msgid "Mute" msgid "Mute"
msgstr "Câm" msgstr "Im lặng"
#. Translators: this is the word "Yesterday" followed by a time string. i.e. "Yesterday, 14:30" #. Translators: this is the word "Yesterday" followed by a time string. i.e. "Yesterday, 14:30"
#: ../js/ui/components/telepathyClient.js:942 #: ../js/ui/components/telepathyClient.js:942
@ -1000,7 +983,7 @@ msgstr "Xem tài khoản"
msgid "Unknown reason" msgid "Unknown reason"
msgstr "Lý do không biết" msgstr "Lý do không biết"
#: ../js/ui/ctrlAltTab.js:29 ../js/ui/viewSelector.js:96 #: ../js/ui/ctrlAltTab.js:29 ../js/ui/viewSelector.js:97
msgid "Windows" msgid "Windows"
msgstr "Cửa sổ" msgstr "Cửa sổ"
@ -1029,7 +1012,7 @@ msgstr "Thiết lập ngày giờ"
#. Translators: This is the date format to use when the calendar popup is #. Translators: This is the date format to use when the calendar popup is
#. * shown - it is shown just below the time in the shell (e.g. "Tue 9:29 AM"). #. * shown - it is shown just below the time in the shell (e.g. "Tue 9:29 AM").
#. #.
#: ../js/ui/dateMenu.js:215 #: ../js/ui/dateMenu.js:205
msgid "%A %B %e, %Y" msgid "%A %B %e, %Y"
msgstr "%A %e %B, %Y" msgstr "%A %e %B, %Y"
@ -1125,7 +1108,7 @@ msgstr "Cài đặt"
#: ../js/ui/extensionDownloader.js:204 #: ../js/ui/extensionDownloader.js:204
#, c-format #, c-format
msgid "Download and install '%s' from extensions.gnome.org?" msgid "Download and install '%s' from extensions.gnome.org?"
msgstr "Tải và cài đặt %s từ extensions.gnome.org chứ?" msgstr "Tải và cài đặt '%s' từ extensions.gnome.org chứ?"
#: ../js/ui/keyboard.js:619 ../js/ui/status/keyboard.js:314 #: ../js/ui/keyboard.js:619 ../js/ui/status/keyboard.js:314
#: ../js/ui/status/power.js:211 #: ../js/ui/status/power.js:211
@ -1154,7 +1137,9 @@ msgstr "Hiện lỗi"
msgid "Enabled" msgid "Enabled"
msgstr "Bật" msgstr "Bật"
#: ../js/ui/lookingGlass.js:769 #. translators:
#. * The device has been disabled
#: ../js/ui/lookingGlass.js:769 ../src/gvc/gvc-mixer-control.c:1830
msgid "Disabled" msgid "Disabled"
msgstr "Tắt" msgstr "Tắt"
@ -1194,15 +1179,15 @@ msgstr "Xoá thông báo"
msgid "Notification Settings" msgid "Notification Settings"
msgstr "Thiết lập thông báo" msgstr "Thiết lập thông báo"
#: ../js/ui/messageTray.js:1709 #: ../js/ui/messageTray.js:1707
msgid "No Messages" msgid "No Messages"
msgstr "Không có thông báo" msgstr "Không có thông báo"
#: ../js/ui/messageTray.js:1782 #: ../js/ui/messageTray.js:1787
msgid "Message Tray" msgid "Message Tray"
msgstr "Khay thông báo" msgstr "Khay thông báo"
#: ../js/ui/messageTray.js:2810 #: ../js/ui/messageTray.js:2864
msgid "System Information" msgid "System Information"
msgstr "Thông tin hệ thống" msgstr "Thông tin hệ thống"
@ -1211,13 +1196,13 @@ msgctxt "program"
msgid "Unknown" msgid "Unknown"
msgstr "Không biết" msgstr "Không biết"
#: ../js/ui/overviewControls.js:463 ../js/ui/screenShield.js:149 #: ../js/ui/overviewControls.js:460 ../js/ui/screenShield.js:153
#, c-format #, c-format
msgid "%d new message" msgid "%d new message"
msgid_plural "%d new messages" msgid_plural "%d new messages"
msgstr[0] "%d tin nhắn mới" msgstr[0] "%d tin nhắn mới"
#: ../js/ui/overview.js:84 #: ../js/ui/overview.js:82
msgid "Undo" msgid "Undo"
msgstr "Hoàn lại" msgstr "Hoàn lại"
@ -1229,21 +1214,21 @@ msgstr "Tổng quan"
#. in the search entry when no search is #. in the search entry when no search is
#. active; it should not exceed ~30 #. active; it should not exceed ~30
#. characters. #. characters.
#: ../js/ui/overview.js:271 #: ../js/ui/overview.js:284
msgid "Type to search…" msgid "Type to search…"
msgstr "Nhập để tìm…" msgstr "Nhập để tìm…"
#: ../js/ui/panel.js:612 #: ../js/ui/panel.js:613
msgid "Quit" msgid "Quit"
msgstr "Thoát" msgstr "Thoát"
#. Translators: If there is no suitable word for "Activities" #. Translators: If there is no suitable word for "Activities"
#. in your language, you can use the word for "Overview". #. in your language, you can use the word for "Overview".
#: ../js/ui/panel.js:636 #: ../js/ui/panel.js:642
msgid "Activities" msgid "Activities"
msgstr "Hoạt động" msgstr "Hoạt động"
#: ../js/ui/panel.js:933 #: ../js/ui/panel.js:983
msgid "Top Bar" msgid "Top Bar"
msgstr "Thanh đỉnh" msgstr "Thanh đỉnh"
@ -1256,31 +1241,31 @@ msgstr "Thanh đỉnh"
msgid "toggle-switch-us" msgid "toggle-switch-us"
msgstr "toggle-switch-intl" msgstr "toggle-switch-intl"
#: ../js/ui/runDialog.js:73 #: ../js/ui/runDialog.js:205
msgid "Enter a Command" msgid "Enter a Command"
msgstr "Nhập lệnh" msgstr "Nhập lệnh"
#: ../js/ui/runDialog.js:109 #: ../js/ui/runDialog.js:241
msgid "Close" msgid "Close"
msgstr "Đóng" msgstr "Đóng"
#. Translators: This is a time format for a date in #. Translators: This is a time format for a date in
#. long format #. long format
#: ../js/ui/screenShield.js:86 #: ../js/ui/screenShield.js:90
msgid "%A, %B %d" msgid "%A, %B %d"
msgstr "%A, %d %B" msgstr "%A, %d %B"
#: ../js/ui/screenShield.js:151 #: ../js/ui/screenShield.js:155
#, c-format #, c-format
msgid "%d new notification" msgid "%d new notification"
msgid_plural "%d new notifications" msgid_plural "%d new notifications"
msgstr[0] "%d thông báo mới" msgstr[0] "%d thông báo mới"
#: ../js/ui/screenShield.js:438 ../js/ui/userMenu.js:807 #: ../js/ui/screenShield.js:442 ../js/ui/userMenu.js:805
msgid "Lock" msgid "Lock"
msgstr "Khoá" msgstr "Khoá"
#: ../js/ui/screenShield.js:637 #: ../js/ui/screenShield.js:639
msgid "GNOME needs to lock the screen" msgid "GNOME needs to lock the screen"
msgstr "GNOME cần khoá màn hình" msgstr "GNOME cần khoá màn hình"
@ -1291,19 +1276,19 @@ msgstr "GNOME cần khoá màn hình"
#. #.
#. XXX: another option is to kick the user into the gdm login #. XXX: another option is to kick the user into the gdm login
#. screen, where we're not affected by grabs #. screen, where we're not affected by grabs
#: ../js/ui/screenShield.js:758 ../js/ui/screenShield.js:1194 #: ../js/ui/screenShield.js:758 ../js/ui/screenShield.js:1169
msgid "Unable to lock" msgid "Unable to lock"
msgstr "Không thể khoá" msgstr "Không thể khoá"
#: ../js/ui/screenShield.js:759 ../js/ui/screenShield.js:1195 #: ../js/ui/screenShield.js:759 ../js/ui/screenShield.js:1170
msgid "Lock was blocked by an application" msgid "Lock was blocked by an application"
msgstr "Một ứng dụng đã ngăn cản khoá" msgstr "Một ứng dụng đã ngăn cản khoá"
#: ../js/ui/searchDisplay.js:453 #: ../js/ui/searchDisplay.js:431
msgid "Searching…" msgid "Searching…"
msgstr "Đang tìm…" msgstr "Đang tìm…"
#: ../js/ui/searchDisplay.js:497 #: ../js/ui/searchDisplay.js:475
msgid "No results." msgid "No results."
msgstr "Không có kết quả." msgstr "Không có kết quả."
@ -1315,11 +1300,11 @@ msgstr "Chép"
msgid "Paste" msgid "Paste"
msgstr "Dán" msgstr "Dán"
#: ../js/ui/shellEntry.js:106 #: ../js/ui/shellEntry.js:105
msgid "Show Text" msgid "Show Text"
msgstr "Hiện chữ" msgstr "Hiện chữ"
#: ../js/ui/shellEntry.js:108 #: ../js/ui/shellEntry.js:107
msgid "Hide Text" msgid "Hide Text"
msgstr "Ẩn chữ" msgstr "Ẩn chữ"
@ -1331,7 +1316,7 @@ msgstr "Mật khẩu"
msgid "Remember Password" msgid "Remember Password"
msgstr "Nhớ mật khẩu" msgstr "Nhớ mật khẩu"
#: ../js/ui/shellMountOperation.js:403 ../js/ui/unlockDialog.js:113 #: ../js/ui/shellMountOperation.js:403 ../js/ui/unlockDialog.js:140
msgid "Unlock" msgid "Unlock"
msgstr "Bỏ khoá" msgstr "Bỏ khoá"
@ -1448,7 +1433,7 @@ msgstr "Yêu cầu cấp quyền từ %s"
#: ../js/ui/status/bluetooth.js:328 #: ../js/ui/status/bluetooth.js:328
#, c-format #, c-format
msgid "Device %s wants access to the service '%s'" msgid "Device %s wants access to the service '%s'"
msgstr "Thiết bị %s muốn truy cập dịch vụ %s" msgstr "Thiết bị %s muốn truy cập dịch vụ '%s'"
#: ../js/ui/status/bluetooth.js:330 #: ../js/ui/status/bluetooth.js:330
msgid "Always grant access" msgid "Always grant access"
@ -1476,7 +1461,7 @@ msgstr "Thiết bị %s muốn kết nối với máy tính này"
#: ../js/ui/status/bluetooth.js:366 #: ../js/ui/status/bluetooth.js:366
#, c-format #, c-format
msgid "Please confirm whether the PIN '%06d' matches the one on the device." msgid "Please confirm whether the PIN '%06d' matches the one on the device."
msgstr "Vui lòng xác nhận PIN %06d khớp với số trên thiết bị." msgstr "Vui lòng xác nhận PIN '%06d' khớp với số trên thiết bị."
#. Translators: this is the verb, not the noun #. Translators: this is the verb, not the noun
#: ../js/ui/status/bluetooth.js:369 #: ../js/ui/status/bluetooth.js:369
@ -1732,59 +1717,59 @@ msgstr "Âm lượng"
msgid "Microphone" msgid "Microphone"
msgstr "Micrô" msgstr "Micrô"
#: ../js/ui/unlockDialog.js:124 #: ../js/ui/unlockDialog.js:151
msgid "Log in as another user" msgid "Log in as another user"
msgstr "Đăng nhập người dùng khác" msgstr "Đăng nhập người dùng khác"
#: ../js/ui/unlockDialog.js:145 #: ../js/ui/unlockDialog.js:177
msgid "Unlock Window" msgid "Unlock Window"
msgstr "Bỏ khoá cửa sổ" msgstr "Bỏ khoá cửa sổ"
#: ../js/ui/userMenu.js:193 #: ../js/ui/userMenu.js:192
msgid "Available" msgid "Available"
msgstr "Có mặt" msgstr "Có mặt"
#: ../js/ui/userMenu.js:196 #: ../js/ui/userMenu.js:195
msgid "Busy" msgid "Busy"
msgstr "Bận" msgstr "Bận"
#: ../js/ui/userMenu.js:199 #: ../js/ui/userMenu.js:198
msgid "Invisible" msgid "Invisible"
msgstr "Giấu mặt" msgstr "Giấu mặt"
#: ../js/ui/userMenu.js:202 #: ../js/ui/userMenu.js:201
msgid "Away" msgid "Away"
msgstr "Vắng mặt" msgstr "Vắng mặt"
#: ../js/ui/userMenu.js:205 #: ../js/ui/userMenu.js:204
msgid "Idle" msgid "Idle"
msgstr "Nhàn rỗi" msgstr "Nhàn rỗi"
#: ../js/ui/userMenu.js:208 #: ../js/ui/userMenu.js:207
msgid "Offline" msgid "Offline"
msgstr "Ngoại tuyến" msgstr "Ngoại tuyến"
#: ../js/ui/userMenu.js:781 #: ../js/ui/userMenu.js:779
msgid "Notifications" msgid "Notifications"
msgstr "Thông báo" msgstr "Thông báo"
#: ../js/ui/userMenu.js:797 #: ../js/ui/userMenu.js:795
msgid "Switch User" msgid "Switch User"
msgstr "Chuyển người dùng" msgstr "Chuyển người dùng"
#: ../js/ui/userMenu.js:802 #: ../js/ui/userMenu.js:800
msgid "Log Out" msgid "Log Out"
msgstr "Đăng xuất" msgstr "Đăng xuất"
#: ../js/ui/userMenu.js:822 #: ../js/ui/userMenu.js:820
msgid "Install Updates & Restart" msgid "Install Updates & Restart"
msgstr "Cài đặt bản cập nhật và khởi động lại" msgstr "Cài đặt bản cập nhật và khởi động lại"
#: ../js/ui/userMenu.js:840 #: ../js/ui/userMenu.js:838
msgid "Your chat status will be set to busy" msgid "Your chat status will be set to busy"
msgstr "Trạng thái nhắn tin của bạn sẽ được đặt là bận" msgstr "Trạng thái nhắn tin của bạn sẽ được đặt là bận"
#: ../js/ui/userMenu.js:841 #: ../js/ui/userMenu.js:839
msgid "" msgid ""
"Notifications are now disabled, including chat messages. Your online status " "Notifications are now disabled, including chat messages. Your online status "
"has been adjusted to let others know that you might not see their messages." "has been adjusted to let others know that you might not see their messages."
@ -1792,35 +1777,33 @@ msgstr ""
"Thông báo đã bị tắt, bao gồm tin nhắn. Trạng thái trực tuyến của bạn đã được " "Thông báo đã bị tắt, bao gồm tin nhắn. Trạng thái trực tuyến của bạn đã được "
"điều chỉnh để mọi người biết bạn sẽ không xem tin nhắn họ gửi đến." "điều chỉnh để mọi người biết bạn sẽ không xem tin nhắn họ gửi đến."
#: ../js/ui/userMenu.js:888 #: ../js/ui/userMenu.js:885
msgid "Other users are logged in." msgid "Other users are logged in."
msgstr "Người dùng khác đang đăng nhập." msgstr "Người dùng khác đang đăng nhập."
#: ../js/ui/userMenu.js:893 #: ../js/ui/userMenu.js:890
msgid "Shutting down might cause them to lose unsaved work." msgid "Shutting down might cause them to lose unsaved work."
msgstr "Tắt sẽ làm mất những kết quả chưa được lưu." msgstr "Tắt sẽ làm mất những kết quả chưa được lưu."
#. Translators: Remote here refers to a remote session, like a ssh login #: ../js/ui/userMenu.js:916
#: ../js/ui/userMenu.js:921
#, c-format #, c-format
msgid "%s (remote)" msgid "%s (remote)"
msgstr "%s (ở xa)" msgstr "%s (ở xa)"
#. Translators: Console here refers to a tty like a VT console #: ../js/ui/userMenu.js:918
#: ../js/ui/userMenu.js:924
#, c-format #, c-format
msgid "%s (console)" msgid "%s (console)"
msgstr "%s (console)" msgstr "%s (console)"
#: ../js/ui/viewSelector.js:100 #: ../js/ui/viewSelector.js:101
msgid "Applications" msgid "Applications"
msgstr "Ứng dụng" msgstr "Ứng dụng"
#: ../js/ui/viewSelector.js:104 #: ../js/ui/viewSelector.js:105
msgid "Search" msgid "Search"
msgstr "Tìm" msgstr "Tìm"
#: ../js/ui/wanda.js:77 #: ../js/ui/wanda.js:92
#, c-format #, c-format
msgid "" msgid ""
"Sorry, no wisdom for you today:\n" "Sorry, no wisdom for you today:\n"
@ -1829,7 +1812,7 @@ msgstr ""
"Rất tiếc, không có lời thông thái nào hôm nay:\n" "Rất tiếc, không có lời thông thái nào hôm nay:\n"
"%s" "%s"
#: ../js/ui/wanda.js:81 #: ../js/ui/wanda.js:96
#, c-format #, c-format
msgid "%s the Oracle says" msgid "%s the Oracle says"
msgstr "Nhà tiên tri %s nói" msgstr "Nhà tiên tri %s nói"
@ -1837,12 +1820,32 @@ msgstr "Nhà tiên tri %s nói"
#: ../js/ui/windowAttentionHandler.js:19 #: ../js/ui/windowAttentionHandler.js:19
#, c-format #, c-format
msgid "'%s' is ready" msgid "'%s' is ready"
msgstr "%s đã sẵn sàng" msgstr "'%s' đã sẵn sàng"
#: ../src/calendar-server/evolution-calendar.desktop.in.in.h:1 #: ../src/calendar-server/evolution-calendar.desktop.in.in.h:1
msgid "Evolution Calendar" msgid "Evolution Calendar"
msgstr "Lịch Evolution" msgstr "Lịch Evolution"
#. translators:
#. * The number of sound outputs on a particular device
#: ../src/gvc/gvc-mixer-control.c:1837
#, c-format
msgid "%u Output"
msgid_plural "%u Outputs"
msgstr[0] "%u đầu ra"
#. translators:
#. * The number of sound inputs on a particular device
#: ../src/gvc/gvc-mixer-control.c:1847
#, c-format
msgid "%u Input"
msgid_plural "%u Inputs"
msgstr[0] "%u đầu vào"
#: ../src/gvc/gvc-mixer-control.c:2371
msgid "System Sounds"
msgstr "Âm thanh hệ thống"
#: ../src/main.c:347 #: ../src/main.c:347
msgid "Print version" msgid "Print version"
msgstr "In phiên bản" msgstr "In phiên bản"
@ -1853,7 +1856,7 @@ msgstr "Chể độ dùng bởi GDM cho màn hình đăng nhập"
#: ../src/main.c:359 #: ../src/main.c:359
msgid "Use a specific mode, e.g. \"gdm\" for login screen" msgid "Use a specific mode, e.g. \"gdm\" for login screen"
msgstr "Dùng chế độ đặc biệt, ví dụ gdm cho màn hình đăng nhập" msgstr "Dùng chế độ đặc biệt, ví dụ \"gdm\" cho màn hình đăng nhập"
#: ../src/main.c:365 #: ../src/main.c:365
msgid "List possible modes" msgid "List possible modes"
@ -1862,7 +1865,7 @@ msgstr "Danh sách chế độ"
#: ../src/shell-app.c:622 #: ../src/shell-app.c:622
#, c-format #, c-format
msgid "Failed to launch '%s'" msgid "Failed to launch '%s'"
msgstr "Lỗi chạy %s" msgstr "Lỗi chạy '%s'"
#: ../src/shell-keyring-prompt.c:708 #: ../src/shell-keyring-prompt.c:708
msgid "Passwords do not match." msgid "Passwords do not match."
@ -1876,17 +1879,6 @@ msgstr "Mật khẩu không thể không có"
msgid "Authentication dialog was dismissed by the user" msgid "Authentication dialog was dismissed by the user"
msgstr "Hộp thoại xác thực bị người dùng bỏ qua" msgstr "Hộp thoại xác thực bị người dùng bỏ qua"
#~ msgid "%u Output"
#~ msgid_plural "%u Outputs"
#~ msgstr[0] "%u đầu ra"
#~ msgid "%u Input"
#~ msgid_plural "%u Inputs"
#~ msgstr[0] "%u đầu vào"
#~ msgid "System Sounds"
#~ msgstr "Âm thanh hệ thống"
#~ msgctxt "title" #~ msgctxt "title"
#~ msgid "Sign In" #~ msgid "Sign In"
#~ msgstr "Đăng nhập" #~ msgstr "Đăng nhập"
@ -1918,7 +1910,7 @@ msgstr "Hộp thoại xác thực bị người dùng bỏ qua"
#~ msgstr "%l:%M %p" #~ msgstr "%l:%M %p"
#~ msgid "Failed to unmount '%s'" #~ msgid "Failed to unmount '%s'"
#~ msgstr "Lỗi bỏ gắn kết %s" #~ msgstr "Lỗi bỏ gắn kết '%s'"
#~ msgid "Retry" #~ msgid "Retry"
#~ msgstr "Thử lại" #~ msgstr "Thử lại"
@ -1933,7 +1925,7 @@ msgstr "Hộp thoại xác thực bị người dùng bỏ qua"
#~ msgstr "Lỗi duyệt tập tin" #~ msgstr "Lỗi duyệt tập tin"
#~ msgid "The requested device cannot be browsed, error is '%s'" #~ msgid "The requested device cannot be browsed, error is '%s'"
#~ msgstr "Không thể duyệt thiết bị yêu cầu , lỗi là %s" #~ msgstr "Không thể duyệt thiết bị yêu cầu , lỗi là '%s'"
#~ msgid "Wireless" #~ msgid "Wireless"
#~ msgstr "Mạng không dây" #~ msgstr "Mạng không dây"
@ -2078,3 +2070,155 @@ msgstr "Hộp thoại xác thực bị người dùng bỏ qua"
#~ msgid "Show password" #~ msgid "Show password"
#~ msgstr "Hiện mật khẩu" #~ msgstr "Hiện mật khẩu"
#~| msgid "If true, display seconds in time."
#~ msgid "If true, display onscreen keyboard."
#~ msgstr "Nếu đúng (true), hiện bàn phím màn hình."
#~| msgid "Screen Keyboard"
#~ msgid "Show the onscreen keyboard"
#~ msgstr "Hiện bàn phím màn hình"
#~ msgid "%s has finished starting"
#~ msgstr "%s đã hoàn tất khởi chạy"
#~ msgid "Uuids of extensions to disable"
#~ msgstr "UUID của phần mở rộng cần tắt"
#~ msgid "You're now connected to mobile broadband connection '%s'"
#~ msgstr "Đã nối mạng '%s' (băng thông rộng)"
#~ msgid "You're now connected to wireless network '%s'"
#~ msgstr "Đã nối mạng '%s' (không dây)"
#~ msgid "You're now connected to wired network '%s'"
#~ msgstr "Đã nối mạng '%s' (dây)"
#~ msgid "You're now connected to VPN network '%s'"
#~ msgstr "Đã nối mạng VPN '%s'"
#~ msgid "Localization Settings"
#~ msgstr "Thiết lập bản địa hoá"
#~ msgid "Less than a minute ago"
#~ msgstr "Chưa đến một phút"
#~ msgid "%d minute ago"
#~ msgid_plural "%d minutes ago"
#~ msgstr[0] "%d phút trước"
#~ msgid "%d hour ago"
#~ msgid_plural "%d hours ago"
#~ msgstr[0] "%d giờ trước"
#~ msgid "%d day ago"
#~ msgid_plural "%d days ago"
#~ msgstr[0] "%d ngày trước"
#~ msgid "%d week ago"
#~ msgid_plural "%d weeks ago"
#~ msgstr[0] "%d tuần trước"
#~ msgid "Shut Down"
#~ msgstr "Tắt máy"
#~ msgid "Click Shut Down to quit these applications and shut down the system."
#~ msgstr "Nhấn Tắt máy để thoát những ứng dụng này và tắt hệ thống."
#~ msgid "The system will shut down automatically in %d seconds."
#~ msgstr "Hệ thống sẽ tự động tắt sau %d giây."
#~ msgid "Shutting down the system."
#~ msgstr "Tắt hệ thống."
#~ msgid "Confirm"
#~ msgstr "Xác nhận"
#~ msgid "Clip the crosshairs at the center"
#~ msgstr "Cắt lưới chéo ở giữa"
#~ msgid "Color of the crosshairs"
#~ msgstr "Màu lưới chéo"
#~ msgid ""
#~ "Determines the length of the vertical and horizontal lines that make up "
#~ "the crosshairs."
#~ msgstr "Xác định độ dài và rộng của những dòng tạo nên lưới chéo."
#~ msgid ""
#~ "Determines the transparency of the crosshairs, from fully opaque to fully "
#~ "transparent."
#~ msgstr "Xác định độ trong suốt của lưới chéo, từ đặc đến trong suốt."
#~ msgid "Enable lens mode"
#~ msgstr "Bật chế độ gương"
#~ msgid "Show or hide crosshairs"
#~ msgstr "Hiện hoặc ẩn lưới chéo"
#~ msgid "Show or hide the magnifier"
#~ msgstr "Hiện hoặc ẩn kính lúp"
#~ msgid "Thickness of the crosshairs"
#~ msgstr "Độ dày lưới chéo"
#~ msgid ""
#~ "Width of the vertical and horizontal lines that make up the crosshairs."
#~ msgstr "Độ rộng của đường dọc/ngang hình thành dấu gạch chéo."
#~ msgid "PREFERENCES"
#~ msgstr "TUỲ THÍCH"
#~ msgid "Shut Down..."
#~ msgstr "Tắt máy..."
#~ msgid "Search your computer"
#~ msgstr "Tìm trong máy"
#~ msgid "Customize the panel clock"
#~ msgstr "Tuỳ biến đồng hồ"
#~ msgid "Clock Format"
#~ msgstr "Dạng đồng hồ"
#~| msgid "System Preferences..."
#~ msgid "Clock Preferences"
#~ msgstr "Thiết lập đồng hồ"
#~ msgid "Panel Display"
#~ msgstr "Khung hiển thị"
#~ msgid "Show seco_nds"
#~ msgstr "Hiện _giây"
#~ msgid "_12 hour format"
#~ msgstr "Dạng _12 giờ"
#~ msgid "_24 hour format"
#~ msgstr "Dạng _24 giờ"
#~| msgid "System Preferences..."
#~ msgid "Preferences"
#~ msgstr "Thiết lập"
#~ msgid ""
#~ "Can't add a new workspace because maximum workspaces limit has been "
#~ "reached."
#~ msgstr ""
#~ "Không thể thêm vùng làm việc mới vì đã đạt giới hạn số vùng làm việc tối "
#~ "đa."
#~ msgid "Can't remove the first workspace."
#~ msgstr "Không thể bỏ vùng làm việc đầu tiên."
#~ msgid "Drag here to add favorites"
#~ msgstr "Kéo vào đây để thêm vào danh mục ưa thích"
#~ msgid "Find..."
#~ msgstr "Tìm"
#~ msgid "Sidebar"
#~ msgstr "Thanh bên"
#~ msgid "Recent Documents"
#~ msgstr "Tài liệu gần đây"

View File

@ -129,18 +129,13 @@ shell_public_headers_h = \
shell-wm.h \ shell-wm.h \
shell-xfixes-cursor.h shell-xfixes-cursor.h
shell_private_sources = \ shell_private_sources = \
gtkactionmuxer.h \ gactionmuxer.h \
gtkactionmuxer.c \ gactionmuxer.c \
gtkactionobservable.h \ gactionobservable.h \
gtkactionobservable.c \ gactionobservable.c \
gtkactionobserver.h \ gactionobserver.h \
gtkactionobserver.c \ gactionobserver.c
gtkmenutrackeritem.c \
gtkmenutrackeritem.h \
gtkmenutracker.c \
gtkmenutracker.h \
$(NULL)
libgnome_shell_la_SOURCES = \ libgnome_shell_la_SOURCES = \
$(shell_built_sources) \ $(shell_built_sources) \
@ -163,8 +158,6 @@ libgnome_shell_la_SOURCES = \
shell-invert-lightness-effect.c \ shell-invert-lightness-effect.c \
shell-keyring-prompt.h \ shell-keyring-prompt.h \
shell-keyring-prompt.c \ shell-keyring-prompt.c \
shell-menu-tracker.c \
shell-menu-tracker.h \
shell-mount-operation.c \ shell-mount-operation.c \
shell-network-agent.c \ shell-network-agent.c \
shell-perf-log.c \ shell-perf-log.c \
@ -293,34 +286,12 @@ libgnome_shell_la_LIBADD = \
libgnome_shell_la_CPPFLAGS = $(gnome_shell_cflags) libgnome_shell_la_CPPFLAGS = $(gnome_shell_cflags)
ShellMenu-0.1.gir: libgnome-shell.la Shell-0.1.gir: libgnome-shell.la St-1.0.gir
ShellMenu_0_1_gir_INCLUDES = Gio-2.0
ShellMenu_0_1_gir_CFLAGS = $(libgnome_shell_la_CPPFLAGS) -I $(srcdir)
ShellMenu_0_1_gir_LIBS = libgnome-shell.la
ShellMenu_0_1_gir_FILES = \
gtkactionmuxer.h \
gtkactionmuxer.c \
gtkactionobservable.h \
gtkactionobservable.c \
gtkactionobserver.h \
gtkactionobserver.c \
gtkmenutrackeritem.c \
gtkmenutrackeritem.h \
$(NULL)
ShellMenu_0_1_gir_SCANNERFLAGS = \
--namespace=ShellMenu --identifier-prefix=Gtk \
$(if $(BLUETOOTH_DIR),-L $(BLUETOOTH_DIR),)
INTROSPECTION_GIRS += ShellMenu-0.1.gir
CLEANFILES += ShellMenu-0.1.gir
Shell-0.1.gir: libgnome-shell.la St-1.0.gir ShellMenu-0.1.gir
Shell_0_1_gir_INCLUDES = Clutter-1.0 ClutterX11-1.0 Meta-3.0 TelepathyGLib-0.12 Soup-2.4 GMenu-3.0 NetworkManager-1.0 NMClient-1.0 Shell_0_1_gir_INCLUDES = Clutter-1.0 ClutterX11-1.0 Meta-3.0 TelepathyGLib-0.12 Soup-2.4 GMenu-3.0 NetworkManager-1.0 NMClient-1.0
Shell_0_1_gir_CFLAGS = $(libgnome_shell_la_CPPFLAGS) -I $(srcdir) Shell_0_1_gir_CFLAGS = $(libgnome_shell_la_CPPFLAGS) -I $(srcdir)
Shell_0_1_gir_LIBS = libgnome-shell.la Shell_0_1_gir_LIBS = libgnome-shell.la
Shell_0_1_gir_FILES = $(libgnome_shell_la_gir_sources) Shell_0_1_gir_FILES = $(libgnome_shell_la_gir_sources)
Shell_0_1_gir_SCANNERFLAGS = \ Shell_0_1_gir_SCANNERFLAGS = --include-uninstalled=$(builddir)/St-1.0.gir \
--include-uninstalled=$(builddir)/St-1.0.gir \
--include-uninstalled=$(builddir)/ShellMenu-0.1.gir \
--add-include-path=$(MUTTER_GIR_DIR) $(if $(BLUETOOTH_DIR),-L $(BLUETOOTH_DIR),) --add-include-path=$(MUTTER_GIR_DIR) $(if $(BLUETOOTH_DIR),-L $(BLUETOOTH_DIR),)
INTROSPECTION_GIRS += Shell-0.1.gir INTROSPECTION_GIRS += Shell-0.1.gir
CLEANFILES += Shell-0.1.gir CLEANFILES += Shell-0.1.gir

546
src/gactionmuxer.c Normal file
View File

@ -0,0 +1,546 @@
/*
* Copyright © 2011 Canonical Limited
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the licence, or (at your option) any later version.
*
* This library is distributed in the hope that 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 library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*
* Author: Ryan Lortie <desrt@desrt.ca>
*/
#include "config.h"
#include "gactionmuxer.h"
#include "gactionobservable.h"
#include "gactionobserver.h"
#include <clutter/clutter.h>
#include <string.h>
/*
* SECTION:gactionmuxer
* @short_description: Aggregate and monitor several action groups
*
* #GActionMuxer is a #GActionGroup and #GActionObservable that is
* capable of containing other #GActionGroup instances.
*
* The typical use is aggregating all of the actions applicable to a
* particular context into a single action group, with namespacing.
*
* Consider the case of two action groups -- one containing actions
* applicable to an entire application (such as 'quit') and one
* containing actions applicable to a particular window in the
* application (such as 'fullscreen').
*
* In this case, each of these action groups could be added to a
* #GActionMuxer with the prefixes "app" and "win", respectively. This
* would expose the actions as "app.quit" and "win.fullscreen" on the
* #GActionGroup interface presented by the #GActionMuxer.
*
* Activations and state change requests on the #GActionMuxer are wired
* through to the underlying action group in the expected way.
*
* This class is typically only used at the site of "consumption" of
* actions (eg: when displaying a menu that contains many actions on
* different objects).
*/
static void g_action_muxer_group_iface_init (GActionGroupInterface *iface);
static void g_action_muxer_observable_iface_init (GActionObservableInterface *iface);
typedef GObjectClass GActionMuxerClass;
struct _GActionMuxer
{
GObject parent_instance;
GHashTable *actions;
GHashTable *groups;
};
G_DEFINE_TYPE_WITH_CODE (GActionMuxer, g_action_muxer, G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (G_TYPE_ACTION_GROUP, g_action_muxer_group_iface_init)
G_IMPLEMENT_INTERFACE (G_TYPE_ACTION_OBSERVABLE, g_action_muxer_observable_iface_init))
typedef struct
{
GActionMuxer *muxer;
GSList *watchers;
gchar *fullname;
} Action;
typedef struct
{
GActionMuxer *muxer;
GActionGroup *group;
gchar *prefix;
gulong handler_ids[4];
} Group;
static gchar **
g_action_muxer_list_actions (GActionGroup *action_group)
{
GActionMuxer *muxer = G_ACTION_MUXER (action_group);
GHashTableIter iter;
gchar *key;
gchar **keys;
gsize i;
keys = g_new (gchar *, g_hash_table_size (muxer->actions) + 1);
i = 0;
g_hash_table_iter_init (&iter, muxer->actions);
while (g_hash_table_iter_next (&iter, (gpointer *) &key, NULL))
keys[i++] = g_strdup (key);
keys[i] = NULL;
return keys;
}
static Group *
g_action_muxer_find_group (GActionMuxer *muxer,
const gchar **name)
{
const gchar *dot;
gchar *prefix;
Group *group;
dot = strchr (*name, '.');
if (!dot)
return NULL;
prefix = g_strndup (*name, dot - *name);
group = g_hash_table_lookup (muxer->groups, prefix);
g_free (prefix);
*name = dot + 1;
return group;
}
static Action *
g_action_muxer_lookup_action (GActionMuxer *muxer,
const gchar *prefix,
const gchar *action_name,
gchar **fullname)
{
Action *action;
*fullname = g_strconcat (prefix, ".", action_name, NULL);
action = g_hash_table_lookup (muxer->actions, *fullname);
return action;
}
static void
g_action_muxer_action_enabled_changed (GActionGroup *action_group,
const gchar *action_name,
gboolean enabled,
gpointer user_data)
{
Group *group = user_data;
gchar *fullname;
Action *action;
GSList *node;
action = g_action_muxer_lookup_action (group->muxer, group->prefix, action_name, &fullname);
for (node = action ? action->watchers : NULL; node; node = node->next)
g_action_observer_action_enabled_changed (node->data, G_ACTION_OBSERVABLE (group->muxer), fullname, enabled);
g_action_group_action_enabled_changed (G_ACTION_GROUP (group->muxer), fullname, enabled);
g_free (fullname);
}
static void
g_action_muxer_action_state_changed (GActionGroup *action_group,
const gchar *action_name,
GVariant *state,
gpointer user_data)
{
Group *group = user_data;
gchar *fullname;
Action *action;
GSList *node;
action = g_action_muxer_lookup_action (group->muxer, group->prefix, action_name, &fullname);
for (node = action ? action->watchers : NULL; node; node = node->next)
g_action_observer_action_state_changed (node->data, G_ACTION_OBSERVABLE (group->muxer), fullname, state);
g_action_group_action_state_changed (G_ACTION_GROUP (group->muxer), fullname, state);
g_free (fullname);
}
static void
g_action_muxer_action_added (GActionGroup *action_group,
const gchar *action_name,
gpointer user_data)
{
const GVariantType *parameter_type;
Group *group = user_data;
gboolean enabled;
GVariant *state;
if (g_action_group_query_action (group->group, action_name, &enabled, &parameter_type, NULL, NULL, &state))
{
gchar *fullname;
Action *action;
GSList *node;
action = g_action_muxer_lookup_action (group->muxer, group->prefix, action_name, &fullname);
for (node = action ? action->watchers : NULL; node; node = node->next)
g_action_observer_action_added (node->data,
G_ACTION_OBSERVABLE (group->muxer),
fullname, parameter_type, enabled, state);
g_action_group_action_added (G_ACTION_GROUP (group->muxer), fullname);
if (state)
g_variant_unref (state);
g_free (fullname);
}
}
static void
g_action_muxer_action_removed (GActionGroup *action_group,
const gchar *action_name,
gpointer user_data)
{
Group *group = user_data;
gchar *fullname;
Action *action;
GSList *node;
action = g_action_muxer_lookup_action (group->muxer, group->prefix, action_name, &fullname);
for (node = action ? action->watchers : NULL; node; node = node->next)
g_action_observer_action_removed (node->data, G_ACTION_OBSERVABLE (group->muxer), fullname);
g_action_group_action_removed (G_ACTION_GROUP (group->muxer), fullname);
g_free (fullname);
}
static gboolean
g_action_muxer_query_action (GActionGroup *action_group,
const gchar *action_name,
gboolean *enabled,
const GVariantType **parameter_type,
const GVariantType **state_type,
GVariant **state_hint,
GVariant **state)
{
GActionMuxer *muxer = G_ACTION_MUXER (action_group);
Group *group;
group = g_action_muxer_find_group (muxer, &action_name);
if (!group)
return FALSE;
return g_action_group_query_action (group->group, action_name, enabled,
parameter_type, state_type, state_hint, state);
}
static GVariant *
get_platform_data (void)
{
gchar time[32];
GVariantBuilder *builder;
GVariant *result;
g_snprintf (time, 32, "_TIME%d", clutter_get_current_event_time ());
builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}"));
g_variant_builder_add (builder, "{sv}", "desktop-startup-id",
g_variant_new_string (time));
result = g_variant_builder_end (builder);
g_variant_builder_unref (builder);
return result;
}
static void
g_action_muxer_activate_action (GActionGroup *action_group,
const gchar *action_name,
GVariant *parameter)
{
GActionMuxer *muxer = G_ACTION_MUXER (action_group);
Group *group;
group = g_action_muxer_find_group (muxer, &action_name);
if (group)
{
if (G_IS_REMOTE_ACTION_GROUP (group->group))
g_remote_action_group_activate_action_full (G_REMOTE_ACTION_GROUP (group->group),
action_name,
parameter,
get_platform_data ());
else
g_action_group_activate_action (group->group, action_name, parameter);
}
}
static void
g_action_muxer_change_action_state (GActionGroup *action_group,
const gchar *action_name,
GVariant *state)
{
GActionMuxer *muxer = G_ACTION_MUXER (action_group);
Group *group;
group = g_action_muxer_find_group (muxer, &action_name);
if (group)
{
if (G_IS_REMOTE_ACTION_GROUP (group->group))
g_remote_action_group_change_action_state_full (G_REMOTE_ACTION_GROUP (group->group),
action_name,
state,
get_platform_data ());
else
g_action_group_change_action_state (group->group, action_name, state);
}
}
static void
g_action_muxer_unregister_internal (Action *action,
gpointer observer)
{
GActionMuxer *muxer = action->muxer;
GSList **ptr;
for (ptr = &action->watchers; *ptr; ptr = &(*ptr)->next)
if ((*ptr)->data == observer)
{
*ptr = g_slist_remove (*ptr, observer);
if (action->watchers == NULL)
{
g_hash_table_remove (muxer->actions, action->fullname);
g_free (action->fullname);
g_slice_free (Action, action);
g_object_unref (muxer);
}
break;
}
}
static void
g_action_muxer_weak_notify (gpointer data,
GObject *where_the_object_was)
{
Action *action = data;
g_action_muxer_unregister_internal (action, where_the_object_was);
}
static void
g_action_muxer_register_observer (GActionObservable *observable,
const gchar *name,
GActionObserver *observer)
{
GActionMuxer *muxer = G_ACTION_MUXER (observable);
Action *action;
action = g_hash_table_lookup (muxer->actions, name);
if (action == NULL)
{
action = g_slice_new (Action);
action->muxer = g_object_ref (muxer);
action->fullname = g_strdup (name);
action->watchers = NULL;
g_hash_table_insert (muxer->actions, action->fullname, action);
}
action->watchers = g_slist_prepend (action->watchers, observer);
g_object_weak_ref (G_OBJECT (observer), g_action_muxer_weak_notify, action);
}
static void
g_action_muxer_unregister_observer (GActionObservable *observable,
const gchar *name,
GActionObserver *observer)
{
GActionMuxer *muxer = G_ACTION_MUXER (observable);
Action *action;
action = g_hash_table_lookup (muxer->actions, name);
g_object_weak_unref (G_OBJECT (observer), g_action_muxer_weak_notify, action);
g_action_muxer_unregister_internal (action, observer);
}
static void
g_action_muxer_free_group (gpointer data)
{
Group *group = data;
gint i;
/* 'for loop' or 'four loop'? */
for (i = 0; i < 4; i++)
g_signal_handler_disconnect (group->group, group->handler_ids[i]);
g_object_unref (group->group);
g_free (group->prefix);
g_slice_free (Group, group);
}
static void
g_action_muxer_finalize (GObject *object)
{
GActionMuxer *muxer = G_ACTION_MUXER (object);
g_assert_cmpint (g_hash_table_size (muxer->actions), ==, 0);
g_hash_table_unref (muxer->actions);
g_hash_table_unref (muxer->groups);
G_OBJECT_CLASS (g_action_muxer_parent_class)
->finalize (object);
}
static void
g_action_muxer_init (GActionMuxer *muxer)
{
muxer->actions = g_hash_table_new (g_str_hash, g_str_equal);
muxer->groups = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_action_muxer_free_group);
}
static void
g_action_muxer_observable_iface_init (GActionObservableInterface *iface)
{
iface->register_observer = g_action_muxer_register_observer;
iface->unregister_observer = g_action_muxer_unregister_observer;
}
static void
g_action_muxer_group_iface_init (GActionGroupInterface *iface)
{
iface->list_actions = g_action_muxer_list_actions;
iface->query_action = g_action_muxer_query_action;
iface->activate_action = g_action_muxer_activate_action;
iface->change_action_state = g_action_muxer_change_action_state;
}
static void
g_action_muxer_class_init (GObjectClass *class)
{
class->finalize = g_action_muxer_finalize;
}
/*
* g_action_muxer_insert:
* @muxer: a #GActionMuxer
* @prefix: the prefix string for the action group
* @action_group: a #GActionGroup
*
* Adds the actions in @action_group to the list of actions provided by
* @muxer. @prefix is prefixed to each action name, such that for each
* action <varname>x</varname> in @action_group, there is an equivalent
* action @prefix<literal>.</literal><varname>x</varname> in @muxer.
*
* For example, if @prefix is "<literal>app</literal>" and @action_group
* contains an action called "<literal>quit</literal>", then @muxer will
* now contain an action called "<literal>app.quit</literal>".
*
* If any #GActionObservers are registered for actions in the group,
* "action_added" notifications will be emitted, as appropriate.
*
* @prefix must not contain a dot ('.').
*/
void
g_action_muxer_insert (GActionMuxer *muxer,
const gchar *prefix,
GActionGroup *action_group)
{
gchar **actions;
Group *group;
gint i;
/* TODO: diff instead of ripout and replace */
g_action_muxer_remove (muxer, prefix);
group = g_slice_new (Group);
group->muxer = muxer;
group->group = g_object_ref (action_group);
group->prefix = g_strdup (prefix);
g_hash_table_insert (muxer->groups, group->prefix, group);
actions = g_action_group_list_actions (group->group);
for (i = 0; actions[i]; i++)
g_action_muxer_action_added (group->group, actions[i], group);
g_strfreev (actions);
group->handler_ids[0] = g_signal_connect (group->group, "action-added",
G_CALLBACK (g_action_muxer_action_added), group);
group->handler_ids[1] = g_signal_connect (group->group, "action-removed",
G_CALLBACK (g_action_muxer_action_removed), group);
group->handler_ids[2] = g_signal_connect (group->group, "action-enabled-changed",
G_CALLBACK (g_action_muxer_action_enabled_changed), group);
group->handler_ids[3] = g_signal_connect (group->group, "action-state-changed",
G_CALLBACK (g_action_muxer_action_state_changed), group);
}
/*
* g_action_muxer_remove:
* @muxer: a #GActionMuxer
* @prefix: the prefix of the action group to remove
*
* Removes a #GActionGroup from the #GActionMuxer.
*
* If any #GActionObservers are registered for actions in the group,
* "action_removed" notifications will be emitted, as appropriate.
*/
void
g_action_muxer_remove (GActionMuxer *muxer,
const gchar *prefix)
{
Group *group;
group = g_hash_table_lookup (muxer->groups, prefix);
if (group != NULL)
{
gchar **actions;
gint i;
g_hash_table_steal (muxer->groups, prefix);
actions = g_action_group_list_actions (group->group);
for (i = 0; actions[i]; i++)
g_action_muxer_action_removed (group->group, actions[i], group);
g_strfreev (actions);
g_action_muxer_free_group (group);
}
}
/*
* g_action_muxer_new:
*
* Creates a new #GActionMuxer.
*/
GActionMuxer *
g_action_muxer_new (void)
{
return g_object_new (G_TYPE_ACTION_MUXER, NULL);
}

53
src/gactionmuxer.h Normal file
View File

@ -0,0 +1,53 @@
/*
* Copyright © 2011 Canonical Limited
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the licence, or (at your option) any later version.
*
* This library is distributed in the hope that 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 library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*
* Author: Ryan Lortie <desrt@desrt.ca>
*/
#ifndef __G_ACTION_MUXER_H__
#define __G_ACTION_MUXER_H__
#include <gio/gio.h>
G_BEGIN_DECLS
#define G_TYPE_ACTION_MUXER (g_action_muxer_get_type ())
#define G_ACTION_MUXER(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), \
G_TYPE_ACTION_MUXER, GActionMuxer))
#define G_IS_ACTION_MUXER(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst), \
G_TYPE_ACTION_MUXER))
typedef struct _GActionMuxer GActionMuxer;
G_GNUC_INTERNAL
GType g_action_muxer_get_type (void);
G_GNUC_INTERNAL
GActionMuxer * g_action_muxer_new (void);
G_GNUC_INTERNAL
void g_action_muxer_insert (GActionMuxer *muxer,
const gchar *prefix,
GActionGroup *group);
G_GNUC_INTERNAL
void g_action_muxer_remove (GActionMuxer *muxer,
const gchar *prefix);
G_END_DECLS
#endif /* __G_ACTION_MUXER_H__ */

80
src/gactionobservable.c Normal file
View File

@ -0,0 +1,80 @@
/*
* Copyright © 2011 Canonical Limited
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2 of the
* licence or (at your option) any later version.
*
* This library is distributed in the hope that 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 library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307,
* USA.
*
* Authors: Ryan Lortie <desrt@desrt.ca>
*/
#include "config.h"
#include "gactionobservable.h"
G_DEFINE_INTERFACE (GActionObservable, g_action_observable, G_TYPE_OBJECT)
/*
* SECTION:gactionobserable
* @short_description: an interface implemented by objects that report
* changes to actions
*/
void
g_action_observable_default_init (GActionObservableInterface *iface)
{
}
/*
* g_action_observable_register_observer:
* @observable: a #GActionObservable
* @action_name: the name of the action
* @observer: the #GActionObserver to which the events will be reported
*
* Registers @observer as being interested in changes to @action_name on
* @observable.
*/
void
g_action_observable_register_observer (GActionObservable *observable,
const gchar *action_name,
GActionObserver *observer)
{
g_return_if_fail (G_IS_ACTION_OBSERVABLE (observable));
G_ACTION_OBSERVABLE_GET_IFACE (observable)
->register_observer (observable, action_name, observer);
}
/*
* g_action_observable_unregister_observer:
* @observable: a #GActionObservable
* @action_name: the name of the action
* @observer: the #GActionObserver to which the events will be reported
*
* Removes the registration of @observer as being interested in changes
* to @action_name on @observable.
*
* If the observer was registered multiple times, it must be
* unregistered an equal number of times.
*/
void
g_action_observable_unregister_observer (GActionObservable *observable,
const gchar *action_name,
GActionObserver *observer)
{
g_return_if_fail (G_IS_ACTION_OBSERVABLE (observable));
G_ACTION_OBSERVABLE_GET_IFACE (observable)
->unregister_observer (observable, action_name, observer);
}

64
src/gactionobservable.h Normal file
View File

@ -0,0 +1,64 @@
/*
* Copyright © 2011 Canonical Limited
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2 of the
* licence or (at your option) any later version.
*
* This library is distributed in the hope that 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 library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307,
* USA.
*
* Authors: Ryan Lortie <desrt@desrt.ca>
*/
#ifndef __G_ACTION_OBSERVABLE_H__
#define __G_ACTION_OBSERVABLE_H__
#include "gactionobserver.h"
G_BEGIN_DECLS
#define G_TYPE_ACTION_OBSERVABLE (g_action_observable_get_type ())
#define G_ACTION_OBSERVABLE(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), \
G_TYPE_ACTION_OBSERVABLE, GActionObservable))
#define G_IS_ACTION_OBSERVABLE(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst), \
G_TYPE_ACTION_OBSERVABLE))
#define G_ACTION_OBSERVABLE_GET_IFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), \
G_TYPE_ACTION_OBSERVABLE, GActionObservableInterface))
typedef struct _GActionObservableInterface GActionObservableInterface;
struct _GActionObservableInterface
{
GTypeInterface g_iface;
void (* register_observer) (GActionObservable *observable,
const gchar *action_name,
GActionObserver *observer);
void (* unregister_observer) (GActionObservable *observable,
const gchar *action_name,
GActionObserver *observer);
};
G_GNUC_INTERNAL
GType g_action_observable_get_type (void);
G_GNUC_INTERNAL
void g_action_observable_register_observer (GActionObservable *observable,
const gchar *action_name,
GActionObserver *observer);
G_GNUC_INTERNAL
void g_action_observable_unregister_observer (GActionObservable *observable,
const gchar *action_name,
GActionObserver *observer);
G_END_DECLS
#endif /* __G_ACTION_OBSERVABLE_H__ */

View File

@ -1,7 +1,7 @@
/* /*
* Copyright © 2011 Canonical Limited * Copyright © 2011 Canonical Limited
* *
* This library is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as * it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2 of the * published by the Free Software Foundation; either version 2 of the
* licence or (at your option) any later version. * licence or (at your option) any later version.
@ -12,23 +12,25 @@
* Lesser General Public License for more details. * Lesser General Public License for more details.
* *
* You should have received a copy of the GNU Lesser General Public * You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>. * License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307,
* USA.
* *
* Authors: Ryan Lortie <desrt@desrt.ca> * Authors: Ryan Lortie <desrt@desrt.ca>
*/ */
#include "config.h" #include "config.h"
#include "gtkactionobserver.h" #include "gactionobserver.h"
G_DEFINE_INTERFACE (GtkActionObserver, gtk_action_observer, G_TYPE_OBJECT) G_DEFINE_INTERFACE (GActionObserver, g_action_observer, G_TYPE_OBJECT)
/** /**
* SECTION:gtkactionobserver * SECTION:gactionobserver
* @short_description: an interface implemented by objects that are * @short_description: an interface implemented by objects that are
* interested in monitoring actions for changes * interested in monitoring actions for changes
* *
* GtkActionObserver is a simple interface allowing objects that wish to * GActionObserver is a simple interface allowing objects that wish to
* be notified of changes to actions to be notified of those changes. * be notified of changes to actions to be notified of those changes.
* *
* It is also possible to monitor changes to action groups using * It is also possible to monitor changes to action groups using
@ -50,13 +52,13 @@ G_DEFINE_INTERFACE (GtkActionObserver, gtk_action_observer, G_TYPE_OBJECT)
*/ */
void void
gtk_action_observer_default_init (GtkActionObserverInterface *class) g_action_observer_default_init (GActionObserverInterface *class)
{ {
} }
/** /*
* gtk_action_observer_action_added: * g_action_observer_action_added:
* @observer: a #GtkActionObserver * @observer: a #GActionObserver
* @observable: the source of the event * @observable: the source of the event
* @action_name: the name of the action * @action_name: the name of the action
* @enabled: %TRUE if the action is now enabled * @enabled: %TRUE if the action is now enabled
@ -72,22 +74,22 @@ gtk_action_observer_default_init (GtkActionObserverInterface *class)
* observer has explicitly registered itself to receive events. * observer has explicitly registered itself to receive events.
*/ */
void void
gtk_action_observer_action_added (GtkActionObserver *observer, g_action_observer_action_added (GActionObserver *observer,
GtkActionObservable *observable, GActionObservable *observable,
const gchar *action_name, const gchar *action_name,
const GVariantType *parameter_type, const GVariantType *parameter_type,
gboolean enabled, gboolean enabled,
GVariant *state) GVariant *state)
{ {
g_return_if_fail (GTK_IS_ACTION_OBSERVER (observer)); g_return_if_fail (G_IS_ACTION_OBSERVER (observer));
GTK_ACTION_OBSERVER_GET_IFACE (observer) G_ACTION_OBSERVER_GET_IFACE (observer)
->action_added (observer, observable, action_name, parameter_type, enabled, state); ->action_added (observer, observable, action_name, parameter_type, enabled, state);
} }
/** /*
* gtk_action_observer_action_enabled_changed: * g_action_observer_action_enabled_changed:
* @observer: a #GtkActionObserver * @observer: a #GActionObserver
* @observable: the source of the event * @observable: the source of the event
* @action_name: the name of the action * @action_name: the name of the action
* @enabled: %TRUE if the action is now enabled * @enabled: %TRUE if the action is now enabled
@ -99,45 +101,45 @@ gtk_action_observer_action_added (GtkActionObserver *observer,
* observer has explicitly registered itself to receive events. * observer has explicitly registered itself to receive events.
*/ */
void void
gtk_action_observer_action_enabled_changed (GtkActionObserver *observer, g_action_observer_action_enabled_changed (GActionObserver *observer,
GtkActionObservable *observable, GActionObservable *observable,
const gchar *action_name, const gchar *action_name,
gboolean enabled) gboolean enabled)
{ {
g_return_if_fail (GTK_IS_ACTION_OBSERVER (observer)); g_return_if_fail (G_IS_ACTION_OBSERVER (observer));
GTK_ACTION_OBSERVER_GET_IFACE (observer) G_ACTION_OBSERVER_GET_IFACE (observer)
->action_enabled_changed (observer, observable, action_name, enabled); ->action_enabled_changed (observer, observable, action_name, enabled);
} }
/** /*
* gtk_action_observer_action_state_changed: * g_action_observer_action_state_changed:
* @observer: a #GtkActionObserver * @observer: a #GActionObserver
* @observable: the source of the event * @observable: the source of the event
* @action_name: the name of the action * @action_name: the name of the action
* @state: the new state of the action * @state: the new state of the action
* *
* This function is called when an action that the observer is * This function is called when an action that the observer is
* registered to receive events for changes to its state. * registered to receive events for changes its state.
* *
* This function should only be called by objects with which the * This function should only be called by objects with which the
* observer has explicitly registered itself to receive events. * observer has explicitly registered itself to receive events.
*/ */
void void
gtk_action_observer_action_state_changed (GtkActionObserver *observer, g_action_observer_action_state_changed (GActionObserver *observer,
GtkActionObservable *observable, GActionObservable *observable,
const gchar *action_name, const gchar *action_name,
GVariant *state) GVariant *state)
{ {
g_return_if_fail (GTK_IS_ACTION_OBSERVER (observer)); g_return_if_fail (G_IS_ACTION_OBSERVER (observer));
GTK_ACTION_OBSERVER_GET_IFACE (observer) G_ACTION_OBSERVER_GET_IFACE (observer)
->action_state_changed (observer, observable, action_name, state); ->action_state_changed (observer, observable, action_name, state);
} }
/** /*
* gtk_action_observer_action_removed: * g_action_observer_action_removed:
* @observer: a #GtkActionObserver * @observer: a #GActionObserver
* @observable: the source of the event * @observable: the source of the event
* @action_name: the name of the action * @action_name: the name of the action
* *
@ -148,12 +150,12 @@ gtk_action_observer_action_state_changed (GtkActionObserver *observer,
* observer has explicitly registered itself to receive events. * observer has explicitly registered itself to receive events.
*/ */
void void
gtk_action_observer_action_removed (GtkActionObserver *observer, g_action_observer_action_removed (GActionObserver *observer,
GtkActionObservable *observable, GActionObservable *observable,
const gchar *action_name) const gchar *action_name)
{ {
g_return_if_fail (GTK_IS_ACTION_OBSERVER (observer)); g_return_if_fail (G_IS_ACTION_OBSERVER (observer));
GTK_ACTION_OBSERVER_GET_IFACE (observer) G_ACTION_OBSERVER_GET_IFACE (observer)
->action_removed (observer, observable, action_name); ->action_removed (observer, observable, action_name);
} }

90
src/gactionobserver.h Normal file
View File

@ -0,0 +1,90 @@
/*
* Copyright © 2011 Canonical Limited
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2 of the
* licence or (at your option) any later version.
*
* This library is distributed in the hope that 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 library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307,
* USA.
*
* Authors: Ryan Lortie <desrt@desrt.ca>
*/
#ifndef __G_ACTION_OBSERVER_H__
#define __G_ACTION_OBSERVER_H__
#include <gio/gio.h>
G_BEGIN_DECLS
#define G_TYPE_ACTION_OBSERVER (g_action_observer_get_type ())
#define G_ACTION_OBSERVER(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), \
G_TYPE_ACTION_OBSERVER, GActionObserver))
#define G_IS_ACTION_OBSERVER(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst), \
G_TYPE_ACTION_OBSERVER))
#define G_ACTION_OBSERVER_GET_IFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), \
G_TYPE_ACTION_OBSERVER, GActionObserverInterface))
typedef struct _GActionObserverInterface GActionObserverInterface;
typedef struct _GActionObservable GActionObservable;
typedef struct _GActionObserver GActionObserver;
struct _GActionObserverInterface
{
GTypeInterface g_iface;
void (* action_added) (GActionObserver *observer,
GActionObservable *observable,
const gchar *action_name,
const GVariantType *parameter_type,
gboolean enabled,
GVariant *state);
void (* action_enabled_changed) (GActionObserver *observer,
GActionObservable *observable,
const gchar *action_name,
gboolean enabled);
void (* action_state_changed) (GActionObserver *observer,
GActionObservable *observable,
const gchar *action_name,
GVariant *state);
void (* action_removed) (GActionObserver *observer,
GActionObservable *observable,
const gchar *action_name);
};
G_GNUC_INTERNAL
GType g_action_observer_get_type (void);
G_GNUC_INTERNAL
void g_action_observer_action_added (GActionObserver *observer,
GActionObservable *observable,
const gchar *action_name,
const GVariantType *parameter_type,
gboolean enabled,
GVariant *state);
G_GNUC_INTERNAL
void g_action_observer_action_enabled_changed (GActionObserver *observer,
GActionObservable *observable,
const gchar *action_name,
gboolean enabled);
G_GNUC_INTERNAL
void g_action_observer_action_state_changed (GActionObserver *observer,
GActionObservable *observable,
const gchar *action_name,
GVariant *state);
G_GNUC_INTERNAL
void g_action_observer_action_removed (GActionObserver *observer,
GActionObservable *observable,
const gchar *action_name);
G_END_DECLS
#endif /* __G_ACTION_OBSERVER_H__ */

View File

@ -1,808 +0,0 @@
/*
* Copyright © 2011 Canonical Limited
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the licence, or (at your option) any later version.
*
* This library is distributed in the hope that 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 library. If not, see <http://www.gnu.org/licenses/>.
*
* Author: Ryan Lortie <desrt@desrt.ca>
*/
#include "config.h"
#include "gtkactionmuxer.h"
#include "gtkactionobservable.h"
#include "gtkactionobserver.h"
#include <clutter/clutter.h>
#include <string.h>
/**
* SECTION:gtkactionmuxer
* @short_description: Aggregate and monitor several action groups
*
* #GtkActionMuxer is a #GActionGroup and #GtkActionObservable that is
* capable of containing other #GActionGroup instances.
*
* The typical use is aggregating all of the actions applicable to a
* particular context into a single action group, with namespacing.
*
* Consider the case of two action groups -- one containing actions
* applicable to an entire application (such as 'quit') and one
* containing actions applicable to a particular window in the
* application (such as 'fullscreen').
*
* In this case, each of these action groups could be added to a
* #GtkActionMuxer with the prefixes "app" and "win", respectively. This
* would expose the actions as "app.quit" and "win.fullscreen" on the
* #GActionGroup interface presented by the #GtkActionMuxer.
*
* Activations and state change requests on the #GtkActionMuxer are wired
* through to the underlying action group in the expected way.
*
* This class is typically only used at the site of "consumption" of
* actions (eg: when displaying a menu that contains many actions on
* different objects).
*/
static void gtk_action_muxer_group_iface_init (GActionGroupInterface *iface);
static void gtk_action_muxer_observable_iface_init (GtkActionObservableInterface *iface);
typedef GObjectClass GtkActionMuxerClass;
struct _GtkActionMuxer
{
GObject parent_instance;
GHashTable *observed_actions;
GHashTable *groups;
GtkActionMuxer *parent;
};
G_DEFINE_TYPE_WITH_CODE (GtkActionMuxer, gtk_action_muxer, G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (G_TYPE_ACTION_GROUP, gtk_action_muxer_group_iface_init)
G_IMPLEMENT_INTERFACE (GTK_TYPE_ACTION_OBSERVABLE, gtk_action_muxer_observable_iface_init))
enum
{
PROP_0,
PROP_PARENT,
NUM_PROPERTIES
};
static GParamSpec *properties[NUM_PROPERTIES];
typedef struct
{
GtkActionMuxer *muxer;
GSList *watchers;
gchar *fullname;
} Action;
typedef struct
{
GtkActionMuxer *muxer;
GActionGroup *group;
gchar *prefix;
gulong handler_ids[4];
} Group;
static void
gtk_action_muxer_append_group_actions (gpointer key,
gpointer value,
gpointer user_data)
{
const gchar *prefix = key;
Group *group = value;
GArray *actions = user_data;
gchar **group_actions;
gchar **action;
group_actions = g_action_group_list_actions (group->group);
for (action = group_actions; *action; action++)
{
gchar *fullname;
fullname = g_strconcat (prefix, ".", *action, NULL);
g_array_append_val (actions, fullname);
}
g_strfreev (group_actions);
}
static gchar **
gtk_action_muxer_list_actions (GActionGroup *action_group)
{
GtkActionMuxer *muxer = GTK_ACTION_MUXER (action_group);
GArray *actions;
actions = g_array_new (TRUE, FALSE, sizeof (gchar *));
for ( ; muxer != NULL; muxer = muxer->parent)
{
g_hash_table_foreach (muxer->groups,
gtk_action_muxer_append_group_actions,
actions);
}
return (gchar **) g_array_free (actions, FALSE);
}
static Group *
gtk_action_muxer_find_group (GtkActionMuxer *muxer,
const gchar *full_name,
const gchar **action_name)
{
const gchar *dot;
gchar *prefix;
Group *group;
dot = strchr (full_name, '.');
if (!dot)
return NULL;
prefix = g_strndup (full_name, dot - full_name);
group = g_hash_table_lookup (muxer->groups, prefix);
g_free (prefix);
if (action_name)
*action_name = dot + 1;
return group;
}
static void
gtk_action_muxer_action_enabled_changed (GtkActionMuxer *muxer,
const gchar *action_name,
gboolean enabled)
{
Action *action;
GSList *node;
action = g_hash_table_lookup (muxer->observed_actions, action_name);
for (node = action ? action->watchers : NULL; node; node = node->next)
gtk_action_observer_action_enabled_changed (node->data, GTK_ACTION_OBSERVABLE (muxer), action_name, enabled);
g_action_group_action_enabled_changed (G_ACTION_GROUP (muxer), action_name, enabled);
}
static void
gtk_action_muxer_group_action_enabled_changed (GActionGroup *action_group,
const gchar *action_name,
gboolean enabled,
gpointer user_data)
{
Group *group = user_data;
gchar *fullname;
fullname = g_strconcat (group->prefix, ".", action_name, NULL);
gtk_action_muxer_action_enabled_changed (group->muxer, fullname, enabled);
g_free (fullname);
}
static void
gtk_action_muxer_parent_action_enabled_changed (GActionGroup *action_group,
const gchar *action_name,
gboolean enabled,
gpointer user_data)
{
GtkActionMuxer *muxer = user_data;
gtk_action_muxer_action_enabled_changed (muxer, action_name, enabled);
}
static void
gtk_action_muxer_action_state_changed (GtkActionMuxer *muxer,
const gchar *action_name,
GVariant *state)
{
Action *action;
GSList *node;
action = g_hash_table_lookup (muxer->observed_actions, action_name);
for (node = action ? action->watchers : NULL; node; node = node->next)
gtk_action_observer_action_state_changed (node->data, GTK_ACTION_OBSERVABLE (muxer), action_name, state);
g_action_group_action_state_changed (G_ACTION_GROUP (muxer), action_name, state);
}
static void
gtk_action_muxer_group_action_state_changed (GActionGroup *action_group,
const gchar *action_name,
GVariant *state,
gpointer user_data)
{
Group *group = user_data;
gchar *fullname;
fullname = g_strconcat (group->prefix, ".", action_name, NULL);
gtk_action_muxer_action_state_changed (group->muxer, fullname, state);
g_free (fullname);
}
static void
gtk_action_muxer_parent_action_state_changed (GActionGroup *action_group,
const gchar *action_name,
GVariant *state,
gpointer user_data)
{
GtkActionMuxer *muxer = user_data;
gtk_action_muxer_action_state_changed (muxer, action_name, state);
}
static void
gtk_action_muxer_action_added (GtkActionMuxer *muxer,
const gchar *action_name,
GActionGroup *original_group,
const gchar *orignal_action_name)
{
const GVariantType *parameter_type;
gboolean enabled;
GVariant *state;
Action *action;
action = g_hash_table_lookup (muxer->observed_actions, action_name);
if (action && action->watchers &&
g_action_group_query_action (original_group, orignal_action_name,
&enabled, &parameter_type, NULL, NULL, &state))
{
GSList *node;
for (node = action->watchers; node; node = node->next)
gtk_action_observer_action_added (node->data,
GTK_ACTION_OBSERVABLE (muxer),
action_name, parameter_type, enabled, state);
if (state)
g_variant_unref (state);
}
g_action_group_action_added (G_ACTION_GROUP (muxer), action_name);
}
static void
gtk_action_muxer_action_added_to_group (GActionGroup *action_group,
const gchar *action_name,
gpointer user_data)
{
Group *group = user_data;
gchar *fullname;
fullname = g_strconcat (group->prefix, ".", action_name, NULL);
gtk_action_muxer_action_added (group->muxer, fullname, action_group, action_name);
g_free (fullname);
}
static void
gtk_action_muxer_action_added_to_parent (GActionGroup *action_group,
const gchar *action_name,
gpointer user_data)
{
GtkActionMuxer *muxer = user_data;
gtk_action_muxer_action_added (muxer, action_name, action_group, action_name);
}
static void
gtk_action_muxer_action_removed (GtkActionMuxer *muxer,
const gchar *action_name)
{
Action *action;
GSList *node;
action = g_hash_table_lookup (muxer->observed_actions, action_name);
for (node = action ? action->watchers : NULL; node; node = node->next)
gtk_action_observer_action_removed (node->data, GTK_ACTION_OBSERVABLE (muxer), action_name);
g_action_group_action_removed (G_ACTION_GROUP (muxer), action_name);
}
static void
gtk_action_muxer_action_removed_from_group (GActionGroup *action_group,
const gchar *action_name,
gpointer user_data)
{
Group *group = user_data;
gchar *fullname;
fullname = g_strconcat (group->prefix, ".", action_name, NULL);
gtk_action_muxer_action_removed (group->muxer, fullname);
g_free (fullname);
}
static void
gtk_action_muxer_action_removed_from_parent (GActionGroup *action_group,
const gchar *action_name,
gpointer user_data)
{
GtkActionMuxer *muxer = user_data;
gtk_action_muxer_action_removed (muxer, action_name);
}
static gboolean
gtk_action_muxer_query_action (GActionGroup *action_group,
const gchar *action_name,
gboolean *enabled,
const GVariantType **parameter_type,
const GVariantType **state_type,
GVariant **state_hint,
GVariant **state)
{
GtkActionMuxer *muxer = GTK_ACTION_MUXER (action_group);
Group *group;
const gchar *unprefixed_name;
group = gtk_action_muxer_find_group (muxer, action_name, &unprefixed_name);
if (group)
return g_action_group_query_action (group->group, unprefixed_name, enabled,
parameter_type, state_type, state_hint, state);
if (muxer->parent)
return g_action_group_query_action (G_ACTION_GROUP (muxer->parent), action_name,
enabled, parameter_type,
state_type, state_hint, state);
return FALSE;
}
static void
gtk_action_muxer_activate_action (GActionGroup *action_group,
const gchar *action_name,
GVariant *parameter)
{
GtkActionMuxer *muxer = GTK_ACTION_MUXER (action_group);
Group *group;
const gchar *unprefixed_name;
group = gtk_action_muxer_find_group (muxer, action_name, &unprefixed_name);
if (group)
g_action_group_activate_action (group->group, unprefixed_name, parameter);
else if (muxer->parent)
g_action_group_activate_action (G_ACTION_GROUP (muxer->parent), action_name, parameter);
}
static GVariant *
get_platform_data (void)
{
gchar time[32];
GVariantBuilder *builder;
GVariant *result;
g_snprintf (time, 32, "_TIME%d", clutter_get_current_event_time ());
builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}"));
g_variant_builder_add (builder, "{sv}", "desktop-startup-id",
g_variant_new_string (time));
result = g_variant_builder_end (builder);
g_variant_builder_unref (builder);
return result;
}
static void
gtk_action_muxer_change_action_state (GActionGroup *action_group,
const gchar *action_name,
GVariant *state)
{
GtkActionMuxer *muxer = GTK_ACTION_MUXER (action_group);
Group *group;
const gchar *unprefixed_name;
group = gtk_action_muxer_find_group (muxer, action_name, &unprefixed_name);
if (group)
{
if (G_IS_REMOTE_ACTION_GROUP (group->group))
g_remote_action_group_change_action_state_full (G_REMOTE_ACTION_GROUP (group->group),
unprefixed_name,
state,
get_platform_data ());
else
g_action_group_change_action_state (group->group, unprefixed_name, state);
}
else if (muxer->parent)
g_action_group_change_action_state (G_ACTION_GROUP (muxer->parent), action_name, state);
}
static void
gtk_action_muxer_unregister_internal (Action *action,
gpointer observer)
{
GtkActionMuxer *muxer = action->muxer;
GSList **ptr;
for (ptr = &action->watchers; *ptr; ptr = &(*ptr)->next)
if ((*ptr)->data == observer)
{
*ptr = g_slist_remove (*ptr, observer);
if (action->watchers == NULL)
g_hash_table_remove (muxer->observed_actions, action->fullname);
break;
}
}
static void
gtk_action_muxer_weak_notify (gpointer data,
GObject *where_the_object_was)
{
Action *action = data;
gtk_action_muxer_unregister_internal (action, where_the_object_was);
}
static void
gtk_action_muxer_register_observer (GtkActionObservable *observable,
const gchar *name,
GtkActionObserver *observer)
{
GtkActionMuxer *muxer = GTK_ACTION_MUXER (observable);
Action *action;
action = g_hash_table_lookup (muxer->observed_actions, name);
if (action == NULL)
{
action = g_slice_new (Action);
action->muxer = muxer;
action->fullname = g_strdup (name);
action->watchers = NULL;
g_hash_table_insert (muxer->observed_actions, action->fullname, action);
}
action->watchers = g_slist_prepend (action->watchers, observer);
g_object_weak_ref (G_OBJECT (observer), gtk_action_muxer_weak_notify, action);
}
static void
gtk_action_muxer_unregister_observer (GtkActionObservable *observable,
const gchar *name,
GtkActionObserver *observer)
{
GtkActionMuxer *muxer = GTK_ACTION_MUXER (observable);
Action *action;
action = g_hash_table_lookup (muxer->observed_actions, name);
g_object_weak_unref (G_OBJECT (observer), gtk_action_muxer_weak_notify, action);
gtk_action_muxer_unregister_internal (action, observer);
}
static void
gtk_action_muxer_free_group (gpointer data)
{
Group *group = data;
gint i;
/* 'for loop' or 'four loop'? */
for (i = 0; i < 4; i++)
g_signal_handler_disconnect (group->group, group->handler_ids[i]);
g_object_unref (group->group);
g_free (group->prefix);
g_slice_free (Group, group);
}
static void
gtk_action_muxer_free_action (gpointer data)
{
Action *action = data;
GSList *it;
for (it = action->watchers; it; it = it->next)
g_object_weak_unref (G_OBJECT (it->data), gtk_action_muxer_weak_notify, action);
g_slist_free (action->watchers);
g_free (action->fullname);
g_slice_free (Action, action);
}
static void
gtk_action_muxer_finalize (GObject *object)
{
GtkActionMuxer *muxer = GTK_ACTION_MUXER (object);
g_assert_cmpint (g_hash_table_size (muxer->observed_actions), ==, 0);
g_hash_table_unref (muxer->observed_actions);
g_hash_table_unref (muxer->groups);
G_OBJECT_CLASS (gtk_action_muxer_parent_class)
->finalize (object);
}
static void
gtk_action_muxer_dispose (GObject *object)
{
GtkActionMuxer *muxer = GTK_ACTION_MUXER (object);
if (muxer->parent)
{
g_signal_handlers_disconnect_by_func (muxer->parent, gtk_action_muxer_action_added_to_parent, muxer);
g_signal_handlers_disconnect_by_func (muxer->parent, gtk_action_muxer_action_removed_from_parent, muxer);
g_signal_handlers_disconnect_by_func (muxer->parent, gtk_action_muxer_parent_action_enabled_changed, muxer);
g_signal_handlers_disconnect_by_func (muxer->parent, gtk_action_muxer_parent_action_state_changed, muxer);
g_clear_object (&muxer->parent);
}
g_hash_table_remove_all (muxer->observed_actions);
G_OBJECT_CLASS (gtk_action_muxer_parent_class)
->dispose (object);
}
static void
gtk_action_muxer_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec)
{
GtkActionMuxer *muxer = GTK_ACTION_MUXER (object);
switch (property_id)
{
case PROP_PARENT:
g_value_set_object (value, gtk_action_muxer_get_parent (muxer));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
}
static void
gtk_action_muxer_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec)
{
GtkActionMuxer *muxer = GTK_ACTION_MUXER (object);
switch (property_id)
{
case PROP_PARENT:
gtk_action_muxer_set_parent (muxer, g_value_get_object (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
}
static void
gtk_action_muxer_init (GtkActionMuxer *muxer)
{
muxer->observed_actions = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, gtk_action_muxer_free_action);
muxer->groups = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, gtk_action_muxer_free_group);
}
static void
gtk_action_muxer_observable_iface_init (GtkActionObservableInterface *iface)
{
iface->register_observer = gtk_action_muxer_register_observer;
iface->unregister_observer = gtk_action_muxer_unregister_observer;
}
static void
gtk_action_muxer_group_iface_init (GActionGroupInterface *iface)
{
iface->list_actions = gtk_action_muxer_list_actions;
iface->query_action = gtk_action_muxer_query_action;
iface->activate_action = gtk_action_muxer_activate_action;
iface->change_action_state = gtk_action_muxer_change_action_state;
}
static void
gtk_action_muxer_class_init (GObjectClass *class)
{
class->get_property = gtk_action_muxer_get_property;
class->set_property = gtk_action_muxer_set_property;
class->finalize = gtk_action_muxer_finalize;
class->dispose = gtk_action_muxer_dispose;
properties[PROP_PARENT] = g_param_spec_object ("parent", "Parent",
"The parent muxer",
GTK_TYPE_ACTION_MUXER,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS);
g_object_class_install_properties (class, NUM_PROPERTIES, properties);
}
/**
* gtk_action_muxer_insert:
* @muxer: a #GtkActionMuxer
* @prefix: the prefix string for the action group
* @action_group: a #GActionGroup
*
* Adds the actions in @action_group to the list of actions provided by
* @muxer. @prefix is prefixed to each action name, such that for each
* action <varname>x</varname> in @action_group, there is an equivalent
* action @prefix<literal>.</literal><varname>x</varname> in @muxer.
*
* For example, if @prefix is "<literal>app</literal>" and @action_group
* contains an action called "<literal>quit</literal>", then @muxer will
* now contain an action called "<literal>app.quit</literal>".
*
* If any #GtkActionObservers are registered for actions in the group,
* "action_added" notifications will be emitted, as appropriate.
*
* @prefix must not contain a dot ('.').
*/
void
gtk_action_muxer_insert (GtkActionMuxer *muxer,
const gchar *prefix,
GActionGroup *action_group)
{
gchar **actions;
Group *group;
gint i;
/* TODO: diff instead of ripout and replace */
gtk_action_muxer_remove (muxer, prefix);
group = g_slice_new (Group);
group->muxer = muxer;
group->group = g_object_ref (action_group);
group->prefix = g_strdup (prefix);
g_hash_table_insert (muxer->groups, group->prefix, group);
actions = g_action_group_list_actions (group->group);
for (i = 0; actions[i]; i++)
gtk_action_muxer_action_added_to_group (group->group, actions[i], group);
g_strfreev (actions);
group->handler_ids[0] = g_signal_connect (group->group, "action-added",
G_CALLBACK (gtk_action_muxer_action_added_to_group), group);
group->handler_ids[1] = g_signal_connect (group->group, "action-removed",
G_CALLBACK (gtk_action_muxer_action_removed_from_group), group);
group->handler_ids[2] = g_signal_connect (group->group, "action-enabled-changed",
G_CALLBACK (gtk_action_muxer_group_action_enabled_changed), group);
group->handler_ids[3] = g_signal_connect (group->group, "action-state-changed",
G_CALLBACK (gtk_action_muxer_group_action_state_changed), group);
}
/**
* gtk_action_muxer_remove:
* @muxer: a #GtkActionMuxer
* @prefix: the prefix of the action group to remove
*
* Removes a #GActionGroup from the #GtkActionMuxer.
*
* If any #GtkActionObservers are registered for actions in the group,
* "action_removed" notifications will be emitted, as appropriate.
*/
void
gtk_action_muxer_remove (GtkActionMuxer *muxer,
const gchar *prefix)
{
Group *group;
group = g_hash_table_lookup (muxer->groups, prefix);
if (group != NULL)
{
gchar **actions;
gint i;
g_hash_table_steal (muxer->groups, prefix);
actions = g_action_group_list_actions (group->group);
for (i = 0; actions[i]; i++)
gtk_action_muxer_action_removed_from_group (group->group, actions[i], group);
g_strfreev (actions);
gtk_action_muxer_free_group (group);
}
}
/**
* gtk_action_muxer_new:
*
* Creates a new #GtkActionMuxer.
*/
GtkActionMuxer *
gtk_action_muxer_new (void)
{
return g_object_new (GTK_TYPE_ACTION_MUXER, NULL);
}
/**
* gtk_action_muxer_get_parent:
* @muxer: a #GtkActionMuxer
*
* Returns: (transfer none): the parent of @muxer, or NULL.
*/
GtkActionMuxer *
gtk_action_muxer_get_parent (GtkActionMuxer *muxer)
{
g_return_val_if_fail (GTK_IS_ACTION_MUXER (muxer), NULL);
return muxer->parent;
}
/**
* gtk_action_muxer_set_parent:
* @muxer: a #GtkActionMuxer
* @parent: (allow-none): the new parent #GtkActionMuxer
*
* Sets the parent of @muxer to @parent.
*/
void
gtk_action_muxer_set_parent (GtkActionMuxer *muxer,
GtkActionMuxer *parent)
{
g_return_if_fail (GTK_IS_ACTION_MUXER (muxer));
g_return_if_fail (parent == NULL || GTK_IS_ACTION_MUXER (parent));
if (muxer->parent == parent)
return;
if (muxer->parent != NULL)
{
gchar **actions;
gchar **it;
actions = g_action_group_list_actions (G_ACTION_GROUP (muxer->parent));
for (it = actions; *it; it++)
gtk_action_muxer_action_removed (muxer, *it);
g_strfreev (actions);
g_signal_handlers_disconnect_by_func (muxer->parent, gtk_action_muxer_action_added_to_parent, muxer);
g_signal_handlers_disconnect_by_func (muxer->parent, gtk_action_muxer_action_removed_from_parent, muxer);
g_signal_handlers_disconnect_by_func (muxer->parent, gtk_action_muxer_parent_action_enabled_changed, muxer);
g_signal_handlers_disconnect_by_func (muxer->parent, gtk_action_muxer_parent_action_state_changed, muxer);
g_object_unref (muxer->parent);
}
muxer->parent = parent;
if (muxer->parent != NULL)
{
gchar **actions;
gchar **it;
g_object_ref (muxer->parent);
actions = g_action_group_list_actions (G_ACTION_GROUP (muxer->parent));
for (it = actions; *it; it++)
gtk_action_muxer_action_added (muxer, *it, G_ACTION_GROUP (muxer->parent), *it);
g_strfreev (actions);
g_signal_connect (muxer->parent, "action-added",
G_CALLBACK (gtk_action_muxer_action_added_to_parent), muxer);
g_signal_connect (muxer->parent, "action-removed",
G_CALLBACK (gtk_action_muxer_action_removed_from_parent), muxer);
g_signal_connect (muxer->parent, "action-enabled-changed",
G_CALLBACK (gtk_action_muxer_parent_action_enabled_changed), muxer);
g_signal_connect (muxer->parent, "action-state-changed",
G_CALLBACK (gtk_action_muxer_parent_action_state_changed), muxer);
}
g_object_notify_by_pspec (G_OBJECT (muxer), properties[PROP_PARENT]);
}

View File

@ -1,52 +0,0 @@
/*
* Copyright © 2011 Canonical Limited
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the licence, or (at your option) any later version.
*
* This library is distributed in the hope that 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 library. If not, see <http://www.gnu.org/licenses/>.
*
* Author: Ryan Lortie <desrt@desrt.ca>
*/
#ifndef __GTK_ACTION_MUXER_H__
#define __GTK_ACTION_MUXER_H__
#include <gio/gio.h>
G_BEGIN_DECLS
#define GTK_TYPE_ACTION_MUXER (gtk_action_muxer_get_type ())
#define GTK_ACTION_MUXER(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), \
GTK_TYPE_ACTION_MUXER, GtkActionMuxer))
#define GTK_IS_ACTION_MUXER(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst), \
GTK_TYPE_ACTION_MUXER))
typedef struct _GtkActionMuxer GtkActionMuxer;
GType gtk_action_muxer_get_type (void);
GtkActionMuxer * gtk_action_muxer_new (void);
void gtk_action_muxer_insert (GtkActionMuxer *muxer,
const gchar *prefix,
GActionGroup *action_group);
void gtk_action_muxer_remove (GtkActionMuxer *muxer,
const gchar *prefix);
GtkActionMuxer * gtk_action_muxer_get_parent (GtkActionMuxer *muxer);
void gtk_action_muxer_set_parent (GtkActionMuxer *muxer,
GtkActionMuxer *parent);
G_END_DECLS
#endif /* __GTK_ACTION_MUXER_H__ */

View File

@ -1,78 +0,0 @@
/*
* Copyright © 2011 Canonical Limited
*
* This library is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2 of the
* licence or (at your option) any later version.
*
* This library is distributed in the hope that 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 library. If not, see <http://www.gnu.org/licenses/>.
*
* Authors: Ryan Lortie <desrt@desrt.ca>
*/
#include "config.h"
#include "gtkactionobservable.h"
G_DEFINE_INTERFACE (GtkActionObservable, gtk_action_observable, G_TYPE_OBJECT)
/*
* SECTION:gtkactionobserable
* @short_description: an interface implemented by objects that report
* changes to actions
*/
void
gtk_action_observable_default_init (GtkActionObservableInterface *iface)
{
}
/**
* gtk_action_observable_register_observer:
* @observable: a #GtkActionObservable
* @action_name: the name of the action
* @observer: the #GtkActionObserver to which the events will be reported
*
* Registers @observer as being interested in changes to @action_name on
* @observable.
*/
void
gtk_action_observable_register_observer (GtkActionObservable *observable,
const gchar *action_name,
GtkActionObserver *observer)
{
g_return_if_fail (GTK_IS_ACTION_OBSERVABLE (observable));
GTK_ACTION_OBSERVABLE_GET_IFACE (observable)
->register_observer (observable, action_name, observer);
}
/**
* gtk_action_observable_unregister_observer:
* @observable: a #GtkActionObservable
* @action_name: the name of the action
* @observer: the #GtkActionObserver to which the events will be reported
*
* Removes the registration of @observer as being interested in changes
* to @action_name on @observable.
*
* If the observer was registered multiple times, it must be
* unregistered an equal number of times.
*/
void
gtk_action_observable_unregister_observer (GtkActionObservable *observable,
const gchar *action_name,
GtkActionObserver *observer)
{
g_return_if_fail (GTK_IS_ACTION_OBSERVABLE (observable));
GTK_ACTION_OBSERVABLE_GET_IFACE (observable)
->unregister_observer (observable, action_name, observer);
}

View File

@ -1,60 +0,0 @@
/*
* Copyright © 2011 Canonical Limited
*
* This library is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2 of the
* licence or (at your option) any later version.
*
* This library is distributed in the hope that 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 library. If not, see <http://www.gnu.org/licenses/>.
*
* Authors: Ryan Lortie <desrt@desrt.ca>
*/
#ifndef __GTK_ACTION_OBSERVABLE_H__
#define __GTK_ACTION_OBSERVABLE_H__
#include "gtkactionobserver.h"
G_BEGIN_DECLS
#define GTK_TYPE_ACTION_OBSERVABLE (gtk_action_observable_get_type ())
#define GTK_ACTION_OBSERVABLE(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), \
GTK_TYPE_ACTION_OBSERVABLE, GtkActionObservable))
#define GTK_IS_ACTION_OBSERVABLE(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst), \
GTK_TYPE_ACTION_OBSERVABLE))
#define GTK_ACTION_OBSERVABLE_GET_IFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), \
GTK_TYPE_ACTION_OBSERVABLE, \
GtkActionObservableInterface))
typedef struct _GtkActionObservableInterface GtkActionObservableInterface;
struct _GtkActionObservableInterface
{
GTypeInterface g_iface;
void (* register_observer) (GtkActionObservable *observable,
const gchar *action_name,
GtkActionObserver *observer);
void (* unregister_observer) (GtkActionObservable *observable,
const gchar *action_name,
GtkActionObserver *observer);
};
GType gtk_action_observable_get_type (void);
void gtk_action_observable_register_observer (GtkActionObservable *observable,
const gchar *action_name,
GtkActionObserver *observer);
void gtk_action_observable_unregister_observer (GtkActionObservable *observable,
const gchar *action_name,
GtkActionObserver *observer);
G_END_DECLS
#endif /* __GTK_ACTION_OBSERVABLE_H__ */

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