Compare commits
157 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
c64f195e96 | ||
|
247546d531 | ||
|
44252b052d | ||
|
226032d2e1 | ||
|
53f28074ad | ||
|
2993e02c33 | ||
|
628bfc8311 | ||
|
27bfaf9b35 | ||
|
e4e87d03c5 | ||
|
956d89fbec | ||
|
1ad62527ea | ||
|
1d79d74e97 | ||
|
b90183665f | ||
|
73fde364c8 | ||
|
21b05e8150 | ||
|
e8391a726d | ||
|
fb85a476a1 | ||
|
047acb887e | ||
|
eaadeb8ef4 | ||
|
03946a9621 | ||
|
820f689f77 | ||
|
724f99cc62 | ||
|
83125c4849 | ||
|
d8a1ce0871 | ||
|
e156e1a438 | ||
|
83f3084415 | ||
|
81e93d083e | ||
|
542353b8d8 | ||
|
8868d3aa6d | ||
|
c419649fe7 | ||
|
130c726fff | ||
|
ac478727cc | ||
|
331c73002f | ||
|
95a587e81b | ||
|
38a45b4f0f | ||
|
c730cd3296 | ||
|
c10a18ab71 | ||
|
ca2f7597b4 | ||
|
3c70435969 | ||
|
0a1b9867fc | ||
|
d8177a8f3b | ||
|
52417a8363 | ||
|
8191e10665 | ||
|
a6f39a12d7 | ||
|
79a42e097d | ||
|
4a5e276551 | ||
|
35abf39971 | ||
|
c1d107a682 | ||
|
31f67d9142 | ||
|
3a0197c8db | ||
|
c4f744d7ec | ||
|
61b1679719 | ||
|
cdbb1bb665 | ||
|
1020d8a0f8 | ||
|
1f6811ca06 | ||
|
c256154190 | ||
|
60225ef86d | ||
|
48498d83d3 | ||
|
14757dbd6c | ||
|
df89d4dc59 | ||
|
ace549c1bf | ||
|
1198ffd297 | ||
|
1aac5c43e4 | ||
|
4d785d249f | ||
|
efbf102b63 | ||
|
4d1668b01c | ||
|
cad6f31c1a | ||
|
294f59103f | ||
|
f88f51dd99 | ||
|
c1eaf97bc6 | ||
|
1420f62dfa | ||
|
3ff194247a | ||
|
36b1cd13c9 | ||
|
bcede26d77 | ||
|
fbf1ee8a01 | ||
|
1360747c9e | ||
|
1d95841da0 | ||
|
494fcfecf8 | ||
|
75705b45ef | ||
|
1ad1e48741 | ||
|
ddb682e4fe | ||
|
5216b77600 | ||
|
c93d91d80b | ||
|
f9e3467b70 | ||
|
13bea1a01b | ||
|
76c930e471 | ||
|
9f6cd75170 | ||
|
c107882828 | ||
|
d18e084cd5 | ||
|
2eb779740c | ||
|
3ce20568d0 | ||
|
d45ab6f15e | ||
|
cd7197e605 | ||
|
3f6c1aadef | ||
|
29e8290b65 | ||
|
3074e48405 | ||
|
12c2939b64 | ||
|
c7eed59562 | ||
|
73903400c5 | ||
|
dc7cc9b517 | ||
|
b18c239240 | ||
|
3c66f1a4d9 | ||
|
1dff5fb5b2 | ||
|
e2561d15b5 | ||
|
326c3732b8 | ||
|
5dd020f2e2 | ||
|
b6edbd46b9 | ||
|
c330036fef | ||
|
d0a864b9b9 | ||
|
9bed5b725e | ||
|
f374ecfc75 | ||
|
dd8ca02425 | ||
|
ff3f9bdd7d | ||
|
fab02ae82f | ||
|
d43c5ec27a | ||
|
f7de35b852 | ||
|
cde0045851 | ||
|
f844613292 | ||
|
ff2e44de53 | ||
|
17aa8e0488 | ||
|
a33df9b046 | ||
|
c25f399f7c | ||
|
bd47d07fbc | ||
|
72282237e1 | ||
|
dfb44aa51d | ||
|
5516cad087 | ||
|
ab60c31629 | ||
|
52dd030087 | ||
|
98240c2857 | ||
|
65bfd6c6d2 | ||
|
1034e33c35 | ||
|
d7528b878c | ||
|
eb2e66c539 | ||
|
30e9a2a7d0 | ||
|
e842694316 | ||
|
b33d87a762 | ||
|
0ff3599d91 | ||
|
28d79a1235 | ||
|
522d21154b | ||
|
7c231916c1 | ||
|
a40bb67fc6 | ||
|
4c350b90c7 | ||
|
47dee22b05 | ||
|
13c0e575f6 | ||
|
ea8736b13a | ||
|
303d53e7f5 | ||
|
31295dfe83 | ||
|
69ea4553cb | ||
|
0d8d77356e | ||
|
8b78032248 | ||
|
ad277a563c | ||
|
db26fb201e | ||
|
9f00be50d6 | ||
|
77d21e53d0 | ||
|
ba0b4ba590 | ||
|
b9fc7a3050 | ||
|
aa053a906d |
93
NEWS
93
NEWS
@ -1,3 +1,96 @@
|
||||
3.8.4
|
||||
=====
|
||||
* Fix initial text in logout dialog [Matthias; #702056]
|
||||
* Clear login messages when the user answers [John; #702458]
|
||||
* Align the "Not Listed?" label properly in the login screen [Mathieu; #702307]
|
||||
* Workaround crash causing bugs in code [Florian; #610279]
|
||||
* Improve time stamp in chat messages (frequency and formatting)
|
||||
[Carlos; #687809, #687809]
|
||||
* Fix unlock screen after prematurely stopping curtain drag [Lionel; #703126]
|
||||
* Fix autorun notification [Matthis; 703418
|
||||
* Fix background occasionally turning solid blue on monitor changes [Lionel: #703001]
|
||||
* Increase message tray performance [Giovanni; #700194]
|
||||
* Fix focus of notifications after they're expanded [Jasper; #698778]
|
||||
* Fix orientation of gradient on app menu in RTL locales [Jasper; #704583]
|
||||
* Support filenames in addition to file uris for background
|
||||
[Giovanni, Ray; #702121]
|
||||
* misc bug fixes [Adel, Florian, Emilio, Alban, Jasper; #702338, #704265,
|
||||
#698863, #698484]
|
||||
|
||||
Contributors:
|
||||
Mathieu Bridon, Alban Browaeys, Giovanni Campagna, Matthias Clasen, Adel Gadllah,
|
||||
Emilio Pozuelo Monfort, Linonel Landwerlin, Carlos Soriano, Ray Strode,
|
||||
John Wendell
|
||||
|
||||
3.8.3
|
||||
=====
|
||||
* Fix child menu regression introduced in 3.8.2 [Florian; #699678]
|
||||
* Fix alt-tab not always switching back to the previous window [Florian; #700356]
|
||||
* Fix VPN network icon regression introduced in 3.8.2 [Florian; #700394]
|
||||
* Allow switch-to-workspace-n keybindings in overview [Florian; #649977]
|
||||
* Update man page [Matthias; #700339]
|
||||
* Add FocusSearch DBus method [Florian; #700536]
|
||||
* gdm: Update the session chooser style [Allan; #695742]
|
||||
* Fix some app folders getting truncated at the top [Florian; #694371]
|
||||
* Fix duplicate cursors in screenshots with magnification [Florian; #700488]
|
||||
* popupMenu: Allow for an optional border for slider handle [Florian; #697917]
|
||||
* 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]
|
||||
* Tweak timeout for activating windows during XDND [Adel; #700150]
|
||||
* Fix fullscreen windows not being unredirected when legacy tray icons
|
||||
are around [Adel; #701224]
|
||||
* Fix ellipsization in control buttons in app picker [Carlos; #696307]
|
||||
* Fix DND to empty dash [Florian; #684618]
|
||||
* Fix OSD window appearing below system modal dialogs [Rui; #701269]
|
||||
* Clear clipboard on screen lock to prevent information leak [Florian; #698922]
|
||||
* Allow session mode specific overrides schema [Florian; #701717]
|
||||
* Fix incomplete app menu if multiple actions only become available later
|
||||
[Xavier; #694612]
|
||||
* Fix showing the OSD when a fullscreen app is unredirected [Adel, #701224]
|
||||
* window-switcher: Only show windows from current workspace by default
|
||||
[Florian; #701214
|
||||
* Misc bug fixes [Florian, Rui, Giovanni, Stef; #700409, #700625, #700807,
|
||||
#700842, #700900, #700944, #700190, #700972, #700877]
|
||||
|
||||
Contributors:
|
||||
Giovanni Campagna, Xavier Claessens, Matthias Clasen, Allan Day,
|
||||
Adel Gadllah, Rui Matos, Florian Müllner, Carlos Soriano, Stef Walter
|
||||
|
||||
Translations:
|
||||
Cheng-Chia Tseng [zh_HK, zh_TW], eternalhui [zh_CN]
|
||||
|
||||
3.8.2
|
||||
=====
|
||||
* 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]
|
||||
* ctrlAltTab: Use symbolic icons for desktop windows [Matthias; #697914]
|
||||
* gdm: Fix regression where domain login hint not shown [Stef; #698200]
|
||||
* 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]
|
||||
* Provide a DBus API for screencasting [Florian; #696247]
|
||||
* Implement app folder keynav and shortcuts [Florian; #695314]
|
||||
* polkitAgent: Allow retrying after mistyped passwords [Stef; #684431]
|
||||
* Add input purpose and hints to StEntry and StIMText [Daiki; #691392]
|
||||
* Set input-purpose property for password entries [Rui; #700043]
|
||||
* Misc fixes and cleanups [Jasper, Florian, Giovanni, Tim, Rui; #697203,
|
||||
#698959, #696720, #698531, #676285, #698812, #699189]
|
||||
|
||||
Contributors:
|
||||
Giovanni Campagna, Matthias Clasen, Lionel Landwerlin, Tim Lunn, Rui Matos,
|
||||
Simon McVittie, Marta Milakovic, Florian Müllner, Jasper St. Pierre,
|
||||
Daiki Ueno, Stef Walter
|
||||
|
||||
Translations:
|
||||
Muhammet Kara [tr], Nik Kalach [ia], Žygimantas Beručka [lt],
|
||||
Kjartan Maraas [nb]
|
||||
|
||||
3.8.1
|
||||
=====
|
||||
* Clip window group during startup animation [Jasper; #696323]
|
||||
|
@ -1,5 +1,5 @@
|
||||
AC_PREREQ(2.63)
|
||||
AC_INIT([gnome-shell],[3.8.1],[https://bugzilla.gnome.org/enter_bug.cgi?product=gnome-shell],[gnome-shell])
|
||||
AC_INIT([gnome-shell],[3.8.4],[https://bugzilla.gnome.org/enter_bug.cgi?product=gnome-shell],[gnome-shell])
|
||||
|
||||
AC_CONFIG_HEADERS([config.h])
|
||||
AC_CONFIG_SRCDIR([src/shell-global.c])
|
||||
@ -63,7 +63,7 @@ AM_CONDITIONAL(BUILD_RECORDER, $build_recorder)
|
||||
CLUTTER_MIN_VERSION=1.13.4
|
||||
GOBJECT_INTROSPECTION_MIN_VERSION=0.10.1
|
||||
GJS_MIN_VERSION=1.35.4
|
||||
MUTTER_MIN_VERSION=3.8.1
|
||||
MUTTER_MIN_VERSION=3.8.3
|
||||
GTK_MIN_VERSION=3.7.9
|
||||
GIO_MIN_VERSION=2.35.0
|
||||
LIBECAL_MIN_VERSION=3.5.3
|
||||
@ -71,7 +71,7 @@ LIBEDATASERVER_MIN_VERSION=3.5.3
|
||||
TELEPATHY_GLIB_MIN_VERSION=0.17.5
|
||||
POLKIT_MIN_VERSION=0.100
|
||||
STARTUP_NOTIFICATION_MIN_VERSION=0.11
|
||||
GCR_MIN_VERSION=3.3.90
|
||||
GCR_MIN_VERSION=3.7.5
|
||||
GNOME_DESKTOP_REQUIRED_VERSION=3.7.90
|
||||
GNOME_MENUS_REQUIRED_VERSION=3.5.3
|
||||
NETWORKMANAGER_MIN_VERSION=0.9.6
|
||||
@ -96,7 +96,7 @@ PKG_CHECK_MODULES(GNOME_SHELL, gio-unix-2.0 >= $GIO_MIN_VERSION
|
||||
polkit-agent-1 >= $POLKIT_MIN_VERSION xfixes
|
||||
libnm-glib libnm-util >= $NETWORKMANAGER_MIN_VERSION
|
||||
libnm-gtk >= $NETWORKMANAGER_MIN_VERSION
|
||||
libsecret-unstable gcr-3 >= $GCR_MIN_VERSION)
|
||||
libsecret-unstable gcr-base-3 >= $GCR_MIN_VERSION)
|
||||
|
||||
PKG_CHECK_MODULES(GNOME_SHELL_JS, gio-2.0 gjs-internals-1.0 >= $GJS_MIN_VERSION)
|
||||
PKG_CHECK_MODULES(ST, clutter-1.0 gtk+-3.0 libcroco-0.6 >= 0.6.8 x11)
|
||||
|
@ -15,6 +15,7 @@ desktop_DATA = gnome-shell.desktop gnome-shell-extension-prefs.desktop
|
||||
|
||||
introspectiondir = $(datadir)/dbus-1/interfaces
|
||||
introspection_DATA = \
|
||||
org.gnome.Shell.Screencast.xml \
|
||||
org.gnome.Shell.Screenshot.xml \
|
||||
org.gnome.ShellSearchProvider.xml \
|
||||
org.gnome.ShellSearchProvider2.xml
|
||||
|
96
data/org.gnome.Shell.Screencast.xml
Normal file
96
data/org.gnome.Shell.Screencast.xml
Normal file
@ -0,0 +1,96 @@
|
||||
<!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>
|
@ -207,7 +207,7 @@ value here is from the GsmPresenceStatus enumeration.</_summary>
|
||||
</_description>
|
||||
</key>
|
||||
<key type="b" name="current-workspace-only">
|
||||
<default>false</default>
|
||||
<default>true</default>
|
||||
<summary>Limit switcher to current workspace.</summary>
|
||||
<description>
|
||||
If true, only windows from the current workspace are shown in the switcher.
|
||||
|
@ -800,6 +800,11 @@ StScrollBar StButton#vhandle:active {
|
||||
height: 24px;
|
||||
}
|
||||
|
||||
.empty-dash-drop-target {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
}
|
||||
|
||||
/* Search Box */
|
||||
|
||||
#searchEntry {
|
||||
@ -887,12 +892,11 @@ StScrollBar StButton#vhandle:active {
|
||||
}
|
||||
|
||||
.app-view-controls {
|
||||
width: 250px;
|
||||
padding-bottom: 32px;
|
||||
}
|
||||
|
||||
.app-view-control {
|
||||
padding: 4px 16px;
|
||||
padding: 4px 32px;
|
||||
}
|
||||
|
||||
.search-display > StBoxLayout,
|
||||
@ -2308,6 +2312,7 @@ StScrollBar StButton#vhandle:active {
|
||||
font-weight: bold;
|
||||
color: #666666;
|
||||
padding-top: 1em;
|
||||
padding-left: 2px;
|
||||
}
|
||||
|
||||
.login-dialog-not-listed-button:focus .login-dialog-not-listed-label,
|
||||
@ -2338,52 +2343,47 @@ StScrollBar StButton#vhandle:active {
|
||||
width: 15em;
|
||||
}
|
||||
|
||||
.login-dialog-session-list {
|
||||
color: #ffffff;
|
||||
font-size: 10.5pt;
|
||||
.login-dialog-session-list,
|
||||
.login-dialog-session-list-item {
|
||||
color: #babdb6;
|
||||
}
|
||||
|
||||
.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 {
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
.login-dialog-session-list-button:focus {
|
||||
background-color: #4c4c4c;
|
||||
}
|
||||
|
||||
.login-dialog-session-list-button:active {
|
||||
background-color: #4c4c4c;
|
||||
}
|
||||
|
||||
.login-dialog-session-list-button:hover {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.login-dialog-session-list-scroll-view {
|
||||
background-gradient-start: rgba(80,80,80,0.3);
|
||||
background-gradient-end: rgba(80,80,80,0.7);
|
||||
background-gradient-direction: vertical;
|
||||
box-shadow: inset 0px 2px 4px rgba(0,0,0,0.9);
|
||||
border-radius: 8px;
|
||||
border: 1px solid rgba(80,80,80,1.0);
|
||||
padding: .5em;
|
||||
padding: 6px;
|
||||
}
|
||||
|
||||
.login-dialog-session-list-item:focus {
|
||||
background-color: #666666;
|
||||
.login-dialog-session-list-item {
|
||||
padding-bottom: 6px;
|
||||
}
|
||||
|
||||
.login-dialog-session-list-triangle {
|
||||
padding-right: .5em;
|
||||
padding-right: 6px;
|
||||
}
|
||||
|
||||
.login-dialog-session-list-item-box {
|
||||
spacing: .25em;
|
||||
padding-left: 6px;
|
||||
spacing: 6px;
|
||||
}
|
||||
|
||||
.login-dialog-session-list-item-dot {
|
||||
width: .75em;
|
||||
height: .75em;
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
}
|
||||
|
||||
.login-dialog-logo-bin {
|
||||
padding: 24px 0px;
|
||||
}
|
||||
|
||||
.login-dialog .modal-dialog-button-box {
|
||||
|
@ -46,6 +46,7 @@
|
||||
<xi:include href="doc-gen-org.gnome.Shell.SearchProvider.xml"/>
|
||||
<xi:include href="doc-gen-org.gnome.Shell.SearchProvider2.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-xfixes-cursor.xml"/>
|
||||
<xi:include href="xml/shell-util.xml"/>
|
||||
|
@ -78,6 +78,7 @@ nobase_dist_js_DATA = \
|
||||
ui/popupMenu.js \
|
||||
ui/remoteSearch.js \
|
||||
ui/runDialog.js \
|
||||
ui/screencast.js \
|
||||
ui/screenshot.js \
|
||||
ui/screenShield.js \
|
||||
ui/scripting.js \
|
||||
|
@ -28,6 +28,7 @@ const Mainloop = imports.mainloop;
|
||||
const Meta = imports.gi.Meta;
|
||||
const Lang = imports.lang;
|
||||
const Pango = imports.gi.Pango;
|
||||
const Realmd = imports.gdm.realmd;
|
||||
const Signals = imports.signals;
|
||||
const Shell = imports.gi.Shell;
|
||||
const St = imports.gi.St;
|
||||
@ -39,7 +40,6 @@ const GdmUtil = imports.gdm.util;
|
||||
const Lightbox = imports.ui.lightbox;
|
||||
const Main = imports.ui.main;
|
||||
const ModalDialog = imports.ui.modalDialog;
|
||||
const Panel = imports.ui.panel;
|
||||
const PanelMenu = imports.ui.panelMenu;
|
||||
const Tweener = imports.ui.tweener;
|
||||
const UserMenu = imports.ui.userMenu;
|
||||
@ -48,44 +48,10 @@ const UserWidget = imports.ui.userWidget;
|
||||
const _FADE_ANIMATION_TIME = 0.25;
|
||||
const _SCROLL_ANIMATION_TIME = 0.5;
|
||||
const _TIMED_LOGIN_IDLE_THRESHOLD = 5.0;
|
||||
const _LOGO_ICON_HEIGHT = 16;
|
||||
|
||||
const WORK_SPINNER_ICON_SIZE = 24;
|
||||
const WORK_SPINNER_ANIMATION_DELAY = 1.0;
|
||||
const WORK_SPINNER_ANIMATION_TIME = 0.3;
|
||||
const _LOGO_ICON_HEIGHT = 48;
|
||||
|
||||
let _loginDialog = null;
|
||||
|
||||
const LogoMenuButton = new Lang.Class({
|
||||
Name: 'LogoMenuButton',
|
||||
Extends: PanelMenu.Button,
|
||||
|
||||
_init: function() {
|
||||
this.parent(0.0, null, true);
|
||||
|
||||
this._settings = new Gio.Settings({ schema: GdmUtil.LOGIN_SCREEN_SCHEMA });
|
||||
this._settings.connect('changed::' + GdmUtil.LOGO_KEY,
|
||||
Lang.bind(this, this._updateLogo));
|
||||
|
||||
this._iconBin = new St.Bin();
|
||||
this.actor.add_actor(this._iconBin);
|
||||
|
||||
this._updateLogo();
|
||||
},
|
||||
|
||||
_updateLogo: function() {
|
||||
let path = this._settings.get_string(GdmUtil.LOGO_KEY);
|
||||
let icon = null;
|
||||
|
||||
if (path) {
|
||||
let file = Gio.file_new_for_path(path);
|
||||
let cache = St.TextureCache.get_default();
|
||||
icon = cache.load_uri_async(file.get_uri(), -1, _LOGO_ICON_HEIGHT);
|
||||
}
|
||||
this._iconBin.set_child(icon);
|
||||
}
|
||||
});
|
||||
|
||||
const UserListItem = new Lang.Class({
|
||||
Name: 'UserListItem',
|
||||
|
||||
@ -552,6 +518,12 @@ const LoginDialog = new Lang.Class({
|
||||
Lang.bind(this, this._updateBanner));
|
||||
this._settings.connect('changed::' + GdmUtil.DISABLE_USER_LIST_KEY,
|
||||
Lang.bind(this, this._updateDisableUserList));
|
||||
this._settings.connect('changed::' + GdmUtil.LOGO_KEY,
|
||||
Lang.bind(this, this._updateLogo));
|
||||
|
||||
this._textureCache = St.TextureCache.get_default();
|
||||
this._textureCache.connect('texture-file-changed',
|
||||
Lang.bind(this, this._updateLogoTexture));
|
||||
|
||||
this._userSelectionBox = new St.BoxLayout({ style_class: 'login-dialog-user-selection-box',
|
||||
vertical: true });
|
||||
@ -609,7 +581,6 @@ const LoginDialog = new Lang.Class({
|
||||
this._promptBox.add(this._promptLoginHint);
|
||||
|
||||
this._signInButton = null;
|
||||
this._workSpinner = null;
|
||||
|
||||
this._sessionList = new SessionList();
|
||||
this._sessionList.connect('session-activated',
|
||||
@ -644,6 +615,11 @@ const LoginDialog = new Lang.Class({
|
||||
x_align: St.Align.START,
|
||||
x_fill: true });
|
||||
|
||||
this._logoBin = new St.Bin({ style_class: 'login-dialog-logo-bin', y_expand: true });
|
||||
this._logoBin.set_y_align(Clutter.ActorAlign.END);
|
||||
this.backgroundStack.add_actor(this._logoBin);
|
||||
this._updateLogo();
|
||||
|
||||
if (!this._userManager.is_loaded)
|
||||
this._userManagerLoadedId = this._userManager.connect('notify::is-loaded',
|
||||
Lang.bind(this, function() {
|
||||
@ -690,6 +666,24 @@ const LoginDialog = new Lang.Class({
|
||||
}
|
||||
},
|
||||
|
||||
_updateLogoTexture: function(cache, uri) {
|
||||
if (this._logoFileUri != uri)
|
||||
return;
|
||||
|
||||
let icon = null;
|
||||
if (this._logoFileUri)
|
||||
icon = this._textureCache.load_uri_async(this._logoFileUri,
|
||||
-1, _LOGO_ICON_HEIGHT);
|
||||
this._logoBin.set_child(icon);
|
||||
},
|
||||
|
||||
_updateLogo: function() {
|
||||
let path = this._settings.get_string(GdmUtil.LOGO_KEY);
|
||||
|
||||
this._logoFileUri = path ? Gio.file_new_for_path(path).get_uri() : null;
|
||||
this._updateLogoTexture(this._textureCache, this._logoFileUri);
|
||||
},
|
||||
|
||||
_reset: function() {
|
||||
this._userVerifier.clear();
|
||||
|
||||
@ -708,7 +702,7 @@ const LoginDialog = new Lang.Class({
|
||||
this._promptEntry.text = '';
|
||||
|
||||
this._updateSensitivity(true);
|
||||
this._setWorking(false);
|
||||
this.setWorking(false);
|
||||
},
|
||||
|
||||
_onDefaultSessionChanged: function(client, sessionId) {
|
||||
@ -774,11 +768,6 @@ const LoginDialog = new Lang.Class({
|
||||
},
|
||||
|
||||
_prepareDialog: function(forSecret, hold) {
|
||||
let spinnerIcon = global.datadir + '/theme/process-working.svg';
|
||||
this._workSpinner = new Panel.AnimatedIcon(spinnerIcon, WORK_SPINNER_ICON_SIZE);
|
||||
this._workSpinner.actor.opacity = 0;
|
||||
this._workSpinner.actor.show();
|
||||
|
||||
this.buttonLayout.visible = true;
|
||||
this.clearButtons();
|
||||
|
||||
@ -791,12 +780,11 @@ const LoginDialog = new Lang.Class({
|
||||
y_fill: false,
|
||||
x_align: St.Align.START,
|
||||
y_align: St.Align.MIDDLE });
|
||||
this.buttonLayout.add(this._workSpinner.actor,
|
||||
{ expand: false,
|
||||
x_fill: false,
|
||||
y_fill: false,
|
||||
x_align: St.Align.END,
|
||||
y_align: St.Align.MIDDLE });
|
||||
this.placeSpinner({ expand: false,
|
||||
x_fill: false,
|
||||
y_fill: false,
|
||||
x_align: St.Align.END,
|
||||
y_align: St.Align.MIDDLE });
|
||||
this._signInButton = this.addButton({ action: Lang.bind(this, function() {
|
||||
hold.release();
|
||||
}),
|
||||
@ -849,7 +837,7 @@ const LoginDialog = new Lang.Class({
|
||||
this._promptEntryActivateId = 0;
|
||||
}
|
||||
|
||||
this._setWorking(false);
|
||||
this.setWorking(false);
|
||||
this._promptBox.hide();
|
||||
this._promptLoginHint.hide();
|
||||
|
||||
@ -862,36 +850,9 @@ const LoginDialog = new Lang.Class({
|
||||
this._promptLoginHint.hide();
|
||||
|
||||
this.clearButtons();
|
||||
this._workSpinner = null;
|
||||
this._signInButton = null;
|
||||
},
|
||||
|
||||
_setWorking: function(working) {
|
||||
if (!this._workSpinner)
|
||||
return;
|
||||
|
||||
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();
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
_askQuestion: function(verifier, serviceName, question, passwordChar) {
|
||||
this._promptLabel.set_text(question);
|
||||
|
||||
@ -906,7 +867,7 @@ const LoginDialog = new Lang.Class({
|
||||
function() {
|
||||
let text = this._promptEntry.get_text();
|
||||
this._updateSensitivity(false);
|
||||
this._setWorking(true);
|
||||
this.setWorking(true);
|
||||
this._userVerifier.answerQuery(serviceName, text);
|
||||
}];
|
||||
|
||||
@ -914,17 +875,40 @@ const LoginDialog = new Lang.Class({
|
||||
return batch.run();
|
||||
},
|
||||
|
||||
_showRealmLoginHint: function(realmManager, hint) {
|
||||
if (!hint)
|
||||
return;
|
||||
|
||||
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._showLoginHint(null, _("(e.g., user or %s)").format(hint));
|
||||
},
|
||||
|
||||
_askForUsernameAndLogIn: function() {
|
||||
this._promptLabel.set_text(_("Username: "));
|
||||
this._promptEntry.set_text('');
|
||||
this._promptEntry.clutter_text.set_password_char('');
|
||||
|
||||
let realmManager = new Realmd.Manager();
|
||||
let signalId = realmManager.connect('login-format-changed',
|
||||
Lang.bind(this, this._showRealmLoginHint));
|
||||
this._showRealmLoginHint(realmManager.loginFormat);
|
||||
|
||||
let tasks = [this._showPrompt,
|
||||
|
||||
function() {
|
||||
let userName = this._promptEntry.get_text();
|
||||
this._promptEntry.reactive = false;
|
||||
return this._beginVerificationForUser(userName);
|
||||
},
|
||||
|
||||
function() {
|
||||
realmManager.disconnect(signalId)
|
||||
realmManager.release();
|
||||
}];
|
||||
|
||||
let batch = new Batch.ConsecutiveBatch(this, tasks);
|
||||
|
@ -63,7 +63,7 @@ const Manager = new Lang.Class({
|
||||
Lang.bind(this, this._reloadRealms))
|
||||
this._realms = {};
|
||||
|
||||
this._aggregateProvider.connect('g-properties-changed',
|
||||
this._signalId = this._aggregateProvider.connect('g-properties-changed',
|
||||
Lang.bind(this, function(proxy, properties) {
|
||||
if ('Realms' in properties.deep_unpack())
|
||||
this._reloadRealms();
|
||||
@ -106,7 +106,7 @@ const Manager = new Lang.Class({
|
||||
realm.connect('g-properties-changed',
|
||||
Lang.bind(this, function(proxy, properties) {
|
||||
if ('Configured' in properties.deep_unpack())
|
||||
this._reloadRealm();
|
||||
this._reloadRealm(realm);
|
||||
}));
|
||||
},
|
||||
|
||||
@ -134,6 +134,18 @@ const Manager = new Lang.Class({
|
||||
this._updateLoginFormat();
|
||||
|
||||
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)
|
||||
|
@ -9,7 +9,6 @@ const Signals = imports.signals;
|
||||
|
||||
const Batch = imports.gdm.batch;
|
||||
const Fprint = imports.gdm.fingerprint;
|
||||
const Realmd = imports.gdm.realmd;
|
||||
const Main = imports.ui.main;
|
||||
const Params = imports.misc.params;
|
||||
const Tweener = imports.ui.tweener;
|
||||
@ -117,7 +116,6 @@ const ShellUserVerifier = new Lang.Class({
|
||||
this._settings = new Gio.Settings({ schema: LOGIN_SCREEN_SCHEMA });
|
||||
|
||||
this._fprintManager = new Fprint.FprintManager();
|
||||
this._realmManager = new Realmd.Manager();
|
||||
this._messageQueue = [];
|
||||
this._messageQueueTimeoutId = 0;
|
||||
this.hasPendingMessages = false;
|
||||
@ -166,6 +164,7 @@ const ShellUserVerifier = new Lang.Class({
|
||||
|
||||
answerQuery: function(serviceName, answer) {
|
||||
if (!this._userVerifier.hasPendingMessages) {
|
||||
this._clearMessageQueue();
|
||||
this._userVerifier.call_answer_query(serviceName, answer, this._cancellable, null);
|
||||
} else {
|
||||
let signalId = this._userVerifier.connect('no-more-messages',
|
||||
@ -377,30 +376,11 @@ const ShellUserVerifier = new Lang.Class({
|
||||
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) {
|
||||
// We only expect questions to come from the main auth service
|
||||
if (serviceName != PASSWORD_SERVICE_NAME)
|
||||
return;
|
||||
|
||||
this._showRealmLoginHint();
|
||||
this._realmLoginHintSignalId = this._realmManager.connect('login-format-changed',
|
||||
Lang.bind(this, this._showRealmLoginHint));
|
||||
|
||||
this.emit('ask-question', serviceName, question, '');
|
||||
},
|
||||
|
||||
@ -476,11 +456,6 @@ const ShellUserVerifier = new Lang.Class({
|
||||
}
|
||||
|
||||
this.emit('hide-login-hint');
|
||||
|
||||
if (this._realmLoginHintSignalId) {
|
||||
this._realmManager.disconnect(this._realmLoginHintSignalId);
|
||||
this._realmLoginHintSignalId = 0;
|
||||
}
|
||||
},
|
||||
});
|
||||
Signals.addSignalMethods(ShellUserVerifier.prototype);
|
||||
|
@ -58,6 +58,7 @@ const Map = new Lang.Class({
|
||||
|
||||
_init: function(iterable) {
|
||||
this._pool = { };
|
||||
this._size = 0;
|
||||
|
||||
if (iterable) {
|
||||
for (let i = 0; i < iterable.length; i++) {
|
||||
@ -99,6 +100,7 @@ const Map = new Lang.Class({
|
||||
node.value = value;
|
||||
} else {
|
||||
this._pool[hash] = { key: key, value: value };
|
||||
this._size++;
|
||||
}
|
||||
},
|
||||
|
||||
@ -108,6 +110,7 @@ const Map = new Lang.Class({
|
||||
|
||||
if (node && _sameValue(node.key, key)) {
|
||||
delete this._pool[hash];
|
||||
this._size--;
|
||||
return [node.key, node.value];
|
||||
} else {
|
||||
return [null, null];
|
||||
@ -136,6 +139,6 @@ const Map = new Lang.Class({
|
||||
},
|
||||
|
||||
size: function() {
|
||||
return Object.getOwnPropertyNames(this._pool).length;
|
||||
return this._size;
|
||||
},
|
||||
});
|
||||
|
@ -234,7 +234,7 @@ const AppSwitcherPopup = new Lang.Class({
|
||||
_finish : function(timestamp) {
|
||||
let appIcon = this._items[this._selectedIndex];
|
||||
if (this._currentWindow < 0)
|
||||
appIcon.app.activate_full(-1, timestamp);
|
||||
appIcon.app.activate_window(appIcon.cachedWindows[0], timestamp);
|
||||
else
|
||||
Main.activateWindow(appIcon.cachedWindows[this._currentWindow], timestamp);
|
||||
|
||||
|
@ -187,6 +187,9 @@ const AllView = new Lang.Class({
|
||||
_init: function() {
|
||||
this.parent();
|
||||
|
||||
this._grid.actor.y_align = Clutter.ActorAlign.START;
|
||||
this._grid.actor.y_expand = true;
|
||||
|
||||
let box = new St.BoxLayout({ vertical: true });
|
||||
this._stack = new St.Widget({ layout_manager: new AllViewLayout() });
|
||||
this._stack.add_actor(this._grid.actor);
|
||||
@ -276,8 +279,12 @@ const AllView = new Lang.Class({
|
||||
this._eventBlocker.reactive = isOpen;
|
||||
this._currentPopup = isOpen ? popup : null;
|
||||
this._updateIconOpacities(isOpen);
|
||||
if (isOpen)
|
||||
if (isOpen) {
|
||||
this._ensureIconVisible(popup.actor);
|
||||
this._grid.actor.y = popup.parentOffset;
|
||||
} else {
|
||||
this._grid.actor.y = 0;
|
||||
}
|
||||
}));
|
||||
},
|
||||
|
||||
@ -327,6 +334,42 @@ const Views = {
|
||||
ALL: 1
|
||||
};
|
||||
|
||||
const ControlsBoxLayout = Lang.Class({
|
||||
Name: 'ControlsBoxLayout',
|
||||
Extends: Clutter.BoxLayout,
|
||||
|
||||
/**
|
||||
* Override the BoxLayout behavior to use the maximum preferred width of all
|
||||
* buttons for each child
|
||||
*/
|
||||
vfunc_get_preferred_width: function(container, forHeight) {
|
||||
let maxMinWidth = 0;
|
||||
let maxNaturalWidth = 0;
|
||||
for (let child = container.get_first_child();
|
||||
child;
|
||||
child = child.get_next_sibling()) {
|
||||
let [minWidth, natWidth] = child.get_preferred_width(forHeight);
|
||||
maxMinWidth = Math.max(maxMinWidth, minWidth);
|
||||
maxNaturalWidth = Math.max(maxNaturalWidth, natWidth);
|
||||
}
|
||||
let childrenCount = container.get_n_children();
|
||||
let totalSpacing = this.spacing * (childrenCount - 1);
|
||||
return [maxMinWidth * childrenCount + totalSpacing,
|
||||
maxNaturalWidth * childrenCount + totalSpacing];
|
||||
},
|
||||
|
||||
vfunc_set_container: function(container) {
|
||||
if(this._styleChangedId) {
|
||||
this._container.disconnect(this._styleChangedId);
|
||||
this._styleChangedId = 0;
|
||||
}
|
||||
if(container != null)
|
||||
this._styleChangedId = container.connect('style-changed', Lang.bind(this,
|
||||
function() { this.spacing = this._container.get_theme_node().get_length('spacing'); }));
|
||||
this._container = container;
|
||||
}
|
||||
});
|
||||
|
||||
const AppDisplay = new Lang.Class({
|
||||
Name: 'AppDisplay',
|
||||
|
||||
@ -367,9 +410,9 @@ const AppDisplay = new Lang.Class({
|
||||
x_expand: true, y_expand: true });
|
||||
this.actor.add(this._viewStack, { expand: true });
|
||||
|
||||
let layout = new Clutter.BoxLayout({ homogeneous: true });
|
||||
this._controls = new St.Widget({ style_class: 'app-view-controls',
|
||||
layout_manager: layout });
|
||||
let layout = new ControlsBoxLayout({ homogeneous: true });
|
||||
this._controls = new St.Widget({ style_class: 'app-view-controls' });
|
||||
this._controls.set_layout_manager(layout);
|
||||
this.actor.add(new St.Bin({ child: this._controls }));
|
||||
|
||||
|
||||
@ -572,7 +615,11 @@ const FolderIcon = new Lang.Class({
|
||||
// Position the popup above or below the source icon
|
||||
if (side == St.Side.BOTTOM) {
|
||||
this._popup.actor.show();
|
||||
this._popup.actor.y = this.actor.y - this._popup.actor.height;
|
||||
let closeButtonOffset = -this._popup.closeButton.translation_y;
|
||||
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();
|
||||
} else {
|
||||
this._popup.actor.y = this.actor.y + this.actor.height;
|
||||
@ -595,6 +642,7 @@ const AppFolderPopup = new Lang.Class({
|
||||
this._arrowSide = side;
|
||||
|
||||
this._isOpen = false;
|
||||
this.parentOffset = 0;
|
||||
|
||||
this.actor = new St.Widget({ layout_manager: new Clutter.BinLayout(),
|
||||
visible: false,
|
||||
@ -618,17 +666,31 @@ const AppFolderPopup = new Lang.Class({
|
||||
this.actor.add_actor(this._boxPointer.actor);
|
||||
this._boxPointer.bin.set_child(this._view.actor);
|
||||
|
||||
let closeButton = Util.makeCloseButton();
|
||||
closeButton.connect('clicked', Lang.bind(this, this.popdown));
|
||||
this.actor.add_actor(closeButton);
|
||||
this.closeButton = Util.makeCloseButton();
|
||||
this.closeButton.connect('clicked', Lang.bind(this, this.popdown));
|
||||
this.actor.add_actor(this.closeButton);
|
||||
|
||||
this._boxPointer.actor.bind_property('opacity', closeButton, 'opacity',
|
||||
this._boxPointer.actor.bind_property('opacity', this.closeButton, 'opacity',
|
||||
GObject.BindingFlags.SYNC_CREATE);
|
||||
|
||||
global.focus_manager.add_group(this.actor);
|
||||
|
||||
source.actor.connect('destroy', Lang.bind(this,
|
||||
function() {
|
||||
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() {
|
||||
@ -643,6 +705,7 @@ const AppFolderPopup = new Lang.Class({
|
||||
return;
|
||||
|
||||
this.actor.show();
|
||||
this.actor.navigate_focus(null, Gtk.DirectionType.TAB_FORWARD, false);
|
||||
|
||||
this._boxPointer.setArrowActor(this._source.actor);
|
||||
this._boxPointer.show(BoxPointer.PopupAnimation.FADE |
|
||||
|
@ -318,9 +318,9 @@ const Background = new Lang.Class({
|
||||
this._cancellable = new Gio.Cancellable();
|
||||
this.isLoaded = false;
|
||||
|
||||
this._settings.connect('changed', Lang.bind(this, function() {
|
||||
this.emit('changed');
|
||||
}));
|
||||
this._settingsChangedSignalId = this._settings.connect('changed', Lang.bind(this, function() {
|
||||
this.emit('changed');
|
||||
}));
|
||||
|
||||
this._load();
|
||||
},
|
||||
@ -361,6 +361,10 @@ const Background = new Lang.Class({
|
||||
|
||||
this.actor.disconnect(this._destroySignalId);
|
||||
this._destroySignalId = 0;
|
||||
|
||||
if (this._settingsChangedSignalId != 0)
|
||||
this._settings.disconnect(this._settingsChangedSignalId);
|
||||
this._settingsChangedSignalId = 0;
|
||||
},
|
||||
|
||||
_setLoaded: function() {
|
||||
@ -571,7 +575,16 @@ const Background = new Lang.Class({
|
||||
}
|
||||
|
||||
let uri = this._settings.get_string(PICTURE_URI_KEY);
|
||||
let filename = Gio.File.new_for_uri(uri).get_path();
|
||||
let filename;
|
||||
if (GLib.uri_parse_scheme(uri) != null)
|
||||
filename = Gio.File.new_for_uri(uri).get_path();
|
||||
else
|
||||
filename = uri;
|
||||
|
||||
if (!filename) {
|
||||
this._setLoaded();
|
||||
return;
|
||||
}
|
||||
|
||||
this._loadFile(filename);
|
||||
},
|
||||
|
@ -46,8 +46,10 @@ function addBackgroundMenu(actor) {
|
||||
clickAction.connect('long-press', function(action, actor, state) {
|
||||
if (state == Clutter.LongPressState.QUERY)
|
||||
return action.get_button() == 1 && !actor._backgroundMenu.isOpen;
|
||||
if (state == Clutter.LongPressState.ACTIVATE)
|
||||
if (state == Clutter.LongPressState.ACTIVATE) {
|
||||
openMenu();
|
||||
actor._backgroundManager.ignoreRelease();
|
||||
}
|
||||
return true;
|
||||
});
|
||||
clickAction.connect('clicked', function(action) {
|
||||
|
@ -589,12 +589,12 @@ const BoxPointer = new Lang.Class({
|
||||
return St.Side.TOP;
|
||||
break;
|
||||
case St.Side.LEFT:
|
||||
if (sourceAllocation.y2 + boxWidth > monitor.x + monitor.width &&
|
||||
if (sourceAllocation.x2 + boxWidth > monitor.x + monitor.width &&
|
||||
boxWidth < sourceAllocation.x1 - monitor.x)
|
||||
return St.Side.RIGHT;
|
||||
break;
|
||||
case St.Side.RIGHT:
|
||||
if (sourceAllocation.y1 - boxWidth < monitor.x &&
|
||||
if (sourceAllocation.x1 - boxWidth < monitor.x &&
|
||||
boxWidth < monitor.x + monitor.width - sourceAllocation.x2)
|
||||
return St.Side.LEFT;
|
||||
break;
|
||||
|
@ -31,7 +31,7 @@ function shouldAutorunMount(mount, forTransient) {
|
||||
if (!volume || (!volume.allowAutorun && forTransient))
|
||||
return false;
|
||||
|
||||
if (!root.is_native() || isMountRootHidden(root))
|
||||
if (root.is_native() && isMountRootHidden(root))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
@ -25,7 +25,7 @@ const KeyringDialog = new Lang.Class({
|
||||
this.prompt = new Shell.KeyringPrompt();
|
||||
this.prompt.connect('show-password', Lang.bind(this, this._onShowPassword));
|
||||
this.prompt.connect('show-confirm', Lang.bind(this, this._onShowConfirm));
|
||||
this.prompt.connect('hide-prompt', Lang.bind(this, this._onHidePrompt));
|
||||
this.prompt.connect('prompt-close', Lang.bind(this, this._onHidePrompt));
|
||||
|
||||
let mainContentBox = new St.BoxLayout({ style_class: 'prompt-dialog-main-layout',
|
||||
vertical: false });
|
||||
@ -63,11 +63,17 @@ const KeyringDialog = new Lang.Class({
|
||||
|
||||
this._cancelButton = this.addButton({ label: '',
|
||||
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: '',
|
||||
action: Lang.bind(this, this._onContinueButton),
|
||||
default: true },
|
||||
{ expand: true, x_fill: false, x_align: St.Align.END });
|
||||
{ expand: false, 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('continue-label', this._continueButton, 'label', GObject.BindingFlags.SYNC_CREATE);
|
||||
@ -143,11 +149,19 @@ const KeyringDialog = new Lang.Class({
|
||||
},
|
||||
|
||||
_updateSensitivity: function(sensitive) {
|
||||
this._passwordEntry.reactive = sensitive;
|
||||
this._passwordEntry.clutter_text.editable = sensitive;
|
||||
if (this._passwordEntry) {
|
||||
this._passwordEntry.reactive = 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.reactive = sensitive;
|
||||
this.setWorking(!sensitive);
|
||||
},
|
||||
|
||||
_ensureOpen: function() {
|
||||
|
@ -31,7 +31,6 @@ const AuthenticationDialog = new Lang.Class({
|
||||
this.message = message;
|
||||
this.userNames = userNames;
|
||||
this._wasDismissed = false;
|
||||
this._completed = false;
|
||||
|
||||
let mainContentBox = new St.BoxLayout({ style_class: 'prompt-dialog-main-layout',
|
||||
vertical: false });
|
||||
@ -161,26 +160,32 @@ const AuthenticationDialog = new Lang.Class({
|
||||
|
||||
this._cancelButton = this.addButton({ label: _("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"),
|
||||
action: Lang.bind(this, this._onAuthenticateButtonPressed),
|
||||
default: true },
|
||||
{ expand: true, x_fill: false, x_align: St.Align.END });
|
||||
{ expand: false, x_fill: false, x_align: St.Align.END });
|
||||
|
||||
this._doneEmitted = false;
|
||||
|
||||
this._identityToAuth = Polkit.UnixUser.new_for_name(userName);
|
||||
this._cookie = cookie;
|
||||
},
|
||||
|
||||
performAuthentication: function() {
|
||||
this.destroySession();
|
||||
this._session = new PolkitAgent.Session({ identity: this._identityToAuth,
|
||||
cookie: this._cookie });
|
||||
this._session.connect('completed', Lang.bind(this, this._onSessionCompleted));
|
||||
this._session.connect('request', Lang.bind(this, this._onSessionRequest));
|
||||
this._session.connect('show-error', Lang.bind(this, this._onSessionShowError));
|
||||
this._session.connect('show-info', Lang.bind(this, this._onSessionShowInfo));
|
||||
},
|
||||
|
||||
startAuthentication: function() {
|
||||
this._session.initiate();
|
||||
},
|
||||
|
||||
@ -202,14 +207,14 @@ const AuthenticationDialog = new Lang.Class({
|
||||
log('polkitAuthenticationAgent: Failed to show modal dialog.' +
|
||||
' Dismissing authentication request for action-id ' + this.actionId +
|
||||
' cookie ' + this._cookie);
|
||||
this._emitDone(false, true);
|
||||
this._emitDone(true);
|
||||
}
|
||||
},
|
||||
|
||||
_emitDone: function(keepVisible, dismissed) {
|
||||
_emitDone: function(dismissed) {
|
||||
if (!this._doneEmitted) {
|
||||
this._doneEmitted = true;
|
||||
this.emit('done', keepVisible, dismissed);
|
||||
this.emit('done', dismissed);
|
||||
}
|
||||
},
|
||||
|
||||
@ -219,6 +224,7 @@ const AuthenticationDialog = new Lang.Class({
|
||||
|
||||
this._okButton.can_focus = sensitive;
|
||||
this._okButton.reactive = sensitive;
|
||||
this.setWorking(!sensitive);
|
||||
},
|
||||
|
||||
_onEntryActivate: function() {
|
||||
@ -237,12 +243,16 @@ const AuthenticationDialog = new Lang.Class({
|
||||
},
|
||||
|
||||
_onSessionCompleted: function(session, gainedAuthorization) {
|
||||
if (this._completed)
|
||||
if (this._completed || this._doneEmitted)
|
||||
return;
|
||||
|
||||
this._completed = true;
|
||||
|
||||
if (!gainedAuthorization) {
|
||||
/* Yay, all done */
|
||||
if (gainedAuthorization) {
|
||||
this._emitDone(false);
|
||||
|
||||
} else {
|
||||
/* Unless we are showing an existing error message from the PAM
|
||||
* module (the PAM module could be reporting the authentication
|
||||
* error providing authentication-method specific information),
|
||||
@ -258,8 +268,10 @@ const AuthenticationDialog = new Lang.Class({
|
||||
this._infoMessageLabel.hide();
|
||||
this._nullMessageLabel.hide();
|
||||
}
|
||||
|
||||
/* Try and authenticate again */
|
||||
this.performAuthentication();
|
||||
}
|
||||
this._emitDone(!gainedAuthorization, false);
|
||||
},
|
||||
|
||||
_onSessionRequest: function(session, request, echo_on) {
|
||||
@ -303,6 +315,7 @@ const AuthenticationDialog = new Lang.Class({
|
||||
if (this._session) {
|
||||
if (!this._completed)
|
||||
this._session.cancel();
|
||||
this._completed = false;
|
||||
this._session = null;
|
||||
}
|
||||
},
|
||||
@ -317,7 +330,7 @@ const AuthenticationDialog = new Lang.Class({
|
||||
cancel: function() {
|
||||
this._wasDismissed = true;
|
||||
this.close(global.get_current_time());
|
||||
this._emitDone(false, true);
|
||||
this._emitDone(true);
|
||||
},
|
||||
});
|
||||
Signals.addSignalMethods(AuthenticationDialog.prototype);
|
||||
@ -327,7 +340,6 @@ const AuthenticationAgent = new Lang.Class({
|
||||
|
||||
_init: function() {
|
||||
this._currentDialog = null;
|
||||
this._isCompleting = false;
|
||||
this._handle = null;
|
||||
this._native = new Shell.PolkitAuthenticationAgent();
|
||||
this._native.connect('initiate', Lang.bind(this, this._onInitiate));
|
||||
@ -364,45 +376,24 @@ const AuthenticationAgent = new Lang.Class({
|
||||
// discussion.
|
||||
|
||||
this._currentDialog.connect('done', Lang.bind(this, this._onDialogDone));
|
||||
this._currentDialog.startAuthentication();
|
||||
this._currentDialog.performAuthentication();
|
||||
},
|
||||
|
||||
_onCancel: function(nativeAgent) {
|
||||
this._completeRequest(false, false);
|
||||
this._completeRequest(false);
|
||||
},
|
||||
|
||||
_onDialogDone: function(dialog, keepVisible, dismissed) {
|
||||
this._completeRequest(keepVisible, dismissed);
|
||||
_onDialogDone: function(dialog, dismissed) {
|
||||
this._completeRequest(dismissed);
|
||||
},
|
||||
|
||||
_reallyCompleteRequest: function(dismissed) {
|
||||
_completeRequest: function(dismissed) {
|
||||
this._currentDialog.close();
|
||||
this._currentDialog.destroySession();
|
||||
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;
|
||||
|
@ -18,7 +18,7 @@ const Params = imports.misc.params;
|
||||
const PopupMenu = imports.ui.popupMenu;
|
||||
|
||||
// See Notification.appendMessage
|
||||
const SCROLLBACK_IMMEDIATE_TIME = 60; // 1 minute
|
||||
const SCROLLBACK_IMMEDIATE_TIME = 3 * 60; // 3 minutes
|
||||
const SCROLLBACK_RECENT_TIME = 15 * 60; // 15 minutes
|
||||
const SCROLLBACK_RECENT_LENGTH = 20;
|
||||
const SCROLLBACK_IDLE_LENGTH = 5;
|
||||
@ -967,7 +967,8 @@ const ChatNotification = new Lang.Class({
|
||||
let timeLabel = this._append({ body: this._formatTimestamp(lastMessageDate),
|
||||
group: 'meta',
|
||||
styles: ['chat-meta-message'],
|
||||
childProps: { expand: true, x_fill: false },
|
||||
childProps: { expand: true, x_fill: false,
|
||||
x_align: St.Align.END },
|
||||
noTimestamp: true,
|
||||
timestamp: lastMessageTime });
|
||||
|
||||
|
@ -89,19 +89,25 @@ const CtrlAltTabManager = new Lang.Class({
|
||||
let items = this._items.filter(function (item) { return item.proxy.mapped; });
|
||||
|
||||
// And add the windows metacity would show in its Ctrl-Alt-Tab list
|
||||
if (!Main.overview.visible) {
|
||||
if (Main.sessionMode.hasWindows && !Main.overview.visible) {
|
||||
let screen = global.screen;
|
||||
let display = screen.get_display();
|
||||
let windows = display.get_tab_list(Meta.TabList.DOCKS, screen, screen.get_active_workspace ());
|
||||
let windowTracker = Shell.WindowTracker.get_default();
|
||||
let textureCache = St.TextureCache.get_default();
|
||||
for (let i = 0; i < windows.length; i++) {
|
||||
let icon;
|
||||
let app = windowTracker.get_window_app(windows[i]);
|
||||
if (app)
|
||||
icon = app.create_icon_texture(POPUP_APPICON_SIZE);
|
||||
else
|
||||
icon = textureCache.bind_pixbuf_property(windows[i], 'icon');
|
||||
let icon = null;
|
||||
let iconName = null;
|
||||
if (windows[i].get_window_type () == Meta.WindowType.DESKTOP) {
|
||||
iconName = 'video-display-symbolic';
|
||||
} else {
|
||||
let app = windowTracker.get_window_app(windows[i]);
|
||||
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,
|
||||
proxy: windows[i].get_compositor_private(),
|
||||
focusCallback: Lang.bind(windows[i],
|
||||
@ -109,6 +115,7 @@ const CtrlAltTabManager = new Lang.Class({
|
||||
Main.activateWindow(this, timestamp);
|
||||
}),
|
||||
iconActor: icon,
|
||||
iconName: iconName,
|
||||
sortGroup: SortGroup.MIDDLE });
|
||||
}
|
||||
}
|
||||
|
@ -326,6 +326,16 @@ const DragPlaceholderItem = new Lang.Class({
|
||||
}
|
||||
});
|
||||
|
||||
const EmptyDropTargetItem = new Lang.Class({
|
||||
Name: 'EmptyDropTargetItem',
|
||||
Extends: DashItemContainer,
|
||||
|
||||
_init: function() {
|
||||
this.parent();
|
||||
this.setChild(new St.Bin({ style_class: 'empty-dash-drop-target' }));
|
||||
}
|
||||
});
|
||||
|
||||
const DashActor = new Lang.Class({
|
||||
Name: 'DashActor',
|
||||
Extends: St.Widget,
|
||||
@ -441,6 +451,12 @@ const Dash = new Lang.Class({
|
||||
dragMotion: Lang.bind(this, this._onDragMotion)
|
||||
};
|
||||
DND.addDragMonitor(this._dragMonitor);
|
||||
|
||||
if (this._box.get_n_children() == 0) {
|
||||
this._emptyDropTarget = new EmptyDropTargetItem();
|
||||
this._box.insert_child_at_index(this._emptyDropTarget, 0);
|
||||
this._emptyDropTarget.show(true);
|
||||
}
|
||||
},
|
||||
|
||||
_onDragCancelled: function() {
|
||||
@ -457,6 +473,7 @@ const Dash = new Lang.Class({
|
||||
|
||||
_endDrag: function() {
|
||||
this._clearDragPlaceholder();
|
||||
this._clearEmptyDropTarget();
|
||||
this._showAppsIcon.setDragApp(null);
|
||||
DND.removeDragMonitor(this._dragMonitor);
|
||||
},
|
||||
@ -797,9 +814,21 @@ const Dash = new Lang.Class({
|
||||
|
||||
_clearDragPlaceholder: function() {
|
||||
if (this._dragPlaceholder) {
|
||||
this._animatingPlaceholdersCount++;
|
||||
this._dragPlaceholder.animateOutAndDestroy();
|
||||
this._dragPlaceholder.connect('destroy',
|
||||
Lang.bind(this, function() {
|
||||
this._animatingPlaceholdersCount--;
|
||||
}));
|
||||
this._dragPlaceholder = null;
|
||||
this._dragPlaceholderPos = -1;
|
||||
}
|
||||
this._dragPlaceholderPos = -1;
|
||||
},
|
||||
|
||||
_clearEmptyDropTarget: function() {
|
||||
if (this._emptyDropTarget) {
|
||||
this._emptyDropTarget.animateOutAndDestroy();
|
||||
this._emptyDropTarget = null;
|
||||
}
|
||||
},
|
||||
|
||||
@ -827,23 +856,18 @@ const Dash = new Lang.Class({
|
||||
numChildren--;
|
||||
}
|
||||
|
||||
let pos = Math.floor(y * numChildren / boxHeight);
|
||||
let pos;
|
||||
if (!this._emptyDropTarget)
|
||||
pos = Math.floor(y * numChildren / boxHeight);
|
||||
else
|
||||
pos = 0; // always insert at the top when dash is empty
|
||||
|
||||
if (pos != this._dragPlaceholderPos && pos <= numFavorites && this._animatingPlaceholdersCount == 0) {
|
||||
this._dragPlaceholderPos = pos;
|
||||
|
||||
// Don't allow positioning before or after self
|
||||
if (favPos != -1 && (pos == favPos || pos == favPos + 1)) {
|
||||
if (this._dragPlaceholder) {
|
||||
this._dragPlaceholder.animateOutAndDestroy();
|
||||
this._animatingPlaceholdersCount++;
|
||||
this._dragPlaceholder.connect('destroy',
|
||||
Lang.bind(this, function() {
|
||||
this._animatingPlaceholdersCount--;
|
||||
}));
|
||||
}
|
||||
this._dragPlaceholder = null;
|
||||
|
||||
this._clearDragPlaceholder();
|
||||
return DND.DragMotionResult.CONTINUE;
|
||||
}
|
||||
|
||||
@ -868,9 +892,9 @@ const Dash = new Lang.Class({
|
||||
|
||||
// Remove the drag placeholder if we are not in the
|
||||
// "favorites zone"
|
||||
if (pos > numFavorites && this._dragPlaceholder) {
|
||||
if (pos > numFavorites)
|
||||
this._clearDragPlaceholder();
|
||||
}
|
||||
|
||||
if (!this._dragPlaceholder)
|
||||
return DND.DragMotionResult.NO_DROP;
|
||||
|
||||
|
@ -100,7 +100,6 @@ const DateMenuButton = new Lang.Class({
|
||||
|
||||
Shell.AppSystem.get_default().connect('installed-changed',
|
||||
Lang.bind(this, this._appInstalledChanged));
|
||||
this._appInstalledChanged();
|
||||
|
||||
item = this.menu.addSettingsAction(_("Date & Time Settings"), 'gnome-datetime-panel.desktop');
|
||||
if (item) {
|
||||
@ -157,14 +156,16 @@ const DateMenuButton = new Lang.Class({
|
||||
},
|
||||
|
||||
_appInstalledChanged: function() {
|
||||
let app = Shell.AppSystem.get_default().lookup_app('gnome-clocks.desktop');
|
||||
this._openClocksItem.actor.visible = app !== null;
|
||||
this._calendarApp = undefined;
|
||||
this._updateEventsVisibility();
|
||||
},
|
||||
|
||||
_updateEventsVisibility: function() {
|
||||
let visible = this._eventSource.hasCalendars;
|
||||
this._openCalendarItem.actor.visible = visible;
|
||||
this._openClocksItem.actor.visible = visible;
|
||||
this._openCalendarItem.actor.visible = visible &&
|
||||
(this._getCalendarApp() != null);
|
||||
this._openClocksItem.actor.visible = visible &&
|
||||
(this._getClockApp() != null);
|
||||
this._separator.visible = visible;
|
||||
if (visible) {
|
||||
let alignment = 0.25;
|
||||
@ -217,18 +218,34 @@ const DateMenuButton = new Lang.Class({
|
||||
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() {
|
||||
this.menu.close();
|
||||
|
||||
let app = Gio.AppInfo.get_default_for_type('text/calendar', false);
|
||||
if (app.get_id() == 'evolution')
|
||||
app = Gio.DesktopAppInfo.new('evolution-calendar');
|
||||
let app = this._getCalendarApp();
|
||||
if (app.get_id() == 'evolution.desktop')
|
||||
app = Gio.DesktopAppInfo.new('evolution-calendar.desktop');
|
||||
app.launch([], global.create_app_launch_context());
|
||||
},
|
||||
|
||||
_onOpenClocksActivate: function() {
|
||||
this.menu.close();
|
||||
let app = Shell.AppSystem.get_default().lookup_app('gnome-clocks.desktop');
|
||||
let app = this._getClockApp();
|
||||
app.activate();
|
||||
}
|
||||
});
|
||||
|
@ -149,16 +149,16 @@ const _Draggable = new Lang.Class({
|
||||
|
||||
_grabEvents: function() {
|
||||
if (!this._eventsGrabbed) {
|
||||
Clutter.grab_pointer(_getEventHandlerActor());
|
||||
Clutter.grab_keyboard(_getEventHandlerActor());
|
||||
this._eventsGrabbed = true;
|
||||
this._eventsGrabbed = Main.pushModal(_getEventHandlerActor());
|
||||
if (this._eventsGrabbed)
|
||||
Clutter.grab_pointer(_getEventHandlerActor());
|
||||
}
|
||||
},
|
||||
|
||||
_ungrabEvents: function() {
|
||||
if (this._eventsGrabbed) {
|
||||
Clutter.ungrab_pointer();
|
||||
Clutter.ungrab_keyboard();
|
||||
Main.popModal(_getEventHandlerActor());
|
||||
this._eventsGrabbed = false;
|
||||
}
|
||||
},
|
||||
|
@ -420,6 +420,7 @@ const EndSessionDialog = new Lang.Class({
|
||||
_startTimer: function() {
|
||||
let startTime = GLib.get_monotonic_time();
|
||||
this._secondsLeft = this._totalSecondsToStayOpen;
|
||||
this._updateDescription();
|
||||
|
||||
this._timerId = Mainloop.timeout_add_seconds(1, Lang.bind(this,
|
||||
function() {
|
||||
|
@ -5,6 +5,8 @@ imports.gi.versions.Gio = '2.0';
|
||||
imports.gi.versions.Gdk = '3.0';
|
||||
imports.gi.versions.GdkPixbuf = '2.0';
|
||||
imports.gi.versions.Gtk = '3.0';
|
||||
imports.gi.versions.TelepathyGLib = '0.12';
|
||||
imports.gi.versions.TelepathyLogger = '0.2';
|
||||
|
||||
const Clutter = imports.gi.Clutter;;
|
||||
const Gettext = imports.gettext;
|
||||
|
@ -347,7 +347,7 @@ const LayoutManager = new Lang.Class({
|
||||
BackgroundMenu.addBackgroundMenu(bgManager.background.actor);
|
||||
}));
|
||||
|
||||
this._bgManagers.push(bgManager);
|
||||
this._bgManagers[monitorIndex] = bgManager;
|
||||
|
||||
return bgManager.background;
|
||||
},
|
||||
@ -728,6 +728,8 @@ const LayoutManager = new Lang.Class({
|
||||
// and shown otherwise)
|
||||
addChrome: function(actor, params) {
|
||||
this.uiGroup.add_actor(actor);
|
||||
if (this.uiGroup.contains(global.top_window_group))
|
||||
this.uiGroup.set_child_below_sibling(actor, global.top_window_group);
|
||||
this._trackActor(actor, params);
|
||||
},
|
||||
|
||||
@ -1092,12 +1094,21 @@ const HotCorner = new Lang.Class({
|
||||
}
|
||||
|
||||
if (size > 0) {
|
||||
this._verticalBarrier = new Meta.Barrier({ display: global.display,
|
||||
x1: this._x, x2: this._x, y1: this._y, y2: this._y + size,
|
||||
directions: Meta.BarrierDirection.POSITIVE_X });
|
||||
this._horizontalBarrier = new Meta.Barrier({ display: global.display,
|
||||
x1: this._x, x2: this._x + size, y1: this._y, y2: this._y,
|
||||
directions: Meta.BarrierDirection.POSITIVE_Y });
|
||||
if (Clutter.get_default_text_direction() == Clutter.TextDirection.RTL) {
|
||||
this._verticalBarrier = new Meta.Barrier({ display: global.display,
|
||||
x1: this._x, x2: this._x, y1: this._y, y2: this._y + size,
|
||||
directions: Meta.BarrierDirection.NEGATIVE_X });
|
||||
this._horizontalBarrier = new Meta.Barrier({ display: global.display,
|
||||
x1: this._x - size, x2: this._x, y1: this._y, y2: this._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._horizontalBarrier);
|
||||
|
@ -38,7 +38,6 @@ const Magnifier = imports.ui.magnifier;
|
||||
const XdndHandler = imports.ui.xdndHandler;
|
||||
const Util = imports.misc.util;
|
||||
|
||||
const OVERRIDES_SCHEMA = 'org.gnome.shell.overrides';
|
||||
const DEFAULT_BACKGROUND_COLOR = Clutter.Color.from_pixel(0x2e3436ff);
|
||||
|
||||
let componentManager = null;
|
||||
@ -68,7 +67,7 @@ let layoutManager = null;
|
||||
let _startDate;
|
||||
let _defaultCssStylesheet = null;
|
||||
let _cssStylesheet = null;
|
||||
let _overridesSettings = null;
|
||||
let _workspacesSettings = null;
|
||||
|
||||
function _sessionUpdated() {
|
||||
_loadDefaultStylesheet();
|
||||
@ -106,6 +105,7 @@ function start() {
|
||||
|
||||
function _sessionsLoaded() {
|
||||
sessionMode.connect('updated', _sessionUpdated);
|
||||
_initializePrefs();
|
||||
_initializeUI();
|
||||
|
||||
shellDBusService = new ShellDBus.GnomeShell();
|
||||
@ -114,6 +114,21 @@ function _sessionsLoaded() {
|
||||
_sessionUpdated();
|
||||
}
|
||||
|
||||
function _initializePrefs() {
|
||||
let keys = new Gio.Settings({ schema: sessionMode.overridesSchema }).list_keys();
|
||||
for (let i = 0; i < keys.length; i++)
|
||||
Meta.prefs_override_preference_schema (keys[i], sessionMode.overridesSchema);
|
||||
|
||||
let workspacesSchema;
|
||||
if (keys.indexOf('dynamic-workspaces') > -1)
|
||||
workspacesSchema = sessionMode.overridesSchema;
|
||||
else
|
||||
workspacesSchema = 'org.gnome.mutter';
|
||||
|
||||
_workspacesSettings = new Gio.Settings({ schema: workspacesSchema });
|
||||
_workspacesSettings.connect('changed::dynamic-workspaces', _queueCheckWorkspaces);
|
||||
}
|
||||
|
||||
function _initializeUI() {
|
||||
// Ensure ShellWindowTracker and ShellAppUsage are initialized; this will
|
||||
// also initialize ShellAppSystem first. ShellAppSystem
|
||||
@ -179,9 +194,6 @@ function _initializeUI() {
|
||||
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);
|
||||
|
@ -1530,11 +1530,7 @@ const MessageTrayContextMenu = new Lang.Class({
|
||||
},
|
||||
|
||||
_updateClearSensitivity: function() {
|
||||
let sources = this._tray.getSources();
|
||||
sources = sources.filter(function(source) {
|
||||
return !source.trayIcon && !source.isChat && !source.resident;
|
||||
});
|
||||
this._clearItem.setSensitive(sources.length > 0);
|
||||
this._clearItem.setSensitive(this._tray.clearableCount > 0);
|
||||
},
|
||||
|
||||
setPosition: function(x, y) {
|
||||
@ -1661,6 +1657,8 @@ const MessageTray = new Lang.Class({
|
||||
this._desktopClone = null;
|
||||
this._inCtrlAltTab = false;
|
||||
|
||||
this.clearableCount = 0;
|
||||
|
||||
this._lightbox = new Lightbox.Lightbox(global.overlay_group,
|
||||
{ inhibitEvents: true,
|
||||
fadeInTime: ANIMATION_TIME,
|
||||
@ -1899,6 +1897,9 @@ const MessageTray = new Lang.Class({
|
||||
this._summary.insert_child_at_index(summaryItem.actor, this._chatSummaryItemsCount);
|
||||
}
|
||||
|
||||
if (!source.trayIcon && !source.isChat && !source.resident)
|
||||
this.clearableCount++;
|
||||
|
||||
this._sources.set(source, obj);
|
||||
|
||||
obj.notifyId = source.connect('notify', Lang.bind(this, this._onNotify));
|
||||
@ -1940,6 +1941,9 @@ const MessageTray = new Lang.Class({
|
||||
if (source.isChat)
|
||||
this._chatSummaryItemsCount--;
|
||||
|
||||
if (!source.trayIcon && !source.isChat && !source.resident)
|
||||
this.clearableCount--;
|
||||
|
||||
source.disconnect(obj.notifyId);
|
||||
source.disconnect(obj.destroyId);
|
||||
source.disconnect(obj.mutedChangedId);
|
||||
@ -2245,10 +2249,15 @@ const MessageTray = new Lang.Class({
|
||||
let canShowSummaryBoxPointer = this._trayState == State.SHOWN;
|
||||
// We only have sources with empty notification stacks for legacy tray icons. Currently, we never attempt
|
||||
// to show notifications for legacy tray icons, but this would be necessary if we did.
|
||||
let requestedNotificationStackIsEmpty = (this._clickedSummaryItemMouseButton == 1 && this._clickedSummaryItem.source.notifications.length == 0);
|
||||
let wrongSummaryNotificationStack = (this._clickedSummaryItemMouseButton == 1 &&
|
||||
let requestedNotificationStackIsEmpty = (haveClickedSummaryItem &&
|
||||
this._clickedSummaryItemMouseButton == 1 &&
|
||||
this._clickedSummaryItem.source.notifications.length == 0);
|
||||
let wrongSummaryNotificationStack = (haveClickedSummaryItem &&
|
||||
this._clickedSummaryItemMouseButton == 1 &&
|
||||
this._summaryBoxPointer.bin.child != this._clickedSummaryItem.notificationStackWidget);
|
||||
let wrongSummaryRightClickMenu = (this._clickedSummaryItemMouseButton == 3 &&
|
||||
let wrongSummaryRightClickMenu = (haveClickedSummaryItem &&
|
||||
this._clickedSummaryItemMouseButton == 3 &&
|
||||
this._clickedSummaryItem.rightClickMenu != null &&
|
||||
this._summaryBoxPointer.bin.child != this._clickedSummaryItem.rightClickMenu);
|
||||
let wrongSummaryBoxPointer = (haveClickedSummaryItem &&
|
||||
(wrongSummaryNotificationStack || wrongSummaryRightClickMenu));
|
||||
@ -2595,16 +2604,16 @@ const MessageTray = new Lang.Class({
|
||||
},
|
||||
|
||||
_expandNotification: function(autoExpanding) {
|
||||
// Don't focus notifications that are auto-expanding.
|
||||
if (!autoExpanding)
|
||||
this._ensureNotificationFocused();
|
||||
|
||||
if (!this._notificationExpandedId)
|
||||
this._notificationExpandedId =
|
||||
this._notification.connect('expanded',
|
||||
Lang.bind(this, this._onNotificationExpanded));
|
||||
// Don't animate changes in notifications that are auto-expanding.
|
||||
this._notification.expand(!autoExpanding);
|
||||
|
||||
// Don't focus notifications that are auto-expanding.
|
||||
if (!autoExpanding)
|
||||
this._ensureNotificationFocused();
|
||||
},
|
||||
|
||||
_onNotificationExpanded: function() {
|
||||
|
@ -22,6 +22,10 @@ const Tweener = imports.ui.tweener;
|
||||
const OPEN_AND_CLOSE_TIME = 0.1;
|
||||
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 = {
|
||||
OPENED: 0,
|
||||
CLOSED: 1,
|
||||
@ -65,7 +69,9 @@ const ModalDialog = new Lang.Class({
|
||||
this._group.connect('key-press-event', Lang.bind(this, this._onKeyPressEvent));
|
||||
this._group.connect('key-release-event', Lang.bind(this, this._onKeyReleaseEvent));
|
||||
|
||||
this._backgroundBin = new St.Bin();
|
||||
this.backgroundStack = new St.Widget({ layout_manager: new Clutter.BinLayout() });
|
||||
this._backgroundBin = new St.Bin({ child: this.backgroundStack,
|
||||
x_fill: true, y_fill: true });
|
||||
this._monitorConstraint = new Layout.MonitorConstraint();
|
||||
this._backgroundBin.add_constraint(this._monitorConstraint);
|
||||
this._group.add_actor(this._backgroundBin);
|
||||
@ -81,15 +87,10 @@ const ModalDialog = new Lang.Class({
|
||||
{ inhibitEvents: true });
|
||||
this._lightbox.highlight(this._backgroundBin);
|
||||
|
||||
let stack = new Shell.Stack();
|
||||
this._backgroundBin.child = stack;
|
||||
|
||||
this._eventBlocker = new Clutter.Actor({ reactive: true });
|
||||
stack.add_actor(this._eventBlocker);
|
||||
stack.add_actor(this.dialogLayout);
|
||||
} else {
|
||||
this._backgroundBin.child = this.dialogLayout;
|
||||
this.backgroundStack.add_actor(this._eventBlocker);
|
||||
}
|
||||
this.backgroundStack.add_actor(this.dialogLayout);
|
||||
|
||||
|
||||
this.contentLayout = new St.BoxLayout({ vertical: true });
|
||||
@ -110,6 +111,8 @@ const ModalDialog = new Lang.Class({
|
||||
this._initialKeyFocus = this.dialogLayout;
|
||||
this._initialKeyFocusDestroyId = 0;
|
||||
this._savedKeyFocus = null;
|
||||
|
||||
this._workSpinner = null;
|
||||
},
|
||||
|
||||
destroy: function() {
|
||||
@ -183,6 +186,44 @@ const ModalDialog = new Lang.Class({
|
||||
return button;
|
||||
},
|
||||
|
||||
placeSpinner: function(layoutInfo) {
|
||||
/* This is here because of recursive imports */
|
||||
const Panel = imports.ui.panel;
|
||||
let spinnerIcon = global.datadir + '/theme/process-working.svg';
|
||||
this._workSpinner = new Panel.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) {
|
||||
this._pressedKey = event.get_key_symbol();
|
||||
},
|
||||
|
@ -8,6 +8,7 @@ const Layout = imports.ui.layout;
|
||||
const Main = imports.ui.main;
|
||||
const Mainloop = imports.mainloop;
|
||||
const Tweener = imports.ui.tweener;
|
||||
const Meta = imports.gi.Meta;
|
||||
|
||||
const HIDE_TIMEOUT = 1500;
|
||||
const FADE_TIME = 0.1;
|
||||
@ -71,6 +72,7 @@ const OsdWindow = new Lang.Class({
|
||||
Name: 'OsdWindow',
|
||||
|
||||
_init: function() {
|
||||
this._popupSize = 0;
|
||||
this.actor = new St.Widget({ x_expand: true,
|
||||
y_expand: true,
|
||||
x_align: Clutter.ActorAlign.CENTER,
|
||||
@ -80,6 +82,15 @@ const OsdWindow = new Lang.Class({
|
||||
vertical: true });
|
||||
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._box.add(this._icon, { expand: true });
|
||||
|
||||
@ -125,8 +136,10 @@ const OsdWindow = new Lang.Class({
|
||||
return;
|
||||
|
||||
if (!this.actor.visible) {
|
||||
Meta.disable_unredirect_for_screen(global.screen);
|
||||
this.actor.show();
|
||||
this.actor.opacity = 0;
|
||||
this.actor.get_parent().set_child_above_sibling(this.actor, null);
|
||||
|
||||
Tweener.addTween(this.actor,
|
||||
{ opacity: 255,
|
||||
@ -154,7 +167,11 @@ const OsdWindow = new Lang.Class({
|
||||
{ opacity: 0,
|
||||
time: FADE_TIME,
|
||||
transition: 'easeOutQuad',
|
||||
onComplete: Lang.bind(this, this._reset) });
|
||||
onComplete: Lang.bind(this, function() {
|
||||
this._reset();
|
||||
Meta.enable_unredirect_for_screen(global.screen);
|
||||
})
|
||||
});
|
||||
},
|
||||
|
||||
_reset: function() {
|
||||
@ -169,11 +186,25 @@ const OsdWindow = new Lang.Class({
|
||||
let scalew = monitor.width / 640.0;
|
||||
let scaleh = monitor.height / 480.0;
|
||||
let scale = Math.min(scalew, scaleh);
|
||||
let size = 110 * Math.max(1, scale);
|
||||
this._popupSize = 110 * Math.max(1, scale);
|
||||
|
||||
this._box.set_size(size, size);
|
||||
this._box.translation_y = monitor.height / 4;
|
||||
this._icon.icon_size = this._popupSize / 2;
|
||||
this._box.style_changed();
|
||||
},
|
||||
|
||||
this._icon.icon_size = size / 2;
|
||||
_onStyleChanged: function() {
|
||||
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));
|
||||
}
|
||||
});
|
||||
|
@ -31,7 +31,7 @@ const ANIMATION_TIME = 0.25;
|
||||
// and don't want the shading animation to get cut off
|
||||
const SHADE_ANIMATION_TIME = .20;
|
||||
|
||||
const DND_WINDOW_SWITCH_TIMEOUT = 1250;
|
||||
const DND_WINDOW_SWITCH_TIMEOUT = 750;
|
||||
|
||||
const OVERVIEW_ACTIVATION_TIMEOUT = 0.5;
|
||||
|
||||
@ -461,6 +461,7 @@ const Overview = new Lang.Class({
|
||||
|
||||
beginItemDrag: function(source) {
|
||||
this.emit('item-drag-begin');
|
||||
this._inDrag = true;
|
||||
},
|
||||
|
||||
cancelledItemDrag: function(source) {
|
||||
@ -469,10 +470,12 @@ const Overview = new Lang.Class({
|
||||
|
||||
endItemDrag: function(source) {
|
||||
this.emit('item-drag-end');
|
||||
this._inDrag = false;
|
||||
},
|
||||
|
||||
beginWindowDrag: function(source) {
|
||||
this.emit('window-drag-begin');
|
||||
this._inDrag = true;
|
||||
},
|
||||
|
||||
cancelledWindowDrag: function(source) {
|
||||
@ -481,6 +484,7 @@ const Overview = new Lang.Class({
|
||||
|
||||
endWindowDrag: function(source) {
|
||||
this.emit('window-drag-end');
|
||||
this._inDrag = false;
|
||||
},
|
||||
|
||||
// show:
|
||||
@ -499,6 +503,11 @@ const Overview = new Lang.Class({
|
||||
this._animateVisible();
|
||||
},
|
||||
|
||||
focusSearch: function() {
|
||||
this.show();
|
||||
this._searchEntry.grab_key_focus();
|
||||
},
|
||||
|
||||
fadeInDesktop: function() {
|
||||
this._desktopFade.opacity = 0;
|
||||
this._desktopFade.show();
|
||||
@ -604,6 +613,8 @@ const Overview = new Lang.Class({
|
||||
shouldToggleByCornerOrButton: function() {
|
||||
if (this.animationInProgress)
|
||||
return false;
|
||||
if (this._inDrag)
|
||||
return false;
|
||||
if (this._activationTime == 0 || Date.now() / 1000 - this._activationTime > OVERVIEW_ACTIVATION_TIMEOUT)
|
||||
return true;
|
||||
return false;
|
||||
|
@ -289,10 +289,10 @@ const AppMenuButton = new Lang.Class({
|
||||
this._visible = !Main.overview.visible;
|
||||
if (!this._visible)
|
||||
this.actor.hide();
|
||||
Main.overview.connect('hiding', Lang.bind(this, function () {
|
||||
this._overviewHidingId = Main.overview.connect('hiding', Lang.bind(this, function () {
|
||||
this.show();
|
||||
}));
|
||||
Main.overview.connect('showing', Lang.bind(this, function () {
|
||||
this._overviewShowingId = Main.overview.connect('showing', Lang.bind(this, function () {
|
||||
this.hide();
|
||||
}));
|
||||
|
||||
@ -302,10 +302,12 @@ const AppMenuButton = new Lang.Class({
|
||||
|
||||
let tracker = Shell.WindowTracker.get_default();
|
||||
let appSys = Shell.AppSystem.get_default();
|
||||
tracker.connect('notify::focus-app', Lang.bind(this, this._focusAppChanged));
|
||||
appSys.connect('app-state-changed', Lang.bind(this, this._onAppStateChanged));
|
||||
|
||||
global.window_manager.connect('switch-workspace', Lang.bind(this, this._sync));
|
||||
this._focusAppNotifyId =
|
||||
tracker.connect('notify::focus-app', Lang.bind(this, this._focusAppChanged));
|
||||
this._appStateChangedSignalId =
|
||||
appSys.connect('app-state-changed', Lang.bind(this, this._onAppStateChanged));
|
||||
this._switchWorkspaceNotifyId =
|
||||
global.window_manager.connect('switch-workspace', Lang.bind(this, this._sync));
|
||||
|
||||
this._sync();
|
||||
},
|
||||
@ -369,13 +371,16 @@ const AppMenuButton = new Lang.Class({
|
||||
this._updateIconBoxClip();
|
||||
},
|
||||
|
||||
_syncIcon: function() {
|
||||
let icon = this._targetApp.get_faded_icon(2 * PANEL_ICON_SIZE, this._iconBox.text_direction);
|
||||
this._iconBox.set_child(icon);
|
||||
},
|
||||
|
||||
_onIconThemeChanged: function() {
|
||||
if (this._iconBox.child == null)
|
||||
return;
|
||||
|
||||
this._iconBox.child.destroy();
|
||||
let icon = this._targetApp.get_faded_icon(2 * PANEL_ICON_SIZE);
|
||||
this._iconBox.set_child(icon);
|
||||
this._syncIcon();
|
||||
},
|
||||
|
||||
_updateIconBoxClip: function() {
|
||||
@ -593,12 +598,10 @@ const AppMenuButton = new Lang.Class({
|
||||
}
|
||||
|
||||
this._targetApp = targetApp;
|
||||
let icon = targetApp.get_faded_icon(2 * PANEL_ICON_SIZE);
|
||||
|
||||
this._label.setText(targetApp.get_name());
|
||||
this.setName(targetApp.get_name());
|
||||
|
||||
this._iconBox.set_child(icon);
|
||||
this._syncIcon();
|
||||
this._iconBox.show();
|
||||
|
||||
if (targetApp.get_state() == Shell.AppState.STARTING)
|
||||
@ -637,6 +640,33 @@ const AppMenuButton = new Lang.Class({
|
||||
|
||||
this.setMenu(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();
|
||||
}
|
||||
});
|
||||
|
||||
@ -894,7 +924,6 @@ const PANEL_ITEM_IMPLEMENTATIONS = {
|
||||
'volume': imports.ui.status.volume.Indicator,
|
||||
'battery': imports.ui.status.power.Indicator,
|
||||
'lockScreen': imports.ui.status.lockScreenMenu.Indicator,
|
||||
'logo': imports.gdm.loginDialog.LogoMenuButton,
|
||||
'keyboard': imports.ui.status.keyboard.InputSourceIndicator,
|
||||
'powerMenu': imports.gdm.powerMenu.PowerMenuButton,
|
||||
'userMenu': imports.ui.userMenu.UserMenuButton
|
||||
@ -923,7 +952,7 @@ const Panel = new Lang.Class({
|
||||
|
||||
this.statusArea = {};
|
||||
|
||||
this.menuManager = new PopupMenu.PopupMenuManager(this);
|
||||
this.menuManager = new PopupMenu.PopupMenuManager(this, { keybindingMode: Shell.KeyBindingMode.TOPBAR_POPUP });
|
||||
|
||||
this._leftBox = new St.BoxLayout({ name: 'panelLeft' });
|
||||
this.actor.add_actor(this._leftBox);
|
||||
@ -1077,17 +1106,18 @@ const Panel = new Lang.Class({
|
||||
return true;
|
||||
},
|
||||
|
||||
openAppMenu: function() {
|
||||
toggleAppMenu: function() {
|
||||
let indicator = this.statusArea.appMenu;
|
||||
if (!indicator) // appMenu not supported by current session mode
|
||||
return;
|
||||
|
||||
let menu = indicator.menu;
|
||||
if (!indicator.actor.reactive || menu.isOpen)
|
||||
if (!indicator.actor.reactive)
|
||||
return;
|
||||
|
||||
menu.open();
|
||||
menu.actor.navigate_focus(null, Gtk.DirectionType.TAB_FORWARD, false);
|
||||
menu.toggle();
|
||||
if (menu.isOpen)
|
||||
menu.actor.navigate_focus(null, Gtk.DirectionType.TAB_FORWARD, false);
|
||||
},
|
||||
|
||||
set boxOpacity(value) {
|
||||
|
@ -553,6 +553,10 @@ const PopupSliderMenuItem = new Lang.Class({
|
||||
|
||||
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 sliderHeight = themeNode.get_length('-slider-height');
|
||||
|
||||
@ -604,7 +608,16 @@ const PopupSliderMenuItem = new Lang.Class({
|
||||
color.blue / 255,
|
||||
color.alpha / 255);
|
||||
cr.arc(handleX, handleY, handleRadius, 0, 2 * Math.PI);
|
||||
cr.fill();
|
||||
cr.fillPreserve();
|
||||
if (hasHandleColor && handleBorderWidth) {
|
||||
cr.setSourceRGBA(
|
||||
handleBorderColor.red / 255,
|
||||
handleBorderColor.green / 255,
|
||||
handleBorderColor.blue / 255,
|
||||
handleBorderColor.alpha / 255);
|
||||
cr.setLineWidth(handleBorderWidth);
|
||||
cr.stroke();
|
||||
}
|
||||
cr.$dispose();
|
||||
},
|
||||
|
||||
@ -1813,6 +1826,8 @@ const RemoteMenu = new Lang.Class({
|
||||
|
||||
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));
|
||||
|
||||
this._skipSignalConnection = false;
|
||||
},
|
||||
|
||||
destroy: function() {
|
||||
@ -1860,7 +1875,7 @@ const RemoteMenu = new Lang.Class({
|
||||
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'];
|
||||
return [null, false, 'action-added::' + action_id];
|
||||
}
|
||||
|
||||
if (!this._actions[action_id])
|
||||
@ -1897,7 +1912,7 @@ const RemoteMenu = new Lang.Class({
|
||||
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'];
|
||||
return [null, false, 'action-state-changed::' + action_id];
|
||||
}
|
||||
} else {
|
||||
target = model.get_item_attribute_value(index, Gio.MENU_ATTRIBUTE_TARGET, null);
|
||||
@ -1973,13 +1988,16 @@ const RemoteMenu = new Lang.Class({
|
||||
target.addMenuItem(separator, k+1);
|
||||
k++;
|
||||
}
|
||||
} else if (changeSignal) {
|
||||
} else if (changeSignal && !this._skipSignalConnection) {
|
||||
let signalId = this.actionGroup.connect(changeSignal, Lang.bind(this, function(actionGroup, actionName) {
|
||||
actionGroup.disconnect(signalId);
|
||||
if (this._actions[actionName]) return;
|
||||
|
||||
// force a full update
|
||||
/* force a full update but do not reconnect signals if other
|
||||
* actions are missing */
|
||||
this._skipSignalConnection = true;
|
||||
this._modelChanged(model, 0, -1, model.get_n_items(), target);
|
||||
this._skipSignalConnection = false;
|
||||
}));
|
||||
}
|
||||
}
|
||||
@ -2052,9 +2070,9 @@ const RemoteMenu = new Lang.Class({
|
||||
const PopupMenuManager = new Lang.Class({
|
||||
Name: 'PopupMenuManager',
|
||||
|
||||
_init: function(owner) {
|
||||
_init: function(owner, grabParams) {
|
||||
this._owner = owner;
|
||||
this._grabHelper = new GrabHelper.GrabHelper(owner.actor);
|
||||
this._grabHelper = new GrabHelper.GrabHelper(owner.actor, grabParams);
|
||||
this._menus = [];
|
||||
},
|
||||
|
||||
@ -2088,7 +2106,7 @@ const PopupMenuManager = new Lang.Class({
|
||||
|
||||
removeMenu: function(menu) {
|
||||
if (menu == this.activeMenu)
|
||||
this._closeMenu(menu);
|
||||
this._closeMenu(false, menu);
|
||||
|
||||
let position = this._findMenu(menu);
|
||||
if (position == -1) // not a menu we manage
|
||||
@ -2124,6 +2142,8 @@ const PopupMenuManager = new Lang.Class({
|
||||
|
||||
_onMenuOpenState: function(menu, 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,
|
||||
onUngrab: Lang.bind(this, this._closeMenu, menu) });
|
||||
} else {
|
||||
@ -2140,13 +2160,8 @@ const PopupMenuManager = new Lang.Class({
|
||||
},
|
||||
|
||||
_changeMenu: function(newMenu) {
|
||||
let oldMenu = this.activeMenu;
|
||||
if (oldMenu) {
|
||||
oldMenu.close(BoxPointer.PopupAnimation.FADE);
|
||||
newMenu.open(BoxPointer.PopupAnimation.FADE);
|
||||
} else {
|
||||
newMenu.open(BoxPointer.PopupAnimation.FULL);
|
||||
}
|
||||
newMenu.open(this.activeMenu ? BoxPointer.PopupAnimation.FADE
|
||||
: BoxPointer.PopupAnimation.FULL);
|
||||
},
|
||||
|
||||
_onMenuSourceEnter: function(menu) {
|
||||
|
@ -478,6 +478,7 @@ const ScreenShield = new Lang.Class({
|
||||
|
||||
this._lockDialogGroup = new St.Widget({ x_expand: true,
|
||||
y_expand: true,
|
||||
reactive: true,
|
||||
opacity: 0,
|
||||
pivot_point: new Clutter.Point({ x: 0.5, y: 0.5 }),
|
||||
name: 'lockDialogGroup' });
|
||||
@ -709,6 +710,8 @@ const ScreenShield = new Lang.Class({
|
||||
},
|
||||
|
||||
_onDragEnd: function(action, actor, eventX, eventY, modifiers) {
|
||||
if (this._lockScreenState != MessageTray.State.HIDING)
|
||||
return;
|
||||
if (this._lockScreenGroup.y < -(ARROW_DRAG_THRESHOLD * global.stage.height)) {
|
||||
// Complete motion automatically
|
||||
let [velocity, velocityX, velocityY] = this._dragAction.get_velocity(0);
|
||||
@ -1115,6 +1118,9 @@ const ScreenShield = new Lang.Class({
|
||||
deactivate: function(animate) {
|
||||
this._hideLockScreen(animate, 0);
|
||||
|
||||
if (this._hasLockScreen)
|
||||
this._clearLockScreen();
|
||||
|
||||
if (Main.sessionMode.currentMode == 'lock-screen')
|
||||
Main.sessionMode.popMode('lock-screen');
|
||||
if (Main.sessionMode.currentMode == 'unlock-dialog')
|
||||
@ -1131,9 +1137,6 @@ const ScreenShield = new Lang.Class({
|
||||
},
|
||||
|
||||
_completeDeactivate: function() {
|
||||
if (this._hasLockScreen)
|
||||
this._clearLockScreen();
|
||||
|
||||
if (this._dialog && !this._isGreeter) {
|
||||
this._dialog.destroy();
|
||||
this._dialog = null;
|
||||
@ -1200,6 +1203,12 @@ const ScreenShield = new Lang.Class({
|
||||
return;
|
||||
}
|
||||
|
||||
// Clear the clipboard - otherwise, its contents may be leaked
|
||||
// to unauthorized parties by pasting into the unlock dialog's
|
||||
// password entry and unmasking the entry
|
||||
St.Clipboard.get_default().set_text(St.ClipboardType.CLIPBOARD, '');
|
||||
St.Clipboard.get_default().set_text(St.ClipboardType.PRIMARY, '');
|
||||
|
||||
this._isLocked = true;
|
||||
this.activate(animate);
|
||||
|
||||
|
140
js/ui/screencast.js
Normal file
140
js/ui/screencast.js
Normal file
@ -0,0 +1,140 @@
|
||||
// -*- 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]));
|
||||
}
|
||||
});
|
@ -16,6 +16,7 @@ const _modes = {
|
||||
'restrictive': {
|
||||
parentMode: null,
|
||||
stylesheetName: 'gnome-shell.css',
|
||||
overridesSchema: 'org.gnome.shell.overrides',
|
||||
hasOverview: false,
|
||||
showCalendarEvents: false,
|
||||
allowSettings: false,
|
||||
@ -45,7 +46,7 @@ const _modes = {
|
||||
unlockDialog: imports.gdm.loginDialog.LoginDialog,
|
||||
components: ['polkitAgent'],
|
||||
panel: {
|
||||
left: ['logo'],
|
||||
left: [],
|
||||
center: ['dateMenu'],
|
||||
right: ['a11yGreeter', 'display', 'keyboard',
|
||||
'volume', 'battery', 'powerMenu']
|
||||
@ -195,6 +196,10 @@ const SessionMode = new Lang.Class({
|
||||
return this._modeStack[this._modeStack.length - 1];
|
||||
},
|
||||
|
||||
get allowScreencast() {
|
||||
return this.components.indexOf('recorder') != -1;
|
||||
},
|
||||
|
||||
_sync: function() {
|
||||
let params = this._modes[this.currentMode];
|
||||
let defaults;
|
||||
|
@ -12,6 +12,7 @@ const ExtensionDownloader = imports.ui.extensionDownloader;
|
||||
const ExtensionUtils = imports.misc.extensionUtils;
|
||||
const Hash = imports.misc.hash;
|
||||
const Main = imports.ui.main;
|
||||
const Screencast = imports.ui.screencast;
|
||||
const Screenshot = imports.ui.screenshot;
|
||||
|
||||
const GnomeShellIface = <interface name="org.gnome.Shell">
|
||||
@ -20,6 +21,7 @@ const GnomeShellIface = <interface name="org.gnome.Shell">
|
||||
<arg type="b" direction="out" name="success" />
|
||||
<arg type="s" direction="out" name="result" />
|
||||
</method>
|
||||
<method name="FocusSearch"/>
|
||||
<method name="ShowOSD">
|
||||
<arg type="a{sv}" direction="in" name="params"/>
|
||||
</method>
|
||||
@ -70,6 +72,7 @@ const GnomeShell = new Lang.Class({
|
||||
this._dbusImpl.export(Gio.DBus.session, '/org/gnome/Shell');
|
||||
|
||||
this._extensionsService = new GnomeShellExtensions();
|
||||
this._screencastService = new Screencast.ScreencastService();
|
||||
this._screenshotService = new Screenshot.ScreenshotService();
|
||||
|
||||
this._grabbedAccelerators = new Hash.Map();
|
||||
@ -97,7 +100,7 @@ const GnomeShell = new Lang.Class({
|
||||
*/
|
||||
Eval: function(code) {
|
||||
if (!global.settings.get_boolean('development-tools'))
|
||||
return [false, null];
|
||||
return [false, ''];
|
||||
|
||||
let returnValue;
|
||||
let success;
|
||||
@ -114,6 +117,10 @@ const GnomeShell = new Lang.Class({
|
||||
return [success, returnValue];
|
||||
},
|
||||
|
||||
FocusSearch: function() {
|
||||
Main.overview.focusSearch();
|
||||
},
|
||||
|
||||
ShowOSD: function(params) {
|
||||
for (let param in params)
|
||||
params[param] = params[param].deep_unpack();
|
||||
|
@ -14,9 +14,7 @@ const EntryMenu = new Lang.Class({
|
||||
Name: 'ShellEntryMenu',
|
||||
Extends: PopupMenu.PopupMenu,
|
||||
|
||||
_init: function(entry, params) {
|
||||
params = Params.parse (params, { isPassword: false });
|
||||
|
||||
_init: function(entry) {
|
||||
this.parent(entry, 0, St.Side.TOP);
|
||||
|
||||
this.actor.add_style_class_name('entry-context-menu');
|
||||
@ -37,8 +35,6 @@ const EntryMenu = new Lang.Class({
|
||||
this._pasteItem = item;
|
||||
|
||||
this._passwordItem = null;
|
||||
if (params.isPassword)
|
||||
this._makePasswordItem();
|
||||
|
||||
Main.uiGroup.add_actor(this.actor);
|
||||
this.actor.hide();
|
||||
@ -53,19 +49,21 @@ const EntryMenu = new Lang.Class({
|
||||
},
|
||||
|
||||
get isPassword() {
|
||||
return this._passwordItem != null;
|
||||
return this._passwordItem != null;
|
||||
},
|
||||
|
||||
set isPassword(v) {
|
||||
if (v == this.isPassword)
|
||||
return;
|
||||
if (v == this.isPassword)
|
||||
return;
|
||||
|
||||
if (v)
|
||||
this._makePasswordItem();
|
||||
else {
|
||||
this._passwordItem.destroy();
|
||||
this._passwordItem = null;
|
||||
}
|
||||
if (v) {
|
||||
this._makePasswordItem();
|
||||
this._entry.input_purpose = Gtk.InputPurpose.PASSWORD;
|
||||
} else {
|
||||
this._passwordItem.destroy();
|
||||
this._passwordItem = null;
|
||||
this._entry.input_purpose = Gtk.InputPurpose.FREE_FORM;
|
||||
}
|
||||
},
|
||||
|
||||
open: function(animate) {
|
||||
@ -155,7 +153,10 @@ function addContextMenu(entry, params) {
|
||||
if (entry.menu)
|
||||
return;
|
||||
|
||||
entry.menu = new EntryMenu(entry, params);
|
||||
params = Params.parse (params, { isPassword: false });
|
||||
|
||||
entry.menu = new EntryMenu(entry);
|
||||
entry.menu.isPassword = params.isPassword;
|
||||
entry._menuManager = new PopupMenu.PopupMenuManager({ actor: entry });
|
||||
entry._menuManager.addMenu(entry.menu);
|
||||
|
||||
|
@ -33,6 +33,33 @@ const KEY_INPUT_SOURCES = 'sources';
|
||||
const INPUT_SOURCE_TYPE_XKB = 'xkb';
|
||||
const INPUT_SOURCE_TYPE_IBUS = 'ibus';
|
||||
|
||||
// This is the longest we'll keep the keyboard frozen until an input
|
||||
// source is active.
|
||||
const MAX_INPUT_SOURCE_ACTIVATION_TIME = 4000; // ms
|
||||
|
||||
const BUS_NAME = 'org.gnome.SettingsDaemon.Keyboard';
|
||||
const OBJECT_PATH = '/org/gnome/SettingsDaemon/Keyboard';
|
||||
|
||||
const KeyboardManagerInterface =
|
||||
<interface name="org.gnome.SettingsDaemon.Keyboard">
|
||||
<method name="SetInputSource">
|
||||
<arg type="u" direction="in" />
|
||||
</method>
|
||||
</interface>;
|
||||
|
||||
const KeyboardManagerProxy = Gio.DBusProxy.makeProxyWrapper(KeyboardManagerInterface);
|
||||
|
||||
function releaseKeyboard() {
|
||||
if (Main.modalCount > 0)
|
||||
global.display.unfreeze_keyboard(global.get_current_time());
|
||||
else
|
||||
global.display.ungrab_keyboard(global.get_current_time());
|
||||
}
|
||||
|
||||
function holdKeyboard() {
|
||||
global.freeze_keyboard(global.get_current_time());
|
||||
}
|
||||
|
||||
const IBusManager = new Lang.Class({
|
||||
Name: 'IBusManager',
|
||||
|
||||
@ -45,26 +72,24 @@ const IBusManager = new Lang.Class({
|
||||
this._readyCallback = readyCallback;
|
||||
this._candidatePopup = new IBusCandidatePopup.CandidatePopup();
|
||||
|
||||
this._ibus = null;
|
||||
this._panelService = null;
|
||||
this._engines = {};
|
||||
this._ready = false;
|
||||
this._registerPropertiesId = 0;
|
||||
this._currentEngineName = null;
|
||||
|
||||
this._nameWatcherId = Gio.DBus.session.watch_name(IBus.SERVICE_IBUS,
|
||||
Gio.BusNameWatcherFlags.NONE,
|
||||
Lang.bind(this, this._onNameAppeared),
|
||||
Lang.bind(this, this._clear));
|
||||
this._ibus = IBus.Bus.new_async();
|
||||
this._ibus.connect('connected', Lang.bind(this, this._onConnected));
|
||||
this._ibus.connect('disconnected', Lang.bind(this, this._clear));
|
||||
// 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));
|
||||
},
|
||||
|
||||
_clear: function() {
|
||||
if (this._panelService)
|
||||
this._panelService.destroy();
|
||||
if (this._ibus)
|
||||
this._ibus.destroy();
|
||||
|
||||
this._ibus = null;
|
||||
this._panelService = null;
|
||||
this._candidatePopup.setPanelService(null);
|
||||
this._engines = {};
|
||||
@ -76,18 +101,12 @@ const IBusManager = new Lang.Class({
|
||||
this._readyCallback(false);
|
||||
},
|
||||
|
||||
_onNameAppeared: function() {
|
||||
this._ibus = IBus.Bus.new_async();
|
||||
this._ibus.connect('connected', Lang.bind(this, this._onConnected));
|
||||
},
|
||||
|
||||
_onConnected: function() {
|
||||
this._ibus.list_engines_async(-1, null, Lang.bind(this, this._initEngines));
|
||||
this._ibus.request_name_async(IBus.SERVICE_PANEL,
|
||||
IBus.BusNameFlag.REPLACE_EXISTING,
|
||||
-1, null,
|
||||
Lang.bind(this, this._initPanelService));
|
||||
this._ibus.connect('disconnected', Lang.bind(this, this._clear));
|
||||
},
|
||||
|
||||
_initEngines: function(ibus, result) {
|
||||
@ -109,9 +128,6 @@ const IBusManager = new Lang.Class({
|
||||
this._panelService = new IBus.PanelService({ connection: this._ibus.get_connection(),
|
||||
object_path: IBus.PATH_PANEL });
|
||||
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));
|
||||
// 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) {
|
||||
@ -140,6 +156,9 @@ const IBusManager = new Lang.Class({
|
||||
},
|
||||
|
||||
_engineChanged: function(bus, engineName) {
|
||||
if (!this._ready)
|
||||
return;
|
||||
|
||||
this._currentEngineName = engineName;
|
||||
|
||||
if (this._registerPropertiesId != 0)
|
||||
@ -337,14 +356,14 @@ const InputSourceIndicator = new Lang.Class({
|
||||
Main.wm.addKeybinding('switch-input-source',
|
||||
new Gio.Settings({ schema: "org.gnome.desktop.wm.keybindings" }),
|
||||
Meta.KeyBindingFlags.REVERSES,
|
||||
Shell.KeyBindingMode.ALL & ~Shell.KeyBindingMode.MESSAGE_TRAY,
|
||||
Shell.KeyBindingMode.ALL,
|
||||
Lang.bind(this, this._switchInputSource));
|
||||
this._keybindingActionBackward =
|
||||
Main.wm.addKeybinding('switch-input-source-backward',
|
||||
new Gio.Settings({ schema: "org.gnome.desktop.wm.keybindings" }),
|
||||
Meta.KeyBindingFlags.REVERSES |
|
||||
Meta.KeyBindingFlags.REVERSED,
|
||||
Shell.KeyBindingMode.ALL & ~Shell.KeyBindingMode.MESSAGE_TRAY,
|
||||
Shell.KeyBindingMode.ALL,
|
||||
Lang.bind(this, this._switchInputSource));
|
||||
this._settings = new Gio.Settings({ schema: DESKTOP_INPUT_SOURCES_SCHEMA });
|
||||
this._settings.connect('changed::' + KEY_CURRENT_INPUT_SOURCE, Lang.bind(this, this._currentInputSourceChanged));
|
||||
@ -364,6 +383,15 @@ const InputSourceIndicator = new Lang.Class({
|
||||
this._ibusManager.connect('property-updated', Lang.bind(this, this._ibusPropertyUpdated));
|
||||
this._inputSourcesChanged();
|
||||
|
||||
this._keyboardManager = new KeyboardManagerProxy(Gio.DBus.session, BUS_NAME, OBJECT_PATH,
|
||||
function(proxy, error) {
|
||||
if (error)
|
||||
log(error.message);
|
||||
});
|
||||
this._keyboardManager.g_default_timeout = MAX_INPUT_SOURCE_ACTIVATION_TIME;
|
||||
|
||||
global.display.connect('modifiers-accelerator-activated', Lang.bind(this, this._modifiersSwitcher));
|
||||
|
||||
this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
|
||||
this._showLayoutItem = this.menu.addAction(_("Show Keyboard Layout"), Lang.bind(this, this._showLayout));
|
||||
|
||||
@ -397,10 +425,43 @@ const InputSourceIndicator = new Lang.Class({
|
||||
this._inputSourcesChanged();
|
||||
},
|
||||
|
||||
_modifiersSwitcher: function() {
|
||||
let sourceIndexes = Object.keys(this._inputSources);
|
||||
if (sourceIndexes.length == 0) {
|
||||
releaseKeyboard();
|
||||
return true;
|
||||
}
|
||||
|
||||
let is = this._currentSource;
|
||||
if (!is)
|
||||
is = this._inputSources[sourceIndexes[0]];
|
||||
|
||||
let nextIndex = is.index + 1;
|
||||
if (nextIndex > sourceIndexes[sourceIndexes.length - 1])
|
||||
nextIndex = 0;
|
||||
|
||||
while (!(is = this._inputSources[nextIndex]))
|
||||
nextIndex += 1;
|
||||
|
||||
is.activate();
|
||||
return true;
|
||||
},
|
||||
|
||||
_switchInputSource: function(display, screen, window, binding) {
|
||||
if (this._mruSources.length < 2)
|
||||
return;
|
||||
|
||||
// HACK: Fall back on simple input source switching since we
|
||||
// can't show a popup switcher while a GrabHelper grab is in
|
||||
// effect without considerable work to consolidate the usage
|
||||
// of pushModal/popModal and grabHelper. See
|
||||
// https://bugzilla.gnome.org/show_bug.cgi?id=695143 .
|
||||
if (Main.keybindingMode == Shell.KeyBindingMode.MESSAGE_TRAY ||
|
||||
Main.keybindingMode == Shell.KeyBindingMode.TOPBAR_POPUP) {
|
||||
this._modifiersSwitcher();
|
||||
return;
|
||||
}
|
||||
|
||||
let popup = new InputSourcePopup(this._mruSources, this._keybindingAction, this._keybindingActionBackward);
|
||||
let modifiers = binding.get_modifiers();
|
||||
let backwards = modifiers & Meta.VirtualModifier.SHIFT_MASK;
|
||||
@ -459,6 +520,7 @@ const InputSourceIndicator = new Lang.Class({
|
||||
|
||||
this._inputSources = {};
|
||||
this._ibusSources = {};
|
||||
this._currentSource = null;
|
||||
|
||||
let inputSourcesByShortName = {};
|
||||
|
||||
@ -487,10 +549,8 @@ const InputSourceIndicator = new Lang.Class({
|
||||
let is = new InputSource(type, id, displayName, shortName, i);
|
||||
|
||||
is.connect('activate', Lang.bind(this, function() {
|
||||
if (this._currentSource && this._currentSource.index == is.index)
|
||||
return;
|
||||
this._settings.set_value(KEY_CURRENT_INPUT_SOURCE,
|
||||
GLib.Variant.new_uint32(is.index));
|
||||
holdKeyboard();
|
||||
this._keyboardManager.SetInputSourceRemote(is.index, releaseKeyboard);
|
||||
}));
|
||||
|
||||
if (!(is.shortName in inputSourcesByShortName))
|
||||
|
@ -2047,6 +2047,7 @@ const NMApplet = new Lang.Class({
|
||||
let default_ip4 = null;
|
||||
let default_ip6 = null;
|
||||
let active_vpn = null;
|
||||
let active_any = null;
|
||||
for (let i = 0; i < this._activeConnections.length; i++) {
|
||||
let a = this._activeConnections[i];
|
||||
|
||||
@ -2077,10 +2078,15 @@ const NMApplet = new Lang.Class({
|
||||
if (a.default6)
|
||||
default_ip6 = a;
|
||||
|
||||
if (a._type == 'vpn')
|
||||
active_vpn = a;
|
||||
else if (a.state == NetworkManager.ActiveConnectionState.ACTIVATING)
|
||||
if (a.state == NetworkManager.ActiveConnectionState.ACTIVATING)
|
||||
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;
|
||||
|
||||
if (!a._primaryDevice) {
|
||||
if (a._type != NetworkManager.SETTING_VPN_SETTING_NAME) {
|
||||
@ -2108,7 +2114,7 @@ const NMApplet = new Lang.Class({
|
||||
}
|
||||
}
|
||||
|
||||
this._mainConnection = activating || default_ip4 || default_ip6 || this._activeConnections[0] || null;
|
||||
this._mainConnection = activating || default_ip4 || default_ip6 || active_any || null;
|
||||
this._vpnConnection = active_vpn;
|
||||
},
|
||||
|
||||
|
@ -307,7 +307,7 @@ const Indicator = new Lang.Class({
|
||||
this._headphoneIcon.visible = value;
|
||||
}));
|
||||
|
||||
this._headphoneIcon = this.addIcon(new Gio.ThemedIcon({ name: 'headphones-symbolic' }));
|
||||
this._headphoneIcon = this.addIcon(new Gio.ThemedIcon({ name: 'audio-headphones-symbolic' }));
|
||||
this._headphoneIcon.visible = false;
|
||||
|
||||
this.menu.addMenuItem(this._volumeMenu);
|
||||
|
@ -91,10 +91,6 @@ const UnlockDialog = new Lang.Class({
|
||||
this._promptLoginHint.hide();
|
||||
this.contentLayout.add_actor(this._promptLoginHint);
|
||||
|
||||
let spinnerIcon = global.datadir + '/theme/process-working.svg';
|
||||
this._workSpinner = new Panel.AnimatedIcon(spinnerIcon, LoginDialog.WORK_SPINNER_ICON_SIZE);
|
||||
this._workSpinner.actor.opacity = 0;
|
||||
|
||||
this.allowCancel = false;
|
||||
this.buttonLayout.visible = true;
|
||||
this.addButton({ label: _("Cancel"),
|
||||
@ -105,12 +101,11 @@ const UnlockDialog = new Lang.Class({
|
||||
y_fill: false,
|
||||
x_align: St.Align.START,
|
||||
y_align: St.Align.MIDDLE });
|
||||
this.buttonLayout.add(this._workSpinner.actor,
|
||||
{ expand: false,
|
||||
x_fill: false,
|
||||
y_fill: false,
|
||||
x_align: St.Align.END,
|
||||
y_align: St.Align.MIDDLE });
|
||||
this.placeSpinner({ expand: false,
|
||||
x_fill: false,
|
||||
y_fill: false,
|
||||
x_align: St.Align.END,
|
||||
y_align: St.Align.MIDDLE });
|
||||
this._okButton = this.addButton({ label: _("Unlock"),
|
||||
action: Lang.bind(this, this._doUnlock),
|
||||
default: true },
|
||||
@ -164,28 +159,6 @@ const UnlockDialog = new Lang.Class({
|
||||
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) {
|
||||
if (message) {
|
||||
this._promptMessage.text = message;
|
||||
@ -216,7 +189,7 @@ const UnlockDialog = new Lang.Class({
|
||||
|
||||
this._currentQuery = serviceName;
|
||||
this._updateSensitivity(true);
|
||||
this._setWorking(false);
|
||||
this.setWorking(false);
|
||||
},
|
||||
|
||||
_showLoginHint: function(verifier, message) {
|
||||
@ -235,7 +208,7 @@ const UnlockDialog = new Lang.Class({
|
||||
// the actual reply to GDM will be sent as soon as asked
|
||||
this._firstQuestionAnswer = this._promptEntry.text;
|
||||
this._updateSensitivity(false);
|
||||
this._setWorking(true);
|
||||
this.setWorking(true);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -246,7 +219,7 @@ const UnlockDialog = new Lang.Class({
|
||||
this._currentQuery = null;
|
||||
|
||||
this._updateSensitivity(false);
|
||||
this._setWorking(true);
|
||||
this.setWorking(true);
|
||||
|
||||
this._userVerifier.answerQuery(query, this._promptEntry.text);
|
||||
},
|
||||
@ -286,7 +259,7 @@ const UnlockDialog = new Lang.Class({
|
||||
this._promptEntry.menu.isPassword = true;
|
||||
|
||||
this._updateSensitivity(false);
|
||||
this._setWorking(false);
|
||||
this.setWorking(false);
|
||||
},
|
||||
|
||||
_escape: function() {
|
||||
|
@ -16,6 +16,7 @@ const UserWidget = new Lang.Class({
|
||||
|
||||
this.actor = new St.BoxLayout({ style_class: 'user-widget',
|
||||
vertical: false });
|
||||
this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
|
||||
|
||||
this._avatar = new UserMenu.UserAvatarWidget(user);
|
||||
this.actor.add(this._avatar.actor,
|
||||
@ -36,7 +37,7 @@ const UserWidget = new Lang.Class({
|
||||
this._updateUser();
|
||||
},
|
||||
|
||||
destroy: function() {
|
||||
_onDestroy: function() {
|
||||
if (this._userLoadedId != 0) {
|
||||
this._user.disconnect(this._userLoadedId);
|
||||
this._userLoadedId = 0;
|
||||
@ -46,8 +47,6 @@ const UserWidget = new Lang.Class({
|
||||
this._user.disconnect(this._userChangedId);
|
||||
this._userChangedId = 0;
|
||||
}
|
||||
|
||||
this.actor.destroy();
|
||||
},
|
||||
|
||||
_updateUser: function() {
|
||||
|
@ -136,6 +136,42 @@ const WindowManager = new Lang.Class({
|
||||
Shell.KeyBindingMode.NORMAL |
|
||||
Shell.KeyBindingMode.OVERVIEW,
|
||||
Lang.bind(this, this._showWorkspaceSwitcher));
|
||||
this.allowKeybinding('switch-to-workspace-1',
|
||||
Shell.KeyBindingMode.NORMAL |
|
||||
Shell.KeyBindingMode.OVERVIEW);
|
||||
this.allowKeybinding('switch-to-workspace-2',
|
||||
Shell.KeyBindingMode.NORMAL |
|
||||
Shell.KeyBindingMode.OVERVIEW);
|
||||
this.allowKeybinding('switch-to-workspace-3',
|
||||
Shell.KeyBindingMode.NORMAL |
|
||||
Shell.KeyBindingMode.OVERVIEW);
|
||||
this.allowKeybinding('switch-to-workspace-4',
|
||||
Shell.KeyBindingMode.NORMAL |
|
||||
Shell.KeyBindingMode.OVERVIEW);
|
||||
this.allowKeybinding('switch-to-workspace-5',
|
||||
Shell.KeyBindingMode.NORMAL |
|
||||
Shell.KeyBindingMode.OVERVIEW);
|
||||
this.allowKeybinding('switch-to-workspace-6',
|
||||
Shell.KeyBindingMode.NORMAL |
|
||||
Shell.KeyBindingMode.OVERVIEW);
|
||||
this.allowKeybinding('switch-to-workspace-7',
|
||||
Shell.KeyBindingMode.NORMAL |
|
||||
Shell.KeyBindingMode.OVERVIEW);
|
||||
this.allowKeybinding('switch-to-workspace-8',
|
||||
Shell.KeyBindingMode.NORMAL |
|
||||
Shell.KeyBindingMode.OVERVIEW);
|
||||
this.allowKeybinding('switch-to-workspace-9',
|
||||
Shell.KeyBindingMode.NORMAL |
|
||||
Shell.KeyBindingMode.OVERVIEW);
|
||||
this.allowKeybinding('switch-to-workspace-10',
|
||||
Shell.KeyBindingMode.NORMAL |
|
||||
Shell.KeyBindingMode.OVERVIEW);
|
||||
this.allowKeybinding('switch-to-workspace-11',
|
||||
Shell.KeyBindingMode.NORMAL |
|
||||
Shell.KeyBindingMode.OVERVIEW);
|
||||
this.allowKeybinding('switch-to-workspace-12',
|
||||
Shell.KeyBindingMode.NORMAL |
|
||||
Shell.KeyBindingMode.OVERVIEW);
|
||||
this.setCustomKeybindingHandler('switch-applications',
|
||||
Shell.KeyBindingMode.NORMAL,
|
||||
Lang.bind(this, this._startAppSwitcher));
|
||||
@ -172,8 +208,9 @@ const WindowManager = new Lang.Class({
|
||||
this.addKeybinding('open-application-menu',
|
||||
new Gio.Settings({ schema: SHELL_KEYBINDINGS_SCHEMA }),
|
||||
Meta.KeyBindingFlags.NONE,
|
||||
Shell.KeyBindingMode.NORMAL,
|
||||
Lang.bind(this, this._openAppMenu));
|
||||
Shell.KeyBindingMode.NORMAL |
|
||||
Shell.KeyBindingMode.TOPBAR_POPUP,
|
||||
Lang.bind(this, this._toggleAppMenu));
|
||||
|
||||
Main.overview.connect('showing', Lang.bind(this, function() {
|
||||
for (let i = 0; i < this._dimmedWindows.length; i++)
|
||||
@ -679,8 +716,8 @@ const WindowManager = new Lang.Class({
|
||||
Main.ctrlAltTabManager.popup(backwards, binding.get_name(), binding.get_mask());
|
||||
},
|
||||
|
||||
_openAppMenu : function(display, screen, window, event, binding) {
|
||||
Main.panel.openAppMenu();
|
||||
_toggleAppMenu : function(display, screen, window, event, binding) {
|
||||
Main.panel.toggleAppMenu();
|
||||
},
|
||||
|
||||
_showWorkspaceSwitcher : function(display, screen, window, binding) {
|
||||
|
@ -1094,6 +1094,7 @@ const Workspace = new Lang.Class({
|
||||
Tweener.removeTweens(clone.actor);
|
||||
clone.actor.set_position(x, y);
|
||||
clone.actor.set_scale(scale, scale);
|
||||
clone.actor.set_opacity(255);
|
||||
clone.overlay.relayout(false);
|
||||
this._showWindowOverlay(clone, overlay, isOnCurrentWorkspace);
|
||||
}
|
||||
|
@ -125,6 +125,12 @@
|
||||
<listitem><para>List possible modes and exit</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>--clutter-display=<replaceable>DISPLAY</replaceable></option></term>
|
||||
|
||||
<listitem><para>Clutter the option display (otherwise ignored)</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
</variablelist>
|
||||
|
||||
</refsect1>
|
||||
|
@ -28,6 +28,7 @@ gu
|
||||
he
|
||||
hi
|
||||
hu
|
||||
ia
|
||||
id
|
||||
it
|
||||
ja
|
||||
@ -45,6 +46,7 @@ ms
|
||||
nb
|
||||
nl
|
||||
nn
|
||||
oc
|
||||
or
|
||||
pa
|
||||
pl
|
||||
|
2
po/eu.po
2
po/eu.po
@ -1244,7 +1244,7 @@ msgstr "Ezezaguna"
|
||||
#, c-format
|
||||
msgid "%d new message"
|
||||
msgid_plural "%d new messages"
|
||||
msgstr[0] "Mezu berri &d"
|
||||
msgstr[0] "Mezu berri %d"
|
||||
msgstr[1] "%d mezu berri"
|
||||
|
||||
#: ../js/ui/overview.js:84
|
||||
|
279
po/lt.po
279
po/lt.po
@ -11,9 +11,9 @@ msgstr ""
|
||||
"Project-Id-Version: gnome-shell master\n"
|
||||
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-"
|
||||
"shell&keywords=I18N+L10N&component=general\n"
|
||||
"POT-Creation-Date: 2013-03-23 11:49+0000\n"
|
||||
"PO-Revision-Date: 2013-03-26 22:43+0200\n"
|
||||
"Last-Translator: Mantas Kriaučiūnas <mantas@akl.lt>\n"
|
||||
"POT-Creation-Date: 2013-12-20 16:10+0000\n"
|
||||
"PO-Revision-Date: 2013-12-21 16:31+0200\n"
|
||||
"Last-Translator: Aurimas Černius <aurisc4@gmail.com>\n"
|
||||
"Language-Team: Lietuvių <gnome-lt@lists.akl.lt>\n"
|
||||
"Language: lt\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
@ -360,7 +360,7 @@ msgstr "Darbalaukiai tik pagrindiniame monitoriuje"
|
||||
#: ../js/extensionPrefs/main.js:125
|
||||
#, c-format
|
||||
msgid "There was an error loading the preferences dialog for %s:"
|
||||
msgstr "Įvyko klaida įkeliant %s nustatymų dialogą:"
|
||||
msgstr "Kilo klaida įkeliant %s nustatymų dialogą:"
|
||||
|
||||
#: ../js/extensionPrefs/main.js:165
|
||||
msgid "Extension"
|
||||
@ -370,43 +370,50 @@ msgstr "Plėtinys"
|
||||
msgid "Select an extension to configure using the combobox above."
|
||||
msgstr "Išskleidžiamajame sąraše pasirinkite konfigūruotiną plėtinį."
|
||||
|
||||
#: ../js/gdm/loginDialog.js:405
|
||||
#: ../js/gdm/loginDialog.js:371
|
||||
msgid "Session…"
|
||||
msgstr "Seansas…"
|
||||
|
||||
#. translators: this message is shown below the user list on the
|
||||
#. login screen. It can be activated to reveal an entry for
|
||||
#. manually entering the username.
|
||||
#: ../js/gdm/loginDialog.js:630
|
||||
#: ../js/gdm/loginDialog.js:601
|
||||
msgid "Not listed?"
|
||||
msgstr "Nėra sąraše?"
|
||||
|
||||
#: ../js/gdm/loginDialog.js:786 ../js/ui/components/networkAgent.js:137
|
||||
#: ../js/ui/components/polkitAgent.js:162 ../js/ui/endSessionDialog.js:375
|
||||
#: ../js/gdm/loginDialog.js:776 ../js/ui/components/networkAgent.js:137
|
||||
#: ../js/ui/components/polkitAgent.js:161 ../js/ui/endSessionDialog.js:376
|
||||
#: ../js/ui/extensionDownloader.js:195 ../js/ui/shellMountOperation.js:399
|
||||
#: ../js/ui/status/bluetooth.js:415 ../js/ui/unlockDialog.js:99
|
||||
#: ../js/ui/status/bluetooth.js:415 ../js/ui/unlockDialog.js:96
|
||||
#: ../js/ui/userMenu.js:938
|
||||
msgid "Cancel"
|
||||
msgstr "Atsisakyti"
|
||||
|
||||
#: ../js/gdm/loginDialog.js:802
|
||||
#: ../js/gdm/loginDialog.js:791
|
||||
msgctxt "button"
|
||||
msgid "Sign In"
|
||||
msgstr "Prisijungti"
|
||||
|
||||
#: ../js/gdm/loginDialog.js:802
|
||||
#: ../js/gdm/loginDialog.js:791
|
||||
msgid "Next"
|
||||
msgstr "Kitas"
|
||||
|
||||
#. 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 "(pvz., naudotojas arba %s)"
|
||||
|
||||
#. TTLS and PEAP are actually much more complicated, but this complication
|
||||
#. is not visible here since we only care about phase2 authentication
|
||||
#. (and don't even care of which one)
|
||||
#: ../js/gdm/loginDialog.js:917 ../js/ui/components/networkAgent.js:260
|
||||
#: ../js/gdm/loginDialog.js:892 ../js/ui/components/networkAgent.js:260
|
||||
#: ../js/ui/components/networkAgent.js:278
|
||||
msgid "Username: "
|
||||
msgstr "Naudotojo vardas: "
|
||||
|
||||
#: ../js/gdm/loginDialog.js:1173
|
||||
#: ../js/gdm/loginDialog.js:1158
|
||||
msgid "Login Window"
|
||||
msgstr "Prisijungimo langas"
|
||||
|
||||
@ -429,21 +436,16 @@ msgstr "Paleisti iš naujo"
|
||||
msgid "Power Off"
|
||||
msgstr "Išjungti"
|
||||
|
||||
#: ../js/gdm/util.js:249
|
||||
#: ../js/gdm/util.js:248
|
||||
msgid "Authentication error"
|
||||
msgstr "Tapatybės patvirtinimo klaida"
|
||||
|
||||
#. Translators: this message is shown below the password entry field
|
||||
#. to indicate the user can swipe their finger instead
|
||||
#: ../js/gdm/util.js:366
|
||||
#: ../js/gdm/util.js:365
|
||||
msgid "(or swipe finger)"
|
||||
msgstr "(arba perbraukite pirštu)"
|
||||
|
||||
#: ../js/gdm/util.js:391
|
||||
#, c-format
|
||||
msgid "(e.g., user or %s)"
|
||||
msgstr "(pvz., naudotojas arba %s)"
|
||||
|
||||
#: ../js/misc/util.js:97
|
||||
msgid "Command not found"
|
||||
msgstr "Komanda nerasta"
|
||||
@ -459,23 +461,23 @@ msgstr "Nepavyko perskaityti komandos:"
|
||||
msgid "Execution of '%s' failed:"
|
||||
msgstr "Nepavyko įvykdyti „%s“:"
|
||||
|
||||
#: ../js/ui/appDisplay.js:349
|
||||
#: ../js/ui/appDisplay.js:392
|
||||
msgid "Frequent"
|
||||
msgstr "Dažniausios"
|
||||
msgstr "Dažnai naudojamos"
|
||||
|
||||
#: ../js/ui/appDisplay.js:356
|
||||
#: ../js/ui/appDisplay.js:399
|
||||
msgid "All"
|
||||
msgstr "Visos"
|
||||
|
||||
#: ../js/ui/appDisplay.js:914
|
||||
#: ../js/ui/appDisplay.js:977
|
||||
msgid "New Window"
|
||||
msgstr "Naujas langas"
|
||||
|
||||
#: ../js/ui/appDisplay.js:917 ../js/ui/dash.js:284
|
||||
#: ../js/ui/appDisplay.js:980 ../js/ui/dash.js:284
|
||||
msgid "Remove from Favorites"
|
||||
msgstr "Pašalinti iš mėgstamų"
|
||||
|
||||
#: ../js/ui/appDisplay.js:918
|
||||
#: ../js/ui/appDisplay.js:981
|
||||
msgid "Add to Favorites"
|
||||
msgstr "Pridėti prie mėgstamų"
|
||||
|
||||
@ -512,7 +514,7 @@ msgctxt "event list time"
|
||||
msgid "%H\\u2236%M"
|
||||
msgstr "%H\\u2236%M"
|
||||
|
||||
#. Transators: Shown in calendar event list, if 12h format,
|
||||
#. Translators: Shown in calendar event list, if 12h format,
|
||||
#. \u2236 is a ratio character, similar to : and \u2009 is
|
||||
#. a thin space
|
||||
#: ../js/ui/calendar.js:77
|
||||
@ -667,11 +669,11 @@ msgstr "Atverti su %s"
|
||||
msgid "Eject"
|
||||
msgstr "Išimti"
|
||||
|
||||
#: ../js/ui/components/keyring.js:82 ../js/ui/components/polkitAgent.js:268
|
||||
#: ../js/ui/components/keyring.js:88 ../js/ui/components/polkitAgent.js:280
|
||||
msgid "Password:"
|
||||
msgstr "Slaptažodis:"
|
||||
|
||||
#: ../js/ui/components/keyring.js:101
|
||||
#: ../js/ui/components/keyring.js:107
|
||||
msgid "Type again:"
|
||||
msgstr "Įveskite dar kartą:"
|
||||
|
||||
@ -751,15 +753,15 @@ msgstr "Mobiliojo plačiajuosčio tinklo slaptažodis"
|
||||
msgid "A password is required to connect to '%s'."
|
||||
msgstr "Būtinas slaptažodis norint prisijungti prie „%s“"
|
||||
|
||||
#: ../js/ui/components/polkitAgent.js:55
|
||||
#: ../js/ui/components/polkitAgent.js:54
|
||||
msgid "Authentication Required"
|
||||
msgstr "Reikia patvirtinti tapatybę"
|
||||
|
||||
#: ../js/ui/components/polkitAgent.js:93
|
||||
#: ../js/ui/components/polkitAgent.js:92
|
||||
msgid "Administrator"
|
||||
msgstr "Administratorius"
|
||||
|
||||
#: ../js/ui/components/polkitAgent.js:165
|
||||
#: ../js/ui/components/polkitAgent.js:170
|
||||
msgid "Authenticate"
|
||||
msgstr "Patvirtinti tapatybę"
|
||||
|
||||
@ -767,12 +769,12 @@ msgstr "Patvirtinti tapatybę"
|
||||
#. * requested authentication was not gained; this can happen
|
||||
#. * because of an authentication error (like invalid password),
|
||||
#. * for instance.
|
||||
#: ../js/ui/components/polkitAgent.js:256 ../js/ui/shellMountOperation.js:383
|
||||
#: ../js/ui/components/polkitAgent.js:266 ../js/ui/shellMountOperation.js:383
|
||||
msgid "Sorry, that didn't work. Please try again."
|
||||
msgstr "Atsiprašome, tai nesuveikė. Bandykite dar kartą."
|
||||
|
||||
#. Translators: this is a filename used for screencast recording
|
||||
#: ../js/ui/components/recorder.js:48
|
||||
#: ../js/ui/components/recorder.js:47
|
||||
#, no-c-format
|
||||
msgid "Screencast from %d %t"
|
||||
msgstr "Ekrano vaizdo įrašas iš %d %t"
|
||||
@ -831,14 +833,14 @@ msgstr "<b>%B</b> <b>%d</b> <b>%Y</b>, <b>%H:%M</b> "
|
||||
|
||||
#. Translators: this is the other person changing their old IM name to their new
|
||||
#. IM name.
|
||||
#: ../js/ui/components/telepathyClient.js:985
|
||||
#: ../js/ui/components/telepathyClient.js:986
|
||||
#, c-format
|
||||
msgid "%s is now known as %s"
|
||||
msgstr "%s nuo šiol vadinasi %s"
|
||||
|
||||
#. translators: argument is a room name like
|
||||
#. * room@jabber.org for example.
|
||||
#: ../js/ui/components/telepathyClient.js:1088
|
||||
#: ../js/ui/components/telepathyClient.js:1089
|
||||
#, c-format
|
||||
msgid "Invitation to %s"
|
||||
msgstr "Kvietimas į %s"
|
||||
@ -846,38 +848,38 @@ msgstr "Kvietimas į %s"
|
||||
#. translators: first argument is the name of a contact and the second
|
||||
#. * one the name of a room. "Alice is inviting you to join room@jabber.org
|
||||
#. * for example.
|
||||
#: ../js/ui/components/telepathyClient.js:1096
|
||||
#: ../js/ui/components/telepathyClient.js:1097
|
||||
#, c-format
|
||||
msgid "%s is inviting you to join %s"
|
||||
msgstr "%s jus kviečia prisijungti prie %s"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1098
|
||||
#: ../js/ui/components/telepathyClient.js:1137
|
||||
#: ../js/ui/components/telepathyClient.js:1177
|
||||
#: ../js/ui/components/telepathyClient.js:1240
|
||||
#: ../js/ui/components/telepathyClient.js:1099
|
||||
#: ../js/ui/components/telepathyClient.js:1138
|
||||
#: ../js/ui/components/telepathyClient.js:1178
|
||||
#: ../js/ui/components/telepathyClient.js:1241
|
||||
msgid "Decline"
|
||||
msgstr "Atmesti"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1099
|
||||
#: ../js/ui/components/telepathyClient.js:1178
|
||||
#: ../js/ui/components/telepathyClient.js:1241
|
||||
#: ../js/ui/components/telepathyClient.js:1100
|
||||
#: ../js/ui/components/telepathyClient.js:1179
|
||||
#: ../js/ui/components/telepathyClient.js:1242
|
||||
msgid "Accept"
|
||||
msgstr "Priimti"
|
||||
|
||||
#. translators: argument is a contact name like Alice for example.
|
||||
#: ../js/ui/components/telepathyClient.js:1129
|
||||
#: ../js/ui/components/telepathyClient.js:1130
|
||||
#, c-format
|
||||
msgid "Video call from %s"
|
||||
msgstr "Vaizdo skambutis nuo %s"
|
||||
|
||||
#. translators: argument is a contact name like Alice for example.
|
||||
#: ../js/ui/components/telepathyClient.js:1132
|
||||
#: ../js/ui/components/telepathyClient.js:1133
|
||||
#, c-format
|
||||
msgid "Call from %s"
|
||||
msgstr "Skambutis nuo %s"
|
||||
|
||||
#. translators: this is a button label (verb), not a noun
|
||||
#: ../js/ui/components/telepathyClient.js:1139
|
||||
#: ../js/ui/components/telepathyClient.js:1140
|
||||
msgid "Answer"
|
||||
msgstr "Atsiliepti"
|
||||
|
||||
@ -886,110 +888,110 @@ msgstr "Atsiliepti"
|
||||
#. * file name. The string will be something
|
||||
#. * like: "Alice is sending you test.ogg"
|
||||
#.
|
||||
#: ../js/ui/components/telepathyClient.js:1171
|
||||
#: ../js/ui/components/telepathyClient.js:1172
|
||||
#, c-format
|
||||
msgid "%s is sending you %s"
|
||||
msgstr "%s jums siunčia %s"
|
||||
|
||||
#. To translators: The parameter is the contact's alias
|
||||
#: ../js/ui/components/telepathyClient.js:1206
|
||||
#: ../js/ui/components/telepathyClient.js:1207
|
||||
#, c-format
|
||||
msgid "%s would like permission to see when you are online"
|
||||
msgstr "%s pageidauja matyti, kai esate prisijungę prie interneto"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1298
|
||||
#: ../js/ui/components/telepathyClient.js:1299
|
||||
msgid "Network error"
|
||||
msgstr "Tinklo klaida"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1300
|
||||
#: ../js/ui/components/telepathyClient.js:1301
|
||||
msgid "Authentication failed"
|
||||
msgstr "Nepavyko patvirtinti tapatybės"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1302
|
||||
#: ../js/ui/components/telepathyClient.js:1303
|
||||
msgid "Encryption error"
|
||||
msgstr "Šifravimo klaida"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1304
|
||||
#: ../js/ui/components/telepathyClient.js:1305
|
||||
msgid "Certificate not provided"
|
||||
msgstr "Liudijimas nepateiktas"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1306
|
||||
#: ../js/ui/components/telepathyClient.js:1307
|
||||
msgid "Certificate untrusted"
|
||||
msgstr "Liudijimas nepatikimas"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1308
|
||||
#: ../js/ui/components/telepathyClient.js:1309
|
||||
msgid "Certificate expired"
|
||||
msgstr "Liudijimo galiojimas pasibaigęs"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1310
|
||||
#: ../js/ui/components/telepathyClient.js:1311
|
||||
msgid "Certificate not activated"
|
||||
msgstr "Liudijimas neaktyvuotas"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1312
|
||||
#: ../js/ui/components/telepathyClient.js:1313
|
||||
msgid "Certificate hostname mismatch"
|
||||
msgstr "Liudijimo serverio vardo nesutapimas"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1314
|
||||
#: ../js/ui/components/telepathyClient.js:1315
|
||||
msgid "Certificate fingerprint mismatch"
|
||||
msgstr "Liudijimo piršto atspaudo nesutapimas"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1316
|
||||
#: ../js/ui/components/telepathyClient.js:1317
|
||||
msgid "Certificate self-signed"
|
||||
msgstr "Liudijimas pačių pasirašytas"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1318
|
||||
#: ../js/ui/components/telepathyClient.js:1319
|
||||
msgid "Status is set to offline"
|
||||
msgstr "Nustatyta atsijungimo būsena"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1320
|
||||
#: ../js/ui/components/telepathyClient.js:1321
|
||||
msgid "Encryption is not available"
|
||||
msgstr "Šifravimas negalimas"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1322
|
||||
#: ../js/ui/components/telepathyClient.js:1323
|
||||
msgid "Certificate is invalid"
|
||||
msgstr "Liudijimas netinkamas"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1324
|
||||
#: ../js/ui/components/telepathyClient.js:1325
|
||||
msgid "Connection has been refused"
|
||||
msgstr "Ryšys atmestas"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1326
|
||||
#: ../js/ui/components/telepathyClient.js:1327
|
||||
msgid "Connection can't be established"
|
||||
msgstr "Nepavyko užmegzti ryšio"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1328
|
||||
#: ../js/ui/components/telepathyClient.js:1329
|
||||
msgid "Connection has been lost"
|
||||
msgstr "Ryšys nutrūko"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1330
|
||||
#: ../js/ui/components/telepathyClient.js:1331
|
||||
msgid "This account is already connected to the server"
|
||||
msgstr "Ši paskyra jau prijungta prie serverio"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1332
|
||||
#: ../js/ui/components/telepathyClient.js:1333
|
||||
msgid ""
|
||||
"Connection has been replaced by a new connection using the same resource"
|
||||
msgstr "Ryšys pakeistas nauju ryšiu naudojant tą patį išteklių"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1334
|
||||
#: ../js/ui/components/telepathyClient.js:1335
|
||||
msgid "The account already exists on the server"
|
||||
msgstr "Tokia paskyra serveryje jau yra"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1336
|
||||
#: ../js/ui/components/telepathyClient.js:1337
|
||||
msgid "Server is currently too busy to handle the connection"
|
||||
msgstr "Šiuo metu serveris per daug užimtas šiai užklausai apdoroti"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1338
|
||||
#: ../js/ui/components/telepathyClient.js:1339
|
||||
msgid "Certificate has been revoked"
|
||||
msgstr "Liudijimas atšauktas"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1340
|
||||
#: ../js/ui/components/telepathyClient.js:1341
|
||||
msgid ""
|
||||
"Certificate uses an insecure cipher algorithm or is cryptographically weak"
|
||||
msgstr ""
|
||||
"Liudijimui naudojamas nesaugus šifravimo algoritmas arba jis kriptografiškai "
|
||||
"silpnas"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1342
|
||||
#: ../js/ui/components/telepathyClient.js:1343
|
||||
msgid ""
|
||||
"The length of the server certificate, or the depth of the server certificate "
|
||||
"chain, exceed the limits imposed by the cryptography library"
|
||||
@ -997,22 +999,22 @@ msgstr ""
|
||||
"Serverio liudijimo ilgis arba liudijimų eilės dydis viršija kriptografijos "
|
||||
"bibliotekos apribojimus"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1344
|
||||
#: ../js/ui/components/telepathyClient.js:1345
|
||||
msgid "Internal error"
|
||||
msgstr "Vidinė klaida"
|
||||
|
||||
#. translators: argument is the account name, like
|
||||
#. * name@jabber.org for example.
|
||||
#: ../js/ui/components/telepathyClient.js:1354
|
||||
#: ../js/ui/components/telepathyClient.js:1355
|
||||
#, c-format
|
||||
msgid "Unable to connect to %s"
|
||||
msgstr "Nepavyksta prisijungti prie %s"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1359
|
||||
#: ../js/ui/components/telepathyClient.js:1360
|
||||
msgid "View account"
|
||||
msgstr "Rodyti paskyrą"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1398
|
||||
#: ../js/ui/components/telepathyClient.js:1399
|
||||
msgid "Unknown reason"
|
||||
msgstr "Nežinoma priežastis"
|
||||
|
||||
@ -1026,7 +1028,7 @@ msgstr "Paleisti programas"
|
||||
|
||||
#. Translators: this is the name of the dock/favorites area on
|
||||
#. the left of the overview
|
||||
#: ../js/ui/dash.js:435
|
||||
#: ../js/ui/dash.js:445
|
||||
msgid "Dash"
|
||||
msgstr "Paleidimo sritis"
|
||||
|
||||
@ -1038,14 +1040,14 @@ msgstr "Atverti kalendorių"
|
||||
msgid "Open Clocks"
|
||||
msgstr "Atverti laikrodžius"
|
||||
|
||||
#: ../js/ui/dateMenu.js:105
|
||||
#: ../js/ui/dateMenu.js:104
|
||||
msgid "Date & Time Settings"
|
||||
msgstr "Datos ir laiko nustatymai"
|
||||
|
||||
#. Translators: This is the date format to use when the calendar popup is
|
||||
#. * shown - it is shown just below the time in the shell (e.g. "Tue 9:29 AM").
|
||||
#.
|
||||
#: ../js/ui/dateMenu.js:215
|
||||
#: ../js/ui/dateMenu.js:216
|
||||
msgid "%A %B %e, %Y"
|
||||
msgstr "%A, %Y m. %B %d d."
|
||||
|
||||
@ -1156,7 +1158,7 @@ msgstr "Įdiegti"
|
||||
msgid "Download and install '%s' from extensions.gnome.org?"
|
||||
msgstr "Atsiųsti ir įdiegti „%s“ iš extensions.gnome.org?"
|
||||
|
||||
#: ../js/ui/keyboard.js:619 ../js/ui/status/keyboard.js:314
|
||||
#: ../js/ui/keyboard.js:619 ../js/ui/status/keyboard.js:333
|
||||
#: ../js/ui/status/power.js:211
|
||||
msgid "Keyboard"
|
||||
msgstr "Klaviatūra"
|
||||
@ -1183,7 +1185,9 @@ msgstr "Rodyti klaidas"
|
||||
msgid "Enabled"
|
||||
msgstr "Įjungta"
|
||||
|
||||
#: ../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"
|
||||
msgstr "Išjungta"
|
||||
|
||||
@ -1223,19 +1227,19 @@ msgstr "Išvalyti pranešimus"
|
||||
msgid "Notification Settings"
|
||||
msgstr "Pranešimų nustatymai"
|
||||
|
||||
#: ../js/ui/messageTray.js:1709
|
||||
#: ../js/ui/messageTray.js:1707
|
||||
msgid "No Messages"
|
||||
msgstr "Nėra pranešimų"
|
||||
|
||||
#: ../js/ui/messageTray.js:1782
|
||||
#: ../js/ui/messageTray.js:1783
|
||||
msgid "Message Tray"
|
||||
msgstr "Pranešimų juosta"
|
||||
|
||||
#: ../js/ui/messageTray.js:2810
|
||||
#: ../js/ui/messageTray.js:2822
|
||||
msgid "System Information"
|
||||
msgstr "Sistemos informacija"
|
||||
|
||||
#: ../js/ui/notificationDaemon.js:629 ../src/shell-app.c:374
|
||||
#: ../js/ui/notificationDaemon.js:629 ../src/shell-app.c:392
|
||||
msgctxt "program"
|
||||
msgid "Unknown"
|
||||
msgstr "Nežinoma"
|
||||
@ -1262,19 +1266,19 @@ msgstr "Apžvalga"
|
||||
#. characters.
|
||||
#: ../js/ui/overview.js:271
|
||||
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:636
|
||||
msgid "Quit"
|
||||
msgstr "Užverti"
|
||||
|
||||
#. Translators: If there is no suitable word for "Activities"
|
||||
#. in your language, you can use the word for "Overview".
|
||||
#: ../js/ui/panel.js:636
|
||||
#: ../js/ui/panel.js:687
|
||||
msgid "Activities"
|
||||
msgstr "Apžvalga"
|
||||
|
||||
#: ../js/ui/panel.js:933
|
||||
#: ../js/ui/panel.js:983
|
||||
msgid "Top Bar"
|
||||
msgstr "Viršutinė juosta"
|
||||
|
||||
@ -1283,15 +1287,15 @@ msgstr "Viršutinė juosta"
|
||||
#. "ON" and "OFF") or "toggle-switch-intl" (for toggle
|
||||
#. switches containing "◯" and "|"). Other values will
|
||||
#. simply result in invisible toggle switches.
|
||||
#: ../js/ui/popupMenu.js:727
|
||||
#: ../js/ui/popupMenu.js:740
|
||||
msgid "toggle-switch-us"
|
||||
msgstr "toggle-switch-intl"
|
||||
|
||||
#: ../js/ui/runDialog.js:73
|
||||
#: ../js/ui/runDialog.js:74
|
||||
msgid "Enter a Command"
|
||||
msgstr "Įveskite komandą"
|
||||
|
||||
#: ../js/ui/runDialog.js:109
|
||||
#: ../js/ui/runDialog.js:110
|
||||
msgid "Close"
|
||||
msgstr "Užverti"
|
||||
|
||||
@ -1299,7 +1303,7 @@ msgstr "Užverti"
|
||||
#. long format
|
||||
#: ../js/ui/screenShield.js:86
|
||||
msgid "%A, %B %d"
|
||||
msgstr "%A, %B %d"
|
||||
msgstr "%A, %B %d d."
|
||||
|
||||
#: ../js/ui/screenShield.js:151
|
||||
#, c-format
|
||||
@ -1313,7 +1317,7 @@ msgstr[2] "%d naujų pranešimų"
|
||||
msgid "Lock"
|
||||
msgstr "Užrakinti"
|
||||
|
||||
#: ../js/ui/screenShield.js:637
|
||||
#: ../js/ui/screenShield.js:642
|
||||
msgid "GNOME needs to lock the screen"
|
||||
msgstr "GNOME aplinkai reikia užrakinti ekraną"
|
||||
|
||||
@ -1324,11 +1328,11 @@ msgstr "GNOME aplinkai reikia užrakinti ekraną"
|
||||
#.
|
||||
#. XXX: another option is to kick the user into the gdm login
|
||||
#. screen, where we're not affected by grabs
|
||||
#: ../js/ui/screenShield.js:758 ../js/ui/screenShield.js:1194
|
||||
#: ../js/ui/screenShield.js:765 ../js/ui/screenShield.js:1201
|
||||
msgid "Unable to lock"
|
||||
msgstr "Nepavyksta užrakinti"
|
||||
|
||||
#: ../js/ui/screenShield.js:759 ../js/ui/screenShield.js:1195
|
||||
#: ../js/ui/screenShield.js:766 ../js/ui/screenShield.js:1202
|
||||
msgid "Lock was blocked by an application"
|
||||
msgstr "Programa užblokavo užrakinimą"
|
||||
|
||||
@ -1340,19 +1344,19 @@ msgstr "Ieškoma…"
|
||||
msgid "No results."
|
||||
msgstr "Nerasta atitikmenų."
|
||||
|
||||
#: ../js/ui/shellEntry.js:29
|
||||
#: ../js/ui/shellEntry.js:27
|
||||
msgid "Copy"
|
||||
msgstr "Kopijuoti"
|
||||
|
||||
#: ../js/ui/shellEntry.js:34
|
||||
#: ../js/ui/shellEntry.js:32
|
||||
msgid "Paste"
|
||||
msgstr "Įdėti"
|
||||
|
||||
#: ../js/ui/shellEntry.js:106
|
||||
#: ../js/ui/shellEntry.js:99
|
||||
msgid "Show Text"
|
||||
msgstr "Rodyti tekstą"
|
||||
|
||||
#: ../js/ui/shellEntry.js:108
|
||||
#: ../js/ui/shellEntry.js:101
|
||||
msgid "Hide Text"
|
||||
msgstr "Slėpti tekstą"
|
||||
|
||||
@ -1364,7 +1368,7 @@ msgstr "Slaptažodis"
|
||||
msgid "Remember Password"
|
||||
msgstr "Atsiminti slaptažodį"
|
||||
|
||||
#: ../js/ui/shellMountOperation.js:403 ../js/ui/unlockDialog.js:113
|
||||
#: ../js/ui/shellMountOperation.js:403 ../js/ui/unlockDialog.js:109
|
||||
msgid "Unlock"
|
||||
msgstr "Atrakinti"
|
||||
|
||||
@ -1533,11 +1537,12 @@ msgstr "Įveskite PIN, nurodytą įrenginyje."
|
||||
msgid "OK"
|
||||
msgstr "Gerai"
|
||||
|
||||
#: ../js/ui/status/keyboard.js:368
|
||||
#: ../js/ui/status/keyboard.js:396
|
||||
msgid "Show Keyboard Layout"
|
||||
msgstr "Rodyti klaviatūros išdėstymą"
|
||||
|
||||
#: ../js/ui/status/keyboard.js:373
|
||||
#: ../js/ui/status/keyboard.js:401
|
||||
#| msgid "Date & Time Settings"
|
||||
msgid "Region & Language Settings"
|
||||
msgstr "Regiono ir kalbos nustatymai"
|
||||
|
||||
@ -1655,7 +1660,7 @@ msgstr "Nepavyko prisijungti"
|
||||
msgid "Activation of network connection failed"
|
||||
msgstr "Tinklo ryšio nepavyko aktyvuoti"
|
||||
|
||||
#: ../js/ui/status/network.js:2276
|
||||
#: ../js/ui/status/network.js:2282
|
||||
msgid "Networking is disabled"
|
||||
msgstr "Tinklas išjungtas"
|
||||
|
||||
@ -1773,11 +1778,11 @@ msgstr "Garsumas"
|
||||
msgid "Microphone"
|
||||
msgstr "Mikrofonas"
|
||||
|
||||
#: ../js/ui/unlockDialog.js:124
|
||||
#: ../js/ui/unlockDialog.js:120
|
||||
msgid "Log in as another user"
|
||||
msgstr "Prisijungti kitu naudotoju"
|
||||
|
||||
#: ../js/ui/unlockDialog.js:145
|
||||
#: ../js/ui/unlockDialog.js:141
|
||||
msgid "Unlock Window"
|
||||
msgstr "Atrakinimo langas"
|
||||
|
||||
@ -1885,32 +1890,56 @@ msgstr "„%s“ yra pasirengusi"
|
||||
msgid "Evolution Calendar"
|
||||
msgstr "Evolution kalendorius"
|
||||
|
||||
#: ../src/main.c:347
|
||||
#. 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 išvestis"
|
||||
msgstr[1] "%u išvestys"
|
||||
msgstr[2] "%u išvesčių"
|
||||
|
||||
#. 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 įvestis"
|
||||
msgstr[1] "%u įvestys"
|
||||
msgstr[2] "%u įvesčių"
|
||||
|
||||
#: ../src/gvc/gvc-mixer-control.c:2373
|
||||
msgid "System Sounds"
|
||||
msgstr "Sistemos garsai"
|
||||
|
||||
#: ../src/main.c:328
|
||||
msgid "Print version"
|
||||
msgstr "Išvesti versijos numerį"
|
||||
|
||||
#: ../src/main.c:353
|
||||
#: ../src/main.c:334
|
||||
msgid "Mode used by GDM for login screen"
|
||||
msgstr "Veiksena, naudojama GDM prisijungimo ekrane"
|
||||
|
||||
#: ../src/main.c:359
|
||||
#: ../src/main.c:340
|
||||
msgid "Use a specific mode, e.g. \"gdm\" for login screen"
|
||||
msgstr "Naudoti konkrečią veikseną, pvz., „gdm“ prisijungimo ekranui"
|
||||
|
||||
#: ../src/main.c:365
|
||||
#: ../src/main.c:346
|
||||
msgid "List possible modes"
|
||||
msgstr "Išvardinti galimas veiksenas"
|
||||
|
||||
#: ../src/shell-app.c:622
|
||||
#: ../src/shell-app.c:640
|
||||
#, c-format
|
||||
msgid "Failed to launch '%s'"
|
||||
msgstr "Nepavyko paleisti „%s“"
|
||||
|
||||
#: ../src/shell-keyring-prompt.c:708
|
||||
#: ../src/shell-keyring-prompt.c:714
|
||||
msgid "Passwords do not match."
|
||||
msgstr "Slaptažodžiai nesutampa."
|
||||
|
||||
#: ../src/shell-keyring-prompt.c:716
|
||||
#: ../src/shell-keyring-prompt.c:722
|
||||
msgid "Password cannot be blank"
|
||||
msgstr "Slaptažodis negali būti tuščias"
|
||||
|
||||
@ -1918,17 +1947,17 @@ msgstr "Slaptažodis negali būti tuščias"
|
||||
msgid "Authentication dialog was dismissed by the user"
|
||||
msgstr "Naudotojas užvėrė tapatybės patvirtinimo dialogą"
|
||||
|
||||
#~ msgid "%u Output"
|
||||
#~ msgid_plural "%u Outputs"
|
||||
#~ msgstr[0] "%u išvestis"
|
||||
#~ msgstr[1] "%u išvestys"
|
||||
#~ msgstr[2] "%u išvesčių"
|
||||
#~ msgctxt "event list time"
|
||||
#~ msgid "%H∶%M"
|
||||
#~ msgstr "%H∶%M"
|
||||
|
||||
#~ msgid "%u Input"
|
||||
#~ msgid_plural "%u Inputs"
|
||||
#~ msgstr[0] "%u įvestis"
|
||||
#~ msgstr[1] "%u įvestys"
|
||||
#~ msgstr[2] "%u įvesčių"
|
||||
#~ msgctxt "event list time"
|
||||
#~ msgid "%l∶%M %p"
|
||||
#~ msgstr "%l∶%M"
|
||||
|
||||
#~ msgid "System Sounds"
|
||||
#~ msgstr "Sistemos garsai"
|
||||
#~ msgid "calendar:MY"
|
||||
#~ msgstr "calendar:YM"
|
||||
|
||||
#~| msgid "Network error"
|
||||
#~ msgid "Network"
|
||||
#~ msgstr "Tinklas"
|
||||
|
86
po/nb.po
86
po/nb.po
@ -8,7 +8,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: gnome-shell 3.8.x\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2013-04-03 13:31+0200\n"
|
||||
"POT-Creation-Date: 2013-05-13 09:47+0200\n"
|
||||
"PO-Revision-Date: 2013-04-03 13:31+0200\n"
|
||||
"Last-Translator: Kjartan Maraas <kmaraas@gnome.org>\n"
|
||||
"Language-Team: Norwegian bokmål <i18n-nb@lister.ping.uio.no>\n"
|
||||
@ -335,43 +335,50 @@ msgstr "Utvidelse"
|
||||
msgid "Select an extension to configure using the combobox above."
|
||||
msgstr "Velg en utvidelse som skal konfigureres med komboboksen over."
|
||||
|
||||
#: ../js/gdm/loginDialog.js:405
|
||||
#: ../js/gdm/loginDialog.js:371
|
||||
msgid "Session…"
|
||||
msgstr "Økt …"
|
||||
|
||||
#. translators: this message is shown below the user list on the
|
||||
#. login screen. It can be activated to reveal an entry for
|
||||
#. manually entering the username.
|
||||
#: ../js/gdm/loginDialog.js:630
|
||||
#: ../js/gdm/loginDialog.js:601
|
||||
msgid "Not listed?"
|
||||
msgstr "Ikke listet?"
|
||||
|
||||
#: ../js/gdm/loginDialog.js:786 ../js/ui/components/networkAgent.js:137
|
||||
#: ../js/ui/components/polkitAgent.js:162 ../js/ui/endSessionDialog.js:375
|
||||
#: ../js/gdm/loginDialog.js:776 ../js/ui/components/networkAgent.js:137
|
||||
#: ../js/ui/components/polkitAgent.js:162 ../js/ui/endSessionDialog.js:376
|
||||
#: ../js/ui/extensionDownloader.js:195 ../js/ui/shellMountOperation.js:399
|
||||
#: ../js/ui/status/bluetooth.js:415 ../js/ui/unlockDialog.js:99
|
||||
#: ../js/ui/status/bluetooth.js:415 ../js/ui/unlockDialog.js:96
|
||||
#: ../js/ui/userMenu.js:938
|
||||
msgid "Cancel"
|
||||
msgstr "Avbryt"
|
||||
|
||||
#: ../js/gdm/loginDialog.js:802
|
||||
#: ../js/gdm/loginDialog.js:791
|
||||
msgctxt "button"
|
||||
msgid "Sign In"
|
||||
msgstr "Logg inn"
|
||||
|
||||
#: ../js/gdm/loginDialog.js:802
|
||||
#: ../js/gdm/loginDialog.js:791
|
||||
msgid "Next"
|
||||
msgstr "Neste"
|
||||
|
||||
#. Translators: this message is shown below the username entry field
|
||||
#. to clue the user in on how to login to the local network realm
|
||||
#: ../js/gdm/loginDialog.js: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
|
||||
#. is not visible here since we only care about phase2 authentication
|
||||
#. (and don't even care of which one)
|
||||
#: ../js/gdm/loginDialog.js:917 ../js/ui/components/networkAgent.js:260
|
||||
#: ../js/gdm/loginDialog.js:892 ../js/ui/components/networkAgent.js:260
|
||||
#: ../js/ui/components/networkAgent.js:278
|
||||
msgid "Username: "
|
||||
msgstr "Brukernavn: "
|
||||
|
||||
#: ../js/gdm/loginDialog.js:1173
|
||||
#: ../js/gdm/loginDialog.js:1158
|
||||
msgid "Login Window"
|
||||
msgstr "Innloggingsvindu"
|
||||
|
||||
@ -394,21 +401,16 @@ msgstr "Start på nytt"
|
||||
msgid "Power Off"
|
||||
msgstr "Slå av"
|
||||
|
||||
#: ../js/gdm/util.js:249
|
||||
#: ../js/gdm/util.js:247
|
||||
msgid "Authentication error"
|
||||
msgstr "Autentiseringsfeil"
|
||||
|
||||
#. Translators: this message is shown below the password entry field
|
||||
#. to indicate the user can swipe their finger instead
|
||||
#: ../js/gdm/util.js:366
|
||||
#: ../js/gdm/util.js:364
|
||||
msgid "(or swipe 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
|
||||
msgid "Command not found"
|
||||
msgstr "Kommando ikke funnet"
|
||||
@ -632,11 +634,11 @@ msgstr "Åpne med %s"
|
||||
msgid "Eject"
|
||||
msgstr "Løs ut"
|
||||
|
||||
#: ../js/ui/components/keyring.js:82 ../js/ui/components/polkitAgent.js:268
|
||||
#: ../js/ui/components/keyring.js:88 ../js/ui/components/polkitAgent.js:275
|
||||
msgid "Password:"
|
||||
msgstr "Passord:"
|
||||
|
||||
#: ../js/ui/components/keyring.js:101
|
||||
#: ../js/ui/components/keyring.js:107
|
||||
msgid "Type again:"
|
||||
msgstr "Skriv på nytt:"
|
||||
|
||||
@ -724,7 +726,7 @@ msgstr "Autentisering kreves"
|
||||
msgid "Administrator"
|
||||
msgstr "Administrator"
|
||||
|
||||
#: ../js/ui/components/polkitAgent.js:165
|
||||
#: ../js/ui/components/polkitAgent.js:171
|
||||
msgid "Authenticate"
|
||||
msgstr "Autentiser"
|
||||
|
||||
@ -732,12 +734,12 @@ msgstr "Autentiser"
|
||||
#. * requested authentication was not gained; this can happen
|
||||
#. * because of an authentication error (like invalid password),
|
||||
#. * for instance.
|
||||
#: ../js/ui/components/polkitAgent.js:256 ../js/ui/shellMountOperation.js:383
|
||||
#: ../js/ui/components/polkitAgent.js:263 ../js/ui/shellMountOperation.js:383
|
||||
msgid "Sorry, that didn't work. Please try again."
|
||||
msgstr "Beklager, det virket ikke. Vennligst prøv igjen."
|
||||
|
||||
#. Translators: this is a filename used for screencast recording
|
||||
#: ../js/ui/components/recorder.js:48
|
||||
#: ../js/ui/components/recorder.js:47
|
||||
#, no-c-format
|
||||
msgid "Screencast from %d %t"
|
||||
msgstr "Skjermvideo fra %d %t"
|
||||
@ -1003,14 +1005,14 @@ msgstr "Åpne kalender"
|
||||
msgid "Open Clocks"
|
||||
msgstr "Åpne Klokker"
|
||||
|
||||
#: ../js/ui/dateMenu.js:105
|
||||
#: ../js/ui/dateMenu.js:104
|
||||
msgid "Date & Time Settings"
|
||||
msgstr "Innstillinger for dato og klokkeslett"
|
||||
|
||||
#. Translators: This is the date format to use when the calendar popup is
|
||||
#. * shown - it is shown just below the time in the shell (e.g. "Tue 9:29 AM").
|
||||
#.
|
||||
#: ../js/ui/dateMenu.js:215
|
||||
#: ../js/ui/dateMenu.js:216
|
||||
msgid "%A %B %e, %Y"
|
||||
msgstr "%a %e %B, %Y"
|
||||
|
||||
@ -1188,11 +1190,11 @@ msgstr "Innstillinger for varsling"
|
||||
msgid "No Messages"
|
||||
msgstr "Ingen meldinger"
|
||||
|
||||
#: ../js/ui/messageTray.js:1782
|
||||
#: ../js/ui/messageTray.js:1785
|
||||
msgid "Message Tray"
|
||||
msgstr "Meldingstrau"
|
||||
|
||||
#: ../js/ui/messageTray.js:2810
|
||||
#: ../js/ui/messageTray.js:2813
|
||||
msgid "System Information"
|
||||
msgstr "Systeminformasjon"
|
||||
|
||||
@ -1224,17 +1226,17 @@ msgstr "Oversikt"
|
||||
msgid "Type to search…"
|
||||
msgstr "Skriv for å søke …"
|
||||
|
||||
#: ../js/ui/panel.js:612
|
||||
#: ../js/ui/panel.js:635
|
||||
msgid "Quit"
|
||||
msgstr "Avslutt"
|
||||
|
||||
#. Translators: If there is no suitable word for "Activities"
|
||||
#. in your language, you can use the word for "Overview".
|
||||
#: ../js/ui/panel.js:636
|
||||
#: ../js/ui/panel.js:686
|
||||
msgid "Activities"
|
||||
msgstr "Aktiviteter"
|
||||
|
||||
#: ../js/ui/panel.js:933
|
||||
#: ../js/ui/panel.js:982
|
||||
msgid "Top Bar"
|
||||
msgstr "Topp-panel"
|
||||
|
||||
@ -1247,11 +1249,11 @@ msgstr "Topp-panel"
|
||||
msgid "toggle-switch-us"
|
||||
msgstr "toggle-switch-intl"
|
||||
|
||||
#: ../js/ui/runDialog.js:73
|
||||
#: ../js/ui/runDialog.js:74
|
||||
msgid "Enter a Command"
|
||||
msgstr "Oppgi en kommando"
|
||||
|
||||
#: ../js/ui/runDialog.js:109
|
||||
#: ../js/ui/runDialog.js:110
|
||||
msgid "Close"
|
||||
msgstr "Lukk"
|
||||
|
||||
@ -1272,7 +1274,7 @@ msgstr[1] "%d nye varslinger"
|
||||
msgid "Lock"
|
||||
msgstr "Lås"
|
||||
|
||||
#: ../js/ui/screenShield.js:640
|
||||
#: ../js/ui/screenShield.js:641
|
||||
msgid "GNOME needs to lock the screen"
|
||||
msgstr "GNOME må låse skjermen"
|
||||
|
||||
@ -1283,11 +1285,11 @@ msgstr "GNOME må låse skjermen"
|
||||
#.
|
||||
#. XXX: another option is to kick the user into the gdm login
|
||||
#. screen, where we're not affected by grabs
|
||||
#: ../js/ui/screenShield.js:761 ../js/ui/screenShield.js:1197
|
||||
#: ../js/ui/screenShield.js:762 ../js/ui/screenShield.js:1198
|
||||
msgid "Unable to lock"
|
||||
msgstr "Kan ikke låse"
|
||||
|
||||
#: ../js/ui/screenShield.js:762 ../js/ui/screenShield.js:1198
|
||||
#: ../js/ui/screenShield.js:763 ../js/ui/screenShield.js:1199
|
||||
msgid "Lock was blocked by an application"
|
||||
msgstr "Låsing ble stoppet av et program"
|
||||
|
||||
@ -1307,11 +1309,11 @@ msgstr "Kopier"
|
||||
msgid "Paste"
|
||||
msgstr "Lim inn"
|
||||
|
||||
#: ../js/ui/shellEntry.js:106
|
||||
#: ../js/ui/shellEntry.js:101
|
||||
msgid "Show Text"
|
||||
msgstr "Vis tekst"
|
||||
|
||||
#: ../js/ui/shellEntry.js:108
|
||||
#: ../js/ui/shellEntry.js:103
|
||||
msgid "Hide Text"
|
||||
msgstr "Skjul tekst"
|
||||
|
||||
@ -1323,7 +1325,7 @@ msgstr "Passord"
|
||||
msgid "Remember Password"
|
||||
msgstr "Husk passord"
|
||||
|
||||
#: ../js/ui/shellMountOperation.js:403 ../js/ui/unlockDialog.js:113
|
||||
#: ../js/ui/shellMountOperation.js:403 ../js/ui/unlockDialog.js:109
|
||||
msgid "Unlock"
|
||||
msgstr "Lås opp"
|
||||
|
||||
@ -1614,7 +1616,7 @@ msgstr "Tilkobling feilet"
|
||||
msgid "Activation of network connection failed"
|
||||
msgstr "Aktivering av nettverkstilkobling feilet"
|
||||
|
||||
#: ../js/ui/status/network.js:2276
|
||||
#: ../js/ui/status/network.js:2282
|
||||
msgid "Networking is disabled"
|
||||
msgstr "Nettverk er slått av"
|
||||
|
||||
@ -1728,11 +1730,11 @@ msgstr "Volum"
|
||||
msgid "Microphone"
|
||||
msgstr "Mikrofon"
|
||||
|
||||
#: ../js/ui/unlockDialog.js:124
|
||||
#: ../js/ui/unlockDialog.js:120
|
||||
msgid "Log in as another user"
|
||||
msgstr "Logg inn som en annen bruker"
|
||||
|
||||
#: ../js/ui/unlockDialog.js:145
|
||||
#: ../js/ui/unlockDialog.js:141
|
||||
msgid "Unlock Window"
|
||||
msgstr "Lås opp vindu"
|
||||
|
||||
@ -1885,11 +1887,11 @@ msgstr "Vis mulige modi"
|
||||
msgid "Failed to launch '%s'"
|
||||
msgstr "Klarte ikke å starte «%s»"
|
||||
|
||||
#: ../src/shell-keyring-prompt.c:708
|
||||
#: ../src/shell-keyring-prompt.c:714
|
||||
msgid "Passwords do not match."
|
||||
msgstr "Passordene er ikke like."
|
||||
|
||||
#: ../src/shell-keyring-prompt.c:716
|
||||
#: ../src/shell-keyring-prompt.c:722
|
||||
msgid "Password cannot be blank"
|
||||
msgstr "Passordet kan ikke være tomt"
|
||||
|
||||
|
569
po/pt_BR.po
569
po/pt_BR.po
File diff suppressed because it is too large
Load Diff
522
po/sr@latin.po
522
po/sr@latin.po
File diff suppressed because it is too large
Load Diff
1027
po/zh_CN.po
1027
po/zh_CN.po
File diff suppressed because it is too large
Load Diff
214
po/zh_HK.po
214
po/zh_HK.po
@ -9,15 +9,16 @@ msgstr ""
|
||||
"Project-Id-Version: gnome-shell 3.3.90\n"
|
||||
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-"
|
||||
"shell&keywords=I18N+L10N&component=general\n"
|
||||
"POT-Creation-Date: 2013-03-04 08:38+0000\n"
|
||||
"PO-Revision-Date: 2013-03-06 19:06+0800\n"
|
||||
"Last-Translator: Chao-Hsiung Liao <j_h_liau@yahoo.com.tw>\n"
|
||||
"POT-Creation-Date: 2013-05-31 18:55+0000\n"
|
||||
"PO-Revision-Date: 2013-06-04 21:50+0800\n"
|
||||
"Last-Translator: Cheng-Chia Tseng <pswo10680@gmail.com>\n"
|
||||
"Language-Team: Chinese (Hong Kong) <community@linuxhall.org>\n"
|
||||
"Language: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=1; plural=0;\n"
|
||||
"X-Generator: Poedit 1.5.3\n"
|
||||
"X-Generator: Poedit 1.5.4\n"
|
||||
|
||||
#: ../data/50-gnome-shell-screenshot.xml.in.h:1
|
||||
msgid "Screenshots"
|
||||
@ -313,44 +314,50 @@ msgstr "擴充功能"
|
||||
msgid "Select an extension to configure using the combobox above."
|
||||
msgstr "使用上面的組合方塊選擇要設定的擴充功能。"
|
||||
|
||||
#: ../js/gdm/loginDialog.js:405
|
||||
#| msgid "Session..."
|
||||
#: ../js/gdm/loginDialog.js:371
|
||||
msgid "Session…"
|
||||
msgstr "作業階段…"
|
||||
|
||||
#. translators: this message is shown below the user list on the
|
||||
#. login screen. It can be activated to reveal an entry for
|
||||
#. manually entering the username.
|
||||
#: ../js/gdm/loginDialog.js:629
|
||||
#: ../js/gdm/loginDialog.js:601
|
||||
msgid "Not listed?"
|
||||
msgstr "沒有列出來?"
|
||||
|
||||
#: ../js/gdm/loginDialog.js:783 ../js/ui/components/networkAgent.js:137
|
||||
#: ../js/ui/components/polkitAgent.js:162 ../js/ui/endSessionDialog.js:375
|
||||
#: ../js/gdm/loginDialog.js:776 ../js/ui/components/networkAgent.js:137
|
||||
#: ../js/ui/components/polkitAgent.js:161 ../js/ui/endSessionDialog.js:376
|
||||
#: ../js/ui/extensionDownloader.js:195 ../js/ui/shellMountOperation.js:399
|
||||
#: ../js/ui/status/bluetooth.js:415 ../js/ui/unlockDialog.js:126
|
||||
#: ../js/ui/userMenu.js:934
|
||||
#: ../js/ui/status/bluetooth.js:415 ../js/ui/unlockDialog.js:96
|
||||
#: ../js/ui/userMenu.js:938
|
||||
msgid "Cancel"
|
||||
msgstr "取消"
|
||||
|
||||
#: ../js/gdm/loginDialog.js:799
|
||||
#: ../js/gdm/loginDialog.js:791
|
||||
msgctxt "button"
|
||||
msgid "Sign In"
|
||||
msgstr "登入"
|
||||
|
||||
#: ../js/gdm/loginDialog.js:799
|
||||
#: ../js/gdm/loginDialog.js:791
|
||||
msgid "Next"
|
||||
msgstr "下一個"
|
||||
|
||||
#. Translators: this message is shown below the username entry field
|
||||
#. to clue the user in on how to login to the local network realm
|
||||
#: ../js/gdm/loginDialog.js:888
|
||||
#, c-format
|
||||
msgid "(e.g., user or %s)"
|
||||
msgstr "(例如: user 或 %s)"
|
||||
|
||||
#. TTLS and PEAP are actually much more complicated, but this complication
|
||||
#. is not visible here since we only care about phase2 authentication
|
||||
#. (and don't even care of which one)
|
||||
#: ../js/gdm/loginDialog.js:904 ../js/ui/components/networkAgent.js:260
|
||||
#: ../js/gdm/loginDialog.js:892 ../js/ui/components/networkAgent.js:260
|
||||
#: ../js/ui/components/networkAgent.js:278
|
||||
msgid "Username: "
|
||||
msgstr "使用者名稱:"
|
||||
|
||||
#: ../js/gdm/loginDialog.js:1157
|
||||
#: ../js/gdm/loginDialog.js:1158
|
||||
msgid "Login Window"
|
||||
msgstr "登入視窗"
|
||||
|
||||
@ -359,8 +366,8 @@ msgstr "登入視窗"
|
||||
msgid "Power"
|
||||
msgstr "電源"
|
||||
|
||||
#: ../js/gdm/powerMenu.js:93 ../js/ui/userMenu.js:695 ../js/ui/userMenu.js:699
|
||||
#: ../js/ui/userMenu.js:815
|
||||
#: ../js/gdm/powerMenu.js:93 ../js/ui/userMenu.js:696 ../js/ui/userMenu.js:700
|
||||
#: ../js/ui/userMenu.js:816
|
||||
msgid "Suspend"
|
||||
msgstr "暫停"
|
||||
|
||||
@ -368,58 +375,53 @@ msgstr "暫停"
|
||||
msgid "Restart"
|
||||
msgstr "重新啟動"
|
||||
|
||||
#: ../js/gdm/powerMenu.js:103 ../js/ui/userMenu.js:697
|
||||
#: ../js/ui/userMenu.js:699 ../js/ui/userMenu.js:814 ../js/ui/userMenu.js:938
|
||||
#: ../js/gdm/powerMenu.js:103 ../js/ui/userMenu.js:698
|
||||
#: ../js/ui/userMenu.js:700 ../js/ui/userMenu.js:815 ../js/ui/userMenu.js:942
|
||||
msgid "Power Off"
|
||||
msgstr "關閉電源"
|
||||
|
||||
#: ../js/gdm/util.js:182
|
||||
#: ../js/gdm/util.js:247
|
||||
msgid "Authentication error"
|
||||
msgstr "驗證錯誤"
|
||||
|
||||
#. Translators: this message is shown below the password entry field
|
||||
#. to indicate the user can swipe their finger instead
|
||||
#: ../js/gdm/util.js:299
|
||||
#: ../js/gdm/util.js:364
|
||||
msgid "(or swipe finger)"
|
||||
msgstr "(或是滑過手指)"
|
||||
|
||||
#: ../js/gdm/util.js:324
|
||||
#, c-format
|
||||
msgid "(e.g., user or %s)"
|
||||
msgstr "(例如: user 或 %s)"
|
||||
|
||||
#: ../js/misc/util.js:94
|
||||
#: ../js/misc/util.js:97
|
||||
msgid "Command not found"
|
||||
msgstr "找不到指令"
|
||||
|
||||
#. Replace "Error invoking GLib.shell_parse_argv: " with
|
||||
#. something nicer
|
||||
#: ../js/misc/util.js:127
|
||||
#: ../js/misc/util.js:130
|
||||
msgid "Could not parse command:"
|
||||
msgstr "無法分析指令:"
|
||||
|
||||
#: ../js/misc/util.js:135
|
||||
#: ../js/misc/util.js:138
|
||||
#, c-format
|
||||
msgid "Execution of '%s' failed:"
|
||||
msgstr "執行「%s」失敗:"
|
||||
|
||||
#: ../js/ui/appDisplay.js:348
|
||||
#: ../js/ui/appDisplay.js:356
|
||||
msgid "Frequent"
|
||||
msgstr "頻率"
|
||||
msgstr "常用"
|
||||
|
||||
#: ../js/ui/appDisplay.js:355
|
||||
#: ../js/ui/appDisplay.js:363
|
||||
msgid "All"
|
||||
msgstr "全部"
|
||||
|
||||
#: ../js/ui/appDisplay.js:913
|
||||
#: ../js/ui/appDisplay.js:941
|
||||
msgid "New Window"
|
||||
msgstr "新視窗"
|
||||
|
||||
#: ../js/ui/appDisplay.js:916 ../js/ui/dash.js:284
|
||||
#: ../js/ui/appDisplay.js:944 ../js/ui/dash.js:284
|
||||
msgid "Remove from Favorites"
|
||||
msgstr "自喜好中移除"
|
||||
|
||||
#: ../js/ui/appDisplay.js:917
|
||||
#: ../js/ui/appDisplay.js:945
|
||||
msgid "Add to Favorites"
|
||||
msgstr "加入喜好"
|
||||
|
||||
@ -433,7 +435,7 @@ msgstr "%s 已加入你的喜好中。"
|
||||
msgid "%s has been removed from your favorites."
|
||||
msgstr "%s 已經從你的喜好中移除。"
|
||||
|
||||
#: ../js/ui/backgroundMenu.js:19 ../js/ui/userMenu.js:788
|
||||
#: ../js/ui/backgroundMenu.js:19 ../js/ui/userMenu.js:789
|
||||
msgid "Settings"
|
||||
msgstr "設定值"
|
||||
|
||||
@ -456,7 +458,7 @@ msgctxt "event list time"
|
||||
msgid "%H\\u2236%M"
|
||||
msgstr "%H\\u2236%M"
|
||||
|
||||
#. Transators: Shown in calendar event list, if 12h format,
|
||||
#. Translators: Shown in calendar event list, if 12h format,
|
||||
#. \u2236 is a ratio character, similar to : and \u2009 is
|
||||
#. a thin space
|
||||
#: ../js/ui/calendar.js:77
|
||||
@ -558,35 +560,35 @@ msgid "S"
|
||||
msgstr "六"
|
||||
|
||||
#. Translators: Text to show if there are no events
|
||||
#: ../js/ui/calendar.js:692
|
||||
#: ../js/ui/calendar.js:720
|
||||
msgid "Nothing Scheduled"
|
||||
msgstr "沒有預訂行程"
|
||||
|
||||
#. Translators: Shown on calendar heading when selected day occurs on current year
|
||||
#: ../js/ui/calendar.js:708
|
||||
#: ../js/ui/calendar.js:736
|
||||
msgctxt "calendar heading"
|
||||
msgid "%A, %B %d"
|
||||
msgstr "%m月%d日%A"
|
||||
|
||||
#. Translators: Shown on calendar heading when selected day occurs on different year
|
||||
#: ../js/ui/calendar.js:711
|
||||
#: ../js/ui/calendar.js:739
|
||||
msgctxt "calendar heading"
|
||||
msgid "%A, %B %d, %Y"
|
||||
msgstr "%Y年%m月%d日%A"
|
||||
|
||||
#: ../js/ui/calendar.js:721
|
||||
#: ../js/ui/calendar.js:749
|
||||
msgid "Today"
|
||||
msgstr "今天"
|
||||
|
||||
#: ../js/ui/calendar.js:725
|
||||
#: ../js/ui/calendar.js:753
|
||||
msgid "Tomorrow"
|
||||
msgstr "明天"
|
||||
|
||||
#: ../js/ui/calendar.js:736
|
||||
#: ../js/ui/calendar.js:764
|
||||
msgid "This week"
|
||||
msgstr "本週"
|
||||
|
||||
#: ../js/ui/calendar.js:744
|
||||
#: ../js/ui/calendar.js:772
|
||||
msgid "Next week"
|
||||
msgstr "下週"
|
||||
|
||||
@ -602,20 +604,20 @@ msgstr "外部裝置已拔除"
|
||||
msgid "Removable Devices"
|
||||
msgstr "可移除式裝置"
|
||||
|
||||
#: ../js/ui/components/autorunManager.js:593
|
||||
#: ../js/ui/components/autorunManager.js:594
|
||||
#, c-format
|
||||
msgid "Open with %s"
|
||||
msgstr "用 %s 開啟"
|
||||
|
||||
#: ../js/ui/components/autorunManager.js:619
|
||||
#: ../js/ui/components/autorunManager.js:620
|
||||
msgid "Eject"
|
||||
msgstr "退出"
|
||||
|
||||
#: ../js/ui/components/keyring.js:82 ../js/ui/components/polkitAgent.js:268
|
||||
#: ../js/ui/components/keyring.js:88 ../js/ui/components/polkitAgent.js:280
|
||||
msgid "Password:"
|
||||
msgstr "密碼: "
|
||||
|
||||
#: ../js/ui/components/keyring.js:101
|
||||
#: ../js/ui/components/keyring.js:107
|
||||
msgid "Type again:"
|
||||
msgstr "再輸入一次:"
|
||||
|
||||
@ -693,15 +695,15 @@ msgstr "流動寬頻網絡密碼"
|
||||
msgid "A password is required to connect to '%s'."
|
||||
msgstr "連線至「%s」需要密碼。"
|
||||
|
||||
#: ../js/ui/components/polkitAgent.js:55
|
||||
#: ../js/ui/components/polkitAgent.js:54
|
||||
msgid "Authentication Required"
|
||||
msgstr "要求驗證"
|
||||
|
||||
#: ../js/ui/components/polkitAgent.js:93
|
||||
#: ../js/ui/components/polkitAgent.js:92
|
||||
msgid "Administrator"
|
||||
msgstr "系統管理員"
|
||||
|
||||
#: ../js/ui/components/polkitAgent.js:165
|
||||
#: ../js/ui/components/polkitAgent.js:170
|
||||
msgid "Authenticate"
|
||||
msgstr "驗證"
|
||||
|
||||
@ -709,12 +711,12 @@ msgstr "驗證"
|
||||
#. * requested authentication was not gained; this can happen
|
||||
#. * because of an authentication error (like invalid password),
|
||||
#. * for instance.
|
||||
#: ../js/ui/components/polkitAgent.js:256 ../js/ui/shellMountOperation.js:383
|
||||
#: ../js/ui/components/polkitAgent.js:266 ../js/ui/shellMountOperation.js:383
|
||||
msgid "Sorry, that didn't work. Please try again."
|
||||
msgstr "抱歉,那樣無法運作。請再試一次。"
|
||||
|
||||
#. Translators: this is a filename used for screencast recording
|
||||
#: ../js/ui/components/recorder.js:48
|
||||
#: ../js/ui/components/recorder.js:47
|
||||
#, no-c-format
|
||||
msgid "Screencast from %d %t"
|
||||
msgstr "Screencast from %d %t"
|
||||
@ -976,14 +978,14 @@ msgstr "開啟行事曆"
|
||||
msgid "Open Clocks"
|
||||
msgstr "開啟時鐘"
|
||||
|
||||
#: ../js/ui/dateMenu.js:105
|
||||
#: ../js/ui/dateMenu.js:104
|
||||
msgid "Date & Time Settings"
|
||||
msgstr "日期與時刻設定值"
|
||||
|
||||
#. Translators: This is the date format to use when the calendar popup is
|
||||
#. * shown - it is shown just below the time in the shell (e.g. "Tue 9:29 AM").
|
||||
#.
|
||||
#: ../js/ui/dateMenu.js:205
|
||||
#: ../js/ui/dateMenu.js:216
|
||||
msgid "%A %B %e, %Y"
|
||||
msgstr "%Y年%m月%e日%A"
|
||||
|
||||
@ -1080,7 +1082,7 @@ msgstr "安裝"
|
||||
msgid "Download and install '%s' from extensions.gnome.org?"
|
||||
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:333
|
||||
#: ../js/ui/status/power.js:211
|
||||
msgid "Keyboard"
|
||||
msgstr "鍵盤"
|
||||
@ -1142,7 +1144,6 @@ msgid "Remove"
|
||||
msgstr "移除"
|
||||
|
||||
#: ../js/ui/messageTray.js:1501
|
||||
#| msgid "No Messages"
|
||||
msgid "Clear Messages"
|
||||
msgstr "清除訊息"
|
||||
|
||||
@ -1150,15 +1151,15 @@ msgstr "清除訊息"
|
||||
msgid "Notification Settings"
|
||||
msgstr "通知設定值"
|
||||
|
||||
#: ../js/ui/messageTray.js:1707
|
||||
#: ../js/ui/messageTray.js:1709
|
||||
msgid "No Messages"
|
||||
msgstr "沒有訊息"
|
||||
|
||||
#: ../js/ui/messageTray.js:1787
|
||||
#: ../js/ui/messageTray.js:1785
|
||||
msgid "Message Tray"
|
||||
msgstr "訊息匣"
|
||||
|
||||
#: ../js/ui/messageTray.js:2864
|
||||
#: ../js/ui/messageTray.js:2818
|
||||
msgid "System Information"
|
||||
msgstr "系統資訊"
|
||||
|
||||
@ -1167,13 +1168,13 @@ msgctxt "program"
|
||||
msgid "Unknown"
|
||||
msgstr "不明"
|
||||
|
||||
#: ../js/ui/overviewControls.js:460 ../js/ui/screenShield.js:153
|
||||
#: ../js/ui/overviewControls.js:463 ../js/ui/screenShield.js:149
|
||||
#, c-format
|
||||
msgid "%d new message"
|
||||
msgid_plural "%d new messages"
|
||||
msgstr[0] "%d 個新訊息"
|
||||
|
||||
#: ../js/ui/overview.js:82
|
||||
#: ../js/ui/overview.js:84
|
||||
msgid "Undo"
|
||||
msgstr "復原"
|
||||
|
||||
@ -1185,22 +1186,21 @@ msgstr "概覽"
|
||||
#. in the search entry when no search is
|
||||
#. active; it should not exceed ~30
|
||||
#. characters.
|
||||
#: ../js/ui/overview.js:284
|
||||
#| msgid "Type to search..."
|
||||
#: ../js/ui/overview.js:271
|
||||
msgid "Type to search…"
|
||||
msgstr "輸入以搜尋…"
|
||||
|
||||
#: ../js/ui/panel.js:613
|
||||
#: ../js/ui/panel.js:635
|
||||
msgid "Quit"
|
||||
msgstr "結束"
|
||||
|
||||
#. Translators: If there is no suitable word for "Activities"
|
||||
#. in your language, you can use the word for "Overview".
|
||||
#: ../js/ui/panel.js:642
|
||||
#: ../js/ui/panel.js:686
|
||||
msgid "Activities"
|
||||
msgstr "概覽 "
|
||||
|
||||
#: ../js/ui/panel.js:983
|
||||
#: ../js/ui/panel.js:982
|
||||
msgid "Top Bar"
|
||||
msgstr "頂端列"
|
||||
|
||||
@ -1209,35 +1209,35 @@ msgstr "頂端列"
|
||||
#. "ON" and "OFF") or "toggle-switch-intl" (for toggle
|
||||
#. switches containing "◯" and "|"). Other values will
|
||||
#. simply result in invisible toggle switches.
|
||||
#: ../js/ui/popupMenu.js:727
|
||||
#: ../js/ui/popupMenu.js:740
|
||||
msgid "toggle-switch-us"
|
||||
msgstr "toggle-switch-us"
|
||||
|
||||
#: ../js/ui/runDialog.js:205
|
||||
#: ../js/ui/runDialog.js:74
|
||||
msgid "Enter a Command"
|
||||
msgstr "請輸入指令"
|
||||
|
||||
#: ../js/ui/runDialog.js:241
|
||||
#: ../js/ui/runDialog.js:110
|
||||
msgid "Close"
|
||||
msgstr "關閉"
|
||||
|
||||
#. Translators: This is a time format for a date in
|
||||
#. long format
|
||||
#: ../js/ui/screenShield.js:90
|
||||
#: ../js/ui/screenShield.js:86
|
||||
msgid "%A, %B %d"
|
||||
msgstr "%m月%d日%A"
|
||||
|
||||
#: ../js/ui/screenShield.js:155
|
||||
#: ../js/ui/screenShield.js:151
|
||||
#, c-format
|
||||
msgid "%d new notification"
|
||||
msgid_plural "%d new notifications"
|
||||
msgstr[0] "%d 個新通知"
|
||||
|
||||
#: ../js/ui/screenShield.js:442 ../js/ui/userMenu.js:806
|
||||
#: ../js/ui/screenShield.js:438 ../js/ui/userMenu.js:807
|
||||
msgid "Lock"
|
||||
msgstr "鎖定"
|
||||
|
||||
#: ../js/ui/screenShield.js:639
|
||||
#: ../js/ui/screenShield.js:641
|
||||
msgid "GNOME needs to lock the screen"
|
||||
msgstr "GNOME 需要鎖定螢幕"
|
||||
|
||||
@ -1248,37 +1248,35 @@ msgstr "GNOME 需要鎖定螢幕"
|
||||
#.
|
||||
#. XXX: another option is to kick the user into the gdm login
|
||||
#. screen, where we're not affected by grabs
|
||||
#: ../js/ui/screenShield.js:758 ../js/ui/screenShield.js:1169
|
||||
#| msgid "Unable to connect to %s"
|
||||
#: ../js/ui/screenShield.js:762 ../js/ui/screenShield.js:1198
|
||||
msgid "Unable to lock"
|
||||
msgstr "無法鎖定"
|
||||
|
||||
#: ../js/ui/screenShield.js:759 ../js/ui/screenShield.js:1170
|
||||
#: ../js/ui/screenShield.js:763 ../js/ui/screenShield.js:1199
|
||||
msgid "Lock was blocked by an application"
|
||||
msgstr "鎖定被應用程式阻擋"
|
||||
|
||||
#: ../js/ui/searchDisplay.js:431
|
||||
#| msgid "Searching..."
|
||||
#: ../js/ui/searchDisplay.js:453
|
||||
msgid "Searching…"
|
||||
msgstr "搜尋…"
|
||||
|
||||
#: ../js/ui/searchDisplay.js:475
|
||||
#: ../js/ui/searchDisplay.js:497
|
||||
msgid "No results."
|
||||
msgstr "沒有結果。"
|
||||
|
||||
#: ../js/ui/shellEntry.js:29
|
||||
#: ../js/ui/shellEntry.js:27
|
||||
msgid "Copy"
|
||||
msgstr "複製"
|
||||
|
||||
#: ../js/ui/shellEntry.js:34
|
||||
#: ../js/ui/shellEntry.js:32
|
||||
msgid "Paste"
|
||||
msgstr "貼上"
|
||||
|
||||
#: ../js/ui/shellEntry.js:105
|
||||
#: ../js/ui/shellEntry.js:99
|
||||
msgid "Show Text"
|
||||
msgstr "顯示文字"
|
||||
|
||||
#: ../js/ui/shellEntry.js:107
|
||||
#: ../js/ui/shellEntry.js:101
|
||||
msgid "Hide Text"
|
||||
msgstr "隱藏文字"
|
||||
|
||||
@ -1290,7 +1288,7 @@ msgstr "密碼"
|
||||
msgid "Remember Password"
|
||||
msgstr "記住密碼"
|
||||
|
||||
#: ../js/ui/shellMountOperation.js:403 ../js/ui/unlockDialog.js:140
|
||||
#: ../js/ui/shellMountOperation.js:403 ../js/ui/unlockDialog.js:109
|
||||
msgid "Unlock"
|
||||
msgstr "解鎖"
|
||||
|
||||
@ -1354,12 +1352,10 @@ msgid "Visibility"
|
||||
msgstr "顯示狀態"
|
||||
|
||||
#: ../js/ui/status/bluetooth.js:59
|
||||
#| msgid "Send Files to Device..."
|
||||
msgid "Send Files to Device…"
|
||||
msgstr "傳送檔案到裝置…"
|
||||
|
||||
#: ../js/ui/status/bluetooth.js:60
|
||||
#| msgid "Set Up a New Device..."
|
||||
msgid "Set Up a New Device…"
|
||||
msgstr "設定新的裝置…"
|
||||
|
||||
@ -1386,7 +1382,6 @@ msgid "connecting..."
|
||||
msgstr "連線中…"
|
||||
|
||||
#: ../js/ui/status/bluetooth.js:239
|
||||
#| msgid "Send Files..."
|
||||
msgid "Send Files…"
|
||||
msgstr "傳送檔案…"
|
||||
|
||||
@ -1462,11 +1457,11 @@ msgstr "請輸入裝置所提及的 PIN。"
|
||||
msgid "OK"
|
||||
msgstr "確定"
|
||||
|
||||
#: ../js/ui/status/keyboard.js:368
|
||||
#: ../js/ui/status/keyboard.js:396
|
||||
msgid "Show Keyboard Layout"
|
||||
msgstr "顯示鍵盤配置"
|
||||
|
||||
#: ../js/ui/status/keyboard.js:373
|
||||
#: ../js/ui/status/keyboard.js:401
|
||||
msgid "Region & Language Settings"
|
||||
msgstr "地區和語言設定值"
|
||||
|
||||
@ -1584,7 +1579,7 @@ msgstr "連線失敗"
|
||||
msgid "Activation of network connection failed"
|
||||
msgstr "啟動網絡連線失敗"
|
||||
|
||||
#: ../js/ui/status/network.js:2276
|
||||
#: ../js/ui/status/network.js:2282
|
||||
msgid "Networking is disabled"
|
||||
msgstr "網絡已停用"
|
||||
|
||||
@ -1599,7 +1594,6 @@ msgstr "電源設定值"
|
||||
#. 0 is reported when UPower does not have enough data
|
||||
#. to estimate battery life
|
||||
#: ../js/ui/status/power.js:99
|
||||
#| msgid "Estimating..."
|
||||
msgid "Estimating…"
|
||||
msgstr "評估中…"
|
||||
|
||||
@ -1695,11 +1689,11 @@ msgstr "音量"
|
||||
msgid "Microphone"
|
||||
msgstr "麥克風"
|
||||
|
||||
#: ../js/ui/unlockDialog.js:151
|
||||
#: ../js/ui/unlockDialog.js:120
|
||||
msgid "Log in as another user"
|
||||
msgstr "以另一個使用者身分登入"
|
||||
|
||||
#: ../js/ui/unlockDialog.js:177
|
||||
#: ../js/ui/unlockDialog.js:141
|
||||
msgid "Unlock Window"
|
||||
msgstr "解鎖視窗"
|
||||
|
||||
@ -1727,46 +1721,48 @@ msgstr "閒置"
|
||||
msgid "Offline"
|
||||
msgstr "離線"
|
||||
|
||||
#: ../js/ui/userMenu.js:780
|
||||
#: ../js/ui/userMenu.js:781
|
||||
msgid "Notifications"
|
||||
msgstr "通知"
|
||||
|
||||
#: ../js/ui/userMenu.js:796
|
||||
#: ../js/ui/userMenu.js:797
|
||||
msgid "Switch User"
|
||||
msgstr "切換使用者"
|
||||
|
||||
#: ../js/ui/userMenu.js:801
|
||||
#: ../js/ui/userMenu.js:802
|
||||
msgid "Log Out"
|
||||
msgstr "登出"
|
||||
|
||||
#: ../js/ui/userMenu.js:821
|
||||
#: ../js/ui/userMenu.js:822
|
||||
msgid "Install Updates & Restart"
|
||||
msgstr "安裝更新 & 重新啟動"
|
||||
|
||||
#: ../js/ui/userMenu.js:839
|
||||
#: ../js/ui/userMenu.js:840
|
||||
msgid "Your chat status will be set to busy"
|
||||
msgstr "你的聊天狀態會設為忙碌"
|
||||
|
||||
#: ../js/ui/userMenu.js:840
|
||||
#: ../js/ui/userMenu.js:841
|
||||
msgid ""
|
||||
"Notifications are now disabled, including chat messages. Your online status "
|
||||
"has been adjusted to let others know that you might not see their messages."
|
||||
msgstr "通知現在已被停用,包含聊天訊息。你的上線狀態也調整為讓其他人知道你沒時間看他們的訊息。"
|
||||
|
||||
#: ../js/ui/userMenu.js:886
|
||||
#: ../js/ui/userMenu.js:888
|
||||
msgid "Other users are logged in."
|
||||
msgstr "其他使用者已登入。"
|
||||
|
||||
#: ../js/ui/userMenu.js:891
|
||||
#: ../js/ui/userMenu.js:893
|
||||
msgid "Shutting down might cause them to lose unsaved work."
|
||||
msgstr "關機可能使它們失去未儲存的工作。"
|
||||
|
||||
#: ../js/ui/userMenu.js:918
|
||||
#. Translators: Remote here refers to a remote session, like a ssh login
|
||||
#: ../js/ui/userMenu.js:921
|
||||
#, c-format
|
||||
msgid "%s (remote)"
|
||||
msgstr "%s (遠端)"
|
||||
|
||||
#: ../js/ui/userMenu.js:920
|
||||
#. Translators: Console here refers to a tty like a VT console
|
||||
#: ../js/ui/userMenu.js:924
|
||||
#, c-format
|
||||
msgid "%s (console)"
|
||||
msgstr "%s (主控臺)"
|
||||
@ -1779,7 +1775,7 @@ msgstr "應用程式"
|
||||
msgid "Search"
|
||||
msgstr "搜尋"
|
||||
|
||||
#: ../js/ui/wanda.js:92
|
||||
#: ../js/ui/wanda.js:77
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Sorry, no wisdom for you today:\n"
|
||||
@ -1788,7 +1784,7 @@ msgstr ""
|
||||
"抱歉,今天可能有些問題:\n"
|
||||
"%s"
|
||||
|
||||
#: ../js/ui/wanda.js:96
|
||||
#: ../js/ui/wanda.js:81
|
||||
#, c-format
|
||||
msgid "%s the Oracle says"
|
||||
msgstr "%s Oracle 說:"
|
||||
@ -1818,7 +1814,7 @@ msgid "%u Input"
|
||||
msgid_plural "%u Inputs"
|
||||
msgstr[0] "%u 輸入"
|
||||
|
||||
#: ../src/gvc/gvc-mixer-control.c:2371
|
||||
#: ../src/gvc/gvc-mixer-control.c:2373
|
||||
msgid "System Sounds"
|
||||
msgstr "系統音效"
|
||||
|
||||
@ -1843,11 +1839,11 @@ msgstr "列出可能的模式"
|
||||
msgid "Failed to launch '%s'"
|
||||
msgstr "無法啟動「%s」"
|
||||
|
||||
#: ../src/shell-keyring-prompt.c:708
|
||||
#: ../src/shell-keyring-prompt.c:714
|
||||
msgid "Passwords do not match."
|
||||
msgstr "密碼不相符。"
|
||||
|
||||
#: ../src/shell-keyring-prompt.c:716
|
||||
#: ../src/shell-keyring-prompt.c:722
|
||||
msgid "Password cannot be blank"
|
||||
msgstr "密碼不能為空白"
|
||||
|
||||
|
214
po/zh_TW.po
214
po/zh_TW.po
@ -9,15 +9,16 @@ msgstr ""
|
||||
"Project-Id-Version: gnome-shell 3.3.90\n"
|
||||
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-"
|
||||
"shell&keywords=I18N+L10N&component=general\n"
|
||||
"POT-Creation-Date: 2013-03-04 08:38+0000\n"
|
||||
"PO-Revision-Date: 2013-03-05 19:49+0800\n"
|
||||
"Last-Translator: Chao-Hsiung Liao <j_h_liau@yahoo.com.tw>\n"
|
||||
"POT-Creation-Date: 2013-05-31 18:55+0000\n"
|
||||
"PO-Revision-Date: 2013-04-27 00:04+0800\n"
|
||||
"Last-Translator: Cheng-Chia Tseng <pswo10680@gmail.com>\n"
|
||||
"Language-Team: Chinese (Taiwan) <zh-l10n@lists.linux.org.tw>\n"
|
||||
"Language: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=1; plural=0;\n"
|
||||
"X-Generator: Poedit 1.5.3\n"
|
||||
"X-Generator: Poedit 1.5.4\n"
|
||||
|
||||
#: ../data/50-gnome-shell-screenshot.xml.in.h:1
|
||||
msgid "Screenshots"
|
||||
@ -343,44 +344,50 @@ msgstr "擴充功能"
|
||||
msgid "Select an extension to configure using the combobox above."
|
||||
msgstr "使用上面的組合方塊選擇要設定的擴充功能。"
|
||||
|
||||
#: ../js/gdm/loginDialog.js:405
|
||||
#| msgid "Session..."
|
||||
#: ../js/gdm/loginDialog.js:371
|
||||
msgid "Session…"
|
||||
msgstr "作業階段…"
|
||||
|
||||
#. translators: this message is shown below the user list on the
|
||||
#. login screen. It can be activated to reveal an entry for
|
||||
#. manually entering the username.
|
||||
#: ../js/gdm/loginDialog.js:629
|
||||
#: ../js/gdm/loginDialog.js:601
|
||||
msgid "Not listed?"
|
||||
msgstr "沒有列出來?"
|
||||
|
||||
#: ../js/gdm/loginDialog.js:783 ../js/ui/components/networkAgent.js:137
|
||||
#: ../js/ui/components/polkitAgent.js:162 ../js/ui/endSessionDialog.js:375
|
||||
#: ../js/gdm/loginDialog.js:776 ../js/ui/components/networkAgent.js:137
|
||||
#: ../js/ui/components/polkitAgent.js:161 ../js/ui/endSessionDialog.js:376
|
||||
#: ../js/ui/extensionDownloader.js:195 ../js/ui/shellMountOperation.js:399
|
||||
#: ../js/ui/status/bluetooth.js:415 ../js/ui/unlockDialog.js:126
|
||||
#: ../js/ui/userMenu.js:934
|
||||
#: ../js/ui/status/bluetooth.js:415 ../js/ui/unlockDialog.js:96
|
||||
#: ../js/ui/userMenu.js:938
|
||||
msgid "Cancel"
|
||||
msgstr "取消"
|
||||
|
||||
#: ../js/gdm/loginDialog.js:799
|
||||
#: ../js/gdm/loginDialog.js:791
|
||||
msgctxt "button"
|
||||
msgid "Sign In"
|
||||
msgstr "登入"
|
||||
|
||||
#: ../js/gdm/loginDialog.js:799
|
||||
#: ../js/gdm/loginDialog.js:791
|
||||
msgid "Next"
|
||||
msgstr "下一個"
|
||||
|
||||
#. Translators: this message is shown below the username entry field
|
||||
#. to clue the user in on how to login to the local network realm
|
||||
#: ../js/gdm/loginDialog.js:888
|
||||
#, c-format
|
||||
msgid "(e.g., user or %s)"
|
||||
msgstr "(例如: user 或 %s)"
|
||||
|
||||
#. TTLS and PEAP are actually much more complicated, but this complication
|
||||
#. is not visible here since we only care about phase2 authentication
|
||||
#. (and don't even care of which one)
|
||||
#: ../js/gdm/loginDialog.js:904 ../js/ui/components/networkAgent.js:260
|
||||
#: ../js/gdm/loginDialog.js:892 ../js/ui/components/networkAgent.js:260
|
||||
#: ../js/ui/components/networkAgent.js:278
|
||||
msgid "Username: "
|
||||
msgstr "使用者名稱:"
|
||||
|
||||
#: ../js/gdm/loginDialog.js:1157
|
||||
#: ../js/gdm/loginDialog.js:1158
|
||||
msgid "Login Window"
|
||||
msgstr "登入視窗"
|
||||
|
||||
@ -389,8 +396,8 @@ msgstr "登入視窗"
|
||||
msgid "Power"
|
||||
msgstr "電源"
|
||||
|
||||
#: ../js/gdm/powerMenu.js:93 ../js/ui/userMenu.js:695 ../js/ui/userMenu.js:699
|
||||
#: ../js/ui/userMenu.js:815
|
||||
#: ../js/gdm/powerMenu.js:93 ../js/ui/userMenu.js:696 ../js/ui/userMenu.js:700
|
||||
#: ../js/ui/userMenu.js:816
|
||||
msgid "Suspend"
|
||||
msgstr "暫停"
|
||||
|
||||
@ -398,58 +405,53 @@ msgstr "暫停"
|
||||
msgid "Restart"
|
||||
msgstr "重新啟動"
|
||||
|
||||
#: ../js/gdm/powerMenu.js:103 ../js/ui/userMenu.js:697
|
||||
#: ../js/ui/userMenu.js:699 ../js/ui/userMenu.js:814 ../js/ui/userMenu.js:938
|
||||
#: ../js/gdm/powerMenu.js:103 ../js/ui/userMenu.js:698
|
||||
#: ../js/ui/userMenu.js:700 ../js/ui/userMenu.js:815 ../js/ui/userMenu.js:942
|
||||
msgid "Power Off"
|
||||
msgstr "關閉電源"
|
||||
|
||||
#: ../js/gdm/util.js:182
|
||||
#: ../js/gdm/util.js:247
|
||||
msgid "Authentication error"
|
||||
msgstr "驗證錯誤"
|
||||
|
||||
#. Translators: this message is shown below the password entry field
|
||||
#. to indicate the user can swipe their finger instead
|
||||
#: ../js/gdm/util.js:299
|
||||
#: ../js/gdm/util.js:364
|
||||
msgid "(or swipe finger)"
|
||||
msgstr "(或是滑過手指)"
|
||||
|
||||
#: ../js/gdm/util.js:324
|
||||
#, c-format
|
||||
msgid "(e.g., user or %s)"
|
||||
msgstr "(例如: user 或 %s)"
|
||||
|
||||
#: ../js/misc/util.js:94
|
||||
#: ../js/misc/util.js:97
|
||||
msgid "Command not found"
|
||||
msgstr "找不到指令"
|
||||
|
||||
#. Replace "Error invoking GLib.shell_parse_argv: " with
|
||||
#. something nicer
|
||||
#: ../js/misc/util.js:127
|
||||
#: ../js/misc/util.js:130
|
||||
msgid "Could not parse command:"
|
||||
msgstr "無法分析指令:"
|
||||
|
||||
#: ../js/misc/util.js:135
|
||||
#: ../js/misc/util.js:138
|
||||
#, c-format
|
||||
msgid "Execution of '%s' failed:"
|
||||
msgstr "執行「%s」失敗:"
|
||||
|
||||
#: ../js/ui/appDisplay.js:348
|
||||
#: ../js/ui/appDisplay.js:356
|
||||
msgid "Frequent"
|
||||
msgstr "頻率"
|
||||
msgstr "常用"
|
||||
|
||||
#: ../js/ui/appDisplay.js:355
|
||||
#: ../js/ui/appDisplay.js:363
|
||||
msgid "All"
|
||||
msgstr "全部"
|
||||
|
||||
#: ../js/ui/appDisplay.js:913
|
||||
#: ../js/ui/appDisplay.js:941
|
||||
msgid "New Window"
|
||||
msgstr "新視窗"
|
||||
|
||||
#: ../js/ui/appDisplay.js:916 ../js/ui/dash.js:284
|
||||
#: ../js/ui/appDisplay.js:944 ../js/ui/dash.js:284
|
||||
msgid "Remove from Favorites"
|
||||
msgstr "自喜好中移除"
|
||||
|
||||
#: ../js/ui/appDisplay.js:917
|
||||
#: ../js/ui/appDisplay.js:945
|
||||
msgid "Add to Favorites"
|
||||
msgstr "加入喜好"
|
||||
|
||||
@ -463,7 +465,7 @@ msgstr "%s 已加入您的喜好中。"
|
||||
msgid "%s has been removed from your favorites."
|
||||
msgstr "%s 已經從您的喜好中移除。"
|
||||
|
||||
#: ../js/ui/backgroundMenu.js:19 ../js/ui/userMenu.js:788
|
||||
#: ../js/ui/backgroundMenu.js:19 ../js/ui/userMenu.js:789
|
||||
msgid "Settings"
|
||||
msgstr "設定值"
|
||||
|
||||
@ -486,7 +488,7 @@ msgctxt "event list time"
|
||||
msgid "%H\\u2236%M"
|
||||
msgstr "%H\\u2236%M"
|
||||
|
||||
#. Transators: Shown in calendar event list, if 12h format,
|
||||
#. Translators: Shown in calendar event list, if 12h format,
|
||||
#. \u2236 is a ratio character, similar to : and \u2009 is
|
||||
#. a thin space
|
||||
#: ../js/ui/calendar.js:77
|
||||
@ -588,35 +590,35 @@ msgid "S"
|
||||
msgstr "六"
|
||||
|
||||
#. Translators: Text to show if there are no events
|
||||
#: ../js/ui/calendar.js:692
|
||||
#: ../js/ui/calendar.js:720
|
||||
msgid "Nothing Scheduled"
|
||||
msgstr "沒有預訂行程"
|
||||
|
||||
#. Translators: Shown on calendar heading when selected day occurs on current year
|
||||
#: ../js/ui/calendar.js:708
|
||||
#: ../js/ui/calendar.js:736
|
||||
msgctxt "calendar heading"
|
||||
msgid "%A, %B %d"
|
||||
msgstr "%m月%d日%A"
|
||||
|
||||
#. Translators: Shown on calendar heading when selected day occurs on different year
|
||||
#: ../js/ui/calendar.js:711
|
||||
#: ../js/ui/calendar.js:739
|
||||
msgctxt "calendar heading"
|
||||
msgid "%A, %B %d, %Y"
|
||||
msgstr "%Y年%m月%d日%A"
|
||||
|
||||
#: ../js/ui/calendar.js:721
|
||||
#: ../js/ui/calendar.js:749
|
||||
msgid "Today"
|
||||
msgstr "今天"
|
||||
|
||||
#: ../js/ui/calendar.js:725
|
||||
#: ../js/ui/calendar.js:753
|
||||
msgid "Tomorrow"
|
||||
msgstr "明天"
|
||||
|
||||
#: ../js/ui/calendar.js:736
|
||||
#: ../js/ui/calendar.js:764
|
||||
msgid "This week"
|
||||
msgstr "本週"
|
||||
|
||||
#: ../js/ui/calendar.js:744
|
||||
#: ../js/ui/calendar.js:772
|
||||
msgid "Next week"
|
||||
msgstr "下週"
|
||||
|
||||
@ -632,20 +634,20 @@ msgstr "外部裝置已拔除"
|
||||
msgid "Removable Devices"
|
||||
msgstr "可移除式裝置"
|
||||
|
||||
#: ../js/ui/components/autorunManager.js:593
|
||||
#: ../js/ui/components/autorunManager.js:594
|
||||
#, c-format
|
||||
msgid "Open with %s"
|
||||
msgstr "用 %s 開啟"
|
||||
|
||||
#: ../js/ui/components/autorunManager.js:619
|
||||
#: ../js/ui/components/autorunManager.js:620
|
||||
msgid "Eject"
|
||||
msgstr "退出"
|
||||
|
||||
#: ../js/ui/components/keyring.js:82 ../js/ui/components/polkitAgent.js:268
|
||||
#: ../js/ui/components/keyring.js:88 ../js/ui/components/polkitAgent.js:280
|
||||
msgid "Password:"
|
||||
msgstr "密碼: "
|
||||
|
||||
#: ../js/ui/components/keyring.js:101
|
||||
#: ../js/ui/components/keyring.js:107
|
||||
msgid "Type again:"
|
||||
msgstr "再輸入一次:"
|
||||
|
||||
@ -723,15 +725,15 @@ msgstr "行動寬頻網路密碼"
|
||||
msgid "A password is required to connect to '%s'."
|
||||
msgstr "連線至「%s」需要密碼。"
|
||||
|
||||
#: ../js/ui/components/polkitAgent.js:55
|
||||
#: ../js/ui/components/polkitAgent.js:54
|
||||
msgid "Authentication Required"
|
||||
msgstr "要求驗證"
|
||||
|
||||
#: ../js/ui/components/polkitAgent.js:93
|
||||
#: ../js/ui/components/polkitAgent.js:92
|
||||
msgid "Administrator"
|
||||
msgstr "系統管理員"
|
||||
|
||||
#: ../js/ui/components/polkitAgent.js:165
|
||||
#: ../js/ui/components/polkitAgent.js:170
|
||||
msgid "Authenticate"
|
||||
msgstr "驗證"
|
||||
|
||||
@ -739,12 +741,12 @@ msgstr "驗證"
|
||||
#. * requested authentication was not gained; this can happen
|
||||
#. * because of an authentication error (like invalid password),
|
||||
#. * for instance.
|
||||
#: ../js/ui/components/polkitAgent.js:256 ../js/ui/shellMountOperation.js:383
|
||||
#: ../js/ui/components/polkitAgent.js:266 ../js/ui/shellMountOperation.js:383
|
||||
msgid "Sorry, that didn't work. Please try again."
|
||||
msgstr "抱歉,那樣無法運作。請再試一次。"
|
||||
|
||||
#. Translators: this is a filename used for screencast recording
|
||||
#: ../js/ui/components/recorder.js:48
|
||||
#: ../js/ui/components/recorder.js:47
|
||||
#, no-c-format
|
||||
msgid "Screencast from %d %t"
|
||||
msgstr "Screencast from %d %t"
|
||||
@ -1006,14 +1008,14 @@ msgstr "開啟行事曆"
|
||||
msgid "Open Clocks"
|
||||
msgstr "開啟時鐘"
|
||||
|
||||
#: ../js/ui/dateMenu.js:105
|
||||
#: ../js/ui/dateMenu.js:104
|
||||
msgid "Date & Time Settings"
|
||||
msgstr "日期與時刻設定值"
|
||||
|
||||
#. Translators: This is the date format to use when the calendar popup is
|
||||
#. * shown - it is shown just below the time in the shell (e.g. "Tue 9:29 AM").
|
||||
#.
|
||||
#: ../js/ui/dateMenu.js:205
|
||||
#: ../js/ui/dateMenu.js:216
|
||||
msgid "%A %B %e, %Y"
|
||||
msgstr "%Y年%m月%e日%A"
|
||||
|
||||
@ -1110,7 +1112,7 @@ msgstr "安裝"
|
||||
msgid "Download and install '%s' from extensions.gnome.org?"
|
||||
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:333
|
||||
#: ../js/ui/status/power.js:211
|
||||
msgid "Keyboard"
|
||||
msgstr "鍵盤"
|
||||
@ -1172,7 +1174,6 @@ msgid "Remove"
|
||||
msgstr "移除"
|
||||
|
||||
#: ../js/ui/messageTray.js:1501
|
||||
#| msgid "No Messages"
|
||||
msgid "Clear Messages"
|
||||
msgstr "清除訊息"
|
||||
|
||||
@ -1180,15 +1181,15 @@ msgstr "清除訊息"
|
||||
msgid "Notification Settings"
|
||||
msgstr "通知設定值"
|
||||
|
||||
#: ../js/ui/messageTray.js:1707
|
||||
#: ../js/ui/messageTray.js:1709
|
||||
msgid "No Messages"
|
||||
msgstr "沒有訊息"
|
||||
|
||||
#: ../js/ui/messageTray.js:1787
|
||||
#: ../js/ui/messageTray.js:1785
|
||||
msgid "Message Tray"
|
||||
msgstr "訊息匣"
|
||||
|
||||
#: ../js/ui/messageTray.js:2864
|
||||
#: ../js/ui/messageTray.js:2818
|
||||
msgid "System Information"
|
||||
msgstr "系統資訊"
|
||||
|
||||
@ -1197,13 +1198,13 @@ msgctxt "program"
|
||||
msgid "Unknown"
|
||||
msgstr "不明"
|
||||
|
||||
#: ../js/ui/overviewControls.js:460 ../js/ui/screenShield.js:153
|
||||
#: ../js/ui/overviewControls.js:463 ../js/ui/screenShield.js:149
|
||||
#, c-format
|
||||
msgid "%d new message"
|
||||
msgid_plural "%d new messages"
|
||||
msgstr[0] "%d 個新訊息"
|
||||
|
||||
#: ../js/ui/overview.js:82
|
||||
#: ../js/ui/overview.js:84
|
||||
msgid "Undo"
|
||||
msgstr "復原"
|
||||
|
||||
@ -1215,22 +1216,21 @@ msgstr "概覽"
|
||||
#. in the search entry when no search is
|
||||
#. active; it should not exceed ~30
|
||||
#. characters.
|
||||
#: ../js/ui/overview.js:284
|
||||
#| msgid "Type to search..."
|
||||
#: ../js/ui/overview.js:271
|
||||
msgid "Type to search…"
|
||||
msgstr "輸入以搜尋…"
|
||||
|
||||
#: ../js/ui/panel.js:613
|
||||
#: ../js/ui/panel.js:635
|
||||
msgid "Quit"
|
||||
msgstr "結束"
|
||||
|
||||
#. Translators: If there is no suitable word for "Activities"
|
||||
#. in your language, you can use the word for "Overview".
|
||||
#: ../js/ui/panel.js:642
|
||||
#: ../js/ui/panel.js:686
|
||||
msgid "Activities"
|
||||
msgstr "概覽 "
|
||||
|
||||
#: ../js/ui/panel.js:983
|
||||
#: ../js/ui/panel.js:982
|
||||
msgid "Top Bar"
|
||||
msgstr "頂端列"
|
||||
|
||||
@ -1239,35 +1239,35 @@ msgstr "頂端列"
|
||||
#. "ON" and "OFF") or "toggle-switch-intl" (for toggle
|
||||
#. switches containing "◯" and "|"). Other values will
|
||||
#. simply result in invisible toggle switches.
|
||||
#: ../js/ui/popupMenu.js:727
|
||||
#: ../js/ui/popupMenu.js:740
|
||||
msgid "toggle-switch-us"
|
||||
msgstr "toggle-switch-us"
|
||||
|
||||
#: ../js/ui/runDialog.js:205
|
||||
#: ../js/ui/runDialog.js:74
|
||||
msgid "Enter a Command"
|
||||
msgstr "請輸入指令"
|
||||
|
||||
#: ../js/ui/runDialog.js:241
|
||||
#: ../js/ui/runDialog.js:110
|
||||
msgid "Close"
|
||||
msgstr "關閉"
|
||||
|
||||
#. Translators: This is a time format for a date in
|
||||
#. long format
|
||||
#: ../js/ui/screenShield.js:90
|
||||
#: ../js/ui/screenShield.js:86
|
||||
msgid "%A, %B %d"
|
||||
msgstr "%m月%d日%A"
|
||||
|
||||
#: ../js/ui/screenShield.js:155
|
||||
#: ../js/ui/screenShield.js:151
|
||||
#, c-format
|
||||
msgid "%d new notification"
|
||||
msgid_plural "%d new notifications"
|
||||
msgstr[0] "%d 個新通知"
|
||||
|
||||
#: ../js/ui/screenShield.js:442 ../js/ui/userMenu.js:806
|
||||
#: ../js/ui/screenShield.js:438 ../js/ui/userMenu.js:807
|
||||
msgid "Lock"
|
||||
msgstr "鎖定"
|
||||
|
||||
#: ../js/ui/screenShield.js:639
|
||||
#: ../js/ui/screenShield.js:641
|
||||
msgid "GNOME needs to lock the screen"
|
||||
msgstr "GNOME 需要鎖定螢幕"
|
||||
|
||||
@ -1278,37 +1278,35 @@ msgstr "GNOME 需要鎖定螢幕"
|
||||
#.
|
||||
#. XXX: another option is to kick the user into the gdm login
|
||||
#. screen, where we're not affected by grabs
|
||||
#: ../js/ui/screenShield.js:758 ../js/ui/screenShield.js:1169
|
||||
#| msgid "Unable to connect to %s"
|
||||
#: ../js/ui/screenShield.js:762 ../js/ui/screenShield.js:1198
|
||||
msgid "Unable to lock"
|
||||
msgstr "無法鎖定"
|
||||
|
||||
#: ../js/ui/screenShield.js:759 ../js/ui/screenShield.js:1170
|
||||
#: ../js/ui/screenShield.js:763 ../js/ui/screenShield.js:1199
|
||||
msgid "Lock was blocked by an application"
|
||||
msgstr "鎖定被應用程式阻擋"
|
||||
|
||||
#: ../js/ui/searchDisplay.js:431
|
||||
#| msgid "Searching..."
|
||||
#: ../js/ui/searchDisplay.js:453
|
||||
msgid "Searching…"
|
||||
msgstr "搜尋…"
|
||||
|
||||
#: ../js/ui/searchDisplay.js:475
|
||||
#: ../js/ui/searchDisplay.js:497
|
||||
msgid "No results."
|
||||
msgstr "沒有結果。"
|
||||
|
||||
#: ../js/ui/shellEntry.js:29
|
||||
#: ../js/ui/shellEntry.js:27
|
||||
msgid "Copy"
|
||||
msgstr "複製"
|
||||
|
||||
#: ../js/ui/shellEntry.js:34
|
||||
#: ../js/ui/shellEntry.js:32
|
||||
msgid "Paste"
|
||||
msgstr "貼上"
|
||||
|
||||
#: ../js/ui/shellEntry.js:105
|
||||
#: ../js/ui/shellEntry.js:99
|
||||
msgid "Show Text"
|
||||
msgstr "顯示文字"
|
||||
|
||||
#: ../js/ui/shellEntry.js:107
|
||||
#: ../js/ui/shellEntry.js:101
|
||||
msgid "Hide Text"
|
||||
msgstr "隱藏文字"
|
||||
|
||||
@ -1320,7 +1318,7 @@ msgstr "密碼"
|
||||
msgid "Remember Password"
|
||||
msgstr "記住密碼"
|
||||
|
||||
#: ../js/ui/shellMountOperation.js:403 ../js/ui/unlockDialog.js:140
|
||||
#: ../js/ui/shellMountOperation.js:403 ../js/ui/unlockDialog.js:109
|
||||
msgid "Unlock"
|
||||
msgstr "解鎖"
|
||||
|
||||
@ -1384,12 +1382,10 @@ msgid "Visibility"
|
||||
msgstr "顯示狀態"
|
||||
|
||||
#: ../js/ui/status/bluetooth.js:59
|
||||
#| msgid "Send Files to Device..."
|
||||
msgid "Send Files to Device…"
|
||||
msgstr "傳送檔案到裝置…"
|
||||
|
||||
#: ../js/ui/status/bluetooth.js:60
|
||||
#| msgid "Set Up a New Device..."
|
||||
msgid "Set Up a New Device…"
|
||||
msgstr "設定新的裝置…"
|
||||
|
||||
@ -1416,7 +1412,6 @@ msgid "connecting..."
|
||||
msgstr "連線中…"
|
||||
|
||||
#: ../js/ui/status/bluetooth.js:239
|
||||
#| msgid "Send Files..."
|
||||
msgid "Send Files…"
|
||||
msgstr "傳送檔案…"
|
||||
|
||||
@ -1492,11 +1487,11 @@ msgstr "請輸入裝置所提及的 PIN。"
|
||||
msgid "OK"
|
||||
msgstr "確定"
|
||||
|
||||
#: ../js/ui/status/keyboard.js:368
|
||||
#: ../js/ui/status/keyboard.js:396
|
||||
msgid "Show Keyboard Layout"
|
||||
msgstr "顯示鍵盤配置"
|
||||
|
||||
#: ../js/ui/status/keyboard.js:373
|
||||
#: ../js/ui/status/keyboard.js:401
|
||||
msgid "Region & Language Settings"
|
||||
msgstr "地區和語言設定值"
|
||||
|
||||
@ -1614,7 +1609,7 @@ msgstr "連線失敗"
|
||||
msgid "Activation of network connection failed"
|
||||
msgstr "啟動網路連線失敗"
|
||||
|
||||
#: ../js/ui/status/network.js:2276
|
||||
#: ../js/ui/status/network.js:2282
|
||||
msgid "Networking is disabled"
|
||||
msgstr "網路已停用"
|
||||
|
||||
@ -1629,7 +1624,6 @@ msgstr "電源設定值"
|
||||
#. 0 is reported when UPower does not have enough data
|
||||
#. to estimate battery life
|
||||
#: ../js/ui/status/power.js:99
|
||||
#| msgid "Estimating..."
|
||||
msgid "Estimating…"
|
||||
msgstr "評估中…"
|
||||
|
||||
@ -1725,11 +1719,11 @@ msgstr "音量"
|
||||
msgid "Microphone"
|
||||
msgstr "麥克風"
|
||||
|
||||
#: ../js/ui/unlockDialog.js:151
|
||||
#: ../js/ui/unlockDialog.js:120
|
||||
msgid "Log in as another user"
|
||||
msgstr "以另一個使用者身分登入"
|
||||
|
||||
#: ../js/ui/unlockDialog.js:177
|
||||
#: ../js/ui/unlockDialog.js:141
|
||||
msgid "Unlock Window"
|
||||
msgstr "解鎖視窗"
|
||||
|
||||
@ -1757,27 +1751,27 @@ msgstr "閒置"
|
||||
msgid "Offline"
|
||||
msgstr "離線"
|
||||
|
||||
#: ../js/ui/userMenu.js:780
|
||||
#: ../js/ui/userMenu.js:781
|
||||
msgid "Notifications"
|
||||
msgstr "通知"
|
||||
|
||||
#: ../js/ui/userMenu.js:796
|
||||
#: ../js/ui/userMenu.js:797
|
||||
msgid "Switch User"
|
||||
msgstr "切換使用者"
|
||||
|
||||
#: ../js/ui/userMenu.js:801
|
||||
#: ../js/ui/userMenu.js:802
|
||||
msgid "Log Out"
|
||||
msgstr "登出"
|
||||
|
||||
#: ../js/ui/userMenu.js:821
|
||||
#: ../js/ui/userMenu.js:822
|
||||
msgid "Install Updates & Restart"
|
||||
msgstr "安裝更新 & 重新啟動"
|
||||
|
||||
#: ../js/ui/userMenu.js:839
|
||||
#: ../js/ui/userMenu.js:840
|
||||
msgid "Your chat status will be set to busy"
|
||||
msgstr "您的聊天狀態會設為忙碌"
|
||||
|
||||
#: ../js/ui/userMenu.js:840
|
||||
#: ../js/ui/userMenu.js:841
|
||||
msgid ""
|
||||
"Notifications are now disabled, including chat messages. Your online status "
|
||||
"has been adjusted to let others know that you might not see their messages."
|
||||
@ -1785,20 +1779,22 @@ msgstr ""
|
||||
"通知現在已被停用,包含聊天訊息。您的上線狀態也調整為讓其他人知道您沒時間看他"
|
||||
"們的訊息。"
|
||||
|
||||
#: ../js/ui/userMenu.js:886
|
||||
#: ../js/ui/userMenu.js:888
|
||||
msgid "Other users are logged in."
|
||||
msgstr "其他使用者已登入。"
|
||||
|
||||
#: ../js/ui/userMenu.js:891
|
||||
#: ../js/ui/userMenu.js:893
|
||||
msgid "Shutting down might cause them to lose unsaved work."
|
||||
msgstr "關機可能使它們失去未儲存的工作。"
|
||||
|
||||
#: ../js/ui/userMenu.js:918
|
||||
#. Translators: Remote here refers to a remote session, like a ssh login
|
||||
#: ../js/ui/userMenu.js:921
|
||||
#, c-format
|
||||
msgid "%s (remote)"
|
||||
msgstr "%s (遠端)"
|
||||
|
||||
#: ../js/ui/userMenu.js:920
|
||||
#. Translators: Console here refers to a tty like a VT console
|
||||
#: ../js/ui/userMenu.js:924
|
||||
#, c-format
|
||||
msgid "%s (console)"
|
||||
msgstr "%s (主控臺)"
|
||||
@ -1811,7 +1807,7 @@ msgstr "應用程式"
|
||||
msgid "Search"
|
||||
msgstr "搜尋"
|
||||
|
||||
#: ../js/ui/wanda.js:92
|
||||
#: ../js/ui/wanda.js:77
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Sorry, no wisdom for you today:\n"
|
||||
@ -1820,7 +1816,7 @@ msgstr ""
|
||||
"抱歉,今天可能有些問題:\n"
|
||||
"%s"
|
||||
|
||||
#: ../js/ui/wanda.js:96
|
||||
#: ../js/ui/wanda.js:81
|
||||
#, c-format
|
||||
msgid "%s the Oracle says"
|
||||
msgstr "%s Oracle 說:"
|
||||
@ -1850,7 +1846,7 @@ msgid "%u Input"
|
||||
msgid_plural "%u Inputs"
|
||||
msgstr[0] "%u 輸入"
|
||||
|
||||
#: ../src/gvc/gvc-mixer-control.c:2371
|
||||
#: ../src/gvc/gvc-mixer-control.c:2373
|
||||
msgid "System Sounds"
|
||||
msgstr "系統音效"
|
||||
|
||||
@ -1875,11 +1871,11 @@ msgstr "列出可能的模式"
|
||||
msgid "Failed to launch '%s'"
|
||||
msgstr "無法啟動「%s」"
|
||||
|
||||
#: ../src/shell-keyring-prompt.c:708
|
||||
#: ../src/shell-keyring-prompt.c:714
|
||||
msgid "Passwords do not match."
|
||||
msgstr "密碼不相符。"
|
||||
|
||||
#: ../src/shell-keyring-prompt.c:716
|
||||
#: ../src/shell-keyring-prompt.c:722
|
||||
msgid "Password cannot be blank"
|
||||
msgstr "密碼不能為空白"
|
||||
|
||||
|
2
src/gvc
2
src/gvc
@ -1 +1 @@
|
||||
Subproject commit 03894efbcd010faf53bbc6e27256d27485f721b8
|
||||
Subproject commit 3d6aac673b88fff548db57a75b82e8f14723c1fe
|
20
src/main.c
20
src/main.c
@ -36,8 +36,6 @@ extern GType gnome_shell_plugin_get_type (void);
|
||||
#define SHELL_DBUS_SERVICE "org.gnome.Shell"
|
||||
#define MAGNIFIER_DBUS_SERVICE "org.gnome.Magnifier"
|
||||
|
||||
#define OVERRIDES_SCHEMA "org.gnome.shell.overrides"
|
||||
|
||||
#define WM_NAME "GNOME Shell"
|
||||
#define GNOME_WM_KEYBINDINGS "Mutter,GNOME Shell"
|
||||
|
||||
@ -166,23 +164,6 @@ shell_dbus_init (gboolean replace)
|
||||
g_object_unref (session);
|
||||
}
|
||||
|
||||
static void
|
||||
shell_prefs_init (void)
|
||||
{
|
||||
meta_prefs_override_preference_schema ("attach-modal-dialogs",
|
||||
OVERRIDES_SCHEMA);
|
||||
meta_prefs_override_preference_schema ("dynamic-workspaces",
|
||||
OVERRIDES_SCHEMA);
|
||||
meta_prefs_override_preference_schema ("workspaces-only-on-primary",
|
||||
OVERRIDES_SCHEMA);
|
||||
meta_prefs_override_preference_schema ("button-layout",
|
||||
OVERRIDES_SCHEMA);
|
||||
meta_prefs_override_preference_schema ("edge-tiling",
|
||||
OVERRIDES_SCHEMA);
|
||||
meta_prefs_override_preference_schema ("focus-change-on-pointer-rest",
|
||||
OVERRIDES_SCHEMA);
|
||||
}
|
||||
|
||||
static void
|
||||
shell_introspection_init (void)
|
||||
{
|
||||
@ -409,7 +390,6 @@ main (int argc, char **argv)
|
||||
shell_dbus_init (meta_get_replace_current_wm ());
|
||||
shell_a11y_init ();
|
||||
shell_perf_log_init ();
|
||||
shell_prefs_init ();
|
||||
shell_introspection_init ();
|
||||
shell_fonts_init ();
|
||||
|
||||
|
@ -210,6 +210,7 @@ shell_app_create_icon_texture (ShellApp *app,
|
||||
typedef struct {
|
||||
ShellApp *app;
|
||||
int size;
|
||||
ClutterTextDirection direction;
|
||||
} CreateFadedIconData;
|
||||
|
||||
static CoglHandle
|
||||
@ -227,7 +228,7 @@ shell_app_create_faded_icon_cpu (StTextureCache *cache,
|
||||
guint8 n_channels;
|
||||
gboolean have_alpha;
|
||||
gint fade_start;
|
||||
gint fade_range;
|
||||
gint fade_end;
|
||||
guint i, j;
|
||||
guint pixbuf_byte_size;
|
||||
guint8 *orig_pixels;
|
||||
@ -279,14 +280,26 @@ shell_app_create_faded_icon_cpu (StTextureCache *cache,
|
||||
pixels = g_malloc0 (rowstride * height);
|
||||
memcpy (pixels, orig_pixels, pixbuf_byte_size);
|
||||
|
||||
fade_start = width / 2;
|
||||
fade_range = width - fade_start;
|
||||
for (i = fade_start; i < width; i++)
|
||||
/* fade on the right side for LTR, left side for RTL */
|
||||
if (data->direction == CLUTTER_TEXT_DIRECTION_LTR)
|
||||
{
|
||||
fade_start = width / 2;
|
||||
fade_end = width;
|
||||
}
|
||||
else
|
||||
{
|
||||
fade_start = 0;
|
||||
fade_end = width / 2;
|
||||
}
|
||||
|
||||
for (i = fade_start; i < fade_end; i++)
|
||||
{
|
||||
for (j = 0; j < height; j++)
|
||||
{
|
||||
guchar *pixel = &pixels[j * rowstride + i * n_channels];
|
||||
float fade = 1.0 - ((float) i - fade_start) / fade_range;
|
||||
float fade = ((float) i - fade_start) / (fade_end - fade_start);
|
||||
if (data->direction == CLUTTER_TEXT_DIRECTION_LTR)
|
||||
fade = 1.0 - fade;
|
||||
pixel[0] = 0.5 + pixel[0] * fade;
|
||||
pixel[1] = 0.5 + pixel[1] * fade;
|
||||
pixel[2] = 0.5 + pixel[2] * fade;
|
||||
@ -312,13 +325,14 @@ shell_app_create_faded_icon_cpu (StTextureCache *cache,
|
||||
* shell_app_get_faded_icon:
|
||||
* @app: A #ShellApp
|
||||
* @size: Size in pixels
|
||||
* @direction: Whether to fade on the left or right
|
||||
*
|
||||
* Return an actor with a horizontally faded look.
|
||||
*
|
||||
* Return value: (transfer none): A floating #ClutterActor, or %NULL if no icon
|
||||
*/
|
||||
ClutterActor *
|
||||
shell_app_get_faded_icon (ShellApp *app, int size)
|
||||
shell_app_get_faded_icon (ShellApp *app, int size, ClutterTextDirection direction)
|
||||
{
|
||||
CoglHandle texture;
|
||||
ClutterActor *result;
|
||||
@ -334,9 +348,13 @@ shell_app_get_faded_icon (ShellApp *app, int size)
|
||||
|
||||
/* Use icon: prefix so that we get evicted from the cache on
|
||||
* icon theme changes. */
|
||||
cache_key = g_strdup_printf ("icon:%s,size=%d,faded", shell_app_get_id (app), size);
|
||||
cache_key = g_strdup_printf ("icon:%s,size=%d,faded-%s",
|
||||
shell_app_get_id (app),
|
||||
size,
|
||||
direction == CLUTTER_TEXT_DIRECTION_RTL ? "rtl" : "ltr");
|
||||
data.app = app;
|
||||
data.size = size;
|
||||
data.direction = direction;
|
||||
texture = st_texture_cache_load (st_texture_cache_get_default (),
|
||||
cache_key,
|
||||
ST_TEXTURE_CACHE_POLICY_FOREVER,
|
||||
|
@ -42,7 +42,7 @@ GMenuTreeEntry *shell_app_get_tree_entry (ShellApp *app);
|
||||
GDesktopAppInfo *shell_app_get_app_info (ShellApp *app);
|
||||
|
||||
ClutterActor *shell_app_create_icon_texture (ShellApp *app, int size);
|
||||
ClutterActor *shell_app_get_faded_icon (ShellApp *app, int size);
|
||||
ClutterActor *shell_app_get_faded_icon (ShellApp *app, int size, ClutterTextDirection direction);
|
||||
const char *shell_app_get_name (ShellApp *app);
|
||||
const char *shell_app_get_description (ShellApp *app);
|
||||
gboolean shell_app_is_window_backed (ShellApp *app);
|
||||
|
@ -1009,6 +1009,13 @@ shell_global_end_modal (ShellGlobal *global,
|
||||
meta_plugin_end_modal (global->plugin, timestamp);
|
||||
}
|
||||
|
||||
void
|
||||
shell_global_freeze_keyboard (ShellGlobal *global,
|
||||
guint32 timestamp)
|
||||
{
|
||||
meta_display_freeze_keyboard (global->meta_display, global->stage_xwindow, timestamp);
|
||||
}
|
||||
|
||||
/* Code to close all file descriptors before we exec; copied from gspawn.c in GLib.
|
||||
*
|
||||
* Authors: Padraig O'Briain, Matthias Clasen, Lennart Poettering
|
||||
|
@ -44,6 +44,8 @@ gboolean shell_global_begin_modal (ShellGlobal *global,
|
||||
MetaModalOptions options);
|
||||
void shell_global_end_modal (ShellGlobal *global,
|
||||
guint32 timestamp);
|
||||
void shell_global_freeze_keyboard (ShellGlobal *global,
|
||||
guint32 timestamp);
|
||||
|
||||
typedef enum {
|
||||
SHELL_STAGE_INPUT_MODE_NONREACTIVE,
|
||||
|
@ -106,6 +106,8 @@ shell_gtk_embed_window_created_cb (MetaDisplay *display,
|
||||
0, 0 /* offset x/y */);
|
||||
cairo_region_destroy (empty_region);
|
||||
|
||||
gdk_window_lower (gdk_window);
|
||||
|
||||
/* Now that we've found the window we don't need to listen for
|
||||
new windows anymore */
|
||||
g_signal_handler_disconnect (display,
|
||||
|
@ -15,6 +15,8 @@
|
||||
* @SHELL_KEYBINDING_MODE_SYSTEM_MODAL: allow keybinding when a system modal
|
||||
* dialog (e.g. authentification or session dialogs) is open
|
||||
* @SHELL_KEYBINDING_MODE_LOOKING_GLASS: allow keybinding in looking glass
|
||||
* @SHELL_KEYBINDING_MODE_TOPBAR_POPUP: allow keybinding while a top bar menu
|
||||
* is open
|
||||
* @SHELL_KEYBINDING_MODE_ALL: always allow keybinding
|
||||
*
|
||||
* Controls in which GNOME Shell states a keybinding should be handled.
|
||||
@ -29,6 +31,7 @@ typedef enum {
|
||||
SHELL_KEYBINDING_MODE_MESSAGE_TRAY = 1 << 5,
|
||||
SHELL_KEYBINDING_MODE_SYSTEM_MODAL = 1 << 6,
|
||||
SHELL_KEYBINDING_MODE_LOOKING_GLASS = 1 << 7,
|
||||
SHELL_KEYBINDING_MODE_TOPBAR_POPUP = 1 << 8,
|
||||
|
||||
SHELL_KEYBINDING_MODE_ALL = ~0,
|
||||
} ShellKeyBindingMode;
|
||||
|
@ -100,7 +100,6 @@ G_DEFINE_TYPE_WITH_CODE (ShellKeyringPrompt, shell_keyring_prompt, G_TYPE_OBJECT
|
||||
enum {
|
||||
SIGNAL_SHOW_PASSWORD,
|
||||
SIGNAL_SHOW_CONFIRM,
|
||||
SIGNAL_HIDE_PROMPT,
|
||||
SIGNAL_LAST
|
||||
};
|
||||
|
||||
@ -258,10 +257,8 @@ shell_keyring_prompt_dispose (GObject *obj)
|
||||
{
|
||||
ShellKeyringPrompt *self = SHELL_KEYRING_PROMPT (obj);
|
||||
|
||||
if (self->shown) {
|
||||
self->shown = FALSE;
|
||||
g_signal_emit (self, signals[SIGNAL_HIDE_PROMPT], 0);
|
||||
}
|
||||
if (self->shown)
|
||||
gcr_prompt_close (GCR_PROMPT (self));
|
||||
|
||||
if (self->async_result)
|
||||
shell_keyring_prompt_cancel (self);
|
||||
@ -384,11 +381,6 @@ shell_keyring_prompt_class_init (ShellKeyringPromptClass *klass)
|
||||
0, 0, NULL, NULL,
|
||||
g_cclosure_marshal_VOID__VOID,
|
||||
G_TYPE_NONE, 0);
|
||||
|
||||
signals[SIGNAL_HIDE_PROMPT] = g_signal_new ("hide-prompt", G_TYPE_FROM_CLASS (klass),
|
||||
0, 0, NULL, NULL,
|
||||
g_cclosure_marshal_VOID__VOID,
|
||||
G_TYPE_NONE, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -482,6 +474,19 @@ shell_keyring_prompt_confirm_finish (GcrPrompt *prompt,
|
||||
return self->last_reply;
|
||||
}
|
||||
|
||||
static void
|
||||
shell_keyring_prompt_close (GcrPrompt *prompt)
|
||||
{
|
||||
ShellKeyringPrompt *self = SHELL_KEYRING_PROMPT (prompt);
|
||||
|
||||
/*
|
||||
* We expect keyring.js to connect to this signal and do the
|
||||
* actual work of closing the prompt.
|
||||
*/
|
||||
|
||||
self->shown = FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
shell_keyring_prompt_iface (GcrPromptIface *iface)
|
||||
{
|
||||
@ -489,6 +494,7 @@ shell_keyring_prompt_iface (GcrPromptIface *iface)
|
||||
iface->prompt_password_finish = shell_keyring_prompt_password_finish;
|
||||
iface->prompt_confirm_async = shell_keyring_prompt_confirm_async;
|
||||
iface->prompt_confirm_finish = shell_keyring_prompt_confirm_finish;
|
||||
iface->prompt_close = shell_keyring_prompt_close;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -746,9 +752,19 @@ shell_keyring_prompt_cancel (ShellKeyringPrompt *self)
|
||||
GSimpleAsyncResult *res;
|
||||
|
||||
g_return_if_fail (SHELL_IS_KEYRING_PROMPT (self));
|
||||
g_return_if_fail (self->mode != PROMPTING_NONE);
|
||||
g_return_if_fail (self->async_result != NULL);
|
||||
|
||||
/*
|
||||
* If cancelled while not prompting, we should just close the prompt,
|
||||
* the user wants it to go away.
|
||||
*/
|
||||
if (self->mode == PROMPTING_NONE)
|
||||
{
|
||||
if (self->shown)
|
||||
gcr_prompt_close (GCR_PROMPT (self));
|
||||
return;
|
||||
}
|
||||
|
||||
g_return_if_fail (self->async_result != NULL);
|
||||
self->last_reply = GCR_PROMPT_REPLY_CANCEL;
|
||||
|
||||
res = self->async_result;
|
||||
|
@ -25,6 +25,9 @@
|
||||
/* This is also hard-coded in mutter and GDK */
|
||||
#define VIRTUAL_CORE_POINTER_ID 2
|
||||
|
||||
#define A11Y_APPS_SCHEMA "org.gnome.desktop.a11y.applications"
|
||||
#define MAGNIFIER_ACTIVE_KEY "screen-magnifier-enabled"
|
||||
|
||||
typedef enum {
|
||||
RECORDER_STATE_CLOSED,
|
||||
RECORDER_STATE_RECORDING
|
||||
@ -50,6 +53,8 @@ struct _ShellRecorder {
|
||||
RecorderState state;
|
||||
|
||||
ClutterStage *stage;
|
||||
gboolean custom_area;
|
||||
cairo_rectangle_int_t area;
|
||||
int stage_width;
|
||||
int stage_height;
|
||||
|
||||
@ -66,6 +71,8 @@ struct _ShellRecorder {
|
||||
|
||||
CoglHandle recording_icon; /* icon shown while playing */
|
||||
|
||||
GSettings *a11y_settings;
|
||||
gboolean draw_cursor;
|
||||
cairo_surface_t *cursor_image;
|
||||
int cursor_hot_x;
|
||||
int cursor_hot_y;
|
||||
@ -110,6 +117,8 @@ static void recorder_set_pipeline (ShellRecorder *recorder,
|
||||
const char *pipeline);
|
||||
static void recorder_set_file_template (ShellRecorder *recorder,
|
||||
const char *file_template);
|
||||
static void recorder_set_draw_cursor (ShellRecorder *recorder,
|
||||
gboolean draw_cursor);
|
||||
|
||||
static void recorder_pipeline_set_caps (RecorderPipeline *pipeline);
|
||||
static void recorder_pipeline_closed (RecorderPipeline *pipeline);
|
||||
@ -119,7 +128,8 @@ enum {
|
||||
PROP_STAGE,
|
||||
PROP_FRAMERATE,
|
||||
PROP_PIPELINE,
|
||||
PROP_FILE_TEMPLATE
|
||||
PROP_FILE_TEMPLATE,
|
||||
PROP_DRAW_CURSOR
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE(ShellRecorder, shell_recorder, G_TYPE_OBJECT);
|
||||
@ -271,8 +281,11 @@ shell_recorder_init (ShellRecorder *recorder)
|
||||
recorder->recording_icon = create_recording_icon ();
|
||||
recorder->memory_target = get_memory_target();
|
||||
|
||||
recorder->a11y_settings = g_settings_new (A11Y_APPS_SCHEMA);
|
||||
|
||||
recorder->state = RECORDER_STATE_CLOSED;
|
||||
recorder->framerate = DEFAULT_FRAMES_PER_SECOND;
|
||||
recorder->draw_cursor = TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -292,6 +305,8 @@ shell_recorder_finalize (GObject *object)
|
||||
|
||||
cogl_handle_unref (recorder->recording_icon);
|
||||
|
||||
g_clear_object (&recorder->a11y_settings);
|
||||
|
||||
G_OBJECT_CLASS (shell_recorder_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
@ -429,10 +444,10 @@ recorder_draw_cursor (ShellRecorder *recorder,
|
||||
/* We don't show a cursor unless the hot spot is in the frame; this
|
||||
* means that sometimes we aren't going to draw a cursor even when
|
||||
* there is a little bit overlapping within the stage */
|
||||
if (recorder->pointer_x < 0 ||
|
||||
recorder->pointer_y < 0 ||
|
||||
recorder->pointer_x >= recorder->stage_width ||
|
||||
recorder->pointer_y >= recorder->stage_height)
|
||||
if (recorder->pointer_x < recorder->area.x ||
|
||||
recorder->pointer_y < recorder->area.y ||
|
||||
recorder->pointer_x >= recorder->area.x + recorder->area.width ||
|
||||
recorder->pointer_y >= recorder->area.y + recorder->area.height)
|
||||
return;
|
||||
|
||||
if (!recorder->cursor_image)
|
||||
@ -444,15 +459,15 @@ recorder_draw_cursor (ShellRecorder *recorder,
|
||||
gst_buffer_map (buffer, &info, GST_MAP_WRITE);
|
||||
surface = cairo_image_surface_create_for_data (info.data,
|
||||
CAIRO_FORMAT_ARGB32,
|
||||
recorder->stage_width,
|
||||
recorder->stage_height,
|
||||
recorder->stage_width * 4);
|
||||
recorder->area.width,
|
||||
recorder->area.height,
|
||||
recorder->area.width * 4);
|
||||
|
||||
cr = cairo_create (surface);
|
||||
cairo_set_source_surface (cr,
|
||||
recorder->cursor_image,
|
||||
recorder->pointer_x - recorder->cursor_hot_x,
|
||||
recorder->pointer_y - recorder->cursor_hot_y);
|
||||
recorder->pointer_x - recorder->cursor_hot_x - recorder->area.x,
|
||||
recorder->pointer_y - recorder->cursor_hot_y - recorder->area.y);
|
||||
cairo_paint (cr);
|
||||
|
||||
cairo_destroy (cr);
|
||||
@ -470,7 +485,7 @@ recorder_draw_buffer_meter (ShellRecorder *recorder)
|
||||
GdkRectangle primary_monitor;
|
||||
float rects[16];
|
||||
|
||||
gdk_screen_get_monitor_geometry (recorder->gdk_screen,
|
||||
gdk_screen_get_monitor_workarea (recorder->gdk_screen,
|
||||
gdk_screen_get_primary_monitor (recorder->gdk_screen),
|
||||
&primary_monitor);
|
||||
|
||||
@ -555,12 +570,13 @@ recorder_record_frame (ShellRecorder *recorder)
|
||||
|
||||
recorder->last_frame_time = now;
|
||||
|
||||
size = recorder->stage_width * recorder->stage_height * 4;
|
||||
size = recorder->area.width * recorder->area.height * 4;
|
||||
|
||||
data = g_malloc (recorder->stage_width * 4 * recorder->stage_height);
|
||||
cogl_read_pixels (0, 0, /* x/y */
|
||||
recorder->stage_width,
|
||||
recorder->stage_height,
|
||||
data = g_malloc (recorder->area.width * 4 * recorder->area.height);
|
||||
cogl_read_pixels (recorder->area.x,
|
||||
recorder->area.y,
|
||||
recorder->area.width,
|
||||
recorder->area.height,
|
||||
COGL_READ_PIXELS_COLOR_BUFFER,
|
||||
CLUTTER_CAIRO_FORMAT_ARGB32,
|
||||
data);
|
||||
@ -572,7 +588,9 @@ recorder_record_frame (ShellRecorder *recorder)
|
||||
|
||||
GST_BUFFER_PTS(buffer) = now - recorder->start_time;
|
||||
|
||||
recorder_draw_cursor (recorder, buffer);
|
||||
if (recorder->draw_cursor &&
|
||||
!g_settings_get_boolean (recorder->a11y_settings, MAGNIFIER_ACTIVE_KEY))
|
||||
recorder_draw_cursor (recorder, buffer);
|
||||
|
||||
shell_recorder_src_add_buffer (SHELL_RECORDER_SRC (recorder->current_pipeline->src), buffer);
|
||||
gst_buffer_unref (buffer);
|
||||
@ -593,7 +611,7 @@ recorder_on_stage_paint (ClutterActor *actor,
|
||||
{
|
||||
GdkRectangle primary_monitor;
|
||||
|
||||
gdk_screen_get_monitor_geometry (recorder->gdk_screen,
|
||||
gdk_screen_get_monitor_workarea (recorder->gdk_screen,
|
||||
gdk_screen_get_primary_monitor (recorder->gdk_screen),
|
||||
&primary_monitor);
|
||||
if (!recorder->only_paint)
|
||||
@ -616,6 +634,14 @@ recorder_update_size (ShellRecorder *recorder)
|
||||
clutter_actor_get_allocation_box (CLUTTER_ACTOR (recorder->stage), &allocation);
|
||||
recorder->stage_width = (int)(0.5 + allocation.x2 - allocation.x1);
|
||||
recorder->stage_height = (int)(0.5 + allocation.y2 - allocation.y1);
|
||||
|
||||
if (!recorder->custom_area)
|
||||
{
|
||||
recorder->area.x = 0;
|
||||
recorder->area.y = 0;
|
||||
recorder->area.width = recorder->stage_width;
|
||||
recorder->area.height = recorder->stage_height;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1006,6 +1032,18 @@ recorder_set_file_template (ShellRecorder *recorder,
|
||||
g_object_notify (G_OBJECT (recorder), "file-template");
|
||||
}
|
||||
|
||||
static void
|
||||
recorder_set_draw_cursor (ShellRecorder *recorder,
|
||||
gboolean draw_cursor)
|
||||
{
|
||||
if (draw_cursor == recorder->draw_cursor)
|
||||
return;
|
||||
|
||||
recorder->draw_cursor = draw_cursor;
|
||||
|
||||
g_object_notify (G_OBJECT (recorder), "draw-cursor");
|
||||
}
|
||||
|
||||
static void
|
||||
shell_recorder_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
@ -1028,6 +1066,9 @@ shell_recorder_set_property (GObject *object,
|
||||
case PROP_FILE_TEMPLATE:
|
||||
recorder_set_file_template (recorder, g_value_get_string (value));
|
||||
break;
|
||||
case PROP_DRAW_CURSOR:
|
||||
recorder_set_draw_cursor (recorder, g_value_get_boolean (value));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
@ -1056,6 +1097,9 @@ shell_recorder_get_property (GObject *object,
|
||||
case PROP_FILE_TEMPLATE:
|
||||
g_value_set_string (value, recorder->file_template);
|
||||
break;
|
||||
case PROP_DRAW_CURSOR:
|
||||
g_value_set_boolean (value, recorder->draw_cursor);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
@ -1104,6 +1148,14 @@ shell_recorder_class_init (ShellRecorderClass *klass)
|
||||
"The filename template to use for output files",
|
||||
NULL,
|
||||
G_PARAM_READWRITE));
|
||||
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_DRAW_CURSOR,
|
||||
g_param_spec_boolean ("draw-cursor",
|
||||
"Draw Cursor",
|
||||
"Whether to record the cursor",
|
||||
TRUE,
|
||||
G_PARAM_READWRITE));
|
||||
}
|
||||
|
||||
/* Sets the GstCaps (video format, in this case) on the stream
|
||||
@ -1126,8 +1178,8 @@ recorder_pipeline_set_caps (RecorderPipeline *pipeline)
|
||||
"bpp", G_TYPE_INT, 32,
|
||||
"depth", G_TYPE_INT, 24,
|
||||
"framerate", GST_TYPE_FRACTION, pipeline->recorder->framerate, 1,
|
||||
"width", G_TYPE_INT, pipeline->recorder->stage_width,
|
||||
"height", G_TYPE_INT, pipeline->recorder->stage_height,
|
||||
"width", G_TYPE_INT, pipeline->recorder->area.width,
|
||||
"height", G_TYPE_INT, pipeline->recorder->area.height,
|
||||
NULL);
|
||||
g_object_set (pipeline->src, "caps", caps, NULL);
|
||||
gst_caps_unref (caps);
|
||||
@ -1678,6 +1730,15 @@ shell_recorder_set_file_template (ShellRecorder *recorder,
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
shell_recorder_set_draw_cursor (ShellRecorder *recorder,
|
||||
gboolean draw_cursor)
|
||||
{
|
||||
g_return_if_fail (SHELL_IS_RECORDER (recorder));
|
||||
|
||||
recorder_set_draw_cursor (recorder, draw_cursor);
|
||||
}
|
||||
|
||||
/**
|
||||
* shell_recorder_set_pipeline:
|
||||
* @recorder: the #ShellRecorder
|
||||
@ -1705,9 +1766,35 @@ shell_recorder_set_pipeline (ShellRecorder *recorder,
|
||||
recorder_set_pipeline (recorder, pipeline);
|
||||
}
|
||||
|
||||
void
|
||||
shell_recorder_set_area (ShellRecorder *recorder,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
g_return_if_fail (SHELL_IS_RECORDER (recorder));
|
||||
|
||||
recorder->custom_area = TRUE;
|
||||
recorder->area.x = CLAMP (x, 0, recorder->stage_width);
|
||||
recorder->area.y = CLAMP (y, 0, recorder->stage_height);
|
||||
recorder->area.width = CLAMP (width,
|
||||
0, recorder->stage_width - recorder->area.x);
|
||||
recorder->area.height = CLAMP (height,
|
||||
0, recorder->stage_height - recorder->area.y);
|
||||
|
||||
/* This breaks the recording but tweaking the GStreamer pipeline a bit
|
||||
* might make it work, at least if the codec can handle a stream where
|
||||
* the frame size changes in the middle.
|
||||
*/
|
||||
if (recorder->current_pipeline)
|
||||
recorder_pipeline_set_caps (recorder->current_pipeline);
|
||||
}
|
||||
|
||||
/**
|
||||
* shell_recorder_record:
|
||||
* @recorder: the #ShellRecorder
|
||||
* @filename_used: (out) (allow-none): actual filename used for recording
|
||||
*
|
||||
* Starts recording, Starting the recording may fail if the output file
|
||||
* cannot be opened, or if the output stream cannot be created
|
||||
@ -1724,7 +1811,8 @@ shell_recorder_set_pipeline (ShellRecorder *recorder,
|
||||
* Return value: %TRUE if recording was succesfully started
|
||||
*/
|
||||
gboolean
|
||||
shell_recorder_record (ShellRecorder *recorder)
|
||||
shell_recorder_record (ShellRecorder *recorder,
|
||||
char **filename_used)
|
||||
{
|
||||
g_return_val_if_fail (SHELL_IS_RECORDER (recorder), FALSE);
|
||||
g_return_val_if_fail (recorder->stage != NULL, FALSE);
|
||||
@ -1733,6 +1821,9 @@ shell_recorder_record (ShellRecorder *recorder)
|
||||
if (!recorder_open_pipeline (recorder))
|
||||
return FALSE;
|
||||
|
||||
if (filename_used)
|
||||
*filename_used = g_strdup (recorder->current_pipeline->filename);
|
||||
|
||||
recorder_connect_stage_callbacks (recorder);
|
||||
|
||||
recorder->start_time = get_wall_time();
|
||||
|
@ -36,7 +36,15 @@ void shell_recorder_set_file_template (ShellRecorder *recorder,
|
||||
const char *file_template);
|
||||
void shell_recorder_set_pipeline (ShellRecorder *recorder,
|
||||
const char *pipeline);
|
||||
gboolean shell_recorder_record (ShellRecorder *recorder);
|
||||
void shell_recorder_set_draw_cursor (ShellRecorder *recorder,
|
||||
gboolean draw_cursor);
|
||||
void shell_recorder_set_area (ShellRecorder *recorder,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height);
|
||||
gboolean shell_recorder_record (ShellRecorder *recorder,
|
||||
char **filename_used);
|
||||
void shell_recorder_close (ShellRecorder *recorder);
|
||||
void shell_recorder_pause (ShellRecorder *recorder);
|
||||
gboolean shell_recorder_is_recording (ShellRecorder *recorder);
|
||||
|
@ -15,6 +15,9 @@
|
||||
#include "shell-global.h"
|
||||
#include "shell-screenshot.h"
|
||||
|
||||
#define A11Y_APPS_SCHEMA "org.gnome.desktop.a11y.applications"
|
||||
#define MAGNIFIER_ACTIVE_KEY "screen-magnifier-enabled"
|
||||
|
||||
struct _ShellScreenshotClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
@ -304,6 +307,7 @@ grab_screenshot (ClutterActor *stage,
|
||||
MetaScreen *screen = shell_global_get_screen (screenshot_data->screenshot->global);
|
||||
int width, height;
|
||||
GSimpleAsyncResult *result;
|
||||
GSettings *settings;
|
||||
|
||||
meta_screen_get_size (screen, &width, &height);
|
||||
|
||||
@ -352,8 +356,11 @@ grab_screenshot (ClutterActor *stage,
|
||||
screenshot_data->screenshot_area.width = width;
|
||||
screenshot_data->screenshot_area.height = height;
|
||||
|
||||
if (screenshot_data->include_cursor)
|
||||
settings = g_settings_new (A11Y_APPS_SCHEMA);
|
||||
if (screenshot_data->include_cursor &&
|
||||
!g_settings_get_boolean (settings, MAGNIFIER_ACTIVE_KEY))
|
||||
_draw_cursor_image (screenshot_data->image, screenshot_data->screenshot_area);
|
||||
g_object_unref (settings);
|
||||
|
||||
g_signal_handlers_disconnect_by_func (stage, (void *)grab_screenshot, (gpointer)screenshot_data);
|
||||
|
||||
@ -476,6 +483,7 @@ shell_screenshot_screenshot_window (ShellScreenshot *screenshot,
|
||||
ShellScreenshotCallback callback)
|
||||
{
|
||||
GSimpleAsyncResult *result;
|
||||
GSettings *settings;
|
||||
|
||||
_screenshot_data *screenshot_data = g_new0 (_screenshot_data, 1);
|
||||
|
||||
@ -492,6 +500,17 @@ shell_screenshot_screenshot_window (ShellScreenshot *screenshot,
|
||||
screenshot_data->filename = g_strdup (filename);
|
||||
screenshot_data->callback = callback;
|
||||
|
||||
if (!window)
|
||||
{
|
||||
screenshot_data->filename_used = g_strdup ("");
|
||||
result = g_simple_async_result_new (NULL, on_screenshot_written, (gpointer)screenshot_data, shell_screenshot_screenshot_window);
|
||||
g_simple_async_result_set_op_res_gboolean (result, FALSE);
|
||||
g_simple_async_result_complete (result);
|
||||
g_object_unref (result);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
window_actor = CLUTTER_ACTOR (meta_window_get_compositor_private (window));
|
||||
clutter_actor_get_position (window_actor, &actor_x, &actor_y);
|
||||
|
||||
@ -522,8 +541,10 @@ shell_screenshot_screenshot_window (ShellScreenshot *screenshot,
|
||||
stex = META_SHAPED_TEXTURE (meta_window_actor_get_texture (META_WINDOW_ACTOR (window_actor)));
|
||||
screenshot_data->image = meta_shaped_texture_get_image (stex, &clip);
|
||||
|
||||
if (include_cursor)
|
||||
settings = g_settings_new (A11Y_APPS_SCHEMA);
|
||||
if (include_cursor && !g_settings_get_boolean (settings, MAGNIFIER_ACTIVE_KEY))
|
||||
_draw_cursor_image (screenshot_data->image, screenshot_data->screenshot_area);
|
||||
g_object_unref (settings);
|
||||
|
||||
result = g_simple_async_result_new (NULL, on_screenshot_written, (gpointer)screenshot_data, shell_screenshot_screenshot_window);
|
||||
g_simple_async_result_run_in_thread (result, write_screenshot_thread, G_PRIORITY_DEFAULT, NULL);
|
||||
|
@ -82,6 +82,8 @@ enum
|
||||
PROP_CLUTTER_TEXT,
|
||||
PROP_HINT_TEXT,
|
||||
PROP_TEXT,
|
||||
PROP_INPUT_PURPOSE,
|
||||
PROP_INPUT_HINTS,
|
||||
};
|
||||
|
||||
/* signals */
|
||||
@ -136,6 +138,14 @@ st_entry_set_property (GObject *gobject,
|
||||
st_entry_set_text (entry, g_value_get_string (value));
|
||||
break;
|
||||
|
||||
case PROP_INPUT_PURPOSE:
|
||||
st_entry_set_input_purpose (entry, g_value_get_enum (value));
|
||||
break;
|
||||
|
||||
case PROP_INPUT_HINTS:
|
||||
st_entry_set_input_hints (entry, g_value_get_flags (value));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||
break;
|
||||
@ -164,6 +174,14 @@ st_entry_get_property (GObject *gobject,
|
||||
g_value_set_string (value, clutter_text_get_text (CLUTTER_TEXT (priv->entry)));
|
||||
break;
|
||||
|
||||
case PROP_INPUT_PURPOSE:
|
||||
g_value_set_enum (value, st_im_text_get_input_purpose (ST_IM_TEXT (priv->entry)));
|
||||
break;
|
||||
|
||||
case PROP_INPUT_HINTS:
|
||||
g_value_set_flags (value, st_im_text_get_input_hints (ST_IM_TEXT (priv->entry)));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||
break;
|
||||
@ -759,6 +777,26 @@ st_entry_class_init (StEntryClass *klass)
|
||||
NULL, G_PARAM_READWRITE);
|
||||
g_object_class_install_property (gobject_class, PROP_TEXT, pspec);
|
||||
|
||||
pspec = g_param_spec_enum ("input-purpose",
|
||||
"Purpose",
|
||||
"Purpose of the text field",
|
||||
GTK_TYPE_INPUT_PURPOSE,
|
||||
GTK_INPUT_PURPOSE_FREE_FORM,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_INPUT_PURPOSE,
|
||||
pspec);
|
||||
|
||||
pspec = g_param_spec_flags ("input-hints",
|
||||
"hints",
|
||||
"Hints for the text field behaviour",
|
||||
GTK_TYPE_INPUT_HINTS,
|
||||
GTK_INPUT_HINT_NONE,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_INPUT_HINTS,
|
||||
pspec);
|
||||
|
||||
/* signals */
|
||||
/**
|
||||
* StEntry::primary-icon-clicked:
|
||||
@ -966,6 +1004,87 @@ st_entry_get_hint_text (StEntry *entry)
|
||||
return entry->priv->hint;
|
||||
}
|
||||
|
||||
/**
|
||||
* st_entry_set_input_purpose:
|
||||
* @entry: a #StEntry
|
||||
* @purpose: the purpose
|
||||
*
|
||||
* Sets the #StEntry:input-purpose property which
|
||||
* can be used by on-screen keyboards and other input
|
||||
* methods to adjust their behaviour.
|
||||
*/
|
||||
void
|
||||
st_entry_set_input_purpose (StEntry *entry,
|
||||
GtkInputPurpose purpose)
|
||||
{
|
||||
StIMText *imtext;
|
||||
|
||||
g_return_if_fail (ST_IS_ENTRY (entry));
|
||||
|
||||
imtext = ST_IM_TEXT (entry->priv->entry);
|
||||
|
||||
if (st_im_text_get_input_purpose (imtext) != purpose)
|
||||
{
|
||||
st_im_text_set_input_purpose (imtext, purpose);
|
||||
|
||||
g_object_notify (G_OBJECT (entry), "input-purpose");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* st_entry_get_input_purpose:
|
||||
* @entry: a #StEntry
|
||||
*
|
||||
* Gets the value of the #StEntry:input-purpose property.
|
||||
*/
|
||||
GtkInputPurpose
|
||||
st_entry_get_input_purpose (StEntry *entry)
|
||||
{
|
||||
g_return_val_if_fail (ST_IS_ENTRY (entry), GTK_INPUT_PURPOSE_FREE_FORM);
|
||||
|
||||
return st_im_text_get_input_purpose (ST_IM_TEXT (entry->priv->entry));
|
||||
}
|
||||
|
||||
/**
|
||||
* st_entry_set_input_hints:
|
||||
* @entry: a #StEntry
|
||||
* @hints: the hints
|
||||
*
|
||||
* Sets the #StEntry:input-hints property, which
|
||||
* allows input methods to fine-tune their behaviour.
|
||||
*/
|
||||
void
|
||||
st_entry_set_input_hints (StEntry *entry,
|
||||
GtkInputHints hints)
|
||||
{
|
||||
StIMText *imtext;
|
||||
|
||||
g_return_if_fail (ST_IS_ENTRY (entry));
|
||||
|
||||
imtext = ST_IM_TEXT (entry->priv->entry);
|
||||
|
||||
if (st_im_text_get_input_hints (imtext) != hints)
|
||||
{
|
||||
st_im_text_set_input_hints (imtext, hints);
|
||||
|
||||
g_object_notify (G_OBJECT (entry), "input-hints");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* st_entry_get_input_hints:
|
||||
* @entry: a #StEntry
|
||||
*
|
||||
* Gets the value of the #StEntry:input-hints property.
|
||||
*/
|
||||
GtkInputHints
|
||||
st_entry_get_input_hints (StEntry *entry)
|
||||
{
|
||||
g_return_val_if_fail (ST_IS_ENTRY (entry), GTK_INPUT_HINT_NONE);
|
||||
|
||||
return st_im_text_get_input_hints (ST_IM_TEXT (entry->priv->entry));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_st_entry_icon_press_cb (ClutterActor *actor,
|
||||
ClutterButtonEvent *event,
|
||||
|
@ -64,20 +64,27 @@ struct _StEntryClass
|
||||
|
||||
GType st_entry_get_type (void) G_GNUC_CONST;
|
||||
|
||||
StWidget * st_entry_new (const gchar *text);
|
||||
const gchar * st_entry_get_text (StEntry *entry);
|
||||
void st_entry_set_text (StEntry *entry,
|
||||
const gchar *text);
|
||||
ClutterActor* st_entry_get_clutter_text (StEntry *entry);
|
||||
StWidget *st_entry_new (const gchar *text);
|
||||
const gchar *st_entry_get_text (StEntry *entry);
|
||||
void st_entry_set_text (StEntry *entry,
|
||||
const gchar *text);
|
||||
ClutterActor *st_entry_get_clutter_text (StEntry *entry);
|
||||
|
||||
void st_entry_set_hint_text (StEntry *entry,
|
||||
const gchar *text);
|
||||
const gchar * st_entry_get_hint_text (StEntry *entry);
|
||||
void st_entry_set_hint_text (StEntry *entry,
|
||||
const gchar *text);
|
||||
const gchar *st_entry_get_hint_text (StEntry *entry);
|
||||
|
||||
void st_entry_set_primary_icon (StEntry *entry,
|
||||
ClutterActor *icon);
|
||||
void st_entry_set_secondary_icon (StEntry *entry,
|
||||
ClutterActor *icon);
|
||||
void st_entry_set_input_purpose (StEntry *entry,
|
||||
GtkInputPurpose purpose);
|
||||
GtkInputPurpose st_entry_get_input_purpose (StEntry *entry);
|
||||
void st_entry_set_input_hints (StEntry *entry,
|
||||
GtkInputHints hints);
|
||||
GtkInputHints st_entry_get_input_hints (StEntry *entry);
|
||||
|
||||
void st_entry_set_primary_icon (StEntry *entry,
|
||||
ClutterActor *icon);
|
||||
void st_entry_set_secondary_icon (StEntry *entry,
|
||||
ClutterActor *icon);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
@ -249,11 +249,6 @@ st_icon_paint (ClutterActor *actor)
|
||||
clutter_actor_get_allocation_box (priv->icon_texture, &allocation);
|
||||
clutter_actor_box_get_size (&allocation, &width, &height);
|
||||
|
||||
allocation.x1 = (width - priv->shadow_width) / 2;
|
||||
allocation.y1 = (height - priv->shadow_height) / 2;
|
||||
allocation.x2 = allocation.x1 + priv->shadow_width;
|
||||
allocation.y2 = allocation.y1 + priv->shadow_height;
|
||||
|
||||
_st_paint_shadow_with_opacity (priv->shadow_spec,
|
||||
priv->shadow_material,
|
||||
&allocation,
|
||||
@ -410,8 +405,8 @@ st_icon_finish_update (StIcon *icon)
|
||||
st_icon_update_shadow_material (icon);
|
||||
|
||||
/* "pixbuf-change" is actually a misnomer for "texture-changed" */
|
||||
g_signal_connect (priv->icon_texture, "pixbuf-change",
|
||||
G_CALLBACK (on_pixbuf_changed), icon);
|
||||
g_signal_connect_object (priv->icon_texture, "pixbuf-change",
|
||||
G_CALLBACK (on_pixbuf_changed), icon, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -469,7 +464,7 @@ st_icon_update (StIcon *icon)
|
||||
else
|
||||
{
|
||||
/* Will be shown when fully loaded */
|
||||
priv->opacity_handler_id = g_signal_connect (priv->pending_texture, "notify::opacity", G_CALLBACK (opacity_changed_cb), icon);
|
||||
priv->opacity_handler_id = g_signal_connect_object (priv->pending_texture, "notify::opacity", G_CALLBACK (opacity_changed_cb), icon, 0);
|
||||
}
|
||||
}
|
||||
else if (priv->icon_texture)
|
||||
@ -544,7 +539,8 @@ st_icon_set_icon_name (StIcon *icon,
|
||||
|
||||
if (g_icon_equal (priv->gicon, gicon)) /* do nothing */
|
||||
{
|
||||
g_object_unref (gicon);
|
||||
if (gicon)
|
||||
g_object_unref (gicon);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -50,6 +50,15 @@
|
||||
|
||||
#include "st-im-text.h"
|
||||
|
||||
/* properties */
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
|
||||
PROP_INPUT_PURPOSE,
|
||||
PROP_INPUT_HINTS,
|
||||
};
|
||||
|
||||
#define ST_IM_TEXT_GET_PRIVATE(obj) \
|
||||
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), ST_TYPE_IM_TEXT, StIMTextPrivate))
|
||||
|
||||
@ -404,16 +413,67 @@ st_im_text_key_focus_out (ClutterActor *actor)
|
||||
CLUTTER_ACTOR_CLASS (st_im_text_parent_class)->key_focus_out (actor);
|
||||
}
|
||||
|
||||
static void
|
||||
st_im_text_set_property (GObject *gobject,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
StIMText *imtext = ST_IM_TEXT (gobject);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_INPUT_PURPOSE:
|
||||
st_im_text_set_input_purpose (imtext, g_value_get_enum (value));
|
||||
break;
|
||||
|
||||
case PROP_INPUT_HINTS:
|
||||
st_im_text_set_input_hints (imtext, g_value_get_flags (value));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
st_im_text_get_property (GObject *gobject,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
StIMText *imtext = ST_IM_TEXT (gobject);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_INPUT_PURPOSE:
|
||||
g_value_set_enum (value, st_im_text_get_input_purpose (imtext));
|
||||
break;
|
||||
|
||||
case PROP_INPUT_HINTS:
|
||||
g_value_set_flags (value, st_im_text_get_input_hints (imtext));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
st_im_text_class_init (StIMTextClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
|
||||
ClutterTextClass *text_class = CLUTTER_TEXT_CLASS (klass);
|
||||
GParamSpec *pspec;
|
||||
|
||||
g_type_class_add_private (klass, sizeof (StIMTextPrivate));
|
||||
|
||||
object_class->dispose = st_im_text_dispose;
|
||||
object_class->set_property = st_im_text_set_property;
|
||||
object_class->get_property = st_im_text_get_property;
|
||||
|
||||
actor_class->get_paint_volume = st_im_text_get_paint_volume;
|
||||
actor_class->realize = st_im_text_realize;
|
||||
@ -425,6 +485,26 @@ st_im_text_class_init (StIMTextClass *klass)
|
||||
actor_class->key_focus_out = st_im_text_key_focus_out;
|
||||
|
||||
text_class->cursor_event = st_im_text_cursor_event;
|
||||
|
||||
pspec = g_param_spec_enum ("input-purpose",
|
||||
"Purpose",
|
||||
"Purpose of the text field",
|
||||
GTK_TYPE_INPUT_PURPOSE,
|
||||
GTK_INPUT_PURPOSE_FREE_FORM,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_INPUT_PURPOSE,
|
||||
pspec);
|
||||
|
||||
pspec = g_param_spec_flags ("input-hints",
|
||||
"hints",
|
||||
"Hints for the text field behaviour",
|
||||
GTK_TYPE_INPUT_HINTS,
|
||||
GTK_INPUT_HINT_NONE,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_INPUT_HINTS,
|
||||
pspec);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -460,3 +540,96 @@ st_im_text_new (const gchar *text)
|
||||
"text", text,
|
||||
NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* st_im_text_set_input_purpose:
|
||||
* @imtext: a #StIMText
|
||||
* @purpose: the purpose
|
||||
*
|
||||
* Sets the #StIMText:input-purpose property which
|
||||
* can be used by on-screen keyboards and other input
|
||||
* methods to adjust their behaviour.
|
||||
*/
|
||||
void
|
||||
st_im_text_set_input_purpose (StIMText *imtext,
|
||||
GtkInputPurpose purpose)
|
||||
{
|
||||
g_return_if_fail (ST_IS_IM_TEXT (imtext));
|
||||
|
||||
if (st_im_text_get_input_purpose (imtext) != purpose)
|
||||
{
|
||||
g_object_set (G_OBJECT (imtext->priv->im_context),
|
||||
"input-purpose", purpose,
|
||||
NULL);
|
||||
|
||||
g_object_get (G_OBJECT (imtext->priv->im_context),
|
||||
"input-purpose", &purpose,
|
||||
NULL);
|
||||
|
||||
g_object_notify (G_OBJECT (imtext), "input-purpose");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* st_im_text_get_input_purpose:
|
||||
* @imtext: a #StIMText
|
||||
*
|
||||
* Gets the value of the #StIMText:input-purpose property.
|
||||
*/
|
||||
GtkInputPurpose
|
||||
st_im_text_get_input_purpose (StIMText *imtext)
|
||||
{
|
||||
GtkInputPurpose purpose;
|
||||
|
||||
g_return_val_if_fail (ST_IS_IM_TEXT (imtext), GTK_INPUT_PURPOSE_FREE_FORM);
|
||||
|
||||
g_object_get (G_OBJECT (imtext->priv->im_context),
|
||||
"input-purpose", &purpose,
|
||||
NULL);
|
||||
|
||||
return purpose;
|
||||
}
|
||||
|
||||
/**
|
||||
* st_im_text_set_input_hints:
|
||||
* @imtext: a #StIMText
|
||||
* @hints: the hints
|
||||
*
|
||||
* Sets the #StIMText:input-hints property, which
|
||||
* allows input methods to fine-tune their behaviour.
|
||||
*/
|
||||
void
|
||||
st_im_text_set_input_hints (StIMText *imtext,
|
||||
GtkInputHints hints)
|
||||
{
|
||||
g_return_if_fail (ST_IS_IM_TEXT (imtext));
|
||||
|
||||
if (st_im_text_get_input_hints (imtext) != hints)
|
||||
{
|
||||
g_object_set (G_OBJECT (imtext->priv->im_context),
|
||||
"input-hints", hints,
|
||||
NULL);
|
||||
|
||||
g_object_notify (G_OBJECT (imtext), "input-hints");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* st_im_text_get_input_hints:
|
||||
* @imtext: a #StIMText
|
||||
*
|
||||
* Gets the value of the #StIMText:input-hints property.
|
||||
*/
|
||||
GtkInputHints
|
||||
st_im_text_get_input_hints (StIMText *imtext)
|
||||
{
|
||||
GtkInputHints hints;
|
||||
|
||||
g_return_val_if_fail (ST_IS_IM_TEXT (imtext), GTK_INPUT_HINT_NONE);
|
||||
|
||||
g_object_get (G_OBJECT (imtext->priv->im_context),
|
||||
"input-hints", &hints,
|
||||
NULL);
|
||||
|
||||
return hints;
|
||||
}
|
||||
|
@ -60,9 +60,13 @@ struct _StIMTextClass
|
||||
|
||||
GType st_im_text_get_type (void) G_GNUC_CONST;
|
||||
|
||||
ClutterActor *st_im_text_new (const gchar *text);
|
||||
void st_im_text_set_autoshow_im (StIMText *self,
|
||||
gboolean autoshow);
|
||||
ClutterActor *st_im_text_new (const gchar *text);
|
||||
void st_im_text_set_input_purpose (StIMText *imtext,
|
||||
GtkInputPurpose purpose);
|
||||
GtkInputPurpose st_im_text_get_input_purpose (StIMText *imtext);
|
||||
void st_im_text_set_input_hints (StIMText *imtext,
|
||||
GtkInputHints hints);
|
||||
GtkInputHints st_im_text_get_input_hints (StIMText *imtext);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
@ -218,10 +218,6 @@ st_label_paint (ClutterActor *actor)
|
||||
clutter_actor_get_allocation_box (priv->label, &allocation);
|
||||
clutter_actor_box_get_size (&allocation, &width, &height);
|
||||
|
||||
allocation.x1 = allocation.y1 = 0;
|
||||
allocation.x2 = width;
|
||||
allocation.y2 = height;
|
||||
|
||||
if (priv->text_shadow_material == COGL_INVALID_HANDLE ||
|
||||
width != priv->shadow_width ||
|
||||
height != priv->shadow_height)
|
||||
|
@ -511,6 +511,7 @@ _st_create_shadow_material_from_actor (StShadow *shadow_spec,
|
||||
cogl_color_set_from_4ub (&clear_color, 0, 0, 0, 0);
|
||||
cogl_push_framebuffer (offscreen);
|
||||
cogl_clear (&clear_color, COGL_BUFFER_BIT_COLOR);
|
||||
cogl_translate (-box.x1, -box.y1, 0);
|
||||
cogl_ortho (0, width, height, 0, 0, 1.0);
|
||||
clutter_actor_paint (actor);
|
||||
cogl_pop_framebuffer ();
|
||||
|
@ -598,42 +598,36 @@ st_scroll_view_allocate (ClutterActor *actor,
|
||||
*/
|
||||
|
||||
/* Vertical scrollbar */
|
||||
if (CLUTTER_ACTOR_IS_VISIBLE (priv->vscroll))
|
||||
{
|
||||
if (clutter_actor_get_text_direction (actor) == CLUTTER_TEXT_DIRECTION_RTL)
|
||||
{
|
||||
child_box.x1 = content_box.x1;
|
||||
child_box.x2 = content_box.x1 + sb_width;
|
||||
}
|
||||
else
|
||||
{
|
||||
child_box.x1 = content_box.x2 - sb_width;
|
||||
child_box.x2 = content_box.x2;
|
||||
}
|
||||
child_box.y1 = content_box.y1;
|
||||
child_box.y2 = content_box.y2 - (hscrollbar_visible ? sb_height : 0);
|
||||
if (clutter_actor_get_text_direction (actor) == CLUTTER_TEXT_DIRECTION_RTL)
|
||||
{
|
||||
child_box.x1 = content_box.x1;
|
||||
child_box.x2 = content_box.x1 + sb_width;
|
||||
}
|
||||
else
|
||||
{
|
||||
child_box.x1 = content_box.x2 - sb_width;
|
||||
child_box.x2 = content_box.x2;
|
||||
}
|
||||
child_box.y1 = content_box.y1;
|
||||
child_box.y2 = content_box.y2 - (hscrollbar_visible ? sb_height : 0);
|
||||
|
||||
clutter_actor_allocate (priv->vscroll, &child_box, flags);
|
||||
}
|
||||
clutter_actor_allocate (priv->vscroll, &child_box, flags);
|
||||
|
||||
/* Horizontal scrollbar */
|
||||
if (CLUTTER_ACTOR_IS_VISIBLE (priv->hscroll))
|
||||
{
|
||||
if (clutter_actor_get_text_direction (actor) == CLUTTER_TEXT_DIRECTION_RTL)
|
||||
{
|
||||
child_box.x1 = content_box.x1 + (vscrollbar_visible ? sb_width : 0);
|
||||
child_box.x2 = content_box.x2;
|
||||
}
|
||||
else
|
||||
{
|
||||
child_box.x1 = content_box.x1;
|
||||
child_box.x2 = content_box.x2 - (vscrollbar_visible ? sb_width : 0);
|
||||
}
|
||||
child_box.y1 = content_box.y2 - sb_height;
|
||||
child_box.y2 = content_box.y2;
|
||||
if (clutter_actor_get_text_direction (actor) == CLUTTER_TEXT_DIRECTION_RTL)
|
||||
{
|
||||
child_box.x1 = content_box.x1 + (vscrollbar_visible ? sb_width : 0);
|
||||
child_box.x2 = content_box.x2;
|
||||
}
|
||||
else
|
||||
{
|
||||
child_box.x1 = content_box.x1;
|
||||
child_box.x2 = content_box.x2 - (vscrollbar_visible ? sb_width : 0);
|
||||
}
|
||||
child_box.y1 = content_box.y2 - sb_height;
|
||||
child_box.y2 = content_box.y2;
|
||||
|
||||
clutter_actor_allocate (priv->hscroll, &child_box, flags);
|
||||
}
|
||||
clutter_actor_allocate (priv->hscroll, &child_box, flags);
|
||||
|
||||
/* In case the scrollbar policy is NEVER or scrollbars should be
|
||||
* overlayed, we don't trim the content box allocation by the
|
||||
|
@ -292,11 +292,6 @@ st_shadow_helper_paint (StShadowHelper *helper,
|
||||
|
||||
clutter_actor_box_get_size (actor_box, &width, &height);
|
||||
|
||||
allocation.x1 = (width - helper->width) / 2;
|
||||
allocation.y1 = (height - helper->height) / 2;
|
||||
allocation.x2 = allocation.x1 + helper->width;
|
||||
allocation.y2 = allocation.y1 + helper->height;
|
||||
|
||||
_st_paint_shadow_with_opacity (helper->shadow,
|
||||
helper->material,
|
||||
&allocation,
|
||||
|
@ -608,8 +608,9 @@ st_widget_get_theme_node (StWidget *widget)
|
||||
|
||||
if (stage == NULL)
|
||||
{
|
||||
g_error ("st_widget_get_theme_node called on the widget %s which is not in the stage.",
|
||||
st_describe_actor (CLUTTER_ACTOR (widget)));
|
||||
g_critical ("st_widget_get_theme_node called on the widget %s which is not in the stage.",
|
||||
st_describe_actor (CLUTTER_ACTOR (widget)));
|
||||
return g_object_new (ST_TYPE_THEME_NODE, NULL);
|
||||
}
|
||||
|
||||
if (parent_node == NULL)
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user