Compare commits
180 Commits
wip/re-sea
...
3.7.4
Author | SHA1 | Date | |
---|---|---|---|
f0ebc84840 | |||
490eb59ea3 | |||
16a9391726 | |||
adf8ba67d2 | |||
c37b222cbf | |||
72f8f2beb1 | |||
16bb9c17f5 | |||
ca44977d92 | |||
bcf294475f | |||
3b31774dd3 | |||
c106347c59 | |||
2679be9d97 | |||
4d59368c7d | |||
3f29680fb6 | |||
8f1df14ae7 | |||
7159e360d9 | |||
65723bcac5 | |||
73ae451cb4 | |||
dc0ea3a248 | |||
9548cd8341 | |||
8410fc38c9 | |||
0c9c2168b3 | |||
2690f54743 | |||
22783813c5 | |||
b5ed46a5af | |||
1a3f17e296 | |||
9281129f07 | |||
0e9ddd3b99 | |||
d87db04e55 | |||
906ec3c8a9 | |||
449575ceae | |||
6255c77eba | |||
c33622f2b3 | |||
e4860acb58 | |||
e96867f757 | |||
57bd43baf3 | |||
3a4e595d32 | |||
dcad22bfa8 | |||
acba0e47d8 | |||
dd19459e18 | |||
8be3c5ed21 | |||
51726d8de7 | |||
8f41c6bad8 | |||
e294abc567 | |||
9f9518c872 | |||
5faf7cb59e | |||
4b095d532c | |||
4288761235 | |||
73388f30fd | |||
2d9ddd4bc8 | |||
55aa0cf303 | |||
52ca15b514 | |||
bd383888de | |||
1bd349485f | |||
155f9dc1b1 | |||
fe7ee1edc3 | |||
c11cbff605 | |||
fbc629266f | |||
75d44dca6b | |||
3e6b794a33 | |||
a757ce48a1 | |||
507f29a7bd | |||
e5f4f77073 | |||
f07fee538d | |||
fa1420b384 | |||
724a2bd72f | |||
d525d02348 | |||
4920cf2b98 | |||
f41d0938a4 | |||
924a405829 | |||
fc9225e24a | |||
ac202cbdd3 | |||
cedd68c942 | |||
4231c879ef | |||
42e58a4b72 | |||
ebd1bc83c9 | |||
0bc9d7455f | |||
5274166f8c | |||
5566aa4588 | |||
ab638a4f54 | |||
86a8452ab7 | |||
8c96c16eac | |||
45c2e6575d | |||
a786a7dc55 | |||
6adf5cbee5 | |||
1964b54627 | |||
c9d0e82c52 | |||
1a4948f0f2 | |||
66da3f5668 | |||
9ebeb64570 | |||
571aaece2e | |||
f60fb954a2 | |||
1d136cacfb | |||
994021d77f | |||
8899325a0e | |||
43876a9357 | |||
d6cace32f5 | |||
2388de455b | |||
b14b3ab276 | |||
32ccb779c6 | |||
52536e94e5 | |||
5d6b3abd26 | |||
79682bbcb0 | |||
770ff19313 | |||
8d4855f100 | |||
7d4e14f384 | |||
f162dd7e87 | |||
06dc12e217 | |||
36edff9e15 | |||
34a0c079de | |||
84b581ae13 | |||
587c93eadf | |||
b5aa549e0c | |||
5fb6738612 | |||
685262fc5e | |||
8802f6cf23 | |||
2698d0db29 | |||
2fa7230133 | |||
658243eae4 | |||
7282bc8859 | |||
07511cb21a | |||
f71f767a3c | |||
176daa1469 | |||
5487f8cf93 | |||
944762ac83 | |||
c66068c435 | |||
d479c936b8 | |||
c5a3f784dd | |||
529d012865 | |||
8a1b83417a | |||
6c64c0873c | |||
d2c6149923 | |||
9f98f6f02d | |||
2f7c0b1985 | |||
f61548234a | |||
6eef830ba4 | |||
88a9b7648c | |||
b7678493f9 | |||
a9ec8a354a | |||
a42d35deab | |||
2008feb7da | |||
c41424b57b | |||
3bd5563a7e | |||
eff8ec00c4 | |||
1256af7b9a | |||
b38ecaf925 | |||
bd5d945fb2 | |||
15063ef3d5 | |||
3b8a125732 | |||
9860b1c677 | |||
a0e340f06e | |||
57d3bec95c | |||
be10f3c2b5 | |||
f7af96dbb2 | |||
468a855f04 | |||
429f9e1d15 | |||
5de91197ae | |||
bc6b4b01ea | |||
e89ce7358a | |||
bdf0a6fd0b | |||
783abd4f5f | |||
28aa9201f0 | |||
378df515d0 | |||
04d68c6e36 | |||
5308d12239 | |||
15cac0157c | |||
fc696bc054 | |||
5a7b7b7389 | |||
9c9cf6f5ab | |||
0155739bef | |||
d0902fa28b | |||
3aa0d455c9 | |||
835d4e4b58 | |||
6075332f2f | |||
c5d8484e19 | |||
575ab0d609 | |||
b48a7d5cfd | |||
9af107feff | |||
70b5db16d3 | |||
5072ea7e47 |
@ -16,6 +16,7 @@ EXTRA_DIST = \
|
|||||||
# These are files checked into Git that we don't want to distribute
|
# These are files checked into Git that we don't want to distribute
|
||||||
DIST_EXCLUDE = \
|
DIST_EXCLUDE = \
|
||||||
.gitignore \
|
.gitignore \
|
||||||
|
.gitmodules \
|
||||||
gnome-shell.doap \
|
gnome-shell.doap \
|
||||||
HACKING \
|
HACKING \
|
||||||
MAINTAINERS \
|
MAINTAINERS \
|
||||||
|
94
NEWS
94
NEWS
@ -1,3 +1,97 @@
|
|||||||
|
3.7.4
|
||||||
|
=====
|
||||||
|
* Make menu separators crisp [Giovanni, Allan; #641745]
|
||||||
|
* power: Update for new D-Bus name [Bastien; #690506]
|
||||||
|
* Add smooth scrolling support [Jasper; #687573]
|
||||||
|
* Tweak notification layout [Allan; #688506]
|
||||||
|
* Ping the active window when using the app menu [Giovanni; #684340]
|
||||||
|
* Make password entries insensitive after submission [Jasper; #690594, #690895]
|
||||||
|
* Honor lock-delay GSettings key [Giovanni, Matthias; #690766, #691170]
|
||||||
|
* Use text/calendar preferred app as the calendar app [Giovanni; #690767]
|
||||||
|
* lookingGlass: Move to an inspect() function [Jasper; #690726]
|
||||||
|
* Make OSK animation quicker, snappier [Rui; #688642]
|
||||||
|
* Allow to close chat notifications with Escape [Jasper; #690897]
|
||||||
|
* Honor org.gnome.desktop.screensaver.user-switch-enabled [Giovanni; #691042]
|
||||||
|
* Add a SelectArea() DBus method [Cosimo; #687954]
|
||||||
|
* Support non-absolute paths when saving screenshots [Cosimo; #688004]
|
||||||
|
* OSK: Fix extended keys popups [Rui; #674955]
|
||||||
|
* Don't hide or show the keyboard immediately [Rui; #688646]
|
||||||
|
* Improve padding in power menu [Giovanni; #689297]
|
||||||
|
* Add per-window input source switching [Rui; #691414]
|
||||||
|
* Misc bug fixes and cleanups [Rico, Jasper, Giovanni, Rui, Florian, Dan;
|
||||||
|
#690608, #690589, #690539, #687081, #690667, #690665, #690666, #685856,
|
||||||
|
#690858, #690895, #680414, #690965, #691019, #690590, #681376, #690180,
|
||||||
|
#685513, #689263, #691553, #691720, #691743, #691750]
|
||||||
|
|
||||||
|
Contributors:
|
||||||
|
Giovanni Campagna, Cosimo Cecchi, Matthias Clasen, Allan Day, Rui Matos,
|
||||||
|
Florian Müllner, Bastien Nocera, Jasper St. Pierre, Rico Tzschichholz,
|
||||||
|
Dan Winship
|
||||||
|
|
||||||
|
Translations:
|
||||||
|
Matej Urbančič [sl], Kjartan Maraas [nb], Mattias Põldaru [et],
|
||||||
|
Yaron Shahrabani [he], Aurimas Černius [lt], Khaled Hosny [ar],
|
||||||
|
Fran Diéguez [gl], Daniel Mustieles [es], Piotr Drąg [pl], Balázs Úr [hu],
|
||||||
|
Baurzhan Muftakhidinov [kk], Tobias Endrigkeit [de], Dušan Kazik [sk],
|
||||||
|
Aron Xu [zh_CN], Gheyret Kenji [ug]
|
||||||
|
|
||||||
|
3.7.3
|
||||||
|
=====
|
||||||
|
* Add 'No Messages' label when message tray is empty [Victoria; #686738]
|
||||||
|
* Use better icons in Ctrl-Alt-Tab popup [Stéphane; #641303]
|
||||||
|
* Show the OSK on the monitor where the focused window lives [Giovanni; #685856]
|
||||||
|
* Highlight window clone and caption when hovered [Giovanni, Marc; #665310]
|
||||||
|
* Improve login process indication [Stéphane; #687113]
|
||||||
|
* Omit empty categories in apps view [Stéphane; #687970]
|
||||||
|
* Style panel differently according to mode [Florian; #684573]
|
||||||
|
* Make it possible to hide the user name [Matthias; #688577]
|
||||||
|
* Consolidate and improve chat connection notifications [Giovanni; #687213]
|
||||||
|
* Improve notification scrollbar appearance [Carlos; #688393]
|
||||||
|
* Fade scroll view fade near scrolling edges [Jasper; #689249]
|
||||||
|
* Add a read-only org.gnome.Shell.Mode property [Debarshi; #689300]
|
||||||
|
* Don't close message tray after using context menus [Giovanni; #689296]
|
||||||
|
* Port swipe-scrolling to ClutterPanAction [Jasper, Florian; #689062, #689552]
|
||||||
|
* Remember state of 'Remember Password' checkbox [Ron; #688039]
|
||||||
|
* Improve timestamp format in chat notifications [Carlos; #680989]
|
||||||
|
* Improve style of missed-messages counter [Carlos; #686472]
|
||||||
|
* Omit connection failure notifications if cancelled by user [Giovanni; #684823]
|
||||||
|
* Add window-based Alt-Tab popup [Florian; #688913]
|
||||||
|
* Support external session mode definitions [Florian; #689304]
|
||||||
|
* Support session-mode-specific extensions [Florian; #689305]
|
||||||
|
* Support 'parentMode' property in session modes [Florian; #689308]
|
||||||
|
* Support a new org.gnome.ShellSearchProvider2 DBus interface
|
||||||
|
[Cosimo; #689735, #690009]
|
||||||
|
* Add "windows" to Ctrl-Alt-Tab popup [Jasper; #689653]
|
||||||
|
* Port PopupMenu to GrabHelper [Jasper; #689109, #689954]
|
||||||
|
* Show headphone icon when headphones are plugged in [Giovanni; #675902]
|
||||||
|
* Display (non-app) search results as list [Tanner, Cosimo; #681797]
|
||||||
|
* Skip diacritical marks in search terms [Aleksander; #648587]
|
||||||
|
* Expose all engine options in input sources [Giovanni, Rui; #682318]
|
||||||
|
* Add input source switcher popup [Rui; #682315]
|
||||||
|
* Add minimal support for InfiniBand in network menu [Dan; #677150]
|
||||||
|
* Misc bug fixes and cleanups [Sebastian, Aleksander, Giovanni, Tim, Cosimo,
|
||||||
|
Florian, Matthias, Rui, Lionel, Colin, Piotr, Guillaume, Bastien, Tanner,
|
||||||
|
Carlos, Stéphane, Jakub; #688422, #688379, #688750, #688771, #686800,
|
||||||
|
#688133, #688895, #688966, #683986, #688004, #689108, #689029, #683449,
|
||||||
|
#688196, #689304, #689243, #689295, #689325, #689400, #679168, #689568,
|
||||||
|
#689537, #689528, #689749, #689789, #689353, #689820, #689868, #689778,
|
||||||
|
#689959, #688589, #688589, #689955, #687250, #689965, #690046, #690049,
|
||||||
|
#689884, #682286, #690173, #690174, #672941, #689876, #687881, #690171,
|
||||||
|
#690241, #690312, #690175, #687955, #650843, #688234, #690427
|
||||||
|
|
||||||
|
Contributors:
|
||||||
|
Giovanni Campagna, Cosimo Cecchi, Matthias Clasen, Stéphane Démurget,
|
||||||
|
Guillaume Desmottes, Tanner Doshier, Piotr Drąg, Sebastian Keller,
|
||||||
|
Lionel Landwerlin, Tim Lunn, Victoria Martínez de la Cruz, Aleksander Morgado,
|
||||||
|
Florian Müllner, Bastien Nocera, Marc Plano-Lesay, Carlos Soriano Sánchez,
|
||||||
|
Jakub Steiner, Jasper St. Pierre, Colin Walters, Dan Winship, Ron Yorston
|
||||||
|
|
||||||
|
Translations:
|
||||||
|
Yuri Myasoedov [ru], Wouter Bolsterlee [nl], Yaron Shahrabani [he],
|
||||||
|
Nilamdyuti Goswami [as], Ani Peter [ml], Kjartan Maraas [nb],
|
||||||
|
Dr.T.Vasudevan [ta], A S Alam [pa], Shankar Prasad [kn], Khaled Hosny [ar],
|
||||||
|
Daniel Mustieles [es], Dušan Kazik [sk]
|
||||||
|
|
||||||
3.7.2
|
3.7.2
|
||||||
=====
|
=====
|
||||||
* Enforce RTL in he for messages that might end up as LTR [Florian; #686630]
|
* Enforce RTL in he for messages that might end up as LTR [Florian; #686630]
|
||||||
|
11
configure.ac
11
configure.ac
@ -1,5 +1,5 @@
|
|||||||
AC_PREREQ(2.63)
|
AC_PREREQ(2.63)
|
||||||
AC_INIT([gnome-shell],[3.7.2],[https://bugzilla.gnome.org/enter_bug.cgi?product=gnome-shell],[gnome-shell])
|
AC_INIT([gnome-shell],[3.7.4],[https://bugzilla.gnome.org/enter_bug.cgi?product=gnome-shell],[gnome-shell])
|
||||||
|
|
||||||
AC_CONFIG_HEADERS([config.h])
|
AC_CONFIG_HEADERS([config.h])
|
||||||
AC_CONFIG_SRCDIR([src/shell-global.c])
|
AC_CONFIG_SRCDIR([src/shell-global.c])
|
||||||
@ -65,7 +65,7 @@ AM_CONDITIONAL(BUILD_RECORDER, $build_recorder)
|
|||||||
CLUTTER_MIN_VERSION=1.11.11
|
CLUTTER_MIN_VERSION=1.11.11
|
||||||
GOBJECT_INTROSPECTION_MIN_VERSION=0.10.1
|
GOBJECT_INTROSPECTION_MIN_VERSION=0.10.1
|
||||||
GJS_MIN_VERSION=1.33.2
|
GJS_MIN_VERSION=1.33.2
|
||||||
MUTTER_MIN_VERSION=3.7.2
|
MUTTER_MIN_VERSION=3.7.4
|
||||||
GTK_MIN_VERSION=3.3.9
|
GTK_MIN_VERSION=3.3.9
|
||||||
GIO_MIN_VERSION=2.35.0
|
GIO_MIN_VERSION=2.35.0
|
||||||
LIBECAL_MIN_VERSION=3.5.3
|
LIBECAL_MIN_VERSION=3.5.3
|
||||||
@ -78,7 +78,8 @@ STARTUP_NOTIFICATION_MIN_VERSION=0.11
|
|||||||
GCR_MIN_VERSION=3.3.90
|
GCR_MIN_VERSION=3.3.90
|
||||||
GNOME_DESKTOP_REQUIRED_VERSION=3.7.1
|
GNOME_DESKTOP_REQUIRED_VERSION=3.7.1
|
||||||
GNOME_MENUS_REQUIRED_VERSION=3.5.3
|
GNOME_MENUS_REQUIRED_VERSION=3.5.3
|
||||||
NETWORKMANAGER_MIN_VERSION=0.9.7
|
NETWORKMANAGER_MIN_VERSION=0.9.6
|
||||||
|
PULSE_MIN_VERS=2.0
|
||||||
|
|
||||||
# Collect more than 20 libraries for a prize!
|
# Collect more than 20 libraries for a prize!
|
||||||
PKG_CHECK_MODULES(GNOME_SHELL, gio-unix-2.0 >= $GIO_MIN_VERSION
|
PKG_CHECK_MODULES(GNOME_SHELL, gio-unix-2.0 >= $GIO_MIN_VERSION
|
||||||
@ -125,8 +126,8 @@ LIBS=$saved_LIBS
|
|||||||
PKG_CHECK_MODULES(GNOME_SHELL_JS, gio-2.0 gjs-internals-1.0 >= $GJS_MIN_VERSION)
|
PKG_CHECK_MODULES(GNOME_SHELL_JS, gio-2.0 gjs-internals-1.0 >= $GJS_MIN_VERSION)
|
||||||
PKG_CHECK_MODULES(ST, clutter-1.0 gtk+-3.0 libcroco-0.6 >= 0.6.8 x11)
|
PKG_CHECK_MODULES(ST, clutter-1.0 gtk+-3.0 libcroco-0.6 >= 0.6.8 x11)
|
||||||
PKG_CHECK_MODULES(TRAY, gtk+-3.0)
|
PKG_CHECK_MODULES(TRAY, gtk+-3.0)
|
||||||
PKG_CHECK_MODULES(GVC, libpulse libpulse-mainloop-glib gobject-2.0)
|
PKG_CHECK_MODULES(GVC, libpulse >= $PULSE_MIN_VERS libpulse-mainloop-glib gobject-2.0)
|
||||||
PKG_CHECK_MODULES(DESKTOP_SCHEMAS, gsettings-desktop-schemas >= 3.7.2)
|
PKG_CHECK_MODULES(DESKTOP_SCHEMAS, gsettings-desktop-schemas >= 3.7.2.2)
|
||||||
|
|
||||||
AC_MSG_CHECKING([for bluetooth support])
|
AC_MSG_CHECKING([for bluetooth support])
|
||||||
PKG_CHECK_EXISTS([gnome-bluetooth-1.0 >= 3.1.0],
|
PKG_CHECK_EXISTS([gnome-bluetooth-1.0 >= 3.1.0],
|
||||||
|
@ -12,6 +12,7 @@ desktop_DATA = gnome-shell.desktop gnome-shell-extension-prefs.desktop
|
|||||||
|
|
||||||
introspectiondir = $(datadir)/dbus-1/interfaces
|
introspectiondir = $(datadir)/dbus-1/interfaces
|
||||||
introspection_DATA = \
|
introspection_DATA = \
|
||||||
|
org.gnome.Shell.Screenshot.xml \
|
||||||
org.gnome.ShellSearchProvider.xml \
|
org.gnome.ShellSearchProvider.xml \
|
||||||
org.gnome.ShellSearchProvider2.xml
|
org.gnome.ShellSearchProvider2.xml
|
||||||
|
|
||||||
@ -34,6 +35,7 @@ dist_theme_DATA = \
|
|||||||
theme/gnome-shell.css \
|
theme/gnome-shell.css \
|
||||||
theme/logged-in-indicator.svg \
|
theme/logged-in-indicator.svg \
|
||||||
theme/message-tray-background.png \
|
theme/message-tray-background.png \
|
||||||
|
theme/more-results.svg \
|
||||||
theme/noise-texture.png \
|
theme/noise-texture.png \
|
||||||
theme/panel-button-border.svg \
|
theme/panel-button-border.svg \
|
||||||
theme/panel-button-highlight-narrow.svg \
|
theme/panel-button-highlight-narrow.svg \
|
||||||
|
128
data/org.gnome.Shell.Screenshot.xml
Normal file
128
data/org.gnome.Shell.Screenshot.xml
Normal file
@ -0,0 +1,128 @@
|
|||||||
|
<!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.Shell.Screenshot:
|
||||||
|
@short_description: Screenshot interface
|
||||||
|
|
||||||
|
The interface used to capture pictures of the screen contents.
|
||||||
|
-->
|
||||||
|
<interface name="org.gnome.Shell.Screenshot">
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Screenshot:
|
||||||
|
@filename: The filename for the screenshot
|
||||||
|
@include_cursor: Whether to include the cursor image or not
|
||||||
|
@flash: Whether to flash the screen or not
|
||||||
|
@success: whether the screenshot was captured
|
||||||
|
@filename_used: the file where the screenshot was saved
|
||||||
|
|
||||||
|
Takes a screenshot of the whole screen and saves it
|
||||||
|
in @filename as png image, it returns a boolean
|
||||||
|
indicating whether the operation was successful or not.
|
||||||
|
@filename can either be an absolute path or a basename, in
|
||||||
|
which case the screenshot will be saved in the $XDG_PICTURES_DIR
|
||||||
|
or the home directory if it doesn't exist. The filename used
|
||||||
|
to save the screenshot will be returned in @filename_used.
|
||||||
|
-->
|
||||||
|
<method name="Screenshot">
|
||||||
|
<arg type="b" direction="in" name="include_cursor"/>
|
||||||
|
<arg type="b" direction="in" name="flash"/>
|
||||||
|
<arg type="s" direction="in" name="filename"/>
|
||||||
|
<arg type="b" direction="out" name="success"/>
|
||||||
|
<arg type="s" direction="out" name="filename_used"/>
|
||||||
|
</method>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
ScreenshotWindow:
|
||||||
|
@include_frame: Whether to include the frame or not
|
||||||
|
@include_cursor: Whether to include the cursor image or not
|
||||||
|
@flash: Whether to flash the window area or not
|
||||||
|
@filename: The filename for the screenshot
|
||||||
|
@success: whether the screenshot was captured
|
||||||
|
@filename_used: the file where the screenshot was saved
|
||||||
|
|
||||||
|
Takes a screenshot of the focused window (optionally omitting the frame)
|
||||||
|
and saves it in @filename as png image, it returns a boolean
|
||||||
|
indicating whether the operation was successful or not.
|
||||||
|
@filename can either be an absolute path or a basename, in
|
||||||
|
which case the screenshot will be saved in the $XDG_PICTURES_DIR
|
||||||
|
or the home directory if it doesn't exist. The filename used
|
||||||
|
to save the screenshot will be returned in @filename_used.
|
||||||
|
-->
|
||||||
|
<method name="ScreenshotWindow">
|
||||||
|
<arg type="b" direction="in" name="include_frame"/>
|
||||||
|
<arg type="b" direction="in" name="include_cursor"/>
|
||||||
|
<arg type="b" direction="in" name="flash"/>
|
||||||
|
<arg type="s" direction="in" name="filename"/>
|
||||||
|
<arg type="b" direction="out" name="success"/>
|
||||||
|
<arg type="s" direction="out" name="filename_used"/>
|
||||||
|
</method>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
ScreenshotArea:
|
||||||
|
@x: the X coordinate of the area to capture
|
||||||
|
@y: the Y coordinate of the area to capture
|
||||||
|
@width: the width of the area to capture
|
||||||
|
@height: the height of the area to capture
|
||||||
|
@flash: whether to flash the area or not
|
||||||
|
@filename: the filename for the screenshot
|
||||||
|
@success: whether the screenshot was captured
|
||||||
|
@filename_used: the file where the screenshot was saved
|
||||||
|
|
||||||
|
Takes a screenshot of the passed in area and saves it
|
||||||
|
in @filename as png image, it returns a boolean
|
||||||
|
indicating whether the operation was successful or not.
|
||||||
|
@filename can either be an absolute path or a basename, in
|
||||||
|
which case the screenshot will be saved in the $XDG_PICTURES_DIR
|
||||||
|
or the home directory if it doesn't exist. The filename used
|
||||||
|
to save the screenshot will be returned in @filename_used.
|
||||||
|
-->
|
||||||
|
<method name="ScreenshotArea">
|
||||||
|
<arg type="i" direction="in" name="x"/>
|
||||||
|
<arg type="i" direction="in" name="y"/>
|
||||||
|
<arg type="i" direction="in" name="width"/>
|
||||||
|
<arg type="i" direction="in" name="height"/>
|
||||||
|
<arg type="b" direction="in" name="flash"/>
|
||||||
|
<arg type="s" direction="in" name="filename"/>
|
||||||
|
<arg type="b" direction="out" name="success"/>
|
||||||
|
<arg type="s" direction="out" name="filename_used"/>
|
||||||
|
</method>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
FlashArea:
|
||||||
|
@x: the X coordinate of the area to flash
|
||||||
|
@y: the Y coordinate of the area to flash
|
||||||
|
@width: the width of the area to flash
|
||||||
|
@height: the height of the area to flash
|
||||||
|
|
||||||
|
Renders a flash spot effect in the specified rectangle of the screen.
|
||||||
|
-->
|
||||||
|
<method name="FlashArea">
|
||||||
|
<arg type="i" direction="in" name="x"/>
|
||||||
|
<arg type="i" direction="in" name="y"/>
|
||||||
|
<arg type="i" direction="in" name="width"/>
|
||||||
|
<arg type="i" direction="in" name="height"/>
|
||||||
|
</method>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
SelectArea:
|
||||||
|
@x: the X coordinate of the selected area
|
||||||
|
@y: the Y coordinate of the selected area
|
||||||
|
@width: the width of the selected area
|
||||||
|
@height: the height of the selected area
|
||||||
|
|
||||||
|
Interactively allows the user to select a rectangular area of
|
||||||
|
the screen, and returns its coordinates.
|
||||||
|
-->
|
||||||
|
<method name="SelectArea">
|
||||||
|
<arg type="i" direction="out" name="x"/>
|
||||||
|
<arg type="i" direction="out" name="y"/>
|
||||||
|
<arg type="i" direction="out" name="width"/>
|
||||||
|
<arg type="i" direction="out" name="height"/>
|
||||||
|
</method>
|
||||||
|
|
||||||
|
</interface>
|
||||||
|
</node>
|
@ -75,11 +75,13 @@
|
|||||||
<!--
|
<!--
|
||||||
LaunchSearch:
|
LaunchSearch:
|
||||||
@terms: Array of search terms, which the provider should treat as logical AND.
|
@terms: Array of search terms, which the provider should treat as logical AND.
|
||||||
|
@timestamp: A timestamp of the user interaction that triggered this call
|
||||||
|
|
||||||
Asks the search provider to launch a full search in the application for the provided terms.
|
Asks the search provider to launch a full search in the application for the provided terms.
|
||||||
-->
|
-->
|
||||||
<method name="LaunchSearch">
|
<method name="LaunchSearch">
|
||||||
<arg type="as" name="terms" direction="in" />
|
<arg type="as" name="terms" direction="in" />
|
||||||
|
<arg type="u" name="timestamp" direction="in" />
|
||||||
</method>
|
</method>
|
||||||
</interface>
|
</interface>
|
||||||
</node>
|
</node>
|
||||||
|
@ -49,7 +49,7 @@ stage {
|
|||||||
.switcher-list,
|
.switcher-list,
|
||||||
.app-well-app > .overview-icon,
|
.app-well-app > .overview-icon,
|
||||||
.show-apps > .overview-icon,
|
.show-apps > .overview-icon,
|
||||||
.search-result-content > .overview-icon {
|
.grid-search-result .overview-icon {
|
||||||
font-size: 9pt;
|
font-size: 9pt;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
@ -206,11 +206,12 @@ StScrollBar StButton#vhandle:active {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.popup-separator-menu-item {
|
.popup-separator-menu-item {
|
||||||
-gradient-height: 2px;
|
-gradient-height: 1px;
|
||||||
-gradient-start: rgba(8,8,8,0);
|
-gradient-start: rgba(255,255,255,0.0);
|
||||||
-gradient-end: #333333;
|
-gradient-end: rgba(255,255,255,0.3);
|
||||||
-margin-horizontal: 1.5em;
|
-margin-horizontal: 24px;
|
||||||
height: 1em;
|
height: 1px;
|
||||||
|
padding: 8px 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.popup-alternating-menu-item:alternate {
|
.popup-alternating-menu-item:alternate {
|
||||||
@ -251,6 +252,10 @@ StScrollBar StButton#vhandle:active {
|
|||||||
icon-size: 1.09em;
|
icon-size: 1.09em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.popup-battery-percentage {
|
||||||
|
padding-left: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
/* Switches */
|
/* Switches */
|
||||||
.toggle-switch {
|
.toggle-switch {
|
||||||
width: 65px;
|
width: 65px;
|
||||||
@ -287,13 +292,17 @@ StScrollBar StButton#vhandle:active {
|
|||||||
.hotplug-notification-item,
|
.hotplug-notification-item,
|
||||||
.hotplug-resident-eject-button,
|
.hotplug-resident-eject-button,
|
||||||
.modal-dialog-button {
|
.modal-dialog-button {
|
||||||
font-weight: bold;
|
|
||||||
border: 1px solid #8b8b8b;
|
border: 1px solid #8b8b8b;
|
||||||
background-gradient-direction: vertical;
|
background-gradient-direction: vertical;
|
||||||
background-gradient-start: rgba(255, 255, 255, 0.2);
|
background-gradient-start: rgba(255, 255, 255, 0.2);
|
||||||
background-gradient-end: rgba(255, 255, 255, 0);
|
background-gradient-end: rgba(255, 255, 255, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.dash-search-button,
|
||||||
|
.modal-dialog-button {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
.dash-search-button:hover,
|
.dash-search-button:hover,
|
||||||
.notification-button:hover,
|
.notification-button:hover,
|
||||||
.notification-icon-button:hover,
|
.notification-icon-button:hover,
|
||||||
@ -354,7 +363,7 @@ StScrollBar StButton#vhandle:active {
|
|||||||
background-gradient-start: rgba(5,5,6,0.1);
|
background-gradient-start: rgba(5,5,6,0.1);
|
||||||
background-gradient-end: rgba(254,254,254,0.1);
|
background-gradient-end: rgba(254,254,254,0.1);
|
||||||
background-gradient-direction: vertical;
|
background-gradient-direction: vertical;
|
||||||
transition-duration: 300;
|
transition-duration: 300ms;
|
||||||
box-shadow: inset 0px 2px 4px rgba(0,0,0,0.6);
|
box-shadow: inset 0px 2px 4px rgba(0,0,0,0.6);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -389,7 +398,7 @@ StScrollBar StButton#vhandle:active {
|
|||||||
color: rgb(64, 64, 64);
|
color: rgb(64, 64, 64);
|
||||||
caret-color: rgb(64, 64, 64);
|
caret-color: rgb(64, 64, 64);
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
transition-duration: 0;
|
transition-duration: 0ms;
|
||||||
}
|
}
|
||||||
|
|
||||||
.notification StEntry,
|
.notification StEntry,
|
||||||
@ -420,7 +429,7 @@ StScrollBar StButton#vhandle:active {
|
|||||||
background-color: black;
|
background-color: black;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
height: 1.86em;
|
height: 1.86em;
|
||||||
transition-duration: 250;
|
transition-duration: 250ms;
|
||||||
}
|
}
|
||||||
|
|
||||||
#panel.lock-screen {
|
#panel.lock-screen {
|
||||||
@ -503,7 +512,7 @@ StScrollBar StButton#vhandle:active {
|
|||||||
-minimum-hpadding: 6px;
|
-minimum-hpadding: 6px;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
color: #ccc;
|
color: #ccc;
|
||||||
transition-duration: 100;
|
transition-duration: 100ms;
|
||||||
}
|
}
|
||||||
|
|
||||||
#panel.unlock-screen .panel-button,
|
#panel.unlock-screen .panel-button,
|
||||||
@ -558,6 +567,10 @@ StScrollBar StButton#vhandle:active {
|
|||||||
spacing: 4px;
|
spacing: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.lock-screen-status-button-box {
|
||||||
|
spacing: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
/* User Menu */
|
/* User Menu */
|
||||||
|
|
||||||
#panelUserMenu {
|
#panelUserMenu {
|
||||||
@ -613,7 +626,15 @@ StScrollBar StButton#vhandle:active {
|
|||||||
/* Overview */
|
/* Overview */
|
||||||
|
|
||||||
#overview {
|
#overview {
|
||||||
spacing: 40px;
|
spacing: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#overview-group {
|
||||||
|
spacing: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.workspaces-display {
|
||||||
|
spacing: 32px; /* needs to be the same value as #overview-group */
|
||||||
}
|
}
|
||||||
|
|
||||||
.window-caption {
|
.window-caption {
|
||||||
@ -702,8 +723,8 @@ StScrollBar StButton#vhandle:active {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.window-picker {
|
.window-picker {
|
||||||
-horizontal-spacing: 40px;
|
-horizontal-spacing: 32px;
|
||||||
-vertical-spacing: 40px;
|
-vertical-spacing: 32px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Dash */
|
/* Dash */
|
||||||
@ -760,7 +781,7 @@ StScrollBar StButton#vhandle:active {
|
|||||||
|
|
||||||
#searchResultsContent {
|
#searchResultsContent {
|
||||||
padding-right: 20px;
|
padding-right: 20px;
|
||||||
spacing: 36px;
|
spacing: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#searchResultsContent:rtl {
|
#searchResultsContent:rtl {
|
||||||
@ -768,11 +789,22 @@ StScrollBar StButton#vhandle:active {
|
|||||||
padding-left: 20px;
|
padding-left: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.search-section-header {
|
.search-section {
|
||||||
padding: 4px 12px;
|
/* This should be equal to #searchResultsContent spacing */
|
||||||
spacing: 4px;
|
spacing: 16px;
|
||||||
color: #6f6f6f;
|
}
|
||||||
font-size: .8em;
|
|
||||||
|
.search-section-separator {
|
||||||
|
-gradient-height: 1px;
|
||||||
|
-gradient-start: rgba(255,255,255,0);
|
||||||
|
-gradient-end: rgba(255,255,255,0.5);
|
||||||
|
-margin-horizontal: 1.5em;
|
||||||
|
height: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-section-content {
|
||||||
|
/* This is the space between the provider icon and the results container */
|
||||||
|
spacing: 32px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.search-statustext {
|
.search-statustext {
|
||||||
@ -781,16 +813,8 @@ StScrollBar StButton#vhandle:active {
|
|||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
.search-section-results {
|
.list-search-results {
|
||||||
padding: 6px;
|
spacing: 3px;
|
||||||
}
|
|
||||||
|
|
||||||
.search-section-list-results {
|
|
||||||
spacing: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.results-container {
|
|
||||||
spacing: 4px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Text labels are an odd number of pixels tall. The uneven top and bottom
|
/* Text labels are an odd number of pixels tall. The uneven top and bottom
|
||||||
@ -819,7 +843,7 @@ StScrollBar StButton#vhandle:active {
|
|||||||
-x-offset: 8px;
|
-x-offset: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Application Launchers and Grid */
|
/* Application Launchers, Grid and List results */
|
||||||
|
|
||||||
.icon-grid {
|
.icon-grid {
|
||||||
spacing: 36px;
|
spacing: 36px;
|
||||||
@ -871,13 +895,38 @@ StScrollBar StButton#vhandle:active {
|
|||||||
padding: 4px 8px;
|
padding: 4px 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.list-search-result-content {
|
||||||
|
spacing: 12px;
|
||||||
|
padding: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.list-search-result-title {
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 14pt;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.list-search-result-description {
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 12pt;
|
||||||
|
color: #eeeeec;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-provider-icon-more {
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
background-image: url("more-results.svg");
|
||||||
|
}
|
||||||
|
|
||||||
.app-well-app > .overview-icon,
|
.app-well-app > .overview-icon,
|
||||||
.show-apps > .overview-icon,
|
.show-apps > .overview-icon,
|
||||||
.search-result-content > .overview-icon {
|
.search-provider-icon,
|
||||||
|
.list-search-result,
|
||||||
|
.grid-search-result .overview-icon {
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
padding: 3px;
|
padding: 3px;
|
||||||
border: 1px rgba(0,0,0,0);
|
border: 1px rgba(0,0,0,0);
|
||||||
transition-duration: 100;
|
transition-duration: 100ms;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -889,10 +938,12 @@ StScrollBar StButton#vhandle:active {
|
|||||||
|
|
||||||
.app-well-app:hover > .overview-icon,
|
.app-well-app:hover > .overview-icon,
|
||||||
.show-apps:hover > .overview-icon,
|
.show-apps:hover > .overview-icon,
|
||||||
.search-result-content:hover > .overview-icon {
|
.search-provider-icon:hover,
|
||||||
|
.list-search-result:hover,
|
||||||
|
.grid-search-result:hover .overview-icon {
|
||||||
background-color: rgba(255,255,255,0.1);
|
background-color: rgba(255,255,255,0.1);
|
||||||
text-shadow: black 0px 2px 2px;
|
text-shadow: black 0px 2px 2px;
|
||||||
transition-duration: 100;
|
transition-duration: 100ms;
|
||||||
color:white;
|
color:white;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -914,20 +965,24 @@ StScrollBar StButton#vhandle:active {
|
|||||||
background-gradient-direction: vertical;
|
background-gradient-direction: vertical;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
box-shadow: inset 0px 1px 2px 0px rgba(0, 0, 0, 1);
|
box-shadow: inset 0px 1px 2px 0px rgba(0, 0, 0, 1);
|
||||||
transition-duration: 100;
|
transition-duration: 100ms;
|
||||||
}
|
}
|
||||||
|
|
||||||
.show-apps:checked .show-apps-icon,
|
.show-apps:checked .show-apps-icon,
|
||||||
.show-apps:focus .show-apps-icon {
|
.show-apps:focus .show-apps-icon {
|
||||||
color: white;
|
color: white;
|
||||||
transition-duration: 100;
|
transition-duration: 100ms;
|
||||||
}
|
}
|
||||||
|
|
||||||
.app-well-app:focus > .overview-icon,
|
.app-well-app:focus > .overview-icon,
|
||||||
.search-result-content:focus > .overview-icon,
|
.grid-search-result:focus .overview-icon,
|
||||||
.show-apps:focus > .overview-icon,
|
.show-apps:focus > .overview-icon,
|
||||||
|
.search-provider-icon:focus,
|
||||||
|
.list-search-result:focus,
|
||||||
.app-well-app:selected > .overview-icon,
|
.app-well-app:selected > .overview-icon,
|
||||||
.search-result-content:selected > .overview-icon {
|
.grid-search-result:selected .overview-icon,
|
||||||
|
.search-provider-icon:selected,
|
||||||
|
.list-search-result:selected {
|
||||||
background-color: rgba(255,255,255,0.33);
|
background-color: rgba(255,255,255,0.33);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -955,7 +1010,7 @@ StScrollBar StButton#vhandle:active {
|
|||||||
-minimum-hpadding: 6px;
|
-minimum-hpadding: 6px;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
color: #ccc;
|
color: #ccc;
|
||||||
transition-duration: 100;
|
transition-duration: 100ms;
|
||||||
padding-left: .3em;
|
padding-left: .3em;
|
||||||
padding-right: .3em;
|
padding-right: .3em;
|
||||||
}
|
}
|
||||||
@ -1258,7 +1313,8 @@ StScrollBar StButton#vhandle:active {
|
|||||||
#message-tray {
|
#message-tray {
|
||||||
background: #2e3436 url(message-tray-background.png);
|
background: #2e3436 url(message-tray-background.png);
|
||||||
background-repeat: repeat;
|
background-repeat: repeat;
|
||||||
transition-duration: 250;
|
transition-duration: 250ms;
|
||||||
|
height: 72px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#message-tray:keyboard {
|
#message-tray:keyboard {
|
||||||
@ -1271,6 +1327,10 @@ StScrollBar StButton#vhandle:active {
|
|||||||
outline: 1px solid rgba(128, 128, 128, 0.3);
|
outline: 1px solid rgba(128, 128, 128, 0.3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.message-tray-summary {
|
||||||
|
height: 72px;
|
||||||
|
}
|
||||||
|
|
||||||
.no-messages-label {
|
.no-messages-label {
|
||||||
font-family: cantarell, sans-serif;
|
font-family: cantarell, sans-serif;
|
||||||
font-size: 11pt;
|
font-size: 11pt;
|
||||||
@ -1279,9 +1339,9 @@ StScrollBar StButton#vhandle:active {
|
|||||||
|
|
||||||
.notification {
|
.notification {
|
||||||
border-radius: 10px 10px 0px 0px;
|
border-radius: 10px 10px 0px 0px;
|
||||||
background: rgba(0,0,0,0.8);
|
background: rgba(0,0,0,0.9);
|
||||||
padding: 8px 8px 4px 8px;
|
padding: 8px 8px 4px 8px;
|
||||||
spacing-rows: 10px;
|
spacing-rows: 4px;
|
||||||
spacing-columns: 10px;
|
spacing-columns: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1311,7 +1371,7 @@ StScrollBar StButton#vhandle:active {
|
|||||||
|
|
||||||
.summary-boxpointer {
|
.summary-boxpointer {
|
||||||
-arrow-border-radius: 15px;
|
-arrow-border-radius: 15px;
|
||||||
-arrow-background-color: rgba(0,0,0,0.8);
|
-arrow-background-color: rgba(0,0,0,0.9);
|
||||||
-arrow-base: 36px;
|
-arrow-base: 36px;
|
||||||
-arrow-rise: 18px;
|
-arrow-rise: 18px;
|
||||||
color: white;
|
color: white;
|
||||||
@ -1361,6 +1421,7 @@ StScrollBar StButton#vhandle:active {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.notification-actions {
|
.notification-actions {
|
||||||
|
padding-top: 18px;
|
||||||
spacing: 10px;
|
spacing: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1499,10 +1560,6 @@ StScrollBar StButton#vhandle:active {
|
|||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#summary-mode {
|
|
||||||
height: 72px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.summary-source-button {
|
.summary-source-button {
|
||||||
padding: 6px 3px 6px 3px;
|
padding: 6px 3px 6px 3px;
|
||||||
}
|
}
|
||||||
@ -1527,7 +1584,7 @@ StScrollBar StButton#vhandle:active {
|
|||||||
.summary-source {
|
.summary-source {
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
padding: 0 6px 0 6px;
|
padding: 0 6px 0 6px;
|
||||||
transition-duration: 100;
|
transition-duration: 100ms;
|
||||||
}
|
}
|
||||||
|
|
||||||
.summary-source-counter {
|
.summary-source-counter {
|
||||||
@ -2389,3 +2446,8 @@ StScrollBar StButton#vhandle:active {
|
|||||||
padding-bottom: 0px;
|
padding-bottom: 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.input-source-switcher-symbol {
|
||||||
|
font-size: 42pt;
|
||||||
|
width: 96px;
|
||||||
|
height: 96px;
|
||||||
|
}
|
||||||
|
109
data/theme/more-results.svg
Normal file
109
data/theme/more-results.svg
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="16"
|
||||||
|
height="16"
|
||||||
|
id="svg12430"
|
||||||
|
version="1.1"
|
||||||
|
inkscape:version="0.48.3.1 r9886"
|
||||||
|
sodipodi:docname="more-results.svg">
|
||||||
|
<defs
|
||||||
|
id="defs12432" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="base"
|
||||||
|
pagecolor="#7a7a7a"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:pageopacity="1"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:zoom="1"
|
||||||
|
inkscape:cx="8.3155237"
|
||||||
|
inkscape:cy="0.89548874"
|
||||||
|
inkscape:document-units="px"
|
||||||
|
inkscape:current-layer="g14642-3-0"
|
||||||
|
showgrid="false"
|
||||||
|
borderlayer="true"
|
||||||
|
inkscape:showpageshadow="false"
|
||||||
|
inkscape:window-width="2560"
|
||||||
|
inkscape:window-height="1376"
|
||||||
|
inkscape:window-x="1200"
|
||||||
|
inkscape:window-y="187"
|
||||||
|
inkscape:window-maximized="1">
|
||||||
|
<inkscape:grid
|
||||||
|
type="xygrid"
|
||||||
|
id="grid13002" />
|
||||||
|
</sodipodi:namedview>
|
||||||
|
<metadata
|
||||||
|
id="metadata12435">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title />
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1"
|
||||||
|
transform="translate(0,-1036.3622)">
|
||||||
|
<g
|
||||||
|
style="display:inline"
|
||||||
|
transform="translate(-141.99984,638.37113)"
|
||||||
|
inkscape:label="zoom-in"
|
||||||
|
id="g14642-3-0">
|
||||||
|
<path
|
||||||
|
sodipodi:type="inkscape:offset"
|
||||||
|
inkscape:radius="0"
|
||||||
|
inkscape:original="M 145.1875 400 C 144.5248 400 144 400.54899 144 401.21875 L 144 410.78125 C 144 411.45101 144.5248 412 145.1875 412 L 154.8125 412 C 155.4752 412 156 411.45101 156 410.78125 L 156 401.21875 C 156 400.54899 155.4752 400 154.8125 400 L 145.1875 400 z M 149 403 L 151 403 L 151 405 L 153 405 L 153 407 L 151 407 L 151 409 L 149 409 L 149 407 L 147 407 L 147 405 L 149 405 L 149 403 z "
|
||||||
|
xlink:href="#rect11749-5-0-1-8"
|
||||||
|
style="color:#bebebe;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;opacity:0.8"
|
||||||
|
id="path13004"
|
||||||
|
inkscape:href="#rect11749-5-0-1-8"
|
||||||
|
d="M 145.1875,400 C 144.5248,400 144,400.54899 144,401.21875 l 0,9.5625 c 0,0.66976 0.5248,1.21875 1.1875,1.21875 l 9.625,0 c 0.6627,0 1.1875,-0.54899 1.1875,-1.21875 l 0,-9.5625 C 156,400.54899 155.4752,400 154.8125,400 L 145.1875,400 z m 3.8125,3 2,0 0,2 2,0 0,2 -2,0 0,2 -2,0 0,-2 -2,0 0,-2 2,0 L 149,403 Z"
|
||||||
|
transform="translate(0,1)" />
|
||||||
|
<use
|
||||||
|
x="0"
|
||||||
|
y="0"
|
||||||
|
xlink:href="#path13004"
|
||||||
|
id="use11960"
|
||||||
|
transform="translate(1,-1)"
|
||||||
|
width="16"
|
||||||
|
height="16" />
|
||||||
|
<use
|
||||||
|
x="0"
|
||||||
|
y="0"
|
||||||
|
xlink:href="#use11960"
|
||||||
|
id="use11962"
|
||||||
|
transform="translate(-2,0)"
|
||||||
|
width="16"
|
||||||
|
height="16" />
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
style="color:#bebebe;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible"
|
||||||
|
d="M 145.1875,400 C 144.5248,400 144,400.54899 144,401.21875 l 0,9.5625 c 0,0.66976 0.5248,1.21875 1.1875,1.21875 l 9.625,0 c 0.6627,0 1.1875,-0.54899 1.1875,-1.21875 l 0,-9.5625 C 156,400.54899 155.4752,400 154.8125,400 L 145.1875,400 z m 3.8125,3 2,0 0,2 2,0 0,2 -2,0 0,2 -2,0 0,-2 -2,0 0,-2 2,0 L 149,403 Z"
|
||||||
|
id="rect11749-5-0-1-8" />
|
||||||
|
<rect
|
||||||
|
style="fill:none;stroke:none"
|
||||||
|
id="rect3620-5-4"
|
||||||
|
width="15.981825"
|
||||||
|
height="16"
|
||||||
|
x="142"
|
||||||
|
y="398"
|
||||||
|
rx="0"
|
||||||
|
ry="0" />
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 4.1 KiB |
@ -88,11 +88,18 @@ doc-gen-org.gnome.Shell.SearchProvider2.xml: $(top_srcdir)/data/org.gnome.ShellS
|
|||||||
--generate-docbook doc-gen \
|
--generate-docbook doc-gen \
|
||||||
$(top_srcdir)/data/org.gnome.ShellSearchProvider2.xml
|
$(top_srcdir)/data/org.gnome.ShellSearchProvider2.xml
|
||||||
|
|
||||||
|
doc-gen-org.gnome.Shell.Screenshot.xml: $(top_srcdir)/data/org.gnome.Shell.Screenshot.xml
|
||||||
|
gdbus-codegen \
|
||||||
|
--interface-prefix org.gnome.Shell.Screenshot. \
|
||||||
|
--generate-docbook doc-gen \
|
||||||
|
$(top_srcdir)/data/org.gnome.Shell.Screenshot.xml
|
||||||
|
|
||||||
# Extra SGML files that are included by $(DOC_MAIN_SGML_FILE).
|
# Extra SGML files that are included by $(DOC_MAIN_SGML_FILE).
|
||||||
# e.g. content_files=running.sgml building.sgml changes-2.0.sgml
|
# e.g. content_files=running.sgml building.sgml changes-2.0.sgml
|
||||||
content_files= \
|
content_files= \
|
||||||
doc-gen-org.gnome.Shell.SearchProvider.xml \
|
doc-gen-org.gnome.Shell.SearchProvider.xml \
|
||||||
doc-gen-org.gnome.Shell.SearchProvider2.xml
|
doc-gen-org.gnome.Shell.SearchProvider2.xml \
|
||||||
|
doc-gen-org.gnome.Shell.Screenshot.xml
|
||||||
|
|
||||||
# SGML files where gtk-doc abbrevations (#GtkWidget) are expanded
|
# SGML files where gtk-doc abbrevations (#GtkWidget) are expanded
|
||||||
# These files must be listed here *and* in content_files
|
# These files must be listed here *and* in content_files
|
||||||
|
@ -49,7 +49,6 @@ nobase_dist_js_DATA = \
|
|||||||
ui/extensionSystem.js \
|
ui/extensionSystem.js \
|
||||||
ui/extensionDownloader.js \
|
ui/extensionDownloader.js \
|
||||||
ui/environment.js \
|
ui/environment.js \
|
||||||
ui/flashspot.js \
|
|
||||||
ui/ibusCandidatePopup.js\
|
ui/ibusCandidatePopup.js\
|
||||||
ui/grabHelper.js \
|
ui/grabHelper.js \
|
||||||
ui/iconGrid.js \
|
ui/iconGrid.js \
|
||||||
@ -62,6 +61,7 @@ nobase_dist_js_DATA = \
|
|||||||
ui/main.js \
|
ui/main.js \
|
||||||
ui/messageTray.js \
|
ui/messageTray.js \
|
||||||
ui/modalDialog.js \
|
ui/modalDialog.js \
|
||||||
|
ui/separator.js \
|
||||||
ui/sessionMode.js \
|
ui/sessionMode.js \
|
||||||
ui/shellEntry.js \
|
ui/shellEntry.js \
|
||||||
ui/shellMountOperation.js \
|
ui/shellMountOperation.js \
|
||||||
@ -73,6 +73,7 @@ nobase_dist_js_DATA = \
|
|||||||
ui/popupMenu.js \
|
ui/popupMenu.js \
|
||||||
ui/remoteSearch.js \
|
ui/remoteSearch.js \
|
||||||
ui/runDialog.js \
|
ui/runDialog.js \
|
||||||
|
ui/screenshot.js \
|
||||||
ui/screenShield.js \
|
ui/screenShield.js \
|
||||||
ui/scripting.js \
|
ui/scripting.js \
|
||||||
ui/search.js \
|
ui/search.js \
|
||||||
|
@ -532,6 +532,7 @@ const SessionListItem = new Lang.Class({
|
|||||||
color.alpha / 255);
|
color.alpha / 255);
|
||||||
cr.arc(width / 2, height / 2, width / 3, 0, 2 * Math.PI);
|
cr.arc(width / 2, height / 2, width / 3, 0, 2 * Math.PI);
|
||||||
cr.fill();
|
cr.fill();
|
||||||
|
cr.$dispose();
|
||||||
},
|
},
|
||||||
|
|
||||||
_onClicked: function() {
|
_onClicked: function() {
|
||||||
|
@ -19,7 +19,6 @@ const IconGrid = imports.ui.iconGrid;
|
|||||||
const Main = imports.ui.main;
|
const Main = imports.ui.main;
|
||||||
const Overview = imports.ui.overview;
|
const Overview = imports.ui.overview;
|
||||||
const PopupMenu = imports.ui.popupMenu;
|
const PopupMenu = imports.ui.popupMenu;
|
||||||
const Search = imports.ui.search;
|
|
||||||
const Tweener = imports.ui.tweener;
|
const Tweener = imports.ui.tweener;
|
||||||
const Workspace = imports.ui.workspace;
|
const Workspace = imports.ui.workspace;
|
||||||
const Params = imports.misc.params;
|
const Params = imports.misc.params;
|
||||||
@ -312,11 +311,10 @@ const AllAppDisplay = new Lang.Class({
|
|||||||
|
|
||||||
const AppSearchProvider = new Lang.Class({
|
const AppSearchProvider = new Lang.Class({
|
||||||
Name: 'AppSearchProvider',
|
Name: 'AppSearchProvider',
|
||||||
Extends: Search.SearchProvider,
|
|
||||||
|
|
||||||
_init: function() {
|
_init: function() {
|
||||||
this.parent(_("APPLICATIONS"));
|
|
||||||
this._appSys = Shell.AppSystem.get_default();
|
this._appSys = Shell.AppSystem.get_default();
|
||||||
|
this.id = 'applications';
|
||||||
},
|
},
|
||||||
|
|
||||||
getResultMetas: function(apps, callback) {
|
getResultMetas: function(apps, callback) {
|
||||||
@ -369,13 +367,10 @@ const AppSearchProvider = new Lang.Class({
|
|||||||
|
|
||||||
const SettingsSearchProvider = new Lang.Class({
|
const SettingsSearchProvider = new Lang.Class({
|
||||||
Name: 'SettingsSearchProvider',
|
Name: 'SettingsSearchProvider',
|
||||||
Extends: Search.SearchProvider,
|
|
||||||
|
|
||||||
_init: function() {
|
_init: function() {
|
||||||
this.parent(_("SETTINGS"));
|
|
||||||
|
|
||||||
this._appSys = Shell.AppSystem.get_default();
|
|
||||||
this.appInfo = Gio.DesktopAppInfo.new('gnome-control-center.desktop');
|
this.appInfo = Gio.DesktopAppInfo.new('gnome-control-center.desktop');
|
||||||
|
this._appSys = Shell.AppSystem.get_default();
|
||||||
},
|
},
|
||||||
|
|
||||||
getResultMetas: function(prefs, callback) {
|
getResultMetas: function(prefs, callback) {
|
||||||
@ -384,9 +379,7 @@ const SettingsSearchProvider = new Lang.Class({
|
|||||||
let pref = prefs[i];
|
let pref = prefs[i];
|
||||||
metas.push({ 'id': pref,
|
metas.push({ 'id': pref,
|
||||||
'name': pref.get_name(),
|
'name': pref.get_name(),
|
||||||
'createIcon': function(size) {
|
'createIcon': function() { return null; }
|
||||||
return pref.create_icon_texture(size);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
callback(metas);
|
callback(metas);
|
||||||
@ -404,12 +397,6 @@ const SettingsSearchProvider = new Lang.Class({
|
|||||||
pref.activate();
|
pref.activate();
|
||||||
},
|
},
|
||||||
|
|
||||||
createResultActor: function (resultMeta, terms) {
|
|
||||||
let app = resultMeta['id'];
|
|
||||||
let icon = new AppWellIcon(app);
|
|
||||||
return icon.actor;
|
|
||||||
},
|
|
||||||
|
|
||||||
launchSearch: function(terms) {
|
launchSearch: function(terms) {
|
||||||
// FIXME: this should be a remote search provider
|
// FIXME: this should be a remote search provider
|
||||||
this.appInfo.launch([], global.create_app_launch_context());
|
this.appInfo.launch([], global.create_app_launch_context());
|
||||||
|
@ -220,25 +220,8 @@ const BoxPointer = new Lang.Class({
|
|||||||
this.bin.allocate(childBox, flags);
|
this.bin.allocate(childBox, flags);
|
||||||
|
|
||||||
if (this._sourceActor && this._sourceActor.mapped) {
|
if (this._sourceActor && this._sourceActor.mapped) {
|
||||||
this._reposition(this._sourceActor, this._arrowAlignment);
|
this._reposition();
|
||||||
|
this._updateFlip();
|
||||||
if (this._shouldFlip()) {
|
|
||||||
switch (this._arrowSide) {
|
|
||||||
case St.Side.TOP:
|
|
||||||
this._arrowSide = St.Side.BOTTOM;
|
|
||||||
break;
|
|
||||||
case St.Side.BOTTOM:
|
|
||||||
this._arrowSide = St.Side.TOP;
|
|
||||||
break;
|
|
||||||
case St.Side.LEFT:
|
|
||||||
this._arrowSide = St.Side.RIGHT;
|
|
||||||
break;
|
|
||||||
case St.Side.RIGHT:
|
|
||||||
this._arrowSide = St.Side.LEFT;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
this._reposition(this._sourceActor, this._arrowAlignment);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -405,11 +388,11 @@ const BoxPointer = new Lang.Class({
|
|||||||
cr.setLineWidth(borderWidth);
|
cr.setLineWidth(borderWidth);
|
||||||
cr.stroke();
|
cr.stroke();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cr.$dispose();
|
||||||
},
|
},
|
||||||
|
|
||||||
setPosition: function(sourceActor, alignment) {
|
setPosition: function(sourceActor, alignment) {
|
||||||
this._arrowSide = this._userArrowSide;
|
|
||||||
|
|
||||||
// We need to show it now to force an allocation,
|
// We need to show it now to force an allocation,
|
||||||
// so that we can query the correct size.
|
// so that we can query the correct size.
|
||||||
this.actor.show();
|
this.actor.show();
|
||||||
@ -417,7 +400,8 @@ const BoxPointer = new Lang.Class({
|
|||||||
this._sourceActor = sourceActor;
|
this._sourceActor = sourceActor;
|
||||||
this._arrowAlignment = alignment;
|
this._arrowAlignment = alignment;
|
||||||
|
|
||||||
this._reposition(sourceActor, alignment);
|
this._reposition();
|
||||||
|
this._updateFlip();
|
||||||
},
|
},
|
||||||
|
|
||||||
setSourceAlignment: function(alignment) {
|
setSourceAlignment: function(alignment) {
|
||||||
@ -429,7 +413,10 @@ const BoxPointer = new Lang.Class({
|
|||||||
this.setPosition(this._sourceActor, this._arrowAlignment);
|
this.setPosition(this._sourceActor, this._arrowAlignment);
|
||||||
},
|
},
|
||||||
|
|
||||||
_reposition: function(sourceActor, alignment) {
|
_reposition: function() {
|
||||||
|
let sourceActor = this._sourceActor;
|
||||||
|
let alignment = this._arrowAlignment;
|
||||||
|
|
||||||
// Position correctly relative to the sourceActor
|
// Position correctly relative to the sourceActor
|
||||||
let sourceNode = sourceActor.get_theme_node();
|
let sourceNode = sourceActor.get_theme_node();
|
||||||
let sourceContentBox = sourceNode.get_content_box(sourceActor.get_allocation_box());
|
let sourceContentBox = sourceNode.get_content_box(sourceActor.get_allocation_box());
|
||||||
@ -553,7 +540,7 @@ const BoxPointer = new Lang.Class({
|
|||||||
_shiftActor : function() {
|
_shiftActor : function() {
|
||||||
// Since the position of the BoxPointer depends on the allocated size
|
// Since the position of the BoxPointer depends on the allocated size
|
||||||
// of the BoxPointer and the position of the source actor, trying
|
// of the BoxPointer and the position of the source actor, trying
|
||||||
// to position the BoxPoiner via the x/y properties will result in
|
// to position the BoxPointer via the x/y properties will result in
|
||||||
// allocation loops and warnings. Instead we do the positioning via
|
// allocation loops and warnings. Instead we do the positioning via
|
||||||
// the anchor point, which is independent of allocation, and leave
|
// the anchor point, which is independent of allocation, and leave
|
||||||
// x == y == 0.
|
// x == y == 0.
|
||||||
@ -561,37 +548,47 @@ const BoxPointer = new Lang.Class({
|
|||||||
-(this._yPosition + this._yOffset));
|
-(this._yPosition + this._yOffset));
|
||||||
},
|
},
|
||||||
|
|
||||||
_shouldFlip: function() {
|
_calculateArrowSide: function(arrowSide) {
|
||||||
let sourceAllocation = Shell.util_get_transformed_allocation(this._sourceActor);
|
let sourceAllocation = Shell.util_get_transformed_allocation(this._sourceActor);
|
||||||
let boxAllocation = Shell.util_get_transformed_allocation(this.actor);
|
let [minWidth, minHeight, boxWidth, boxHeight] = this._container.get_preferred_size();
|
||||||
let boxWidth = boxAllocation.x2 - boxAllocation.x1;
|
|
||||||
let boxHeight = boxAllocation.y2 - boxAllocation.y1;
|
|
||||||
let monitor = Main.layoutManager.findMonitorForActor(this.actor);
|
let monitor = Main.layoutManager.findMonitorForActor(this.actor);
|
||||||
|
|
||||||
switch (this._arrowSide) {
|
switch (arrowSide) {
|
||||||
case St.Side.TOP:
|
case St.Side.TOP:
|
||||||
if (boxAllocation.y2 > monitor.y + monitor.height &&
|
if (sourceAllocation.y2 + boxHeight > monitor.y + monitor.height &&
|
||||||
boxHeight < sourceAllocation.y1 - monitor.y)
|
boxHeight < sourceAllocation.y1 - monitor.y)
|
||||||
return true;
|
return St.Side.BOTTOM;
|
||||||
break;
|
break;
|
||||||
case St.Side.BOTTOM:
|
case St.Side.BOTTOM:
|
||||||
if (boxAllocation.y1 < monitor.y &&
|
if (sourceAllocation.y1 - boxHeight < monitor.y &&
|
||||||
boxHeight < monitor.y + monitor.height - sourceAllocation.y2)
|
boxHeight < monitor.y + monitor.height - sourceAllocation.y2)
|
||||||
return true;
|
return St.Side.TOP;
|
||||||
break;
|
break;
|
||||||
case St.Side.LEFT:
|
case St.Side.LEFT:
|
||||||
if (boxAllocation.x2 > monitor.x + monitor.width &&
|
if (sourceAllocation.y2 + boxWidth > monitor.x + monitor.width &&
|
||||||
boxWidth < sourceAllocation.x1 - monitor.x)
|
boxWidth < sourceAllocation.x1 - monitor.x)
|
||||||
return true;
|
return St.Side.RIGHT;
|
||||||
break;
|
break;
|
||||||
case St.Side.RIGHT:
|
case St.Side.RIGHT:
|
||||||
if (boxAllocation.x1 < monitor.x &&
|
if (sourceAllocation.y1 - boxWidth < monitor.x &&
|
||||||
boxWidth < monitor.x + monitor.width - sourceAllocation.x2)
|
boxWidth < monitor.x + monitor.width - sourceAllocation.x2)
|
||||||
return true;
|
return St.Side.LEFT;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return arrowSide;
|
||||||
|
},
|
||||||
|
|
||||||
|
_updateFlip: function() {
|
||||||
|
let arrowSide = this._calculateArrowSide(this._userArrowSide);
|
||||||
|
if (this._arrowSide != arrowSide) {
|
||||||
|
this._arrowSide = arrowSide;
|
||||||
|
this._reposition();
|
||||||
|
Meta.later_add(Meta.LaterType.BEFORE_REDRAW, Lang.bind(this, function() {
|
||||||
|
this._container.queue_relayout();
|
||||||
|
return false;
|
||||||
|
}));
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
set xOffset(offset) {
|
set xOffset(offset) {
|
||||||
|
@ -11,7 +11,6 @@ const Mainloop = imports.mainloop;
|
|||||||
const Shell = imports.gi.Shell;
|
const Shell = imports.gi.Shell;
|
||||||
|
|
||||||
const MSECS_IN_DAY = 24 * 60 * 60 * 1000;
|
const MSECS_IN_DAY = 24 * 60 * 60 * 1000;
|
||||||
const WEEKDATE_HEADER_WIDTH_DIGITS = 3;
|
|
||||||
const SHOW_WEEKDATE_KEY = 'show-weekdate';
|
const SHOW_WEEKDATE_KEY = 'show-weekdate';
|
||||||
|
|
||||||
// in org.gnome.desktop.interface
|
// in org.gnome.desktop.interface
|
||||||
@ -95,15 +94,6 @@ function _getCalendarWeekForDate(date) {
|
|||||||
return weekNumber;
|
return weekNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
function _getDigitWidth(actor){
|
|
||||||
let context = actor.get_pango_context();
|
|
||||||
let themeNode = actor.get_theme_node();
|
|
||||||
let font = themeNode.get_font();
|
|
||||||
let metrics = context.get_metrics(font, context.get_language());
|
|
||||||
let width = metrics.get_approximate_digit_width();
|
|
||||||
return width;
|
|
||||||
}
|
|
||||||
|
|
||||||
function _getCalendarDayAbbreviation(dayNumber) {
|
function _getCalendarDayAbbreviation(dayNumber) {
|
||||||
let abbreviations = [
|
let abbreviations = [
|
||||||
/* Translators: Calendar grid abbreviation for Sunday.
|
/* Translators: Calendar grid abbreviation for Sunday.
|
||||||
@ -345,8 +335,6 @@ const Calendar = new Lang.Class({
|
|||||||
|
|
||||||
_init: function() {
|
_init: function() {
|
||||||
this._weekStart = Shell.util_get_week_start();
|
this._weekStart = Shell.util_get_week_start();
|
||||||
this._weekdate = NaN;
|
|
||||||
this._digitWidth = NaN;
|
|
||||||
this._settings = new Gio.Settings({ schema: 'org.gnome.shell.calendar' });
|
this._settings = new Gio.Settings({ schema: 'org.gnome.shell.calendar' });
|
||||||
|
|
||||||
this._settings.connect('changed::' + SHOW_WEEKDATE_KEY, Lang.bind(this, this._onSettingsChange));
|
this._settings.connect('changed::' + SHOW_WEEKDATE_KEY, Lang.bind(this, this._onSettingsChange));
|
||||||
@ -419,8 +407,6 @@ const Calendar = new Lang.Class({
|
|||||||
this.actor.add(this._topBox,
|
this.actor.add(this._topBox,
|
||||||
{ row: 0, col: 0, col_span: offsetCols + 7 });
|
{ row: 0, col: 0, col_span: offsetCols + 7 });
|
||||||
|
|
||||||
this.actor.connect('style-changed', Lang.bind(this, this._onStyleChange));
|
|
||||||
|
|
||||||
let back = new St.Button({ style_class: 'calendar-change-month-back' });
|
let back = new St.Button({ style_class: 'calendar-change-month-back' });
|
||||||
this._topBox.add(back);
|
this._topBox.add(back);
|
||||||
back.connect('clicked', Lang.bind(this, this._onPrevMonthButtonClicked));
|
back.connect('clicked', Lang.bind(this, this._onPrevMonthButtonClicked));
|
||||||
@ -457,18 +443,6 @@ const Calendar = new Lang.Class({
|
|||||||
this._firstDayIndex = this.actor.get_n_children();
|
this._firstDayIndex = this.actor.get_n_children();
|
||||||
},
|
},
|
||||||
|
|
||||||
_onStyleChange: function(actor, event) {
|
|
||||||
// width of a digit in pango units
|
|
||||||
this._digitWidth = _getDigitWidth(this.actor) / Pango.SCALE;
|
|
||||||
this._setWeekdateHeaderWidth();
|
|
||||||
},
|
|
||||||
|
|
||||||
_setWeekdateHeaderWidth: function() {
|
|
||||||
if (this.digitWidth != NaN && this._useWeekdate && this._weekdateHeader) {
|
|
||||||
this._weekdateHeader.set_width (this._digitWidth * WEEKDATE_HEADER_WIDTH_DIGITS);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
_onScroll : function(actor, event) {
|
_onScroll : function(actor, event) {
|
||||||
switch (event.get_scroll_direction()) {
|
switch (event.get_scroll_direction()) {
|
||||||
case Clutter.ScrollDirection.UP:
|
case Clutter.ScrollDirection.UP:
|
||||||
|
@ -60,18 +60,14 @@ const KeyringDialog = new Lang.Class({
|
|||||||
|
|
||||||
this._controlTable = null;
|
this._controlTable = null;
|
||||||
|
|
||||||
let buttons = [{ label: '',
|
|
||||||
action: Lang.bind(this, this._onCancelButton),
|
|
||||||
key: Clutter.Escape
|
|
||||||
},
|
|
||||||
{ label: '',
|
|
||||||
action: Lang.bind(this, this._onContinueButton),
|
|
||||||
default: true
|
|
||||||
}]
|
|
||||||
|
|
||||||
this.setButtons(buttons);
|
this._cancelButton = this.addButton({ label: '',
|
||||||
this._cancelButton = buttons[0].button;
|
action: Lang.bind(this, this._onCancelButton),
|
||||||
this._continueButton = buttons[1].button;
|
key: Clutter.Escape });
|
||||||
|
this._continueButton = this.addButton({ label: '',
|
||||||
|
action: Lang.bind(this, this._onContinueButton),
|
||||||
|
default: true },
|
||||||
|
{ expand: true, x_fill: false, x_align: St.Align.END });
|
||||||
|
|
||||||
this.prompt.bind_property('cancel-label', this._cancelButton, 'label', GObject.BindingFlags.SYNC_CREATE);
|
this.prompt.bind_property('cancel-label', this._cancelButton, 'label', GObject.BindingFlags.SYNC_CREATE);
|
||||||
this.prompt.bind_property('continue-label', this._continueButton, 'label', GObject.BindingFlags.SYNC_CREATE);
|
this.prompt.bind_property('continue-label', this._continueButton, 'label', GObject.BindingFlags.SYNC_CREATE);
|
||||||
@ -146,6 +142,14 @@ const KeyringDialog = new Lang.Class({
|
|||||||
this._messageBox.add(table, { x_fill: true, y_fill: true });
|
this._messageBox.add(table, { x_fill: true, y_fill: true });
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_updateSensitivity: function(sensitive) {
|
||||||
|
this._passwordEntry.reactive = sensitive;
|
||||||
|
this._passwordEntry.clutter_text.editable = sensitive;
|
||||||
|
|
||||||
|
this._continueButton.can_focus = sensitive;
|
||||||
|
this._continueButton.reactive = sensitive;
|
||||||
|
},
|
||||||
|
|
||||||
_ensureOpen: function() {
|
_ensureOpen: function() {
|
||||||
// NOTE: ModalDialog.open() is safe to call if the dialog is
|
// NOTE: ModalDialog.open() is safe to call if the dialog is
|
||||||
// already open - it just returns true without side-effects
|
// already open - it just returns true without side-effects
|
||||||
@ -167,12 +171,14 @@ const KeyringDialog = new Lang.Class({
|
|||||||
_onShowPassword: function(prompt) {
|
_onShowPassword: function(prompt) {
|
||||||
this._buildControlTable();
|
this._buildControlTable();
|
||||||
this._ensureOpen();
|
this._ensureOpen();
|
||||||
|
this._updateSensitivity(true);
|
||||||
this._passwordEntry.grab_key_focus();
|
this._passwordEntry.grab_key_focus();
|
||||||
},
|
},
|
||||||
|
|
||||||
_onShowConfirm: function(prompt) {
|
_onShowConfirm: function(prompt) {
|
||||||
this._buildControlTable();
|
this._buildControlTable();
|
||||||
this._ensureOpen();
|
this._ensureOpen();
|
||||||
|
this._updateSensitivity(true);
|
||||||
this._continueButton.grab_key_focus();
|
this._continueButton.grab_key_focus();
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -192,6 +198,7 @@ const KeyringDialog = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
_onContinueButton: function() {
|
_onContinueButton: function() {
|
||||||
|
this._updateSensitivity(false);
|
||||||
this.prompt.complete();
|
this.prompt.complete();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -613,7 +613,8 @@ const NetworkAgent = new Lang.Class({
|
|||||||
this._vpnRequests = { };
|
this._vpnRequests = { };
|
||||||
|
|
||||||
this._native.auto_register = false;
|
this._native.auto_register = false;
|
||||||
this._native.unregister();
|
if (this._native.registered)
|
||||||
|
this._native.unregister();
|
||||||
},
|
},
|
||||||
|
|
||||||
_newRequest: function(agent, requestId, connection, settingName, hints, flags) {
|
_newRequest: function(agent, requestId, connection, settingName, hints, flags) {
|
||||||
|
@ -159,14 +159,13 @@ const AuthenticationDialog = new Lang.Class({
|
|||||||
messageBox.add(this._nullMessageLabel);
|
messageBox.add(this._nullMessageLabel);
|
||||||
this._nullMessageLabel.show();
|
this._nullMessageLabel.show();
|
||||||
|
|
||||||
this.setButtons([{ label: _("Cancel"),
|
this._cancelButton = this.addButton({ label: _("Cancel"),
|
||||||
action: Lang.bind(this, this.cancel),
|
action: Lang.bind(this, this.cancel),
|
||||||
key: Clutter.Escape
|
key: Clutter.Escape });
|
||||||
},
|
this._okButton = this.addButton({ label: _("Authenticate"),
|
||||||
{ label: _("Authenticate"),
|
action: Lang.bind(this, this._onAuthenticateButtonPressed),
|
||||||
action: Lang.bind(this, this._onAuthenticateButtonPressed),
|
default: true },
|
||||||
default: true
|
{ expand: true, x_fill: false, x_align: St.Align.END });
|
||||||
}]);
|
|
||||||
|
|
||||||
this._doneEmitted = false;
|
this._doneEmitted = false;
|
||||||
|
|
||||||
@ -214,8 +213,17 @@ const AuthenticationDialog = new Lang.Class({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_updateSensitivity: function(sensitive) {
|
||||||
|
this._passwordEntry.reactive = sensitive;
|
||||||
|
this._passwordEntry.clutter_text.editable = sensitive;
|
||||||
|
|
||||||
|
this._okButton.can_focus = sensitive;
|
||||||
|
this._okButton.reactive = sensitive;
|
||||||
|
},
|
||||||
|
|
||||||
_onEntryActivate: function() {
|
_onEntryActivate: function() {
|
||||||
let response = this._passwordEntry.get_text();
|
let response = this._passwordEntry.get_text();
|
||||||
|
this._updateSensitivity(false);
|
||||||
this._session.response(response);
|
this._session.response(response);
|
||||||
// When the user responds, dismiss already shown info and
|
// When the user responds, dismiss already shown info and
|
||||||
// error texts (if any)
|
// error texts (if any)
|
||||||
@ -269,6 +277,7 @@ const AuthenticationDialog = new Lang.Class({
|
|||||||
this._passwordBox.show();
|
this._passwordBox.show();
|
||||||
this._passwordEntry.set_text('');
|
this._passwordEntry.set_text('');
|
||||||
this._passwordEntry.grab_key_focus();
|
this._passwordEntry.grab_key_focus();
|
||||||
|
this._updateSensitivity(true);
|
||||||
this._ensureOpen();
|
this._ensureOpen();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -1346,9 +1346,8 @@ const AccountNotification = new Lang.Class({
|
|||||||
this.connect('action-invoked', Lang.bind(this, function(self, action) {
|
this.connect('action-invoked', Lang.bind(this, function(self, action) {
|
||||||
switch (action) {
|
switch (action) {
|
||||||
case 'view':
|
case 'view':
|
||||||
let cmd = '/usr/bin/empathy-accounts'
|
let cmd = 'empathy-accounts --select-account=' +
|
||||||
+ ' --select-account=%s'
|
account.get_path_suffix();
|
||||||
.format(account.get_path_suffix());
|
|
||||||
let app_info = Gio.app_info_create_from_commandline(cmd, null, 0);
|
let app_info = Gio.app_info_create_from_commandline(cmd, null, 0);
|
||||||
app_info.launch([], global.create_app_launch_context());
|
app_info.launch([], global.create_app_launch_context());
|
||||||
break;
|
break;
|
||||||
|
@ -102,8 +102,7 @@ const CtrlAltTabManager = new Lang.Class({
|
|||||||
icon = app.create_icon_texture(POPUP_APPICON_SIZE);
|
icon = app.create_icon_texture(POPUP_APPICON_SIZE);
|
||||||
else
|
else
|
||||||
icon = textureCache.bind_pixbuf_property(windows[i], 'icon');
|
icon = textureCache.bind_pixbuf_property(windows[i], 'icon');
|
||||||
items.push({ window: windows[i],
|
items.push({ name: windows[i].title,
|
||||||
name: windows[i].title,
|
|
||||||
iconActor: icon,
|
iconActor: icon,
|
||||||
sortGroup: SortGroup.MIDDLE });
|
sortGroup: SortGroup.MIDDLE });
|
||||||
}
|
}
|
||||||
|
@ -32,6 +32,7 @@ function _onVertSepRepaint (area)
|
|||||||
cr.setDash([1, 3], 1); // Hard-code for now
|
cr.setDash([1, 3], 1); // Hard-code for now
|
||||||
cr.setLineWidth(stippleWidth);
|
cr.setLineWidth(stippleWidth);
|
||||||
cr.stroke();
|
cr.stroke();
|
||||||
|
cr.$dispose();
|
||||||
};
|
};
|
||||||
|
|
||||||
const DateMenuButton = new Lang.Class({
|
const DateMenuButton = new Lang.Class({
|
||||||
@ -113,11 +114,6 @@ const DateMenuButton = new Lang.Class({
|
|||||||
this._openCalendarItem.actor.can_focus = false;
|
this._openCalendarItem.actor.can_focus = false;
|
||||||
vbox.add(this._openCalendarItem.actor, {y_align: St.Align.END, expand: true, y_fill: false});
|
vbox.add(this._openCalendarItem.actor, {y_align: St.Align.END, expand: true, y_fill: false});
|
||||||
|
|
||||||
this._calendarSettings = new Gio.Settings({ schema: 'org.gnome.desktop.default-applications.office.calendar' });
|
|
||||||
this._calendarSettings.connect('changed::exec',
|
|
||||||
Lang.bind(this, this._calendarSettingsChanged));
|
|
||||||
this._calendarSettingsChanged();
|
|
||||||
|
|
||||||
// Whenever the menu is opened, select today
|
// Whenever the menu is opened, select today
|
||||||
this.menu.connect('open-state-changed', Lang.bind(this, function(menu, isOpen) {
|
this.menu.connect('open-state-changed', Lang.bind(this, function(menu, isOpen) {
|
||||||
if (isOpen) {
|
if (isOpen) {
|
||||||
@ -151,12 +147,6 @@ const DateMenuButton = new Lang.Class({
|
|||||||
this._sessionUpdated();
|
this._sessionUpdated();
|
||||||
},
|
},
|
||||||
|
|
||||||
_calendarSettingsChanged: function() {
|
|
||||||
let exec = this._calendarSettings.get_string('exec');
|
|
||||||
let fullExec = GLib.find_program_in_path(exec);
|
|
||||||
this._openCalendarItem.actor.visible = fullExec != null;
|
|
||||||
},
|
|
||||||
|
|
||||||
_setEventsVisibility: function(visible) {
|
_setEventsVisibility: function(visible) {
|
||||||
this._openCalendarItem.actor.visible = visible;
|
this._openCalendarItem.actor.visible = visible;
|
||||||
this._separator.visible = visible;
|
this._separator.visible = visible;
|
||||||
@ -205,24 +195,8 @@ const DateMenuButton = new Lang.Class({
|
|||||||
|
|
||||||
_onOpenCalendarActivate: function() {
|
_onOpenCalendarActivate: function() {
|
||||||
this.menu.close();
|
this.menu.close();
|
||||||
let tool = this._calendarSettings.get_string('exec');
|
|
||||||
if (tool.length == 0 || tool.substr(0, 9) == 'evolution') {
|
let app = Gio.AppInfo.get_default_for_type('text/calendar', false);
|
||||||
// TODO: pass the selected day
|
app.launch([], global.create_app_launch_context());
|
||||||
let app = Shell.AppSystem.get_default().lookup_app('evolution-calendar.desktop');
|
|
||||||
app.activate();
|
|
||||||
} else {
|
|
||||||
let needTerm = this._calendarSettings.get_boolean('needs-term');
|
|
||||||
if (needTerm) {
|
|
||||||
let terminalSettings = new Gio.Settings({ schema: 'org.gnome.desktop.default-applications.terminal' });
|
|
||||||
let term = terminalSettings.get_string('exec');
|
|
||||||
let arg = terminalSettings.get_string('exec-arg');
|
|
||||||
if (arg != '')
|
|
||||||
Util.spawn([term, arg, tool]);
|
|
||||||
else
|
|
||||||
Util.spawn([term, tool]);
|
|
||||||
} else {
|
|
||||||
Util.spawnCommandLine(tool)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -234,7 +234,7 @@ const _Draggable = new Lang.Class({
|
|||||||
this._dragY = this._dragStartY = stageY;
|
this._dragY = this._dragStartY = stageY;
|
||||||
|
|
||||||
if (this.actor._delegate && this.actor._delegate.getDragActor) {
|
if (this.actor._delegate && this.actor._delegate.getDragActor) {
|
||||||
this._dragActor = this.actor._delegate.getDragActor(this._dragStartX, this._dragStartY);
|
this._dragActor = this.actor._delegate.getDragActor();
|
||||||
this._dragActor.reparent(Main.uiGroup);
|
this._dragActor.reparent(Main.uiGroup);
|
||||||
this._dragActor.raise_top();
|
this._dragActor.raise_top();
|
||||||
Shell.util_set_hidden_from_pick(this._dragActor, true);
|
Shell.util_set_hidden_from_pick(this._dragActor, true);
|
||||||
|
@ -129,6 +129,7 @@ function logExtensionError(uuid, error) {
|
|||||||
extension.state = ExtensionState.ERROR;
|
extension.state = ExtensionState.ERROR;
|
||||||
if (!extension.errors)
|
if (!extension.errors)
|
||||||
extension.errors = [];
|
extension.errors = [];
|
||||||
|
extension.errors.push(message);
|
||||||
|
|
||||||
log('Extension "%s" had error: %s'.format(uuid, message));
|
log('Extension "%s" had error: %s'.format(uuid, message));
|
||||||
_signals.emit('extension-state-changed', { uuid: uuid,
|
_signals.emit('extension-state-changed', { uuid: uuid,
|
||||||
|
@ -1,45 +0,0 @@
|
|||||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
|
||||||
|
|
||||||
const Lang = imports.lang;
|
|
||||||
|
|
||||||
const Lightbox = imports.ui.lightbox;
|
|
||||||
const Main = imports.ui.main;
|
|
||||||
const Tweener = imports.ui.tweener;
|
|
||||||
|
|
||||||
const FLASHSPOT_ANIMATION_TIME = 0.25; // seconds
|
|
||||||
|
|
||||||
const Flashspot = new Lang.Class({
|
|
||||||
Name: 'Flashspot',
|
|
||||||
Extends: Lightbox.Lightbox,
|
|
||||||
|
|
||||||
_init: function(area) {
|
|
||||||
this.parent(Main.uiGroup, { inhibitEvents: true,
|
|
||||||
width: area.width,
|
|
||||||
height: area.height });
|
|
||||||
|
|
||||||
this.actor.style_class = 'flashspot';
|
|
||||||
this.actor.set_position(area.x, area.y);
|
|
||||||
},
|
|
||||||
|
|
||||||
fire: function() {
|
|
||||||
this.actor.opacity = 0;
|
|
||||||
Tweener.addTween(this.actor,
|
|
||||||
{ opacity: 255,
|
|
||||||
time: FLASHSPOT_ANIMATION_TIME,
|
|
||||||
transition: 'linear',
|
|
||||||
onComplete: Lang.bind(this, this._onFireShowComplete)
|
|
||||||
});
|
|
||||||
this.actor.show();
|
|
||||||
},
|
|
||||||
|
|
||||||
_onFireShowComplete: function() {
|
|
||||||
Tweener.addTween(this.actor,
|
|
||||||
{ opacity: 0,
|
|
||||||
time: FLASHSPOT_ANIMATION_TIME,
|
|
||||||
transition: 'linear',
|
|
||||||
onComplete: Lang.bind(this, function() {
|
|
||||||
this.destroy();
|
|
||||||
})
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
@ -183,6 +183,9 @@ const GrabHelper = new Lang.Class({
|
|||||||
else if (hadFocus || params.grabFocus)
|
else if (hadFocus || params.grabFocus)
|
||||||
_navigateActor(newFocus);
|
_navigateActor(newFocus);
|
||||||
|
|
||||||
|
if ((params.grabFocus || params.modal) && !this._capturedEventId)
|
||||||
|
this._capturedEventId = global.stage.connect('captured-event', Lang.bind(this, this._onCapturedEvent));
|
||||||
|
|
||||||
this._grabStack.push(params);
|
this._grabStack.push(params);
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
@ -192,8 +195,6 @@ const GrabHelper = new Lang.Class({
|
|||||||
if (firstGrab) {
|
if (firstGrab) {
|
||||||
if (!Main.pushModal(this._owner, this._modalParams))
|
if (!Main.pushModal(this._owner, this._modalParams))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
this._capturedEventId = global.stage.connect('captured-event', Lang.bind(this, this._onCapturedEvent));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this._modalCount++;
|
this._modalCount++;
|
||||||
@ -205,11 +206,6 @@ const GrabHelper = new Lang.Class({
|
|||||||
if (this._modalCount > 0)
|
if (this._modalCount > 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (this._capturedEventId > 0) {
|
|
||||||
global.stage.disconnect(this._capturedEventId);
|
|
||||||
this._capturedEventId = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
Main.popModal(this._owner);
|
Main.popModal(this._owner);
|
||||||
global.sync_pointer();
|
global.sync_pointer();
|
||||||
},
|
},
|
||||||
@ -308,6 +304,11 @@ const GrabHelper = new Lang.Class({
|
|||||||
this._releaseFocusGrab();
|
this._releaseFocusGrab();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!this.grabbed && this._capturedEventId > 0) {
|
||||||
|
global.stage.disconnect(this._capturedEventId);
|
||||||
|
this._capturedEventId = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (hadFocus) {
|
if (hadFocus) {
|
||||||
let poppedGrab = poppedGrabs[0];
|
let poppedGrab = poppedGrabs[0];
|
||||||
_navigateActor(poppedGrab.savedFocus);
|
_navigateActor(poppedGrab.savedFocus);
|
||||||
@ -316,6 +317,13 @@ const GrabHelper = new Lang.Class({
|
|||||||
|
|
||||||
_onCapturedEvent: function(actor, event) {
|
_onCapturedEvent: function(actor, event) {
|
||||||
let type = event.type();
|
let type = event.type();
|
||||||
|
|
||||||
|
if (type == Clutter.EventType.KEY_PRESS &&
|
||||||
|
event.get_key_symbol() == Clutter.KEY_Escape) {
|
||||||
|
this.ungrab({ isUser: true });
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
let press = type == Clutter.EventType.BUTTON_PRESS;
|
let press = type == Clutter.EventType.BUTTON_PRESS;
|
||||||
let release = type == Clutter.EventType.BUTTON_RELEASE;
|
let release = type == Clutter.EventType.BUTTON_RELEASE;
|
||||||
let button = press || release;
|
let button = press || release;
|
||||||
@ -328,12 +336,6 @@ const GrabHelper = new Lang.Class({
|
|||||||
if (!button && this._modalCount == 0)
|
if (!button && this._modalCount == 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (type == Clutter.EventType.KEY_PRESS &&
|
|
||||||
event.get_key_symbol() == Clutter.KEY_Escape) {
|
|
||||||
this.ungrab({ isUser: true });
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this._isWithinGrabbedActor(event.get_source()))
|
if (this._isWithinGrabbedActor(event.get_source()))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -23,6 +23,8 @@ const BaseIcon = new Lang.Class({
|
|||||||
this.actor._delegate = this;
|
this.actor._delegate = this;
|
||||||
this.actor.connect('style-changed',
|
this.actor.connect('style-changed',
|
||||||
Lang.bind(this, this._onStyleChanged));
|
Lang.bind(this, this._onStyleChanged));
|
||||||
|
this.actor.connect('destroy',
|
||||||
|
Lang.bind(this, this._onDestroy));
|
||||||
|
|
||||||
this._spacing = 0;
|
this._spacing = 0;
|
||||||
|
|
||||||
@ -52,6 +54,9 @@ const BaseIcon = new Lang.Class({
|
|||||||
this._setSizeManually = params.setSizeManually;
|
this._setSizeManually = params.setSizeManually;
|
||||||
|
|
||||||
this.icon = null;
|
this.icon = null;
|
||||||
|
|
||||||
|
let cache = St.TextureCache.get_default();
|
||||||
|
this._iconThemeChangedId = cache.connect('icon-theme-changed', Lang.bind(this, this._onIconThemeChanged));
|
||||||
},
|
},
|
||||||
|
|
||||||
_allocate: function(actor, box, flags) {
|
_allocate: function(actor, box, flags) {
|
||||||
@ -146,7 +151,22 @@ const BaseIcon = new Lang.Class({
|
|||||||
size = found ? len : ICON_SIZE;
|
size = found ? len : ICON_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.iconSize == size && this._iconBin.child)
|
||||||
|
return;
|
||||||
|
|
||||||
this._createIconTexture(size);
|
this._createIconTexture(size);
|
||||||
|
},
|
||||||
|
|
||||||
|
_onDestroy: function() {
|
||||||
|
if (this._iconThemeChangedId > 0) {
|
||||||
|
let cache = St.TextureCache.get_default();
|
||||||
|
cache.disconnect(this._iconThemeChangedId);
|
||||||
|
this._iconThemeChangedId = 0;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_onIconThemeChanged: function() {
|
||||||
|
this._createIconTexture(this.iconSize);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -2,18 +2,21 @@
|
|||||||
|
|
||||||
const Caribou = imports.gi.Caribou;
|
const Caribou = imports.gi.Caribou;
|
||||||
const Clutter = imports.gi.Clutter;
|
const Clutter = imports.gi.Clutter;
|
||||||
const DBus = imports.dbus;
|
|
||||||
const Gdk = imports.gi.Gdk;
|
const Gdk = imports.gi.Gdk;
|
||||||
const Gio = imports.gi.Gio;
|
const Gio = imports.gi.Gio;
|
||||||
const GLib = imports.gi.GLib;
|
const GLib = imports.gi.GLib;
|
||||||
const Lang = imports.lang;
|
const Lang = imports.lang;
|
||||||
const Shell = imports.gi.Shell;
|
const Shell = imports.gi.Shell;
|
||||||
|
const Signals = imports.signals;
|
||||||
const St = imports.gi.St;
|
const St = imports.gi.St;
|
||||||
|
|
||||||
const BoxPointer = imports.ui.boxpointer;
|
const BoxPointer = imports.ui.boxpointer;
|
||||||
|
const Layout = imports.ui.layout;
|
||||||
const Main = imports.ui.main;
|
const Main = imports.ui.main;
|
||||||
const MessageTray = imports.ui.messageTray;
|
const MessageTray = imports.ui.messageTray;
|
||||||
|
|
||||||
|
const KEYBOARD_REST_TIME = Layout.KEYBOARD_ANIMATION_TIME * 2 * 1000;
|
||||||
|
|
||||||
const KEYBOARD_SCHEMA = 'org.gnome.shell.keyboard';
|
const KEYBOARD_SCHEMA = 'org.gnome.shell.keyboard';
|
||||||
const KEYBOARD_TYPE = 'keyboard-type';
|
const KEYBOARD_TYPE = 'keyboard-type';
|
||||||
|
|
||||||
@ -56,14 +59,7 @@ const Key = new Lang.Class({
|
|||||||
if (this._key.name == 'Control_L' || this._key.name == 'Alt_L')
|
if (this._key.name == 'Control_L' || this._key.name == 'Alt_L')
|
||||||
this._key.latch = true;
|
this._key.latch = true;
|
||||||
|
|
||||||
this._key.connect('key-pressed', Lang.bind(this, function ()
|
|
||||||
{ this.actor.checked = true }));
|
|
||||||
this._key.connect('key-released', Lang.bind(this, function ()
|
|
||||||
{ this.actor.checked = false; }));
|
|
||||||
|
|
||||||
if (this._extended_keys.length > 0) {
|
if (this._extended_keys.length > 0) {
|
||||||
this._grabbed = false;
|
|
||||||
this._eventCaptureId = 0;
|
|
||||||
this._key.connect('notify::show-subkeys', Lang.bind(this, this._onShowSubkeysChanged));
|
this._key.connect('notify::show-subkeys', Lang.bind(this, this._onShowSubkeysChanged));
|
||||||
this._boxPointer = new BoxPointer.BoxPointer(St.Side.BOTTOM,
|
this._boxPointer = new BoxPointer.BoxPointer(St.Side.BOTTOM,
|
||||||
{ x_fill: true,
|
{ x_fill: true,
|
||||||
@ -115,52 +111,23 @@ const Key = new Lang.Class({
|
|||||||
this._boxPointer.bin.add_actor(this._extended_keyboard);
|
this._boxPointer.bin.add_actor(this._extended_keyboard);
|
||||||
},
|
},
|
||||||
|
|
||||||
_onEventCapture: function (actor, event) {
|
get subkeys() {
|
||||||
let source = event.get_source();
|
return this._boxPointer;
|
||||||
let type = event.type();
|
|
||||||
|
|
||||||
if ((type == Clutter.EventType.BUTTON_PRESS ||
|
|
||||||
type == Clutter.EventType.BUTTON_RELEASE) &&
|
|
||||||
this._extended_keyboard.contains(source)) {
|
|
||||||
source.extended_key.press();
|
|
||||||
source.extended_key.release();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (type == Clutter.EventType.BUTTON_PRESS) {
|
|
||||||
this._boxPointer.actor.hide();
|
|
||||||
this._ungrab();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
|
|
||||||
_ungrab: function () {
|
|
||||||
global.stage.disconnect(this._eventCaptureId);
|
|
||||||
this._eventCaptureId = 0;
|
|
||||||
this._grabbed = false;
|
|
||||||
Main.popModal(this.actor);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_onShowSubkeysChanged: function () {
|
_onShowSubkeysChanged: function () {
|
||||||
if (this._key.show_subkeys) {
|
if (this._key.show_subkeys) {
|
||||||
this.actor.fake_release();
|
|
||||||
this._boxPointer.actor.raise_top();
|
this._boxPointer.actor.raise_top();
|
||||||
this._boxPointer.setPosition(this.actor, 0.5);
|
this._boxPointer.setPosition(this.actor, 0.5);
|
||||||
this._boxPointer.show(BoxPointer.PopupAnimation.FULL);
|
this.emit('show-subkeys');
|
||||||
|
this.actor.fake_release();
|
||||||
this.actor.set_hover(false);
|
this.actor.set_hover(false);
|
||||||
if (!this._grabbed) {
|
|
||||||
Main.pushModal(this.actor);
|
|
||||||
this._eventCaptureId = global.stage.connect('captured-event', Lang.bind(this, this._onEventCapture));
|
|
||||||
this._grabbed = true;
|
|
||||||
}
|
|
||||||
this._key.release();
|
|
||||||
} else {
|
} else {
|
||||||
if (this._grabbed)
|
this.emit('hide-subkeys');
|
||||||
this._ungrab();
|
|
||||||
this._boxPointer.hide(BoxPointer.PopupAnimation.FULL);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
Signals.addSignalMethods(Key.prototype);
|
||||||
|
|
||||||
const Keyboard = new Lang.Class({
|
const Keyboard = new Lang.Class({
|
||||||
// HACK: we can't set Name, because it collides with Name dbus property
|
// HACK: we can't set Name, because it collides with Name dbus property
|
||||||
@ -182,6 +149,18 @@ const Keyboard = new Lang.Class({
|
|||||||
this._a11yApplicationsSettings = new Gio.Settings({ schema: A11Y_APPLICATIONS_SCHEMA });
|
this._a11yApplicationsSettings = new Gio.Settings({ schema: A11Y_APPLICATIONS_SCHEMA });
|
||||||
this._a11yApplicationsSettings.connect('changed', Lang.bind(this, this._settingsChanged));
|
this._a11yApplicationsSettings.connect('changed', Lang.bind(this, this._settingsChanged));
|
||||||
this._settingsChanged();
|
this._settingsChanged();
|
||||||
|
|
||||||
|
this._showIdleId = 0;
|
||||||
|
this._subkeysBoxPointer = null;
|
||||||
|
this._capturedEventId = 0;
|
||||||
|
this._capturedPress = false;
|
||||||
|
|
||||||
|
this._keyboardVisible = false;
|
||||||
|
Main.layoutManager.connect('keyboard-visible-changed', Lang.bind(this, function(o, visible) {
|
||||||
|
this._keyboardVisible = visible;
|
||||||
|
}));
|
||||||
|
this._keyboardRequested = false;
|
||||||
|
this._keyboardRestingId = 0;
|
||||||
},
|
},
|
||||||
|
|
||||||
init: function () {
|
init: function () {
|
||||||
@ -273,10 +252,14 @@ const Keyboard = new Lang.Class({
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
let time = global.get_current_time();
|
let time = global.get_current_time();
|
||||||
if (focus instanceof Clutter.Text)
|
if (!(focus instanceof Clutter.Text)) {
|
||||||
this.Show(time);
|
|
||||||
else
|
|
||||||
this.Hide(time);
|
this.Hide(time);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this._showIdleId)
|
||||||
|
this._showIdleId = GLib.idle_add(GLib.PRIORITY_DEFAULT_IDLE,
|
||||||
|
Lang.bind(this, function() { this.Show(time); }));
|
||||||
},
|
},
|
||||||
|
|
||||||
_addKeys: function () {
|
_addKeys: function () {
|
||||||
@ -331,6 +314,19 @@ const Keyboard = new Lang.Class({
|
|||||||
return trayButton;
|
return trayButton;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_onCapturedEvent: function(actor, event) {
|
||||||
|
let type = event.type();
|
||||||
|
let press = type == Clutter.EventType.BUTTON_PRESS;
|
||||||
|
let release = type == Clutter.EventType.BUTTON_RELEASE;
|
||||||
|
|
||||||
|
if (press)
|
||||||
|
this._capturedPress = true;
|
||||||
|
else if (release && this._capturedPress)
|
||||||
|
this._hideSubkeys();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
|
||||||
_addRows : function (keys, layout) {
|
_addRows : function (keys, layout) {
|
||||||
let keyboard_row = new St.BoxLayout();
|
let keyboard_row = new St.BoxLayout();
|
||||||
for (let i = 0; i < keys.length; ++i) {
|
for (let i = 0; i < keys.length; ++i) {
|
||||||
@ -353,6 +349,19 @@ const Keyboard = new Lang.Class({
|
|||||||
// Add new key for hiding message tray
|
// Add new key for hiding message tray
|
||||||
right_box.add(this._getTrayIcon());
|
right_box.add(this._getTrayIcon());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
button.connect('show-subkeys', Lang.bind(this, function() {
|
||||||
|
if (this._subkeysBoxPointer)
|
||||||
|
this._subkeysBoxPointer.hide(BoxPointer.PopupAnimation.FULL);
|
||||||
|
this._subkeysBoxPointer = button.subkeys;
|
||||||
|
this._subkeysBoxPointer.show(BoxPointer.PopupAnimation.FULL);
|
||||||
|
if (!this._capturedEventId)
|
||||||
|
this._capturedEventId = this.actor.connect('captured-event',
|
||||||
|
Lang.bind(this, this._onCapturedEvent));
|
||||||
|
}));
|
||||||
|
button.connect('hide-subkeys', Lang.bind(this, function() {
|
||||||
|
this._hideSubkeys();
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
keyboard_row.add(left_box, { expand: true, x_fill: false, x_align: St.Align.START });
|
keyboard_row.add(left_box, { expand: true, x_fill: false, x_align: St.Align.START });
|
||||||
keyboard_row.add(right_box, { expand: true, x_fill: false, x_align: St.Align.END });
|
keyboard_row.add(right_box, { expand: true, x_fill: false, x_align: St.Align.END });
|
||||||
@ -462,7 +471,37 @@ const Keyboard = new Lang.Class({
|
|||||||
actor._extended_keys || actor.extended_key;
|
actor._extended_keys || actor.extended_key;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_clearKeyboardRestTimer: function() {
|
||||||
|
if (!this._keyboardRestingId)
|
||||||
|
return;
|
||||||
|
GLib.source_remove(this._keyboardRestingId);
|
||||||
|
this._keyboardRestingId = 0;
|
||||||
|
},
|
||||||
|
|
||||||
show: function (monitor) {
|
show: function (monitor) {
|
||||||
|
this._keyboardRequested = true;
|
||||||
|
|
||||||
|
if (this._keyboardVisible) {
|
||||||
|
if (monitor != Main.layoutManager.keyboardIndex) {
|
||||||
|
Main.layoutManager.keyboardIndex = monitor;
|
||||||
|
this._redraw();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._clearKeyboardRestTimer();
|
||||||
|
this._keyboardRestingId = GLib.timeout_add(GLib.PRIORITY_DEFAULT,
|
||||||
|
KEYBOARD_REST_TIME,
|
||||||
|
Lang.bind(this, function() {
|
||||||
|
this._clearKeyboardRestTimer();
|
||||||
|
this._show(monitor);
|
||||||
|
}));
|
||||||
|
},
|
||||||
|
|
||||||
|
_show: function(monitor) {
|
||||||
|
if (!this._keyboardRequested)
|
||||||
|
return;
|
||||||
|
|
||||||
Main.layoutManager.keyboardIndex = monitor;
|
Main.layoutManager.keyboardIndex = monitor;
|
||||||
this._redraw();
|
this._redraw();
|
||||||
Main.layoutManager.showKeyboard();
|
Main.layoutManager.showKeyboard();
|
||||||
@ -470,10 +509,41 @@ const Keyboard = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
hide: function () {
|
hide: function () {
|
||||||
|
this._keyboardRequested = false;
|
||||||
|
|
||||||
|
if (!this._keyboardVisible)
|
||||||
|
return;
|
||||||
|
|
||||||
|
this._clearKeyboardRestTimer();
|
||||||
|
this._keyboardRestingId = GLib.timeout_add(GLib.PRIORITY_DEFAULT,
|
||||||
|
KEYBOARD_REST_TIME,
|
||||||
|
Lang.bind(this, function() {
|
||||||
|
this._clearKeyboardRestTimer();
|
||||||
|
this._hide();
|
||||||
|
}));
|
||||||
|
},
|
||||||
|
|
||||||
|
_hide: function() {
|
||||||
|
if (this._keyboardRequested)
|
||||||
|
return;
|
||||||
|
|
||||||
|
this._hideSubkeys();
|
||||||
Main.layoutManager.hideKeyboard();
|
Main.layoutManager.hideKeyboard();
|
||||||
this._createSource();
|
this._createSource();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_hideSubkeys: function() {
|
||||||
|
if (this._subkeysBoxPointer) {
|
||||||
|
this._subkeysBoxPointer.hide(BoxPointer.PopupAnimation.FULL);
|
||||||
|
this._subkeysBoxPointer = null;
|
||||||
|
}
|
||||||
|
if (this._capturedEventId) {
|
||||||
|
this.actor.disconnect(this._capturedEventId);
|
||||||
|
this._capturedEventId = 0;
|
||||||
|
}
|
||||||
|
this._capturedPress = false;
|
||||||
|
},
|
||||||
|
|
||||||
_moveTemporarily: function () {
|
_moveTemporarily: function () {
|
||||||
let currentWindow = global.screen.get_display().focus_window;
|
let currentWindow = global.screen.get_display().focus_window;
|
||||||
let rect = currentWindow.get_outer_rect();
|
let rect = currentWindow.get_outer_rect();
|
||||||
@ -502,6 +572,13 @@ const Keyboard = new Lang.Class({
|
|||||||
return one - two;
|
return one - two;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_clearShowIdle: function() {
|
||||||
|
if (!this._showIdleId)
|
||||||
|
return;
|
||||||
|
GLib.source_remove(this._showIdleId);
|
||||||
|
this._showIdleId = 0;
|
||||||
|
},
|
||||||
|
|
||||||
// D-Bus methods
|
// D-Bus methods
|
||||||
Show: function(timestamp) {
|
Show: function(timestamp) {
|
||||||
if (!this._enableKeyboard)
|
if (!this._enableKeyboard)
|
||||||
@ -510,6 +587,8 @@ const Keyboard = new Lang.Class({
|
|||||||
if (this._compareTimestamp(timestamp, this._timestamp) < 0)
|
if (this._compareTimestamp(timestamp, this._timestamp) < 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
this._clearShowIdle();
|
||||||
|
|
||||||
if (timestamp != Clutter.CURRENT_TIME)
|
if (timestamp != Clutter.CURRENT_TIME)
|
||||||
this._timestamp = timestamp;
|
this._timestamp = timestamp;
|
||||||
this.show(Main.layoutManager.focusIndex);
|
this.show(Main.layoutManager.focusIndex);
|
||||||
@ -522,6 +601,8 @@ const Keyboard = new Lang.Class({
|
|||||||
if (this._compareTimestamp(timestamp, this._timestamp) < 0)
|
if (this._compareTimestamp(timestamp, this._timestamp) < 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
this._clearShowIdle();
|
||||||
|
|
||||||
if (timestamp != Clutter.CURRENT_TIME)
|
if (timestamp != Clutter.CURRENT_TIME)
|
||||||
this._timestamp = timestamp;
|
this._timestamp = timestamp;
|
||||||
this.hide();
|
this.hide();
|
||||||
|
@ -16,7 +16,7 @@ const Tweener = imports.ui.tweener;
|
|||||||
|
|
||||||
const HOT_CORNER_ACTIVATION_TIMEOUT = 0.5;
|
const HOT_CORNER_ACTIVATION_TIMEOUT = 0.5;
|
||||||
const STARTUP_ANIMATION_TIME = 0.2;
|
const STARTUP_ANIMATION_TIME = 0.2;
|
||||||
const KEYBOARD_ANIMATION_TIME = 0.5;
|
const KEYBOARD_ANIMATION_TIME = 0.15;
|
||||||
const PLYMOUTH_TRANSITION_TIME = 1;
|
const PLYMOUTH_TRANSITION_TIME = 1;
|
||||||
|
|
||||||
const MonitorConstraint = new Lang.Class({
|
const MonitorConstraint = new Lang.Class({
|
||||||
@ -325,7 +325,7 @@ const LayoutManager = new Lang.Class({
|
|||||||
} else {
|
} else {
|
||||||
let focusWindow = global.display.focus_window;
|
let focusWindow = global.display.focus_window;
|
||||||
if (focusWindow)
|
if (focusWindow)
|
||||||
i = this._chrome.findIndexForWindow(focusWindow.get_compositor_private());
|
i = this._chrome.findIndexForWindow(focusWindow);
|
||||||
}
|
}
|
||||||
|
|
||||||
return i;
|
return i;
|
||||||
@ -437,7 +437,7 @@ const LayoutManager = new Lang.Class({
|
|||||||
Tweener.addTween(this.keyboardBox,
|
Tweener.addTween(this.keyboardBox,
|
||||||
{ anchor_y: 0,
|
{ anchor_y: 0,
|
||||||
time: immediate ? 0 : KEYBOARD_ANIMATION_TIME,
|
time: immediate ? 0 : KEYBOARD_ANIMATION_TIME,
|
||||||
transition: 'easeOutQuad',
|
transition: 'easeInQuad',
|
||||||
onComplete: this._hideKeyboardComplete,
|
onComplete: this._hideKeyboardComplete,
|
||||||
onCompleteScope: this
|
onCompleteScope: this
|
||||||
});
|
});
|
||||||
@ -513,7 +513,11 @@ const LayoutManager = new Lang.Class({
|
|||||||
|
|
||||||
findMonitorForActor: function(actor) {
|
findMonitorForActor: function(actor) {
|
||||||
return this.monitors[this._chrome.findIndexForActor(actor)];
|
return this.monitors[this._chrome.findIndexForActor(actor)];
|
||||||
}
|
},
|
||||||
|
|
||||||
|
findMonitorForWindow: function(window) {
|
||||||
|
return this.monitors[this._chrome.findIndexForWindow(window)];
|
||||||
|
},
|
||||||
});
|
});
|
||||||
Signals.addSignalMethods(LayoutManager.prototype);
|
Signals.addSignalMethods(LayoutManager.prototype);
|
||||||
|
|
||||||
@ -891,7 +895,8 @@ const Chrome = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
findIndexForWindow: function(window) {
|
findIndexForWindow: function(window) {
|
||||||
let i = this._findMonitorForRect(window.x, window.y, window.width, window.height);
|
let rect = window.get_input_rect();
|
||||||
|
let i = this._findMonitorForRect(rect.x, rect.y, rect.width, rect.height);
|
||||||
if (i >= 0)
|
if (i >= 0)
|
||||||
return i;
|
return i;
|
||||||
return this._primaryIndex; // Not on any monitor, pretend its on the primary
|
return this._primaryIndex; // Not on any monitor, pretend its on the primary
|
||||||
@ -909,7 +914,8 @@ const Chrome = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
findMonitorForWindow: function(window) {
|
findMonitorForWindow: function(window) {
|
||||||
let i = this._findMonitorForRect(window.x, window.y, window.width, window.height);
|
let rect = window.get_input_rect();
|
||||||
|
let i = this._findMonitorForRect(rect.x, rect.y, rect.width, rect.height);
|
||||||
if (i >= 0)
|
if (i >= 0)
|
||||||
return this._monitors[i];
|
return this._monitors[i];
|
||||||
else
|
else
|
||||||
@ -958,14 +964,15 @@ const Chrome = new Lang.Class({
|
|||||||
|
|
||||||
for (let i = windows.length - 1; i > -1; i--) {
|
for (let i = windows.length - 1; i > -1; i--) {
|
||||||
let window = windows[i];
|
let window = windows[i];
|
||||||
let layer = window.get_meta_window().get_layer();
|
let metaWindow = window.meta_window;
|
||||||
|
let layer = metaWindow.get_layer();
|
||||||
|
|
||||||
// Skip minimized windows
|
// Skip minimized windows
|
||||||
if (!window.showing_on_its_workspace())
|
if (!window.showing_on_its_workspace())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (layer == Meta.StackLayer.FULLSCREEN) {
|
if (layer == Meta.StackLayer.FULLSCREEN) {
|
||||||
let monitor = this.findMonitorForWindow(window);
|
let monitor = this.findMonitorForWindow(metaWindow);
|
||||||
if (monitor)
|
if (monitor)
|
||||||
monitor.inFullscreen = true;
|
monitor.inFullscreen = true;
|
||||||
}
|
}
|
||||||
@ -982,7 +989,7 @@ const Chrome = new Lang.Class({
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Or whether it is monitor sized
|
// Or whether it is monitor sized
|
||||||
let monitor = this.findMonitorForWindow(window);
|
let monitor = this.findMonitorForWindow(metaWindow);
|
||||||
if (monitor &&
|
if (monitor &&
|
||||||
window.x <= monitor.x &&
|
window.x <= monitor.x &&
|
||||||
window.x + window.width >= monitor.x + monitor.width &&
|
window.x + window.width >= monitor.x + monitor.width &&
|
||||||
@ -1085,7 +1092,7 @@ const Chrome = new Lang.Class({
|
|||||||
} else if (y1 <= primary.y && y2 >= primary.y + primary.height) {
|
} else if (y1 <= primary.y && y2 >= primary.y + primary.height) {
|
||||||
if (x1 <= 0)
|
if (x1 <= 0)
|
||||||
side = Meta.Side.LEFT;
|
side = Meta.Side.LEFT;
|
||||||
else if (x2 >= global.screen_width)
|
else if (x2 >= primary.x + primary.width)
|
||||||
side = Meta.Side.RIGHT;
|
side = Meta.Side.RIGHT;
|
||||||
else
|
else
|
||||||
continue;
|
continue;
|
||||||
|
@ -39,6 +39,7 @@ var commandHeader = 'const Clutter = imports.gi.Clutter; ' +
|
|||||||
* in the shell core code too. */
|
* in the shell core code too. */
|
||||||
'const stage = global.stage; ' +
|
'const stage = global.stage; ' +
|
||||||
/* Special lookingGlass functions */
|
/* Special lookingGlass functions */
|
||||||
|
'const inspect = Lang.bind(Main.lookingGlass, Main.lookingGlass.inspect); ' +
|
||||||
'const it = Main.lookingGlass.getIt(); ' +
|
'const it = Main.lookingGlass.getIt(); ' +
|
||||||
'const r = Lang.bind(Main.lookingGlass, Main.lookingGlass.getResult); ';
|
'const r = Lang.bind(Main.lookingGlass, Main.lookingGlass.getResult); ';
|
||||||
|
|
||||||
@ -871,8 +872,7 @@ const LookingGlass = new Lang.Class({
|
|||||||
inspectIcon.connect('button-press-event', Lang.bind(this, function () {
|
inspectIcon.connect('button-press-event', Lang.bind(this, function () {
|
||||||
let inspector = new Inspector(this);
|
let inspector = new Inspector(this);
|
||||||
inspector.connect('target', Lang.bind(this, function(i, target, stageX, stageY) {
|
inspector.connect('target', Lang.bind(this, function(i, target, stageX, stageY) {
|
||||||
this._pushResult('<inspect x:' + stageX + ' y:' + stageY + '>',
|
this._pushResult('inspect(' + Math.round(stageX) + ', ' + Math.round(stageY) + ')', target);
|
||||||
target);
|
|
||||||
}));
|
}));
|
||||||
inspector.connect('closed', Lang.bind(this, function() {
|
inspector.connect('closed', Lang.bind(this, function() {
|
||||||
this.actor.show();
|
this.actor.show();
|
||||||
@ -1057,6 +1057,10 @@ const LookingGlass = new Lang.Class({
|
|||||||
this._entry.text = '';
|
this._entry.text = '';
|
||||||
},
|
},
|
||||||
|
|
||||||
|
inspect: function(x, y) {
|
||||||
|
return global.stage.get_actor_at_pos(Clutter.PickMode.REACTIVE, x, y);
|
||||||
|
},
|
||||||
|
|
||||||
getIt: function () {
|
getIt: function () {
|
||||||
return this._it;
|
return this._it;
|
||||||
},
|
},
|
||||||
|
@ -49,7 +49,8 @@ const KeybindingMode = {
|
|||||||
LOGIN_SCREEN: 1 << 4,
|
LOGIN_SCREEN: 1 << 4,
|
||||||
MESSAGE_TRAY: 1 << 5,
|
MESSAGE_TRAY: 1 << 5,
|
||||||
SYSTEM_MODAL: 1 << 6,
|
SYSTEM_MODAL: 1 << 6,
|
||||||
LOOKING_GLASS: 1 << 7
|
LOOKING_GLASS: 1 << 7,
|
||||||
|
ALL: ~0,
|
||||||
};
|
};
|
||||||
|
|
||||||
let componentManager = null;
|
let componentManager = null;
|
||||||
@ -80,8 +81,6 @@ let _defaultCssStylesheet = null;
|
|||||||
let _cssStylesheet = null;
|
let _cssStylesheet = null;
|
||||||
let _overridesSettings = null;
|
let _overridesSettings = null;
|
||||||
|
|
||||||
let background = null;
|
|
||||||
|
|
||||||
function _sessionUpdated() {
|
function _sessionUpdated() {
|
||||||
wm.setCustomKeybindingHandler('panel-main-menu',
|
wm.setCustomKeybindingHandler('panel-main-menu',
|
||||||
KeybindingMode.NORMAL |
|
KeybindingMode.NORMAL |
|
||||||
@ -160,13 +159,13 @@ function start() {
|
|||||||
xdndHandler = new XdndHandler.XdndHandler();
|
xdndHandler = new XdndHandler.XdndHandler();
|
||||||
ctrlAltTabManager = new CtrlAltTab.CtrlAltTabManager();
|
ctrlAltTabManager = new CtrlAltTab.CtrlAltTabManager();
|
||||||
overview = new Overview.Overview();
|
overview = new Overview.Overview();
|
||||||
|
wm = new WindowManager.WindowManager();
|
||||||
magnifier = new Magnifier.Magnifier();
|
magnifier = new Magnifier.Magnifier();
|
||||||
if (UnlockDialog.isSupported())
|
if (UnlockDialog.isSupported())
|
||||||
screenShield = new ScreenShield.ScreenShield();
|
screenShield = new ScreenShield.ScreenShield();
|
||||||
else
|
else
|
||||||
screenShield = new ScreenShield.ScreenShieldFallback();
|
screenShield = new ScreenShield.ScreenShieldFallback();
|
||||||
panel = new Panel.Panel();
|
panel = new Panel.Panel();
|
||||||
wm = new WindowManager.WindowManager();
|
|
||||||
messageTray = new MessageTray.MessageTray();
|
messageTray = new MessageTray.MessageTray();
|
||||||
keyboard = new Keyboard.Keyboard();
|
keyboard = new Keyboard.Keyboard();
|
||||||
notificationDaemon = new NotificationDaemon.NotificationDaemon();
|
notificationDaemon = new NotificationDaemon.NotificationDaemon();
|
||||||
@ -546,19 +545,20 @@ function pushModal(actor, params) {
|
|||||||
if (index >= 0)
|
if (index >= 0)
|
||||||
popModal(actor);
|
popModal(actor);
|
||||||
});
|
});
|
||||||
let curFocus = global.stage.get_key_focus();
|
|
||||||
let curFocusDestroyId;
|
let prevFocus = global.stage.get_key_focus();
|
||||||
if (curFocus != null) {
|
let prevFocusDestroyId;
|
||||||
curFocusDestroyId = curFocus.connect('destroy', function() {
|
if (prevFocus != null) {
|
||||||
|
prevFocusDestroyId = prevFocus.connect('destroy', function() {
|
||||||
let index = _findModal(actor);
|
let index = _findModal(actor);
|
||||||
if (index >= 0)
|
if (index >= 0)
|
||||||
modalActorFocusStack[index].actor = null;
|
modalActorFocusStack[index].prevFocus = null;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
modalActorFocusStack.push({ actor: actor,
|
modalActorFocusStack.push({ actor: actor,
|
||||||
focus: curFocus,
|
|
||||||
destroyId: actorDestroyId,
|
destroyId: actorDestroyId,
|
||||||
focusDestroyId: curFocusDestroyId,
|
prevFocus: prevFocus,
|
||||||
|
prevFocusDestroyId: prevFocusDestroyId,
|
||||||
keybindingMode: keybindingMode });
|
keybindingMode: keybindingMode });
|
||||||
|
|
||||||
keybindingMode = params.keybindingMode;
|
keybindingMode = params.keybindingMode;
|
||||||
@ -599,18 +599,33 @@ function popModal(actor, timestamp) {
|
|||||||
record.actor.disconnect(record.destroyId);
|
record.actor.disconnect(record.destroyId);
|
||||||
|
|
||||||
if (focusIndex == modalActorFocusStack.length - 1) {
|
if (focusIndex == modalActorFocusStack.length - 1) {
|
||||||
if (record.focus)
|
if (record.prevFocus)
|
||||||
record.focus.disconnect(record.focusDestroyId);
|
record.prevFocus.disconnect(record.prevFocusDestroyId);
|
||||||
keybindingMode = record.keybindingMode;
|
keybindingMode = record.keybindingMode;
|
||||||
global.stage.set_key_focus(record.focus);
|
global.stage.set_key_focus(record.prevFocus);
|
||||||
} else {
|
} else {
|
||||||
|
// If we have:
|
||||||
|
// global.stage.set_focus(a);
|
||||||
|
// Main.pushModal(b);
|
||||||
|
// Main.pushModal(c);
|
||||||
|
// Main.pushModal(d);
|
||||||
|
//
|
||||||
|
// then we have the stack:
|
||||||
|
// [{ prevFocus: a, actor: b },
|
||||||
|
// { prevFocus: b, actor: c },
|
||||||
|
// { prevFocus: c, actor: d }]
|
||||||
|
//
|
||||||
|
// When actor c is destroyed/popped, if we only simply remove the
|
||||||
|
// record, then the focus stack will be [a, c], rather than the correct
|
||||||
|
// [a, b]. Shift the focus stack up before removing the record to ensure
|
||||||
|
// that we get the correct result.
|
||||||
let t = modalActorFocusStack[modalActorFocusStack.length - 1];
|
let t = modalActorFocusStack[modalActorFocusStack.length - 1];
|
||||||
if (t.focus)
|
if (t.prevFocus)
|
||||||
t.focus.disconnect(t.focusDestroyId);
|
t.prevFocus.disconnect(t.prevFocusDestroyId);
|
||||||
// Remove from the middle, shift the focus chain up
|
// Remove from the middle, shift the focus chain up
|
||||||
for (let i = modalActorFocusStack.length - 1; i > focusIndex; i--) {
|
for (let i = modalActorFocusStack.length - 1; i > focusIndex; i--) {
|
||||||
modalActorFocusStack[i].focus = modalActorFocusStack[i - 1].focus;
|
modalActorFocusStack[i].prevFocus = modalActorFocusStack[i - 1].prevFocus;
|
||||||
modalActorFocusStack[i].focusDestroyId = modalActorFocusStack[i - 1].focusDestroyId;
|
modalActorFocusStack[i].prevFocusDestroyId = modalActorFocusStack[i - 1].prevFocusDestroyId;
|
||||||
modalActorFocusStack[i].keybindingMode = modalActorFocusStack[i - 1].keybindingMode;
|
modalActorFocusStack[i].keybindingMode = modalActorFocusStack[i - 1].keybindingMode;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -611,6 +611,8 @@ const Notification = new Lang.Class({
|
|||||||
setImage: function(image) {
|
setImage: function(image) {
|
||||||
if (this._imageBin)
|
if (this._imageBin)
|
||||||
this.unsetImage();
|
this.unsetImage();
|
||||||
|
if (!image)
|
||||||
|
return;
|
||||||
this._imageBin = new St.Bin();
|
this._imageBin = new St.Bin();
|
||||||
this._imageBin.child = image;
|
this._imageBin.child = image;
|
||||||
this._imageBin.opacity = 230;
|
this._imageBin.opacity = 230;
|
||||||
@ -1412,7 +1414,7 @@ const MessageTray = new Lang.Class({
|
|||||||
actor.grab_key_focus();
|
actor.grab_key_focus();
|
||||||
}));
|
}));
|
||||||
global.focus_manager.add_group(this.actor);
|
global.focus_manager.add_group(this.actor);
|
||||||
this._summary = new St.BoxLayout({ name: 'summary-mode',
|
this._summary = new St.BoxLayout({ style_class: 'message-tray-summary',
|
||||||
reactive: true,
|
reactive: true,
|
||||||
track_hover: true,
|
track_hover: true,
|
||||||
x_align: Clutter.ActorAlign.END,
|
x_align: Clutter.ActorAlign.END,
|
||||||
|
@ -96,8 +96,7 @@ const ModalDialog = new Lang.Class({
|
|||||||
y_align: St.Align.START });
|
y_align: St.Align.START });
|
||||||
|
|
||||||
this.buttonLayout = new St.BoxLayout({ style_class: 'modal-dialog-button-box',
|
this.buttonLayout = new St.BoxLayout({ style_class: 'modal-dialog-button-box',
|
||||||
visible: false,
|
vertical: false });
|
||||||
vertical: false });
|
|
||||||
this.dialogLayout.add(this.buttonLayout,
|
this.dialogLayout.add(this.buttonLayout,
|
||||||
{ expand: true,
|
{ expand: true,
|
||||||
x_align: St.Align.MIDDLE,
|
x_align: St.Align.MIDDLE,
|
||||||
@ -120,7 +119,6 @@ const ModalDialog = new Lang.Class({
|
|||||||
|
|
||||||
setButtons: function(buttons) {
|
setButtons: function(buttons) {
|
||||||
this.clearButtons();
|
this.clearButtons();
|
||||||
this.buttonLayout.visible = (buttons.length > 0);
|
|
||||||
|
|
||||||
for (let i = 0; i < buttons.length; i++) {
|
for (let i = 0; i < buttons.length; i++) {
|
||||||
let buttonInfo = buttons[i];
|
let buttonInfo = buttons[i];
|
||||||
|
@ -127,42 +127,42 @@ const NotificationDaemon = new Lang.Class({
|
|||||||
this._trayManager.manage_stage(global.stage, Main.messageTray.actor);
|
this._trayManager.manage_stage(global.stage, Main.messageTray.actor);
|
||||||
},
|
},
|
||||||
|
|
||||||
_iconForNotificationData: function(icon, hints) {
|
_imageForNotificationData: function(hints) {
|
||||||
// If an icon is not specified, we use 'image-data' or 'image-path' hint for an icon
|
if (hints['image-data']) {
|
||||||
// and don't show a large image. There are currently many applications that use
|
|
||||||
// notify_notification_set_icon_from_pixbuf() from libnotify, which in turn sets
|
|
||||||
// the 'image-data' hint. These applications don't typically pass in 'app_icon'
|
|
||||||
// argument to Notify() and actually expect the pixbuf to be shown as an icon.
|
|
||||||
// So the logic here does the right thing for this case. If both an icon and either
|
|
||||||
// one of 'image-data' or 'image-path' are specified, we show both an icon and
|
|
||||||
// a large image.
|
|
||||||
if (icon) {
|
|
||||||
if (icon.substr(0, 7) == 'file://')
|
|
||||||
return new Gio.FileIcon({ file: Gio.File.new_for_uri(icon) });
|
|
||||||
else if (icon[0] == '/') {
|
|
||||||
return new Gio.FileIcon({ file: Gio.File.new_for_path(icon) });
|
|
||||||
} else
|
|
||||||
return new Gio.ThemedIcon({ name: icon });
|
|
||||||
} else if (hints['image-data']) {
|
|
||||||
let [width, height, rowStride, hasAlpha,
|
let [width, height, rowStride, hasAlpha,
|
||||||
bitsPerSample, nChannels, data] = hints['image-data'];
|
bitsPerSample, nChannels, data] = hints['image-data'];
|
||||||
return Shell.util_create_pixbuf_from_data(data, GdkPixbuf.Colorspace.RGB, hasAlpha,
|
return Shell.util_create_pixbuf_from_data(data, GdkPixbuf.Colorspace.RGB, hasAlpha,
|
||||||
bitsPerSample, width, height, rowStride);
|
bitsPerSample, width, height, rowStride);
|
||||||
} else if (hints['image-path']) {
|
} else if (hints['image-path']) {
|
||||||
return new Gio.FileIcon({ file: Gio.File.new_for_path(hints['image-path']) });
|
return new Gio.FileIcon({ file: Gio.File.new_for_path(hints['image-path']) });
|
||||||
} else {
|
|
||||||
let stockIcon;
|
|
||||||
switch (hints.urgency) {
|
|
||||||
case Urgency.LOW:
|
|
||||||
case Urgency.NORMAL:
|
|
||||||
stockIcon = 'gtk-dialog-info';
|
|
||||||
break;
|
|
||||||
case Urgency.CRITICAL:
|
|
||||||
stockIcon = 'gtk-dialog-error';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return new Gio.ThemedIcon({ name: stockIcon });
|
|
||||||
}
|
}
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
|
||||||
|
_fallbackIconForNotificationData: function(hints) {
|
||||||
|
let stockIcon;
|
||||||
|
switch (hints.urgency) {
|
||||||
|
case Urgency.LOW:
|
||||||
|
case Urgency.NORMAL:
|
||||||
|
stockIcon = 'gtk-dialog-info';
|
||||||
|
break;
|
||||||
|
case Urgency.CRITICAL:
|
||||||
|
stockIcon = 'gtk-dialog-error';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return new Gio.ThemedIcon({ name: stockIcon });
|
||||||
|
},
|
||||||
|
|
||||||
|
_iconForNotificationData: function(icon) {
|
||||||
|
if (icon) {
|
||||||
|
if (icon.substr(0, 7) == 'file://')
|
||||||
|
return new Gio.FileIcon({ file: Gio.File.new_for_uri(icon) });
|
||||||
|
else if (icon[0] == '/')
|
||||||
|
return new Gio.FileIcon({ file: Gio.File.new_for_path(icon) });
|
||||||
|
else
|
||||||
|
return new Gio.ThemedIcon({ name: icon });
|
||||||
|
}
|
||||||
|
return null;
|
||||||
},
|
},
|
||||||
|
|
||||||
_lookupSource: function(title, pid, trayIcon) {
|
_lookupSource: function(title, pid, trayIcon) {
|
||||||
@ -355,12 +355,8 @@ const NotificationDaemon = new Lang.Class({
|
|||||||
[ndata.id, ndata.icon, ndata.summary, ndata.body,
|
[ndata.id, ndata.icon, ndata.summary, ndata.body,
|
||||||
ndata.actions, ndata.hints, ndata.notification];
|
ndata.actions, ndata.hints, ndata.notification];
|
||||||
|
|
||||||
let gicon = this._iconForNotificationData(icon, hints);
|
|
||||||
|
|
||||||
if (notification == null) {
|
if (notification == null) {
|
||||||
notification = new MessageTray.Notification(source, summary, body,
|
notification = new MessageTray.Notification(source);
|
||||||
{ gicon: gicon,
|
|
||||||
bannerMarkup: true });
|
|
||||||
ndata.notification = notification;
|
ndata.notification = notification;
|
||||||
notification.connect('destroy', Lang.bind(this,
|
notification.connect('destroy', Lang.bind(this,
|
||||||
function(n, reason) {
|
function(n, reason) {
|
||||||
@ -383,29 +379,33 @@ const NotificationDaemon = new Lang.Class({
|
|||||||
function(n, actionId) {
|
function(n, actionId) {
|
||||||
this._emitActionInvoked(ndata.id, actionId);
|
this._emitActionInvoked(ndata.id, actionId);
|
||||||
}));
|
}));
|
||||||
} else {
|
|
||||||
notification.update(summary, body, { gicon: gicon,
|
|
||||||
bannerMarkup: true,
|
|
||||||
clear: true });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// We only display a large image if an icon is also specified.
|
let gicon = this._iconForNotificationData(icon, hints);
|
||||||
if (icon && (hints['image-data'] || hints['image-path'])) {
|
let gimage = this._imageForNotificationData(hints);
|
||||||
let image = null;
|
|
||||||
if (hints['image-data']) {
|
let image = null;
|
||||||
let [width, height, rowStride, hasAlpha,
|
|
||||||
bitsPerSample, nChannels, data] = hints['image-data'];
|
// If an icon is not specified, we use 'image-data' or 'image-path' hint for an icon
|
||||||
image = St.TextureCache.get_default().load_from_raw(data, hasAlpha,
|
// and don't show a large image. There are currently many applications that use
|
||||||
width, height, rowStride, notification.IMAGE_SIZE);
|
// notify_notification_set_icon_from_pixbuf() from libnotify, which in turn sets
|
||||||
} else if (hints['image-path']) {
|
// the 'image-data' hint. These applications don't typically pass in 'app_icon'
|
||||||
image = St.TextureCache.get_default().load_uri_async(GLib.filename_to_uri(hints['image-path'], null),
|
// argument to Notify() and actually expect the pixbuf to be shown as an icon.
|
||||||
notification.IMAGE_SIZE,
|
// So the logic here does the right thing for this case. If both an icon and either
|
||||||
notification.IMAGE_SIZE);
|
// one of 'image-data' or 'image-path' are specified, we show both an icon and
|
||||||
}
|
// a large image.
|
||||||
notification.setImage(image);
|
if (gicon && gimage)
|
||||||
} else {
|
image = new St.Icon({ gicon: gimage });
|
||||||
notification.unsetImage();
|
else if (!gicon && gimage)
|
||||||
}
|
gicon = gimage;
|
||||||
|
else if (!gicon)
|
||||||
|
gicon = this._fallbackIconForNotificationData(hints);
|
||||||
|
|
||||||
|
notification.setImage(image);
|
||||||
|
|
||||||
|
notification.update(summary, body, { gicon: gicon,
|
||||||
|
bannerMarkup: true,
|
||||||
|
clear: true });
|
||||||
|
|
||||||
if (actions.length) {
|
if (actions.length) {
|
||||||
notification.setUseActionIcons(hints['action-icons'] == true);
|
notification.setUseActionIcons(hints['action-icons'] == true);
|
||||||
@ -435,7 +435,7 @@ const NotificationDaemon = new Lang.Class({
|
|||||||
// of the 'transient' hint with hints['transient'] rather than hints.transient
|
// of the 'transient' hint with hints['transient'] rather than hints.transient
|
||||||
notification.setTransient(hints['transient'] == true);
|
notification.setTransient(hints['transient'] == true);
|
||||||
|
|
||||||
let sourceGIcon = source.useNotificationIcon ? this._iconForNotificationData(icon, hints) : null;
|
let sourceGIcon = source.useNotificationIcon ? gicon : null;
|
||||||
source.processNotification(notification, sourceGIcon);
|
source.processNotification(notification, sourceGIcon);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -23,9 +23,6 @@ const WorkspaceThumbnail = imports.ui.workspaceThumbnail;
|
|||||||
// Time for initial animation going into Overview mode
|
// Time for initial animation going into Overview mode
|
||||||
const ANIMATION_TIME = 0.25;
|
const ANIMATION_TIME = 0.25;
|
||||||
|
|
||||||
// XXX -- grab this automatically. Hard to do.
|
|
||||||
const DASH_MAX_WIDTH = 96;
|
|
||||||
|
|
||||||
const DND_WINDOW_SWITCH_TIMEOUT = 1250;
|
const DND_WINDOW_SWITCH_TIMEOUT = 1250;
|
||||||
|
|
||||||
const GLSL_DIM_EFFECT_DECLARATIONS = '';
|
const GLSL_DIM_EFFECT_DECLARATIONS = '';
|
||||||
@ -33,9 +30,9 @@ const GLSL_DIM_EFFECT_CODE = '\
|
|||||||
vec2 dist = cogl_tex_coord_in[0].xy - vec2(0.5, 0.5); \
|
vec2 dist = cogl_tex_coord_in[0].xy - vec2(0.5, 0.5); \
|
||||||
float elipse_radius = 0.5; \
|
float elipse_radius = 0.5; \
|
||||||
/* from https://bugzilla.gnome.org/show_bug.cgi?id=669798: \
|
/* from https://bugzilla.gnome.org/show_bug.cgi?id=669798: \
|
||||||
the alpha on the gradient goes from 165 at its darkest to 98 at its most transparent. */ \
|
the alpha on the gradient goes from 250 at its darkest to 180 at its most transparent. */ \
|
||||||
float y = 165.0 / 255.0; \
|
float y = 250.0 / 255.0; \
|
||||||
float x = 98.0 / 255.0; \
|
float x = 180.0 / 255.0; \
|
||||||
/* interpolate darkening value, based on distance from screen center */ \
|
/* interpolate darkening value, based on distance from screen center */ \
|
||||||
float val = min(length(dist), elipse_radius); \
|
float val = min(length(dist), elipse_radius); \
|
||||||
float a = mix(x, y, val / elipse_radius); \
|
float a = mix(x, y, val / elipse_radius); \
|
||||||
@ -136,23 +133,15 @@ const Overview = new Lang.Class({
|
|||||||
this._desktopFade = new St.Bin();
|
this._desktopFade = new St.Bin();
|
||||||
global.overlay_group.add_actor(this._desktopFade);
|
global.overlay_group.add_actor(this._desktopFade);
|
||||||
|
|
||||||
this._spacing = 0;
|
|
||||||
|
|
||||||
/* Translators: This is the main view to select
|
/* Translators: This is the main view to select
|
||||||
activities. See also note for "Activities" string. */
|
activities. See also note for "Activities" string. */
|
||||||
this._group = new St.Widget({ name: 'overview',
|
this._overview = new St.BoxLayout({ name: 'overview',
|
||||||
accessible_name: _("Overview"),
|
accessible_name: _("Overview"),
|
||||||
reactive: true });
|
reactive: true,
|
||||||
this._group._delegate = this;
|
vertical: true });
|
||||||
this._group.connect('style-changed',
|
this._overview._delegate = this;
|
||||||
Lang.bind(this, function() {
|
|
||||||
let node = this._group.get_theme_node();
|
this._group = new St.BoxLayout({ name: 'overview-group' });
|
||||||
let spacing = node.get_length('spacing');
|
|
||||||
if (spacing != this._spacing) {
|
|
||||||
this._spacing = spacing;
|
|
||||||
this._relayout();
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
|
|
||||||
this._capturedEventId = 0;
|
this._capturedEventId = 0;
|
||||||
this._buttonPressId = 0;
|
this._buttonPressId = 0;
|
||||||
@ -169,12 +158,11 @@ const Overview = new Lang.Class({
|
|||||||
// Dash elements, or mouseover handlers in the workspaces.
|
// Dash elements, or mouseover handlers in the workspaces.
|
||||||
this._coverPane = new Clutter.Rectangle({ opacity: 0,
|
this._coverPane = new Clutter.Rectangle({ opacity: 0,
|
||||||
reactive: true });
|
reactive: true });
|
||||||
this._group.add_actor(this._coverPane);
|
this._overview.add_actor(this._coverPane);
|
||||||
this._coverPane.connect('event', Lang.bind(this, function (actor, event) { return true; }));
|
this._coverPane.connect('event', Lang.bind(this, function (actor, event) { return true; }));
|
||||||
|
|
||||||
|
this._overview.hide();
|
||||||
this._group.hide();
|
global.overlay_group.add_actor(this._overview);
|
||||||
global.overlay_group.add_actor(this._group);
|
|
||||||
|
|
||||||
this._coverPane.hide();
|
this._coverPane.hide();
|
||||||
|
|
||||||
@ -186,6 +174,8 @@ const Overview = new Lang.Class({
|
|||||||
Main.xdndHandler.connect('drag-begin', Lang.bind(this, this._onDragBegin));
|
Main.xdndHandler.connect('drag-begin', Lang.bind(this, this._onDragBegin));
|
||||||
Main.xdndHandler.connect('drag-end', Lang.bind(this, this._onDragEnd));
|
Main.xdndHandler.connect('drag-end', Lang.bind(this, this._onDragEnd));
|
||||||
|
|
||||||
|
global.screen.connect('restacked', Lang.bind(this, this._onRestacked));
|
||||||
|
|
||||||
this._windowSwitchTimeoutId = 0;
|
this._windowSwitchTimeoutId = 0;
|
||||||
this._windowSwitchTimestamp = 0;
|
this._windowSwitchTimestamp = 0;
|
||||||
this._lastActiveWorkspaceIndex = -1;
|
this._lastActiveWorkspaceIndex = -1;
|
||||||
@ -213,6 +203,13 @@ const Overview = new Lang.Class({
|
|||||||
|
|
||||||
this._shellInfo = new ShellInfo();
|
this._shellInfo = new ShellInfo();
|
||||||
|
|
||||||
|
// Add a clone of the panel to the overview so spacing and such is
|
||||||
|
// automatic
|
||||||
|
this._panelGhost = new St.Bin({ child: new Clutter.Clone({ source: Main.panel.actor }),
|
||||||
|
reactive: false,
|
||||||
|
opacity: 0 });
|
||||||
|
this._overview.add_actor(this._panelGhost);
|
||||||
|
|
||||||
this._searchEntry = new St.Entry({ name: 'searchEntry',
|
this._searchEntry = new St.Entry({ name: 'searchEntry',
|
||||||
/* Translators: this is the text displayed
|
/* Translators: this is the text displayed
|
||||||
in the search entry when no search is
|
in the search entry when no search is
|
||||||
@ -221,16 +218,13 @@ const Overview = new Lang.Class({
|
|||||||
hint_text: _("Type to search..."),
|
hint_text: _("Type to search..."),
|
||||||
track_hover: true,
|
track_hover: true,
|
||||||
can_focus: true });
|
can_focus: true });
|
||||||
this._group.add_actor(this._searchEntry);
|
this._searchEntryBin = new St.Bin({ child: this._searchEntry,
|
||||||
|
x_align: St.Align.MIDDLE });
|
||||||
this._dash = new Dash.Dash();
|
this._overview.add_actor(this._searchEntryBin);
|
||||||
this._viewSelector = new ViewSelector.ViewSelector(this._searchEntry,
|
|
||||||
this._dash.showAppsButton);
|
|
||||||
this._group.add_actor(this._viewSelector.actor);
|
|
||||||
this._group.add_actor(this._dash.actor);
|
|
||||||
|
|
||||||
// TODO - recalculate everything when desktop size changes
|
// TODO - recalculate everything when desktop size changes
|
||||||
this._dash.actor.add_constraint(this._viewSelector.constrainHeight);
|
this._dash = new Dash.Dash();
|
||||||
|
this._group.add_actor(this._dash.actor);
|
||||||
this.dashIconSize = this._dash.iconSize;
|
this.dashIconSize = this._dash.iconSize;
|
||||||
this._dash.connect('icon-size-changed',
|
this._dash.connect('icon-size-changed',
|
||||||
Lang.bind(this, function() {
|
Lang.bind(this, function() {
|
||||||
@ -241,6 +235,23 @@ const Overview = new Lang.Class({
|
|||||||
// the left of the overview
|
// the left of the overview
|
||||||
Main.ctrlAltTabManager.addGroup(this._dash.actor, _("Dash"), 'user-bookmarks-symbolic');
|
Main.ctrlAltTabManager.addGroup(this._dash.actor, _("Dash"), 'user-bookmarks-symbolic');
|
||||||
|
|
||||||
|
this._viewSelector = new ViewSelector.ViewSelector(this._searchEntry,
|
||||||
|
this._dash.showAppsButton);
|
||||||
|
this._group.add(this._viewSelector.actor, { x_fill: true,
|
||||||
|
expand: true });
|
||||||
|
|
||||||
|
// Add our same-line elements after the search entry
|
||||||
|
this._overview.add(this._group, { y_fill: true,
|
||||||
|
expand: true });
|
||||||
|
|
||||||
|
// Then account for message tray
|
||||||
|
this._messageTrayGhost = new St.Bin({ style_class: 'message-tray-summary',
|
||||||
|
reactive: false,
|
||||||
|
opacity: 0,
|
||||||
|
x_fill: true,
|
||||||
|
y_fill: true });
|
||||||
|
this._overview.add_actor(this._messageTrayGhost);
|
||||||
|
|
||||||
Main.layoutManager.connect('monitors-changed', Lang.bind(this, this._relayout));
|
Main.layoutManager.connect('monitors-changed', Lang.bind(this, this._relayout));
|
||||||
this._relayout();
|
this._relayout();
|
||||||
},
|
},
|
||||||
@ -337,7 +348,7 @@ const Overview = new Lang.Class({
|
|||||||
if (this.isDummy)
|
if (this.isDummy)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
this._group.add_action(action);
|
this._overview.add_action(action);
|
||||||
},
|
},
|
||||||
|
|
||||||
_getDesktopClone: function() {
|
_getDesktopClone: function() {
|
||||||
@ -363,41 +374,27 @@ const Overview = new Lang.Class({
|
|||||||
this.hide();
|
this.hide();
|
||||||
|
|
||||||
let primary = Main.layoutManager.primaryMonitor;
|
let primary = Main.layoutManager.primaryMonitor;
|
||||||
let rtl = (Clutter.get_default_text_direction() == Clutter.TextDirection.RTL);
|
|
||||||
|
|
||||||
let contentY = Main.panel.actor.height;
|
let contentY = Main.panel.actor.height;
|
||||||
let contentHeight = primary.height - contentY - Main.messageTray.actor.height;
|
let contentHeight = primary.height - contentY - Main.messageTray.actor.height;
|
||||||
|
|
||||||
this._group.set_position(primary.x, primary.y);
|
this._overview.set_position(primary.x, primary.y);
|
||||||
this._group.set_size(primary.width, primary.height);
|
this._overview.set_size(primary.width, primary.height);
|
||||||
|
|
||||||
this._coverPane.set_position(0, contentY);
|
this._coverPane.set_position(0, contentY);
|
||||||
this._coverPane.set_size(primary.width, contentHeight);
|
this._coverPane.set_size(primary.width, contentHeight);
|
||||||
|
},
|
||||||
|
|
||||||
let searchWidth = this._searchEntry.get_width();
|
_onRestacked: function() {
|
||||||
let searchHeight = this._searchEntry.get_height();
|
let stack = global.get_window_actors();
|
||||||
let searchX = (primary.width - searchWidth) / 2;
|
let stackIndices = {};
|
||||||
let searchY = contentY + this._spacing;
|
|
||||||
|
|
||||||
let dashWidth = DASH_MAX_WIDTH;
|
for (let i = 0; i < stack.length; i++) {
|
||||||
let dashY = searchY + searchHeight + this._spacing;
|
// Use the stable sequence for an integer to use as a hash key
|
||||||
let dashX;
|
stackIndices[stack[i].get_meta_window().get_stable_sequence()] = i;
|
||||||
if (rtl) {
|
|
||||||
this._dash.actor.set_anchor_point_from_gravity(Clutter.Gravity.NORTH_EAST);
|
|
||||||
dashX = primary.width;
|
|
||||||
} else {
|
|
||||||
dashX = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let viewX = rtl ? 0 : dashWidth + this._spacing;
|
this.emit('windows-restacked', stackIndices);
|
||||||
let viewY = searchY + searchHeight + this._spacing;
|
|
||||||
let viewWidth = primary.width - dashWidth - this._spacing;
|
|
||||||
let viewHeight = contentHeight - this._spacing - viewY;
|
|
||||||
|
|
||||||
this._searchEntry.set_position(searchX, searchY);
|
|
||||||
this._dash.actor.set_position(dashX, dashY);
|
|
||||||
this._viewSelector.actor.set_position(viewX, viewY);
|
|
||||||
this._viewSelector.actor.set_size(viewWidth, viewHeight);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
//// Public methods ////
|
//// Public methods ////
|
||||||
@ -481,12 +478,12 @@ const Overview = new Lang.Class({
|
|||||||
// Disable unredirection while in the overview
|
// Disable unredirection while in the overview
|
||||||
Meta.disable_unredirect_for_screen(global.screen);
|
Meta.disable_unredirect_for_screen(global.screen);
|
||||||
global.window_group.hide();
|
global.window_group.hide();
|
||||||
this._group.show();
|
this._overview.show();
|
||||||
this._background.show();
|
this._background.show();
|
||||||
this._viewSelector.show();
|
this._viewSelector.show();
|
||||||
|
|
||||||
this._group.opacity = 0;
|
this._overview.opacity = 0;
|
||||||
Tweener.addTween(this._group,
|
Tweener.addTween(this._overview,
|
||||||
{ opacity: 255,
|
{ opacity: 255,
|
||||||
transition: 'easeOutQuad',
|
transition: 'easeOutQuad',
|
||||||
time: ANIMATION_TIME,
|
time: ANIMATION_TIME,
|
||||||
@ -578,7 +575,7 @@ const Overview = new Lang.Class({
|
|||||||
|
|
||||||
if (this._shown) {
|
if (this._shown) {
|
||||||
if (!this._modal) {
|
if (!this._modal) {
|
||||||
if (Main.pushModal(this._group,
|
if (Main.pushModal(this._overview,
|
||||||
{ keybindingMode: Main.KeybindingMode.OVERVIEW }))
|
{ keybindingMode: Main.KeybindingMode.OVERVIEW }))
|
||||||
this._modal = true;
|
this._modal = true;
|
||||||
else
|
else
|
||||||
@ -586,13 +583,13 @@ const Overview = new Lang.Class({
|
|||||||
}
|
}
|
||||||
} else if (this._shownTemporarily) {
|
} else if (this._shownTemporarily) {
|
||||||
if (this._modal) {
|
if (this._modal) {
|
||||||
Main.popModal(this._group);
|
Main.popModal(this._overview);
|
||||||
this._modal = false;
|
this._modal = false;
|
||||||
}
|
}
|
||||||
global.stage_input_mode = Shell.StageInputMode.FULLSCREEN;
|
global.stage_input_mode = Shell.StageInputMode.FULLSCREEN;
|
||||||
} else {
|
} else {
|
||||||
if (this._modal) {
|
if (this._modal) {
|
||||||
Main.popModal(this._group);
|
Main.popModal(this._overview);
|
||||||
this._modal = false;
|
this._modal = false;
|
||||||
}
|
}
|
||||||
else if (global.stage_input_mode == Shell.StageInputMode.FULLSCREEN)
|
else if (global.stage_input_mode == Shell.StageInputMode.FULLSCREEN)
|
||||||
@ -610,7 +607,7 @@ const Overview = new Lang.Class({
|
|||||||
this._viewSelector.zoomFromOverview();
|
this._viewSelector.zoomFromOverview();
|
||||||
|
|
||||||
// Make other elements fade out.
|
// Make other elements fade out.
|
||||||
Tweener.addTween(this._group,
|
Tweener.addTween(this._overview,
|
||||||
{ opacity: 0,
|
{ opacity: 0,
|
||||||
transition: 'easeOutQuad',
|
transition: 'easeOutQuad',
|
||||||
time: ANIMATION_TIME,
|
time: ANIMATION_TIME,
|
||||||
@ -652,7 +649,7 @@ const Overview = new Lang.Class({
|
|||||||
this._viewSelector.hide();
|
this._viewSelector.hide();
|
||||||
this._desktopFade.hide();
|
this._desktopFade.hide();
|
||||||
this._background.hide();
|
this._background.hide();
|
||||||
this._group.hide();
|
this._overview.hide();
|
||||||
|
|
||||||
this.visible = false;
|
this.visible = false;
|
||||||
this.animationInProgress = false;
|
this.animationInProgress = false;
|
||||||
|
@ -598,6 +598,11 @@ const AppMenuButton = new Lang.Class({
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
menu = new PopupMenu.RemoteMenu(this.actor, this._targetApp.menu, this._targetApp.action_group);
|
menu = new PopupMenu.RemoteMenu(this.actor, this._targetApp.menu, this._targetApp.action_group);
|
||||||
|
menu.connect('activate', Lang.bind(this, function() {
|
||||||
|
let win = this._targetApp.get_windows()[0];
|
||||||
|
win.check_alive(global.get_current_time());
|
||||||
|
}));
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if (this.menu.isDummyQuitMenu)
|
if (this.menu.isDummyQuitMenu)
|
||||||
return;
|
return;
|
||||||
@ -746,12 +751,9 @@ const ActivitiesButton = new Lang.Class({
|
|||||||
const PanelCorner = new Lang.Class({
|
const PanelCorner = new Lang.Class({
|
||||||
Name: 'PanelCorner',
|
Name: 'PanelCorner',
|
||||||
|
|
||||||
_init: function(box, side) {
|
_init: function(side) {
|
||||||
this._side = side;
|
this._side = side;
|
||||||
|
|
||||||
this._box = box;
|
|
||||||
this._box.connect('style-changed', Lang.bind(this, this._boxStyleChanged));
|
|
||||||
|
|
||||||
this.actor = new St.DrawingArea({ style_class: 'panel-corner' });
|
this.actor = new St.DrawingArea({ style_class: 'panel-corner' });
|
||||||
this.actor.connect('style-changed', Lang.bind(this, this._styleChanged));
|
this.actor.connect('style-changed', Lang.bind(this, this._styleChanged));
|
||||||
this.actor.connect('repaint', Lang.bind(this, this._repaint));
|
this.actor.connect('repaint', Lang.bind(this, this._repaint));
|
||||||
@ -807,12 +809,12 @@ const PanelCorner = new Lang.Class({
|
|||||||
return children[index];
|
return children[index];
|
||||||
},
|
},
|
||||||
|
|
||||||
_boxStyleChanged: function() {
|
setStyleParent: function(box) {
|
||||||
let side = this._side;
|
let side = this._side;
|
||||||
|
|
||||||
let rtlAwareContainer = this._box instanceof St.BoxLayout;
|
let rtlAwareContainer = box instanceof St.BoxLayout;
|
||||||
if (rtlAwareContainer &&
|
if (rtlAwareContainer &&
|
||||||
this._box.get_text_direction() == Clutter.TextDirection.RTL) {
|
box.get_text_direction() == Clutter.TextDirection.RTL) {
|
||||||
if (this._side == St.Side.LEFT)
|
if (this._side == St.Side.LEFT)
|
||||||
side = St.Side.RIGHT;
|
side = St.Side.RIGHT;
|
||||||
else if (this._side == St.Side.RIGHT)
|
else if (this._side == St.Side.RIGHT)
|
||||||
@ -821,9 +823,9 @@ const PanelCorner = new Lang.Class({
|
|||||||
|
|
||||||
let button;
|
let button;
|
||||||
if (side == St.Side.LEFT)
|
if (side == St.Side.LEFT)
|
||||||
button = this._findLeftmostButton(this._box);
|
button = this._findLeftmostButton(box);
|
||||||
else if (side == St.Side.RIGHT)
|
else if (side == St.Side.RIGHT)
|
||||||
button = this._findRightmostButton(this._box);
|
button = this._findRightmostButton(box);
|
||||||
|
|
||||||
if (button) {
|
if (button) {
|
||||||
if (this._button && this._buttonStyleChangedSignalId) {
|
if (this._button && this._buttonStyleChangedSignalId) {
|
||||||
@ -850,7 +852,7 @@ const PanelCorner = new Lang.Class({
|
|||||||
|
|
||||||
// The corner doesn't support theme transitions, so override
|
// The corner doesn't support theme transitions, so override
|
||||||
// the .panel-button default
|
// the .panel-button default
|
||||||
button.style = 'transition-duration: 0';
|
button.style = 'transition-duration: 0ms';
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -863,8 +865,8 @@ const PanelCorner = new Lang.Class({
|
|||||||
let backgroundColor = node.get_color('-panel-corner-background-color');
|
let backgroundColor = node.get_color('-panel-corner-background-color');
|
||||||
let borderColor = node.get_color('-panel-corner-border-color');
|
let borderColor = node.get_color('-panel-corner-border-color');
|
||||||
|
|
||||||
let noOverlap = borderColor.alpha == 0;
|
let overlap = borderColor.alpha != 0;
|
||||||
let offsetY = noOverlap ? borderWidth : 0;
|
let offsetY = overlap ? 0 : borderWidth;
|
||||||
|
|
||||||
let cr = this.actor.get_context();
|
let cr = this.actor.get_context();
|
||||||
cr.setOperator(Cairo.Operator.SOURCE);
|
cr.setOperator(Cairo.Operator.SOURCE);
|
||||||
@ -888,17 +890,18 @@ const PanelCorner = new Lang.Class({
|
|||||||
Clutter.cairo_set_source_color(cr, over);
|
Clutter.cairo_set_source_color(cr, over);
|
||||||
cr.fill();
|
cr.fill();
|
||||||
|
|
||||||
if (noOverlap)
|
if (overlap) {
|
||||||
return;
|
let offset = borderWidth;
|
||||||
|
Clutter.cairo_set_source_color(cr, backgroundColor);
|
||||||
|
|
||||||
let offset = borderWidth;
|
cr.save();
|
||||||
Clutter.cairo_set_source_color(cr, backgroundColor);
|
cr.translate(xOffsetDirection * offset, - offset);
|
||||||
|
cr.appendPath(savedPath);
|
||||||
|
cr.fill();
|
||||||
|
cr.restore();
|
||||||
|
}
|
||||||
|
|
||||||
cr.save();
|
cr.$dispose();
|
||||||
cr.translate(xOffsetDirection * offset, - offset);
|
|
||||||
cr.appendPath(savedPath);
|
|
||||||
cr.fill();
|
|
||||||
cr.restore();
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_styleChanged: function() {
|
_styleChanged: function() {
|
||||||
@ -958,17 +961,10 @@ const Panel = new Lang.Class({
|
|||||||
this._rightBox = new St.BoxLayout({ name: 'panelRight' });
|
this._rightBox = new St.BoxLayout({ name: 'panelRight' });
|
||||||
this.actor.add_actor(this._rightBox);
|
this.actor.add_actor(this._rightBox);
|
||||||
|
|
||||||
if (this.actor.get_text_direction() == Clutter.TextDirection.RTL)
|
this._leftCorner = new PanelCorner(St.Side.LEFT);
|
||||||
this._leftCorner = new PanelCorner(this._rightBox, St.Side.LEFT);
|
|
||||||
else
|
|
||||||
this._leftCorner = new PanelCorner(this._leftBox, St.Side.LEFT);
|
|
||||||
|
|
||||||
this.actor.add_actor(this._leftCorner.actor);
|
this.actor.add_actor(this._leftCorner.actor);
|
||||||
|
|
||||||
if (this.actor.get_text_direction() == Clutter.TextDirection.RTL)
|
this._rightCorner = new PanelCorner(St.Side.RIGHT);
|
||||||
this._rightCorner = new PanelCorner(this._leftBox, St.Side.RIGHT);
|
|
||||||
else
|
|
||||||
this._rightCorner = new PanelCorner(this._rightBox, St.Side.RIGHT);
|
|
||||||
this.actor.add_actor(this._rightCorner.actor);
|
this.actor.add_actor(this._rightCorner.actor);
|
||||||
|
|
||||||
this.actor.connect('get-preferred-width', Lang.bind(this, this._getPreferredWidth));
|
this.actor.connect('get-preferred-width', Lang.bind(this, this._getPreferredWidth));
|
||||||
@ -1141,17 +1137,13 @@ const Panel = new Lang.Class({
|
|||||||
this._sessionStyle = Main.sessionMode.panelStyle;
|
this._sessionStyle = Main.sessionMode.panelStyle;
|
||||||
if (this._sessionStyle)
|
if (this._sessionStyle)
|
||||||
this._addStyleClassName(this._sessionStyle);
|
this._addStyleClassName(this._sessionStyle);
|
||||||
},
|
|
||||||
|
|
||||||
_initBox: function(elements, box) {
|
if (this.actor.get_text_direction() == Clutter.TextDirection.RTL) {
|
||||||
for (let i = 0; i < elements.length; i++) {
|
this._leftCorner.setStyleParent(this._rightBox);
|
||||||
let role = elements[i];
|
this._rightCorner.setStyleParent(this._leftBox);
|
||||||
let constructor = PANEL_ITEM_IMPLEMENTATIONS[role];
|
} else {
|
||||||
if (!constructor) {
|
this._leftCorner.setStyleParent(this._leftBox);
|
||||||
// panel icon is not supported (can happen for
|
this._rightCorner.setStyleParent(this._rightBox);
|
||||||
// bluetooth or network)
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -244,18 +244,21 @@ const SystemStatusButton = new Lang.Class({
|
|||||||
this.setIcon(iconName);
|
this.setIcon(iconName);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
get icons() {
|
||||||
|
return this._box.get_children();
|
||||||
|
},
|
||||||
|
|
||||||
addIcon: function(gicon) {
|
addIcon: function(gicon) {
|
||||||
let icon = new St.Icon({ gicon: gicon,
|
let icon = new St.Icon({ gicon: gicon,
|
||||||
style_class: 'system-status-icon' });
|
style_class: 'system-status-icon' });
|
||||||
this._box.add_actor(icon);
|
this._box.add_actor(icon);
|
||||||
|
|
||||||
|
this.emit('icons-changed');
|
||||||
|
|
||||||
return icon;
|
return icon;
|
||||||
},
|
},
|
||||||
|
|
||||||
setIcon: function(iconName) {
|
setIcon: function(iconName) {
|
||||||
// Need to first add a NULL GIcon and then set icon_name, to ensure
|
|
||||||
// compatibility with -symbolic fallbacks
|
|
||||||
|
|
||||||
if (!this.mainIcon)
|
if (!this.mainIcon)
|
||||||
this.mainIcon = this.addIcon(null);
|
this.mainIcon = this.addIcon(null);
|
||||||
this.mainIcon.icon_name = iconName;
|
this.mainIcon.icon_name = iconName;
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
const Cairo = imports.cairo;
|
|
||||||
const Clutter = imports.gi.Clutter;
|
const Clutter = imports.gi.Clutter;
|
||||||
const GLib = imports.gi.GLib;
|
const GLib = imports.gi.GLib;
|
||||||
const Gtk = imports.gi.Gtk;
|
const Gtk = imports.gi.Gtk;
|
||||||
@ -15,6 +14,7 @@ const BoxPointer = imports.ui.boxpointer;
|
|||||||
const GrabHelper = imports.ui.grabHelper;
|
const GrabHelper = imports.ui.grabHelper;
|
||||||
const Main = imports.ui.main;
|
const Main = imports.ui.main;
|
||||||
const Params = imports.misc.params;
|
const Params = imports.misc.params;
|
||||||
|
const Separator = imports.ui.separator;
|
||||||
const Tweener = imports.ui.tweener;
|
const Tweener = imports.ui.tweener;
|
||||||
|
|
||||||
const SLIDER_SCROLL_STEP = 0.05; /* Slider scrolling step in % */
|
const SLIDER_SCROLL_STEP = 0.05; /* Slider scrolling step in % */
|
||||||
@ -207,6 +207,7 @@ const PopupBaseMenuItem = new Lang.Class({
|
|||||||
color.alpha / 255);
|
color.alpha / 255);
|
||||||
cr.arc(width / 2, height / 2, width / 3, 0, 2 * Math.PI);
|
cr.arc(width / 2, height / 2, width / 3, 0, 2 * Math.PI);
|
||||||
cr.fill();
|
cr.fill();
|
||||||
|
cr.$dispose();
|
||||||
},
|
},
|
||||||
|
|
||||||
// This returns column widths in logical order (i.e. from the dot
|
// This returns column widths in logical order (i.e. from the dot
|
||||||
@ -405,29 +406,8 @@ const PopupSeparatorMenuItem = new Lang.Class({
|
|||||||
this.parent({ reactive: false,
|
this.parent({ reactive: false,
|
||||||
can_focus: false});
|
can_focus: false});
|
||||||
|
|
||||||
this._drawingArea = new St.DrawingArea({ style_class: 'popup-separator-menu-item' });
|
this._separator = new Separator.HorizontalSeparator({ style_class: 'popup-separator-menu-item' });
|
||||||
this.addActor(this._drawingArea, { span: -1, expand: true });
|
this.addActor(this._separator.actor, { span: -1, expand: true });
|
||||||
this._drawingArea.connect('repaint', Lang.bind(this, this._onRepaint));
|
|
||||||
},
|
|
||||||
|
|
||||||
_onRepaint: function(area) {
|
|
||||||
let cr = area.get_context();
|
|
||||||
let themeNode = area.get_theme_node();
|
|
||||||
let [width, height] = area.get_surface_size();
|
|
||||||
let margin = themeNode.get_length('-margin-horizontal');
|
|
||||||
let gradientHeight = themeNode.get_length('-gradient-height');
|
|
||||||
let startColor = themeNode.get_color('-gradient-start');
|
|
||||||
let endColor = themeNode.get_color('-gradient-end');
|
|
||||||
|
|
||||||
let gradientWidth = (width - margin * 2);
|
|
||||||
let gradientOffset = (height - gradientHeight) / 2;
|
|
||||||
let pattern = new Cairo.LinearGradient(margin, gradientOffset, width - margin, gradientOffset + gradientHeight);
|
|
||||||
pattern.addColorStopRGBA(0, startColor.red / 255, startColor.green / 255, startColor.blue / 255, startColor.alpha / 255);
|
|
||||||
pattern.addColorStopRGBA(0.5, endColor.red / 255, endColor.green / 255, endColor.blue / 255, endColor.alpha / 255);
|
|
||||||
pattern.addColorStopRGBA(1, startColor.red / 255, startColor.green / 255, startColor.blue / 255, startColor.alpha / 255);
|
|
||||||
cr.setSource(pattern);
|
|
||||||
cr.rectangle(margin, gradientOffset, gradientWidth, gradientHeight);
|
|
||||||
cr.fill();
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -625,6 +605,7 @@ const PopupSliderMenuItem = new Lang.Class({
|
|||||||
color.alpha / 255);
|
color.alpha / 255);
|
||||||
cr.arc(handleX, handleY, handleRadius, 0, 2 * Math.PI);
|
cr.arc(handleX, handleY, handleRadius, 0, 2 * Math.PI);
|
||||||
cr.fill();
|
cr.fill();
|
||||||
|
cr.$dispose();
|
||||||
},
|
},
|
||||||
|
|
||||||
_startDragging: function(actor, event) {
|
_startDragging: function(actor, event) {
|
||||||
@ -657,20 +638,34 @@ const PopupSliderMenuItem = new Lang.Class({
|
|||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
|
|
||||||
_onScrollEvent: function (actor, event) {
|
scroll: function(event) {
|
||||||
let direction = event.get_scroll_direction();
|
let direction = event.get_scroll_direction();
|
||||||
|
let delta;
|
||||||
|
|
||||||
|
if (event.is_pointer_emulated())
|
||||||
|
return;
|
||||||
|
|
||||||
if (direction == Clutter.ScrollDirection.DOWN) {
|
if (direction == Clutter.ScrollDirection.DOWN) {
|
||||||
this._value = Math.max(0, this._value - SLIDER_SCROLL_STEP);
|
delta = -SLIDER_SCROLL_STEP;
|
||||||
}
|
} else if (direction == Clutter.ScrollDirection.UP) {
|
||||||
else if (direction == Clutter.ScrollDirection.UP) {
|
delta = +SLIDER_SCROLL_STEP;
|
||||||
this._value = Math.min(1, this._value + SLIDER_SCROLL_STEP);
|
} else if (direction == Clutter.ScrollDirection.SMOOTH) {
|
||||||
|
let [dx, dy] = event.get_scroll_delta();
|
||||||
|
// Even though the slider is horizontal, use dy to match
|
||||||
|
// the UP/DOWN above.
|
||||||
|
delta = -dy / 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this._value = Math.min(Math.max(0, this._value + delta), 1);
|
||||||
|
|
||||||
this._slider.queue_repaint();
|
this._slider.queue_repaint();
|
||||||
this.emit('value-changed', this._value);
|
this.emit('value-changed', this._value);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_onScrollEvent: function(actor, event) {
|
||||||
|
this.scroll(event);
|
||||||
|
},
|
||||||
|
|
||||||
_motionEvent: function(actor, event) {
|
_motionEvent: function(actor, event) {
|
||||||
let absX, absY;
|
let absX, absY;
|
||||||
[absX, absY] = event.get_coords();
|
[absX, absY] = event.get_coords();
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
|
const GdkPixbuf = imports.gi.GdkPixbuf;
|
||||||
const Gio = imports.gi.Gio;
|
const Gio = imports.gi.Gio;
|
||||||
const GLib = imports.gi.GLib;
|
const GLib = imports.gi.GLib;
|
||||||
const Lang = imports.lang;
|
const Lang = imports.lang;
|
||||||
const St = imports.gi.St;
|
const St = imports.gi.St;
|
||||||
|
const Shell = imports.gi.Shell;
|
||||||
|
|
||||||
const FileUtils = imports.misc.fileUtils;
|
const FileUtils = imports.misc.fileUtils;
|
||||||
const Search = imports.ui.search;
|
const Search = imports.ui.search;
|
||||||
@ -50,6 +52,7 @@ const SearchProvider2Iface = <interface name="org.gnome.Shell.SearchProvider2">
|
|||||||
</method>
|
</method>
|
||||||
<method name="LaunchSearch">
|
<method name="LaunchSearch">
|
||||||
<arg type="as" direction="in" />
|
<arg type="as" direction="in" />
|
||||||
|
<arg type="u" direction="in" />
|
||||||
</method>
|
</method>
|
||||||
</interface>;
|
</interface>;
|
||||||
|
|
||||||
@ -166,7 +169,6 @@ function remoteProvidersLoaded(loadState) {
|
|||||||
|
|
||||||
const RemoteSearchProvider = new Lang.Class({
|
const RemoteSearchProvider = new Lang.Class({
|
||||||
Name: 'RemoteSearchProvider',
|
Name: 'RemoteSearchProvider',
|
||||||
Extends: Search.SearchProvider,
|
|
||||||
|
|
||||||
_init: function(appInfo, dbusName, dbusPath, proxyType) {
|
_init: function(appInfo, dbusName, dbusPath, proxyType) {
|
||||||
if (!proxyType)
|
if (!proxyType)
|
||||||
@ -175,7 +177,10 @@ const RemoteSearchProvider = new Lang.Class({
|
|||||||
this.proxy = new proxyType(Gio.DBus.session,
|
this.proxy = new proxyType(Gio.DBus.session,
|
||||||
dbusName, dbusPath, Lang.bind(this, this._onProxyConstructed));
|
dbusName, dbusPath, Lang.bind(this, this._onProxyConstructed));
|
||||||
|
|
||||||
this.parent(appInfo.get_name().toUpperCase(), appInfo, true);
|
this.appInfo = appInfo;
|
||||||
|
this.id = appInfo.get_id();
|
||||||
|
this.isRemoteProvider = true;
|
||||||
|
|
||||||
this._cancellable = new Gio.Cancellable();
|
this._cancellable = new Gio.Cancellable();
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -184,19 +189,17 @@ const RemoteSearchProvider = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
createIcon: function(size, meta) {
|
createIcon: function(size, meta) {
|
||||||
|
let gicon;
|
||||||
if (meta['gicon']) {
|
if (meta['gicon']) {
|
||||||
return new St.Icon({ gicon: Gio.icon_new_for_string(meta['gicon']),
|
gicon = Gio.icon_new_for_string(meta['gicon']);
|
||||||
icon_size: size });
|
|
||||||
} else if (meta['icon-data']) {
|
} else if (meta['icon-data']) {
|
||||||
let [width, height, rowStride, hasAlpha,
|
let [width, height, rowStride, hasAlpha,
|
||||||
bitsPerSample, nChannels, data] = meta['icon-data'];
|
bitsPerSample, nChannels, data] = meta['icon-data'];
|
||||||
let textureCache = St.TextureCache.get_default();
|
gicon = Shell.util_create_pixbuf_from_data(data, GdkPixbuf.Colorspace.RGB, hasAlpha,
|
||||||
return textureCache.load_from_raw(data, hasAlpha,
|
bitsPerSample, width, height, rowStride);
|
||||||
width, height, rowStride, size);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ugh, but we want to fall back to something ...
|
return new St.Icon({ gicon: gicon,
|
||||||
return new St.Icon({ icon_name: 'text-x-generic',
|
|
||||||
icon_size: size });
|
icon_size: size });
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -290,6 +293,6 @@ const RemoteSearchProvider2 = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
launchSearch: function(terms) {
|
launchSearch: function(terms) {
|
||||||
this.proxy.LaunchSearchRemote(terms);
|
this.proxy.LaunchSearchRemote(terms, global.get_current_time());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -25,6 +25,7 @@ const Util = imports.misc.util;
|
|||||||
|
|
||||||
const SCREENSAVER_SCHEMA = 'org.gnome.desktop.screensaver';
|
const SCREENSAVER_SCHEMA = 'org.gnome.desktop.screensaver';
|
||||||
const LOCK_ENABLED_KEY = 'lock-enabled';
|
const LOCK_ENABLED_KEY = 'lock-enabled';
|
||||||
|
const LOCK_DELAY_KEY = 'lock-delay';
|
||||||
|
|
||||||
const CURTAIN_SLIDE_TIME = 0.3;
|
const CURTAIN_SLIDE_TIME = 0.3;
|
||||||
// fraction of screen height the arrow must reach before completing
|
// fraction of screen height the arrow must reach before completing
|
||||||
@ -636,7 +637,11 @@ const ScreenShield = new Lang.Class({
|
|||||||
let lightboxWasShown = this._lightbox.shown;
|
let lightboxWasShown = this._lightbox.shown;
|
||||||
this._lightbox.hide();
|
this._lightbox.hide();
|
||||||
|
|
||||||
let shouldLock = lightboxWasShown && this._settings.get_boolean(LOCK_ENABLED_KEY);
|
// GLib.get_monotonic_time() returns microseconds, convert to seconds
|
||||||
|
let elapsedTime = (GLib.get_monotonic_time() - this._activationTime) / 1000000;
|
||||||
|
let shouldLock = lightboxWasShown &&
|
||||||
|
this._settings.get_boolean(LOCK_ENABLED_KEY) &&
|
||||||
|
(elapsedTime >= this._settings.get_uint(LOCK_DELAY_KEY));
|
||||||
if (shouldLock || this._isLocked) {
|
if (shouldLock || this._isLocked) {
|
||||||
this.lock(false);
|
this.lock(false);
|
||||||
} else if (this._isActive) {
|
} else if (this._isActive) {
|
||||||
@ -755,6 +760,10 @@ const ScreenShield = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
_resetLockScreen: function(animateLockScreen, animateLockDialog) {
|
_resetLockScreen: function(animateLockScreen, animateLockDialog) {
|
||||||
|
if (this._lockScreenState == MessageTray.State.SHOWING ||
|
||||||
|
this._lockScreenState == MessageTray.State.SHOWN)
|
||||||
|
return;
|
||||||
|
|
||||||
this._ensureLockScreen();
|
this._ensureLockScreen();
|
||||||
this._lockDialogGroup.scale_x = 1;
|
this._lockDialogGroup.scale_x = 1;
|
||||||
this._lockDialogGroup.scale_y = 1;
|
this._lockDialogGroup.scale_y = 1;
|
||||||
|
281
js/ui/screenshot.js
Normal file
281
js/ui/screenshot.js
Normal file
@ -0,0 +1,281 @@
|
|||||||
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
|
const Clutter = imports.gi.Clutter;
|
||||||
|
const Gdk = imports.gi.Gdk;
|
||||||
|
const Gio = imports.gi.Gio;
|
||||||
|
const GLib = imports.gi.GLib;
|
||||||
|
const Gtk = imports.gi.Gtk;
|
||||||
|
const Lang = imports.lang;
|
||||||
|
const Shell = imports.gi.Shell;
|
||||||
|
const Signals = imports.signals;
|
||||||
|
const St = imports.gi.St;
|
||||||
|
|
||||||
|
const Lightbox = imports.ui.lightbox;
|
||||||
|
const Main = imports.ui.main;
|
||||||
|
const Tweener = imports.ui.tweener;
|
||||||
|
|
||||||
|
const ScreenshotIface = <interface name="org.gnome.Shell.Screenshot">
|
||||||
|
<method name="ScreenshotArea">
|
||||||
|
<arg type="i" direction="in" name="x"/>
|
||||||
|
<arg type="i" direction="in" name="y"/>
|
||||||
|
<arg type="i" direction="in" name="width"/>
|
||||||
|
<arg type="i" direction="in" name="height"/>
|
||||||
|
<arg type="b" direction="in" name="flash"/>
|
||||||
|
<arg type="s" direction="in" name="filename"/>
|
||||||
|
<arg type="b" direction="out" name="success"/>
|
||||||
|
<arg type="s" direction="out" name="filename_used"/>
|
||||||
|
</method>
|
||||||
|
<method name="ScreenshotWindow">
|
||||||
|
<arg type="b" direction="in" name="include_frame"/>
|
||||||
|
<arg type="b" direction="in" name="include_cursor"/>
|
||||||
|
<arg type="b" direction="in" name="flash"/>
|
||||||
|
<arg type="s" direction="in" name="filename"/>
|
||||||
|
<arg type="b" direction="out" name="success"/>
|
||||||
|
<arg type="s" direction="out" name="filename_used"/>
|
||||||
|
</method>
|
||||||
|
<method name="Screenshot">
|
||||||
|
<arg type="b" direction="in" name="include_cursor"/>
|
||||||
|
<arg type="b" direction="in" name="flash"/>
|
||||||
|
<arg type="s" direction="in" name="filename"/>
|
||||||
|
<arg type="b" direction="out" name="success"/>
|
||||||
|
<arg type="s" direction="out" name="filename_used"/>
|
||||||
|
</method>
|
||||||
|
<method name="SelectArea">
|
||||||
|
<arg type="i" direction="out" name="x"/>
|
||||||
|
<arg type="i" direction="out" name="y"/>
|
||||||
|
<arg type="i" direction="out" name="width"/>
|
||||||
|
<arg type="i" direction="out" name="height"/>
|
||||||
|
</method>
|
||||||
|
<method name="FlashArea">
|
||||||
|
<arg type="i" direction="in" name="x"/>
|
||||||
|
<arg type="i" direction="in" name="y"/>
|
||||||
|
<arg type="i" direction="in" name="width"/>
|
||||||
|
<arg type="i" direction="in" name="height"/>
|
||||||
|
</method>
|
||||||
|
</interface>;
|
||||||
|
|
||||||
|
const ScreenshotService = new Lang.Class({
|
||||||
|
Name: 'ScreenshotService',
|
||||||
|
|
||||||
|
_init: function() {
|
||||||
|
this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(ScreenshotIface, this);
|
||||||
|
this._dbusImpl.export(Gio.DBus.session, '/org/gnome/Shell/Screenshot');
|
||||||
|
|
||||||
|
Gio.DBus.session.own_name('org.gnome.Shell.Screenshot', Gio.BusNameOwnerFlags.REPLACE, null, null);
|
||||||
|
},
|
||||||
|
|
||||||
|
_onScreenshotComplete: function(obj, result, area, filenameUsed, flash, invocation) {
|
||||||
|
if (flash && result) {
|
||||||
|
let flashspot = new Flashspot(area);
|
||||||
|
flashspot.fire();
|
||||||
|
}
|
||||||
|
|
||||||
|
let retval = GLib.Variant.new('(bs)', [result, filenameUsed]);
|
||||||
|
invocation.return_value(retval);
|
||||||
|
},
|
||||||
|
|
||||||
|
ScreenshotAreaAsync : function (params, invocation) {
|
||||||
|
let [x, y, width, height, flash, filename, callback] = params;
|
||||||
|
let screenshot = new Shell.Screenshot();
|
||||||
|
screenshot.screenshot_area (x, y, width, height, filename,
|
||||||
|
Lang.bind(this, this._onScreenshotComplete,
|
||||||
|
flash, invocation));
|
||||||
|
},
|
||||||
|
|
||||||
|
ScreenshotWindowAsync : function (params, invocation) {
|
||||||
|
let [include_frame, include_cursor, flash, filename] = params;
|
||||||
|
let screenshot = new Shell.Screenshot();
|
||||||
|
screenshot.screenshot_window (include_frame, include_cursor, filename,
|
||||||
|
Lang.bind(this, this._onScreenshotComplete,
|
||||||
|
flash, invocation));
|
||||||
|
},
|
||||||
|
|
||||||
|
ScreenshotAsync : function (params, invocation) {
|
||||||
|
let [include_cursor, flash, filename] = params;
|
||||||
|
let screenshot = new Shell.Screenshot();
|
||||||
|
screenshot.screenshot(include_cursor, filename,
|
||||||
|
Lang.bind(this, this._onScreenshotComplete,
|
||||||
|
flash, invocation));
|
||||||
|
},
|
||||||
|
|
||||||
|
SelectAreaAsync: function (params, invocation) {
|
||||||
|
let selectArea = new SelectArea();
|
||||||
|
selectArea.show();
|
||||||
|
selectArea.connect('finished', Lang.bind(this,
|
||||||
|
function(selectArea, areaRectangle) {
|
||||||
|
if (areaRectangle) {
|
||||||
|
let retval = GLib.Variant.new('(iiii)',
|
||||||
|
[areaRectangle.x, areaRectangle.y,
|
||||||
|
areaRectangle.width, areaRectangle.height]);
|
||||||
|
invocation.return_value(retval);
|
||||||
|
} else {
|
||||||
|
invocation.return_error_literal(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED,
|
||||||
|
"Operation was cancelled");
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
},
|
||||||
|
|
||||||
|
FlashArea: function(x, y, width, height) {
|
||||||
|
let flashspot = new Flashspot({ x : x, y : y, width: width, height: height});
|
||||||
|
flashspot.fire();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const SelectArea = new Lang.Class({
|
||||||
|
Name: 'SelectArea',
|
||||||
|
|
||||||
|
_init: function() {
|
||||||
|
this._startX = -1;
|
||||||
|
this._startY = -1;
|
||||||
|
this._lastX = 0;
|
||||||
|
this._lastY = 0;
|
||||||
|
|
||||||
|
this._initRubberbandColors();
|
||||||
|
|
||||||
|
this._group = new St.Widget({ visible: false,
|
||||||
|
reactive: true,
|
||||||
|
x: 0,
|
||||||
|
y: 0 });
|
||||||
|
Main.uiGroup.add_actor(this._group);
|
||||||
|
|
||||||
|
this._group.connect('button-press-event',
|
||||||
|
Lang.bind(this, this._onButtonPress));
|
||||||
|
this._group.connect('button-release-event',
|
||||||
|
Lang.bind(this, this._onButtonRelease));
|
||||||
|
this._group.connect('key-press-event',
|
||||||
|
Lang.bind(this, this._onKeyPress));
|
||||||
|
this._group.connect('motion-event',
|
||||||
|
Lang.bind(this, this._onMotionEvent));
|
||||||
|
|
||||||
|
let constraint = new Clutter.BindConstraint({ source: global.stage,
|
||||||
|
coordinate: Clutter.BindCoordinate.ALL });
|
||||||
|
this._group.add_constraint(constraint);
|
||||||
|
|
||||||
|
this._rubberband = new Clutter.Rectangle({ color: this._background,
|
||||||
|
has_border: true,
|
||||||
|
border_width: 1,
|
||||||
|
border_color: this._border });
|
||||||
|
this._group.add_actor(this._rubberband);
|
||||||
|
},
|
||||||
|
|
||||||
|
show: function() {
|
||||||
|
if (!Main.pushModal(this._group) || this._group.visible)
|
||||||
|
return;
|
||||||
|
|
||||||
|
global.set_cursor(Shell.Cursor.CROSSHAIR);
|
||||||
|
this._group.visible = true;
|
||||||
|
},
|
||||||
|
|
||||||
|
_initRubberbandColors: function() {
|
||||||
|
function colorFromRGBA(rgba) {
|
||||||
|
return new Clutter.Color({ red: rgba.red * 255,
|
||||||
|
green: rgba.green * 255,
|
||||||
|
blue: rgba.blue * 255,
|
||||||
|
alpha: rgba.alpha * 255 });
|
||||||
|
}
|
||||||
|
|
||||||
|
let path = new Gtk.WidgetPath();
|
||||||
|
path.append_type(Gtk.IconView);
|
||||||
|
|
||||||
|
let context = new Gtk.StyleContext();
|
||||||
|
context.set_path(path);
|
||||||
|
context.add_class('rubberband');
|
||||||
|
|
||||||
|
this._background = colorFromRGBA(context.get_background_color(Gtk.StateFlags.NORMAL));
|
||||||
|
this._border = colorFromRGBA(context.get_border_color(Gtk.StateFlags.NORMAL));
|
||||||
|
},
|
||||||
|
|
||||||
|
_getGeometry: function() {
|
||||||
|
return { x: Math.min(this._startX, this._lastX),
|
||||||
|
y: Math.min(this._startY, this._lastY),
|
||||||
|
width: Math.abs(this._startX - this._lastX),
|
||||||
|
height: Math.abs(this._startY - this._lastY) };
|
||||||
|
},
|
||||||
|
|
||||||
|
_onKeyPress: function(actor, event) {
|
||||||
|
if (event.get_key_symbol() == Clutter.Escape)
|
||||||
|
this._destroy(null, false);
|
||||||
|
|
||||||
|
return;
|
||||||
|
},
|
||||||
|
|
||||||
|
_onMotionEvent: function(actor, event) {
|
||||||
|
if (this._startX == -1 || this._startY == -1)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
[this._lastX, this._lastY] = event.get_coords();
|
||||||
|
let geometry = this._getGeometry();
|
||||||
|
|
||||||
|
this._rubberband.set_position(geometry.x, geometry.y);
|
||||||
|
this._rubberband.set_size(geometry.width, geometry.height);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
|
||||||
|
_onButtonPress: function(actor, event) {
|
||||||
|
[this._startX, this._startY] = event.get_coords();
|
||||||
|
this._rubberband.set_position(this._startX, this._startY);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
|
||||||
|
_onButtonRelease: function(actor, event) {
|
||||||
|
this._destroy(this._getGeometry(), true);
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
|
||||||
|
_destroy: function(geometry, fade) {
|
||||||
|
Tweener.addTween(this._group,
|
||||||
|
{ opacity: 0,
|
||||||
|
time: fade ? 0.2 : 0,
|
||||||
|
transition: 'easeOutQuad',
|
||||||
|
onComplete: Lang.bind(this,
|
||||||
|
function() {
|
||||||
|
Main.popModal(this._group);
|
||||||
|
this._group.destroy();
|
||||||
|
global.unset_cursor();
|
||||||
|
|
||||||
|
this.emit('finished', geometry);
|
||||||
|
})
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Signals.addSignalMethods(SelectArea.prototype);
|
||||||
|
|
||||||
|
const FLASHSPOT_ANIMATION_TIME = 0.25; // seconds
|
||||||
|
|
||||||
|
const Flashspot = new Lang.Class({
|
||||||
|
Name: 'Flashspot',
|
||||||
|
Extends: Lightbox.Lightbox,
|
||||||
|
|
||||||
|
_init: function(area) {
|
||||||
|
this.parent(Main.uiGroup, { inhibitEvents: true,
|
||||||
|
width: area.width,
|
||||||
|
height: area.height });
|
||||||
|
|
||||||
|
this.actor.style_class = 'flashspot';
|
||||||
|
this.actor.set_position(area.x, area.y);
|
||||||
|
},
|
||||||
|
|
||||||
|
fire: function() {
|
||||||
|
this.actor.opacity = 0;
|
||||||
|
Tweener.addTween(this.actor,
|
||||||
|
{ opacity: 255,
|
||||||
|
time: FLASHSPOT_ANIMATION_TIME,
|
||||||
|
transition: 'linear',
|
||||||
|
onComplete: Lang.bind(this, this._onFireShowComplete)
|
||||||
|
});
|
||||||
|
this.actor.show();
|
||||||
|
},
|
||||||
|
|
||||||
|
_onFireShowComplete: function() {
|
||||||
|
Tweener.addTween(this.actor,
|
||||||
|
{ opacity: 0,
|
||||||
|
time: FLASHSPOT_ANIMATION_TIME,
|
||||||
|
transition: 'linear',
|
||||||
|
onComplete: Lang.bind(this, function() {
|
||||||
|
this.destroy();
|
||||||
|
})
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
181
js/ui/search.js
181
js/ui/search.js
@ -1,187 +1,10 @@
|
|||||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
const Gio = imports.gi.Gio;
|
|
||||||
const GLib = imports.gi.GLib;
|
|
||||||
const Lang = imports.lang;
|
const Lang = imports.lang;
|
||||||
const Signals = imports.signals;
|
const Signals = imports.signals;
|
||||||
const Shell = imports.gi.Shell;
|
|
||||||
const Util = imports.misc.util;
|
|
||||||
|
|
||||||
const FileUtils = imports.misc.fileUtils;
|
|
||||||
const Main = imports.ui.main;
|
|
||||||
|
|
||||||
const SEARCH_PROVIDERS_SCHEMA = 'org.gnome.desktop.search-providers';
|
const SEARCH_PROVIDERS_SCHEMA = 'org.gnome.desktop.search-providers';
|
||||||
|
|
||||||
// Not currently referenced by the search API, but
|
|
||||||
// this enumeration can be useful for provider
|
|
||||||
// implementations.
|
|
||||||
const MatchType = {
|
|
||||||
NONE: 0,
|
|
||||||
SUBSTRING: 1,
|
|
||||||
PREFIX: 2
|
|
||||||
};
|
|
||||||
|
|
||||||
const SearchResultDisplay = new Lang.Class({
|
|
||||||
Name: 'SearchResultDisplay',
|
|
||||||
|
|
||||||
_init: function(provider) {
|
|
||||||
this.provider = provider;
|
|
||||||
this.actor = null;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* renderResults:
|
|
||||||
* @results: List of identifier strings
|
|
||||||
* @terms: List of search term strings
|
|
||||||
*
|
|
||||||
* Display the given search matches which resulted
|
|
||||||
* from the given terms. It's expected that not
|
|
||||||
* all results will fit in the space for the container
|
|
||||||
* actor; in this case, show as many as makes sense
|
|
||||||
* for your result type.
|
|
||||||
*
|
|
||||||
* The terms are useful for search match highlighting.
|
|
||||||
*/
|
|
||||||
renderResults: function(results, terms) {
|
|
||||||
throw new Error('Not implemented');
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* clear:
|
|
||||||
* Remove all results from this display.
|
|
||||||
*/
|
|
||||||
clear: function() {
|
|
||||||
this.actor.destroy_all_children();
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* getVisibleResultCount:
|
|
||||||
*
|
|
||||||
* Returns: The number of actors visible.
|
|
||||||
*/
|
|
||||||
getVisibleResultCount: function() {
|
|
||||||
throw new Error('Not implemented');
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
|
||||||
* SearchProvider:
|
|
||||||
*
|
|
||||||
* Subclass this object to add a new result type
|
|
||||||
* to the search system, then call registerProvider()
|
|
||||||
* in SearchSystem with an instance.
|
|
||||||
* Search is asynchronous and uses the
|
|
||||||
* getInitialResultSet()/getSubsearchResultSet() methods.
|
|
||||||
*/
|
|
||||||
const SearchProvider = new Lang.Class({
|
|
||||||
Name: 'SearchProvider',
|
|
||||||
|
|
||||||
_init: function(title, appInfo, isRemoteProvider) {
|
|
||||||
this.title = title;
|
|
||||||
this.appInfo = appInfo;
|
|
||||||
this.searchSystem = null;
|
|
||||||
this.isRemoteProvider = !!isRemoteProvider;
|
|
||||||
this.canLaunchSearch = false;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* getInitialResultSet:
|
|
||||||
* @terms: Array of search terms, treated as logical AND
|
|
||||||
*
|
|
||||||
* Called when the user first begins a search (most likely
|
|
||||||
* therefore a single term of length one or two), or when
|
|
||||||
* a new term is added.
|
|
||||||
*
|
|
||||||
* Should "return" an array of result identifier strings representing
|
|
||||||
* items which match the given search terms. This
|
|
||||||
* is expected to be a substring match on the metadata for a given
|
|
||||||
* item. Ordering of returned results is up to the discretion of the provider,
|
|
||||||
* but you should follow these heruistics:
|
|
||||||
*
|
|
||||||
* * Put items where the term matches multiple criteria (e.g. name and
|
|
||||||
* description) before single matches
|
|
||||||
* * Put items which match on a prefix before non-prefix substring matches
|
|
||||||
*
|
|
||||||
* We say "return" above, but in order to make the query asynchronous, use
|
|
||||||
* this.searchSystem.pushResults();. The return value should be ignored.
|
|
||||||
*
|
|
||||||
* This function should be fast; do not perform unindexed full-text searches
|
|
||||||
* or network queries.
|
|
||||||
*/
|
|
||||||
getInitialResultSet: function(terms) {
|
|
||||||
throw new Error('Not implemented');
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* getSubsearchResultSet:
|
|
||||||
* @previousResults: Array of item identifiers
|
|
||||||
* @newTerms: Updated search terms
|
|
||||||
*
|
|
||||||
* Called when a search is performed which is a "subsearch" of
|
|
||||||
* the previous search; i.e. when every search term has exactly
|
|
||||||
* one corresponding term in the previous search which is a prefix
|
|
||||||
* of the new term.
|
|
||||||
*
|
|
||||||
* This allows search providers to only search through the previous
|
|
||||||
* result set, rather than possibly performing a full re-query.
|
|
||||||
*
|
|
||||||
* Similar to getInitialResultSet, the return value for this will
|
|
||||||
* be ignored; use this.searchSystem.pushResults();.
|
|
||||||
*/
|
|
||||||
getSubsearchResultSet: function(previousResults, newTerms) {
|
|
||||||
throw new Error('Not implemented');
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* getResultMetas:
|
|
||||||
* @ids: Result identifier strings
|
|
||||||
*
|
|
||||||
* Call callback with array of objects with 'id', 'name', (both strings) and
|
|
||||||
* 'createIcon' (function(size) returning a Clutter.Texture) properties
|
|
||||||
* with the same number of members as @ids
|
|
||||||
*/
|
|
||||||
getResultMetas: function(ids, callback) {
|
|
||||||
throw new Error('Not implemented');
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* createResultActor:
|
|
||||||
* @resultMeta: Object with result metadata
|
|
||||||
* @terms: Array of search terms, should be used for highlighting
|
|
||||||
*
|
|
||||||
* Search providers may optionally override this to render a
|
|
||||||
* particular serch result in a custom fashion. The default
|
|
||||||
* implementation will show the icon next to the name.
|
|
||||||
*
|
|
||||||
* The actor should be an instance of St.Widget, with the style class
|
|
||||||
* 'search-result-content'.
|
|
||||||
*/
|
|
||||||
createResultActor: function(resultMeta, terms) {
|
|
||||||
return null;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* activateResult:
|
|
||||||
* @id: Result identifier string
|
|
||||||
*
|
|
||||||
* Called when the user chooses a given result.
|
|
||||||
*/
|
|
||||||
activateResult: function(id) {
|
|
||||||
throw new Error('Not implemented');
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* launchSearch:
|
|
||||||
* @terms: Current search terms
|
|
||||||
*
|
|
||||||
* Called when the user clicks the provider icon.
|
|
||||||
*/
|
|
||||||
launchSearch: function(terms) {
|
|
||||||
throw new Error('Not implemented');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
Signals.addSignalMethods(SearchProvider.prototype);
|
|
||||||
|
|
||||||
const SearchSystem = new Lang.Class({
|
const SearchSystem = new Lang.Class({
|
||||||
Name: 'SearchSystem',
|
Name: 'SearchSystem',
|
||||||
|
|
||||||
@ -273,7 +96,7 @@ const SearchSystem = new Lang.Class({
|
|||||||
results.push([provider, []]);
|
results.push([provider, []]);
|
||||||
provider.getSubsearchResultSet(previousResults, terms);
|
provider.getSubsearchResultSet(previousResults, terms);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log('A ' + error.name + ' has occured in ' + provider.title + ': ' + error.message);
|
log('A ' + error.name + ' has occured in ' + provider.id + ': ' + error.message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -283,7 +106,7 @@ const SearchSystem = new Lang.Class({
|
|||||||
results.push([provider, []]);
|
results.push([provider, []]);
|
||||||
provider.getInitialResultSet(terms);
|
provider.getInitialResultSet(terms);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log('A ' + error.name + ' has occured in ' + provider.title + ': ' + error.message);
|
log('A ' + error.name + ' has occured in ' + provider.id + ': ' + error.message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,10 +11,11 @@ const DND = imports.ui.dnd;
|
|||||||
const IconGrid = imports.ui.iconGrid;
|
const IconGrid = imports.ui.iconGrid;
|
||||||
const Main = imports.ui.main;
|
const Main = imports.ui.main;
|
||||||
const Overview = imports.ui.overview;
|
const Overview = imports.ui.overview;
|
||||||
|
const Separator = imports.ui.separator;
|
||||||
const Search = imports.ui.search;
|
const Search = imports.ui.search;
|
||||||
|
|
||||||
const MAX_SEARCH_RESULTS_ROWS = 1;
|
const MAX_LIST_SEARCH_RESULTS_ROWS = 3;
|
||||||
|
const MAX_GRID_SEARCH_RESULTS_ROWS = 1;
|
||||||
|
|
||||||
const SearchResult = new Lang.Class({
|
const SearchResult = new Lang.Class({
|
||||||
Name: 'SearchResult',
|
Name: 'SearchResult',
|
||||||
@ -23,33 +24,102 @@ const SearchResult = new Lang.Class({
|
|||||||
this.provider = provider;
|
this.provider = provider;
|
||||||
this.metaInfo = metaInfo;
|
this.metaInfo = metaInfo;
|
||||||
this.terms = terms;
|
this.terms = terms;
|
||||||
this.actor = new St.Button({ style_class: 'search-result',
|
|
||||||
reactive: true,
|
this.actor = new St.Button({ reactive: true,
|
||||||
|
can_focus: true,
|
||||||
|
track_hover: true,
|
||||||
x_align: St.Align.START,
|
x_align: St.Align.START,
|
||||||
y_fill: true });
|
y_fill: true });
|
||||||
|
|
||||||
this.actor._delegate = this;
|
this.actor._delegate = this;
|
||||||
this._dragActorSource = null;
|
this.actor.connect('clicked', Lang.bind(this, this.activate));
|
||||||
|
},
|
||||||
|
|
||||||
|
activate: function() {
|
||||||
|
this.provider.activateResult(this.metaInfo.id, this.terms);
|
||||||
|
Main.overview.toggle();
|
||||||
|
},
|
||||||
|
|
||||||
|
setSelected: function(selected) {
|
||||||
|
if (selected)
|
||||||
|
this.actor.add_style_pseudo_class('selected');
|
||||||
|
else
|
||||||
|
this.actor.remove_style_pseudo_class('selected');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const ListSearchResult = new Lang.Class({
|
||||||
|
Name: 'ListSearchResult',
|
||||||
|
Extends: SearchResult,
|
||||||
|
|
||||||
|
ICON_SIZE: 64,
|
||||||
|
|
||||||
|
_init: function(provider, metaInfo, terms) {
|
||||||
|
this.parent(provider, metaInfo, terms);
|
||||||
|
|
||||||
|
this.actor.style_class = 'list-search-result';
|
||||||
|
this.actor.x_fill = true;
|
||||||
|
|
||||||
|
let content = new St.BoxLayout({ style_class: 'list-search-result-content',
|
||||||
|
vertical: false });
|
||||||
|
this.actor.set_child(content);
|
||||||
|
|
||||||
|
// An icon for, or thumbnail of, content
|
||||||
|
let icon = this.metaInfo['createIcon'](this.ICON_SIZE);
|
||||||
|
if (icon) {
|
||||||
|
content.add(icon);
|
||||||
|
}
|
||||||
|
|
||||||
|
let details = new St.BoxLayout({ vertical: true });
|
||||||
|
content.add(details, { x_fill: true,
|
||||||
|
y_fill: false,
|
||||||
|
x_align: St.Align.START,
|
||||||
|
y_align: St.Align.MIDDLE });
|
||||||
|
|
||||||
|
let title = new St.Label({ style_class: 'list-search-result-title',
|
||||||
|
text: this.metaInfo['name'] })
|
||||||
|
details.add(title, { x_fill: false,
|
||||||
|
y_fill: false,
|
||||||
|
x_align: St.Align.START,
|
||||||
|
y_align: St.Align.START });
|
||||||
|
|
||||||
|
// TODO: should highlight terms in the description here
|
||||||
|
if (this.metaInfo['description']) {
|
||||||
|
let description = new St.Label({ style_class: 'list-search-result-description',
|
||||||
|
text: '"' + this.metaInfo['description'] + '"' });
|
||||||
|
details.add(description, { x_fill: false,
|
||||||
|
y_fill: false,
|
||||||
|
x_align: St.Align.START,
|
||||||
|
y_align: St.Align.END });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const GridSearchResult = new Lang.Class({
|
||||||
|
Name: 'GridSearchResult',
|
||||||
|
Extends: SearchResult,
|
||||||
|
|
||||||
|
_init: function(provider, metaInfo, terms) {
|
||||||
|
this.parent(provider, metaInfo, terms);
|
||||||
|
|
||||||
|
this.actor.style_class = 'grid-search-result';
|
||||||
|
|
||||||
let content = provider.createResultActor(metaInfo, terms);
|
let content = provider.createResultActor(metaInfo, terms);
|
||||||
|
let dragSource = null;
|
||||||
|
|
||||||
if (content == null) {
|
if (content == null) {
|
||||||
content = new St.Bin({ style_class: 'search-result-content',
|
content = new St.Bin();
|
||||||
reactive: true,
|
|
||||||
can_focus: true,
|
|
||||||
track_hover: true,
|
|
||||||
accessible_role: Atk.Role.PUSH_BUTTON });
|
|
||||||
let icon = new IconGrid.BaseIcon(this.metaInfo['name'],
|
let icon = new IconGrid.BaseIcon(this.metaInfo['name'],
|
||||||
{ createIcon: this.metaInfo['createIcon'] });
|
{ createIcon: this.metaInfo['createIcon'] });
|
||||||
content.set_child(icon.actor);
|
content.set_child(icon.actor);
|
||||||
this._dragActorSource = icon.icon;
|
|
||||||
content.label_actor = icon.label;
|
content.label_actor = icon.label;
|
||||||
|
dragSource = icon.icon;
|
||||||
} else {
|
} else {
|
||||||
if (content._delegate && content._delegate.getDragActorSource)
|
if (content._delegate && content._delegate.getDragActorSource)
|
||||||
this._dragActorSource = content._delegate.getDragActorSource();
|
dragSource = content._delegate.getDragActorSource();
|
||||||
}
|
}
|
||||||
this._content = content;
|
|
||||||
this.actor.set_child(content);
|
|
||||||
|
|
||||||
this.actor.connect('clicked', Lang.bind(this, this._onResultClicked));
|
this.actor.set_child(content);
|
||||||
|
|
||||||
let draggable = DND.makeDraggable(this.actor);
|
let draggable = DND.makeDraggable(this.actor);
|
||||||
draggable.connect('drag-begin',
|
draggable.connect('drag-begin',
|
||||||
@ -64,32 +134,18 @@ const SearchResult = new Lang.Class({
|
|||||||
Lang.bind(this, function() {
|
Lang.bind(this, function() {
|
||||||
Main.overview.endItemDrag(this);
|
Main.overview.endItemDrag(this);
|
||||||
}));
|
}));
|
||||||
},
|
|
||||||
|
|
||||||
setSelected: function(selected) {
|
if (!dragSource)
|
||||||
if (selected)
|
// not exactly right, but alignment problems are hard to notice
|
||||||
this._content.add_style_pseudo_class('selected');
|
dragSource = content;
|
||||||
else
|
this._dragActorSource = dragSource;
|
||||||
this._content.remove_style_pseudo_class('selected');
|
|
||||||
},
|
|
||||||
|
|
||||||
activate: function() {
|
|
||||||
this.provider.activateResult(this.metaInfo.id, this.terms);
|
|
||||||
Main.overview.toggle();
|
|
||||||
},
|
|
||||||
|
|
||||||
_onResultClicked: function(actor) {
|
|
||||||
this.activate();
|
|
||||||
},
|
},
|
||||||
|
|
||||||
getDragActorSource: function() {
|
getDragActorSource: function() {
|
||||||
if (this._dragActorSource)
|
return this._dragActorSource;
|
||||||
return this._dragActorSource;
|
|
||||||
// not exactly right, but alignment problems are hard to notice
|
|
||||||
return this._content;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
getDragActor: function(stageX, stageY) {
|
getDragActor: function() {
|
||||||
return this.metaInfo['createIcon'](Main.overview.dashIconSize);
|
return this.metaInfo['createIcon'](Main.overview.dashIconSize);
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -101,47 +157,48 @@ const SearchResult = new Lang.Class({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const ListSearchResults = new Lang.Class({
|
||||||
|
Name: 'ListSearchResults',
|
||||||
|
|
||||||
const GridSearchResults = new Lang.Class({
|
_init: function(provider) {
|
||||||
Name: 'GridSearchResults',
|
this.provider = provider;
|
||||||
Extends: Search.SearchResultDisplay,
|
|
||||||
|
|
||||||
_init: function(provider, grid) {
|
this.actor = new St.BoxLayout({ style_class: 'search-section-content' });
|
||||||
this.parent(provider);
|
this.providerIcon = new ProviderIcon(provider);
|
||||||
|
this.providerIcon.connect('clicked', Lang.bind(this,
|
||||||
this._grid = grid || new IconGrid.IconGrid({ rowLimit: MAX_SEARCH_RESULTS_ROWS,
|
function() {
|
||||||
xAlign: St.Align.START });
|
provider.launchSearch(this._terms);
|
||||||
this.actor = new St.Bin({ x_align: St.Align.START });
|
Main.overview.toggle();
|
||||||
|
|
||||||
this.actor.set_child(this._grid.actor);
|
|
||||||
this._width = 0;
|
|
||||||
this.actor.connect('notify::width', Lang.bind(this, function() {
|
|
||||||
this._width = this.actor.width;
|
|
||||||
Meta.later_add(Meta.LaterType.BEFORE_REDRAW, Lang.bind(this, function() {
|
|
||||||
let results = this.getResultsForDisplay();
|
|
||||||
if (results.length == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
provider.getResultMetas(results, Lang.bind(this, this.renderResults));
|
|
||||||
}));
|
}));
|
||||||
}));
|
|
||||||
|
this.actor.add(this.providerIcon, { x_fill: false,
|
||||||
|
y_fill: false,
|
||||||
|
x_align: St.Align.START,
|
||||||
|
y_align: St.Align.START });
|
||||||
|
|
||||||
|
this._content = new St.BoxLayout({ style_class: 'list-search-results',
|
||||||
|
vertical: true });
|
||||||
|
this.actor.add_actor(this._content);
|
||||||
|
|
||||||
this._notDisplayedResult = [];
|
this._notDisplayedResult = [];
|
||||||
this._terms = [];
|
this._terms = [];
|
||||||
this._pendingClear = false;
|
this._pendingClear = false;
|
||||||
},
|
},
|
||||||
|
|
||||||
getResultsForDisplay: function() {
|
getResultsForDisplay: function() {
|
||||||
let alreadyVisible = this._pendingClear ? 0 : this._grid.visibleItemsCount();
|
let alreadyVisible = this._pendingClear ? 0 : this.getVisibleResultCount();
|
||||||
let canDisplay = this._grid.childrenInRow(this._width) * this._grid.getRowLimit()
|
let canDisplay = MAX_LIST_SEARCH_RESULTS_ROWS - alreadyVisible;
|
||||||
- alreadyVisible;
|
|
||||||
|
|
||||||
let numResults = Math.min(this._notDisplayedResult.length, canDisplay);
|
let newResults = this._notDisplayedResult.splice(0, canDisplay);
|
||||||
|
return newResults;
|
||||||
return this._notDisplayedResult.splice(0, numResults);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
getVisibleResultCount: function() {
|
getVisibleResultCount: function() {
|
||||||
return this._grid.visibleItemsCount();
|
return this._content.get_n_children();
|
||||||
|
},
|
||||||
|
|
||||||
|
hasMoreResults: function() {
|
||||||
|
return this._notDisplayedResult.length > 0;
|
||||||
},
|
},
|
||||||
|
|
||||||
setResults: function(results, terms) {
|
setResults: function(results, terms) {
|
||||||
@ -153,7 +210,68 @@ const GridSearchResults = new Lang.Class({
|
|||||||
|
|
||||||
renderResults: function(metas) {
|
renderResults: function(metas) {
|
||||||
for (let i = 0; i < metas.length; i++) {
|
for (let i = 0; i < metas.length; i++) {
|
||||||
let display = new SearchResult(this.provider, metas[i], this._terms);
|
let display = new ListSearchResult(this.provider, metas[i], this._terms);
|
||||||
|
this._content.add_actor(display.actor);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
clear: function () {
|
||||||
|
this._content.destroy_all_children();
|
||||||
|
this._pendingClear = false;
|
||||||
|
},
|
||||||
|
|
||||||
|
getFirstResult: function() {
|
||||||
|
if (this.getVisibleResultCount() > 0)
|
||||||
|
return this._content.get_child_at_index(0)._delegate;
|
||||||
|
else
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const GridSearchResults = new Lang.Class({
|
||||||
|
Name: 'GridSearchResults',
|
||||||
|
|
||||||
|
_init: function(provider) {
|
||||||
|
this.provider = provider;
|
||||||
|
|
||||||
|
this._grid = new IconGrid.IconGrid({ rowLimit: MAX_GRID_SEARCH_RESULTS_ROWS,
|
||||||
|
xAlign: St.Align.START });
|
||||||
|
this.actor = new St.Bin({ x_align: St.Align.MIDDLE });
|
||||||
|
|
||||||
|
this.actor.set_child(this._grid.actor);
|
||||||
|
|
||||||
|
this._notDisplayedResult = [];
|
||||||
|
this._terms = [];
|
||||||
|
this._pendingClear = false;
|
||||||
|
},
|
||||||
|
|
||||||
|
getResultsForDisplay: function() {
|
||||||
|
let alreadyVisible = this._pendingClear ? 0 : this._grid.visibleItemsCount();
|
||||||
|
let canDisplay = this._grid.childrenInRow(this.actor.width) * this._grid.getRowLimit()
|
||||||
|
- alreadyVisible;
|
||||||
|
|
||||||
|
let newResults = this._notDisplayedResult.splice(0, canDisplay);
|
||||||
|
return newResults;
|
||||||
|
},
|
||||||
|
|
||||||
|
getVisibleResultCount: function() {
|
||||||
|
return this._grid.visibleItemsCount();
|
||||||
|
},
|
||||||
|
|
||||||
|
hasMoreResults: function() {
|
||||||
|
return this._notDisplayedResult.length > 0;
|
||||||
|
},
|
||||||
|
|
||||||
|
setResults: function(results, terms) {
|
||||||
|
// copy the lists
|
||||||
|
this._notDisplayedResult = results.slice(0);
|
||||||
|
this._terms = terms.slice(0);
|
||||||
|
this._pendingClear = true;
|
||||||
|
},
|
||||||
|
|
||||||
|
renderResults: function(metas) {
|
||||||
|
for (let i = 0; i < metas.length; i++) {
|
||||||
|
let display = new GridSearchResult(this.provider, metas[i], this._terms);
|
||||||
this._grid.addItem(display.actor);
|
this._grid.addItem(display.actor);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -224,19 +342,27 @@ const SearchResults = new Lang.Class({
|
|||||||
createProviderMeta: function(provider) {
|
createProviderMeta: function(provider) {
|
||||||
let providerBox = new St.BoxLayout({ style_class: 'search-section',
|
let providerBox = new St.BoxLayout({ style_class: 'search-section',
|
||||||
vertical: true });
|
vertical: true });
|
||||||
let title = new St.Label({ style_class: 'search-section-header',
|
let providerIcon = null;
|
||||||
text: provider.title });
|
let resultDisplay = null;
|
||||||
providerBox.add(title, { x_fill: false, x_align: St.Align.START });
|
|
||||||
|
|
||||||
let resultDisplayBin = new St.Bin({ style_class: 'search-section-results',
|
if (provider.appInfo) {
|
||||||
|
resultDisplay = new ListSearchResults(provider);
|
||||||
|
providerIcon = resultDisplay.providerIcon;
|
||||||
|
} else {
|
||||||
|
resultDisplay = new GridSearchResults(provider);
|
||||||
|
}
|
||||||
|
|
||||||
|
let resultDisplayBin = new St.Bin({ child: resultDisplay.actor,
|
||||||
x_fill: true,
|
x_fill: true,
|
||||||
y_fill: true });
|
y_fill: true });
|
||||||
providerBox.add(resultDisplayBin, { expand: true });
|
providerBox.add(resultDisplayBin, { expand: true });
|
||||||
let resultDisplay = new GridSearchResults(provider);
|
|
||||||
resultDisplayBin.set_child(resultDisplay.actor);
|
let separator = new Separator.HorizontalSeparator({ style_class: 'search-section-separator' });
|
||||||
|
providerBox.add(separator.actor);
|
||||||
|
|
||||||
this._providerMeta.push({ provider: provider,
|
this._providerMeta.push({ provider: provider,
|
||||||
actor: providerBox,
|
actor: providerBox,
|
||||||
|
icon: providerIcon,
|
||||||
resultDisplay: resultDisplay });
|
resultDisplay: resultDisplay });
|
||||||
this._content.add(providerBox);
|
this._content.add(providerBox);
|
||||||
},
|
},
|
||||||
@ -343,6 +469,11 @@ const SearchResults = new Lang.Class({
|
|||||||
meta.resultDisplay.setResults(providerResults, terms);
|
meta.resultDisplay.setResults(providerResults, terms);
|
||||||
let results = meta.resultDisplay.getResultsForDisplay();
|
let results = meta.resultDisplay.getResultsForDisplay();
|
||||||
|
|
||||||
|
if (meta.icon)
|
||||||
|
meta.icon.moreIcon.visible =
|
||||||
|
meta.resultDisplay.hasMoreResults() &&
|
||||||
|
provider.canLaunchSearch;
|
||||||
|
|
||||||
provider.getResultMetas(results, Lang.bind(this, function(metas) {
|
provider.getResultMetas(results, Lang.bind(this, function(metas) {
|
||||||
this._clearDisplayForProvider(provider);
|
this._clearDisplayForProvider(provider);
|
||||||
meta.actor.show();
|
meta.actor.show();
|
||||||
@ -388,10 +519,37 @@ const SearchResults = new Lang.Class({
|
|||||||
|
|
||||||
let from = this._defaultResult ? this._defaultResult.actor : null;
|
let from = this._defaultResult ? this._defaultResult.actor : null;
|
||||||
this.actor.navigate_focus(from, direction, false);
|
this.actor.navigate_focus(from, direction, false);
|
||||||
if (this._defaultResult) {
|
}
|
||||||
// The default result appears focused, so navigate directly to the
|
});
|
||||||
// next result.
|
|
||||||
this.actor.navigate_focus(global.stage.key_focus, direction, false);
|
const ProviderIcon = new Lang.Class({
|
||||||
}
|
Name: 'ProviderIcon',
|
||||||
|
Extends: St.Button,
|
||||||
|
|
||||||
|
PROVIDER_ICON_SIZE: 48,
|
||||||
|
|
||||||
|
_init: function(provider) {
|
||||||
|
this.provider = provider;
|
||||||
|
this.parent({ style_class: 'search-provider-icon',
|
||||||
|
reactive: true,
|
||||||
|
can_focus: true,
|
||||||
|
track_hover: true });
|
||||||
|
|
||||||
|
this._content = new St.Widget({ layout_manager: new Clutter.BinLayout() });
|
||||||
|
this.set_child(this._content);
|
||||||
|
|
||||||
|
let rtl = (this.get_text_direction() == Clutter.TextDirection.RTL);
|
||||||
|
|
||||||
|
this.moreIcon = new St.Widget({ style_class: 'search-provider-icon-more',
|
||||||
|
visible: false,
|
||||||
|
x_align: rtl ? Clutter.ActorAlign.START : Clutter.ActorAlign.END,
|
||||||
|
y_align: Clutter.ActorAlign.END,
|
||||||
|
x_expand: true,
|
||||||
|
y_expand: true });
|
||||||
|
|
||||||
|
let icon = new St.Icon({ icon_size: this.PROVIDER_ICON_SIZE,
|
||||||
|
gicon: provider.appInfo.get_icon() });
|
||||||
|
this._content.add_actor(icon);
|
||||||
|
this._content.add_actor(this.moreIcon);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
35
js/ui/separator.js
Normal file
35
js/ui/separator.js
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
|
const Cairo = imports.cairo;
|
||||||
|
const Lang = imports.lang;
|
||||||
|
const St = imports.gi.St;
|
||||||
|
|
||||||
|
const HorizontalSeparator = new Lang.Class({
|
||||||
|
Name: 'HorizontalSeparator',
|
||||||
|
|
||||||
|
_init: function (params) {
|
||||||
|
this.actor = new St.DrawingArea(params);
|
||||||
|
this.actor.connect('repaint', Lang.bind(this, this._onRepaint));
|
||||||
|
},
|
||||||
|
|
||||||
|
_onRepaint: function(area) {
|
||||||
|
let cr = area.get_context();
|
||||||
|
let themeNode = area.get_theme_node();
|
||||||
|
let [width, height] = area.get_surface_size();
|
||||||
|
let margin = themeNode.get_length('-margin-horizontal');
|
||||||
|
let gradientHeight = themeNode.get_length('-gradient-height');
|
||||||
|
let startColor = themeNode.get_color('-gradient-start');
|
||||||
|
let endColor = themeNode.get_color('-gradient-end');
|
||||||
|
|
||||||
|
let gradientWidth = (width - margin * 2);
|
||||||
|
let gradientOffset = (height - gradientHeight) / 2;
|
||||||
|
let pattern = new Cairo.LinearGradient(margin, gradientOffset, width - margin, gradientOffset + gradientHeight);
|
||||||
|
pattern.addColorStopRGBA(0, startColor.red / 255, startColor.green / 255, startColor.blue / 255, startColor.alpha / 255);
|
||||||
|
pattern.addColorStopRGBA(0.5, endColor.red / 255, endColor.green / 255, endColor.blue / 255, endColor.alpha / 255);
|
||||||
|
pattern.addColorStopRGBA(1, startColor.red / 255, startColor.green / 255, startColor.blue / 255, startColor.alpha / 255);
|
||||||
|
cr.setSource(pattern);
|
||||||
|
cr.rectangle(margin, gradientOffset, gradientWidth, gradientHeight);
|
||||||
|
cr.fill();
|
||||||
|
cr.$dispose();
|
||||||
|
}
|
||||||
|
});
|
@ -9,8 +9,8 @@ const Config = imports.misc.config;
|
|||||||
const ExtensionSystem = imports.ui.extensionSystem;
|
const ExtensionSystem = imports.ui.extensionSystem;
|
||||||
const ExtensionDownloader = imports.ui.extensionDownloader;
|
const ExtensionDownloader = imports.ui.extensionDownloader;
|
||||||
const ExtensionUtils = imports.misc.extensionUtils;
|
const ExtensionUtils = imports.misc.extensionUtils;
|
||||||
const Flashspot = imports.ui.flashspot;
|
|
||||||
const Main = imports.ui.main;
|
const Main = imports.ui.main;
|
||||||
|
const Screenshot = imports.ui.screenshot;
|
||||||
|
|
||||||
const GnomeShellIface = <interface name="org.gnome.Shell">
|
const GnomeShellIface = <interface name="org.gnome.Shell">
|
||||||
<method name="Eval">
|
<method name="Eval">
|
||||||
@ -18,34 +18,6 @@ const GnomeShellIface = <interface name="org.gnome.Shell">
|
|||||||
<arg type="b" direction="out" name="success" />
|
<arg type="b" direction="out" name="success" />
|
||||||
<arg type="s" direction="out" name="result" />
|
<arg type="s" direction="out" name="result" />
|
||||||
</method>
|
</method>
|
||||||
<method name="ScreenshotArea">
|
|
||||||
<arg type="i" direction="in" name="x"/>
|
|
||||||
<arg type="i" direction="in" name="y"/>
|
|
||||||
<arg type="i" direction="in" name="width"/>
|
|
||||||
<arg type="i" direction="in" name="height"/>
|
|
||||||
<arg type="b" direction="in" name="flash"/>
|
|
||||||
<arg type="s" direction="in" name="filename"/>
|
|
||||||
<arg type="b" direction="out" name="success"/>
|
|
||||||
</method>
|
|
||||||
<method name="ScreenshotWindow">
|
|
||||||
<arg type="b" direction="in" name="include_frame"/>
|
|
||||||
<arg type="b" direction="in" name="include_cursor"/>
|
|
||||||
<arg type="b" direction="in" name="flash"/>
|
|
||||||
<arg type="s" direction="in" name="filename"/>
|
|
||||||
<arg type="b" direction="out" name="success"/>
|
|
||||||
</method>
|
|
||||||
<method name="Screenshot">
|
|
||||||
<arg type="b" direction="in" name="include_cursor"/>
|
|
||||||
<arg type="b" direction="in" name="flash"/>
|
|
||||||
<arg type="s" direction="in" name="filename"/>
|
|
||||||
<arg type="b" direction="out" name="success"/>
|
|
||||||
</method>
|
|
||||||
<method name="FlashArea">
|
|
||||||
<arg type="i" direction="in" name="x"/>
|
|
||||||
<arg type="i" direction="in" name="y"/>
|
|
||||||
<arg type="i" direction="in" name="width"/>
|
|
||||||
<arg type="i" direction="in" name="height"/>
|
|
||||||
</method>
|
|
||||||
<property name="Mode" type="s" access="read" />
|
<property name="Mode" type="s" access="read" />
|
||||||
<property name="OverviewActive" type="b" access="readwrite" />
|
<property name="OverviewActive" type="b" access="readwrite" />
|
||||||
<property name="ShellVersion" type="s" access="read" />
|
<property name="ShellVersion" type="s" access="read" />
|
||||||
@ -76,6 +48,7 @@ const GnomeShell = new Lang.Class({
|
|||||||
this._dbusImpl.export(Gio.DBus.session, '/org/gnome/Shell');
|
this._dbusImpl.export(Gio.DBus.session, '/org/gnome/Shell');
|
||||||
|
|
||||||
this._extensionsSerivce = new GnomeShellExtensions();
|
this._extensionsSerivce = new GnomeShellExtensions();
|
||||||
|
this._screenshotService = new Screenshot.ScreenshotService();
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -111,82 +84,6 @@ const GnomeShell = new Lang.Class({
|
|||||||
return [success, returnValue];
|
return [success, returnValue];
|
||||||
},
|
},
|
||||||
|
|
||||||
_onScreenshotComplete: function(obj, result, area, flash, invocation) {
|
|
||||||
if (flash && result) {
|
|
||||||
let flashspot = new Flashspot.Flashspot(area);
|
|
||||||
flashspot.fire();
|
|
||||||
}
|
|
||||||
|
|
||||||
let retval = GLib.Variant.new('(b)', [result]);
|
|
||||||
invocation.return_value(retval);
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ScreenshotArea:
|
|
||||||
* @x: The X coordinate of the area
|
|
||||||
* @y: The Y coordinate of the area
|
|
||||||
* @width: The width of the area
|
|
||||||
* @height: The height of the area
|
|
||||||
* @flash: Whether to flash the area or not
|
|
||||||
* @filename: The filename for the screenshot
|
|
||||||
*
|
|
||||||
* Takes a screenshot of the passed in area and saves it
|
|
||||||
* in @filename as png image, it returns a boolean
|
|
||||||
* indicating whether the operation was successful or not.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
ScreenshotAreaAsync : function (params, invocation) {
|
|
||||||
let [x, y, width, height, flash, filename, callback] = params;
|
|
||||||
let screenshot = new Shell.Screenshot();
|
|
||||||
screenshot.screenshot_area (x, y, width, height, filename,
|
|
||||||
Lang.bind(this, this._onScreenshotComplete,
|
|
||||||
flash, invocation));
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ScreenshotWindow:
|
|
||||||
* @include_frame: Whether to include the frame or not
|
|
||||||
* @include_cursor: Whether to include the cursor image or not
|
|
||||||
* @flash: Whether to flash the window area or not
|
|
||||||
* @filename: The filename for the screenshot
|
|
||||||
*
|
|
||||||
* Takes a screenshot of the focused window (optionally omitting the frame)
|
|
||||||
* and saves it in @filename as png image, it returns a boolean
|
|
||||||
* indicating whether the operation was successful or not.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
ScreenshotWindowAsync : function (params, invocation) {
|
|
||||||
let [include_frame, include_cursor, flash, filename] = params;
|
|
||||||
let screenshot = new Shell.Screenshot();
|
|
||||||
screenshot.screenshot_window (include_frame, include_cursor, filename,
|
|
||||||
Lang.bind(this, this._onScreenshotComplete,
|
|
||||||
flash, invocation));
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Screenshot:
|
|
||||||
* @filename: The filename for the screenshot
|
|
||||||
* @include_cursor: Whether to include the cursor image or not
|
|
||||||
* @flash: Whether to flash the screen or not
|
|
||||||
*
|
|
||||||
* Takes a screenshot of the whole screen and saves it
|
|
||||||
* in @filename as png image, it returns a boolean
|
|
||||||
* indicating whether the operation was successful or not.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
ScreenshotAsync : function (params, invocation) {
|
|
||||||
let [include_cursor, flash, filename] = params;
|
|
||||||
let screenshot = new Shell.Screenshot();
|
|
||||||
screenshot.screenshot(include_cursor, filename,
|
|
||||||
Lang.bind(this, this._onScreenshotComplete,
|
|
||||||
flash, invocation));
|
|
||||||
},
|
|
||||||
|
|
||||||
FlashArea: function(x, y, width, height) {
|
|
||||||
let flashspot = new Flashspot.Flashspot({ x : x, y : y, width: width, height: height});
|
|
||||||
flashspot.fire();
|
|
||||||
},
|
|
||||||
|
|
||||||
Mode: global.session_mode,
|
Mode: global.session_mode,
|
||||||
|
|
||||||
get OverviewActive() {
|
get OverviewActive() {
|
||||||
|
@ -80,7 +80,7 @@ const Indicator = new Lang.Class({
|
|||||||
this._applet.connect('notify::show-full-menu', Lang.bind(this, this._updateFullMenu));
|
this._applet.connect('notify::show-full-menu', Lang.bind(this, this._updateFullMenu));
|
||||||
this._updateFullMenu();
|
this._updateFullMenu();
|
||||||
|
|
||||||
this.menu.addSettingsAction(_("Bluetooth Settings"), 'bluetooth-properties.desktop');
|
this.menu.addSettingsAction(_("Bluetooth Settings"), 'gnome-bluetooth-panel.desktop');
|
||||||
|
|
||||||
this._applet.connect('pincode-request', Lang.bind(this, this._pinRequest));
|
this._applet.connect('pincode-request', Lang.bind(this, this._pinRequest));
|
||||||
this._applet.connect('confirm-request', Lang.bind(this, this._confirmRequest));
|
this._applet.connect('confirm-request', Lang.bind(this, this._confirmRequest));
|
||||||
@ -446,10 +446,5 @@ const PinNotification = new Lang.Class({
|
|||||||
return this._entry.clutter_text.text.length == 6;
|
return this._entry.clutter_text.text.length == 6;
|
||||||
else
|
else
|
||||||
return true;
|
return true;
|
||||||
},
|
|
||||||
|
|
||||||
grabFocus: function(lockTray) {
|
|
||||||
this.parent(lockTray);
|
|
||||||
global.stage.set_key_focus(this._entry);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
|
const Clutter = imports.gi.Clutter;
|
||||||
const Gio = imports.gi.Gio;
|
const Gio = imports.gi.Gio;
|
||||||
const GLib = imports.gi.GLib;
|
const GLib = imports.gi.GLib;
|
||||||
const GnomeDesktop = imports.gi.GnomeDesktop;
|
const GnomeDesktop = imports.gi.GnomeDesktop;
|
||||||
const Lang = imports.lang;
|
const Lang = imports.lang;
|
||||||
|
const Meta = imports.gi.Meta;
|
||||||
const Shell = imports.gi.Shell;
|
const Shell = imports.gi.Shell;
|
||||||
const Signals = imports.signals;
|
const Signals = imports.signals;
|
||||||
const St = imports.gi.St;
|
const St = imports.gi.St;
|
||||||
@ -21,6 +23,7 @@ try {
|
|||||||
const Main = imports.ui.main;
|
const Main = imports.ui.main;
|
||||||
const PopupMenu = imports.ui.popupMenu;
|
const PopupMenu = imports.ui.popupMenu;
|
||||||
const PanelMenu = imports.ui.panelMenu;
|
const PanelMenu = imports.ui.panelMenu;
|
||||||
|
const SwitcherPopup = imports.ui.switcherPopup;
|
||||||
const Util = imports.misc.util;
|
const Util = imports.misc.util;
|
||||||
|
|
||||||
const DESKTOP_INPUT_SOURCES_SCHEMA = 'org.gnome.desktop.input-sources';
|
const DESKTOP_INPUT_SOURCES_SCHEMA = 'org.gnome.desktop.input-sources';
|
||||||
@ -47,6 +50,7 @@ const IBusManager = new Lang.Class({
|
|||||||
this._engines = {};
|
this._engines = {};
|
||||||
this._ready = false;
|
this._ready = false;
|
||||||
this._registerPropertiesId = 0;
|
this._registerPropertiesId = 0;
|
||||||
|
this._currentEngineName = null;
|
||||||
|
|
||||||
this._nameWatcherId = Gio.DBus.session.watch_name(IBus.SERVICE_IBUS,
|
this._nameWatcherId = Gio.DBus.session.watch_name(IBus.SERVICE_IBUS,
|
||||||
Gio.BusNameWatcherFlags.NONE,
|
Gio.BusNameWatcherFlags.NONE,
|
||||||
@ -66,6 +70,10 @@ const IBusManager = new Lang.Class({
|
|||||||
this._engines = {};
|
this._engines = {};
|
||||||
this._ready = false;
|
this._ready = false;
|
||||||
this._registerPropertiesId = 0;
|
this._registerPropertiesId = 0;
|
||||||
|
this._currentEngineName = null;
|
||||||
|
|
||||||
|
if (this._readyCallback)
|
||||||
|
this._readyCallback(false);
|
||||||
},
|
},
|
||||||
|
|
||||||
_onNameAppeared: function() {
|
_onNameAppeared: function() {
|
||||||
@ -89,12 +97,10 @@ const IBusManager = new Lang.Class({
|
|||||||
let name = enginesList[i].get_name();
|
let name = enginesList[i].get_name();
|
||||||
this._engines[name] = enginesList[i];
|
this._engines[name] = enginesList[i];
|
||||||
}
|
}
|
||||||
|
this._updateReadiness();
|
||||||
} else {
|
} else {
|
||||||
this._clear();
|
this._clear();
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this._updateReadiness();
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_initPanelService: function(ibus, result) {
|
_initPanelService: function(ibus, result) {
|
||||||
@ -105,27 +111,31 @@ const IBusManager = new Lang.Class({
|
|||||||
this._candidatePopup.setPanelService(this._panelService);
|
this._candidatePopup.setPanelService(this._panelService);
|
||||||
// Need to set this to get 'global-engine-changed' emitions
|
// Need to set this to get 'global-engine-changed' emitions
|
||||||
this._ibus.set_watch_ibus_signal(true);
|
this._ibus.set_watch_ibus_signal(true);
|
||||||
this._ibus.connect('global-engine-changed', Lang.bind(this, this._resetProperties));
|
this._ibus.connect('global-engine-changed', Lang.bind(this, this._engineChanged));
|
||||||
this._panelService.connect('update-property', Lang.bind(this, this._updateProperty));
|
this._panelService.connect('update-property', Lang.bind(this, this._updateProperty));
|
||||||
this._resetProperties();
|
// If an engine is already active we need to get its properties
|
||||||
|
this._ibus.get_global_engine_async(-1, null, Lang.bind(this, function(i, result) {
|
||||||
|
let engine = this._ibus.get_global_engine_async_finish(result);
|
||||||
|
if (!engine)
|
||||||
|
return;
|
||||||
|
this._engineChanged(this._ibus, engine.get_name());
|
||||||
|
}));
|
||||||
|
this._updateReadiness();
|
||||||
} else {
|
} else {
|
||||||
this._clear();
|
this._clear();
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this._updateReadiness();
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_updateReadiness: function() {
|
_updateReadiness: function() {
|
||||||
this._ready = (Object.keys(this._engines).length > 0 &&
|
this._ready = (Object.keys(this._engines).length > 0 &&
|
||||||
this._panelService != null);
|
this._panelService != null);
|
||||||
|
|
||||||
if (this._ready && this._readyCallback)
|
if (this._readyCallback)
|
||||||
this._readyCallback();
|
this._readyCallback(this._ready);
|
||||||
},
|
},
|
||||||
|
|
||||||
_resetProperties: function() {
|
_engineChanged: function(bus, engineName) {
|
||||||
this.emit('properties-registered', null);
|
this._currentEngineName = engineName;
|
||||||
|
|
||||||
if (this._registerPropertiesId != 0)
|
if (this._registerPropertiesId != 0)
|
||||||
return;
|
return;
|
||||||
@ -138,25 +148,18 @@ const IBusManager = new Lang.Class({
|
|||||||
this._panelService.disconnect(this._registerPropertiesId);
|
this._panelService.disconnect(this._registerPropertiesId);
|
||||||
this._registerPropertiesId = 0;
|
this._registerPropertiesId = 0;
|
||||||
|
|
||||||
this.emit('properties-registered', props);
|
this.emit('properties-registered', this._currentEngineName, props);
|
||||||
}));
|
}));
|
||||||
},
|
},
|
||||||
|
|
||||||
_updateProperty: function(panel, prop) {
|
_updateProperty: function(panel, prop) {
|
||||||
this.emit('property-updated', prop);
|
this.emit('property-updated', this._currentEngineName, prop);
|
||||||
},
|
},
|
||||||
|
|
||||||
activateProperty: function(key, state) {
|
activateProperty: function(key, state) {
|
||||||
this._panelService.property_activate(key, state);
|
this._panelService.property_activate(key, state);
|
||||||
},
|
},
|
||||||
|
|
||||||
hasProperties: function(id) {
|
|
||||||
if (id == 'anthy')
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
|
|
||||||
getEngineDesc: function(id) {
|
getEngineDesc: function(id) {
|
||||||
if (!IBus || !this._ready)
|
if (!IBus || !this._ready)
|
||||||
return null;
|
return null;
|
||||||
@ -181,16 +184,127 @@ const LayoutMenuItem = new Lang.Class({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const InputSource = new Lang.Class({
|
||||||
|
Name: 'InputSource',
|
||||||
|
|
||||||
|
_init: function(type, id, displayName, shortName, index) {
|
||||||
|
this.type = type;
|
||||||
|
this.id = id;
|
||||||
|
this.displayName = displayName;
|
||||||
|
this._shortName = shortName;
|
||||||
|
this.index = index;
|
||||||
|
|
||||||
|
this._menuItem = new LayoutMenuItem(this.displayName, this._shortName);
|
||||||
|
this._menuItem.connect('activate', Lang.bind(this, this.activate));
|
||||||
|
this._indicatorLabel = new St.Label({ text: this._shortName });
|
||||||
|
|
||||||
|
this.properties = null;
|
||||||
|
},
|
||||||
|
|
||||||
|
destroy: function() {
|
||||||
|
this._menuItem.destroy();
|
||||||
|
this._indicatorLabel.destroy();
|
||||||
|
},
|
||||||
|
|
||||||
|
get shortName() {
|
||||||
|
return this._shortName;
|
||||||
|
},
|
||||||
|
|
||||||
|
set shortName(v) {
|
||||||
|
this._shortName = v;
|
||||||
|
this._menuItem.indicator.set_text(v);
|
||||||
|
this._indicatorLabel.set_text(v);
|
||||||
|
},
|
||||||
|
|
||||||
|
get menuItem() {
|
||||||
|
return this._menuItem;
|
||||||
|
},
|
||||||
|
|
||||||
|
get indicatorLabel() {
|
||||||
|
return this._indicatorLabel;
|
||||||
|
},
|
||||||
|
|
||||||
|
activate: function() {
|
||||||
|
this.emit('activate');
|
||||||
|
},
|
||||||
|
});
|
||||||
|
Signals.addSignalMethods(InputSource.prototype);
|
||||||
|
|
||||||
|
const InputSourcePopup = new Lang.Class({
|
||||||
|
Name: 'InputSourcePopup',
|
||||||
|
Extends: SwitcherPopup.SwitcherPopup,
|
||||||
|
|
||||||
|
_init: function(items, action, actionBackward) {
|
||||||
|
this.parent(items);
|
||||||
|
|
||||||
|
this._action = action;
|
||||||
|
this._actionBackward = actionBackward;
|
||||||
|
},
|
||||||
|
|
||||||
|
_createSwitcher: function() {
|
||||||
|
this._switcherList = new InputSourceSwitcher(this._items);
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
|
||||||
|
_initialSelection: function(backward, binding) {
|
||||||
|
if (binding == 'switch-input-source') {
|
||||||
|
if (backward)
|
||||||
|
this._selectedIndex = this._items.length - 1;
|
||||||
|
} else if (binding == 'switch-input-source-backward') {
|
||||||
|
if (!backward)
|
||||||
|
this._selectedIndex = this._items.length - 1;
|
||||||
|
}
|
||||||
|
this._select(this._selectedIndex);
|
||||||
|
},
|
||||||
|
|
||||||
|
_keyPressHandler: function(keysym, backwards, action) {
|
||||||
|
if (action == this._action)
|
||||||
|
this._select(backwards ? this._previous() : this._next());
|
||||||
|
else if (action == this._actionBackward)
|
||||||
|
this._select(backwards ? this._next() : this._previous());
|
||||||
|
else if (keysym == Clutter.Left)
|
||||||
|
this._select(this._previous());
|
||||||
|
else if (keysym == Clutter.Right)
|
||||||
|
this._select(this._next());
|
||||||
|
},
|
||||||
|
|
||||||
|
_finish : function() {
|
||||||
|
this.parent();
|
||||||
|
|
||||||
|
this._items[this._selectedIndex].activate();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const InputSourceSwitcher = new Lang.Class({
|
||||||
|
Name: 'InputSourceSwitcher',
|
||||||
|
Extends: SwitcherPopup.SwitcherList,
|
||||||
|
|
||||||
|
_init: function(items) {
|
||||||
|
this.parent(true);
|
||||||
|
|
||||||
|
for (let i = 0; i < items.length; i++)
|
||||||
|
this._addIcon(items[i]);
|
||||||
|
},
|
||||||
|
|
||||||
|
_addIcon: function(item) {
|
||||||
|
let box = new St.BoxLayout({ vertical: true });
|
||||||
|
|
||||||
|
let bin = new St.Bin({ style_class: 'input-source-switcher-symbol' });
|
||||||
|
let symbol = new St.Label({ text: item.shortName });
|
||||||
|
bin.set_child(symbol);
|
||||||
|
box.add(bin, { x_fill: false, y_fill: false } );
|
||||||
|
|
||||||
|
let text = new St.Label({ text: item.displayName });
|
||||||
|
box.add(text, { x_fill: false });
|
||||||
|
|
||||||
|
this.addItem(box, text);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
const InputSourceIndicator = new Lang.Class({
|
const InputSourceIndicator = new Lang.Class({
|
||||||
Name: 'InputSourceIndicator',
|
Name: 'InputSourceIndicator',
|
||||||
Extends: PanelMenu.Button,
|
Extends: PanelMenu.Button,
|
||||||
|
|
||||||
_propertiesWhitelist: [
|
|
||||||
'InputMode',
|
|
||||||
'TypingMode',
|
|
||||||
'DictMode'
|
|
||||||
],
|
|
||||||
|
|
||||||
_init: function() {
|
_init: function() {
|
||||||
this.parent(0.0, _("Keyboard"));
|
this.parent(0.0, _("Keyboard"));
|
||||||
|
|
||||||
@ -201,14 +315,36 @@ const InputSourceIndicator = new Lang.Class({
|
|||||||
this.actor.add_actor(this._container);
|
this.actor.add_actor(this._container);
|
||||||
this.actor.add_style_class_name('panel-status-button');
|
this.actor.add_style_class_name('panel-status-button');
|
||||||
|
|
||||||
this._labelActors = {};
|
// All valid input sources currently in the gsettings
|
||||||
this._layoutItems = {};
|
// KEY_INPUT_SOURCES list indexed by their index there
|
||||||
|
this._inputSources = {};
|
||||||
|
// All valid input sources currently in the gsettings
|
||||||
|
// KEY_INPUT_SOURCES list of type INPUT_SOURCE_TYPE_IBUS
|
||||||
|
// indexed by the IBus ID
|
||||||
|
this._ibusSources = {};
|
||||||
|
|
||||||
|
this._currentSource = null;
|
||||||
|
|
||||||
|
// All valid input sources currently in the gsettings
|
||||||
|
// KEY_INPUT_SOURCES list ordered by most recently used
|
||||||
|
this._mruSources = [];
|
||||||
|
this._keybindingAction =
|
||||||
|
Main.wm.addKeybinding('switch-input-source',
|
||||||
|
new Gio.Settings({ schema: "org.gnome.desktop.wm.keybindings" }),
|
||||||
|
Meta.KeyBindingFlags.REVERSES,
|
||||||
|
Main.KeybindingMode.ALL,
|
||||||
|
Lang.bind(this, this._switchInputSource));
|
||||||
|
this._keybindingActionBackward =
|
||||||
|
Main.wm.addKeybinding('switch-input-source-backward',
|
||||||
|
new Gio.Settings({ schema: "org.gnome.desktop.wm.keybindings" }),
|
||||||
|
Meta.KeyBindingFlags.REVERSES |
|
||||||
|
Meta.KeyBindingFlags.REVERSED,
|
||||||
|
Main.KeybindingMode.ALL,
|
||||||
|
Lang.bind(this, this._switchInputSource));
|
||||||
this._settings = new Gio.Settings({ schema: DESKTOP_INPUT_SOURCES_SCHEMA });
|
this._settings = new Gio.Settings({ schema: DESKTOP_INPUT_SOURCES_SCHEMA });
|
||||||
this._settings.connect('changed::' + KEY_CURRENT_INPUT_SOURCE, Lang.bind(this, this._currentInputSourceChanged));
|
this._settings.connect('changed::' + KEY_CURRENT_INPUT_SOURCE, Lang.bind(this, this._currentInputSourceChanged));
|
||||||
this._settings.connect('changed::' + KEY_INPUT_SOURCES, Lang.bind(this, this._inputSourcesChanged));
|
this._settings.connect('changed::' + KEY_INPUT_SOURCES, Lang.bind(this, this._inputSourcesChanged));
|
||||||
|
|
||||||
this._currentSourceIndex = this._settings.get_uint(KEY_CURRENT_INPUT_SOURCE);
|
|
||||||
this._xkbInfo = new GnomeDesktop.XkbInfo();
|
this._xkbInfo = new GnomeDesktop.XkbInfo();
|
||||||
|
|
||||||
this._propSeparator = new PopupMenu.PopupSeparatorMenuItem();
|
this._propSeparator = new PopupMenu.PopupSeparatorMenuItem();
|
||||||
@ -217,9 +353,8 @@ const InputSourceIndicator = new Lang.Class({
|
|||||||
this.menu.addMenuItem(this._propSection);
|
this.menu.addMenuItem(this._propSection);
|
||||||
this._propSection.actor.hide();
|
this._propSection.actor.hide();
|
||||||
|
|
||||||
this._properties = null;
|
this._ibusReady = false;
|
||||||
|
this._ibusManager = new IBusManager(Lang.bind(this, this._ibusReadyCallback));
|
||||||
this._ibusManager = new IBusManager(Lang.bind(this, this._inputSourcesChanged));
|
|
||||||
this._ibusManager.connect('properties-registered', Lang.bind(this, this._ibusPropertiesRegistered));
|
this._ibusManager.connect('properties-registered', Lang.bind(this, this._ibusPropertiesRegistered));
|
||||||
this._ibusManager.connect('property-updated', Lang.bind(this, this._ibusPropertyUpdated));
|
this._ibusManager.connect('property-updated', Lang.bind(this, this._ibusPropertyUpdated));
|
||||||
this._inputSourcesChanged();
|
this._inputSourcesChanged();
|
||||||
@ -231,6 +366,13 @@ const InputSourceIndicator = new Lang.Class({
|
|||||||
this._sessionUpdated();
|
this._sessionUpdated();
|
||||||
|
|
||||||
this.menu.addSettingsAction(_("Region and Language Settings"), 'gnome-region-panel.desktop');
|
this.menu.addSettingsAction(_("Region and Language Settings"), 'gnome-region-panel.desktop');
|
||||||
|
|
||||||
|
this._sourcesPerWindow = false;
|
||||||
|
this._focusWindowNotifyId = 0;
|
||||||
|
this._overviewShowingId = 0;
|
||||||
|
this._overviewHiddenId = 0;
|
||||||
|
this._settings.connect('changed::per-window', Lang.bind(this, this._sourcesPerWindowChanged));
|
||||||
|
this._sourcesPerWindowChanged();
|
||||||
},
|
},
|
||||||
|
|
||||||
_sessionUpdated: function() {
|
_sessionUpdated: function() {
|
||||||
@ -241,18 +383,29 @@ const InputSourceIndicator = new Lang.Class({
|
|||||||
this._showLayoutItem.actor.visible = Main.sessionMode.allowSettings;
|
this._showLayoutItem.actor.visible = Main.sessionMode.allowSettings;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_ibusReadyCallback: function(ready) {
|
||||||
|
if (this._ibusReady == ready)
|
||||||
|
return;
|
||||||
|
|
||||||
|
this._ibusReady = ready;
|
||||||
|
this._mruSources = [];
|
||||||
|
this._inputSourcesChanged();
|
||||||
|
},
|
||||||
|
|
||||||
|
_switchInputSource: function(display, screen, window, binding) {
|
||||||
|
let popup = new InputSourcePopup(this._mruSources, this._keybindingAction, this._keybindingActionBackward);
|
||||||
|
let modifiers = binding.get_modifiers();
|
||||||
|
let backwards = modifiers & Meta.VirtualModifier.SHIFT_MASK;
|
||||||
|
if (!popup.show(backwards, binding.get_name(), binding.get_mask()))
|
||||||
|
popup.destroy();
|
||||||
|
},
|
||||||
|
|
||||||
_currentInputSourceChanged: function() {
|
_currentInputSourceChanged: function() {
|
||||||
let nVisibleSources = Object.keys(this._layoutItems).length;
|
let nVisibleSources = Object.keys(this._inputSources).length;
|
||||||
let newCurrentSourceIndex = this._settings.get_uint(KEY_CURRENT_INPUT_SOURCE);
|
let newSourceIndex = this._settings.get_uint(KEY_CURRENT_INPUT_SOURCE);
|
||||||
let newLayoutItem = this._layoutItems[newCurrentSourceIndex];
|
let newSource = this._inputSources[newSourceIndex];
|
||||||
let hasProperties;
|
|
||||||
|
|
||||||
if (newLayoutItem)
|
if (!newSource || (nVisibleSources < 2 && !newSource.properties)) {
|
||||||
hasProperties = this._ibusManager.hasProperties(newLayoutItem.ibusEngineId);
|
|
||||||
else
|
|
||||||
hasProperties = false;
|
|
||||||
|
|
||||||
if (!newLayoutItem || (nVisibleSources < 2 && !hasProperties)) {
|
|
||||||
// This source index might be invalid if we weren't able
|
// This source index might be invalid if we weren't able
|
||||||
// to build a menu item for it, so we hide ourselves since
|
// to build a menu item for it, so we hide ourselves since
|
||||||
// we can't fix it here. *shrug*
|
// we can't fix it here. *shrug*
|
||||||
@ -266,106 +419,125 @@ const InputSourceIndicator = new Lang.Class({
|
|||||||
|
|
||||||
this.actor.show();
|
this.actor.show();
|
||||||
|
|
||||||
if (this._layoutItems[this._currentSourceIndex]) {
|
let oldSource;
|
||||||
this._layoutItems[this._currentSourceIndex].setShowDot(false);
|
[oldSource, this._currentSource] = [this._currentSource, newSource];
|
||||||
this._container.set_skip_paint(this._labelActors[this._currentSourceIndex], true);
|
|
||||||
|
if (oldSource) {
|
||||||
|
oldSource.menuItem.setShowDot(false);
|
||||||
|
this._container.set_skip_paint(oldSource.indicatorLabel, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
newLayoutItem.setShowDot(true);
|
newSource.menuItem.setShowDot(true);
|
||||||
|
this._container.set_skip_paint(newSource.indicatorLabel, false);
|
||||||
|
|
||||||
let newLabelActor = this._labelActors[newCurrentSourceIndex];
|
this._buildPropSection(newSource.properties);
|
||||||
this._container.set_skip_paint(newLabelActor, false);
|
|
||||||
|
|
||||||
if (hasProperties)
|
for (let i = 1; i < this._mruSources.length; ++i)
|
||||||
newLabelActor.set_text(newLayoutItem.indicator.get_text());
|
if (this._mruSources[i] == newSource) {
|
||||||
|
let currentSource = this._mruSources.splice(i, 1);
|
||||||
|
this._mruSources = currentSource.concat(this._mruSources);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
this._currentSourceIndex = newCurrentSourceIndex;
|
this._changePerWindowSource();
|
||||||
},
|
},
|
||||||
|
|
||||||
_inputSourcesChanged: function() {
|
_inputSourcesChanged: function() {
|
||||||
let sources = this._settings.get_value(KEY_INPUT_SOURCES);
|
let sources = this._settings.get_value(KEY_INPUT_SOURCES);
|
||||||
let nSources = sources.n_children();
|
let nSources = sources.n_children();
|
||||||
|
|
||||||
for (let i in this._layoutItems)
|
for (let i in this._inputSources)
|
||||||
this._layoutItems[i].destroy();
|
this._inputSources[i].destroy();
|
||||||
|
|
||||||
for (let i in this._labelActors)
|
this._inputSources = {};
|
||||||
this._labelActors[i].destroy();
|
this._ibusSources = {};
|
||||||
|
|
||||||
this._layoutItems = {};
|
let inputSourcesByShortName = {};
|
||||||
this._labelActors = {};
|
|
||||||
|
|
||||||
let infos = [];
|
|
||||||
let infosByShortName = {};
|
|
||||||
|
|
||||||
for (let i = 0; i < nSources; i++) {
|
for (let i = 0; i < nSources; i++) {
|
||||||
let info = { exists: false };
|
let displayName;
|
||||||
|
let shortName;
|
||||||
let [type, id] = sources.get_child_value(i).deep_unpack();
|
let [type, id] = sources.get_child_value(i).deep_unpack();
|
||||||
|
let exists = false;
|
||||||
|
|
||||||
if (type == INPUT_SOURCE_TYPE_XKB) {
|
if (type == INPUT_SOURCE_TYPE_XKB) {
|
||||||
[info.exists, info.displayName, info.shortName, , ] =
|
[exists, displayName, shortName, , ] =
|
||||||
this._xkbInfo.get_layout_info(id);
|
this._xkbInfo.get_layout_info(id);
|
||||||
} else if (type == INPUT_SOURCE_TYPE_IBUS) {
|
} else if (type == INPUT_SOURCE_TYPE_IBUS) {
|
||||||
let engineDesc = this._ibusManager.getEngineDesc(id);
|
let engineDesc = this._ibusManager.getEngineDesc(id);
|
||||||
if (engineDesc) {
|
if (engineDesc) {
|
||||||
let language = IBus.get_language_name(engineDesc.get_language());
|
let language = IBus.get_language_name(engineDesc.get_language());
|
||||||
|
exists = true;
|
||||||
info.exists = true;
|
displayName = language + ' (' + engineDesc.get_longname() + ')';
|
||||||
info.displayName = language + ' (' + engineDesc.get_longname() + ')';
|
shortName = this._makeEngineShortName(engineDesc);
|
||||||
info.shortName = this._makeEngineShortName(engineDesc);
|
|
||||||
info.ibusEngineId = id;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!info.exists)
|
if (!exists)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
info.sourceIndex = i;
|
let is = new InputSource(type, id, displayName, shortName, i);
|
||||||
|
|
||||||
if (!(info.shortName in infosByShortName))
|
is.connect('activate', Lang.bind(this, function() {
|
||||||
infosByShortName[info.shortName] = [];
|
if (this._currentSource.index == is.index)
|
||||||
infosByShortName[info.shortName].push(info);
|
return;
|
||||||
infos.push(info);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (let i = 0; i < infos.length; i++) {
|
|
||||||
let info = infos[i];
|
|
||||||
if (infosByShortName[info.shortName].length > 1) {
|
|
||||||
let sub = infosByShortName[info.shortName].indexOf(info) + 1;
|
|
||||||
info.shortName += String.fromCharCode(0x2080 + sub);
|
|
||||||
}
|
|
||||||
|
|
||||||
let item = new LayoutMenuItem(info.displayName, info.shortName);
|
|
||||||
item.ibusEngineId = info.ibusEngineId;
|
|
||||||
this._layoutItems[info.sourceIndex] = item;
|
|
||||||
this.menu.addMenuItem(item, i);
|
|
||||||
item.connect('activate', Lang.bind(this, function() {
|
|
||||||
this._settings.set_value(KEY_CURRENT_INPUT_SOURCE,
|
this._settings.set_value(KEY_CURRENT_INPUT_SOURCE,
|
||||||
GLib.Variant.new_uint32(info.sourceIndex));
|
GLib.Variant.new_uint32(is.index));
|
||||||
}));
|
}));
|
||||||
|
|
||||||
let shortLabel = new St.Label({ text: info.shortName });
|
if (!(is.shortName in inputSourcesByShortName))
|
||||||
this._labelActors[info.sourceIndex] = shortLabel;
|
inputSourcesByShortName[is.shortName] = [];
|
||||||
this._container.add_actor(shortLabel);
|
inputSourcesByShortName[is.shortName].push(is);
|
||||||
this._container.set_skip_paint(shortLabel, true);
|
|
||||||
|
this._inputSources[is.index] = is;
|
||||||
|
|
||||||
|
if (is.type == INPUT_SOURCE_TYPE_IBUS)
|
||||||
|
this._ibusSources[is.id] = is;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let menuIndex = 0;
|
||||||
|
for (let i in this._inputSources) {
|
||||||
|
let is = this._inputSources[i];
|
||||||
|
if (inputSourcesByShortName[is.shortName].length > 1) {
|
||||||
|
let sub = inputSourcesByShortName[is.shortName].indexOf(is) + 1;
|
||||||
|
is.shortName += String.fromCharCode(0x2080 + sub);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.menu.addMenuItem(is.menuItem, menuIndex++);
|
||||||
|
|
||||||
|
this._container.add_actor(is.indicatorLabel);
|
||||||
|
this._container.set_skip_paint(is.indicatorLabel, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
let sourcesList = [];
|
||||||
|
for (let i in this._inputSources)
|
||||||
|
sourcesList.push(this._inputSources[i]);
|
||||||
|
|
||||||
|
let mruSources = [];
|
||||||
|
for (let i = 0; i < this._mruSources.length; i++) {
|
||||||
|
for (let j = 0; j < sourcesList.length; j++)
|
||||||
|
if (this._mruSources[i].type == sourcesList[j].type &&
|
||||||
|
this._mruSources[i].id == sourcesList[j].id) {
|
||||||
|
mruSources = mruSources.concat(sourcesList.splice(j, 1));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this._mruSources = mruSources.concat(sourcesList);
|
||||||
|
|
||||||
this._currentInputSourceChanged();
|
this._currentInputSourceChanged();
|
||||||
},
|
},
|
||||||
|
|
||||||
_showLayout: function() {
|
_showLayout: function() {
|
||||||
Main.overview.hide();
|
Main.overview.hide();
|
||||||
|
|
||||||
let sources = this._settings.get_value(KEY_INPUT_SOURCES);
|
let source = this._currentSource;
|
||||||
let current = this._settings.get_uint(KEY_CURRENT_INPUT_SOURCE);
|
|
||||||
let [type, id] = sources.get_child_value(current).deep_unpack();
|
|
||||||
let xkbLayout = '';
|
let xkbLayout = '';
|
||||||
let xkbVariant = '';
|
let xkbVariant = '';
|
||||||
|
|
||||||
if (type == INPUT_SOURCE_TYPE_XKB) {
|
if (source.type == INPUT_SOURCE_TYPE_XKB) {
|
||||||
[, , , xkbLayout, xkbVariant] = this._xkbInfo.get_layout_info(id);
|
[, , , xkbLayout, xkbVariant] = this._xkbInfo.get_layout_info(source.id);
|
||||||
} else if (type == INPUT_SOURCE_TYPE_IBUS) {
|
} else if (source.type == INPUT_SOURCE_TYPE_IBUS) {
|
||||||
let engineDesc = this._ibusManager.getEngineDesc(id);
|
let engineDesc = this._ibusManager.getEngineDesc(source.id);
|
||||||
if (engineDesc) {
|
if (engineDesc) {
|
||||||
xkbLayout = engineDesc.get_layout();
|
xkbLayout = engineDesc.get_layout();
|
||||||
xkbVariant = '';
|
xkbVariant = '';
|
||||||
@ -394,26 +566,25 @@ const InputSourceIndicator = new Lang.Class({
|
|||||||
return String.fromCharCode(0x2328); // keyboard glyph
|
return String.fromCharCode(0x2328); // keyboard glyph
|
||||||
},
|
},
|
||||||
|
|
||||||
_propertyWhitelisted: function(prop) {
|
_ibusPropertiesRegistered: function(im, engineName, props) {
|
||||||
for (let i = 0; i < this._propertiesWhitelist.length; ++i) {
|
let source = this._ibusSources[engineName];
|
||||||
let key = prop.get_key();
|
if (!source)
|
||||||
if (key.substr(0, this._propertiesWhitelist[i].length) == this._propertiesWhitelist[i])
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
|
|
||||||
_ibusPropertiesRegistered: function(im, props) {
|
|
||||||
this._properties = props;
|
|
||||||
this._buildPropSection();
|
|
||||||
},
|
|
||||||
|
|
||||||
_ibusPropertyUpdated: function(im, prop) {
|
|
||||||
if (!this._propertyWhitelisted(prop))
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (this._updateSubProperty(this._properties, prop))
|
source.properties = props;
|
||||||
this._buildPropSection();
|
|
||||||
|
if (source == this._currentSource)
|
||||||
|
this._currentInputSourceChanged();
|
||||||
|
},
|
||||||
|
|
||||||
|
_ibusPropertyUpdated: function(im, engineName, prop) {
|
||||||
|
let source = this._ibusSources[engineName];
|
||||||
|
if (!source)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (this._updateSubProperty(source.properties, prop) &&
|
||||||
|
source == this._currentSource)
|
||||||
|
this._currentInputSourceChanged();
|
||||||
},
|
},
|
||||||
|
|
||||||
_updateSubProperty: function(props, prop) {
|
_updateSubProperty: function(props, prop) {
|
||||||
@ -433,25 +604,12 @@ const InputSourceIndicator = new Lang.Class({
|
|||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
|
|
||||||
_updateIndicatorLabel: function(text) {
|
_buildPropSection: function(properties) {
|
||||||
let layoutItem = this._layoutItems[this._currentSourceIndex];
|
|
||||||
let hasProperties;
|
|
||||||
|
|
||||||
if (layoutItem)
|
|
||||||
hasProperties = this._ibusManager.hasProperties(layoutItem.ibusEngineId);
|
|
||||||
else
|
|
||||||
hasProperties = false;
|
|
||||||
|
|
||||||
if (hasProperties)
|
|
||||||
this._labelActors[this._currentSourceIndex].set_text(text);
|
|
||||||
},
|
|
||||||
|
|
||||||
_buildPropSection: function() {
|
|
||||||
this._propSeparator.actor.hide();
|
this._propSeparator.actor.hide();
|
||||||
this._propSection.actor.hide();
|
this._propSection.actor.hide();
|
||||||
this._propSection.removeAll();
|
this._propSection.removeAll();
|
||||||
|
|
||||||
this._buildPropSubMenu(this._propSection, this._properties);
|
this._buildPropSubMenu(this._propSection, properties);
|
||||||
|
|
||||||
if (!this._propSection.isEmpty()) {
|
if (!this._propSection.isEmpty()) {
|
||||||
this._propSection.actor.show();
|
this._propSection.actor.show();
|
||||||
@ -468,8 +626,7 @@ const InputSourceIndicator = new Lang.Class({
|
|||||||
for (let i = 0; (p = props.get(i)) != null; ++i) {
|
for (let i = 0; (p = props.get(i)) != null; ++i) {
|
||||||
let prop = p;
|
let prop = p;
|
||||||
|
|
||||||
if (!this._propertyWhitelisted(prop) ||
|
if (!prop.get_visible())
|
||||||
!prop.get_visible())
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (prop.get_key() == 'InputMode') {
|
if (prop.get_key() == 'InputMode') {
|
||||||
@ -480,15 +637,17 @@ const InputSourceIndicator = new Lang.Class({
|
|||||||
text = prop.get_label().get_text();
|
text = prop.get_label().get_text();
|
||||||
|
|
||||||
if (text && text.length > 0 && text.length < 3)
|
if (text && text.length > 0 && text.length < 3)
|
||||||
this._updateIndicatorLabel(text);
|
this._currentSource.indicatorLabel.set_text(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
let item;
|
let item;
|
||||||
let type = prop.get_prop_type();
|
switch (prop.get_prop_type()) {
|
||||||
if (type == IBus.PropType.MENU) {
|
case IBus.PropType.MENU:
|
||||||
item = new PopupMenu.PopupSubMenuMenuItem(prop.get_label().get_text());
|
item = new PopupMenu.PopupSubMenuMenuItem(prop.get_label().get_text());
|
||||||
this._buildPropSubMenu(item.menu, prop.get_sub_props());
|
this._buildPropSubMenu(item.menu, prop.get_sub_props());
|
||||||
} else if (type == IBus.PropType.RADIO) {
|
break;
|
||||||
|
|
||||||
|
case IBus.PropType.RADIO:
|
||||||
item = new PopupMenu.PopupMenuItem(prop.get_label().get_text());
|
item = new PopupMenu.PopupMenuItem(prop.get_label().get_text());
|
||||||
item.prop = prop;
|
item.prop = prop;
|
||||||
radioGroup.push(item);
|
radioGroup.push(item);
|
||||||
@ -513,7 +672,39 @@ const InputSourceIndicator = new Lang.Class({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
} else {
|
break;
|
||||||
|
|
||||||
|
case IBus.PropType.TOGGLE:
|
||||||
|
item = new PopupMenu.PopupSwitchMenuItem(prop.get_label().get_text(), prop.get_state() == IBus.PropState.CHECKED);
|
||||||
|
item.prop = prop;
|
||||||
|
item.connect('toggled', Lang.bind(this, function() {
|
||||||
|
if (item.state) {
|
||||||
|
item.prop.set_state(IBus.PropState.CHECKED);
|
||||||
|
this._ibusManager.activateProperty(item.prop.get_key(),
|
||||||
|
IBus.PropState.CHECKED);
|
||||||
|
} else {
|
||||||
|
item.prop.set_state(IBus.PropState.UNCHECKED);
|
||||||
|
this._ibusManager.activateProperty(item.prop.get_key(),
|
||||||
|
IBus.PropState.UNCHECKED);
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IBus.PropType.NORMAL:
|
||||||
|
item = new PopupMenu.PopupMenuItem(prop.get_label().get_text());
|
||||||
|
item.prop = prop;
|
||||||
|
item.connect('activate', Lang.bind(this, function() {
|
||||||
|
this._ibusManager.activateProperty(item.prop.get_key(),
|
||||||
|
IBus.PropState.CHECKED);
|
||||||
|
}));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IBus.PropType.SEPARATOR:
|
||||||
|
item = new PopupMenu.PopupSeparatorMenuItem();
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
log ('IBus property %s has invalid type %d'.format(prop.get_key(), type));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -522,14 +713,91 @@ const InputSourceIndicator = new Lang.Class({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_getNewInputSource: function(current) {
|
||||||
|
for (let i in this._inputSources) {
|
||||||
|
let is = this._inputSources[i];
|
||||||
|
if (is.type == current.type &&
|
||||||
|
is.id == current.id)
|
||||||
|
return is;
|
||||||
|
}
|
||||||
|
return this._currentSource;
|
||||||
|
},
|
||||||
|
|
||||||
|
_getCurrentWindow: function() {
|
||||||
|
if (Main.overview.visible)
|
||||||
|
return Main.overview;
|
||||||
|
else
|
||||||
|
return global.display.focus_window;
|
||||||
|
},
|
||||||
|
|
||||||
|
_setPerWindowInputSource: function() {
|
||||||
|
let window = this._getCurrentWindow();
|
||||||
|
if (!window)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!window._inputSources) {
|
||||||
|
window._inputSources = this._inputSources;
|
||||||
|
window._currentSource = this._currentSource;
|
||||||
|
} else if (window._inputSources == this._inputSources) {
|
||||||
|
window._currentSource.activate();
|
||||||
|
} else {
|
||||||
|
window._inputSources = this._inputSources;
|
||||||
|
window._currentSource = this._getNewInputSource(window._currentSource);
|
||||||
|
window._currentSource.activate();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_sourcesPerWindowChanged: function() {
|
||||||
|
this._sourcesPerWindow = this._settings.get_boolean('per-window');
|
||||||
|
|
||||||
|
if (this._sourcesPerWindow && this._focusWindowNotifyId == 0) {
|
||||||
|
this._focusWindowNotifyId = global.display.connect('notify::focus-window',
|
||||||
|
Lang.bind(this, this._setPerWindowInputSource));
|
||||||
|
this._overviewShowingId = Main.overview.connect('showing',
|
||||||
|
Lang.bind(this, this._setPerWindowInputSource));
|
||||||
|
this._overviewHiddenId = Main.overview.connect('hidden',
|
||||||
|
Lang.bind(this, this._setPerWindowInputSource));
|
||||||
|
} else if (!this._sourcesPerWindow && this._focusWindowNotifyId != 0) {
|
||||||
|
global.display.disconnect(this._focusWindowNotifyId);
|
||||||
|
this._focusWindowNotifyId = 0;
|
||||||
|
Main.overview.disconnect(this._overviewShowingId);
|
||||||
|
this._overviewShowingId = 0;
|
||||||
|
Main.overview.disconnect(this._overviewHiddenId);
|
||||||
|
this._overviewHiddenId = 0;
|
||||||
|
|
||||||
|
let windows = global.get_window_actors().map(function(w) {
|
||||||
|
return w.meta_window;
|
||||||
|
});
|
||||||
|
for (let i = 0; i < windows.length; ++i) {
|
||||||
|
delete windows[i]._inputSources;
|
||||||
|
delete windows[i]._currentSource;
|
||||||
|
}
|
||||||
|
delete Main.overview._inputSources;
|
||||||
|
delete Main.overview._currentSource;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_changePerWindowSource: function() {
|
||||||
|
if (!this._sourcesPerWindow)
|
||||||
|
return;
|
||||||
|
|
||||||
|
let window = this._getCurrentWindow();
|
||||||
|
if (!window)
|
||||||
|
return;
|
||||||
|
|
||||||
|
window._inputSources = this._inputSources;
|
||||||
|
window._currentSource = this._currentSource;
|
||||||
|
},
|
||||||
|
|
||||||
_containerGetPreferredWidth: function(container, for_height, alloc) {
|
_containerGetPreferredWidth: function(container, for_height, alloc) {
|
||||||
// Here, and in _containerGetPreferredHeight, we need to query
|
// Here, and in _containerGetPreferredHeight, we need to query
|
||||||
// for the height of all children, but we ignore the results
|
// for the height of all children, but we ignore the results
|
||||||
// for those we don't actually display.
|
// for those we don't actually display.
|
||||||
let max_min_width = 0, max_natural_width = 0;
|
let max_min_width = 0, max_natural_width = 0;
|
||||||
|
|
||||||
for (let i in this._labelActors) {
|
for (let i in this._inputSources) {
|
||||||
let [min_width, natural_width] = this._labelActors[i].get_preferred_width(for_height);
|
let is = this._inputSources[i];
|
||||||
|
let [min_width, natural_width] = is.indicatorLabel.get_preferred_width(for_height);
|
||||||
max_min_width = Math.max(max_min_width, min_width);
|
max_min_width = Math.max(max_min_width, min_width);
|
||||||
max_natural_width = Math.max(max_natural_width, natural_width);
|
max_natural_width = Math.max(max_natural_width, natural_width);
|
||||||
}
|
}
|
||||||
@ -541,8 +809,9 @@ const InputSourceIndicator = new Lang.Class({
|
|||||||
_containerGetPreferredHeight: function(container, for_width, alloc) {
|
_containerGetPreferredHeight: function(container, for_width, alloc) {
|
||||||
let max_min_height = 0, max_natural_height = 0;
|
let max_min_height = 0, max_natural_height = 0;
|
||||||
|
|
||||||
for (let i in this._labelActors) {
|
for (let i in this._inputSources) {
|
||||||
let [min_height, natural_height] = this._labelActors[i].get_preferred_height(for_width);
|
let is = this._inputSources[i];
|
||||||
|
let [min_height, natural_height] = is.indicatorLabel.get_preferred_height(for_width);
|
||||||
max_min_height = Math.max(max_min_height, min_height);
|
max_min_height = Math.max(max_min_height, min_height);
|
||||||
max_natural_height = Math.max(max_natural_height, natural_height);
|
max_natural_height = Math.max(max_natural_height, natural_height);
|
||||||
}
|
}
|
||||||
@ -558,7 +827,9 @@ const InputSourceIndicator = new Lang.Class({
|
|||||||
box.y2 -= box.y1;
|
box.y2 -= box.y1;
|
||||||
box.y1 = 0;
|
box.y1 = 0;
|
||||||
|
|
||||||
for (let i in this._labelActors)
|
for (let i in this._inputSources) {
|
||||||
this._labelActors[i].allocate_align_fill(box, 0.5, 0, false, false, flags);
|
let is = this._inputSources[i];
|
||||||
|
is.indicatorLabel.allocate_align_fill(box, 0.5, 0, false, false, flags);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -10,48 +10,53 @@ const PanelMenu = imports.ui.panelMenu;
|
|||||||
const PopupMenu = imports.ui.popupMenu;
|
const PopupMenu = imports.ui.popupMenu;
|
||||||
const VolumeMenu = imports.ui.status.volume;
|
const VolumeMenu = imports.ui.status.volume;
|
||||||
|
|
||||||
|
const FakeStatusIcon = new Lang.Class({
|
||||||
|
Name: 'FakeStatusIcon',
|
||||||
|
|
||||||
|
_init: function(button) {
|
||||||
|
this.actor = new St.BoxLayout({ style_class: 'panel-status-button-box' });
|
||||||
|
this._button = button;
|
||||||
|
this._button.connect('icons-updated', Lang.bind(this, this._reconstructIcons));
|
||||||
|
this._button.actor.bind_property('visible', this.actor, 'visible',
|
||||||
|
GObject.BindingFlags.SYNC_CREATE);
|
||||||
|
this._reconstructIcons();
|
||||||
|
},
|
||||||
|
|
||||||
|
_reconstructIcons: function() {
|
||||||
|
this.actor.destroy_all_children();
|
||||||
|
this._button.icons.forEach(Lang.bind(this, function(icon) {
|
||||||
|
let newIcon = new St.Icon({ style_class: 'system-status-icon' });
|
||||||
|
icon.bind_property('gicon', newIcon, 'gicon',
|
||||||
|
GObject.BindingFlags.SYNC_CREATE);
|
||||||
|
icon.bind_property('visible', newIcon, 'visible',
|
||||||
|
GObject.BindingFlags.SYNC_CREATE);
|
||||||
|
this.actor.add_actor(newIcon);
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
const Indicator = new Lang.Class({
|
const Indicator = new Lang.Class({
|
||||||
Name: 'LockScreenMenuIndicator',
|
Name: 'LockScreenMenuIndicator',
|
||||||
Extends: PanelMenu.SystemStatusButton,
|
Extends: PanelMenu.SystemStatusButton,
|
||||||
|
|
||||||
_init: function() {
|
_init: function() {
|
||||||
this.parent(null, _("Volume, network, battery"));
|
this.parent(null, _("Volume, network, battery"));
|
||||||
|
this._box.style_class = 'lock-screen-status-button-box';
|
||||||
|
|
||||||
this._volume = Main.panel.statusArea.volume;
|
this._volumeControl = VolumeMenu.getMixerControl();
|
||||||
if (this._volume) {
|
this._volumeMenu = new VolumeMenu.VolumeMenu(this._volumeControl);
|
||||||
this._volumeIcon = this.addIcon(null);
|
this.menu.addMenuItem(this._volumeMenu);
|
||||||
this._volume.mainIcon.bind_property('gicon', this._volumeIcon, 'gicon',
|
|
||||||
GObject.BindingFlags.SYNC_CREATE);
|
|
||||||
this._volume.mainIcon.bind_property('visible', this._volumeIcon, 'visible',
|
|
||||||
GObject.BindingFlags.SYNC_CREATE);
|
|
||||||
|
|
||||||
this._volumeControl = VolumeMenu.getMixerControl();
|
this._volume = new FakeStatusIcon(Main.panel.statusArea.volume);
|
||||||
this._volumeMenu = new VolumeMenu.VolumeMenu(this._volumeControl);
|
this._box.add_child(this._volume.actor);
|
||||||
this.menu.addMenuItem(this._volumeMenu);
|
|
||||||
|
// Network may not exist if the user doesn't have NetworkManager
|
||||||
|
if (Main.panel.statusArea.network) {
|
||||||
|
this._network = new FakeStatusIcon(Main.panel.statusArea.network);
|
||||||
|
this._box.add_child(this._network.actor);
|
||||||
}
|
}
|
||||||
|
|
||||||
this._network = Main.panel.statusArea.network;
|
this._battery = new FakeStatusIcon(Main.panel.statusArea.battery);
|
||||||
if (this._network) {
|
this._box.add_child(this._battery.actor);
|
||||||
this._networkIcon = this.addIcon(null);
|
|
||||||
this._network.mainIcon.bind_property('gicon', this._networkIcon, 'gicon',
|
|
||||||
GObject.BindingFlags.SYNC_CREATE);
|
|
||||||
this._network.mainIcon.bind_property('visible', this._networkIcon, 'visible',
|
|
||||||
GObject.BindingFlags.SYNC_CREATE);
|
|
||||||
|
|
||||||
this._networkSecondaryIcon = this.addIcon(null);
|
|
||||||
this._network.secondaryIcon.bind_property('gicon', this._networkSecondaryIcon, 'gicon',
|
|
||||||
GObject.BindingFlags.SYNC_CREATE);
|
|
||||||
this._network.secondaryIcon.bind_property('visible', this._networkSecondaryIcon, 'visible',
|
|
||||||
GObject.BindingFlags.SYNC_CREATE);
|
|
||||||
}
|
|
||||||
|
|
||||||
this._battery = Main.panel.statusArea.battery;
|
|
||||||
if (this._battery) {
|
|
||||||
this._batteryIcon = this.addIcon(null);
|
|
||||||
this._battery.mainIcon.bind_property('gicon', this._batteryIcon, 'gicon',
|
|
||||||
GObject.BindingFlags.SYNC_CREATE);
|
|
||||||
this._battery.mainIcon.bind_property('visible', this._batteryIcon, 'visible',
|
|
||||||
GObject.BindingFlags.SYNC_CREATE);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -5,10 +5,17 @@ const Gio = imports.gi.Gio;
|
|||||||
const Lang = imports.lang;
|
const Lang = imports.lang;
|
||||||
const NetworkManager = imports.gi.NetworkManager;
|
const NetworkManager = imports.gi.NetworkManager;
|
||||||
const NMClient = imports.gi.NMClient;
|
const NMClient = imports.gi.NMClient;
|
||||||
const NMGtk = imports.gi.NMGtk;
|
|
||||||
const Signals = imports.signals;
|
const Signals = imports.signals;
|
||||||
const St = imports.gi.St;
|
const St = imports.gi.St;
|
||||||
|
|
||||||
|
// Some of the new code depends on as-yet-unreleased NM
|
||||||
|
var NMGtk;
|
||||||
|
try {
|
||||||
|
NMGtk = imports.gi.NMGtk;
|
||||||
|
} catch(e) {
|
||||||
|
NMGtk = null;
|
||||||
|
}
|
||||||
|
|
||||||
const Main = imports.ui.main;
|
const Main = imports.ui.main;
|
||||||
const PanelMenu = imports.ui.panelMenu;
|
const PanelMenu = imports.ui.panelMenu;
|
||||||
const PopupMenu = imports.ui.popupMenu;
|
const PopupMenu = imports.ui.popupMenu;
|
||||||
@ -474,7 +481,8 @@ const NMDevice = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
syncDescription: function() {
|
syncDescription: function() {
|
||||||
this.statusItem.label.text = this.device._description;
|
if (this.device._description)
|
||||||
|
this.statusItem.label.text = this.device._description;
|
||||||
},
|
},
|
||||||
|
|
||||||
// protected
|
// protected
|
||||||
@ -611,12 +619,11 @@ const NMDevice = new Lang.Class({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const NMDeviceWired = new Lang.Class({
|
const NMDeviceSimple = new Lang.Class({
|
||||||
Name: 'NMDeviceWired',
|
Name: 'NMDeviceSimple',
|
||||||
Extends: NMDevice,
|
Extends: NMDevice,
|
||||||
|
|
||||||
_init: function(client, device, connections) {
|
_init: function(client, device, connections) {
|
||||||
this._autoConnectionName = _("Auto Ethernet");
|
|
||||||
this.category = NMConnectionCategory.WIRED;
|
this.category = NMConnectionCategory.WIRED;
|
||||||
|
|
||||||
this.parent(client, device, connections);
|
this.parent(client, device, connections);
|
||||||
@ -631,6 +638,19 @@ const NMDeviceWired = new Lang.Class({
|
|||||||
// we can do it here because addConnection and removeConnection
|
// we can do it here because addConnection and removeConnection
|
||||||
// both call _createSection at some point
|
// both call _createSection at some point
|
||||||
this.section.actor.visible = this._connections.length > 1;
|
this.section.actor.visible = this._connections.length > 1;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const NMDeviceWired = new Lang.Class({
|
||||||
|
Name: 'NMDeviceWired',
|
||||||
|
Extends: NMDeviceSimple,
|
||||||
|
|
||||||
|
_init: function(client, device, connections) {
|
||||||
|
device._description = _("Wired");
|
||||||
|
this._autoConnectionName = _("Auto Ethernet");
|
||||||
|
this.category = NMConnectionCategory.WIRED;
|
||||||
|
|
||||||
|
this.parent(client, device, connections);
|
||||||
},
|
},
|
||||||
|
|
||||||
_createAutomaticConnection: function() {
|
_createAutomaticConnection: function() {
|
||||||
@ -654,6 +674,7 @@ const NMDeviceModem = new Lang.Class({
|
|||||||
_init: function(client, device, connections) {
|
_init: function(client, device, connections) {
|
||||||
let is_wwan = false;
|
let is_wwan = false;
|
||||||
|
|
||||||
|
device._description = _("Mobile broadband");
|
||||||
this._enabled = true;
|
this._enabled = true;
|
||||||
this.mobileDevice = null;
|
this.mobileDevice = null;
|
||||||
this._connectionType = 'ppp';
|
this._connectionType = 'ppp';
|
||||||
@ -772,6 +793,7 @@ const NMDeviceBluetooth = new Lang.Class({
|
|||||||
Extends: NMDevice,
|
Extends: NMDevice,
|
||||||
|
|
||||||
_init: function(client, device, connections) {
|
_init: function(client, device, connections) {
|
||||||
|
device._description = _("Bluetooth");
|
||||||
this._autoConnectionName = this._makeConnectionName(device);
|
this._autoConnectionName = this._makeConnectionName(device);
|
||||||
device.connect('notify::name', Lang.bind(this, this._updateAutoConnectionName));
|
device.connect('notify::name', Lang.bind(this, this._updateAutoConnectionName));
|
||||||
|
|
||||||
@ -1640,6 +1662,7 @@ const NMApplet = new Lang.Class({
|
|||||||
this._dtypes[NetworkManager.DeviceType.WIFI] = NMDeviceWireless;
|
this._dtypes[NetworkManager.DeviceType.WIFI] = NMDeviceWireless;
|
||||||
this._dtypes[NetworkManager.DeviceType.MODEM] = NMDeviceModem;
|
this._dtypes[NetworkManager.DeviceType.MODEM] = NMDeviceModem;
|
||||||
this._dtypes[NetworkManager.DeviceType.BT] = NMDeviceBluetooth;
|
this._dtypes[NetworkManager.DeviceType.BT] = NMDeviceBluetooth;
|
||||||
|
this._dtypes[NetworkManager.DeviceType.INFINIBAND] = NMDeviceSimple;
|
||||||
// TODO: WiMax support
|
// TODO: WiMax support
|
||||||
|
|
||||||
// Connection types
|
// Connection types
|
||||||
@ -1651,6 +1674,7 @@ const NMApplet = new Lang.Class({
|
|||||||
this._ctypes[NetworkManager.SETTING_BLUETOOTH_SETTING_NAME] = NMConnectionCategory.WWAN;
|
this._ctypes[NetworkManager.SETTING_BLUETOOTH_SETTING_NAME] = NMConnectionCategory.WWAN;
|
||||||
this._ctypes[NetworkManager.SETTING_CDMA_SETTING_NAME] = NMConnectionCategory.WWAN;
|
this._ctypes[NetworkManager.SETTING_CDMA_SETTING_NAME] = NMConnectionCategory.WWAN;
|
||||||
this._ctypes[NetworkManager.SETTING_GSM_SETTING_NAME] = NMConnectionCategory.WWAN;
|
this._ctypes[NetworkManager.SETTING_GSM_SETTING_NAME] = NMConnectionCategory.WWAN;
|
||||||
|
this._ctypes[NetworkManager.SETTING_INFINIBAND_SETTING_NAME] = NMConnectionCategory.WIRED;
|
||||||
this._ctypes[NetworkManager.SETTING_VPN_SETTING_NAME] = NMConnectionCategory.VPN;
|
this._ctypes[NetworkManager.SETTING_VPN_SETTING_NAME] = NMConnectionCategory.VPN;
|
||||||
|
|
||||||
this._settings = NMClient.RemoteSettings.new(null);
|
this._settings = NMClient.RemoteSettings.new(null);
|
||||||
@ -1781,13 +1805,18 @@ const NMApplet = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
_syncDeviceNames: function() {
|
_syncDeviceNames: function() {
|
||||||
let names = NMGtk.utils_disambiguate_device_names(this._nmDevices);
|
if (NMGtk) {
|
||||||
for (let i = 0; i < this._nmDevices.length; i++) {
|
let names = NMGtk.utils_disambiguate_device_names(this._nmDevices);
|
||||||
let device = this._nmDevices[i];
|
for (let i = 0; i < this._nmDevices.length; i++) {
|
||||||
if (device._description != names[i]) {
|
let device = this._nmDevices[i];
|
||||||
device._description = names[i];
|
device._description = names[i];
|
||||||
device._delegate.syncDescription();
|
device._delegate.syncDescription();
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
for (let i = 0; i < this._nmDevices.length; i++) {
|
||||||
|
let device = this._nmDevices[i];
|
||||||
|
device._delegate.syncDescription();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ const St = imports.gi.St;
|
|||||||
const PanelMenu = imports.ui.panelMenu;
|
const PanelMenu = imports.ui.panelMenu;
|
||||||
const PopupMenu = imports.ui.popupMenu;
|
const PopupMenu = imports.ui.popupMenu;
|
||||||
|
|
||||||
const BUS_NAME = 'org.gnome.SettingsDaemon';
|
const BUS_NAME = 'org.gnome.SettingsDaemon.Power';
|
||||||
const OBJECT_PATH = '/org/gnome/SettingsDaemon/Power';
|
const OBJECT_PATH = '/org/gnome/SettingsDaemon/Power';
|
||||||
|
|
||||||
const UPDeviceType = {
|
const UPDeviceType = {
|
||||||
@ -61,7 +61,7 @@ const Indicator = new Lang.Class({
|
|||||||
this._primaryDeviceId = null;
|
this._primaryDeviceId = null;
|
||||||
|
|
||||||
this._batteryItem = new PopupMenu.PopupMenuItem('', { reactive: false });
|
this._batteryItem = new PopupMenu.PopupMenuItem('', { reactive: false });
|
||||||
this._primaryPercentage = new St.Label();
|
this._primaryPercentage = new St.Label({ style_class: 'popup-battery-percentage' });
|
||||||
this._batteryItem.addActor(this._primaryPercentage, { align: St.Align.END });
|
this._batteryItem.addActor(this._primaryPercentage, { align: St.Align.END });
|
||||||
this.menu.addMenuItem(this._batteryItem);
|
this.menu.addMenuItem(this._batteryItem);
|
||||||
|
|
||||||
@ -183,7 +183,8 @@ const DeviceItem = new Lang.Class({
|
|||||||
this._box.add_actor(this._label);
|
this._box.add_actor(this._label);
|
||||||
this.addActor(this._box);
|
this.addActor(this._box);
|
||||||
|
|
||||||
let percentLabel = new St.Label({ text: C_("percent of battery remaining", "%d%%").format(Math.round(percentage)) });
|
let percentLabel = new St.Label({ text: C_("percent of battery remaining", "%d%%").format(Math.round(percentage)),
|
||||||
|
style_class: 'popup-battery-percentage' });
|
||||||
this.addActor(percentLabel, { align: St.Align.END });
|
this.addActor(percentLabel, { align: St.Align.END });
|
||||||
//FIXME: ideally we would like to expose this._label and percentLabel
|
//FIXME: ideally we would like to expose this._label and percentLabel
|
||||||
this.actor.label_actor = percentLabel;
|
this.actor.label_actor = percentLabel;
|
||||||
|
@ -5,6 +5,7 @@ const Lang = imports.lang;
|
|||||||
const Gio = imports.gi.Gio;
|
const Gio = imports.gi.Gio;
|
||||||
const Gvc = imports.gi.Gvc;
|
const Gvc = imports.gi.Gvc;
|
||||||
const St = imports.gi.St;
|
const St = imports.gi.St;
|
||||||
|
const Signals = imports.signals;
|
||||||
|
|
||||||
const PanelMenu = imports.ui.panelMenu;
|
const PanelMenu = imports.ui.panelMenu;
|
||||||
const PopupMenu = imports.ui.popupMenu;
|
const PopupMenu = imports.ui.popupMenu;
|
||||||
@ -26,79 +27,134 @@ function getMixerControl() {
|
|||||||
return _mixerControl;
|
return _mixerControl;
|
||||||
}
|
}
|
||||||
|
|
||||||
const VolumeMenu = new Lang.Class({
|
const StreamSlider = new Lang.Class({
|
||||||
Name: 'VolumeMenu',
|
Name: 'StreamSlider',
|
||||||
Extends: PopupMenu.PopupMenuSection,
|
|
||||||
|
|
||||||
_init: function(control) {
|
|
||||||
this.parent();
|
|
||||||
|
|
||||||
this.hasHeadphones = false;
|
|
||||||
|
|
||||||
|
_init: function(control, title) {
|
||||||
this._control = control;
|
this._control = control;
|
||||||
this._control.connect('state-changed', Lang.bind(this, this._onControlStateChanged));
|
|
||||||
this._control.connect('default-sink-changed', Lang.bind(this, this._readOutput));
|
|
||||||
this._control.connect('default-source-changed', Lang.bind(this, this._readInput));
|
|
||||||
this._control.connect('stream-added', Lang.bind(this, this._maybeShowInput));
|
|
||||||
this._control.connect('stream-removed', Lang.bind(this, this._maybeShowInput));
|
|
||||||
this._volumeMax = this._control.get_vol_max_norm();
|
|
||||||
|
|
||||||
this._output = null;
|
this.item = new PopupMenu.PopupMenuSection();
|
||||||
this._outputVolumeId = 0;
|
|
||||||
this._outputMutedId = 0;
|
|
||||||
/* Translators: This is the label for audio volume */
|
|
||||||
this._outputTitle = new PopupMenu.PopupMenuItem(_("Volume"), { reactive: false });
|
|
||||||
this._outputSlider = new PopupMenu.PopupSliderMenuItem(0);
|
|
||||||
this._outputSlider.connect('value-changed', Lang.bind(this, this._sliderChanged, '_output'));
|
|
||||||
this._outputSlider.connect('drag-end', Lang.bind(this, this._notifyVolumeChange));
|
|
||||||
this.addMenuItem(this._outputTitle);
|
|
||||||
this.addMenuItem(this._outputSlider);
|
|
||||||
|
|
||||||
this.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
|
this._title = new PopupMenu.PopupMenuItem(title, { reactive: false });
|
||||||
|
this._slider = new PopupMenu.PopupSliderMenuItem(0);
|
||||||
|
this._slider.connect('value-changed', Lang.bind(this, this._sliderChanged));
|
||||||
|
this._slider.connect('drag-end', Lang.bind(this, this._notifyVolumeChange));
|
||||||
|
|
||||||
this._input = null;
|
this.item.addMenuItem(this._title);
|
||||||
this._inputVolumeId = 0;
|
this.item.addMenuItem(this._slider);
|
||||||
this._inputMutedId = 0;
|
|
||||||
this._inputTitle = new PopupMenu.PopupMenuItem(_("Microphone"), { reactive: false });
|
|
||||||
this._inputSlider = new PopupMenu.PopupSliderMenuItem(0);
|
|
||||||
this._inputSlider.connect('value-changed', Lang.bind(this, this._sliderChanged, '_input'));
|
|
||||||
this._inputSlider.connect('drag-end', Lang.bind(this, this._notifyVolumeChange));
|
|
||||||
this.addMenuItem(this._inputTitle);
|
|
||||||
this.addMenuItem(this._inputSlider);
|
|
||||||
|
|
||||||
this._onControlStateChanged();
|
this._stream = null;
|
||||||
|
this._shouldShow = true;
|
||||||
},
|
},
|
||||||
|
|
||||||
scroll: function(direction) {
|
get stream() {
|
||||||
let currentVolume = this._output.volume;
|
return this._stream;
|
||||||
|
|
||||||
if (direction == Clutter.ScrollDirection.DOWN) {
|
|
||||||
let prev_muted = this._output.is_muted;
|
|
||||||
this._output.volume = Math.max(0, currentVolume - this._volumeMax * VOLUME_ADJUSTMENT_STEP);
|
|
||||||
if (this._output.volume < 1) {
|
|
||||||
this._output.volume = 0;
|
|
||||||
if (!prev_muted)
|
|
||||||
this._output.change_is_muted(true);
|
|
||||||
}
|
|
||||||
this._output.push_volume();
|
|
||||||
}
|
|
||||||
else if (direction == Clutter.ScrollDirection.UP) {
|
|
||||||
this._output.volume = Math.min(this._volumeMax, currentVolume + this._volumeMax * VOLUME_ADJUSTMENT_STEP);
|
|
||||||
this._output.change_is_muted(false);
|
|
||||||
this._output.push_volume();
|
|
||||||
}
|
|
||||||
|
|
||||||
this._notifyVolumeChange();
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_onControlStateChanged: function() {
|
set stream(stream) {
|
||||||
if (this._control.get_state() == Gvc.MixerControlState.READY) {
|
if (this._stream) {
|
||||||
this._readOutput();
|
this._disconnectStream(this._stream);
|
||||||
this._readInput();
|
}
|
||||||
this._maybeShowInput();
|
|
||||||
|
this._stream = stream;
|
||||||
|
|
||||||
|
if (this._stream) {
|
||||||
|
this._connectStream(this._stream);
|
||||||
|
this._updateVolume();
|
||||||
} else {
|
} else {
|
||||||
this.emit('icon-changed', null);
|
this.emit('stream-updated');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this._updateVisibility();
|
||||||
|
},
|
||||||
|
|
||||||
|
_disconnectStream: function(stream) {
|
||||||
|
stream.disconnect(this._mutedChangedId);
|
||||||
|
this._mutedChangedId = 0;
|
||||||
|
stream.disconnect(this._volumeChangedId);
|
||||||
|
this._volumeChangedId = 0;
|
||||||
|
},
|
||||||
|
|
||||||
|
_connectStream: function(stream) {
|
||||||
|
this._mutedChangedId = stream.connect('notify::is-muted', Lang.bind(this, this._updateVolume));
|
||||||
|
this._volumeChangedId = stream.connect('notify::volume', Lang.bind(this, this._updateVolume));
|
||||||
|
},
|
||||||
|
|
||||||
|
_shouldBeVisible: function() {
|
||||||
|
return this._stream != null;
|
||||||
|
},
|
||||||
|
|
||||||
|
_updateVisibility: function() {
|
||||||
|
let visible = this._shouldBeVisible();
|
||||||
|
this._title.actor.visible = visible;
|
||||||
|
this._slider.actor.visible = visible;
|
||||||
|
},
|
||||||
|
|
||||||
|
scroll: function(event) {
|
||||||
|
this._slider.scroll(event);
|
||||||
|
},
|
||||||
|
|
||||||
|
setValue: function(value) {
|
||||||
|
// piggy-back off of sliderChanged
|
||||||
|
this._slider.setValue(value);
|
||||||
|
},
|
||||||
|
|
||||||
|
_sliderChanged: function(slider, value, property) {
|
||||||
|
if (!this._stream)
|
||||||
|
return;
|
||||||
|
|
||||||
|
let volume = value * this._control.get_vol_max_norm();
|
||||||
|
let prevMuted = this._stream.is_muted;
|
||||||
|
if (volume < 1) {
|
||||||
|
this._stream.volume = 0;
|
||||||
|
if (!prevMuted)
|
||||||
|
this._stream.change_is_muted(true);
|
||||||
|
} else {
|
||||||
|
this._stream.volume = volume;
|
||||||
|
if (prevMuted)
|
||||||
|
this._stream.change_is_muted(false);
|
||||||
|
}
|
||||||
|
this._stream.push_volume();
|
||||||
|
},
|
||||||
|
|
||||||
|
_notifyVolumeChange: function() {
|
||||||
|
global.cancel_theme_sound(VOLUME_NOTIFY_ID);
|
||||||
|
global.play_theme_sound(VOLUME_NOTIFY_ID, 'audio-volume-change');
|
||||||
|
},
|
||||||
|
|
||||||
|
_updateVolume: function() {
|
||||||
|
let muted = this._stream.is_muted;
|
||||||
|
this._slider.setValue(muted ? 0 : (this._stream.volume / this._control.get_vol_max_norm()));
|
||||||
|
this.emit('stream-updated');
|
||||||
|
},
|
||||||
|
|
||||||
|
getIcon: function() {
|
||||||
|
if (!this._stream)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
let volume = this._stream.volume;
|
||||||
|
if (this._stream.is_muted || volume <= 0) {
|
||||||
|
return 'audio-volume-muted-symbolic';
|
||||||
|
} else {
|
||||||
|
let n = Math.floor(3 * volume / this._control.get_vol_max_norm()) + 1;
|
||||||
|
if (n < 2)
|
||||||
|
return 'audio-volume-low-symbolic';
|
||||||
|
if (n >= 3)
|
||||||
|
return 'audio-volume-high-symbolic';
|
||||||
|
return 'audio-volume-medium-symbolic';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Signals.addSignalMethods(StreamSlider.prototype);
|
||||||
|
|
||||||
|
const OutputStreamSlider = new Lang.Class({
|
||||||
|
Name: 'OutputStreamSlider',
|
||||||
|
Extends: StreamSlider,
|
||||||
|
|
||||||
|
_connectStream: function(stream) {
|
||||||
|
this.parent(stream);
|
||||||
|
this._portChangedId = stream.connect('notify::port', Lang.bind(this, this._portChanged));
|
||||||
|
this._portChanged();
|
||||||
},
|
},
|
||||||
|
|
||||||
_findHeadphones: function(sink) {
|
_findHeadphones: function(sink) {
|
||||||
@ -117,60 +173,41 @@ const VolumeMenu = new Lang.Class({
|
|||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_disconnectStream: function(stream) {
|
||||||
|
this.parent(stream);
|
||||||
|
stream.disconnect(this._portChangedId);
|
||||||
|
this._portChangedId = 0;
|
||||||
|
},
|
||||||
|
|
||||||
_portChanged: function() {
|
_portChanged: function() {
|
||||||
this.hasHeadphones = this._findHeadphones(this._output);
|
let hasHeadphones = this._findHeadphones(this._stream);
|
||||||
this.emit('headphones-changed');
|
if (hasHeadphones != this._hasHeadphones) {
|
||||||
|
this._hasHeadphones = hasHeadphones;
|
||||||
|
this.emit('headphones-changed', this._hasHeadphones);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const InputStreamSlider = new Lang.Class({
|
||||||
|
Name: 'InputStreamSlider',
|
||||||
|
Extends: StreamSlider,
|
||||||
|
|
||||||
|
_init: function(control, title) {
|
||||||
|
this.parent(control, title);
|
||||||
|
this._control.connect('stream-added', Lang.bind(this, this._maybeShowInput));
|
||||||
|
this._control.connect('stream-removed', Lang.bind(this, this._maybeShowInput));
|
||||||
},
|
},
|
||||||
|
|
||||||
_readOutput: function() {
|
_connectStream: function(stream) {
|
||||||
if (this._outputVolumeId) {
|
this.parent(stream);
|
||||||
this._output.disconnect(this._outputVolumeId);
|
this._maybeShowInput();
|
||||||
this._output.disconnect(this._outputMutedId);
|
|
||||||
this._output.disconnect(this._outputPortId);
|
|
||||||
this._outputVolumeId = 0;
|
|
||||||
this._outputMutedId = 0;
|
|
||||||
this._outputPortId = 0;
|
|
||||||
}
|
|
||||||
this._output = this._control.get_default_sink();
|
|
||||||
if (this._output) {
|
|
||||||
this._outputMutedId = this._output.connect('notify::is-muted', Lang.bind(this, this._mutedChanged, '_output'));
|
|
||||||
this._outputVolumeId = this._output.connect('notify::volume', Lang.bind(this, this._volumeChanged, '_output'));
|
|
||||||
this._outputPortId = this._output.connect('notify::port', Lang.bind(this, this._portChanged));
|
|
||||||
|
|
||||||
this._mutedChanged(null, null, '_output');
|
|
||||||
this._volumeChanged(null, null, '_output');
|
|
||||||
this._portChanged();
|
|
||||||
} else {
|
|
||||||
this.hasHeadphones = false;
|
|
||||||
this._outputSlider.setValue(0);
|
|
||||||
this.emit('icon-changed', 'audio-volume-muted-symbolic');
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
_readInput: function() {
|
|
||||||
if (this._inputVolumeId) {
|
|
||||||
this._input.disconnect(this._inputVolumeId);
|
|
||||||
this._input.disconnect(this._inputMutedId);
|
|
||||||
this._inputVolumeId = 0;
|
|
||||||
this._inputMutedId = 0;
|
|
||||||
}
|
|
||||||
this._input = this._control.get_default_source();
|
|
||||||
if (this._input) {
|
|
||||||
this._inputMutedId = this._input.connect('notify::is-muted', Lang.bind(this, this._mutedChanged, '_input'));
|
|
||||||
this._inputVolumeId = this._input.connect('notify::volume', Lang.bind(this, this._volumeChanged, '_input'));
|
|
||||||
this._mutedChanged (null, null, '_input');
|
|
||||||
this._volumeChanged (null, null, '_input');
|
|
||||||
} else {
|
|
||||||
this._inputTitle.actor.hide();
|
|
||||||
this._inputSlider.actor.hide();
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_maybeShowInput: function() {
|
_maybeShowInput: function() {
|
||||||
// only show input widgets if any application is recording audio
|
// only show input widgets if any application is recording audio
|
||||||
let showInput = false;
|
let showInput = false;
|
||||||
let recordingApps = this._control.get_source_outputs();
|
let recordingApps = this._control.get_source_outputs();
|
||||||
if (this._input && recordingApps) {
|
if (this._stream && recordingApps) {
|
||||||
for (let i = 0; i < recordingApps.length; i++) {
|
for (let i = 0; i < recordingApps.length; i++) {
|
||||||
let outputStream = recordingApps[i];
|
let outputStream = recordingApps[i];
|
||||||
let id = outputStream.get_application_id();
|
let id = outputStream.get_application_id();
|
||||||
@ -183,63 +220,70 @@ const VolumeMenu = new Lang.Class({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this._inputTitle.actor.visible = showInput;
|
this._showInput = showInput;
|
||||||
this._inputSlider.actor.visible = showInput;
|
this._updateVisibility();
|
||||||
},
|
},
|
||||||
|
|
||||||
_volumeToIcon: function(volume) {
|
_shouldBeVisible: function() {
|
||||||
if (volume <= 0) {
|
return this.parent() && this._showInput;
|
||||||
return 'audio-volume-muted-symbolic';
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const VolumeMenu = new Lang.Class({
|
||||||
|
Name: 'VolumeMenu',
|
||||||
|
Extends: PopupMenu.PopupMenuSection,
|
||||||
|
|
||||||
|
_init: function(control) {
|
||||||
|
this.parent();
|
||||||
|
|
||||||
|
this.hasHeadphones = false;
|
||||||
|
|
||||||
|
this._control = control;
|
||||||
|
this._control.connect('state-changed', Lang.bind(this, this._onControlStateChanged));
|
||||||
|
this._control.connect('default-sink-changed', Lang.bind(this, this._readOutput));
|
||||||
|
this._control.connect('default-source-changed', Lang.bind(this, this._readInput));
|
||||||
|
|
||||||
|
/* Translators: This is the label for audio volume */
|
||||||
|
this._output = new OutputStreamSlider(this._control, _("Volume"));
|
||||||
|
this._output.connect('stream-updated', Lang.bind(this, function() {
|
||||||
|
this.emit('icon-changed');
|
||||||
|
}));
|
||||||
|
this._output.connect('headphones-changed', Lang.bind(this, function(stream, value) {
|
||||||
|
this.emit('headphones-changed', value);
|
||||||
|
}));
|
||||||
|
this.addMenuItem(this._output.item);
|
||||||
|
|
||||||
|
this._input = new InputStreamSlider(this._control, _("Microphone"));
|
||||||
|
this.addMenuItem(this._input.item);
|
||||||
|
|
||||||
|
this.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
|
||||||
|
|
||||||
|
this._onControlStateChanged();
|
||||||
|
},
|
||||||
|
|
||||||
|
scroll: function(event) {
|
||||||
|
this._output.scroll(event);
|
||||||
|
},
|
||||||
|
|
||||||
|
_onControlStateChanged: function() {
|
||||||
|
if (this._control.get_state() == Gvc.MixerControlState.READY) {
|
||||||
|
this._readInput();
|
||||||
|
this._readOutput();
|
||||||
} else {
|
} else {
|
||||||
let n = Math.floor(3 * volume / this._volumeMax) + 1;
|
this.emit('icon-changed');
|
||||||
if (n < 2)
|
|
||||||
return 'audio-volume-low-symbolic';
|
|
||||||
if (n >= 3)
|
|
||||||
return 'audio-volume-high-symbolic';
|
|
||||||
return 'audio-volume-medium-symbolic';
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
_sliderChanged: function(slider, value, property) {
|
_readOutput: function() {
|
||||||
if (this[property] == null) {
|
this._output.stream = this._control.get_default_sink();
|
||||||
log ('Volume slider changed for %s, but %s does not exist'.format(property, property));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
let volume = value * this._volumeMax;
|
|
||||||
let prev_muted = this[property].is_muted;
|
|
||||||
if (volume < 1) {
|
|
||||||
this[property].volume = 0;
|
|
||||||
if (!prev_muted)
|
|
||||||
this[property].change_is_muted(true);
|
|
||||||
} else {
|
|
||||||
this[property].volume = volume;
|
|
||||||
if (prev_muted)
|
|
||||||
this[property].change_is_muted(false);
|
|
||||||
}
|
|
||||||
this[property].push_volume();
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_notifyVolumeChange: function() {
|
_readInput: function() {
|
||||||
global.cancel_theme_sound(VOLUME_NOTIFY_ID);
|
this._input.stream = this._control.get_default_source();
|
||||||
global.play_theme_sound(VOLUME_NOTIFY_ID, 'audio-volume-change');
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_mutedChanged: function(object, param_spec, property) {
|
getIcon: function() {
|
||||||
let muted = this[property].is_muted;
|
return this._output.getIcon();
|
||||||
let slider = this[property+'Slider'];
|
|
||||||
slider.setValue(muted ? 0 : (this[property].volume / this._volumeMax));
|
|
||||||
if (property == '_output') {
|
|
||||||
if (muted)
|
|
||||||
this.emit('icon-changed', 'audio-volume-muted-symbolic');
|
|
||||||
else
|
|
||||||
this.emit('icon-changed', this._volumeToIcon(this._output.volume));
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
_volumeChanged: function(object, param_spec, property) {
|
|
||||||
this[property+'Slider'].setValue(this[property].volume / this._volumeMax);
|
|
||||||
if (property == '_output' && !this._output.is_muted)
|
|
||||||
this.emit('icon-changed', this._volumeToIcon(this._output.volume));
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -252,13 +296,13 @@ const Indicator = new Lang.Class({
|
|||||||
|
|
||||||
this._control = getMixerControl();
|
this._control = getMixerControl();
|
||||||
this._volumeMenu = new VolumeMenu(this._control);
|
this._volumeMenu = new VolumeMenu(this._control);
|
||||||
this._volumeMenu.connect('icon-changed', Lang.bind(this, function(menu, icon) {
|
this._volumeMenu.connect('icon-changed', Lang.bind(this, function(menu) {
|
||||||
this._hasPulseAudio = (icon != null);
|
let icon = this._volumeMenu.getIcon();
|
||||||
|
this.actor.visible = (icon != null);
|
||||||
this.setIcon(icon);
|
this.setIcon(icon);
|
||||||
this._syncVisibility();
|
|
||||||
}));
|
}));
|
||||||
this._volumeMenu.connect('headphones-changed', Lang.bind(this, function() {
|
this._volumeMenu.connect('headphones-changed', Lang.bind(this, function(menu, value) {
|
||||||
this._syncVisibility();
|
this._headphoneIcon.visible = value;
|
||||||
}));
|
}));
|
||||||
|
|
||||||
this._headphoneIcon = this.addIcon(new Gio.ThemedIcon({ name: 'headphones-symbolic' }));
|
this._headphoneIcon = this.addIcon(new Gio.ThemedIcon({ name: 'headphones-symbolic' }));
|
||||||
@ -272,13 +316,7 @@ const Indicator = new Lang.Class({
|
|||||||
this.actor.connect('scroll-event', Lang.bind(this, this._onScrollEvent));
|
this.actor.connect('scroll-event', Lang.bind(this, this._onScrollEvent));
|
||||||
},
|
},
|
||||||
|
|
||||||
_syncVisibility: function() {
|
|
||||||
this.actor.visible = this._hasPulseAudio;
|
|
||||||
this.mainIcon.visible = this._hasPulseAudio;
|
|
||||||
this._headphoneIcon.visible = this._hasPulseAudio && this._volumeMenu.hasHeadphones;
|
|
||||||
},
|
|
||||||
|
|
||||||
_onScrollEvent: function(actor, event) {
|
_onScrollEvent: function(actor, event) {
|
||||||
this._volumeMenu.scroll(event.get_scroll_direction());
|
this._volumeMenu.scroll(event);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -637,5 +637,6 @@ function drawArrow(area, side) {
|
|||||||
|
|
||||||
Clutter.cairo_set_source_color(cr, bodyColor);
|
Clutter.cairo_set_source_color(cr, bodyColor);
|
||||||
cr.fill();
|
cr.fill();
|
||||||
|
cr.$dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -198,18 +198,23 @@ const UnlockDialog = new Lang.Class({
|
|||||||
x_align: St.Align.END,
|
x_align: St.Align.END,
|
||||||
y_align: St.Align.MIDDLE });
|
y_align: St.Align.MIDDLE });
|
||||||
|
|
||||||
let otherUserLabel = new St.Label({ text: _("Log in as another user"),
|
let screenSaverSettings = new Gio.Settings({ schema: 'org.gnome.desktop.screensaver' });
|
||||||
style_class: 'login-dialog-not-listed-label' });
|
if (screenSaverSettings.get_boolean('user-switch-enabled')) {
|
||||||
this._otherUserButton = new St.Button({ style_class: 'login-dialog-not-listed-button',
|
let otherUserLabel = new St.Label({ text: _("Log in as another user"),
|
||||||
can_focus: true,
|
style_class: 'login-dialog-not-listed-label' });
|
||||||
child: otherUserLabel,
|
this._otherUserButton = new St.Button({ style_class: 'login-dialog-not-listed-button',
|
||||||
reactive: true,
|
can_focus: true,
|
||||||
x_align: St.Align.START,
|
child: otherUserLabel,
|
||||||
x_fill: true });
|
reactive: true,
|
||||||
this._otherUserButton.connect('clicked', Lang.bind(this, this._otherUserClicked));
|
x_align: St.Align.START,
|
||||||
this.dialogLayout.add(this._otherUserButton,
|
x_fill: true });
|
||||||
{ x_align: St.Align.START,
|
this._otherUserButton.connect('clicked', Lang.bind(this, this._otherUserClicked));
|
||||||
x_fill: false });
|
this.dialogLayout.add(this._otherUserButton,
|
||||||
|
{ x_align: St.Align.START,
|
||||||
|
x_fill: false });
|
||||||
|
} else {
|
||||||
|
this._otherUserButton = null;
|
||||||
|
}
|
||||||
|
|
||||||
this._updateSensitivity(true);
|
this._updateSensitivity(true);
|
||||||
|
|
||||||
@ -231,8 +236,10 @@ const UnlockDialog = new Lang.Class({
|
|||||||
this._promptEntry.reactive = sensitive;
|
this._promptEntry.reactive = sensitive;
|
||||||
this._promptEntry.clutter_text.editable = sensitive;
|
this._promptEntry.clutter_text.editable = sensitive;
|
||||||
this._updateOkButtonSensitivity(sensitive && this._promptEntry.text.length > 0);
|
this._updateOkButtonSensitivity(sensitive && this._promptEntry.text.length > 0);
|
||||||
this._otherUserButton.reactive = sensitive;
|
if (this._otherUserButton) {
|
||||||
this._otherUserButton.can_focus = sensitive;
|
this._otherUserButton.reactive = sensitive;
|
||||||
|
this._otherUserButton.can_focus = sensitive;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
_updateOkButtonSensitivity: function(sensitive) {
|
_updateOkButtonSensitivity: function(sensitive) {
|
||||||
|
@ -593,6 +593,7 @@ const UserMenuButton = new Lang.Class({
|
|||||||
|
|
||||||
this.setSensitive(!Main.sessionMode.isLocked);
|
this.setSensitive(!Main.sessionMode.isLocked);
|
||||||
this._updatePresenceIcon();
|
this._updatePresenceIcon();
|
||||||
|
this._updateUserName();
|
||||||
},
|
},
|
||||||
|
|
||||||
_onDestroy: function() {
|
_onDestroy: function() {
|
||||||
|
@ -39,17 +39,11 @@ const ViewSelector = new Lang.Class({
|
|||||||
Name: 'ViewSelector',
|
Name: 'ViewSelector',
|
||||||
|
|
||||||
_init : function(searchEntry, showAppsButton) {
|
_init : function(searchEntry, showAppsButton) {
|
||||||
this.actor = new St.BoxLayout({ name: 'viewSelector',
|
this.actor = new Shell.Stack({ name: 'viewSelector' });
|
||||||
vertical: true });
|
|
||||||
|
|
||||||
this._showAppsButton = showAppsButton;
|
this._showAppsButton = showAppsButton;
|
||||||
this._showAppsButton.connect('notify::checked', Lang.bind(this, this._onShowAppsButtonToggled));
|
this._showAppsButton.connect('notify::checked', Lang.bind(this, this._onShowAppsButtonToggled));
|
||||||
|
|
||||||
this._pageArea = new Shell.Stack();
|
|
||||||
this.actor.add(this._pageArea, { x_fill: true,
|
|
||||||
y_fill: true,
|
|
||||||
expand: true });
|
|
||||||
|
|
||||||
this._activePage = null;
|
this._activePage = null;
|
||||||
|
|
||||||
this.active = false;
|
this.active = false;
|
||||||
@ -138,17 +132,6 @@ const ViewSelector = new Lang.Class({
|
|||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// Public constraints which may be used to tie actors' height or
|
|
||||||
// vertical position to the current tab's content; as the content's
|
|
||||||
// height and position depend on the view selector's style properties
|
|
||||||
// (e.g. font size, padding, spacing, ...) it would be extremely hard
|
|
||||||
// and ugly to get these from the outside. While it would be possible
|
|
||||||
// to use position and height properties directly, outside code would
|
|
||||||
// need to ensure that the content is properly allocated before
|
|
||||||
// accessing the properties.
|
|
||||||
this.constrainHeight = new Clutter.BindConstraint({ source: this._pageArea,
|
|
||||||
coordinate: Clutter.BindCoordinate.HEIGHT });
|
|
||||||
|
|
||||||
Main.wm.addKeybinding('toggle-application-view',
|
Main.wm.addKeybinding('toggle-application-view',
|
||||||
new Gio.Settings({ schema: SHELL_KEYBINDINGS_SCHEMA }),
|
new Gio.Settings({ schema: SHELL_KEYBINDINGS_SCHEMA }),
|
||||||
Meta.KeyBindingFlags.NONE,
|
Meta.KeyBindingFlags.NONE,
|
||||||
@ -202,7 +185,7 @@ const ViewSelector = new Lang.Class({
|
|||||||
this._a11yFocusPage(page);
|
this._a11yFocusPage(page);
|
||||||
})
|
})
|
||||||
});;
|
});;
|
||||||
this._pageArea.add_actor(page);
|
this.actor.add_actor(page);
|
||||||
return page;
|
return page;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -10,7 +10,6 @@ const IconGrid = imports.ui.iconGrid;
|
|||||||
const Layout = imports.ui.layout;
|
const Layout = imports.ui.layout;
|
||||||
const Main = imports.ui.main;
|
const Main = imports.ui.main;
|
||||||
const Panel = imports.ui.panel;
|
const Panel = imports.ui.panel;
|
||||||
const Search = imports.ui.search;
|
|
||||||
|
|
||||||
// we could make these gsettings
|
// we could make these gsettings
|
||||||
const FISH_NAME = 'wanda';
|
const FISH_NAME = 'wanda';
|
||||||
@ -71,8 +70,7 @@ const WandaIconBin = new Lang.Class({
|
|||||||
Name: 'WandaIconBin',
|
Name: 'WandaIconBin',
|
||||||
|
|
||||||
_init: function(fish, label, params) {
|
_init: function(fish, label, params) {
|
||||||
this.actor = new St.Bin({ style_class: 'search-result-content',
|
this.actor = new St.Bin({ reactive: true,
|
||||||
reactive: true,
|
|
||||||
track_hover: true });
|
track_hover: true });
|
||||||
this.icon = new WandaIcon(fish, label, params);
|
this.icon = new WandaIcon(fish, label, params);
|
||||||
|
|
||||||
@ -133,10 +131,9 @@ function capitalize(str) {
|
|||||||
|
|
||||||
const WandaSearchProvider = new Lang.Class({
|
const WandaSearchProvider = new Lang.Class({
|
||||||
Name: 'WandaSearchProvider',
|
Name: 'WandaSearchProvider',
|
||||||
Extends: Search.SearchProvider,
|
|
||||||
|
|
||||||
_init: function() {
|
_init: function() {
|
||||||
this.parent(_("Your favorite Easter Egg"));
|
this.id = 'wanda';
|
||||||
},
|
},
|
||||||
|
|
||||||
getResultMetas: function(fish, callback) {
|
getResultMetas: function(fish, callback) {
|
||||||
|
@ -191,8 +191,10 @@ const WindowManager = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
addKeybinding: function(name, settings, flags, modes, handler) {
|
addKeybinding: function(name, settings, flags, modes, handler) {
|
||||||
if (global.display.add_keybinding(name, settings, flags, handler))
|
let action = global.display.add_keybinding(name, settings, flags, handler);
|
||||||
|
if (action != Meta.KeyBindingAction.NONE)
|
||||||
this.allowKeybinding(name, modes);
|
this.allowKeybinding(name, modes);
|
||||||
|
return action;
|
||||||
},
|
},
|
||||||
|
|
||||||
removeKeybinding: function(name) {
|
removeKeybinding: function(name) {
|
||||||
@ -219,7 +221,9 @@ const WindowManager = new Lang.Class({
|
|||||||
_shouldAnimateActor: function(actor) {
|
_shouldAnimateActor: function(actor) {
|
||||||
if (!this._shouldAnimate())
|
if (!this._shouldAnimate())
|
||||||
return false;
|
return false;
|
||||||
return actor.meta_window.get_window_type() == Meta.WindowType.NORMAL;
|
let windowType = actor.meta_window.get_window_type();
|
||||||
|
return windowType == Meta.WindowType.NORMAL ||
|
||||||
|
windowType == Meta.WindowType.MODAL_DIALOG;
|
||||||
},
|
},
|
||||||
|
|
||||||
_removeEffect : function(list, actor) {
|
_removeEffect : function(list, actor) {
|
||||||
@ -245,16 +249,17 @@ const WindowManager = new Lang.Class({
|
|||||||
*/
|
*/
|
||||||
this._minimizing.push(actor);
|
this._minimizing.push(actor);
|
||||||
|
|
||||||
let primary = Main.layoutManager.primaryMonitor;
|
let monitor = Main.layoutManager.findMonitorForWindow(actor.meta_window);
|
||||||
let xDest = primary.x;
|
let xDest = monitor.x;
|
||||||
|
let yDest = monitor.y;
|
||||||
if (Clutter.get_default_text_direction() == Clutter.TextDirection.RTL)
|
if (Clutter.get_default_text_direction() == Clutter.TextDirection.RTL)
|
||||||
xDest += primary.width;
|
xDest += monitor.width;
|
||||||
|
|
||||||
Tweener.addTween(actor,
|
Tweener.addTween(actor,
|
||||||
{ scale_x: 0.0,
|
{ scale_x: 0.0,
|
||||||
scale_y: 0.0,
|
scale_y: 0.0,
|
||||||
x: xDest,
|
x: xDest,
|
||||||
y: 0,
|
y: yDest,
|
||||||
time: WINDOW_ANIMATION_TIME,
|
time: WINDOW_ANIMATION_TIME,
|
||||||
transition: 'easeOutQuad',
|
transition: 'easeOutQuad',
|
||||||
onComplete: this._minimizeWindowDone,
|
onComplete: this._minimizeWindowDone,
|
||||||
@ -369,57 +374,56 @@ const WindowManager = new Lang.Class({
|
|||||||
|
|
||||||
actor._windowType = type;
|
actor._windowType = type;
|
||||||
}));
|
}));
|
||||||
if (actor.meta_window.is_attached_dialog()) {
|
|
||||||
this._checkDimming(actor.get_meta_window().get_transient_for());
|
|
||||||
if (this._shouldAnimate()) {
|
|
||||||
actor.set_scale(1.0, 0.0);
|
|
||||||
actor.scale_gravity = Clutter.Gravity.CENTER;
|
|
||||||
actor.show();
|
|
||||||
this._mapping.push(actor);
|
|
||||||
|
|
||||||
Tweener.addTween(actor,
|
|
||||||
{ scale_y: 1,
|
|
||||||
time: WINDOW_ANIMATION_TIME,
|
|
||||||
transition: "easeOutQuad",
|
|
||||||
onComplete: this._mapWindowDone,
|
|
||||||
onCompleteScope: this,
|
|
||||||
onCompleteParams: [shellwm, actor],
|
|
||||||
onOverwrite: this._mapWindowOverwrite,
|
|
||||||
onOverwriteScope: this,
|
|
||||||
onOverwriteParams: [shellwm, actor]
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
shellwm.completed_map(actor);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!this._shouldAnimateActor(actor)) {
|
if (!this._shouldAnimateActor(actor)) {
|
||||||
shellwm.completed_map(actor);
|
shellwm.completed_map(actor);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
actor.opacity = 0;
|
if (actor.meta_window.is_attached_dialog()) {
|
||||||
actor.show();
|
/* Scale the window from the center of the parent */
|
||||||
|
this._checkDimming(actor.get_meta_window().get_transient_for());
|
||||||
|
actor.set_scale(1.0, 0.0);
|
||||||
|
actor.scale_gravity = Clutter.Gravity.CENTER;
|
||||||
|
actor.show();
|
||||||
|
this._mapping.push(actor);
|
||||||
|
|
||||||
/* Fade window in */
|
Tweener.addTween(actor,
|
||||||
this._mapping.push(actor);
|
{ scale_y: 1,
|
||||||
Tweener.addTween(actor,
|
time: WINDOW_ANIMATION_TIME,
|
||||||
{ opacity: 255,
|
transition: "easeOutQuad",
|
||||||
time: WINDOW_ANIMATION_TIME,
|
onComplete: this._mapWindowDone,
|
||||||
transition: 'easeOutQuad',
|
onCompleteScope: this,
|
||||||
onComplete: this._mapWindowDone,
|
onCompleteParams: [shellwm, actor],
|
||||||
onCompleteScope: this,
|
onOverwrite: this._mapWindowOverwrite,
|
||||||
onCompleteParams: [shellwm, actor],
|
onOverwriteScope: this,
|
||||||
onOverwrite: this._mapWindowOverwrite,
|
onOverwriteParams: [shellwm, actor]
|
||||||
onOverwriteScope: this,
|
});
|
||||||
onOverwriteParams: [shellwm, actor]
|
} else {
|
||||||
});
|
/* Fade window in */
|
||||||
|
actor.opacity = 0;
|
||||||
|
actor.show();
|
||||||
|
this._mapping.push(actor);
|
||||||
|
|
||||||
|
Tweener.addTween(actor,
|
||||||
|
{ opacity: 255,
|
||||||
|
time: WINDOW_ANIMATION_TIME,
|
||||||
|
transition: 'easeOutQuad',
|
||||||
|
onComplete: this._mapWindowDone,
|
||||||
|
onCompleteScope: this,
|
||||||
|
onCompleteParams: [shellwm, actor],
|
||||||
|
onOverwrite: this._mapWindowOverwrite,
|
||||||
|
onOverwriteScope: this,
|
||||||
|
onOverwriteParams: [shellwm, actor]
|
||||||
|
});
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
_mapWindowDone : function(shellwm, actor) {
|
_mapWindowDone : function(shellwm, actor) {
|
||||||
if (this._removeEffect(this._mapping, actor)) {
|
if (this._removeEffect(this._mapping, actor)) {
|
||||||
Tweener.removeTweens(actor);
|
Tweener.removeTweens(actor);
|
||||||
actor.opacity = 255;
|
actor.opacity = 255;
|
||||||
|
actor.scale_y = 1;
|
||||||
shellwm.completed_map(actor);
|
shellwm.completed_map(actor);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -441,18 +445,21 @@ const WindowManager = new Lang.Class({
|
|||||||
return win != window;
|
return win != window;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!this._shouldAnimateActor(actor)) {
|
||||||
|
shellwm.completed_destroy(actor);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._destroying.push(actor);
|
||||||
|
|
||||||
if (window.is_attached_dialog()) {
|
if (window.is_attached_dialog()) {
|
||||||
let parent = window.get_transient_for();
|
let parent = window.get_transient_for();
|
||||||
this._checkDimming(parent, window);
|
this._checkDimming(parent, window);
|
||||||
if (!this._shouldAnimate()) {
|
|
||||||
shellwm.completed_destroy(actor);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
actor.set_scale(1.0, 1.0);
|
actor.set_scale(1.0, 1.0);
|
||||||
actor.scale_gravity = Clutter.Gravity.CENTER;
|
actor.scale_gravity = Clutter.Gravity.CENTER;
|
||||||
actor.show();
|
actor.show();
|
||||||
this._destroying.push(actor);
|
|
||||||
|
|
||||||
actor._parentDestroyId = parent.connect('unmanaged', Lang.bind(this, function () {
|
actor._parentDestroyId = parent.connect('unmanaged', Lang.bind(this, function () {
|
||||||
Tweener.removeTweens(actor);
|
Tweener.removeTweens(actor);
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
const Clutter = imports.gi.Clutter;
|
const Clutter = imports.gi.Clutter;
|
||||||
const Gio = imports.gi.Gio;
|
|
||||||
const Lang = imports.lang;
|
const Lang = imports.lang;
|
||||||
const Mainloop = imports.mainloop;
|
const Mainloop = imports.mainloop;
|
||||||
const Meta = imports.gi.Meta;
|
const Meta = imports.gi.Meta;
|
||||||
@ -30,9 +29,6 @@ const CLOSE_BUTTON_FADE_TIME = 0.1;
|
|||||||
|
|
||||||
const DRAGGING_WINDOW_OPACITY = 100;
|
const DRAGGING_WINDOW_OPACITY = 100;
|
||||||
|
|
||||||
const BUTTON_LAYOUT_SCHEMA = 'org.gnome.shell.overrides';
|
|
||||||
const BUTTON_LAYOUT_KEY = 'button-layout';
|
|
||||||
|
|
||||||
// When calculating a layout, we calculate the scale of windows and the percent
|
// When calculating a layout, we calculate the scale of windows and the percent
|
||||||
// of the available area the new layout uses. If the values for the new layout,
|
// of the available area the new layout uses. If the values for the new layout,
|
||||||
// when weighted with the values as below, are worse than the previous layout's,
|
// when weighted with the values as below, are worse than the previous layout's,
|
||||||
@ -124,6 +120,8 @@ const WindowClone = new Lang.Class({
|
|||||||
|
|
||||||
this.actor._delegate = this;
|
this.actor._delegate = this;
|
||||||
|
|
||||||
|
this._slot = [0, 0, 0, 0];
|
||||||
|
this._dragSlot = [0, 0, 0, 0];
|
||||||
this._stackAbove = null;
|
this._stackAbove = null;
|
||||||
|
|
||||||
this._sizeChangedId = this.realWindow.connect('size-changed',
|
this._sizeChangedId = this.realWindow.connect('size-changed',
|
||||||
@ -159,22 +157,15 @@ const WindowClone = new Lang.Class({
|
|||||||
this._selected = false;
|
this._selected = false;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
set slot(slot) {
|
||||||
|
this._slot = slot;
|
||||||
|
},
|
||||||
|
|
||||||
get slot() {
|
get slot() {
|
||||||
let x, y, w, h;
|
if (this.inDrag)
|
||||||
|
return this._dragSlot;
|
||||||
if (this.inDrag) {
|
else
|
||||||
x = this.dragOrigX;
|
return this._slot;
|
||||||
y = this.dragOrigY;
|
|
||||||
w = this.actor.width * this.dragOrigScale;
|
|
||||||
h = this.actor.height * this.dragOrigScale;
|
|
||||||
} else {
|
|
||||||
x = this.actor.x;
|
|
||||||
y = this.actor.y;
|
|
||||||
w = this.actor.width * this.actor.scale_x;
|
|
||||||
h = this.actor.height * this.actor.scale_y;
|
|
||||||
}
|
|
||||||
|
|
||||||
return [x, y, w, h];
|
|
||||||
},
|
},
|
||||||
|
|
||||||
setStackAbove: function (actor) {
|
setStackAbove: function (actor) {
|
||||||
@ -265,23 +256,37 @@ const WindowClone = new Lang.Class({
|
|||||||
|
|
||||||
_onScroll : function (actor, event) {
|
_onScroll : function (actor, event) {
|
||||||
let direction = event.get_scroll_direction();
|
let direction = event.get_scroll_direction();
|
||||||
if (direction == Clutter.ScrollDirection.UP) {
|
let delta;
|
||||||
|
|
||||||
|
if (event.is_pointer_emulated())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (direction == Clutter.ScrollDirection.DOWN) {
|
||||||
|
delta = -SCROLL_SCALE_AMOUNT;
|
||||||
|
} else if (direction == Clutter.ScrollDirection.UP) {
|
||||||
|
delta = +SCROLL_SCALE_AMOUNT;
|
||||||
|
} else if (direction == Clutter.ScrollDirection.SMOOTH) {
|
||||||
|
let [dx, dy] = event.get_scroll_delta();
|
||||||
|
delta = -dy * 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (delta > 0) {
|
||||||
if (this._zoomStep == undefined)
|
if (this._zoomStep == undefined)
|
||||||
this._zoomStart();
|
this._zoomStart();
|
||||||
if (this._zoomStep < 100) {
|
if (this._zoomStep < 100) {
|
||||||
this._zoomStep += SCROLL_SCALE_AMOUNT;
|
this._zoomStep += delta;
|
||||||
|
this._zoomStep = Math.min(100, this._zoomStep);
|
||||||
this._zoomUpdate();
|
this._zoomUpdate();
|
||||||
}
|
}
|
||||||
} else if (direction == Clutter.ScrollDirection.DOWN) {
|
} else if (delta < 0) {
|
||||||
if (this._zoomStep > 0) {
|
if (this._zoomStep > 0) {
|
||||||
this._zoomStep -= SCROLL_SCALE_AMOUNT;
|
this._zoomStep += delta;
|
||||||
this._zoomStep = Math.max(0, this._zoomStep);
|
this._zoomStep = Math.max(0, this._zoomStep);
|
||||||
this._zoomUpdate();
|
this._zoomUpdate();
|
||||||
}
|
}
|
||||||
if (this._zoomStep <= 0.0)
|
if (this._zoomStep <= 0.0)
|
||||||
this._zoomEnd();
|
this._zoomEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_zoomUpdate : function () {
|
_zoomUpdate : function () {
|
||||||
@ -392,6 +397,7 @@ const WindowClone = new Lang.Class({
|
|||||||
if (this._zooming)
|
if (this._zooming)
|
||||||
this._zoomEnd();
|
this._zoomEnd();
|
||||||
|
|
||||||
|
this._dragSlot = this._slot;
|
||||||
[this.dragOrigX, this.dragOrigY] = this.actor.get_position();
|
[this.dragOrigX, this.dragOrigY] = this.actor.get_position();
|
||||||
this.dragOrigScale = this.actor.scale_x;
|
this.dragOrigScale = this.actor.scale_x;
|
||||||
this.inDrag = true;
|
this.inDrag = true;
|
||||||
@ -456,11 +462,7 @@ const WindowOverlay = new Lang.Class({
|
|||||||
this._updateCaptionId = metaWindow.connect('notify::title',
|
this._updateCaptionId = metaWindow.connect('notify::title',
|
||||||
Lang.bind(this, function(w) {
|
Lang.bind(this, function(w) {
|
||||||
this.title.text = w.title;
|
this.title.text = w.title;
|
||||||
// we need this for the next call to get_preferred_width
|
this.relayout(false);
|
||||||
// to return useful results
|
|
||||||
this.title.set_size(-1, -1);
|
|
||||||
|
|
||||||
this._repositionSelf();
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
let button = new St.Button({ style_class: 'window-close' });
|
let button = new St.Button({ style_class: 'window-close' });
|
||||||
@ -535,35 +537,14 @@ const WindowOverlay = new Lang.Class({
|
|||||||
return [this.borderSize, this.borderSize];
|
return [this.borderSize, this.borderSize];
|
||||||
},
|
},
|
||||||
|
|
||||||
_repositionSelf: function() {
|
relayout: function(animate) {
|
||||||
let [cloneX, cloneY, cloneWidth, cloneHeight] = this._windowClone.slot;
|
let [cloneX, cloneY, cloneWidth, cloneHeight] = this._windowClone.slot;
|
||||||
this.updatePositions(cloneX, cloneY, cloneWidth, cloneHeight, false);
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @cloneX: x position of windowClone
|
|
||||||
* @cloneY: y position of windowClone
|
|
||||||
* @cloneWidth: width of windowClone
|
|
||||||
* @cloneHeight height of windowClone
|
|
||||||
*/
|
|
||||||
// These parameters are not the values retrieved with
|
|
||||||
// get_transformed_position() and get_transformed_size(),
|
|
||||||
// as windowClone might be moving.
|
|
||||||
// See Workspace._showWindowOverlay
|
|
||||||
updatePositions: function(cloneX, cloneY, cloneWidth, cloneHeight, animate) {
|
|
||||||
let button = this.closeButton;
|
let button = this.closeButton;
|
||||||
let title = this.title;
|
let title = this.title;
|
||||||
|
|
||||||
let settings = new Gio.Settings({ schema: BUTTON_LAYOUT_SCHEMA });
|
let layout = Meta.prefs_get_button_layout();
|
||||||
let layout = settings.get_string(BUTTON_LAYOUT_KEY);
|
let side = layout.left_buttons.indexOf(Meta.ButtonFunction.CLOSE) > -1 ? St.Side.LEFT : St.Side.RIGHT;
|
||||||
let rtl = Clutter.get_default_text_direction() == Clutter.TextDirection.RTL;
|
|
||||||
|
|
||||||
let split = layout.split(":");
|
|
||||||
let side;
|
|
||||||
if (split[0].indexOf("close") > -1)
|
|
||||||
side = rtl ? St.Side.RIGHT : St.Side.LEFT;
|
|
||||||
else
|
|
||||||
side = rtl ? St.Side.LEFT : St.Side.RIGHT;
|
|
||||||
|
|
||||||
let buttonX;
|
let buttonX;
|
||||||
let buttonY = cloneY - (button.height - button._overlap);
|
let buttonY = cloneY - (button.height - button._overlap);
|
||||||
@ -577,8 +558,16 @@ const WindowOverlay = new Lang.Class({
|
|||||||
else
|
else
|
||||||
button.set_position(Math.floor(buttonX), Math.floor(buttonY));
|
button.set_position(Math.floor(buttonX), Math.floor(buttonY));
|
||||||
|
|
||||||
|
// Clutter.Actor.get_preferred_width() will return the fixed width if one
|
||||||
|
// is set, so we need to reset the width by calling set_width(-1), to forward
|
||||||
|
// the call down to StLabel.
|
||||||
|
// We also need to save and restore the current width, otherwise the animation
|
||||||
|
// starts from the wrong point.
|
||||||
|
let prevTitleWidth = title.width;
|
||||||
|
title.set_width(-1);
|
||||||
let [titleMinWidth, titleNatWidth] = title.get_preferred_width(-1);
|
let [titleMinWidth, titleNatWidth] = title.get_preferred_width(-1);
|
||||||
let titleWidth = Math.max(titleMinWidth, Math.min(titleNatWidth, cloneWidth));
|
let titleWidth = Math.max(titleMinWidth, Math.min(titleNatWidth, cloneWidth));
|
||||||
|
title.width = prevTitleWidth;
|
||||||
|
|
||||||
let titleX = cloneX + (cloneWidth - titleWidth) / 2;
|
let titleX = cloneX + (cloneWidth - titleWidth) / 2;
|
||||||
let titleY = cloneY + cloneHeight + title._spacing;
|
let titleY = cloneY + cloneHeight + title._spacing;
|
||||||
@ -1184,8 +1173,8 @@ const Workspace = new Lang.Class({
|
|||||||
let slot = slots[i];
|
let slot = slots[i];
|
||||||
let clone = clones[i];
|
let clone = clones[i];
|
||||||
let metaWindow = clone.metaWindow;
|
let metaWindow = clone.metaWindow;
|
||||||
let mainIndex = this._lookupIndex(metaWindow);
|
let overlay = clone.overlay;
|
||||||
let overlay = this._windowOverlays[mainIndex];
|
clone.slotId = i;
|
||||||
|
|
||||||
// Positioning a window currently being dragged must be avoided;
|
// Positioning a window currently being dragged must be avoided;
|
||||||
// we'll just leave a blank spot in the layout for it.
|
// we'll just leave a blank spot in the layout for it.
|
||||||
@ -1193,6 +1182,7 @@ const Workspace = new Lang.Class({
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
let [x, y, scale] = slot;
|
let [x, y, scale] = slot;
|
||||||
|
clone.slot = [x, y, clone.actor.width * scale, clone.actor.height * scale];
|
||||||
|
|
||||||
if (overlay && initialPositioning)
|
if (overlay && initialPositioning)
|
||||||
overlay.hide();
|
overlay.hide();
|
||||||
@ -1224,7 +1214,7 @@ const Workspace = new Lang.Class({
|
|||||||
Tweener.removeTweens(clone.actor);
|
Tweener.removeTweens(clone.actor);
|
||||||
clone.actor.set_position(x, y);
|
clone.actor.set_position(x, y);
|
||||||
clone.actor.set_scale(scale, scale);
|
clone.actor.set_scale(scale, scale);
|
||||||
this._updateWindowOverlayPositions(clone, overlay, x, y, scale, false);
|
clone.overlay.relayout(false);
|
||||||
this._showWindowOverlay(clone, overlay, isOnCurrentWorkspace);
|
this._showWindowOverlay(clone, overlay, isOnCurrentWorkspace);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1259,15 +1249,7 @@ const Workspace = new Lang.Class({
|
|||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
this._updateWindowOverlayPositions(clone, overlay, x, y, scale, true);
|
clone.overlay.relayout(true);
|
||||||
},
|
|
||||||
|
|
||||||
_updateWindowOverlayPositions: function(clone, overlay, x, y, scale, animate) {
|
|
||||||
if (!overlay)
|
|
||||||
return;
|
|
||||||
|
|
||||||
let [cloneWidth, cloneHeight] = clone.actor.get_size();
|
|
||||||
overlay.updatePositions(x, y, cloneWidth * scale, cloneHeight * scale, animate);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_showWindowOverlay: function(clone, overlay, fade) {
|
_showWindowOverlay: function(clone, overlay, fade) {
|
||||||
@ -1402,9 +1384,10 @@ const Workspace = new Lang.Class({
|
|||||||
let scale = win._overviewHint.scale;
|
let scale = win._overviewHint.scale;
|
||||||
delete win._overviewHint;
|
delete win._overviewHint;
|
||||||
|
|
||||||
|
clone.slot = [x, y, clone.actor.width * scale, clone.actor.height * scale];
|
||||||
clone.actor.set_position (x, y);
|
clone.actor.set_position (x, y);
|
||||||
clone.actor.set_scale (scale, scale);
|
clone.actor.set_scale (scale, scale);
|
||||||
this._updateWindowOverlayPositions(clone, overlay, x, y, scale, false);
|
clone.overlay.relayout(false);
|
||||||
} else {
|
} else {
|
||||||
// Position new windows at the top corner of the workspace rather
|
// Position new windows at the top corner of the workspace rather
|
||||||
// than where they were placed for real to avoid the window
|
// than where they were placed for real to avoid the window
|
||||||
@ -1569,6 +1552,7 @@ const Workspace = new Lang.Class({
|
|||||||
_addWindowClone : function(win) {
|
_addWindowClone : function(win) {
|
||||||
let clone = new WindowClone(win, this);
|
let clone = new WindowClone(win, this);
|
||||||
let overlay = new WindowOverlay(clone, this._windowOverlaysGroup);
|
let overlay = new WindowOverlay(clone, this._windowOverlaysGroup);
|
||||||
|
clone.overlay = overlay;
|
||||||
|
|
||||||
clone.connect('selected',
|
clone.connect('selected',
|
||||||
Lang.bind(this, this._onCloneSelected));
|
Lang.bind(this, this._onCloneSelected));
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
const Clutter = imports.gi.Clutter;
|
const Clutter = imports.gi.Clutter;
|
||||||
|
const Gio = imports.gi.Gio;
|
||||||
const Lang = imports.lang;
|
const Lang = imports.lang;
|
||||||
const Mainloop = imports.mainloop;
|
const Mainloop = imports.mainloop;
|
||||||
const Meta = imports.gi.Meta;
|
const Meta = imports.gi.Meta;
|
||||||
@ -27,6 +28,8 @@ const WORKSPACE_CUT_SIZE = 10;
|
|||||||
|
|
||||||
const WORKSPACE_KEEP_ALIVE_TIME = 100;
|
const WORKSPACE_KEEP_ALIVE_TIME = 100;
|
||||||
|
|
||||||
|
const OVERRIDE_SCHEMA = 'org.gnome.shell.overrides';
|
||||||
|
|
||||||
const WindowClone = new Lang.Class({
|
const WindowClone = new Lang.Class({
|
||||||
Name: 'WindowClone',
|
Name: 'WindowClone',
|
||||||
|
|
||||||
@ -541,6 +544,12 @@ const ThumbnailsBox = new Lang.Class({
|
|||||||
|
|
||||||
this.actor.connect('button-press-event', function() { return true; });
|
this.actor.connect('button-press-event', function() { return true; });
|
||||||
this.actor.connect('button-release-event', Lang.bind(this, this._onButtonRelease));
|
this.actor.connect('button-release-event', Lang.bind(this, this._onButtonRelease));
|
||||||
|
this.actor.connect('scroll-event', Lang.bind(this, this._onScrollEvent));
|
||||||
|
|
||||||
|
Main.overview.connect('showing',
|
||||||
|
Lang.bind(this, this._createThumbnails));
|
||||||
|
Main.overview.connect('hidden',
|
||||||
|
Lang.bind(this, this._destroyThumbnails));
|
||||||
|
|
||||||
Main.overview.connect('item-drag-begin',
|
Main.overview.connect('item-drag-begin',
|
||||||
Lang.bind(this, this._onDragBegin));
|
Lang.bind(this, this._onDragBegin));
|
||||||
@ -554,6 +563,16 @@ const ThumbnailsBox = new Lang.Class({
|
|||||||
Lang.bind(this, this._onDragEnd));
|
Lang.bind(this, this._onDragEnd));
|
||||||
Main.overview.connect('window-drag-cancelled',
|
Main.overview.connect('window-drag-cancelled',
|
||||||
Lang.bind(this, this._onDragCancelled));
|
Lang.bind(this, this._onDragCancelled));
|
||||||
|
|
||||||
|
this._settings = new Gio.Settings({ schema: OVERRIDE_SCHEMA });
|
||||||
|
this._settings.connect('changed::dynamic-workspaces',
|
||||||
|
Lang.bind(this, this._updateSwitcherVisibility));
|
||||||
|
},
|
||||||
|
|
||||||
|
_updateSwitcherVisibility: function() {
|
||||||
|
this.actor.visible =
|
||||||
|
this._settings.get_boolean('dynamic-workspaces') ||
|
||||||
|
global.screen.n_workspaces > 1;
|
||||||
},
|
},
|
||||||
|
|
||||||
_onButtonRelease: function(actor, event) {
|
_onButtonRelease: function(actor, event) {
|
||||||
@ -719,10 +738,16 @@ const ThumbnailsBox = new Lang.Class({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
show: function() {
|
_createThumbnails: function() {
|
||||||
this._switchWorkspaceNotifyId =
|
this._switchWorkspaceNotifyId =
|
||||||
global.window_manager.connect('switch-workspace',
|
global.window_manager.connect('switch-workspace',
|
||||||
Lang.bind(this, this._activeWorkspaceChanged));
|
Lang.bind(this, this._activeWorkspaceChanged));
|
||||||
|
this._nWorkspacesNotifyId =
|
||||||
|
global.screen.connect('notify::n-workspaces',
|
||||||
|
Lang.bind(this, this._workspacesChanged));
|
||||||
|
this._syncStackingId =
|
||||||
|
Main.overview.connect('windows-restacked',
|
||||||
|
Lang.bind(this, this._syncStacking));
|
||||||
|
|
||||||
this._targetScale = 0;
|
this._targetScale = 0;
|
||||||
this._scale = 0;
|
this._scale = 0;
|
||||||
@ -744,19 +769,54 @@ const ThumbnailsBox = new Lang.Class({
|
|||||||
};
|
};
|
||||||
|
|
||||||
this.addThumbnails(0, global.screen.n_workspaces);
|
this.addThumbnails(0, global.screen.n_workspaces);
|
||||||
|
|
||||||
|
this._updateSwitcherVisibility();
|
||||||
},
|
},
|
||||||
|
|
||||||
hide: function() {
|
_destroyThumbnails: function() {
|
||||||
if (this._switchWorkspaceNotifyId > 0) {
|
if (this._switchWorkspaceNotifyId > 0) {
|
||||||
global.window_manager.disconnect(this._switchWorkspaceNotifyId);
|
global.window_manager.disconnect(this._switchWorkspaceNotifyId);
|
||||||
this._switchWorkspaceNotifyId = 0;
|
this._switchWorkspaceNotifyId = 0;
|
||||||
}
|
}
|
||||||
|
if (this._nWorkspacesNotifyId > 0) {
|
||||||
|
global.screen.disconnect(this._nWorkspacesNotifyId);
|
||||||
|
this._nWorkspacesNotifyId = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this._syncStackingId > 0) {
|
||||||
|
Main.overview.disconnect(this._syncStackingId);
|
||||||
|
this._syncStackingId = 0;
|
||||||
|
}
|
||||||
|
|
||||||
for (let w = 0; w < this._thumbnails.length; w++)
|
for (let w = 0; w < this._thumbnails.length; w++)
|
||||||
this._thumbnails[w].destroy();
|
this._thumbnails[w].destroy();
|
||||||
this._thumbnails = [];
|
this._thumbnails = [];
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_workspacesChanged: function() {
|
||||||
|
let oldNumWorkspaces = this._thumbnails.length;
|
||||||
|
let newNumWorkspaces = global.screen.n_workspaces;
|
||||||
|
let active = global.screen.get_active_workspace_index();
|
||||||
|
|
||||||
|
if (newNumWorkspaces > oldNumWorkspaces) {
|
||||||
|
this.addThumbnails(oldNumWorkspaces, newNumWorkspaces - oldNumWorkspaces);
|
||||||
|
} else {
|
||||||
|
let removedIndex;
|
||||||
|
let removedNum = oldNumWorkspaces - newNumWorkspaces;
|
||||||
|
for (let w = 0; w < oldNumWorkspaces; w++) {
|
||||||
|
let metaWorkspace = global.screen.get_workspace_by_index(w);
|
||||||
|
if (this._thumbnails[w].metaWorkspace != metaWorkspace) {
|
||||||
|
removedIndex = w;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.removeThumbnails(removedIndex, removedNum);
|
||||||
|
}
|
||||||
|
|
||||||
|
this._updateSwitcherVisibility();
|
||||||
|
},
|
||||||
|
|
||||||
addThumbnails: function(start, count) {
|
addThumbnails: function(start, count) {
|
||||||
for (let k = start; k < start + count; k++) {
|
for (let k = start; k < start + count; k++) {
|
||||||
let metaWorkspace = global.screen.get_workspace_by_index(k);
|
let metaWorkspace = global.screen.get_workspace_by_index(k);
|
||||||
@ -802,7 +862,7 @@ const ThumbnailsBox = new Lang.Class({
|
|||||||
this._queueUpdateStates();
|
this._queueUpdateStates();
|
||||||
},
|
},
|
||||||
|
|
||||||
syncStacking: function(stackIndices) {
|
_syncStacking: function(overview, stackIndices) {
|
||||||
for (let i = 0; i < this._thumbnails.length; i++)
|
for (let i = 0; i < this._thumbnails.length; i++)
|
||||||
this._thumbnails[i].syncStacking(stackIndices);
|
this._thumbnails[i].syncStacking(stackIndices);
|
||||||
},
|
},
|
||||||
@ -1157,5 +1217,16 @@ const ThumbnailsBox = new Lang.Class({
|
|||||||
},
|
},
|
||||||
onCompleteScope: this
|
onCompleteScope: this
|
||||||
});
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
_onScrollEvent: function (actor, event) {
|
||||||
|
switch (event.get_scroll_direction()) {
|
||||||
|
case Clutter.ScrollDirection.UP:
|
||||||
|
Main.wm.actionMoveWorkspace(Meta.MotionDirection.UP);
|
||||||
|
break;
|
||||||
|
case Clutter.ScrollDirection.DOWN:
|
||||||
|
Main.wm.actionMoveWorkspace(Meta.MotionDirection.DOWN);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -69,7 +69,7 @@ const WorkspacesView = new Lang.Class({
|
|||||||
|
|
||||||
// Add workspace actors
|
// Add workspace actors
|
||||||
for (let w = 0; w < global.screen.n_workspaces; w++)
|
for (let w = 0; w < global.screen.n_workspaces; w++)
|
||||||
this._workspaces[w].actor.reparent(this.actor);
|
this.actor.add_actor(this._workspaces[w].actor);
|
||||||
this._workspaces[activeWorkspaceIndex].actor.raise_top();
|
this._workspaces[activeWorkspaceIndex].actor.raise_top();
|
||||||
|
|
||||||
this._extraWorkspaces = [];
|
this._extraWorkspaces = [];
|
||||||
@ -129,11 +129,10 @@ const WorkspacesView = new Lang.Class({
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
let ws = new Workspace.Workspace(null, i);
|
let ws = new Workspace.Workspace(null, i);
|
||||||
let overviewSpacing = Main.overview._spacing;
|
ws.setGeometry(monitors[i].x,
|
||||||
ws.setGeometry(monitors[i].x + overviewSpacing/2,
|
monitors[i].y,
|
||||||
monitors[i].y + overviewSpacing/2,
|
monitors[i].width,
|
||||||
monitors[i].width - overviewSpacing,
|
monitors[i].height);
|
||||||
monitors[i].height - overviewSpacing);
|
|
||||||
global.overlay_group.add_actor(ws.actor);
|
global.overlay_group.add_actor(ws.actor);
|
||||||
this._extraWorkspaces.push(ws);
|
this._extraWorkspaces.push(ws);
|
||||||
}
|
}
|
||||||
@ -438,13 +437,24 @@ const WorkspacesDisplay = new Lang.Class({
|
|||||||
Name: 'WorkspacesDisplay',
|
Name: 'WorkspacesDisplay',
|
||||||
|
|
||||||
_init: function() {
|
_init: function() {
|
||||||
this.actor = new Shell.GenericContainer();
|
this.actor = new Shell.GenericContainer({ style_class: 'workspaces-display' });
|
||||||
this.actor.connect('get-preferred-width', Lang.bind(this, this._getPreferredWidth));
|
this.actor.connect('get-preferred-width', Lang.bind(this, this._getPreferredWidth));
|
||||||
this.actor.connect('get-preferred-height', Lang.bind(this, this._getPreferredHeight));
|
this.actor.connect('get-preferred-height', Lang.bind(this, this._getPreferredHeight));
|
||||||
this.actor.connect('allocate', Lang.bind(this, this._allocate));
|
this.actor.connect('allocate', Lang.bind(this, this._allocate));
|
||||||
this.actor.connect('parent-set', Lang.bind(this, this._parentSet));
|
this.actor.connect('parent-set', Lang.bind(this, this._parentSet));
|
||||||
this.actor.set_clip_to_allocation(true);
|
this.actor.set_clip_to_allocation(true);
|
||||||
|
|
||||||
|
this._spacing = 0;
|
||||||
|
this.actor.connect('style-changed', Lang.bind(this,
|
||||||
|
function() {
|
||||||
|
let node = this.actor.get_theme_node();
|
||||||
|
let spacing = node.get_length('spacing');
|
||||||
|
if (spacing != this._spacing) {
|
||||||
|
this._spacing = spacing;
|
||||||
|
this._updateWorkspacesGeometry();
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
let clickAction = new Clutter.ClickAction()
|
let clickAction = new Clutter.ClickAction()
|
||||||
clickAction.connect('clicked', Lang.bind(this, function(action) {
|
clickAction.connect('clicked', Lang.bind(this, function(action) {
|
||||||
// Only switch to the workspace when there's no application
|
// Only switch to the workspace when there's no application
|
||||||
@ -483,15 +493,14 @@ const WorkspacesDisplay = new Lang.Class({
|
|||||||
controls.track_hover = true;
|
controls.track_hover = true;
|
||||||
controls.connect('notify::hover',
|
controls.connect('notify::hover',
|
||||||
Lang.bind(this, this._onControlsHoverChanged));
|
Lang.bind(this, this._onControlsHoverChanged));
|
||||||
controls.connect('scroll-event',
|
|
||||||
Lang.bind(this, this._onScrollEvent));
|
|
||||||
|
|
||||||
this._primaryIndex = Main.layoutManager.primaryIndex;
|
this._primaryIndex = Main.layoutManager.primaryIndex;
|
||||||
|
|
||||||
this._thumbnailsBox = new WorkspaceThumbnail.ThumbnailsBox();
|
this._thumbnailsBox = new WorkspaceThumbnail.ThumbnailsBox();
|
||||||
controls.add_actor(this._thumbnailsBox.actor);
|
controls.add_actor(this._thumbnailsBox.actor);
|
||||||
|
|
||||||
this._workspacesViews = null;
|
this._workspacesViews = [];
|
||||||
|
this._workspaces = [];
|
||||||
this._primaryScrollAdjustment = null;
|
this._primaryScrollAdjustment = null;
|
||||||
|
|
||||||
this._settings = new Gio.Settings({ schema: OVERRIDE_SCHEMA });
|
this._settings = new Gio.Settings({ schema: OVERRIDE_SCHEMA });
|
||||||
@ -537,10 +546,6 @@ const WorkspacesDisplay = new Lang.Class({
|
|||||||
this._notifyOpacityId = 0;
|
this._notifyOpacityId = 0;
|
||||||
this._swipeScrollBeginId = 0;
|
this._swipeScrollBeginId = 0;
|
||||||
this._swipeScrollEndId = 0;
|
this._swipeScrollEndId = 0;
|
||||||
|
|
||||||
this._settings = new Gio.Settings({ schema: OVERRIDE_SCHEMA });
|
|
||||||
this._settings.connect('changed::dynamic-workspaces',
|
|
||||||
Lang.bind(this, this._updateSwitcherVisibility));
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_onPan: function(action) {
|
_onPan: function(action) {
|
||||||
@ -550,12 +555,6 @@ const WorkspacesDisplay = new Lang.Class({
|
|||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
|
|
||||||
_updateSwitcherVisibility: function() {
|
|
||||||
this._thumbnailsBox.actor.visible =
|
|
||||||
this._settings.get_boolean('dynamic-workspaces') ||
|
|
||||||
global.screen.n_workspaces > 1;
|
|
||||||
},
|
|
||||||
|
|
||||||
show: function() {
|
show: function() {
|
||||||
if(!this._alwaysZoomOut) {
|
if(!this._alwaysZoomOut) {
|
||||||
let [mouseX, mouseY] = global.get_pointer();
|
let [mouseX, mouseY] = global.get_pointer();
|
||||||
@ -575,13 +574,11 @@ const WorkspacesDisplay = new Lang.Class({
|
|||||||
this._updateZoom();
|
this._updateZoom();
|
||||||
|
|
||||||
this._controls.show();
|
this._controls.show();
|
||||||
this._thumbnailsBox.show();
|
|
||||||
this._updateSwitcherVisibility();
|
|
||||||
|
|
||||||
this._updateWorkspacesViews();
|
this._updateWorkspacesViews();
|
||||||
|
|
||||||
this._restackedNotifyId =
|
this._restackedNotifyId =
|
||||||
global.screen.connect('restacked',
|
Main.overview.connect('windows-restacked',
|
||||||
Lang.bind(this, this._onRestacked));
|
Lang.bind(this, this._onRestacked));
|
||||||
|
|
||||||
if (this._itemDragBeginId == 0)
|
if (this._itemDragBeginId == 0)
|
||||||
@ -602,8 +599,6 @@ const WorkspacesDisplay = new Lang.Class({
|
|||||||
if (this._windowDragEndId == 0)
|
if (this._windowDragEndId == 0)
|
||||||
this._windowDragEndId = Main.overview.connect('window-drag-end',
|
this._windowDragEndId = Main.overview.connect('window-drag-end',
|
||||||
Lang.bind(this, this._dragEnd));
|
Lang.bind(this, this._dragEnd));
|
||||||
|
|
||||||
this._onRestacked();
|
|
||||||
},
|
},
|
||||||
|
|
||||||
zoomFromOverview: function() {
|
zoomFromOverview: function() {
|
||||||
@ -614,13 +609,12 @@ const WorkspacesDisplay = new Lang.Class({
|
|||||||
|
|
||||||
hide: function() {
|
hide: function() {
|
||||||
this._controls.hide();
|
this._controls.hide();
|
||||||
this._thumbnailsBox.hide();
|
|
||||||
|
|
||||||
if (!this._alwaysZoomOut)
|
if (!this._alwaysZoomOut)
|
||||||
this.zoomFraction = 0;
|
this.zoomFraction = 0;
|
||||||
|
|
||||||
if (this._restackedNotifyId > 0){
|
if (this._restackedNotifyId > 0){
|
||||||
global.screen.disconnect(this._restackedNotifyId);
|
Main.overview.disconnect(this._restackedNotifyId);
|
||||||
this._restackedNotifyId = 0;
|
this._restackedNotifyId = 0;
|
||||||
}
|
}
|
||||||
if (this._itemDragBeginId > 0) {
|
if (this._itemDragBeginId > 0) {
|
||||||
@ -650,7 +644,7 @@ const WorkspacesDisplay = new Lang.Class({
|
|||||||
|
|
||||||
for (let i = 0; i < this._workspacesViews.length; i++)
|
for (let i = 0; i < this._workspacesViews.length; i++)
|
||||||
this._workspacesViews[i].destroy();
|
this._workspacesViews[i].destroy();
|
||||||
this._workspacesViews = null;
|
this._workspacesViews = [];
|
||||||
|
|
||||||
for (let i = 0; i < this._workspaces.length; i++)
|
for (let i = 0; i < this._workspaces.length; i++)
|
||||||
for (let w = 0; w < this._workspaces[i].length; w++) {
|
for (let w = 0; w < this._workspaces[i].length; w++) {
|
||||||
@ -669,14 +663,12 @@ const WorkspacesDisplay = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
_updateWorkspacesViews: function() {
|
_updateWorkspacesViews: function() {
|
||||||
if (this._workspacesViews)
|
for (let i = 0; i < this._workspacesViews.length; i++)
|
||||||
for (let i = 0; i < this._workspacesViews.length; i++)
|
this._workspacesViews[i].destroy();
|
||||||
this._workspacesViews[i].destroy();
|
|
||||||
|
|
||||||
if (this._workspaces)
|
for (let i = 0; i < this._workspaces.length; i++)
|
||||||
for (let i = 0; i < this._workspaces.length; i++)
|
for (let w = 0; w < this._workspaces[i].length; w++)
|
||||||
for (let w = 0; w < this._workspaces[i].length; w++)
|
this._workspaces[i][w].destroy();
|
||||||
this._workspaces[i][w].destroy();
|
|
||||||
|
|
||||||
this._workspacesViews = [];
|
this._workspacesViews = [];
|
||||||
this._workspaces = [];
|
this._workspaces = [];
|
||||||
@ -724,7 +716,7 @@ const WorkspacesDisplay = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
_getPrimaryView: function() {
|
_getPrimaryView: function() {
|
||||||
if (!this._workspacesViews)
|
if (!this._workspacesViews.length)
|
||||||
return null;
|
return null;
|
||||||
if (this._workspacesOnlyOnPrimary)
|
if (this._workspacesOnlyOnPrimary)
|
||||||
return this._workspacesViews[0];
|
return this._workspacesViews[0];
|
||||||
@ -833,7 +825,7 @@ const WorkspacesDisplay = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
_updateWorkspacesGeometry: function() {
|
_updateWorkspacesGeometry: function() {
|
||||||
if (!this._workspacesViews)
|
if (!this._workspacesViews.length)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
let fullWidth = this.actor.allocation.x2 - this.actor.allocation.x1;
|
let fullWidth = this.actor.allocation.x2 - this.actor.allocation.x1;
|
||||||
@ -854,9 +846,8 @@ const WorkspacesDisplay = new Lang.Class({
|
|||||||
let clipX = rtl ? x + controlsVisible : x;
|
let clipX = rtl ? x + controlsVisible : x;
|
||||||
let clipY = y + (fullHeight - clipHeight) / 2;
|
let clipY = y + (fullHeight - clipHeight) / 2;
|
||||||
|
|
||||||
let overviewSpacing = Main.overview._spacing;
|
|
||||||
let widthAdjust = this._zoomOut ? controlsNatural : controlsVisible;
|
let widthAdjust = this._zoomOut ? controlsNatural : controlsVisible;
|
||||||
widthAdjust += overviewSpacing;
|
widthAdjust += this._spacing;
|
||||||
width -= widthAdjust;
|
width -= widthAdjust;
|
||||||
if (rtl)
|
if (rtl)
|
||||||
x += widthAdjust;
|
x += widthAdjust;
|
||||||
@ -874,35 +865,25 @@ const WorkspacesDisplay = new Lang.Class({
|
|||||||
monitors[i].y,
|
monitors[i].y,
|
||||||
monitors[i].width,
|
monitors[i].width,
|
||||||
monitors[i].height);
|
monitors[i].height);
|
||||||
this._workspacesViews[m].setGeometry(monitors[i].x + overviewSpacing/2,
|
this._workspacesViews[m].setGeometry(monitors[i].x,
|
||||||
monitors[i].y + overviewSpacing/2,
|
monitors[i].y,
|
||||||
monitors[i].width - overviewSpacing,
|
monitors[i].width,
|
||||||
monitors[i].height - overviewSpacing);
|
monitors[i].height);
|
||||||
m++;
|
m++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
_onRestacked: function() {
|
_onRestacked: function(overview, stackIndices) {
|
||||||
let stack = global.get_window_actors();
|
|
||||||
let stackIndices = {};
|
|
||||||
|
|
||||||
for (let i = 0; i < stack.length; i++) {
|
|
||||||
// Use the stable sequence for an integer to use as a hash key
|
|
||||||
stackIndices[stack[i].get_meta_window().get_stable_sequence()] = i;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (let i = 0; i < this._workspacesViews.length; i++)
|
for (let i = 0; i < this._workspacesViews.length; i++)
|
||||||
this._workspacesViews[i].syncStacking(stackIndices);
|
this._workspacesViews[i].syncStacking(stackIndices);
|
||||||
|
|
||||||
this._thumbnailsBox.syncStacking(stackIndices);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_workspacesChanged: function() {
|
_workspacesChanged: function() {
|
||||||
this._updateAlwaysZoom();
|
this._updateAlwaysZoom();
|
||||||
this._updateZoom();
|
this._updateZoom();
|
||||||
|
|
||||||
if (this._workspacesViews == null)
|
if (!this._workspacesViews.length)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
let oldNumWorkspaces = this._workspaces[0].length;
|
let oldNumWorkspaces = this._workspaces[0].length;
|
||||||
@ -926,8 +907,6 @@ const WorkspacesDisplay = new Lang.Class({
|
|||||||
}
|
}
|
||||||
m++;
|
m++;
|
||||||
}
|
}
|
||||||
|
|
||||||
this._thumbnailsBox.addThumbnails(oldNumWorkspaces, newNumWorkspaces - oldNumWorkspaces);
|
|
||||||
} else {
|
} else {
|
||||||
// Assume workspaces are only removed sequentially
|
// Assume workspaces are only removed sequentially
|
||||||
// (e.g. 2,3,4 - not 2,4,7)
|
// (e.g. 2,3,4 - not 2,4,7)
|
||||||
@ -950,14 +929,11 @@ const WorkspacesDisplay = new Lang.Class({
|
|||||||
lostWorkspaces[l].destroy();
|
lostWorkspaces[l].destroy();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this._thumbnailsBox.removeThumbnails(removedIndex, removedNum);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let i = 0; i < this._workspacesViews.length; i++)
|
for (let i = 0; i < this._workspacesViews.length; i++)
|
||||||
this._workspacesViews[i].updateWorkspaces(oldNumWorkspaces,
|
this._workspacesViews[i].updateWorkspaces(oldNumWorkspaces,
|
||||||
newNumWorkspaces);
|
newNumWorkspaces);
|
||||||
this._updateSwitcherVisibility();
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_updateZoom : function() {
|
_updateZoom : function() {
|
||||||
@ -969,7 +945,7 @@ const WorkspacesDisplay = new Lang.Class({
|
|||||||
this._zoomOut = shouldZoom;
|
this._zoomOut = shouldZoom;
|
||||||
this._updateWorkspacesGeometry();
|
this._updateWorkspacesGeometry();
|
||||||
|
|
||||||
if (!this._workspacesViews)
|
if (!this._workspacesViews.length)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Tweener.addTween(this,
|
Tweener.addTween(this,
|
||||||
@ -1020,17 +996,6 @@ const WorkspacesDisplay = new Lang.Class({
|
|||||||
// might as well avoid it.
|
// might as well avoid it.
|
||||||
Meta.later_add(Meta.LaterType.BEFORE_REDRAW,
|
Meta.later_add(Meta.LaterType.BEFORE_REDRAW,
|
||||||
Lang.bind(this, this._updateZoom));
|
Lang.bind(this, this._updateZoom));
|
||||||
},
|
|
||||||
|
|
||||||
_onScrollEvent: function (actor, event) {
|
|
||||||
switch ( event.get_scroll_direction() ) {
|
|
||||||
case Clutter.ScrollDirection.UP:
|
|
||||||
Main.wm.actionMoveWorkspace(Meta.MotionDirection.UP);
|
|
||||||
break;
|
|
||||||
case Clutter.ScrollDirection.DOWN:
|
|
||||||
Main.wm.actionMoveWorkspace(Meta.MotionDirection.DOWN);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
Signals.addSignalMethods(WorkspacesDisplay.prototype);
|
Signals.addSignalMethods(WorkspacesDisplay.prototype);
|
||||||
|
237
po/ar.po
237
po/ar.po
@ -8,7 +8,7 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: HEAD\n"
|
"Project-Id-Version: HEAD\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2012-12-09 04:45+0200\n"
|
"POT-Creation-Date: 2012-12-23 18:34+0200\n"
|
||||||
"PO-Revision-Date: 2012-12-09 04:52+0200\n"
|
"PO-Revision-Date: 2012-12-09 04:52+0200\n"
|
||||||
"Last-Translator: Khaled Hosny <khaledhosny@eglug.org>\n"
|
"Last-Translator: Khaled Hosny <khaledhosny@eglug.org>\n"
|
||||||
"Language-Team: Arabic <doc@arabeyes.org>\n"
|
"Language-Team: Arabic <doc@arabeyes.org>\n"
|
||||||
@ -365,8 +365,8 @@ msgstr "نافذة الولوج"
|
|||||||
msgid "Power"
|
msgid "Power"
|
||||||
msgstr "الطاقة"
|
msgstr "الطاقة"
|
||||||
|
|
||||||
#: ../js/gdm/powerMenu.js:93 ../js/ui/userMenu.js:674 ../js/ui/userMenu.js:678
|
#: ../js/gdm/powerMenu.js:93 ../js/ui/userMenu.js:675 ../js/ui/userMenu.js:679
|
||||||
#: ../js/ui/userMenu.js:789
|
#: ../js/ui/userMenu.js:790
|
||||||
msgid "Suspend"
|
msgid "Suspend"
|
||||||
msgstr "علّق"
|
msgstr "علّق"
|
||||||
|
|
||||||
@ -374,8 +374,8 @@ msgstr "علّق"
|
|||||||
msgid "Restart"
|
msgid "Restart"
|
||||||
msgstr "أعِد التشغيل"
|
msgstr "أعِد التشغيل"
|
||||||
|
|
||||||
#: ../js/gdm/powerMenu.js:103 ../js/ui/userMenu.js:676
|
#: ../js/gdm/powerMenu.js:103 ../js/ui/userMenu.js:677
|
||||||
#: ../js/ui/userMenu.js:678 ../js/ui/userMenu.js:788
|
#: ../js/ui/userMenu.js:679 ../js/ui/userMenu.js:789
|
||||||
msgid "Power Off"
|
msgid "Power Off"
|
||||||
msgstr "أطفئ الحاسوب"
|
msgstr "أطفئ الحاسوب"
|
||||||
|
|
||||||
@ -410,27 +410,19 @@ msgid "Execution of '%s' failed:"
|
|||||||
msgstr "فشل تنفيذ '%s':"
|
msgstr "فشل تنفيذ '%s':"
|
||||||
|
|
||||||
#. Translators: Filter to display all applications
|
#. Translators: Filter to display all applications
|
||||||
#: ../js/ui/appDisplay.js:259
|
#: ../js/ui/appDisplay.js:258
|
||||||
msgid "All"
|
msgid "All"
|
||||||
msgstr "الكل"
|
msgstr "الكل"
|
||||||
|
|
||||||
#: ../js/ui/appDisplay.js:318
|
#: ../js/ui/appDisplay.js:666
|
||||||
msgid "APPLICATIONS"
|
|
||||||
msgstr "التطبيقات"
|
|
||||||
|
|
||||||
#: ../js/ui/appDisplay.js:375
|
|
||||||
msgid "SETTINGS"
|
|
||||||
msgstr "الإعدادات"
|
|
||||||
|
|
||||||
#: ../js/ui/appDisplay.js:679
|
|
||||||
msgid "New Window"
|
msgid "New Window"
|
||||||
msgstr "نافذة جديدة"
|
msgstr "نافذة جديدة"
|
||||||
|
|
||||||
#: ../js/ui/appDisplay.js:682 ../js/ui/dash.js:289
|
#: ../js/ui/appDisplay.js:669 ../js/ui/dash.js:289
|
||||||
msgid "Remove from Favorites"
|
msgid "Remove from Favorites"
|
||||||
msgstr "أزِل من المفضّلة"
|
msgstr "أزِل من المفضّلة"
|
||||||
|
|
||||||
#: ../js/ui/appDisplay.js:683
|
#: ../js/ui/appDisplay.js:670
|
||||||
msgid "Add to Favorites"
|
msgid "Add to Favorites"
|
||||||
msgstr "أضِف إلى المفضّلة"
|
msgstr "أضِف إلى المفضّلة"
|
||||||
|
|
||||||
@ -447,19 +439,19 @@ msgstr "أُزيل %s من مفضّلتك."
|
|||||||
#. Translators: Shown in calendar event list for all day events
|
#. Translators: Shown in calendar event list for all day events
|
||||||
#. * Keep it short, best if you can use less then 10 characters
|
#. * Keep it short, best if you can use less then 10 characters
|
||||||
#.
|
#.
|
||||||
#: ../js/ui/calendar.js:62
|
#: ../js/ui/calendar.js:61
|
||||||
msgctxt "event list time"
|
msgctxt "event list time"
|
||||||
msgid "All Day"
|
msgid "All Day"
|
||||||
msgstr "طوال اليوم"
|
msgstr "طوال اليوم"
|
||||||
|
|
||||||
#. Translators: Shown in calendar event list, if 24h format
|
#. Translators: Shown in calendar event list, if 24h format
|
||||||
#: ../js/ui/calendar.js:67
|
#: ../js/ui/calendar.js:66
|
||||||
msgctxt "event list time"
|
msgctxt "event list time"
|
||||||
msgid "%H:%M"
|
msgid "%H:%M"
|
||||||
msgstr "%H:%M"
|
msgstr "%H:%M"
|
||||||
|
|
||||||
#. Transators: Shown in calendar event list, if 12h format
|
#. Transators: Shown in calendar event list, if 12h format
|
||||||
#: ../js/ui/calendar.js:74
|
#: ../js/ui/calendar.js:73
|
||||||
msgctxt "event list time"
|
msgctxt "event list time"
|
||||||
msgid "%l:%M %p"
|
msgid "%l:%M %p"
|
||||||
msgstr "%l:%M %p"
|
msgstr "%l:%M %p"
|
||||||
@ -469,43 +461,43 @@ msgstr "%l:%M %p"
|
|||||||
#. * NOTE: These grid abbreviations are always shown together
|
#. * NOTE: These grid abbreviations are always shown together
|
||||||
#. * and in order, e.g. "S M T W T F S".
|
#. * and in order, e.g. "S M T W T F S".
|
||||||
#.
|
#.
|
||||||
#: ../js/ui/calendar.js:114
|
#: ../js/ui/calendar.js:104
|
||||||
msgctxt "grid sunday"
|
msgctxt "grid sunday"
|
||||||
msgid "S"
|
msgid "S"
|
||||||
msgstr "ح"
|
msgstr "ح"
|
||||||
|
|
||||||
#. Translators: Calendar grid abbreviation for Monday
|
#. Translators: Calendar grid abbreviation for Monday
|
||||||
#: ../js/ui/calendar.js:116
|
#: ../js/ui/calendar.js:106
|
||||||
msgctxt "grid monday"
|
msgctxt "grid monday"
|
||||||
msgid "M"
|
msgid "M"
|
||||||
msgstr "ن"
|
msgstr "ن"
|
||||||
|
|
||||||
#. Translators: Calendar grid abbreviation for Tuesday
|
#. Translators: Calendar grid abbreviation for Tuesday
|
||||||
#: ../js/ui/calendar.js:118
|
#: ../js/ui/calendar.js:108
|
||||||
msgctxt "grid tuesday"
|
msgctxt "grid tuesday"
|
||||||
msgid "T"
|
msgid "T"
|
||||||
msgstr "ث"
|
msgstr "ث"
|
||||||
|
|
||||||
#. Translators: Calendar grid abbreviation for Wednesday
|
#. Translators: Calendar grid abbreviation for Wednesday
|
||||||
#: ../js/ui/calendar.js:120
|
#: ../js/ui/calendar.js:110
|
||||||
msgctxt "grid wednesday"
|
msgctxt "grid wednesday"
|
||||||
msgid "W"
|
msgid "W"
|
||||||
msgstr "ر"
|
msgstr "ر"
|
||||||
|
|
||||||
#. Translators: Calendar grid abbreviation for Thursday
|
#. Translators: Calendar grid abbreviation for Thursday
|
||||||
#: ../js/ui/calendar.js:122
|
#: ../js/ui/calendar.js:112
|
||||||
msgctxt "grid thursday"
|
msgctxt "grid thursday"
|
||||||
msgid "T"
|
msgid "T"
|
||||||
msgstr "خ"
|
msgstr "خ"
|
||||||
|
|
||||||
#. Translators: Calendar grid abbreviation for Friday
|
#. Translators: Calendar grid abbreviation for Friday
|
||||||
#: ../js/ui/calendar.js:124
|
#: ../js/ui/calendar.js:114
|
||||||
msgctxt "grid friday"
|
msgctxt "grid friday"
|
||||||
msgid "F"
|
msgid "F"
|
||||||
msgstr "ج"
|
msgstr "ج"
|
||||||
|
|
||||||
#. Translators: Calendar grid abbreviation for Saturday
|
#. Translators: Calendar grid abbreviation for Saturday
|
||||||
#: ../js/ui/calendar.js:126
|
#: ../js/ui/calendar.js:116
|
||||||
msgctxt "grid saturday"
|
msgctxt "grid saturday"
|
||||||
msgid "S"
|
msgid "S"
|
||||||
msgstr "س"
|
msgstr "س"
|
||||||
@ -516,77 +508,77 @@ msgstr "س"
|
|||||||
#. * so they need to be unique (e.g. Tuesday and Thursday cannot
|
#. * so they need to be unique (e.g. Tuesday and Thursday cannot
|
||||||
#. * both be 'T').
|
#. * both be 'T').
|
||||||
#.
|
#.
|
||||||
#: ../js/ui/calendar.js:139
|
#: ../js/ui/calendar.js:129
|
||||||
msgctxt "list sunday"
|
msgctxt "list sunday"
|
||||||
msgid "Su"
|
msgid "Su"
|
||||||
msgstr "الأحد"
|
msgstr "الأحد"
|
||||||
|
|
||||||
#. Translators: Event list abbreviation for Monday
|
#. Translators: Event list abbreviation for Monday
|
||||||
#: ../js/ui/calendar.js:141
|
#: ../js/ui/calendar.js:131
|
||||||
msgctxt "list monday"
|
msgctxt "list monday"
|
||||||
msgid "M"
|
msgid "M"
|
||||||
msgstr "الاثنين"
|
msgstr "الاثنين"
|
||||||
|
|
||||||
#. Translators: Event list abbreviation for Tuesday
|
#. Translators: Event list abbreviation for Tuesday
|
||||||
#: ../js/ui/calendar.js:143
|
#: ../js/ui/calendar.js:133
|
||||||
msgctxt "list tuesday"
|
msgctxt "list tuesday"
|
||||||
msgid "T"
|
msgid "T"
|
||||||
msgstr "الثلاثاء"
|
msgstr "الثلاثاء"
|
||||||
|
|
||||||
#. Translators: Event list abbreviation for Wednesday
|
#. Translators: Event list abbreviation for Wednesday
|
||||||
#: ../js/ui/calendar.js:145
|
#: ../js/ui/calendar.js:135
|
||||||
msgctxt "list wednesday"
|
msgctxt "list wednesday"
|
||||||
msgid "W"
|
msgid "W"
|
||||||
msgstr "الأربعاء"
|
msgstr "الأربعاء"
|
||||||
|
|
||||||
#. Translators: Event list abbreviation for Thursday
|
#. Translators: Event list abbreviation for Thursday
|
||||||
#: ../js/ui/calendar.js:147
|
#: ../js/ui/calendar.js:137
|
||||||
msgctxt "list thursday"
|
msgctxt "list thursday"
|
||||||
msgid "Th"
|
msgid "Th"
|
||||||
msgstr "الخميس"
|
msgstr "الخميس"
|
||||||
|
|
||||||
#. Translators: Event list abbreviation for Friday
|
#. Translators: Event list abbreviation for Friday
|
||||||
#: ../js/ui/calendar.js:149
|
#: ../js/ui/calendar.js:139
|
||||||
msgctxt "list friday"
|
msgctxt "list friday"
|
||||||
msgid "F"
|
msgid "F"
|
||||||
msgstr "الجمعة"
|
msgstr "الجمعة"
|
||||||
|
|
||||||
#. Translators: Event list abbreviation for Saturday
|
#. Translators: Event list abbreviation for Saturday
|
||||||
#: ../js/ui/calendar.js:151
|
#: ../js/ui/calendar.js:141
|
||||||
msgctxt "list saturday"
|
msgctxt "list saturday"
|
||||||
msgid "S"
|
msgid "S"
|
||||||
msgstr "السبت"
|
msgstr "السبت"
|
||||||
|
|
||||||
#. Translators: Text to show if there are no events
|
#. Translators: Text to show if there are no events
|
||||||
#: ../js/ui/calendar.js:700
|
#: ../js/ui/calendar.js:674
|
||||||
msgid "Nothing Scheduled"
|
msgid "Nothing Scheduled"
|
||||||
msgstr "الجدول خال"
|
msgstr "الجدول خال"
|
||||||
|
|
||||||
#. Translators: Shown on calendar heading when selected day occurs on current year
|
#. Translators: Shown on calendar heading when selected day occurs on current year
|
||||||
#: ../js/ui/calendar.js:716
|
#: ../js/ui/calendar.js:690
|
||||||
msgctxt "calendar heading"
|
msgctxt "calendar heading"
|
||||||
msgid "%A, %B %d"
|
msgid "%A, %B %d"
|
||||||
msgstr "%A %d %B"
|
msgstr "%A %d %B"
|
||||||
|
|
||||||
#. Translators: Shown on calendar heading when selected day occurs on different year
|
#. Translators: Shown on calendar heading when selected day occurs on different year
|
||||||
#: ../js/ui/calendar.js:719
|
#: ../js/ui/calendar.js:693
|
||||||
msgctxt "calendar heading"
|
msgctxt "calendar heading"
|
||||||
msgid "%A, %B %d, %Y"
|
msgid "%A, %B %d, %Y"
|
||||||
msgstr "%A %d %B %Y"
|
msgstr "%A %d %B %Y"
|
||||||
|
|
||||||
#: ../js/ui/calendar.js:729
|
#: ../js/ui/calendar.js:703
|
||||||
msgid "Today"
|
msgid "Today"
|
||||||
msgstr "اليوم"
|
msgstr "اليوم"
|
||||||
|
|
||||||
#: ../js/ui/calendar.js:733
|
#: ../js/ui/calendar.js:707
|
||||||
msgid "Tomorrow"
|
msgid "Tomorrow"
|
||||||
msgstr "غدا"
|
msgstr "غدا"
|
||||||
|
|
||||||
#: ../js/ui/calendar.js:744
|
#: ../js/ui/calendar.js:718
|
||||||
msgid "This week"
|
msgid "This week"
|
||||||
msgstr "هذا الأسبوع"
|
msgstr "هذا الأسبوع"
|
||||||
|
|
||||||
#: ../js/ui/calendar.js:752
|
#: ../js/ui/calendar.js:726
|
||||||
msgid "Next week"
|
msgid "Next week"
|
||||||
msgstr "الأسبوع القادم"
|
msgstr "الأسبوع القادم"
|
||||||
|
|
||||||
@ -948,7 +940,7 @@ msgstr "أظهر الحساب"
|
|||||||
msgid "Unknown reason"
|
msgid "Unknown reason"
|
||||||
msgstr "السبب غير معروف"
|
msgstr "السبب غير معروف"
|
||||||
|
|
||||||
#: ../js/ui/ctrlAltTab.js:29 ../js/ui/viewSelector.js:87
|
#: ../js/ui/ctrlAltTab.js:29 ../js/ui/viewSelector.js:81
|
||||||
msgid "Windows"
|
msgid "Windows"
|
||||||
msgstr "النوافذ"
|
msgstr "النوافذ"
|
||||||
|
|
||||||
@ -1088,7 +1080,7 @@ msgstr "هل تريد تنزيل وتثبيت '%s' من extensions.gnome.org؟"
|
|||||||
msgid "tray"
|
msgid "tray"
|
||||||
msgstr "لوحة النظام"
|
msgstr "لوحة النظام"
|
||||||
|
|
||||||
#: ../js/ui/keyboard.js:555 ../js/ui/status/keyboard.js:195
|
#: ../js/ui/keyboard.js:555 ../js/ui/status/keyboard.js:309
|
||||||
#: ../js/ui/status/power.js:205
|
#: ../js/ui/status/power.js:205
|
||||||
msgid "Keyboard"
|
msgid "Keyboard"
|
||||||
msgstr "لوحة المفاتيح"
|
msgstr "لوحة المفاتيح"
|
||||||
@ -1115,7 +1107,9 @@ msgstr "اظهر الأخطاء"
|
|||||||
msgid "Enabled"
|
msgid "Enabled"
|
||||||
msgstr "مفعّل"
|
msgstr "مفعّل"
|
||||||
|
|
||||||
#: ../js/ui/lookingGlass.js:767
|
#. translators:
|
||||||
|
#. * The device has been disabled
|
||||||
|
#: ../js/ui/lookingGlass.js:767 ../src/gvc/gvc-mixer-control.c:1830
|
||||||
msgid "Disabled"
|
msgid "Disabled"
|
||||||
msgstr "معطّل"
|
msgstr "معطّل"
|
||||||
|
|
||||||
@ -1147,15 +1141,15 @@ msgstr "افتح"
|
|||||||
msgid "Remove"
|
msgid "Remove"
|
||||||
msgstr "أزِل"
|
msgstr "أزِل"
|
||||||
|
|
||||||
#: ../js/ui/messageTray.js:1551
|
#: ../js/ui/messageTray.js:1552
|
||||||
msgid "No Messages"
|
msgid "No Messages"
|
||||||
msgstr "لا رسائل"
|
msgstr "لا رسائل"
|
||||||
|
|
||||||
#: ../js/ui/messageTray.js:1568
|
#: ../js/ui/messageTray.js:1570
|
||||||
msgid "Message Tray"
|
msgid "Message Tray"
|
||||||
msgstr "لوحة الرسائل"
|
msgstr "لوحة الرسائل"
|
||||||
|
|
||||||
#: ../js/ui/messageTray.js:2635
|
#: ../js/ui/messageTray.js:2639
|
||||||
msgid "System Information"
|
msgid "System Information"
|
||||||
msgstr "معلومات النظام"
|
msgstr "معلومات النظام"
|
||||||
|
|
||||||
@ -1164,11 +1158,11 @@ msgctxt "program"
|
|||||||
msgid "Unknown"
|
msgid "Unknown"
|
||||||
msgstr "غير معروف"
|
msgstr "غير معروف"
|
||||||
|
|
||||||
#: ../js/ui/overview.js:95
|
#: ../js/ui/overview.js:92
|
||||||
msgid "Undo"
|
msgid "Undo"
|
||||||
msgstr "تراجع"
|
msgstr "تراجع"
|
||||||
|
|
||||||
#: ../js/ui/overview.js:144
|
#: ../js/ui/overview.js:139
|
||||||
msgid "Overview"
|
msgid "Overview"
|
||||||
msgstr "نظرة عامة"
|
msgstr "نظرة عامة"
|
||||||
|
|
||||||
@ -1176,13 +1170,13 @@ msgstr "نظرة عامة"
|
|||||||
#. in the search entry when no search is
|
#. in the search entry when no search is
|
||||||
#. active; it should not exceed ~30
|
#. active; it should not exceed ~30
|
||||||
#. characters.
|
#. characters.
|
||||||
#: ../js/ui/overview.js:221
|
#: ../js/ui/overview.js:218
|
||||||
msgid "Type to search..."
|
msgid "Type to search..."
|
||||||
msgstr "اكتب نصا للبحث عنه..."
|
msgstr "اكتب نصا للبحث عنه..."
|
||||||
|
|
||||||
#. Translators: this is the name of the dock/favorites area on
|
#. Translators: this is the name of the dock/favorites area on
|
||||||
#. the left of the overview
|
#. the left of the overview
|
||||||
#: ../js/ui/overview.js:242
|
#: ../js/ui/overview.js:236
|
||||||
msgid "Dash"
|
msgid "Dash"
|
||||||
msgstr "الشريط"
|
msgstr "الشريط"
|
||||||
|
|
||||||
@ -1205,7 +1199,7 @@ msgstr "الشريط العلوي"
|
|||||||
#. "ON" and "OFF") or "toggle-switch-intl" (for toggle
|
#. "ON" and "OFF") or "toggle-switch-intl" (for toggle
|
||||||
#. switches containing "◯" and "|"). Other values will
|
#. switches containing "◯" and "|"). Other values will
|
||||||
#. simply result in invisible toggle switches.
|
#. simply result in invisible toggle switches.
|
||||||
#: ../js/ui/popupMenu.js:732
|
#: ../js/ui/popupMenu.js:725
|
||||||
msgid "toggle-switch-us"
|
msgid "toggle-switch-us"
|
||||||
msgstr "toggle-switch-intl"
|
msgstr "toggle-switch-intl"
|
||||||
|
|
||||||
@ -1245,15 +1239,15 @@ msgstr[3] "%d تنبيهات جديدة"
|
|||||||
msgstr[4] "%d تنبيها جديدا"
|
msgstr[4] "%d تنبيها جديدا"
|
||||||
msgstr[5] "%d تنبيه جديد"
|
msgstr[5] "%d تنبيه جديد"
|
||||||
|
|
||||||
#: ../js/ui/screenShield.js:402 ../js/ui/userMenu.js:780
|
#: ../js/ui/screenShield.js:402 ../js/ui/userMenu.js:781
|
||||||
msgid "Lock"
|
msgid "Lock"
|
||||||
msgstr "أوصِد"
|
msgstr "أوصِد"
|
||||||
|
|
||||||
#: ../js/ui/searchDisplay.js:277
|
#: ../js/ui/searchDisplay.js:403
|
||||||
msgid "Searching..."
|
msgid "Searching..."
|
||||||
msgstr "يبحث..."
|
msgstr "يبحث..."
|
||||||
|
|
||||||
#: ../js/ui/searchDisplay.js:325
|
#: ../js/ui/searchDisplay.js:451
|
||||||
msgid "No results."
|
msgid "No results."
|
||||||
msgstr "لا نتائج."
|
msgstr "لا نتائج."
|
||||||
|
|
||||||
@ -1369,7 +1363,7 @@ msgid "disconnecting..."
|
|||||||
msgstr "يقطع الاتّصال..."
|
msgstr "يقطع الاتّصال..."
|
||||||
|
|
||||||
#: ../js/ui/status/bluetooth.js:220 ../js/ui/status/network.js:442
|
#: ../js/ui/status/bluetooth.js:220 ../js/ui/status/network.js:442
|
||||||
#: ../js/ui/status/network.js:1453
|
#: ../js/ui/status/network.js:1464
|
||||||
msgid "connecting..."
|
msgid "connecting..."
|
||||||
msgstr "يتّصل..."
|
msgstr "يتّصل..."
|
||||||
|
|
||||||
@ -1385,7 +1379,7 @@ msgstr "إعدادات لوحة المفاتيح"
|
|||||||
msgid "Mouse Settings"
|
msgid "Mouse Settings"
|
||||||
msgstr "إعدادات الفأرة"
|
msgstr "إعدادات الفأرة"
|
||||||
|
|
||||||
#: ../js/ui/status/bluetooth.js:253 ../js/ui/status/volume.js:270
|
#: ../js/ui/status/bluetooth.js:253 ../js/ui/status/volume.js:314
|
||||||
msgid "Sound Settings"
|
msgid "Sound Settings"
|
||||||
msgstr "إعدادات الصوت"
|
msgstr "إعدادات الصوت"
|
||||||
|
|
||||||
@ -1449,15 +1443,15 @@ msgstr "من فضلك أدخل الرقم المذكور على الجهاز."
|
|||||||
msgid "OK"
|
msgid "OK"
|
||||||
msgstr "حسنا"
|
msgstr "حسنا"
|
||||||
|
|
||||||
#: ../js/ui/status/keyboard.js:228
|
#: ../js/ui/status/keyboard.js:363
|
||||||
msgid "Show Keyboard Layout"
|
msgid "Show Keyboard Layout"
|
||||||
msgstr "أظهر تخطيط لوحة المفاتيح"
|
msgstr "أظهر تخطيط لوحة المفاتيح"
|
||||||
|
|
||||||
#: ../js/ui/status/keyboard.js:233
|
#: ../js/ui/status/keyboard.js:368
|
||||||
msgid "Region and Language Settings"
|
msgid "Region and Language Settings"
|
||||||
msgstr "إعدادات الإقليم واللغة"
|
msgstr "إعدادات الإقليم واللغة"
|
||||||
|
|
||||||
#: ../js/ui/status/lockScreenMenu.js:18
|
#: ../js/ui/status/lockScreenMenu.js:43
|
||||||
msgid "Volume, network, battery"
|
msgid "Volume, network, battery"
|
||||||
msgstr "الصوت، الشبكة، البطارية"
|
msgstr "الصوت، الشبكة، البطارية"
|
||||||
|
|
||||||
@ -1477,7 +1471,7 @@ msgid "unmanaged"
|
|||||||
msgstr "غير مُدار"
|
msgstr "غير مُدار"
|
||||||
|
|
||||||
#. Translators: this is for network connections that require some kind of key or password
|
#. Translators: this is for network connections that require some kind of key or password
|
||||||
#: ../js/ui/status/network.js:445 ../js/ui/status/network.js:1456
|
#: ../js/ui/status/network.js:445 ../js/ui/status/network.js:1467
|
||||||
msgid "authentication required"
|
msgid "authentication required"
|
||||||
msgstr "الاستيثاق مطلوب"
|
msgstr "الاستيثاق مطلوب"
|
||||||
|
|
||||||
@ -1498,72 +1492,72 @@ msgstr "الكبل مفصول"
|
|||||||
msgid "unavailable"
|
msgid "unavailable"
|
||||||
msgstr "غير متاح"
|
msgstr "غير متاح"
|
||||||
|
|
||||||
#: ../js/ui/status/network.js:469 ../js/ui/status/network.js:1458
|
#: ../js/ui/status/network.js:469 ../js/ui/status/network.js:1469
|
||||||
msgid "connection failed"
|
msgid "connection failed"
|
||||||
msgstr "فشل الاتصال"
|
msgstr "فشل الاتصال"
|
||||||
|
|
||||||
#: ../js/ui/status/network.js:525 ../js/ui/status/network.js:1392
|
#: ../js/ui/status/network.js:525 ../js/ui/status/network.js:1403
|
||||||
#: ../js/ui/status/network.js:1534
|
#: ../js/ui/status/network.js:1545
|
||||||
msgid "More..."
|
msgid "More..."
|
||||||
msgstr "المزيد..."
|
msgstr "المزيد..."
|
||||||
|
|
||||||
#. TRANSLATORS: this is the indication that a connection for another logged in user is active,
|
#. TRANSLATORS: this is the indication that a connection for another logged in user is active,
|
||||||
#. and we cannot access its settings (including the name)
|
#. and we cannot access its settings (including the name)
|
||||||
#: ../js/ui/status/network.js:561 ../js/ui/status/network.js:1322
|
#: ../js/ui/status/network.js:561 ../js/ui/status/network.js:1333
|
||||||
msgid "Connected (private)"
|
msgid "Connected (private)"
|
||||||
msgstr "متّصل (شخصي)"
|
msgstr "متّصل (شخصي)"
|
||||||
|
|
||||||
#: ../js/ui/status/network.js:619
|
#: ../js/ui/status/network.js:641
|
||||||
msgid "Auto Ethernet"
|
msgid "Auto Ethernet"
|
||||||
msgstr "إيثرنت تلقائي"
|
msgstr "إيثرنت تلقائي"
|
||||||
|
|
||||||
#: ../js/ui/status/network.js:677
|
#: ../js/ui/status/network.js:688
|
||||||
msgid "Auto broadband"
|
msgid "Auto broadband"
|
||||||
msgstr "شبكة هاتف محمول تلقائية"
|
msgstr "شبكة هاتف محمول تلقائية"
|
||||||
|
|
||||||
#: ../js/ui/status/network.js:680
|
#: ../js/ui/status/network.js:691
|
||||||
msgid "Auto dial-up"
|
msgid "Auto dial-up"
|
||||||
msgstr "اتصال هاتفي تلقائي"
|
msgstr "اتصال هاتفي تلقائي"
|
||||||
|
|
||||||
#. TRANSLATORS: this the automatic wireless connection name (including the network name)
|
#. TRANSLATORS: this the automatic wireless connection name (including the network name)
|
||||||
#: ../js/ui/status/network.js:809 ../js/ui/status/network.js:1339
|
#: ../js/ui/status/network.js:820 ../js/ui/status/network.js:1350
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Auto %s"
|
msgid "Auto %s"
|
||||||
msgstr "%s تلقائي"
|
msgstr "%s تلقائي"
|
||||||
|
|
||||||
#: ../js/ui/status/network.js:811
|
#: ../js/ui/status/network.js:822
|
||||||
msgid "Auto bluetooth"
|
msgid "Auto bluetooth"
|
||||||
msgstr "بلوتوث تلقائي"
|
msgstr "بلوتوث تلقائي"
|
||||||
|
|
||||||
#: ../js/ui/status/network.js:1341
|
#: ../js/ui/status/network.js:1352
|
||||||
msgid "Auto wireless"
|
msgid "Auto wireless"
|
||||||
msgstr "لاسلكي تلقائي"
|
msgstr "لاسلكي تلقائي"
|
||||||
|
|
||||||
#: ../js/ui/status/network.js:1584
|
#: ../js/ui/status/network.js:1595
|
||||||
msgid "Enable networking"
|
msgid "Enable networking"
|
||||||
msgstr "فعّل الشبكات"
|
msgstr "فعّل الشبكات"
|
||||||
|
|
||||||
#: ../js/ui/status/network.js:1616
|
#: ../js/ui/status/network.js:1627
|
||||||
msgid "Wi-Fi"
|
msgid "Wi-Fi"
|
||||||
msgstr "واي فاي"
|
msgstr "واي فاي"
|
||||||
|
|
||||||
#: ../js/ui/status/network.js:1635
|
#: ../js/ui/status/network.js:1646
|
||||||
msgid "Network Settings"
|
msgid "Network Settings"
|
||||||
msgstr "إعدادات الشّبكة"
|
msgstr "إعدادات الشّبكة"
|
||||||
|
|
||||||
#: ../js/ui/status/network.js:1679
|
#: ../js/ui/status/network.js:1692
|
||||||
msgid "Network Manager"
|
msgid "Network Manager"
|
||||||
msgstr "مدير الشبكة"
|
msgstr "مدير الشبكة"
|
||||||
|
|
||||||
#: ../js/ui/status/network.js:1761
|
#: ../js/ui/status/network.js:1774
|
||||||
msgid "Connection failed"
|
msgid "Connection failed"
|
||||||
msgstr "فشل الاتصال"
|
msgstr "فشل الاتصال"
|
||||||
|
|
||||||
#: ../js/ui/status/network.js:1762
|
#: ../js/ui/status/network.js:1775
|
||||||
msgid "Activation of network connection failed"
|
msgid "Activation of network connection failed"
|
||||||
msgstr "فشل تفعيل اتصال الشبكة"
|
msgstr "فشل تفعيل اتصال الشبكة"
|
||||||
|
|
||||||
#: ../js/ui/status/network.js:2079
|
#: ../js/ui/status/network.js:2092
|
||||||
msgid "Networking is disabled"
|
msgid "Networking is disabled"
|
||||||
msgstr "عُطّلت الشبكات"
|
msgstr "عُطّلت الشبكات"
|
||||||
|
|
||||||
@ -1681,11 +1675,11 @@ msgid "Unknown"
|
|||||||
msgstr "غير معروف"
|
msgstr "غير معروف"
|
||||||
|
|
||||||
#. Translators: This is the label for audio volume
|
#. Translators: This is the label for audio volume
|
||||||
#: ../js/ui/status/volume.js:50 ../js/ui/status/volume.js:251
|
#: ../js/ui/status/volume.js:247 ../js/ui/status/volume.js:295
|
||||||
msgid "Volume"
|
msgid "Volume"
|
||||||
msgstr "شدة الصوت"
|
msgstr "شدة الصوت"
|
||||||
|
|
||||||
#: ../js/ui/status/volume.js:62
|
#: ../js/ui/status/volume.js:256
|
||||||
msgid "Microphone"
|
msgid "Microphone"
|
||||||
msgstr "ميكروفون"
|
msgstr "ميكروفون"
|
||||||
|
|
||||||
@ -1721,31 +1715,31 @@ msgstr "ساكن"
|
|||||||
msgid "Offline"
|
msgid "Offline"
|
||||||
msgstr "غير متصل"
|
msgstr "غير متصل"
|
||||||
|
|
||||||
#: ../js/ui/userMenu.js:754
|
#: ../js/ui/userMenu.js:755
|
||||||
msgid "Notifications"
|
msgid "Notifications"
|
||||||
msgstr "التنبيهات"
|
msgstr "التنبيهات"
|
||||||
|
|
||||||
#: ../js/ui/userMenu.js:762
|
#: ../js/ui/userMenu.js:763
|
||||||
msgid "Settings"
|
msgid "Settings"
|
||||||
msgstr "الإعدادات"
|
msgstr "الإعدادات"
|
||||||
|
|
||||||
#: ../js/ui/userMenu.js:770
|
#: ../js/ui/userMenu.js:771
|
||||||
msgid "Switch User"
|
msgid "Switch User"
|
||||||
msgstr "بدّل المستخدم"
|
msgstr "بدّل المستخدم"
|
||||||
|
|
||||||
#: ../js/ui/userMenu.js:775
|
#: ../js/ui/userMenu.js:776
|
||||||
msgid "Log Out"
|
msgid "Log Out"
|
||||||
msgstr "اخرج"
|
msgstr "اخرج"
|
||||||
|
|
||||||
#: ../js/ui/userMenu.js:795
|
#: ../js/ui/userMenu.js:796
|
||||||
msgid "Install Updates & Restart"
|
msgid "Install Updates & Restart"
|
||||||
msgstr "ثبّت التحديثات وأعد التشغيل"
|
msgstr "ثبّت التحديثات وأعد التشغيل"
|
||||||
|
|
||||||
#: ../js/ui/userMenu.js:813
|
#: ../js/ui/userMenu.js:814
|
||||||
msgid "Your chat status will be set to busy"
|
msgid "Your chat status will be set to busy"
|
||||||
msgstr "ستُجعل حالة اتصالك ”مشغول“"
|
msgstr "ستُجعل حالة اتصالك ”مشغول“"
|
||||||
|
|
||||||
#: ../js/ui/userMenu.js:814
|
#: ../js/ui/userMenu.js:815
|
||||||
msgid ""
|
msgid ""
|
||||||
"Notifications are now disabled, including chat messages. Your online status "
|
"Notifications are now disabled, including chat messages. Your online status "
|
||||||
"has been adjusted to let others know that you might not see their messages."
|
"has been adjusted to let others know that you might not see their messages."
|
||||||
@ -1753,15 +1747,15 @@ msgstr ""
|
|||||||
"التنبيهات معطلة الآن، بما فيها رسائل المحادثة. حالة اتصالك تغيرت حتى يعلم "
|
"التنبيهات معطلة الآن، بما فيها رسائل المحادثة. حالة اتصالك تغيرت حتى يعلم "
|
||||||
"الآخرون أنك قد لا ترى رسائلهم."
|
"الآخرون أنك قد لا ترى رسائلهم."
|
||||||
|
|
||||||
#: ../js/ui/viewSelector.js:91
|
#: ../js/ui/viewSelector.js:85
|
||||||
msgid "Applications"
|
msgid "Applications"
|
||||||
msgstr "التطبيقات"
|
msgstr "التطبيقات"
|
||||||
|
|
||||||
#: ../js/ui/viewSelector.js:95
|
#: ../js/ui/viewSelector.js:89
|
||||||
msgid "Search"
|
msgid "Search"
|
||||||
msgstr "ابحث"
|
msgstr "ابحث"
|
||||||
|
|
||||||
#: ../js/ui/wanda.js:94
|
#: ../js/ui/wanda.js:92
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"Sorry, no wisdom for you today:\n"
|
"Sorry, no wisdom for you today:\n"
|
||||||
@ -1770,15 +1764,11 @@ msgstr ""
|
|||||||
"عذرًا, لا حكمة لك اليوم:\n"
|
"عذرًا, لا حكمة لك اليوم:\n"
|
||||||
"%s"
|
"%s"
|
||||||
|
|
||||||
#: ../js/ui/wanda.js:98
|
#: ../js/ui/wanda.js:96
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%s the Oracle says"
|
msgid "%s the Oracle says"
|
||||||
msgstr "يقول الحكيم %s"
|
msgstr "يقول الحكيم %s"
|
||||||
|
|
||||||
#: ../js/ui/wanda.js:139
|
|
||||||
msgid "Your favorite Easter Egg"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: ../js/ui/windowAttentionHandler.js:19
|
#: ../js/ui/windowAttentionHandler.js:19
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "'%s' is ready"
|
msgid "'%s' is ready"
|
||||||
@ -1788,6 +1778,36 @@ msgstr "'%s' جاهز"
|
|||||||
msgid "Evolution Calendar"
|
msgid "Evolution Calendar"
|
||||||
msgstr "تقويم إيفُليوشِن"
|
msgstr "تقويم إيفُليوشِن"
|
||||||
|
|
||||||
|
#. translators:
|
||||||
|
#. * The number of sound outputs on a particular device
|
||||||
|
#: ../src/gvc/gvc-mixer-control.c:1837
|
||||||
|
#, c-format
|
||||||
|
msgid "%u Output"
|
||||||
|
msgid_plural "%u Outputs"
|
||||||
|
msgstr[0] "لا مخرَج"
|
||||||
|
msgstr[1] "مخرَج واحد"
|
||||||
|
msgstr[2] "مخرَجين"
|
||||||
|
msgstr[3] "%u مخارج"
|
||||||
|
msgstr[4] "%u مخرجا"
|
||||||
|
msgstr[5] "%u مخرج"
|
||||||
|
|
||||||
|
#. translators:
|
||||||
|
#. * The number of sound inputs on a particular device
|
||||||
|
#: ../src/gvc/gvc-mixer-control.c:1847
|
||||||
|
#, c-format
|
||||||
|
msgid "%u Input"
|
||||||
|
msgid_plural "%u Inputs"
|
||||||
|
msgstr[0] "لا مدخل"
|
||||||
|
msgstr[1] "مدخل واحد"
|
||||||
|
msgstr[2] "مدخلين"
|
||||||
|
msgstr[3] "%u مداخل"
|
||||||
|
msgstr[4] "%u مدخلا"
|
||||||
|
msgstr[5] "%u مدخل"
|
||||||
|
|
||||||
|
#: ../src/gvc/gvc-mixer-control.c:2371
|
||||||
|
msgid "System Sounds"
|
||||||
|
msgstr "أصوات النظام"
|
||||||
|
|
||||||
#: ../src/main.c:332
|
#: ../src/main.c:332
|
||||||
msgid "Print version"
|
msgid "Print version"
|
||||||
msgstr "اطبع الإصدارة"
|
msgstr "اطبع الإصدارة"
|
||||||
@ -1829,6 +1849,12 @@ msgstr "المبدئي"
|
|||||||
msgid "Authentication dialog was dismissed by the user"
|
msgid "Authentication dialog was dismissed by the user"
|
||||||
msgstr "أغلق المستخدم مربع الاستيثاق الحِواري"
|
msgstr "أغلق المستخدم مربع الاستيثاق الحِواري"
|
||||||
|
|
||||||
|
#~ msgid "APPLICATIONS"
|
||||||
|
#~ msgstr "التطبيقات"
|
||||||
|
|
||||||
|
#~ msgid "SETTINGS"
|
||||||
|
#~ msgstr "الإعدادات"
|
||||||
|
|
||||||
#~ msgid "Subscription request"
|
#~ msgid "Subscription request"
|
||||||
#~ msgstr "طلب اشتراك"
|
#~ msgstr "طلب اشتراك"
|
||||||
|
|
||||||
@ -1877,27 +1903,6 @@ msgstr "أغلق المستخدم مربع الاستيثاق الحِواري"
|
|||||||
#~ msgid "System Settings"
|
#~ msgid "System Settings"
|
||||||
#~ msgstr "إعدادات النظام"
|
#~ msgstr "إعدادات النظام"
|
||||||
|
|
||||||
#~ msgid "%u Output"
|
|
||||||
#~ msgid_plural "%u Outputs"
|
|
||||||
#~ msgstr[0] "لا مخرَج"
|
|
||||||
#~ msgstr[1] "مخرَج واحد"
|
|
||||||
#~ msgstr[2] "مخرَجين"
|
|
||||||
#~ msgstr[3] "%u مخارج"
|
|
||||||
#~ msgstr[4] "%u مخرجا"
|
|
||||||
#~ msgstr[5] "%u مخرج"
|
|
||||||
|
|
||||||
#~ msgid "%u Input"
|
|
||||||
#~ msgid_plural "%u Inputs"
|
|
||||||
#~ msgstr[0] "لا مدخل"
|
|
||||||
#~ msgstr[1] "مدخل واحد"
|
|
||||||
#~ msgstr[2] "مدخلين"
|
|
||||||
#~ msgstr[3] "%u مداخل"
|
|
||||||
#~ msgstr[4] "%u مدخلا"
|
|
||||||
#~ msgstr[5] "%u مدخل"
|
|
||||||
|
|
||||||
#~ msgid "System Sounds"
|
|
||||||
#~ msgstr "أصوات النظام"
|
|
||||||
|
|
||||||
#~ msgid "Failed to unmount '%s'"
|
#~ msgid "Failed to unmount '%s'"
|
||||||
#~ msgstr "فشل فصْل '%s'"
|
#~ msgstr "فشل فصْل '%s'"
|
||||||
|
|
||||||
|
173
po/et.po
173
po/et.po
@ -13,8 +13,8 @@ msgstr ""
|
|||||||
"Project-Id-Version: gnome-shell MASTER\n"
|
"Project-Id-Version: gnome-shell MASTER\n"
|
||||||
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-"
|
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-"
|
||||||
"shell&keywords=I18N+L10N&component=general\n"
|
"shell&keywords=I18N+L10N&component=general\n"
|
||||||
"POT-Creation-Date: 2012-11-16 18:27+0000\n"
|
"POT-Creation-Date: 2012-12-09 13:03+0000\n"
|
||||||
"PO-Revision-Date: 2012-11-16 20:40+0300\n"
|
"PO-Revision-Date: 2012-12-19 16:47+0300\n"
|
||||||
"Last-Translator: Mattias Põldaru <mahfiaz@gmail.com>\n"
|
"Last-Translator: Mattias Põldaru <mahfiaz@gmail.com>\n"
|
||||||
"Language-Team: Estonian <>\n"
|
"Language-Team: Estonian <>\n"
|
||||||
"Language: et\n"
|
"Language: et\n"
|
||||||
@ -135,6 +135,28 @@ msgstr ""
|
|||||||
"See võti keelab automaatse 'Logi välja' menüükirje peitmise, kui arvutis on "
|
"See võti keelab automaatse 'Logi välja' menüükirje peitmise, kui arvutis on "
|
||||||
"üks kasutaja ning avatud üks seanss."
|
"üks kasutaja ning avatud üks seanss."
|
||||||
|
|
||||||
|
msgid "Show full name in the user menu"
|
||||||
|
msgstr "Kasutajamenüüs näidatakse kasutaja tervet nime"
|
||||||
|
|
||||||
|
msgid "Whether the users full name is shown in the user menu or not."
|
||||||
|
msgstr "Kas kasutajamenüüs näidatakse kasutaja kogu nime või mitte."
|
||||||
|
|
||||||
|
msgid ""
|
||||||
|
"Whether to remember password for mounting encrypted or remote filesystems"
|
||||||
|
msgstr ""
|
||||||
|
"Kas pidada meeles krüpteeritud või kaugfailisüsteemide haakimise paroole."
|
||||||
|
|
||||||
|
msgid ""
|
||||||
|
"The shell will request a password when an encrypted device or a remote "
|
||||||
|
"filesystem is mounted. If the password can be saved for future use a "
|
||||||
|
"'Remember Password' checkbox will be present. This key sets the default "
|
||||||
|
"state of the checkbox."
|
||||||
|
msgstr ""
|
||||||
|
"Shell küsib parooli, kui haagitakse krüpteeritud seade või kaugfailisüsteem. "
|
||||||
|
"Kui parooli on võimalik salvestada edaspidiseks kasutuseks, näidatakse "
|
||||||
|
"'Salvesta parool' märkeruutu. See võti määrab selle märkeruudu vaikimisi "
|
||||||
|
"oleku."
|
||||||
|
|
||||||
msgid "Show the week date in the calendar"
|
msgid "Show the week date in the calendar"
|
||||||
msgstr "Kalendris näidatakse kuupäeva nädalavormingus"
|
msgstr "Kalendris näidatakse kuupäeva nädalavormingus"
|
||||||
|
|
||||||
@ -227,6 +249,18 @@ msgstr ""
|
|||||||
"konteinervormingusse salvestades tuleks ka sellele vormingule vastav laiend "
|
"konteinervormingusse salvestades tuleks ka sellele vormingule vastav laiend "
|
||||||
"määrata."
|
"määrata."
|
||||||
|
|
||||||
|
msgid "The application icon mode."
|
||||||
|
msgstr "Rakenduste ikooni režiim."
|
||||||
|
|
||||||
|
msgid ""
|
||||||
|
"Configures how the windows are shown in the switcher. Valid possibilities "
|
||||||
|
"are 'thumbnail-only' (shows a thumbnail of the window), 'app-icon-"
|
||||||
|
"only' (shows only the application icon) or 'both'."
|
||||||
|
msgstr ""
|
||||||
|
"Seadistab, kuidas aknaid aknavahetajas kuvatakse. Sobivad väärtused on "
|
||||||
|
"'thumbnail-only' (näidatakse ainult pisipilti aknast), 'app-icon-"
|
||||||
|
"only' (näidatakse ainult akna ikooni) või 'both' (mõlemad)."
|
||||||
|
|
||||||
msgid "Attach modal dialog to the parent window"
|
msgid "Attach modal dialog to the parent window"
|
||||||
msgstr "Modaaldialoog kuulub vanemakna juurde"
|
msgstr "Modaaldialoog kuulub vanemakna juurde"
|
||||||
|
|
||||||
@ -588,11 +622,8 @@ msgstr "Helista"
|
|||||||
msgid "File Transfer"
|
msgid "File Transfer"
|
||||||
msgstr "Failiülekanne"
|
msgstr "Failiülekanne"
|
||||||
|
|
||||||
msgid "Subscription request"
|
msgid "Chat"
|
||||||
msgstr "Tellimuse päring"
|
msgstr "Vestlus"
|
||||||
|
|
||||||
msgid "Connection error"
|
|
||||||
msgstr "Ühenduse viga"
|
|
||||||
|
|
||||||
msgid "Unmute"
|
msgid "Unmute"
|
||||||
msgstr "Heli peale"
|
msgstr "Heli peale"
|
||||||
@ -600,27 +631,25 @@ msgstr "Heli peale"
|
|||||||
msgid "Mute"
|
msgid "Mute"
|
||||||
msgstr "Heli maha"
|
msgstr "Heli maha"
|
||||||
|
|
||||||
#. Translators: this is a time format string followed by the word "Yesterday". i.e. "14:30 on Yesterday"
|
#. Translators: this is the word "Yesterday" followed by a time string. i.e. "Yesterday, 14:30"
|
||||||
#, no-c-format
|
#, no-c-format
|
||||||
msgid "<b>%H:%M</b> on Yesterday"
|
msgid "<b>Yesterday</b>, <b>%H:%M</b>"
|
||||||
msgstr "Eile <b>%H:%M</b>"
|
msgstr "<b>Eile</b> <b>%H:%M</b>"
|
||||||
|
|
||||||
#. Translators: this is a time format string followed by a week day name. i.e. "14:30 on Monday
|
#. Translators: this is the week day name followed by a time string. i.e. "Monday, 14:30
|
||||||
#, no-c-format
|
#, no-c-format
|
||||||
msgid "<b>%H:%M</b> on <b>%A</b>"
|
msgid "<b>%A</b>, <b>%H:%M</b>"
|
||||||
msgstr "<b>%H:%M</b>, <b>%A</b>"
|
msgstr "<b>%A</b>, <b>%H:%M</b>"
|
||||||
|
|
||||||
#. Translators: this is a time format in the style of "14:30 on Wednesday, May 25",
|
#. Translators: this is the month name and day number followed by a time string. i.e. "May 25, 14:30"
|
||||||
#. shown when you get a chat message in the same year
|
|
||||||
#, no-c-format
|
#, no-c-format
|
||||||
msgid "<b>%H:%M</b> on <b>%A</b>, <b>%B</b> <b>%d</b>"
|
msgid "<b>%B</b> <b>%d</b>, <b>%H:%M</b>"
|
||||||
msgstr "<b>%H:%M</b>, <b>%A</b>, <b>%d. %B</b>"
|
msgstr "<b>%d. %B</b>, <b>%H:%M</b>"
|
||||||
|
|
||||||
#. Translators: this is a time format in the style of "14:30 on Wednesday, May 25, 2012",
|
#. Translators: this is the month name, day number, year number followed by a time string. i.e. "May 25 2012, 14:30"
|
||||||
#. shown when you get a chat message in a different year
|
|
||||||
#, no-c-format
|
#, no-c-format
|
||||||
msgid "<b>%H:%M</b> on <b>%A</b>, <b>%B</b> <b>%d</b>, %Y"
|
msgid "<b>%B</b> <b>%d</b> <b>%Y</b>, <b>%H:%M</b> "
|
||||||
msgstr "<b>%H:%M</b>, <b>%A</b>, <b>%d. %B</b> %Y"
|
msgstr "<b>%d. %B %Y</b>, <b>%H:%M</b>"
|
||||||
|
|
||||||
#. Translators: this is the other person changing their old IM name to their new
|
#. Translators: this is the other person changing their old IM name to their new
|
||||||
#. IM name.
|
#. IM name.
|
||||||
@ -757,18 +786,18 @@ msgstr "Sisemine viga"
|
|||||||
#. translators: argument is the account name, like
|
#. translators: argument is the account name, like
|
||||||
#. * name@jabber.org for example.
|
#. * name@jabber.org for example.
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Connection to %s failed"
|
msgid "Unable to connect to %s"
|
||||||
msgstr "Ühendus %s nurjus"
|
msgstr "Pole võimalik ühenduda võrguga %s"
|
||||||
|
|
||||||
msgid "Reconnect"
|
msgid "View account"
|
||||||
msgstr "Ühendu uuesti"
|
msgstr "Konto kuvamine"
|
||||||
|
|
||||||
msgid "Edit account"
|
|
||||||
msgstr "Konto muutmine"
|
|
||||||
|
|
||||||
msgid "Unknown reason"
|
msgid "Unknown reason"
|
||||||
msgstr "Põhjus teadmata"
|
msgstr "Põhjus teadmata"
|
||||||
|
|
||||||
|
msgid "Windows"
|
||||||
|
msgstr "Aknad"
|
||||||
|
|
||||||
msgid "Show Applications"
|
msgid "Show Applications"
|
||||||
msgstr "Rakenduste kuvamine"
|
msgstr "Rakenduste kuvamine"
|
||||||
|
|
||||||
@ -891,8 +920,6 @@ msgstr "Näita vigu"
|
|||||||
msgid "Enabled"
|
msgid "Enabled"
|
||||||
msgstr "Lubatud"
|
msgstr "Lubatud"
|
||||||
|
|
||||||
#. translators:
|
|
||||||
#. * The device has been disabled
|
|
||||||
msgid "Disabled"
|
msgid "Disabled"
|
||||||
msgstr "Keelatud"
|
msgstr "Keelatud"
|
||||||
|
|
||||||
@ -917,6 +944,9 @@ msgstr "Ava"
|
|||||||
msgid "Remove"
|
msgid "Remove"
|
||||||
msgstr "Eemalda"
|
msgstr "Eemalda"
|
||||||
|
|
||||||
|
msgid "No Messages"
|
||||||
|
msgstr "Teateid pole"
|
||||||
|
|
||||||
msgid "Message Tray"
|
msgid "Message Tray"
|
||||||
msgstr "Teateala"
|
msgstr "Teateala"
|
||||||
|
|
||||||
@ -987,6 +1017,9 @@ msgid_plural "%d new notifications"
|
|||||||
msgstr[0] "%d uus märguanne"
|
msgstr[0] "%d uus märguanne"
|
||||||
msgstr[1] "%d uut märguannet"
|
msgstr[1] "%d uut märguannet"
|
||||||
|
|
||||||
|
msgid "Lock"
|
||||||
|
msgstr "Lukusta"
|
||||||
|
|
||||||
msgid "Searching..."
|
msgid "Searching..."
|
||||||
msgstr "Otsimine..."
|
msgstr "Otsimine..."
|
||||||
|
|
||||||
@ -1107,6 +1140,7 @@ msgstr "Luba ainult seekord"
|
|||||||
msgid "Reject"
|
msgid "Reject"
|
||||||
msgstr "Lükka tagasi"
|
msgstr "Lükka tagasi"
|
||||||
|
|
||||||
|
#. Translators: argument is the device short name
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Pairing confirmation for %s"
|
msgid "Pairing confirmation for %s"
|
||||||
msgstr "Paardumise kinnitus seadmele %s"
|
msgstr "Paardumise kinnitus seadmele %s"
|
||||||
@ -1119,6 +1153,7 @@ msgstr "Seade '%s' tahab selle arvutiga paarduda"
|
|||||||
msgid "Please confirm whether the PIN '%06d' matches the one on the device."
|
msgid "Please confirm whether the PIN '%06d' matches the one on the device."
|
||||||
msgstr "Palun kontrolli, kas PIN-kood '%06d' kattub seadme parooliga."
|
msgstr "Palun kontrolli, kas PIN-kood '%06d' kattub seadme parooliga."
|
||||||
|
|
||||||
|
#. Translators: this is the verb, not the noun
|
||||||
msgid "Matches"
|
msgid "Matches"
|
||||||
msgstr "Kattub"
|
msgstr "Kattub"
|
||||||
|
|
||||||
@ -1208,14 +1243,8 @@ msgstr "Automaatne juhtmeta ühendus"
|
|||||||
msgid "Enable networking"
|
msgid "Enable networking"
|
||||||
msgstr "Luba võrguühendused"
|
msgstr "Luba võrguühendused"
|
||||||
|
|
||||||
msgid "Wired"
|
msgid "Wi-Fi"
|
||||||
msgstr "Juhtmega"
|
msgstr "Wi-Fi"
|
||||||
|
|
||||||
msgid "Wireless"
|
|
||||||
msgstr "Juhtmeta"
|
|
||||||
|
|
||||||
msgid "Mobile broadband"
|
|
||||||
msgstr "Mobiiliühendus"
|
|
||||||
|
|
||||||
msgid "Network Settings"
|
msgid "Network Settings"
|
||||||
msgstr "Võrgusätted"
|
msgstr "Võrgusätted"
|
||||||
@ -1319,6 +1348,9 @@ msgstr "Mikrofon"
|
|||||||
msgid "Log in as another user"
|
msgid "Log in as another user"
|
||||||
msgstr "Logi sisse teise kasutajana"
|
msgstr "Logi sisse teise kasutajana"
|
||||||
|
|
||||||
|
msgid "Unlock Window"
|
||||||
|
msgstr "Võta aken lukust lahti"
|
||||||
|
|
||||||
msgid "Available"
|
msgid "Available"
|
||||||
msgstr "Saadaval"
|
msgstr "Saadaval"
|
||||||
|
|
||||||
@ -1349,9 +1381,6 @@ msgstr "Vaheta kasutajat"
|
|||||||
msgid "Log Out"
|
msgid "Log Out"
|
||||||
msgstr "Logi välja"
|
msgstr "Logi välja"
|
||||||
|
|
||||||
msgid "Lock"
|
|
||||||
msgstr "Lukusta"
|
|
||||||
|
|
||||||
msgid "Install Updates & Restart"
|
msgid "Install Updates & Restart"
|
||||||
msgstr "Paigalda uuendused ja taaskäivita"
|
msgstr "Paigalda uuendused ja taaskäivita"
|
||||||
|
|
||||||
@ -1365,9 +1394,6 @@ msgstr ""
|
|||||||
"Märguanded on nüüd keelatud, sealhulgas vestlusteated. Sinu netiolekut "
|
"Märguanded on nüüd keelatud, sealhulgas vestlusteated. Sinu netiolekut "
|
||||||
"muudeti, et teised teaksid, et sa ei pruugi nende teateid näha."
|
"muudeti, et teised teaksid, et sa ei pruugi nende teateid näha."
|
||||||
|
|
||||||
msgid "Windows"
|
|
||||||
msgstr "Aknad"
|
|
||||||
|
|
||||||
msgid "Applications"
|
msgid "Applications"
|
||||||
msgstr "Rakendused"
|
msgstr "Rakendused"
|
||||||
|
|
||||||
@ -1396,25 +1422,6 @@ msgstr "'%s' on valmis"
|
|||||||
msgid "Evolution Calendar"
|
msgid "Evolution Calendar"
|
||||||
msgstr "Evolutioni kalender"
|
msgstr "Evolutioni kalender"
|
||||||
|
|
||||||
#. translators:
|
|
||||||
#. * The number of sound outputs on a particular device
|
|
||||||
#, c-format
|
|
||||||
msgid "%u Output"
|
|
||||||
msgid_plural "%u Outputs"
|
|
||||||
msgstr[0] "%u väljund"
|
|
||||||
msgstr[1] "%u väljundit"
|
|
||||||
|
|
||||||
#. translators:
|
|
||||||
#. * The number of sound inputs on a particular device
|
|
||||||
#, c-format
|
|
||||||
msgid "%u Input"
|
|
||||||
msgid_plural "%u Inputs"
|
|
||||||
msgstr[0] "%u sisend"
|
|
||||||
msgstr[1] "%u sisendit"
|
|
||||||
|
|
||||||
msgid "System Sounds"
|
|
||||||
msgstr "Süsteemi helid"
|
|
||||||
|
|
||||||
msgid "Print version"
|
msgid "Print version"
|
||||||
msgstr "Printimise versioon"
|
msgstr "Printimise versioon"
|
||||||
|
|
||||||
@ -1446,6 +1453,46 @@ msgstr "Vaikimisi"
|
|||||||
msgid "Authentication dialog was dismissed by the user"
|
msgid "Authentication dialog was dismissed by the user"
|
||||||
msgstr "Kasutaja katkestas autentimisdialoogi"
|
msgstr "Kasutaja katkestas autentimisdialoogi"
|
||||||
|
|
||||||
|
#~ msgid "Subscription request"
|
||||||
|
#~ msgstr "Tellimuse päring"
|
||||||
|
|
||||||
|
#~ msgid "Connection error"
|
||||||
|
#~ msgstr "Ühenduse viga"
|
||||||
|
|
||||||
|
#~ msgid "<b>%H:%M</b> on Yesterday"
|
||||||
|
#~ msgstr "Eile <b>%H:%M</b>"
|
||||||
|
|
||||||
|
#~ msgid "<b>%H:%M</b> on <b>%A</b>, <b>%B</b> <b>%d</b>, %Y"
|
||||||
|
#~ msgstr "<b>%H:%M</b>, <b>%A</b>, <b>%d. %B</b> %Y"
|
||||||
|
|
||||||
|
#~ msgid "Connection to %s failed"
|
||||||
|
#~ msgstr "Ühendus %s nurjus"
|
||||||
|
|
||||||
|
#~ msgid "Reconnect"
|
||||||
|
#~ msgstr "Ühendu uuesti"
|
||||||
|
|
||||||
|
#~ msgid "Wired"
|
||||||
|
#~ msgstr "Juhtmega"
|
||||||
|
|
||||||
|
#~ msgid "Wireless"
|
||||||
|
#~ msgstr "Juhtmeta"
|
||||||
|
|
||||||
|
#~ msgid "Mobile broadband"
|
||||||
|
#~ msgstr "Mobiiliühendus"
|
||||||
|
|
||||||
|
#~ msgid "%u Output"
|
||||||
|
#~ msgid_plural "%u Outputs"
|
||||||
|
#~ msgstr[0] "%u väljund"
|
||||||
|
#~ msgstr[1] "%u väljundit"
|
||||||
|
|
||||||
|
#~ msgid "%u Input"
|
||||||
|
#~ msgid_plural "%u Inputs"
|
||||||
|
#~ msgstr[0] "%u sisend"
|
||||||
|
#~ msgstr[1] "%u sisendit"
|
||||||
|
|
||||||
|
#~ msgid "System Sounds"
|
||||||
|
#~ msgstr "Süsteemi helid"
|
||||||
|
|
||||||
#~ msgid "disabled OpenSearch providers"
|
#~ msgid "disabled OpenSearch providers"
|
||||||
#~ msgstr "keelatud OpenSearch pakkujad"
|
#~ msgstr "keelatud OpenSearch pakkujad"
|
||||||
|
|
||||||
|
308
po/nb.po
308
po/nb.po
@ -2,14 +2,14 @@
|
|||||||
# Copyright (C) 2009 THE PACKAGE'S COPYRIGHT HOLDER
|
# Copyright (C) 2009 THE PACKAGE'S COPYRIGHT HOLDER
|
||||||
# This file is distributed under the same license as the gnome-shell package.
|
# This file is distributed under the same license as the gnome-shell package.
|
||||||
#
|
#
|
||||||
# Kjartan Maraas <kmaraas@gnome.org>, 2009-2012.
|
# Kjartan Maraas <kmaraas@gnome.org>, 2009-2013.
|
||||||
# Torstein Adolf Winterseth <kvikende@fsfe.org>, 2010.
|
# Torstein Adolf Winterseth <kvikende@fsfe.org>, 2010.
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: gnome-shell 3.7.x\n"
|
"Project-Id-Version: gnome-shell 3.7.x\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2012-12-09 14:01+0100\n"
|
"POT-Creation-Date: 2013-01-14 11:20+0100\n"
|
||||||
"PO-Revision-Date: 2012-12-09 14:02+0100\n"
|
"PO-Revision-Date: 2013-01-14 11:21+0100\n"
|
||||||
"Last-Translator: Kjartan Maraas <kmaraas@gnome.org>\n"
|
"Last-Translator: Kjartan Maraas <kmaraas@gnome.org>\n"
|
||||||
"Language-Team: Norwegian bokmål <i18n-nb@lister.ping.uio.no>\n"
|
"Language-Team: Norwegian bokmål <i18n-nb@lister.ping.uio.no>\n"
|
||||||
"Language: \n"
|
"Language: \n"
|
||||||
@ -311,11 +311,11 @@ msgstr ""
|
|||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.in.h:47
|
#: ../data/org.gnome.shell.gschema.xml.in.in.h:47
|
||||||
msgid "Workspaces are managed dynamically"
|
msgid "Workspaces are managed dynamically"
|
||||||
msgstr ""
|
msgstr "Arbeidsområder håndteres dynamisk"
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.in.h:48
|
#: ../data/org.gnome.shell.gschema.xml.in.in.h:48
|
||||||
msgid "Workspaces only on primary monitor"
|
msgid "Workspaces only on primary monitor"
|
||||||
msgstr ""
|
msgstr "Arbeidsområder vises kun på hovedskjerm"
|
||||||
|
|
||||||
#: ../js/extensionPrefs/main.js:124
|
#: ../js/extensionPrefs/main.js:124
|
||||||
#, c-format
|
#, c-format
|
||||||
@ -330,11 +330,11 @@ msgstr "Utvidelse"
|
|||||||
msgid "Select an extension to configure using the combobox above."
|
msgid "Select an extension to configure using the combobox above."
|
||||||
msgstr "Velg en utvidelse som skal konfigureres med komboboksen over."
|
msgstr "Velg en utvidelse som skal konfigureres med komboboksen over."
|
||||||
|
|
||||||
#: ../js/gdm/loginDialog.js:565
|
#: ../js/gdm/loginDialog.js:566
|
||||||
msgid "Session..."
|
msgid "Session..."
|
||||||
msgstr "Økt …"
|
msgstr "Økt …"
|
||||||
|
|
||||||
#: ../js/gdm/loginDialog.js:722
|
#: ../js/gdm/loginDialog.js:723
|
||||||
msgctxt "title"
|
msgctxt "title"
|
||||||
msgid "Sign In"
|
msgid "Sign In"
|
||||||
msgstr "Logg inn"
|
msgstr "Logg inn"
|
||||||
@ -342,35 +342,35 @@ msgstr "Logg inn"
|
|||||||
#. translators: this message is shown below the user list on the
|
#. translators: this message is shown below the user list on the
|
||||||
#. login screen. It can be activated to reveal an entry for
|
#. login screen. It can be activated to reveal an entry for
|
||||||
#. manually entering the username.
|
#. manually entering the username.
|
||||||
#: ../js/gdm/loginDialog.js:786
|
#: ../js/gdm/loginDialog.js:787
|
||||||
msgid "Not listed?"
|
msgid "Not listed?"
|
||||||
msgstr "Ikke listet?"
|
msgstr "Ikke listet?"
|
||||||
|
|
||||||
#: ../js/gdm/loginDialog.js:962 ../js/ui/components/networkAgent.js:137
|
#: ../js/gdm/loginDialog.js:963 ../js/ui/components/networkAgent.js:137
|
||||||
#: ../js/ui/components/polkitAgent.js:162 ../js/ui/endSessionDialog.js:373
|
#: ../js/ui/components/polkitAgent.js:162 ../js/ui/endSessionDialog.js:373
|
||||||
#: ../js/ui/extensionDownloader.js:195 ../js/ui/shellMountOperation.js:399
|
#: ../js/ui/extensionDownloader.js:195 ../js/ui/shellMountOperation.js:399
|
||||||
#: ../js/ui/status/bluetooth.js:413 ../js/ui/unlockDialog.js:178
|
#: ../js/ui/status/bluetooth.js:413 ../js/ui/unlockDialog.js:178
|
||||||
msgid "Cancel"
|
msgid "Cancel"
|
||||||
msgstr "Avbryt"
|
msgstr "Avbryt"
|
||||||
|
|
||||||
#: ../js/gdm/loginDialog.js:978
|
#: ../js/gdm/loginDialog.js:979
|
||||||
msgctxt "button"
|
msgctxt "button"
|
||||||
msgid "Sign In"
|
msgid "Sign In"
|
||||||
msgstr "Logg inn"
|
msgstr "Logg inn"
|
||||||
|
|
||||||
#: ../js/gdm/loginDialog.js:978
|
#: ../js/gdm/loginDialog.js:979
|
||||||
msgid "Next"
|
msgid "Next"
|
||||||
msgstr "Neste"
|
msgstr "Neste"
|
||||||
|
|
||||||
#. TTLS and PEAP are actually much more complicated, but this complication
|
#. TTLS and PEAP are actually much more complicated, but this complication
|
||||||
#. is not visible here since we only care about phase2 authentication
|
#. is not visible here since we only care about phase2 authentication
|
||||||
#. (and don't even care of which one)
|
#. (and don't even care of which one)
|
||||||
#: ../js/gdm/loginDialog.js:1086 ../js/ui/components/networkAgent.js:260
|
#: ../js/gdm/loginDialog.js:1087 ../js/ui/components/networkAgent.js:260
|
||||||
#: ../js/ui/components/networkAgent.js:278
|
#: ../js/ui/components/networkAgent.js:278
|
||||||
msgid "Username: "
|
msgid "Username: "
|
||||||
msgstr "Brukernavn: "
|
msgstr "Brukernavn: "
|
||||||
|
|
||||||
#: ../js/gdm/loginDialog.js:1382
|
#: ../js/gdm/loginDialog.js:1383
|
||||||
msgid "Login Window"
|
msgid "Login Window"
|
||||||
msgstr "Innloggingsvindu"
|
msgstr "Innloggingsvindu"
|
||||||
|
|
||||||
@ -379,8 +379,8 @@ msgstr "Innloggingsvindu"
|
|||||||
msgid "Power"
|
msgid "Power"
|
||||||
msgstr "Strøm"
|
msgstr "Strøm"
|
||||||
|
|
||||||
#: ../js/gdm/powerMenu.js:93 ../js/ui/userMenu.js:674 ../js/ui/userMenu.js:678
|
#: ../js/gdm/powerMenu.js:93 ../js/ui/userMenu.js:675 ../js/ui/userMenu.js:679
|
||||||
#: ../js/ui/userMenu.js:789
|
#: ../js/ui/userMenu.js:790
|
||||||
msgid "Suspend"
|
msgid "Suspend"
|
||||||
msgstr "Hvilemodus"
|
msgstr "Hvilemodus"
|
||||||
|
|
||||||
@ -388,8 +388,8 @@ msgstr "Hvilemodus"
|
|||||||
msgid "Restart"
|
msgid "Restart"
|
||||||
msgstr "Start på nytt"
|
msgstr "Start på nytt"
|
||||||
|
|
||||||
#: ../js/gdm/powerMenu.js:103 ../js/ui/userMenu.js:676
|
#: ../js/gdm/powerMenu.js:103 ../js/ui/userMenu.js:677
|
||||||
#: ../js/ui/userMenu.js:678 ../js/ui/userMenu.js:788
|
#: ../js/ui/userMenu.js:679 ../js/ui/userMenu.js:789
|
||||||
msgid "Power Off"
|
msgid "Power Off"
|
||||||
msgstr "Slå av"
|
msgstr "Slå av"
|
||||||
|
|
||||||
@ -424,27 +424,19 @@ msgid "Execution of '%s' failed:"
|
|||||||
msgstr "Kjøring av «%s» feilet:"
|
msgstr "Kjøring av «%s» feilet:"
|
||||||
|
|
||||||
#. Translators: Filter to display all applications
|
#. Translators: Filter to display all applications
|
||||||
#: ../js/ui/appDisplay.js:259
|
#: ../js/ui/appDisplay.js:258
|
||||||
msgid "All"
|
msgid "All"
|
||||||
msgstr "Alle"
|
msgstr "Alle"
|
||||||
|
|
||||||
#: ../js/ui/appDisplay.js:318
|
#: ../js/ui/appDisplay.js:666
|
||||||
msgid "APPLICATIONS"
|
|
||||||
msgstr "PROGRAMMER"
|
|
||||||
|
|
||||||
#: ../js/ui/appDisplay.js:375
|
|
||||||
msgid "SETTINGS"
|
|
||||||
msgstr "INNSTILLINGER"
|
|
||||||
|
|
||||||
#: ../js/ui/appDisplay.js:679
|
|
||||||
msgid "New Window"
|
msgid "New Window"
|
||||||
msgstr "Nytt vindu"
|
msgstr "Nytt vindu"
|
||||||
|
|
||||||
#: ../js/ui/appDisplay.js:682 ../js/ui/dash.js:289
|
#: ../js/ui/appDisplay.js:669 ../js/ui/dash.js:289
|
||||||
msgid "Remove from Favorites"
|
msgid "Remove from Favorites"
|
||||||
msgstr "Fjern fra favoritter"
|
msgstr "Fjern fra favoritter"
|
||||||
|
|
||||||
#: ../js/ui/appDisplay.js:683
|
#: ../js/ui/appDisplay.js:670
|
||||||
msgid "Add to Favorites"
|
msgid "Add to Favorites"
|
||||||
msgstr "Legg til i favoritter"
|
msgstr "Legg til i favoritter"
|
||||||
|
|
||||||
@ -461,19 +453,19 @@ msgstr "%s ble fjernet fra dine favoritter."
|
|||||||
#. Translators: Shown in calendar event list for all day events
|
#. Translators: Shown in calendar event list for all day events
|
||||||
#. * Keep it short, best if you can use less then 10 characters
|
#. * Keep it short, best if you can use less then 10 characters
|
||||||
#.
|
#.
|
||||||
#: ../js/ui/calendar.js:62
|
#: ../js/ui/calendar.js:61
|
||||||
msgctxt "event list time"
|
msgctxt "event list time"
|
||||||
msgid "All Day"
|
msgid "All Day"
|
||||||
msgstr "Hele dagen"
|
msgstr "Hele dagen"
|
||||||
|
|
||||||
#. Translators: Shown in calendar event list, if 24h format
|
#. Translators: Shown in calendar event list, if 24h format
|
||||||
#: ../js/ui/calendar.js:67
|
#: ../js/ui/calendar.js:66
|
||||||
msgctxt "event list time"
|
msgctxt "event list time"
|
||||||
msgid "%H:%M"
|
msgid "%H:%M"
|
||||||
msgstr "%H.%M"
|
msgstr "%H.%M"
|
||||||
|
|
||||||
#. Transators: Shown in calendar event list, if 12h format
|
#. Transators: Shown in calendar event list, if 12h format
|
||||||
#: ../js/ui/calendar.js:74
|
#: ../js/ui/calendar.js:73
|
||||||
msgctxt "event list time"
|
msgctxt "event list time"
|
||||||
msgid "%l:%M %p"
|
msgid "%l:%M %p"
|
||||||
msgstr "%l.%M %p"
|
msgstr "%l.%M %p"
|
||||||
@ -483,43 +475,43 @@ msgstr "%l.%M %p"
|
|||||||
#. * NOTE: These grid abbreviations are always shown together
|
#. * NOTE: These grid abbreviations are always shown together
|
||||||
#. * and in order, e.g. "S M T W T F S".
|
#. * and in order, e.g. "S M T W T F S".
|
||||||
#.
|
#.
|
||||||
#: ../js/ui/calendar.js:114
|
#: ../js/ui/calendar.js:104
|
||||||
msgctxt "grid sunday"
|
msgctxt "grid sunday"
|
||||||
msgid "S"
|
msgid "S"
|
||||||
msgstr "S"
|
msgstr "S"
|
||||||
|
|
||||||
#. Translators: Calendar grid abbreviation for Monday
|
#. Translators: Calendar grid abbreviation for Monday
|
||||||
#: ../js/ui/calendar.js:116
|
#: ../js/ui/calendar.js:106
|
||||||
msgctxt "grid monday"
|
msgctxt "grid monday"
|
||||||
msgid "M"
|
msgid "M"
|
||||||
msgstr "M"
|
msgstr "M"
|
||||||
|
|
||||||
#. Translators: Calendar grid abbreviation for Tuesday
|
#. Translators: Calendar grid abbreviation for Tuesday
|
||||||
#: ../js/ui/calendar.js:118
|
#: ../js/ui/calendar.js:108
|
||||||
msgctxt "grid tuesday"
|
msgctxt "grid tuesday"
|
||||||
msgid "T"
|
msgid "T"
|
||||||
msgstr "T"
|
msgstr "T"
|
||||||
|
|
||||||
#. Translators: Calendar grid abbreviation for Wednesday
|
#. Translators: Calendar grid abbreviation for Wednesday
|
||||||
#: ../js/ui/calendar.js:120
|
#: ../js/ui/calendar.js:110
|
||||||
msgctxt "grid wednesday"
|
msgctxt "grid wednesday"
|
||||||
msgid "W"
|
msgid "W"
|
||||||
msgstr "O"
|
msgstr "O"
|
||||||
|
|
||||||
#. Translators: Calendar grid abbreviation for Thursday
|
#. Translators: Calendar grid abbreviation for Thursday
|
||||||
#: ../js/ui/calendar.js:122
|
#: ../js/ui/calendar.js:112
|
||||||
msgctxt "grid thursday"
|
msgctxt "grid thursday"
|
||||||
msgid "T"
|
msgid "T"
|
||||||
msgstr "T"
|
msgstr "T"
|
||||||
|
|
||||||
#. Translators: Calendar grid abbreviation for Friday
|
#. Translators: Calendar grid abbreviation for Friday
|
||||||
#: ../js/ui/calendar.js:124
|
#: ../js/ui/calendar.js:114
|
||||||
msgctxt "grid friday"
|
msgctxt "grid friday"
|
||||||
msgid "F"
|
msgid "F"
|
||||||
msgstr "F"
|
msgstr "F"
|
||||||
|
|
||||||
#. Translators: Calendar grid abbreviation for Saturday
|
#. Translators: Calendar grid abbreviation for Saturday
|
||||||
#: ../js/ui/calendar.js:126
|
#: ../js/ui/calendar.js:116
|
||||||
msgctxt "grid saturday"
|
msgctxt "grid saturday"
|
||||||
msgid "S"
|
msgid "S"
|
||||||
msgstr "L"
|
msgstr "L"
|
||||||
@ -530,77 +522,77 @@ msgstr "L"
|
|||||||
#. * so they need to be unique (e.g. Tuesday and Thursday cannot
|
#. * so they need to be unique (e.g. Tuesday and Thursday cannot
|
||||||
#. * both be 'T').
|
#. * both be 'T').
|
||||||
#.
|
#.
|
||||||
#: ../js/ui/calendar.js:139
|
#: ../js/ui/calendar.js:129
|
||||||
msgctxt "list sunday"
|
msgctxt "list sunday"
|
||||||
msgid "Su"
|
msgid "Su"
|
||||||
msgstr "Sø"
|
msgstr "Sø"
|
||||||
|
|
||||||
#. Translators: Event list abbreviation for Monday
|
#. Translators: Event list abbreviation for Monday
|
||||||
#: ../js/ui/calendar.js:141
|
#: ../js/ui/calendar.js:131
|
||||||
msgctxt "list monday"
|
msgctxt "list monday"
|
||||||
msgid "M"
|
msgid "M"
|
||||||
msgstr "Ma"
|
msgstr "Ma"
|
||||||
|
|
||||||
#. Translators: Event list abbreviation for Tuesday
|
#. Translators: Event list abbreviation for Tuesday
|
||||||
#: ../js/ui/calendar.js:143
|
#: ../js/ui/calendar.js:133
|
||||||
msgctxt "list tuesday"
|
msgctxt "list tuesday"
|
||||||
msgid "T"
|
msgid "T"
|
||||||
msgstr "Ti"
|
msgstr "Ti"
|
||||||
|
|
||||||
#. Translators: Event list abbreviation for Wednesday
|
#. Translators: Event list abbreviation for Wednesday
|
||||||
#: ../js/ui/calendar.js:145
|
#: ../js/ui/calendar.js:135
|
||||||
msgctxt "list wednesday"
|
msgctxt "list wednesday"
|
||||||
msgid "W"
|
msgid "W"
|
||||||
msgstr "On"
|
msgstr "On"
|
||||||
|
|
||||||
#. Translators: Event list abbreviation for Thursday
|
#. Translators: Event list abbreviation for Thursday
|
||||||
#: ../js/ui/calendar.js:147
|
#: ../js/ui/calendar.js:137
|
||||||
msgctxt "list thursday"
|
msgctxt "list thursday"
|
||||||
msgid "Th"
|
msgid "Th"
|
||||||
msgstr "To"
|
msgstr "To"
|
||||||
|
|
||||||
#. Translators: Event list abbreviation for Friday
|
#. Translators: Event list abbreviation for Friday
|
||||||
#: ../js/ui/calendar.js:149
|
#: ../js/ui/calendar.js:139
|
||||||
msgctxt "list friday"
|
msgctxt "list friday"
|
||||||
msgid "F"
|
msgid "F"
|
||||||
msgstr "Fr"
|
msgstr "Fr"
|
||||||
|
|
||||||
#. Translators: Event list abbreviation for Saturday
|
#. Translators: Event list abbreviation for Saturday
|
||||||
#: ../js/ui/calendar.js:151
|
#: ../js/ui/calendar.js:141
|
||||||
msgctxt "list saturday"
|
msgctxt "list saturday"
|
||||||
msgid "S"
|
msgid "S"
|
||||||
msgstr "Lø"
|
msgstr "Lø"
|
||||||
|
|
||||||
#. Translators: Text to show if there are no events
|
#. Translators: Text to show if there are no events
|
||||||
#: ../js/ui/calendar.js:700
|
#: ../js/ui/calendar.js:674
|
||||||
msgid "Nothing Scheduled"
|
msgid "Nothing Scheduled"
|
||||||
msgstr "Ingenting planlagt"
|
msgstr "Ingenting planlagt"
|
||||||
|
|
||||||
#. Translators: Shown on calendar heading when selected day occurs on current year
|
#. Translators: Shown on calendar heading when selected day occurs on current year
|
||||||
#: ../js/ui/calendar.js:716
|
#: ../js/ui/calendar.js:690
|
||||||
msgctxt "calendar heading"
|
msgctxt "calendar heading"
|
||||||
msgid "%A, %B %d"
|
msgid "%A, %B %d"
|
||||||
msgstr "%A %B %d"
|
msgstr "%A %B %d"
|
||||||
|
|
||||||
#. Translators: Shown on calendar heading when selected day occurs on different year
|
#. Translators: Shown on calendar heading when selected day occurs on different year
|
||||||
#: ../js/ui/calendar.js:719
|
#: ../js/ui/calendar.js:693
|
||||||
msgctxt "calendar heading"
|
msgctxt "calendar heading"
|
||||||
msgid "%A, %B %d, %Y"
|
msgid "%A, %B %d, %Y"
|
||||||
msgstr "%A %B %d, %Y"
|
msgstr "%A %B %d, %Y"
|
||||||
|
|
||||||
#: ../js/ui/calendar.js:729
|
#: ../js/ui/calendar.js:703
|
||||||
msgid "Today"
|
msgid "Today"
|
||||||
msgstr "I dag"
|
msgstr "I dag"
|
||||||
|
|
||||||
#: ../js/ui/calendar.js:733
|
#: ../js/ui/calendar.js:707
|
||||||
msgid "Tomorrow"
|
msgid "Tomorrow"
|
||||||
msgstr "I morgen"
|
msgstr "I morgen"
|
||||||
|
|
||||||
#: ../js/ui/calendar.js:744
|
#: ../js/ui/calendar.js:718
|
||||||
msgid "This week"
|
msgid "This week"
|
||||||
msgstr "Denne uken"
|
msgstr "Denne uken"
|
||||||
|
|
||||||
#: ../js/ui/calendar.js:752
|
#: ../js/ui/calendar.js:726
|
||||||
msgid "Next week"
|
msgid "Next week"
|
||||||
msgstr "Neste uke"
|
msgstr "Neste uke"
|
||||||
|
|
||||||
@ -617,11 +609,11 @@ msgstr "Åpne med %s"
|
|||||||
msgid "Eject"
|
msgid "Eject"
|
||||||
msgstr "Løs ut"
|
msgstr "Løs ut"
|
||||||
|
|
||||||
#: ../js/ui/components/keyring.js:86 ../js/ui/components/polkitAgent.js:260
|
#: ../js/ui/components/keyring.js:82 ../js/ui/components/polkitAgent.js:268
|
||||||
msgid "Password:"
|
msgid "Password:"
|
||||||
msgstr "Passord:"
|
msgstr "Passord:"
|
||||||
|
|
||||||
#: ../js/ui/components/keyring.js:105
|
#: ../js/ui/components/keyring.js:101
|
||||||
msgid "Type again:"
|
msgid "Type again:"
|
||||||
msgstr "Skriv på nytt:"
|
msgstr "Skriv på nytt:"
|
||||||
|
|
||||||
@ -709,7 +701,7 @@ msgstr "Autentisering kreves"
|
|||||||
msgid "Administrator"
|
msgid "Administrator"
|
||||||
msgstr "Administrator"
|
msgstr "Administrator"
|
||||||
|
|
||||||
#: ../js/ui/components/polkitAgent.js:166
|
#: ../js/ui/components/polkitAgent.js:165
|
||||||
msgid "Authenticate"
|
msgid "Authenticate"
|
||||||
msgstr "Autentiser"
|
msgstr "Autentiser"
|
||||||
|
|
||||||
@ -717,7 +709,7 @@ msgstr "Autentiser"
|
|||||||
#. * requested authentication was not gained; this can happen
|
#. * requested authentication was not gained; this can happen
|
||||||
#. * because of an authentication error (like invalid password),
|
#. * because of an authentication error (like invalid password),
|
||||||
#. * for instance.
|
#. * for instance.
|
||||||
#: ../js/ui/components/polkitAgent.js:248 ../js/ui/shellMountOperation.js:383
|
#: ../js/ui/components/polkitAgent.js:256 ../js/ui/shellMountOperation.js:383
|
||||||
msgid "Sorry, that didn't work. Please try again."
|
msgid "Sorry, that didn't work. Please try again."
|
||||||
msgstr "Beklager, det virket ikke. Vennligst prøv igjen."
|
msgstr "Beklager, det virket ikke. Vennligst prøv igjen."
|
||||||
|
|
||||||
@ -962,11 +954,11 @@ msgstr "Kan ikke koble til %s"
|
|||||||
msgid "View account"
|
msgid "View account"
|
||||||
msgstr "Vis konto"
|
msgstr "Vis konto"
|
||||||
|
|
||||||
#: ../js/ui/components/telepathyClient.js:1384
|
#: ../js/ui/components/telepathyClient.js:1383
|
||||||
msgid "Unknown reason"
|
msgid "Unknown reason"
|
||||||
msgstr "Ukjent årsak"
|
msgstr "Ukjent årsak"
|
||||||
|
|
||||||
#: ../js/ui/ctrlAltTab.js:29 ../js/ui/viewSelector.js:87
|
#: ../js/ui/ctrlAltTab.js:29 ../js/ui/viewSelector.js:81
|
||||||
msgid "Windows"
|
msgid "Windows"
|
||||||
msgstr "Vinduer"
|
msgstr "Vinduer"
|
||||||
|
|
||||||
@ -974,18 +966,18 @@ msgstr "Vinduer"
|
|||||||
msgid "Show Applications"
|
msgid "Show Applications"
|
||||||
msgstr "Vis programmer"
|
msgstr "Vis programmer"
|
||||||
|
|
||||||
#: ../js/ui/dateMenu.js:86
|
#: ../js/ui/dateMenu.js:87
|
||||||
msgid "Date and Time Settings"
|
msgid "Date and Time Settings"
|
||||||
msgstr "Innstillinger for dato og klokkeslett"
|
msgstr "Innstillinger for dato og klokkeslett"
|
||||||
|
|
||||||
#: ../js/ui/dateMenu.js:111
|
#: ../js/ui/dateMenu.js:112
|
||||||
msgid "Open Calendar"
|
msgid "Open Calendar"
|
||||||
msgstr "Åpne kalender"
|
msgstr "Åpne kalender"
|
||||||
|
|
||||||
#. Translators: This is the date format to use when the calendar popup is
|
#. Translators: This is the date format to use when the calendar popup is
|
||||||
#. * shown - it is shown just below the time in the shell (e.g. "Tue 9:29 AM").
|
#. * shown - it is shown just below the time in the shell (e.g. "Tue 9:29 AM").
|
||||||
#.
|
#.
|
||||||
#: ../js/ui/dateMenu.js:201
|
#: ../js/ui/dateMenu.js:191
|
||||||
msgid "%A %B %e, %Y"
|
msgid "%A %B %e, %Y"
|
||||||
msgstr "%a %e %B, %Y"
|
msgstr "%a %e %B, %Y"
|
||||||
|
|
||||||
@ -1090,78 +1082,80 @@ msgstr "Installer"
|
|||||||
msgid "Download and install '%s' from extensions.gnome.org?"
|
msgid "Download and install '%s' from extensions.gnome.org?"
|
||||||
msgstr "Last ned og installer «%s» fra extensions.gnome.org?"
|
msgstr "Last ned og installer «%s» fra extensions.gnome.org?"
|
||||||
|
|
||||||
#: ../js/ui/keyboard.js:308
|
#: ../js/ui/keyboard.js:291
|
||||||
msgid "tray"
|
msgid "tray"
|
||||||
msgstr "varslingsområde"
|
msgstr "varslingsområde"
|
||||||
|
|
||||||
#: ../js/ui/keyboard.js:555 ../js/ui/status/keyboard.js:195
|
#: ../js/ui/keyboard.js:636 ../js/ui/status/keyboard.js:309
|
||||||
#: ../js/ui/status/power.js:205
|
#: ../js/ui/status/power.js:206
|
||||||
msgid "Keyboard"
|
msgid "Keyboard"
|
||||||
msgstr "Tastatur"
|
msgstr "Tastatur"
|
||||||
|
|
||||||
#: ../js/ui/lookingGlass.js:691
|
#: ../js/ui/lookingGlass.js:692
|
||||||
msgid "No extensions installed"
|
msgid "No extensions installed"
|
||||||
msgstr "Ingen utvidelser installert"
|
msgstr "Ingen utvidelser installert"
|
||||||
|
|
||||||
#. Translators: argument is an extension UUID.
|
#. Translators: argument is an extension UUID.
|
||||||
#: ../js/ui/lookingGlass.js:745
|
#: ../js/ui/lookingGlass.js:746
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%s has not emitted any errors."
|
msgid "%s has not emitted any errors."
|
||||||
msgstr "%s har ikke avgitt noen feil."
|
msgstr "%s har ikke avgitt noen feil."
|
||||||
|
|
||||||
#: ../js/ui/lookingGlass.js:751
|
#: ../js/ui/lookingGlass.js:752
|
||||||
msgid "Hide Errors"
|
msgid "Hide Errors"
|
||||||
msgstr "Skjul feil"
|
msgstr "Skjul feil"
|
||||||
|
|
||||||
#: ../js/ui/lookingGlass.js:755 ../js/ui/lookingGlass.js:815
|
#: ../js/ui/lookingGlass.js:756 ../js/ui/lookingGlass.js:816
|
||||||
msgid "Show Errors"
|
msgid "Show Errors"
|
||||||
msgstr "Vis feil"
|
msgstr "Vis feil"
|
||||||
|
|
||||||
#: ../js/ui/lookingGlass.js:764
|
#: ../js/ui/lookingGlass.js:765
|
||||||
msgid "Enabled"
|
msgid "Enabled"
|
||||||
msgstr "Aktivert"
|
msgstr "Aktivert"
|
||||||
|
|
||||||
#: ../js/ui/lookingGlass.js:767
|
#. translators:
|
||||||
|
#. * The device has been disabled
|
||||||
|
#: ../js/ui/lookingGlass.js:768 ../src/gvc/gvc-mixer-control.c:1830
|
||||||
msgid "Disabled"
|
msgid "Disabled"
|
||||||
msgstr "Deaktivert"
|
msgstr "Deaktivert"
|
||||||
|
|
||||||
#: ../js/ui/lookingGlass.js:769
|
#: ../js/ui/lookingGlass.js:770
|
||||||
msgid "Error"
|
msgid "Error"
|
||||||
msgstr "Feil"
|
msgstr "Feil"
|
||||||
|
|
||||||
#: ../js/ui/lookingGlass.js:771
|
#: ../js/ui/lookingGlass.js:772
|
||||||
msgid "Out of date"
|
msgid "Out of date"
|
||||||
msgstr "Utdatert"
|
msgstr "Utdatert"
|
||||||
|
|
||||||
#: ../js/ui/lookingGlass.js:773
|
#: ../js/ui/lookingGlass.js:774
|
||||||
msgid "Downloading"
|
msgid "Downloading"
|
||||||
msgstr "Laster ned"
|
msgstr "Laster ned"
|
||||||
|
|
||||||
#: ../js/ui/lookingGlass.js:797
|
#: ../js/ui/lookingGlass.js:798
|
||||||
msgid "View Source"
|
msgid "View Source"
|
||||||
msgstr "Vis kildekode"
|
msgstr "Vis kildekode"
|
||||||
|
|
||||||
#: ../js/ui/lookingGlass.js:806
|
#: ../js/ui/lookingGlass.js:807
|
||||||
msgid "Web Page"
|
msgid "Web Page"
|
||||||
msgstr "Nettside"
|
msgstr "Nettside"
|
||||||
|
|
||||||
#: ../js/ui/messageTray.js:1088
|
#: ../js/ui/messageTray.js:1090
|
||||||
msgid "Open"
|
msgid "Open"
|
||||||
msgstr "Åpne"
|
msgstr "Åpne"
|
||||||
|
|
||||||
#: ../js/ui/messageTray.js:1095
|
#: ../js/ui/messageTray.js:1097
|
||||||
msgid "Remove"
|
msgid "Remove"
|
||||||
msgstr "Fjern"
|
msgstr "Fjern"
|
||||||
|
|
||||||
#: ../js/ui/messageTray.js:1551
|
#: ../js/ui/messageTray.js:1554
|
||||||
msgid "No Messages"
|
msgid "No Messages"
|
||||||
msgstr "Ingen meldinger"
|
msgstr "Ingen meldinger"
|
||||||
|
|
||||||
#: ../js/ui/messageTray.js:1568
|
#: ../js/ui/messageTray.js:1572
|
||||||
msgid "Message Tray"
|
msgid "Message Tray"
|
||||||
msgstr "Meldingstrau"
|
msgstr "Meldingstrau"
|
||||||
|
|
||||||
#: ../js/ui/messageTray.js:2635
|
#: ../js/ui/messageTray.js:2641
|
||||||
msgid "System Information"
|
msgid "System Information"
|
||||||
msgstr "Systeminformasjon"
|
msgstr "Systeminformasjon"
|
||||||
|
|
||||||
@ -1170,11 +1164,11 @@ msgctxt "program"
|
|||||||
msgid "Unknown"
|
msgid "Unknown"
|
||||||
msgstr "Ukjent"
|
msgstr "Ukjent"
|
||||||
|
|
||||||
#: ../js/ui/overview.js:95
|
#: ../js/ui/overview.js:92
|
||||||
msgid "Undo"
|
msgid "Undo"
|
||||||
msgstr "Angre"
|
msgstr "Angre"
|
||||||
|
|
||||||
#: ../js/ui/overview.js:144
|
#: ../js/ui/overview.js:139
|
||||||
msgid "Overview"
|
msgid "Overview"
|
||||||
msgstr "Oversikt"
|
msgstr "Oversikt"
|
||||||
|
|
||||||
@ -1182,27 +1176,27 @@ msgstr "Oversikt"
|
|||||||
#. in the search entry when no search is
|
#. in the search entry when no search is
|
||||||
#. active; it should not exceed ~30
|
#. active; it should not exceed ~30
|
||||||
#. characters.
|
#. characters.
|
||||||
#: ../js/ui/overview.js:221
|
#: ../js/ui/overview.js:218
|
||||||
msgid "Type to search..."
|
msgid "Type to search..."
|
||||||
msgstr "Skriv for å søke …"
|
msgstr "Skriv for å søke …"
|
||||||
|
|
||||||
#. Translators: this is the name of the dock/favorites area on
|
#. Translators: this is the name of the dock/favorites area on
|
||||||
#. the left of the overview
|
#. the left of the overview
|
||||||
#: ../js/ui/overview.js:242
|
#: ../js/ui/overview.js:236
|
||||||
msgid "Dash"
|
msgid "Dash"
|
||||||
msgstr "Favoritter"
|
msgstr "Favoritter"
|
||||||
|
|
||||||
#: ../js/ui/panel.js:608
|
#: ../js/ui/panel.js:613
|
||||||
msgid "Quit"
|
msgid "Quit"
|
||||||
msgstr "Avslutt"
|
msgstr "Avslutt"
|
||||||
|
|
||||||
#. Translators: If there is no suitable word for "Activities"
|
#. Translators: If there is no suitable word for "Activities"
|
||||||
#. in your language, you can use the word for "Overview".
|
#. in your language, you can use the word for "Overview".
|
||||||
#: ../js/ui/panel.js:637
|
#: ../js/ui/panel.js:642
|
||||||
msgid "Activities"
|
msgid "Activities"
|
||||||
msgstr "Aktiviteter"
|
msgstr "Aktiviteter"
|
||||||
|
|
||||||
#: ../js/ui/panel.js:980
|
#: ../js/ui/panel.js:976
|
||||||
msgid "Top Bar"
|
msgid "Top Bar"
|
||||||
msgstr "Topp-panel"
|
msgstr "Topp-panel"
|
||||||
|
|
||||||
@ -1211,7 +1205,7 @@ msgstr "Topp-panel"
|
|||||||
#. "ON" and "OFF") or "toggle-switch-intl" (for toggle
|
#. "ON" and "OFF") or "toggle-switch-intl" (for toggle
|
||||||
#. switches containing "◯" and "|"). Other values will
|
#. switches containing "◯" and "|"). Other values will
|
||||||
#. simply result in invisible toggle switches.
|
#. simply result in invisible toggle switches.
|
||||||
#: ../js/ui/popupMenu.js:732
|
#: ../js/ui/popupMenu.js:727
|
||||||
msgid "toggle-switch-us"
|
msgid "toggle-switch-us"
|
||||||
msgstr "toggle-switch-intl"
|
msgstr "toggle-switch-intl"
|
||||||
|
|
||||||
@ -1225,33 +1219,33 @@ msgstr "Lukk"
|
|||||||
|
|
||||||
#. Translators: This is a time format for a date in
|
#. Translators: This is a time format for a date in
|
||||||
#. long format
|
#. long format
|
||||||
#: ../js/ui/screenShield.js:112
|
#: ../js/ui/screenShield.js:113
|
||||||
msgid "%A, %B %d"
|
msgid "%A, %B %d"
|
||||||
msgstr "%A, %B %d"
|
msgstr "%A, %B %d"
|
||||||
|
|
||||||
#: ../js/ui/screenShield.js:176
|
#: ../js/ui/screenShield.js:177
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%d new message"
|
msgid "%d new message"
|
||||||
msgid_plural "%d new messages"
|
msgid_plural "%d new messages"
|
||||||
msgstr[0] "%d ny melding"
|
msgstr[0] "%d ny melding"
|
||||||
msgstr[1] "%d nye meldinger"
|
msgstr[1] "%d nye meldinger"
|
||||||
|
|
||||||
#: ../js/ui/screenShield.js:178
|
#: ../js/ui/screenShield.js:179
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%d new notification"
|
msgid "%d new notification"
|
||||||
msgid_plural "%d new notifications"
|
msgid_plural "%d new notifications"
|
||||||
msgstr[0] "%d ny varsling"
|
msgstr[0] "%d ny varsling"
|
||||||
msgstr[1] "%d nye varslinger"
|
msgstr[1] "%d nye varslinger"
|
||||||
|
|
||||||
#: ../js/ui/screenShield.js:402 ../js/ui/userMenu.js:780
|
#: ../js/ui/screenShield.js:403 ../js/ui/userMenu.js:781
|
||||||
msgid "Lock"
|
msgid "Lock"
|
||||||
msgstr "Lås"
|
msgstr "Lås"
|
||||||
|
|
||||||
#: ../js/ui/searchDisplay.js:277
|
#: ../js/ui/searchDisplay.js:403
|
||||||
msgid "Searching..."
|
msgid "Searching..."
|
||||||
msgstr "Søker …"
|
msgstr "Søker …"
|
||||||
|
|
||||||
#: ../js/ui/searchDisplay.js:325
|
#: ../js/ui/searchDisplay.js:451
|
||||||
msgid "No results."
|
msgid "No results."
|
||||||
msgstr "Ingen resultater."
|
msgstr "Ingen resultater."
|
||||||
|
|
||||||
@ -1367,7 +1361,7 @@ msgid "disconnecting..."
|
|||||||
msgstr "kobler fra …"
|
msgstr "kobler fra …"
|
||||||
|
|
||||||
#: ../js/ui/status/bluetooth.js:220 ../js/ui/status/network.js:442
|
#: ../js/ui/status/bluetooth.js:220 ../js/ui/status/network.js:442
|
||||||
#: ../js/ui/status/network.js:1453
|
#: ../js/ui/status/network.js:1464
|
||||||
msgid "connecting..."
|
msgid "connecting..."
|
||||||
msgstr "kobler til …"
|
msgstr "kobler til …"
|
||||||
|
|
||||||
@ -1383,7 +1377,7 @@ msgstr "Innstillinger for tastatur"
|
|||||||
msgid "Mouse Settings"
|
msgid "Mouse Settings"
|
||||||
msgstr "Innstillinger for mus"
|
msgstr "Innstillinger for mus"
|
||||||
|
|
||||||
#: ../js/ui/status/bluetooth.js:253 ../js/ui/status/volume.js:270
|
#: ../js/ui/status/bluetooth.js:253 ../js/ui/status/volume.js:314
|
||||||
msgid "Sound Settings"
|
msgid "Sound Settings"
|
||||||
msgstr "Innstillinger for lyd"
|
msgstr "Innstillinger for lyd"
|
||||||
|
|
||||||
@ -1447,15 +1441,15 @@ msgstr "Vennligst oppgi PIN som oppgitt på enheten."
|
|||||||
msgid "OK"
|
msgid "OK"
|
||||||
msgstr "OK"
|
msgstr "OK"
|
||||||
|
|
||||||
#: ../js/ui/status/keyboard.js:228
|
#: ../js/ui/status/keyboard.js:363
|
||||||
msgid "Show Keyboard Layout"
|
msgid "Show Keyboard Layout"
|
||||||
msgstr "Vis tastaturutforming"
|
msgstr "Vis tastaturutforming"
|
||||||
|
|
||||||
#: ../js/ui/status/keyboard.js:233
|
#: ../js/ui/status/keyboard.js:368
|
||||||
msgid "Region and Language Settings"
|
msgid "Region and Language Settings"
|
||||||
msgstr "Innstillinger for region og språk"
|
msgstr "Innstillinger for region og språk"
|
||||||
|
|
||||||
#: ../js/ui/status/lockScreenMenu.js:18
|
#: ../js/ui/status/lockScreenMenu.js:43
|
||||||
msgid "Volume, network, battery"
|
msgid "Volume, network, battery"
|
||||||
msgstr "Volum, nettverk, batteri"
|
msgstr "Volum, nettverk, batteri"
|
||||||
|
|
||||||
@ -1475,7 +1469,7 @@ msgid "unmanaged"
|
|||||||
msgstr "ikke håndtert"
|
msgstr "ikke håndtert"
|
||||||
|
|
||||||
#. Translators: this is for network connections that require some kind of key or password
|
#. Translators: this is for network connections that require some kind of key or password
|
||||||
#: ../js/ui/status/network.js:445 ../js/ui/status/network.js:1456
|
#: ../js/ui/status/network.js:445 ../js/ui/status/network.js:1467
|
||||||
msgid "authentication required"
|
msgid "authentication required"
|
||||||
msgstr "autentisering kreves"
|
msgstr "autentisering kreves"
|
||||||
|
|
||||||
@ -1496,72 +1490,72 @@ msgstr "kabel koblet fra"
|
|||||||
msgid "unavailable"
|
msgid "unavailable"
|
||||||
msgstr "ikke tilgjengelig"
|
msgstr "ikke tilgjengelig"
|
||||||
|
|
||||||
#: ../js/ui/status/network.js:469 ../js/ui/status/network.js:1458
|
#: ../js/ui/status/network.js:469 ../js/ui/status/network.js:1469
|
||||||
msgid "connection failed"
|
msgid "connection failed"
|
||||||
msgstr "tilkobling feilet"
|
msgstr "tilkobling feilet"
|
||||||
|
|
||||||
#: ../js/ui/status/network.js:525 ../js/ui/status/network.js:1392
|
#: ../js/ui/status/network.js:525 ../js/ui/status/network.js:1403
|
||||||
#: ../js/ui/status/network.js:1534
|
#: ../js/ui/status/network.js:1545
|
||||||
msgid "More..."
|
msgid "More..."
|
||||||
msgstr "Mer …"
|
msgstr "Mer …"
|
||||||
|
|
||||||
#. TRANSLATORS: this is the indication that a connection for another logged in user is active,
|
#. TRANSLATORS: this is the indication that a connection for another logged in user is active,
|
||||||
#. and we cannot access its settings (including the name)
|
#. and we cannot access its settings (including the name)
|
||||||
#: ../js/ui/status/network.js:561 ../js/ui/status/network.js:1322
|
#: ../js/ui/status/network.js:561 ../js/ui/status/network.js:1333
|
||||||
msgid "Connected (private)"
|
msgid "Connected (private)"
|
||||||
msgstr "Tilkoblet (privat)"
|
msgstr "Tilkoblet (privat)"
|
||||||
|
|
||||||
#: ../js/ui/status/network.js:619
|
#: ../js/ui/status/network.js:641
|
||||||
msgid "Auto Ethernet"
|
msgid "Auto Ethernet"
|
||||||
msgstr "Automatisk Ethernet"
|
msgstr "Automatisk Ethernet"
|
||||||
|
|
||||||
#: ../js/ui/status/network.js:677
|
#: ../js/ui/status/network.js:688
|
||||||
msgid "Auto broadband"
|
msgid "Auto broadband"
|
||||||
msgstr "Automatisk bredbånd"
|
msgstr "Automatisk bredbånd"
|
||||||
|
|
||||||
#: ../js/ui/status/network.js:680
|
#: ../js/ui/status/network.js:691
|
||||||
msgid "Auto dial-up"
|
msgid "Auto dial-up"
|
||||||
msgstr "Automatisk oppringt"
|
msgstr "Automatisk oppringt"
|
||||||
|
|
||||||
#. TRANSLATORS: this the automatic wireless connection name (including the network name)
|
#. TRANSLATORS: this the automatic wireless connection name (including the network name)
|
||||||
#: ../js/ui/status/network.js:809 ../js/ui/status/network.js:1339
|
#: ../js/ui/status/network.js:820 ../js/ui/status/network.js:1350
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Auto %s"
|
msgid "Auto %s"
|
||||||
msgstr "Automatisk %s"
|
msgstr "Automatisk %s"
|
||||||
|
|
||||||
#: ../js/ui/status/network.js:811
|
#: ../js/ui/status/network.js:822
|
||||||
msgid "Auto bluetooth"
|
msgid "Auto bluetooth"
|
||||||
msgstr "Automatisk Bluetooth"
|
msgstr "Automatisk Bluetooth"
|
||||||
|
|
||||||
#: ../js/ui/status/network.js:1341
|
#: ../js/ui/status/network.js:1352
|
||||||
msgid "Auto wireless"
|
msgid "Auto wireless"
|
||||||
msgstr "Automatisk trådløst"
|
msgstr "Automatisk trådløst"
|
||||||
|
|
||||||
#: ../js/ui/status/network.js:1584
|
#: ../js/ui/status/network.js:1595
|
||||||
msgid "Enable networking"
|
msgid "Enable networking"
|
||||||
msgstr "Slå på nettverk"
|
msgstr "Slå på nettverk"
|
||||||
|
|
||||||
#: ../js/ui/status/network.js:1616
|
#: ../js/ui/status/network.js:1627
|
||||||
msgid "Wi-Fi"
|
msgid "Wi-Fi"
|
||||||
msgstr "Wi-Fi"
|
msgstr "Wi-Fi"
|
||||||
|
|
||||||
#: ../js/ui/status/network.js:1635
|
#: ../js/ui/status/network.js:1646
|
||||||
msgid "Network Settings"
|
msgid "Network Settings"
|
||||||
msgstr "Innstillinger for nettverk"
|
msgstr "Innstillinger for nettverk"
|
||||||
|
|
||||||
#: ../js/ui/status/network.js:1679
|
#: ../js/ui/status/network.js:1692
|
||||||
msgid "Network Manager"
|
msgid "Network Manager"
|
||||||
msgstr "Nettverkshåndtering"
|
msgstr "Nettverkshåndtering"
|
||||||
|
|
||||||
#: ../js/ui/status/network.js:1761
|
#: ../js/ui/status/network.js:1774
|
||||||
msgid "Connection failed"
|
msgid "Connection failed"
|
||||||
msgstr "Tilkobling feilet"
|
msgstr "Tilkobling feilet"
|
||||||
|
|
||||||
#: ../js/ui/status/network.js:1762
|
#: ../js/ui/status/network.js:1775
|
||||||
msgid "Activation of network connection failed"
|
msgid "Activation of network connection failed"
|
||||||
msgstr "Aktivering av nettverkstilkobling feilet"
|
msgstr "Aktivering av nettverkstilkobling feilet"
|
||||||
|
|
||||||
#: ../js/ui/status/network.js:2079
|
#: ../js/ui/status/network.js:2092
|
||||||
msgid "Networking is disabled"
|
msgid "Networking is disabled"
|
||||||
msgstr "Nettverk er slått av"
|
msgstr "Nettverk er slått av"
|
||||||
|
|
||||||
@ -1617,65 +1611,65 @@ msgctxt "percent of battery remaining"
|
|||||||
msgid "%d%%"
|
msgid "%d%%"
|
||||||
msgstr "%d%%"
|
msgstr "%d%%"
|
||||||
|
|
||||||
#: ../js/ui/status/power.js:195
|
#: ../js/ui/status/power.js:196
|
||||||
msgid "AC adapter"
|
msgid "AC adapter"
|
||||||
msgstr "Strømadapter"
|
msgstr "Strømadapter"
|
||||||
|
|
||||||
#: ../js/ui/status/power.js:197
|
#: ../js/ui/status/power.js:198
|
||||||
msgid "Laptop battery"
|
msgid "Laptop battery"
|
||||||
msgstr "Batteri på bærbar"
|
msgstr "Batteri på bærbar"
|
||||||
|
|
||||||
#: ../js/ui/status/power.js:199
|
#: ../js/ui/status/power.js:200
|
||||||
msgid "UPS"
|
msgid "UPS"
|
||||||
msgstr "UPS"
|
msgstr "UPS"
|
||||||
|
|
||||||
#: ../js/ui/status/power.js:201
|
#: ../js/ui/status/power.js:202
|
||||||
msgid "Monitor"
|
msgid "Monitor"
|
||||||
msgstr "Skjerm"
|
msgstr "Skjerm"
|
||||||
|
|
||||||
#: ../js/ui/status/power.js:203
|
#: ../js/ui/status/power.js:204
|
||||||
msgid "Mouse"
|
msgid "Mouse"
|
||||||
msgstr "Mus"
|
msgstr "Mus"
|
||||||
|
|
||||||
#: ../js/ui/status/power.js:207
|
#: ../js/ui/status/power.js:208
|
||||||
msgid "PDA"
|
msgid "PDA"
|
||||||
msgstr "PDA"
|
msgstr "PDA"
|
||||||
|
|
||||||
#: ../js/ui/status/power.js:209
|
#: ../js/ui/status/power.js:210
|
||||||
msgid "Cell phone"
|
msgid "Cell phone"
|
||||||
msgstr "Mobiltelefon"
|
msgstr "Mobiltelefon"
|
||||||
|
|
||||||
#: ../js/ui/status/power.js:211
|
#: ../js/ui/status/power.js:212
|
||||||
msgid "Media player"
|
msgid "Media player"
|
||||||
msgstr "Medieavspiller"
|
msgstr "Medieavspiller"
|
||||||
|
|
||||||
#: ../js/ui/status/power.js:213
|
#: ../js/ui/status/power.js:214
|
||||||
msgid "Tablet"
|
msgid "Tablet"
|
||||||
msgstr "Nettbrett"
|
msgstr "Nettbrett"
|
||||||
|
|
||||||
#: ../js/ui/status/power.js:215
|
#: ../js/ui/status/power.js:216
|
||||||
msgid "Computer"
|
msgid "Computer"
|
||||||
msgstr "Datamaskin"
|
msgstr "Datamaskin"
|
||||||
|
|
||||||
#: ../js/ui/status/power.js:217
|
#: ../js/ui/status/power.js:218
|
||||||
msgctxt "device"
|
msgctxt "device"
|
||||||
msgid "Unknown"
|
msgid "Unknown"
|
||||||
msgstr "Ukjent"
|
msgstr "Ukjent"
|
||||||
|
|
||||||
#. Translators: This is the label for audio volume
|
#. Translators: This is the label for audio volume
|
||||||
#: ../js/ui/status/volume.js:50 ../js/ui/status/volume.js:251
|
#: ../js/ui/status/volume.js:247 ../js/ui/status/volume.js:295
|
||||||
msgid "Volume"
|
msgid "Volume"
|
||||||
msgstr "Volum"
|
msgstr "Volum"
|
||||||
|
|
||||||
#: ../js/ui/status/volume.js:62
|
#: ../js/ui/status/volume.js:256
|
||||||
msgid "Microphone"
|
msgid "Microphone"
|
||||||
msgstr "Mikrofon"
|
msgstr "Mikrofon"
|
||||||
|
|
||||||
#: ../js/ui/unlockDialog.js:201
|
#: ../js/ui/unlockDialog.js:203
|
||||||
msgid "Log in as another user"
|
msgid "Log in as another user"
|
||||||
msgstr "Logg inn som en annen bruker"
|
msgstr "Logg inn som en annen bruker"
|
||||||
|
|
||||||
#: ../js/ui/unlockDialog.js:224
|
#: ../js/ui/unlockDialog.js:229
|
||||||
msgid "Unlock Window"
|
msgid "Unlock Window"
|
||||||
msgstr "Lås opp vindu"
|
msgstr "Lås opp vindu"
|
||||||
|
|
||||||
@ -1703,31 +1697,31 @@ msgstr "Ledig"
|
|||||||
msgid "Offline"
|
msgid "Offline"
|
||||||
msgstr "Frakoblet"
|
msgstr "Frakoblet"
|
||||||
|
|
||||||
#: ../js/ui/userMenu.js:754
|
#: ../js/ui/userMenu.js:755
|
||||||
msgid "Notifications"
|
msgid "Notifications"
|
||||||
msgstr "Varslinger"
|
msgstr "Varslinger"
|
||||||
|
|
||||||
#: ../js/ui/userMenu.js:762
|
#: ../js/ui/userMenu.js:763
|
||||||
msgid "Settings"
|
msgid "Settings"
|
||||||
msgstr "Innstillinger"
|
msgstr "Innstillinger"
|
||||||
|
|
||||||
#: ../js/ui/userMenu.js:770
|
#: ../js/ui/userMenu.js:771
|
||||||
msgid "Switch User"
|
msgid "Switch User"
|
||||||
msgstr "Bytt bruker"
|
msgstr "Bytt bruker"
|
||||||
|
|
||||||
#: ../js/ui/userMenu.js:775
|
#: ../js/ui/userMenu.js:776
|
||||||
msgid "Log Out"
|
msgid "Log Out"
|
||||||
msgstr "Logg ut"
|
msgstr "Logg ut"
|
||||||
|
|
||||||
#: ../js/ui/userMenu.js:795
|
#: ../js/ui/userMenu.js:796
|
||||||
msgid "Install Updates & Restart"
|
msgid "Install Updates & Restart"
|
||||||
msgstr "Installer oppdateringer og start på nytt"
|
msgstr "Installer oppdateringer og start på nytt"
|
||||||
|
|
||||||
#: ../js/ui/userMenu.js:813
|
#: ../js/ui/userMenu.js:814
|
||||||
msgid "Your chat status will be set to busy"
|
msgid "Your chat status will be set to busy"
|
||||||
msgstr "Din pratestatus vil bli satt til opptatt"
|
msgstr "Din pratestatus vil bli satt til opptatt"
|
||||||
|
|
||||||
#: ../js/ui/userMenu.js:814
|
#: ../js/ui/userMenu.js:815
|
||||||
msgid ""
|
msgid ""
|
||||||
"Notifications are now disabled, including chat messages. Your online status "
|
"Notifications are now disabled, including chat messages. Your online status "
|
||||||
"has been adjusted to let others know that you might not see their messages."
|
"has been adjusted to let others know that you might not see their messages."
|
||||||
@ -1736,15 +1730,15 @@ msgstr ""
|
|||||||
"tilkoblingsstatus er justert for å la andre vite at du kanskje ikke ser "
|
"tilkoblingsstatus er justert for å la andre vite at du kanskje ikke ser "
|
||||||
"deres meldinger."
|
"deres meldinger."
|
||||||
|
|
||||||
#: ../js/ui/viewSelector.js:91
|
#: ../js/ui/viewSelector.js:85
|
||||||
msgid "Applications"
|
msgid "Applications"
|
||||||
msgstr "Programmer"
|
msgstr "Programmer"
|
||||||
|
|
||||||
#: ../js/ui/viewSelector.js:95
|
#: ../js/ui/viewSelector.js:89
|
||||||
msgid "Search"
|
msgid "Search"
|
||||||
msgstr "Søk"
|
msgstr "Søk"
|
||||||
|
|
||||||
#: ../js/ui/wanda.js:94
|
#: ../js/ui/wanda.js:92
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"Sorry, no wisdom for you today:\n"
|
"Sorry, no wisdom for you today:\n"
|
||||||
@ -1753,15 +1747,11 @@ msgstr ""
|
|||||||
"Beklager, ingen visdom til deg i dag:\n"
|
"Beklager, ingen visdom til deg i dag:\n"
|
||||||
"%s"
|
"%s"
|
||||||
|
|
||||||
#: ../js/ui/wanda.js:98
|
#: ../js/ui/wanda.js:96
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%s the Oracle says"
|
msgid "%s the Oracle says"
|
||||||
msgstr "Orakelet sier %s"
|
msgstr "Orakelet sier %s"
|
||||||
|
|
||||||
#: ../js/ui/wanda.js:139
|
|
||||||
msgid "Your favorite Easter Egg"
|
|
||||||
msgstr "Favorittpåskeegget ditt"
|
|
||||||
|
|
||||||
#: ../js/ui/windowAttentionHandler.js:19
|
#: ../js/ui/windowAttentionHandler.js:19
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "'%s' is ready"
|
msgid "'%s' is ready"
|
||||||
@ -1771,6 +1761,28 @@ msgstr "«%s» er klar"
|
|||||||
msgid "Evolution Calendar"
|
msgid "Evolution Calendar"
|
||||||
msgstr "Evolution kalender"
|
msgstr "Evolution kalender"
|
||||||
|
|
||||||
|
#. translators:
|
||||||
|
#. * The number of sound outputs on a particular device
|
||||||
|
#: ../src/gvc/gvc-mixer-control.c:1837
|
||||||
|
#, c-format
|
||||||
|
msgid "%u Output"
|
||||||
|
msgid_plural "%u Outputs"
|
||||||
|
msgstr[0] "%u utgang"
|
||||||
|
msgstr[1] "%u utganger"
|
||||||
|
|
||||||
|
#. translators:
|
||||||
|
#. * The number of sound inputs on a particular device
|
||||||
|
#: ../src/gvc/gvc-mixer-control.c:1847
|
||||||
|
#, c-format
|
||||||
|
msgid "%u Input"
|
||||||
|
msgid_plural "%u Inputs"
|
||||||
|
msgstr[0] "%u inngang"
|
||||||
|
msgstr[1] "%u innganger"
|
||||||
|
|
||||||
|
#: ../src/gvc/gvc-mixer-control.c:2371
|
||||||
|
msgid "System Sounds"
|
||||||
|
msgstr "Systemlyder"
|
||||||
|
|
||||||
#: ../src/main.c:332
|
#: ../src/main.c:332
|
||||||
msgid "Print version"
|
msgid "Print version"
|
||||||
msgstr "Skriv ut versjon"
|
msgstr "Skriv ut versjon"
|
||||||
|
1059
po/pt_BR.po
1059
po/pt_BR.po
File diff suppressed because it is too large
Load Diff
828
po/zh_CN.po
828
po/zh_CN.po
File diff suppressed because it is too large
Load Diff
@ -75,9 +75,8 @@ def start_shell():
|
|||||||
if 'GI_TYPELIB_PATH' in os.environ:
|
if 'GI_TYPELIB_PATH' in os.environ:
|
||||||
typelib_dir += ':%s' % (os.environ['GI_TYPELIB_PATH'],)
|
typelib_dir += ':%s' % (os.environ['GI_TYPELIB_PATH'],)
|
||||||
|
|
||||||
env.update({'GNOME_SHELL_JS' : os.path.join(top_dir, "js"),
|
env.update({'GI_TYPELIB_PATH' : typelib_dir,
|
||||||
'GNOME_SHELL_BINDIR' : self_dir,
|
'GNOME_SHELL_JS' : os.path.join(top_dir, "js"),
|
||||||
'GI_TYPELIB_PATH' : typelib_dir,
|
|
||||||
'GNOME_SHELL_DATADIR' : os.path.join(top_dir, "data"),
|
'GNOME_SHELL_DATADIR' : os.path.join(top_dir, "data"),
|
||||||
'GSETTINGS_SCHEMA_DIR' : os.path.join(top_dir, "data") })
|
'GSETTINGS_SCHEMA_DIR' : os.path.join(top_dir, "data") })
|
||||||
|
|
||||||
|
@ -284,12 +284,44 @@ gnome_shell_plugin_kill_switch_workspace (MetaPlugin *plugin)
|
|||||||
_shell_wm_kill_switch_workspace (get_shell_wm());
|
_shell_wm_kill_switch_workspace (get_shell_wm());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
ignore_crossing_event (MetaPlugin *plugin,
|
||||||
|
XIEnterEvent *enter_event)
|
||||||
|
{
|
||||||
|
MetaScreen *screen = meta_plugin_get_screen (plugin);
|
||||||
|
ClutterStage *stage = CLUTTER_STAGE (meta_get_stage_for_screen (screen));
|
||||||
|
|
||||||
|
if (enter_event->event == clutter_x11_get_stage_window (stage))
|
||||||
|
{
|
||||||
|
/* If the pointer enters a child of the stage window (eg, a
|
||||||
|
* trayicon), we want to consider it to still be in the stage,
|
||||||
|
* so don't let Clutter see the event.
|
||||||
|
*/
|
||||||
|
if (enter_event->detail == XINotifyInferior)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
/* If the pointer is grabbed by a window it is not currently in,
|
||||||
|
* filter that out as well. In particular, if a trayicon grabs
|
||||||
|
* the pointer after a click on its label, we don't want to hide
|
||||||
|
* the message tray. Filtering out this event will leave Clutter
|
||||||
|
* out of sync, but that happens fairly often with grabs, and we
|
||||||
|
* can work around it. (Eg, shell_global_sync_pointer().)
|
||||||
|
*/
|
||||||
|
if (enter_event->mode == XINotifyGrab &&
|
||||||
|
(enter_event->detail == XINotifyNonlinear ||
|
||||||
|
enter_event->detail == XINotifyNonlinearVirtual))
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gnome_shell_plugin_xevent_filter (MetaPlugin *plugin,
|
gnome_shell_plugin_xevent_filter (MetaPlugin *plugin,
|
||||||
XEvent *xev)
|
XEvent *xev)
|
||||||
{
|
{
|
||||||
MetaScreen *screen = meta_plugin_get_screen (plugin);
|
MetaScreen *screen = meta_plugin_get_screen (plugin);
|
||||||
ClutterStage *stage = CLUTTER_STAGE (meta_get_stage_for_screen (screen));
|
MetaDisplay *display = meta_screen_get_display (screen);
|
||||||
|
|
||||||
GnomeShellPlugin *shell_plugin = GNOME_SHELL_PLUGIN (plugin);
|
GnomeShellPlugin *shell_plugin = GNOME_SHELL_PLUGIN (plugin);
|
||||||
#ifdef GLX_INTEL_swap_event
|
#ifdef GLX_INTEL_swap_event
|
||||||
@ -309,26 +341,15 @@ gnome_shell_plugin_xevent_filter (MetaPlugin *plugin,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if ((xev->xany.type == EnterNotify || xev->xany.type == LeaveNotify)
|
/* Make sure that Clutter doesn't see certain focus change events,
|
||||||
&& xev->xcrossing.window == clutter_x11_get_stage_window (stage))
|
* so that when we're moving into something like a tray icon, we
|
||||||
|
* don't unfocus the container. */
|
||||||
|
if (xev->type == GenericEvent &&
|
||||||
|
xev->xcookie.extension == meta_display_get_xinput_opcode (display))
|
||||||
{
|
{
|
||||||
/* If the pointer enters a child of the stage window (eg, a
|
XIEvent *input_event = (XIEvent *) xev->xcookie.data;
|
||||||
* trayicon), we want to consider it to still be in the stage,
|
if ((input_event->evtype == XI_Enter || input_event->evtype == XI_Leave) &&
|
||||||
* so don't let Clutter see the event.
|
ignore_crossing_event (plugin, (XIEnterEvent *) input_event))
|
||||||
*/
|
|
||||||
if (xev->xcrossing.detail == NotifyInferior)
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
/* If the pointer is grabbed by a window it is not currently in,
|
|
||||||
* filter that out as well. In particular, if a trayicon grabs
|
|
||||||
* the pointer after a click on its label, we don't want to hide
|
|
||||||
* the message tray. Filtering out this event will leave Clutter
|
|
||||||
* out of sync, but that happens fairly often with grabs, and we
|
|
||||||
* can work around it. (Eg, shell_global_sync_pointer().)
|
|
||||||
*/
|
|
||||||
if (xev->xcrossing.mode == NotifyGrab &&
|
|
||||||
(xev->xcrossing.detail == NotifyNonlinear ||
|
|
||||||
xev->xcrossing.detail == NotifyNonlinearVirtual))
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
2
src/gvc
2
src/gvc
Submodule src/gvc updated: 40cdff2479...03894efbcd
@ -738,7 +738,8 @@ normalize_terms (GSList *terms)
|
|||||||
for (iter = terms; iter; iter = iter->next)
|
for (iter = terms; iter; iter = iter->next)
|
||||||
{
|
{
|
||||||
const char *term = iter->data;
|
const char *term = iter->data;
|
||||||
normalized_terms = g_slist_prepend (normalized_terms, shell_util_normalize_and_casefold (term));
|
normalized_terms = g_slist_prepend (normalized_terms,
|
||||||
|
shell_util_normalize_casefold_and_unaccent (term));
|
||||||
}
|
}
|
||||||
return normalized_terms;
|
return normalized_terms;
|
||||||
}
|
}
|
||||||
|
@ -1319,16 +1319,16 @@ shell_app_init_search_data (ShellApp *app)
|
|||||||
|
|
||||||
appinfo = gmenu_tree_entry_get_app_info (app->entry);
|
appinfo = gmenu_tree_entry_get_app_info (app->entry);
|
||||||
name = g_app_info_get_name (G_APP_INFO (appinfo));
|
name = g_app_info_get_name (G_APP_INFO (appinfo));
|
||||||
app->casefolded_name = shell_util_normalize_and_casefold (name);
|
app->casefolded_name = shell_util_normalize_casefold_and_unaccent (name);
|
||||||
|
|
||||||
generic_name = g_desktop_app_info_get_generic_name (appinfo);
|
generic_name = g_desktop_app_info_get_generic_name (appinfo);
|
||||||
if (generic_name)
|
if (generic_name)
|
||||||
app->casefolded_generic_name = shell_util_normalize_and_casefold (generic_name);
|
app->casefolded_generic_name = shell_util_normalize_casefold_and_unaccent (generic_name);
|
||||||
else
|
else
|
||||||
app->casefolded_generic_name = NULL;
|
app->casefolded_generic_name = NULL;
|
||||||
|
|
||||||
exec = g_app_info_get_executable (G_APP_INFO (appinfo));
|
exec = g_app_info_get_executable (G_APP_INFO (appinfo));
|
||||||
normalized_exec = shell_util_normalize_and_casefold (exec);
|
normalized_exec = shell_util_normalize_casefold_and_unaccent (exec);
|
||||||
app->casefolded_exec = trim_exec_line (normalized_exec);
|
app->casefolded_exec = trim_exec_line (normalized_exec);
|
||||||
g_free (normalized_exec);
|
g_free (normalized_exec);
|
||||||
|
|
||||||
@ -1343,7 +1343,7 @@ shell_app_init_search_data (ShellApp *app)
|
|||||||
i = 0;
|
i = 0;
|
||||||
while (keywords[i])
|
while (keywords[i])
|
||||||
{
|
{
|
||||||
app->casefolded_keywords[i] = shell_util_normalize_and_casefold (keywords[i]);
|
app->casefolded_keywords[i] = shell_util_normalize_casefold_and_unaccent (keywords[i]);
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
app->casefolded_keywords[i] = NULL;
|
app->casefolded_keywords[i] = NULL;
|
||||||
|
@ -616,6 +616,9 @@ shell_global_set_cursor (ShellGlobal *global,
|
|||||||
case SHELL_CURSOR_POINTING_HAND:
|
case SHELL_CURSOR_POINTING_HAND:
|
||||||
name = "hand";
|
name = "hand";
|
||||||
break;
|
break;
|
||||||
|
case SHELL_CURSOR_CROSSHAIR:
|
||||||
|
name = "crosshair";
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
g_return_if_reached ();
|
g_return_if_reached ();
|
||||||
}
|
}
|
||||||
@ -638,6 +641,9 @@ shell_global_set_cursor (ShellGlobal *global,
|
|||||||
case SHELL_CURSOR_POINTING_HAND:
|
case SHELL_CURSOR_POINTING_HAND:
|
||||||
cursor_type = GDK_HAND2;
|
cursor_type = GDK_HAND2;
|
||||||
break;
|
break;
|
||||||
|
case SHELL_CURSOR_CROSSHAIR:
|
||||||
|
cursor_type = GDK_CROSSHAIR;
|
||||||
|
break;
|
||||||
case SHELL_CURSOR_DND_UNSUPPORTED_TARGET:
|
case SHELL_CURSOR_DND_UNSUPPORTED_TARGET:
|
||||||
cursor_type = GDK_X_CURSOR;
|
cursor_type = GDK_X_CURSOR;
|
||||||
break;
|
break;
|
||||||
@ -1404,7 +1410,6 @@ guint32
|
|||||||
shell_global_get_current_time (ShellGlobal *global)
|
shell_global_get_current_time (ShellGlobal *global)
|
||||||
{
|
{
|
||||||
guint32 time;
|
guint32 time;
|
||||||
const ClutterEvent *clutter_event;
|
|
||||||
|
|
||||||
/* In case we have a xdnd timestamp use it */
|
/* In case we have a xdnd timestamp use it */
|
||||||
if (global->xdnd_timestamp != 0)
|
if (global->xdnd_timestamp != 0)
|
||||||
@ -1415,7 +1420,7 @@ shell_global_get_current_time (ShellGlobal *global)
|
|||||||
from some Clutter event callbacks.
|
from some Clutter event callbacks.
|
||||||
|
|
||||||
clutter_get_current_event_time() will return the correct time
|
clutter_get_current_event_time() will return the correct time
|
||||||
from a Clutter event callback, but may return an out-of-date
|
from a Clutter event callback, but may return CLUTTER_CURRENT_TIME
|
||||||
timestamp if called at other times.
|
timestamp if called at other times.
|
||||||
|
|
||||||
So we try meta_display_get_current_time() first, since we
|
So we try meta_display_get_current_time() first, since we
|
||||||
@ -1425,17 +1430,9 @@ shell_global_get_current_time (ShellGlobal *global)
|
|||||||
|
|
||||||
time = meta_display_get_current_time (global->meta_display);
|
time = meta_display_get_current_time (global->meta_display);
|
||||||
if (time != CLUTTER_CURRENT_TIME)
|
if (time != CLUTTER_CURRENT_TIME)
|
||||||
return time;
|
return time;
|
||||||
/*
|
|
||||||
* We don't use clutter_get_current_event_time as it can give us a
|
|
||||||
* too old timestamp if there is no current event.
|
|
||||||
*/
|
|
||||||
clutter_event = clutter_get_current_event ();
|
|
||||||
|
|
||||||
if (clutter_event != NULL)
|
return clutter_get_current_event_time ();
|
||||||
return clutter_event_get_time (clutter_event);
|
|
||||||
else
|
|
||||||
return CLUTTER_CURRENT_TIME;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -63,7 +63,8 @@ typedef enum {
|
|||||||
SHELL_CURSOR_DND_UNSUPPORTED_TARGET,
|
SHELL_CURSOR_DND_UNSUPPORTED_TARGET,
|
||||||
SHELL_CURSOR_DND_MOVE,
|
SHELL_CURSOR_DND_MOVE,
|
||||||
SHELL_CURSOR_DND_COPY,
|
SHELL_CURSOR_DND_COPY,
|
||||||
SHELL_CURSOR_POINTING_HAND
|
SHELL_CURSOR_POINTING_HAND,
|
||||||
|
SHELL_CURSOR_CROSSHAIR
|
||||||
} ShellCursor;
|
} ShellCursor;
|
||||||
|
|
||||||
void shell_global_set_cursor (ShellGlobal *global,
|
void shell_global_set_cursor (ShellGlobal *global,
|
||||||
|
@ -32,6 +32,7 @@ typedef struct _screenshot_data {
|
|||||||
ShellScreenshot *screenshot;
|
ShellScreenshot *screenshot;
|
||||||
|
|
||||||
char *filename;
|
char *filename;
|
||||||
|
char *filename_used;
|
||||||
|
|
||||||
cairo_surface_t *image;
|
cairo_surface_t *image;
|
||||||
cairo_rectangle_int_t screenshot_area;
|
cairo_rectangle_int_t screenshot_area;
|
||||||
@ -64,25 +65,140 @@ on_screenshot_written (GObject *source,
|
|||||||
if (screenshot_data->callback)
|
if (screenshot_data->callback)
|
||||||
screenshot_data->callback (screenshot_data->screenshot,
|
screenshot_data->callback (screenshot_data->screenshot,
|
||||||
g_simple_async_result_get_op_res_gboolean (G_SIMPLE_ASYNC_RESULT (result)),
|
g_simple_async_result_get_op_res_gboolean (G_SIMPLE_ASYNC_RESULT (result)),
|
||||||
&screenshot_data->screenshot_area);
|
&screenshot_data->screenshot_area,
|
||||||
|
screenshot_data->filename_used);
|
||||||
|
|
||||||
cairo_surface_destroy (screenshot_data->image);
|
cairo_surface_destroy (screenshot_data->image);
|
||||||
g_object_unref (screenshot_data->screenshot);
|
g_object_unref (screenshot_data->screenshot);
|
||||||
g_free (screenshot_data->filename);
|
g_free (screenshot_data->filename);
|
||||||
|
g_free (screenshot_data->filename_used);
|
||||||
g_free (screenshot_data);
|
g_free (screenshot_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* called in an I/O thread */
|
||||||
|
static GOutputStream *
|
||||||
|
get_stream_for_unique_path (const gchar *path,
|
||||||
|
const gchar *filename,
|
||||||
|
gchar **filename_used)
|
||||||
|
{
|
||||||
|
GOutputStream *stream;
|
||||||
|
GFile *file;
|
||||||
|
gchar *real_path, *real_filename, *name, *ptr;
|
||||||
|
gint idx;
|
||||||
|
|
||||||
|
ptr = g_strrstr (filename, ".png");
|
||||||
|
|
||||||
|
if (ptr != NULL)
|
||||||
|
real_filename = g_strndup (filename, ptr - filename);
|
||||||
|
else
|
||||||
|
real_filename = g_strdup (filename);
|
||||||
|
|
||||||
|
idx = 0;
|
||||||
|
real_path = NULL;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if (idx == 0)
|
||||||
|
name = g_strdup_printf ("%s.png", real_filename);
|
||||||
|
else
|
||||||
|
name = g_strdup_printf ("%s - %d.png", real_filename, idx);
|
||||||
|
|
||||||
|
real_path = g_build_filename (path, name, NULL);
|
||||||
|
g_free (name);
|
||||||
|
|
||||||
|
file = g_file_new_for_path (real_path);
|
||||||
|
stream = G_OUTPUT_STREAM (g_file_create (file, G_FILE_CREATE_NONE, NULL, NULL));
|
||||||
|
g_object_unref (file);
|
||||||
|
|
||||||
|
if (stream != NULL)
|
||||||
|
*filename_used = real_path;
|
||||||
|
else
|
||||||
|
g_free (real_path);
|
||||||
|
|
||||||
|
idx++;
|
||||||
|
}
|
||||||
|
while (stream == NULL);
|
||||||
|
|
||||||
|
g_free (real_filename);
|
||||||
|
|
||||||
|
return stream;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* called in an I/O thread */
|
||||||
|
static GOutputStream *
|
||||||
|
get_stream_for_filename (const gchar *filename,
|
||||||
|
gchar **filename_used)
|
||||||
|
{
|
||||||
|
const gchar *path;
|
||||||
|
|
||||||
|
path = g_get_user_special_dir (G_USER_DIRECTORY_PICTURES);
|
||||||
|
if (!g_file_test (path, G_FILE_TEST_EXISTS))
|
||||||
|
{
|
||||||
|
path = g_get_home_dir ();
|
||||||
|
if (!g_file_test (path, G_FILE_TEST_EXISTS))
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return get_stream_for_unique_path (path, filename, filename_used);
|
||||||
|
}
|
||||||
|
|
||||||
|
static GOutputStream *
|
||||||
|
prepare_write_stream (const gchar *filename,
|
||||||
|
gchar **filename_used)
|
||||||
|
{
|
||||||
|
GOutputStream *stream;
|
||||||
|
GFile *file;
|
||||||
|
|
||||||
|
if (g_path_is_absolute (filename))
|
||||||
|
{
|
||||||
|
file = g_file_new_for_path (filename);
|
||||||
|
*filename_used = g_strdup (filename);
|
||||||
|
stream = G_OUTPUT_STREAM (g_file_replace (file, NULL, FALSE, G_FILE_CREATE_NONE, NULL, NULL));
|
||||||
|
g_object_unref (file);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
stream = get_stream_for_filename (filename, filename_used);
|
||||||
|
}
|
||||||
|
|
||||||
|
return stream;
|
||||||
|
}
|
||||||
|
|
||||||
|
static cairo_status_t
|
||||||
|
do_write_to_stream (void *closure,
|
||||||
|
const guchar *data,
|
||||||
|
guint length)
|
||||||
|
{
|
||||||
|
GOutputStream *stream = closure;
|
||||||
|
gboolean res;
|
||||||
|
|
||||||
|
res = g_output_stream_write_all (stream, data, length, NULL, NULL, NULL);
|
||||||
|
|
||||||
|
return res ? CAIRO_STATUS_SUCCESS : CAIRO_STATUS_WRITE_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
write_screenshot_thread (GSimpleAsyncResult *result,
|
write_screenshot_thread (GSimpleAsyncResult *result,
|
||||||
GObject *object,
|
GObject *object,
|
||||||
GCancellable *cancellable)
|
GCancellable *cancellable)
|
||||||
{
|
{
|
||||||
cairo_status_t status;
|
cairo_status_t status;
|
||||||
|
GOutputStream *stream;
|
||||||
_screenshot_data *screenshot_data = g_async_result_get_user_data (G_ASYNC_RESULT (result));
|
_screenshot_data *screenshot_data = g_async_result_get_user_data (G_ASYNC_RESULT (result));
|
||||||
|
|
||||||
g_assert (screenshot_data != NULL);
|
g_assert (screenshot_data != NULL);
|
||||||
|
|
||||||
status = cairo_surface_write_to_png (screenshot_data->image, screenshot_data->filename);
|
stream = prepare_write_stream (screenshot_data->filename,
|
||||||
|
&screenshot_data->filename_used);
|
||||||
|
|
||||||
|
if (stream == NULL)
|
||||||
|
status = CAIRO_STATUS_FILE_NOT_FOUND;
|
||||||
|
else
|
||||||
|
status = cairo_surface_write_to_png_stream (screenshot_data->image, do_write_to_stream, stream);
|
||||||
|
|
||||||
g_simple_async_result_set_op_res_gboolean (result, status == CAIRO_STATUS_SUCCESS);
|
g_simple_async_result_set_op_res_gboolean (result, status == CAIRO_STATUS_SUCCESS);
|
||||||
|
|
||||||
|
g_clear_object (&stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -26,8 +26,9 @@ GType shell_screenshot_get_type (void) G_GNUC_CONST;
|
|||||||
ShellScreenshot *shell_screenshot_new (void);
|
ShellScreenshot *shell_screenshot_new (void);
|
||||||
|
|
||||||
typedef void (*ShellScreenshotCallback) (ShellScreenshot *screenshot,
|
typedef void (*ShellScreenshotCallback) (ShellScreenshot *screenshot,
|
||||||
gboolean success,
|
gboolean success,
|
||||||
cairo_rectangle_int_t *screenshot_area);
|
cairo_rectangle_int_t *screenshot_area,
|
||||||
|
const gchar *filename_used);
|
||||||
|
|
||||||
void shell_screenshot_screenshot_area (ShellScreenshot *screenshot,
|
void shell_screenshot_screenshot_area (ShellScreenshot *screenshot,
|
||||||
int x,
|
int x,
|
||||||
|
@ -122,12 +122,90 @@ shell_util_normalize_and_casefold (const char *str)
|
|||||||
if (str == NULL)
|
if (str == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
/* NOTE: 'ALL' is equivalent to 'NFKD'. If this is ever updated, please
|
||||||
|
* update the unaccenting mechanism as well. */
|
||||||
normalized = g_utf8_normalize (str, -1, G_NORMALIZE_ALL);
|
normalized = g_utf8_normalize (str, -1, G_NORMALIZE_ALL);
|
||||||
result = g_utf8_casefold (normalized, -1);
|
result = g_utf8_casefold (normalized, -1);
|
||||||
g_free (normalized);
|
g_free (normalized);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Combining diacritical mark?
|
||||||
|
* Basic range: [0x0300,0x036F]
|
||||||
|
* Supplement: [0x1DC0,0x1DFF]
|
||||||
|
* For Symbols: [0x20D0,0x20FF]
|
||||||
|
* Half marks: [0xFE20,0xFE2F]
|
||||||
|
*/
|
||||||
|
#define IS_CDM_UCS4(c) (((c) >= 0x0300 && (c) <= 0x036F) || \
|
||||||
|
((c) >= 0x1DC0 && (c) <= 0x1DFF) || \
|
||||||
|
((c) >= 0x20D0 && (c) <= 0x20FF) || \
|
||||||
|
((c) >= 0xFE20 && (c) <= 0xFE2F))
|
||||||
|
|
||||||
|
/* Copied from tracker/src/libtracker-fts/tracker-parser-glib.c under the GPL
|
||||||
|
* Originally written by Aleksander Morgado <aleksander@gnu.org>
|
||||||
|
*/
|
||||||
|
char *
|
||||||
|
shell_util_normalize_casefold_and_unaccent (const char *str)
|
||||||
|
{
|
||||||
|
char *tmp;
|
||||||
|
gsize i = 0, j = 0, ilen;
|
||||||
|
|
||||||
|
if (str == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
/* Get the NFKD-normalized and casefolded string */
|
||||||
|
tmp = shell_util_normalize_and_casefold (str);
|
||||||
|
ilen = strlen (tmp);
|
||||||
|
|
||||||
|
while (i < ilen)
|
||||||
|
{
|
||||||
|
gunichar unichar;
|
||||||
|
gchar *next_utf8;
|
||||||
|
gint utf8_len;
|
||||||
|
|
||||||
|
/* Get next character of the word as UCS4 */
|
||||||
|
unichar = g_utf8_get_char_validated (&tmp[i], -1);
|
||||||
|
|
||||||
|
/* Invalid UTF-8 character or end of original string. */
|
||||||
|
if (unichar == (gunichar) -1 ||
|
||||||
|
unichar == (gunichar) -2)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Find next UTF-8 character */
|
||||||
|
next_utf8 = g_utf8_next_char (&tmp[i]);
|
||||||
|
utf8_len = next_utf8 - &tmp[i];
|
||||||
|
|
||||||
|
if (IS_CDM_UCS4 ((guint32) unichar))
|
||||||
|
{
|
||||||
|
/* If the given unichar is a combining diacritical mark,
|
||||||
|
* just update the original index, not the output one */
|
||||||
|
i += utf8_len;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If already found a previous combining
|
||||||
|
* diacritical mark, indexes are different so
|
||||||
|
* need to copy characters. As output and input
|
||||||
|
* buffers may overlap, need to use memmove
|
||||||
|
* instead of memcpy */
|
||||||
|
if (i != j)
|
||||||
|
{
|
||||||
|
memmove (&tmp[j], &tmp[i], utf8_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Update both indexes */
|
||||||
|
i += utf8_len;
|
||||||
|
j += utf8_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Force proper string end */
|
||||||
|
tmp[j] = '\0';
|
||||||
|
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* shell_util_format_date:
|
* shell_util_format_date:
|
||||||
* @format: a strftime-style string format, as parsed by
|
* @format: a strftime-style string format, as parsed by
|
||||||
|
@ -20,6 +20,8 @@ int shell_util_get_week_start (void);
|
|||||||
|
|
||||||
char *shell_util_normalize_and_casefold (const char *str);
|
char *shell_util_normalize_and_casefold (const char *str);
|
||||||
|
|
||||||
|
char *shell_util_normalize_casefold_and_unaccent (const char *str);
|
||||||
|
|
||||||
char *shell_util_format_date (const char *format,
|
char *shell_util_format_date (const char *format,
|
||||||
gint64 time_ms);
|
gint64 time_ms);
|
||||||
|
|
||||||
|
@ -32,6 +32,7 @@
|
|||||||
|
|
||||||
#include <glib-object.h>
|
#include <glib-object.h>
|
||||||
#include <clutter/clutter.h>
|
#include <clutter/clutter.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
#include "st-adjustment.h"
|
#include "st-adjustment.h"
|
||||||
#include "st-private.h"
|
#include "st-private.h"
|
||||||
@ -566,3 +567,31 @@ st_adjustment_get_values (StAdjustment *adjustment,
|
|||||||
*page_size = priv->page_size;
|
*page_size = priv->page_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* st_adjustment_adjust_for_scroll_event:
|
||||||
|
* @adjustment: An #StAdjustment
|
||||||
|
* @delta: A delta, retrieved directly from clutter_event_get_scroll_delta()
|
||||||
|
* or similar.
|
||||||
|
*
|
||||||
|
* Adjusts the adjustment using delta values from a scroll event.
|
||||||
|
* You should use this instead of using st_adjustment_set_value()
|
||||||
|
* as this method will tweak the values directly using the same
|
||||||
|
* math as GTK+, to ensure that scrolling is consistent across
|
||||||
|
* the environment.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
st_adjustment_adjust_for_scroll_event (StAdjustment *adjustment,
|
||||||
|
gdouble delta)
|
||||||
|
{
|
||||||
|
StAdjustmentPrivate *priv;
|
||||||
|
gdouble new_value, scroll_unit;
|
||||||
|
|
||||||
|
g_return_if_fail (ST_IS_ADJUSTMENT (adjustment));
|
||||||
|
|
||||||
|
priv = adjustment->priv;
|
||||||
|
|
||||||
|
scroll_unit = pow (priv->page_size, 2.0 / 3.0);
|
||||||
|
|
||||||
|
new_value = priv->value + delta * scroll_unit;
|
||||||
|
st_adjustment_set_value (adjustment, new_value);
|
||||||
|
}
|
||||||
|
@ -99,6 +99,10 @@ void st_adjustment_get_values (StAdjustment *adjustment,
|
|||||||
gdouble *step_increment,
|
gdouble *step_increment,
|
||||||
gdouble *page_increment,
|
gdouble *page_increment,
|
||||||
gdouble *page_size);
|
gdouble *page_size);
|
||||||
|
|
||||||
|
void st_adjustment_adjust_for_scroll_event (StAdjustment *adjustment,
|
||||||
|
gdouble delta);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* __ST_ADJUSTMENT_H__ */
|
#endif /* __ST_ADJUSTMENT_H__ */
|
||||||
|
@ -152,7 +152,7 @@ st_drawing_area_paint (ClutterActor *self)
|
|||||||
|
|
||||||
cogl_set_source (priv->material);
|
cogl_set_source (priv->material);
|
||||||
cogl_rectangle_with_texture_coords (content_box.x1, content_box.y1,
|
cogl_rectangle_with_texture_coords (content_box.x1, content_box.y1,
|
||||||
width, height,
|
content_box.x2, content_box.y2,
|
||||||
0.0f, 0.0f, 1.0f, 1.0f);
|
0.0f, 0.0f, 1.0f, 1.0f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -433,42 +433,57 @@ st_scroll_bar_constructor (GType type,
|
|||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
adjust_with_direction (StAdjustment *adj,
|
||||||
|
ClutterScrollDirection direction)
|
||||||
|
{
|
||||||
|
gdouble delta;
|
||||||
|
|
||||||
|
switch (direction)
|
||||||
|
{
|
||||||
|
case CLUTTER_SCROLL_UP:
|
||||||
|
case CLUTTER_SCROLL_LEFT:
|
||||||
|
delta = -1.0;
|
||||||
|
break;
|
||||||
|
case CLUTTER_SCROLL_RIGHT:
|
||||||
|
case CLUTTER_SCROLL_DOWN:
|
||||||
|
delta = 1.0;
|
||||||
|
break;
|
||||||
|
case CLUTTER_SCROLL_SMOOTH:
|
||||||
|
g_assert_not_reached ();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
st_adjustment_adjust_for_scroll_event (adj, delta);
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
st_scroll_bar_scroll_event (ClutterActor *actor,
|
st_scroll_bar_scroll_event (ClutterActor *actor,
|
||||||
ClutterScrollEvent *event)
|
ClutterScrollEvent *event)
|
||||||
{
|
{
|
||||||
StScrollBarPrivate *priv = ST_SCROLL_BAR (actor)->priv;
|
StScrollBarPrivate *priv = ST_SCROLL_BAR (actor)->priv;
|
||||||
gdouble step, value, delta_x, delta_y;
|
|
||||||
|
|
||||||
if (priv->adjustment)
|
if (clutter_event_is_pointer_emulated ((ClutterEvent *) event))
|
||||||
{
|
return TRUE;
|
||||||
g_object_get (priv->adjustment,
|
|
||||||
"step-increment", &step,
|
|
||||||
"value", &value,
|
|
||||||
NULL);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (event->direction)
|
switch (event->direction)
|
||||||
{
|
{
|
||||||
case CLUTTER_SCROLL_SMOOTH:
|
case CLUTTER_SCROLL_SMOOTH:
|
||||||
clutter_event_get_scroll_delta ((ClutterEvent *)event,
|
{
|
||||||
&delta_x, &delta_y);
|
gdouble delta_x, delta_y;
|
||||||
if (fabs (delta_x) > fabs (delta_y))
|
clutter_event_get_scroll_delta ((ClutterEvent *)event, &delta_x, &delta_y);
|
||||||
st_adjustment_set_value (priv->adjustment, value + delta_x);
|
|
||||||
else
|
if (priv->vertical)
|
||||||
st_adjustment_set_value (priv->adjustment, value + delta_y);
|
st_adjustment_adjust_for_scroll_event (priv->adjustment, delta_y);
|
||||||
|
else
|
||||||
|
st_adjustment_adjust_for_scroll_event (priv->adjustment, delta_x);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case CLUTTER_SCROLL_UP:
|
case CLUTTER_SCROLL_UP:
|
||||||
case CLUTTER_SCROLL_LEFT:
|
|
||||||
st_adjustment_set_value (priv->adjustment, value - step);
|
|
||||||
break;
|
|
||||||
case CLUTTER_SCROLL_DOWN:
|
case CLUTTER_SCROLL_DOWN:
|
||||||
|
case CLUTTER_SCROLL_LEFT:
|
||||||
case CLUTTER_SCROLL_RIGHT:
|
case CLUTTER_SCROLL_RIGHT:
|
||||||
st_adjustment_set_value (priv->adjustment, value + step);
|
adjust_with_direction (priv->adjustment, event->direction);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -665,6 +665,31 @@ st_scroll_view_allocate (ClutterActor *actor,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
adjust_with_direction (StAdjustment *adj,
|
||||||
|
ClutterScrollDirection direction)
|
||||||
|
{
|
||||||
|
gdouble delta;
|
||||||
|
|
||||||
|
switch (direction)
|
||||||
|
{
|
||||||
|
case CLUTTER_SCROLL_UP:
|
||||||
|
case CLUTTER_SCROLL_LEFT:
|
||||||
|
delta = -1.0;
|
||||||
|
break;
|
||||||
|
case CLUTTER_SCROLL_RIGHT:
|
||||||
|
case CLUTTER_SCROLL_DOWN:
|
||||||
|
delta = 1.0;
|
||||||
|
break;
|
||||||
|
case CLUTTER_SCROLL_SMOOTH:
|
||||||
|
default:
|
||||||
|
g_assert_not_reached ();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
st_adjustment_adjust_for_scroll_event (adj, delta);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
st_scroll_view_style_changed (StWidget *widget)
|
st_scroll_view_style_changed (StWidget *widget)
|
||||||
{
|
{
|
||||||
@ -687,57 +712,31 @@ st_scroll_view_scroll_event (ClutterActor *self,
|
|||||||
ClutterScrollEvent *event)
|
ClutterScrollEvent *event)
|
||||||
{
|
{
|
||||||
StScrollViewPrivate *priv = ST_SCROLL_VIEW (self)->priv;
|
StScrollViewPrivate *priv = ST_SCROLL_VIEW (self)->priv;
|
||||||
gdouble value, step, hvalue, vvalue, delta_x, delta_y;
|
|
||||||
|
|
||||||
/* don't handle scroll events if requested not to */
|
/* don't handle scroll events if requested not to */
|
||||||
if (!priv->mouse_scroll)
|
if (!priv->mouse_scroll)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
switch (event->direction)
|
if (clutter_event_is_pointer_emulated ((ClutterEvent *) event))
|
||||||
{
|
return TRUE;
|
||||||
case CLUTTER_SCROLL_SMOOTH:
|
|
||||||
clutter_event_get_scroll_delta ((ClutterEvent *)event,
|
|
||||||
&delta_x, &delta_y);
|
|
||||||
g_object_get (priv->hadjustment,
|
|
||||||
"value", &hvalue,
|
|
||||||
NULL);
|
|
||||||
g_object_get (priv->vadjustment,
|
|
||||||
"value", &vvalue,
|
|
||||||
NULL);
|
|
||||||
break;
|
|
||||||
case CLUTTER_SCROLL_UP:
|
|
||||||
case CLUTTER_SCROLL_DOWN:
|
|
||||||
g_object_get (priv->vadjustment,
|
|
||||||
"step-increment", &step,
|
|
||||||
"value", &value,
|
|
||||||
NULL);
|
|
||||||
break;
|
|
||||||
case CLUTTER_SCROLL_LEFT:
|
|
||||||
case CLUTTER_SCROLL_RIGHT:
|
|
||||||
g_object_get (priv->hadjustment,
|
|
||||||
"step-increment", &step,
|
|
||||||
"value", &value,
|
|
||||||
NULL);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (event->direction)
|
switch (event->direction)
|
||||||
{
|
{
|
||||||
case CLUTTER_SCROLL_SMOOTH:
|
case CLUTTER_SCROLL_SMOOTH:
|
||||||
st_adjustment_set_value (priv->hadjustment, hvalue + delta_x);
|
{
|
||||||
st_adjustment_set_value (priv->vadjustment, vvalue + delta_y);
|
gdouble delta_x, delta_y;
|
||||||
|
clutter_event_get_scroll_delta ((ClutterEvent *)event, &delta_x, &delta_y);
|
||||||
|
st_adjustment_adjust_for_scroll_event (priv->hadjustment, delta_x);
|
||||||
|
st_adjustment_adjust_for_scroll_event (priv->vadjustment, delta_y);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case CLUTTER_SCROLL_UP:
|
case CLUTTER_SCROLL_UP:
|
||||||
st_adjustment_set_value (priv->vadjustment, value - step);
|
|
||||||
break;
|
|
||||||
case CLUTTER_SCROLL_DOWN:
|
case CLUTTER_SCROLL_DOWN:
|
||||||
st_adjustment_set_value (priv->vadjustment, value + step);
|
adjust_with_direction (priv->vadjustment, event->direction);
|
||||||
break;
|
break;
|
||||||
case CLUTTER_SCROLL_LEFT:
|
case CLUTTER_SCROLL_LEFT:
|
||||||
st_adjustment_set_value (priv->hadjustment, value - step);
|
|
||||||
break;
|
|
||||||
case CLUTTER_SCROLL_RIGHT:
|
case CLUTTER_SCROLL_RIGHT:
|
||||||
st_adjustment_set_value (priv->hadjustment, value + step);
|
adjust_with_direction (priv->hadjustment, event->direction);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,8 +30,6 @@
|
|||||||
#define CACHE_PREFIX_ICON "icon:"
|
#define CACHE_PREFIX_ICON "icon:"
|
||||||
#define CACHE_PREFIX_URI "uri:"
|
#define CACHE_PREFIX_URI "uri:"
|
||||||
#define CACHE_PREFIX_URI_FOR_CAIRO "uri-for-cairo:"
|
#define CACHE_PREFIX_URI_FOR_CAIRO "uri-for-cairo:"
|
||||||
#define CACHE_PREFIX_RAW_CHECKSUM "raw-checksum:"
|
|
||||||
#define CACHE_PREFIX_COMPRESSED_CHECKSUM "compressed-checksum:"
|
|
||||||
|
|
||||||
struct _StTextureCachePrivate
|
struct _StTextureCachePrivate
|
||||||
{
|
{
|
||||||
@ -1414,63 +1412,6 @@ st_texture_cache_load_file_to_cairo_surface (StTextureCache *cache,
|
|||||||
return surface;
|
return surface;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* st_texture_cache_load_from_raw:
|
|
||||||
* @cache: a #StTextureCache
|
|
||||||
* @data: (array length=len): raw pixel data
|
|
||||||
* @len: the length of @data
|
|
||||||
* @has_alpha: whether @data includes an alpha channel
|
|
||||||
* @width: width in pixels of @data
|
|
||||||
* @height: width in pixels of @data
|
|
||||||
* @rowstride: rowstride of @data
|
|
||||||
* @size: size of icon to return
|
|
||||||
*
|
|
||||||
* Creates (or retrieves from cache) an icon based on raw pixel data.
|
|
||||||
*
|
|
||||||
* Return value: (transfer none): a new #ClutterActor displaying a
|
|
||||||
* pixbuf created from @data and the other parameters.
|
|
||||||
**/
|
|
||||||
ClutterActor *
|
|
||||||
st_texture_cache_load_from_raw (StTextureCache *cache,
|
|
||||||
const guchar *data,
|
|
||||||
gsize len,
|
|
||||||
gboolean has_alpha,
|
|
||||||
int width,
|
|
||||||
int height,
|
|
||||||
int rowstride,
|
|
||||||
int size,
|
|
||||||
GError **error)
|
|
||||||
{
|
|
||||||
ClutterTexture *texture;
|
|
||||||
CoglHandle texdata;
|
|
||||||
char *key;
|
|
||||||
char *checksum;
|
|
||||||
|
|
||||||
texture = create_default_texture ();
|
|
||||||
clutter_actor_set_size (CLUTTER_ACTOR (texture), size, size);
|
|
||||||
|
|
||||||
/* In theory, two images of with different width and height could have the same
|
|
||||||
* pixel data and thus hash the same. (Say, a 16x16 and a 8x32 blank image.)
|
|
||||||
* We ignore this for now. If anybody hits this problem they should use
|
|
||||||
* GChecksum directly to compute a checksum including the width and height.
|
|
||||||
*/
|
|
||||||
checksum = g_compute_checksum_for_data (G_CHECKSUM_SHA1, data, len);
|
|
||||||
key = g_strdup_printf (CACHE_PREFIX_RAW_CHECKSUM "checksum=%s", checksum);
|
|
||||||
g_free (checksum);
|
|
||||||
|
|
||||||
texdata = g_hash_table_lookup (cache->priv->keyed_cache, key);
|
|
||||||
if (texdata == NULL)
|
|
||||||
{
|
|
||||||
texdata = data_to_cogl_handle (data, has_alpha, width, height, rowstride, TRUE);
|
|
||||||
g_hash_table_insert (cache->priv->keyed_cache, g_strdup (key), texdata);
|
|
||||||
}
|
|
||||||
|
|
||||||
g_free (key);
|
|
||||||
|
|
||||||
set_texture_cogl_texture (texture, texdata);
|
|
||||||
return CLUTTER_ACTOR (texture);
|
|
||||||
}
|
|
||||||
|
|
||||||
static StTextureCache *instance = NULL;
|
static StTextureCache *instance = NULL;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -96,16 +96,6 @@ CoglHandle st_texture_cache_load_file_to_cogl_texture (StTextureCache *cache,
|
|||||||
cairo_surface_t *st_texture_cache_load_file_to_cairo_surface (StTextureCache *cache,
|
cairo_surface_t *st_texture_cache_load_file_to_cairo_surface (StTextureCache *cache,
|
||||||
const gchar *file_path);
|
const gchar *file_path);
|
||||||
|
|
||||||
ClutterActor *st_texture_cache_load_from_raw (StTextureCache *cache,
|
|
||||||
const guchar *data,
|
|
||||||
gsize len,
|
|
||||||
gboolean has_alpha,
|
|
||||||
int width,
|
|
||||||
int height,
|
|
||||||
int rowstride,
|
|
||||||
int size,
|
|
||||||
GError **error);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* StTextureCacheLoader: (skip)
|
* StTextureCacheLoader: (skip)
|
||||||
* @cache: a #StTextureCache
|
* @cache: a #StTextureCache
|
||||||
|
@ -770,6 +770,72 @@ st_theme_node_lookup_double (StThemeNode *node,
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* st_theme_node_lookup_time:
|
||||||
|
* @node: a #StThemeNode
|
||||||
|
* @property_name: The name of the time property
|
||||||
|
* @inherit: if %TRUE, if a value is not found for the property on the
|
||||||
|
* node, then it will be looked up on the parent node, and then on the
|
||||||
|
* parent's parent, and so forth. Note that if the property has a
|
||||||
|
* value of 'inherit' it will be inherited even if %FALSE is passed
|
||||||
|
* in for @inherit; this only affects the default behavior for inheritance.
|
||||||
|
* @value: (out): location to store the value that was determined.
|
||||||
|
* If the property is not found, the value in this location
|
||||||
|
* will not be changed.
|
||||||
|
*
|
||||||
|
* Generically looks up a property containing a single time value,
|
||||||
|
* which is converted to milliseconds.
|
||||||
|
*
|
||||||
|
* Return value: %TRUE if the property was found in the properties for this
|
||||||
|
* theme node (or in the properties of parent nodes when inheriting.)
|
||||||
|
*/
|
||||||
|
gboolean
|
||||||
|
st_theme_node_lookup_time (StThemeNode *node,
|
||||||
|
const char *property_name,
|
||||||
|
gboolean inherit,
|
||||||
|
double *value)
|
||||||
|
{
|
||||||
|
gboolean result = FALSE;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
ensure_properties (node);
|
||||||
|
|
||||||
|
for (i = node->n_properties - 1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
CRDeclaration *decl = node->properties[i];
|
||||||
|
|
||||||
|
if (strcmp (decl->property->stryng->str, property_name) == 0)
|
||||||
|
{
|
||||||
|
CRTerm *term = decl->value;
|
||||||
|
|
||||||
|
if (term->type != TERM_NUMBER)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
switch (term->content.num->type)
|
||||||
|
{
|
||||||
|
case NUM_TIME_S:
|
||||||
|
*value = 1000 * term->content.num->val;
|
||||||
|
result = TRUE;
|
||||||
|
break;
|
||||||
|
case NUM_TIME_MS:
|
||||||
|
*value = term->content.num->val;
|
||||||
|
result = TRUE;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!result && inherit && node->parent_node)
|
||||||
|
result = st_theme_node_lookup_time (node->parent_node, property_name, inherit, value);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* st_theme_node_get_double:
|
* st_theme_node_get_double:
|
||||||
* @node: a #StThemeNode
|
* @node: a #StThemeNode
|
||||||
@ -1738,15 +1804,19 @@ _st_theme_node_ensure_background (StThemeNode *node)
|
|||||||
else if (term->type == TERM_URI)
|
else if (term->type == TERM_URI)
|
||||||
{
|
{
|
||||||
CRStyleSheet *base_stylesheet;
|
CRStyleSheet *base_stylesheet;
|
||||||
|
GFile *file;
|
||||||
|
|
||||||
if (decl->parent_statement != NULL)
|
if (decl->parent_statement != NULL)
|
||||||
base_stylesheet = decl->parent_statement->parent_sheet;
|
base_stylesheet = decl->parent_statement->parent_sheet;
|
||||||
else
|
else
|
||||||
base_stylesheet = NULL;
|
base_stylesheet = NULL;
|
||||||
|
|
||||||
node->background_image = _st_theme_resolve_url (node->theme,
|
file = _st_theme_resolve_url (node->theme,
|
||||||
base_stylesheet,
|
base_stylesheet,
|
||||||
term->content.str->stryng->str);
|
term->content.str->stryng->str);
|
||||||
|
|
||||||
|
node->background_image = g_file_get_path (file);
|
||||||
|
g_object_unref (file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1843,6 +1913,7 @@ _st_theme_node_ensure_background (StThemeNode *node)
|
|||||||
if (decl->value->type == TERM_URI)
|
if (decl->value->type == TERM_URI)
|
||||||
{
|
{
|
||||||
CRStyleSheet *base_stylesheet;
|
CRStyleSheet *base_stylesheet;
|
||||||
|
GFile *file;
|
||||||
|
|
||||||
if (decl->parent_statement != NULL)
|
if (decl->parent_statement != NULL)
|
||||||
base_stylesheet = decl->parent_statement->parent_sheet;
|
base_stylesheet = decl->parent_statement->parent_sheet;
|
||||||
@ -1850,9 +1921,12 @@ _st_theme_node_ensure_background (StThemeNode *node)
|
|||||||
base_stylesheet = NULL;
|
base_stylesheet = NULL;
|
||||||
|
|
||||||
g_free (node->background_image);
|
g_free (node->background_image);
|
||||||
node->background_image = _st_theme_resolve_url (node->theme,
|
file = _st_theme_resolve_url (node->theme,
|
||||||
base_stylesheet,
|
base_stylesheet,
|
||||||
decl->value->content.str->stryng->str);
|
decl->value->content.str->stryng->str);
|
||||||
|
|
||||||
|
node->background_image = g_file_get_path (file);
|
||||||
|
g_object_unref (file);
|
||||||
}
|
}
|
||||||
else if (term_is_inherit (decl->value))
|
else if (term_is_inherit (decl->value))
|
||||||
{
|
{
|
||||||
@ -2055,7 +2129,7 @@ st_theme_node_get_transition_duration (StThemeNode *node)
|
|||||||
if (node->transition_duration > -1)
|
if (node->transition_duration > -1)
|
||||||
return st_slow_down_factor * node->transition_duration;
|
return st_slow_down_factor * node->transition_duration;
|
||||||
|
|
||||||
st_theme_node_lookup_double (node, "transition-duration", FALSE, &value);
|
st_theme_node_lookup_time (node, "transition-duration", FALSE, &value);
|
||||||
|
|
||||||
node->transition_duration = (int)value;
|
node->transition_duration = (int)value;
|
||||||
|
|
||||||
@ -2668,6 +2742,7 @@ st_theme_node_get_border_image (StThemeNode *node)
|
|||||||
int border_bottom;
|
int border_bottom;
|
||||||
int border_left;
|
int border_left;
|
||||||
|
|
||||||
|
GFile *file;
|
||||||
char *filename;
|
char *filename;
|
||||||
|
|
||||||
/* Support border-image: none; to suppress a previously specified border image */
|
/* Support border-image: none; to suppress a previously specified border image */
|
||||||
@ -2746,7 +2821,10 @@ st_theme_node_get_border_image (StThemeNode *node)
|
|||||||
else
|
else
|
||||||
base_stylesheet = NULL;
|
base_stylesheet = NULL;
|
||||||
|
|
||||||
filename = _st_theme_resolve_url (node->theme, base_stylesheet, url);
|
file = _st_theme_resolve_url (node->theme, base_stylesheet, url);
|
||||||
|
filename = g_file_get_path (file);
|
||||||
|
g_object_unref (file);
|
||||||
|
|
||||||
if (filename == NULL)
|
if (filename == NULL)
|
||||||
goto next_property;
|
goto next_property;
|
||||||
|
|
||||||
|
@ -134,6 +134,10 @@ gboolean st_theme_node_lookup_length (StThemeNode *node,
|
|||||||
const char *property_name,
|
const char *property_name,
|
||||||
gboolean inherit,
|
gboolean inherit,
|
||||||
gdouble *length);
|
gdouble *length);
|
||||||
|
gboolean st_theme_node_lookup_time (StThemeNode *node,
|
||||||
|
const char *property_name,
|
||||||
|
gboolean inherit,
|
||||||
|
gdouble *value);
|
||||||
gboolean st_theme_node_lookup_shadow (StThemeNode *node,
|
gboolean st_theme_node_lookup_shadow (StThemeNode *node,
|
||||||
const char *property_name,
|
const char *property_name,
|
||||||
gboolean inherit,
|
gboolean inherit,
|
||||||
|
@ -29,10 +29,10 @@ G_BEGIN_DECLS
|
|||||||
GPtrArray *_st_theme_get_matched_properties (StTheme *theme,
|
GPtrArray *_st_theme_get_matched_properties (StTheme *theme,
|
||||||
StThemeNode *node);
|
StThemeNode *node);
|
||||||
|
|
||||||
/* Resolve an URL from the stylesheet to a filename */
|
/* Resolve an URL from the stylesheet to a file */
|
||||||
char *_st_theme_resolve_url (StTheme *theme,
|
GFile *_st_theme_resolve_url (StTheme *theme,
|
||||||
CRStyleSheet *base_stylesheet,
|
CRStyleSheet *base_stylesheet,
|
||||||
const char *url);
|
const char *url);
|
||||||
|
|
||||||
CRDeclaration *_st_theme_parse_declaration_list (const char *str);
|
CRDeclaration *_st_theme_parse_declaration_list (const char *str);
|
||||||
|
|
||||||
|
@ -849,9 +849,16 @@ add_matched_properties (StTheme *a_this,
|
|||||||
char *filename = NULL;
|
char *filename = NULL;
|
||||||
|
|
||||||
if (import_rule->url->stryng && import_rule->url->stryng->str)
|
if (import_rule->url->stryng && import_rule->url->stryng->str)
|
||||||
filename = _st_theme_resolve_url (a_this,
|
{
|
||||||
a_nodesheet,
|
GFile *file;
|
||||||
import_rule->url->stryng->str);
|
|
||||||
|
file = _st_theme_resolve_url (a_this,
|
||||||
|
a_nodesheet,
|
||||||
|
import_rule->url->stryng->str);
|
||||||
|
filename = g_file_get_path (file);
|
||||||
|
|
||||||
|
g_object_unref (file);
|
||||||
|
}
|
||||||
|
|
||||||
if (filename)
|
if (filename)
|
||||||
import_rule->sheet = parse_stylesheet (filename, NULL);
|
import_rule->sheet = parse_stylesheet (filename, NULL);
|
||||||
@ -999,84 +1006,41 @@ _st_theme_get_matched_properties (StTheme *theme,
|
|||||||
* local filename, if possible. The resolution here is distinctly lame and
|
* local filename, if possible. The resolution here is distinctly lame and
|
||||||
* will fail on many examples.
|
* will fail on many examples.
|
||||||
*/
|
*/
|
||||||
char *
|
GFile *
|
||||||
_st_theme_resolve_url (StTheme *theme,
|
_st_theme_resolve_url (StTheme *theme,
|
||||||
CRStyleSheet *base_stylesheet,
|
CRStyleSheet *base_stylesheet,
|
||||||
const char *url)
|
const char *url)
|
||||||
{
|
{
|
||||||
const char *base_filename = NULL;
|
char *scheme;
|
||||||
char *dirname;
|
GFile *stylesheet, *resource;
|
||||||
char *filename;
|
|
||||||
char *canonicalized_path;
|
|
||||||
|
|
||||||
/* Handle absolute file:/ URLs */
|
if ((scheme = g_uri_parse_scheme (url)))
|
||||||
if (g_str_has_prefix (url, "file:") ||
|
|
||||||
g_str_has_prefix (url, "File:") ||
|
|
||||||
g_str_has_prefix (url, "FILE:"))
|
|
||||||
{
|
{
|
||||||
GError *error = NULL;
|
g_free (scheme);
|
||||||
char *filename;
|
resource = g_file_new_for_uri (url);
|
||||||
|
|
||||||
filename = g_filename_from_uri (url, NULL, &error);
|
|
||||||
if (filename == NULL)
|
|
||||||
{
|
|
||||||
g_warning ("%s", error->message);
|
|
||||||
g_error_free (error);
|
|
||||||
}
|
|
||||||
|
|
||||||
return filename;
|
|
||||||
}
|
}
|
||||||
|
else if (base_stylesheet != NULL)
|
||||||
/* Guard against http:/ URLs */
|
|
||||||
|
|
||||||
if (g_str_has_prefix (url, "http:") ||
|
|
||||||
g_str_has_prefix (url, "Http:") ||
|
|
||||||
g_str_has_prefix (url, "HTTP:"))
|
|
||||||
{
|
{
|
||||||
g_warning ("Http URL '%s' in theme stylesheet is not supported", url);
|
const char *base_filename = NULL;
|
||||||
return NULL;
|
char *dirname;
|
||||||
}
|
|
||||||
|
|
||||||
/* Assume anything else is a relative URL, and "resolve" it
|
base_filename = g_hash_table_lookup (theme->filenames_by_stylesheet, base_stylesheet);
|
||||||
*/
|
|
||||||
if (url[0] == '/')
|
|
||||||
{
|
|
||||||
canonicalized_path = realpath (url, NULL);
|
|
||||||
if (g_mem_is_system_malloc ())
|
|
||||||
{
|
|
||||||
filename = canonicalized_path;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
filename = g_strdup (canonicalized_path);
|
|
||||||
free (canonicalized_path);
|
|
||||||
}
|
|
||||||
return filename;
|
|
||||||
}
|
|
||||||
|
|
||||||
base_filename = g_hash_table_lookup (theme->filenames_by_stylesheet, base_stylesheet);
|
/* This is an internal function, if we get here with
|
||||||
|
a bad @base_stylesheet we have a problem. */
|
||||||
|
g_assert (base_filename);
|
||||||
|
|
||||||
if (base_filename == NULL)
|
dirname = g_path_get_dirname (base_filename);
|
||||||
{
|
stylesheet = g_file_new_for_path (dirname);
|
||||||
g_warning ("Can't get base to resolve url '%s'", url);
|
resource = g_file_resolve_relative_path (stylesheet, url);
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
dirname = g_path_get_dirname (base_filename);
|
g_object_unref (stylesheet);
|
||||||
filename = g_build_filename (dirname, url, NULL);
|
g_free (dirname);
|
||||||
canonicalized_path = realpath (filename, NULL);
|
|
||||||
g_free (dirname);
|
|
||||||
g_free (filename);
|
|
||||||
|
|
||||||
if (g_mem_is_system_malloc ())
|
|
||||||
{
|
|
||||||
filename = canonicalized_path;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
filename = g_strdup (canonicalized_path);
|
resource = g_file_new_for_path (url);
|
||||||
free (canonicalized_path);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return filename;
|
return resource;
|
||||||
}
|
}
|
||||||
|
@ -30,13 +30,15 @@ builddir=`cd $builddir && pwd`
|
|||||||
srcdir=$builddir/@srcdir@
|
srcdir=$builddir/@srcdir@
|
||||||
srcdir=`cd $srcdir && pwd`
|
srcdir=`cd $srcdir && pwd`
|
||||||
|
|
||||||
GI_TYPELIB_PATH="$GI_TYPELIB_PATH${GI_TYPELIB_PATH:+:}@MUTTER_TYPELIB_DIR@:$builddir/../src"
|
GI_TYPELIB_PATH="$GI_TYPELIB_PATH${GI_TYPELIB_PATH:+:}@MUTTER_TYPELIB_DIR@:$builddir/../src:$builddir/../src/gvc"
|
||||||
GJS_PATH="$srcdir:$srcdir/../js"
|
GJS_PATH="$srcdir:$srcdir/../js"
|
||||||
GJS_DEBUG_OUTPUT=stderr
|
GJS_DEBUG_OUTPUT=stderr
|
||||||
$verbose || GJS_DEBUG_TOPICS="JS ERROR;JS LOG"
|
$verbose || GJS_DEBUG_TOPICS="JS ERROR;JS LOG"
|
||||||
GNOME_SHELL_TESTSDIR="$srcdir/"
|
GNOME_SHELL_TESTSDIR="$srcdir/"
|
||||||
|
GNOME_SHELL_JS="$srcdir/../js"
|
||||||
|
GNOME_SHELL_DATADIR="$srcdir/../data"
|
||||||
|
|
||||||
export GI_TYPELIB_PATH GJS_PATH GJS_DEBUG_OUTPUT GJS_DEBUG_TOPICS GNOME_SHELL_JS GNOME_SHELL_TESTSDIR LD_PRELOAD
|
export GI_TYPELIB_PATH GJS_PATH GJS_DEBUG_OUTPUT GJS_DEBUG_TOPICS GNOME_SHELL_TESTSDIR GNOME_SHELL_JS GNOME_SHELL_DATADIR LD_PRELOAD
|
||||||
|
|
||||||
for test in $tests ; do
|
for test in $tests ; do
|
||||||
$debug $builddir/../src/run-js-test $test || exit $?
|
$debug $builddir/../src/run-js-test $test || exit $?
|
||||||
|
@ -98,7 +98,7 @@ stage {
|
|||||||
background-color: #333;
|
background-color: #333;
|
||||||
border: 2px solid black;
|
border: 2px solid black;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
transition-duration: 1000; /* One second */
|
transition-duration: 1s;
|
||||||
}
|
}
|
||||||
|
|
||||||
#transition-container:hover .transition-label {
|
#transition-container:hover .transition-label {
|
||||||
|
Reference in New Issue
Block a user