Compare commits
9 Commits
wip/carlos
...
wip/exalm/
Author | SHA1 | Date | |
---|---|---|---|
c3aa25e4e3 | |||
cfd792fe86 | |||
7bdcc503cb | |||
856a4d27e0 | |||
9d1fe27221 | |||
407abeb178 | |||
95fc8021d2 | |||
060cbb65f6 | |||
1759e27ef7 |
@ -9,6 +9,7 @@ stages:
|
||||
variables:
|
||||
BUNDLE: "extensions-git.flatpak"
|
||||
JS_LOG: "js-report.txt"
|
||||
POT_LOG: "pot-update.txt"
|
||||
|
||||
.only_default: &only_default
|
||||
only:
|
||||
@ -66,7 +67,6 @@ no_template_check:
|
||||
build:
|
||||
image: registry.gitlab.gnome.org/gnome/mutter/master:v4
|
||||
stage: build
|
||||
needs: []
|
||||
before_script:
|
||||
- .gitlab-ci/checkout-mutter.sh
|
||||
- meson mutter mutter/build --prefix=/usr -Dtests=false
|
||||
@ -85,7 +85,6 @@ build:
|
||||
test:
|
||||
image: registry.gitlab.gnome.org/gnome/mutter/master:v4
|
||||
stage: test
|
||||
needs: ["build"]
|
||||
variables:
|
||||
XDG_RUNTIME_DIR: "$CI_PROJECT_DIR/runtime-dir"
|
||||
NO_AT_BRIDGE: "1"
|
||||
@ -100,9 +99,24 @@ test:
|
||||
- build/meson-logs/testlog.txt
|
||||
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:
|
||||
stage: build
|
||||
needs: []
|
||||
variables:
|
||||
SUBPROJECT: "subprojects/extensions-app"
|
||||
# Your manifest path
|
||||
|
32
NEWS
32
NEWS
@ -1,35 +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
|
||||
|
@ -20,12 +20,6 @@
|
||||
<method name="ListSessions">
|
||||
<arg name="sessions" type="a(susso)" direction="out"/>
|
||||
</method>
|
||||
<method name="CanRebootToBootLoaderMenu">
|
||||
<arg type="s" direction="out"/>
|
||||
</method>
|
||||
<method name="SetRebootToBootLoaderMenu">
|
||||
<arg type="t" direction="in"/>
|
||||
</method>
|
||||
<signal name="PrepareForSleep">
|
||||
<arg type="b" direction="out"/>
|
||||
</signal>
|
||||
|
@ -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>
|
@ -70,14 +70,6 @@
|
||||
-->
|
||||
<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"/>
|
||||
</interface>
|
||||
</node>
|
||||
|
@ -28,7 +28,6 @@
|
||||
<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.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.SessionManager.EndSessionDialog.xml</file>
|
||||
<file preprocess="xml-stripblanks">org.gnome.SessionManager.Inhibitor.xml</file>
|
||||
|
@ -1,7 +1,7 @@
|
||||
[Unit]
|
||||
Description=GNOME Shell on Wayland
|
||||
# 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
|
||||
CollectMode=inactive-or-failed
|
||||
RefuseManualStart=on
|
||||
@ -13,21 +13,18 @@ Requisite=gnome-session-initialized.target
|
||||
PartOf=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]
|
||||
Slice=session.slice
|
||||
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
|
||||
# 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
|
||||
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
|
||||
Restart=no
|
||||
# Kill any stubborn child processes after this long
|
@ -6,5 +6,5 @@ Requisite=gnome-session-initialized.target
|
||||
PartOf=gnome-session-initialized.target
|
||||
Before=gnome-session-initialized.target
|
||||
|
||||
Wants=org.gnome.Shell@wayland.service
|
||||
Wants=org.gnome.Shell@x11.service
|
||||
Requires=gnome-shell-wayland.service
|
||||
After=gnome-shell-wayland.service
|
@ -1,7 +1,7 @@
|
||||
[Unit]
|
||||
Description=GNOME Shell on X11
|
||||
# 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
|
||||
CollectMode=inactive-or-failed
|
||||
RefuseManualStart=on
|
||||
@ -13,24 +13,18 @@ Requisite=gnome-session-initialized.target
|
||||
PartOf=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
|
||||
StartLimitIntervalSec=15s
|
||||
StartLimitBurst=3
|
||||
|
||||
[Service]
|
||||
Slice=session.slice
|
||||
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
|
||||
# Exit code 1 means we are probably *not* dealing with an extension failure
|
||||
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.
|
||||
Restart=always
|
||||
# Do not wait before restarting the shell
|
10
data/gnome-shell-x11.target
Normal file
10
data/gnome-shell-x11.target
Normal 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
|
@ -101,21 +101,22 @@ if have_systemd
|
||||
unitconf.set('bindir', bindir)
|
||||
|
||||
configure_file(
|
||||
input: 'org.gnome.Shell@x11.service.in',
|
||||
output: 'org.gnome.Shell@x11.service',
|
||||
input: 'gnome-shell-x11.service.in',
|
||||
output: 'gnome-shell-x11.service',
|
||||
configuration: unitconf,
|
||||
install_dir: systemduserunitdir
|
||||
)
|
||||
|
||||
configure_file(
|
||||
input: 'org.gnome.Shell@wayland.service.in',
|
||||
output: 'org.gnome.Shell@wayland.service',
|
||||
input: 'gnome-shell-wayland.service.in',
|
||||
output: 'gnome-shell-wayland.service',
|
||||
configuration: unitconf,
|
||||
install_dir: systemduserunitdir
|
||||
)
|
||||
|
||||
units = files('org.gnome.Shell.target',
|
||||
'org.gnome.Shell-disable-extensions.service')
|
||||
units = files('gnome-shell-x11.target',
|
||||
'gnome-shell-wayland.target',
|
||||
'gnome-shell-disable-extensions.service')
|
||||
|
||||
install_data(units, install_dir: systemduserunitdir)
|
||||
endif
|
||||
|
@ -232,9 +232,7 @@
|
||||
color: $fg_color;
|
||||
font-feature-settings: "tnum";
|
||||
@include fontsize($base_font_size);
|
||||
|
||||
&:ltr { text-align: right; }
|
||||
&:rtl { text-align: left; }
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
// timezone offset label
|
||||
|
@ -138,10 +138,11 @@
|
||||
.user-widget.horizontal .user-widget-label {
|
||||
@include fontsize($base_font_size + 2);
|
||||
font-weight: bold;
|
||||
text-align: left;
|
||||
padding-left: 15px;
|
||||
|
||||
&:ltr { padding-left: 14px; text-align: left; }
|
||||
&:rtl { padding-right: 14px; text-align: right; }
|
||||
&:ltr { padding-left: 14px; }
|
||||
&:rtl { padding-right: 14px; }
|
||||
}
|
||||
|
||||
.user-widget.vertical .user-widget-label {
|
||||
|
@ -71,11 +71,9 @@
|
||||
> .event-time {
|
||||
color: transparentize($fg_color, 0.5);
|
||||
@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 */
|
||||
padding-bottom: 0.13em;
|
||||
|
||||
&:ltr { text-align: right };
|
||||
&:rtl { text-align: left };
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -76,10 +76,8 @@ $popover_arrow_height: 12px;
|
||||
|
||||
// container for radio and check boxes
|
||||
.popup-menu-ornament {
|
||||
text-align: right;
|
||||
width: 1.2em;
|
||||
|
||||
&:ltr { text-align: right };
|
||||
&:rtl { text-align: left };
|
||||
}
|
||||
|
||||
// separator
|
||||
|
@ -3,8 +3,13 @@ private_headers = [
|
||||
'gactionobservable.h',
|
||||
'gactionobserver.h',
|
||||
'shell-network-agent.h',
|
||||
'shell-recorder-src.h'
|
||||
]
|
||||
|
||||
if not enable_recorder
|
||||
private_headers += 'shell-recorder.h'
|
||||
endif
|
||||
|
||||
exclude_directories = [
|
||||
'calendar-server',
|
||||
'hotplug-sniffer',
|
||||
|
@ -25,8 +25,6 @@ var ServiceImplementation = class {
|
||||
|
||||
// subclasses may override this to disable automatic shutdown
|
||||
this._autoShutdown = true;
|
||||
|
||||
this._queueShutdownCheck();
|
||||
}
|
||||
|
||||
// subclasses may override this to own additional names
|
||||
|
@ -8,12 +8,6 @@ dbus_services = {
|
||||
'org.gnome.Shell.Notifications': 'notifications',
|
||||
}
|
||||
|
||||
if enable_recorder
|
||||
dbus_services += {
|
||||
'org.gnome.Shell.Screencast': 'screencast',
|
||||
}
|
||||
endif
|
||||
|
||||
config_dir = '@0@/..'.format(meson.current_build_dir())
|
||||
|
||||
foreach service, dir : dbus_services
|
||||
|
@ -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>
|
@ -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();
|
||||
}
|
@ -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]));
|
||||
});
|
||||
}
|
||||
};
|
@ -953,15 +953,16 @@ var LoginDialog = GObject.registerClass({
|
||||
if (this.opacity == 255 && this._authPrompt.verificationStatus == AuthPrompt.AuthPromptStatus.NOT_VERIFYING)
|
||||
return;
|
||||
|
||||
if (this._authPrompt.verificationStatus !== AuthPrompt.AuthPromptStatus.NOT_VERIFYING)
|
||||
this._authPrompt.reset();
|
||||
|
||||
this._bindOpacity();
|
||||
this.ease({
|
||||
opacity: 255,
|
||||
duration: _FADE_ANIMATION_TIME,
|
||||
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
|
||||
onComplete: () => this._unbindOpacity(),
|
||||
onComplete: () => {
|
||||
if (this._authPrompt.verificationStatus != AuthPrompt.AuthPromptStatus.NOT_VERIFYING)
|
||||
this._authPrompt.reset();
|
||||
this._unbindOpacity();
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -32,7 +32,6 @@
|
||||
<file>misc/util.js</file>
|
||||
<file>misc/weather.js</file>
|
||||
|
||||
<file>perf/basic.js</file>
|
||||
<file>perf/core.js</file>
|
||||
<file>perf/hwtest.js</file>
|
||||
|
||||
@ -93,6 +92,7 @@
|
||||
<file>ui/ripples.js</file>
|
||||
<file>ui/runDialog.js</file>
|
||||
<file>ui/screenShield.js</file>
|
||||
<file>ui/screencast.js</file>
|
||||
<file>ui/screenshot.js</file>
|
||||
<file>ui/scripting.js</file>
|
||||
<file>ui/search.js</file>
|
||||
@ -112,6 +112,7 @@
|
||||
<file>ui/windowManager.js</file>
|
||||
<file>ui/windowPreview.js</file>
|
||||
<file>ui/workspace.js</file>
|
||||
<file>ui/workspaceAnimation.js</file>
|
||||
<file>ui/workspaceSwitcherPopup.js</file>
|
||||
<file>ui/workspaceThumbnail.js</file>
|
||||
<file>ui/workspacesView.js</file>
|
||||
@ -137,6 +138,7 @@
|
||||
<file>ui/status/volume.js</file>
|
||||
<file>ui/status/bluetooth.js</file>
|
||||
<file>ui/status/remoteAccess.js</file>
|
||||
<file>ui/status/screencast.js</file>
|
||||
<file>ui/status/system.js</file>
|
||||
<file>ui/status/thunderbolt.js</file>
|
||||
</gresource>
|
||||
|
@ -1,6 +1,6 @@
|
||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported collectFromDatadirs, recursivelyDeleteDir,
|
||||
recursivelyMoveDir, loadInterfaceXML, loadSubInterfaceXML */
|
||||
recursivelyMoveDir, loadInterfaceXML */
|
||||
|
||||
const { Gio, GLib } = imports.gi;
|
||||
const Config = imports.misc.config;
|
||||
@ -67,19 +67,14 @@ function recursivelyMoveDir(srcDir, destDir) {
|
||||
}
|
||||
|
||||
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) {
|
||||
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 f = Gio.File.new_for_uri(uri);
|
||||
@ -93,25 +88,3 @@ function loadInterfaceXML(iface) {
|
||||
|
||||
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);
|
||||
}
|
||||
|
@ -3,9 +3,9 @@ const { Gio, GLib, Meta, Shell, St } = imports.gi;
|
||||
|
||||
const INTROSPECT_SCHEMA = 'org.gnome.shell';
|
||||
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;
|
||||
|
||||
@ -46,24 +46,19 @@ var IntrospectService = class {
|
||||
|
||||
this._syncRunningApplications();
|
||||
|
||||
this._allowlistMap = new Map();
|
||||
APP_ALLOWLIST.forEach(appName => {
|
||||
this._whitelistMap = new Map();
|
||||
APP_WHITELIST.forEach(appName => {
|
||||
Gio.DBus.watch_name(Gio.BusType.SESSION,
|
||||
appName,
|
||||
Gio.BusNameWatcherFlags.NONE,
|
||||
(conn, name, owner) => this._allowlistMap.set(name, owner),
|
||||
(conn, name) => this._allowlistMap.delete(name));
|
||||
(conn, name, owner) => this._whitelistMap.set(name, owner),
|
||||
(conn, name) => this._whitelistMap.delete(name));
|
||||
});
|
||||
|
||||
this._settings = St.Settings.get();
|
||||
this._settings.connect('notify::enable-animations',
|
||||
this._syncAnimationsEnabled.bind(this));
|
||||
this._syncAnimationsEnabled();
|
||||
|
||||
const monitorManager = Meta.MonitorManager.get();
|
||||
monitorManager.connect('monitors-changed',
|
||||
this._syncScreenSize.bind(this));
|
||||
this._syncScreenSize();
|
||||
}
|
||||
|
||||
_isStandaloneApp(app) {
|
||||
@ -74,8 +69,8 @@ var IntrospectService = class {
|
||||
return this._introspectSettings.get_boolean(INTROSPECT_KEY);
|
||||
}
|
||||
|
||||
_isSenderAllowed(sender) {
|
||||
return [...this._allowlistMap.values()].includes(sender);
|
||||
_isSenderWhitelisted(sender) {
|
||||
return [...this._whitelistMap.values()].includes(sender);
|
||||
}
|
||||
|
||||
_getSandboxedAppId(app) {
|
||||
@ -138,7 +133,7 @@ var IntrospectService = class {
|
||||
if (this._isIntrospectEnabled())
|
||||
return true;
|
||||
|
||||
if (this._isSenderAllowed(invocation.get_sender()))
|
||||
if (this._isSenderWhitelisted(invocation.get_sender()))
|
||||
return true;
|
||||
|
||||
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() {
|
||||
return this._animationsEnabled;
|
||||
}
|
||||
|
||||
get ScreenSize() {
|
||||
return [this._screenWidth, this._screenHeight];
|
||||
}
|
||||
|
||||
get version() {
|
||||
return INTROSPECT_DBUS_API_VERSION;
|
||||
}
|
||||
|
@ -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) {
|
||||
this._proxy.ListSessionsRemote((result, error) => {
|
||||
if (error)
|
||||
@ -220,13 +203,6 @@ var LoginManagerDummy = class {
|
||||
asyncCallback(false, false);
|
||||
}
|
||||
|
||||
canRebootToBootLoaderMenu(asyncCallback) {
|
||||
asyncCallback(false, false);
|
||||
}
|
||||
|
||||
setRebootToBootLoaderMenu() {
|
||||
}
|
||||
|
||||
listSessions(asyncCallback) {
|
||||
asyncCallback([]);
|
||||
}
|
||||
|
@ -121,10 +121,10 @@ var ParentalControlsManager = GObject.registerClass({
|
||||
// Calculate whether the given app (a Gio.DesktopAppInfo) should be shown
|
||||
// on the desktop, in search results, etc. The app should be shown if:
|
||||
// - The .desktop file doesn’t say it should be hidden.
|
||||
// - The executable from the .desktop file’s Exec line isn’t denied in
|
||||
// - The executable from the .desktop file’s Exec line isn’t blacklisted in
|
||||
// the user’s parental controls.
|
||||
// - None of the flatpak app IDs from the X-Flatpak and the
|
||||
// X-Flatpak-RenamedFrom lines are denied in the user’s parental
|
||||
// X-Flatpak-RenamedFrom lines are blacklisted in the user’s parental
|
||||
// controls.
|
||||
shouldShowApp(appInfo) {
|
||||
// Quick decision?
|
||||
|
@ -21,7 +21,6 @@ const SENSOR_OBJECT_PATH = '/net/hadess/SensorProxy';
|
||||
const SensorProxyInterface = loadInterfaceXML('net.hadess.SensorProxy');
|
||||
|
||||
const POWER_OFF_ACTION_ID = 'power-off';
|
||||
const RESTART_ACTION_ID = 'restart';
|
||||
const LOCK_SCREEN_ACTION_ID = 'lock-screen';
|
||||
const LOGOUT_ACTION_ID = 'logout';
|
||||
const SUSPEND_ACTION_ID = 'suspend';
|
||||
@ -41,38 +40,41 @@ function getDefault() {
|
||||
|
||||
const SystemActions = GObject.registerClass({
|
||||
Properties: {
|
||||
'can-power-off': GObject.ParamSpec.boolean(
|
||||
'can-power-off', 'can-power-off', 'can-power-off',
|
||||
GObject.ParamFlags.READABLE,
|
||||
false),
|
||||
'can-restart': GObject.ParamSpec.boolean(
|
||||
'can-restart', 'can-restart', 'can-restart',
|
||||
GObject.ParamFlags.READABLE,
|
||||
false),
|
||||
'can-suspend': GObject.ParamSpec.boolean(
|
||||
'can-suspend', 'can-suspend', 'can-suspend',
|
||||
GObject.ParamFlags.READABLE,
|
||||
false),
|
||||
'can-lock-screen': GObject.ParamSpec.boolean(
|
||||
'can-lock-screen', 'can-lock-screen', 'can-lock-screen',
|
||||
GObject.ParamFlags.READABLE,
|
||||
false),
|
||||
'can-switch-user': GObject.ParamSpec.boolean(
|
||||
'can-switch-user', 'can-switch-user', 'can-switch-user',
|
||||
GObject.ParamFlags.READABLE,
|
||||
false),
|
||||
'can-logout': GObject.ParamSpec.boolean(
|
||||
'can-logout', 'can-logout', 'can-logout',
|
||||
GObject.ParamFlags.READABLE,
|
||||
false),
|
||||
'can-lock-orientation': GObject.ParamSpec.boolean(
|
||||
'can-lock-orientation', 'can-lock-orientation', 'can-lock-orientation',
|
||||
GObject.ParamFlags.READABLE,
|
||||
false),
|
||||
'orientation-lock-icon': GObject.ParamSpec.string(
|
||||
'orientation-lock-icon', 'orientation-lock-icon', 'orientation-lock-icon',
|
||||
GObject.ParamFlags.READWRITE,
|
||||
null),
|
||||
'can-power-off': GObject.ParamSpec.boolean('can-power-off',
|
||||
'can-power-off',
|
||||
'can-power-off',
|
||||
GObject.ParamFlags.READABLE,
|
||||
false),
|
||||
'can-suspend': GObject.ParamSpec.boolean('can-suspend',
|
||||
'can-suspend',
|
||||
'can-suspend',
|
||||
GObject.ParamFlags.READABLE,
|
||||
false),
|
||||
'can-lock-screen': GObject.ParamSpec.boolean('can-lock-screen',
|
||||
'can-lock-screen',
|
||||
'can-lock-screen',
|
||||
GObject.ParamFlags.READABLE,
|
||||
false),
|
||||
'can-switch-user': GObject.ParamSpec.boolean('can-switch-user',
|
||||
'can-switch-user',
|
||||
'can-switch-user',
|
||||
GObject.ParamFlags.READABLE,
|
||||
false),
|
||||
'can-logout': GObject.ParamSpec.boolean('can-logout',
|
||||
'can-logout',
|
||||
'can-logout',
|
||||
GObject.ParamFlags.READABLE,
|
||||
false),
|
||||
'can-lock-orientation': GObject.ParamSpec.boolean('can-lock-orientation',
|
||||
'can-lock-orientation',
|
||||
'can-lock-orientation',
|
||||
GObject.ParamFlags.READABLE,
|
||||
false),
|
||||
'orientation-lock-icon': GObject.ParamSpec.string('orientation-lock-icon',
|
||||
'orientation-lock-icon',
|
||||
'orientation-lock-icon',
|
||||
GObject.ParamFlags.READWRITE,
|
||||
null),
|
||||
},
|
||||
}, class SystemActions extends GObject.Object {
|
||||
_init() {
|
||||
@ -91,15 +93,7 @@ const SystemActions = GObject.registerClass({
|
||||
name: C_("search-result", "Power Off"),
|
||||
iconName: 'system-shutdown-symbolic',
|
||||
// Translators: A list of keywords that match the power-off action, separated by semicolons
|
||||
keywords: tokenizeKeywords(_('power off;shutdown;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;')),
|
||||
keywords: tokenizeKeywords(_('power off;shutdown;reboot;restart;halt;stop')),
|
||||
available: false,
|
||||
});
|
||||
this._actions.set(LOCK_SCREEN_ACTION_ID, {
|
||||
@ -209,11 +203,6 @@ const SystemActions = GObject.registerClass({
|
||||
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
|
||||
get can_suspend() {
|
||||
return this._actions.get(SUSPEND_ACTION_ID).available;
|
||||
@ -317,9 +306,6 @@ const SystemActions = GObject.registerClass({
|
||||
case POWER_OFF_ACTION_ID:
|
||||
this.activatePowerOff();
|
||||
break;
|
||||
case RESTART_ACTION_ID:
|
||||
this.activateRestart();
|
||||
break;
|
||||
case LOCK_SCREEN_ACTION_ID:
|
||||
this.activateLockScreen();
|
||||
break;
|
||||
@ -361,9 +347,6 @@ const SystemActions = GObject.registerClass({
|
||||
this._loginScreenSettings.get_boolean(DISABLE_RESTART_KEY));
|
||||
this._actions.get(POWER_OFF_ACTION_ID).available = this._canHavePowerOff && !disabled;
|
||||
this.notify('can-power-off');
|
||||
|
||||
this._actions.get(RESTART_ACTION_ID).available = this._canHavePowerOff && !disabled;
|
||||
this.notify('can-restart');
|
||||
}
|
||||
|
||||
_updateHaveSuspend() {
|
||||
@ -462,13 +445,6 @@ const SystemActions = GObject.registerClass({
|
||||
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() {
|
||||
if (!this._actions.get(SUSPEND_ACTION_ID).available)
|
||||
throw new Error('The suspend action is not available!');
|
||||
|
146
js/perf/basic.js
146
js/perf/basic.js
@ -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');
|
||||
}
|
@ -70,8 +70,7 @@ let WINDOW_CONFIGS = [
|
||||
{ width: 640, height: 480, alpha: true, maximized: false, count: 10, metric: 'overviewFps10Alpha' },
|
||||
];
|
||||
|
||||
async function run() {
|
||||
/* eslint-disable no-await-in-loop */
|
||||
function *run() {
|
||||
Scripting.defineScriptEvent("overviewShowStart", "Starting to show the overview");
|
||||
Scripting.defineScriptEvent("overviewShowDone", "Overview finished showing");
|
||||
Scripting.defineScriptEvent("afterShowHide", "After a show/hide cycle for the overview");
|
||||
@ -85,7 +84,7 @@ async function run() {
|
||||
Scripting.scriptEvent('overviewShowDone');
|
||||
});
|
||||
|
||||
await Scripting.sleep(1000);
|
||||
yield Scripting.sleep(1000);
|
||||
|
||||
for (let i = 0; i < 2 * WINDOW_CONFIGS.length; i++) {
|
||||
// We go to the overview twice for each configuration; the first time
|
||||
@ -93,50 +92,49 @@ async function run() {
|
||||
// a clean set of numbers.
|
||||
if ((i % 2) == 0) {
|
||||
let config = WINDOW_CONFIGS[i / 2];
|
||||
await Scripting.destroyTestWindows();
|
||||
yield Scripting.destroyTestWindows();
|
||||
|
||||
for (let k = 0; k < config.count; k++) {
|
||||
await Scripting.createTestWindow({ width: config.width,
|
||||
yield Scripting.createTestWindow({ width: config.width,
|
||||
height: config.height,
|
||||
alpha: config.alpha,
|
||||
maximized: config.maximized });
|
||||
}
|
||||
|
||||
await Scripting.waitTestWindows();
|
||||
await Scripting.sleep(1000);
|
||||
await Scripting.waitLeisure();
|
||||
yield Scripting.waitTestWindows();
|
||||
yield Scripting.sleep(1000);
|
||||
yield Scripting.waitLeisure();
|
||||
}
|
||||
|
||||
Scripting.scriptEvent('overviewShowStart');
|
||||
Main.overview.show();
|
||||
|
||||
await Scripting.waitLeisure();
|
||||
yield Scripting.waitLeisure();
|
||||
Main.overview.hide();
|
||||
await Scripting.waitLeisure();
|
||||
yield Scripting.waitLeisure();
|
||||
|
||||
System.gc();
|
||||
await Scripting.sleep(1000);
|
||||
yield Scripting.sleep(1000);
|
||||
Scripting.collectStatistics();
|
||||
Scripting.scriptEvent('afterShowHide');
|
||||
}
|
||||
|
||||
await Scripting.destroyTestWindows();
|
||||
await Scripting.sleep(1000);
|
||||
yield Scripting.destroyTestWindows();
|
||||
yield Scripting.sleep(1000);
|
||||
|
||||
Main.overview.show();
|
||||
await Scripting.waitLeisure();
|
||||
yield Scripting.waitLeisure();
|
||||
|
||||
for (let i = 0; i < 2; i++) {
|
||||
Scripting.scriptEvent('applicationsShowStart');
|
||||
// eslint-disable-next-line require-atomic-updates
|
||||
Main.overview.dash.showAppsButton.checked = true;
|
||||
await Scripting.waitLeisure();
|
||||
yield Scripting.waitLeisure();
|
||||
Scripting.scriptEvent('applicationsShowDone');
|
||||
// eslint-disable-next-line require-atomic-updates
|
||||
Main.overview.dash.showAppsButton.checked = false;
|
||||
await Scripting.waitLeisure();
|
||||
yield Scripting.waitLeisure();
|
||||
}
|
||||
/* eslint-enable no-await-in-loop */
|
||||
}
|
||||
|
||||
let showingOverview = false;
|
||||
|
@ -94,8 +94,7 @@ function extractBootTimestamp() {
|
||||
return result;
|
||||
}
|
||||
|
||||
async function run() {
|
||||
/* eslint-disable no-await-in-loop */
|
||||
function *run() {
|
||||
Scripting.defineScriptEvent("desktopShown", "Finished initial animation");
|
||||
Scripting.defineScriptEvent("overviewShowStart", "Starting to show the overview");
|
||||
Scripting.defineScriptEvent("overviewShowDone", "Overview finished showing");
|
||||
@ -111,7 +110,7 @@ async function run() {
|
||||
Scripting.defineScriptEvent("geditLaunch", "gedit application launch");
|
||||
Scripting.defineScriptEvent("geditFirstFrame", "first frame of gedit window drawn");
|
||||
|
||||
await Scripting.waitLeisure();
|
||||
yield Scripting.waitLeisure();
|
||||
Scripting.scriptEvent('desktopShown');
|
||||
|
||||
let interfaceSettings = new Gio.Settings({
|
||||
@ -121,22 +120,22 @@ async function run() {
|
||||
|
||||
Scripting.scriptEvent('overviewShowStart');
|
||||
Main.overview.show();
|
||||
await Scripting.waitLeisure();
|
||||
yield Scripting.waitLeisure();
|
||||
Scripting.scriptEvent('overviewShowDone');
|
||||
|
||||
await Scripting.sleep(1000);
|
||||
yield Scripting.sleep(1000);
|
||||
|
||||
Scripting.scriptEvent('applicationsShowStart');
|
||||
// eslint-disable-next-line require-atomic-updates
|
||||
Main.overview.dash.showAppsButton.checked = true;
|
||||
|
||||
await Scripting.waitLeisure();
|
||||
yield Scripting.waitLeisure();
|
||||
Scripting.scriptEvent('applicationsShowDone');
|
||||
|
||||
await Scripting.sleep(1000);
|
||||
yield Scripting.sleep(1000);
|
||||
|
||||
Main.overview.hide();
|
||||
await Scripting.waitLeisure();
|
||||
yield Scripting.waitLeisure();
|
||||
|
||||
// --------------------- //
|
||||
// Tests of redraw speed //
|
||||
@ -146,46 +145,46 @@ async function run() {
|
||||
global.frame_finish_timestamp = true;
|
||||
|
||||
for (let k = 0; k < 5; k++)
|
||||
await Scripting.createTestWindow({ maximized: true });
|
||||
await Scripting.waitTestWindows();
|
||||
yield Scripting.createTestWindow({ maximized: true });
|
||||
yield Scripting.waitTestWindows();
|
||||
|
||||
await Scripting.sleep(1000);
|
||||
yield Scripting.sleep(1000);
|
||||
|
||||
Scripting.scriptEvent('mainViewDrawStart');
|
||||
await waitAndDraw(1000);
|
||||
yield waitAndDraw(1000);
|
||||
Scripting.scriptEvent('mainViewDrawDone');
|
||||
|
||||
Main.overview.show();
|
||||
Scripting.waitLeisure();
|
||||
|
||||
await Scripting.sleep(1500);
|
||||
yield Scripting.sleep(1500);
|
||||
|
||||
Scripting.scriptEvent('overviewDrawStart');
|
||||
await waitAndDraw(1000);
|
||||
yield waitAndDraw(1000);
|
||||
Scripting.scriptEvent('overviewDrawDone');
|
||||
|
||||
await Scripting.destroyTestWindows();
|
||||
yield Scripting.destroyTestWindows();
|
||||
Main.overview.hide();
|
||||
|
||||
await Scripting.createTestWindow({ maximized: true,
|
||||
yield Scripting.createTestWindow({ maximized: true,
|
||||
redraws: true });
|
||||
await Scripting.waitTestWindows();
|
||||
yield Scripting.waitTestWindows();
|
||||
|
||||
await Scripting.sleep(1000);
|
||||
yield Scripting.sleep(1000);
|
||||
|
||||
Scripting.scriptEvent('redrawTestStart');
|
||||
await Scripting.sleep(1000);
|
||||
yield Scripting.sleep(1000);
|
||||
Scripting.scriptEvent('redrawTestDone');
|
||||
|
||||
await Scripting.sleep(1000);
|
||||
yield Scripting.sleep(1000);
|
||||
Scripting.scriptEvent('collectTimings');
|
||||
|
||||
await Scripting.destroyTestWindows();
|
||||
yield Scripting.destroyTestWindows();
|
||||
|
||||
global.frame_timestamps = false;
|
||||
global.frame_finish_timestamp = false;
|
||||
|
||||
await Scripting.sleep(1000);
|
||||
yield Scripting.sleep(1000);
|
||||
|
||||
let appSys = Shell.AppSystem.get_default();
|
||||
let app = appSys.lookup_app('org.gnome.gedit.desktop');
|
||||
@ -198,22 +197,21 @@ async function run() {
|
||||
throw new Error('gedit was already running');
|
||||
|
||||
while (windows.length == 0) {
|
||||
await waitSignal(global.display, 'window-created');
|
||||
yield waitSignal(global.display, 'window-created');
|
||||
windows = app.get_windows();
|
||||
}
|
||||
|
||||
let actor = windows[0].get_compositor_private();
|
||||
await waitSignal(actor, 'first-frame');
|
||||
yield waitSignal(actor, 'first-frame');
|
||||
Scripting.scriptEvent('geditFirstFrame');
|
||||
|
||||
await Scripting.sleep(1000);
|
||||
yield Scripting.sleep(1000);
|
||||
|
||||
windows[0].delete(global.get_current_time());
|
||||
|
||||
await Scripting.sleep(1000);
|
||||
yield Scripting.sleep(1000);
|
||||
|
||||
interfaceSettings.set_boolean('enable-animations', true);
|
||||
/* eslint-enable no-await-in-loop */
|
||||
}
|
||||
|
||||
let overviewShowStart;
|
||||
|
@ -1541,7 +1541,7 @@ class AppViewItem extends St.Button {
|
||||
return false;
|
||||
|
||||
if (this._withinLeeways(x))
|
||||
return false;
|
||||
return DND.DragMotionResult.CONTINUE;
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -2335,8 +2335,13 @@ var AppFolderDialog = GObject.registerClass({
|
||||
}
|
||||
|
||||
_withinDialog(x, y) {
|
||||
const childExtents = this.child.get_transformed_extents();
|
||||
return childExtents.contains_point(new Graphene.Point({ x, y }));
|
||||
const childAllocation =
|
||||
Shell.util_get_transformed_allocation(this.child);
|
||||
|
||||
return x > childAllocation.x1 &&
|
||||
x < childAllocation.x2 &&
|
||||
y > childAllocation.y1 &&
|
||||
y < childAllocation.y2;
|
||||
}
|
||||
|
||||
_setupDragMonitor() {
|
||||
|
@ -347,8 +347,6 @@ var Background = GObject.registerClass({
|
||||
this.set_color(color);
|
||||
else
|
||||
this.set_gradient(shadingType, color, secondColor);
|
||||
|
||||
this._setLoaded();
|
||||
}
|
||||
|
||||
_watchFile(file) {
|
||||
@ -767,27 +765,10 @@ var BackgroundManager = class BackgroundManager {
|
||||
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', () => {
|
||||
if (changeSignalId)
|
||||
background.disconnect(changeSignalId);
|
||||
|
||||
if (loadedSignalId)
|
||||
background.disconnect(loadedSignalId);
|
||||
|
||||
if (backgroundActor.loadedSignalId)
|
||||
background.disconnect(backgroundActor.loadedSignalId);
|
||||
});
|
||||
|
@ -1,7 +1,7 @@
|
||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported BoxPointer */
|
||||
|
||||
const { Clutter, GObject, St } = imports.gi;
|
||||
const { Clutter, GObject, Shell, St } = imports.gi;
|
||||
|
||||
const Main = imports.ui.main;
|
||||
|
||||
@ -453,16 +453,15 @@ var BoxPointer = GObject.registerClass({
|
||||
let alignment = this._arrowAlignment;
|
||||
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);
|
||||
|
||||
// Position correctly relative to the sourceActor
|
||||
let sourceNode = sourceActor.get_theme_node();
|
||||
let sourceContentBox = sourceNode.get_content_box(sourceActor.get_allocation_box());
|
||||
let sourceTopLeft = this._sourceExtents.get_top_left();
|
||||
let sourceBottomRight = this._sourceExtents.get_bottom_right();
|
||||
let sourceCenterX = sourceTopLeft.x + sourceContentBox.x1 + (sourceContentBox.x2 - sourceContentBox.x1) * this._sourceAlignment;
|
||||
let sourceCenterY = sourceTopLeft.y + sourceContentBox.y1 + (sourceContentBox.y2 - sourceContentBox.y1) * this._sourceAlignment;
|
||||
let sourceAllocation = this._sourceAllocation;
|
||||
let sourceCenterX = sourceAllocation.x1 + sourceContentBox.x1 + (sourceContentBox.x2 - sourceContentBox.x1) * this._sourceAlignment;
|
||||
let sourceCenterY = sourceAllocation.y1 + sourceContentBox.y1 + (sourceContentBox.y2 - sourceContentBox.y1) * this._sourceAlignment;
|
||||
let [, , natWidth, natHeight] = this.get_preferred_size();
|
||||
|
||||
// We also want to keep it onscreen, and separated from the
|
||||
@ -482,16 +481,16 @@ var BoxPointer = GObject.registerClass({
|
||||
|
||||
switch (this._arrowSide) {
|
||||
case St.Side.TOP:
|
||||
resY = sourceBottomRight.y + gap;
|
||||
resY = sourceAllocation.y2 + gap;
|
||||
break;
|
||||
case St.Side.BOTTOM:
|
||||
resY = sourceTopLeft.y - natHeight - gap;
|
||||
resY = sourceAllocation.y1 - natHeight - gap;
|
||||
break;
|
||||
case St.Side.LEFT:
|
||||
resX = sourceBottomRight.x + gap;
|
||||
resX = sourceAllocation.x2 + gap;
|
||||
break;
|
||||
case St.Side.RIGHT:
|
||||
resX = sourceTopLeft.x - natWidth - gap;
|
||||
resX = sourceAllocation.x1 - natWidth - gap;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -587,30 +586,29 @@ var BoxPointer = GObject.registerClass({
|
||||
}
|
||||
|
||||
_calculateArrowSide(arrowSide) {
|
||||
let sourceTopLeft = this._sourceExtents.get_top_left();
|
||||
let sourceBottomRight = this._sourceExtents.get_bottom_right();
|
||||
let sourceAllocation = this._sourceAllocation;
|
||||
let [, , boxWidth, boxHeight] = this.get_preferred_size();
|
||||
let workarea = this._workArea;
|
||||
|
||||
switch (arrowSide) {
|
||||
case St.Side.TOP:
|
||||
if (sourceBottomRight.y + boxHeight > workarea.y + workarea.height &&
|
||||
boxHeight < sourceTopLeft.y - workarea.y)
|
||||
if (sourceAllocation.y2 + boxHeight > workarea.y + workarea.height &&
|
||||
boxHeight < sourceAllocation.y1 - workarea.y)
|
||||
return St.Side.BOTTOM;
|
||||
break;
|
||||
case St.Side.BOTTOM:
|
||||
if (sourceTopLeft.y - boxHeight < workarea.y &&
|
||||
boxHeight < workarea.y + workarea.height - sourceBottomRight.y)
|
||||
if (sourceAllocation.y1 - boxHeight < workarea.y &&
|
||||
boxHeight < workarea.y + workarea.height - sourceAllocation.y2)
|
||||
return St.Side.TOP;
|
||||
break;
|
||||
case St.Side.LEFT:
|
||||
if (sourceBottomRight.x + boxWidth > workarea.x + workarea.width &&
|
||||
boxWidth < sourceTopLeft.x - workarea.x)
|
||||
if (sourceAllocation.x2 + boxWidth > workarea.x + workarea.width &&
|
||||
boxWidth < sourceAllocation.x1 - workarea.x)
|
||||
return St.Side.RIGHT;
|
||||
break;
|
||||
case St.Side.RIGHT:
|
||||
if (sourceTopLeft.x - boxWidth < workarea.x &&
|
||||
boxWidth < workarea.x + workarea.width - sourceBottomRight.x)
|
||||
if (sourceAllocation.x1 - boxWidth < workarea.x &&
|
||||
boxWidth < workarea.x + workarea.width - sourceAllocation.x2)
|
||||
return St.Side.LEFT;
|
||||
break;
|
||||
}
|
||||
|
11
js/ui/dnd.js
11
js/ui/dnd.js
@ -388,16 +388,17 @@ var _Draggable = class _Draggable {
|
||||
const [, newAllocatedWidth] = this._dragActor.get_preferred_width(-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
|
||||
// transformed size when it's reparented to the uiGroup
|
||||
this._dragActor.set_scale(
|
||||
transformedExtents.get_width() / newAllocatedWidth,
|
||||
transformedExtents.get_height() / newAllocatedHeight);
|
||||
transformedAllocation.get_width() / newAllocatedWidth,
|
||||
transformedAllocation.get_height() / newAllocatedHeight);
|
||||
|
||||
this._dragOffsetX = transformedExtents.origin.x - this._dragStartX;
|
||||
this._dragOffsetY = transformedExtents.origin.y - this._dragStartY;
|
||||
this._dragOffsetX = transformedAllocation.x1 - this._dragStartX;
|
||||
this._dragOffsetY = transformedAllocation.y1 - this._dragStartY;
|
||||
|
||||
this._dragOrigParent.remove_actor(this._dragActor);
|
||||
Main.uiGroup.add_child(this._dragActor);
|
||||
|
@ -18,7 +18,7 @@
|
||||
*/
|
||||
|
||||
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 Dialog = imports.ui.dialog;
|
||||
@ -31,30 +31,24 @@ const { loadInterfaceXML } = imports.misc.fileUtils;
|
||||
|
||||
const _ITEM_ICON_SIZE = 64;
|
||||
|
||||
const LOW_BATTERY_THRESHOLD = 30;
|
||||
|
||||
const EndSessionDialogIface = loadInterfaceXML('org.gnome.SessionManager.EndSessionDialog');
|
||||
|
||||
const logoutDialogContent = {
|
||||
subjectWithUser: C_("title", "Log Out %s"),
|
||||
subject: C_("title", "Log Out"),
|
||||
descriptionWithUser(user, seconds) {
|
||||
return ngettext(
|
||||
'%s will be logged out automatically in %d second.',
|
||||
'%s will be logged out automatically in %d seconds.',
|
||||
seconds).format(user, seconds);
|
||||
return ngettext("%s will be logged out automatically in %d second.",
|
||||
"%s will be logged out automatically in %d seconds.",
|
||||
seconds).format(user, seconds);
|
||||
},
|
||||
description(seconds) {
|
||||
return ngettext(
|
||||
'You will be logged out automatically in %d second.',
|
||||
'You will be logged out automatically in %d seconds.',
|
||||
seconds).format(seconds);
|
||||
return ngettext("You will be logged out automatically in %d second.",
|
||||
"You will be logged out automatically in %d seconds.",
|
||||
seconds).format(seconds);
|
||||
},
|
||||
showBatteryWarning: false,
|
||||
confirmButtons: [{
|
||||
signal: 'ConfirmedLogout',
|
||||
label: C_('button', 'Log Out'),
|
||||
}],
|
||||
confirmButtons: [{ signal: 'ConfirmedLogout',
|
||||
label: C_("button", "Log Out") }],
|
||||
showOtherSessions: false,
|
||||
};
|
||||
|
||||
@ -62,36 +56,30 @@ const shutdownDialogContent = {
|
||||
subject: C_("title", "Power Off"),
|
||||
subjectWithUpdates: C_("title", "Install Updates & Power Off"),
|
||||
description(seconds) {
|
||||
return ngettext(
|
||||
'The system will power off automatically in %d second.',
|
||||
'The system will power off automatically in %d seconds.',
|
||||
seconds).format(seconds);
|
||||
return ngettext("The system will power off automatically in %d second.",
|
||||
"The system will power off automatically in %d seconds.",
|
||||
seconds).format(seconds);
|
||||
},
|
||||
checkBoxText: C_("checkbox", "Install pending software updates"),
|
||||
showBatteryWarning: true,
|
||||
confirmButtons: [{
|
||||
signal: 'ConfirmedShutdown',
|
||||
label: C_('button', 'Power Off'),
|
||||
}],
|
||||
confirmButtons: [{ signal: 'ConfirmedReboot',
|
||||
label: C_("button", "Restart") },
|
||||
{ signal: 'ConfirmedShutdown',
|
||||
label: C_("button", "Power Off") }],
|
||||
iconName: 'system-shutdown-symbolic',
|
||||
showOtherSessions: true,
|
||||
};
|
||||
|
||||
const restartDialogContent = {
|
||||
subject: C_("title", "Restart"),
|
||||
subjectWithUpdates: C_('title', 'Install Updates & Restart'),
|
||||
description(seconds) {
|
||||
return ngettext(
|
||||
'The system will restart automatically in %d second.',
|
||||
'The system will restart automatically in %d seconds.',
|
||||
seconds).format(seconds);
|
||||
return ngettext("The system will restart automatically in %d second.",
|
||||
"The system will restart automatically in %d seconds.",
|
||||
seconds).format(seconds);
|
||||
},
|
||||
checkBoxText: C_('checkbox', 'Install pending software updates'),
|
||||
showBatteryWarning: true,
|
||||
confirmButtons: [{
|
||||
signal: 'ConfirmedReboot',
|
||||
label: C_('button', 'Restart'),
|
||||
}],
|
||||
showBatteryWarning: false,
|
||||
confirmButtons: [{ signal: 'ConfirmedReboot',
|
||||
label: C_("button", "Restart") }],
|
||||
iconName: 'view-refresh-symbolic',
|
||||
showOtherSessions: true,
|
||||
};
|
||||
@ -100,16 +88,13 @@ const restartUpdateDialogContent = {
|
||||
|
||||
subject: C_("title", "Restart & Install Updates"),
|
||||
description(seconds) {
|
||||
return ngettext(
|
||||
'The system will automatically restart and install updates in %d second.',
|
||||
'The system will automatically restart and install updates in %d seconds.',
|
||||
seconds).format(seconds);
|
||||
return ngettext("The system will automatically restart and install updates in %d second.",
|
||||
"The system will automatically restart and install updates in %d seconds.",
|
||||
seconds).format(seconds);
|
||||
},
|
||||
showBatteryWarning: true,
|
||||
confirmButtons: [{
|
||||
signal: 'ConfirmedReboot',
|
||||
label: C_('button', 'Restart & Install'),
|
||||
}],
|
||||
confirmButtons: [{ signal: 'ConfirmedReboot',
|
||||
label: C_("button", "Restart & Install") }],
|
||||
unusedFutureButtonForTranslation: C_("button", "Install & Power Off"),
|
||||
unusedFutureCheckBoxForTranslation: C_("checkbox", "Power off after updates are installed"),
|
||||
iconName: 'view-refresh-symbolic',
|
||||
@ -127,10 +112,8 @@ const restartUpgradeDialogContent = {
|
||||
},
|
||||
disableTimer: true,
|
||||
showBatteryWarning: false,
|
||||
confirmButtons: [{
|
||||
signal: 'ConfirmedReboot',
|
||||
label: C_('button', 'Restart & Install'),
|
||||
}],
|
||||
confirmButtons: [{ signal: 'ConfirmedReboot',
|
||||
label: C_("button", "Restart & Install") }],
|
||||
iconName: 'view-refresh-symbolic',
|
||||
showOtherSessions: true,
|
||||
};
|
||||
@ -159,7 +142,7 @@ const LogindSession = Gio.DBusProxy.makeProxyWrapper(LogindSessionIface);
|
||||
const PkOfflineIface = loadInterfaceXML('org.freedesktop.PackageKit.Offline');
|
||||
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);
|
||||
|
||||
function findAppFromInhibitor(inhibitor) {
|
||||
@ -230,11 +213,6 @@ class EndSessionDialog extends ModalDialog.ModalDialog {
|
||||
destroyOnClose: false });
|
||||
|
||||
this._loginManager = LoginManager.getLoginManager();
|
||||
this._loginManager.canRebootToBootLoaderMenu(
|
||||
(canRebootToBootLoaderMenu, unusedNeedsAuth) => {
|
||||
this._canRebootToBootLoaderMenu = canRebootToBootLoaderMenu;
|
||||
});
|
||||
|
||||
this._userManager = AccountsService.UserManager.get_default();
|
||||
this._user = this._userManager.get_user(GLib.get_user_name());
|
||||
this._updatesPermission = null;
|
||||
@ -246,7 +224,7 @@ class EndSessionDialog extends ModalDialog.ModalDialog {
|
||||
|
||||
this._powerProxy = new UPowerProxy(Gio.DBus.system,
|
||||
'org.freedesktop.UPower',
|
||||
'/org/freedesktop/UPower/devices/DisplayDevice',
|
||||
'/org/freedesktop/UPower',
|
||||
(proxy, error) => {
|
||||
if (error) {
|
||||
log(error.message);
|
||||
@ -261,9 +239,6 @@ class EndSessionDialog extends ModalDialog.ModalDialog {
|
||||
this._totalSecondsToStayOpen = 0;
|
||||
this._applications = [];
|
||||
this._sessions = [];
|
||||
this._capturedEventId = 0;
|
||||
this._rebootButton = null;
|
||||
this._rebootButtonAlt = null;
|
||||
|
||||
this.connect('destroy',
|
||||
this._onDestroy.bind(this));
|
||||
@ -281,7 +256,7 @@ class EndSessionDialog extends ModalDialog.ModalDialog {
|
||||
|
||||
this._batteryWarning = new St.Label({
|
||||
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.line_wrap = true;
|
||||
@ -331,32 +306,6 @@ class EndSessionDialog extends ModalDialog.ModalDialog {
|
||||
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() {
|
||||
let open = this.state == ModalDialog.State.OPENING || this.state == ModalDialog.State.OPENED;
|
||||
if (!open)
|
||||
@ -370,7 +319,10 @@ class EndSessionDialog extends ModalDialog.ModalDialog {
|
||||
if (dialogContent.subjectWithUpdates && this._checkBox.checked)
|
||||
subject = dialogContent.subjectWithUpdates;
|
||||
|
||||
this._batteryWarning.visible = this._shouldShowLowBatteryWarning(dialogContent);
|
||||
if (dialogContent.showBatteryWarning) {
|
||||
this._batteryWarning.visible =
|
||||
this._powerProxy.OnBattery && this._checkBox.checked;
|
||||
}
|
||||
|
||||
let description;
|
||||
let displayTime = _roundSecondsToInterval(this._totalSecondsToStayOpen,
|
||||
@ -411,38 +363,16 @@ class EndSessionDialog extends ModalDialog.ModalDialog {
|
||||
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() {
|
||||
this.clearButtons();
|
||||
|
||||
this.addButton({ action: this.cancel.bind(this),
|
||||
label: _("Cancel"),
|
||||
key: Clutter.KEY_Escape });
|
||||
|
||||
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++) {
|
||||
let signal = dialogContent.confirmButtons[i].signal;
|
||||
let label = dialogContent.confirmButtons[i].label;
|
||||
let button = this.addButton({
|
||||
buttons.push({
|
||||
action: () => {
|
||||
this.close(true);
|
||||
let signalId = this.connect('closed', () => {
|
||||
@ -452,34 +382,9 @@ class EndSessionDialog extends ModalDialog.ModalDialog {
|
||||
},
|
||||
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() {
|
||||
if (this._capturedEventId > 0) {
|
||||
global.stage.disconnect(this._capturedEventId);
|
||||
this._capturedEventId = 0;
|
||||
}
|
||||
this._rebootButton = null;
|
||||
this._rebootButtonAlt = null;
|
||||
this.setButtons(buttons);
|
||||
}
|
||||
|
||||
close(skipSignal) {
|
||||
@ -491,21 +396,14 @@ class EndSessionDialog extends ModalDialog.ModalDialog {
|
||||
|
||||
cancel() {
|
||||
this._stopTimer();
|
||||
this._stopAltCapture();
|
||||
this._dbusImpl.emit_signal('Canceled', null);
|
||||
this.close();
|
||||
}
|
||||
|
||||
_confirmRebootToBootLoaderMenu() {
|
||||
this._loginManager.setRebootToBootLoaderMenu();
|
||||
this._confirm('ConfirmedReboot');
|
||||
}
|
||||
|
||||
_confirm(signal) {
|
||||
let callback = () => {
|
||||
this._fadeOutDialog();
|
||||
this._stopTimer();
|
||||
this._stopAltCapture();
|
||||
this._dbusImpl.emit_signal(signal, null);
|
||||
};
|
||||
|
||||
@ -773,17 +671,19 @@ class EndSessionDialog extends ModalDialog.ModalDialog {
|
||||
if (dialogContent.showOtherSessions)
|
||||
this._loadSessions();
|
||||
|
||||
let updateTriggered = this._updateInfo.UpdateTriggered;
|
||||
let updatePrepared = this._updateInfo.UpdatePrepared;
|
||||
let updatesAllowed = this._updatesPermission && this._updatesPermission.allowed;
|
||||
|
||||
_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)
|
||||
this._checkBox.checked = this._checkBox.visible && this._updateInfo.UpdateTriggered && !this._isDischargingBattery();
|
||||
else
|
||||
this._checkBox.checked = this._checkBox.visible && !this._isBatteryLow();
|
||||
|
||||
this._batteryWarning.visible = this._shouldShowLowBatteryWarning(dialogContent);
|
||||
// We show the warning either together with the checkbox, or when
|
||||
// updates have already been triggered, but the user doesn't have
|
||||
// enough permissions to cancel them.
|
||||
this._batteryWarning.visible = dialogContent.showBatteryWarning &&
|
||||
(this._checkBox.visible || updatePrepared && updateTriggered && !updatesAllowed);
|
||||
|
||||
this._updateButtons();
|
||||
|
||||
|
@ -134,14 +134,7 @@ function _easeActor(actor, params) {
|
||||
actor.set_easing_mode(params.mode);
|
||||
delete params.mode;
|
||||
|
||||
const prepare = () => {
|
||||
Meta.disable_unredirect_for_display(global.display);
|
||||
global.begin_work();
|
||||
};
|
||||
const cleanup = () => {
|
||||
Meta.enable_unredirect_for_display(global.display);
|
||||
global.end_work();
|
||||
};
|
||||
let cleanup = () => Meta.enable_unredirect_for_display(global.display);
|
||||
let callback = _makeEaseCallback(params, cleanup);
|
||||
|
||||
// cancel overwritten transitions
|
||||
@ -156,9 +149,9 @@ function _easeActor(actor, params) {
|
||||
.find(t => t !== null);
|
||||
|
||||
if (transition && transition.delay)
|
||||
transition.connect('started', () => prepare());
|
||||
transition.connect('started', () => Meta.disable_unredirect_for_display(global.display));
|
||||
else
|
||||
prepare();
|
||||
Meta.disable_unredirect_for_display(global.display);
|
||||
|
||||
if (transition) {
|
||||
transition.set({ repeatCount, autoReverse });
|
||||
@ -198,14 +191,7 @@ function _easeActorProperty(actor, propName, target, params) {
|
||||
if (actor instanceof Clutter.Actor && !actor.mapped)
|
||||
duration = 0;
|
||||
|
||||
const prepare = () => {
|
||||
Meta.disable_unredirect_for_display(global.display);
|
||||
global.begin_work();
|
||||
};
|
||||
const cleanup = () => {
|
||||
Meta.enable_unredirect_for_display(global.display);
|
||||
global.end_work();
|
||||
};
|
||||
let cleanup = () => Meta.enable_unredirect_for_display(global.display);
|
||||
let callback = _makeEaseCallback(params, cleanup);
|
||||
|
||||
// cancel overwritten transition
|
||||
@ -217,7 +203,7 @@ function _easeActorProperty(actor, propName, target, params) {
|
||||
if (!isReversed)
|
||||
obj[prop] = target;
|
||||
|
||||
prepare();
|
||||
Meta.disable_unredirect_for_display(global.display);
|
||||
callback(true);
|
||||
|
||||
return;
|
||||
@ -236,9 +222,9 @@ function _easeActorProperty(actor, propName, target, params) {
|
||||
transition.set_to(target);
|
||||
|
||||
if (transition.delay)
|
||||
transition.connect('started', () => prepare());
|
||||
transition.connect('started', () => Meta.disable_unredirect_for_display(global.display));
|
||||
else
|
||||
prepare();
|
||||
Meta.disable_unredirect_for_display(global.display);
|
||||
|
||||
transition.connect('stopped', (t, finished) => callback(finished));
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ const PermissionStore = imports.misc.permissionStore;
|
||||
|
||||
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_ID = 'shortcuts-inhibitor';
|
||||
const GRANTED = 'GRANTED';
|
||||
@ -118,7 +118,7 @@ var InhibitShortcutsDialog = GObject.registerClass({
|
||||
}
|
||||
|
||||
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);
|
||||
return;
|
||||
}
|
||||
|
@ -1091,8 +1091,8 @@ var Keypad = GObject.registerClass({
|
||||
{ label: '8', keyval: Clutter.KEY_8, left: 1, top: 2 },
|
||||
{ label: '9', keyval: Clutter.KEY_9, left: 2, top: 2 },
|
||||
{ label: '0', keyval: Clutter.KEY_0, left: 1, top: 3 },
|
||||
{ keyval: Clutter.KEY_BackSpace, icon: 'edit-clear-symbolic', left: 3, top: 0 },
|
||||
{ keyval: Clutter.KEY_Return, extraClassName: 'enter-key', icon: 'keyboard-enter-symbolic', left: 3, top: 1, height: 2 },
|
||||
{ label: '⌫', keyval: Clutter.KEY_BackSpace, left: 3, top: 0 },
|
||||
{ keyval: Clutter.KEY_Return, extraClassName: 'enter-key', left: 3, top: 1, height: 2 },
|
||||
];
|
||||
|
||||
super._init({
|
||||
@ -1109,7 +1109,7 @@ var Keypad = GObject.registerClass({
|
||||
|
||||
for (let i = 0; i < keys.length; i++) {
|
||||
let cur = keys[i];
|
||||
let key = new Key(cur.label || "", [], cur.icon);
|
||||
let key = new Key(cur.label || "", []);
|
||||
|
||||
if (keys[i].extraClassName)
|
||||
key.keyButton.add_style_class_name(cur.extraClassName);
|
||||
|
@ -457,15 +457,6 @@ var LayoutManager = GObject.registerClass({
|
||||
}
|
||||
}
|
||||
|
||||
_waitLoaded(bgManager) {
|
||||
return new Promise(resolve => {
|
||||
const id = bgManager.connect('loaded', () => {
|
||||
bgManager.disconnect(id);
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
_updateBackgrounds() {
|
||||
for (let i = 0; i < this._bgManagers.length; i++)
|
||||
this._bgManagers[i].destroy();
|
||||
@ -473,7 +464,7 @@ var LayoutManager = GObject.registerClass({
|
||||
this._bgManagers = [];
|
||||
|
||||
if (Main.sessionMode.isGreeter)
|
||||
return Promise.resolve();
|
||||
return;
|
||||
|
||||
for (let i = 0; i < this.monitors.length; i++) {
|
||||
let bgManager = this._createBackgroundManager(i);
|
||||
@ -482,8 +473,6 @@ var LayoutManager = GObject.registerClass({
|
||||
if (i != this.primaryIndex && this._startingUp)
|
||||
bgManager.backgroundActor.hide();
|
||||
}
|
||||
|
||||
return Promise.all(this._bgManagers.map(this._waitLoaded));
|
||||
}
|
||||
|
||||
_updateKeyboardBox() {
|
||||
@ -642,7 +631,7 @@ var LayoutManager = GObject.registerClass({
|
||||
// When starting a normal user session, we want to grow it out of the middle
|
||||
// of the screen.
|
||||
|
||||
async _prepareStartupAnimation() {
|
||||
_prepareStartupAnimation() {
|
||||
// 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.
|
||||
this._coverPane = new Clutter.Actor({ opacity: 0,
|
||||
@ -659,6 +648,8 @@ var LayoutManager = GObject.registerClass({
|
||||
} else if (Main.sessionMode.isGreeter) {
|
||||
this.panelBox.translation_y = -this.panelBox.height;
|
||||
} else {
|
||||
this._updateBackgrounds();
|
||||
|
||||
// We need to force an update of the regions now before we scale
|
||||
// the UI group to get the correct allocation for the struts.
|
||||
this._updateRegions();
|
||||
@ -674,8 +665,6 @@ var LayoutManager = GObject.registerClass({
|
||||
this.uiGroup.scale_x = this.uiGroup.scale_y = 0.75;
|
||||
this.uiGroup.opacity = 0;
|
||||
global.window_group.set_clip(monitor.x, monitor.y, monitor.width, monitor.height);
|
||||
|
||||
await this._updateBackgrounds();
|
||||
}
|
||||
|
||||
this.emit('startup-prepared');
|
||||
@ -1228,9 +1217,8 @@ class HotCorner extends Clutter.Actor {
|
||||
return;
|
||||
|
||||
if (Main.overview.shouldToggleByCornerOrButton()) {
|
||||
this._ripples.playAnimation(this._x, this._y);
|
||||
Main.overview.toggle();
|
||||
if (Main.overview.animationInProgress)
|
||||
this._ripples.playAnimation(this._x, this._y);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,10 +3,10 @@
|
||||
ctrlAltTabManager, padOsdService, osdWindowManager,
|
||||
osdMonitorLabeler, shellMountOpDBusService, shellDBusService,
|
||||
shellAccessDialogDBusService, shellAudioSelectionDBusService,
|
||||
screenSaverDBus, uiGroup, magnifier, xdndHandler, keyboard,
|
||||
kbdA11yDialog, introspectService, start, pushModal, popModal,
|
||||
activateWindow, createLookingGlass, initializeDeferredWork,
|
||||
getThemeStylesheet, setThemeStylesheet */
|
||||
screenSaverDBus, screencastService, uiGroup, magnifier,
|
||||
xdndHandler, keyboard, kbdA11yDialog, introspectService,
|
||||
start, pushModal, popModal, activateWindow, createLookingGlass,
|
||||
initializeDeferredWork, getThemeStylesheet, setThemeStylesheet */
|
||||
|
||||
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 NotificationDaemon = imports.ui.notificationDaemon;
|
||||
const WindowAttentionHandler = imports.ui.windowAttentionHandler;
|
||||
const Screencast = imports.ui.screencast;
|
||||
const ScreenShield = imports.ui.screenShield;
|
||||
const Scripting = imports.ui.scripting;
|
||||
const SessionMode = imports.ui.sessionMode;
|
||||
@ -73,6 +74,7 @@ var shellAudioSelectionDBusService = null;
|
||||
var shellDBusService = null;
|
||||
var shellMountOpDBusService = null;
|
||||
var screenSaverDBus = null;
|
||||
var screencastService = null;
|
||||
var modalCount = 0;
|
||||
var actionMode = Shell.ActionMode.NONE;
|
||||
var modalActorFocusStack = [];
|
||||
@ -198,6 +200,7 @@ function _initializeUI() {
|
||||
uiGroup = layoutManager.uiGroup;
|
||||
|
||||
padOsdService = new PadOsd.PadOsdService();
|
||||
screencastService = new Screencast.ScreencastService();
|
||||
xdndHandler = new XdndHandler.XdndHandler();
|
||||
ctrlAltTabManager = new CtrlAltTab.CtrlAltTabManager();
|
||||
osdWindowManager = new OsdWindow.OsdWindowManager();
|
||||
|
@ -736,11 +736,13 @@ class AggregateMenu extends PanelMenu.Button {
|
||||
this._volume = new imports.ui.status.volume.Indicator();
|
||||
this._brightness = new imports.ui.status.brightness.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._nightLight = new imports.ui.status.nightLight.Indicator();
|
||||
this._thunderbolt = new imports.ui.status.thunderbolt.Indicator();
|
||||
|
||||
this._indicators.add_child(this._thunderbolt);
|
||||
this._indicators.add_child(this._screencast);
|
||||
this._indicators.add_child(this._location);
|
||||
this._indicators.add_child(this._nightLight);
|
||||
if (this._network)
|
||||
|
@ -183,9 +183,10 @@ var Button = GObject.registerClass({
|
||||
}
|
||||
|
||||
_onDestroy() {
|
||||
super._onDestroy();
|
||||
|
||||
if (this.menu)
|
||||
this.menu.destroy();
|
||||
super._onDestroy();
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -881,10 +881,9 @@ var PopupMenu = class extends PopupMenuBase {
|
||||
|
||||
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
|
||||
state &= ~Clutter.ModifierType.LOCK_MASK;
|
||||
state &= ~Clutter.ModifierType.MOD2_MASK;
|
||||
state &= Clutter.ModifierType.MODIFIER_MASK;
|
||||
|
||||
if (state)
|
||||
@ -1325,7 +1324,7 @@ var PopupMenuManager = class {
|
||||
|
||||
removeMenu(menu) {
|
||||
if (menu == this.activeMenu)
|
||||
this._grabHelper.ungrab({ actor: menu.actor });
|
||||
this._closeMenu(false, menu);
|
||||
|
||||
let position = this._findMenu(menu);
|
||||
if (position == -1) // not a menu we manage
|
||||
|
146
js/ui/screencast.js
Normal file
146
js/ui/screencast.js
Normal 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);
|
@ -21,13 +21,16 @@ const { loadInterfaceXML } = imports.misc.fileUtils;
|
||||
// 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
|
||||
// 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.
|
||||
//
|
||||
// await Scripting.sleep(1000);
|
||||
// yield Scripting.sleep(1000);
|
||||
// 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:
|
||||
@ -282,11 +285,13 @@ function _collect(scriptModule, outputFile) {
|
||||
}
|
||||
|
||||
async function _runPerfScript(scriptModule, outputFile) {
|
||||
try {
|
||||
await scriptModule.run();
|
||||
} catch (err) {
|
||||
log(`Script failed: ${err}\n${err.stack}`);
|
||||
Meta.exit(Meta.ExitCode.ERROR);
|
||||
for (let step of scriptModule.run()) {
|
||||
try {
|
||||
await step; // eslint-disable-line no-await-in-loop
|
||||
} catch (err) {
|
||||
log(`Script failed: ${err}\n${err.stack}`);
|
||||
Meta.exit(Meta.ExitCode.ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
|
@ -113,10 +113,10 @@ function _loadMode(file, info) {
|
||||
}
|
||||
|
||||
_modes[modeName] = {};
|
||||
const excludedProps = ['unlockDialog'];
|
||||
let propBlacklist = ['unlockDialog'];
|
||||
for (let prop in _modes[DEFAULT_MODE]) {
|
||||
if (newMode[prop] !== undefined &&
|
||||
!excludedProps.includes(prop))
|
||||
!propBlacklist.includes(prop))
|
||||
_modes[modeName][prop] = newMode[prop];
|
||||
}
|
||||
_modes[modeName]['isPrimary'] = true;
|
||||
|
@ -15,7 +15,6 @@ const Util = imports.misc.util;
|
||||
|
||||
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.prototype,
|
||||
'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 {
|
||||
constructor(section, connection) {
|
||||
this._section = section;
|
||||
@ -564,7 +539,8 @@ var NMDeviceModem = class extends NMConnectionDevice {
|
||||
}
|
||||
|
||||
_autoConnect() {
|
||||
launchSettingsPanel('network', 'connect-3g', this._device.get_path());
|
||||
Util.spawn(['gnome-control-center', 'network',
|
||||
'connect-3g', this._device.get_path()]);
|
||||
}
|
||||
|
||||
destroy() {
|
||||
@ -955,8 +931,8 @@ class NMWirelessDialog extends ModalDialog.ModalDialog {
|
||||
(accessPoints[0]._secType == NMAccessPointSecurity.WPA_ENT)) {
|
||||
// 802.1x-enabled APs require further configuration, so they're
|
||||
// handled in gnome-control-center
|
||||
launchSettingsPanel('wifi', 'connect-8021x-wifi',
|
||||
this._device.get_path(), accessPoints[0].get_path());
|
||||
Util.spawn(['gnome-control-center', 'wifi', 'connect-8021x-wifi',
|
||||
this._device.get_path(), accessPoints[0].get_path()]);
|
||||
} else {
|
||||
let connection = new NM.SimpleConnection();
|
||||
this._client.add_and_activate_connection_async(connection, this._device, accessPoints[0].get_path(), null, null);
|
||||
|
@ -24,8 +24,7 @@ class RemoteAccessApplet extends PanelMenu.SystemIndicator {
|
||||
return;
|
||||
|
||||
this._handles = new Set();
|
||||
this._sharedIndicator = null;
|
||||
this._recordingIndicator = null;
|
||||
this._indicator = null;
|
||||
this._menuSection = null;
|
||||
|
||||
controller.connect('new-handle', (o, handle) => {
|
||||
@ -34,49 +33,32 @@ class RemoteAccessApplet extends PanelMenu.SystemIndicator {
|
||||
}
|
||||
|
||||
_ensureControls() {
|
||||
if (this._sharedIndicator && this._recordingIndicator)
|
||||
if (this._indicator)
|
||||
return;
|
||||
|
||||
this._sharedIndicator = this._addIndicator();
|
||||
this._sharedIndicator.icon_name = 'screen-shared-symbolic';
|
||||
this._sharedIndicator.add_style_class_name('remote-access-indicator');
|
||||
|
||||
this._sharedItem =
|
||||
this._indicator = this._addIndicator();
|
||||
this._indicator.icon_name = 'screen-shared-symbolic';
|
||||
this._indicator.add_style_class_name('remote-access-indicator');
|
||||
this._item =
|
||||
new PopupMenu.PopupSubMenuMenuItem(_("Screen is Being Shared"),
|
||||
true);
|
||||
this._sharedItem.menu.addAction(_("Turn off"),
|
||||
() => {
|
||||
for (let handle of this._handles) {
|
||||
if (!handle.is_recording)
|
||||
handle.stop();
|
||||
}
|
||||
});
|
||||
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);
|
||||
this._item.menu.addAction(_("Turn off"),
|
||||
() => {
|
||||
for (let handle of this._handles)
|
||||
handle.stop();
|
||||
});
|
||||
this._item.icon.icon_name = 'screen-shared-symbolic';
|
||||
this.menu.addMenuItem(this._item);
|
||||
}
|
||||
|
||||
_sync() {
|
||||
if (this._isScreenShared()) {
|
||||
this._sharedIndicator.visible = true;
|
||||
this._sharedItem.visible = true;
|
||||
if (this._handles.size == 0) {
|
||||
this._indicator.visible = false;
|
||||
this._item.visible = false;
|
||||
} else {
|
||||
this._sharedIndicator.visible = false;
|
||||
this._sharedItem.visible = false;
|
||||
this._indicator.visible = true;
|
||||
this._item.visible = true;
|
||||
}
|
||||
|
||||
this._recordingIndicator.visible = this._isRecording();
|
||||
}
|
||||
|
||||
_onStopped(handle) {
|
||||
@ -88,7 +70,9 @@ class RemoteAccessApplet extends PanelMenu.SystemIndicator {
|
||||
this._handles.add(handle);
|
||||
handle.connect('stopped', this._onStopped.bind(this));
|
||||
|
||||
this._ensureControls();
|
||||
this._sync();
|
||||
if (this._handles.size == 1) {
|
||||
this._ensureControls();
|
||||
this._sync();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -86,8 +86,6 @@ class Indicator extends PanelMenu.SystemIndicator {
|
||||
|
||||
Main.sessionMode.connect('updated', this._sessionUpdated.bind(this));
|
||||
this._sessionUpdated();
|
||||
|
||||
this._sync();
|
||||
}
|
||||
|
||||
_sessionUpdated() {
|
||||
|
25
js/ui/status/screencast.js
Normal file
25
js/ui/status/screencast.js
Normal 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;
|
||||
}
|
||||
});
|
@ -27,8 +27,6 @@ class Indicator extends PanelMenu.SystemIndicator {
|
||||
() => this._updateSessionSubMenu());
|
||||
this._powerOffItem.connect('notify::visible',
|
||||
() => this._updateSessionSubMenu());
|
||||
this._restartItem.connect('notify::visible',
|
||||
() => this._updateSessionSubMenu());
|
||||
// Whether shutdown is available or not depends on both lockdown
|
||||
// settings (disable-log-out) and Polkit policy - the latter doesn't
|
||||
// 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._logoutItem.visible ||
|
||||
this._suspendItem.visible ||
|
||||
this._restartItem.visible ||
|
||||
this._powerOffItem.visible;
|
||||
}
|
||||
|
||||
@ -73,8 +70,9 @@ class Indicator extends PanelMenu.SystemIndicator {
|
||||
this.menu.addMenuItem(item);
|
||||
this._orientationLockItem = item;
|
||||
this._systemActions.bind_property('can-lock-orientation',
|
||||
this._orientationLockItem, 'visible',
|
||||
bindFlags);
|
||||
this._orientationLockItem,
|
||||
'visible',
|
||||
bindFlags);
|
||||
this._systemActions.connect('notify::orientation-lock-icon', () => {
|
||||
let iconName = this._systemActions.orientation_lock_icon;
|
||||
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(
|
||||
'gnome-control-center.desktop');
|
||||
if (app) {
|
||||
const [icon] = app.app_info.get_icon().names;
|
||||
const name = app.app_info.get_name();
|
||||
let [icon, name] = [app.app_info.get_icon().names[0],
|
||||
app.get_name()];
|
||||
item = new PopupMenu.PopupImageMenuItem(name, icon);
|
||||
item.connect('activate', () => {
|
||||
this.menu.itemActivated(BoxPointer.PopupAnimation.NONE);
|
||||
@ -109,49 +107,15 @@ class Indicator extends PanelMenu.SystemIndicator {
|
||||
this.menu.addMenuItem(item);
|
||||
this._lockScreenItem = item;
|
||||
this._systemActions.bind_property('can-lock-screen',
|
||||
this._lockScreenItem, 'visible',
|
||||
bindFlags);
|
||||
this._lockScreenItem,
|
||||
'visible',
|
||||
bindFlags);
|
||||
|
||||
this._sessionSubMenu = new PopupMenu.PopupSubMenuMenuItem(
|
||||
_('Power Off / Log Out'), true);
|
||||
this._sessionSubMenu.icon.icon_name = 'system-shutdown-symbolic';
|
||||
|
||||
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(_('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 = new PopupMenu.PopupMenuItem(_("Log Out"));
|
||||
item.connect('activate', () => {
|
||||
this.menu.itemActivated(BoxPointer.PopupAnimation.NONE);
|
||||
this._systemActions.activateLogout();
|
||||
@ -159,10 +123,11 @@ class Indicator extends PanelMenu.SystemIndicator {
|
||||
this._sessionSubMenu.menu.addMenuItem(item);
|
||||
this._logoutItem = item;
|
||||
this._systemActions.bind_property('can-logout',
|
||||
this._logoutItem, 'visible',
|
||||
bindFlags);
|
||||
this._logoutItem,
|
||||
'visible',
|
||||
bindFlags);
|
||||
|
||||
item = new PopupMenu.PopupMenuItem(_('Switch User…'));
|
||||
item = new PopupMenu.PopupMenuItem(_("Switch User…"));
|
||||
item.connect('activate', () => {
|
||||
this.menu.itemActivated(BoxPointer.PopupAnimation.NONE);
|
||||
this._systemActions.activateSwitchUser();
|
||||
@ -170,8 +135,35 @@ class Indicator extends PanelMenu.SystemIndicator {
|
||||
this._sessionSubMenu.menu.addMenuItem(item);
|
||||
this._loginScreenItem = item;
|
||||
this._systemActions.bind_property('can-switch-user',
|
||||
this._loginScreenItem, 'visible',
|
||||
bindFlags);
|
||||
this._loginScreenItem,
|
||||
'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);
|
||||
}
|
||||
|
@ -14,9 +14,9 @@ const WindowMenu = imports.ui.windowMenu;
|
||||
const PadOsd = imports.ui.padOsd;
|
||||
const EdgeDragAction = imports.ui.edgeDragAction;
|
||||
const CloseDialog = imports.ui.closeDialog;
|
||||
const SwipeTracker = imports.ui.swipeTracker;
|
||||
const SwitchMonitor = imports.ui.switchMonitor;
|
||||
const IBusManager = imports.misc.ibusManager;
|
||||
const WorkspaceAnimation = imports.ui.workspaceAnimation;
|
||||
|
||||
const { loadInterfaceXML } = imports.misc.fileUtils;
|
||||
|
||||
@ -42,11 +42,6 @@ const GsdWacomProxy = Gio.DBusProxy.makeProxyWrapper(GsdWacomIface);
|
||||
|
||||
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(
|
||||
class DisplayChangeDialog extends ModalDialog.ModalDialog {
|
||||
_init(wm) {
|
||||
@ -566,7 +561,6 @@ var WindowManager = class {
|
||||
this._resizing = new Set();
|
||||
this._resizePending = new Set();
|
||||
this._destroying = new Set();
|
||||
this._movingWindow = null;
|
||||
|
||||
this._dimmedWindows = [];
|
||||
|
||||
@ -576,15 +570,6 @@ var WindowManager = class {
|
||||
|
||||
this._isWorkspacePrepended = false;
|
||||
|
||||
this._switchData = null;
|
||||
this._shellwm.connect('kill-switch-workspace', shellwm => {
|
||||
if (this._switchData) {
|
||||
if (this._switchData.inProgress)
|
||||
this._switchWorkspaceDone(shellwm);
|
||||
else if (!this._switchData.gestureActivated)
|
||||
this._finishWorkspaceSwitch(this._switchData);
|
||||
}
|
||||
});
|
||||
this._shellwm.connect('kill-window-effects', (shellwm, actor) => {
|
||||
this._minimizeWindowDone(shellwm, actor);
|
||||
this._mapWindowDone(shellwm, actor);
|
||||
@ -606,7 +591,6 @@ var WindowManager = class {
|
||||
this._shellwm.connect('confirm-display-change', this._confirmDisplayChange.bind(this));
|
||||
this._shellwm.connect('create-close-dialog', this._createCloseDialog.bind(this));
|
||||
this._shellwm.connect('create-inhibit-shortcuts-dialog', this._createInhibitShortcutsDialog.bind(this));
|
||||
global.display.connect('restacked', this._syncStacking.bind(this));
|
||||
|
||||
this._workspaceSwitcherPopup = null;
|
||||
this._tilePreview = null;
|
||||
@ -906,40 +890,56 @@ var WindowManager = class {
|
||||
global.display.connect('init-xserver', (display, task) => {
|
||||
IBusManager.getIBusManager().restartDaemon(['--xim']);
|
||||
|
||||
/* Timeout waiting for start job completion after 5 seconds */
|
||||
let cancellable = new Gio.Cancellable();
|
||||
GLib.timeout_add_seconds(GLib.PRIORITY_DEFAULT, 5, () => {
|
||||
cancellable.cancel();
|
||||
return GLib.SOURCE_REMOVE;
|
||||
});
|
||||
try {
|
||||
if (!Shell.util_start_systemd_unit('gsd-xsettings.target', 'fail'))
|
||||
log('Not starting gsd-xsettings; waiting for gnome-session to do so');
|
||||
|
||||
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;
|
||||
});
|
||||
global.display.connect('x11-display-closing', () => {
|
||||
if (!Meta.is_wayland_compositor())
|
||||
return;
|
||||
|
||||
this._stopX11Services(null);
|
||||
|
||||
try {
|
||||
Shell.util_stop_systemd_unit('gsd-xsettings.target', 'fail');
|
||||
} catch (e) {
|
||||
log('Error stopping gsd-xsettings: %s'.format(e.message));
|
||||
}
|
||||
IBusManager.getIBusManager().restartDaemon();
|
||||
});
|
||||
|
||||
Main.overview.connect('showing', () => {
|
||||
for (let i = 0; i < this._dimmedWindows.length; i++)
|
||||
this._undimWindow(this._dimmedWindows[i]);
|
||||
|
||||
if (this._switchData) {
|
||||
if (this._switchData.gestureActivated)
|
||||
this._switchWorkspaceStop();
|
||||
this._swipeTracker.enabled = false;
|
||||
}
|
||||
});
|
||||
Main.overview.connect('hiding', () => {
|
||||
for (let i = 0; i < this._dimmedWindows.length; i++)
|
||||
this._dimWindow(this._dimmedWindows[i]);
|
||||
this._swipeTracker.enabled = true;
|
||||
});
|
||||
|
||||
this._windowMenuManager = new WindowMenu.WindowMenuManager();
|
||||
@ -950,13 +950,6 @@ var WindowManager = class {
|
||||
global.workspace_manager.override_workspace_layout(Meta.DisplayCorner.TOPLEFT,
|
||||
false, -1, 1);
|
||||
|
||||
let swipeTracker = new SwipeTracker.SwipeTracker(global.stage,
|
||||
Shell.ActionMode.NORMAL, { allowDrag: false, allowScroll: false });
|
||||
swipeTracker.connect('begin', this._switchWorkspaceBegin.bind(this));
|
||||
swipeTracker.connect('update', this._switchWorkspaceUpdate.bind(this));
|
||||
swipeTracker.connect('end', this._switchWorkspaceEnd.bind(this));
|
||||
this._swipeTracker = swipeTracker;
|
||||
|
||||
let appSwitchAction = new AppSwitchAction();
|
||||
appSwitchAction.connect('activated', this._switchApp.bind(this));
|
||||
global.stage.add_action(appSwitchAction);
|
||||
@ -988,36 +981,14 @@ var WindowManager = class {
|
||||
global.display.connect('in-fullscreen-changed', updateUnfullscreenGesture);
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
this._workspaceAnimation =
|
||||
new WorkspaceAnimation.WorkspaceAnimationController();
|
||||
|
||||
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));
|
||||
}
|
||||
this._shellwm.connect('kill-switch-workspace', () => {
|
||||
this._workspaceAnimation.cancelSwitchAnimation();
|
||||
this._switchWorkspaceDone();
|
||||
});
|
||||
}
|
||||
|
||||
_showPadOsd(display, device, settings, imagePath, editionMode, monitorIndex) {
|
||||
@ -1140,8 +1111,7 @@ var WindowManager = class {
|
||||
}
|
||||
|
||||
_shouldAnimate() {
|
||||
return !(Main.overview.visible ||
|
||||
(this._switchData && this._switchData.gestureActivated));
|
||||
return !(Main.overview.visible || this._workspaceAnimation.gestureActive);
|
||||
}
|
||||
|
||||
_shouldAnimateActor(actor, types) {
|
||||
@ -1637,376 +1607,26 @@ var WindowManager = class {
|
||||
return !(this._allowedKeybindings[binding.get_name()] & Main.actionMode);
|
||||
}
|
||||
|
||||
_syncStacking() {
|
||||
if (this._switchData == null)
|
||||
return;
|
||||
|
||||
let windows = global.get_window_actors();
|
||||
let lastCurSibling = null;
|
||||
let lastDirSibling = [];
|
||||
for (let i = 0; i < windows.length; i++) {
|
||||
if (windows[i].get_parent() == this._switchData.curGroup) {
|
||||
this._switchData.curGroup.set_child_above_sibling(windows[i], lastCurSibling);
|
||||
lastCurSibling = windows[i];
|
||||
} else {
|
||||
for (let dir of Object.values(Meta.MotionDirection)) {
|
||||
let info = this._switchData.surroundings[dir];
|
||||
if (!info || windows[i].get_parent() != info.actor)
|
||||
continue;
|
||||
|
||||
let sibling = lastDirSibling[dir];
|
||||
if (sibling == undefined)
|
||||
sibling = null;
|
||||
|
||||
info.actor.set_child_above_sibling(windows[i], sibling);
|
||||
lastDirSibling[dir] = windows[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_getPositionForDirection(direction, fromWs, toWs) {
|
||||
let xDest = 0, yDest = 0;
|
||||
|
||||
let oldWsIsFullscreen = fromWs.list_windows().some(w => w.is_fullscreen());
|
||||
let newWsIsFullscreen = toWs.list_windows().some(w => w.is_fullscreen());
|
||||
|
||||
// We have to shift windows up or down by the height of the panel to prevent having a
|
||||
// visible gap between the windows while switching workspaces. Since fullscreen windows
|
||||
// hide the panel, they don't need to be shifted up or down.
|
||||
let shiftHeight = Main.panel.height;
|
||||
|
||||
if (direction == Meta.MotionDirection.UP ||
|
||||
direction == Meta.MotionDirection.UP_LEFT ||
|
||||
direction == Meta.MotionDirection.UP_RIGHT)
|
||||
yDest = -global.screen_height + (oldWsIsFullscreen ? 0 : shiftHeight);
|
||||
else if (direction == Meta.MotionDirection.DOWN ||
|
||||
direction == Meta.MotionDirection.DOWN_LEFT ||
|
||||
direction == Meta.MotionDirection.DOWN_RIGHT)
|
||||
yDest = global.screen_height - (newWsIsFullscreen ? 0 : shiftHeight);
|
||||
|
||||
if (direction == Meta.MotionDirection.LEFT ||
|
||||
direction == Meta.MotionDirection.UP_LEFT ||
|
||||
direction == Meta.MotionDirection.DOWN_LEFT)
|
||||
xDest = -global.screen_width;
|
||||
else if (direction == Meta.MotionDirection.RIGHT ||
|
||||
direction == Meta.MotionDirection.UP_RIGHT ||
|
||||
direction == Meta.MotionDirection.DOWN_RIGHT)
|
||||
xDest = global.screen_width;
|
||||
|
||||
return [xDest, yDest];
|
||||
}
|
||||
|
||||
_prepareWorkspaceSwitch(from, to, direction) {
|
||||
if (this._switchData)
|
||||
return;
|
||||
|
||||
let wgroup = global.window_group;
|
||||
let windows = global.get_window_actors();
|
||||
let switchData = {};
|
||||
|
||||
this._switchData = switchData;
|
||||
switchData.curGroup = new Clutter.Actor();
|
||||
switchData.movingWindowBin = new Clutter.Actor();
|
||||
switchData.windows = [];
|
||||
switchData.surroundings = {};
|
||||
switchData.gestureActivated = false;
|
||||
switchData.inProgress = false;
|
||||
|
||||
switchData.container = new Clutter.Actor();
|
||||
switchData.container.add_actor(switchData.curGroup);
|
||||
|
||||
wgroup.add_actor(switchData.movingWindowBin);
|
||||
wgroup.add_actor(switchData.container);
|
||||
|
||||
let workspaceManager = global.workspace_manager;
|
||||
let curWs = workspaceManager.get_workspace_by_index(from);
|
||||
|
||||
for (let dir of Object.values(Meta.MotionDirection)) {
|
||||
let ws = null;
|
||||
|
||||
if (to < 0)
|
||||
ws = curWs.get_neighbor(dir);
|
||||
else if (dir == direction)
|
||||
ws = workspaceManager.get_workspace_by_index(to);
|
||||
|
||||
if (ws == null || ws == curWs) {
|
||||
switchData.surroundings[dir] = null;
|
||||
continue;
|
||||
}
|
||||
|
||||
let [x, y] = this._getPositionForDirection(dir, curWs, ws);
|
||||
let info = {
|
||||
index: ws.index(),
|
||||
actor: new Clutter.Actor(),
|
||||
xDest: x,
|
||||
yDest: y,
|
||||
};
|
||||
switchData.surroundings[dir] = info;
|
||||
switchData.container.add_actor(info.actor);
|
||||
switchData.container.set_child_above_sibling(info.actor, null);
|
||||
|
||||
info.actor.set_position(x, y);
|
||||
}
|
||||
|
||||
wgroup.set_child_above_sibling(switchData.movingWindowBin, null);
|
||||
|
||||
for (let i = 0; i < windows.length; i++) {
|
||||
let actor = windows[i];
|
||||
let window = actor.get_meta_window();
|
||||
|
||||
if (!window.showing_on_its_workspace())
|
||||
continue;
|
||||
|
||||
if (window.is_on_all_workspaces())
|
||||
continue;
|
||||
|
||||
let record = { window: actor,
|
||||
parent: actor.get_parent() };
|
||||
|
||||
if (this._movingWindow && window == this._movingWindow) {
|
||||
record.parent.remove_child(actor);
|
||||
switchData.movingWindow = record;
|
||||
switchData.windows.push(switchData.movingWindow);
|
||||
switchData.movingWindowBin.add_child(actor);
|
||||
} else if (window.get_workspace().index() == from) {
|
||||
record.parent.remove_child(actor);
|
||||
switchData.windows.push(record);
|
||||
switchData.curGroup.add_child(actor);
|
||||
} else {
|
||||
let visible = false;
|
||||
for (let dir of Object.values(Meta.MotionDirection)) {
|
||||
let info = switchData.surroundings[dir];
|
||||
|
||||
if (!info || info.index != window.get_workspace().index())
|
||||
continue;
|
||||
|
||||
record.parent.remove_child(actor);
|
||||
switchData.windows.push(record);
|
||||
info.actor.add_child(actor);
|
||||
visible = true;
|
||||
break;
|
||||
}
|
||||
|
||||
actor.visible = visible;
|
||||
}
|
||||
}
|
||||
|
||||
for (let i = 0; i < switchData.windows.length; i++) {
|
||||
let w = switchData.windows[i];
|
||||
|
||||
w.windowDestroyId = w.window.connect('destroy', () => {
|
||||
switchData.windows.splice(switchData.windows.indexOf(w), 1);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
_finishWorkspaceSwitch(switchData) {
|
||||
this._switchData = null;
|
||||
|
||||
for (let i = 0; i < switchData.windows.length; i++) {
|
||||
let w = switchData.windows[i];
|
||||
|
||||
w.window.disconnect(w.windowDestroyId);
|
||||
w.window.get_parent().remove_child(w.window);
|
||||
w.parent.add_child(w.window);
|
||||
|
||||
if (!w.window.get_meta_window().get_workspace().active)
|
||||
w.window.hide();
|
||||
}
|
||||
switchData.container.destroy();
|
||||
switchData.movingWindowBin.destroy();
|
||||
|
||||
this._movingWindow = null;
|
||||
}
|
||||
|
||||
_switchWorkspace(shellwm, from, to, direction) {
|
||||
if (!Main.sessionMode.hasWorkspaces || !this._shouldAnimate()) {
|
||||
shellwm.completed_switch_workspace();
|
||||
return;
|
||||
}
|
||||
|
||||
this._prepareWorkspaceSwitch(from, to, direction);
|
||||
this._switchData.inProgress = true;
|
||||
this._switchInProgress = true;
|
||||
|
||||
let workspaceManager = global.workspace_manager;
|
||||
let fromWs = workspaceManager.get_workspace_by_index(from);
|
||||
let toWs = workspaceManager.get_workspace_by_index(to);
|
||||
|
||||
let [xDest, yDest] = this._getPositionForDirection(direction, fromWs, toWs);
|
||||
|
||||
/* @direction is the direction that the "camera" moves, so the
|
||||
* screen contents have to move one screen's worth in the
|
||||
* opposite direction.
|
||||
*/
|
||||
xDest = -xDest;
|
||||
yDest = -yDest;
|
||||
|
||||
this._switchData.container.ease({
|
||||
x: xDest,
|
||||
y: yDest,
|
||||
duration: WINDOW_ANIMATION_TIME,
|
||||
mode: Clutter.AnimationMode.EASE_OUT_CUBIC,
|
||||
onComplete: () => this._switchWorkspaceDone(shellwm),
|
||||
this._workspaceAnimation.animateSwitch(from, to, direction, () => {
|
||||
this._shellwm.completed_switch_workspace();
|
||||
this._switchInProgress = false;
|
||||
});
|
||||
}
|
||||
|
||||
_switchWorkspaceDone(shellwm) {
|
||||
this._finishWorkspaceSwitch(this._switchData);
|
||||
shellwm.completed_switch_workspace();
|
||||
}
|
||||
|
||||
_directionForProgress(progress) {
|
||||
if (global.workspace_manager.layout_rows === -1) {
|
||||
return progress > 0
|
||||
? Meta.MotionDirection.DOWN
|
||||
: Meta.MotionDirection.UP;
|
||||
} else if (Clutter.get_default_text_direction() === Clutter.TextDirection.RTL) {
|
||||
return progress > 0
|
||||
? Meta.MotionDirection.LEFT
|
||||
: Meta.MotionDirection.RIGHT;
|
||||
} else {
|
||||
return progress > 0
|
||||
? Meta.MotionDirection.RIGHT
|
||||
: Meta.MotionDirection.LEFT;
|
||||
}
|
||||
}
|
||||
|
||||
_getProgressRange() {
|
||||
if (!this._switchData)
|
||||
return [0, 0];
|
||||
|
||||
let lower = 0;
|
||||
let upper = 0;
|
||||
|
||||
let horiz = global.workspace_manager.layout_rows !== -1;
|
||||
let baseDistance;
|
||||
if (horiz)
|
||||
baseDistance = global.screen_width;
|
||||
else
|
||||
baseDistance = global.screen_height;
|
||||
|
||||
let direction = this._directionForProgress(-1);
|
||||
let info = this._switchData.surroundings[direction];
|
||||
if (info !== null) {
|
||||
let distance = horiz ? info.xDest : info.yDest;
|
||||
lower = -Math.abs(distance) / baseDistance;
|
||||
}
|
||||
|
||||
direction = this._directionForProgress(1);
|
||||
info = this._switchData.surroundings[direction];
|
||||
if (info !== null) {
|
||||
let distance = horiz ? info.xDest : info.yDest;
|
||||
upper = Math.abs(distance) / baseDistance;
|
||||
}
|
||||
|
||||
return [lower, upper];
|
||||
}
|
||||
|
||||
_switchWorkspaceBegin(tracker, monitor) {
|
||||
if (Meta.prefs_get_workspaces_only_on_primary() &&
|
||||
monitor !== Main.layoutManager.primaryIndex)
|
||||
_switchWorkspaceDone() {
|
||||
if (!this._switchInProgress)
|
||||
return;
|
||||
|
||||
let workspaceManager = global.workspace_manager;
|
||||
let horiz = workspaceManager.layout_rows !== -1;
|
||||
tracker.orientation = horiz
|
||||
? Clutter.Orientation.HORIZONTAL
|
||||
: Clutter.Orientation.VERTICAL;
|
||||
|
||||
let activeWorkspace = workspaceManager.get_active_workspace();
|
||||
|
||||
let baseDistance;
|
||||
if (horiz)
|
||||
baseDistance = global.screen_width;
|
||||
else
|
||||
baseDistance = global.screen_height;
|
||||
|
||||
let progress;
|
||||
if (this._switchData && this._switchData.gestureActivated) {
|
||||
this._switchData.container.remove_all_transitions();
|
||||
if (!horiz)
|
||||
progress = -this._switchData.container.y / baseDistance;
|
||||
else if (Clutter.get_default_text_direction() === Clutter.TextDirection.RTL)
|
||||
progress = this._switchData.container.x / baseDistance;
|
||||
else
|
||||
progress = -this._switchData.container.x / baseDistance;
|
||||
} else {
|
||||
this._prepareWorkspaceSwitch(activeWorkspace.index(), -1);
|
||||
progress = 0;
|
||||
}
|
||||
|
||||
let points = [];
|
||||
let [lower, upper] = this._getProgressRange();
|
||||
|
||||
if (lower !== 0)
|
||||
points.push(lower);
|
||||
|
||||
points.push(0);
|
||||
|
||||
if (upper !== 0)
|
||||
points.push(upper);
|
||||
|
||||
tracker.confirmSwipe(baseDistance, points, progress, 0);
|
||||
}
|
||||
|
||||
_switchWorkspaceUpdate(tracker, progress) {
|
||||
if (!this._switchData)
|
||||
return;
|
||||
|
||||
let direction = this._directionForProgress(progress);
|
||||
let info = this._switchData.surroundings[direction];
|
||||
let xPos = 0;
|
||||
let yPos = 0;
|
||||
if (info) {
|
||||
if (global.workspace_manager.layout_rows === -1)
|
||||
yPos = -Math.round(progress * global.screen_height);
|
||||
else if (Clutter.get_default_text_direction() === Clutter.TextDirection.RTL)
|
||||
xPos = Math.round(progress * global.screen_width);
|
||||
else
|
||||
xPos = -Math.round(progress * global.screen_width);
|
||||
}
|
||||
|
||||
this._switchData.container.set_position(xPos, yPos);
|
||||
}
|
||||
|
||||
_switchWorkspaceEnd(tracker, duration, endProgress) {
|
||||
if (!this._switchData)
|
||||
return;
|
||||
|
||||
let workspaceManager = global.workspace_manager;
|
||||
let activeWorkspace = workspaceManager.get_active_workspace();
|
||||
let newWs = activeWorkspace;
|
||||
let xDest = 0;
|
||||
let yDest = 0;
|
||||
if (endProgress !== 0) {
|
||||
let direction = this._directionForProgress(endProgress);
|
||||
newWs = activeWorkspace.get_neighbor(direction);
|
||||
xDest = -this._switchData.surroundings[direction].xDest;
|
||||
yDest = -this._switchData.surroundings[direction].yDest;
|
||||
}
|
||||
|
||||
let switchData = this._switchData;
|
||||
switchData.gestureActivated = true;
|
||||
|
||||
this._switchData.container.ease({
|
||||
x: xDest,
|
||||
y: yDest,
|
||||
duration,
|
||||
mode: Clutter.AnimationMode.EASE_OUT_CUBIC,
|
||||
onComplete: () => {
|
||||
if (!newWs.active)
|
||||
this.actionMoveWorkspace(newWs);
|
||||
this._finishWorkspaceSwitch(switchData);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
_switchWorkspaceStop() {
|
||||
this._switchData.container.x = 0;
|
||||
this._switchData.container.y = 0;
|
||||
this._finishWorkspaceSwitch(this._switchData);
|
||||
this._shellwm.completed_switch_workspace();
|
||||
this._switchInProgress = false;
|
||||
}
|
||||
|
||||
_showTilePreview(shellwm, window, tileRect, monitorIndex) {
|
||||
@ -2208,7 +1828,7 @@ var WindowManager = class {
|
||||
// This won't have any effect for "always sticky" windows
|
||||
// (like desktop windows or docks)
|
||||
|
||||
this._movingWindow = window;
|
||||
this._workspaceAnimation.movingWindow = window;
|
||||
window.change_workspace(workspace);
|
||||
|
||||
global.display.clear_mouse_mode();
|
||||
|
475
js/ui/workspaceAnimation.js
Normal file
475
js/ui/workspaceAnimation.js
Normal file
@ -0,0 +1,475 @@
|
||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported WorkspaceAnimationController */
|
||||
|
||||
const { Clutter, GObject, Meta, Shell } = imports.gi;
|
||||
|
||||
const Background = imports.ui.background;
|
||||
const Layout = imports.ui.layout;
|
||||
const Main = imports.ui.main;
|
||||
const SwipeTracker = imports.ui.swipeTracker;
|
||||
|
||||
const WINDOW_ANIMATION_TIME = 250;
|
||||
|
||||
const WorkspaceGroup = GObject.registerClass(
|
||||
class WorkspaceGroup extends Clutter.Actor {
|
||||
_init(workspace, monitor, movingWindow) {
|
||||
super._init();
|
||||
|
||||
this._workspace = workspace;
|
||||
this._monitor = monitor;
|
||||
this._movingWindow = movingWindow;
|
||||
this._windowRecords = [];
|
||||
|
||||
this._createWindows();
|
||||
|
||||
this.connect('destroy', this._onDestroy.bind(this));
|
||||
this._restackedId = global.display.connect('restacked',
|
||||
this._syncStacking.bind(this));
|
||||
}
|
||||
|
||||
get workspace() {
|
||||
return this._workspace;
|
||||
}
|
||||
|
||||
_shouldShowWindow(window) {
|
||||
if (!window.showing_on_its_workspace())
|
||||
return false;
|
||||
|
||||
const geometry = global.display.get_monitor_geometry(this._monitor.index);
|
||||
const [intersects, intersection_] = window.get_frame_rect().intersect(geometry);
|
||||
if (!intersects)
|
||||
return false;
|
||||
|
||||
const isSticky =
|
||||
window.is_on_all_workspaces() || window === this._movingWindow;
|
||||
|
||||
// No workspace means we should show windows that are on all workspaces
|
||||
if (!this._workspace)
|
||||
return isSticky;
|
||||
|
||||
// Otherwise only show windows that are (only) on that workspace
|
||||
return !isSticky && window.located_on_workspace(this._workspace);
|
||||
}
|
||||
|
||||
_syncStacking() {
|
||||
const windowActors = global.get_window_actors().filter(w =>
|
||||
this._shouldShowWindow(w.meta_window));
|
||||
|
||||
let lastRecord;
|
||||
|
||||
for (const windowActor of windowActors) {
|
||||
const record = this._windowRecords.find(r => r.windowActor === windowActor);
|
||||
|
||||
this.set_child_above_sibling(record.clone, lastRecord ? lastRecord.clone : null);
|
||||
lastRecord = record;
|
||||
}
|
||||
}
|
||||
|
||||
_createWindows() {
|
||||
const windowActors = global.get_window_actors().filter(w =>
|
||||
this._shouldShowWindow(w.meta_window));
|
||||
|
||||
for (const windowActor of windowActors) {
|
||||
const clone = new Clutter.Clone({
|
||||
source: windowActor,
|
||||
x: windowActor.x - this._monitor.x,
|
||||
y: windowActor.y - this._monitor.y,
|
||||
});
|
||||
|
||||
this.add_child(clone);
|
||||
|
||||
const record = { windowActor, clone };
|
||||
|
||||
record.windowDestroyId = windowActor.connect('destroy', () => {
|
||||
clone.destroy();
|
||||
this._windowRecords.splice(this._windowRecords.indexOf(record), 1);
|
||||
});
|
||||
|
||||
this._windowRecords.push(record);
|
||||
}
|
||||
}
|
||||
|
||||
_removeWindows() {
|
||||
for (const record of this._windowRecords) {
|
||||
record.windowActor.disconnect(record.windowDestroyId);
|
||||
record.clone.destroy();
|
||||
}
|
||||
|
||||
this._windowRecords = [];
|
||||
}
|
||||
|
||||
_onDestroy() {
|
||||
global.display.disconnect(this._restackedId);
|
||||
this._removeWindows();
|
||||
}
|
||||
});
|
||||
|
||||
const MonitorGroup = GObject.registerClass({
|
||||
Properties: {
|
||||
'progress': GObject.ParamSpec.double(
|
||||
'progress', 'progress', 'progress',
|
||||
GObject.ParamFlags.READWRITE,
|
||||
-Infinity, Infinity, 0),
|
||||
},
|
||||
}, class MonitorGroup extends Clutter.Actor {
|
||||
_init(monitor, workspaceIndices, movingWindow) {
|
||||
super._init({
|
||||
clip_to_allocation: true,
|
||||
});
|
||||
|
||||
this._monitor = monitor;
|
||||
|
||||
const constraint = new Layout.MonitorConstraint({ index: monitor.index });
|
||||
this.add_constraint(constraint);
|
||||
|
||||
const background = new Meta.BackgroundGroup();
|
||||
|
||||
this.add_child(background);
|
||||
|
||||
this._container = new Clutter.Actor();
|
||||
this.add_child(this._container);
|
||||
|
||||
const stickyGroup = new WorkspaceGroup(null, monitor, movingWindow);
|
||||
this.add_child(stickyGroup);
|
||||
|
||||
this._workspaceGroups = [];
|
||||
|
||||
const workspaceManager = global.workspace_manager;
|
||||
const vertical = workspaceManager.layout_rows === -1;
|
||||
const activeWorkspace = workspaceManager.get_active_workspace();
|
||||
|
||||
let x = 0;
|
||||
let y = 0;
|
||||
|
||||
for (const i of workspaceIndices) {
|
||||
const ws = workspaceManager.get_workspace_by_index(i);
|
||||
const fullscreen = ws.list_windows().some(w => w.get_monitor() === monitor.index && w.is_fullscreen());
|
||||
|
||||
if (i > 0 && vertical && !fullscreen && monitor.index === Main.layoutManager.primaryIndex) {
|
||||
// We have to shift windows up or down by the height of the panel to prevent having a
|
||||
// visible gap between the windows while switching workspaces. Since fullscreen windows
|
||||
// hide the panel, they don't need to be shifted up or down.
|
||||
y -= Main.panel.height;
|
||||
}
|
||||
|
||||
const group = new WorkspaceGroup(ws, monitor, movingWindow);
|
||||
|
||||
this._workspaceGroups.push(group);
|
||||
this._container.add_child(group);
|
||||
group.set_position(x, y);
|
||||
|
||||
if (vertical)
|
||||
y += this.baseDistance;
|
||||
else if (Clutter.get_default_text_direction() === Clutter.TextDirection.RTL)
|
||||
x -= this.baseDistance;
|
||||
else
|
||||
x += this.baseDistance;
|
||||
}
|
||||
|
||||
this.progress = this.getWorkspaceProgress(activeWorkspace);
|
||||
|
||||
this._bgManager = new Background.BackgroundManager({
|
||||
container: background,
|
||||
monitorIndex: monitor.index,
|
||||
controlPosition: false,
|
||||
});
|
||||
|
||||
this.connect('destroy', this._onDestroy.bind(this));
|
||||
}
|
||||
|
||||
_onDestroy() {
|
||||
this._bgManager.destroy();
|
||||
}
|
||||
|
||||
get baseDistance() {
|
||||
if (global.workspace_manager.layout_rows === -1)
|
||||
return this._monitor.height;
|
||||
else
|
||||
return this._monitor.width;
|
||||
}
|
||||
|
||||
get progress() {
|
||||
if (global.workspace_manager.layout_rows === -1)
|
||||
return -this._container.y / this.baseDistance;
|
||||
else if (this.get_text_direction() === Clutter.TextDirection.RTL)
|
||||
return this._container.x / this.baseDistance;
|
||||
else
|
||||
return -this._container.x / this.baseDistance;
|
||||
}
|
||||
|
||||
set progress(p) {
|
||||
if (global.workspace_manager.layout_rows === -1)
|
||||
this._container.y = -Math.round(p * this.baseDistance);
|
||||
else if (this.get_text_direction() === Clutter.TextDirection.RTL)
|
||||
this._container.x = Math.round(p * this.baseDistance);
|
||||
else
|
||||
this._container.x = -Math.round(p * this.baseDistance);
|
||||
}
|
||||
|
||||
get index() {
|
||||
return this._monitor.index;
|
||||
}
|
||||
|
||||
getWorkspaceProgress(workspace) {
|
||||
const group = this._workspaceGroups.find(g =>
|
||||
g.workspace.index() === workspace.index());
|
||||
return this._getWorkspaceGroupProgress(group);
|
||||
}
|
||||
|
||||
_getWorkspaceGroupProgress(group) {
|
||||
if (global.workspace_manager.layout_rows === -1)
|
||||
return group.y / this.baseDistance;
|
||||
else if (this.get_text_direction() === Clutter.TextDirection.RTL)
|
||||
return -group.x / this.baseDistance;
|
||||
else
|
||||
return group.x / this.baseDistance;
|
||||
}
|
||||
|
||||
getSnapPoints() {
|
||||
return this._workspaceGroups.map(g =>
|
||||
this._getWorkspaceGroupProgress(g));
|
||||
}
|
||||
|
||||
findClosestWorkspace(progress) {
|
||||
const distances = this.getSnapPoints().map(p =>
|
||||
Math.abs(p - progress));
|
||||
const index = distances.indexOf(Math.min(...distances));
|
||||
return this._workspaceGroups[index].workspace;
|
||||
}
|
||||
|
||||
_interpolateProgress(progress, monitorGroup) {
|
||||
if (this.index === monitorGroup.index)
|
||||
return progress;
|
||||
|
||||
const points1 = monitorGroup.getSnapPoints();
|
||||
const points2 = this.getSnapPoints();
|
||||
|
||||
const upper = points1.indexOf(points1.find(p => p >= progress));
|
||||
const lower = points1.indexOf(points1.slice().reverse().find(p => p <= progress));
|
||||
|
||||
if (points1[upper] === points1[lower])
|
||||
return points2[upper];
|
||||
|
||||
const t = (progress - points1[lower]) / (points1[upper] - points1[lower]);
|
||||
|
||||
return points2[lower] + (points2[upper] - points2[lower]) * t;
|
||||
}
|
||||
|
||||
updateSwipeForMonitor(progress, monitorGroup) {
|
||||
this.progress = this._interpolateProgress(progress, monitorGroup);
|
||||
}
|
||||
});
|
||||
|
||||
var WorkspaceAnimationController = class {
|
||||
constructor() {
|
||||
this._movingWindow = null;
|
||||
this._switchData = null;
|
||||
|
||||
Main.overview.connect('showing', () => {
|
||||
if (this._switchData) {
|
||||
if (this._switchData.gestureActivated)
|
||||
this._finishWorkspaceSwitch(this._switchData);
|
||||
this._swipeTracker.enabled = false;
|
||||
}
|
||||
});
|
||||
Main.overview.connect('hiding', () => {
|
||||
this._swipeTracker.enabled = true;
|
||||
});
|
||||
|
||||
let swipeTracker = new SwipeTracker.SwipeTracker(global.stage,
|
||||
Shell.ActionMode.NORMAL, { allowDrag: false, allowScroll: false });
|
||||
swipeTracker.connect('begin', this._switchWorkspaceBegin.bind(this));
|
||||
swipeTracker.connect('update', this._switchWorkspaceUpdate.bind(this));
|
||||
swipeTracker.connect('end', this._switchWorkspaceEnd.bind(this));
|
||||
this._swipeTracker = swipeTracker;
|
||||
}
|
||||
|
||||
_prepareWorkspaceSwitch(workspaceIndices) {
|
||||
if (this._switchData)
|
||||
return;
|
||||
|
||||
const workspaceManager = global.workspace_manager;
|
||||
const nWorkspaces = workspaceManager.get_n_workspaces();
|
||||
|
||||
const switchData = {};
|
||||
|
||||
this._switchData = switchData;
|
||||
switchData.monitors = [];
|
||||
|
||||
switchData.gestureActivated = false;
|
||||
switchData.inProgress = false;
|
||||
|
||||
if (!workspaceIndices)
|
||||
workspaceIndices = [...Array(nWorkspaces).keys()];
|
||||
|
||||
const monitors = Meta.prefs_get_workspaces_only_on_primary()
|
||||
? [Main.layoutManager.primaryMonitor] : Main.layoutManager.monitors;
|
||||
|
||||
for (const monitor of monitors) {
|
||||
if (Meta.prefs_get_workspaces_only_on_primary() &&
|
||||
monitor.index !== Main.layoutManager.primaryIndex)
|
||||
continue;
|
||||
|
||||
const group = new MonitorGroup(monitor, workspaceIndices, this.movingWindow);
|
||||
|
||||
Main.uiGroup.insert_child_above(group, global.window_group);
|
||||
|
||||
switchData.monitors.push(group);
|
||||
}
|
||||
}
|
||||
|
||||
_finishWorkspaceSwitch(switchData) {
|
||||
this._switchData = null;
|
||||
|
||||
switchData.monitors.forEach(m => m.destroy());
|
||||
|
||||
this.movingWindow = null;
|
||||
}
|
||||
|
||||
animateSwitch(from, to, direction, onComplete) {
|
||||
this._swipeTracker.enabled = false;
|
||||
|
||||
let workspaceIndices = [];
|
||||
|
||||
switch (direction) {
|
||||
case Meta.MotionDirection.UP:
|
||||
case Meta.MotionDirection.LEFT:
|
||||
case Meta.MotionDirection.UP_LEFT:
|
||||
case Meta.MotionDirection.UP_RIGHT:
|
||||
workspaceIndices = [to, from];
|
||||
break;
|
||||
|
||||
case Meta.MotionDirection.DOWN:
|
||||
case Meta.MotionDirection.RIGHT:
|
||||
case Meta.MotionDirection.DOWN_LEFT:
|
||||
case Meta.MotionDirection.DOWN_RIGHT:
|
||||
workspaceIndices = [from, to];
|
||||
break;
|
||||
}
|
||||
|
||||
if (Clutter.get_default_text_direction() === Clutter.TextDirection.RTL &&
|
||||
direction !== Meta.MotionDirection.UP &&
|
||||
direction !== Meta.MotionDirection.DOWN)
|
||||
workspaceIndices.reverse();
|
||||
|
||||
this._prepareWorkspaceSwitch(workspaceIndices);
|
||||
this._switchData.inProgress = true;
|
||||
|
||||
const fromWs = global.workspace_manager.get_workspace_by_index(from);
|
||||
const toWs = global.workspace_manager.get_workspace_by_index(to);
|
||||
|
||||
for (const monitorGroup of this._switchData.monitors) {
|
||||
monitorGroup.progress = monitorGroup.getWorkspaceProgress(fromWs);
|
||||
const progress = monitorGroup.getWorkspaceProgress(toWs);
|
||||
|
||||
const params = {
|
||||
duration: WINDOW_ANIMATION_TIME,
|
||||
mode: Clutter.AnimationMode.EASE_OUT_CUBIC,
|
||||
};
|
||||
|
||||
if (monitorGroup.index === Main.layoutManager.primaryIndex) {
|
||||
params.onComplete = () => {
|
||||
this._finishWorkspaceSwitch(this._switchData);
|
||||
onComplete();
|
||||
this._swipeTracker.enabled = true;
|
||||
};
|
||||
}
|
||||
|
||||
monitorGroup.ease_property('progress', progress, params);
|
||||
}
|
||||
}
|
||||
|
||||
_findMonitorGroup(monitorIndex) {
|
||||
return this._switchData.monitors.find(m => m.index === monitorIndex);
|
||||
}
|
||||
|
||||
_switchWorkspaceBegin(tracker, monitor) {
|
||||
if (Meta.prefs_get_workspaces_only_on_primary() &&
|
||||
monitor !== Main.layoutManager.primaryIndex)
|
||||
return;
|
||||
|
||||
const workspaceManager = global.workspace_manager;
|
||||
const horiz = workspaceManager.layout_rows !== -1;
|
||||
tracker.orientation = horiz
|
||||
? Clutter.Orientation.HORIZONTAL
|
||||
: Clutter.Orientation.VERTICAL;
|
||||
|
||||
if (this._switchData && this._switchData.gestureActivated) {
|
||||
for (const group of this._switchData.monitors)
|
||||
group.remove_all_transitions();
|
||||
} else {
|
||||
this._prepareWorkspaceSwitch();
|
||||
}
|
||||
|
||||
const monitorGroup = this._findMonitorGroup(monitor);
|
||||
const baseDistance = monitorGroup.baseDistance;
|
||||
const progress = monitorGroup.progress;
|
||||
|
||||
const closestWs = monitorGroup.findClosestWorkspace(progress);
|
||||
const cancelProgress = monitorGroup.getWorkspaceProgress(closestWs);
|
||||
const points = monitorGroup.getSnapPoints();
|
||||
|
||||
this._switchData.baseMonitorGroup = monitorGroup;
|
||||
|
||||
tracker.confirmSwipe(baseDistance, points, progress, cancelProgress);
|
||||
}
|
||||
|
||||
_switchWorkspaceUpdate(tracker, progress) {
|
||||
if (!this._switchData)
|
||||
return;
|
||||
|
||||
for (const monitorGroup of this._switchData.monitors)
|
||||
monitorGroup.updateSwipeForMonitor(progress, this._switchData.baseMonitorGroup);
|
||||
}
|
||||
|
||||
_switchWorkspaceEnd(tracker, duration, endProgress) {
|
||||
if (!this._switchData)
|
||||
return;
|
||||
|
||||
const switchData = this._switchData;
|
||||
switchData.gestureActivated = true;
|
||||
|
||||
const newWs = switchData.baseMonitorGroup.findClosestWorkspace(endProgress);
|
||||
|
||||
for (const monitorGroup of this._switchData.monitors) {
|
||||
const progress = monitorGroup.getWorkspaceProgress(newWs);
|
||||
|
||||
const params = {
|
||||
duration,
|
||||
mode: Clutter.AnimationMode.EASE_OUT_CUBIC,
|
||||
};
|
||||
|
||||
if (monitorGroup.index === Main.layoutManager.primaryIndex) {
|
||||
params.onComplete = () => {
|
||||
if (!newWs.active)
|
||||
newWs.activate(global.get_current_time());
|
||||
this._finishWorkspaceSwitch(switchData);
|
||||
};
|
||||
}
|
||||
|
||||
monitorGroup.ease_property('progress', progress, params);
|
||||
}
|
||||
}
|
||||
|
||||
get gestureActive() {
|
||||
return this._switchData !== null && this._switchData.gestureActivated;
|
||||
}
|
||||
|
||||
cancelSwitchAnimation() {
|
||||
if (!this._switchData)
|
||||
return;
|
||||
|
||||
if (this._switchData.gestureActivated)
|
||||
return;
|
||||
|
||||
this._finishWorkspaceSwitch(this._switchData);
|
||||
}
|
||||
|
||||
set movingWindow(movingWindow) {
|
||||
this._movingWindow = movingWindow;
|
||||
}
|
||||
|
||||
get movingWindow() {
|
||||
return this._movingWindow;
|
||||
}
|
||||
};
|
@ -1,5 +1,5 @@
|
||||
project('gnome-shell', 'c',
|
||||
version: '3.37.90',
|
||||
version: '3.37.3',
|
||||
meson_version: '>= 0.53.0',
|
||||
license: 'GPLv2+'
|
||||
)
|
||||
@ -25,7 +25,7 @@ gio_req = '>= 2.56.0'
|
||||
gi_req = '>= 1.49.1'
|
||||
gjs_req = '>= 1.65.1'
|
||||
gtk_req = '>= 3.15.0'
|
||||
mutter_req = '>= 3.37.90'
|
||||
mutter_req = '>= 3.37.3'
|
||||
polkit_req = '>= 0.100'
|
||||
schemas_req = '>= 3.33.1'
|
||||
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)
|
||||
gst_dep = dependency('gstreamer-1.0', version: gst_req, required: false)
|
||||
gst_base_dep = dependency('gstreamer-base-1.0', required: false)
|
||||
pipewire_dep = dependency('libpipewire-0.3', required: false)
|
||||
|
||||
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
|
||||
recorder_deps += [gst_dep, gst_base_dep, gtk_dep, x11_dep]
|
||||
endif
|
||||
|
@ -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
|
||||
|
275
po/pt_BR.po
275
po/pt_BR.po
@ -24,8 +24,8 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: gnome-shell\n"
|
||||
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gnome-shell/issues\n"
|
||||
"POT-Creation-Date: 2020-08-10 08:53+0000\n"
|
||||
"PO-Revision-Date: 2020-08-10 08:51-0300\n"
|
||||
"POT-Creation-Date: 2020-07-18 13:44+0000\n"
|
||||
"PO-Revision-Date: 2020-07-19 09:46-0300\n"
|
||||
"Last-Translator: Rafael Fontenelle <rafaelff@gnome.org>\n"
|
||||
"Language-Team: Brazilian Portuguese <gnome-pt_br-list@gnome.org>\n"
|
||||
"Language: pt_BR\n"
|
||||
@ -237,109 +237,92 @@ msgstr ""
|
||||
"Habilita uma API de D-Bus que permite introspectar o estado do aplicativo do "
|
||||
"shell."
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:114
|
||||
msgid "Layout of the app picker"
|
||||
msgstr "Layout do seletor de aplicativo"
|
||||
|
||||
#: 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 ""
|
||||
"Layout do seletor de aplicativo. Cada entrada na matriz é uma página. As "
|
||||
"páginas são armazenadas na ordem em que aparecem no GNOME Shell. Cada página "
|
||||
"contém um par “id do aplicativo” → “dados”. Atualmente, os seguintes valores "
|
||||
"são armazenados como “dados”: • “posição”: a posição do ícone do aplicativo "
|
||||
"na página"
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:130
|
||||
#: data/org.gnome.shell.gschema.xml.in:119
|
||||
msgid "Keybinding to open the application menu"
|
||||
msgstr "Atalho de teclado para abrir um menu de aplicativo"
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:131
|
||||
#: data/org.gnome.shell.gschema.xml.in:120
|
||||
msgid "Keybinding to open the application menu."
|
||||
msgstr "Atalho de teclado para abrir um menu de aplicativo."
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:137
|
||||
#: data/org.gnome.shell.gschema.xml.in:126
|
||||
msgid "Keybinding to open the “Show Applications” view"
|
||||
msgstr "Atalho de teclado para abrir a visualização “Mostrar aplicativos”"
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:138
|
||||
#: data/org.gnome.shell.gschema.xml.in:127
|
||||
msgid ""
|
||||
"Keybinding to open the “Show Applications” view of the Activities Overview."
|
||||
msgstr ""
|
||||
"Atalho de teclado para abrir a visualização “Mostrar aplicativos” do "
|
||||
"panorama de atividades."
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:145
|
||||
#: data/org.gnome.shell.gschema.xml.in:134
|
||||
msgid "Keybinding to open the overview"
|
||||
msgstr "Atalho de teclado para abrir o panorama"
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:146
|
||||
#: data/org.gnome.shell.gschema.xml.in:135
|
||||
msgid "Keybinding to open the Activities Overview."
|
||||
msgstr "Atalho de teclado para abrir o panorama de atividades."
|
||||
|
||||
#: 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"
|
||||
msgstr "Atalho de teclado para alternar a visibilidade da lista de notificação"
|
||||
|
||||
#: 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."
|
||||
msgstr ""
|
||||
"Atalho de teclado para alternar a visibilidade da lista de notificação."
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:159
|
||||
#: data/org.gnome.shell.gschema.xml.in:148
|
||||
msgid "Keybinding to focus the active notification"
|
||||
msgstr "Atalho de teclado para ativar a notificação ativa"
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:160
|
||||
#: data/org.gnome.shell.gschema.xml.in:149
|
||||
msgid "Keybinding to focus the active notification."
|
||||
msgstr "Atalho de teclado para ativar a notificação ativa."
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:166
|
||||
#: data/org.gnome.shell.gschema.xml.in:155
|
||||
msgid "Switch to application 1"
|
||||
msgstr "Alternar para o aplicativo 1"
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:170
|
||||
#: data/org.gnome.shell.gschema.xml.in:159
|
||||
msgid "Switch to application 2"
|
||||
msgstr "Alternar para o aplicativo 2"
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:174
|
||||
#: data/org.gnome.shell.gschema.xml.in:163
|
||||
msgid "Switch to application 3"
|
||||
msgstr "Alternar para o aplicativo 3"
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:178
|
||||
#: data/org.gnome.shell.gschema.xml.in:167
|
||||
msgid "Switch to application 4"
|
||||
msgstr "Alternar para o aplicativo 4"
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:182
|
||||
#: data/org.gnome.shell.gschema.xml.in:171
|
||||
msgid "Switch to application 5"
|
||||
msgstr "Alternar para o aplicativo 5"
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:186
|
||||
#: data/org.gnome.shell.gschema.xml.in:175
|
||||
msgid "Switch to application 6"
|
||||
msgstr "Alternar para o aplicativo 6"
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:190
|
||||
#: data/org.gnome.shell.gschema.xml.in:179
|
||||
msgid "Switch to application 7"
|
||||
msgstr "Alternar para o aplicativo 7"
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:194
|
||||
#: data/org.gnome.shell.gschema.xml.in:183
|
||||
msgid "Switch to application 8"
|
||||
msgstr "Alternar para o aplicativo 8"
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:198
|
||||
#: data/org.gnome.shell.gschema.xml.in:187
|
||||
msgid "Switch to application 9"
|
||||
msgstr "Alternar para o aplicativo 9"
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:207
|
||||
#: data/org.gnome.shell.gschema.xml.in:234
|
||||
#: data/org.gnome.shell.gschema.xml.in:196
|
||||
#: data/org.gnome.shell.gschema.xml.in:223
|
||||
msgid "Limit switcher to current workspace."
|
||||
msgstr "Limitar o alternador ao espaço de trabalho atual."
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:208
|
||||
#: data/org.gnome.shell.gschema.xml.in:197
|
||||
msgid ""
|
||||
"If true, only applications that have windows on the current workspace are "
|
||||
"shown in the switcher. Otherwise, all applications are included."
|
||||
@ -348,11 +331,11 @@ msgstr ""
|
||||
"janelas no espaço de trabalho atual. Caso contrário, todos os aplicativos "
|
||||
"serão incluídos."
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:225
|
||||
#: data/org.gnome.shell.gschema.xml.in:214
|
||||
msgid "The application icon mode."
|
||||
msgstr "O modo ícone do aplicativo."
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:226
|
||||
#: data/org.gnome.shell.gschema.xml.in:215
|
||||
msgid ""
|
||||
"Configures how the windows are shown in the switcher. Valid possibilities "
|
||||
"are “thumbnail-only” (shows a thumbnail of the window), “app-icon-"
|
||||
@ -362,7 +345,7 @@ msgstr ""
|
||||
"válidas são “thumbnail-only” (mostra uma miniatura da janela), “app-icon-"
|
||||
"only” (mostra apenas o ícone do aplicativo) ou “both”."
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:235
|
||||
#: data/org.gnome.shell.gschema.xml.in:224
|
||||
msgid ""
|
||||
"If true, only windows from the current workspace are shown in the switcher. "
|
||||
"Otherwise, all windows are included."
|
||||
@ -370,58 +353,58 @@ msgstr ""
|
||||
"Se verdadeiro, o alternador mostrará somente as janelas do espaço de "
|
||||
"trabalho atual. Caso contrário, todos as janelas serão incluídas."
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:245
|
||||
#: data/org.gnome.shell.gschema.xml.in:234
|
||||
msgid "Locations"
|
||||
msgstr "Localizações"
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:246
|
||||
#: data/org.gnome.shell.gschema.xml.in:235
|
||||
msgid "The locations to show in world clocks"
|
||||
msgstr "As localizações para mostrar nos relógios mundiais"
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:256
|
||||
#: data/org.gnome.shell.gschema.xml.in:245
|
||||
msgid "Automatic location"
|
||||
msgstr "Localização automática"
|
||||
|
||||
#: 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"
|
||||
msgstr "Se deve-se obter a localização atual ou não"
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:264
|
||||
#: data/org.gnome.shell.gschema.xml.in:253
|
||||
msgid "Location"
|
||||
msgstr "Localização"
|
||||
|
||||
#: 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"
|
||||
msgstr "A localização para a qual deve-se mostrar uma previsão do tempo"
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:277
|
||||
#: data/org.gnome.shell.gschema.xml.in:266
|
||||
msgid "Attach modal dialog to the parent window"
|
||||
msgstr "Anexar diálogo modal à janela pai"
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:278
|
||||
#: data/org.gnome.shell.gschema.xml.in:287
|
||||
#: data/org.gnome.shell.gschema.xml.in:295
|
||||
#: data/org.gnome.shell.gschema.xml.in:303
|
||||
#: data/org.gnome.shell.gschema.xml.in:311
|
||||
#: data/org.gnome.shell.gschema.xml.in:267
|
||||
#: data/org.gnome.shell.gschema.xml.in:276
|
||||
#: data/org.gnome.shell.gschema.xml.in:284
|
||||
#: data/org.gnome.shell.gschema.xml.in:292
|
||||
#: data/org.gnome.shell.gschema.xml.in:300
|
||||
msgid ""
|
||||
"This key overrides the key in org.gnome.mutter when running GNOME Shell."
|
||||
msgstr ""
|
||||
"Esta chave sobrescreve a chave em org.gnome.mutter ao executar o GNOME Shell."
|
||||
|
||||
#: 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"
|
||||
msgstr ""
|
||||
"Habilitar contorno ladrilhado ao arrastar janelas sobre as bordas da tela"
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:294
|
||||
#: data/org.gnome.shell.gschema.xml.in:283
|
||||
msgid "Workspaces are managed dynamically"
|
||||
msgstr "Espaços de trabalho são gerenciados dinamicamente"
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:302
|
||||
#: data/org.gnome.shell.gschema.xml.in:291
|
||||
msgid "Workspaces only on primary monitor"
|
||||
msgstr "Espaços de trabalho apenas no monitor primário"
|
||||
|
||||
#: 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"
|
||||
msgstr "Atrasar foco altera o modo do mouse até o ponteiro parar de mover"
|
||||
|
||||
@ -458,9 +441,9 @@ msgstr "Visita a página web da extensão"
|
||||
|
||||
#: js/gdm/authPrompt.js:135 js/ui/audioDeviceSelection.js:57
|
||||
#: js/ui/components/networkAgent.js:110 js/ui/components/polkitAgent.js:139
|
||||
#: js/ui/endSessionDialog.js:398 js/ui/extensionDownloader.js:183
|
||||
#: js/ui/endSessionDialog.js:369 js/ui/extensionDownloader.js:183
|
||||
#: js/ui/shellMountOperation.js:376 js/ui/shellMountOperation.js:386
|
||||
#: js/ui/status/network.js:940 subprojects/extensions-app/js/main.js:149
|
||||
#: js/ui/status/network.js:916 subprojects/extensions-app/js/main.js:149
|
||||
msgid "Cancel"
|
||||
msgstr "Cancelar"
|
||||
|
||||
@ -496,7 +479,7 @@ msgstr "(ex.: usuário ou %s)"
|
||||
msgid "Username"
|
||||
msgstr "Nome de usuário"
|
||||
|
||||
#: js/gdm/loginDialog.js:1253
|
||||
#: js/gdm/loginDialog.js:1254
|
||||
msgid "Login Window"
|
||||
msgstr "Janela de sessão"
|
||||
|
||||
@ -744,36 +727,38 @@ msgstr "Negar acesso"
|
||||
msgid "Grant Access"
|
||||
msgstr "Conceder acesso"
|
||||
|
||||
#: js/ui/appDisplay.js:1297
|
||||
#: js/ui/appDisplay.js:903
|
||||
msgid "Unnamed Folder"
|
||||
msgstr "Pasta sem nome"
|
||||
|
||||
#. Translators: This is the heading of a list of open windows
|
||||
#: js/ui/appDisplay.js:2762 js/ui/panel.js:75
|
||||
#: js/ui/appDisplay.js:2225 js/ui/panel.js:75
|
||||
msgid "Open Windows"
|
||||
msgstr "Janelas abertas"
|
||||
|
||||
#: js/ui/appDisplay.js:2781 js/ui/panel.js:82
|
||||
#: js/ui/appDisplay.js:2244 js/ui/panel.js:82
|
||||
msgid "New Window"
|
||||
msgstr "Nova janela"
|
||||
|
||||
#: js/ui/appDisplay.js:2797
|
||||
#: js/ui/appDisplay.js:2260
|
||||
#| msgid "Launch using Dedicated Graphics Card"
|
||||
msgid "Launch using Integrated Graphics Card"
|
||||
msgstr "Iniciar usando placa de vídeo integrada"
|
||||
|
||||
#: js/ui/appDisplay.js:2798
|
||||
#: js/ui/appDisplay.js:2261
|
||||
#| msgid "Launch using Dedicated Graphics Card"
|
||||
msgid "Launch using Discrete Graphics Card"
|
||||
msgstr "Iniciar usando placa de vídeo dedicada"
|
||||
|
||||
#: js/ui/appDisplay.js:2826 js/ui/dash.js:239
|
||||
#: js/ui/appDisplay.js:2289 js/ui/dash.js:239
|
||||
msgid "Remove from Favorites"
|
||||
msgstr "Remover dos favoritos"
|
||||
|
||||
#: js/ui/appDisplay.js:2832
|
||||
#: js/ui/appDisplay.js:2295
|
||||
msgid "Add to Favorites"
|
||||
msgstr "Adicionar aos favoritos"
|
||||
|
||||
#: js/ui/appDisplay.js:2842 js/ui/panel.js:93
|
||||
#: js/ui/appDisplay.js:2305 js/ui/panel.js:93
|
||||
msgid "Show Details"
|
||||
msgstr "Mostrar detalhes"
|
||||
|
||||
@ -974,8 +959,8 @@ msgstr ""
|
||||
"Alternativamente, você pode conectar pressionando o botão “WPS” em seu "
|
||||
"roteador."
|
||||
|
||||
#: js/ui/components/networkAgent.js:104 js/ui/status/network.js:252
|
||||
#: js/ui/status/network.js:343 js/ui/status/network.js:943
|
||||
#: js/ui/components/networkAgent.js:104 js/ui/status/network.js:227
|
||||
#: js/ui/status/network.js:318 js/ui/status/network.js:919
|
||||
msgid "Connect"
|
||||
msgstr "Conectar"
|
||||
|
||||
@ -1040,7 +1025,7 @@ msgstr "PIN"
|
||||
msgid "A password is required to connect to “%s”."
|
||||
msgstr "Uma senha é necessária para se conectar a “%s”."
|
||||
|
||||
#: js/ui/components/networkAgent.js:669 js/ui/status/network.js:1718
|
||||
#: js/ui/components/networkAgent.js:669 js/ui/status/network.js:1694
|
||||
msgid "Network Manager"
|
||||
msgstr "Gerenciador de rede"
|
||||
|
||||
@ -1108,12 +1093,14 @@ msgstr "%A, %e de %B de %Y"
|
||||
|
||||
#. Translators: Shown on calendar heading when selected day occurs on current year
|
||||
#: js/ui/dateMenu.js:151
|
||||
#| msgid "%B %-d %Y"
|
||||
msgctxt "calendar heading"
|
||||
msgid "%B %-d"
|
||||
msgstr "%-d de %B"
|
||||
|
||||
#. Translators: Shown on calendar heading when selected day occurs on different year
|
||||
#: js/ui/dateMenu.js:154
|
||||
#| msgid "%B %-d %Y"
|
||||
msgctxt "calendar heading"
|
||||
msgid "%B %-d %Y"
|
||||
msgstr "%-d de %B de %Y"
|
||||
@ -1163,6 +1150,7 @@ msgid "Weather"
|
||||
msgstr "Meteorologia"
|
||||
|
||||
#: js/ui/dateMenu.js:653
|
||||
#| msgid "Select a location…"
|
||||
msgid "Select weather location…"
|
||||
msgstr "Selecione uma localização meteorológica…"
|
||||
|
||||
@ -1290,32 +1278,27 @@ msgstr ""
|
||||
"pode levar um longo tempo: certifique-se de que fez cópia de segurança (back "
|
||||
"up) e que o computador esteja ligado na tomada."
|
||||
|
||||
#: js/ui/endSessionDialog.js:267
|
||||
#: js/ui/endSessionDialog.js:259
|
||||
msgid "Running on battery power: Please plug in before installing updates."
|
||||
msgstr ""
|
||||
"Funcionando na bateria: conecte na tomada antes de instalar atualizações."
|
||||
|
||||
#: js/ui/endSessionDialog.js:276
|
||||
#: js/ui/endSessionDialog.js:268
|
||||
msgid "Some applications are busy or have unsaved work"
|
||||
msgstr "Alguns aplicativos estão ocupados ou possuem trabalhos não salvos"
|
||||
|
||||
#: js/ui/endSessionDialog.js:281
|
||||
#: js/ui/endSessionDialog.js:273
|
||||
msgid "Other users are logged in"
|
||||
msgstr "Outros usuários estão com sessão aberta"
|
||||
|
||||
#: js/ui/endSessionDialog.js:427
|
||||
msgctxt "button"
|
||||
msgid "Boot Options"
|
||||
msgstr "Opções de inicialização"
|
||||
|
||||
#. Translators: Remote here refers to a remote session, like a ssh login
|
||||
#: js/ui/endSessionDialog.js:645
|
||||
#: js/ui/endSessionDialog.js:583
|
||||
#, javascript-format
|
||||
msgid "%s (remote)"
|
||||
msgstr "%s (remoto)"
|
||||
|
||||
#. Translators: Console here refers to a tty like a VT console
|
||||
#: js/ui/endSessionDialog.js:648
|
||||
#: js/ui/endSessionDialog.js:586
|
||||
#, javascript-format
|
||||
msgid "%s (console)"
|
||||
msgstr "%s (console)"
|
||||
@ -1418,15 +1401,15 @@ msgid "Leave On"
|
||||
msgstr "Deixar ativado"
|
||||
|
||||
#: js/ui/kbdA11yDialog.js:55 js/ui/status/bluetooth.js:156
|
||||
#: js/ui/status/network.js:1315
|
||||
#: js/ui/status/network.js:1291
|
||||
msgid "Turn On"
|
||||
msgstr "Ligar"
|
||||
|
||||
#: js/ui/kbdA11yDialog.js:63 js/ui/status/bluetooth.js:156
|
||||
#: js/ui/status/network.js:160 js/ui/status/network.js:344
|
||||
#: js/ui/status/network.js:1315 js/ui/status/network.js:1427
|
||||
#: js/ui/status/network.js:135 js/ui/status/network.js:319
|
||||
#: js/ui/status/network.js:1291 js/ui/status/network.js:1403
|
||||
#: js/ui/status/nightLight.js:41 js/ui/status/rfkill.js:81
|
||||
#: js/ui/status/rfkill.js:110
|
||||
#: js/ui/status/rfkill.js:108
|
||||
msgid "Turn Off"
|
||||
msgstr "Desligar"
|
||||
|
||||
@ -1487,11 +1470,11 @@ msgstr "Ver fonte"
|
||||
msgid "Web Page"
|
||||
msgstr "Página web"
|
||||
|
||||
#: js/ui/main.js:294
|
||||
#: js/ui/main.js:297
|
||||
msgid "Logged in as a privileged user"
|
||||
msgstr "Sessão aberta como um usuário privilegiado"
|
||||
|
||||
#: js/ui/main.js:295
|
||||
#: js/ui/main.js:298
|
||||
msgid ""
|
||||
"Running a session as a privileged user should be avoided for security "
|
||||
"reasons. If possible, you should log in as a normal user."
|
||||
@ -1499,11 +1482,11 @@ msgstr ""
|
||||
"Usar uma sessão como um usuário privilegiado deve ser evitado por motivos de "
|
||||
"segurança. Se possível, você deve abrir uma sessão como um usuário normal."
|
||||
|
||||
#: js/ui/main.js:334
|
||||
#: js/ui/main.js:337
|
||||
msgid "Screen Lock disabled"
|
||||
msgstr "Bloqueio de tela desabilitado"
|
||||
|
||||
#: js/ui/main.js:335
|
||||
#: js/ui/main.js:338
|
||||
msgid "Screen Locking requires the GNOME display manager."
|
||||
msgstr "O bloqueio de tela requer o gerenciador de exibição do GNOME."
|
||||
|
||||
@ -1596,7 +1579,7 @@ msgctxt "System menu in the top bar"
|
||||
msgid "System"
|
||||
msgstr "Sistema"
|
||||
|
||||
#: js/ui/panel.js:825
|
||||
#: js/ui/panel.js:827
|
||||
msgid "Top Bar"
|
||||
msgstr "Barra superior"
|
||||
|
||||
@ -1773,15 +1756,17 @@ msgstr "Texto grande"
|
||||
msgid "Bluetooth"
|
||||
msgstr "Bluetooth"
|
||||
|
||||
#: js/ui/status/bluetooth.js:49 js/ui/status/network.js:619
|
||||
#: js/ui/status/bluetooth.js:49 js/ui/status/network.js:595
|
||||
msgid "Bluetooth Settings"
|
||||
msgstr "Configurações de Bluetooth"
|
||||
|
||||
#: js/ui/status/bluetooth.js:152
|
||||
#| msgid "Bluetooth"
|
||||
msgid "Bluetooth Off"
|
||||
msgstr "Bluetooth desligado"
|
||||
|
||||
#: js/ui/status/bluetooth.js:154
|
||||
#| msgid "Bluetooth"
|
||||
msgid "Bluetooth On"
|
||||
msgstr "Bluetooth ligado"
|
||||
|
||||
@ -1857,18 +1842,18 @@ msgstr ""
|
||||
"Acesso a localização pode ser alterado a qualquer momento nas configurações "
|
||||
"de privacidade."
|
||||
|
||||
#: js/ui/status/network.js:71
|
||||
#: js/ui/status/network.js:70
|
||||
msgid "<unknown>"
|
||||
msgstr "<desconhecido>"
|
||||
|
||||
#. Translators: %s is a network identifier
|
||||
#: js/ui/status/network.js:449 js/ui/status/network.js:1344
|
||||
#: js/ui/status/network.js:424 js/ui/status/network.js:1320
|
||||
#, javascript-format
|
||||
msgid "%s Off"
|
||||
msgstr "%s desligada"
|
||||
|
||||
#. Translators: %s is a network identifier
|
||||
#: js/ui/status/network.js:452
|
||||
#: js/ui/status/network.js:427
|
||||
#, javascript-format
|
||||
msgid "%s Connected"
|
||||
msgstr "Conectado à %s"
|
||||
@ -1877,189 +1862,189 @@ msgstr "Conectado à %s"
|
||||
#. Translators: this is for network devices that are physically present but are not
|
||||
#. under NetworkManager's control (and thus cannot be used in the menu);
|
||||
#. %s is a network identifier
|
||||
#: js/ui/status/network.js:457
|
||||
#: js/ui/status/network.js:432
|
||||
#, javascript-format
|
||||
msgid "%s Unmanaged"
|
||||
msgstr "%s não é gerenciável"
|
||||
|
||||
#. Translators: %s is a network identifier
|
||||
#: js/ui/status/network.js:460
|
||||
#: js/ui/status/network.js:435
|
||||
#, javascript-format
|
||||
msgid "%s Disconnecting"
|
||||
msgstr "Desconectando de %s"
|
||||
|
||||
#. Translators: %s is a network identifier
|
||||
#: js/ui/status/network.js:467 js/ui/status/network.js:1336
|
||||
#: js/ui/status/network.js:442 js/ui/status/network.js:1312
|
||||
#, javascript-format
|
||||
msgid "%s Connecting"
|
||||
msgstr "Conectando à %s"
|
||||
|
||||
#. Translators: this is for network connections that require some kind of key or password; %s is a network identifier
|
||||
#: js/ui/status/network.js:470
|
||||
#: js/ui/status/network.js:445
|
||||
#, javascript-format
|
||||
msgid "%s Requires Authentication"
|
||||
msgstr "%s requer autenticação"
|
||||
|
||||
#. Translators: this is for devices that require some kind of firmware or kernel
|
||||
#. module, which is missing; %s is a network identifier
|
||||
#: js/ui/status/network.js:478
|
||||
#: js/ui/status/network.js:453
|
||||
#, javascript-format
|
||||
msgid "Firmware Missing For %s"
|
||||
msgstr "Firmware em falta para %s"
|
||||
|
||||
#. Translators: this is for a network device that cannot be activated (for example it
|
||||
#. is disabled by rfkill, or it has no coverage; %s is a network identifier
|
||||
#: js/ui/status/network.js:482
|
||||
#: js/ui/status/network.js:457
|
||||
#, javascript-format
|
||||
msgid "%s Unavailable"
|
||||
msgstr "%s está indisponível"
|
||||
|
||||
#. Translators: %s is a network identifier
|
||||
#: js/ui/status/network.js:485
|
||||
#: js/ui/status/network.js:460
|
||||
#, javascript-format
|
||||
msgid "%s Connection Failed"
|
||||
msgstr "Falha na conexão de %s"
|
||||
|
||||
#: js/ui/status/network.js:497
|
||||
#: js/ui/status/network.js:472
|
||||
msgid "Wired Settings"
|
||||
msgstr "Configurações da rede cabeada"
|
||||
|
||||
#: js/ui/status/network.js:540
|
||||
#: js/ui/status/network.js:515
|
||||
msgid "Mobile Broadband Settings"
|
||||
msgstr "Configurações de banda larga móvel"
|
||||
|
||||
#. Translators: %s is a network identifier
|
||||
#: js/ui/status/network.js:586 js/ui/status/network.js:1341
|
||||
#: js/ui/status/network.js:562 js/ui/status/network.js:1317
|
||||
#, javascript-format
|
||||
msgid "%s Hardware Disabled"
|
||||
msgstr "Hardware de %s desabilitado"
|
||||
|
||||
#. Translators: this is for a network device that cannot be activated
|
||||
#. because it's disabled by rfkill (airplane mode); %s is a network identifier
|
||||
#: js/ui/status/network.js:590
|
||||
#: js/ui/status/network.js:566
|
||||
#, javascript-format
|
||||
msgid "%s Disabled"
|
||||
msgstr "%s está desabilitado"
|
||||
|
||||
#: js/ui/status/network.js:631
|
||||
#: js/ui/status/network.js:607
|
||||
msgid "Connect to Internet"
|
||||
msgstr "Conectar à Internet"
|
||||
|
||||
#: js/ui/status/network.js:835
|
||||
#: js/ui/status/network.js:811
|
||||
msgid "Airplane Mode is On"
|
||||
msgstr "Modo avião ligado"
|
||||
|
||||
#: js/ui/status/network.js:836
|
||||
#: js/ui/status/network.js:812
|
||||
msgid "Wi-Fi is disabled when airplane mode is on."
|
||||
msgstr "O Wi-Fi é desabilitado quando o modo avião está ligado."
|
||||
|
||||
#: js/ui/status/network.js:837
|
||||
#: js/ui/status/network.js:813
|
||||
msgid "Turn Off Airplane Mode"
|
||||
msgstr "Desligar modo avião"
|
||||
|
||||
#: js/ui/status/network.js:846
|
||||
#: js/ui/status/network.js:822
|
||||
msgid "Wi-Fi is Off"
|
||||
msgstr "Wi-Fi desligado"
|
||||
|
||||
#: js/ui/status/network.js:847
|
||||
#: js/ui/status/network.js:823
|
||||
msgid "Wi-Fi needs to be turned on in order to connect to a network."
|
||||
msgstr "O Wi-Fi precisa ser ligado a fim de conectar-se a uma rede."
|
||||
|
||||
#: js/ui/status/network.js:848
|
||||
#: js/ui/status/network.js:824
|
||||
msgid "Turn On Wi-Fi"
|
||||
msgstr "Ligar Wi-Fi"
|
||||
|
||||
#: js/ui/status/network.js:873
|
||||
#: js/ui/status/network.js:849
|
||||
msgid "Wi-Fi Networks"
|
||||
msgstr "Redes Wi-Fi"
|
||||
|
||||
#: js/ui/status/network.js:875
|
||||
#: js/ui/status/network.js:851
|
||||
msgid "Select a network"
|
||||
msgstr "Selecione uma rede"
|
||||
|
||||
#: js/ui/status/network.js:907
|
||||
#: js/ui/status/network.js:883
|
||||
msgid "No Networks"
|
||||
msgstr "Nenhuma rede"
|
||||
|
||||
#: js/ui/status/network.js:928 js/ui/status/rfkill.js:108
|
||||
#: js/ui/status/network.js:904 js/ui/status/rfkill.js:106
|
||||
msgid "Use hardware switch to turn off"
|
||||
msgstr "Usar alternador de hardware para desligar"
|
||||
|
||||
#: js/ui/status/network.js:1205
|
||||
#: js/ui/status/network.js:1181
|
||||
msgid "Select Network"
|
||||
msgstr "Selecione a rede"
|
||||
|
||||
#: js/ui/status/network.js:1211
|
||||
#: js/ui/status/network.js:1187
|
||||
msgid "Wi-Fi Settings"
|
||||
msgstr "Configurações de Wi-Fi"
|
||||
|
||||
#. Translators: %s is a network identifier
|
||||
#: js/ui/status/network.js:1332
|
||||
#: js/ui/status/network.js:1308
|
||||
#, javascript-format
|
||||
msgid "%s Hotspot Active"
|
||||
msgstr "Ponto de acesso %s está ativo"
|
||||
|
||||
#. Translators: %s is a network identifier
|
||||
#: js/ui/status/network.js:1347
|
||||
#: js/ui/status/network.js:1323
|
||||
#, javascript-format
|
||||
msgid "%s Not Connected"
|
||||
msgstr "%s não está conectado"
|
||||
|
||||
#: js/ui/status/network.js:1444
|
||||
#: js/ui/status/network.js:1420
|
||||
msgid "connecting…"
|
||||
msgstr "conectando…"
|
||||
|
||||
#. Translators: this is for network connections that require some kind of key or password
|
||||
#: js/ui/status/network.js:1447
|
||||
#: js/ui/status/network.js:1423
|
||||
msgid "authentication required"
|
||||
msgstr "autenticação necessária"
|
||||
|
||||
#: js/ui/status/network.js:1449
|
||||
#: js/ui/status/network.js:1425
|
||||
msgid "connection failed"
|
||||
msgstr "conexão falhou"
|
||||
|
||||
#: js/ui/status/network.js:1500
|
||||
#: js/ui/status/network.js:1476
|
||||
msgid "VPN Settings"
|
||||
msgstr "Configurações de VPN"
|
||||
|
||||
#: js/ui/status/network.js:1517
|
||||
#: js/ui/status/network.js:1493
|
||||
msgid "VPN"
|
||||
msgstr "VPN"
|
||||
|
||||
#: js/ui/status/network.js:1527
|
||||
#: js/ui/status/network.js:1503
|
||||
msgid "VPN Off"
|
||||
msgstr "VPN desligada"
|
||||
|
||||
#: js/ui/status/network.js:1588 js/ui/status/rfkill.js:84
|
||||
#: js/ui/status/network.js:1564 js/ui/status/rfkill.js:84
|
||||
msgid "Network Settings"
|
||||
msgstr "Configurações de rede"
|
||||
|
||||
#: js/ui/status/network.js:1617
|
||||
#: js/ui/status/network.js:1593
|
||||
#, javascript-format
|
||||
msgid "%s Wired Connection"
|
||||
msgid_plural "%s Wired Connections"
|
||||
msgstr[0] "%s conexão cabeada"
|
||||
msgstr[1] "%s conexões cabeadas"
|
||||
|
||||
#: js/ui/status/network.js:1621
|
||||
#: js/ui/status/network.js:1597
|
||||
#, javascript-format
|
||||
msgid "%s Wi-Fi Connection"
|
||||
msgid_plural "%s Wi-Fi Connections"
|
||||
msgstr[0] "%s conexão Wi-Fi"
|
||||
msgstr[1] "%s conexões Wi-Fi"
|
||||
|
||||
#: js/ui/status/network.js:1625
|
||||
#: js/ui/status/network.js:1601
|
||||
#, javascript-format
|
||||
msgid "%s Modem Connection"
|
||||
msgid_plural "%s Modem Connections"
|
||||
msgstr[0] "%s conexão por modem"
|
||||
msgstr[1] "%s conexões por modems"
|
||||
|
||||
#: js/ui/status/network.js:1759
|
||||
#: js/ui/status/network.js:1735
|
||||
msgid "Connection failed"
|
||||
msgstr "Falha de conexão"
|
||||
|
||||
#: js/ui/status/network.js:1760
|
||||
#: js/ui/status/network.js:1736
|
||||
msgid "Activation of network connection failed"
|
||||
msgstr "Falha ao ativar a conexão da rede"
|
||||
|
||||
@ -2114,11 +2099,11 @@ msgstr "%d:%02d até completar (%d %%)"
|
||||
msgid "%d %%"
|
||||
msgstr "%d %%"
|
||||
|
||||
#: js/ui/status/remoteAccess.js:45
|
||||
#: js/ui/status/remoteAccess.js:43
|
||||
msgid "Screen is Being Shared"
|
||||
msgstr "A tela está sendo compartilhada"
|
||||
|
||||
#: js/ui/status/remoteAccess.js:47
|
||||
#: js/ui/status/remoteAccess.js:45
|
||||
msgid "Turn off"
|
||||
msgstr "Desativar"
|
||||
|
||||
@ -2263,22 +2248,22 @@ msgstr "“%s” está pronto"
|
||||
# Título de janela de confirmação; Se grande demais, pode ser exibida com "..."
|
||||
# Vide: https://bugzilla.gnome.org/show_bug.cgi?id=786331
|
||||
#. Translators: This string should be shorter than 30 characters
|
||||
#: js/ui/windowManager.js:60
|
||||
#: js/ui/windowManager.js:55
|
||||
msgid "Keep these display settings?"
|
||||
msgstr "Manter essas configurações da tela?"
|
||||
|
||||
#. Translators: this and the following message should be limited in length,
|
||||
#. to avoid ellipsizing the labels.
|
||||
#.
|
||||
#: js/ui/windowManager.js:69
|
||||
#: js/ui/windowManager.js:64
|
||||
msgid "Revert Settings"
|
||||
msgstr "Reverter configurações"
|
||||
|
||||
#: js/ui/windowManager.js:72
|
||||
#: js/ui/windowManager.js:67
|
||||
msgid "Keep Changes"
|
||||
msgstr "Manter alterações"
|
||||
|
||||
#: js/ui/windowManager.js:91
|
||||
#: js/ui/windowManager.js:86
|
||||
#, javascript-format
|
||||
msgid "Settings changes will revert in %d second"
|
||||
msgid_plural "Settings changes will revert in %d seconds"
|
||||
@ -2287,7 +2272,7 @@ msgstr[1] "Alterações nas configurações serão revertidas em %d segundos"
|
||||
|
||||
#. Translators: This represents the size of a window. The first number is
|
||||
#. * the width of the window and the second is the height.
|
||||
#: js/ui/windowManager.js:551
|
||||
#: js/ui/windowManager.js:546
|
||||
#, javascript-format
|
||||
msgid "%d × %d"
|
||||
msgstr "%d × %d"
|
||||
@ -2465,6 +2450,7 @@ msgid "The extension is incompatible with the current GNOME version"
|
||||
msgstr "A extensão é incompatível com a versão atual do GNOME"
|
||||
|
||||
#: subprojects/extensions-app/js/main.js:464
|
||||
#| msgid "Show extension info"
|
||||
msgid "The extension had an error"
|
||||
msgstr "A extensão apresentou um erro"
|
||||
|
||||
@ -2621,6 +2607,7 @@ msgid "TEMPLATE"
|
||||
msgstr "MODELO"
|
||||
|
||||
#: subprojects/extensions-tool/src/command-create.c:447
|
||||
#| msgid "The user-visible name of the new extension"
|
||||
msgid "The template to use for the new extension"
|
||||
msgstr "O modelo para usar para a nova extensão"
|
||||
|
||||
@ -2797,6 +2784,7 @@ msgstr "Mais de um diretório fonte especificado"
|
||||
|
||||
#: subprojects/extensions-tool/src/command-prefs.c:47
|
||||
#, c-format
|
||||
#| msgid "Show extensions with preferences"
|
||||
msgid "Extension “%s” doesn't have preferences\n"
|
||||
msgstr "A extensão “%s” não tem preferências\n"
|
||||
|
||||
@ -2809,11 +2797,13 @@ msgid "Reset an extension"
|
||||
msgstr "Redefine uma extensão"
|
||||
|
||||
#: subprojects/extensions-tool/src/command-uninstall.c:49
|
||||
#| msgid "List installed extensions"
|
||||
msgid "Cannot uninstall system extensions\n"
|
||||
msgstr "Não é possível desinstalar as extensões do sistema\n"
|
||||
|
||||
#: subprojects/extensions-tool/src/command-uninstall.c:64
|
||||
#, c-format
|
||||
#| msgid "Failed to launch “%s”"
|
||||
msgid "Failed to uninstall “%s”\n"
|
||||
msgstr "Falha ao desinstalar “%s”\n"
|
||||
|
||||
@ -2926,6 +2916,7 @@ msgid "Plain"
|
||||
msgstr "Em branco"
|
||||
|
||||
#: subprojects/extensions-tool/src/templates/00-plain.desktop.in:5
|
||||
#| msgid "Reset extension"
|
||||
msgid "An empty extension"
|
||||
msgstr "Uma extensão vazia"
|
||||
|
||||
|
300
po/uk.po
300
po/uk.po
@ -10,8 +10,8 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: gnome-shell master\n"
|
||||
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gnome-shell/issues\n"
|
||||
"POT-Creation-Date: 2020-08-10 23:58+0000\n"
|
||||
"PO-Revision-Date: 2020-08-11 09:23+0300\n"
|
||||
"POT-Creation-Date: 2020-07-20 16:18+0000\n"
|
||||
"PO-Revision-Date: 2020-07-21 08:42+0300\n"
|
||||
"Last-Translator: Yuri Chornoivan <yurchor@ukr.net>\n"
|
||||
"Language-Team: Ukrainian <kde-i18n-uk@kde.org>\n"
|
||||
"Language: uk\n"
|
||||
@ -227,11 +227,11 @@ msgid ""
|
||||
"“application id” → 'data' pair. Currently, the following values are stored "
|
||||
"as 'data': • “position”: the position of the application icon in the page"
|
||||
msgstr ""
|
||||
"Компонування засобу вибору програм. Кожен запис у цьому масиві є сторінкою. "
|
||||
"Сторінки зберігаються у порядку, у якому їх буде показано у GNOME Shell. "
|
||||
"Кожна сторінка містить пану записів “ідентифікатор програми” → 'дані'. У "
|
||||
"поточній версії як 'дані' може бути збережено такі значення: • “позиція”: "
|
||||
"позиція піктограми програми на сторінці"
|
||||
"Компонування засобу вибору програм. Кожен запис у цьому масиві є сторінкою."
|
||||
" Сторінки зберігаються у порядку, у якому їх буде показано у GNOME Shell."
|
||||
" Кожна сторінка містить пану записів “ідентифікатор програми” → 'дані'. У"
|
||||
" поточній версії як 'дані' може бути збережено такі значення: • “позиція”:"
|
||||
" позиція піктограми програми на сторінці"
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:130
|
||||
msgid "Keybinding to open the application menu"
|
||||
@ -431,9 +431,9 @@ msgstr "Відвідати сторінку розширення"
|
||||
|
||||
#: js/gdm/authPrompt.js:135 js/ui/audioDeviceSelection.js:57
|
||||
#: js/ui/components/networkAgent.js:110 js/ui/components/polkitAgent.js:139
|
||||
#: js/ui/endSessionDialog.js:438 js/ui/extensionDownloader.js:183
|
||||
#: js/ui/endSessionDialog.js:369 js/ui/extensionDownloader.js:183
|
||||
#: js/ui/shellMountOperation.js:376 js/ui/shellMountOperation.js:386
|
||||
#: js/ui/status/network.js:940 subprojects/extensions-app/js/main.js:149
|
||||
#: js/ui/status/network.js:916 subprojects/extensions-app/js/main.js:149
|
||||
msgid "Cancel"
|
||||
msgstr "Скасувати"
|
||||
|
||||
@ -469,7 +469,7 @@ msgstr "(наприклад, користувач або %s)"
|
||||
msgid "Username"
|
||||
msgstr "Користувач"
|
||||
|
||||
#: js/gdm/loginDialog.js:1253
|
||||
#: js/gdm/loginDialog.js:1254
|
||||
msgid "Login Window"
|
||||
msgstr "Вікно входу"
|
||||
|
||||
@ -487,84 +487,73 @@ msgid "(or swipe finger)"
|
||||
msgstr "(або проведіть пальцем)"
|
||||
|
||||
#. Translators: The name of the power-off action in search
|
||||
#: js/misc/systemActions.js:91
|
||||
#: js/misc/systemActions.js:93
|
||||
msgctxt "search-result"
|
||||
msgid "Power Off"
|
||||
msgstr "Вимкнути"
|
||||
|
||||
#. Translators: A list of keywords that match the power-off action, separated by semicolons
|
||||
#: js/misc/systemActions.js:94
|
||||
msgid "power off;shutdown;halt;stop"
|
||||
msgstr "вимкнути;перезавантажити;зупинити;power off;shutdown;halt;stop"
|
||||
|
||||
#. Translators: The name of the restart action in search
|
||||
#: js/misc/systemActions.js:99
|
||||
msgctxt "search-result"
|
||||
msgid "Restart"
|
||||
msgstr "Перезапустити"
|
||||
|
||||
#. Translators: A list of keywords that match the restart action, separated by semicolons
|
||||
#: js/misc/systemActions.js:102
|
||||
msgid "reboot;restart;"
|
||||
msgstr "reboot;restart;перезавантаження;перезапуск;"
|
||||
#: js/misc/systemActions.js:96
|
||||
msgid "power off;shutdown;reboot;restart;halt;stop"
|
||||
msgstr "вимкнути;перезавантажити;power off;shutdown;reboot;restart;halt;stop"
|
||||
|
||||
#. Translators: The name of the lock screen action in search
|
||||
#: js/misc/systemActions.js:107
|
||||
#: js/misc/systemActions.js:101
|
||||
msgctxt "search-result"
|
||||
msgid "Lock Screen"
|
||||
msgstr "Заблокувати екран"
|
||||
|
||||
#. Translators: A list of keywords that match the lock screen action, separated by semicolons
|
||||
#: js/misc/systemActions.js:110
|
||||
#: js/misc/systemActions.js:104
|
||||
msgid "lock screen"
|
||||
msgstr "заблокувати екран;lock screen"
|
||||
|
||||
#. Translators: The name of the logout action in search
|
||||
#: js/misc/systemActions.js:115
|
||||
#: js/misc/systemActions.js:109
|
||||
msgctxt "search-result"
|
||||
msgid "Log Out"
|
||||
msgstr "Вийти"
|
||||
|
||||
#. Translators: A list of keywords that match the logout action, separated by semicolons
|
||||
#: js/misc/systemActions.js:118
|
||||
#: js/misc/systemActions.js:112
|
||||
msgid "logout;log out;sign off"
|
||||
msgstr "вийти;завершити роботу;logout;log out;sign off"
|
||||
|
||||
#. Translators: The name of the suspend action in search
|
||||
#: js/misc/systemActions.js:123
|
||||
#: js/misc/systemActions.js:117
|
||||
msgctxt "search-result"
|
||||
msgid "Suspend"
|
||||
msgstr "Призупинити"
|
||||
|
||||
#. Translators: A list of keywords that match the suspend action, separated by semicolons
|
||||
#: js/misc/systemActions.js:126
|
||||
#: js/misc/systemActions.js:120
|
||||
msgid "suspend;sleep"
|
||||
msgstr "призупинити;сон;suspend;sleep"
|
||||
|
||||
#. Translators: The name of the switch user action in search
|
||||
#: js/misc/systemActions.js:131
|
||||
#: js/misc/systemActions.js:125
|
||||
msgctxt "search-result"
|
||||
msgid "Switch User"
|
||||
msgstr "Змінити користувача"
|
||||
|
||||
#. Translators: A list of keywords that match the switch user action, separated by semicolons
|
||||
#: js/misc/systemActions.js:134
|
||||
#: js/misc/systemActions.js:128
|
||||
msgid "switch user"
|
||||
msgstr "змінити користувача;перемкнути;switch user"
|
||||
|
||||
#. Translators: A list of keywords that match the lock orientation action, separated by semicolons
|
||||
#: js/misc/systemActions.js:141
|
||||
#: js/misc/systemActions.js:135
|
||||
msgid "lock orientation;unlock orientation;screen;rotation"
|
||||
msgstr ""
|
||||
"заблокувати орієнтацію;розблокувати орієнтацію;екран;обертання;lock "
|
||||
"orientation;unlock orientation;screen;rotation"
|
||||
|
||||
#: js/misc/systemActions.js:266
|
||||
#: js/misc/systemActions.js:255
|
||||
msgctxt "search-result"
|
||||
msgid "Unlock Screen Rotation"
|
||||
msgstr "Розблокувати обертання екрана"
|
||||
|
||||
#: js/misc/systemActions.js:267
|
||||
#: js/misc/systemActions.js:256
|
||||
msgctxt "search-result"
|
||||
msgid "Lock Screen Rotation"
|
||||
msgstr "Заблокувати обертання екрана"
|
||||
@ -746,31 +735,31 @@ msgid "Unnamed Folder"
|
||||
msgstr "Неназвана тека"
|
||||
|
||||
#. Translators: This is the heading of a list of open windows
|
||||
#: js/ui/appDisplay.js:2762 js/ui/panel.js:75
|
||||
#: js/ui/appDisplay.js:2767 js/ui/panel.js:75
|
||||
msgid "Open Windows"
|
||||
msgstr "Відкрити вікна"
|
||||
|
||||
#: js/ui/appDisplay.js:2781 js/ui/panel.js:82
|
||||
#: js/ui/appDisplay.js:2786 js/ui/panel.js:82
|
||||
msgid "New Window"
|
||||
msgstr "Нове вікно"
|
||||
|
||||
#: js/ui/appDisplay.js:2797
|
||||
#: js/ui/appDisplay.js:2802
|
||||
msgid "Launch using Integrated Graphics Card"
|
||||
msgstr "Запустити через інтегровану графічну плату"
|
||||
|
||||
#: js/ui/appDisplay.js:2798
|
||||
#: js/ui/appDisplay.js:2803
|
||||
msgid "Launch using Discrete Graphics Card"
|
||||
msgstr "Запустити через дискретну графічну плату"
|
||||
|
||||
#: js/ui/appDisplay.js:2826 js/ui/dash.js:239
|
||||
#: js/ui/appDisplay.js:2831 js/ui/dash.js:239
|
||||
msgid "Remove from Favorites"
|
||||
msgstr "Вилучити з улюбленого"
|
||||
|
||||
#: js/ui/appDisplay.js:2832
|
||||
#: js/ui/appDisplay.js:2837
|
||||
msgid "Add to Favorites"
|
||||
msgstr "Додати до улюбленого"
|
||||
|
||||
#: js/ui/appDisplay.js:2842 js/ui/panel.js:93
|
||||
#: js/ui/appDisplay.js:2847 js/ui/panel.js:93
|
||||
msgid "Show Details"
|
||||
msgstr "Показати подробиці"
|
||||
|
||||
@ -969,8 +958,8 @@ msgid ""
|
||||
msgstr ""
|
||||
"Також можете під'єднатися, натиснувши кнопку «WPS» на вашому маршрутизаторі."
|
||||
|
||||
#: js/ui/components/networkAgent.js:104 js/ui/status/network.js:252
|
||||
#: js/ui/status/network.js:343 js/ui/status/network.js:943
|
||||
#: js/ui/components/networkAgent.js:104 js/ui/status/network.js:227
|
||||
#: js/ui/status/network.js:318 js/ui/status/network.js:919
|
||||
msgid "Connect"
|
||||
msgstr "З'єднатись"
|
||||
|
||||
@ -1033,7 +1022,7 @@ msgstr "Пін-код"
|
||||
msgid "A password is required to connect to “%s”."
|
||||
msgstr "Пароль потрібен для з'єднання з «%s»."
|
||||
|
||||
#: js/ui/components/networkAgent.js:669 js/ui/status/network.js:1718
|
||||
#: js/ui/components/networkAgent.js:669 js/ui/status/network.js:1694
|
||||
msgid "Network Manager"
|
||||
msgstr "Керування мережею"
|
||||
|
||||
@ -1159,18 +1148,18 @@ msgstr "Погода"
|
||||
msgid "Select weather location…"
|
||||
msgstr "Виберіть місцевість для погоди…"
|
||||
|
||||
#: js/ui/endSessionDialog.js:39
|
||||
#: js/ui/endSessionDialog.js:37
|
||||
#, javascript-format
|
||||
msgctxt "title"
|
||||
msgid "Log Out %s"
|
||||
msgstr "Завершити сеанс %s"
|
||||
|
||||
#: js/ui/endSessionDialog.js:40
|
||||
#: js/ui/endSessionDialog.js:38
|
||||
msgctxt "title"
|
||||
msgid "Log Out"
|
||||
msgstr "Завершити сеанс"
|
||||
|
||||
#: js/ui/endSessionDialog.js:43
|
||||
#: js/ui/endSessionDialog.js:40
|
||||
#, javascript-format
|
||||
msgid "%s will be logged out automatically in %d second."
|
||||
msgid_plural "%s will be logged out automatically in %d seconds."
|
||||
@ -1179,7 +1168,7 @@ msgstr[1] "%s вийде автоматично через %d секунди."
|
||||
msgstr[2] "%s вийде автоматично через %d секунд."
|
||||
msgstr[3] "%s вийде автоматично через %d секунду."
|
||||
|
||||
#: js/ui/endSessionDialog.js:49
|
||||
#: js/ui/endSessionDialog.js:45
|
||||
#, javascript-format
|
||||
msgid "You will be logged out automatically in %d second."
|
||||
msgid_plural "You will be logged out automatically in %d seconds."
|
||||
@ -1188,22 +1177,22 @@ msgstr[1] "Вихід автоматично через %d секунди."
|
||||
msgstr[2] "Вихід автоматично через %d секунд."
|
||||
msgstr[3] "Вихід автоматично через %d секунду."
|
||||
|
||||
#: js/ui/endSessionDialog.js:56
|
||||
#: js/ui/endSessionDialog.js:51
|
||||
msgctxt "button"
|
||||
msgid "Log Out"
|
||||
msgstr "Вийти"
|
||||
|
||||
#: js/ui/endSessionDialog.js:62
|
||||
#: js/ui/endSessionDialog.js:56
|
||||
msgctxt "title"
|
||||
msgid "Power Off"
|
||||
msgstr "Вимкнути"
|
||||
|
||||
#: js/ui/endSessionDialog.js:63
|
||||
#: js/ui/endSessionDialog.js:57
|
||||
msgctxt "title"
|
||||
msgid "Install Updates & Power Off"
|
||||
msgstr "Установити оновлення і вимкнути"
|
||||
|
||||
#: js/ui/endSessionDialog.js:66
|
||||
#: js/ui/endSessionDialog.js:59
|
||||
#, javascript-format
|
||||
msgid "The system will power off automatically in %d second."
|
||||
msgid_plural "The system will power off automatically in %d seconds."
|
||||
@ -1212,27 +1201,27 @@ msgstr[1] "Система автоматично вимкнеться через
|
||||
msgstr[2] "Система автоматично вимкнеться через %d секунд."
|
||||
msgstr[3] "Система автоматично вимкнеться через %d секунду."
|
||||
|
||||
#: js/ui/endSessionDialog.js:70 js/ui/endSessionDialog.js:89
|
||||
#: js/ui/endSessionDialog.js:63
|
||||
msgctxt "checkbox"
|
||||
msgid "Install pending software updates"
|
||||
msgstr "Установити оновлення, які в черзі"
|
||||
|
||||
#: js/ui/endSessionDialog.js:74
|
||||
#: js/ui/endSessionDialog.js:66 js/ui/endSessionDialog.js:82
|
||||
msgctxt "button"
|
||||
msgid "Restart"
|
||||
msgstr "Перезапустити"
|
||||
|
||||
#: js/ui/endSessionDialog.js:68
|
||||
msgctxt "button"
|
||||
msgid "Power Off"
|
||||
msgstr "Вимкнути"
|
||||
|
||||
#: js/ui/endSessionDialog.js:81
|
||||
#: js/ui/endSessionDialog.js:74
|
||||
msgctxt "title"
|
||||
msgid "Restart"
|
||||
msgstr "Перезапустити"
|
||||
|
||||
#: js/ui/endSessionDialog.js:82
|
||||
msgctxt "title"
|
||||
msgid "Install Updates & Restart"
|
||||
msgstr "Установити оновлення і перезапустити"
|
||||
|
||||
#: js/ui/endSessionDialog.js:85
|
||||
#: js/ui/endSessionDialog.js:76
|
||||
#, javascript-format
|
||||
msgid "The system will restart automatically in %d second."
|
||||
msgid_plural "The system will restart automatically in %d seconds."
|
||||
@ -1241,17 +1230,12 @@ msgstr[1] "Система автоматично перезапуститься
|
||||
msgstr[2] "Система автоматично перезапуститься через %d секунд."
|
||||
msgstr[3] "Система автоматично перезапуститься через %d секунду."
|
||||
|
||||
#: js/ui/endSessionDialog.js:93
|
||||
msgctxt "button"
|
||||
msgid "Restart"
|
||||
msgstr "Перезапустити"
|
||||
|
||||
#: js/ui/endSessionDialog.js:101
|
||||
#: js/ui/endSessionDialog.js:89
|
||||
msgctxt "title"
|
||||
msgid "Restart & Install Updates"
|
||||
msgstr "Перезапустити і встановити оновлення"
|
||||
|
||||
#: js/ui/endSessionDialog.js:104
|
||||
#: js/ui/endSessionDialog.js:91
|
||||
#, javascript-format
|
||||
msgid "The system will automatically restart and install updates in %d second."
|
||||
msgid_plural ""
|
||||
@ -1265,22 +1249,22 @@ msgstr[2] ""
|
||||
msgstr[3] ""
|
||||
"Система автоматично перезапуститься та встановить оновлення через %d секунду."
|
||||
|
||||
#: js/ui/endSessionDialog.js:111 js/ui/endSessionDialog.js:132
|
||||
#: js/ui/endSessionDialog.js:97 js/ui/endSessionDialog.js:116
|
||||
msgctxt "button"
|
||||
msgid "Restart & Install"
|
||||
msgstr "Перезапустити та встановити"
|
||||
|
||||
#: js/ui/endSessionDialog.js:113
|
||||
#: js/ui/endSessionDialog.js:98
|
||||
msgctxt "button"
|
||||
msgid "Install & Power Off"
|
||||
msgstr "Установити та вимкнути"
|
||||
|
||||
#: js/ui/endSessionDialog.js:114
|
||||
#: js/ui/endSessionDialog.js:99
|
||||
msgctxt "checkbox"
|
||||
msgid "Power off after updates are installed"
|
||||
msgstr "Вимкнути після встановлення оновлень"
|
||||
|
||||
#: js/ui/endSessionDialog.js:121
|
||||
#: js/ui/endSessionDialog.js:106
|
||||
msgctxt "title"
|
||||
msgid "Restart & Install Upgrade"
|
||||
msgstr "Перезапустити і встановити оновлення"
|
||||
@ -1288,7 +1272,7 @@ msgstr "Перезапустити і встановити оновлення"
|
||||
#. Translators: This is the text displayed for system upgrades in the
|
||||
#. shut down dialog. First %s gets replaced with the distro name and
|
||||
#. second %s with the distro version to upgrade to
|
||||
#: js/ui/endSessionDialog.js:126
|
||||
#: js/ui/endSessionDialog.js:111
|
||||
#, javascript-format
|
||||
msgid ""
|
||||
"%s %s will be installed after restart. Upgrade installation can take a long "
|
||||
@ -1298,34 +1282,28 @@ msgstr ""
|
||||
"переконайтесь, що ви зробили резервні копії та комп'ютер під'єднано до "
|
||||
"живлення."
|
||||
|
||||
#: js/ui/endSessionDialog.js:284
|
||||
#| msgid "Running on battery power: Please plug in before installing updates."
|
||||
msgid "Low battery power: please plug in before installing updates."
|
||||
#: js/ui/endSessionDialog.js:259
|
||||
msgid "Running on battery power: Please plug in before installing updates."
|
||||
msgstr ""
|
||||
"Низький рівень заряду батареї: під'єднайте до живлення перед установленням"
|
||||
" оновлень."
|
||||
"Працює від заряду батареї: під'єднайте до живлення перед установленням "
|
||||
"оновлень."
|
||||
|
||||
#: js/ui/endSessionDialog.js:293
|
||||
#: js/ui/endSessionDialog.js:268
|
||||
msgid "Some applications are busy or have unsaved work"
|
||||
msgstr "Деякі програми зайняті або мають незбережені дані"
|
||||
|
||||
#: js/ui/endSessionDialog.js:298
|
||||
#: js/ui/endSessionDialog.js:273
|
||||
msgid "Other users are logged in"
|
||||
msgstr "Є інші користувачі з активним сеансом"
|
||||
|
||||
#: js/ui/endSessionDialog.js:467
|
||||
msgctxt "button"
|
||||
msgid "Boot Options"
|
||||
msgstr "Параметри завантаження"
|
||||
|
||||
#. Translators: Remote here refers to a remote session, like a ssh login
|
||||
#: js/ui/endSessionDialog.js:685
|
||||
#: js/ui/endSessionDialog.js:583
|
||||
#, javascript-format
|
||||
msgid "%s (remote)"
|
||||
msgstr "%s (віддалено)"
|
||||
|
||||
#. Translators: Console here refers to a tty like a VT console
|
||||
#: js/ui/endSessionDialog.js:688
|
||||
#: js/ui/endSessionDialog.js:586
|
||||
#, javascript-format
|
||||
msgid "%s (console)"
|
||||
msgstr "%s (консоль)"
|
||||
@ -1425,15 +1403,15 @@ msgid "Leave On"
|
||||
msgstr "Залишити"
|
||||
|
||||
#: js/ui/kbdA11yDialog.js:55 js/ui/status/bluetooth.js:156
|
||||
#: js/ui/status/network.js:1315
|
||||
#: js/ui/status/network.js:1291
|
||||
msgid "Turn On"
|
||||
msgstr "Увімкнути"
|
||||
|
||||
#: js/ui/kbdA11yDialog.js:63 js/ui/status/bluetooth.js:156
|
||||
#: js/ui/status/network.js:160 js/ui/status/network.js:344
|
||||
#: js/ui/status/network.js:1315 js/ui/status/network.js:1427
|
||||
#: js/ui/status/network.js:135 js/ui/status/network.js:319
|
||||
#: js/ui/status/network.js:1291 js/ui/status/network.js:1403
|
||||
#: js/ui/status/nightLight.js:41 js/ui/status/rfkill.js:81
|
||||
#: js/ui/status/rfkill.js:110
|
||||
#: js/ui/status/rfkill.js:108
|
||||
msgid "Turn Off"
|
||||
msgstr "Вимкнути"
|
||||
|
||||
@ -1494,11 +1472,11 @@ msgstr "Переглянути джерело"
|
||||
msgid "Web Page"
|
||||
msgstr "Веб-сторінка"
|
||||
|
||||
#: js/ui/main.js:294
|
||||
#: js/ui/main.js:297
|
||||
msgid "Logged in as a privileged user"
|
||||
msgstr "Увійшов як наділений користувач"
|
||||
|
||||
#: js/ui/main.js:295
|
||||
#: js/ui/main.js:298
|
||||
msgid ""
|
||||
"Running a session as a privileged user should be avoided for security "
|
||||
"reasons. If possible, you should log in as a normal user."
|
||||
@ -1506,11 +1484,11 @@ msgstr ""
|
||||
"З міркувань безпеки слід уникати сеансів з наділеними правами. Користуйтесь "
|
||||
"звичайним сеансом."
|
||||
|
||||
#: js/ui/main.js:334
|
||||
#: js/ui/main.js:337
|
||||
msgid "Screen Lock disabled"
|
||||
msgstr "Блокування екрана вимкнено"
|
||||
|
||||
#: js/ui/main.js:335
|
||||
#: js/ui/main.js:338
|
||||
msgid "Screen Locking requires the GNOME display manager."
|
||||
msgstr "Блокування екрана потребує керування входом GNOME."
|
||||
|
||||
@ -1603,7 +1581,7 @@ msgctxt "System menu in the top bar"
|
||||
msgid "System"
|
||||
msgstr "Система"
|
||||
|
||||
#: js/ui/panel.js:825
|
||||
#: js/ui/panel.js:827
|
||||
msgid "Top Bar"
|
||||
msgstr "Верхня панель"
|
||||
|
||||
@ -1780,7 +1758,7 @@ msgstr "Більший текст"
|
||||
msgid "Bluetooth"
|
||||
msgstr "Bluetooth"
|
||||
|
||||
#: js/ui/status/bluetooth.js:49 js/ui/status/network.js:619
|
||||
#: js/ui/status/bluetooth.js:49 js/ui/status/network.js:595
|
||||
msgid "Bluetooth Settings"
|
||||
msgstr "Параметри Bluetooth"
|
||||
|
||||
@ -1864,18 +1842,18 @@ msgstr ""
|
||||
"Доступ до місця перебування можна змінити в будь-яку мить у параметрах "
|
||||
"конфіденційності."
|
||||
|
||||
#: js/ui/status/network.js:71
|
||||
#: js/ui/status/network.js:70
|
||||
msgid "<unknown>"
|
||||
msgstr "<невідомо>"
|
||||
|
||||
#. Translators: %s is a network identifier
|
||||
#: js/ui/status/network.js:449 js/ui/status/network.js:1344
|
||||
#: js/ui/status/network.js:424 js/ui/status/network.js:1320
|
||||
#, javascript-format
|
||||
msgid "%s Off"
|
||||
msgstr "%s вимкнено"
|
||||
|
||||
#. Translators: %s is a network identifier
|
||||
#: js/ui/status/network.js:452
|
||||
#: js/ui/status/network.js:427
|
||||
#, javascript-format
|
||||
msgid "%s Connected"
|
||||
msgstr "%s під'єднано"
|
||||
@ -1883,164 +1861,164 @@ msgstr "%s під'єднано"
|
||||
#. Translators: this is for network devices that are physically present but are not
|
||||
#. under NetworkManager's control (and thus cannot be used in the menu);
|
||||
#. %s is a network identifier
|
||||
#: js/ui/status/network.js:457
|
||||
#: js/ui/status/network.js:432
|
||||
#, javascript-format
|
||||
msgid "%s Unmanaged"
|
||||
msgstr "%s нескеровано"
|
||||
|
||||
#. Translators: %s is a network identifier
|
||||
#: js/ui/status/network.js:460
|
||||
#: js/ui/status/network.js:435
|
||||
#, javascript-format
|
||||
msgid "%s Disconnecting"
|
||||
msgstr "%s від'єднується"
|
||||
|
||||
#. Translators: %s is a network identifier
|
||||
#: js/ui/status/network.js:467 js/ui/status/network.js:1336
|
||||
#: js/ui/status/network.js:442 js/ui/status/network.js:1312
|
||||
#, javascript-format
|
||||
msgid "%s Connecting"
|
||||
msgstr "%s під'єднується"
|
||||
|
||||
#. Translators: this is for network connections that require some kind of key or password; %s is a network identifier
|
||||
#: js/ui/status/network.js:470
|
||||
#: js/ui/status/network.js:445
|
||||
#, javascript-format
|
||||
msgid "%s Requires Authentication"
|
||||
msgstr "%s вимагає засвідчення"
|
||||
|
||||
#. Translators: this is for devices that require some kind of firmware or kernel
|
||||
#. module, which is missing; %s is a network identifier
|
||||
#: js/ui/status/network.js:478
|
||||
#: js/ui/status/network.js:453
|
||||
#, javascript-format
|
||||
msgid "Firmware Missing For %s"
|
||||
msgstr "Бракує мікропрограми для %s"
|
||||
|
||||
#. Translators: this is for a network device that cannot be activated (for example it
|
||||
#. is disabled by rfkill, or it has no coverage; %s is a network identifier
|
||||
#: js/ui/status/network.js:482
|
||||
#: js/ui/status/network.js:457
|
||||
#, javascript-format
|
||||
msgid "%s Unavailable"
|
||||
msgstr "%s недоступний"
|
||||
|
||||
#. Translators: %s is a network identifier
|
||||
#: js/ui/status/network.js:485
|
||||
#: js/ui/status/network.js:460
|
||||
#, javascript-format
|
||||
msgid "%s Connection Failed"
|
||||
msgstr "%s під'єднано невдало"
|
||||
|
||||
#: js/ui/status/network.js:497
|
||||
#: js/ui/status/network.js:472
|
||||
msgid "Wired Settings"
|
||||
msgstr "Параметри мережі"
|
||||
|
||||
#: js/ui/status/network.js:540
|
||||
#: js/ui/status/network.js:515
|
||||
msgid "Mobile Broadband Settings"
|
||||
msgstr "параметри мобільної радіомережі"
|
||||
|
||||
#. Translators: %s is a network identifier
|
||||
#: js/ui/status/network.js:586 js/ui/status/network.js:1341
|
||||
#: js/ui/status/network.js:562 js/ui/status/network.js:1317
|
||||
#, javascript-format
|
||||
msgid "%s Hardware Disabled"
|
||||
msgstr "%s вимкнено апаратно"
|
||||
|
||||
#. Translators: this is for a network device that cannot be activated
|
||||
#. because it's disabled by rfkill (airplane mode); %s is a network identifier
|
||||
#: js/ui/status/network.js:590
|
||||
#: js/ui/status/network.js:566
|
||||
#, javascript-format
|
||||
msgid "%s Disabled"
|
||||
msgstr "%s вимкнено"
|
||||
|
||||
#: js/ui/status/network.js:631
|
||||
#: js/ui/status/network.js:607
|
||||
msgid "Connect to Internet"
|
||||
msgstr "Під'єднатись до інтернету"
|
||||
|
||||
#: js/ui/status/network.js:835
|
||||
#: js/ui/status/network.js:811
|
||||
msgid "Airplane Mode is On"
|
||||
msgstr "Режим «у літаку» ввімкнено"
|
||||
|
||||
#: js/ui/status/network.js:836
|
||||
#: js/ui/status/network.js:812
|
||||
msgid "Wi-Fi is disabled when airplane mode is on."
|
||||
msgstr "Wi-Fi вимкнено, коли режим «у літаку» ввімкнено."
|
||||
|
||||
#: js/ui/status/network.js:837
|
||||
#: js/ui/status/network.js:813
|
||||
msgid "Turn Off Airplane Mode"
|
||||
msgstr "Вимкнути режим «у літаку»"
|
||||
|
||||
#: js/ui/status/network.js:846
|
||||
#: js/ui/status/network.js:822
|
||||
msgid "Wi-Fi is Off"
|
||||
msgstr "Wi-Fi вимкнено"
|
||||
|
||||
#: js/ui/status/network.js:847
|
||||
#: js/ui/status/network.js:823
|
||||
msgid "Wi-Fi needs to be turned on in order to connect to a network."
|
||||
msgstr "Wi-Fi потрібно ввімкнути, щоб з'єднатись з мережею."
|
||||
|
||||
#: js/ui/status/network.js:848
|
||||
#: js/ui/status/network.js:824
|
||||
msgid "Turn On Wi-Fi"
|
||||
msgstr "Увімкнути Wi-Fi"
|
||||
|
||||
#: js/ui/status/network.js:873
|
||||
#: js/ui/status/network.js:849
|
||||
msgid "Wi-Fi Networks"
|
||||
msgstr "Мережі Wi-Fi"
|
||||
|
||||
#: js/ui/status/network.js:875
|
||||
#: js/ui/status/network.js:851
|
||||
msgid "Select a network"
|
||||
msgstr "Вибрати мережу"
|
||||
|
||||
#: js/ui/status/network.js:907
|
||||
#: js/ui/status/network.js:883
|
||||
msgid "No Networks"
|
||||
msgstr "Немає мереж"
|
||||
|
||||
#: js/ui/status/network.js:928 js/ui/status/rfkill.js:108
|
||||
#: js/ui/status/network.js:904 js/ui/status/rfkill.js:106
|
||||
msgid "Use hardware switch to turn off"
|
||||
msgstr "Натисніть апаратну кнопку, щоб вимкнути"
|
||||
|
||||
#: js/ui/status/network.js:1205
|
||||
#: js/ui/status/network.js:1181
|
||||
msgid "Select Network"
|
||||
msgstr "Виберіть мережу"
|
||||
|
||||
#: js/ui/status/network.js:1211
|
||||
#: js/ui/status/network.js:1187
|
||||
msgid "Wi-Fi Settings"
|
||||
msgstr "Параметри Wi-Fi"
|
||||
|
||||
#. Translators: %s is a network identifier
|
||||
#: js/ui/status/network.js:1332
|
||||
#: js/ui/status/network.js:1308
|
||||
#, javascript-format
|
||||
msgid "%s Hotspot Active"
|
||||
msgstr "%s точка доступу"
|
||||
|
||||
#. Translators: %s is a network identifier
|
||||
#: js/ui/status/network.js:1347
|
||||
#: js/ui/status/network.js:1323
|
||||
#, javascript-format
|
||||
msgid "%s Not Connected"
|
||||
msgstr "%s не під'єднано"
|
||||
|
||||
#: js/ui/status/network.js:1444
|
||||
#: js/ui/status/network.js:1420
|
||||
msgid "connecting…"
|
||||
msgstr "З'єднання…"
|
||||
|
||||
#. Translators: this is for network connections that require some kind of key or password
|
||||
#: js/ui/status/network.js:1447
|
||||
#: js/ui/status/network.js:1423
|
||||
msgid "authentication required"
|
||||
msgstr "Потрібна аутентифікація"
|
||||
|
||||
#: js/ui/status/network.js:1449
|
||||
#: js/ui/status/network.js:1425
|
||||
msgid "connection failed"
|
||||
msgstr "не вдалось з'єднатись"
|
||||
|
||||
#: js/ui/status/network.js:1500
|
||||
#: js/ui/status/network.js:1476
|
||||
msgid "VPN Settings"
|
||||
msgstr "Параметри VPN"
|
||||
|
||||
#: js/ui/status/network.js:1517
|
||||
#: js/ui/status/network.js:1493
|
||||
msgid "VPN"
|
||||
msgstr "VPN"
|
||||
|
||||
#: js/ui/status/network.js:1527
|
||||
#: js/ui/status/network.js:1503
|
||||
msgid "VPN Off"
|
||||
msgstr "VPN вимкнено"
|
||||
|
||||
#: js/ui/status/network.js:1588 js/ui/status/rfkill.js:84
|
||||
#: js/ui/status/network.js:1564 js/ui/status/rfkill.js:84
|
||||
msgid "Network Settings"
|
||||
msgstr "Налаштування мережі"
|
||||
|
||||
#: js/ui/status/network.js:1617
|
||||
#: js/ui/status/network.js:1593
|
||||
#, javascript-format
|
||||
msgid "%s Wired Connection"
|
||||
msgid_plural "%s Wired Connections"
|
||||
@ -2049,7 +2027,7 @@ msgstr[1] "%s з'єднання через дріт"
|
||||
msgstr[2] "%s з'єднань через дріт"
|
||||
msgstr[3] "%s з'єднання через дріт"
|
||||
|
||||
#: js/ui/status/network.js:1621
|
||||
#: js/ui/status/network.js:1597
|
||||
#, javascript-format
|
||||
msgid "%s Wi-Fi Connection"
|
||||
msgid_plural "%s Wi-Fi Connections"
|
||||
@ -2058,7 +2036,7 @@ msgstr[1] "%s з'єднання через Wi-Fi"
|
||||
msgstr[2] "%s з'єднань через Wi-Fi"
|
||||
msgstr[3] "%s з'єднання через Wi-Fi"
|
||||
|
||||
#: js/ui/status/network.js:1625
|
||||
#: js/ui/status/network.js:1601
|
||||
#, javascript-format
|
||||
msgid "%s Modem Connection"
|
||||
msgid_plural "%s Modem Connections"
|
||||
@ -2067,11 +2045,11 @@ msgstr[1] "%s з'єднання через модем"
|
||||
msgstr[2] "%s з'єднань через модем"
|
||||
msgstr[3] "%s з'єднання через модем"
|
||||
|
||||
#: js/ui/status/network.js:1759
|
||||
#: js/ui/status/network.js:1735
|
||||
msgid "Connection failed"
|
||||
msgstr "Не вдалось з'єднатись"
|
||||
|
||||
#: js/ui/status/network.js:1760
|
||||
#: js/ui/status/network.js:1736
|
||||
msgid "Activation of network connection failed"
|
||||
msgstr "Не вдалось увімкнути мережеве з'єднання"
|
||||
|
||||
@ -2126,11 +2104,11 @@ msgstr "Зарядиться через %d∶%02d (%d %%)"
|
||||
msgid "%d %%"
|
||||
msgstr "%d %%"
|
||||
|
||||
#: js/ui/status/remoteAccess.js:45
|
||||
#: js/ui/status/remoteAccess.js:43
|
||||
msgid "Screen is Being Shared"
|
||||
msgstr "Екран у спільному доступі"
|
||||
|
||||
#: js/ui/status/remoteAccess.js:47
|
||||
#: js/ui/status/remoteAccess.js:45
|
||||
msgid "Turn off"
|
||||
msgstr "Вимкнути"
|
||||
|
||||
@ -2141,34 +2119,30 @@ msgstr "Вимкнути"
|
||||
msgid "Airplane Mode On"
|
||||
msgstr "Режим «у літаку» ввімкнено"
|
||||
|
||||
#: js/ui/status/system.js:104
|
||||
#: js/ui/status/system.js:102
|
||||
msgid "Lock"
|
||||
msgstr "Заблокувати"
|
||||
|
||||
#: js/ui/status/system.js:116
|
||||
#: js/ui/status/system.js:115
|
||||
msgid "Power Off / Log Out"
|
||||
msgstr "Вимкнути / Вийти"
|
||||
|
||||
#: js/ui/status/system.js:119
|
||||
msgid "Suspend"
|
||||
msgstr "Призупинити"
|
||||
|
||||
#: js/ui/status/system.js:130
|
||||
msgid "Restart…"
|
||||
msgstr "Перезапуск…"
|
||||
|
||||
#: js/ui/status/system.js:141
|
||||
msgid "Power Off…"
|
||||
msgstr "Вимкнути…"
|
||||
|
||||
#: js/ui/status/system.js:154
|
||||
#: js/ui/status/system.js:118
|
||||
msgid "Log Out"
|
||||
msgstr "Вийти"
|
||||
|
||||
#: js/ui/status/system.js:165
|
||||
#: js/ui/status/system.js:130
|
||||
msgid "Switch User…"
|
||||
msgstr "Змінити користувача…"
|
||||
|
||||
#: js/ui/status/system.js:144
|
||||
msgid "Suspend"
|
||||
msgstr "Призупинити"
|
||||
|
||||
#: js/ui/status/system.js:156
|
||||
msgid "Power Off…"
|
||||
msgstr "Вимкнути…"
|
||||
|
||||
#: js/ui/status/thunderbolt.js:263
|
||||
msgid "Thunderbolt"
|
||||
msgstr "Thunderbolt"
|
||||
@ -2275,22 +2249,22 @@ msgid "“%s” is ready"
|
||||
msgstr "«%s» готовий"
|
||||
|
||||
#. Translators: This string should be shorter than 30 characters
|
||||
#: js/ui/windowManager.js:60
|
||||
#: js/ui/windowManager.js:55
|
||||
msgid "Keep these display settings?"
|
||||
msgstr "Зберегти ці параметри екрана?"
|
||||
|
||||
#. Translators: this and the following message should be limited in length,
|
||||
#. to avoid ellipsizing the labels.
|
||||
#.
|
||||
#: js/ui/windowManager.js:69
|
||||
#: js/ui/windowManager.js:64
|
||||
msgid "Revert Settings"
|
||||
msgstr "Повернути параметри"
|
||||
|
||||
#: js/ui/windowManager.js:72
|
||||
#: js/ui/windowManager.js:67
|
||||
msgid "Keep Changes"
|
||||
msgstr "Зберегти зміни"
|
||||
|
||||
#: js/ui/windowManager.js:91
|
||||
#: js/ui/windowManager.js:86
|
||||
#, javascript-format
|
||||
msgid "Settings changes will revert in %d second"
|
||||
msgid_plural "Settings changes will revert in %d seconds"
|
||||
@ -2301,7 +2275,7 @@ msgstr[3] "Зміни параметрів буде повернуто чере
|
||||
|
||||
#. Translators: This represents the size of a window. The first number is
|
||||
#. * the width of the window and the second is the height.
|
||||
#: js/ui/windowManager.js:551
|
||||
#: js/ui/windowManager.js:546
|
||||
#, javascript-format
|
||||
msgid "%d × %d"
|
||||
msgstr "%d × %d"
|
||||
|
@ -51,8 +51,6 @@ def start_shell(perf_output=None):
|
||||
args.append('--nested')
|
||||
else:
|
||||
args.append('--display-server')
|
||||
elif options.x11:
|
||||
args.append('--x11')
|
||||
|
||||
return subprocess.Popen(args, env=env)
|
||||
|
||||
@ -297,8 +295,6 @@ parser.add_option("-w", "--wayland", action="store_true",
|
||||
help="Run as a Wayland compositor")
|
||||
parser.add_option("-n", "--nested", action="store_true",
|
||||
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()
|
||||
|
||||
|
@ -163,6 +163,15 @@ libshell_private_sources = [
|
||||
'shell-app-cache.c',
|
||||
]
|
||||
|
||||
if enable_recorder
|
||||
libshell_sources += ['shell-recorder.c']
|
||||
libshell_public_headers += ['shell-recorder.h']
|
||||
|
||||
libshell_private_sources += ['shell-recorder-src.c']
|
||||
libshell_private_headers += ['shell-recorder-src.h']
|
||||
endif
|
||||
|
||||
|
||||
libshell_enums = gnome.mkenums_simple('shell-enum-types',
|
||||
sources: libshell_public_headers
|
||||
)
|
||||
|
@ -1361,15 +1361,9 @@ shell_global_get_pointer (ShellGlobal *global,
|
||||
{
|
||||
ClutterModifierType raw_mods;
|
||||
MetaCursorTracker *tracker;
|
||||
graphene_point_t point;
|
||||
|
||||
tracker = meta_cursor_tracker_get_for_display (global->meta_display);
|
||||
meta_cursor_tracker_get_pointer (tracker, &point, &raw_mods);
|
||||
|
||||
if (x)
|
||||
*x = point.x;
|
||||
if (y)
|
||||
*y = point.y;
|
||||
meta_cursor_tracker_get_pointer (tracker, x, y, &raw_mods);
|
||||
|
||||
*mods = raw_mods & CLUTTER_MODIFIER_MASK;
|
||||
}
|
||||
|
425
src/shell-recorder-src.c
Normal file
425
src/shell-recorder-src.c
Normal file
@ -0,0 +1,425 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#define GST_USE_UNSTABLE_API
|
||||
#include <gst/base/gstpushsrc.h>
|
||||
|
||||
#include "shell-recorder-src.h"
|
||||
|
||||
struct _ShellRecorderSrc
|
||||
{
|
||||
GstPushSrc parent;
|
||||
|
||||
GMutex mutex;
|
||||
|
||||
GstCaps *caps;
|
||||
GMutex queue_lock;
|
||||
GCond queue_cond;
|
||||
GQueue *queue;
|
||||
|
||||
gboolean eos;
|
||||
gboolean flushing;
|
||||
guint memory_used;
|
||||
guint memory_used_update_idle;
|
||||
};
|
||||
|
||||
struct _ShellRecorderSrcClass
|
||||
{
|
||||
GstPushSrcClass parent_class;
|
||||
};
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_CAPS,
|
||||
PROP_MEMORY_USED
|
||||
};
|
||||
|
||||
#define shell_recorder_src_parent_class parent_class
|
||||
G_DEFINE_TYPE(ShellRecorderSrc, shell_recorder_src, GST_TYPE_PUSH_SRC);
|
||||
|
||||
static void
|
||||
shell_recorder_src_init (ShellRecorderSrc *src)
|
||||
{
|
||||
gst_base_src_set_format (GST_BASE_SRC (src), GST_FORMAT_TIME);
|
||||
gst_base_src_set_live (GST_BASE_SRC (src), TRUE);
|
||||
|
||||
src->queue = g_queue_new ();
|
||||
g_mutex_init (&src->mutex);
|
||||
g_mutex_init (&src->queue_lock);
|
||||
g_cond_init (&src->queue_cond);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
shell_recorder_src_memory_used_update_idle (gpointer data)
|
||||
{
|
||||
ShellRecorderSrc *src = data;
|
||||
|
||||
g_mutex_lock (&src->mutex);
|
||||
src->memory_used_update_idle = 0;
|
||||
g_mutex_unlock (&src->mutex);
|
||||
|
||||
g_object_notify (G_OBJECT (src), "memory-used");
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* The memory_used property is used to monitor buffer usage,
|
||||
* so we marshal notification back to the main loop thread.
|
||||
*/
|
||||
static void
|
||||
shell_recorder_src_update_memory_used (ShellRecorderSrc *src,
|
||||
int delta)
|
||||
{
|
||||
g_mutex_lock (&src->mutex);
|
||||
src->memory_used += delta;
|
||||
if (src->memory_used_update_idle == 0)
|
||||
{
|
||||
src->memory_used_update_idle = g_idle_add (shell_recorder_src_memory_used_update_idle, src);
|
||||
g_source_set_name_by_id (src->memory_used_update_idle, "[gnome-shell] shell_recorder_src_memory_used_update_idle");
|
||||
}
|
||||
g_mutex_unlock (&src->mutex);
|
||||
}
|
||||
|
||||
/* _negotiate() is called when we have to decide on a format. We
|
||||
* use the configured format */
|
||||
static gboolean
|
||||
shell_recorder_src_negotiate (GstBaseSrc * base_src)
|
||||
{
|
||||
ShellRecorderSrc *src = SHELL_RECORDER_SRC (base_src);
|
||||
gboolean result;
|
||||
|
||||
result = gst_base_src_set_caps (base_src, src->caps);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
shell_recorder_src_unlock (GstBaseSrc * base_src)
|
||||
{
|
||||
ShellRecorderSrc *src = SHELL_RECORDER_SRC (base_src);
|
||||
|
||||
g_mutex_lock (&src->queue_lock);
|
||||
src->flushing = TRUE;
|
||||
g_cond_signal (&src->queue_cond);
|
||||
g_mutex_unlock (&src->queue_lock);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
shell_recorder_src_unlock_stop (GstBaseSrc * base_src)
|
||||
{
|
||||
ShellRecorderSrc *src = SHELL_RECORDER_SRC (base_src);
|
||||
|
||||
g_mutex_lock (&src->queue_lock);
|
||||
src->flushing = FALSE;
|
||||
g_cond_signal (&src->queue_cond);
|
||||
g_mutex_unlock (&src->queue_lock);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
shell_recorder_src_start (GstBaseSrc * base_src)
|
||||
{
|
||||
ShellRecorderSrc *src = SHELL_RECORDER_SRC (base_src);
|
||||
|
||||
g_mutex_lock (&src->queue_lock);
|
||||
src->flushing = FALSE;
|
||||
src->eos = FALSE;
|
||||
g_cond_signal (&src->queue_cond);
|
||||
g_mutex_unlock (&src->queue_lock);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
shell_recorder_src_stop (GstBaseSrc * base_src)
|
||||
{
|
||||
ShellRecorderSrc *src = SHELL_RECORDER_SRC (base_src);
|
||||
|
||||
g_mutex_lock (&src->queue_lock);
|
||||
src->flushing = TRUE;
|
||||
src->eos = FALSE;
|
||||
g_queue_foreach (src->queue, (GFunc) gst_buffer_unref, NULL);
|
||||
g_queue_clear (src->queue);
|
||||
g_cond_signal (&src->queue_cond);
|
||||
g_mutex_unlock (&src->queue_lock);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
shell_recorder_src_send_event (GstElement * element, GstEvent * event)
|
||||
{
|
||||
ShellRecorderSrc *src = SHELL_RECORDER_SRC (element);
|
||||
gboolean res;
|
||||
|
||||
if (GST_EVENT_TYPE (event) == GST_EVENT_EOS)
|
||||
{
|
||||
shell_recorder_src_close (src);
|
||||
gst_event_unref (event);
|
||||
res = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
res = GST_CALL_PARENT_WITH_DEFAULT (GST_ELEMENT_CLASS, send_event, (element,
|
||||
event), FALSE);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/* The create() virtual function is responsible for returning the next buffer.
|
||||
* We just pop buffers off of the queue and block if necessary.
|
||||
*/
|
||||
static GstFlowReturn
|
||||
shell_recorder_src_create (GstPushSrc *push_src,
|
||||
GstBuffer **buffer_out)
|
||||
{
|
||||
ShellRecorderSrc *src = SHELL_RECORDER_SRC (push_src);
|
||||
GstBuffer *buffer;
|
||||
|
||||
g_mutex_lock (&src->queue_lock);
|
||||
while (TRUE) {
|
||||
/* int the flushing state we just return FLUSHING */
|
||||
if (src->flushing) {
|
||||
g_mutex_unlock (&src->queue_lock);
|
||||
return GST_FLOW_FLUSHING;
|
||||
}
|
||||
|
||||
buffer = g_queue_pop_head (src->queue);
|
||||
|
||||
/* we have a buffer, exit the loop to handle it */
|
||||
if (buffer != NULL)
|
||||
break;
|
||||
|
||||
/* no buffer, check EOS */
|
||||
if (src->eos) {
|
||||
g_mutex_unlock (&src->queue_lock);
|
||||
return GST_FLOW_EOS;
|
||||
}
|
||||
/* wait for something to happen and try again */
|
||||
g_cond_wait (&src->queue_cond, &src->queue_lock);
|
||||
}
|
||||
g_mutex_unlock (&src->queue_lock);
|
||||
|
||||
shell_recorder_src_update_memory_used (src,
|
||||
- (int)(gst_buffer_get_size(buffer) / 1024));
|
||||
|
||||
*buffer_out = buffer;
|
||||
|
||||
return GST_FLOW_OK;
|
||||
}
|
||||
|
||||
static void
|
||||
shell_recorder_src_set_caps (ShellRecorderSrc *src,
|
||||
const GstCaps *caps)
|
||||
{
|
||||
if (caps == src->caps)
|
||||
return;
|
||||
|
||||
if (src->caps != NULL)
|
||||
{
|
||||
gst_caps_unref (src->caps);
|
||||
src->caps = NULL;
|
||||
}
|
||||
|
||||
if (caps)
|
||||
{
|
||||
/* The capabilities will be negotated with the downstream element
|
||||
* and set on the pad when the first buffer is pushed.
|
||||
*/
|
||||
src->caps = gst_caps_copy (caps);
|
||||
}
|
||||
else
|
||||
src->caps = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
shell_recorder_src_finalize (GObject *object)
|
||||
{
|
||||
ShellRecorderSrc *src = SHELL_RECORDER_SRC (object);
|
||||
|
||||
g_clear_handle_id (&src->memory_used_update_idle, g_source_remove);
|
||||
|
||||
shell_recorder_src_set_caps (src, NULL);
|
||||
g_queue_free_full (src->queue, (GDestroyNotify) gst_buffer_unref);
|
||||
|
||||
g_mutex_clear (&src->mutex);
|
||||
g_mutex_clear (&src->queue_lock);
|
||||
g_cond_clear (&src->queue_cond);
|
||||
|
||||
G_OBJECT_CLASS (shell_recorder_src_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
shell_recorder_src_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
ShellRecorderSrc *src = SHELL_RECORDER_SRC (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_CAPS:
|
||||
shell_recorder_src_set_caps (src, gst_value_get_caps (value));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
shell_recorder_src_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
ShellRecorderSrc *src = SHELL_RECORDER_SRC (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_CAPS:
|
||||
gst_value_set_caps (value, src->caps);
|
||||
break;
|
||||
case PROP_MEMORY_USED:
|
||||
g_mutex_lock (&src->mutex);
|
||||
g_value_set_uint (value, src->memory_used);
|
||||
g_mutex_unlock (&src->mutex);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
shell_recorder_src_class_init (ShellRecorderSrcClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
|
||||
GstBaseSrcClass *base_src_class = GST_BASE_SRC_CLASS (klass);
|
||||
GstPushSrcClass *push_src_class = GST_PUSH_SRC_CLASS (klass);
|
||||
|
||||
static GstStaticPadTemplate src_template =
|
||||
GST_STATIC_PAD_TEMPLATE ("src",
|
||||
GST_PAD_SRC,
|
||||
GST_PAD_ALWAYS,
|
||||
GST_STATIC_CAPS_ANY);
|
||||
|
||||
object_class->finalize = shell_recorder_src_finalize;
|
||||
object_class->set_property = shell_recorder_src_set_property;
|
||||
object_class->get_property = shell_recorder_src_get_property;
|
||||
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_CAPS,
|
||||
g_param_spec_boxed ("caps",
|
||||
"Caps",
|
||||
"Fixed GstCaps for the source",
|
||||
GST_TYPE_CAPS,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_MEMORY_USED,
|
||||
g_param_spec_uint ("memory-used",
|
||||
"Memory Used",
|
||||
"Memory currently used by the queue (in kB)",
|
||||
0, G_MAXUINT, 0,
|
||||
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
gst_static_pad_template_get (&src_template));
|
||||
|
||||
gst_element_class_set_details_simple (element_class,
|
||||
"ShellRecorderSrc",
|
||||
"Generic/Src",
|
||||
"Feed screen capture data to a pipeline",
|
||||
"Owen Taylor <otaylor@redhat.com>");
|
||||
|
||||
element_class->send_event = shell_recorder_src_send_event;
|
||||
|
||||
base_src_class->negotiate = shell_recorder_src_negotiate;
|
||||
base_src_class->unlock = shell_recorder_src_unlock;
|
||||
base_src_class->unlock_stop = shell_recorder_src_unlock_stop;
|
||||
base_src_class->start = shell_recorder_src_start;
|
||||
base_src_class->stop = shell_recorder_src_stop;
|
||||
|
||||
push_src_class->create = shell_recorder_src_create;
|
||||
}
|
||||
|
||||
/**
|
||||
* shell_recorder_src_add_buffer:
|
||||
*
|
||||
* Adds a buffer to the internal queue to be pushed out at the next opportunity.
|
||||
* There is no flow control, so arbitrary amounts of memory may be used by
|
||||
* the buffers on the queue. The buffer contents must match the #GstCaps
|
||||
* set in the :caps property.
|
||||
*/
|
||||
void
|
||||
shell_recorder_src_add_buffer (ShellRecorderSrc *src,
|
||||
GstBuffer *buffer)
|
||||
{
|
||||
g_return_if_fail (SHELL_IS_RECORDER_SRC (src));
|
||||
g_return_if_fail (src->caps != NULL);
|
||||
|
||||
shell_recorder_src_update_memory_used (src,
|
||||
(int)(gst_buffer_get_size(buffer) / 1024));
|
||||
|
||||
g_mutex_lock (&src->queue_lock);
|
||||
g_queue_push_tail (src->queue, gst_buffer_ref (buffer));
|
||||
g_cond_signal (&src->queue_cond);
|
||||
g_mutex_unlock (&src->queue_lock);
|
||||
}
|
||||
|
||||
/**
|
||||
* shell_recorder_src_close:
|
||||
*
|
||||
* Indicates the end of the input stream. Once all previously added buffers have
|
||||
* been pushed out an end-of-stream message will be sent.
|
||||
*/
|
||||
void
|
||||
shell_recorder_src_close (ShellRecorderSrc *src)
|
||||
{
|
||||
/* We can't send a message to the source immediately or buffers that haven't
|
||||
* been pushed yet will be discarded. Instead mark ourselves EOS, which will
|
||||
* make us send an event once everything has been pushed.
|
||||
*/
|
||||
g_mutex_lock (&src->queue_lock);
|
||||
src->eos = TRUE;
|
||||
g_cond_signal (&src->queue_cond);
|
||||
g_mutex_unlock (&src->queue_lock);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
plugin_init (GstPlugin *plugin)
|
||||
{
|
||||
gst_element_register(plugin, "shellrecordersrc", GST_RANK_NONE,
|
||||
SHELL_TYPE_RECORDER_SRC);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* shell_recorder_src_register:
|
||||
*
|
||||
* Registers a plugin holding our single element to use privately in
|
||||
* this application. Can safely be called multiple times.
|
||||
*/
|
||||
void
|
||||
shell_recorder_src_register (void)
|
||||
{
|
||||
static gboolean registered = FALSE;
|
||||
if (registered)
|
||||
return;
|
||||
|
||||
gst_plugin_register_static (GST_VERSION_MAJOR, GST_VERSION_MINOR,
|
||||
"shellrecorder",
|
||||
"Plugin for ShellRecorder",
|
||||
plugin_init,
|
||||
"0.1",
|
||||
"LGPL",
|
||||
"gnome-shell", "gnome-shell", "http://live.gnome.org/GnomeShell");
|
||||
|
||||
registered = TRUE;
|
||||
}
|
40
src/shell-recorder-src.h
Normal file
40
src/shell-recorder-src.h
Normal file
@ -0,0 +1,40 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
#ifndef __SHELL_RECORDER_SRC_H__
|
||||
#define __SHELL_RECORDER_SRC_H__
|
||||
|
||||
#include <gst/gst.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
/**
|
||||
* ShellRecorderSrc:
|
||||
*
|
||||
* shellrecordersrc a custom source element is pretty much like a very
|
||||
* simple version of the stander GStreamer 'appsrc' element, without
|
||||
* any of the provisions for seeking, generating data on demand,
|
||||
* etc. In both cases, the application supplies the buffers and the
|
||||
* element pushes them into the pipeline. The main reason for not using
|
||||
* appsrc is that it wasn't a supported element until gstreamer 0.10.22,
|
||||
* and as of 2009-03, many systems still have 0.10.21.
|
||||
*/
|
||||
typedef struct _ShellRecorderSrc ShellRecorderSrc;
|
||||
typedef struct _ShellRecorderSrcClass ShellRecorderSrcClass;
|
||||
|
||||
#define SHELL_TYPE_RECORDER_SRC (shell_recorder_src_get_type ())
|
||||
#define SHELL_RECORDER_SRC(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), SHELL_TYPE_RECORDER_SRC, ShellRecorderSrc))
|
||||
#define SHELL_RECORDER_SRC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SHELL_TYPE_RECORDER_SRC, ShellRecorderSrcClass))
|
||||
#define SHELL_IS_RECORDER_SRC(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), SHELL_TYPE_RECORDER_SRC))
|
||||
#define SHELL_IS_RECORDER_SRC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SHELL_TYPE_RECORDER_SRC))
|
||||
#define SHELL_RECORDER_SRC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SHELL_TYPE_RECORDER_SRC, ShellRecorderSrcClass))
|
||||
|
||||
GType shell_recorder_src_get_type (void) G_GNUC_CONST;
|
||||
|
||||
void shell_recorder_src_register (void);
|
||||
|
||||
void shell_recorder_src_add_buffer (ShellRecorderSrc *src,
|
||||
GstBuffer *buffer);
|
||||
void shell_recorder_src_close (ShellRecorderSrc *src);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __SHELL_RECORDER_SRC_H__ */
|
1625
src/shell-recorder.c
Normal file
1625
src/shell-recorder.c
Normal file
File diff suppressed because it is too large
Load Diff
45
src/shell-recorder.h
Normal file
45
src/shell-recorder.h
Normal file
@ -0,0 +1,45 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
#ifndef __SHELL_RECORDER_H__
|
||||
#define __SHELL_RECORDER_H__
|
||||
|
||||
#include <clutter/clutter.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
/**
|
||||
* SECTION:shell-recorder
|
||||
* @short_description: Record from a #ClutterStage
|
||||
*
|
||||
* The #ShellRecorder object is used to make recordings ("screencasts")
|
||||
* of a #ClutterStage. Recording is done via #GStreamer. The default is
|
||||
* to encode as a Theora movie and write it to a file in the current
|
||||
* directory named after the date, but the encoding and output can
|
||||
* be configured.
|
||||
*/
|
||||
#define SHELL_TYPE_RECORDER (shell_recorder_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (ShellRecorder, shell_recorder, SHELL, RECORDER, GObject)
|
||||
|
||||
ShellRecorder *shell_recorder_new (ClutterStage *stage);
|
||||
|
||||
void shell_recorder_set_framerate (ShellRecorder *recorder,
|
||||
int framerate);
|
||||
void shell_recorder_set_file_template (ShellRecorder *recorder,
|
||||
const char *file_template);
|
||||
void shell_recorder_set_pipeline (ShellRecorder *recorder,
|
||||
const char *pipeline);
|
||||
void shell_recorder_set_draw_cursor (ShellRecorder *recorder,
|
||||
gboolean draw_cursor);
|
||||
void shell_recorder_set_area (ShellRecorder *recorder,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height);
|
||||
gboolean shell_recorder_record (ShellRecorder *recorder,
|
||||
char **filename_used);
|
||||
void shell_recorder_close (ShellRecorder *recorder);
|
||||
void shell_recorder_pause (ShellRecorder *recorder);
|
||||
gboolean shell_recorder_is_recording (ShellRecorder *recorder);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __SHELL_RECORDER_H__ */
|
@ -12,12 +12,6 @@
|
||||
#include "shell-screenshot.h"
|
||||
#include "shell-util.h"
|
||||
|
||||
typedef enum _ShellScreenshotFlag
|
||||
{
|
||||
SHELL_SCREENSHOT_FLAG_NONE,
|
||||
SHELL_SCREENSHOT_FLAG_INCLUDE_CURSOR,
|
||||
} ShellScreenshotFlag;
|
||||
|
||||
typedef struct _ShellScreenshotPrivate ShellScreenshotPrivate;
|
||||
|
||||
struct _ShellScreenshot
|
||||
@ -38,6 +32,7 @@ struct _ShellScreenshotPrivate
|
||||
cairo_surface_t *image;
|
||||
cairo_rectangle_int_t screenshot_area;
|
||||
|
||||
gboolean include_cursor;
|
||||
gboolean include_frame;
|
||||
};
|
||||
|
||||
@ -50,6 +45,10 @@ typedef enum
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (ShellScreenshot, shell_screenshot, G_TYPE_OBJECT);
|
||||
|
||||
static void
|
||||
grab_screenshot (ClutterActor *stage,
|
||||
GTask *result);
|
||||
|
||||
static void
|
||||
shell_screenshot_class_init (ShellScreenshotClass *screenshot_class)
|
||||
{
|
||||
@ -78,6 +77,8 @@ on_screenshot_written (GObject *source,
|
||||
g_clear_pointer (&priv->image, cairo_surface_destroy);
|
||||
g_clear_object (&priv->stream);
|
||||
g_clear_pointer (&priv->datetime, g_date_time_unref);
|
||||
|
||||
meta_enable_unredirect_for_display (shell_global_get_display (priv->global));
|
||||
}
|
||||
|
||||
static void
|
||||
@ -120,49 +121,63 @@ write_screenshot_thread (GTask *result,
|
||||
}
|
||||
|
||||
static void
|
||||
do_grab_screenshot (ShellScreenshot *screenshot,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height,
|
||||
ShellScreenshotFlag flags)
|
||||
do_grab_screenshot (ShellScreenshot *screenshot,
|
||||
ClutterStage *stage,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
ShellScreenshotPrivate *priv = screenshot->priv;
|
||||
ClutterStage *stage = shell_global_get_stage (priv->global);
|
||||
cairo_rectangle_int_t screenshot_rect = { x, y, width, height };
|
||||
int image_width;
|
||||
int image_height;
|
||||
float scale;
|
||||
cairo_surface_t *image;
|
||||
ClutterPaintFlag paint_flags = CLUTTER_PAINT_FLAG_NONE;
|
||||
g_autoptr (GError) error = NULL;
|
||||
ClutterCapture *captures;
|
||||
int n_captures;
|
||||
int i;
|
||||
|
||||
clutter_stage_get_capture_final_size (stage, &screenshot_rect,
|
||||
&image_width,
|
||||
&image_height,
|
||||
&scale);
|
||||
image = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
|
||||
image_width, image_height);
|
||||
if (!clutter_stage_capture (stage, FALSE,
|
||||
&screenshot_rect,
|
||||
&captures,
|
||||
&n_captures))
|
||||
return;
|
||||
|
||||
if (flags & SHELL_SCREENSHOT_FLAG_INCLUDE_CURSOR)
|
||||
paint_flags |= CLUTTER_PAINT_FLAG_FORCE_CURSORS;
|
||||
if (n_captures == 1)
|
||||
priv->image = cairo_surface_reference (captures[0].image);
|
||||
else
|
||||
paint_flags |= CLUTTER_PAINT_FLAG_NO_CURSORS;
|
||||
if (!clutter_stage_paint_to_buffer (stage, &screenshot_rect, scale,
|
||||
cairo_image_surface_get_data (image),
|
||||
cairo_image_surface_get_stride (image),
|
||||
CLUTTER_CAIRO_FORMAT_ARGB32,
|
||||
paint_flags,
|
||||
&error))
|
||||
{
|
||||
cairo_surface_destroy (image);
|
||||
g_warning ("Failed to take screenshot: %s", error->message);
|
||||
return;
|
||||
float target_scale;
|
||||
|
||||
clutter_stage_get_capture_final_size (stage, &screenshot_rect,
|
||||
&width, &height, &target_scale);
|
||||
priv->image = shell_util_composite_capture_images (captures,
|
||||
n_captures,
|
||||
x, y,
|
||||
width, height,
|
||||
target_scale);
|
||||
}
|
||||
|
||||
priv->image = image;
|
||||
|
||||
priv->datetime = g_date_time_new_now_local ();
|
||||
|
||||
for (i = 0; i < n_captures; i++)
|
||||
cairo_surface_destroy (captures[i].image);
|
||||
|
||||
g_free (captures);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
should_draw_cursor_image (ShellScreenshotMode mode)
|
||||
{
|
||||
if (mode == SHELL_SCREENSHOT_WINDOW || !meta_is_wayland_compositor ())
|
||||
{
|
||||
StSettings *settings = st_settings_get ();
|
||||
gboolean magnifier_active = FALSE;
|
||||
|
||||
g_object_get (settings, "magnifier-active", &magnifier_active, NULL);
|
||||
|
||||
if (!magnifier_active)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -181,7 +196,6 @@ draw_cursor_image (cairo_surface_t *surface,
|
||||
int x, y;
|
||||
int xhot, yhot;
|
||||
double xscale, yscale;
|
||||
graphene_point_t point;
|
||||
|
||||
display = shell_global_get_display (shell_global_get ());
|
||||
tracker = meta_cursor_tracker_get_for_display (display);
|
||||
@ -191,11 +205,9 @@ draw_cursor_image (cairo_surface_t *surface,
|
||||
return;
|
||||
|
||||
screenshot_region = cairo_region_create_rectangle (&area);
|
||||
meta_cursor_tracker_get_pointer (tracker, &point, NULL);
|
||||
x = point.x;
|
||||
y = point.y;
|
||||
meta_cursor_tracker_get_pointer (tracker, &x, &y, NULL);
|
||||
|
||||
if (!cairo_region_contains_point (screenshot_region, point.x, point.y))
|
||||
if (!cairo_region_contains_point (screenshot_region, x, y))
|
||||
{
|
||||
cairo_region_destroy (screenshot_region);
|
||||
return;
|
||||
@ -244,37 +256,116 @@ draw_cursor_image (cairo_surface_t *surface,
|
||||
}
|
||||
|
||||
static void
|
||||
grab_screenshot (ShellScreenshot *screenshot,
|
||||
ShellScreenshotFlag flags,
|
||||
GTask *result)
|
||||
on_paint (ClutterActor *actor,
|
||||
ClutterPaintContext *paint_context,
|
||||
GTask *result)
|
||||
{
|
||||
grab_screenshot (actor, result);
|
||||
}
|
||||
|
||||
static void
|
||||
on_actors_painted (ClutterActor *actor,
|
||||
GTask *result)
|
||||
{
|
||||
grab_screenshot (actor, result);
|
||||
}
|
||||
|
||||
static void
|
||||
grab_screenshot (ClutterActor *stage,
|
||||
GTask *result)
|
||||
{
|
||||
ShellScreenshotPrivate *priv = screenshot->priv;
|
||||
MetaDisplay *display;
|
||||
int width, height;
|
||||
ShellScreenshot *screenshot = g_task_get_source_object (result);
|
||||
ShellScreenshotPrivate *priv = screenshot->priv;
|
||||
GTask *task;
|
||||
|
||||
display = shell_global_get_display (priv->global);
|
||||
meta_display_get_size (display, &width, &height);
|
||||
|
||||
do_grab_screenshot (screenshot,
|
||||
0, 0, width, height,
|
||||
flags);
|
||||
do_grab_screenshot (screenshot, CLUTTER_STAGE (stage), 0, 0, width, height);
|
||||
|
||||
if (meta_display_get_n_monitors (display) > 1)
|
||||
{
|
||||
cairo_region_t *screen_region = cairo_region_create ();
|
||||
cairo_region_t *stage_region;
|
||||
MetaRectangle monitor_rect;
|
||||
cairo_rectangle_int_t stage_rect;
|
||||
int i;
|
||||
cairo_t *cr;
|
||||
|
||||
for (i = meta_display_get_n_monitors (display) - 1; i >= 0; i--)
|
||||
{
|
||||
meta_display_get_monitor_geometry (display, i, &monitor_rect);
|
||||
cairo_region_union_rectangle (screen_region,
|
||||
(const cairo_rectangle_int_t *) &monitor_rect);
|
||||
}
|
||||
|
||||
stage_rect.x = 0;
|
||||
stage_rect.y = 0;
|
||||
stage_rect.width = width;
|
||||
stage_rect.height = height;
|
||||
|
||||
stage_region = cairo_region_create_rectangle ((const cairo_rectangle_int_t *) &stage_rect);
|
||||
cairo_region_xor (stage_region, screen_region);
|
||||
cairo_region_destroy (screen_region);
|
||||
|
||||
cr = cairo_create (priv->image);
|
||||
|
||||
for (i = 0; i < cairo_region_num_rectangles (stage_region); i++)
|
||||
{
|
||||
cairo_rectangle_int_t rect;
|
||||
cairo_region_get_rectangle (stage_region, i, &rect);
|
||||
cairo_rectangle (cr, (double) rect.x, (double) rect.y, (double) rect.width, (double) rect.height);
|
||||
cairo_fill (cr);
|
||||
}
|
||||
|
||||
cairo_destroy (cr);
|
||||
cairo_region_destroy (stage_region);
|
||||
}
|
||||
|
||||
priv->screenshot_area.x = 0;
|
||||
priv->screenshot_area.y = 0;
|
||||
priv->screenshot_area.width = width;
|
||||
priv->screenshot_area.height = height;
|
||||
|
||||
if (priv->include_cursor)
|
||||
draw_cursor_image (priv->image, priv->screenshot_area);
|
||||
|
||||
g_signal_handlers_disconnect_by_func (stage, on_paint, result);
|
||||
g_signal_handlers_disconnect_by_func (stage, on_actors_painted, result);
|
||||
|
||||
task = g_task_new (screenshot, NULL, on_screenshot_written, result);
|
||||
g_task_run_in_thread (task, write_screenshot_thread);
|
||||
g_object_unref (task);
|
||||
}
|
||||
|
||||
static void
|
||||
grab_window_screenshot (ShellScreenshot *screenshot,
|
||||
ShellScreenshotFlag flags,
|
||||
GTask *result)
|
||||
grab_area_screenshot (ClutterActor *stage,
|
||||
GTask *result)
|
||||
{
|
||||
ShellScreenshot *screenshot = g_task_get_source_object (result);
|
||||
ShellScreenshotPrivate *priv = screenshot->priv;
|
||||
GTask *task;
|
||||
|
||||
do_grab_screenshot (screenshot,
|
||||
CLUTTER_STAGE (stage),
|
||||
priv->screenshot_area.x,
|
||||
priv->screenshot_area.y,
|
||||
priv->screenshot_area.width,
|
||||
priv->screenshot_area.height);
|
||||
|
||||
g_signal_handlers_disconnect_by_func (stage, grab_area_screenshot, result);
|
||||
task = g_task_new (screenshot, NULL, on_screenshot_written, result);
|
||||
g_task_run_in_thread (task, write_screenshot_thread);
|
||||
g_object_unref (task);
|
||||
}
|
||||
|
||||
static void
|
||||
grab_window_screenshot (ClutterActor *stage,
|
||||
GTask *result)
|
||||
{
|
||||
ShellScreenshot *screenshot = g_task_get_source_object (result);
|
||||
ShellScreenshotPrivate *priv = screenshot->priv;
|
||||
GTask *task;
|
||||
MetaDisplay *display = shell_global_get_display (priv->global);
|
||||
@ -297,7 +388,7 @@ grab_window_screenshot (ShellScreenshot *screenshot,
|
||||
NULL);
|
||||
priv->datetime = g_date_time_new_now_local ();
|
||||
|
||||
if (flags & SHELL_SCREENSHOT_FLAG_INCLUDE_CURSOR)
|
||||
if (priv->include_cursor)
|
||||
{
|
||||
if (meta_window_get_client_type (window) == META_WINDOW_CLIENT_TYPE_WAYLAND)
|
||||
{
|
||||
@ -310,11 +401,33 @@ grab_window_screenshot (ShellScreenshot *screenshot,
|
||||
draw_cursor_image (priv->image, priv->screenshot_area);
|
||||
}
|
||||
|
||||
g_signal_handlers_disconnect_by_func (stage, grab_window_screenshot, result);
|
||||
task = g_task_new (screenshot, NULL, on_screenshot_written, result);
|
||||
g_task_run_in_thread (task, write_screenshot_thread);
|
||||
g_object_unref (task);
|
||||
}
|
||||
|
||||
static void
|
||||
grab_pixel (ClutterActor *stage,
|
||||
GTask *result)
|
||||
{
|
||||
ShellScreenshot *screenshot = g_task_get_source_object (result);
|
||||
ShellScreenshotPrivate *priv = screenshot->priv;
|
||||
|
||||
do_grab_screenshot (screenshot,
|
||||
CLUTTER_STAGE (stage),
|
||||
priv->screenshot_area.x,
|
||||
priv->screenshot_area.y,
|
||||
1,
|
||||
1);
|
||||
|
||||
meta_enable_unredirect_for_display (shell_global_get_display (priv->global));
|
||||
|
||||
g_signal_handlers_disconnect_by_func (stage, grab_pixel, result);
|
||||
g_task_return_boolean (result, TRUE);
|
||||
g_object_unref (result);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
finish_screenshot (ShellScreenshot *screenshot,
|
||||
GAsyncResult *result,
|
||||
@ -352,9 +465,10 @@ shell_screenshot_screenshot (ShellScreenshot *screenshot,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
ClutterActor *stage;
|
||||
ShellScreenshotPrivate *priv;
|
||||
gboolean use_paint_signal = FALSE;
|
||||
GTask *result;
|
||||
ShellScreenshotFlag flags;
|
||||
|
||||
g_return_if_fail (SHELL_IS_SCREENSHOT (screenshot));
|
||||
g_return_if_fail (G_IS_OUTPUT_STREAM (stream));
|
||||
@ -378,12 +492,34 @@ shell_screenshot_screenshot (ShellScreenshot *screenshot,
|
||||
g_task_set_source_tag (result, shell_screenshot_screenshot);
|
||||
|
||||
priv->stream = g_object_ref (stream);
|
||||
priv->include_cursor = FALSE;
|
||||
|
||||
stage = CLUTTER_ACTOR (shell_global_get_stage (priv->global));
|
||||
|
||||
meta_disable_unredirect_for_display (shell_global_get_display (priv->global));
|
||||
|
||||
flags = SHELL_SCREENSHOT_FLAG_NONE;
|
||||
if (include_cursor)
|
||||
flags |= SHELL_SCREENSHOT_FLAG_INCLUDE_CURSOR;
|
||||
{
|
||||
if (should_draw_cursor_image (SHELL_SCREENSHOT_SCREEN))
|
||||
priv->include_cursor = TRUE;
|
||||
else
|
||||
use_paint_signal = TRUE;
|
||||
}
|
||||
|
||||
grab_screenshot (screenshot, flags, result);
|
||||
if (use_paint_signal)
|
||||
{
|
||||
g_signal_connect_after (stage, "paint",
|
||||
G_CALLBACK (on_paint),
|
||||
result);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_signal_connect_after (stage, "actors-painted",
|
||||
G_CALLBACK (on_actors_painted),
|
||||
result);
|
||||
}
|
||||
|
||||
clutter_actor_queue_redraw (stage);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -439,9 +575,9 @@ shell_screenshot_screenshot_area (ShellScreenshot *screenshot,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
ClutterActor *stage;
|
||||
ShellScreenshotPrivate *priv;
|
||||
GTask *result;
|
||||
g_autoptr (GTask) task = NULL;
|
||||
|
||||
g_return_if_fail (SHELL_IS_SCREENSHOT (screenshot));
|
||||
g_return_if_fail (G_IS_OUTPUT_STREAM (stream));
|
||||
@ -470,15 +606,13 @@ shell_screenshot_screenshot_area (ShellScreenshot *screenshot,
|
||||
priv->screenshot_area.width = width;
|
||||
priv->screenshot_area.height = height;
|
||||
|
||||
do_grab_screenshot (screenshot,
|
||||
priv->screenshot_area.x,
|
||||
priv->screenshot_area.y,
|
||||
priv->screenshot_area.width,
|
||||
priv->screenshot_area.height,
|
||||
SHELL_SCREENSHOT_FLAG_NONE);
|
||||
stage = CLUTTER_ACTOR (shell_global_get_stage (priv->global));
|
||||
|
||||
task = g_task_new (screenshot, NULL, on_screenshot_written, result);
|
||||
g_task_run_in_thread (task, write_screenshot_thread);
|
||||
meta_disable_unredirect_for_display (shell_global_get_display (shell_global_get ()));
|
||||
|
||||
g_signal_connect_after (stage, "actors-painted", G_CALLBACK (grab_area_screenshot), result);
|
||||
|
||||
clutter_actor_queue_redraw (stage);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -532,6 +666,7 @@ shell_screenshot_screenshot_window (ShellScreenshot *screenshot,
|
||||
{
|
||||
ShellScreenshotPrivate *priv;
|
||||
MetaDisplay *display;
|
||||
ClutterActor *stage;
|
||||
MetaWindow *window;
|
||||
GTask *result;
|
||||
|
||||
@ -560,8 +695,16 @@ shell_screenshot_screenshot_window (ShellScreenshot *screenshot,
|
||||
|
||||
priv->stream = g_object_ref (stream);
|
||||
priv->include_frame = include_frame;
|
||||
priv->include_cursor = include_cursor &&
|
||||
should_draw_cursor_image (SHELL_SCREENSHOT_WINDOW);
|
||||
|
||||
grab_window_screenshot (screenshot, include_cursor, result);
|
||||
stage = CLUTTER_ACTOR (shell_global_get_stage (priv->global));
|
||||
|
||||
meta_disable_unredirect_for_display (shell_global_get_display (shell_global_get ()));
|
||||
|
||||
g_signal_connect_after (stage, "actors-painted", G_CALLBACK (grab_window_screenshot), result);
|
||||
|
||||
clutter_actor_queue_redraw (stage);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -610,7 +753,9 @@ shell_screenshot_pick_color (ShellScreenshot *screenshot,
|
||||
gpointer user_data)
|
||||
{
|
||||
ShellScreenshotPrivate *priv;
|
||||
g_autoptr (GTask) result = NULL;
|
||||
MetaDisplay *display;
|
||||
ClutterActor *stage;
|
||||
GTask *result;
|
||||
|
||||
g_return_if_fail (SHELL_IS_SCREENSHOT (screenshot));
|
||||
|
||||
@ -624,14 +769,14 @@ shell_screenshot_pick_color (ShellScreenshot *screenshot,
|
||||
priv->screenshot_area.width = 1;
|
||||
priv->screenshot_area.height = 1;
|
||||
|
||||
do_grab_screenshot (screenshot,
|
||||
priv->screenshot_area.x,
|
||||
priv->screenshot_area.y,
|
||||
1,
|
||||
1,
|
||||
SHELL_SCREENSHOT_FLAG_NONE);
|
||||
display = shell_global_get_display (priv->global);
|
||||
stage = CLUTTER_ACTOR (shell_global_get_stage (priv->global));
|
||||
|
||||
g_task_return_boolean (result, TRUE);
|
||||
meta_disable_unredirect_for_display (display);
|
||||
|
||||
g_signal_connect_after (stage, "actors-painted", G_CALLBACK (grab_pixel), result);
|
||||
|
||||
clutter_actor_queue_redraw (stage);
|
||||
}
|
||||
|
||||
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
|
||||
|
291
src/shell-util.c
291
src/shell-util.c
@ -77,6 +77,61 @@ shell_util_set_hidden_from_pick (ClutterActor *actor,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* shell_util_get_transformed_allocation:
|
||||
* @actor: a #ClutterActor
|
||||
* @box: (out): location to store returned box in stage coordinates
|
||||
*
|
||||
* This function is similar to a combination of clutter_actor_get_transformed_position(),
|
||||
* and clutter_actor_get_transformed_size(), but unlike
|
||||
* clutter_actor_get_transformed_size(), it always returns a transform
|
||||
* of the current allocation, while clutter_actor_get_transformed_size() returns
|
||||
* bad values (the transform of the requested size) if a relayout has been
|
||||
* queued.
|
||||
*
|
||||
* This function is more convenient to use than
|
||||
* clutter_actor_get_abs_allocation_vertices() if no transformation is in effect
|
||||
* and also works around limitations in the GJS binding of arrays.
|
||||
*/
|
||||
void
|
||||
shell_util_get_transformed_allocation (ClutterActor *actor,
|
||||
ClutterActorBox *box)
|
||||
{
|
||||
/* Code adapted from clutter-actor.c:
|
||||
* Copyright 2006, 2007, 2008 OpenedHand Ltd
|
||||
*/
|
||||
graphene_point3d_t v[4];
|
||||
gfloat x_min, x_max, y_min, y_max;
|
||||
guint i;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_ACTOR (actor));
|
||||
|
||||
clutter_actor_get_abs_allocation_vertices (actor, v);
|
||||
|
||||
x_min = x_max = v[0].x;
|
||||
y_min = y_max = v[0].y;
|
||||
|
||||
for (i = 1; i < G_N_ELEMENTS (v); ++i)
|
||||
{
|
||||
if (v[i].x < x_min)
|
||||
x_min = v[i].x;
|
||||
|
||||
if (v[i].x > x_max)
|
||||
x_max = v[i].x;
|
||||
|
||||
if (v[i].y < y_min)
|
||||
y_min = v[i].y;
|
||||
|
||||
if (v[i].y > y_max)
|
||||
y_max = v[i].y;
|
||||
}
|
||||
|
||||
box->x1 = x_min;
|
||||
box->y1 = y_min;
|
||||
box->x2 = x_max;
|
||||
box->y2 = y_max;
|
||||
}
|
||||
|
||||
/**
|
||||
* shell_util_get_week_start:
|
||||
*
|
||||
@ -570,57 +625,6 @@ shell_util_get_uid (void)
|
||||
return getuid ();
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
GDBusConnection *connection;
|
||||
gchar *command;
|
||||
|
||||
GCancellable *cancellable;
|
||||
gulong cancel_id;
|
||||
|
||||
guint job_watch;
|
||||
gchar *job;
|
||||
} SystemdCall;
|
||||
|
||||
static void
|
||||
shell_util_systemd_call_data_free (SystemdCall *data)
|
||||
{
|
||||
if (data->job_watch)
|
||||
{
|
||||
g_dbus_connection_signal_unsubscribe (data->connection, data->job_watch);
|
||||
data->job_watch = 0;
|
||||
}
|
||||
|
||||
if (data->cancellable)
|
||||
{
|
||||
g_cancellable_disconnect (data->cancellable, data->cancel_id);
|
||||
g_clear_object (&data->cancellable);
|
||||
data->cancel_id = 0;
|
||||
}
|
||||
|
||||
g_clear_object (&data->connection);
|
||||
g_clear_pointer (&data->job, g_free);
|
||||
g_clear_pointer (&data->command, g_free);
|
||||
g_free (data);
|
||||
}
|
||||
|
||||
static void
|
||||
shell_util_systemd_call_cancelled_cb (GCancellable *cancellable,
|
||||
GTask *task)
|
||||
{
|
||||
SystemdCall *data = g_task_get_task_data (task);
|
||||
|
||||
/* Task has returned, but data is not yet free'ed, ignore signal. */
|
||||
if (g_task_get_completed (task))
|
||||
return;
|
||||
|
||||
/* We are still in the DBus call; it will return the error. */
|
||||
if (data->job == NULL)
|
||||
return;
|
||||
|
||||
g_task_return_error_if_cancelled (task);
|
||||
g_object_unref (task);
|
||||
}
|
||||
|
||||
static void
|
||||
on_systemd_call_cb (GObject *source,
|
||||
GAsyncResult *res,
|
||||
@ -628,143 +632,46 @@ on_systemd_call_cb (GObject *source,
|
||||
{
|
||||
g_autoptr (GVariant) reply = NULL;
|
||||
g_autoptr (GError) error = NULL;
|
||||
GTask *task = G_TASK (user_data);
|
||||
SystemdCall *data;
|
||||
const gchar *command = user_data;
|
||||
|
||||
reply = g_dbus_connection_call_finish (G_DBUS_CONNECTION (source),
|
||||
res, &error);
|
||||
|
||||
data = g_task_get_task_data (task);
|
||||
|
||||
if (error) {
|
||||
g_warning ("Could not issue '%s' systemd call", data->command);
|
||||
g_task_return_error (task, g_steal_pointer (&error));
|
||||
g_object_unref (task);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
g_assert (data->job == NULL);
|
||||
g_variant_get (reply, "(o)", &data->job);
|
||||
|
||||
/* And we wait for the JobRemoved notification. */
|
||||
if (error)
|
||||
g_warning ("Could not issue '%s' systemd call", command);
|
||||
}
|
||||
|
||||
static void
|
||||
on_systemd_job_removed_cb (GDBusConnection *connection,
|
||||
const gchar *sender_name,
|
||||
const gchar *object_path,
|
||||
const gchar *interface_name,
|
||||
const gchar *signal_name,
|
||||
GVariant *parameters,
|
||||
gpointer user_data)
|
||||
static gboolean
|
||||
shell_util_systemd_call (const char *command,
|
||||
const char *unit,
|
||||
const char *mode,
|
||||
GError **error)
|
||||
{
|
||||
GTask *task = G_TASK (user_data);
|
||||
SystemdCall *data;
|
||||
guint32 id;
|
||||
const char *path, *unit, *result;
|
||||
|
||||
/* Task has returned, but data is not yet free'ed, ignore signal. */
|
||||
if (g_task_get_completed (task))
|
||||
return;
|
||||
|
||||
data = g_task_get_task_data (task);
|
||||
|
||||
/* No job information yet, ignore. */
|
||||
if (data->job == NULL)
|
||||
return;
|
||||
|
||||
g_variant_get (parameters, "(u&o&s&s)", &id, &path, &unit, &result);
|
||||
|
||||
/* Is it the job we are waiting for? */
|
||||
if (g_strcmp0 (path, data->job) != 0)
|
||||
return;
|
||||
|
||||
/* Task has completed; return the result of the job */
|
||||
if (g_strcmp0 (result, "done") == 0)
|
||||
g_task_return_boolean (task, TRUE);
|
||||
else
|
||||
g_task_return_new_error (task,
|
||||
G_IO_ERROR,
|
||||
G_IO_ERROR_FAILED,
|
||||
"Systemd job completed with status \"%s\"",
|
||||
result);
|
||||
|
||||
g_object_unref (task);
|
||||
}
|
||||
|
||||
static void
|
||||
shell_util_systemd_call (const char *command,
|
||||
const char *unit,
|
||||
const char *mode,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
g_autoptr (GTask) task = g_task_new (NULL, cancellable, callback, user_data);
|
||||
|
||||
#ifdef HAVE_SYSTEMD
|
||||
g_autoptr (GDBusConnection) connection = NULL;
|
||||
GError *error = NULL;
|
||||
SystemdCall *data;
|
||||
g_autofree char *self_unit = NULL;
|
||||
int res;
|
||||
|
||||
connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
|
||||
|
||||
if (connection == NULL) {
|
||||
g_task_return_error (task, error);
|
||||
return;
|
||||
}
|
||||
|
||||
/* We look up the systemd unit that our own process is running in here.
|
||||
* This way we determine whether the session is managed using systemd.
|
||||
*/
|
||||
res = sd_pid_get_user_unit (getpid (), &self_unit);
|
||||
|
||||
if (res == -ENODATA)
|
||||
{
|
||||
g_task_return_new_error (task,
|
||||
G_IO_ERROR,
|
||||
G_IO_ERROR_NOT_SUPPORTED,
|
||||
"Not systemd managed");
|
||||
return;
|
||||
g_debug ("Not systemd-managed, not doing '%s' on '%s'", mode, unit);
|
||||
return FALSE;
|
||||
}
|
||||
else if (res < 0)
|
||||
{
|
||||
g_task_return_new_error (task,
|
||||
G_IO_ERROR,
|
||||
g_io_error_from_errno (-res),
|
||||
"Error fetching own systemd unit: %s",
|
||||
g_strerror (-res));
|
||||
return;
|
||||
g_set_error (error,
|
||||
G_IO_ERROR,
|
||||
g_io_error_from_errno (-res),
|
||||
"Error trying to start systemd unit '%s': %s",
|
||||
unit, g_strerror (-res));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
data = g_new0 (SystemdCall, 1);
|
||||
data->command = g_strdup (command);
|
||||
data->connection = g_object_ref (connection);
|
||||
data->job_watch = g_dbus_connection_signal_subscribe (connection,
|
||||
"org.freedesktop.systemd1",
|
||||
"org.freedesktop.systemd1.Manager",
|
||||
"JobRemoved",
|
||||
"/org/freedesktop/systemd1",
|
||||
NULL,
|
||||
G_DBUS_SIGNAL_FLAGS_NONE,
|
||||
on_systemd_job_removed_cb,
|
||||
task,
|
||||
NULL);
|
||||
g_task_set_task_data (task,
|
||||
data,
|
||||
(GDestroyNotify) shell_util_systemd_call_data_free);
|
||||
connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, error);
|
||||
|
||||
if (cancellable)
|
||||
{
|
||||
data->cancellable = g_object_ref (cancellable);
|
||||
data->cancel_id = g_cancellable_connect (cancellable,
|
||||
G_CALLBACK (shell_util_systemd_call_cancelled_cb),
|
||||
task,
|
||||
NULL);
|
||||
}
|
||||
if (connection == NULL)
|
||||
return FALSE;
|
||||
|
||||
g_dbus_connection_call (connection,
|
||||
"org.freedesktop.systemd1",
|
||||
@ -773,53 +680,31 @@ shell_util_systemd_call (const char *command,
|
||||
command,
|
||||
g_variant_new ("(ss)",
|
||||
unit, mode),
|
||||
G_VARIANT_TYPE ("(o)"),
|
||||
NULL,
|
||||
G_DBUS_CALL_FLAGS_NONE,
|
||||
-1, cancellable,
|
||||
-1, NULL,
|
||||
on_systemd_call_cb,
|
||||
g_steal_pointer (&task));
|
||||
#else /* HAVE_SYSTEMD */
|
||||
g_task_return_new_error (task,
|
||||
G_IO_ERROR,
|
||||
G_IO_ERROR_NOT_SUPPORTED,
|
||||
"systemd not supported by gnome-shell");
|
||||
#endif /* !HAVE_SYSTEMD */
|
||||
}
|
||||
(gpointer) command);
|
||||
return TRUE;
|
||||
#endif /* HAVE_SYSTEMD */
|
||||
|
||||
void
|
||||
shell_util_start_systemd_unit (const char *unit,
|
||||
const char *mode,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
shell_util_systemd_call ("StartUnit", unit, mode,
|
||||
cancellable, callback, user_data);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
shell_util_start_systemd_unit_finish (GAsyncResult *res,
|
||||
GError **error)
|
||||
shell_util_start_systemd_unit (const char *unit,
|
||||
const char *mode,
|
||||
GError **error)
|
||||
{
|
||||
return g_task_propagate_boolean (G_TASK (res), error);
|
||||
}
|
||||
|
||||
void
|
||||
shell_util_stop_systemd_unit (const char *unit,
|
||||
const char *mode,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
shell_util_systemd_call ("StopUnit", unit, mode,
|
||||
cancellable, callback, user_data);
|
||||
return shell_util_systemd_call ("StartUnit", unit, mode, error);
|
||||
}
|
||||
|
||||
gboolean
|
||||
shell_util_stop_systemd_unit_finish (GAsyncResult *res,
|
||||
GError **error)
|
||||
shell_util_stop_systemd_unit (const char *unit,
|
||||
const char *mode,
|
||||
GError **error)
|
||||
{
|
||||
return g_task_propagate_boolean (G_TASK (res), error);
|
||||
return shell_util_systemd_call ("StopUnit", unit, mode, error);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -14,6 +14,9 @@ G_BEGIN_DECLS
|
||||
void shell_util_set_hidden_from_pick (ClutterActor *actor,
|
||||
gboolean hidden);
|
||||
|
||||
void shell_util_get_transformed_allocation (ClutterActor *actor,
|
||||
ClutterActorBox *box);
|
||||
|
||||
int shell_util_get_week_start (void);
|
||||
|
||||
const char *shell_util_translate_time_string (const char *str);
|
||||
@ -59,21 +62,12 @@ cairo_surface_t * shell_util_composite_capture_images (ClutterCapture *captures
|
||||
|
||||
void shell_util_check_cloexec_fds (void);
|
||||
|
||||
void shell_util_start_systemd_unit (const char *unit,
|
||||
const char *mode,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data);
|
||||
gboolean shell_util_start_systemd_unit_finish (GAsyncResult *res,
|
||||
GError **error);
|
||||
|
||||
void shell_util_stop_systemd_unit (const char *unit,
|
||||
const char *mode,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data);
|
||||
gboolean shell_util_stop_systemd_unit_finish (GAsyncResult *res,
|
||||
GError **error);
|
||||
gboolean shell_util_start_systemd_unit (const char *unit,
|
||||
const char *mode,
|
||||
GError **error);
|
||||
gboolean shell_util_stop_systemd_unit (const char *unit,
|
||||
const char *mode,
|
||||
GError **error);
|
||||
|
||||
void shell_util_sd_notify (void);
|
||||
|
||||
|
@ -136,8 +136,6 @@ struct _CRParserPriv {
|
||||
|
||||
#define CHARS_TAB_SIZE 12
|
||||
|
||||
#define RECURSIVE_CALLERS_LIMIT 100
|
||||
|
||||
/**
|
||||
* IS_NUM:
|
||||
*@a_char: the char to test.
|
||||
@ -345,11 +343,9 @@ static enum CRStatus cr_parser_parse_selector_core (CRParser * a_this);
|
||||
|
||||
static enum CRStatus cr_parser_parse_declaration_core (CRParser * a_this);
|
||||
|
||||
static enum CRStatus cr_parser_parse_any_core (CRParser * a_this,
|
||||
guint n_calls);
|
||||
static enum CRStatus cr_parser_parse_any_core (CRParser * a_this);
|
||||
|
||||
static enum CRStatus cr_parser_parse_block_core (CRParser * a_this,
|
||||
guint n_calls);
|
||||
static enum CRStatus cr_parser_parse_block_core (CRParser * a_this);
|
||||
|
||||
static enum CRStatus cr_parser_parse_value_core (CRParser * a_this);
|
||||
|
||||
@ -787,7 +783,7 @@ cr_parser_parse_atrule_core (CRParser * a_this)
|
||||
cr_parser_try_to_skip_spaces_and_comments (a_this);
|
||||
|
||||
do {
|
||||
status = cr_parser_parse_any_core (a_this, 0);
|
||||
status = cr_parser_parse_any_core (a_this);
|
||||
} while (status == CR_OK);
|
||||
|
||||
status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr,
|
||||
@ -798,7 +794,7 @@ cr_parser_parse_atrule_core (CRParser * a_this)
|
||||
cr_tknzr_unget_token (PRIVATE (a_this)->tknzr,
|
||||
token);
|
||||
token = NULL;
|
||||
status = cr_parser_parse_block_core (a_this, 0);
|
||||
status = cr_parser_parse_block_core (a_this);
|
||||
CHECK_PARSING_STATUS (status,
|
||||
FALSE);
|
||||
goto done;
|
||||
@ -933,11 +929,11 @@ cr_parser_parse_selector_core (CRParser * a_this)
|
||||
|
||||
RECORD_INITIAL_POS (a_this, &init_pos);
|
||||
|
||||
status = cr_parser_parse_any_core (a_this, 0);
|
||||
status = cr_parser_parse_any_core (a_this);
|
||||
CHECK_PARSING_STATUS (status, FALSE);
|
||||
|
||||
do {
|
||||
status = cr_parser_parse_any_core (a_this, 0);
|
||||
status = cr_parser_parse_any_core (a_this);
|
||||
|
||||
} while (status == CR_OK);
|
||||
|
||||
@ -959,12 +955,10 @@ cr_parser_parse_selector_core (CRParser * a_this)
|
||||
*in chapter 4.1 of the css2 spec.
|
||||
*block ::= '{' S* [ any | block | ATKEYWORD S* | ';' ]* '}' S*;
|
||||
*@param a_this the current instance of #CRParser.
|
||||
*@param n_calls used to limit recursion depth
|
||||
*FIXME: code this function.
|
||||
*/
|
||||
static enum CRStatus
|
||||
cr_parser_parse_block_core (CRParser * a_this,
|
||||
guint n_calls)
|
||||
cr_parser_parse_block_core (CRParser * a_this)
|
||||
{
|
||||
CRToken *token = NULL;
|
||||
CRInputPos init_pos;
|
||||
@ -972,9 +966,6 @@ cr_parser_parse_block_core (CRParser * a_this,
|
||||
|
||||
g_return_val_if_fail (a_this && PRIVATE (a_this), CR_BAD_PARAM_ERROR);
|
||||
|
||||
if (n_calls > RECURSIVE_CALLERS_LIMIT)
|
||||
return CR_ERROR;
|
||||
|
||||
RECORD_INITIAL_POS (a_this, &init_pos);
|
||||
|
||||
status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, &token);
|
||||
@ -1004,13 +995,13 @@ cr_parser_parse_block_core (CRParser * a_this,
|
||||
} else if (token->type == CBO_TK) {
|
||||
cr_tknzr_unget_token (PRIVATE (a_this)->tknzr, token);
|
||||
token = NULL;
|
||||
status = cr_parser_parse_block_core (a_this, n_calls + 1);
|
||||
status = cr_parser_parse_block_core (a_this);
|
||||
CHECK_PARSING_STATUS (status, FALSE);
|
||||
goto parse_block_content;
|
||||
} else {
|
||||
cr_tknzr_unget_token (PRIVATE (a_this)->tknzr, token);
|
||||
token = NULL;
|
||||
status = cr_parser_parse_any_core (a_this, n_calls + 1);
|
||||
status = cr_parser_parse_any_core (a_this);
|
||||
CHECK_PARSING_STATUS (status, FALSE);
|
||||
goto parse_block_content;
|
||||
}
|
||||
@ -1117,7 +1108,7 @@ cr_parser_parse_value_core (CRParser * a_this)
|
||||
status = cr_tknzr_unget_token (PRIVATE (a_this)->tknzr,
|
||||
token);
|
||||
token = NULL;
|
||||
status = cr_parser_parse_block_core (a_this, 0);
|
||||
status = cr_parser_parse_block_core (a_this);
|
||||
CHECK_PARSING_STATUS (status, FALSE);
|
||||
ref++;
|
||||
goto continue_parsing;
|
||||
@ -1131,7 +1122,7 @@ cr_parser_parse_value_core (CRParser * a_this)
|
||||
status = cr_tknzr_unget_token (PRIVATE (a_this)->tknzr,
|
||||
token);
|
||||
token = NULL;
|
||||
status = cr_parser_parse_any_core (a_this, 0);
|
||||
status = cr_parser_parse_any_core (a_this);
|
||||
if (status == CR_OK) {
|
||||
ref++;
|
||||
goto continue_parsing;
|
||||
@ -1170,12 +1161,10 @@ cr_parser_parse_value_core (CRParser * a_this)
|
||||
* | FUNCTION | DASHMATCH | '(' any* ')' | '[' any* ']' ] S*;
|
||||
*
|
||||
*@param a_this the current instance of #CRParser.
|
||||
*@param n_calls used to limit recursion depth
|
||||
*@return CR_OK upon successfull completion, an error code otherwise.
|
||||
*/
|
||||
static enum CRStatus
|
||||
cr_parser_parse_any_core (CRParser * a_this,
|
||||
guint n_calls)
|
||||
cr_parser_parse_any_core (CRParser * a_this)
|
||||
{
|
||||
CRToken *token1 = NULL,
|
||||
*token2 = NULL;
|
||||
@ -1184,9 +1173,6 @@ cr_parser_parse_any_core (CRParser * a_this,
|
||||
|
||||
g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR);
|
||||
|
||||
if (n_calls > RECURSIVE_CALLERS_LIMIT)
|
||||
return CR_ERROR;
|
||||
|
||||
RECORD_INITIAL_POS (a_this, &init_pos);
|
||||
|
||||
status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, &token1);
|
||||
@ -1225,7 +1211,7 @@ cr_parser_parse_any_core (CRParser * a_this,
|
||||
*We consider parameter as being an "any*" production.
|
||||
*/
|
||||
do {
|
||||
status = cr_parser_parse_any_core (a_this, n_calls + 1);
|
||||
status = cr_parser_parse_any_core (a_this);
|
||||
} while (status == CR_OK);
|
||||
|
||||
ENSURE_PARSING_COND (status == CR_PARSING_ERROR);
|
||||
@ -1250,7 +1236,7 @@ cr_parser_parse_any_core (CRParser * a_this,
|
||||
}
|
||||
|
||||
do {
|
||||
status = cr_parser_parse_any_core (a_this, n_calls + 1);
|
||||
status = cr_parser_parse_any_core (a_this);
|
||||
} while (status == CR_OK);
|
||||
|
||||
ENSURE_PARSING_COND (status == CR_PARSING_ERROR);
|
||||
@ -1278,7 +1264,7 @@ cr_parser_parse_any_core (CRParser * a_this,
|
||||
}
|
||||
|
||||
do {
|
||||
status = cr_parser_parse_any_core (a_this, n_calls + 1);
|
||||
status = cr_parser_parse_any_core (a_this);
|
||||
} while (status == CR_OK);
|
||||
|
||||
ENSURE_PARSING_COND (status == CR_PARSING_ERROR);
|
||||
|
@ -279,23 +279,11 @@ st_adjustment_class_init (StAdjustmentClass *klass)
|
||||
object_class->set_property = st_adjustment_set_property;
|
||||
object_class->dispose = st_adjustment_dispose;
|
||||
|
||||
/**
|
||||
* StAdjustment:actor:
|
||||
*
|
||||
* If the adjustment is used as #ClutterAnimatable for a
|
||||
* #ClutterPropertyTransition, this property is used to determine which
|
||||
* monitor should drive the animation.
|
||||
*/
|
||||
props[PROP_ACTOR] =
|
||||
g_param_spec_object ("actor", "Actor", "Actor",
|
||||
CLUTTER_TYPE_ACTOR,
|
||||
ST_PARAM_READWRITE);
|
||||
|
||||
/**
|
||||
* StAdjustment:lower:
|
||||
*
|
||||
* The minimum value of the adjustment.
|
||||
*/
|
||||
props[PROP_LOWER] =
|
||||
g_param_spec_double ("lower", "Lower", "Lower bound",
|
||||
-G_MAXDOUBLE, G_MAXDOUBLE, 0.0,
|
||||
@ -303,14 +291,6 @@ st_adjustment_class_init (StAdjustmentClass *klass)
|
||||
G_PARAM_CONSTRUCT |
|
||||
G_PARAM_EXPLICIT_NOTIFY);
|
||||
|
||||
/**
|
||||
* StAdjustment:upper:
|
||||
*
|
||||
* The maximum value of the adjustment.
|
||||
*
|
||||
* Note that values will be restricted by `upper - page-size` if
|
||||
* #StAdjustment:page-size is non-zero.
|
||||
*/
|
||||
props[PROP_UPPER] =
|
||||
g_param_spec_double ("upper", "Upper", "Upper bound",
|
||||
-G_MAXDOUBLE, G_MAXDOUBLE, 0.0,
|
||||
@ -318,11 +298,6 @@ st_adjustment_class_init (StAdjustmentClass *klass)
|
||||
G_PARAM_CONSTRUCT |
|
||||
G_PARAM_EXPLICIT_NOTIFY);
|
||||
|
||||
/**
|
||||
* StAdjustment:value:
|
||||
*
|
||||
* The value of the adjustment.
|
||||
*/
|
||||
props[PROP_VALUE] =
|
||||
g_param_spec_double ("value", "Value", "Current value",
|
||||
-G_MAXDOUBLE, G_MAXDOUBLE, 0.0,
|
||||
@ -330,11 +305,6 @@ st_adjustment_class_init (StAdjustmentClass *klass)
|
||||
G_PARAM_CONSTRUCT |
|
||||
G_PARAM_EXPLICIT_NOTIFY);
|
||||
|
||||
/**
|
||||
* StAdjustment:step-increment:
|
||||
*
|
||||
* The step increment of the adjustment.
|
||||
*/
|
||||
props[PROP_STEP_INC] =
|
||||
g_param_spec_double ("step-increment", "Step Increment", "Step increment",
|
||||
0.0, G_MAXDOUBLE, 0.0,
|
||||
@ -342,11 +312,6 @@ st_adjustment_class_init (StAdjustmentClass *klass)
|
||||
G_PARAM_CONSTRUCT |
|
||||
G_PARAM_EXPLICIT_NOTIFY);
|
||||
|
||||
/**
|
||||
* StAdjustment:page-increment:
|
||||
*
|
||||
* The page increment of the adjustment.
|
||||
*/
|
||||
props[PROP_PAGE_INC] =
|
||||
g_param_spec_double ("page-increment", "Page Increment", "Page increment",
|
||||
0.0, G_MAXDOUBLE, 0.0,
|
||||
@ -354,14 +319,6 @@ st_adjustment_class_init (StAdjustmentClass *klass)
|
||||
G_PARAM_CONSTRUCT |
|
||||
G_PARAM_EXPLICIT_NOTIFY);
|
||||
|
||||
/**
|
||||
* StAdjustment:page-size:
|
||||
*
|
||||
* The page size of the adjustment.
|
||||
*
|
||||
* Note that the page-size is irrelevant and should be set to zero if the
|
||||
* adjustment is used for a simple scalar value.
|
||||
*/
|
||||
props[PROP_PAGE_SIZE] =
|
||||
g_param_spec_double ("page-size", "Page Size", "Page size",
|
||||
0.0, G_MAXDOUBLE, 0.0,
|
||||
@ -393,20 +350,6 @@ st_adjustment_init (StAdjustment *self)
|
||||
priv->is_constructing = TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* st_adjustment_new:
|
||||
* @actor: (nullable): a #ClutterActor
|
||||
* @value: the initial value
|
||||
* @lower: the minimum value
|
||||
* @upper: the maximum value
|
||||
* @step_increment: the step increment
|
||||
* @page_increment: the page increment
|
||||
* @page_size: the page size
|
||||
*
|
||||
* Creates a new #StAdjustment
|
||||
*
|
||||
* Returns: a new #StAdjustment
|
||||
*/
|
||||
StAdjustment *
|
||||
st_adjustment_new (ClutterActor *actor,
|
||||
gdouble value,
|
||||
@ -427,14 +370,6 @@ st_adjustment_new (ClutterActor *actor,
|
||||
NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* st_adjustment_get_value:
|
||||
* @adjustment: a #StAdjustment
|
||||
*
|
||||
* Gets the current value of the adjustment. See st_adjustment_set_value().
|
||||
*
|
||||
* Returns: The current value of the adjustment
|
||||
*/
|
||||
gdouble
|
||||
st_adjustment_get_value (StAdjustment *adjustment)
|
||||
{
|
||||
@ -443,14 +378,6 @@ st_adjustment_get_value (StAdjustment *adjustment)
|
||||
return ((StAdjustmentPrivate *)st_adjustment_get_instance_private (adjustment))->value;
|
||||
}
|
||||
|
||||
/**
|
||||
* st_adjustment_set_value:
|
||||
* @adjustment: a #StAdjustment
|
||||
* @value: the new value
|
||||
*
|
||||
* Sets the #StAdjustment value. The value is clamped to lie between
|
||||
* #StAdjustment:lower and #StAdjustment:upper - #StAdjustment:page-size.
|
||||
*/
|
||||
void
|
||||
st_adjustment_set_value (StAdjustment *adjustment,
|
||||
gdouble value)
|
||||
@ -477,15 +404,6 @@ st_adjustment_set_value (StAdjustment *adjustment,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* st_adjustment_clamp_page:
|
||||
* @adjustment: a #StAdjustment
|
||||
* @lower: the lower value
|
||||
* @upper: the upper value
|
||||
*
|
||||
* Set #StAdjustment:value to a value clamped between @lower and @upper. The
|
||||
* clamping described by st_adjustment_set_value() still applies.
|
||||
*/
|
||||
void
|
||||
st_adjustment_clamp_page (StAdjustment *adjustment,
|
||||
gdouble lower,
|
||||
@ -519,23 +437,6 @@ st_adjustment_clamp_page (StAdjustment *adjustment,
|
||||
g_object_notify_by_pspec (G_OBJECT (adjustment), props[PROP_VALUE]);
|
||||
}
|
||||
|
||||
/**
|
||||
* st_adjustment_set_lower:
|
||||
* @adjustment: a #StAdjustment
|
||||
* @lower: the new minimum value
|
||||
*
|
||||
* Sets the minimum value of the adjustment.
|
||||
*
|
||||
* When setting multiple adjustment properties via their individual
|
||||
* setters, multiple #GObject::notify and #StAdjustment::changed
|
||||
* signals will be emitted. However, it’s possible to compress the
|
||||
* #GObject::notify signals into one by calling
|
||||
* g_object_freeze_notify() and g_object_thaw_notify() around the
|
||||
* calls to the individual setters.
|
||||
*
|
||||
* Alternatively, using st_adjustment_set_values() will compress both
|
||||
* #GObject::notify and #StAdjustment::changed emissions.
|
||||
*/
|
||||
static gboolean
|
||||
st_adjustment_set_lower (StAdjustment *adjustment,
|
||||
gdouble lower)
|
||||
@ -560,21 +461,6 @@ st_adjustment_set_lower (StAdjustment *adjustment,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* st_adjustment_set_upper:
|
||||
* @adjustment: a #StAdjustment
|
||||
* @upper: the new maximum value
|
||||
*
|
||||
* Sets the maximum value of the adjustment.
|
||||
*
|
||||
* Note that values will be restricted by `upper - page-size`
|
||||
* if the page-size property is nonzero.
|
||||
*
|
||||
* See st_adjustment_set_lower() about how to compress multiple
|
||||
* signal emissions when setting multiple adjustment properties.
|
||||
*
|
||||
* Returns: %TRUE if the value was changed
|
||||
*/
|
||||
static gboolean
|
||||
st_adjustment_set_upper (StAdjustment *adjustment,
|
||||
gdouble upper)
|
||||
@ -599,18 +485,6 @@ st_adjustment_set_upper (StAdjustment *adjustment,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* st_adjustment_set_step_increment:
|
||||
* @adjustment: a #StAdjustment
|
||||
* @step: the new step increment
|
||||
*
|
||||
* Sets the step increment of the adjustment.
|
||||
*
|
||||
* See st_adjustment_set_lower() about how to compress multiple
|
||||
* signal emissions when setting multiple adjustment properties.
|
||||
*
|
||||
* Returns: %TRUE if the value was changed
|
||||
*/
|
||||
static gboolean
|
||||
st_adjustment_set_step_increment (StAdjustment *adjustment,
|
||||
gdouble step)
|
||||
@ -631,18 +505,6 @@ st_adjustment_set_step_increment (StAdjustment *adjustment,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* st_adjustment_set_page_increment:
|
||||
* @adjustment: a #StAdjustment
|
||||
* @page: the new page increment
|
||||
*
|
||||
* Sets the page increment of the adjustment.
|
||||
*
|
||||
* See st_adjustment_set_lower() about how to compress multiple
|
||||
* signal emissions when setting multiple adjustment properties.
|
||||
*
|
||||
* Returns: %TRUE if the value was changed
|
||||
*/
|
||||
static gboolean
|
||||
st_adjustment_set_page_increment (StAdjustment *adjustment,
|
||||
gdouble page)
|
||||
@ -663,18 +525,6 @@ st_adjustment_set_page_increment (StAdjustment *adjustment,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* st_adjustment_set_page_size:
|
||||
* @adjustment: a #StAdjustment
|
||||
* @size: the new page size
|
||||
*
|
||||
* Sets the page size of the adjustment.
|
||||
*
|
||||
* See st_adjustment_set_lower() about how to compress multiple
|
||||
* signal emissions when setting multiple adjustment properties.
|
||||
*
|
||||
* Returns: %TRUE if the value was changed
|
||||
*/
|
||||
static gboolean
|
||||
st_adjustment_set_page_size (StAdjustment *adjustment,
|
||||
gdouble size)
|
||||
@ -699,23 +549,6 @@ st_adjustment_set_page_size (StAdjustment *adjustment,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* st_adjustment_set_values:
|
||||
* @adjustment: a #StAdjustment
|
||||
* @value: the new value
|
||||
* @lower: the new minimum value
|
||||
* @upper: the new maximum value
|
||||
* @step_increment: the new step increment
|
||||
* @page_increment: the new page increment
|
||||
* @page_size: the new page size
|
||||
*
|
||||
* Sets all properties of the adjustment at once.
|
||||
*
|
||||
* Use this function to avoid multiple emissions of the #GObject::notify and
|
||||
* #StAdjustment::changed signals. See st_adjustment_set_lower() for an
|
||||
* alternative way of compressing multiple emissions of #GObject::notify into
|
||||
* one.
|
||||
*/
|
||||
void
|
||||
st_adjustment_set_values (StAdjustment *adjustment,
|
||||
gdouble value,
|
||||
@ -760,12 +593,12 @@ st_adjustment_set_values (StAdjustment *adjustment,
|
||||
/**
|
||||
* st_adjustment_get_values:
|
||||
* @adjustment: an #StAdjustment
|
||||
* @value: (out) (optional): the current value
|
||||
* @lower: (out) (optional): the lower bound
|
||||
* @upper: (out) (optional): the upper bound
|
||||
* @step_increment: (out) (optional): the step increment
|
||||
* @page_increment: (out) (optional): the page increment
|
||||
* @page_size: (out) (optional): the page size
|
||||
* @value: (out): the current value
|
||||
* @lower: (out): the lower bound
|
||||
* @upper: (out): the upper bound
|
||||
* @step_increment: (out): the step increment
|
||||
* @page_increment: (out): the page increment
|
||||
* @page_size: (out): the page size
|
||||
*
|
||||
* Gets all of @adjustment's values at once.
|
||||
*/
|
||||
@ -889,13 +722,7 @@ on_transition_stopped (ClutterTransition *transition,
|
||||
|
||||
/**
|
||||
* st_adjustment_get_transition:
|
||||
* @adjustment: a #StAdjustment
|
||||
* @name: a transition name
|
||||
*
|
||||
* Get the #ClutterTransition for @name previously added with
|
||||
* st_adjustment_add_transition() or %NULL if not found.
|
||||
*
|
||||
* Returns: (transfer none) (nullable): a #ClutterTransition
|
||||
* Returns: (transfer none) (nullable):
|
||||
*/
|
||||
ClutterTransition *
|
||||
st_adjustment_get_transition (StAdjustment *adjustment,
|
||||
@ -918,15 +745,6 @@ st_adjustment_get_transition (StAdjustment *adjustment,
|
||||
return clos->transition;
|
||||
}
|
||||
|
||||
/**
|
||||
* st_adjustment_add_transition:
|
||||
* @adjustment: a #StAdjustment
|
||||
* @name: a unique name for the transition
|
||||
* @transtion: a #ClutterTransition
|
||||
*
|
||||
* Add a #ClutterTransition for the adjustment. If the transiton stops, it will
|
||||
* be automatically removed if #ClutterTransition:remove-on-complete is %TRUE.
|
||||
*/
|
||||
void
|
||||
st_adjustment_add_transition (StAdjustment *adjustment,
|
||||
const char *name,
|
||||
@ -967,14 +785,6 @@ st_adjustment_add_transition (StAdjustment *adjustment,
|
||||
clutter_timeline_start (CLUTTER_TIMELINE (transition));
|
||||
}
|
||||
|
||||
/**
|
||||
* st_adjusmtent_remove_transition:
|
||||
* @adjusment: a #StAdjustment
|
||||
* @name: the name of the transition to remove
|
||||
*
|
||||
* Remove a #ClutterTransition previously added by st_adjustment_add_transtion()
|
||||
* with @name.
|
||||
*/
|
||||
void
|
||||
st_adjustment_remove_transition (StAdjustment *adjustment,
|
||||
const char *name)
|
||||
|
@ -327,7 +327,7 @@ st_bin_init (StBin *bin)
|
||||
*
|
||||
* Creates a new #StBin, a simple container for one child.
|
||||
*
|
||||
* Returns: the newly created #StBin actor
|
||||
* Return value: the newly created #StBin actor
|
||||
*/
|
||||
StWidget *
|
||||
st_bin_new (void)
|
||||
@ -378,9 +378,9 @@ st_bin_set_child (StBin *bin,
|
||||
* st_bin_get_child:
|
||||
* @bin: a #StBin
|
||||
*
|
||||
* Gets the #ClutterActor child for @bin.
|
||||
* Retrieves a pointer to the child of @bin.
|
||||
*
|
||||
* Returns: (transfer none) (nullable): a #ClutterActor, or %NULL
|
||||
* Return value: (transfer none): a #ClutterActor, or %NULL
|
||||
*/
|
||||
ClutterActor *
|
||||
st_bin_get_child (StBin *bin)
|
||||
|
@ -66,19 +66,6 @@ st_border_image_init (StBorderImage *image)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* st_border_image_new:
|
||||
* @file: a #GFile
|
||||
* @border_top: the top border
|
||||
* @border_right: the right border
|
||||
* @border_bottom: the bottom border
|
||||
* @border_left: the left border
|
||||
* @scale_factor: the scale factor
|
||||
*
|
||||
* Creates a new #StBorderImage.
|
||||
*
|
||||
* Returns: a new #StBorderImage.
|
||||
*/
|
||||
StBorderImage *
|
||||
st_border_image_new (GFile *file,
|
||||
int border_top,
|
||||
@ -103,11 +90,9 @@ st_border_image_new (GFile *file,
|
||||
|
||||
/**
|
||||
* st_border_image_get_file:
|
||||
* @image: a #StBorderImage
|
||||
* @image: a #StBorder_Image
|
||||
*
|
||||
* Get the #GFile for @image.
|
||||
*
|
||||
* Returns: (transfer none): a #GFile
|
||||
* Returns: (transfer none): the #GFile for the #StBorder_Image
|
||||
*/
|
||||
GFile *
|
||||
st_border_image_get_file (StBorderImage *image)
|
||||
@ -117,17 +102,6 @@ st_border_image_get_file (StBorderImage *image)
|
||||
return image->file;
|
||||
}
|
||||
|
||||
/**
|
||||
* st_border_image_get_border:
|
||||
* @image: a #StBorderImage
|
||||
* @border_top: (out) (optional): the top border
|
||||
* @border_right: (out) (optional): the right border
|
||||
* @border_bottom: (out) (optional): the bottom border
|
||||
* @border_left: (out) (optional): the left border
|
||||
*
|
||||
* Get the border widths for @image, taking into account the scale factor
|
||||
* provided at construction.
|
||||
*/
|
||||
void
|
||||
st_border_image_get_borders (StBorderImage *image,
|
||||
int *border_top,
|
||||
@ -149,12 +123,12 @@ st_border_image_get_borders (StBorderImage *image,
|
||||
|
||||
/**
|
||||
* st_border_image_equal:
|
||||
* @image: a #StBorderImage
|
||||
* @other: a different #StBorderImage
|
||||
* @image: a #StBorder_Image
|
||||
* @other: a different #StBorder_Image
|
||||
*
|
||||
* Check if two #StBorderImage objects are identical.
|
||||
* Check if two border_image objects are identical.
|
||||
*
|
||||
* Returns: %TRUE if the two border image objects are identical
|
||||
* Return value: %TRUE if the two border image objects are identical
|
||||
*/
|
||||
gboolean
|
||||
st_border_image_equal (StBorderImage *image,
|
||||
|
@ -181,8 +181,8 @@ st_box_layout_class_init (StBoxLayoutClass *klass)
|
||||
/**
|
||||
* StBoxLayout:vertical:
|
||||
*
|
||||
* A convenience property for the #ClutterBoxLayout:vertical property of the
|
||||
* internal layout for #StBoxLayout.
|
||||
* A convenience property for getting the #ClutterBoxLayout:vertical
|
||||
* property of the layout for #StBoxLayout.
|
||||
*/
|
||||
pspec = g_param_spec_boolean ("vertical",
|
||||
"Vertical",
|
||||
@ -195,8 +195,8 @@ st_box_layout_class_init (StBoxLayoutClass *klass)
|
||||
/**
|
||||
* StBoxLayout:pack-start:
|
||||
*
|
||||
* A convenience property for the #ClutterBoxLayout:pack-start property of the
|
||||
* internal layout for #StBoxLayout.
|
||||
* A convenience property for getting the #ClutterBoxLayout:pack-start
|
||||
* property of the layout for #StBoxLayout.
|
||||
*/
|
||||
pspec = g_param_spec_boolean ("pack-start",
|
||||
"Pack Start",
|
||||
|
@ -484,11 +484,6 @@ st_button_class_init (StButtonClass *klass)
|
||||
widget_class->style_changed = st_button_style_changed;
|
||||
widget_class->get_accessible_type = st_button_accessible_get_type;
|
||||
|
||||
/**
|
||||
* StButton:label:
|
||||
*
|
||||
* The label of the #StButton.
|
||||
*/
|
||||
props[PROP_LABEL] =
|
||||
g_param_spec_string ("label",
|
||||
"Label",
|
||||
@ -496,11 +491,6 @@ st_button_class_init (StButtonClass *klass)
|
||||
NULL,
|
||||
ST_PARAM_READWRITE);
|
||||
|
||||
/**
|
||||
* StButton:button-mask:
|
||||
*
|
||||
* Which buttons will trigger the #StButton::clicked signal.
|
||||
*/
|
||||
props[PROP_BUTTON_MASK] =
|
||||
g_param_spec_flags ("button-mask",
|
||||
"Button mask",
|
||||
@ -508,11 +498,6 @@ st_button_class_init (StButtonClass *klass)
|
||||
ST_TYPE_BUTTON_MASK, ST_BUTTON_ONE,
|
||||
ST_PARAM_READWRITE);
|
||||
|
||||
/**
|
||||
* StButton:toggle-mode:
|
||||
*
|
||||
* Whether the #StButton is operating in toggle mode (on/off).
|
||||
*/
|
||||
props[PROP_TOGGLE_MODE] =
|
||||
g_param_spec_boolean ("toggle-mode",
|
||||
"Toggle Mode",
|
||||
@ -520,15 +505,6 @@ st_button_class_init (StButtonClass *klass)
|
||||
FALSE,
|
||||
ST_PARAM_READWRITE);
|
||||
|
||||
/**
|
||||
* StButton:checked:
|
||||
*
|
||||
* If #StButton:toggle-mode is %TRUE, indicates if the #StButton is toggled
|
||||
* "on" or "off".
|
||||
*
|
||||
* When the value is %TRUE, the #StButton will have the `checked` CSS
|
||||
* pseudo-class set.
|
||||
*/
|
||||
props[PROP_CHECKED] =
|
||||
g_param_spec_boolean ("checked",
|
||||
"Checked",
|
||||
@ -536,12 +512,6 @@ st_button_class_init (StButtonClass *klass)
|
||||
FALSE,
|
||||
ST_PARAM_READWRITE);
|
||||
|
||||
/**
|
||||
* StButton:pressed:
|
||||
*
|
||||
* In contrast to #StButton:checked, this property indicates whether the
|
||||
* #StButton is being actively pressed, rather than just in the "on" state.
|
||||
*/
|
||||
props[PROP_PRESSED] =
|
||||
g_param_spec_boolean ("pressed",
|
||||
"Pressed",
|
||||
@ -613,10 +583,9 @@ st_button_new_with_label (const gchar *text)
|
||||
* st_button_get_label:
|
||||
* @button: a #StButton
|
||||
*
|
||||
* Get the text displayed on the button. If the label is empty, an empty string
|
||||
* will be returned instead of %NULL.
|
||||
* Get the text displayed on the button
|
||||
*
|
||||
* Returns: (transfer none): the text for the button
|
||||
* Returns: the text for the button. This must not be freed by the application
|
||||
*/
|
||||
const gchar *
|
||||
st_button_get_label (StButton *button)
|
||||
@ -629,9 +598,9 @@ st_button_get_label (StButton *button)
|
||||
/**
|
||||
* st_button_set_label:
|
||||
* @button: a #Stbutton
|
||||
* @text: (nullable): text to set the label to
|
||||
* @text: text to set the label to
|
||||
*
|
||||
* Sets the text displayed on the button.
|
||||
* Sets the text displayed on the button
|
||||
*/
|
||||
void
|
||||
st_button_set_label (StButton *button,
|
||||
@ -757,7 +726,7 @@ st_button_set_toggle_mode (StButton *button,
|
||||
* st_button_get_checked:
|
||||
* @button: a #StButton
|
||||
*
|
||||
* Get the #StButton:checked property of a #StButton that is in toggle mode.
|
||||
* Get the state of the button that is in toggle mode.
|
||||
*
|
||||
* Returns: %TRUE if the button is checked, or %FALSE if not
|
||||
*/
|
||||
@ -774,8 +743,8 @@ st_button_get_checked (StButton *button)
|
||||
* @button: a #Stbutton
|
||||
* @checked: %TRUE or %FALSE
|
||||
*
|
||||
* Set the #StButton:checked property of the button. This is only really useful
|
||||
* if the button has #StButton:toggle-mode property set to %TRUE.
|
||||
* Sets the pressed state of the button. This is only really useful if the
|
||||
* button has #toggle-mode mode set to %TRUE.
|
||||
*/
|
||||
void
|
||||
st_button_set_checked (StButton *button,
|
||||
@ -804,9 +773,9 @@ st_button_set_checked (StButton *button,
|
||||
* @button: an #StButton
|
||||
*
|
||||
* If this widget is holding a pointer grab, this function will
|
||||
* will ungrab it, and reset the #StButton:pressed state. The effect is
|
||||
* will ungrab it, and reset the pressed state. The effect is
|
||||
* similar to if the user had released the mouse button, but without
|
||||
* emitting the #StButton::clicked signal.
|
||||
* emitting the clicked signal.
|
||||
*
|
||||
* This function is useful if for example you want to do something
|
||||
* after the user is holding the mouse button for a given period of
|
||||
|
@ -63,7 +63,7 @@ void st_button_fake_release (StButton *button);
|
||||
* @ST_BUTTON_TWO: button 2 (middle)
|
||||
* @ST_BUTTON_THREE: button 3 (right)
|
||||
*
|
||||
* A mask representing which mouse buttons an #StButton responds to.
|
||||
* A mask representing which mouse buttons an StButton responds to.
|
||||
*/
|
||||
typedef enum {
|
||||
ST_BUTTON_ONE = (1 << 0),
|
||||
|
@ -195,6 +195,7 @@ st_clipboard_get_mimetypes (StClipboard *clipboard,
|
||||
*
|
||||
* Request the data from the clipboard in text form. @callback is executed
|
||||
* when the data is retreived.
|
||||
*
|
||||
*/
|
||||
void
|
||||
st_clipboard_get_text (StClipboard *clipboard,
|
||||
@ -243,6 +244,7 @@ st_clipboard_get_text (StClipboard *clipboard,
|
||||
*
|
||||
* Request the data from the clipboard in #GBytes form. @callback is executed
|
||||
* when the data is retrieved.
|
||||
*
|
||||
*/
|
||||
void
|
||||
st_clipboard_get_content (StClipboard *clipboard,
|
||||
@ -285,9 +287,7 @@ st_clipboard_get_content (StClipboard *clipboard,
|
||||
* @mimetype: content mimetype
|
||||
* @bytes: content data
|
||||
*
|
||||
* Sets the clipboard content to @bytes.
|
||||
*
|
||||
* @mimetype is a semi-colon separated list of mime-type strings.
|
||||
* Sets the clipboard content.
|
||||
**/
|
||||
void
|
||||
st_clipboard_set_content (StClipboard *clipboard,
|
||||
@ -334,13 +334,6 @@ st_clipboard_set_text (StClipboard *clipboard,
|
||||
g_bytes_unref (bytes);
|
||||
}
|
||||
|
||||
/**
|
||||
* st_clipboard_set_selection: (skip)
|
||||
*
|
||||
* Sets the #MetaSelection of the default #StClipboard.
|
||||
*
|
||||
* This function is called during the initialization of GNOME Shell.
|
||||
*/
|
||||
void
|
||||
st_clipboard_set_selection (MetaSelection *selection)
|
||||
{
|
||||
|
@ -150,8 +150,8 @@ st_drawing_area_init (StDrawingArea *area)
|
||||
* st_drawing_area_queue_repaint:
|
||||
* @area: the #StDrawingArea
|
||||
*
|
||||
* Will cause the actor to emit a #StDrawingArea::repaint signal before it is
|
||||
* next drawn to the scene. Useful if some parameters for the area being
|
||||
* Will cause the actor to emit a ::repaint signal before it is next
|
||||
* drawn to the scene. Useful if some parameters for the area being
|
||||
* drawn other than the size or style have changed. Note that
|
||||
* clutter_actor_queue_redraw() will simply result in the same
|
||||
* contents being drawn to the scene again.
|
||||
@ -169,26 +169,9 @@ st_drawing_area_queue_repaint (StDrawingArea *area)
|
||||
* @area: the #StDrawingArea
|
||||
*
|
||||
* Gets the Cairo context to paint to. This function must only be called
|
||||
* from a signal hander or virtual function for the #StDrawingArea::repaint
|
||||
* signal.
|
||||
* from a signal hander for the ::repaint signal.
|
||||
*
|
||||
* JavaScript code must call the special dispose function before returning from
|
||||
* the signal handler or virtual function to avoid leaking memory:
|
||||
*
|
||||
* |[<!-- language="JavaScript" -->
|
||||
* function onRepaint(area) {
|
||||
* let cr = area.get_context();
|
||||
*
|
||||
* // Draw to the context
|
||||
*
|
||||
* cr.$dispose();
|
||||
* }
|
||||
*
|
||||
* let area = new St.DrawingArea();
|
||||
* area.connect('repaint', onRepaint);
|
||||
* ]|
|
||||
*
|
||||
* Returns: (transfer none): the Cairo context for the paint operation
|
||||
* Return Value: (transfer none): the Cairo context for the paint operation
|
||||
*/
|
||||
cairo_t *
|
||||
st_drawing_area_get_context (StDrawingArea *area)
|
||||
@ -206,12 +189,12 @@ st_drawing_area_get_context (StDrawingArea *area)
|
||||
/**
|
||||
* st_drawing_area_get_surface_size:
|
||||
* @area: the #StDrawingArea
|
||||
* @width: (out) (optional): location to store the width of the painted area
|
||||
* @height: (out) (optional): location to store the height of the painted area
|
||||
* @width: (out): location to store the width of the painted area
|
||||
* @height: (out): location to store the height of the painted area
|
||||
*
|
||||
* Gets the size of the cairo surface being painted to, which is equal
|
||||
* to the size of the content area of the widget. This function must
|
||||
* only be called from a signal hander for the #StDrawingArea::repaint signal.
|
||||
* only be called from a signal hander for the ::repaint signal.
|
||||
*/
|
||||
void
|
||||
st_drawing_area_get_surface_size (StDrawingArea *area,
|
||||
|
@ -29,9 +29,14 @@
|
||||
* applications to set further properties.
|
||||
*
|
||||
* #StEntry supports the following pseudo style states:
|
||||
*
|
||||
* - `focus`: the widget has focus
|
||||
* - `indeterminate`: the widget is showing the hint text or actor
|
||||
* <itemizedlist>
|
||||
* <listitem>
|
||||
* <para>focus: the widget has focus</para>
|
||||
* </listitem>
|
||||
* <listitem>
|
||||
* <para>indeterminate: the widget is showing the hint text or actor</para>
|
||||
* </listitem>
|
||||
* </itemizedlist>
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
@ -892,11 +897,6 @@ st_entry_class_init (StEntryClass *klass)
|
||||
widget_class->navigate_focus = st_entry_navigate_focus;
|
||||
widget_class->get_accessible_type = st_entry_accessible_get_type;
|
||||
|
||||
/**
|
||||
* StEntry:clutter-text:
|
||||
*
|
||||
* The internal #ClutterText actor supporting the #StEntry.
|
||||
*/
|
||||
props[PROP_CLUTTER_TEXT] =
|
||||
g_param_spec_object ("clutter-text",
|
||||
"Clutter Text",
|
||||
@ -904,11 +904,6 @@ st_entry_class_init (StEntryClass *klass)
|
||||
CLUTTER_TYPE_TEXT,
|
||||
ST_PARAM_READABLE);
|
||||
|
||||
/**
|
||||
* StEntry:primary-icon:
|
||||
*
|
||||
* The #ClutterActor acting as the primary icon at the start of the #StEntry.
|
||||
*/
|
||||
props[PROP_PRIMARY_ICON] =
|
||||
g_param_spec_object ("primary-icon",
|
||||
"Primary Icon",
|
||||
@ -916,11 +911,6 @@ st_entry_class_init (StEntryClass *klass)
|
||||
CLUTTER_TYPE_ACTOR,
|
||||
ST_PARAM_READWRITE);
|
||||
|
||||
/**
|
||||
* StEntry:secondary-icon:
|
||||
*
|
||||
* The #ClutterActor acting as the secondary icon at the end of the #StEntry.
|
||||
*/
|
||||
props[PROP_SECONDARY_ICON] =
|
||||
g_param_spec_object ("secondary-icon",
|
||||
"Secondary Icon",
|
||||
@ -928,12 +918,6 @@ st_entry_class_init (StEntryClass *klass)
|
||||
CLUTTER_TYPE_ACTOR,
|
||||
ST_PARAM_READWRITE);
|
||||
|
||||
/**
|
||||
* StEntry:hint-text:
|
||||
*
|
||||
* The text to display when the entry is empty and unfocused. Setting this
|
||||
* will replace the actor of #StEntry::hint-actor.
|
||||
*/
|
||||
props[PROP_HINT_TEXT] =
|
||||
g_param_spec_string ("hint-text",
|
||||
"Hint Text",
|
||||
@ -942,12 +926,6 @@ st_entry_class_init (StEntryClass *klass)
|
||||
NULL,
|
||||
ST_PARAM_READWRITE);
|
||||
|
||||
/**
|
||||
* StEntry:hint-actor:
|
||||
*
|
||||
* A #ClutterActor to display when the entry is empty and unfocused. Setting
|
||||
* this will replace the actor displaying #StEntry:hint-text.
|
||||
*/
|
||||
props[PROP_HINT_ACTOR] =
|
||||
g_param_spec_object ("hint-actor",
|
||||
"Hint Actor",
|
||||
@ -956,11 +934,6 @@ st_entry_class_init (StEntryClass *klass)
|
||||
CLUTTER_TYPE_ACTOR,
|
||||
ST_PARAM_READWRITE);
|
||||
|
||||
/**
|
||||
* StEntry:text:
|
||||
*
|
||||
* The current text value of the #StEntry.
|
||||
*/
|
||||
props[PROP_TEXT] =
|
||||
g_param_spec_string ("text",
|
||||
"Text",
|
||||
@ -968,12 +941,6 @@ st_entry_class_init (StEntryClass *klass)
|
||||
NULL,
|
||||
ST_PARAM_READWRITE);
|
||||
|
||||
/**
|
||||
* StEntry:input-purpose:
|
||||
*
|
||||
* The #ClutterInputContentPurpose that helps on-screen keyboards and similar
|
||||
* input methods to decide which keys should be presented to the user.
|
||||
*/
|
||||
props[PROP_INPUT_PURPOSE] =
|
||||
g_param_spec_enum ("input-purpose",
|
||||
"Purpose",
|
||||
@ -982,13 +949,6 @@ st_entry_class_init (StEntryClass *klass)
|
||||
CLUTTER_INPUT_CONTENT_PURPOSE_NORMAL,
|
||||
ST_PARAM_READWRITE);
|
||||
|
||||
/**
|
||||
* StEntry:input-hints:
|
||||
*
|
||||
* The #ClutterInputContentHintFlags providing additional hints (beyond
|
||||
* #StEntry:input-purpose) that allow input methods to fine-tune their
|
||||
* behaviour.
|
||||
*/
|
||||
props[PROP_INPUT_HINTS] =
|
||||
g_param_spec_flags ("input-hints",
|
||||
"hints",
|
||||
@ -1004,7 +964,8 @@ st_entry_class_init (StEntryClass *klass)
|
||||
* StEntry::primary-icon-clicked:
|
||||
* @self: the #StEntry
|
||||
*
|
||||
* Emitted when the primary icon is clicked.
|
||||
*
|
||||
* Emitted when the primary icon is clicked
|
||||
*/
|
||||
entry_signals[PRIMARY_ICON_CLICKED] =
|
||||
g_signal_new ("primary-icon-clicked",
|
||||
@ -1013,12 +974,11 @@ st_entry_class_init (StEntryClass *klass)
|
||||
G_STRUCT_OFFSET (StEntryClass, primary_icon_clicked),
|
||||
NULL, NULL, NULL,
|
||||
G_TYPE_NONE, 0);
|
||||
|
||||
/**
|
||||
* StEntry::secondary-icon-clicked:
|
||||
* @self: the #StEntry
|
||||
*
|
||||
* Emitted when the secondary icon is clicked.
|
||||
* Emitted when the secondary icon is clicked
|
||||
*/
|
||||
entry_signals[SECONDARY_ICON_CLICKED] =
|
||||
g_signal_new ("secondary-icon-clicked",
|
||||
@ -1080,9 +1040,9 @@ st_entry_init (StEntry *entry)
|
||||
|
||||
/**
|
||||
* st_entry_new:
|
||||
* @text: (nullable): text to set the entry to
|
||||
* @text: text to set the entry to
|
||||
*
|
||||
* Create a new #StEntry with the specified text.
|
||||
* Create a new #StEntry with the specified entry
|
||||
*
|
||||
* Returns: a new #StEntry
|
||||
*/
|
||||
@ -1103,10 +1063,9 @@ st_entry_new (const gchar *text)
|
||||
* st_entry_get_text:
|
||||
* @entry: a #StEntry
|
||||
*
|
||||
* Get the text displayed on the entry. If @entry is empty, an empty string will
|
||||
* be returned instead of %NULL.
|
||||
* Get the text displayed on the entry
|
||||
*
|
||||
* Returns: (transfer none): the text for the entry
|
||||
* Returns: the text for the entry. This must not be freed by the application
|
||||
*/
|
||||
const gchar *
|
||||
st_entry_get_text (StEntry *entry)
|
||||
@ -1125,8 +1084,7 @@ st_entry_get_text (StEntry *entry)
|
||||
* @entry: a #StEntry
|
||||
* @text: (nullable): text to set the entry to
|
||||
*
|
||||
* Sets the text displayed on the entry. If @text is %NULL, the #ClutterText
|
||||
* will instead be set to an empty string.
|
||||
* Sets the text displayed on the entry
|
||||
*/
|
||||
void
|
||||
st_entry_set_text (StEntry *entry,
|
||||
@ -1148,9 +1106,10 @@ st_entry_set_text (StEntry *entry,
|
||||
* st_entry_get_clutter_text:
|
||||
* @entry: a #StEntry
|
||||
*
|
||||
* Retrieve the internal #ClutterText so that extra parameters can be set.
|
||||
* Retrieve the internal #ClutterText so that extra parameters can be set
|
||||
*
|
||||
* Returns: (transfer none): the #ClutterText used by @entry
|
||||
* Returns: (transfer none): the #ClutterText used by #StEntry. The entry is
|
||||
* owned by the #StEntry and should not be unref'ed by the application.
|
||||
*/
|
||||
ClutterActor*
|
||||
st_entry_get_clutter_text (StEntry *entry)
|
||||
@ -1166,8 +1125,8 @@ st_entry_get_clutter_text (StEntry *entry)
|
||||
* @text: (nullable): text to set as the entry hint
|
||||
*
|
||||
* Sets the text to display when the entry is empty and unfocused. When the
|
||||
* entry is displaying the hint, it has a pseudo class of `indeterminate`.
|
||||
* A value of %NULL unsets the hint.
|
||||
* entry is displaying the hint, it has a pseudo class of "indeterminate".
|
||||
* A value of NULL unsets the hint.
|
||||
*/
|
||||
void
|
||||
st_entry_set_hint_text (StEntry *entry,
|
||||
@ -1187,13 +1146,10 @@ st_entry_set_hint_text (StEntry *entry,
|
||||
* st_entry_get_hint_text:
|
||||
* @entry: a #StEntry
|
||||
*
|
||||
* Gets the text that is displayed when the entry is empty and unfocused or
|
||||
* %NULL if the #StEntry:hint-actor was set to an actor that is not a #StLabel.
|
||||
* Gets the text that is displayed when the entry is empty and unfocused
|
||||
*
|
||||
* Unlike st_entry_get_text() this function may return %NULL if
|
||||
* #StEntry:hint-actor is not a #StLabel.
|
||||
*
|
||||
* Returns: (nullable) (transfer none): the current value of the hint property
|
||||
* Returns: the current value of the hint property. This string is owned by the
|
||||
* #StEntry and should not be freed or modified.
|
||||
*/
|
||||
const gchar *
|
||||
st_entry_get_hint_text (StEntry *entry)
|
||||
@ -1244,8 +1200,6 @@ st_entry_set_input_purpose (StEntry *entry,
|
||||
* @entry: a #StEntry
|
||||
*
|
||||
* Gets the value of the #StEntry:input-purpose property.
|
||||
*
|
||||
* Returns: the input purpose of the entry
|
||||
*/
|
||||
ClutterInputContentPurpose
|
||||
st_entry_get_input_purpose (StEntry *entry)
|
||||
@ -1291,8 +1245,6 @@ st_entry_set_input_hints (StEntry *entry,
|
||||
* @entry: a #StEntry
|
||||
*
|
||||
* Gets the value of the #StEntry:input-hints property.
|
||||
*
|
||||
* Returns: the input hints for the entry
|
||||
*/
|
||||
ClutterInputContentHintFlags
|
||||
st_entry_get_input_hints (StEntry *entry)
|
||||
@ -1353,7 +1305,7 @@ _st_entry_set_icon (StEntry *entry,
|
||||
* @entry: a #StEntry
|
||||
* @icon: (nullable): a #ClutterActor
|
||||
*
|
||||
* Set the primary icon of the entry to @icon.
|
||||
* Set the primary icon of the entry to @icon
|
||||
*/
|
||||
void
|
||||
st_entry_set_primary_icon (StEntry *entry,
|
||||
@ -1372,9 +1324,7 @@ st_entry_set_primary_icon (StEntry *entry,
|
||||
* st_entry_get_primary_icon:
|
||||
* @entry: a #StEntry
|
||||
*
|
||||
* Get the value of the #StEntry:primary-icon property.
|
||||
*
|
||||
* Returns: (nullable) (transfer none): a #ClutterActor
|
||||
* Returns: (transfer none): a #ClutterActor
|
||||
*/
|
||||
ClutterActor *
|
||||
st_entry_get_primary_icon (StEntry *entry)
|
||||
@ -1392,7 +1342,7 @@ st_entry_get_primary_icon (StEntry *entry)
|
||||
* @entry: a #StEntry
|
||||
* @icon: (nullable): an #ClutterActor
|
||||
*
|
||||
* Set the secondary icon of the entry to @icon.
|
||||
* Set the secondary icon of the entry to @icon
|
||||
*/
|
||||
void
|
||||
st_entry_set_secondary_icon (StEntry *entry,
|
||||
@ -1411,9 +1361,7 @@ st_entry_set_secondary_icon (StEntry *entry,
|
||||
* st_entry_get_secondary_icon:
|
||||
* @entry: a #StEntry
|
||||
*
|
||||
* Get the value of the #StEntry:secondary-icon property.
|
||||
*
|
||||
* Returns: (nullable) (transfer none): a #ClutterActor
|
||||
* Returns: (transfer none): a #ClutterActor
|
||||
*/
|
||||
ClutterActor *
|
||||
st_entry_get_secondary_icon (StEntry *entry)
|
||||
@ -1429,9 +1377,9 @@ st_entry_get_secondary_icon (StEntry *entry)
|
||||
/**
|
||||
* st_entry_set_hint_actor:
|
||||
* @entry: a #StEntry
|
||||
* @hint_actor: (nullable): a #ClutterActor
|
||||
* @hint_actor: (allow-none): a #ClutterActor
|
||||
*
|
||||
* Set the hint actor of the entry to @hint_actor.
|
||||
* Set the hint actor of the entry to @hint_actor
|
||||
*/
|
||||
void
|
||||
st_entry_set_hint_actor (StEntry *entry,
|
||||
@ -1464,9 +1412,7 @@ st_entry_set_hint_actor (StEntry *entry,
|
||||
* st_entry_get_hint_actor:
|
||||
* @entry: a #StEntry
|
||||
*
|
||||
* Get the value of the #StEntry:hint-actor property.
|
||||
*
|
||||
* Returns: (nullable) (transfer none): a #ClutterActor
|
||||
* Returns: (transfer none): a #ClutterActor
|
||||
*/
|
||||
ClutterActor *
|
||||
st_entry_get_hint_actor (StEntry *entry)
|
||||
|
@ -133,7 +133,7 @@ st_focus_manager_stage_event (ClutterActor *stage,
|
||||
*
|
||||
* Gets the #StFocusManager for @stage, creating it if necessary.
|
||||
*
|
||||
* Returns: (transfer none): the focus manager for @stage
|
||||
* Return value: (transfer none): the focus manager for @stage
|
||||
*/
|
||||
StFocusManager *
|
||||
st_focus_manager_get_for_stage (ClutterStage *stage)
|
||||
@ -215,7 +215,7 @@ st_focus_manager_remove_group (StFocusManager *manager,
|
||||
* Checks if @widget is inside a focus group, and if so, returns
|
||||
* the root of that group.
|
||||
*
|
||||
* Returns: (transfer none): the focus group root, or %NULL if
|
||||
* Return value: (transfer none): the focus group root, or %NULL if
|
||||
* @widget is not in a focus group
|
||||
*/
|
||||
StWidget *
|
||||
|
@ -72,7 +72,7 @@ st_generic_accessible_class_init (StGenericAccessibleClass *klass)
|
||||
* @self. Right now we only care about doubles, so the value is
|
||||
* directly returned by the signal.
|
||||
*
|
||||
* Returns: value of the current element.
|
||||
* Return value: value of the current element.
|
||||
*/
|
||||
st_generic_accessible_signals[GET_CURRENT_VALUE] =
|
||||
g_signal_new ("get-current-value",
|
||||
@ -90,7 +90,7 @@ st_generic_accessible_class_init (StGenericAccessibleClass *klass)
|
||||
* @self. Right now we only care about doubles, so the value is
|
||||
* directly returned by the signal.
|
||||
*
|
||||
* Returns: maximum value of the accessible.
|
||||
* Return value: maximum value of the accessible.
|
||||
*/
|
||||
st_generic_accessible_signals[GET_MAXIMUM_VALUE] =
|
||||
g_signal_new ("get-maximum-value",
|
||||
@ -108,7 +108,7 @@ st_generic_accessible_class_init (StGenericAccessibleClass *klass)
|
||||
* @self. Right now we only care about doubles, so the value is
|
||||
* directly returned by the signal.
|
||||
*
|
||||
* Returns: minimum value of the accessible.
|
||||
* Return value: minimum value of the accessible.
|
||||
*/
|
||||
st_generic_accessible_signals[GET_MINIMUM_VALUE] =
|
||||
g_signal_new ("get-minimum-value",
|
||||
@ -126,7 +126,7 @@ st_generic_accessible_class_init (StGenericAccessibleClass *klass)
|
||||
* @self. Right now we only care about doubles, so the value is
|
||||
* directly returned by the signal.
|
||||
*
|
||||
* Returns: value of the current element.
|
||||
* Return value: value of the current element.
|
||||
*/
|
||||
st_generic_accessible_signals[GET_MINIMUM_INCREMENT] =
|
||||
g_signal_new ("get-minimum-increment",
|
||||
@ -221,16 +221,6 @@ atk_value_iface_init (AtkValueIface *iface)
|
||||
iface->set_current_value = st_generic_accessible_set_current_value;
|
||||
}
|
||||
|
||||
/**
|
||||
* st_generic_accessible_new_for_actor:
|
||||
* @actor: a #Clutter Actor
|
||||
*
|
||||
* Create a new #StGenericAccessible for @actor.
|
||||
*
|
||||
* This is useful only for custom widgets that need a proxy for #AtkObject.
|
||||
*
|
||||
* Returns: (transfer full): a new #AtkObject
|
||||
*/
|
||||
AtkObject*
|
||||
st_generic_accessible_new_for_actor (ClutterActor *actor)
|
||||
{
|
||||
|
@ -26,7 +26,7 @@
|
||||
*
|
||||
* Creates a new #StIconColors. All colors are initialized to transparent black.
|
||||
*
|
||||
* Returns: a newly created #StIconColors. Free with st_icon_colors_unref()
|
||||
* Return value: a newly created #StIconColors. Free with st_icon_colors_unref()
|
||||
*/
|
||||
StIconColors *
|
||||
st_icon_colors_new (void)
|
||||
@ -107,8 +107,6 @@ st_icon_colors_copy (StIconColors *colors)
|
||||
* @colors: a #StIconColors
|
||||
* @other: another #StIconColors
|
||||
*
|
||||
* Check if two #StIconColors objects are identical.
|
||||
*
|
||||
* Returns: %TRUE if the #StIconColors are equal
|
||||
*/
|
||||
gboolean
|
||||
|
@ -255,11 +255,6 @@ st_icon_class_init (StIconClass *klass)
|
||||
widget_class->style_changed = st_icon_style_changed;
|
||||
actor_class->resource_scale_changed = st_icon_resource_scale_changed;
|
||||
|
||||
/**
|
||||
* StIcon:gicon:
|
||||
*
|
||||
* The #GIcon being displayed by this #StIcon.
|
||||
*/
|
||||
props[PROP_GICON] =
|
||||
g_param_spec_object ("gicon",
|
||||
"GIcon",
|
||||
@ -267,11 +262,6 @@ st_icon_class_init (StIconClass *klass)
|
||||
G_TYPE_ICON,
|
||||
ST_PARAM_READWRITE);
|
||||
|
||||
/**
|
||||
* StIcon:fallback-gicon:
|
||||
*
|
||||
* The fallback #GIcon to display if #StIcon:gicon fails to load.
|
||||
*/
|
||||
props[PROP_FALLBACK_GICON] =
|
||||
g_param_spec_object ("fallback-gicon",
|
||||
"Fallback GIcon",
|
||||
@ -279,11 +269,6 @@ st_icon_class_init (StIconClass *klass)
|
||||
G_TYPE_ICON,
|
||||
ST_PARAM_READWRITE);
|
||||
|
||||
/**
|
||||
* StIcon:icon-name:
|
||||
*
|
||||
* The name of the icon if the icon being displayed is a #GThemedIcon.
|
||||
*/
|
||||
props[PROP_ICON_NAME] =
|
||||
g_param_spec_string ("icon-name",
|
||||
"Icon name",
|
||||
@ -291,12 +276,6 @@ st_icon_class_init (StIconClass *klass)
|
||||
NULL,
|
||||
ST_PARAM_READWRITE);
|
||||
|
||||
/**
|
||||
* StIcon:icon-size:
|
||||
*
|
||||
* The size of the icon, if greater than `0`. Other the icon sise is derived
|
||||
* from the current style.
|
||||
*/
|
||||
props[PROP_ICON_SIZE] =
|
||||
g_param_spec_int ("icon-size",
|
||||
"Icon size",
|
||||
@ -304,12 +283,6 @@ st_icon_class_init (StIconClass *klass)
|
||||
-1, G_MAXINT, -1,
|
||||
ST_PARAM_READWRITE);
|
||||
|
||||
/**
|
||||
* StIcon:fallback-icon-name:
|
||||
*
|
||||
* The fallback icon name of the #StIcon. See st_icon_set_fallback_icon_name()
|
||||
* for details.
|
||||
*/
|
||||
props[PROP_FALLBACK_ICON_NAME] =
|
||||
g_param_spec_string ("fallback-icon-name",
|
||||
"Fallback icon name",
|
||||
@ -551,7 +524,7 @@ st_icon_update_icon_size (StIcon *icon)
|
||||
/**
|
||||
* st_icon_new:
|
||||
*
|
||||
* Create a newly allocated #StIcon.
|
||||
* Create a newly allocated #StIcon
|
||||
*
|
||||
* Returns: A newly allocated #StIcon
|
||||
*/
|
||||
@ -565,10 +538,10 @@ st_icon_new (void)
|
||||
* st_icon_get_icon_name:
|
||||
* @icon: an #StIcon
|
||||
*
|
||||
* This is a convenience method to get the icon name of the current icon, if it
|
||||
* is currenyly a #GThemedIcon, or %NULL otherwise.
|
||||
* This is a convenience method to get the icon name of the #GThemedIcon that
|
||||
* is currently set.
|
||||
*
|
||||
* Returns: (transfer none) (nullable): The name of the icon or %NULL
|
||||
* Returns: (transfer none): The name of the icon or %NULL if no icon is set
|
||||
*/
|
||||
const gchar *
|
||||
st_icon_get_icon_name (StIcon *icon)
|
||||
@ -619,7 +592,7 @@ st_icon_set_icon_name (StIcon *icon,
|
||||
*
|
||||
* Gets the current #GIcon in use.
|
||||
*
|
||||
* Returns: (nullable) (transfer none): The current #GIcon, if set, otherwise %NULL
|
||||
* Returns: (transfer none): The current #GIcon, if set, otherwise %NULL
|
||||
*/
|
||||
GIcon *
|
||||
st_icon_get_gicon (StIcon *icon)
|
||||
|
@ -329,10 +329,7 @@ g_loadable_icon_interface_init (GLoadableIconIface *iface)
|
||||
*
|
||||
* Creates a new #StImageContent, a simple content for sized images.
|
||||
*
|
||||
* See #ClutterImage for setting the actual image to display or #StIcon for
|
||||
* displaying icons.
|
||||
*
|
||||
* Returns: (transfer full): the newly created #StImageContent content
|
||||
* Return value: (transfer full): the newly created #StImageContent content
|
||||
* Use g_object_unref() when done.
|
||||
*/
|
||||
ClutterContent *
|
||||
|
@ -274,11 +274,6 @@ st_label_class_init (StLabelClass *klass)
|
||||
widget_class->style_changed = st_label_style_changed;
|
||||
widget_class->get_accessible_type = st_label_accessible_get_type;
|
||||
|
||||
/**
|
||||
* StLabel:clutter-text:
|
||||
*
|
||||
* The internal #ClutterText actor supporting the label
|
||||
*/
|
||||
props[PROP_CLUTTER_TEXT] =
|
||||
g_param_spec_object ("clutter-text",
|
||||
"Clutter Text",
|
||||
@ -286,11 +281,6 @@ st_label_class_init (StLabelClass *klass)
|
||||
CLUTTER_TYPE_TEXT,
|
||||
ST_PARAM_READABLE);
|
||||
|
||||
/**
|
||||
* StLabel:text:
|
||||
*
|
||||
* The current text being display in the #StLabel.
|
||||
*/
|
||||
props[PROP_TEXT] =
|
||||
g_param_spec_string ("text",
|
||||
"Text",
|
||||
@ -324,9 +314,9 @@ st_label_init (StLabel *label)
|
||||
|
||||
/**
|
||||
* st_label_new:
|
||||
* @text: (nullable): text to set the label to
|
||||
* @text: text to set the label to
|
||||
*
|
||||
* Create a new #StLabel with the label specified by @text.
|
||||
* Create a new #StLabel with the specified label
|
||||
*
|
||||
* Returns: a new #StLabel
|
||||
*/
|
||||
@ -345,10 +335,9 @@ st_label_new (const gchar *text)
|
||||
* st_label_get_text:
|
||||
* @label: a #StLabel
|
||||
*
|
||||
* Get the text displayed on the label.
|
||||
* Get the text displayed on the label
|
||||
*
|
||||
* Returns: (transfer none): the text for the label. This must not be freed by
|
||||
* the application
|
||||
* Returns: the text for the label. This must not be freed by the application
|
||||
*/
|
||||
const gchar *
|
||||
st_label_get_text (StLabel *label)
|
||||
@ -361,9 +350,9 @@ st_label_get_text (StLabel *label)
|
||||
/**
|
||||
* st_label_set_text:
|
||||
* @label: a #StLabel
|
||||
* @text: (nullable): text to set the label to
|
||||
* @text: text to set the label to
|
||||
*
|
||||
* Sets the text displayed by the label.
|
||||
* Sets the text displayed on the label
|
||||
*/
|
||||
void
|
||||
st_label_set_text (StLabel *label,
|
||||
@ -393,11 +382,10 @@ st_label_set_text (StLabel *label,
|
||||
* st_label_get_clutter_text:
|
||||
* @label: a #StLabel
|
||||
*
|
||||
* Retrieve the internal #ClutterText used by @label so that extra parameters
|
||||
* can be set.
|
||||
* Retrieve the internal #ClutterText so that extra parameters can be set
|
||||
*
|
||||
* Returns: (transfer none): the #ClutterText used by #StLabel. The actor
|
||||
* is owned by the #StLabel and should not be destroyed by the application.
|
||||
* Returns: (transfer none): ethe #ClutterText used by #StLabel. The label
|
||||
* is owned by the #StLabel and should not be unref'ed by the application.
|
||||
*/
|
||||
ClutterActor*
|
||||
st_label_get_clutter_text (StLabel *label)
|
||||
|
@ -133,23 +133,12 @@ st_password_entry_class_init (StPasswordEntryClass *klass)
|
||||
|
||||
st_entry_class->secondary_icon_clicked = st_password_entry_secondary_icon_clicked;
|
||||
|
||||
/**
|
||||
* StPasswordEntry:password-visible:
|
||||
*
|
||||
* Whether the text in the entry is masked for privacy.
|
||||
*/
|
||||
props[PROP_PASSWORD_VISIBLE] = g_param_spec_boolean ("password-visible",
|
||||
"Password visible",
|
||||
"Whether the text in the entry is masked or not",
|
||||
"Whether to text in the entry is masked or not",
|
||||
FALSE,
|
||||
ST_PARAM_READWRITE);
|
||||
|
||||
/**
|
||||
* StPasswordEntry:show-peek-icon:
|
||||
*
|
||||
* Whether to display an icon button to toggle the masking enabled by the
|
||||
* #StPasswordEntry:password-visible property.
|
||||
*/
|
||||
props[PROP_SHOW_PEEK_ICON] = g_param_spec_boolean ("show-peek-icon",
|
||||
"Show peek icon",
|
||||
"Whether to show the password peek icon",
|
||||
@ -213,15 +202,12 @@ st_password_entry_new (void)
|
||||
/**
|
||||
* st_password_entry_set_show_peek_icon:
|
||||
* @entry: a #StPasswordEntry
|
||||
* @value: %TRUE to show the peek-icon in the entry
|
||||
* @value: #TRUE to show the peek-icon in the entry, #FALSE otherwise
|
||||
*
|
||||
* Sets whether to show or hide the peek-icon in the password entry. If %TRUE,
|
||||
* a icon button for temporarily unmasking the password will be shown at the
|
||||
* end of the entry.
|
||||
* Sets whether to show or hide the peek-icon in the password entry.
|
||||
*/
|
||||
void
|
||||
st_password_entry_set_show_peek_icon (StPasswordEntry *entry,
|
||||
gboolean value)
|
||||
st_password_entry_set_show_peek_icon (StPasswordEntry *entry, gboolean value)
|
||||
{
|
||||
StPasswordEntryPrivate *priv;
|
||||
|
||||
@ -245,8 +231,6 @@ st_password_entry_set_show_peek_icon (StPasswordEntry *entry,
|
||||
* @entry: a #StPasswordEntry
|
||||
*
|
||||
* Gets whether peek-icon is shown or hidden in the password entry.
|
||||
*
|
||||
* Returns: %TRUE if visible
|
||||
*/
|
||||
gboolean
|
||||
st_password_entry_get_show_peek_icon (StPasswordEntry *entry)
|
||||
@ -262,13 +246,12 @@ st_password_entry_get_show_peek_icon (StPasswordEntry *entry)
|
||||
/**
|
||||
* st_password_entry_set_password_visible:
|
||||
* @entry: a #StPasswordEntry
|
||||
* @value: %TRUE to show the password in the entry, #FALSE otherwise
|
||||
* @value: #TRUE to show the password in the entry, #FALSE otherwise
|
||||
*
|
||||
* Sets whether to show or hide text in the password entry.
|
||||
*/
|
||||
void
|
||||
st_password_entry_set_password_visible (StPasswordEntry *entry,
|
||||
gboolean value)
|
||||
st_password_entry_set_password_visible (StPasswordEntry *entry, gboolean value)
|
||||
{
|
||||
StPasswordEntryPrivate *priv;
|
||||
ClutterActor *clutter_text;
|
||||
@ -301,8 +284,6 @@ st_password_entry_set_password_visible (StPasswordEntry *entry,
|
||||
* @entry: a #StPasswordEntry
|
||||
*
|
||||
* Gets whether the text is masked in the password entry.
|
||||
*
|
||||
* Returns: %TRUE if visible
|
||||
*/
|
||||
gboolean
|
||||
st_password_entry_get_password_visible (StPasswordEntry *entry)
|
||||
|
@ -508,8 +508,6 @@ _st_create_shadow_pipeline_from_actor (StShadow *shadow_spec,
|
||||
|
||||
cogl_color_init_from_4ub (&clear_color, 0, 0, 0, 0);
|
||||
clutter_actor_get_position (actor, &x, &y);
|
||||
x *= resource_scale;
|
||||
y *= resource_scale;
|
||||
|
||||
cogl_framebuffer_clear (fb, COGL_BUFFER_BIT_COLOR, &clear_color);
|
||||
cogl_framebuffer_translate (fb, -x, -y, 0);
|
||||
|
@ -538,21 +538,11 @@ st_scroll_bar_class_init (StScrollBarClass *klass)
|
||||
|
||||
widget_class->style_changed = st_scroll_bar_style_changed;
|
||||
|
||||
/**
|
||||
* StScrollBar:adjustment:
|
||||
*
|
||||
* The #StAdjustment controlling the #StScrollBar.
|
||||
*/
|
||||
props[PROP_ADJUSTMENT] =
|
||||
g_param_spec_object ("adjustment", "Adjustment", "The adjustment",
|
||||
ST_TYPE_ADJUSTMENT,
|
||||
ST_PARAM_READWRITE);
|
||||
|
||||
/**
|
||||
* StScrollBar:vertical:
|
||||
*
|
||||
* Whether the #StScrollBar is vertical. If %FALSE it is horizontal.
|
||||
*/
|
||||
props[PROP_VERTICAL] =
|
||||
g_param_spec_boolean ("vertical",
|
||||
"Vertical Orientation",
|
||||
@ -562,13 +552,6 @@ st_scroll_bar_class_init (StScrollBarClass *klass)
|
||||
|
||||
g_object_class_install_properties (object_class, N_PROPS, props);
|
||||
|
||||
|
||||
/**
|
||||
* StScrollBar::scroll-start:
|
||||
* @bar: a #StScrollBar
|
||||
*
|
||||
* Emitted when the #StScrollBar begins scrolling.
|
||||
*/
|
||||
signals[SCROLL_START] =
|
||||
g_signal_new ("scroll-start",
|
||||
G_TYPE_FROM_CLASS (klass),
|
||||
@ -577,12 +560,6 @@ st_scroll_bar_class_init (StScrollBarClass *klass)
|
||||
NULL, NULL, NULL,
|
||||
G_TYPE_NONE, 0);
|
||||
|
||||
/**
|
||||
* StScrollBar::scroll-stop:
|
||||
* @bar: a #StScrollBar
|
||||
*
|
||||
* Emitted when the #StScrollBar finishes scrolling.
|
||||
*/
|
||||
signals[SCROLL_STOP] =
|
||||
g_signal_new ("scroll-stop",
|
||||
G_TYPE_FROM_CLASS (klass),
|
||||
@ -1005,9 +982,10 @@ st_scroll_bar_set_adjustment (StScrollBar *bar,
|
||||
* st_scroll_bar_get_adjustment:
|
||||
* @bar: a #StScrollbar
|
||||
*
|
||||
* Gets the #StAdjustment that controls the current position of @bar.
|
||||
* Gets the adjustment object that stores the current position
|
||||
* of the scrollbar.
|
||||
*
|
||||
* Returns: (transfer none): an #StAdjustment
|
||||
* Return value: (transfer none): the adjustment
|
||||
*/
|
||||
StAdjustment *
|
||||
st_scroll_bar_get_adjustment (StScrollBar *bar)
|
||||
|
@ -389,12 +389,6 @@ st_scroll_view_fade_class_init (StScrollViewFadeClass *klass)
|
||||
offscreen_class->create_texture = st_scroll_view_fade_create_texture;
|
||||
offscreen_class->paint_target = st_scroll_view_fade_paint_target;
|
||||
|
||||
/**
|
||||
* StScrollViewFade:vfade-offset:
|
||||
*
|
||||
* The height of area which is faded at the top and bottom edges of the
|
||||
* #StScrollViewFade.
|
||||
*/
|
||||
props[PROP_VFADE_OFFSET] =
|
||||
g_param_spec_float ("vfade-offset",
|
||||
"Vertical Fade Offset",
|
||||
@ -402,12 +396,6 @@ st_scroll_view_fade_class_init (StScrollViewFadeClass *klass)
|
||||
0.f, G_MAXFLOAT, DEFAULT_FADE_OFFSET,
|
||||
ST_PARAM_READWRITE);
|
||||
|
||||
/**
|
||||
* StScrollViewFade:hfade-offset:
|
||||
*
|
||||
* The height of area which is faded at the left and right edges of the
|
||||
* #StScrollViewFade.
|
||||
*/
|
||||
props[PROP_HFADE_OFFSET] =
|
||||
g_param_spec_float ("hfade-offset",
|
||||
"Horizontal Fade Offset",
|
||||
@ -415,11 +403,6 @@ st_scroll_view_fade_class_init (StScrollViewFadeClass *klass)
|
||||
0.f, G_MAXFLOAT, DEFAULT_FADE_OFFSET,
|
||||
ST_PARAM_READWRITE);
|
||||
|
||||
/**
|
||||
* StScrollViewFade:fade-edges:
|
||||
*
|
||||
* Whether the faded area should extend to the edges of the #StScrollViewFade.
|
||||
*/
|
||||
props[PROP_FADE_EDGES] =
|
||||
g_param_spec_boolean ("fade-edges",
|
||||
"Fade Edges",
|
||||
@ -437,13 +420,6 @@ st_scroll_view_fade_init (StScrollViewFade *self)
|
||||
self->hfade_offset = DEFAULT_FADE_OFFSET;
|
||||
}
|
||||
|
||||
/**
|
||||
* st_scroll_view_fade_new:
|
||||
*
|
||||
* Create a new #StScrollViewFade.
|
||||
*
|
||||
* Returns: (transfer full): a new #StScrollViewFade
|
||||
*/
|
||||
ClutterEffect *
|
||||
st_scroll_view_fade_new (void)
|
||||
{
|
||||
|
@ -172,8 +172,8 @@ st_scroll_view_get_property (GObject *object,
|
||||
*/
|
||||
void
|
||||
st_scroll_view_update_fade_effect (StScrollView *scroll,
|
||||
float vfade_offset,
|
||||
float hfade_offset)
|
||||
float vfade_offset,
|
||||
float hfade_offset)
|
||||
{
|
||||
StScrollViewPrivate *priv = ST_SCROLL_VIEW (scroll)->priv;
|
||||
|
||||
@ -830,11 +830,6 @@ st_scroll_view_class_init (StScrollViewClass *klass)
|
||||
|
||||
widget_class->style_changed = st_scroll_view_style_changed;
|
||||
|
||||
/**
|
||||
* StScrollView:hscroll:
|
||||
*
|
||||
* The horizontal #StScrollBar for the #StScrollView.
|
||||
*/
|
||||
props[PROP_HSCROLL] =
|
||||
g_param_spec_object ("hscroll",
|
||||
"StScrollBar",
|
||||
@ -842,11 +837,6 @@ st_scroll_view_class_init (StScrollViewClass *klass)
|
||||
ST_TYPE_SCROLL_BAR,
|
||||
ST_PARAM_READABLE);
|
||||
|
||||
/**
|
||||
* StScrollView:vscroll:
|
||||
*
|
||||
* The vertical #StScrollBar for the #StScrollView.
|
||||
*/
|
||||
props[PROP_VSCROLL] =
|
||||
g_param_spec_object ("vscroll",
|
||||
"StScrollBar",
|
||||
@ -854,11 +844,6 @@ st_scroll_view_class_init (StScrollViewClass *klass)
|
||||
ST_TYPE_SCROLL_BAR,
|
||||
ST_PARAM_READABLE);
|
||||
|
||||
/**
|
||||
* StScrollView:vscrollbar-policy:
|
||||
*
|
||||
* The #StPolicyType for when to show the vertical #StScrollBar.
|
||||
*/
|
||||
props[PROP_VSCROLLBAR_POLICY] =
|
||||
g_param_spec_enum ("vscrollbar-policy",
|
||||
"Vertical Scrollbar Policy",
|
||||
@ -867,11 +852,6 @@ st_scroll_view_class_init (StScrollViewClass *klass)
|
||||
ST_POLICY_AUTOMATIC,
|
||||
ST_PARAM_READWRITE);
|
||||
|
||||
/**
|
||||
* StScrollView:hscrollbar-policy:
|
||||
*
|
||||
* The #StPolicyType for when to show the horizontal #StScrollBar.
|
||||
*/
|
||||
props[PROP_HSCROLLBAR_POLICY] =
|
||||
g_param_spec_enum ("hscrollbar-policy",
|
||||
"Horizontal Scrollbar Policy",
|
||||
@ -880,11 +860,6 @@ st_scroll_view_class_init (StScrollViewClass *klass)
|
||||
ST_POLICY_AUTOMATIC,
|
||||
ST_PARAM_READWRITE);
|
||||
|
||||
/**
|
||||
* StScrollView:hscrollbar-visible:
|
||||
*
|
||||
* Whether the horizontal #StScrollBar is visible.
|
||||
*/
|
||||
props[PROP_HSCROLLBAR_VISIBLE] =
|
||||
g_param_spec_boolean ("hscrollbar-visible",
|
||||
"Horizontal Scrollbar Visibility",
|
||||
@ -892,11 +867,6 @@ st_scroll_view_class_init (StScrollViewClass *klass)
|
||||
TRUE,
|
||||
ST_PARAM_READABLE);
|
||||
|
||||
/**
|
||||
* StScrollView:vscrollbar-visible:
|
||||
*
|
||||
* Whether the vertical #StScrollBar is visible.
|
||||
*/
|
||||
props[PROP_VSCROLLBAR_VISIBLE] =
|
||||
g_param_spec_boolean ("vscrollbar-visible",
|
||||
"Vertical Scrollbar Visibility",
|
||||
@ -904,11 +874,6 @@ st_scroll_view_class_init (StScrollViewClass *klass)
|
||||
TRUE,
|
||||
ST_PARAM_READABLE);
|
||||
|
||||
/**
|
||||
* StScrollView:enable-mouse-scrolling:
|
||||
*
|
||||
* Whether to enable automatic mouse wheel scrolling.
|
||||
*/
|
||||
props[PROP_MOUSE_SCROLL] =
|
||||
g_param_spec_boolean ("enable-mouse-scrolling",
|
||||
"Enable Mouse Scrolling",
|
||||
@ -916,11 +881,6 @@ st_scroll_view_class_init (StScrollViewClass *klass)
|
||||
TRUE,
|
||||
ST_PARAM_READWRITE);
|
||||
|
||||
/**
|
||||
* StScrollView:overlay-scrollbars:
|
||||
*
|
||||
* Whether scrollbars are painted on top of the content.
|
||||
*/
|
||||
props[PROP_OVERLAY_SCROLLBARS] =
|
||||
g_param_spec_boolean ("overlay-scrollbars",
|
||||
"Use Overlay Scrollbars",
|
||||
@ -1035,13 +995,6 @@ clutter_container_iface_init (ClutterContainerIface *iface)
|
||||
iface->remove = st_scroll_view_remove;
|
||||
}
|
||||
|
||||
/**
|
||||
* st_scroll_view_new:
|
||||
*
|
||||
* Create a new #StScrollView.
|
||||
*
|
||||
* Returns: (transfer full): a new #StScrollView
|
||||
*/
|
||||
StWidget *
|
||||
st_scroll_view_new (void)
|
||||
{
|
||||
@ -1052,9 +1005,9 @@ st_scroll_view_new (void)
|
||||
* st_scroll_view_get_hscroll_bar:
|
||||
* @scroll: a #StScrollView
|
||||
*
|
||||
* Gets the horizontal #StScrollBar of the #StScrollView.
|
||||
* Gets the horizontal scrollbar of the scrollbiew
|
||||
*
|
||||
* Returns: (transfer none): the horizontal scrollbar
|
||||
* Return value: (transfer none): the horizontal #StScrollBar
|
||||
*/
|
||||
ClutterActor *
|
||||
st_scroll_view_get_hscroll_bar (StScrollView *scroll)
|
||||
@ -1068,9 +1021,9 @@ st_scroll_view_get_hscroll_bar (StScrollView *scroll)
|
||||
* st_scroll_view_get_vscroll_bar:
|
||||
* @scroll: a #StScrollView
|
||||
*
|
||||
* Gets the vertical scrollbar of the #StScrollView.
|
||||
* Gets the vertical scrollbar of the scrollbiew
|
||||
*
|
||||
* Returns: (transfer none): the vertical #StScrollBar
|
||||
* Return value: (transfer none): the vertical #StScrollBar
|
||||
*/
|
||||
ClutterActor *
|
||||
st_scroll_view_get_vscroll_bar (StScrollView *scroll)
|
||||
@ -1080,14 +1033,6 @@ st_scroll_view_get_vscroll_bar (StScrollView *scroll)
|
||||
return scroll->priv->vscroll;
|
||||
}
|
||||
|
||||
/**
|
||||
* st_scroll_view_get_column_size:
|
||||
* @scroll: a #StScrollView
|
||||
*
|
||||
* Get the step increment of the horizontal plane.
|
||||
*
|
||||
* Returns: the horizontal step increment
|
||||
*/
|
||||
gfloat
|
||||
st_scroll_view_get_column_size (StScrollView *scroll)
|
||||
{
|
||||
@ -1102,13 +1047,6 @@ st_scroll_view_get_column_size (StScrollView *scroll)
|
||||
return column_size;
|
||||
}
|
||||
|
||||
/**
|
||||
* st_scroll_view_set_column_size:
|
||||
* @scroll: a #StScrollView
|
||||
* @column_size: horizontal step increment
|
||||
*
|
||||
* Set the step increment of the horizontal plane to @column_size.
|
||||
*/
|
||||
void
|
||||
st_scroll_view_set_column_size (StScrollView *scroll,
|
||||
gfloat column_size)
|
||||
@ -1131,14 +1069,6 @@ st_scroll_view_set_column_size (StScrollView *scroll,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* st_scroll_view_get_row_size:
|
||||
* @scroll: a #StScrollView
|
||||
*
|
||||
* Get the step increment of the vertical plane.
|
||||
*
|
||||
* Returns: the vertical step increment
|
||||
*/
|
||||
gfloat
|
||||
st_scroll_view_get_row_size (StScrollView *scroll)
|
||||
{
|
||||
@ -1153,13 +1083,6 @@ st_scroll_view_get_row_size (StScrollView *scroll)
|
||||
return row_size;
|
||||
}
|
||||
|
||||
/**
|
||||
* st_scroll_view_set_row_size:
|
||||
* @scroll: a #StScrollView
|
||||
* @row_size: vertical step increment
|
||||
*
|
||||
* Set the step increment of the vertical plane to @row_size.
|
||||
*/
|
||||
void
|
||||
st_scroll_view_set_row_size (StScrollView *scroll,
|
||||
gfloat row_size)
|
||||
@ -1182,13 +1105,6 @@ st_scroll_view_set_row_size (StScrollView *scroll,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* st_scroll_view_set_mouse_scrolling:
|
||||
* @scroll: a #StScrollView
|
||||
* @enabled: %TRUE or %FALSE
|
||||
*
|
||||
* Sets automatic mouse wheel scrolling to enabled or disabled.
|
||||
*/
|
||||
void
|
||||
st_scroll_view_set_mouse_scrolling (StScrollView *scroll,
|
||||
gboolean enabled)
|
||||
@ -1209,14 +1125,6 @@ st_scroll_view_set_mouse_scrolling (StScrollView *scroll,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* st_scroll_view_get_mouse_scrolling:
|
||||
* @scroll: a #StScrollView
|
||||
*
|
||||
* Get whether automatic mouse wheel scrolling is enabled or disabled.
|
||||
*
|
||||
* Returns: %TRUE if enabled, %FALSE otherwise
|
||||
*/
|
||||
gboolean
|
||||
st_scroll_view_get_mouse_scrolling (StScrollView *scroll)
|
||||
{
|
||||
@ -1259,9 +1167,7 @@ st_scroll_view_set_overlay_scrollbars (StScrollView *scroll,
|
||||
* st_scroll_view_get_overlay_scrollbars:
|
||||
* @scroll: A #StScrollView
|
||||
*
|
||||
* Gets whether scrollbars are painted on top of the content.
|
||||
*
|
||||
* Returns: %TRUE if enabled, %FALSE otherwise
|
||||
* Gets the value set by st_scroll_view_set_overlay_scrollbars().
|
||||
*/
|
||||
gboolean
|
||||
st_scroll_view_get_overlay_scrollbars (StScrollView *scroll)
|
||||
|
@ -86,40 +86,6 @@ st_scrollable_default_init (StScrollableInterface *g_iface)
|
||||
|
||||
if (!initialized)
|
||||
{
|
||||
/**
|
||||
* StScrollable:hadjustment:
|
||||
*
|
||||
* The horizontal #StAdjustment used by the #StScrollable.
|
||||
*
|
||||
* Implementations should override this property to provide read-write
|
||||
* access to the #StAdjustment.
|
||||
*
|
||||
* JavaScript code may override this as demonstrated below:
|
||||
*
|
||||
* |[<!-- language="JavaScript" -->
|
||||
* var MyScrollable = GObject.registerClass({
|
||||
* Properties: {
|
||||
* 'hadjustment': GObject.ParamSpec.override(
|
||||
* 'hadjustment',
|
||||
* St.Scrollable
|
||||
* )
|
||||
* }
|
||||
* }, class MyScrollable extends St.Scrollable {
|
||||
*
|
||||
* get hadjustment() {
|
||||
* return this._hadjustment || null;
|
||||
* }
|
||||
*
|
||||
* set hadjustment(adjustment) {
|
||||
* if (this.hadjustment === adjustment)
|
||||
* return;
|
||||
*
|
||||
* this._hadjustment = adjustment;
|
||||
* this.notify('hadjustment');
|
||||
* }
|
||||
* });
|
||||
* ]|
|
||||
*/
|
||||
g_object_interface_install_property (g_iface,
|
||||
g_param_spec_object ("hadjustment",
|
||||
"StAdjustment",
|
||||
@ -127,17 +93,6 @@ st_scrollable_default_init (StScrollableInterface *g_iface)
|
||||
ST_TYPE_ADJUSTMENT,
|
||||
ST_PARAM_READWRITE));
|
||||
|
||||
/**
|
||||
* StScrollable:vadjustment:
|
||||
*
|
||||
* The vertical #StAdjustment used by the #StScrollable.
|
||||
*
|
||||
* Implementations should override this property to provide read-write
|
||||
* access to the #StAdjustment.
|
||||
*
|
||||
* See #StScrollable:hadjustment for an example of how to override this
|
||||
* property in JavaScript code.
|
||||
*/
|
||||
g_object_interface_install_property (g_iface,
|
||||
g_param_spec_object ("vadjustment",
|
||||
"StAdjustment",
|
||||
@ -149,18 +104,6 @@ st_scrollable_default_init (StScrollableInterface *g_iface)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* st_scrollable_set_adjustments:
|
||||
* @scrollable: a #StScrollable
|
||||
* @hadjustment: the horizontal #StAdjustment
|
||||
* @vadjustment: the vertical #StAdjustment
|
||||
*
|
||||
* This method should be implemented by classes implementing the #StScrollable
|
||||
* interface.
|
||||
*
|
||||
* JavaScript code should do this by overriding the `vfunc_set_adjustments()`
|
||||
* method.
|
||||
*/
|
||||
void
|
||||
st_scrollable_set_adjustments (StScrollable *scrollable,
|
||||
StAdjustment *hadjustment,
|
||||
@ -173,17 +116,11 @@ st_scrollable_set_adjustments (StScrollable *scrollable,
|
||||
|
||||
/**
|
||||
* st_scroll_bar_get_adjustments:
|
||||
* @hadjustment: (transfer none) (out) (optional): location to store the horizontal adjustment, or %NULL
|
||||
* @vadjustment: (transfer none) (out) (optional): location to store the vertical adjustment, or %NULL
|
||||
* @hadjustment: (transfer none) (out) (optional) (nullable): location to store the horizontal adjustment, or %NULL
|
||||
* @vadjustment: (transfer none) (out) (optional) (nullable): location to store the vertical adjustment, or %NULL
|
||||
*
|
||||
* Gets the adjustment objects that store the offsets of the scrollable widget
|
||||
* into its possible scrolling area.
|
||||
*
|
||||
* This method should be implemented by classes implementing the #StScrollable
|
||||
* interface.
|
||||
*
|
||||
* JavaScript code should do this by overriding the `vfunc_get_adjustments()`
|
||||
* method.
|
||||
*/
|
||||
void
|
||||
st_scrollable_get_adjustments (StScrollable *scrollable,
|
||||
|
@ -199,89 +199,41 @@ st_settings_class_init (StSettingsClass *klass)
|
||||
object_class->set_property = st_settings_set_property;
|
||||
object_class->get_property = st_settings_get_property;
|
||||
|
||||
/**
|
||||
* StSettings:enable-animations:
|
||||
*
|
||||
* Whether animations are enabled.
|
||||
*/
|
||||
props[PROP_ENABLE_ANIMATIONS] = g_param_spec_boolean ("enable-animations",
|
||||
"Enable animations",
|
||||
"Enable animations",
|
||||
TRUE,
|
||||
ST_PARAM_READABLE);
|
||||
|
||||
/**
|
||||
* StSettings:primary-paste:
|
||||
*
|
||||
* Whether pasting from the `PRIMARY` selection is supported (eg. middle-click
|
||||
* paste).
|
||||
*/
|
||||
props[PROP_PRIMARY_PASTE] = g_param_spec_boolean ("primary-paste",
|
||||
"Primary paste",
|
||||
"Primary paste",
|
||||
TRUE,
|
||||
ST_PARAM_READABLE);
|
||||
|
||||
/**
|
||||
* StSettings:drag-threshold:
|
||||
*
|
||||
* The threshold before a drag operation begins.
|
||||
*/
|
||||
props[PROP_DRAG_THRESHOLD] = g_param_spec_int ("drag-threshold",
|
||||
"Drag threshold",
|
||||
"Drag threshold",
|
||||
0, G_MAXINT, 8,
|
||||
ST_PARAM_READABLE);
|
||||
|
||||
/**
|
||||
* StSettings:font-name:
|
||||
*
|
||||
* The current font name.
|
||||
*/
|
||||
props[PROP_FONT_NAME] = g_param_spec_string ("font-name",
|
||||
"font name",
|
||||
"font name",
|
||||
"",
|
||||
ST_PARAM_READABLE);
|
||||
|
||||
/**
|
||||
* StSettings:gtk-theme:
|
||||
*
|
||||
* The current GTK theme.
|
||||
*/
|
||||
props[PROP_GTK_THEME] = g_param_spec_string ("gtk-theme",
|
||||
"GTK Theme",
|
||||
"GTK Theme",
|
||||
"GTK+ Theme",
|
||||
"GTK+ Theme",
|
||||
"",
|
||||
ST_PARAM_READABLE);
|
||||
|
||||
/**
|
||||
* StSettings:gtk-icon-theme:
|
||||
*
|
||||
* The current GTK icon theme
|
||||
*/
|
||||
props[PROP_GTK_ICON_THEME] = g_param_spec_string ("gtk-icon-theme",
|
||||
"GTK Icon Theme",
|
||||
"GTK Icon Theme",
|
||||
"GTK+ Icon Theme",
|
||||
"GTK+ Icon Theme",
|
||||
"",
|
||||
ST_PARAM_READABLE);
|
||||
|
||||
/**
|
||||
* StSettings:magnifier-active:
|
||||
*
|
||||
* Whether the accessibility magnifier is active.
|
||||
*/
|
||||
props[PROP_MAGNIFIER_ACTIVE] = g_param_spec_boolean("magnifier-active",
|
||||
"Magnifier is active",
|
||||
"Whether the a11y magnifier is active",
|
||||
"Weather the a11y magnifier is active",
|
||||
FALSE,
|
||||
ST_PARAM_READABLE);
|
||||
|
||||
/**
|
||||
* StSettings:slow-down-factor:
|
||||
*
|
||||
* The slow-down factor applied to all animation durations.
|
||||
*/
|
||||
props[PROP_SLOW_DOWN_FACTOR] = g_param_spec_double("slow-down-factor",
|
||||
"Slow down factor",
|
||||
"Factor applied to all animation durations",
|
||||
@ -386,9 +338,9 @@ st_settings_init (StSettings *settings)
|
||||
/**
|
||||
* st_settings_get:
|
||||
*
|
||||
* Gets the global #StSettings object.
|
||||
* Gets the #StSettings
|
||||
*
|
||||
* Returns: (transfer none): the global #StSettings object
|
||||
* Returns: (transfer none): a settings object
|
||||
**/
|
||||
StSettings *
|
||||
st_settings_get (void)
|
||||
|
@ -117,7 +117,7 @@ st_shadow_unref (StShadow *shadow)
|
||||
* compare non-identically if they differ only by floating point rounding
|
||||
* errors.
|
||||
*
|
||||
* Returns: %TRUE if the two shadows are identical
|
||||
* Return value: %TRUE if the two shadows are identical
|
||||
*/
|
||||
gboolean
|
||||
st_shadow_equal (StShadow *shadow,
|
||||
@ -216,13 +216,6 @@ st_shadow_helper_new (StShadow *shadow)
|
||||
return helper;
|
||||
}
|
||||
|
||||
/**
|
||||
* st_shadow_helper_update:
|
||||
* @helper: a #StShadowHelper
|
||||
* @source: a #ClutterActor
|
||||
*
|
||||
* Update @helper from @source.
|
||||
*/
|
||||
void
|
||||
st_shadow_helper_update (StShadowHelper *helper,
|
||||
ClutterActor *source)
|
||||
|
@ -100,12 +100,6 @@ st_texture_cache_class_init (StTextureCacheClass *klass)
|
||||
gobject_class->dispose = st_texture_cache_dispose;
|
||||
gobject_class->finalize = st_texture_cache_finalize;
|
||||
|
||||
/**
|
||||
* StTextureCache::icon-theme-changed:
|
||||
* @self: a #StTextureCache
|
||||
*
|
||||
* Emitted when the icon theme is changed.
|
||||
*/
|
||||
signals[ICON_THEME_CHANGED] =
|
||||
g_signal_new ("icon-theme-changed",
|
||||
G_TYPE_FROM_CLASS (klass),
|
||||
@ -114,13 +108,6 @@ st_texture_cache_class_init (StTextureCacheClass *klass)
|
||||
NULL, NULL, NULL,
|
||||
G_TYPE_NONE, 0);
|
||||
|
||||
/**
|
||||
* StTextureCache::texture-file-changed:
|
||||
* @self: a #StTextureCache
|
||||
* @file: a #GFile
|
||||
*
|
||||
* Emitted when the source file of a texture is changed.
|
||||
*/
|
||||
signals[TEXTURE_FILE_CHANGED] =
|
||||
g_signal_new ("texture-file-changed",
|
||||
G_TYPE_FROM_CLASS (klass),
|
||||
@ -812,7 +799,7 @@ st_texture_cache_free_bind (gpointer data)
|
||||
|
||||
/**
|
||||
* st_texture_cache_bind_cairo_surface_property:
|
||||
* @cache: A #StTextureCache
|
||||
* @cache:
|
||||
* @object: A #GObject with a property @property_name of type #cairo_surface_t
|
||||
* @property_name: Name of a property
|
||||
*
|
||||
@ -823,7 +810,7 @@ st_texture_cache_free_bind (gpointer data)
|
||||
* If the source object is destroyed, the texture will continue to show the last
|
||||
* value of the property.
|
||||
*
|
||||
* Returns: (transfer none): A new #GIcon
|
||||
* Return value: (transfer none): A new #GIcon
|
||||
*/
|
||||
GIcon *
|
||||
st_texture_cache_bind_cairo_surface_property (StTextureCache *cache,
|
||||
@ -892,7 +879,7 @@ st_texture_cache_load (StTextureCache *cache,
|
||||
|
||||
/**
|
||||
* ensure_request:
|
||||
* @cache: A #StTextureCache
|
||||
* @cache:
|
||||
* @key: A cache key
|
||||
* @policy: Cache policy
|
||||
* @request: (out): If no request is outstanding, one will be created and returned here
|
||||
@ -945,8 +932,8 @@ ensure_request (StTextureCache *cache,
|
||||
|
||||
/**
|
||||
* st_texture_cache_load_gicon:
|
||||
* @cache: A #StTextureCache
|
||||
* @theme_node: (nullable): The #StThemeNode to use for colors, or %NULL
|
||||
* @cache: The texture cache instance
|
||||
* @theme_node: (nullable): The #StThemeNode to use for colors, or NULL
|
||||
* if the icon must not be recolored
|
||||
* @icon: the #GIcon to load
|
||||
* @size: Size of themed
|
||||
@ -957,7 +944,7 @@ ensure_request (StTextureCache *cache,
|
||||
* icon isn't loaded already, the texture will be filled
|
||||
* asynchronously.
|
||||
*
|
||||
* Returns: (transfer none) (nullable): A new #ClutterActor for the icon, or %NULL if not found
|
||||
* Return Value: (transfer none): A new #ClutterActor for the icon, or %NULL if not found
|
||||
*/
|
||||
ClutterActor *
|
||||
st_texture_cache_load_gicon (StTextureCache *cache,
|
||||
@ -1384,7 +1371,7 @@ st_texture_cache_load_sliced_image (StTextureCache *cache,
|
||||
|
||||
/**
|
||||
* st_texture_cache_load_file_async:
|
||||
* @cache: A #StTextureCache
|
||||
* @cache: The texture cache instance
|
||||
* @file: a #GFile of the image file from which to create a pixbuf
|
||||
* @available_width: available width for the image, can be -1 if not limited
|
||||
* @available_height: available height for the image, can be -1 if not limited
|
||||
@ -1395,7 +1382,7 @@ st_texture_cache_load_sliced_image (StTextureCache *cache,
|
||||
* size of zero. At some later point, either the image will be loaded successfully
|
||||
* and at that point size will be negotiated, or upon an error, no image will be set.
|
||||
*
|
||||
* Returns: (transfer none): A new #ClutterActor with no image loaded initially.
|
||||
* Return value: (transfer none): A new #ClutterActor with no image loaded initially.
|
||||
*/
|
||||
ClutterActor *
|
||||
st_texture_cache_load_file_async (StTextureCache *cache,
|
||||
@ -1625,7 +1612,7 @@ static StTextureCache *instance = NULL;
|
||||
/**
|
||||
* st_texture_cache_get_default:
|
||||
*
|
||||
* Returns: (transfer none): The global texture cache
|
||||
* Return value: (transfer none): The global texture cache
|
||||
*/
|
||||
StTextureCache*
|
||||
st_texture_cache_get_default (void)
|
||||
@ -1635,13 +1622,6 @@ st_texture_cache_get_default (void)
|
||||
return instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* st_texture_cache_rescan_icon_theme:
|
||||
*
|
||||
* Rescan the current icon theme, if necessary.
|
||||
*
|
||||
* Returns: %TRUE if the icon theme has changed and needed to be reloaded.
|
||||
*/
|
||||
gboolean
|
||||
st_texture_cache_rescan_icon_theme (StTextureCache *cache)
|
||||
{
|
||||
|
@ -118,23 +118,16 @@ st_theme_context_class_init (StThemeContextClass *klass)
|
||||
/**
|
||||
* StThemeContext:scale-factor:
|
||||
*
|
||||
* The scaling factor used for HiDPI scaling.
|
||||
* The scaling factor used or high dpi scaling.
|
||||
*/
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_SCALE_FACTOR,
|
||||
g_param_spec_int ("scale-factor",
|
||||
"Scale factor",
|
||||
"Integer scale factor used for HiDPI scaling",
|
||||
"Integer scale factor used for high dpi scaling",
|
||||
0, G_MAXINT, 1,
|
||||
ST_PARAM_READWRITE));
|
||||
|
||||
/**
|
||||
* StThemeContext::changed:
|
||||
* @self: a #StThemeContext
|
||||
*
|
||||
* Emitted when the icon theme, font, resolution, scale factor or the current
|
||||
* theme's custom stylesheets change.
|
||||
*/
|
||||
signals[CHANGED] =
|
||||
g_signal_new ("changed",
|
||||
G_TYPE_FROM_CLASS (klass),
|
||||
@ -221,8 +214,6 @@ st_theme_context_get_property (GObject *object,
|
||||
* This can be useful in testing scenarios, or if using StThemeContext
|
||||
* with something other than #ClutterActor objects, but you generally
|
||||
* should use st_theme_context_get_for_stage() instead.
|
||||
*
|
||||
* Returns: (transfer full): a new #StThemeContext
|
||||
*/
|
||||
StThemeContext *
|
||||
st_theme_context_new (void)
|
||||
@ -305,7 +296,7 @@ on_icon_theme_changed (StTextureCache *cache,
|
||||
*
|
||||
* Gets a singleton theme context associated with the stage.
|
||||
*
|
||||
* Returns: (transfer none): the singleton theme context for the stage
|
||||
* Return value: (transfer none): the singleton theme context for the stage
|
||||
*/
|
||||
StThemeContext *
|
||||
st_theme_context_get_for_stage (ClutterStage *stage)
|
||||
@ -329,7 +320,6 @@ st_theme_context_get_for_stage (ClutterStage *stage)
|
||||
/**
|
||||
* st_theme_context_set_theme:
|
||||
* @context: a #StThemeContext
|
||||
* @theme: a #StTheme
|
||||
*
|
||||
* Sets the default set of theme stylesheets for the context. This theme will
|
||||
* be used for the root node and for nodes descending from it, unless some other
|
||||
@ -368,7 +358,7 @@ st_theme_context_set_theme (StThemeContext *context,
|
||||
*
|
||||
* Gets the default theme for the context. See st_theme_context_set_theme()
|
||||
*
|
||||
* Returns: (transfer none): the default theme for the context
|
||||
* Return value: (transfer none): the default theme for the context
|
||||
*/
|
||||
StTheme *
|
||||
st_theme_context_get_theme (StThemeContext *context)
|
||||
@ -386,7 +376,7 @@ st_theme_context_get_theme (StThemeContext *context)
|
||||
* Sets the default font for the theme context. This is the font that
|
||||
* is inherited by the root node of the tree of theme nodes. If the
|
||||
* font is not overriden, then this font will be used. If the font is
|
||||
* partially modified (for example, with 'font-size: 110%'), then that
|
||||
* partially modified (for example, with 'font-size: 110%', then that
|
||||
* modification is based on this font.
|
||||
*/
|
||||
void
|
||||
@ -411,7 +401,7 @@ st_theme_context_set_font (StThemeContext *context,
|
||||
*
|
||||
* Gets the default font for the theme context. See st_theme_context_set_font().
|
||||
*
|
||||
* Returns: the default font for the theme context.
|
||||
* Return value: the default font for the theme context.
|
||||
*/
|
||||
const PangoFontDescription *
|
||||
st_theme_context_get_font (StThemeContext *context)
|
||||
@ -429,7 +419,7 @@ st_theme_context_get_font (StThemeContext *context)
|
||||
* context. For the node tree associated with a stage, this node represents
|
||||
* styles applied to the stage itself.
|
||||
*
|
||||
* Returns: (transfer none): the root node of the context's style tree
|
||||
* Return value: (transfer none): the root node of the context's style tree
|
||||
*/
|
||||
StThemeNode *
|
||||
st_theme_context_get_root_node (StThemeContext *context)
|
||||
@ -449,7 +439,7 @@ st_theme_context_get_root_node (StThemeContext *context)
|
||||
* Return an existing node matching @node, or if that isn't possible,
|
||||
* @node itself.
|
||||
*
|
||||
* Returns: (transfer none): a node with the same properties as @node
|
||||
* Return value: (transfer none): a node with the same properties as @node
|
||||
*/
|
||||
StThemeNode *
|
||||
st_theme_context_intern_node (StThemeContext *context,
|
||||
@ -471,7 +461,7 @@ st_theme_context_intern_node (StThemeContext *context,
|
||||
*
|
||||
* Return the current scale factor of @context.
|
||||
*
|
||||
* Returns: an integer scale factor
|
||||
* Return value: a scale factor
|
||||
*/
|
||||
int
|
||||
st_theme_context_get_scale_factor (StThemeContext *context)
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user