Compare commits
248 Commits
3.37.2
...
wip/fmuell
Author | SHA1 | Date | |
---|---|---|---|
e7a502e5c3 | |||
b689b35b7d | |||
01a927f388 | |||
41d5b1455f | |||
b710c6e275 | |||
4c9f42eea9 | |||
2b0731ab81 | |||
a9b803f075 | |||
73436b5276 | |||
20dcc8aa87 | |||
fdac0602db | |||
e5272c84d7 | |||
1812db7aa8 | |||
260405a49e | |||
71d37bffdf | |||
95436a08b5 | |||
13137aad9d | |||
71f55643b2 | |||
5c550daecb | |||
4e0492c517 | |||
f386103bc1 | |||
26e66aa4fd | |||
4420f52080 | |||
b4082063de | |||
bde974087a | |||
d93b51e135 | |||
730a68dffc | |||
f06c257952 | |||
7afab2c28c | |||
16a18f2ae7 | |||
704e08dc08 | |||
60311aa4d1 | |||
cceb74706a | |||
578ae29ed2 | |||
701d110493 | |||
d1cbf6c7a9 | |||
b64ce217e4 | |||
783dbe2aa9 | |||
f4ce1cf462 | |||
d04d6e069d | |||
40de201056 | |||
18234ea91a | |||
e3f3297cba | |||
e1ea1d2954 | |||
8e23ff8111 | |||
8a50a8e64c | |||
fae207811a | |||
1d86424942 | |||
2bc8175219 | |||
1e31caf0b8 | |||
8e24ac6b26 | |||
427b9ac75f | |||
f50205e9b4 | |||
168cfdd86b | |||
d339c94c18 | |||
97509bf1d2 | |||
4a9c2ee805 | |||
51e1e6d15c | |||
f0d2509dc3 | |||
95bb194356 | |||
de8b43a45d | |||
82be010fd8 | |||
2a0c116757 | |||
6cdaec4001 | |||
ed4baec40f | |||
9e8883c922 | |||
9bb64da895 | |||
049f348e25 | |||
be190cc4d9 | |||
0893789b34 | |||
7b5c6b657a | |||
9363fd3524 | |||
0ad242a81e | |||
7031449f01 | |||
06df79286d | |||
9297d87775 | |||
ef56b14553 | |||
30ff76272e | |||
52a7481ba6 | |||
14cfd74f08 | |||
fa97f7141b | |||
03bcd4c05b | |||
89574abc83 | |||
602078cbde | |||
96f63b08c2 | |||
d66cd0d206 | |||
ff13ad9e71 | |||
5e4b65d37e | |||
51fd0875d1 | |||
75f8903c7e | |||
124eb1ca18 | |||
b5d925817f | |||
c134091268 | |||
ff89693998 | |||
c26860dcb7 | |||
6757c7d20a | |||
751189253a | |||
21187a4cec | |||
b7db56ca9b | |||
261d36ba72 | |||
1e72874192 | |||
f29dbd1f18 | |||
b60836932a | |||
bf47d1b22d | |||
4ea0fca4fc | |||
809f820cd4 | |||
75235624b2 | |||
5ea54426b9 | |||
4aabcd9e7d | |||
918b3eeb42 | |||
482c655590 | |||
86b5a43008 | |||
d7cb2eeebc | |||
770231c2d7 | |||
ecdf62d63e | |||
d885486397 | |||
1524abc947 | |||
cb9842e4a4 | |||
140ab4dec1 | |||
845122497b | |||
d51a622fc0 | |||
e90466347a | |||
73f8c1c482 | |||
0ff75941ea | |||
e4bb2037ca | |||
481014ac9e | |||
6dbcb5f9da | |||
c1f06daf88 | |||
0717f76362 | |||
da738988cd | |||
e86e88ea47 | |||
ae338af1e8 | |||
3f9cc0ed37 | |||
8f8ecdb983 | |||
8f547c9d5d | |||
821f3e8ddf | |||
81be25bbd6 | |||
26d27fdbf8 | |||
c7e597cf72 | |||
e4db68a1da | |||
980a90f8fb | |||
87e4bf52b7 | |||
a368df61ac | |||
5e66b104dc | |||
08a5f41505 | |||
ec36762309 | |||
aa70020bc8 | |||
1e77e6fc79 | |||
68203e7091 | |||
cff0752bcc | |||
45d8e11123 | |||
5aee714b70 | |||
3c3c3b7c69 | |||
6ba2913075 | |||
75c4e1cd63 | |||
fb4a4ca4a2 | |||
4c2c1297be | |||
c5dbdad5fc | |||
4e05bcd3b6 | |||
3555550d5e | |||
8e05fa2728 | |||
d7c3050e2d | |||
89ba8562c3 | |||
82da73baff | |||
b2eeda9b46 | |||
0db41a3773 | |||
8d7f7e61dd | |||
3f4b253dac | |||
e4cbe5126a | |||
8357739ef8 | |||
6bef9334b7 | |||
8c49f45ac8 | |||
46600740fe | |||
c281e868a0 | |||
039431a73f | |||
d4f8ea1c53 | |||
96f5e2b33e | |||
93a542d52c | |||
f4fcba74ff | |||
cadbf7cd8b | |||
dd8e1aef51 | |||
15dc37a139 | |||
c23ad83c59 | |||
4a6f550acb | |||
8078d78c30 | |||
d7185d71c6 | |||
522ecba180 | |||
9b22f6183f | |||
b2c35e4fb0 | |||
af543daf1c | |||
baeb4079ee | |||
f91f9801b4 | |||
c5634335b0 | |||
2b4317349f | |||
96bfd1f8be | |||
33ab53068e | |||
40123ae6da | |||
df149524d4 | |||
f0ee9cdcf8 | |||
a3257e8df5 | |||
d2cf13eff4 | |||
8cd352b72b | |||
c210052dc6 | |||
0561af66e7 | |||
1e9b170d87 | |||
be02f76aa7 | |||
687928e7b7 | |||
ffdf3feb04 | |||
a60b8b3b50 | |||
3d6add68c7 | |||
85e055ffe3 | |||
1691e422e7 | |||
f442c9510e | |||
0de98eb772 | |||
30172b5625 | |||
8ae99a6898 | |||
5cfe5bf8c8 | |||
c790c01a3b | |||
d4a947b475 | |||
60d7999b6a | |||
c040d08b97 | |||
3a53b25873 | |||
d8e6f654a3 | |||
fdfcacf1db | |||
d3efbcce9b | |||
ac34dbe353 | |||
e0f3e13456 | |||
fdd9def922 | |||
771050f4d7 | |||
8451df977c | |||
ff55cf017e | |||
d36a180852 | |||
12c7f693d0 | |||
e0a8cb565e | |||
46547ae027 | |||
68745328df | |||
4582d7a183 | |||
cc5ed2fbf5 | |||
a2545d186a | |||
1ea22a5281 | |||
090057d2df | |||
b3aab7f401 | |||
8154728d09 | |||
5569090d1c | |||
fc3bc7678d | |||
8914a46669 | |||
e7ec373aee | |||
fe131f926d |
35
NEWS
35
NEWS
@ -1,3 +1,38 @@
|
||||
3.37.3
|
||||
======
|
||||
* Refactor and clean up window picker
|
||||
[Jonas D., Florian; !1297, !1298, !1305, !1345, !1353]
|
||||
* Move calendar events out of notifications list [Florian; !1282]
|
||||
* Refine app folder dialogs [Georges; !1301]
|
||||
* Hide switch-user button on lock screen if unsupported [Chingkai; #2687]
|
||||
* Refactor and clean up app picker pagination [Georges; !1271]
|
||||
* Add API to retrieve specified mimetypes from clipboards [Carlos; !1321]
|
||||
* Support prepending workspace with horizontal layouts [Florian; #2916]
|
||||
* Update microphone icon on input volume changes [fludixx; #2902]
|
||||
* Cache labels on GPU [Daniel; !1329]
|
||||
* Fix regressions in redesigned modal dialogs [Florian, Jonas D.; #2491, !1336]
|
||||
* Use GIcon for all application icons [Florian; !1342]
|
||||
* Support pre-authenticated logins in vmware environments [yun341; #1983]
|
||||
* Better support sandboxed apps with multiple .desktop files [Florian; #219]
|
||||
* Fix on-screen keyboard size in portrait orientation [Florian; #2349]
|
||||
* Plugged leaks [Sebastian, Daniel, Florian; !1306, !1319, !1341]
|
||||
* Misc. bug fixes and cleanups [Jonas D., Georges, Marco, Florian, Sebastian,
|
||||
MOZGIII, Daniel, Mariana, Jonas Å.; !1296, !1295, #2643, !1300, !1309,
|
||||
!1119, #2901, !1313, !1251, !1285, !1307, !1318, !1310, !1320, !1327, !1315,
|
||||
!1289, !1331, !1332, !1333, !1334, !1340, !1287, !1308, !1346, !1299, !1343,
|
||||
!1351, !1352, !1322]
|
||||
|
||||
Contributors:
|
||||
Marco Trevisan (Treviño), Chingkai, Jonas Dreßler, Carlos Garnacho,
|
||||
Sebastian Keller, MOZGIII, Florian Müllner, Georges Basile Stavracas Neto,
|
||||
Mariana Picolo, Daniel van Vugt, fludixx, yun341, Jonas Ådahl
|
||||
|
||||
Translators:
|
||||
Daniel Mustieles [es], Boyuan Yang [zh_CN], Yuri Chornoivan [uk],
|
||||
Jordi Mas [ca], sicklylife [ja], Emin Tufan Çetin [tr],
|
||||
Baurzhan Muftakhidinov [kk], Florentina Mușat [ro], Aurimas Černius [lt],
|
||||
Rūdolfs Mazurs [lv]
|
||||
|
||||
3.37.2
|
||||
======
|
||||
* Add support for "PrefersNonDefaultGPU" desktop key [Bastien; !1226]
|
||||
|
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>
|
||||
|
@ -6,25 +6,25 @@
|
||||
<file>checkbox-off-focused.svg</file>
|
||||
<file>checkbox-off.svg</file>
|
||||
<file>checkbox.svg</file>
|
||||
<file alias="icons/color-pick.svg">color-pick.svg</file>
|
||||
<file alias="icons/scalable/actions/color-pick.svg">color-pick.svg</file>
|
||||
<file>dash-placeholder.svg</file>
|
||||
<file>gnome-shell.css</file>
|
||||
<file>gnome-shell-high-contrast.css</file>
|
||||
<file alias="icons/message-indicator-symbolic.svg">message-indicator-symbolic.svg</file>
|
||||
<file alias="icons/scalable/status/message-indicator-symbolic.svg">message-indicator-symbolic.svg</file>
|
||||
<file>no-events.svg</file>
|
||||
<file>no-notifications.svg</file>
|
||||
<file>pad-osd.css</file>
|
||||
<file alias="icons/eye-open-negative-filled-symbolic.svg">eye-open-negative-filled-symbolic.svg</file>
|
||||
<file alias="icons/eye-not-looking-symbolic.svg">eye-not-looking-symbolic.svg</file>
|
||||
<file alias="icons/pointer-double-click-symbolic.svg">pointer-double-click-symbolic.svg</file>
|
||||
<file alias="icons/pointer-drag-symbolic.svg">pointer-drag-symbolic.svg</file>
|
||||
<file alias="icons/pointer-primary-click-symbolic.svg">pointer-primary-click-symbolic.svg</file>
|
||||
<file alias="icons/pointer-secondary-click-symbolic.svg">pointer-secondary-click-symbolic.svg</file>
|
||||
<file alias="icons/keyboard-caps-lock-filled-symbolic.svg">keyboard-caps-lock-filled-symbolic.svg</file>
|
||||
<file alias="icons/keyboard-enter-symbolic.svg">keyboard-enter-symbolic.svg</file>
|
||||
<file alias="icons/keyboard-hide-symbolic.svg">keyboard-hide-symbolic.svg</file>
|
||||
<file alias="icons/keyboard-layout-filled-symbolic.svg">keyboard-layout-filled-symbolic.svg</file>
|
||||
<file alias="icons/keyboard-shift-filled-symbolic.svg">keyboard-shift-filled-symbolic.svg</file>
|
||||
<file alias="icons/scalable/status/eye-open-negative-filled-symbolic.svg">eye-open-negative-filled-symbolic.svg</file>
|
||||
<file alias="icons/scalable/status/eye-not-looking-symbolic.svg">eye-not-looking-symbolic.svg</file>
|
||||
<file alias="icons/scalable/actions/pointer-double-click-symbolic.svg">pointer-double-click-symbolic.svg</file>
|
||||
<file alias="icons/scalable/actions/pointer-drag-symbolic.svg">pointer-drag-symbolic.svg</file>
|
||||
<file alias="icons/scalable/actions/pointer-primary-click-symbolic.svg">pointer-primary-click-symbolic.svg</file>
|
||||
<file alias="icons/scalable/actions/pointer-secondary-click-symbolic.svg">pointer-secondary-click-symbolic.svg</file>
|
||||
<file alias="icons/scalable/status/keyboard-caps-lock-filled-symbolic.svg">keyboard-caps-lock-filled-symbolic.svg</file>
|
||||
<file alias="icons/scalable/status/keyboard-enter-symbolic.svg">keyboard-enter-symbolic.svg</file>
|
||||
<file alias="icons/scalable/status/keyboard-hide-symbolic.svg">keyboard-hide-symbolic.svg</file>
|
||||
<file alias="icons/scalable/status/keyboard-layout-filled-symbolic.svg">keyboard-layout-filled-symbolic.svg</file>
|
||||
<file alias="icons/scalable/status/keyboard-shift-filled-symbolic.svg">keyboard-shift-filled-symbolic.svg</file>
|
||||
<file>process-working.svg</file>
|
||||
<file>toggle-off.svg</file>
|
||||
<file>toggle-off-dark.svg</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
|
@ -109,6 +109,17 @@
|
||||
the shell.
|
||||
</description>
|
||||
</key>
|
||||
<key name="app-picker-layout" type="aa{sv}">
|
||||
<default>[]</default>
|
||||
<summary>Layout of the app picker</summary>
|
||||
<description>
|
||||
Layout of the app picker. Each entry in the array is a page. Pages are
|
||||
stored in the order they appear in GNOME Shell. Each page contains an
|
||||
“application id” → 'data' pair. Currently, the following values are
|
||||
stored as 'data':
|
||||
• “position”: the position of the application icon in the page
|
||||
</description>
|
||||
</key>
|
||||
<child name="keybindings" schema="org.gnome.shell.keybindings"/>
|
||||
</schema>
|
||||
|
||||
|
@ -1,17 +1,13 @@
|
||||
/* App Grid */
|
||||
|
||||
$app_icon_size: 96px;
|
||||
$app_icon_padding: 24px;
|
||||
|
||||
// app icons
|
||||
.icon-grid {
|
||||
-shell-grid-horizontal-item-size: $app_icon_size + $app_icon_padding * 2;
|
||||
-shell-grid-vertical-item-size: $app_icon_size + $app_icon_padding * 2;
|
||||
spacing: $base_spacing * 6;
|
||||
|
||||
.overview-icon {
|
||||
icon-size: $app_icon_size;
|
||||
}
|
||||
row-spacing: $base_spacing * 6;
|
||||
column-spacing: $base_spacing * 6;
|
||||
max-row-spacing: $base_spacing * 12;
|
||||
max-column-spacing: $base_spacing * 12;
|
||||
}
|
||||
|
||||
/* App Icons */
|
||||
@ -42,8 +38,8 @@ $app_grid_fg_color: #fff;
|
||||
.app-folder-dialog {
|
||||
border-radius: $modal_radius * 1.5;
|
||||
border: 1px solid $osd_outer_borders_color;
|
||||
spacing: 12px;
|
||||
background-color: transparentize(darken($osd_bg_color,10%), 0.05);
|
||||
padding: 12px;
|
||||
|
||||
& .folder-name-container {
|
||||
padding: 24px 36px 0;
|
||||
@ -52,7 +48,7 @@ $app_grid_fg_color: #fff;
|
||||
& .folder-name-label,
|
||||
& .folder-name-entry {
|
||||
font-size: 18pt;
|
||||
font-weight: bold;
|
||||
font-weight: 800;
|
||||
}
|
||||
|
||||
& .folder-name-entry { width: 300px }
|
||||
@ -71,11 +67,24 @@ $app_grid_fg_color: #fff;
|
||||
& > StIcon { icon-size: 16px }
|
||||
}
|
||||
}
|
||||
|
||||
& .icon-grid {
|
||||
row-spacing: $base_spacing * 2;
|
||||
column-spacing: $base_spacing * 5;
|
||||
}
|
||||
|
||||
& .page-indicators {
|
||||
margin-bottom: 18px;
|
||||
|
||||
.page-indicator {
|
||||
padding: 15px 12px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.app-folder-dialog-container {
|
||||
padding: 12px;
|
||||
width: 800px;
|
||||
height: 600px;
|
||||
width: 620px;
|
||||
height: 620px;
|
||||
}
|
||||
|
||||
.app-folder-icon {
|
||||
|
@ -177,6 +177,32 @@
|
||||
}
|
||||
}
|
||||
|
||||
/* Events */
|
||||
.events-button {
|
||||
@include notification_bubble;
|
||||
padding: $base_padding * 2;
|
||||
|
||||
.events-box {
|
||||
spacing: $base_spacing;
|
||||
}
|
||||
|
||||
.events-list {
|
||||
spacing: 2 * $base_spacing;
|
||||
}
|
||||
|
||||
.events-title {
|
||||
color: desaturate(darken($fg_color,40%), 10%);
|
||||
font-weight: bold;
|
||||
margin-bottom: $base_margin;
|
||||
}
|
||||
|
||||
.event-time {
|
||||
color: darken($fg_color,20%);
|
||||
font-feature-settings: "tnum";
|
||||
@include fontsize($base_font_size - 1);
|
||||
}
|
||||
}
|
||||
|
||||
/* World clocks */
|
||||
.world-clocks-button {
|
||||
@include notification_bubble;
|
||||
|
@ -1,19 +1,20 @@
|
||||
/* Window Picker */
|
||||
|
||||
$window_picker_spacing: $base_spacing * 2; // 16px
|
||||
$window_picker_padding: $base_padding * 2; // 16px
|
||||
$window_picker_spacing: $base_spacing; // 6px
|
||||
$window_picker_padding: $base_padding * 2; // 12px
|
||||
|
||||
$window_thumbnail_border_color:transparentize($selected_fg_color, 0.65);
|
||||
|
||||
$window_close_button_size: 24px;
|
||||
$window_close_button_padding: 3px;
|
||||
|
||||
$window_clone_border_size: 6px;
|
||||
|
||||
// Window picker
|
||||
.window-picker {
|
||||
// Space between window thumbnails
|
||||
-horizontal-spacing: $window_picker_spacing;
|
||||
-vertical-spacing: $window_picker_spacing;
|
||||
spacing: $window_picker_spacing;
|
||||
|
||||
// Padding for container around window thumbnails
|
||||
padding: $window_picker_padding;
|
||||
|
||||
@ -22,7 +23,7 @@ $window_close_button_padding: 3px;
|
||||
|
||||
// Borders on window thumbnails
|
||||
.window-clone-border {
|
||||
border-width: 6px;
|
||||
border-width: $window_clone_border_size;
|
||||
border-style: solid;
|
||||
border-color: $window_thumbnail_border_color;
|
||||
border-radius: $base_border_radius + 2;
|
||||
@ -54,8 +55,6 @@ $window_close_button_padding: 3px;
|
||||
width: $window_close_button_size;
|
||||
box-shadow: -1px 1px 5px 0px rgba(0,0,0,0.5);
|
||||
|
||||
-shell-close-overlap: $window_close_button_size * 0.5;
|
||||
|
||||
&:hover {
|
||||
background-color: lighten($selected_bg_color, 5%);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -1,2 +1,6 @@
|
||||
.expander-frame > * { border-top-width: 0; }
|
||||
.expander-toolbar { border: 0 solid @borders; border-top-width: 1px; }
|
||||
.expander-toolbar {
|
||||
border: 0 solid @borders;
|
||||
border-top-width: 1px;
|
||||
padding: 3px;
|
||||
}
|
||||
|
@ -128,7 +128,7 @@ var ExtensionsService = class extends ServiceImplementation {
|
||||
externalWindow = Shew.ExternalWindow.new_from_handle(parentWindow);
|
||||
|
||||
if (externalWindow)
|
||||
externalWindow.set_parent_of(window.window);
|
||||
externalWindow.set_parent_of(window.get_surface());
|
||||
|
||||
if (options.modal)
|
||||
window.modal = options.modal.get_boolean();
|
||||
@ -156,7 +156,6 @@ var ExtensionPrefsDialog = GObject.registerClass({
|
||||
GTypeName: 'ExtensionPrefsDialog',
|
||||
Template: 'resource:///org/gnome/Shell/Extensions/ui/extension-prefs-dialog.ui',
|
||||
InternalChildren: [
|
||||
'headerBar',
|
||||
'stack',
|
||||
'expander',
|
||||
'expanderArrow',
|
||||
@ -165,24 +164,24 @@ var ExtensionPrefsDialog = GObject.registerClass({
|
||||
],
|
||||
}, class ExtensionPrefsDialog extends Gtk.Window {
|
||||
_init(extension) {
|
||||
super._init();
|
||||
super._init({
|
||||
title: extension.metadata.name,
|
||||
});
|
||||
|
||||
this._uuid = extension.uuid;
|
||||
this._url = extension.metadata.url || '';
|
||||
|
||||
this._headerBar.title = extension.metadata.name;
|
||||
|
||||
this._actionGroup = new Gio.SimpleActionGroup();
|
||||
this.insert_action_group('win', this._actionGroup);
|
||||
|
||||
this._initActions();
|
||||
this._addCustomStylesheet();
|
||||
|
||||
this._gesture = new Gtk.GestureMultiPress({
|
||||
widget: this._expander,
|
||||
this._gesture = new Gtk.GestureClick({
|
||||
button: 0,
|
||||
exclusive: true,
|
||||
});
|
||||
this._expander.add_controller(this._gesture);
|
||||
|
||||
this._gesture.connect('released', (gesture, nPress) => {
|
||||
if (nPress === 1)
|
||||
@ -205,7 +204,7 @@ var ExtensionPrefsDialog = GObject.registerClass({
|
||||
prefsModule.init(extension.metadata);
|
||||
|
||||
const widget = prefsModule.buildPrefsWidget();
|
||||
this._stack.add(widget);
|
||||
this._stack.add_named(widget, 'prefs');
|
||||
this._stack.visible_child = widget;
|
||||
} catch (e) {
|
||||
this._setError(e);
|
||||
@ -267,7 +266,7 @@ var ExtensionPrefsDialog = GObject.registerClass({
|
||||
} catch (e) {
|
||||
logError(e, 'Failed to add application style');
|
||||
}
|
||||
Gtk.StyleContext.add_provider_for_screen(Gdk.Screen.get_default(),
|
||||
Gtk.StyleContext.add_provider_for_display(Gdk.Display.get_default(),
|
||||
provider,
|
||||
Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION);
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* exported main */
|
||||
|
||||
imports.gi.versions.Gdk = '3.0';
|
||||
imports.gi.versions.Gtk = '3.0';
|
||||
imports.gi.versions.Gdk = '4.0';
|
||||
imports.gi.versions.Gtk = '4.0';
|
||||
|
||||
const { Gtk } = imports.gi;
|
||||
const pkg = imports.package;
|
||||
@ -10,7 +10,7 @@ const { DBusService } = imports.dbusService;
|
||||
const { ExtensionsService } = imports.extensionsService;
|
||||
|
||||
function main() {
|
||||
Gtk.init(null);
|
||||
Gtk.init();
|
||||
pkg.initFormat();
|
||||
|
||||
const service = new DBusService(
|
||||
|
@ -1,38 +1,32 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Generated with glade 3.22.1 -->
|
||||
<interface>
|
||||
<requires lib="gtk+" version="3.20"/>
|
||||
<template class="ExtensionPrefsDialog" parent="GtkWindow">
|
||||
<property name="default_width">600</property>
|
||||
<property name="default_height">400</property>
|
||||
<child type="titlebar">
|
||||
<object class="GtkHeaderBar" id="headerBar">
|
||||
<property name="visible">True</property>
|
||||
<property name="show_close_button">True</property>
|
||||
<object class="GtkHeaderBar">
|
||||
<property name="show-title-buttons">True</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkStack" id="stack">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow">
|
||||
<property name="visible">True</property>
|
||||
<property name="hscrollbar_policy">never</property>
|
||||
<property name="propagate_natural_height">True</property>
|
||||
<child>
|
||||
<object class="GtkViewport">
|
||||
<property name="visible">True</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="margin">100</property>
|
||||
<property name="margin_bottom">60</property>
|
||||
<property name="margin-start">100</property>
|
||||
<property name="margin-end">100</property>
|
||||
<property name="margin-top">100</property>
|
||||
<property name="margin-bottom">60</property>
|
||||
<property name="spacing">12</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Something’s gone wrong</property>
|
||||
<attributes>
|
||||
<attribute name="scale" value="1.44"/> <!-- x-large -->
|
||||
@ -44,44 +38,33 @@
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">We’re very sorry, but there’s been a problem: the settings for this extension can’t be displayed. We recommend that you report the issue to the extension authors.</property>
|
||||
<property name="justify">center</property>
|
||||
<property name="wrap">True</property>
|
||||
<property name="xalign">0.5</property>
|
||||
<property name="yalign">0.5</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="margin_top">12</property>
|
||||
<property name="margin-top">12</property>
|
||||
<child>
|
||||
<object class="GtkFrame" id="expander">
|
||||
<property name="visible">True</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="shadow_type">in</property>
|
||||
<child>
|
||||
<object class="GtkEventBox">
|
||||
<property name="visible">True</property>
|
||||
<object class="GtkBox">
|
||||
<property name="margin-start">12</property>
|
||||
<property name="margin-end">12</property>
|
||||
<property name="margin-top">12</property>
|
||||
<property name="margin-bottom">12</property>
|
||||
<property name="spacing">6</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="margin">12</property>
|
||||
<property name="spacing">6</property>
|
||||
<child>
|
||||
<object class="GtkImage" id="expanderArrow">
|
||||
<property name="visible">True</property>
|
||||
<property name="icon_name">pan-end-symbolic</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Technical Details</property>
|
||||
</object>
|
||||
</child>
|
||||
<object class="GtkImage" id="expanderArrow">
|
||||
<property name="icon_name">pan-end-symbolic</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label" translatable="yes">Technical Details</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
@ -90,22 +73,16 @@
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkRevealer" id="revealer">
|
||||
<property name="visible">True</property>
|
||||
<child>
|
||||
<object class="GtkFrame">
|
||||
<property name="visible">True</property>
|
||||
<property name="shadow_type">in</property>
|
||||
<style>
|
||||
<class name="expander-frame"/>
|
||||
</style>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkTextView" id="errorView">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="monospace">True</property>
|
||||
<property name="editable">False</property>
|
||||
<property name="wrap_mode">word</property>
|
||||
@ -116,63 +93,34 @@
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkToolbar">
|
||||
<property name="visible">True</property>
|
||||
<object class="GtkBox">
|
||||
<style>
|
||||
<class name="expander-toolbar"/>
|
||||
</style>
|
||||
<child>
|
||||
<object class="GtkToolItem">
|
||||
<property name="visible">True</property>
|
||||
<child>
|
||||
<object class="GtkButton">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="action_name">win.copy-error</property>
|
||||
<style>
|
||||
<class name="flat"/>
|
||||
<class name="image-button"/>
|
||||
</style>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<property name="visible">True</property>
|
||||
<property name="icon_name">edit-copy-symbolic</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<object class="GtkButton">
|
||||
<property name="receives_default">True</property>
|
||||
<property name="action_name">win.copy-error</property>
|
||||
<property name="has-frame">False</property>
|
||||
<property name="icon-name">edit-copy-symbolic</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparatorToolItem">
|
||||
<property name="visible">True</property>
|
||||
<property name="draw">False</property>
|
||||
<object class="GtkLabel">
|
||||
<property name="hexpand">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkToolItem">
|
||||
<property name="visible">True</property>
|
||||
<child>
|
||||
<object class="GtkButton" id="homeButton">
|
||||
<property name="visible"
|
||||
bind-source="homeButton"
|
||||
bind-property="sensitive"
|
||||
bind-flags="sync-create"/>
|
||||
<property name="label" translatable="yes">Homepage</property>
|
||||
<property name="tooltip_text" translatable="yes">Visit extension homepage</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="no_show_all">True</property>
|
||||
<property name="action_name">win.show-url</property>
|
||||
<style>
|
||||
<class name="flat"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
<object class="GtkButton" id="homeButton">
|
||||
<property name="visible"
|
||||
bind-source="homeButton"
|
||||
bind-property="sensitive"
|
||||
bind-flags="sync-create"/>
|
||||
<property name="label" translatable="yes">Homepage</property>
|
||||
<property name="tooltip_text" translatable="yes">Visit extension homepage</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="has-frame">False</property>
|
||||
<property name="action_name">win.show-url</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
|
@ -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]));
|
||||
});
|
||||
}
|
||||
};
|
@ -71,7 +71,7 @@ var AuthPrompt = GObject.registerClass({
|
||||
this._userVerifier.connect('verification-complete', this._onVerificationComplete.bind(this));
|
||||
this._userVerifier.connect('reset', this._onReset.bind(this));
|
||||
this._userVerifier.connect('smartcard-status-changed', this._onSmartcardStatusChanged.bind(this));
|
||||
this._userVerifier.connect('ovirt-user-authenticated', this._onOVirtUserAuthenticated.bind(this));
|
||||
this._userVerifier.connect('credential-manager-authenticated', this._onCredentialManagerAuthenticated.bind(this));
|
||||
this.smartcardDetected = this._userVerifier.smartcardDetected;
|
||||
|
||||
this.connect('destroy', this._onDestroy.bind(this));
|
||||
@ -242,7 +242,7 @@ var AuthPrompt = GObject.registerClass({
|
||||
this.emit('prompted');
|
||||
}
|
||||
|
||||
_onOVirtUserAuthenticated() {
|
||||
_onCredentialManagerAuthenticated() {
|
||||
if (this.verificationStatus != AuthPromptStatus.VERIFICATION_SUCCEEDED)
|
||||
this.reset();
|
||||
}
|
||||
|
24
js/gdm/credentialManager.js
Normal file
24
js/gdm/credentialManager.js
Normal file
@ -0,0 +1,24 @@
|
||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported CredentialManager */
|
||||
|
||||
class CredentialManager {
|
||||
constructor(service) {
|
||||
this._token = null;
|
||||
this._service = service;
|
||||
this._authenticatedSignalId = null;
|
||||
}
|
||||
|
||||
get token() {
|
||||
return this._token;
|
||||
}
|
||||
|
||||
set token(t) {
|
||||
this._token = t;
|
||||
if (this._token)
|
||||
this.emit('user-authenticated', this._token);
|
||||
}
|
||||
|
||||
get service() {
|
||||
return this._service;
|
||||
}
|
||||
}
|
@ -810,8 +810,8 @@ var LoginDialog = GObject.registerClass({
|
||||
return;
|
||||
|
||||
this._logoBin.destroy_all_children();
|
||||
const [valid, resourceScale] = this._logoBin.get_resource_scale();
|
||||
if (this._logoFile && valid) {
|
||||
const resourceScale = this._logoBin.get_resource_scale();
|
||||
if (this._logoFile) {
|
||||
let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor;
|
||||
this._logoBin.add_child(this._textureCache.load_file_async(this._logoFile,
|
||||
-1, -1,
|
||||
@ -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(),
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -3,6 +3,9 @@
|
||||
|
||||
const Gio = imports.gi.Gio;
|
||||
const Signals = imports.signals;
|
||||
const Credential = imports.gdm.credentialManager;
|
||||
|
||||
var SERVICE_NAME = 'gdm-ovirtcred';
|
||||
|
||||
const OVirtCredentialsIface = `
|
||||
<node>
|
||||
@ -28,30 +31,14 @@ function OVirtCredentials() {
|
||||
return self;
|
||||
}
|
||||
|
||||
var OVirtCredentialsManager = class {
|
||||
var OVirtCredentialsManager = class OVirtCredentialsManager extends Credential.CredentialManager {
|
||||
constructor() {
|
||||
this._token = null;
|
||||
|
||||
super(SERVICE_NAME);
|
||||
this._credentials = new OVirtCredentials();
|
||||
this._credentials.connectSignal('UserAuthenticated',
|
||||
this._onUserAuthenticated.bind(this));
|
||||
}
|
||||
|
||||
_onUserAuthenticated(proxy, sender, [token]) {
|
||||
this._token = token;
|
||||
this.emit('user-authenticated', token);
|
||||
}
|
||||
|
||||
hasToken() {
|
||||
return this._token != null;
|
||||
}
|
||||
|
||||
getToken() {
|
||||
return this._token;
|
||||
}
|
||||
|
||||
resetToken() {
|
||||
this._token = null;
|
||||
(proxy, sender, [token]) => {
|
||||
this.token = token;
|
||||
});
|
||||
}
|
||||
};
|
||||
Signals.addSignalMethods(OVirtCredentialsManager.prototype);
|
||||
|
@ -8,6 +8,7 @@ const Signals = imports.signals;
|
||||
const Batch = imports.gdm.batch;
|
||||
const Fprint = imports.gdm.fingerprint;
|
||||
const OVirt = imports.gdm.oVirt;
|
||||
const Vmware = imports.gdm.vmware;
|
||||
const Main = imports.ui.main;
|
||||
const Params = imports.misc.params;
|
||||
const SmartcardManager = imports.misc.smartcardManager;
|
||||
@ -24,7 +25,6 @@ Gio._promisify(Gdm.UserVerifierProxy.prototype,
|
||||
var PASSWORD_SERVICE_NAME = 'gdm-password';
|
||||
var FINGERPRINT_SERVICE_NAME = 'gdm-fingerprint';
|
||||
var SMARTCARD_SERVICE_NAME = 'gdm-smartcard';
|
||||
var OVIRT_SERVICE_NAME = 'gdm-ovirtcred';
|
||||
var FADE_ANIMATION_TIME = 160;
|
||||
var CLONE_FADE_ANIMATION_TIME = 250;
|
||||
|
||||
@ -160,13 +160,20 @@ var ShellUserVerifier = class {
|
||||
|
||||
this._failCounter = 0;
|
||||
|
||||
this._oVirtCredentialsManager = OVirt.getOVirtCredentialsManager();
|
||||
this._credentialManagers = {};
|
||||
this._credentialManagers[OVirt.SERVICE_NAME] = OVirt.getOVirtCredentialsManager();
|
||||
this._credentialManagers[Vmware.SERVICE_NAME] = Vmware.getVmwareCredentialsManager();
|
||||
|
||||
if (this._oVirtCredentialsManager.hasToken())
|
||||
this._oVirtUserAuthenticated(this._oVirtCredentialsManager.getToken());
|
||||
for (let service in this._credentialManagers) {
|
||||
if (this._credentialManagers[service].token) {
|
||||
this._onCredentialManagerAuthenticated(this._credentialManagers[service],
|
||||
this._credentialManagers[service].token);
|
||||
}
|
||||
|
||||
this._oVirtUserAuthenticatedId = this._oVirtCredentialsManager.connect('user-authenticated',
|
||||
this._oVirtUserAuthenticated.bind(this));
|
||||
this._credentialManagers[service]._authenticatedSignalId =
|
||||
this._credentialManagers[service].connect('user-authenticated',
|
||||
this._onCredentialManagerAuthenticated.bind(this));
|
||||
}
|
||||
}
|
||||
|
||||
begin(userName, hold) {
|
||||
@ -222,8 +229,11 @@ var ShellUserVerifier = class {
|
||||
this._smartcardManager.disconnect(this._smartcardRemovedId);
|
||||
this._smartcardManager = null;
|
||||
|
||||
this._oVirtCredentialsManager.disconnect(this._oVirtUserAuthenticatedId);
|
||||
this._oVirtCredentialsManager = null;
|
||||
for (let service in this._credentialManagers) {
|
||||
let credentialManager = this._credentialManagers[service];
|
||||
credentialManager.disconnect(credentialManager._authenticatedSignalId);
|
||||
credentialManager = null;
|
||||
}
|
||||
}
|
||||
|
||||
answerQuery(serviceName, answer) {
|
||||
@ -311,9 +321,9 @@ var ShellUserVerifier = class {
|
||||
});
|
||||
}
|
||||
|
||||
_oVirtUserAuthenticated(_token) {
|
||||
this._preemptingService = OVIRT_SERVICE_NAME;
|
||||
this.emit('ovirt-user-authenticated');
|
||||
_onCredentialManagerAuthenticated(credentialManager, _token) {
|
||||
this._preemptingService = credentialManager.service;
|
||||
this.emit('credential-manager-authenticated');
|
||||
}
|
||||
|
||||
_checkForSmartcard() {
|
||||
@ -490,9 +500,12 @@ var ShellUserVerifier = class {
|
||||
if (!this.serviceIsForeground(serviceName))
|
||||
return;
|
||||
|
||||
if (serviceName == OVIRT_SERVICE_NAME) {
|
||||
// The only question asked by this service is "Token?"
|
||||
this.answerQuery(serviceName, this._oVirtCredentialsManager.getToken());
|
||||
let token = null;
|
||||
if (this._credentialManagers[serviceName])
|
||||
token = this._credentialManagers[serviceName].token;
|
||||
|
||||
if (token) {
|
||||
this.answerQuery(serviceName, token);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -560,8 +573,10 @@ var ShellUserVerifier = class {
|
||||
// If the login failed with the preauthenticated oVirt credentials
|
||||
// then discard the credentials and revert to default authentication
|
||||
// mechanism.
|
||||
if (this.serviceIsForeground(OVIRT_SERVICE_NAME)) {
|
||||
this._oVirtCredentialsManager.resetToken();
|
||||
let foregroundService = Object.keys(this._credentialManagers).find(service =>
|
||||
this.serviceIsForeground(service));
|
||||
if (foregroundService) {
|
||||
this._credentialManagers[foregroundService].token = null;
|
||||
this._preemptingService = null;
|
||||
this._verificationFailed(false);
|
||||
return;
|
||||
|
54
js/gdm/vmware.js
Normal file
54
js/gdm/vmware.js
Normal file
@ -0,0 +1,54 @@
|
||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported getVmwareCredentialsManager */
|
||||
|
||||
const Gio = imports.gi.Gio;
|
||||
const Signals = imports.signals;
|
||||
const Credential = imports.gdm.credentialManager;
|
||||
|
||||
const dbusPath = '/org/vmware/viewagent/Credentials';
|
||||
const dbusInterface = 'org.vmware.viewagent.Credentials';
|
||||
|
||||
var SERVICE_NAME = 'gdm-vmwcred';
|
||||
|
||||
const VmwareCredentialsIface = '<node> \
|
||||
<interface name="' + dbusInterface + '"> \
|
||||
<signal name="UserAuthenticated"> \
|
||||
<arg type="s" name="token"/> \
|
||||
</signal> \
|
||||
</interface> \
|
||||
</node>';
|
||||
|
||||
|
||||
const VmwareCredentialsInfo = Gio.DBusInterfaceInfo.new_for_xml(VmwareCredentialsIface);
|
||||
|
||||
let _vmwareCredentialsManager = null;
|
||||
|
||||
function VmwareCredentials() {
|
||||
var self = new Gio.DBusProxy({ g_connection: Gio.DBus.session,
|
||||
g_interface_name: VmwareCredentialsInfo.name,
|
||||
g_interface_info: VmwareCredentialsInfo,
|
||||
g_name: dbusInterface,
|
||||
g_object_path: dbusPath,
|
||||
g_flags: Gio.DBusProxyFlags.DO_NOT_LOAD_PROPERTIES });
|
||||
self.init(null);
|
||||
return self;
|
||||
}
|
||||
|
||||
var VmwareCredentialsManager = class VmwareCredentialsManager extends Credential.CredentialManager {
|
||||
constructor() {
|
||||
super(SERVICE_NAME);
|
||||
this._credentials = new VmwareCredentials();
|
||||
this._credentials.connectSignal('UserAuthenticated',
|
||||
(proxy, sender, [token]) => {
|
||||
this.token = token;
|
||||
});
|
||||
}
|
||||
};
|
||||
Signals.addSignalMethods(VmwareCredentialsManager.prototype);
|
||||
|
||||
function getVmwareCredentialsManager() {
|
||||
if (!_vmwareCredentialsManager)
|
||||
_vmwareCredentialsManager = new VmwareCredentialsManager();
|
||||
|
||||
return _vmwareCredentialsManager;
|
||||
}
|
@ -6,6 +6,8 @@
|
||||
<file>gdm/fingerprint.js</file>
|
||||
<file>gdm/loginDialog.js</file>
|
||||
<file>gdm/oVirt.js</file>
|
||||
<file>gdm/credentialManager.js</file>
|
||||
<file>gdm/vmware.js</file>
|
||||
<file>gdm/realmd.js</file>
|
||||
<file>gdm/util.js</file>
|
||||
|
||||
@ -90,7 +92,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>
|
||||
@ -108,6 +109,7 @@
|
||||
<file>ui/windowAttentionHandler.js</file>
|
||||
<file>ui/windowMenu.js</file>
|
||||
<file>ui/windowManager.js</file>
|
||||
<file>ui/windowPreview.js</file>
|
||||
<file>ui/workspace.js</file>
|
||||
<file>ui/workspaceSwitcherPopup.js</file>
|
||||
<file>ui/workspaceThumbnail.js</file>
|
||||
@ -134,7 +136,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);
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ const INTROSPECT_SCHEMA = 'org.gnome.shell';
|
||||
const INTROSPECT_KEY = 'introspect';
|
||||
const APP_WHITELIST = ['org.freedesktop.impl.portal.desktop.gtk'];
|
||||
|
||||
const INTROSPECT_DBUS_API_VERSION = 2;
|
||||
const INTROSPECT_DBUS_API_VERSION = 3;
|
||||
|
||||
const { loadInterfaceXML } = imports.misc.fileUtils;
|
||||
|
||||
@ -59,6 +59,11 @@ var IntrospectService = class {
|
||||
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) {
|
||||
@ -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;
|
||||
}
|
||||
|
@ -1,9 +1,9 @@
|
||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported findUrls, spawn, spawnCommandLine, spawnApp, trySpawnCommandLine,
|
||||
formatTime, formatTimeSpan, createTimeLabel, insertSorted,
|
||||
makeCloseButton, ensureActorVisibleInScrollView, wiggle */
|
||||
ensureActorVisibleInScrollView, wiggle */
|
||||
|
||||
const { Clutter, Gio, GLib, GObject, Shell, St, GnomeDesktop } = imports.gi;
|
||||
const { Clutter, Gio, GLib, Shell, St, GnomeDesktop } = imports.gi;
|
||||
const Gettext = imports.gettext;
|
||||
|
||||
const Main = imports.ui.main;
|
||||
@ -363,51 +363,6 @@ function insertSorted(array, val, cmp) {
|
||||
return pos;
|
||||
}
|
||||
|
||||
var CloseButton = GObject.registerClass(
|
||||
class CloseButton extends St.Button {
|
||||
_init(boxpointer) {
|
||||
super._init({
|
||||
style_class: 'notification-close',
|
||||
x_expand: true,
|
||||
y_expand: true,
|
||||
x_align: Clutter.ActorAlign.END,
|
||||
y_align: Clutter.ActorAlign.START,
|
||||
});
|
||||
|
||||
this._boxPointer = boxpointer;
|
||||
if (boxpointer)
|
||||
this._boxPointer.connect('arrow-side-changed', this._sync.bind(this));
|
||||
}
|
||||
|
||||
_computeBoxPointerOffset() {
|
||||
if (!this._boxPointer || !this._boxPointer.get_stage())
|
||||
return 0;
|
||||
|
||||
let side = this._boxPointer.arrowSide;
|
||||
if (side == St.Side.TOP)
|
||||
return this._boxPointer.getArrowHeight();
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
_sync() {
|
||||
let themeNode = this.get_theme_node();
|
||||
|
||||
let offY = this._computeBoxPointerOffset();
|
||||
this.translation_x = themeNode.get_length('-shell-close-overlap-x');
|
||||
this.translation_y = themeNode.get_length('-shell-close-overlap-y') + offY;
|
||||
}
|
||||
|
||||
vfunc_style_changed() {
|
||||
this._sync();
|
||||
super.vfunc_style_changed();
|
||||
}
|
||||
});
|
||||
|
||||
function makeCloseButton(boxpointer) {
|
||||
return new CloseButton(boxpointer);
|
||||
}
|
||||
|
||||
function ensureActorVisibleInScrollView(scrollView, actor) {
|
||||
let adjustment = scrollView.vscroll.adjustment;
|
||||
let [value, lower_, upper, stepIncrement_, pageIncrement_, pageSize] = adjustment.get_values();
|
||||
|
@ -852,6 +852,9 @@ class AppSwitcher extends SwitcherPopup.SwitcherList {
|
||||
if (index === -1)
|
||||
return;
|
||||
|
||||
this._arrows[index].destroy();
|
||||
this._arrows.splice(index, 1);
|
||||
|
||||
this.icons.splice(index, 1);
|
||||
this.removeItem(index);
|
||||
}
|
||||
|
@ -60,7 +60,7 @@ class Animation extends St.Bin {
|
||||
}
|
||||
|
||||
_loadFile(file, width, height) {
|
||||
let [validResourceScale, resourceScale] = this.get_resource_scale();
|
||||
const resourceScale = this.get_resource_scale();
|
||||
let wasPlaying = this._isPlaying;
|
||||
|
||||
if (this._isPlaying)
|
||||
@ -69,12 +69,6 @@ class Animation extends St.Bin {
|
||||
this._isLoaded = false;
|
||||
this.destroy_all_children();
|
||||
|
||||
if (!validResourceScale) {
|
||||
if (wasPlaying)
|
||||
this.play();
|
||||
return;
|
||||
}
|
||||
|
||||
let textureCache = St.TextureCache.get_default();
|
||||
let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor;
|
||||
this._animations = textureCache.load_sliced_image(file, width, height,
|
||||
|
1833
js/ui/appDisplay.js
1833
js/ui/appDisplay.js
File diff suppressed because it is too large
Load Diff
@ -347,6 +347,8 @@ var Background = GObject.registerClass({
|
||||
this.set_color(color);
|
||||
else
|
||||
this.set_gradient(shadingType, color, secondColor);
|
||||
|
||||
this._setLoaded();
|
||||
}
|
||||
|
||||
_watchFile(file) {
|
||||
@ -512,8 +514,8 @@ var SystemBackground = GObject.registerClass({
|
||||
super._init({
|
||||
meta_display: global.display,
|
||||
monitor: 0,
|
||||
background: _systemBackground,
|
||||
});
|
||||
this.content.background = _systemBackground;
|
||||
|
||||
let id = GLib.idle_add(GLib.PRIORITY_DEFAULT, () => {
|
||||
this.emit('loaded');
|
||||
@ -712,13 +714,18 @@ var BackgroundManager = class BackgroundManager {
|
||||
}
|
||||
|
||||
let newBackgroundActor = this._createBackgroundActor();
|
||||
newBackgroundActor.vignette_sharpness = this.backgroundActor.vignette_sharpness;
|
||||
newBackgroundActor.brightness = this.backgroundActor.brightness;
|
||||
|
||||
const oldContent = this.backgroundActor.content;
|
||||
const newContent = newBackgroundActor.content;
|
||||
|
||||
newContent.vignette_sharpness = oldContent.vignette_sharpness;
|
||||
newContent.brightness = oldContent.brightness;
|
||||
|
||||
newBackgroundActor.visible = this.backgroundActor.visible;
|
||||
|
||||
this._newBackgroundActor = newBackgroundActor;
|
||||
|
||||
let background = newBackgroundActor.background;
|
||||
const { background } = newBackgroundActor.content;
|
||||
|
||||
if (background.isLoaded) {
|
||||
this._swapBackgroundActor();
|
||||
@ -738,6 +745,8 @@ var BackgroundManager = class BackgroundManager {
|
||||
let backgroundActor = new Meta.BackgroundActor({
|
||||
meta_display: global.display,
|
||||
monitor: this._monitorIndex,
|
||||
});
|
||||
backgroundActor.content.set({
|
||||
background,
|
||||
vignette: this._vignette,
|
||||
vignette_sharpness: 0.5,
|
||||
@ -758,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;
|
||||
}
|
||||
|
@ -14,7 +14,6 @@ const { loadInterfaceXML } = imports.misc.fileUtils;
|
||||
|
||||
var MSECS_IN_DAY = 24 * 60 * 60 * 1000;
|
||||
var SHOW_WEEKDATE_KEY = 'show-weekdate';
|
||||
var ELLIPSIS_CHAR = '\u2026';
|
||||
|
||||
var MESSAGE_ICON_SIZE = -1; // pick up from CSS
|
||||
|
||||
@ -32,10 +31,6 @@ function sameDay(dateA, dateB) {
|
||||
return sameMonth(dateA, dateB) && (dateA.getDate() == dateB.getDate());
|
||||
}
|
||||
|
||||
function isToday(date) {
|
||||
return sameDay(new Date(), date);
|
||||
}
|
||||
|
||||
function _isWorkDay(date) {
|
||||
/* Translators: Enter 0-6 (Sunday-Saturday) for non-work days. Examples: "0" (Sunday) "6" (Saturday) "06" (Sunday and Saturday). */
|
||||
let days = C_('calendar-no-work', "06");
|
||||
@ -723,67 +718,6 @@ var Calendar = GObject.registerClass({
|
||||
}
|
||||
});
|
||||
|
||||
var EventMessage = GObject.registerClass(
|
||||
class EventMessage extends MessageList.Message {
|
||||
_init(event, date) {
|
||||
super._init('', '');
|
||||
|
||||
this._date = date;
|
||||
|
||||
this.update(event);
|
||||
|
||||
this._icon = new St.Icon({ icon_name: 'x-office-calendar-symbolic' });
|
||||
this.setIcon(this._icon);
|
||||
}
|
||||
|
||||
vfunc_style_changed() {
|
||||
let iconVisible = this.get_parent().has_style_pseudo_class('first-child');
|
||||
this._icon.opacity = iconVisible ? 255 : 0;
|
||||
super.vfunc_style_changed();
|
||||
}
|
||||
|
||||
update(event) {
|
||||
this._event = event;
|
||||
|
||||
this.setTitle(this._formatEventTime());
|
||||
this.setBody(event.summary);
|
||||
}
|
||||
|
||||
_formatEventTime() {
|
||||
let periodBegin = _getBeginningOfDay(this._date);
|
||||
let periodEnd = _getEndOfDay(this._date);
|
||||
let allDay = this._event.allDay || (this._event.date <= periodBegin &&
|
||||
this._event.end >= periodEnd);
|
||||
let title;
|
||||
if (allDay) {
|
||||
/* Translators: Shown in calendar event list for all day events
|
||||
* Keep it short, best if you can use less then 10 characters
|
||||
*/
|
||||
title = C_("event list time", "All Day");
|
||||
} else {
|
||||
let date = this._event.date >= periodBegin
|
||||
? this._event.date
|
||||
: this._event.end;
|
||||
title = Util.formatTime(date, { timeOnly: true });
|
||||
}
|
||||
|
||||
let rtl = Clutter.get_default_text_direction() == Clutter.TextDirection.RTL;
|
||||
if (this._event.date < periodBegin && !this._event.allDay) {
|
||||
if (rtl)
|
||||
title = '%s%s'.format(title, ELLIPSIS_CHAR);
|
||||
else
|
||||
title = '%s%s'.format(ELLIPSIS_CHAR, title);
|
||||
}
|
||||
if (this._event.end > periodEnd && !this._event.allDay) {
|
||||
if (rtl)
|
||||
title = '%s%s'.format(ELLIPSIS_CHAR, title);
|
||||
else
|
||||
title = '%s%s'.format(title, ELLIPSIS_CHAR);
|
||||
}
|
||||
return title;
|
||||
}
|
||||
});
|
||||
|
||||
var NotificationMessage = GObject.registerClass(
|
||||
class NotificationMessage extends MessageList.Message {
|
||||
_init(notification) {
|
||||
@ -849,149 +783,6 @@ class NotificationMessage extends MessageList.Message {
|
||||
}
|
||||
});
|
||||
|
||||
var EventsSection = GObject.registerClass(
|
||||
class EventsSection extends MessageList.MessageListSection {
|
||||
_init() {
|
||||
super._init();
|
||||
|
||||
this._desktopSettings = new Gio.Settings({ schema_id: 'org.gnome.desktop.interface' });
|
||||
this._desktopSettings.connect('changed', this._reloadEvents.bind(this));
|
||||
this._eventSource = new EmptyEventSource();
|
||||
|
||||
this._messageById = new Map();
|
||||
|
||||
this._title = new St.Button({ style_class: 'events-section-title',
|
||||
label: '',
|
||||
can_focus: true });
|
||||
this._title.child.x_align = Clutter.ActorAlign.START;
|
||||
this.insert_child_below(this._title, null);
|
||||
|
||||
this._title.connect('clicked', this._onTitleClicked.bind(this));
|
||||
this._title.connect('key-focus-in', this._onKeyFocusIn.bind(this));
|
||||
|
||||
this._appSys = Shell.AppSystem.get_default();
|
||||
this._appSys.connect('installed-changed',
|
||||
this._appInstalledChanged.bind(this));
|
||||
this._appInstalledChanged();
|
||||
}
|
||||
|
||||
setEventSource(eventSource) {
|
||||
if (!(eventSource instanceof EventSourceBase))
|
||||
throw new Error('Event source is not valid type');
|
||||
|
||||
this._eventSource = eventSource;
|
||||
this._eventSource.connect('changed', this._reloadEvents.bind(this));
|
||||
}
|
||||
|
||||
get allowed() {
|
||||
return Main.sessionMode.showCalendarEvents;
|
||||
}
|
||||
|
||||
_updateTitle() {
|
||||
this._title.visible = !isToday(this._date);
|
||||
|
||||
if (!this._title.visible)
|
||||
return;
|
||||
|
||||
let dayFormat;
|
||||
let now = new Date();
|
||||
if (sameYear(this._date, now)) {
|
||||
/* Translators: Shown on calendar heading when selected day occurs on current year */
|
||||
dayFormat = Shell.util_translate_time_string(NC_("calendar heading", "%A, %B %-d"));
|
||||
} else {
|
||||
/* Translators: Shown on calendar heading when selected day occurs on different year */
|
||||
dayFormat = Shell.util_translate_time_string(NC_("calendar heading", "%A, %B %-d, %Y"));
|
||||
}
|
||||
this._title.label = this._date.toLocaleFormat(dayFormat);
|
||||
}
|
||||
|
||||
_reloadEvents() {
|
||||
if (this._eventSource.isLoading || this._reloading)
|
||||
return;
|
||||
|
||||
this._reloading = true;
|
||||
|
||||
let periodBegin = _getBeginningOfDay(this._date);
|
||||
let periodEnd = _getEndOfDay(this._date);
|
||||
let events = this._eventSource.getEvents(periodBegin, periodEnd);
|
||||
|
||||
let ids = events.map(e => e.id);
|
||||
this._messageById.forEach((message, id) => {
|
||||
if (ids.includes(id))
|
||||
return;
|
||||
this._messageById.delete(id);
|
||||
this.removeMessage(message);
|
||||
});
|
||||
|
||||
for (let i = 0; i < events.length; i++) {
|
||||
let event = events[i];
|
||||
|
||||
let message = this._messageById.get(event.id);
|
||||
if (!message) {
|
||||
message = new EventMessage(event, this._date);
|
||||
this._messageById.set(event.id, message);
|
||||
this.addMessage(message, false);
|
||||
} else {
|
||||
message.update(event);
|
||||
this.moveMessage(message, i, false);
|
||||
}
|
||||
}
|
||||
|
||||
this._reloading = false;
|
||||
this._sync();
|
||||
}
|
||||
|
||||
_appInstalledChanged() {
|
||||
this._calendarApp = undefined;
|
||||
this._title.reactive = this._getCalendarApp() != null;
|
||||
}
|
||||
|
||||
_getCalendarApp() {
|
||||
if (this._calendarApp !== undefined)
|
||||
return this._calendarApp;
|
||||
|
||||
let apps = Gio.AppInfo.get_recommended_for_type('text/calendar');
|
||||
if (apps && (apps.length > 0)) {
|
||||
let app = Gio.AppInfo.get_default_for_type('text/calendar', false);
|
||||
let defaultInRecommended = apps.some(a => a.equal(app));
|
||||
this._calendarApp = defaultInRecommended ? app : apps[0];
|
||||
} else {
|
||||
this._calendarApp = null;
|
||||
}
|
||||
return this._calendarApp;
|
||||
}
|
||||
|
||||
_onTitleClicked() {
|
||||
Main.overview.hide();
|
||||
Main.panel.closeCalendar();
|
||||
|
||||
let appInfo = this._getCalendarApp();
|
||||
if (appInfo.get_id() === 'org.gnome.Evolution.desktop') {
|
||||
let app = this._appSys.lookup_app('evolution-calendar.desktop');
|
||||
if (app)
|
||||
appInfo = app.app_info;
|
||||
}
|
||||
appInfo.launch([], global.create_app_launch_context(0, -1));
|
||||
}
|
||||
|
||||
setDate(date) {
|
||||
super.setDate(date);
|
||||
this._updateTitle();
|
||||
this._reloadEvents();
|
||||
}
|
||||
|
||||
_shouldShow() {
|
||||
return !this.empty || !isToday(this._date);
|
||||
}
|
||||
|
||||
_sync() {
|
||||
if (this._reloading)
|
||||
return;
|
||||
|
||||
super._sync();
|
||||
}
|
||||
});
|
||||
|
||||
var TimeLabel = GObject.registerClass(
|
||||
class NotificationTimeLabel extends St.Label {
|
||||
_init(datetime) {
|
||||
@ -1088,10 +879,6 @@ class NotificationSection extends MessageList.MessageListSection {
|
||||
});
|
||||
super.vfunc_map();
|
||||
}
|
||||
|
||||
_shouldShow() {
|
||||
return !this.empty && isToday(this._date);
|
||||
}
|
||||
});
|
||||
|
||||
var Placeholder = GObject.registerClass(
|
||||
@ -1100,41 +887,13 @@ class Placeholder extends St.BoxLayout {
|
||||
super._init({ style_class: 'message-list-placeholder', vertical: true });
|
||||
this._date = new Date();
|
||||
|
||||
let todayFile = Gio.File.new_for_uri('resource:///org/gnome/shell/theme/no-notifications.svg');
|
||||
let otherFile = Gio.File.new_for_uri('resource:///org/gnome/shell/theme/no-events.svg');
|
||||
this._todayIcon = new Gio.FileIcon({ file: todayFile });
|
||||
this._otherIcon = new Gio.FileIcon({ file: otherFile });
|
||||
|
||||
this._icon = new St.Icon();
|
||||
const file = Gio.File.new_for_uri(
|
||||
'resource:///org/gnome/shell/theme/no-notifications.svg');
|
||||
this._icon = new St.Icon({ gicon: new Gio.FileIcon({ file }) });
|
||||
this.add_actor(this._icon);
|
||||
|
||||
this._label = new St.Label();
|
||||
this._label = new St.Label({ text: _('No Notifications') });
|
||||
this.add_actor(this._label);
|
||||
|
||||
this._sync();
|
||||
}
|
||||
|
||||
setDate(date) {
|
||||
if (sameDay(this._date, date))
|
||||
return;
|
||||
this._date = date;
|
||||
this._sync();
|
||||
}
|
||||
|
||||
_sync() {
|
||||
let today = isToday(this._date);
|
||||
if (today && this._icon.gicon == this._todayIcon)
|
||||
return;
|
||||
if (!today && this._icon.gicon == this._otherIcon)
|
||||
return;
|
||||
|
||||
if (today) {
|
||||
this._icon.gicon = this._todayIcon;
|
||||
this._label.text = _("No Notifications");
|
||||
} else {
|
||||
this._icon.gicon = this._otherIcon;
|
||||
this._label.text = _("No Events");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@ -1235,9 +994,6 @@ class CalendarMessageList extends St.Widget {
|
||||
this._notificationSection = new NotificationSection();
|
||||
this._addSection(this._notificationSection);
|
||||
|
||||
this._eventsSection = new EventsSection();
|
||||
this._addSection(this._eventsSection);
|
||||
|
||||
Main.sessionMode.connect('updated', this._sync.bind(this));
|
||||
}
|
||||
|
||||
@ -1273,13 +1029,4 @@ class CalendarMessageList extends St.Widget {
|
||||
let canClear = sections.some(s => s.canClear && s.visible);
|
||||
this._clearButton.reactive = canClear;
|
||||
}
|
||||
|
||||
setEventSource(eventSource) {
|
||||
this._eventsSection.setEventSource(eventSource);
|
||||
}
|
||||
|
||||
setDate(date) {
|
||||
this._sectionList.get_children().forEach(s => s.setDate(date));
|
||||
this._placeholder.setDate(date);
|
||||
}
|
||||
});
|
||||
|
@ -13,7 +13,11 @@ const System = imports.system;
|
||||
|
||||
const { loadInterfaceXML } = imports.misc.fileUtils;
|
||||
|
||||
const NC_ = (context, str) => '%s\u0004%s'.format(context, str);
|
||||
const T_ = Shell.util_translate_time_string;
|
||||
|
||||
const MAX_FORECASTS = 5;
|
||||
const ELLIPSIS_CHAR = '\u2026';
|
||||
|
||||
const ClocksIntegrationIface = loadInterfaceXML('org.gnome.Shell.ClocksIntegration');
|
||||
const ClocksProxy = Gio.DBusProxy.makeProxyWrapper(ClocksIntegrationIface);
|
||||
@ -84,6 +88,188 @@ class TodayButton extends St.Button {
|
||||
}
|
||||
});
|
||||
|
||||
var EventsSection = GObject.registerClass(
|
||||
class EventsSection extends St.Button {
|
||||
_init() {
|
||||
super._init({
|
||||
style_class: 'events-button',
|
||||
can_focus: true,
|
||||
x_expand: true,
|
||||
child: new St.BoxLayout({
|
||||
style_class: 'events-box',
|
||||
vertical: true,
|
||||
x_expand: true,
|
||||
}),
|
||||
});
|
||||
|
||||
this._startDate = null;
|
||||
this._endDate = null;
|
||||
|
||||
this._eventSource = null;
|
||||
this._calendarApp = null;
|
||||
|
||||
this._title = new St.Label({
|
||||
style_class: 'events-title',
|
||||
});
|
||||
this.child.add_child(this._title);
|
||||
|
||||
this._eventsList = new St.BoxLayout({
|
||||
style_class: 'events-list',
|
||||
vertical: true,
|
||||
x_expand: true,
|
||||
});
|
||||
this.child.add_child(this._eventsList);
|
||||
|
||||
this._appSys = Shell.AppSystem.get_default();
|
||||
this._appSys.connect('installed-changed',
|
||||
this._appInstalledChanged.bind(this));
|
||||
this._appInstalledChanged();
|
||||
}
|
||||
|
||||
setDate(date) {
|
||||
const day = [date.getFullYear(), date.getMonth(), date.getDate()];
|
||||
this._startDate = new Date(...day);
|
||||
this._endDate = new Date(...day, 23, 59, 59, 999);
|
||||
|
||||
this._updateTitle();
|
||||
this._reloadEvents();
|
||||
}
|
||||
|
||||
setEventSource(eventSource) {
|
||||
if (!(eventSource instanceof Calendar.EventSourceBase))
|
||||
throw new Error('Event source is not valid type');
|
||||
|
||||
this._eventSource = eventSource;
|
||||
this._eventSource.connect('changed', this._reloadEvents.bind(this));
|
||||
this._eventSource.connect('notify::has-calendars',
|
||||
this._sync.bind(this));
|
||||
this._sync();
|
||||
}
|
||||
|
||||
_updateTitle() {
|
||||
/* Translators: Shown on calendar heading when selected day occurs on current year */
|
||||
const sameYearFormat = T_(NC_('calendar heading', '%B %-d'));
|
||||
|
||||
/* Translators: Shown on calendar heading when selected day occurs on different year */
|
||||
const otherYearFormat = T_(NC_('calendar heading', '%B %-d %Y'));
|
||||
|
||||
const timeSpanDay = GLib.TIME_SPAN_DAY / 1000;
|
||||
const now = new Date();
|
||||
|
||||
if (this._startDate <= now && now <= this._endDate)
|
||||
this._title.text = _('Today');
|
||||
else if (this._endDate < now && now - this._endDate < timeSpanDay)
|
||||
this._title.text = _('Yesterday');
|
||||
else if (this._startDate > now && this._startDate - now < timeSpanDay)
|
||||
this._title.text = _('Tomorrow');
|
||||
else if (this._startDate.getFullYear() === now.getFullYear())
|
||||
this._title.text = this._startDate.toLocaleFormat(sameYearFormat);
|
||||
else
|
||||
this._title.text = this._startDate.toLocaleFormat(otherYearFormat);
|
||||
}
|
||||
|
||||
_formatEventTime(event) {
|
||||
const allDay = event.allDay ||
|
||||
(event.date <= this._startDate && event.end >= this._endDate);
|
||||
|
||||
let title;
|
||||
if (allDay) {
|
||||
/* Translators: Shown in calendar event list for all day events
|
||||
* Keep it short, best if you can use less then 10 characters
|
||||
*/
|
||||
title = C_('event list time', 'All Day');
|
||||
} else {
|
||||
let date = event.date >= this._startDate ? event.date : event.end;
|
||||
title = Util.formatTime(date, { timeOnly: true });
|
||||
}
|
||||
|
||||
const rtl = Clutter.get_default_text_direction() === Clutter.TextDirection.RTL;
|
||||
if (event.date < this._startDate && !event.allDay) {
|
||||
if (rtl)
|
||||
title = '%s%s'.format(title, ELLIPSIS_CHAR);
|
||||
else
|
||||
title = '%s%s'.format(ELLIPSIS_CHAR, title);
|
||||
}
|
||||
if (event.end > this._endDate && !event.allDay) {
|
||||
if (rtl)
|
||||
title = '%s%s'.format(ELLIPSIS_CHAR, title);
|
||||
else
|
||||
title = '%s%s'.format(title, ELLIPSIS_CHAR);
|
||||
}
|
||||
return title;
|
||||
}
|
||||
|
||||
_reloadEvents() {
|
||||
if (this._eventSource.isLoading || this._reloading)
|
||||
return;
|
||||
|
||||
this._reloading = true;
|
||||
|
||||
[...this._eventsList].forEach(c => c.destroy());
|
||||
|
||||
const events =
|
||||
this._eventSource.getEvents(this._startDate, this._endDate);
|
||||
|
||||
for (let event of events) {
|
||||
const box = new St.BoxLayout({
|
||||
style_class: 'event-box',
|
||||
vertical: true,
|
||||
});
|
||||
box.add(new St.Label({
|
||||
text: event.summary,
|
||||
style_class: 'event-summary',
|
||||
}));
|
||||
box.add(new St.Label({
|
||||
text: this._formatEventTime(event),
|
||||
style_class: 'event-time',
|
||||
}));
|
||||
this._eventsList.add_child(box);
|
||||
}
|
||||
|
||||
if (this._eventsList.get_n_children() === 0) {
|
||||
const placeholder = new St.Label({
|
||||
text: _('No Events'),
|
||||
style_class: 'event-placeholder',
|
||||
});
|
||||
this._eventsList.add_child(placeholder);
|
||||
}
|
||||
|
||||
this._reloading = false;
|
||||
this._sync();
|
||||
}
|
||||
|
||||
vfunc_clicked() {
|
||||
Main.overview.hide();
|
||||
Main.panel.closeCalendar();
|
||||
|
||||
let appInfo = this._calendarApp;
|
||||
if (appInfo.get_id() === 'org.gnome.Evolution.desktop') {
|
||||
const app = this._appSys.lookup_app('evolution-calendar.desktop');
|
||||
if (app)
|
||||
appInfo = app.app_info;
|
||||
}
|
||||
appInfo.launch([], global.create_app_launch_context(0, -1));
|
||||
}
|
||||
|
||||
_appInstalledChanged() {
|
||||
const apps = Gio.AppInfo.get_recommended_for_type('text/calendar');
|
||||
if (apps && (apps.length > 0)) {
|
||||
const app = Gio.AppInfo.get_default_for_type('text/calendar', false);
|
||||
const defaultInRecommended = apps.some(a => a.equal(app));
|
||||
this._calendarApp = defaultInRecommended ? app : apps[0];
|
||||
} else {
|
||||
this._calendarApp = null;
|
||||
}
|
||||
|
||||
return this._sync();
|
||||
}
|
||||
|
||||
_sync() {
|
||||
this.visible = this._eventSource && this._eventSource.hasCalendars;
|
||||
this.reactive = this._calendarApp !== null;
|
||||
}
|
||||
});
|
||||
|
||||
var WorldClocksSection = GObject.registerClass(
|
||||
class WorldClocksSection extends St.Button {
|
||||
_init() {
|
||||
@ -598,6 +784,7 @@ class DateMenuButton extends PanelMenu.Button {
|
||||
|
||||
this._clockDisplay = new St.Label({ style_class: 'clock' });
|
||||
this._clockDisplay.clutter_text.y_align = Clutter.ActorAlign.CENTER;
|
||||
this._clockDisplay.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
|
||||
|
||||
this._indicator = new MessagesIndicator();
|
||||
|
||||
@ -632,7 +819,7 @@ class DateMenuButton extends PanelMenu.Button {
|
||||
this._calendar.connect('selected-date-changed', (_calendar, datetime) => {
|
||||
let date = _gDateTimeToDate(datetime);
|
||||
layout.frozen = !_isToday(date);
|
||||
this._messageList.setDate(date);
|
||||
this._eventsItem.setDate(date);
|
||||
});
|
||||
|
||||
this.menu.connect('open-state-changed', (menu, isOpen) => {
|
||||
@ -641,7 +828,7 @@ class DateMenuButton extends PanelMenu.Button {
|
||||
let now = new Date();
|
||||
this._calendar.setDate(now);
|
||||
this._date.setDate(now);
|
||||
this._messageList.setDate(now);
|
||||
this._eventsItem.setDate(now);
|
||||
}
|
||||
});
|
||||
|
||||
@ -672,6 +859,9 @@ class DateMenuButton extends PanelMenu.Button {
|
||||
style_class: 'datemenu-displays-box' });
|
||||
this._displaysSection.add_actor(displaysBox);
|
||||
|
||||
this._eventsItem = new EventsSection();
|
||||
displaysBox.add_child(this._eventsItem);
|
||||
|
||||
this._clocksItem = new WorldClocksSection();
|
||||
displaysBox.add_child(this._clocksItem);
|
||||
|
||||
@ -697,7 +887,7 @@ class DateMenuButton extends PanelMenu.Button {
|
||||
this._eventSource.destroy();
|
||||
|
||||
this._calendar.setEventSource(eventSource);
|
||||
this._messageList.setEventSource(eventSource);
|
||||
this._eventsItem.setEventSource(eventSource);
|
||||
|
||||
this._eventSource = eventSource;
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported Dialog, MessageDialogContent, ListSection, ListSectionItem */
|
||||
|
||||
const { Clutter, GObject, Meta, Pango, St } = imports.gi;
|
||||
const { Clutter, GLib, GObject, Meta, Pango, St } = imports.gi;
|
||||
|
||||
function _setLabel(label, value) {
|
||||
label.set({
|
||||
@ -221,13 +221,16 @@ var MessageDialogContent = GObject.registerClass({
|
||||
this._updateTitleStyleLater = Meta.later_add(Meta.LaterType.BEFORE_REDRAW, () => {
|
||||
this._updateTitleStyleLater = 0;
|
||||
this._title.add_style_class_name('leightweight');
|
||||
return false;
|
||||
return GLib.SOURCE_REMOVE;
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
set title(title) {
|
||||
if (this._title.text === title)
|
||||
return;
|
||||
|
||||
_setLabel(this._title, title);
|
||||
|
||||
this._title.remove_style_class_name('leightweight');
|
||||
@ -237,6 +240,9 @@ var MessageDialogContent = GObject.registerClass({
|
||||
}
|
||||
|
||||
set description(description) {
|
||||
if (this._description.text === description)
|
||||
return;
|
||||
|
||||
_setLabel(this._description, description);
|
||||
this.notify('description');
|
||||
}
|
||||
|
43
js/ui/dnd.js
43
js/ui/dnd.js
@ -375,19 +375,29 @@ var _Draggable = class _Draggable {
|
||||
|
||||
this._dragActorSource = undefined;
|
||||
this._dragOrigParent = this.actor.get_parent();
|
||||
this._dragOrigX = this._dragActor.x;
|
||||
this._dragOrigY = this._dragActor.y;
|
||||
this._dragActorHadFixedPos = this._dragActor.fixed_position_set;
|
||||
this._dragOrigX = this._dragActor.allocation.x1;
|
||||
this._dragOrigY = this._dragActor.allocation.y1;
|
||||
this._dragOrigWidth = this._dragActor.allocation.get_width();
|
||||
this._dragOrigHeight = this._dragActor.allocation.get_height();
|
||||
this._dragOrigScale = this._dragActor.scale_x;
|
||||
|
||||
// When the actor gets reparented to the uiGroup, it will be
|
||||
// allocated its preferred size, so use that size instead of the
|
||||
// current allocation size.
|
||||
const [, newAllocatedWidth] = this._dragActor.get_preferred_width(-1);
|
||||
const [, newAllocatedHeight] = this._dragActor.get_preferred_height(-1);
|
||||
|
||||
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
|
||||
let [scaledWidth, scaledHeight] = this.actor.get_transformed_size();
|
||||
this._dragActor.set_scale(scaledWidth / this.actor.width,
|
||||
scaledHeight / this.actor.height);
|
||||
this._dragActor.set_scale(
|
||||
transformedExtents.get_width() / newAllocatedWidth,
|
||||
transformedExtents.get_height() / newAllocatedHeight);
|
||||
|
||||
let [actorStageX, actorStageY] = this.actor.get_transformed_position();
|
||||
this._dragOffsetX = actorStageX - this._dragStartX;
|
||||
this._dragOffsetY = actorStageY - 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);
|
||||
@ -417,6 +427,10 @@ var _Draggable = class _Draggable {
|
||||
this._dragOffsetX -= transX;
|
||||
this._dragOffsetY -= transY;
|
||||
|
||||
this._dragActor.set_position(
|
||||
this._dragX + this._dragOffsetX,
|
||||
this._dragY + this._dragOffsetY);
|
||||
|
||||
if (this._dragActorMaxSize != undefined) {
|
||||
let [scaledWidth, scaledHeight] = this._dragActor.get_transformed_size();
|
||||
let currentSize = Math.max(scaledWidth, scaledHeight);
|
||||
@ -635,9 +649,15 @@ var _Draggable = class _Draggable {
|
||||
if (parentWidth != 0)
|
||||
parentScale = parentScaledWidth / parentWidth;
|
||||
|
||||
// Also adjust for the difference in the original actor width
|
||||
// and the width it is now (children of uiGroup always get
|
||||
// allocated their preferred size)
|
||||
const childScaleX =
|
||||
this._dragOrigWidth / this._dragActor.allocation.get_width();
|
||||
|
||||
x = parentX + parentScale * this._dragOrigX;
|
||||
y = parentY + parentScale * this._dragOrigY;
|
||||
scale = this._dragOrigScale * parentScale;
|
||||
scale = this._dragOrigScale * parentScale * childScaleX;
|
||||
} else {
|
||||
// Snap back actor to its original stage position
|
||||
x = this._snapBackX;
|
||||
@ -718,7 +738,10 @@ var _Draggable = class _Draggable {
|
||||
Main.uiGroup.remove_child(this._dragActor);
|
||||
this._dragOrigParent.add_actor(this._dragActor);
|
||||
dragActor.set_scale(this._dragOrigScale, this._dragOrigScale);
|
||||
dragActor.set_position(this._dragOrigX, this._dragOrigY);
|
||||
if (this._dragActorHadFixedPos)
|
||||
dragActor.set_position(this._dragOrigX, this._dragOrigY);
|
||||
else
|
||||
dragActor.fixed_position_set = false;
|
||||
} else {
|
||||
dragActor.destroy();
|
||||
}
|
||||
|
@ -362,6 +362,10 @@ function init() {
|
||||
const Format = imports.format;
|
||||
|
||||
String.prototype.format = Format.format;
|
||||
|
||||
Math.clamp = function (x, lower, upper) {
|
||||
return Math.min(Math.max(x, lower), upper);
|
||||
};
|
||||
}
|
||||
|
||||
// adjustAnimationTime:
|
||||
|
@ -139,7 +139,9 @@ function checkForUpdates() {
|
||||
return;
|
||||
if (extension.hasUpdate)
|
||||
return;
|
||||
metadatas[uuid] = extension.metadata;
|
||||
metadatas[uuid] = {
|
||||
version: extension.metadata.version,
|
||||
};
|
||||
});
|
||||
|
||||
if (Object.keys(metadatas).length === 0)
|
||||
|
1732
js/ui/iconGrid.js
1732
js/ui/iconGrid.js
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,5 @@
|
||||
/* exported InhibitShortcutsDialog */
|
||||
const { Clutter, Gio, GLib, GObject, Gtk, Meta, Shell, St } = imports.gi;
|
||||
const { Clutter, Gio, GLib, GObject, Gtk, Meta, Pango, Shell, St } = imports.gi;
|
||||
|
||||
const Dialog = imports.ui.dialog;
|
||||
const ModalDialog = imports.ui.modalDialog;
|
||||
@ -90,6 +90,8 @@ var InhibitShortcutsDialog = GObject.registerClass({
|
||||
text: _('You can restore shortcuts by pressing %s.').format(restoreAccel),
|
||||
style_class: 'message-dialog-description',
|
||||
});
|
||||
restoreLabel.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
|
||||
restoreLabel.clutter_text.line_wrap = true;
|
||||
content.add_child(restoreLabel);
|
||||
}
|
||||
|
||||
|
@ -42,7 +42,7 @@ const defaultKeysPost = [
|
||||
[[{ width: 1.5, keyval: Clutter.KEY_BackSpace, icon: 'edit-clear-symbolic' }],
|
||||
[{ width: 2, keyval: Clutter.KEY_Return, extraClassName: 'enter-key', icon: 'keyboard-enter-symbolic' }],
|
||||
[{ label: '=/<', width: 3, level: 3, right: true }],
|
||||
[{ action: 'emoji', icon: 'face-smile-symbolic' }, { action: 'languageMenu', extraClassName: 'layout-key' }, { action: 'hide', extraClassName: 'hide-key' }]],
|
||||
[{ action: 'emoji', icon: 'face-smile-symbolic' }, { action: 'languageMenu', extraClassName: 'layout-key', icon: 'keyboard-layout-filled-symbolic' }, { action: 'hide', extraClassName: 'hide-key', icon: 'go-down-symbolic' }]],
|
||||
[[{ width: 1.5, keyval: Clutter.KEY_BackSpace, icon: 'edit-clear-symbolic' }],
|
||||
[{ width: 2, keyval: Clutter.KEY_Return, extraClassName: 'enter-key', icon: 'keyboard-enter-symbolic' }],
|
||||
[{ label: '?123', width: 3, level: 2, right: true }],
|
||||
@ -61,6 +61,24 @@ class AspectContainer extends St.Widget {
|
||||
this.queue_relayout();
|
||||
}
|
||||
|
||||
vfunc_get_preferred_width(forHeight) {
|
||||
let [min, nat] = super.vfunc_get_preferred_width(forHeight);
|
||||
|
||||
if (forHeight > 0)
|
||||
nat = forHeight * this._ratio;
|
||||
|
||||
return [min, nat];
|
||||
}
|
||||
|
||||
vfunc_get_preferred_height(forWidth) {
|
||||
let [min, nat] = super.vfunc_get_preferred_height(forWidth);
|
||||
|
||||
if (forWidth > 0)
|
||||
nat = forWidth / this._ratio;
|
||||
|
||||
return [min, nat];
|
||||
}
|
||||
|
||||
vfunc_allocate(box) {
|
||||
if (box.get_width() > 0 && box.get_height() > 0) {
|
||||
let sizeRatio = box.get_width() / box.get_height();
|
||||
@ -1608,7 +1626,9 @@ class Keyboard extends St.BoxLayout {
|
||||
* we allow the OSK being smaller than 1/3rd of the monitor height
|
||||
* there.
|
||||
*/
|
||||
this.height = Math.min(maxHeight, this.get_preferred_height(monitor.width));
|
||||
const forWidth = this.get_theme_node().adjust_for_width(monitor.width);
|
||||
const [, natHeight] = this.get_preferred_height(forWidth);
|
||||
this.height = Math.min(maxHeight, natHeight);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6,7 +6,6 @@ const Signals = imports.signals;
|
||||
|
||||
const Background = imports.ui.background;
|
||||
const BackgroundMenu = imports.ui.backgroundMenu;
|
||||
const LoginManager = imports.misc.loginManager;
|
||||
|
||||
const DND = imports.ui.dnd;
|
||||
const Main = imports.ui.main;
|
||||
@ -295,18 +294,6 @@ var LayoutManager = GObject.registerClass({
|
||||
monitorManager.connect('monitors-changed',
|
||||
this._monitorsChanged.bind(this));
|
||||
this._monitorsChanged();
|
||||
|
||||
// NVIDIA drivers don't preserve FBO contents across
|
||||
// suspend/resume, see
|
||||
// https://bugzilla.gnome.org/show_bug.cgi?id=739178
|
||||
if (Shell.util_need_background_refresh()) {
|
||||
LoginManager.getLoginManager().connect('prepare-for-sleep',
|
||||
(lm, suspending) => {
|
||||
if (suspending)
|
||||
return;
|
||||
Meta.Background.refresh_all();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// This is called by Main after everything else is constructed
|
||||
@ -470,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();
|
||||
@ -477,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);
|
||||
@ -486,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() {
|
||||
@ -644,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,
|
||||
@ -661,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();
|
||||
@ -678,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');
|
||||
@ -1204,7 +1202,8 @@ class HotCorner extends Clutter.Actor {
|
||||
|
||||
if (Clutter.get_default_text_direction() == Clutter.TextDirection.RTL) {
|
||||
this._corner.set_position(this.width - this._corner.width, 0);
|
||||
this.set_anchor_point_from_gravity(Clutter.Gravity.NORTH_EAST);
|
||||
this.set_pivot_point(1.0, 0.0);
|
||||
this.translation_x = -this.width;
|
||||
} else {
|
||||
this._corner.set_position(0, 0);
|
||||
}
|
||||
@ -1229,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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -489,7 +489,10 @@ var Magnifier = class Magnifier {
|
||||
_updateMouseSprite() {
|
||||
this._updateSpriteTexture();
|
||||
let [xHot, yHot] = this._cursorTracker.get_hot();
|
||||
this._mouseSprite.set_anchor_point(xHot, yHot);
|
||||
this._mouseSprite.set({
|
||||
translation_x: -xHot,
|
||||
translation_y: -yHot,
|
||||
});
|
||||
}
|
||||
|
||||
_updateSpriteTexture() {
|
||||
|
@ -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();
|
||||
|
@ -4,7 +4,6 @@ const { Atk, Clutter, Gio, GLib,
|
||||
const Main = imports.ui.main;
|
||||
const MessageTray = imports.ui.messageTray;
|
||||
|
||||
const Calendar = imports.ui.calendar;
|
||||
const Util = imports.misc.util;
|
||||
|
||||
var MESSAGE_ANIMATION_TIME = 100;
|
||||
@ -572,7 +571,6 @@ var MessageListSection = GObject.registerClass({
|
||||
Main.sessionMode.disconnect(id);
|
||||
});
|
||||
|
||||
this._date = new Date();
|
||||
this._empty = true;
|
||||
this._canClear = false;
|
||||
this._sync();
|
||||
@ -598,13 +596,6 @@ var MessageListSection = GObject.registerClass({
|
||||
return true;
|
||||
}
|
||||
|
||||
setDate(date) {
|
||||
if (Calendar.sameDay(date, this._date))
|
||||
return;
|
||||
this._date = date;
|
||||
this._sync();
|
||||
}
|
||||
|
||||
addMessage(message, animate) {
|
||||
this.addMessageAtIndex(message, -1, animate);
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported NotificationPolicy, NotificationGenericPolicy,
|
||||
NotificationApplicationPolicy, Source, SourceActor, SourceActorWithLabel,
|
||||
NotificationApplicationPolicy, Source, SourceActor,
|
||||
SystemNotificationSource, MessageTray */
|
||||
|
||||
const { Clutter, Gio, GLib, GObject, Meta, Shell, St } = imports.gi;
|
||||
@ -655,77 +655,6 @@ class SourceActor extends St.Widget {
|
||||
}
|
||||
});
|
||||
|
||||
var SourceActorWithLabel = GObject.registerClass(
|
||||
class SourceActorWithLabel extends SourceActor {
|
||||
_init(source, size) {
|
||||
super._init(source, size);
|
||||
|
||||
this._counterLabel = new St.Label({ x_align: Clutter.ActorAlign.CENTER,
|
||||
x_expand: true,
|
||||
y_align: Clutter.ActorAlign.CENTER,
|
||||
y_expand: true });
|
||||
|
||||
this._counterBin = new St.Bin({ style_class: 'summary-source-counter',
|
||||
child: this._counterLabel,
|
||||
layout_manager: new Clutter.BinLayout() });
|
||||
this._counterBin.hide();
|
||||
|
||||
this._counterBin.connect('style-changed', () => {
|
||||
let themeNode = this._counterBin.get_theme_node();
|
||||
this._counterBin.translation_x = themeNode.get_length('-shell-counter-overlap-x');
|
||||
this._counterBin.translation_y = themeNode.get_length('-shell-counter-overlap-y');
|
||||
});
|
||||
|
||||
this.add_actor(this._counterBin);
|
||||
|
||||
this._countUpdatedId = this._source.connect('notify::count', this._updateCount.bind(this));
|
||||
this._updateCount();
|
||||
|
||||
this.connect('destroy', () => {
|
||||
this._source.disconnect(this._countUpdatedId);
|
||||
});
|
||||
}
|
||||
|
||||
vfunc_allocate(box) {
|
||||
super.vfunc_allocate(box);
|
||||
|
||||
let childBox = new Clutter.ActorBox();
|
||||
|
||||
let [, , naturalWidth, naturalHeight] = this._counterBin.get_preferred_size();
|
||||
let direction = this.get_text_direction();
|
||||
|
||||
if (direction == Clutter.TextDirection.LTR) {
|
||||
// allocate on the right in LTR
|
||||
childBox.x1 = box.x2 - naturalWidth;
|
||||
childBox.x2 = box.x2;
|
||||
} else {
|
||||
// allocate on the left in RTL
|
||||
childBox.x1 = 0;
|
||||
childBox.x2 = naturalWidth;
|
||||
}
|
||||
|
||||
childBox.y1 = box.y2 - naturalHeight;
|
||||
childBox.y2 = box.y2;
|
||||
|
||||
this._counterBin.allocate(childBox);
|
||||
}
|
||||
|
||||
_updateCount() {
|
||||
if (this._actorDestroyed)
|
||||
return;
|
||||
|
||||
this._counterBin.visible = this._source.countVisible;
|
||||
|
||||
let text;
|
||||
if (this._source.count < 100)
|
||||
text = this._source.count.toString();
|
||||
else
|
||||
text = String.fromCharCode(0x22EF); // midline horizontal ellipsis
|
||||
|
||||
this._counterLabel.set_text(text);
|
||||
}
|
||||
});
|
||||
|
||||
var Source = GObject.registerClass({
|
||||
Properties: {
|
||||
'count': GObject.ParamSpec.int(
|
||||
|
@ -2,7 +2,6 @@
|
||||
const { Gio, GObject, Shell, St } = imports.gi;
|
||||
const Signals = imports.signals;
|
||||
|
||||
const Calendar = imports.ui.calendar;
|
||||
const Main = imports.ui.main;
|
||||
const MessageList = imports.ui.messageList;
|
||||
|
||||
@ -252,10 +251,6 @@ class MediaSection extends MessageList.MessageListSection {
|
||||
this._onProxyReady.bind(this));
|
||||
}
|
||||
|
||||
_shouldShow() {
|
||||
return !this.empty && Calendar.isToday(this._date);
|
||||
}
|
||||
|
||||
get allowed() {
|
||||
return !Main.sessionMode.isGreeter;
|
||||
}
|
||||
|
@ -4,6 +4,10 @@
|
||||
const { Clutter, GLib, GObject, Meta, Shell, St } = imports.gi;
|
||||
const Signals = imports.signals;
|
||||
|
||||
// Time for initial animation going into Overview mode;
|
||||
// this is defined here to make it available in imports.
|
||||
var ANIMATION_TIME = 250;
|
||||
|
||||
const Background = imports.ui.background;
|
||||
const DND = imports.ui.dnd;
|
||||
const LayoutManager = imports.ui.layout;
|
||||
@ -14,9 +18,6 @@ const OverviewControls = imports.ui.overviewControls;
|
||||
const Params = imports.misc.params;
|
||||
const WorkspaceThumbnail = imports.ui.workspaceThumbnail;
|
||||
|
||||
// Time for initial animation going into Overview mode
|
||||
var ANIMATION_TIME = 250;
|
||||
|
||||
// Must be less than ANIMATION_TIME, since we switch to
|
||||
// or from the overview completely after ANIMATION_TIME,
|
||||
// and don't want the shading animation to get cut off
|
||||
@ -244,11 +245,11 @@ var Overview = class {
|
||||
_unshadeBackgrounds() {
|
||||
let backgrounds = this._backgroundGroup.get_children();
|
||||
for (let i = 0; i < backgrounds.length; i++) {
|
||||
backgrounds[i].ease_property('brightness', 1.0, {
|
||||
backgrounds[i].ease_property('@content.brightness', 1.0, {
|
||||
duration: SHADE_ANIMATION_TIME,
|
||||
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
|
||||
});
|
||||
backgrounds[i].ease_property('vignette-sharpness', 0.0, {
|
||||
backgrounds[i].ease_property('@content.vignette-sharpness', 0.0, {
|
||||
duration: SHADE_ANIMATION_TIME,
|
||||
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
|
||||
});
|
||||
@ -258,14 +259,16 @@ var Overview = class {
|
||||
_shadeBackgrounds() {
|
||||
let backgrounds = this._backgroundGroup.get_children();
|
||||
for (let i = 0; i < backgrounds.length; i++) {
|
||||
backgrounds[i].ease_property('brightness', Lightbox.VIGNETTE_BRIGHTNESS, {
|
||||
duration: SHADE_ANIMATION_TIME,
|
||||
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
|
||||
});
|
||||
backgrounds[i].ease_property('vignette-sharpness', Lightbox.VIGNETTE_SHARPNESS, {
|
||||
duration: SHADE_ANIMATION_TIME,
|
||||
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
|
||||
});
|
||||
backgrounds[i].ease_property('@content.brightness',
|
||||
Lightbox.VIGNETTE_BRIGHTNESS, {
|
||||
duration: SHADE_ANIMATION_TIME,
|
||||
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
|
||||
});
|
||||
backgrounds[i].ease_property('@content.vignette-sharpness',
|
||||
Lightbox.VIGNETTE_SHARPNESS, {
|
||||
duration: SHADE_ANIMATION_TIME,
|
||||
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -437,19 +440,19 @@ var Overview = class {
|
||||
this.emit('windows-restacked', stackIndices);
|
||||
}
|
||||
|
||||
beginItemDrag(_source) {
|
||||
this.emit('item-drag-begin');
|
||||
beginItemDrag(source) {
|
||||
this.emit('item-drag-begin', source);
|
||||
this._inItemDrag = true;
|
||||
}
|
||||
|
||||
cancelledItemDrag(_source) {
|
||||
this.emit('item-drag-cancelled');
|
||||
cancelledItemDrag(source) {
|
||||
this.emit('item-drag-cancelled', source);
|
||||
}
|
||||
|
||||
endItemDrag(_source) {
|
||||
endItemDrag(source) {
|
||||
if (!this._inItemDrag)
|
||||
return;
|
||||
this.emit('item-drag-end');
|
||||
this.emit('item-drag-end', source);
|
||||
this._inItemDrag = false;
|
||||
}
|
||||
|
||||
@ -575,7 +578,7 @@ var Overview = class {
|
||||
this._activationTime = GLib.get_monotonic_time() / GLib.USEC_PER_SEC;
|
||||
|
||||
Meta.disable_unredirect_for_display(global.display);
|
||||
this.viewSelector.show();
|
||||
this.viewSelector.animateToOverview();
|
||||
|
||||
this._overview.opacity = 0;
|
||||
this._overview.ease({
|
||||
|
@ -8,8 +8,9 @@ const Main = imports.ui.main;
|
||||
const Params = imports.misc.params;
|
||||
const ViewSelector = imports.ui.viewSelector;
|
||||
const WorkspaceThumbnail = imports.ui.workspaceThumbnail;
|
||||
const Overview = imports.ui.overview;
|
||||
|
||||
var SIDE_CONTROLS_ANIMATION_TIME = 160;
|
||||
var SIDE_CONTROLS_ANIMATION_TIME = Overview.ANIMATION_TIME;
|
||||
|
||||
function getRtlSlideDirection(direction, actor) {
|
||||
let rtl = actor.text_direction == Clutter.TextDirection.RTL;
|
||||
@ -422,6 +423,7 @@ class ControlsManager extends St.Widget {
|
||||
let activeWorkspaceIndex = workspaceManager.get_active_workspace_index();
|
||||
|
||||
this._workspaceAdjustment = new St.Adjustment({
|
||||
actor: this,
|
||||
value: activeWorkspaceIndex,
|
||||
lower: 0,
|
||||
page_increment: 1,
|
||||
@ -453,8 +455,6 @@ class ControlsManager extends St.Widget {
|
||||
this._group.add_child(this.viewSelector);
|
||||
this._group.add_actor(this._thumbnailsSlider);
|
||||
|
||||
layout.connect('allocation-changed', this._updateWorkspacesGeometry.bind(this));
|
||||
|
||||
Main.overview.connect('showing', this._updateSpacerVisibility.bind(this));
|
||||
|
||||
this.connect('destroy', this._onDestroy.bind(this));
|
||||
@ -477,26 +477,6 @@ class ControlsManager extends St.Widget {
|
||||
this._workspaceAdjustment.value = activeIndex;
|
||||
}
|
||||
|
||||
_updateWorkspacesGeometry() {
|
||||
let [x, y] = this.get_transformed_position();
|
||||
let [width, height] = this.get_transformed_size();
|
||||
let geometry = { x, y, width, height };
|
||||
|
||||
let spacing = this.get_theme_node().get_length('spacing');
|
||||
let dashWidth = this._dashSlider.getVisibleWidth() + spacing;
|
||||
let thumbnailsWidth = this._thumbnailsSlider.getNonExpandedWidth() + spacing;
|
||||
|
||||
geometry.width -= dashWidth;
|
||||
geometry.width -= thumbnailsWidth;
|
||||
|
||||
if (this.get_text_direction() == Clutter.TextDirection.LTR)
|
||||
geometry.x += dashWidth;
|
||||
else
|
||||
geometry.x += thumbnailsWidth;
|
||||
|
||||
this.viewSelector.setWorkspacesFullGeometry(geometry);
|
||||
}
|
||||
|
||||
_setVisibility() {
|
||||
// Ignore the case when we're leaving the overview, since
|
||||
// actors will be made visible again when entering the overview
|
||||
|
@ -120,6 +120,10 @@ var PageIndicators = GObject.registerClass({
|
||||
for (let i = 0; i < children.length; i++)
|
||||
this._updateIndicator(children[i], i);
|
||||
}
|
||||
|
||||
get nPages() {
|
||||
return this._nPages;
|
||||
}
|
||||
});
|
||||
|
||||
var AnimatedPageIndicators = GObject.registerClass(
|
||||
|
@ -675,7 +675,7 @@ class PanelCorner extends St.DrawingArea {
|
||||
let borderWidth = node.get_length('-panel-corner-border-width');
|
||||
|
||||
this.set_size(cornerRadius, borderWidth + cornerRadius);
|
||||
this.set_anchor_point(0, borderWidth);
|
||||
this.translation_y = -borderWidth;
|
||||
}
|
||||
});
|
||||
|
||||
@ -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);
|
@ -225,10 +225,6 @@ class Indicator extends PanelMenu.SystemIndicator {
|
||||
}
|
||||
});
|
||||
|
||||
function clamp(value, min, max) {
|
||||
return Math.max(min, Math.min(max, value));
|
||||
}
|
||||
|
||||
var AppAuthorizer = class {
|
||||
constructor(desktopId, reqAccuracyLevel, permStoreProxy, maxAccuracyLevel) {
|
||||
this.desktopId = desktopId;
|
||||
@ -313,9 +309,8 @@ var AppAuthorizer = class {
|
||||
|
||||
_completeAuth() {
|
||||
if (this._accuracyLevel != GeoclueAccuracyLevel.NONE) {
|
||||
this._accuracyLevel = clamp(this._accuracyLevel,
|
||||
0,
|
||||
this._maxAccuracyLevel);
|
||||
this._accuracyLevel = Math.clamp(this._accuracyLevel,
|
||||
0, this._maxAccuracyLevel);
|
||||
}
|
||||
this._saveToPermissionStore();
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
});
|
||||
|
@ -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;
|
||||
}
|
||||
});
|
@ -62,6 +62,7 @@ var StreamSlider = class {
|
||||
|
||||
this._stream = null;
|
||||
this._volumeCancellable = null;
|
||||
this._icons = [];
|
||||
}
|
||||
|
||||
get stream() {
|
||||
@ -182,24 +183,15 @@ var StreamSlider = class {
|
||||
if (!this._stream)
|
||||
return null;
|
||||
|
||||
let icons = ["audio-volume-muted-symbolic",
|
||||
"audio-volume-low-symbolic",
|
||||
"audio-volume-medium-symbolic",
|
||||
"audio-volume-high-symbolic",
|
||||
"audio-volume-overamplified-symbolic"];
|
||||
|
||||
let volume = this._stream.volume;
|
||||
let n;
|
||||
if (this._stream.is_muted || volume <= 0) {
|
||||
n = 0;
|
||||
} else {
|
||||
n = Math.ceil(3 * volume / this._control.get_vol_max_norm());
|
||||
if (n < 1)
|
||||
n = 1;
|
||||
else if (n > 3)
|
||||
n = 4;
|
||||
n = Math.clamp(n, 1, this._icons.length - 1);
|
||||
}
|
||||
return icons[n];
|
||||
return this._icons[n];
|
||||
}
|
||||
|
||||
getLevel() {
|
||||
@ -223,6 +215,13 @@ var OutputStreamSlider = class extends StreamSlider {
|
||||
constructor(control) {
|
||||
super(control);
|
||||
this._slider.accessible_name = _("Volume");
|
||||
this._icons = [
|
||||
'audio-volume-muted-symbolic',
|
||||
'audio-volume-low-symbolic',
|
||||
'audio-volume-medium-symbolic',
|
||||
'audio-volume-high-symbolic',
|
||||
'audio-volume-overamplified-symbolic',
|
||||
];
|
||||
}
|
||||
|
||||
_connectStream(stream) {
|
||||
@ -274,6 +273,12 @@ var InputStreamSlider = class extends StreamSlider {
|
||||
this._control.connect('stream-added', this._maybeShowInput.bind(this));
|
||||
this._control.connect('stream-removed', this._maybeShowInput.bind(this));
|
||||
this._icon.icon_name = 'audio-input-microphone-symbolic';
|
||||
this._icons = [
|
||||
'microphone-sensitivity-muted-symbolic',
|
||||
'microphone-sensitivity-low-symbolic',
|
||||
'microphone-sensitivity-medium-symbolic',
|
||||
'microphone-sensitivity-high-symbolic',
|
||||
];
|
||||
}
|
||||
|
||||
_connectStream(stream) {
|
||||
@ -319,7 +324,7 @@ var VolumeMenu = class extends PopupMenu.PopupMenuSection {
|
||||
|
||||
this._output = new OutputStreamSlider(this._control);
|
||||
this._output.connect('stream-updated', () => {
|
||||
this.emit('icon-changed');
|
||||
this.emit('output-icon-changed');
|
||||
});
|
||||
this.addMenuItem(this._output.item);
|
||||
|
||||
@ -327,6 +332,9 @@ var VolumeMenu = class extends PopupMenu.PopupMenuSection {
|
||||
this._input.item.connect('notify::visible', () => {
|
||||
this.emit('input-visible-changed');
|
||||
});
|
||||
this._input.connect('stream-updated', () => {
|
||||
this.emit('input-icon-changed');
|
||||
});
|
||||
this.addMenuItem(this._input.item);
|
||||
|
||||
this.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
|
||||
@ -343,7 +351,7 @@ var VolumeMenu = class extends PopupMenu.PopupMenuSection {
|
||||
this._readInput();
|
||||
this._readOutput();
|
||||
} else {
|
||||
this.emit('icon-changed');
|
||||
this.emit('output-icon-changed');
|
||||
}
|
||||
}
|
||||
|
||||
@ -355,10 +363,14 @@ var VolumeMenu = class extends PopupMenu.PopupMenuSection {
|
||||
this._input.stream = this._control.get_default_source();
|
||||
}
|
||||
|
||||
getIcon() {
|
||||
getOutputIcon() {
|
||||
return this._output.getIcon();
|
||||
}
|
||||
|
||||
getInputIcon() {
|
||||
return this._input.getIcon();
|
||||
}
|
||||
|
||||
getLevel() {
|
||||
return this._output.getLevel();
|
||||
}
|
||||
@ -382,21 +394,24 @@ class Indicator extends PanelMenu.SystemIndicator {
|
||||
|
||||
this._control = getMixerControl();
|
||||
this._volumeMenu = new VolumeMenu(this._control);
|
||||
this._volumeMenu.connect('icon-changed', () => {
|
||||
let icon = this._volumeMenu.getIcon();
|
||||
this._volumeMenu.connect('output-icon-changed', () => {
|
||||
let icon = this._volumeMenu.getOutputIcon();
|
||||
|
||||
if (icon != null)
|
||||
this._primaryIndicator.icon_name = icon;
|
||||
this._primaryIndicator.visible = icon !== null;
|
||||
});
|
||||
|
||||
this._inputIndicator.set({
|
||||
icon_name: 'audio-input-microphone-symbolic',
|
||||
visible: this._volumeMenu.getInputVisible(),
|
||||
});
|
||||
this._inputIndicator.visible = this._volumeMenu.getInputVisible();
|
||||
this._volumeMenu.connect('input-visible-changed', () => {
|
||||
this._inputIndicator.visible = this._volumeMenu.getInputVisible();
|
||||
});
|
||||
this._volumeMenu.connect('input-icon-changed', () => {
|
||||
let icon = this._volumeMenu.getInputIcon();
|
||||
|
||||
if (icon !== null)
|
||||
this._inputIndicator.icon_name = icon;
|
||||
});
|
||||
|
||||
this.menu.addMenuItem(this._volumeMenu);
|
||||
}
|
||||
@ -406,7 +421,7 @@ class Indicator extends PanelMenu.SystemIndicator {
|
||||
if (result == Clutter.EVENT_PROPAGATE || this.menu.actor.mapped)
|
||||
return result;
|
||||
|
||||
let gicon = new Gio.ThemedIcon({ name: this._volumeMenu.getIcon() });
|
||||
let gicon = new Gio.ThemedIcon({ name: this._volumeMenu.getOutputIcon() });
|
||||
let level = this._volumeMenu.getLevel();
|
||||
let maxLevel = this._volumeMenu.getMaxLevel();
|
||||
Main.osdWindowManager.show(-1, gicon, null, level, maxLevel);
|
||||
|
@ -28,10 +28,6 @@ const State = {
|
||||
SCROLLING: 1,
|
||||
};
|
||||
|
||||
function clamp(value, min, max) {
|
||||
return Math.max(min, Math.min(max, value));
|
||||
}
|
||||
|
||||
const TouchpadSwipeGesture = GObject.registerClass({
|
||||
Properties: {
|
||||
'enabled': GObject.ParamSpec.boolean(
|
||||
@ -558,8 +554,8 @@ var SwipeTracker = GObject.registerClass({
|
||||
|
||||
let firstPoint = this._snapPoints[0];
|
||||
let lastPoint = this._snapPoints[this._snapPoints.length - 1];
|
||||
this._progress = clamp(this._progress, firstPoint, lastPoint);
|
||||
this._progress = clamp(this._progress,
|
||||
this._progress = Math.clamp(this._progress, firstPoint, lastPoint);
|
||||
this._progress = Math.clamp(this._progress,
|
||||
this._initialProgress - 1, this._initialProgress + 1);
|
||||
|
||||
this.emit('update', this._progress);
|
||||
@ -606,7 +602,7 @@ var SwipeTracker = GObject.registerClass({
|
||||
|
||||
let duration = Math.abs((this._progress - endProgress) / velocity * DURATION_MULTIPLIER);
|
||||
if (duration > 0) {
|
||||
duration = clamp(duration,
|
||||
duration = Math.clamp(duration,
|
||||
MIN_ANIMATION_DURATION, MAX_ANIMATION_DURATION);
|
||||
}
|
||||
|
||||
|
@ -485,6 +485,7 @@ var UnlockDialog = GObject.registerClass({
|
||||
this._gdmClient = new Gdm.Client();
|
||||
|
||||
this._adjustment = new St.Adjustment({
|
||||
actor: this,
|
||||
lower: 0,
|
||||
upper: 2,
|
||||
page_size: 1,
|
||||
@ -524,6 +525,10 @@ var UnlockDialog = GObject.registerClass({
|
||||
|
||||
this._bgManagers = [];
|
||||
|
||||
const themeContext = St.ThemeContext.get_for_stage(global.stage);
|
||||
this._scaleChangedId = themeContext.connect('notify::scale-factor',
|
||||
() => this._updateBackgroundEffects());
|
||||
|
||||
this._updateBackgrounds();
|
||||
this._monitorsChangedId =
|
||||
Main.layoutManager.connect('monitors-changed', this._updateBackgrounds.bind(this));
|
||||
@ -566,9 +571,15 @@ var UnlockDialog = GObject.registerClass({
|
||||
this._otherUserButton.set_pivot_point(0.5, 0.5);
|
||||
this._otherUserButton.connect('clicked', this._otherUserClicked.bind(this));
|
||||
|
||||
let screenSaverSettings = new Gio.Settings({ schema_id: 'org.gnome.desktop.screensaver' });
|
||||
screenSaverSettings.bind('user-switch-enabled',
|
||||
this._otherUserButton, 'visible', Gio.SettingsBindFlags.GET);
|
||||
this._screenSaverSettings = new Gio.Settings({ schema_id: 'org.gnome.desktop.screensaver' });
|
||||
|
||||
this._userSwitchEnabledId = this._screenSaverSettings.connect('changed::user-switch-enabled',
|
||||
this._updateUserSwitchVisibility.bind(this));
|
||||
|
||||
this._userLoadedId = this._user.connect('notify::is-loaded',
|
||||
this._updateUserSwitchVisibility.bind(this));
|
||||
|
||||
this._updateUserSwitchVisibility();
|
||||
|
||||
// Main Box
|
||||
let mainBox = new St.Widget();
|
||||
@ -618,6 +629,7 @@ var UnlockDialog = GObject.registerClass({
|
||||
y: monitor.y,
|
||||
width: monitor.width,
|
||||
height: monitor.height,
|
||||
effect: new Shell.BlurEffect({ name: 'blur' }),
|
||||
});
|
||||
|
||||
let bgManager = new Background.BackgroundManager({
|
||||
@ -629,19 +641,17 @@ var UnlockDialog = GObject.registerClass({
|
||||
this._bgManagers.push(bgManager);
|
||||
|
||||
this._backgroundGroup.add_child(widget);
|
||||
}
|
||||
|
||||
_updateBackgroundEffects() {
|
||||
const themeContext = St.ThemeContext.get_for_stage(global.stage);
|
||||
|
||||
let effect = new Shell.BlurEffect({
|
||||
brightness: BLUR_BRIGHTNESS,
|
||||
sigma: BLUR_SIGMA * themeContext.scale_factor,
|
||||
});
|
||||
|
||||
this._scaleChangedId = themeContext.connect('notify::scale-factor', () => {
|
||||
effect.sigma = BLUR_SIGMA * themeContext.scale_factor;
|
||||
});
|
||||
|
||||
widget.add_effect(effect);
|
||||
for (const widget of this._backgroundGroup) {
|
||||
widget.get_effect('blur').set({
|
||||
brightness: BLUR_BRIGHTNESS,
|
||||
sigma: BLUR_SIGMA * themeContext.scale_factor,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
_updateBackgrounds() {
|
||||
@ -653,6 +663,7 @@ var UnlockDialog = GObject.registerClass({
|
||||
|
||||
for (let i = 0; i < Main.layoutManager.monitors.length; i++)
|
||||
this._createBackground(i);
|
||||
this._updateBackgroundEffects();
|
||||
}
|
||||
|
||||
_ensureAuthPrompt() {
|
||||
@ -828,6 +839,21 @@ var UnlockDialog = GObject.registerClass({
|
||||
this._gdmClient = null;
|
||||
delete this._gdmClient;
|
||||
}
|
||||
|
||||
if (this._userLoadedId) {
|
||||
this._user.disconnect(this._userLoadedId);
|
||||
this._userLoadedId = 0;
|
||||
}
|
||||
|
||||
if (this._userSwitchEnabledId) {
|
||||
this._screenSaverSettings.disconnect(this._userSwitchEnabledId);
|
||||
this._userSwitchEnabledId = 0;
|
||||
}
|
||||
}
|
||||
|
||||
_updateUserSwitchVisibility() {
|
||||
this._otherUserButton.visible = this._userManager.can_switch() &&
|
||||
this._screenSaverSettings.get_boolean('user-switch-enabled');
|
||||
}
|
||||
|
||||
cancel() {
|
||||
|
@ -132,6 +132,7 @@ var ViewSelector = GObject.registerClass({
|
||||
super._init({
|
||||
name: 'viewSelector',
|
||||
x_expand: true,
|
||||
visible: false,
|
||||
});
|
||||
|
||||
this._showAppsButton = showAppsButton;
|
||||
@ -271,9 +272,10 @@ var ViewSelector = GObject.registerClass({
|
||||
Main.overview.show();
|
||||
}
|
||||
|
||||
show() {
|
||||
animateToOverview() {
|
||||
this.show();
|
||||
this.reset();
|
||||
this._workspacesDisplay.show(this._showAppsButton.checked);
|
||||
this._workspacesDisplay.animateToOverview(this._showAppsButton.checked);
|
||||
this._activePage = null;
|
||||
if (this._showAppsButton.checked)
|
||||
this._showPage(this._appsPage);
|
||||
@ -297,13 +299,11 @@ var ViewSelector = GObject.registerClass({
|
||||
Main.overview.fadeInDesktop();
|
||||
}
|
||||
|
||||
setWorkspacesFullGeometry(geom) {
|
||||
this._workspacesDisplay.setWorkspacesFullGeometry(geom);
|
||||
}
|
||||
|
||||
hide() {
|
||||
vfunc_hide() {
|
||||
this.reset();
|
||||
this._workspacesDisplay.hide();
|
||||
|
||||
super.vfunc_hide();
|
||||
}
|
||||
|
||||
_addPage(actor, name, a11yIcon, params) {
|
||||
|
@ -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));
|
||||
@ -1278,13 +1290,13 @@ var WindowManager = class {
|
||||
}
|
||||
|
||||
_sizeChangeWindow(shellwm, actor, whichChange, oldFrameRect, _oldBufferRect) {
|
||||
let types = [Meta.WindowType.NORMAL];
|
||||
if (!this._shouldAnimateActor(actor, types)) {
|
||||
shellwm.completed_size_change(actor);
|
||||
return;
|
||||
}
|
||||
const types = [Meta.WindowType.NORMAL];
|
||||
const shouldAnimate =
|
||||
this._shouldAnimateActor(actor, types) &&
|
||||
oldFrameRect.width > 0 &&
|
||||
oldFrameRect.height > 0;
|
||||
|
||||
if (oldFrameRect.width > 0 && oldFrameRect.height > 0)
|
||||
if (shouldAnimate)
|
||||
this._prepareAnimationInfo(shellwm, actor, oldFrameRect, whichChange);
|
||||
else
|
||||
shellwm.completed_size_change(actor);
|
||||
@ -1299,17 +1311,24 @@ var WindowManager = class {
|
||||
actorClone.set_position(oldFrameRect.x, oldFrameRect.y);
|
||||
actorClone.set_size(oldFrameRect.width, oldFrameRect.height);
|
||||
|
||||
if (this._clearAnimationInfo(actor))
|
||||
actor.freeze();
|
||||
|
||||
if (this._clearAnimationInfo(actor)) {
|
||||
log('Old animationInfo removed from actor %s'.format(actor));
|
||||
this._shellwm.completed_size_change(actor);
|
||||
}
|
||||
|
||||
let destroyId = actor.connect('destroy', () => {
|
||||
this._clearAnimationInfo(actor);
|
||||
});
|
||||
|
||||
this._resizePending.add(actor);
|
||||
actor.__animationInfo = { clone: actorClone,
|
||||
oldRect: oldFrameRect,
|
||||
destroyId };
|
||||
actor.__animationInfo = {
|
||||
clone: actorClone,
|
||||
oldRect: oldFrameRect,
|
||||
frozen: true,
|
||||
destroyId,
|
||||
};
|
||||
}
|
||||
|
||||
_sizeChangedWindow(shellwm, actor) {
|
||||
@ -1362,13 +1381,17 @@ var WindowManager = class {
|
||||
// Now unfreeze actor updates, to get it to the new size.
|
||||
// It's important that we don't wait until the animation is completed to
|
||||
// do this, otherwise our scale will be applied to the old texture size.
|
||||
shellwm.completed_size_change(actor);
|
||||
actor.thaw();
|
||||
actor.__animationInfo.frozen = false;
|
||||
}
|
||||
|
||||
_clearAnimationInfo(actor) {
|
||||
if (actor.__animationInfo) {
|
||||
actor.__animationInfo.clone.destroy();
|
||||
actor.disconnect(actor.__animationInfo.destroyId);
|
||||
if (actor.__animationInfo.frozen)
|
||||
actor.thaw();
|
||||
|
||||
delete actor.__animationInfo;
|
||||
return true;
|
||||
}
|
||||
@ -1383,10 +1406,13 @@ var WindowManager = class {
|
||||
actor.translation_x = 0;
|
||||
actor.translation_y = 0;
|
||||
this._clearAnimationInfo(actor);
|
||||
this._shellwm.completed_size_change(actor);
|
||||
}
|
||||
|
||||
if (this._resizePending.delete(actor))
|
||||
if (this._resizePending.delete(actor)) {
|
||||
this._clearAnimationInfo(actor);
|
||||
this._shellwm.completed_size_change(actor);
|
||||
}
|
||||
}
|
||||
|
||||
_hasAttachedDialogs(window, ignoreWindow) {
|
||||
@ -1786,8 +1812,7 @@ var WindowManager = class {
|
||||
w.window.get_parent().remove_child(w.window);
|
||||
w.parent.add_child(w.window);
|
||||
|
||||
if (w.window.get_meta_window().get_workspace() !=
|
||||
global.workspace_manager.get_active_workspace())
|
||||
if (!w.window.get_meta_window().get_workspace().active)
|
||||
w.window.hide();
|
||||
}
|
||||
switchData.container.destroy();
|
||||
@ -1971,7 +1996,7 @@ var WindowManager = class {
|
||||
duration,
|
||||
mode: Clutter.AnimationMode.EASE_OUT_CUBIC,
|
||||
onComplete: () => {
|
||||
if (newWs !== activeWorkspace)
|
||||
if (!newWs.active)
|
||||
this.actionMoveWorkspace(newWs);
|
||||
this._finishWorkspaceSwitch(switchData);
|
||||
},
|
||||
@ -2101,8 +2126,16 @@ var WindowManager = class {
|
||||
newWs = workspaceManager.get_workspace_by_index(workspaceManager.n_workspaces - 1);
|
||||
} else if (isNaN(target)) {
|
||||
// Prepend a new workspace dynamically
|
||||
if (workspaceManager.get_active_workspace_index() == 0 &&
|
||||
action == 'move' && target == 'up' && this._isWorkspacePrepended == false) {
|
||||
let prependTarget;
|
||||
if (vertical)
|
||||
prependTarget = 'up';
|
||||
else if (rtl)
|
||||
prependTarget = 'right';
|
||||
else
|
||||
prependTarget = 'left';
|
||||
if (workspaceManager.get_active_workspace_index() === 0 &&
|
||||
action === 'move' && target === prependTarget &&
|
||||
this._isWorkspacePrepended === false) {
|
||||
this.insertWorkspace(0);
|
||||
this._isWorkspacePrepended = true;
|
||||
}
|
||||
@ -2163,10 +2196,7 @@ var WindowManager = class {
|
||||
if (!Main.sessionMode.hasWorkspaces)
|
||||
return;
|
||||
|
||||
let workspaceManager = global.workspace_manager;
|
||||
let activeWorkspace = workspaceManager.get_active_workspace();
|
||||
|
||||
if (activeWorkspace != workspace)
|
||||
if (!workspace.active)
|
||||
workspace.activate(global.get_current_time());
|
||||
}
|
||||
|
||||
@ -2174,10 +2204,7 @@ var WindowManager = class {
|
||||
if (!Main.sessionMode.hasWorkspaces)
|
||||
return;
|
||||
|
||||
let workspaceManager = global.workspace_manager;
|
||||
let activeWorkspace = workspaceManager.get_active_workspace();
|
||||
|
||||
if (activeWorkspace != workspace) {
|
||||
if (!workspace.active) {
|
||||
// This won't have any effect for "always sticky" windows
|
||||
// (like desktop windows or docks)
|
||||
|
||||
|
771
js/ui/windowPreview.js
Normal file
771
js/ui/windowPreview.js
Normal file
@ -0,0 +1,771 @@
|
||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported WindowPreview */
|
||||
|
||||
const { Atk, Clutter, GLib, GObject,
|
||||
Graphene, Meta, Pango, Shell, St } = imports.gi;
|
||||
|
||||
const DND = imports.ui.dnd;
|
||||
|
||||
var WINDOW_DND_SIZE = 256;
|
||||
|
||||
var WINDOW_OVERLAY_IDLE_HIDE_TIMEOUT = 750;
|
||||
var WINDOW_OVERLAY_FADE_TIME = 200;
|
||||
|
||||
var DRAGGING_WINDOW_OPACITY = 100;
|
||||
|
||||
var WindowPreviewLayout = GObject.registerClass({
|
||||
Properties: {
|
||||
'bounding-box': GObject.ParamSpec.boxed(
|
||||
'bounding-box', 'Bounding box', 'Bounding box',
|
||||
GObject.ParamFlags.READABLE,
|
||||
Clutter.ActorBox.$gtype),
|
||||
},
|
||||
}, class WindowPreviewLayout extends Clutter.LayoutManager {
|
||||
_init() {
|
||||
super._init();
|
||||
|
||||
this._container = null;
|
||||
this._boundingBox = new Clutter.ActorBox();
|
||||
this._windows = new Map();
|
||||
}
|
||||
|
||||
_layoutChanged() {
|
||||
let frameRect;
|
||||
|
||||
for (const windowInfo of this._windows.values()) {
|
||||
const frame = windowInfo.metaWindow.get_frame_rect();
|
||||
frameRect = frameRect ? frameRect.union(frame) : frame;
|
||||
}
|
||||
|
||||
if (!frameRect)
|
||||
frameRect = new Meta.Rectangle();
|
||||
|
||||
const oldBox = this._boundingBox.copy();
|
||||
this._boundingBox.set_origin(frameRect.x, frameRect.y);
|
||||
this._boundingBox.set_size(frameRect.width, frameRect.height);
|
||||
|
||||
if (!this._boundingBox.equal(oldBox))
|
||||
this.notify('bounding-box');
|
||||
|
||||
// Always call layout_changed(), a size or position change of an
|
||||
// attached dialog might not affect the boundingBox
|
||||
this.layout_changed();
|
||||
}
|
||||
|
||||
vfunc_set_container(container) {
|
||||
this._container = container;
|
||||
}
|
||||
|
||||
vfunc_get_preferred_height(_container, _forWidth) {
|
||||
return [0, this._boundingBox.get_height()];
|
||||
}
|
||||
|
||||
vfunc_get_preferred_width(_container, _forHeight) {
|
||||
return [0, this._boundingBox.get_width()];
|
||||
}
|
||||
|
||||
vfunc_allocate(container, box) {
|
||||
// If the scale isn't 1, we weren't allocated our preferred size
|
||||
// and have to scale the children allocations accordingly.
|
||||
const scaleX = this._boundingBox.get_width() > 0
|
||||
? box.get_width() / this._boundingBox.get_width()
|
||||
: 1;
|
||||
const scaleY = this._boundingBox.get_height() > 0
|
||||
? box.get_height() / this._boundingBox.get_height()
|
||||
: 1;
|
||||
|
||||
const childBox = new Clutter.ActorBox();
|
||||
|
||||
for (const child of container) {
|
||||
if (!child.visible)
|
||||
continue;
|
||||
|
||||
const windowInfo = this._windows.get(child);
|
||||
if (windowInfo) {
|
||||
const bufferRect = windowInfo.metaWindow.get_buffer_rect();
|
||||
childBox.set_origin(
|
||||
bufferRect.x - this._boundingBox.x1,
|
||||
bufferRect.y - this._boundingBox.y1);
|
||||
|
||||
const [, , natWidth, natHeight] = child.get_preferred_size();
|
||||
childBox.set_size(natWidth, natHeight);
|
||||
|
||||
childBox.x1 *= scaleX;
|
||||
childBox.x2 *= scaleX;
|
||||
childBox.y1 *= scaleY;
|
||||
childBox.y2 *= scaleY;
|
||||
|
||||
child.allocate(childBox);
|
||||
} else {
|
||||
child.allocate_preferred_size(0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* addWindow:
|
||||
* @param {Meta.Window} window: the MetaWindow instance
|
||||
*
|
||||
* Creates a ClutterActor drawing the texture of @window and adds it
|
||||
* to the container. If @window is already part of the preview, this
|
||||
* function will do nothing.
|
||||
*
|
||||
* @returns {Clutter.Actor} The newly created actor drawing @window
|
||||
*/
|
||||
addWindow(window) {
|
||||
const index = [...this._windows.values()].findIndex(info =>
|
||||
info.metaWindow === window);
|
||||
|
||||
if (index !== -1)
|
||||
return null;
|
||||
|
||||
const windowActor = window.get_compositor_private();
|
||||
const actor = new Clutter.Clone({ source: windowActor });
|
||||
|
||||
this._windows.set(actor, {
|
||||
metaWindow: window,
|
||||
windowActor,
|
||||
sizeChangedId: window.connect('size-changed', () =>
|
||||
this._layoutChanged()),
|
||||
positionChangedId: window.connect('position-changed', () =>
|
||||
this._layoutChanged()),
|
||||
windowActorDestroyId: windowActor.connect('destroy', () =>
|
||||
actor.destroy()),
|
||||
destroyId: actor.connect('destroy', () =>
|
||||
this.removeWindow(window)),
|
||||
});
|
||||
|
||||
this._container.add_child(actor);
|
||||
|
||||
this._layoutChanged();
|
||||
|
||||
return actor;
|
||||
}
|
||||
|
||||
/**
|
||||
* removeWindow:
|
||||
* @param {Meta.Window} window: the window to remove from the preview
|
||||
*
|
||||
* Removes a MetaWindow @window from the preview which has been added
|
||||
* previously using addWindow(). If @window is not part of preview,
|
||||
* this function will do nothing.
|
||||
*/
|
||||
removeWindow(window) {
|
||||
const entry = [...this._windows].find(
|
||||
([, i]) => i.metaWindow === window);
|
||||
|
||||
if (!entry)
|
||||
return;
|
||||
|
||||
const [actor, windowInfo] = entry;
|
||||
|
||||
windowInfo.metaWindow.disconnect(windowInfo.sizeChangedId);
|
||||
windowInfo.metaWindow.disconnect(windowInfo.positionChangedId);
|
||||
windowInfo.windowActor.disconnect(windowInfo.windowActorDestroyId);
|
||||
actor.disconnect(windowInfo.destroyId);
|
||||
|
||||
this._windows.delete(actor);
|
||||
this._container.remove_child(actor);
|
||||
|
||||
this._layoutChanged();
|
||||
}
|
||||
|
||||
/**
|
||||
* getWindows:
|
||||
*
|
||||
* Gets an array of all MetaWindows that were added to the layout
|
||||
* using addWindow(), ordered by the insertion order.
|
||||
*
|
||||
* @returns {Array} An array including all windows
|
||||
*/
|
||||
getWindows() {
|
||||
return [...this._windows.values()].map(i => i.metaWindow);
|
||||
}
|
||||
|
||||
// eslint-disable-next-line camelcase
|
||||
get bounding_box() {
|
||||
return this._boundingBox;
|
||||
}
|
||||
});
|
||||
|
||||
var WindowPreview = GObject.registerClass({
|
||||
Properties: {
|
||||
'overlay-enabled': GObject.ParamSpec.boolean(
|
||||
'overlay-enabled', 'overlay-enabled', 'overlay-enabled',
|
||||
GObject.ParamFlags.READWRITE,
|
||||
true),
|
||||
},
|
||||
Signals: {
|
||||
'drag-begin': {},
|
||||
'drag-cancelled': {},
|
||||
'drag-end': {},
|
||||
'selected': { param_types: [GObject.TYPE_UINT] },
|
||||
'show-chrome': {},
|
||||
'size-changed': {},
|
||||
},
|
||||
}, class WindowPreview extends St.Widget {
|
||||
_init(metaWindow, workspace) {
|
||||
this.metaWindow = metaWindow;
|
||||
this.metaWindow._delegate = this;
|
||||
this._windowActor = metaWindow.get_compositor_private();
|
||||
this._workspace = workspace;
|
||||
|
||||
super._init({
|
||||
reactive: true,
|
||||
can_focus: true,
|
||||
accessible_role: Atk.Role.PUSH_BUTTON,
|
||||
offscreen_redirect: Clutter.OffscreenRedirect.AUTOMATIC_FOR_OPACITY,
|
||||
});
|
||||
|
||||
this._windowContainer = new Clutter.Actor();
|
||||
// gjs currently can't handle setting an actors layout manager during
|
||||
// the initialization of the actor if that layout manager keeps track
|
||||
// of its container, so set the layout manager after creating the
|
||||
// container
|
||||
this._windowContainer.layout_manager = new WindowPreviewLayout();
|
||||
this.add_child(this._windowContainer);
|
||||
|
||||
this._addWindow(metaWindow);
|
||||
|
||||
this._delegate = this;
|
||||
|
||||
this._stackAbove = null;
|
||||
|
||||
this._windowContainer.layout_manager.connect(
|
||||
'notify::bounding-box', layout => {
|
||||
// A bounding box of 0x0 means all windows were removed
|
||||
if (layout.bounding_box.get_area() > 0)
|
||||
this.emit('size-changed');
|
||||
});
|
||||
|
||||
this._windowDestroyId =
|
||||
this._windowActor.connect('destroy', () => this.destroy());
|
||||
|
||||
this._updateAttachedDialogs();
|
||||
|
||||
let clickAction = new Clutter.ClickAction();
|
||||
clickAction.connect('clicked', () => this._activate());
|
||||
clickAction.connect('long-press', this._onLongPress.bind(this));
|
||||
this.add_action(clickAction);
|
||||
this.connect('destroy', this._onDestroy.bind(this));
|
||||
|
||||
this._draggable = DND.makeDraggable(this,
|
||||
{ restoreOnSuccess: true,
|
||||
manualMode: true,
|
||||
dragActorMaxSize: WINDOW_DND_SIZE,
|
||||
dragActorOpacity: DRAGGING_WINDOW_OPACITY });
|
||||
this._draggable.connect('drag-begin', this._onDragBegin.bind(this));
|
||||
this._draggable.connect('drag-cancelled', this._onDragCancelled.bind(this));
|
||||
this._draggable.connect('drag-end', this._onDragEnd.bind(this));
|
||||
this.inDrag = false;
|
||||
|
||||
this._selected = false;
|
||||
this._overlayEnabled = true;
|
||||
this._closeRequested = false;
|
||||
this._idleHideOverlayId = 0;
|
||||
|
||||
this._border = new St.Widget({
|
||||
visible: false,
|
||||
style_class: 'window-clone-border',
|
||||
});
|
||||
this._borderConstraint = new Clutter.BindConstraint({
|
||||
source: this._windowContainer,
|
||||
coordinate: Clutter.BindCoordinate.SIZE,
|
||||
});
|
||||
this._border.add_constraint(this._borderConstraint);
|
||||
this._border.add_constraint(new Clutter.AlignConstraint({
|
||||
source: this._windowContainer,
|
||||
align_axis: Clutter.AlignAxis.BOTH,
|
||||
factor: 0.5,
|
||||
}));
|
||||
this._borderCenter = new Clutter.Actor();
|
||||
this._border.bind_property('visible', this._borderCenter, 'visible',
|
||||
GObject.BindingFlags.SYNC_CREATE);
|
||||
this._borderCenterConstraint = new Clutter.BindConstraint({
|
||||
source: this._windowContainer,
|
||||
coordinate: Clutter.BindCoordinate.SIZE,
|
||||
});
|
||||
this._borderCenter.add_constraint(this._borderCenterConstraint);
|
||||
this._borderCenter.add_constraint(new Clutter.AlignConstraint({
|
||||
source: this._windowContainer,
|
||||
align_axis: Clutter.AlignAxis.BOTH,
|
||||
factor: 0.5,
|
||||
}));
|
||||
this._border.connect('style-changed',
|
||||
this._onBorderStyleChanged.bind(this));
|
||||
|
||||
this._title = new St.Label({
|
||||
visible: false,
|
||||
style_class: 'window-caption',
|
||||
text: this._getCaption(),
|
||||
reactive: true,
|
||||
});
|
||||
this._title.add_constraint(new Clutter.BindConstraint({
|
||||
source: this._borderCenter,
|
||||
coordinate: Clutter.BindCoordinate.POSITION,
|
||||
}));
|
||||
this._title.add_constraint(new Clutter.AlignConstraint({
|
||||
source: this._borderCenter,
|
||||
align_axis: Clutter.AlignAxis.X_AXIS,
|
||||
factor: 0.5,
|
||||
}));
|
||||
this._title.add_constraint(new Clutter.AlignConstraint({
|
||||
source: this._borderCenter,
|
||||
align_axis: Clutter.AlignAxis.Y_AXIS,
|
||||
pivot_point: new Graphene.Point({ x: -1, y: 0.5 }),
|
||||
factor: 1,
|
||||
}));
|
||||
this._title.clutter_text.ellipsize = Pango.EllipsizeMode.END;
|
||||
this.label_actor = this._title;
|
||||
this._updateCaptionId = this.metaWindow.connect('notify::title', () => {
|
||||
this._title.text = this._getCaption();
|
||||
});
|
||||
|
||||
const layout = Meta.prefs_get_button_layout();
|
||||
this._closeButtonSide =
|
||||
layout.left_buttons.includes(Meta.ButtonFunction.CLOSE)
|
||||
? St.Side.LEFT : St.Side.RIGHT;
|
||||
|
||||
this._closeButton = new St.Button({
|
||||
visible: false,
|
||||
style_class: 'window-close',
|
||||
child: new St.Icon({ icon_name: 'window-close-symbolic' }),
|
||||
});
|
||||
this._closeButton.add_constraint(new Clutter.BindConstraint({
|
||||
source: this._borderCenter,
|
||||
coordinate: Clutter.BindCoordinate.POSITION,
|
||||
}));
|
||||
this._closeButton.add_constraint(new Clutter.AlignConstraint({
|
||||
source: this._borderCenter,
|
||||
align_axis: Clutter.AlignAxis.X_AXIS,
|
||||
pivot_point: new Graphene.Point({ x: 0.5, y: -1 }),
|
||||
factor: this._closeButtonSide === St.Side.LEFT ? 0 : 1,
|
||||
}));
|
||||
this._closeButton.add_constraint(new Clutter.AlignConstraint({
|
||||
source: this._borderCenter,
|
||||
align_axis: Clutter.AlignAxis.Y_AXIS,
|
||||
pivot_point: new Graphene.Point({ x: -1, y: 0.5 }),
|
||||
factor: 0,
|
||||
}));
|
||||
this._closeButton.connect('clicked', () => this._deleteAll());
|
||||
|
||||
this.add_child(this._borderCenter);
|
||||
this.add_child(this._border);
|
||||
this.add_child(this._title);
|
||||
this.add_child(this._closeButton);
|
||||
|
||||
this.connect('notify::realized', () => {
|
||||
if (!this.realized)
|
||||
return;
|
||||
|
||||
this._border.ensure_style();
|
||||
this._title.ensure_style();
|
||||
});
|
||||
}
|
||||
|
||||
vfunc_get_preferred_width(forHeight) {
|
||||
const themeNode = this.get_theme_node();
|
||||
|
||||
// Only include window previews in size request, not chrome
|
||||
const [minWidth, natWidth] =
|
||||
this._windowContainer.get_preferred_width(
|
||||
themeNode.adjust_for_height(forHeight));
|
||||
|
||||
return themeNode.adjust_preferred_width(minWidth, natWidth);
|
||||
}
|
||||
|
||||
vfunc_get_preferred_height(forWidth) {
|
||||
const themeNode = this.get_theme_node();
|
||||
const [minHeight, natHeight] =
|
||||
this._windowContainer.get_preferred_height(
|
||||
themeNode.adjust_for_width(forWidth));
|
||||
|
||||
return themeNode.adjust_preferred_height(minHeight, natHeight);
|
||||
}
|
||||
|
||||
vfunc_allocate(box) {
|
||||
this.set_allocation(box);
|
||||
|
||||
for (const child of this)
|
||||
child.allocate_available_size(0, 0, box.get_width(), box.get_height());
|
||||
}
|
||||
|
||||
_onBorderStyleChanged() {
|
||||
let borderNode = this._border.get_theme_node();
|
||||
this._borderSize = borderNode.get_border_width(St.Side.TOP);
|
||||
|
||||
// Increase the size of the border actor so the border outlines
|
||||
// the bounding box
|
||||
this._borderConstraint.offset = this._borderSize * 2;
|
||||
this._borderCenterConstraint.offset = this._borderSize;
|
||||
}
|
||||
|
||||
_windowCanClose() {
|
||||
return this.metaWindow.can_close() &&
|
||||
!this._hasAttachedDialogs();
|
||||
}
|
||||
|
||||
_getCaption() {
|
||||
if (this.metaWindow.title)
|
||||
return this.metaWindow.title;
|
||||
|
||||
let tracker = Shell.WindowTracker.get_default();
|
||||
let app = tracker.get_window_app(this.metaWindow);
|
||||
return app.get_name();
|
||||
}
|
||||
|
||||
chromeHeights() {
|
||||
const [, closeButtonHeight] = this._closeButton.get_preferred_height(-1);
|
||||
const [, titleHeight] = this._title.get_preferred_height(-1);
|
||||
|
||||
const topOversize = (this._borderSize / 2) + (closeButtonHeight / 2);
|
||||
const bottomOversize = Math.max(
|
||||
this._borderSize,
|
||||
(titleHeight / 2) + (this._borderSize / 2));
|
||||
|
||||
return [topOversize, bottomOversize];
|
||||
}
|
||||
|
||||
chromeWidths() {
|
||||
const [, closeButtonWidth] = this._closeButton.get_preferred_width(-1);
|
||||
|
||||
const leftOversize = this._closeButtonSide === St.Side.LEFT
|
||||
? (this._borderSize / 2) + (closeButtonWidth / 2)
|
||||
: this._borderSize;
|
||||
const rightOversize = this._closeButtonSide === St.Side.LEFT
|
||||
? this._borderSize
|
||||
: (this._borderSize / 2) + (closeButtonWidth / 2);
|
||||
|
||||
return [leftOversize, rightOversize];
|
||||
}
|
||||
|
||||
showOverlay(animate) {
|
||||
if (!this._overlayEnabled)
|
||||
return;
|
||||
|
||||
const ongoingTransition = this._border.get_transition('opacity');
|
||||
|
||||
// Don't do anything if we're fully visible already
|
||||
if (this._border.visible && !ongoingTransition)
|
||||
return;
|
||||
|
||||
// If we're supposed to animate and an animation in our direction
|
||||
// is already happening, let that one continue
|
||||
if (animate &&
|
||||
ongoingTransition &&
|
||||
ongoingTransition.get_interval().peek_final_value() === 255)
|
||||
return;
|
||||
|
||||
const toShow = this._windowCanClose()
|
||||
? [this._border, this._title, this._closeButton]
|
||||
: [this._border, this._title];
|
||||
|
||||
toShow.forEach(a => {
|
||||
a.opacity = 0;
|
||||
a.show();
|
||||
a.ease({
|
||||
opacity: 255,
|
||||
duration: animate ? WINDOW_OVERLAY_FADE_TIME : 0,
|
||||
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
|
||||
});
|
||||
});
|
||||
|
||||
this.emit('show-chrome');
|
||||
}
|
||||
|
||||
hideOverlay(animate) {
|
||||
const ongoingTransition = this._border.get_transition('opacity');
|
||||
|
||||
// Don't do anything if we're fully hidden already
|
||||
if (!this._border.visible && !ongoingTransition)
|
||||
return;
|
||||
|
||||
// If we're supposed to animate and an animation in our direction
|
||||
// is already happening, let that one continue
|
||||
if (animate &&
|
||||
ongoingTransition &&
|
||||
ongoingTransition.get_interval().peek_final_value() === 0)
|
||||
return;
|
||||
|
||||
[this._border, this._title, this._closeButton].forEach(a => {
|
||||
a.opacity = 255;
|
||||
a.ease({
|
||||
opacity: 0,
|
||||
duration: animate ? WINDOW_OVERLAY_FADE_TIME : 0,
|
||||
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
|
||||
onComplete: () => a.hide(),
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
_addWindow(metaWindow) {
|
||||
const clone = this._windowContainer.layout_manager.addWindow(metaWindow);
|
||||
|
||||
// We expect this to be used for all interaction rather than
|
||||
// the ClutterClone; as the former is reactive and the latter
|
||||
// is not, this just works for most cases. However, for DND all
|
||||
// actors are picked, so DND operations would operate on the clone.
|
||||
// To avoid this, we hide it from pick.
|
||||
Shell.util_set_hidden_from_pick(clone, true);
|
||||
}
|
||||
|
||||
vfunc_has_overlaps() {
|
||||
return this._hasAttachedDialogs();
|
||||
}
|
||||
|
||||
_deleteAll() {
|
||||
const windows = this._windowContainer.layout_manager.getWindows();
|
||||
|
||||
// Delete all windows, starting from the bottom-most (most-modal) one
|
||||
for (const window of windows.reverse())
|
||||
window.delete(global.get_current_time());
|
||||
|
||||
this._closeRequested = true;
|
||||
}
|
||||
|
||||
addDialog(win) {
|
||||
let parent = win.get_transient_for();
|
||||
while (parent.is_attached_dialog())
|
||||
parent = parent.get_transient_for();
|
||||
|
||||
// Display dialog if it is attached to our metaWindow
|
||||
if (win.is_attached_dialog() && parent == this.metaWindow)
|
||||
this._addWindow(win);
|
||||
|
||||
// The dialog popped up after the user tried to close the window,
|
||||
// assume it's a close confirmation and leave the overview
|
||||
if (this._closeRequested)
|
||||
this._activate();
|
||||
}
|
||||
|
||||
_hasAttachedDialogs() {
|
||||
return this._windowContainer.layout_manager.getWindows().length > 1;
|
||||
}
|
||||
|
||||
_updateAttachedDialogs() {
|
||||
let iter = win => {
|
||||
let actor = win.get_compositor_private();
|
||||
|
||||
if (!actor)
|
||||
return false;
|
||||
if (!win.is_attached_dialog())
|
||||
return false;
|
||||
|
||||
this._addWindow(win);
|
||||
win.foreach_transient(iter);
|
||||
return true;
|
||||
};
|
||||
this.metaWindow.foreach_transient(iter);
|
||||
}
|
||||
|
||||
get boundingBox() {
|
||||
const box = this._windowContainer.layout_manager.bounding_box;
|
||||
|
||||
return {
|
||||
x: box.x1,
|
||||
y: box.y1,
|
||||
width: box.get_width(),
|
||||
height: box.get_height(),
|
||||
};
|
||||
}
|
||||
|
||||
get windowCenter() {
|
||||
const box = this._windowContainer.layout_manager.bounding_box;
|
||||
|
||||
return new Graphene.Point({
|
||||
x: box.get_x() + box.get_width() / 2,
|
||||
y: box.get_y() + box.get_height() / 2,
|
||||
});
|
||||
}
|
||||
|
||||
// eslint-disable-next-line camelcase
|
||||
get overlay_enabled() {
|
||||
return this._overlayEnabled;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line camelcase
|
||||
set overlay_enabled(enabled) {
|
||||
if (this._overlayEnabled === enabled)
|
||||
return;
|
||||
|
||||
this._overlayEnabled = enabled;
|
||||
this.notify('overlay-enabled');
|
||||
|
||||
if (!enabled)
|
||||
this.hideOverlay(false);
|
||||
else if (this['has-pointer'] || global.stage.key_focus === this)
|
||||
this.showOverlay(true);
|
||||
}
|
||||
|
||||
// Find the actor just below us, respecting reparenting done by DND code
|
||||
_getActualStackAbove() {
|
||||
if (this._stackAbove == null)
|
||||
return null;
|
||||
|
||||
if (this.inDrag) {
|
||||
if (this._stackAbove._delegate)
|
||||
return this._stackAbove._delegate._getActualStackAbove();
|
||||
else
|
||||
return null;
|
||||
} else {
|
||||
return this._stackAbove;
|
||||
}
|
||||
}
|
||||
|
||||
setStackAbove(actor) {
|
||||
this._stackAbove = actor;
|
||||
if (this.inDrag)
|
||||
// We'll fix up the stack after the drag
|
||||
return;
|
||||
|
||||
let parent = this.get_parent();
|
||||
let actualAbove = this._getActualStackAbove();
|
||||
if (actualAbove == null)
|
||||
parent.set_child_below_sibling(this, null);
|
||||
else
|
||||
parent.set_child_above_sibling(this, actualAbove);
|
||||
}
|
||||
|
||||
_onDestroy() {
|
||||
this._windowActor.disconnect(this._windowDestroyId);
|
||||
|
||||
this.metaWindow._delegate = null;
|
||||
this._delegate = null;
|
||||
|
||||
this.metaWindow.disconnect(this._updateCaptionId);
|
||||
|
||||
if (this._longPressLater) {
|
||||
Meta.later_remove(this._longPressLater);
|
||||
delete this._longPressLater;
|
||||
}
|
||||
|
||||
if (this._idleHideOverlayId > 0) {
|
||||
GLib.source_remove(this._idleHideOverlayId);
|
||||
this._idleHideOverlayId = 0;
|
||||
}
|
||||
|
||||
if (this.inDrag) {
|
||||
this.emit('drag-end');
|
||||
this.inDrag = false;
|
||||
}
|
||||
}
|
||||
|
||||
_activate() {
|
||||
this._selected = true;
|
||||
this.emit('selected', global.get_current_time());
|
||||
}
|
||||
|
||||
vfunc_enter_event(crossingEvent) {
|
||||
this.showOverlay(true);
|
||||
return super.vfunc_enter_event(crossingEvent);
|
||||
}
|
||||
|
||||
vfunc_leave_event(crossingEvent) {
|
||||
if (this._idleHideOverlayId > 0)
|
||||
GLib.source_remove(this._idleHideOverlayId);
|
||||
|
||||
this._idleHideOverlayId = GLib.timeout_add(
|
||||
GLib.PRIORITY_DEFAULT,
|
||||
WINDOW_OVERLAY_IDLE_HIDE_TIMEOUT, () => {
|
||||
if (this._closeButton['has-pointer'] ||
|
||||
this._title['has-pointer'])
|
||||
return GLib.SOURCE_CONTINUE;
|
||||
|
||||
if (!this['has-pointer'])
|
||||
this.hideOverlay(true);
|
||||
|
||||
this._idleHideOverlayId = 0;
|
||||
return GLib.SOURCE_REMOVE;
|
||||
});
|
||||
|
||||
GLib.Source.set_name_by_id(this._idleHideOverlayId, '[gnome-shell] this._idleHideOverlayId');
|
||||
|
||||
return super.vfunc_leave_event(crossingEvent);
|
||||
}
|
||||
|
||||
vfunc_key_focus_in() {
|
||||
super.vfunc_key_focus_in();
|
||||
this.showOverlay(true);
|
||||
}
|
||||
|
||||
vfunc_key_focus_out() {
|
||||
super.vfunc_key_focus_out();
|
||||
this.hideOverlay(true);
|
||||
}
|
||||
|
||||
vfunc_key_press_event(keyEvent) {
|
||||
let symbol = keyEvent.keyval;
|
||||
let isEnter = symbol == Clutter.KEY_Return || symbol == Clutter.KEY_KP_Enter;
|
||||
if (isEnter) {
|
||||
this._activate();
|
||||
return true;
|
||||
}
|
||||
|
||||
return super.vfunc_key_press_event(keyEvent);
|
||||
}
|
||||
|
||||
_onLongPress(action, actor, state) {
|
||||
// Take advantage of the Clutter policy to consider
|
||||
// a long-press canceled when the pointer movement
|
||||
// exceeds dnd-drag-threshold to manually start the drag
|
||||
if (state == Clutter.LongPressState.CANCEL) {
|
||||
let event = Clutter.get_current_event();
|
||||
this._dragTouchSequence = event.get_event_sequence();
|
||||
|
||||
if (this._longPressLater)
|
||||
return true;
|
||||
|
||||
// A click cancels a long-press before any click handler is
|
||||
// run - make sure to not start a drag in that case
|
||||
this._longPressLater = Meta.later_add(Meta.LaterType.BEFORE_REDRAW, () => {
|
||||
delete this._longPressLater;
|
||||
if (this._selected)
|
||||
return;
|
||||
let [x, y] = action.get_coords();
|
||||
action.release();
|
||||
this._draggable.startDrag(x, y, global.get_current_time(), this._dragTouchSequence, event.get_device());
|
||||
});
|
||||
} else {
|
||||
this.showOverlay(true);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
_onDragBegin(_draggable, _time) {
|
||||
this.inDrag = true;
|
||||
this.hideOverlay(false);
|
||||
this.emit('drag-begin');
|
||||
}
|
||||
|
||||
handleDragOver(source, actor, x, y, time) {
|
||||
return this._workspace.handleDragOver(source, actor, x, y, time);
|
||||
}
|
||||
|
||||
acceptDrop(source, actor, x, y, time) {
|
||||
return this._workspace.acceptDrop(source, actor, x, y, time);
|
||||
}
|
||||
|
||||
_onDragCancelled(_draggable, _time) {
|
||||
this.emit('drag-cancelled');
|
||||
}
|
||||
|
||||
_onDragEnd(_draggable, _time, _snapback) {
|
||||
this.inDrag = false;
|
||||
|
||||
// We may not have a parent if DnD completed successfully, in
|
||||
// which case our clone will shortly be destroyed and replaced
|
||||
// with a new one on the target workspace.
|
||||
let parent = this.get_parent();
|
||||
if (parent !== null) {
|
||||
if (this._stackAbove == null)
|
||||
parent.set_child_below_sibling(this, null);
|
||||
else
|
||||
parent.set_child_above_sibling(this, this._stackAbove);
|
||||
}
|
||||
|
||||
if (this['has-pointer'])
|
||||
this.showOverlay(true);
|
||||
|
||||
this.emit('drag-end');
|
||||
}
|
||||
});
|
1919
js/ui/workspace.js
1919
js/ui/workspace.js
File diff suppressed because it is too large
Load Diff
@ -11,7 +11,10 @@ var DISPLAY_TIMEOUT = 600;
|
||||
var WorkspaceSwitcherPopupList = GObject.registerClass(
|
||||
class WorkspaceSwitcherPopupList extends St.Widget {
|
||||
_init() {
|
||||
super._init({ style_class: 'workspace-switcher' });
|
||||
super._init({
|
||||
style_class: 'workspace-switcher',
|
||||
offscreen_redirect: Clutter.OffscreenRedirect.ALWAYS,
|
||||
});
|
||||
|
||||
this._itemSpacing = 0;
|
||||
this._childHeight = 0;
|
||||
|
@ -549,9 +549,7 @@ var WorkspaceThumbnail = GObject.registerClass({
|
||||
return;
|
||||
|
||||
// a click on the already current workspace should go back to the main view
|
||||
let workspaceManager = global.workspace_manager;
|
||||
let activeWorkspace = workspaceManager.get_active_workspace();
|
||||
if (this.metaWorkspace == activeWorkspace)
|
||||
if (this.metaWorkspace.active)
|
||||
Main.overview.hide();
|
||||
else
|
||||
this.metaWorkspace.activate(time);
|
||||
@ -567,7 +565,8 @@ var WorkspaceThumbnail = GObject.registerClass({
|
||||
if (this.state > ThumbnailState.NORMAL)
|
||||
return DND.DragMotionResult.CONTINUE;
|
||||
|
||||
if (source.realWindow && !this._isMyWindow(source.realWindow))
|
||||
if (source.metaWindow &&
|
||||
!this._isMyWindow(source.metaWindow.get_compositor_private()))
|
||||
return DND.DragMotionResult.MOVE_DROP;
|
||||
if (source.app && source.app.can_open_new_window())
|
||||
return DND.DragMotionResult.COPY_DROP;
|
||||
@ -581,8 +580,8 @@ var WorkspaceThumbnail = GObject.registerClass({
|
||||
if (this.state > ThumbnailState.NORMAL)
|
||||
return false;
|
||||
|
||||
if (source.realWindow) {
|
||||
let win = source.realWindow;
|
||||
if (source.metaWindow) {
|
||||
let win = source.metaWindow.get_compositor_private();
|
||||
if (this._isMyWindow(win))
|
||||
return false;
|
||||
|
||||
@ -795,7 +794,7 @@ var ThumbnailsBox = GObject.registerClass({
|
||||
|
||||
// Draggable target interface
|
||||
handleDragOver(source, actor, x, y, time) {
|
||||
if (!source.realWindow &&
|
||||
if (!source.metaWindow &&
|
||||
(!source.app || !source.app.can_open_new_window()) &&
|
||||
(source.app || !source.shellWorkspaceLaunch) &&
|
||||
source != Main.xdndHandler)
|
||||
@ -846,7 +845,7 @@ var ThumbnailsBox = GObject.registerClass({
|
||||
if (this._dropWorkspace != -1)
|
||||
return this._thumbnails[this._dropWorkspace].handleDragOverInternal(source, actor, time);
|
||||
else if (this._dropPlaceholderPos != -1)
|
||||
return source.realWindow ? DND.DragMotionResult.MOVE_DROP : DND.DragMotionResult.COPY_DROP;
|
||||
return source.metaWindow ? DND.DragMotionResult.MOVE_DROP : DND.DragMotionResult.COPY_DROP;
|
||||
else
|
||||
return DND.DragMotionResult.CONTINUE;
|
||||
}
|
||||
@ -855,12 +854,12 @@ var ThumbnailsBox = GObject.registerClass({
|
||||
if (this._dropWorkspace != -1) {
|
||||
return this._thumbnails[this._dropWorkspace].acceptDropInternal(source, actor, time);
|
||||
} else if (this._dropPlaceholderPos != -1) {
|
||||
if (!source.realWindow &&
|
||||
if (!source.metaWindow &&
|
||||
(!source.app || !source.app.can_open_new_window()) &&
|
||||
(source.app || !source.shellWorkspaceLaunch))
|
||||
return false;
|
||||
|
||||
let isWindow = !!source.realWindow;
|
||||
let isWindow = !!source.metaWindow;
|
||||
|
||||
let newWorkspaceIndex;
|
||||
[newWorkspaceIndex, this._dropPlaceholderPos] = [this._dropPlaceholderPos, -1];
|
||||
|
@ -7,6 +7,7 @@ const Main = imports.ui.main;
|
||||
const SwipeTracker = imports.ui.swipeTracker;
|
||||
const Workspace = imports.ui.workspace;
|
||||
|
||||
var { ANIMATION_TIME } = imports.ui.overview;
|
||||
var WORKSPACE_SWITCH_TIME = 250;
|
||||
var SCROLL_TIMEOUT_TIME = 150;
|
||||
|
||||
@ -21,18 +22,18 @@ var WorkspacesViewBase = GObject.registerClass({
|
||||
GTypeFlags: GObject.TypeFlags.ABSTRACT,
|
||||
}, class WorkspacesViewBase extends St.Widget {
|
||||
_init(monitorIndex) {
|
||||
super._init({ style_class: 'workspaces-view', reactive: true });
|
||||
const { x, y, width, height } =
|
||||
Main.layoutManager.getWorkAreaForMonitor(monitorIndex);
|
||||
|
||||
super._init({
|
||||
style_class: 'workspaces-view',
|
||||
x, y, width, height,
|
||||
});
|
||||
this.connect('destroy', this._onDestroy.bind(this));
|
||||
global.focus_manager.add_group(this);
|
||||
|
||||
// The actor itself isn't a drop target, so we don't want to pick on its area
|
||||
this.set_size(0, 0);
|
||||
|
||||
this._monitorIndex = monitorIndex;
|
||||
|
||||
this._fullGeometry = null;
|
||||
this._actualGeometry = null;
|
||||
|
||||
this._inDrag = false;
|
||||
this._windowDragBeginId = Main.overview.connect('window-drag-begin', this._dragBegin.bind(this));
|
||||
this._windowDragEndId = Main.overview.connect('window-drag-end', this._dragEnd.bind(this));
|
||||
@ -51,24 +52,19 @@ var WorkspacesViewBase = GObject.registerClass({
|
||||
}
|
||||
}
|
||||
|
||||
_dragBegin(overview, window) {
|
||||
_dragBegin() {
|
||||
this._inDrag = true;
|
||||
this._setReservedSlot(window);
|
||||
}
|
||||
|
||||
_dragEnd() {
|
||||
this._inDrag = false;
|
||||
this._setReservedSlot(null);
|
||||
}
|
||||
|
||||
setFullGeometry(geom) {
|
||||
this._fullGeometry = geom;
|
||||
this._syncFullGeometry();
|
||||
}
|
||||
vfunc_allocate(box) {
|
||||
this.set_allocation(box);
|
||||
|
||||
setActualGeometry(geom) {
|
||||
this._actualGeometry = geom;
|
||||
this._syncActualGeometry();
|
||||
for (const child of this)
|
||||
child.allocate_available_size(0, 0, box.get_width(), box.get_height());
|
||||
}
|
||||
});
|
||||
|
||||
@ -83,9 +79,8 @@ class WorkspacesView extends WorkspacesViewBase {
|
||||
this._gestureActive = false; // touch(pad) gestures
|
||||
|
||||
this._scrollAdjustment = scrollAdjustment;
|
||||
this._onScrollId =
|
||||
this._scrollAdjustment.connect('notify::value',
|
||||
this._onScroll.bind(this));
|
||||
this._onScrollId = this._scrollAdjustment.connect('notify::value',
|
||||
this._updateScrollPosition.bind(this));
|
||||
|
||||
this._workspaces = [];
|
||||
this._updateWorkspaces();
|
||||
@ -97,34 +92,42 @@ class WorkspacesView extends WorkspacesViewBase {
|
||||
this._workspaces.sort((a, b) => {
|
||||
return a.metaWorkspace.index() - b.metaWorkspace.index();
|
||||
});
|
||||
this._updateWorkspaceActors(false);
|
||||
this._workspaces.forEach(
|
||||
(ws, i) => this.set_child_at_index(ws, i));
|
||||
});
|
||||
|
||||
|
||||
this._overviewShownId =
|
||||
Main.overview.connect('shown', () => {
|
||||
this.set_clip(this._fullGeometry.x, this._fullGeometry.y,
|
||||
this._fullGeometry.width, this._fullGeometry.height);
|
||||
});
|
||||
this._overviewShownId = Main.overview.connect('shown', () => {
|
||||
this.clip_to_allocation = true;
|
||||
});
|
||||
|
||||
this._switchWorkspaceNotifyId =
|
||||
global.window_manager.connect('switch-workspace',
|
||||
this._activeWorkspaceChanged.bind(this));
|
||||
}
|
||||
|
||||
_setReservedSlot(window) {
|
||||
for (let i = 0; i < this._workspaces.length; i++)
|
||||
this._workspaces[i].setReservedSlot(window);
|
||||
}
|
||||
vfunc_allocate(box) {
|
||||
this.set_allocation(box);
|
||||
|
||||
_syncFullGeometry() {
|
||||
for (let i = 0; i < this._workspaces.length; i++)
|
||||
this._workspaces[i].setFullGeometry(this._fullGeometry);
|
||||
}
|
||||
if (this.get_n_children() === 0)
|
||||
return;
|
||||
|
||||
_syncActualGeometry() {
|
||||
for (let i = 0; i < this._workspaces.length; i++)
|
||||
this._workspaces[i].setActualGeometry(this._actualGeometry);
|
||||
const { workspaceManager } = global;
|
||||
const { nWorkspaces } = workspaceManager;
|
||||
|
||||
const vertical = workspaceManager.layout_rows === -1;
|
||||
const rtl = this.text_direction === Clutter.TextDirection.RTL;
|
||||
|
||||
this._workspaces.forEach((child, index) => {
|
||||
if (rtl && !vertical)
|
||||
index = nWorkspaces - index - 1;
|
||||
|
||||
const x = vertical ? 0 : index * this.width;
|
||||
const y = vertical ? index * this.height : 0;
|
||||
|
||||
child.allocate_available_size(x, y, box.get_width(), box.get_height());
|
||||
});
|
||||
|
||||
this._updateScrollPosition();
|
||||
}
|
||||
|
||||
getActiveWorkspace() {
|
||||
@ -140,11 +143,11 @@ class WorkspacesView extends WorkspacesViewBase {
|
||||
else
|
||||
this._workspaces[w].fadeToOverview();
|
||||
}
|
||||
this._updateWorkspaceActors(false);
|
||||
this._updateScrollPosition();
|
||||
}
|
||||
|
||||
animateFromOverview(animationType) {
|
||||
this.remove_clip();
|
||||
this.clip_to_allocation = false;
|
||||
|
||||
for (let w = 0; w < this._workspaces.length; w++) {
|
||||
if (animationType == AnimationType.ZOOM)
|
||||
@ -159,49 +162,22 @@ class WorkspacesView extends WorkspacesViewBase {
|
||||
this._workspaces[i].syncStacking(stackIndices);
|
||||
}
|
||||
|
||||
// Update workspace actors parameters
|
||||
// @showAnimation: iff %true, transition between states
|
||||
_updateWorkspaceActors(showAnimation) {
|
||||
let workspaceManager = global.workspace_manager;
|
||||
let active = workspaceManager.get_active_workspace_index();
|
||||
_scrollToActive() {
|
||||
const { workspaceManager } = global;
|
||||
const active = workspaceManager.get_active_workspace_index();
|
||||
|
||||
this._animating = showAnimation;
|
||||
this._animating = true;
|
||||
this._updateVisibility();
|
||||
|
||||
for (let w = 0; w < this._workspaces.length; w++) {
|
||||
let workspace = this._workspaces[w];
|
||||
|
||||
workspace.remove_all_transitions();
|
||||
|
||||
let params = {};
|
||||
if (workspaceManager.layout_rows == -1)
|
||||
params.y = (w - active) * this._fullGeometry.height;
|
||||
else if (this.text_direction == Clutter.TextDirection.RTL)
|
||||
params.x = (active - w) * this._fullGeometry.width;
|
||||
else
|
||||
params.x = (w - active) * this._fullGeometry.width;
|
||||
|
||||
if (showAnimation) {
|
||||
let easeParams = Object.assign(params, {
|
||||
duration: WORKSPACE_SWITCH_TIME,
|
||||
mode: Clutter.AnimationMode.EASE_OUT_CUBIC,
|
||||
});
|
||||
// we have to call _updateVisibility() once before the
|
||||
// animation and once afterwards - it does not really
|
||||
// matter which tween we use, so we pick the first one ...
|
||||
if (w == 0) {
|
||||
this._updateVisibility();
|
||||
easeParams.onComplete = () => {
|
||||
this._animating = false;
|
||||
this._updateVisibility();
|
||||
};
|
||||
}
|
||||
workspace.ease(easeParams);
|
||||
} else {
|
||||
workspace.set(params);
|
||||
if (w == 0)
|
||||
this._updateVisibility();
|
||||
}
|
||||
}
|
||||
this._scrollAdjustment.remove_transition('value');
|
||||
this._scrollAdjustment.ease(active, {
|
||||
duration: WORKSPACE_SWITCH_TIME,
|
||||
mode: Clutter.AnimationMode.EASE_OUT_CUBIC,
|
||||
onComplete: () => {
|
||||
this._animating = false;
|
||||
this._updateVisibility();
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
_updateVisibility() {
|
||||
@ -242,19 +218,14 @@ class WorkspacesView extends WorkspacesViewBase {
|
||||
}
|
||||
}
|
||||
|
||||
if (this._fullGeometry) {
|
||||
this._updateWorkspaceActors(false);
|
||||
this._syncFullGeometry();
|
||||
}
|
||||
if (this._actualGeometry)
|
||||
this._syncActualGeometry();
|
||||
this._updateScrollPosition();
|
||||
}
|
||||
|
||||
_activeWorkspaceChanged(_wm, _from, _to, _direction) {
|
||||
if (this._scrolling)
|
||||
return;
|
||||
|
||||
this._updateWorkspaceActors(true);
|
||||
this._scrollToActive();
|
||||
}
|
||||
|
||||
_onDestroy() {
|
||||
@ -270,27 +241,33 @@ class WorkspacesView extends WorkspacesViewBase {
|
||||
|
||||
startTouchGesture() {
|
||||
this._gestureActive = true;
|
||||
|
||||
this._updateVisibility();
|
||||
}
|
||||
|
||||
endTouchGesture() {
|
||||
this._gestureActive = false;
|
||||
|
||||
// Make sure title captions etc are shown as necessary
|
||||
this._updateWorkspaceActors(true);
|
||||
this._scrollToActive();
|
||||
this._updateVisibility();
|
||||
}
|
||||
|
||||
// sync the workspaces' positions to the value of the scroll adjustment
|
||||
// and change the active workspace if appropriate
|
||||
_onScroll(adj) {
|
||||
if (adj.get_transition('value') !== null && !this._gestureActive)
|
||||
_updateScrollPosition() {
|
||||
if (!this.has_allocation())
|
||||
return;
|
||||
|
||||
const adj = this._scrollAdjustment;
|
||||
const allowSwitch =
|
||||
adj.get_transition('value') === null && !this._gestureActive;
|
||||
|
||||
let workspaceManager = global.workspace_manager;
|
||||
let active = workspaceManager.get_active_workspace_index();
|
||||
let current = Math.round(adj.value);
|
||||
|
||||
if (active != current && !this._gestureActive) {
|
||||
if (allowSwitch && active !== current) {
|
||||
if (!this._workspaces[current]) {
|
||||
// The current workspace was destroyed. This could happen
|
||||
// when you are on the last empty workspace, and consolidate
|
||||
@ -307,36 +284,16 @@ class WorkspacesView extends WorkspacesViewBase {
|
||||
if (adj.upper == 1)
|
||||
return;
|
||||
|
||||
let last = this._workspaces.length - 1;
|
||||
const vertical = workspaceManager.layout_rows === -1;
|
||||
const rtl = this.text_direction === Clutter.TextDirection.RTL;
|
||||
const progress = vertical || !rtl
|
||||
? adj.value : adj.upper - adj.value;
|
||||
|
||||
if (workspaceManager.layout_rows == -1) {
|
||||
let firstWorkspaceY = this._workspaces[0].y;
|
||||
let lastWorkspaceY = this._workspaces[last].y;
|
||||
let workspacesHeight = lastWorkspaceY - firstWorkspaceY;
|
||||
|
||||
let currentY = firstWorkspaceY;
|
||||
let newY = -Math.round(adj.value / (adj.upper - 1) * workspacesHeight);
|
||||
|
||||
let dy = newY - currentY;
|
||||
|
||||
for (let i = 0; i < this._workspaces.length; i++) {
|
||||
this._workspaces[i].visible = Math.abs(i - adj.value) <= 1;
|
||||
this._workspaces[i].y += dy;
|
||||
}
|
||||
} else {
|
||||
let firstWorkspaceX = this._workspaces[0].x;
|
||||
let lastWorkspaceX = this._workspaces[last].x;
|
||||
let workspacesWidth = lastWorkspaceX - firstWorkspaceX;
|
||||
|
||||
let currentX = firstWorkspaceX;
|
||||
let newX = -Math.round(adj.value / (adj.upper - 1) * workspacesWidth);
|
||||
|
||||
let dx = newX - currentX;
|
||||
|
||||
for (let i = 0; i < this._workspaces.length; i++) {
|
||||
this._workspaces[i].visible = Math.abs(i - adj.value) <= 1;
|
||||
this._workspaces[i].x += dx;
|
||||
}
|
||||
for (const ws of this._workspaces) {
|
||||
if (vertical)
|
||||
ws.translation_y = -progress * this.height;
|
||||
else
|
||||
ws.translation_x = -progress * this.width;
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -349,18 +306,6 @@ class ExtraWorkspaceView extends WorkspacesViewBase {
|
||||
this.add_actor(this._workspace);
|
||||
}
|
||||
|
||||
_setReservedSlot(window) {
|
||||
this._workspace.setReservedSlot(window);
|
||||
}
|
||||
|
||||
_syncFullGeometry() {
|
||||
this._workspace.setFullGeometry(this._fullGeometry);
|
||||
}
|
||||
|
||||
_syncActualGeometry() {
|
||||
this._workspace.setActualGeometry(this._actualGeometry);
|
||||
}
|
||||
|
||||
getActiveWorkspace() {
|
||||
return this._workspace;
|
||||
}
|
||||
@ -393,7 +338,10 @@ class ExtraWorkspaceView extends WorkspacesViewBase {
|
||||
var WorkspacesDisplay = GObject.registerClass(
|
||||
class WorkspacesDisplay extends St.Widget {
|
||||
_init(scrollAdjustment) {
|
||||
super._init({ clip_to_allocation: true });
|
||||
super._init({
|
||||
visible: false,
|
||||
clip_to_allocation: true,
|
||||
});
|
||||
this.connect('notify::allocation', this._updateWorkspacesActualGeometry.bind(this));
|
||||
|
||||
let workspaceManager = global.workspace_manager;
|
||||
@ -435,6 +383,10 @@ class WorkspacesDisplay extends St.Widget {
|
||||
this._windowDragEndId =
|
||||
Main.overview.connect('window-drag-begin',
|
||||
this._windowDragEnd.bind(this));
|
||||
this._overviewShownId = Main.overview.connect('shown', () => {
|
||||
this._inWindowFade = false;
|
||||
this._syncWorkspacesActualGeometry();
|
||||
});
|
||||
|
||||
this._primaryIndex = Main.layoutManager.primaryIndex;
|
||||
this._workspacesViews = [];
|
||||
@ -449,9 +401,11 @@ class WorkspacesDisplay extends St.Widget {
|
||||
this._scrollEventId = 0;
|
||||
this._keyPressEventId = 0;
|
||||
this._scrollTimeoutId = 0;
|
||||
this._syncActualGeometryLater = 0;
|
||||
|
||||
this._fullGeometry = null;
|
||||
this._actualGeometry = null;
|
||||
this._inWindowDrag = false;
|
||||
this._inWindowFade = false;
|
||||
|
||||
this._gestureActive = false; // touch(pad) gestures
|
||||
this._canScroll = true; // limiting scrolling speed
|
||||
@ -472,6 +426,11 @@ class WorkspacesDisplay extends St.Widget {
|
||||
this._parentSetLater = 0;
|
||||
}
|
||||
|
||||
if (this._syncActualGeometryLater) {
|
||||
Meta.later_remove(this._syncActualGeometryLater);
|
||||
this._syncActualGeometryLater = 0;
|
||||
}
|
||||
|
||||
if (this._scrollTimeoutId !== 0) {
|
||||
GLib.source_remove(this._scrollTimeoutId);
|
||||
this._scrollTimeoutId = 0;
|
||||
@ -481,6 +440,7 @@ class WorkspacesDisplay extends St.Widget {
|
||||
global.workspace_manager.disconnect(this._reorderWorkspacesdId);
|
||||
Main.overview.disconnect(this._windowDragBeginId);
|
||||
Main.overview.disconnect(this._windowDragEndId);
|
||||
Main.overview.disconnect(this._overviewShownId);
|
||||
}
|
||||
|
||||
_windowDragBegin() {
|
||||
@ -504,25 +464,11 @@ class WorkspacesDisplay extends St.Widget {
|
||||
workspaceManager.get_active_workspace_index();
|
||||
}
|
||||
|
||||
_activeWorkspaceChanged(_wm, _from, _to, _direction) {
|
||||
_activeWorkspaceChanged(_wm, _from, to, _direction) {
|
||||
if (this._gestureActive)
|
||||
return;
|
||||
|
||||
this._scrollToActive();
|
||||
}
|
||||
|
||||
_scrollToActive() {
|
||||
let workspaceManager = global.workspace_manager;
|
||||
let active = workspaceManager.get_active_workspace_index();
|
||||
|
||||
this._updateScrollAdjustment(active);
|
||||
}
|
||||
|
||||
_updateScrollAdjustment(index) {
|
||||
if (this._gestureActive)
|
||||
return;
|
||||
|
||||
this._scrollAdjustment.ease(index, {
|
||||
this._scrollAdjustment.ease(to, {
|
||||
mode: Clutter.AnimationMode.EASE_OUT_CUBIC,
|
||||
duration: WORKSPACE_SWITCH_TIME,
|
||||
});
|
||||
@ -560,11 +506,8 @@ class WorkspacesDisplay extends St.Widget {
|
||||
for (let i = 0; i < this._workspacesViews.length; i++)
|
||||
this._workspacesViews[i].startTouchGesture();
|
||||
|
||||
let monitors = Main.layoutManager.monitors;
|
||||
let geometry = monitor === this._primaryIndex
|
||||
? this._fullGeometry : monitors[monitor];
|
||||
let distance = global.workspace_manager.layout_rows === -1
|
||||
? geometry.height : geometry.width;
|
||||
? this.height : this.width;
|
||||
|
||||
let progress = adjustment.value / adjustment.page_size;
|
||||
let points = Array.from(
|
||||
@ -584,14 +527,13 @@ class WorkspacesDisplay extends St.Widget {
|
||||
this._clickAction.release();
|
||||
|
||||
let workspaceManager = global.workspace_manager;
|
||||
let activeWorkspace = workspaceManager.get_active_workspace();
|
||||
let newWs = workspaceManager.get_workspace_by_index(endProgress);
|
||||
|
||||
this._scrollAdjustment.ease(endProgress, {
|
||||
mode: Clutter.AnimationMode.EASE_OUT_CUBIC,
|
||||
duration,
|
||||
onComplete: () => {
|
||||
if (newWs !== activeWorkspace)
|
||||
if (!newWs.active)
|
||||
newWs.activate(global.get_current_time());
|
||||
this._endTouchGesture();
|
||||
},
|
||||
@ -608,8 +550,10 @@ class WorkspacesDisplay extends St.Widget {
|
||||
return this._getPrimaryView().navigate_focus(from, direction, false);
|
||||
}
|
||||
|
||||
show(fadeOnPrimary) {
|
||||
animateToOverview(fadeOnPrimary) {
|
||||
this.show();
|
||||
this._updateWorkspacesViews();
|
||||
|
||||
for (let i = 0; i < this._workspacesViews.length; i++) {
|
||||
let animationType;
|
||||
if (fadeOnPrimary && i == this._primaryIndex)
|
||||
@ -619,6 +563,11 @@ class WorkspacesDisplay extends St.Widget {
|
||||
this._workspacesViews[i].animateToOverview(animationType);
|
||||
}
|
||||
|
||||
this._inWindowFade = fadeOnPrimary;
|
||||
|
||||
if (this._actualGeometry && !fadeOnPrimary)
|
||||
this._syncWorkspacesActualGeometry();
|
||||
|
||||
this._restackedNotifyId =
|
||||
Main.overview.connect('windows-restacked',
|
||||
this._onRestacked.bind(this));
|
||||
@ -638,9 +587,20 @@ class WorkspacesDisplay extends St.Widget {
|
||||
animationType = AnimationType.ZOOM;
|
||||
this._workspacesViews[i].animateFromOverview(animationType);
|
||||
}
|
||||
|
||||
this._inWindowFade = fadeOnPrimary;
|
||||
|
||||
const { primaryIndex } = Main.layoutManager;
|
||||
const { x, y, width, height } =
|
||||
Main.layoutManager.getWorkAreaForMonitor(primaryIndex);
|
||||
this._getPrimaryView().ease({
|
||||
x, y, width, height,
|
||||
duration: fadeOnPrimary ? 0 : ANIMATION_TIME,
|
||||
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
|
||||
});
|
||||
}
|
||||
|
||||
hide() {
|
||||
vfunc_hide() {
|
||||
if (this._restackedNotifyId > 0) {
|
||||
Main.overview.disconnect(this._restackedNotifyId);
|
||||
this._restackedNotifyId = 0;
|
||||
@ -656,6 +616,8 @@ class WorkspacesDisplay extends St.Widget {
|
||||
for (let i = 0; i < this._workspacesViews.length; i++)
|
||||
this._workspacesViews[i].destroy();
|
||||
this._workspacesViews = [];
|
||||
|
||||
super.vfunc_hide();
|
||||
}
|
||||
|
||||
_workspacesOnlyOnPrimaryChanged() {
|
||||
@ -665,6 +627,7 @@ class WorkspacesDisplay extends St.Widget {
|
||||
return;
|
||||
|
||||
this._updateWorkspacesViews();
|
||||
this._syncWorkspacesActualGeometry();
|
||||
}
|
||||
|
||||
_updateWorkspacesViews() {
|
||||
@ -681,17 +644,9 @@ class WorkspacesDisplay extends St.Widget {
|
||||
else
|
||||
view = new WorkspacesView(i, this._scrollAdjustment);
|
||||
|
||||
// HACK: Avoid spurious allocation changes while updating views
|
||||
view.hide();
|
||||
|
||||
this._workspacesViews.push(view);
|
||||
Main.layoutManager.overviewGroup.add_actor(view);
|
||||
}
|
||||
|
||||
this._workspacesViews.forEach(v => v.show());
|
||||
|
||||
this._updateWorkspacesFullGeometry();
|
||||
this._updateWorkspacesActualGeometry();
|
||||
}
|
||||
|
||||
_getMonitorIndexForEvent(event) {
|
||||
@ -738,40 +693,35 @@ class WorkspacesDisplay extends St.Widget {
|
||||
});
|
||||
}
|
||||
|
||||
// This geometry should always be the fullest geometry
|
||||
// the workspaces switcher can ever be allocated, as if
|
||||
// the sliding controls were never slid in at all.
|
||||
setWorkspacesFullGeometry(geom) {
|
||||
this._fullGeometry = geom;
|
||||
this._updateWorkspacesFullGeometry();
|
||||
}
|
||||
|
||||
_updateWorkspacesFullGeometry() {
|
||||
if (!this._workspacesViews.length)
|
||||
return;
|
||||
|
||||
let monitors = Main.layoutManager.monitors;
|
||||
for (let i = 0; i < monitors.length; i++) {
|
||||
let geometry = i == this._primaryIndex ? this._fullGeometry : monitors[i];
|
||||
this._workspacesViews[i].setFullGeometry(geometry);
|
||||
}
|
||||
}
|
||||
|
||||
_updateWorkspacesActualGeometry() {
|
||||
if (!this._workspacesViews.length)
|
||||
const [x, y] = this.get_transformed_position();
|
||||
const width = this.allocation.get_width();
|
||||
const height = this.allocation.get_height();
|
||||
|
||||
this._actualGeometry = { x, y, width, height };
|
||||
|
||||
if (this._syncActualGeometryLater > 0)
|
||||
return;
|
||||
|
||||
let [x, y] = this.get_transformed_position();
|
||||
let allocation = this.allocation;
|
||||
let width = allocation.x2 - allocation.x1;
|
||||
let height = allocation.y2 - allocation.y1;
|
||||
let primaryGeometry = { x, y, width, height };
|
||||
this._syncActualGeometryLater =
|
||||
Meta.later_add(Meta.LaterType.BEFORE_REDRAW, () => {
|
||||
this._syncWorkspacesActualGeometry();
|
||||
|
||||
let monitors = Main.layoutManager.monitors;
|
||||
for (let i = 0; i < monitors.length; i++) {
|
||||
let geometry = i == this._primaryIndex ? primaryGeometry : monitors[i];
|
||||
this._workspacesViews[i].setActualGeometry(geometry);
|
||||
}
|
||||
this._syncActualGeometryLater = 0;
|
||||
return GLib.SOURCE_REMOVE;
|
||||
});
|
||||
}
|
||||
|
||||
_syncWorkspacesActualGeometry() {
|
||||
const primaryView = this._getPrimaryView();
|
||||
if (!primaryView || this._inWindowFade)
|
||||
return;
|
||||
|
||||
primaryView.ease({
|
||||
...this._actualGeometry,
|
||||
duration: Main.overview.animationInProgress ? ANIMATION_TIME : 0,
|
||||
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
|
||||
});
|
||||
}
|
||||
|
||||
_onRestacked(overview, stackIndices) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
project('gnome-shell', 'c',
|
||||
version: '3.37.2',
|
||||
version: '3.37.3',
|
||||
meson_version: '>= 0.53.0',
|
||||
license: 'GPLv2+'
|
||||
)
|
||||
@ -25,7 +25,7 @@ gio_req = '>= 2.56.0'
|
||||
gi_req = '>= 1.49.1'
|
||||
gjs_req = '>= 1.65.1'
|
||||
gtk_req = '>= 3.15.0'
|
||||
mutter_req = '>= 3.37.2'
|
||||
mutter_req = '>= 3.37.3'
|
||||
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
|
||||
|
290
po/ja.po
290
po/ja.po
@ -1,5 +1,5 @@
|
||||
# Japanese translation of gnome-shell package.
|
||||
# Copyright (C) 2009-2020 the gnome-shell copyright holder.
|
||||
# Copyright (C) 2010-2017, 2019-2020 the gnome-shell copyright holder.
|
||||
# This file is distributed under the same license as the gnome-shell package.
|
||||
# Nishio Futoshi <fut_nis@d3.dion.ne.jp>, 2010.
|
||||
# Kiyotaka NISHIBORI <ml.nishibori.kiyotaka@gmail.com>, 2011.
|
||||
@ -16,8 +16,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-05-04 14:38+0000\n"
|
||||
"PO-Revision-Date: 2020-05-13 23:00+0900\n"
|
||||
"POT-Creation-Date: 2020-06-10 17:32+0000\n"
|
||||
"PO-Revision-Date: 2020-06-11 19:00+0900\n"
|
||||
"Last-Translator: sicklylife <translation@sicklylife.jp>\n"
|
||||
"Language-Team: Japanese <gnome-translation@gnome.gr.jp>\n"
|
||||
"Language: ja\n"
|
||||
@ -421,7 +421,7 @@ msgstr "拡張機能のホームページを開く"
|
||||
#: js/ui/components/networkAgent.js:110 js/ui/components/polkitAgent.js:139
|
||||
#: js/ui/endSessionDialog.js:369 js/ui/extensionDownloader.js:181
|
||||
#: js/ui/shellMountOperation.js:376 js/ui/shellMountOperation.js:386
|
||||
#: js/ui/status/network.js:916 subprojects/extensions-app/js/main.js:148
|
||||
#: js/ui/status/network.js:916 subprojects/extensions-app/js/main.js:149
|
||||
msgid "Cancel"
|
||||
msgstr "キャンセル"
|
||||
|
||||
@ -577,7 +577,7 @@ msgid "%d hour ago"
|
||||
msgid_plural "%d hours ago"
|
||||
msgstr[0] "%d 時間前"
|
||||
|
||||
#: js/misc/util.js:191
|
||||
#: js/misc/util.js:191 js/ui/dateMenu.js:162
|
||||
msgid "Yesterday"
|
||||
msgstr "昨日"
|
||||
|
||||
@ -692,56 +692,44 @@ msgstr ""
|
||||
|
||||
#. No support for non-modal system dialogs, so ignore the option
|
||||
#. let modal = options['modal'] || true;
|
||||
#: js/ui/accessDialog.js:39 js/ui/status/location.js:374
|
||||
#: js/ui/accessDialog.js:39 js/ui/status/location.js:369
|
||||
msgid "Deny Access"
|
||||
msgstr "拒否"
|
||||
|
||||
#: js/ui/accessDialog.js:40 js/ui/status/location.js:377
|
||||
#: js/ui/accessDialog.js:40 js/ui/status/location.js:372
|
||||
msgid "Grant Access"
|
||||
msgstr "許可"
|
||||
|
||||
#: js/ui/appDisplay.js:943
|
||||
#: js/ui/appDisplay.js:902
|
||||
msgid "Unnamed Folder"
|
||||
msgstr "名前なしのフォルダー"
|
||||
|
||||
#: js/ui/appDisplay.js:966
|
||||
msgid "Frequently used applications will appear here"
|
||||
msgstr "よく使用するアプリケーションがここに表示されます"
|
||||
|
||||
#: js/ui/appDisplay.js:1101
|
||||
msgid "Frequent"
|
||||
msgstr "常用"
|
||||
|
||||
#: js/ui/appDisplay.js:1108
|
||||
msgid "All"
|
||||
msgstr "すべて"
|
||||
|
||||
#. Translators: This is the heading of a list of open windows
|
||||
#: js/ui/appDisplay.js:2485 js/ui/panel.js:75
|
||||
#: js/ui/appDisplay.js:2241 js/ui/panel.js:75
|
||||
msgid "Open Windows"
|
||||
msgstr "開いているウィンドウ"
|
||||
|
||||
#: js/ui/appDisplay.js:2504 js/ui/panel.js:82
|
||||
#: js/ui/appDisplay.js:2260 js/ui/panel.js:82
|
||||
msgid "New Window"
|
||||
msgstr "新しいウィンドウで開く"
|
||||
|
||||
#: js/ui/appDisplay.js:2520
|
||||
#: js/ui/appDisplay.js:2276
|
||||
msgid "Launch using Integrated Graphics Card"
|
||||
msgstr "統合グラフィックカードを使用して起動"
|
||||
|
||||
#: js/ui/appDisplay.js:2521
|
||||
#: js/ui/appDisplay.js:2277
|
||||
msgid "Launch using Discrete Graphics Card"
|
||||
msgstr "ディスクリートグラフィックカードを使用して起動"
|
||||
|
||||
#: js/ui/appDisplay.js:2549 js/ui/dash.js:239
|
||||
#: js/ui/appDisplay.js:2305 js/ui/dash.js:239
|
||||
msgid "Remove from Favorites"
|
||||
msgstr "お気に入りから削除"
|
||||
|
||||
#: js/ui/appDisplay.js:2555
|
||||
#: js/ui/appDisplay.js:2311
|
||||
msgid "Add to Favorites"
|
||||
msgstr "お気に入りに追加"
|
||||
|
||||
#: js/ui/appDisplay.js:2565 js/ui/panel.js:93
|
||||
#: js/ui/appDisplay.js:2321 js/ui/panel.js:93
|
||||
msgid "Show Details"
|
||||
msgstr "詳細を表示"
|
||||
|
||||
@ -771,7 +759,7 @@ msgstr "ヘッドフォン"
|
||||
msgid "Headset"
|
||||
msgstr "ヘッドセット"
|
||||
|
||||
#: js/ui/audioDeviceSelection.js:68 js/ui/status/volume.js:270
|
||||
#: js/ui/audioDeviceSelection.js:68 js/ui/status/volume.js:273
|
||||
msgid "Microphone"
|
||||
msgstr "マイク"
|
||||
|
||||
@ -788,7 +776,7 @@ msgid "Settings"
|
||||
msgstr "設定"
|
||||
|
||||
#. Translators: Enter 0-6 (Sunday-Saturday) for non-work days. Examples: "0" (Sunday) "6" (Saturday) "06" (Sunday and Saturday).
|
||||
#: js/ui/calendar.js:41
|
||||
#: js/ui/calendar.js:36
|
||||
msgctxt "calendar-no-work"
|
||||
msgid "06"
|
||||
msgstr "06"
|
||||
@ -798,43 +786,43 @@ msgstr "06"
|
||||
#. * NOTE: These grid abbreviations are always shown together
|
||||
#. * and in order, e.g. "S M T W T F S".
|
||||
#.
|
||||
#: js/ui/calendar.js:70
|
||||
#: js/ui/calendar.js:65
|
||||
msgctxt "grid sunday"
|
||||
msgid "S"
|
||||
msgstr "日"
|
||||
|
||||
#. Translators: Calendar grid abbreviation for Monday
|
||||
#: js/ui/calendar.js:72
|
||||
#: js/ui/calendar.js:67
|
||||
msgctxt "grid monday"
|
||||
msgid "M"
|
||||
msgstr "月"
|
||||
|
||||
#. Translators: Calendar grid abbreviation for Tuesday
|
||||
#: js/ui/calendar.js:74
|
||||
#: js/ui/calendar.js:69
|
||||
msgctxt "grid tuesday"
|
||||
msgid "T"
|
||||
msgstr "火"
|
||||
|
||||
#. Translators: Calendar grid abbreviation for Wednesday
|
||||
#: js/ui/calendar.js:76
|
||||
#: js/ui/calendar.js:71
|
||||
msgctxt "grid wednesday"
|
||||
msgid "W"
|
||||
msgstr "水"
|
||||
|
||||
#. Translators: Calendar grid abbreviation for Thursday
|
||||
#: js/ui/calendar.js:78
|
||||
#: js/ui/calendar.js:73
|
||||
msgctxt "grid thursday"
|
||||
msgid "T"
|
||||
msgstr "木"
|
||||
|
||||
#. Translators: Calendar grid abbreviation for Friday
|
||||
#: js/ui/calendar.js:80
|
||||
#: js/ui/calendar.js:75
|
||||
msgctxt "grid friday"
|
||||
msgid "F"
|
||||
msgstr "金"
|
||||
|
||||
#. Translators: Calendar grid abbreviation for Saturday
|
||||
#: js/ui/calendar.js:82
|
||||
#: js/ui/calendar.js:77
|
||||
msgctxt "grid saturday"
|
||||
msgid "S"
|
||||
msgstr "土"
|
||||
@ -847,7 +835,7 @@ msgstr "土"
|
||||
#. * "%OB" is the new format specifier introduced in glibc 2.27,
|
||||
#. * in most cases you should not change it.
|
||||
#.
|
||||
#: js/ui/calendar.js:397
|
||||
#: js/ui/calendar.js:392
|
||||
msgid "%OB"
|
||||
msgstr "%B"
|
||||
|
||||
@ -860,61 +848,37 @@ msgstr "%B"
|
||||
#. * in most cases you should not use the old "%B" here unless you
|
||||
#. * absolutely know what you are doing.
|
||||
#.
|
||||
#: js/ui/calendar.js:407
|
||||
#: js/ui/calendar.js:402
|
||||
msgid "%OB %Y"
|
||||
msgstr "%Y年%B"
|
||||
|
||||
#: js/ui/calendar.js:466
|
||||
#: js/ui/calendar.js:461
|
||||
msgid "Previous month"
|
||||
msgstr "先月"
|
||||
|
||||
#: js/ui/calendar.js:481
|
||||
#: js/ui/calendar.js:476
|
||||
msgid "Next month"
|
||||
msgstr "来月"
|
||||
|
||||
#: js/ui/calendar.js:631
|
||||
#: js/ui/calendar.js:626
|
||||
#, no-javascript-format
|
||||
msgctxt "date day number format"
|
||||
msgid "%d"
|
||||
msgstr "%d"
|
||||
|
||||
#: js/ui/calendar.js:687
|
||||
#: js/ui/calendar.js:682
|
||||
msgid "Week %V"
|
||||
msgstr "第 %V 週"
|
||||
|
||||
#. Translators: Shown in calendar event list for all day events
|
||||
#. * Keep it short, best if you can use less then 10 characters
|
||||
#.
|
||||
#: js/ui/calendar.js:762
|
||||
msgctxt "event list time"
|
||||
msgid "All Day"
|
||||
msgstr "終日"
|
||||
|
||||
#. Translators: Shown on calendar heading when selected day occurs on current year
|
||||
#: js/ui/calendar.js:900
|
||||
msgctxt "calendar heading"
|
||||
msgid "%A, %B %-d"
|
||||
msgstr "%B%-e日 (%a)"
|
||||
|
||||
#. Translators: Shown on calendar heading when selected day occurs on different year
|
||||
#: js/ui/calendar.js:903
|
||||
msgctxt "calendar heading"
|
||||
msgid "%A, %B %-d, %Y"
|
||||
msgstr "%Y年%B%-e日 (%a)"
|
||||
|
||||
#: js/ui/calendar.js:1133
|
||||
#: js/ui/calendar.js:895
|
||||
msgid "No Notifications"
|
||||
msgstr "通知なし"
|
||||
|
||||
#: js/ui/calendar.js:1136
|
||||
msgid "No Events"
|
||||
msgstr "イベントなし"
|
||||
|
||||
#: js/ui/calendar.js:1190
|
||||
#: js/ui/calendar.js:949
|
||||
msgid "Do Not Disturb"
|
||||
msgstr "通知ポップアップを表示しない"
|
||||
|
||||
#: js/ui/calendar.js:1209
|
||||
#: js/ui/calendar.js:968
|
||||
msgid "Clear"
|
||||
msgstr "消去"
|
||||
|
||||
@ -1066,7 +1030,7 @@ msgstr "申し訳ありません、認証できませんでした。再試行し
|
||||
msgid "%s is now known as %s"
|
||||
msgstr "%s は %s になりました"
|
||||
|
||||
#: js/ui/ctrlAltTab.js:21 js/ui/viewSelector.js:177
|
||||
#: js/ui/ctrlAltTab.js:21 js/ui/viewSelector.js:178
|
||||
msgid "Windows"
|
||||
msgstr "ウィンドウ"
|
||||
|
||||
@ -1085,7 +1049,7 @@ msgstr "ダッシュボード"
|
||||
#. * "Tue 9:29 AM"). The string itself should become a full date, e.g.,
|
||||
#. * "February 17 2015".
|
||||
#.
|
||||
#: js/ui/dateMenu.js:75
|
||||
#: js/ui/dateMenu.js:79
|
||||
msgid "%B %-d %Y"
|
||||
msgstr "%Y年%-m月%-e日"
|
||||
|
||||
@ -1093,35 +1057,67 @@ msgstr "%Y年%-m月%-e日"
|
||||
#. * below the time in the shell; it should combine the weekday and the
|
||||
#. * date, e.g. "Tuesday February 17 2015".
|
||||
#.
|
||||
#: js/ui/dateMenu.js:82
|
||||
#: js/ui/dateMenu.js:86
|
||||
msgid "%A %B %e %Y"
|
||||
msgstr "%Y年%-m月%-e日 (%a)"
|
||||
|
||||
#: js/ui/dateMenu.js:161
|
||||
#. Translators: Shown on calendar heading when selected day occurs on current year
|
||||
#: js/ui/dateMenu.js:151
|
||||
msgctxt "calendar heading"
|
||||
msgid "%B %-d"
|
||||
msgstr "%-m月%-e日"
|
||||
|
||||
#. Translators: Shown on calendar heading when selected day occurs on different year
|
||||
#: js/ui/dateMenu.js:154
|
||||
msgctxt "calendar heading"
|
||||
msgid "%B %-d %Y"
|
||||
msgstr "%Y年%-m月%-e日"
|
||||
|
||||
#: js/ui/dateMenu.js:160
|
||||
msgid "Today"
|
||||
msgstr "今日"
|
||||
|
||||
#: js/ui/dateMenu.js:164
|
||||
msgid "Tomorrow"
|
||||
msgstr "明日"
|
||||
|
||||
#. Translators: Shown in calendar event list for all day events
|
||||
#. * Keep it short, best if you can use less then 10 characters
|
||||
#.
|
||||
#: js/ui/dateMenu.js:180
|
||||
msgctxt "event list time"
|
||||
msgid "All Day"
|
||||
msgstr "終日"
|
||||
|
||||
#: js/ui/dateMenu.js:231
|
||||
msgid "No Events"
|
||||
msgstr "イベントなし"
|
||||
|
||||
#: js/ui/dateMenu.js:348
|
||||
msgid "Add world clocks…"
|
||||
msgstr "世界時計を追加…"
|
||||
|
||||
#: js/ui/dateMenu.js:162
|
||||
#: js/ui/dateMenu.js:349
|
||||
msgid "World Clocks"
|
||||
msgstr "世界時計"
|
||||
|
||||
#: js/ui/dateMenu.js:424
|
||||
#: js/ui/dateMenu.js:629
|
||||
msgid "Loading…"
|
||||
msgstr "読み込み中…"
|
||||
|
||||
#: js/ui/dateMenu.js:434
|
||||
#: js/ui/dateMenu.js:639
|
||||
msgid "Go online for weather information"
|
||||
msgstr "気象情報取得のためにネットワークに接続してください"
|
||||
|
||||
#: js/ui/dateMenu.js:436
|
||||
#: js/ui/dateMenu.js:641
|
||||
msgid "Weather information is currently unavailable"
|
||||
msgstr "気象情報を取得できません"
|
||||
|
||||
#: js/ui/dateMenu.js:446
|
||||
#: js/ui/dateMenu.js:651
|
||||
msgid "Weather"
|
||||
msgstr "天気"
|
||||
|
||||
#: js/ui/dateMenu.js:448
|
||||
#: js/ui/dateMenu.js:653
|
||||
msgid "Select weather location…"
|
||||
msgstr "天気の場所を選択…"
|
||||
|
||||
@ -1279,11 +1275,11 @@ msgstr "拡張機能をインストール"
|
||||
msgid "Download and install “%s” from extensions.gnome.org?"
|
||||
msgstr "extensions.gnome.org から“%s”をダウンロードしてインストールしますか?"
|
||||
|
||||
#: js/ui/extensionSystem.js:251
|
||||
#: js/ui/extensionSystem.js:252
|
||||
msgid "Extension Updates Available"
|
||||
msgstr "拡張機能のアップデートが利用可能です"
|
||||
|
||||
#: js/ui/extensionSystem.js:252
|
||||
#: js/ui/extensionSystem.js:253
|
||||
msgid "Extension updates are ready to be installed."
|
||||
msgstr "拡張機能のアップデートをインストールする準備ができました。"
|
||||
|
||||
@ -1410,6 +1406,7 @@ msgid "Disabled"
|
||||
msgstr "無効"
|
||||
|
||||
#: js/ui/lookingGlass.js:743
|
||||
#: subprojects/extensions-app/data/ui/extension-row.ui:188
|
||||
msgid "Error"
|
||||
msgstr "エラー"
|
||||
|
||||
@ -1453,11 +1450,11 @@ msgstr "画面ロックには GNOME ディスプレイマネージャーが必
|
||||
msgid "System Information"
|
||||
msgstr "システム情報"
|
||||
|
||||
#: js/ui/mpris.js:199
|
||||
#: js/ui/mpris.js:203
|
||||
msgid "Unknown artist"
|
||||
msgstr "不明なアーティスト"
|
||||
|
||||
#: js/ui/mpris.js:209
|
||||
#: js/ui/mpris.js:213
|
||||
msgid "Unknown title"
|
||||
msgstr "不明なタイトル"
|
||||
|
||||
@ -1503,23 +1500,23 @@ msgstr "キーストロークを割り当て"
|
||||
msgid "Done"
|
||||
msgstr "完了"
|
||||
|
||||
#: js/ui/padOsd.js:745
|
||||
#: js/ui/padOsd.js:732
|
||||
msgid "Edit…"
|
||||
msgstr "編集…"
|
||||
|
||||
#: js/ui/padOsd.js:787 js/ui/padOsd.js:910
|
||||
#: js/ui/padOsd.js:774 js/ui/padOsd.js:891
|
||||
msgid "None"
|
||||
msgstr "なし"
|
||||
|
||||
#: js/ui/padOsd.js:863
|
||||
#: js/ui/padOsd.js:845
|
||||
msgid "Press a button to configure"
|
||||
msgstr "ボタンを押して設定してください"
|
||||
|
||||
#: js/ui/padOsd.js:864
|
||||
#: js/ui/padOsd.js:846
|
||||
msgid "Press Esc to exit"
|
||||
msgstr "Esc を押すと終了します"
|
||||
|
||||
#: js/ui/padOsd.js:867
|
||||
#: js/ui/padOsd.js:849
|
||||
msgid "Press any key to exit"
|
||||
msgstr "キーを押すと終了します"
|
||||
|
||||
@ -1529,16 +1526,16 @@ msgstr "終了"
|
||||
|
||||
#. Translators: If there is no suitable word for "Activities"
|
||||
#. in your language, you can use the word for "Overview".
|
||||
#: js/ui/panel.js:432
|
||||
#: js/ui/panel.js:435
|
||||
msgid "Activities"
|
||||
msgstr "アクティビティ"
|
||||
|
||||
#: js/ui/panel.js:711
|
||||
#: js/ui/panel.js:714
|
||||
msgctxt "System menu in the top bar"
|
||||
msgid "System"
|
||||
msgstr "システム"
|
||||
|
||||
#: js/ui/panel.js:824
|
||||
#: js/ui/panel.js:827
|
||||
msgid "Top Bar"
|
||||
msgstr "トップバー"
|
||||
|
||||
@ -1577,15 +1574,15 @@ msgstr "ロックできません"
|
||||
msgid "Lock was blocked by an application"
|
||||
msgstr "アプリケーションによってロックがブロックされました"
|
||||
|
||||
#: js/ui/search.js:702
|
||||
#: js/ui/search.js:823
|
||||
msgid "Searching…"
|
||||
msgstr "検索中…"
|
||||
|
||||
#: js/ui/search.js:704
|
||||
#: js/ui/search.js:825
|
||||
msgid "No results."
|
||||
msgstr "一致するものがありません。"
|
||||
|
||||
#: js/ui/search.js:830
|
||||
#: js/ui/search.js:951
|
||||
#, javascript-format
|
||||
msgid "%d more"
|
||||
msgid_plural "%d more"
|
||||
@ -1782,17 +1779,17 @@ msgstr "位置情報サービス無効"
|
||||
msgid "Enable"
|
||||
msgstr "有効"
|
||||
|
||||
#: js/ui/status/location.js:355
|
||||
#: js/ui/status/location.js:350
|
||||
msgid "Allow location access"
|
||||
msgstr "位置情報へのアクセスの許可"
|
||||
|
||||
#. Translators: %s is an application name
|
||||
#: js/ui/status/location.js:357
|
||||
#: js/ui/status/location.js:352
|
||||
#, javascript-format
|
||||
msgid "The app %s wants to access your location"
|
||||
msgstr "アプリ %s が位置情報へのアクセスを要求しています"
|
||||
|
||||
#: js/ui/status/location.js:367
|
||||
#: js/ui/status/location.js:362
|
||||
msgid "Location access can be changed at any time from the privacy settings."
|
||||
msgstr ""
|
||||
"位置情報のアクセス許可設定は、プライバシー設定からいつでも変更できます。"
|
||||
@ -2123,11 +2120,11 @@ msgstr "Thunderbolt 認証エラー"
|
||||
msgid "Could not authorize the Thunderbolt device: %s"
|
||||
msgstr "Thunderbolt デバイスを認証できませんでした: %s"
|
||||
|
||||
#: js/ui/status/volume.js:151
|
||||
#: js/ui/status/volume.js:154
|
||||
msgid "Volume changed"
|
||||
msgstr "音量変更しました"
|
||||
|
||||
#: js/ui/status/volume.js:222
|
||||
#: js/ui/status/volume.js:225
|
||||
msgid "Volume"
|
||||
msgstr "音量"
|
||||
|
||||
@ -2181,11 +2178,11 @@ msgstr "ロック解除"
|
||||
msgid "Log in as another user"
|
||||
msgstr "別のユーザーでログイン"
|
||||
|
||||
#: js/ui/viewSelector.js:181
|
||||
#: js/ui/viewSelector.js:182
|
||||
msgid "Applications"
|
||||
msgstr "アプリケーション"
|
||||
|
||||
#: js/ui/viewSelector.js:185
|
||||
#: js/ui/viewSelector.js:186
|
||||
msgid "Search"
|
||||
msgstr "検索"
|
||||
|
||||
@ -2335,19 +2332,19 @@ msgstr "認証ダイアログはユーザーに拒否されました"
|
||||
|
||||
#: subprojects/extensions-app/data/metainfo/org.gnome.Extensions.metainfo.xml.in:5
|
||||
#: subprojects/extensions-app/data/org.gnome.Extensions.desktop.in.in:4
|
||||
#: subprojects/extensions-app/js/main.js:182
|
||||
#: subprojects/extensions-app/js/main.js:183
|
||||
#: subprojects/extensions-app/data/ui/extensions-window.ui:61
|
||||
msgid "Extensions"
|
||||
msgstr "拡張機能"
|
||||
|
||||
#: subprojects/extensions-app/data/metainfo/org.gnome.Extensions.metainfo.xml.in:6
|
||||
#: subprojects/extensions-app/js/main.js:183
|
||||
#: subprojects/extensions-app/js/main.js:184
|
||||
msgid "Manage your GNOME Extensions"
|
||||
msgstr "GNOME 拡張機能を管理します"
|
||||
|
||||
#: subprojects/extensions-app/data/metainfo/org.gnome.Extensions.metainfo.xml.in:17
|
||||
msgid "The GNOME Project"
|
||||
msgstr ""
|
||||
msgstr "The GNOME Project"
|
||||
|
||||
#: subprojects/extensions-app/data/metainfo/org.gnome.Extensions.metainfo.xml.in:36
|
||||
msgid ""
|
||||
@ -2359,23 +2356,23 @@ msgstr ""
|
||||
msgid "Configure GNOME Shell Extensions"
|
||||
msgstr "GNOME Shell 拡張機能の設定を行います"
|
||||
|
||||
#: subprojects/extensions-app/js/main.js:144
|
||||
#: subprojects/extensions-app/js/main.js:145
|
||||
#, javascript-format
|
||||
msgid "Remove “%s”?"
|
||||
msgstr "“%s”を削除しますか?"
|
||||
|
||||
#: subprojects/extensions-app/js/main.js:145
|
||||
#: subprojects/extensions-app/js/main.js:146
|
||||
msgid ""
|
||||
"If you remove the extension, you need to return to download it if you want "
|
||||
"to enable it again"
|
||||
msgstr ""
|
||||
"拡張機能を削除した場合、再度有効にするにはダウンロードし直す必要があります"
|
||||
|
||||
#: subprojects/extensions-app/js/main.js:149
|
||||
#: subprojects/extensions-app/js/main.js:150
|
||||
msgid "Remove"
|
||||
msgstr "削除"
|
||||
|
||||
#: subprojects/extensions-app/js/main.js:181
|
||||
#: subprojects/extensions-app/js/main.js:182
|
||||
msgid "translator-credits"
|
||||
msgstr ""
|
||||
"Hideki Yamane <henrich@debian.org>\n"
|
||||
@ -2389,32 +2386,40 @@ msgstr ""
|
||||
"Takayuki KUSANO <AE5T-KSN@asahi-net.or.jp>\n"
|
||||
"Yoji TOYODA <bsyamato@sea.plala.or.jp>"
|
||||
|
||||
#: subprojects/extensions-app/js/main.js:313
|
||||
#: subprojects/extensions-app/js/main.js:314
|
||||
#, javascript-format
|
||||
msgid "%d extension will be updated on next login."
|
||||
msgid_plural "%d extensions will be updated on next login."
|
||||
msgstr[0] "%d 個の拡張機能を次回ログイン時に更新します。"
|
||||
|
||||
#: subprojects/extensions-app/data/ui/extension-row.ui:100
|
||||
#: subprojects/extensions-tool/src/command-create.c:301
|
||||
#: subprojects/extensions-app/js/main.js:461
|
||||
msgid "The extension is incompatible with the current GNOME version"
|
||||
msgstr "現在の GNOME のバージョンと互換性のない拡張機能です"
|
||||
|
||||
#: subprojects/extensions-app/js/main.js:464
|
||||
msgid "The extension had an error"
|
||||
msgstr "拡張機能にエラーがありました"
|
||||
|
||||
#: subprojects/extensions-app/data/ui/extension-row.ui:109
|
||||
#: subprojects/extensions-tool/src/command-create.c:325
|
||||
#: subprojects/extensions-tool/src/main.c:241
|
||||
msgid "Description"
|
||||
msgstr "説明"
|
||||
|
||||
#: subprojects/extensions-app/data/ui/extension-row.ui:123
|
||||
#: subprojects/extensions-app/data/ui/extension-row.ui:132
|
||||
#: subprojects/extensions-tool/src/main.c:253
|
||||
msgid "Version"
|
||||
msgstr "バージョン"
|
||||
|
||||
#: subprojects/extensions-app/data/ui/extension-row.ui:151
|
||||
#: subprojects/extensions-app/data/ui/extension-row.ui:160
|
||||
msgid "Author"
|
||||
msgstr "作者"
|
||||
|
||||
#: subprojects/extensions-app/data/ui/extension-row.ui:175
|
||||
#: subprojects/extensions-app/data/ui/extension-row.ui:216
|
||||
msgid "Website"
|
||||
msgstr "ウェブサイト"
|
||||
|
||||
#: subprojects/extensions-app/data/ui/extension-row.ui:192
|
||||
#: subprojects/extensions-app/data/ui/extension-row.ui:233
|
||||
msgid "Remove…"
|
||||
msgstr "削除…"
|
||||
|
||||
@ -2470,94 +2475,94 @@ msgstr ""
|
||||
|
||||
#: subprojects/extensions-app/data/ui/extensions-window.ui:273
|
||||
msgid "Extension Updates Ready"
|
||||
msgstr "拡張機能を更新できます"
|
||||
msgstr "拡張機能の更新準備完了"
|
||||
|
||||
#: subprojects/extensions-app/data/ui/extensions-window.ui:289
|
||||
msgid "Log Out…"
|
||||
msgstr "ログアウト…"
|
||||
|
||||
#. Translators: a file path to an extension directory
|
||||
#: subprojects/extensions-tool/src/command-create.c:202
|
||||
#: subprojects/extensions-tool/src/command-create.c:226
|
||||
#, c-format
|
||||
msgid "The new extension was successfully created in %s.\n"
|
||||
msgstr ""
|
||||
|
||||
#: subprojects/extensions-tool/src/command-create.c:275
|
||||
#: subprojects/extensions-tool/src/command-create.c:299
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Name should be a very short (ideally descriptive) string.\n"
|
||||
"Examples are: %s"
|
||||
msgstr ""
|
||||
|
||||
#: subprojects/extensions-tool/src/command-create.c:281
|
||||
#: subprojects/extensions-tool/src/command-create.c:305
|
||||
#: subprojects/extensions-tool/src/main.c:238
|
||||
msgid "Name"
|
||||
msgstr "名前"
|
||||
|
||||
#: subprojects/extensions-tool/src/command-create.c:295
|
||||
#: subprojects/extensions-tool/src/command-create.c:319
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Description is a single-sentence explanation of what your extension does.\n"
|
||||
"Examples are: %s"
|
||||
msgstr ""
|
||||
|
||||
#: subprojects/extensions-tool/src/command-create.c:315
|
||||
#: subprojects/extensions-tool/src/command-create.c:339
|
||||
msgid ""
|
||||
"UUID is a globally-unique identifier for your extension.\n"
|
||||
"This should be in the format of an email address (clicktofocus@janedoe."
|
||||
"example.com)\n"
|
||||
msgstr ""
|
||||
|
||||
#: subprojects/extensions-tool/src/command-create.c:342
|
||||
#: subprojects/extensions-tool/src/command-create.c:366
|
||||
msgid "Choose one of the available templates:\n"
|
||||
msgstr ""
|
||||
|
||||
#: subprojects/extensions-tool/src/command-create.c:356
|
||||
#: subprojects/extensions-tool/src/command-create.c:380
|
||||
msgid "Template"
|
||||
msgstr ""
|
||||
|
||||
#: subprojects/extensions-tool/src/command-create.c:411
|
||||
#: subprojects/extensions-tool/src/command-create.c:435
|
||||
msgid "The unique identifier of the new extension"
|
||||
msgstr ""
|
||||
|
||||
#: subprojects/extensions-tool/src/command-create.c:414
|
||||
#: subprojects/extensions-tool/src/command-create.c:438
|
||||
msgid "NAME"
|
||||
msgstr ""
|
||||
|
||||
#: subprojects/extensions-tool/src/command-create.c:415
|
||||
#: subprojects/extensions-tool/src/command-create.c:439
|
||||
msgid "The user-visible name of the new extension"
|
||||
msgstr ""
|
||||
|
||||
#: subprojects/extensions-tool/src/command-create.c:417
|
||||
#: subprojects/extensions-tool/src/command-create.c:441
|
||||
msgid "DESCRIPTION"
|
||||
msgstr ""
|
||||
|
||||
#: subprojects/extensions-tool/src/command-create.c:419
|
||||
#: subprojects/extensions-tool/src/command-create.c:443
|
||||
msgid "A short description of what the extension does"
|
||||
msgstr ""
|
||||
|
||||
#: subprojects/extensions-tool/src/command-create.c:422
|
||||
#: subprojects/extensions-tool/src/command-create.c:446
|
||||
msgid "TEMPLATE"
|
||||
msgstr ""
|
||||
|
||||
#: subprojects/extensions-tool/src/command-create.c:423
|
||||
#: subprojects/extensions-tool/src/command-create.c:447
|
||||
msgid "The template to use for the new extension"
|
||||
msgstr ""
|
||||
|
||||
#: subprojects/extensions-tool/src/command-create.c:429
|
||||
#: subprojects/extensions-tool/src/command-create.c:453
|
||||
msgid "Enter extension information interactively"
|
||||
msgstr ""
|
||||
|
||||
#: subprojects/extensions-tool/src/command-create.c:437
|
||||
#: subprojects/extensions-tool/src/command-create.c:461
|
||||
msgid "Create a new extension"
|
||||
msgstr "新しい拡張機能を作成します"
|
||||
|
||||
#: subprojects/extensions-tool/src/command-create.c:455
|
||||
#: subprojects/extensions-tool/src/command-create.c:479
|
||||
#: subprojects/extensions-tool/src/command-list.c:172
|
||||
msgid "Unknown arguments"
|
||||
msgstr "不明な引数です"
|
||||
|
||||
#: subprojects/extensions-tool/src/command-create.c:480
|
||||
#: subprojects/extensions-tool/src/command-create.c:504
|
||||
msgid "UUID, name and description are required"
|
||||
msgstr ""
|
||||
|
||||
@ -2877,6 +2882,23 @@ msgstr[0] "入力数: %u"
|
||||
msgid "System Sounds"
|
||||
msgstr "システムのサウンド"
|
||||
|
||||
#~ msgid "Frequently used applications will appear here"
|
||||
#~ msgstr "よく使用するアプリケーションがここに表示されます"
|
||||
|
||||
#~ msgid "Frequent"
|
||||
#~ msgstr "常用"
|
||||
|
||||
#~ msgid "All"
|
||||
#~ msgstr "すべて"
|
||||
|
||||
#~ msgctxt "calendar heading"
|
||||
#~ msgid "%A, %B %-d"
|
||||
#~ msgstr "%B%-e日 (%a)"
|
||||
|
||||
#~ msgctxt "calendar heading"
|
||||
#~ msgid "%A, %B %-d, %Y"
|
||||
#~ msgstr "%Y年%B%-e日 (%a)"
|
||||
|
||||
#~ msgid "Copy Error"
|
||||
#~ msgstr "エラーをコピー"
|
||||
|
||||
|
896
po/pt_BR.po
896
po/pt_BR.po
File diff suppressed because it is too large
Load Diff
378
po/ro.po
378
po/ro.po
@ -10,9 +10,10 @@ 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-05-21 23:22+0000\n"
|
||||
"PO-Revision-Date: 2020-05-22 15:07+0300\n"
|
||||
"Last-Translator: Florentina Mușat <emryslokadottir [at] gmail [dot] com>\n"
|
||||
"POT-Creation-Date: 2020-07-21 05:44+0000\n"
|
||||
"PO-Revision-Date: 2020-07-21 09:07+0200\n"
|
||||
"Last-Translator: Florentina Mușat <florentina [dot] musat [dot] 28 [at] "
|
||||
"gmail [dot] com>\n"
|
||||
"Language-Team: Gnome Romanian Translation Team <gnomero-list@lists."
|
||||
"sourceforge.net>\n"
|
||||
"Language: ro\n"
|
||||
@ -223,95 +224,112 @@ msgid ""
|
||||
msgstr ""
|
||||
"Activează un API D-Bus care permite introspecția stării aplicației shell."
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:119
|
||||
#: data/org.gnome.shell.gschema.xml.in:114
|
||||
msgid "Layout of the app picker"
|
||||
msgstr "Aspectul selectorului de aplicații"
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:115
|
||||
msgid ""
|
||||
"Layout of the app picker. Each entry in the array is a page. Pages are "
|
||||
"stored in the order they appear in GNOME Shell. Each page contains an "
|
||||
"“application id” → 'data' pair. Currently, the following values are stored "
|
||||
"as 'data': • “position”: the position of the application icon in the page"
|
||||
msgstr ""
|
||||
"Aspectul selectorului de aplicații. Fiecare intrare din matrice este o "
|
||||
"pagină. Paginile sunt stocate în ordinea în care apar în GNOME Shell. "
|
||||
"Fiecare pagină conține o pereche de „id aplicație” → „date”. Momentan, "
|
||||
"următoarele valori sunt stocate ca „data”: • „poziție”: poziția iconiței "
|
||||
"aplicației în pagină."
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:130
|
||||
msgid "Keybinding to open the application menu"
|
||||
msgstr "Combinație de taste pentru deschiderea meniului aplicației"
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:120
|
||||
#: data/org.gnome.shell.gschema.xml.in:131
|
||||
msgid "Keybinding to open the application menu."
|
||||
msgstr "Combinație de taste pentru deschiderea meniului aplicației."
|
||||
|
||||
#: 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 ""
|
||||
"Combinație de taste pentru deschiderea modului de afișare „Arată aplicațiile”"
|
||||
|
||||
#: 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 ""
|
||||
"Combinație de taste pentru deschiderea modului de afișare „Arată "
|
||||
"aplicațiile” a prezentării generale a activităților."
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:134
|
||||
#: data/org.gnome.shell.gschema.xml.in:145
|
||||
msgid "Keybinding to open the overview"
|
||||
msgstr "Combinație de taste pentru deschiderea prezentării generale"
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:135
|
||||
#: data/org.gnome.shell.gschema.xml.in:146
|
||||
msgid "Keybinding to open the Activities Overview."
|
||||
msgstr ""
|
||||
"Combinație de taste pentru deschiderea prezentării generale a activităților."
|
||||
|
||||
#: 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 ""
|
||||
"Combinație de taste pentru comutarea vizibilității listei de notificare"
|
||||
|
||||
#: 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 ""
|
||||
"Combinație de taste pentru comutarea vizibilității listei de notificare."
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:148
|
||||
#: data/org.gnome.shell.gschema.xml.in:159
|
||||
msgid "Keybinding to focus the active notification"
|
||||
msgstr "Combinație de taste pentru focalizarea notificării active"
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:149
|
||||
#: data/org.gnome.shell.gschema.xml.in:160
|
||||
msgid "Keybinding to focus the active notification."
|
||||
msgstr "Combinație de taste pentru focalizarea notificării active."
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:155
|
||||
#: data/org.gnome.shell.gschema.xml.in:166
|
||||
msgid "Switch to application 1"
|
||||
msgstr "Comută la aplicația 1"
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:159
|
||||
#: data/org.gnome.shell.gschema.xml.in:170
|
||||
msgid "Switch to application 2"
|
||||
msgstr "Comută la aplicația 2"
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:163
|
||||
#: data/org.gnome.shell.gschema.xml.in:174
|
||||
msgid "Switch to application 3"
|
||||
msgstr "Comută la aplicația 3"
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:167
|
||||
#: data/org.gnome.shell.gschema.xml.in:178
|
||||
msgid "Switch to application 4"
|
||||
msgstr "Comută la aplicația 4"
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:171
|
||||
#: data/org.gnome.shell.gschema.xml.in:182
|
||||
msgid "Switch to application 5"
|
||||
msgstr "Comută la aplicația 5"
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:175
|
||||
#: data/org.gnome.shell.gschema.xml.in:186
|
||||
msgid "Switch to application 6"
|
||||
msgstr "Comută la aplicația 6"
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:179
|
||||
#: data/org.gnome.shell.gschema.xml.in:190
|
||||
msgid "Switch to application 7"
|
||||
msgstr "Comută la aplicația 7"
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:183
|
||||
#: data/org.gnome.shell.gschema.xml.in:194
|
||||
msgid "Switch to application 8"
|
||||
msgstr "Comută la aplicația 8"
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:187
|
||||
#: data/org.gnome.shell.gschema.xml.in:198
|
||||
msgid "Switch to application 9"
|
||||
msgstr "Comută la aplicația 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 "Limitează comutatorul la spațiul de lucru curent."
|
||||
|
||||
#: 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."
|
||||
@ -319,11 +337,11 @@ msgstr ""
|
||||
"Dacă este activat, doar aplicațiile care au ferestre în spațiul de lucru "
|
||||
"curent sunt arătate în comutator. Altfel, toate aplicațiile sunt incluse."
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:214
|
||||
#: data/org.gnome.shell.gschema.xml.in:225
|
||||
msgid "The application icon mode."
|
||||
msgstr "Miniatură și pictograma aplicației."
|
||||
|
||||
#: 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-"
|
||||
@ -333,7 +351,7 @@ msgstr ""
|
||||
"Posibilități valide sunt „mod miniatură” (arată o miniatură a ferestrei) "
|
||||
"„mod iconiță” (arată doar iconița aplicației) sau „ambele”."
|
||||
|
||||
#: 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."
|
||||
@ -341,59 +359,59 @@ msgstr ""
|
||||
"Dacă este activat, doar ferestrele din spațiul de lucru curent sunt arătate "
|
||||
"în comutator. Altfel, toate ferestrele sunt incluse."
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:234
|
||||
#: data/org.gnome.shell.gschema.xml.in:245
|
||||
msgid "Locations"
|
||||
msgstr "Locații"
|
||||
|
||||
#: 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 "Locațiile de arătat în ceasuri globale"
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:245
|
||||
#: data/org.gnome.shell.gschema.xml.in:256
|
||||
msgid "Automatic location"
|
||||
msgstr "Locație automată"
|
||||
|
||||
#: 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 "Dacă să se obțină locația curentă"
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:253
|
||||
#: data/org.gnome.shell.gschema.xml.in:264
|
||||
msgid "Location"
|
||||
msgstr "Locație"
|
||||
|
||||
#: 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 "Locația pentru care să se arate o prognoză"
|
||||
|
||||
#: 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 "Atașează dialogul modal la fereastra părinte"
|
||||
|
||||
#: 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 ""
|
||||
"Această cheie suprascrie cheia corespondentă din org.gnome.mutter când "
|
||||
"Vizualizatorul activităților GNOME rulează."
|
||||
|
||||
#: 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 ""
|
||||
"Activează mozaic lateral la plasarea ferestrelor pe marginile ecranului"
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:283
|
||||
#: data/org.gnome.shell.gschema.xml.in:294
|
||||
msgid "Workspaces are managed dynamically"
|
||||
msgstr "Spațiile de lucru sunt gestionate în mod dinamic"
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:291
|
||||
#: data/org.gnome.shell.gschema.xml.in:302
|
||||
msgid "Workspaces only on primary monitor"
|
||||
msgstr "Spații de lucru doar pe monitorul principal"
|
||||
|
||||
#: 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 ""
|
||||
"Întârzie schimbările de focalizare în maus până când cursorul încetează să "
|
||||
@ -432,7 +450,7 @@ msgstr "Vizitează pagina principală a extensiei"
|
||||
|
||||
#: 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:181
|
||||
#: js/ui/endSessionDialog.js:369 js/ui/extensionDownloader.js:183
|
||||
#: js/ui/shellMountOperation.js:376 js/ui/shellMountOperation.js:386
|
||||
#: js/ui/status/network.js:916 subprojects/extensions-app/js/main.js:149
|
||||
msgid "Cancel"
|
||||
@ -474,7 +492,7 @@ msgstr "Nume de utilizator"
|
||||
msgid "Login Window"
|
||||
msgstr "Fereastră de autentificare"
|
||||
|
||||
#: js/gdm/util.js:345
|
||||
#: js/gdm/util.js:355
|
||||
msgid "Authentication error"
|
||||
msgstr "Eroare de autentificare"
|
||||
|
||||
@ -483,7 +501,7 @@ msgstr "Eroare de autentificare"
|
||||
#. as a cue to display our own message.
|
||||
#. Translators: this message is shown below the password entry field
|
||||
#. to indicate the user can swipe their finger instead
|
||||
#: js/gdm/util.js:471
|
||||
#: js/gdm/util.js:481
|
||||
msgid "(or swipe finger)"
|
||||
msgstr "(sau treceți degetul peste)"
|
||||
|
||||
@ -594,7 +612,7 @@ msgstr[0] "%d oră în urmă"
|
||||
msgstr[1] "%d ore în urmă"
|
||||
msgstr[2] "%d de ore în urmă"
|
||||
|
||||
#: js/misc/util.js:191
|
||||
#: js/misc/util.js:191 js/ui/dateMenu.js:162
|
||||
msgid "Yesterday"
|
||||
msgstr "Ieri"
|
||||
|
||||
@ -718,56 +736,44 @@ msgstr ""
|
||||
|
||||
#. No support for non-modal system dialogs, so ignore the option
|
||||
#. let modal = options['modal'] || true;
|
||||
#: js/ui/accessDialog.js:39 js/ui/status/location.js:374
|
||||
#: js/ui/accessDialog.js:39 js/ui/status/location.js:369
|
||||
msgid "Deny Access"
|
||||
msgstr "Refuză accesul"
|
||||
|
||||
#: js/ui/accessDialog.js:40 js/ui/status/location.js:377
|
||||
#: js/ui/accessDialog.js:40 js/ui/status/location.js:372
|
||||
msgid "Grant Access"
|
||||
msgstr "Permite accesul"
|
||||
|
||||
#: js/ui/appDisplay.js:944
|
||||
#: js/ui/appDisplay.js:1297
|
||||
msgid "Unnamed Folder"
|
||||
msgstr "Dosar nedenumit"
|
||||
|
||||
#: js/ui/appDisplay.js:967
|
||||
msgid "Frequently used applications will appear here"
|
||||
msgstr "Aplicațiile utilizate frecvent vor fi afișate aici"
|
||||
|
||||
#: js/ui/appDisplay.js:1102
|
||||
msgid "Frequent"
|
||||
msgstr "Frecvente"
|
||||
|
||||
#: js/ui/appDisplay.js:1109
|
||||
msgid "All"
|
||||
msgstr "Toate"
|
||||
|
||||
#. Translators: This is the heading of a list of open windows
|
||||
#: js/ui/appDisplay.js:2486 js/ui/panel.js:75
|
||||
#: js/ui/appDisplay.js:2767 js/ui/panel.js:75
|
||||
msgid "Open Windows"
|
||||
msgstr "Ferestre deschise"
|
||||
|
||||
#: js/ui/appDisplay.js:2505 js/ui/panel.js:82
|
||||
#: js/ui/appDisplay.js:2786 js/ui/panel.js:82
|
||||
msgid "New Window"
|
||||
msgstr "Fereastră nouă"
|
||||
|
||||
#: js/ui/appDisplay.js:2521
|
||||
#: js/ui/appDisplay.js:2802
|
||||
msgid "Launch using Integrated Graphics Card"
|
||||
msgstr "Lansează folosind placa grafică integrată"
|
||||
|
||||
#: js/ui/appDisplay.js:2522
|
||||
#: js/ui/appDisplay.js:2803
|
||||
msgid "Launch using Discrete Graphics Card"
|
||||
msgstr "Lansează folosind placa grafică discretă"
|
||||
|
||||
#: js/ui/appDisplay.js:2550 js/ui/dash.js:239
|
||||
#: js/ui/appDisplay.js:2831 js/ui/dash.js:239
|
||||
msgid "Remove from Favorites"
|
||||
msgstr "Elimină din favorite"
|
||||
|
||||
#: js/ui/appDisplay.js:2556
|
||||
#: js/ui/appDisplay.js:2837
|
||||
msgid "Add to Favorites"
|
||||
msgstr "Adaugă la Favorite"
|
||||
|
||||
#: js/ui/appDisplay.js:2566 js/ui/panel.js:93
|
||||
#: js/ui/appDisplay.js:2847 js/ui/panel.js:93
|
||||
msgid "Show Details"
|
||||
msgstr "Arată detaliile"
|
||||
|
||||
@ -797,7 +803,7 @@ msgstr "Căști auriculare"
|
||||
msgid "Headset"
|
||||
msgstr "Căști cu microfon"
|
||||
|
||||
#: js/ui/audioDeviceSelection.js:68 js/ui/status/volume.js:273
|
||||
#: js/ui/audioDeviceSelection.js:68 js/ui/status/volume.js:272
|
||||
msgid "Microphone"
|
||||
msgstr "Microfon"
|
||||
|
||||
@ -814,7 +820,7 @@ msgid "Settings"
|
||||
msgstr "Configurări"
|
||||
|
||||
#. Translators: Enter 0-6 (Sunday-Saturday) for non-work days. Examples: "0" (Sunday) "6" (Saturday) "06" (Sunday and Saturday).
|
||||
#: js/ui/calendar.js:41
|
||||
#: js/ui/calendar.js:36
|
||||
msgctxt "calendar-no-work"
|
||||
msgid "06"
|
||||
msgstr "06"
|
||||
@ -824,43 +830,43 @@ msgstr "06"
|
||||
#. * NOTE: These grid abbreviations are always shown together
|
||||
#. * and in order, e.g. "S M T W T F S".
|
||||
#.
|
||||
#: js/ui/calendar.js:70
|
||||
#: js/ui/calendar.js:65
|
||||
msgctxt "grid sunday"
|
||||
msgid "S"
|
||||
msgstr "D"
|
||||
|
||||
#. Translators: Calendar grid abbreviation for Monday
|
||||
#: js/ui/calendar.js:72
|
||||
#: js/ui/calendar.js:67
|
||||
msgctxt "grid monday"
|
||||
msgid "M"
|
||||
msgstr "L"
|
||||
|
||||
#. Translators: Calendar grid abbreviation for Tuesday
|
||||
#: js/ui/calendar.js:74
|
||||
#: js/ui/calendar.js:69
|
||||
msgctxt "grid tuesday"
|
||||
msgid "T"
|
||||
msgstr "M"
|
||||
|
||||
#. Translators: Calendar grid abbreviation for Wednesday
|
||||
#: js/ui/calendar.js:76
|
||||
#: js/ui/calendar.js:71
|
||||
msgctxt "grid wednesday"
|
||||
msgid "W"
|
||||
msgstr "M"
|
||||
|
||||
#. Translators: Calendar grid abbreviation for Thursday
|
||||
#: js/ui/calendar.js:78
|
||||
#: js/ui/calendar.js:73
|
||||
msgctxt "grid thursday"
|
||||
msgid "T"
|
||||
msgstr "J"
|
||||
|
||||
#. Translators: Calendar grid abbreviation for Friday
|
||||
#: js/ui/calendar.js:80
|
||||
#: js/ui/calendar.js:75
|
||||
msgctxt "grid friday"
|
||||
msgid "F"
|
||||
msgstr "V"
|
||||
|
||||
#. Translators: Calendar grid abbreviation for Saturday
|
||||
#: js/ui/calendar.js:82
|
||||
#: js/ui/calendar.js:77
|
||||
msgctxt "grid saturday"
|
||||
msgid "S"
|
||||
msgstr "S"
|
||||
@ -871,7 +877,7 @@ msgstr "S"
|
||||
#. * "%OB" is the new format specifier introduced in glibc 2.27,
|
||||
#. * in most cases you should not change it.
|
||||
#.
|
||||
#: js/ui/calendar.js:397
|
||||
#: js/ui/calendar.js:392
|
||||
msgid "%OB"
|
||||
msgstr "%OB"
|
||||
|
||||
@ -884,61 +890,37 @@ msgstr "%OB"
|
||||
#. * in most cases you should not use the old "%B" here unless you
|
||||
#. * absolutely know what you are doing.
|
||||
#.
|
||||
#: js/ui/calendar.js:407
|
||||
#: js/ui/calendar.js:402
|
||||
msgid "%OB %Y"
|
||||
msgstr "%OB %Y"
|
||||
|
||||
#: js/ui/calendar.js:466
|
||||
#: js/ui/calendar.js:461
|
||||
msgid "Previous month"
|
||||
msgstr "Luna precedentă"
|
||||
|
||||
#: js/ui/calendar.js:481
|
||||
#: js/ui/calendar.js:476
|
||||
msgid "Next month"
|
||||
msgstr "Luna viitoare"
|
||||
|
||||
#: js/ui/calendar.js:631
|
||||
#: js/ui/calendar.js:626
|
||||
#, no-javascript-format
|
||||
msgctxt "date day number format"
|
||||
msgid "%d"
|
||||
msgstr "%d"
|
||||
|
||||
#: js/ui/calendar.js:687
|
||||
#: js/ui/calendar.js:682
|
||||
msgid "Week %V"
|
||||
msgstr "Săptămâna %V"
|
||||
|
||||
#. Translators: Shown in calendar event list for all day events
|
||||
#. * Keep it short, best if you can use less then 10 characters
|
||||
#.
|
||||
#: js/ui/calendar.js:762
|
||||
msgctxt "event list time"
|
||||
msgid "All Day"
|
||||
msgstr "Toată ziua"
|
||||
|
||||
#. Translators: Shown on calendar heading when selected day occurs on current year
|
||||
#: js/ui/calendar.js:900
|
||||
msgctxt "calendar heading"
|
||||
msgid "%A, %B %-d"
|
||||
msgstr "%A, %B %-d"
|
||||
|
||||
#. Translators: Shown on calendar heading when selected day occurs on different year
|
||||
#: js/ui/calendar.js:903
|
||||
msgctxt "calendar heading"
|
||||
msgid "%A, %B %-d, %Y"
|
||||
msgstr "%A, %B %-d, %Y"
|
||||
|
||||
#: js/ui/calendar.js:1133
|
||||
#: js/ui/calendar.js:895
|
||||
msgid "No Notifications"
|
||||
msgstr "Nu există notificări"
|
||||
|
||||
#: js/ui/calendar.js:1136
|
||||
msgid "No Events"
|
||||
msgstr "Nu există evenimente"
|
||||
|
||||
#: js/ui/calendar.js:1190
|
||||
#: js/ui/calendar.js:949
|
||||
msgid "Do Not Disturb"
|
||||
msgstr "Nu deranja"
|
||||
|
||||
#: js/ui/calendar.js:1209
|
||||
#: js/ui/calendar.js:968
|
||||
msgid "Clear"
|
||||
msgstr "Curăță"
|
||||
|
||||
@ -1093,7 +1075,7 @@ msgstr "Nu a funcționat. Încercați din nou."
|
||||
msgid "%s is now known as %s"
|
||||
msgstr "%s este acum cunoscut ca %s"
|
||||
|
||||
#: js/ui/ctrlAltTab.js:21 js/ui/viewSelector.js:177
|
||||
#: js/ui/ctrlAltTab.js:21 js/ui/viewSelector.js:178
|
||||
msgid "Windows"
|
||||
msgstr "Ferestre"
|
||||
|
||||
@ -1112,7 +1094,7 @@ msgstr "Dash"
|
||||
#. * "Tue 9:29 AM"). The string itself should become a full date, e.g.,
|
||||
#. * "February 17 2015".
|
||||
#.
|
||||
#: js/ui/dateMenu.js:75
|
||||
#: js/ui/dateMenu.js:79
|
||||
msgid "%B %-d %Y"
|
||||
msgstr "%B %-d %Y"
|
||||
|
||||
@ -1120,35 +1102,67 @@ msgstr "%B %-d %Y"
|
||||
#. * below the time in the shell; it should combine the weekday and the
|
||||
#. * date, e.g. "Tuesday February 17 2015".
|
||||
#.
|
||||
#: js/ui/dateMenu.js:82
|
||||
#: js/ui/dateMenu.js:86
|
||||
msgid "%A %B %e %Y"
|
||||
msgstr "%A %B %e %Y"
|
||||
|
||||
#: js/ui/dateMenu.js:162
|
||||
#. Translators: Shown on calendar heading when selected day occurs on current year
|
||||
#: js/ui/dateMenu.js:151
|
||||
msgctxt "calendar heading"
|
||||
msgid "%B %-d"
|
||||
msgstr "%B %-d"
|
||||
|
||||
#. Translators: Shown on calendar heading when selected day occurs on different year
|
||||
#: js/ui/dateMenu.js:154
|
||||
msgctxt "calendar heading"
|
||||
msgid "%B %-d %Y"
|
||||
msgstr "%B %-d %Y"
|
||||
|
||||
#: js/ui/dateMenu.js:160
|
||||
msgid "Today"
|
||||
msgstr "Astăzi"
|
||||
|
||||
#: js/ui/dateMenu.js:164
|
||||
msgid "Tomorrow"
|
||||
msgstr "Mâine"
|
||||
|
||||
#. Translators: Shown in calendar event list for all day events
|
||||
#. * Keep it short, best if you can use less then 10 characters
|
||||
#.
|
||||
#: js/ui/dateMenu.js:180
|
||||
msgctxt "event list time"
|
||||
msgid "All Day"
|
||||
msgstr "Toată ziua"
|
||||
|
||||
#: js/ui/dateMenu.js:231
|
||||
msgid "No Events"
|
||||
msgstr "Nu există evenimente"
|
||||
|
||||
#: js/ui/dateMenu.js:348
|
||||
msgid "Add world clocks…"
|
||||
msgstr "Adaugă un fus orar…"
|
||||
|
||||
#: js/ui/dateMenu.js:163
|
||||
#: js/ui/dateMenu.js:349
|
||||
msgid "World Clocks"
|
||||
msgstr "Fusuri orare"
|
||||
|
||||
#: js/ui/dateMenu.js:443
|
||||
#: js/ui/dateMenu.js:629
|
||||
msgid "Loading…"
|
||||
msgstr "Se încarcă…"
|
||||
|
||||
#: js/ui/dateMenu.js:453
|
||||
#: js/ui/dateMenu.js:639
|
||||
msgid "Go online for weather information"
|
||||
msgstr "Conectați-vă la internet pentru informații despre vreme"
|
||||
|
||||
#: js/ui/dateMenu.js:455
|
||||
#: js/ui/dateMenu.js:641
|
||||
msgid "Weather information is currently unavailable"
|
||||
msgstr "Informațiile despre vreme nu sunt disponibile momentan"
|
||||
|
||||
#: js/ui/dateMenu.js:465
|
||||
#: js/ui/dateMenu.js:651
|
||||
msgid "Weather"
|
||||
msgstr "Vreme"
|
||||
|
||||
#: js/ui/dateMenu.js:467
|
||||
#: js/ui/dateMenu.js:653
|
||||
msgid "Select weather location…"
|
||||
msgstr "Selectează locația vremii…"
|
||||
|
||||
@ -1303,15 +1317,15 @@ msgstr "%s (la distanță)"
|
||||
msgid "%s (console)"
|
||||
msgstr "%s (consolă)"
|
||||
|
||||
#: js/ui/extensionDownloader.js:185
|
||||
#: js/ui/extensionDownloader.js:187
|
||||
msgid "Install"
|
||||
msgstr "Instalează"
|
||||
|
||||
#: js/ui/extensionDownloader.js:191
|
||||
#: js/ui/extensionDownloader.js:193
|
||||
msgid "Install Extension"
|
||||
msgstr "Instalează extensia"
|
||||
|
||||
#: js/ui/extensionDownloader.js:192
|
||||
#: js/ui/extensionDownloader.js:194
|
||||
#, javascript-format
|
||||
msgid "Download and install “%s” from extensions.gnome.org?"
|
||||
msgstr "Descărcați și instalați „%s” de la extensions.gnome.org?"
|
||||
@ -1344,11 +1358,11 @@ msgstr "O aplicație vrea să inhibe scurtăturile"
|
||||
msgid "You can restore shortcuts by pressing %s."
|
||||
msgstr "Puteți restaura scurtăturile apăsând %s."
|
||||
|
||||
#: js/ui/inhibitShortcutsDialog.js:98
|
||||
#: js/ui/inhibitShortcutsDialog.js:100
|
||||
msgid "Deny"
|
||||
msgstr "Refuză"
|
||||
|
||||
#: js/ui/inhibitShortcutsDialog.js:105
|
||||
#: js/ui/inhibitShortcutsDialog.js:107
|
||||
msgid "Allow"
|
||||
msgstr "Permite"
|
||||
|
||||
@ -1417,7 +1431,7 @@ msgstr "Oprește"
|
||||
msgid "Leave Off"
|
||||
msgstr "Lasă oprit"
|
||||
|
||||
#: js/ui/keyboard.js:207
|
||||
#: js/ui/keyboard.js:225
|
||||
msgid "Region & Language Settings"
|
||||
msgstr "Configurări de regiune și limbă"
|
||||
|
||||
@ -1491,25 +1505,25 @@ msgstr "Blocarea ecranului este dezactivată"
|
||||
msgid "Screen Locking requires the GNOME display manager."
|
||||
msgstr "Blocarea ecranului necesită administratorul de afișaj GNOME."
|
||||
|
||||
#: js/ui/messageTray.js:1547
|
||||
#: js/ui/messageTray.js:1476
|
||||
msgid "System Information"
|
||||
msgstr "Informații despre sistem"
|
||||
|
||||
#: js/ui/mpris.js:204
|
||||
#: js/ui/mpris.js:203
|
||||
msgid "Unknown artist"
|
||||
msgstr "Artist necunoscut"
|
||||
|
||||
#: js/ui/mpris.js:214
|
||||
#: js/ui/mpris.js:213
|
||||
msgid "Unknown title"
|
||||
msgstr "Titlu necunoscut"
|
||||
|
||||
#: js/ui/overview.js:73
|
||||
#: js/ui/overview.js:74
|
||||
msgid "Undo"
|
||||
msgstr "Anulează"
|
||||
|
||||
#. Translators: This is the main view to select
|
||||
#. activities. See also note for "Activities" string.
|
||||
#: js/ui/overview.js:86
|
||||
#: js/ui/overview.js:87
|
||||
msgid "Overview"
|
||||
msgstr "Prezentare generală"
|
||||
|
||||
@ -1517,7 +1531,7 @@ msgstr "Prezentare generală"
|
||||
#. in the search entry when no search is
|
||||
#. active; it should not exceed ~30
|
||||
#. characters.
|
||||
#: js/ui/overview.js:107
|
||||
#: js/ui/overview.js:108
|
||||
msgid "Type to search"
|
||||
msgstr "Tastați pentru a căuta"
|
||||
|
||||
@ -1545,23 +1559,23 @@ msgstr "Alochează tasta apăsată"
|
||||
msgid "Done"
|
||||
msgstr "Gata"
|
||||
|
||||
#: js/ui/padOsd.js:745
|
||||
#: js/ui/padOsd.js:732
|
||||
msgid "Edit…"
|
||||
msgstr "Editează…"
|
||||
|
||||
#: js/ui/padOsd.js:787 js/ui/padOsd.js:910
|
||||
#: js/ui/padOsd.js:774 js/ui/padOsd.js:891
|
||||
msgid "None"
|
||||
msgstr "Nespecificat"
|
||||
|
||||
#: js/ui/padOsd.js:863
|
||||
#: js/ui/padOsd.js:845
|
||||
msgid "Press a button to configure"
|
||||
msgstr "Apăsați un buton de configurat"
|
||||
|
||||
#: js/ui/padOsd.js:864
|
||||
#: js/ui/padOsd.js:846
|
||||
msgid "Press Esc to exit"
|
||||
msgstr "Apăsați Esc pentru a ieși"
|
||||
|
||||
#: js/ui/padOsd.js:867
|
||||
#: js/ui/padOsd.js:849
|
||||
msgid "Press any key to exit"
|
||||
msgstr "Apăsați orice tastă pentru a ieși"
|
||||
|
||||
@ -1826,17 +1840,17 @@ msgstr "Locația dezactivată"
|
||||
msgid "Enable"
|
||||
msgstr "Activează"
|
||||
|
||||
#: js/ui/status/location.js:355
|
||||
#: js/ui/status/location.js:350
|
||||
msgid "Allow location access"
|
||||
msgstr "Permite accesul la locație"
|
||||
|
||||
#. Translators: %s is an application name
|
||||
#: js/ui/status/location.js:357
|
||||
#: js/ui/status/location.js:352
|
||||
#, javascript-format
|
||||
msgid "The app %s wants to access your location"
|
||||
msgstr "Aplicația %s dorește să vă acceseze locația"
|
||||
|
||||
#: js/ui/status/location.js:367
|
||||
#: js/ui/status/location.js:362
|
||||
msgid "Location access can be changed at any time from the privacy settings."
|
||||
msgstr ""
|
||||
"Accesul la locație poate fi schimbat oricând din configurările de "
|
||||
@ -2175,11 +2189,11 @@ msgstr "Eroare de autorizare Thunderbolt"
|
||||
msgid "Could not authorize the Thunderbolt device: %s"
|
||||
msgstr "Nu s-a putut autoriza dispozitivul Thunderbolt: %s"
|
||||
|
||||
#: js/ui/status/volume.js:154
|
||||
#: js/ui/status/volume.js:155
|
||||
msgid "Volume changed"
|
||||
msgstr "Volumul a fost schimbat"
|
||||
|
||||
#: js/ui/status/volume.js:225
|
||||
#: js/ui/status/volume.js:217
|
||||
msgid "Volume"
|
||||
msgstr "Volum"
|
||||
|
||||
@ -2225,19 +2239,19 @@ msgstr "Glisați în sus pentru a debloca"
|
||||
msgid "Click or press a key to unlock"
|
||||
msgstr "Apăsați clic sau o tastă pentru a debloca"
|
||||
|
||||
#: js/ui/unlockDialog.js:550
|
||||
#: js/ui/unlockDialog.js:555
|
||||
msgid "Unlock Window"
|
||||
msgstr "Deblochează fereastră"
|
||||
|
||||
#: js/ui/unlockDialog.js:559
|
||||
#: js/ui/unlockDialog.js:564
|
||||
msgid "Log in as another user"
|
||||
msgstr "Intră în sesiune ca utilizator diferit"
|
||||
|
||||
#: js/ui/viewSelector.js:181
|
||||
#: js/ui/viewSelector.js:182
|
||||
msgid "Applications"
|
||||
msgstr "Aplicații"
|
||||
|
||||
#: js/ui/viewSelector.js:185
|
||||
#: js/ui/viewSelector.js:186
|
||||
msgid "Search"
|
||||
msgstr "Caută"
|
||||
|
||||
@ -2365,12 +2379,12 @@ msgstr "Utilizează un mod specific, de exemplu „gdm” pentru ecranul de loga
|
||||
msgid "List possible modes"
|
||||
msgstr "Enumeră câmpurile care pot fi afișate"
|
||||
|
||||
#: src/shell-app.c:286
|
||||
#: src/shell-app.c:268
|
||||
msgctxt "program"
|
||||
msgid "Unknown"
|
||||
msgstr "Necunoscut"
|
||||
|
||||
#: src/shell-app.c:537
|
||||
#: src/shell-app.c:519
|
||||
#, c-format
|
||||
msgid "Failed to launch “%s”"
|
||||
msgstr "Nu s-a putut lansa „%s”"
|
||||
@ -2434,7 +2448,8 @@ msgstr "Elimină"
|
||||
|
||||
#: subprojects/extensions-app/js/main.js:182
|
||||
msgid "translator-credits"
|
||||
msgstr "Florentina Mușat <emryslokadottir [at] gmail [dot] com>, 2020"
|
||||
msgstr ""
|
||||
"Florentina Mușat <florentina [dot] musat [dot] 28 [at] gmail [dot] com>, 2020"
|
||||
|
||||
#: subprojects/extensions-app/js/main.js:314
|
||||
#, javascript-format
|
||||
@ -2453,7 +2468,7 @@ msgid "The extension had an error"
|
||||
msgstr "Extensia a avut o eroare"
|
||||
|
||||
#: subprojects/extensions-app/data/ui/extension-row.ui:109
|
||||
#: subprojects/extensions-tool/src/command-create.c:301
|
||||
#: subprojects/extensions-tool/src/command-create.c:325
|
||||
#: subprojects/extensions-tool/src/main.c:241
|
||||
msgid "Description"
|
||||
msgstr "Descriere"
|
||||
@ -2534,12 +2549,12 @@ msgid "Log Out…"
|
||||
msgstr "Deautentificare…"
|
||||
|
||||
#. Translators: a file path to an extension directory
|
||||
#: subprojects/extensions-tool/src/command-create.c:202
|
||||
#: subprojects/extensions-tool/src/command-create.c:226
|
||||
#, c-format
|
||||
msgid "The new extension was successfully created in %s.\n"
|
||||
msgstr "Extensia nouă a fost creată cu succes la %s.\n"
|
||||
|
||||
#: subprojects/extensions-tool/src/command-create.c:275
|
||||
#: subprojects/extensions-tool/src/command-create.c:299
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Name should be a very short (ideally descriptive) string.\n"
|
||||
@ -2548,12 +2563,12 @@ msgstr ""
|
||||
"Numele ar trebui să fie un șir foarte scurt (ideal descriptiv).\n"
|
||||
"Exemple: %s"
|
||||
|
||||
#: subprojects/extensions-tool/src/command-create.c:281
|
||||
#: subprojects/extensions-tool/src/command-create.c:305
|
||||
#: subprojects/extensions-tool/src/main.c:238
|
||||
msgid "Name"
|
||||
msgstr "Nume"
|
||||
|
||||
#: subprojects/extensions-tool/src/command-create.c:295
|
||||
#: subprojects/extensions-tool/src/command-create.c:319
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Description is a single-sentence explanation of what your extension does.\n"
|
||||
@ -2563,7 +2578,7 @@ msgstr ""
|
||||
"extensia.\n"
|
||||
"Exemple: %s"
|
||||
|
||||
#: subprojects/extensions-tool/src/command-create.c:315
|
||||
#: subprojects/extensions-tool/src/command-create.c:339
|
||||
msgid ""
|
||||
"UUID is a globally-unique identifier for your extension.\n"
|
||||
"This should be in the format of an email address (clicktofocus@janedoe."
|
||||
@ -2573,56 +2588,56 @@ msgstr ""
|
||||
"Aceasta ar trebui să fie în formatul unei adrese de email "
|
||||
"(clicktofocus@janedoe.example.com)\n"
|
||||
|
||||
#: subprojects/extensions-tool/src/command-create.c:342
|
||||
#: subprojects/extensions-tool/src/command-create.c:366
|
||||
msgid "Choose one of the available templates:\n"
|
||||
msgstr "Alege unul din șabloanele existente:\n"
|
||||
|
||||
#: subprojects/extensions-tool/src/command-create.c:356
|
||||
#: subprojects/extensions-tool/src/command-create.c:380
|
||||
msgid "Template"
|
||||
msgstr "Șablon"
|
||||
|
||||
#: subprojects/extensions-tool/src/command-create.c:411
|
||||
#: subprojects/extensions-tool/src/command-create.c:435
|
||||
msgid "The unique identifier of the new extension"
|
||||
msgstr "Identificatorul unic al noii extensii"
|
||||
|
||||
#: subprojects/extensions-tool/src/command-create.c:414
|
||||
#: subprojects/extensions-tool/src/command-create.c:438
|
||||
msgid "NAME"
|
||||
msgstr "NUME"
|
||||
|
||||
#: subprojects/extensions-tool/src/command-create.c:415
|
||||
#: subprojects/extensions-tool/src/command-create.c:439
|
||||
msgid "The user-visible name of the new extension"
|
||||
msgstr "Numele vizibil de utilizator pentru noua extensie"
|
||||
|
||||
#: subprojects/extensions-tool/src/command-create.c:417
|
||||
#: subprojects/extensions-tool/src/command-create.c:441
|
||||
msgid "DESCRIPTION"
|
||||
msgstr "DESCRIERE"
|
||||
|
||||
#: subprojects/extensions-tool/src/command-create.c:419
|
||||
#: subprojects/extensions-tool/src/command-create.c:443
|
||||
msgid "A short description of what the extension does"
|
||||
msgstr "O scurtă descriere despre ce face extensia"
|
||||
|
||||
#: subprojects/extensions-tool/src/command-create.c:422
|
||||
#: subprojects/extensions-tool/src/command-create.c:446
|
||||
msgid "TEMPLATE"
|
||||
msgstr "ȘABLON"
|
||||
|
||||
#: subprojects/extensions-tool/src/command-create.c:423
|
||||
#: subprojects/extensions-tool/src/command-create.c:447
|
||||
msgid "The template to use for the new extension"
|
||||
msgstr "Șablonul de utilizat pentru extensia nouă"
|
||||
|
||||
#: subprojects/extensions-tool/src/command-create.c:429
|
||||
#: subprojects/extensions-tool/src/command-create.c:453
|
||||
msgid "Enter extension information interactively"
|
||||
msgstr "Introdu informațiile extensiei interactiv"
|
||||
|
||||
#: subprojects/extensions-tool/src/command-create.c:437
|
||||
#: subprojects/extensions-tool/src/command-create.c:461
|
||||
msgid "Create a new extension"
|
||||
msgstr "Creează o nouă extensie"
|
||||
|
||||
#: subprojects/extensions-tool/src/command-create.c:455
|
||||
#: subprojects/extensions-tool/src/command-create.c:479
|
||||
#: subprojects/extensions-tool/src/command-list.c:172
|
||||
msgid "Unknown arguments"
|
||||
msgstr "Argumente necunoscute"
|
||||
|
||||
#: subprojects/extensions-tool/src/command-create.c:480
|
||||
#: subprojects/extensions-tool/src/command-create.c:504
|
||||
msgid "UUID, name and description are required"
|
||||
msgstr "UUID-ul, numele și descrierea sunt necesare"
|
||||
|
||||
@ -2946,6 +2961,23 @@ msgstr[2] "%u de intrări"
|
||||
msgid "System Sounds"
|
||||
msgstr "Sunete de sistem"
|
||||
|
||||
#~ msgid "Frequently used applications will appear here"
|
||||
#~ msgstr "Aplicațiile utilizate frecvent vor fi afișate aici"
|
||||
|
||||
#~ msgid "Frequent"
|
||||
#~ msgstr "Frecvente"
|
||||
|
||||
#~ msgid "All"
|
||||
#~ msgstr "Toate"
|
||||
|
||||
#~ msgctxt "calendar heading"
|
||||
#~ msgid "%A, %B %-d"
|
||||
#~ msgstr "%A, %B %-d"
|
||||
|
||||
#~ msgctxt "calendar heading"
|
||||
#~ msgid "%A, %B %-d, %Y"
|
||||
#~ msgstr "%A, %B %-d, %Y"
|
||||
|
||||
#~ msgid "Copy Error"
|
||||
#~ msgstr "Eroare la copiere"
|
||||
|
||||
@ -3115,12 +3147,6 @@ msgstr "Sunete de sistem"
|
||||
#~ msgid "Nothing Scheduled"
|
||||
#~ msgstr "Nimic programat"
|
||||
|
||||
#~ msgid "Today"
|
||||
#~ msgstr "Astăzi"
|
||||
|
||||
#~ msgid "Tomorrow"
|
||||
#~ msgstr "Mâine"
|
||||
|
||||
#~ msgid "This week"
|
||||
#~ msgstr "Săptămâna aceasta"
|
||||
|
||||
|
403
po/tr.po
403
po/tr.po
@ -17,8 +17,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-05-15 18:43+0000\n"
|
||||
"PO-Revision-Date: 2020-05-16 12:12+0300\n"
|
||||
"POT-Creation-Date: 2020-07-29 07:55+0000\n"
|
||||
"PO-Revision-Date: 2020-07-30 00:49+0300\n"
|
||||
"Last-Translator: Emin Tufan Çetin <etcetin@gmail.com>\n"
|
||||
"Language-Team: Türkçe <gnome-turk@gnome.org>\n"
|
||||
"Language: tr\n"
|
||||
@ -225,91 +225,107 @@ msgstr ""
|
||||
"Kabuğun uygulama durumunu gözden geçirmeyi sağlayan D-Bus APIʼsını "
|
||||
"etkinleştirir."
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:119
|
||||
#: data/org.gnome.shell.gschema.xml.in:114
|
||||
msgid "Layout of the app picker"
|
||||
msgstr "Uygulama seçicinin düzeni"
|
||||
|
||||
#: 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 ""
|
||||
"Uygulama seçicinin düzeni. Dizideki her girdi bir sayfadır. Sayfalar "
|
||||
"GNOME Kabuğu’nda göründüğü sırayla depolanır. Her sayfa bir “application id” "
|
||||
"→ 'data' çifti içerir. Şimdilik şu değerler 'data' olarak depolanır: "
|
||||
"• “position”: sayfadaki uygulama simgesinin konumu"
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:130
|
||||
msgid "Keybinding to open the application menu"
|
||||
msgstr "Uygulama menüsünü açmak için klavye kısayolu"
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:120
|
||||
#: data/org.gnome.shell.gschema.xml.in:131
|
||||
msgid "Keybinding to open the application menu."
|
||||
msgstr "Uygulama menüsünü açmak için klavye kısayolu."
|
||||
|
||||
#: 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 "“Uygulamaları Göster” görünümünü açmak için klavye kısayolu"
|
||||
|
||||
#: 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 ""
|
||||
"Etkinlikler Genel Görünümünün “Uygulamaları Göster” görünümünü açmak için "
|
||||
"klavye kısayolu."
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:134
|
||||
#: data/org.gnome.shell.gschema.xml.in:145
|
||||
msgid "Keybinding to open the overview"
|
||||
msgstr "Genel görünümü açmak için klavye kısayolu"
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:135
|
||||
#: data/org.gnome.shell.gschema.xml.in:146
|
||||
msgid "Keybinding to open the Activities Overview."
|
||||
msgstr "Etkinlikler Genel Görünümünü açmak için klavye kısayolu."
|
||||
|
||||
#: 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 "Bildirim listesinin görünürlüğünü değiştirmek için klavye kısayolu"
|
||||
|
||||
#: 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 "Bildirim listesinin görünürlüğünü değiştirmek için klavye kısayolu."
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:148
|
||||
#: data/org.gnome.shell.gschema.xml.in:159
|
||||
msgid "Keybinding to focus the active notification"
|
||||
msgstr "Etkin bildirime odaklanmak için klavye kısayolu"
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:149
|
||||
#: data/org.gnome.shell.gschema.xml.in:160
|
||||
msgid "Keybinding to focus the active notification."
|
||||
msgstr "Etkin bildirime odaklanmak için klavye kısayolu."
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:155
|
||||
#: data/org.gnome.shell.gschema.xml.in:166
|
||||
msgid "Switch to application 1"
|
||||
msgstr "Uygulama 1ʼe geç"
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:159
|
||||
#: data/org.gnome.shell.gschema.xml.in:170
|
||||
msgid "Switch to application 2"
|
||||
msgstr "Uygulama 2ʼye geç"
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:163
|
||||
#: data/org.gnome.shell.gschema.xml.in:174
|
||||
msgid "Switch to application 3"
|
||||
msgstr "Uygulama 3ʼe geç"
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:167
|
||||
#: data/org.gnome.shell.gschema.xml.in:178
|
||||
msgid "Switch to application 4"
|
||||
msgstr "Uygulama 4ʼe geç"
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:171
|
||||
#: data/org.gnome.shell.gschema.xml.in:182
|
||||
msgid "Switch to application 5"
|
||||
msgstr "Uygulama 5ʼe geç"
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:175
|
||||
#: data/org.gnome.shell.gschema.xml.in:186
|
||||
msgid "Switch to application 6"
|
||||
msgstr "Uygulama 6ʼya geç"
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:179
|
||||
#: data/org.gnome.shell.gschema.xml.in:190
|
||||
msgid "Switch to application 7"
|
||||
msgstr "Uygulama 7ʼye geç"
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:183
|
||||
#: data/org.gnome.shell.gschema.xml.in:194
|
||||
msgid "Switch to application 8"
|
||||
msgstr "Uygulama 8ʼe geç"
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:187
|
||||
#: data/org.gnome.shell.gschema.xml.in:198
|
||||
msgid "Switch to application 9"
|
||||
msgstr "Uygulama 9ʼa geç"
|
||||
|
||||
#: 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 "Geçiş menüsünü geçerli çalışma alanıyla sınırla."
|
||||
|
||||
#: 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."
|
||||
@ -318,11 +334,11 @@ msgstr ""
|
||||
"uygulamalar geçiş menüsünde gösterilir. Aksi halde, tüm uygulamalar "
|
||||
"görünecektir."
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:214
|
||||
#: data/org.gnome.shell.gschema.xml.in:225
|
||||
msgid "The application icon mode."
|
||||
msgstr "Uygulama simge kipi."
|
||||
|
||||
#: 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-"
|
||||
@ -333,7 +349,7 @@ msgstr ""
|
||||
"only” (yalnızca uygulama simgesini gösterir) ya da “both” (her ikisi) "
|
||||
"değerleridir."
|
||||
|
||||
#: 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."
|
||||
@ -341,59 +357,59 @@ msgstr ""
|
||||
"Eğer bu seçenek etkinse, yalnızca geçerli çalışma alanındaki pencereler "
|
||||
"geçiş menüsünde gösterilir. Aksi halde, tüm pencereler görünecektir."
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:234
|
||||
#: data/org.gnome.shell.gschema.xml.in:245
|
||||
msgid "Locations"
|
||||
msgstr "Konumlar"
|
||||
|
||||
#: 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 "Dünya saatlerinde gösterilecek konumlar"
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:245
|
||||
#: data/org.gnome.shell.gschema.xml.in:256
|
||||
msgid "Automatic location"
|
||||
msgstr "Kendiliğinden konumlama"
|
||||
|
||||
#: 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 "Geçerli konumun getirilip getirilmeyeceğini belirler"
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:253
|
||||
#: data/org.gnome.shell.gschema.xml.in:264
|
||||
msgid "Location"
|
||||
msgstr "Konum"
|
||||
|
||||
#: 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 "Hava durumunun gösterileceği konum"
|
||||
|
||||
#: 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 "Yardımcı iletişim penceresini üst pencereye iliştir"
|
||||
|
||||
#: 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 ""
|
||||
"Bu anahtar, GNOME Shell çalışırken org.gnome.mutter içindeki anahtarı "
|
||||
"geçersiz kılar."
|
||||
|
||||
#: 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 ""
|
||||
"Pencereler ekran kenarlarında bırakıldığında kenar döşemeyi etkinleştir"
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:283
|
||||
#: data/org.gnome.shell.gschema.xml.in:294
|
||||
msgid "Workspaces are managed dynamically"
|
||||
msgstr "Çalışma alanları dinamik olarak yönetilir"
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:291
|
||||
#: data/org.gnome.shell.gschema.xml.in:302
|
||||
msgid "Workspaces only on primary monitor"
|
||||
msgstr "Çalışma alanları yalnızca birincil ekranda"
|
||||
|
||||
#: 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 ""
|
||||
"Fare kipinde odak değişikliklerini işaretçi hareketi durana kadar beklet"
|
||||
@ -430,7 +446,7 @@ msgstr "Uzantı ana sayfasını ziyaret et"
|
||||
|
||||
#: 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:181
|
||||
#: js/ui/endSessionDialog.js:369 js/ui/extensionDownloader.js:183
|
||||
#: js/ui/shellMountOperation.js:376 js/ui/shellMountOperation.js:386
|
||||
#: js/ui/status/network.js:916 subprojects/extensions-app/js/main.js:149
|
||||
msgid "Cancel"
|
||||
@ -468,11 +484,11 @@ msgstr "(örneğin, kullanıcı veya %s)"
|
||||
msgid "Username"
|
||||
msgstr "Kullanıcı Adı"
|
||||
|
||||
#: js/gdm/loginDialog.js:1254
|
||||
#: js/gdm/loginDialog.js:1253
|
||||
msgid "Login Window"
|
||||
msgstr "Oturum Açma Penceresi"
|
||||
|
||||
#: js/gdm/util.js:345
|
||||
#: js/gdm/util.js:355
|
||||
msgid "Authentication error"
|
||||
msgstr "Kimlik doğrulama hatası"
|
||||
|
||||
@ -481,7 +497,7 @@ msgstr "Kimlik doğrulama hatası"
|
||||
#. as a cue to display our own message.
|
||||
#. Translators: this message is shown below the password entry field
|
||||
#. to indicate the user can swipe their finger instead
|
||||
#: js/gdm/util.js:471
|
||||
#: js/gdm/util.js:481
|
||||
msgid "(or swipe finger)"
|
||||
msgstr "(ya da parmak izi okut)"
|
||||
|
||||
@ -586,7 +602,7 @@ msgid "%d hour ago"
|
||||
msgid_plural "%d hours ago"
|
||||
msgstr[0] "%d saat önce"
|
||||
|
||||
#: js/misc/util.js:191
|
||||
#: js/misc/util.js:191 js/ui/dateMenu.js:162
|
||||
msgid "Yesterday"
|
||||
msgstr "Dün"
|
||||
|
||||
@ -702,56 +718,44 @@ msgstr ""
|
||||
|
||||
#. No support for non-modal system dialogs, so ignore the option
|
||||
#. let modal = options['modal'] || true;
|
||||
#: js/ui/accessDialog.js:39 js/ui/status/location.js:374
|
||||
#: js/ui/accessDialog.js:39 js/ui/status/location.js:369
|
||||
msgid "Deny Access"
|
||||
msgstr "Erişimi Reddet"
|
||||
|
||||
#: js/ui/accessDialog.js:40 js/ui/status/location.js:377
|
||||
#: js/ui/accessDialog.js:40 js/ui/status/location.js:372
|
||||
msgid "Grant Access"
|
||||
msgstr "Erişime İzin Ver"
|
||||
|
||||
#: js/ui/appDisplay.js:944
|
||||
#: js/ui/appDisplay.js:1297
|
||||
msgid "Unnamed Folder"
|
||||
msgstr "Adsız Klasör"
|
||||
|
||||
#: js/ui/appDisplay.js:967
|
||||
msgid "Frequently used applications will appear here"
|
||||
msgstr "Sık kullanılan uygulamalar burada yer alacak"
|
||||
|
||||
#: js/ui/appDisplay.js:1102
|
||||
msgid "Frequent"
|
||||
msgstr "Sık Sık"
|
||||
|
||||
#: js/ui/appDisplay.js:1109
|
||||
msgid "All"
|
||||
msgstr "Tümü"
|
||||
|
||||
#. Translators: This is the heading of a list of open windows
|
||||
#: js/ui/appDisplay.js:2486 js/ui/panel.js:75
|
||||
#: js/ui/appDisplay.js:2767 js/ui/panel.js:75
|
||||
msgid "Open Windows"
|
||||
msgstr "Açık Pencereler"
|
||||
|
||||
#: js/ui/appDisplay.js:2505 js/ui/panel.js:82
|
||||
#: js/ui/appDisplay.js:2786 js/ui/panel.js:82
|
||||
msgid "New Window"
|
||||
msgstr "Yeni Pencere"
|
||||
|
||||
#: js/ui/appDisplay.js:2521
|
||||
#: js/ui/appDisplay.js:2802
|
||||
msgid "Launch using Integrated Graphics Card"
|
||||
msgstr "Tümleşik Ekran Kartıyla Başlat"
|
||||
|
||||
#: js/ui/appDisplay.js:2522
|
||||
#: js/ui/appDisplay.js:2803
|
||||
msgid "Launch using Discrete Graphics Card"
|
||||
msgstr "Ayrık Ekran Kartıyla Başlat"
|
||||
|
||||
#: js/ui/appDisplay.js:2550 js/ui/dash.js:239
|
||||
#: js/ui/appDisplay.js:2831 js/ui/dash.js:239
|
||||
msgid "Remove from Favorites"
|
||||
msgstr "Sık Kullanılanlardan Çıkar"
|
||||
|
||||
#: js/ui/appDisplay.js:2556
|
||||
#: js/ui/appDisplay.js:2837
|
||||
msgid "Add to Favorites"
|
||||
msgstr "Sık Kullanılanlara Ekle"
|
||||
|
||||
#: js/ui/appDisplay.js:2566 js/ui/panel.js:93
|
||||
#: js/ui/appDisplay.js:2847 js/ui/panel.js:93
|
||||
msgid "Show Details"
|
||||
msgstr "Ayrıntıları Göster"
|
||||
|
||||
@ -781,7 +785,7 @@ msgstr "Kulaklıklar"
|
||||
msgid "Headset"
|
||||
msgstr "Kulaklıklı Mikrofon"
|
||||
|
||||
#: js/ui/audioDeviceSelection.js:68 js/ui/status/volume.js:270
|
||||
#: js/ui/audioDeviceSelection.js:68 js/ui/status/volume.js:272
|
||||
msgid "Microphone"
|
||||
msgstr "Mikrofon"
|
||||
|
||||
@ -798,7 +802,7 @@ msgid "Settings"
|
||||
msgstr "Ayarlar"
|
||||
|
||||
#. Translators: Enter 0-6 (Sunday-Saturday) for non-work days. Examples: "0" (Sunday) "6" (Saturday) "06" (Sunday and Saturday).
|
||||
#: js/ui/calendar.js:41
|
||||
#: js/ui/calendar.js:36
|
||||
msgctxt "calendar-no-work"
|
||||
msgid "06"
|
||||
msgstr "06"
|
||||
@ -808,43 +812,43 @@ msgstr "06"
|
||||
#. * NOTE: These grid abbreviations are always shown together
|
||||
#. * and in order, e.g. "S M T W T F S".
|
||||
#.
|
||||
#: js/ui/calendar.js:70
|
||||
#: js/ui/calendar.js:65
|
||||
msgctxt "grid sunday"
|
||||
msgid "S"
|
||||
msgstr "P"
|
||||
|
||||
#. Translators: Calendar grid abbreviation for Monday
|
||||
#: js/ui/calendar.js:72
|
||||
#: js/ui/calendar.js:67
|
||||
msgctxt "grid monday"
|
||||
msgid "M"
|
||||
msgstr "P"
|
||||
|
||||
#. Translators: Calendar grid abbreviation for Tuesday
|
||||
#: js/ui/calendar.js:74
|
||||
#: js/ui/calendar.js:69
|
||||
msgctxt "grid tuesday"
|
||||
msgid "T"
|
||||
msgstr "S"
|
||||
|
||||
#. Translators: Calendar grid abbreviation for Wednesday
|
||||
#: js/ui/calendar.js:76
|
||||
#: js/ui/calendar.js:71
|
||||
msgctxt "grid wednesday"
|
||||
msgid "W"
|
||||
msgstr "Ç"
|
||||
|
||||
#. Translators: Calendar grid abbreviation for Thursday
|
||||
#: js/ui/calendar.js:78
|
||||
#: js/ui/calendar.js:73
|
||||
msgctxt "grid thursday"
|
||||
msgid "T"
|
||||
msgstr "P"
|
||||
|
||||
#. Translators: Calendar grid abbreviation for Friday
|
||||
#: js/ui/calendar.js:80
|
||||
#: js/ui/calendar.js:75
|
||||
msgctxt "grid friday"
|
||||
msgid "F"
|
||||
msgstr "C"
|
||||
|
||||
#. Translators: Calendar grid abbreviation for Saturday
|
||||
#: js/ui/calendar.js:82
|
||||
#: js/ui/calendar.js:77
|
||||
msgctxt "grid saturday"
|
||||
msgid "S"
|
||||
msgstr "C"
|
||||
@ -855,7 +859,7 @@ msgstr "C"
|
||||
#. * "%OB" is the new format specifier introduced in glibc 2.27,
|
||||
#. * in most cases you should not change it.
|
||||
#.
|
||||
#: js/ui/calendar.js:397
|
||||
#: js/ui/calendar.js:392
|
||||
msgid "%OB"
|
||||
msgstr "%OB"
|
||||
|
||||
@ -868,61 +872,37 @@ msgstr "%OB"
|
||||
#. * in most cases you should not use the old "%B" here unless you
|
||||
#. * absolutely know what you are doing.
|
||||
#.
|
||||
#: js/ui/calendar.js:407
|
||||
#: js/ui/calendar.js:402
|
||||
msgid "%OB %Y"
|
||||
msgstr "%OB %Y"
|
||||
|
||||
#: js/ui/calendar.js:466
|
||||
#: js/ui/calendar.js:461
|
||||
msgid "Previous month"
|
||||
msgstr "Önceki ay"
|
||||
|
||||
#: js/ui/calendar.js:481
|
||||
#: js/ui/calendar.js:476
|
||||
msgid "Next month"
|
||||
msgstr "Gelecek ay"
|
||||
|
||||
#: js/ui/calendar.js:631
|
||||
#: js/ui/calendar.js:626
|
||||
#, no-javascript-format
|
||||
msgctxt "date day number format"
|
||||
msgid "%d"
|
||||
msgstr "%d"
|
||||
|
||||
#: js/ui/calendar.js:687
|
||||
#: js/ui/calendar.js:682
|
||||
msgid "Week %V"
|
||||
msgstr "%V. Hafta"
|
||||
|
||||
#. Translators: Shown in calendar event list for all day events
|
||||
#. * Keep it short, best if you can use less then 10 characters
|
||||
#.
|
||||
#: js/ui/calendar.js:762
|
||||
msgctxt "event list time"
|
||||
msgid "All Day"
|
||||
msgstr "Tüm Gün"
|
||||
|
||||
#. Translators: Shown on calendar heading when selected day occurs on current year
|
||||
#: js/ui/calendar.js:900
|
||||
msgctxt "calendar heading"
|
||||
msgid "%A, %B %-d"
|
||||
msgstr "%A, %-d %B"
|
||||
|
||||
#. Translators: Shown on calendar heading when selected day occurs on different year
|
||||
#: js/ui/calendar.js:903
|
||||
msgctxt "calendar heading"
|
||||
msgid "%A, %B %-d, %Y"
|
||||
msgstr "%A, %-d %B, %Y"
|
||||
|
||||
#: js/ui/calendar.js:1133
|
||||
#: js/ui/calendar.js:895
|
||||
msgid "No Notifications"
|
||||
msgstr "Bildirim Yok"
|
||||
|
||||
#: js/ui/calendar.js:1136
|
||||
msgid "No Events"
|
||||
msgstr "Olay Yok"
|
||||
|
||||
#: js/ui/calendar.js:1190
|
||||
#: js/ui/calendar.js:949
|
||||
msgid "Do Not Disturb"
|
||||
msgstr "Rahatsız Etme"
|
||||
|
||||
#: js/ui/calendar.js:1209
|
||||
#: js/ui/calendar.js:968
|
||||
msgid "Clear"
|
||||
msgstr "Temizle"
|
||||
|
||||
@ -1076,7 +1056,7 @@ msgstr "Üzgünüm ama işe yaramadı. Lütfen yeniden deneyin."
|
||||
msgid "%s is now known as %s"
|
||||
msgstr "%s, şimdi %s olarak biliniyor"
|
||||
|
||||
#: js/ui/ctrlAltTab.js:21 js/ui/viewSelector.js:177
|
||||
#: js/ui/ctrlAltTab.js:21 js/ui/viewSelector.js:178
|
||||
msgid "Windows"
|
||||
msgstr "Pencereler"
|
||||
|
||||
@ -1095,7 +1075,7 @@ msgstr "Konsol"
|
||||
#. * "Tue 9:29 AM"). The string itself should become a full date, e.g.,
|
||||
#. * "February 17 2015".
|
||||
#.
|
||||
#: js/ui/dateMenu.js:75
|
||||
#: js/ui/dateMenu.js:79
|
||||
msgid "%B %-d %Y"
|
||||
msgstr "%-d %B %Y"
|
||||
|
||||
@ -1103,35 +1083,67 @@ msgstr "%-d %B %Y"
|
||||
#. * below the time in the shell; it should combine the weekday and the
|
||||
#. * date, e.g. "Tuesday February 17 2015".
|
||||
#.
|
||||
#: js/ui/dateMenu.js:82
|
||||
#: js/ui/dateMenu.js:86
|
||||
msgid "%A %B %e %Y"
|
||||
msgstr "%e %B %Y %A"
|
||||
|
||||
#: js/ui/dateMenu.js:161
|
||||
#. Translators: Shown on calendar heading when selected day occurs on current year
|
||||
#: js/ui/dateMenu.js:151
|
||||
msgctxt "calendar heading"
|
||||
msgid "%B %-d"
|
||||
msgstr "%-d %B"
|
||||
|
||||
#. Translators: Shown on calendar heading when selected day occurs on different year
|
||||
#: js/ui/dateMenu.js:154
|
||||
msgctxt "calendar heading"
|
||||
msgid "%B %-d %Y"
|
||||
msgstr "%-d %B %Y"
|
||||
|
||||
#: js/ui/dateMenu.js:160
|
||||
msgid "Today"
|
||||
msgstr "Bugün"
|
||||
|
||||
#: js/ui/dateMenu.js:164
|
||||
msgid "Tomorrow"
|
||||
msgstr "Yarın"
|
||||
|
||||
#. Translators: Shown in calendar event list for all day events
|
||||
#. * Keep it short, best if you can use less then 10 characters
|
||||
#.
|
||||
#: js/ui/dateMenu.js:180
|
||||
msgctxt "event list time"
|
||||
msgid "All Day"
|
||||
msgstr "Tüm Gün"
|
||||
|
||||
#: js/ui/dateMenu.js:231
|
||||
msgid "No Events"
|
||||
msgstr "Olay Yok"
|
||||
|
||||
#: js/ui/dateMenu.js:348
|
||||
msgid "Add world clocks…"
|
||||
msgstr "Dünya saatlerini ekle…"
|
||||
|
||||
#: js/ui/dateMenu.js:162
|
||||
#: js/ui/dateMenu.js:349
|
||||
msgid "World Clocks"
|
||||
msgstr "Dünya Saatleri"
|
||||
|
||||
#: js/ui/dateMenu.js:424
|
||||
#: js/ui/dateMenu.js:629
|
||||
msgid "Loading…"
|
||||
msgstr "Yükleniyor…"
|
||||
|
||||
#: js/ui/dateMenu.js:434
|
||||
#: js/ui/dateMenu.js:639
|
||||
msgid "Go online for weather information"
|
||||
msgstr "Hava durumu bilgisi için çevrim içi olun"
|
||||
|
||||
#: js/ui/dateMenu.js:436
|
||||
#: js/ui/dateMenu.js:641
|
||||
msgid "Weather information is currently unavailable"
|
||||
msgstr "Hava durumu bilgisi şu anda kullanılabilir değil"
|
||||
|
||||
#: js/ui/dateMenu.js:446
|
||||
#: js/ui/dateMenu.js:651
|
||||
msgid "Weather"
|
||||
msgstr "Hava Durumu"
|
||||
|
||||
#: js/ui/dateMenu.js:448
|
||||
#: js/ui/dateMenu.js:653
|
||||
msgid "Select weather location…"
|
||||
msgstr "Hava durumu konumu seç…"
|
||||
|
||||
@ -1277,24 +1289,24 @@ msgstr "%s (uzak)"
|
||||
msgid "%s (console)"
|
||||
msgstr "%s (uçbirim)"
|
||||
|
||||
#: js/ui/extensionDownloader.js:185
|
||||
#: js/ui/extensionDownloader.js:187
|
||||
msgid "Install"
|
||||
msgstr "Kur"
|
||||
|
||||
#: js/ui/extensionDownloader.js:191
|
||||
#: js/ui/extensionDownloader.js:193
|
||||
msgid "Install Extension"
|
||||
msgstr "Uzantı Yükle"
|
||||
|
||||
#: js/ui/extensionDownloader.js:192
|
||||
#: js/ui/extensionDownloader.js:194
|
||||
#, javascript-format
|
||||
msgid "Download and install “%s” from extensions.gnome.org?"
|
||||
msgstr "extensions.gnome.org üstünden “%s” uzantısı indirilip kurulsun mu?"
|
||||
|
||||
#: js/ui/extensionSystem.js:251
|
||||
#: js/ui/extensionSystem.js:252
|
||||
msgid "Extension Updates Available"
|
||||
msgstr "Uzantı Güncellemeleri Var"
|
||||
|
||||
#: js/ui/extensionSystem.js:252
|
||||
#: js/ui/extensionSystem.js:253
|
||||
msgid "Extension updates are ready to be installed."
|
||||
msgstr "Uzantı güncellemeleri kuruluma hazır."
|
||||
|
||||
@ -1318,11 +1330,11 @@ msgstr "Bir uygulama, kısayolları baskılamak istiyor"
|
||||
msgid "You can restore shortcuts by pressing %s."
|
||||
msgstr "%s kısayoluyla, kısayolları geri yükleyebilirsiniz."
|
||||
|
||||
#: js/ui/inhibitShortcutsDialog.js:98
|
||||
#: js/ui/inhibitShortcutsDialog.js:100
|
||||
msgid "Deny"
|
||||
msgstr "Reddet"
|
||||
|
||||
#: js/ui/inhibitShortcutsDialog.js:105
|
||||
#: js/ui/inhibitShortcutsDialog.js:107
|
||||
msgid "Allow"
|
||||
msgstr "İzin ver"
|
||||
|
||||
@ -1388,7 +1400,7 @@ msgstr "Kapat"
|
||||
msgid "Leave Off"
|
||||
msgstr "Kapalı Bırak"
|
||||
|
||||
#: js/ui/keyboard.js:207
|
||||
#: js/ui/keyboard.js:225
|
||||
msgid "Region & Language Settings"
|
||||
msgstr "Bölge ve Dil Ayarları"
|
||||
|
||||
@ -1421,6 +1433,7 @@ msgid "Disabled"
|
||||
msgstr "Devre dışı"
|
||||
|
||||
#: js/ui/lookingGlass.js:743
|
||||
#: subprojects/extensions-app/data/ui/extension-row.ui:188
|
||||
msgid "Error"
|
||||
msgstr "Hata"
|
||||
|
||||
@ -1460,25 +1473,25 @@ msgstr "Ekran Kilidi devre dışı"
|
||||
msgid "Screen Locking requires the GNOME display manager."
|
||||
msgstr "Ekran Kilitleme, GNOME ekran yöneticisi gerektirir."
|
||||
|
||||
#: js/ui/messageTray.js:1547
|
||||
#: js/ui/messageTray.js:1476
|
||||
msgid "System Information"
|
||||
msgstr "Sistem Bilgisi"
|
||||
|
||||
#: js/ui/mpris.js:204
|
||||
#: js/ui/mpris.js:203
|
||||
msgid "Unknown artist"
|
||||
msgstr "Bilinmeyen sanatçı"
|
||||
|
||||
#: js/ui/mpris.js:214
|
||||
#: js/ui/mpris.js:213
|
||||
msgid "Unknown title"
|
||||
msgstr "Bilinmeyen başlık"
|
||||
|
||||
#: js/ui/overview.js:73
|
||||
#: js/ui/overview.js:74
|
||||
msgid "Undo"
|
||||
msgstr "Geri Al"
|
||||
|
||||
#. Translators: This is the main view to select
|
||||
#. activities. See also note for "Activities" string.
|
||||
#: js/ui/overview.js:86
|
||||
#: js/ui/overview.js:87
|
||||
msgid "Overview"
|
||||
msgstr "Genel Görünüm"
|
||||
|
||||
@ -1486,7 +1499,7 @@ msgstr "Genel Görünüm"
|
||||
#. in the search entry when no search is
|
||||
#. active; it should not exceed ~30
|
||||
#. characters.
|
||||
#: js/ui/overview.js:107
|
||||
#: js/ui/overview.js:108
|
||||
msgid "Type to search"
|
||||
msgstr "Aramak için yaz"
|
||||
|
||||
@ -1514,23 +1527,23 @@ msgstr "Tuş vuruşu ata"
|
||||
msgid "Done"
|
||||
msgstr "Bitti"
|
||||
|
||||
#: js/ui/padOsd.js:745
|
||||
#: js/ui/padOsd.js:732
|
||||
msgid "Edit…"
|
||||
msgstr "Düzenle…"
|
||||
|
||||
#: js/ui/padOsd.js:787 js/ui/padOsd.js:910
|
||||
#: js/ui/padOsd.js:774 js/ui/padOsd.js:891
|
||||
msgid "None"
|
||||
msgstr "Yok"
|
||||
|
||||
#: js/ui/padOsd.js:863
|
||||
#: js/ui/padOsd.js:845
|
||||
msgid "Press a button to configure"
|
||||
msgstr "Yapılandırmak için düğmeye bas"
|
||||
|
||||
#: js/ui/padOsd.js:864
|
||||
#: js/ui/padOsd.js:846
|
||||
msgid "Press Esc to exit"
|
||||
msgstr "Çıkmak için Esc’ye bas"
|
||||
|
||||
#: js/ui/padOsd.js:867
|
||||
#: js/ui/padOsd.js:849
|
||||
msgid "Press any key to exit"
|
||||
msgstr "Çıkmak için herhangi bir tuşa bas"
|
||||
|
||||
@ -1588,15 +1601,15 @@ msgstr "Kilitlenemedi"
|
||||
msgid "Lock was blocked by an application"
|
||||
msgstr "Kilitleme bir uygulama tarafından engellendi"
|
||||
|
||||
#: js/ui/search.js:702
|
||||
#: js/ui/search.js:823
|
||||
msgid "Searching…"
|
||||
msgstr "Aranıyor…"
|
||||
|
||||
#: js/ui/search.js:704
|
||||
#: js/ui/search.js:825
|
||||
msgid "No results."
|
||||
msgstr "Sonuç yok."
|
||||
|
||||
#: js/ui/search.js:830
|
||||
#: js/ui/search.js:951
|
||||
#, javascript-format
|
||||
msgid "%d more"
|
||||
msgid_plural "%d more"
|
||||
@ -1793,17 +1806,17 @@ msgstr "Konum Devre Dışı"
|
||||
msgid "Enable"
|
||||
msgstr "Etkinleştir"
|
||||
|
||||
#: js/ui/status/location.js:355
|
||||
#: js/ui/status/location.js:350
|
||||
msgid "Allow location access"
|
||||
msgstr "Konum erişimine izin ver"
|
||||
|
||||
#. Translators: %s is an application name
|
||||
#: js/ui/status/location.js:357
|
||||
#: js/ui/status/location.js:352
|
||||
#, javascript-format
|
||||
msgid "The app %s wants to access your location"
|
||||
msgstr "%s uygulaması konumunuza erişmek istiyor"
|
||||
|
||||
#: js/ui/status/location.js:367
|
||||
#: js/ui/status/location.js:362
|
||||
msgid "Location access can be changed at any time from the privacy settings."
|
||||
msgstr "Konum erişimi, gizlilik ayarlarından her zaman değiştirilebilir."
|
||||
|
||||
@ -2134,11 +2147,11 @@ msgstr "Thunderbolt yetkilendirme hatası"
|
||||
msgid "Could not authorize the Thunderbolt device: %s"
|
||||
msgstr "Thunderbolt aygıtı yetkilendirilemedi: %s"
|
||||
|
||||
#: js/ui/status/volume.js:151
|
||||
#: js/ui/status/volume.js:155
|
||||
msgid "Volume changed"
|
||||
msgstr "Bölüm değişti"
|
||||
|
||||
#: js/ui/status/volume.js:222
|
||||
#: js/ui/status/volume.js:217
|
||||
msgid "Volume"
|
||||
msgstr "Bölüm"
|
||||
|
||||
@ -2184,19 +2197,19 @@ msgstr "Kilidi açmak için yukarı kaydır"
|
||||
msgid "Click or press a key to unlock"
|
||||
msgstr "Kilidi açmak için tıklayın veya tuşa basın"
|
||||
|
||||
#: js/ui/unlockDialog.js:550
|
||||
#: js/ui/unlockDialog.js:555
|
||||
msgid "Unlock Window"
|
||||
msgstr "Kilit Açma Penceresi"
|
||||
|
||||
#: js/ui/unlockDialog.js:559
|
||||
#: js/ui/unlockDialog.js:564
|
||||
msgid "Log in as another user"
|
||||
msgstr "Başka kullanıcı olarak oturum aç"
|
||||
|
||||
#: js/ui/viewSelector.js:181
|
||||
#: js/ui/viewSelector.js:182
|
||||
msgid "Applications"
|
||||
msgstr "Uygulamalar"
|
||||
|
||||
#: js/ui/viewSelector.js:185
|
||||
#: js/ui/viewSelector.js:186
|
||||
msgid "Search"
|
||||
msgstr "Ara"
|
||||
|
||||
@ -2322,12 +2335,12 @@ msgstr "Oturum açma ekranı için -“gdm” gibi- özel kip kullan"
|
||||
msgid "List possible modes"
|
||||
msgstr "Olası kipleri listele"
|
||||
|
||||
#: src/shell-app.c:286
|
||||
#: src/shell-app.c:268
|
||||
msgctxt "program"
|
||||
msgid "Unknown"
|
||||
msgstr "Bilinmeyen"
|
||||
|
||||
#: src/shell-app.c:537
|
||||
#: src/shell-app.c:519
|
||||
#, c-format
|
||||
msgid "Failed to launch “%s”"
|
||||
msgstr "“%s” başlatılamadı"
|
||||
@ -2402,26 +2415,34 @@ msgid "%d extension will be updated on next login."
|
||||
msgid_plural "%d extensions will be updated on next login."
|
||||
msgstr[0] "%d uzantı sonraki girişte güncellenecek."
|
||||
|
||||
#: subprojects/extensions-app/data/ui/extension-row.ui:100
|
||||
#: subprojects/extensions-tool/src/command-create.c:301
|
||||
#: subprojects/extensions-app/js/main.js:461
|
||||
msgid "The extension is incompatible with the current GNOME version"
|
||||
msgstr "Uzantı, geçerli GNOME sürümüyle uyumsuz"
|
||||
|
||||
#: subprojects/extensions-app/js/main.js:464
|
||||
msgid "The extension had an error"
|
||||
msgstr "Uzantıda hata oluştu"
|
||||
|
||||
#: subprojects/extensions-app/data/ui/extension-row.ui:109
|
||||
#: subprojects/extensions-tool/src/command-create.c:325
|
||||
#: subprojects/extensions-tool/src/main.c:241
|
||||
msgid "Description"
|
||||
msgstr "Açıklama"
|
||||
|
||||
#: subprojects/extensions-app/data/ui/extension-row.ui:123
|
||||
#: subprojects/extensions-app/data/ui/extension-row.ui:132
|
||||
#: subprojects/extensions-tool/src/main.c:253
|
||||
msgid "Version"
|
||||
msgstr "Sürüm"
|
||||
|
||||
#: subprojects/extensions-app/data/ui/extension-row.ui:151
|
||||
#: subprojects/extensions-app/data/ui/extension-row.ui:160
|
||||
msgid "Author"
|
||||
msgstr "Yazar"
|
||||
|
||||
#: subprojects/extensions-app/data/ui/extension-row.ui:175
|
||||
#: subprojects/extensions-app/data/ui/extension-row.ui:216
|
||||
msgid "Website"
|
||||
msgstr "Web Sitesi"
|
||||
|
||||
#: subprojects/extensions-app/data/ui/extension-row.ui:192
|
||||
#: subprojects/extensions-app/data/ui/extension-row.ui:233
|
||||
msgid "Remove…"
|
||||
msgstr "Kaldır…"
|
||||
|
||||
@ -2483,12 +2504,12 @@ msgid "Log Out…"
|
||||
msgstr "Oturumu Kapat…"
|
||||
|
||||
#. Translators: a file path to an extension directory
|
||||
#: subprojects/extensions-tool/src/command-create.c:202
|
||||
#: subprojects/extensions-tool/src/command-create.c:226
|
||||
#, c-format
|
||||
msgid "The new extension was successfully created in %s.\n"
|
||||
msgstr "Yeni uzantı %s içinde oluşturuldu.\n"
|
||||
|
||||
#: subprojects/extensions-tool/src/command-create.c:275
|
||||
#: subprojects/extensions-tool/src/command-create.c:299
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Name should be a very short (ideally descriptive) string.\n"
|
||||
@ -2497,12 +2518,12 @@ msgstr ""
|
||||
"Ad çok kısa (ideal olarak açıklayıcı) dizge olmalıdır.\n"
|
||||
"Örnekler: %s"
|
||||
|
||||
#: subprojects/extensions-tool/src/command-create.c:281
|
||||
#: subprojects/extensions-tool/src/command-create.c:305
|
||||
#: subprojects/extensions-tool/src/main.c:238
|
||||
msgid "Name"
|
||||
msgstr "Ad"
|
||||
|
||||
#: subprojects/extensions-tool/src/command-create.c:295
|
||||
#: subprojects/extensions-tool/src/command-create.c:319
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Description is a single-sentence explanation of what your extension does.\n"
|
||||
@ -2511,7 +2532,7 @@ msgstr ""
|
||||
"Açıklama, uzantınızın ne yaptığı anlatan tek tümcelik tanımlamadır.\n"
|
||||
"Örnekler: %s"
|
||||
|
||||
#: subprojects/extensions-tool/src/command-create.c:315
|
||||
#: subprojects/extensions-tool/src/command-create.c:339
|
||||
msgid ""
|
||||
"UUID is a globally-unique identifier for your extension.\n"
|
||||
"This should be in the format of an email address (clicktofocus@janedoe."
|
||||
@ -2520,56 +2541,56 @@ msgstr ""
|
||||
"UUID, uzantınız için genel ve benzersiz tanımlayıcıdır.\n"
|
||||
"E-posta biçiminde olmalıdır (clicktofocus@janedoe.example.com)\n"
|
||||
|
||||
#: subprojects/extensions-tool/src/command-create.c:342
|
||||
#: subprojects/extensions-tool/src/command-create.c:366
|
||||
msgid "Choose one of the available templates:\n"
|
||||
msgstr "Uygun şablonlardan birini seçin:\n"
|
||||
|
||||
#: subprojects/extensions-tool/src/command-create.c:356
|
||||
#: subprojects/extensions-tool/src/command-create.c:380
|
||||
msgid "Template"
|
||||
msgstr "Şablon"
|
||||
|
||||
#: subprojects/extensions-tool/src/command-create.c:411
|
||||
#: subprojects/extensions-tool/src/command-create.c:435
|
||||
msgid "The unique identifier of the new extension"
|
||||
msgstr "Yeni uzantının eşsiz tanımlayıcısı"
|
||||
|
||||
#: subprojects/extensions-tool/src/command-create.c:414
|
||||
#: subprojects/extensions-tool/src/command-create.c:438
|
||||
msgid "NAME"
|
||||
msgstr "AD"
|
||||
|
||||
#: subprojects/extensions-tool/src/command-create.c:415
|
||||
#: subprojects/extensions-tool/src/command-create.c:439
|
||||
msgid "The user-visible name of the new extension"
|
||||
msgstr "Yeni uzantının kullanıcı tarafından görülebilir adı"
|
||||
|
||||
#: subprojects/extensions-tool/src/command-create.c:417
|
||||
#: subprojects/extensions-tool/src/command-create.c:441
|
||||
msgid "DESCRIPTION"
|
||||
msgstr "AÇIKLAMA"
|
||||
|
||||
#: subprojects/extensions-tool/src/command-create.c:419
|
||||
#: subprojects/extensions-tool/src/command-create.c:443
|
||||
msgid "A short description of what the extension does"
|
||||
msgstr "Uzantının ne yaptığına dair kısa açıklama"
|
||||
|
||||
#: subprojects/extensions-tool/src/command-create.c:422
|
||||
#: subprojects/extensions-tool/src/command-create.c:446
|
||||
msgid "TEMPLATE"
|
||||
msgstr "ŞABLON"
|
||||
|
||||
#: subprojects/extensions-tool/src/command-create.c:423
|
||||
#: subprojects/extensions-tool/src/command-create.c:447
|
||||
msgid "The template to use for the new extension"
|
||||
msgstr "Yeni uzantı için kullanılacak şablon"
|
||||
|
||||
#: subprojects/extensions-tool/src/command-create.c:429
|
||||
#: subprojects/extensions-tool/src/command-create.c:453
|
||||
msgid "Enter extension information interactively"
|
||||
msgstr "Uzantı bilgisini etkileşimli olarak gir"
|
||||
|
||||
#: subprojects/extensions-tool/src/command-create.c:437
|
||||
#: subprojects/extensions-tool/src/command-create.c:461
|
||||
msgid "Create a new extension"
|
||||
msgstr "Yeni uzantı oluştur"
|
||||
|
||||
#: subprojects/extensions-tool/src/command-create.c:455
|
||||
#: subprojects/extensions-tool/src/command-create.c:479
|
||||
#: subprojects/extensions-tool/src/command-list.c:172
|
||||
msgid "Unknown arguments"
|
||||
msgstr "Bilinmeyen argüman"
|
||||
|
||||
#: subprojects/extensions-tool/src/command-create.c:480
|
||||
#: subprojects/extensions-tool/src/command-create.c:504
|
||||
msgid "UUID, name and description are required"
|
||||
msgstr "UUID, ad ve açıklama gereklidir"
|
||||
|
||||
@ -2889,7 +2910,23 @@ msgstr[0] "%u Girdi"
|
||||
msgid "System Sounds"
|
||||
msgstr "Sistem Sesleri"
|
||||
|
||||
#, javascript-format
|
||||
#~ msgid "Frequently used applications will appear here"
|
||||
#~ msgstr "Sık kullanılan uygulamalar burada yer alacak"
|
||||
|
||||
#~ msgid "Frequent"
|
||||
#~ msgstr "Sık Sık"
|
||||
|
||||
#~ msgid "All"
|
||||
#~ msgstr "Tümü"
|
||||
|
||||
#~ msgctxt "calendar heading"
|
||||
#~ msgid "%A, %B %-d"
|
||||
#~ msgstr "%A, %-d %B"
|
||||
|
||||
#~ msgctxt "calendar heading"
|
||||
#~ msgid "%A, %B %-d, %Y"
|
||||
#~ msgstr "%A, %-d %B, %Y"
|
||||
|
||||
#~ msgid "%d Connected"
|
||||
#~ msgid_plural "%d Connected"
|
||||
#~ msgstr[0] "%d Aygıt Bağlandı"
|
||||
@ -3217,12 +3254,6 @@ msgstr "Sistem Sesleri"
|
||||
#~ msgid "Nothing Scheduled"
|
||||
#~ msgstr "Planınız Boş"
|
||||
|
||||
#~ msgid "Today"
|
||||
#~ msgstr "Bugün"
|
||||
|
||||
#~ msgid "Tomorrow"
|
||||
#~ msgstr "Yarın"
|
||||
|
||||
#~ msgid "This week"
|
||||
#~ msgstr "Bu hafta"
|
||||
|
||||
|
366
po/uk.po
366
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-05-21 23:22+0000\n"
|
||||
"PO-Revision-Date: 2020-05-22 08:44+0300\n"
|
||||
"POT-Creation-Date: 2020-07-20 16:18+0000\n"
|
||||
"PO-Revision-Date: 2020-07-21 08:42+0300\n"
|
||||
"Last-Translator: Yuri Chornoivan <yurchor@ukr.net>\n"
|
||||
"Language-Team: Ukrainian <kde-i18n-uk@kde.org>\n"
|
||||
"Language: uk\n"
|
||||
@ -216,89 +216,106 @@ msgid ""
|
||||
"shell."
|
||||
msgstr "Вмикає D-Bus API для самоаналізу стану оболонки."
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:119
|
||||
#: data/org.gnome.shell.gschema.xml.in:114
|
||||
msgid "Layout of the app picker"
|
||||
msgstr "Компонування засобу вибору програм"
|
||||
|
||||
#: 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 ""
|
||||
"Компонування засобу вибору програм. Кожен запис у цьому масиві є сторінкою."
|
||||
" Сторінки зберігаються у порядку, у якому їх буде показано у GNOME Shell."
|
||||
" Кожна сторінка містить пану записів “ідентифікатор програми” → 'дані'. У"
|
||||
" поточній версії як 'дані' може бути збережено такі значення: • “позиція”:"
|
||||
" позиція піктограми програми на сторінці"
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:130
|
||||
msgid "Keybinding to open the application menu"
|
||||
msgstr "Комбінація клавіш, щоб відкрити меню програм"
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:120
|
||||
#: data/org.gnome.shell.gschema.xml.in:131
|
||||
msgid "Keybinding to open the application menu."
|
||||
msgstr "Комбінація клавіш, щоб відкрити меню програм."
|
||||
|
||||
#: 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 "Комбінація клавіш, щоб «Показати програми»"
|
||||
|
||||
#: 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 "Комбінація клавіш, щоб «Показати програми» в огляді діяльності."
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:134
|
||||
#: data/org.gnome.shell.gschema.xml.in:145
|
||||
msgid "Keybinding to open the overview"
|
||||
msgstr "Комбінація клавіш, щоб відкрити огляд"
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:135
|
||||
#: data/org.gnome.shell.gschema.xml.in:146
|
||||
msgid "Keybinding to open the Activities Overview."
|
||||
msgstr "Комбінація клавіш, щоб відкрити огляд діяльності."
|
||||
|
||||
#: 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 "Комбінація клавіш, щоб змінювати видимість переліку сповіщень"
|
||||
|
||||
#: 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 "Комбінація клавіш, щоб змінювати видимість переліку сповіщень."
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:148
|
||||
#: data/org.gnome.shell.gschema.xml.in:159
|
||||
msgid "Keybinding to focus the active notification"
|
||||
msgstr "Комбінація клавіш, щоб перейти до активних сповіщень"
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:149
|
||||
#: data/org.gnome.shell.gschema.xml.in:160
|
||||
msgid "Keybinding to focus the active notification."
|
||||
msgstr "Комбінація клавіш, щоб перейти до активних сповіщень."
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:155
|
||||
#: data/org.gnome.shell.gschema.xml.in:166
|
||||
msgid "Switch to application 1"
|
||||
msgstr "Перемкнутися на програму 1"
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:159
|
||||
#: data/org.gnome.shell.gschema.xml.in:170
|
||||
msgid "Switch to application 2"
|
||||
msgstr "Перемкнутися на програму 2"
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:163
|
||||
#: data/org.gnome.shell.gschema.xml.in:174
|
||||
msgid "Switch to application 3"
|
||||
msgstr "Перемкнутися на програму 3"
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:167
|
||||
#: data/org.gnome.shell.gschema.xml.in:178
|
||||
msgid "Switch to application 4"
|
||||
msgstr "Перемкнутися на програму 4"
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:171
|
||||
#: data/org.gnome.shell.gschema.xml.in:182
|
||||
msgid "Switch to application 5"
|
||||
msgstr "Перемкнутися на програму 5"
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:175
|
||||
#: data/org.gnome.shell.gschema.xml.in:186
|
||||
msgid "Switch to application 6"
|
||||
msgstr "Перемкнутися на програму 6"
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:179
|
||||
#: data/org.gnome.shell.gschema.xml.in:190
|
||||
msgid "Switch to application 7"
|
||||
msgstr "Перемкнутися на програму 7"
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:183
|
||||
#: data/org.gnome.shell.gschema.xml.in:194
|
||||
msgid "Switch to application 8"
|
||||
msgstr "Перемкнутися на програму 8"
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:187
|
||||
#: data/org.gnome.shell.gschema.xml.in:198
|
||||
msgid "Switch to application 9"
|
||||
msgstr "Перемкнутися на програму 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 "Обмежити перемикач на поточний робочий простір."
|
||||
|
||||
#: 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."
|
||||
@ -306,11 +323,11 @@ msgstr ""
|
||||
"Якщо це вказано, то тільки програми з поточного робочого простору будуть "
|
||||
"показані в перемикачі. Інакше — програми з усіх просторів."
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:214
|
||||
#: data/org.gnome.shell.gschema.xml.in:225
|
||||
msgid "The application icon mode."
|
||||
msgstr "Режим піктограм для програм."
|
||||
|
||||
#: 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-"
|
||||
@ -320,7 +337,7 @@ msgstr ""
|
||||
"«thumbnail-only» (показує мініатюру вікна), «app-icon-only» (показує тільки "
|
||||
"піктограми програм) або «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."
|
||||
@ -328,57 +345,57 @@ msgstr ""
|
||||
"Якщо це вказано, то тільки вікна з поточного робочого простору будуть "
|
||||
"показані в перемикачі. Інакше — вікна з усіх просторів."
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:234
|
||||
#: data/org.gnome.shell.gschema.xml.in:245
|
||||
msgid "Locations"
|
||||
msgstr "Місцевості"
|
||||
|
||||
#: 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 "Місцевість для світового годинника"
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:245
|
||||
#: data/org.gnome.shell.gschema.xml.in:256
|
||||
msgid "Automatic location"
|
||||
msgstr "Автоматичне визначення місцевості"
|
||||
|
||||
#: 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 "Чи одержувати поточну локацію"
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:253
|
||||
#: data/org.gnome.shell.gschema.xml.in:264
|
||||
msgid "Location"
|
||||
msgstr "Місцевість"
|
||||
|
||||
#: 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 "Місцевість для прогнозу погоди"
|
||||
|
||||
#: 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 "Приєднати модальне вікно до батьківського вікна"
|
||||
|
||||
#: 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 ""
|
||||
"Цей ключ перевизначає ключ у org.gnome.mutter, коли запущено 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 "Увімкнути розбиття країв, коли кладуться вікна на краї екрана"
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:283
|
||||
#: data/org.gnome.shell.gschema.xml.in:294
|
||||
msgid "Workspaces are managed dynamically"
|
||||
msgstr "Робочі простори організовуються динамічно"
|
||||
|
||||
#: data/org.gnome.shell.gschema.xml.in:291
|
||||
#: data/org.gnome.shell.gschema.xml.in:302
|
||||
msgid "Workspaces only on primary monitor"
|
||||
msgstr "Робочий простір лише на основному моніторі"
|
||||
|
||||
#: 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 "Затримувати зміни фокусу миші, поки вказівник не перестане рухатись"
|
||||
|
||||
@ -414,7 +431,7 @@ 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:181
|
||||
#: js/ui/endSessionDialog.js:369 js/ui/extensionDownloader.js:183
|
||||
#: js/ui/shellMountOperation.js:376 js/ui/shellMountOperation.js:386
|
||||
#: js/ui/status/network.js:916 subprojects/extensions-app/js/main.js:149
|
||||
msgid "Cancel"
|
||||
@ -456,7 +473,7 @@ msgstr "Користувач"
|
||||
msgid "Login Window"
|
||||
msgstr "Вікно входу"
|
||||
|
||||
#: js/gdm/util.js:345
|
||||
#: js/gdm/util.js:355
|
||||
msgid "Authentication error"
|
||||
msgstr "Помилка розпізнавання"
|
||||
|
||||
@ -465,7 +482,7 @@ msgstr "Помилка розпізнавання"
|
||||
#. as a cue to display our own message.
|
||||
#. Translators: this message is shown below the password entry field
|
||||
#. to indicate the user can swipe their finger instead
|
||||
#: js/gdm/util.js:471
|
||||
#: js/gdm/util.js:481
|
||||
msgid "(or swipe finger)"
|
||||
msgstr "(або проведіть пальцем)"
|
||||
|
||||
@ -578,7 +595,7 @@ msgstr[1] "%d години тому"
|
||||
msgstr[2] "%d годин тому"
|
||||
msgstr[3] "%d година тому"
|
||||
|
||||
#: js/misc/util.js:191
|
||||
#: js/misc/util.js:191 js/ui/dateMenu.js:162
|
||||
msgid "Yesterday"
|
||||
msgstr "Учора"
|
||||
|
||||
@ -705,56 +722,44 @@ msgstr ""
|
||||
|
||||
#. No support for non-modal system dialogs, so ignore the option
|
||||
#. let modal = options['modal'] || true;
|
||||
#: js/ui/accessDialog.js:39 js/ui/status/location.js:374
|
||||
#: js/ui/accessDialog.js:39 js/ui/status/location.js:369
|
||||
msgid "Deny Access"
|
||||
msgstr "Заборонити доступ"
|
||||
|
||||
#: js/ui/accessDialog.js:40 js/ui/status/location.js:377
|
||||
#: js/ui/accessDialog.js:40 js/ui/status/location.js:372
|
||||
msgid "Grant Access"
|
||||
msgstr "Надати доступ"
|
||||
|
||||
#: js/ui/appDisplay.js:944
|
||||
#: js/ui/appDisplay.js:1297
|
||||
msgid "Unnamed Folder"
|
||||
msgstr "Неназвана тека"
|
||||
|
||||
#: js/ui/appDisplay.js:967
|
||||
msgid "Frequently used applications will appear here"
|
||||
msgstr "Часто використовувані програми будуть з'являтись тут"
|
||||
|
||||
#: js/ui/appDisplay.js:1102
|
||||
msgid "Frequent"
|
||||
msgstr "Частовживане"
|
||||
|
||||
#: js/ui/appDisplay.js:1109
|
||||
msgid "All"
|
||||
msgstr "Усе"
|
||||
|
||||
#. Translators: This is the heading of a list of open windows
|
||||
#: js/ui/appDisplay.js:2486 js/ui/panel.js:75
|
||||
#: js/ui/appDisplay.js:2767 js/ui/panel.js:75
|
||||
msgid "Open Windows"
|
||||
msgstr "Відкрити вікна"
|
||||
|
||||
#: js/ui/appDisplay.js:2505 js/ui/panel.js:82
|
||||
#: js/ui/appDisplay.js:2786 js/ui/panel.js:82
|
||||
msgid "New Window"
|
||||
msgstr "Нове вікно"
|
||||
|
||||
#: js/ui/appDisplay.js:2521
|
||||
#: js/ui/appDisplay.js:2802
|
||||
msgid "Launch using Integrated Graphics Card"
|
||||
msgstr "Запустити через інтегровану графічну плату"
|
||||
|
||||
#: js/ui/appDisplay.js:2522
|
||||
#: js/ui/appDisplay.js:2803
|
||||
msgid "Launch using Discrete Graphics Card"
|
||||
msgstr "Запустити через дискретну графічну плату"
|
||||
|
||||
#: js/ui/appDisplay.js:2550 js/ui/dash.js:239
|
||||
#: js/ui/appDisplay.js:2831 js/ui/dash.js:239
|
||||
msgid "Remove from Favorites"
|
||||
msgstr "Вилучити з улюбленого"
|
||||
|
||||
#: js/ui/appDisplay.js:2556
|
||||
#: js/ui/appDisplay.js:2837
|
||||
msgid "Add to Favorites"
|
||||
msgstr "Додати до улюбленого"
|
||||
|
||||
#: js/ui/appDisplay.js:2566 js/ui/panel.js:93
|
||||
#: js/ui/appDisplay.js:2847 js/ui/panel.js:93
|
||||
msgid "Show Details"
|
||||
msgstr "Показати подробиці"
|
||||
|
||||
@ -784,7 +789,7 @@ msgstr "Навушники"
|
||||
msgid "Headset"
|
||||
msgstr "Гарнітура"
|
||||
|
||||
#: js/ui/audioDeviceSelection.js:68 js/ui/status/volume.js:273
|
||||
#: js/ui/audioDeviceSelection.js:68 js/ui/status/volume.js:272
|
||||
msgid "Microphone"
|
||||
msgstr "Мікрофон"
|
||||
|
||||
@ -801,7 +806,7 @@ msgid "Settings"
|
||||
msgstr "Параметри"
|
||||
|
||||
#. Translators: Enter 0-6 (Sunday-Saturday) for non-work days. Examples: "0" (Sunday) "6" (Saturday) "06" (Sunday and Saturday).
|
||||
#: js/ui/calendar.js:41
|
||||
#: js/ui/calendar.js:36
|
||||
msgctxt "calendar-no-work"
|
||||
msgid "06"
|
||||
msgstr "06"
|
||||
@ -811,43 +816,43 @@ msgstr "06"
|
||||
#. * NOTE: These grid abbreviations are always shown together
|
||||
#. * and in order, e.g. "S M T W T F S".
|
||||
#.
|
||||
#: js/ui/calendar.js:70
|
||||
#: js/ui/calendar.js:65
|
||||
msgctxt "grid sunday"
|
||||
msgid "S"
|
||||
msgstr "Н"
|
||||
|
||||
#. Translators: Calendar grid abbreviation for Monday
|
||||
#: js/ui/calendar.js:72
|
||||
#: js/ui/calendar.js:67
|
||||
msgctxt "grid monday"
|
||||
msgid "M"
|
||||
msgstr "П"
|
||||
|
||||
#. Translators: Calendar grid abbreviation for Tuesday
|
||||
#: js/ui/calendar.js:74
|
||||
#: js/ui/calendar.js:69
|
||||
msgctxt "grid tuesday"
|
||||
msgid "T"
|
||||
msgstr "В"
|
||||
|
||||
#. Translators: Calendar grid abbreviation for Wednesday
|
||||
#: js/ui/calendar.js:76
|
||||
#: js/ui/calendar.js:71
|
||||
msgctxt "grid wednesday"
|
||||
msgid "W"
|
||||
msgstr "С"
|
||||
|
||||
#. Translators: Calendar grid abbreviation for Thursday
|
||||
#: js/ui/calendar.js:78
|
||||
#: js/ui/calendar.js:73
|
||||
msgctxt "grid thursday"
|
||||
msgid "T"
|
||||
msgstr "Ч"
|
||||
|
||||
#. Translators: Calendar grid abbreviation for Friday
|
||||
#: js/ui/calendar.js:80
|
||||
#: js/ui/calendar.js:75
|
||||
msgctxt "grid friday"
|
||||
msgid "F"
|
||||
msgstr "П"
|
||||
|
||||
#. Translators: Calendar grid abbreviation for Saturday
|
||||
#: js/ui/calendar.js:82
|
||||
#: js/ui/calendar.js:77
|
||||
msgctxt "grid saturday"
|
||||
msgid "S"
|
||||
msgstr "С"
|
||||
@ -858,7 +863,7 @@ msgstr "С"
|
||||
#. * "%OB" is the new format specifier introduced in glibc 2.27,
|
||||
#. * in most cases you should not change it.
|
||||
#.
|
||||
#: js/ui/calendar.js:397
|
||||
#: js/ui/calendar.js:392
|
||||
msgid "%OB"
|
||||
msgstr "%OB"
|
||||
|
||||
@ -871,61 +876,37 @@ msgstr "%OB"
|
||||
#. * in most cases you should not use the old "%B" here unless you
|
||||
#. * absolutely know what you are doing.
|
||||
#.
|
||||
#: js/ui/calendar.js:407
|
||||
#: js/ui/calendar.js:402
|
||||
msgid "%OB %Y"
|
||||
msgstr "%OB %Y"
|
||||
|
||||
#: js/ui/calendar.js:466
|
||||
#: js/ui/calendar.js:461
|
||||
msgid "Previous month"
|
||||
msgstr "Попередній місяць"
|
||||
|
||||
#: js/ui/calendar.js:481
|
||||
#: js/ui/calendar.js:476
|
||||
msgid "Next month"
|
||||
msgstr "Наступний місяць"
|
||||
|
||||
#: js/ui/calendar.js:631
|
||||
#: js/ui/calendar.js:626
|
||||
#, no-javascript-format
|
||||
msgctxt "date day number format"
|
||||
msgid "%d"
|
||||
msgstr "%d"
|
||||
|
||||
#: js/ui/calendar.js:687
|
||||
#: js/ui/calendar.js:682
|
||||
msgid "Week %V"
|
||||
msgstr "Тиждень %V"
|
||||
|
||||
#. Translators: Shown in calendar event list for all day events
|
||||
#. * Keep it short, best if you can use less then 10 characters
|
||||
#.
|
||||
#: js/ui/calendar.js:762
|
||||
msgctxt "event list time"
|
||||
msgid "All Day"
|
||||
msgstr "Увесь день"
|
||||
|
||||
#. Translators: Shown on calendar heading when selected day occurs on current year
|
||||
#: js/ui/calendar.js:900
|
||||
msgctxt "calendar heading"
|
||||
msgid "%A, %B %-d"
|
||||
msgstr "%A, %-d %B"
|
||||
|
||||
#. Translators: Shown on calendar heading when selected day occurs on different year
|
||||
#: js/ui/calendar.js:903
|
||||
msgctxt "calendar heading"
|
||||
msgid "%A, %B %-d, %Y"
|
||||
msgstr "%A, %-d %B, %Y"
|
||||
|
||||
#: js/ui/calendar.js:1133
|
||||
#: js/ui/calendar.js:895
|
||||
msgid "No Notifications"
|
||||
msgstr "Немає сповіщень"
|
||||
|
||||
#: js/ui/calendar.js:1136
|
||||
msgid "No Events"
|
||||
msgstr "Немає подій"
|
||||
|
||||
#: js/ui/calendar.js:1190
|
||||
#: js/ui/calendar.js:949
|
||||
msgid "Do Not Disturb"
|
||||
msgstr "Не турбувати"
|
||||
|
||||
#: js/ui/calendar.js:1209
|
||||
#: js/ui/calendar.js:968
|
||||
msgid "Clear"
|
||||
msgstr "Очистити"
|
||||
|
||||
@ -1076,7 +1057,7 @@ msgstr "Вибачте, це не спрацювало. Спробуйте ще.
|
||||
msgid "%s is now known as %s"
|
||||
msgstr "%s тепер відомий як %s"
|
||||
|
||||
#: js/ui/ctrlAltTab.js:21 js/ui/viewSelector.js:177
|
||||
#: js/ui/ctrlAltTab.js:21 js/ui/viewSelector.js:178
|
||||
msgid "Windows"
|
||||
msgstr "Вікна"
|
||||
|
||||
@ -1095,7 +1076,7 @@ msgstr "Риска"
|
||||
#. * "Tue 9:29 AM"). The string itself should become a full date, e.g.,
|
||||
#. * "February 17 2015".
|
||||
#.
|
||||
#: js/ui/dateMenu.js:75
|
||||
#: js/ui/dateMenu.js:79
|
||||
msgid "%B %-d %Y"
|
||||
msgstr "%-d %B %Y"
|
||||
|
||||
@ -1103,35 +1084,67 @@ msgstr "%-d %B %Y"
|
||||
#. * below the time in the shell; it should combine the weekday and the
|
||||
#. * date, e.g. "Tuesday February 17 2015".
|
||||
#.
|
||||
#: js/ui/dateMenu.js:82
|
||||
#: js/ui/dateMenu.js:86
|
||||
msgid "%A %B %e %Y"
|
||||
msgstr "%A %-d %B %Y"
|
||||
|
||||
#: js/ui/dateMenu.js:162
|
||||
#. Translators: Shown on calendar heading when selected day occurs on current year
|
||||
#: js/ui/dateMenu.js:151
|
||||
msgctxt "calendar heading"
|
||||
msgid "%B %-d"
|
||||
msgstr "%-d %B"
|
||||
|
||||
#. Translators: Shown on calendar heading when selected day occurs on different year
|
||||
#: js/ui/dateMenu.js:154
|
||||
msgctxt "calendar heading"
|
||||
msgid "%B %-d %Y"
|
||||
msgstr "%-d %B %Y"
|
||||
|
||||
#: js/ui/dateMenu.js:160
|
||||
msgid "Today"
|
||||
msgstr "Сьогодні"
|
||||
|
||||
#: js/ui/dateMenu.js:164
|
||||
msgid "Tomorrow"
|
||||
msgstr "Завтра"
|
||||
|
||||
#. Translators: Shown in calendar event list for all day events
|
||||
#. * Keep it short, best if you can use less then 10 characters
|
||||
#.
|
||||
#: js/ui/dateMenu.js:180
|
||||
msgctxt "event list time"
|
||||
msgid "All Day"
|
||||
msgstr "Увесь день"
|
||||
|
||||
#: js/ui/dateMenu.js:231
|
||||
msgid "No Events"
|
||||
msgstr "Немає подій"
|
||||
|
||||
#: js/ui/dateMenu.js:348
|
||||
msgid "Add world clocks…"
|
||||
msgstr "Додати світові годинники…"
|
||||
|
||||
#: js/ui/dateMenu.js:163
|
||||
#: js/ui/dateMenu.js:349
|
||||
msgid "World Clocks"
|
||||
msgstr "Світові годинники"
|
||||
|
||||
#: js/ui/dateMenu.js:443
|
||||
#: js/ui/dateMenu.js:629
|
||||
msgid "Loading…"
|
||||
msgstr "Завантаження…"
|
||||
|
||||
#: js/ui/dateMenu.js:453
|
||||
#: js/ui/dateMenu.js:639
|
||||
msgid "Go online for weather information"
|
||||
msgstr "Увійти в мережу за прогнозом погоди"
|
||||
|
||||
#: js/ui/dateMenu.js:455
|
||||
#: js/ui/dateMenu.js:641
|
||||
msgid "Weather information is currently unavailable"
|
||||
msgstr "Наразі інформації про погоду недоступна"
|
||||
|
||||
#: js/ui/dateMenu.js:465
|
||||
#: js/ui/dateMenu.js:651
|
||||
msgid "Weather"
|
||||
msgstr "Погода"
|
||||
|
||||
#: js/ui/dateMenu.js:467
|
||||
#: js/ui/dateMenu.js:653
|
||||
msgid "Select weather location…"
|
||||
msgstr "Виберіть місцевість для погоди…"
|
||||
|
||||
@ -1295,15 +1308,15 @@ msgstr "%s (віддалено)"
|
||||
msgid "%s (console)"
|
||||
msgstr "%s (консоль)"
|
||||
|
||||
#: js/ui/extensionDownloader.js:185
|
||||
#: js/ui/extensionDownloader.js:187
|
||||
msgid "Install"
|
||||
msgstr "Встановити"
|
||||
|
||||
#: js/ui/extensionDownloader.js:191
|
||||
#: js/ui/extensionDownloader.js:193
|
||||
msgid "Install Extension"
|
||||
msgstr "Встановити розширення"
|
||||
|
||||
#: js/ui/extensionDownloader.js:192
|
||||
#: js/ui/extensionDownloader.js:194
|
||||
#, javascript-format
|
||||
msgid "Download and install “%s” from extensions.gnome.org?"
|
||||
msgstr "Звантажити і встановити «%s» з extensions.gnome.org?"
|
||||
@ -1336,11 +1349,11 @@ msgstr "Програма бажає успадкувати скорочення"
|
||||
msgid "You can restore shortcuts by pressing %s."
|
||||
msgstr "Можна відновити скорочення, натиснувши %s."
|
||||
|
||||
#: js/ui/inhibitShortcutsDialog.js:98
|
||||
#: js/ui/inhibitShortcutsDialog.js:100
|
||||
msgid "Deny"
|
||||
msgstr "Заборонити"
|
||||
|
||||
#: js/ui/inhibitShortcutsDialog.js:105
|
||||
#: js/ui/inhibitShortcutsDialog.js:107
|
||||
msgid "Allow"
|
||||
msgstr "Дозволити"
|
||||
|
||||
@ -1406,7 +1419,7 @@ msgstr "Вимкнути"
|
||||
msgid "Leave Off"
|
||||
msgstr "Покинути"
|
||||
|
||||
#: js/ui/keyboard.js:207
|
||||
#: js/ui/keyboard.js:225
|
||||
msgid "Region & Language Settings"
|
||||
msgstr "Параметри регіону та мови"
|
||||
|
||||
@ -1479,25 +1492,25 @@ msgstr "Блокування екрана вимкнено"
|
||||
msgid "Screen Locking requires the GNOME display manager."
|
||||
msgstr "Блокування екрана потребує керування входом GNOME."
|
||||
|
||||
#: js/ui/messageTray.js:1547
|
||||
#: js/ui/messageTray.js:1476
|
||||
msgid "System Information"
|
||||
msgstr "Інформація про систему"
|
||||
|
||||
#: js/ui/mpris.js:204
|
||||
#: js/ui/mpris.js:203
|
||||
msgid "Unknown artist"
|
||||
msgstr "Невідомий виконавець"
|
||||
|
||||
#: js/ui/mpris.js:214
|
||||
#: js/ui/mpris.js:213
|
||||
msgid "Unknown title"
|
||||
msgstr "Невідома назва"
|
||||
|
||||
#: js/ui/overview.js:73
|
||||
#: js/ui/overview.js:74
|
||||
msgid "Undo"
|
||||
msgstr "Повернути"
|
||||
|
||||
#. Translators: This is the main view to select
|
||||
#. activities. See also note for "Activities" string.
|
||||
#: js/ui/overview.js:86
|
||||
#: js/ui/overview.js:87
|
||||
msgid "Overview"
|
||||
msgstr "Огляд"
|
||||
|
||||
@ -1505,7 +1518,7 @@ msgstr "Огляд"
|
||||
#. in the search entry when no search is
|
||||
#. active; it should not exceed ~30
|
||||
#. characters.
|
||||
#: js/ui/overview.js:107
|
||||
#: js/ui/overview.js:108
|
||||
msgid "Type to search"
|
||||
msgstr "Введіть текст для пошуку"
|
||||
|
||||
@ -1533,23 +1546,23 @@ msgstr "Призначити клавішу"
|
||||
msgid "Done"
|
||||
msgstr "Зроблено"
|
||||
|
||||
#: js/ui/padOsd.js:745
|
||||
#: js/ui/padOsd.js:732
|
||||
msgid "Edit…"
|
||||
msgstr "Редагувати…"
|
||||
|
||||
#: js/ui/padOsd.js:787 js/ui/padOsd.js:910
|
||||
#: js/ui/padOsd.js:774 js/ui/padOsd.js:891
|
||||
msgid "None"
|
||||
msgstr "Немає"
|
||||
|
||||
#: js/ui/padOsd.js:863
|
||||
#: js/ui/padOsd.js:845
|
||||
msgid "Press a button to configure"
|
||||
msgstr "Натисніть кнопку, щоб налаштувати"
|
||||
|
||||
#: js/ui/padOsd.js:864
|
||||
#: js/ui/padOsd.js:846
|
||||
msgid "Press Esc to exit"
|
||||
msgstr "Натисніть клавішу «Esc», щоб вийти"
|
||||
|
||||
#: js/ui/padOsd.js:867
|
||||
#: js/ui/padOsd.js:849
|
||||
msgid "Press any key to exit"
|
||||
msgstr "Натисніть будь-яку клавішу, щоб вийти"
|
||||
|
||||
@ -1813,17 +1826,17 @@ msgstr "Місцевість вимкнено"
|
||||
msgid "Enable"
|
||||
msgstr "Увімкнути"
|
||||
|
||||
#: js/ui/status/location.js:355
|
||||
#: js/ui/status/location.js:350
|
||||
msgid "Allow location access"
|
||||
msgstr "Дозволити доступ до даних перебування"
|
||||
|
||||
#. Translators: %s is an application name
|
||||
#: js/ui/status/location.js:357
|
||||
#: js/ui/status/location.js:352
|
||||
#, javascript-format
|
||||
msgid "The app %s wants to access your location"
|
||||
msgstr "Програмі %s потрібен доступ до даних щодо місця вашого перебування"
|
||||
|
||||
#: js/ui/status/location.js:367
|
||||
#: js/ui/status/location.js:362
|
||||
msgid "Location access can be changed at any time from the privacy settings."
|
||||
msgstr ""
|
||||
"Доступ до місця перебування можна змінити в будь-яку мить у параметрах "
|
||||
@ -2164,11 +2177,11 @@ msgstr "Помилка завірення Thunderbolt"
|
||||
msgid "Could not authorize the Thunderbolt device: %s"
|
||||
msgstr "Неможливо завірити пристрій Thunderbolt: %s"
|
||||
|
||||
#: js/ui/status/volume.js:154
|
||||
#: js/ui/status/volume.js:155
|
||||
msgid "Volume changed"
|
||||
msgstr "Гучність змінено"
|
||||
|
||||
#: js/ui/status/volume.js:225
|
||||
#: js/ui/status/volume.js:217
|
||||
msgid "Volume"
|
||||
msgstr "Гучність"
|
||||
|
||||
@ -2214,19 +2227,19 @@ msgstr "Проведіть вгору для розблокування"
|
||||
msgid "Click or press a key to unlock"
|
||||
msgstr "Клацніть або натисніть клавішу для розблокування"
|
||||
|
||||
#: js/ui/unlockDialog.js:550
|
||||
#: js/ui/unlockDialog.js:555
|
||||
msgid "Unlock Window"
|
||||
msgstr "Розблокувати вікно"
|
||||
|
||||
#: js/ui/unlockDialog.js:559
|
||||
#: js/ui/unlockDialog.js:564
|
||||
msgid "Log in as another user"
|
||||
msgstr "Увійти як інший користувач"
|
||||
|
||||
#: js/ui/viewSelector.js:181
|
||||
#: js/ui/viewSelector.js:182
|
||||
msgid "Applications"
|
||||
msgstr "Програми"
|
||||
|
||||
#: js/ui/viewSelector.js:185
|
||||
#: js/ui/viewSelector.js:186
|
||||
msgid "Search"
|
||||
msgstr "Пошук"
|
||||
|
||||
@ -2355,12 +2368,12 @@ msgstr "Використовувати вказаний режим, прикла
|
||||
msgid "List possible modes"
|
||||
msgstr "Перелік можливих режимів"
|
||||
|
||||
#: src/shell-app.c:286
|
||||
#: src/shell-app.c:268
|
||||
msgctxt "program"
|
||||
msgid "Unknown"
|
||||
msgstr "Невідомо"
|
||||
|
||||
#: src/shell-app.c:537
|
||||
#: src/shell-app.c:519
|
||||
#, c-format
|
||||
msgid "Failed to launch “%s”"
|
||||
msgstr "Не вдалося запустити «%s»"
|
||||
@ -2443,12 +2456,11 @@ msgid "The extension is incompatible with the current GNOME version"
|
||||
msgstr "Розширення є несумісним із поточною версією GNOME"
|
||||
|
||||
#: subprojects/extensions-app/js/main.js:464
|
||||
#| msgid "Show extension info"
|
||||
msgid "The extension had an error"
|
||||
msgstr "У розширенні сталася помилка"
|
||||
|
||||
#: subprojects/extensions-app/data/ui/extension-row.ui:109
|
||||
#: subprojects/extensions-tool/src/command-create.c:301
|
||||
#: subprojects/extensions-tool/src/command-create.c:325
|
||||
#: subprojects/extensions-tool/src/main.c:241
|
||||
msgid "Description"
|
||||
msgstr "Опис"
|
||||
@ -2529,12 +2541,12 @@ msgid "Log Out…"
|
||||
msgstr "Вийти…"
|
||||
|
||||
#. Translators: a file path to an extension directory
|
||||
#: subprojects/extensions-tool/src/command-create.c:202
|
||||
#: subprojects/extensions-tool/src/command-create.c:226
|
||||
#, c-format
|
||||
msgid "The new extension was successfully created in %s.\n"
|
||||
msgstr "Нове розширення успішно створено в %s.\n"
|
||||
|
||||
#: subprojects/extensions-tool/src/command-create.c:275
|
||||
#: subprojects/extensions-tool/src/command-create.c:299
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Name should be a very short (ideally descriptive) string.\n"
|
||||
@ -2543,12 +2555,12 @@ msgstr ""
|
||||
"Назва повинна бути дуже короткою (бажано максимально описовою).\n"
|
||||
"Наприклад: %s"
|
||||
|
||||
#: subprojects/extensions-tool/src/command-create.c:281
|
||||
#: subprojects/extensions-tool/src/command-create.c:305
|
||||
#: subprojects/extensions-tool/src/main.c:238
|
||||
msgid "Name"
|
||||
msgstr "Назва"
|
||||
|
||||
#: subprojects/extensions-tool/src/command-create.c:295
|
||||
#: subprojects/extensions-tool/src/command-create.c:319
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Description is a single-sentence explanation of what your extension does.\n"
|
||||
@ -2557,7 +2569,7 @@ msgstr ""
|
||||
"Опис — пояснення одним реченням того, що розширення робить.\n"
|
||||
"Наприклад: %s"
|
||||
|
||||
#: subprojects/extensions-tool/src/command-create.c:315
|
||||
#: subprojects/extensions-tool/src/command-create.c:339
|
||||
msgid ""
|
||||
"UUID is a globally-unique identifier for your extension.\n"
|
||||
"This should be in the format of an email address (clicktofocus@janedoe."
|
||||
@ -2567,56 +2579,56 @@ msgstr ""
|
||||
"Він зберігається у форматі електронної адреси (clicktofocus@janedoe.example."
|
||||
"com)\n"
|
||||
|
||||
#: subprojects/extensions-tool/src/command-create.c:342
|
||||
#: subprojects/extensions-tool/src/command-create.c:366
|
||||
msgid "Choose one of the available templates:\n"
|
||||
msgstr "Виберіть один із доступних шаблонів:\n"
|
||||
|
||||
#: subprojects/extensions-tool/src/command-create.c:356
|
||||
#: subprojects/extensions-tool/src/command-create.c:380
|
||||
msgid "Template"
|
||||
msgstr "Шаблон"
|
||||
|
||||
#: subprojects/extensions-tool/src/command-create.c:411
|
||||
#: subprojects/extensions-tool/src/command-create.c:435
|
||||
msgid "The unique identifier of the new extension"
|
||||
msgstr "Унікальний код розширення"
|
||||
|
||||
#: subprojects/extensions-tool/src/command-create.c:414
|
||||
#: subprojects/extensions-tool/src/command-create.c:438
|
||||
msgid "NAME"
|
||||
msgstr "НАЗВА"
|
||||
|
||||
#: subprojects/extensions-tool/src/command-create.c:415
|
||||
#: subprojects/extensions-tool/src/command-create.c:439
|
||||
msgid "The user-visible name of the new extension"
|
||||
msgstr "Загальна назва розширення"
|
||||
|
||||
#: subprojects/extensions-tool/src/command-create.c:417
|
||||
#: subprojects/extensions-tool/src/command-create.c:441
|
||||
msgid "DESCRIPTION"
|
||||
msgstr "ОПИС"
|
||||
|
||||
#: subprojects/extensions-tool/src/command-create.c:419
|
||||
#: subprojects/extensions-tool/src/command-create.c:443
|
||||
msgid "A short description of what the extension does"
|
||||
msgstr "Короткий опис того, що розширення робить"
|
||||
|
||||
#: subprojects/extensions-tool/src/command-create.c:422
|
||||
#: subprojects/extensions-tool/src/command-create.c:446
|
||||
msgid "TEMPLATE"
|
||||
msgstr "ШАБЛОН"
|
||||
|
||||
#: subprojects/extensions-tool/src/command-create.c:423
|
||||
#: subprojects/extensions-tool/src/command-create.c:447
|
||||
msgid "The template to use for the new extension"
|
||||
msgstr "Шаблон, яким слід скористатися для нового розширення"
|
||||
|
||||
#: subprojects/extensions-tool/src/command-create.c:429
|
||||
#: subprojects/extensions-tool/src/command-create.c:453
|
||||
msgid "Enter extension information interactively"
|
||||
msgstr "Ввести інформацію про розширення покроково"
|
||||
|
||||
#: subprojects/extensions-tool/src/command-create.c:437
|
||||
#: subprojects/extensions-tool/src/command-create.c:461
|
||||
msgid "Create a new extension"
|
||||
msgstr "Створити розширення"
|
||||
|
||||
#: subprojects/extensions-tool/src/command-create.c:455
|
||||
#: subprojects/extensions-tool/src/command-create.c:479
|
||||
#: subprojects/extensions-tool/src/command-list.c:172
|
||||
msgid "Unknown arguments"
|
||||
msgstr "Невідомі параметри"
|
||||
|
||||
#: subprojects/extensions-tool/src/command-create.c:480
|
||||
#: subprojects/extensions-tool/src/command-create.c:504
|
||||
msgid "UUID, name and description are required"
|
||||
msgstr "UUID, назва і опис — обов'язкові"
|
||||
|
||||
@ -2941,19 +2953,3 @@ msgstr[3] "%u вхід"
|
||||
#: subprojects/gvc/gvc-mixer-control.c:2766
|
||||
msgid "System Sounds"
|
||||
msgstr "Системні звуки"
|
||||
|
||||
#~ msgid "Copy Error"
|
||||
#~ msgstr "Скопіювати помилку"
|
||||
|
||||
#~ msgid "%d Connected"
|
||||
#~ msgid_plural "%d Connected"
|
||||
#~ msgstr[0] "%d під'єднано"
|
||||
#~ msgstr[1] "%d під'єднано"
|
||||
#~ msgstr[2] "%d під'єднано"
|
||||
#~ msgstr[3] "%d під'єднано"
|
||||
|
||||
#~ msgid "Off"
|
||||
#~ msgstr "Вимкнено"
|
||||
|
||||
#~ msgid "On"
|
||||
#~ msgstr "Увімкнено"
|
||||
|
760
po/zh_CN.po
760
po/zh_CN.po
File diff suppressed because it is too large
Load Diff
@ -346,8 +346,6 @@ struct _App
|
||||
|
||||
GSList *notify_appointments; /* CalendarAppointment *, for EventsAdded */
|
||||
GSList *notify_ids; /* gchar *, for EventsRemoved */
|
||||
guint events_added_timeout_id;
|
||||
guint events_removed_timeout_id;
|
||||
|
||||
GSList *live_views;
|
||||
};
|
||||
@ -370,24 +368,19 @@ app_update_timezone (App *app)
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
on_app_schedule_events_added_cb (gpointer user_data)
|
||||
static void
|
||||
app_notify_events_added (App *app)
|
||||
{
|
||||
App *app = user_data;
|
||||
GVariantBuilder builder, extras_builder;
|
||||
GSList *events, *link;
|
||||
|
||||
if (g_source_is_destroyed (g_main_current_source ()))
|
||||
return FALSE;
|
||||
|
||||
events = g_slist_reverse (app->notify_appointments);
|
||||
app->notify_appointments = NULL;
|
||||
app->events_added_timeout_id = 0;
|
||||
|
||||
print_debug ("Emitting EventsAddedOrUpdated with %d events", g_slist_length (events));
|
||||
|
||||
if (!events)
|
||||
return FALSE;
|
||||
return;
|
||||
|
||||
/* The a{sv} is used as an escape hatch in case we want to provide more
|
||||
* information in the future without breaking ABI
|
||||
@ -428,41 +421,21 @@ on_app_schedule_events_added_cb (gpointer user_data)
|
||||
g_variant_builder_clear (&builder);
|
||||
|
||||
g_slist_free_full (events, calendar_appointment_free);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
app_schedule_events_added (App *app)
|
||||
app_notify_events_removed (App *app)
|
||||
{
|
||||
print_debug ("Scheduling EventsAddedOrUpdated");
|
||||
if (app->events_added_timeout_id == 0)
|
||||
{
|
||||
app->events_added_timeout_id = g_timeout_add_seconds (2,
|
||||
on_app_schedule_events_added_cb,
|
||||
app);
|
||||
g_source_set_name_by_id (app->events_added_timeout_id, "[gnome-shell] on_app_schedule_events_added_cb");
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
on_app_schedule_events_removed_cb (gpointer user_data)
|
||||
{
|
||||
App *app = user_data;
|
||||
GVariantBuilder builder;
|
||||
GSList *ids, *link;
|
||||
|
||||
if (g_source_is_destroyed (g_main_current_source ()))
|
||||
return FALSE;
|
||||
|
||||
ids = app->notify_ids;
|
||||
app->notify_ids = NULL;
|
||||
app->events_removed_timeout_id = 0;
|
||||
|
||||
print_debug ("Emitting EventsRemoved with %d ids", g_slist_length (ids));
|
||||
|
||||
if (!ids)
|
||||
return FALSE;
|
||||
return;
|
||||
|
||||
g_variant_builder_init (&builder, G_VARIANT_TYPE ("as"));
|
||||
for (link = ids; link; link = g_slist_next (link))
|
||||
@ -483,20 +456,7 @@ on_app_schedule_events_removed_cb (gpointer user_data)
|
||||
|
||||
g_slist_free_full (ids, g_free);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
app_schedule_events_removed (App *app)
|
||||
{
|
||||
print_debug ("Scheduling EventsRemoved");
|
||||
if (app->events_removed_timeout_id == 0)
|
||||
{
|
||||
app->events_removed_timeout_id = g_timeout_add_seconds (2,
|
||||
on_app_schedule_events_removed_cb,
|
||||
app);
|
||||
g_source_set_name_by_id (app->events_removed_timeout_id, "[gnome-shell] on_app_schedule_events_removed_cb");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -546,7 +506,7 @@ app_process_added_modified_objects (App *app,
|
||||
g_clear_object (&cal_client);
|
||||
|
||||
if (app->notify_appointments)
|
||||
app_schedule_events_added (app);
|
||||
app_notify_events_added (app);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -610,7 +570,7 @@ on_objects_removed (ECalClientView *view,
|
||||
g_clear_object (&client);
|
||||
|
||||
if (app->notify_ids)
|
||||
app_schedule_events_removed (app);
|
||||
app_notify_events_removed (app);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@ -695,10 +655,35 @@ app_stop_view (App *app,
|
||||
g_signal_handlers_disconnect_by_func (view, on_objects_removed, app);
|
||||
}
|
||||
|
||||
static void
|
||||
app_notify_has_calendars (App *app)
|
||||
{
|
||||
GVariantBuilder dict_builder;
|
||||
|
||||
g_variant_builder_init (&dict_builder, G_VARIANT_TYPE ("a{sv}"));
|
||||
g_variant_builder_add (&dict_builder, "{sv}", "HasCalendars",
|
||||
g_variant_new_boolean (app_has_calendars (app)));
|
||||
|
||||
g_dbus_connection_emit_signal (app->connection,
|
||||
NULL,
|
||||
"/org/gnome/Shell/CalendarServer",
|
||||
"org.freedesktop.DBus.Properties",
|
||||
"PropertiesChanged",
|
||||
g_variant_new ("(sa{sv}as)",
|
||||
"org.gnome.Shell.CalendarServer",
|
||||
&dict_builder,
|
||||
NULL),
|
||||
NULL);
|
||||
g_variant_builder_clear (&dict_builder);
|
||||
}
|
||||
|
||||
static void
|
||||
app_update_views (App *app)
|
||||
{
|
||||
GSList *link, *clients;
|
||||
gboolean had_views, has_views;
|
||||
|
||||
had_views = app->live_views != NULL;
|
||||
|
||||
for (link = app->live_views; link; link = g_slist_next (link))
|
||||
{
|
||||
@ -723,31 +708,14 @@ app_update_views (App *app)
|
||||
app->live_views = g_slist_prepend (app->live_views, view);
|
||||
}
|
||||
|
||||
has_views = app->live_views != NULL;
|
||||
|
||||
if (has_views != had_views)
|
||||
app_notify_has_calendars (app);
|
||||
|
||||
g_slist_free_full (clients, g_object_unref);
|
||||
}
|
||||
|
||||
static void
|
||||
app_notify_has_calendars (App *app)
|
||||
{
|
||||
GVariantBuilder dict_builder;
|
||||
|
||||
g_variant_builder_init (&dict_builder, G_VARIANT_TYPE ("a{sv}"));
|
||||
g_variant_builder_add (&dict_builder, "{sv}", "HasCalendars",
|
||||
g_variant_new_boolean (app_has_calendars (app)));
|
||||
|
||||
g_dbus_connection_emit_signal (g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL),
|
||||
NULL,
|
||||
"/org/gnome/Shell/CalendarServer",
|
||||
"org.freedesktop.DBus.Properties",
|
||||
"PropertiesChanged",
|
||||
g_variant_new ("(sa{sv}as)",
|
||||
"org.gnome.Shell.CalendarServer",
|
||||
&dict_builder,
|
||||
NULL),
|
||||
NULL);
|
||||
g_variant_builder_clear (&dict_builder);
|
||||
}
|
||||
|
||||
static void
|
||||
on_client_appeared_cb (CalendarSources *sources,
|
||||
ECalClient *client,
|
||||
@ -866,9 +834,6 @@ app_free (App *app)
|
||||
{
|
||||
GSList *ll;
|
||||
|
||||
g_clear_handle_id (&app->events_added_timeout_id, g_source_remove);
|
||||
g_clear_handle_id (&app->events_removed_timeout_id, g_source_remove);
|
||||
|
||||
for (ll = app->live_views; ll != NULL; ll = g_slist_next (ll))
|
||||
{
|
||||
ECalClientView *view = E_CAL_CLIENT_VIEW (ll->data);
|
||||
|
@ -253,7 +253,9 @@ deep_count_one (DeepCountState *state,
|
||||
else
|
||||
{
|
||||
content_type = g_file_info_get_content_type (info);
|
||||
add_content_type_to_cache (state, content_type);
|
||||
|
||||
if (content_type)
|
||||
add_content_type_to_cache (state, content_type);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
)
|
||||
|
@ -78,6 +78,7 @@ struct _ShellApp
|
||||
* want (e.g. it will be of TYPE_NORMAL from
|
||||
* the way shell-window-tracker.c works).
|
||||
*/
|
||||
GIcon *fallback_icon;
|
||||
|
||||
ShellAppRunningState *running_state;
|
||||
|
||||
@ -180,66 +181,47 @@ window_backed_app_get_window (ShellApp *app)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static ClutterActor *
|
||||
window_backed_app_get_icon (ShellApp *app,
|
||||
int size)
|
||||
/**
|
||||
* shell_app_get_icon:
|
||||
*
|
||||
* Look up the icon for this application
|
||||
*
|
||||
* Return value: (transfer none): A #GIcon
|
||||
*/
|
||||
GIcon *
|
||||
shell_app_get_icon (ShellApp *app)
|
||||
{
|
||||
MetaWindow *window = NULL;
|
||||
StWidget *widget;
|
||||
int scale, scaled_size;
|
||||
ShellGlobal *global;
|
||||
StThemeContext *context;
|
||||
|
||||
global = shell_global_get ();
|
||||
context = st_theme_context_get_for_stage (shell_global_get_stage (global));
|
||||
g_object_get (context, "scale-factor", &scale, NULL);
|
||||
g_return_val_if_fail (SHELL_IS_APP (app), NULL);
|
||||
|
||||
scaled_size = size * scale;
|
||||
if (app->info)
|
||||
return g_app_info_get_icon (G_APP_INFO (app->info));
|
||||
|
||||
if (app->fallback_icon)
|
||||
return app->fallback_icon;
|
||||
|
||||
/* During a state transition from running to not-running for
|
||||
* window-backend apps, it's possible we get a request for the icon.
|
||||
* Avoid asserting here and just return an empty image.
|
||||
* Avoid asserting here and just return a fallback icon
|
||||
*/
|
||||
if (app->running_state != NULL)
|
||||
window = window_backed_app_get_window (app);
|
||||
|
||||
if (window == NULL)
|
||||
if (window &&
|
||||
meta_window_get_client_type (window) == META_WINDOW_CLIENT_TYPE_X11)
|
||||
{
|
||||
ClutterActor *actor;
|
||||
|
||||
actor = clutter_actor_new ();
|
||||
g_object_set (actor,
|
||||
"opacity", 0,
|
||||
"width", (float) scaled_size,
|
||||
"height", (float) scaled_size,
|
||||
NULL);
|
||||
return actor;
|
||||
}
|
||||
|
||||
if (meta_window_get_client_type (window) == META_WINDOW_CLIENT_TYPE_X11)
|
||||
{
|
||||
StWidget *texture_actor;
|
||||
|
||||
texture_actor =
|
||||
app->fallback_icon =
|
||||
st_texture_cache_bind_cairo_surface_property (st_texture_cache_get_default (),
|
||||
G_OBJECT (window),
|
||||
"icon",
|
||||
scaled_size);
|
||||
|
||||
widget = g_object_new (ST_TYPE_BIN,
|
||||
"child", texture_actor,
|
||||
NULL);
|
||||
"icon");
|
||||
}
|
||||
else
|
||||
{
|
||||
widget = g_object_new (ST_TYPE_ICON,
|
||||
"icon-size", size,
|
||||
"icon-name", "application-x-executable",
|
||||
NULL);
|
||||
app->fallback_icon = g_themed_icon_new ("application-x-executable");
|
||||
}
|
||||
st_widget_add_style_class_name (widget, "fallback-app-icon");
|
||||
|
||||
return CLUTTER_ACTOR (widget);
|
||||
return app->fallback_icon;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -257,16 +239,16 @@ shell_app_create_icon_texture (ShellApp *app,
|
||||
GIcon *icon;
|
||||
ClutterActor *ret;
|
||||
|
||||
if (app->info == NULL)
|
||||
return window_backed_app_get_icon (app, size);
|
||||
|
||||
ret = st_icon_new ();
|
||||
st_icon_set_icon_size (ST_ICON (ret), size);
|
||||
st_icon_set_fallback_icon_name (ST_ICON (ret), "application-x-executable");
|
||||
|
||||
icon = g_app_info_get_icon (G_APP_INFO (app->info));
|
||||
icon = shell_app_get_icon (app);
|
||||
st_icon_set_gicon (ST_ICON (ret), icon);
|
||||
|
||||
if (shell_app_is_window_backed (app))
|
||||
st_widget_add_style_class_name (ST_WIDGET (ret), "fallback-app-icon");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -1576,6 +1558,7 @@ shell_app_dispose (GObject *object)
|
||||
ShellApp *app = SHELL_APP (object);
|
||||
|
||||
g_clear_object (&app->info);
|
||||
g_clear_object (&app->fallback_icon);
|
||||
|
||||
while (app->running_state)
|
||||
_shell_app_remove_window (app, app->running_state->windows->data);
|
||||
|
@ -29,6 +29,7 @@ const char *shell_app_get_id (ShellApp *app);
|
||||
GDesktopAppInfo *shell_app_get_app_info (ShellApp *app);
|
||||
|
||||
ClutterActor *shell_app_create_icon_texture (ShellApp *app, int size);
|
||||
GIcon *shell_app_get_icon (ShellApp *app);
|
||||
const char *shell_app_get_name (ShellApp *app);
|
||||
const char *shell_app_get_description (ShellApp *app);
|
||||
gboolean shell_app_is_window_backed (ShellApp *app);
|
||||
|
@ -899,8 +899,9 @@ load_gl_symbol (const char *name,
|
||||
}
|
||||
|
||||
static void
|
||||
global_stage_after_paint (ClutterStage *stage,
|
||||
ShellGlobal *global)
|
||||
global_stage_after_paint (ClutterStage *stage,
|
||||
ClutterStageView *stage_view,
|
||||
ShellGlobal *global)
|
||||
{
|
||||
/* At this point, we've finished all layout and painting, but haven't
|
||||
* actually flushed or swapped */
|
||||
|
@ -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__ */
|
1624
src/shell-recorder.c
1624
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__ */
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user