Compare commits

..

1 Commits

Author SHA1 Message Date
Evan Welsh
170fe945a9 Initial experiment unifying app menus. 2020-06-21 03:28:17 -05:00
153 changed files with 9380 additions and 10990 deletions

View File

@@ -9,6 +9,7 @@ stages:
variables: variables:
BUNDLE: "extensions-git.flatpak" BUNDLE: "extensions-git.flatpak"
JS_LOG: "js-report.txt" JS_LOG: "js-report.txt"
POT_LOG: "pot-update.txt"
.only_default: &only_default .only_default: &only_default
only: only:
@@ -66,7 +67,6 @@ no_template_check:
build: build:
image: registry.gitlab.gnome.org/gnome/mutter/master:v4 image: registry.gitlab.gnome.org/gnome/mutter/master:v4
stage: build stage: build
needs: []
before_script: before_script:
- .gitlab-ci/checkout-mutter.sh - .gitlab-ci/checkout-mutter.sh
- meson mutter mutter/build --prefix=/usr -Dtests=false - meson mutter mutter/build --prefix=/usr -Dtests=false
@@ -85,7 +85,6 @@ build:
test: test:
image: registry.gitlab.gnome.org/gnome/mutter/master:v4 image: registry.gitlab.gnome.org/gnome/mutter/master:v4
stage: test stage: test
needs: ["build"]
variables: variables:
XDG_RUNTIME_DIR: "$CI_PROJECT_DIR/runtime-dir" XDG_RUNTIME_DIR: "$CI_PROJECT_DIR/runtime-dir"
NO_AT_BRIDGE: "1" NO_AT_BRIDGE: "1"
@@ -100,9 +99,24 @@ test:
- build/meson-logs/testlog.txt - build/meson-logs/testlog.txt
when: on_failure when: on_failure
test-pot:
image: registry.gitlab.gnome.org/gnome/mutter/master:v4
stage: test
before_script:
- ninja -C mutter/build install
script:
# Check that pot files are generated correctly:
# https://savannah.gnu.org/bugs/?50920#comment5
- ninja -C build gnome-shell-pot 2>&1 | awk '
BEGIN { start=0; }
start==1 { print $0; }
/gnome-shell-pot/ { start=1; }
' | tee $POT_LOG
- (! grep -q . $POT_LOG)
<<: *only_default
flatpak: flatpak:
stage: build stage: build
needs: []
variables: variables:
SUBPROJECT: "subprojects/extensions-app" SUBPROJECT: "subprojects/extensions-app"
# Your manifest path # Your manifest path

67
NEWS
View File

@@ -1,70 +1,3 @@
3.37.90
=======
* Fix extension updates when many extensions are installed [Jeremias; !1363]
* Fix missing icons in on-screen keyboard [Emre; #2631, #3007]
* Fix delay when showing calendar events [Sebastian; #2992]
* Allow rearranging items in app picker [Georges; !1284]
* Fix top bar navigation when NumLock is active [Olivier; #550]
* Delay login animation until wallpaper has loaded [Michael; #734996]
* Reset auth prompt on login screen on VT switch before fade in [Ray; #2997]
* Move screencasting into a separate service [Jonas Å.; !1372]
* Replace loaded terms with more descriptive one [Olivier; !1393]
* Add "Boot Options" support to restart dialog [Hans; !199]
* Move "Restart" into a separate menu item/dialog [Florian; #2202]
* Default to not installing updates on low battery [Michael; #2717]
* Misc. bug fixes and cleanups [Florian, Daniel V., Georges, Jonas Å.,
Daniel G., Carlos, Benjamin, Piotr, Andre, Jonas D., Andy; !1357, !1356,
#2969, #2969, !1358, !1371, #3005, !1380, #3022, !1381, !895, !1387, !1386,
!1385, #3037, !1389, !1390, !1391, !1383, !1399, #2983, !1403]
Contributors:
Jonas Ådahl, Benjamin Berg, Michael Catanzaro, Piotr Drąg, Jonas Dreßler,
Olivier Fourdan, Carlos Garnacho, Hans de Goede, Andy Holmes,
Sebastian Keller, Andre Moreira Magalhaes, Daniel García Moreno,
Florian Müllner, Georges Basile Stavracas Neto, Jeremias Ortega, Ray Strode,
Emre Uyguroglu, Daniel van Vugt
Translators:
Tim Sabsch [de], Boyuan Yang [zh_CN], Fabio Tomat [fur],
Efstathios Iosifidis [el], Rafael Fontenelle [pt_BR], Yuri Chornoivan [uk],
Daniel Șerbănescu [ro], Jordi Mas [ca], Daniel Mustieles [es],
Emin Tufan Çetin [tr], Asier Sarasua Garmendia [eu]
3.37.3
======
* Refactor and clean up window picker
[Jonas D., Florian; !1297, !1298, !1305, !1345, !1353]
* Move calendar events out of notifications list [Florian; !1282]
* Refine app folder dialogs [Georges; !1301]
* Hide switch-user button on lock screen if unsupported [Chingkai; #2687]
* Refactor and clean up app picker pagination [Georges; !1271]
* Add API to retrieve specified mimetypes from clipboards [Carlos; !1321]
* Support prepending workspace with horizontal layouts [Florian; #2916]
* Update microphone icon on input volume changes [fludixx; #2902]
* Cache labels on GPU [Daniel; !1329]
* Fix regressions in redesigned modal dialogs [Florian, Jonas D.; #2491, !1336]
* Use GIcon for all application icons [Florian; !1342]
* Support pre-authenticated logins in vmware environments [yun341; #1983]
* Better support sandboxed apps with multiple .desktop files [Florian; #219]
* Fix on-screen keyboard size in portrait orientation [Florian; #2349]
* Plugged leaks [Sebastian, Daniel, Florian; !1306, !1319, !1341]
* Misc. bug fixes and cleanups [Jonas D., Georges, Marco, Florian, Sebastian,
MOZGIII, Daniel, Mariana, Jonas Å.; !1296, !1295, #2643, !1300, !1309,
!1119, #2901, !1313, !1251, !1285, !1307, !1318, !1310, !1320, !1327, !1315,
!1289, !1331, !1332, !1333, !1334, !1340, !1287, !1308, !1346, !1299, !1343,
!1351, !1352, !1322]
Contributors:
Marco Trevisan (Treviño), Chingkai, Jonas Dreßler, Carlos Garnacho,
Sebastian Keller, MOZGIII, Florian Müllner, Georges Basile Stavracas Neto,
Mariana Picolo, Daniel van Vugt, fludixx, yun341, Jonas Ådahl
Translators:
Daniel Mustieles [es], Boyuan Yang [zh_CN], Yuri Chornoivan [uk],
Jordi Mas [ca], sicklylife [ja], Emin Tufan Çetin [tr],
Baurzhan Muftakhidinov [kk], Florentina Mușat [ro], Aurimas Černius [lt],
Rūdolfs Mazurs [lv]
3.37.2 3.37.2
====== ======
* Add support for "PrefersNonDefaultGPU" desktop key [Bastien; !1226] * Add support for "PrefersNonDefaultGPU" desktop key [Bastien; !1226]

View File

@@ -20,12 +20,6 @@
<method name="ListSessions"> <method name="ListSessions">
<arg name="sessions" type="a(susso)" direction="out"/> <arg name="sessions" type="a(susso)" direction="out"/>
</method> </method>
<method name="CanRebootToBootLoaderMenu">
<arg type="s" direction="out"/>
</method>
<method name="SetRebootToBootLoaderMenu">
<arg type="t" direction="in"/>
</method>
<signal name="PrepareForSleep"> <signal name="PrepareForSleep">
<arg type="b" direction="out"/> <arg type="b" direction="out"/>
</signal> </signal>

View File

@@ -1,191 +0,0 @@
<!DOCTYPE node PUBLIC
'-//freedesktop//DTD D-BUS Object Introspection 1.0//EN'
'http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd'>
<node>
<!--
org.gnome.Mutter.ScreenCast:
@short_description: Screen cast interface
This API is private and not intended to be used outside of the integrated
system that uses libmutter. No compatibility between versions are
promised.
-->
<interface name="org.gnome.Mutter.ScreenCast">
<!--
CreateSession:
@properties: Properties
@session_path: Path to the new session object
* "remote-desktop-session-id" (s): The ID of a remote desktop session.
Remote desktop driven screen casts
are started and stopped by the remote
desktop session.
* "disable-animations" (b): Set to "true" if the screen cast application
would prefer animations to be globally
disabled, while the session is running. Default
is "false". Available since version 3.
-->
<method name="CreateSession">
<arg name="properties" type="a{sv}" direction="in" />
<arg name="session_path" type="o" direction="out" />
</method>
<!--
Version:
@short_description: API version
-->
<property name="Version" type="i" access="read" />
</interface>
<!--
org.gnome.Mutter.ScreenCast.Session:
@short_description: Screen cast session
-->
<interface name="org.gnome.Mutter.ScreenCast.Session">
<!--
Start:
Start the screen cast session
-->
<method name="Start" />
<!--
Stop:
Stop the screen cast session
-->
<method name="Stop" />
<!--
Closed:
The session has closed.
-->
<signal name="Closed" />
<!--
RecordMonitor:
@connector: Connector of the monitor to record
@properties: Properties
@stream_path: Path to the new stream object
Record a single monitor.
Available @properties include:
* "cursor-mode" (u): Cursor mode. Default: 'hidden' (see below)
Available since API version 2.
* "is-recording" (b): Whether this is a screen recording. May be
be used for choosing panel icon.
Default: false. Available since API version 4.
Available cursor mode values:
0: hidden - cursor is not included in the stream
1: embedded - cursor is included in the framebuffer
2: metadata - cursor is included as metadata in the PipeWire stream
-->
<method name="RecordMonitor">
<arg name="connector" type="s" direction="in" />
<arg name="properties" type="a{sv}" direction="in" />
<arg name="stream_path" type="o" direction="out" />
</method>
<!--
RecordWindow:
@properties: Properties used determining what window to select
@stream_path: Path to the new stream object
Supported since API version 2.
Record a single window. The cursor will not be included.
Available @properties include:
* "window-id" (t): Id of the window to record.
* "cursor-mode" (u): Cursor mode. Default: 'hidden' (see RecordMonitor).
* "is-recording" (b): Whether this is a screen recording. May be
be used for choosing panel icon.
Default: false. Available since API version 4.
-->
<method name="RecordWindow">
<arg name="properties" type="a{sv}" direction="in" />
<arg name="stream_path" type="o" direction="out" />
</method>
<!--
RecordArea:
@x: X position of the recorded area
@y: Y position of the recorded area
@width: width of the recorded area
@height: height of the recorded area
@properties: Properties
@stream_path: Path to the new stream object
Record an area of the stage. The coordinates are in stage coordinates.
The size of the stream does not necessarily match the size of the
recorded area, and will depend on DPI scale of the affected monitors.
Available @properties include:
* "cursor-mode" (u): Cursor mode. Default: 'hidden' (see below)
Available since API version 2.
* "is-recording" (b): Whether this is a screen recording. May be
be used for choosing panel icon.
Default: false. Available since API version 4.
Available cursor mode values:
0: hidden - cursor is not included in the stream
1: embedded - cursor is included in the framebuffer
2: metadata - cursor is included as metadata in the PipeWire stream
-->
<method name="RecordArea">
<arg name="x" type="i" direction="in" />
<arg name="y" type="i" direction="in" />
<arg name="width" type="i" direction="in" />
<arg name="height" type="i" direction="in" />
<arg name="properties" type="a{sv}" direction="in" />
<arg name="stream_path" type="o" direction="out" />
</method>
</interface>
<!--
org.gnome.Mutter.ScreenCast.Stream:
@short_description: Screen cast stream
-->
<interface name="org.gnome.Mutter.ScreenCast.Stream">
<!--
PipeWireStreamAdded:
@short_description: Pipewire stream added
A signal emitted when PipeWire stream for the screen cast stream has
been created. The @node_id corresponds to the PipeWire stream node.
-->
<signal name="PipeWireStreamAdded">
<annotation name="org.gtk.GDBus.C.Name" value="pipewire-stream-added"/>
<arg name="node_id" type="u" direction="out" />
</signal>
<!--
Parameters:
@short_description: Optional stream parameters
Available parameters include:
* "position" (ii): Position of the source of the stream in the
compositor coordinate space.
* "size" (ii): Size of the source of the stream in the compositor
coordinate space.
-->
<property name="Parameters" type="a{sv}" access="read" />
</interface>
</node>

View File

@@ -70,14 +70,6 @@
--> -->
<property name="AnimationsEnabled" type="b" access="read"/> <property name="AnimationsEnabled" type="b" access="read"/>
<!--
ScreenSize:
@short_description: The size of the screen
Since: 3
-->
<property name="ScreenSize" type="(ii)" access="read"/>
<property name="version" type="u" access="read"/> <property name="version" type="u" access="read"/>
</interface> </interface>
</node> </node>

View File

@@ -28,7 +28,6 @@
<file preprocess="xml-stripblanks">org.freedesktop.UPower.xml</file> <file preprocess="xml-stripblanks">org.freedesktop.UPower.xml</file>
<file preprocess="xml-stripblanks">org.gnome.Magnifier.xml</file> <file preprocess="xml-stripblanks">org.gnome.Magnifier.xml</file>
<file preprocess="xml-stripblanks">org.gnome.Magnifier.ZoomRegion.xml</file> <file preprocess="xml-stripblanks">org.gnome.Magnifier.ZoomRegion.xml</file>
<file preprocess="xml-stripblanks">org.gnome.Mutter.ScreenCast.xml</file>
<file preprocess="xml-stripblanks">org.gnome.ScreenSaver.xml</file> <file preprocess="xml-stripblanks">org.gnome.ScreenSaver.xml</file>
<file preprocess="xml-stripblanks">org.gnome.SessionManager.EndSessionDialog.xml</file> <file preprocess="xml-stripblanks">org.gnome.SessionManager.EndSessionDialog.xml</file>
<file preprocess="xml-stripblanks">org.gnome.SessionManager.Inhibitor.xml</file> <file preprocess="xml-stripblanks">org.gnome.SessionManager.Inhibitor.xml</file>

View File

@@ -6,25 +6,25 @@
<file>checkbox-off-focused.svg</file> <file>checkbox-off-focused.svg</file>
<file>checkbox-off.svg</file> <file>checkbox-off.svg</file>
<file>checkbox.svg</file> <file>checkbox.svg</file>
<file alias="icons/scalable/actions/color-pick.svg">color-pick.svg</file> <file alias="icons/color-pick.svg">color-pick.svg</file>
<file>dash-placeholder.svg</file> <file>dash-placeholder.svg</file>
<file>gnome-shell.css</file> <file>gnome-shell.css</file>
<file>gnome-shell-high-contrast.css</file> <file>gnome-shell-high-contrast.css</file>
<file alias="icons/scalable/status/message-indicator-symbolic.svg">message-indicator-symbolic.svg</file> <file alias="icons/message-indicator-symbolic.svg">message-indicator-symbolic.svg</file>
<file>no-events.svg</file> <file>no-events.svg</file>
<file>no-notifications.svg</file> <file>no-notifications.svg</file>
<file>pad-osd.css</file> <file>pad-osd.css</file>
<file alias="icons/scalable/status/eye-open-negative-filled-symbolic.svg">eye-open-negative-filled-symbolic.svg</file> <file alias="icons/eye-open-negative-filled-symbolic.svg">eye-open-negative-filled-symbolic.svg</file>
<file alias="icons/scalable/status/eye-not-looking-symbolic.svg">eye-not-looking-symbolic.svg</file> <file alias="icons/eye-not-looking-symbolic.svg">eye-not-looking-symbolic.svg</file>
<file alias="icons/scalable/actions/pointer-double-click-symbolic.svg">pointer-double-click-symbolic.svg</file> <file alias="icons/pointer-double-click-symbolic.svg">pointer-double-click-symbolic.svg</file>
<file alias="icons/scalable/actions/pointer-drag-symbolic.svg">pointer-drag-symbolic.svg</file> <file alias="icons/pointer-drag-symbolic.svg">pointer-drag-symbolic.svg</file>
<file alias="icons/scalable/actions/pointer-primary-click-symbolic.svg">pointer-primary-click-symbolic.svg</file> <file alias="icons/pointer-primary-click-symbolic.svg">pointer-primary-click-symbolic.svg</file>
<file alias="icons/scalable/actions/pointer-secondary-click-symbolic.svg">pointer-secondary-click-symbolic.svg</file> <file alias="icons/pointer-secondary-click-symbolic.svg">pointer-secondary-click-symbolic.svg</file>
<file alias="icons/scalable/status/keyboard-caps-lock-filled-symbolic.svg">keyboard-caps-lock-filled-symbolic.svg</file> <file alias="icons/keyboard-caps-lock-filled-symbolic.svg">keyboard-caps-lock-filled-symbolic.svg</file>
<file alias="icons/scalable/status/keyboard-enter-symbolic.svg">keyboard-enter-symbolic.svg</file> <file alias="icons/keyboard-enter-symbolic.svg">keyboard-enter-symbolic.svg</file>
<file alias="icons/scalable/status/keyboard-hide-symbolic.svg">keyboard-hide-symbolic.svg</file> <file alias="icons/keyboard-hide-symbolic.svg">keyboard-hide-symbolic.svg</file>
<file alias="icons/scalable/status/keyboard-layout-filled-symbolic.svg">keyboard-layout-filled-symbolic.svg</file> <file alias="icons/keyboard-layout-filled-symbolic.svg">keyboard-layout-filled-symbolic.svg</file>
<file alias="icons/scalable/status/keyboard-shift-filled-symbolic.svg">keyboard-shift-filled-symbolic.svg</file> <file alias="icons/keyboard-shift-filled-symbolic.svg">keyboard-shift-filled-symbolic.svg</file>
<file>process-working.svg</file> <file>process-working.svg</file>
<file>toggle-off.svg</file> <file>toggle-off.svg</file>
<file>toggle-off-dark.svg</file> <file>toggle-off-dark.svg</file>

View File

@@ -1,7 +1,7 @@
[Unit] [Unit]
Description=GNOME Shell on Wayland Description=GNOME Shell on Wayland
# On wayland, force a session shutdown # On wayland, force a session shutdown
OnFailure=org.gnome.Shell-disable-extensions.service gnome-session-shutdown.target OnFailure=gnome-shell-disable-extensions.service gnome-session-shutdown.target
OnFailureJobMode=replace-irreversibly OnFailureJobMode=replace-irreversibly
CollectMode=inactive-or-failed CollectMode=inactive-or-failed
RefuseManualStart=on RefuseManualStart=on
@@ -13,21 +13,18 @@ Requisite=gnome-session-initialized.target
PartOf=gnome-session-initialized.target PartOf=gnome-session-initialized.target
Before=gnome-session-initialized.target Before=gnome-session-initialized.target
# The units already conflict because they use the same BusName
#Conflicts=gnome-shell-x11.service
[Service] [Service]
Slice=session.slice
Type=notify Type=notify
# NOTE: This can be replaced with ConditionEnvironment=XDG_SESSION_TYPE=%I
# with systemd >= 245. Also, the current solution is kind of painful
# as systemd had a bug where it retries the condition.
# Only start if the template instance matches the session type.
ExecCondition=/bin/sh -c 'test "$XDG_SESSION_TYPE" = "%I" || exit 2'
ExecStart=@bindir@/gnome-shell ExecStart=@bindir@/gnome-shell
# Exit code 1 means we are probably *not* dealing with an extension failure
SuccessExitStatus=1
# unset some environment variables that were set by the shell and won't work now that the shell is gone # unset some environment variables that were set by the shell and won't work now that the shell is gone
ExecStopPost=-systemctl --user unset-environment GNOME_SETUP_DISPLAY WAYLAND_DISPLAY DISPLAY XAUTHORITY ExecStopPost=-systemctl --user unset-environment GNOME_SETUP_DISPLAY WAYLAND_DISPLAY DISPLAY XAUTHORITY
# Exit code 1 means we are probably *not* dealing with an extension failure
SuccessExitStatus=1
# On wayland we cannot restart # On wayland we cannot restart
Restart=no Restart=no
# Kill any stubborn child processes after this long # Kill any stubborn child processes after this long

View File

@@ -6,5 +6,5 @@ Requisite=gnome-session-initialized.target
PartOf=gnome-session-initialized.target PartOf=gnome-session-initialized.target
Before=gnome-session-initialized.target Before=gnome-session-initialized.target
Wants=org.gnome.Shell@wayland.service Requires=gnome-shell-wayland.service
Wants=org.gnome.Shell@x11.service After=gnome-shell-wayland.service

View File

@@ -1,7 +1,7 @@
[Unit] [Unit]
Description=GNOME Shell on X11 Description=GNOME Shell on X11
# On X11, try to show the GNOME Session Failed screen # On X11, try to show the GNOME Session Failed screen
OnFailure=org.gnome.Shell-disable-extensions.service gnome-session-failed.target OnFailure=gnome-shell-disable-extensions.service gnome-session-failed.target
OnFailureJobMode=replace OnFailureJobMode=replace
CollectMode=inactive-or-failed CollectMode=inactive-or-failed
RefuseManualStart=on RefuseManualStart=on
@@ -13,24 +13,18 @@ Requisite=gnome-session-initialized.target
PartOf=gnome-session-initialized.target PartOf=gnome-session-initialized.target
Before=gnome-session-initialized.target Before=gnome-session-initialized.target
# The units already conflict because they use the same BusName
#Conflicts=gnome-shell-wayland.service
# Limit startup frequency more than the default # Limit startup frequency more than the default
StartLimitIntervalSec=15s StartLimitIntervalSec=15s
StartLimitBurst=3 StartLimitBurst=3
[Service] [Service]
Slice=session.slice
Type=notify Type=notify
# NOTE: This can be replaced with ConditionEnvironment=XDG_SESSION_TYPE=%I
# with systemd >= 245. Also, the current solution is kind of painful
# as systemd had a bug where it retries the condition.
# Only start if the template instance matches the session type.
ExecCondition=/bin/sh -c 'test "$XDG_SESSION_TYPE" = "%I" || exit 2'
ExecStart=@bindir@/gnome-shell ExecStart=@bindir@/gnome-shell
# Exit code 1 means we are probably *not* dealing with an extension failure # Exit code 1 means we are probably *not* dealing with an extension failure
SuccessExitStatus=1 SuccessExitStatus=1
# On X11 we do not need to unset any variables
# On X11 we want to restart on-success (Alt+F2 + r) and on-failure. # On X11 we want to restart on-success (Alt+F2 + r) and on-failure.
Restart=always Restart=always
# Do not wait before restarting the shell # Do not wait before restarting the shell

View File

@@ -0,0 +1,10 @@
[Unit]
Description=GNOME Shell on X11
DefaultDependencies=no
Requisite=gnome-session-initialized.target
PartOf=gnome-session-initialized.target
Before=gnome-session-initialized.target
Requires=gnome-shell-x11.service
After=gnome-shell-x11.service

View File

@@ -101,21 +101,22 @@ if have_systemd
unitconf.set('bindir', bindir) unitconf.set('bindir', bindir)
configure_file( configure_file(
input: 'org.gnome.Shell@x11.service.in', input: 'gnome-shell-x11.service.in',
output: 'org.gnome.Shell@x11.service', output: 'gnome-shell-x11.service',
configuration: unitconf, configuration: unitconf,
install_dir: systemduserunitdir install_dir: systemduserunitdir
) )
configure_file( configure_file(
input: 'org.gnome.Shell@wayland.service.in', input: 'gnome-shell-wayland.service.in',
output: 'org.gnome.Shell@wayland.service', output: 'gnome-shell-wayland.service',
configuration: unitconf, configuration: unitconf,
install_dir: systemduserunitdir install_dir: systemduserunitdir
) )
units = files('org.gnome.Shell.target', units = files('gnome-shell-x11.target',
'org.gnome.Shell-disable-extensions.service') 'gnome-shell-wayland.target',
'gnome-shell-disable-extensions.service')
install_data(units, install_dir: systemduserunitdir) install_data(units, install_dir: systemduserunitdir)
endif endif

View File

@@ -109,17 +109,6 @@
the shell. the shell.
</description> </description>
</key> </key>
<key name="app-picker-layout" type="aa{sv}">
<default>[]</default>
<summary>Layout of the app picker</summary>
<description>
Layout of the app picker. Each entry in the array is a page. Pages are
stored in the order they appear in GNOME Shell. Each page contains an
“application id” → 'data' pair. Currently, the following values are
stored as 'data':
• “position”: the position of the application icon in the page
</description>
</key>
<child name="keybindings" schema="org.gnome.shell.keybindings"/> <child name="keybindings" schema="org.gnome.shell.keybindings"/>
</schema> </schema>

View File

@@ -232,9 +232,7 @@
color: $fg_color; color: $fg_color;
font-feature-settings: "tnum"; font-feature-settings: "tnum";
@include fontsize($base_font_size); @include fontsize($base_font_size);
text-align: right;
&:ltr { text-align: right; }
&:rtl { text-align: left; }
} }
// timezone offset label // timezone offset label

View File

@@ -138,10 +138,11 @@
.user-widget.horizontal .user-widget-label { .user-widget.horizontal .user-widget-label {
@include fontsize($base_font_size + 2); @include fontsize($base_font_size + 2);
font-weight: bold; font-weight: bold;
text-align: left;
padding-left: 15px; padding-left: 15px;
&:ltr { padding-left: 14px; text-align: left; } &:ltr { padding-left: 14px; }
&:rtl { padding-right: 14px; text-align: right; } &:rtl { padding-right: 14px; }
} }
.user-widget.vertical .user-widget-label { .user-widget.vertical .user-widget-label {

View File

@@ -71,11 +71,9 @@
> .event-time { > .event-time {
color: transparentize($fg_color, 0.5); color: transparentize($fg_color, 0.5);
@include fontsize($base_font_size - 2); @include fontsize($base_font_size - 2);
text-align: right;
/* HACK: the label should be baseline-aligned with a 1em label, fake this with some bottom padding */ /* HACK: the label should be baseline-aligned with a 1em label, fake this with some bottom padding */
padding-bottom: 0.13em; padding-bottom: 0.13em;
&:ltr { text-align: right };
&:rtl { text-align: left };
} }
} }

View File

@@ -76,10 +76,8 @@ $popover_arrow_height: 12px;
// container for radio and check boxes // container for radio and check boxes
.popup-menu-ornament { .popup-menu-ornament {
text-align: right;
width: 1.2em; width: 1.2em;
&:ltr { text-align: right };
&:rtl { text-align: left };
} }
// separator // separator

View File

@@ -1,7 +1,7 @@
/* Window Picker */ /* Window Picker */
$window_picker_spacing: $base_spacing; // 6px $window_picker_spacing: $base_spacing * 2; // 16px
$window_picker_padding: $base_padding * 2; // 12px $window_picker_padding: $base_padding * 2; // 16px
$window_thumbnail_border_color:transparentize($selected_fg_color, 0.65); $window_thumbnail_border_color:transparentize($selected_fg_color, 0.65);
@@ -13,8 +13,8 @@ $window_clone_border_size: 6px;
// Window picker // Window picker
.window-picker { .window-picker {
// Space between window thumbnails // Space between window thumbnails
spacing: $window_picker_spacing; -horizontal-spacing: $window_picker_spacing;
-vertical-spacing: $window_picker_spacing;
// Padding for container around window thumbnails // Padding for container around window thumbnails
padding: $window_picker_padding; padding: $window_picker_padding;

View File

@@ -3,8 +3,13 @@ private_headers = [
'gactionobservable.h', 'gactionobservable.h',
'gactionobserver.h', 'gactionobserver.h',
'shell-network-agent.h', 'shell-network-agent.h',
'shell-recorder-src.h'
] ]
if not enable_recorder
private_headers += 'shell-recorder.h'
endif
exclude_directories = [ exclude_directories = [
'calendar-server', 'calendar-server',
'hotplug-sniffer', 'hotplug-sniffer',

View File

@@ -25,8 +25,6 @@ var ServiceImplementation = class {
// subclasses may override this to disable automatic shutdown // subclasses may override this to disable automatic shutdown
this._autoShutdown = true; this._autoShutdown = true;
this._queueShutdownCheck();
} }
// subclasses may override this to own additional names // subclasses may override this to own additional names

View File

@@ -8,12 +8,6 @@ dbus_services = {
'org.gnome.Shell.Notifications': 'notifications', 'org.gnome.Shell.Notifications': 'notifications',
} }
if enable_recorder
dbus_services += {
'org.gnome.Shell.Screencast': 'screencast',
}
endif
config_dir = '@0@/..'.format(meson.current_build_dir()) config_dir = '@0@/..'.format(meson.current_build_dir())
foreach service, dir : dbus_services foreach service, dir : dbus_services

View File

@@ -1,11 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<gresources>
<gresource prefix="/org/gnome/Shell/Screencast/js">
<file>main.js</file>
<file>screencastService.js</file>
<file>dbusService.js</file>
<file>misc/config.js</file>
<file>misc/fileUtils.js</file>
</gresource>
</gresources>

View File

@@ -1,11 +0,0 @@
/* exported main */
const { DBusService } = imports.dbusService;
const { ScreencastService } = imports.screencastService;
function main() {
const service = new DBusService(
'org.gnome.Shell.Screencast',
new ScreencastService());
service.run();
}

View File

@@ -1,458 +0,0 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
/* exported ScreencastService */
const { Gio, GLib, Gst } = imports.gi;
const { loadInterfaceXML, loadSubInterfaceXML } = imports.misc.fileUtils;
const { ServiceImplementation } = imports.dbusService;
const ScreencastIface = loadInterfaceXML('org.gnome.Shell.Screencast');
const IntrospectIface = loadInterfaceXML('org.gnome.Shell.Introspect');
const IntrospectProxy = Gio.DBusProxy.makeProxyWrapper(IntrospectIface);
const ScreenCastIface = loadSubInterfaceXML(
'org.gnome.Mutter.ScreenCast', 'org.gnome.Mutter.ScreenCast');
const ScreenCastSessionIface = loadSubInterfaceXML(
'org.gnome.Mutter.ScreenCast.Session', 'org.gnome.Mutter.ScreenCast');
const ScreenCastStreamIface = loadSubInterfaceXML(
'org.gnome.Mutter.ScreenCast.Stream', 'org.gnome.Mutter.ScreenCast');
const ScreenCastProxy = Gio.DBusProxy.makeProxyWrapper(ScreenCastIface);
const ScreenCastSessionProxy = Gio.DBusProxy.makeProxyWrapper(ScreenCastSessionIface);
const ScreenCastStreamProxy = Gio.DBusProxy.makeProxyWrapper(ScreenCastStreamIface);
const DEFAULT_PIPELINE = 'vp8enc min_quantizer=13 max_quantizer=13 cpu-used=5 deadline=1000000 threads=%T ! queue ! webmmux';
const DEFAULT_FRAMERATE = 30;
const DEFAULT_DRAW_CURSOR = true;
const PipelineState = {
INIT: 0,
PLAYING: 1,
FLUSHING: 2,
STOPPED: 3,
};
const SessionState = {
INIT: 0,
ACTIVE: 1,
STOPPED: 2,
};
var Recorder = class {
constructor(sessionPath, x, y, width, height, filePath, options,
invocation,
onErrorCallback) {
this._startInvocation = invocation;
this._dbusConnection = invocation.get_connection();
this._onErrorCallback = onErrorCallback;
this._stopInvocation = null;
this._pipelineIsPlaying = false;
this._sessionIsActive = false;
this._x = x;
this._y = y;
this._width = width;
this._height = height;
this._filePath = filePath;
this._pipelineString = DEFAULT_PIPELINE;
this._framerate = DEFAULT_FRAMERATE;
this._drawCursor = DEFAULT_DRAW_CURSOR;
this._applyOptions(options);
this._watchSender(invocation.get_sender());
this._initSession(sessionPath);
}
_applyOptions(options) {
for (const option in options)
options[option] = options[option].deep_unpack();
if (options['pipeline'] !== undefined)
this._pipelineString = options['pipeline'];
if (options['framerate'] !== undefined)
this._framerate = options['framerate'];
if ('draw-cursor' in options)
this._drawCursor = options['draw-cursor'];
}
_watchSender(sender) {
this._nameWatchId = this._dbusConnection.watch_name(
sender,
Gio.BusNameWatcherFlags.NONE,
null,
this._senderVanished.bind(this));
}
_unwatchSender() {
if (this._nameWatchId !== 0) {
this._dbusConnection.unwatch_name(this._nameWatchId);
this._nameWatchId = 0;
}
}
_senderVanished() {
this._unwatchSender();
this.stopRecording(null);
}
_notifyStopped() {
this._unwatchSender();
if (this._onStartedCallback)
this._onStartedCallback(this, false);
else if (this._onStoppedCallback)
this._onStoppedCallback(this);
else
this._onErrorCallback(this);
}
_onSessionClosed() {
switch (this._pipelineState) {
case PipelineState.STOPPED:
break;
default:
this._pipeline.set_state(Gst.State.NULL);
log(`Unexpected pipeline state: ${this._pipelineState}`);
break;
}
this._notifyStopped();
}
_initSession(sessionPath) {
this._sessionProxy = new ScreenCastSessionProxy(Gio.DBus.session,
'org.gnome.Mutter.ScreenCast',
sessionPath);
this._sessionProxy.connectSignal('Closed', this._onSessionClosed.bind(this));
}
_startPipeline(nodeId) {
this._ensurePipeline(nodeId);
const bus = this._pipeline.get_bus();
bus.add_watch(bus, this._onBusMessage.bind(this));
this._pipeline.set_state(Gst.State.PLAYING);
this._pipelineState = PipelineState.PLAYING;
this._onStartedCallback(this, true);
this._onStartedCallback = null;
}
startRecording(onStartedCallback) {
this._onStartedCallback = onStartedCallback;
const [streamPath] = this._sessionProxy.RecordAreaSync(
this._x, this._y,
this._width, this._height,
{
'is-recording': GLib.Variant.new('b', true),
'cursor-mode': GLib.Variant.new('u', this._drawCursor ? 1 : 0),
});
this._streamProxy = new ScreenCastStreamProxy(Gio.DBus.session,
'org.gnome.ScreenCast.Stream',
streamPath);
this._streamProxy.connectSignal('PipeWireStreamAdded',
(proxy, sender, params) => {
const [nodeId] = params;
this._startPipeline(nodeId);
});
this._sessionProxy.StartSync();
this._sessionState = SessionState.ACTIVE;
}
stopRecording(onStoppedCallback) {
this._pipelineState = PipelineState.FLUSHING;
this._onStoppedCallback = onStoppedCallback;
this._pipeline.send_event(Gst.Event.new_eos());
}
_stopSession() {
this._sessionProxy.StopSync();
this._sessionState = SessionState.STOPPED;
}
_onBusMessage(bus, message, _) {
switch (message.type) {
case Gst.MessageType.EOS:
this._pipeline.set_state(Gst.State.NULL);
switch (this._pipelineState) {
case PipelineState.FLUSHING:
this._pipelineState = PipelineState.STOPPED;
break;
default:
break;
}
switch (this._sessionState) {
case SessionState.ACTIVE:
this._stopSession();
break;
case SessionState.STOPPED:
this._notifyStopped();
break;
default:
break;
}
break;
default:
break;
}
return true;
}
_substituteThreadCount(pipelineDescr) {
const numProcessors = GLib.get_num_processors();
const numThreads = Math.min(Math.max(1, numProcessors), 64);
return pipelineDescr.replace(/%T/, numThreads);
}
_ensurePipeline(nodeId) {
const framerate = this._framerate;
let fullPipeline = `
pipewiresrc path=${nodeId}
do-timestamp=true
keepalive-time=1000
resend-last=true !
video/x-raw,max-framerate=${framerate}/1 !
videoconvert !
${this._pipelineString} !
filesink location="${this._filePath}"`;
fullPipeline = this._substituteThreadCount(fullPipeline);
this._pipeline = Gst.parse_launch_full(fullPipeline,
null,
Gst.ParseFlags.FATAL_ERRORS);
}
};
var ScreencastService = class extends ServiceImplementation {
constructor() {
super(ScreencastIface, '/org/gnome/Shell/Screencast');
Gst.init(null);
this._recorders = new Map();
this._senders = new Map();
this._lockdownSettings = new Gio.Settings({
schema_id: 'org.gnome.desktop.lockdown',
});
this._proxy = new ScreenCastProxy(Gio.DBus.session,
'org.gnome.Mutter.ScreenCast',
'/org/gnome/Mutter/ScreenCast');
this._introspectProxy = new IntrospectProxy(Gio.DBus.session,
'org.gnome.Shell.Introspect',
'/org/gnome/Shell/Introspect');
}
_removeRecorder(sender) {
this._recorders.delete(sender);
if (this._recorders.size === 0)
this.release();
}
_addRecorder(sender, recorder) {
this._recorders.set(sender, recorder);
if (this._recorders.size === 1)
this.hold();
}
_getAbsolutePath(filename) {
if (GLib.path_is_absolute(filename))
return filename;
let videoDir = GLib.get_user_special_dir(GLib.UserDirectory.DIRECTORY_VIDEOS);
if (!GLib.file_test(videoDir, GLib.FileTest.EXISTS))
videoDir = GLib.get_home_dir();
return GLib.build_filenamev([videoDir, filename]);
}
_generateFilePath(template) {
let filename = '';
let escape = false;
[...template].forEach(c => {
if (escape) {
switch (c) {
case '%':
filename += '%';
break;
case 'd': {
const datetime = GLib.DateTime.new_now_local();
const datestr = datetime.format('%0x');
const datestrEscaped = datestr.replace(/\//g, '-');
filename += datestrEscaped;
break;
}
case 't': {
const datetime = GLib.DateTime.new_now_local();
const datestr = datetime.format('%0X');
const datestrEscaped = datestr.replace(/\//g, ':');
filename += datestrEscaped;
break;
}
default:
log(`Warning: Unknown escape ${c}`);
}
escape = false;
} else if (c === '%') {
escape = true;
} else {
filename += c;
}
});
if (escape)
filename += '%';
return this._getAbsolutePath(filename);
}
ScreencastAsync(params, invocation) {
let returnValue = [false, ''];
if (this._lockdownSettings.get_boolean('disable-save-to-disk')) {
invocation.return_value(GLib.Variant.new('(bs)', returnValue));
return;
}
const sender = invocation.get_sender();
if (this._recorders.get(sender)) {
invocation.return_value(GLib.Variant.new('(bs)', returnValue));
return;
}
const [sessionPath] = this._proxy.CreateSessionSync({});
const [fileTemplate, options] = params;
const [screenWidth, screenHeight] = this._introspectProxy.ScreenSize;
const filePath = this._generateFilePath(fileTemplate);
let recorder;
try {
recorder = new Recorder(
sessionPath,
0, 0,
screenWidth, screenHeight,
fileTemplate,
options,
invocation,
_recorder => this._removeRecorder(sender));
} catch (error) {
log(`Failed to create recorder: ${error.message}`);
invocation.return_value(GLib.Variant.new('(bs)', returnValue));
return;
}
this._addRecorder(sender, recorder);
try {
recorder.startRecording(
(_, result) => {
if (result) {
returnValue = [true, filePath];
invocation.return_value(GLib.Variant.new('(bs)', returnValue));
} else {
this._removeRecorder(sender);
invocation.return_value(GLib.Variant.new('(bs)', returnValue));
}
});
} catch (error) {
log(`Failed to start recorder: ${error.message}`);
this._removeRecorder(sender);
invocation.return_value(GLib.Variant.new('(bs)', returnValue));
}
}
ScreencastAreaAsync(params, invocation) {
let returnValue = [false, ''];
if (this._lockdownSettings.get_boolean('disable-save-to-disk')) {
invocation.return_value(GLib.Variant.new('(bs)', returnValue));
return;
}
const sender = invocation.get_sender();
if (this._recorders.get(sender)) {
invocation.return_value(GLib.Variant.new('(bs)', returnValue));
return;
}
const [sessionPath] = this._proxy.CreateSessionSync({});
const [x, y, width, height, fileTemplate, options] = params;
const filePath = this._generateFilePath(fileTemplate);
let recorder;
try {
recorder = new Recorder(
sessionPath,
x, y,
width, height,
filePath,
options,
invocation,
_recorder => this._removeRecorder(sender));
} catch (error) {
log(`Failed to create recorder: ${error.message}`);
invocation.return_value(GLib.Variant.new('(bs)', returnValue));
return;
}
this._addRecorder(sender, recorder);
try {
recorder.startRecording(
(_, result) => {
if (result) {
returnValue = [true, filePath];
invocation.return_value(GLib.Variant.new('(bs)', returnValue));
} else {
this._removeRecorder(sender);
invocation.return_value(GLib.Variant.new('(bs)', returnValue));
}
});
} catch (error) {
log(`Failed to start recorder: ${error.message}`);
this._removeRecorder(sender);
invocation.return_value(GLib.Variant.new('(bs)', returnValue));
}
}
StopScreencastAsync(params, invocation) {
const sender = invocation.get_sender();
const recorder = this._recorders.get(sender);
if (!recorder) {
invocation.return_value(GLib.Variant.new('(b)', [false]));
return;
}
recorder.stopRecording(() => {
this._removeRecorder(sender);
invocation.return_value(GLib.Variant.new('(b)', [true]));
});
}
};

View File

@@ -71,7 +71,7 @@ var AuthPrompt = GObject.registerClass({
this._userVerifier.connect('verification-complete', this._onVerificationComplete.bind(this)); this._userVerifier.connect('verification-complete', this._onVerificationComplete.bind(this));
this._userVerifier.connect('reset', this._onReset.bind(this)); this._userVerifier.connect('reset', this._onReset.bind(this));
this._userVerifier.connect('smartcard-status-changed', this._onSmartcardStatusChanged.bind(this)); this._userVerifier.connect('smartcard-status-changed', this._onSmartcardStatusChanged.bind(this));
this._userVerifier.connect('credential-manager-authenticated', this._onCredentialManagerAuthenticated.bind(this)); this._userVerifier.connect('ovirt-user-authenticated', this._onOVirtUserAuthenticated.bind(this));
this.smartcardDetected = this._userVerifier.smartcardDetected; this.smartcardDetected = this._userVerifier.smartcardDetected;
this.connect('destroy', this._onDestroy.bind(this)); this.connect('destroy', this._onDestroy.bind(this));
@@ -242,7 +242,7 @@ var AuthPrompt = GObject.registerClass({
this.emit('prompted'); this.emit('prompted');
} }
_onCredentialManagerAuthenticated() { _onOVirtUserAuthenticated() {
if (this.verificationStatus != AuthPromptStatus.VERIFICATION_SUCCEEDED) if (this.verificationStatus != AuthPromptStatus.VERIFICATION_SUCCEEDED)
this.reset(); this.reset();
} }

View File

@@ -1,24 +0,0 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
/* exported CredentialManager */
class CredentialManager {
constructor(service) {
this._token = null;
this._service = service;
this._authenticatedSignalId = null;
}
get token() {
return this._token;
}
set token(t) {
this._token = t;
if (this._token)
this.emit('user-authenticated', this._token);
}
get service() {
return this._service;
}
}

View File

@@ -810,8 +810,8 @@ var LoginDialog = GObject.registerClass({
return; return;
this._logoBin.destroy_all_children(); this._logoBin.destroy_all_children();
const resourceScale = this._logoBin.get_resource_scale(); const [valid, resourceScale] = this._logoBin.get_resource_scale();
if (this._logoFile) { 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,
@@ -953,15 +953,16 @@ var LoginDialog = GObject.registerClass({
if (this.opacity == 255 && this._authPrompt.verificationStatus == AuthPrompt.AuthPromptStatus.NOT_VERIFYING) if (this.opacity == 255 && this._authPrompt.verificationStatus == AuthPrompt.AuthPromptStatus.NOT_VERIFYING)
return; return;
if (this._authPrompt.verificationStatus !== AuthPrompt.AuthPromptStatus.NOT_VERIFYING)
this._authPrompt.reset();
this._bindOpacity(); this._bindOpacity();
this.ease({ this.ease({
opacity: 255, opacity: 255,
duration: _FADE_ANIMATION_TIME, duration: _FADE_ANIMATION_TIME,
mode: Clutter.AnimationMode.EASE_OUT_QUAD, mode: Clutter.AnimationMode.EASE_OUT_QUAD,
onComplete: () => this._unbindOpacity(), onComplete: () => {
if (this._authPrompt.verificationStatus != AuthPrompt.AuthPromptStatus.NOT_VERIFYING)
this._authPrompt.reset();
this._unbindOpacity();
},
}); });
} }

View File

@@ -3,9 +3,6 @@
const Gio = imports.gi.Gio; const Gio = imports.gi.Gio;
const Signals = imports.signals; const Signals = imports.signals;
const Credential = imports.gdm.credentialManager;
var SERVICE_NAME = 'gdm-ovirtcred';
const OVirtCredentialsIface = ` const OVirtCredentialsIface = `
<node> <node>
@@ -31,14 +28,30 @@ function OVirtCredentials() {
return self; return self;
} }
var OVirtCredentialsManager = class OVirtCredentialsManager extends Credential.CredentialManager { var OVirtCredentialsManager = class {
constructor() { constructor() {
super(SERVICE_NAME); this._token = null;
this._credentials = new OVirtCredentials(); this._credentials = new OVirtCredentials();
this._credentials.connectSignal('UserAuthenticated', this._credentials.connectSignal('UserAuthenticated',
(proxy, sender, [token]) => { this._onUserAuthenticated.bind(this));
this.token = token; }
});
_onUserAuthenticated(proxy, sender, [token]) {
this._token = token;
this.emit('user-authenticated', token);
}
hasToken() {
return this._token != null;
}
getToken() {
return this._token;
}
resetToken() {
this._token = null;
} }
}; };
Signals.addSignalMethods(OVirtCredentialsManager.prototype); Signals.addSignalMethods(OVirtCredentialsManager.prototype);

View File

@@ -8,7 +8,6 @@ const Signals = imports.signals;
const Batch = imports.gdm.batch; const Batch = imports.gdm.batch;
const Fprint = imports.gdm.fingerprint; const Fprint = imports.gdm.fingerprint;
const OVirt = imports.gdm.oVirt; const OVirt = imports.gdm.oVirt;
const Vmware = imports.gdm.vmware;
const Main = imports.ui.main; 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;
@@ -25,6 +24,7 @@ Gio._promisify(Gdm.UserVerifierProxy.prototype,
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';
var OVIRT_SERVICE_NAME = 'gdm-ovirtcred';
var FADE_ANIMATION_TIME = 160; var FADE_ANIMATION_TIME = 160;
var CLONE_FADE_ANIMATION_TIME = 250; var CLONE_FADE_ANIMATION_TIME = 250;
@@ -160,20 +160,13 @@ var ShellUserVerifier = class {
this._failCounter = 0; this._failCounter = 0;
this._credentialManagers = {}; this._oVirtCredentialsManager = OVirt.getOVirtCredentialsManager();
this._credentialManagers[OVirt.SERVICE_NAME] = OVirt.getOVirtCredentialsManager();
this._credentialManagers[Vmware.SERVICE_NAME] = Vmware.getVmwareCredentialsManager();
for (let service in this._credentialManagers) { if (this._oVirtCredentialsManager.hasToken())
if (this._credentialManagers[service].token) { this._oVirtUserAuthenticated(this._oVirtCredentialsManager.getToken());
this._onCredentialManagerAuthenticated(this._credentialManagers[service],
this._credentialManagers[service].token);
}
this._credentialManagers[service]._authenticatedSignalId = this._oVirtUserAuthenticatedId = this._oVirtCredentialsManager.connect('user-authenticated',
this._credentialManagers[service].connect('user-authenticated', this._oVirtUserAuthenticated.bind(this));
this._onCredentialManagerAuthenticated.bind(this));
}
} }
begin(userName, hold) { begin(userName, hold) {
@@ -229,11 +222,8 @@ var ShellUserVerifier = class {
this._smartcardManager.disconnect(this._smartcardRemovedId); this._smartcardManager.disconnect(this._smartcardRemovedId);
this._smartcardManager = null; this._smartcardManager = null;
for (let service in this._credentialManagers) { this._oVirtCredentialsManager.disconnect(this._oVirtUserAuthenticatedId);
let credentialManager = this._credentialManagers[service]; this._oVirtCredentialsManager = null;
credentialManager.disconnect(credentialManager._authenticatedSignalId);
credentialManager = null;
}
} }
answerQuery(serviceName, answer) { answerQuery(serviceName, answer) {
@@ -321,9 +311,9 @@ var ShellUserVerifier = class {
}); });
} }
_onCredentialManagerAuthenticated(credentialManager, _token) { _oVirtUserAuthenticated(_token) {
this._preemptingService = credentialManager.service; this._preemptingService = OVIRT_SERVICE_NAME;
this.emit('credential-manager-authenticated'); this.emit('ovirt-user-authenticated');
} }
_checkForSmartcard() { _checkForSmartcard() {
@@ -500,12 +490,9 @@ var ShellUserVerifier = class {
if (!this.serviceIsForeground(serviceName)) if (!this.serviceIsForeground(serviceName))
return; return;
let token = null; if (serviceName == OVIRT_SERVICE_NAME) {
if (this._credentialManagers[serviceName]) // The only question asked by this service is "Token?"
token = this._credentialManagers[serviceName].token; this.answerQuery(serviceName, this._oVirtCredentialsManager.getToken());
if (token) {
this.answerQuery(serviceName, token);
return; return;
} }
@@ -573,10 +560,8 @@ var ShellUserVerifier = class {
// If the login failed with the preauthenticated oVirt credentials // If the login failed with the preauthenticated oVirt credentials
// then discard the credentials and revert to default authentication // then discard the credentials and revert to default authentication
// mechanism. // mechanism.
let foregroundService = Object.keys(this._credentialManagers).find(service => if (this.serviceIsForeground(OVIRT_SERVICE_NAME)) {
this.serviceIsForeground(service)); this._oVirtCredentialsManager.resetToken();
if (foregroundService) {
this._credentialManagers[foregroundService].token = null;
this._preemptingService = null; this._preemptingService = null;
this._verificationFailed(false); this._verificationFailed(false);
return; return;

View File

@@ -1,54 +0,0 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
/* exported getVmwareCredentialsManager */
const Gio = imports.gi.Gio;
const Signals = imports.signals;
const Credential = imports.gdm.credentialManager;
const dbusPath = '/org/vmware/viewagent/Credentials';
const dbusInterface = 'org.vmware.viewagent.Credentials';
var SERVICE_NAME = 'gdm-vmwcred';
const VmwareCredentialsIface = '<node> \
<interface name="' + dbusInterface + '"> \
<signal name="UserAuthenticated"> \
<arg type="s" name="token"/> \
</signal> \
</interface> \
</node>';
const VmwareCredentialsInfo = Gio.DBusInterfaceInfo.new_for_xml(VmwareCredentialsIface);
let _vmwareCredentialsManager = null;
function VmwareCredentials() {
var self = new Gio.DBusProxy({ g_connection: Gio.DBus.session,
g_interface_name: VmwareCredentialsInfo.name,
g_interface_info: VmwareCredentialsInfo,
g_name: dbusInterface,
g_object_path: dbusPath,
g_flags: Gio.DBusProxyFlags.DO_NOT_LOAD_PROPERTIES });
self.init(null);
return self;
}
var VmwareCredentialsManager = class VmwareCredentialsManager extends Credential.CredentialManager {
constructor() {
super(SERVICE_NAME);
this._credentials = new VmwareCredentials();
this._credentials.connectSignal('UserAuthenticated',
(proxy, sender, [token]) => {
this.token = token;
});
}
};
Signals.addSignalMethods(VmwareCredentialsManager.prototype);
function getVmwareCredentialsManager() {
if (!_vmwareCredentialsManager)
_vmwareCredentialsManager = new VmwareCredentialsManager();
return _vmwareCredentialsManager;
}

View File

@@ -6,8 +6,6 @@
<file>gdm/fingerprint.js</file> <file>gdm/fingerprint.js</file>
<file>gdm/loginDialog.js</file> <file>gdm/loginDialog.js</file>
<file>gdm/oVirt.js</file> <file>gdm/oVirt.js</file>
<file>gdm/credentialManager.js</file>
<file>gdm/vmware.js</file>
<file>gdm/realmd.js</file> <file>gdm/realmd.js</file>
<file>gdm/util.js</file> <file>gdm/util.js</file>
@@ -32,7 +30,6 @@
<file>misc/util.js</file> <file>misc/util.js</file>
<file>misc/weather.js</file> <file>misc/weather.js</file>
<file>perf/basic.js</file>
<file>perf/core.js</file> <file>perf/core.js</file>
<file>perf/hwtest.js</file> <file>perf/hwtest.js</file>
@@ -93,6 +90,7 @@
<file>ui/ripples.js</file> <file>ui/ripples.js</file>
<file>ui/runDialog.js</file> <file>ui/runDialog.js</file>
<file>ui/screenShield.js</file> <file>ui/screenShield.js</file>
<file>ui/screencast.js</file>
<file>ui/screenshot.js</file> <file>ui/screenshot.js</file>
<file>ui/scripting.js</file> <file>ui/scripting.js</file>
<file>ui/search.js</file> <file>ui/search.js</file>
@@ -137,6 +135,7 @@
<file>ui/status/volume.js</file> <file>ui/status/volume.js</file>
<file>ui/status/bluetooth.js</file> <file>ui/status/bluetooth.js</file>
<file>ui/status/remoteAccess.js</file> <file>ui/status/remoteAccess.js</file>
<file>ui/status/screencast.js</file>
<file>ui/status/system.js</file> <file>ui/status/system.js</file>
<file>ui/status/thunderbolt.js</file> <file>ui/status/thunderbolt.js</file>
</gresource> </gresource>

View File

@@ -1,6 +1,6 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
/* exported collectFromDatadirs, recursivelyDeleteDir, /* exported collectFromDatadirs, recursivelyDeleteDir,
recursivelyMoveDir, loadInterfaceXML, loadSubInterfaceXML */ recursivelyMoveDir, loadInterfaceXML */
const { Gio, GLib } = imports.gi; const { Gio, GLib } = imports.gi;
const Config = imports.misc.config; const Config = imports.misc.config;
@@ -67,19 +67,14 @@ function recursivelyMoveDir(srcDir, destDir) {
} }
let _ifaceResource = null; let _ifaceResource = null;
function ensureIfaceResource() {
if (_ifaceResource)
return;
// don't use global.datadir so the method is usable from tests/tools
let dir = GLib.getenv('GNOME_SHELL_DATADIR') || Config.PKGDATADIR;
let path = `${dir}/gnome-shell-dbus-interfaces.gresource`;
_ifaceResource = Gio.Resource.load(path);
_ifaceResource._register();
}
function loadInterfaceXML(iface) { function loadInterfaceXML(iface) {
ensureIfaceResource(); if (!_ifaceResource) {
// don't use global.datadir so the method is usable from tests/tools
let dir = GLib.getenv('GNOME_SHELL_DATADIR') || Config.PKGDATADIR;
let path = `${dir}/gnome-shell-dbus-interfaces.gresource`;
_ifaceResource = Gio.Resource.load(path);
_ifaceResource._register();
}
let uri = `resource:///org/gnome/shell/dbus-interfaces/${iface}.xml`; let uri = `resource:///org/gnome/shell/dbus-interfaces/${iface}.xml`;
let f = Gio.File.new_for_uri(uri); let f = Gio.File.new_for_uri(uri);
@@ -93,25 +88,3 @@ function loadInterfaceXML(iface) {
return null; return null;
} }
function loadSubInterfaceXML(iface, ifaceFile) {
let xml = loadInterfaceXML(ifaceFile);
if (!xml)
return null;
let ifaceStartTag = `<interface name="${iface}">`;
let ifaceStopTag = '</interface>';
let ifaceStartIndex = xml.indexOf(ifaceStartTag);
let ifaceEndIndex = xml.indexOf(ifaceStopTag, ifaceStartIndex + 1) + ifaceStopTag.length;
let xmlHeader = '<!DOCTYPE node PUBLIC\n' +
'\'-//freedesktop//DTD D-BUS Object Introspection 1.0//EN\'\n' +
'\'http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd\'>\n' +
'<node>\n';
let xmlFooter = '</node>';
return (
xmlHeader +
xml.substr(ifaceStartIndex, ifaceEndIndex - ifaceStartIndex) +
xmlFooter);
}

View File

@@ -3,9 +3,9 @@ const { Gio, GLib, Meta, Shell, St } = imports.gi;
const INTROSPECT_SCHEMA = 'org.gnome.shell'; const INTROSPECT_SCHEMA = 'org.gnome.shell';
const INTROSPECT_KEY = 'introspect'; const INTROSPECT_KEY = 'introspect';
const APP_ALLOWLIST = ['org.freedesktop.impl.portal.desktop.gtk']; const APP_WHITELIST = ['org.freedesktop.impl.portal.desktop.gtk'];
const INTROSPECT_DBUS_API_VERSION = 3; const INTROSPECT_DBUS_API_VERSION = 2;
const { loadInterfaceXML } = imports.misc.fileUtils; const { loadInterfaceXML } = imports.misc.fileUtils;
@@ -46,24 +46,19 @@ var IntrospectService = class {
this._syncRunningApplications(); this._syncRunningApplications();
this._allowlistMap = new Map(); this._whitelistMap = new Map();
APP_ALLOWLIST.forEach(appName => { APP_WHITELIST.forEach(appName => {
Gio.DBus.watch_name(Gio.BusType.SESSION, Gio.DBus.watch_name(Gio.BusType.SESSION,
appName, appName,
Gio.BusNameWatcherFlags.NONE, Gio.BusNameWatcherFlags.NONE,
(conn, name, owner) => this._allowlistMap.set(name, owner), (conn, name, owner) => this._whitelistMap.set(name, owner),
(conn, name) => this._allowlistMap.delete(name)); (conn, name) => this._whitelistMap.delete(name));
}); });
this._settings = St.Settings.get(); this._settings = St.Settings.get();
this._settings.connect('notify::enable-animations', this._settings.connect('notify::enable-animations',
this._syncAnimationsEnabled.bind(this)); this._syncAnimationsEnabled.bind(this));
this._syncAnimationsEnabled(); this._syncAnimationsEnabled();
const monitorManager = Meta.MonitorManager.get();
monitorManager.connect('monitors-changed',
this._syncScreenSize.bind(this));
this._syncScreenSize();
} }
_isStandaloneApp(app) { _isStandaloneApp(app) {
@@ -74,8 +69,8 @@ var IntrospectService = class {
return this._introspectSettings.get_boolean(INTROSPECT_KEY); return this._introspectSettings.get_boolean(INTROSPECT_KEY);
} }
_isSenderAllowed(sender) { _isSenderWhitelisted(sender) {
return [...this._allowlistMap.values()].includes(sender); return [...this._whitelistMap.values()].includes(sender);
} }
_getSandboxedAppId(app) { _getSandboxedAppId(app) {
@@ -138,7 +133,7 @@ var IntrospectService = class {
if (this._isIntrospectEnabled()) if (this._isIntrospectEnabled())
return true; return true;
if (this._isSenderAllowed(invocation.get_sender())) if (this._isSenderWhitelisted(invocation.get_sender()))
return true; return true;
return false; return false;
@@ -214,28 +209,10 @@ var IntrospectService = class {
} }
} }
_syncScreenSize() {
const oldScreenWidth = this._screenWidth;
const oldScreenHeight = this._screenHeight;
this._screenWidth = global.screen_width;
this._screenHeight = global.screen_height;
if (oldScreenWidth !== this._screenWidth ||
oldScreenHeight !== this._screenHeight) {
const variant = new GLib.Variant('(ii)',
[this._screenWidth, this._screenHeight]);
this._dbusImpl.emit_property_changed('ScreenSize', variant);
}
}
get AnimationsEnabled() { get AnimationsEnabled() {
return this._animationsEnabled; return this._animationsEnabled;
} }
get ScreenSize() {
return [this._screenWidth, this._screenHeight];
}
get version() { get version() {
return INTROSPECT_DBUS_API_VERSION; return INTROSPECT_DBUS_API_VERSION;
} }

View File

@@ -158,23 +158,6 @@ var LoginManagerSystemd = class {
}); });
} }
canRebootToBootLoaderMenu(asyncCallback) {
this._proxy.CanRebootToBootLoaderMenuRemote((result, error) => {
if (error) {
asyncCallback(false, false);
} else {
const needsAuth = result[0] === 'challenge';
const canRebootToBootLoaderMenu = needsAuth || result[0] === 'yes';
asyncCallback(canRebootToBootLoaderMenu, needsAuth);
}
});
}
setRebootToBootLoaderMenu() {
/* Parameter is timeout in usec, show to menu for 60 seconds */
this._proxy.SetRebootToBootLoaderMenuRemote(60000000);
}
listSessions(asyncCallback) { listSessions(asyncCallback) {
this._proxy.ListSessionsRemote((result, error) => { this._proxy.ListSessionsRemote((result, error) => {
if (error) if (error)
@@ -220,13 +203,6 @@ var LoginManagerDummy = class {
asyncCallback(false, false); asyncCallback(false, false);
} }
canRebootToBootLoaderMenu(asyncCallback) {
asyncCallback(false, false);
}
setRebootToBootLoaderMenu() {
}
listSessions(asyncCallback) { listSessions(asyncCallback) {
asyncCallback([]); asyncCallback([]);
} }

View File

@@ -121,10 +121,10 @@ var ParentalControlsManager = GObject.registerClass({
// Calculate whether the given app (a Gio.DesktopAppInfo) should be shown // Calculate whether the given app (a Gio.DesktopAppInfo) should be shown
// on the desktop, in search results, etc. The app should be shown if: // on the desktop, in search results, etc. The app should be shown if:
// - The .desktop file doesnt say it should be hidden. // - The .desktop file doesnt say it should be hidden.
// - The executable from the .desktop files Exec line isnt denied in // - The executable from the .desktop files Exec line isnt blacklisted in
// the users parental controls. // the users parental controls.
// - None of the flatpak app IDs from the X-Flatpak and the // - None of the flatpak app IDs from the X-Flatpak and the
// X-Flatpak-RenamedFrom lines are denied in the users parental // X-Flatpak-RenamedFrom lines are blacklisted in the users parental
// controls. // controls.
shouldShowApp(appInfo) { shouldShowApp(appInfo) {
// Quick decision? // Quick decision?

View File

@@ -21,7 +21,6 @@ const SENSOR_OBJECT_PATH = '/net/hadess/SensorProxy';
const SensorProxyInterface = loadInterfaceXML('net.hadess.SensorProxy'); const SensorProxyInterface = loadInterfaceXML('net.hadess.SensorProxy');
const POWER_OFF_ACTION_ID = 'power-off'; const POWER_OFF_ACTION_ID = 'power-off';
const RESTART_ACTION_ID = 'restart';
const LOCK_SCREEN_ACTION_ID = 'lock-screen'; const LOCK_SCREEN_ACTION_ID = 'lock-screen';
const LOGOUT_ACTION_ID = 'logout'; const LOGOUT_ACTION_ID = 'logout';
const SUSPEND_ACTION_ID = 'suspend'; const SUSPEND_ACTION_ID = 'suspend';
@@ -41,38 +40,41 @@ function getDefault() {
const SystemActions = GObject.registerClass({ const SystemActions = GObject.registerClass({
Properties: { Properties: {
'can-power-off': GObject.ParamSpec.boolean( 'can-power-off': GObject.ParamSpec.boolean('can-power-off',
'can-power-off', 'can-power-off', 'can-power-off', 'can-power-off',
GObject.ParamFlags.READABLE, 'can-power-off',
false), GObject.ParamFlags.READABLE,
'can-restart': GObject.ParamSpec.boolean( false),
'can-restart', 'can-restart', 'can-restart', 'can-suspend': GObject.ParamSpec.boolean('can-suspend',
GObject.ParamFlags.READABLE, 'can-suspend',
false), 'can-suspend',
'can-suspend': GObject.ParamSpec.boolean( GObject.ParamFlags.READABLE,
'can-suspend', 'can-suspend', 'can-suspend', false),
GObject.ParamFlags.READABLE, 'can-lock-screen': GObject.ParamSpec.boolean('can-lock-screen',
false), 'can-lock-screen',
'can-lock-screen': GObject.ParamSpec.boolean( 'can-lock-screen',
'can-lock-screen', 'can-lock-screen', 'can-lock-screen', GObject.ParamFlags.READABLE,
GObject.ParamFlags.READABLE, false),
false), 'can-switch-user': GObject.ParamSpec.boolean('can-switch-user',
'can-switch-user': GObject.ParamSpec.boolean( 'can-switch-user',
'can-switch-user', 'can-switch-user', 'can-switch-user', 'can-switch-user',
GObject.ParamFlags.READABLE, GObject.ParamFlags.READABLE,
false), false),
'can-logout': GObject.ParamSpec.boolean( 'can-logout': GObject.ParamSpec.boolean('can-logout',
'can-logout', 'can-logout', 'can-logout', 'can-logout',
GObject.ParamFlags.READABLE, 'can-logout',
false), GObject.ParamFlags.READABLE,
'can-lock-orientation': GObject.ParamSpec.boolean( false),
'can-lock-orientation', 'can-lock-orientation', 'can-lock-orientation', 'can-lock-orientation': GObject.ParamSpec.boolean('can-lock-orientation',
GObject.ParamFlags.READABLE, 'can-lock-orientation',
false), 'can-lock-orientation',
'orientation-lock-icon': GObject.ParamSpec.string( GObject.ParamFlags.READABLE,
'orientation-lock-icon', 'orientation-lock-icon', 'orientation-lock-icon', false),
GObject.ParamFlags.READWRITE, 'orientation-lock-icon': GObject.ParamSpec.string('orientation-lock-icon',
null), 'orientation-lock-icon',
'orientation-lock-icon',
GObject.ParamFlags.READWRITE,
null),
}, },
}, class SystemActions extends GObject.Object { }, class SystemActions extends GObject.Object {
_init() { _init() {
@@ -91,15 +93,7 @@ const SystemActions = GObject.registerClass({
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: tokenizeKeywords(_('power off;shutdown;halt;stop')), keywords: tokenizeKeywords(_('power off;shutdown;reboot;restart;halt;stop')),
available: false,
});
this._actions.set(RESTART_ACTION_ID, {
// Translators: The name of the restart action in search
name: C_('search-result', 'Restart'),
iconName: 'system-reboot-symbolic',
// Translators: A list of keywords that match the restart action, separated by semicolons
keywords: tokenizeKeywords(_('reboot;restart;')),
available: false, available: false,
}); });
this._actions.set(LOCK_SCREEN_ACTION_ID, { this._actions.set(LOCK_SCREEN_ACTION_ID, {
@@ -209,11 +203,6 @@ const SystemActions = GObject.registerClass({
return this._actions.get(POWER_OFF_ACTION_ID).available; return this._actions.get(POWER_OFF_ACTION_ID).available;
} }
// eslint-disable-next-line camelcase
get can_restart() {
return this._actions.get(RESTART_ACTION_ID).available;
}
// eslint-disable-next-line camelcase // eslint-disable-next-line camelcase
get can_suspend() { get can_suspend() {
return this._actions.get(SUSPEND_ACTION_ID).available; return this._actions.get(SUSPEND_ACTION_ID).available;
@@ -317,9 +306,6 @@ const SystemActions = GObject.registerClass({
case POWER_OFF_ACTION_ID: case POWER_OFF_ACTION_ID:
this.activatePowerOff(); this.activatePowerOff();
break; break;
case RESTART_ACTION_ID:
this.activateRestart();
break;
case LOCK_SCREEN_ACTION_ID: case LOCK_SCREEN_ACTION_ID:
this.activateLockScreen(); this.activateLockScreen();
break; break;
@@ -361,9 +347,6 @@ const SystemActions = GObject.registerClass({
this._loginScreenSettings.get_boolean(DISABLE_RESTART_KEY)); this._loginScreenSettings.get_boolean(DISABLE_RESTART_KEY));
this._actions.get(POWER_OFF_ACTION_ID).available = this._canHavePowerOff && !disabled; this._actions.get(POWER_OFF_ACTION_ID).available = this._canHavePowerOff && !disabled;
this.notify('can-power-off'); this.notify('can-power-off');
this._actions.get(RESTART_ACTION_ID).available = this._canHavePowerOff && !disabled;
this.notify('can-restart');
} }
_updateHaveSuspend() { _updateHaveSuspend() {
@@ -462,13 +445,6 @@ const SystemActions = GObject.registerClass({
this._session.ShutdownRemote(0); this._session.ShutdownRemote(0);
} }
activateRestart() {
if (!this._actions.get(RESTART_ACTION_ID).available)
throw new Error('The restart action is not available!');
this._session.RebootRemote();
}
activateSuspend() { activateSuspend() {
if (!this._actions.get(SUSPEND_ACTION_ID).available) if (!this._actions.get(SUSPEND_ACTION_ID).available)
throw new Error('The suspend action is not available!'); throw new Error('The suspend action is not available!');

View File

@@ -1,146 +0,0 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
/* exported run, finish, script_topBarNavDone, script_notificationShowDone,
script_notificationCloseDone, script_overviewShowDone,
script_applicationsShowStart, script_applicationsShowDone, METRICS,
*/
/* eslint camelcase: ["error", { properties: "never", allow: ["^script_"] }] */
const { St } = imports.gi;
const Main = imports.ui.main;
const MessageTray = imports.ui.messageTray;
const Scripting = imports.ui.scripting;
// This script tests the most important (basic) functionality of the shell.
var METRICS = {};
async function run() {
/* eslint-disable no-await-in-loop */
Scripting.defineScriptEvent('topBarNavStart', 'Starting to navigate the top bar');
Scripting.defineScriptEvent('topBarNavDone', 'Done navigating the top bar');
Scripting.defineScriptEvent('notificationShowStart', 'Showing a notification');
Scripting.defineScriptEvent('notificationShowDone', 'Done showing a notification');
Scripting.defineScriptEvent('notificationCloseStart', 'Closing a notification');
Scripting.defineScriptEvent('notificationCloseDone', 'Done closing a notification');
Scripting.defineScriptEvent('overviewShowStart', 'Starting to show the overview');
Scripting.defineScriptEvent('overviewShowDone', 'Overview finished showing');
Scripting.defineScriptEvent('applicationsShowStart', 'Starting to switch to applications view');
Scripting.defineScriptEvent('applicationsShowDone', 'Done switching to applications view');
Main.overview.connect('shown',
() => Scripting.scriptEvent('overviewShowDone'));
await Scripting.sleep(1000);
// navigate through top bar
Scripting.scriptEvent('topBarNavStart');
Main.panel.statusArea.aggregateMenu.menu.open();
await Scripting.sleep(400);
const { menuManager } = Main.panel;
while (menuManager.activeMenu &&
Main.panel.navigate_focus(menuManager.activeMenu.sourceActor,
St.DirectionType.TAB_BACKWARD, false))
await Scripting.sleep(400);
Scripting.scriptEvent('topBarNavDone');
await Scripting.sleep(1000);
// notification
const source = new MessageTray.SystemNotificationSource();
Main.messageTray.add(source);
Scripting.scriptEvent('notificationShowStart');
source.connect('notification-show',
() => Scripting.scriptEvent('notificationShowDone'));
const notification = new MessageTray.Notification(source,
'A test notification');
source.showNotification(notification);
await Scripting.sleep(400);
Main.panel.statusArea.dateMenu.menu.open();
await Scripting.sleep(400);
Scripting.scriptEvent('notificationCloseStart');
notification.connect('destroy',
() => Scripting.scriptEvent('notificationCloseDone'));
notification.destroy();
await Scripting.sleep(400);
Main.panel.statusArea.dateMenu.menu.close();
await Scripting.waitLeisure();
await Scripting.sleep(1000);
// overview (window picker)
Scripting.scriptEvent('overviewShowStart');
Main.overview.show();
await Scripting.waitLeisure();
Main.overview.hide();
await Scripting.waitLeisure();
await Scripting.sleep(1000);
// overview (app picker)
Main.overview.show();
await Scripting.waitLeisure();
Scripting.scriptEvent('applicationsShowStart');
// eslint-disable-next-line require-atomic-updates
Main.overview.dash.showAppsButton.checked = true;
await Scripting.waitLeisure();
Scripting.scriptEvent('applicationsShowDone');
// eslint-disable-next-line require-atomic-updates
Main.overview.dash.showAppsButton.checked = false;
await Scripting.waitLeisure();
Main.overview.hide();
await Scripting.waitLeisure();
/* eslint-enable no-await-in-loop */
}
let topBarNav = false;
let notificationShown = false;
let notificationClosed = false;
let windowPickerShown = false;
let appPickerShown = false;
function script_topBarNavDone() {
topBarNav = true;
}
function script_notificationShowDone() {
notificationShown = true;
}
function script_notificationCloseDone() {
notificationClosed = true;
}
function script_overviewShowDone() {
windowPickerShown = true;
}
function script_applicationsShowDone() {
appPickerShown = true;
}
function finish() {
if (!topBarNav)
throw new Error('Failed to navigate top bar');
if (!notificationShown)
throw new Error('Failed to show notification');
if (!notificationClosed)
throw new Error('Failed to close notification');
if (!windowPickerShown)
throw new Error('Failed to show window picker');
if (!appPickerShown)
throw new Error('Failed to show app picker');
}

View File

@@ -70,8 +70,7 @@ let WINDOW_CONFIGS = [
{ width: 640, height: 480, alpha: true, maximized: false, count: 10, metric: 'overviewFps10Alpha' }, { width: 640, height: 480, alpha: true, maximized: false, count: 10, metric: 'overviewFps10Alpha' },
]; ];
async function run() { function *run() {
/* eslint-disable no-await-in-loop */
Scripting.defineScriptEvent("overviewShowStart", "Starting to show the overview"); Scripting.defineScriptEvent("overviewShowStart", "Starting to show the overview");
Scripting.defineScriptEvent("overviewShowDone", "Overview finished showing"); Scripting.defineScriptEvent("overviewShowDone", "Overview finished showing");
Scripting.defineScriptEvent("afterShowHide", "After a show/hide cycle for the overview"); Scripting.defineScriptEvent("afterShowHide", "After a show/hide cycle for the overview");
@@ -85,7 +84,7 @@ async function run() {
Scripting.scriptEvent('overviewShowDone'); Scripting.scriptEvent('overviewShowDone');
}); });
await Scripting.sleep(1000); yield Scripting.sleep(1000);
for (let i = 0; i < 2 * WINDOW_CONFIGS.length; i++) { for (let i = 0; i < 2 * WINDOW_CONFIGS.length; i++) {
// We go to the overview twice for each configuration; the first time // We go to the overview twice for each configuration; the first time
@@ -93,50 +92,49 @@ async function run() {
// a clean set of numbers. // a clean set of numbers.
if ((i % 2) == 0) { if ((i % 2) == 0) {
let config = WINDOW_CONFIGS[i / 2]; let config = WINDOW_CONFIGS[i / 2];
await Scripting.destroyTestWindows(); yield Scripting.destroyTestWindows();
for (let k = 0; k < config.count; k++) { for (let k = 0; k < config.count; k++) {
await Scripting.createTestWindow({ width: config.width, yield Scripting.createTestWindow({ width: config.width,
height: config.height, height: config.height,
alpha: config.alpha, alpha: config.alpha,
maximized: config.maximized }); maximized: config.maximized });
} }
await Scripting.waitTestWindows(); yield Scripting.waitTestWindows();
await Scripting.sleep(1000); yield Scripting.sleep(1000);
await Scripting.waitLeisure(); yield Scripting.waitLeisure();
} }
Scripting.scriptEvent('overviewShowStart'); Scripting.scriptEvent('overviewShowStart');
Main.overview.show(); Main.overview.show();
await Scripting.waitLeisure(); yield Scripting.waitLeisure();
Main.overview.hide(); Main.overview.hide();
await Scripting.waitLeisure(); yield Scripting.waitLeisure();
System.gc(); System.gc();
await Scripting.sleep(1000); yield Scripting.sleep(1000);
Scripting.collectStatistics(); Scripting.collectStatistics();
Scripting.scriptEvent('afterShowHide'); Scripting.scriptEvent('afterShowHide');
} }
await Scripting.destroyTestWindows(); yield Scripting.destroyTestWindows();
await Scripting.sleep(1000); yield Scripting.sleep(1000);
Main.overview.show(); Main.overview.show();
await Scripting.waitLeisure(); yield Scripting.waitLeisure();
for (let i = 0; i < 2; i++) { for (let i = 0; i < 2; i++) {
Scripting.scriptEvent('applicationsShowStart'); Scripting.scriptEvent('applicationsShowStart');
// eslint-disable-next-line require-atomic-updates // eslint-disable-next-line require-atomic-updates
Main.overview.dash.showAppsButton.checked = true; Main.overview.dash.showAppsButton.checked = true;
await Scripting.waitLeisure(); yield Scripting.waitLeisure();
Scripting.scriptEvent('applicationsShowDone'); Scripting.scriptEvent('applicationsShowDone');
// eslint-disable-next-line require-atomic-updates // eslint-disable-next-line require-atomic-updates
Main.overview.dash.showAppsButton.checked = false; Main.overview.dash.showAppsButton.checked = false;
await Scripting.waitLeisure(); yield Scripting.waitLeisure();
} }
/* eslint-enable no-await-in-loop */
} }
let showingOverview = false; let showingOverview = false;

View File

@@ -94,8 +94,7 @@ function extractBootTimestamp() {
return result; return result;
} }
async function run() { function *run() {
/* eslint-disable no-await-in-loop */
Scripting.defineScriptEvent("desktopShown", "Finished initial animation"); Scripting.defineScriptEvent("desktopShown", "Finished initial animation");
Scripting.defineScriptEvent("overviewShowStart", "Starting to show the overview"); Scripting.defineScriptEvent("overviewShowStart", "Starting to show the overview");
Scripting.defineScriptEvent("overviewShowDone", "Overview finished showing"); Scripting.defineScriptEvent("overviewShowDone", "Overview finished showing");
@@ -111,7 +110,7 @@ async function run() {
Scripting.defineScriptEvent("geditLaunch", "gedit application launch"); Scripting.defineScriptEvent("geditLaunch", "gedit application launch");
Scripting.defineScriptEvent("geditFirstFrame", "first frame of gedit window drawn"); Scripting.defineScriptEvent("geditFirstFrame", "first frame of gedit window drawn");
await Scripting.waitLeisure(); yield Scripting.waitLeisure();
Scripting.scriptEvent('desktopShown'); Scripting.scriptEvent('desktopShown');
let interfaceSettings = new Gio.Settings({ let interfaceSettings = new Gio.Settings({
@@ -121,22 +120,22 @@ async function run() {
Scripting.scriptEvent('overviewShowStart'); Scripting.scriptEvent('overviewShowStart');
Main.overview.show(); Main.overview.show();
await Scripting.waitLeisure(); yield Scripting.waitLeisure();
Scripting.scriptEvent('overviewShowDone'); Scripting.scriptEvent('overviewShowDone');
await Scripting.sleep(1000); yield Scripting.sleep(1000);
Scripting.scriptEvent('applicationsShowStart'); Scripting.scriptEvent('applicationsShowStart');
// eslint-disable-next-line require-atomic-updates // eslint-disable-next-line require-atomic-updates
Main.overview.dash.showAppsButton.checked = true; Main.overview.dash.showAppsButton.checked = true;
await Scripting.waitLeisure(); yield Scripting.waitLeisure();
Scripting.scriptEvent('applicationsShowDone'); Scripting.scriptEvent('applicationsShowDone');
await Scripting.sleep(1000); yield Scripting.sleep(1000);
Main.overview.hide(); Main.overview.hide();
await Scripting.waitLeisure(); yield Scripting.waitLeisure();
// --------------------- // // --------------------- //
// Tests of redraw speed // // Tests of redraw speed //
@@ -146,46 +145,46 @@ async function run() {
global.frame_finish_timestamp = true; global.frame_finish_timestamp = true;
for (let k = 0; k < 5; k++) for (let k = 0; k < 5; k++)
await Scripting.createTestWindow({ maximized: true }); yield Scripting.createTestWindow({ maximized: true });
await Scripting.waitTestWindows(); yield Scripting.waitTestWindows();
await Scripting.sleep(1000); yield Scripting.sleep(1000);
Scripting.scriptEvent('mainViewDrawStart'); Scripting.scriptEvent('mainViewDrawStart');
await waitAndDraw(1000); yield waitAndDraw(1000);
Scripting.scriptEvent('mainViewDrawDone'); Scripting.scriptEvent('mainViewDrawDone');
Main.overview.show(); Main.overview.show();
Scripting.waitLeisure(); Scripting.waitLeisure();
await Scripting.sleep(1500); yield Scripting.sleep(1500);
Scripting.scriptEvent('overviewDrawStart'); Scripting.scriptEvent('overviewDrawStart');
await waitAndDraw(1000); yield waitAndDraw(1000);
Scripting.scriptEvent('overviewDrawDone'); Scripting.scriptEvent('overviewDrawDone');
await Scripting.destroyTestWindows(); yield Scripting.destroyTestWindows();
Main.overview.hide(); Main.overview.hide();
await Scripting.createTestWindow({ maximized: true, yield Scripting.createTestWindow({ maximized: true,
redraws: true }); redraws: true });
await Scripting.waitTestWindows(); yield Scripting.waitTestWindows();
await Scripting.sleep(1000); yield Scripting.sleep(1000);
Scripting.scriptEvent('redrawTestStart'); Scripting.scriptEvent('redrawTestStart');
await Scripting.sleep(1000); yield Scripting.sleep(1000);
Scripting.scriptEvent('redrawTestDone'); Scripting.scriptEvent('redrawTestDone');
await Scripting.sleep(1000); yield Scripting.sleep(1000);
Scripting.scriptEvent('collectTimings'); Scripting.scriptEvent('collectTimings');
await Scripting.destroyTestWindows(); yield Scripting.destroyTestWindows();
global.frame_timestamps = false; global.frame_timestamps = false;
global.frame_finish_timestamp = false; global.frame_finish_timestamp = false;
await Scripting.sleep(1000); yield Scripting.sleep(1000);
let appSys = Shell.AppSystem.get_default(); let appSys = Shell.AppSystem.get_default();
let app = appSys.lookup_app('org.gnome.gedit.desktop'); let app = appSys.lookup_app('org.gnome.gedit.desktop');
@@ -198,22 +197,21 @@ async function run() {
throw new Error('gedit was already running'); throw new Error('gedit was already running');
while (windows.length == 0) { while (windows.length == 0) {
await waitSignal(global.display, 'window-created'); yield waitSignal(global.display, 'window-created');
windows = app.get_windows(); windows = app.get_windows();
} }
let actor = windows[0].get_compositor_private(); let actor = windows[0].get_compositor_private();
await waitSignal(actor, 'first-frame'); yield waitSignal(actor, 'first-frame');
Scripting.scriptEvent('geditFirstFrame'); Scripting.scriptEvent('geditFirstFrame');
await Scripting.sleep(1000); yield Scripting.sleep(1000);
windows[0].delete(global.get_current_time()); windows[0].delete(global.get_current_time());
await Scripting.sleep(1000); yield Scripting.sleep(1000);
interfaceSettings.set_boolean('enable-animations', true); interfaceSettings.set_boolean('enable-animations', true);
/* eslint-enable no-await-in-loop */
} }
let overviewShowStart; let overviewShowStart;

View File

@@ -852,9 +852,6 @@ class AppSwitcher extends SwitcherPopup.SwitcherList {
if (index === -1) if (index === -1)
return; return;
this._arrows[index].destroy();
this._arrows.splice(index, 1);
this.icons.splice(index, 1); this.icons.splice(index, 1);
this.removeItem(index); this.removeItem(index);
} }

View File

@@ -60,7 +60,7 @@ class Animation extends St.Bin {
} }
_loadFile(file, width, height) { _loadFile(file, width, height) {
const resourceScale = this.get_resource_scale(); let [validResourceScale, resourceScale] = this.get_resource_scale();
let wasPlaying = this._isPlaying; let wasPlaying = this._isPlaying;
if (this._isPlaying) if (this._isPlaying)
@@ -69,6 +69,12 @@ class Animation extends St.Bin {
this._isLoaded = false; this._isLoaded = false;
this.destroy_all_children(); this.destroy_all_children();
if (!validResourceScale) {
if (wasPlaying)
this.play();
return;
}
let textureCache = St.TextureCache.get_default(); let textureCache = St.TextureCache.get_default();
let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor; let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor;
this._animations = textureCache.load_sliced_image(file, width, height, this._animations = textureCache.load_sliced_image(file, width, height,

File diff suppressed because it is too large Load Diff

View File

@@ -347,8 +347,6 @@ var Background = GObject.registerClass({
this.set_color(color); this.set_color(color);
else else
this.set_gradient(shadingType, color, secondColor); this.set_gradient(shadingType, color, secondColor);
this._setLoaded();
} }
_watchFile(file) { _watchFile(file) {
@@ -714,18 +712,13 @@ var BackgroundManager = class BackgroundManager {
} }
let newBackgroundActor = this._createBackgroundActor(); let newBackgroundActor = this._createBackgroundActor();
newBackgroundActor.vignette_sharpness = this.backgroundActor.vignette_sharpness;
const oldContent = this.backgroundActor.content; newBackgroundActor.brightness = this.backgroundActor.brightness;
const newContent = newBackgroundActor.content;
newContent.vignette_sharpness = oldContent.vignette_sharpness;
newContent.brightness = oldContent.brightness;
newBackgroundActor.visible = this.backgroundActor.visible; newBackgroundActor.visible = this.backgroundActor.visible;
this._newBackgroundActor = newBackgroundActor; this._newBackgroundActor = newBackgroundActor;
const { background } = newBackgroundActor.content; let background = newBackgroundActor.background;
if (background.isLoaded) { if (background.isLoaded) {
this._swapBackgroundActor(); this._swapBackgroundActor();
@@ -767,27 +760,10 @@ var BackgroundManager = class BackgroundManager {
this._updateBackgroundActor(); this._updateBackgroundActor();
}); });
let loadedSignalId;
if (background.isLoaded) {
GLib.idle_add(GLib.PRIORITY_DEFAULT, () => {
this.emit('loaded');
return GLib.SOURCE_REMOVE;
});
} else {
loadedSignalId = background.connect('loaded', () => {
background.disconnect(loadedSignalId);
loadedSignalId = null;
this.emit('loaded');
});
}
backgroundActor.connect('destroy', () => { backgroundActor.connect('destroy', () => {
if (changeSignalId) if (changeSignalId)
background.disconnect(changeSignalId); background.disconnect(changeSignalId);
if (loadedSignalId)
background.disconnect(loadedSignalId);
if (backgroundActor.loadedSignalId) if (backgroundActor.loadedSignalId)
background.disconnect(backgroundActor.loadedSignalId); background.disconnect(backgroundActor.loadedSignalId);
}); });

View 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 BoxPointer */ /* exported BoxPointer */
const { Clutter, GObject, St } = imports.gi; const { Clutter, GObject, Shell, St } = imports.gi;
const Main = imports.ui.main; const Main = imports.ui.main;
@@ -453,16 +453,15 @@ var BoxPointer = GObject.registerClass({
let alignment = this._arrowAlignment; let alignment = this._arrowAlignment;
let monitorIndex = Main.layoutManager.findIndexForActor(sourceActor); let monitorIndex = Main.layoutManager.findIndexForActor(sourceActor);
this._sourceExtents = sourceActor.get_transformed_extents(); this._sourceAllocation = Shell.util_get_transformed_allocation(sourceActor);
this._workArea = Main.layoutManager.getWorkAreaForMonitor(monitorIndex); this._workArea = Main.layoutManager.getWorkAreaForMonitor(monitorIndex);
// Position correctly relative to the sourceActor // Position correctly relative to the sourceActor
let sourceNode = sourceActor.get_theme_node(); let sourceNode = sourceActor.get_theme_node();
let sourceContentBox = sourceNode.get_content_box(sourceActor.get_allocation_box()); let sourceContentBox = sourceNode.get_content_box(sourceActor.get_allocation_box());
let sourceTopLeft = this._sourceExtents.get_top_left(); let sourceAllocation = this._sourceAllocation;
let sourceBottomRight = this._sourceExtents.get_bottom_right(); let sourceCenterX = sourceAllocation.x1 + sourceContentBox.x1 + (sourceContentBox.x2 - sourceContentBox.x1) * this._sourceAlignment;
let sourceCenterX = sourceTopLeft.x + sourceContentBox.x1 + (sourceContentBox.x2 - sourceContentBox.x1) * this._sourceAlignment; let sourceCenterY = sourceAllocation.y1 + sourceContentBox.y1 + (sourceContentBox.y2 - sourceContentBox.y1) * this._sourceAlignment;
let sourceCenterY = sourceTopLeft.y + sourceContentBox.y1 + (sourceContentBox.y2 - sourceContentBox.y1) * this._sourceAlignment;
let [, , natWidth, natHeight] = this.get_preferred_size(); let [, , natWidth, natHeight] = this.get_preferred_size();
// We also want to keep it onscreen, and separated from the // We also want to keep it onscreen, and separated from the
@@ -482,16 +481,16 @@ var BoxPointer = GObject.registerClass({
switch (this._arrowSide) { switch (this._arrowSide) {
case St.Side.TOP: case St.Side.TOP:
resY = sourceBottomRight.y + gap; resY = sourceAllocation.y2 + gap;
break; break;
case St.Side.BOTTOM: case St.Side.BOTTOM:
resY = sourceTopLeft.y - natHeight - gap; resY = sourceAllocation.y1 - natHeight - gap;
break; break;
case St.Side.LEFT: case St.Side.LEFT:
resX = sourceBottomRight.x + gap; resX = sourceAllocation.x2 + gap;
break; break;
case St.Side.RIGHT: case St.Side.RIGHT:
resX = sourceTopLeft.x - natWidth - gap; resX = sourceAllocation.x1 - natWidth - gap;
break; break;
} }
@@ -587,30 +586,29 @@ var BoxPointer = GObject.registerClass({
} }
_calculateArrowSide(arrowSide) { _calculateArrowSide(arrowSide) {
let sourceTopLeft = this._sourceExtents.get_top_left(); let sourceAllocation = this._sourceAllocation;
let sourceBottomRight = this._sourceExtents.get_bottom_right();
let [, , boxWidth, boxHeight] = this.get_preferred_size(); let [, , boxWidth, boxHeight] = this.get_preferred_size();
let workarea = this._workArea; let workarea = this._workArea;
switch (arrowSide) { switch (arrowSide) {
case St.Side.TOP: case St.Side.TOP:
if (sourceBottomRight.y + boxHeight > workarea.y + workarea.height && if (sourceAllocation.y2 + boxHeight > workarea.y + workarea.height &&
boxHeight < sourceTopLeft.y - workarea.y) boxHeight < sourceAllocation.y1 - workarea.y)
return St.Side.BOTTOM; return St.Side.BOTTOM;
break; break;
case St.Side.BOTTOM: case St.Side.BOTTOM:
if (sourceTopLeft.y - boxHeight < workarea.y && if (sourceAllocation.y1 - boxHeight < workarea.y &&
boxHeight < workarea.y + workarea.height - sourceBottomRight.y) boxHeight < workarea.y + workarea.height - sourceAllocation.y2)
return St.Side.TOP; return St.Side.TOP;
break; break;
case St.Side.LEFT: case St.Side.LEFT:
if (sourceBottomRight.x + boxWidth > workarea.x + workarea.width && if (sourceAllocation.x2 + boxWidth > workarea.x + workarea.width &&
boxWidth < sourceTopLeft.x - workarea.x) boxWidth < sourceAllocation.x1 - workarea.x)
return St.Side.RIGHT; return St.Side.RIGHT;
break; break;
case St.Side.RIGHT: case St.Side.RIGHT:
if (sourceTopLeft.x - boxWidth < workarea.x && if (sourceAllocation.x1 - boxWidth < workarea.x &&
boxWidth < workarea.x + workarea.width - sourceBottomRight.x) boxWidth < workarea.x + workarea.width - sourceAllocation.x2)
return St.Side.LEFT; return St.Side.LEFT;
break; break;
} }

View File

@@ -784,7 +784,6 @@ class DateMenuButton extends PanelMenu.Button {
this._clockDisplay = new St.Label({ style_class: 'clock' }); this._clockDisplay = new St.Label({ style_class: 'clock' });
this._clockDisplay.clutter_text.y_align = Clutter.ActorAlign.CENTER; this._clockDisplay.clutter_text.y_align = Clutter.ActorAlign.CENTER;
this._clockDisplay.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
this._indicator = new MessagesIndicator(); this._indicator = new MessagesIndicator();

View 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 Dialog, MessageDialogContent, ListSection, ListSectionItem */ /* exported Dialog, MessageDialogContent, ListSection, ListSectionItem */
const { Clutter, GLib, GObject, Meta, Pango, St } = imports.gi; const { Clutter, GObject, Meta, Pango, St } = imports.gi;
function _setLabel(label, value) { function _setLabel(label, value) {
label.set({ label.set({
@@ -221,16 +221,13 @@ var MessageDialogContent = GObject.registerClass({
this._updateTitleStyleLater = Meta.later_add(Meta.LaterType.BEFORE_REDRAW, () => { this._updateTitleStyleLater = Meta.later_add(Meta.LaterType.BEFORE_REDRAW, () => {
this._updateTitleStyleLater = 0; this._updateTitleStyleLater = 0;
this._title.add_style_class_name('leightweight'); this._title.add_style_class_name('leightweight');
return GLib.SOURCE_REMOVE; return false;
}); });
} }
} }
set title(title) { set title(title) {
if (this._title.text === title)
return;
_setLabel(this._title, title); _setLabel(this._title, title);
this._title.remove_style_class_name('leightweight'); this._title.remove_style_class_name('leightweight');
@@ -240,9 +237,6 @@ var MessageDialogContent = GObject.registerClass({
} }
set description(description) { set description(description) {
if (this._description.text === description)
return;
_setLabel(this._description, description); _setLabel(this._description, description);
this.notify('description'); this.notify('description');
} }

View File

@@ -388,16 +388,17 @@ var _Draggable = class _Draggable {
const [, newAllocatedWidth] = this._dragActor.get_preferred_width(-1); const [, newAllocatedWidth] = this._dragActor.get_preferred_width(-1);
const [, newAllocatedHeight] = this._dragActor.get_preferred_height(-1); const [, newAllocatedHeight] = this._dragActor.get_preferred_height(-1);
const transformedExtents = this._dragActor.get_transformed_extents(); const transformedAllocation =
Shell.util_get_transformed_allocation(this._dragActor);
// Set the actor's scale such that it will keep the same // Set the actor's scale such that it will keep the same
// transformed size when it's reparented to the uiGroup // transformed size when it's reparented to the uiGroup
this._dragActor.set_scale( this._dragActor.set_scale(
transformedExtents.get_width() / newAllocatedWidth, transformedAllocation.get_width() / newAllocatedWidth,
transformedExtents.get_height() / newAllocatedHeight); transformedAllocation.get_height() / newAllocatedHeight);
this._dragOffsetX = transformedExtents.origin.x - this._dragStartX; this._dragOffsetX = transformedAllocation.x1 - this._dragStartX;
this._dragOffsetY = transformedExtents.origin.y - this._dragStartY; this._dragOffsetY = transformedAllocation.y1 - this._dragStartY;
this._dragOrigParent.remove_actor(this._dragActor); this._dragOrigParent.remove_actor(this._dragActor);
Main.uiGroup.add_child(this._dragActor); Main.uiGroup.add_child(this._dragActor);

View File

@@ -18,7 +18,7 @@
*/ */
const { AccountsService, Clutter, Gio, const { AccountsService, Clutter, Gio,
GLib, GObject, Pango, Polkit, Shell, St, UPowerGlib: UPower } = imports.gi; GLib, GObject, Pango, Polkit, Shell, St } = imports.gi;
const CheckBox = imports.ui.checkBox; const CheckBox = imports.ui.checkBox;
const Dialog = imports.ui.dialog; const Dialog = imports.ui.dialog;
@@ -31,30 +31,24 @@ const { loadInterfaceXML } = imports.misc.fileUtils;
const _ITEM_ICON_SIZE = 64; const _ITEM_ICON_SIZE = 64;
const LOW_BATTERY_THRESHOLD = 30;
const EndSessionDialogIface = loadInterfaceXML('org.gnome.SessionManager.EndSessionDialog'); const EndSessionDialogIface = loadInterfaceXML('org.gnome.SessionManager.EndSessionDialog');
const logoutDialogContent = { const logoutDialogContent = {
subjectWithUser: C_("title", "Log Out %s"), subjectWithUser: C_("title", "Log Out %s"),
subject: C_("title", "Log Out"), subject: C_("title", "Log Out"),
descriptionWithUser(user, seconds) { descriptionWithUser(user, seconds) {
return ngettext( return ngettext("%s will be logged out automatically in %d second.",
'%s will be logged out automatically in %d second.', "%s will be logged out automatically in %d seconds.",
'%s will be logged out automatically in %d seconds.', seconds).format(user, seconds);
seconds).format(user, seconds);
}, },
description(seconds) { description(seconds) {
return ngettext( return ngettext("You will be logged out automatically in %d second.",
'You will be logged out automatically in %d second.', "You will be logged out automatically in %d seconds.",
'You will be logged out automatically in %d seconds.', seconds).format(seconds);
seconds).format(seconds);
}, },
showBatteryWarning: false, showBatteryWarning: false,
confirmButtons: [{ confirmButtons: [{ signal: 'ConfirmedLogout',
signal: 'ConfirmedLogout', label: C_("button", "Log Out") }],
label: C_('button', 'Log Out'),
}],
showOtherSessions: false, showOtherSessions: false,
}; };
@@ -62,36 +56,30 @@ const shutdownDialogContent = {
subject: C_("title", "Power Off"), subject: C_("title", "Power Off"),
subjectWithUpdates: C_("title", "Install Updates & Power Off"), subjectWithUpdates: C_("title", "Install Updates & Power Off"),
description(seconds) { description(seconds) {
return ngettext( return ngettext("The system will power off automatically in %d second.",
'The system will power off automatically in %d second.', "The system will power off automatically in %d seconds.",
'The system will power off automatically in %d seconds.', seconds).format(seconds);
seconds).format(seconds);
}, },
checkBoxText: C_("checkbox", "Install pending software updates"), checkBoxText: C_("checkbox", "Install pending software updates"),
showBatteryWarning: true, showBatteryWarning: true,
confirmButtons: [{ confirmButtons: [{ signal: 'ConfirmedReboot',
signal: 'ConfirmedShutdown', label: C_("button", "Restart") },
label: C_('button', 'Power Off'), { signal: 'ConfirmedShutdown',
}], label: C_("button", "Power Off") }],
iconName: 'system-shutdown-symbolic', iconName: 'system-shutdown-symbolic',
showOtherSessions: true, showOtherSessions: true,
}; };
const restartDialogContent = { const restartDialogContent = {
subject: C_("title", "Restart"), subject: C_("title", "Restart"),
subjectWithUpdates: C_('title', 'Install Updates & Restart'),
description(seconds) { description(seconds) {
return ngettext( return ngettext("The system will restart automatically in %d second.",
'The system will restart automatically in %d second.', "The system will restart automatically in %d seconds.",
'The system will restart automatically in %d seconds.', seconds).format(seconds);
seconds).format(seconds);
}, },
checkBoxText: C_('checkbox', 'Install pending software updates'), showBatteryWarning: false,
showBatteryWarning: true, confirmButtons: [{ signal: 'ConfirmedReboot',
confirmButtons: [{ label: C_("button", "Restart") }],
signal: 'ConfirmedReboot',
label: C_('button', 'Restart'),
}],
iconName: 'view-refresh-symbolic', iconName: 'view-refresh-symbolic',
showOtherSessions: true, showOtherSessions: true,
}; };
@@ -100,16 +88,13 @@ const restartUpdateDialogContent = {
subject: C_("title", "Restart & Install Updates"), subject: C_("title", "Restart & Install Updates"),
description(seconds) { description(seconds) {
return ngettext( return ngettext("The system will automatically restart and install updates in %d second.",
'The system will automatically restart and install updates in %d second.', "The system will automatically restart and install updates in %d seconds.",
'The system will automatically restart and install updates in %d seconds.', seconds).format(seconds);
seconds).format(seconds);
}, },
showBatteryWarning: true, showBatteryWarning: true,
confirmButtons: [{ confirmButtons: [{ signal: 'ConfirmedReboot',
signal: 'ConfirmedReboot', label: C_("button", "Restart &amp; Install") }],
label: C_('button', 'Restart &amp; Install'),
}],
unusedFutureButtonForTranslation: C_("button", "Install &amp; Power Off"), unusedFutureButtonForTranslation: C_("button", "Install &amp; Power Off"),
unusedFutureCheckBoxForTranslation: C_("checkbox", "Power off after updates are installed"), unusedFutureCheckBoxForTranslation: C_("checkbox", "Power off after updates are installed"),
iconName: 'view-refresh-symbolic', iconName: 'view-refresh-symbolic',
@@ -127,10 +112,8 @@ const restartUpgradeDialogContent = {
}, },
disableTimer: true, disableTimer: true,
showBatteryWarning: false, showBatteryWarning: false,
confirmButtons: [{ confirmButtons: [{ signal: 'ConfirmedReboot',
signal: 'ConfirmedReboot', label: C_("button", "Restart &amp; Install") }],
label: C_('button', 'Restart &amp; Install'),
}],
iconName: 'view-refresh-symbolic', iconName: 'view-refresh-symbolic',
showOtherSessions: true, showOtherSessions: true,
}; };
@@ -159,7 +142,7 @@ const LogindSession = Gio.DBusProxy.makeProxyWrapper(LogindSessionIface);
const PkOfflineIface = loadInterfaceXML('org.freedesktop.PackageKit.Offline'); const PkOfflineIface = loadInterfaceXML('org.freedesktop.PackageKit.Offline');
const PkOfflineProxy = Gio.DBusProxy.makeProxyWrapper(PkOfflineIface); const PkOfflineProxy = Gio.DBusProxy.makeProxyWrapper(PkOfflineIface);
const UPowerIface = loadInterfaceXML('org.freedesktop.UPower.Device'); const UPowerIface = loadInterfaceXML('org.freedesktop.UPower');
const UPowerProxy = Gio.DBusProxy.makeProxyWrapper(UPowerIface); const UPowerProxy = Gio.DBusProxy.makeProxyWrapper(UPowerIface);
function findAppFromInhibitor(inhibitor) { function findAppFromInhibitor(inhibitor) {
@@ -230,11 +213,6 @@ class EndSessionDialog extends ModalDialog.ModalDialog {
destroyOnClose: false }); destroyOnClose: false });
this._loginManager = LoginManager.getLoginManager(); this._loginManager = LoginManager.getLoginManager();
this._loginManager.canRebootToBootLoaderMenu(
(canRebootToBootLoaderMenu, unusedNeedsAuth) => {
this._canRebootToBootLoaderMenu = canRebootToBootLoaderMenu;
});
this._userManager = AccountsService.UserManager.get_default(); this._userManager = AccountsService.UserManager.get_default();
this._user = this._userManager.get_user(GLib.get_user_name()); this._user = this._userManager.get_user(GLib.get_user_name());
this._updatesPermission = null; this._updatesPermission = null;
@@ -246,7 +224,7 @@ class EndSessionDialog extends ModalDialog.ModalDialog {
this._powerProxy = new UPowerProxy(Gio.DBus.system, this._powerProxy = new UPowerProxy(Gio.DBus.system,
'org.freedesktop.UPower', 'org.freedesktop.UPower',
'/org/freedesktop/UPower/devices/DisplayDevice', '/org/freedesktop/UPower',
(proxy, error) => { (proxy, error) => {
if (error) { if (error) {
log(error.message); log(error.message);
@@ -261,9 +239,6 @@ class EndSessionDialog extends ModalDialog.ModalDialog {
this._totalSecondsToStayOpen = 0; this._totalSecondsToStayOpen = 0;
this._applications = []; this._applications = [];
this._sessions = []; this._sessions = [];
this._capturedEventId = 0;
this._rebootButton = null;
this._rebootButtonAlt = null;
this.connect('destroy', this.connect('destroy',
this._onDestroy.bind(this)); this._onDestroy.bind(this));
@@ -281,7 +256,7 @@ class EndSessionDialog extends ModalDialog.ModalDialog {
this._batteryWarning = new St.Label({ this._batteryWarning = new St.Label({
style_class: 'end-session-dialog-battery-warning', style_class: 'end-session-dialog-battery-warning',
text: _('Low battery power: please plug in before installing updates.'), text: _('Running on battery power: Please plug in before installing updates.'),
}); });
this._batteryWarning.clutter_text.ellipsize = Pango.EllipsizeMode.NONE; this._batteryWarning.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
this._batteryWarning.clutter_text.line_wrap = true; this._batteryWarning.clutter_text.line_wrap = true;
@@ -331,32 +306,6 @@ class EndSessionDialog extends ModalDialog.ModalDialog {
this._user.disconnect(this._userChangedId); this._user.disconnect(this._userChangedId);
} }
_isDischargingBattery() {
return this._powerProxy.IsPresent &&
this._powerProxy.State !== UPower.DeviceState.CHARGING &&
this._powerProxy.State !== UPower.DeviceState.FULLY_CHARGED;
}
_isBatteryLow() {
return this._isDischargingBattery() && this._powerProxy.Percentage < LOW_BATTERY_THRESHOLD;
}
_shouldShowLowBatteryWarning(dialogContent) {
if (!dialogContent.showBatteryWarning)
return false;
if (!this._isBatteryLow())
return false;
if (this._checkBox.checked)
return true;
// Show the warning if updates have already been triggered, but
// the user doesn't have enough permissions to cancel them.
let updatesAllowed = this._updatesPermission && this._updatesPermission.allowed;
return this._updateInfo.UpdatePrepared && this._updateInfo.UpdateTriggered && !updatesAllowed;
}
_sync() { _sync() {
let open = this.state == ModalDialog.State.OPENING || this.state == ModalDialog.State.OPENED; let open = this.state == ModalDialog.State.OPENING || this.state == ModalDialog.State.OPENED;
if (!open) if (!open)
@@ -370,7 +319,10 @@ class EndSessionDialog extends ModalDialog.ModalDialog {
if (dialogContent.subjectWithUpdates && this._checkBox.checked) if (dialogContent.subjectWithUpdates && this._checkBox.checked)
subject = dialogContent.subjectWithUpdates; subject = dialogContent.subjectWithUpdates;
this._batteryWarning.visible = this._shouldShowLowBatteryWarning(dialogContent); if (dialogContent.showBatteryWarning) {
this._batteryWarning.visible =
this._powerProxy.OnBattery && this._checkBox.checked;
}
let description; let description;
let displayTime = _roundSecondsToInterval(this._totalSecondsToStayOpen, let displayTime = _roundSecondsToInterval(this._totalSecondsToStayOpen,
@@ -411,38 +363,16 @@ class EndSessionDialog extends ModalDialog.ModalDialog {
this._sessionSection.visible = hasSessions; this._sessionSection.visible = hasSessions;
} }
_onCapturedEvent(actor, event) {
let altEnabled = false;
let type = event.type();
if (type !== Clutter.EventType.KEY_PRESS && type !== Clutter.EventType.KEY_RELEASE)
return Clutter.EVENT_PROPAGATE;
let key = event.get_key_symbol();
if (key !== Clutter.KEY_Alt_L && key !== Clutter.KEY_Alt_R)
return Clutter.EVENT_PROPAGATE;
if (type === Clutter.EventType.KEY_PRESS)
altEnabled = true;
this._rebootButton.visible = !altEnabled;
this._rebootButtonAlt.visible = altEnabled;
return Clutter.EVENT_PROPAGATE;
}
_updateButtons() { _updateButtons() {
this.clearButtons();
this.addButton({ action: this.cancel.bind(this),
label: _("Cancel"),
key: Clutter.KEY_Escape });
let dialogContent = DialogContent[this._type]; let dialogContent = DialogContent[this._type];
let buttons = [{ action: this.cancel.bind(this),
label: _("Cancel"),
key: Clutter.KEY_Escape }];
for (let i = 0; i < dialogContent.confirmButtons.length; i++) { for (let i = 0; i < dialogContent.confirmButtons.length; i++) {
let signal = dialogContent.confirmButtons[i].signal; let signal = dialogContent.confirmButtons[i].signal;
let label = dialogContent.confirmButtons[i].label; let label = dialogContent.confirmButtons[i].label;
let button = this.addButton({ buttons.push({
action: () => { action: () => {
this.close(true); this.close(true);
let signalId = this.connect('closed', () => { let signalId = this.connect('closed', () => {
@@ -452,34 +382,9 @@ class EndSessionDialog extends ModalDialog.ModalDialog {
}, },
label, label,
}); });
// Add Alt "Boot Options" option to the Reboot button
if (this._canRebootToBootLoaderMenu && signal === 'ConfirmedReboot') {
this._rebootButton = button;
this._rebootButtonAlt = this.addButton({
action: () => {
this.close(true);
let signalId = this.connect('closed', () => {
this.disconnect(signalId);
this._confirmRebootToBootLoaderMenu();
});
},
label: C_('button', 'Boot Options'),
});
this._rebootButtonAlt.visible = false;
this._capturedEventId = global.stage.connect('captured-event',
this._onCapturedEvent.bind(this));
}
} }
}
_stopAltCapture() { this.setButtons(buttons);
if (this._capturedEventId > 0) {
global.stage.disconnect(this._capturedEventId);
this._capturedEventId = 0;
}
this._rebootButton = null;
this._rebootButtonAlt = null;
} }
close(skipSignal) { close(skipSignal) {
@@ -491,21 +396,14 @@ class EndSessionDialog extends ModalDialog.ModalDialog {
cancel() { cancel() {
this._stopTimer(); this._stopTimer();
this._stopAltCapture();
this._dbusImpl.emit_signal('Canceled', null); this._dbusImpl.emit_signal('Canceled', null);
this.close(); this.close();
} }
_confirmRebootToBootLoaderMenu() {
this._loginManager.setRebootToBootLoaderMenu();
this._confirm('ConfirmedReboot');
}
_confirm(signal) { _confirm(signal) {
let callback = () => { let callback = () => {
this._fadeOutDialog(); this._fadeOutDialog();
this._stopTimer(); this._stopTimer();
this._stopAltCapture();
this._dbusImpl.emit_signal(signal, null); this._dbusImpl.emit_signal(signal, null);
}; };
@@ -773,17 +671,19 @@ class EndSessionDialog extends ModalDialog.ModalDialog {
if (dialogContent.showOtherSessions) if (dialogContent.showOtherSessions)
this._loadSessions(); this._loadSessions();
let updateTriggered = this._updateInfo.UpdateTriggered;
let updatePrepared = this._updateInfo.UpdatePrepared;
let updatesAllowed = this._updatesPermission && this._updatesPermission.allowed; let updatesAllowed = this._updatesPermission && this._updatesPermission.allowed;
_setCheckBoxLabel(this._checkBox, dialogContent.checkBoxText || ''); _setCheckBoxLabel(this._checkBox, dialogContent.checkBoxText || '');
this._checkBox.visible = dialogContent.checkBoxText && this._updateInfo.UpdatePrepared && updatesAllowed; this._checkBox.visible = dialogContent.checkBoxText && updatePrepared && updatesAllowed;
this._checkBox.checked = this._checkBox.visible;
if (this._type === DialogType.UPGRADE_RESTART) // We show the warning either together with the checkbox, or when
this._checkBox.checked = this._checkBox.visible && this._updateInfo.UpdateTriggered && !this._isDischargingBattery(); // updates have already been triggered, but the user doesn't have
else // enough permissions to cancel them.
this._checkBox.checked = this._checkBox.visible && !this._isBatteryLow(); this._batteryWarning.visible = dialogContent.showBatteryWarning &&
(this._checkBox.visible || updatePrepared && updateTriggered && !updatesAllowed);
this._batteryWarning.visible = this._shouldShowLowBatteryWarning(dialogContent);
this._updateButtons(); this._updateButtons();

View File

@@ -134,14 +134,7 @@ function _easeActor(actor, params) {
actor.set_easing_mode(params.mode); actor.set_easing_mode(params.mode);
delete params.mode; delete params.mode;
const prepare = () => { let cleanup = () => Meta.enable_unredirect_for_display(global.display);
Meta.disable_unredirect_for_display(global.display);
global.begin_work();
};
const cleanup = () => {
Meta.enable_unredirect_for_display(global.display);
global.end_work();
};
let callback = _makeEaseCallback(params, cleanup); let callback = _makeEaseCallback(params, cleanup);
// cancel overwritten transitions // cancel overwritten transitions
@@ -156,9 +149,9 @@ function _easeActor(actor, params) {
.find(t => t !== null); .find(t => t !== null);
if (transition && transition.delay) if (transition && transition.delay)
transition.connect('started', () => prepare()); transition.connect('started', () => Meta.disable_unredirect_for_display(global.display));
else else
prepare(); Meta.disable_unredirect_for_display(global.display);
if (transition) { if (transition) {
transition.set({ repeatCount, autoReverse }); transition.set({ repeatCount, autoReverse });
@@ -198,14 +191,7 @@ function _easeActorProperty(actor, propName, target, params) {
if (actor instanceof Clutter.Actor && !actor.mapped) if (actor instanceof Clutter.Actor && !actor.mapped)
duration = 0; duration = 0;
const prepare = () => { let cleanup = () => Meta.enable_unredirect_for_display(global.display);
Meta.disable_unredirect_for_display(global.display);
global.begin_work();
};
const cleanup = () => {
Meta.enable_unredirect_for_display(global.display);
global.end_work();
};
let callback = _makeEaseCallback(params, cleanup); let callback = _makeEaseCallback(params, cleanup);
// cancel overwritten transition // cancel overwritten transition
@@ -217,7 +203,7 @@ function _easeActorProperty(actor, propName, target, params) {
if (!isReversed) if (!isReversed)
obj[prop] = target; obj[prop] = target;
prepare(); Meta.disable_unredirect_for_display(global.display);
callback(true); callback(true);
return; return;
@@ -236,9 +222,9 @@ function _easeActorProperty(actor, propName, target, params) {
transition.set_to(target); transition.set_to(target);
if (transition.delay) if (transition.delay)
transition.connect('started', () => prepare()); transition.connect('started', () => Meta.disable_unredirect_for_display(global.display));
else else
prepare(); Meta.disable_unredirect_for_display(global.display);
transition.connect('stopped', (t, finished) => callback(finished)); transition.connect('stopped', (t, finished) => callback(finished));
} }

View File

@@ -139,9 +139,7 @@ function checkForUpdates() {
return; return;
if (extension.hasUpdate) if (extension.hasUpdate)
return; return;
metadatas[uuid] = { metadatas[uuid] = extension.metadata;
version: extension.metadata.version,
};
}); });
if (Object.keys(metadatas).length === 0) if (Object.keys(metadatas).length === 0)

View File

@@ -31,7 +31,7 @@ var IconSize = {
var APPICON_ANIMATION_OUT_SCALE = 3; var APPICON_ANIMATION_OUT_SCALE = 3;
var APPICON_ANIMATION_OUT_TIME = 250; var APPICON_ANIMATION_OUT_TIME = 250;
const ICON_POSITION_DELAY = 10; const ICON_POSITION_DELAY = 25;
const defaultGridModes = [ const defaultGridModes = [
{ {
@@ -52,17 +52,6 @@ const defaultGridModes = [
}, },
]; ];
var LEFT_DIVIDER_LEEWAY = 20;
var RIGHT_DIVIDER_LEEWAY = 20;
var DragLocation = {
INVALID: 0,
START_EDGE: 1,
ON_ICON: 2,
END_EDGE: 3,
EMPTY_SPACE: 4,
};
var BaseIcon = GObject.registerClass( var BaseIcon = GObject.registerClass(
class BaseIcon extends St.Bin { class BaseIcon extends St.Bin {
_init(label, params) { _init(label, params) {
@@ -957,99 +946,6 @@ var IconGridLayout = GObject.registerClass({
} }
} }
/**
* getDropTarget:
* @param {int} x: position of the horizontal axis
* @param {int} y: position of the vertical axis
*
* Retrieves the item located at (@x, @y), as well as the drag location.
* Both @x and @y are relative to the grid.
*
* @returns {[Clutter.Actor, DragLocation]} the item and drag location
* under (@x, @y)
*/
getDropTarget(x, y) {
const childSize = this._getChildrenMaxSize();
const [leftEmptySpace, topEmptySpace, hSpacing, vSpacing] =
this._calculateSpacing(childSize);
const isRtl =
Clutter.get_default_text_direction() === Clutter.TextDirection.RTL;
let page = this._orientation === Clutter.Orientation.VERTICAL
? Math.floor(y / this._pageHeight)
: Math.floor(x / this._pageWidth);
// Out of bounds
if (page >= this._pages.length)
return [null, DragLocation.INVALID];
if (isRtl && this._orientation === Clutter.Orientation.HORIZONTAL)
page = swap(page, this._pages.length);
// Page-relative coordinates from now on
x %= this._pageWidth;
y %= this._pageHeight;
if (x < leftEmptySpace || y < topEmptySpace)
return [null, DragLocation.INVALID];
const gridWidth =
childSize * this._columnsPerPage +
hSpacing * (this._columnsPerPage - 1);
const gridHeight =
childSize * this._rowsPerPage +
vSpacing * (this._rowsPerPage - 1);
if (x > leftEmptySpace + gridWidth || y > topEmptySpace + gridHeight)
return [null, DragLocation.INVALID];
const halfHSpacing = hSpacing / 2;
const halfVSpacing = vSpacing / 2;
const visibleItems = this._getVisibleChildrenForPage(page);
for (const item of visibleItems) {
const childBox = item.allocation.copy();
// Page offset
switch (this._orientation) {
case Clutter.Orientation.HORIZONTAL:
childBox.set_origin(childBox.x1 % this._pageWidth, childBox.y1);
break;
case Clutter.Orientation.VERTICAL:
childBox.set_origin(childBox.x1, childBox.y1 % this._pageHeight);
break;
}
// Outside the icon boundaries
if (x < childBox.x1 - halfHSpacing ||
x > childBox.x2 + halfHSpacing ||
y < childBox.y1 - halfVSpacing ||
y > childBox.y2 + halfVSpacing)
continue;
let dragLocation;
if (x < childBox.x1 + LEFT_DIVIDER_LEEWAY)
dragLocation = DragLocation.START_EDGE;
else if (x > childBox.x2 - RIGHT_DIVIDER_LEEWAY)
dragLocation = DragLocation.END_EDGE;
else
dragLocation = DragLocation.ON_ICON;
if (isRtl) {
if (dragLocation === DragLocation.START_EDGE)
dragLocation = DragLocation.END_EDGE;
else if (dragLocation === DragLocation.END_EDGE)
dragLocation = DragLocation.START_EDGE;
}
return [item, dragLocation];
}
return [null, DragLocation.EMPTY_SPACE];
}
// eslint-disable-next-line camelcase // eslint-disable-next-line camelcase
get allow_incomplete_pages() { get allow_incomplete_pages() {
return this._allowIncompletePages; return this._allowIncompletePages;
@@ -1663,11 +1559,6 @@ var IconGrid = GObject.registerClass({
this.queue_relayout(); this.queue_relayout();
} }
getDropTarget(x, y) {
const layoutManager = this.layout_manager;
return layoutManager.getDropTarget(x, y, this._currentPage);
}
get itemsPerPage() { get itemsPerPage() {
const layoutManager = this.layout_manager; const layoutManager = this.layout_manager;
return layoutManager.rows_per_page * layoutManager.columns_per_page; return layoutManager.rows_per_page * layoutManager.columns_per_page;

View File

@@ -1,5 +1,5 @@
/* exported InhibitShortcutsDialog */ /* exported InhibitShortcutsDialog */
const { Clutter, Gio, GLib, GObject, Gtk, Meta, Pango, Shell, St } = imports.gi; const { Clutter, Gio, GLib, GObject, Gtk, Meta, Shell, St } = imports.gi;
const Dialog = imports.ui.dialog; const Dialog = imports.ui.dialog;
const ModalDialog = imports.ui.modalDialog; const ModalDialog = imports.ui.modalDialog;
@@ -7,7 +7,7 @@ const PermissionStore = imports.misc.permissionStore;
const WAYLAND_KEYBINDINGS_SCHEMA = 'org.gnome.mutter.wayland.keybindings'; const WAYLAND_KEYBINDINGS_SCHEMA = 'org.gnome.mutter.wayland.keybindings';
const APP_ALLOWLIST = ['gnome-control-center.desktop']; const APP_WHITELIST = ['gnome-control-center.desktop'];
const APP_PERMISSIONS_TABLE = 'gnome'; const APP_PERMISSIONS_TABLE = 'gnome';
const APP_PERMISSIONS_ID = 'shortcuts-inhibitor'; const APP_PERMISSIONS_ID = 'shortcuts-inhibitor';
const GRANTED = 'GRANTED'; const GRANTED = 'GRANTED';
@@ -90,8 +90,6 @@ var InhibitShortcutsDialog = GObject.registerClass({
text: _('You can restore shortcuts by pressing %s.').format(restoreAccel), text: _('You can restore shortcuts by pressing %s.').format(restoreAccel),
style_class: 'message-dialog-description', style_class: 'message-dialog-description',
}); });
restoreLabel.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
restoreLabel.clutter_text.line_wrap = true;
content.add_child(restoreLabel); content.add_child(restoreLabel);
} }
@@ -118,7 +116,7 @@ var InhibitShortcutsDialog = GObject.registerClass({
} }
vfunc_show() { vfunc_show() {
if (this._app && APP_ALLOWLIST.includes(this._app.get_id())) { if (this._app && APP_WHITELIST.includes(this._app.get_id())) {
this._emitResponse(DialogResponse.ALLOW); this._emitResponse(DialogResponse.ALLOW);
return; return;
} }

View File

@@ -42,7 +42,7 @@ const defaultKeysPost = [
[[{ width: 1.5, keyval: Clutter.KEY_BackSpace, icon: 'edit-clear-symbolic' }], [[{ width: 1.5, keyval: Clutter.KEY_BackSpace, icon: 'edit-clear-symbolic' }],
[{ width: 2, keyval: Clutter.KEY_Return, extraClassName: 'enter-key', icon: 'keyboard-enter-symbolic' }], [{ width: 2, keyval: Clutter.KEY_Return, extraClassName: 'enter-key', icon: 'keyboard-enter-symbolic' }],
[{ label: '=/<', width: 3, level: 3, right: true }], [{ label: '=/<', width: 3, level: 3, right: true }],
[{ action: 'emoji', icon: 'face-smile-symbolic' }, { action: 'languageMenu', extraClassName: 'layout-key', icon: 'keyboard-layout-filled-symbolic' }, { action: 'hide', extraClassName: 'hide-key', icon: 'go-down-symbolic' }]], [{ action: 'emoji', icon: 'face-smile-symbolic' }, { action: 'languageMenu', extraClassName: 'layout-key' }, { action: 'hide', extraClassName: 'hide-key' }]],
[[{ width: 1.5, keyval: Clutter.KEY_BackSpace, icon: 'edit-clear-symbolic' }], [[{ width: 1.5, keyval: Clutter.KEY_BackSpace, icon: 'edit-clear-symbolic' }],
[{ width: 2, keyval: Clutter.KEY_Return, extraClassName: 'enter-key', icon: 'keyboard-enter-symbolic' }], [{ width: 2, keyval: Clutter.KEY_Return, extraClassName: 'enter-key', icon: 'keyboard-enter-symbolic' }],
[{ label: '?123', width: 3, level: 2, right: true }], [{ label: '?123', width: 3, level: 2, right: true }],
@@ -61,24 +61,6 @@ class AspectContainer extends St.Widget {
this.queue_relayout(); this.queue_relayout();
} }
vfunc_get_preferred_width(forHeight) {
let [min, nat] = super.vfunc_get_preferred_width(forHeight);
if (forHeight > 0)
nat = forHeight * this._ratio;
return [min, nat];
}
vfunc_get_preferred_height(forWidth) {
let [min, nat] = super.vfunc_get_preferred_height(forWidth);
if (forWidth > 0)
nat = forWidth / this._ratio;
return [min, nat];
}
vfunc_allocate(box) { vfunc_allocate(box) {
if (box.get_width() > 0 && box.get_height() > 0) { if (box.get_width() > 0 && box.get_height() > 0) {
let sizeRatio = box.get_width() / box.get_height(); let sizeRatio = box.get_width() / box.get_height();
@@ -1091,8 +1073,8 @@ var Keypad = GObject.registerClass({
{ label: '8', keyval: Clutter.KEY_8, left: 1, top: 2 }, { label: '8', keyval: Clutter.KEY_8, left: 1, top: 2 },
{ label: '9', keyval: Clutter.KEY_9, left: 2, top: 2 }, { label: '9', keyval: Clutter.KEY_9, left: 2, top: 2 },
{ label: '0', keyval: Clutter.KEY_0, left: 1, top: 3 }, { label: '0', keyval: Clutter.KEY_0, left: 1, top: 3 },
{ keyval: Clutter.KEY_BackSpace, icon: 'edit-clear-symbolic', left: 3, top: 0 }, { label: '⌫', keyval: Clutter.KEY_BackSpace, left: 3, top: 0 },
{ keyval: Clutter.KEY_Return, extraClassName: 'enter-key', icon: 'keyboard-enter-symbolic', left: 3, top: 1, height: 2 }, { keyval: Clutter.KEY_Return, extraClassName: 'enter-key', left: 3, top: 1, height: 2 },
]; ];
super._init({ super._init({
@@ -1109,7 +1091,7 @@ var Keypad = GObject.registerClass({
for (let i = 0; i < keys.length; i++) { for (let i = 0; i < keys.length; i++) {
let cur = keys[i]; let cur = keys[i];
let key = new Key(cur.label || "", [], cur.icon); let key = new Key(cur.label || "", []);
if (keys[i].extraClassName) if (keys[i].extraClassName)
key.keyButton.add_style_class_name(cur.extraClassName); key.keyButton.add_style_class_name(cur.extraClassName);
@@ -1626,9 +1608,7 @@ class Keyboard extends St.BoxLayout {
* we allow the OSK being smaller than 1/3rd of the monitor height * we allow the OSK being smaller than 1/3rd of the monitor height
* there. * there.
*/ */
const forWidth = this.get_theme_node().adjust_for_width(monitor.width); this.height = Math.min(maxHeight, this.get_preferred_height(monitor.width));
const [, natHeight] = this.get_preferred_height(forWidth);
this.height = Math.min(maxHeight, natHeight);
} }
} }

View File

@@ -6,6 +6,7 @@ const Signals = imports.signals;
const Background = imports.ui.background; const Background = imports.ui.background;
const BackgroundMenu = imports.ui.backgroundMenu; const BackgroundMenu = imports.ui.backgroundMenu;
const LoginManager = imports.misc.loginManager;
const DND = imports.ui.dnd; const DND = imports.ui.dnd;
const Main = imports.ui.main; const Main = imports.ui.main;
@@ -294,6 +295,18 @@ var LayoutManager = GObject.registerClass({
monitorManager.connect('monitors-changed', monitorManager.connect('monitors-changed',
this._monitorsChanged.bind(this)); this._monitorsChanged.bind(this));
this._monitorsChanged(); this._monitorsChanged();
// NVIDIA drivers don't preserve FBO contents across
// suspend/resume, see
// https://bugzilla.gnome.org/show_bug.cgi?id=739178
if (Shell.util_need_background_refresh()) {
LoginManager.getLoginManager().connect('prepare-for-sleep',
(lm, suspending) => {
if (suspending)
return;
Meta.Background.refresh_all();
});
}
} }
// This is called by Main after everything else is constructed // This is called by Main after everything else is constructed
@@ -457,15 +470,6 @@ var LayoutManager = GObject.registerClass({
} }
} }
_waitLoaded(bgManager) {
return new Promise(resolve => {
const id = bgManager.connect('loaded', () => {
bgManager.disconnect(id);
resolve();
});
});
}
_updateBackgrounds() { _updateBackgrounds() {
for (let i = 0; i < this._bgManagers.length; i++) for (let i = 0; i < this._bgManagers.length; i++)
this._bgManagers[i].destroy(); this._bgManagers[i].destroy();
@@ -473,7 +477,7 @@ var LayoutManager = GObject.registerClass({
this._bgManagers = []; this._bgManagers = [];
if (Main.sessionMode.isGreeter) if (Main.sessionMode.isGreeter)
return Promise.resolve(); return;
for (let i = 0; i < this.monitors.length; i++) { for (let i = 0; i < this.monitors.length; i++) {
let bgManager = this._createBackgroundManager(i); let bgManager = this._createBackgroundManager(i);
@@ -482,8 +486,6 @@ var LayoutManager = GObject.registerClass({
if (i != this.primaryIndex && this._startingUp) if (i != this.primaryIndex && this._startingUp)
bgManager.backgroundActor.hide(); bgManager.backgroundActor.hide();
} }
return Promise.all(this._bgManagers.map(this._waitLoaded));
} }
_updateKeyboardBox() { _updateKeyboardBox() {
@@ -642,7 +644,7 @@ var LayoutManager = GObject.registerClass({
// When starting a normal user session, we want to grow it out of the middle // When starting a normal user session, we want to grow it out of the middle
// of the screen. // of the screen.
async _prepareStartupAnimation() { _prepareStartupAnimation() {
// During the initial transition, add a simple actor to block all events, // During the initial transition, add a simple actor to block all events,
// so they don't get delivered to X11 windows that have been transformed. // so they don't get delivered to X11 windows that have been transformed.
this._coverPane = new Clutter.Actor({ opacity: 0, this._coverPane = new Clutter.Actor({ opacity: 0,
@@ -659,6 +661,8 @@ var LayoutManager = GObject.registerClass({
} else if (Main.sessionMode.isGreeter) { } else if (Main.sessionMode.isGreeter) {
this.panelBox.translation_y = -this.panelBox.height; this.panelBox.translation_y = -this.panelBox.height;
} else { } else {
this._updateBackgrounds();
// We need to force an update of the regions now before we scale // We need to force an update of the regions now before we scale
// the UI group to get the correct allocation for the struts. // the UI group to get the correct allocation for the struts.
this._updateRegions(); this._updateRegions();
@@ -674,8 +678,6 @@ var LayoutManager = GObject.registerClass({
this.uiGroup.scale_x = this.uiGroup.scale_y = 0.75; this.uiGroup.scale_x = this.uiGroup.scale_y = 0.75;
this.uiGroup.opacity = 0; this.uiGroup.opacity = 0;
global.window_group.set_clip(monitor.x, monitor.y, monitor.width, monitor.height); global.window_group.set_clip(monitor.x, monitor.y, monitor.width, monitor.height);
await this._updateBackgrounds();
} }
this.emit('startup-prepared'); this.emit('startup-prepared');
@@ -1202,8 +1204,7 @@ class HotCorner extends Clutter.Actor {
if (Clutter.get_default_text_direction() == Clutter.TextDirection.RTL) { if (Clutter.get_default_text_direction() == Clutter.TextDirection.RTL) {
this._corner.set_position(this.width - this._corner.width, 0); this._corner.set_position(this.width - this._corner.width, 0);
this.set_pivot_point(1.0, 0.0); this.set_anchor_point_from_gravity(Clutter.Gravity.NORTH_EAST);
this.translation_x = -this.width;
} else { } else {
this._corner.set_position(0, 0); this._corner.set_position(0, 0);
} }
@@ -1228,9 +1229,8 @@ class HotCorner extends Clutter.Actor {
return; return;
if (Main.overview.shouldToggleByCornerOrButton()) { if (Main.overview.shouldToggleByCornerOrButton()) {
this._ripples.playAnimation(this._x, this._y);
Main.overview.toggle(); Main.overview.toggle();
if (Main.overview.animationInProgress)
this._ripples.playAnimation(this._x, this._y);
} }
} }

View File

@@ -489,10 +489,7 @@ var Magnifier = class Magnifier {
_updateMouseSprite() { _updateMouseSprite() {
this._updateSpriteTexture(); this._updateSpriteTexture();
let [xHot, yHot] = this._cursorTracker.get_hot(); let [xHot, yHot] = this._cursorTracker.get_hot();
this._mouseSprite.set({ this._mouseSprite.set_anchor_point(xHot, yHot);
translation_x: -xHot,
translation_y: -yHot,
});
} }
_updateSpriteTexture() { _updateSpriteTexture() {

View File

@@ -3,10 +3,10 @@
ctrlAltTabManager, padOsdService, osdWindowManager, ctrlAltTabManager, padOsdService, osdWindowManager,
osdMonitorLabeler, shellMountOpDBusService, shellDBusService, osdMonitorLabeler, shellMountOpDBusService, shellDBusService,
shellAccessDialogDBusService, shellAudioSelectionDBusService, shellAccessDialogDBusService, shellAudioSelectionDBusService,
screenSaverDBus, uiGroup, magnifier, xdndHandler, keyboard, screenSaverDBus, screencastService, uiGroup, magnifier,
kbdA11yDialog, introspectService, start, pushModal, popModal, xdndHandler, keyboard, kbdA11yDialog, introspectService,
activateWindow, createLookingGlass, initializeDeferredWork, start, pushModal, popModal, activateWindow, createLookingGlass,
getThemeStylesheet, setThemeStylesheet */ initializeDeferredWork, getThemeStylesheet, setThemeStylesheet */
const { Clutter, Gio, GLib, GObject, Meta, Shell, St } = imports.gi; const { Clutter, Gio, GLib, GObject, Meta, Shell, St } = imports.gi;
@@ -34,6 +34,7 @@ const LoginManager = imports.misc.loginManager;
const LookingGlass = imports.ui.lookingGlass; const LookingGlass = imports.ui.lookingGlass;
const NotificationDaemon = imports.ui.notificationDaemon; const NotificationDaemon = imports.ui.notificationDaemon;
const WindowAttentionHandler = imports.ui.windowAttentionHandler; const WindowAttentionHandler = imports.ui.windowAttentionHandler;
const Screencast = imports.ui.screencast;
const ScreenShield = imports.ui.screenShield; const ScreenShield = imports.ui.screenShield;
const Scripting = imports.ui.scripting; const Scripting = imports.ui.scripting;
const SessionMode = imports.ui.sessionMode; const SessionMode = imports.ui.sessionMode;
@@ -73,6 +74,7 @@ var shellAudioSelectionDBusService = null;
var shellDBusService = null; var shellDBusService = null;
var shellMountOpDBusService = null; var shellMountOpDBusService = null;
var screenSaverDBus = null; var screenSaverDBus = null;
var screencastService = null;
var modalCount = 0; var modalCount = 0;
var actionMode = Shell.ActionMode.NONE; var actionMode = Shell.ActionMode.NONE;
var modalActorFocusStack = []; var modalActorFocusStack = [];
@@ -198,6 +200,7 @@ function _initializeUI() {
uiGroup = layoutManager.uiGroup; uiGroup = layoutManager.uiGroup;
padOsdService = new PadOsd.PadOsdService(); padOsdService = new PadOsd.PadOsdService();
screencastService = new Screencast.ScreencastService();
xdndHandler = new XdndHandler.XdndHandler(); xdndHandler = new XdndHandler.XdndHandler();
ctrlAltTabManager = new CtrlAltTab.CtrlAltTabManager(); ctrlAltTabManager = new CtrlAltTab.CtrlAltTabManager();
osdWindowManager = new OsdWindow.OsdWindowManager(); osdWindowManager = new OsdWindow.OsdWindowManager();

View File

@@ -1,6 +1,6 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
/* exported NotificationPolicy, NotificationGenericPolicy, /* exported NotificationPolicy, NotificationGenericPolicy,
NotificationApplicationPolicy, Source, SourceActor, NotificationApplicationPolicy, Source, SourceActor, SourceActorWithLabel,
SystemNotificationSource, MessageTray */ SystemNotificationSource, MessageTray */
const { Clutter, Gio, GLib, GObject, Meta, Shell, St } = imports.gi; const { Clutter, Gio, GLib, GObject, Meta, Shell, St } = imports.gi;
@@ -655,6 +655,77 @@ class SourceActor extends St.Widget {
} }
}); });
var SourceActorWithLabel = GObject.registerClass(
class SourceActorWithLabel extends SourceActor {
_init(source, size) {
super._init(source, size);
this._counterLabel = new St.Label({ x_align: Clutter.ActorAlign.CENTER,
x_expand: true,
y_align: Clutter.ActorAlign.CENTER,
y_expand: true });
this._counterBin = new St.Bin({ style_class: 'summary-source-counter',
child: this._counterLabel,
layout_manager: new Clutter.BinLayout() });
this._counterBin.hide();
this._counterBin.connect('style-changed', () => {
let themeNode = this._counterBin.get_theme_node();
this._counterBin.translation_x = themeNode.get_length('-shell-counter-overlap-x');
this._counterBin.translation_y = themeNode.get_length('-shell-counter-overlap-y');
});
this.add_actor(this._counterBin);
this._countUpdatedId = this._source.connect('notify::count', this._updateCount.bind(this));
this._updateCount();
this.connect('destroy', () => {
this._source.disconnect(this._countUpdatedId);
});
}
vfunc_allocate(box) {
super.vfunc_allocate(box);
let childBox = new Clutter.ActorBox();
let [, , naturalWidth, naturalHeight] = this._counterBin.get_preferred_size();
let direction = this.get_text_direction();
if (direction == Clutter.TextDirection.LTR) {
// allocate on the right in LTR
childBox.x1 = box.x2 - naturalWidth;
childBox.x2 = box.x2;
} else {
// allocate on the left in RTL
childBox.x1 = 0;
childBox.x2 = naturalWidth;
}
childBox.y1 = box.y2 - naturalHeight;
childBox.y2 = box.y2;
this._counterBin.allocate(childBox);
}
_updateCount() {
if (this._actorDestroyed)
return;
this._counterBin.visible = this._source.countVisible;
let text;
if (this._source.count < 100)
text = this._source.count.toString();
else
text = String.fromCharCode(0x22EF); // midline horizontal ellipsis
this._counterLabel.set_text(text);
}
});
var Source = GObject.registerClass({ var Source = GObject.registerClass({
Properties: { Properties: {
'count': GObject.ParamSpec.int( 'count': GObject.ParamSpec.int(

View File

@@ -4,10 +4,6 @@
const { Clutter, GLib, GObject, Meta, Shell, St } = imports.gi; const { Clutter, GLib, GObject, Meta, Shell, St } = imports.gi;
const Signals = imports.signals; const Signals = imports.signals;
// Time for initial animation going into Overview mode;
// this is defined here to make it available in imports.
var ANIMATION_TIME = 250;
const Background = imports.ui.background; const Background = imports.ui.background;
const DND = imports.ui.dnd; const DND = imports.ui.dnd;
const LayoutManager = imports.ui.layout; const LayoutManager = imports.ui.layout;
@@ -18,6 +14,9 @@ const OverviewControls = imports.ui.overviewControls;
const Params = imports.misc.params; const Params = imports.misc.params;
const WorkspaceThumbnail = imports.ui.workspaceThumbnail; const WorkspaceThumbnail = imports.ui.workspaceThumbnail;
// Time for initial animation going into Overview mode
var ANIMATION_TIME = 250;
// Must be less than ANIMATION_TIME, since we switch to // Must be less than ANIMATION_TIME, since we switch to
// or from the overview completely after ANIMATION_TIME, // or from the overview completely after ANIMATION_TIME,
// and don't want the shading animation to get cut off // and don't want the shading animation to get cut off
@@ -440,19 +439,19 @@ var Overview = class {
this.emit('windows-restacked', stackIndices); this.emit('windows-restacked', stackIndices);
} }
beginItemDrag(source) { beginItemDrag(_source) {
this.emit('item-drag-begin', source); this.emit('item-drag-begin');
this._inItemDrag = true; this._inItemDrag = true;
} }
cancelledItemDrag(source) { cancelledItemDrag(_source) {
this.emit('item-drag-cancelled', source); this.emit('item-drag-cancelled');
} }
endItemDrag(source) { endItemDrag(_source) {
if (!this._inItemDrag) if (!this._inItemDrag)
return; return;
this.emit('item-drag-end', source); this.emit('item-drag-end');
this._inItemDrag = false; this._inItemDrag = false;
} }

View File

@@ -8,9 +8,8 @@ const Main = imports.ui.main;
const Params = imports.misc.params; const Params = imports.misc.params;
const ViewSelector = imports.ui.viewSelector; const ViewSelector = imports.ui.viewSelector;
const WorkspaceThumbnail = imports.ui.workspaceThumbnail; const WorkspaceThumbnail = imports.ui.workspaceThumbnail;
const Overview = imports.ui.overview;
var SIDE_CONTROLS_ANIMATION_TIME = Overview.ANIMATION_TIME; var SIDE_CONTROLS_ANIMATION_TIME = 160;
function getRtlSlideDirection(direction, actor) { function getRtlSlideDirection(direction, actor) {
let rtl = actor.text_direction == Clutter.TextDirection.RTL; let rtl = actor.text_direction == Clutter.TextDirection.RTL;
@@ -423,7 +422,6 @@ class ControlsManager extends St.Widget {
let activeWorkspaceIndex = workspaceManager.get_active_workspace_index(); let activeWorkspaceIndex = workspaceManager.get_active_workspace_index();
this._workspaceAdjustment = new St.Adjustment({ this._workspaceAdjustment = new St.Adjustment({
actor: this,
value: activeWorkspaceIndex, value: activeWorkspaceIndex,
lower: 0, lower: 0,
page_increment: 1, page_increment: 1,
@@ -455,6 +453,8 @@ class ControlsManager extends St.Widget {
this._group.add_child(this.viewSelector); this._group.add_child(this.viewSelector);
this._group.add_actor(this._thumbnailsSlider); this._group.add_actor(this._thumbnailsSlider);
layout.connect('allocation-changed', this._updateWorkspacesGeometry.bind(this));
Main.overview.connect('showing', this._updateSpacerVisibility.bind(this)); Main.overview.connect('showing', this._updateSpacerVisibility.bind(this));
this.connect('destroy', this._onDestroy.bind(this)); this.connect('destroy', this._onDestroy.bind(this));
@@ -477,6 +477,26 @@ class ControlsManager extends St.Widget {
this._workspaceAdjustment.value = activeIndex; this._workspaceAdjustment.value = activeIndex;
} }
_updateWorkspacesGeometry() {
let [x, y] = this.get_transformed_position();
let [width, height] = this.get_transformed_size();
let geometry = { x, y, width, height };
let spacing = this.get_theme_node().get_length('spacing');
let dashWidth = this._dashSlider.getVisibleWidth() + spacing;
let thumbnailsWidth = this._thumbnailsSlider.getNonExpandedWidth() + spacing;
geometry.width -= dashWidth;
geometry.width -= thumbnailsWidth;
if (this.get_text_direction() == Clutter.TextDirection.LTR)
geometry.x += dashWidth;
else
geometry.x += thumbnailsWidth;
this.viewSelector.setWorkspacesFullGeometry(geometry);
}
_setVisibility() { _setVisibility() {
// Ignore the case when we're leaving the overview, since // Ignore the case when we're leaving the overview, since
// actors will be made visible again when entering the overview // actors will be made visible again when entering the overview

View File

@@ -5,6 +5,7 @@ const { Atk, Clutter, Gio, GLib, GObject, Meta, Shell, St } = imports.gi;
const Cairo = imports.cairo; const Cairo = imports.cairo;
const Animation = imports.ui.animation; const Animation = imports.ui.animation;
const AppDisplay = imports.ui.appDisplay;
const Config = imports.misc.config; const Config = imports.misc.config;
const CtrlAltTab = imports.ui.ctrlAltTab; const CtrlAltTab = imports.ui.ctrlAltTab;
const DND = imports.ui.dnd; const DND = imports.ui.dnd;
@@ -60,69 +61,20 @@ function _unpremultiply(color) {
return new Clutter.Color({ red, green, blue, alpha: color.alpha }); return new Clutter.Color({ red, green, blue, alpha: color.alpha });
} }
class AppMenu extends PopupMenu.PopupMenu { class AppMenu extends AppDisplay.BaseAppMenu {
constructor(sourceActor) { constructor(sourceActor) {
super(sourceActor, 0.5, St.Side.TOP); super(sourceActor, St.Side.TOP);
this.actor.add_style_class_name('app-menu'); this.actor.add_style_class_name('app-menu');
this._app = null; this._app = null;
this._appSystem = Shell.AppSystem.get_default();
this._windowsChangedId = 0; this._windowsChangedId = 0;
/* Translators: This is the heading of a list of open windows */
this.addMenuItem(new PopupMenu.PopupSeparatorMenuItem(_("Open Windows")));
this._windowSection = new PopupMenu.PopupMenuSection();
this.addMenuItem(this._windowSection);
this.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
this._newWindowItem = this.addAction(_("New Window"), () => {
this._app.open_new_window(-1);
});
this.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
this._actionSection = new PopupMenu.PopupMenuSection();
this.addMenuItem(this._actionSection);
this.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
this._detailsItem = this.addAction(_('Show Details'), async () => {
let id = this._app.get_id();
let args = GLib.Variant.new('(ss)', [id, '']);
const bus = await Gio.DBus.get(Gio.BusType.SESSION, null);
bus.call(
'org.gnome.Software',
'/org/gnome/Software',
'org.gtk.Actions', 'Activate',
new GLib.Variant('(sava{sv})', ['details', [args], null]),
null, 0, -1, null);
});
this.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
this.addAction(_("Quit"), () => {
this._app.request_quit();
});
this._appSystem.connect('installed-changed', () => {
this._updateDetailsVisibility();
});
this._updateDetailsVisibility();
} }
_updateDetailsVisibility() { get app() {
let sw = this._appSystem.lookup_app('org.gnome.Software.desktop'); return this._app;
this._detailsItem.visible = sw != null;
}
isEmpty() {
if (!this._app)
return true;
return super.isEmpty();
} }
setApp(app) { setApp(app) {
@@ -157,25 +109,6 @@ class AppMenu extends PopupMenu.PopupMenu {
this._newWindowItem.visible = this._newWindowItem.visible =
app && app.can_open_new_window() && !actions.includes('new-window'); app && app.can_open_new_window() && !actions.includes('new-window');
} }
_updateWindowsSection() {
this._windowSection.removeAll();
if (!this._app)
return;
let windows = this._app.get_windows();
windows.forEach(window => {
let title = window.title || this._app.get_name();
let item = this._windowSection.addAction(title, event => {
Main.activateWindow(window, event.get_time());
});
let id = window.connect('notify::title', () => {
item.label.text = window.title || this._app.get_name();
});
item.connect('destroy', () => window.disconnect(id));
});
}
} }
/** /**
@@ -675,7 +608,7 @@ class PanelCorner extends St.DrawingArea {
let borderWidth = node.get_length('-panel-corner-border-width'); let borderWidth = node.get_length('-panel-corner-border-width');
this.set_size(cornerRadius, borderWidth + cornerRadius); this.set_size(cornerRadius, borderWidth + cornerRadius);
this.translation_y = -borderWidth; this.set_anchor_point(0, borderWidth);
} }
}); });
@@ -736,11 +669,13 @@ class AggregateMenu extends PanelMenu.Button {
this._volume = new imports.ui.status.volume.Indicator(); this._volume = new imports.ui.status.volume.Indicator();
this._brightness = new imports.ui.status.brightness.Indicator(); this._brightness = new imports.ui.status.brightness.Indicator();
this._system = new imports.ui.status.system.Indicator(); this._system = new imports.ui.status.system.Indicator();
this._screencast = new imports.ui.status.screencast.Indicator();
this._location = new imports.ui.status.location.Indicator(); this._location = new imports.ui.status.location.Indicator();
this._nightLight = new imports.ui.status.nightLight.Indicator(); this._nightLight = new imports.ui.status.nightLight.Indicator();
this._thunderbolt = new imports.ui.status.thunderbolt.Indicator(); this._thunderbolt = new imports.ui.status.thunderbolt.Indicator();
this._indicators.add_child(this._thunderbolt); this._indicators.add_child(this._thunderbolt);
this._indicators.add_child(this._screencast);
this._indicators.add_child(this._location); this._indicators.add_child(this._location);
this._indicators.add_child(this._nightLight); this._indicators.add_child(this._nightLight);
if (this._network) if (this._network)

View File

@@ -183,9 +183,10 @@ var Button = GObject.registerClass({
} }
_onDestroy() { _onDestroy() {
super._onDestroy();
if (this.menu) if (this.menu)
this.menu.destroy(); this.menu.destroy();
super._onDestroy();
} }
}); });

View File

@@ -881,10 +881,9 @@ var PopupMenu = class extends PopupMenuBase {
let state = event.get_state(); let state = event.get_state();
// if user has a modifier down (except capslock and numlock) // if user has a modifier down (except capslock)
// then don't handle the key press here // then don't handle the key press here
state &= ~Clutter.ModifierType.LOCK_MASK; state &= ~Clutter.ModifierType.LOCK_MASK;
state &= ~Clutter.ModifierType.MOD2_MASK;
state &= Clutter.ModifierType.MODIFIER_MASK; state &= Clutter.ModifierType.MODIFIER_MASK;
if (state) if (state)
@@ -1325,7 +1324,7 @@ var PopupMenuManager = class {
removeMenu(menu) { removeMenu(menu) {
if (menu == this.activeMenu) if (menu == this.activeMenu)
this._grabHelper.ungrab({ actor: menu.actor }); this._closeMenu(false, menu);
let position = this._findMenu(menu); let position = this._findMenu(menu);
if (position == -1) // not a menu we manage if (position == -1) // not a menu we manage

146
js/ui/screencast.js Normal file
View File

@@ -0,0 +1,146 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const { Gio, GLib, Shell } = imports.gi;
const Signals = imports.signals;
const Main = imports.ui.main;
const { loadInterfaceXML } = imports.misc.fileUtils;
const ScreencastIface = loadInterfaceXML('org.gnome.Shell.Screencast');
var ScreencastService = class {
constructor() {
this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(ScreencastIface, this);
this._dbusImpl.export(Gio.DBus.session, '/org/gnome/Shell/Screencast');
Gio.DBus.session.own_name('org.gnome.Shell.Screencast', Gio.BusNameOwnerFlags.REPLACE, null, null);
this._recorders = new Map();
this._lockdownSettings = new Gio.Settings({ schema_id: 'org.gnome.desktop.lockdown' });
Main.sessionMode.connect('updated', this._sessionUpdated.bind(this));
}
get isRecording() {
return this._recorders.size > 0;
}
_ensureRecorderForSender(sender) {
let recorder = this._recorders.get(sender);
if (!recorder) {
recorder = new Shell.Recorder({ stage: global.stage,
display: global.display });
recorder._watchNameId =
Gio.bus_watch_name(Gio.BusType.SESSION, sender, 0, null,
this._onNameVanished.bind(this));
this._recorders.set(sender, recorder);
this.emit('updated');
}
return recorder;
}
_sessionUpdated() {
if (Main.sessionMode.allowScreencast)
return;
for (let sender of this._recorders.keys())
this._stopRecordingForSender(sender);
}
_onNameVanished(connection, name) {
this._stopRecordingForSender(name);
}
_stopRecordingForSender(sender) {
let recorder = this._recorders.get(sender);
if (!recorder)
return false;
Gio.bus_unwatch_name(recorder._watchNameId);
recorder.close();
this._recorders.delete(sender);
this.emit('updated');
return true;
}
_applyOptionalParameters(recorder, options) {
for (let option in options)
options[option] = options[option].deep_unpack();
if (options['pipeline'])
recorder.set_pipeline(options['pipeline']);
if (options['framerate'])
recorder.set_framerate(options['framerate']);
if ('draw-cursor' in options)
recorder.set_draw_cursor(options['draw-cursor']);
}
ScreencastAsync(params, invocation) {
let returnValue = [false, ''];
if (!Main.sessionMode.allowScreencast ||
this._lockdownSettings.get_boolean('disable-save-to-disk')) {
invocation.return_value(GLib.Variant.new('(bs)', returnValue));
return;
}
let sender = invocation.get_sender();
let recorder = this._ensureRecorderForSender(sender);
if (!recorder.is_recording()) {
let [fileTemplate, options] = params;
recorder.set_file_template(fileTemplate);
this._applyOptionalParameters(recorder, options);
let [success, fileName] = recorder.record();
returnValue = [success, fileName ? fileName : ''];
if (!success)
this._stopRecordingForSender(sender);
}
invocation.return_value(GLib.Variant.new('(bs)', returnValue));
}
ScreencastAreaAsync(params, invocation) {
let returnValue = [false, ''];
if (!Main.sessionMode.allowScreencast ||
this._lockdownSettings.get_boolean('disable-save-to-disk')) {
invocation.return_value(GLib.Variant.new('(bs)', returnValue));
return;
}
let sender = invocation.get_sender();
let recorder = this._ensureRecorderForSender(sender);
if (!recorder.is_recording()) {
let [x, y, width, height, fileTemplate, options] = params;
if (x < 0 || y < 0 ||
width <= 0 || height <= 0 ||
x + width > global.screen_width ||
y + height > global.screen_height) {
invocation.return_error_literal(Gio.IOErrorEnum,
Gio.IOErrorEnum.CANCELLED,
"Invalid params");
return;
}
recorder.set_file_template(fileTemplate);
recorder.set_area(x, y, width, height);
this._applyOptionalParameters(recorder, options);
let [success, fileName] = recorder.record();
returnValue = [success, fileName ? fileName : ''];
if (!success)
this._stopRecordingForSender(sender);
}
invocation.return_value(GLib.Variant.new('(bs)', returnValue));
}
StopScreencastAsync(params, invocation) {
let success = this._stopRecordingForSender(invocation.get_sender());
invocation.return_value(GLib.Variant.new('(b)', [success]));
}
};
Signals.addSignalMethods(ScreencastService.prototype);

View File

@@ -21,13 +21,16 @@ const { loadInterfaceXML } = imports.misc.fileUtils;
// When scripting an automated test we want to make a series of calls // When scripting an automated test we want to make a series of calls
// in a linear fashion, but we also want to be able to let the main // in a linear fashion, but we also want to be able to let the main
// loop run so actions can finish. For this reason we write the script // loop run so actions can finish. For this reason we write the script
// as an async function that uses await when it wants to let the main // as a generator function that yields when it want to let the main
// loop run. // loop run.
// //
// await Scripting.sleep(1000); // yield Scripting.sleep(1000);
// main.overview.show(); // main.overview.show();
// await Scripting.waitLeisure(); // yield Scripting.waitLeisure();
// //
// While it isn't important to the person writing the script, the actual
// yielded result is a function that the caller uses to provide the
// callback for resuming the script.
/** /**
* sleep: * sleep:
@@ -282,11 +285,13 @@ function _collect(scriptModule, outputFile) {
} }
async function _runPerfScript(scriptModule, outputFile) { async function _runPerfScript(scriptModule, outputFile) {
try { for (let step of scriptModule.run()) {
await scriptModule.run(); try {
} catch (err) { await step; // eslint-disable-line no-await-in-loop
log(`Script failed: ${err}\n${err.stack}`); } catch (err) {
Meta.exit(Meta.ExitCode.ERROR); log(`Script failed: ${err}\n${err.stack}`);
Meta.exit(Meta.ExitCode.ERROR);
}
} }
try { try {

View File

@@ -113,10 +113,10 @@ function _loadMode(file, info) {
} }
_modes[modeName] = {}; _modes[modeName] = {};
const excludedProps = ['unlockDialog']; let propBlacklist = ['unlockDialog'];
for (let prop in _modes[DEFAULT_MODE]) { for (let prop in _modes[DEFAULT_MODE]) {
if (newMode[prop] !== undefined && if (newMode[prop] !== undefined &&
!excludedProps.includes(prop)) !propBlacklist.includes(prop))
_modes[modeName][prop] = newMode[prop]; _modes[modeName][prop] = newMode[prop];
} }
_modes[modeName]['isPrimary'] = true; _modes[modeName]['isPrimary'] = true;

View File

@@ -15,7 +15,6 @@ const Util = imports.misc.util;
const { loadInterfaceXML } = imports.misc.fileUtils; const { loadInterfaceXML } = imports.misc.fileUtils;
Gio._promisify(Gio.DBusConnection.prototype, 'call', 'call_finish');
Gio._promisify(NM.Client, 'new_async', 'new_finish'); Gio._promisify(NM.Client, 'new_async', 'new_finish');
Gio._promisify(NM.Client.prototype, Gio._promisify(NM.Client.prototype,
'check_connectivity_async', 'check_connectivity_finish'); 'check_connectivity_async', 'check_connectivity_finish');
@@ -83,30 +82,6 @@ function ensureActiveConnectionProps(active) {
} }
} }
function launchSettingsPanel(panel, ...args) {
const param = new GLib.Variant('(sav)',
[panel, args.map(s => new GLib.Variant('s', s))]);
const platformData = {
'desktop-startup-id': new GLib.Variant('s',
'_TIME%s'.format(global.get_current_time())),
};
try {
Gio.DBus.session.call(
'org.gnome.ControlCenter',
'/org/gnome/ControlCenter',
'org.freedesktop.Application',
'ActivateAction',
new GLib.Variant('(sava{sv})',
['launch-panel', [param], platformData]),
null,
Gio.DBusCallFlags.NONE,
-1,
null);
} catch (e) {
log('Failed to launch Settings panel: %s'.format(e.message));
}
}
var NMConnectionItem = class { var NMConnectionItem = class {
constructor(section, connection) { constructor(section, connection) {
this._section = section; this._section = section;
@@ -564,7 +539,8 @@ var NMDeviceModem = class extends NMConnectionDevice {
} }
_autoConnect() { _autoConnect() {
launchSettingsPanel('network', 'connect-3g', this._device.get_path()); Util.spawn(['gnome-control-center', 'network',
'connect-3g', this._device.get_path()]);
} }
destroy() { destroy() {
@@ -955,8 +931,8 @@ class NMWirelessDialog extends ModalDialog.ModalDialog {
(accessPoints[0]._secType == NMAccessPointSecurity.WPA_ENT)) { (accessPoints[0]._secType == NMAccessPointSecurity.WPA_ENT)) {
// 802.1x-enabled APs require further configuration, so they're // 802.1x-enabled APs require further configuration, so they're
// handled in gnome-control-center // handled in gnome-control-center
launchSettingsPanel('wifi', 'connect-8021x-wifi', Util.spawn(['gnome-control-center', 'wifi', 'connect-8021x-wifi',
this._device.get_path(), accessPoints[0].get_path()); this._device.get_path(), accessPoints[0].get_path()]);
} else { } else {
let connection = new NM.SimpleConnection(); let connection = new NM.SimpleConnection();
this._client.add_and_activate_connection_async(connection, this._device, accessPoints[0].get_path(), null, null); this._client.add_and_activate_connection_async(connection, this._device, accessPoints[0].get_path(), null, null);

View File

@@ -24,8 +24,7 @@ class RemoteAccessApplet extends PanelMenu.SystemIndicator {
return; return;
this._handles = new Set(); this._handles = new Set();
this._sharedIndicator = null; this._indicator = null;
this._recordingIndicator = null;
this._menuSection = null; this._menuSection = null;
controller.connect('new-handle', (o, handle) => { controller.connect('new-handle', (o, handle) => {
@@ -34,49 +33,32 @@ class RemoteAccessApplet extends PanelMenu.SystemIndicator {
} }
_ensureControls() { _ensureControls() {
if (this._sharedIndicator && this._recordingIndicator) if (this._indicator)
return; return;
this._sharedIndicator = this._addIndicator(); this._indicator = this._addIndicator();
this._sharedIndicator.icon_name = 'screen-shared-symbolic'; this._indicator.icon_name = 'screen-shared-symbolic';
this._sharedIndicator.add_style_class_name('remote-access-indicator'); this._indicator.add_style_class_name('remote-access-indicator');
this._item =
this._sharedItem =
new PopupMenu.PopupSubMenuMenuItem(_("Screen is Being Shared"), new PopupMenu.PopupSubMenuMenuItem(_("Screen is Being Shared"),
true); true);
this._sharedItem.menu.addAction(_("Turn off"), this._item.menu.addAction(_("Turn off"),
() => { () => {
for (let handle of this._handles) { for (let handle of this._handles)
if (!handle.is_recording) handle.stop();
handle.stop(); });
} this._item.icon.icon_name = 'screen-shared-symbolic';
}); this.menu.addMenuItem(this._item);
this._sharedItem.icon.icon_name = 'screen-shared-symbolic';
this.menu.addMenuItem(this._sharedItem);
this._recordingIndicator = this._addIndicator();
this._recordingIndicator.icon_name = 'media-record-symbolic';
this._recordingIndicator.add_style_class_name('screencast-indicator');
}
_isScreenShared() {
return [...this._handles].some(handle => !handle.is_recording);
}
_isRecording() {
return [...this._handles].some(handle => handle.is_recording);
} }
_sync() { _sync() {
if (this._isScreenShared()) { if (this._handles.size == 0) {
this._sharedIndicator.visible = true; this._indicator.visible = false;
this._sharedItem.visible = true; this._item.visible = false;
} else { } else {
this._sharedIndicator.visible = false; this._indicator.visible = true;
this._sharedItem.visible = false; this._item.visible = true;
} }
this._recordingIndicator.visible = this._isRecording();
} }
_onStopped(handle) { _onStopped(handle) {
@@ -88,7 +70,9 @@ class RemoteAccessApplet extends PanelMenu.SystemIndicator {
this._handles.add(handle); this._handles.add(handle);
handle.connect('stopped', this._onStopped.bind(this)); handle.connect('stopped', this._onStopped.bind(this));
this._ensureControls(); if (this._handles.size == 1) {
this._sync(); this._ensureControls();
this._sync();
}
} }
}); });

View File

@@ -86,8 +86,6 @@ class Indicator extends PanelMenu.SystemIndicator {
Main.sessionMode.connect('updated', this._sessionUpdated.bind(this)); Main.sessionMode.connect('updated', this._sessionUpdated.bind(this));
this._sessionUpdated(); this._sessionUpdated();
this._sync();
} }
_sessionUpdated() { _sessionUpdated() {

View File

@@ -0,0 +1,25 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
/* exported Indicator */
const GObject = imports.gi.GObject;
const Main = imports.ui.main;
const PanelMenu = imports.ui.panelMenu;
var Indicator = GObject.registerClass(
class Indicator extends PanelMenu.SystemIndicator {
_init() {
super._init();
this._indicator = this._addIndicator();
this._indicator.icon_name = 'media-record-symbolic';
this._indicator.add_style_class_name('screencast-indicator');
this._sync();
Main.screencastService.connect('updated', this._sync.bind(this));
}
_sync() {
this._indicator.visible = Main.screencastService.isRecording;
}
});

View File

@@ -27,8 +27,6 @@ class Indicator extends PanelMenu.SystemIndicator {
() => this._updateSessionSubMenu()); () => this._updateSessionSubMenu());
this._powerOffItem.connect('notify::visible', this._powerOffItem.connect('notify::visible',
() => this._updateSessionSubMenu()); () => this._updateSessionSubMenu());
this._restartItem.connect('notify::visible',
() => this._updateSessionSubMenu());
// Whether shutdown is available or not depends on both lockdown // Whether shutdown is available or not depends on both lockdown
// settings (disable-log-out) and Polkit policy - the latter doesn't // settings (disable-log-out) and Polkit policy - the latter doesn't
// notify, so we update the menu item each time the menu opens or // notify, so we update the menu item each time the menu opens or
@@ -54,7 +52,6 @@ class Indicator extends PanelMenu.SystemIndicator {
this._loginScreenItem.visible || this._loginScreenItem.visible ||
this._logoutItem.visible || this._logoutItem.visible ||
this._suspendItem.visible || this._suspendItem.visible ||
this._restartItem.visible ||
this._powerOffItem.visible; this._powerOffItem.visible;
} }
@@ -73,8 +70,9 @@ class Indicator extends PanelMenu.SystemIndicator {
this.menu.addMenuItem(item); this.menu.addMenuItem(item);
this._orientationLockItem = item; this._orientationLockItem = item;
this._systemActions.bind_property('can-lock-orientation', this._systemActions.bind_property('can-lock-orientation',
this._orientationLockItem, 'visible', this._orientationLockItem,
bindFlags); 'visible',
bindFlags);
this._systemActions.connect('notify::orientation-lock-icon', () => { this._systemActions.connect('notify::orientation-lock-icon', () => {
let iconName = this._systemActions.orientation_lock_icon; let iconName = this._systemActions.orientation_lock_icon;
let labelText = this._systemActions.getName("lock-orientation"); let labelText = this._systemActions.getName("lock-orientation");
@@ -86,8 +84,8 @@ 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) {
const [icon] = app.app_info.get_icon().names; let [icon, name] = [app.app_info.get_icon().names[0],
const name = app.app_info.get_name(); app.get_name()];
item = new PopupMenu.PopupImageMenuItem(name, icon); item = new PopupMenu.PopupImageMenuItem(name, icon);
item.connect('activate', () => { item.connect('activate', () => {
this.menu.itemActivated(BoxPointer.PopupAnimation.NONE); this.menu.itemActivated(BoxPointer.PopupAnimation.NONE);
@@ -109,49 +107,15 @@ class Indicator extends PanelMenu.SystemIndicator {
this.menu.addMenuItem(item); this.menu.addMenuItem(item);
this._lockScreenItem = item; this._lockScreenItem = item;
this._systemActions.bind_property('can-lock-screen', this._systemActions.bind_property('can-lock-screen',
this._lockScreenItem, 'visible', this._lockScreenItem,
bindFlags); 'visible',
bindFlags);
this._sessionSubMenu = new PopupMenu.PopupSubMenuMenuItem( this._sessionSubMenu = new PopupMenu.PopupSubMenuMenuItem(
_('Power Off / Log Out'), true); _('Power Off / Log Out'), true);
this._sessionSubMenu.icon.icon_name = 'system-shutdown-symbolic'; this._sessionSubMenu.icon.icon_name = 'system-shutdown-symbolic';
item = new PopupMenu.PopupMenuItem(_('Suspend')); item = new PopupMenu.PopupMenuItem(_("Log Out"));
item.connect('activate', () => {
this.menu.itemActivated(BoxPointer.PopupAnimation.NONE);
this._systemActions.activateSuspend();
});
this._sessionSubMenu.menu.addMenuItem(item);
this._suspendItem = item;
this._systemActions.bind_property('can-suspend',
this._suspendItem, 'visible',
bindFlags);
item = new PopupMenu.PopupMenuItem(_('Restart…'));
item.connect('activate', () => {
this.menu.itemActivated(BoxPointer.PopupAnimation.NONE);
this._systemActions.activateRestart();
});
this._sessionSubMenu.menu.addMenuItem(item);
this._restartItem = item;
this._systemActions.bind_property('can-restart',
this._restartItem, 'visible',
bindFlags);
item = new PopupMenu.PopupMenuItem(_('Power Off…'));
item.connect('activate', () => {
this.menu.itemActivated(BoxPointer.PopupAnimation.NONE);
this._systemActions.activatePowerOff();
});
this._sessionSubMenu.menu.addMenuItem(item);
this._powerOffItem = item;
this._systemActions.bind_property('can-power-off',
this._powerOffItem, 'visible',
bindFlags);
this._sessionSubMenu.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
item = new PopupMenu.PopupMenuItem(_('Log Out'));
item.connect('activate', () => { item.connect('activate', () => {
this.menu.itemActivated(BoxPointer.PopupAnimation.NONE); this.menu.itemActivated(BoxPointer.PopupAnimation.NONE);
this._systemActions.activateLogout(); this._systemActions.activateLogout();
@@ -159,10 +123,11 @@ class Indicator extends PanelMenu.SystemIndicator {
this._sessionSubMenu.menu.addMenuItem(item); this._sessionSubMenu.menu.addMenuItem(item);
this._logoutItem = item; this._logoutItem = item;
this._systemActions.bind_property('can-logout', this._systemActions.bind_property('can-logout',
this._logoutItem, 'visible', this._logoutItem,
bindFlags); 'visible',
bindFlags);
item = new PopupMenu.PopupMenuItem(_('Switch User…')); item = new PopupMenu.PopupMenuItem(_("Switch User…"));
item.connect('activate', () => { item.connect('activate', () => {
this.menu.itemActivated(BoxPointer.PopupAnimation.NONE); this.menu.itemActivated(BoxPointer.PopupAnimation.NONE);
this._systemActions.activateSwitchUser(); this._systemActions.activateSwitchUser();
@@ -170,8 +135,35 @@ class Indicator extends PanelMenu.SystemIndicator {
this._sessionSubMenu.menu.addMenuItem(item); this._sessionSubMenu.menu.addMenuItem(item);
this._loginScreenItem = item; this._loginScreenItem = item;
this._systemActions.bind_property('can-switch-user', this._systemActions.bind_property('can-switch-user',
this._loginScreenItem, 'visible', this._loginScreenItem,
bindFlags); 'visible',
bindFlags);
this._sessionSubMenu.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
item = new PopupMenu.PopupMenuItem(_("Suspend"));
item.connect('activate', () => {
this.menu.itemActivated(BoxPointer.PopupAnimation.NONE);
this._systemActions.activateSuspend();
});
this._sessionSubMenu.menu.addMenuItem(item);
this._suspendItem = item;
this._systemActions.bind_property('can-suspend',
this._suspendItem,
'visible',
bindFlags);
item = new PopupMenu.PopupMenuItem(_("Power Off…"));
item.connect('activate', () => {
this.menu.itemActivated(BoxPointer.PopupAnimation.NONE);
this._systemActions.activatePowerOff();
});
this._sessionSubMenu.menu.addMenuItem(item);
this._powerOffItem = item;
this._systemActions.bind_property('can-power-off',
this._powerOffItem,
'visible',
bindFlags);
this.menu.addMenuItem(this._sessionSubMenu); this.menu.addMenuItem(this._sessionSubMenu);
} }

View File

@@ -62,7 +62,6 @@ var StreamSlider = class {
this._stream = null; this._stream = null;
this._volumeCancellable = null; this._volumeCancellable = null;
this._icons = [];
} }
get stream() { get stream() {
@@ -183,15 +182,24 @@ var StreamSlider = class {
if (!this._stream) if (!this._stream)
return null; return null;
let icons = ["audio-volume-muted-symbolic",
"audio-volume-low-symbolic",
"audio-volume-medium-symbolic",
"audio-volume-high-symbolic",
"audio-volume-overamplified-symbolic"];
let volume = this._stream.volume; let volume = this._stream.volume;
let n; let n;
if (this._stream.is_muted || volume <= 0) { if (this._stream.is_muted || volume <= 0) {
n = 0; n = 0;
} else { } else {
n = Math.ceil(3 * volume / this._control.get_vol_max_norm()); n = Math.ceil(3 * volume / this._control.get_vol_max_norm());
n = Math.clamp(n, 1, this._icons.length - 1); if (n < 1)
n = 1;
else if (n > 3)
n = 4;
} }
return this._icons[n]; return icons[n];
} }
getLevel() { getLevel() {
@@ -215,13 +223,6 @@ var OutputStreamSlider = class extends StreamSlider {
constructor(control) { constructor(control) {
super(control); super(control);
this._slider.accessible_name = _("Volume"); this._slider.accessible_name = _("Volume");
this._icons = [
'audio-volume-muted-symbolic',
'audio-volume-low-symbolic',
'audio-volume-medium-symbolic',
'audio-volume-high-symbolic',
'audio-volume-overamplified-symbolic',
];
} }
_connectStream(stream) { _connectStream(stream) {
@@ -273,12 +274,6 @@ var InputStreamSlider = class extends StreamSlider {
this._control.connect('stream-added', this._maybeShowInput.bind(this)); this._control.connect('stream-added', this._maybeShowInput.bind(this));
this._control.connect('stream-removed', this._maybeShowInput.bind(this)); this._control.connect('stream-removed', this._maybeShowInput.bind(this));
this._icon.icon_name = 'audio-input-microphone-symbolic'; this._icon.icon_name = 'audio-input-microphone-symbolic';
this._icons = [
'microphone-sensitivity-muted-symbolic',
'microphone-sensitivity-low-symbolic',
'microphone-sensitivity-medium-symbolic',
'microphone-sensitivity-high-symbolic',
];
} }
_connectStream(stream) { _connectStream(stream) {
@@ -324,7 +319,7 @@ var VolumeMenu = class extends PopupMenu.PopupMenuSection {
this._output = new OutputStreamSlider(this._control); this._output = new OutputStreamSlider(this._control);
this._output.connect('stream-updated', () => { this._output.connect('stream-updated', () => {
this.emit('output-icon-changed'); this.emit('icon-changed');
}); });
this.addMenuItem(this._output.item); this.addMenuItem(this._output.item);
@@ -332,9 +327,6 @@ var VolumeMenu = class extends PopupMenu.PopupMenuSection {
this._input.item.connect('notify::visible', () => { this._input.item.connect('notify::visible', () => {
this.emit('input-visible-changed'); this.emit('input-visible-changed');
}); });
this._input.connect('stream-updated', () => {
this.emit('input-icon-changed');
});
this.addMenuItem(this._input.item); this.addMenuItem(this._input.item);
this.addMenuItem(new PopupMenu.PopupSeparatorMenuItem()); this.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
@@ -351,7 +343,7 @@ var VolumeMenu = class extends PopupMenu.PopupMenuSection {
this._readInput(); this._readInput();
this._readOutput(); this._readOutput();
} else { } else {
this.emit('output-icon-changed'); this.emit('icon-changed');
} }
} }
@@ -363,14 +355,10 @@ var VolumeMenu = class extends PopupMenu.PopupMenuSection {
this._input.stream = this._control.get_default_source(); this._input.stream = this._control.get_default_source();
} }
getOutputIcon() { getIcon() {
return this._output.getIcon(); return this._output.getIcon();
} }
getInputIcon() {
return this._input.getIcon();
}
getLevel() { getLevel() {
return this._output.getLevel(); return this._output.getLevel();
} }
@@ -394,24 +382,21 @@ class Indicator extends PanelMenu.SystemIndicator {
this._control = getMixerControl(); this._control = getMixerControl();
this._volumeMenu = new VolumeMenu(this._control); this._volumeMenu = new VolumeMenu(this._control);
this._volumeMenu.connect('output-icon-changed', () => { this._volumeMenu.connect('icon-changed', () => {
let icon = this._volumeMenu.getOutputIcon(); let icon = this._volumeMenu.getIcon();
if (icon != null) if (icon != null)
this._primaryIndicator.icon_name = icon; this._primaryIndicator.icon_name = icon;
this._primaryIndicator.visible = icon !== null; this._primaryIndicator.visible = icon !== null;
}); });
this._inputIndicator.visible = this._volumeMenu.getInputVisible(); this._inputIndicator.set({
icon_name: 'audio-input-microphone-symbolic',
visible: this._volumeMenu.getInputVisible(),
});
this._volumeMenu.connect('input-visible-changed', () => { this._volumeMenu.connect('input-visible-changed', () => {
this._inputIndicator.visible = this._volumeMenu.getInputVisible(); this._inputIndicator.visible = this._volumeMenu.getInputVisible();
}); });
this._volumeMenu.connect('input-icon-changed', () => {
let icon = this._volumeMenu.getInputIcon();
if (icon !== null)
this._inputIndicator.icon_name = icon;
});
this.menu.addMenuItem(this._volumeMenu); this.menu.addMenuItem(this._volumeMenu);
} }
@@ -421,7 +406,7 @@ class Indicator extends PanelMenu.SystemIndicator {
if (result == Clutter.EVENT_PROPAGATE || this.menu.actor.mapped) if (result == Clutter.EVENT_PROPAGATE || this.menu.actor.mapped)
return result; return result;
let gicon = new Gio.ThemedIcon({ name: this._volumeMenu.getOutputIcon() }); let gicon = new Gio.ThemedIcon({ name: this._volumeMenu.getIcon() });
let level = this._volumeMenu.getLevel(); let level = this._volumeMenu.getLevel();
let maxLevel = this._volumeMenu.getMaxLevel(); let maxLevel = this._volumeMenu.getMaxLevel();
Main.osdWindowManager.show(-1, gicon, null, level, maxLevel); Main.osdWindowManager.show(-1, gicon, null, level, maxLevel);

View File

@@ -485,7 +485,6 @@ var UnlockDialog = GObject.registerClass({
this._gdmClient = new Gdm.Client(); this._gdmClient = new Gdm.Client();
this._adjustment = new St.Adjustment({ this._adjustment = new St.Adjustment({
actor: this,
lower: 0, lower: 0,
upper: 2, upper: 2,
page_size: 1, page_size: 1,
@@ -525,10 +524,6 @@ var UnlockDialog = GObject.registerClass({
this._bgManagers = []; this._bgManagers = [];
const themeContext = St.ThemeContext.get_for_stage(global.stage);
this._scaleChangedId = themeContext.connect('notify::scale-factor',
() => this._updateBackgroundEffects());
this._updateBackgrounds(); this._updateBackgrounds();
this._monitorsChangedId = this._monitorsChangedId =
Main.layoutManager.connect('monitors-changed', this._updateBackgrounds.bind(this)); Main.layoutManager.connect('monitors-changed', this._updateBackgrounds.bind(this));
@@ -573,9 +568,11 @@ var UnlockDialog = GObject.registerClass({
this._screenSaverSettings = new Gio.Settings({ schema_id: 'org.gnome.desktop.screensaver' }); this._screenSaverSettings = new Gio.Settings({ schema_id: 'org.gnome.desktop.screensaver' });
this._userSwitchEnabledId = 0;
this._userSwitchEnabledId = this._screenSaverSettings.connect('changed::user-switch-enabled', this._userSwitchEnabledId = this._screenSaverSettings.connect('changed::user-switch-enabled',
this._updateUserSwitchVisibility.bind(this)); this._updateUserSwitchVisibility.bind(this));
this._userLoadedId = 0;
this._userLoadedId = this._user.connect('notify::is-loaded', this._userLoadedId = this._user.connect('notify::is-loaded',
this._updateUserSwitchVisibility.bind(this)); this._updateUserSwitchVisibility.bind(this));
@@ -629,7 +626,6 @@ var UnlockDialog = GObject.registerClass({
y: monitor.y, y: monitor.y,
width: monitor.width, width: monitor.width,
height: monitor.height, height: monitor.height,
effect: new Shell.BlurEffect({ name: 'blur' }),
}); });
let bgManager = new Background.BackgroundManager({ let bgManager = new Background.BackgroundManager({
@@ -641,17 +637,19 @@ var UnlockDialog = GObject.registerClass({
this._bgManagers.push(bgManager); this._bgManagers.push(bgManager);
this._backgroundGroup.add_child(widget); this._backgroundGroup.add_child(widget);
}
_updateBackgroundEffects() {
const themeContext = St.ThemeContext.get_for_stage(global.stage); const themeContext = St.ThemeContext.get_for_stage(global.stage);
for (const widget of this._backgroundGroup) { let effect = new Shell.BlurEffect({
widget.get_effect('blur').set({ brightness: BLUR_BRIGHTNESS,
brightness: BLUR_BRIGHTNESS, sigma: BLUR_SIGMA * themeContext.scale_factor,
sigma: BLUR_SIGMA * themeContext.scale_factor, });
});
} this._scaleChangedId = themeContext.connect('notify::scale-factor', () => {
effect.sigma = BLUR_SIGMA * themeContext.scale_factor;
});
widget.add_effect(effect);
} }
_updateBackgrounds() { _updateBackgrounds() {
@@ -663,7 +661,6 @@ var UnlockDialog = GObject.registerClass({
for (let i = 0; i < Main.layoutManager.monitors.length; i++) for (let i = 0; i < Main.layoutManager.monitors.length; i++)
this._createBackground(i); this._createBackground(i);
this._updateBackgroundEffects();
} }
_ensureAuthPrompt() { _ensureAuthPrompt() {

View File

@@ -299,6 +299,10 @@ var ViewSelector = GObject.registerClass({
Main.overview.fadeInDesktop(); Main.overview.fadeInDesktop();
} }
setWorkspacesFullGeometry(geom) {
this._workspacesDisplay.setWorkspacesFullGeometry(geom);
}
vfunc_hide() { vfunc_hide() {
this.reset(); this.reset();
this._workspacesDisplay.hide(); this._workspacesDisplay.hide();

View File

@@ -42,11 +42,6 @@ const GsdWacomProxy = Gio.DBusProxy.makeProxyWrapper(GsdWacomIface);
const WINDOW_DIMMER_EFFECT_NAME = "gnome-shell-window-dimmer"; const WINDOW_DIMMER_EFFECT_NAME = "gnome-shell-window-dimmer";
Gio._promisify(Shell,
'util_start_systemd_unit', 'util_start_systemd_unit_finish');
Gio._promisify(Shell,
'util_stop_systemd_unit', 'util_stop_systemd_unit_finish');
var DisplayChangeDialog = GObject.registerClass( var DisplayChangeDialog = GObject.registerClass(
class DisplayChangeDialog extends ModalDialog.ModalDialog { class DisplayChangeDialog extends ModalDialog.ModalDialog {
_init(wm) { _init(wm) {
@@ -906,23 +901,46 @@ var WindowManager = class {
global.display.connect('init-xserver', (display, task) => { global.display.connect('init-xserver', (display, task) => {
IBusManager.getIBusManager().restartDaemon(['--xim']); IBusManager.getIBusManager().restartDaemon(['--xim']);
/* Timeout waiting for start job completion after 5 seconds */ try {
let cancellable = new Gio.Cancellable(); if (!Shell.util_start_systemd_unit('gsd-xsettings.target', 'fail'))
GLib.timeout_add_seconds(GLib.PRIORITY_DEFAULT, 5, () => { log('Not starting gsd-xsettings; waiting for gnome-session to do so');
cancellable.cancel();
return GLib.SOURCE_REMOVE;
});
this._startX11Services(task, cancellable); /* Leave this watchdog timeout so don't block indefinitely here */
let timeoutId = GLib.timeout_add_seconds(GLib.PRIORITY_DEFAULT, 5, () => {
Gio.DBus.session.unwatch_name(watchId);
log('Warning: Failed to start gsd-xsettings');
task.return_boolean(true);
timeoutId = 0;
return GLib.SOURCE_REMOVE;
});
/* When gsd-xsettings daemon is started, we are good to resume */
let watchId = Gio.DBus.session.watch_name(
'org.gnome.SettingsDaemon.XSettings',
Gio.BusNameWatcherFlags.NONE,
() => {
Gio.DBus.session.unwatch_name(watchId);
if (timeoutId > 0) {
task.return_boolean(true);
GLib.source_remove(timeoutId);
}
},
null);
} catch (e) {
log('Error starting gsd-xsettings: %s'.format(e.message));
task.return_boolean(true);
}
return true; return true;
}); });
global.display.connect('x11-display-closing', () => { global.display.connect('x11-display-closing', () => {
if (!Meta.is_wayland_compositor()) if (!Meta.is_wayland_compositor())
return; return;
try {
this._stopX11Services(null); Shell.util_stop_systemd_unit('gsd-xsettings.target', 'fail');
} catch (e) {
log('Error stopping gsd-xsettings: %s'.format(e.message));
}
IBusManager.getIBusManager().restartDaemon(); IBusManager.getIBusManager().restartDaemon();
}); });
@@ -990,36 +1008,6 @@ var WindowManager = class {
global.stage.add_action(topDragAction); global.stage.add_action(topDragAction);
} }
async _startX11Services(task, cancellable) {
try {
await Shell.util_start_systemd_unit(
'gnome-session-x11-services-ready.target', 'fail', cancellable);
} catch (e) {
// Ignore NOT_SUPPORTED error, which indicates we are not systemd
// managed and gnome-session will have taken care of everything
// already.
// Note that we do log cancellation from here.
if (!e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.NOT_SUPPORTED))
log('Error starting X11 services: %s'.format(e.message));
} finally {
task.return_boolean(true);
}
}
async _stopX11Services(cancellable) {
try {
await Shell.util_stop_systemd_unit(
'gnome-session-x11-services.target', 'fail', cancellable);
} catch (e) {
// Ignore NOT_SUPPORTED error, which indicates we are not systemd
// managed and gnome-session will have taken care of everything
// already.
// Note that we do log cancellation from here.
if (!e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.NOT_SUPPORTED))
log('Error stopping X11 services: %s'.format(e.message));
}
}
_showPadOsd(display, device, settings, imagePath, editionMode, monitorIndex) { _showPadOsd(display, device, settings, imagePath, editionMode, monitorIndex) {
this._currentPadOsd = new PadOsd.PadOsd(device, settings, imagePath, editionMode, monitorIndex); this._currentPadOsd = new PadOsd.PadOsd(device, settings, imagePath, editionMode, monitorIndex);
this._currentPadOsd.connect('closed', () => (this._currentPadOsd = null)); this._currentPadOsd.connect('closed', () => (this._currentPadOsd = null));
@@ -1812,7 +1800,8 @@ var WindowManager = class {
w.window.get_parent().remove_child(w.window); w.window.get_parent().remove_child(w.window);
w.parent.add_child(w.window); w.parent.add_child(w.window);
if (!w.window.get_meta_window().get_workspace().active) if (w.window.get_meta_window().get_workspace() !=
global.workspace_manager.get_active_workspace())
w.window.hide(); w.window.hide();
} }
switchData.container.destroy(); switchData.container.destroy();
@@ -1996,7 +1985,7 @@ var WindowManager = class {
duration, duration,
mode: Clutter.AnimationMode.EASE_OUT_CUBIC, mode: Clutter.AnimationMode.EASE_OUT_CUBIC,
onComplete: () => { onComplete: () => {
if (!newWs.active) if (newWs !== activeWorkspace)
this.actionMoveWorkspace(newWs); this.actionMoveWorkspace(newWs);
this._finishWorkspaceSwitch(switchData); this._finishWorkspaceSwitch(switchData);
}, },
@@ -2196,7 +2185,10 @@ var WindowManager = class {
if (!Main.sessionMode.hasWorkspaces) if (!Main.sessionMode.hasWorkspaces)
return; return;
if (!workspace.active) let workspaceManager = global.workspace_manager;
let activeWorkspace = workspaceManager.get_active_workspace();
if (activeWorkspace != workspace)
workspace.activate(global.get_current_time()); workspace.activate(global.get_current_time());
} }
@@ -2204,7 +2196,10 @@ var WindowManager = class {
if (!Main.sessionMode.hasWorkspaces) if (!Main.sessionMode.hasWorkspaces)
return; return;
if (!workspace.active) { let workspaceManager = global.workspace_manager;
let activeWorkspace = workspaceManager.get_active_workspace();
if (activeWorkspace != workspace) {
// This won't have any effect for "always sticky" windows // This won't have any effect for "always sticky" windows
// (like desktop windows or docks) // (like desktop windows or docks)

View File

@@ -67,12 +67,8 @@ var WindowPreviewLayout = GObject.registerClass({
vfunc_allocate(container, box) { vfunc_allocate(container, box) {
// If the scale isn't 1, we weren't allocated our preferred size // If the scale isn't 1, we weren't allocated our preferred size
// and have to scale the children allocations accordingly. // and have to scale the children allocations accordingly.
const scaleX = this._boundingBox.get_width() > 0 const scaleX = box.get_width() / this._boundingBox.get_width();
? box.get_width() / this._boundingBox.get_width() const scaleY = box.get_height() / this._boundingBox.get_height();
: 1;
const scaleY = this._boundingBox.get_height() > 0
? box.get_height() / this._boundingBox.get_height()
: 1;
const childBox = new Clutter.ActorBox(); const childBox = new Clutter.ActorBox();
@@ -97,7 +93,7 @@ var WindowPreviewLayout = GObject.registerClass({
child.allocate(childBox); child.allocate(childBox);
} else { } else {
child.allocate_preferred_size(0, 0); child.allocate_preferred_size();
} }
} }
} }
@@ -189,12 +185,6 @@ var WindowPreviewLayout = GObject.registerClass({
}); });
var WindowPreview = GObject.registerClass({ var WindowPreview = GObject.registerClass({
Properties: {
'overlay-enabled': GObject.ParamSpec.boolean(
'overlay-enabled', 'overlay-enabled', 'overlay-enabled',
GObject.ParamFlags.READWRITE,
true),
},
Signals: { Signals: {
'drag-begin': {}, 'drag-begin': {},
'drag-cancelled': {}, 'drag-cancelled': {},
@@ -229,6 +219,7 @@ var WindowPreview = GObject.registerClass({
this._delegate = this; this._delegate = this;
this.slotId = 0;
this._stackAbove = null; this._stackAbove = null;
this._windowContainer.layout_manager.connect( this._windowContainer.layout_manager.connect(
@@ -242,6 +233,8 @@ var WindowPreview = GObject.registerClass({
this._windowActor.connect('destroy', () => this.destroy()); this._windowActor.connect('destroy', () => this.destroy());
this._updateAttachedDialogs(); this._updateAttachedDialogs();
this.x = this.boundingBox.x;
this.y = this.boundingBox.y;
let clickAction = new Clutter.ClickAction(); let clickAction = new Clutter.ClickAction();
clickAction.connect('clicked', () => this._activate()); clickAction.connect('clicked', () => this._activate());
@@ -260,7 +253,6 @@ var WindowPreview = GObject.registerClass({
this.inDrag = false; this.inDrag = false;
this._selected = false; this._selected = false;
this._overlayEnabled = true;
this._closeRequested = false; this._closeRequested = false;
this._idleHideOverlayId = 0; this._idleHideOverlayId = 0;
@@ -353,14 +345,6 @@ var WindowPreview = GObject.registerClass({
this.add_child(this._border); this.add_child(this._border);
this.add_child(this._title); this.add_child(this._title);
this.add_child(this._closeButton); this.add_child(this._closeButton);
this.connect('notify::realized', () => {
if (!this.realized)
return;
this._border.ensure_style();
this._title.ensure_style();
});
} }
vfunc_get_preferred_width(forHeight) { vfunc_get_preferred_width(forHeight) {
@@ -415,6 +399,8 @@ var WindowPreview = GObject.registerClass({
} }
chromeHeights() { chromeHeights() {
this._border.ensure_style();
this._title.ensure_style();
const [, closeButtonHeight] = this._closeButton.get_preferred_height(-1); const [, closeButtonHeight] = this._closeButton.get_preferred_height(-1);
const [, titleHeight] = this._title.get_preferred_height(-1); const [, titleHeight] = this._title.get_preferred_height(-1);
@@ -427,6 +413,7 @@ var WindowPreview = GObject.registerClass({
} }
chromeWidths() { chromeWidths() {
this._border.ensure_style();
const [, closeButtonWidth] = this._closeButton.get_preferred_width(-1); const [, closeButtonWidth] = this._closeButton.get_preferred_width(-1);
const leftOversize = this._closeButtonSide === St.Side.LEFT const leftOversize = this._closeButtonSide === St.Side.LEFT
@@ -440,9 +427,6 @@ var WindowPreview = GObject.registerClass({
} }
showOverlay(animate) { showOverlay(animate) {
if (!this._overlayEnabled)
return;
const ongoingTransition = this._border.get_transition('opacity'); const ongoingTransition = this._border.get_transition('opacity');
// Don't do anything if we're fully visible already // Don't do anything if we're fully visible already
@@ -578,25 +562,6 @@ var WindowPreview = GObject.registerClass({
}); });
} }
// eslint-disable-next-line camelcase
get overlay_enabled() {
return this._overlayEnabled;
}
// eslint-disable-next-line camelcase
set overlay_enabled(enabled) {
if (this._overlayEnabled === enabled)
return;
this._overlayEnabled = enabled;
this.notify('overlay-enabled');
if (!enabled)
this.hideOverlay(false);
else if (this['has-pointer'] || global.stage.key_focus === this)
this.showOverlay(true);
}
// Find the actor just below us, respecting reparenting done by DND code // Find the actor just below us, respecting reparenting done by DND code
_getActualStackAbove() { _getActualStackAbove() {
if (this._stackAbove == null) if (this._stackAbove == null)

File diff suppressed because it is too large Load Diff

View File

@@ -11,10 +11,7 @@ var DISPLAY_TIMEOUT = 600;
var WorkspaceSwitcherPopupList = GObject.registerClass( var WorkspaceSwitcherPopupList = GObject.registerClass(
class WorkspaceSwitcherPopupList extends St.Widget { class WorkspaceSwitcherPopupList extends St.Widget {
_init() { _init() {
super._init({ super._init({ style_class: 'workspace-switcher' });
style_class: 'workspace-switcher',
offscreen_redirect: Clutter.OffscreenRedirect.ALWAYS,
});
this._itemSpacing = 0; this._itemSpacing = 0;
this._childHeight = 0; this._childHeight = 0;

View File

@@ -549,7 +549,9 @@ var WorkspaceThumbnail = GObject.registerClass({
return; return;
// a click on the already current workspace should go back to the main view // a click on the already current workspace should go back to the main view
if (this.metaWorkspace.active) let workspaceManager = global.workspace_manager;
let activeWorkspace = workspaceManager.get_active_workspace();
if (this.metaWorkspace == activeWorkspace)
Main.overview.hide(); Main.overview.hide();
else else
this.metaWorkspace.activate(time); this.metaWorkspace.activate(time);

View File

@@ -7,7 +7,6 @@ const Main = imports.ui.main;
const SwipeTracker = imports.ui.swipeTracker; const SwipeTracker = imports.ui.swipeTracker;
const Workspace = imports.ui.workspace; const Workspace = imports.ui.workspace;
var { ANIMATION_TIME } = imports.ui.overview;
var WORKSPACE_SWITCH_TIME = 250; var WORKSPACE_SWITCH_TIME = 250;
var SCROLL_TIMEOUT_TIME = 150; var SCROLL_TIMEOUT_TIME = 150;
@@ -22,18 +21,18 @@ var WorkspacesViewBase = GObject.registerClass({
GTypeFlags: GObject.TypeFlags.ABSTRACT, GTypeFlags: GObject.TypeFlags.ABSTRACT,
}, class WorkspacesViewBase extends St.Widget { }, class WorkspacesViewBase extends St.Widget {
_init(monitorIndex) { _init(monitorIndex) {
const { x, y, width, height } = super._init({ style_class: 'workspaces-view', reactive: true });
Main.layoutManager.getWorkAreaForMonitor(monitorIndex);
super._init({
style_class: 'workspaces-view',
x, y, width, height,
});
this.connect('destroy', this._onDestroy.bind(this)); this.connect('destroy', this._onDestroy.bind(this));
global.focus_manager.add_group(this); global.focus_manager.add_group(this);
// The actor itself isn't a drop target, so we don't want to pick on its area
this.set_size(0, 0);
this._monitorIndex = monitorIndex; this._monitorIndex = monitorIndex;
this._fullGeometry = null;
this._actualGeometry = null;
this._inDrag = false; this._inDrag = false;
this._windowDragBeginId = Main.overview.connect('window-drag-begin', this._dragBegin.bind(this)); this._windowDragBeginId = Main.overview.connect('window-drag-begin', this._dragBegin.bind(this));
this._windowDragEndId = Main.overview.connect('window-drag-end', this._dragEnd.bind(this)); this._windowDragEndId = Main.overview.connect('window-drag-end', this._dragEnd.bind(this));
@@ -52,19 +51,24 @@ var WorkspacesViewBase = GObject.registerClass({
} }
} }
_dragBegin() { _dragBegin(overview, window) {
this._inDrag = true; this._inDrag = true;
this._setReservedSlot(window);
} }
_dragEnd() { _dragEnd() {
this._inDrag = false; this._inDrag = false;
this._setReservedSlot(null);
} }
vfunc_allocate(box) { setFullGeometry(geom) {
this.set_allocation(box); this._fullGeometry = geom;
this._syncFullGeometry();
}
for (const child of this) setActualGeometry(geom) {
child.allocate_available_size(0, 0, box.get_width(), box.get_height()); this._actualGeometry = geom;
this._syncActualGeometry();
} }
}); });
@@ -79,8 +83,9 @@ class WorkspacesView extends WorkspacesViewBase {
this._gestureActive = false; // touch(pad) gestures this._gestureActive = false; // touch(pad) gestures
this._scrollAdjustment = scrollAdjustment; this._scrollAdjustment = scrollAdjustment;
this._onScrollId = this._scrollAdjustment.connect('notify::value', this._onScrollId =
this._updateScrollPosition.bind(this)); this._scrollAdjustment.connect('notify::value',
this._onScroll.bind(this));
this._workspaces = []; this._workspaces = [];
this._updateWorkspaces(); this._updateWorkspaces();
@@ -92,42 +97,34 @@ class WorkspacesView extends WorkspacesViewBase {
this._workspaces.sort((a, b) => { this._workspaces.sort((a, b) => {
return a.metaWorkspace.index() - b.metaWorkspace.index(); return a.metaWorkspace.index() - b.metaWorkspace.index();
}); });
this._workspaces.forEach( this._updateWorkspaceActors(false);
(ws, i) => this.set_child_at_index(ws, i));
}); });
this._overviewShownId = Main.overview.connect('shown', () => {
this.clip_to_allocation = true; this._overviewShownId =
}); Main.overview.connect('shown', () => {
this.set_clip(this._fullGeometry.x, this._fullGeometry.y,
this._fullGeometry.width, this._fullGeometry.height);
});
this._switchWorkspaceNotifyId = this._switchWorkspaceNotifyId =
global.window_manager.connect('switch-workspace', global.window_manager.connect('switch-workspace',
this._activeWorkspaceChanged.bind(this)); this._activeWorkspaceChanged.bind(this));
} }
vfunc_allocate(box) { _setReservedSlot(window) {
this.set_allocation(box); for (let i = 0; i < this._workspaces.length; i++)
this._workspaces[i].setReservedSlot(window);
}
if (this.get_n_children() === 0) _syncFullGeometry() {
return; for (let i = 0; i < this._workspaces.length; i++)
this._workspaces[i].setFullGeometry(this._fullGeometry);
}
const { workspaceManager } = global; _syncActualGeometry() {
const { nWorkspaces } = workspaceManager; for (let i = 0; i < this._workspaces.length; i++)
this._workspaces[i].setActualGeometry(this._actualGeometry);
const vertical = workspaceManager.layout_rows === -1;
const rtl = this.text_direction === Clutter.TextDirection.RTL;
this._workspaces.forEach((child, index) => {
if (rtl && !vertical)
index = nWorkspaces - index - 1;
const x = vertical ? 0 : index * this.width;
const y = vertical ? index * this.height : 0;
child.allocate_available_size(x, y, box.get_width(), box.get_height());
});
this._updateScrollPosition();
} }
getActiveWorkspace() { getActiveWorkspace() {
@@ -143,11 +140,11 @@ class WorkspacesView extends WorkspacesViewBase {
else else
this._workspaces[w].fadeToOverview(); this._workspaces[w].fadeToOverview();
} }
this._updateScrollPosition(); this._updateWorkspaceActors(false);
} }
animateFromOverview(animationType) { animateFromOverview(animationType) {
this.clip_to_allocation = false; this.remove_clip();
for (let w = 0; w < this._workspaces.length; w++) { for (let w = 0; w < this._workspaces.length; w++) {
if (animationType == AnimationType.ZOOM) if (animationType == AnimationType.ZOOM)
@@ -162,22 +159,49 @@ class WorkspacesView extends WorkspacesViewBase {
this._workspaces[i].syncStacking(stackIndices); this._workspaces[i].syncStacking(stackIndices);
} }
_scrollToActive() { // Update workspace actors parameters
const { workspaceManager } = global; // @showAnimation: iff %true, transition between states
const active = workspaceManager.get_active_workspace_index(); _updateWorkspaceActors(showAnimation) {
let workspaceManager = global.workspace_manager;
let active = workspaceManager.get_active_workspace_index();
this._animating = true; this._animating = showAnimation;
this._updateVisibility();
this._scrollAdjustment.remove_transition('value'); for (let w = 0; w < this._workspaces.length; w++) {
this._scrollAdjustment.ease(active, { let workspace = this._workspaces[w];
duration: WORKSPACE_SWITCH_TIME,
mode: Clutter.AnimationMode.EASE_OUT_CUBIC, workspace.remove_all_transitions();
onComplete: () => {
this._animating = false; let params = {};
this._updateVisibility(); if (workspaceManager.layout_rows == -1)
}, params.y = (w - active) * this._fullGeometry.height;
}); else if (this.text_direction == Clutter.TextDirection.RTL)
params.x = (active - w) * this._fullGeometry.width;
else
params.x = (w - active) * this._fullGeometry.width;
if (showAnimation) {
let easeParams = Object.assign(params, {
duration: WORKSPACE_SWITCH_TIME,
mode: Clutter.AnimationMode.EASE_OUT_CUBIC,
});
// we have to call _updateVisibility() once before the
// animation and once afterwards - it does not really
// matter which tween we use, so we pick the first one ...
if (w == 0) {
this._updateVisibility();
easeParams.onComplete = () => {
this._animating = false;
this._updateVisibility();
};
}
workspace.ease(easeParams);
} else {
workspace.set(params);
if (w == 0)
this._updateVisibility();
}
}
} }
_updateVisibility() { _updateVisibility() {
@@ -218,14 +242,19 @@ class WorkspacesView extends WorkspacesViewBase {
} }
} }
this._updateScrollPosition(); if (this._fullGeometry) {
this._updateWorkspaceActors(false);
this._syncFullGeometry();
}
if (this._actualGeometry)
this._syncActualGeometry();
} }
_activeWorkspaceChanged(_wm, _from, _to, _direction) { _activeWorkspaceChanged(_wm, _from, _to, _direction) {
if (this._scrolling) if (this._scrolling)
return; return;
this._scrollToActive(); this._updateWorkspaceActors(true);
} }
_onDestroy() { _onDestroy() {
@@ -241,33 +270,27 @@ class WorkspacesView extends WorkspacesViewBase {
startTouchGesture() { startTouchGesture() {
this._gestureActive = true; this._gestureActive = true;
this._updateVisibility();
} }
endTouchGesture() { endTouchGesture() {
this._gestureActive = false; this._gestureActive = false;
// Make sure title captions etc are shown as necessary // Make sure title captions etc are shown as necessary
this._scrollToActive(); this._updateWorkspaceActors(true);
this._updateVisibility(); this._updateVisibility();
} }
// sync the workspaces' positions to the value of the scroll adjustment // sync the workspaces' positions to the value of the scroll adjustment
// and change the active workspace if appropriate // and change the active workspace if appropriate
_updateScrollPosition() { _onScroll(adj) {
if (!this.has_allocation()) if (adj.get_transition('value') !== null && !this._gestureActive)
return; return;
const adj = this._scrollAdjustment;
const allowSwitch =
adj.get_transition('value') === null && !this._gestureActive;
let workspaceManager = global.workspace_manager; let workspaceManager = global.workspace_manager;
let active = workspaceManager.get_active_workspace_index(); let active = workspaceManager.get_active_workspace_index();
let current = Math.round(adj.value); let current = Math.round(adj.value);
if (allowSwitch && active !== current) { if (active != current && !this._gestureActive) {
if (!this._workspaces[current]) { if (!this._workspaces[current]) {
// The current workspace was destroyed. This could happen // The current workspace was destroyed. This could happen
// when you are on the last empty workspace, and consolidate // when you are on the last empty workspace, and consolidate
@@ -284,16 +307,36 @@ class WorkspacesView extends WorkspacesViewBase {
if (adj.upper == 1) if (adj.upper == 1)
return; return;
const vertical = workspaceManager.layout_rows === -1; let last = this._workspaces.length - 1;
const rtl = this.text_direction === Clutter.TextDirection.RTL;
const progress = vertical || !rtl
? adj.value : adj.upper - adj.value;
for (const ws of this._workspaces) { if (workspaceManager.layout_rows == -1) {
if (vertical) let firstWorkspaceY = this._workspaces[0].y;
ws.translation_y = -progress * this.height; let lastWorkspaceY = this._workspaces[last].y;
else let workspacesHeight = lastWorkspaceY - firstWorkspaceY;
ws.translation_x = -progress * this.width;
let currentY = firstWorkspaceY;
let newY = -Math.round(adj.value / (adj.upper - 1) * workspacesHeight);
let dy = newY - currentY;
for (let i = 0; i < this._workspaces.length; i++) {
this._workspaces[i].visible = Math.abs(i - adj.value) <= 1;
this._workspaces[i].y += dy;
}
} else {
let firstWorkspaceX = this._workspaces[0].x;
let lastWorkspaceX = this._workspaces[last].x;
let workspacesWidth = lastWorkspaceX - firstWorkspaceX;
let currentX = firstWorkspaceX;
let newX = -Math.round(adj.value / (adj.upper - 1) * workspacesWidth);
let dx = newX - currentX;
for (let i = 0; i < this._workspaces.length; i++) {
this._workspaces[i].visible = Math.abs(i - adj.value) <= 1;
this._workspaces[i].x += dx;
}
} }
} }
}); });
@@ -306,6 +349,18 @@ class ExtraWorkspaceView extends WorkspacesViewBase {
this.add_actor(this._workspace); this.add_actor(this._workspace);
} }
_setReservedSlot(window) {
this._workspace.setReservedSlot(window);
}
_syncFullGeometry() {
this._workspace.setFullGeometry(this._fullGeometry);
}
_syncActualGeometry() {
this._workspace.setActualGeometry(this._actualGeometry);
}
getActiveWorkspace() { getActiveWorkspace() {
return this._workspace; return this._workspace;
} }
@@ -383,10 +438,6 @@ class WorkspacesDisplay extends St.Widget {
this._windowDragEndId = this._windowDragEndId =
Main.overview.connect('window-drag-begin', Main.overview.connect('window-drag-begin',
this._windowDragEnd.bind(this)); this._windowDragEnd.bind(this));
this._overviewShownId = Main.overview.connect('shown', () => {
this._inWindowFade = false;
this._syncWorkspacesActualGeometry();
});
this._primaryIndex = Main.layoutManager.primaryIndex; this._primaryIndex = Main.layoutManager.primaryIndex;
this._workspacesViews = []; this._workspacesViews = [];
@@ -401,11 +452,10 @@ class WorkspacesDisplay extends St.Widget {
this._scrollEventId = 0; this._scrollEventId = 0;
this._keyPressEventId = 0; this._keyPressEventId = 0;
this._scrollTimeoutId = 0; this._scrollTimeoutId = 0;
this._syncActualGeometryLater = 0;
this._actualGeometry = null; this._actualGeometry = null;
this._fullGeometry = null;
this._inWindowDrag = false; this._inWindowDrag = false;
this._inWindowFade = false;
this._gestureActive = false; // touch(pad) gestures this._gestureActive = false; // touch(pad) gestures
this._canScroll = true; // limiting scrolling speed this._canScroll = true; // limiting scrolling speed
@@ -426,11 +476,6 @@ class WorkspacesDisplay extends St.Widget {
this._parentSetLater = 0; this._parentSetLater = 0;
} }
if (this._syncActualGeometryLater) {
Meta.later_remove(this._syncActualGeometryLater);
this._syncActualGeometryLater = 0;
}
if (this._scrollTimeoutId !== 0) { if (this._scrollTimeoutId !== 0) {
GLib.source_remove(this._scrollTimeoutId); GLib.source_remove(this._scrollTimeoutId);
this._scrollTimeoutId = 0; this._scrollTimeoutId = 0;
@@ -440,7 +485,6 @@ class WorkspacesDisplay extends St.Widget {
global.workspace_manager.disconnect(this._reorderWorkspacesdId); global.workspace_manager.disconnect(this._reorderWorkspacesdId);
Main.overview.disconnect(this._windowDragBeginId); Main.overview.disconnect(this._windowDragBeginId);
Main.overview.disconnect(this._windowDragEndId); Main.overview.disconnect(this._windowDragEndId);
Main.overview.disconnect(this._overviewShownId);
} }
_windowDragBegin() { _windowDragBegin() {
@@ -464,11 +508,25 @@ class WorkspacesDisplay extends St.Widget {
workspaceManager.get_active_workspace_index(); workspaceManager.get_active_workspace_index();
} }
_activeWorkspaceChanged(_wm, _from, to, _direction) { _activeWorkspaceChanged(_wm, _from, _to, _direction) {
if (this._gestureActive) if (this._gestureActive)
return; return;
this._scrollAdjustment.ease(to, { this._scrollToActive();
}
_scrollToActive() {
let workspaceManager = global.workspace_manager;
let active = workspaceManager.get_active_workspace_index();
this._updateScrollAdjustment(active);
}
_updateScrollAdjustment(index) {
if (this._gestureActive)
return;
this._scrollAdjustment.ease(index, {
mode: Clutter.AnimationMode.EASE_OUT_CUBIC, mode: Clutter.AnimationMode.EASE_OUT_CUBIC,
duration: WORKSPACE_SWITCH_TIME, duration: WORKSPACE_SWITCH_TIME,
}); });
@@ -506,8 +564,11 @@ class WorkspacesDisplay extends St.Widget {
for (let i = 0; i < this._workspacesViews.length; i++) for (let i = 0; i < this._workspacesViews.length; i++)
this._workspacesViews[i].startTouchGesture(); this._workspacesViews[i].startTouchGesture();
let monitors = Main.layoutManager.monitors;
let geometry = monitor === this._primaryIndex
? this._fullGeometry : monitors[monitor];
let distance = global.workspace_manager.layout_rows === -1 let distance = global.workspace_manager.layout_rows === -1
? this.height : this.width; ? geometry.height : geometry.width;
let progress = adjustment.value / adjustment.page_size; let progress = adjustment.value / adjustment.page_size;
let points = Array.from( let points = Array.from(
@@ -527,13 +588,14 @@ class WorkspacesDisplay extends St.Widget {
this._clickAction.release(); this._clickAction.release();
let workspaceManager = global.workspace_manager; let workspaceManager = global.workspace_manager;
let activeWorkspace = workspaceManager.get_active_workspace();
let newWs = workspaceManager.get_workspace_by_index(endProgress); let newWs = workspaceManager.get_workspace_by_index(endProgress);
this._scrollAdjustment.ease(endProgress, { this._scrollAdjustment.ease(endProgress, {
mode: Clutter.AnimationMode.EASE_OUT_CUBIC, mode: Clutter.AnimationMode.EASE_OUT_CUBIC,
duration, duration,
onComplete: () => { onComplete: () => {
if (!newWs.active) if (newWs !== activeWorkspace)
newWs.activate(global.get_current_time()); newWs.activate(global.get_current_time());
this._endTouchGesture(); this._endTouchGesture();
}, },
@@ -554,20 +616,17 @@ class WorkspacesDisplay extends St.Widget {
this.show(); this.show();
this._updateWorkspacesViews(); this._updateWorkspacesViews();
for (let i = 0; i < this._workspacesViews.length; i++) { if (this._actualGeometry && this._fullGeometry) {
let animationType; for (let i = 0; i < this._workspacesViews.length; i++) {
if (fadeOnPrimary && i == this._primaryIndex) let animationType;
animationType = AnimationType.FADE; if (fadeOnPrimary && i == this._primaryIndex)
else animationType = AnimationType.FADE;
animationType = AnimationType.ZOOM; else
this._workspacesViews[i].animateToOverview(animationType); animationType = AnimationType.ZOOM;
this._workspacesViews[i].animateToOverview(animationType);
}
} }
this._inWindowFade = fadeOnPrimary;
if (this._actualGeometry && !fadeOnPrimary)
this._syncWorkspacesActualGeometry();
this._restackedNotifyId = this._restackedNotifyId =
Main.overview.connect('windows-restacked', Main.overview.connect('windows-restacked',
this._onRestacked.bind(this)); this._onRestacked.bind(this));
@@ -587,17 +646,6 @@ class WorkspacesDisplay extends St.Widget {
animationType = AnimationType.ZOOM; animationType = AnimationType.ZOOM;
this._workspacesViews[i].animateFromOverview(animationType); this._workspacesViews[i].animateFromOverview(animationType);
} }
this._inWindowFade = fadeOnPrimary;
const { primaryIndex } = Main.layoutManager;
const { x, y, width, height } =
Main.layoutManager.getWorkAreaForMonitor(primaryIndex);
this._getPrimaryView().ease({
x, y, width, height,
duration: fadeOnPrimary ? 0 : ANIMATION_TIME,
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
});
} }
vfunc_hide() { vfunc_hide() {
@@ -627,7 +675,6 @@ class WorkspacesDisplay extends St.Widget {
return; return;
this._updateWorkspacesViews(); this._updateWorkspacesViews();
this._syncWorkspacesActualGeometry();
} }
_updateWorkspacesViews() { _updateWorkspacesViews() {
@@ -644,9 +691,19 @@ class WorkspacesDisplay extends St.Widget {
else else
view = new WorkspacesView(i, this._scrollAdjustment); view = new WorkspacesView(i, this._scrollAdjustment);
// HACK: Avoid spurious allocation changes while updating views
view.hide();
this._workspacesViews.push(view); this._workspacesViews.push(view);
Main.layoutManager.overviewGroup.add_actor(view); Main.layoutManager.overviewGroup.add_actor(view);
} }
this._workspacesViews.forEach(v => v.show());
if (this._fullGeometry)
this._syncWorkspacesFullGeometry();
if (this._actualGeometry)
this._syncWorkspacesActualGeometry();
} }
_getMonitorIndexForEvent(event) { _getMonitorIndexForEvent(event) {
@@ -693,35 +750,43 @@ class WorkspacesDisplay extends St.Widget {
}); });
} }
// This geometry should always be the fullest geometry
// the workspaces switcher can ever be allocated, as if
// the sliding controls were never slid in at all.
setWorkspacesFullGeometry(geom) {
this._fullGeometry = geom;
this._syncWorkspacesFullGeometry();
}
_syncWorkspacesFullGeometry() {
if (!this._workspacesViews.length)
return;
let monitors = Main.layoutManager.monitors;
for (let i = 0; i < monitors.length; i++) {
let geometry = i == this._primaryIndex ? this._fullGeometry : monitors[i];
this._workspacesViews[i].setFullGeometry(geometry);
}
}
_updateWorkspacesActualGeometry() { _updateWorkspacesActualGeometry() {
const [x, y] = this.get_transformed_position(); const [x, y] = this.get_transformed_position();
const width = this.allocation.get_width(); const width = this.allocation.get_width();
const height = this.allocation.get_height(); const height = this.allocation.get_height();
this._actualGeometry = { x, y, width, height }; this._actualGeometry = { x, y, width, height };
this._syncWorkspacesActualGeometry();
if (this._syncActualGeometryLater > 0)
return;
this._syncActualGeometryLater =
Meta.later_add(Meta.LaterType.BEFORE_REDRAW, () => {
this._syncWorkspacesActualGeometry();
this._syncActualGeometryLater = 0;
return GLib.SOURCE_REMOVE;
});
} }
_syncWorkspacesActualGeometry() { _syncWorkspacesActualGeometry() {
const primaryView = this._getPrimaryView(); if (!this._workspacesViews.length)
if (!primaryView || this._inWindowFade)
return; return;
primaryView.ease({ let monitors = Main.layoutManager.monitors;
...this._actualGeometry, for (let i = 0; i < monitors.length; i++) {
duration: Main.overview.animationInProgress ? ANIMATION_TIME : 0, let geometry = i === this._primaryIndex ? this._actualGeometry : monitors[i];
mode: Clutter.AnimationMode.EASE_OUT_QUAD, this._workspacesViews[i].setActualGeometry(geometry);
}); }
} }
_onRestacked(overview, stackIndices) { _onRestacked(overview, stackIndices) {

View File

@@ -1,5 +1,5 @@
project('gnome-shell', 'c', project('gnome-shell', 'c',
version: '3.37.90', version: '3.37.2',
meson_version: '>= 0.53.0', meson_version: '>= 0.53.0',
license: 'GPLv2+' license: 'GPLv2+'
) )
@@ -25,7 +25,7 @@ gio_req = '>= 2.56.0'
gi_req = '>= 1.49.1' gi_req = '>= 1.49.1'
gjs_req = '>= 1.65.1' gjs_req = '>= 1.65.1'
gtk_req = '>= 3.15.0' gtk_req = '>= 3.15.0'
mutter_req = '>= 3.37.90' mutter_req = '>= 3.37.2'
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'
@@ -96,10 +96,9 @@ gnome_desktop_dep = dependency('gnome-desktop-3.0', version: gnome_desktop_req)
bt_dep = dependency('gnome-bluetooth-1.0', version: bt_req, required: false) bt_dep = dependency('gnome-bluetooth-1.0', version: bt_req, required: false)
gst_dep = dependency('gstreamer-1.0', version: gst_req, required: false) gst_dep = dependency('gstreamer-1.0', version: gst_req, required: false)
gst_base_dep = dependency('gstreamer-base-1.0', required: false) gst_base_dep = dependency('gstreamer-base-1.0', required: false)
pipewire_dep = dependency('libpipewire-0.3', required: false)
recorder_deps = [] recorder_deps = []
enable_recorder = gst_dep.found() and gst_base_dep.found() and pipewire_dep.found() enable_recorder = gst_dep.found() and gst_base_dep.found()
if enable_recorder if enable_recorder
recorder_deps += [gst_dep, gst_base_dep, gtk_dep, x11_dep] recorder_deps += [gst_dep, gst_base_dep, gtk_dep, x11_dep]
endif endif

1
mutter Submodule

Submodule mutter added at 1551b6d386

View File

@@ -1,3 +1 @@
data/org.gnome.Shell@wayland.service.in
data/org.gnome.Shell@x11.service.in
subprojects/extensions-tool/src/templates/indicator/extension.js subprojects/extensions-tool/src/templates/indicator/extension.js

589
po/ca.po

File diff suppressed because it is too large Load Diff

752
po/de.po

File diff suppressed because it is too large Load Diff

1128
po/el.po

File diff suppressed because it is too large Load Diff

436
po/es.po

File diff suppressed because it is too large Load Diff

743
po/eu.po

File diff suppressed because it is too large Load Diff

483
po/fur.po

File diff suppressed because it is too large Load Diff

1280
po/gl.po

File diff suppressed because it is too large Load Diff

313
po/kk.po
View File

@@ -1,14 +1,14 @@
# Kazakh translation for gnome-shell. # Kazakh translation for gnome-shell.
# Copyright (C) 2015 The gnome-shell authors. # Copyright (C) 2015 The gnome-shell authors.
# This file is distributed under the same license as the gnome-shell package. # This file is distributed under the same license as the gnome-shell package.
# Baurzhan Muftakhidinov <baurthefirst@gmail.com>, 2012-2020. # Baurzhan Muftakhidinov <baurthefirst@gmail.com>, 2012-2019.
# #
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: master\n" "Project-Id-Version: 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-06-25 04:35+0000\n" "POT-Creation-Date: 2020-06-05 23:11+0000\n"
"PO-Revision-Date: 2020-06-27 23:27+0500\n" "PO-Revision-Date: 2020-06-15 18:37+0500\n"
"Last-Translator: Baurzhan Muftakhidinov <baurthefirst@gmail.com>\n" "Last-Translator: Baurzhan Muftakhidinov <baurthefirst@gmail.com>\n"
"Language-Team: Kazakh <kk_KZ@googlegroups.com>\n" "Language-Team: Kazakh <kk_KZ@googlegroups.com>\n"
"Language: kk\n" "Language: kk\n"
@@ -81,10 +81,16 @@ msgstr ""
"DisableExtension DBus тәсілдерімен де өзгертуге болады." "DisableExtension DBus тәсілдерімен де өзгертуге болады."
#: data/org.gnome.shell.gschema.xml.in:26 #: data/org.gnome.shell.gschema.xml.in:26
#| msgid "UUIDs of extensions to enable"
msgid "UUIDs of extensions to force disabling" msgid "UUIDs of extensions to force disabling"
msgstr "Мәжбүрлі сөндіру үшін кеңейтулер UUID-лары" msgstr ""
#: data/org.gnome.shell.gschema.xml.in:27 #: data/org.gnome.shell.gschema.xml.in:27
#| msgid ""
#| "GNOME Shell extensions have a UUID property; this key lists extensions "
#| "which should be loaded. Any extension that wants to be loaded needs to be "
#| "in this list. You can also manipulate this list with the EnableExtension "
#| "and DisableExtension D-Bus methods on org.gnome.Shell."
msgid "" msgid ""
"GNOME Shell extensions have a UUID property; this key lists extensions which " "GNOME Shell extensions have a UUID property; this key lists extensions which "
"should be disabled, even if loaded as part of the current mode. You can also " "should be disabled, even if loaded as part of the current mode. You can also "
@@ -92,11 +98,6 @@ msgid ""
"methods on org.gnome.Shell. This key takes precedence over the “enabled-" "methods on org.gnome.Shell. This key takes precedence over the “enabled-"
"extensions” setting." "extensions” setting."
msgstr "" msgstr ""
"GNOME Shell кеңейтулерінде UUID қасиеті бар; бұл кілт сөндіру үшін "
"кеңейтулер тізімін сақтайды, олар қазіргі режимде іске қосылған болса да. "
"Сонымен қатар, бұл тізімді org.gnome.Shell EnableExtension және "
"DisableExtension D-Bus тәсілдері арқылы түзетуге болады. Бұл кілт \"enabled-"
"extensions\" баптауын үстінен басады."
#: data/org.gnome.shell.gschema.xml.in:37 #: data/org.gnome.shell.gschema.xml.in:37
msgid "Disable user extensions" msgid "Disable user extensions"
@@ -332,19 +333,19 @@ msgstr ""
#: data/org.gnome.shell.gschema.xml.in:234 #: data/org.gnome.shell.gschema.xml.in:234
msgid "Locations" msgid "Locations"
msgstr "Орналасулар" msgstr "Орналасу"
#: data/org.gnome.shell.gschema.xml.in:235 #: data/org.gnome.shell.gschema.xml.in:235
msgid "The locations to show in world clocks" msgid "The locations to show in world clocks"
msgstr "Дүниежүзілік сағаттарда көрсетілетін орналасулар" msgstr ""
#: data/org.gnome.shell.gschema.xml.in:245 #: data/org.gnome.shell.gschema.xml.in:245
msgid "Automatic location" msgid "Automatic location"
msgstr "Автоматты орналасу" msgstr ""
#: data/org.gnome.shell.gschema.xml.in:246 #: data/org.gnome.shell.gschema.xml.in:246
msgid "Whether to fetch the current location or not" msgid "Whether to fetch the current location or not"
msgstr "Ағымдағы орналасуды алу керек пе, жоқ па" msgstr ""
#: data/org.gnome.shell.gschema.xml.in:253 #: data/org.gnome.shell.gschema.xml.in:253
msgid "Location" msgid "Location"
@@ -352,7 +353,7 @@ msgstr "Орналасу"
#: data/org.gnome.shell.gschema.xml.in:254 #: data/org.gnome.shell.gschema.xml.in:254
msgid "The location for which to show a forecast" msgid "The location for which to show a forecast"
msgstr "Ауа райы болжамын көрсету үшін орналасу" msgstr ""
#: data/org.gnome.shell.gschema.xml.in:266 #: data/org.gnome.shell.gschema.xml.in:266
msgid "Attach modal dialog to the parent window" msgid "Attach modal dialog to the parent window"
@@ -531,20 +532,23 @@ msgstr "пайдаланушыны ауыстыру"
#. 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
#: js/misc/systemActions.js:135 #: js/misc/systemActions.js:135
#| msgid "lock orientation;screen;rotation"
msgid "lock orientation;unlock orientation;screen;rotation" msgid "lock orientation;unlock orientation;screen;rotation"
msgstr "" msgstr ""
"lock orientation;unlock orientation;screen;rotation;бұрылуды құлыптау;экран "
"бұрылуы"
#: js/misc/systemActions.js:255 #: js/misc/systemActions.js:255
#| msgctxt "search-result"
#| msgid "Lock Orientation"
msgctxt "search-result" msgctxt "search-result"
msgid "Unlock Screen Rotation" msgid "Unlock Screen Rotation"
msgstr "Экранды бұруды құлыптан босату" msgstr ""
#: js/misc/systemActions.js:256 #: js/misc/systemActions.js:256
#| msgctxt "search-result"
#| msgid "Lock Orientation"
msgctxt "search-result" msgctxt "search-result"
msgid "Lock Screen Rotation" msgid "Lock Screen Rotation"
msgstr "Экранды бұруды құлыптау" msgstr ""
#: js/misc/util.js:120 #: js/misc/util.js:120
msgid "Command not found" msgid "Command not found"
@@ -701,36 +705,38 @@ msgstr "Тыйым салу"
msgid "Grant Access" msgid "Grant Access"
msgstr "Рұқсат ету" msgstr "Рұқсат ету"
#: js/ui/appDisplay.js:903 #: js/ui/appDisplay.js:956
msgid "Unnamed Folder" msgid "Unnamed Folder"
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:2225 js/ui/panel.js:75 #: js/ui/appDisplay.js:2215 js/ui/panel.js:75
msgid "Open Windows" msgid "Open Windows"
msgstr "Ашық терезелер" msgstr "Ашық терезелер"
#: js/ui/appDisplay.js:2244 js/ui/panel.js:82 #: js/ui/appDisplay.js:2234 js/ui/panel.js:82
msgid "New Window" msgid "New Window"
msgstr "Жаңа терезе" msgstr "Жаңа терезе"
#: js/ui/appDisplay.js:2260 #: js/ui/appDisplay.js:2250
#| msgid "Launch using Dedicated Graphics Card"
msgid "Launch using Integrated Graphics Card" msgid "Launch using Integrated Graphics Card"
msgstr "Құрамындағы графикалық картаны пайдаланып жөнелту" msgstr ""
#: js/ui/appDisplay.js:2261 #: js/ui/appDisplay.js:2251
#| msgid "Launch using Dedicated Graphics Card"
msgid "Launch using Discrete Graphics Card" msgid "Launch using Discrete Graphics Card"
msgstr "Бөлек графикалық картаны пайдаланып жөнелту" msgstr ""
#: js/ui/appDisplay.js:2289 js/ui/dash.js:239 #: js/ui/appDisplay.js:2279 js/ui/dash.js:239
msgid "Remove from Favorites" msgid "Remove from Favorites"
msgstr "Таңдамалылардан өшіру" msgstr "Таңдамалылардан өшіру"
#: js/ui/appDisplay.js:2295 #: js/ui/appDisplay.js:2285
msgid "Add to Favorites" msgid "Add to Favorites"
msgstr "Таңдамалыларға қосу" msgstr "Таңдамалыларға қосу"
#: js/ui/appDisplay.js:2305 js/ui/panel.js:93 #: js/ui/appDisplay.js:2295 js/ui/panel.js:93
msgid "Show Details" msgid "Show Details"
msgstr "Деректерді көрсету" msgstr "Деректерді көрсету"
@@ -760,7 +766,7 @@ msgstr "Құлаққап"
msgid "Headset" msgid "Headset"
msgstr "Микрофонды құлаққап" msgstr "Микрофонды құлаққап"
#: js/ui/audioDeviceSelection.js:68 js/ui/status/volume.js:272 #: js/ui/audioDeviceSelection.js:68 js/ui/status/volume.js:273
msgid "Microphone" msgid "Microphone"
msgstr "Микрофон" msgstr "Микрофон"
@@ -912,8 +918,9 @@ msgid "External drive disconnected"
msgstr "Сыртқы диск алынды" msgstr "Сыртқы диск алынды"
#: js/ui/components/automountManager.js:208 #: js/ui/components/automountManager.js:208
#| msgid "Unable to lock"
msgid "Unable to unlock volume" msgid "Unable to unlock volume"
msgstr "Томды босату мүмкін емес" msgstr ""
#: js/ui/components/automountManager.js:209 #: js/ui/components/automountManager.js:209
msgid "The installed udisks version does not support the PIM setting" msgid "The installed udisks version does not support the PIM setting"
@@ -986,6 +993,7 @@ msgid "PIN code is needed for the mobile broadband device"
msgstr "Сымсыз кеңжолақты құрылғы үшін PIN коды керек" msgstr "Сымсыз кеңжолақты құрылғы үшін PIN коды керек"
#: js/ui/components/networkAgent.js:334 #: js/ui/components/networkAgent.js:334
#| msgid "PIN: "
msgid "PIN" msgid "PIN"
msgstr "PIN" msgstr "PIN"
@@ -1121,8 +1129,9 @@ msgid "Weather"
msgstr "Ауа райы" msgstr "Ауа райы"
#: js/ui/dateMenu.js:653 #: js/ui/dateMenu.js:653
#| msgid "Select a location…"
msgid "Select weather location…" msgid "Select weather location…"
msgstr "Ауа райы орнын таңдау…" msgstr ""
#: js/ui/endSessionDialog.js:37 #: js/ui/endSessionDialog.js:37
#, javascript-format #, javascript-format
@@ -1242,10 +1251,9 @@ msgstr ""
"эл. желісіне жалғанып тұрғанына көз жеткізіңіз." "эл. желісіне жалғанып тұрғанына көз жеткізіңіз."
#: js/ui/endSessionDialog.js:259 #: js/ui/endSessionDialog.js:259
#| msgid "Running on battery power: please plug in before installing updates."
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:268
msgid "Some applications are busy or have unsaved work" msgid "Some applications are busy or have unsaved work"
@@ -1281,26 +1289,30 @@ msgid "Download and install “%s” from extensions.gnome.org?"
msgstr "extensions.gnome.org адресінен \"%s\" жүктеп алып, орнату керек пе?" msgstr "extensions.gnome.org адресінен \"%s\" жүктеп алып, орнату керек пе?"
#: js/ui/extensionSystem.js:252 #: js/ui/extensionSystem.js:252
#| msgid "No Extensions Installed"
msgid "Extension Updates Available" msgid "Extension Updates Available"
msgstr "Кеңейту жаңартулары дайын" msgstr ""
#: js/ui/extensionSystem.js:253 #: js/ui/extensionSystem.js:253
msgid "Extension updates are ready to be installed." msgid "Extension updates are ready to be installed."
msgstr "Кеңейту жаңартулары орнатылуға дайын." msgstr ""
#: js/ui/inhibitShortcutsDialog.js:79 #: js/ui/inhibitShortcutsDialog.js:79
#| msgid "%s wants to inhibit shortcuts"
msgid "Allow inhibiting shortcuts" msgid "Allow inhibiting shortcuts"
msgstr "Пернелер жарлығын алмастыруды рұқсат ету" msgstr ""
#. Translators: %s is an application name like "Settings" #. Translators: %s is an application name like "Settings"
#: js/ui/inhibitShortcutsDialog.js:82 #: js/ui/inhibitShortcutsDialog.js:82
#, javascript-format #, javascript-format
#| msgid "Application wants to inhibit shortcuts"
msgid "The application %s wants to inhibit shortcuts" msgid "The application %s wants to inhibit shortcuts"
msgstr "%s қолданбасы пернелер жарлығын алмастырғысы келеді" msgstr ""
#: js/ui/inhibitShortcutsDialog.js:83 #: js/ui/inhibitShortcutsDialog.js:83
#| msgid "Application wants to inhibit shortcuts"
msgid "An application wants to inhibit shortcuts" msgid "An application wants to inhibit shortcuts"
msgstr "Қолданба пернелер жарлығын алмастырғысы келеді" msgstr ""
#. Translators: %s is a keyboard shortcut like "Super+x" #. Translators: %s is a keyboard shortcut like "Super+x"
#: js/ui/inhibitShortcutsDialog.js:90 #: js/ui/inhibitShortcutsDialog.js:90
@@ -1433,25 +1445,23 @@ msgid "Web Page"
msgstr "Веб парағы" msgstr "Веб парағы"
#: js/ui/main.js:297 #: js/ui/main.js:297
#| msgid "Log in as another user"
msgid "Logged in as a privileged user" msgid "Logged in as a privileged user"
msgstr "Привилегияланған пайдаланушы ретінде жүйеге кірген" msgstr ""
#: js/ui/main.js:298 #: js/ui/main.js:298
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."
msgstr "" msgstr ""
"Привилегияланған пайдаланушы ретінде сессияны орындаудан қауіпсіздік "
"салдарынан аулақ болу керек. Мүмкін болса, қалыпты пайдаланушы ретінде "
"жүйеге кіріңіз."
#: js/ui/main.js:337 #: js/ui/main.js:337
msgid "Screen Lock disabled" msgid "Screen Lock disabled"
msgstr "Экранды блоктау сөндірілген" msgstr ""
#: js/ui/main.js:338 #: js/ui/main.js:338
msgid "Screen Locking requires the GNOME display manager." msgid "Screen Locking requires the GNOME display manager."
msgstr "Экранды блоктау GNOME дисплейлер басқарушысын талап етеді." msgstr ""
#: js/ui/messageTray.js:1547 #: js/ui/messageTray.js:1547
msgid "System Information" msgid "System Information"
@@ -1465,13 +1475,13 @@ msgstr "Белгісіз әртіс"
msgid "Unknown title" msgid "Unknown title"
msgstr "Белгісіз атауы" msgstr "Белгісіз атауы"
#: js/ui/overview.js:74 #: js/ui/overview.js:73
msgid "Undo" msgid "Undo"
msgstr "Болдырмау" msgstr "Болдырмау"
#. Translators: This is the main view to select #. Translators: This is the main view to select
#. activities. See also note for "Activities" string. #. activities. See also note for "Activities" string.
#: js/ui/overview.js:87 #: js/ui/overview.js:86
msgid "Overview" msgid "Overview"
msgstr "Шолу" msgstr "Шолу"
@@ -1479,7 +1489,7 @@ msgstr "Шолу"
#. in the search entry when no search is #. in the search entry when no search is
#. active; it should not exceed ~30 #. active; it should not exceed ~30
#. characters. #. characters.
#: js/ui/overview.js:108 #: js/ui/overview.js:107
msgid "Type to search" msgid "Type to search"
msgstr "Іздеу үшін теріңіз" msgstr "Іздеу үшін теріңіз"
@@ -1616,16 +1626,18 @@ msgid "Caps lock is on."
msgstr "Caps lock іске қосылған." msgstr "Caps lock іске қосылған."
#: js/ui/shellMountOperation.js:285 #: js/ui/shellMountOperation.js:285
#| msgid "Volume"
msgid "Hidden Volume" msgid "Hidden Volume"
msgstr "Жасырын том" msgstr ""
#: js/ui/shellMountOperation.js:288 #: js/ui/shellMountOperation.js:288
msgid "Windows System Volume" msgid "Windows System Volume"
msgstr "Windows жүйелік томы" msgstr ""
#: js/ui/shellMountOperation.js:291 #: js/ui/shellMountOperation.js:291
#| msgid "Mouse Keys"
msgid "Uses Keyfiles" msgid "Uses Keyfiles"
msgstr "Кілт файлдарды қолданады" msgstr ""
#. Translators: %s is the Disks application #. Translators: %s is the Disks application
#: js/ui/shellMountOperation.js:298 #: js/ui/shellMountOperation.js:298
@@ -1633,7 +1645,6 @@ msgstr "Кілт файлдарды қолданады"
msgid "" msgid ""
"To unlock a volume that uses keyfiles, use the <i>%s</i> utility instead." "To unlock a volume that uses keyfiles, use the <i>%s</i> utility instead."
msgstr "" msgstr ""
"Кілт файлдарын қолданатын томды босату үшін, <i>%s</i> утилитасын қолданыңыз."
#: js/ui/shellMountOperation.js:306 #: js/ui/shellMountOperation.js:306
msgid "PIM Number" msgid "PIM Number"
@@ -1655,7 +1666,7 @@ msgstr "%s ашу"
#: js/ui/shellMountOperation.js:423 #: js/ui/shellMountOperation.js:423
msgid "The PIM must be a number or empty." msgid "The PIM must be a number or empty."
msgstr "PIM тек сандардан тұруы, немесе бос болуы тиіс." msgstr ""
#. Translators: %s is the Disks application #. Translators: %s is the Disks application
#: js/ui/shellMountOperation.js:465 #: js/ui/shellMountOperation.js:465
@@ -1667,7 +1678,7 @@ msgstr "%s іске қосу мүмкін емес"
#: js/ui/shellMountOperation.js:467 #: js/ui/shellMountOperation.js:467
#, javascript-format #, javascript-format
msgid "Couldnt find the %s application" msgid "Couldnt find the %s application"
msgstr "%s қолданбасы табылмады" msgstr ""
#: js/ui/status/accessibility.js:35 #: js/ui/status/accessibility.js:35
msgid "Accessibility" msgid "Accessibility"
@@ -1722,12 +1733,14 @@ msgid "Bluetooth Settings"
msgstr "Bluetooth баптаулары" msgstr "Bluetooth баптаулары"
#: js/ui/status/bluetooth.js:152 #: js/ui/status/bluetooth.js:152
#| msgid "Bluetooth"
msgid "Bluetooth Off" msgid "Bluetooth Off"
msgstr "Bluetooth сөндірілген" msgstr ""
#: js/ui/status/bluetooth.js:154 #: js/ui/status/bluetooth.js:154
#| msgid "Bluetooth"
msgid "Bluetooth On" msgid "Bluetooth On"
msgstr "Bluetooth іске қосылған" msgstr ""
#: js/ui/status/brightness.js:39 #: js/ui/status/brightness.js:39
msgid "Brightness" msgid "Brightness"
@@ -1735,7 +1748,7 @@ msgstr "Жарықтылығы"
#: js/ui/status/dwellClick.js:13 #: js/ui/status/dwellClick.js:13
msgid "Single Click" msgid "Single Click"
msgstr "Дара шерту" msgstr ""
#: js/ui/status/dwellClick.js:18 #: js/ui/status/dwellClick.js:18
msgid "Double Click" msgid "Double Click"
@@ -1747,11 +1760,11 @@ msgstr "Тартып апару"
#: js/ui/status/dwellClick.js:28 #: js/ui/status/dwellClick.js:28
msgid "Secondary Click" msgid "Secondary Click"
msgstr "Екінші шерту" msgstr ""
#: js/ui/status/dwellClick.js:37 #: js/ui/status/dwellClick.js:37
msgid "Dwell Click" msgid "Dwell Click"
msgstr "Пернеде кідіртуден кейінгі сол жақпен шерту" msgstr ""
#: js/ui/status/keyboard.js:826 #: js/ui/status/keyboard.js:826
msgid "Keyboard" msgid "Keyboard"
@@ -1787,7 +1800,7 @@ msgstr "Іске қосу"
#: js/ui/status/location.js:350 #: js/ui/status/location.js:350
msgid "Allow location access" msgid "Allow location access"
msgstr "Орналасуға қатынауды рұқсат ету" msgstr ""
#. Translators: %s is an application name #. Translators: %s is an application name
#: js/ui/status/location.js:352 #: js/ui/status/location.js:352
@@ -2127,11 +2140,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:155 #: js/ui/status/volume.js:154
msgid "Volume changed" msgid "Volume changed"
msgstr "Дыбыс өзгертілді" msgstr "Дыбыс өзгертілді"
#: js/ui/status/volume.js:217 #: js/ui/status/volume.js:225
msgid "Volume" msgid "Volume"
msgstr "Дыбыс деңгейі" msgstr "Дыбыс деңгейі"
@@ -2166,16 +2179,18 @@ 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:371 #: js/ui/unlockDialog.js:371
#| msgctxt "calendar heading"
#| msgid "%A, %B %-d"
msgid "%A %B %-d" msgid "%A %B %-d"
msgstr "%A %B %-d" msgstr "%A %B %-d"
#: js/ui/unlockDialog.js:377 #: js/ui/unlockDialog.js:377
msgid "Swipe up to unlock" msgid "Swipe up to unlock"
msgstr "Босату үшін жоғары өткізіңіз" msgstr ""
#: js/ui/unlockDialog.js:378 #: 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:550 #: js/ui/unlockDialog.js:550
msgid "Unlock Window" msgid "Unlock Window"
@@ -2358,8 +2373,6 @@ msgid ""
"GNOME Extensions handles updating extensions, configuring extension " "GNOME Extensions handles updating extensions, configuring extension "
"preferences and removing or disabling unwanted extensions." "preferences and removing or disabling unwanted extensions."
msgstr "" msgstr ""
"GNOME кеңейтулері көмегімен кеңейтулерді жаңарту, баптау және оларды өшіру "
"немесе сөндіруге болады."
#: subprojects/extensions-app/data/org.gnome.Extensions.desktop.in.in:7 #: subprojects/extensions-app/data/org.gnome.Extensions.desktop.in.in:7
msgid "Configure GNOME Shell Extensions" msgid "Configure GNOME Shell Extensions"
@@ -2375,7 +2388,6 @@ msgid ""
"If you remove the extension, you need to return to download it if you want " "If you remove the extension, you need to return to download it if you want "
"to enable it again" "to enable it again"
msgstr "" msgstr ""
"Кеңейтуді өшірсеңіз, оны қайта іске қосу үшін қайта жүктеп алу керек болады"
#: subprojects/extensions-app/js/main.js:150 #: subprojects/extensions-app/js/main.js:150
msgid "Remove" msgid "Remove"
@@ -2389,15 +2401,15 @@ msgstr "Baurzhan Muftakhidinov <baurthefirst@gmail.com>"
#, javascript-format #, javascript-format
msgid "%d extension will be updated on next login." msgid "%d extension will be updated on next login."
msgid_plural "%d extensions will be updated on next login." msgid_plural "%d extensions will be updated on next login."
msgstr[0] "%d кеңейту жүйеге келесі рет кірген кезде жаңартылатын болады." msgstr[0] ""
#: subprojects/extensions-app/js/main.js:461 #: subprojects/extensions-app/js/main.js:461
msgid "The extension is incompatible with the current GNOME version" msgid "The extension is incompatible with the current GNOME version"
msgstr "Бұл кеңейту ағымдағы GNOME нұсқасымен үйлеспейді" msgstr ""
#: subprojects/extensions-app/js/main.js:464 #: subprojects/extensions-app/js/main.js:464
msgid "The extension had an error" msgid "The extension had an error"
msgstr "Кеңейтуде қате болды" msgstr ""
#: subprojects/extensions-app/data/ui/extension-row.ui:109 #: subprojects/extensions-app/data/ui/extension-row.ui:109
#: subprojects/extensions-tool/src/command-create.c:325 #: subprojects/extensions-tool/src/command-create.c:325
@@ -2416,7 +2428,7 @@ msgstr "Авторы"
#: subprojects/extensions-app/data/ui/extension-row.ui:216 #: subprojects/extensions-app/data/ui/extension-row.ui:216
msgid "Website" msgid "Website"
msgstr "Веб сайт" msgstr "Веб-сайт"
#: subprojects/extensions-app/data/ui/extension-row.ui:233 #: subprojects/extensions-app/data/ui/extension-row.ui:233
msgid "Remove…" msgid "Remove…"
@@ -2448,9 +2460,6 @@ msgid ""
"encounter problems with your system, it is recommended to disable all " "encounter problems with your system, it is recommended to disable all "
"extensions." "extensions."
msgstr "" msgstr ""
"Кеңейтулер жүйелік мәселелерді, соның ішінде өнімділік мәселелерін туғызуы "
"мүмкін. Жүйелік мәселелерге тап болсаңыз, барлық кеңейтулерді сөндіру "
"ұсынылады."
#: subprojects/extensions-app/data/ui/extensions-window.ui:135 #: subprojects/extensions-app/data/ui/extensions-window.ui:135
msgid "Manually Installed" msgid "Manually Installed"
@@ -2469,12 +2478,10 @@ msgid ""
"Were very sorry, but it was not possible to get the list of installed " "Were very sorry, but it was not possible to get the list of installed "
"extensions. Make sure you are logged into GNOME and try again." "extensions. Make sure you are logged into GNOME and try again."
msgstr "" msgstr ""
"Кешірім өтінеміз, барлық орнатылған кеңейтулер тізімін алу мүмкін болмады. "
"GNOME ішіне кіргеніңізді тексеріп, қайталап көріңіз."
#: subprojects/extensions-app/data/ui/extensions-window.ui:273 #: subprojects/extensions-app/data/ui/extensions-window.ui:273
msgid "Extension Updates Ready" msgid "Extension Updates Ready"
msgstr "Кеңейту жаңартулары дайын" msgstr ""
#: subprojects/extensions-app/data/ui/extensions-window.ui:289 #: subprojects/extensions-app/data/ui/extensions-window.ui:289
msgid "Log Out…" msgid "Log Out…"
@@ -2484,7 +2491,7 @@ msgstr "Жүйеден шығу…"
#: subprojects/extensions-tool/src/command-create.c:226 #: subprojects/extensions-tool/src/command-create.c:226
#, c-format #, c-format
msgid "The new extension was successfully created in %s.\n" msgid "The new extension was successfully created in %s.\n"
msgstr "Жаңа кеңейту %s ішінде сәтті жасалды.\n" msgstr ""
#: subprojects/extensions-tool/src/command-create.c:299 #: subprojects/extensions-tool/src/command-create.c:299
#, c-format #, c-format
@@ -2492,13 +2499,11 @@ msgid ""
"Name should be a very short (ideally descriptive) string.\n" "Name should be a very short (ideally descriptive) string.\n"
"Examples are: %s" "Examples are: %s"
msgstr "" msgstr ""
"Атауы қысқа мәтіндік жол (сипаттайтын) болуы тиіс.\n"
"Мысалы: %s"
#: subprojects/extensions-tool/src/command-create.c:305 #: subprojects/extensions-tool/src/command-create.c:305
#: subprojects/extensions-tool/src/main.c:238 #: subprojects/extensions-tool/src/main.c:238
msgid "Name" msgid "Name"
msgstr "Аты" msgstr "Атауы"
#: subprojects/extensions-tool/src/command-create.c:319 #: subprojects/extensions-tool/src/command-create.c:319
#, c-format #, c-format
@@ -2506,9 +2511,6 @@ msgid ""
"Description is a single-sentence explanation of what your extension does.\n" "Description is a single-sentence explanation of what your extension does.\n"
"Examples are: %s" "Examples are: %s"
msgstr "" msgstr ""
"Сипаттамасы - бұл сіздің кеңейтуіңіз жасайтын әрекеттің бір сөйлемді "
"анықтамасы.\n"
"Мысалы: %s"
#: subprojects/extensions-tool/src/command-create.c:339 #: subprojects/extensions-tool/src/command-create.c:339
msgid "" msgid ""
@@ -2516,12 +2518,10 @@ msgid ""
"This should be in the format of an email address (clicktofocus@janedoe." "This should be in the format of an email address (clicktofocus@janedoe."
"example.com)\n" "example.com)\n"
msgstr "" msgstr ""
"UUID - бұл кеңейтуңіздің глобалды деңгейдегі бірегей идентификаторы.\n"
"Ол эл. пошта адресі пішімінде болуы тиіс (clicktofocus@janedoe.example.com)\n"
#: subprojects/extensions-tool/src/command-create.c:366 #: subprojects/extensions-tool/src/command-create.c:366
msgid "Choose one of the available templates:\n" msgid "Choose one of the available templates:\n"
msgstr "Қол жетімді үлгілердің бірін таңдаңыз:\n" msgstr ""
#: subprojects/extensions-tool/src/command-create.c:380 #: subprojects/extensions-tool/src/command-create.c:380
msgid "Template" msgid "Template"
@@ -2529,7 +2529,7 @@ msgstr "Үлгі"
#: subprojects/extensions-tool/src/command-create.c:435 #: subprojects/extensions-tool/src/command-create.c:435
msgid "The unique identifier of the new extension" msgid "The unique identifier of the new extension"
msgstr "Жаңа кеңейтудің бірегей идентификаторы" msgstr ""
#: subprojects/extensions-tool/src/command-create.c:438 #: subprojects/extensions-tool/src/command-create.c:438
msgid "NAME" msgid "NAME"
@@ -2537,7 +2537,7 @@ msgstr "АТАУЫ"
#: subprojects/extensions-tool/src/command-create.c:439 #: subprojects/extensions-tool/src/command-create.c:439
msgid "The user-visible name of the new extension" msgid "The user-visible name of the new extension"
msgstr "Жаңа кеңейтудің пайдаланушыға көрінетін атауы" msgstr ""
#: subprojects/extensions-tool/src/command-create.c:441 #: subprojects/extensions-tool/src/command-create.c:441
msgid "DESCRIPTION" msgid "DESCRIPTION"
@@ -2545,7 +2545,7 @@ msgstr "СИПАТТАМАСЫ"
#: subprojects/extensions-tool/src/command-create.c:443 #: subprojects/extensions-tool/src/command-create.c:443
msgid "A short description of what the extension does" msgid "A short description of what the extension does"
msgstr "Кеңейтудің қысқаша сипаттамасы" msgstr ""
#: subprojects/extensions-tool/src/command-create.c:446 #: subprojects/extensions-tool/src/command-create.c:446
msgid "TEMPLATE" msgid "TEMPLATE"
@@ -2553,11 +2553,11 @@ msgstr "ҮЛГІ"
#: subprojects/extensions-tool/src/command-create.c:447 #: subprojects/extensions-tool/src/command-create.c:447
msgid "The template to use for the new extension" msgid "The template to use for the new extension"
msgstr "Жаңа кеңейту үшін қолданылатын үлгі" msgstr ""
#: subprojects/extensions-tool/src/command-create.c:453 #: subprojects/extensions-tool/src/command-create.c:453
msgid "Enter extension information interactively" msgid "Enter extension information interactively"
msgstr "Кеңейту ақпаратын интерактивті түрде енгізу" msgstr ""
#: subprojects/extensions-tool/src/command-create.c:461 #: subprojects/extensions-tool/src/command-create.c:461
msgid "Create a new extension" msgid "Create a new extension"
@@ -2570,20 +2570,20 @@ msgstr "Белгісіз аргументтер"
#: subprojects/extensions-tool/src/command-create.c:504 #: subprojects/extensions-tool/src/command-create.c:504
msgid "UUID, name and description are required" msgid "UUID, name and description are required"
msgstr "UUID, аты және сипаттамасы керек" msgstr ""
#: subprojects/extensions-tool/src/command-disable.c:46 #: subprojects/extensions-tool/src/command-disable.c:46
#: subprojects/extensions-tool/src/command-enable.c:46 #: subprojects/extensions-tool/src/command-enable.c:46
#: subprojects/extensions-tool/src/command-info.c:50 #: subprojects/extensions-tool/src/command-info.c:50
#: subprojects/extensions-tool/src/command-list.c:64 #: subprojects/extensions-tool/src/command-list.c:64
msgid "Failed to connect to GNOME Shell\n" msgid "Failed to connect to GNOME Shell\n"
msgstr "GNOME Shell-ға байланысты орнату сәтсіз аяқталды\n" msgstr "GNOME Shell-ға байланысты орнату мүмкін емес\n"
#: subprojects/extensions-tool/src/command-disable.c:53 #: subprojects/extensions-tool/src/command-disable.c:53
#: subprojects/extensions-tool/src/command-enable.c:53 #: subprojects/extensions-tool/src/command-enable.c:53
#, c-format #, c-format
msgid "Extension “%s” does not exist\n" msgid "Extension “%s” does not exist\n"
msgstr "\"%s\" кеңейтуі жоқ\n" msgstr ""
#: subprojects/extensions-tool/src/command-disable.c:101 #: subprojects/extensions-tool/src/command-disable.c:101
msgid "Disable an extension" msgid "Disable an extension"
@@ -2605,7 +2605,7 @@ msgstr "UUID көрсетілмеген"
#: subprojects/extensions-tool/src/command-reset.c:81 #: subprojects/extensions-tool/src/command-reset.c:81
#: subprojects/extensions-tool/src/command-uninstall.c:109 #: subprojects/extensions-tool/src/command-uninstall.c:109
msgid "More than one UUID given" msgid "More than one UUID given"
msgstr "Бірден көп UUID көрсетілген" msgstr ""
#: subprojects/extensions-tool/src/command-enable.c:101 #: subprojects/extensions-tool/src/command-enable.c:101
msgid "Enable an extension" msgid "Enable an extension"
@@ -2615,7 +2615,7 @@ msgstr "Кеңейтуді іске қосу"
#: subprojects/extensions-tool/src/main.c:155 #: subprojects/extensions-tool/src/main.c:155
#, c-format #, c-format
msgid "Extension “%s” doesn't exist\n" msgid "Extension “%s” doesn't exist\n"
msgstr "\"%s\" кеңейтуі жоқ\n" msgstr ""
#: subprojects/extensions-tool/src/command-info.c:85 #: subprojects/extensions-tool/src/command-info.c:85
msgid "Show extensions info" msgid "Show extensions info"
@@ -2623,51 +2623,60 @@ msgstr "Кеңейтулер ақпаратын көрсету"
#: subprojects/extensions-tool/src/command-install.c:173 #: subprojects/extensions-tool/src/command-install.c:173
msgid "Overwrite an existing extension" msgid "Overwrite an existing extension"
msgstr "Бар болып тұрған кеңейтуді үстінен жазу" msgstr ""
#: subprojects/extensions-tool/src/command-install.c:175 #: subprojects/extensions-tool/src/command-install.c:175
msgid "EXTENSION_BUNDLE" msgid "EXTENSION_BUNDLE"
msgstr "КЕҢЕЙТУЕСТЕСІ" msgstr ""
#: subprojects/extensions-tool/src/command-install.c:184 #: subprojects/extensions-tool/src/command-install.c:184
#| msgid "UUIDs of extensions to enable"
msgid "Install an extension bundle" msgid "Install an extension bundle"
msgstr "Кеңейту дестесін орнату" msgstr ""
#: subprojects/extensions-tool/src/command-install.c:202 #: subprojects/extensions-tool/src/command-install.c:202
#| msgid "No extensions installed"
msgid "No extension bundle specified" msgid "No extension bundle specified"
msgstr "Кеңейту дестесі көрсетілмеген" msgstr ""
#: subprojects/extensions-tool/src/command-install.c:208 #: subprojects/extensions-tool/src/command-install.c:208
msgid "More than one extension bundle specified" msgid "More than one extension bundle specified"
msgstr "Бірден көп кеңейту дестесі көрсетілген" msgstr ""
#: subprojects/extensions-tool/src/command-list.c:128 #: subprojects/extensions-tool/src/command-list.c:128
#| msgid "Shell Extensions"
msgid "Show user-installed extensions" msgid "Show user-installed extensions"
msgstr "Пайдаланушы орнатқан кеңейтулерді көрсету" msgstr ""
#: subprojects/extensions-tool/src/command-list.c:131 #: subprojects/extensions-tool/src/command-list.c:131
#| msgid "Shell Extensions"
msgid "Show system-installed extensions" msgid "Show system-installed extensions"
msgstr "Жүйелік деңгейде орнатылған кеңейтулерді көрсету" msgstr ""
#: subprojects/extensions-tool/src/command-list.c:134 #: subprojects/extensions-tool/src/command-list.c:134
#| msgid "Shell Extensions"
msgid "Show enabled extensions" msgid "Show enabled extensions"
msgstr "Іске қосылған кеңейтулерді көрсету" msgstr ""
#: subprojects/extensions-tool/src/command-list.c:137 #: subprojects/extensions-tool/src/command-list.c:137
#| msgid "Disable user extensions"
msgid "Show disabled extensions" msgid "Show disabled extensions"
msgstr "Сөндірілген кеңейтулерді көрсету" msgstr ""
#: subprojects/extensions-tool/src/command-list.c:140 #: subprojects/extensions-tool/src/command-list.c:140
#| msgid "GNOME Shell Extension Preferences"
msgid "Show extensions with preferences" msgid "Show extensions with preferences"
msgstr "Баптаулары бар кеңейтулерді көрсету" msgstr ""
#: subprojects/extensions-tool/src/command-list.c:143 #: subprojects/extensions-tool/src/command-list.c:143
#| msgid "No extensions installed"
msgid "Show extensions with updates" msgid "Show extensions with updates"
msgstr "Жаңартулары бар кеңейтулерді көрсету" msgstr ""
#: subprojects/extensions-tool/src/command-list.c:146 #: subprojects/extensions-tool/src/command-list.c:146
#| msgid "Visit extension homepage"
msgid "Print extension details" msgid "Print extension details"
msgstr "Кеңейту ақпаратын басып шығару" msgstr ""
#: subprojects/extensions-tool/src/command-list.c:154 #: subprojects/extensions-tool/src/command-list.c:154
msgid "List installed extensions" msgid "List installed extensions"
@@ -2679,7 +2688,7 @@ msgstr "ФАЙЛ"
#: subprojects/extensions-tool/src/command-pack.c:451 #: subprojects/extensions-tool/src/command-pack.c:451
msgid "Additional source to include in the bundle" msgid "Additional source to include in the bundle"
msgstr "Дестеге қосылатын қосымша қайнар көз" msgstr ""
#: subprojects/extensions-tool/src/command-pack.c:454 #: subprojects/extensions-tool/src/command-pack.c:454
msgid "SCHEMA" msgid "SCHEMA"
@@ -2687,7 +2696,7 @@ msgstr "СҰЛБА"
#: subprojects/extensions-tool/src/command-pack.c:455 #: subprojects/extensions-tool/src/command-pack.c:455
msgid "A GSettings schema that should be included" msgid "A GSettings schema that should be included"
msgstr "Құрамына енуі тиіс GSettings сұлбасы" msgstr ""
#: subprojects/extensions-tool/src/command-pack.c:457 #: subprojects/extensions-tool/src/command-pack.c:457
#: subprojects/extensions-tool/src/command-pack.c:468 #: subprojects/extensions-tool/src/command-pack.c:468
@@ -2696,7 +2705,7 @@ msgstr "БУМА"
#: subprojects/extensions-tool/src/command-pack.c:459 #: subprojects/extensions-tool/src/command-pack.c:459
msgid "The directory where translations are found" msgid "The directory where translations are found"
msgstr "Аудармалар орналасқан бума" msgstr ""
#: subprojects/extensions-tool/src/command-pack.c:461 #: subprojects/extensions-tool/src/command-pack.c:461
msgid "DOMAIN" msgid "DOMAIN"
@@ -2704,37 +2713,37 @@ msgstr "ДОМЕН"
#: subprojects/extensions-tool/src/command-pack.c:463 #: subprojects/extensions-tool/src/command-pack.c:463
msgid "The gettext domain to use for translations" msgid "The gettext domain to use for translations"
msgstr "Аудармалар үшін қолданылуы тиіс gettext домені" msgstr ""
#: subprojects/extensions-tool/src/command-pack.c:466 #: subprojects/extensions-tool/src/command-pack.c:466
msgid "Overwrite an existing pack" msgid "Overwrite an existing pack"
msgstr "Бар болып тұрған пакетті үстінен жазу" msgstr ""
#: subprojects/extensions-tool/src/command-pack.c:470 #: subprojects/extensions-tool/src/command-pack.c:470
msgid "The directory where the pack should be created" msgid "The directory where the pack should be created"
msgstr "Десте жасалуы тиіс бума" msgstr ""
#: subprojects/extensions-tool/src/command-pack.c:472 #: subprojects/extensions-tool/src/command-pack.c:472
msgid "SOURCE_DIRECTORY" msgid "SOURCE_DIRECTORY"
msgstr "ҚАЙНАР_КӨЗУМАСЫ" msgstr ""
#: subprojects/extensions-tool/src/command-pack.c:481 #: subprojects/extensions-tool/src/command-pack.c:481
msgid "Create an extension bundle" msgid "Create an extension bundle"
msgstr "Кеңейту дестесін жасау" msgstr ""
#: subprojects/extensions-tool/src/command-pack.c:501 #: subprojects/extensions-tool/src/command-pack.c:501
msgid "More than one source directory specified" msgid "More than one source directory specified"
msgstr "Бірден көп қайнар көз бумасы көрсетілген" msgstr ""
#: subprojects/extensions-tool/src/command-prefs.c:47 #: subprojects/extensions-tool/src/command-prefs.c:47
#, c-format #, c-format
#| msgid "Show extensions with preferences"
msgid "Extension “%s” doesn't have preferences\n" msgid "Extension “%s” doesn't have preferences\n"
msgstr "\"%s\" кеңейтудің баптаулары жоқ\n" msgstr ""
#: subprojects/extensions-tool/src/command-prefs.c:79 #: subprojects/extensions-tool/src/command-prefs.c:79
#| msgid "GNOME Shell Extension Preferences"
msgid "Opens extension preferences" msgid "Opens extension preferences"
msgstr "Кеңейту баптауларын ашады" msgstr ""
#: subprojects/extensions-tool/src/command-reset.c:58 #: subprojects/extensions-tool/src/command-reset.c:58
msgid "Reset an extension" msgid "Reset an extension"
@@ -2755,11 +2764,11 @@ msgstr "Кеңейтуді өшіру"
#: subprojects/extensions-tool/src/main.c:72 #: subprojects/extensions-tool/src/main.c:72
msgid "Do not print error messages" msgid "Do not print error messages"
msgstr "Қате туралы хабарламаларды басып шығармау" msgstr ""
#: subprojects/extensions-tool/src/main.c:146 #: subprojects/extensions-tool/src/main.c:146
msgid "Failed to connect to GNOME Shell" msgid "Failed to connect to GNOME Shell"
msgstr "GNOME Shell-ға байланысты орнату сәтсіз аяқталды" msgstr "GNOME Shell-ға байланысты орнату мүмкін емес"
#: subprojects/extensions-tool/src/main.c:244 #: subprojects/extensions-tool/src/main.c:244
msgid "Path" msgid "Path"
@@ -2779,7 +2788,7 @@ msgstr "Қалып-күйі"
#: subprojects/extensions-tool/src/main.c:290 #: subprojects/extensions-tool/src/main.c:290
msgid "“version” takes no arguments" msgid "“version” takes no arguments"
msgstr "“version” аргументтерді қабылдамайды" msgstr ""
#: subprojects/extensions-tool/src/main.c:292 #: subprojects/extensions-tool/src/main.c:292
#: subprojects/extensions-tool/src/main.c:312 #: subprojects/extensions-tool/src/main.c:312
@@ -2851,11 +2860,11 @@ msgstr "Кеңейту дестесін орнату"
#: subprojects/extensions-tool/src/main.c:330 #: subprojects/extensions-tool/src/main.c:330
#, c-format #, c-format
msgid "Use “%s” to get detailed help.\n" msgid "Use “%s” to get detailed help.\n"
msgstr "Толық көмекті алу үшін \"%s\" пайдаланыңыз.\n" msgstr ""
#: subprojects/extensions-tool/src/templates/00-plain.desktop.in:4 #: subprojects/extensions-tool/src/templates/00-plain.desktop.in:4
msgid "Plain" msgid "Plain"
msgstr "Қалыпты" msgstr "Кәдімгі"
#: subprojects/extensions-tool/src/templates/00-plain.desktop.in:5 #: subprojects/extensions-tool/src/templates/00-plain.desktop.in:5
msgid "An empty extension" msgid "An empty extension"
@@ -2867,7 +2876,7 @@ msgstr "Индикатор"
#: subprojects/extensions-tool/src/templates/indicator.desktop.in:5 #: subprojects/extensions-tool/src/templates/indicator.desktop.in:5
msgid "Add an icon to the top bar" msgid "Add an icon to the top bar"
msgstr "Жоғарғы панельге таңбашаны қосу" msgstr ""
#. translators: #. translators:
#. * The number of sound outputs on a particular device #. * The number of sound outputs on a particular device
@@ -2889,33 +2898,6 @@ msgstr[0] "%u кірісі"
msgid "System Sounds" msgid "System Sounds"
msgstr "Жүйелік дыбыстар" msgstr "Жүйелік дыбыстар"
#~ msgid "Frequently used applications will appear here"
#~ msgstr "Жиі қолданылатын қолданбалар осында көрінеді"
#~ msgid "Frequent"
#~ msgstr "Жиі қолданылатын"
#~ msgid "All"
#~ msgstr "Барлығы"
#~ msgctxt "calendar heading"
#~ msgid "%A, %B %-d"
#~ msgstr "%A, %B %-d"
#~ msgctxt "calendar heading"
#~ msgid "%A, %B %-d, %Y"
#~ msgstr "%A, %B %-d, %Y"
#~ msgid "%d Connected"
#~ msgid_plural "%d Connected"
#~ msgstr[0] "%d байланысқан"
#~ msgid "Off"
#~ msgstr "Сөнд."
#~ msgid "On"
#~ 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"
@@ -2945,6 +2927,21 @@ msgstr "Жүйелік дыбыстар"
#~ msgid "Sign In" #~ msgid "Sign In"
#~ msgstr "Кіру" #~ msgstr "Кіру"
#~ msgid "Frequently used applications will appear here"
#~ msgstr "Жиі қолданылатын қолданбалар осында көрінеді"
#~ msgid "Frequent"
#~ msgstr "Жиі қолданылатын"
#~ msgid "All"
#~ msgstr "Барлығы"
#~| msgctxt "calendar heading"
#~| msgid "%A, %B %d, %Y"
#~ msgctxt "calendar heading"
#~ msgid "%A, %B %-d, %Y"
#~ msgstr "%A, %B %-d, %Y"
#~ msgid "Password:" #~ msgid "Password:"
#~ msgstr "Пароль:" #~ msgstr "Пароль:"
@@ -2974,6 +2971,16 @@ msgstr "Жүйелік дыбыстар"
#~ msgid_plural "%d new notifications" #~ msgid_plural "%d new notifications"
#~ msgstr[0] "%d жаңа ескерту" #~ msgstr[0] "%d жаңа ескерту"
#~ msgid "%d Connected"
#~ msgid_plural "%d Connected"
#~ msgstr[0] "%d байланысқан"
#~ msgid "Off"
#~ msgstr "Сөнд."
#~ msgid "On"
#~ msgstr "Іске қос."
#~ msgid "Account Settings" #~ msgid "Account Settings"
#~ msgstr "Тіркелгі баптаулары" #~ msgstr "Тіркелгі баптаулары"

882
po/lt.po

File diff suppressed because it is too large Load Diff

949
po/lv.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

159
po/ro.po
View File

@@ -10,8 +10,8 @@ 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-07-21 05:44+0000\n" "POT-Creation-Date: 2020-06-09 19:41+0000\n"
"PO-Revision-Date: 2020-07-21 09:07+0200\n" "PO-Revision-Date: 2020-06-17 18:47+0300\n"
"Last-Translator: Florentina Mușat <florentina [dot] musat [dot] 28 [at] " "Last-Translator: Florentina Mușat <florentina [dot] musat [dot] 28 [at] "
"gmail [dot] com>\n" "gmail [dot] com>\n"
"Language-Team: Gnome Romanian Translation Team <gnomero-list@lists." "Language-Team: Gnome Romanian Translation Team <gnomero-list@lists."
@@ -224,112 +224,95 @@ msgid ""
msgstr "" msgstr ""
"Activează un API D-Bus care permite introspecția stării aplicației shell." "Activează un API D-Bus care permite introspecția stării aplicației shell."
#: data/org.gnome.shell.gschema.xml.in:114 #: data/org.gnome.shell.gschema.xml.in:119
msgid "Layout of the app picker"
msgstr "Aspectul selectorului de aplicații"
#: data/org.gnome.shell.gschema.xml.in:115
msgid ""
"Layout of the app picker. Each entry in the array is a page. Pages are "
"stored in the order they appear in GNOME Shell. Each page contains an "
"“application id” → 'data' pair. Currently, the following values are stored "
"as 'data': • “position”: the position of the application icon in the page"
msgstr ""
"Aspectul selectorului de aplicații. Fiecare intrare din matrice este o "
"pagină. Paginile sunt stocate în ordinea în care apar în GNOME Shell. "
"Fiecare pagină conține o pereche de „id aplicație” → „date”. Momentan, "
"următoarele valori sunt stocate ca „data”: • „poziție”: poziția iconiței "
"aplicației în pagină."
#: data/org.gnome.shell.gschema.xml.in:130
msgid "Keybinding to open the application menu" msgid "Keybinding to open the application menu"
msgstr "Combinație de taste pentru deschiderea meniului aplicației" msgstr "Combinație de taste pentru deschiderea meniului aplicației"
#: data/org.gnome.shell.gschema.xml.in:131 #: data/org.gnome.shell.gschema.xml.in:120
msgid "Keybinding to open the application menu." msgid "Keybinding to open the application menu."
msgstr "Combinație de taste pentru deschiderea meniului aplicației." msgstr "Combinație de taste pentru deschiderea meniului aplicației."
#: data/org.gnome.shell.gschema.xml.in:137 #: data/org.gnome.shell.gschema.xml.in:126
msgid "Keybinding to open the “Show Applications” view" msgid "Keybinding to open the “Show Applications” view"
msgstr "" msgstr ""
"Combinație de taste pentru deschiderea modului de afișare „Arată aplicațiile”" "Combinație de taste pentru deschiderea modului de afișare „Arată aplicațiile”"
#: data/org.gnome.shell.gschema.xml.in:138 #: data/org.gnome.shell.gschema.xml.in:127
msgid "" msgid ""
"Keybinding to open the “Show Applications” view of the Activities Overview." "Keybinding to open the “Show Applications” view of the Activities Overview."
msgstr "" msgstr ""
"Combinație de taste pentru deschiderea modului de afișare „Arată " "Combinație de taste pentru deschiderea modului de afișare „Arată "
"aplicațiile” a prezentării generale a activităților." "aplicațiile” a prezentării generale a activităților."
#: data/org.gnome.shell.gschema.xml.in:145 #: data/org.gnome.shell.gschema.xml.in:134
msgid "Keybinding to open the overview" msgid "Keybinding to open the overview"
msgstr "Combinație de taste pentru deschiderea prezentării generale" msgstr "Combinație de taste pentru deschiderea prezentării generale"
#: data/org.gnome.shell.gschema.xml.in:146 #: data/org.gnome.shell.gschema.xml.in:135
msgid "Keybinding to open the Activities Overview." msgid "Keybinding to open the Activities Overview."
msgstr "" msgstr ""
"Combinație de taste pentru deschiderea prezentării generale a activităților." "Combinație de taste pentru deschiderea prezentării generale a activităților."
#: data/org.gnome.shell.gschema.xml.in:152 #: data/org.gnome.shell.gschema.xml.in:141
msgid "Keybinding to toggle the visibility of the notification list" msgid "Keybinding to toggle the visibility of the notification list"
msgstr "" msgstr ""
"Combinație de taste pentru comutarea vizibilității listei de notificare" "Combinație de taste pentru comutarea vizibilității listei de notificare"
#: data/org.gnome.shell.gschema.xml.in:153 #: data/org.gnome.shell.gschema.xml.in:142
msgid "Keybinding to toggle the visibility of the notification list." msgid "Keybinding to toggle the visibility of the notification list."
msgstr "" msgstr ""
"Combinație de taste pentru comutarea vizibilității listei de notificare." "Combinație de taste pentru comutarea vizibilității listei de notificare."
#: data/org.gnome.shell.gschema.xml.in:159 #: data/org.gnome.shell.gschema.xml.in:148
msgid "Keybinding to focus the active notification" msgid "Keybinding to focus the active notification"
msgstr "Combinație de taste pentru focalizarea notificării active" msgstr "Combinație de taste pentru focalizarea notificării active"
#: data/org.gnome.shell.gschema.xml.in:160 #: data/org.gnome.shell.gschema.xml.in:149
msgid "Keybinding to focus the active notification." msgid "Keybinding to focus the active notification."
msgstr "Combinație de taste pentru focalizarea notificării active." msgstr "Combinație de taste pentru focalizarea notificării active."
#: data/org.gnome.shell.gschema.xml.in:166 #: data/org.gnome.shell.gschema.xml.in:155
msgid "Switch to application 1" msgid "Switch to application 1"
msgstr "Comută la aplicația 1" msgstr "Comută la aplicația 1"
#: data/org.gnome.shell.gschema.xml.in:170 #: data/org.gnome.shell.gschema.xml.in:159
msgid "Switch to application 2" msgid "Switch to application 2"
msgstr "Comută la aplicația 2" msgstr "Comută la aplicația 2"
#: data/org.gnome.shell.gschema.xml.in:174 #: data/org.gnome.shell.gschema.xml.in:163
msgid "Switch to application 3" msgid "Switch to application 3"
msgstr "Comută la aplicația 3" msgstr "Comută la aplicația 3"
#: data/org.gnome.shell.gschema.xml.in:178 #: data/org.gnome.shell.gschema.xml.in:167
msgid "Switch to application 4" msgid "Switch to application 4"
msgstr "Comută la aplicația 4" msgstr "Comută la aplicația 4"
#: data/org.gnome.shell.gschema.xml.in:182 #: data/org.gnome.shell.gschema.xml.in:171
msgid "Switch to application 5" msgid "Switch to application 5"
msgstr "Comută la aplicația 5" msgstr "Comută la aplicația 5"
#: data/org.gnome.shell.gschema.xml.in:186 #: data/org.gnome.shell.gschema.xml.in:175
msgid "Switch to application 6" msgid "Switch to application 6"
msgstr "Comută la aplicația 6" msgstr "Comută la aplicația 6"
#: data/org.gnome.shell.gschema.xml.in:190 #: data/org.gnome.shell.gschema.xml.in:179
msgid "Switch to application 7" msgid "Switch to application 7"
msgstr "Comută la aplicația 7" msgstr "Comută la aplicația 7"
#: data/org.gnome.shell.gschema.xml.in:194 #: data/org.gnome.shell.gschema.xml.in:183
msgid "Switch to application 8" msgid "Switch to application 8"
msgstr "Comută la aplicația 8" msgstr "Comută la aplicația 8"
#: data/org.gnome.shell.gschema.xml.in:198 #: data/org.gnome.shell.gschema.xml.in:187
msgid "Switch to application 9" msgid "Switch to application 9"
msgstr "Comută la aplicația 9" msgstr "Comută la aplicația 9"
#: data/org.gnome.shell.gschema.xml.in:207 #: data/org.gnome.shell.gschema.xml.in:196
#: data/org.gnome.shell.gschema.xml.in:234 #: data/org.gnome.shell.gschema.xml.in:223
msgid "Limit switcher to current workspace." msgid "Limit switcher to current workspace."
msgstr "Limitează comutatorul la spațiul de lucru curent." msgstr "Limitează comutatorul la spațiul de lucru curent."
#: data/org.gnome.shell.gschema.xml.in:208 #: data/org.gnome.shell.gschema.xml.in:197
msgid "" msgid ""
"If true, only applications that have windows on the current workspace are " "If true, only applications that have windows on the current workspace are "
"shown in the switcher. Otherwise, all applications are included." "shown in the switcher. Otherwise, all applications are included."
@@ -337,11 +320,11 @@ msgstr ""
"Dacă este activat, doar aplicațiile care au ferestre în spațiul de lucru " "Dacă este activat, doar aplicațiile care au ferestre în spațiul de lucru "
"curent sunt arătate în comutator. Altfel, toate aplicațiile sunt incluse." "curent sunt arătate în comutator. Altfel, toate aplicațiile sunt incluse."
#: data/org.gnome.shell.gschema.xml.in:225 #: data/org.gnome.shell.gschema.xml.in:214
msgid "The application icon mode." msgid "The application icon mode."
msgstr "Miniatură și pictograma aplicației." msgstr "Miniatură și pictograma aplicației."
#: data/org.gnome.shell.gschema.xml.in:226 #: data/org.gnome.shell.gschema.xml.in:215
msgid "" msgid ""
"Configures how the windows are shown in the switcher. Valid possibilities " "Configures how the windows are shown in the switcher. Valid possibilities "
"are “thumbnail-only” (shows a thumbnail of the window), “app-icon-" "are “thumbnail-only” (shows a thumbnail of the window), “app-icon-"
@@ -351,7 +334,7 @@ msgstr ""
"Posibilități valide sunt „mod miniatură” (arată o miniatură a ferestrei) " "Posibilități valide sunt „mod miniatură” (arată o miniatură a ferestrei) "
"„mod iconiță” (arată doar iconița aplicației) sau „ambele”." "„mod iconiță” (arată doar iconița aplicației) sau „ambele”."
#: data/org.gnome.shell.gschema.xml.in:235 #: data/org.gnome.shell.gschema.xml.in:224
msgid "" msgid ""
"If true, only windows from the current workspace are shown in the switcher. " "If true, only windows from the current workspace are shown in the switcher. "
"Otherwise, all windows are included." "Otherwise, all windows are included."
@@ -359,59 +342,59 @@ msgstr ""
"Dacă este activat, doar ferestrele din spațiul de lucru curent sunt arătate " "Dacă este activat, doar ferestrele din spațiul de lucru curent sunt arătate "
"în comutator. Altfel, toate ferestrele sunt incluse." "în comutator. Altfel, toate ferestrele sunt incluse."
#: data/org.gnome.shell.gschema.xml.in:245 #: data/org.gnome.shell.gschema.xml.in:234
msgid "Locations" msgid "Locations"
msgstr "Locații" msgstr "Locații"
#: data/org.gnome.shell.gschema.xml.in:246 #: data/org.gnome.shell.gschema.xml.in:235
msgid "The locations to show in world clocks" msgid "The locations to show in world clocks"
msgstr "Locațiile de arătat în ceasuri globale" msgstr "Locațiile de arătat în ceasuri globale"
#: data/org.gnome.shell.gschema.xml.in:256 #: data/org.gnome.shell.gschema.xml.in:245
msgid "Automatic location" msgid "Automatic location"
msgstr "Locație automată" msgstr "Locație automată"
#: data/org.gnome.shell.gschema.xml.in:257 #: data/org.gnome.shell.gschema.xml.in:246
msgid "Whether to fetch the current location or not" msgid "Whether to fetch the current location or not"
msgstr "Dacă să se obțină locația curentă" msgstr "Dacă să se obțină locația curentă"
#: data/org.gnome.shell.gschema.xml.in:264 #: data/org.gnome.shell.gschema.xml.in:253
msgid "Location" msgid "Location"
msgstr "Locație" msgstr "Locație"
#: data/org.gnome.shell.gschema.xml.in:265 #: data/org.gnome.shell.gschema.xml.in:254
msgid "The location for which to show a forecast" msgid "The location for which to show a forecast"
msgstr "Locația pentru care să se arate o prognoză" msgstr "Locația pentru care să se arate o prognoză"
#: data/org.gnome.shell.gschema.xml.in:277 #: data/org.gnome.shell.gschema.xml.in:266
msgid "Attach modal dialog to the parent window" msgid "Attach modal dialog to the parent window"
msgstr "Atașează dialogul modal la fereastra părinte" msgstr "Atașează dialogul modal la fereastra părinte"
#: data/org.gnome.shell.gschema.xml.in:278 #: data/org.gnome.shell.gschema.xml.in:267
#: data/org.gnome.shell.gschema.xml.in:287 #: data/org.gnome.shell.gschema.xml.in:276
#: data/org.gnome.shell.gschema.xml.in:295 #: data/org.gnome.shell.gschema.xml.in:284
#: data/org.gnome.shell.gschema.xml.in:303 #: data/org.gnome.shell.gschema.xml.in:292
#: data/org.gnome.shell.gschema.xml.in:311 #: data/org.gnome.shell.gschema.xml.in:300
msgid "" msgid ""
"This key overrides the key in org.gnome.mutter when running GNOME Shell." "This key overrides the key in org.gnome.mutter when running GNOME Shell."
msgstr "" msgstr ""
"Această cheie suprascrie cheia corespondentă din org.gnome.mutter când " "Această cheie suprascrie cheia corespondentă din org.gnome.mutter când "
"Vizualizatorul activităților GNOME rulează." "Vizualizatorul activităților GNOME rulează."
#: data/org.gnome.shell.gschema.xml.in:286 #: data/org.gnome.shell.gschema.xml.in:275
msgid "Enable edge tiling when dropping windows on screen edges" msgid "Enable edge tiling when dropping windows on screen edges"
msgstr "" msgstr ""
"Activează mozaic lateral la plasarea ferestrelor pe marginile ecranului" "Activează mozaic lateral la plasarea ferestrelor pe marginile ecranului"
#: data/org.gnome.shell.gschema.xml.in:294 #: data/org.gnome.shell.gschema.xml.in:283
msgid "Workspaces are managed dynamically" msgid "Workspaces are managed dynamically"
msgstr "Spațiile de lucru sunt gestionate în mod dinamic" msgstr "Spațiile de lucru sunt gestionate în mod dinamic"
#: data/org.gnome.shell.gschema.xml.in:302 #: data/org.gnome.shell.gschema.xml.in:291
msgid "Workspaces only on primary monitor" msgid "Workspaces only on primary monitor"
msgstr "Spații de lucru doar pe monitorul principal" msgstr "Spații de lucru doar pe monitorul principal"
#: data/org.gnome.shell.gschema.xml.in:310 #: data/org.gnome.shell.gschema.xml.in:299
msgid "Delay focus changes in mouse mode until the pointer stops moving" msgid "Delay focus changes in mouse mode until the pointer stops moving"
msgstr "" msgstr ""
"Întârzie schimbările de focalizare în maus până când cursorul încetează să " "Întârzie schimbările de focalizare în maus până când cursorul încetează să "
@@ -450,7 +433,7 @@ msgstr "Vizitează pagina principală a extensiei"
#: js/gdm/authPrompt.js:135 js/ui/audioDeviceSelection.js:57 #: js/gdm/authPrompt.js:135 js/ui/audioDeviceSelection.js:57
#: js/ui/components/networkAgent.js:110 js/ui/components/polkitAgent.js:139 #: js/ui/components/networkAgent.js:110 js/ui/components/polkitAgent.js:139
#: js/ui/endSessionDialog.js:369 js/ui/extensionDownloader.js:183 #: js/ui/endSessionDialog.js:369 js/ui/extensionDownloader.js:181
#: js/ui/shellMountOperation.js:376 js/ui/shellMountOperation.js:386 #: js/ui/shellMountOperation.js:376 js/ui/shellMountOperation.js:386
#: js/ui/status/network.js:916 subprojects/extensions-app/js/main.js:149 #: js/ui/status/network.js:916 subprojects/extensions-app/js/main.js:149
msgid "Cancel" msgid "Cancel"
@@ -492,7 +475,7 @@ msgstr "Nume de utilizator"
msgid "Login Window" msgid "Login Window"
msgstr "Fereastră de autentificare" msgstr "Fereastră de autentificare"
#: js/gdm/util.js:355 #: js/gdm/util.js:345
msgid "Authentication error" msgid "Authentication error"
msgstr "Eroare de autentificare" msgstr "Eroare de autentificare"
@@ -501,7 +484,7 @@ msgstr "Eroare de autentificare"
#. as a cue to display our own message. #. as a cue to display our own message.
#. Translators: this message is shown below the password entry field #. Translators: this message is shown below the password entry field
#. to indicate the user can swipe their finger instead #. to indicate the user can swipe their finger instead
#: js/gdm/util.js:481 #: js/gdm/util.js:471
msgid "(or swipe finger)" msgid "(or swipe finger)"
msgstr "(sau treceți degetul peste)" msgstr "(sau treceți degetul peste)"
@@ -744,36 +727,36 @@ msgstr "Refuză accesul"
msgid "Grant Access" msgid "Grant Access"
msgstr "Permite accesul" msgstr "Permite accesul"
#: js/ui/appDisplay.js:1297 #: js/ui/appDisplay.js:902
msgid "Unnamed Folder" msgid "Unnamed Folder"
msgstr "Dosar nedenumit" msgstr "Dosar nedenumit"
#. 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:2767 js/ui/panel.js:75 #: js/ui/appDisplay.js:2241 js/ui/panel.js:75
msgid "Open Windows" msgid "Open Windows"
msgstr "Ferestre deschise" msgstr "Ferestre deschise"
#: js/ui/appDisplay.js:2786 js/ui/panel.js:82 #: js/ui/appDisplay.js:2260 js/ui/panel.js:82
msgid "New Window" msgid "New Window"
msgstr "Fereastră nouă" msgstr "Fereastră nouă"
#: js/ui/appDisplay.js:2802 #: js/ui/appDisplay.js:2276
msgid "Launch using Integrated Graphics Card" msgid "Launch using Integrated Graphics Card"
msgstr "Lansează folosind placa grafică integrată" msgstr "Lansează folosind placa grafică integrată"
#: js/ui/appDisplay.js:2803 #: js/ui/appDisplay.js:2277
msgid "Launch using Discrete Graphics Card" msgid "Launch using Discrete Graphics Card"
msgstr "Lansează folosind placa grafică discretă" msgstr "Lansează folosind placa grafică discretă"
#: js/ui/appDisplay.js:2831 js/ui/dash.js:239 #: js/ui/appDisplay.js:2305 js/ui/dash.js:239
msgid "Remove from Favorites" msgid "Remove from Favorites"
msgstr "Elimină din favorite" msgstr "Elimină din favorite"
#: js/ui/appDisplay.js:2837 #: js/ui/appDisplay.js:2311
msgid "Add to Favorites" msgid "Add to Favorites"
msgstr "Adaugă la Favorite" msgstr "Adaugă la Favorite"
#: js/ui/appDisplay.js:2847 js/ui/panel.js:93 #: js/ui/appDisplay.js:2321 js/ui/panel.js:93
msgid "Show Details" msgid "Show Details"
msgstr "Arată detaliile" msgstr "Arată detaliile"
@@ -803,7 +786,7 @@ msgstr "Căști auriculare"
msgid "Headset" msgid "Headset"
msgstr "Căști cu microfon" msgstr "Căști cu microfon"
#: js/ui/audioDeviceSelection.js:68 js/ui/status/volume.js:272 #: js/ui/audioDeviceSelection.js:68 js/ui/status/volume.js:273
msgid "Microphone" msgid "Microphone"
msgstr "Microfon" msgstr "Microfon"
@@ -1317,15 +1300,15 @@ msgstr "%s (la distanță)"
msgid "%s (console)" msgid "%s (console)"
msgstr "%s (consolă)" msgstr "%s (consolă)"
#: js/ui/extensionDownloader.js:187 #: js/ui/extensionDownloader.js:185
msgid "Install" msgid "Install"
msgstr "Instalează" msgstr "Instalează"
#: js/ui/extensionDownloader.js:193 #: js/ui/extensionDownloader.js:191
msgid "Install Extension" msgid "Install Extension"
msgstr "Instalează extensia" msgstr "Instalează extensia"
#: js/ui/extensionDownloader.js:194 #: 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 "Descărcați și instalați „%s” de la extensions.gnome.org?" msgstr "Descărcați și instalați „%s” de la extensions.gnome.org?"
@@ -1358,11 +1341,11 @@ msgstr "O aplicație vrea să inhibe scurtăturile"
msgid "You can restore shortcuts by pressing %s." msgid "You can restore shortcuts by pressing %s."
msgstr "Puteți restaura scurtăturile apăsând %s." msgstr "Puteți restaura scurtăturile apăsând %s."
#: js/ui/inhibitShortcutsDialog.js:100 #: js/ui/inhibitShortcutsDialog.js:98
msgid "Deny" msgid "Deny"
msgstr "Refuză" msgstr "Refuză"
#: js/ui/inhibitShortcutsDialog.js:107 #: js/ui/inhibitShortcutsDialog.js:105
msgid "Allow" msgid "Allow"
msgstr "Permite" msgstr "Permite"
@@ -1431,7 +1414,7 @@ msgstr "Oprește"
msgid "Leave Off" msgid "Leave Off"
msgstr "Lasă oprit" msgstr "Lasă oprit"
#: js/ui/keyboard.js:225 #: js/ui/keyboard.js:207
msgid "Region & Language Settings" msgid "Region & Language Settings"
msgstr "Configurări de regiune și limbă" msgstr "Configurări de regiune și limbă"
@@ -1505,7 +1488,7 @@ msgstr "Blocarea ecranului este dezactivată"
msgid "Screen Locking requires the GNOME display manager." msgid "Screen Locking requires the GNOME display manager."
msgstr "Blocarea ecranului necesită administratorul de afișaj GNOME." msgstr "Blocarea ecranului necesită administratorul de afișaj GNOME."
#: js/ui/messageTray.js:1476 #: js/ui/messageTray.js:1547
msgid "System Information" msgid "System Information"
msgstr "Informații despre sistem" msgstr "Informații despre sistem"
@@ -1517,13 +1500,13 @@ msgstr "Artist necunoscut"
msgid "Unknown title" msgid "Unknown title"
msgstr "Titlu necunoscut" msgstr "Titlu necunoscut"
#: js/ui/overview.js:74 #: js/ui/overview.js:73
msgid "Undo" msgid "Undo"
msgstr "Anulează" msgstr "Anulează"
#. Translators: This is the main view to select #. Translators: This is the main view to select
#. activities. See also note for "Activities" string. #. activities. See also note for "Activities" string.
#: js/ui/overview.js:87 #: js/ui/overview.js:86
msgid "Overview" msgid "Overview"
msgstr "Prezentare generală" msgstr "Prezentare generală"
@@ -1531,7 +1514,7 @@ msgstr "Prezentare generală"
#. in the search entry when no search is #. in the search entry when no search is
#. active; it should not exceed ~30 #. active; it should not exceed ~30
#. characters. #. characters.
#: js/ui/overview.js:108 #: js/ui/overview.js:107
msgid "Type to search" msgid "Type to search"
msgstr "Tastați pentru a căuta" msgstr "Tastați pentru a căuta"
@@ -2189,11 +2172,11 @@ msgstr "Eroare de autorizare Thunderbolt"
msgid "Could not authorize the Thunderbolt device: %s" msgid "Could not authorize the Thunderbolt device: %s"
msgstr "Nu s-a putut autoriza dispozitivul Thunderbolt: %s" msgstr "Nu s-a putut autoriza dispozitivul Thunderbolt: %s"
#: js/ui/status/volume.js:155 #: js/ui/status/volume.js:154
msgid "Volume changed" msgid "Volume changed"
msgstr "Volumul a fost schimbat" msgstr "Volumul a fost schimbat"
#: js/ui/status/volume.js:217 #: js/ui/status/volume.js:225
msgid "Volume" msgid "Volume"
msgstr "Volum" msgstr "Volum"
@@ -2239,11 +2222,11 @@ msgstr "Glisați în sus pentru a debloca"
msgid "Click or press a key to unlock" msgid "Click or press a key to unlock"
msgstr "Apăsați clic sau o tastă pentru a debloca" msgstr "Apăsați clic sau o tastă pentru a debloca"
#: js/ui/unlockDialog.js:555 #: js/ui/unlockDialog.js:550
msgid "Unlock Window" msgid "Unlock Window"
msgstr "Deblochează fereastră" msgstr "Deblochează fereastră"
#: js/ui/unlockDialog.js:564 #: js/ui/unlockDialog.js:559
msgid "Log in as another user" msgid "Log in as another user"
msgstr "Intră în sesiune ca utilizator diferit" msgstr "Intră în sesiune ca utilizator diferit"
@@ -2379,12 +2362,12 @@ msgstr "Utilizează un mod specific, de exemplu „gdm” pentru ecranul de loga
msgid "List possible modes" msgid "List possible modes"
msgstr "Enumeră câmpurile care pot fi afișate" msgstr "Enumeră câmpurile care pot fi afișate"
#: src/shell-app.c:268 #: src/shell-app.c:286
msgctxt "program" msgctxt "program"
msgid "Unknown" msgid "Unknown"
msgstr "Necunoscut" msgstr "Necunoscut"
#: src/shell-app.c:519 #: src/shell-app.c:537
#, c-format #, c-format
msgid "Failed to launch “%s”" msgid "Failed to launch “%s”"
msgstr "Nu s-a putut lansa „%s”" msgstr "Nu s-a putut lansa „%s”"

421
po/tr.po

File diff suppressed because it is too large Load Diff

464
po/uk.po

File diff suppressed because it is too large Load Diff

View File

@@ -23,8 +23,8 @@ 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-07-12 02:14+0000\n" "POT-Creation-Date: 2020-05-28 11:29+0000\n"
"PO-Revision-Date: 2020-07-11 22:32-0400\n" "PO-Revision-Date: 2020-05-29 09:03-0400\n"
"Last-Translator: Boyuan Yang <073plan@gmail.com>\n" "Last-Translator: Boyuan Yang <073plan@gmail.com>\n"
"Language-Team: Chinese (China) <i18n-zh@googlegroups.com>\n" "Language-Team: Chinese (China) <i18n-zh@googlegroups.com>\n"
"Language: zh_CN\n" "Language: zh_CN\n"
@@ -444,7 +444,7 @@ msgstr "用户名"
msgid "Login Window" msgid "Login Window"
msgstr "登录窗口" msgstr "登录窗口"
#: js/gdm/util.js:355 #: js/gdm/util.js:345
msgid "Authentication error" msgid "Authentication error"
msgstr "认证出错" msgstr "认证出错"
@@ -453,7 +453,7 @@ msgstr "认证出错"
#. as a cue to display our own message. #. as a cue to display our own message.
#. Translators: this message is shown below the password entry field #. Translators: this message is shown below the password entry field
#. to indicate the user can swipe their finger instead #. to indicate the user can swipe their finger instead
#: js/gdm/util.js:481 #: js/gdm/util.js:471
msgid "(or swipe finger)" msgid "(or swipe finger)"
msgstr "(或滑动手指)" msgstr "(或滑动手指)"
@@ -559,7 +559,7 @@ msgid "%d hour ago"
msgid_plural "%d hours ago" msgid_plural "%d hours ago"
msgstr[0] "%d 小时前" msgstr[0] "%d 小时前"
#: js/misc/util.js:191 js/ui/dateMenu.js:162 #: js/misc/util.js:191
msgid "Yesterday" msgid "Yesterday"
msgstr "昨天" msgstr "昨天"
@@ -672,44 +672,44 @@ msgstr "您到热点登录的连接不安全。您在此页面输入的密码或
#. No support for non-modal system dialogs, so ignore the option #. No support for non-modal system dialogs, so ignore the option
#. let modal = options['modal'] || true; #. let modal = options['modal'] || true;
#: js/ui/accessDialog.js:39 js/ui/status/location.js:369 #: js/ui/accessDialog.js:39 js/ui/status/location.js:374
msgid "Deny Access" msgid "Deny Access"
msgstr "拒绝访问" msgstr "拒绝访问"
#: js/ui/accessDialog.js:40 js/ui/status/location.js:372 #: js/ui/accessDialog.js:40 js/ui/status/location.js:377
msgid "Grant Access" msgid "Grant Access"
msgstr "允许访问" msgstr "允许访问"
#: js/ui/appDisplay.js:903 #: js/ui/appDisplay.js:960
msgid "Unnamed Folder" msgid "Unnamed Folder"
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:2225 js/ui/panel.js:75 #: js/ui/appDisplay.js:2219 js/ui/panel.js:75
msgid "Open Windows" msgid "Open Windows"
msgstr "打开窗口" msgstr "打开窗口"
#: js/ui/appDisplay.js:2244 js/ui/panel.js:82 #: js/ui/appDisplay.js:2238 js/ui/panel.js:82
msgid "New Window" msgid "New Window"
msgstr "新窗口" msgstr "新窗口"
#: js/ui/appDisplay.js:2260 #: js/ui/appDisplay.js:2254
msgid "Launch using Integrated Graphics Card" msgid "Launch using Integrated Graphics Card"
msgstr "使用集成显卡启动" msgstr "使用集成显卡启动"
#: js/ui/appDisplay.js:2261 #: js/ui/appDisplay.js:2255
msgid "Launch using Discrete Graphics Card" msgid "Launch using Discrete Graphics Card"
msgstr "使用独立显卡启动" msgstr "使用独立显卡启动"
#: js/ui/appDisplay.js:2289 js/ui/dash.js:239 #: js/ui/appDisplay.js:2283 js/ui/dash.js:239
msgid "Remove from Favorites" msgid "Remove from Favorites"
msgstr "从收藏夹中移除" msgstr "从收藏夹中移除"
#: js/ui/appDisplay.js:2295 #: js/ui/appDisplay.js:2289
msgid "Add to Favorites" msgid "Add to Favorites"
msgstr "添加到收藏夹" msgstr "添加到收藏夹"
#: js/ui/appDisplay.js:2305 js/ui/panel.js:93 #: js/ui/appDisplay.js:2299 js/ui/panel.js:93
msgid "Show Details" msgid "Show Details"
msgstr "显示细节" msgstr "显示细节"
@@ -739,7 +739,7 @@ msgstr "耳机"
msgid "Headset" msgid "Headset"
msgstr "耳麦" msgstr "耳麦"
#: js/ui/audioDeviceSelection.js:68 js/ui/status/volume.js:272 #: js/ui/audioDeviceSelection.js:68 js/ui/status/volume.js:273
msgid "Microphone" msgid "Microphone"
msgstr "麦克风" msgstr "麦克风"
@@ -756,7 +756,7 @@ msgid "Settings"
msgstr "设置" msgstr "设置"
#. Translators: Enter 0-6 (Sunday-Saturday) for non-work days. Examples: "0" (Sunday) "6" (Saturday) "06" (Sunday and Saturday). #. Translators: Enter 0-6 (Sunday-Saturday) for non-work days. Examples: "0" (Sunday) "6" (Saturday) "06" (Sunday and Saturday).
#: js/ui/calendar.js:36 #: js/ui/calendar.js:41
msgctxt "calendar-no-work" msgctxt "calendar-no-work"
msgid "06" msgid "06"
msgstr "06" msgstr "06"
@@ -766,43 +766,43 @@ msgstr "06"
#. * NOTE: These grid abbreviations are always shown together #. * NOTE: These grid abbreviations are always shown together
#. * and in order, e.g. "S M T W T F S". #. * and in order, e.g. "S M T W T F S".
#. #.
#: js/ui/calendar.js:65 #: js/ui/calendar.js:70
msgctxt "grid sunday" msgctxt "grid sunday"
msgid "S" msgid "S"
msgstr "日" msgstr "日"
#. Translators: Calendar grid abbreviation for Monday #. Translators: Calendar grid abbreviation for Monday
#: js/ui/calendar.js:67 #: js/ui/calendar.js:72
msgctxt "grid monday" msgctxt "grid monday"
msgid "M" msgid "M"
msgstr "一" msgstr "一"
#. Translators: Calendar grid abbreviation for Tuesday #. Translators: Calendar grid abbreviation for Tuesday
#: js/ui/calendar.js:69 #: js/ui/calendar.js:74
msgctxt "grid tuesday" msgctxt "grid tuesday"
msgid "T" msgid "T"
msgstr "二" msgstr "二"
#. Translators: Calendar grid abbreviation for Wednesday #. Translators: Calendar grid abbreviation for Wednesday
#: js/ui/calendar.js:71 #: js/ui/calendar.js:76
msgctxt "grid wednesday" msgctxt "grid wednesday"
msgid "W" msgid "W"
msgstr "三" msgstr "三"
#. Translators: Calendar grid abbreviation for Thursday #. Translators: Calendar grid abbreviation for Thursday
#: js/ui/calendar.js:73 #: js/ui/calendar.js:78
msgctxt "grid thursday" msgctxt "grid thursday"
msgid "T" msgid "T"
msgstr "四" msgstr "四"
#. Translators: Calendar grid abbreviation for Friday #. Translators: Calendar grid abbreviation for Friday
#: js/ui/calendar.js:75 #: js/ui/calendar.js:80
msgctxt "grid friday" msgctxt "grid friday"
msgid "F" msgid "F"
msgstr "五" msgstr "五"
#. Translators: Calendar grid abbreviation for Saturday #. Translators: Calendar grid abbreviation for Saturday
#: js/ui/calendar.js:77 #: js/ui/calendar.js:82
msgctxt "grid saturday" msgctxt "grid saturday"
msgid "S" msgid "S"
msgstr "六" msgstr "六"
@@ -813,7 +813,7 @@ msgstr "六"
#. * "%OB" is the new format specifier introduced in glibc 2.27, #. * "%OB" is the new format specifier introduced in glibc 2.27,
#. * in most cases you should not change it. #. * in most cases you should not change it.
#. #.
#: js/ui/calendar.js:392 #: js/ui/calendar.js:397
msgid "%OB" msgid "%OB"
msgstr "%OB" msgstr "%OB"
@@ -826,37 +826,61 @@ msgstr "%OB"
#. * in most cases you should not use the old "%B" here unless you #. * in most cases you should not use the old "%B" here unless you
#. * absolutely know what you are doing. #. * absolutely know what you are doing.
#. #.
#: js/ui/calendar.js:402 #: js/ui/calendar.js:407
msgid "%OB %Y" msgid "%OB %Y"
msgstr "%Y %OB" msgstr "%Y %OB"
#: js/ui/calendar.js:461 #: js/ui/calendar.js:466
msgid "Previous month" msgid "Previous month"
msgstr "上个月" msgstr "上个月"
#: js/ui/calendar.js:476 #: js/ui/calendar.js:481
msgid "Next month" msgid "Next month"
msgstr "下个月" msgstr "下个月"
#: js/ui/calendar.js:626 #: js/ui/calendar.js:631
#, no-javascript-format #, no-javascript-format
msgctxt "date day number format" msgctxt "date day number format"
msgid "%d" msgid "%d"
msgstr "%d" msgstr "%d"
#: js/ui/calendar.js:682 #: js/ui/calendar.js:687
msgid "Week %V" msgid "Week %V"
msgstr "第 %V 个星期" msgstr "第 %V 个星期"
#: js/ui/calendar.js:895 #. Translators: Shown in calendar event list for all day events
#. * Keep it short, best if you can use less then 10 characters
#.
#: js/ui/calendar.js:762
msgctxt "event list time"
msgid "All Day"
msgstr "全天"
#. Translators: Shown on calendar heading when selected day occurs on current year
#: js/ui/calendar.js:900
msgctxt "calendar heading"
msgid "%A, %B %-d"
msgstr "%-m月%-d日 %A"
#. Translators: Shown on calendar heading when selected day occurs on different year
#: js/ui/calendar.js:903
msgctxt "calendar heading"
msgid "%A, %B %-d, %Y"
msgstr "%Y年%-m月%-d日 %A"
#: js/ui/calendar.js:1133
msgid "No Notifications" msgid "No Notifications"
msgstr "无通知" msgstr "无通知"
#: js/ui/calendar.js:949 #: js/ui/calendar.js:1136
msgid "No Events"
msgstr "无事件"
#: js/ui/calendar.js:1190
msgid "Do Not Disturb" msgid "Do Not Disturb"
msgstr "请勿打扰" msgstr "请勿打扰"
#: js/ui/calendar.js:968 #: js/ui/calendar.js:1209
msgid "Clear" msgid "Clear"
msgstr "清除" msgstr "清除"
@@ -1006,7 +1030,7 @@ msgstr "抱歉,认证失败。请重试。"
msgid "%s is now known as %s" msgid "%s is now known as %s"
msgstr "%s 现在叫做 %s" msgstr "%s 现在叫做 %s"
#: js/ui/ctrlAltTab.js:21 js/ui/viewSelector.js:178 #: js/ui/ctrlAltTab.js:21 js/ui/viewSelector.js:177
msgid "Windows" msgid "Windows"
msgstr "窗口" msgstr "窗口"
@@ -1025,7 +1049,7 @@ msgstr "Dash"
#. * "Tue 9:29 AM"). The string itself should become a full date, e.g., #. * "Tue 9:29 AM"). The string itself should become a full date, e.g.,
#. * "February 17 2015". #. * "February 17 2015".
#. #.
#: js/ui/dateMenu.js:79 #: js/ui/dateMenu.js:75
msgid "%B %-d %Y" msgid "%B %-d %Y"
msgstr "%Y年%-m月%-d日" msgstr "%Y年%-m月%-d日"
@@ -1033,67 +1057,35 @@ msgstr "%Y年%-m月%-d日"
#. * below the time in the shell; it should combine the weekday and the #. * below the time in the shell; it should combine the weekday and the
#. * date, e.g. "Tuesday February 17 2015". #. * date, e.g. "Tuesday February 17 2015".
#. #.
#: js/ui/dateMenu.js:86 #: js/ui/dateMenu.js:82
msgid "%A %B %e %Y" msgid "%A %B %e %Y"
msgstr "%Y年%-m月%-d日 %A" msgstr "%Y年%-m月%-d日 %A"
#. Translators: Shown on calendar heading when selected day occurs on current year #: js/ui/dateMenu.js:162
#: js/ui/dateMenu.js:151
msgctxt "calendar heading"
msgid "%B %-d"
msgstr "%-m月%-d日"
#. Translators: Shown on calendar heading when selected day occurs on different year
#: js/ui/dateMenu.js:154
msgctxt "calendar heading"
msgid "%B %-d %Y"
msgstr "%Y年%-m月%-d日"
#: js/ui/dateMenu.js:160
msgid "Today"
msgstr "今天"
#: js/ui/dateMenu.js:164
msgid "Tomorrow"
msgstr "明天"
#. Translators: Shown in calendar event list for all day events
#. * Keep it short, best if you can use less then 10 characters
#.
#: js/ui/dateMenu.js:180
msgctxt "event list time"
msgid "All Day"
msgstr "全天"
#: js/ui/dateMenu.js:231
msgid "No Events"
msgstr "无事件"
#: js/ui/dateMenu.js:348
msgid "Add world clocks…" msgid "Add world clocks…"
msgstr "添加世界时钟…" msgstr "添加世界时钟…"
#: js/ui/dateMenu.js:349 #: js/ui/dateMenu.js:163
msgid "World Clocks" msgid "World Clocks"
msgstr "世界时钟" msgstr "世界时钟"
#: js/ui/dateMenu.js:629 #: js/ui/dateMenu.js:443
msgid "Loading…" msgid "Loading…"
msgstr "正在载入……" msgstr "正在载入……"
#: js/ui/dateMenu.js:639 #: js/ui/dateMenu.js:453
msgid "Go online for weather information" msgid "Go online for weather information"
msgstr "通过互联网查看天气信息" msgstr "通过互联网查看天气信息"
#: js/ui/dateMenu.js:641 #: js/ui/dateMenu.js:455
msgid "Weather information is currently unavailable" msgid "Weather information is currently unavailable"
msgstr "天气信息目前不可用" msgstr "天气信息目前不可用"
#: js/ui/dateMenu.js:651 #: js/ui/dateMenu.js:465
msgid "Weather" msgid "Weather"
msgstr "天气" msgstr "天气"
#: js/ui/dateMenu.js:653 #: js/ui/dateMenu.js:467
msgid "Select weather location…" msgid "Select weather location…"
msgstr "选择天气地点…" msgstr "选择天气地点…"
@@ -1276,11 +1268,11 @@ msgstr "某应用程序希望禁用快捷键"
msgid "You can restore shortcuts by pressing %s." msgid "You can restore shortcuts by pressing %s."
msgstr "按 %s 以恢复快捷键。" msgstr "按 %s 以恢复快捷键。"
#: js/ui/inhibitShortcutsDialog.js:100 #: js/ui/inhibitShortcutsDialog.js:98
msgid "Deny" msgid "Deny"
msgstr "拒绝" msgstr "拒绝"
#: js/ui/inhibitShortcutsDialog.js:107 #: js/ui/inhibitShortcutsDialog.js:105
msgid "Allow" msgid "Allow"
msgstr "允许" msgstr "允许"
@@ -1345,7 +1337,7 @@ msgstr "关闭"
msgid "Leave Off" msgid "Leave Off"
msgstr "保持关闭" msgstr "保持关闭"
#: js/ui/keyboard.js:225 #: js/ui/keyboard.js:207
msgid "Region & Language Settings" msgid "Region & Language Settings"
msgstr "区域与语言设置" msgstr "区域与语言设置"
@@ -1418,25 +1410,25 @@ msgstr "屏幕锁定已禁用"
msgid "Screen Locking requires the GNOME display manager." msgid "Screen Locking requires the GNOME display manager."
msgstr "屏幕锁定需要 GNOME 显示管理器。" msgstr "屏幕锁定需要 GNOME 显示管理器。"
#: js/ui/messageTray.js:1476 #: js/ui/messageTray.js:1547
msgid "System Information" msgid "System Information"
msgstr "系统信息" msgstr "系统信息"
#: js/ui/mpris.js:203 #: js/ui/mpris.js:204
msgid "Unknown artist" msgid "Unknown artist"
msgstr "未知艺人" msgstr "未知艺人"
#: js/ui/mpris.js:213 #: js/ui/mpris.js:214
msgid "Unknown title" msgid "Unknown title"
msgstr "未知标题" msgstr "未知标题"
#: js/ui/overview.js:74 #: js/ui/overview.js:73
msgid "Undo" msgid "Undo"
msgstr "撤消" msgstr "撤消"
#. Translators: This is the main view to select #. Translators: This is the main view to select
#. activities. See also note for "Activities" string. #. activities. See also note for "Activities" string.
#: js/ui/overview.js:87 #: js/ui/overview.js:86
msgid "Overview" msgid "Overview"
msgstr "概览" msgstr "概览"
@@ -1444,7 +1436,7 @@ msgstr "概览"
#. in the search entry when no search is #. in the search entry when no search is
#. active; it should not exceed ~30 #. active; it should not exceed ~30
#. characters. #. characters.
#: js/ui/overview.js:108 #: js/ui/overview.js:107
msgid "Type to search" msgid "Type to search"
msgstr "输入以搜索" msgstr "输入以搜索"
@@ -1472,23 +1464,23 @@ msgstr "分配按键"
msgid "Done" msgid "Done"
msgstr "完成" msgstr "完成"
#: js/ui/padOsd.js:732 #: js/ui/padOsd.js:745
msgid "Edit…" msgid "Edit…"
msgstr "编辑…" msgstr "编辑…"
#: js/ui/padOsd.js:774 js/ui/padOsd.js:891 #: js/ui/padOsd.js:787 js/ui/padOsd.js:910
msgid "None" msgid "None"
msgstr "无" msgstr "无"
#: js/ui/padOsd.js:845 #: js/ui/padOsd.js:863
msgid "Press a button to configure" msgid "Press a button to configure"
msgstr "按下按键以配置" msgstr "按下按键以配置"
#: js/ui/padOsd.js:846 #: js/ui/padOsd.js:864
msgid "Press Esc to exit" msgid "Press Esc to exit"
msgstr "按 Esc 以退出" msgstr "按 Esc 以退出"
#: js/ui/padOsd.js:849 #: js/ui/padOsd.js:867
msgid "Press any key to exit" msgid "Press any key to exit"
msgstr "按任意键退出" msgstr "按任意键退出"
@@ -1578,7 +1570,7 @@ msgstr "隐藏文本"
#: js/ui/shellEntry.js:162 #: js/ui/shellEntry.js:162
msgid "Caps lock is on." msgid "Caps lock is on."
msgstr "大写锁定已开启。" msgstr "大写锁定已开启。"
#: js/ui/shellMountOperation.js:285 #: js/ui/shellMountOperation.js:285
msgid "Hidden Volume" msgid "Hidden Volume"
@@ -1750,17 +1742,17 @@ msgstr "定位服务已禁用"
msgid "Enable" msgid "Enable"
msgstr "启用" msgstr "启用"
#: js/ui/status/location.js:350 #: js/ui/status/location.js:355
msgid "Allow location access" msgid "Allow location access"
msgstr "允许获取位置信息" msgstr "允许获取位置信息"
#. Translators: %s is an application name #. Translators: %s is an application name
#: js/ui/status/location.js:352 #: js/ui/status/location.js:357
#, javascript-format #, javascript-format
msgid "The app %s wants to access your location" msgid "The app %s wants to access your location"
msgstr "应用 %s 想要获取您的位置信息" msgstr "应用 %s 想要获取您的位置信息"
#: js/ui/status/location.js:362 #: js/ui/status/location.js:367
msgid "Location access can be changed at any time from the privacy settings." msgid "Location access can be changed at any time from the privacy settings."
msgstr "位置访问权限可以随时在隐私设置里更改。" msgstr "位置访问权限可以随时在隐私设置里更改。"
@@ -2089,11 +2081,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:155 #: js/ui/status/volume.js:154
msgid "Volume changed" msgid "Volume changed"
msgstr "音量已变更" msgstr "音量已变更"
#: js/ui/status/volume.js:217 #: js/ui/status/volume.js:225
msgid "Volume" msgid "Volume"
msgstr "音量" msgstr "音量"
@@ -2139,19 +2131,19 @@ msgstr "向上滑动解锁"
msgid "Click or press a key to unlock" msgid "Click or press a key to unlock"
msgstr "单击或按键解锁" msgstr "单击或按键解锁"
#: js/ui/unlockDialog.js:555 #: js/ui/unlockDialog.js:550
msgid "Unlock Window" msgid "Unlock Window"
msgstr "解锁窗口" msgstr "解锁窗口"
#: js/ui/unlockDialog.js:564 #: js/ui/unlockDialog.js:559
msgid "Log in as another user" msgid "Log in as another user"
msgstr "以另一个用户身份登录" msgstr "以另一个用户身份登录"
#: js/ui/viewSelector.js:182 #: js/ui/viewSelector.js:181
msgid "Applications" msgid "Applications"
msgstr "应用程序" msgstr "应用程序"
#: js/ui/viewSelector.js:186 #: js/ui/viewSelector.js:185
msgid "Search" msgid "Search"
msgstr "搜索" msgstr "搜索"
@@ -2277,12 +2269,12 @@ msgstr "使用指定模式如“gdm”用于登录屏幕"
msgid "List possible modes" msgid "List possible modes"
msgstr "列出可用的模式" msgstr "列出可用的模式"
#: src/shell-app.c:268 #: src/shell-app.c:286
msgctxt "program" msgctxt "program"
msgid "Unknown" msgid "Unknown"
msgstr "未知" msgstr "未知"
#: src/shell-app.c:519 #: src/shell-app.c:537
#, c-format #, c-format
msgid "Failed to launch “%s”" msgid "Failed to launch “%s”"
msgstr "启动“%s”失败" msgstr "启动“%s”失败"
@@ -2512,7 +2504,7 @@ msgstr "描述"
#: subprojects/extensions-tool/src/command-create.c:443 #: subprojects/extensions-tool/src/command-create.c:443
msgid "A short description of what the extension does" msgid "A short description of what the extension does"
msgstr "扩展功能的简短描述" msgstr "简短描述下扩展所做的事情"
#: subprojects/extensions-tool/src/command-create.c:446 #: subprojects/extensions-tool/src/command-create.c:446
msgid "TEMPLATE" msgid "TEMPLATE"
@@ -2855,14 +2847,6 @@ msgstr[0] "%u 个输入"
msgid "System Sounds" msgid "System Sounds"
msgstr "系统声音" msgstr "系统声音"
#~ msgctxt "calendar heading"
#~ msgid "%A, %B %-d"
#~ msgstr "%-m月%-d日 %A"
#~ msgctxt "calendar heading"
#~ msgid "%A, %B %-d, %Y"
#~ msgstr "%Y年%-m月%-d日 %A"
#~ msgid "Frequently used applications will appear here" #~ msgid "Frequently used applications will appear here"
#~ msgstr "常用的应用程序会出现在这里" #~ msgstr "常用的应用程序会出现在这里"

View File

@@ -346,6 +346,8 @@ struct _App
GSList *notify_appointments; /* CalendarAppointment *, for EventsAdded */ GSList *notify_appointments; /* CalendarAppointment *, for EventsAdded */
GSList *notify_ids; /* gchar *, for EventsRemoved */ GSList *notify_ids; /* gchar *, for EventsRemoved */
guint events_added_timeout_id;
guint events_removed_timeout_id;
GSList *live_views; GSList *live_views;
}; };
@@ -368,19 +370,24 @@ app_update_timezone (App *app)
} }
} }
static void static gboolean
app_notify_events_added (App *app) on_app_schedule_events_added_cb (gpointer user_data)
{ {
App *app = user_data;
GVariantBuilder builder, extras_builder; GVariantBuilder builder, extras_builder;
GSList *events, *link; GSList *events, *link;
if (g_source_is_destroyed (g_main_current_source ()))
return FALSE;
events = g_slist_reverse (app->notify_appointments); events = g_slist_reverse (app->notify_appointments);
app->notify_appointments = NULL; app->notify_appointments = NULL;
app->events_added_timeout_id = 0;
print_debug ("Emitting EventsAddedOrUpdated with %d events", g_slist_length (events)); print_debug ("Emitting EventsAddedOrUpdated with %d events", g_slist_length (events));
if (!events) if (!events)
return; return FALSE;
/* The a{sv} is used as an escape hatch in case we want to provide more /* The a{sv} is used as an escape hatch in case we want to provide more
* information in the future without breaking ABI * information in the future without breaking ABI
@@ -421,21 +428,41 @@ app_notify_events_added (App *app)
g_variant_builder_clear (&builder); g_variant_builder_clear (&builder);
g_slist_free_full (events, calendar_appointment_free); g_slist_free_full (events, calendar_appointment_free);
return FALSE;
} }
static void static void
app_notify_events_removed (App *app) app_schedule_events_added (App *app)
{ {
print_debug ("Scheduling EventsAddedOrUpdated");
if (app->events_added_timeout_id == 0)
{
app->events_added_timeout_id = g_timeout_add_seconds (2,
on_app_schedule_events_added_cb,
app);
g_source_set_name_by_id (app->events_added_timeout_id, "[gnome-shell] on_app_schedule_events_added_cb");
}
}
static gboolean
on_app_schedule_events_removed_cb (gpointer user_data)
{
App *app = user_data;
GVariantBuilder builder; GVariantBuilder builder;
GSList *ids, *link; GSList *ids, *link;
if (g_source_is_destroyed (g_main_current_source ()))
return FALSE;
ids = app->notify_ids; ids = app->notify_ids;
app->notify_ids = NULL; app->notify_ids = NULL;
app->events_removed_timeout_id = 0;
print_debug ("Emitting EventsRemoved with %d ids", g_slist_length (ids)); print_debug ("Emitting EventsRemoved with %d ids", g_slist_length (ids));
if (!ids) if (!ids)
return; return FALSE;
g_variant_builder_init (&builder, G_VARIANT_TYPE ("as")); g_variant_builder_init (&builder, G_VARIANT_TYPE ("as"));
for (link = ids; link; link = g_slist_next (link)) for (link = ids; link; link = g_slist_next (link))
@@ -456,7 +483,20 @@ app_notify_events_removed (App *app)
g_slist_free_full (ids, g_free); g_slist_free_full (ids, g_free);
return; return FALSE;
}
static void
app_schedule_events_removed (App *app)
{
print_debug ("Scheduling EventsRemoved");
if (app->events_removed_timeout_id == 0)
{
app->events_removed_timeout_id = g_timeout_add_seconds (2,
on_app_schedule_events_removed_cb,
app);
g_source_set_name_by_id (app->events_removed_timeout_id, "[gnome-shell] on_app_schedule_events_removed_cb");
}
} }
static void static void
@@ -506,7 +546,7 @@ app_process_added_modified_objects (App *app,
g_clear_object (&cal_client); g_clear_object (&cal_client);
if (app->notify_appointments) if (app->notify_appointments)
app_notify_events_added (app); app_schedule_events_added (app);
} }
static void static void
@@ -570,7 +610,7 @@ on_objects_removed (ECalClientView *view,
g_clear_object (&client); g_clear_object (&client);
if (app->notify_ids) if (app->notify_ids)
app_notify_events_removed (app); app_schedule_events_removed (app);
} }
static gboolean static gboolean
@@ -834,6 +874,9 @@ app_free (App *app)
{ {
GSList *ll; GSList *ll;
g_clear_handle_id (&app->events_added_timeout_id, g_source_remove);
g_clear_handle_id (&app->events_removed_timeout_id, g_source_remove);
for (ll = app->live_views; ll != NULL; ll = g_slist_next (ll)) for (ll = app->live_views; ll != NULL; ll = g_slist_next (ll))
{ {
ECalClientView *view = E_CAL_CLIENT_VIEW (ll->data); ECalClientView *view = E_CAL_CLIENT_VIEW (ll->data);

View File

@@ -51,8 +51,6 @@ def start_shell(perf_output=None):
args.append('--nested') args.append('--nested')
else: else:
args.append('--display-server') args.append('--display-server')
elif options.x11:
args.append('--x11')
return subprocess.Popen(args, env=env) return subprocess.Popen(args, env=env)
@@ -297,8 +295,6 @@ parser.add_option("-w", "--wayland", action="store_true",
help="Run as a Wayland compositor") help="Run as a Wayland compositor")
parser.add_option("-n", "--nested", action="store_true", parser.add_option("-n", "--nested", action="store_true",
help="Run as a Wayland nested compositor") help="Run as a Wayland nested compositor")
parser.add_option("-x", "--x11", action="store_true",
help="Run as an X11 compositor")
options, args = parser.parse_args() options, args = parser.parse_args()

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