Compare commits
65 Commits
wip/exalm/
...
wip/carlos
Author | SHA1 | Date | |
---|---|---|---|
f0cf611e1b | |||
beddbc0583 | |||
2f840174cb | |||
015559a207 | |||
98d6c4e8dd | |||
1675b54738 | |||
44cbd1e718 | |||
0dc1e1e99a | |||
1029e683d3 | |||
cf1d09b482 | |||
a436226266 | |||
33ff3dc44f | |||
2e77ed712c | |||
9d6ccb6072 | |||
5091eab280 | |||
6d38bc69ca | |||
adc8b1ba89 | |||
38777b41a5 | |||
263320696e | |||
e6153bb578 | |||
c723a1b72a | |||
0b56416d30 | |||
0c5716b018 | |||
1fa1333e13 | |||
6edd3c4b93 | |||
72a8522a10 | |||
b91903555a | |||
6b78f58a75 | |||
e62c0757c3 | |||
9168f6055e | |||
8993de76f0 | |||
01fedeed8f | |||
757e4b6731 | |||
c2b70101f2 | |||
9d4a3a614d | |||
2af7264cff | |||
a96c8d91b5 | |||
3541a57570 | |||
18155fc6ea | |||
b83c93ad62 | |||
d0dab5a6d1 | |||
c9708b140c | |||
dd846f1ba2 | |||
ec3653240a | |||
b689b35b7d | |||
01a927f388 | |||
41d5b1455f | |||
b710c6e275 | |||
4c9f42eea9 | |||
2b0731ab81 | |||
a9b803f075 | |||
73436b5276 | |||
20dcc8aa87 | |||
fdac0602db | |||
e5272c84d7 | |||
1812db7aa8 | |||
260405a49e | |||
71d37bffdf | |||
95436a08b5 | |||
13137aad9d | |||
71f55643b2 | |||
5c550daecb | |||
4e0492c517 | |||
f386103bc1 | |||
26e66aa4fd |
@ -9,7 +9,6 @@ stages:
|
||||
variables:
|
||||
BUNDLE: "extensions-git.flatpak"
|
||||
JS_LOG: "js-report.txt"
|
||||
POT_LOG: "pot-update.txt"
|
||||
|
||||
.only_default: &only_default
|
||||
only:
|
||||
@ -67,6 +66,7 @@ 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,6 +85,7 @@ 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"
|
||||
@ -99,24 +100,9 @@ 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,3 +1,35 @@
|
||||
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,6 +20,12 @@
|
||||
<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>
|
||||
|
191
data/dbus-interfaces/org.gnome.Mutter.ScreenCast.xml
Normal file
191
data/dbus-interfaces/org.gnome.Mutter.ScreenCast.xml
Normal file
@ -0,0 +1,191 @@
|
||||
<!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,6 +70,14 @@
|
||||
-->
|
||||
<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,6 +28,7 @@
|
||||
<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,10 +0,0 @@
|
||||
[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,22 +101,21 @@ if have_systemd
|
||||
unitconf.set('bindir', bindir)
|
||||
|
||||
configure_file(
|
||||
input: 'gnome-shell-x11.service.in',
|
||||
output: 'gnome-shell-x11.service',
|
||||
input: 'org.gnome.Shell@x11.service.in',
|
||||
output: 'org.gnome.Shell@x11.service',
|
||||
configuration: unitconf,
|
||||
install_dir: systemduserunitdir
|
||||
)
|
||||
|
||||
configure_file(
|
||||
input: 'gnome-shell-wayland.service.in',
|
||||
output: 'gnome-shell-wayland.service',
|
||||
input: 'org.gnome.Shell@wayland.service.in',
|
||||
output: 'org.gnome.Shell@wayland.service',
|
||||
configuration: unitconf,
|
||||
install_dir: systemduserunitdir
|
||||
)
|
||||
|
||||
units = files('gnome-shell-x11.target',
|
||||
'gnome-shell-wayland.target',
|
||||
'gnome-shell-disable-extensions.service')
|
||||
units = files('org.gnome.Shell.target',
|
||||
'org.gnome.Shell-disable-extensions.service')
|
||||
|
||||
install_data(units, install_dir: systemduserunitdir)
|
||||
endif
|
||||
|
@ -6,5 +6,5 @@ Requisite=gnome-session-initialized.target
|
||||
PartOf=gnome-session-initialized.target
|
||||
Before=gnome-session-initialized.target
|
||||
|
||||
Requires=gnome-shell-wayland.service
|
||||
After=gnome-shell-wayland.service
|
||||
Wants=org.gnome.Shell@wayland.service
|
||||
Wants=org.gnome.Shell@x11.service
|
@ -1,7 +1,7 @@
|
||||
[Unit]
|
||||
Description=GNOME Shell on Wayland
|
||||
# On wayland, force a session shutdown
|
||||
OnFailure=gnome-shell-disable-extensions.service gnome-session-shutdown.target
|
||||
OnFailure=org.gnome.Shell-disable-extensions.service gnome-session-shutdown.target
|
||||
OnFailureJobMode=replace-irreversibly
|
||||
CollectMode=inactive-or-failed
|
||||
RefuseManualStart=on
|
||||
@ -13,18 +13,21 @@ 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
|
@ -1,7 +1,7 @@
|
||||
[Unit]
|
||||
Description=GNOME Shell on X11
|
||||
# On X11, try to show the GNOME Session Failed screen
|
||||
OnFailure=gnome-shell-disable-extensions.service gnome-session-failed.target
|
||||
OnFailure=org.gnome.Shell-disable-extensions.service gnome-session-failed.target
|
||||
OnFailureJobMode=replace
|
||||
CollectMode=inactive-or-failed
|
||||
RefuseManualStart=on
|
||||
@ -13,18 +13,24 @@ 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
|
@ -232,7 +232,9 @@
|
||||
color: $fg_color;
|
||||
font-feature-settings: "tnum";
|
||||
@include fontsize($base_font_size);
|
||||
text-align: right;
|
||||
|
||||
&:ltr { text-align: right; }
|
||||
&:rtl { text-align: left; }
|
||||
}
|
||||
|
||||
// timezone offset label
|
||||
|
@ -138,11 +138,10 @@
|
||||
.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; }
|
||||
&:rtl { padding-right: 14px; }
|
||||
&:ltr { padding-left: 14px; text-align: left; }
|
||||
&:rtl { padding-right: 14px; text-align: right; }
|
||||
}
|
||||
|
||||
.user-widget.vertical .user-widget-label {
|
||||
|
@ -71,9 +71,11 @@
|
||||
> .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,8 +76,10 @@ $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,13 +3,8 @@ 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,6 +25,8 @@ 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,6 +8,12 @@ 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
|
||||
|
11
js/dbusServices/org.gnome.Shell.Screencast.src.gresource.xml
Normal file
11
js/dbusServices/org.gnome.Shell.Screencast.src.gresource.xml
Normal file
@ -0,0 +1,11 @@
|
||||
<?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>
|
11
js/dbusServices/screencast/main.js
Normal file
11
js/dbusServices/screencast/main.js
Normal file
@ -0,0 +1,11 @@
|
||||
/* exported main */
|
||||
|
||||
const { DBusService } = imports.dbusService;
|
||||
const { ScreencastService } = imports.screencastService;
|
||||
|
||||
function main() {
|
||||
const service = new DBusService(
|
||||
'org.gnome.Shell.Screencast',
|
||||
new ScreencastService());
|
||||
service.run();
|
||||
}
|
458
js/dbusServices/screencast/screencastService.js
Normal file
458
js/dbusServices/screencast/screencastService.js
Normal file
@ -0,0 +1,458 @@
|
||||
// -*- 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,16 +953,15 @@ 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: () => {
|
||||
if (this._authPrompt.verificationStatus != AuthPrompt.AuthPromptStatus.NOT_VERIFYING)
|
||||
this._authPrompt.reset();
|
||||
this._unbindOpacity();
|
||||
},
|
||||
onComplete: () => this._unbindOpacity(),
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -32,6 +32,7 @@
|
||||
<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>
|
||||
|
||||
@ -92,7 +93,6 @@
|
||||
<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>
|
||||
@ -137,7 +137,6 @@
|
||||
<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 */
|
||||
recursivelyMoveDir, loadInterfaceXML, loadSubInterfaceXML */
|
||||
|
||||
const { Gio, GLib } = imports.gi;
|
||||
const Config = imports.misc.config;
|
||||
@ -67,14 +67,19 @@ 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) {
|
||||
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();
|
||||
}
|
||||
ensureIfaceResource();
|
||||
|
||||
let uri = `resource:///org/gnome/shell/dbus-interfaces/${iface}.xml`;
|
||||
let f = Gio.File.new_for_uri(uri);
|
||||
@ -88,3 +93,25 @@ 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_WHITELIST = ['org.freedesktop.impl.portal.desktop.gtk'];
|
||||
const APP_ALLOWLIST = ['org.freedesktop.impl.portal.desktop.gtk'];
|
||||
|
||||
const INTROSPECT_DBUS_API_VERSION = 2;
|
||||
const INTROSPECT_DBUS_API_VERSION = 3;
|
||||
|
||||
const { loadInterfaceXML } = imports.misc.fileUtils;
|
||||
|
||||
@ -46,19 +46,24 @@ var IntrospectService = class {
|
||||
|
||||
this._syncRunningApplications();
|
||||
|
||||
this._whitelistMap = new Map();
|
||||
APP_WHITELIST.forEach(appName => {
|
||||
this._allowlistMap = new Map();
|
||||
APP_ALLOWLIST.forEach(appName => {
|
||||
Gio.DBus.watch_name(Gio.BusType.SESSION,
|
||||
appName,
|
||||
Gio.BusNameWatcherFlags.NONE,
|
||||
(conn, name, owner) => this._whitelistMap.set(name, owner),
|
||||
(conn, name) => this._whitelistMap.delete(name));
|
||||
(conn, name, owner) => this._allowlistMap.set(name, owner),
|
||||
(conn, name) => this._allowlistMap.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) {
|
||||
@ -69,8 +74,8 @@ var IntrospectService = class {
|
||||
return this._introspectSettings.get_boolean(INTROSPECT_KEY);
|
||||
}
|
||||
|
||||
_isSenderWhitelisted(sender) {
|
||||
return [...this._whitelistMap.values()].includes(sender);
|
||||
_isSenderAllowed(sender) {
|
||||
return [...this._allowlistMap.values()].includes(sender);
|
||||
}
|
||||
|
||||
_getSandboxedAppId(app) {
|
||||
@ -133,7 +138,7 @@ var IntrospectService = class {
|
||||
if (this._isIntrospectEnabled())
|
||||
return true;
|
||||
|
||||
if (this._isSenderWhitelisted(invocation.get_sender()))
|
||||
if (this._isSenderAllowed(invocation.get_sender()))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
@ -209,10 +214,28 @@ 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,6 +158,23 @@ 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)
|
||||
@ -203,6 +220,13 @@ 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 blacklisted in
|
||||
// - The executable from the .desktop file’s Exec line isn’t denied in
|
||||
// the user’s parental controls.
|
||||
// - None of the flatpak app IDs from the X-Flatpak and the
|
||||
// X-Flatpak-RenamedFrom lines are blacklisted in the user’s parental
|
||||
// X-Flatpak-RenamedFrom lines are denied in the user’s parental
|
||||
// controls.
|
||||
shouldShowApp(appInfo) {
|
||||
// Quick decision?
|
||||
|
@ -21,6 +21,7 @@ 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';
|
||||
@ -40,41 +41,38 @@ 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-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-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),
|
||||
},
|
||||
}, class SystemActions extends GObject.Object {
|
||||
_init() {
|
||||
@ -93,7 +91,15 @@ 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;reboot;restart;halt;stop')),
|
||||
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;')),
|
||||
available: false,
|
||||
});
|
||||
this._actions.set(LOCK_SCREEN_ACTION_ID, {
|
||||
@ -203,6 +209,11 @@ 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;
|
||||
@ -306,6 +317,9 @@ 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;
|
||||
@ -347,6 +361,9 @@ 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() {
|
||||
@ -445,6 +462,13 @@ 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
Normal file
146
js/perf/basic.js
Normal file
@ -0,0 +1,146 @@
|
||||
// -*- 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,7 +70,8 @@ let WINDOW_CONFIGS = [
|
||||
{ width: 640, height: 480, alpha: true, maximized: false, count: 10, metric: 'overviewFps10Alpha' },
|
||||
];
|
||||
|
||||
function *run() {
|
||||
async function run() {
|
||||
/* eslint-disable no-await-in-loop */
|
||||
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");
|
||||
@ -84,7 +85,7 @@ function *run() {
|
||||
Scripting.scriptEvent('overviewShowDone');
|
||||
});
|
||||
|
||||
yield Scripting.sleep(1000);
|
||||
await 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
|
||||
@ -92,49 +93,50 @@ function *run() {
|
||||
// a clean set of numbers.
|
||||
if ((i % 2) == 0) {
|
||||
let config = WINDOW_CONFIGS[i / 2];
|
||||
yield Scripting.destroyTestWindows();
|
||||
await Scripting.destroyTestWindows();
|
||||
|
||||
for (let k = 0; k < config.count; k++) {
|
||||
yield Scripting.createTestWindow({ width: config.width,
|
||||
await Scripting.createTestWindow({ width: config.width,
|
||||
height: config.height,
|
||||
alpha: config.alpha,
|
||||
maximized: config.maximized });
|
||||
}
|
||||
|
||||
yield Scripting.waitTestWindows();
|
||||
yield Scripting.sleep(1000);
|
||||
yield Scripting.waitLeisure();
|
||||
await Scripting.waitTestWindows();
|
||||
await Scripting.sleep(1000);
|
||||
await Scripting.waitLeisure();
|
||||
}
|
||||
|
||||
Scripting.scriptEvent('overviewShowStart');
|
||||
Main.overview.show();
|
||||
|
||||
yield Scripting.waitLeisure();
|
||||
await Scripting.waitLeisure();
|
||||
Main.overview.hide();
|
||||
yield Scripting.waitLeisure();
|
||||
await Scripting.waitLeisure();
|
||||
|
||||
System.gc();
|
||||
yield Scripting.sleep(1000);
|
||||
await Scripting.sleep(1000);
|
||||
Scripting.collectStatistics();
|
||||
Scripting.scriptEvent('afterShowHide');
|
||||
}
|
||||
|
||||
yield Scripting.destroyTestWindows();
|
||||
yield Scripting.sleep(1000);
|
||||
await Scripting.destroyTestWindows();
|
||||
await Scripting.sleep(1000);
|
||||
|
||||
Main.overview.show();
|
||||
yield Scripting.waitLeisure();
|
||||
await 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;
|
||||
yield Scripting.waitLeisure();
|
||||
await Scripting.waitLeisure();
|
||||
Scripting.scriptEvent('applicationsShowDone');
|
||||
// eslint-disable-next-line require-atomic-updates
|
||||
Main.overview.dash.showAppsButton.checked = false;
|
||||
yield Scripting.waitLeisure();
|
||||
await Scripting.waitLeisure();
|
||||
}
|
||||
/* eslint-enable no-await-in-loop */
|
||||
}
|
||||
|
||||
let showingOverview = false;
|
||||
|
@ -94,7 +94,8 @@ function extractBootTimestamp() {
|
||||
return result;
|
||||
}
|
||||
|
||||
function *run() {
|
||||
async function run() {
|
||||
/* eslint-disable no-await-in-loop */
|
||||
Scripting.defineScriptEvent("desktopShown", "Finished initial animation");
|
||||
Scripting.defineScriptEvent("overviewShowStart", "Starting to show the overview");
|
||||
Scripting.defineScriptEvent("overviewShowDone", "Overview finished showing");
|
||||
@ -110,7 +111,7 @@ function *run() {
|
||||
Scripting.defineScriptEvent("geditLaunch", "gedit application launch");
|
||||
Scripting.defineScriptEvent("geditFirstFrame", "first frame of gedit window drawn");
|
||||
|
||||
yield Scripting.waitLeisure();
|
||||
await Scripting.waitLeisure();
|
||||
Scripting.scriptEvent('desktopShown');
|
||||
|
||||
let interfaceSettings = new Gio.Settings({
|
||||
@ -120,22 +121,22 @@ function *run() {
|
||||
|
||||
Scripting.scriptEvent('overviewShowStart');
|
||||
Main.overview.show();
|
||||
yield Scripting.waitLeisure();
|
||||
await Scripting.waitLeisure();
|
||||
Scripting.scriptEvent('overviewShowDone');
|
||||
|
||||
yield Scripting.sleep(1000);
|
||||
await Scripting.sleep(1000);
|
||||
|
||||
Scripting.scriptEvent('applicationsShowStart');
|
||||
// eslint-disable-next-line require-atomic-updates
|
||||
Main.overview.dash.showAppsButton.checked = true;
|
||||
|
||||
yield Scripting.waitLeisure();
|
||||
await Scripting.waitLeisure();
|
||||
Scripting.scriptEvent('applicationsShowDone');
|
||||
|
||||
yield Scripting.sleep(1000);
|
||||
await Scripting.sleep(1000);
|
||||
|
||||
Main.overview.hide();
|
||||
yield Scripting.waitLeisure();
|
||||
await Scripting.waitLeisure();
|
||||
|
||||
// --------------------- //
|
||||
// Tests of redraw speed //
|
||||
@ -145,46 +146,46 @@ function *run() {
|
||||
global.frame_finish_timestamp = true;
|
||||
|
||||
for (let k = 0; k < 5; k++)
|
||||
yield Scripting.createTestWindow({ maximized: true });
|
||||
yield Scripting.waitTestWindows();
|
||||
await Scripting.createTestWindow({ maximized: true });
|
||||
await Scripting.waitTestWindows();
|
||||
|
||||
yield Scripting.sleep(1000);
|
||||
await Scripting.sleep(1000);
|
||||
|
||||
Scripting.scriptEvent('mainViewDrawStart');
|
||||
yield waitAndDraw(1000);
|
||||
await waitAndDraw(1000);
|
||||
Scripting.scriptEvent('mainViewDrawDone');
|
||||
|
||||
Main.overview.show();
|
||||
Scripting.waitLeisure();
|
||||
|
||||
yield Scripting.sleep(1500);
|
||||
await Scripting.sleep(1500);
|
||||
|
||||
Scripting.scriptEvent('overviewDrawStart');
|
||||
yield waitAndDraw(1000);
|
||||
await waitAndDraw(1000);
|
||||
Scripting.scriptEvent('overviewDrawDone');
|
||||
|
||||
yield Scripting.destroyTestWindows();
|
||||
await Scripting.destroyTestWindows();
|
||||
Main.overview.hide();
|
||||
|
||||
yield Scripting.createTestWindow({ maximized: true,
|
||||
await Scripting.createTestWindow({ maximized: true,
|
||||
redraws: true });
|
||||
yield Scripting.waitTestWindows();
|
||||
await Scripting.waitTestWindows();
|
||||
|
||||
yield Scripting.sleep(1000);
|
||||
await Scripting.sleep(1000);
|
||||
|
||||
Scripting.scriptEvent('redrawTestStart');
|
||||
yield Scripting.sleep(1000);
|
||||
await Scripting.sleep(1000);
|
||||
Scripting.scriptEvent('redrawTestDone');
|
||||
|
||||
yield Scripting.sleep(1000);
|
||||
await Scripting.sleep(1000);
|
||||
Scripting.scriptEvent('collectTimings');
|
||||
|
||||
yield Scripting.destroyTestWindows();
|
||||
await Scripting.destroyTestWindows();
|
||||
|
||||
global.frame_timestamps = false;
|
||||
global.frame_finish_timestamp = false;
|
||||
|
||||
yield Scripting.sleep(1000);
|
||||
await Scripting.sleep(1000);
|
||||
|
||||
let appSys = Shell.AppSystem.get_default();
|
||||
let app = appSys.lookup_app('org.gnome.gedit.desktop');
|
||||
@ -197,21 +198,22 @@ function *run() {
|
||||
throw new Error('gedit was already running');
|
||||
|
||||
while (windows.length == 0) {
|
||||
yield waitSignal(global.display, 'window-created');
|
||||
await waitSignal(global.display, 'window-created');
|
||||
windows = app.get_windows();
|
||||
}
|
||||
|
||||
let actor = windows[0].get_compositor_private();
|
||||
yield waitSignal(actor, 'first-frame');
|
||||
await waitSignal(actor, 'first-frame');
|
||||
Scripting.scriptEvent('geditFirstFrame');
|
||||
|
||||
yield Scripting.sleep(1000);
|
||||
await Scripting.sleep(1000);
|
||||
|
||||
windows[0].delete(global.get_current_time());
|
||||
|
||||
yield Scripting.sleep(1000);
|
||||
await 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 DND.DragMotionResult.CONTINUE;
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -2335,13 +2335,8 @@ var AppFolderDialog = GObject.registerClass({
|
||||
}
|
||||
|
||||
_withinDialog(x, y) {
|
||||
const childAllocation =
|
||||
Shell.util_get_transformed_allocation(this.child);
|
||||
|
||||
return x > childAllocation.x1 &&
|
||||
x < childAllocation.x2 &&
|
||||
y > childAllocation.y1 &&
|
||||
y < childAllocation.y2;
|
||||
const childExtents = this.child.get_transformed_extents();
|
||||
return childExtents.contains_point(new Graphene.Point({ x, y }));
|
||||
}
|
||||
|
||||
_setupDragMonitor() {
|
||||
|
@ -347,6 +347,8 @@ var Background = GObject.registerClass({
|
||||
this.set_color(color);
|
||||
else
|
||||
this.set_gradient(shadingType, color, secondColor);
|
||||
|
||||
this._setLoaded();
|
||||
}
|
||||
|
||||
_watchFile(file) {
|
||||
@ -765,10 +767,27 @@ 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, Shell, St } = imports.gi;
|
||||
const { Clutter, GObject, St } = imports.gi;
|
||||
|
||||
const Main = imports.ui.main;
|
||||
|
||||
@ -453,15 +453,16 @@ var BoxPointer = GObject.registerClass({
|
||||
let alignment = this._arrowAlignment;
|
||||
let monitorIndex = Main.layoutManager.findIndexForActor(sourceActor);
|
||||
|
||||
this._sourceAllocation = Shell.util_get_transformed_allocation(sourceActor);
|
||||
this._sourceExtents = sourceActor.get_transformed_extents();
|
||||
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 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 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 [, , natWidth, natHeight] = this.get_preferred_size();
|
||||
|
||||
// We also want to keep it onscreen, and separated from the
|
||||
@ -481,16 +482,16 @@ var BoxPointer = GObject.registerClass({
|
||||
|
||||
switch (this._arrowSide) {
|
||||
case St.Side.TOP:
|
||||
resY = sourceAllocation.y2 + gap;
|
||||
resY = sourceBottomRight.y + gap;
|
||||
break;
|
||||
case St.Side.BOTTOM:
|
||||
resY = sourceAllocation.y1 - natHeight - gap;
|
||||
resY = sourceTopLeft.y - natHeight - gap;
|
||||
break;
|
||||
case St.Side.LEFT:
|
||||
resX = sourceAllocation.x2 + gap;
|
||||
resX = sourceBottomRight.x + gap;
|
||||
break;
|
||||
case St.Side.RIGHT:
|
||||
resX = sourceAllocation.x1 - natWidth - gap;
|
||||
resX = sourceTopLeft.x - natWidth - gap;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -586,29 +587,30 @@ var BoxPointer = GObject.registerClass({
|
||||
}
|
||||
|
||||
_calculateArrowSide(arrowSide) {
|
||||
let sourceAllocation = this._sourceAllocation;
|
||||
let sourceTopLeft = this._sourceExtents.get_top_left();
|
||||
let sourceBottomRight = this._sourceExtents.get_bottom_right();
|
||||
let [, , boxWidth, boxHeight] = this.get_preferred_size();
|
||||
let workarea = this._workArea;
|
||||
|
||||
switch (arrowSide) {
|
||||
case St.Side.TOP:
|
||||
if (sourceAllocation.y2 + boxHeight > workarea.y + workarea.height &&
|
||||
boxHeight < sourceAllocation.y1 - workarea.y)
|
||||
if (sourceBottomRight.y + boxHeight > workarea.y + workarea.height &&
|
||||
boxHeight < sourceTopLeft.y - workarea.y)
|
||||
return St.Side.BOTTOM;
|
||||
break;
|
||||
case St.Side.BOTTOM:
|
||||
if (sourceAllocation.y1 - boxHeight < workarea.y &&
|
||||
boxHeight < workarea.y + workarea.height - sourceAllocation.y2)
|
||||
if (sourceTopLeft.y - boxHeight < workarea.y &&
|
||||
boxHeight < workarea.y + workarea.height - sourceBottomRight.y)
|
||||
return St.Side.TOP;
|
||||
break;
|
||||
case St.Side.LEFT:
|
||||
if (sourceAllocation.x2 + boxWidth > workarea.x + workarea.width &&
|
||||
boxWidth < sourceAllocation.x1 - workarea.x)
|
||||
if (sourceBottomRight.x + boxWidth > workarea.x + workarea.width &&
|
||||
boxWidth < sourceTopLeft.x - workarea.x)
|
||||
return St.Side.RIGHT;
|
||||
break;
|
||||
case St.Side.RIGHT:
|
||||
if (sourceAllocation.x1 - boxWidth < workarea.x &&
|
||||
boxWidth < workarea.x + workarea.width - sourceAllocation.x2)
|
||||
if (sourceTopLeft.x - boxWidth < workarea.x &&
|
||||
boxWidth < workarea.x + workarea.width - sourceBottomRight.x)
|
||||
return St.Side.LEFT;
|
||||
break;
|
||||
}
|
||||
|
11
js/ui/dnd.js
11
js/ui/dnd.js
@ -388,17 +388,16 @@ var _Draggable = class _Draggable {
|
||||
const [, newAllocatedWidth] = this._dragActor.get_preferred_width(-1);
|
||||
const [, newAllocatedHeight] = this._dragActor.get_preferred_height(-1);
|
||||
|
||||
const transformedAllocation =
|
||||
Shell.util_get_transformed_allocation(this._dragActor);
|
||||
const transformedExtents = this._dragActor.get_transformed_extents();
|
||||
|
||||
// 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(
|
||||
transformedAllocation.get_width() / newAllocatedWidth,
|
||||
transformedAllocation.get_height() / newAllocatedHeight);
|
||||
transformedExtents.get_width() / newAllocatedWidth,
|
||||
transformedExtents.get_height() / newAllocatedHeight);
|
||||
|
||||
this._dragOffsetX = transformedAllocation.x1 - this._dragStartX;
|
||||
this._dragOffsetY = transformedAllocation.y1 - this._dragStartY;
|
||||
this._dragOffsetX = transformedExtents.origin.x - this._dragStartX;
|
||||
this._dragOffsetY = transformedExtents.origin.y - 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 } = imports.gi;
|
||||
GLib, GObject, Pango, Polkit, Shell, St, UPowerGlib: UPower } = imports.gi;
|
||||
|
||||
const CheckBox = imports.ui.checkBox;
|
||||
const Dialog = imports.ui.dialog;
|
||||
@ -31,24 +31,30 @@ 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,
|
||||
};
|
||||
|
||||
@ -56,30 +62,36 @@ 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: 'ConfirmedReboot',
|
||||
label: C_("button", "Restart") },
|
||||
{ signal: 'ConfirmedShutdown',
|
||||
label: C_("button", "Power Off") }],
|
||||
confirmButtons: [{
|
||||
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);
|
||||
},
|
||||
showBatteryWarning: false,
|
||||
confirmButtons: [{ signal: 'ConfirmedReboot',
|
||||
label: C_("button", "Restart") }],
|
||||
checkBoxText: C_('checkbox', 'Install pending software updates'),
|
||||
showBatteryWarning: true,
|
||||
confirmButtons: [{
|
||||
signal: 'ConfirmedReboot',
|
||||
label: C_('button', 'Restart'),
|
||||
}],
|
||||
iconName: 'view-refresh-symbolic',
|
||||
showOtherSessions: true,
|
||||
};
|
||||
@ -88,13 +100,16 @@ 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',
|
||||
@ -112,8 +127,10 @@ 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,
|
||||
};
|
||||
@ -142,7 +159,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');
|
||||
const UPowerIface = loadInterfaceXML('org.freedesktop.UPower.Device');
|
||||
const UPowerProxy = Gio.DBusProxy.makeProxyWrapper(UPowerIface);
|
||||
|
||||
function findAppFromInhibitor(inhibitor) {
|
||||
@ -213,6 +230,11 @@ 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;
|
||||
@ -224,7 +246,7 @@ class EndSessionDialog extends ModalDialog.ModalDialog {
|
||||
|
||||
this._powerProxy = new UPowerProxy(Gio.DBus.system,
|
||||
'org.freedesktop.UPower',
|
||||
'/org/freedesktop/UPower',
|
||||
'/org/freedesktop/UPower/devices/DisplayDevice',
|
||||
(proxy, error) => {
|
||||
if (error) {
|
||||
log(error.message);
|
||||
@ -239,6 +261,9 @@ 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));
|
||||
@ -256,7 +281,7 @@ class EndSessionDialog extends ModalDialog.ModalDialog {
|
||||
|
||||
this._batteryWarning = new St.Label({
|
||||
style_class: 'end-session-dialog-battery-warning',
|
||||
text: _('Running on battery power: Please plug in before installing updates.'),
|
||||
text: _('Low battery power: please plug in before installing updates.'),
|
||||
});
|
||||
this._batteryWarning.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
|
||||
this._batteryWarning.clutter_text.line_wrap = true;
|
||||
@ -306,6 +331,32 @@ 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)
|
||||
@ -319,10 +370,7 @@ class EndSessionDialog extends ModalDialog.ModalDialog {
|
||||
if (dialogContent.subjectWithUpdates && this._checkBox.checked)
|
||||
subject = dialogContent.subjectWithUpdates;
|
||||
|
||||
if (dialogContent.showBatteryWarning) {
|
||||
this._batteryWarning.visible =
|
||||
this._powerProxy.OnBattery && this._checkBox.checked;
|
||||
}
|
||||
this._batteryWarning.visible = this._shouldShowLowBatteryWarning(dialogContent);
|
||||
|
||||
let description;
|
||||
let displayTime = _roundSecondsToInterval(this._totalSecondsToStayOpen,
|
||||
@ -363,16 +411,38 @@ class EndSessionDialog extends ModalDialog.ModalDialog {
|
||||
this._sessionSection.visible = hasSessions;
|
||||
}
|
||||
|
||||
_updateButtons() {
|
||||
let dialogContent = DialogContent[this._type];
|
||||
let buttons = [{ action: this.cancel.bind(this),
|
||||
label: _("Cancel"),
|
||||
key: Clutter.KEY_Escape }];
|
||||
_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];
|
||||
for (let i = 0; i < dialogContent.confirmButtons.length; i++) {
|
||||
let signal = dialogContent.confirmButtons[i].signal;
|
||||
let label = dialogContent.confirmButtons[i].label;
|
||||
buttons.push({
|
||||
let button = this.addButton({
|
||||
action: () => {
|
||||
this.close(true);
|
||||
let signalId = this.connect('closed', () => {
|
||||
@ -382,9 +452,34 @@ class EndSessionDialog extends ModalDialog.ModalDialog {
|
||||
},
|
||||
label,
|
||||
});
|
||||
}
|
||||
|
||||
this.setButtons(buttons);
|
||||
// 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;
|
||||
}
|
||||
|
||||
close(skipSignal) {
|
||||
@ -396,14 +491,21 @@ 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);
|
||||
};
|
||||
|
||||
@ -671,19 +773,17 @@ 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 && updatePrepared && updatesAllowed;
|
||||
this._checkBox.checked = this._checkBox.visible;
|
||||
this._checkBox.visible = dialogContent.checkBoxText && this._updateInfo.UpdatePrepared && updatesAllowed;
|
||||
|
||||
// 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);
|
||||
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);
|
||||
|
||||
this._updateButtons();
|
||||
|
||||
|
@ -134,7 +134,14 @@ function _easeActor(actor, params) {
|
||||
actor.set_easing_mode(params.mode);
|
||||
delete params.mode;
|
||||
|
||||
let cleanup = () => Meta.enable_unredirect_for_display(global.display);
|
||||
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 callback = _makeEaseCallback(params, cleanup);
|
||||
|
||||
// cancel overwritten transitions
|
||||
@ -149,9 +156,9 @@ function _easeActor(actor, params) {
|
||||
.find(t => t !== null);
|
||||
|
||||
if (transition && transition.delay)
|
||||
transition.connect('started', () => Meta.disable_unredirect_for_display(global.display));
|
||||
transition.connect('started', () => prepare());
|
||||
else
|
||||
Meta.disable_unredirect_for_display(global.display);
|
||||
prepare();
|
||||
|
||||
if (transition) {
|
||||
transition.set({ repeatCount, autoReverse });
|
||||
@ -191,7 +198,14 @@ function _easeActorProperty(actor, propName, target, params) {
|
||||
if (actor instanceof Clutter.Actor && !actor.mapped)
|
||||
duration = 0;
|
||||
|
||||
let cleanup = () => Meta.enable_unredirect_for_display(global.display);
|
||||
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 callback = _makeEaseCallback(params, cleanup);
|
||||
|
||||
// cancel overwritten transition
|
||||
@ -203,7 +217,7 @@ function _easeActorProperty(actor, propName, target, params) {
|
||||
if (!isReversed)
|
||||
obj[prop] = target;
|
||||
|
||||
Meta.disable_unredirect_for_display(global.display);
|
||||
prepare();
|
||||
callback(true);
|
||||
|
||||
return;
|
||||
@ -222,9 +236,9 @@ function _easeActorProperty(actor, propName, target, params) {
|
||||
transition.set_to(target);
|
||||
|
||||
if (transition.delay)
|
||||
transition.connect('started', () => Meta.disable_unredirect_for_display(global.display));
|
||||
transition.connect('started', () => prepare());
|
||||
else
|
||||
Meta.disable_unredirect_for_display(global.display);
|
||||
prepare();
|
||||
|
||||
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_WHITELIST = ['gnome-control-center.desktop'];
|
||||
const APP_ALLOWLIST = ['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_WHITELIST.includes(this._app.get_id())) {
|
||||
if (this._app && APP_ALLOWLIST.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 },
|
||||
{ label: '⌫', keyval: Clutter.KEY_BackSpace, left: 3, top: 0 },
|
||||
{ keyval: Clutter.KEY_Return, extraClassName: 'enter-key', left: 3, top: 1, height: 2 },
|
||||
{ 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 },
|
||||
];
|
||||
|
||||
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 || "", []);
|
||||
let key = new Key(cur.label || "", [], cur.icon);
|
||||
|
||||
if (keys[i].extraClassName)
|
||||
key.keyButton.add_style_class_name(cur.extraClassName);
|
||||
|
@ -457,6 +457,15 @@ 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();
|
||||
@ -464,7 +473,7 @@ var LayoutManager = GObject.registerClass({
|
||||
this._bgManagers = [];
|
||||
|
||||
if (Main.sessionMode.isGreeter)
|
||||
return;
|
||||
return Promise.resolve();
|
||||
|
||||
for (let i = 0; i < this.monitors.length; i++) {
|
||||
let bgManager = this._createBackgroundManager(i);
|
||||
@ -473,6 +482,8 @@ var LayoutManager = GObject.registerClass({
|
||||
if (i != this.primaryIndex && this._startingUp)
|
||||
bgManager.backgroundActor.hide();
|
||||
}
|
||||
|
||||
return Promise.all(this._bgManagers.map(this._waitLoaded));
|
||||
}
|
||||
|
||||
_updateKeyboardBox() {
|
||||
@ -631,7 +642,7 @@ var LayoutManager = GObject.registerClass({
|
||||
// When starting a normal user session, we want to grow it out of the middle
|
||||
// of the screen.
|
||||
|
||||
_prepareStartupAnimation() {
|
||||
async _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,
|
||||
@ -648,8 +659,6 @@ 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();
|
||||
@ -665,6 +674,8 @@ 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');
|
||||
@ -1217,8 +1228,9 @@ 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, screencastService, uiGroup, magnifier,
|
||||
xdndHandler, keyboard, kbdA11yDialog, introspectService,
|
||||
start, pushModal, popModal, activateWindow, createLookingGlass,
|
||||
initializeDeferredWork, getThemeStylesheet, setThemeStylesheet */
|
||||
screenSaverDBus, 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,7 +34,6 @@ 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;
|
||||
@ -74,7 +73,6 @@ 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 = [];
|
||||
@ -200,7 +198,6 @@ 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,13 +736,11 @@ 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,10 +183,9 @@ var Button = GObject.registerClass({
|
||||
}
|
||||
|
||||
_onDestroy() {
|
||||
super._onDestroy();
|
||||
|
||||
if (this.menu)
|
||||
this.menu.destroy();
|
||||
super._onDestroy();
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -881,9 +881,10 @@ var PopupMenu = class extends PopupMenuBase {
|
||||
|
||||
let state = event.get_state();
|
||||
|
||||
// if user has a modifier down (except capslock)
|
||||
// if user has a modifier down (except capslock and numlock)
|
||||
// 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)
|
||||
@ -1324,7 +1325,7 @@ var PopupMenuManager = class {
|
||||
|
||||
removeMenu(menu) {
|
||||
if (menu == this.activeMenu)
|
||||
this._closeMenu(false, menu);
|
||||
this._grabHelper.ungrab({ actor: menu.actor });
|
||||
|
||||
let position = this._findMenu(menu);
|
||||
if (position == -1) // not a menu we manage
|
||||
|
@ -1,146 +0,0 @@
|
||||
// -*- 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,16 +21,13 @@ 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 a generator function that yields when it want to let the main
|
||||
// as an async function that uses await when it wants to let the main
|
||||
// loop run.
|
||||
//
|
||||
// yield Scripting.sleep(1000);
|
||||
// await Scripting.sleep(1000);
|
||||
// main.overview.show();
|
||||
// yield Scripting.waitLeisure();
|
||||
// await 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:
|
||||
@ -285,13 +282,11 @@ function _collect(scriptModule, outputFile) {
|
||||
}
|
||||
|
||||
async function _runPerfScript(scriptModule, outputFile) {
|
||||
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 {
|
||||
await scriptModule.run();
|
||||
} 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] = {};
|
||||
let propBlacklist = ['unlockDialog'];
|
||||
const excludedProps = ['unlockDialog'];
|
||||
for (let prop in _modes[DEFAULT_MODE]) {
|
||||
if (newMode[prop] !== undefined &&
|
||||
!propBlacklist.includes(prop))
|
||||
!excludedProps.includes(prop))
|
||||
_modes[modeName][prop] = newMode[prop];
|
||||
}
|
||||
_modes[modeName]['isPrimary'] = true;
|
||||
|
@ -15,6 +15,7 @@ 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');
|
||||
@ -82,6 +83,30 @@ 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;
|
||||
@ -539,8 +564,7 @@ var NMDeviceModem = class extends NMConnectionDevice {
|
||||
}
|
||||
|
||||
_autoConnect() {
|
||||
Util.spawn(['gnome-control-center', 'network',
|
||||
'connect-3g', this._device.get_path()]);
|
||||
launchSettingsPanel('network', 'connect-3g', this._device.get_path());
|
||||
}
|
||||
|
||||
destroy() {
|
||||
@ -931,8 +955,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
|
||||
Util.spawn(['gnome-control-center', 'wifi', 'connect-8021x-wifi',
|
||||
this._device.get_path(), accessPoints[0].get_path()]);
|
||||
launchSettingsPanel('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,7 +24,8 @@ class RemoteAccessApplet extends PanelMenu.SystemIndicator {
|
||||
return;
|
||||
|
||||
this._handles = new Set();
|
||||
this._indicator = null;
|
||||
this._sharedIndicator = null;
|
||||
this._recordingIndicator = null;
|
||||
this._menuSection = null;
|
||||
|
||||
controller.connect('new-handle', (o, handle) => {
|
||||
@ -33,32 +34,49 @@ class RemoteAccessApplet extends PanelMenu.SystemIndicator {
|
||||
}
|
||||
|
||||
_ensureControls() {
|
||||
if (this._indicator)
|
||||
if (this._sharedIndicator && this._recordingIndicator)
|
||||
return;
|
||||
|
||||
this._indicator = this._addIndicator();
|
||||
this._indicator.icon_name = 'screen-shared-symbolic';
|
||||
this._indicator.add_style_class_name('remote-access-indicator');
|
||||
this._item =
|
||||
this._sharedIndicator = this._addIndicator();
|
||||
this._sharedIndicator.icon_name = 'screen-shared-symbolic';
|
||||
this._sharedIndicator.add_style_class_name('remote-access-indicator');
|
||||
|
||||
this._sharedItem =
|
||||
new PopupMenu.PopupSubMenuMenuItem(_("Screen is Being Shared"),
|
||||
true);
|
||||
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);
|
||||
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);
|
||||
}
|
||||
|
||||
_sync() {
|
||||
if (this._handles.size == 0) {
|
||||
this._indicator.visible = false;
|
||||
this._item.visible = false;
|
||||
if (this._isScreenShared()) {
|
||||
this._sharedIndicator.visible = true;
|
||||
this._sharedItem.visible = true;
|
||||
} else {
|
||||
this._indicator.visible = true;
|
||||
this._item.visible = true;
|
||||
this._sharedIndicator.visible = false;
|
||||
this._sharedItem.visible = false;
|
||||
}
|
||||
|
||||
this._recordingIndicator.visible = this._isRecording();
|
||||
}
|
||||
|
||||
_onStopped(handle) {
|
||||
@ -70,9 +88,7 @@ class RemoteAccessApplet extends PanelMenu.SystemIndicator {
|
||||
this._handles.add(handle);
|
||||
handle.connect('stopped', this._onStopped.bind(this));
|
||||
|
||||
if (this._handles.size == 1) {
|
||||
this._ensureControls();
|
||||
this._sync();
|
||||
}
|
||||
this._ensureControls();
|
||||
this._sync();
|
||||
}
|
||||
});
|
||||
|
@ -86,6 +86,8 @@ class Indicator extends PanelMenu.SystemIndicator {
|
||||
|
||||
Main.sessionMode.connect('updated', this._sessionUpdated.bind(this));
|
||||
this._sessionUpdated();
|
||||
|
||||
this._sync();
|
||||
}
|
||||
|
||||
_sessionUpdated() {
|
||||
|
@ -1,25 +0,0 @@
|
||||
// -*- 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,6 +27,8 @@ 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
|
||||
@ -52,6 +54,7 @@ class Indicator extends PanelMenu.SystemIndicator {
|
||||
this._loginScreenItem.visible ||
|
||||
this._logoutItem.visible ||
|
||||
this._suspendItem.visible ||
|
||||
this._restartItem.visible ||
|
||||
this._powerOffItem.visible;
|
||||
}
|
||||
|
||||
@ -70,9 +73,8 @@ 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");
|
||||
@ -84,8 +86,8 @@ class Indicator extends PanelMenu.SystemIndicator {
|
||||
let app = this._settingsApp = Shell.AppSystem.get_default().lookup_app(
|
||||
'gnome-control-center.desktop');
|
||||
if (app) {
|
||||
let [icon, name] = [app.app_info.get_icon().names[0],
|
||||
app.get_name()];
|
||||
const [icon] = app.app_info.get_icon().names;
|
||||
const name = app.app_info.get_name();
|
||||
item = new PopupMenu.PopupImageMenuItem(name, icon);
|
||||
item.connect('activate', () => {
|
||||
this.menu.itemActivated(BoxPointer.PopupAnimation.NONE);
|
||||
@ -107,41 +109,14 @@ 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(_("Log Out"));
|
||||
item.connect('activate', () => {
|
||||
this.menu.itemActivated(BoxPointer.PopupAnimation.NONE);
|
||||
this._systemActions.activateLogout();
|
||||
});
|
||||
this._sessionSubMenu.menu.addMenuItem(item);
|
||||
this._logoutItem = item;
|
||||
this._systemActions.bind_property('can-logout',
|
||||
this._logoutItem,
|
||||
'visible',
|
||||
bindFlags);
|
||||
|
||||
item = new PopupMenu.PopupMenuItem(_("Switch User…"));
|
||||
item.connect('activate', () => {
|
||||
this.menu.itemActivated(BoxPointer.PopupAnimation.NONE);
|
||||
this._systemActions.activateSwitchUser();
|
||||
});
|
||||
this._sessionSubMenu.menu.addMenuItem(item);
|
||||
this._loginScreenItem = item;
|
||||
this._systemActions.bind_property('can-switch-user',
|
||||
this._loginScreenItem,
|
||||
'visible',
|
||||
bindFlags);
|
||||
|
||||
this._sessionSubMenu.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
|
||||
|
||||
item = new PopupMenu.PopupMenuItem(_("Suspend"));
|
||||
item = new PopupMenu.PopupMenuItem(_('Suspend'));
|
||||
item.connect('activate', () => {
|
||||
this.menu.itemActivated(BoxPointer.PopupAnimation.NONE);
|
||||
this._systemActions.activateSuspend();
|
||||
@ -149,11 +124,21 @@ class Indicator extends PanelMenu.SystemIndicator {
|
||||
this._sessionSubMenu.menu.addMenuItem(item);
|
||||
this._suspendItem = item;
|
||||
this._systemActions.bind_property('can-suspend',
|
||||
this._suspendItem,
|
||||
'visible',
|
||||
bindFlags);
|
||||
this._suspendItem, 'visible',
|
||||
bindFlags);
|
||||
|
||||
item = new PopupMenu.PopupMenuItem(_("Power Off…"));
|
||||
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();
|
||||
@ -161,9 +146,32 @@ class Indicator extends PanelMenu.SystemIndicator {
|
||||
this._sessionSubMenu.menu.addMenuItem(item);
|
||||
this._powerOffItem = item;
|
||||
this._systemActions.bind_property('can-power-off',
|
||||
this._powerOffItem,
|
||||
'visible',
|
||||
bindFlags);
|
||||
this._powerOffItem, 'visible',
|
||||
bindFlags);
|
||||
|
||||
this._sessionSubMenu.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
|
||||
|
||||
item = new PopupMenu.PopupMenuItem(_('Log Out'));
|
||||
item.connect('activate', () => {
|
||||
this.menu.itemActivated(BoxPointer.PopupAnimation.NONE);
|
||||
this._systemActions.activateLogout();
|
||||
});
|
||||
this._sessionSubMenu.menu.addMenuItem(item);
|
||||
this._logoutItem = item;
|
||||
this._systemActions.bind_property('can-logout',
|
||||
this._logoutItem, 'visible',
|
||||
bindFlags);
|
||||
|
||||
item = new PopupMenu.PopupMenuItem(_('Switch User…'));
|
||||
item.connect('activate', () => {
|
||||
this.menu.itemActivated(BoxPointer.PopupAnimation.NONE);
|
||||
this._systemActions.activateSwitchUser();
|
||||
});
|
||||
this._sessionSubMenu.menu.addMenuItem(item);
|
||||
this._loginScreenItem = item;
|
||||
this._systemActions.bind_property('can-switch-user',
|
||||
this._loginScreenItem, 'visible',
|
||||
bindFlags);
|
||||
|
||||
this.menu.addMenuItem(this._sessionSubMenu);
|
||||
}
|
||||
|
@ -42,6 +42,11 @@ 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) {
|
||||
@ -901,46 +906,23 @@ var WindowManager = class {
|
||||
global.display.connect('init-xserver', (display, task) => {
|
||||
IBusManager.getIBusManager().restartDaemon(['--xim']);
|
||||
|
||||
try {
|
||||
if (!Shell.util_start_systemd_unit('gsd-xsettings.target', 'fail'))
|
||||
log('Not starting gsd-xsettings; waiting for gnome-session to do so');
|
||||
/* 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;
|
||||
});
|
||||
|
||||
/* 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);
|
||||
}
|
||||
this._startX11Services(task, cancellable);
|
||||
|
||||
return true;
|
||||
});
|
||||
global.display.connect('x11-display-closing', () => {
|
||||
if (!Meta.is_wayland_compositor())
|
||||
return;
|
||||
try {
|
||||
Shell.util_stop_systemd_unit('gsd-xsettings.target', 'fail');
|
||||
} catch (e) {
|
||||
log('Error stopping gsd-xsettings: %s'.format(e.message));
|
||||
}
|
||||
|
||||
this._stopX11Services(null);
|
||||
|
||||
IBusManager.getIBusManager().restartDaemon();
|
||||
});
|
||||
|
||||
@ -1008,6 +990,36 @@ var WindowManager = class {
|
||||
global.stage.add_action(topDragAction);
|
||||
}
|
||||
|
||||
async _startX11Services(task, cancellable) {
|
||||
try {
|
||||
await Shell.util_start_systemd_unit(
|
||||
'gnome-session-x11-services-ready.target', 'fail', cancellable);
|
||||
} catch (e) {
|
||||
// Ignore NOT_SUPPORTED error, which indicates we are not systemd
|
||||
// managed and gnome-session will have taken care of everything
|
||||
// already.
|
||||
// Note that we do log cancellation from here.
|
||||
if (!e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.NOT_SUPPORTED))
|
||||
log('Error starting X11 services: %s'.format(e.message));
|
||||
} finally {
|
||||
task.return_boolean(true);
|
||||
}
|
||||
}
|
||||
|
||||
async _stopX11Services(cancellable) {
|
||||
try {
|
||||
await Shell.util_stop_systemd_unit(
|
||||
'gnome-session-x11-services.target', 'fail', cancellable);
|
||||
} catch (e) {
|
||||
// Ignore NOT_SUPPORTED error, which indicates we are not systemd
|
||||
// managed and gnome-session will have taken care of everything
|
||||
// already.
|
||||
// Note that we do log cancellation from here.
|
||||
if (!e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.NOT_SUPPORTED))
|
||||
log('Error stopping X11 services: %s'.format(e.message));
|
||||
}
|
||||
}
|
||||
|
||||
_showPadOsd(display, device, settings, imagePath, editionMode, monitorIndex) {
|
||||
this._currentPadOsd = new PadOsd.PadOsd(device, settings, imagePath, editionMode, monitorIndex);
|
||||
this._currentPadOsd.connect('closed', () => (this._currentPadOsd = null));
|
||||
|
@ -1,5 +1,5 @@
|
||||
project('gnome-shell', 'c',
|
||||
version: '3.37.3',
|
||||
version: '3.37.90',
|
||||
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.3'
|
||||
mutter_req = '>= 3.37.90'
|
||||
polkit_req = '>= 0.100'
|
||||
schemas_req = '>= 3.33.1'
|
||||
startup_req = '>= 0.11'
|
||||
@ -96,9 +96,10 @@ 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()
|
||||
enable_recorder = gst_dep.found() and gst_base_dep.found() and pipewire_dep.found()
|
||||
if enable_recorder
|
||||
recorder_deps += [gst_dep, gst_base_dep, gtk_dep, x11_dep]
|
||||
endif
|
||||
|
@ -1 +1,3 @@
|
||||
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-07-18 13:44+0000\n"
|
||||
"PO-Revision-Date: 2020-07-19 09:46-0300\n"
|
||||
"POT-Creation-Date: 2020-08-10 08:53+0000\n"
|
||||
"PO-Revision-Date: 2020-08-10 08:51-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,92 +237,109 @@ msgstr ""
|
||||
"Habilita uma API de D-Bus que permite introspectar o estado do aplicativo do "
|
||||
"shell."
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:119
|
||||
#: 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
|
||||
msgid "Keybinding to open the application menu"
|
||||
msgstr "Atalho de teclado para abrir um menu de aplicativo"
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:120
|
||||
#: data/org.gnome.shell.gschema.xml.in:131
|
||||
msgid "Keybinding to open the application menu."
|
||||
msgstr "Atalho de teclado para abrir um menu de aplicativo."
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:126
|
||||
#: data/org.gnome.shell.gschema.xml.in:137
|
||||
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:127
|
||||
#: data/org.gnome.shell.gschema.xml.in:138
|
||||
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:134
|
||||
#: data/org.gnome.shell.gschema.xml.in:145
|
||||
msgid "Keybinding to open the overview"
|
||||
msgstr "Atalho de teclado para abrir o panorama"
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:135
|
||||
#: data/org.gnome.shell.gschema.xml.in:146
|
||||
msgid "Keybinding to open the Activities Overview."
|
||||
msgstr "Atalho de teclado para abrir o panorama de atividades."
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:141
|
||||
#: data/org.gnome.shell.gschema.xml.in:152
|
||||
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:142
|
||||
#: data/org.gnome.shell.gschema.xml.in:153
|
||||
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:148
|
||||
#: data/org.gnome.shell.gschema.xml.in:159
|
||||
msgid "Keybinding to focus the active notification"
|
||||
msgstr "Atalho de teclado para ativar a notificação ativa"
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:149
|
||||
#: data/org.gnome.shell.gschema.xml.in:160
|
||||
msgid "Keybinding to focus the active notification."
|
||||
msgstr "Atalho de teclado para ativar a notificação ativa."
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:155
|
||||
#: data/org.gnome.shell.gschema.xml.in:166
|
||||
msgid "Switch to application 1"
|
||||
msgstr "Alternar para o aplicativo 1"
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:159
|
||||
#: data/org.gnome.shell.gschema.xml.in:170
|
||||
msgid "Switch to application 2"
|
||||
msgstr "Alternar para o aplicativo 2"
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:163
|
||||
#: data/org.gnome.shell.gschema.xml.in:174
|
||||
msgid "Switch to application 3"
|
||||
msgstr "Alternar para o aplicativo 3"
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:167
|
||||
#: data/org.gnome.shell.gschema.xml.in:178
|
||||
msgid "Switch to application 4"
|
||||
msgstr "Alternar para o aplicativo 4"
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:171
|
||||
#: data/org.gnome.shell.gschema.xml.in:182
|
||||
msgid "Switch to application 5"
|
||||
msgstr "Alternar para o aplicativo 5"
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:175
|
||||
#: data/org.gnome.shell.gschema.xml.in:186
|
||||
msgid "Switch to application 6"
|
||||
msgstr "Alternar para o aplicativo 6"
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:179
|
||||
#: data/org.gnome.shell.gschema.xml.in:190
|
||||
msgid "Switch to application 7"
|
||||
msgstr "Alternar para o aplicativo 7"
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:183
|
||||
#: data/org.gnome.shell.gschema.xml.in:194
|
||||
msgid "Switch to application 8"
|
||||
msgstr "Alternar para o aplicativo 8"
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:187
|
||||
#: data/org.gnome.shell.gschema.xml.in:198
|
||||
msgid "Switch to application 9"
|
||||
msgstr "Alternar para o aplicativo 9"
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:196
|
||||
#: data/org.gnome.shell.gschema.xml.in:223
|
||||
#: data/org.gnome.shell.gschema.xml.in:207
|
||||
#: data/org.gnome.shell.gschema.xml.in:234
|
||||
msgid "Limit switcher to current workspace."
|
||||
msgstr "Limitar o alternador ao espaço de trabalho atual."
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:197
|
||||
#: data/org.gnome.shell.gschema.xml.in:208
|
||||
msgid ""
|
||||
"If true, only applications that have windows on the current workspace are "
|
||||
"shown in the switcher. Otherwise, all applications are included."
|
||||
@ -331,11 +348,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:214
|
||||
#: data/org.gnome.shell.gschema.xml.in:225
|
||||
msgid "The application icon mode."
|
||||
msgstr "O modo ícone do aplicativo."
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:215
|
||||
#: data/org.gnome.shell.gschema.xml.in:226
|
||||
msgid ""
|
||||
"Configures how the windows are shown in the switcher. Valid possibilities "
|
||||
"are “thumbnail-only” (shows a thumbnail of the window), “app-icon-"
|
||||
@ -345,7 +362,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:224
|
||||
#: data/org.gnome.shell.gschema.xml.in:235
|
||||
msgid ""
|
||||
"If true, only windows from the current workspace are shown in the switcher. "
|
||||
"Otherwise, all windows are included."
|
||||
@ -353,58 +370,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:234
|
||||
#: data/org.gnome.shell.gschema.xml.in:245
|
||||
msgid "Locations"
|
||||
msgstr "Localizações"
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:235
|
||||
#: data/org.gnome.shell.gschema.xml.in:246
|
||||
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:245
|
||||
#: data/org.gnome.shell.gschema.xml.in:256
|
||||
msgid "Automatic location"
|
||||
msgstr "Localização automática"
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:246
|
||||
#: data/org.gnome.shell.gschema.xml.in:257
|
||||
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:253
|
||||
#: data/org.gnome.shell.gschema.xml.in:264
|
||||
msgid "Location"
|
||||
msgstr "Localização"
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:254
|
||||
#: data/org.gnome.shell.gschema.xml.in:265
|
||||
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:266
|
||||
#: data/org.gnome.shell.gschema.xml.in:277
|
||||
msgid "Attach modal dialog to the parent window"
|
||||
msgstr "Anexar diálogo modal à janela pai"
|
||||
|
||||
#: 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
|
||||
#: 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
|
||||
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:275
|
||||
#: data/org.gnome.shell.gschema.xml.in:286
|
||||
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:283
|
||||
#: data/org.gnome.shell.gschema.xml.in:294
|
||||
msgid "Workspaces are managed dynamically"
|
||||
msgstr "Espaços de trabalho são gerenciados dinamicamente"
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:291
|
||||
#: data/org.gnome.shell.gschema.xml.in:302
|
||||
msgid "Workspaces only on primary monitor"
|
||||
msgstr "Espaços de trabalho apenas no monitor primário"
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:299
|
||||
#: data/org.gnome.shell.gschema.xml.in:310
|
||||
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"
|
||||
|
||||
@ -441,9 +458,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:369 js/ui/extensionDownloader.js:183
|
||||
#: js/ui/endSessionDialog.js:398 js/ui/extensionDownloader.js:183
|
||||
#: js/ui/shellMountOperation.js:376 js/ui/shellMountOperation.js:386
|
||||
#: js/ui/status/network.js:916 subprojects/extensions-app/js/main.js:149
|
||||
#: js/ui/status/network.js:940 subprojects/extensions-app/js/main.js:149
|
||||
msgid "Cancel"
|
||||
msgstr "Cancelar"
|
||||
|
||||
@ -479,7 +496,7 @@ msgstr "(ex.: usuário ou %s)"
|
||||
msgid "Username"
|
||||
msgstr "Nome de usuário"
|
||||
|
||||
#: js/gdm/loginDialog.js:1254
|
||||
#: js/gdm/loginDialog.js:1253
|
||||
msgid "Login Window"
|
||||
msgstr "Janela de sessão"
|
||||
|
||||
@ -727,38 +744,36 @@ msgstr "Negar acesso"
|
||||
msgid "Grant Access"
|
||||
msgstr "Conceder acesso"
|
||||
|
||||
#: js/ui/appDisplay.js:903
|
||||
#: js/ui/appDisplay.js:1297
|
||||
msgid "Unnamed Folder"
|
||||
msgstr "Pasta sem nome"
|
||||
|
||||
#. Translators: This is the heading of a list of open windows
|
||||
#: js/ui/appDisplay.js:2225 js/ui/panel.js:75
|
||||
#: js/ui/appDisplay.js:2762 js/ui/panel.js:75
|
||||
msgid "Open Windows"
|
||||
msgstr "Janelas abertas"
|
||||
|
||||
#: js/ui/appDisplay.js:2244 js/ui/panel.js:82
|
||||
#: js/ui/appDisplay.js:2781 js/ui/panel.js:82
|
||||
msgid "New Window"
|
||||
msgstr "Nova janela"
|
||||
|
||||
#: js/ui/appDisplay.js:2260
|
||||
#| msgid "Launch using Dedicated Graphics Card"
|
||||
#: js/ui/appDisplay.js:2797
|
||||
msgid "Launch using Integrated Graphics Card"
|
||||
msgstr "Iniciar usando placa de vídeo integrada"
|
||||
|
||||
#: js/ui/appDisplay.js:2261
|
||||
#| msgid "Launch using Dedicated Graphics Card"
|
||||
#: js/ui/appDisplay.js:2798
|
||||
msgid "Launch using Discrete Graphics Card"
|
||||
msgstr "Iniciar usando placa de vídeo dedicada"
|
||||
|
||||
#: js/ui/appDisplay.js:2289 js/ui/dash.js:239
|
||||
#: js/ui/appDisplay.js:2826 js/ui/dash.js:239
|
||||
msgid "Remove from Favorites"
|
||||
msgstr "Remover dos favoritos"
|
||||
|
||||
#: js/ui/appDisplay.js:2295
|
||||
#: js/ui/appDisplay.js:2832
|
||||
msgid "Add to Favorites"
|
||||
msgstr "Adicionar aos favoritos"
|
||||
|
||||
#: js/ui/appDisplay.js:2305 js/ui/panel.js:93
|
||||
#: js/ui/appDisplay.js:2842 js/ui/panel.js:93
|
||||
msgid "Show Details"
|
||||
msgstr "Mostrar detalhes"
|
||||
|
||||
@ -959,8 +974,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:227
|
||||
#: js/ui/status/network.js:318 js/ui/status/network.js:919
|
||||
#: js/ui/components/networkAgent.js:104 js/ui/status/network.js:252
|
||||
#: js/ui/status/network.js:343 js/ui/status/network.js:943
|
||||
msgid "Connect"
|
||||
msgstr "Conectar"
|
||||
|
||||
@ -1025,7 +1040,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:1694
|
||||
#: js/ui/components/networkAgent.js:669 js/ui/status/network.js:1718
|
||||
msgid "Network Manager"
|
||||
msgstr "Gerenciador de rede"
|
||||
|
||||
@ -1093,14 +1108,12 @@ 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"
|
||||
@ -1150,7 +1163,6 @@ msgid "Weather"
|
||||
msgstr "Meteorologia"
|
||||
|
||||
#: js/ui/dateMenu.js:653
|
||||
#| msgid "Select a location…"
|
||||
msgid "Select weather location…"
|
||||
msgstr "Selecione uma localização meteorológica…"
|
||||
|
||||
@ -1278,27 +1290,32 @@ 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:259
|
||||
#: js/ui/endSessionDialog.js:267
|
||||
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:268
|
||||
#: js/ui/endSessionDialog.js:276
|
||||
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:273
|
||||
#: js/ui/endSessionDialog.js:281
|
||||
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:583
|
||||
#: js/ui/endSessionDialog.js:645
|
||||
#, javascript-format
|
||||
msgid "%s (remote)"
|
||||
msgstr "%s (remoto)"
|
||||
|
||||
#. Translators: Console here refers to a tty like a VT console
|
||||
#: js/ui/endSessionDialog.js:586
|
||||
#: js/ui/endSessionDialog.js:648
|
||||
#, javascript-format
|
||||
msgid "%s (console)"
|
||||
msgstr "%s (console)"
|
||||
@ -1401,15 +1418,15 @@ msgid "Leave On"
|
||||
msgstr "Deixar ativado"
|
||||
|
||||
#: js/ui/kbdA11yDialog.js:55 js/ui/status/bluetooth.js:156
|
||||
#: js/ui/status/network.js:1291
|
||||
#: js/ui/status/network.js:1315
|
||||
msgid "Turn On"
|
||||
msgstr "Ligar"
|
||||
|
||||
#: js/ui/kbdA11yDialog.js:63 js/ui/status/bluetooth.js:156
|
||||
#: 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/network.js:160 js/ui/status/network.js:344
|
||||
#: js/ui/status/network.js:1315 js/ui/status/network.js:1427
|
||||
#: js/ui/status/nightLight.js:41 js/ui/status/rfkill.js:81
|
||||
#: js/ui/status/rfkill.js:108
|
||||
#: js/ui/status/rfkill.js:110
|
||||
msgid "Turn Off"
|
||||
msgstr "Desligar"
|
||||
|
||||
@ -1470,11 +1487,11 @@ msgstr "Ver fonte"
|
||||
msgid "Web Page"
|
||||
msgstr "Página web"
|
||||
|
||||
#: js/ui/main.js:297
|
||||
#: js/ui/main.js:294
|
||||
msgid "Logged in as a privileged user"
|
||||
msgstr "Sessão aberta como um usuário privilegiado"
|
||||
|
||||
#: js/ui/main.js:298
|
||||
#: js/ui/main.js:295
|
||||
msgid ""
|
||||
"Running a session as a privileged user should be avoided for security "
|
||||
"reasons. If possible, you should log in as a normal user."
|
||||
@ -1482,11 +1499,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:337
|
||||
#: js/ui/main.js:334
|
||||
msgid "Screen Lock disabled"
|
||||
msgstr "Bloqueio de tela desabilitado"
|
||||
|
||||
#: js/ui/main.js:338
|
||||
#: js/ui/main.js:335
|
||||
msgid "Screen Locking requires the GNOME display manager."
|
||||
msgstr "O bloqueio de tela requer o gerenciador de exibição do GNOME."
|
||||
|
||||
@ -1579,7 +1596,7 @@ msgctxt "System menu in the top bar"
|
||||
msgid "System"
|
||||
msgstr "Sistema"
|
||||
|
||||
#: js/ui/panel.js:827
|
||||
#: js/ui/panel.js:825
|
||||
msgid "Top Bar"
|
||||
msgstr "Barra superior"
|
||||
|
||||
@ -1756,17 +1773,15 @@ msgstr "Texto grande"
|
||||
msgid "Bluetooth"
|
||||
msgstr "Bluetooth"
|
||||
|
||||
#: js/ui/status/bluetooth.js:49 js/ui/status/network.js:595
|
||||
#: js/ui/status/bluetooth.js:49 js/ui/status/network.js:619
|
||||
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"
|
||||
|
||||
@ -1842,18 +1857,18 @@ msgstr ""
|
||||
"Acesso a localização pode ser alterado a qualquer momento nas configurações "
|
||||
"de privacidade."
|
||||
|
||||
#: js/ui/status/network.js:70
|
||||
#: js/ui/status/network.js:71
|
||||
msgid "<unknown>"
|
||||
msgstr "<desconhecido>"
|
||||
|
||||
#. Translators: %s is a network identifier
|
||||
#: js/ui/status/network.js:424 js/ui/status/network.js:1320
|
||||
#: js/ui/status/network.js:449 js/ui/status/network.js:1344
|
||||
#, javascript-format
|
||||
msgid "%s Off"
|
||||
msgstr "%s desligada"
|
||||
|
||||
#. Translators: %s is a network identifier
|
||||
#: js/ui/status/network.js:427
|
||||
#: js/ui/status/network.js:452
|
||||
#, javascript-format
|
||||
msgid "%s Connected"
|
||||
msgstr "Conectado à %s"
|
||||
@ -1862,189 +1877,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:432
|
||||
#: js/ui/status/network.js:457
|
||||
#, javascript-format
|
||||
msgid "%s Unmanaged"
|
||||
msgstr "%s não é gerenciável"
|
||||
|
||||
#. Translators: %s is a network identifier
|
||||
#: js/ui/status/network.js:435
|
||||
#: js/ui/status/network.js:460
|
||||
#, javascript-format
|
||||
msgid "%s Disconnecting"
|
||||
msgstr "Desconectando de %s"
|
||||
|
||||
#. Translators: %s is a network identifier
|
||||
#: js/ui/status/network.js:442 js/ui/status/network.js:1312
|
||||
#: js/ui/status/network.js:467 js/ui/status/network.js:1336
|
||||
#, 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:445
|
||||
#: js/ui/status/network.js:470
|
||||
#, 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:453
|
||||
#: js/ui/status/network.js:478
|
||||
#, 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:457
|
||||
#: js/ui/status/network.js:482
|
||||
#, javascript-format
|
||||
msgid "%s Unavailable"
|
||||
msgstr "%s está indisponível"
|
||||
|
||||
#. Translators: %s is a network identifier
|
||||
#: js/ui/status/network.js:460
|
||||
#: js/ui/status/network.js:485
|
||||
#, javascript-format
|
||||
msgid "%s Connection Failed"
|
||||
msgstr "Falha na conexão de %s"
|
||||
|
||||
#: js/ui/status/network.js:472
|
||||
#: js/ui/status/network.js:497
|
||||
msgid "Wired Settings"
|
||||
msgstr "Configurações da rede cabeada"
|
||||
|
||||
#: js/ui/status/network.js:515
|
||||
#: js/ui/status/network.js:540
|
||||
msgid "Mobile Broadband Settings"
|
||||
msgstr "Configurações de banda larga móvel"
|
||||
|
||||
#. Translators: %s is a network identifier
|
||||
#: js/ui/status/network.js:562 js/ui/status/network.js:1317
|
||||
#: js/ui/status/network.js:586 js/ui/status/network.js:1341
|
||||
#, 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:566
|
||||
#: js/ui/status/network.js:590
|
||||
#, javascript-format
|
||||
msgid "%s Disabled"
|
||||
msgstr "%s está desabilitado"
|
||||
|
||||
#: js/ui/status/network.js:607
|
||||
#: js/ui/status/network.js:631
|
||||
msgid "Connect to Internet"
|
||||
msgstr "Conectar à Internet"
|
||||
|
||||
#: js/ui/status/network.js:811
|
||||
#: js/ui/status/network.js:835
|
||||
msgid "Airplane Mode is On"
|
||||
msgstr "Modo avião ligado"
|
||||
|
||||
#: js/ui/status/network.js:812
|
||||
#: js/ui/status/network.js:836
|
||||
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:813
|
||||
#: js/ui/status/network.js:837
|
||||
msgid "Turn Off Airplane Mode"
|
||||
msgstr "Desligar modo avião"
|
||||
|
||||
#: js/ui/status/network.js:822
|
||||
#: js/ui/status/network.js:846
|
||||
msgid "Wi-Fi is Off"
|
||||
msgstr "Wi-Fi desligado"
|
||||
|
||||
#: js/ui/status/network.js:823
|
||||
#: js/ui/status/network.js:847
|
||||
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:824
|
||||
#: js/ui/status/network.js:848
|
||||
msgid "Turn On Wi-Fi"
|
||||
msgstr "Ligar Wi-Fi"
|
||||
|
||||
#: js/ui/status/network.js:849
|
||||
#: js/ui/status/network.js:873
|
||||
msgid "Wi-Fi Networks"
|
||||
msgstr "Redes Wi-Fi"
|
||||
|
||||
#: js/ui/status/network.js:851
|
||||
#: js/ui/status/network.js:875
|
||||
msgid "Select a network"
|
||||
msgstr "Selecione uma rede"
|
||||
|
||||
#: js/ui/status/network.js:883
|
||||
#: js/ui/status/network.js:907
|
||||
msgid "No Networks"
|
||||
msgstr "Nenhuma rede"
|
||||
|
||||
#: js/ui/status/network.js:904 js/ui/status/rfkill.js:106
|
||||
#: js/ui/status/network.js:928 js/ui/status/rfkill.js:108
|
||||
msgid "Use hardware switch to turn off"
|
||||
msgstr "Usar alternador de hardware para desligar"
|
||||
|
||||
#: js/ui/status/network.js:1181
|
||||
#: js/ui/status/network.js:1205
|
||||
msgid "Select Network"
|
||||
msgstr "Selecione a rede"
|
||||
|
||||
#: js/ui/status/network.js:1187
|
||||
#: js/ui/status/network.js:1211
|
||||
msgid "Wi-Fi Settings"
|
||||
msgstr "Configurações de Wi-Fi"
|
||||
|
||||
#. Translators: %s is a network identifier
|
||||
#: js/ui/status/network.js:1308
|
||||
#: js/ui/status/network.js:1332
|
||||
#, javascript-format
|
||||
msgid "%s Hotspot Active"
|
||||
msgstr "Ponto de acesso %s está ativo"
|
||||
|
||||
#. Translators: %s is a network identifier
|
||||
#: js/ui/status/network.js:1323
|
||||
#: js/ui/status/network.js:1347
|
||||
#, javascript-format
|
||||
msgid "%s Not Connected"
|
||||
msgstr "%s não está conectado"
|
||||
|
||||
#: js/ui/status/network.js:1420
|
||||
#: js/ui/status/network.js:1444
|
||||
msgid "connecting…"
|
||||
msgstr "conectando…"
|
||||
|
||||
#. Translators: this is for network connections that require some kind of key or password
|
||||
#: js/ui/status/network.js:1423
|
||||
#: js/ui/status/network.js:1447
|
||||
msgid "authentication required"
|
||||
msgstr "autenticação necessária"
|
||||
|
||||
#: js/ui/status/network.js:1425
|
||||
#: js/ui/status/network.js:1449
|
||||
msgid "connection failed"
|
||||
msgstr "conexão falhou"
|
||||
|
||||
#: js/ui/status/network.js:1476
|
||||
#: js/ui/status/network.js:1500
|
||||
msgid "VPN Settings"
|
||||
msgstr "Configurações de VPN"
|
||||
|
||||
#: js/ui/status/network.js:1493
|
||||
#: js/ui/status/network.js:1517
|
||||
msgid "VPN"
|
||||
msgstr "VPN"
|
||||
|
||||
#: js/ui/status/network.js:1503
|
||||
#: js/ui/status/network.js:1527
|
||||
msgid "VPN Off"
|
||||
msgstr "VPN desligada"
|
||||
|
||||
#: js/ui/status/network.js:1564 js/ui/status/rfkill.js:84
|
||||
#: js/ui/status/network.js:1588 js/ui/status/rfkill.js:84
|
||||
msgid "Network Settings"
|
||||
msgstr "Configurações de rede"
|
||||
|
||||
#: js/ui/status/network.js:1593
|
||||
#: js/ui/status/network.js:1617
|
||||
#, 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:1597
|
||||
#: js/ui/status/network.js:1621
|
||||
#, 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:1601
|
||||
#: js/ui/status/network.js:1625
|
||||
#, 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:1735
|
||||
#: js/ui/status/network.js:1759
|
||||
msgid "Connection failed"
|
||||
msgstr "Falha de conexão"
|
||||
|
||||
#: js/ui/status/network.js:1736
|
||||
#: js/ui/status/network.js:1760
|
||||
msgid "Activation of network connection failed"
|
||||
msgstr "Falha ao ativar a conexão da rede"
|
||||
|
||||
@ -2099,11 +2114,11 @@ msgstr "%d:%02d até completar (%d %%)"
|
||||
msgid "%d %%"
|
||||
msgstr "%d %%"
|
||||
|
||||
#: js/ui/status/remoteAccess.js:43
|
||||
#: js/ui/status/remoteAccess.js:45
|
||||
msgid "Screen is Being Shared"
|
||||
msgstr "A tela está sendo compartilhada"
|
||||
|
||||
#: js/ui/status/remoteAccess.js:45
|
||||
#: js/ui/status/remoteAccess.js:47
|
||||
msgid "Turn off"
|
||||
msgstr "Desativar"
|
||||
|
||||
@ -2248,22 +2263,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:55
|
||||
#: js/ui/windowManager.js:60
|
||||
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:64
|
||||
#: js/ui/windowManager.js:69
|
||||
msgid "Revert Settings"
|
||||
msgstr "Reverter configurações"
|
||||
|
||||
#: js/ui/windowManager.js:67
|
||||
#: js/ui/windowManager.js:72
|
||||
msgid "Keep Changes"
|
||||
msgstr "Manter alterações"
|
||||
|
||||
#: js/ui/windowManager.js:86
|
||||
#: js/ui/windowManager.js:91
|
||||
#, javascript-format
|
||||
msgid "Settings changes will revert in %d second"
|
||||
msgid_plural "Settings changes will revert in %d seconds"
|
||||
@ -2272,7 +2287,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:546
|
||||
#: js/ui/windowManager.js:551
|
||||
#, javascript-format
|
||||
msgid "%d × %d"
|
||||
msgstr "%d × %d"
|
||||
@ -2450,7 +2465,6 @@ 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"
|
||||
|
||||
@ -2607,7 +2621,6 @@ 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"
|
||||
|
||||
@ -2784,7 +2797,6 @@ 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"
|
||||
|
||||
@ -2797,13 +2809,11 @@ 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"
|
||||
|
||||
@ -2916,7 +2926,6 @@ 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-07-20 16:18+0000\n"
|
||||
"PO-Revision-Date: 2020-07-21 08:42+0300\n"
|
||||
"POT-Creation-Date: 2020-08-10 23:58+0000\n"
|
||||
"PO-Revision-Date: 2020-08-11 09:23+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:369 js/ui/extensionDownloader.js:183
|
||||
#: js/ui/endSessionDialog.js:438 js/ui/extensionDownloader.js:183
|
||||
#: js/ui/shellMountOperation.js:376 js/ui/shellMountOperation.js:386
|
||||
#: js/ui/status/network.js:916 subprojects/extensions-app/js/main.js:149
|
||||
#: js/ui/status/network.js:940 subprojects/extensions-app/js/main.js:149
|
||||
msgid "Cancel"
|
||||
msgstr "Скасувати"
|
||||
|
||||
@ -469,7 +469,7 @@ msgstr "(наприклад, користувач або %s)"
|
||||
msgid "Username"
|
||||
msgstr "Користувач"
|
||||
|
||||
#: js/gdm/loginDialog.js:1254
|
||||
#: js/gdm/loginDialog.js:1253
|
||||
msgid "Login Window"
|
||||
msgstr "Вікно входу"
|
||||
|
||||
@ -487,73 +487,84 @@ msgid "(or swipe finger)"
|
||||
msgstr "(або проведіть пальцем)"
|
||||
|
||||
#. Translators: The name of the power-off action in search
|
||||
#: js/misc/systemActions.js:93
|
||||
#: js/misc/systemActions.js:91
|
||||
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:96
|
||||
msgid "power off;shutdown;reboot;restart;halt;stop"
|
||||
msgstr "вимкнути;перезавантажити;power off;shutdown;reboot;restart;halt;stop"
|
||||
#: 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;перезавантаження;перезапуск;"
|
||||
|
||||
#. Translators: The name of the lock screen action in search
|
||||
#: js/misc/systemActions.js:101
|
||||
#: js/misc/systemActions.js:107
|
||||
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:104
|
||||
#: js/misc/systemActions.js:110
|
||||
msgid "lock screen"
|
||||
msgstr "заблокувати екран;lock screen"
|
||||
|
||||
#. Translators: The name of the logout action in search
|
||||
#: js/misc/systemActions.js:109
|
||||
#: js/misc/systemActions.js:115
|
||||
msgctxt "search-result"
|
||||
msgid "Log Out"
|
||||
msgstr "Вийти"
|
||||
|
||||
#. Translators: A list of keywords that match the logout action, separated by semicolons
|
||||
#: js/misc/systemActions.js:112
|
||||
#: js/misc/systemActions.js:118
|
||||
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:117
|
||||
#: js/misc/systemActions.js:123
|
||||
msgctxt "search-result"
|
||||
msgid "Suspend"
|
||||
msgstr "Призупинити"
|
||||
|
||||
#. Translators: A list of keywords that match the suspend action, separated by semicolons
|
||||
#: js/misc/systemActions.js:120
|
||||
#: js/misc/systemActions.js:126
|
||||
msgid "suspend;sleep"
|
||||
msgstr "призупинити;сон;suspend;sleep"
|
||||
|
||||
#. Translators: The name of the switch user action in search
|
||||
#: js/misc/systemActions.js:125
|
||||
#: js/misc/systemActions.js:131
|
||||
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:128
|
||||
#: js/misc/systemActions.js:134
|
||||
msgid "switch user"
|
||||
msgstr "змінити користувача;перемкнути;switch user"
|
||||
|
||||
#. Translators: A list of keywords that match the lock orientation action, separated by semicolons
|
||||
#: js/misc/systemActions.js:135
|
||||
#: js/misc/systemActions.js:141
|
||||
msgid "lock orientation;unlock orientation;screen;rotation"
|
||||
msgstr ""
|
||||
"заблокувати орієнтацію;розблокувати орієнтацію;екран;обертання;lock "
|
||||
"orientation;unlock orientation;screen;rotation"
|
||||
|
||||
#: js/misc/systemActions.js:255
|
||||
#: js/misc/systemActions.js:266
|
||||
msgctxt "search-result"
|
||||
msgid "Unlock Screen Rotation"
|
||||
msgstr "Розблокувати обертання екрана"
|
||||
|
||||
#: js/misc/systemActions.js:256
|
||||
#: js/misc/systemActions.js:267
|
||||
msgctxt "search-result"
|
||||
msgid "Lock Screen Rotation"
|
||||
msgstr "Заблокувати обертання екрана"
|
||||
@ -735,31 +746,31 @@ msgid "Unnamed Folder"
|
||||
msgstr "Неназвана тека"
|
||||
|
||||
#. Translators: This is the heading of a list of open windows
|
||||
#: js/ui/appDisplay.js:2767 js/ui/panel.js:75
|
||||
#: js/ui/appDisplay.js:2762 js/ui/panel.js:75
|
||||
msgid "Open Windows"
|
||||
msgstr "Відкрити вікна"
|
||||
|
||||
#: js/ui/appDisplay.js:2786 js/ui/panel.js:82
|
||||
#: js/ui/appDisplay.js:2781 js/ui/panel.js:82
|
||||
msgid "New Window"
|
||||
msgstr "Нове вікно"
|
||||
|
||||
#: js/ui/appDisplay.js:2802
|
||||
#: js/ui/appDisplay.js:2797
|
||||
msgid "Launch using Integrated Graphics Card"
|
||||
msgstr "Запустити через інтегровану графічну плату"
|
||||
|
||||
#: js/ui/appDisplay.js:2803
|
||||
#: js/ui/appDisplay.js:2798
|
||||
msgid "Launch using Discrete Graphics Card"
|
||||
msgstr "Запустити через дискретну графічну плату"
|
||||
|
||||
#: js/ui/appDisplay.js:2831 js/ui/dash.js:239
|
||||
#: js/ui/appDisplay.js:2826 js/ui/dash.js:239
|
||||
msgid "Remove from Favorites"
|
||||
msgstr "Вилучити з улюбленого"
|
||||
|
||||
#: js/ui/appDisplay.js:2837
|
||||
#: js/ui/appDisplay.js:2832
|
||||
msgid "Add to Favorites"
|
||||
msgstr "Додати до улюбленого"
|
||||
|
||||
#: js/ui/appDisplay.js:2847 js/ui/panel.js:93
|
||||
#: js/ui/appDisplay.js:2842 js/ui/panel.js:93
|
||||
msgid "Show Details"
|
||||
msgstr "Показати подробиці"
|
||||
|
||||
@ -958,8 +969,8 @@ msgid ""
|
||||
msgstr ""
|
||||
"Також можете під'єднатися, натиснувши кнопку «WPS» на вашому маршрутизаторі."
|
||||
|
||||
#: js/ui/components/networkAgent.js:104 js/ui/status/network.js:227
|
||||
#: js/ui/status/network.js:318 js/ui/status/network.js:919
|
||||
#: js/ui/components/networkAgent.js:104 js/ui/status/network.js:252
|
||||
#: js/ui/status/network.js:343 js/ui/status/network.js:943
|
||||
msgid "Connect"
|
||||
msgstr "З'єднатись"
|
||||
|
||||
@ -1022,7 +1033,7 @@ msgstr "Пін-код"
|
||||
msgid "A password is required to connect to “%s”."
|
||||
msgstr "Пароль потрібен для з'єднання з «%s»."
|
||||
|
||||
#: js/ui/components/networkAgent.js:669 js/ui/status/network.js:1694
|
||||
#: js/ui/components/networkAgent.js:669 js/ui/status/network.js:1718
|
||||
msgid "Network Manager"
|
||||
msgstr "Керування мережею"
|
||||
|
||||
@ -1148,18 +1159,18 @@ msgstr "Погода"
|
||||
msgid "Select weather location…"
|
||||
msgstr "Виберіть місцевість для погоди…"
|
||||
|
||||
#: js/ui/endSessionDialog.js:37
|
||||
#: js/ui/endSessionDialog.js:39
|
||||
#, javascript-format
|
||||
msgctxt "title"
|
||||
msgid "Log Out %s"
|
||||
msgstr "Завершити сеанс %s"
|
||||
|
||||
#: js/ui/endSessionDialog.js:38
|
||||
#: js/ui/endSessionDialog.js:40
|
||||
msgctxt "title"
|
||||
msgid "Log Out"
|
||||
msgstr "Завершити сеанс"
|
||||
|
||||
#: js/ui/endSessionDialog.js:40
|
||||
#: js/ui/endSessionDialog.js:43
|
||||
#, javascript-format
|
||||
msgid "%s will be logged out automatically in %d second."
|
||||
msgid_plural "%s will be logged out automatically in %d seconds."
|
||||
@ -1168,7 +1179,7 @@ msgstr[1] "%s вийде автоматично через %d секунди."
|
||||
msgstr[2] "%s вийде автоматично через %d секунд."
|
||||
msgstr[3] "%s вийде автоматично через %d секунду."
|
||||
|
||||
#: js/ui/endSessionDialog.js:45
|
||||
#: js/ui/endSessionDialog.js:49
|
||||
#, javascript-format
|
||||
msgid "You will be logged out automatically in %d second."
|
||||
msgid_plural "You will be logged out automatically in %d seconds."
|
||||
@ -1177,22 +1188,22 @@ msgstr[1] "Вихід автоматично через %d секунди."
|
||||
msgstr[2] "Вихід автоматично через %d секунд."
|
||||
msgstr[3] "Вихід автоматично через %d секунду."
|
||||
|
||||
#: js/ui/endSessionDialog.js:51
|
||||
#: js/ui/endSessionDialog.js:56
|
||||
msgctxt "button"
|
||||
msgid "Log Out"
|
||||
msgstr "Вийти"
|
||||
|
||||
#: js/ui/endSessionDialog.js:56
|
||||
#: js/ui/endSessionDialog.js:62
|
||||
msgctxt "title"
|
||||
msgid "Power Off"
|
||||
msgstr "Вимкнути"
|
||||
|
||||
#: js/ui/endSessionDialog.js:57
|
||||
#: js/ui/endSessionDialog.js:63
|
||||
msgctxt "title"
|
||||
msgid "Install Updates & Power Off"
|
||||
msgstr "Установити оновлення і вимкнути"
|
||||
|
||||
#: js/ui/endSessionDialog.js:59
|
||||
#: js/ui/endSessionDialog.js:66
|
||||
#, javascript-format
|
||||
msgid "The system will power off automatically in %d second."
|
||||
msgid_plural "The system will power off automatically in %d seconds."
|
||||
@ -1201,27 +1212,27 @@ msgstr[1] "Система автоматично вимкнеться через
|
||||
msgstr[2] "Система автоматично вимкнеться через %d секунд."
|
||||
msgstr[3] "Система автоматично вимкнеться через %d секунду."
|
||||
|
||||
#: js/ui/endSessionDialog.js:63
|
||||
#: js/ui/endSessionDialog.js:70 js/ui/endSessionDialog.js:89
|
||||
msgctxt "checkbox"
|
||||
msgid "Install pending software updates"
|
||||
msgstr "Установити оновлення, які в черзі"
|
||||
|
||||
#: js/ui/endSessionDialog.js:66 js/ui/endSessionDialog.js:82
|
||||
msgctxt "button"
|
||||
msgid "Restart"
|
||||
msgstr "Перезапустити"
|
||||
|
||||
#: js/ui/endSessionDialog.js:68
|
||||
#: js/ui/endSessionDialog.js:74
|
||||
msgctxt "button"
|
||||
msgid "Power Off"
|
||||
msgstr "Вимкнути"
|
||||
|
||||
#: js/ui/endSessionDialog.js:74
|
||||
#: js/ui/endSessionDialog.js:81
|
||||
msgctxt "title"
|
||||
msgid "Restart"
|
||||
msgstr "Перезапустити"
|
||||
|
||||
#: js/ui/endSessionDialog.js:76
|
||||
#: js/ui/endSessionDialog.js:82
|
||||
msgctxt "title"
|
||||
msgid "Install Updates & Restart"
|
||||
msgstr "Установити оновлення і перезапустити"
|
||||
|
||||
#: js/ui/endSessionDialog.js:85
|
||||
#, javascript-format
|
||||
msgid "The system will restart automatically in %d second."
|
||||
msgid_plural "The system will restart automatically in %d seconds."
|
||||
@ -1230,12 +1241,17 @@ msgstr[1] "Система автоматично перезапуститься
|
||||
msgstr[2] "Система автоматично перезапуститься через %d секунд."
|
||||
msgstr[3] "Система автоматично перезапуститься через %d секунду."
|
||||
|
||||
#: js/ui/endSessionDialog.js:89
|
||||
#: js/ui/endSessionDialog.js:93
|
||||
msgctxt "button"
|
||||
msgid "Restart"
|
||||
msgstr "Перезапустити"
|
||||
|
||||
#: js/ui/endSessionDialog.js:101
|
||||
msgctxt "title"
|
||||
msgid "Restart & Install Updates"
|
||||
msgstr "Перезапустити і встановити оновлення"
|
||||
|
||||
#: js/ui/endSessionDialog.js:91
|
||||
#: js/ui/endSessionDialog.js:104
|
||||
#, javascript-format
|
||||
msgid "The system will automatically restart and install updates in %d second."
|
||||
msgid_plural ""
|
||||
@ -1249,22 +1265,22 @@ msgstr[2] ""
|
||||
msgstr[3] ""
|
||||
"Система автоматично перезапуститься та встановить оновлення через %d секунду."
|
||||
|
||||
#: js/ui/endSessionDialog.js:97 js/ui/endSessionDialog.js:116
|
||||
#: js/ui/endSessionDialog.js:111 js/ui/endSessionDialog.js:132
|
||||
msgctxt "button"
|
||||
msgid "Restart & Install"
|
||||
msgstr "Перезапустити та встановити"
|
||||
|
||||
#: js/ui/endSessionDialog.js:98
|
||||
#: js/ui/endSessionDialog.js:113
|
||||
msgctxt "button"
|
||||
msgid "Install & Power Off"
|
||||
msgstr "Установити та вимкнути"
|
||||
|
||||
#: js/ui/endSessionDialog.js:99
|
||||
#: js/ui/endSessionDialog.js:114
|
||||
msgctxt "checkbox"
|
||||
msgid "Power off after updates are installed"
|
||||
msgstr "Вимкнути після встановлення оновлень"
|
||||
|
||||
#: js/ui/endSessionDialog.js:106
|
||||
#: js/ui/endSessionDialog.js:121
|
||||
msgctxt "title"
|
||||
msgid "Restart & Install Upgrade"
|
||||
msgstr "Перезапустити і встановити оновлення"
|
||||
@ -1272,7 +1288,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:111
|
||||
#: js/ui/endSessionDialog.js:126
|
||||
#, javascript-format
|
||||
msgid ""
|
||||
"%s %s will be installed after restart. Upgrade installation can take a long "
|
||||
@ -1282,28 +1298,34 @@ msgstr ""
|
||||
"переконайтесь, що ви зробили резервні копії та комп'ютер під'єднано до "
|
||||
"живлення."
|
||||
|
||||
#: js/ui/endSessionDialog.js:259
|
||||
msgid "Running on battery power: Please plug in before installing updates."
|
||||
#: 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."
|
||||
msgstr ""
|
||||
"Працює від заряду батареї: під'єднайте до живлення перед установленням "
|
||||
"оновлень."
|
||||
"Низький рівень заряду батареї: під'єднайте до живлення перед установленням"
|
||||
" оновлень."
|
||||
|
||||
#: js/ui/endSessionDialog.js:268
|
||||
#: js/ui/endSessionDialog.js:293
|
||||
msgid "Some applications are busy or have unsaved work"
|
||||
msgstr "Деякі програми зайняті або мають незбережені дані"
|
||||
|
||||
#: js/ui/endSessionDialog.js:273
|
||||
#: js/ui/endSessionDialog.js:298
|
||||
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:583
|
||||
#: js/ui/endSessionDialog.js:685
|
||||
#, javascript-format
|
||||
msgid "%s (remote)"
|
||||
msgstr "%s (віддалено)"
|
||||
|
||||
#. Translators: Console here refers to a tty like a VT console
|
||||
#: js/ui/endSessionDialog.js:586
|
||||
#: js/ui/endSessionDialog.js:688
|
||||
#, javascript-format
|
||||
msgid "%s (console)"
|
||||
msgstr "%s (консоль)"
|
||||
@ -1403,15 +1425,15 @@ msgid "Leave On"
|
||||
msgstr "Залишити"
|
||||
|
||||
#: js/ui/kbdA11yDialog.js:55 js/ui/status/bluetooth.js:156
|
||||
#: js/ui/status/network.js:1291
|
||||
#: js/ui/status/network.js:1315
|
||||
msgid "Turn On"
|
||||
msgstr "Увімкнути"
|
||||
|
||||
#: js/ui/kbdA11yDialog.js:63 js/ui/status/bluetooth.js:156
|
||||
#: 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/network.js:160 js/ui/status/network.js:344
|
||||
#: js/ui/status/network.js:1315 js/ui/status/network.js:1427
|
||||
#: js/ui/status/nightLight.js:41 js/ui/status/rfkill.js:81
|
||||
#: js/ui/status/rfkill.js:108
|
||||
#: js/ui/status/rfkill.js:110
|
||||
msgid "Turn Off"
|
||||
msgstr "Вимкнути"
|
||||
|
||||
@ -1472,11 +1494,11 @@ msgstr "Переглянути джерело"
|
||||
msgid "Web Page"
|
||||
msgstr "Веб-сторінка"
|
||||
|
||||
#: js/ui/main.js:297
|
||||
#: js/ui/main.js:294
|
||||
msgid "Logged in as a privileged user"
|
||||
msgstr "Увійшов як наділений користувач"
|
||||
|
||||
#: js/ui/main.js:298
|
||||
#: js/ui/main.js:295
|
||||
msgid ""
|
||||
"Running a session as a privileged user should be avoided for security "
|
||||
"reasons. If possible, you should log in as a normal user."
|
||||
@ -1484,11 +1506,11 @@ msgstr ""
|
||||
"З міркувань безпеки слід уникати сеансів з наділеними правами. Користуйтесь "
|
||||
"звичайним сеансом."
|
||||
|
||||
#: js/ui/main.js:337
|
||||
#: js/ui/main.js:334
|
||||
msgid "Screen Lock disabled"
|
||||
msgstr "Блокування екрана вимкнено"
|
||||
|
||||
#: js/ui/main.js:338
|
||||
#: js/ui/main.js:335
|
||||
msgid "Screen Locking requires the GNOME display manager."
|
||||
msgstr "Блокування екрана потребує керування входом GNOME."
|
||||
|
||||
@ -1581,7 +1603,7 @@ msgctxt "System menu in the top bar"
|
||||
msgid "System"
|
||||
msgstr "Система"
|
||||
|
||||
#: js/ui/panel.js:827
|
||||
#: js/ui/panel.js:825
|
||||
msgid "Top Bar"
|
||||
msgstr "Верхня панель"
|
||||
|
||||
@ -1758,7 +1780,7 @@ msgstr "Більший текст"
|
||||
msgid "Bluetooth"
|
||||
msgstr "Bluetooth"
|
||||
|
||||
#: js/ui/status/bluetooth.js:49 js/ui/status/network.js:595
|
||||
#: js/ui/status/bluetooth.js:49 js/ui/status/network.js:619
|
||||
msgid "Bluetooth Settings"
|
||||
msgstr "Параметри Bluetooth"
|
||||
|
||||
@ -1842,18 +1864,18 @@ msgstr ""
|
||||
"Доступ до місця перебування можна змінити в будь-яку мить у параметрах "
|
||||
"конфіденційності."
|
||||
|
||||
#: js/ui/status/network.js:70
|
||||
#: js/ui/status/network.js:71
|
||||
msgid "<unknown>"
|
||||
msgstr "<невідомо>"
|
||||
|
||||
#. Translators: %s is a network identifier
|
||||
#: js/ui/status/network.js:424 js/ui/status/network.js:1320
|
||||
#: js/ui/status/network.js:449 js/ui/status/network.js:1344
|
||||
#, javascript-format
|
||||
msgid "%s Off"
|
||||
msgstr "%s вимкнено"
|
||||
|
||||
#. Translators: %s is a network identifier
|
||||
#: js/ui/status/network.js:427
|
||||
#: js/ui/status/network.js:452
|
||||
#, javascript-format
|
||||
msgid "%s Connected"
|
||||
msgstr "%s під'єднано"
|
||||
@ -1861,164 +1883,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:432
|
||||
#: js/ui/status/network.js:457
|
||||
#, javascript-format
|
||||
msgid "%s Unmanaged"
|
||||
msgstr "%s нескеровано"
|
||||
|
||||
#. Translators: %s is a network identifier
|
||||
#: js/ui/status/network.js:435
|
||||
#: js/ui/status/network.js:460
|
||||
#, javascript-format
|
||||
msgid "%s Disconnecting"
|
||||
msgstr "%s від'єднується"
|
||||
|
||||
#. Translators: %s is a network identifier
|
||||
#: js/ui/status/network.js:442 js/ui/status/network.js:1312
|
||||
#: js/ui/status/network.js:467 js/ui/status/network.js:1336
|
||||
#, 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:445
|
||||
#: js/ui/status/network.js:470
|
||||
#, 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:453
|
||||
#: js/ui/status/network.js:478
|
||||
#, 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:457
|
||||
#: js/ui/status/network.js:482
|
||||
#, javascript-format
|
||||
msgid "%s Unavailable"
|
||||
msgstr "%s недоступний"
|
||||
|
||||
#. Translators: %s is a network identifier
|
||||
#: js/ui/status/network.js:460
|
||||
#: js/ui/status/network.js:485
|
||||
#, javascript-format
|
||||
msgid "%s Connection Failed"
|
||||
msgstr "%s під'єднано невдало"
|
||||
|
||||
#: js/ui/status/network.js:472
|
||||
#: js/ui/status/network.js:497
|
||||
msgid "Wired Settings"
|
||||
msgstr "Параметри мережі"
|
||||
|
||||
#: js/ui/status/network.js:515
|
||||
#: js/ui/status/network.js:540
|
||||
msgid "Mobile Broadband Settings"
|
||||
msgstr "параметри мобільної радіомережі"
|
||||
|
||||
#. Translators: %s is a network identifier
|
||||
#: js/ui/status/network.js:562 js/ui/status/network.js:1317
|
||||
#: js/ui/status/network.js:586 js/ui/status/network.js:1341
|
||||
#, 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:566
|
||||
#: js/ui/status/network.js:590
|
||||
#, javascript-format
|
||||
msgid "%s Disabled"
|
||||
msgstr "%s вимкнено"
|
||||
|
||||
#: js/ui/status/network.js:607
|
||||
#: js/ui/status/network.js:631
|
||||
msgid "Connect to Internet"
|
||||
msgstr "Під'єднатись до інтернету"
|
||||
|
||||
#: js/ui/status/network.js:811
|
||||
#: js/ui/status/network.js:835
|
||||
msgid "Airplane Mode is On"
|
||||
msgstr "Режим «у літаку» ввімкнено"
|
||||
|
||||
#: js/ui/status/network.js:812
|
||||
#: js/ui/status/network.js:836
|
||||
msgid "Wi-Fi is disabled when airplane mode is on."
|
||||
msgstr "Wi-Fi вимкнено, коли режим «у літаку» ввімкнено."
|
||||
|
||||
#: js/ui/status/network.js:813
|
||||
#: js/ui/status/network.js:837
|
||||
msgid "Turn Off Airplane Mode"
|
||||
msgstr "Вимкнути режим «у літаку»"
|
||||
|
||||
#: js/ui/status/network.js:822
|
||||
#: js/ui/status/network.js:846
|
||||
msgid "Wi-Fi is Off"
|
||||
msgstr "Wi-Fi вимкнено"
|
||||
|
||||
#: js/ui/status/network.js:823
|
||||
#: js/ui/status/network.js:847
|
||||
msgid "Wi-Fi needs to be turned on in order to connect to a network."
|
||||
msgstr "Wi-Fi потрібно ввімкнути, щоб з'єднатись з мережею."
|
||||
|
||||
#: js/ui/status/network.js:824
|
||||
#: js/ui/status/network.js:848
|
||||
msgid "Turn On Wi-Fi"
|
||||
msgstr "Увімкнути Wi-Fi"
|
||||
|
||||
#: js/ui/status/network.js:849
|
||||
#: js/ui/status/network.js:873
|
||||
msgid "Wi-Fi Networks"
|
||||
msgstr "Мережі Wi-Fi"
|
||||
|
||||
#: js/ui/status/network.js:851
|
||||
#: js/ui/status/network.js:875
|
||||
msgid "Select a network"
|
||||
msgstr "Вибрати мережу"
|
||||
|
||||
#: js/ui/status/network.js:883
|
||||
#: js/ui/status/network.js:907
|
||||
msgid "No Networks"
|
||||
msgstr "Немає мереж"
|
||||
|
||||
#: js/ui/status/network.js:904 js/ui/status/rfkill.js:106
|
||||
#: js/ui/status/network.js:928 js/ui/status/rfkill.js:108
|
||||
msgid "Use hardware switch to turn off"
|
||||
msgstr "Натисніть апаратну кнопку, щоб вимкнути"
|
||||
|
||||
#: js/ui/status/network.js:1181
|
||||
#: js/ui/status/network.js:1205
|
||||
msgid "Select Network"
|
||||
msgstr "Виберіть мережу"
|
||||
|
||||
#: js/ui/status/network.js:1187
|
||||
#: js/ui/status/network.js:1211
|
||||
msgid "Wi-Fi Settings"
|
||||
msgstr "Параметри Wi-Fi"
|
||||
|
||||
#. Translators: %s is a network identifier
|
||||
#: js/ui/status/network.js:1308
|
||||
#: js/ui/status/network.js:1332
|
||||
#, javascript-format
|
||||
msgid "%s Hotspot Active"
|
||||
msgstr "%s точка доступу"
|
||||
|
||||
#. Translators: %s is a network identifier
|
||||
#: js/ui/status/network.js:1323
|
||||
#: js/ui/status/network.js:1347
|
||||
#, javascript-format
|
||||
msgid "%s Not Connected"
|
||||
msgstr "%s не під'єднано"
|
||||
|
||||
#: js/ui/status/network.js:1420
|
||||
#: js/ui/status/network.js:1444
|
||||
msgid "connecting…"
|
||||
msgstr "З'єднання…"
|
||||
|
||||
#. Translators: this is for network connections that require some kind of key or password
|
||||
#: js/ui/status/network.js:1423
|
||||
#: js/ui/status/network.js:1447
|
||||
msgid "authentication required"
|
||||
msgstr "Потрібна аутентифікація"
|
||||
|
||||
#: js/ui/status/network.js:1425
|
||||
#: js/ui/status/network.js:1449
|
||||
msgid "connection failed"
|
||||
msgstr "не вдалось з'єднатись"
|
||||
|
||||
#: js/ui/status/network.js:1476
|
||||
#: js/ui/status/network.js:1500
|
||||
msgid "VPN Settings"
|
||||
msgstr "Параметри VPN"
|
||||
|
||||
#: js/ui/status/network.js:1493
|
||||
#: js/ui/status/network.js:1517
|
||||
msgid "VPN"
|
||||
msgstr "VPN"
|
||||
|
||||
#: js/ui/status/network.js:1503
|
||||
#: js/ui/status/network.js:1527
|
||||
msgid "VPN Off"
|
||||
msgstr "VPN вимкнено"
|
||||
|
||||
#: js/ui/status/network.js:1564 js/ui/status/rfkill.js:84
|
||||
#: js/ui/status/network.js:1588 js/ui/status/rfkill.js:84
|
||||
msgid "Network Settings"
|
||||
msgstr "Налаштування мережі"
|
||||
|
||||
#: js/ui/status/network.js:1593
|
||||
#: js/ui/status/network.js:1617
|
||||
#, javascript-format
|
||||
msgid "%s Wired Connection"
|
||||
msgid_plural "%s Wired Connections"
|
||||
@ -2027,7 +2049,7 @@ msgstr[1] "%s з'єднання через дріт"
|
||||
msgstr[2] "%s з'єднань через дріт"
|
||||
msgstr[3] "%s з'єднання через дріт"
|
||||
|
||||
#: js/ui/status/network.js:1597
|
||||
#: js/ui/status/network.js:1621
|
||||
#, javascript-format
|
||||
msgid "%s Wi-Fi Connection"
|
||||
msgid_plural "%s Wi-Fi Connections"
|
||||
@ -2036,7 +2058,7 @@ msgstr[1] "%s з'єднання через Wi-Fi"
|
||||
msgstr[2] "%s з'єднань через Wi-Fi"
|
||||
msgstr[3] "%s з'єднання через Wi-Fi"
|
||||
|
||||
#: js/ui/status/network.js:1601
|
||||
#: js/ui/status/network.js:1625
|
||||
#, javascript-format
|
||||
msgid "%s Modem Connection"
|
||||
msgid_plural "%s Modem Connections"
|
||||
@ -2045,11 +2067,11 @@ msgstr[1] "%s з'єднання через модем"
|
||||
msgstr[2] "%s з'єднань через модем"
|
||||
msgstr[3] "%s з'єднання через модем"
|
||||
|
||||
#: js/ui/status/network.js:1735
|
||||
#: js/ui/status/network.js:1759
|
||||
msgid "Connection failed"
|
||||
msgstr "Не вдалось з'єднатись"
|
||||
|
||||
#: js/ui/status/network.js:1736
|
||||
#: js/ui/status/network.js:1760
|
||||
msgid "Activation of network connection failed"
|
||||
msgstr "Не вдалось увімкнути мережеве з'єднання"
|
||||
|
||||
@ -2104,11 +2126,11 @@ msgstr "Зарядиться через %d∶%02d (%d %%)"
|
||||
msgid "%d %%"
|
||||
msgstr "%d %%"
|
||||
|
||||
#: js/ui/status/remoteAccess.js:43
|
||||
#: js/ui/status/remoteAccess.js:45
|
||||
msgid "Screen is Being Shared"
|
||||
msgstr "Екран у спільному доступі"
|
||||
|
||||
#: js/ui/status/remoteAccess.js:45
|
||||
#: js/ui/status/remoteAccess.js:47
|
||||
msgid "Turn off"
|
||||
msgstr "Вимкнути"
|
||||
|
||||
@ -2119,30 +2141,34 @@ msgstr "Вимкнути"
|
||||
msgid "Airplane Mode On"
|
||||
msgstr "Режим «у літаку» ввімкнено"
|
||||
|
||||
#: js/ui/status/system.js:102
|
||||
#: js/ui/status/system.js:104
|
||||
msgid "Lock"
|
||||
msgstr "Заблокувати"
|
||||
|
||||
#: js/ui/status/system.js:115
|
||||
#: js/ui/status/system.js:116
|
||||
msgid "Power Off / Log Out"
|
||||
msgstr "Вимкнути / Вийти"
|
||||
|
||||
#: js/ui/status/system.js:118
|
||||
msgid "Log Out"
|
||||
msgstr "Вийти"
|
||||
|
||||
#: js/ui/status/system.js:130
|
||||
msgid "Switch User…"
|
||||
msgstr "Змінити користувача…"
|
||||
|
||||
#: js/ui/status/system.js:144
|
||||
#: js/ui/status/system.js:119
|
||||
msgid "Suspend"
|
||||
msgstr "Призупинити"
|
||||
|
||||
#: js/ui/status/system.js:156
|
||||
#: 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
|
||||
msgid "Log Out"
|
||||
msgstr "Вийти"
|
||||
|
||||
#: js/ui/status/system.js:165
|
||||
msgid "Switch User…"
|
||||
msgstr "Змінити користувача…"
|
||||
|
||||
#: js/ui/status/thunderbolt.js:263
|
||||
msgid "Thunderbolt"
|
||||
msgstr "Thunderbolt"
|
||||
@ -2249,22 +2275,22 @@ msgid "“%s” is ready"
|
||||
msgstr "«%s» готовий"
|
||||
|
||||
#. Translators: This string should be shorter than 30 characters
|
||||
#: js/ui/windowManager.js:55
|
||||
#: js/ui/windowManager.js:60
|
||||
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:64
|
||||
#: js/ui/windowManager.js:69
|
||||
msgid "Revert Settings"
|
||||
msgstr "Повернути параметри"
|
||||
|
||||
#: js/ui/windowManager.js:67
|
||||
#: js/ui/windowManager.js:72
|
||||
msgid "Keep Changes"
|
||||
msgstr "Зберегти зміни"
|
||||
|
||||
#: js/ui/windowManager.js:86
|
||||
#: js/ui/windowManager.js:91
|
||||
#, javascript-format
|
||||
msgid "Settings changes will revert in %d second"
|
||||
msgid_plural "Settings changes will revert in %d seconds"
|
||||
@ -2275,7 +2301,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:546
|
||||
#: js/ui/windowManager.js:551
|
||||
#, javascript-format
|
||||
msgid "%d × %d"
|
||||
msgstr "%d × %d"
|
||||
|
@ -51,6 +51,8 @@ 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)
|
||||
|
||||
@ -295,6 +297,8 @@ 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,15 +163,6 @@ 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,9 +1361,15 @@ 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, x, y, &raw_mods);
|
||||
meta_cursor_tracker_get_pointer (tracker, &point, &raw_mods);
|
||||
|
||||
if (x)
|
||||
*x = point.x;
|
||||
if (y)
|
||||
*y = point.y;
|
||||
|
||||
*mods = raw_mods & CLUTTER_MODIFIER_MASK;
|
||||
}
|
||||
|
@ -1,425 +0,0 @@
|
||||
/* -*- 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;
|
||||
}
|
@ -1,40 +0,0 @@
|
||||
/* -*- 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
1625
src/shell-recorder.c
File diff suppressed because it is too large
Load Diff
@ -1,45 +0,0 @@
|
||||
/* -*- 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,6 +12,12 @@
|
||||
#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
|
||||
@ -32,7 +38,6 @@ struct _ShellScreenshotPrivate
|
||||
cairo_surface_t *image;
|
||||
cairo_rectangle_int_t screenshot_area;
|
||||
|
||||
gboolean include_cursor;
|
||||
gboolean include_frame;
|
||||
};
|
||||
|
||||
@ -45,10 +50,6 @@ 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)
|
||||
{
|
||||
@ -77,8 +78,6 @@ 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
|
||||
@ -121,63 +120,49 @@ write_screenshot_thread (GTask *result,
|
||||
}
|
||||
|
||||
static void
|
||||
do_grab_screenshot (ShellScreenshot *screenshot,
|
||||
ClutterStage *stage,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height)
|
||||
do_grab_screenshot (ShellScreenshot *screenshot,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height,
|
||||
ShellScreenshotFlag flags)
|
||||
{
|
||||
ShellScreenshotPrivate *priv = screenshot->priv;
|
||||
ClutterStage *stage = shell_global_get_stage (priv->global);
|
||||
cairo_rectangle_int_t screenshot_rect = { x, y, width, height };
|
||||
ClutterCapture *captures;
|
||||
int n_captures;
|
||||
int i;
|
||||
int image_width;
|
||||
int image_height;
|
||||
float scale;
|
||||
cairo_surface_t *image;
|
||||
ClutterPaintFlag paint_flags = CLUTTER_PAINT_FLAG_NONE;
|
||||
g_autoptr (GError) error = NULL;
|
||||
|
||||
if (!clutter_stage_capture (stage, FALSE,
|
||||
&screenshot_rect,
|
||||
&captures,
|
||||
&n_captures))
|
||||
return;
|
||||
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 (n_captures == 1)
|
||||
priv->image = cairo_surface_reference (captures[0].image);
|
||||
if (flags & SHELL_SCREENSHOT_FLAG_INCLUDE_CURSOR)
|
||||
paint_flags |= CLUTTER_PAINT_FLAG_FORCE_CURSORS;
|
||||
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))
|
||||
{
|
||||
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);
|
||||
cairo_surface_destroy (image);
|
||||
g_warning ("Failed to take screenshot: %s", error->message);
|
||||
return;
|
||||
}
|
||||
|
||||
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
|
||||
@ -196,6 +181,7 @@ 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);
|
||||
@ -205,9 +191,11 @@ draw_cursor_image (cairo_surface_t *surface,
|
||||
return;
|
||||
|
||||
screenshot_region = cairo_region_create_rectangle (&area);
|
||||
meta_cursor_tracker_get_pointer (tracker, &x, &y, NULL);
|
||||
meta_cursor_tracker_get_pointer (tracker, &point, NULL);
|
||||
x = point.x;
|
||||
y = point.y;
|
||||
|
||||
if (!cairo_region_contains_point (screenshot_region, x, y))
|
||||
if (!cairo_region_contains_point (screenshot_region, point.x, point.y))
|
||||
{
|
||||
cairo_region_destroy (screenshot_region);
|
||||
return;
|
||||
@ -256,116 +244,37 @@ draw_cursor_image (cairo_surface_t *surface,
|
||||
}
|
||||
|
||||
static void
|
||||
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)
|
||||
grab_screenshot (ShellScreenshot *screenshot,
|
||||
ShellScreenshotFlag flags,
|
||||
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, 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);
|
||||
}
|
||||
do_grab_screenshot (screenshot,
|
||||
0, 0, width, height,
|
||||
flags);
|
||||
|
||||
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_area_screenshot (ClutterActor *stage,
|
||||
GTask *result)
|
||||
grab_window_screenshot (ShellScreenshot *screenshot,
|
||||
ShellScreenshotFlag flags,
|
||||
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);
|
||||
@ -388,7 +297,7 @@ grab_window_screenshot (ClutterActor *stage,
|
||||
NULL);
|
||||
priv->datetime = g_date_time_new_now_local ();
|
||||
|
||||
if (priv->include_cursor)
|
||||
if (flags & SHELL_SCREENSHOT_FLAG_INCLUDE_CURSOR)
|
||||
{
|
||||
if (meta_window_get_client_type (window) == META_WINDOW_CLIENT_TYPE_WAYLAND)
|
||||
{
|
||||
@ -401,33 +310,11 @@ grab_window_screenshot (ClutterActor *stage,
|
||||
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,
|
||||
@ -465,10 +352,9 @@ 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));
|
||||
@ -492,34 +378,12 @@ 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)
|
||||
{
|
||||
if (should_draw_cursor_image (SHELL_SCREENSHOT_SCREEN))
|
||||
priv->include_cursor = TRUE;
|
||||
else
|
||||
use_paint_signal = TRUE;
|
||||
}
|
||||
flags |= SHELL_SCREENSHOT_FLAG_INCLUDE_CURSOR;
|
||||
|
||||
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);
|
||||
grab_screenshot (screenshot, flags, result);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -575,9 +439,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));
|
||||
@ -606,13 +470,15 @@ shell_screenshot_screenshot_area (ShellScreenshot *screenshot,
|
||||
priv->screenshot_area.width = width;
|
||||
priv->screenshot_area.height = height;
|
||||
|
||||
stage = CLUTTER_ACTOR (shell_global_get_stage (priv->global));
|
||||
do_grab_screenshot (screenshot,
|
||||
priv->screenshot_area.x,
|
||||
priv->screenshot_area.y,
|
||||
priv->screenshot_area.width,
|
||||
priv->screenshot_area.height,
|
||||
SHELL_SCREENSHOT_FLAG_NONE);
|
||||
|
||||
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);
|
||||
task = g_task_new (screenshot, NULL, on_screenshot_written, result);
|
||||
g_task_run_in_thread (task, write_screenshot_thread);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -666,7 +532,6 @@ shell_screenshot_screenshot_window (ShellScreenshot *screenshot,
|
||||
{
|
||||
ShellScreenshotPrivate *priv;
|
||||
MetaDisplay *display;
|
||||
ClutterActor *stage;
|
||||
MetaWindow *window;
|
||||
GTask *result;
|
||||
|
||||
@ -695,16 +560,8 @@ 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);
|
||||
|
||||
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);
|
||||
grab_window_screenshot (screenshot, include_cursor, result);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -753,9 +610,7 @@ shell_screenshot_pick_color (ShellScreenshot *screenshot,
|
||||
gpointer user_data)
|
||||
{
|
||||
ShellScreenshotPrivate *priv;
|
||||
MetaDisplay *display;
|
||||
ClutterActor *stage;
|
||||
GTask *result;
|
||||
g_autoptr (GTask) result = NULL;
|
||||
|
||||
g_return_if_fail (SHELL_IS_SCREENSHOT (screenshot));
|
||||
|
||||
@ -769,14 +624,14 @@ shell_screenshot_pick_color (ShellScreenshot *screenshot,
|
||||
priv->screenshot_area.width = 1;
|
||||
priv->screenshot_area.height = 1;
|
||||
|
||||
display = shell_global_get_display (priv->global);
|
||||
stage = CLUTTER_ACTOR (shell_global_get_stage (priv->global));
|
||||
do_grab_screenshot (screenshot,
|
||||
priv->screenshot_area.x,
|
||||
priv->screenshot_area.y,
|
||||
1,
|
||||
1,
|
||||
SHELL_SCREENSHOT_FLAG_NONE);
|
||||
|
||||
meta_disable_unredirect_for_display (display);
|
||||
|
||||
g_signal_connect_after (stage, "actors-painted", G_CALLBACK (grab_pixel), result);
|
||||
|
||||
clutter_actor_queue_redraw (stage);
|
||||
g_task_return_boolean (result, TRUE);
|
||||
}
|
||||
|
||||
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
|
||||
|
291
src/shell-util.c
291
src/shell-util.c
@ -77,61 +77,6 @@ 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:
|
||||
*
|
||||
@ -625,6 +570,57 @@ 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,
|
||||
@ -632,46 +628,143 @@ on_systemd_call_cb (GObject *source,
|
||||
{
|
||||
g_autoptr (GVariant) reply = NULL;
|
||||
g_autoptr (GError) error = NULL;
|
||||
const gchar *command = user_data;
|
||||
GTask *task = G_TASK (user_data);
|
||||
SystemdCall *data;
|
||||
|
||||
reply = g_dbus_connection_call_finish (G_DBUS_CONNECTION (source),
|
||||
res, &error);
|
||||
if (error)
|
||||
g_warning ("Could not issue '%s' systemd call", command);
|
||||
|
||||
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. */
|
||||
}
|
||||
|
||||
static gboolean
|
||||
shell_util_systemd_call (const char *command,
|
||||
const char *unit,
|
||||
const char *mode,
|
||||
GError **error)
|
||||
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)
|
||||
{
|
||||
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_debug ("Not systemd-managed, not doing '%s' on '%s'", mode, unit);
|
||||
return FALSE;
|
||||
g_task_return_new_error (task,
|
||||
G_IO_ERROR,
|
||||
G_IO_ERROR_NOT_SUPPORTED,
|
||||
"Not systemd managed");
|
||||
return;
|
||||
}
|
||||
else if (res < 0)
|
||||
{
|
||||
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;
|
||||
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;
|
||||
}
|
||||
|
||||
connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, error);
|
||||
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);
|
||||
|
||||
if (connection == NULL)
|
||||
return FALSE;
|
||||
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);
|
||||
}
|
||||
|
||||
g_dbus_connection_call (connection,
|
||||
"org.freedesktop.systemd1",
|
||||
@ -680,31 +773,53 @@ shell_util_systemd_call (const char *command,
|
||||
command,
|
||||
g_variant_new ("(ss)",
|
||||
unit, mode),
|
||||
NULL,
|
||||
G_VARIANT_TYPE ("(o)"),
|
||||
G_DBUS_CALL_FLAGS_NONE,
|
||||
-1, NULL,
|
||||
-1, cancellable,
|
||||
on_systemd_call_cb,
|
||||
(gpointer) command);
|
||||
return TRUE;
|
||||
#endif /* HAVE_SYSTEMD */
|
||||
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 */
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
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);
|
||||
}
|
||||
|
||||
gboolean
|
||||
shell_util_start_systemd_unit (const char *unit,
|
||||
const char *mode,
|
||||
GError **error)
|
||||
shell_util_start_systemd_unit_finish (GAsyncResult *res,
|
||||
GError **error)
|
||||
{
|
||||
return shell_util_systemd_call ("StartUnit", unit, mode, 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);
|
||||
}
|
||||
|
||||
gboolean
|
||||
shell_util_stop_systemd_unit (const char *unit,
|
||||
const char *mode,
|
||||
GError **error)
|
||||
shell_util_stop_systemd_unit_finish (GAsyncResult *res,
|
||||
GError **error)
|
||||
{
|
||||
return shell_util_systemd_call ("StopUnit", unit, mode, error);
|
||||
return g_task_propagate_boolean (G_TASK (res), error);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -14,9 +14,6 @@ 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);
|
||||
@ -62,12 +59,21 @@ cairo_surface_t * shell_util_composite_capture_images (ClutterCapture *captures
|
||||
|
||||
void shell_util_check_cloexec_fds (void);
|
||||
|
||||
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_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);
|
||||
|
||||
void shell_util_sd_notify (void);
|
||||
|
||||
|
@ -136,6 +136,8 @@ struct _CRParserPriv {
|
||||
|
||||
#define CHARS_TAB_SIZE 12
|
||||
|
||||
#define RECURSIVE_CALLERS_LIMIT 100
|
||||
|
||||
/**
|
||||
* IS_NUM:
|
||||
*@a_char: the char to test.
|
||||
@ -343,9 +345,11 @@ 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);
|
||||
static enum CRStatus cr_parser_parse_any_core (CRParser * a_this,
|
||||
guint n_calls);
|
||||
|
||||
static enum CRStatus cr_parser_parse_block_core (CRParser * a_this);
|
||||
static enum CRStatus cr_parser_parse_block_core (CRParser * a_this,
|
||||
guint n_calls);
|
||||
|
||||
static enum CRStatus cr_parser_parse_value_core (CRParser * a_this);
|
||||
|
||||
@ -783,7 +787,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);
|
||||
status = cr_parser_parse_any_core (a_this, 0);
|
||||
} while (status == CR_OK);
|
||||
|
||||
status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr,
|
||||
@ -794,7 +798,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);
|
||||
status = cr_parser_parse_block_core (a_this, 0);
|
||||
CHECK_PARSING_STATUS (status,
|
||||
FALSE);
|
||||
goto done;
|
||||
@ -929,11 +933,11 @@ cr_parser_parse_selector_core (CRParser * a_this)
|
||||
|
||||
RECORD_INITIAL_POS (a_this, &init_pos);
|
||||
|
||||
status = cr_parser_parse_any_core (a_this);
|
||||
status = cr_parser_parse_any_core (a_this, 0);
|
||||
CHECK_PARSING_STATUS (status, FALSE);
|
||||
|
||||
do {
|
||||
status = cr_parser_parse_any_core (a_this);
|
||||
status = cr_parser_parse_any_core (a_this, 0);
|
||||
|
||||
} while (status == CR_OK);
|
||||
|
||||
@ -955,10 +959,12 @@ 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)
|
||||
cr_parser_parse_block_core (CRParser * a_this,
|
||||
guint n_calls)
|
||||
{
|
||||
CRToken *token = NULL;
|
||||
CRInputPos init_pos;
|
||||
@ -966,6 +972,9 @@ 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);
|
||||
@ -995,13 +1004,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);
|
||||
status = cr_parser_parse_block_core (a_this, n_calls + 1);
|
||||
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);
|
||||
status = cr_parser_parse_any_core (a_this, n_calls + 1);
|
||||
CHECK_PARSING_STATUS (status, FALSE);
|
||||
goto parse_block_content;
|
||||
}
|
||||
@ -1108,7 +1117,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);
|
||||
status = cr_parser_parse_block_core (a_this, 0);
|
||||
CHECK_PARSING_STATUS (status, FALSE);
|
||||
ref++;
|
||||
goto continue_parsing;
|
||||
@ -1122,7 +1131,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);
|
||||
status = cr_parser_parse_any_core (a_this, 0);
|
||||
if (status == CR_OK) {
|
||||
ref++;
|
||||
goto continue_parsing;
|
||||
@ -1161,10 +1170,12 @@ 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)
|
||||
cr_parser_parse_any_core (CRParser * a_this,
|
||||
guint n_calls)
|
||||
{
|
||||
CRToken *token1 = NULL,
|
||||
*token2 = NULL;
|
||||
@ -1173,6 +1184,9 @@ 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);
|
||||
@ -1211,7 +1225,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);
|
||||
status = cr_parser_parse_any_core (a_this, n_calls + 1);
|
||||
} while (status == CR_OK);
|
||||
|
||||
ENSURE_PARSING_COND (status == CR_PARSING_ERROR);
|
||||
@ -1236,7 +1250,7 @@ cr_parser_parse_any_core (CRParser * a_this)
|
||||
}
|
||||
|
||||
do {
|
||||
status = cr_parser_parse_any_core (a_this);
|
||||
status = cr_parser_parse_any_core (a_this, n_calls + 1);
|
||||
} while (status == CR_OK);
|
||||
|
||||
ENSURE_PARSING_COND (status == CR_PARSING_ERROR);
|
||||
@ -1264,7 +1278,7 @@ cr_parser_parse_any_core (CRParser * a_this)
|
||||
}
|
||||
|
||||
do {
|
||||
status = cr_parser_parse_any_core (a_this);
|
||||
status = cr_parser_parse_any_core (a_this, n_calls + 1);
|
||||
} while (status == CR_OK);
|
||||
|
||||
ENSURE_PARSING_COND (status == CR_PARSING_ERROR);
|
||||
|
@ -279,11 +279,23 @@ 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,
|
||||
@ -291,6 +303,14 @@ 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,
|
||||
@ -298,6 +318,11 @@ 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,
|
||||
@ -305,6 +330,11 @@ 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,
|
||||
@ -312,6 +342,11 @@ 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,
|
||||
@ -319,6 +354,14 @@ 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,
|
||||
@ -350,6 +393,20 @@ 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,
|
||||
@ -370,6 +427,14 @@ 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)
|
||||
{
|
||||
@ -378,6 +443,14 @@ 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)
|
||||
@ -404,6 +477,15 @@ 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,
|
||||
@ -437,6 +519,23 @@ 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)
|
||||
@ -461,6 +560,21 @@ 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)
|
||||
@ -485,6 +599,18 @@ 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)
|
||||
@ -505,6 +631,18 @@ 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)
|
||||
@ -525,6 +663,18 @@ 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)
|
||||
@ -549,6 +699,23 @@ 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,
|
||||
@ -593,12 +760,12 @@ st_adjustment_set_values (StAdjustment *adjustment,
|
||||
/**
|
||||
* st_adjustment_get_values:
|
||||
* @adjustment: an #StAdjustment
|
||||
* @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
|
||||
* @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
|
||||
*
|
||||
* Gets all of @adjustment's values at once.
|
||||
*/
|
||||
@ -722,7 +889,13 @@ on_transition_stopped (ClutterTransition *transition,
|
||||
|
||||
/**
|
||||
* st_adjustment_get_transition:
|
||||
* Returns: (transfer none) (nullable):
|
||||
* @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
|
||||
*/
|
||||
ClutterTransition *
|
||||
st_adjustment_get_transition (StAdjustment *adjustment,
|
||||
@ -745,6 +918,15 @@ 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,
|
||||
@ -785,6 +967,14 @@ 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.
|
||||
*
|
||||
* Return value: the newly created #StBin actor
|
||||
* Returns: 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
|
||||
*
|
||||
* Retrieves a pointer to the child of @bin.
|
||||
* Gets the #ClutterActor child for @bin.
|
||||
*
|
||||
* Return value: (transfer none): a #ClutterActor, or %NULL
|
||||
* Returns: (transfer none) (nullable): a #ClutterActor, or %NULL
|
||||
*/
|
||||
ClutterActor *
|
||||
st_bin_get_child (StBin *bin)
|
||||
|
@ -66,6 +66,19 @@ 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,
|
||||
@ -90,9 +103,11 @@ st_border_image_new (GFile *file,
|
||||
|
||||
/**
|
||||
* st_border_image_get_file:
|
||||
* @image: a #StBorder_Image
|
||||
* @image: a #StBorderImage
|
||||
*
|
||||
* Returns: (transfer none): the #GFile for the #StBorder_Image
|
||||
* Get the #GFile for @image.
|
||||
*
|
||||
* Returns: (transfer none): a #GFile
|
||||
*/
|
||||
GFile *
|
||||
st_border_image_get_file (StBorderImage *image)
|
||||
@ -102,6 +117,17 @@ 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,
|
||||
@ -123,12 +149,12 @@ st_border_image_get_borders (StBorderImage *image,
|
||||
|
||||
/**
|
||||
* st_border_image_equal:
|
||||
* @image: a #StBorder_Image
|
||||
* @other: a different #StBorder_Image
|
||||
* @image: a #StBorderImage
|
||||
* @other: a different #StBorderImage
|
||||
*
|
||||
* Check if two border_image objects are identical.
|
||||
* Check if two #StBorderImage objects are identical.
|
||||
*
|
||||
* Return value: %TRUE if the two border image objects are identical
|
||||
* Returns: %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 getting the #ClutterBoxLayout:vertical
|
||||
* property of the layout for #StBoxLayout.
|
||||
* A convenience property for the #ClutterBoxLayout:vertical property of the
|
||||
* internal 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 getting the #ClutterBoxLayout:pack-start
|
||||
* property of the layout for #StBoxLayout.
|
||||
* A convenience property for the #ClutterBoxLayout:pack-start property of the
|
||||
* internal layout for #StBoxLayout.
|
||||
*/
|
||||
pspec = g_param_spec_boolean ("pack-start",
|
||||
"Pack Start",
|
||||
|
@ -484,6 +484,11 @@ 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",
|
||||
@ -491,6 +496,11 @@ 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",
|
||||
@ -498,6 +508,11 @@ 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",
|
||||
@ -505,6 +520,15 @@ 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",
|
||||
@ -512,6 +536,12 @@ 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",
|
||||
@ -583,9 +613,10 @@ st_button_new_with_label (const gchar *text)
|
||||
* st_button_get_label:
|
||||
* @button: a #StButton
|
||||
*
|
||||
* Get the text displayed on the button
|
||||
* Get the text displayed on the button. If the label is empty, an empty string
|
||||
* will be returned instead of %NULL.
|
||||
*
|
||||
* Returns: the text for the button. This must not be freed by the application
|
||||
* Returns: (transfer none): the text for the button
|
||||
*/
|
||||
const gchar *
|
||||
st_button_get_label (StButton *button)
|
||||
@ -598,9 +629,9 @@ st_button_get_label (StButton *button)
|
||||
/**
|
||||
* st_button_set_label:
|
||||
* @button: a #Stbutton
|
||||
* @text: text to set the label to
|
||||
* @text: (nullable): 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,
|
||||
@ -726,7 +757,7 @@ st_button_set_toggle_mode (StButton *button,
|
||||
* st_button_get_checked:
|
||||
* @button: a #StButton
|
||||
*
|
||||
* Get the state of the button that is in toggle mode.
|
||||
* Get the #StButton:checked property of a #StButton that is in toggle mode.
|
||||
*
|
||||
* Returns: %TRUE if the button is checked, or %FALSE if not
|
||||
*/
|
||||
@ -743,8 +774,8 @@ st_button_get_checked (StButton *button)
|
||||
* @button: a #Stbutton
|
||||
* @checked: %TRUE or %FALSE
|
||||
*
|
||||
* Sets the pressed state of the button. This is only really useful if the
|
||||
* button has #toggle-mode mode set to %TRUE.
|
||||
* Set the #StButton:checked property of the button. This is only really useful
|
||||
* if the button has #StButton:toggle-mode property set to %TRUE.
|
||||
*/
|
||||
void
|
||||
st_button_set_checked (StButton *button,
|
||||
@ -773,9 +804,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 pressed state. The effect is
|
||||
* will ungrab it, and reset the #StButton:pressed state. The effect is
|
||||
* similar to if the user had released the mouse button, but without
|
||||
* emitting the clicked signal.
|
||||
* emitting the #StButton::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,7 +195,6 @@ 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,
|
||||
@ -244,7 +243,6 @@ 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,
|
||||
@ -287,7 +285,9 @@ st_clipboard_get_content (StClipboard *clipboard,
|
||||
* @mimetype: content mimetype
|
||||
* @bytes: content data
|
||||
*
|
||||
* Sets the clipboard content.
|
||||
* Sets the clipboard content to @bytes.
|
||||
*
|
||||
* @mimetype is a semi-colon separated list of mime-type strings.
|
||||
**/
|
||||
void
|
||||
st_clipboard_set_content (StClipboard *clipboard,
|
||||
@ -334,6 +334,13 @@ 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 ::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 #StDrawingArea::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,9 +169,26 @@ 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 for the ::repaint signal.
|
||||
* from a signal hander or virtual function for the #StDrawingArea::repaint
|
||||
* signal.
|
||||
*
|
||||
* Return Value: (transfer none): the Cairo context for the paint operation
|
||||
* 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
|
||||
*/
|
||||
cairo_t *
|
||||
st_drawing_area_get_context (StDrawingArea *area)
|
||||
@ -189,12 +206,12 @@ st_drawing_area_get_context (StDrawingArea *area)
|
||||
/**
|
||||
* st_drawing_area_get_surface_size:
|
||||
* @area: the #StDrawingArea
|
||||
* @width: (out): location to store the width of the painted area
|
||||
* @height: (out): location to store the height of the painted area
|
||||
* @width: (out) (optional): location to store the width of the painted area
|
||||
* @height: (out) (optional): 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 ::repaint signal.
|
||||
* only be called from a signal hander for the #StDrawingArea::repaint signal.
|
||||
*/
|
||||
void
|
||||
st_drawing_area_get_surface_size (StDrawingArea *area,
|
||||
|
@ -29,14 +29,9 @@
|
||||
* applications to set further properties.
|
||||
*
|
||||
* #StEntry supports the following pseudo style states:
|
||||
* <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>
|
||||
*
|
||||
* - `focus`: the widget has focus
|
||||
* - `indeterminate`: the widget is showing the hint text or actor
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
@ -897,6 +892,11 @@ 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,6 +904,11 @@ 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",
|
||||
@ -911,6 +916,11 @@ 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",
|
||||
@ -918,6 +928,12 @@ 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",
|
||||
@ -926,6 +942,12 @@ 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",
|
||||
@ -934,6 +956,11 @@ 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",
|
||||
@ -941,6 +968,12 @@ 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",
|
||||
@ -949,6 +982,13 @@ 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",
|
||||
@ -964,8 +1004,7 @@ 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",
|
||||
@ -974,11 +1013,12 @@ 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",
|
||||
@ -1040,9 +1080,9 @@ st_entry_init (StEntry *entry)
|
||||
|
||||
/**
|
||||
* st_entry_new:
|
||||
* @text: text to set the entry to
|
||||
* @text: (nullable): text to set the entry to
|
||||
*
|
||||
* Create a new #StEntry with the specified entry
|
||||
* Create a new #StEntry with the specified text.
|
||||
*
|
||||
* Returns: a new #StEntry
|
||||
*/
|
||||
@ -1063,9 +1103,10 @@ st_entry_new (const gchar *text)
|
||||
* st_entry_get_text:
|
||||
* @entry: a #StEntry
|
||||
*
|
||||
* Get the text displayed on the entry
|
||||
* Get the text displayed on the entry. If @entry is empty, an empty string will
|
||||
* be returned instead of %NULL.
|
||||
*
|
||||
* Returns: the text for the entry. This must not be freed by the application
|
||||
* Returns: (transfer none): the text for the entry
|
||||
*/
|
||||
const gchar *
|
||||
st_entry_get_text (StEntry *entry)
|
||||
@ -1084,7 +1125,8 @@ st_entry_get_text (StEntry *entry)
|
||||
* @entry: a #StEntry
|
||||
* @text: (nullable): text to set the entry to
|
||||
*
|
||||
* Sets the text displayed on the entry
|
||||
* Sets the text displayed on the entry. If @text is %NULL, the #ClutterText
|
||||
* will instead be set to an empty string.
|
||||
*/
|
||||
void
|
||||
st_entry_set_text (StEntry *entry,
|
||||
@ -1106,10 +1148,9 @@ 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 #StEntry. The entry is
|
||||
* owned by the #StEntry and should not be unref'ed by the application.
|
||||
* Returns: (transfer none): the #ClutterText used by @entry
|
||||
*/
|
||||
ClutterActor*
|
||||
st_entry_get_clutter_text (StEntry *entry)
|
||||
@ -1125,8 +1166,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,
|
||||
@ -1146,10 +1187,13 @@ 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
|
||||
* 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.
|
||||
*
|
||||
* Returns: the current value of the hint property. This string is owned by the
|
||||
* #StEntry and should not be freed or modified.
|
||||
* 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
|
||||
*/
|
||||
const gchar *
|
||||
st_entry_get_hint_text (StEntry *entry)
|
||||
@ -1200,6 +1244,8 @@ 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)
|
||||
@ -1245,6 +1291,8 @@ 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)
|
||||
@ -1305,7 +1353,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,
|
||||
@ -1324,7 +1372,9 @@ st_entry_set_primary_icon (StEntry *entry,
|
||||
* st_entry_get_primary_icon:
|
||||
* @entry: a #StEntry
|
||||
*
|
||||
* Returns: (transfer none): a #ClutterActor
|
||||
* Get the value of the #StEntry:primary-icon property.
|
||||
*
|
||||
* Returns: (nullable) (transfer none): a #ClutterActor
|
||||
*/
|
||||
ClutterActor *
|
||||
st_entry_get_primary_icon (StEntry *entry)
|
||||
@ -1342,7 +1392,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,
|
||||
@ -1361,7 +1411,9 @@ st_entry_set_secondary_icon (StEntry *entry,
|
||||
* st_entry_get_secondary_icon:
|
||||
* @entry: a #StEntry
|
||||
*
|
||||
* Returns: (transfer none): a #ClutterActor
|
||||
* Get the value of the #StEntry:secondary-icon property.
|
||||
*
|
||||
* Returns: (nullable) (transfer none): a #ClutterActor
|
||||
*/
|
||||
ClutterActor *
|
||||
st_entry_get_secondary_icon (StEntry *entry)
|
||||
@ -1377,9 +1429,9 @@ st_entry_get_secondary_icon (StEntry *entry)
|
||||
/**
|
||||
* st_entry_set_hint_actor:
|
||||
* @entry: a #StEntry
|
||||
* @hint_actor: (allow-none): a #ClutterActor
|
||||
* @hint_actor: (nullable): 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,
|
||||
@ -1412,7 +1464,9 @@ st_entry_set_hint_actor (StEntry *entry,
|
||||
* st_entry_get_hint_actor:
|
||||
* @entry: a #StEntry
|
||||
*
|
||||
* Returns: (transfer none): a #ClutterActor
|
||||
* Get the value of the #StEntry:hint-actor property.
|
||||
*
|
||||
* Returns: (nullable) (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.
|
||||
*
|
||||
* Return value: (transfer none): the focus manager for @stage
|
||||
* Returns: (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.
|
||||
*
|
||||
* Return value: (transfer none): the focus group root, or %NULL if
|
||||
* Returns: (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.
|
||||
*
|
||||
* Return value: value of the current element.
|
||||
* Returns: 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.
|
||||
*
|
||||
* Return value: maximum value of the accessible.
|
||||
* Returns: 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.
|
||||
*
|
||||
* Return value: minimum value of the accessible.
|
||||
* Returns: 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.
|
||||
*
|
||||
* Return value: value of the current element.
|
||||
* Returns: value of the current element.
|
||||
*/
|
||||
st_generic_accessible_signals[GET_MINIMUM_INCREMENT] =
|
||||
g_signal_new ("get-minimum-increment",
|
||||
@ -221,6 +221,16 @@ 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.
|
||||
*
|
||||
* Return value: a newly created #StIconColors. Free with st_icon_colors_unref()
|
||||
* Returns: a newly created #StIconColors. Free with st_icon_colors_unref()
|
||||
*/
|
||||
StIconColors *
|
||||
st_icon_colors_new (void)
|
||||
@ -107,6 +107,8 @@ 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,6 +255,11 @@ 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",
|
||||
@ -262,6 +267,11 @@ 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",
|
||||
@ -269,6 +279,11 @@ 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",
|
||||
@ -276,6 +291,12 @@ 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",
|
||||
@ -283,6 +304,12 @@ 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",
|
||||
@ -524,7 +551,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
|
||||
*/
|
||||
@ -538,10 +565,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 #GThemedIcon that
|
||||
* is currently set.
|
||||
* This is a convenience method to get the icon name of the current icon, if it
|
||||
* is currenyly a #GThemedIcon, or %NULL otherwise.
|
||||
*
|
||||
* Returns: (transfer none): The name of the icon or %NULL if no icon is set
|
||||
* Returns: (transfer none) (nullable): The name of the icon or %NULL
|
||||
*/
|
||||
const gchar *
|
||||
st_icon_get_icon_name (StIcon *icon)
|
||||
@ -592,7 +619,7 @@ st_icon_set_icon_name (StIcon *icon,
|
||||
*
|
||||
* Gets the current #GIcon in use.
|
||||
*
|
||||
* Returns: (transfer none): The current #GIcon, if set, otherwise %NULL
|
||||
* Returns: (nullable) (transfer none): The current #GIcon, if set, otherwise %NULL
|
||||
*/
|
||||
GIcon *
|
||||
st_icon_get_gicon (StIcon *icon)
|
||||
|
@ -329,7 +329,10 @@ g_loadable_icon_interface_init (GLoadableIconIface *iface)
|
||||
*
|
||||
* Creates a new #StImageContent, a simple content for sized images.
|
||||
*
|
||||
* Return value: (transfer full): the newly created #StImageContent content
|
||||
* See #ClutterImage for setting the actual image to display or #StIcon for
|
||||
* displaying icons.
|
||||
*
|
||||
* Returns: (transfer full): the newly created #StImageContent content
|
||||
* Use g_object_unref() when done.
|
||||
*/
|
||||
ClutterContent *
|
||||
|
@ -274,6 +274,11 @@ 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",
|
||||
@ -281,6 +286,11 @@ 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",
|
||||
@ -314,9 +324,9 @@ st_label_init (StLabel *label)
|
||||
|
||||
/**
|
||||
* st_label_new:
|
||||
* @text: text to set the label to
|
||||
* @text: (nullable): text to set the label to
|
||||
*
|
||||
* Create a new #StLabel with the specified label
|
||||
* Create a new #StLabel with the label specified by @text.
|
||||
*
|
||||
* Returns: a new #StLabel
|
||||
*/
|
||||
@ -335,9 +345,10 @@ 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: the text for the label. This must not be freed by the application
|
||||
* Returns: (transfer none): the text for the label. This must not be freed by
|
||||
* the application
|
||||
*/
|
||||
const gchar *
|
||||
st_label_get_text (StLabel *label)
|
||||
@ -350,9 +361,9 @@ st_label_get_text (StLabel *label)
|
||||
/**
|
||||
* st_label_set_text:
|
||||
* @label: a #StLabel
|
||||
* @text: text to set the label to
|
||||
* @text: (nullable): text to set the label to
|
||||
*
|
||||
* Sets the text displayed on the label
|
||||
* Sets the text displayed by the label.
|
||||
*/
|
||||
void
|
||||
st_label_set_text (StLabel *label,
|
||||
@ -382,10 +393,11 @@ st_label_set_text (StLabel *label,
|
||||
* st_label_get_clutter_text:
|
||||
* @label: a #StLabel
|
||||
*
|
||||
* Retrieve the internal #ClutterText so that extra parameters can be set
|
||||
* Retrieve the internal #ClutterText used by @label so that extra parameters
|
||||
* can be set.
|
||||
*
|
||||
* Returns: (transfer none): ethe #ClutterText used by #StLabel. The label
|
||||
* is owned by the #StLabel and should not be unref'ed by the application.
|
||||
* Returns: (transfer none): the #ClutterText used by #StLabel. The actor
|
||||
* is owned by the #StLabel and should not be destroyed by the application.
|
||||
*/
|
||||
ClutterActor*
|
||||
st_label_get_clutter_text (StLabel *label)
|
||||
|
@ -133,12 +133,23 @@ 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 to text in the entry is masked or not",
|
||||
"Whether the 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",
|
||||
@ -202,12 +213,15 @@ 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, #FALSE otherwise
|
||||
* @value: %TRUE to show the peek-icon in the entry
|
||||
*
|
||||
* Sets whether to show or hide the peek-icon in the password entry.
|
||||
* 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.
|
||||
*/
|
||||
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;
|
||||
|
||||
@ -231,6 +245,8 @@ st_password_entry_set_show_peek_icon (StPasswordEntry *entry, gboolean value)
|
||||
* @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)
|
||||
@ -246,12 +262,13 @@ 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;
|
||||
@ -284,6 +301,8 @@ st_password_entry_set_password_visible (StPasswordEntry *entry, gboolean value)
|
||||
* @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,6 +508,8 @@ _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,11 +538,21 @@ 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",
|
||||
@ -552,6 +562,13 @@ 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),
|
||||
@ -560,6 +577,12 @@ 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),
|
||||
@ -982,10 +1005,9 @@ st_scroll_bar_set_adjustment (StScrollBar *bar,
|
||||
* st_scroll_bar_get_adjustment:
|
||||
* @bar: a #StScrollbar
|
||||
*
|
||||
* Gets the adjustment object that stores the current position
|
||||
* of the scrollbar.
|
||||
* Gets the #StAdjustment that controls the current position of @bar.
|
||||
*
|
||||
* Return value: (transfer none): the adjustment
|
||||
* Returns: (transfer none): an #StAdjustment
|
||||
*/
|
||||
StAdjustment *
|
||||
st_scroll_bar_get_adjustment (StScrollBar *bar)
|
||||
|
@ -389,6 +389,12 @@ 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",
|
||||
@ -396,6 +402,12 @@ 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",
|
||||
@ -403,6 +415,11 @@ 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",
|
||||
@ -420,6 +437,13 @@ 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,6 +830,11 @@ 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",
|
||||
@ -837,6 +842,11 @@ 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",
|
||||
@ -844,6 +854,11 @@ 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",
|
||||
@ -852,6 +867,11 @@ 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",
|
||||
@ -860,6 +880,11 @@ 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",
|
||||
@ -867,6 +892,11 @@ 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",
|
||||
@ -874,6 +904,11 @@ 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",
|
||||
@ -881,6 +916,11 @@ 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",
|
||||
@ -995,6 +1035,13 @@ 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)
|
||||
{
|
||||
@ -1005,9 +1052,9 @@ st_scroll_view_new (void)
|
||||
* st_scroll_view_get_hscroll_bar:
|
||||
* @scroll: a #StScrollView
|
||||
*
|
||||
* Gets the horizontal scrollbar of the scrollbiew
|
||||
* Gets the horizontal #StScrollBar of the #StScrollView.
|
||||
*
|
||||
* Return value: (transfer none): the horizontal #StScrollBar
|
||||
* Returns: (transfer none): the horizontal scrollbar
|
||||
*/
|
||||
ClutterActor *
|
||||
st_scroll_view_get_hscroll_bar (StScrollView *scroll)
|
||||
@ -1021,9 +1068,9 @@ st_scroll_view_get_hscroll_bar (StScrollView *scroll)
|
||||
* st_scroll_view_get_vscroll_bar:
|
||||
* @scroll: a #StScrollView
|
||||
*
|
||||
* Gets the vertical scrollbar of the scrollbiew
|
||||
* Gets the vertical scrollbar of the #StScrollView.
|
||||
*
|
||||
* Return value: (transfer none): the vertical #StScrollBar
|
||||
* Returns: (transfer none): the vertical #StScrollBar
|
||||
*/
|
||||
ClutterActor *
|
||||
st_scroll_view_get_vscroll_bar (StScrollView *scroll)
|
||||
@ -1033,6 +1080,14 @@ 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)
|
||||
{
|
||||
@ -1047,6 +1102,13 @@ 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)
|
||||
@ -1069,6 +1131,14 @@ 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)
|
||||
{
|
||||
@ -1083,6 +1153,13 @@ 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)
|
||||
@ -1105,6 +1182,13 @@ 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)
|
||||
@ -1125,6 +1209,14 @@ 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)
|
||||
{
|
||||
@ -1167,7 +1259,9 @@ st_scroll_view_set_overlay_scrollbars (StScrollView *scroll,
|
||||
* st_scroll_view_get_overlay_scrollbars:
|
||||
* @scroll: A #StScrollView
|
||||
*
|
||||
* Gets the value set by st_scroll_view_set_overlay_scrollbars().
|
||||
* Gets whether scrollbars are painted on top of the content.
|
||||
*
|
||||
* Returns: %TRUE if enabled, %FALSE otherwise
|
||||
*/
|
||||
gboolean
|
||||
st_scroll_view_get_overlay_scrollbars (StScrollView *scroll)
|
||||
|
@ -86,6 +86,40 @@ 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",
|
||||
@ -93,6 +127,17 @@ 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",
|
||||
@ -104,6 +149,18 @@ 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,
|
||||
@ -116,11 +173,17 @@ st_scrollable_set_adjustments (StScrollable *scrollable,
|
||||
|
||||
/**
|
||||
* st_scroll_bar_get_adjustments:
|
||||
* @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
|
||||
* @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
|
||||
*
|
||||
* 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,41 +199,89 @@ 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",
|
||||
"Weather the a11y magnifier is active",
|
||||
"Whether 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",
|
||||
@ -338,9 +386,9 @@ st_settings_init (StSettings *settings)
|
||||
/**
|
||||
* st_settings_get:
|
||||
*
|
||||
* Gets the #StSettings
|
||||
* Gets the global #StSettings object.
|
||||
*
|
||||
* Returns: (transfer none): a settings object
|
||||
* Returns: (transfer none): the global #StSettings 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.
|
||||
*
|
||||
* Return value: %TRUE if the two shadows are identical
|
||||
* Returns: %TRUE if the two shadows are identical
|
||||
*/
|
||||
gboolean
|
||||
st_shadow_equal (StShadow *shadow,
|
||||
@ -216,6 +216,13 @@ 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,6 +100,12 @@ 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),
|
||||
@ -108,6 +114,13 @@ 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),
|
||||
@ -799,7 +812,7 @@ st_texture_cache_free_bind (gpointer data)
|
||||
|
||||
/**
|
||||
* st_texture_cache_bind_cairo_surface_property:
|
||||
* @cache:
|
||||
* @cache: A #StTextureCache
|
||||
* @object: A #GObject with a property @property_name of type #cairo_surface_t
|
||||
* @property_name: Name of a property
|
||||
*
|
||||
@ -810,7 +823,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.
|
||||
*
|
||||
* Return value: (transfer none): A new #GIcon
|
||||
* Returns: (transfer none): A new #GIcon
|
||||
*/
|
||||
GIcon *
|
||||
st_texture_cache_bind_cairo_surface_property (StTextureCache *cache,
|
||||
@ -879,7 +892,7 @@ st_texture_cache_load (StTextureCache *cache,
|
||||
|
||||
/**
|
||||
* ensure_request:
|
||||
* @cache:
|
||||
* @cache: A #StTextureCache
|
||||
* @key: A cache key
|
||||
* @policy: Cache policy
|
||||
* @request: (out): If no request is outstanding, one will be created and returned here
|
||||
@ -932,8 +945,8 @@ ensure_request (StTextureCache *cache,
|
||||
|
||||
/**
|
||||
* st_texture_cache_load_gicon:
|
||||
* @cache: The texture cache instance
|
||||
* @theme_node: (nullable): The #StThemeNode to use for colors, or NULL
|
||||
* @cache: A #StTextureCache
|
||||
* @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
|
||||
@ -944,7 +957,7 @@ ensure_request (StTextureCache *cache,
|
||||
* icon isn't loaded already, the texture will be filled
|
||||
* asynchronously.
|
||||
*
|
||||
* Return Value: (transfer none): A new #ClutterActor for the icon, or %NULL if not found
|
||||
* Returns: (transfer none) (nullable): A new #ClutterActor for the icon, or %NULL if not found
|
||||
*/
|
||||
ClutterActor *
|
||||
st_texture_cache_load_gicon (StTextureCache *cache,
|
||||
@ -1371,7 +1384,7 @@ st_texture_cache_load_sliced_image (StTextureCache *cache,
|
||||
|
||||
/**
|
||||
* st_texture_cache_load_file_async:
|
||||
* @cache: The texture cache instance
|
||||
* @cache: A #StTextureCache
|
||||
* @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
|
||||
@ -1382,7 +1395,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.
|
||||
*
|
||||
* Return value: (transfer none): A new #ClutterActor with no image loaded initially.
|
||||
* Returns: (transfer none): A new #ClutterActor with no image loaded initially.
|
||||
*/
|
||||
ClutterActor *
|
||||
st_texture_cache_load_file_async (StTextureCache *cache,
|
||||
@ -1612,7 +1625,7 @@ static StTextureCache *instance = NULL;
|
||||
/**
|
||||
* st_texture_cache_get_default:
|
||||
*
|
||||
* Return value: (transfer none): The global texture cache
|
||||
* Returns: (transfer none): The global texture cache
|
||||
*/
|
||||
StTextureCache*
|
||||
st_texture_cache_get_default (void)
|
||||
@ -1622,6 +1635,13 @@ 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,16 +118,23 @@ st_theme_context_class_init (StThemeContextClass *klass)
|
||||
/**
|
||||
* StThemeContext:scale-factor:
|
||||
*
|
||||
* The scaling factor used or high dpi scaling.
|
||||
* The scaling factor used for HiDPI scaling.
|
||||
*/
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_SCALE_FACTOR,
|
||||
g_param_spec_int ("scale-factor",
|
||||
"Scale factor",
|
||||
"Integer scale factor used for high dpi scaling",
|
||||
"Integer scale factor used for HiDPI 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),
|
||||
@ -214,6 +221,8 @@ 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)
|
||||
@ -296,7 +305,7 @@ on_icon_theme_changed (StTextureCache *cache,
|
||||
*
|
||||
* Gets a singleton theme context associated with the stage.
|
||||
*
|
||||
* Return value: (transfer none): the singleton theme context for the stage
|
||||
* Returns: (transfer none): the singleton theme context for the stage
|
||||
*/
|
||||
StThemeContext *
|
||||
st_theme_context_get_for_stage (ClutterStage *stage)
|
||||
@ -320,6 +329,7 @@ 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
|
||||
@ -358,7 +368,7 @@ st_theme_context_set_theme (StThemeContext *context,
|
||||
*
|
||||
* Gets the default theme for the context. See st_theme_context_set_theme()
|
||||
*
|
||||
* Return value: (transfer none): the default theme for the context
|
||||
* Returns: (transfer none): the default theme for the context
|
||||
*/
|
||||
StTheme *
|
||||
st_theme_context_get_theme (StThemeContext *context)
|
||||
@ -376,7 +386,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
|
||||
@ -401,7 +411,7 @@ st_theme_context_set_font (StThemeContext *context,
|
||||
*
|
||||
* Gets the default font for the theme context. See st_theme_context_set_font().
|
||||
*
|
||||
* Return value: the default font for the theme context.
|
||||
* Returns: the default font for the theme context.
|
||||
*/
|
||||
const PangoFontDescription *
|
||||
st_theme_context_get_font (StThemeContext *context)
|
||||
@ -419,7 +429,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.
|
||||
*
|
||||
* Return value: (transfer none): the root node of the context's style tree
|
||||
* Returns: (transfer none): the root node of the context's style tree
|
||||
*/
|
||||
StThemeNode *
|
||||
st_theme_context_get_root_node (StThemeContext *context)
|
||||
@ -439,7 +449,7 @@ st_theme_context_get_root_node (StThemeContext *context)
|
||||
* Return an existing node matching @node, or if that isn't possible,
|
||||
* @node itself.
|
||||
*
|
||||
* Return value: (transfer none): a node with the same properties as @node
|
||||
* Returns: (transfer none): a node with the same properties as @node
|
||||
*/
|
||||
StThemeNode *
|
||||
st_theme_context_intern_node (StThemeContext *context,
|
||||
@ -461,7 +471,7 @@ st_theme_context_intern_node (StThemeContext *context,
|
||||
*
|
||||
* Return the current scale factor of @context.
|
||||
*
|
||||
* Return value: a scale factor
|
||||
* Returns: an integer scale factor
|
||||
*/
|
||||
int
|
||||
st_theme_context_get_scale_factor (StThemeContext *context)
|
||||
|
@ -180,11 +180,11 @@ split_on_whitespace (const gchar *s)
|
||||
* @pseudo_class: (nullable): a whitespace-separated list of pseudo-classes
|
||||
* (like 'hover' or 'visited') to match CSS rules against
|
||||
*
|
||||
* Creates a new #StThemeNode. Once created, a node is immutable. Of any
|
||||
* Creates a new #StThemeNode. Once created, a node is immutable. If any
|
||||
* of the attributes of the node (like the @element_class) change the node
|
||||
* and its child nodes must be destroyed and recreated.
|
||||
*
|
||||
* Return value: (transfer full): the theme node
|
||||
* Returns: (transfer full): a new #StThemeNode
|
||||
*/
|
||||
StThemeNode *
|
||||
st_theme_node_new (StThemeContext *context,
|
||||
@ -229,8 +229,8 @@ st_theme_node_new (StThemeContext *context,
|
||||
*
|
||||
* Gets the parent themed element node.
|
||||
*
|
||||
* Return value: (transfer none): the parent #StThemeNode, or %NULL if this
|
||||
* is the root node of the tree of theme elements.
|
||||
* Returns: (nullable) (transfer none): the parent #StThemeNode, or %NULL if
|
||||
* this is the root node of the tree of theme elements.
|
||||
*/
|
||||
StThemeNode *
|
||||
st_theme_node_get_parent (StThemeNode *node)
|
||||
@ -246,7 +246,7 @@ st_theme_node_get_parent (StThemeNode *node)
|
||||
*
|
||||
* Gets the theme stylesheet set that styles this node
|
||||
*
|
||||
* Return value: (transfer none): the theme stylesheet set
|
||||
* Returns: (transfer none): the theme stylesheet set
|
||||
*/
|
||||
StTheme *
|
||||
st_theme_node_get_theme (StThemeNode *node)
|
||||
@ -256,6 +256,14 @@ st_theme_node_get_theme (StThemeNode *node)
|
||||
return node->theme;
|
||||
}
|
||||
|
||||
/**
|
||||
* st_theme_node_get_element_type:
|
||||
* @node: a #StThemeNode
|
||||
*
|
||||
* Get the element #GType for @node.
|
||||
*
|
||||
* Returns: the element type
|
||||
*/
|
||||
GType
|
||||
st_theme_node_get_element_type (StThemeNode *node)
|
||||
{
|
||||
@ -264,6 +272,14 @@ st_theme_node_get_element_type (StThemeNode *node)
|
||||
return node->element_type;
|
||||
}
|
||||
|
||||
/**
|
||||
* st_theme_node_get_element_id:
|
||||
* @node: a #StThemeNode
|
||||
*
|
||||
* Get the unqiue element ID for @node.
|
||||
*
|
||||
* Returns: (transfer none): the element's ID
|
||||
*/
|
||||
const char *
|
||||
st_theme_node_get_element_id (StThemeNode *node)
|
||||
{
|
||||
@ -274,6 +290,9 @@ st_theme_node_get_element_id (StThemeNode *node)
|
||||
|
||||
/**
|
||||
* st_theme_node_get_element_classes:
|
||||
* @node: a #StThemeNode
|
||||
*
|
||||
* Get the list of element classes for @node.
|
||||
*
|
||||
* Returns: (transfer none): the element's classes
|
||||
*/
|
||||
@ -287,6 +306,9 @@ st_theme_node_get_element_classes (StThemeNode *node)
|
||||
|
||||
/**
|
||||
* st_theme_node_get_pseudo_classes:
|
||||
* @node: a #StThemeNode
|
||||
*
|
||||
* Get the list of pseudo-classes for @node (eg. `:focused`).
|
||||
*
|
||||
* Returns: (transfer none): the element's pseudo-classes
|
||||
*/
|
||||
@ -307,21 +329,13 @@ st_theme_node_get_pseudo_classes (StThemeNode *node)
|
||||
* the same CSS rules and have the same style properties. However, two
|
||||
* nodes that have ended up with identical style properties do not
|
||||
* necessarily compare equal.
|
||||
* In detail, @node_a and @node_b are considered equal iff
|
||||
* <itemizedlist>
|
||||
* <listitem>
|
||||
* <para>they share the same #StTheme and #StThemeContext</para>
|
||||
* </listitem>
|
||||
* <listitem>
|
||||
* <para>they have the same parent</para>
|
||||
* </listitem>
|
||||
* <listitem>
|
||||
* <para>they have the same element type</para>
|
||||
* </listitem>
|
||||
* <listitem>
|
||||
* <para>their id, class, pseudo-class and inline-style match</para>
|
||||
* </listitem>
|
||||
* </itemizedlist>
|
||||
*
|
||||
* In detail, @node_a and @node_b are considered equal if and only if:
|
||||
*
|
||||
* - they share the same #StTheme and #StThemeContext
|
||||
* - they have the same parent
|
||||
* - they have the same element type
|
||||
* - their id, class, pseudo-class and inline-style match
|
||||
*
|
||||
* Returns: %TRUE if @node_a equals @node_b
|
||||
*/
|
||||
@ -383,6 +397,14 @@ st_theme_node_equal (StThemeNode *node_a, StThemeNode *node_b)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* st_theme_node_hash:
|
||||
* @node: a #StThemeNode
|
||||
*
|
||||
* Converts @node to a hash value.
|
||||
*
|
||||
* Returns: a hash value corresponding to @node
|
||||
*/
|
||||
guint
|
||||
st_theme_node_hash (StThemeNode *node)
|
||||
{
|
||||
@ -637,7 +659,7 @@ get_color_from_term (StThemeNode *node,
|
||||
*
|
||||
* See also st_theme_node_get_color(), which provides a simpler API.
|
||||
*
|
||||
* Return value: %TRUE if the property was found in the properties for this
|
||||
* Returns: %TRUE if the property was found in the properties for this
|
||||
* theme node (or in the properties of parent nodes when inheriting.)
|
||||
*/
|
||||
gboolean
|
||||
@ -727,7 +749,7 @@ st_theme_node_get_color (StThemeNode *node,
|
||||
*
|
||||
* See also st_theme_node_get_double(), which provides a simpler API.
|
||||
*
|
||||
* Return value: %TRUE if the property was found in the properties for this
|
||||
* Returns: %TRUE if the property was found in the properties for this
|
||||
* theme node (or in the properties of parent nodes when inheriting.)
|
||||
*/
|
||||
gboolean
|
||||
@ -780,7 +802,7 @@ st_theme_node_lookup_double (StThemeNode *node,
|
||||
* Generically looks up a property containing a single time value,
|
||||
* which is converted to milliseconds.
|
||||
*
|
||||
* Return value: %TRUE if the property was found in the properties for this
|
||||
* Returns: %TRUE if the property was found in the properties for this
|
||||
* theme node (or in the properties of parent nodes when inheriting.)
|
||||
*/
|
||||
gboolean
|
||||
@ -837,7 +859,7 @@ st_theme_node_lookup_time (StThemeNode *node,
|
||||
* and lets you handle the case where the theme does not specify the
|
||||
* indicated value.
|
||||
*
|
||||
* Return value: the value found. If @property_name is not
|
||||
* Returns: the value found. If @property_name is not
|
||||
* found, a warning will be logged and 0 will be returned.
|
||||
*/
|
||||
gdouble
|
||||
@ -872,7 +894,7 @@ st_theme_node_get_double (StThemeNode *node,
|
||||
*
|
||||
* See also st_theme_node_get_url(), which provides a simpler API.
|
||||
*
|
||||
* Return value: %TRUE if the property was found in the properties for this
|
||||
* Returns: %TRUE if the property was found in the properties for this
|
||||
* theme node (or in the properties of parent nodes when inheriting.)
|
||||
*/
|
||||
gboolean
|
||||
@ -928,7 +950,7 @@ st_theme_node_lookup_url (StThemeNode *node,
|
||||
* and lets you handle the case where the theme does not specify the
|
||||
* indicated value.
|
||||
*
|
||||
* Returns: (transfer full): the newly allocated value if found.
|
||||
* Returns: (nullable) (transfer full): the newly allocated value if found.
|
||||
* If @property_name is not found, a warning will be logged and %NULL
|
||||
* will be returned.
|
||||
*/
|
||||
@ -1169,7 +1191,7 @@ get_length_internal (StThemeNode *node,
|
||||
*
|
||||
* See also st_theme_node_get_length(), which provides a simpler API.
|
||||
*
|
||||
* Return value: %TRUE if the property was found in the properties for this
|
||||
* Returns: %TRUE if the property was found in the properties for this
|
||||
* theme node (or in the properties of parent nodes when inheriting.)
|
||||
*/
|
||||
gboolean
|
||||
@ -1204,9 +1226,10 @@ st_theme_node_lookup_length (StThemeNode *node,
|
||||
* this does not print a warning if the property is not found; it just
|
||||
* returns 0.
|
||||
*
|
||||
* See also st_theme_node_lookup_length(), which provides more options.
|
||||
* See also st_theme_node_lookup_length(), which provides more options. The
|
||||
* returned value is in physical pixels, as opposed to logical pixels.
|
||||
*
|
||||
* Return value: the length, in pixels, or 0 if the property was not found.
|
||||
* Returns: the length, in pixels, or 0 if the property was not found.
|
||||
*/
|
||||
gdouble
|
||||
st_theme_node_get_length (StThemeNode *node,
|
||||
@ -1807,6 +1830,15 @@ _st_theme_node_ensure_geometry (StThemeNode *node)
|
||||
node->height = node->min_height;
|
||||
}
|
||||
|
||||
/**
|
||||
* st_theme_node_get_border_width:
|
||||
* @node: a #StThemeNode
|
||||
* @side: a #StCorner
|
||||
*
|
||||
* Get the border width for @node on @side, in physical pixels.
|
||||
*
|
||||
* Returns: the border width in physical pixels
|
||||
*/
|
||||
int
|
||||
st_theme_node_get_border_width (StThemeNode *node,
|
||||
StSide side)
|
||||
@ -1819,6 +1851,15 @@ st_theme_node_get_border_width (StThemeNode *node,
|
||||
return node->border_width[side];
|
||||
}
|
||||
|
||||
/**
|
||||
* st_theme_node_get_border_radius:
|
||||
* @node: a #StThemeNode
|
||||
* @corner: a #StCorner
|
||||
*
|
||||
* Get the border radius for @node at @corner, in physical pixels.
|
||||
*
|
||||
* Returns: the border radius in physical pixels
|
||||
*/
|
||||
int
|
||||
st_theme_node_get_border_radius (StThemeNode *node,
|
||||
StCorner corner)
|
||||
@ -1831,6 +1872,14 @@ st_theme_node_get_border_radius (StThemeNode *node,
|
||||
return node->border_radius[corner];
|
||||
}
|
||||
|
||||
/**
|
||||
* st_theme_node_get_outline_width:
|
||||
* @node: a #StThemeNode
|
||||
*
|
||||
* Get the width of the outline for @node, in physical pixels.
|
||||
*
|
||||
* Returns: the width in physical pixels
|
||||
*/
|
||||
int
|
||||
st_theme_node_get_outline_width (StThemeNode *node)
|
||||
{
|
||||
@ -1859,6 +1908,14 @@ st_theme_node_get_outline_color (StThemeNode *node,
|
||||
*color = node->outline_color;
|
||||
}
|
||||
|
||||
/**
|
||||
* st_theme_node_get_width:
|
||||
* @node: a #StThemeNode
|
||||
*
|
||||
* Get the width for @node, in physical pixels.
|
||||
*
|
||||
* Returns: the width in physical pixels
|
||||
*/
|
||||
int
|
||||
st_theme_node_get_width (StThemeNode *node)
|
||||
{
|
||||
@ -1868,6 +1925,14 @@ st_theme_node_get_width (StThemeNode *node)
|
||||
return node->width;
|
||||
}
|
||||
|
||||
/**
|
||||
* st_theme_node_get_height:
|
||||
* @node: a #StThemeNode
|
||||
*
|
||||
* Get the height for @node, in physical pixels.
|
||||
*
|
||||
* Returns: the height in physical pixels
|
||||
*/
|
||||
int
|
||||
st_theme_node_get_height (StThemeNode *node)
|
||||
{
|
||||
@ -1877,6 +1942,14 @@ st_theme_node_get_height (StThemeNode *node)
|
||||
return node->height;
|
||||
}
|
||||
|
||||
/**
|
||||
* st_theme_node_get_min_width:
|
||||
* @node: a #StThemeNode
|
||||
*
|
||||
* Get the minimum width for @node, in physical pixels.
|
||||
*
|
||||
* Returns: the minimum width in physical pixels
|
||||
*/
|
||||
int
|
||||
st_theme_node_get_min_width (StThemeNode *node)
|
||||
{
|
||||
@ -1886,6 +1959,14 @@ st_theme_node_get_min_width (StThemeNode *node)
|
||||
return node->min_width;
|
||||
}
|
||||
|
||||
/**
|
||||
* st_theme_node_get_min_height:
|
||||
* @node: a #StThemeNode
|
||||
*
|
||||
* Get the minimum height for @node, in physical pixels.
|
||||
*
|
||||
* Returns: the minimum height in physical pixels
|
||||
*/
|
||||
int
|
||||
st_theme_node_get_min_height (StThemeNode *node)
|
||||
{
|
||||
@ -1895,6 +1976,14 @@ st_theme_node_get_min_height (StThemeNode *node)
|
||||
return node->min_height;
|
||||
}
|
||||
|
||||
/**
|
||||
* st_theme_node_get_max_width:
|
||||
* @node: a #StThemeNode
|
||||
*
|
||||
* Get the maximum width for @node, in physical pixels.
|
||||
*
|
||||
* Returns: the maximum width in physical pixels
|
||||
*/
|
||||
int
|
||||
st_theme_node_get_max_width (StThemeNode *node)
|
||||
{
|
||||
@ -1904,6 +1993,14 @@ st_theme_node_get_max_width (StThemeNode *node)
|
||||
return node->max_width;
|
||||
}
|
||||
|
||||
/**
|
||||
* st_theme_node_get_max_height:
|
||||
* @node: a #StThemeNode
|
||||
*
|
||||
* Get the maximum height for @node, in physical pixels.
|
||||
*
|
||||
* Returns: the maximum height in physical pixels
|
||||
*/
|
||||
int
|
||||
st_theme_node_get_max_height (StThemeNode *node)
|
||||
{
|
||||
@ -2270,6 +2367,16 @@ st_theme_node_get_border_color (StThemeNode *node,
|
||||
*color = node->border_color[side];
|
||||
}
|
||||
|
||||
/**
|
||||
* st_theme_node_get_padding:
|
||||
* @node: a #StThemeNode
|
||||
* @side: a #StSide
|
||||
*
|
||||
* Get the padding for @node on @side, in physical pixels. This corresponds to
|
||||
* the CSS properties such as `padding-top`.
|
||||
*
|
||||
* Returns: the padding size in physical pixels
|
||||
*/
|
||||
double
|
||||
st_theme_node_get_padding (StThemeNode *node,
|
||||
StSide side)
|
||||
@ -2282,6 +2389,16 @@ st_theme_node_get_padding (StThemeNode *node,
|
||||
return node->padding[side];
|
||||
}
|
||||
|
||||
/**
|
||||
* st_theme_node_get_margin:
|
||||
* @node: a #StThemeNode
|
||||
* @side: a #StSide
|
||||
*
|
||||
* Get the margin for @node on @side, in physical pixels. This corresponds to
|
||||
* the CSS properties such as `margin-top`.
|
||||
*
|
||||
* Returns: the margin size in physical pixels
|
||||
*/
|
||||
double
|
||||
st_theme_node_get_margin (StThemeNode *node,
|
||||
StSide side)
|
||||
@ -2326,6 +2443,15 @@ st_theme_node_get_transition_duration (StThemeNode *node)
|
||||
return factor * node->transition_duration;
|
||||
}
|
||||
|
||||
/**
|
||||
* st_theme_node_get_icon_style:
|
||||
* @node: a #StThemeNode
|
||||
*
|
||||
* Get the icon style for @node (eg. symbolic, regular). This corresponds to the
|
||||
* special `-st-icon-style` CSS property.
|
||||
*
|
||||
* Returns: the icon style for @node
|
||||
*/
|
||||
StIconStyle
|
||||
st_theme_node_get_icon_style (StThemeNode *node)
|
||||
{
|
||||
@ -2368,6 +2494,14 @@ st_theme_node_get_icon_style (StThemeNode *node)
|
||||
return ST_ICON_STYLE_REQUESTED;
|
||||
}
|
||||
|
||||
/**
|
||||
* st_theme_node_get_text_decoration
|
||||
* @node: a #StThemeNode
|
||||
*
|
||||
* Get the text decoration for @node (eg. underline, line-through, etc).
|
||||
*
|
||||
* Returns: the text decoration for @node
|
||||
*/
|
||||
StTextDecoration
|
||||
st_theme_node_get_text_decoration (StThemeNode *node)
|
||||
{
|
||||
@ -2435,6 +2569,14 @@ st_theme_node_get_text_decoration (StThemeNode *node)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* st_theme_node_get_text_align:
|
||||
* @node: a #StThemeNode
|
||||
*
|
||||
* Get the text alignment of @node.
|
||||
*
|
||||
* Returns: the alignment of text for @node
|
||||
*/
|
||||
StTextAlign
|
||||
st_theme_node_get_text_align(StThemeNode *node)
|
||||
{
|
||||
@ -2486,9 +2628,9 @@ st_theme_node_get_text_align(StThemeNode *node)
|
||||
* st_theme_node_get_letter_spacing:
|
||||
* @node: a #StThemeNode
|
||||
*
|
||||
* Gets the value for the letter-spacing style property, in pixels.
|
||||
* Gets the value for the letter-spacing style property, in physical pixels.
|
||||
*
|
||||
* Return value: the value of the letter-spacing property, if
|
||||
* Returns: the value of the letter-spacing property, if
|
||||
* found, or zero if such property has not been found.
|
||||
*/
|
||||
gdouble
|
||||
@ -2763,6 +2905,14 @@ font_variant_from_term (CRTerm *term,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* st_theme_node_get_font:
|
||||
* @node: a #StThemeNode
|
||||
*
|
||||
* Get the current font of @node as a #PangoFontDescription
|
||||
*
|
||||
* Returns: (transfer none): the current font
|
||||
*/
|
||||
const PangoFontDescription *
|
||||
st_theme_node_get_font (StThemeNode *node)
|
||||
{
|
||||
@ -2956,6 +3106,14 @@ st_theme_node_get_font (StThemeNode *node)
|
||||
return node->font_desc;
|
||||
}
|
||||
|
||||
/**
|
||||
* st_theme_node_get_font_features:
|
||||
* @node: a #StThemeNode
|
||||
*
|
||||
* Get the CSS font-features for @node.
|
||||
*
|
||||
* Returns: (transfer full): font-features as a string
|
||||
*/
|
||||
gchar *
|
||||
st_theme_node_get_font_features (StThemeNode *node)
|
||||
{
|
||||
@ -2995,7 +3153,7 @@ st_theme_node_get_font_features (StThemeNode *node)
|
||||
*
|
||||
* Gets the value for the border-image style property
|
||||
*
|
||||
* Return value: (transfer none): the border image, or %NULL
|
||||
* Returns: (transfer none): the border image, or %NULL
|
||||
* if there is no border image.
|
||||
*/
|
||||
StBorderImage *
|
||||
@ -3132,10 +3290,9 @@ st_theme_node_get_border_image (StThemeNode *node)
|
||||
* st_theme_node_get_horizontal_padding:
|
||||
* @node: a #StThemeNode
|
||||
*
|
||||
* Gets the total horizonal padding (left + right padding)
|
||||
* Gets the total horizonal padding (left + right padding), in physical pixels.
|
||||
*
|
||||
* Return value: the total horizonal padding
|
||||
* in pixels
|
||||
* Returns: the total horizonal padding in physical pixels
|
||||
*/
|
||||
double
|
||||
st_theme_node_get_horizontal_padding (StThemeNode *node)
|
||||
@ -3151,10 +3308,9 @@ st_theme_node_get_horizontal_padding (StThemeNode *node)
|
||||
* st_theme_node_get_vertical_padding:
|
||||
* @node: a #StThemeNode
|
||||
*
|
||||
* Gets the total vertical padding (top + bottom padding)
|
||||
* Gets the total vertical padding (top + bottom padding), in physical pixels.
|
||||
*
|
||||
* Return value: the total vertical padding
|
||||
* in pixels
|
||||
* Returns: the total vertical padding in physical pixels
|
||||
*/
|
||||
double
|
||||
st_theme_node_get_vertical_padding (StThemeNode *node)
|
||||
@ -3317,9 +3473,9 @@ parse_shadow_property (StThemeNode *node,
|
||||
*
|
||||
* See also st_theme_node_get_shadow(), which provides a simpler API.
|
||||
*
|
||||
* Return value: %TRUE if the property was found in the properties for this
|
||||
* theme node (or in the properties of parent nodes when inheriting.), %FALSE
|
||||
* if the property was not found, or was explicitly set to 'none'.
|
||||
* Returns: %TRUE if the property was found in the properties for this
|
||||
* theme node (or in the properties of parent nodes when inheriting.), %FALSE
|
||||
* if the property was not found, or was explicitly set to 'none'.
|
||||
*/
|
||||
gboolean
|
||||
st_theme_node_lookup_shadow (StThemeNode *node,
|
||||
@ -3402,7 +3558,8 @@ st_theme_node_lookup_shadow (StThemeNode *node,
|
||||
*
|
||||
* See also st_theme_node_lookup_shadow (), which provides more options.
|
||||
*
|
||||
* Return value: (transfer full): the shadow, or %NULL if the property was not found.
|
||||
* Returns: (nullable) (transfer full): the shadow, or %NULL if the property was
|
||||
* not found.
|
||||
*/
|
||||
StShadow *
|
||||
st_theme_node_get_shadow (StThemeNode *node,
|
||||
@ -3422,7 +3579,7 @@ st_theme_node_get_shadow (StThemeNode *node,
|
||||
*
|
||||
* Gets the value for the box-shadow style property
|
||||
*
|
||||
* Return value: (transfer none): the node's shadow, or %NULL
|
||||
* Returns: (nullable) (transfer none): the node's shadow, or %NULL
|
||||
* if node has no shadow
|
||||
*/
|
||||
StShadow *
|
||||
@ -3455,8 +3612,8 @@ st_theme_node_get_box_shadow (StThemeNode *node)
|
||||
*
|
||||
* Gets the value for the -st-background-image-shadow style property
|
||||
*
|
||||
* Return value: (transfer none): the node's background image shadow, or %NULL
|
||||
* if node has no such shadow
|
||||
* Returns: (nullable) (transfer none): the node's background image shadow, or
|
||||
* %NULL if node has no such shadow
|
||||
*/
|
||||
StShadow *
|
||||
st_theme_node_get_background_image_shadow (StThemeNode *node)
|
||||
@ -3496,7 +3653,7 @@ st_theme_node_get_background_image_shadow (StThemeNode *node)
|
||||
*
|
||||
* Gets the value for the text-shadow style property
|
||||
*
|
||||
* Return value: (transfer none): the node's text-shadow, or %NULL
|
||||
* Returns: (nullable) (transfer none): the node's text-shadow, or %NULL
|
||||
* if node has no text-shadow
|
||||
*/
|
||||
StShadow *
|
||||
@ -3542,7 +3699,7 @@ st_theme_node_get_text_shadow (StThemeNode *node)
|
||||
* Gets the colors that should be used for colorizing symbolic icons according
|
||||
* the style of this node.
|
||||
*
|
||||
* Return value: (transfer none): the icon colors to use for this theme node
|
||||
* Returns: (transfer none): the icon colors to use for this theme node
|
||||
*/
|
||||
StIconColors *
|
||||
st_theme_node_get_icon_colors (StThemeNode *node)
|
||||
@ -3941,6 +4098,8 @@ st_theme_node_get_paint_box (StThemeNode *node,
|
||||
* Tests if two theme nodes have the same borders and padding; this can be
|
||||
* used to optimize having to relayout when the style applied to a Clutter
|
||||
* actor changes colors without changing the geometry.
|
||||
*
|
||||
* Returns: %TRUE if equal, %FALSE otherwise
|
||||
*/
|
||||
gboolean
|
||||
st_theme_node_geometry_equal (StThemeNode *node,
|
||||
@ -3988,7 +4147,7 @@ st_theme_node_geometry_equal (StThemeNode *node,
|
||||
* for @other. Note that in some cases this function may return %TRUE even
|
||||
* if there is no visible difference in the painting.
|
||||
*
|
||||
* Return value: %TRUE if the two theme nodes paint identically. %FALSE if the
|
||||
* Returns: %TRUE if the two theme nodes paint identically. %FALSE if the
|
||||
* two nodes potentially paint differently.
|
||||
*/
|
||||
gboolean
|
||||
@ -4077,6 +4236,15 @@ st_theme_node_paint_equal (StThemeNode *node,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* st_theme_node_to_string:
|
||||
* @node: a #StThemeNode
|
||||
*
|
||||
* Serialize @node to a string of its #GType name, CSS ID, classes and
|
||||
* pseudo-classes.
|
||||
*
|
||||
* Returns: the serialized theme node
|
||||
*/
|
||||
gchar *
|
||||
st_theme_node_to_string (StThemeNode *node)
|
||||
{
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user