Compare commits
131 Commits
Author | SHA1 | Date | |
---|---|---|---|
f1af37f220 | |||
d3880c0bff | |||
4dfa39457e | |||
325ff73c5b | |||
1fa4e3b1b2 | |||
f89091d0f0 | |||
859927df39 | |||
e7512fcd79 | |||
2b70151794 | |||
153b7d525d | |||
2e80995f19 | |||
9232cbf8a7 | |||
55f74bb863 | |||
b02e3719b3 | |||
3ba4304da9 | |||
49d6db34b7 | |||
63a0e521fd | |||
c00d79bae2 | |||
30d902f898 | |||
8f9da6f801 | |||
20648e9207 | |||
614fe202e0 | |||
c3646a7642 | |||
772df91762 | |||
c90910731f | |||
ba69cd99d1 | |||
fb6e341efd | |||
3dc4f01113 | |||
d94d0f60c8 | |||
8d79f6f4c8 | |||
c5e5bb0be1 | |||
8d139bbd95 | |||
fb1bb291eb | |||
3199620a83 | |||
c88bb66369 | |||
a60d57ea1f | |||
527ce66cd4 | |||
40415a6849 | |||
1ff638a51f | |||
2a9ccf2e2c | |||
2909d91c13 | |||
0dba12193d | |||
02f40b3b63 | |||
1fd51efc7f | |||
6f881f232e | |||
be12c71534 | |||
6aa1b817c9 | |||
300961e19e | |||
b191e9ef91 | |||
5ec5978d4a | |||
f4d90bc127 | |||
bfa34914db | |||
8d1e4659d1 | |||
b3b91f1699 | |||
ff4c5270d3 | |||
e240f7ea59 | |||
9f1ad5d86d | |||
a1ab32af0f | |||
3fac0632a8 | |||
c2b518929d | |||
c422d82752 | |||
da0c7fc2b6 | |||
167bc080d9 | |||
7d7a15f978 | |||
1b5cf0b8a8 | |||
306b005943 | |||
d229abf07d | |||
6f6251c0bc | |||
fd034e3551 | |||
f9bee05d49 | |||
37c6fbc6b2 | |||
9719604b79 | |||
b6262f0666 | |||
6c0bd207e9 | |||
91b13effc8 | |||
143ab6ac7f | |||
3e5b90dbba | |||
b82039e324 | |||
83862d04a0 | |||
52d07f6d9b | |||
21de88c3ba | |||
456ca3d3e0 | |||
f4ba3e4ab8 | |||
d4db5a59c1 | |||
4aee87a31b | |||
e8f5a842b1 | |||
5c681a76b6 | |||
53a24e6ddd | |||
b27c89f836 | |||
9f870aa1c7 | |||
c9cfeb8318 | |||
497e66ce6a | |||
bc973b80d7 | |||
85846d88f0 | |||
6b7c85b079 | |||
d80ef67d1d | |||
62f3457a95 | |||
636ab4b0e9 | |||
23e382dd33 | |||
f5a170ce46 | |||
fbd6beea2c | |||
360f5b1642 | |||
f0a785df9d | |||
e2c1bfbedd | |||
7e5a1cfd90 | |||
07deda593a | |||
1ca39e8586 | |||
402fd8ec29 | |||
fbe2e30f38 | |||
fb6ead2881 | |||
7ff7fb5d3b | |||
8030d9ad32 | |||
45bc850715 | |||
51a913730e | |||
0a4974ac8c | |||
1666fa195d | |||
a9df4e7516 | |||
343b3351f1 | |||
407b12c3cb | |||
455a8f3076 | |||
5067bda61a | |||
e138b6e3af | |||
9bc9d5165f | |||
26c2cb9f65 | |||
da44649e6f | |||
a0def23940 | |||
f49b58cf97 | |||
cadd9a99c0 | |||
7061889a29 | |||
764527c8c9 | |||
18742fcc32 |
1
.gitignore
vendored
1
.gitignore
vendored
@ -60,7 +60,6 @@ src/calendar-server/evolution-calendar.desktop
|
|||||||
src/calendar-server/org.gnome.Shell.CalendarServer.service
|
src/calendar-server/org.gnome.Shell.CalendarServer.service
|
||||||
src/gnome-shell
|
src/gnome-shell
|
||||||
src/gnome-shell-calendar-server
|
src/gnome-shell-calendar-server
|
||||||
src/gnome-shell-extension-prefs
|
|
||||||
src/gnome-shell-extension-tool
|
src/gnome-shell-extension-tool
|
||||||
src/gnome-shell-hotplug-sniffer
|
src/gnome-shell-hotplug-sniffer
|
||||||
src/gnome-shell-perf-helper
|
src/gnome-shell-perf-helper
|
||||||
|
@ -18,7 +18,7 @@ variables:
|
|||||||
- merge_requests
|
- merge_requests
|
||||||
|
|
||||||
check_commit_log:
|
check_commit_log:
|
||||||
image: registry.gitlab.gnome.org/gnome/mutter/master:v3
|
image: registry.gitlab.gnome.org/gnome/mutter/master:v4
|
||||||
stage: review
|
stage: review
|
||||||
variables:
|
variables:
|
||||||
GIT_DEPTH: "100"
|
GIT_DEPTH: "100"
|
||||||
@ -28,10 +28,10 @@ check_commit_log:
|
|||||||
- merge_requests
|
- merge_requests
|
||||||
|
|
||||||
js_check:
|
js_check:
|
||||||
image: registry.gitlab.gnome.org/gnome/gnome-shell/extension-ci:v1
|
image: registry.gitlab.gnome.org/gnome/gnome-shell/extension-ci:v2
|
||||||
stage: review
|
stage: review
|
||||||
script:
|
script:
|
||||||
- find js -name '*.js' -exec js60 -c -s '{}' ';' 2>&1 | tee $JS_LOG
|
- find js -name '*.js' -exec js68 -c -s '{}' ';' 2>&1 | tee $JS_LOG
|
||||||
- (! grep -q . $JS_LOG)
|
- (! grep -q . $JS_LOG)
|
||||||
<<: *only_default
|
<<: *only_default
|
||||||
artifacts:
|
artifacts:
|
||||||
@ -40,7 +40,7 @@ js_check:
|
|||||||
when: on_failure
|
when: on_failure
|
||||||
|
|
||||||
eslint:
|
eslint:
|
||||||
image: registry.gitlab.gnome.org/gnome/gnome-shell/extension-ci:v1
|
image: registry.gitlab.gnome.org/gnome/gnome-shell/extension-ci:v2
|
||||||
stage: review
|
stage: review
|
||||||
script:
|
script:
|
||||||
- ./.gitlab-ci/run-eslint.sh
|
- ./.gitlab-ci/run-eslint.sh
|
||||||
@ -51,21 +51,21 @@ eslint:
|
|||||||
when: always
|
when: always
|
||||||
|
|
||||||
potfile_check:
|
potfile_check:
|
||||||
image: registry.gitlab.gnome.org/gnome/gnome-shell/extension-ci:v1
|
image: registry.gitlab.gnome.org/gnome/gnome-shell/extension-ci:v2
|
||||||
stage: review
|
stage: review
|
||||||
script:
|
script:
|
||||||
- ./.gitlab-ci/check-potfiles.sh
|
- ./.gitlab-ci/check-potfiles.sh
|
||||||
<<: *only_default
|
<<: *only_default
|
||||||
|
|
||||||
no_template_check:
|
no_template_check:
|
||||||
image: registry.gitlab.gnome.org/gnome/gnome-shell/extension-ci:v1
|
image: registry.gitlab.gnome.org/gnome/gnome-shell/extension-ci:v2
|
||||||
stage: review
|
stage: review
|
||||||
script:
|
script:
|
||||||
- ./.gitlab-ci/check-template-strings.sh
|
- ./.gitlab-ci/check-template-strings.sh
|
||||||
<<: *only_default
|
<<: *only_default
|
||||||
|
|
||||||
build:
|
build:
|
||||||
image: registry.gitlab.gnome.org/gnome/mutter/master:v3
|
image: registry.gitlab.gnome.org/gnome/mutter/master:v4
|
||||||
stage: build
|
stage: build
|
||||||
before_script:
|
before_script:
|
||||||
- .gitlab-ci/checkout-mutter.sh
|
- .gitlab-ci/checkout-mutter.sh
|
||||||
@ -83,7 +83,7 @@ build:
|
|||||||
- build
|
- build
|
||||||
|
|
||||||
test:
|
test:
|
||||||
image: registry.gitlab.gnome.org/gnome/mutter/master:v3
|
image: registry.gitlab.gnome.org/gnome/mutter/master:v4
|
||||||
stage: test
|
stage: test
|
||||||
variables:
|
variables:
|
||||||
XDG_RUNTIME_DIR: "$CI_PROJECT_DIR/runtime-dir"
|
XDG_RUNTIME_DIR: "$CI_PROJECT_DIR/runtime-dir"
|
||||||
@ -100,7 +100,7 @@ test:
|
|||||||
when: on_failure
|
when: on_failure
|
||||||
|
|
||||||
test-pot:
|
test-pot:
|
||||||
image: registry.gitlab.gnome.org/gnome/mutter/master:v3
|
image: registry.gitlab.gnome.org/gnome/mutter/master:v4
|
||||||
stage: test
|
stage: test
|
||||||
before_script:
|
before_script:
|
||||||
- ninja -C mutter/build install
|
- ninja -C mutter/build install
|
||||||
@ -124,11 +124,7 @@ flatpak:
|
|||||||
RUNTIME_REPO: "https://nightly.gnome.org/gnome-nightly.flatpakrepo"
|
RUNTIME_REPO: "https://nightly.gnome.org/gnome-nightly.flatpakrepo"
|
||||||
FLATPAK_MODULE: "gnome-extensions-app"
|
FLATPAK_MODULE: "gnome-extensions-app"
|
||||||
APP_ID: "org.gnome.Extensions"
|
APP_ID: "org.gnome.Extensions"
|
||||||
MESON_ARGS: "$SUBPROJECT"
|
|
||||||
extends: .flatpak
|
extends: .flatpak
|
||||||
before_script:
|
|
||||||
- flatpak run --command=$SUBPROJECT/generate-translations.sh
|
|
||||||
--filesystem=host org.gnome.Sdk//master
|
|
||||||
<<: *only_default
|
<<: *only_default
|
||||||
|
|
||||||
nightly:
|
nightly:
|
||||||
|
24
.gitlab-ci/Dockerfile
Normal file
24
.gitlab-ci/Dockerfile
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
# Rebuild and push with
|
||||||
|
#
|
||||||
|
# cd .gitlab-ci/
|
||||||
|
# podman build --format docker --no-cache -t registry.gitlab.gnome.org/gnome/gnome-shell/extension-ci:v2 .
|
||||||
|
# podman push registry.gitlab.gnome.org/gnome/gnome-shell/extension-ci:v2
|
||||||
|
#
|
||||||
|
|
||||||
|
FROM registry.fedoraproject.org/fedora:32
|
||||||
|
|
||||||
|
RUN dnf -y update && dnf -y upgrade && \
|
||||||
|
dnf install -y 'dnf-command(copr)' git && \
|
||||||
|
|
||||||
|
# For syntax checks with `find . -name '*.js' -exec js68 -c -s '{}' ';'`
|
||||||
|
dnf install -y findutils mozjs68-devel && \
|
||||||
|
|
||||||
|
# For static analysis with eslint
|
||||||
|
dnf install -y nodejs && \
|
||||||
|
npm install -g eslint && \
|
||||||
|
|
||||||
|
# Shameless plug for my own tooling; useful for generating zip
|
||||||
|
dnf copr enable -y fmuellner/gnome-shell-ci && \
|
||||||
|
dnf install -y gnome-extensions-tool meson && \
|
||||||
|
|
||||||
|
dnf clean all
|
@ -1,18 +0,0 @@
|
|||||||
FROM registry.fedoraproject.org/fedora:latest
|
|
||||||
|
|
||||||
RUN dnf -y update && dnf -y upgrade && \
|
|
||||||
dnf install -y 'dnf-command(copr)' git && \
|
|
||||||
|
|
||||||
# For syntax checks with `find . -name '*.js' -exec js60 -c -s '{}' ';'`
|
|
||||||
dnf install -y findutils mozjs60-devel && \
|
|
||||||
|
|
||||||
# For static analysis with eslint
|
|
||||||
dnf install -y nodejs && \
|
|
||||||
npm install -g eslint && \
|
|
||||||
|
|
||||||
# Shameless plug for my own tooling; useful for generating zip
|
|
||||||
dnf copr enable -y fmuellner/gnome-shell-ci && \
|
|
||||||
dnf install -y gnome-extensions-tool meson && \
|
|
||||||
|
|
||||||
dnf clean all && \
|
|
||||||
rm -rf /var/cache/dnf
|
|
@ -6,6 +6,11 @@ globs=('*.js' '*.c')
|
|||||||
# find source files that contain gettext keywords
|
# find source files that contain gettext keywords
|
||||||
files=$(grep -lR ${globs[@]/#/--include=} '\(gettext\|[^I_)]_\)(' $srcdirs)
|
files=$(grep -lR ${globs[@]/#/--include=} '\(gettext\|[^I_)]_\)(' $srcdirs)
|
||||||
|
|
||||||
|
# filter out excluded files
|
||||||
|
if [ -f po/POTFILES.skip ]; then
|
||||||
|
files=$(for f in $files; do ! grep -q ^$f po/POTFILES.skip && echo $f; done)
|
||||||
|
fi
|
||||||
|
|
||||||
# find those that aren't listed in POTFILES.in
|
# find those that aren't listed in POTFILES.in
|
||||||
missing=$(for f in $files; do ! grep -q ^$f po/POTFILES.in && echo $f; done)
|
missing=$(for f in $files; do ! grep -q ^$f po/POTFILES.in && echo $f; done)
|
||||||
|
|
||||||
|
@ -18,12 +18,14 @@ run_eslint() {
|
|||||||
local extra_args=ARGS_$1
|
local extra_args=ARGS_$1
|
||||||
local output_var=OUTPUT_$1
|
local output_var=OUTPUT_$1
|
||||||
local output=${!output_var}
|
local output=${!output_var}
|
||||||
|
local cache=.eslintcache-${1,,}
|
||||||
|
|
||||||
# ensure output exists even if eslint doesn't report any errors
|
# ensure output exists even if eslint doesn't report any errors
|
||||||
mkdir -p $(dirname $output)
|
mkdir -p $(dirname $output)
|
||||||
touch $output
|
touch $output
|
||||||
|
|
||||||
eslint -f unix ${!extra_args} -o $output js subprojects/extensions-app/js
|
eslint -f unix --cache --cache-location $cache ${!extra_args} -o $output \
|
||||||
|
js subprojects/extensions-app/js
|
||||||
}
|
}
|
||||||
|
|
||||||
list_commit_range_additions() {
|
list_commit_range_additions() {
|
||||||
|
44
NEWS
44
NEWS
@ -1,3 +1,47 @@
|
|||||||
|
3.37.1
|
||||||
|
======
|
||||||
|
* Improve bluetooth submenu title [Mariana; #2340]
|
||||||
|
* Add openPrefs() convenience method for extensions [Florian; !1163]
|
||||||
|
* Bring back support for empty StIcons [Andre, Jonas D.; !1173, !1178]
|
||||||
|
* Wake up screen when unlocking programmatically [Florian; !1158]
|
||||||
|
* Improve extensions tool error reporting [Florian; #2391]
|
||||||
|
* Improve handling of scale-factor changes [Georges; !1176]
|
||||||
|
* Tone down weekend days with events in calendar [Jakub; #2588]
|
||||||
|
* Fix showing bluetooth submenu when devices were set up [Florian; !1174]
|
||||||
|
* Add support for parental controls filtering [Philip W.; !465]
|
||||||
|
* Provide alternative extension templates [Florian; !812]
|
||||||
|
* Improve weather section's empty state [Mariana; #2179]
|
||||||
|
* Fix translations of folder names [Florian; #2623]
|
||||||
|
* Drop Tweener [Jonas Å.; !1200]
|
||||||
|
* Match ASCII alternatives of system actions [Will; #2688]
|
||||||
|
* Fix delay on lock screen after entering wrong password [Jonas D.; #2655]
|
||||||
|
* Use globalThis instead of window [Andy; #2322]
|
||||||
|
* Inhibit remote access when disabled by session mode [Jonas Å.; !1210]
|
||||||
|
* Improve calendar-server performance [Milan; #1875]
|
||||||
|
* Add gnome-shell-extension-prefs wrapper for compatibility [Florian; !1220]
|
||||||
|
* Fix stuck lock screen after unlock [Jonas D., Florian; #2446]
|
||||||
|
* Fixed crashes [Jonas D., Florian, Carlos; #2584, #2625, !1223, !1218]
|
||||||
|
* Misc. bug fixes and cleanups [Florian, Jonas Å., Marco, Andre, Georges,
|
||||||
|
Jonas D., Jan, Philip Ch.,, Xiaoguang, Will, Jordan, Matthew, qarmin;
|
||||||
|
!1126, !1155, !1156, !1165, !1168, !1169, #2551, #2563, !1172, !1175, !1179,
|
||||||
|
!1160, #2562, #2578, !1184, #2559, !1186, #2607, !1191, !1194, !1199, !1203,
|
||||||
|
#2649, #2628, !1205, !1206, !1208, !1207, !1211, !1214, !1213, !1192, !1217,
|
||||||
|
!1219, #1615, #2691, !1094, !1177]
|
||||||
|
|
||||||
|
Contributors:
|
||||||
|
Marco Trevisan (Treviño), Philip Chimento, Milan Crha, Jonas Dreßler,
|
||||||
|
Carlos Garnacho, Andy Holmes, Matthew Leeds, Andre Moreira Magalhaes,
|
||||||
|
Florian Müllner, Georges Basile Stavracas Neto, Jordan Petridis,
|
||||||
|
Mariana Picolo, Jakub Steiner, Will Thompson, Jan Tojnar, Xiaoguang Wang,
|
||||||
|
Philip Withnall, qarmin, Jonas Ådahl
|
||||||
|
|
||||||
|
Translators:
|
||||||
|
Fabio Tomat [fur], Cheng-Chia Tseng [zh_TW], Danial Behzadi [fa],
|
||||||
|
Jiri Grönroos [fi], Ibai Oihanguren Sala [eu], Марко Костић [sr],
|
||||||
|
Rūdolfs Mazurs [lv], Yuri Chornoivan [uk], Carmen Bianca BAKKER [eo],
|
||||||
|
Dingzhong Chen [zh_CN], Rafael Fontenelle [pt_BR], Petr Kovář [cs],
|
||||||
|
Asier Sarasua Garmendia [eu], Daniel Mustieles [es], Emin Tufan Çetin [tr]
|
||||||
|
|
||||||
3.36.0
|
3.36.0
|
||||||
======
|
======
|
||||||
* Fix off-by-1900 error in date conversions [Florian; !1061]
|
* Fix off-by-1900 error in date conversions [Florian; !1061]
|
||||||
|
@ -1,12 +1,19 @@
|
|||||||
<node>
|
<node>
|
||||||
<interface name="org.gnome.Shell.CalendarServer">
|
<interface name="org.gnome.Shell.CalendarServer">
|
||||||
<method name="GetEvents">
|
<method name="SetTimeRange">
|
||||||
<arg type="x" direction="in" />
|
<arg type="x" name="since" direction="in"/>
|
||||||
<arg type="x" direction="in" />
|
<arg type="x" name="until" direction="in"/>
|
||||||
<arg type="b" direction="in" />
|
<arg type="b" name="force_reload" direction="in"/>
|
||||||
<arg type="a(sssbxxa{sv})" direction="out" />
|
|
||||||
</method>
|
</method>
|
||||||
|
<signal name="EventsAddedOrUpdated">
|
||||||
|
<arg type="a(ssbxxa{sv})" name="events" direction="out"/>
|
||||||
|
</signal>
|
||||||
|
<signal name="EventsRemoved">
|
||||||
|
<arg type="as" name="ids" direction="out"/>
|
||||||
|
</signal>
|
||||||
|
<signal name="ClientDisappeared">
|
||||||
|
<arg type="s" name="source_uid" direction="out"/>
|
||||||
|
</signal>
|
||||||
<property name="HasCalendars" type="b" access="read" />
|
<property name="HasCalendars" type="b" access="read" />
|
||||||
<signal name="Changed" />
|
|
||||||
</interface>
|
</interface>
|
||||||
</node>
|
</node>
|
||||||
|
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 6.1 KiB |
@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path d="M6.5 1.031c-.371 0-.742-.035-1.11.016-.367.05-.73.203-.972.476-.125.141-.215.309-.266.485-.047.18-.054.367-.02.55.032.184.102.356.192.516.09.164.203.309.317.457L5 4H2a1.8 1.8 0 00-.41.035.791.791 0 00-.36.195.791.791 0 00-.195.36C1 4.723 1 4.863 1 5v2.75l.77-.344c.265-.117.542-.23.832-.242.289-.016.586.074.812.254.227.18.383.441.465.723.082.277.101.57.121.859.02.316.04.637-.016.95-.058.312-.199.616-.43.831a1.264 1.264 0 01-.874.32c-.317-.007-.618-.128-.91-.257L1 10.5V14c0 .137.004.277.035.41a.791.791 0 00.195.36c.098.097.227.16.36.195.133.035.273.035.41.035h3l-.328-.68c-.14-.293-.274-.597-.29-.922-.015-.32.095-.652.31-.894.214-.242.523-.39.84-.453.316-.067.644-.059.968-.059.324 0 .652-.008.969.059.316.062.625.21.84.453.214.242.324.574.308.894-.015.325-.148.63-.289.922L8 15h3a1.8 1.8 0 00.41-.035.791.791 0 00.36-.195.791.791 0 00.195-.36C12 14.277 12 14.137 12 14v-3.563l.703.297c.29.125.59.239.902.246.313.004.63-.101.864-.308.238-.203.386-.496.46-.8C15 9.565 15 9.25 15 8.937c0-.313 0-.63-.07-.934-.075-.305-.223-.598-.461-.8a1.288 1.288 0 00-.864-.31c-.312.008-.613.122-.902.247L12 7.437V5a1.8 1.8 0 00-.035-.41.791.791 0 00-.195-.36.791.791 0 00-.36-.195C11.277 4 11.137 4 11 4H8l.36-.469c.113-.148.226-.293.316-.457.09-.16.16-.332.191-.515a1.248 1.248 0 00-.02-.551 1.256 1.256 0 00-.265-.485c-.242-.273-.605-.425-.973-.476-.367-.05-.738-.016-1.109-.016zm0 0" fill="#474747"/></svg>
|
After Width: | Height: | Size: 1.4 KiB |
1
data/icons/meson.build
Normal file
1
data/icons/meson.build
Normal file
@ -0,0 +1 @@
|
|||||||
|
install_subdir('hicolor', install_dir: icondir)
|
@ -1,5 +1,6 @@
|
|||||||
desktop_files = [
|
desktop_files = [
|
||||||
'org.gnome.Shell.desktop',
|
'org.gnome.Shell.desktop',
|
||||||
|
'org.gnome.Shell.Extensions.desktop',
|
||||||
]
|
]
|
||||||
service_files = []
|
service_files = []
|
||||||
|
|
||||||
@ -42,6 +43,7 @@ endforeach
|
|||||||
|
|
||||||
|
|
||||||
subdir('dbus-interfaces')
|
subdir('dbus-interfaces')
|
||||||
|
subdir('icons')
|
||||||
subdir('theme')
|
subdir('theme')
|
||||||
|
|
||||||
data_resources = [
|
data_resources = [
|
||||||
|
10
data/org.gnome.Shell.Extensions.desktop.in.in
Normal file
10
data/org.gnome.Shell.Extensions.desktop.in.in
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
[Desktop Entry]
|
||||||
|
Type=Application
|
||||||
|
# Keep in sync with subprojects/extensions-app
|
||||||
|
Name=Extensions
|
||||||
|
# Translators: Do NOT translate or transliterate this text (this is an icon file name)!
|
||||||
|
Icon=org.gnome.Shell.Extensions
|
||||||
|
# Never launch this, just provide name+icon to portal dialog
|
||||||
|
Exec=false
|
||||||
|
OnlyShowIn=GNOME;
|
||||||
|
NoDisplay=true
|
@ -153,9 +153,11 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.calendar-day-with-events {
|
.calendar-day-with-events {
|
||||||
color: lighten($fg_color,10%);
|
|
||||||
font-weight: bold;
|
|
||||||
background-image: url("resource:///org/gnome/shell/theme/calendar-today.svg");
|
background-image: url("resource:///org/gnome/shell/theme/calendar-today.svg");
|
||||||
|
&.calendar-work-day {
|
||||||
|
color: lighten($fg_color,10%);
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.calendar-other-month-day {
|
.calendar-other-month-day {
|
||||||
|
@ -184,7 +184,7 @@ var AuthPrompt = GObject.registerClass({
|
|||||||
});
|
});
|
||||||
this._defaultButtonWell.add_constraint(new Clutter.BindConstraint({
|
this._defaultButtonWell.add_constraint(new Clutter.BindConstraint({
|
||||||
source: this.cancelButton,
|
source: this.cancelButton,
|
||||||
coordinate: Clutter.BindCoordinate.SIZE,
|
coordinate: Clutter.BindCoordinate.WIDTH,
|
||||||
}));
|
}));
|
||||||
this._mainBox.add_child(this._defaultButtonWell);
|
this._mainBox.add_child(this._defaultButtonWell);
|
||||||
|
|
||||||
@ -424,7 +424,13 @@ var AuthPrompt = GObject.registerClass({
|
|||||||
}
|
}
|
||||||
|
|
||||||
updateSensitivity(sensitive) {
|
updateSensitivity(sensitive) {
|
||||||
|
if (this._entry.reactive === sensitive)
|
||||||
|
return;
|
||||||
|
|
||||||
this._entry.reactive = sensitive;
|
this._entry.reactive = sensitive;
|
||||||
|
|
||||||
|
if (sensitive)
|
||||||
|
this._entry.grab_key_focus();
|
||||||
}
|
}
|
||||||
|
|
||||||
vfunc_hide() {
|
vfunc_hide() {
|
||||||
|
@ -810,12 +810,13 @@ var LoginDialog = GObject.registerClass({
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
this._logoBin.destroy_all_children();
|
this._logoBin.destroy_all_children();
|
||||||
if (this._logoFile && this._logoBin.resource_scale > 0) {
|
const [valid, resourceScale] = this._logoBin.get_resource_scale();
|
||||||
|
if (this._logoFile && valid) {
|
||||||
let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor;
|
let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor;
|
||||||
this._logoBin.add_child(this._textureCache.load_file_async(this._logoFile,
|
this._logoBin.add_child(this._textureCache.load_file_async(this._logoFile,
|
||||||
-1, -1,
|
-1, -1,
|
||||||
scaleFactor,
|
scaleFactor,
|
||||||
this._logoBin.resource_scale));
|
resourceScale));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
/* exported BANNER_MESSAGE_KEY, BANNER_MESSAGE_TEXT_KEY, LOGO_KEY,
|
/* exported BANNER_MESSAGE_KEY, BANNER_MESSAGE_TEXT_KEY, LOGO_KEY,
|
||||||
DISABLE_USER_LIST_KEY, fadeInActor, fadeOutActor, cloneAndFadeOutActor */
|
DISABLE_USER_LIST_KEY, fadeInActor, fadeOutActor, cloneAndFadeOutActor */
|
||||||
|
|
||||||
const { Clutter, Gio, GLib } = imports.gi;
|
const { Clutter, Gdm, Gio, GLib } = imports.gi;
|
||||||
const Signals = imports.signals;
|
const Signals = imports.signals;
|
||||||
|
|
||||||
const Batch = imports.gdm.batch;
|
const Batch = imports.gdm.batch;
|
||||||
@ -12,6 +12,15 @@ const Main = imports.ui.main;
|
|||||||
const Params = imports.misc.params;
|
const Params = imports.misc.params;
|
||||||
const SmartcardManager = imports.misc.smartcardManager;
|
const SmartcardManager = imports.misc.smartcardManager;
|
||||||
|
|
||||||
|
Gio._promisify(Gdm.Client.prototype,
|
||||||
|
'open_reauthentication_channel', 'open_reauthentication_channel_finish');
|
||||||
|
Gio._promisify(Gdm.Client.prototype,
|
||||||
|
'get_user_verifier', 'get_user_verifier_finish');
|
||||||
|
Gio._promisify(Gdm.UserVerifierProxy.prototype,
|
||||||
|
'call_begin_verification_for_user', 'call_begin_verification_for_user_finish');
|
||||||
|
Gio._promisify(Gdm.UserVerifierProxy.prototype,
|
||||||
|
'call_begin_verification', 'call_begin_verification_finish');
|
||||||
|
|
||||||
var PASSWORD_SERVICE_NAME = 'gdm-password';
|
var PASSWORD_SERVICE_NAME = 'gdm-password';
|
||||||
var FINGERPRINT_SERVICE_NAME = 'gdm-fingerprint';
|
var FINGERPRINT_SERVICE_NAME = 'gdm-fingerprint';
|
||||||
var SMARTCARD_SERVICE_NAME = 'gdm-smartcard';
|
var SMARTCARD_SERVICE_NAME = 'gdm-smartcard';
|
||||||
@ -168,14 +177,12 @@ var ShellUserVerifier = class {
|
|||||||
|
|
||||||
this._checkForFingerprintReader();
|
this._checkForFingerprintReader();
|
||||||
|
|
||||||
if (userName) {
|
// If possible, reauthenticate an already running session,
|
||||||
// If possible, reauthenticate an already running session,
|
// so any session specific credentials get updated appropriately
|
||||||
// so any session specific credentials get updated appropriately
|
if (userName)
|
||||||
this._client.open_reauthentication_channel(userName, this._cancellable,
|
this._openReauthenticationChannel(userName);
|
||||||
this._reauthenticationChannelOpened.bind(this));
|
else
|
||||||
} else {
|
this._getUserVerifier();
|
||||||
this._client.get_user_verifier(this._cancellable, this._userVerifierGot.bind(this));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cancel() {
|
cancel() {
|
||||||
@ -339,10 +346,11 @@ var ShellUserVerifier = class {
|
|||||||
this._verificationFailed(false);
|
this._verificationFailed(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
_reauthenticationChannelOpened(client, result) {
|
async _openReauthenticationChannel(userName) {
|
||||||
try {
|
try {
|
||||||
this._clearUserVerifier();
|
this._clearUserVerifier();
|
||||||
this._userVerifier = client.open_reauthentication_channel_finish(result);
|
this._userVerifier = await this._client.open_reauthentication_channel(
|
||||||
|
userName, this._cancellable);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED))
|
if (e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED))
|
||||||
return;
|
return;
|
||||||
@ -351,8 +359,7 @@ var ShellUserVerifier = class {
|
|||||||
// Gdm emits org.freedesktop.DBus.Error.AccessDenied when there
|
// Gdm emits org.freedesktop.DBus.Error.AccessDenied when there
|
||||||
// is no session to reauthenticate. Fall back to performing
|
// is no session to reauthenticate. Fall back to performing
|
||||||
// verification from this login session
|
// verification from this login session
|
||||||
client.get_user_verifier(this._cancellable,
|
this._getUserVerifier();
|
||||||
this._userVerifierGot.bind(this));
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -366,10 +373,11 @@ var ShellUserVerifier = class {
|
|||||||
this._hold.release();
|
this._hold.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
_userVerifierGot(client, result) {
|
async _getUserVerifier() {
|
||||||
try {
|
try {
|
||||||
this._clearUserVerifier();
|
this._clearUserVerifier();
|
||||||
this._userVerifier = client.get_user_verifier_finish(result);
|
this._userVerifier =
|
||||||
|
await this._client.get_user_verifier(this._cancellable);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED))
|
if (e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED))
|
||||||
return;
|
return;
|
||||||
@ -421,35 +429,25 @@ var ShellUserVerifier = class {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_startService(serviceName) {
|
async _startService(serviceName) {
|
||||||
this._hold.acquire();
|
this._hold.acquire();
|
||||||
if (this._userName) {
|
try {
|
||||||
this._userVerifier.call_begin_verification_for_user(serviceName, this._userName, this._cancellable, (obj, result) => {
|
if (this._userName) {
|
||||||
try {
|
await this._userVerifier.call_begin_verification_for_user(
|
||||||
obj.call_begin_verification_for_user_finish(result);
|
serviceName, this._userName, this._cancellable);
|
||||||
} catch (e) {
|
} else {
|
||||||
if (e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED))
|
await this._userVerifier.call_begin_verification(
|
||||||
return;
|
serviceName, this._cancellable);
|
||||||
this._reportInitError('Failed to start verification for user', e);
|
}
|
||||||
return;
|
} catch (e) {
|
||||||
}
|
if (e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED))
|
||||||
|
return;
|
||||||
this._hold.release();
|
this._reportInitError(this._userName
|
||||||
});
|
? 'Failed to start verification for user'
|
||||||
} else {
|
: 'Failed to start verification', e);
|
||||||
this._userVerifier.call_begin_verification(serviceName, this._cancellable, (obj, result) => {
|
return;
|
||||||
try {
|
|
||||||
obj.call_begin_verification_finish(result);
|
|
||||||
} catch (e) {
|
|
||||||
if (e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED))
|
|
||||||
return;
|
|
||||||
this._reportInitError('Failed to start verification', e);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this._hold.release();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
this._hold.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
_beginVerification() {
|
_beginVerification() {
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
<file>misc/modemManager.js</file>
|
<file>misc/modemManager.js</file>
|
||||||
<file>misc/objectManager.js</file>
|
<file>misc/objectManager.js</file>
|
||||||
<file>misc/params.js</file>
|
<file>misc/params.js</file>
|
||||||
|
<file>misc/parentalControlsManager.js</file>
|
||||||
<file>misc/permissionStore.js</file>
|
<file>misc/permissionStore.js</file>
|
||||||
<file>misc/smartcardManager.js</file>
|
<file>misc/smartcardManager.js</file>
|
||||||
<file>misc/systemActions.js</file>
|
<file>misc/systemActions.js</file>
|
||||||
@ -101,7 +102,6 @@
|
|||||||
<file>ui/swipeTracker.js</file>
|
<file>ui/swipeTracker.js</file>
|
||||||
<file>ui/switcherPopup.js</file>
|
<file>ui/switcherPopup.js</file>
|
||||||
<file>ui/switchMonitor.js</file>
|
<file>ui/switchMonitor.js</file>
|
||||||
<file>ui/tweener.js</file>
|
|
||||||
<file>ui/unlockDialog.js</file>
|
<file>ui/unlockDialog.js</file>
|
||||||
<file>ui/userWidget.js</file>
|
<file>ui/userWidget.js</file>
|
||||||
<file>ui/viewSelector.js</file>
|
<file>ui/viewSelector.js</file>
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
/* exported ExtensionState, ExtensionType, getCurrentExtension,
|
/* exported ExtensionState, ExtensionType, getCurrentExtension,
|
||||||
getSettings, initTranslations, isOutOfDate, installImporter,
|
getSettings, initTranslations, openPrefs, isOutOfDate,
|
||||||
serializeExtension, deserializeExtension */
|
installImporter, serializeExtension, deserializeExtension */
|
||||||
|
|
||||||
// Common utils for the extension system and the extension
|
// Common utils for the extension system and the extension
|
||||||
// preferences tool
|
// preferences tool
|
||||||
@ -153,6 +153,27 @@ function getSettings(schema) {
|
|||||||
return new Gio.Settings({ settings_schema: schemaObj });
|
return new Gio.Settings({ settings_schema: schemaObj });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* openPrefs:
|
||||||
|
*
|
||||||
|
* Open the preference dialog of the current extension
|
||||||
|
*/
|
||||||
|
function openPrefs() {
|
||||||
|
const extension = getCurrentExtension();
|
||||||
|
|
||||||
|
if (!extension)
|
||||||
|
throw new Error('openPrefs() can only be called from extensions');
|
||||||
|
|
||||||
|
try {
|
||||||
|
const extensionManager = imports.ui.main.extensionManager;
|
||||||
|
extensionManager.openExtensionPrefs(extension.uuid, '', {});
|
||||||
|
} catch (e) {
|
||||||
|
if (e.name === 'ImportError')
|
||||||
|
throw new Error('openPrefs() cannot be called from preferences');
|
||||||
|
logError(e, 'Failed to open extension preferences');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* versionCheck:
|
* versionCheck:
|
||||||
* @param {string[]} required - an array of versions we're compatible with
|
* @param {string[]} required - an array of versions we're compatible with
|
||||||
|
@ -6,6 +6,15 @@ const Signals = imports.signals;
|
|||||||
|
|
||||||
const IBusCandidatePopup = imports.ui.ibusCandidatePopup;
|
const IBusCandidatePopup = imports.ui.ibusCandidatePopup;
|
||||||
|
|
||||||
|
Gio._promisify(IBus.Bus.prototype,
|
||||||
|
'list_engines_async', 'list_engines_async_finish');
|
||||||
|
Gio._promisify(IBus.Bus.prototype,
|
||||||
|
'request_name_async', 'request_name_async_finish');
|
||||||
|
Gio._promisify(IBus.Bus.prototype,
|
||||||
|
'get_global_engine_async', 'get_global_engine_async_finish');
|
||||||
|
Gio._promisify(IBus.Bus.prototype,
|
||||||
|
'set_global_engine_async', 'set_global_engine_async_finish');
|
||||||
|
|
||||||
// Ensure runtime version matches
|
// Ensure runtime version matches
|
||||||
_checkIBusVersion(1, 5, 2);
|
_checkIBusVersion(1, 5, 2);
|
||||||
|
|
||||||
@ -102,16 +111,14 @@ var IBusManager = class {
|
|||||||
|
|
||||||
_onConnected() {
|
_onConnected() {
|
||||||
this._cancellable = new Gio.Cancellable();
|
this._cancellable = new Gio.Cancellable();
|
||||||
this._ibus.list_engines_async(-1, this._cancellable,
|
this._initEngines();
|
||||||
this._initEngines.bind(this));
|
this._initPanelService();
|
||||||
this._ibus.request_name_async(IBus.SERVICE_PANEL,
|
|
||||||
IBus.BusNameFlag.REPLACE_EXISTING, -1, this._cancellable,
|
|
||||||
this._initPanelService.bind(this));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_initEngines(ibus, result) {
|
async _initEngines() {
|
||||||
try {
|
try {
|
||||||
let enginesList = this._ibus.list_engines_async_finish(result);
|
const enginesList =
|
||||||
|
await this._ibus.list_engines_async(-1, this._cancellable);
|
||||||
for (let i = 0; i < enginesList.length; ++i) {
|
for (let i = 0; i < enginesList.length; ++i) {
|
||||||
let name = enginesList[i].get_name();
|
let name = enginesList[i].get_name();
|
||||||
this._engines.set(name, enginesList[i]);
|
this._engines.set(name, enginesList[i]);
|
||||||
@ -126,9 +133,10 @@ var IBusManager = class {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_initPanelService(ibus, result) {
|
async _initPanelService() {
|
||||||
try {
|
try {
|
||||||
this._ibus.request_name_async_finish(result);
|
await this._ibus.request_name_async(IBus.SERVICE_PANEL,
|
||||||
|
IBus.BusNameFlag.REPLACE_EXISTING, -1, this._cancellable);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (!e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED)) {
|
if (!e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED)) {
|
||||||
logError(e);
|
logError(e);
|
||||||
@ -163,19 +171,15 @@ var IBusManager = class {
|
|||||||
this._panelService.connect('set-content-type', this._setContentType.bind(this));
|
this._panelService.connect('set-content-type', this._setContentType.bind(this));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
}
|
}
|
||||||
// If an engine is already active we need to get its properties
|
|
||||||
this._ibus.get_global_engine_async(-1, this._cancellable, (_bus, res) => {
|
try {
|
||||||
let engine;
|
// If an engine is already active we need to get its properties
|
||||||
try {
|
const engine =
|
||||||
engine = this._ibus.get_global_engine_async_finish(res);
|
await this._ibus.get_global_engine_async(-1, this._cancellable);
|
||||||
if (!engine)
|
|
||||||
return;
|
|
||||||
} catch (e) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this._engineChanged(this._ibus, engine.get_name());
|
this._engineChanged(this._ibus, engine.get_name());
|
||||||
});
|
this._updateReadiness();
|
||||||
this._updateReadiness();
|
} catch (e) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_updateReadiness() {
|
_updateReadiness() {
|
||||||
@ -223,7 +227,7 @@ var IBusManager = class {
|
|||||||
return this._engines.get(id);
|
return this._engines.get(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
setEngine(id, callback) {
|
async setEngine(id, callback) {
|
||||||
// Send id even if id == this._currentEngineName
|
// Send id even if id == this._currentEngineName
|
||||||
// because 'properties-registered' signal can be emitted
|
// because 'properties-registered' signal can be emitted
|
||||||
// while this._ibusSources == null on a lock screen.
|
// while this._ibusSources == null on a lock screen.
|
||||||
@ -233,18 +237,16 @@ var IBusManager = class {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this._ibus.set_global_engine_async(id,
|
try {
|
||||||
this._MAX_INPUT_SOURCE_ACTIVATION_TIME,
|
await this._ibus.set_global_engine_async(id,
|
||||||
this._cancellable, (_bus, res) => {
|
this._MAX_INPUT_SOURCE_ACTIVATION_TIME,
|
||||||
try {
|
this._cancellable);
|
||||||
this._ibus.set_global_engine_async_finish(res);
|
} catch (e) {
|
||||||
} catch (e) {
|
if (!e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED))
|
||||||
if (!e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED))
|
logError(e);
|
||||||
logError(e);
|
}
|
||||||
}
|
if (callback)
|
||||||
if (callback)
|
callback();
|
||||||
callback();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
preloadEngines(ids) {
|
preloadEngines(ids) {
|
||||||
|
@ -4,6 +4,9 @@ const { Clutter, GLib, Gio, GObject, IBus } = imports.gi;
|
|||||||
|
|
||||||
const Keyboard = imports.ui.status.keyboard;
|
const Keyboard = imports.ui.status.keyboard;
|
||||||
|
|
||||||
|
Gio._promisify(IBus.Bus.prototype,
|
||||||
|
'create_input_context_async', 'create_input_context_async_finish');
|
||||||
|
|
||||||
var HIDE_PANEL_TIME = 50;
|
var HIDE_PANEL_TIME = 50;
|
||||||
|
|
||||||
var InputMethod = GObject.registerClass(
|
var InputMethod = GObject.registerClass(
|
||||||
@ -46,15 +49,11 @@ class InputMethod extends Clutter.InputMethod {
|
|||||||
this._currentSource = this._inputSourceManager.currentSource;
|
this._currentSource = this._inputSourceManager.currentSource;
|
||||||
}
|
}
|
||||||
|
|
||||||
_onConnected() {
|
async _onConnected() {
|
||||||
this._cancellable = new Gio.Cancellable();
|
this._cancellable = new Gio.Cancellable();
|
||||||
this._ibus.create_input_context_async('gnome-shell', -1,
|
|
||||||
this._cancellable, this._setContext.bind(this));
|
|
||||||
}
|
|
||||||
|
|
||||||
_setContext(bus, res) {
|
|
||||||
try {
|
try {
|
||||||
this._context = this._ibus.create_input_context_async_finish(res);
|
this._context = await this._ibus.create_input_context_async(
|
||||||
|
'gnome-shell', -1, this._cancellable);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (!e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED)) {
|
if (!e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED)) {
|
||||||
logError(e);
|
logError(e);
|
||||||
|
@ -24,8 +24,7 @@ function getCompletions(text, commandHeader, globalCompletionList) {
|
|||||||
[expr_, base, attrHead] = matches;
|
[expr_, base, attrHead] = matches;
|
||||||
|
|
||||||
methods = getPropertyNamesFromExpression(base, commandHeader).filter(
|
methods = getPropertyNamesFromExpression(base, commandHeader).filter(
|
||||||
attr => attr.slice(0, attrHead.length) == attrHead
|
attr => attr.slice(0, attrHead.length) === attrHead);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Look for the empty expression or partially entered words
|
// Look for the empty expression or partially entered words
|
||||||
@ -34,8 +33,7 @@ function getCompletions(text, commandHeader, globalCompletionList) {
|
|||||||
if (text == '' || matches) {
|
if (text == '' || matches) {
|
||||||
[expr_, attrHead] = matches;
|
[expr_, attrHead] = matches;
|
||||||
methods = globalCompletionList.filter(
|
methods = globalCompletionList.filter(
|
||||||
attr => attr.slice(0, attrHead.length) == attrHead
|
attr => attr.slice(0, attrHead.length) === attrHead);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
/* exported getKeyboardManager, holdKeyboard, releaseKeyboard */
|
/* exported getKeyboardManager, holdKeyboard, releaseKeyboard */
|
||||||
|
|
||||||
const { GLib, GnomeDesktop, Meta } = imports.gi;
|
const { GLib, GnomeDesktop } = imports.gi;
|
||||||
|
|
||||||
const Main = imports.ui.main;
|
const Main = imports.ui.main;
|
||||||
|
|
||||||
@ -62,11 +62,11 @@ var KeyboardManager = class {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
this._currentKeymap = { layouts, variants, options };
|
this._currentKeymap = { layouts, variants, options };
|
||||||
Meta.get_backend().set_keymap(layouts, variants, options);
|
global.backend.set_keymap(layouts, variants, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
_applyLayoutGroupIndex(idx) {
|
_applyLayoutGroupIndex(idx) {
|
||||||
Meta.get_backend().lock_layout_group(idx);
|
global.backend.lock_layout_group(idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
apply(id) {
|
apply(id) {
|
||||||
|
@ -50,25 +50,22 @@ function canLock() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function registerSessionWithGDM() {
|
async function registerSessionWithGDM() {
|
||||||
log("Registering session with GDM");
|
log("Registering session with GDM");
|
||||||
Gio.DBus.system.call('org.gnome.DisplayManager',
|
try {
|
||||||
'/org/gnome/DisplayManager/Manager',
|
await Gio.DBus.system.call(
|
||||||
'org.gnome.DisplayManager.Manager',
|
'org.gnome.DisplayManager',
|
||||||
'RegisterSession',
|
'/org/gnome/DisplayManager/Manager',
|
||||||
GLib.Variant.new('(a{sv})', [{}]), null,
|
'org.gnome.DisplayManager.Manager',
|
||||||
Gio.DBusCallFlags.NONE, -1, null,
|
'RegisterSession',
|
||||||
(source, result) => {
|
GLib.Variant.new('(a{sv})', [{}]), null,
|
||||||
try {
|
Gio.DBusCallFlags.NONE, -1, null);
|
||||||
source.call_finish(result);
|
} catch (e) {
|
||||||
} catch (e) {
|
if (!e.matches(Gio.DBusError, Gio.DBusError.UNKNOWN_METHOD))
|
||||||
if (!e.matches(Gio.DBusError, Gio.DBusError.UNKNOWN_METHOD))
|
log(`Error registering session with GDM: ${e.message}`);
|
||||||
log(`Error registering session with GDM: ${e.message}`);
|
else
|
||||||
else
|
log('Not calling RegisterSession(): method not exported, GDM too old?');
|
||||||
log("Not calling RegisterSession(): method not exported, GDM too old?");
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let _loginManager = null;
|
let _loginManager = null;
|
||||||
@ -174,24 +171,19 @@ var LoginManagerSystemd = class {
|
|||||||
this._proxy.SuspendRemote(true);
|
this._proxy.SuspendRemote(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
inhibit(reason, callback) {
|
async inhibit(reason, callback) {
|
||||||
let inVariant = GLib.Variant.new('(ssss)',
|
try {
|
||||||
['sleep',
|
const inVariant = new GLib.Variant('(ssss)',
|
||||||
'GNOME Shell',
|
['sleep', 'GNOME Shell', reason, 'delay']);
|
||||||
reason,
|
const [outVariant_, fdList] =
|
||||||
'delay']);
|
await this._proxy.call_with_unix_fd_list('Inhibit',
|
||||||
this._proxy.call_with_unix_fd_list('Inhibit', inVariant, 0, -1, null, null,
|
inVariant, 0, -1, null, null);
|
||||||
(proxy, result) => {
|
const [fd] = fdList.steal_fds();
|
||||||
let fd = -1;
|
callback(new Gio.UnixInputStream({ fd }));
|
||||||
try {
|
} catch (e) {
|
||||||
let [outVariant_, fdList] = proxy.call_with_unix_fd_list_finish(result);
|
logError(e, 'Error getting systemd inhibitor');
|
||||||
fd = fdList.steal_fds()[0];
|
callback(null);
|
||||||
callback(new Gio.UnixInputStream({ fd }));
|
}
|
||||||
} catch (e) {
|
|
||||||
logError(e, "Error getting systemd inhibitor");
|
|
||||||
callback(null);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_prepareForSleep(proxy, sender, [aboutToSuspend]) {
|
_prepareForSleep(proxy, sender, [aboutToSuspend]) {
|
||||||
|
@ -57,9 +57,7 @@ var ObjectManager = class {
|
|||||||
// Start out inhibiting load until at least the proxy
|
// Start out inhibiting load until at least the proxy
|
||||||
// manager is loaded and the remote objects are fetched
|
// manager is loaded and the remote objects are fetched
|
||||||
this._numLoadInhibitors = 1;
|
this._numLoadInhibitors = 1;
|
||||||
this._managerProxy.init_async(GLib.PRIORITY_DEFAULT,
|
this._initManagerProxy();
|
||||||
this._cancellable,
|
|
||||||
this._onManagerProxyLoaded.bind(this));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_tryToCompleteLoad() {
|
_tryToCompleteLoad() {
|
||||||
@ -73,7 +71,7 @@ var ObjectManager = class {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_addInterface(objectPath, interfaceName, onFinished) {
|
async _addInterface(objectPath, interfaceName, onFinished) {
|
||||||
let info = this._interfaceInfos[interfaceName];
|
let info = this._interfaceInfos[interfaceName];
|
||||||
|
|
||||||
if (!info) {
|
if (!info) {
|
||||||
@ -89,40 +87,38 @@ var ObjectManager = class {
|
|||||||
g_interface_info: info,
|
g_interface_info: info,
|
||||||
g_flags: Gio.DBusProxyFlags.DO_NOT_AUTO_START });
|
g_flags: Gio.DBusProxyFlags.DO_NOT_AUTO_START });
|
||||||
|
|
||||||
proxy.init_async(GLib.PRIORITY_DEFAULT, this._cancellable, (initable, result) => {
|
try {
|
||||||
try {
|
await proxy.init_async(GLib.PRIORITY_DEFAULT, this._cancellable);
|
||||||
initable.init_finish(result);
|
} catch (e) {
|
||||||
} catch (e) {
|
logError(e, `could not initialize proxy for interface ${interfaceName}`);
|
||||||
logError(e, `could not initialize proxy for interface ${interfaceName}`);
|
|
||||||
|
|
||||||
if (onFinished)
|
|
||||||
onFinished();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let isNewObject;
|
|
||||||
if (!this._objects[objectPath]) {
|
|
||||||
this._objects[objectPath] = {};
|
|
||||||
isNewObject = true;
|
|
||||||
} else {
|
|
||||||
isNewObject = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
this._objects[objectPath][interfaceName] = proxy;
|
|
||||||
|
|
||||||
if (!this._interfaces[interfaceName])
|
|
||||||
this._interfaces[interfaceName] = [];
|
|
||||||
|
|
||||||
this._interfaces[interfaceName].push(proxy);
|
|
||||||
|
|
||||||
if (isNewObject)
|
|
||||||
this.emit('object-added', objectPath);
|
|
||||||
|
|
||||||
this.emit('interface-added', interfaceName, proxy);
|
|
||||||
|
|
||||||
if (onFinished)
|
if (onFinished)
|
||||||
onFinished();
|
onFinished();
|
||||||
});
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let isNewObject;
|
||||||
|
if (!this._objects[objectPath]) {
|
||||||
|
this._objects[objectPath] = {};
|
||||||
|
isNewObject = true;
|
||||||
|
} else {
|
||||||
|
isNewObject = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._objects[objectPath][interfaceName] = proxy;
|
||||||
|
|
||||||
|
if (!this._interfaces[interfaceName])
|
||||||
|
this._interfaces[interfaceName] = [];
|
||||||
|
|
||||||
|
this._interfaces[interfaceName].push(proxy);
|
||||||
|
|
||||||
|
if (isNewObject)
|
||||||
|
this.emit('object-added', objectPath);
|
||||||
|
|
||||||
|
this.emit('interface-added', interfaceName, proxy);
|
||||||
|
|
||||||
|
if (onFinished)
|
||||||
|
onFinished();
|
||||||
}
|
}
|
||||||
|
|
||||||
_removeInterface(objectPath, interfaceName) {
|
_removeInterface(objectPath, interfaceName) {
|
||||||
@ -151,9 +147,10 @@ var ObjectManager = class {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_onManagerProxyLoaded(initable, result) {
|
async _initManagerProxy() {
|
||||||
try {
|
try {
|
||||||
initable.init_finish(result);
|
await this._managerProxy.init_async(
|
||||||
|
GLib.PRIORITY_DEFAULT, this._cancellable);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
logError(e, `could not initialize object manager for object ${this._serviceName}`);
|
logError(e, `could not initialize object manager for object ${this._serviceName}`);
|
||||||
|
|
||||||
|
146
js/misc/parentalControlsManager.js
Normal file
146
js/misc/parentalControlsManager.js
Normal file
@ -0,0 +1,146 @@
|
|||||||
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
//
|
||||||
|
// Copyright (C) 2018, 2019, 2020 Endless Mobile, Inc.
|
||||||
|
//
|
||||||
|
// This is a GNOME Shell component to wrap the interactions over
|
||||||
|
// D-Bus with the malcontent library.
|
||||||
|
//
|
||||||
|
// Licensed under the GNU General Public License Version 2
|
||||||
|
//
|
||||||
|
// This program is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License
|
||||||
|
// as published by the Free Software Foundation; either version 2
|
||||||
|
// of the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program; if not, write to the Free Software
|
||||||
|
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
/* exported getDefault */
|
||||||
|
|
||||||
|
const { Gio, GObject, Shell } = imports.gi;
|
||||||
|
|
||||||
|
// We require libmalcontent ≥ 0.6.0
|
||||||
|
const HAVE_MALCONTENT = imports.package.checkSymbol(
|
||||||
|
'Malcontent', '0', 'ManagerGetValueFlags');
|
||||||
|
|
||||||
|
var Malcontent = null;
|
||||||
|
if (HAVE_MALCONTENT) {
|
||||||
|
Malcontent = imports.gi.Malcontent;
|
||||||
|
Gio._promisify(Malcontent.Manager.prototype, 'get_app_filter_async', 'get_app_filter_finish');
|
||||||
|
}
|
||||||
|
|
||||||
|
let _singleton = null;
|
||||||
|
|
||||||
|
function getDefault() {
|
||||||
|
if (_singleton === null)
|
||||||
|
_singleton = new ParentalControlsManager();
|
||||||
|
|
||||||
|
return _singleton;
|
||||||
|
}
|
||||||
|
|
||||||
|
// A manager class which provides cached access to the constructing user’s
|
||||||
|
// parental controls settings. It’s possible for the user’s parental controls
|
||||||
|
// to change at runtime if the Parental Controls application is used by an
|
||||||
|
// administrator from within the user’s session.
|
||||||
|
var ParentalControlsManager = GObject.registerClass({
|
||||||
|
Signals: {
|
||||||
|
'app-filter-changed': {},
|
||||||
|
},
|
||||||
|
}, class ParentalControlsManager extends GObject.Object {
|
||||||
|
_init() {
|
||||||
|
super._init();
|
||||||
|
|
||||||
|
this._initialized = false;
|
||||||
|
this._disabled = false;
|
||||||
|
this._appFilter = null;
|
||||||
|
|
||||||
|
this._initializeManager();
|
||||||
|
}
|
||||||
|
|
||||||
|
async _initializeManager() {
|
||||||
|
if (!HAVE_MALCONTENT) {
|
||||||
|
log('Skipping parental controls support as it’s disabled');
|
||||||
|
this._initialized = true;
|
||||||
|
this.emit('app-filter-changed');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
log(`Getting parental controls for user ${Shell.util_get_uid()}`);
|
||||||
|
try {
|
||||||
|
const connection = await Gio.DBus.get(Gio.BusType.SYSTEM, null);
|
||||||
|
this._manager = new Malcontent.Manager({ connection });
|
||||||
|
this._appFilter = await this._manager.get_app_filter_async(
|
||||||
|
Shell.util_get_uid(),
|
||||||
|
Malcontent.ManagerGetValueFlags.NONE,
|
||||||
|
null);
|
||||||
|
} catch (e) {
|
||||||
|
if (e.matches(Malcontent.ManagerError, Malcontent.ManagerError.DISABLED)) {
|
||||||
|
log('Parental controls globally disabled');
|
||||||
|
this._disabled = true;
|
||||||
|
} else {
|
||||||
|
logError(e, 'Failed to get parental controls settings');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this._manager.connect('app-filter-changed', this._onAppFilterChanged.bind(this));
|
||||||
|
|
||||||
|
// Signal initialisation is complete.
|
||||||
|
this._initialized = true;
|
||||||
|
this.emit('app-filter-changed');
|
||||||
|
}
|
||||||
|
|
||||||
|
async _onAppFilterChanged(manager, uid) {
|
||||||
|
// Emit 'changed' signal only if app-filter is changed for currently logged-in user.
|
||||||
|
let currentUid = Shell.util_get_uid();
|
||||||
|
if (currentUid !== uid)
|
||||||
|
return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
this._appFilter = await this._manager.get_app_filter_async(
|
||||||
|
currentUid,
|
||||||
|
Malcontent.ManagerGetValueFlags.NONE,
|
||||||
|
null);
|
||||||
|
this.emit('app-filter-changed');
|
||||||
|
} catch (e) {
|
||||||
|
// Log an error and keep the old app filter.
|
||||||
|
logError(e, `Failed to get new MctAppFilter for uid ${Shell.util_get_uid()} on app-filter-changed`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
get initialized() {
|
||||||
|
return this._initialized;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate whether the given app (a Gio.DesktopAppInfo) should be shown
|
||||||
|
// on the desktop, in search results, etc. The app should be shown if:
|
||||||
|
// - The .desktop file doesn’t say it should be hidden.
|
||||||
|
// - The executable from the .desktop file’s Exec line isn’t blacklisted in
|
||||||
|
// the user’s parental controls.
|
||||||
|
// - None of the flatpak app IDs from the X-Flatpak and the
|
||||||
|
// X-Flatpak-RenamedFrom lines are blacklisted in the user’s parental
|
||||||
|
// controls.
|
||||||
|
shouldShowApp(appInfo) {
|
||||||
|
// Quick decision?
|
||||||
|
if (!appInfo.should_show())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Are parental controls enabled (at configure time or runtime)?
|
||||||
|
if (!HAVE_MALCONTENT || this._disabled)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// Have we finished initialising yet?
|
||||||
|
if (!this.initialized) {
|
||||||
|
log(`Warning: Hiding app because parental controls not yet initialised: ${appInfo.get_id()}`);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this._appFilter.is_appinfo_allowed(appInfo);
|
||||||
|
}
|
||||||
|
});
|
@ -83,13 +83,17 @@ const SystemActions = GObject.registerClass({
|
|||||||
this._canHavePowerOff = true;
|
this._canHavePowerOff = true;
|
||||||
this._canHaveSuspend = true;
|
this._canHaveSuspend = true;
|
||||||
|
|
||||||
|
function tokenizeKeywords(keywords) {
|
||||||
|
return keywords.split(';').map(keyword => GLib.str_tokenize_and_fold(keyword, null)).flat(2);
|
||||||
|
}
|
||||||
|
|
||||||
this._actions = new Map();
|
this._actions = new Map();
|
||||||
this._actions.set(POWER_OFF_ACTION_ID, {
|
this._actions.set(POWER_OFF_ACTION_ID, {
|
||||||
// Translators: The name of the power-off action in search
|
// Translators: The name of the power-off action in search
|
||||||
name: C_("search-result", "Power Off"),
|
name: C_("search-result", "Power Off"),
|
||||||
iconName: 'system-shutdown-symbolic',
|
iconName: 'system-shutdown-symbolic',
|
||||||
// Translators: A list of keywords that match the power-off action, separated by semicolons
|
// Translators: A list of keywords that match the power-off action, separated by semicolons
|
||||||
keywords: _('power off;shutdown;reboot;restart;halt;stop').split(/[; ]/),
|
keywords: tokenizeKeywords(_('power off;shutdown;reboot;restart;halt;stop')),
|
||||||
available: false,
|
available: false,
|
||||||
});
|
});
|
||||||
this._actions.set(LOCK_SCREEN_ACTION_ID, {
|
this._actions.set(LOCK_SCREEN_ACTION_ID, {
|
||||||
@ -97,7 +101,7 @@ const SystemActions = GObject.registerClass({
|
|||||||
name: C_("search-result", "Lock Screen"),
|
name: C_("search-result", "Lock Screen"),
|
||||||
iconName: 'system-lock-screen-symbolic',
|
iconName: 'system-lock-screen-symbolic',
|
||||||
// Translators: A list of keywords that match the lock screen action, separated by semicolons
|
// Translators: A list of keywords that match the lock screen action, separated by semicolons
|
||||||
keywords: _("lock screen").split(/[; ]/),
|
keywords: tokenizeKeywords(_('lock screen')),
|
||||||
available: false,
|
available: false,
|
||||||
});
|
});
|
||||||
this._actions.set(LOGOUT_ACTION_ID, {
|
this._actions.set(LOGOUT_ACTION_ID, {
|
||||||
@ -105,7 +109,7 @@ const SystemActions = GObject.registerClass({
|
|||||||
name: C_("search-result", "Log Out"),
|
name: C_("search-result", "Log Out"),
|
||||||
iconName: 'application-exit-symbolic',
|
iconName: 'application-exit-symbolic',
|
||||||
// Translators: A list of keywords that match the logout action, separated by semicolons
|
// Translators: A list of keywords that match the logout action, separated by semicolons
|
||||||
keywords: _("logout;log out;sign off").split(/[; ]/),
|
keywords: tokenizeKeywords(_('logout;log out;sign off')),
|
||||||
available: false,
|
available: false,
|
||||||
});
|
});
|
||||||
this._actions.set(SUSPEND_ACTION_ID, {
|
this._actions.set(SUSPEND_ACTION_ID, {
|
||||||
@ -113,7 +117,7 @@ const SystemActions = GObject.registerClass({
|
|||||||
name: C_("search-result", "Suspend"),
|
name: C_("search-result", "Suspend"),
|
||||||
iconName: 'media-playback-pause-symbolic',
|
iconName: 'media-playback-pause-symbolic',
|
||||||
// Translators: A list of keywords that match the suspend action, separated by semicolons
|
// Translators: A list of keywords that match the suspend action, separated by semicolons
|
||||||
keywords: _("suspend;sleep").split(/[; ]/),
|
keywords: tokenizeKeywords(_('suspend;sleep')),
|
||||||
available: false,
|
available: false,
|
||||||
});
|
});
|
||||||
this._actions.set(SWITCH_USER_ACTION_ID, {
|
this._actions.set(SWITCH_USER_ACTION_ID, {
|
||||||
@ -121,14 +125,14 @@ const SystemActions = GObject.registerClass({
|
|||||||
name: C_("search-result", "Switch User"),
|
name: C_("search-result", "Switch User"),
|
||||||
iconName: 'system-switch-user-symbolic',
|
iconName: 'system-switch-user-symbolic',
|
||||||
// Translators: A list of keywords that match the switch user action, separated by semicolons
|
// Translators: A list of keywords that match the switch user action, separated by semicolons
|
||||||
keywords: _("switch user").split(/[; ]/),
|
keywords: tokenizeKeywords(_('switch user')),
|
||||||
available: false,
|
available: false,
|
||||||
});
|
});
|
||||||
this._actions.set(LOCK_ORIENTATION_ACTION_ID, {
|
this._actions.set(LOCK_ORIENTATION_ACTION_ID, {
|
||||||
name: '',
|
name: '',
|
||||||
iconName: '',
|
iconName: '',
|
||||||
// Translators: A list of keywords that match the lock orientation action, separated by semicolons
|
// Translators: A list of keywords that match the lock orientation action, separated by semicolons
|
||||||
keywords: _("lock orientation;unlock orientation;screen;rotation").split(/[; ]/),
|
keywords: tokenizeKeywords(_('lock orientation;unlock orientation;screen;rotation')),
|
||||||
available: false,
|
available: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -277,7 +281,7 @@ const SystemActions = GObject.registerClass({
|
|||||||
|
|
||||||
getMatchingActions(terms) {
|
getMatchingActions(terms) {
|
||||||
// terms is a list of strings
|
// terms is a list of strings
|
||||||
terms = terms.map(term => term.toLowerCase());
|
terms = terms.map(term => GLib.str_tokenize_and_fold(term, null)[0]);
|
||||||
|
|
||||||
let results = [];
|
let results = [];
|
||||||
|
|
||||||
|
@ -7,6 +7,8 @@ const PermissionStore = imports.misc.permissionStore;
|
|||||||
|
|
||||||
const { loadInterfaceXML } = imports.misc.fileUtils;
|
const { loadInterfaceXML } = imports.misc.fileUtils;
|
||||||
|
|
||||||
|
Gio._promisify(Geoclue.Simple, 'new', 'new_finish');
|
||||||
|
|
||||||
const WeatherIntegrationIface = loadInterfaceXML('org.gnome.Shell.WeatherIntegration');
|
const WeatherIntegrationIface = loadInterfaceXML('org.gnome.Shell.WeatherIntegration');
|
||||||
|
|
||||||
const WEATHER_BUS_NAME = 'org.gnome.Weather';
|
const WEATHER_BUS_NAME = 'org.gnome.Weather';
|
||||||
@ -79,16 +81,7 @@ var WeatherClient = class {
|
|||||||
this._weatherApp = null;
|
this._weatherApp = null;
|
||||||
this._weatherProxy = null;
|
this._weatherProxy = null;
|
||||||
|
|
||||||
let nodeInfo = Gio.DBusNodeInfo.new_for_xml(WeatherIntegrationIface);
|
this._createWeatherProxy();
|
||||||
Gio.DBusProxy.new(
|
|
||||||
Gio.DBus.session,
|
|
||||||
Gio.DBusProxyFlags.DO_NOT_AUTO_START | Gio.DBusProxyFlags.GET_INVALIDATED_PROPERTIES,
|
|
||||||
nodeInfo.lookup_interface(WEATHER_INTEGRATION_IFACE),
|
|
||||||
WEATHER_BUS_NAME,
|
|
||||||
WEATHER_OBJECT_PATH,
|
|
||||||
WEATHER_INTEGRATION_IFACE,
|
|
||||||
null,
|
|
||||||
this._onWeatherProxyReady.bind(this));
|
|
||||||
|
|
||||||
this._settings = new Gio.Settings({
|
this._settings = new Gio.Settings({
|
||||||
schema_id: 'org.gnome.shell.weather',
|
schema_id: 'org.gnome.shell.weather',
|
||||||
@ -146,9 +139,17 @@ var WeatherClient = class {
|
|||||||
(!this._needsAuth || this._weatherAuthorized);
|
(!this._needsAuth || this._weatherAuthorized);
|
||||||
}
|
}
|
||||||
|
|
||||||
_onWeatherProxyReady(o, res) {
|
async _createWeatherProxy() {
|
||||||
|
const nodeInfo = Gio.DBusNodeInfo.new_for_xml(WeatherIntegrationIface);
|
||||||
try {
|
try {
|
||||||
this._weatherProxy = Gio.DBusProxy.new_finish(res);
|
this._weatherProxy = await Gio.DBusProxy.new(
|
||||||
|
Gio.DBus.session,
|
||||||
|
Gio.DBusProxyFlags.DO_NOT_AUTO_START | Gio.DBusProxyFlags.GET_INVALIDATED_PROPERTIES,
|
||||||
|
nodeInfo.lookup_interface(WEATHER_INTEGRATION_IFACE),
|
||||||
|
WEATHER_BUS_NAME,
|
||||||
|
WEATHER_OBJECT_PATH,
|
||||||
|
WEATHER_INTEGRATION_IFACE,
|
||||||
|
null);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
log(`Failed to create GNOME Weather proxy: ${e}`);
|
log(`Failed to create GNOME Weather proxy: ${e}`);
|
||||||
return;
|
return;
|
||||||
@ -239,25 +240,23 @@ var WeatherClient = class {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_startGClueService() {
|
async _startGClueService() {
|
||||||
if (this._gclueStarting)
|
if (this._gclueStarting)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
this._gclueStarting = true;
|
this._gclueStarting = true;
|
||||||
|
|
||||||
Geoclue.Simple.new('org.gnome.Shell', Geoclue.AccuracyLevel.CITY, null,
|
try {
|
||||||
(o, res) => {
|
this._gclueService = await Geoclue.Simple.new(
|
||||||
try {
|
'org.gnome.Shell', Geoclue.AccuracyLevel.CITY, null);
|
||||||
this._gclueService = Geoclue.Simple.new_finish(res);
|
} catch (e) {
|
||||||
} catch (e) {
|
log(`Failed to connect to Geoclue2 service: ${e.message}`);
|
||||||
log(`Failed to connect to Geoclue2 service: ${e.message}`);
|
this._setLocation(this._mostRecentLocation);
|
||||||
this._setLocation(this._mostRecentLocation);
|
return;
|
||||||
return;
|
}
|
||||||
}
|
this._gclueStarted = true;
|
||||||
this._gclueStarted = true;
|
this._gclueService.get_client().distance_threshold = 100;
|
||||||
this._gclueService.get_client().distance_threshold = 100;
|
this._updateLocationMonitoring();
|
||||||
this._updateLocationMonitoring();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_onGClueLocationChanged() {
|
_onGClueLocationChanged() {
|
||||||
|
@ -681,8 +681,7 @@ class AppSwitcher extends SwitcherPopup.SwitcherList {
|
|||||||
// Cache the window list now; we don't handle dynamic changes here,
|
// Cache the window list now; we don't handle dynamic changes here,
|
||||||
// and we don't want to be continually retrieving it
|
// and we don't want to be continually retrieving it
|
||||||
appIcon.cachedWindows = allWindows.filter(
|
appIcon.cachedWindows = allWindows.filter(
|
||||||
w => windowTracker.get_window_app(w) == appIcon.app
|
w => windowTracker.get_window_app(w) === appIcon.app);
|
||||||
);
|
|
||||||
if (appIcon.cachedWindows.length > 0)
|
if (appIcon.cachedWindows.length > 0)
|
||||||
this._addIcon(appIcon);
|
this._addIcon(appIcon);
|
||||||
}
|
}
|
||||||
@ -1060,25 +1059,25 @@ class WindowSwitcher extends SwitcherPopup.SwitcherList {
|
|||||||
vfunc_allocate(box, flags) {
|
vfunc_allocate(box, flags) {
|
||||||
let themeNode = this.get_theme_node();
|
let themeNode = this.get_theme_node();
|
||||||
let contentBox = themeNode.get_content_box(box);
|
let contentBox = themeNode.get_content_box(box);
|
||||||
|
const labelHeight = this._label.height;
|
||||||
|
const totalLabelHeight =
|
||||||
|
labelHeight + themeNode.get_padding(St.Side.BOTTOM);
|
||||||
|
|
||||||
let childBox = new Clutter.ActorBox();
|
box.y2 -= totalLabelHeight;
|
||||||
childBox.x1 = contentBox.x1;
|
super.vfunc_allocate(box, flags);
|
||||||
childBox.x2 = contentBox.x2;
|
|
||||||
childBox.y2 = contentBox.y2;
|
|
||||||
childBox.y1 = childBox.y2 - this._label.height;
|
|
||||||
this._label.allocate(childBox, flags);
|
|
||||||
|
|
||||||
let totalLabelHeight = this._label.height + themeNode.get_padding(St.Side.BOTTOM);
|
|
||||||
childBox.x1 = box.x1;
|
|
||||||
childBox.x2 = box.x2;
|
|
||||||
childBox.y1 = box.y1;
|
|
||||||
childBox.y2 = box.y2 - totalLabelHeight;
|
|
||||||
super.vfunc_allocate(childBox, flags);
|
|
||||||
|
|
||||||
// Hooking up the parent vfunc will call this.set_allocation() with
|
// Hooking up the parent vfunc will call this.set_allocation() with
|
||||||
// the height without the label height, so call it again with the
|
// the height without the label height, so call it again with the
|
||||||
// correct size here.
|
// correct size here.
|
||||||
|
box.y2 += totalLabelHeight;
|
||||||
this.set_allocation(box, flags);
|
this.set_allocation(box, flags);
|
||||||
|
|
||||||
|
const childBox = new Clutter.ActorBox();
|
||||||
|
childBox.x1 = contentBox.x1;
|
||||||
|
childBox.x2 = contentBox.x2;
|
||||||
|
childBox.y2 = contentBox.y2;
|
||||||
|
childBox.y1 = childBox.y2 - labelHeight;
|
||||||
|
this._label.allocate(childBox, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
highlight(index, justOutline) {
|
highlight(index, justOutline) {
|
||||||
|
@ -15,8 +15,7 @@ class Animation extends St.Bin {
|
|||||||
const themeContext = St.ThemeContext.get_for_stage(global.stage);
|
const themeContext = St.ThemeContext.get_for_stage(global.stage);
|
||||||
|
|
||||||
super._init({
|
super._init({
|
||||||
width: width * themeContext.scale_factor,
|
style: `width: ${width}px; height: ${height}px;`,
|
||||||
height: height * themeContext.scale_factor,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
this.connect('destroy', this._onDestroy.bind(this));
|
this.connect('destroy', this._onDestroy.bind(this));
|
||||||
|
@ -10,6 +10,7 @@ const GrabHelper = imports.ui.grabHelper;
|
|||||||
const IconGrid = imports.ui.iconGrid;
|
const IconGrid = imports.ui.iconGrid;
|
||||||
const Main = imports.ui.main;
|
const Main = imports.ui.main;
|
||||||
const PageIndicators = imports.ui.pageIndicators;
|
const PageIndicators = imports.ui.pageIndicators;
|
||||||
|
const ParentalControlsManager = imports.misc.parentalControlsManager;
|
||||||
const PopupMenu = imports.ui.popupMenu;
|
const PopupMenu = imports.ui.popupMenu;
|
||||||
const Search = imports.ui.search;
|
const Search = imports.ui.search;
|
||||||
const SwipeTracker = imports.ui.swipeTracker;
|
const SwipeTracker = imports.ui.swipeTracker;
|
||||||
@ -114,7 +115,8 @@ function _findBestFolderName(apps) {
|
|||||||
}, commonCategories);
|
}, commonCategories);
|
||||||
|
|
||||||
for (let category of commonCategories) {
|
for (let category of commonCategories) {
|
||||||
let translated = Shell.util_get_translated_folder_name(category);
|
const directory = '%s.directory'.format(category);
|
||||||
|
const translated = Shell.util_get_translated_folder_name(directory);
|
||||||
if (translated !== null)
|
if (translated !== null)
|
||||||
return translated;
|
return translated;
|
||||||
}
|
}
|
||||||
@ -157,6 +159,16 @@ var BaseAppView = GObject.registerClass({
|
|||||||
|
|
||||||
this._items = new Map();
|
this._items = new Map();
|
||||||
this._orderedItems = [];
|
this._orderedItems = [];
|
||||||
|
|
||||||
|
this._animateLaterId = 0;
|
||||||
|
this._viewLoadedHandlerId = 0;
|
||||||
|
this._viewIsReady = false;
|
||||||
|
|
||||||
|
// Filter the apps through the user’s parental controls.
|
||||||
|
this._parentalControlsManager = ParentalControlsManager.getDefault();
|
||||||
|
this._parentalControlsManager.connect('app-filter-changed', () => {
|
||||||
|
this._redisplay();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
_childFocused(_actor) {
|
_childFocused(_actor) {
|
||||||
@ -192,8 +204,6 @@ var BaseAppView = GObject.registerClass({
|
|||||||
this._items.set(icon.id, icon);
|
this._items.set(icon.id, icon);
|
||||||
});
|
});
|
||||||
|
|
||||||
this._animateLaterId = 0;
|
|
||||||
this._viewLoadedHandlerId = 0;
|
|
||||||
this._viewIsReady = true;
|
this._viewIsReady = true;
|
||||||
this.emit('view-loaded');
|
this.emit('view-loaded');
|
||||||
}
|
}
|
||||||
@ -291,6 +301,11 @@ var BaseAppView = GObject.registerClass({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vfunc_unmap() {
|
||||||
|
this._clearAnimateLater();
|
||||||
|
super.vfunc_unmap();
|
||||||
|
}
|
||||||
|
|
||||||
animateSwitch(animationDirection) {
|
animateSwitch(animationDirection) {
|
||||||
this.remove_all_transitions();
|
this.remove_all_transitions();
|
||||||
this._grid.remove_all_transitions();
|
this._grid.remove_all_transitions();
|
||||||
@ -327,14 +342,37 @@ var AllView = GObject.registerClass({
|
|||||||
use_pagination: true,
|
use_pagination: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this._grid._delegate = this;
|
||||||
|
|
||||||
|
this._stack = new St.Widget({
|
||||||
|
layout_manager: new Clutter.BinLayout(),
|
||||||
|
x_expand: true,
|
||||||
|
y_expand: true,
|
||||||
|
});
|
||||||
|
this.add_actor(this._stack);
|
||||||
|
|
||||||
|
let box = new St.BoxLayout({
|
||||||
|
vertical: true,
|
||||||
|
y_align: Clutter.ActorAlign.START,
|
||||||
|
});
|
||||||
|
box.add_child(this._grid);
|
||||||
|
|
||||||
this._scrollView = new St.ScrollView({
|
this._scrollView = new St.ScrollView({
|
||||||
style_class: 'all-apps',
|
style_class: 'all-apps',
|
||||||
x_expand: true,
|
x_expand: true,
|
||||||
y_expand: true,
|
y_expand: true,
|
||||||
reactive: true,
|
reactive: true,
|
||||||
});
|
});
|
||||||
this.add_actor(this._scrollView);
|
this._scrollView.add_actor(box);
|
||||||
this._grid._delegate = this;
|
this._stack.add_actor(this._scrollView);
|
||||||
|
|
||||||
|
this._eventBlocker = new St.Widget({
|
||||||
|
x_expand: true,
|
||||||
|
y_expand: true,
|
||||||
|
reactive: true,
|
||||||
|
visible: false,
|
||||||
|
});
|
||||||
|
this._stack.add_actor(this._eventBlocker);
|
||||||
|
|
||||||
this._scrollView.set_policy(St.PolicyType.NEVER,
|
this._scrollView.set_policy(St.PolicyType.NEVER,
|
||||||
St.PolicyType.EXTERNAL);
|
St.PolicyType.EXTERNAL);
|
||||||
@ -355,24 +393,7 @@ var AllView = GObject.registerClass({
|
|||||||
|
|
||||||
this._folderIcons = [];
|
this._folderIcons = [];
|
||||||
|
|
||||||
this._stack = new St.Widget({ layout_manager: new Clutter.BinLayout() });
|
|
||||||
let box = new St.BoxLayout({
|
|
||||||
vertical: true,
|
|
||||||
y_align: Clutter.ActorAlign.START,
|
|
||||||
});
|
|
||||||
|
|
||||||
this._grid.currentPage = 0;
|
this._grid.currentPage = 0;
|
||||||
this._stack.add_actor(this._grid);
|
|
||||||
this._eventBlocker = new St.Widget({
|
|
||||||
x_expand: true,
|
|
||||||
y_expand: true,
|
|
||||||
reactive: true,
|
|
||||||
visible: false,
|
|
||||||
});
|
|
||||||
this._stack.add_actor(this._eventBlocker);
|
|
||||||
|
|
||||||
box.add_actor(this._stack);
|
|
||||||
this._scrollView.add_actor(box);
|
|
||||||
|
|
||||||
this._scrollView.connect('scroll-event', this._onScroll.bind(this));
|
this._scrollView.connect('scroll-event', this._onScroll.bind(this));
|
||||||
|
|
||||||
@ -407,8 +428,6 @@ var AllView = GObject.registerClass({
|
|||||||
this._lastOvershootY = -1;
|
this._lastOvershootY = -1;
|
||||||
this._lastOvershootTimeoutId = 0;
|
this._lastOvershootTimeoutId = 0;
|
||||||
|
|
||||||
this._viewIsReady = false;
|
|
||||||
|
|
||||||
Main.overview.connect('hidden', () => this.goToPage(0));
|
Main.overview.connect('hidden', () => this.goToPage(0));
|
||||||
|
|
||||||
this._redisplayWorkId = Main.initializeDeferredWork(this, this._redisplay.bind(this));
|
this._redisplayWorkId = Main.initializeDeferredWork(this, this._redisplay.bind(this));
|
||||||
@ -509,7 +528,7 @@ var AllView = GObject.registerClass({
|
|||||||
} catch (e) {
|
} catch (e) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return appInfo.should_show();
|
return this._parentalControlsManager.shouldShowApp(appInfo);
|
||||||
});
|
});
|
||||||
|
|
||||||
let apps = this._appInfoList.map(app => app.get_id());
|
let apps = this._appInfoList.map(app => app.get_id());
|
||||||
@ -619,7 +638,7 @@ var AllView = GObject.registerClass({
|
|||||||
|
|
||||||
this._grid.currentPage = pageNumber;
|
this._grid.currentPage = pageNumber;
|
||||||
|
|
||||||
// Tween the change between pages.
|
// Animate the change between pages.
|
||||||
this._adjustment.ease(this._grid.getPageY(this._grid.currentPage), {
|
this._adjustment.ease(this._grid.getPageY(this._grid.currentPage), {
|
||||||
mode: Clutter.AnimationMode.EASE_OUT_CUBIC,
|
mode: Clutter.AnimationMode.EASE_OUT_CUBIC,
|
||||||
duration: animate ? PAGE_SWITCH_TIME : 0,
|
duration: animate ? PAGE_SWITCH_TIME : 0,
|
||||||
@ -650,8 +669,7 @@ var AllView = GObject.registerClass({
|
|||||||
this._canScroll = true;
|
this._canScroll = true;
|
||||||
this._scrollTimeoutId = 0;
|
this._scrollTimeoutId = 0;
|
||||||
return GLib.SOURCE_REMOVE;
|
return GLib.SOURCE_REMOVE;
|
||||||
}
|
});
|
||||||
);
|
|
||||||
|
|
||||||
return Clutter.EVENT_STOP;
|
return Clutter.EVENT_STOP;
|
||||||
}
|
}
|
||||||
@ -999,7 +1017,7 @@ class FrequentView extends BaseAppView {
|
|||||||
let favoritesWritable = global.settings.is_writable('favorite-apps');
|
let favoritesWritable = global.settings.is_writable('favorite-apps');
|
||||||
|
|
||||||
for (let i = 0; i < mostUsed.length; i++) {
|
for (let i = 0; i < mostUsed.length; i++) {
|
||||||
if (!mostUsed[i].get_app_info().should_show())
|
if (!this._parentalControlsManager.shouldShowApp(mostUsed[i].get_app_info()))
|
||||||
continue;
|
continue;
|
||||||
let appIcon = this._items.get(mostUsed[i].get_id());
|
let appIcon = this._items.get(mostUsed[i].get_id());
|
||||||
if (!appIcon) {
|
if (!appIcon) {
|
||||||
@ -1245,6 +1263,8 @@ var AppSearchProvider = class AppSearchProvider {
|
|||||||
this.canLaunchSearch = false;
|
this.canLaunchSearch = false;
|
||||||
|
|
||||||
this._systemActions = new SystemActions.getDefault();
|
this._systemActions = new SystemActions.getDefault();
|
||||||
|
|
||||||
|
this._parentalControlsManager = ParentalControlsManager.getDefault();
|
||||||
}
|
}
|
||||||
|
|
||||||
getResultMetas(apps, callback) {
|
getResultMetas(apps, callback) {
|
||||||
@ -1279,18 +1299,30 @@ var AppSearchProvider = class AppSearchProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getInitialResultSet(terms, callback, _cancellable) {
|
getInitialResultSet(terms, callback, _cancellable) {
|
||||||
|
// Defer until the parental controls manager is initialised, so the
|
||||||
|
// results can be filtered correctly.
|
||||||
|
if (!this._parentalControlsManager.initialized) {
|
||||||
|
let initializedId = this._parentalControlsManager.connect('app-filter-changed', () => {
|
||||||
|
if (this._parentalControlsManager.initialized) {
|
||||||
|
this._parentalControlsManager.disconnect(initializedId);
|
||||||
|
this.getInitialResultSet(terms, callback, _cancellable);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let query = terms.join(' ');
|
let query = terms.join(' ');
|
||||||
let groups = Shell.AppSystem.search(query);
|
let groups = Shell.AppSystem.search(query);
|
||||||
let usage = Shell.AppUsage.get_default();
|
let usage = Shell.AppUsage.get_default();
|
||||||
let results = [];
|
let results = [];
|
||||||
|
|
||||||
groups.forEach(group => {
|
groups.forEach(group => {
|
||||||
group = group.filter(appID => {
|
group = group.filter(appID => {
|
||||||
const app = this._appSys.lookup_app(appID);
|
const app = this._appSys.lookup_app(appID);
|
||||||
return app && app.app_info.should_show();
|
return app && this._parentalControlsManager.shouldShowApp(app.app_info);
|
||||||
});
|
});
|
||||||
results = results.concat(group.sort(
|
results = results.concat(group.sort(
|
||||||
(a, b) => usage.compare(a, b)
|
(a, b) => usage.compare(a, b)));
|
||||||
));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
results = results.concat(this._systemActions.getMatchingActions(terms));
|
results = results.concat(this._systemActions.getMatchingActions(terms));
|
||||||
@ -1371,12 +1403,12 @@ class FolderView extends BaseAppView {
|
|||||||
});
|
});
|
||||||
layout.hookup_style(icon);
|
layout.hookup_style(icon);
|
||||||
let subSize = Math.floor(FOLDER_SUBICON_FRACTION * size);
|
let subSize = Math.floor(FOLDER_SUBICON_FRACTION * size);
|
||||||
let scale = St.ThemeContext.get_for_stage(global.stage).scale_factor;
|
|
||||||
|
|
||||||
let numItems = this._orderedItems.length;
|
let numItems = this._orderedItems.length;
|
||||||
let rtl = icon.get_text_direction() == Clutter.TextDirection.RTL;
|
let rtl = icon.get_text_direction() == Clutter.TextDirection.RTL;
|
||||||
for (let i = 0; i < 4; i++) {
|
for (let i = 0; i < 4; i++) {
|
||||||
let bin = new St.Bin({ width: subSize * scale, height: subSize * scale });
|
const style = 'width: %dpx; height: %dpx;'.format(subSize, subSize);
|
||||||
|
let bin = new St.Bin({ style });
|
||||||
if (i < numItems)
|
if (i < numItems)
|
||||||
bin.child = this._orderedItems[i].app.create_icon_texture(subSize);
|
bin.child = this._orderedItems[i].app.create_icon_texture(subSize);
|
||||||
layout.attach(bin, rtl ? (i + 1) % 2 : i % 2, Math.floor(i / 2), 1, 1);
|
layout.attach(bin, rtl ? (i + 1) % 2 : i % 2, Math.floor(i / 2), 1, 1);
|
||||||
@ -1425,7 +1457,7 @@ class FolderView extends BaseAppView {
|
|||||||
if (!app)
|
if (!app)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!app.get_app_info().should_show())
|
if (!this._parentalControlsManager.shouldShowApp(app.get_app_info()))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (apps.some(appIcon => appIcon.id == appId))
|
if (apps.some(appIcon => appIcon.id == appId))
|
||||||
@ -2171,7 +2203,7 @@ var AppIcon = GObject.registerClass({
|
|||||||
}
|
}
|
||||||
|
|
||||||
vfunc_leave_event(crossingEvent) {
|
vfunc_leave_event(crossingEvent) {
|
||||||
let ret = super.vfunc_leave_event(crossingEvent);
|
const ret = super.vfunc_leave_event(crossingEvent);
|
||||||
|
|
||||||
this.fake_release();
|
this.fake_release();
|
||||||
this._removeMenuTimeout();
|
this._removeMenuTimeout();
|
||||||
@ -2179,22 +2211,22 @@ var AppIcon = GObject.registerClass({
|
|||||||
}
|
}
|
||||||
|
|
||||||
vfunc_button_press_event(buttonEvent) {
|
vfunc_button_press_event(buttonEvent) {
|
||||||
super.vfunc_button_press_event(buttonEvent);
|
const ret = super.vfunc_button_press_event(buttonEvent);
|
||||||
if (buttonEvent.button == 1) {
|
if (buttonEvent.button == 1) {
|
||||||
this._setPopupTimeout();
|
this._setPopupTimeout();
|
||||||
} else if (buttonEvent.button == 3) {
|
} else if (buttonEvent.button == 3) {
|
||||||
this.popupMenu();
|
this.popupMenu();
|
||||||
return Clutter.EVENT_STOP;
|
return Clutter.EVENT_STOP;
|
||||||
}
|
}
|
||||||
return Clutter.EVENT_PROPAGATE;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
vfunc_touch_event(touchEvent) {
|
vfunc_touch_event(touchEvent) {
|
||||||
super.vfunc_touch_event(touchEvent);
|
const ret = super.vfunc_touch_event(touchEvent);
|
||||||
if (touchEvent.type == Clutter.EventType.TOUCH_BEGIN)
|
if (touchEvent.type == Clutter.EventType.TOUCH_BEGIN)
|
||||||
this._setPopupTimeout();
|
this._setPopupTimeout();
|
||||||
|
|
||||||
return Clutter.EVENT_PROPAGATE;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
vfunc_clicked(button) {
|
vfunc_clicked(button) {
|
||||||
@ -2464,14 +2496,12 @@ var AppIconMenu = class AppIconMenu extends PopupMenu.PopupMenu {
|
|||||||
this.removeAll();
|
this.removeAll();
|
||||||
|
|
||||||
let windows = this._source.app.get_windows().filter(
|
let windows = this._source.app.get_windows().filter(
|
||||||
w => !w.skip_taskbar
|
w => !w.skip_taskbar);
|
||||||
);
|
|
||||||
|
|
||||||
if (windows.length > 0) {
|
if (windows.length > 0) {
|
||||||
this.addMenuItem(
|
this.addMenuItem(
|
||||||
/* Translators: This is the heading of a list of open windows */
|
/* Translators: This is the heading of a list of open windows */
|
||||||
new PopupMenu.PopupSeparatorMenuItem(_("Open Windows"))
|
new PopupMenu.PopupSeparatorMenuItem(_('Open Windows')));
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
windows.forEach(window => {
|
windows.forEach(window => {
|
||||||
@ -2546,19 +2576,18 @@ var AppIconMenu = class AppIconMenu extends PopupMenu.PopupMenu {
|
|||||||
if (Shell.AppSystem.get_default().lookup_app('org.gnome.Software.desktop')) {
|
if (Shell.AppSystem.get_default().lookup_app('org.gnome.Software.desktop')) {
|
||||||
this._appendSeparator();
|
this._appendSeparator();
|
||||||
let item = this._appendMenuItem(_("Show Details"));
|
let item = this._appendMenuItem(_("Show Details"));
|
||||||
item.connect('activate', () => {
|
item.connect('activate', async () => {
|
||||||
let id = this._source.app.get_id();
|
let id = this._source.app.get_id();
|
||||||
let args = GLib.Variant.new('(ss)', [id, '']);
|
let args = GLib.Variant.new('(ss)', [id, '']);
|
||||||
Gio.DBus.get(Gio.BusType.SESSION, null, (o, res) => {
|
const bus = await Gio.DBus.get(Gio.BusType.SESSION, null);
|
||||||
let bus = Gio.DBus.get_finish(res);
|
bus.call(
|
||||||
bus.call('org.gnome.Software',
|
'org.gnome.Software',
|
||||||
'/org/gnome/Software',
|
'/org/gnome/Software',
|
||||||
'org.gtk.Actions', 'Activate',
|
'org.gtk.Actions', 'Activate',
|
||||||
GLib.Variant.new('(sava{sv})',
|
new GLib.Variant.new(
|
||||||
['details', [args], null]),
|
'(sava{sv})', ['details', [args], null]),
|
||||||
null, 0, -1, null, null);
|
null, 0, -1, null);
|
||||||
Main.overview.hide();
|
Main.overview.hide();
|
||||||
});
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
/* exported getAppFavorites */
|
/* exported getAppFavorites */
|
||||||
|
|
||||||
const Shell = imports.gi.Shell;
|
const Shell = imports.gi.Shell;
|
||||||
|
const ParentalControlsManager = imports.misc.parentalControlsManager;
|
||||||
const Signals = imports.signals;
|
const Signals = imports.signals;
|
||||||
|
|
||||||
const Main = imports.ui.main;
|
const Main = imports.ui.main;
|
||||||
@ -64,6 +65,13 @@ const RENAMED_DESKTOP_IDS = {
|
|||||||
|
|
||||||
class AppFavorites {
|
class AppFavorites {
|
||||||
constructor() {
|
constructor() {
|
||||||
|
// Filter the apps through the user’s parental controls.
|
||||||
|
this._parentalControlsManager = ParentalControlsManager.getDefault();
|
||||||
|
this._parentalControlsManager.connect('app-filter-changed', () => {
|
||||||
|
this.reload();
|
||||||
|
this.emit('changed');
|
||||||
|
});
|
||||||
|
|
||||||
this.FAVORITE_APPS_KEY = 'favorite-apps';
|
this.FAVORITE_APPS_KEY = 'favorite-apps';
|
||||||
this._favorites = {};
|
this._favorites = {};
|
||||||
global.settings.connect('changed::%s'.format(this.FAVORITE_APPS_KEY), this._onFavsChanged.bind(this));
|
global.settings.connect('changed::%s'.format(this.FAVORITE_APPS_KEY), this._onFavsChanged.bind(this));
|
||||||
@ -95,7 +103,7 @@ class AppFavorites {
|
|||||||
global.settings.set_strv(this.FAVORITE_APPS_KEY, ids);
|
global.settings.set_strv(this.FAVORITE_APPS_KEY, ids);
|
||||||
|
|
||||||
let apps = ids.map(id => appSys.lookup_app(id))
|
let apps = ids.map(id => appSys.lookup_app(id))
|
||||||
.filter(app => app != null);
|
.filter(app => app !== null && this._parentalControlsManager.shouldShowApp(app.app_info));
|
||||||
this._favorites = {};
|
this._favorites = {};
|
||||||
for (let i = 0; i < apps.length; i++) {
|
for (let i = 0; i < apps.length; i++) {
|
||||||
let app = apps[i];
|
let app = apps[i];
|
||||||
@ -134,6 +142,9 @@ class AppFavorites {
|
|||||||
if (!app)
|
if (!app)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (!this._parentalControlsManager.shouldShowApp(app.app_info))
|
||||||
|
return false;
|
||||||
|
|
||||||
let ids = this._getIds();
|
let ids = this._getIds();
|
||||||
if (pos == -1)
|
if (pos == -1)
|
||||||
ids.push(appId);
|
ids.push(appId);
|
||||||
|
@ -147,9 +147,8 @@ var AudioDeviceSelectionDBus = class AudioDeviceSelectionDBus {
|
|||||||
_onDeviceSelected(dialog, device) {
|
_onDeviceSelected(dialog, device) {
|
||||||
let connection = this._dbusImpl.get_connection();
|
let connection = this._dbusImpl.get_connection();
|
||||||
let info = this._dbusImpl.get_info();
|
let info = this._dbusImpl.get_info();
|
||||||
let deviceName = Object.keys(AudioDevice).filter(
|
const deviceName = Object.keys(AudioDevice)
|
||||||
dev => AudioDevice[dev] == device
|
.filter(dev => AudioDevice[dev] === device)[0].toLowerCase();
|
||||||
)[0].toLowerCase();
|
|
||||||
connection.emit_signal(this._audioSelectionDialog._sender,
|
connection.emit_signal(this._audioSelectionDialog._sender,
|
||||||
this._dbusImpl.get_object_path(),
|
this._dbusImpl.get_object_path(),
|
||||||
info ? info.name : null,
|
info ? info.name : null,
|
||||||
|
@ -197,6 +197,11 @@ var BoxPointer = GObject.registerClass({
|
|||||||
}
|
}
|
||||||
|
|
||||||
vfunc_allocate(box, flags) {
|
vfunc_allocate(box, flags) {
|
||||||
|
if (this._sourceActor && this._sourceActor.mapped) {
|
||||||
|
this._reposition(box);
|
||||||
|
this._updateFlip(box);
|
||||||
|
}
|
||||||
|
|
||||||
this.set_allocation(box, flags);
|
this.set_allocation(box, flags);
|
||||||
|
|
||||||
let themeNode = this.get_theme_node();
|
let themeNode = this.get_theme_node();
|
||||||
@ -230,12 +235,6 @@ var BoxPointer = GObject.registerClass({
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
this.bin.allocate(childBox, flags);
|
this.bin.allocate(childBox, flags);
|
||||||
|
|
||||||
if (this._sourceActor && this._sourceActor.mapped) {
|
|
||||||
this._reposition(box);
|
|
||||||
this._updateFlip(box);
|
|
||||||
this.set_allocation(box, flags);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_drawBorder(area) {
|
_drawBorder(area) {
|
||||||
|
@ -199,46 +199,52 @@ class DBusEventSource extends EventSourceBase {
|
|||||||
|
|
||||||
this._initialized = false;
|
this._initialized = false;
|
||||||
this._dbusProxy = new CalendarServer();
|
this._dbusProxy = new CalendarServer();
|
||||||
this._dbusProxy.init_async(GLib.PRIORITY_DEFAULT, null, (object, result) => {
|
this._initProxy();
|
||||||
let loaded = false;
|
}
|
||||||
|
|
||||||
try {
|
async _initProxy() {
|
||||||
this._dbusProxy.init_finish(result);
|
let loaded = false;
|
||||||
loaded = true;
|
|
||||||
} catch (e) {
|
try {
|
||||||
if (e.matches(Gio.DBusError, Gio.DBusError.TIMED_OUT)) {
|
await this._dbusProxy.init_async(GLib.PRIORITY_DEFAULT, null);
|
||||||
// Ignore timeouts and install signals as normal, because with high
|
loaded = true;
|
||||||
// probability the service will appear later on, and we will get a
|
} catch (e) {
|
||||||
// NameOwnerChanged which will finish loading
|
// Ignore timeouts and install signals as normal, because with high
|
||||||
//
|
// probability the service will appear later on, and we will get a
|
||||||
// (But still _initialized to false, because the proxy does not know
|
// NameOwnerChanged which will finish loading
|
||||||
// about the HasCalendars property and would cause an exception trying
|
//
|
||||||
// to read it)
|
// (But still _initialized to false, because the proxy does not know
|
||||||
} else {
|
// about the HasCalendars property and would cause an exception trying
|
||||||
log('Error loading calendars: %s'.format(e.message));
|
// to read it)
|
||||||
return;
|
if (!e.matches(Gio.DBusError, Gio.DBusError.TIMED_OUT)) {
|
||||||
}
|
log('Error loading calendars: %s'.format(e.message));
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
this._dbusProxy.connectSignal('Changed', this._onChanged.bind(this));
|
this._dbusProxy.connectSignal('EventsAddedOrUpdated',
|
||||||
|
this._onEventsAddedOrUpdated.bind(this));
|
||||||
|
this._dbusProxy.connectSignal('EventsRemoved',
|
||||||
|
this._onEventsRemoved.bind(this));
|
||||||
|
this._dbusProxy.connectSignal('ClientDisappeared',
|
||||||
|
this._onClientDisappeared.bind(this));
|
||||||
|
|
||||||
this._dbusProxy.connect('notify::g-name-owner', () => {
|
this._dbusProxy.connect('notify::g-name-owner', () => {
|
||||||
if (this._dbusProxy.g_name_owner)
|
if (this._dbusProxy.g_name_owner)
|
||||||
this._onNameAppeared();
|
|
||||||
else
|
|
||||||
this._onNameVanished();
|
|
||||||
});
|
|
||||||
|
|
||||||
this._dbusProxy.connect('g-properties-changed', () => {
|
|
||||||
this.notify('has-calendars');
|
|
||||||
});
|
|
||||||
|
|
||||||
this._initialized = loaded;
|
|
||||||
if (loaded) {
|
|
||||||
this.notify('has-calendars');
|
|
||||||
this._onNameAppeared();
|
this._onNameAppeared();
|
||||||
}
|
else
|
||||||
|
this._onNameVanished();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this._dbusProxy.connect('g-properties-changed', () => {
|
||||||
|
this.notify('has-calendars');
|
||||||
|
});
|
||||||
|
|
||||||
|
this._initialized = loaded;
|
||||||
|
if (loaded) {
|
||||||
|
this.notify('has-calendars');
|
||||||
|
this._onNameAppeared();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
destroy() {
|
destroy() {
|
||||||
@ -257,7 +263,7 @@ class DBusEventSource extends EventSourceBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_resetCache() {
|
_resetCache() {
|
||||||
this._events = [];
|
this._events = new Map();
|
||||||
this._lastRequestBegin = null;
|
this._lastRequestBegin = null;
|
||||||
this._lastRequestEnd = null;
|
this._lastRequestEnd = null;
|
||||||
}
|
}
|
||||||
@ -273,28 +279,47 @@ class DBusEventSource extends EventSourceBase {
|
|||||||
this.emit('changed');
|
this.emit('changed');
|
||||||
}
|
}
|
||||||
|
|
||||||
_onChanged() {
|
_onEventsAddedOrUpdated(dbusProxy, nameOwner, argArray) {
|
||||||
this._loadEvents(false);
|
const [appointments = []] = argArray;
|
||||||
|
let changed = false;
|
||||||
|
|
||||||
|
for (let n = 0; n < appointments.length; n++) {
|
||||||
|
const [id, summary, allDay, startTime, endTime] = appointments[n];
|
||||||
|
const date = new Date(startTime * 1000);
|
||||||
|
const end = new Date(endTime * 1000);
|
||||||
|
let event = new CalendarEvent(id, date, end, summary, allDay);
|
||||||
|
this._events.set(event.id, event);
|
||||||
|
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (changed)
|
||||||
|
this.emit('changed');
|
||||||
}
|
}
|
||||||
|
|
||||||
_onEventsReceived(results, _error) {
|
_onEventsRemoved(dbusProxy, nameOwner, argArray) {
|
||||||
let newEvents = [];
|
const [ids = []] = argArray;
|
||||||
let appointments = results[0] || [];
|
|
||||||
for (let n = 0; n < appointments.length; n++) {
|
|
||||||
let a = appointments[n];
|
|
||||||
let date = new Date(a[4] * 1000);
|
|
||||||
let end = new Date(a[5] * 1000);
|
|
||||||
let id = a[0];
|
|
||||||
let summary = a[1];
|
|
||||||
let allDay = a[3];
|
|
||||||
let event = new CalendarEvent(id, date, end, summary, allDay);
|
|
||||||
newEvents.push(event);
|
|
||||||
}
|
|
||||||
newEvents.sort((ev1, ev2) => ev1.date.getTime() - ev2.date.getTime());
|
|
||||||
|
|
||||||
this._events = newEvents;
|
let changed = false;
|
||||||
this._isLoading = false;
|
for (const id of ids)
|
||||||
this.emit('changed');
|
changed |= this._events.delete(id);
|
||||||
|
|
||||||
|
if (changed)
|
||||||
|
this.emit('changed');
|
||||||
|
}
|
||||||
|
|
||||||
|
_onClientDisappeared(dbusProxy, nameOwner, argArray) {
|
||||||
|
let [sourceUid = ''] = argArray;
|
||||||
|
sourceUid += '\n';
|
||||||
|
|
||||||
|
let changed = false;
|
||||||
|
for (const id of this._events.keys()) {
|
||||||
|
if (id.startsWith(sourceUid))
|
||||||
|
changed |= this._events.delete(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (changed)
|
||||||
|
this.emit('changed');
|
||||||
}
|
}
|
||||||
|
|
||||||
_loadEvents(forceReload) {
|
_loadEvents(forceReload) {
|
||||||
@ -303,33 +328,38 @@ class DBusEventSource extends EventSourceBase {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
if (this._curRequestBegin && this._curRequestEnd) {
|
if (this._curRequestBegin && this._curRequestEnd) {
|
||||||
this._dbusProxy.GetEventsRemote(this._curRequestBegin.getTime() / 1000,
|
if (forceReload) {
|
||||||
this._curRequestEnd.getTime() / 1000,
|
this._events.clear();
|
||||||
forceReload,
|
this.emit('changed');
|
||||||
this._onEventsReceived.bind(this),
|
}
|
||||||
Gio.DBusCallFlags.NONE);
|
this._dbusProxy.SetTimeRangeRemote(
|
||||||
|
this._curRequestBegin.getTime() / 1000,
|
||||||
|
this._curRequestEnd.getTime() / 1000,
|
||||||
|
forceReload,
|
||||||
|
Gio.DBusCallFlags.NONE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
requestRange(begin, end) {
|
requestRange(begin, end) {
|
||||||
if (!(_datesEqual(begin, this._lastRequestBegin) && _datesEqual(end, this._lastRequestEnd))) {
|
if (!(_datesEqual(begin, this._lastRequestBegin) && _datesEqual(end, this._lastRequestEnd))) {
|
||||||
this._isLoading = true;
|
|
||||||
this._lastRequestBegin = begin;
|
this._lastRequestBegin = begin;
|
||||||
this._lastRequestEnd = end;
|
this._lastRequestEnd = end;
|
||||||
this._curRequestBegin = begin;
|
this._curRequestBegin = begin;
|
||||||
this._curRequestEnd = end;
|
this._curRequestEnd = end;
|
||||||
this._loadEvents(false);
|
this._loadEvents(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*_getFilteredEvents(begin, end) {
|
||||||
|
for (const event of this._events.values()) {
|
||||||
|
if (_dateIntervalsOverlap(event.date, event.end, begin, end))
|
||||||
|
yield event;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getEvents(begin, end) {
|
getEvents(begin, end) {
|
||||||
let result = [];
|
let result = [...this._getFilteredEvents(begin, end)];
|
||||||
for (let n = 0; n < this._events.length; n++) {
|
|
||||||
let event = this._events[n];
|
|
||||||
|
|
||||||
if (_dateIntervalsOverlap(event.date, event.end, begin, end))
|
|
||||||
result.push(event);
|
|
||||||
}
|
|
||||||
result.sort((event1, event2) => {
|
result.sort((event1, event2) => {
|
||||||
// sort events by end time on ending day
|
// sort events by end time on ending day
|
||||||
let d1 = event1.date < begin && event1.end <= end ? event1.end : event1.date;
|
let d1 = event1.date < begin && event1.end <= end ? event1.end : event1.date;
|
||||||
@ -343,12 +373,8 @@ class DBusEventSource extends EventSourceBase {
|
|||||||
let dayBegin = _getBeginningOfDay(day);
|
let dayBegin = _getBeginningOfDay(day);
|
||||||
let dayEnd = _getEndOfDay(day);
|
let dayEnd = _getEndOfDay(day);
|
||||||
|
|
||||||
let events = this.getEvents(dayBegin, dayEnd);
|
const { done } = this._getFilteredEvents(dayBegin, dayEnd).next();
|
||||||
|
return !done;
|
||||||
if (events.length == 0)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -700,12 +726,11 @@ var Calendar = GObject.registerClass({
|
|||||||
var EventMessage = GObject.registerClass(
|
var EventMessage = GObject.registerClass(
|
||||||
class EventMessage extends MessageList.Message {
|
class EventMessage extends MessageList.Message {
|
||||||
_init(event, date) {
|
_init(event, date) {
|
||||||
super._init('', event.summary);
|
super._init('', '');
|
||||||
|
|
||||||
this._event = event;
|
|
||||||
this._date = date;
|
this._date = date;
|
||||||
|
|
||||||
this.setTitle(this._formatEventTime());
|
this.update(event);
|
||||||
|
|
||||||
this._icon = new St.Icon({ icon_name: 'x-office-calendar-symbolic' });
|
this._icon = new St.Icon({ icon_name: 'x-office-calendar-symbolic' });
|
||||||
this.setIcon(this._icon);
|
this.setIcon(this._icon);
|
||||||
@ -717,6 +742,13 @@ class EventMessage extends MessageList.Message {
|
|||||||
super.vfunc_style_changed();
|
super.vfunc_style_changed();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
update(event) {
|
||||||
|
this._event = event;
|
||||||
|
|
||||||
|
this.setTitle(this._formatEventTime());
|
||||||
|
this.setBody(event.summary);
|
||||||
|
}
|
||||||
|
|
||||||
_formatEventTime() {
|
_formatEventTime() {
|
||||||
let periodBegin = _getBeginningOfDay(this._date);
|
let periodBegin = _getBeginningOfDay(this._date);
|
||||||
let periodEnd = _getEndOfDay(this._date);
|
let periodEnd = _getEndOfDay(this._date);
|
||||||
@ -874,7 +906,7 @@ class EventsSection extends MessageList.MessageListSection {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_reloadEvents() {
|
_reloadEvents() {
|
||||||
if (this._eventSource.isLoading)
|
if (this._eventSource.isLoading || this._reloading)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
this._reloading = true;
|
this._reloading = true;
|
||||||
@ -900,6 +932,7 @@ class EventsSection extends MessageList.MessageListSection {
|
|||||||
this._messageById.set(event.id, message);
|
this._messageById.set(event.id, message);
|
||||||
this.addMessage(message, false);
|
this.addMessage(message, false);
|
||||||
} else {
|
} else {
|
||||||
|
message.update(event);
|
||||||
this.moveMessage(message, i, false);
|
this.moveMessage(message, i, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,17 +13,13 @@ var ComponentManager = class {
|
|||||||
_sessionUpdated() {
|
_sessionUpdated() {
|
||||||
let newEnabledComponents = Main.sessionMode.components;
|
let newEnabledComponents = Main.sessionMode.components;
|
||||||
|
|
||||||
newEnabledComponents.filter(
|
newEnabledComponents
|
||||||
name => !this._enabledComponents.includes(name)
|
.filter(name => !this._enabledComponents.includes(name))
|
||||||
).forEach(name => {
|
.forEach(name => this._enableComponent(name));
|
||||||
this._enableComponent(name);
|
|
||||||
});
|
|
||||||
|
|
||||||
this._enabledComponents.filter(
|
this._enabledComponents
|
||||||
name => !newEnabledComponents.includes(name)
|
.filter(name => !newEnabledComponents.includes(name))
|
||||||
).forEach(name => {
|
.forEach(name => this._disableComponent(name));
|
||||||
this._disableComponent(name);
|
|
||||||
});
|
|
||||||
|
|
||||||
this._enabledComponents = newEnabledComponents;
|
this._enabledComponents = newEnabledComponents;
|
||||||
}
|
}
|
||||||
|
@ -125,8 +125,7 @@ var ContentTypeDiscoverer = class {
|
|||||||
_emitCallback(mount, contentTypes = []) {
|
_emitCallback(mount, contentTypes = []) {
|
||||||
// we're not interested in win32 software content types here
|
// we're not interested in win32 software content types here
|
||||||
contentTypes = contentTypes.filter(
|
contentTypes = contentTypes.filter(
|
||||||
type => type != 'x-content/win32-software'
|
type => type !== 'x-content/win32-software');
|
||||||
);
|
|
||||||
|
|
||||||
let apps = [];
|
let apps = [];
|
||||||
contentTypes.forEach(type => {
|
contentTypes.forEach(type => {
|
||||||
|
@ -10,6 +10,7 @@ const MessageTray = imports.ui.messageTray;
|
|||||||
const ModalDialog = imports.ui.modalDialog;
|
const ModalDialog = imports.ui.modalDialog;
|
||||||
const ShellEntry = imports.ui.shellEntry;
|
const ShellEntry = imports.ui.shellEntry;
|
||||||
|
|
||||||
|
Gio._promisify(Shell.NetworkAgent.prototype, 'init_async', 'init_finish');
|
||||||
Gio._promisify(Shell.NetworkAgent.prototype,
|
Gio._promisify(Shell.NetworkAgent.prototype,
|
||||||
'search_vpn_plugin', 'search_vpn_plugin_finish');
|
'search_vpn_plugin', 'search_vpn_plugin_finish');
|
||||||
|
|
||||||
@ -482,39 +483,37 @@ var VPNRequestHandler = class {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_readStdoutOldStyle() {
|
async _readStdoutOldStyle() {
|
||||||
this._dataStdout.read_line_async(GLib.PRIORITY_DEFAULT, null, (stream, result) => {
|
const [line, len_] =
|
||||||
let [line, len_] = this._dataStdout.read_line_finish_utf8(result);
|
await this._dataStdout.read_line_async(GLib.PRIORITY_DEFAULT, null);
|
||||||
|
|
||||||
if (line == null) {
|
if (line === null) {
|
||||||
// end of file
|
// end of file
|
||||||
this._stdout.close(null);
|
this._stdout.close(null);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this._vpnChildProcessLineOldStyle(line);
|
this._vpnChildProcessLineOldStyle(line);
|
||||||
|
|
||||||
// try to read more!
|
// try to read more!
|
||||||
this._readStdoutOldStyle();
|
this._readStdoutOldStyle();
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_readStdoutNewStyle() {
|
async _readStdoutNewStyle() {
|
||||||
this._dataStdout.fill_async(-1, GLib.PRIORITY_DEFAULT, null, (stream, result) => {
|
const cnt =
|
||||||
let cnt = this._dataStdout.fill_finish(result);
|
await this._dataStdout.fill_async(-1, GLib.PRIORITY_DEFAULT, null);
|
||||||
|
|
||||||
if (cnt == 0) {
|
if (cnt === 0) {
|
||||||
// end of file
|
// end of file
|
||||||
this._showNewStyleDialog();
|
this._showNewStyleDialog();
|
||||||
|
|
||||||
this._stdout.close(null);
|
this._stdout.close(null);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try to read more
|
// Try to read more
|
||||||
this._dataStdout.set_buffer_size(2 * this._dataStdout.get_buffer_size());
|
this._dataStdout.set_buffer_size(2 * this._dataStdout.get_buffer_size());
|
||||||
this._readStdoutNewStyle();
|
this._readStdoutNewStyle();
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_showNewStyleDialog() {
|
_showNewStyleDialog() {
|
||||||
@ -621,15 +620,17 @@ var NetworkAgent = class {
|
|||||||
this._native.connect('cancel-request', this._cancelRequest.bind(this));
|
this._native.connect('cancel-request', this._cancelRequest.bind(this));
|
||||||
|
|
||||||
this._initialized = false;
|
this._initialized = false;
|
||||||
this._native.init_async(GLib.PRIORITY_DEFAULT, null, (o, res) => {
|
this._initNative();
|
||||||
try {
|
}
|
||||||
this._native.init_finish(res);
|
|
||||||
this._initialized = true;
|
async _initNative() {
|
||||||
} catch (e) {
|
try {
|
||||||
this._native = null;
|
await this._native.init_async(GLib.PRIORITY_DEFAULT, null);
|
||||||
logError(e, 'error initializing the NetworkManager Agent');
|
this._initialized = true;
|
||||||
}
|
} catch (e) {
|
||||||
});
|
this._native = null;
|
||||||
|
logError(e, 'error initializing the NetworkManager Agent');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enable() {
|
enable() {
|
||||||
|
@ -327,12 +327,16 @@ var AuthenticationDialog = GObject.registerClass({
|
|||||||
}
|
}
|
||||||
|
|
||||||
let resetDialog = () => {
|
let resetDialog = () => {
|
||||||
|
this._sessionRequestTimeoutId = 0;
|
||||||
|
|
||||||
if (this.state != ModalDialog.State.OPENED)
|
if (this.state != ModalDialog.State.OPENED)
|
||||||
return;
|
return GLib.SOURCE_REMOVE;
|
||||||
|
|
||||||
this._passwordEntry.hide();
|
this._passwordEntry.hide();
|
||||||
this._cancelButton.grab_key_focus();
|
this._cancelButton.grab_key_focus();
|
||||||
this._okButton.reactive = false;
|
this._okButton.reactive = false;
|
||||||
|
|
||||||
|
return GLib.SOURCE_REMOVE;
|
||||||
};
|
};
|
||||||
|
|
||||||
if (delay) {
|
if (delay) {
|
||||||
|
@ -7,6 +7,14 @@ var Tpl = null;
|
|||||||
var Tp = null;
|
var Tp = null;
|
||||||
try {
|
try {
|
||||||
({ TelepathyGLib: Tp, TelepathyLogger: Tpl } = imports.gi);
|
({ TelepathyGLib: Tp, TelepathyLogger: Tpl } = imports.gi);
|
||||||
|
|
||||||
|
Gio._promisify(Tp.Channel.prototype, 'close_async', 'close_finish');
|
||||||
|
Gio._promisify(Tp.Channel.prototype,
|
||||||
|
'send_message_async', 'send_message_finish');
|
||||||
|
Gio._promisify(Tp.ChannelDispatchOperation.prototype,
|
||||||
|
'claim_with_async', 'claim_with_finish');
|
||||||
|
Gio._promisify(Tpl.LogManager.prototype,
|
||||||
|
'get_filtered_events_async', 'get_filtered_events_finish');
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
log('Telepathy is not available, chat integration will be disabled.');
|
log('Telepathy is not available, chat integration will be disabled.');
|
||||||
}
|
}
|
||||||
@ -215,7 +223,7 @@ class TelepathyClient extends Tp.BaseClient {
|
|||||||
|
|
||||||
// We can only handle text channel, so close any other channel
|
// We can only handle text channel, so close any other channel
|
||||||
if (!(channel instanceof Tp.TextChannel)) {
|
if (!(channel instanceof Tp.TextChannel)) {
|
||||||
channel.close_async(null);
|
channel.close_async();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -261,7 +269,7 @@ class TelepathyClient extends Tp.BaseClient {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_approveTextChannel(account, conn, channel, dispatchOp, context) {
|
async _approveTextChannel(account, conn, channel, dispatchOp, context) {
|
||||||
let [targetHandle_, targetHandleType] = channel.get_handle();
|
let [targetHandle_, targetHandleType] = channel.get_handle();
|
||||||
|
|
||||||
if (targetHandleType != Tp.HandleType.CONTACT) {
|
if (targetHandleType != Tp.HandleType.CONTACT) {
|
||||||
@ -270,17 +278,15 @@ class TelepathyClient extends Tp.BaseClient {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Approve private text channels right away as we are going to handle it
|
|
||||||
dispatchOp.claim_with_async(this, (o, result) => {
|
|
||||||
try {
|
|
||||||
dispatchOp.claim_with_finish(result);
|
|
||||||
this._handlingChannels(account, conn, [channel], false);
|
|
||||||
} catch (err) {
|
|
||||||
log('Failed to Claim channel: %s'.format(err.toString()));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
context.accept();
|
context.accept();
|
||||||
|
|
||||||
|
// Approve private text channels right away as we are going to handle it
|
||||||
|
try {
|
||||||
|
await dispatchOp.claim_with_async(this);
|
||||||
|
this._handlingChannels(account, conn, [channel], false);
|
||||||
|
} catch (err) {
|
||||||
|
log('Failed to Claim channel: %s'.format(err.toString()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_delegatedChannelsCb(_client, _channels) {
|
_delegatedChannelsCb(_client, _channels) {
|
||||||
@ -441,17 +447,14 @@ class ChatSource extends MessageTray.Source {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_getLogMessages() {
|
async _getLogMessages() {
|
||||||
let logManager = Tpl.LogManager.dup_singleton();
|
let logManager = Tpl.LogManager.dup_singleton();
|
||||||
let entity = Tpl.Entity.new_from_tp_contact(this._contact, Tpl.EntityType.CONTACT);
|
let entity = Tpl.Entity.new_from_tp_contact(this._contact, Tpl.EntityType.CONTACT);
|
||||||
|
|
||||||
logManager.get_filtered_events_async(this._account, entity,
|
const [events] = await logManager.get_filtered_events_async(
|
||||||
Tpl.EventTypeMask.TEXT, SCROLLBACK_HISTORY_LINES,
|
this._account, entity,
|
||||||
null, this._displayPendingMessages.bind(this));
|
Tpl.EventTypeMask.TEXT, SCROLLBACK_HISTORY_LINES,
|
||||||
}
|
null);
|
||||||
|
|
||||||
_displayPendingMessages(logManager, result) {
|
|
||||||
let [success_, events] = logManager.get_filtered_events_finish(result);
|
|
||||||
|
|
||||||
let logMessages = events.map(e => ChatMessage.newFromTplTextEvent(e));
|
let logMessages = events.map(e => ChatMessage.newFromTplTextEvent(e));
|
||||||
this._ensureNotification();
|
this._ensureNotification();
|
||||||
@ -509,9 +512,7 @@ class ChatSource extends MessageTray.Source {
|
|||||||
this._ackMessages();
|
this._ackMessages();
|
||||||
// The chat box has been destroyed so it can't
|
// The chat box has been destroyed so it can't
|
||||||
// handle the channel any more.
|
// handle the channel any more.
|
||||||
this._channel.close_async((channel, result) => {
|
this._channel.close_async();
|
||||||
channel.close_finish(result);
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
// Don't indicate any unread messages when the notification
|
// Don't indicate any unread messages when the notification
|
||||||
// that represents them has been destroyed.
|
// that represents them has been destroyed.
|
||||||
@ -609,9 +610,7 @@ class ChatSource extends MessageTray.Source {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let msg = Tp.ClientMessage.new_text(type, text);
|
let msg = Tp.ClientMessage.new_text(type, text);
|
||||||
this._channel.send_message_async(msg, 0, (src, result) => {
|
this._channel.send_message_async(msg, 0);
|
||||||
this._channel.send_message_finish(result);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
setChatState(state) {
|
setChatState(state) {
|
||||||
|
@ -281,13 +281,13 @@ class WeatherSection extends St.Button {
|
|||||||
this.child = box;
|
this.child = box;
|
||||||
|
|
||||||
let titleBox = new St.BoxLayout({ style_class: 'weather-header-box' });
|
let titleBox = new St.BoxLayout({ style_class: 'weather-header-box' });
|
||||||
titleBox.add_child(new St.Label({
|
this._titleLabel = new St.Label({
|
||||||
style_class: 'weather-header',
|
style_class: 'weather-header',
|
||||||
x_align: Clutter.ActorAlign.START,
|
x_align: Clutter.ActorAlign.START,
|
||||||
x_expand: true,
|
x_expand: true,
|
||||||
y_align: Clutter.ActorAlign.END,
|
y_align: Clutter.ActorAlign.END,
|
||||||
text: _('Weather'),
|
});
|
||||||
}));
|
titleBox.add_child(this._titleLabel);
|
||||||
box.add_child(titleBox);
|
box.add_child(titleBox);
|
||||||
|
|
||||||
this._titleLocation = new St.Label({
|
this._titleLocation = new St.Label({
|
||||||
@ -414,10 +414,8 @@ class WeatherSection extends St.Button {
|
|||||||
_updateForecasts() {
|
_updateForecasts() {
|
||||||
this._forecastGrid.destroy_all_children();
|
this._forecastGrid.destroy_all_children();
|
||||||
|
|
||||||
if (!this._weatherClient.hasLocation) {
|
if (!this._weatherClient.hasLocation)
|
||||||
this._setStatusLabel(_("Select a location…"));
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
const { info } = this._weatherClient;
|
const { info } = this._weatherClient;
|
||||||
this._titleLocation.text = this._findBestLocationName(info.location);
|
this._titleLocation.text = this._findBestLocationName(info.location);
|
||||||
@ -444,6 +442,12 @@ class WeatherSection extends St.Button {
|
|||||||
if (!this.visible)
|
if (!this.visible)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (this._weatherClient.hasLocation)
|
||||||
|
this._titleLabel.text = _('Weather');
|
||||||
|
else
|
||||||
|
this._titleLabel.text = _('Select weather location…');
|
||||||
|
|
||||||
|
this._forecastGrid.visible = this._weatherClient.hasLocation;
|
||||||
this._titleLocation.visible = this._weatherClient.hasLocation;
|
this._titleLocation.visible = this._weatherClient.hasLocation;
|
||||||
|
|
||||||
this._updateForecasts();
|
this._updateForecasts();
|
||||||
|
@ -29,8 +29,6 @@ const UserWidget = imports.ui.userWidget;
|
|||||||
|
|
||||||
const { loadInterfaceXML } = imports.misc.fileUtils;
|
const { loadInterfaceXML } = imports.misc.fileUtils;
|
||||||
|
|
||||||
Gio._promisify(Gio.DBusConnection.prototype, 'call', 'call_finish');
|
|
||||||
|
|
||||||
const _ITEM_ICON_SIZE = 64;
|
const _ITEM_ICON_SIZE = 64;
|
||||||
|
|
||||||
const EndSessionDialogIface = loadInterfaceXML('org.gnome.SessionManager.EndSessionDialog');
|
const EndSessionDialogIface = loadInterfaceXML('org.gnome.SessionManager.EndSessionDialog');
|
||||||
@ -280,7 +278,7 @@ class EndSessionDialog extends ModalDialog.ModalDialog {
|
|||||||
this._dbusImpl.export(Gio.DBus.session, '/org/gnome/SessionManager/EndSessionDialog');
|
this._dbusImpl.export(Gio.DBus.session, '/org/gnome/SessionManager/EndSessionDialog');
|
||||||
}
|
}
|
||||||
|
|
||||||
_onPkOfflineProxyCreated(proxy, error) {
|
async _onPkOfflineProxyCreated(proxy, error) {
|
||||||
if (error) {
|
if (error) {
|
||||||
log(error.message);
|
log(error.message);
|
||||||
return;
|
return;
|
||||||
@ -295,15 +293,12 @@ class EndSessionDialog extends ModalDialog.ModalDialog {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// It only makes sense to check for this permission if PackageKit is available.
|
// It only makes sense to check for this permission if PackageKit is available.
|
||||||
Polkit.Permission.new(
|
try {
|
||||||
'org.freedesktop.packagekit.trigger-offline-update', null, null,
|
this._updatesPermission = await Polkit.Permission.new(
|
||||||
(source, res) => {
|
'org.freedesktop.packagekit.trigger-offline-update', null, null);
|
||||||
try {
|
} catch (e) {
|
||||||
this._updatesPermission = Polkit.Permission.new_finish(res);
|
log('No permission to trigger offline updates: %s'.format(e.toString()));
|
||||||
} catch (e) {
|
}
|
||||||
log('No permission to trigger offline updates: %s'.format(e.toString()));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_onDestroy() {
|
_onDestroy() {
|
||||||
|
@ -10,10 +10,21 @@ imports.gi.versions.Gtk = '3.0';
|
|||||||
imports.gi.versions.TelepathyGLib = '0.12';
|
imports.gi.versions.TelepathyGLib = '0.12';
|
||||||
imports.gi.versions.TelepathyLogger = '0.2';
|
imports.gi.versions.TelepathyLogger = '0.2';
|
||||||
|
|
||||||
const { Clutter, Gio, GLib, GObject, Meta, Shell, St } = imports.gi;
|
const { Clutter, Gio, GLib, GObject, Meta, Polkit, Shell, St } = imports.gi;
|
||||||
const Gettext = imports.gettext;
|
const Gettext = imports.gettext;
|
||||||
const System = imports.system;
|
const System = imports.system;
|
||||||
|
|
||||||
|
Gio._promisify(Gio.DataInputStream.prototype, 'fill_async', 'fill_finish');
|
||||||
|
Gio._promisify(Gio.DataInputStream.prototype,
|
||||||
|
'read_line_async', 'read_line_finish');
|
||||||
|
Gio._promisify(Gio.DBus, 'get', 'get_finish');
|
||||||
|
Gio._promisify(Gio.DBusConnection.prototype, 'call', 'call_finish');
|
||||||
|
Gio._promisify(Gio.DBusProxy, 'new', 'new_finish');
|
||||||
|
Gio._promisify(Gio.DBusProxy.prototype, 'init_async', 'init_finish');
|
||||||
|
Gio._promisify(Gio.DBusProxy.prototype,
|
||||||
|
'call_with_unix_fd_list', 'call_with_unix_fd_list_finish');
|
||||||
|
Gio._promisify(Polkit.Permission, 'new', 'new_finish');
|
||||||
|
|
||||||
let _localTimeZone = null;
|
let _localTimeZone = null;
|
||||||
|
|
||||||
// We can't import shell JS modules yet, because they may have
|
// We can't import shell JS modules yet, because they may have
|
||||||
@ -234,16 +245,15 @@ function _loggingFunc(...args) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function init() {
|
function init() {
|
||||||
// Add some bindings to the global JS namespace; (gjs keeps the web
|
// Add some bindings to the global JS namespace
|
||||||
// browser convention of having that namespace be called 'window'.)
|
globalThis.global = Shell.Global.get();
|
||||||
window.global = Shell.Global.get();
|
|
||||||
|
|
||||||
window.log = _loggingFunc;
|
globalThis.log = _loggingFunc;
|
||||||
|
|
||||||
window._ = Gettext.gettext;
|
globalThis._ = Gettext.gettext;
|
||||||
window.C_ = Gettext.pgettext;
|
globalThis.C_ = Gettext.pgettext;
|
||||||
window.ngettext = Gettext.ngettext;
|
globalThis.ngettext = Gettext.ngettext;
|
||||||
window.N_ = s => s;
|
globalThis.N_ = s => s;
|
||||||
|
|
||||||
GObject.gtypeNameBasedOnJSPath = true;
|
GObject.gtypeNameBasedOnJSPath = true;
|
||||||
|
|
||||||
@ -345,9 +355,7 @@ function init() {
|
|||||||
|
|
||||||
// OK, now things are initialized enough that we can import shell JS
|
// OK, now things are initialized enough that we can import shell JS
|
||||||
const Format = imports.format;
|
const Format = imports.format;
|
||||||
const Tweener = imports.ui.tweener;
|
|
||||||
|
|
||||||
Tweener.init();
|
|
||||||
String.prototype.format = Format.format;
|
String.prototype.format = Format.format;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -215,6 +215,24 @@ var ExtensionManager = class {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
openExtensionPrefs(uuid, parentWindow, options) {
|
||||||
|
const extension = this.lookup(uuid);
|
||||||
|
if (!extension || !extension.hasPrefs)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Gio.DBus.session.call(
|
||||||
|
'org.gnome.Shell.Extensions',
|
||||||
|
'/org/gnome/Shell/Extensions',
|
||||||
|
'org.gnome.Shell.Extensions',
|
||||||
|
'OpenExtensionPrefs',
|
||||||
|
new GLib.Variant('(ssa{sv})', [uuid, parentWindow, options]),
|
||||||
|
null,
|
||||||
|
Gio.DBusCallFlags.NONE,
|
||||||
|
-1,
|
||||||
|
null);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
notifyExtensionUpdate(uuid) {
|
notifyExtensionUpdate(uuid) {
|
||||||
let extension = this.lookup(uuid);
|
let extension = this.lookup(uuid);
|
||||||
if (!extension)
|
if (!extension)
|
||||||
@ -445,19 +463,15 @@ var ExtensionManager = class {
|
|||||||
|
|
||||||
// Find and enable all the newly enabled extensions: UUIDs found in the
|
// Find and enable all the newly enabled extensions: UUIDs found in the
|
||||||
// new setting, but not in the old one.
|
// new setting, but not in the old one.
|
||||||
newEnabledExtensions.filter(
|
newEnabledExtensions
|
||||||
uuid => !this._enabledExtensions.includes(uuid)
|
.filter(uuid => !this._enabledExtensions.includes(uuid))
|
||||||
).forEach(uuid => {
|
.forEach(uuid => this._callExtensionEnable(uuid));
|
||||||
this._callExtensionEnable(uuid);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Find and disable all the newly disabled extensions: UUIDs found in the
|
// Find and disable all the newly disabled extensions: UUIDs found in the
|
||||||
// old setting, but not in the new one.
|
// old setting, but not in the new one.
|
||||||
this._extensionOrder.filter(
|
this._extensionOrder
|
||||||
uuid => !newEnabledExtensions.includes(uuid)
|
.filter(uuid => !newEnabledExtensions.includes(uuid))
|
||||||
).reverse().forEach(uuid => {
|
.reverse().forEach(uuid => this._callExtensionDisable(uuid));
|
||||||
this._callExtensionDisable(uuid);
|
|
||||||
});
|
|
||||||
|
|
||||||
this._enabledExtensions = newEnabledExtensions;
|
this._enabledExtensions = newEnabledExtensions;
|
||||||
}
|
}
|
||||||
|
@ -114,8 +114,11 @@ class BaseIcon extends St.Bin {
|
|||||||
if (this._setSizeManually) {
|
if (this._setSizeManually) {
|
||||||
size = this.iconSize;
|
size = this.iconSize;
|
||||||
} else {
|
} else {
|
||||||
|
const { scaleFactor } =
|
||||||
|
St.ThemeContext.get_for_stage(global.stage);
|
||||||
|
|
||||||
let [found, len] = node.lookup_length('icon-size', false);
|
let [found, len] = node.lookup_length('icon-size', false);
|
||||||
size = found ? len : ICON_SIZE;
|
size = found ? len / scaleFactor : ICON_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.iconSize == size && this._iconBin.child)
|
if (this.iconSize == size && this._iconBin.child)
|
||||||
|
@ -722,7 +722,7 @@ var EmojiPager = GObject.registerClass({
|
|||||||
|
|
||||||
_onPan(action) {
|
_onPan(action) {
|
||||||
let [dist_, dx, dy_] = action.get_motion_delta(0);
|
let [dist_, dx, dy_] = action.get_motion_delta(0);
|
||||||
this.delta = this.delta + dx;
|
this.delta += dx;
|
||||||
|
|
||||||
if (this._currentKey != null) {
|
if (this._currentKey != null) {
|
||||||
this._currentKey.cancel();
|
this._currentKey.cancel();
|
||||||
@ -935,8 +935,7 @@ var EmojiSelection = GObject.registerClass({
|
|||||||
this.add_child(this._emojiPager);
|
this.add_child(this._emojiPager);
|
||||||
|
|
||||||
this._pageIndicator = new PageIndicators.PageIndicators(
|
this._pageIndicator = new PageIndicators.PageIndicators(
|
||||||
Clutter.Orientation.HORIZONTAL
|
Clutter.Orientation.HORIZONTAL);
|
||||||
);
|
|
||||||
this.add_child(this._pageIndicator);
|
this.add_child(this._pageIndicator);
|
||||||
this._pageIndicator.setReactive(false);
|
this._pageIndicator.setReactive(false);
|
||||||
|
|
||||||
@ -1119,7 +1118,7 @@ var KeyboardManager = class KeyBoardManager {
|
|||||||
this._seat.connect('notify::touch-mode', this._syncEnabled.bind(this));
|
this._seat.connect('notify::touch-mode', this._syncEnabled.bind(this));
|
||||||
|
|
||||||
this._lastDevice = null;
|
this._lastDevice = null;
|
||||||
Meta.get_backend().connect('last-device-changed', (backend, device) => {
|
global.backend.connect('last-device-changed', (backend, device) => {
|
||||||
if (device.device_type === Clutter.InputDeviceType.KEYBOARD_DEVICE)
|
if (device.device_type === Clutter.InputDeviceType.KEYBOARD_DEVICE)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -1257,6 +1256,10 @@ class Keyboard extends St.BoxLayout {
|
|||||||
return this._keyboardVisible && super.visible;
|
return this._keyboardVisible && super.visible;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
set visible(visible) {
|
||||||
|
super.visible = visible;
|
||||||
|
}
|
||||||
|
|
||||||
_onFocusPositionChanged(focusTracker) {
|
_onFocusPositionChanged(focusTracker) {
|
||||||
let rect = focusTracker.getCurrentRect();
|
let rect = focusTracker.getCurrentRect();
|
||||||
this.setCursorLocation(focusTracker.currentWindow, rect.x, rect.y, rect.width, rect.height);
|
this.setCursorLocation(focusTracker.currentWindow, rect.x, rect.y, rect.width, rect.height);
|
||||||
|
@ -27,13 +27,11 @@ var RadialShaderEffect = GObject.registerClass({
|
|||||||
'brightness': GObject.ParamSpec.float(
|
'brightness': GObject.ParamSpec.float(
|
||||||
'brightness', 'brightness', 'brightness',
|
'brightness', 'brightness', 'brightness',
|
||||||
GObject.ParamFlags.READWRITE,
|
GObject.ParamFlags.READWRITE,
|
||||||
0, 1, 1
|
0, 1, 1),
|
||||||
),
|
|
||||||
'sharpness': GObject.ParamSpec.float(
|
'sharpness': GObject.ParamSpec.float(
|
||||||
'sharpness', 'sharpness', 'sharpness',
|
'sharpness', 'sharpness', 'sharpness',
|
||||||
GObject.ParamFlags.READWRITE,
|
GObject.ParamFlags.READWRITE,
|
||||||
0, 1, 0
|
0, 1, 0),
|
||||||
),
|
|
||||||
},
|
},
|
||||||
}, class RadialShaderEffect extends Shell.GLSLEffect {
|
}, class RadialShaderEffect extends Shell.GLSLEffect {
|
||||||
_init(params) {
|
_init(params) {
|
||||||
|
@ -37,10 +37,9 @@ const LG_ANIMATION_TIME = 500;
|
|||||||
|
|
||||||
function _getAutoCompleteGlobalKeywords() {
|
function _getAutoCompleteGlobalKeywords() {
|
||||||
const keywords = ['true', 'false', 'null', 'new'];
|
const keywords = ['true', 'false', 'null', 'new'];
|
||||||
// Don't add the private properties of window (i.e., ones starting with '_')
|
// Don't add the private properties of globalThis (i.e., ones starting with '_')
|
||||||
const windowProperties = Object.getOwnPropertyNames(window).filter(
|
const windowProperties = Object.getOwnPropertyNames(globalThis).filter(
|
||||||
a => a.charAt(0) != '_'
|
a => a.charAt(0) !== '_');
|
||||||
);
|
|
||||||
const headerProperties = JsParse.getDeclaredConstants(commandHeader);
|
const headerProperties = JsParse.getDeclaredConstants(commandHeader);
|
||||||
|
|
||||||
return keywords.concat(windowProperties).concat(headerProperties);
|
return keywords.concat(windowProperties).concat(headerProperties);
|
||||||
|
@ -643,8 +643,7 @@ var Magnifier = class Magnifier {
|
|||||||
// Applies only to the first zoom region.
|
// Applies only to the first zoom region.
|
||||||
if (this._zoomRegions.length) {
|
if (this._zoomRegions.length) {
|
||||||
this._zoomRegions[0].setClampScrollingAtEdges(
|
this._zoomRegions[0].setClampScrollingAtEdges(
|
||||||
!this._settings.get_boolean(CLAMP_MODE_KEY)
|
!this._settings.get_boolean(CLAMP_MODE_KEY));
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -652,8 +651,7 @@ var Magnifier = class Magnifier {
|
|||||||
// Applies only to the first zoom region.
|
// Applies only to the first zoom region.
|
||||||
if (this._zoomRegions.length) {
|
if (this._zoomRegions.length) {
|
||||||
this._zoomRegions[0].setMouseTrackingMode(
|
this._zoomRegions[0].setMouseTrackingMode(
|
||||||
this._settings.get_enum(MOUSE_TRACKING_KEY)
|
this._settings.get_enum(MOUSE_TRACKING_KEY));
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -661,8 +659,7 @@ var Magnifier = class Magnifier {
|
|||||||
// Applies only to the first zoom region.
|
// Applies only to the first zoom region.
|
||||||
if (this._zoomRegions.length) {
|
if (this._zoomRegions.length) {
|
||||||
this._zoomRegions[0].setFocusTrackingMode(
|
this._zoomRegions[0].setFocusTrackingMode(
|
||||||
this._settings.get_enum(FOCUS_TRACKING_KEY)
|
this._settings.get_enum(FOCUS_TRACKING_KEY));
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -670,8 +667,7 @@ var Magnifier = class Magnifier {
|
|||||||
// Applies only to the first zoom region.
|
// Applies only to the first zoom region.
|
||||||
if (this._zoomRegions.length) {
|
if (this._zoomRegions.length) {
|
||||||
this._zoomRegions[0].setCaretTrackingMode(
|
this._zoomRegions[0].setCaretTrackingMode(
|
||||||
this._settings.get_enum(CARET_TRACKING_KEY)
|
this._settings.get_enum(CARET_TRACKING_KEY));
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -679,8 +675,7 @@ var Magnifier = class Magnifier {
|
|||||||
// Applies only to the first zoom region.
|
// Applies only to the first zoom region.
|
||||||
if (this._zoomRegions.length) {
|
if (this._zoomRegions.length) {
|
||||||
this._zoomRegions[0].setInvertLightness(
|
this._zoomRegions[0].setInvertLightness(
|
||||||
this._settings.get_boolean(INVERT_LIGHTNESS_KEY)
|
this._settings.get_boolean(INVERT_LIGHTNESS_KEY));
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -688,8 +683,7 @@ var Magnifier = class Magnifier {
|
|||||||
// Applies only to the first zoom region.
|
// Applies only to the first zoom region.
|
||||||
if (this._zoomRegions.length) {
|
if (this._zoomRegions.length) {
|
||||||
this._zoomRegions[0].setColorSaturation(
|
this._zoomRegions[0].setColorSaturation(
|
||||||
this._settings.get_double(COLOR_SATURATION_KEY)
|
this._settings.get_double(COLOR_SATURATION_KEY));
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1941,9 +1935,8 @@ var MagShaderEffects = class MagShaderEffects {
|
|||||||
// it modifies the brightness and/or contrast.
|
// it modifies the brightness and/or contrast.
|
||||||
let [cRed, cGreen, cBlue] = this._brightnessContrast.get_contrast();
|
let [cRed, cGreen, cBlue] = this._brightnessContrast.get_contrast();
|
||||||
this._brightnessContrast.set_enabled(
|
this._brightnessContrast.set_enabled(
|
||||||
bRed != NO_CHANGE || bGreen != NO_CHANGE || bBlue != NO_CHANGE ||
|
bRed !== NO_CHANGE || bGreen !== NO_CHANGE || bBlue !== NO_CHANGE ||
|
||||||
cRed != NO_CHANGE || cGreen != NO_CHANGE || cBlue != NO_CHANGE
|
cRed !== NO_CHANGE || cGreen !== NO_CHANGE || cBlue !== NO_CHANGE);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1970,8 +1963,7 @@ var MagShaderEffects = class MagShaderEffects {
|
|||||||
// a null first argument.
|
// a null first argument.
|
||||||
let [bRed, bGreen, bBlue] = this._brightnessContrast.get_brightness();
|
let [bRed, bGreen, bBlue] = this._brightnessContrast.get_brightness();
|
||||||
this._brightnessContrast.set_enabled(
|
this._brightnessContrast.set_enabled(
|
||||||
cRed != NO_CHANGE || cGreen != NO_CHANGE || cBlue != NO_CHANGE ||
|
cRed !== NO_CHANGE || cGreen !== NO_CHANGE || cBlue !== NO_CHANGE ||
|
||||||
bRed != NO_CHANGE || bGreen != NO_CHANGE || bBlue != NO_CHANGE
|
bRed !== NO_CHANGE || bGreen !== NO_CHANGE || bBlue !== NO_CHANGE);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -46,6 +46,7 @@ const XdndHandler = imports.ui.xdndHandler;
|
|||||||
const KbdA11yDialog = imports.ui.kbdA11yDialog;
|
const KbdA11yDialog = imports.ui.kbdA11yDialog;
|
||||||
const LocatePointer = imports.ui.locatePointer;
|
const LocatePointer = imports.ui.locatePointer;
|
||||||
const PointerA11yTimeout = imports.ui.pointerA11yTimeout;
|
const PointerA11yTimeout = imports.ui.pointerA11yTimeout;
|
||||||
|
const ParentalControlsManager = imports.misc.parentalControlsManager;
|
||||||
|
|
||||||
const A11Y_SCHEMA = 'org.gnome.desktop.a11y.keyboard';
|
const A11Y_SCHEMA = 'org.gnome.desktop.a11y.keyboard';
|
||||||
const STICKY_KEYS_ENABLE = 'stickykeys-enable';
|
const STICKY_KEYS_ENABLE = 'stickykeys-enable';
|
||||||
@ -96,6 +97,8 @@ let _oskResource = null;
|
|||||||
Gio._promisify(Gio._LocalFilePrototype, 'delete_async', 'delete_finish');
|
Gio._promisify(Gio._LocalFilePrototype, 'delete_async', 'delete_finish');
|
||||||
Gio._promisify(Gio._LocalFilePrototype, 'touch_async', 'touch_finish');
|
Gio._promisify(Gio._LocalFilePrototype, 'touch_async', 'touch_finish');
|
||||||
|
|
||||||
|
let _remoteAccessInhibited = false;
|
||||||
|
|
||||||
function _sessionUpdated() {
|
function _sessionUpdated() {
|
||||||
if (sessionMode.isPrimary)
|
if (sessionMode.isPrimary)
|
||||||
_loadDefaultStylesheet();
|
_loadDefaultStylesheet();
|
||||||
@ -120,24 +123,41 @@ function _sessionUpdated() {
|
|||||||
if (lookingGlass)
|
if (lookingGlass)
|
||||||
lookingGlass.close();
|
lookingGlass.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let remoteAccessController = global.backend.get_remote_access_controller();
|
||||||
|
if (remoteAccessController) {
|
||||||
|
if (sessionMode.allowScreencast && _remoteAccessInhibited) {
|
||||||
|
remoteAccessController.uninhibit_remote_access();
|
||||||
|
_remoteAccessInhibited = false;
|
||||||
|
} else if (!sessionMode.allowScreencast && !_remoteAccessInhibited) {
|
||||||
|
remoteAccessController.inhibit_remote_access();
|
||||||
|
_remoteAccessInhibited = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function start() {
|
function start() {
|
||||||
// These are here so we don't break compatibility.
|
// These are here so we don't break compatibility.
|
||||||
global.logError = window.log;
|
global.logError = globalThis.log;
|
||||||
global.log = window.log;
|
global.log = globalThis.log;
|
||||||
|
|
||||||
// Chain up async errors reported from C
|
// Chain up async errors reported from C
|
||||||
global.connect('notify-error', (global, msg, detail) => {
|
global.connect('notify-error', (global, msg, detail) => {
|
||||||
notifyError(msg, detail);
|
notifyError(msg, detail);
|
||||||
});
|
});
|
||||||
|
|
||||||
Gio.DesktopAppInfo.set_desktop_env('GNOME');
|
let currentDesktop = GLib.getenv('XDG_CURRENT_DESKTOP');
|
||||||
|
if (!currentDesktop || !currentDesktop.split(':').includes('GNOME'))
|
||||||
|
Gio.DesktopAppInfo.set_desktop_env('GNOME');
|
||||||
|
|
||||||
sessionMode = new SessionMode.SessionMode();
|
sessionMode = new SessionMode.SessionMode();
|
||||||
sessionMode.connect('updated', _sessionUpdated);
|
sessionMode.connect('updated', _sessionUpdated);
|
||||||
|
|
||||||
St.Settings.get().connect('notify::gtk-theme', _loadDefaultStylesheet);
|
St.Settings.get().connect('notify::gtk-theme', _loadDefaultStylesheet);
|
||||||
|
|
||||||
|
// Initialize ParentalControlsManager before the UI
|
||||||
|
ParentalControlsManager.getDefault();
|
||||||
|
|
||||||
_initializeUI();
|
_initializeUI();
|
||||||
|
|
||||||
shellAccessDialogDBusService = new AccessDialog.AccessDialogDBus();
|
shellAccessDialogDBusService = new AccessDialog.AccessDialogDBus();
|
||||||
@ -519,7 +539,9 @@ function pushModal(actor, params) {
|
|||||||
let prevFocusDestroyId;
|
let prevFocusDestroyId;
|
||||||
if (prevFocus != null) {
|
if (prevFocus != null) {
|
||||||
prevFocusDestroyId = prevFocus.connect('destroy', () => {
|
prevFocusDestroyId = prevFocus.connect('destroy', () => {
|
||||||
let index = _findModal(actor);
|
const index = modalActorFocusStack.findIndex(
|
||||||
|
record => record.prevFocus === prevFocus);
|
||||||
|
|
||||||
if (index >= 0)
|
if (index >= 0)
|
||||||
modalActorFocusStack[index].prevFocus = null;
|
modalActorFocusStack[index].prevFocus = null;
|
||||||
});
|
});
|
||||||
@ -795,7 +817,7 @@ function showRestartMessage(message) {
|
|||||||
|
|
||||||
var AnimationsSettings = class {
|
var AnimationsSettings = class {
|
||||||
constructor() {
|
constructor() {
|
||||||
let backend = Meta.get_backend();
|
let backend = global.backend;
|
||||||
if (!backend.is_rendering_hardware_accelerated()) {
|
if (!backend.is_rendering_hardware_accelerated()) {
|
||||||
St.Settings.get().inhibit_animations();
|
St.Settings.get().inhibit_animations();
|
||||||
return;
|
return;
|
||||||
|
@ -136,29 +136,22 @@ var FocusGrabber = class FocusGrabber {
|
|||||||
var NotificationPolicy = GObject.registerClass({
|
var NotificationPolicy = GObject.registerClass({
|
||||||
Properties: {
|
Properties: {
|
||||||
'enable': GObject.ParamSpec.boolean(
|
'enable': GObject.ParamSpec.boolean(
|
||||||
'enable', 'enable', 'enable',
|
'enable', 'enable', 'enable', GObject.ParamFlags.READABLE, true),
|
||||||
GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY,
|
|
||||||
true),
|
|
||||||
'enable-sound': GObject.ParamSpec.boolean(
|
'enable-sound': GObject.ParamSpec.boolean(
|
||||||
'enable-sound', 'enable-sound', 'enable-sound',
|
'enable-sound', 'enable-sound', 'enable-sound',
|
||||||
GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY,
|
GObject.ParamFlags.READABLE, true),
|
||||||
true),
|
|
||||||
'show-banners': GObject.ParamSpec.boolean(
|
'show-banners': GObject.ParamSpec.boolean(
|
||||||
'show-banners', 'show-banners', 'show-banners',
|
'show-banners', 'show-banners', 'show-banners',
|
||||||
GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY,
|
GObject.ParamFlags.READABLE, true),
|
||||||
true),
|
|
||||||
'force-expanded': GObject.ParamSpec.boolean(
|
'force-expanded': GObject.ParamSpec.boolean(
|
||||||
'force-expanded', 'force-expanded', 'force-expanded',
|
'force-expanded', 'force-expanded', 'force-expanded',
|
||||||
GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY,
|
GObject.ParamFlags.READABLE, false),
|
||||||
false),
|
|
||||||
'show-in-lock-screen': GObject.ParamSpec.boolean(
|
'show-in-lock-screen': GObject.ParamSpec.boolean(
|
||||||
'show-in-lock-screen', 'show-in-lock-screen', 'show-in-lock-screen',
|
'show-in-lock-screen', 'show-in-lock-screen', 'show-in-lock-screen',
|
||||||
GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY,
|
GObject.ParamFlags.READABLE, false),
|
||||||
false),
|
|
||||||
'details-in-lock-screen': GObject.ParamSpec.boolean(
|
'details-in-lock-screen': GObject.ParamSpec.boolean(
|
||||||
'details-in-lock-screen', 'details-in-lock-screen', 'details-in-lock-screen',
|
'details-in-lock-screen', 'details-in-lock-screen', 'details-in-lock-screen',
|
||||||
GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY,
|
GObject.ParamFlags.READABLE, false),
|
||||||
false),
|
|
||||||
},
|
},
|
||||||
}, class NotificationPolicy extends GObject.Object {
|
}, class NotificationPolicy extends GObject.Object {
|
||||||
// Do nothing for the default policy. These methods are only useful for the
|
// Do nothing for the default policy. These methods are only useful for the
|
||||||
@ -170,23 +163,23 @@ var NotificationPolicy = GObject.registerClass({
|
|||||||
}
|
}
|
||||||
|
|
||||||
get enableSound() {
|
get enableSound() {
|
||||||
return this.enable_sound;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
get showBanners() {
|
get showBanners() {
|
||||||
return this.show_banners;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
get forceExpanded() {
|
get forceExpanded() {
|
||||||
return this.force_expanded;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
get showInLockScreen() {
|
get showInLockScreen() {
|
||||||
return this.show_in_lock_screen;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
get detailsInLockScreen() {
|
get detailsInLockScreen() {
|
||||||
return this.details_in_lock_screen;
|
return false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -1167,8 +1160,7 @@ var MessageTray = GObject.registerClass({
|
|||||||
this._onNotificationDestroy.bind(this));
|
this._onNotificationDestroy.bind(this));
|
||||||
this._notificationQueue.push(notification);
|
this._notificationQueue.push(notification);
|
||||||
this._notificationQueue.sort(
|
this._notificationQueue.sort(
|
||||||
(n1, n2) => n2.urgency - n1.urgency
|
(n1, n2) => n2.urgency - n1.urgency);
|
||||||
);
|
|
||||||
this.emit('queue-changed');
|
this.emit('queue-changed');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -400,8 +400,7 @@ var Overview = class {
|
|||||||
|
|
||||||
_getDesktopClone() {
|
_getDesktopClone() {
|
||||||
let windows = global.get_window_actors().filter(
|
let windows = global.get_window_actors().filter(
|
||||||
w => w.meta_window.get_window_type() == Meta.WindowType.DESKTOP
|
w => w.meta_window.get_window_type() === Meta.WindowType.DESKTOP);
|
||||||
);
|
|
||||||
if (windows.length == 0)
|
if (windows.length == 0)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
|
@ -473,6 +473,7 @@ class ControlsManager extends St.Widget {
|
|||||||
|
|
||||||
// A workspace might have been inserted or removed before the active
|
// A workspace might have been inserted or removed before the active
|
||||||
// one, causing the adjustment to go out of sync, so update the value
|
// one, causing the adjustment to go out of sync, so update the value
|
||||||
|
this._workspaceAdjustment.remove_transition('value');
|
||||||
this._workspaceAdjustment.value = activeIndex;
|
this._workspaceAdjustment.value = activeIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,18 +90,16 @@ class AppMenu extends PopupMenu.PopupMenu {
|
|||||||
|
|
||||||
this.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
|
this.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
|
||||||
|
|
||||||
this._detailsItem = this.addAction(_("Show Details"), () => {
|
this._detailsItem = this.addAction(_('Show Details'), async () => {
|
||||||
let id = this._app.get_id();
|
let id = this._app.get_id();
|
||||||
let args = GLib.Variant.new('(ss)', [id, '']);
|
let args = GLib.Variant.new('(ss)', [id, '']);
|
||||||
Gio.DBus.get(Gio.BusType.SESSION, null, (o, res) => {
|
const bus = await Gio.DBus.get(Gio.BusType.SESSION, null);
|
||||||
let bus = Gio.DBus.get_finish(res);
|
bus.call(
|
||||||
bus.call('org.gnome.Software',
|
'org.gnome.Software',
|
||||||
'/org/gnome/Software',
|
'/org/gnome/Software',
|
||||||
'org.gtk.Actions', 'Activate',
|
'org.gtk.Actions', 'Activate',
|
||||||
GLib.Variant.new('(sava{sv})',
|
new GLib.Variant('(sava{sv})', ['details', [args], null]),
|
||||||
['details', [args], null]),
|
null, 0, -1, null);
|
||||||
null, 0, -1, null, null);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
this.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
|
this.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
|
||||||
@ -283,7 +281,7 @@ var AppMenuButton = GObject.registerClass({
|
|||||||
this.remove_all_transitions();
|
this.remove_all_transitions();
|
||||||
this.ease({
|
this.ease({
|
||||||
opacity: 0,
|
opacity: 0,
|
||||||
mode: Clutter.Animation.EASE_OUT_QUAD,
|
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
|
||||||
duration: Overview.ANIMATION_TIME,
|
duration: Overview.ANIMATION_TIME,
|
||||||
onComplete: () => this.hide(),
|
onComplete: () => this.hide(),
|
||||||
});
|
});
|
||||||
@ -1155,10 +1153,9 @@ class Panel extends St.Widget {
|
|||||||
|
|
||||||
_getDraggableWindowForPosition(stageX) {
|
_getDraggableWindowForPosition(stageX) {
|
||||||
let workspaceManager = global.workspace_manager;
|
let workspaceManager = global.workspace_manager;
|
||||||
let workspace = workspaceManager.get_active_workspace();
|
const windows = workspaceManager.get_active_workspace().list_windows();
|
||||||
let allWindowsByStacking = global.display.sort_windows_by_stacking(
|
const allWindowsByStacking =
|
||||||
workspace.list_windows()
|
global.display.sort_windows_by_stacking(windows).reverse();
|
||||||
).reverse();
|
|
||||||
|
|
||||||
return allWindowsByStacking.find(metaWindow => {
|
return allWindowsByStacking.find(metaWindow => {
|
||||||
let rect = metaWindow.get_frame_rect();
|
let rect = metaWindow.get_frame_rect();
|
||||||
|
@ -204,7 +204,7 @@ var RemoteSearchProvider = class {
|
|||||||
g_interface_info: proxyInfo,
|
g_interface_info: proxyInfo,
|
||||||
g_interface_name: proxyInfo.name,
|
g_interface_name: proxyInfo.name,
|
||||||
gFlags });
|
gFlags });
|
||||||
this.proxy.init_async(GLib.PRIORITY_DEFAULT, null, null);
|
this.proxy.init_async(GLib.PRIORITY_DEFAULT, null);
|
||||||
|
|
||||||
this.appInfo = appInfo;
|
this.appInfo = appInfo;
|
||||||
this.id = appInfo.get_id();
|
this.id = appInfo.get_id();
|
||||||
|
@ -198,7 +198,7 @@ var ScreenShield = class {
|
|||||||
let lockEnabled = this._settings.get_boolean(LOCK_ENABLED_KEY);
|
let lockEnabled = this._settings.get_boolean(LOCK_ENABLED_KEY);
|
||||||
let lockLocked = this._lockSettings.get_boolean(DISABLE_LOCK_KEY);
|
let lockLocked = this._lockSettings.get_boolean(DISABLE_LOCK_KEY);
|
||||||
let inhibit = this._loginSession && this._loginSession.Active &&
|
let inhibit = this._loginSession && this._loginSession.Active &&
|
||||||
!this._isActive && lockEnabled && !lockLocked;
|
!this._isActive && lockEnabled && !lockLocked && Main.sessionMode.unlockDialog;
|
||||||
if (inhibit) {
|
if (inhibit) {
|
||||||
this._loginManager.inhibit(_("GNOME needs to lock the screen"),
|
this._loginManager.inhibit(_("GNOME needs to lock the screen"),
|
||||||
inhibitor => {
|
inhibitor => {
|
||||||
@ -345,7 +345,7 @@ var ScreenShield = class {
|
|||||||
this._lockDialogGroup.remove_all_transitions();
|
this._lockDialogGroup.remove_all_transitions();
|
||||||
|
|
||||||
if (animate) {
|
if (animate) {
|
||||||
// Tween the lock screen out of screen
|
// Animate the lock screen out of screen
|
||||||
// if velocity is not specified (i.e. we come here from pressing ESC),
|
// if velocity is not specified (i.e. we come here from pressing ESC),
|
||||||
// use the same speed regardless of original position
|
// use the same speed regardless of original position
|
||||||
// if velocity is specified, it's in pixels per milliseconds
|
// if velocity is specified, it's in pixels per milliseconds
|
||||||
@ -498,6 +498,8 @@ var ScreenShield = class {
|
|||||||
if (Main.sessionMode.currentMode == 'unlock-dialog')
|
if (Main.sessionMode.currentMode == 'unlock-dialog')
|
||||||
Main.sessionMode.popMode('unlock-dialog');
|
Main.sessionMode.popMode('unlock-dialog');
|
||||||
|
|
||||||
|
this.emit('wake-up-screen');
|
||||||
|
|
||||||
if (this._isGreeter) {
|
if (this._isGreeter) {
|
||||||
// We don't want to "deactivate" any more than
|
// We don't want to "deactivate" any more than
|
||||||
// this. In particular, we don't want to drop
|
// this. In particular, we don't want to drop
|
||||||
@ -519,6 +521,9 @@ var ScreenShield = class {
|
|||||||
this._isModal = false;
|
this._isModal = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this._longLightbox.lightOff();
|
||||||
|
this._shortLightbox.lightOff();
|
||||||
|
|
||||||
this._lockDialogGroup.ease({
|
this._lockDialogGroup.ease({
|
||||||
translation_y: -global.screen_height,
|
translation_y: -global.screen_height,
|
||||||
duration: Overview.ANIMATION_TIME,
|
duration: Overview.ANIMATION_TIME,
|
||||||
@ -533,8 +538,6 @@ var ScreenShield = class {
|
|||||||
this._dialog = null;
|
this._dialog = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
this._longLightbox.lightOff();
|
|
||||||
this._shortLightbox.lightOff();
|
|
||||||
this.actor.hide();
|
this.actor.hide();
|
||||||
|
|
||||||
if (this._becameActiveId != 0) {
|
if (this._becameActiveId != 0) {
|
||||||
@ -558,7 +561,8 @@ var ScreenShield = class {
|
|||||||
if (this._activationTime == 0)
|
if (this._activationTime == 0)
|
||||||
this._activationTime = GLib.get_monotonic_time();
|
this._activationTime = GLib.get_monotonic_time();
|
||||||
|
|
||||||
this._ensureUnlockDialog(true);
|
if (!this._ensureUnlockDialog(true))
|
||||||
|
return;
|
||||||
|
|
||||||
this.actor.show();
|
this.actor.show();
|
||||||
|
|
||||||
|
@ -7,6 +7,13 @@ const GrabHelper = imports.ui.grabHelper;
|
|||||||
const Lightbox = imports.ui.lightbox;
|
const Lightbox = imports.ui.lightbox;
|
||||||
const Main = imports.ui.main;
|
const Main = imports.ui.main;
|
||||||
|
|
||||||
|
Gio._promisify(Shell.Screenshot.prototype, 'pick_color', 'pick_color_finish');
|
||||||
|
Gio._promisify(Shell.Screenshot.prototype, 'screenshot', 'screenshot_finish');
|
||||||
|
Gio._promisify(Shell.Screenshot.prototype,
|
||||||
|
'screenshot_window', 'screenshot_window_finish');
|
||||||
|
Gio._promisify(Shell.Screenshot.prototype,
|
||||||
|
'screenshot_area', 'screenshot_area_finish');
|
||||||
|
|
||||||
const { loadInterfaceXML } = imports.misc.fileUtils;
|
const { loadInterfaceXML } = imports.misc.fileUtils;
|
||||||
|
|
||||||
const ScreenshotIface = loadInterfaceXML('org.gnome.Shell.Screenshot');
|
const ScreenshotIface = loadInterfaceXML('org.gnome.Shell.Screenshot');
|
||||||
@ -156,7 +163,7 @@ var ScreenshotService = class {
|
|||||||
return [x, y, width, height];
|
return [x, y, width, height];
|
||||||
}
|
}
|
||||||
|
|
||||||
ScreenshotAreaAsync(params, invocation) {
|
async ScreenshotAreaAsync(params, invocation) {
|
||||||
let [x, y, width, height, flash, filename] = params;
|
let [x, y, width, height, flash, filename] = params;
|
||||||
[x, y, width, height] = this._scaleArea(x, y, width, height);
|
[x, y, width, height] = this._scaleArea(x, y, width, height);
|
||||||
if (!this._checkArea(x, y, width, height)) {
|
if (!this._checkArea(x, y, width, height)) {
|
||||||
@ -173,21 +180,17 @@ var ScreenshotService = class {
|
|||||||
if (!stream)
|
if (!stream)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
screenshot.screenshot_area(x, y, width, height, stream,
|
try {
|
||||||
(o, res) => {
|
let [area] =
|
||||||
try {
|
await screenshot.screenshot_area(x, y, width, height, stream);
|
||||||
let [success_, area] =
|
this._onScreenshotComplete(area, stream, file, flash, invocation);
|
||||||
screenshot.screenshot_area_finish(res);
|
} catch (e) {
|
||||||
this._onScreenshotComplete(
|
this._removeShooterForSender(invocation.get_sender());
|
||||||
area, stream, file, flash, invocation);
|
invocation.return_value(new GLib.Variant('(bs)', [false, '']));
|
||||||
} catch (e) {
|
}
|
||||||
this._removeShooterForSender(invocation.get_sender());
|
|
||||||
invocation.return_value(new GLib.Variant('(bs)', [false, '']));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ScreenshotWindowAsync(params, invocation) {
|
async ScreenshotWindowAsync(params, invocation) {
|
||||||
let [includeFrame, includeCursor, flash, filename] = params;
|
let [includeFrame, includeCursor, flash, filename] = params;
|
||||||
let screenshot = this._createScreenshot(invocation);
|
let screenshot = this._createScreenshot(invocation);
|
||||||
if (!screenshot)
|
if (!screenshot)
|
||||||
@ -197,21 +200,17 @@ var ScreenshotService = class {
|
|||||||
if (!stream)
|
if (!stream)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
screenshot.screenshot_window(includeFrame, includeCursor, stream,
|
try {
|
||||||
(o, res) => {
|
let [area] =
|
||||||
try {
|
await screenshot.screenshot_window(includeFrame, includeCursor, stream);
|
||||||
let [success_, area] =
|
this._onScreenshotComplete(area, stream, file, flash, invocation);
|
||||||
screenshot.screenshot_window_finish(res);
|
} catch (e) {
|
||||||
this._onScreenshotComplete(
|
this._removeShooterForSender(invocation.get_sender());
|
||||||
area, stream, file, flash, invocation);
|
invocation.return_value(new GLib.Variant('(bs)', [false, '']));
|
||||||
} catch (e) {
|
}
|
||||||
this._removeShooterForSender(invocation.get_sender());
|
|
||||||
invocation.return_value(new GLib.Variant('(bs)', [false, '']));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ScreenshotAsync(params, invocation) {
|
async ScreenshotAsync(params, invocation) {
|
||||||
let [includeCursor, flash, filename] = params;
|
let [includeCursor, flash, filename] = params;
|
||||||
let screenshot = this._createScreenshot(invocation);
|
let screenshot = this._createScreenshot(invocation);
|
||||||
if (!screenshot)
|
if (!screenshot)
|
||||||
@ -221,18 +220,13 @@ var ScreenshotService = class {
|
|||||||
if (!stream)
|
if (!stream)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
screenshot.screenshot(includeCursor, stream,
|
try {
|
||||||
(o, res) => {
|
let [area] = await screenshot.screenshot(includeCursor, stream);
|
||||||
try {
|
this._onScreenshotComplete(area, stream, file, flash, invocation);
|
||||||
let [success_, area] =
|
} catch (e) {
|
||||||
screenshot.screenshot_finish(res);
|
this._removeShooterForSender(invocation.get_sender());
|
||||||
this._onScreenshotComplete(
|
invocation.return_value(new GLib.Variant('(bs)', [false, '']));
|
||||||
area, stream, file, flash, invocation);
|
}
|
||||||
} catch (e) {
|
|
||||||
this._removeShooterForSender(invocation.get_sender());
|
|
||||||
invocation.return_value(new GLib.Variant('(bs)', [false, '']));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async SelectAreaAsync(params, invocation) {
|
async SelectAreaAsync(params, invocation) {
|
||||||
@ -273,19 +267,17 @@ var ScreenshotService = class {
|
|||||||
if (!screenshot)
|
if (!screenshot)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
screenshot.pick_color(coords.x, coords.y, (_o, res) => {
|
const [color] = await screenshot.pick_color(coords.x, coords.y);
|
||||||
let [success_, color] = screenshot.pick_color_finish(res);
|
const { red, green, blue } = color;
|
||||||
let { red, green, blue } = color;
|
const retval = GLib.Variant.new('(a{sv})', [{
|
||||||
let retval = GLib.Variant.new('(a{sv})', [{
|
color: GLib.Variant.new('(ddd)', [
|
||||||
color: GLib.Variant.new('(ddd)', [
|
red / 255.0,
|
||||||
red / 255.0,
|
green / 255.0,
|
||||||
green / 255.0,
|
blue / 255.0,
|
||||||
blue / 255.0,
|
]),
|
||||||
]),
|
}]);
|
||||||
}]);
|
this._removeShooterForSender(invocation.get_sender());
|
||||||
this._removeShooterForSender(invocation.get_sender());
|
invocation.return_value(retval);
|
||||||
invocation.return_value(retval);
|
|
||||||
});
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
invocation.return_error_literal(
|
invocation.return_error_literal(
|
||||||
Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED,
|
Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED,
|
||||||
|
@ -6,6 +6,7 @@ const { Clutter, Gio, GLib, GObject, Meta, Shell, St } = imports.gi;
|
|||||||
const AppDisplay = imports.ui.appDisplay;
|
const AppDisplay = imports.ui.appDisplay;
|
||||||
const IconGrid = imports.ui.iconGrid;
|
const IconGrid = imports.ui.iconGrid;
|
||||||
const Main = imports.ui.main;
|
const Main = imports.ui.main;
|
||||||
|
const ParentalControlsManager = imports.misc.parentalControlsManager;
|
||||||
const RemoteSearch = imports.ui.remoteSearch;
|
const RemoteSearch = imports.ui.remoteSearch;
|
||||||
const Util = imports.misc.util;
|
const Util = imports.misc.util;
|
||||||
|
|
||||||
@ -219,8 +220,7 @@ var SearchResultsBase = GObject.registerClass({
|
|||||||
|
|
||||||
_ensureResultActors(results, callback) {
|
_ensureResultActors(results, callback) {
|
||||||
let metasNeeded = results.filter(
|
let metasNeeded = results.filter(
|
||||||
resultId => this._resultDisplays[resultId] === undefined
|
resultId => this._resultDisplays[resultId] === undefined);
|
||||||
);
|
|
||||||
|
|
||||||
if (metasNeeded.length === 0) {
|
if (metasNeeded.length === 0) {
|
||||||
callback(true);
|
callback(true);
|
||||||
@ -431,6 +431,9 @@ var SearchResultsView = GObject.registerClass({
|
|||||||
_init() {
|
_init() {
|
||||||
super._init({ name: 'searchResults', vertical: true });
|
super._init({ name: 'searchResults', vertical: true });
|
||||||
|
|
||||||
|
this._parentalControlsManager = ParentalControlsManager.getDefault();
|
||||||
|
this._parentalControlsManager.connect('app-filter-changed', this._reloadRemoteProviders.bind(this));
|
||||||
|
|
||||||
this._content = new MaxWidthBox({
|
this._content = new MaxWidthBox({
|
||||||
name: 'searchResultsContent',
|
name: 'searchResultsContent',
|
||||||
vertical: true,
|
vertical: true,
|
||||||
@ -505,6 +508,11 @@ var SearchResultsView = GObject.registerClass({
|
|||||||
|
|
||||||
_registerProvider(provider) {
|
_registerProvider(provider) {
|
||||||
provider.searchInProgress = false;
|
provider.searchInProgress = false;
|
||||||
|
|
||||||
|
// Filter out unwanted providers.
|
||||||
|
if (provider.appInfo && !this._parentalControlsManager.shouldShowApp(provider.appInfo))
|
||||||
|
return;
|
||||||
|
|
||||||
this._providers.push(provider);
|
this._providers.push(provider);
|
||||||
this._ensureProviderDisplay(provider);
|
this._ensureProviderDisplay(provider);
|
||||||
}
|
}
|
||||||
|
@ -316,17 +316,7 @@ var GnomeShellExtensions = class {
|
|||||||
}
|
}
|
||||||
|
|
||||||
OpenExtensionPrefs(uuid, parentWindow, options) {
|
OpenExtensionPrefs(uuid, parentWindow, options) {
|
||||||
Gio.DBus.session.call(
|
Main.extensionManager.openExtensionPrefs(uuid, parentWindow, options);
|
||||||
'org.gnome.Shell.Extensions',
|
|
||||||
'/org/gnome/Shell/Extensions',
|
|
||||||
'org.gnome.Shell.Extensions',
|
|
||||||
'OpenExtensionPrefs',
|
|
||||||
new GLib.Variant('(ssa{sv})', [uuid, parentWindow, options]),
|
|
||||||
null,
|
|
||||||
Gio.DBusCallFlags.NONE,
|
|
||||||
-1,
|
|
||||||
null,
|
|
||||||
(conn, res) => conn.call_finish(res));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ReloadExtensionAsync(params, invocation) {
|
ReloadExtensionAsync(params, invocation) {
|
||||||
|
@ -295,8 +295,8 @@ var ShellMountPasswordDialog = GObject.registerClass({
|
|||||||
this._keyfilesLabel = new St.Label({ visible: false });
|
this._keyfilesLabel = new St.Label({ visible: false });
|
||||||
this._keyfilesLabel.clutter_text.set_markup(
|
this._keyfilesLabel.clutter_text.set_markup(
|
||||||
/* Translators: %s is the Disks application */
|
/* Translators: %s is the Disks application */
|
||||||
_("To unlock a volume that uses keyfiles, use the <i>%s</i> utility instead.").format(disksApp.get_name())
|
_('To unlock a volume that uses keyfiles, use the <i>%s</i> utility instead.')
|
||||||
);
|
.format(disksApp.get_name()));
|
||||||
this._keyfilesLabel.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
|
this._keyfilesLabel.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
|
||||||
this._keyfilesLabel.clutter_text.line_wrap = true;
|
this._keyfilesLabel.clutter_text.line_wrap = true;
|
||||||
content.add_child(this._keyfilesLabel);
|
content.add_child(this._keyfilesLabel);
|
||||||
@ -464,8 +464,7 @@ var ShellMountPasswordDialog = GObject.registerClass({
|
|||||||
/* Translators: %s is the Disks application */
|
/* Translators: %s is the Disks application */
|
||||||
_("Unable to start %s").format(app.get_name()),
|
_("Unable to start %s").format(app.get_name()),
|
||||||
/* Translators: %s is the Disks application */
|
/* Translators: %s is the Disks application */
|
||||||
_("Couldn’t find the %s application").format(app.get_name())
|
_('Couldn’t find the %s application').format(app.get_name()));
|
||||||
);
|
|
||||||
}
|
}
|
||||||
this._onCancelButton();
|
this._onCancelButton();
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
/* exported Indicator */
|
/* exported Indicator */
|
||||||
|
|
||||||
const { Gio, GnomeBluetooth, GObject } = imports.gi;
|
const { Gio, GLib, GnomeBluetooth, GObject } = imports.gi;
|
||||||
|
|
||||||
const Main = imports.ui.main;
|
const Main = imports.ui.main;
|
||||||
const PanelMenu = imports.ui.panelMenu;
|
const PanelMenu = imports.ui.panelMenu;
|
||||||
@ -35,7 +35,7 @@ class Indicator extends PanelMenu.SystemIndicator {
|
|||||||
|
|
||||||
this._sync();
|
this._sync();
|
||||||
});
|
});
|
||||||
this._proxy.connect('g-properties-changed', this._sync.bind(this));
|
this._proxy.connect('g-properties-changed', this._queueSync.bind(this));
|
||||||
|
|
||||||
this._item = new PopupMenu.PopupSubMenuMenuItem(_("Bluetooth"), true);
|
this._item = new PopupMenu.PopupSubMenuMenuItem(_("Bluetooth"), true);
|
||||||
this._item.icon.icon_name = 'bluetooth-active-symbolic';
|
this._item.icon.icon_name = 'bluetooth-active-symbolic';
|
||||||
@ -49,15 +49,27 @@ class Indicator extends PanelMenu.SystemIndicator {
|
|||||||
this._item.menu.addSettingsAction(_("Bluetooth Settings"), 'gnome-bluetooth-panel.desktop');
|
this._item.menu.addSettingsAction(_("Bluetooth Settings"), 'gnome-bluetooth-panel.desktop');
|
||||||
this.menu.addMenuItem(this._item);
|
this.menu.addMenuItem(this._item);
|
||||||
|
|
||||||
|
this._syncId = 0;
|
||||||
|
this._adapter = null;
|
||||||
|
|
||||||
this._client = new GnomeBluetooth.Client();
|
this._client = new GnomeBluetooth.Client();
|
||||||
this._model = this._client.get_model();
|
this._model = this._client.get_model();
|
||||||
this._model.connect('row-changed', this._sync.bind(this));
|
this._model.connect('row-deleted', this._queueSync.bind(this));
|
||||||
this._model.connect('row-deleted', this._sync.bind(this));
|
this._model.connect('row-changed', this._queueSync.bind(this));
|
||||||
this._model.connect('row-inserted', this._sync.bind(this));
|
this._model.connect('row-inserted', this._sync.bind(this));
|
||||||
Main.sessionMode.connect('updated', this._sync.bind(this));
|
Main.sessionMode.connect('updated', this._sync.bind(this));
|
||||||
this._sync();
|
this._sync();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_setHadSetupDevices(value) {
|
||||||
|
if (this._hadSetupDevices === value)
|
||||||
|
return;
|
||||||
|
|
||||||
|
this._hadSetupDevices = value;
|
||||||
|
global.settings.set_boolean(
|
||||||
|
HAD_BLUETOOTH_DEVICES_SETUP, this._hadSetupDevices);
|
||||||
|
}
|
||||||
|
|
||||||
_getDefaultAdapter() {
|
_getDefaultAdapter() {
|
||||||
let [ret, iter] = this._model.get_iter_first();
|
let [ret, iter] = this._model.get_iter_first();
|
||||||
while (ret) {
|
while (ret) {
|
||||||
@ -72,46 +84,53 @@ class Indicator extends PanelMenu.SystemIndicator {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// nDevices is the number of devices setup for the current default
|
_getDeviceInfos(adapter) {
|
||||||
// adapter if one exists and is powered. If unpowered or unavailable,
|
|
||||||
// nDevice is "1" if it had setup devices associated to it the last
|
|
||||||
// time it was seen, and "-1" if not.
|
|
||||||
//
|
|
||||||
// nConnectedDevices is the number of devices connected to the default
|
|
||||||
// adapter if one exists and is powered, or -1 if it's not available.
|
|
||||||
_getNDevices() {
|
|
||||||
let adapter = this._getDefaultAdapter();
|
|
||||||
if (!adapter)
|
if (!adapter)
|
||||||
return [this._hadSetupDevices ? 1 : -1, -1];
|
return [];
|
||||||
|
|
||||||
let nConnectedDevices = 0;
|
let deviceInfos = [];
|
||||||
let nDevices = 0;
|
|
||||||
let [ret, iter] = this._model.iter_children(adapter);
|
let [ret, iter] = this._model.iter_children(adapter);
|
||||||
while (ret) {
|
while (ret) {
|
||||||
let isConnected = this._model.get_value(iter,
|
const isPaired = this._model.get_value(iter,
|
||||||
GnomeBluetooth.Column.CONNECTED);
|
GnomeBluetooth.Column.PAIRED);
|
||||||
if (isConnected)
|
const isTrusted = this._model.get_value(iter,
|
||||||
nConnectedDevices++;
|
GnomeBluetooth.Column.TRUSTED);
|
||||||
|
|
||||||
|
if (isPaired || isTrusted) {
|
||||||
|
deviceInfos.push({
|
||||||
|
connected: this._model.get_value(iter,
|
||||||
|
GnomeBluetooth.Column.CONNECTED),
|
||||||
|
name: this._model.get_value(iter,
|
||||||
|
GnomeBluetooth.Column.ALIAS),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
let isPaired = this._model.get_value(iter,
|
|
||||||
GnomeBluetooth.Column.PAIRED);
|
|
||||||
let isTrusted = this._model.get_value(iter,
|
|
||||||
GnomeBluetooth.Column.TRUSTED);
|
|
||||||
if (isPaired || isTrusted)
|
|
||||||
nDevices++;
|
|
||||||
ret = this._model.iter_next(iter);
|
ret = this._model.iter_next(iter);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this._hadSetupDevices != (nDevices > 0)) {
|
return deviceInfos;
|
||||||
this._hadSetupDevices = !this._hadSetupDevices;
|
}
|
||||||
global.settings.set_boolean(HAD_BLUETOOTH_DEVICES_SETUP, this._hadSetupDevices);
|
|
||||||
}
|
|
||||||
|
|
||||||
return [nDevices, nConnectedDevices];
|
_queueSync() {
|
||||||
|
if (this._syncId)
|
||||||
|
return;
|
||||||
|
this._syncId = GLib.idle_add(GLib.PRIORITY_DEFAULT, () => {
|
||||||
|
this._syncId = 0;
|
||||||
|
this._sync();
|
||||||
|
return GLib.SOURCE_REMOVE;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
_sync() {
|
_sync() {
|
||||||
let [nDevices, nConnectedDevices] = this._getNDevices();
|
let adapter = this._getDefaultAdapter();
|
||||||
|
let devices = this._getDeviceInfos(adapter);
|
||||||
|
const connectedDevices = devices.filter(dev => dev.connected);
|
||||||
|
const nConnectedDevices = connectedDevices.length;
|
||||||
|
|
||||||
|
if (adapter && this._adapter)
|
||||||
|
this._setHadSetupDevices(devices.length > 0);
|
||||||
|
this._adapter = adapter;
|
||||||
|
|
||||||
let sensitive = !Main.sessionMode.isLocked && !Main.sessionMode.isGreeter;
|
let sensitive = !Main.sessionMode.isLocked && !Main.sessionMode.isGreeter;
|
||||||
|
|
||||||
this.menu.setSensitive(sensitive);
|
this.menu.setSensitive(sensitive);
|
||||||
@ -119,19 +138,21 @@ class Indicator extends PanelMenu.SystemIndicator {
|
|||||||
|
|
||||||
// Remember if there were setup devices and show the menu
|
// Remember if there were setup devices and show the menu
|
||||||
// if we've seen setup devices and we're not hard blocked
|
// if we've seen setup devices and we're not hard blocked
|
||||||
if (nDevices > 0)
|
if (this._hadSetupDevices)
|
||||||
this._item.visible = !this._proxy.BluetoothHardwareAirplaneMode;
|
this._item.visible = !this._proxy.BluetoothHardwareAirplaneMode;
|
||||||
else
|
else
|
||||||
this._item.visible = this._proxy.BluetoothHasAirplaneMode && !this._proxy.BluetoothAirplaneMode;
|
this._item.visible = this._proxy.BluetoothHasAirplaneMode && !this._proxy.BluetoothAirplaneMode;
|
||||||
|
|
||||||
if (nConnectedDevices > 0)
|
if (nConnectedDevices > 1)
|
||||||
/* Translators: this is the number of connected bluetooth devices */
|
/* Translators: this is the number of connected bluetooth devices */
|
||||||
this._item.label.text = ngettext("%d Connected", "%d Connected", nConnectedDevices).format(nConnectedDevices);
|
this._item.label.text = ngettext('%d Connected", "%d Connected', nConnectedDevices).format(nConnectedDevices);
|
||||||
else if (nConnectedDevices == -1)
|
else if (nConnectedDevices === 1)
|
||||||
this._item.label.text = _("Off");
|
this._item.label.text = connectedDevices[0].name;
|
||||||
|
else if (adapter === null)
|
||||||
|
this._item.label.text = _('Bluetooth Off');
|
||||||
else
|
else
|
||||||
this._item.label.text = _("On");
|
this._item.label.text = _('Bluetooth On');
|
||||||
|
|
||||||
this._toggleItem.label.text = this._proxy.BluetoothAirplaneMode ? _("Turn On") : _("Turn Off");
|
this._toggleItem.label.text = this._proxy.BluetoothAirplaneMode ? _('Turn On') : _('Turn Off');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -199,36 +199,36 @@ var InputSourceSystemSettings = class extends InputSourceSettings {
|
|||||||
this._reload.bind(this));
|
this._reload.bind(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
_reload() {
|
async _reload() {
|
||||||
Gio.DBus.system.call(this._BUS_NAME,
|
let props;
|
||||||
this._BUS_PATH,
|
try {
|
||||||
this._BUS_PROPS_IFACE,
|
const result = await Gio.DBus.system.call(
|
||||||
'GetAll',
|
this._BUS_NAME,
|
||||||
new GLib.Variant('(s)', [this._BUS_IFACE]),
|
this._BUS_PATH,
|
||||||
null, Gio.DBusCallFlags.NONE, -1, null,
|
this._BUS_PROPS_IFACE,
|
||||||
(conn, result) => {
|
'GetAll',
|
||||||
let props;
|
new GLib.Variant('(s)', [this._BUS_IFACE]),
|
||||||
try {
|
null, Gio.DBusCallFlags.NONE, -1, null);
|
||||||
props = conn.call_finish(result).deep_unpack()[0];
|
[props] = result.deep_unpack();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
log('Could not get properties from %s'.format(this._BUS_NAME));
|
log('Could not get properties from %s'.format(this._BUS_NAME));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let layouts = props['X11Layout'].unpack();
|
|
||||||
let variants = props['X11Variant'].unpack();
|
|
||||||
let options = props['X11Options'].unpack();
|
|
||||||
|
|
||||||
if (layouts != this._layouts ||
|
const layouts = props['X11Layout'].unpack();
|
||||||
variants != this._variants) {
|
const variants = props['X11Variant'].unpack();
|
||||||
this._layouts = layouts;
|
const options = props['X11Options'].unpack();
|
||||||
this._variants = variants;
|
|
||||||
this._emitInputSourcesChanged();
|
if (layouts !== this._layouts ||
|
||||||
}
|
variants !== this._variants) {
|
||||||
if (options != this._options) {
|
this._layouts = layouts;
|
||||||
this._options = options;
|
this._variants = variants;
|
||||||
this._emitKeyboardOptionsChanged();
|
this._emitInputSourcesChanged();
|
||||||
}
|
}
|
||||||
});
|
if (options !== this._options) {
|
||||||
|
this._options = options;
|
||||||
|
this._emitKeyboardOptionsChanged();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
get inputSources() {
|
get inputSources() {
|
||||||
|
@ -15,6 +15,10 @@ const Util = imports.misc.util;
|
|||||||
|
|
||||||
const { loadInterfaceXML } = imports.misc.fileUtils;
|
const { loadInterfaceXML } = imports.misc.fileUtils;
|
||||||
|
|
||||||
|
Gio._promisify(NM.Client, 'new_async', 'new_finish');
|
||||||
|
Gio._promisify(NM.Client.prototype,
|
||||||
|
'check_connectivity_async', 'check_connectivity_finish');
|
||||||
|
|
||||||
const NMConnectionCategory = {
|
const NMConnectionCategory = {
|
||||||
INVALID: 'invalid',
|
INVALID: 'invalid',
|
||||||
WIRED: 'wired',
|
WIRED: 'wired',
|
||||||
@ -712,8 +716,7 @@ class NMWirelessDialog extends ModalDialog.ModalDialog {
|
|||||||
|
|
||||||
let connections = client.get_connections();
|
let connections = client.get_connections();
|
||||||
this._connections = connections.filter(
|
this._connections = connections.filter(
|
||||||
connection => device.connection_valid(connection)
|
connection => device.connection_valid(connection));
|
||||||
);
|
|
||||||
|
|
||||||
this._apAddedId = device.connect('access-point-added', this._accessPointAdded.bind(this));
|
this._apAddedId = device.connect('access-point-added', this._accessPointAdded.bind(this));
|
||||||
this._apRemovedId = device.connect('access-point-removed', this._accessPointRemoved.bind(this));
|
this._apRemovedId = device.connect('access-point-removed', this._accessPointRemoved.bind(this));
|
||||||
@ -1627,11 +1630,11 @@ class Indicator extends PanelMenu.SystemIndicator {
|
|||||||
this._ctypes[NM.SETTING_GSM_SETTING_NAME] = NMConnectionCategory.WWAN;
|
this._ctypes[NM.SETTING_GSM_SETTING_NAME] = NMConnectionCategory.WWAN;
|
||||||
this._ctypes[NM.SETTING_VPN_SETTING_NAME] = NMConnectionCategory.VPN;
|
this._ctypes[NM.SETTING_VPN_SETTING_NAME] = NMConnectionCategory.VPN;
|
||||||
|
|
||||||
NM.Client.new_async(null, this._clientGot.bind(this));
|
this._getClient();
|
||||||
}
|
}
|
||||||
|
|
||||||
_clientGot(obj, result) {
|
async _getClient() {
|
||||||
this._client = NM.Client.new_finish(result);
|
this._client = await NM.Client.new_async(null);
|
||||||
|
|
||||||
this._activeConnections = [];
|
this._activeConnections = [];
|
||||||
this._connections = [];
|
this._connections = [];
|
||||||
@ -1859,8 +1862,7 @@ class Indicator extends PanelMenu.SystemIndicator {
|
|||||||
_syncVpnConnections() {
|
_syncVpnConnections() {
|
||||||
let activeConnections = this._client.get_active_connections() || [];
|
let activeConnections = this._client.get_active_connections() || [];
|
||||||
let vpnConnections = activeConnections.filter(
|
let vpnConnections = activeConnections.filter(
|
||||||
a => a instanceof NM.VpnConnection
|
a => a instanceof NM.VpnConnection);
|
||||||
);
|
|
||||||
vpnConnections.forEach(a => {
|
vpnConnections.forEach(a => {
|
||||||
ensureActiveConnectionProps(a);
|
ensureActiveConnectionProps(a);
|
||||||
});
|
});
|
||||||
@ -1982,7 +1984,7 @@ class Indicator extends PanelMenu.SystemIndicator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_portalHelperDone(proxy, emitter, parameters) {
|
async _portalHelperDone(proxy, emitter, parameters) {
|
||||||
let [path, result] = parameters;
|
let [path, result] = parameters;
|
||||||
|
|
||||||
if (result == PortalHelperResult.CANCELLED) {
|
if (result == PortalHelperResult.CANCELLED) {
|
||||||
@ -1993,13 +1995,11 @@ class Indicator extends PanelMenu.SystemIndicator {
|
|||||||
} else if (result == PortalHelperResult.COMPLETED) {
|
} else if (result == PortalHelperResult.COMPLETED) {
|
||||||
this._closeConnectivityCheck(path);
|
this._closeConnectivityCheck(path);
|
||||||
} else if (result == PortalHelperResult.RECHECK) {
|
} else if (result == PortalHelperResult.RECHECK) {
|
||||||
this._client.check_connectivity_async(null, (client, res) => {
|
try {
|
||||||
try {
|
const state = await this._client.check_connectivity_async(null);
|
||||||
let state = client.check_connectivity_finish(res);
|
if (state >= NM.ConnectivityState.FULL)
|
||||||
if (state >= NM.ConnectivityState.FULL)
|
this._closeConnectivityCheck(path);
|
||||||
this._closeConnectivityCheck(path);
|
} catch (e) { }
|
||||||
} catch (e) { }
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
log('Invalid result from portal helper: %s'.format(result));
|
log('Invalid result from portal helper: %s'.format(result));
|
||||||
}
|
}
|
||||||
|
@ -11,8 +11,7 @@ class RemoteAccessApplet extends PanelMenu.SystemIndicator {
|
|||||||
_init() {
|
_init() {
|
||||||
super._init();
|
super._init();
|
||||||
|
|
||||||
let backend = Meta.get_backend();
|
let controller = global.backend.get_remote_access_controller();
|
||||||
let controller = backend.get_remote_access_controller();
|
|
||||||
|
|
||||||
if (!controller)
|
if (!controller)
|
||||||
return;
|
return;
|
||||||
|
@ -82,8 +82,7 @@ class Indicator extends PanelMenu.SystemIndicator {
|
|||||||
});
|
});
|
||||||
|
|
||||||
let app = this._settingsApp = Shell.AppSystem.get_default().lookup_app(
|
let app = this._settingsApp = Shell.AppSystem.get_default().lookup_app(
|
||||||
'gnome-control-center.desktop'
|
'gnome-control-center.desktop');
|
||||||
);
|
|
||||||
if (app) {
|
if (app) {
|
||||||
let [icon, name] = [app.app_info.get_icon().names[0],
|
let [icon, name] = [app.app_info.get_icon().names[0],
|
||||||
app.get_name()];
|
app.get_name()];
|
||||||
|
@ -52,22 +52,21 @@ const BOLT_DBUS_PATH = '/org/freedesktop/bolt';
|
|||||||
var Client = class {
|
var Client = class {
|
||||||
constructor() {
|
constructor() {
|
||||||
this._proxy = null;
|
this._proxy = null;
|
||||||
let nodeInfo = Gio.DBusNodeInfo.new_for_xml(BoltClientInterface);
|
|
||||||
Gio.DBusProxy.new(Gio.DBus.system,
|
|
||||||
Gio.DBusProxyFlags.DO_NOT_AUTO_START,
|
|
||||||
nodeInfo.lookup_interface(BOLT_DBUS_CLIENT_IFACE),
|
|
||||||
BOLT_DBUS_NAME,
|
|
||||||
BOLT_DBUS_PATH,
|
|
||||||
BOLT_DBUS_CLIENT_IFACE,
|
|
||||||
null,
|
|
||||||
this._onProxyReady.bind(this));
|
|
||||||
|
|
||||||
this.probing = false;
|
this.probing = false;
|
||||||
|
this._getProxy();
|
||||||
}
|
}
|
||||||
|
|
||||||
_onProxyReady(o, res) {
|
async _getProxy() {
|
||||||
|
let nodeInfo = Gio.DBusNodeInfo.new_for_xml(BoltClientInterface);
|
||||||
try {
|
try {
|
||||||
this._proxy = Gio.DBusProxy.new_finish(res);
|
this._proxy = await Gio.DBusProxy.new(
|
||||||
|
Gio.DBus.system,
|
||||||
|
Gio.DBusProxyFlags.DO_NOT_AUTO_START,
|
||||||
|
nodeInfo.lookup_interface(BOLT_DBUS_CLIENT_IFACE),
|
||||||
|
BOLT_DBUS_NAME,
|
||||||
|
BOLT_DBUS_PATH,
|
||||||
|
BOLT_DBUS_CLIENT_IFACE,
|
||||||
|
null);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
log('error creating bolt proxy: %s'.format(e.message));
|
log('error creating bolt proxy: %s'.format(e.message));
|
||||||
return;
|
return;
|
||||||
@ -243,14 +242,15 @@ class Indicator extends PanelMenu.SystemIndicator {
|
|||||||
|
|
||||||
this._source = null;
|
this._source = null;
|
||||||
this._perm = null;
|
this._perm = null;
|
||||||
|
this._createPermission();
|
||||||
|
}
|
||||||
|
|
||||||
Polkit.Permission.new('org.freedesktop.bolt.enroll', null, null, (source, res) => {
|
async _createPermission() {
|
||||||
try {
|
try {
|
||||||
this._perm = Polkit.Permission.new_finish(res);
|
this._perm = await Polkit.Permission.new('org.freedesktop.bolt.enroll', null, null);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
log('Failed to get PolKit permission: %s'.format(e.toString()));
|
log('Failed to get PolKit permission: %s'.format(e.toString()));
|
||||||
}
|
}
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_onDestroy() {
|
_onDestroy() {
|
||||||
|
@ -317,7 +317,7 @@ var SwitcherPopup = GObject.registerClass({
|
|||||||
this.ease({
|
this.ease({
|
||||||
opacity: 0,
|
opacity: 0,
|
||||||
duration: POPUP_FADE_OUT_TIME,
|
duration: POPUP_FADE_OUT_TIME,
|
||||||
mode: Clutter.Animation.EASE_OUT_QUAD,
|
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
|
||||||
onComplete: () => this.destroy(),
|
onComplete: () => this.destroy(),
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
228
js/ui/tweener.js
228
js/ui/tweener.js
@ -1,228 +0,0 @@
|
|||||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
|
||||||
/* exported init, addCaller, addTween, getTweenCount, removeTweens,
|
|
||||||
pauseTweens, resumeTweens, registerSpecialProperty,
|
|
||||||
registerSpecialPropertyModifier, registerSpecialPropertySplitter */
|
|
||||||
|
|
||||||
const { Clutter, GLib, Shell } = imports.gi;
|
|
||||||
const Signals = imports.signals;
|
|
||||||
const Tweener = imports.tweener.tweener;
|
|
||||||
|
|
||||||
const { adjustAnimationTime } = imports.ui.environment;
|
|
||||||
|
|
||||||
// This is a wrapper around imports.tweener.tweener that adds a bit of
|
|
||||||
// Clutter integration. If the tweening target is a Clutter.Actor, then
|
|
||||||
// the tweenings will automatically be removed if the actor is destroyed.
|
|
||||||
|
|
||||||
// ActionScript Tweener methods that imports.tweener.tweener doesn't
|
|
||||||
// currently implement: getTweens, getVersion, registerTransition,
|
|
||||||
// setTimeScale, updateTime.
|
|
||||||
|
|
||||||
// imports.tweener.tweener methods that we don't re-export:
|
|
||||||
// pauseAllTweens, removeAllTweens, resumeAllTweens. (It would be hard
|
|
||||||
// to clean up properly after removeAllTweens, and also, any code that
|
|
||||||
// calls any of these is almost certainly wrong anyway, because they
|
|
||||||
// affect the entire application.)
|
|
||||||
|
|
||||||
// Called from Main.start
|
|
||||||
function init() {
|
|
||||||
Tweener.setFrameTicker(new ClutterFrameTicker());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function addCaller(target, tweeningParameters) {
|
|
||||||
_wrapTweening(target, tweeningParameters);
|
|
||||||
Tweener.addCaller(target, tweeningParameters);
|
|
||||||
}
|
|
||||||
|
|
||||||
function addTween(target, tweeningParameters) {
|
|
||||||
_wrapTweening(target, tweeningParameters);
|
|
||||||
Tweener.addTween(target, tweeningParameters);
|
|
||||||
}
|
|
||||||
|
|
||||||
function _wrapTweening(target, tweeningParameters) {
|
|
||||||
let state = _getTweenState(target);
|
|
||||||
|
|
||||||
if (!state.destroyedId) {
|
|
||||||
if (target instanceof Clutter.Actor) {
|
|
||||||
state.actor = target;
|
|
||||||
state.destroyedId = target.connect('destroy', _actorDestroyed);
|
|
||||||
} else if (target.actor && target.actor instanceof Clutter.Actor) {
|
|
||||||
state.actor = target.actor;
|
|
||||||
state.destroyedId = target.actor.connect('destroy', () => _actorDestroyed(target));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let { time, delay } = tweeningParameters;
|
|
||||||
if (!isNaN(time))
|
|
||||||
tweeningParameters['time'] = adjustAnimationTime(1000 * time) / 1000;
|
|
||||||
if (!isNaN(delay))
|
|
||||||
tweeningParameters['delay'] = adjustAnimationTime(1000 * delay) / 1000;
|
|
||||||
|
|
||||||
_addHandler(target, tweeningParameters, 'onComplete', _tweenCompleted);
|
|
||||||
}
|
|
||||||
|
|
||||||
function _getTweenState(target) {
|
|
||||||
// If we were paranoid, we could keep a plist mapping targets to
|
|
||||||
// states... but we're not that paranoid.
|
|
||||||
if (!target.__ShellTweenerState)
|
|
||||||
target.__ShellTweenerState = {};
|
|
||||||
return target.__ShellTweenerState;
|
|
||||||
}
|
|
||||||
|
|
||||||
function _resetTweenState(target) {
|
|
||||||
let state = target.__ShellTweenerState;
|
|
||||||
|
|
||||||
if (state) {
|
|
||||||
if (state.destroyedId)
|
|
||||||
state.actor.disconnect(state.destroyedId);
|
|
||||||
}
|
|
||||||
|
|
||||||
target.__ShellTweenerState = {};
|
|
||||||
}
|
|
||||||
|
|
||||||
function _addHandler(target, params, name, handler) {
|
|
||||||
if (params[name]) {
|
|
||||||
let oldHandler = params[name];
|
|
||||||
let oldScope = params[`${name}Scope`];
|
|
||||||
let oldParams = params[`${name}Params`];
|
|
||||||
let eventScope = oldScope ? oldScope : target;
|
|
||||||
|
|
||||||
params[name] = () => {
|
|
||||||
oldHandler.apply(eventScope, oldParams);
|
|
||||||
handler(target);
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
params[name] = () => handler(target);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function _actorDestroyed(target) {
|
|
||||||
_resetTweenState(target);
|
|
||||||
Tweener.removeTweens(target);
|
|
||||||
}
|
|
||||||
|
|
||||||
function _tweenCompleted(target) {
|
|
||||||
if (!isTweening(target))
|
|
||||||
_resetTweenState(target);
|
|
||||||
}
|
|
||||||
|
|
||||||
function getTweenCount(scope) {
|
|
||||||
return Tweener.getTweenCount(scope);
|
|
||||||
}
|
|
||||||
|
|
||||||
// imports.tweener.tweener doesn't provide this method (which exists
|
|
||||||
// in the ActionScript version) but it's easy to implement.
|
|
||||||
function isTweening(scope) {
|
|
||||||
return Tweener.getTweenCount(scope) != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
function removeTweens(...args) {
|
|
||||||
if (Tweener.removeTweens(args)) {
|
|
||||||
let [scope] = args;
|
|
||||||
// If we just removed the last active tween, clean up
|
|
||||||
if (Tweener.getTweenCount(scope) == 0)
|
|
||||||
_tweenCompleted(scope);
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function pauseTweens(...args) {
|
|
||||||
return Tweener.pauseTweens(...args);
|
|
||||||
}
|
|
||||||
|
|
||||||
function resumeTweens(...args) {
|
|
||||||
return Tweener.resumeTweens(...args);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function registerSpecialProperty(...args) {
|
|
||||||
Tweener.registerSpecialProperty(...args);
|
|
||||||
}
|
|
||||||
|
|
||||||
function registerSpecialPropertyModifier(name, modifyFunction, getFunction) {
|
|
||||||
Tweener.registerSpecialPropertyModifier(name, modifyFunction, getFunction);
|
|
||||||
}
|
|
||||||
|
|
||||||
function registerSpecialPropertySplitter(name, splitFunction, parameters) {
|
|
||||||
Tweener.registerSpecialPropertySplitter(name, splitFunction, parameters);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// The 'FrameTicker' object is an object used to feed new frames to
|
|
||||||
// Tweener so it can update values and redraw. The default frame
|
|
||||||
// ticker for Tweener just uses a simple timeout at a fixed frame rate
|
|
||||||
// and has no idea of "catching up" by dropping frames.
|
|
||||||
//
|
|
||||||
// We substitute it with custom frame ticker here that connects
|
|
||||||
// Tweener to a Clutter.TimeLine. Now, Clutter.Timeline itself isn't a
|
|
||||||
// whole lot more sophisticated than a simple timeout at a fixed frame
|
|
||||||
// rate, but at least it knows how to drop frames. (See
|
|
||||||
// HippoAnimationManager for a more sophisticated view of continuous
|
|
||||||
// time updates; even better is to pay attention to the vertical
|
|
||||||
// vblank and sync to that when possible.)
|
|
||||||
//
|
|
||||||
var ClutterFrameTicker = class {
|
|
||||||
constructor() {
|
|
||||||
// We don't have a finite duration; tweener will tell us to stop
|
|
||||||
// when we need to stop, so use 1000 seconds as "infinity", and
|
|
||||||
// set the timeline to loop. Doing this means we have to track
|
|
||||||
// time ourselves, since clutter timeline's time will cycle
|
|
||||||
// instead of strictly increase.
|
|
||||||
this._timeline = new Clutter.Timeline({ duration: 1000 * 1000 });
|
|
||||||
this._timeline.set_loop(true);
|
|
||||||
this._startTime = -1;
|
|
||||||
this._currentTime = -1;
|
|
||||||
|
|
||||||
this._timeline.connect('new-frame', () => {
|
|
||||||
this._onNewFrame();
|
|
||||||
});
|
|
||||||
|
|
||||||
let perfLog = Shell.PerfLog.get_default();
|
|
||||||
perfLog.define_event("tweener.framePrepareStart",
|
|
||||||
"Start of a new animation frame",
|
|
||||||
"");
|
|
||||||
perfLog.define_event("tweener.framePrepareDone",
|
|
||||||
"Finished preparing frame",
|
|
||||||
"");
|
|
||||||
}
|
|
||||||
|
|
||||||
get FRAME_RATE() {
|
|
||||||
return 60;
|
|
||||||
}
|
|
||||||
|
|
||||||
_onNewFrame() {
|
|
||||||
// If there is a lot of setup to start the animation, then
|
|
||||||
// first frame number we get from clutter might be a long ways
|
|
||||||
// into the animation (or the animation might even be done).
|
|
||||||
// That looks bad, so we always start at the first frame of the
|
|
||||||
// animation then only do frame dropping from there.
|
|
||||||
if (this._startTime < 0)
|
|
||||||
this._startTime = GLib.get_monotonic_time() / 1000.0;
|
|
||||||
|
|
||||||
// currentTime is in milliseconds
|
|
||||||
let perfLog = Shell.PerfLog.get_default();
|
|
||||||
this._currentTime = GLib.get_monotonic_time() / 1000.0 - this._startTime;
|
|
||||||
perfLog.event("tweener.framePrepareStart");
|
|
||||||
this.emit('prepare-frame');
|
|
||||||
perfLog.event("tweener.framePrepareDone");
|
|
||||||
}
|
|
||||||
|
|
||||||
getTime() {
|
|
||||||
return this._currentTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
start() {
|
|
||||||
this._timeline.start();
|
|
||||||
global.begin_work();
|
|
||||||
}
|
|
||||||
|
|
||||||
stop() {
|
|
||||||
this._timeline.stop();
|
|
||||||
this._startTime = -1;
|
|
||||||
this._currentTime = -1;
|
|
||||||
global.end_work();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
Signals.addSignalMethods(ClutterFrameTicker.prototype);
|
|
@ -605,7 +605,7 @@ var UnlockDialog = GObject.registerClass({
|
|||||||
this._showPrompt();
|
this._showPrompt();
|
||||||
|
|
||||||
if (GLib.unichar_isgraph(unichar))
|
if (GLib.unichar_isgraph(unichar))
|
||||||
this.addCharacter(unichar);
|
this._authPrompt.addCharacter(unichar);
|
||||||
|
|
||||||
return Clutter.EVENT_PROPAGATE;
|
return Clutter.EVENT_PROPAGATE;
|
||||||
}
|
}
|
||||||
@ -835,11 +835,6 @@ var UnlockDialog = GObject.registerClass({
|
|||||||
this._authPrompt.cancel();
|
this._authPrompt.cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
addCharacter(unichar) {
|
|
||||||
this._showPrompt();
|
|
||||||
this._authPrompt.addCharacter(unichar);
|
|
||||||
}
|
|
||||||
|
|
||||||
finish(onComplete) {
|
finish(onComplete) {
|
||||||
this._ensureAuthPrompt();
|
this._ensureAuthPrompt();
|
||||||
this._authPrompt.finish(onComplete);
|
this._authPrompt.finish(onComplete);
|
||||||
|
@ -82,8 +82,10 @@ class DisplayChangeDialog extends ModalDialog.ModalDialog {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_formatCountDown() {
|
_formatCountDown() {
|
||||||
let fmt = ngettext("Settings changes will revert in %d second",
|
const fmt = ngettext(
|
||||||
"Settings changes will revert in %d seconds");
|
'Settings changes will revert in %d second',
|
||||||
|
'Settings changes will revert in %d seconds',
|
||||||
|
this._countDown);
|
||||||
return fmt.format(this._countDown);
|
return fmt.format(this._countDown);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -404,7 +404,7 @@ var WindowClone = GObject.registerClass({
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return super.key_press_event(keyEvent);
|
return super.vfunc_key_press_event(keyEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
_onClicked() {
|
_onClicked() {
|
||||||
|
@ -819,8 +819,7 @@ class WorkspacesDisplay extends St.Widget {
|
|||||||
this._canScroll = true;
|
this._canScroll = true;
|
||||||
this._scrollTimeoutId = 0;
|
this._scrollTimeoutId = 0;
|
||||||
return GLib.SOURCE_REMOVE;
|
return GLib.SOURCE_REMOVE;
|
||||||
}
|
});
|
||||||
);
|
|
||||||
|
|
||||||
return Clutter.EVENT_STOP;
|
return Clutter.EVENT_STOP;
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
const { Clutter, Meta } = imports.gi;
|
const { Clutter } = imports.gi;
|
||||||
const Signals = imports.signals;
|
const Signals = imports.signals;
|
||||||
|
|
||||||
const DND = imports.ui.dnd;
|
const DND = imports.ui.dnd;
|
||||||
@ -17,7 +17,7 @@ var XdndHandler = class {
|
|||||||
Main.uiGroup.add_actor(this._dummy);
|
Main.uiGroup.add_actor(this._dummy);
|
||||||
this._dummy.hide();
|
this._dummy.hide();
|
||||||
|
|
||||||
var dnd = Meta.get_backend().get_dnd();
|
var dnd = global.backend.get_dnd();
|
||||||
dnd.connect('dnd-enter', this._onEnter.bind(this));
|
dnd.connect('dnd-enter', this._onEnter.bind(this));
|
||||||
dnd.connect('dnd-position-change', this._onPositionChanged.bind(this));
|
dnd.connect('dnd-position-change', this._onPositionChanged.bind(this));
|
||||||
dnd.connect('dnd-leave', this._onLeave.bind(this));
|
dnd.connect('dnd-leave', this._onLeave.bind(this));
|
||||||
|
@ -218,12 +218,12 @@ globals:
|
|||||||
ARGV: readonly
|
ARGV: readonly
|
||||||
Debugger: readonly
|
Debugger: readonly
|
||||||
GIRepositoryGType: readonly
|
GIRepositoryGType: readonly
|
||||||
|
globalThis: readonly
|
||||||
imports: readonly
|
imports: readonly
|
||||||
Intl: readonly
|
Intl: readonly
|
||||||
log: readonly
|
log: readonly
|
||||||
logError: readonly
|
logError: readonly
|
||||||
print: readonly
|
print: readonly
|
||||||
printerr: readonly
|
printerr: readonly
|
||||||
window: readonly
|
|
||||||
parserOptions:
|
parserOptions:
|
||||||
ecmaVersion: 2019
|
ecmaVersion: 2019
|
||||||
|
32
meson.build
32
meson.build
@ -1,6 +1,6 @@
|
|||||||
project('gnome-shell', 'c',
|
project('gnome-shell', 'c',
|
||||||
version: '3.36.0',
|
version: '3.37.1',
|
||||||
meson_version: '>= 0.47.0',
|
meson_version: '>= 0.53.0',
|
||||||
license: 'GPLv2+'
|
license: 'GPLv2+'
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -19,13 +19,13 @@ cogl_pango_pc = 'mutter-cogl-pango-' + mutter_api_version
|
|||||||
libmutter_pc = 'libmutter-' + mutter_api_version
|
libmutter_pc = 'libmutter-' + mutter_api_version
|
||||||
|
|
||||||
ecal_req = '>= 3.33.1'
|
ecal_req = '>= 3.33.1'
|
||||||
eds_req = '>= 3.17.2'
|
eds_req = '>= 3.33.1'
|
||||||
gcr_req = '>= 3.7.5'
|
gcr_req = '>= 3.7.5'
|
||||||
gio_req = '>= 2.56.0'
|
gio_req = '>= 2.56.0'
|
||||||
gi_req = '>= 1.49.1'
|
gi_req = '>= 1.49.1'
|
||||||
gjs_req = '>= 1.63.2'
|
gjs_req = '>= 1.65.1'
|
||||||
gtk_req = '>= 3.15.0'
|
gtk_req = '>= 3.15.0'
|
||||||
mutter_req = '>= 3.36.0'
|
mutter_req = '>= 3.37.1'
|
||||||
polkit_req = '>= 0.100'
|
polkit_req = '>= 0.100'
|
||||||
schemas_req = '>= 3.33.1'
|
schemas_req = '>= 3.33.1'
|
||||||
startup_req = '>= 0.11'
|
startup_req = '>= 0.11'
|
||||||
@ -63,16 +63,9 @@ portaldir = join_paths(datadir, 'xdg-desktop-portal', 'portals')
|
|||||||
schemadir = join_paths(datadir, 'glib-2.0', 'schemas')
|
schemadir = join_paths(datadir, 'glib-2.0', 'schemas')
|
||||||
servicedir = join_paths(datadir, 'dbus-1', 'services')
|
servicedir = join_paths(datadir, 'dbus-1', 'services')
|
||||||
|
|
||||||
# XXX: Once https://github.com/systemd/systemd/issues/9595 is fixed and we can
|
|
||||||
# depend on this version, replace with something like:
|
|
||||||
# systemduserunitdir = systemd_dep.get_pkgconfig_variable('systemduserunitdir',
|
|
||||||
# define_variable: ['prefix', prefix])
|
|
||||||
# and uncomment systemd_dep below
|
|
||||||
systemduserunitdir = join_paths(prefix, 'lib', 'systemd', 'user')
|
|
||||||
|
|
||||||
keybindings_dep = dependency('gnome-keybindings', required: false)
|
keybindings_dep = dependency('gnome-keybindings', required: false)
|
||||||
if keybindings_dep.found()
|
if keybindings_dep.found()
|
||||||
keysdir = keybindings_dep.get_pkgconfig_variable('keysdir')
|
keysdir = keybindings_dep.get_pkgconfig_variable('keysdir', define_variable: ['datadir', datadir])
|
||||||
else
|
else
|
||||||
keysdir = join_paths(datadir, 'gnome-control-center', 'keybindings')
|
keysdir = join_paths(datadir, 'gnome-control-center', 'keybindings')
|
||||||
endif
|
endif
|
||||||
@ -122,8 +115,9 @@ endif
|
|||||||
|
|
||||||
if get_option('systemd')
|
if get_option('systemd')
|
||||||
libsystemd_dep = dependency('libsystemd')
|
libsystemd_dep = dependency('libsystemd')
|
||||||
# XXX: see systemduserunitdir
|
systemd_dep = dependency('systemd')
|
||||||
# systemd_dep = dependency('systemd')
|
systemduserunitdir = systemd_dep.get_pkgconfig_variable('systemduserunitdir',
|
||||||
|
define_variable: ['prefix', prefix])
|
||||||
have_systemd = true
|
have_systemd = true
|
||||||
else
|
else
|
||||||
libsystemd_dep = []
|
libsystemd_dep = []
|
||||||
@ -321,8 +315,6 @@ if get_option('man')
|
|||||||
summary_dirs += { 'mandir': get_option('mandir') }
|
summary_dirs += { 'mandir': get_option('mandir') }
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if meson.version().version_compare('>= 0.53.0')
|
summary(summary_dirs, section: 'Directories')
|
||||||
summary(summary_dirs, section: 'Directories')
|
summary(summary_build, section: 'Build Configuration')
|
||||||
summary(summary_build, section: 'Build Configuration')
|
summary(summary_options, section: 'Build Options')
|
||||||
summary(summary_options, section: 'Build Options')
|
|
||||||
endif
|
|
||||||
|
@ -94,5 +94,7 @@ subprojects/extensions-tool/src/command-prefs.c
|
|||||||
subprojects/extensions-tool/src/command-reset.c
|
subprojects/extensions-tool/src/command-reset.c
|
||||||
subprojects/extensions-tool/src/command-uninstall.c
|
subprojects/extensions-tool/src/command-uninstall.c
|
||||||
subprojects/extensions-tool/src/main.c
|
subprojects/extensions-tool/src/main.c
|
||||||
|
subprojects/extensions-tool/src/templates/00-plain.desktop.in
|
||||||
|
subprojects/extensions-tool/src/templates/indicator.desktop.in
|
||||||
# Please do not remove this file from POTFILES.in. Run "git submodule init && git submodule update" to get it.
|
# Please do not remove this file from POTFILES.in. Run "git submodule init && git submodule update" to get it.
|
||||||
subprojects/gvc/gvc-mixer-control.c
|
subprojects/gvc/gvc-mixer-control.c
|
||||||
|
1
po/POTFILES.skip
Normal file
1
po/POTFILES.skip
Normal file
@ -0,0 +1 @@
|
|||||||
|
subprojects/extensions-tool/src/templates/indicator/extension.js
|
488
po/fi.po
488
po/fi.po
@ -25,8 +25,8 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: gnome-shell\n"
|
"Project-Id-Version: gnome-shell\n"
|
||||||
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gnome-shell/issues\n"
|
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gnome-shell/issues\n"
|
||||||
"POT-Creation-Date: 2020-02-21 09:52+0000\n"
|
"POT-Creation-Date: 2020-04-02 09:45+0000\n"
|
||||||
"PO-Revision-Date: 2020-02-22 17:34+0200\n"
|
"PO-Revision-Date: 2020-04-13 18:02+0300\n"
|
||||||
"Last-Translator: Jiri Grönroos <jiri.gronroos+l10n@iki.fi>\n"
|
"Last-Translator: Jiri Grönroos <jiri.gronroos+l10n@iki.fi>\n"
|
||||||
"Language-Team: suomi <lokalisointi-lista@googlegroups.com>\n"
|
"Language-Team: suomi <lokalisointi-lista@googlegroups.com>\n"
|
||||||
"Language: fi\n"
|
"Language: fi\n"
|
||||||
@ -63,15 +63,6 @@ msgstr "Näytä kaikki sovellukset"
|
|||||||
msgid "Open the application menu"
|
msgid "Open the application menu"
|
||||||
msgstr "Avaa sovellusvalikko"
|
msgstr "Avaa sovellusvalikko"
|
||||||
|
|
||||||
#: data/org.gnome.Extensions.desktop.in.in:4 js/extensionPrefs/main.js:218
|
|
||||||
#: js/extensionPrefs/ui/extensions-window.ui:61
|
|
||||||
msgid "Extensions"
|
|
||||||
msgstr "Laajennukset"
|
|
||||||
|
|
||||||
#: data/org.gnome.Extensions.desktop.in.in:7
|
|
||||||
msgid "Configure GNOME Shell Extensions"
|
|
||||||
msgstr "Hallitse Gnome Shell -laajennuksia"
|
|
||||||
|
|
||||||
#: data/org.gnome.Shell.desktop.in.in:4
|
#: data/org.gnome.Shell.desktop.in.in:4
|
||||||
msgid "GNOME Shell"
|
msgid "GNOME Shell"
|
||||||
msgstr "Gnome Shell"
|
msgstr "Gnome Shell"
|
||||||
@ -429,44 +420,12 @@ msgstr ""
|
|||||||
msgid "Network Login"
|
msgid "Network Login"
|
||||||
msgstr "Verkkokirjautuminen"
|
msgstr "Verkkokirjautuminen"
|
||||||
|
|
||||||
#: js/extensionPrefs/main.js:140
|
#: js/dbusServices/extensions/ui/extension-prefs-dialog.ui:36
|
||||||
#, javascript-format
|
#: subprojects/extensions-app/data/ui/extensions-window.ui:223
|
||||||
msgid "Remove “%s”?"
|
|
||||||
msgstr "Poista “%s”?"
|
|
||||||
|
|
||||||
#: js/extensionPrefs/main.js:141
|
|
||||||
msgid ""
|
|
||||||
"If you remove the extension, you need to return to download it if you want "
|
|
||||||
"to enable it again"
|
|
||||||
msgstr ""
|
|
||||||
"Ota huomioon jos poistat laajennuksen; sinun tulee palata ja ladata se "
|
|
||||||
"uudelleen, jos haluat sen uudelleen käyttöön"
|
|
||||||
|
|
||||||
#: js/extensionPrefs/main.js:144 js/ui/audioDeviceSelection.js:57
|
|
||||||
#: js/ui/components/networkAgent.js:107 js/ui/components/polkitAgent.js:139
|
|
||||||
#: js/ui/endSessionDialog.js:374 js/ui/extensionDownloader.js:165
|
|
||||||
#: js/ui/shellMountOperation.js:376 js/ui/shellMountOperation.js:386
|
|
||||||
#: js/ui/status/network.js:913
|
|
||||||
msgid "Cancel"
|
|
||||||
msgstr "Peru"
|
|
||||||
|
|
||||||
#: js/extensionPrefs/main.js:145
|
|
||||||
msgid "Remove"
|
|
||||||
msgstr "Poista"
|
|
||||||
|
|
||||||
#: js/extensionPrefs/main.js:217
|
|
||||||
msgid "translator-credits"
|
|
||||||
msgstr "Jiri Grönroos"
|
|
||||||
|
|
||||||
#: js/extensionPrefs/main.js:219
|
|
||||||
msgid "Manage your GNOME Extensions"
|
|
||||||
msgstr "Hallitse Gnome-laajennuksia"
|
|
||||||
|
|
||||||
#: js/extensionPrefs/main.js:261 js/extensionPrefs/ui/extensions-window.ui:222
|
|
||||||
msgid "Something’s gone wrong"
|
msgid "Something’s gone wrong"
|
||||||
msgstr "Jokin meni pieleen"
|
msgstr "Jokin meni pieleen"
|
||||||
|
|
||||||
#: js/extensionPrefs/main.js:268
|
#: js/dbusServices/extensions/ui/extension-prefs-dialog.ui:48
|
||||||
msgid ""
|
msgid ""
|
||||||
"We’re very sorry, but there’s been a problem: the settings for this "
|
"We’re very sorry, but there’s been a problem: the settings for this "
|
||||||
"extension can’t be displayed. We recommend that you report the issue to the "
|
"extension can’t be displayed. We recommend that you report the issue to the "
|
||||||
@ -475,111 +434,31 @@ msgstr ""
|
|||||||
"Ongelma havaittu: tämän laajennuksen asetuksia ei voi näyttää. Suosittelemme "
|
"Ongelma havaittu: tämän laajennuksen asetuksia ei voi näyttää. Suosittelemme "
|
||||||
"ilmoittamaan ongelmasta laajennuksen tekijälle."
|
"ilmoittamaan ongelmasta laajennuksen tekijälle."
|
||||||
|
|
||||||
#: js/extensionPrefs/main.js:275
|
#: js/dbusServices/extensions/ui/extension-prefs-dialog.ui:82
|
||||||
msgid "Technical Details"
|
msgid "Technical Details"
|
||||||
msgstr "Tekniset tiedot"
|
msgstr "Tekniset tiedot"
|
||||||
|
|
||||||
#: js/extensionPrefs/main.js:310
|
#: js/dbusServices/extensions/ui/extension-prefs-dialog.ui:165
|
||||||
msgid "Copy Error"
|
|
||||||
msgstr "Kopiointivirhe"
|
|
||||||
|
|
||||||
#: js/extensionPrefs/main.js:337
|
|
||||||
msgid "Homepage"
|
msgid "Homepage"
|
||||||
msgstr "Verkkosivu"
|
msgstr "Verkkosivu"
|
||||||
|
|
||||||
#: js/extensionPrefs/main.js:338
|
#: js/dbusServices/extensions/ui/extension-prefs-dialog.ui:166
|
||||||
msgid "Visit extension homepage"
|
msgid "Visit extension homepage"
|
||||||
msgstr "Käy laajennuksen verkkosivulla"
|
msgstr "Käy laajennuksen verkkosivulla"
|
||||||
|
|
||||||
#: js/extensionPrefs/main.js:449
|
#: js/gdm/authPrompt.js:135 js/ui/audioDeviceSelection.js:57
|
||||||
#, javascript-format
|
#: js/ui/components/networkAgent.js:109 js/ui/components/polkitAgent.js:139
|
||||||
msgid "%d extension will be updated on next login."
|
#: js/ui/endSessionDialog.js:374 js/ui/extensionDownloader.js:181
|
||||||
msgid_plural "%d extensions will be updated on next login."
|
#: js/ui/shellMountOperation.js:376 js/ui/shellMountOperation.js:386
|
||||||
msgstr[0] "%d laajennus päivitetään seuraavan kerran, kun kirjaudut sisään."
|
#: js/ui/status/network.js:913 subprojects/extensions-app/js/main.js:148
|
||||||
msgstr[1] "%d laajennusta päivitetään seuraavan kerran, kun kirjaudut sisään."
|
msgid "Cancel"
|
||||||
|
msgstr "Peru"
|
||||||
#: js/extensionPrefs/ui/extension-row.ui:100
|
|
||||||
#: subprojects/extensions-tool/src/command-create.c:211
|
|
||||||
#: subprojects/extensions-tool/src/main.c:173
|
|
||||||
msgid "Description"
|
|
||||||
msgstr "Kuvaus"
|
|
||||||
|
|
||||||
#: js/extensionPrefs/ui/extension-row.ui:123
|
|
||||||
#: subprojects/extensions-tool/src/main.c:185
|
|
||||||
msgid "Version"
|
|
||||||
msgstr "Versio"
|
|
||||||
|
|
||||||
#: js/extensionPrefs/ui/extension-row.ui:151
|
|
||||||
msgid "Author"
|
|
||||||
msgstr "Tekijä"
|
|
||||||
|
|
||||||
#: js/extensionPrefs/ui/extension-row.ui:175
|
|
||||||
msgid "Website"
|
|
||||||
msgstr "Verkkosivusto"
|
|
||||||
|
|
||||||
#: js/extensionPrefs/ui/extension-row.ui:192
|
|
||||||
msgid "Remove…"
|
|
||||||
msgstr "Poista…"
|
|
||||||
|
|
||||||
#: js/extensionPrefs/ui/extensions-window.ui:8
|
|
||||||
msgid "Help"
|
|
||||||
msgstr "Tuki"
|
|
||||||
|
|
||||||
#: js/extensionPrefs/ui/extensions-window.ui:12
|
|
||||||
msgid "About Extensions"
|
|
||||||
msgstr "Tietoja - Laajennukset"
|
|
||||||
|
|
||||||
#: js/extensionPrefs/ui/extensions-window.ui:27
|
|
||||||
msgid ""
|
|
||||||
"To find and add extensions, visit <a href=\"https://extensions.gnome.org"
|
|
||||||
"\">extensions.gnome.org</a>."
|
|
||||||
msgstr ""
|
|
||||||
"Etsi ja asenna laajennuksia osoitteessa <a href=\"https://extensions.gnome."
|
|
||||||
"org\">extensions.gnome.org</a>."
|
|
||||||
|
|
||||||
#: js/extensionPrefs/ui/extensions-window.ui:35
|
|
||||||
msgid "Warning"
|
|
||||||
msgstr "Varoitus"
|
|
||||||
|
|
||||||
#: js/extensionPrefs/ui/extensions-window.ui:46
|
|
||||||
msgid ""
|
|
||||||
"Extensions can cause system issues, including performance problems. If you "
|
|
||||||
"encounter problems with your system, it is recommended to disable all "
|
|
||||||
"extensions."
|
|
||||||
msgstr ""
|
|
||||||
"Laajennukset voivat aiheuttaa ongelmia järjestelmässä, myös suorituskykyyn. "
|
|
||||||
"Jos kohtaat ongelmia järjestelmän kanssa, on suositeltavaa poistaa kaikki "
|
|
||||||
"laajennukset käytöstä."
|
|
||||||
|
|
||||||
#: js/extensionPrefs/ui/extensions-window.ui:133
|
|
||||||
msgid "Manually Installed"
|
|
||||||
msgstr "Manuaalisesti asennettu"
|
|
||||||
|
|
||||||
#: js/extensionPrefs/ui/extensions-window.ui:157
|
|
||||||
msgid "Built-In"
|
|
||||||
msgstr "Sisäänrakennettu"
|
|
||||||
|
|
||||||
#: js/extensionPrefs/ui/extensions-window.ui:198
|
|
||||||
msgid "No Installed Extensions"
|
|
||||||
msgstr "Ei asennettuja laajennuksia"
|
|
||||||
|
|
||||||
#: js/extensionPrefs/ui/extensions-window.ui:234
|
|
||||||
msgid ""
|
|
||||||
"We’re very sorry, but it was not possible to get the list of installed "
|
|
||||||
"extensions. Make sure you are logged into GNOME and try again."
|
|
||||||
msgstr ""
|
|
||||||
"Valitettavasti asennettujen laajennusten listaa ei voitu muodostaa. Varmista "
|
|
||||||
"että olet kirjautunut Gnomeen ja yritä uudelleen."
|
|
||||||
|
|
||||||
#: js/extensionPrefs/ui/extensions-window.ui:287
|
|
||||||
msgid "Log Out…"
|
|
||||||
msgstr "Kirjaudu ulos…"
|
|
||||||
|
|
||||||
#. Cisco LEAP
|
#. Cisco LEAP
|
||||||
#: js/gdm/authPrompt.js:236 js/ui/components/networkAgent.js:202
|
#: js/gdm/authPrompt.js:237 js/ui/components/networkAgent.js:204
|
||||||
#: js/ui/components/networkAgent.js:218 js/ui/components/networkAgent.js:242
|
#: js/ui/components/networkAgent.js:220 js/ui/components/networkAgent.js:244
|
||||||
#: js/ui/components/networkAgent.js:263 js/ui/components/networkAgent.js:283
|
#: js/ui/components/networkAgent.js:265 js/ui/components/networkAgent.js:285
|
||||||
#: js/ui/components/networkAgent.js:293 js/ui/components/polkitAgent.js:277
|
#: js/ui/components/networkAgent.js:295 js/ui/components/polkitAgent.js:277
|
||||||
#: js/ui/shellMountOperation.js:326
|
#: js/ui/shellMountOperation.js:326
|
||||||
msgid "Password"
|
msgid "Password"
|
||||||
msgstr "Salasana"
|
msgstr "Salasana"
|
||||||
@ -602,8 +481,8 @@ msgstr "(esim. käyttäjä tai %s)"
|
|||||||
#. TTLS and PEAP are actually much more complicated, but this complication
|
#. TTLS and PEAP are actually much more complicated, but this complication
|
||||||
#. is not visible here since we only care about phase2 authentication
|
#. is not visible here since we only care about phase2 authentication
|
||||||
#. (and don't even care of which one)
|
#. (and don't even care of which one)
|
||||||
#: js/gdm/loginDialog.js:917 js/ui/components/networkAgent.js:238
|
#: js/gdm/loginDialog.js:917 js/ui/components/networkAgent.js:240
|
||||||
#: js/ui/components/networkAgent.js:261 js/ui/components/networkAgent.js:279
|
#: js/ui/components/networkAgent.js:263 js/ui/components/networkAgent.js:281
|
||||||
msgid "Username"
|
msgid "Username"
|
||||||
msgstr "Käyttäjätunnus"
|
msgstr "Käyttäjätunnus"
|
||||||
|
|
||||||
@ -857,44 +736,44 @@ msgstr "Estä pääsy"
|
|||||||
msgid "Grant Access"
|
msgid "Grant Access"
|
||||||
msgstr "Salli pääsy"
|
msgstr "Salli pääsy"
|
||||||
|
|
||||||
#: js/ui/appDisplay.js:906
|
#: js/ui/appDisplay.js:937
|
||||||
msgid "Unnamed Folder"
|
msgid "Unnamed Folder"
|
||||||
msgstr "Nimetön kansio"
|
msgstr "Nimetön kansio"
|
||||||
|
|
||||||
#: js/ui/appDisplay.js:929
|
#: js/ui/appDisplay.js:960
|
||||||
msgid "Frequently used applications will appear here"
|
msgid "Frequently used applications will appear here"
|
||||||
msgstr "Usein käytetyt sovellukset ilmestyvät tänne"
|
msgstr "Usein käytetyt sovellukset ilmestyvät tänne"
|
||||||
|
|
||||||
#: js/ui/appDisplay.js:1064
|
#: js/ui/appDisplay.js:1095
|
||||||
msgid "Frequent"
|
msgid "Frequent"
|
||||||
msgstr "Käytetyimmät"
|
msgstr "Käytetyimmät"
|
||||||
|
|
||||||
#: js/ui/appDisplay.js:1071
|
#: js/ui/appDisplay.js:1102
|
||||||
msgid "All"
|
msgid "All"
|
||||||
msgstr "Kaikki"
|
msgstr "Kaikki"
|
||||||
|
|
||||||
#. Translators: This is the heading of a list of open windows
|
#. Translators: This is the heading of a list of open windows
|
||||||
#: js/ui/appDisplay.js:2450 js/ui/panel.js:75
|
#: js/ui/appDisplay.js:2478 js/ui/panel.js:75
|
||||||
msgid "Open Windows"
|
msgid "Open Windows"
|
||||||
msgstr "Avoimet ikkunat"
|
msgstr "Avoimet ikkunat"
|
||||||
|
|
||||||
#: js/ui/appDisplay.js:2470 js/ui/panel.js:82
|
#: js/ui/appDisplay.js:2498 js/ui/panel.js:82
|
||||||
msgid "New Window"
|
msgid "New Window"
|
||||||
msgstr "Uusi ikkuna"
|
msgstr "Uusi ikkuna"
|
||||||
|
|
||||||
#: js/ui/appDisplay.js:2481
|
#: js/ui/appDisplay.js:2509
|
||||||
msgid "Launch using Dedicated Graphics Card"
|
msgid "Launch using Dedicated Graphics Card"
|
||||||
msgstr "Käynnistä erillisnäytönohjainta käyttäen"
|
msgstr "Käynnistä erillisnäytönohjainta käyttäen"
|
||||||
|
|
||||||
#: js/ui/appDisplay.js:2509 js/ui/dash.js:239
|
#: js/ui/appDisplay.js:2537 js/ui/dash.js:239
|
||||||
msgid "Remove from Favorites"
|
msgid "Remove from Favorites"
|
||||||
msgstr "Poista suosikeista"
|
msgstr "Poista suosikeista"
|
||||||
|
|
||||||
#: js/ui/appDisplay.js:2515
|
#: js/ui/appDisplay.js:2543
|
||||||
msgid "Add to Favorites"
|
msgid "Add to Favorites"
|
||||||
msgstr "Lisää suosikkeihin"
|
msgstr "Lisää suosikkeihin"
|
||||||
|
|
||||||
#: js/ui/appDisplay.js:2525 js/ui/panel.js:93
|
#: js/ui/appDisplay.js:2553 js/ui/panel.js:93
|
||||||
msgid "Show Details"
|
msgid "Show Details"
|
||||||
msgstr "Näytä tiedot"
|
msgstr "Näytä tiedot"
|
||||||
|
|
||||||
@ -924,7 +803,7 @@ msgstr "Kuulokkeet"
|
|||||||
msgid "Headset"
|
msgid "Headset"
|
||||||
msgstr "Headset-kuulokkeet"
|
msgstr "Headset-kuulokkeet"
|
||||||
|
|
||||||
#: js/ui/audioDeviceSelection.js:68 js/ui/status/volume.js:269
|
#: js/ui/audioDeviceSelection.js:68 js/ui/status/volume.js:270
|
||||||
msgid "Microphone"
|
msgid "Microphone"
|
||||||
msgstr "Mikrofoni"
|
msgstr "Mikrofoni"
|
||||||
|
|
||||||
@ -1042,30 +921,30 @@ msgid "All Day"
|
|||||||
msgstr "Koko päivä"
|
msgstr "Koko päivä"
|
||||||
|
|
||||||
#. Translators: Shown on calendar heading when selected day occurs on current year
|
#. Translators: Shown on calendar heading when selected day occurs on current year
|
||||||
#: js/ui/calendar.js:867
|
#: js/ui/calendar.js:868
|
||||||
msgctxt "calendar heading"
|
msgctxt "calendar heading"
|
||||||
msgid "%A, %B %-d"
|
msgid "%A, %B %-d"
|
||||||
msgstr "%A, %-d. %Bta"
|
msgstr "%A, %-d. %Bta"
|
||||||
|
|
||||||
#. Translators: Shown on calendar heading when selected day occurs on different year
|
#. Translators: Shown on calendar heading when selected day occurs on different year
|
||||||
#: js/ui/calendar.js:870
|
#: js/ui/calendar.js:871
|
||||||
msgctxt "calendar heading"
|
msgctxt "calendar heading"
|
||||||
msgid "%A, %B %-d, %Y"
|
msgid "%A, %B %-d, %Y"
|
||||||
msgstr "%A, %-d. %Bta %Y"
|
msgstr "%A, %-d. %Bta %Y"
|
||||||
|
|
||||||
#: js/ui/calendar.js:1096
|
#: js/ui/calendar.js:1100
|
||||||
msgid "No Notifications"
|
msgid "No Notifications"
|
||||||
msgstr "Ei ilmoituksia"
|
msgstr "Ei ilmoituksia"
|
||||||
|
|
||||||
#: js/ui/calendar.js:1099
|
#: js/ui/calendar.js:1103
|
||||||
msgid "No Events"
|
msgid "No Events"
|
||||||
msgstr "Ei tapahtumia"
|
msgstr "Ei tapahtumia"
|
||||||
|
|
||||||
#: js/ui/calendar.js:1153
|
#: js/ui/calendar.js:1157
|
||||||
msgid "Do Not Disturb"
|
msgid "Do Not Disturb"
|
||||||
msgstr "Älä häiritse"
|
msgstr "Älä häiritse"
|
||||||
|
|
||||||
#: js/ui/calendar.js:1167
|
#: js/ui/calendar.js:1176
|
||||||
msgid "Clear"
|
msgid "Clear"
|
||||||
msgstr "Tyhjennä"
|
msgstr "Tyhjennä"
|
||||||
|
|
||||||
@ -1112,81 +991,81 @@ msgstr "Asennettu udisks-versio ei tue PIM-asetusta"
|
|||||||
msgid "Open with %s"
|
msgid "Open with %s"
|
||||||
msgstr "Avaa käyttäen sovellusta %s"
|
msgstr "Avaa käyttäen sovellusta %s"
|
||||||
|
|
||||||
#: js/ui/components/networkAgent.js:89
|
#: js/ui/components/networkAgent.js:91
|
||||||
msgid ""
|
msgid ""
|
||||||
"Alternatively you can connect by pushing the “WPS” button on your router."
|
"Alternatively you can connect by pushing the “WPS” button on your router."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Vaihtoehtoisesti voit yhdistää painamalla reitittimesi “WPS”-painiketta."
|
"Vaihtoehtoisesti voit yhdistää painamalla reitittimesi “WPS”-painiketta."
|
||||||
|
|
||||||
#: js/ui/components/networkAgent.js:101 js/ui/status/network.js:223
|
#: js/ui/components/networkAgent.js:103 js/ui/status/network.js:223
|
||||||
#: js/ui/status/network.js:314 js/ui/status/network.js:916
|
#: js/ui/status/network.js:314 js/ui/status/network.js:916
|
||||||
msgid "Connect"
|
msgid "Connect"
|
||||||
msgstr "Yhdistä"
|
msgstr "Yhdistä"
|
||||||
|
|
||||||
#: js/ui/components/networkAgent.js:208
|
#: js/ui/components/networkAgent.js:210
|
||||||
msgid "Key"
|
msgid "Key"
|
||||||
msgstr "Avain"
|
msgstr "Avain"
|
||||||
|
|
||||||
#: js/ui/components/networkAgent.js:246 js/ui/components/networkAgent.js:269
|
#: js/ui/components/networkAgent.js:248 js/ui/components/networkAgent.js:271
|
||||||
msgid "Private key password"
|
msgid "Private key password"
|
||||||
msgstr "Yksityisen avaimen salasana"
|
msgstr "Yksityisen avaimen salasana"
|
||||||
|
|
||||||
#: js/ui/components/networkAgent.js:267
|
#: js/ui/components/networkAgent.js:269
|
||||||
msgid "Identity"
|
msgid "Identity"
|
||||||
msgstr "Identiteetti"
|
msgstr "Identiteetti"
|
||||||
|
|
||||||
#: js/ui/components/networkAgent.js:281
|
#: js/ui/components/networkAgent.js:283
|
||||||
msgid "Service"
|
msgid "Service"
|
||||||
msgstr "Palvelu"
|
msgstr "Palvelu"
|
||||||
|
|
||||||
#: js/ui/components/networkAgent.js:310 js/ui/components/networkAgent.js:338
|
#: js/ui/components/networkAgent.js:312 js/ui/components/networkAgent.js:340
|
||||||
#: js/ui/components/networkAgent.js:685 js/ui/components/networkAgent.js:706
|
#: js/ui/components/networkAgent.js:679 js/ui/components/networkAgent.js:700
|
||||||
msgid "Authentication required"
|
msgid "Authentication required"
|
||||||
msgstr "Tunnistautuminen vaaditaan"
|
msgstr "Tunnistautuminen vaaditaan"
|
||||||
|
|
||||||
#: js/ui/components/networkAgent.js:311 js/ui/components/networkAgent.js:686
|
#: js/ui/components/networkAgent.js:313 js/ui/components/networkAgent.js:680
|
||||||
#, javascript-format
|
#, javascript-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"Passwords or encryption keys are required to access the wireless network "
|
"Passwords or encryption keys are required to access the wireless network "
|
||||||
"“%s”."
|
"“%s”."
|
||||||
msgstr "Langaton verkko \"%s\" vaatii salasanan tai salausavaimia."
|
msgstr "Langaton verkko \"%s\" vaatii salasanan tai salausavaimia."
|
||||||
|
|
||||||
#: js/ui/components/networkAgent.js:315 js/ui/components/networkAgent.js:690
|
#: js/ui/components/networkAgent.js:317 js/ui/components/networkAgent.js:684
|
||||||
msgid "Wired 802.1X authentication"
|
msgid "Wired 802.1X authentication"
|
||||||
msgstr "Kiinteän 802.1X-yhteyden tunnistautuminen"
|
msgstr "Kiinteän 802.1X-yhteyden tunnistautuminen"
|
||||||
|
|
||||||
#: js/ui/components/networkAgent.js:317
|
#: js/ui/components/networkAgent.js:319
|
||||||
msgid "Network name"
|
msgid "Network name"
|
||||||
msgstr "Verkon nimi"
|
msgstr "Verkon nimi"
|
||||||
|
|
||||||
#: js/ui/components/networkAgent.js:322 js/ui/components/networkAgent.js:694
|
#: js/ui/components/networkAgent.js:324 js/ui/components/networkAgent.js:688
|
||||||
msgid "DSL authentication"
|
msgid "DSL authentication"
|
||||||
msgstr "DSL-tunnistautuminen"
|
msgstr "DSL-tunnistautuminen"
|
||||||
|
|
||||||
#: js/ui/components/networkAgent.js:329 js/ui/components/networkAgent.js:699
|
#: js/ui/components/networkAgent.js:331 js/ui/components/networkAgent.js:693
|
||||||
msgid "PIN code required"
|
msgid "PIN code required"
|
||||||
msgstr "PIN-koodi vaaditaan"
|
msgstr "PIN-koodi vaaditaan"
|
||||||
|
|
||||||
#: js/ui/components/networkAgent.js:330 js/ui/components/networkAgent.js:700
|
#: js/ui/components/networkAgent.js:332 js/ui/components/networkAgent.js:694
|
||||||
msgid "PIN code is needed for the mobile broadband device"
|
msgid "PIN code is needed for the mobile broadband device"
|
||||||
msgstr "Mobiililaajakaista vaatii PIN-koodin"
|
msgstr "Mobiililaajakaista vaatii PIN-koodin"
|
||||||
|
|
||||||
#: js/ui/components/networkAgent.js:331
|
#: js/ui/components/networkAgent.js:333
|
||||||
msgid "PIN"
|
msgid "PIN"
|
||||||
msgstr "PIN"
|
msgstr "PIN"
|
||||||
|
|
||||||
#: js/ui/components/networkAgent.js:339 js/ui/components/networkAgent.js:691
|
#: js/ui/components/networkAgent.js:341 js/ui/components/networkAgent.js:685
|
||||||
#: js/ui/components/networkAgent.js:695 js/ui/components/networkAgent.js:707
|
#: js/ui/components/networkAgent.js:689 js/ui/components/networkAgent.js:701
|
||||||
#: js/ui/components/networkAgent.js:711
|
#: js/ui/components/networkAgent.js:705
|
||||||
#, javascript-format
|
#, javascript-format
|
||||||
msgid "A password is required to connect to “%s”."
|
msgid "A password is required to connect to “%s”."
|
||||||
msgstr "Salasana vaaditaan kohteeseen \"%s\" yhdistämiseksi."
|
msgstr "Salasana vaaditaan kohteeseen \"%s\" yhdistämiseksi."
|
||||||
|
|
||||||
#: js/ui/components/networkAgent.js:674 js/ui/status/network.js:1691
|
#: js/ui/components/networkAgent.js:668 js/ui/status/network.js:1691
|
||||||
msgid "Network Manager"
|
msgid "Network Manager"
|
||||||
msgstr "Verkon hallinta"
|
msgstr "Verkon hallinta"
|
||||||
|
|
||||||
#: js/ui/components/networkAgent.js:710
|
#: js/ui/components/networkAgent.js:704
|
||||||
msgid "VPN password"
|
msgid "VPN password"
|
||||||
msgstr "VPN-salasana"
|
msgstr "VPN-salasana"
|
||||||
|
|
||||||
@ -1212,7 +1091,7 @@ msgstr "Kirjautuminen epäonnistui. Yritä uudelleen."
|
|||||||
|
|
||||||
#. Translators: this is the other person changing their old IM name to their new
|
#. Translators: this is the other person changing their old IM name to their new
|
||||||
#. IM name.
|
#. IM name.
|
||||||
#: js/ui/components/telepathyClient.js:787
|
#: js/ui/components/telepathyClient.js:823
|
||||||
#, javascript-format
|
#, javascript-format
|
||||||
msgid "%s is now known as %s"
|
msgid "%s is now known as %s"
|
||||||
msgstr "%s on nyt nimeltään %s"
|
msgstr "%s on nyt nimeltään %s"
|
||||||
@ -1256,94 +1135,94 @@ msgstr "Lisää maailmankelloja…"
|
|||||||
msgid "World Clocks"
|
msgid "World Clocks"
|
||||||
msgstr "Maailmankellot"
|
msgstr "Maailmankellot"
|
||||||
|
|
||||||
#: js/ui/dateMenu.js:276
|
#: js/ui/dateMenu.js:289
|
||||||
msgid "Weather"
|
msgid "Weather"
|
||||||
msgstr "Sää"
|
msgstr "Sää"
|
||||||
|
|
||||||
#: js/ui/dateMenu.js:391
|
#: js/ui/dateMenu.js:418
|
||||||
msgid "Select a location…"
|
msgid "Select a location…"
|
||||||
msgstr "Valitse sijainti…"
|
msgstr "Valitse sijainti…"
|
||||||
|
|
||||||
#: js/ui/dateMenu.js:404
|
#: js/ui/dateMenu.js:426
|
||||||
msgid "Loading…"
|
msgid "Loading…"
|
||||||
msgstr "Ladataan…"
|
msgstr "Ladataan…"
|
||||||
|
|
||||||
#: js/ui/dateMenu.js:414
|
#: js/ui/dateMenu.js:436
|
||||||
msgid "Go online for weather information"
|
msgid "Go online for weather information"
|
||||||
msgstr "Yhdistä verkkoon saadaksesi säätietoja"
|
msgstr "Yhdistä verkkoon saadaksesi säätietoja"
|
||||||
|
|
||||||
#: js/ui/dateMenu.js:416
|
#: js/ui/dateMenu.js:438
|
||||||
msgid "Weather information is currently unavailable"
|
msgid "Weather information is currently unavailable"
|
||||||
msgstr "Säätiedot eivät ole juuri nyt saatavilla"
|
msgstr "Säätiedot eivät ole juuri nyt saatavilla"
|
||||||
|
|
||||||
#: js/ui/endSessionDialog.js:37
|
#: js/ui/endSessionDialog.js:39
|
||||||
#, javascript-format
|
#, javascript-format
|
||||||
msgctxt "title"
|
msgctxt "title"
|
||||||
msgid "Log Out %s"
|
msgid "Log Out %s"
|
||||||
msgstr "Kirjaa %s ulos"
|
msgstr "Kirjaa %s ulos"
|
||||||
|
|
||||||
#: js/ui/endSessionDialog.js:38
|
#: js/ui/endSessionDialog.js:40
|
||||||
msgctxt "title"
|
msgctxt "title"
|
||||||
msgid "Log Out"
|
msgid "Log Out"
|
||||||
msgstr "Kirjaudu ulos"
|
msgstr "Kirjaudu ulos"
|
||||||
|
|
||||||
#: js/ui/endSessionDialog.js:40
|
#: js/ui/endSessionDialog.js:42
|
||||||
#, javascript-format
|
#, javascript-format
|
||||||
msgid "%s will be logged out automatically in %d second."
|
msgid "%s will be logged out automatically in %d second."
|
||||||
msgid_plural "%s will be logged out automatically in %d seconds."
|
msgid_plural "%s will be logged out automatically in %d seconds."
|
||||||
msgstr[0] "%s - kirjaudutaan ulos automaattisesti %d sekunnin kuluttua."
|
msgstr[0] "%s - kirjaudutaan ulos automaattisesti %d sekunnin kuluttua."
|
||||||
msgstr[1] "%s - kirjaudutaan ulos automaattisesti %d sekunnin kuluttua."
|
msgstr[1] "%s - kirjaudutaan ulos automaattisesti %d sekunnin kuluttua."
|
||||||
|
|
||||||
#: js/ui/endSessionDialog.js:45
|
#: js/ui/endSessionDialog.js:47
|
||||||
#, javascript-format
|
#, javascript-format
|
||||||
msgid "You will be logged out automatically in %d second."
|
msgid "You will be logged out automatically in %d second."
|
||||||
msgid_plural "You will be logged out automatically in %d seconds."
|
msgid_plural "You will be logged out automatically in %d seconds."
|
||||||
msgstr[0] "Sinut kirjataan ulos automaattisesti %d sekunnin kuluttua."
|
msgstr[0] "Sinut kirjataan ulos automaattisesti %d sekunnin kuluttua."
|
||||||
msgstr[1] "Sinut kirjataan ulos automaattisesti %d sekunnin kuluttua."
|
msgstr[1] "Sinut kirjataan ulos automaattisesti %d sekunnin kuluttua."
|
||||||
|
|
||||||
#: js/ui/endSessionDialog.js:51
|
#: js/ui/endSessionDialog.js:53
|
||||||
msgctxt "button"
|
msgctxt "button"
|
||||||
msgid "Log Out"
|
msgid "Log Out"
|
||||||
msgstr "Kirjaudu ulos"
|
msgstr "Kirjaudu ulos"
|
||||||
|
|
||||||
#: js/ui/endSessionDialog.js:56
|
#: js/ui/endSessionDialog.js:58
|
||||||
msgctxt "title"
|
msgctxt "title"
|
||||||
msgid "Power Off"
|
msgid "Power Off"
|
||||||
msgstr "Sammuta"
|
msgstr "Sammuta"
|
||||||
|
|
||||||
#: js/ui/endSessionDialog.js:57
|
#: js/ui/endSessionDialog.js:59
|
||||||
msgctxt "title"
|
msgctxt "title"
|
||||||
msgid "Install Updates & Power Off"
|
msgid "Install Updates & Power Off"
|
||||||
msgstr "Asenna päivitykset ja sammuta"
|
msgstr "Asenna päivitykset ja sammuta"
|
||||||
|
|
||||||
#: js/ui/endSessionDialog.js:59
|
#: js/ui/endSessionDialog.js:61
|
||||||
#, javascript-format
|
#, javascript-format
|
||||||
msgid "The system will power off automatically in %d second."
|
msgid "The system will power off automatically in %d second."
|
||||||
msgid_plural "The system will power off automatically in %d seconds."
|
msgid_plural "The system will power off automatically in %d seconds."
|
||||||
msgstr[0] "Järjestelmä sammuu automaattisesti %d sekunnin kuluttua."
|
msgstr[0] "Järjestelmä sammuu automaattisesti %d sekunnin kuluttua."
|
||||||
msgstr[1] "Järjestelmä sammuu automaattisesti %d sekunnin kuluttua."
|
msgstr[1] "Järjestelmä sammuu automaattisesti %d sekunnin kuluttua."
|
||||||
|
|
||||||
#: js/ui/endSessionDialog.js:63
|
#: js/ui/endSessionDialog.js:65
|
||||||
msgctxt "checkbox"
|
msgctxt "checkbox"
|
||||||
msgid "Install pending software updates"
|
msgid "Install pending software updates"
|
||||||
msgstr "Asenna odottavat ohjelmistopäivitykset"
|
msgstr "Asenna odottavat ohjelmistopäivitykset"
|
||||||
|
|
||||||
#: js/ui/endSessionDialog.js:66 js/ui/endSessionDialog.js:82
|
#: js/ui/endSessionDialog.js:68 js/ui/endSessionDialog.js:84
|
||||||
msgctxt "button"
|
msgctxt "button"
|
||||||
msgid "Restart"
|
msgid "Restart"
|
||||||
msgstr "Käynnistä uudelleen"
|
msgstr "Käynnistä uudelleen"
|
||||||
|
|
||||||
#: js/ui/endSessionDialog.js:68
|
#: js/ui/endSessionDialog.js:70
|
||||||
msgctxt "button"
|
msgctxt "button"
|
||||||
msgid "Power Off"
|
msgid "Power Off"
|
||||||
msgstr "Sammuta"
|
msgstr "Sammuta"
|
||||||
|
|
||||||
#: js/ui/endSessionDialog.js:74
|
#: js/ui/endSessionDialog.js:76
|
||||||
msgctxt "title"
|
msgctxt "title"
|
||||||
msgid "Restart"
|
msgid "Restart"
|
||||||
msgstr "Käynnistä uudelleen"
|
msgstr "Käynnistä uudelleen"
|
||||||
|
|
||||||
#: js/ui/endSessionDialog.js:76
|
#: js/ui/endSessionDialog.js:78
|
||||||
#, javascript-format
|
#, javascript-format
|
||||||
msgid "The system will restart automatically in %d second."
|
msgid "The system will restart automatically in %d second."
|
||||||
msgid_plural "The system will restart automatically in %d seconds."
|
msgid_plural "The system will restart automatically in %d seconds."
|
||||||
@ -1352,12 +1231,12 @@ msgstr[0] ""
|
|||||||
msgstr[1] ""
|
msgstr[1] ""
|
||||||
"Järjestelmä käynnistyy automaattisesti uudelleen %d sekunnin kuluttua."
|
"Järjestelmä käynnistyy automaattisesti uudelleen %d sekunnin kuluttua."
|
||||||
|
|
||||||
#: js/ui/endSessionDialog.js:89
|
#: js/ui/endSessionDialog.js:91
|
||||||
msgctxt "title"
|
msgctxt "title"
|
||||||
msgid "Restart & Install Updates"
|
msgid "Restart & Install Updates"
|
||||||
msgstr "Käynnistä uudelleen ja asenna päivitykset"
|
msgstr "Käynnistä uudelleen ja asenna päivitykset"
|
||||||
|
|
||||||
#: js/ui/endSessionDialog.js:91
|
#: js/ui/endSessionDialog.js:93
|
||||||
#, javascript-format
|
#, javascript-format
|
||||||
msgid "The system will automatically restart and install updates in %d second."
|
msgid "The system will automatically restart and install updates in %d second."
|
||||||
msgid_plural ""
|
msgid_plural ""
|
||||||
@ -1369,22 +1248,22 @@ msgstr[1] ""
|
|||||||
"Järjestelmä käynnistyy automaattisesti uudelleen ja asentaa päivitykset %d "
|
"Järjestelmä käynnistyy automaattisesti uudelleen ja asentaa päivitykset %d "
|
||||||
"sekunnin kuluttua."
|
"sekunnin kuluttua."
|
||||||
|
|
||||||
#: js/ui/endSessionDialog.js:97 js/ui/endSessionDialog.js:116
|
#: js/ui/endSessionDialog.js:99 js/ui/endSessionDialog.js:118
|
||||||
msgctxt "button"
|
msgctxt "button"
|
||||||
msgid "Restart & Install"
|
msgid "Restart & Install"
|
||||||
msgstr "Käynnistä uudelleen ja asenna"
|
msgstr "Käynnistä uudelleen ja asenna"
|
||||||
|
|
||||||
#: js/ui/endSessionDialog.js:98
|
#: js/ui/endSessionDialog.js:100
|
||||||
msgctxt "button"
|
msgctxt "button"
|
||||||
msgid "Install & Power Off"
|
msgid "Install & Power Off"
|
||||||
msgstr "Asenna ja sammuta"
|
msgstr "Asenna ja sammuta"
|
||||||
|
|
||||||
#: js/ui/endSessionDialog.js:99
|
#: js/ui/endSessionDialog.js:101
|
||||||
msgctxt "checkbox"
|
msgctxt "checkbox"
|
||||||
msgid "Power off after updates are installed"
|
msgid "Power off after updates are installed"
|
||||||
msgstr "Sammuta päivitysten asennuksen jälkeen"
|
msgstr "Sammuta päivitysten asennuksen jälkeen"
|
||||||
|
|
||||||
#: js/ui/endSessionDialog.js:106
|
#: js/ui/endSessionDialog.js:108
|
||||||
msgctxt "title"
|
msgctxt "title"
|
||||||
msgid "Restart & Install Upgrade"
|
msgid "Restart & Install Upgrade"
|
||||||
msgstr "Käynnistä uudelleen ja asenna päivitys"
|
msgstr "Käynnistä uudelleen ja asenna päivitys"
|
||||||
@ -1392,7 +1271,7 @@ msgstr "Käynnistä uudelleen ja asenna päivitys"
|
|||||||
#. Translators: This is the text displayed for system upgrades in the
|
#. Translators: This is the text displayed for system upgrades in the
|
||||||
#. shut down dialog. First %s gets replaced with the distro name and
|
#. shut down dialog. First %s gets replaced with the distro name and
|
||||||
#. second %s with the distro version to upgrade to
|
#. second %s with the distro version to upgrade to
|
||||||
#: js/ui/endSessionDialog.js:111
|
#: js/ui/endSessionDialog.js:113
|
||||||
#, javascript-format
|
#, javascript-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"%s %s will be installed after restart. Upgrade installation can take a long "
|
"%s %s will be installed after restart. Upgrade installation can take a long "
|
||||||
@ -1402,16 +1281,16 @@ msgstr ""
|
|||||||
"voi kestää kauan: varmista varmuuskopioidesi ajantasaisuus ja toimivuus. "
|
"voi kestää kauan: varmista varmuuskopioidesi ajantasaisuus ja toimivuus. "
|
||||||
"Kiinnitä kone myös verkkovirtaan."
|
"Kiinnitä kone myös verkkovirtaan."
|
||||||
|
|
||||||
#: js/ui/endSessionDialog.js:259
|
#: js/ui/endSessionDialog.js:261
|
||||||
msgid "Running on battery power: Please plug in before installing updates."
|
msgid "Running on battery power: Please plug in before installing updates."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Laite käy akkuvirralla: kiinnitä verkkovirtaan ennen päivitysten asennusta."
|
"Laite käy akkuvirralla: kiinnitä verkkovirtaan ennen päivitysten asennusta."
|
||||||
|
|
||||||
#: js/ui/endSessionDialog.js:268
|
#: js/ui/endSessionDialog.js:270
|
||||||
msgid "Some applications are busy or have unsaved work"
|
msgid "Some applications are busy or have unsaved work"
|
||||||
msgstr "Jotkin sovellukset ovat kiireisiä tai sisältävät tallentamatonta työtä"
|
msgstr "Jotkin sovellukset ovat kiireisiä tai sisältävät tallentamatonta työtä"
|
||||||
|
|
||||||
#: js/ui/endSessionDialog.js:273
|
#: js/ui/endSessionDialog.js:275
|
||||||
msgid "Other users are logged in"
|
msgid "Other users are logged in"
|
||||||
msgstr "Muita käyttäjiä on kirjautuneena"
|
msgstr "Muita käyttäjiä on kirjautuneena"
|
||||||
|
|
||||||
@ -1427,24 +1306,24 @@ msgstr "%s (etä)"
|
|||||||
msgid "%s (console)"
|
msgid "%s (console)"
|
||||||
msgstr "%s (konsoli)"
|
msgstr "%s (konsoli)"
|
||||||
|
|
||||||
#: js/ui/extensionDownloader.js:169
|
#: js/ui/extensionDownloader.js:185
|
||||||
msgid "Install"
|
msgid "Install"
|
||||||
msgstr "Asenna"
|
msgstr "Asenna"
|
||||||
|
|
||||||
#: js/ui/extensionDownloader.js:175
|
#: js/ui/extensionDownloader.js:191
|
||||||
msgid "Install Extension"
|
msgid "Install Extension"
|
||||||
msgstr "Asenna laajennus"
|
msgstr "Asenna laajennus"
|
||||||
|
|
||||||
#: js/ui/extensionDownloader.js:176
|
#: js/ui/extensionDownloader.js:192
|
||||||
#, javascript-format
|
#, javascript-format
|
||||||
msgid "Download and install “%s” from extensions.gnome.org?"
|
msgid "Download and install “%s” from extensions.gnome.org?"
|
||||||
msgstr "Ladataanko ja asennetaanko ”%s” sivustolta extensions.gnome.org?"
|
msgstr "Ladataanko ja asennetaanko ”%s” sivustolta extensions.gnome.org?"
|
||||||
|
|
||||||
#: js/ui/extensionSystem.js:228
|
#: js/ui/extensionSystem.js:233
|
||||||
msgid "Extension Updates Available"
|
msgid "Extension Updates Available"
|
||||||
msgstr "Laajennusten päivityksiä saatavilla"
|
msgstr "Laajennusten päivityksiä saatavilla"
|
||||||
|
|
||||||
#: js/ui/extensionSystem.js:229
|
#: js/ui/extensionSystem.js:234
|
||||||
msgid "Extension updates are ready to be installed."
|
msgid "Extension updates are ready to be installed."
|
||||||
msgstr "Laajennusten päivitykset ovat valmiina asennettavaksi."
|
msgstr "Laajennusten päivitykset ovat valmiina asennettavaksi."
|
||||||
|
|
||||||
@ -1593,11 +1472,11 @@ msgstr "Näytä lähde"
|
|||||||
msgid "Web Page"
|
msgid "Web Page"
|
||||||
msgstr "Verkkosivusto"
|
msgstr "Verkkosivusto"
|
||||||
|
|
||||||
#: js/ui/main.js:269
|
#: js/ui/main.js:279
|
||||||
msgid "Logged in as a privileged user"
|
msgid "Logged in as a privileged user"
|
||||||
msgstr "Kirjautuneena etuoikeutettuna käyttäjänä"
|
msgstr "Kirjautuneena etuoikeutettuna käyttäjänä"
|
||||||
|
|
||||||
#: js/ui/main.js:270
|
#: js/ui/main.js:280
|
||||||
msgid ""
|
msgid ""
|
||||||
"Running a session as a privileged user should be avoided for security "
|
"Running a session as a privileged user should be avoided for security "
|
||||||
"reasons. If possible, you should log in as a normal user."
|
"reasons. If possible, you should log in as a normal user."
|
||||||
@ -1605,15 +1484,15 @@ msgstr ""
|
|||||||
"Istunnon suorittamista etuoikeutettuna käyttäjänä tulisi välttää "
|
"Istunnon suorittamista etuoikeutettuna käyttäjänä tulisi välttää "
|
||||||
"tietoturvasyistä. Jos mahdollista, kirjaudu tavallisena käyttäjänä."
|
"tietoturvasyistä. Jos mahdollista, kirjaudu tavallisena käyttäjänä."
|
||||||
|
|
||||||
#: js/ui/main.js:276
|
#: js/ui/main.js:319
|
||||||
msgid "Screen Lock disabled"
|
msgid "Screen Lock disabled"
|
||||||
msgstr "Näytön lukitus pois käytöstä"
|
msgstr "Näytön lukitus pois käytöstä"
|
||||||
|
|
||||||
#: js/ui/main.js:277
|
#: js/ui/main.js:320
|
||||||
msgid "Screen Locking requires the GNOME display manager."
|
msgid "Screen Locking requires the GNOME display manager."
|
||||||
msgstr "Näytön lukitus vaatii Gnomen kirjautumishallinnan."
|
msgstr "Näytön lukitus vaatii Gnomen kirjautumishallinnan."
|
||||||
|
|
||||||
#: js/ui/messageTray.js:1554
|
#: js/ui/messageTray.js:1551
|
||||||
msgid "System Information"
|
msgid "System Information"
|
||||||
msgstr "Järjestelmän tiedot"
|
msgstr "Järjestelmän tiedot"
|
||||||
|
|
||||||
@ -1699,12 +1578,12 @@ msgstr "Lopeta"
|
|||||||
msgid "Activities"
|
msgid "Activities"
|
||||||
msgstr "Toiminnot"
|
msgstr "Toiminnot"
|
||||||
|
|
||||||
#: js/ui/panel.js:707
|
#: js/ui/panel.js:713
|
||||||
msgctxt "System menu in the top bar"
|
msgctxt "System menu in the top bar"
|
||||||
msgid "System"
|
msgid "System"
|
||||||
msgstr "Järjestelmä"
|
msgstr "Järjestelmä"
|
||||||
|
|
||||||
#: js/ui/panel.js:820
|
#: js/ui/panel.js:826
|
||||||
msgid "Top Bar"
|
msgid "Top Bar"
|
||||||
msgstr "Yläpalkki"
|
msgstr "Yläpalkki"
|
||||||
|
|
||||||
@ -1820,13 +1699,13 @@ msgid "The PIM must be a number or empty."
|
|||||||
msgstr "PIM tulee olla numeerinen tai tyhjä."
|
msgstr "PIM tulee olla numeerinen tai tyhjä."
|
||||||
|
|
||||||
#. Translators: %s is the Disks application
|
#. Translators: %s is the Disks application
|
||||||
#: js/ui/shellMountOperation.js:469
|
#: js/ui/shellMountOperation.js:465
|
||||||
#, javascript-format
|
#, javascript-format
|
||||||
msgid "Unable to start %s"
|
msgid "Unable to start %s"
|
||||||
msgstr "Sovelluksen %s käynnistäminen ei onnistunut"
|
msgstr "Sovelluksen %s käynnistäminen ei onnistunut"
|
||||||
|
|
||||||
#. Translators: %s is the Disks application
|
#. Translators: %s is the Disks application
|
||||||
#: js/ui/shellMountOperation.js:471
|
#: js/ui/shellMountOperation.js:467
|
||||||
#, javascript-format
|
#, javascript-format
|
||||||
msgid "Couldn’t find the %s application"
|
msgid "Couldn’t find the %s application"
|
||||||
msgstr "Sovellusta %s ei löytynyt"
|
msgstr "Sovellusta %s ei löytynyt"
|
||||||
@ -2300,11 +2179,11 @@ msgstr "Thunderbolt-valtuutusvirhe"
|
|||||||
msgid "Could not authorize the Thunderbolt device: %s"
|
msgid "Could not authorize the Thunderbolt device: %s"
|
||||||
msgstr "Thunderbolt-laitetta ei voitu valtuuttaa: %s"
|
msgstr "Thunderbolt-laitetta ei voitu valtuuttaa: %s"
|
||||||
|
|
||||||
#: js/ui/status/volume.js:150
|
#: js/ui/status/volume.js:151
|
||||||
msgid "Volume changed"
|
msgid "Volume changed"
|
||||||
msgstr "Äänenvoimakkuutta muutettu"
|
msgstr "Äänenvoimakkuutta muutettu"
|
||||||
|
|
||||||
#: js/ui/status/volume.js:221
|
#: js/ui/status/volume.js:222
|
||||||
msgid "Volume"
|
msgid "Volume"
|
||||||
msgstr "Äänenvoimakkuus"
|
msgstr "Äänenvoimakkuus"
|
||||||
|
|
||||||
@ -2338,25 +2217,26 @@ msgstr "Vain sisäinen"
|
|||||||
|
|
||||||
#. Translators: This is a time format for a date in
|
#. Translators: This is a time format for a date in
|
||||||
#. long format
|
#. long format
|
||||||
#: js/ui/unlockDialog.js:372
|
#: js/ui/unlockDialog.js:371
|
||||||
#, fuzzy
|
|
||||||
#| msgctxt "calendar heading"
|
|
||||||
#| msgid "%A, %B %-d"
|
|
||||||
msgid "%A %B %-d"
|
msgid "%A %B %-d"
|
||||||
msgstr "%A, %-d. %Bta"
|
msgstr "%A, %-e. %Bta"
|
||||||
|
|
||||||
#: js/ui/unlockDialog.js:378
|
#: js/ui/unlockDialog.js:377
|
||||||
msgid "Swipe up to unlock"
|
msgid "Swipe up to unlock"
|
||||||
msgstr "Vedä ylös avataksesi lukituksen"
|
msgstr "Vedä ylös avataksesi lukituksen"
|
||||||
|
|
||||||
#: js/ui/unlockDialog.js:379
|
#: js/ui/unlockDialog.js:378
|
||||||
msgid "Click or press a key to unlock"
|
msgid "Click or press a key to unlock"
|
||||||
msgstr "Napsauta tai paina näppäintä avataksesi lukituksen"
|
msgstr "Napsauta tai paina näppäintä avataksesi lukituksen"
|
||||||
|
|
||||||
#: js/ui/unlockDialog.js:552
|
#: js/ui/unlockDialog.js:550
|
||||||
msgid "Unlock Window"
|
msgid "Unlock Window"
|
||||||
msgstr "Lukituksen avausikkuna"
|
msgstr "Lukituksen avausikkuna"
|
||||||
|
|
||||||
|
#: js/ui/unlockDialog.js:559
|
||||||
|
msgid "Log in as another user"
|
||||||
|
msgstr "Kirjaudu toisena käyttäjänä"
|
||||||
|
|
||||||
#: js/ui/viewSelector.js:181
|
#: js/ui/viewSelector.js:181
|
||||||
msgid "Applications"
|
msgid "Applications"
|
||||||
msgstr "Sovellukset"
|
msgstr "Sovellukset"
|
||||||
@ -2472,19 +2352,19 @@ msgstr "Sulje"
|
|||||||
msgid "Evolution Calendar"
|
msgid "Evolution Calendar"
|
||||||
msgstr "Evolution-kalenteri"
|
msgstr "Evolution-kalenteri"
|
||||||
|
|
||||||
#: src/main.c:460 subprojects/extensions-tool/src/main.c:249
|
#: src/main.c:458 subprojects/extensions-tool/src/main.c:249
|
||||||
msgid "Print version"
|
msgid "Print version"
|
||||||
msgstr "Tulosta versio"
|
msgstr "Tulosta versio"
|
||||||
|
|
||||||
#: src/main.c:466
|
#: src/main.c:464
|
||||||
msgid "Mode used by GDM for login screen"
|
msgid "Mode used by GDM for login screen"
|
||||||
msgstr "GDM:n kirjautumisruudussa käyttämä tila"
|
msgstr "GDM:n kirjautumisruudussa käyttämä tila"
|
||||||
|
|
||||||
#: src/main.c:472
|
#: src/main.c:470
|
||||||
msgid "Use a specific mode, e.g. “gdm” for login screen"
|
msgid "Use a specific mode, e.g. “gdm” for login screen"
|
||||||
msgstr "Käytä tiettyä tilaa (esim. “gdm”) kirjautumisnäkymää varten"
|
msgstr "Käytä tiettyä tilaa (esim. “gdm”) kirjautumisnäkymää varten"
|
||||||
|
|
||||||
#: src/main.c:478
|
#: src/main.c:476
|
||||||
msgid "List possible modes"
|
msgid "List possible modes"
|
||||||
msgstr "Listaa mahdolliset tilat"
|
msgstr "Listaa mahdolliset tilat"
|
||||||
|
|
||||||
@ -2510,6 +2390,136 @@ msgstr "Salasana ei voi olla tyhjä"
|
|||||||
msgid "Authentication dialog was dismissed by the user"
|
msgid "Authentication dialog was dismissed by the user"
|
||||||
msgstr "Käyttäjä poistui tunnistautumisvalintaikkunasta"
|
msgstr "Käyttäjä poistui tunnistautumisvalintaikkunasta"
|
||||||
|
|
||||||
|
#: subprojects/extensions-app/data/metainfo/org.gnome.Extensions.metainfo.xml.in:5
|
||||||
|
#: subprojects/extensions-app/data/org.gnome.Extensions.desktop.in.in:4
|
||||||
|
#: subprojects/extensions-app/js/main.js:182
|
||||||
|
#: subprojects/extensions-app/data/ui/extensions-window.ui:61
|
||||||
|
msgid "Extensions"
|
||||||
|
msgstr "Laajennukset"
|
||||||
|
|
||||||
|
#: subprojects/extensions-app/data/metainfo/org.gnome.Extensions.metainfo.xml.in:6
|
||||||
|
#: subprojects/extensions-app/js/main.js:183
|
||||||
|
msgid "Manage your GNOME Extensions"
|
||||||
|
msgstr "Hallitse Gnome-laajennuksia"
|
||||||
|
|
||||||
|
#: subprojects/extensions-app/data/metainfo/org.gnome.Extensions.metainfo.xml.in:35
|
||||||
|
msgid ""
|
||||||
|
"GNOME Extensions handles updating extensions, configuring extension "
|
||||||
|
"preferences and removing or disabling unwanted extensions."
|
||||||
|
msgstr ""
|
||||||
|
"Gnomen laajennussovellus Laajennukset käsittelee laajennusten päivitykset, "
|
||||||
|
"niiden asetukset ja sen avulla voi poistaa laajennuksia käytöstä tai "
|
||||||
|
"kokonaan järjestelmästä."
|
||||||
|
|
||||||
|
#: subprojects/extensions-app/data/org.gnome.Extensions.desktop.in.in:7
|
||||||
|
msgid "Configure GNOME Shell Extensions"
|
||||||
|
msgstr "Hallitse Gnome Shell -laajennuksia"
|
||||||
|
|
||||||
|
#: subprojects/extensions-app/js/main.js:144
|
||||||
|
#, javascript-format
|
||||||
|
msgid "Remove “%s”?"
|
||||||
|
msgstr "Poista “%s”?"
|
||||||
|
|
||||||
|
#: subprojects/extensions-app/js/main.js:145
|
||||||
|
msgid ""
|
||||||
|
"If you remove the extension, you need to return to download it if you want "
|
||||||
|
"to enable it again"
|
||||||
|
msgstr ""
|
||||||
|
"Ota huomioon jos poistat laajennuksen; sinun tulee palata ja ladata se "
|
||||||
|
"uudelleen, jos haluat sen uudelleen käyttöön"
|
||||||
|
|
||||||
|
#: subprojects/extensions-app/js/main.js:149
|
||||||
|
msgid "Remove"
|
||||||
|
msgstr "Poista"
|
||||||
|
|
||||||
|
#: subprojects/extensions-app/js/main.js:181
|
||||||
|
msgid "translator-credits"
|
||||||
|
msgstr "Jiri Grönroos"
|
||||||
|
|
||||||
|
#: subprojects/extensions-app/js/main.js:316
|
||||||
|
#, javascript-format
|
||||||
|
msgid "%d extension will be updated on next login."
|
||||||
|
msgid_plural "%d extensions will be updated on next login."
|
||||||
|
msgstr[0] "%d laajennus päivitetään seuraavan kerran, kun kirjaudut sisään."
|
||||||
|
msgstr[1] "%d laajennusta päivitetään seuraavan kerran, kun kirjaudut sisään."
|
||||||
|
|
||||||
|
#: subprojects/extensions-app/data/ui/extension-row.ui:100
|
||||||
|
#: subprojects/extensions-tool/src/command-create.c:211
|
||||||
|
#: subprojects/extensions-tool/src/main.c:173
|
||||||
|
msgid "Description"
|
||||||
|
msgstr "Kuvaus"
|
||||||
|
|
||||||
|
#: subprojects/extensions-app/data/ui/extension-row.ui:123
|
||||||
|
#: subprojects/extensions-tool/src/main.c:185
|
||||||
|
msgid "Version"
|
||||||
|
msgstr "Versio"
|
||||||
|
|
||||||
|
#: subprojects/extensions-app/data/ui/extension-row.ui:151
|
||||||
|
msgid "Author"
|
||||||
|
msgstr "Tekijä"
|
||||||
|
|
||||||
|
#: subprojects/extensions-app/data/ui/extension-row.ui:175
|
||||||
|
msgid "Website"
|
||||||
|
msgstr "Verkkosivusto"
|
||||||
|
|
||||||
|
#: subprojects/extensions-app/data/ui/extension-row.ui:192
|
||||||
|
msgid "Remove…"
|
||||||
|
msgstr "Poista…"
|
||||||
|
|
||||||
|
#: subprojects/extensions-app/data/ui/extensions-window.ui:8
|
||||||
|
msgid "Help"
|
||||||
|
msgstr "Tuki"
|
||||||
|
|
||||||
|
#: subprojects/extensions-app/data/ui/extensions-window.ui:12
|
||||||
|
msgid "About Extensions"
|
||||||
|
msgstr "Tietoja - Laajennukset"
|
||||||
|
|
||||||
|
#: subprojects/extensions-app/data/ui/extensions-window.ui:27
|
||||||
|
msgid ""
|
||||||
|
"To find and add extensions, visit <a href=\"https://extensions.gnome.org"
|
||||||
|
"\">extensions.gnome.org</a>."
|
||||||
|
msgstr ""
|
||||||
|
"Etsi ja asenna laajennuksia osoitteessa <a href=\"https://extensions.gnome."
|
||||||
|
"org\">extensions.gnome.org</a>."
|
||||||
|
|
||||||
|
#: subprojects/extensions-app/data/ui/extensions-window.ui:35
|
||||||
|
msgid "Warning"
|
||||||
|
msgstr "Varoitus"
|
||||||
|
|
||||||
|
#: subprojects/extensions-app/data/ui/extensions-window.ui:46
|
||||||
|
msgid ""
|
||||||
|
"Extensions can cause system issues, including performance problems. If you "
|
||||||
|
"encounter problems with your system, it is recommended to disable all "
|
||||||
|
"extensions."
|
||||||
|
msgstr ""
|
||||||
|
"Laajennukset voivat aiheuttaa ongelmia järjestelmässä, myös suorituskykyyn. "
|
||||||
|
"Jos kohtaat ongelmia järjestelmän kanssa, on suositeltavaa poistaa kaikki "
|
||||||
|
"laajennukset käytöstä."
|
||||||
|
|
||||||
|
#: subprojects/extensions-app/data/ui/extensions-window.ui:134
|
||||||
|
msgid "Manually Installed"
|
||||||
|
msgstr "Manuaalisesti asennettu"
|
||||||
|
|
||||||
|
#: subprojects/extensions-app/data/ui/extensions-window.ui:158
|
||||||
|
msgid "Built-In"
|
||||||
|
msgstr "Sisäänrakennettu"
|
||||||
|
|
||||||
|
#: subprojects/extensions-app/data/ui/extensions-window.ui:199
|
||||||
|
msgid "No Installed Extensions"
|
||||||
|
msgstr "Ei asennettuja laajennuksia"
|
||||||
|
|
||||||
|
#: subprojects/extensions-app/data/ui/extensions-window.ui:235
|
||||||
|
msgid ""
|
||||||
|
"We’re very sorry, but it was not possible to get the list of installed "
|
||||||
|
"extensions. Make sure you are logged into GNOME and try again."
|
||||||
|
msgstr ""
|
||||||
|
"Valitettavasti asennettujen laajennusten listaa ei voitu muodostaa. Varmista "
|
||||||
|
"että olet kirjautunut Gnomeen ja yritä uudelleen."
|
||||||
|
|
||||||
|
#: subprojects/extensions-app/data/ui/extensions-window.ui:288
|
||||||
|
msgid "Log Out…"
|
||||||
|
msgstr "Kirjaudu ulos…"
|
||||||
|
|
||||||
#. Translators: a file path to an extension directory
|
#. Translators: a file path to an extension directory
|
||||||
#: subprojects/extensions-tool/src/command-create.c:125
|
#: subprojects/extensions-tool/src/command-create.c:125
|
||||||
#, c-format
|
#, c-format
|
||||||
@ -2847,6 +2857,9 @@ msgstr[1] "%u sisääntuloa"
|
|||||||
msgid "System Sounds"
|
msgid "System Sounds"
|
||||||
msgstr "Järjestelmän äänet"
|
msgstr "Järjestelmän äänet"
|
||||||
|
|
||||||
|
#~ msgid "Copy Error"
|
||||||
|
#~ msgstr "Kopiointivirhe"
|
||||||
|
|
||||||
#~ msgid "Username…"
|
#~ msgid "Username…"
|
||||||
#~ msgstr "Käyttäjänimi…"
|
#~ msgstr "Käyttäjänimi…"
|
||||||
|
|
||||||
@ -2876,9 +2889,6 @@ msgstr "Järjestelmän äänet"
|
|||||||
#~ msgstr[0] "%d uusi ilmoitus"
|
#~ msgstr[0] "%d uusi ilmoitus"
|
||||||
#~ msgstr[1] "%d uutta ilmoitusta"
|
#~ msgstr[1] "%d uutta ilmoitusta"
|
||||||
|
|
||||||
#~ msgid "Log in as another user"
|
|
||||||
#~ msgstr "Kirjaudu toisena käyttäjänä"
|
|
||||||
|
|
||||||
#~ msgid "Browse in Software"
|
#~ msgid "Browse in Software"
|
||||||
#~ msgstr "Selaa ohjelmistokeskuksessa"
|
#~ msgstr "Selaa ohjelmistokeskuksessa"
|
||||||
|
|
||||||
|
423
po/pt_BR.po
423
po/pt_BR.po
@ -24,8 +24,8 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: gnome-shell\n"
|
"Project-Id-Version: gnome-shell\n"
|
||||||
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gnome-shell/issues\n"
|
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gnome-shell/issues\n"
|
||||||
"POT-Creation-Date: 2020-03-19 14:34+0000\n"
|
"POT-Creation-Date: 2020-03-31 07:15+0000\n"
|
||||||
"PO-Revision-Date: 2020-03-19 11:36-0300\n"
|
"PO-Revision-Date: 2020-04-22 09:30-0300\n"
|
||||||
"Last-Translator: Rafael Fontenelle <rafaelff@gnome.org>\n"
|
"Last-Translator: Rafael Fontenelle <rafaelff@gnome.org>\n"
|
||||||
"Language-Team: Brazilian Portuguese <gnome-pt_br-list@gnome.org>\n"
|
"Language-Team: Brazilian Portuguese <gnome-pt_br-list@gnome.org>\n"
|
||||||
"Language: pt_BR\n"
|
"Language: pt_BR\n"
|
||||||
@ -413,66 +413,12 @@ msgstr "Atrasar foco altera o modo do mouse até o ponteiro parar de mover"
|
|||||||
msgid "Network Login"
|
msgid "Network Login"
|
||||||
msgstr "Sessão de Rede"
|
msgstr "Sessão de Rede"
|
||||||
|
|
||||||
#: js/extensionPrefs/data/metainfo/org.gnome.Extensions.metainfo.xml.in:5
|
#: js/dbusServices/extensions/ui/extension-prefs-dialog.ui:36
|
||||||
#: js/extensionPrefs/data/org.gnome.Extensions.desktop.in.in:4
|
#: subprojects/extensions-app/data/ui/extensions-window.ui:223
|
||||||
#: js/extensionPrefs/js/main.js:242
|
|
||||||
#: js/extensionPrefs/data/ui/extensions-window.ui:61
|
|
||||||
msgid "Extensions"
|
|
||||||
msgstr "Extensões"
|
|
||||||
|
|
||||||
#: js/extensionPrefs/data/metainfo/org.gnome.Extensions.metainfo.xml.in:6
|
|
||||||
#: js/extensionPrefs/js/main.js:243
|
|
||||||
msgid "Manage your GNOME Extensions"
|
|
||||||
msgstr "Gerenciar suas extensões do GNOME"
|
|
||||||
|
|
||||||
#: js/extensionPrefs/data/metainfo/org.gnome.Extensions.metainfo.xml.in:35
|
|
||||||
msgid ""
|
|
||||||
"GNOME Extensions handles updating extensions, configuring extension "
|
|
||||||
"preferences and removing or disabling unwanted extensions."
|
|
||||||
msgstr ""
|
|
||||||
"GNOME Extensões lida com a atualização da extensões, configuração das "
|
|
||||||
"preferências de extensões e remoção ou desabilitação de extensões "
|
|
||||||
"indesejadas."
|
|
||||||
|
|
||||||
#: js/extensionPrefs/data/org.gnome.Extensions.desktop.in.in:7
|
|
||||||
msgid "Configure GNOME Shell Extensions"
|
|
||||||
msgstr "Configurar extensões do Shell do GNOME"
|
|
||||||
|
|
||||||
#: js/extensionPrefs/js/main.js:164
|
|
||||||
#, javascript-format
|
|
||||||
msgid "Remove “%s”?"
|
|
||||||
msgstr "Remover “%s”?"
|
|
||||||
|
|
||||||
#: js/extensionPrefs/js/main.js:165
|
|
||||||
msgid ""
|
|
||||||
"If you remove the extension, you need to return to download it if you want "
|
|
||||||
"to enable it again"
|
|
||||||
msgstr ""
|
|
||||||
"Se você remover a extensão, você precisa voltar a baixá-la se você quiser "
|
|
||||||
"habilitá-la novamente"
|
|
||||||
|
|
||||||
#: js/extensionPrefs/js/main.js:168 js/gdm/authPrompt.js:135
|
|
||||||
#: js/ui/audioDeviceSelection.js:57 js/ui/components/networkAgent.js:109
|
|
||||||
#: js/ui/components/polkitAgent.js:139 js/ui/endSessionDialog.js:374
|
|
||||||
#: js/ui/extensionDownloader.js:177 js/ui/shellMountOperation.js:376
|
|
||||||
#: js/ui/shellMountOperation.js:386 js/ui/status/network.js:913
|
|
||||||
msgid "Cancel"
|
|
||||||
msgstr "Cancelar"
|
|
||||||
|
|
||||||
#: js/extensionPrefs/js/main.js:169
|
|
||||||
msgid "Remove"
|
|
||||||
msgstr "Remover"
|
|
||||||
|
|
||||||
#: js/extensionPrefs/js/main.js:241
|
|
||||||
msgid "translator-credits"
|
|
||||||
msgstr "Rafael Fontenelle <rafaelff@gnome.org>"
|
|
||||||
|
|
||||||
#: js/extensionPrefs/js/main.js:285
|
|
||||||
#: js/extensionPrefs/data/ui/extensions-window.ui:223
|
|
||||||
msgid "Something’s gone wrong"
|
msgid "Something’s gone wrong"
|
||||||
msgstr "Algo deu errado"
|
msgstr "Algo deu errado"
|
||||||
|
|
||||||
#: js/extensionPrefs/js/main.js:292
|
#: js/dbusServices/extensions/ui/extension-prefs-dialog.ui:48
|
||||||
msgid ""
|
msgid ""
|
||||||
"We’re very sorry, but there’s been a problem: the settings for this "
|
"We’re very sorry, but there’s been a problem: the settings for this "
|
||||||
"extension can’t be displayed. We recommend that you report the issue to the "
|
"extension can’t be displayed. We recommend that you report the issue to the "
|
||||||
@ -482,105 +428,25 @@ msgstr ""
|
|||||||
"ser exibidas. Recomendamos que você relate o problema aos autores da "
|
"ser exibidas. Recomendamos que você relate o problema aos autores da "
|
||||||
"extensão."
|
"extensão."
|
||||||
|
|
||||||
#: js/extensionPrefs/js/main.js:299
|
#: js/dbusServices/extensions/ui/extension-prefs-dialog.ui:82
|
||||||
msgid "Technical Details"
|
msgid "Technical Details"
|
||||||
msgstr "Detalhes técnicos"
|
msgstr "Detalhes técnicos"
|
||||||
|
|
||||||
#: js/extensionPrefs/js/main.js:334
|
#: js/dbusServices/extensions/ui/extension-prefs-dialog.ui:165
|
||||||
msgid "Copy Error"
|
|
||||||
msgstr "Copiar erro"
|
|
||||||
|
|
||||||
#: js/extensionPrefs/js/main.js:361
|
|
||||||
msgid "Homepage"
|
msgid "Homepage"
|
||||||
msgstr "Site"
|
msgstr "Site"
|
||||||
|
|
||||||
#: js/extensionPrefs/js/main.js:362
|
#: js/dbusServices/extensions/ui/extension-prefs-dialog.ui:166
|
||||||
msgid "Visit extension homepage"
|
msgid "Visit extension homepage"
|
||||||
msgstr "Visita a página web da extensão"
|
msgstr "Visita a página web da extensão"
|
||||||
|
|
||||||
#: js/extensionPrefs/js/main.js:479
|
#: js/gdm/authPrompt.js:135 js/ui/audioDeviceSelection.js:57
|
||||||
#, javascript-format
|
#: js/ui/components/networkAgent.js:109 js/ui/components/polkitAgent.js:139
|
||||||
msgid "%d extension will be updated on next login."
|
#: js/ui/endSessionDialog.js:374 js/ui/extensionDownloader.js:181
|
||||||
msgid_plural "%d extensions will be updated on next login."
|
#: js/ui/shellMountOperation.js:376 js/ui/shellMountOperation.js:386
|
||||||
msgstr[0] "%d extensão será atualizada na próxima sessão."
|
#: js/ui/status/network.js:913 subprojects/extensions-app/js/main.js:148
|
||||||
msgstr[1] "%d extensões serão atualizadas na próxima sessão."
|
msgid "Cancel"
|
||||||
|
msgstr "Cancelar"
|
||||||
#: js/extensionPrefs/data/ui/extension-row.ui:100
|
|
||||||
#: subprojects/extensions-tool/src/command-create.c:211
|
|
||||||
#: subprojects/extensions-tool/src/main.c:173
|
|
||||||
msgid "Description"
|
|
||||||
msgstr "Descrição"
|
|
||||||
|
|
||||||
#: js/extensionPrefs/data/ui/extension-row.ui:123
|
|
||||||
#: subprojects/extensions-tool/src/main.c:185
|
|
||||||
msgid "Version"
|
|
||||||
msgstr "Versão"
|
|
||||||
|
|
||||||
#: js/extensionPrefs/data/ui/extension-row.ui:151
|
|
||||||
msgid "Author"
|
|
||||||
msgstr "Autor"
|
|
||||||
|
|
||||||
#: js/extensionPrefs/data/ui/extension-row.ui:175
|
|
||||||
msgid "Website"
|
|
||||||
msgstr "Site"
|
|
||||||
|
|
||||||
#: js/extensionPrefs/data/ui/extension-row.ui:192
|
|
||||||
msgid "Remove…"
|
|
||||||
msgstr "Remover…"
|
|
||||||
|
|
||||||
#: js/extensionPrefs/data/ui/extensions-window.ui:8
|
|
||||||
msgid "Help"
|
|
||||||
msgstr "Ajuda"
|
|
||||||
|
|
||||||
#: js/extensionPrefs/data/ui/extensions-window.ui:12
|
|
||||||
msgid "About Extensions"
|
|
||||||
msgstr "Sobre as Extensões"
|
|
||||||
|
|
||||||
#: js/extensionPrefs/data/ui/extensions-window.ui:27
|
|
||||||
msgid ""
|
|
||||||
"To find and add extensions, visit <a href=\"https://extensions.gnome.org"
|
|
||||||
"\">extensions.gnome.org</a>."
|
|
||||||
msgstr ""
|
|
||||||
"Para encontrar e adicionar extensões, visite <a href=\"https://extensions."
|
|
||||||
"gnome.org\">extensions.gnome.org</a>."
|
|
||||||
|
|
||||||
#: js/extensionPrefs/data/ui/extensions-window.ui:35
|
|
||||||
msgid "Warning"
|
|
||||||
msgstr "Aviso"
|
|
||||||
|
|
||||||
#: js/extensionPrefs/data/ui/extensions-window.ui:46
|
|
||||||
msgid ""
|
|
||||||
"Extensions can cause system issues, including performance problems. If you "
|
|
||||||
"encounter problems with your system, it is recommended to disable all "
|
|
||||||
"extensions."
|
|
||||||
msgstr ""
|
|
||||||
"Extensões podem causar problemas no sistema, incluindo problemas de "
|
|
||||||
"desempenho. Se você encontrar problemas com o seu sistema, é recomendável "
|
|
||||||
"desativar todas as extensões."
|
|
||||||
|
|
||||||
#: js/extensionPrefs/data/ui/extensions-window.ui:134
|
|
||||||
msgid "Manually Installed"
|
|
||||||
msgstr "Instalada manualmente"
|
|
||||||
|
|
||||||
#: js/extensionPrefs/data/ui/extensions-window.ui:158
|
|
||||||
msgid "Built-In"
|
|
||||||
msgstr "Interna"
|
|
||||||
|
|
||||||
#: js/extensionPrefs/data/ui/extensions-window.ui:199
|
|
||||||
msgid "No Installed Extensions"
|
|
||||||
msgstr "Nenhuma extensão instalada"
|
|
||||||
|
|
||||||
#: js/extensionPrefs/data/ui/extensions-window.ui:235
|
|
||||||
msgid ""
|
|
||||||
"We’re very sorry, but it was not possible to get the list of installed "
|
|
||||||
"extensions. Make sure you are logged into GNOME and try again."
|
|
||||||
msgstr ""
|
|
||||||
"Sentimos muito, mas não foi possível obter a lista de extensões instaladas. "
|
|
||||||
"Certifique-se de estar em uma sessão do GNOME e tente novamente."
|
|
||||||
|
|
||||||
#: js/extensionPrefs/data/ui/extensions-window.ui:288
|
|
||||||
msgid "Log Out…"
|
|
||||||
msgstr "Encerrar sessão…"
|
|
||||||
|
|
||||||
#. Cisco LEAP
|
#. Cisco LEAP
|
||||||
#: js/gdm/authPrompt.js:237 js/ui/components/networkAgent.js:204
|
#: js/gdm/authPrompt.js:237 js/ui/components/networkAgent.js:204
|
||||||
@ -862,44 +728,44 @@ msgstr "Negar acesso"
|
|||||||
msgid "Grant Access"
|
msgid "Grant Access"
|
||||||
msgstr "Conceder acesso"
|
msgstr "Conceder acesso"
|
||||||
|
|
||||||
#: js/ui/appDisplay.js:898
|
#: js/ui/appDisplay.js:932
|
||||||
msgid "Unnamed Folder"
|
msgid "Unnamed Folder"
|
||||||
msgstr "Pasta sem nome"
|
msgstr "Pasta sem nome"
|
||||||
|
|
||||||
#: js/ui/appDisplay.js:921
|
#: js/ui/appDisplay.js:955
|
||||||
msgid "Frequently used applications will appear here"
|
msgid "Frequently used applications will appear here"
|
||||||
msgstr "Aplicativos usados frequentemente vão aparecer aqui"
|
msgstr "Aplicativos usados frequentemente vão aparecer aqui"
|
||||||
|
|
||||||
#: js/ui/appDisplay.js:1056
|
#: js/ui/appDisplay.js:1090
|
||||||
msgid "Frequent"
|
msgid "Frequent"
|
||||||
msgstr "Frequente"
|
msgstr "Frequente"
|
||||||
|
|
||||||
#: js/ui/appDisplay.js:1063
|
#: js/ui/appDisplay.js:1097
|
||||||
msgid "All"
|
msgid "All"
|
||||||
msgstr "Todos"
|
msgstr "Todos"
|
||||||
|
|
||||||
#. Translators: This is the heading of a list of open windows
|
#. Translators: This is the heading of a list of open windows
|
||||||
#: js/ui/appDisplay.js:2446 js/ui/panel.js:75
|
#: js/ui/appDisplay.js:2473 js/ui/panel.js:75
|
||||||
msgid "Open Windows"
|
msgid "Open Windows"
|
||||||
msgstr "Janelas abertas"
|
msgstr "Janelas abertas"
|
||||||
|
|
||||||
#: js/ui/appDisplay.js:2466 js/ui/panel.js:82
|
#: js/ui/appDisplay.js:2493 js/ui/panel.js:82
|
||||||
msgid "New Window"
|
msgid "New Window"
|
||||||
msgstr "Nova janela"
|
msgstr "Nova janela"
|
||||||
|
|
||||||
#: js/ui/appDisplay.js:2477
|
#: js/ui/appDisplay.js:2504
|
||||||
msgid "Launch using Dedicated Graphics Card"
|
msgid "Launch using Dedicated Graphics Card"
|
||||||
msgstr "Inicia usando placa de vídeo dedicada"
|
msgstr "Inicia usando placa de vídeo dedicada"
|
||||||
|
|
||||||
#: js/ui/appDisplay.js:2505 js/ui/dash.js:239
|
#: js/ui/appDisplay.js:2532 js/ui/dash.js:239
|
||||||
msgid "Remove from Favorites"
|
msgid "Remove from Favorites"
|
||||||
msgstr "Remover dos favoritos"
|
msgstr "Remover dos favoritos"
|
||||||
|
|
||||||
#: js/ui/appDisplay.js:2511
|
#: js/ui/appDisplay.js:2538
|
||||||
msgid "Add to Favorites"
|
msgid "Add to Favorites"
|
||||||
msgstr "Adicionar aos favoritos"
|
msgstr "Adicionar aos favoritos"
|
||||||
|
|
||||||
#: js/ui/appDisplay.js:2521 js/ui/panel.js:93
|
#: js/ui/appDisplay.js:2548 js/ui/panel.js:93
|
||||||
msgid "Show Details"
|
msgid "Show Details"
|
||||||
msgstr "Mostrar detalhes"
|
msgstr "Mostrar detalhes"
|
||||||
|
|
||||||
@ -929,7 +795,7 @@ msgstr "Fones de ouvido"
|
|||||||
msgid "Headset"
|
msgid "Headset"
|
||||||
msgstr "Fone de ouvido com microfone"
|
msgstr "Fone de ouvido com microfone"
|
||||||
|
|
||||||
#: js/ui/audioDeviceSelection.js:68 js/ui/status/volume.js:269
|
#: js/ui/audioDeviceSelection.js:68 js/ui/status/volume.js:270
|
||||||
msgid "Microphone"
|
msgid "Microphone"
|
||||||
msgstr "Microfone"
|
msgstr "Microfone"
|
||||||
|
|
||||||
@ -1070,7 +936,7 @@ msgstr "Nenhum evento"
|
|||||||
msgid "Do Not Disturb"
|
msgid "Do Not Disturb"
|
||||||
msgstr "Não perturbe"
|
msgstr "Não perturbe"
|
||||||
|
|
||||||
#: js/ui/calendar.js:1171
|
#: js/ui/calendar.js:1176
|
||||||
msgid "Clear"
|
msgid "Clear"
|
||||||
msgstr "Limpar"
|
msgstr "Limpar"
|
||||||
|
|
||||||
@ -1220,7 +1086,7 @@ msgstr "Desculpe, isto não funcionou. Por favor, tente novamente."
|
|||||||
|
|
||||||
#. Translators: this is the other person changing their old IM name to their new
|
#. Translators: this is the other person changing their old IM name to their new
|
||||||
#. IM name.
|
#. IM name.
|
||||||
#: js/ui/components/telepathyClient.js:787
|
#: js/ui/components/telepathyClient.js:823
|
||||||
#, javascript-format
|
#, javascript-format
|
||||||
msgid "%s is now known as %s"
|
msgid "%s is now known as %s"
|
||||||
msgstr "%s agora é conhecido como %s"
|
msgstr "%s agora é conhecido como %s"
|
||||||
@ -1264,106 +1130,106 @@ msgstr "Adicionar relógios mundiais…"
|
|||||||
msgid "World Clocks"
|
msgid "World Clocks"
|
||||||
msgstr "Relógios mundiais"
|
msgstr "Relógios mundiais"
|
||||||
|
|
||||||
#: js/ui/dateMenu.js:279
|
#: js/ui/dateMenu.js:289
|
||||||
msgid "Weather"
|
msgid "Weather"
|
||||||
msgstr "Meteorologia"
|
msgstr "Meteorologia"
|
||||||
|
|
||||||
#: js/ui/dateMenu.js:394
|
#: js/ui/dateMenu.js:418
|
||||||
msgid "Select a location…"
|
msgid "Select a location…"
|
||||||
msgstr "Selecione uma localização…"
|
msgstr "Selecione uma localização…"
|
||||||
|
|
||||||
#: js/ui/dateMenu.js:407
|
#: js/ui/dateMenu.js:426
|
||||||
msgid "Loading…"
|
msgid "Loading…"
|
||||||
msgstr "Carregando…"
|
msgstr "Carregando…"
|
||||||
|
|
||||||
#: js/ui/dateMenu.js:417
|
#: js/ui/dateMenu.js:436
|
||||||
msgid "Go online for weather information"
|
msgid "Go online for weather information"
|
||||||
msgstr "Conecte-se à internet para obter as informações meteorológicas"
|
msgstr "Conecte-se à internet para obter as informações meteorológicas"
|
||||||
|
|
||||||
#: js/ui/dateMenu.js:419
|
#: js/ui/dateMenu.js:438
|
||||||
msgid "Weather information is currently unavailable"
|
msgid "Weather information is currently unavailable"
|
||||||
msgstr "No momento as informações meteorológicas não estão disponíveis"
|
msgstr "No momento as informações meteorológicas não estão disponíveis"
|
||||||
|
|
||||||
#: js/ui/endSessionDialog.js:37
|
#: js/ui/endSessionDialog.js:39
|
||||||
#, javascript-format
|
#, javascript-format
|
||||||
msgctxt "title"
|
msgctxt "title"
|
||||||
msgid "Log Out %s"
|
msgid "Log Out %s"
|
||||||
msgstr "Encerrar sessão de %s"
|
msgstr "Encerrar sessão de %s"
|
||||||
|
|
||||||
#: js/ui/endSessionDialog.js:38
|
#: js/ui/endSessionDialog.js:40
|
||||||
msgctxt "title"
|
msgctxt "title"
|
||||||
msgid "Log Out"
|
msgid "Log Out"
|
||||||
msgstr "Encerrar sessão"
|
msgstr "Encerrar sessão"
|
||||||
|
|
||||||
#: js/ui/endSessionDialog.js:40
|
#: js/ui/endSessionDialog.js:42
|
||||||
#, javascript-format
|
#, javascript-format
|
||||||
msgid "%s will be logged out automatically in %d second."
|
msgid "%s will be logged out automatically in %d second."
|
||||||
msgid_plural "%s will be logged out automatically in %d seconds."
|
msgid_plural "%s will be logged out automatically in %d seconds."
|
||||||
msgstr[0] "%s encerrará a sessão automaticamente em %d segundo."
|
msgstr[0] "%s encerrará a sessão automaticamente em %d segundo."
|
||||||
msgstr[1] "%s encerrará a sessão automaticamente em %d segundos."
|
msgstr[1] "%s encerrará a sessão automaticamente em %d segundos."
|
||||||
|
|
||||||
#: js/ui/endSessionDialog.js:45
|
#: js/ui/endSessionDialog.js:47
|
||||||
#, javascript-format
|
#, javascript-format
|
||||||
msgid "You will be logged out automatically in %d second."
|
msgid "You will be logged out automatically in %d second."
|
||||||
msgid_plural "You will be logged out automatically in %d seconds."
|
msgid_plural "You will be logged out automatically in %d seconds."
|
||||||
msgstr[0] "Sua sessão será encerrada automaticamente em %d segundo."
|
msgstr[0] "Sua sessão será encerrada automaticamente em %d segundo."
|
||||||
msgstr[1] "Sua sessão será encerrada automaticamente em %d segundos."
|
msgstr[1] "Sua sessão será encerrada automaticamente em %d segundos."
|
||||||
|
|
||||||
#: js/ui/endSessionDialog.js:51
|
#: js/ui/endSessionDialog.js:53
|
||||||
msgctxt "button"
|
msgctxt "button"
|
||||||
msgid "Log Out"
|
msgid "Log Out"
|
||||||
msgstr "Encerrar sessão"
|
msgstr "Encerrar sessão"
|
||||||
|
|
||||||
#: js/ui/endSessionDialog.js:56
|
#: js/ui/endSessionDialog.js:58
|
||||||
msgctxt "title"
|
msgctxt "title"
|
||||||
msgid "Power Off"
|
msgid "Power Off"
|
||||||
msgstr "Desligar"
|
msgstr "Desligar"
|
||||||
|
|
||||||
#: js/ui/endSessionDialog.js:57
|
#: js/ui/endSessionDialog.js:59
|
||||||
msgctxt "title"
|
msgctxt "title"
|
||||||
msgid "Install Updates & Power Off"
|
msgid "Install Updates & Power Off"
|
||||||
msgstr "Instalar atualizações & desligar"
|
msgstr "Instalar atualizações & desligar"
|
||||||
|
|
||||||
#: js/ui/endSessionDialog.js:59
|
#: js/ui/endSessionDialog.js:61
|
||||||
#, javascript-format
|
#, javascript-format
|
||||||
msgid "The system will power off automatically in %d second."
|
msgid "The system will power off automatically in %d second."
|
||||||
msgid_plural "The system will power off automatically in %d seconds."
|
msgid_plural "The system will power off automatically in %d seconds."
|
||||||
msgstr[0] "O sistema será desligado automaticamente em %d segundo."
|
msgstr[0] "O sistema será desligado automaticamente em %d segundo."
|
||||||
msgstr[1] "O sistema será desligado automaticamente em %d segundos."
|
msgstr[1] "O sistema será desligado automaticamente em %d segundos."
|
||||||
|
|
||||||
#: js/ui/endSessionDialog.js:63
|
#: js/ui/endSessionDialog.js:65
|
||||||
msgctxt "checkbox"
|
msgctxt "checkbox"
|
||||||
msgid "Install pending software updates"
|
msgid "Install pending software updates"
|
||||||
msgstr "Instalar atualizações de software pendentes"
|
msgstr "Instalar atualizações de software pendentes"
|
||||||
|
|
||||||
#: js/ui/endSessionDialog.js:66 js/ui/endSessionDialog.js:82
|
#: js/ui/endSessionDialog.js:68 js/ui/endSessionDialog.js:84
|
||||||
msgctxt "button"
|
msgctxt "button"
|
||||||
msgid "Restart"
|
msgid "Restart"
|
||||||
msgstr "Reiniciar"
|
msgstr "Reiniciar"
|
||||||
|
|
||||||
#: js/ui/endSessionDialog.js:68
|
#: js/ui/endSessionDialog.js:70
|
||||||
msgctxt "button"
|
msgctxt "button"
|
||||||
msgid "Power Off"
|
msgid "Power Off"
|
||||||
msgstr "Desligar"
|
msgstr "Desligar"
|
||||||
|
|
||||||
#: js/ui/endSessionDialog.js:74
|
#: js/ui/endSessionDialog.js:76
|
||||||
msgctxt "title"
|
msgctxt "title"
|
||||||
msgid "Restart"
|
msgid "Restart"
|
||||||
msgstr "Reiniciar"
|
msgstr "Reiniciar"
|
||||||
|
|
||||||
#: js/ui/endSessionDialog.js:76
|
#: js/ui/endSessionDialog.js:78
|
||||||
#, javascript-format
|
#, javascript-format
|
||||||
msgid "The system will restart automatically in %d second."
|
msgid "The system will restart automatically in %d second."
|
||||||
msgid_plural "The system will restart automatically in %d seconds."
|
msgid_plural "The system will restart automatically in %d seconds."
|
||||||
msgstr[0] "O sistema irá reiniciar automaticamente em %d segundo."
|
msgstr[0] "O sistema irá reiniciar automaticamente em %d segundo."
|
||||||
msgstr[1] "O sistema irá reiniciar automaticamente em %d segundos."
|
msgstr[1] "O sistema irá reiniciar automaticamente em %d segundos."
|
||||||
|
|
||||||
#: js/ui/endSessionDialog.js:89
|
#: js/ui/endSessionDialog.js:91
|
||||||
msgctxt "title"
|
msgctxt "title"
|
||||||
msgid "Restart & Install Updates"
|
msgid "Restart & Install Updates"
|
||||||
msgstr "Reiniciar & instalar atualizações"
|
msgstr "Reiniciar & instalar atualizações"
|
||||||
|
|
||||||
#: js/ui/endSessionDialog.js:91
|
#: js/ui/endSessionDialog.js:93
|
||||||
#, javascript-format
|
#, javascript-format
|
||||||
msgid "The system will automatically restart and install updates in %d second."
|
msgid "The system will automatically restart and install updates in %d second."
|
||||||
msgid_plural ""
|
msgid_plural ""
|
||||||
@ -1375,22 +1241,22 @@ msgstr[1] ""
|
|||||||
"O sistema irá reiniciar e instalar atualizações automaticamente em %d "
|
"O sistema irá reiniciar e instalar atualizações automaticamente em %d "
|
||||||
"segundos."
|
"segundos."
|
||||||
|
|
||||||
#: js/ui/endSessionDialog.js:97 js/ui/endSessionDialog.js:116
|
#: js/ui/endSessionDialog.js:99 js/ui/endSessionDialog.js:118
|
||||||
msgctxt "button"
|
msgctxt "button"
|
||||||
msgid "Restart & Install"
|
msgid "Restart & Install"
|
||||||
msgstr "Reiniciar & instalar"
|
msgstr "Reiniciar & instalar"
|
||||||
|
|
||||||
#: js/ui/endSessionDialog.js:98
|
#: js/ui/endSessionDialog.js:100
|
||||||
msgctxt "button"
|
msgctxt "button"
|
||||||
msgid "Install & Power Off"
|
msgid "Install & Power Off"
|
||||||
msgstr "Instalar & desligar"
|
msgstr "Instalar & desligar"
|
||||||
|
|
||||||
#: js/ui/endSessionDialog.js:99
|
#: js/ui/endSessionDialog.js:101
|
||||||
msgctxt "checkbox"
|
msgctxt "checkbox"
|
||||||
msgid "Power off after updates are installed"
|
msgid "Power off after updates are installed"
|
||||||
msgstr "Desligar após atualizações serem instaladas"
|
msgstr "Desligar após atualizações serem instaladas"
|
||||||
|
|
||||||
#: js/ui/endSessionDialog.js:106
|
#: js/ui/endSessionDialog.js:108
|
||||||
msgctxt "title"
|
msgctxt "title"
|
||||||
msgid "Restart & Install Upgrade"
|
msgid "Restart & Install Upgrade"
|
||||||
msgstr "Reiniciar & instalar atualizações"
|
msgstr "Reiniciar & instalar atualizações"
|
||||||
@ -1398,7 +1264,7 @@ msgstr "Reiniciar & instalar atualizações"
|
|||||||
#. Translators: This is the text displayed for system upgrades in the
|
#. Translators: This is the text displayed for system upgrades in the
|
||||||
#. shut down dialog. First %s gets replaced with the distro name and
|
#. shut down dialog. First %s gets replaced with the distro name and
|
||||||
#. second %s with the distro version to upgrade to
|
#. second %s with the distro version to upgrade to
|
||||||
#: js/ui/endSessionDialog.js:111
|
#: js/ui/endSessionDialog.js:113
|
||||||
#, javascript-format
|
#, javascript-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"%s %s will be installed after restart. Upgrade installation can take a long "
|
"%s %s will be installed after restart. Upgrade installation can take a long "
|
||||||
@ -1408,16 +1274,16 @@ msgstr ""
|
|||||||
"pode levar um longo tempo: certifique-se de que fez cópia de segurança (back "
|
"pode levar um longo tempo: certifique-se de que fez cópia de segurança (back "
|
||||||
"up) e que o computador esteja ligado na tomada."
|
"up) e que o computador esteja ligado na tomada."
|
||||||
|
|
||||||
#: js/ui/endSessionDialog.js:259
|
#: js/ui/endSessionDialog.js:261
|
||||||
msgid "Running on battery power: Please plug in before installing updates."
|
msgid "Running on battery power: Please plug in before installing updates."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Funcionando na bateria: conecte na tomada antes de instalar atualizações."
|
"Funcionando na bateria: conecte na tomada antes de instalar atualizações."
|
||||||
|
|
||||||
#: js/ui/endSessionDialog.js:268
|
#: js/ui/endSessionDialog.js:270
|
||||||
msgid "Some applications are busy or have unsaved work"
|
msgid "Some applications are busy or have unsaved work"
|
||||||
msgstr "Alguns aplicativos estão ocupados ou possuem trabalhos não salvos"
|
msgstr "Alguns aplicativos estão ocupados ou possuem trabalhos não salvos"
|
||||||
|
|
||||||
#: js/ui/endSessionDialog.js:273
|
#: js/ui/endSessionDialog.js:275
|
||||||
msgid "Other users are logged in"
|
msgid "Other users are logged in"
|
||||||
msgstr "Outros usuários estão com sessão aberta"
|
msgstr "Outros usuários estão com sessão aberta"
|
||||||
|
|
||||||
@ -1433,24 +1299,24 @@ msgstr "%s (remoto)"
|
|||||||
msgid "%s (console)"
|
msgid "%s (console)"
|
||||||
msgstr "%s (console)"
|
msgstr "%s (console)"
|
||||||
|
|
||||||
#: js/ui/extensionDownloader.js:181
|
#: js/ui/extensionDownloader.js:185
|
||||||
msgid "Install"
|
msgid "Install"
|
||||||
msgstr "Instalar"
|
msgstr "Instalar"
|
||||||
|
|
||||||
#: js/ui/extensionDownloader.js:187
|
#: js/ui/extensionDownloader.js:191
|
||||||
msgid "Install Extension"
|
msgid "Install Extension"
|
||||||
msgstr "Instalar extensão"
|
msgstr "Instalar extensão"
|
||||||
|
|
||||||
#: js/ui/extensionDownloader.js:188
|
#: js/ui/extensionDownloader.js:192
|
||||||
#, javascript-format
|
#, javascript-format
|
||||||
msgid "Download and install “%s” from extensions.gnome.org?"
|
msgid "Download and install “%s” from extensions.gnome.org?"
|
||||||
msgstr "Baixar e instalar “%s” de extensions.gnome.org?"
|
msgstr "Baixar e instalar “%s” de extensions.gnome.org?"
|
||||||
|
|
||||||
#: js/ui/extensionSystem.js:228
|
#: js/ui/extensionSystem.js:233
|
||||||
msgid "Extension Updates Available"
|
msgid "Extension Updates Available"
|
||||||
msgstr "Atualizações de extensões disponíveis"
|
msgstr "Atualizações de extensões disponíveis"
|
||||||
|
|
||||||
#: js/ui/extensionSystem.js:229
|
#: js/ui/extensionSystem.js:234
|
||||||
msgid "Extension updates are ready to be installed."
|
msgid "Extension updates are ready to be installed."
|
||||||
msgstr "Atualizações de extensões estão prontas para serem instaladas."
|
msgstr "Atualizações de extensões estão prontas para serem instaladas."
|
||||||
|
|
||||||
@ -1599,11 +1465,11 @@ msgstr "Ver fonte"
|
|||||||
msgid "Web Page"
|
msgid "Web Page"
|
||||||
msgstr "Página web"
|
msgstr "Página web"
|
||||||
|
|
||||||
#: js/ui/main.js:274
|
#: js/ui/main.js:277
|
||||||
msgid "Logged in as a privileged user"
|
msgid "Logged in as a privileged user"
|
||||||
msgstr "Sessão aberta como um usuário privilegiado"
|
msgstr "Sessão aberta como um usuário privilegiado"
|
||||||
|
|
||||||
#: js/ui/main.js:275
|
#: js/ui/main.js:278
|
||||||
msgid ""
|
msgid ""
|
||||||
"Running a session as a privileged user should be avoided for security "
|
"Running a session as a privileged user should be avoided for security "
|
||||||
"reasons. If possible, you should log in as a normal user."
|
"reasons. If possible, you should log in as a normal user."
|
||||||
@ -1611,15 +1477,15 @@ msgstr ""
|
|||||||
"Usar uma sessão como um usuário privilegiado deve ser evitado por motivos de "
|
"Usar uma sessão como um usuário privilegiado deve ser evitado por motivos de "
|
||||||
"segurança. Se possível, você deve abrir uma sessão como um usuário normal."
|
"segurança. Se possível, você deve abrir uma sessão como um usuário normal."
|
||||||
|
|
||||||
#: js/ui/main.js:281
|
#: js/ui/main.js:317
|
||||||
msgid "Screen Lock disabled"
|
msgid "Screen Lock disabled"
|
||||||
msgstr "Bloqueio de tela desabilitado"
|
msgstr "Bloqueio de tela desabilitado"
|
||||||
|
|
||||||
#: js/ui/main.js:282
|
#: js/ui/main.js:318
|
||||||
msgid "Screen Locking requires the GNOME display manager."
|
msgid "Screen Locking requires the GNOME display manager."
|
||||||
msgstr "O bloqueio de tela requer o gerenciador de exibição do GNOME."
|
msgstr "O bloqueio de tela requer o gerenciador de exibição do GNOME."
|
||||||
|
|
||||||
#: js/ui/messageTray.js:1554
|
#: js/ui/messageTray.js:1551
|
||||||
msgid "System Information"
|
msgid "System Information"
|
||||||
msgstr "Informações do sistema"
|
msgstr "Informações do sistema"
|
||||||
|
|
||||||
@ -1826,13 +1692,13 @@ msgid "The PIM must be a number or empty."
|
|||||||
msgstr "O PIM deve ser um número ou vazio."
|
msgstr "O PIM deve ser um número ou vazio."
|
||||||
|
|
||||||
#. Translators: %s is the Disks application
|
#. Translators: %s is the Disks application
|
||||||
#: js/ui/shellMountOperation.js:469
|
#: js/ui/shellMountOperation.js:465
|
||||||
#, javascript-format
|
#, javascript-format
|
||||||
msgid "Unable to start %s"
|
msgid "Unable to start %s"
|
||||||
msgstr "Não foi possível iniciar o %s"
|
msgstr "Não foi possível iniciar o %s"
|
||||||
|
|
||||||
#. Translators: %s is the Disks application
|
#. Translators: %s is the Disks application
|
||||||
#: js/ui/shellMountOperation.js:471
|
#: js/ui/shellMountOperation.js:467
|
||||||
#, javascript-format
|
#, javascript-format
|
||||||
msgid "Couldn’t find the %s application"
|
msgid "Couldn’t find the %s application"
|
||||||
msgstr "Não foi possível localizar o aplicativo %s"
|
msgstr "Não foi possível localizar o aplicativo %s"
|
||||||
@ -1985,13 +1851,13 @@ msgstr "<desconhecido>"
|
|||||||
#: js/ui/status/network.js:420 js/ui/status/network.js:1317
|
#: js/ui/status/network.js:420 js/ui/status/network.js:1317
|
||||||
#, javascript-format
|
#, javascript-format
|
||||||
msgid "%s Off"
|
msgid "%s Off"
|
||||||
msgstr "%s desligado"
|
msgstr "%s desligada"
|
||||||
|
|
||||||
#. Translators: %s is a network identifier
|
#. Translators: %s is a network identifier
|
||||||
#: js/ui/status/network.js:423
|
#: js/ui/status/network.js:423
|
||||||
#, javascript-format
|
#, javascript-format
|
||||||
msgid "%s Connected"
|
msgid "%s Connected"
|
||||||
msgstr "Conectado a %s"
|
msgstr "Conectado à %s"
|
||||||
|
|
||||||
# Não gerenciável para transmitir a ideia que o Networkmanager não consegue gerenciar o dispositivo --Enrico
|
# Não gerenciável para transmitir a ideia que o Networkmanager não consegue gerenciar o dispositivo --Enrico
|
||||||
#. Translators: this is for network devices that are physically present but are not
|
#. Translators: this is for network devices that are physically present but are not
|
||||||
@ -2012,7 +1878,7 @@ msgstr "Desconectando de %s"
|
|||||||
#: js/ui/status/network.js:438 js/ui/status/network.js:1309
|
#: js/ui/status/network.js:438 js/ui/status/network.js:1309
|
||||||
#, javascript-format
|
#, javascript-format
|
||||||
msgid "%s Connecting"
|
msgid "%s Connecting"
|
||||||
msgstr "Conectando a %s"
|
msgstr "Conectando à %s"
|
||||||
|
|
||||||
#. Translators: this is for network connections that require some kind of key or password; %s is a network identifier
|
#. Translators: this is for network connections that require some kind of key or password; %s is a network identifier
|
||||||
#: js/ui/status/network.js:441
|
#: js/ui/status/network.js:441
|
||||||
@ -2309,11 +2175,11 @@ msgstr "Erro de autorização de thunderbolt"
|
|||||||
msgid "Could not authorize the Thunderbolt device: %s"
|
msgid "Could not authorize the Thunderbolt device: %s"
|
||||||
msgstr "Não foi possível autorizar o dispositivo Thunderbolt: %s"
|
msgstr "Não foi possível autorizar o dispositivo Thunderbolt: %s"
|
||||||
|
|
||||||
#: js/ui/status/volume.js:150
|
#: js/ui/status/volume.js:151
|
||||||
msgid "Volume changed"
|
msgid "Volume changed"
|
||||||
msgstr "Volume alterado"
|
msgstr "Volume alterado"
|
||||||
|
|
||||||
#: js/ui/status/volume.js:221
|
#: js/ui/status/volume.js:222
|
||||||
msgid "Volume"
|
msgid "Volume"
|
||||||
msgstr "Volume"
|
msgstr "Volume"
|
||||||
|
|
||||||
@ -2347,23 +2213,23 @@ msgstr "Interna apenas"
|
|||||||
|
|
||||||
#. Translators: This is a time format for a date in
|
#. Translators: This is a time format for a date in
|
||||||
#. long format
|
#. long format
|
||||||
#: js/ui/unlockDialog.js:370
|
#: js/ui/unlockDialog.js:371
|
||||||
msgid "%A %B %-d"
|
msgid "%A %B %-d"
|
||||||
msgstr "%A, %-d de %B"
|
msgstr "%A, %-d de %B"
|
||||||
|
|
||||||
#: js/ui/unlockDialog.js:376
|
#: js/ui/unlockDialog.js:377
|
||||||
msgid "Swipe up to unlock"
|
msgid "Swipe up to unlock"
|
||||||
msgstr "Deslize para desbloquear"
|
msgstr "Deslize para desbloquear"
|
||||||
|
|
||||||
#: js/ui/unlockDialog.js:377
|
#: js/ui/unlockDialog.js:378
|
||||||
msgid "Click or press a key to unlock"
|
msgid "Click or press a key to unlock"
|
||||||
msgstr "Clique ou pressione uma tecla para desbloquear"
|
msgstr "Clique ou pressione uma tecla para desbloquear"
|
||||||
|
|
||||||
#: js/ui/unlockDialog.js:549
|
#: js/ui/unlockDialog.js:550
|
||||||
msgid "Unlock Window"
|
msgid "Unlock Window"
|
||||||
msgstr "Desbloquear janela"
|
msgstr "Desbloquear janela"
|
||||||
|
|
||||||
#: js/ui/unlockDialog.js:558
|
#: js/ui/unlockDialog.js:559
|
||||||
msgid "Log in as another user"
|
msgid "Log in as another user"
|
||||||
msgstr "Iniciar sessão como outro usuário"
|
msgstr "Iniciar sessão como outro usuário"
|
||||||
|
|
||||||
@ -2523,6 +2389,136 @@ msgstr "A senha não pode estar em branco"
|
|||||||
msgid "Authentication dialog was dismissed by the user"
|
msgid "Authentication dialog was dismissed by the user"
|
||||||
msgstr "O diálogo de autenticação foi descartado pelo usuário"
|
msgstr "O diálogo de autenticação foi descartado pelo usuário"
|
||||||
|
|
||||||
|
#: subprojects/extensions-app/data/metainfo/org.gnome.Extensions.metainfo.xml.in:5
|
||||||
|
#: subprojects/extensions-app/data/org.gnome.Extensions.desktop.in.in:4
|
||||||
|
#: subprojects/extensions-app/js/main.js:182
|
||||||
|
#: subprojects/extensions-app/data/ui/extensions-window.ui:61
|
||||||
|
msgid "Extensions"
|
||||||
|
msgstr "Extensões"
|
||||||
|
|
||||||
|
#: subprojects/extensions-app/data/metainfo/org.gnome.Extensions.metainfo.xml.in:6
|
||||||
|
#: subprojects/extensions-app/js/main.js:183
|
||||||
|
msgid "Manage your GNOME Extensions"
|
||||||
|
msgstr "Gerenciar suas extensões do GNOME"
|
||||||
|
|
||||||
|
#: subprojects/extensions-app/data/metainfo/org.gnome.Extensions.metainfo.xml.in:35
|
||||||
|
msgid ""
|
||||||
|
"GNOME Extensions handles updating extensions, configuring extension "
|
||||||
|
"preferences and removing or disabling unwanted extensions."
|
||||||
|
msgstr ""
|
||||||
|
"GNOME Extensões lida com a atualização da extensões, configuração das "
|
||||||
|
"preferências de extensões e remoção ou desabilitação de extensões "
|
||||||
|
"indesejadas."
|
||||||
|
|
||||||
|
#: subprojects/extensions-app/data/org.gnome.Extensions.desktop.in.in:7
|
||||||
|
msgid "Configure GNOME Shell Extensions"
|
||||||
|
msgstr "Configurar extensões do Shell do GNOME"
|
||||||
|
|
||||||
|
#: subprojects/extensions-app/js/main.js:144
|
||||||
|
#, javascript-format
|
||||||
|
msgid "Remove “%s”?"
|
||||||
|
msgstr "Remover “%s”?"
|
||||||
|
|
||||||
|
#: subprojects/extensions-app/js/main.js:145
|
||||||
|
msgid ""
|
||||||
|
"If you remove the extension, you need to return to download it if you want "
|
||||||
|
"to enable it again"
|
||||||
|
msgstr ""
|
||||||
|
"Se você remover a extensão, você precisa voltar a baixá-la se você quiser "
|
||||||
|
"habilitá-la novamente"
|
||||||
|
|
||||||
|
#: subprojects/extensions-app/js/main.js:149
|
||||||
|
msgid "Remove"
|
||||||
|
msgstr "Remover"
|
||||||
|
|
||||||
|
#: subprojects/extensions-app/js/main.js:181
|
||||||
|
msgid "translator-credits"
|
||||||
|
msgstr "Rafael Fontenelle <rafaelff@gnome.org>"
|
||||||
|
|
||||||
|
#: subprojects/extensions-app/js/main.js:316
|
||||||
|
#, javascript-format
|
||||||
|
msgid "%d extension will be updated on next login."
|
||||||
|
msgid_plural "%d extensions will be updated on next login."
|
||||||
|
msgstr[0] "%d extensão será atualizada na próxima sessão."
|
||||||
|
msgstr[1] "%d extensões serão atualizadas na próxima sessão."
|
||||||
|
|
||||||
|
#: subprojects/extensions-app/data/ui/extension-row.ui:100
|
||||||
|
#: subprojects/extensions-tool/src/command-create.c:211
|
||||||
|
#: subprojects/extensions-tool/src/main.c:173
|
||||||
|
msgid "Description"
|
||||||
|
msgstr "Descrição"
|
||||||
|
|
||||||
|
#: subprojects/extensions-app/data/ui/extension-row.ui:123
|
||||||
|
#: subprojects/extensions-tool/src/main.c:185
|
||||||
|
msgid "Version"
|
||||||
|
msgstr "Versão"
|
||||||
|
|
||||||
|
#: subprojects/extensions-app/data/ui/extension-row.ui:151
|
||||||
|
msgid "Author"
|
||||||
|
msgstr "Autor"
|
||||||
|
|
||||||
|
#: subprojects/extensions-app/data/ui/extension-row.ui:175
|
||||||
|
msgid "Website"
|
||||||
|
msgstr "Site"
|
||||||
|
|
||||||
|
#: subprojects/extensions-app/data/ui/extension-row.ui:192
|
||||||
|
msgid "Remove…"
|
||||||
|
msgstr "Remover…"
|
||||||
|
|
||||||
|
#: subprojects/extensions-app/data/ui/extensions-window.ui:8
|
||||||
|
msgid "Help"
|
||||||
|
msgstr "Ajuda"
|
||||||
|
|
||||||
|
#: subprojects/extensions-app/data/ui/extensions-window.ui:12
|
||||||
|
msgid "About Extensions"
|
||||||
|
msgstr "Sobre as Extensões"
|
||||||
|
|
||||||
|
#: subprojects/extensions-app/data/ui/extensions-window.ui:27
|
||||||
|
msgid ""
|
||||||
|
"To find and add extensions, visit <a href=\"https://extensions.gnome.org"
|
||||||
|
"\">extensions.gnome.org</a>."
|
||||||
|
msgstr ""
|
||||||
|
"Para encontrar e adicionar extensões, visite <a href=\"https://extensions."
|
||||||
|
"gnome.org\">extensions.gnome.org</a>."
|
||||||
|
|
||||||
|
#: subprojects/extensions-app/data/ui/extensions-window.ui:35
|
||||||
|
msgid "Warning"
|
||||||
|
msgstr "Aviso"
|
||||||
|
|
||||||
|
#: subprojects/extensions-app/data/ui/extensions-window.ui:46
|
||||||
|
msgid ""
|
||||||
|
"Extensions can cause system issues, including performance problems. If you "
|
||||||
|
"encounter problems with your system, it is recommended to disable all "
|
||||||
|
"extensions."
|
||||||
|
msgstr ""
|
||||||
|
"Extensões podem causar problemas no sistema, incluindo problemas de "
|
||||||
|
"desempenho. Se você encontrar problemas com o seu sistema, é recomendável "
|
||||||
|
"desativar todas as extensões."
|
||||||
|
|
||||||
|
#: subprojects/extensions-app/data/ui/extensions-window.ui:134
|
||||||
|
msgid "Manually Installed"
|
||||||
|
msgstr "Instalada manualmente"
|
||||||
|
|
||||||
|
#: subprojects/extensions-app/data/ui/extensions-window.ui:158
|
||||||
|
msgid "Built-In"
|
||||||
|
msgstr "Interna"
|
||||||
|
|
||||||
|
#: subprojects/extensions-app/data/ui/extensions-window.ui:199
|
||||||
|
msgid "No Installed Extensions"
|
||||||
|
msgstr "Nenhuma extensão instalada"
|
||||||
|
|
||||||
|
#: subprojects/extensions-app/data/ui/extensions-window.ui:235
|
||||||
|
msgid ""
|
||||||
|
"We’re very sorry, but it was not possible to get the list of installed "
|
||||||
|
"extensions. Make sure you are logged into GNOME and try again."
|
||||||
|
msgstr ""
|
||||||
|
"Sentimos muito, mas não foi possível obter a lista de extensões instaladas. "
|
||||||
|
"Certifique-se de estar em uma sessão do GNOME e tente novamente."
|
||||||
|
|
||||||
|
#: subprojects/extensions-app/data/ui/extensions-window.ui:288
|
||||||
|
msgid "Log Out…"
|
||||||
|
msgstr "Encerrar sessão…"
|
||||||
|
|
||||||
#. Translators: a file path to an extension directory
|
#. Translators: a file path to an extension directory
|
||||||
#: subprojects/extensions-tool/src/command-create.c:125
|
#: subprojects/extensions-tool/src/command-create.c:125
|
||||||
#, c-format
|
#, c-format
|
||||||
@ -2860,6 +2856,9 @@ msgstr[1] "%u entradas"
|
|||||||
msgid "System Sounds"
|
msgid "System Sounds"
|
||||||
msgstr "Sons do sistema"
|
msgstr "Sons do sistema"
|
||||||
|
|
||||||
|
#~ msgid "Copy Error"
|
||||||
|
#~ msgstr "Copiar erro"
|
||||||
|
|
||||||
#~| msgid "Username: "
|
#~| msgid "Username: "
|
||||||
#~ msgid "Username…"
|
#~ msgid "Username…"
|
||||||
#~ msgstr "Nome de usuário…"
|
#~ msgstr "Nome de usuário…"
|
||||||
|
442
po/sr.po
442
po/sr.po
@ -5,25 +5,26 @@
|
|||||||
# Translators:
|
# Translators:
|
||||||
# Милош Поповић <gpopac@gmail.com>, 2010—2011.
|
# Милош Поповић <gpopac@gmail.com>, 2010—2011.
|
||||||
# Мирослав Николић <miroslavnikolic@rocketmail.com>, 2011—2017.
|
# Мирослав Николић <miroslavnikolic@rocketmail.com>, 2011—2017.
|
||||||
# Марко М. Костић <marko.m.kostic@gmail.com>, 2016.
|
|
||||||
# Борисав Живановић <borisavzivanovic@gmail.com>, 2017—2018.
|
# Борисав Живановић <borisavzivanovic@gmail.com>, 2017—2018.
|
||||||
|
# Марко М. Костић <marko.m.kostic@gmail.com>, 2016-2020.
|
||||||
|
#
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: gnome-shell master\n"
|
"Project-Id-Version: gnome-shell master\n"
|
||||||
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gnome-shell/issues\n"
|
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gnome-shell/issues\n"
|
||||||
"POT-Creation-Date: 2020-03-19 14:34+0000\n"
|
"POT-Creation-Date: 2020-03-31 07:15+0000\n"
|
||||||
"PO-Revision-Date: 2020-03-21 15:30+0100\n"
|
"PO-Revision-Date: 2020-04-02 21:42+0200\n"
|
||||||
"Last-Translator: Марко М. Костић <marko.m.kostic@gmail.com>\n"
|
"Last-Translator: Марко М. Костић <marko.m.kostic@gmail.com>\n"
|
||||||
"Language-Team: српски <gnome-sr@googlegroups.org>\n"
|
"Language-Team: Serbian <gnome-sr@googlegroups.org>\n"
|
||||||
"Language: sr\n"
|
"Language: sr\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=4; plural=n==1? 3 : n%10==1 && n%100!=11 ? 0 : n"
|
"Plural-Forms: nplurals=4; plural=n==1? 3 : n%10==1 && n%100!=11 ? 0 : n"
|
||||||
"%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
|
"%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2\n"
|
||||||
"X-Project-Style: gnome\n"
|
"X-Project-Style: gnome\n"
|
||||||
"X-Poedit-Bookmarks: -1,167,-1,-1,-1,-1,-1,-1,-1,-1\n"
|
"X-Poedit-Bookmarks: -1,167,-1,-1,-1,-1,-1,-1,-1,-1\n"
|
||||||
"X-Generator: Poedit 2.3\n"
|
"X-Generator: Gtranslator 3.36.0\n"
|
||||||
|
|
||||||
#: data/50-gnome-shell-system.xml:6
|
#: data/50-gnome-shell-system.xml:6
|
||||||
msgid "System"
|
msgid "System"
|
||||||
@ -67,7 +68,7 @@ msgid ""
|
|||||||
"dialog."
|
"dialog."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Дозвољава приступ унутрашњем отклањању грешака и алатима за праћење "
|
"Дозвољава приступ унутрашњем отклањању грешака и алатима за праћење "
|
||||||
"коришћењем „Alt-F2“ прозорчета."
|
"коришћењем „Alt-F2“ прозорчета"
|
||||||
|
|
||||||
#: data/org.gnome.shell.gschema.xml.in:16
|
#: data/org.gnome.shell.gschema.xml.in:16
|
||||||
msgid "UUIDs of extensions to enable"
|
msgid "UUIDs of extensions to enable"
|
||||||
@ -389,71 +390,12 @@ msgstr "Застој првог плана се мења у режиму миш
|
|||||||
msgid "Network Login"
|
msgid "Network Login"
|
||||||
msgstr "Мрежна пријава"
|
msgstr "Мрежна пријава"
|
||||||
|
|
||||||
#: js/extensionPrefs/data/metainfo/org.gnome.Extensions.metainfo.xml.in:5
|
#: js/dbusServices/extensions/ui/extension-prefs-dialog.ui:36
|
||||||
#: js/extensionPrefs/data/org.gnome.Extensions.desktop.in.in:4
|
#: subprojects/extensions-app/data/ui/extensions-window.ui:223
|
||||||
#: js/extensionPrefs/js/main.js:242
|
|
||||||
#: js/extensionPrefs/data/ui/extensions-window.ui:61
|
|
||||||
msgid "Extensions"
|
|
||||||
msgstr "Проширења"
|
|
||||||
|
|
||||||
#: js/extensionPrefs/data/metainfo/org.gnome.Extensions.metainfo.xml.in:6
|
|
||||||
#: js/extensionPrefs/js/main.js:243
|
|
||||||
msgid "Manage your GNOME Extensions"
|
|
||||||
msgstr "Подесите проширења Гнома"
|
|
||||||
|
|
||||||
#: js/extensionPrefs/data/metainfo/org.gnome.Extensions.metainfo.xml.in:35
|
|
||||||
msgid ""
|
|
||||||
"GNOME Extensions handles updating extensions, configuring extension "
|
|
||||||
"preferences and removing or disabling unwanted extensions."
|
|
||||||
msgstr ""
|
|
||||||
"Гномова проширења руководе ажурирањем проширења, подешавањем поставки "
|
|
||||||
"проширења и уклањањем или онемогућавањем проширења."
|
|
||||||
|
|
||||||
#: js/extensionPrefs/data/org.gnome.Extensions.desktop.in.in:7
|
|
||||||
msgid "Configure GNOME Shell Extensions"
|
|
||||||
msgstr "Подесите проширења Гномове шкољке"
|
|
||||||
|
|
||||||
#: js/extensionPrefs/js/main.js:164
|
|
||||||
#, javascript-format
|
|
||||||
msgid "Remove “%s”?"
|
|
||||||
msgstr "Уклонити „%s“?"
|
|
||||||
|
|
||||||
#: js/extensionPrefs/js/main.js:165
|
|
||||||
msgid ""
|
|
||||||
"If you remove the extension, you need to return to download it if you want "
|
|
||||||
"to enable it again"
|
|
||||||
msgstr ""
|
|
||||||
"Уколико уклоните проширење, мораћете га поново преузети да бисте га поново "
|
|
||||||
"омогућили"
|
|
||||||
|
|
||||||
#: js/extensionPrefs/js/main.js:168 js/gdm/authPrompt.js:135
|
|
||||||
#: js/ui/audioDeviceSelection.js:57 js/ui/components/networkAgent.js:109
|
|
||||||
#: js/ui/components/polkitAgent.js:139 js/ui/endSessionDialog.js:374
|
|
||||||
#: js/ui/extensionDownloader.js:177 js/ui/shellMountOperation.js:376
|
|
||||||
#: js/ui/shellMountOperation.js:386 js/ui/status/network.js:913
|
|
||||||
msgid "Cancel"
|
|
||||||
msgstr "Откажи"
|
|
||||||
|
|
||||||
#: js/extensionPrefs/js/main.js:169
|
|
||||||
msgid "Remove"
|
|
||||||
msgstr "Уклони"
|
|
||||||
|
|
||||||
#: js/extensionPrefs/js/main.js:241
|
|
||||||
msgid "translator-credits"
|
|
||||||
msgstr ""
|
|
||||||
"Мирослав Николић <miroslavnikolic@rocketmail.com>\n"
|
|
||||||
"Милош Поповић <gpopac@gmail.com>\n"
|
|
||||||
"Борисав Живановић <borisavzivanovic@gmail.com>\n"
|
|
||||||
"Марко М. Костић <marko.m.kostic@gmail.com>\n"
|
|
||||||
"\n"
|
|
||||||
" https://гном.срб/ — превд пројекта Гном на српски језик"
|
|
||||||
|
|
||||||
#: js/extensionPrefs/js/main.js:285
|
|
||||||
#: js/extensionPrefs/data/ui/extensions-window.ui:223
|
|
||||||
msgid "Something’s gone wrong"
|
msgid "Something’s gone wrong"
|
||||||
msgstr "Нешто је пошло наопако"
|
msgstr "Нешто је пошло наопако"
|
||||||
|
|
||||||
#: js/extensionPrefs/js/main.js:292
|
#: js/dbusServices/extensions/ui/extension-prefs-dialog.ui:48
|
||||||
msgid ""
|
msgid ""
|
||||||
"We’re very sorry, but there’s been a problem: the settings for this "
|
"We’re very sorry, but there’s been a problem: the settings for this "
|
||||||
"extension can’t be displayed. We recommend that you report the issue to the "
|
"extension can’t be displayed. We recommend that you report the issue to the "
|
||||||
@ -462,107 +404,25 @@ msgstr ""
|
|||||||
"Веома нам је жао али се догодио проблем, не можемо приказати подешавања за "
|
"Веома нам је жао али се догодио проблем, не можемо приказати подешавања за "
|
||||||
"ово проширење. Предлажемо вам да пријавите овај проблем творцима проширења."
|
"ово проширење. Предлажемо вам да пријавите овај проблем творцима проширења."
|
||||||
|
|
||||||
#: js/extensionPrefs/js/main.js:299
|
#: js/dbusServices/extensions/ui/extension-prefs-dialog.ui:82
|
||||||
msgid "Technical Details"
|
msgid "Technical Details"
|
||||||
msgstr "Техничке појединости"
|
msgstr "Техничке појединости"
|
||||||
|
|
||||||
#: js/extensionPrefs/js/main.js:334
|
#: js/dbusServices/extensions/ui/extension-prefs-dialog.ui:165
|
||||||
msgid "Copy Error"
|
|
||||||
msgstr "Грешка при копирању"
|
|
||||||
|
|
||||||
#: js/extensionPrefs/js/main.js:361
|
|
||||||
msgid "Homepage"
|
msgid "Homepage"
|
||||||
msgstr "Матична страна"
|
msgstr "Матична страна"
|
||||||
|
|
||||||
#: js/extensionPrefs/js/main.js:362
|
#: js/dbusServices/extensions/ui/extension-prefs-dialog.ui:166
|
||||||
msgid "Visit extension homepage"
|
msgid "Visit extension homepage"
|
||||||
msgstr "Посети матичну страну проширењ"
|
msgstr "Посети матичну страну проширењ"
|
||||||
|
|
||||||
#: js/extensionPrefs/js/main.js:479
|
#: js/gdm/authPrompt.js:135 js/ui/audioDeviceSelection.js:57
|
||||||
#, javascript-format
|
#: js/ui/components/networkAgent.js:109 js/ui/components/polkitAgent.js:139
|
||||||
msgid "%d extension will be updated on next login."
|
#: js/ui/endSessionDialog.js:374 js/ui/extensionDownloader.js:181
|
||||||
msgid_plural "%d extensions will be updated on next login."
|
#: js/ui/shellMountOperation.js:376 js/ui/shellMountOperation.js:386
|
||||||
msgstr[0] "%d проширење биће ажурирано током следећег пријављивања."
|
#: js/ui/status/network.js:913 subprojects/extensions-app/js/main.js:148
|
||||||
msgstr[1] "%d проширења биће ажурирана током следећег пријављивања."
|
msgid "Cancel"
|
||||||
msgstr[2] "%d проширења биће ажурирана током следећег пријављивања."
|
msgstr "Откажи"
|
||||||
msgstr[3] "Једно проширење биће ажурирано током следећег пријављивања."
|
|
||||||
|
|
||||||
#: js/extensionPrefs/data/ui/extension-row.ui:100
|
|
||||||
#: subprojects/extensions-tool/src/command-create.c:211
|
|
||||||
#: subprojects/extensions-tool/src/main.c:173
|
|
||||||
msgid "Description"
|
|
||||||
msgstr "Опис"
|
|
||||||
|
|
||||||
#: js/extensionPrefs/data/ui/extension-row.ui:123
|
|
||||||
#: subprojects/extensions-tool/src/main.c:185
|
|
||||||
msgid "Version"
|
|
||||||
msgstr "Издање"
|
|
||||||
|
|
||||||
#: js/extensionPrefs/data/ui/extension-row.ui:151
|
|
||||||
msgid "Author"
|
|
||||||
msgstr "Творац"
|
|
||||||
|
|
||||||
#: js/extensionPrefs/data/ui/extension-row.ui:175
|
|
||||||
msgid "Website"
|
|
||||||
msgstr "Веб страница"
|
|
||||||
|
|
||||||
#: js/extensionPrefs/data/ui/extension-row.ui:192
|
|
||||||
msgid "Remove…"
|
|
||||||
msgstr "Уклони…"
|
|
||||||
|
|
||||||
#: js/extensionPrefs/data/ui/extensions-window.ui:8
|
|
||||||
msgid "Help"
|
|
||||||
msgstr "Помоћ"
|
|
||||||
|
|
||||||
#: js/extensionPrefs/data/ui/extensions-window.ui:12
|
|
||||||
msgid "About Extensions"
|
|
||||||
msgstr "О Проширењима"
|
|
||||||
|
|
||||||
#: js/extensionPrefs/data/ui/extensions-window.ui:27
|
|
||||||
msgid ""
|
|
||||||
"To find and add extensions, visit <a href=\"https://extensions.gnome.org"
|
|
||||||
"\">extensions.gnome.org</a>."
|
|
||||||
msgstr ""
|
|
||||||
"Да бисте пронашли и додали проширења, посетите страницу <a href=\"https://"
|
|
||||||
"extensions.gnome.org\">extensions.gnome.org</a>."
|
|
||||||
|
|
||||||
#: js/extensionPrefs/data/ui/extensions-window.ui:35
|
|
||||||
msgid "Warning"
|
|
||||||
msgstr "Упозорење"
|
|
||||||
|
|
||||||
#: js/extensionPrefs/data/ui/extensions-window.ui:46
|
|
||||||
msgid ""
|
|
||||||
"Extensions can cause system issues, including performance problems. If you "
|
|
||||||
"encounter problems with your system, it is recommended to disable all "
|
|
||||||
"extensions."
|
|
||||||
msgstr ""
|
|
||||||
"Проширења могу утицати на стабилност система, укључујући и на делотворност. "
|
|
||||||
"Уколико приметите проблеме у раду, препоручујемо да онемогућите сва "
|
|
||||||
"проширења."
|
|
||||||
|
|
||||||
#: js/extensionPrefs/data/ui/extensions-window.ui:134
|
|
||||||
msgid "Manually Installed"
|
|
||||||
msgstr "Ручно инсталирана"
|
|
||||||
|
|
||||||
#: js/extensionPrefs/data/ui/extensions-window.ui:158
|
|
||||||
msgid "Built-In"
|
|
||||||
msgstr "Уграђена"
|
|
||||||
|
|
||||||
#: js/extensionPrefs/data/ui/extensions-window.ui:199
|
|
||||||
msgid "No Installed Extensions"
|
|
||||||
msgstr "Неинсталирана проширења"
|
|
||||||
|
|
||||||
#: js/extensionPrefs/data/ui/extensions-window.ui:235
|
|
||||||
msgid ""
|
|
||||||
"We’re very sorry, but it was not possible to get the list of installed "
|
|
||||||
"extensions. Make sure you are logged into GNOME and try again."
|
|
||||||
msgstr ""
|
|
||||||
"Нажалост, није било могуће добавити списак инсталираних проширења. Проверите "
|
|
||||||
"да ли сте пријављени у Гном и пробајте поново."
|
|
||||||
|
|
||||||
#: js/extensionPrefs/data/ui/extensions-window.ui:288
|
|
||||||
msgid "Log Out…"
|
|
||||||
msgstr "Одјава…"
|
|
||||||
|
|
||||||
#. Cisco LEAP
|
#. Cisco LEAP
|
||||||
#: js/gdm/authPrompt.js:237 js/ui/components/networkAgent.js:204
|
#: js/gdm/authPrompt.js:237 js/ui/components/networkAgent.js:204
|
||||||
@ -866,44 +726,44 @@ msgstr "Забрани приступ"
|
|||||||
msgid "Grant Access"
|
msgid "Grant Access"
|
||||||
msgstr "Дозволи приступ"
|
msgstr "Дозволи приступ"
|
||||||
|
|
||||||
#: js/ui/appDisplay.js:898
|
#: js/ui/appDisplay.js:932
|
||||||
msgid "Unnamed Folder"
|
msgid "Unnamed Folder"
|
||||||
msgstr "Неименована фасцикла"
|
msgstr "Неименована фасцикла"
|
||||||
|
|
||||||
#: js/ui/appDisplay.js:921
|
#: js/ui/appDisplay.js:955
|
||||||
msgid "Frequently used applications will appear here"
|
msgid "Frequently used applications will appear here"
|
||||||
msgstr "Често коришћени програми ће се појавити овде"
|
msgstr "Често коришћени програми ће се појавити овде"
|
||||||
|
|
||||||
#: js/ui/appDisplay.js:1056
|
#: js/ui/appDisplay.js:1090
|
||||||
msgid "Frequent"
|
msgid "Frequent"
|
||||||
msgstr "Често"
|
msgstr "Често"
|
||||||
|
|
||||||
#: js/ui/appDisplay.js:1063
|
#: js/ui/appDisplay.js:1097
|
||||||
msgid "All"
|
msgid "All"
|
||||||
msgstr "Све"
|
msgstr "Све"
|
||||||
|
|
||||||
#. Translators: This is the heading of a list of open windows
|
#. Translators: This is the heading of a list of open windows
|
||||||
#: js/ui/appDisplay.js:2446 js/ui/panel.js:75
|
#: js/ui/appDisplay.js:2473 js/ui/panel.js:75
|
||||||
msgid "Open Windows"
|
msgid "Open Windows"
|
||||||
msgstr "Отвори прозоре"
|
msgstr "Отвори прозоре"
|
||||||
|
|
||||||
#: js/ui/appDisplay.js:2466 js/ui/panel.js:82
|
#: js/ui/appDisplay.js:2493 js/ui/panel.js:82
|
||||||
msgid "New Window"
|
msgid "New Window"
|
||||||
msgstr "Нови прозор"
|
msgstr "Нови прозор"
|
||||||
|
|
||||||
#: js/ui/appDisplay.js:2477
|
#: js/ui/appDisplay.js:2504
|
||||||
msgid "Launch using Dedicated Graphics Card"
|
msgid "Launch using Dedicated Graphics Card"
|
||||||
msgstr "Покрени са намењеном графичком картицом"
|
msgstr "Покрени са намењеном графичком картицом"
|
||||||
|
|
||||||
#: js/ui/appDisplay.js:2505 js/ui/dash.js:239
|
#: js/ui/appDisplay.js:2532 js/ui/dash.js:239
|
||||||
msgid "Remove from Favorites"
|
msgid "Remove from Favorites"
|
||||||
msgstr "Уклони из омиљених"
|
msgstr "Уклони из омиљених"
|
||||||
|
|
||||||
#: js/ui/appDisplay.js:2511
|
#: js/ui/appDisplay.js:2538
|
||||||
msgid "Add to Favorites"
|
msgid "Add to Favorites"
|
||||||
msgstr "Додај у омиљене"
|
msgstr "Додај у омиљене"
|
||||||
|
|
||||||
#: js/ui/appDisplay.js:2521 js/ui/panel.js:93
|
#: js/ui/appDisplay.js:2548 js/ui/panel.js:93
|
||||||
msgid "Show Details"
|
msgid "Show Details"
|
||||||
msgstr "Прикажи детаље"
|
msgstr "Прикажи детаље"
|
||||||
|
|
||||||
@ -933,7 +793,7 @@ msgstr "Слушалице"
|
|||||||
msgid "Headset"
|
msgid "Headset"
|
||||||
msgstr "Слушалице са микрофоном"
|
msgstr "Слушалице са микрофоном"
|
||||||
|
|
||||||
#: js/ui/audioDeviceSelection.js:68 js/ui/status/volume.js:269
|
#: js/ui/audioDeviceSelection.js:68 js/ui/status/volume.js:270
|
||||||
msgid "Microphone"
|
msgid "Microphone"
|
||||||
msgstr "Микрофон"
|
msgstr "Микрофон"
|
||||||
|
|
||||||
@ -1074,7 +934,7 @@ msgstr "Без догађаја"
|
|||||||
msgid "Do Not Disturb"
|
msgid "Do Not Disturb"
|
||||||
msgstr "Не узнемиравај"
|
msgstr "Не узнемиравај"
|
||||||
|
|
||||||
#: js/ui/calendar.js:1171
|
#: js/ui/calendar.js:1176
|
||||||
msgid "Clear"
|
msgid "Clear"
|
||||||
msgstr "Очисти"
|
msgstr "Очисти"
|
||||||
|
|
||||||
@ -1221,7 +1081,7 @@ msgstr "Погрешили сте! Покушајте поново."
|
|||||||
|
|
||||||
#. Translators: this is the other person changing their old IM name to their new
|
#. Translators: this is the other person changing their old IM name to their new
|
||||||
#. IM name.
|
#. IM name.
|
||||||
#: js/ui/components/telepathyClient.js:787
|
#: js/ui/components/telepathyClient.js:823
|
||||||
#, javascript-format
|
#, javascript-format
|
||||||
msgid "%s is now known as %s"
|
msgid "%s is now known as %s"
|
||||||
msgstr "„%s“ је сада познат као „%s“"
|
msgstr "„%s“ је сада познат као „%s“"
|
||||||
@ -1265,38 +1125,38 @@ msgstr "Светски сатови…"
|
|||||||
msgid "World Clocks"
|
msgid "World Clocks"
|
||||||
msgstr "Светски сатови"
|
msgstr "Светски сатови"
|
||||||
|
|
||||||
#: js/ui/dateMenu.js:279
|
#: js/ui/dateMenu.js:289
|
||||||
msgid "Weather"
|
msgid "Weather"
|
||||||
msgstr "Временска прогноза"
|
msgstr "Временска прогноза"
|
||||||
|
|
||||||
#: js/ui/dateMenu.js:394
|
#: js/ui/dateMenu.js:418
|
||||||
msgid "Select a location…"
|
msgid "Select a location…"
|
||||||
msgstr "Изаберите место…"
|
msgstr "Изаберите место…"
|
||||||
|
|
||||||
#: js/ui/dateMenu.js:407
|
#: js/ui/dateMenu.js:426
|
||||||
msgid "Loading…"
|
msgid "Loading…"
|
||||||
msgstr "Учитавам…"
|
msgstr "Учитавам…"
|
||||||
|
|
||||||
#: js/ui/dateMenu.js:417
|
#: js/ui/dateMenu.js:436
|
||||||
msgid "Go online for weather information"
|
msgid "Go online for weather information"
|
||||||
msgstr "Идите на мрежу за податке о временској прогнози."
|
msgstr "Идите на мрежу за податке о временској прогнози."
|
||||||
|
|
||||||
#: js/ui/dateMenu.js:419
|
#: js/ui/dateMenu.js:438
|
||||||
msgid "Weather information is currently unavailable"
|
msgid "Weather information is currently unavailable"
|
||||||
msgstr "Подаци о временској прогнози тренутно нису доступни."
|
msgstr "Подаци о временској прогнози тренутно нису доступни."
|
||||||
|
|
||||||
#: js/ui/endSessionDialog.js:37
|
#: js/ui/endSessionDialog.js:39
|
||||||
#, javascript-format
|
#, javascript-format
|
||||||
msgctxt "title"
|
msgctxt "title"
|
||||||
msgid "Log Out %s"
|
msgid "Log Out %s"
|
||||||
msgstr "Одјави корисника „%s“"
|
msgstr "Одјави корисника „%s“"
|
||||||
|
|
||||||
#: js/ui/endSessionDialog.js:38
|
#: js/ui/endSessionDialog.js:40
|
||||||
msgctxt "title"
|
msgctxt "title"
|
||||||
msgid "Log Out"
|
msgid "Log Out"
|
||||||
msgstr "Одјави ме"
|
msgstr "Одјави ме"
|
||||||
|
|
||||||
#: js/ui/endSessionDialog.js:40
|
#: js/ui/endSessionDialog.js:42
|
||||||
#, javascript-format
|
#, javascript-format
|
||||||
msgid "%s will be logged out automatically in %d second."
|
msgid "%s will be logged out automatically in %d second."
|
||||||
msgid_plural "%s will be logged out automatically in %d seconds."
|
msgid_plural "%s will be logged out automatically in %d seconds."
|
||||||
@ -1305,7 +1165,7 @@ msgstr[1] "%s ће бити одјављен за %d секунде."
|
|||||||
msgstr[2] "%s ће бити одјављен за %d секунди."
|
msgstr[2] "%s ће бити одјављен за %d секунди."
|
||||||
msgstr[3] "%s ће бити одјављен за %d секунду."
|
msgstr[3] "%s ће бити одјављен за %d секунду."
|
||||||
|
|
||||||
#: js/ui/endSessionDialog.js:45
|
#: js/ui/endSessionDialog.js:47
|
||||||
#, javascript-format
|
#, javascript-format
|
||||||
msgid "You will be logged out automatically in %d second."
|
msgid "You will be logged out automatically in %d second."
|
||||||
msgid_plural "You will be logged out automatically in %d seconds."
|
msgid_plural "You will be logged out automatically in %d seconds."
|
||||||
@ -1314,22 +1174,22 @@ msgstr[1] "Бићете одјављени за %d секунде."
|
|||||||
msgstr[2] "Бићете одјављени за %d секунди."
|
msgstr[2] "Бићете одјављени за %d секунди."
|
||||||
msgstr[3] "Бићете одјављени за %d секунду."
|
msgstr[3] "Бићете одјављени за %d секунду."
|
||||||
|
|
||||||
#: js/ui/endSessionDialog.js:51
|
#: js/ui/endSessionDialog.js:53
|
||||||
msgctxt "button"
|
msgctxt "button"
|
||||||
msgid "Log Out"
|
msgid "Log Out"
|
||||||
msgstr "Одјави"
|
msgstr "Одјави"
|
||||||
|
|
||||||
#: js/ui/endSessionDialog.js:56
|
#: js/ui/endSessionDialog.js:58
|
||||||
msgctxt "title"
|
msgctxt "title"
|
||||||
msgid "Power Off"
|
msgid "Power Off"
|
||||||
msgstr "Искључи"
|
msgstr "Искључи"
|
||||||
|
|
||||||
#: js/ui/endSessionDialog.js:57
|
#: js/ui/endSessionDialog.js:59
|
||||||
msgctxt "title"
|
msgctxt "title"
|
||||||
msgid "Install Updates & Power Off"
|
msgid "Install Updates & Power Off"
|
||||||
msgstr "Инсталирај освежења и искључи"
|
msgstr "Инсталирај освежења и искључи"
|
||||||
|
|
||||||
#: js/ui/endSessionDialog.js:59
|
#: js/ui/endSessionDialog.js:61
|
||||||
#, javascript-format
|
#, javascript-format
|
||||||
msgid "The system will power off automatically in %d second."
|
msgid "The system will power off automatically in %d second."
|
||||||
msgid_plural "The system will power off automatically in %d seconds."
|
msgid_plural "The system will power off automatically in %d seconds."
|
||||||
@ -1338,27 +1198,27 @@ msgstr[1] "Рачунар ће се искључити за %d секунде."
|
|||||||
msgstr[2] "Рачунар ће се искључити за %d секунди."
|
msgstr[2] "Рачунар ће се искључити за %d секунди."
|
||||||
msgstr[3] "Рачунар ће се искључити за %d секунду."
|
msgstr[3] "Рачунар ће се искључити за %d секунду."
|
||||||
|
|
||||||
#: js/ui/endSessionDialog.js:63
|
#: js/ui/endSessionDialog.js:65
|
||||||
msgctxt "checkbox"
|
msgctxt "checkbox"
|
||||||
msgid "Install pending software updates"
|
msgid "Install pending software updates"
|
||||||
msgstr "Инсталирај освежења софтвера на чекању"
|
msgstr "Инсталирај освежења софтвера на чекању"
|
||||||
|
|
||||||
#: js/ui/endSessionDialog.js:66 js/ui/endSessionDialog.js:82
|
#: js/ui/endSessionDialog.js:68 js/ui/endSessionDialog.js:84
|
||||||
msgctxt "button"
|
msgctxt "button"
|
||||||
msgid "Restart"
|
msgid "Restart"
|
||||||
msgstr "Поново покрени"
|
msgstr "Поново покрени"
|
||||||
|
|
||||||
#: js/ui/endSessionDialog.js:68
|
#: js/ui/endSessionDialog.js:70
|
||||||
msgctxt "button"
|
msgctxt "button"
|
||||||
msgid "Power Off"
|
msgid "Power Off"
|
||||||
msgstr "Искључи"
|
msgstr "Искључи"
|
||||||
|
|
||||||
#: js/ui/endSessionDialog.js:74
|
#: js/ui/endSessionDialog.js:76
|
||||||
msgctxt "title"
|
msgctxt "title"
|
||||||
msgid "Restart"
|
msgid "Restart"
|
||||||
msgstr "Поново покрени"
|
msgstr "Поново покрени"
|
||||||
|
|
||||||
#: js/ui/endSessionDialog.js:76
|
#: js/ui/endSessionDialog.js:78
|
||||||
#, javascript-format
|
#, javascript-format
|
||||||
msgid "The system will restart automatically in %d second."
|
msgid "The system will restart automatically in %d second."
|
||||||
msgid_plural "The system will restart automatically in %d seconds."
|
msgid_plural "The system will restart automatically in %d seconds."
|
||||||
@ -1367,12 +1227,12 @@ msgstr[1] "Систем ће се поново покренути за %d сек
|
|||||||
msgstr[2] "Систем ће се поново покренути за %d секунди."
|
msgstr[2] "Систем ће се поново покренути за %d секунди."
|
||||||
msgstr[3] "Систем ће се поново покренути за %d секунду."
|
msgstr[3] "Систем ће се поново покренути за %d секунду."
|
||||||
|
|
||||||
#: js/ui/endSessionDialog.js:89
|
#: js/ui/endSessionDialog.js:91
|
||||||
msgctxt "title"
|
msgctxt "title"
|
||||||
msgid "Restart & Install Updates"
|
msgid "Restart & Install Updates"
|
||||||
msgstr "Поново покрени и инсталирај ажурирања"
|
msgstr "Поново покрени и инсталирај ажурирања"
|
||||||
|
|
||||||
#: js/ui/endSessionDialog.js:91
|
#: js/ui/endSessionDialog.js:93
|
||||||
#, javascript-format
|
#, javascript-format
|
||||||
msgid "The system will automatically restart and install updates in %d second."
|
msgid "The system will automatically restart and install updates in %d second."
|
||||||
msgid_plural ""
|
msgid_plural ""
|
||||||
@ -1386,22 +1246,22 @@ msgstr[2] ""
|
|||||||
msgstr[3] ""
|
msgstr[3] ""
|
||||||
"Систем ће се сам поново покренути и инсталирати ажурирања за %d секунду."
|
"Систем ће се сам поново покренути и инсталирати ажурирања за %d секунду."
|
||||||
|
|
||||||
#: js/ui/endSessionDialog.js:97 js/ui/endSessionDialog.js:116
|
#: js/ui/endSessionDialog.js:99 js/ui/endSessionDialog.js:118
|
||||||
msgctxt "button"
|
msgctxt "button"
|
||||||
msgid "Restart & Install"
|
msgid "Restart & Install"
|
||||||
msgstr "Поново покрени и инсталирај"
|
msgstr "Поново покрени и инсталирај"
|
||||||
|
|
||||||
#: js/ui/endSessionDialog.js:98
|
#: js/ui/endSessionDialog.js:100
|
||||||
msgctxt "button"
|
msgctxt "button"
|
||||||
msgid "Install & Power Off"
|
msgid "Install & Power Off"
|
||||||
msgstr "Инсталирај и искључи"
|
msgstr "Инсталирај и искључи"
|
||||||
|
|
||||||
#: js/ui/endSessionDialog.js:99
|
#: js/ui/endSessionDialog.js:101
|
||||||
msgctxt "checkbox"
|
msgctxt "checkbox"
|
||||||
msgid "Power off after updates are installed"
|
msgid "Power off after updates are installed"
|
||||||
msgstr "Искључи након инсталирања освежења"
|
msgstr "Искључи након инсталирања освежења"
|
||||||
|
|
||||||
#: js/ui/endSessionDialog.js:106
|
#: js/ui/endSessionDialog.js:108
|
||||||
msgctxt "title"
|
msgctxt "title"
|
||||||
msgid "Restart & Install Upgrade"
|
msgid "Restart & Install Upgrade"
|
||||||
msgstr "Поново покрени и инсталирај надоградњу"
|
msgstr "Поново покрени и инсталирај надоградњу"
|
||||||
@ -1409,7 +1269,7 @@ msgstr "Поново покрени и инсталирај надоградњу
|
|||||||
#. Translators: This is the text displayed for system upgrades in the
|
#. Translators: This is the text displayed for system upgrades in the
|
||||||
#. shut down dialog. First %s gets replaced with the distro name and
|
#. shut down dialog. First %s gets replaced with the distro name and
|
||||||
#. second %s with the distro version to upgrade to
|
#. second %s with the distro version to upgrade to
|
||||||
#: js/ui/endSessionDialog.js:111
|
#: js/ui/endSessionDialog.js:113
|
||||||
#, javascript-format
|
#, javascript-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"%s %s will be installed after restart. Upgrade installation can take a long "
|
"%s %s will be installed after restart. Upgrade installation can take a long "
|
||||||
@ -1419,15 +1279,15 @@ msgstr ""
|
|||||||
"понекад може да потраје: проверите да ли сте направили резерву ваших важних "
|
"понекад може да потраје: проверите да ли сте направили резерву ваших важних "
|
||||||
"података и да ли је рачунар прикључен на мрежно напајање."
|
"података и да ли је рачунар прикључен на мрежно напајање."
|
||||||
|
|
||||||
#: js/ui/endSessionDialog.js:259
|
#: js/ui/endSessionDialog.js:261
|
||||||
msgid "Running on battery power: Please plug in before installing updates."
|
msgid "Running on battery power: Please plug in before installing updates."
|
||||||
msgstr "На батерији сте, прикључите мрежно напајање пре инсталирања ажурирања."
|
msgstr "На батерији сте, прикључите мрежно напајање пре инсталирања ажурирања."
|
||||||
|
|
||||||
#: js/ui/endSessionDialog.js:268
|
#: js/ui/endSessionDialog.js:270
|
||||||
msgid "Some applications are busy or have unsaved work"
|
msgid "Some applications are busy or have unsaved work"
|
||||||
msgstr "Неки програми су заузети или имају несачувани рад"
|
msgstr "Неки програми су заузети или имају несачувани рад"
|
||||||
|
|
||||||
#: js/ui/endSessionDialog.js:273
|
#: js/ui/endSessionDialog.js:275
|
||||||
msgid "Other users are logged in"
|
msgid "Other users are logged in"
|
||||||
msgstr "Други корисници су пријављени"
|
msgstr "Други корисници су пријављени"
|
||||||
|
|
||||||
@ -1443,24 +1303,24 @@ msgstr "%s (удаљено)"
|
|||||||
msgid "%s (console)"
|
msgid "%s (console)"
|
||||||
msgstr "%s (љуска)"
|
msgstr "%s (љуска)"
|
||||||
|
|
||||||
#: js/ui/extensionDownloader.js:181
|
#: js/ui/extensionDownloader.js:185
|
||||||
msgid "Install"
|
msgid "Install"
|
||||||
msgstr "Инсталирај"
|
msgstr "Инсталирај"
|
||||||
|
|
||||||
#: js/ui/extensionDownloader.js:187
|
#: js/ui/extensionDownloader.js:191
|
||||||
msgid "Install Extension"
|
msgid "Install Extension"
|
||||||
msgstr "Инсталирај проширење"
|
msgstr "Инсталирај проширење"
|
||||||
|
|
||||||
#: js/ui/extensionDownloader.js:188
|
#: js/ui/extensionDownloader.js:192
|
||||||
#, javascript-format
|
#, javascript-format
|
||||||
msgid "Download and install “%s” from extensions.gnome.org?"
|
msgid "Download and install “%s” from extensions.gnome.org?"
|
||||||
msgstr "Да преузмем и да инсталирам „%s“ са „extensions.gnome.org“-а?"
|
msgstr "Да преузмем и да инсталирам „%s“ са „extensions.gnome.org“-а?"
|
||||||
|
|
||||||
#: js/ui/extensionSystem.js:228
|
#: js/ui/extensionSystem.js:233
|
||||||
msgid "Extension Updates Available"
|
msgid "Extension Updates Available"
|
||||||
msgstr "Доступна су ажурирања проширења"
|
msgstr "Доступна су ажурирања проширења"
|
||||||
|
|
||||||
#: js/ui/extensionSystem.js:229
|
#: js/ui/extensionSystem.js:234
|
||||||
msgid "Extension updates are ready to be installed."
|
msgid "Extension updates are ready to be installed."
|
||||||
msgstr "Ажурирања проширења су доступна за инсталирање."
|
msgstr "Ажурирања проширења су доступна за инсталирање."
|
||||||
|
|
||||||
@ -1607,11 +1467,11 @@ msgstr "Прикажи код"
|
|||||||
msgid "Web Page"
|
msgid "Web Page"
|
||||||
msgstr "Веб страница"
|
msgstr "Веб страница"
|
||||||
|
|
||||||
#: js/ui/main.js:274
|
#: js/ui/main.js:277
|
||||||
msgid "Logged in as a privileged user"
|
msgid "Logged in as a privileged user"
|
||||||
msgstr "Пријављен као повлашћен корисник"
|
msgstr "Пријављен као повлашћен корисник"
|
||||||
|
|
||||||
#: js/ui/main.js:275
|
#: js/ui/main.js:278
|
||||||
msgid ""
|
msgid ""
|
||||||
"Running a session as a privileged user should be avoided for security "
|
"Running a session as a privileged user should be avoided for security "
|
||||||
"reasons. If possible, you should log in as a normal user."
|
"reasons. If possible, you should log in as a normal user."
|
||||||
@ -1619,15 +1479,15 @@ msgstr ""
|
|||||||
"Покретање сесије под повлашћеним корисничким налогом треба избегавати из "
|
"Покретање сесије под повлашћеним корисничким налогом треба избегавати из "
|
||||||
"безбедносних разлога. Ако је то могуће, пријавите се као обичан корисник."
|
"безбедносних разлога. Ако је то могуће, пријавите се као обичан корисник."
|
||||||
|
|
||||||
#: js/ui/main.js:281
|
#: js/ui/main.js:317
|
||||||
msgid "Screen Lock disabled"
|
msgid "Screen Lock disabled"
|
||||||
msgstr "Закључавање екрана онемогућено"
|
msgstr "Закључавање екрана онемогућено"
|
||||||
|
|
||||||
#: js/ui/main.js:282
|
#: js/ui/main.js:318
|
||||||
msgid "Screen Locking requires the GNOME display manager."
|
msgid "Screen Locking requires the GNOME display manager."
|
||||||
msgstr "Потребан је Гномов управник екрана за могућност закључавања екрана."
|
msgstr "Потребан је Гномов управник екрана за могућност закључавања екрана."
|
||||||
|
|
||||||
#: js/ui/messageTray.js:1554
|
#: js/ui/messageTray.js:1551
|
||||||
msgid "System Information"
|
msgid "System Information"
|
||||||
msgstr "Подаци о систему"
|
msgstr "Подаци о систему"
|
||||||
|
|
||||||
@ -1836,13 +1696,13 @@ msgid "The PIM must be a number or empty."
|
|||||||
msgstr "ЛИЧ (PIM) мора бити број или празно."
|
msgstr "ЛИЧ (PIM) мора бити број или празно."
|
||||||
|
|
||||||
#. Translators: %s is the Disks application
|
#. Translators: %s is the Disks application
|
||||||
#: js/ui/shellMountOperation.js:469
|
#: js/ui/shellMountOperation.js:465
|
||||||
#, javascript-format
|
#, javascript-format
|
||||||
msgid "Unable to start %s"
|
msgid "Unable to start %s"
|
||||||
msgstr "Не могу да покренем „%s“"
|
msgstr "Не могу да покренем „%s“"
|
||||||
|
|
||||||
#. Translators: %s is the Disks application
|
#. Translators: %s is the Disks application
|
||||||
#: js/ui/shellMountOperation.js:471
|
#: js/ui/shellMountOperation.js:467
|
||||||
#, javascript-format
|
#, javascript-format
|
||||||
msgid "Couldn’t find the %s application"
|
msgid "Couldn’t find the %s application"
|
||||||
msgstr "Нисам могао наћи програм %s"
|
msgstr "Нисам могао наћи програм %s"
|
||||||
@ -2326,11 +2186,11 @@ msgstr "Грешка у овлашћивању Тандерболта"
|
|||||||
msgid "Could not authorize the Thunderbolt device: %s"
|
msgid "Could not authorize the Thunderbolt device: %s"
|
||||||
msgstr "Не могу да овластим Тандерболт уређај: %s"
|
msgstr "Не могу да овластим Тандерболт уређај: %s"
|
||||||
|
|
||||||
#: js/ui/status/volume.js:150
|
#: js/ui/status/volume.js:151
|
||||||
msgid "Volume changed"
|
msgid "Volume changed"
|
||||||
msgstr "Промена јачине звука"
|
msgstr "Промена јачине звука"
|
||||||
|
|
||||||
#: js/ui/status/volume.js:221
|
#: js/ui/status/volume.js:222
|
||||||
msgid "Volume"
|
msgid "Volume"
|
||||||
msgstr "Јачина звука"
|
msgstr "Јачина звука"
|
||||||
|
|
||||||
@ -2364,23 +2224,23 @@ msgstr "Само уграђени"
|
|||||||
|
|
||||||
#. Translators: This is a time format for a date in
|
#. Translators: This is a time format for a date in
|
||||||
#. long format
|
#. long format
|
||||||
#: js/ui/unlockDialog.js:370
|
#: js/ui/unlockDialog.js:371
|
||||||
msgid "%A %B %-d"
|
msgid "%A %B %-d"
|
||||||
msgstr "%A, %-d. %B"
|
msgstr "%A, %-d. %B"
|
||||||
|
|
||||||
#: js/ui/unlockDialog.js:376
|
#: js/ui/unlockDialog.js:377
|
||||||
msgid "Swipe up to unlock"
|
msgid "Swipe up to unlock"
|
||||||
msgstr "Превуци за откључавање"
|
msgstr "Превуци за откључавање"
|
||||||
|
|
||||||
#: js/ui/unlockDialog.js:377
|
#: js/ui/unlockDialog.js:378
|
||||||
msgid "Click or press a key to unlock"
|
msgid "Click or press a key to unlock"
|
||||||
msgstr "Кликни или притисни тастер за откључавање"
|
msgstr "Кликни или притисни тастер за откључавање"
|
||||||
|
|
||||||
#: js/ui/unlockDialog.js:549
|
#: js/ui/unlockDialog.js:550
|
||||||
msgid "Unlock Window"
|
msgid "Unlock Window"
|
||||||
msgstr "Откључај прозор"
|
msgstr "Откључај прозор"
|
||||||
|
|
||||||
#: js/ui/unlockDialog.js:558
|
#: js/ui/unlockDialog.js:559
|
||||||
msgid "Log in as another user"
|
msgid "Log in as another user"
|
||||||
msgstr "Пријавите се као други корисник"
|
msgstr "Пријавите се као други корисник"
|
||||||
|
|
||||||
@ -2539,6 +2399,143 @@ msgstr "Лозинка не може бити празна"
|
|||||||
msgid "Authentication dialog was dismissed by the user"
|
msgid "Authentication dialog was dismissed by the user"
|
||||||
msgstr "Корисник је одбацио прозорче за потврђивање идентитета"
|
msgstr "Корисник је одбацио прозорче за потврђивање идентитета"
|
||||||
|
|
||||||
|
#: subprojects/extensions-app/data/metainfo/org.gnome.Extensions.metainfo.xml.in:5
|
||||||
|
#: subprojects/extensions-app/data/org.gnome.Extensions.desktop.in.in:4
|
||||||
|
#: subprojects/extensions-app/js/main.js:182
|
||||||
|
#: subprojects/extensions-app/data/ui/extensions-window.ui:61
|
||||||
|
msgid "Extensions"
|
||||||
|
msgstr "Проширења"
|
||||||
|
|
||||||
|
#: subprojects/extensions-app/data/metainfo/org.gnome.Extensions.metainfo.xml.in:6
|
||||||
|
#: subprojects/extensions-app/js/main.js:183
|
||||||
|
msgid "Manage your GNOME Extensions"
|
||||||
|
msgstr "Подесите проширења Гнома"
|
||||||
|
|
||||||
|
#: subprojects/extensions-app/data/metainfo/org.gnome.Extensions.metainfo.xml.in:35
|
||||||
|
msgid ""
|
||||||
|
"GNOME Extensions handles updating extensions, configuring extension "
|
||||||
|
"preferences and removing or disabling unwanted extensions."
|
||||||
|
msgstr ""
|
||||||
|
"Гномова проширења руководе ажурирањем проширења, подешавањем поставки "
|
||||||
|
"проширења и уклањањем или онемогућавањем проширења."
|
||||||
|
|
||||||
|
#: subprojects/extensions-app/data/org.gnome.Extensions.desktop.in.in:7
|
||||||
|
msgid "Configure GNOME Shell Extensions"
|
||||||
|
msgstr "Подесите проширења Гномове шкољке"
|
||||||
|
|
||||||
|
#: subprojects/extensions-app/js/main.js:144
|
||||||
|
#, javascript-format
|
||||||
|
msgid "Remove “%s”?"
|
||||||
|
msgstr "Уклонити „%s“?"
|
||||||
|
|
||||||
|
#: subprojects/extensions-app/js/main.js:145
|
||||||
|
msgid ""
|
||||||
|
"If you remove the extension, you need to return to download it if you want "
|
||||||
|
"to enable it again"
|
||||||
|
msgstr ""
|
||||||
|
"Уколико уклоните проширење, мораћете га поново преузети да бисте га поново "
|
||||||
|
"омогућили"
|
||||||
|
|
||||||
|
#: subprojects/extensions-app/js/main.js:149
|
||||||
|
msgid "Remove"
|
||||||
|
msgstr "Уклони"
|
||||||
|
|
||||||
|
#: subprojects/extensions-app/js/main.js:181
|
||||||
|
msgid "translator-credits"
|
||||||
|
msgstr ""
|
||||||
|
"Мирослав Николић <miroslavnikolic@rocketmail.com>\n"
|
||||||
|
"Милош Поповић <gpopac@gmail.com>\n"
|
||||||
|
"Борисав Живановић <borisavzivanovic@gmail.com>\n"
|
||||||
|
"Марко М. Костић <marko.m.kostic@gmail.com>\n"
|
||||||
|
"\n"
|
||||||
|
" https://гном.срб/ — превод пројекта Гном на српски језик"
|
||||||
|
|
||||||
|
#: subprojects/extensions-app/js/main.js:316
|
||||||
|
#, javascript-format
|
||||||
|
msgid "%d extension will be updated on next login."
|
||||||
|
msgid_plural "%d extensions will be updated on next login."
|
||||||
|
msgstr[0] "%d проширење биће ажурирано током следећег пријављивања."
|
||||||
|
msgstr[1] "%d проширења биће ажурирана током следећег пријављивања."
|
||||||
|
msgstr[2] "%d проширења биће ажурирана током следећег пријављивања."
|
||||||
|
msgstr[3] "Једно проширење биће ажурирано током следећег пријављивања."
|
||||||
|
|
||||||
|
#: subprojects/extensions-app/data/ui/extension-row.ui:100
|
||||||
|
#: subprojects/extensions-tool/src/command-create.c:211
|
||||||
|
#: subprojects/extensions-tool/src/main.c:173
|
||||||
|
msgid "Description"
|
||||||
|
msgstr "Опис"
|
||||||
|
|
||||||
|
#: subprojects/extensions-app/data/ui/extension-row.ui:123
|
||||||
|
#: subprojects/extensions-tool/src/main.c:185
|
||||||
|
msgid "Version"
|
||||||
|
msgstr "Издање"
|
||||||
|
|
||||||
|
#: subprojects/extensions-app/data/ui/extension-row.ui:151
|
||||||
|
msgid "Author"
|
||||||
|
msgstr "Творац"
|
||||||
|
|
||||||
|
#: subprojects/extensions-app/data/ui/extension-row.ui:175
|
||||||
|
msgid "Website"
|
||||||
|
msgstr "Веб страница"
|
||||||
|
|
||||||
|
#: subprojects/extensions-app/data/ui/extension-row.ui:192
|
||||||
|
msgid "Remove…"
|
||||||
|
msgstr "Уклони…"
|
||||||
|
|
||||||
|
#: subprojects/extensions-app/data/ui/extensions-window.ui:8
|
||||||
|
msgid "Help"
|
||||||
|
msgstr "Помоћ"
|
||||||
|
|
||||||
|
#: subprojects/extensions-app/data/ui/extensions-window.ui:12
|
||||||
|
msgid "About Extensions"
|
||||||
|
msgstr "О Проширењима"
|
||||||
|
|
||||||
|
#: subprojects/extensions-app/data/ui/extensions-window.ui:27
|
||||||
|
msgid ""
|
||||||
|
"To find and add extensions, visit <a href=\"https://extensions.gnome.org"
|
||||||
|
"\">extensions.gnome.org</a>."
|
||||||
|
msgstr ""
|
||||||
|
"Да бисте пронашли и додали проширења, посетите страницу <a href=\"https://"
|
||||||
|
"extensions.gnome.org\">extensions.gnome.org</a>."
|
||||||
|
|
||||||
|
#: subprojects/extensions-app/data/ui/extensions-window.ui:35
|
||||||
|
msgid "Warning"
|
||||||
|
msgstr "Упозорење"
|
||||||
|
|
||||||
|
#: subprojects/extensions-app/data/ui/extensions-window.ui:46
|
||||||
|
msgid ""
|
||||||
|
"Extensions can cause system issues, including performance problems. If you "
|
||||||
|
"encounter problems with your system, it is recommended to disable all "
|
||||||
|
"extensions."
|
||||||
|
msgstr ""
|
||||||
|
"Проширења могу утицати на стабилност система, укључујући и на делотворност. "
|
||||||
|
"Уколико приметите проблеме у раду, препоручујемо да онемогућите сва "
|
||||||
|
"проширења."
|
||||||
|
|
||||||
|
#: subprojects/extensions-app/data/ui/extensions-window.ui:134
|
||||||
|
msgid "Manually Installed"
|
||||||
|
msgstr "Ручно инсталирана"
|
||||||
|
|
||||||
|
#: subprojects/extensions-app/data/ui/extensions-window.ui:158
|
||||||
|
msgid "Built-In"
|
||||||
|
msgstr "Уграђена"
|
||||||
|
|
||||||
|
#: subprojects/extensions-app/data/ui/extensions-window.ui:199
|
||||||
|
msgid "No Installed Extensions"
|
||||||
|
msgstr "Неинсталирана проширења"
|
||||||
|
|
||||||
|
#: subprojects/extensions-app/data/ui/extensions-window.ui:235
|
||||||
|
msgid ""
|
||||||
|
"We’re very sorry, but it was not possible to get the list of installed "
|
||||||
|
"extensions. Make sure you are logged into GNOME and try again."
|
||||||
|
msgstr ""
|
||||||
|
"Нажалост, није било могуће добавити списак инсталираних проширења. Проверите "
|
||||||
|
"да ли сте пријављени у Гном и пробајте поново."
|
||||||
|
|
||||||
|
#: subprojects/extensions-app/data/ui/extensions-window.ui:288
|
||||||
|
msgid "Log Out…"
|
||||||
|
msgstr "Одјава…"
|
||||||
|
|
||||||
#. Translators: a file path to an extension directory
|
#. Translators: a file path to an extension directory
|
||||||
#: subprojects/extensions-tool/src/command-create.c:125
|
#: subprojects/extensions-tool/src/command-create.c:125
|
||||||
#, c-format
|
#, c-format
|
||||||
@ -2879,6 +2876,9 @@ msgstr[3] "%u улаз"
|
|||||||
msgid "System Sounds"
|
msgid "System Sounds"
|
||||||
msgstr "Системски звуци"
|
msgstr "Системски звуци"
|
||||||
|
|
||||||
|
#~ msgid "Copy Error"
|
||||||
|
#~ msgstr "Грешка при копирању"
|
||||||
|
|
||||||
#~ msgid "Username…"
|
#~ msgid "Username…"
|
||||||
#~ msgstr "Корисник…"
|
#~ msgstr "Корисник…"
|
||||||
|
|
||||||
|
1935
po/zh_CN.po
1935
po/zh_CN.po
File diff suppressed because it is too large
Load Diff
504
po/zh_TW.po
504
po/zh_TW.po
@ -8,16 +8,16 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: gnome-shell 3.3.90\n"
|
"Project-Id-Version: gnome-shell 3.3.90\n"
|
||||||
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gnome-shell/issues\n"
|
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gnome-shell/issues\n"
|
||||||
"POT-Creation-Date: 2020-02-17 22:27+0000\n"
|
"POT-Creation-Date: 2020-03-31 07:15+0000\n"
|
||||||
"PO-Revision-Date: 2020-02-19 14:32+0800\n"
|
"PO-Revision-Date: 2020-04-01 00:04+0800\n"
|
||||||
"Last-Translator: Yi-Jyun Pan <pan93412@gmail.com>\n"
|
"Last-Translator: Cheng-Chia Tseng <pswo10680@gmail.com>\n"
|
||||||
"Language-Team: Chinese (Taiwan) <zh-l10n@lists.linux.org.tw>\n"
|
"Language-Team: Chinese (Taiwan) <zh-l10n@lists.linux.org.tw>\n"
|
||||||
"Language: zh_TW\n"
|
"Language: zh_TW\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=1; plural=0;\n"
|
"Plural-Forms: nplurals=1; plural=0;\n"
|
||||||
"X-Generator: Poedit 2.2.4\n"
|
"X-Generator: Poedit 2.3\n"
|
||||||
|
|
||||||
#: data/50-gnome-shell-system.xml:6
|
#: data/50-gnome-shell-system.xml:6
|
||||||
msgid "System"
|
msgid "System"
|
||||||
@ -43,15 +43,6 @@ msgstr "顯示所有的應用程式"
|
|||||||
msgid "Open the application menu"
|
msgid "Open the application menu"
|
||||||
msgstr "開啟應用程式選單"
|
msgstr "開啟應用程式選單"
|
||||||
|
|
||||||
#: data/org.gnome.Extensions.desktop.in.in:4 js/extensionPrefs/main.js:218
|
|
||||||
#: js/extensionPrefs/ui/extensions-window.ui:61
|
|
||||||
msgid "Extensions"
|
|
||||||
msgstr "擴充套件"
|
|
||||||
|
|
||||||
#: data/org.gnome.Extensions.desktop.in.in:7
|
|
||||||
msgid "Configure GNOME Shell Extensions"
|
|
||||||
msgstr "設定 GNOME Shell 擴充套件"
|
|
||||||
|
|
||||||
#: data/org.gnome.Shell.desktop.in.in:4
|
#: data/org.gnome.Shell.desktop.in.in:4
|
||||||
msgid "GNOME Shell"
|
msgid "GNOME Shell"
|
||||||
msgstr "GNOME Shell"
|
msgstr "GNOME Shell"
|
||||||
@ -371,42 +362,12 @@ msgstr "在滑鼠模式中延遲焦點變更直到指標停止移動"
|
|||||||
msgid "Network Login"
|
msgid "Network Login"
|
||||||
msgstr "網路登入"
|
msgstr "網路登入"
|
||||||
|
|
||||||
#: js/extensionPrefs/main.js:140
|
#: js/dbusServices/extensions/ui/extension-prefs-dialog.ui:36
|
||||||
#, javascript-format
|
#: subprojects/extensions-app/data/ui/extensions-window.ui:223
|
||||||
msgid "Remove “%s”?"
|
|
||||||
msgstr "移除“%s”?"
|
|
||||||
|
|
||||||
#: js/extensionPrefs/main.js:141
|
|
||||||
msgid ""
|
|
||||||
"If you remove the extension, you need to return to download it if you want "
|
|
||||||
"to enable it again"
|
|
||||||
msgstr "如果您移除擴充套件,如果需要再次啟用,就需要回去重新下載一次"
|
|
||||||
|
|
||||||
#: js/extensionPrefs/main.js:144 js/ui/audioDeviceSelection.js:57
|
|
||||||
#: js/ui/components/networkAgent.js:107 js/ui/components/polkitAgent.js:139
|
|
||||||
#: js/ui/endSessionDialog.js:374 js/ui/extensionDownloader.js:165
|
|
||||||
#: js/ui/shellMountOperation.js:376 js/ui/shellMountOperation.js:386
|
|
||||||
#: js/ui/status/network.js:913
|
|
||||||
msgid "Cancel"
|
|
||||||
msgstr "取消"
|
|
||||||
|
|
||||||
#: js/extensionPrefs/main.js:145
|
|
||||||
msgid "Remove"
|
|
||||||
msgstr "移除"
|
|
||||||
|
|
||||||
#: js/extensionPrefs/main.js:217
|
|
||||||
msgid "translator-credits"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: js/extensionPrefs/main.js:219
|
|
||||||
msgid "Manage your GNOME Extensions"
|
|
||||||
msgstr "管理 GNOME Shell 擴充套件"
|
|
||||||
|
|
||||||
#: js/extensionPrefs/main.js:261 js/extensionPrefs/ui/extensions-window.ui:222
|
|
||||||
msgid "Something’s gone wrong"
|
msgid "Something’s gone wrong"
|
||||||
msgstr "有地方出錯了"
|
msgstr "有地方出錯了"
|
||||||
|
|
||||||
#: js/extensionPrefs/main.js:268
|
#: js/dbusServices/extensions/ui/extension-prefs-dialog.ui:48
|
||||||
msgid ""
|
msgid ""
|
||||||
"We’re very sorry, but there’s been a problem: the settings for this "
|
"We’re very sorry, but there’s been a problem: the settings for this "
|
||||||
"extension can’t be displayed. We recommend that you report the issue to the "
|
"extension can’t be displayed. We recommend that you report the issue to the "
|
||||||
@ -415,108 +376,31 @@ msgstr ""
|
|||||||
"我們非常抱歉,發生了這個問題:無法顯示此擴充套件的設定。我們建議您回報此議題"
|
"我們非常抱歉,發生了這個問題:無法顯示此擴充套件的設定。我們建議您回報此議題"
|
||||||
"給擴充套件作者知曉。"
|
"給擴充套件作者知曉。"
|
||||||
|
|
||||||
#: js/extensionPrefs/main.js:275
|
#: js/dbusServices/extensions/ui/extension-prefs-dialog.ui:82
|
||||||
msgid "Technical Details"
|
msgid "Technical Details"
|
||||||
msgstr "技術細節"
|
msgstr "技術細節"
|
||||||
|
|
||||||
#: js/extensionPrefs/main.js:310
|
#: js/dbusServices/extensions/ui/extension-prefs-dialog.ui:165
|
||||||
msgid "Copy Error"
|
|
||||||
msgstr "複製錯誤"
|
|
||||||
|
|
||||||
#: js/extensionPrefs/main.js:337
|
|
||||||
msgid "Homepage"
|
msgid "Homepage"
|
||||||
msgstr "首頁"
|
msgstr "首頁"
|
||||||
|
|
||||||
#: js/extensionPrefs/main.js:338
|
#: js/dbusServices/extensions/ui/extension-prefs-dialog.ui:166
|
||||||
msgid "Visit extension homepage"
|
msgid "Visit extension homepage"
|
||||||
msgstr "造訪擴充套件首頁"
|
msgstr "造訪擴充套件首頁"
|
||||||
|
|
||||||
#: js/extensionPrefs/main.js:449
|
#: js/gdm/authPrompt.js:135 js/ui/audioDeviceSelection.js:57
|
||||||
#, javascript-format
|
#: js/ui/components/networkAgent.js:109 js/ui/components/polkitAgent.js:139
|
||||||
msgid "%d extension will be updated on next login."
|
#: js/ui/endSessionDialog.js:374 js/ui/extensionDownloader.js:181
|
||||||
msgid_plural "%d extensions will be updated on next login."
|
#: js/ui/shellMountOperation.js:376 js/ui/shellMountOperation.js:386
|
||||||
msgstr[0] "%d 個擴充套件會在下次登入時更新。"
|
#: js/ui/status/network.js:913 subprojects/extensions-app/js/main.js:148
|
||||||
|
msgid "Cancel"
|
||||||
#: js/extensionPrefs/ui/extension-row.ui:100
|
msgstr "取消"
|
||||||
#: subprojects/extensions-tool/src/command-create.c:211
|
|
||||||
#: subprojects/extensions-tool/src/main.c:173
|
|
||||||
msgid "Description"
|
|
||||||
msgstr "描述"
|
|
||||||
|
|
||||||
#: js/extensionPrefs/ui/extension-row.ui:123
|
|
||||||
#: subprojects/extensions-tool/src/main.c:185
|
|
||||||
msgid "Version"
|
|
||||||
msgstr "版本"
|
|
||||||
|
|
||||||
#: js/extensionPrefs/ui/extension-row.ui:151
|
|
||||||
msgid "Author"
|
|
||||||
msgstr "作者"
|
|
||||||
|
|
||||||
#: js/extensionPrefs/ui/extension-row.ui:175
|
|
||||||
msgid "Website"
|
|
||||||
msgstr "網站"
|
|
||||||
|
|
||||||
#: js/extensionPrefs/ui/extension-row.ui:192
|
|
||||||
msgid "Remove…"
|
|
||||||
msgstr "移除…"
|
|
||||||
|
|
||||||
#: js/extensionPrefs/ui/extensions-window.ui:8
|
|
||||||
msgid "Help"
|
|
||||||
msgstr "求助"
|
|
||||||
|
|
||||||
#: js/extensionPrefs/ui/extensions-window.ui:12
|
|
||||||
msgid "About Extensions"
|
|
||||||
msgstr "關於擴充套件"
|
|
||||||
|
|
||||||
#: js/extensionPrefs/ui/extensions-window.ui:27
|
|
||||||
msgid ""
|
|
||||||
"To find and add extensions, visit <a href=\"https://extensions.gnome.org"
|
|
||||||
"\">extensions.gnome.org</a>."
|
|
||||||
msgstr ""
|
|
||||||
"要尋找並加入擴充套件,可以到 <a href=\"https://extensions.gnome.org"
|
|
||||||
"\">extensions.gnome.org</a> 安裝。"
|
|
||||||
|
|
||||||
#: js/extensionPrefs/ui/extensions-window.ui:35
|
|
||||||
msgid "Warning"
|
|
||||||
msgstr "警告"
|
|
||||||
|
|
||||||
#: js/extensionPrefs/ui/extensions-window.ui:46
|
|
||||||
msgid ""
|
|
||||||
"Extensions can cause system issues, including performance problems. If you "
|
|
||||||
"encounter problems with your system, it is recommended to disable all "
|
|
||||||
"extensions."
|
|
||||||
msgstr ""
|
|
||||||
"擴充套件可能會造成系統問題,包含效能問題。如果您遇到系統問題,建議您先停用所"
|
|
||||||
"有的擴充套件。"
|
|
||||||
|
|
||||||
#: js/extensionPrefs/ui/extensions-window.ui:133
|
|
||||||
msgid "Manually Installed"
|
|
||||||
msgstr "手動安裝"
|
|
||||||
|
|
||||||
#: js/extensionPrefs/ui/extensions-window.ui:157
|
|
||||||
msgid "Built-In"
|
|
||||||
msgstr "內建"
|
|
||||||
|
|
||||||
#: js/extensionPrefs/ui/extensions-window.ui:198
|
|
||||||
msgid "No Installed Extensions"
|
|
||||||
msgstr "沒有已安裝的擴充套件"
|
|
||||||
|
|
||||||
#: js/extensionPrefs/ui/extensions-window.ui:234
|
|
||||||
msgid ""
|
|
||||||
"We’re very sorry, but it was not possible to get the list of installed "
|
|
||||||
"extensions. Make sure you are logged into GNOME and try again."
|
|
||||||
msgstr ""
|
|
||||||
"非常抱歉,但無法取得已安裝擴充套件的清單。請確定您已登入 GNOME 後重試。"
|
|
||||||
|
|
||||||
#: js/extensionPrefs/ui/extensions-window.ui:287
|
|
||||||
msgid "Log Out…"
|
|
||||||
msgstr "登出…"
|
|
||||||
|
|
||||||
#. Cisco LEAP
|
#. Cisco LEAP
|
||||||
#: js/gdm/authPrompt.js:235 js/ui/components/networkAgent.js:202
|
#: js/gdm/authPrompt.js:237 js/ui/components/networkAgent.js:204
|
||||||
#: js/ui/components/networkAgent.js:218 js/ui/components/networkAgent.js:242
|
#: js/ui/components/networkAgent.js:220 js/ui/components/networkAgent.js:244
|
||||||
#: js/ui/components/networkAgent.js:263 js/ui/components/networkAgent.js:283
|
#: js/ui/components/networkAgent.js:265 js/ui/components/networkAgent.js:285
|
||||||
#: js/ui/components/networkAgent.js:293 js/ui/components/polkitAgent.js:277
|
#: js/ui/components/networkAgent.js:295 js/ui/components/polkitAgent.js:277
|
||||||
#: js/ui/shellMountOperation.js:326
|
#: js/ui/shellMountOperation.js:326
|
||||||
msgid "Password"
|
msgid "Password"
|
||||||
msgstr "密碼"
|
msgstr "密碼"
|
||||||
@ -539,8 +423,8 @@ msgstr "(例如: user 或 %s)"
|
|||||||
#. TTLS and PEAP are actually much more complicated, but this complication
|
#. TTLS and PEAP are actually much more complicated, but this complication
|
||||||
#. is not visible here since we only care about phase2 authentication
|
#. is not visible here since we only care about phase2 authentication
|
||||||
#. (and don't even care of which one)
|
#. (and don't even care of which one)
|
||||||
#: js/gdm/loginDialog.js:917 js/ui/components/networkAgent.js:238
|
#: js/gdm/loginDialog.js:917 js/ui/components/networkAgent.js:240
|
||||||
#: js/ui/components/networkAgent.js:261 js/ui/components/networkAgent.js:279
|
#: js/ui/components/networkAgent.js:263 js/ui/components/networkAgent.js:281
|
||||||
msgid "Username"
|
msgid "Username"
|
||||||
msgstr "使用者名稱"
|
msgstr "使用者名稱"
|
||||||
|
|
||||||
@ -789,44 +673,44 @@ msgstr "禁止存取"
|
|||||||
msgid "Grant Access"
|
msgid "Grant Access"
|
||||||
msgstr "授予存取權限"
|
msgstr "授予存取權限"
|
||||||
|
|
||||||
#: js/ui/appDisplay.js:906
|
#: js/ui/appDisplay.js:932
|
||||||
msgid "Unnamed Folder"
|
msgid "Unnamed Folder"
|
||||||
msgstr "未命名資料夾"
|
msgstr "未命名資料夾"
|
||||||
|
|
||||||
#: js/ui/appDisplay.js:929
|
#: js/ui/appDisplay.js:955
|
||||||
msgid "Frequently used applications will appear here"
|
msgid "Frequently used applications will appear here"
|
||||||
msgstr "經常使用的應用程式會出現在這裡"
|
msgstr "經常使用的應用程式會出現在這裡"
|
||||||
|
|
||||||
#: js/ui/appDisplay.js:1064
|
#: js/ui/appDisplay.js:1090
|
||||||
msgid "Frequent"
|
msgid "Frequent"
|
||||||
msgstr "常用"
|
msgstr "常用"
|
||||||
|
|
||||||
#: js/ui/appDisplay.js:1071
|
#: js/ui/appDisplay.js:1097
|
||||||
msgid "All"
|
msgid "All"
|
||||||
msgstr "全部"
|
msgstr "全部"
|
||||||
|
|
||||||
#. Translators: This is the heading of a list of open windows
|
#. Translators: This is the heading of a list of open windows
|
||||||
#: js/ui/appDisplay.js:2454 js/ui/panel.js:75
|
#: js/ui/appDisplay.js:2473 js/ui/panel.js:75
|
||||||
msgid "Open Windows"
|
msgid "Open Windows"
|
||||||
msgstr "開啟視窗"
|
msgstr "開啟視窗"
|
||||||
|
|
||||||
#: js/ui/appDisplay.js:2474 js/ui/panel.js:82
|
#: js/ui/appDisplay.js:2493 js/ui/panel.js:82
|
||||||
msgid "New Window"
|
msgid "New Window"
|
||||||
msgstr "新視窗"
|
msgstr "新視窗"
|
||||||
|
|
||||||
#: js/ui/appDisplay.js:2485
|
#: js/ui/appDisplay.js:2504
|
||||||
msgid "Launch using Dedicated Graphics Card"
|
msgid "Launch using Dedicated Graphics Card"
|
||||||
msgstr "使用獨立顯卡啟動"
|
msgstr "使用獨立顯卡啟動"
|
||||||
|
|
||||||
#: js/ui/appDisplay.js:2513 js/ui/dash.js:239
|
#: js/ui/appDisplay.js:2532 js/ui/dash.js:239
|
||||||
msgid "Remove from Favorites"
|
msgid "Remove from Favorites"
|
||||||
msgstr "自喜好中移除"
|
msgstr "自喜好中移除"
|
||||||
|
|
||||||
#: js/ui/appDisplay.js:2519
|
#: js/ui/appDisplay.js:2538
|
||||||
msgid "Add to Favorites"
|
msgid "Add to Favorites"
|
||||||
msgstr "加入喜好"
|
msgstr "加入喜好"
|
||||||
|
|
||||||
#: js/ui/appDisplay.js:2529 js/ui/panel.js:93
|
#: js/ui/appDisplay.js:2548 js/ui/panel.js:93
|
||||||
msgid "Show Details"
|
msgid "Show Details"
|
||||||
msgstr "顯示詳細資訊"
|
msgstr "顯示詳細資訊"
|
||||||
|
|
||||||
@ -856,7 +740,7 @@ msgstr "頭戴式耳機"
|
|||||||
msgid "Headset"
|
msgid "Headset"
|
||||||
msgstr "耳機麥克風"
|
msgstr "耳機麥克風"
|
||||||
|
|
||||||
#: js/ui/audioDeviceSelection.js:68 js/ui/status/volume.js:269
|
#: js/ui/audioDeviceSelection.js:68 js/ui/status/volume.js:270
|
||||||
msgid "Microphone"
|
msgid "Microphone"
|
||||||
msgstr "麥克風"
|
msgstr "麥克風"
|
||||||
|
|
||||||
@ -974,30 +858,30 @@ msgid "All Day"
|
|||||||
msgstr "整天"
|
msgstr "整天"
|
||||||
|
|
||||||
#. Translators: Shown on calendar heading when selected day occurs on current year
|
#. Translators: Shown on calendar heading when selected day occurs on current year
|
||||||
#: js/ui/calendar.js:867
|
#: js/ui/calendar.js:868
|
||||||
msgctxt "calendar heading"
|
msgctxt "calendar heading"
|
||||||
msgid "%A, %B %-d"
|
msgid "%A, %B %-d"
|
||||||
msgstr "%b%-d日%A"
|
msgstr "%b%-d日%A"
|
||||||
|
|
||||||
#. Translators: Shown on calendar heading when selected day occurs on different year
|
#. Translators: Shown on calendar heading when selected day occurs on different year
|
||||||
#: js/ui/calendar.js:870
|
#: js/ui/calendar.js:871
|
||||||
msgctxt "calendar heading"
|
msgctxt "calendar heading"
|
||||||
msgid "%A, %B %-d, %Y"
|
msgid "%A, %B %-d, %Y"
|
||||||
msgstr "%Y年%b%-d日%A"
|
msgstr "%Y年%b%-d日%A"
|
||||||
|
|
||||||
#: js/ui/calendar.js:1096
|
#: js/ui/calendar.js:1100
|
||||||
msgid "No Notifications"
|
msgid "No Notifications"
|
||||||
msgstr "沒有通知"
|
msgstr "沒有通知"
|
||||||
|
|
||||||
#: js/ui/calendar.js:1099
|
#: js/ui/calendar.js:1103
|
||||||
msgid "No Events"
|
msgid "No Events"
|
||||||
msgstr "沒有行程"
|
msgstr "沒有行程"
|
||||||
|
|
||||||
#: js/ui/calendar.js:1153
|
#: js/ui/calendar.js:1157
|
||||||
msgid "Do Not Disturb"
|
msgid "Do Not Disturb"
|
||||||
msgstr "不要打擾"
|
msgstr "不要打擾"
|
||||||
|
|
||||||
#: js/ui/calendar.js:1167
|
#: js/ui/calendar.js:1176
|
||||||
msgid "Clear"
|
msgid "Clear"
|
||||||
msgstr "清除"
|
msgstr "清除"
|
||||||
|
|
||||||
@ -1042,80 +926,80 @@ msgstr "安裝的 udisks 版本不支援設定 PIM"
|
|||||||
msgid "Open with %s"
|
msgid "Open with %s"
|
||||||
msgstr "用 %s 開啟"
|
msgstr "用 %s 開啟"
|
||||||
|
|
||||||
#: js/ui/components/networkAgent.js:89
|
#: js/ui/components/networkAgent.js:91
|
||||||
msgid ""
|
msgid ""
|
||||||
"Alternatively you can connect by pushing the “WPS” button on your router."
|
"Alternatively you can connect by pushing the “WPS” button on your router."
|
||||||
msgstr "或者您可以按下路由器的「WPS」按鈕來連接看看。"
|
msgstr "或者您可以按下路由器的「WPS」按鈕來連接看看。"
|
||||||
|
|
||||||
#: js/ui/components/networkAgent.js:101 js/ui/status/network.js:223
|
#: js/ui/components/networkAgent.js:103 js/ui/status/network.js:223
|
||||||
#: js/ui/status/network.js:314 js/ui/status/network.js:916
|
#: js/ui/status/network.js:314 js/ui/status/network.js:916
|
||||||
msgid "Connect"
|
msgid "Connect"
|
||||||
msgstr "連線"
|
msgstr "連線"
|
||||||
|
|
||||||
#: js/ui/components/networkAgent.js:208
|
#: js/ui/components/networkAgent.js:210
|
||||||
msgid "Key"
|
msgid "Key"
|
||||||
msgstr "金鑰"
|
msgstr "金鑰"
|
||||||
|
|
||||||
#: js/ui/components/networkAgent.js:246 js/ui/components/networkAgent.js:269
|
#: js/ui/components/networkAgent.js:248 js/ui/components/networkAgent.js:271
|
||||||
msgid "Private key password"
|
msgid "Private key password"
|
||||||
msgstr "私密金鑰密碼"
|
msgstr "私密金鑰密碼"
|
||||||
|
|
||||||
#: js/ui/components/networkAgent.js:267
|
#: js/ui/components/networkAgent.js:269
|
||||||
msgid "Identity"
|
msgid "Identity"
|
||||||
msgstr "識別身分"
|
msgstr "識別身分"
|
||||||
|
|
||||||
#: js/ui/components/networkAgent.js:281
|
#: js/ui/components/networkAgent.js:283
|
||||||
msgid "Service"
|
msgid "Service"
|
||||||
msgstr "服務"
|
msgstr "服務"
|
||||||
|
|
||||||
#: js/ui/components/networkAgent.js:310 js/ui/components/networkAgent.js:338
|
#: js/ui/components/networkAgent.js:312 js/ui/components/networkAgent.js:340
|
||||||
#: js/ui/components/networkAgent.js:685 js/ui/components/networkAgent.js:706
|
#: js/ui/components/networkAgent.js:679 js/ui/components/networkAgent.js:700
|
||||||
msgid "Authentication required"
|
msgid "Authentication required"
|
||||||
msgstr "要求核對"
|
msgstr "要求核對"
|
||||||
|
|
||||||
#: js/ui/components/networkAgent.js:311 js/ui/components/networkAgent.js:686
|
#: js/ui/components/networkAgent.js:313 js/ui/components/networkAgent.js:680
|
||||||
#, javascript-format
|
#, javascript-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"Passwords or encryption keys are required to access the wireless network "
|
"Passwords or encryption keys are required to access the wireless network "
|
||||||
"“%s”."
|
"“%s”."
|
||||||
msgstr "需要密碼或是加密金鑰來存取無線網路「%s」。"
|
msgstr "需要密碼或是加密金鑰來存取無線網路「%s」。"
|
||||||
|
|
||||||
#: js/ui/components/networkAgent.js:315 js/ui/components/networkAgent.js:690
|
#: js/ui/components/networkAgent.js:317 js/ui/components/networkAgent.js:684
|
||||||
msgid "Wired 802.1X authentication"
|
msgid "Wired 802.1X authentication"
|
||||||
msgstr "有線網路 802.1X 核對"
|
msgstr "有線網路 802.1X 核對"
|
||||||
|
|
||||||
#: js/ui/components/networkAgent.js:317
|
#: js/ui/components/networkAgent.js:319
|
||||||
msgid "Network name"
|
msgid "Network name"
|
||||||
msgstr "網路名稱"
|
msgstr "網路名稱"
|
||||||
|
|
||||||
#: js/ui/components/networkAgent.js:322 js/ui/components/networkAgent.js:694
|
#: js/ui/components/networkAgent.js:324 js/ui/components/networkAgent.js:688
|
||||||
msgid "DSL authentication"
|
msgid "DSL authentication"
|
||||||
msgstr "DSL 核對"
|
msgstr "DSL 核對"
|
||||||
|
|
||||||
#: js/ui/components/networkAgent.js:329 js/ui/components/networkAgent.js:699
|
#: js/ui/components/networkAgent.js:331 js/ui/components/networkAgent.js:693
|
||||||
msgid "PIN code required"
|
msgid "PIN code required"
|
||||||
msgstr "需要 PIN 碼"
|
msgstr "需要 PIN 碼"
|
||||||
|
|
||||||
#: js/ui/components/networkAgent.js:330 js/ui/components/networkAgent.js:700
|
#: js/ui/components/networkAgent.js:332 js/ui/components/networkAgent.js:694
|
||||||
msgid "PIN code is needed for the mobile broadband device"
|
msgid "PIN code is needed for the mobile broadband device"
|
||||||
msgstr "這個行動寬頻裝置需要 PIN 碼"
|
msgstr "這個行動寬頻裝置需要 PIN 碼"
|
||||||
|
|
||||||
#: js/ui/components/networkAgent.js:331
|
#: js/ui/components/networkAgent.js:333
|
||||||
msgid "PIN"
|
msgid "PIN"
|
||||||
msgstr "PIN:"
|
msgstr "PIN 碼"
|
||||||
|
|
||||||
#: js/ui/components/networkAgent.js:339 js/ui/components/networkAgent.js:691
|
#: js/ui/components/networkAgent.js:341 js/ui/components/networkAgent.js:685
|
||||||
#: js/ui/components/networkAgent.js:695 js/ui/components/networkAgent.js:707
|
#: js/ui/components/networkAgent.js:689 js/ui/components/networkAgent.js:701
|
||||||
#: js/ui/components/networkAgent.js:711
|
#: js/ui/components/networkAgent.js:705
|
||||||
#, javascript-format
|
#, javascript-format
|
||||||
msgid "A password is required to connect to “%s”."
|
msgid "A password is required to connect to “%s”."
|
||||||
msgstr "連線至「%s」需要密碼。"
|
msgstr "連線至「%s」需要密碼。"
|
||||||
|
|
||||||
#: js/ui/components/networkAgent.js:674 js/ui/status/network.js:1691
|
#: js/ui/components/networkAgent.js:668 js/ui/status/network.js:1691
|
||||||
msgid "Network Manager"
|
msgid "Network Manager"
|
||||||
msgstr "網路管理員"
|
msgstr "網路管理員"
|
||||||
|
|
||||||
#: js/ui/components/networkAgent.js:710
|
#: js/ui/components/networkAgent.js:704
|
||||||
msgid "VPN password"
|
msgid "VPN password"
|
||||||
msgstr "VPN 密碼"
|
msgstr "VPN 密碼"
|
||||||
|
|
||||||
@ -1141,7 +1025,7 @@ msgstr "抱歉,那沒有作用。請再試一次。"
|
|||||||
|
|
||||||
#. Translators: this is the other person changing their old IM name to their new
|
#. Translators: this is the other person changing their old IM name to their new
|
||||||
#. IM name.
|
#. IM name.
|
||||||
#: js/ui/components/telepathyClient.js:787
|
#: js/ui/components/telepathyClient.js:823
|
||||||
#, javascript-format
|
#, javascript-format
|
||||||
msgid "%s is now known as %s"
|
msgid "%s is now known as %s"
|
||||||
msgstr "%s 現在被稱為 %s"
|
msgstr "%s 現在被稱為 %s"
|
||||||
@ -1185,124 +1069,124 @@ msgstr "加入世界時鐘…"
|
|||||||
msgid "World Clocks"
|
msgid "World Clocks"
|
||||||
msgstr "世界時鐘"
|
msgstr "世界時鐘"
|
||||||
|
|
||||||
#: js/ui/dateMenu.js:276
|
#: js/ui/dateMenu.js:289
|
||||||
msgid "Weather"
|
msgid "Weather"
|
||||||
msgstr "天氣"
|
msgstr "天氣"
|
||||||
|
|
||||||
#: js/ui/dateMenu.js:391
|
#: js/ui/dateMenu.js:418
|
||||||
msgid "Select a location…"
|
msgid "Select a location…"
|
||||||
msgstr "選擇位置…"
|
msgstr "選擇位置…"
|
||||||
|
|
||||||
#: js/ui/dateMenu.js:404
|
#: js/ui/dateMenu.js:426
|
||||||
msgid "Loading…"
|
msgid "Loading…"
|
||||||
msgstr "載入中…"
|
msgstr "載入中…"
|
||||||
|
|
||||||
#: js/ui/dateMenu.js:414
|
#: js/ui/dateMenu.js:436
|
||||||
msgid "Go online for weather information"
|
msgid "Go online for weather information"
|
||||||
msgstr "上線以取得天氣資訊"
|
msgstr "上線以取得天氣資訊"
|
||||||
|
|
||||||
#: js/ui/dateMenu.js:416
|
#: js/ui/dateMenu.js:438
|
||||||
msgid "Weather information is currently unavailable"
|
msgid "Weather information is currently unavailable"
|
||||||
msgstr "天氣資訊目前不可使用"
|
msgstr "天氣資訊目前不可使用"
|
||||||
|
|
||||||
#: js/ui/endSessionDialog.js:37
|
#: js/ui/endSessionDialog.js:39
|
||||||
#, javascript-format
|
#, javascript-format
|
||||||
msgctxt "title"
|
msgctxt "title"
|
||||||
msgid "Log Out %s"
|
msgid "Log Out %s"
|
||||||
msgstr "登出 %s"
|
msgstr "登出 %s"
|
||||||
|
|
||||||
#: js/ui/endSessionDialog.js:38
|
#: js/ui/endSessionDialog.js:40
|
||||||
msgctxt "title"
|
msgctxt "title"
|
||||||
msgid "Log Out"
|
msgid "Log Out"
|
||||||
msgstr "登出"
|
msgstr "登出"
|
||||||
|
|
||||||
#: js/ui/endSessionDialog.js:40
|
#: js/ui/endSessionDialog.js:42
|
||||||
#, javascript-format
|
#, javascript-format
|
||||||
msgid "%s will be logged out automatically in %d second."
|
msgid "%s will be logged out automatically in %d second."
|
||||||
msgid_plural "%s will be logged out automatically in %d seconds."
|
msgid_plural "%s will be logged out automatically in %d seconds."
|
||||||
msgstr[0] "%s 會在 %d 秒後自動登出。"
|
msgstr[0] "%s 會在 %d 秒後自動登出。"
|
||||||
|
|
||||||
#: js/ui/endSessionDialog.js:45
|
#: js/ui/endSessionDialog.js:47
|
||||||
#, javascript-format
|
#, javascript-format
|
||||||
msgid "You will be logged out automatically in %d second."
|
msgid "You will be logged out automatically in %d second."
|
||||||
msgid_plural "You will be logged out automatically in %d seconds."
|
msgid_plural "You will be logged out automatically in %d seconds."
|
||||||
msgstr[0] "您會在 %d 秒後自動登出。"
|
msgstr[0] "您會在 %d 秒後自動登出。"
|
||||||
|
|
||||||
#: js/ui/endSessionDialog.js:51
|
#: js/ui/endSessionDialog.js:53
|
||||||
msgctxt "button"
|
msgctxt "button"
|
||||||
msgid "Log Out"
|
msgid "Log Out"
|
||||||
msgstr "登出"
|
msgstr "登出"
|
||||||
|
|
||||||
#: js/ui/endSessionDialog.js:56
|
#: js/ui/endSessionDialog.js:58
|
||||||
msgctxt "title"
|
msgctxt "title"
|
||||||
msgid "Power Off"
|
msgid "Power Off"
|
||||||
msgstr "關閉電源"
|
msgstr "關閉電源"
|
||||||
|
|
||||||
#: js/ui/endSessionDialog.js:57
|
#: js/ui/endSessionDialog.js:59
|
||||||
msgctxt "title"
|
msgctxt "title"
|
||||||
msgid "Install Updates & Power Off"
|
msgid "Install Updates & Power Off"
|
||||||
msgstr "安裝更新並關機"
|
msgstr "安裝更新並關機"
|
||||||
|
|
||||||
#: js/ui/endSessionDialog.js:59
|
#: js/ui/endSessionDialog.js:61
|
||||||
#, javascript-format
|
#, javascript-format
|
||||||
msgid "The system will power off automatically in %d second."
|
msgid "The system will power off automatically in %d second."
|
||||||
msgid_plural "The system will power off automatically in %d seconds."
|
msgid_plural "The system will power off automatically in %d seconds."
|
||||||
msgstr[0] "系統會在 %d 秒後關閉電源。"
|
msgstr[0] "系統會在 %d 秒後關閉電源。"
|
||||||
|
|
||||||
#: js/ui/endSessionDialog.js:63
|
#: js/ui/endSessionDialog.js:65
|
||||||
msgctxt "checkbox"
|
msgctxt "checkbox"
|
||||||
msgid "Install pending software updates"
|
msgid "Install pending software updates"
|
||||||
msgstr "安裝擱置的軟體更新"
|
msgstr "安裝擱置的軟體更新"
|
||||||
|
|
||||||
#: js/ui/endSessionDialog.js:66 js/ui/endSessionDialog.js:82
|
#: js/ui/endSessionDialog.js:68 js/ui/endSessionDialog.js:84
|
||||||
msgctxt "button"
|
msgctxt "button"
|
||||||
msgid "Restart"
|
msgid "Restart"
|
||||||
msgstr "重新啟動"
|
msgstr "重新啟動"
|
||||||
|
|
||||||
#: js/ui/endSessionDialog.js:68
|
#: js/ui/endSessionDialog.js:70
|
||||||
msgctxt "button"
|
msgctxt "button"
|
||||||
msgid "Power Off"
|
msgid "Power Off"
|
||||||
msgstr "關閉電源"
|
msgstr "關閉電源"
|
||||||
|
|
||||||
#: js/ui/endSessionDialog.js:74
|
#: js/ui/endSessionDialog.js:76
|
||||||
msgctxt "title"
|
msgctxt "title"
|
||||||
msgid "Restart"
|
msgid "Restart"
|
||||||
msgstr "重新啟動"
|
msgstr "重新啟動"
|
||||||
|
|
||||||
#: js/ui/endSessionDialog.js:76
|
#: js/ui/endSessionDialog.js:78
|
||||||
#, javascript-format
|
#, javascript-format
|
||||||
msgid "The system will restart automatically in %d second."
|
msgid "The system will restart automatically in %d second."
|
||||||
msgid_plural "The system will restart automatically in %d seconds."
|
msgid_plural "The system will restart automatically in %d seconds."
|
||||||
msgstr[0] "系統會在 %d 秒後自動重新啟動。"
|
msgstr[0] "系統會在 %d 秒後自動重新啟動。"
|
||||||
|
|
||||||
#: js/ui/endSessionDialog.js:89
|
#: js/ui/endSessionDialog.js:91
|
||||||
msgctxt "title"
|
msgctxt "title"
|
||||||
msgid "Restart & Install Updates"
|
msgid "Restart & Install Updates"
|
||||||
msgstr "重新啟動並安裝更新"
|
msgstr "重新啟動並安裝更新"
|
||||||
|
|
||||||
#: js/ui/endSessionDialog.js:91
|
#: js/ui/endSessionDialog.js:93
|
||||||
#, javascript-format
|
#, javascript-format
|
||||||
msgid "The system will automatically restart and install updates in %d second."
|
msgid "The system will automatically restart and install updates in %d second."
|
||||||
msgid_plural ""
|
msgid_plural ""
|
||||||
"The system will automatically restart and install updates in %d seconds."
|
"The system will automatically restart and install updates in %d seconds."
|
||||||
msgstr[0] "系統會在 %d 秒後自動重新啟動。"
|
msgstr[0] "系統會在 %d 秒後自動重新啟動。"
|
||||||
|
|
||||||
#: js/ui/endSessionDialog.js:97 js/ui/endSessionDialog.js:116
|
#: js/ui/endSessionDialog.js:99 js/ui/endSessionDialog.js:118
|
||||||
msgctxt "button"
|
msgctxt "button"
|
||||||
msgid "Restart & Install"
|
msgid "Restart & Install"
|
||||||
msgstr "重新啟動並安裝"
|
msgstr "重新啟動並安裝"
|
||||||
|
|
||||||
#: js/ui/endSessionDialog.js:98
|
#: js/ui/endSessionDialog.js:100
|
||||||
msgctxt "button"
|
msgctxt "button"
|
||||||
msgid "Install & Power Off"
|
msgid "Install & Power Off"
|
||||||
msgstr "安裝並關機"
|
msgstr "安裝並關機"
|
||||||
|
|
||||||
#: js/ui/endSessionDialog.js:99
|
#: js/ui/endSessionDialog.js:101
|
||||||
msgctxt "checkbox"
|
msgctxt "checkbox"
|
||||||
msgid "Power off after updates are installed"
|
msgid "Power off after updates are installed"
|
||||||
msgstr "在安裝完更新之後關機"
|
msgstr "在安裝完更新之後關機"
|
||||||
|
|
||||||
#: js/ui/endSessionDialog.js:106
|
#: js/ui/endSessionDialog.js:108
|
||||||
msgctxt "title"
|
msgctxt "title"
|
||||||
msgid "Restart & Install Upgrade"
|
msgid "Restart & Install Upgrade"
|
||||||
msgstr "重新啟動並安裝升級"
|
msgstr "重新啟動並安裝升級"
|
||||||
@ -1310,7 +1194,7 @@ msgstr "重新啟動並安裝升級"
|
|||||||
#. Translators: This is the text displayed for system upgrades in the
|
#. Translators: This is the text displayed for system upgrades in the
|
||||||
#. shut down dialog. First %s gets replaced with the distro name and
|
#. shut down dialog. First %s gets replaced with the distro name and
|
||||||
#. second %s with the distro version to upgrade to
|
#. second %s with the distro version to upgrade to
|
||||||
#: js/ui/endSessionDialog.js:111
|
#: js/ui/endSessionDialog.js:113
|
||||||
#, javascript-format
|
#, javascript-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"%s %s will be installed after restart. Upgrade installation can take a long "
|
"%s %s will be installed after restart. Upgrade installation can take a long "
|
||||||
@ -1319,15 +1203,15 @@ msgstr ""
|
|||||||
"%s %s 將在重新啟動之後展開安裝。升級的過程可能會花上一段較長的時間:請確認您"
|
"%s %s 將在重新啟動之後展開安裝。升級的過程可能會花上一段較長的時間:請確認您"
|
||||||
"已有備份,並且已將電腦電源插上。"
|
"已有備份,並且已將電腦電源插上。"
|
||||||
|
|
||||||
#: js/ui/endSessionDialog.js:259
|
#: js/ui/endSessionDialog.js:261
|
||||||
msgid "Running on battery power: Please plug in before installing updates."
|
msgid "Running on battery power: Please plug in before installing updates."
|
||||||
msgstr "正於電池電源執行:請在安裝更新前插入電源線。"
|
msgstr "正於電池電源執行:請在安裝更新前插入電源線。"
|
||||||
|
|
||||||
#: js/ui/endSessionDialog.js:268
|
#: js/ui/endSessionDialog.js:270
|
||||||
msgid "Some applications are busy or have unsaved work"
|
msgid "Some applications are busy or have unsaved work"
|
||||||
msgstr "部分應用程式忙碌中或有未儲存的工作"
|
msgstr "部分應用程式忙碌中或有未儲存的工作"
|
||||||
|
|
||||||
#: js/ui/endSessionDialog.js:273
|
#: js/ui/endSessionDialog.js:275
|
||||||
msgid "Other users are logged in"
|
msgid "Other users are logged in"
|
||||||
msgstr "其他使用者已登入"
|
msgstr "其他使用者已登入"
|
||||||
|
|
||||||
@ -1343,24 +1227,24 @@ msgstr "%s (遠端)"
|
|||||||
msgid "%s (console)"
|
msgid "%s (console)"
|
||||||
msgstr "%s (主控臺)"
|
msgstr "%s (主控臺)"
|
||||||
|
|
||||||
#: js/ui/extensionDownloader.js:169
|
#: js/ui/extensionDownloader.js:185
|
||||||
msgid "Install"
|
msgid "Install"
|
||||||
msgstr "安裝"
|
msgstr "安裝"
|
||||||
|
|
||||||
#: js/ui/extensionDownloader.js:175
|
#: js/ui/extensionDownloader.js:191
|
||||||
msgid "Install Extension"
|
msgid "Install Extension"
|
||||||
msgstr "安裝擴充套件"
|
msgstr "安裝擴充套件"
|
||||||
|
|
||||||
#: js/ui/extensionDownloader.js:176
|
#: js/ui/extensionDownloader.js:192
|
||||||
#, javascript-format
|
#, javascript-format
|
||||||
msgid "Download and install “%s” from extensions.gnome.org?"
|
msgid "Download and install “%s” from extensions.gnome.org?"
|
||||||
msgstr "是否從 extensions.gnome.org 下載並安裝「%s」?"
|
msgstr "是否從 extensions.gnome.org 下載並安裝「%s」?"
|
||||||
|
|
||||||
#: js/ui/extensionSystem.js:228
|
#: js/ui/extensionSystem.js:233
|
||||||
msgid "Extension Updates Available"
|
msgid "Extension Updates Available"
|
||||||
msgstr "有擴充套件的更新"
|
msgstr "有擴充套件的更新"
|
||||||
|
|
||||||
#: js/ui/extensionSystem.js:229
|
#: js/ui/extensionSystem.js:234
|
||||||
msgid "Extension updates are ready to be installed."
|
msgid "Extension updates are ready to be installed."
|
||||||
msgstr "擴充套件更新已準備好安裝。"
|
msgstr "擴充套件更新已準備好安裝。"
|
||||||
|
|
||||||
@ -1458,59 +1342,59 @@ msgstr "離開"
|
|||||||
msgid "Region & Language Settings"
|
msgid "Region & Language Settings"
|
||||||
msgstr "地區和語言設定值"
|
msgstr "地區和語言設定值"
|
||||||
|
|
||||||
#: js/ui/lookingGlass.js:659
|
#: js/ui/lookingGlass.js:665
|
||||||
msgid "No extensions installed"
|
msgid "No extensions installed"
|
||||||
msgstr "沒有安裝擴充套件"
|
msgstr "沒有安裝擴充套件"
|
||||||
|
|
||||||
#. Translators: argument is an extension UUID.
|
#. Translators: argument is an extension UUID.
|
||||||
#: js/ui/lookingGlass.js:714
|
#: js/ui/lookingGlass.js:720
|
||||||
#, javascript-format
|
#, javascript-format
|
||||||
msgid "%s has not emitted any errors."
|
msgid "%s has not emitted any errors."
|
||||||
msgstr "%s 沒有發出任何錯誤。"
|
msgstr "%s 沒有發出任何錯誤。"
|
||||||
|
|
||||||
#: js/ui/lookingGlass.js:720
|
#: js/ui/lookingGlass.js:726
|
||||||
msgid "Hide Errors"
|
msgid "Hide Errors"
|
||||||
msgstr "隱藏錯誤"
|
msgstr "隱藏錯誤"
|
||||||
|
|
||||||
#: js/ui/lookingGlass.js:724 js/ui/lookingGlass.js:789
|
#: js/ui/lookingGlass.js:730 js/ui/lookingGlass.js:795
|
||||||
msgid "Show Errors"
|
msgid "Show Errors"
|
||||||
msgstr "顯示錯誤"
|
msgstr "顯示錯誤"
|
||||||
|
|
||||||
#: js/ui/lookingGlass.js:733
|
#: js/ui/lookingGlass.js:739
|
||||||
msgid "Enabled"
|
msgid "Enabled"
|
||||||
msgstr "已啟用"
|
msgstr "已啟用"
|
||||||
|
|
||||||
#. translators:
|
#. translators:
|
||||||
#. * The device has been disabled
|
#. * The device has been disabled
|
||||||
#: js/ui/lookingGlass.js:736 subprojects/gvc/gvc-mixer-control.c:1892
|
#: js/ui/lookingGlass.js:742 subprojects/gvc/gvc-mixer-control.c:1892
|
||||||
msgid "Disabled"
|
msgid "Disabled"
|
||||||
msgstr "已停用"
|
msgstr "已停用"
|
||||||
|
|
||||||
#: js/ui/lookingGlass.js:738
|
#: js/ui/lookingGlass.js:744
|
||||||
msgid "Error"
|
msgid "Error"
|
||||||
msgstr "錯誤"
|
msgstr "錯誤"
|
||||||
|
|
||||||
#: js/ui/lookingGlass.js:740
|
#: js/ui/lookingGlass.js:746
|
||||||
msgid "Out of date"
|
msgid "Out of date"
|
||||||
msgstr "過期"
|
msgstr "過期"
|
||||||
|
|
||||||
#: js/ui/lookingGlass.js:742
|
#: js/ui/lookingGlass.js:748
|
||||||
msgid "Downloading"
|
msgid "Downloading"
|
||||||
msgstr "下載中"
|
msgstr "下載中"
|
||||||
|
|
||||||
#: js/ui/lookingGlass.js:771
|
#: js/ui/lookingGlass.js:777
|
||||||
msgid "View Source"
|
msgid "View Source"
|
||||||
msgstr "檢示來源"
|
msgstr "檢示來源"
|
||||||
|
|
||||||
#: js/ui/lookingGlass.js:780
|
#: js/ui/lookingGlass.js:786
|
||||||
msgid "Web Page"
|
msgid "Web Page"
|
||||||
msgstr "網頁"
|
msgstr "網頁"
|
||||||
|
|
||||||
#: js/ui/main.js:267
|
#: js/ui/main.js:277
|
||||||
msgid "Logged in as a privileged user"
|
msgid "Logged in as a privileged user"
|
||||||
msgstr "以特權使用者身分登入"
|
msgstr "以特權使用者身分登入"
|
||||||
|
|
||||||
#: js/ui/main.js:268
|
#: js/ui/main.js:278
|
||||||
msgid ""
|
msgid ""
|
||||||
"Running a session as a privileged user should be avoided for security "
|
"Running a session as a privileged user should be avoided for security "
|
||||||
"reasons. If possible, you should log in as a normal user."
|
"reasons. If possible, you should log in as a normal user."
|
||||||
@ -1518,15 +1402,15 @@ msgstr ""
|
|||||||
"因安全因素,應避免在特權使用者執行工作階段。如果可以,應以一般使用者身份登"
|
"因安全因素,應避免在特權使用者執行工作階段。如果可以,應以一般使用者身份登"
|
||||||
"入。"
|
"入。"
|
||||||
|
|
||||||
#: js/ui/main.js:274
|
#: js/ui/main.js:317
|
||||||
msgid "Screen Lock disabled"
|
msgid "Screen Lock disabled"
|
||||||
msgstr "已停用螢幕鎖定"
|
msgstr "已停用螢幕鎖定"
|
||||||
|
|
||||||
#: js/ui/main.js:275
|
#: js/ui/main.js:318
|
||||||
msgid "Screen Locking requires the GNOME display manager."
|
msgid "Screen Locking requires the GNOME display manager."
|
||||||
msgstr "螢幕鎖定需要 GNOME 登入管理員。"
|
msgstr "螢幕鎖定需要 GNOME 登入管理員。"
|
||||||
|
|
||||||
#: js/ui/messageTray.js:1554
|
#: js/ui/messageTray.js:1551
|
||||||
msgid "System Information"
|
msgid "System Information"
|
||||||
msgstr "系統資訊"
|
msgstr "系統資訊"
|
||||||
|
|
||||||
@ -1610,12 +1494,12 @@ msgstr "結束"
|
|||||||
msgid "Activities"
|
msgid "Activities"
|
||||||
msgstr "概覽"
|
msgstr "概覽"
|
||||||
|
|
||||||
#: js/ui/panel.js:707
|
#: js/ui/panel.js:713
|
||||||
msgctxt "System menu in the top bar"
|
msgctxt "System menu in the top bar"
|
||||||
msgid "System"
|
msgid "System"
|
||||||
msgstr "系統"
|
msgstr "系統"
|
||||||
|
|
||||||
#: js/ui/panel.js:820
|
#: js/ui/panel.js:826
|
||||||
msgid "Top Bar"
|
msgid "Top Bar"
|
||||||
msgstr "頂端列"
|
msgstr "頂端列"
|
||||||
|
|
||||||
@ -1730,13 +1614,13 @@ msgid "The PIM must be a number or empty."
|
|||||||
msgstr "PIM 必須是數字或空白。"
|
msgstr "PIM 必須是數字或空白。"
|
||||||
|
|
||||||
#. Translators: %s is the Disks application
|
#. Translators: %s is the Disks application
|
||||||
#: js/ui/shellMountOperation.js:469
|
#: js/ui/shellMountOperation.js:465
|
||||||
#, javascript-format
|
#, javascript-format
|
||||||
msgid "Unable to start %s"
|
msgid "Unable to start %s"
|
||||||
msgstr "無法啟動 %s"
|
msgstr "無法啟動 %s"
|
||||||
|
|
||||||
#. Translators: %s is the Disks application
|
#. Translators: %s is the Disks application
|
||||||
#: js/ui/shellMountOperation.js:471
|
#: js/ui/shellMountOperation.js:467
|
||||||
#, javascript-format
|
#, javascript-format
|
||||||
msgid "Couldn’t find the %s application"
|
msgid "Couldn’t find the %s application"
|
||||||
msgstr "找不到 %s 應用程式"
|
msgstr "找不到 %s 應用程式"
|
||||||
@ -1832,11 +1716,11 @@ msgstr "右鍵"
|
|||||||
msgid "Dwell Click"
|
msgid "Dwell Click"
|
||||||
msgstr "替代點選"
|
msgstr "替代點選"
|
||||||
|
|
||||||
#: js/ui/status/keyboard.js:825
|
#: js/ui/status/keyboard.js:826
|
||||||
msgid "Keyboard"
|
msgid "Keyboard"
|
||||||
msgstr "鍵盤"
|
msgstr "鍵盤"
|
||||||
|
|
||||||
#: js/ui/status/keyboard.js:847
|
#: js/ui/status/keyboard.js:848
|
||||||
msgid "Show Keyboard Layout"
|
msgid "Show Keyboard Layout"
|
||||||
msgstr "顯示鍵盤配置"
|
msgstr "顯示鍵盤配置"
|
||||||
|
|
||||||
@ -2202,11 +2086,11 @@ msgstr "Thunderbolt 授權錯誤"
|
|||||||
msgid "Could not authorize the Thunderbolt device: %s"
|
msgid "Could not authorize the Thunderbolt device: %s"
|
||||||
msgstr "無法授權該 Thunderbolt 裝置:%s"
|
msgstr "無法授權該 Thunderbolt 裝置:%s"
|
||||||
|
|
||||||
#: js/ui/status/volume.js:150
|
#: js/ui/status/volume.js:151
|
||||||
msgid "Volume changed"
|
msgid "Volume changed"
|
||||||
msgstr "音量已變更"
|
msgstr "音量已變更"
|
||||||
|
|
||||||
#: js/ui/status/volume.js:221
|
#: js/ui/status/volume.js:222
|
||||||
msgid "Volume"
|
msgid "Volume"
|
||||||
msgstr "音量"
|
msgstr "音量"
|
||||||
|
|
||||||
@ -2240,22 +2124,26 @@ msgstr "僅內建"
|
|||||||
|
|
||||||
#. Translators: This is a time format for a date in
|
#. Translators: This is a time format for a date in
|
||||||
#. long format
|
#. long format
|
||||||
#: js/ui/unlockDialog.js:372
|
#: js/ui/unlockDialog.js:371
|
||||||
msgid "%A %B %-d"
|
msgid "%A %B %-d"
|
||||||
msgstr "%b%-d日%A"
|
msgstr "%b%-d日%A"
|
||||||
|
|
||||||
#: js/ui/unlockDialog.js:378
|
#: js/ui/unlockDialog.js:377
|
||||||
msgid "Swipe up to unlock"
|
msgid "Swipe up to unlock"
|
||||||
msgstr "向上滑動解鎖"
|
msgstr "向上滑動解鎖"
|
||||||
|
|
||||||
#: js/ui/unlockDialog.js:379
|
#: js/ui/unlockDialog.js:378
|
||||||
msgid "Click or press a key to unlock"
|
msgid "Click or press a key to unlock"
|
||||||
msgstr "點選或按按鍵解鎖"
|
msgstr "點選或按按鍵解鎖"
|
||||||
|
|
||||||
#: js/ui/unlockDialog.js:552
|
#: js/ui/unlockDialog.js:550
|
||||||
msgid "Unlock Window"
|
msgid "Unlock Window"
|
||||||
msgstr "解鎖視窗"
|
msgstr "解鎖視窗"
|
||||||
|
|
||||||
|
#: js/ui/unlockDialog.js:559
|
||||||
|
msgid "Log in as another user"
|
||||||
|
msgstr "以另一個使用者身分登入"
|
||||||
|
|
||||||
#: js/ui/viewSelector.js:181
|
#: js/ui/viewSelector.js:181
|
||||||
msgid "Applications"
|
msgid "Applications"
|
||||||
msgstr "應用程式"
|
msgstr "應用程式"
|
||||||
@ -2370,19 +2258,19 @@ msgstr "關閉"
|
|||||||
msgid "Evolution Calendar"
|
msgid "Evolution Calendar"
|
||||||
msgstr "Evolution 行事曆"
|
msgstr "Evolution 行事曆"
|
||||||
|
|
||||||
#: src/main.c:460 subprojects/extensions-tool/src/main.c:249
|
#: src/main.c:458 subprojects/extensions-tool/src/main.c:249
|
||||||
msgid "Print version"
|
msgid "Print version"
|
||||||
msgstr "顯示版本"
|
msgstr "顯示版本"
|
||||||
|
|
||||||
#: src/main.c:466
|
#: src/main.c:464
|
||||||
msgid "Mode used by GDM for login screen"
|
msgid "Mode used by GDM for login screen"
|
||||||
msgstr "GDM 在登入畫面使用的模式"
|
msgstr "GDM 在登入畫面使用的模式"
|
||||||
|
|
||||||
#: src/main.c:472
|
#: src/main.c:470
|
||||||
msgid "Use a specific mode, e.g. “gdm” for login screen"
|
msgid "Use a specific mode, e.g. “gdm” for login screen"
|
||||||
msgstr "使用指定的模式,例如「gdm」為登入畫面"
|
msgstr "使用指定的模式,例如「gdm」為登入畫面"
|
||||||
|
|
||||||
#: src/main.c:478
|
#: src/main.c:476
|
||||||
msgid "List possible modes"
|
msgid "List possible modes"
|
||||||
msgstr "列出可能的模式"
|
msgstr "列出可能的模式"
|
||||||
|
|
||||||
@ -2408,6 +2296,130 @@ msgstr "密碼不能為空白"
|
|||||||
msgid "Authentication dialog was dismissed by the user"
|
msgid "Authentication dialog was dismissed by the user"
|
||||||
msgstr "核對對話盒被使用者取消了"
|
msgstr "核對對話盒被使用者取消了"
|
||||||
|
|
||||||
|
#: subprojects/extensions-app/data/metainfo/org.gnome.Extensions.metainfo.xml.in:5
|
||||||
|
#: subprojects/extensions-app/data/org.gnome.Extensions.desktop.in.in:4
|
||||||
|
#: subprojects/extensions-app/js/main.js:182
|
||||||
|
#: subprojects/extensions-app/data/ui/extensions-window.ui:61
|
||||||
|
msgid "Extensions"
|
||||||
|
msgstr "擴充套件"
|
||||||
|
|
||||||
|
#: subprojects/extensions-app/data/metainfo/org.gnome.Extensions.metainfo.xml.in:6
|
||||||
|
#: subprojects/extensions-app/js/main.js:183
|
||||||
|
msgid "Manage your GNOME Extensions"
|
||||||
|
msgstr "管理 GNOME Shell 擴充套件"
|
||||||
|
|
||||||
|
#: subprojects/extensions-app/data/metainfo/org.gnome.Extensions.metainfo.xml.in:35
|
||||||
|
msgid ""
|
||||||
|
"GNOME Extensions handles updating extensions, configuring extension "
|
||||||
|
"preferences and removing or disabling unwanted extensions."
|
||||||
|
msgstr ""
|
||||||
|
"GNOME 擴充套件,能處理擴充套件的更新、調整擴充套件偏好設定、移除或停用不想用"
|
||||||
|
"的擴充套件等。"
|
||||||
|
|
||||||
|
#: subprojects/extensions-app/data/org.gnome.Extensions.desktop.in.in:7
|
||||||
|
msgid "Configure GNOME Shell Extensions"
|
||||||
|
msgstr "設定 GNOME Shell 擴充套件"
|
||||||
|
|
||||||
|
#: subprojects/extensions-app/js/main.js:144
|
||||||
|
#, javascript-format
|
||||||
|
msgid "Remove “%s”?"
|
||||||
|
msgstr "移除“%s”?"
|
||||||
|
|
||||||
|
#: subprojects/extensions-app/js/main.js:145
|
||||||
|
msgid ""
|
||||||
|
"If you remove the extension, you need to return to download it if you want "
|
||||||
|
"to enable it again"
|
||||||
|
msgstr "如果您移除擴充套件,如果需要再次啟用,就需要回去重新下載一次"
|
||||||
|
|
||||||
|
#: subprojects/extensions-app/js/main.js:149
|
||||||
|
msgid "Remove"
|
||||||
|
msgstr "移除"
|
||||||
|
|
||||||
|
#: subprojects/extensions-app/js/main.js:181
|
||||||
|
msgid "translator-credits"
|
||||||
|
msgstr "Cheng-Chia Tseng <pswo10680@gmail.com>, 2020."
|
||||||
|
|
||||||
|
#: subprojects/extensions-app/js/main.js:316
|
||||||
|
#, javascript-format
|
||||||
|
msgid "%d extension will be updated on next login."
|
||||||
|
msgid_plural "%d extensions will be updated on next login."
|
||||||
|
msgstr[0] "%d 個擴充套件會在下次登入時更新。"
|
||||||
|
|
||||||
|
#: subprojects/extensions-app/data/ui/extension-row.ui:100
|
||||||
|
#: subprojects/extensions-tool/src/command-create.c:211
|
||||||
|
#: subprojects/extensions-tool/src/main.c:173
|
||||||
|
msgid "Description"
|
||||||
|
msgstr "描述"
|
||||||
|
|
||||||
|
#: subprojects/extensions-app/data/ui/extension-row.ui:123
|
||||||
|
#: subprojects/extensions-tool/src/main.c:185
|
||||||
|
msgid "Version"
|
||||||
|
msgstr "版本"
|
||||||
|
|
||||||
|
#: subprojects/extensions-app/data/ui/extension-row.ui:151
|
||||||
|
msgid "Author"
|
||||||
|
msgstr "作者"
|
||||||
|
|
||||||
|
#: subprojects/extensions-app/data/ui/extension-row.ui:175
|
||||||
|
msgid "Website"
|
||||||
|
msgstr "網站"
|
||||||
|
|
||||||
|
#: subprojects/extensions-app/data/ui/extension-row.ui:192
|
||||||
|
msgid "Remove…"
|
||||||
|
msgstr "移除…"
|
||||||
|
|
||||||
|
#: subprojects/extensions-app/data/ui/extensions-window.ui:8
|
||||||
|
msgid "Help"
|
||||||
|
msgstr "求助"
|
||||||
|
|
||||||
|
#: subprojects/extensions-app/data/ui/extensions-window.ui:12
|
||||||
|
msgid "About Extensions"
|
||||||
|
msgstr "關於擴充套件"
|
||||||
|
|
||||||
|
#: subprojects/extensions-app/data/ui/extensions-window.ui:27
|
||||||
|
msgid ""
|
||||||
|
"To find and add extensions, visit <a href=\"https://extensions.gnome.org"
|
||||||
|
"\">extensions.gnome.org</a>."
|
||||||
|
msgstr ""
|
||||||
|
"要尋找並加入擴充套件,可以到 <a href=\"https://extensions.gnome.org"
|
||||||
|
"\">extensions.gnome.org</a> 安裝。"
|
||||||
|
|
||||||
|
#: subprojects/extensions-app/data/ui/extensions-window.ui:35
|
||||||
|
msgid "Warning"
|
||||||
|
msgstr "警告"
|
||||||
|
|
||||||
|
#: subprojects/extensions-app/data/ui/extensions-window.ui:46
|
||||||
|
msgid ""
|
||||||
|
"Extensions can cause system issues, including performance problems. If you "
|
||||||
|
"encounter problems with your system, it is recommended to disable all "
|
||||||
|
"extensions."
|
||||||
|
msgstr ""
|
||||||
|
"擴充套件可能會造成系統問題,包含效能問題。如果您遇到系統問題,建議您先停用所"
|
||||||
|
"有的擴充套件。"
|
||||||
|
|
||||||
|
#: subprojects/extensions-app/data/ui/extensions-window.ui:134
|
||||||
|
msgid "Manually Installed"
|
||||||
|
msgstr "手動安裝"
|
||||||
|
|
||||||
|
#: subprojects/extensions-app/data/ui/extensions-window.ui:158
|
||||||
|
msgid "Built-In"
|
||||||
|
msgstr "內建"
|
||||||
|
|
||||||
|
#: subprojects/extensions-app/data/ui/extensions-window.ui:199
|
||||||
|
msgid "No Installed Extensions"
|
||||||
|
msgstr "沒有已安裝的擴充套件"
|
||||||
|
|
||||||
|
#: subprojects/extensions-app/data/ui/extensions-window.ui:235
|
||||||
|
msgid ""
|
||||||
|
"We’re very sorry, but it was not possible to get the list of installed "
|
||||||
|
"extensions. Make sure you are logged into GNOME and try again."
|
||||||
|
msgstr ""
|
||||||
|
"非常抱歉,但無法取得已安裝擴充套件的清單。請確定您已登入 GNOME 後重試。"
|
||||||
|
|
||||||
|
#: subprojects/extensions-app/data/ui/extensions-window.ui:288
|
||||||
|
msgid "Log Out…"
|
||||||
|
msgstr "登出…"
|
||||||
|
|
||||||
#. Translators: a file path to an extension directory
|
#. Translators: a file path to an extension directory
|
||||||
#: subprojects/extensions-tool/src/command-create.c:125
|
#: subprojects/extensions-tool/src/command-create.c:125
|
||||||
#, c-format
|
#, c-format
|
||||||
@ -2742,6 +2754,9 @@ msgstr[0] "%u 輸入"
|
|||||||
msgid "System Sounds"
|
msgid "System Sounds"
|
||||||
msgstr "系統音效"
|
msgstr "系統音效"
|
||||||
|
|
||||||
|
#~ msgid "Copy Error"
|
||||||
|
#~ msgstr "複製錯誤"
|
||||||
|
|
||||||
#~ msgid "Browse in Software"
|
#~ msgid "Browse in Software"
|
||||||
#~ msgstr "在《軟體》中瀏覽"
|
#~ msgstr "在《軟體》中瀏覽"
|
||||||
|
|
||||||
@ -2785,9 +2800,6 @@ msgstr "系統音效"
|
|||||||
#~ msgid_plural "%d new notifications"
|
#~ msgid_plural "%d new notifications"
|
||||||
#~ msgstr[0] "%d 個新通知"
|
#~ msgstr[0] "%d 個新通知"
|
||||||
|
|
||||||
#~ msgid "Log in as another user"
|
|
||||||
#~ msgstr "以另一個使用者身分登入"
|
|
||||||
|
|
||||||
#~ msgid ""
|
#~ msgid ""
|
||||||
#~ "Keybinding that pauses and resumes all running tweens, for debugging "
|
#~ "Keybinding that pauses and resumes all running tweens, for debugging "
|
||||||
#~ "purposes"
|
#~ "purposes"
|
||||||
|
@ -45,199 +45,155 @@ struct _ClientData
|
|||||||
gulong backend_died_id;
|
gulong backend_died_id;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _CalendarSourceData
|
|
||||||
{
|
|
||||||
ECalClientSourceType source_type;
|
|
||||||
CalendarSources *sources;
|
|
||||||
guint changed_signal;
|
|
||||||
|
|
||||||
/* ESource -> EClient */
|
|
||||||
GHashTable *clients;
|
|
||||||
|
|
||||||
guint timeout_id;
|
|
||||||
|
|
||||||
guint loaded : 1;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct _CalendarSourcesPrivate CalendarSourcesPrivate;
|
typedef struct _CalendarSourcesPrivate CalendarSourcesPrivate;
|
||||||
|
|
||||||
struct _CalendarSources
|
struct _CalendarSources
|
||||||
{
|
{
|
||||||
GObject parent;
|
GObject parent;
|
||||||
CalendarSourcesPrivate *priv;
|
|
||||||
|
ESourceRegistryWatcher *registry_watcher;
|
||||||
|
gulong filter_id;
|
||||||
|
gulong appeared_id;
|
||||||
|
gulong disappeared_id;
|
||||||
|
|
||||||
|
GMutex clients_lock;
|
||||||
|
GHashTable *clients; /* ESource -> ClientData */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _CalendarSourcesPrivate
|
G_DEFINE_TYPE (CalendarSources, calendar_sources, G_TYPE_OBJECT)
|
||||||
{
|
|
||||||
ESourceRegistry *registry;
|
|
||||||
gulong source_added_id;
|
|
||||||
gulong source_changed_id;
|
|
||||||
gulong source_removed_id;
|
|
||||||
|
|
||||||
CalendarSourceData appointment_sources;
|
|
||||||
CalendarSourceData task_sources;
|
|
||||||
};
|
|
||||||
|
|
||||||
G_DEFINE_TYPE_WITH_PRIVATE (CalendarSources, calendar_sources, G_TYPE_OBJECT)
|
|
||||||
|
|
||||||
static void calendar_sources_finalize (GObject *object);
|
|
||||||
|
|
||||||
static void backend_died_cb (EClient *client, CalendarSourceData *source_data);
|
|
||||||
static void calendar_sources_registry_source_changed_cb (ESourceRegistry *registry,
|
|
||||||
ESource *source,
|
|
||||||
CalendarSources *sources);
|
|
||||||
static void calendar_sources_registry_source_removed_cb (ESourceRegistry *registry,
|
|
||||||
ESource *source,
|
|
||||||
CalendarSources *sources);
|
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
APPOINTMENT_SOURCES_CHANGED,
|
CLIENT_APPEARED,
|
||||||
TASK_SOURCES_CHANGED,
|
CLIENT_DISAPPEARED,
|
||||||
LAST_SIGNAL
|
LAST_SIGNAL
|
||||||
};
|
};
|
||||||
static guint signals [LAST_SIGNAL] = { 0, };
|
static guint signals [LAST_SIGNAL] = { 0, };
|
||||||
|
|
||||||
static GObjectClass *parent_class = NULL;
|
static void
|
||||||
static CalendarSources *calendar_sources_singleton = NULL;
|
calendar_sources_client_connected_cb (GObject *source_object,
|
||||||
|
GAsyncResult *result,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
CalendarSources *sources = CALENDAR_SOURCES (source_object);
|
||||||
|
ESource *source = user_data;
|
||||||
|
EClient *client;
|
||||||
|
g_autoptr (GError) error = NULL;
|
||||||
|
|
||||||
|
/* The calendar_sources_connect_client_sync() already stored the 'client'
|
||||||
|
* into the sources->clients */
|
||||||
|
client = calendar_sources_connect_client_finish (sources, result, &error);
|
||||||
|
if (error)
|
||||||
|
{
|
||||||
|
g_warning ("Could not load source '%s': %s",
|
||||||
|
e_source_get_uid (source),
|
||||||
|
error->message);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_signal_emit (sources, signals[CLIENT_APPEARED], 0, client, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_clear_object (&client);
|
||||||
|
g_clear_object (&source);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
registry_watcher_filter_cb (ESourceRegistryWatcher *watcher,
|
||||||
|
ESource *source,
|
||||||
|
CalendarSources *sources)
|
||||||
|
{
|
||||||
|
return e_source_has_extension (source, E_SOURCE_EXTENSION_CALENDAR) &&
|
||||||
|
e_source_selectable_get_selected (e_source_get_extension (source, E_SOURCE_EXTENSION_CALENDAR));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
registry_watcher_source_appeared_cb (ESourceRegistryWatcher *watcher,
|
||||||
|
ESource *source,
|
||||||
|
CalendarSources *sources)
|
||||||
|
{
|
||||||
|
ECalClientSourceType source_type;
|
||||||
|
|
||||||
|
if (e_source_has_extension (source, E_SOURCE_EXTENSION_CALENDAR))
|
||||||
|
source_type = E_CAL_CLIENT_SOURCE_TYPE_EVENTS;
|
||||||
|
else if (e_source_has_extension (source, E_SOURCE_EXTENSION_MEMO_LIST))
|
||||||
|
source_type = E_CAL_CLIENT_SOURCE_TYPE_MEMOS;
|
||||||
|
else if (e_source_has_extension (source, E_SOURCE_EXTENSION_TASK_LIST))
|
||||||
|
source_type = E_CAL_CLIENT_SOURCE_TYPE_TASKS;
|
||||||
|
else
|
||||||
|
g_return_if_reached ();
|
||||||
|
|
||||||
|
calendar_sources_connect_client (sources, source, source_type, 30, NULL, calendar_sources_client_connected_cb, g_object_ref (source));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
registry_watcher_source_disappeared_cb (ESourceRegistryWatcher *watcher,
|
||||||
|
ESource *source,
|
||||||
|
CalendarSources *sources)
|
||||||
|
{
|
||||||
|
gboolean emit;
|
||||||
|
|
||||||
|
g_mutex_lock (&sources->clients_lock);
|
||||||
|
|
||||||
|
emit = g_hash_table_remove (sources->clients, source);
|
||||||
|
|
||||||
|
g_mutex_unlock (&sources->clients_lock);
|
||||||
|
|
||||||
|
if (emit)
|
||||||
|
g_signal_emit (sources, signals[CLIENT_DISAPPEARED], 0, e_source_get_uid (source), NULL);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
client_data_free (ClientData *data)
|
client_data_free (ClientData *data)
|
||||||
{
|
{
|
||||||
g_clear_signal_handler (&data->backend_died_id, data->client);
|
g_signal_handler_disconnect (data->client, data->backend_died_id);
|
||||||
g_object_unref (data->client);
|
g_object_unref (data->client);
|
||||||
g_slice_free (ClientData, data);
|
g_slice_free (ClientData, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
calendar_sources_class_init (CalendarSourcesClass *klass)
|
calendar_sources_constructed (GObject *object)
|
||||||
{
|
|
||||||
GObjectClass *gobject_class = (GObjectClass *) klass;
|
|
||||||
|
|
||||||
parent_class = g_type_class_peek_parent (klass);
|
|
||||||
|
|
||||||
gobject_class->finalize = calendar_sources_finalize;
|
|
||||||
|
|
||||||
signals [APPOINTMENT_SOURCES_CHANGED] =
|
|
||||||
g_signal_new ("appointment-sources-changed",
|
|
||||||
G_TYPE_FROM_CLASS (gobject_class),
|
|
||||||
G_SIGNAL_RUN_LAST,
|
|
||||||
0,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
G_TYPE_NONE,
|
|
||||||
0);
|
|
||||||
|
|
||||||
signals [TASK_SOURCES_CHANGED] =
|
|
||||||
g_signal_new ("task-sources-changed",
|
|
||||||
G_TYPE_FROM_CLASS (gobject_class),
|
|
||||||
G_SIGNAL_RUN_LAST,
|
|
||||||
0,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
G_TYPE_NONE,
|
|
||||||
0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
calendar_sources_init (CalendarSources *sources)
|
|
||||||
{
|
{
|
||||||
|
CalendarSources *sources = CALENDAR_SOURCES (object);
|
||||||
|
ESourceRegistry *registry = NULL;
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
GDBusConnection *session_bus;
|
|
||||||
GVariant *result;
|
|
||||||
|
|
||||||
sources->priv = calendar_sources_get_instance_private (sources);
|
G_OBJECT_CLASS (calendar_sources_parent_class)->constructed (object);
|
||||||
|
|
||||||
/* WORKAROUND: the hardcoded timeout for e_source_registry_new_sync()
|
|
||||||
(and other library calls that eventually call g_dbus_proxy_new[_sync]())
|
|
||||||
is 25 seconds. This has been shown to be too small for
|
|
||||||
evolution-source-registry in certain cases (slow disk, concurrent IO,
|
|
||||||
many configured sources), so we first ensure that the service
|
|
||||||
starts with a manual call and a higher timeout.
|
|
||||||
|
|
||||||
HACK: every time the DBus API is bumped in e-d-s we need
|
|
||||||
to update this!
|
|
||||||
*/
|
|
||||||
session_bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
|
|
||||||
if (session_bus == NULL)
|
|
||||||
{
|
|
||||||
g_error ("Failed to connect to the session bus: %s", error->message);
|
|
||||||
}
|
|
||||||
|
|
||||||
result = g_dbus_connection_call_sync (session_bus, "org.freedesktop.DBus",
|
|
||||||
"/", "org.freedesktop.DBus",
|
|
||||||
"StartServiceByName",
|
|
||||||
g_variant_new ("(su)",
|
|
||||||
"org.gnome.evolution.dataserver.Sources5",
|
|
||||||
0),
|
|
||||||
NULL,
|
|
||||||
G_DBUS_CALL_FLAGS_NONE,
|
|
||||||
60 * 1000,
|
|
||||||
NULL, &error);
|
|
||||||
if (result != NULL)
|
|
||||||
{
|
|
||||||
g_variant_unref (result);
|
|
||||||
sources->priv->registry = e_source_registry_new_sync (NULL, &error);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
registry = e_source_registry_new_sync (NULL, &error);
|
||||||
if (error != NULL)
|
if (error != NULL)
|
||||||
{
|
{
|
||||||
/* Any error is fatal, but we don't want to crash gnome-shell-calendar-server
|
/* Any error is fatal, but we don't want to crash gnome-shell-calendar-server
|
||||||
because of e-d-s problems. So just exit here.
|
because of e-d-s problems. So just exit here.
|
||||||
*/
|
*/
|
||||||
g_warning ("Failed to start evolution-source-registry: %s", error->message);
|
g_warning ("Failed to start evolution-source-registry: %s", error->message);
|
||||||
exit(EXIT_FAILURE);
|
exit (EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_object_unref (session_bus);
|
g_return_if_fail (registry != NULL);
|
||||||
|
|
||||||
sources->priv->source_added_id = g_signal_connect (sources->priv->registry,
|
sources->registry_watcher = e_source_registry_watcher_new (registry, NULL);
|
||||||
"source-added",
|
|
||||||
G_CALLBACK (calendar_sources_registry_source_changed_cb),
|
|
||||||
sources);
|
|
||||||
sources->priv->source_changed_id = g_signal_connect (sources->priv->registry,
|
|
||||||
"source-changed",
|
|
||||||
G_CALLBACK (calendar_sources_registry_source_changed_cb),
|
|
||||||
sources);
|
|
||||||
sources->priv->source_removed_id = g_signal_connect (sources->priv->registry,
|
|
||||||
"source-removed",
|
|
||||||
G_CALLBACK (calendar_sources_registry_source_removed_cb),
|
|
||||||
sources);
|
|
||||||
|
|
||||||
sources->priv->appointment_sources.source_type = E_CAL_CLIENT_SOURCE_TYPE_EVENTS;
|
g_clear_object (®istry);
|
||||||
sources->priv->appointment_sources.sources = sources;
|
|
||||||
sources->priv->appointment_sources.changed_signal = signals [APPOINTMENT_SOURCES_CHANGED];
|
|
||||||
sources->priv->appointment_sources.clients = g_hash_table_new_full ((GHashFunc) e_source_hash,
|
|
||||||
(GEqualFunc) e_source_equal,
|
|
||||||
(GDestroyNotify) g_object_unref,
|
|
||||||
(GDestroyNotify) client_data_free);
|
|
||||||
sources->priv->appointment_sources.timeout_id = 0;
|
|
||||||
|
|
||||||
sources->priv->task_sources.source_type = E_CAL_CLIENT_SOURCE_TYPE_TASKS;
|
sources->clients = g_hash_table_new_full ((GHashFunc) e_source_hash,
|
||||||
sources->priv->task_sources.sources = sources;
|
(GEqualFunc) e_source_equal,
|
||||||
sources->priv->task_sources.changed_signal = signals [TASK_SOURCES_CHANGED];
|
(GDestroyNotify) g_object_unref,
|
||||||
sources->priv->task_sources.clients = g_hash_table_new_full ((GHashFunc) e_source_hash,
|
(GDestroyNotify) client_data_free);
|
||||||
(GEqualFunc) e_source_equal,
|
sources->filter_id = g_signal_connect (sources->registry_watcher,
|
||||||
(GDestroyNotify) g_object_unref,
|
"filter",
|
||||||
(GDestroyNotify) client_data_free);
|
G_CALLBACK (registry_watcher_filter_cb),
|
||||||
sources->priv->task_sources.timeout_id = 0;
|
sources);
|
||||||
}
|
sources->appeared_id = g_signal_connect (sources->registry_watcher,
|
||||||
|
"appeared",
|
||||||
|
G_CALLBACK (registry_watcher_source_appeared_cb),
|
||||||
|
sources);
|
||||||
|
sources->disappeared_id = g_signal_connect (sources->registry_watcher,
|
||||||
|
"disappeared",
|
||||||
|
G_CALLBACK (registry_watcher_source_disappeared_cb),
|
||||||
|
sources);
|
||||||
|
|
||||||
static void
|
e_source_registry_watcher_reclaim (sources->registry_watcher);
|
||||||
calendar_sources_finalize_source_data (CalendarSources *sources,
|
|
||||||
CalendarSourceData *source_data)
|
|
||||||
{
|
|
||||||
if (source_data->loaded)
|
|
||||||
{
|
|
||||||
g_hash_table_destroy (source_data->clients);
|
|
||||||
source_data->clients = NULL;
|
|
||||||
|
|
||||||
g_clear_handle_id (&source_data->timeout_id, g_source_remove);
|
|
||||||
|
|
||||||
source_data->loaded = FALSE;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -245,28 +201,67 @@ calendar_sources_finalize (GObject *object)
|
|||||||
{
|
{
|
||||||
CalendarSources *sources = CALENDAR_SOURCES (object);
|
CalendarSources *sources = CALENDAR_SOURCES (object);
|
||||||
|
|
||||||
if (sources->priv->registry)
|
g_clear_pointer (&sources->clients, g_hash_table_destroy);
|
||||||
|
|
||||||
|
if (sources->registry_watcher)
|
||||||
{
|
{
|
||||||
g_clear_signal_handler (&sources->priv->source_added_id,
|
g_signal_handler_disconnect (sources->registry_watcher,
|
||||||
sources->priv->registry);
|
sources->filter_id);
|
||||||
g_clear_signal_handler (&sources->priv->source_changed_id,
|
g_signal_handler_disconnect (sources->registry_watcher,
|
||||||
sources->priv->registry);
|
sources->appeared_id);
|
||||||
g_clear_signal_handler (&sources->priv->source_removed_id,
|
g_signal_handler_disconnect (sources->registry_watcher,
|
||||||
sources->priv->registry);
|
sources->disappeared_id);
|
||||||
g_object_unref (sources->priv->registry);
|
g_clear_object (&sources->registry_watcher);
|
||||||
}
|
}
|
||||||
sources->priv->registry = NULL;
|
|
||||||
|
|
||||||
calendar_sources_finalize_source_data (sources, &sources->priv->appointment_sources);
|
g_mutex_clear (&sources->clients_lock);
|
||||||
calendar_sources_finalize_source_data (sources, &sources->priv->task_sources);
|
|
||||||
|
|
||||||
if (G_OBJECT_CLASS (parent_class)->finalize)
|
G_OBJECT_CLASS (calendar_sources_parent_class)->finalize (object);
|
||||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
calendar_sources_class_init (CalendarSourcesClass *klass)
|
||||||
|
{
|
||||||
|
GObjectClass *gobject_class = (GObjectClass *) klass;
|
||||||
|
|
||||||
|
gobject_class->constructed = calendar_sources_constructed;
|
||||||
|
gobject_class->finalize = calendar_sources_finalize;
|
||||||
|
|
||||||
|
signals [CLIENT_APPEARED] =
|
||||||
|
g_signal_new ("client-appeared",
|
||||||
|
G_TYPE_FROM_CLASS (gobject_class),
|
||||||
|
G_SIGNAL_RUN_LAST,
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
G_TYPE_NONE,
|
||||||
|
1,
|
||||||
|
E_TYPE_CAL_CLIENT);
|
||||||
|
|
||||||
|
signals [CLIENT_DISAPPEARED] =
|
||||||
|
g_signal_new ("client-disappeared",
|
||||||
|
G_TYPE_FROM_CLASS (gobject_class),
|
||||||
|
G_SIGNAL_RUN_LAST,
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
G_TYPE_NONE,
|
||||||
|
1,
|
||||||
|
G_TYPE_STRING); /* ESource::uid of the disappeared client */
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
calendar_sources_init (CalendarSources *sources)
|
||||||
|
{
|
||||||
|
g_mutex_init (&sources->clients_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
CalendarSources *
|
CalendarSources *
|
||||||
calendar_sources_get (void)
|
calendar_sources_get (void)
|
||||||
{
|
{
|
||||||
|
static CalendarSources *calendar_sources_singleton = NULL;
|
||||||
gpointer singleton_location = &calendar_sources_singleton;
|
gpointer singleton_location = &calendar_sources_singleton;
|
||||||
|
|
||||||
if (calendar_sources_singleton)
|
if (calendar_sources_singleton)
|
||||||
@ -274,85 +269,70 @@ calendar_sources_get (void)
|
|||||||
|
|
||||||
calendar_sources_singleton = g_object_new (CALENDAR_TYPE_SOURCES, NULL);
|
calendar_sources_singleton = g_object_new (CALENDAR_TYPE_SOURCES, NULL);
|
||||||
g_object_add_weak_pointer (G_OBJECT (calendar_sources_singleton),
|
g_object_add_weak_pointer (G_OBJECT (calendar_sources_singleton),
|
||||||
singleton_location);
|
singleton_location);
|
||||||
|
|
||||||
return calendar_sources_singleton;
|
return calendar_sources_singleton;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The clients are just created here but not loaded */
|
ESourceRegistry *
|
||||||
static void
|
calendar_sources_get_registry (CalendarSources *sources)
|
||||||
create_client_for_source (ESource *source,
|
|
||||||
ECalClientSourceType source_type,
|
|
||||||
CalendarSourceData *source_data)
|
|
||||||
{
|
{
|
||||||
ClientData *data;
|
return e_source_registry_watcher_get_registry (sources->registry_watcher);
|
||||||
EClient *client;
|
|
||||||
GError *error = NULL;
|
|
||||||
|
|
||||||
client = g_hash_table_lookup (source_data->clients, source);
|
|
||||||
g_return_if_fail (client == NULL);
|
|
||||||
|
|
||||||
client = e_cal_client_connect_sync (source, source_type, -1, NULL, &error);
|
|
||||||
if (!client)
|
|
||||||
{
|
|
||||||
g_warning ("Could not load source '%s': %s",
|
|
||||||
e_source_get_uid (source),
|
|
||||||
error->message);
|
|
||||||
g_clear_error(&error);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
data = g_slice_new0 (ClientData);
|
|
||||||
data->client = E_CAL_CLIENT (client); /* takes ownership */
|
|
||||||
data->backend_died_id = g_signal_connect (client,
|
|
||||||
"backend-died",
|
|
||||||
G_CALLBACK (backend_died_cb),
|
|
||||||
source_data);
|
|
||||||
|
|
||||||
g_hash_table_insert (source_data->clients, g_object_ref (source), data);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
debug_dump_ecal_list (GHashTable *clients)
|
|
||||||
{
|
|
||||||
#ifdef CALENDAR_ENABLE_DEBUG
|
|
||||||
GList *list, *link;
|
|
||||||
|
|
||||||
dprintf ("Loaded clients:\n");
|
|
||||||
list = g_hash_table_get_keys (clients);
|
|
||||||
for (link = list; link != NULL; link = g_list_next (link))
|
|
||||||
{
|
|
||||||
ESource *source = E_SOURCE (link->data);
|
|
||||||
|
|
||||||
dprintf (" %s %s\n",
|
|
||||||
e_source_get_uid (source),
|
|
||||||
e_source_get_display_name (source));
|
|
||||||
}
|
|
||||||
g_list_free (list);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
calendar_sources_load_esource_list (ESourceRegistry *registry,
|
gather_event_clients_cb (gpointer key,
|
||||||
CalendarSourceData *source_data);
|
gpointer value,
|
||||||
|
gpointer user_data)
|
||||||
static gboolean
|
|
||||||
backend_restart (gpointer data)
|
|
||||||
{
|
{
|
||||||
CalendarSourceData *source_data = data;
|
GSList **plist = user_data;
|
||||||
ESourceRegistry *registry;
|
ClientData *cd = value;
|
||||||
|
|
||||||
registry = source_data->sources->priv->registry;
|
if (cd)
|
||||||
calendar_sources_load_esource_list (registry, source_data);
|
*plist = g_slist_prepend (*plist, g_object_ref (cd->client));
|
||||||
g_signal_emit (source_data->sources, source_data->changed_signal, 0);
|
}
|
||||||
|
|
||||||
source_data->timeout_id = 0;
|
GSList *
|
||||||
|
calendar_sources_ref_clients (CalendarSources *sources)
|
||||||
return FALSE;
|
{
|
||||||
|
GSList *list = NULL;
|
||||||
|
|
||||||
|
g_return_val_if_fail (CALENDAR_IS_SOURCES (sources), NULL);
|
||||||
|
|
||||||
|
g_mutex_lock (&sources->clients_lock);
|
||||||
|
g_hash_table_foreach (sources->clients, gather_event_clients_cb, &list);
|
||||||
|
g_mutex_unlock (&sources->clients_lock);
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
calendar_sources_has_clients (CalendarSources *sources)
|
||||||
|
{
|
||||||
|
GHashTableIter iter;
|
||||||
|
gpointer value;
|
||||||
|
gboolean has = FALSE;
|
||||||
|
|
||||||
|
g_return_val_if_fail (CALENDAR_IS_SOURCES (sources), FALSE);
|
||||||
|
|
||||||
|
g_mutex_lock (&sources->clients_lock);
|
||||||
|
|
||||||
|
g_hash_table_iter_init (&iter, sources->clients);
|
||||||
|
while (!has && g_hash_table_iter_next (&iter, NULL, &value))
|
||||||
|
{
|
||||||
|
ClientData *cd = value;
|
||||||
|
|
||||||
|
has = cd != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_mutex_unlock (&sources->clients_lock);
|
||||||
|
|
||||||
|
return has;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
backend_died_cb (EClient *client, CalendarSourceData *source_data)
|
backend_died_cb (EClient *client,
|
||||||
|
CalendarSources *sources)
|
||||||
{
|
{
|
||||||
ESource *source;
|
ESource *source;
|
||||||
const char *display_name;
|
const char *display_name;
|
||||||
@ -360,196 +340,167 @@ backend_died_cb (EClient *client, CalendarSourceData *source_data)
|
|||||||
source = e_client_get_source (client);
|
source = e_client_get_source (client);
|
||||||
display_name = e_source_get_display_name (source);
|
display_name = e_source_get_display_name (source);
|
||||||
g_warning ("The calendar backend for '%s' has crashed.", display_name);
|
g_warning ("The calendar backend for '%s' has crashed.", display_name);
|
||||||
g_hash_table_remove (source_data->clients, source);
|
g_mutex_lock (&sources->clients_lock);
|
||||||
|
g_hash_table_remove (sources->clients, source);
|
||||||
g_clear_handle_id (&source_data->timeout_id, g_source_remove);
|
g_mutex_unlock (&sources->clients_lock);
|
||||||
|
|
||||||
source_data->timeout_id = g_timeout_add_seconds (2, backend_restart,
|
|
||||||
source_data);
|
|
||||||
g_source_set_name_by_id (source_data->timeout_id, "[gnome-shell] backend_restart");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static EClient *
|
||||||
calendar_sources_load_esource_list (ESourceRegistry *registry,
|
calendar_sources_connect_client_sync (CalendarSources *sources,
|
||||||
CalendarSourceData *source_data)
|
ESource *source,
|
||||||
|
ECalClientSourceType source_type,
|
||||||
|
guint32 wait_for_connected_seconds,
|
||||||
|
GCancellable *cancellable,
|
||||||
|
GError **error)
|
||||||
{
|
{
|
||||||
GList *list, *link;
|
EClient *client = NULL;
|
||||||
const gchar *extension_name;
|
ClientData *client_data;
|
||||||
|
|
||||||
switch (source_data->source_type)
|
g_mutex_lock (&sources->clients_lock);
|
||||||
|
client_data = g_hash_table_lookup (sources->clients, source);
|
||||||
|
if (client_data)
|
||||||
|
client = E_CLIENT (g_object_ref (client_data->client));
|
||||||
|
g_mutex_unlock (&sources->clients_lock);
|
||||||
|
|
||||||
|
if (client)
|
||||||
|
return client;
|
||||||
|
|
||||||
|
client = e_cal_client_connect_sync (source, source_type, wait_for_connected_seconds, cancellable, error);
|
||||||
|
if (!client)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
g_mutex_lock (&sources->clients_lock);
|
||||||
|
client_data = g_hash_table_lookup (sources->clients, source);
|
||||||
|
if (client_data)
|
||||||
{
|
{
|
||||||
case E_CAL_CLIENT_SOURCE_TYPE_EVENTS:
|
g_clear_object (&client);
|
||||||
extension_name = E_SOURCE_EXTENSION_CALENDAR;
|
client = E_CLIENT (g_object_ref (client_data->client));
|
||||||
break;
|
|
||||||
case E_CAL_CLIENT_SOURCE_TYPE_TASKS:
|
|
||||||
extension_name = E_SOURCE_EXTENSION_TASK_LIST;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
g_return_if_reached ();
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
list = e_source_registry_list_sources (registry, extension_name);
|
|
||||||
|
|
||||||
for (link = list; link != NULL; link = g_list_next (link))
|
|
||||||
{
|
{
|
||||||
ESource *source = E_SOURCE (link->data);
|
client_data = g_slice_new0 (ClientData);
|
||||||
ESourceSelectable *extension;
|
client_data->client = E_CAL_CLIENT (g_object_ref (client));
|
||||||
gboolean show_source;
|
client_data->backend_died_id = g_signal_connect (client,
|
||||||
|
"backend-died",
|
||||||
|
G_CALLBACK (backend_died_cb),
|
||||||
|
sources);
|
||||||
|
|
||||||
extension = e_source_get_extension (source, extension_name);
|
g_hash_table_insert (sources->clients, g_object_ref (source), client_data);
|
||||||
show_source = e_source_get_enabled (source) && e_source_selectable_get_selected (extension);
|
|
||||||
|
|
||||||
if (show_source)
|
|
||||||
create_client_for_source (source, source_data->source_type, source_data);
|
|
||||||
}
|
}
|
||||||
|
g_mutex_unlock (&sources->clients_lock);
|
||||||
|
|
||||||
debug_dump_ecal_list (source_data->clients);
|
return client;
|
||||||
|
|
||||||
g_list_free_full (list, g_object_unref);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct _AsyncContext {
|
||||||
|
ESource *source;
|
||||||
|
ECalClientSourceType source_type;
|
||||||
|
guint32 wait_for_connected_seconds;
|
||||||
|
} AsyncContext;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
calendar_sources_registry_source_changed_cb (ESourceRegistry *registry,
|
async_context_free (gpointer ptr)
|
||||||
ESource *source,
|
|
||||||
CalendarSources *sources)
|
|
||||||
{
|
{
|
||||||
if (e_source_has_extension (source, E_SOURCE_EXTENSION_CALENDAR))
|
AsyncContext *ctx = ptr;
|
||||||
|
|
||||||
|
if (ctx)
|
||||||
{
|
{
|
||||||
CalendarSourceData *source_data;
|
g_clear_object (&ctx->source);
|
||||||
ESourceSelectable *extension;
|
g_slice_free (AsyncContext, ctx);
|
||||||
gboolean have_client;
|
|
||||||
gboolean show_source;
|
|
||||||
|
|
||||||
source_data = &sources->priv->appointment_sources;
|
|
||||||
extension = e_source_get_extension (source, E_SOURCE_EXTENSION_CALENDAR);
|
|
||||||
have_client = (g_hash_table_lookup (source_data->clients, source) != NULL);
|
|
||||||
show_source = e_source_get_enabled (source) && e_source_selectable_get_selected (extension);
|
|
||||||
|
|
||||||
if (!show_source && have_client)
|
|
||||||
{
|
|
||||||
g_hash_table_remove (source_data->clients, source);
|
|
||||||
g_signal_emit (sources, source_data->changed_signal, 0);
|
|
||||||
}
|
|
||||||
if (show_source && !have_client)
|
|
||||||
{
|
|
||||||
create_client_for_source (source, source_data->source_type, source_data);
|
|
||||||
g_signal_emit (sources, source_data->changed_signal, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (e_source_has_extension (source, E_SOURCE_EXTENSION_TASK_LIST))
|
|
||||||
{
|
|
||||||
CalendarSourceData *source_data;
|
|
||||||
ESourceSelectable *extension;
|
|
||||||
gboolean have_client;
|
|
||||||
gboolean show_source;
|
|
||||||
|
|
||||||
source_data = &sources->priv->task_sources;
|
|
||||||
extension = e_source_get_extension (source, E_SOURCE_EXTENSION_TASK_LIST);
|
|
||||||
have_client = (g_hash_table_lookup (source_data->clients, source) != NULL);
|
|
||||||
show_source = e_source_get_enabled (source) && e_source_selectable_get_selected (extension);
|
|
||||||
|
|
||||||
if (!show_source && have_client)
|
|
||||||
{
|
|
||||||
g_hash_table_remove (source_data->clients, source);
|
|
||||||
g_signal_emit (sources, source_data->changed_signal, 0);
|
|
||||||
}
|
|
||||||
if (show_source && !have_client)
|
|
||||||
{
|
|
||||||
create_client_for_source (source, source_data->source_type, source_data);
|
|
||||||
g_signal_emit (sources, source_data->changed_signal, 0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
calendar_sources_registry_source_removed_cb (ESourceRegistry *registry,
|
calendar_sources_connect_client_thread (GTask *task,
|
||||||
ESource *source,
|
gpointer source_object,
|
||||||
CalendarSources *sources)
|
gpointer task_data,
|
||||||
|
GCancellable *cancellable)
|
||||||
{
|
{
|
||||||
if (e_source_has_extension (source, E_SOURCE_EXTENSION_CALENDAR))
|
CalendarSources *sources = source_object;
|
||||||
|
AsyncContext *ctx = task_data;
|
||||||
|
EClient *client;
|
||||||
|
GError *local_error = NULL;
|
||||||
|
|
||||||
|
client = calendar_sources_connect_client_sync (sources, ctx->source, ctx->source_type,
|
||||||
|
ctx->wait_for_connected_seconds, cancellable, &local_error);
|
||||||
|
if (!client)
|
||||||
{
|
{
|
||||||
CalendarSourceData *source_data;
|
if (local_error)
|
||||||
|
g_task_return_error (task, local_error);
|
||||||
source_data = &sources->priv->appointment_sources;
|
else
|
||||||
g_hash_table_remove (source_data->clients, source);
|
g_task_return_pointer (task, NULL, NULL);
|
||||||
g_signal_emit (sources, source_data->changed_signal, 0);
|
} else {
|
||||||
}
|
g_task_return_pointer (task, client, g_object_unref);
|
||||||
|
|
||||||
if (e_source_has_extension (source, E_SOURCE_EXTENSION_TASK_LIST))
|
|
||||||
{
|
|
||||||
CalendarSourceData *source_data;
|
|
||||||
|
|
||||||
source_data = &sources->priv->task_sources;
|
|
||||||
g_hash_table_remove (source_data->clients, source);
|
|
||||||
g_signal_emit (sources, source_data->changed_signal, 0);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void
|
||||||
ensure_appointment_sources (CalendarSources *sources)
|
calendar_sources_connect_client (CalendarSources *sources,
|
||||||
|
ESource *source,
|
||||||
|
ECalClientSourceType source_type,
|
||||||
|
guint32 wait_for_connected_seconds,
|
||||||
|
GCancellable *cancellable,
|
||||||
|
GAsyncReadyCallback callback,
|
||||||
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
if (!sources->priv->appointment_sources.loaded)
|
AsyncContext *ctx;
|
||||||
|
g_autoptr (GTask) task = NULL;
|
||||||
|
|
||||||
|
ctx = g_slice_new0 (AsyncContext);
|
||||||
|
ctx->source = g_object_ref (source);
|
||||||
|
ctx->source_type = source_type;
|
||||||
|
ctx->wait_for_connected_seconds = wait_for_connected_seconds;
|
||||||
|
|
||||||
|
task = g_task_new (sources, cancellable, callback, user_data);
|
||||||
|
g_task_set_source_tag (task, calendar_sources_connect_client);
|
||||||
|
g_task_set_task_data (task, ctx, async_context_free);
|
||||||
|
|
||||||
|
g_task_run_in_thread (task, calendar_sources_connect_client_thread);
|
||||||
|
}
|
||||||
|
|
||||||
|
EClient *
|
||||||
|
calendar_sources_connect_client_finish (CalendarSources *sources,
|
||||||
|
GAsyncResult *result,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (g_task_is_valid (result, sources), NULL);
|
||||||
|
g_return_val_if_fail (g_async_result_is_tagged (result, calendar_sources_connect_client), NULL);
|
||||||
|
|
||||||
|
return g_task_propagate_pointer (G_TASK (result), error);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
print_debug (const gchar *format,
|
||||||
|
...)
|
||||||
|
{
|
||||||
|
g_autofree char *s = NULL;
|
||||||
|
g_autofree char *timestamp = NULL;
|
||||||
|
va_list ap;
|
||||||
|
g_autoptr (GDateTime) now = NULL;
|
||||||
|
static volatile gsize once_init_value = 0;
|
||||||
|
static gboolean show_debug = FALSE;
|
||||||
|
static guint pid = 0;
|
||||||
|
|
||||||
|
if (g_once_init_enter (&once_init_value))
|
||||||
{
|
{
|
||||||
calendar_sources_load_esource_list (sources->priv->registry,
|
show_debug = (g_getenv ("CALENDAR_SERVER_DEBUG") != NULL);
|
||||||
&sources->priv->appointment_sources);
|
pid = getpid ();
|
||||||
sources->priv->appointment_sources.loaded = TRUE;
|
g_once_init_leave (&once_init_value, 1);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
if (!show_debug)
|
||||||
GList *
|
goto out;
|
||||||
calendar_sources_get_appointment_clients (CalendarSources *sources)
|
|
||||||
{
|
now = g_date_time_new_now_local ();
|
||||||
GList *list, *link;
|
timestamp = g_date_time_format (now, "%H:%M:%S");
|
||||||
|
|
||||||
g_return_val_if_fail (CALENDAR_IS_SOURCES (sources), NULL);
|
va_start (ap, format);
|
||||||
|
s = g_strdup_vprintf (format, ap);
|
||||||
ensure_appointment_sources (sources);
|
va_end (ap);
|
||||||
|
|
||||||
list = g_hash_table_get_values (sources->priv->appointment_sources.clients);
|
g_print ("gnome-shell-calendar-server[%d]: %s.%03d: %s\n",
|
||||||
|
pid, timestamp, g_date_time_get_microsecond (now), s);
|
||||||
for (link = list; link != NULL; link = g_list_next (link))
|
out:
|
||||||
link->data = ((ClientData *) link->data)->client;
|
;
|
||||||
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
ensure_task_sources (CalendarSources *sources)
|
|
||||||
{
|
|
||||||
if (!sources->priv->task_sources.loaded)
|
|
||||||
{
|
|
||||||
calendar_sources_load_esource_list (sources->priv->registry,
|
|
||||||
&sources->priv->task_sources);
|
|
||||||
sources->priv->task_sources.loaded = TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
GList *
|
|
||||||
calendar_sources_get_task_clients (CalendarSources *sources)
|
|
||||||
{
|
|
||||||
GList *list, *link;
|
|
||||||
|
|
||||||
g_return_val_if_fail (CALENDAR_IS_SOURCES (sources), NULL);
|
|
||||||
|
|
||||||
ensure_task_sources (sources);
|
|
||||||
|
|
||||||
list = g_hash_table_get_values (sources->priv->task_sources.clients);
|
|
||||||
|
|
||||||
for (link = list; link != NULL; link = g_list_next (link))
|
|
||||||
link->data = ((ClientData *) link->data)->client;
|
|
||||||
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
gboolean
|
|
||||||
calendar_sources_has_sources (CalendarSources *sources)
|
|
||||||
{
|
|
||||||
g_return_val_if_fail (CALENDAR_IS_SOURCES (sources), FALSE);
|
|
||||||
|
|
||||||
ensure_appointment_sources (sources);
|
|
||||||
ensure_task_sources (sources);
|
|
||||||
|
|
||||||
return g_hash_table_size (sources->priv->appointment_sources.clients) > 0 ||
|
|
||||||
g_hash_table_size (sources->priv->task_sources.clients) > 0;
|
|
||||||
}
|
}
|
||||||
|
@ -26,17 +26,38 @@
|
|||||||
|
|
||||||
#include <glib-object.h>
|
#include <glib-object.h>
|
||||||
|
|
||||||
|
#define EDS_DISABLE_DEPRECATED
|
||||||
|
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||||
|
#include <libedataserver/libedataserver.h>
|
||||||
|
#include <libecal/libecal.h>
|
||||||
|
G_GNUC_END_IGNORE_DEPRECATIONS
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
#define CALENDAR_TYPE_SOURCES (calendar_sources_get_type ())
|
#define CALENDAR_TYPE_SOURCES (calendar_sources_get_type ())
|
||||||
G_DECLARE_FINAL_TYPE (CalendarSources, calendar_sources,
|
G_DECLARE_FINAL_TYPE (CalendarSources, calendar_sources,
|
||||||
CALENDAR, SOURCES, GObject)
|
CALENDAR, SOURCES, GObject)
|
||||||
|
|
||||||
CalendarSources *calendar_sources_get (void);
|
CalendarSources *calendar_sources_get (void);
|
||||||
GList *calendar_sources_get_appointment_clients (CalendarSources *sources);
|
ESourceRegistry *calendar_sources_get_registry (CalendarSources *sources);
|
||||||
GList *calendar_sources_get_task_clients (CalendarSources *sources);
|
GSList *calendar_sources_ref_clients (CalendarSources *sources);
|
||||||
|
gboolean calendar_sources_has_clients (CalendarSources *sources);
|
||||||
|
|
||||||
gboolean calendar_sources_has_sources (CalendarSources *sources);
|
void calendar_sources_connect_client (CalendarSources *sources,
|
||||||
|
ESource *source,
|
||||||
|
ECalClientSourceType source_type,
|
||||||
|
guint32 wait_for_connected_seconds,
|
||||||
|
GCancellable *cancellable,
|
||||||
|
GAsyncReadyCallback callback,
|
||||||
|
gpointer user_data);
|
||||||
|
EClient *calendar_sources_connect_client_finish
|
||||||
|
(CalendarSources *sources,
|
||||||
|
GAsyncResult *result,
|
||||||
|
GError **error);
|
||||||
|
|
||||||
|
/* Set the environment variable CALENDAR_SERVER_DEBUG to show debug */
|
||||||
|
void print_debug (const gchar *str,
|
||||||
|
...) G_GNUC_PRINTF (1, 2);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
31
src/gnome-shell-extension-prefs
Executable file
31
src/gnome-shell-extension-prefs
Executable file
@ -0,0 +1,31 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
openPrefs() {
|
||||||
|
if [ "$(which gnome-extensions)" ]
|
||||||
|
then
|
||||||
|
gnome-extensions prefs $1
|
||||||
|
else
|
||||||
|
gdbus call --session \
|
||||||
|
--dest=org.gnome.Shell.Extensions \
|
||||||
|
--object-path=/org/gnome/Shell/Extensions \
|
||||||
|
--method=org.gnome.Shell.Extensions.OpenExtensionPrefs $1 '' '{}'
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
cat >&2 <<EOT
|
||||||
|
gnome-shell-extension-prefs is deprecated
|
||||||
|
|
||||||
|
Install https://flathub.org/apps/details/org.gnome.Extensions for extension
|
||||||
|
management, or use the gnome-extensions command line tool.
|
||||||
|
|
||||||
|
Extensions can use the ExtensionUtils.openPrefs() method.
|
||||||
|
EOT
|
||||||
|
|
||||||
|
UUID=$1
|
||||||
|
|
||||||
|
if [ "$UUID" ]
|
||||||
|
then
|
||||||
|
openPrefs $UUID
|
||||||
|
else
|
||||||
|
gapplication launch org.gnome.Extensions
|
||||||
|
fi
|
@ -31,6 +31,10 @@ foreach tool : script_tools
|
|||||||
)
|
)
|
||||||
endforeach
|
endforeach
|
||||||
|
|
||||||
|
install_data('gnome-shell-extension-prefs',
|
||||||
|
install_dir: bindir
|
||||||
|
)
|
||||||
|
|
||||||
gnome_shell_cflags = [
|
gnome_shell_cflags = [
|
||||||
'-DCLUTTER_ENABLE_EXPERIMENTAL_API',
|
'-DCLUTTER_ENABLE_EXPERIMENTAL_API',
|
||||||
'-DCOGL_ENABLE_EXPERIMENTAL_API',
|
'-DCOGL_ENABLE_EXPERIMENTAL_API',
|
||||||
|
@ -218,10 +218,17 @@ window_backed_app_get_icon (ShellApp *app,
|
|||||||
|
|
||||||
if (meta_window_get_client_type (window) == META_WINDOW_CLIENT_TYPE_X11)
|
if (meta_window_get_client_type (window) == META_WINDOW_CLIENT_TYPE_X11)
|
||||||
{
|
{
|
||||||
widget = st_texture_cache_bind_cairo_surface_property (st_texture_cache_get_default (),
|
StWidget *texture_actor;
|
||||||
G_OBJECT (window),
|
|
||||||
"icon",
|
texture_actor =
|
||||||
scaled_size);
|
st_texture_cache_bind_cairo_surface_property (st_texture_cache_get_default (),
|
||||||
|
G_OBJECT (window),
|
||||||
|
"icon",
|
||||||
|
scaled_size);
|
||||||
|
|
||||||
|
widget = g_object_new (ST_TYPE_BIN,
|
||||||
|
"child", texture_actor,
|
||||||
|
NULL);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1152,6 +1159,10 @@ shell_app_get_pids (ShellApp *app)
|
|||||||
{
|
{
|
||||||
MetaWindow *window = iter->data;
|
MetaWindow *window = iter->data;
|
||||||
int pid = meta_window_get_pid (window);
|
int pid = meta_window_get_pid (window);
|
||||||
|
|
||||||
|
if (pid < 1)
|
||||||
|
continue;
|
||||||
|
|
||||||
/* Note in the (by far) common case, app will only have one pid, so
|
/* Note in the (by far) common case, app will only have one pid, so
|
||||||
* we'll hit the first element, so don't worry about O(N^2) here.
|
* we'll hit the first element, so don't worry about O(N^2) here.
|
||||||
*/
|
*/
|
||||||
|
@ -57,6 +57,7 @@ struct _ShellGlobal {
|
|||||||
|
|
||||||
ClutterStage *stage;
|
ClutterStage *stage;
|
||||||
|
|
||||||
|
MetaBackend *backend;
|
||||||
MetaDisplay *meta_display;
|
MetaDisplay *meta_display;
|
||||||
MetaWorkspaceManager *workspace_manager;
|
MetaWorkspaceManager *workspace_manager;
|
||||||
Display *xdisplay;
|
Display *xdisplay;
|
||||||
@ -95,6 +96,7 @@ enum {
|
|||||||
PROP_0,
|
PROP_0,
|
||||||
|
|
||||||
PROP_SESSION_MODE,
|
PROP_SESSION_MODE,
|
||||||
|
PROP_BACKEND,
|
||||||
PROP_DISPLAY,
|
PROP_DISPLAY,
|
||||||
PROP_WORKSPACE_MANAGER,
|
PROP_WORKSPACE_MANAGER,
|
||||||
PROP_SCREEN_WIDTH,
|
PROP_SCREEN_WIDTH,
|
||||||
@ -230,6 +232,9 @@ shell_global_get_property(GObject *object,
|
|||||||
case PROP_SESSION_MODE:
|
case PROP_SESSION_MODE:
|
||||||
g_value_set_string (value, shell_global_get_session_mode (global));
|
g_value_set_string (value, shell_global_get_session_mode (global));
|
||||||
break;
|
break;
|
||||||
|
case PROP_BACKEND:
|
||||||
|
g_value_set_object (value, global->backend);
|
||||||
|
break;
|
||||||
case PROP_DISPLAY:
|
case PROP_DISPLAY:
|
||||||
g_value_set_object (value, global->meta_display);
|
g_value_set_object (value, global->meta_display);
|
||||||
break;
|
break;
|
||||||
@ -472,6 +477,13 @@ shell_global_class_init (ShellGlobalClass *klass)
|
|||||||
"Screen height, in pixels",
|
"Screen height, in pixels",
|
||||||
0, G_MAXINT, 1,
|
0, G_MAXINT, 1,
|
||||||
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
|
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
|
||||||
|
g_object_class_install_property (gobject_class,
|
||||||
|
PROP_BACKEND,
|
||||||
|
g_param_spec_object ("backend",
|
||||||
|
"Backend",
|
||||||
|
"MetaBackend object",
|
||||||
|
META_TYPE_BACKEND,
|
||||||
|
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
|
||||||
g_object_class_install_property (gobject_class,
|
g_object_class_install_property (gobject_class,
|
||||||
PROP_DISPLAY,
|
PROP_DISPLAY,
|
||||||
g_param_spec_object ("display",
|
g_param_spec_object ("display",
|
||||||
@ -947,6 +959,7 @@ _shell_global_set_plugin (ShellGlobal *global,
|
|||||||
g_return_if_fail (SHELL_IS_GLOBAL (global));
|
g_return_if_fail (SHELL_IS_GLOBAL (global));
|
||||||
g_return_if_fail (global->plugin == NULL);
|
g_return_if_fail (global->plugin == NULL);
|
||||||
|
|
||||||
|
global->backend = meta_get_backend ();
|
||||||
global->plugin = plugin;
|
global->plugin = plugin;
|
||||||
global->wm = shell_wm_new (plugin);
|
global->wm = shell_wm_new (plugin);
|
||||||
|
|
||||||
@ -1599,10 +1612,8 @@ shell_global_end_work (ShellGlobal *global)
|
|||||||
* Idle means here no animations, no redrawing, and no ongoing background
|
* Idle means here no animations, no redrawing, and no ongoing background
|
||||||
* work. Since there is currently no way to hook into the Clutter master
|
* work. Since there is currently no way to hook into the Clutter master
|
||||||
* clock and know when is running, the implementation here is somewhat
|
* clock and know when is running, the implementation here is somewhat
|
||||||
* approximation. Animations done through the shell's Tweener module will
|
* approximation. Animations may be detected as terminating early if they
|
||||||
* be handled properly, but other animations may be detected as terminating
|
* can be drawn fast enough so that the event loop goes idle between frames.
|
||||||
* early if they can be drawn fast enough so that the event loop goes idle
|
|
||||||
* between frames.
|
|
||||||
*
|
*
|
||||||
* The intent of this function is for performance measurement runs
|
* The intent of this function is for performance measurement runs
|
||||||
* where a number of actions should be run serially and each action is
|
* where a number of actions should be run serially and each action is
|
||||||
|
@ -638,6 +638,20 @@ shell_util_check_cloexec_fds (void)
|
|||||||
g_info ("Open fd CLOEXEC check complete");
|
g_info ("Open fd CLOEXEC check complete");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* shell_util_get_uid:
|
||||||
|
*
|
||||||
|
* A wrapper around getuid() so that it can be used from JavaScript. This
|
||||||
|
* function will always succeed.
|
||||||
|
*
|
||||||
|
* Returns: the real user ID of the calling process
|
||||||
|
*/
|
||||||
|
gint
|
||||||
|
shell_util_get_uid (void)
|
||||||
|
{
|
||||||
|
return getuid ();
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
on_systemd_call_cb (GObject *source,
|
on_systemd_call_cb (GObject *source,
|
||||||
GAsyncResult *res,
|
GAsyncResult *res,
|
||||||
|
@ -78,6 +78,8 @@ gboolean shell_util_has_x11_display_extension (MetaDisplay *display,
|
|||||||
|
|
||||||
char *shell_util_get_translated_folder_name (const char *name);
|
char *shell_util_get_translated_folder_name (const char *name);
|
||||||
|
|
||||||
|
gint shell_util_get_uid (void);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* __SHELL_UTIL_H__ */
|
#endif /* __SHELL_UTIL_H__ */
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user