Compare commits
66 Commits
wip/re-sea
...
3.7.3.1-br
Author | SHA1 | Date | |
---|---|---|---|
7d598b7725 | |||
9f890982b2 | |||
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 \
|
||||||
|
61
NEWS
61
NEWS
@ -1,3 +1,64 @@
|
|||||||
|
3.7.3.1
|
||||||
|
=======
|
||||||
|
* Revert 490206b to not depend on NMGTK-0.9.7, which hasn't been released yet
|
||||||
|
|
||||||
|
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]
|
||||||
|
15
configure.ac
15
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.3.1],[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.3
|
||||||
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,7 @@ 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
|
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
|
||||||
@ -99,9 +99,8 @@ PKG_CHECK_MODULES(GNOME_SHELL, gio-unix-2.0 >= $GIO_MIN_VERSION
|
|||||||
telepathy-glib >= $TELEPATHY_GLIB_MIN_VERSION
|
telepathy-glib >= $TELEPATHY_GLIB_MIN_VERSION
|
||||||
telepathy-logger-0.2 >= $TELEPATHY_LOGGER_MIN_VERSION
|
telepathy-logger-0.2 >= $TELEPATHY_LOGGER_MIN_VERSION
|
||||||
polkit-agent-1 >= $POLKIT_MIN_VERSION xfixes
|
polkit-agent-1 >= $POLKIT_MIN_VERSION xfixes
|
||||||
libnm-glib libnm-util >= $NETWORKMANAGER_MIN_VERSION
|
libnm-glib libnm-util gnome-keyring-1
|
||||||
libnm-gtk >= $NETWORKMANAGER_MIN_VERSION
|
gcr-3 >= $GCR_MIN_VERSION)
|
||||||
gnome-keyring-1 gcr-3 >= $GCR_MIN_VERSION)
|
|
||||||
|
|
||||||
PKG_CHECK_MODULES(SHELL_PERF_HELPER, gtk+-3.0 gio-2.0)
|
PKG_CHECK_MODULES(SHELL_PERF_HELPER, gtk+-3.0 gio-2.0)
|
||||||
|
|
||||||
@ -125,8 +124,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],
|
||||||
|
@ -34,6 +34,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 \
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
@ -558,6 +558,10 @@ StScrollBar StButton#vhandle:active {
|
|||||||
spacing: 4px;
|
spacing: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.lock-screen-status-button-box {
|
||||||
|
spacing: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
/* User Menu */
|
/* User Menu */
|
||||||
|
|
||||||
#panelUserMenu {
|
#panelUserMenu {
|
||||||
@ -613,7 +617,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 +714,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 +772,7 @@ StScrollBar StButton#vhandle:active {
|
|||||||
|
|
||||||
#searchResultsContent {
|
#searchResultsContent {
|
||||||
padding-right: 20px;
|
padding-right: 20px;
|
||||||
spacing: 36px;
|
spacing: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#searchResultsContent:rtl {
|
#searchResultsContent:rtl {
|
||||||
@ -768,11 +780,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 +804,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 +834,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,9 +886,34 @@ 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);
|
||||||
@ -889,7 +929,9 @@ 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: 100;
|
||||||
@ -924,10 +966,14 @@ StScrollBar StButton#vhandle:active {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.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);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1271,6 +1317,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,7 +1329,7 @@ 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: 10px;
|
||||||
spacing-columns: 10px;
|
spacing-columns: 10px;
|
||||||
@ -1311,7 +1361,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;
|
||||||
@ -1499,10 +1549,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;
|
||||||
}
|
}
|
||||||
@ -2389,3 +2435,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 |
@ -62,6 +62,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 \
|
||||||
|
@ -159,6 +159,86 @@ function killall(processName) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This was ported from network-manager-applet
|
||||||
|
// Copyright 2007 - 2011 Red Hat, Inc.
|
||||||
|
// Author: Dan Williams <dcbw@redhat.com>
|
||||||
|
|
||||||
|
const _IGNORED_WORDS = [
|
||||||
|
'Semiconductor',
|
||||||
|
'Components',
|
||||||
|
'Corporation',
|
||||||
|
'Communications',
|
||||||
|
'Company',
|
||||||
|
'Corp.',
|
||||||
|
'Corp',
|
||||||
|
'Co.',
|
||||||
|
'Inc.',
|
||||||
|
'Inc',
|
||||||
|
'Incorporated',
|
||||||
|
'Ltd.',
|
||||||
|
'Limited.',
|
||||||
|
'Intel',
|
||||||
|
'chipset',
|
||||||
|
'adapter',
|
||||||
|
'[hex]',
|
||||||
|
'NDIS',
|
||||||
|
'Module'
|
||||||
|
];
|
||||||
|
|
||||||
|
const _IGNORED_PHRASES = [
|
||||||
|
'Multiprotocol MAC/baseband processor',
|
||||||
|
'Wireless LAN Controller',
|
||||||
|
'Wireless LAN Adapter',
|
||||||
|
'Wireless Adapter',
|
||||||
|
'Network Connection',
|
||||||
|
'Wireless Cardbus Adapter',
|
||||||
|
'Wireless CardBus Adapter',
|
||||||
|
'54 Mbps Wireless PC Card',
|
||||||
|
'Wireless PC Card',
|
||||||
|
'Wireless PC',
|
||||||
|
'PC Card with XJACK(r) Antenna',
|
||||||
|
'Wireless cardbus',
|
||||||
|
'Wireless LAN PC Card',
|
||||||
|
'Technology Group Ltd.',
|
||||||
|
'Communication S.p.A.',
|
||||||
|
'Business Mobile Networks BV',
|
||||||
|
'Mobile Broadband Minicard Composite Device',
|
||||||
|
'Mobile Communications AB',
|
||||||
|
'(PC-Suite Mode)'
|
||||||
|
];
|
||||||
|
|
||||||
|
function fixupPCIDescription(desc) {
|
||||||
|
desc = desc.replace(/[_,]/, ' ');
|
||||||
|
|
||||||
|
/* Attempt to shorten ID by ignoring certain phrases */
|
||||||
|
for (let i = 0; i < _IGNORED_PHRASES.length; i++) {
|
||||||
|
let item = _IGNORED_PHRASES[i];
|
||||||
|
let pos = desc.indexOf(item);
|
||||||
|
if (pos != -1) {
|
||||||
|
let before = desc.substring(0, pos);
|
||||||
|
let after = desc.substring(pos + item.length, desc.length);
|
||||||
|
desc = before + after;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Attmept to shorten ID by ignoring certain individual words */
|
||||||
|
let words = desc.split(' ');
|
||||||
|
let out = [ ];
|
||||||
|
for (let i = 0; i < words.length; i++) {
|
||||||
|
let item = words[i];
|
||||||
|
|
||||||
|
// skip empty items (that come out from consecutive spaces)
|
||||||
|
if (item.length == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (_IGNORED_WORDS.indexOf(item) == -1) {
|
||||||
|
out.push(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return out.join(' ');
|
||||||
|
}
|
||||||
|
|
||||||
// lowerBound:
|
// lowerBound:
|
||||||
// @array: an array or array-like object, already sorted
|
// @array: an array or array-like object, already sorted
|
||||||
// according to @cmp
|
// according to @cmp
|
||||||
|
@ -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());
|
||||||
|
@ -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:
|
||||||
|
@ -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) {
|
||||||
|
@ -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 });
|
||||||
}
|
}
|
||||||
|
@ -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,
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -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;
|
||||||
@ -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 &&
|
||||||
|
@ -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;
|
||||||
@ -160,13 +161,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();
|
||||||
|
@ -1412,7 +1412,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,
|
||||||
|
@ -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;
|
||||||
|
@ -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 % */
|
||||||
@ -405,29 +405,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();
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -50,6 +50,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 +167,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 +175,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();
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -195,9 +198,7 @@ const RemoteSearchProvider = new Lang.Class({
|
|||||||
width, height, rowStride, size);
|
width, height, rowStride, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ugh, but we want to fall back to something ...
|
return null;
|
||||||
return new St.Icon({ icon_name: 'text-x-generic',
|
|
||||||
icon_size: size });
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_getResultsFinished: function(results, error) {
|
_getResultsFinished: function(results, error) {
|
||||||
@ -290,6 +291,6 @@ const RemoteSearchProvider2 = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
launchSearch: function(terms) {
|
launchSearch: function(terms) {
|
||||||
this.proxy.LaunchSearchRemote(terms);
|
this.proxy.LaunchSearchRemote(terms, global.get_current_time());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
34
js/ui/separator.js
Normal file
34
js/ui/separator.js
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
// -*- 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();
|
||||||
|
}
|
||||||
|
});
|
@ -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));
|
||||||
|
@ -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();
|
||||||
@ -241,18 +376,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 +412,121 @@ 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._currentSourceIndex = newCurrentSourceIndex;
|
this._mruSources = currentSource.concat(this._mruSources);
|
||||||
|
break;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
_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] = [];
|
|
||||||
infosByShortName[info.shortName].push(info);
|
|
||||||
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 +555,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 +593,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 +615,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 +626,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 +661,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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -528,8 +708,9 @@ const InputSourceIndicator = new Lang.Class({
|
|||||||
// 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 +722,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 +740,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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -16,6 +16,7 @@ const Indicator = new Lang.Class({
|
|||||||
|
|
||||||
_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._volume = Main.panel.statusArea.volume;
|
||||||
if (this._volume) {
|
if (this._volume) {
|
||||||
|
@ -5,7 +5,6 @@ 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;
|
||||||
|
|
||||||
@ -140,6 +139,46 @@ const NMNetworkMenuItem = new Lang.Class({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const NMWiredSectionTitleMenuItem = new Lang.Class({
|
||||||
|
Name: 'NMWiredSectionTitleMenuItem',
|
||||||
|
Extends: PopupMenu.PopupSwitchMenuItem,
|
||||||
|
|
||||||
|
_init: function(label, params) {
|
||||||
|
params = params || { };
|
||||||
|
params.style_class = 'popup-subtitle-menu-item';
|
||||||
|
this.parent(label, false, params);
|
||||||
|
},
|
||||||
|
|
||||||
|
updateForDevice: function(device) {
|
||||||
|
if (device) {
|
||||||
|
this._device = device;
|
||||||
|
this.setStatus(device.getStatusLabel());
|
||||||
|
this.setToggleState(device.connected);
|
||||||
|
} else
|
||||||
|
this.setStatus('');
|
||||||
|
},
|
||||||
|
|
||||||
|
activate: function(event) {
|
||||||
|
this.parent(event);
|
||||||
|
|
||||||
|
if (!this._device) {
|
||||||
|
log('Section title activated when there is more than one device, should be non reactive');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let newState = this._switch.state;
|
||||||
|
|
||||||
|
let ok;
|
||||||
|
if (newState)
|
||||||
|
ok = this._device.activate();
|
||||||
|
else
|
||||||
|
ok = this._device.deactivate();
|
||||||
|
|
||||||
|
if (!ok)
|
||||||
|
this._switch.setToggleState(false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
const NMWirelessSectionTitleMenuItem = new Lang.Class({
|
const NMWirelessSectionTitleMenuItem = new Lang.Class({
|
||||||
Name: 'NMWirelessSectionTitleMenuItem',
|
Name: 'NMWirelessSectionTitleMenuItem',
|
||||||
Extends: PopupMenu.PopupSwitchMenuItem,
|
Extends: PopupMenu.PopupSwitchMenuItem,
|
||||||
@ -312,7 +351,7 @@ const NMDevice = new Lang.Class({
|
|||||||
this._autoConnectionItem = null;
|
this._autoConnectionItem = null;
|
||||||
this._overflowItem = null;
|
this._overflowItem = null;
|
||||||
|
|
||||||
this.statusItem = new PopupMenu.PopupSwitchMenuItem('', this.connected, { style_class: 'popup-subtitle-menu-item' });
|
this.statusItem = new PopupMenu.PopupSwitchMenuItem(this._getDescription(), this.connected, { style_class: 'popup-subtitle-menu-item' });
|
||||||
this._statusChanged = this.statusItem.connect('toggled', Lang.bind(this, function(item, state) {
|
this._statusChanged = this.statusItem.connect('toggled', Lang.bind(this, function(item, state) {
|
||||||
let ok;
|
let ok;
|
||||||
if (state)
|
if (state)
|
||||||
@ -473,10 +512,6 @@ const NMDevice = new Lang.Class({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
syncDescription: function() {
|
|
||||||
this.statusItem.label.text = this.device._description;
|
|
||||||
},
|
|
||||||
|
|
||||||
// protected
|
// protected
|
||||||
_createAutomaticConnection: function() {
|
_createAutomaticConnection: function() {
|
||||||
throw new TypeError('Invoking pure virtual function NMDevice.createAutomaticConnection');
|
throw new TypeError('Invoking pure virtual function NMDevice.createAutomaticConnection');
|
||||||
@ -608,15 +643,33 @@ const NMDevice = new Lang.Class({
|
|||||||
this.statusItem.setStatus(this.getStatusLabel());
|
this.statusItem.setStatus(this.getStatusLabel());
|
||||||
|
|
||||||
this.emit('state-changed');
|
this.emit('state-changed');
|
||||||
|
},
|
||||||
|
|
||||||
|
_getDescription: function() {
|
||||||
|
let dev_product = this.device.get_product();
|
||||||
|
let dev_vendor = this.device.get_vendor();
|
||||||
|
if (!dev_product || !dev_vendor)
|
||||||
|
return '';
|
||||||
|
|
||||||
|
let product = Util.fixupPCIDescription(dev_product);
|
||||||
|
let vendor = Util.fixupPCIDescription(dev_vendor);
|
||||||
|
let out = '';
|
||||||
|
|
||||||
|
// Another quick hack; if all of the fixed up vendor string
|
||||||
|
// is found in product, ignore the vendor.
|
||||||
|
if (product.indexOf(vendor) == -1)
|
||||||
|
out += vendor + ' ';
|
||||||
|
out += product;
|
||||||
|
|
||||||
|
return out;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
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 +684,18 @@ 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) {
|
||||||
|
this._autoConnectionName = _("Auto Ethernet");
|
||||||
|
this.category = NMConnectionCategory.WIRED;
|
||||||
|
|
||||||
|
this.parent(client, device, connections);
|
||||||
},
|
},
|
||||||
|
|
||||||
_createAutomaticConnection: function() {
|
_createAutomaticConnection: function() {
|
||||||
@ -817,6 +882,10 @@ const NMDeviceBluetooth = new Lang.Class({
|
|||||||
this._clearSection();
|
this._clearSection();
|
||||||
this._queueCreateSection();
|
this._queueCreateSection();
|
||||||
this._updateStatusItem();
|
this._updateStatusItem();
|
||||||
|
},
|
||||||
|
|
||||||
|
_getDescription: function() {
|
||||||
|
return this.device.name || _("Bluetooth");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -1598,14 +1667,15 @@ const NMApplet = new Lang.Class({
|
|||||||
this._mobileUpdateId = 0;
|
this._mobileUpdateId = 0;
|
||||||
this._mobileUpdateDevice = null;
|
this._mobileUpdateDevice = null;
|
||||||
|
|
||||||
this._nmDevices = [];
|
|
||||||
this._devices = { };
|
this._devices = { };
|
||||||
|
|
||||||
this._devices.wired = {
|
this._devices.wired = {
|
||||||
section: new PopupMenu.PopupMenuSection(),
|
section: new PopupMenu.PopupMenuSection(),
|
||||||
devices: [ ],
|
devices: [ ],
|
||||||
|
item: new NMWiredSectionTitleMenuItem(_("Wired"))
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this._devices.wired.section.addMenuItem(this._devices.wired.item);
|
||||||
this._devices.wired.section.actor.hide();
|
this._devices.wired.section.actor.hide();
|
||||||
this.menu.addMenuItem(this._devices.wired.section);
|
this.menu.addMenuItem(this._devices.wired.section);
|
||||||
this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
|
this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
|
||||||
@ -1613,7 +1683,7 @@ const NMApplet = new Lang.Class({
|
|||||||
this._devices.wireless = {
|
this._devices.wireless = {
|
||||||
section: new PopupMenu.PopupMenuSection(),
|
section: new PopupMenu.PopupMenuSection(),
|
||||||
devices: [ ],
|
devices: [ ],
|
||||||
item: this._makeToggleItem('wireless', _("Wi-Fi"))
|
item: this._makeToggleItem('wireless', _("Wireless"))
|
||||||
};
|
};
|
||||||
this._devices.wireless.section.addMenuItem(this._devices.wireless.item);
|
this._devices.wireless.section.addMenuItem(this._devices.wireless.item);
|
||||||
this._devices.wireless.section.actor.hide();
|
this._devices.wireless.section.actor.hide();
|
||||||
@ -1623,7 +1693,9 @@ const NMApplet = new Lang.Class({
|
|||||||
this._devices.wwan = {
|
this._devices.wwan = {
|
||||||
section: new PopupMenu.PopupMenuSection(),
|
section: new PopupMenu.PopupMenuSection(),
|
||||||
devices: [ ],
|
devices: [ ],
|
||||||
|
item: this._makeToggleItem('wwan', _("Mobile broadband"))
|
||||||
};
|
};
|
||||||
|
this._devices.wwan.section.addMenuItem(this._devices.wwan.item);
|
||||||
this._devices.wwan.section.actor.hide();
|
this._devices.wwan.section.actor.hide();
|
||||||
this.menu.addMenuItem(this._devices.wwan.section);
|
this.menu.addMenuItem(this._devices.wwan.section);
|
||||||
this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
|
this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
|
||||||
@ -1640,6 +1712,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 +1724,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);
|
||||||
@ -1706,23 +1780,16 @@ const NMApplet = new Lang.Class({
|
|||||||
section.actor.hide();
|
section.actor.hide();
|
||||||
else {
|
else {
|
||||||
section.actor.show();
|
section.actor.show();
|
||||||
|
if (devices.length == 1) {
|
||||||
// Sync the relation between the section title
|
let dev = devices[0];
|
||||||
// item (the one with the airplane mode switch)
|
dev.statusItem.actor.hide();
|
||||||
// and the individual device switches
|
item.updateForDevice(dev);
|
||||||
if (item) {
|
} else {
|
||||||
if (devices.length == 1) {
|
devices.forEach(function(dev) {
|
||||||
let dev = devices[0];
|
dev.statusItem.actor.show();
|
||||||
dev.statusItem.actor.hide();
|
});
|
||||||
item.updateForDevice(dev);
|
// remove status text from the section title item
|
||||||
} else {
|
item.updateForDevice(null);
|
||||||
devices.forEach(function(dev) {
|
|
||||||
dev.statusItem.actor.show();
|
|
||||||
});
|
|
||||||
|
|
||||||
// remove status text from the section title item
|
|
||||||
item.updateForDevice(null);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -1730,9 +1797,8 @@ const NMApplet = new Lang.Class({
|
|||||||
_readDevices: function() {
|
_readDevices: function() {
|
||||||
let devices = this._client.get_devices() || [ ];
|
let devices = this._client.get_devices() || [ ];
|
||||||
for (let i = 0; i < devices.length; ++i) {
|
for (let i = 0; i < devices.length; ++i) {
|
||||||
this._deviceAdded(this._client, devices[i], true);
|
this._deviceAdded(this._client, devices[i]);
|
||||||
}
|
}
|
||||||
this._syncDeviceNames();
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_notifyForDevice: function(device, iconName, title, text, urgency) {
|
_notifyForDevice: function(device, iconName, title, text, urgency) {
|
||||||
@ -1780,18 +1846,7 @@ const NMApplet = new Lang.Class({
|
|||||||
return wrapper;
|
return wrapper;
|
||||||
},
|
},
|
||||||
|
|
||||||
_syncDeviceNames: function() {
|
_deviceAdded: function(client, device) {
|
||||||
let names = NMGtk.utils_disambiguate_device_names(this._nmDevices);
|
|
||||||
for (let i = 0; i < this._nmDevices.length; i++) {
|
|
||||||
let device = this._nmDevices[i];
|
|
||||||
if (device._description != names[i]) {
|
|
||||||
device._description = names[i];
|
|
||||||
device._delegate.syncDescription();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
_deviceAdded: function(client, device, skipSyncDeviceNames) {
|
|
||||||
if (device._delegate) {
|
if (device._delegate) {
|
||||||
// already seen, not adding again
|
// already seen, not adding again
|
||||||
return;
|
return;
|
||||||
@ -1802,14 +1857,10 @@ const NMApplet = new Lang.Class({
|
|||||||
let section = this._devices[wrapper.category].section;
|
let section = this._devices[wrapper.category].section;
|
||||||
let devices = this._devices[wrapper.category].devices;
|
let devices = this._devices[wrapper.category].devices;
|
||||||
|
|
||||||
section.addMenuItem(wrapper.statusItem);
|
section.addMenuItem(wrapper.section, 1);
|
||||||
section.addMenuItem(wrapper.section);
|
section.addMenuItem(wrapper.statusItem, 1);
|
||||||
devices.push(wrapper);
|
devices.push(wrapper);
|
||||||
|
|
||||||
this._nmDevices.push(device);
|
|
||||||
if (!skipSyncDeviceNames)
|
|
||||||
this._syncDeviceNames();
|
|
||||||
|
|
||||||
this._syncSectionTitle(wrapper.category);
|
this._syncSectionTitle(wrapper.category);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -1827,10 +1878,6 @@ const NMApplet = new Lang.Class({
|
|||||||
let pos = devices.indexOf(wrapper);
|
let pos = devices.indexOf(wrapper);
|
||||||
devices.splice(pos, 1);
|
devices.splice(pos, 1);
|
||||||
|
|
||||||
pos = this._nmDevices.indexOf(device);
|
|
||||||
this._nmDevices.splice(pos, 1);
|
|
||||||
this._syncDeviceNames();
|
|
||||||
|
|
||||||
this._syncSectionTitle(wrapper.category)
|
this._syncSectionTitle(wrapper.category)
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
@ -124,6 +124,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 +161,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) {
|
||||||
@ -392,6 +387,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;
|
||||||
@ -445,6 +441,8 @@ const WindowOverlay = new Lang.Class({
|
|||||||
this._parentActor = parentActor;
|
this._parentActor = parentActor;
|
||||||
this._hidden = false;
|
this._hidden = false;
|
||||||
|
|
||||||
|
this._settings = new Gio.Settings({ schema: BUTTON_LAYOUT_SCHEMA });
|
||||||
|
|
||||||
this.borderSize = 0;
|
this.borderSize = 0;
|
||||||
this.border = new St.Bin({ style_class: 'window-clone-border' });
|
this.border = new St.Bin({ style_class: 'window-clone-border' });
|
||||||
|
|
||||||
@ -456,11 +454,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,27 +529,13 @@ 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 = this._settings.get_string(BUTTON_LAYOUT_KEY);
|
||||||
let layout = settings.get_string(BUTTON_LAYOUT_KEY);
|
|
||||||
let rtl = Clutter.get_default_text_direction() == Clutter.TextDirection.RTL;
|
let rtl = Clutter.get_default_text_direction() == Clutter.TextDirection.RTL;
|
||||||
|
|
||||||
let split = layout.split(":");
|
let split = layout.split(":");
|
||||||
@ -577,8 +557,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 +1172,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 +1181,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 +1213,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 +1248,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 +1383,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 +1551,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);
|
||||||
|
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-18 17:13+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 järgmise kasutuse jaoks, näidatakse "
|
||||||
|
"\"Jäta parool meelde\" märkeruutu. See võti määrab 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 akendevahetajas kuvatakse. Sobivad väärtused on "
|
||||||
|
"'thumbnail-only' (näidatakse ainult pisipilti), 'app-icon-only' (näidatakse "
|
||||||
|
"ainult rakenduse ikooni) või 'both' (näidatakse mõlemaid)."
|
||||||
|
|
||||||
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"
|
||||||
|
|
||||||
|
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;
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -1738,15 +1738,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 +1847,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 +1855,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))
|
||||||
{
|
{
|
||||||
@ -2668,6 +2676,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 +2755,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;
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user