Compare commits
	
		
			237 Commits
		
	
	
		
			3.34.0
			...
			wip/hadess
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					752b1df659 | ||
| 
						 | 
					366b06716d | ||
| 
						 | 
					4d47b16d33 | ||
| 
						 | 
					6526e9edf6 | ||
| 
						 | 
					055c007ac2 | ||
| 
						 | 
					43cf466d09 | ||
| 
						 | 
					6965781d59 | ||
| 
						 | 
					80680803aa | ||
| 
						 | 
					51601f3ead | ||
| 
						 | 
					b25a73c243 | ||
| 
						 | 
					d0690c3952 | ||
| 
						 | 
					f2466caef3 | ||
| 
						 | 
					b1d22d2058 | ||
| 
						 | 
					6f7e5976e2 | ||
| 
						 | 
					29543f369f | ||
| 
						 | 
					a144a1c76d | ||
| 
						 | 
					d91927674d | ||
| 
						 | 
					d12cd12e1b | ||
| 
						 | 
					caa50dc1a3 | ||
| 
						 | 
					55b57421dc | ||
| 
						 | 
					320df13b65 | ||
| 
						 | 
					e4920b2f80 | ||
| 
						 | 
					c9fbae3408 | ||
| 
						 | 
					a3c6217875 | ||
| 
						 | 
					db7726c5bf | ||
| 
						 | 
					0b91dee5a9 | ||
| 
						 | 
					3838220961 | ||
| 
						 | 
					9bb12f6f87 | ||
| 
						 | 
					4dea1f801a | ||
| 
						 | 
					91a5133116 | ||
| 
						 | 
					c4c5c4fd5c | ||
| 
						 | 
					f67b409fc1 | ||
| 
						 | 
					22fe4e92c7 | ||
| 
						 | 
					91eb84fa4e | ||
| 
						 | 
					4e1492c926 | ||
| 
						 | 
					ed97f61750 | ||
| 
						 | 
					b5676a2a5c | ||
| 
						 | 
					7059dcced3 | ||
| 
						 | 
					c7e0c7eb79 | ||
| 
						 | 
					ff775213a5 | ||
| 
						 | 
					7f9c709c85 | ||
| 
						 | 
					74d7d3e259 | ||
| 
						 | 
					0353a5bf2c | ||
| 
						 | 
					ab6a629955 | ||
| 
						 | 
					6cad251187 | ||
| 
						 | 
					d7c569c692 | ||
| 
						 | 
					0615370930 | ||
| 
						 | 
					7a92a9ba21 | ||
| 
						 | 
					0199857c5b | ||
| 
						 | 
					59e3a1a816 | ||
| 
						 | 
					6533690fff | ||
| 
						 | 
					d0d1845bb6 | ||
| 
						 | 
					20f4fc7c87 | ||
| 
						 | 
					b4128967a1 | ||
| 
						 | 
					38ad1d7c13 | ||
| 
						 | 
					f78136182f | ||
| 
						 | 
					11d46cf5b3 | ||
| 
						 | 
					7326e7a9fa | ||
| 
						 | 
					a65164e540 | ||
| 
						 | 
					279024afc2 | ||
| 
						 | 
					ef8000d2e6 | ||
| 
						 | 
					986600ab31 | ||
| 
						 | 
					3d39b32a0b | ||
| 
						 | 
					6205d5eb27 | ||
| 
						 | 
					a722b4c51d | ||
| 
						 | 
					31fe517007 | ||
| 
						 | 
					31d915a38a | ||
| 
						 | 
					e00878ab75 | ||
| 
						 | 
					3b5675b79a | ||
| 
						 | 
					ee97512bcc | ||
| 
						 | 
					085531b43d | ||
| 
						 | 
					9e8b97d474 | ||
| 
						 | 
					a3a7953704 | ||
| 
						 | 
					92c0171aeb | ||
| 
						 | 
					6a6d66486d | ||
| 
						 | 
					1cc766d636 | ||
| 
						 | 
					60cad01880 | ||
| 
						 | 
					63c9a6efd0 | ||
| 
						 | 
					1d1b42756f | ||
| 
						 | 
					a95601afdb | ||
| 
						 | 
					2dbdf792db | ||
| 
						 | 
					e23ce37e62 | ||
| 
						 | 
					a05cb76e0d | ||
| 
						 | 
					60cab56f86 | ||
| 
						 | 
					70a5c3875c | ||
| 
						 | 
					0fdbde9101 | ||
| 
						 | 
					2156577333 | ||
| 
						 | 
					f3e09b2b2f | ||
| 
						 | 
					6180f59c13 | ||
| 
						 | 
					506b75fc7f | ||
| 
						 | 
					a0d0a17d68 | ||
| 
						 | 
					92e5713e29 | ||
| 
						 | 
					856c32db91 | ||
| 
						 | 
					7b45ffa511 | ||
| 
						 | 
					b6754d7db7 | ||
| 
						 | 
					2a9977a5b3 | ||
| 
						 | 
					dab60d5580 | ||
| 
						 | 
					8e3aac8ed7 | ||
| 
						 | 
					147cb53140 | ||
| 
						 | 
					54f369404a | ||
| 
						 | 
					af1aabff75 | ||
| 
						 | 
					d6ba6dc554 | ||
| 
						 | 
					42188b7698 | ||
| 
						 | 
					48adb2ef4b | ||
| 
						 | 
					f8e648b7e3 | ||
| 
						 | 
					daa5452af2 | ||
| 
						 | 
					259874d731 | ||
| 
						 | 
					23344701de | ||
| 
						 | 
					00e95de114 | ||
| 
						 | 
					942758bb30 | ||
| 
						 | 
					e0947b01bd | ||
| 
						 | 
					cf00231aa8 | ||
| 
						 | 
					5c3f4f5f8b | ||
| 
						 | 
					5f10047b58 | ||
| 
						 | 
					3094f86334 | ||
| 
						 | 
					8ffea9d5c5 | ||
| 
						 | 
					4f3c8b8d69 | ||
| 
						 | 
					edf6bd6909 | ||
| 
						 | 
					3e58af10ca | ||
| 
						 | 
					9e55d262f9 | ||
| 
						 | 
					252e694979 | ||
| 
						 | 
					efed695eca | ||
| 
						 | 
					b446667df6 | ||
| 
						 | 
					133a1e7bef | ||
| 
						 | 
					5b3935fa43 | ||
| 
						 | 
					471165ca9b | ||
| 
						 | 
					111f87a1b2 | ||
| 
						 | 
					93525539c2 | ||
| 
						 | 
					a77377efe7 | ||
| 
						 | 
					81ab2865f7 | ||
| 
						 | 
					e585f7d97b | ||
| 
						 | 
					1a32e3e74a | ||
| 
						 | 
					8d6820c4df | ||
| 
						 | 
					2546445884 | ||
| 
						 | 
					e44b7df078 | ||
| 
						 | 
					3a9eaa39ea | ||
| 
						 | 
					af87bd8c87 | ||
| 
						 | 
					4bfb4a0e3d | ||
| 
						 | 
					d1a6601e60 | ||
| 
						 | 
					817aec5466 | ||
| 
						 | 
					314a89a837 | ||
| 
						 | 
					57ed68541a | ||
| 
						 | 
					413c677fcf | ||
| 
						 | 
					3d86e6e791 | ||
| 
						 | 
					3fbd61cbf0 | ||
| 
						 | 
					43b4f2c7d5 | ||
| 
						 | 
					7eb4088f45 | ||
| 
						 | 
					f00201fa6c | ||
| 
						 | 
					1aca2ba6bb | ||
| 
						 | 
					e9131465dd | ||
| 
						 | 
					0ee7f02f8e | ||
| 
						 | 
					451f4e3636 | ||
| 
						 | 
					2fc4987c73 | ||
| 
						 | 
					4525ad346d | ||
| 
						 | 
					e4b8a4b432 | ||
| 
						 | 
					62e594af6d | ||
| 
						 | 
					ce92270626 | ||
| 
						 | 
					bdcf3037ca | ||
| 
						 | 
					9698ff491a | ||
| 
						 | 
					2a9e065cfb | ||
| 
						 | 
					4c93ef39fa | ||
| 
						 | 
					22107c183b | ||
| 
						 | 
					c06eb5d0a7 | ||
| 
						 | 
					e76877c4b8 | ||
| 
						 | 
					2a32fb2e72 | ||
| 
						 | 
					de86920e0e | ||
| 
						 | 
					8754736fda | ||
| 
						 | 
					d2ead59d74 | ||
| 
						 | 
					2f4fcc59a1 | ||
| 
						 | 
					ba6dbb228d | ||
| 
						 | 
					60e386048b | ||
| 
						 | 
					c2904fa14d | ||
| 
						 | 
					dfdb139d9c | ||
| 
						 | 
					ce63d21dcc | ||
| 
						 | 
					1da9937453 | ||
| 
						 | 
					9f11fbad16 | ||
| 
						 | 
					f54e7804c5 | ||
| 
						 | 
					7db5f8b28e | ||
| 
						 | 
					743ce23fbc | ||
| 
						 | 
					a3267be192 | ||
| 
						 | 
					4ad2523877 | ||
| 
						 | 
					4bfee3a8ca | ||
| 
						 | 
					fc964f975a | ||
| 
						 | 
					52f85c9465 | ||
| 
						 | 
					691610f23c | ||
| 
						 | 
					b6a2b2b8a5 | ||
| 
						 | 
					1ad8a2fcf6 | ||
| 
						 | 
					7ce08845f1 | ||
| 
						 | 
					d469250130 | ||
| 
						 | 
					7fd5c47e06 | ||
| 
						 | 
					8704b1004e | ||
| 
						 | 
					65a9fb8c01 | ||
| 
						 | 
					25a7a8006a | ||
| 
						 | 
					6fe1d3248a | ||
| 
						 | 
					13f97532bf | ||
| 
						 | 
					1acee3d702 | ||
| 
						 | 
					1d17404471 | ||
| 
						 | 
					48b860b69f | ||
| 
						 | 
					a030c54661 | ||
| 
						 | 
					dcf7bae6c7 | ||
| 
						 | 
					d0ace108e5 | ||
| 
						 | 
					32d5744014 | ||
| 
						 | 
					d16094774b | ||
| 
						 | 
					ac664ba321 | ||
| 
						 | 
					0888a9bffd | ||
| 
						 | 
					5e82d72424 | ||
| 
						 | 
					2513835e89 | ||
| 
						 | 
					98b70ef00f | ||
| 
						 | 
					ae11381b88 | ||
| 
						 | 
					e9596f2775 | ||
| 
						 | 
					8adbc8010a | ||
| 
						 | 
					76fb559964 | ||
| 
						 | 
					1bc1b4d9d8 | ||
| 
						 | 
					dfc0ef56f6 | ||
| 
						 | 
					1e68e78d8e | ||
| 
						 | 
					17fa5a2db4 | ||
| 
						 | 
					004a5e1042 | ||
| 
						 | 
					4915a9e8e4 | ||
| 
						 | 
					8a7e44ccf0 | ||
| 
						 | 
					a497afe695 | ||
| 
						 | 
					15c252c11d | ||
| 
						 | 
					27da3ed1fe | ||
| 
						 | 
					8656102182 | ||
| 
						 | 
					24d3744cb9 | ||
| 
						 | 
					031913b9df | ||
| 
						 | 
					e53443daf9 | ||
| 
						 | 
					06317f4f6a | ||
| 
						 | 
					c69e195441 | ||
| 
						 | 
					a53b48de4c | ||
| 
						 | 
					eca98aee42 | ||
| 
						 | 
					ea5aaa8ab2 | ||
| 
						 | 
					72566eda43 | ||
| 
						 | 
					7a4f9a5ff3 | ||
| 
						 | 
					ba23fd9989 | ||
| 
						 | 
					c101196f5b | ||
| 
						 | 
					1687a5451e | ||
| 
						 | 
					ea4d5f89eb | 
@@ -54,7 +54,7 @@ build:
 | 
			
		||||
        - meson mutter mutter/build --prefix=/usr -Dtests=false
 | 
			
		||||
        - ninja -C mutter/build install
 | 
			
		||||
    script:
 | 
			
		||||
        - meson . build -Dbuiltype=debugoptimized -Dman=false
 | 
			
		||||
        - meson . build -Dbuiltype=debugoptimized -Dman=false --werror
 | 
			
		||||
        - ninja -C build
 | 
			
		||||
        - ninja -C build install
 | 
			
		||||
    <<: *only_default
 | 
			
		||||
 
 | 
			
		||||
@@ -16,8 +16,14 @@ run_eslint() {
 | 
			
		||||
  ARGS_LEGACY='--config lint/eslintrc-legacy.json'
 | 
			
		||||
 | 
			
		||||
  local extra_args=ARGS_$1
 | 
			
		||||
  local output=OUTPUT_$1
 | 
			
		||||
  eslint -f unix ${!extra_args} -o ${!output} js
 | 
			
		||||
  local output_var=OUTPUT_$1
 | 
			
		||||
  local output=${!output_var}
 | 
			
		||||
 | 
			
		||||
  # ensure output exists even if eslint doesn't report any errors
 | 
			
		||||
  mkdir -p $(dirname $output)
 | 
			
		||||
  touch $output
 | 
			
		||||
 | 
			
		||||
  eslint -f unix ${!extra_args} -o $output js
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
list_commit_range_additions() {
 | 
			
		||||
@@ -66,10 +72,17 @@ create_common() {
 | 
			
		||||
  rm $OUTPUT_FINAL.tmp
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
if [ "$CI_MERGE_REQUEST_TARGET_BRANCH_NAME" ]; then
 | 
			
		||||
  git fetch $CI_MERGE_REQUEST_PROJECT_URL.git $CI_MERGE_REQUEST_TARGET_BRANCH_NAME
 | 
			
		||||
# Disable MR handling for now. We aren't ready to enforce
 | 
			
		||||
# non-legacy style just yet ...
 | 
			
		||||
unset CI_MERGE_REQUEST_TARGET_BRANCH_NAME
 | 
			
		||||
 | 
			
		||||
REMOTE=${1:-$CI_MERGE_REQUEST_PROJECT_URL.git}
 | 
			
		||||
BRANCH_NAME=${2:-$CI_MERGE_REQUEST_TARGET_BRANCH_NAME}
 | 
			
		||||
 | 
			
		||||
if [ "$BRANCH_NAME" ]; then
 | 
			
		||||
  git fetch $REMOTE $BRANCH_NAME
 | 
			
		||||
  branch_point=$(git merge-base HEAD FETCH_HEAD)
 | 
			
		||||
  commit_range=$branch_point...$CI_COMMIT_SHA
 | 
			
		||||
  commit_range=$branch_point...HEAD
 | 
			
		||||
 | 
			
		||||
  list_commit_range_additions $commit_range > $LINE_CHANGES
 | 
			
		||||
 | 
			
		||||
@@ -86,12 +99,16 @@ run_eslint LEGACY
 | 
			
		||||
echo Done.
 | 
			
		||||
create_common
 | 
			
		||||
 | 
			
		||||
# Just show the report and succeed when not testing a MR
 | 
			
		||||
if [ -z "$CI_MERGE_REQUEST_TARGET_BRANCH_NAME" ]; then
 | 
			
		||||
if ! is_empty $OUTPUT_FINAL; then
 | 
			
		||||
  cat $OUTPUT_FINAL
 | 
			
		||||
  exit 1
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
# Just show the report and succeed when not testing a MR
 | 
			
		||||
if [ -z "$BRANCH_NAME" ]; then
 | 
			
		||||
  exit 0
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
copy_matched_lines $OUTPUT_FINAL $LINE_CHANGES $OUTPUT_MR
 | 
			
		||||
copy_matched_lines $OUTPUT_REGULAR $LINE_CHANGES $OUTPUT_MR
 | 
			
		||||
cat $OUTPUT_MR
 | 
			
		||||
is_empty $OUTPUT_MR
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										19
									
								
								HACKING.md
									
									
									
									
									
								
							
							
						
						
									
										19
									
								
								HACKING.md
									
									
									
									
									
								
							@@ -186,15 +186,27 @@ and "double quotes" for strings that the user may see. This allows us to
 | 
			
		||||
quickly find untranslated or mistranslated strings by grepping through the
 | 
			
		||||
sources for double quotes without a gettext call around them.
 | 
			
		||||
 | 
			
		||||
## `actor` and `_delegate`
 | 
			
		||||
## `actor` (deprecated) and `_delegate`
 | 
			
		||||
 | 
			
		||||
gjs allows us to set so-called "expando properties" on introspected objects,
 | 
			
		||||
allowing us to treat them like any other. Because the Shell was built before
 | 
			
		||||
you could inherit from GTypes natively in JS, we usually have a wrapper class
 | 
			
		||||
that has a property called `actor`. We call this wrapper class the "delegate".
 | 
			
		||||
you could inherit from GTypes natively in JS, in some cases we have a wrapper
 | 
			
		||||
class that has a property called `actor` (now deprecated). We call this
 | 
			
		||||
wrapper class the "delegate".
 | 
			
		||||
 | 
			
		||||
We sometimes use expando properties to set a property called `_delegate` on
 | 
			
		||||
the actor itself:
 | 
			
		||||
```javascript
 | 
			
		||||
    var MyActor = GObject.registerClass(
 | 
			
		||||
    class MyActor extends Clutter.Actor {
 | 
			
		||||
        _init(params) {
 | 
			
		||||
            super._init(params);
 | 
			
		||||
            this._delegate = this;
 | 
			
		||||
        }
 | 
			
		||||
    });
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Or using the deprecated `actor`:
 | 
			
		||||
```javascript
 | 
			
		||||
    var MyClass = class {
 | 
			
		||||
        constructor() {
 | 
			
		||||
@@ -215,6 +227,7 @@ delegate object from an associated actor. For instance, the drag and drop
 | 
			
		||||
system calls the `handleDragOver` function on the delegate of a "drop target"
 | 
			
		||||
when the user drags an item over it. If you do not set the `_delegate`
 | 
			
		||||
property, your actor will not be able to be dropped onto.
 | 
			
		||||
In case the class is an actor itself, the `_delegate` can be just set to `this`.
 | 
			
		||||
 | 
			
		||||
## Functional style
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										48
									
								
								NEWS
									
									
									
									
									
								
							
							
						
						
									
										48
									
								
								NEWS
									
									
									
									
									
								
							@@ -1,3 +1,51 @@
 | 
			
		||||
3.35.1
 | 
			
		||||
======
 | 
			
		||||
* Misc. bug fixes and cleanups [Marco; Matthias; !758, #701212]
 | 
			
		||||
 | 
			
		||||
Contributors:
 | 
			
		||||
  Marco Trevisan (Treviño)
 | 
			
		||||
 | 
			
		||||
3.34.1
 | 
			
		||||
======
 | 
			
		||||
* Fix "Frequent" view icons disappearing on hover [Jonas D.; #1502]
 | 
			
		||||
* Allow editing app folder names [Georges, Marco; !675, !720]
 | 
			
		||||
* Skip property transitions while hidden [Florian; !708]
 | 
			
		||||
* Make menu animations more consistent [Florian, GB_2; #1595, !717]
 | 
			
		||||
* Improve performance when enabling/disabling all extensions [Jonas D.; !96]
 | 
			
		||||
* Fix extra icons appearing in "Frequent" view animation [Georges; !696]
 | 
			
		||||
* Fix fading out desktop icons [Harshula; #1616]
 | 
			
		||||
* Fix box-shadow glitch with prerendered resources [Daniel; #1186]
 | 
			
		||||
* Fix accidentally skipped animations [Florian; #1572]
 | 
			
		||||
* Fix screenshots and window animations when scaled [Robert; !728]
 | 
			
		||||
* Don't leak NOTIFY_SOCKET environment variable to applications [Benjamin; !741]
 | 
			
		||||
* Fix lock-up on X11 when ibus is already running on startup [Marco; #1712]
 | 
			
		||||
* Fix screen dimming on idle [Marco; #1683]
 | 
			
		||||
* Do not notify systemd before initialization is complete [Iain; !750]
 | 
			
		||||
* Support SAE secrets in network agent [Lubomir; !751]
 | 
			
		||||
* Fix various regressions with dynamic workspaces [Florian; #1497]
 | 
			
		||||
* Fixed crashes [Florian, Marco; #1678, !746]
 | 
			
		||||
* Misc. bug fixes and cleanups [Marco, Jonas D., Florian, Iain, Georges,
 | 
			
		||||
  Jonas Å., Martin, Takao, Carlos; !700, !705, !709, !711, !707, #1538, !710,
 | 
			
		||||
  !713, !699, !715, !718, !716, !719, !721, #1243, !725, !731, #1614, !683,
 | 
			
		||||
  !732, !121, !735, !736, !740, #573, #1641, #1571]
 | 
			
		||||
 | 
			
		||||
Contributors:
 | 
			
		||||
  Marco Trevisan (Treviño), Benjamin Berg, Jonas Dreßler, Takao Fujiwara, GB_2,
 | 
			
		||||
  Carlos Garnacho, Harshula Jayasuriya, Iain Lane, Robert Mader,
 | 
			
		||||
  Daniel García Moreno, Florian Müllner, Georges Basile Stavracas Neto,
 | 
			
		||||
  Lubomir Rintel, Martin Zurowietz, Jonas Ådahl
 | 
			
		||||
 | 
			
		||||
Translators:
 | 
			
		||||
  Rafael Fontenelle [pt_BR], Fran Dieguez [gl], Balázs Úr [hu],
 | 
			
		||||
  Milo Casagrande [it], Daniel Șerbănescu [ro], Kukuh Syafaat [id],
 | 
			
		||||
  Jiri Grönroos [fi], Daniel Mustieles [es], Piotr Drąg [pl],
 | 
			
		||||
  Anders Jonsson [sv], Marek Černocký [cs], Jordi Mas [ca],
 | 
			
		||||
  Aurimas Černius [lt], Christian Kirbach [de], Emin Tufan Çetin [tr],
 | 
			
		||||
  Enrico Nicoletto [pt_BR], Danial Behzadi [fa], Марко Костић [sr],
 | 
			
		||||
  Alexandre Franke [fr], Charles Monzat [fr], Kjartan Maraas [nb],
 | 
			
		||||
  Ryuta Fujii [ja], Nathan Follens [nl], Dušan Kazik [sk], Fabio Tomat [fur],
 | 
			
		||||
  Matej Urbančič [sl], Ask Hjorth Larsen [da], Alan Mortensen [da]
 | 
			
		||||
 | 
			
		||||
3.34.0
 | 
			
		||||
======
 | 
			
		||||
* Handle startup/shutdown of misc X11 services [Carlos; !680]
 | 
			
		||||
 
 | 
			
		||||
@@ -23,3 +23,5 @@ ExecStart=@bindir@/gnome-shell
 | 
			
		||||
SuccessExitStatus=1
 | 
			
		||||
# On wayland we cannot restart
 | 
			
		||||
Restart=no
 | 
			
		||||
# Kill any stubborn child processes after this long
 | 
			
		||||
TimeoutStopSec=5
 | 
			
		||||
 
 | 
			
		||||
@@ -29,3 +29,5 @@ SuccessExitStatus=1
 | 
			
		||||
Restart=always
 | 
			
		||||
# Do not wait before restarting the shell
 | 
			
		||||
RestartSec=0ms
 | 
			
		||||
# Kill any stubborn child processes after this long
 | 
			
		||||
TimeoutStopSec=5
 | 
			
		||||
 
 | 
			
		||||
@@ -50,7 +50,7 @@
 | 
			
		||||
      </description>
 | 
			
		||||
    </key>
 | 
			
		||||
    <key name="favorite-apps" type="as">
 | 
			
		||||
      <default>[ 'epiphany.desktop', 'evolution.desktop', 'rhythmbox.desktop', 'shotwell.desktop', 'org.gnome.Nautilus.desktop', 'org.gnome.Software.desktop' ]</default>
 | 
			
		||||
      <default>[ 'epiphany.desktop', 'evolution.desktop', 'rhythmbox.desktop', 'org.gnome.Shotwell.desktop', 'org.gnome.Nautilus.desktop', 'org.gnome.Software.desktop' ]</default>
 | 
			
		||||
      <summary>List of desktop file IDs for favorite applications</summary>
 | 
			
		||||
      <description>
 | 
			
		||||
        The applications corresponding to these identifiers
 | 
			
		||||
 
 | 
			
		||||
@@ -610,6 +610,13 @@ StScrollBar {
 | 
			
		||||
    border-bottom-style: solid;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
// Rename popup
 | 
			
		||||
.rename-folder-popup {
 | 
			
		||||
  .rename-folder-popup-item {
 | 
			
		||||
    spacing: 6px;
 | 
			
		||||
    &:ltr, &:rtl { padding: 0, 12px; }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Background menu
 | 
			
		||||
.background-menu { -boxpointer-gap: 4px; -arrow-rise: 0px; }
 | 
			
		||||
@@ -742,7 +749,7 @@ StScrollBar {
 | 
			
		||||
 | 
			
		||||
  .ws-switcher-active-up, .ws-switcher-active-down,
 | 
			
		||||
  .ws-switcher-active-left, .ws-switcher-active-right {
 | 
			
		||||
    height: 50px;
 | 
			
		||||
    height: 52px;
 | 
			
		||||
    background-color: $selected_bg_color;
 | 
			
		||||
    color: $selected_fg_color;
 | 
			
		||||
    background-size: 32px;
 | 
			
		||||
 
 | 
			
		||||
@@ -31,34 +31,34 @@ its dependencies to build from tarballs.</description>
 | 
			
		||||
  <programming-language>JavaScript</programming-language>
 | 
			
		||||
  <programming-language>C</programming-language>
 | 
			
		||||
 | 
			
		||||
  <maintainer>
 | 
			
		||||
  <author>
 | 
			
		||||
    <foaf:Person>
 | 
			
		||||
      <foaf:name>William Jon McCann</foaf:name>
 | 
			
		||||
      <foaf:mbox rdf:resource="mailto:jmccann@redhat.com" />
 | 
			
		||||
      <gnome:userid>mccann</gnome:userid>
 | 
			
		||||
    </foaf:Person>
 | 
			
		||||
  </maintainer>
 | 
			
		||||
  <maintainer>
 | 
			
		||||
  </author>
 | 
			
		||||
  <author>
 | 
			
		||||
    <foaf:Person>
 | 
			
		||||
      <foaf:name>Owen Taylor</foaf:name>
 | 
			
		||||
      <foaf:mbox rdf:resource="mailto:otaylor@redhat.com" />
 | 
			
		||||
      <gnome:userid>otaylor</gnome:userid>
 | 
			
		||||
    </foaf:Person>
 | 
			
		||||
  </maintainer>
 | 
			
		||||
  <maintainer>
 | 
			
		||||
  </author>
 | 
			
		||||
  <author>
 | 
			
		||||
    <foaf:Person>
 | 
			
		||||
      <foaf:name>Colin Walters</foaf:name>
 | 
			
		||||
      <foaf:mbox rdf:resource="mailto:walters@verbum.org" />
 | 
			
		||||
      <gnome:userid>walters</gnome:userid>
 | 
			
		||||
    </foaf:Person>
 | 
			
		||||
  </maintainer>
 | 
			
		||||
  <maintainer>
 | 
			
		||||
  </author>
 | 
			
		||||
  <author>
 | 
			
		||||
    <foaf:Person>
 | 
			
		||||
      <foaf:name>Marina Zhurakhinskaya</foaf:name>
 | 
			
		||||
      <foaf:mbox rdf:resource="mailto:marinaz@redhat.com" />
 | 
			
		||||
      <gnome:userid>marinaz</gnome:userid>
 | 
			
		||||
    </foaf:Person>
 | 
			
		||||
  </maintainer>
 | 
			
		||||
  </author>
 | 
			
		||||
  <maintainer>
 | 
			
		||||
    <foaf:Person>
 | 
			
		||||
      <foaf:name>Florian Müllner</foaf:name>
 | 
			
		||||
 
 | 
			
		||||
@@ -285,8 +285,9 @@ var Application = GObject.registerClass({
 | 
			
		||||
                    log(`Failed to connect to shell proxy: ${e}`);
 | 
			
		||||
                    this._mainStack.add_named(new NoShellPlaceholder(), 'noshell');
 | 
			
		||||
                    this._mainStack.visible_child_name = 'noshell';
 | 
			
		||||
                } else
 | 
			
		||||
                } else {
 | 
			
		||||
                    throw e;
 | 
			
		||||
                }
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
@@ -567,6 +568,10 @@ class ExtensionRow extends Gtk.ListBoxRow {
 | 
			
		||||
        this._extension = extension;
 | 
			
		||||
        this._prefsModule = null;
 | 
			
		||||
 | 
			
		||||
        this.connect('destroy', this._onDestroy.bind(this));
 | 
			
		||||
 | 
			
		||||
        this._buildUI();
 | 
			
		||||
 | 
			
		||||
        this._extensionStateChangedId = this._app.shellProxy.connectSignal(
 | 
			
		||||
            'ExtensionStateChanged', (p, sender, [uuid, newState]) => {
 | 
			
		||||
                if (this.uuid !== uuid)
 | 
			
		||||
@@ -574,13 +579,13 @@ class ExtensionRow extends Gtk.ListBoxRow {
 | 
			
		||||
 | 
			
		||||
                this._extension = ExtensionUtils.deserializeExtension(newState);
 | 
			
		||||
                let state = (this._extension.state == ExtensionState.ENABLED);
 | 
			
		||||
 | 
			
		||||
                GObject.signal_handler_block(this._switch, this._notifyActiveId);
 | 
			
		||||
                this._switch.state = state;
 | 
			
		||||
                GObject.signal_handler_unblock(this._switch, this._notifyActiveId);
 | 
			
		||||
 | 
			
		||||
                this._switch.sensitive = this._canToggle();
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
        this.connect('destroy', this._onDestroy.bind(this));
 | 
			
		||||
 | 
			
		||||
        this._buildUI();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    get uuid() {
 | 
			
		||||
@@ -646,7 +651,7 @@ class ExtensionRow extends Gtk.ListBoxRow {
 | 
			
		||||
            sensitive: this._canToggle(),
 | 
			
		||||
            state: this._extension.state === ExtensionState.ENABLED
 | 
			
		||||
        });
 | 
			
		||||
        this._switch.connect('notify::active', () => {
 | 
			
		||||
        this._notifyActiveId = this._switch.connect('notify::active', () => {
 | 
			
		||||
            if (this._switch.active)
 | 
			
		||||
                this._app.shellProxy.EnableExtensionRemote(this.uuid);
 | 
			
		||||
            else
 | 
			
		||||
 
 | 
			
		||||
@@ -1,11 +1,12 @@
 | 
			
		||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
 | 
			
		||||
/* exported AuthPrompt */
 | 
			
		||||
 | 
			
		||||
const { Clutter, Pango, Shell, St } = imports.gi;
 | 
			
		||||
const Signals = imports.signals;
 | 
			
		||||
const { Clutter, GObject, Pango, Shell, St } = imports.gi;
 | 
			
		||||
 | 
			
		||||
const Animation = imports.ui.animation;
 | 
			
		||||
const Batch = imports.gdm.batch;
 | 
			
		||||
const GdmUtil = imports.gdm.util;
 | 
			
		||||
const Util = imports.misc.util;
 | 
			
		||||
const Params = imports.misc.params;
 | 
			
		||||
const ShellEntry = imports.ui.shellEntry;
 | 
			
		||||
const UserWidget = imports.ui.userWidget;
 | 
			
		||||
@@ -16,6 +17,10 @@ var DEFAULT_BUTTON_WELL_ANIMATION_TIME = 300;
 | 
			
		||||
 | 
			
		||||
var MESSAGE_FADE_OUT_ANIMATION_TIME = 500;
 | 
			
		||||
 | 
			
		||||
const WIGGLE_OFFSET = 6;
 | 
			
		||||
const WIGGLE_DURATION = 65;
 | 
			
		||||
const N_WIGGLES = 3;
 | 
			
		||||
 | 
			
		||||
var AuthPromptMode = {
 | 
			
		||||
    UNLOCK_ONLY: 0,
 | 
			
		||||
    UNLOCK_OR_LOG_IN: 1
 | 
			
		||||
@@ -33,8 +38,21 @@ var BeginRequestType = {
 | 
			
		||||
    DONT_PROVIDE_USERNAME: 1
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
var AuthPrompt = class {
 | 
			
		||||
    constructor(gdmClient, mode) {
 | 
			
		||||
var AuthPrompt = GObject.registerClass({
 | 
			
		||||
    Signals: {
 | 
			
		||||
        'cancelled': {},
 | 
			
		||||
        'failed': {},
 | 
			
		||||
        'next': {},
 | 
			
		||||
        'prompted': {},
 | 
			
		||||
        'reset': { param_types: [GObject.TYPE_UINT] },
 | 
			
		||||
    }
 | 
			
		||||
}, class AuthPrompt extends St.BoxLayout {
 | 
			
		||||
    _init(gdmClient, mode) {
 | 
			
		||||
        super._init({
 | 
			
		||||
            style_class: 'login-dialog-prompt-layout',
 | 
			
		||||
            vertical: true
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        this.verificationStatus = AuthPromptStatus.NOT_VERIFYING;
 | 
			
		||||
 | 
			
		||||
        this._gdmClient = gdmClient;
 | 
			
		||||
@@ -67,38 +85,33 @@ var AuthPrompt = class {
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        this.actor = new St.BoxLayout({ style_class: 'login-dialog-prompt-layout',
 | 
			
		||||
                                        vertical: true });
 | 
			
		||||
        this.actor.connect('destroy', this._onDestroy.bind(this));
 | 
			
		||||
        this.actor.connect('key-press-event', (actor, event) => {
 | 
			
		||||
            if (event.get_key_symbol() == Clutter.KEY_Escape)
 | 
			
		||||
                this.cancel();
 | 
			
		||||
            return Clutter.EVENT_PROPAGATE;
 | 
			
		||||
        });
 | 
			
		||||
        this.connect('destroy', this._onDestroy.bind(this));
 | 
			
		||||
 | 
			
		||||
        this._userWell = new St.Bin({ x_fill: true,
 | 
			
		||||
                                      x_align: St.Align.START });
 | 
			
		||||
        this.actor.add(this._userWell,
 | 
			
		||||
                       { x_align: St.Align.START,
 | 
			
		||||
                         x_fill: true,
 | 
			
		||||
                         y_fill: true,
 | 
			
		||||
                         expand: true });
 | 
			
		||||
        this._userWell = new St.Bin({ x_fill: true, x_align: St.Align.START });
 | 
			
		||||
        this.add(this._userWell, {
 | 
			
		||||
            x_align: St.Align.START,
 | 
			
		||||
            x_fill: true,
 | 
			
		||||
            y_fill: true,
 | 
			
		||||
            expand: true
 | 
			
		||||
        });
 | 
			
		||||
        this._label = new St.Label({ style_class: 'login-dialog-prompt-label' });
 | 
			
		||||
 | 
			
		||||
        this.actor.add(this._label,
 | 
			
		||||
                       { expand: true,
 | 
			
		||||
                         x_fill: false,
 | 
			
		||||
                         y_fill: true,
 | 
			
		||||
                         x_align: St.Align.START });
 | 
			
		||||
        this.add(this._label, {
 | 
			
		||||
            expand: true,
 | 
			
		||||
            x_fill: false,
 | 
			
		||||
            y_fill: true,
 | 
			
		||||
            x_align: St.Align.START
 | 
			
		||||
        });
 | 
			
		||||
        this._entry = new St.Entry({ style_class: 'login-dialog-prompt-entry',
 | 
			
		||||
                                     can_focus: true });
 | 
			
		||||
        ShellEntry.addContextMenu(this._entry, { isPassword: true, actionMode: Shell.ActionMode.NONE });
 | 
			
		||||
 | 
			
		||||
        this.actor.add(this._entry,
 | 
			
		||||
                       { expand: true,
 | 
			
		||||
                         x_fill: true,
 | 
			
		||||
                         y_fill: false,
 | 
			
		||||
                         x_align: St.Align.START });
 | 
			
		||||
        this.add(this._entry, {
 | 
			
		||||
            expand: true,
 | 
			
		||||
            x_fill: true,
 | 
			
		||||
            y_fill: false,
 | 
			
		||||
            x_align: St.Align.START
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        this._entry.grab_key_focus();
 | 
			
		||||
 | 
			
		||||
@@ -106,14 +119,15 @@ var AuthPrompt = class {
 | 
			
		||||
                                       styleClass: 'login-dialog-message' });
 | 
			
		||||
        this._message.clutter_text.line_wrap = true;
 | 
			
		||||
        this._message.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
 | 
			
		||||
        this.actor.add(this._message, { x_fill: false, x_align: St.Align.START, y_align: St.Align.START });
 | 
			
		||||
        this.add(this._message, { x_fill: false, x_align: St.Align.START, y_align: St.Align.START });
 | 
			
		||||
 | 
			
		||||
        this._buttonBox = new St.BoxLayout({ style_class: 'login-dialog-button-box',
 | 
			
		||||
                                             vertical: false });
 | 
			
		||||
        this.actor.add(this._buttonBox,
 | 
			
		||||
                       { expand: true,
 | 
			
		||||
                         x_align: St.Align.MIDDLE,
 | 
			
		||||
                         y_align: St.Align.END });
 | 
			
		||||
        this.add(this._buttonBox, {
 | 
			
		||||
            expand: true,
 | 
			
		||||
            x_align: St.Align.MIDDLE,
 | 
			
		||||
            y_align: St.Align.END
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        this._defaultButtonWell = new St.Widget({ layout_manager: new Clutter.BinLayout() });
 | 
			
		||||
        this._defaultButtonWellActor = null;
 | 
			
		||||
@@ -121,9 +135,9 @@ var AuthPrompt = class {
 | 
			
		||||
        this._initButtons();
 | 
			
		||||
 | 
			
		||||
        this._spinner = new Animation.Spinner(DEFAULT_BUTTON_WELL_ICON_SIZE);
 | 
			
		||||
        this._spinner.actor.opacity = 0;
 | 
			
		||||
        this._spinner.actor.show();
 | 
			
		||||
        this._defaultButtonWell.add_child(this._spinner.actor);
 | 
			
		||||
        this._spinner.opacity = 0;
 | 
			
		||||
        this._spinner.show();
 | 
			
		||||
        this._defaultButtonWell.add_child(this._spinner);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _onDestroy() {
 | 
			
		||||
@@ -131,6 +145,12 @@ var AuthPrompt = class {
 | 
			
		||||
        this._userVerifier = null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    vfunc_key_press_event(keyPressEvent) {
 | 
			
		||||
        if (keyPressEvent.keyval == Clutter.KEY_Escape)
 | 
			
		||||
            this.cancel();
 | 
			
		||||
        return Clutter.EVENT_PROPAGATE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _initButtons() {
 | 
			
		||||
        this.cancelButton = new St.Button({ style_class: 'modal-dialog-button button',
 | 
			
		||||
                                            button_mask: St.ButtonMask.ONE | St.ButtonMask.THREE,
 | 
			
		||||
@@ -241,6 +261,12 @@ var AuthPrompt = class {
 | 
			
		||||
        this.updateSensitivity(canRetry);
 | 
			
		||||
        this.setActorInDefaultButtonWell(null);
 | 
			
		||||
        this.verificationStatus = AuthPromptStatus.VERIFICATION_FAILED;
 | 
			
		||||
 | 
			
		||||
        Util.wiggle(this._entry, {
 | 
			
		||||
            offset: WIGGLE_OFFSET,
 | 
			
		||||
            duration: WIGGLE_DURATION,
 | 
			
		||||
            wiggleCount: N_WIGGLES,
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _onVerificationComplete() {
 | 
			
		||||
@@ -269,13 +295,13 @@ var AuthPrompt = class {
 | 
			
		||||
            oldActor.remove_all_transitions();
 | 
			
		||||
 | 
			
		||||
        let wasSpinner;
 | 
			
		||||
        if (oldActor == this._spinner.actor)
 | 
			
		||||
        if (oldActor == this._spinner)
 | 
			
		||||
            wasSpinner = true;
 | 
			
		||||
        else
 | 
			
		||||
            wasSpinner = false;
 | 
			
		||||
 | 
			
		||||
        let isSpinner;
 | 
			
		||||
        if (actor == this._spinner.actor)
 | 
			
		||||
        if (actor == this._spinner)
 | 
			
		||||
            isSpinner = true;
 | 
			
		||||
        else
 | 
			
		||||
            isSpinner = false;
 | 
			
		||||
@@ -323,7 +349,7 @@ var AuthPrompt = class {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    startSpinning() {
 | 
			
		||||
        this.setActorInDefaultButtonWell(this._spinner.actor, true);
 | 
			
		||||
        this.setActorInDefaultButtonWell(this._spinner, true);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    stopSpinning() {
 | 
			
		||||
@@ -404,9 +430,9 @@ var AuthPrompt = class {
 | 
			
		||||
        this._entry.clutter_text.editable = sensitive;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    hide() {
 | 
			
		||||
    vfunc_hide() {
 | 
			
		||||
        this.setActorInDefaultButtonWell(null, true);
 | 
			
		||||
        this.actor.hide();
 | 
			
		||||
        super.vfunc_hide();
 | 
			
		||||
        this._message.opacity = 0;
 | 
			
		||||
 | 
			
		||||
        this.setUser(null);
 | 
			
		||||
@@ -422,7 +448,7 @@ var AuthPrompt = class {
 | 
			
		||||
 | 
			
		||||
        if (user) {
 | 
			
		||||
            let userWidget = new UserWidget.UserWidget(user);
 | 
			
		||||
            this._userWell.set_child(userWidget.actor);
 | 
			
		||||
            this._userWell.set_child(userWidget);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -507,5 +533,4 @@ var AuthPrompt = class {
 | 
			
		||||
        this.reset();
 | 
			
		||||
        this.emit('cancelled');
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
Signals.addSignalMethods(AuthPrompt.prototype);
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -202,7 +202,6 @@ var ConsecutiveBatch = class extends Batch {
 | 
			
		||||
                hold.disconnect(signalId);
 | 
			
		||||
                this.nextTask();
 | 
			
		||||
            });
 | 
			
		||||
            return;
 | 
			
		||||
        } else {
 | 
			
		||||
            // This task finished, process the next one
 | 
			
		||||
            this.nextTask();
 | 
			
		||||
 
 | 
			
		||||
@@ -19,7 +19,6 @@
 | 
			
		||||
 | 
			
		||||
const { AccountsService, Atk, Clutter, Gdm, Gio,
 | 
			
		||||
        GLib, GObject, Meta, Pango, Shell, St } = imports.gi;
 | 
			
		||||
const Signals = imports.signals;
 | 
			
		||||
 | 
			
		||||
const AuthPrompt = imports.gdm.authPrompt;
 | 
			
		||||
const Batch = imports.gdm.batch;
 | 
			
		||||
@@ -39,72 +38,80 @@ const _TIMED_LOGIN_IDLE_THRESHOLD = 5.0;
 | 
			
		||||
const _LOGO_ICON_HEIGHT = 48;
 | 
			
		||||
const _MAX_BOTTOM_MENU_ITEMS = 5;
 | 
			
		||||
 | 
			
		||||
var UserListItem = class {
 | 
			
		||||
    constructor(user) {
 | 
			
		||||
var UserListItem = GObject.registerClass({
 | 
			
		||||
    GTypeName: 'LoginDialog_UserListItem',
 | 
			
		||||
    Signals: { 'activate': {} }
 | 
			
		||||
}, class UserListItem extends St.Button {
 | 
			
		||||
    _init(user) {
 | 
			
		||||
        let layout = new St.BoxLayout({ vertical: true });
 | 
			
		||||
        super._init({
 | 
			
		||||
            style_class: 'login-dialog-user-list-item',
 | 
			
		||||
            button_mask: St.ButtonMask.ONE | St.ButtonMask.THREE,
 | 
			
		||||
            can_focus: true,
 | 
			
		||||
            child: layout,
 | 
			
		||||
            reactive: true,
 | 
			
		||||
            x_align: St.Align.START,
 | 
			
		||||
            x_fill: true
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        this.user = user;
 | 
			
		||||
        this._userChangedId = this.user.connect('changed',
 | 
			
		||||
                                                this._onUserChanged.bind(this));
 | 
			
		||||
 | 
			
		||||
        let layout = new St.BoxLayout({ vertical: true });
 | 
			
		||||
        this.actor = new St.Button({ style_class: 'login-dialog-user-list-item',
 | 
			
		||||
                                     button_mask: St.ButtonMask.ONE | St.ButtonMask.THREE,
 | 
			
		||||
                                     can_focus: true,
 | 
			
		||||
                                     child: layout,
 | 
			
		||||
                                     reactive: true,
 | 
			
		||||
                                     x_align: St.Align.START,
 | 
			
		||||
                                     x_fill: true });
 | 
			
		||||
        this.actor.connect('destroy', this._onDestroy.bind(this));
 | 
			
		||||
 | 
			
		||||
        this.actor.connect('key-focus-in', () => {
 | 
			
		||||
            this._setSelected(true);
 | 
			
		||||
        });
 | 
			
		||||
        this.actor.connect('key-focus-out', () => {
 | 
			
		||||
            this._setSelected(false);
 | 
			
		||||
        });
 | 
			
		||||
        this.actor.connect('notify::hover', () => {
 | 
			
		||||
            this._setSelected(this.actor.hover);
 | 
			
		||||
        this.connect('destroy', this._onDestroy.bind(this));
 | 
			
		||||
        this.connect('notify::hover', () => {
 | 
			
		||||
            this._setSelected(this.hover);
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        this._userWidget = new UserWidget.UserWidget(this.user);
 | 
			
		||||
        layout.add(this._userWidget.actor);
 | 
			
		||||
        layout.add(this._userWidget);
 | 
			
		||||
 | 
			
		||||
        this._userWidget.actor.bind_property('label-actor', this.actor, 'label-actor',
 | 
			
		||||
                                             GObject.BindingFlags.SYNC_CREATE);
 | 
			
		||||
        this._userWidget.bind_property('label-actor', this, 'label-actor',
 | 
			
		||||
                                       GObject.BindingFlags.SYNC_CREATE);
 | 
			
		||||
 | 
			
		||||
        this._timedLoginIndicator = new St.Bin({ style_class: 'login-dialog-timed-login-indicator',
 | 
			
		||||
                                                 scale_x: 0,
 | 
			
		||||
                                                 visible: false });
 | 
			
		||||
        layout.add(this._timedLoginIndicator);
 | 
			
		||||
 | 
			
		||||
        this.actor.connect('clicked', this._onClicked.bind(this));
 | 
			
		||||
        this._onUserChanged();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    vfunc_key_focus_in() {
 | 
			
		||||
        super.vfunc_key_focus_in();
 | 
			
		||||
        this._setSelected(true);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    vfunc_key_focus_out() {
 | 
			
		||||
        super.vfunc_key_focus_out();
 | 
			
		||||
        this._setSelected(false);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _onUserChanged() {
 | 
			
		||||
        this._updateLoggedIn();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _updateLoggedIn() {
 | 
			
		||||
        if (this.user.is_logged_in())
 | 
			
		||||
            this.actor.add_style_pseudo_class('logged-in');
 | 
			
		||||
            this.add_style_pseudo_class('logged-in');
 | 
			
		||||
        else
 | 
			
		||||
            this.actor.remove_style_pseudo_class('logged-in');
 | 
			
		||||
            this.remove_style_pseudo_class('logged-in');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _onDestroy() {
 | 
			
		||||
        this.user.disconnect(this._userChangedId);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _onClicked() {
 | 
			
		||||
    vfunc_clicked() {
 | 
			
		||||
        this.emit('activate');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _setSelected(selected) {
 | 
			
		||||
        if (selected) {
 | 
			
		||||
            this.actor.add_style_pseudo_class('selected');
 | 
			
		||||
            this.actor.grab_key_focus();
 | 
			
		||||
            this.add_style_pseudo_class('selected');
 | 
			
		||||
            this.grab_key_focus();
 | 
			
		||||
        } else {
 | 
			
		||||
            this.actor.remove_style_pseudo_class('selected');
 | 
			
		||||
            this.remove_style_pseudo_class('selected');
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -145,23 +152,30 @@ var UserListItem = class {
 | 
			
		||||
        this._timedLoginIndicator.visible = false;
 | 
			
		||||
        this._timedLoginIndicator.scale_x = 0.;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
Signals.addSignalMethods(UserListItem.prototype);
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
var UserList = class {
 | 
			
		||||
    constructor() {
 | 
			
		||||
        this.actor = new St.ScrollView({ style_class: 'login-dialog-user-list-view' });
 | 
			
		||||
        this.actor.set_policy(St.PolicyType.NEVER,
 | 
			
		||||
                              St.PolicyType.AUTOMATIC);
 | 
			
		||||
var UserList = GObject.registerClass({
 | 
			
		||||
    GTypeName: 'LoginDialog_UserList',
 | 
			
		||||
    Signals: {
 | 
			
		||||
        'activate': { param_types: [UserListItem.$gtype] },
 | 
			
		||||
        'item-added': { param_types: [UserListItem.$gtype] },
 | 
			
		||||
    }
 | 
			
		||||
}, class UserList extends St.ScrollView {
 | 
			
		||||
    _init() {
 | 
			
		||||
        super._init({ style_class: 'login-dialog-user-list-view' });
 | 
			
		||||
        this.set_policy(St.PolicyType.NEVER,
 | 
			
		||||
                        St.PolicyType.AUTOMATIC);
 | 
			
		||||
 | 
			
		||||
        this._box = new St.BoxLayout({ vertical: true,
 | 
			
		||||
                                       style_class: 'login-dialog-user-list',
 | 
			
		||||
                                       pseudo_class: 'expanded' });
 | 
			
		||||
 | 
			
		||||
        this.actor.add_actor(this._box);
 | 
			
		||||
        this.add_actor(this._box);
 | 
			
		||||
        this._items = {};
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
        this.actor.connect('key-focus-in', this._moveFocusToItems.bind(this));
 | 
			
		||||
    vfunc_key_focus_in() {
 | 
			
		||||
        this._moveFocusToItems();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _moveFocusToItems() {
 | 
			
		||||
@@ -170,10 +184,10 @@ var UserList = class {
 | 
			
		||||
        if (!hasItems)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        if (global.stage.get_key_focus() != this.actor)
 | 
			
		||||
        if (global.stage.get_key_focus() != this)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        let focusSet = this.actor.navigate_focus(null, St.DirectionType.TAB_FORWARD, false);
 | 
			
		||||
        let focusSet = this.navigate_focus(null, St.DirectionType.TAB_FORWARD, false);
 | 
			
		||||
        if (!focusSet) {
 | 
			
		||||
            Meta.later_add(Meta.LaterType.BEFORE_REDRAW, () => {
 | 
			
		||||
                this._moveFocusToItems();
 | 
			
		||||
@@ -194,14 +208,14 @@ var UserList = class {
 | 
			
		||||
 | 
			
		||||
        for (let userName in this._items) {
 | 
			
		||||
            let item = this._items[userName];
 | 
			
		||||
            item.actor.sync_hover();
 | 
			
		||||
            item.sync_hover();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    scrollToItem(item) {
 | 
			
		||||
        let box = item.actor.get_allocation_box();
 | 
			
		||||
        let box = item.get_allocation_box();
 | 
			
		||||
 | 
			
		||||
        let adjustment = this.actor.get_vscroll_bar().get_adjustment();
 | 
			
		||||
        let adjustment = this.get_vscroll_bar().get_adjustment();
 | 
			
		||||
 | 
			
		||||
        let value = (box.y1 + adjustment.step_increment / 2.0) - (adjustment.page_size / 2.0);
 | 
			
		||||
        adjustment.ease(value, {
 | 
			
		||||
@@ -211,9 +225,9 @@ var UserList = class {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    jumpToItem(item) {
 | 
			
		||||
        let box = item.actor.get_allocation_box();
 | 
			
		||||
        let box = item.get_allocation_box();
 | 
			
		||||
 | 
			
		||||
        let adjustment = this.actor.get_vscroll_bar().get_adjustment();
 | 
			
		||||
        let adjustment = this.get_vscroll_bar().get_adjustment();
 | 
			
		||||
 | 
			
		||||
        let value = (box.y1 + adjustment.step_increment / 2.0) - (adjustment.page_size / 2.0);
 | 
			
		||||
 | 
			
		||||
@@ -251,14 +265,14 @@ var UserList = class {
 | 
			
		||||
        this.removeUser(user);
 | 
			
		||||
 | 
			
		||||
        let item = new UserListItem(user);
 | 
			
		||||
        this._box.add(item.actor, { x_fill: true });
 | 
			
		||||
        this._box.add(item, { x_fill: true });
 | 
			
		||||
 | 
			
		||||
        this._items[userName] = item;
 | 
			
		||||
 | 
			
		||||
        item.connect('activate', this._onItemActivated.bind(this));
 | 
			
		||||
 | 
			
		||||
        // Try to keep the focused item front-and-center
 | 
			
		||||
        item.actor.connect('key-focus-in', () => this.scrollToItem(item));
 | 
			
		||||
        item.connect('key-focus-in', () => this.scrollToItem(item));
 | 
			
		||||
 | 
			
		||||
        this._moveFocusToItems();
 | 
			
		||||
 | 
			
		||||
@@ -279,33 +293,38 @@ var UserList = class {
 | 
			
		||||
        if (!item)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        item.actor.destroy();
 | 
			
		||||
        item.destroy();
 | 
			
		||||
        delete this._items[userName];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    numItems() {
 | 
			
		||||
        return Object.keys(this._items).length;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
Signals.addSignalMethods(UserList.prototype);
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
var SessionMenuButton = class {
 | 
			
		||||
    constructor() {
 | 
			
		||||
var SessionMenuButton = GObject.registerClass({
 | 
			
		||||
    GTypeName: 'LoginDialog_SessionMenuButton',
 | 
			
		||||
    Signals: { 'session-activated': { param_types: [GObject.TYPE_STRING] } }
 | 
			
		||||
}, class SessionMenuButton extends St.Bin {
 | 
			
		||||
    _init() {
 | 
			
		||||
        let gearIcon = new St.Icon({ icon_name: 'emblem-system-symbolic' });
 | 
			
		||||
        this._button = new St.Button({ style_class: 'login-dialog-session-list-button',
 | 
			
		||||
                                       reactive: true,
 | 
			
		||||
                                       track_hover: true,
 | 
			
		||||
                                       can_focus: true,
 | 
			
		||||
                                       accessible_name: _("Choose Session"),
 | 
			
		||||
                                       accessible_role: Atk.Role.MENU,
 | 
			
		||||
                                       child: gearIcon });
 | 
			
		||||
        let button = new St.Button({
 | 
			
		||||
            style_class: 'login-dialog-session-list-button',
 | 
			
		||||
            reactive: true,
 | 
			
		||||
            track_hover: true,
 | 
			
		||||
            can_focus: true,
 | 
			
		||||
            accessible_name: _("Choose Session"),
 | 
			
		||||
            accessible_role: Atk.Role.MENU,
 | 
			
		||||
            child: gearIcon
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        this.actor = new St.Bin({ child: this._button });
 | 
			
		||||
        super._init({ child: button });
 | 
			
		||||
        this._button = button;
 | 
			
		||||
 | 
			
		||||
        let side = St.Side.TOP;
 | 
			
		||||
        let align = 0;
 | 
			
		||||
        if (Gdm.get_session_ids().length > _MAX_BOTTOM_MENU_ITEMS) {
 | 
			
		||||
            if (this.actor.text_direction == Clutter.TextDirection.RTL)
 | 
			
		||||
            if (this.text_direction == Clutter.TextDirection.RTL)
 | 
			
		||||
                side = St.Side.RIGHT;
 | 
			
		||||
            else
 | 
			
		||||
                side = St.Side.LEFT;
 | 
			
		||||
@@ -384,15 +403,13 @@ var SessionMenuButton = class {
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
Signals.addSignalMethods(SessionMenuButton.prototype);
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
var LoginDialog = GObject.registerClass({
 | 
			
		||||
    Signals: { 'failed': {} },
 | 
			
		||||
}, class LoginDialog extends St.Widget {
 | 
			
		||||
    _init(parentActor) {
 | 
			
		||||
        super._init({ style_class: 'login-dialog',
 | 
			
		||||
                      visible: false });
 | 
			
		||||
        super._init({ style_class: 'login-dialog', visible: false });
 | 
			
		||||
 | 
			
		||||
        this.get_accessible().set_role(Atk.Role.WINDOW);
 | 
			
		||||
 | 
			
		||||
@@ -426,7 +443,7 @@ var LoginDialog = GObject.registerClass({
 | 
			
		||||
        this.add_child(this._userSelectionBox);
 | 
			
		||||
 | 
			
		||||
        this._userList = new UserList();
 | 
			
		||||
        this._userSelectionBox.add(this._userList.actor,
 | 
			
		||||
        this._userSelectionBox.add(this._userList,
 | 
			
		||||
                                   { expand: true,
 | 
			
		||||
                                     x_fill: true,
 | 
			
		||||
                                     y_fill: true });
 | 
			
		||||
@@ -435,7 +452,7 @@ var LoginDialog = GObject.registerClass({
 | 
			
		||||
        this._authPrompt.connect('prompted', this._onPrompted.bind(this));
 | 
			
		||||
        this._authPrompt.connect('reset', this._onReset.bind(this));
 | 
			
		||||
        this._authPrompt.hide();
 | 
			
		||||
        this.add_child(this._authPrompt.actor);
 | 
			
		||||
        this.add_child(this._authPrompt);
 | 
			
		||||
 | 
			
		||||
        // translators: this message is shown below the user list on the
 | 
			
		||||
        // login screen. It can be activated to reveal an entry for
 | 
			
		||||
@@ -494,9 +511,9 @@ var LoginDialog = GObject.registerClass({
 | 
			
		||||
            (list, sessionId) => {
 | 
			
		||||
                this._greeter.call_select_session_sync (sessionId, null);
 | 
			
		||||
            });
 | 
			
		||||
        this._sessionMenuButton.actor.opacity = 0;
 | 
			
		||||
        this._sessionMenuButton.actor.show();
 | 
			
		||||
        this._authPrompt.addActorToDefaultButtonWell(this._sessionMenuButton.actor);
 | 
			
		||||
        this._sessionMenuButton.opacity = 0;
 | 
			
		||||
        this._sessionMenuButton.show();
 | 
			
		||||
        this._authPrompt.addActorToDefaultButtonWell(this._sessionMenuButton);
 | 
			
		||||
 | 
			
		||||
        this._disableUserList = undefined;
 | 
			
		||||
        this._userListLoaded = false;
 | 
			
		||||
@@ -579,8 +596,8 @@ var LoginDialog = GObject.registerClass({
 | 
			
		||||
 | 
			
		||||
        let authPromptAllocation = null;
 | 
			
		||||
        let authPromptWidth = 0;
 | 
			
		||||
        if (this._authPrompt.actor.visible) {
 | 
			
		||||
            authPromptAllocation = this._getCenterActorAllocation(dialogBox, this._authPrompt.actor);
 | 
			
		||||
        if (this._authPrompt.visible) {
 | 
			
		||||
            authPromptAllocation = this._getCenterActorAllocation(dialogBox, this._authPrompt);
 | 
			
		||||
            authPromptWidth = authPromptAllocation.x2 - authPromptAllocation.x1;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@@ -690,7 +707,7 @@ var LoginDialog = GObject.registerClass({
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (authPromptAllocation)
 | 
			
		||||
            this._authPrompt.actor.allocate(authPromptAllocation, flags);
 | 
			
		||||
            this._authPrompt.allocate(authPromptAllocation, flags);
 | 
			
		||||
 | 
			
		||||
        if (userSelectionAllocation)
 | 
			
		||||
            this._userSelectionBox.allocate(userSelectionAllocation, flags);
 | 
			
		||||
@@ -794,7 +811,7 @@ var LoginDialog = GObject.registerClass({
 | 
			
		||||
    _onPrompted() {
 | 
			
		||||
        if (this._shouldShowSessionMenuButton()) {
 | 
			
		||||
            this._sessionMenuButton.updateSensitivity(true);
 | 
			
		||||
            this._authPrompt.setActorInDefaultButtonWell(this._sessionMenuButton.actor);
 | 
			
		||||
            this._authPrompt.setActorInDefaultButtonWell(this._sessionMenuButton);
 | 
			
		||||
        } else {
 | 
			
		||||
            this._sessionMenuButton.updateSensitivity(false);
 | 
			
		||||
        }
 | 
			
		||||
@@ -854,11 +871,11 @@ var LoginDialog = GObject.registerClass({
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _showPrompt() {
 | 
			
		||||
        if (this._authPrompt.actor.visible)
 | 
			
		||||
        if (this._authPrompt.visible)
 | 
			
		||||
            return;
 | 
			
		||||
        this._authPrompt.actor.opacity = 0;
 | 
			
		||||
        this._authPrompt.actor.show();
 | 
			
		||||
        this._authPrompt.actor.ease({
 | 
			
		||||
        this._authPrompt.opacity = 0;
 | 
			
		||||
        this._authPrompt.show();
 | 
			
		||||
        this._authPrompt.ease({
 | 
			
		||||
            opacity: 255,
 | 
			
		||||
            duration: _FADE_ANIMATION_TIME,
 | 
			
		||||
            mode: Clutter.AnimationMode.EASE_OUT_QUAD
 | 
			
		||||
@@ -921,7 +938,7 @@ var LoginDialog = GObject.registerClass({
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        this._bindOpacity();
 | 
			
		||||
        this.actor.ease({
 | 
			
		||||
        this.ease({
 | 
			
		||||
            opacity: 255,
 | 
			
		||||
            duration: _FADE_ANIMATION_TIME,
 | 
			
		||||
            mode: Clutter.AnimationMode.EASE_OUT_QUAD,
 | 
			
		||||
@@ -944,7 +961,7 @@ var LoginDialog = GObject.registerClass({
 | 
			
		||||
 | 
			
		||||
    _startSession(serviceName) {
 | 
			
		||||
        this._bindOpacity();
 | 
			
		||||
        this.actor.ease({
 | 
			
		||||
        this.ease({
 | 
			
		||||
            opacity: 0,
 | 
			
		||||
            duration: _FADE_ANIMATION_TIME,
 | 
			
		||||
            mode: Clutter.AnimationMode.EASE_OUT_QUAD,
 | 
			
		||||
@@ -1045,12 +1062,12 @@ var LoginDialog = GObject.registerClass({
 | 
			
		||||
                     () => {
 | 
			
		||||
                         // If idle timeout is done, make sure the timed login indicator is shown
 | 
			
		||||
                         if (delay > _TIMED_LOGIN_IDLE_THRESHOLD &&
 | 
			
		||||
                             this._authPrompt.actor.visible)
 | 
			
		||||
                             this._authPrompt.visible)
 | 
			
		||||
                             this._authPrompt.cancel();
 | 
			
		||||
 | 
			
		||||
                         if (delay > _TIMED_LOGIN_IDLE_THRESHOLD || firstRun) {
 | 
			
		||||
                             this._userList.scrollToItem(loginItem);
 | 
			
		||||
                             loginItem.actor.grab_key_focus();
 | 
			
		||||
                             loginItem.grab_key_focus();
 | 
			
		||||
                         }
 | 
			
		||||
                     },
 | 
			
		||||
 | 
			
		||||
@@ -1111,7 +1128,7 @@ var LoginDialog = GObject.registerClass({
 | 
			
		||||
        this._sessionMenuButton.close();
 | 
			
		||||
        this._setUserListExpanded(true);
 | 
			
		||||
        this._notListedButton.show();
 | 
			
		||||
        this._userList.actor.grab_key_focus();
 | 
			
		||||
        this._userList.grab_key_focus();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _beginVerificationForItem(item) {
 | 
			
		||||
@@ -1219,7 +1236,7 @@ var LoginDialog = GObject.registerClass({
 | 
			
		||||
                                        _("Login Window"),
 | 
			
		||||
                                        'dialog-password-symbolic',
 | 
			
		||||
                                        { sortGroup: CtrlAltTab.SortGroup.MIDDLE });
 | 
			
		||||
        this._userList.actor.grab_key_focus();
 | 
			
		||||
        this._userList.grab_key_focus();
 | 
			
		||||
        this.show();
 | 
			
		||||
        this.opacity = 0;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -21,6 +21,7 @@ var Manager = class {
 | 
			
		||||
                                           '/org/freedesktop/realmd',
 | 
			
		||||
                                           this._reloadRealms.bind(this));
 | 
			
		||||
        this._realms = {};
 | 
			
		||||
        this._loginFormat = null;
 | 
			
		||||
 | 
			
		||||
        this._signalId = this._aggregateProvider.connect('g-properties-changed',
 | 
			
		||||
            (proxy, properties) => {
 | 
			
		||||
@@ -86,7 +87,7 @@ var Manager = class {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    get loginFormat() {
 | 
			
		||||
        if (this._loginFormat !== undefined)
 | 
			
		||||
        if (this._loginFormat)
 | 
			
		||||
            return this._loginFormat;
 | 
			
		||||
 | 
			
		||||
        this._updateLoginFormat();
 | 
			
		||||
 
 | 
			
		||||
@@ -165,8 +165,8 @@ function versionCheck(required, current) {
 | 
			
		||||
        let requiredArray = required[i].split('.');
 | 
			
		||||
        if (requiredArray[0] == major &&
 | 
			
		||||
            requiredArray[1] == minor &&
 | 
			
		||||
            (requiredArray[2] == point ||
 | 
			
		||||
             (requiredArray[2] == undefined && parseInt(minor) % 2 == 0)))
 | 
			
		||||
            ((requiredArray[2] === undefined && parseInt(minor) % 2 == 0) ||
 | 
			
		||||
             requiredArray[2] == point))
 | 
			
		||||
            return true;
 | 
			
		||||
    }
 | 
			
		||||
    return false;
 | 
			
		||||
 
 | 
			
		||||
@@ -28,7 +28,7 @@ var HistoryManager = class {
 | 
			
		||||
        this._entry = params.entry;
 | 
			
		||||
 | 
			
		||||
        if (this._entry) {
 | 
			
		||||
            this._entry.connect('key-press-event', 
 | 
			
		||||
            this._entry.connect('key-press-event',
 | 
			
		||||
                                this._onEntryKeyPress.bind(this));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -2,7 +2,6 @@
 | 
			
		||||
/* exported getIBusManager */
 | 
			
		||||
 | 
			
		||||
const { Gio, GLib, IBus } = imports.gi;
 | 
			
		||||
const Mainloop = imports.mainloop;
 | 
			
		||||
const Signals = imports.signals;
 | 
			
		||||
 | 
			
		||||
const IBusCandidatePopup = imports.ui.ibusCandidatePopup;
 | 
			
		||||
@@ -19,9 +18,9 @@ function _checkIBusVersion(requiredMajor, requiredMinor, requiredMicro) {
 | 
			
		||||
         IBus.MICRO_VERSION >= requiredMicro))
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    throw "Found IBus version %d.%d.%d but required is %d.%d.%d".
 | 
			
		||||
        format(IBus.MAJOR_VERSION, IBus.MINOR_VERSION, IBus.MINOR_VERSION,
 | 
			
		||||
               requiredMajor, requiredMinor, requiredMicro);
 | 
			
		||||
    throw "Found IBus version %d.%d.%d but required is %d.%d.%d"
 | 
			
		||||
        .format(IBus.MAJOR_VERSION, IBus.MINOR_VERSION, IBus.MINOR_VERSION,
 | 
			
		||||
                requiredMajor, requiredMinor, requiredMicro);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function getIBusManager() {
 | 
			
		||||
@@ -73,6 +72,16 @@ var IBusManager = class {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _clear() {
 | 
			
		||||
        if (this._cancellable) {
 | 
			
		||||
            this._cancellable.cancel();
 | 
			
		||||
            this._cancellable = null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (this._preloadEnginesId) {
 | 
			
		||||
            GLib.source_remove(this._preloadEnginesId);
 | 
			
		||||
            this._preloadEnginesId = 0;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (this._panelService)
 | 
			
		||||
            this._panelService.destroy();
 | 
			
		||||
 | 
			
		||||
@@ -87,28 +96,41 @@ var IBusManager = class {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _onConnected() {
 | 
			
		||||
        this._ibus.list_engines_async(-1, null, this._initEngines.bind(this));
 | 
			
		||||
        this._cancellable = new Gio.Cancellable();
 | 
			
		||||
        this._ibus.list_engines_async(-1, this._cancellable,
 | 
			
		||||
            this._initEngines.bind(this));
 | 
			
		||||
        this._ibus.request_name_async(IBus.SERVICE_PANEL,
 | 
			
		||||
                                      IBus.BusNameFlag.REPLACE_EXISTING,
 | 
			
		||||
                                      -1, null,
 | 
			
		||||
                                      this._initPanelService.bind(this));
 | 
			
		||||
            IBus.BusNameFlag.REPLACE_EXISTING, -1, this._cancellable,
 | 
			
		||||
            this._initPanelService.bind(this));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _initEngines(ibus, result) {
 | 
			
		||||
        let enginesList = this._ibus.list_engines_async_finish(result);
 | 
			
		||||
        if (enginesList) {
 | 
			
		||||
        try {
 | 
			
		||||
            let enginesList = this._ibus.list_engines_async_finish(result);
 | 
			
		||||
            for (let i = 0; i < enginesList.length; ++i) {
 | 
			
		||||
                let name = enginesList[i].get_name();
 | 
			
		||||
                this._engines.set(name, enginesList[i]);
 | 
			
		||||
            }
 | 
			
		||||
            this._updateReadiness();
 | 
			
		||||
        } else {
 | 
			
		||||
        } catch (e) {
 | 
			
		||||
            if (e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED))
 | 
			
		||||
                return;
 | 
			
		||||
 | 
			
		||||
            logError(e);
 | 
			
		||||
            this._clear();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _initPanelService(ibus, result) {
 | 
			
		||||
        let success = this._ibus.request_name_async_finish(result);
 | 
			
		||||
        let success = false;
 | 
			
		||||
        try {
 | 
			
		||||
            success = !!this._ibus.request_name_async_finish(result);
 | 
			
		||||
        } catch (e) {
 | 
			
		||||
            if (e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED))
 | 
			
		||||
                return;
 | 
			
		||||
            logError(e);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (success) {
 | 
			
		||||
            this._panelService = new IBus.PanelService({ connection: this._ibus.get_connection(),
 | 
			
		||||
                                                         object_path: IBus.PATH_PANEL });
 | 
			
		||||
@@ -135,7 +157,7 @@ var IBusManager = class {
 | 
			
		||||
            } catch (e) {
 | 
			
		||||
            }
 | 
			
		||||
            // If an engine is already active we need to get its properties
 | 
			
		||||
            this._ibus.get_global_engine_async(-1, null, (i, result) => {
 | 
			
		||||
            this._ibus.get_global_engine_async(-1, this._cancellable, (_bus, result) => {
 | 
			
		||||
                let engine;
 | 
			
		||||
                try {
 | 
			
		||||
                    engine = this._ibus.get_global_engine_async_finish(result);
 | 
			
		||||
@@ -207,8 +229,18 @@ var IBusManager = class {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this._ibus.set_global_engine_async(id, this._MAX_INPUT_SOURCE_ACTIVATION_TIME,
 | 
			
		||||
                                           null, callback || null);
 | 
			
		||||
        this._ibus.set_global_engine_async(id,
 | 
			
		||||
            this._MAX_INPUT_SOURCE_ACTIVATION_TIME,
 | 
			
		||||
            this._cancellable, (_bus, res) => {
 | 
			
		||||
                try {
 | 
			
		||||
                    this._ibus.set_global_engine_async_finish(res);
 | 
			
		||||
                } catch (e) {
 | 
			
		||||
                    if (!e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED))
 | 
			
		||||
                        logError(e);
 | 
			
		||||
                }
 | 
			
		||||
                if (callback)
 | 
			
		||||
                    callback();
 | 
			
		||||
            });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    preloadEngines(ids) {
 | 
			
		||||
@@ -216,21 +248,23 @@ var IBusManager = class {
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        if (this._preloadEnginesId != 0) {
 | 
			
		||||
            Mainloop.source_remove(this._preloadEnginesId);
 | 
			
		||||
            GLib.source_remove(this._preloadEnginesId);
 | 
			
		||||
            this._preloadEnginesId = 0;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this._preloadEnginesId =
 | 
			
		||||
            Mainloop.timeout_add_seconds(this._PRELOAD_ENGINES_DELAY_TIME,
 | 
			
		||||
                                         () => {
 | 
			
		||||
                                             this._ibus.preload_engines_async(
 | 
			
		||||
                                                 ids,
 | 
			
		||||
                                                 -1,
 | 
			
		||||
                                                 null,
 | 
			
		||||
                                                 null);
 | 
			
		||||
                                             this._preloadEnginesId = 0;
 | 
			
		||||
                                             return GLib.SOURCE_REMOVE;
 | 
			
		||||
                                         });
 | 
			
		||||
            GLib.timeout_add_seconds(
 | 
			
		||||
                GLib.PRIORITY_DEFAULT,
 | 
			
		||||
                this._PRELOAD_ENGINES_DELAY_TIME,
 | 
			
		||||
                () => {
 | 
			
		||||
                    this._ibus.preload_engines_async(
 | 
			
		||||
                        ids,
 | 
			
		||||
                        -1,
 | 
			
		||||
                        this._cancellable,
 | 
			
		||||
                        null);
 | 
			
		||||
                    this._preloadEnginesId = 0;
 | 
			
		||||
                    return GLib.SOURCE_REMOVE;
 | 
			
		||||
                });
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
Signals.addSignalMethods(IBusManager.prototype);
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
 | 
			
		||||
/* exported InputMethod */
 | 
			
		||||
const { Clutter, GLib, GObject, IBus } = imports.gi;
 | 
			
		||||
const { Clutter, GLib, Gio, GObject, IBus } = imports.gi;
 | 
			
		||||
 | 
			
		||||
const Keyboard = imports.ui.status.keyboard;
 | 
			
		||||
 | 
			
		||||
@@ -36,15 +36,7 @@ class InputMethod extends Clutter.InputMethod {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _updateCapabilities() {
 | 
			
		||||
        let caps = 0;
 | 
			
		||||
 | 
			
		||||
        if (this.can_show_preedit)
 | 
			
		||||
            caps |= IBus.Capabilite.PREEDIT_TEXT;
 | 
			
		||||
 | 
			
		||||
        if (this._currentFocus)
 | 
			
		||||
            caps |= IBus.Capabilite.FOCUS | IBus.Capabilite.SURROUNDING_TEXT;
 | 
			
		||||
        else
 | 
			
		||||
            caps |= IBus.Capabilite.PREEDIT_TEXT | IBus.Capabilite.AUXILIARY_TEXT | IBus.Capabilite.LOOKUP_TABLE | IBus.Capabilite.PROPERTY;
 | 
			
		||||
        let caps = IBus.Capabilite.PREEDIT_TEXT | IBus.Capabilite.FOCUS | IBus.Capabilite.SURROUNDING_TEXT;
 | 
			
		||||
 | 
			
		||||
        if (this._context)
 | 
			
		||||
            this._context.set_capabilities(caps);
 | 
			
		||||
@@ -55,12 +47,22 @@ class InputMethod extends Clutter.InputMethod {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _onConnected() {
 | 
			
		||||
        this._ibus.create_input_context_async ('gnome-shell', -1, null,
 | 
			
		||||
                                               this._setContext.bind(this));
 | 
			
		||||
        this._cancellable = new Gio.Cancellable();
 | 
			
		||||
        this._ibus.create_input_context_async ('gnome-shell', -1,
 | 
			
		||||
            this._cancellable, this._setContext.bind(this));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _setContext(bus, res) {
 | 
			
		||||
        this._context = this._ibus.create_input_context_async_finish(res);
 | 
			
		||||
        try {
 | 
			
		||||
            this._context = this._ibus.create_input_context_async_finish(res);
 | 
			
		||||
        } catch (e) {
 | 
			
		||||
            if (!e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED)) {
 | 
			
		||||
                logError(e);
 | 
			
		||||
                this._clear();
 | 
			
		||||
            }
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this._context.connect('commit-text', this._onCommitText.bind(this));
 | 
			
		||||
        this._context.connect('delete-surrounding-text', this._onDeleteSurroundingText.bind(this));
 | 
			
		||||
        this._context.connect('update-preedit-text', this._onUpdatePreeditText.bind(this));
 | 
			
		||||
@@ -72,6 +74,11 @@ class InputMethod extends Clutter.InputMethod {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _clear() {
 | 
			
		||||
        if (this._cancellable) {
 | 
			
		||||
            this._cancellable.cancel();
 | 
			
		||||
            this._cancellable = null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this._context = null;
 | 
			
		||||
        this._hints = 0;
 | 
			
		||||
        this._purpose = 0;
 | 
			
		||||
@@ -137,7 +144,6 @@ class InputMethod extends Clutter.InputMethod {
 | 
			
		||||
        this._currentFocus = focus;
 | 
			
		||||
        if (this._context) {
 | 
			
		||||
            this._context.focus_in();
 | 
			
		||||
            this._updateCapabilities();
 | 
			
		||||
            this._emitRequestSurrounding();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@@ -149,10 +155,8 @@ class InputMethod extends Clutter.InputMethod {
 | 
			
		||||
 | 
			
		||||
    vfunc_focus_out() {
 | 
			
		||||
        this._currentFocus = null;
 | 
			
		||||
        if (this._context) {
 | 
			
		||||
        if (this._context)
 | 
			
		||||
            this._context.focus_out();
 | 
			
		||||
            this._updateCapabilities();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (this._preeditStr) {
 | 
			
		||||
            // Unset any preedit text
 | 
			
		||||
@@ -255,17 +259,19 @@ class InputMethod extends Clutter.InputMethod {
 | 
			
		||||
        if (event.type() == Clutter.EventType.KEY_RELEASE)
 | 
			
		||||
            state |= IBus.ModifierType.RELEASE_MASK;
 | 
			
		||||
 | 
			
		||||
        this._context.process_key_event_async(event.get_key_symbol(),
 | 
			
		||||
                                              event.get_key_code() - 8, // Convert XKB keycodes to evcodes
 | 
			
		||||
                                              state, -1, null,
 | 
			
		||||
                                              (context, res) => {
 | 
			
		||||
                                                  try {
 | 
			
		||||
                                                      let retval = context.process_key_event_async_finish(res);
 | 
			
		||||
                                                      this.notify_key_event(event, retval);
 | 
			
		||||
                                                  } catch (e) {
 | 
			
		||||
                                                      log(`Error processing key on IM: ${e.message}`);
 | 
			
		||||
                                                  }
 | 
			
		||||
                                              });
 | 
			
		||||
        this._context.process_key_event_async(
 | 
			
		||||
            event.get_key_symbol(),
 | 
			
		||||
            event.get_key_code() - 8, // Convert XKB keycodes to evcodes
 | 
			
		||||
            state, -1, this._cancellable,
 | 
			
		||||
            (context, res) => {
 | 
			
		||||
                try {
 | 
			
		||||
                    let retval = context.process_key_event_async_finish(res);
 | 
			
		||||
                    this.notify_key_event(event, retval);
 | 
			
		||||
                } catch (e) {
 | 
			
		||||
                    if (!e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED))
 | 
			
		||||
                        log(`Error processing key on IM: ${e.message}`);
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -127,7 +127,8 @@ var IntrospectService = class {
 | 
			
		||||
        let apps = this._appSystem.get_running();
 | 
			
		||||
        let windowsList = {};
 | 
			
		||||
 | 
			
		||||
        if (!this._isIntrospectEnabled()) {
 | 
			
		||||
        if (!this._isIntrospectEnabled() &&
 | 
			
		||||
            !this._isSenderWhitelisted(invocation.get_sender())) {
 | 
			
		||||
            invocation.return_error_literal(Gio.DBusError,
 | 
			
		||||
                                            Gio.DBusError.ACCESS_DENIED,
 | 
			
		||||
                                            'App introspection not allowed');
 | 
			
		||||
 
 | 
			
		||||
@@ -172,7 +172,7 @@ function getPropertyNamesFromExpression(expr, commandHeader = '') {
 | 
			
		||||
 | 
			
		||||
        // Make sure propsUnique contains one key for every
 | 
			
		||||
        // property so we end up with a unique list of properties
 | 
			
		||||
        allProps.map(p => propsUnique[p] = null);
 | 
			
		||||
        allProps.map(p => (propsUnique[p] = null));
 | 
			
		||||
    }
 | 
			
		||||
    return Object.keys(propsUnique).sort();
 | 
			
		||||
}
 | 
			
		||||
@@ -217,7 +217,7 @@ function isUnsafeExpression(str) {
 | 
			
		||||
    prunedStr = prunedStr.replace(/[=!]==/g, '');    //replace === and !== with nothing
 | 
			
		||||
    prunedStr = prunedStr.replace(/[=<>!]=/g, '');    //replace ==, <=, >=, != with nothing
 | 
			
		||||
 | 
			
		||||
    if (prunedStr.match(/=/)) {
 | 
			
		||||
    if (prunedStr.match(/[=]/)) {
 | 
			
		||||
        return true;
 | 
			
		||||
    } else if (prunedStr.match(/;/)) {
 | 
			
		||||
        // If we contain a semicolon not inside of a quote/regex, assume we're unsafe as well
 | 
			
		||||
 
 | 
			
		||||
@@ -84,9 +84,9 @@ function _findProviderForSid(sid) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Support for the old ModemManager interface (MM < 0.7)
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// ----------------------------------------------------- //
 | 
			
		||||
// Support for the old ModemManager interface (MM < 0.7) //
 | 
			
		||||
// ----------------------------------------------------- //
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// The following are not the complete interfaces, just the methods we need
 | 
			
		||||
@@ -182,9 +182,9 @@ var ModemCdma = class {
 | 
			
		||||
Signals.addSignalMethods(ModemCdma.prototype);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Support for the new ModemManager1 interface (MM >= 0.7)
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// ------------------------------------------------------- //
 | 
			
		||||
// Support for the new ModemManager1 interface (MM >= 0.7) //
 | 
			
		||||
// ------------------------------------------------------- //
 | 
			
		||||
 | 
			
		||||
const BroadbandModemInterface = loadInterfaceXML('org.freedesktop.ModemManager1.Modem');
 | 
			
		||||
const BroadbandModemProxy = Gio.DBusProxy.makeProxyWrapper(BroadbandModemInterface);
 | 
			
		||||
 
 | 
			
		||||
@@ -244,8 +244,9 @@ const SystemActions = GObject.registerClass({
 | 
			
		||||
 | 
			
		||||
    _updateOrientationLockIcon() {
 | 
			
		||||
        let locked = this._orientationSettings.get_boolean('orientation-lock');
 | 
			
		||||
        let iconName = locked ? 'rotation-locked-symbolic'
 | 
			
		||||
                              : 'rotation-allowed-symbolic';
 | 
			
		||||
        let iconName = locked
 | 
			
		||||
            ? 'rotation-locked-symbolic'
 | 
			
		||||
            : 'rotation-allowed-symbolic';
 | 
			
		||||
        this._actions.get(LOCK_ORIENTATION_ACTION_ID).iconName = iconName;
 | 
			
		||||
 | 
			
		||||
        this.notify('orientation-lock-icon');
 | 
			
		||||
@@ -268,7 +269,7 @@ const SystemActions = GObject.registerClass({
 | 
			
		||||
 | 
			
		||||
    getMatchingActions(terms) {
 | 
			
		||||
        // terms is a list of strings
 | 
			
		||||
        terms = terms.map((term) => term.toLowerCase());
 | 
			
		||||
        terms = terms.map(term => term.toLowerCase());
 | 
			
		||||
 | 
			
		||||
        let results = [];
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,11 +1,10 @@
 | 
			
		||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
 | 
			
		||||
/* exported findUrls, spawn, spawnCommandLine, spawnApp, trySpawnCommandLine,
 | 
			
		||||
            formatTime, formatTimeSpan, createTimeLabel, insertSorted,
 | 
			
		||||
            makeCloseButton, ensureActorVisibleInScrollView */
 | 
			
		||||
            makeCloseButton, ensureActorVisibleInScrollView, wiggle */
 | 
			
		||||
 | 
			
		||||
const { Clutter, Gio, GLib, GObject, Shell, St } = imports.gi;
 | 
			
		||||
const Gettext = imports.gettext;
 | 
			
		||||
const Mainloop = imports.mainloop;
 | 
			
		||||
 | 
			
		||||
const Main = imports.ui.main;
 | 
			
		||||
const Params = imports.misc.params;
 | 
			
		||||
@@ -15,7 +14,7 @@ var SCROLL_TIME = 100;
 | 
			
		||||
// http://daringfireball.net/2010/07/improved_regex_for_matching_urls
 | 
			
		||||
const _balancedParens = '\\([^\\s()<>]+\\)';
 | 
			
		||||
const _leadingJunk = '[\\s`(\\[{\'\\"<\u00AB\u201C\u2018]';
 | 
			
		||||
const _notTrailingJunk = '[^\\s`!()\\[\\]{};:\'\\".,<>?\u00AB\u00BB\u201C\u201D\u2018\u2019]';
 | 
			
		||||
const _notTrailingJunk = '[^\\s`!()\\[\\]{};:\'\\".,<>?\u00AB\u00BB\u200E\u200F\u201C\u201D\u2018\u2019\u202A\u202C]';
 | 
			
		||||
 | 
			
		||||
const _urlRegexp = new RegExp(
 | 
			
		||||
    `(^|${_leadingJunk})` +
 | 
			
		||||
@@ -314,7 +313,8 @@ function lowerBound(array, val, cmp) {
 | 
			
		||||
    if (array.length == 0)
 | 
			
		||||
        return 0;
 | 
			
		||||
 | 
			
		||||
    min = 0; max = array.length;
 | 
			
		||||
    min = 0;
 | 
			
		||||
    max = array.length;
 | 
			
		||||
    while (min < (max - 1)) {
 | 
			
		||||
        mid = Math.floor((min + max) / 2);
 | 
			
		||||
        v = cmp(array[mid], val);
 | 
			
		||||
@@ -429,3 +429,37 @@ function ensureActorVisibleInScrollView(scrollView, actor) {
 | 
			
		||||
        duration: SCROLL_TIME
 | 
			
		||||
    });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function wiggle(actor, params) {
 | 
			
		||||
    params = Params.parse(params, {
 | 
			
		||||
        offset: 0,
 | 
			
		||||
        duration: 0,
 | 
			
		||||
        wiggleCount: 0,
 | 
			
		||||
    });
 | 
			
		||||
    actor.translation_x = 0;
 | 
			
		||||
 | 
			
		||||
    // Accelerate before wiggling
 | 
			
		||||
    actor.ease({
 | 
			
		||||
        translation_x: -params.offset,
 | 
			
		||||
        duration: params.duration,
 | 
			
		||||
        mode: Clutter.AnimationMode.EASE_OUT_QUAD,
 | 
			
		||||
        onComplete: () => {
 | 
			
		||||
            // Wiggle
 | 
			
		||||
            actor.ease({
 | 
			
		||||
                translation_x: params.offset,
 | 
			
		||||
                duration: params.duration,
 | 
			
		||||
                mode: Clutter.AnimationMode.LINEAR,
 | 
			
		||||
                repeatCount: params.wiggleCount,
 | 
			
		||||
                autoReverse: true,
 | 
			
		||||
                onComplete: () => {
 | 
			
		||||
                    // Decelerate and return to the original position
 | 
			
		||||
                    actor.ease({
 | 
			
		||||
                        translation_x: 0,
 | 
			
		||||
                        duration: params.duration,
 | 
			
		||||
                        mode: Clutter.AnimationMode.EASE_IN_QUAD,
 | 
			
		||||
                    });
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
    });
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -127,11 +127,11 @@ function *run() {
 | 
			
		||||
    for (let i = 0; i < 2; i++) {
 | 
			
		||||
        Scripting.scriptEvent('applicationsShowStart');
 | 
			
		||||
        // eslint-disable-next-line require-atomic-updates
 | 
			
		||||
        Main.overview._dash.showAppsButton.checked = true;
 | 
			
		||||
        Main.overview.dash.showAppsButton.checked = true;
 | 
			
		||||
        yield Scripting.waitLeisure();
 | 
			
		||||
        Scripting.scriptEvent('applicationsShowDone');
 | 
			
		||||
        // eslint-disable-next-line require-atomic-updates
 | 
			
		||||
        Main.overview._dash.showAppsButton.checked = false;
 | 
			
		||||
        Main.overview.dash.showAppsButton.checked = false;
 | 
			
		||||
        yield Scripting.waitLeisure();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -57,7 +57,7 @@ function waitAndDraw(milliseconds) {
 | 
			
		||||
            cb();
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    return callback => cb = callback;
 | 
			
		||||
    return callback => (cb = callback);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function waitSignal(object, signal) {
 | 
			
		||||
@@ -69,7 +69,7 @@ function waitSignal(object, signal) {
 | 
			
		||||
            cb();
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    return callback => cb = callback;
 | 
			
		||||
    return callback => (cb = callback);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function extractBootTimestamp() {
 | 
			
		||||
@@ -127,7 +127,7 @@ function *run() {
 | 
			
		||||
 | 
			
		||||
    Scripting.scriptEvent('applicationsShowStart');
 | 
			
		||||
    // eslint-disable-next-line require-atomic-updates
 | 
			
		||||
    Main.overview._dash.showAppsButton.checked = true;
 | 
			
		||||
    Main.overview.dash.showAppsButton.checked = true;
 | 
			
		||||
 | 
			
		||||
    yield Scripting.waitLeisure();
 | 
			
		||||
    Scripting.scriptEvent('applicationsShowDone');
 | 
			
		||||
@@ -137,9 +137,9 @@ function *run() {
 | 
			
		||||
    Main.overview.hide();
 | 
			
		||||
    yield Scripting.waitLeisure();
 | 
			
		||||
 | 
			
		||||
    ////////////////////////////////////////
 | 
			
		||||
    // Tests of redraw speed
 | 
			
		||||
    ////////////////////////////////////////
 | 
			
		||||
    // --------------------- //
 | 
			
		||||
    // Tests of redraw speed //
 | 
			
		||||
    // --------------------- //
 | 
			
		||||
 | 
			
		||||
    global.frame_timestamps = true;
 | 
			
		||||
    global.frame_finish_timestamp = true;
 | 
			
		||||
@@ -186,8 +186,6 @@ function *run() {
 | 
			
		||||
 | 
			
		||||
    yield Scripting.sleep(1000);
 | 
			
		||||
 | 
			
		||||
    ////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
    let appSys = Shell.AppSystem.get_default();
 | 
			
		||||
    let app = appSys.lookup_app('org.gnome.gedit.desktop');
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -56,8 +56,8 @@ class AccessDialog extends ModalDialog.ModalDialog {
 | 
			
		||||
 | 
			
		||||
            let check = new CheckBox.CheckBox();
 | 
			
		||||
            check.getLabelActor().text = name;
 | 
			
		||||
            check.actor.checked = selected == "true";
 | 
			
		||||
            content.insertBeforeBody(check.actor);
 | 
			
		||||
            check.checked = selected == "true";
 | 
			
		||||
            content.insertBeforeBody(check);
 | 
			
		||||
 | 
			
		||||
            this._choices.set(id, check);
 | 
			
		||||
        }
 | 
			
		||||
@@ -99,7 +99,7 @@ class AccessDialog extends ModalDialog.ModalDialog {
 | 
			
		||||
        let results = {};
 | 
			
		||||
        if (response == DialogResponse.OK) {
 | 
			
		||||
            for (let [id, check] of this._choices) {
 | 
			
		||||
                let checked = check.actor.checked ? 'true' : 'false';
 | 
			
		||||
                let checked = check.checked ? 'true' : 'false';
 | 
			
		||||
                results[id] = new GLib.Variant('s', checked);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
@@ -147,7 +147,7 @@ var AccessDialogDBus = class {
 | 
			
		||||
                                      subtitle, body, options);
 | 
			
		||||
        dialog.open();
 | 
			
		||||
 | 
			
		||||
        dialog.connect('closed', () => this._accessDialog = null);
 | 
			
		||||
        dialog.connect('closed', () => (this._accessDialog = null));
 | 
			
		||||
 | 
			
		||||
        this._accessDialog = dialog;
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -3,7 +3,6 @@
 | 
			
		||||
            WindowCyclerPopup */
 | 
			
		||||
 | 
			
		||||
const { Atk, Clutter, Gio, GLib, GObject, Meta, Shell, St } = imports.gi;
 | 
			
		||||
const Mainloop = imports.mainloop;
 | 
			
		||||
 | 
			
		||||
const Main = imports.ui.main;
 | 
			
		||||
const SwitcherPopup = imports.ui.switcherPopup;
 | 
			
		||||
@@ -292,7 +291,7 @@ class AppSwitcherPopup extends SwitcherPopup.SwitcherPopup {
 | 
			
		||||
        if (this._thumbnails)
 | 
			
		||||
            this._destroyThumbnails();
 | 
			
		||||
        if (this._thumbnailTimeoutId != 0)
 | 
			
		||||
            Mainloop.source_remove(this._thumbnailTimeoutId);
 | 
			
		||||
            GLib.source_remove(this._thumbnailTimeoutId);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@@ -327,7 +326,7 @@ class AppSwitcherPopup extends SwitcherPopup.SwitcherPopup {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (this._thumbnailTimeoutId != 0) {
 | 
			
		||||
            Mainloop.source_remove(this._thumbnailTimeoutId);
 | 
			
		||||
            GLib.source_remove(this._thumbnailTimeoutId);
 | 
			
		||||
            this._thumbnailTimeoutId = 0;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@@ -344,7 +343,8 @@ class AppSwitcherPopup extends SwitcherPopup.SwitcherPopup {
 | 
			
		||||
            this._thumbnails.highlight(window, forceAppFocus);
 | 
			
		||||
        } else if (this._items[this._selectedIndex].cachedWindows.length > 1 &&
 | 
			
		||||
                   !forceAppFocus) {
 | 
			
		||||
            this._thumbnailTimeoutId = Mainloop.timeout_add (
 | 
			
		||||
            this._thumbnailTimeoutId = GLib.timeout_add(
 | 
			
		||||
                GLib.PRIORITY_DEFAULT,
 | 
			
		||||
                THUMBNAIL_POPUP_TIME,
 | 
			
		||||
                this._timeoutPopupThumbnails.bind(this));
 | 
			
		||||
            GLib.Source.set_name_by_id(this._thumbnailTimeoutId, '[gnome-shell] this._timeoutPopupThumbnails');
 | 
			
		||||
@@ -405,27 +405,26 @@ class AppSwitcherPopup extends SwitcherPopup.SwitcherPopup {
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
class CyclerHighlight {
 | 
			
		||||
    constructor() {
 | 
			
		||||
var CyclerHighlight = GObject.registerClass(
 | 
			
		||||
class CyclerHighlight extends St.Widget {
 | 
			
		||||
    _init() {
 | 
			
		||||
        super._init({ layout_manager: new Clutter.BinLayout() });
 | 
			
		||||
        this._window = null;
 | 
			
		||||
 | 
			
		||||
        this.actor = new St.Widget({ layout_manager: new Clutter.BinLayout() });
 | 
			
		||||
 | 
			
		||||
        this._clone = new Clutter.Clone();
 | 
			
		||||
        this.actor.add_actor(this._clone);
 | 
			
		||||
        this.add_actor(this._clone);
 | 
			
		||||
 | 
			
		||||
        this._highlight = new St.Widget({ style_class: 'cycler-highlight' });
 | 
			
		||||
        this.actor.add_actor(this._highlight);
 | 
			
		||||
        this.add_actor(this._highlight);
 | 
			
		||||
 | 
			
		||||
        let coordinate = Clutter.BindCoordinate.ALL;
 | 
			
		||||
        let constraint = new Clutter.BindConstraint({ coordinate: coordinate });
 | 
			
		||||
        this._clone.bind_property('source', constraint, 'source', 0);
 | 
			
		||||
 | 
			
		||||
        this.actor.add_constraint(constraint);
 | 
			
		||||
        this.add_constraint(constraint);
 | 
			
		||||
 | 
			
		||||
        this.actor.connect('notify::allocation',
 | 
			
		||||
                           this._onAllocationChanged.bind(this));
 | 
			
		||||
        this.actor.connect('destroy', this._onDestroy.bind(this));
 | 
			
		||||
        this.connect('notify::allocation', this._onAllocationChanged.bind(this));
 | 
			
		||||
        this.connect('destroy', this._onDestroy.bind(this));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    set window(w) {
 | 
			
		||||
@@ -437,8 +436,8 @@ class CyclerHighlight {
 | 
			
		||||
        if (this._clone.source)
 | 
			
		||||
            this._clone.source.sync_visibility();
 | 
			
		||||
 | 
			
		||||
        let windowActor = this._window ? this._window.get_compositor_private()
 | 
			
		||||
                                       : null;
 | 
			
		||||
        let windowActor = this._window
 | 
			
		||||
            ? this._window.get_compositor_private() : null;
 | 
			
		||||
 | 
			
		||||
        if (windowActor)
 | 
			
		||||
            windowActor.hide();
 | 
			
		||||
@@ -451,7 +450,7 @@ class CyclerHighlight {
 | 
			
		||||
            this._highlight.set_size(0, 0);
 | 
			
		||||
            this._highlight.hide();
 | 
			
		||||
        } else {
 | 
			
		||||
            let [x, y] = this.actor.allocation.get_origin();
 | 
			
		||||
            let [x, y] = this.allocation.get_origin();
 | 
			
		||||
            let rect = this._window.get_frame_rect();
 | 
			
		||||
            this._highlight.set_size(rect.width, rect.height);
 | 
			
		||||
            this._highlight.set_position(rect.x - x, rect.y - y);
 | 
			
		||||
@@ -462,7 +461,7 @@ class CyclerHighlight {
 | 
			
		||||
    _onDestroy() {
 | 
			
		||||
        this.window = null;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
// We don't show an actual popup, so just provide what SwitcherPopup
 | 
			
		||||
// expects instead of inheriting from SwitcherList
 | 
			
		||||
@@ -489,7 +488,7 @@ var CyclerPopup = GObject.registerClass({
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        this._highlight = new CyclerHighlight();
 | 
			
		||||
        global.window_group.add_actor(this._highlight.actor);
 | 
			
		||||
        global.window_group.add_actor(this._highlight);
 | 
			
		||||
 | 
			
		||||
        this._switcherList = new CyclerList();
 | 
			
		||||
        this._switcherList.connect('item-highlighted', (list, index) => {
 | 
			
		||||
@@ -499,7 +498,7 @@ var CyclerPopup = GObject.registerClass({
 | 
			
		||||
 | 
			
		||||
    _highlightItem(index, _justOutline) {
 | 
			
		||||
        this._highlight.window = this._items[index];
 | 
			
		||||
        global.window_group.set_child_above_sibling(this._highlight.actor, null);
 | 
			
		||||
        global.window_group.set_child_above_sibling(this._highlight, null);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _finish() {
 | 
			
		||||
@@ -529,7 +528,7 @@ var CyclerPopup = GObject.registerClass({
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _onDestroy() {
 | 
			
		||||
        this._highlight.actor.destroy();
 | 
			
		||||
        this._highlight.destroy();
 | 
			
		||||
 | 
			
		||||
        super._onDestroy();
 | 
			
		||||
    }
 | 
			
		||||
@@ -648,8 +647,9 @@ class WindowCyclerPopup extends CyclerPopup {
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
var AppIcon = GObject.registerClass(
 | 
			
		||||
class AppIcon extends St.BoxLayout {
 | 
			
		||||
var AppIcon = GObject.registerClass({
 | 
			
		||||
    GTypeName: 'AltTab_AppIcon'
 | 
			
		||||
}, class AppIcon extends St.BoxLayout {
 | 
			
		||||
    _init(app) {
 | 
			
		||||
        super._init({ style_class: 'alt-tab-app',
 | 
			
		||||
                      vertical: true });
 | 
			
		||||
@@ -711,7 +711,7 @@ class AppSwitcher extends SwitcherPopup.SwitcherList {
 | 
			
		||||
 | 
			
		||||
    _onDestroy() {
 | 
			
		||||
        if (this._mouseTimeOutId != 0)
 | 
			
		||||
            Mainloop.source_remove(this._mouseTimeOutId);
 | 
			
		||||
            GLib.source_remove(this._mouseTimeOutId);
 | 
			
		||||
 | 
			
		||||
        this.icons.forEach(icon => {
 | 
			
		||||
            icon.app.disconnect(icon._stateChangedId);
 | 
			
		||||
@@ -790,14 +790,16 @@ class AppSwitcher extends SwitcherPopup.SwitcherList {
 | 
			
		||||
    // activation when the thumbnail list is open
 | 
			
		||||
    _onItemEnter(index) {
 | 
			
		||||
        if (this._mouseTimeOutId != 0)
 | 
			
		||||
            Mainloop.source_remove(this._mouseTimeOutId);
 | 
			
		||||
            GLib.source_remove(this._mouseTimeOutId);
 | 
			
		||||
        if (this._altTabPopup.thumbnailsVisible) {
 | 
			
		||||
            this._mouseTimeOutId = Mainloop.timeout_add(APP_ICON_HOVER_TIMEOUT,
 | 
			
		||||
                                                        () => {
 | 
			
		||||
                                                            this._enterItem(index);
 | 
			
		||||
                                                            this._mouseTimeOutId = 0;
 | 
			
		||||
                                                            return GLib.SOURCE_REMOVE;
 | 
			
		||||
                                                        });
 | 
			
		||||
            this._mouseTimeOutId = GLib.timeout_add(
 | 
			
		||||
                GLib.PRIORITY_DEFAULT,
 | 
			
		||||
                APP_ICON_HOVER_TIMEOUT,
 | 
			
		||||
                () => {
 | 
			
		||||
                    this._enterItem(index);
 | 
			
		||||
                    this._mouseTimeOutId = 0;
 | 
			
		||||
                    return GLib.SOURCE_REMOVE;
 | 
			
		||||
                });
 | 
			
		||||
            GLib.Source.set_name_by_id(this._mouseTimeOutId, '[gnome-shell] this._enterItem');
 | 
			
		||||
        } else {
 | 
			
		||||
            this._itemEntered(index);
 | 
			
		||||
@@ -874,9 +876,9 @@ class ThumbnailList extends SwitcherPopup.SwitcherList {
 | 
			
		||||
    _init(windows) {
 | 
			
		||||
        super._init(false);
 | 
			
		||||
 | 
			
		||||
        this._labels = new Array();
 | 
			
		||||
        this._thumbnailBins = new Array();
 | 
			
		||||
        this._clones = new Array();
 | 
			
		||||
        this._labels = [];
 | 
			
		||||
        this._thumbnailBins = [];
 | 
			
		||||
        this._clones = [];
 | 
			
		||||
        this._windows = windows;
 | 
			
		||||
 | 
			
		||||
        for (let i = 0; i < windows.length; i++) {
 | 
			
		||||
@@ -937,7 +939,7 @@ class ThumbnailList extends SwitcherPopup.SwitcherList {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Make sure we only do this once
 | 
			
		||||
        this._thumbnailBins = new Array();
 | 
			
		||||
        this._thumbnailBins = [];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _removeThumbnail(source, clone) {
 | 
			
		||||
@@ -1011,9 +1013,9 @@ class WindowIcon extends St.BoxLayout {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _createAppIcon(app, size) {
 | 
			
		||||
        let appIcon = app ? app.create_icon_texture(size)
 | 
			
		||||
                          : new St.Icon({ icon_name: 'icon-missing',
 | 
			
		||||
                                          icon_size: size });
 | 
			
		||||
        let appIcon = app
 | 
			
		||||
            ? app.create_icon_texture(size)
 | 
			
		||||
            : new St.Icon({ icon_name: 'icon-missing', icon_size: size });
 | 
			
		||||
        appIcon.x_expand = appIcon.y_expand = true;
 | 
			
		||||
        appIcon.x_align = appIcon.y_align = Clutter.ActorAlign.END;
 | 
			
		||||
 | 
			
		||||
@@ -1040,7 +1042,7 @@ class WindowList extends SwitcherPopup.SwitcherList {
 | 
			
		||||
            this.addItem(icon, icon.label);
 | 
			
		||||
            this.icons.push(icon);
 | 
			
		||||
 | 
			
		||||
            icon._unmanagedSignalId = icon.window.connect('unmanaged', (window) => {
 | 
			
		||||
            icon._unmanagedSignalId = icon.window.connect('unmanaged', window => {
 | 
			
		||||
                this._removeWindow(window);
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -1,20 +1,18 @@
 | 
			
		||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
 | 
			
		||||
/* exported Animation, AnimatedIcon, Spinner */
 | 
			
		||||
 | 
			
		||||
const { Clutter, GLib, Gio, St } = imports.gi;
 | 
			
		||||
const Mainloop = imports.mainloop;
 | 
			
		||||
const { Clutter, GLib, GObject, Gio, St } = imports.gi;
 | 
			
		||||
 | 
			
		||||
var ANIMATED_ICON_UPDATE_TIMEOUT = 16;
 | 
			
		||||
var SPINNER_ANIMATION_TIME = 300;
 | 
			
		||||
var SPINNER_ANIMATION_DELAY = 1000;
 | 
			
		||||
 | 
			
		||||
var Animation = class {
 | 
			
		||||
    constructor(file, width, height, speed) {
 | 
			
		||||
        this.actor = new St.Bin();
 | 
			
		||||
        this.actor.set_size(width, height);
 | 
			
		||||
        this.actor.connect('destroy', this._onDestroy.bind(this));
 | 
			
		||||
        this.actor.connect('notify::size', this._syncAnimationSize.bind(this));
 | 
			
		||||
        this.actor.connect('resource-scale-changed',
 | 
			
		||||
var Animation = GObject.registerClass(
 | 
			
		||||
class Animation extends St.Bin {
 | 
			
		||||
    _init(file, width, height, speed) {
 | 
			
		||||
        super._init({ width: width, height: height });
 | 
			
		||||
        this.connect('destroy', this._onDestroy.bind(this));
 | 
			
		||||
        this.connect('resource-scale-changed',
 | 
			
		||||
            this._loadFile.bind(this, file, width, height));
 | 
			
		||||
 | 
			
		||||
        let themeContext = St.ThemeContext.get_for_stage(global.stage);
 | 
			
		||||
@@ -45,7 +43,7 @@ var Animation = class {
 | 
			
		||||
 | 
			
		||||
    stop() {
 | 
			
		||||
        if (this._timeoutId > 0) {
 | 
			
		||||
            Mainloop.source_remove(this._timeoutId);
 | 
			
		||||
            GLib.source_remove(this._timeoutId);
 | 
			
		||||
            this._timeoutId = 0;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@@ -53,20 +51,30 @@ var Animation = class {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _loadFile(file, width, height) {
 | 
			
		||||
        let [validResourceScale, resourceScale] = this.actor.get_resource_scale();
 | 
			
		||||
        let [validResourceScale, resourceScale] = this.get_resource_scale();
 | 
			
		||||
        let wasPlaying = this._isPlaying;
 | 
			
		||||
 | 
			
		||||
        if (this._isPlaying)
 | 
			
		||||
            this.stop();
 | 
			
		||||
 | 
			
		||||
        this._isLoaded = false;
 | 
			
		||||
        this.actor.destroy_all_children();
 | 
			
		||||
        this.destroy_all_children();
 | 
			
		||||
 | 
			
		||||
        if (!validResourceScale)
 | 
			
		||||
        if (!validResourceScale) {
 | 
			
		||||
            if (wasPlaying)
 | 
			
		||||
                this.play();
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let textureCache = St.TextureCache.get_default();
 | 
			
		||||
        let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor;
 | 
			
		||||
        this._animations = textureCache.load_sliced_image(file, width, height,
 | 
			
		||||
                                                          scaleFactor, resourceScale,
 | 
			
		||||
                                                          this._animationsLoaded.bind(this));
 | 
			
		||||
        this.actor.set_child(this._animations);
 | 
			
		||||
        this.set_child(this._animations);
 | 
			
		||||
 | 
			
		||||
        if (wasPlaying)
 | 
			
		||||
            this.play();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _showFrame(frame) {
 | 
			
		||||
@@ -90,7 +98,7 @@ var Animation = class {
 | 
			
		||||
        if (!this._isLoaded)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        let [width, height] = this.actor.get_size();
 | 
			
		||||
        let [width, height] = this.get_size();
 | 
			
		||||
 | 
			
		||||
        for (let i = 0; i < this._animations.get_n_children(); ++i)
 | 
			
		||||
            this._animations.get_child_at_index(i).set_size(width, height);
 | 
			
		||||
@@ -113,20 +121,22 @@ var Animation = class {
 | 
			
		||||
            themeContext.disconnect(this._scaleChangedId);
 | 
			
		||||
        this._scaleChangedId = 0;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
var AnimatedIcon = class extends Animation {
 | 
			
		||||
    constructor(file, size) {
 | 
			
		||||
        super(file, size, size, ANIMATED_ICON_UPDATE_TIMEOUT);
 | 
			
		||||
var AnimatedIcon = GObject.registerClass(
 | 
			
		||||
class AnimatedIcon extends Animation {
 | 
			
		||||
    _init(file, size) {
 | 
			
		||||
        super._init(file, size, size, ANIMATED_ICON_UPDATE_TIMEOUT);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
var Spinner = class extends AnimatedIcon {
 | 
			
		||||
    constructor(size, animate = false) {
 | 
			
		||||
var Spinner = GObject.registerClass(
 | 
			
		||||
class Spinner extends AnimatedIcon {
 | 
			
		||||
    _init(size, animate = false) {
 | 
			
		||||
        let file = Gio.File.new_for_uri('resource:///org/gnome/shell/theme/process-working.svg');
 | 
			
		||||
        super(file, size);
 | 
			
		||||
        super._init(file, size);
 | 
			
		||||
 | 
			
		||||
        this.actor.opacity = 0;
 | 
			
		||||
        this.opacity = 0;
 | 
			
		||||
        this._animate = animate;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -136,35 +146,35 @@ var Spinner = class extends AnimatedIcon {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    play() {
 | 
			
		||||
        this.actor.remove_all_transitions();
 | 
			
		||||
        this.remove_all_transitions();
 | 
			
		||||
 | 
			
		||||
        if (this._animate) {
 | 
			
		||||
            super.play();
 | 
			
		||||
            this.actor.ease({
 | 
			
		||||
            this.ease({
 | 
			
		||||
                opacity: 255,
 | 
			
		||||
                delay: SPINNER_ANIMATION_DELAY,
 | 
			
		||||
                duration: SPINNER_ANIMATION_TIME,
 | 
			
		||||
                mode: Clutter.AnimationMode.LINEAR
 | 
			
		||||
            });
 | 
			
		||||
        } else {
 | 
			
		||||
            this.actor.opacity = 255;
 | 
			
		||||
            this.opacity = 255;
 | 
			
		||||
            super.play();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    stop() {
 | 
			
		||||
        this.actor.remove_all_transitions();
 | 
			
		||||
        this.remove_all_transitions();
 | 
			
		||||
 | 
			
		||||
        if (this._animate) {
 | 
			
		||||
            this.actor.ease({
 | 
			
		||||
            this.ease({
 | 
			
		||||
                opacity: 0,
 | 
			
		||||
                time: SPINNER_ANIMATION_TIME,
 | 
			
		||||
                transition: 'linear',
 | 
			
		||||
                duration: SPINNER_ANIMATION_TIME,
 | 
			
		||||
                mode: Clutter.AnimationMode.LINEAR,
 | 
			
		||||
                onComplete: () => super.stop()
 | 
			
		||||
            });
 | 
			
		||||
        } else {
 | 
			
		||||
            this.actor.opacity = 0;
 | 
			
		||||
            this.opacity = 0;
 | 
			
		||||
            super.stop();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -55,6 +55,7 @@ const RENAMED_DESKTOP_IDS = {
 | 
			
		||||
    'org.gnome.taquin.desktop': 'org.gnome.Taquin.desktop',
 | 
			
		||||
    'org.gnome.Weather.Application.desktop': 'org.gnome.Weather.desktop',
 | 
			
		||||
    'polari.desktop': 'org.gnome.Polari.desktop',
 | 
			
		||||
    'shotwell.desktop': 'org.gnome.Shotwell.desktop',
 | 
			
		||||
    'tali.desktop': 'org.gnome.Tali.desktop',
 | 
			
		||||
    'totem.desktop': 'org.gnome.Totem.desktop',
 | 
			
		||||
    'evince.desktop': 'org.gnome.Evince.desktop',
 | 
			
		||||
@@ -147,12 +148,11 @@ class AppFavorites {
 | 
			
		||||
 | 
			
		||||
        let app = Shell.AppSystem.get_default().lookup_app(appId);
 | 
			
		||||
 | 
			
		||||
        Main.overview.setMessage(_("%s has been added to your favorites.").format(app.get_name()),
 | 
			
		||||
                                 { forFeedback: true,
 | 
			
		||||
                                   undoCallback: () => {
 | 
			
		||||
                                       this._removeFavorite(appId);
 | 
			
		||||
                                   }
 | 
			
		||||
                                 });
 | 
			
		||||
        let msg = _("%s has been added to your favorites.").format(app.get_name());
 | 
			
		||||
        Main.overview.setMessage(msg, {
 | 
			
		||||
            forFeedback: true,
 | 
			
		||||
            undoCallback: () => this._removeFavorite(appId),
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    addFavorite(appId) {
 | 
			
		||||
@@ -181,12 +181,11 @@ class AppFavorites {
 | 
			
		||||
        if (!this._removeFavorite(appId))
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        Main.overview.setMessage(_("%s has been removed from your favorites.").format(app.get_name()),
 | 
			
		||||
                                 { forFeedback: true,
 | 
			
		||||
                                   undoCallback: () => {
 | 
			
		||||
                                       this._addFavorite(appId, pos);
 | 
			
		||||
                                   }
 | 
			
		||||
                                 });
 | 
			
		||||
        let msg = _("%s has been removed from your favorites.").format(app.get_name());
 | 
			
		||||
        Main.overview.setMessage(msg, {
 | 
			
		||||
            forFeedback: true,
 | 
			
		||||
            undoCallback: () => this._addFavorite(appId, pos),
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
Signals.addSignalMethods(AppFavorites.prototype);
 | 
			
		||||
 
 | 
			
		||||
@@ -161,7 +161,7 @@ var AudioDeviceSelectionDBus = class AudioDeviceSelectionDBus {
 | 
			
		||||
 | 
			
		||||
        let [deviceNames] = params;
 | 
			
		||||
        let devices = 0;
 | 
			
		||||
        deviceNames.forEach(n => devices |= AudioDevice[n.toUpperCase()]);
 | 
			
		||||
        deviceNames.forEach(n => (devices |= AudioDevice[n.toUpperCase()]));
 | 
			
		||||
 | 
			
		||||
        let dialog;
 | 
			
		||||
        try {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
 | 
			
		||||
/* exported SystemBackground */
 | 
			
		||||
 | 
			
		||||
// READ THIS FIRST
 | 
			
		||||
// Background handling is a maze of objects, both objects in this file, and
 | 
			
		||||
@@ -93,7 +94,7 @@
 | 
			
		||||
//     MetaBackgroundImage         MetaBackgroundImage
 | 
			
		||||
//     MetaBackgroundImage         MetaBackgroundImage
 | 
			
		||||
 | 
			
		||||
const { Clutter, GDesktopEnums, Gio, GLib, GnomeDesktop, Meta } = imports.gi;
 | 
			
		||||
const { Clutter, GDesktopEnums, Gio, GLib, GObject, GnomeDesktop, Meta } = imports.gi;
 | 
			
		||||
const Signals = imports.signals;
 | 
			
		||||
 | 
			
		||||
const LoginManager = imports.misc.loginManager;
 | 
			
		||||
@@ -220,16 +221,17 @@ function getBackgroundCache() {
 | 
			
		||||
    return _backgroundCache;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var Background = class Background {
 | 
			
		||||
    constructor(params) {
 | 
			
		||||
var Background = GObject.registerClass({
 | 
			
		||||
    Signals: { 'loaded': {}, 'bg-changed': {} }
 | 
			
		||||
}, class Background extends Meta.Background {
 | 
			
		||||
    _init(params) {
 | 
			
		||||
        params = Params.parse(params, { monitorIndex: 0,
 | 
			
		||||
                                        layoutManager: Main.layoutManager,
 | 
			
		||||
                                        settings: null,
 | 
			
		||||
                                        file: null,
 | 
			
		||||
                                        style: null });
 | 
			
		||||
 | 
			
		||||
        this.background = new Meta.Background({ meta_display: global.display });
 | 
			
		||||
        this.background._delegate = this;
 | 
			
		||||
        super._init({ meta_display: global.display });
 | 
			
		||||
 | 
			
		||||
        this._settings = params.settings;
 | 
			
		||||
        this._file = params.file;
 | 
			
		||||
@@ -262,8 +264,6 @@ var Background = class Background {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    destroy() {
 | 
			
		||||
        this.background = null;
 | 
			
		||||
 | 
			
		||||
        this._cancellable.cancel();
 | 
			
		||||
        this._removeAnimationTimeout();
 | 
			
		||||
 | 
			
		||||
@@ -300,9 +300,11 @@ var Background = class Background {
 | 
			
		||||
 | 
			
		||||
        this._changedIdleId = GLib.idle_add(GLib.PRIORITY_DEFAULT, () => {
 | 
			
		||||
            this._changedIdleId = 0;
 | 
			
		||||
            this.emit('changed');
 | 
			
		||||
            this.emit('bg-changed');
 | 
			
		||||
            return GLib.SOURCE_REMOVE;
 | 
			
		||||
        });
 | 
			
		||||
        GLib.Source.set_name_by_id(this._changedIdleId,
 | 
			
		||||
            '[gnome-shell] Background._emitChangedSignal');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    updateResolution() {
 | 
			
		||||
@@ -328,7 +330,7 @@ var Background = class Background {
 | 
			
		||||
            this.emit('loaded');
 | 
			
		||||
            return GLib.SOURCE_REMOVE;
 | 
			
		||||
        });
 | 
			
		||||
        GLib.Source.set_name_by_id(id, '[gnome-shell] this.emit');
 | 
			
		||||
        GLib.Source.set_name_by_id(id, '[gnome-shell] Background._setLoaded Idle');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _loadPattern() {
 | 
			
		||||
@@ -342,9 +344,9 @@ var Background = class Background {
 | 
			
		||||
        let shadingType = this._settings.get_enum(COLOR_SHADING_TYPE_KEY);
 | 
			
		||||
 | 
			
		||||
        if (shadingType == GDesktopEnums.BackgroundShading.SOLID)
 | 
			
		||||
            this.background.set_color(color);
 | 
			
		||||
            this.set_color(color);
 | 
			
		||||
        else
 | 
			
		||||
            this.background.set_gradient(shadingType, color, secondColor);
 | 
			
		||||
            this.set_gradient(shadingType, color, secondColor);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _watchFile(file) {
 | 
			
		||||
@@ -380,13 +382,13 @@ var Background = class Background {
 | 
			
		||||
        let finish = () => {
 | 
			
		||||
            this._setLoaded();
 | 
			
		||||
            if (files.length > 1) {
 | 
			
		||||
                this.background.set_blend(files[0], files[1],
 | 
			
		||||
                                          this._animation.transitionProgress,
 | 
			
		||||
                                          this._style);
 | 
			
		||||
                this.set_blend(files[0], files[1],
 | 
			
		||||
                               this._animation.transitionProgress,
 | 
			
		||||
                               this._style);
 | 
			
		||||
            } else if (files.length > 0) {
 | 
			
		||||
                this.background.set_file(files[0], this._style);
 | 
			
		||||
                this.set_file(files[0], this._style);
 | 
			
		||||
            } else {
 | 
			
		||||
                this.background.set_file(null, this._style);
 | 
			
		||||
                this.set_file(null, this._style);
 | 
			
		||||
            }
 | 
			
		||||
            this._queueUpdateAnimation();
 | 
			
		||||
        };
 | 
			
		||||
@@ -441,24 +443,25 @@ var Background = class Background {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _loadAnimation(file) {
 | 
			
		||||
        this._cache.getAnimation({ file: file,
 | 
			
		||||
                                   settingsSchema: this._settings.schema_id,
 | 
			
		||||
                                   onLoaded: animation => {
 | 
			
		||||
                                       this._animation = animation;
 | 
			
		||||
        this._cache.getAnimation({
 | 
			
		||||
            file: file,
 | 
			
		||||
            settingsSchema: this._settings.schema_id,
 | 
			
		||||
            onLoaded: animation => {
 | 
			
		||||
                this._animation = animation;
 | 
			
		||||
 | 
			
		||||
                                       if (!this._animation || this._cancellable.is_cancelled()) {
 | 
			
		||||
                                           this._setLoaded();
 | 
			
		||||
                                           return;
 | 
			
		||||
                                       }
 | 
			
		||||
                if (!this._animation || this._cancellable.is_cancelled()) {
 | 
			
		||||
                    this._setLoaded();
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                                       this._updateAnimation();
 | 
			
		||||
                                       this._watchFile(file);
 | 
			
		||||
                                   }
 | 
			
		||||
                                 });
 | 
			
		||||
                this._updateAnimation();
 | 
			
		||||
                this._watchFile(file);
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _loadImage(file) {
 | 
			
		||||
        this.background.set_file(file, this._style);
 | 
			
		||||
        this.set_file(file, this._style);
 | 
			
		||||
        this._watchFile(file);
 | 
			
		||||
 | 
			
		||||
        let cache = Meta.BackgroundImageCache.get_default();
 | 
			
		||||
@@ -492,13 +495,14 @@ var Background = class Background {
 | 
			
		||||
 | 
			
		||||
        this._loadFile(this._file);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
Signals.addSignalMethods(Background.prototype);
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
let _systemBackground;
 | 
			
		||||
 | 
			
		||||
var SystemBackground = class SystemBackground {
 | 
			
		||||
    constructor() {
 | 
			
		||||
var SystemBackground = GObject.registerClass({
 | 
			
		||||
    Signals: { 'loaded': {} }
 | 
			
		||||
}, class SystemBackground extends Meta.BackgroundActor {
 | 
			
		||||
    _init() {
 | 
			
		||||
        let file = Gio.File.new_for_uri('resource:///org/gnome/shell/theme/noise-texture.png');
 | 
			
		||||
 | 
			
		||||
        if (_systemBackground == null) {
 | 
			
		||||
@@ -507,9 +511,11 @@ var SystemBackground = class SystemBackground {
 | 
			
		||||
            _systemBackground.set_file(file, GDesktopEnums.BackgroundStyle.WALLPAPER);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this.actor = new Meta.BackgroundActor({ meta_display: global.display,
 | 
			
		||||
                                                monitor: 0,
 | 
			
		||||
                                                background: _systemBackground });
 | 
			
		||||
        super._init({
 | 
			
		||||
            meta_display: global.display,
 | 
			
		||||
            monitor: 0,
 | 
			
		||||
            background: _systemBackground
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        let cache = Meta.BackgroundImageCache.get_default();
 | 
			
		||||
        let image = cache.load(file);
 | 
			
		||||
@@ -528,8 +534,7 @@ var SystemBackground = class SystemBackground {
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
Signals.addSignalMethods(SystemBackground.prototype);
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
var BackgroundSource = class BackgroundSource {
 | 
			
		||||
    constructor(layoutManager, settingsSchema) {
 | 
			
		||||
@@ -565,7 +570,7 @@ var BackgroundSource = class BackgroundSource {
 | 
			
		||||
 | 
			
		||||
        // We don't watch changes to settings here,
 | 
			
		||||
        // instead we rely on Background to watch those
 | 
			
		||||
        // and emit 'changed' at the right time
 | 
			
		||||
        // and emit 'bg-changed' at the right time
 | 
			
		||||
 | 
			
		||||
        if (this._overrideImage != null) {
 | 
			
		||||
            file = Gio.File.new_for_path(this._overrideImage);
 | 
			
		||||
@@ -594,7 +599,7 @@ var BackgroundSource = class BackgroundSource {
 | 
			
		||||
                style: style
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            background._changedId = background.connect('changed', () => {
 | 
			
		||||
            background._changedId = background.connect('bg-changed', () => {
 | 
			
		||||
                background.disconnect(background._changedId);
 | 
			
		||||
                background.destroy();
 | 
			
		||||
                delete this._backgrounds[monitorIndex];
 | 
			
		||||
@@ -731,7 +736,7 @@ var BackgroundManager = class BackgroundManager {
 | 
			
		||||
 | 
			
		||||
        this._newBackgroundActor = newBackgroundActor;
 | 
			
		||||
 | 
			
		||||
        let background = newBackgroundActor.background._delegate;
 | 
			
		||||
        let background = newBackgroundActor.background;
 | 
			
		||||
 | 
			
		||||
        if (background.isLoaded) {
 | 
			
		||||
            this._swapBackgroundActor();
 | 
			
		||||
@@ -748,13 +753,14 @@ var BackgroundManager = class BackgroundManager {
 | 
			
		||||
 | 
			
		||||
    _createBackgroundActor() {
 | 
			
		||||
        let background = this._backgroundSource.getBackground(this._monitorIndex);
 | 
			
		||||
        let backgroundActor = new Meta.BackgroundActor({ meta_display: global.display,
 | 
			
		||||
                                                         monitor: this._monitorIndex,
 | 
			
		||||
                                                         background: background.background,
 | 
			
		||||
                                                         vignette: this._vignette,
 | 
			
		||||
                                                         vignette_sharpness: 0.5,
 | 
			
		||||
                                                         brightness: 0.5,
 | 
			
		||||
                                                       });
 | 
			
		||||
        let backgroundActor = new Meta.BackgroundActor({
 | 
			
		||||
            meta_display: global.display,
 | 
			
		||||
            monitor: this._monitorIndex,
 | 
			
		||||
            background,
 | 
			
		||||
            vignette: this._vignette,
 | 
			
		||||
            vignette_sharpness: 0.5,
 | 
			
		||||
            brightness: 0.5,
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        this._container.add_child(backgroundActor);
 | 
			
		||||
 | 
			
		||||
@@ -764,7 +770,7 @@ var BackgroundManager = class BackgroundManager {
 | 
			
		||||
            backgroundActor.lower_bottom();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let changeSignalId = background.connect('changed', () => {
 | 
			
		||||
        let changeSignalId = background.connect('bg-changed', () => {
 | 
			
		||||
            background.disconnect(changeSignalId);
 | 
			
		||||
            changeSignalId = null;
 | 
			
		||||
            this._updateBackgroundActor();
 | 
			
		||||
 
 | 
			
		||||
@@ -31,7 +31,7 @@ function addBackgroundMenu(actor, layoutManager) {
 | 
			
		||||
 | 
			
		||||
    function openMenu(x, y) {
 | 
			
		||||
        Main.layoutManager.setDummyCursorGeometry(x, y, 0, 0);
 | 
			
		||||
        actor._backgroundMenu.open(BoxPointer.PopupAnimation.NONE);
 | 
			
		||||
        actor._backgroundMenu.open(BoxPointer.PopupAnimation.FULL);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    let clickAction = new Clutter.ClickAction();
 | 
			
		||||
 
 | 
			
		||||
@@ -46,12 +46,18 @@ var BoxPointer = GObject.registerClass({
 | 
			
		||||
        this.add_actor(this._border);
 | 
			
		||||
        this.bin.raise(this._border);
 | 
			
		||||
        this._sourceAlignment = 0.5;
 | 
			
		||||
        this._capturedEventId = 0;
 | 
			
		||||
        this._muteInput();
 | 
			
		||||
        this._muteInput = true;
 | 
			
		||||
 | 
			
		||||
        this.connect('destroy', this._onDestroy.bind(this));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    vfunc_captured_event() {
 | 
			
		||||
        if (this._muteInput)
 | 
			
		||||
            return Clutter.EVENT_STOP;
 | 
			
		||||
 | 
			
		||||
        return Clutter.EVENT_PROPAGATE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _onDestroy() {
 | 
			
		||||
        if (this._sourceActorDestroyId) {
 | 
			
		||||
            this._sourceActor.disconnect(this._sourceActorDestroyId);
 | 
			
		||||
@@ -63,19 +69,6 @@ var BoxPointer = GObject.registerClass({
 | 
			
		||||
        return this._arrowSide;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _muteInput() {
 | 
			
		||||
        if (this._capturedEventId == 0)
 | 
			
		||||
            this._capturedEventId = this.connect('captured-event',
 | 
			
		||||
                                                 () => Clutter.EVENT_STOP);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _unmuteInput() {
 | 
			
		||||
        if (this._capturedEventId != 0) {
 | 
			
		||||
            this.disconnect(this._capturedEventId);
 | 
			
		||||
            this._capturedEventId = 0;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    open(animate, onComplete) {
 | 
			
		||||
        let themeNode = this.get_theme_node();
 | 
			
		||||
        let rise = themeNode.get_length('-arrow-rise');
 | 
			
		||||
@@ -112,7 +105,7 @@ var BoxPointer = GObject.registerClass({
 | 
			
		||||
            duration: animationTime,
 | 
			
		||||
            mode: Clutter.AnimationMode.LINEAR,
 | 
			
		||||
            onComplete: () => {
 | 
			
		||||
                this._unmuteInput();
 | 
			
		||||
                this._muteInput = false;
 | 
			
		||||
                if (onComplete)
 | 
			
		||||
                    onComplete();
 | 
			
		||||
            }
 | 
			
		||||
@@ -147,7 +140,7 @@ var BoxPointer = GObject.registerClass({
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this._muteInput();
 | 
			
		||||
        this._muteInput = true;
 | 
			
		||||
 | 
			
		||||
        this.remove_all_transitions();
 | 
			
		||||
        this.ease({
 | 
			
		||||
@@ -172,8 +165,8 @@ var BoxPointer = GObject.registerClass({
 | 
			
		||||
        let borderWidth = themeNode.get_length('-arrow-border-width');
 | 
			
		||||
        minSize += borderWidth * 2;
 | 
			
		||||
        natSize += borderWidth * 2;
 | 
			
		||||
        if ((!isWidth && (this._arrowSide == St.Side.TOP || this._arrowSide == St.Side.BOTTOM))
 | 
			
		||||
            || (isWidth && (this._arrowSide == St.Side.LEFT || this._arrowSide == St.Side.RIGHT))) {
 | 
			
		||||
        if ((!isWidth && (this._arrowSide == St.Side.TOP || this._arrowSide == St.Side.BOTTOM)) ||
 | 
			
		||||
            (isWidth && (this._arrowSide == St.Side.LEFT || this._arrowSide == St.Side.RIGHT))) {
 | 
			
		||||
            let rise = themeNode.get_length('-arrow-rise');
 | 
			
		||||
            minSize += rise;
 | 
			
		||||
            natSize += rise;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,7 @@
 | 
			
		||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
 | 
			
		||||
/* exported Calendar, CalendarMessageList */
 | 
			
		||||
 | 
			
		||||
const { Clutter, Gio, GLib, Shell, St } = imports.gi;
 | 
			
		||||
const { Clutter, Gio, GLib, GObject, Shell, St } = imports.gi;
 | 
			
		||||
const Signals = imports.signals;
 | 
			
		||||
 | 
			
		||||
const Main = imports.ui.main;
 | 
			
		||||
@@ -313,8 +313,10 @@ var DBusEventSource = class DBusEventSource {
 | 
			
		||||
};
 | 
			
		||||
Signals.addSignalMethods(DBusEventSource.prototype);
 | 
			
		||||
 | 
			
		||||
var Calendar = class Calendar {
 | 
			
		||||
    constructor() {
 | 
			
		||||
var Calendar = GObject.registerClass({
 | 
			
		||||
    Signals: { 'selected-date-changed': { param_types: [GLib.DateTime.$gtype] } }
 | 
			
		||||
}, class Calendar extends St.Widget {
 | 
			
		||||
    _init() {
 | 
			
		||||
        this._weekStart = Shell.util_get_week_start();
 | 
			
		||||
        this._settings = new Gio.Settings({ schema_id: 'org.gnome.desktop.calendar' });
 | 
			
		||||
 | 
			
		||||
@@ -344,12 +346,11 @@ var Calendar = class Calendar {
 | 
			
		||||
 | 
			
		||||
        this._shouldDateGrabFocus = false;
 | 
			
		||||
 | 
			
		||||
        this.actor = new St.Widget({ style_class: 'calendar',
 | 
			
		||||
                                     layout_manager: new Clutter.TableLayout(),
 | 
			
		||||
                                     reactive: true });
 | 
			
		||||
 | 
			
		||||
        this.actor.connect('scroll-event',
 | 
			
		||||
                           this._onScroll.bind(this));
 | 
			
		||||
        super._init({
 | 
			
		||||
            style_class: 'calendar',
 | 
			
		||||
            layout_manager: new Clutter.TableLayout(),
 | 
			
		||||
            reactive: true
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        this._buildHeader ();
 | 
			
		||||
    }
 | 
			
		||||
@@ -373,7 +374,10 @@ var Calendar = class Calendar {
 | 
			
		||||
 | 
			
		||||
        this._selectedDate = date;
 | 
			
		||||
        this._update();
 | 
			
		||||
        this.emit('selected-date-changed', new Date(this._selectedDate));
 | 
			
		||||
 | 
			
		||||
        let datetime = GLib.DateTime.new_from_unix_local(
 | 
			
		||||
            this._selectedDate.getTime() / 1000);
 | 
			
		||||
        this.emit('selected-date-changed', datetime);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    updateTimeZone() {
 | 
			
		||||
@@ -384,9 +388,9 @@ var Calendar = class Calendar {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _buildHeader() {
 | 
			
		||||
        let layout = this.actor.layout_manager;
 | 
			
		||||
        let layout = this.layout_manager;
 | 
			
		||||
        let offsetCols = this._useWeekdate ? 1 : 0;
 | 
			
		||||
        this.actor.destroy_all_children();
 | 
			
		||||
        this.destroy_all_children();
 | 
			
		||||
 | 
			
		||||
        // Top line of the calendar '<| September 2009 |>'
 | 
			
		||||
        this._topBox = new St.BoxLayout();
 | 
			
		||||
@@ -428,7 +432,7 @@ var Calendar = class Calendar {
 | 
			
		||||
                                       can_focus: true });
 | 
			
		||||
            label.accessible_name = iter.toLocaleFormat('%A');
 | 
			
		||||
            let col;
 | 
			
		||||
            if (this.actor.get_text_direction() == Clutter.TextDirection.RTL)
 | 
			
		||||
            if (this.get_text_direction() == Clutter.TextDirection.RTL)
 | 
			
		||||
                col = 6 - (7 + iter.getDay() - this._weekStart) % 7;
 | 
			
		||||
            else
 | 
			
		||||
                col = offsetCols + (7 + iter.getDay() - this._weekStart) % 7;
 | 
			
		||||
@@ -437,11 +441,11 @@ var Calendar = class Calendar {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // All the children after this are days, and get removed when we update the calendar
 | 
			
		||||
        this._firstDayIndex = this.actor.get_n_children();
 | 
			
		||||
        this._firstDayIndex = this.get_n_children();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _onScroll(actor, event) {
 | 
			
		||||
        switch (event.get_scroll_direction()) {
 | 
			
		||||
    vfunc_scroll_event(scrollEvent) {
 | 
			
		||||
        switch (scrollEvent.direction) {
 | 
			
		||||
        case Clutter.ScrollDirection.UP:
 | 
			
		||||
        case Clutter.ScrollDirection.LEFT:
 | 
			
		||||
            this._onPrevMonthButtonClicked();
 | 
			
		||||
@@ -511,7 +515,7 @@ var Calendar = class Calendar {
 | 
			
		||||
        let now = new Date();
 | 
			
		||||
 | 
			
		||||
        // Remove everything but the topBox and the weekday labels
 | 
			
		||||
        let children = this.actor.get_children();
 | 
			
		||||
        let children = this.get_children();
 | 
			
		||||
        for (let i = this._firstDayIndex; i < children.length; i++)
 | 
			
		||||
            children[i].destroy();
 | 
			
		||||
 | 
			
		||||
@@ -548,7 +552,7 @@ var Calendar = class Calendar {
 | 
			
		||||
 | 
			
		||||
        beginDate.setTime(beginDate.getTime() - (weekPadding + daysToWeekStart) * MSECS_IN_DAY);
 | 
			
		||||
 | 
			
		||||
        let layout = this.actor.layout_manager;
 | 
			
		||||
        let layout = this.layout_manager;
 | 
			
		||||
        let iter = new Date(beginDate);
 | 
			
		||||
        let row = 2;
 | 
			
		||||
        // nRows here means 6 weeks + one header + one navbar
 | 
			
		||||
@@ -581,8 +585,9 @@ var Calendar = class Calendar {
 | 
			
		||||
            if (row == 2)
 | 
			
		||||
                styleClass = `calendar-day-top ${styleClass}`;
 | 
			
		||||
 | 
			
		||||
            let leftMost = rtl ? iter.getDay() == (this._weekStart + 6) % 7
 | 
			
		||||
                               : iter.getDay() == this._weekStart;
 | 
			
		||||
            let leftMost = rtl
 | 
			
		||||
                ? iter.getDay() == (this._weekStart + 6) % 7
 | 
			
		||||
                : iter.getDay() == this._weekStart;
 | 
			
		||||
            if (leftMost)
 | 
			
		||||
                styleClass = `calendar-day-left ${styleClass}`;
 | 
			
		||||
 | 
			
		||||
@@ -647,12 +652,12 @@ var Calendar = class Calendar {
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
Signals.addSignalMethods(Calendar.prototype);
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
var EventMessage = class EventMessage extends MessageList.Message {
 | 
			
		||||
    constructor(event, date) {
 | 
			
		||||
        super('', event.summary);
 | 
			
		||||
var EventMessage = GObject.registerClass(
 | 
			
		||||
class EventMessage extends MessageList.Message {
 | 
			
		||||
    _init(event, date) {
 | 
			
		||||
        super._init('', event.summary);
 | 
			
		||||
 | 
			
		||||
        this._event = event;
 | 
			
		||||
        this._date = date;
 | 
			
		||||
@@ -661,11 +666,12 @@ var EventMessage = class EventMessage extends MessageList.Message {
 | 
			
		||||
 | 
			
		||||
        this._icon = new St.Icon({ icon_name: 'x-office-calendar-symbolic' });
 | 
			
		||||
        this.setIcon(this._icon);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
        this.actor.connect('style-changed', () => {
 | 
			
		||||
            let iconVisible = this.actor.get_parent().has_style_pseudo_class('first-child');
 | 
			
		||||
            this._icon.opacity = (iconVisible ? 255 : 0);
 | 
			
		||||
        });
 | 
			
		||||
    vfunc_style_changed() {
 | 
			
		||||
        let iconVisible = this.get_parent().has_style_pseudo_class('first-child');
 | 
			
		||||
        this._icon.opacity = (iconVisible ? 255 : 0);
 | 
			
		||||
        super.vfunc_style_changed();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _formatEventTime() {
 | 
			
		||||
@@ -680,32 +686,33 @@ var EventMessage = class EventMessage extends MessageList.Message {
 | 
			
		||||
             */
 | 
			
		||||
            title = C_("event list time", "All Day");
 | 
			
		||||
        } else {
 | 
			
		||||
            let date = this._event.date >= periodBegin ? this._event.date
 | 
			
		||||
                                                       : this._event.end;
 | 
			
		||||
            let date = this._event.date >= periodBegin
 | 
			
		||||
                ? this._event.date
 | 
			
		||||
                : this._event.end;
 | 
			
		||||
            title = Util.formatTime(date, { timeOnly: true });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let rtl = Clutter.get_default_text_direction() == Clutter.TextDirection.RTL;
 | 
			
		||||
        if (this._event.date < periodBegin && !this._event.allDay) {
 | 
			
		||||
            if (rtl)
 | 
			
		||||
                title = title + ELLIPSIS_CHAR;
 | 
			
		||||
                title = `${title}${ELLIPSIS_CHAR}`;
 | 
			
		||||
            else
 | 
			
		||||
                title = ELLIPSIS_CHAR + title;
 | 
			
		||||
                title = `${ELLIPSIS_CHAR}${title}`;
 | 
			
		||||
        }
 | 
			
		||||
        if (this._event.end > periodEnd && !this._event.allDay) {
 | 
			
		||||
            if (rtl)
 | 
			
		||||
                title = ELLIPSIS_CHAR + title;
 | 
			
		||||
                title = `${ELLIPSIS_CHAR}${title}`;
 | 
			
		||||
            else
 | 
			
		||||
                title = title + ELLIPSIS_CHAR;
 | 
			
		||||
                title = `${title}${ELLIPSIS_CHAR}`;
 | 
			
		||||
        }
 | 
			
		||||
        return title;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
var NotificationMessage =
 | 
			
		||||
var NotificationMessage = GObject.registerClass(
 | 
			
		||||
class NotificationMessage extends MessageList.Message {
 | 
			
		||||
    constructor(notification) {
 | 
			
		||||
        super(notification.title, notification.bannerBodyText);
 | 
			
		||||
    _init(notification) {
 | 
			
		||||
        super._init(notification.title, notification.bannerBodyText);
 | 
			
		||||
        this.setUseBodyMarkup(notification.bannerBodyMarkup);
 | 
			
		||||
 | 
			
		||||
        this.notification = notification;
 | 
			
		||||
@@ -742,7 +749,7 @@ class NotificationMessage extends MessageList.Message {
 | 
			
		||||
        this.setUseBodyMarkup(n.bannerBodyMarkup);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _onClicked() {
 | 
			
		||||
    vfunc_clicked() {
 | 
			
		||||
        this.notification.activate();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -764,11 +771,12 @@ class NotificationMessage extends MessageList.Message {
 | 
			
		||||
    canClose() {
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
var EventsSection = class EventsSection extends MessageList.MessageListSection {
 | 
			
		||||
    constructor() {
 | 
			
		||||
        super();
 | 
			
		||||
var EventsSection = GObject.registerClass(
 | 
			
		||||
class EventsSection extends MessageList.MessageListSection {
 | 
			
		||||
    _init() {
 | 
			
		||||
        super._init();
 | 
			
		||||
 | 
			
		||||
        this._desktopSettings = new Gio.Settings({ schema_id: 'org.gnome.desktop.interface' });
 | 
			
		||||
        this._desktopSettings.connect('changed', this._reloadEvents.bind(this));
 | 
			
		||||
@@ -780,7 +788,7 @@ var EventsSection = class EventsSection extends MessageList.MessageListSection {
 | 
			
		||||
                                      label: '',
 | 
			
		||||
                                      x_align: St.Align.START,
 | 
			
		||||
                                      can_focus: true });
 | 
			
		||||
        this.actor.insert_child_below(this._title, null);
 | 
			
		||||
        this.insert_child_below(this._title, null);
 | 
			
		||||
 | 
			
		||||
        this._title.connect('clicked', this._onTitleClicked.bind(this));
 | 
			
		||||
        this._title.connect('key-focus-in', this._onKeyFocusIn.bind(this));
 | 
			
		||||
@@ -899,12 +907,29 @@ var EventsSection = class EventsSection extends MessageList.MessageListSection {
 | 
			
		||||
 | 
			
		||||
        super._sync();
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
var NotificationSection =
 | 
			
		||||
var TimeLabel = GObject.registerClass(
 | 
			
		||||
class NotificationTimeLabel extends St.Label {
 | 
			
		||||
    _init(datetime) {
 | 
			
		||||
        super._init({
 | 
			
		||||
            style_class: 'event-time',
 | 
			
		||||
            x_align: Clutter.ActorAlign.START,
 | 
			
		||||
            y_align: Clutter.ActorAlign.END
 | 
			
		||||
        });
 | 
			
		||||
        this._datetime = datetime;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    vfunc_map() {
 | 
			
		||||
        this.text = Util.formatTimeSpan(this._datetime);
 | 
			
		||||
        super.vfunc_map();
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
var NotificationSection = GObject.registerClass(
 | 
			
		||||
class NotificationSection extends MessageList.MessageListSection {
 | 
			
		||||
    constructor() {
 | 
			
		||||
        super();
 | 
			
		||||
    _init() {
 | 
			
		||||
        super._init();
 | 
			
		||||
 | 
			
		||||
        this._sources = new Map();
 | 
			
		||||
        this._nUrgent = 0;
 | 
			
		||||
@@ -913,8 +938,6 @@ class NotificationSection extends MessageList.MessageListSection {
 | 
			
		||||
        Main.messageTray.getSources().forEach(source => {
 | 
			
		||||
            this._sourceAdded(Main.messageTray, source);
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        this.actor.connect('notify::mapped', this._onMapped.bind(this));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    get allowed() {
 | 
			
		||||
@@ -922,17 +945,6 @@ class NotificationSection extends MessageList.MessageListSection {
 | 
			
		||||
               !Main.sessionMode.isGreeter;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _createTimeLabel(datetime) {
 | 
			
		||||
        let label = new St.Label({ style_class: 'event-time',
 | 
			
		||||
                                   x_align: Clutter.ActorAlign.START,
 | 
			
		||||
                                   y_align: Clutter.ActorAlign.END });
 | 
			
		||||
        label.connect('notify::mapped', () => {
 | 
			
		||||
            if (label.mapped)
 | 
			
		||||
                label.text = Util.formatTimeSpan(datetime);
 | 
			
		||||
        });
 | 
			
		||||
        return label;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _sourceAdded(tray, source) {
 | 
			
		||||
        let obj = {
 | 
			
		||||
            destroyId: 0,
 | 
			
		||||
@@ -950,13 +962,13 @@ class NotificationSection extends MessageList.MessageListSection {
 | 
			
		||||
 | 
			
		||||
    _onNotificationAdded(source, notification) {
 | 
			
		||||
        let message = new NotificationMessage(notification);
 | 
			
		||||
        message.setSecondaryActor(this._createTimeLabel(notification.datetime));
 | 
			
		||||
        message.setSecondaryActor(new TimeLabel(notification.datetime));
 | 
			
		||||
 | 
			
		||||
        let isUrgent = notification.urgency == MessageTray.Urgency.CRITICAL;
 | 
			
		||||
 | 
			
		||||
        let updatedId = notification.connect('updated', () => {
 | 
			
		||||
            message.setSecondaryActor(this._createTimeLabel(notification.datetime));
 | 
			
		||||
            this.moveMessage(message, isUrgent ? 0 : this._nUrgent, this.actor.mapped);
 | 
			
		||||
            message.setSecondaryActor(new TimeLabel(notification.datetime));
 | 
			
		||||
            this.moveMessage(message, isUrgent ? 0 : this._nUrgent, this.mapped);
 | 
			
		||||
        });
 | 
			
		||||
        let destroyId = notification.connect('destroy', () => {
 | 
			
		||||
            notification.disconnect(destroyId);
 | 
			
		||||
@@ -976,7 +988,7 @@ class NotificationSection extends MessageList.MessageListSection {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let index = isUrgent ? 0 : this._nUrgent;
 | 
			
		||||
        this.addMessageAtIndex(message, index, this.actor.mapped);
 | 
			
		||||
        this.addMessageAtIndex(message, index, this.mapped);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _onSourceDestroy(source, obj) {
 | 
			
		||||
@@ -986,25 +998,23 @@ class NotificationSection extends MessageList.MessageListSection {
 | 
			
		||||
        this._sources.delete(source);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _onMapped() {
 | 
			
		||||
        if (!this.actor.mapped)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        for (let message of this._messages.keys())
 | 
			
		||||
    vfunc_map() {
 | 
			
		||||
        this._messages.forEach(message => {
 | 
			
		||||
            if (message.notification.urgency != MessageTray.Urgency.CRITICAL)
 | 
			
		||||
                message.notification.acknowledged = true;
 | 
			
		||||
        });
 | 
			
		||||
        super.vfunc_map();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _shouldShow() {
 | 
			
		||||
        return !this.empty && isToday(this._date);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
var Placeholder = class Placeholder {
 | 
			
		||||
    constructor() {
 | 
			
		||||
        this.actor = new St.BoxLayout({ style_class: 'message-list-placeholder',
 | 
			
		||||
                                        vertical: true });
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
var Placeholder = GObject.registerClass(
 | 
			
		||||
class Placeholder extends St.BoxLayout {
 | 
			
		||||
    _init() {
 | 
			
		||||
        super._init({ style_class: 'message-list-placeholder', vertical: true });
 | 
			
		||||
        this._date = new Date();
 | 
			
		||||
 | 
			
		||||
        let todayFile = Gio.File.new_for_uri('resource:///org/gnome/shell/theme/no-notifications.svg');
 | 
			
		||||
@@ -1013,10 +1023,10 @@ var Placeholder = class Placeholder {
 | 
			
		||||
        this._otherIcon = new Gio.FileIcon({ file: otherFile });
 | 
			
		||||
 | 
			
		||||
        this._icon = new St.Icon();
 | 
			
		||||
        this.actor.add_actor(this._icon);
 | 
			
		||||
        this.add_actor(this._icon);
 | 
			
		||||
 | 
			
		||||
        this._label = new St.Label();
 | 
			
		||||
        this.actor.add_actor(this._label);
 | 
			
		||||
        this.add_actor(this._label);
 | 
			
		||||
 | 
			
		||||
        this._sync();
 | 
			
		||||
    }
 | 
			
		||||
@@ -1043,20 +1053,24 @@ var Placeholder = class Placeholder {
 | 
			
		||||
            this._label.text = _("No Events");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
var CalendarMessageList = class CalendarMessageList {
 | 
			
		||||
    constructor() {
 | 
			
		||||
        this.actor = new St.Widget({ style_class: 'message-list',
 | 
			
		||||
                                     layout_manager: new Clutter.BinLayout(),
 | 
			
		||||
                                     x_expand: true, y_expand: true });
 | 
			
		||||
var CalendarMessageList = GObject.registerClass(
 | 
			
		||||
class CalendarMessageList extends St.Widget {
 | 
			
		||||
    _init() {
 | 
			
		||||
        super._init({
 | 
			
		||||
            style_class: 'message-list',
 | 
			
		||||
            layout_manager: new Clutter.BinLayout(),
 | 
			
		||||
            x_expand: true,
 | 
			
		||||
            y_expand: true
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        this._placeholder = new Placeholder();
 | 
			
		||||
        this.actor.add_actor(this._placeholder.actor);
 | 
			
		||||
        this.add_actor(this._placeholder);
 | 
			
		||||
 | 
			
		||||
        let box = new St.BoxLayout({ vertical: true,
 | 
			
		||||
                                     x_expand: true, y_expand: true });
 | 
			
		||||
        this.actor.add_actor(box);
 | 
			
		||||
        this.add_actor(box);
 | 
			
		||||
 | 
			
		||||
        this._scrollView = new St.ScrollView({ style_class: 'vfade',
 | 
			
		||||
                                               overlay_scrollbars: true,
 | 
			
		||||
@@ -1070,17 +1084,21 @@ var CalendarMessageList = class CalendarMessageList {
 | 
			
		||||
                                            can_focus: true });
 | 
			
		||||
        this._clearButton.set_x_align(Clutter.ActorAlign.END);
 | 
			
		||||
        this._clearButton.connect('clicked', () => {
 | 
			
		||||
            let sections = [...this._sections.keys()];
 | 
			
		||||
            sections.forEach((s) => s.clear());
 | 
			
		||||
            this._sectionList.get_children().forEach(s => s.clear());
 | 
			
		||||
        });
 | 
			
		||||
        box.add_actor(this._clearButton);
 | 
			
		||||
 | 
			
		||||
        this._placeholder.bind_property('visible',
 | 
			
		||||
            this._clearButton, 'visible',
 | 
			
		||||
            GObject.BindingFlags.INVERT_BOOLEAN);
 | 
			
		||||
 | 
			
		||||
        this._sectionList = new St.BoxLayout({ style_class: 'message-list-sections',
 | 
			
		||||
                                               vertical: true,
 | 
			
		||||
                                               y_expand: true,
 | 
			
		||||
                                               y_align: Clutter.ActorAlign.START });
 | 
			
		||||
        this._sectionList.connect('actor-added', this._sync.bind(this));
 | 
			
		||||
        this._sectionList.connect('actor-removed', this._sync.bind(this));
 | 
			
		||||
        this._scrollView.add_actor(this._sectionList);
 | 
			
		||||
        this._sections = new Map();
 | 
			
		||||
 | 
			
		||||
        this._mediaSection = new Mpris.MediaSection();
 | 
			
		||||
        this._addSection(this._mediaSection);
 | 
			
		||||
@@ -1095,59 +1113,35 @@ var CalendarMessageList = class CalendarMessageList {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _addSection(section) {
 | 
			
		||||
        let obj = {
 | 
			
		||||
            destroyId: 0,
 | 
			
		||||
            visibleId: 0,
 | 
			
		||||
            emptyChangedId: 0,
 | 
			
		||||
            canClearChangedId: 0,
 | 
			
		||||
            keyFocusId: 0
 | 
			
		||||
        };
 | 
			
		||||
        obj.destroyId = section.actor.connect('destroy', () => {
 | 
			
		||||
            this._removeSection(section);
 | 
			
		||||
        });
 | 
			
		||||
        obj.visibleId = section.actor.connect('notify::visible',
 | 
			
		||||
                                              this._sync.bind(this));
 | 
			
		||||
        obj.emptyChangedId = section.connect('empty-changed',
 | 
			
		||||
                                             this._sync.bind(this));
 | 
			
		||||
        obj.canClearChangedId = section.connect('can-clear-changed',
 | 
			
		||||
                                                this._sync.bind(this));
 | 
			
		||||
        obj.keyFocusId = section.connect('key-focus-in',
 | 
			
		||||
                                         this._onKeyFocusIn.bind(this));
 | 
			
		||||
        let connectionsIds = [];
 | 
			
		||||
 | 
			
		||||
        this._sections.set(section, obj);
 | 
			
		||||
        this._sectionList.add_actor(section.actor);
 | 
			
		||||
        this._sync();
 | 
			
		||||
    }
 | 
			
		||||
        for (let prop of ['visible', 'empty', 'can-clear']) {
 | 
			
		||||
            connectionsIds.push(
 | 
			
		||||
                section.connect(`notify::${prop}`, this._sync.bind(this)));
 | 
			
		||||
        }
 | 
			
		||||
        connectionsIds.push(section.connect('message-focused', (_s, messageActor) => {
 | 
			
		||||
            Util.ensureActorVisibleInScrollView(this._scrollView, messageActor);
 | 
			
		||||
        }));
 | 
			
		||||
 | 
			
		||||
    _removeSection(section) {
 | 
			
		||||
        let obj = this._sections.get(section);
 | 
			
		||||
        section.actor.disconnect(obj.destroyId);
 | 
			
		||||
        section.actor.disconnect(obj.visibleId);
 | 
			
		||||
        section.disconnect(obj.emptyChangedId);
 | 
			
		||||
        section.disconnect(obj.canClearChangedId);
 | 
			
		||||
        section.disconnect(obj.keyFocusId);
 | 
			
		||||
        connectionsIds.push(section.connect('destroy', (section) => {
 | 
			
		||||
            connectionsIds.forEach(id => section.disconnect(id));
 | 
			
		||||
            this._sectionList.remove_actor(section);
 | 
			
		||||
        }));
 | 
			
		||||
 | 
			
		||||
        this._sections.delete(section);
 | 
			
		||||
        this._sectionList.remove_actor(section.actor);
 | 
			
		||||
        this._sync();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _onKeyFocusIn(section, actor) {
 | 
			
		||||
        Util.ensureActorVisibleInScrollView(this._scrollView, actor);
 | 
			
		||||
        this._sectionList.add_actor(section);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _sync() {
 | 
			
		||||
        let sections = [...this._sections.keys()];
 | 
			
		||||
        let sections = this._sectionList.get_children();
 | 
			
		||||
        let visible = sections.some(s => s.allowed);
 | 
			
		||||
        this.actor.visible = visible;
 | 
			
		||||
        this.visible = visible;
 | 
			
		||||
        if (!visible)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        let empty = sections.every(s => s.empty || !s.actor.visible);
 | 
			
		||||
        this._placeholder.actor.visible = empty;
 | 
			
		||||
        this._clearButton.visible = !empty;
 | 
			
		||||
        let empty = sections.every(s => s.empty || !s.visible);
 | 
			
		||||
        this._placeholder.visible = empty;
 | 
			
		||||
 | 
			
		||||
        let canClear = sections.some(s => s.canClear && s.actor.visible);
 | 
			
		||||
        let canClear = sections.some(s => s.canClear && s.visible);
 | 
			
		||||
        this._clearButton.reactive = canClear;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -1156,8 +1150,7 @@ var CalendarMessageList = class CalendarMessageList {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    setDate(date) {
 | 
			
		||||
        for (let section of this._sections.keys())
 | 
			
		||||
            section.setDate(date);
 | 
			
		||||
        this._sectionList.get_children().forEach(s => s.setDate(date));
 | 
			
		||||
        this._placeholder.setDate(date);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -1,16 +1,19 @@
 | 
			
		||||
/* exported CheckBox */
 | 
			
		||||
const { Clutter, Pango, St } = imports.gi;
 | 
			
		||||
const { Clutter, GObject, Pango, St } = imports.gi;
 | 
			
		||||
 | 
			
		||||
var CheckBox = class CheckBox {
 | 
			
		||||
    constructor(label) {
 | 
			
		||||
var CheckBox = GObject.registerClass(
 | 
			
		||||
class CheckBox extends St.Button {
 | 
			
		||||
    _init(label) {
 | 
			
		||||
        let container = new St.BoxLayout();
 | 
			
		||||
        this.actor = new St.Button({ style_class: 'check-box',
 | 
			
		||||
                                     child: container,
 | 
			
		||||
                                     button_mask: St.ButtonMask.ONE,
 | 
			
		||||
                                     toggle_mode: true,
 | 
			
		||||
                                     can_focus: true,
 | 
			
		||||
                                     x_fill: true,
 | 
			
		||||
                                     y_fill: true });
 | 
			
		||||
        super._init({
 | 
			
		||||
            style_class: 'check-box',
 | 
			
		||||
            child: container,
 | 
			
		||||
            button_mask: St.ButtonMask.ONE,
 | 
			
		||||
            toggle_mode: true,
 | 
			
		||||
            can_focus: true,
 | 
			
		||||
            x_fill: true,
 | 
			
		||||
            y_fill: true
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        this._box = new St.Bin();
 | 
			
		||||
        this._box.set_y_align(Clutter.ActorAlign.START);
 | 
			
		||||
@@ -32,4 +35,4 @@ var CheckBox = class CheckBox {
 | 
			
		||||
    getLabelActor() {
 | 
			
		||||
        return this._label;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -2,7 +2,6 @@
 | 
			
		||||
/* exported Component */
 | 
			
		||||
 | 
			
		||||
const { Gio, GLib } = imports.gi;
 | 
			
		||||
const Mainloop = imports.mainloop;
 | 
			
		||||
const Params = imports.misc.params;
 | 
			
		||||
 | 
			
		||||
const GnomeSession = imports.misc.gnomeSession;
 | 
			
		||||
@@ -39,7 +38,7 @@ var AutomountManager = class {
 | 
			
		||||
        this._driveDisconnectedId = this._volumeMonitor.connect('drive-disconnected', this._onDriveDisconnected.bind(this));
 | 
			
		||||
        this._driveEjectButtonId = this._volumeMonitor.connect('drive-eject-button', this._onDriveEjectButton.bind(this));
 | 
			
		||||
 | 
			
		||||
        this._mountAllId = Mainloop.idle_add(this._startupMountAll.bind(this));
 | 
			
		||||
        this._mountAllId = GLib.idle_add(GLib.PRIORITY_DEFAULT, this._startupMountAll.bind(this));
 | 
			
		||||
        GLib.Source.set_name_by_id(this._mountAllId, '[gnome-shell] this._startupMountAll');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -51,7 +50,7 @@ var AutomountManager = class {
 | 
			
		||||
        this._volumeMonitor.disconnect(this._driveEjectButtonId);
 | 
			
		||||
 | 
			
		||||
        if (this._mountAllId > 0) {
 | 
			
		||||
            Mainloop.source_remove(this._mountAllId);
 | 
			
		||||
            GLib.source_remove(this._mountAllId);
 | 
			
		||||
            this._mountAllId = 0;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
@@ -157,7 +156,7 @@ var AutomountManager = class {
 | 
			
		||||
            !volume.should_automount() ||
 | 
			
		||||
            !volume.can_mount()) {
 | 
			
		||||
            // allow the autorun to run anyway; this can happen if the
 | 
			
		||||
            // mount gets added programmatically later, even if 
 | 
			
		||||
            // mount gets added programmatically later, even if
 | 
			
		||||
            // should_automount() or can_mount() are false, like for
 | 
			
		||||
            // blank optical media.
 | 
			
		||||
            this._allowAutorun(volume);
 | 
			
		||||
@@ -220,17 +219,17 @@ var AutomountManager = class {
 | 
			
		||||
 | 
			
		||||
    _onVolumeRemoved(monitor, volume) {
 | 
			
		||||
        if (volume._allowAutorunExpireId && volume._allowAutorunExpireId > 0) {
 | 
			
		||||
            Mainloop.source_remove(volume._allowAutorunExpireId);
 | 
			
		||||
            GLib.source_remove(volume._allowAutorunExpireId);
 | 
			
		||||
            delete volume._allowAutorunExpireId;
 | 
			
		||||
        }
 | 
			
		||||
        this._volumeQueue = 
 | 
			
		||||
        this._volumeQueue =
 | 
			
		||||
            this._volumeQueue.filter(element => (element != volume));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _reaskPassword(volume) {
 | 
			
		||||
        let prevOperation = this._activeOperations.get(volume);
 | 
			
		||||
        let existingDialog = prevOperation ? prevOperation.borrowDialog() : null;
 | 
			
		||||
        let operation = 
 | 
			
		||||
        let operation =
 | 
			
		||||
            new ShellMountOperation.ShellMountOperation(volume,
 | 
			
		||||
                                                        { existingDialog: existingDialog });
 | 
			
		||||
        this._mountVolume(volume, operation);
 | 
			
		||||
@@ -249,7 +248,7 @@ var AutomountManager = class {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _allowAutorunExpire(volume) {
 | 
			
		||||
        let id = Mainloop.timeout_add_seconds(AUTORUN_EXPIRE_TIMEOUT_SECS, () => {
 | 
			
		||||
        let id = GLib.timeout_add_seconds(GLib.PRIORITY_DEFAULT, AUTORUN_EXPIRE_TIMEOUT_SECS, () => {
 | 
			
		||||
            volume.allowAutorun = false;
 | 
			
		||||
            delete volume._allowAutorunExpireId;
 | 
			
		||||
            return GLib.SOURCE_REMOVE;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,7 @@
 | 
			
		||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
 | 
			
		||||
/* exported Component */
 | 
			
		||||
 | 
			
		||||
const { Gio, St } = imports.gi;
 | 
			
		||||
const { Gio, GObject, St } = imports.gi;
 | 
			
		||||
 | 
			
		||||
const GnomeSession = imports.misc.gnomeSession;
 | 
			
		||||
const Main = imports.ui.main;
 | 
			
		||||
@@ -63,7 +63,7 @@ function startAppForMount(app, mount) {
 | 
			
		||||
    files.push(root);
 | 
			
		||||
 | 
			
		||||
    try {
 | 
			
		||||
        retval = app.launch(files, 
 | 
			
		||||
        retval = app.launch(files,
 | 
			
		||||
                            global.create_app_launch_context(0, -1));
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
        log(`Unable to launch the application ${app.get_name()}: ${e}`);
 | 
			
		||||
@@ -72,8 +72,6 @@ function startAppForMount(app, mount) {
 | 
			
		||||
    return retval;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/******************************************/
 | 
			
		||||
 | 
			
		||||
const HotplugSnifferIface = loadInterfaceXML('org.gnome.Shell.HotplugSniffer');
 | 
			
		||||
const HotplugSnifferProxy = Gio.DBusProxy.makeProxyWrapper(HotplugSnifferIface);
 | 
			
		||||
function HotplugSniffer() {
 | 
			
		||||
@@ -117,9 +115,9 @@ var ContentTypeDiscoverer = class {
 | 
			
		||||
 | 
			
		||||
            let hotplugSniffer = new HotplugSniffer();
 | 
			
		||||
            hotplugSniffer.SniffURIRemote(root.get_uri(),
 | 
			
		||||
                 ([contentTypes]) => {
 | 
			
		||||
                     this._emitCallback(mount, contentTypes);
 | 
			
		||||
                 });
 | 
			
		||||
                ([contentTypes]) => {
 | 
			
		||||
                    this._emitCallback(mount, contentTypes);
 | 
			
		||||
                });
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -215,11 +213,11 @@ var AutorunDispatcher = class {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _addSource(mount, apps) {
 | 
			
		||||
        // if we already have a source showing for this 
 | 
			
		||||
        // if we already have a source showing for this
 | 
			
		||||
        // mount, return
 | 
			
		||||
        if (this._getSourceForMount(mount))
 | 
			
		||||
            return;
 | 
			
		||||
     
 | 
			
		||||
 | 
			
		||||
        // add a new source
 | 
			
		||||
        this._sources.push(new AutorunSource(this._manager, mount, apps));
 | 
			
		||||
    }
 | 
			
		||||
@@ -264,7 +262,7 @@ var AutorunDispatcher = class {
 | 
			
		||||
 | 
			
		||||
    removeMount(mount) {
 | 
			
		||||
        let source = this._getSourceForMount(mount);
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
        // if we aren't tracking this mount, don't do anything
 | 
			
		||||
        if (!source)
 | 
			
		||||
            return;
 | 
			
		||||
@@ -274,9 +272,10 @@ var AutorunDispatcher = class {
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
var AutorunSource = class extends MessageTray.Source {
 | 
			
		||||
    constructor(manager, mount, apps) {
 | 
			
		||||
        super(mount.get_name());
 | 
			
		||||
var AutorunSource = GObject.registerClass(
 | 
			
		||||
class AutorunSource extends MessageTray.Source {
 | 
			
		||||
    _init(manager, mount, apps) {
 | 
			
		||||
        super._init(mount.get_name());
 | 
			
		||||
 | 
			
		||||
        this._manager = manager;
 | 
			
		||||
        this.mount = mount;
 | 
			
		||||
@@ -286,7 +285,7 @@ var AutorunSource = class extends MessageTray.Source {
 | 
			
		||||
 | 
			
		||||
        // add ourselves as a source, and popup the notification
 | 
			
		||||
        Main.messageTray.add(this);
 | 
			
		||||
        this.notify(this._notification);
 | 
			
		||||
        this.showNotification(this._notification);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    getIcon() {
 | 
			
		||||
@@ -296,11 +295,12 @@ var AutorunSource = class extends MessageTray.Source {
 | 
			
		||||
    _createPolicy() {
 | 
			
		||||
        return new MessageTray.NotificationApplicationPolicy('org.gnome.Nautilus');
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
var AutorunNotification = class extends MessageTray.Notification {
 | 
			
		||||
    constructor(manager, source) {
 | 
			
		||||
        super(source, source.title);
 | 
			
		||||
var AutorunNotification = GObject.registerClass(
 | 
			
		||||
class AutorunNotification extends MessageTray.Notification {
 | 
			
		||||
    _init(manager, source) {
 | 
			
		||||
        super._init(source, source.title);
 | 
			
		||||
 | 
			
		||||
        this._manager = manager;
 | 
			
		||||
        this._mount = source.mount;
 | 
			
		||||
@@ -325,10 +325,10 @@ var AutorunNotification = class extends MessageTray.Notification {
 | 
			
		||||
                                 style_class: 'hotplug-notification-item-icon' });
 | 
			
		||||
        box.add(icon);
 | 
			
		||||
 | 
			
		||||
        let label = new St.Bin({ y_align: St.Align.MIDDLE,
 | 
			
		||||
                                 child: new St.Label
 | 
			
		||||
                                 ({ text: _("Open with %s").format(app.get_name()) })
 | 
			
		||||
                               });
 | 
			
		||||
        let label = new St.Bin({
 | 
			
		||||
            y_align: St.Align.MIDDLE,
 | 
			
		||||
            child: new St.Label({ text: _("Open with %s").format(app.get_name()) }),
 | 
			
		||||
        });
 | 
			
		||||
        box.add(label);
 | 
			
		||||
 | 
			
		||||
        let button = new St.Button({ child: box,
 | 
			
		||||
@@ -352,6 +352,6 @@ var AutorunNotification = class extends MessageTray.Notification {
 | 
			
		||||
        let app = Gio.app_info_get_default_for_type('inode/directory', false);
 | 
			
		||||
        startAppForMount(app, this._mount);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
var Component = AutorunManager;
 | 
			
		||||
 
 | 
			
		||||
@@ -77,13 +77,13 @@ class KeyringDialog extends ModalDialog.ModalDialog {
 | 
			
		||||
            this._workSpinner = new Animation.Spinner(WORK_SPINNER_ICON_SIZE, true);
 | 
			
		||||
 | 
			
		||||
            if (rtl) {
 | 
			
		||||
                layout.attach(this._workSpinner.actor, 0, row, 1, 1);
 | 
			
		||||
                layout.attach(this._workSpinner, 0, row, 1, 1);
 | 
			
		||||
                layout.attach(this._passwordEntry, 1, row, 1, 1);
 | 
			
		||||
                layout.attach(label, 2, row, 1, 1);
 | 
			
		||||
            } else {
 | 
			
		||||
                layout.attach(label, 0, row, 1, 1);
 | 
			
		||||
                layout.attach(this._passwordEntry, 1, row, 1, 1);
 | 
			
		||||
                layout.attach(this._workSpinner.actor, 2, row, 1, 1);
 | 
			
		||||
                layout.attach(this._workSpinner, 2, row, 1, 1);
 | 
			
		||||
            }
 | 
			
		||||
            row++;
 | 
			
		||||
        } else {
 | 
			
		||||
@@ -121,8 +121,8 @@ class KeyringDialog extends ModalDialog.ModalDialog {
 | 
			
		||||
        if (this.prompt.choice_visible) {
 | 
			
		||||
            let choice = new CheckBox.CheckBox();
 | 
			
		||||
            this.prompt.bind_property('choice-label', choice.getLabelActor(), 'text', GObject.BindingFlags.SYNC_CREATE);
 | 
			
		||||
            this.prompt.bind_property('choice-chosen', choice.actor, 'checked', GObject.BindingFlags.SYNC_CREATE | GObject.BindingFlags.BIDIRECTIONAL);
 | 
			
		||||
            layout.attach(choice.actor, rtl ? 0 : 1, row, 1, 1);
 | 
			
		||||
            this.prompt.bind_property('choice-chosen', choice, 'checked', GObject.BindingFlags.SYNC_CREATE | GObject.BindingFlags.BIDIRECTIONAL);
 | 
			
		||||
            layout.attach(choice, rtl ? 0 : 1, row, 1, 1);
 | 
			
		||||
            row++;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@@ -232,8 +232,9 @@ var KeyringPrompter = class {
 | 
			
		||||
    constructor() {
 | 
			
		||||
        this._prompter = new Gcr.SystemPrompter();
 | 
			
		||||
        this._prompter.connect('new-prompt', () => {
 | 
			
		||||
            let dialog = this._enabled ? new KeyringDialog()
 | 
			
		||||
                                       : new KeyringDummyDialog();
 | 
			
		||||
            let dialog = this._enabled
 | 
			
		||||
                ? new KeyringDialog()
 | 
			
		||||
                : new KeyringDummyDialog();
 | 
			
		||||
            this._currentPrompt = dialog.prompt;
 | 
			
		||||
            return this._currentPrompt;
 | 
			
		||||
        });
 | 
			
		||||
 
 | 
			
		||||
@@ -112,16 +112,17 @@ class NetworkSecretDialog extends ModalDialog.ModalDialog {
 | 
			
		||||
                                        expand: true });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this._okButton = { label: _("Connect"),
 | 
			
		||||
                           action: this._onOk.bind(this),
 | 
			
		||||
                           default: true
 | 
			
		||||
                         };
 | 
			
		||||
        this._okButton = {
 | 
			
		||||
            label: _("Connect"),
 | 
			
		||||
            action: this._onOk.bind(this),
 | 
			
		||||
            default: true,
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        this.setButtons([{ label: _("Cancel"),
 | 
			
		||||
                           action: this.cancel.bind(this),
 | 
			
		||||
                           key: Clutter.KEY_Escape,
 | 
			
		||||
                         },
 | 
			
		||||
                         this._okButton]);
 | 
			
		||||
        this.setButtons([{
 | 
			
		||||
            label: _("Cancel"),
 | 
			
		||||
            action: this.cancel.bind(this),
 | 
			
		||||
            key: Clutter.KEY_Escape,
 | 
			
		||||
        }, this._okButton]);
 | 
			
		||||
 | 
			
		||||
        this._updateOkButton();
 | 
			
		||||
    }
 | 
			
		||||
@@ -163,9 +164,9 @@ class NetworkSecretDialog extends ModalDialog.ModalDialog {
 | 
			
		||||
        if (value.length == 64) {
 | 
			
		||||
            // must be composed of hexadecimal digits only
 | 
			
		||||
            for (let i = 0; i < 64; i++) {
 | 
			
		||||
                if (!((value[i] >= 'a' && value[i] <= 'f')
 | 
			
		||||
                      || (value[i] >= 'A' && value[i] <= 'F')
 | 
			
		||||
                      || (value[i] >= '0' && value[i] <= '9')))
 | 
			
		||||
                if (!((value[i] >= 'a' && value[i] <= 'f') ||
 | 
			
		||||
                      (value[i] >= 'A' && value[i] <= 'F') ||
 | 
			
		||||
                      (value[i] >= '0' && value[i] <= '9')))
 | 
			
		||||
                    return false;
 | 
			
		||||
            }
 | 
			
		||||
            return true;
 | 
			
		||||
@@ -179,15 +180,15 @@ class NetworkSecretDialog extends ModalDialog.ModalDialog {
 | 
			
		||||
        if (secret.wep_key_type == NM.WepKeyType.KEY) {
 | 
			
		||||
            if (value.length == 10 || value.length == 26) {
 | 
			
		||||
                for (let i = 0; i < value.length; i++) {
 | 
			
		||||
                    if (!((value[i] >= 'a' && value[i] <= 'f')
 | 
			
		||||
                          || (value[i] >= 'A' && value[i] <= 'F')
 | 
			
		||||
                          || (value[i] >= '0' && value[i] <= '9')))
 | 
			
		||||
                    if (!((value[i] >= 'a' && value[i] <= 'f') ||
 | 
			
		||||
                          (value[i] >= 'A' && value[i] <= 'F') ||
 | 
			
		||||
                          (value[i] >= '0' && value[i] <= '9')))
 | 
			
		||||
                        return false;
 | 
			
		||||
                }
 | 
			
		||||
            } else if (value.length == 5 || value.length == 13) {
 | 
			
		||||
                for (let i = 0; i < value.length; i++) {
 | 
			
		||||
                    if (!((value[i] >= 'a' && value[i] <= 'z')
 | 
			
		||||
                          || (value[i] >= 'A' && value[i] <= 'Z')))
 | 
			
		||||
                    if (!((value[i] >= 'a' && value[i] <= 'z') ||
 | 
			
		||||
                          (value[i] >= 'A' && value[i] <= 'Z')))
 | 
			
		||||
                        return false;
 | 
			
		||||
                }
 | 
			
		||||
            } else {
 | 
			
		||||
@@ -212,6 +213,7 @@ class NetworkSecretDialog extends ModalDialog.ModalDialog {
 | 
			
		||||
        // First the easy ones
 | 
			
		||||
        case 'wpa-none':
 | 
			
		||||
        case 'wpa-psk':
 | 
			
		||||
        case 'sae':
 | 
			
		||||
            secrets.push({ label: _("Password: "), key: 'psk',
 | 
			
		||||
                           value: wirelessSecuritySetting.psk || '',
 | 
			
		||||
                           validate: this._validateWpaPsk, password: true });
 | 
			
		||||
@@ -551,11 +553,12 @@ var VPNRequestHandler = class {
 | 
			
		||||
                let shouldAsk = keyfile.get_boolean(groups[i], 'ShouldAsk');
 | 
			
		||||
 | 
			
		||||
                if (shouldAsk) {
 | 
			
		||||
                    contentOverride.secrets.push({ label: keyfile.get_string(groups[i], 'Label'),
 | 
			
		||||
                                                   key: groups[i],
 | 
			
		||||
                                                   value: value,
 | 
			
		||||
                                                   password: keyfile.get_boolean(groups[i], 'IsSecret')
 | 
			
		||||
                                                 });
 | 
			
		||||
                    contentOverride.secrets.push({
 | 
			
		||||
                        label: keyfile.get_string(groups[i], 'Label'),
 | 
			
		||||
                        key: groups[i],
 | 
			
		||||
                        value: value,
 | 
			
		||||
                        password: keyfile.get_boolean(groups[i], 'IsSecret'),
 | 
			
		||||
                    });
 | 
			
		||||
                } else {
 | 
			
		||||
                    if (!value.length) // Ignore empty secrets
 | 
			
		||||
                        continue;
 | 
			
		||||
@@ -609,10 +612,11 @@ Signals.addSignalMethods(VPNRequestHandler.prototype);
 | 
			
		||||
 | 
			
		||||
var NetworkAgent = class {
 | 
			
		||||
    constructor() {
 | 
			
		||||
        this._native = new Shell.NetworkAgent({ identifier: 'org.gnome.Shell.NetworkAgent',
 | 
			
		||||
                                                capabilities: NM.SecretAgentCapabilities.VPN_HINTS,
 | 
			
		||||
                                                auto_register: false
 | 
			
		||||
                                              });
 | 
			
		||||
        this._native = new Shell.NetworkAgent({
 | 
			
		||||
            identifier: 'org.gnome.Shell.NetworkAgent',
 | 
			
		||||
            capabilities: NM.SecretAgentCapabilities.VPN_HINTS,
 | 
			
		||||
            auto_register: false,
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        this._dialogs = { };
 | 
			
		||||
        this._vpnRequests = { };
 | 
			
		||||
@@ -621,7 +625,7 @@ var NetworkAgent = class {
 | 
			
		||||
        this._pluginDir = Gio.file_new_for_path(Config.VPNDIR);
 | 
			
		||||
        try {
 | 
			
		||||
            let monitor = this._pluginDir.monitor(Gio.FileMonitorFlags.NONE, null);
 | 
			
		||||
            monitor.connect('changed', () => this._vpnCacheBuilt = false);
 | 
			
		||||
            monitor.connect('changed', () => (this._vpnCacheBuilt = false));
 | 
			
		||||
        } catch (e) {
 | 
			
		||||
            log(`Failed to create monitor for VPN plugin dir: ${e.message}`);
 | 
			
		||||
        }
 | 
			
		||||
@@ -730,7 +734,7 @@ var NetworkAgent = class {
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        Main.messageTray.add(source);
 | 
			
		||||
        source.notify(notification);
 | 
			
		||||
        source.showNotification(notification);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _newRequest(agent, requestId, connection, settingName, hints, flags) {
 | 
			
		||||
 
 | 
			
		||||
@@ -76,8 +76,8 @@ var AuthenticationDialog = GObject.registerClass({
 | 
			
		||||
            this._userAvatar = new UserWidget.Avatar(this._user,
 | 
			
		||||
                                                     { iconSize: DIALOG_ICON_SIZE,
 | 
			
		||||
                                                       styleClass: 'polkit-dialog-user-icon' });
 | 
			
		||||
            this._userAvatar.actor.hide();
 | 
			
		||||
            userBox.add(this._userAvatar.actor,
 | 
			
		||||
            this._userAvatar.hide();
 | 
			
		||||
            userBox.add(this._userAvatar,
 | 
			
		||||
                        { x_fill: true,
 | 
			
		||||
                          y_fill: false,
 | 
			
		||||
                          x_align: St.Align.END,
 | 
			
		||||
@@ -106,7 +106,7 @@ var AuthenticationDialog = GObject.registerClass({
 | 
			
		||||
                              { expand: true });
 | 
			
		||||
 | 
			
		||||
        this._workSpinner = new Animation.Spinner(WORK_SPINNER_ICON_SIZE, true);
 | 
			
		||||
        this._passwordBox.add(this._workSpinner.actor);
 | 
			
		||||
        this._passwordBox.add(this._workSpinner);
 | 
			
		||||
 | 
			
		||||
        this.setInitialKeyFocus(this._passwordEntry);
 | 
			
		||||
        this._passwordBox.hide();
 | 
			
		||||
@@ -305,7 +305,7 @@ var AuthenticationDialog = GObject.registerClass({
 | 
			
		||||
    _onUserChanged() {
 | 
			
		||||
        if (this._user.is_loaded && this._userAvatar) {
 | 
			
		||||
            this._userAvatar.update();
 | 
			
		||||
            this._userAvatar.actor.show();
 | 
			
		||||
            this._userAvatar.show();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -3,7 +3,6 @@
 | 
			
		||||
 | 
			
		||||
const { Clutter, Gio, GLib, GObject, St } = imports.gi;
 | 
			
		||||
const Lang = imports.lang;
 | 
			
		||||
const Mainloop = imports.mainloop;
 | 
			
		||||
 | 
			
		||||
var Tpl = null;
 | 
			
		||||
var Tp = null;
 | 
			
		||||
@@ -216,7 +215,7 @@ class TelepathyClient extends Tp.BaseClient {
 | 
			
		||||
                // We are already handling the channel, display the source
 | 
			
		||||
                let source = this._chatSources[channel.get_object_path()];
 | 
			
		||||
                if (source)
 | 
			
		||||
                    source.notify();
 | 
			
		||||
                    source.showNotification();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
@@ -267,9 +266,10 @@ class TelepathyClient extends Tp.BaseClient {
 | 
			
		||||
    }
 | 
			
		||||
}) : null;
 | 
			
		||||
 | 
			
		||||
var ChatSource = class extends MessageTray.Source {
 | 
			
		||||
    constructor(account, conn, channel, contact, client) {
 | 
			
		||||
        super(contact.get_alias());
 | 
			
		||||
var ChatSource = HAVE_TP ? GObject.registerClass(
 | 
			
		||||
class ChatSource extends MessageTray.Source {
 | 
			
		||||
    _init(account, conn, channel, contact, client) {
 | 
			
		||||
        super._init(contact.get_alias());
 | 
			
		||||
 | 
			
		||||
        this._account = account;
 | 
			
		||||
        this._contact = contact;
 | 
			
		||||
@@ -327,7 +327,7 @@ var ChatSource = class extends MessageTray.Source {
 | 
			
		||||
 | 
			
		||||
        // We ack messages when the user expands the new notification
 | 
			
		||||
        let id = this._banner.connect('expanded', this._ackMessages.bind(this));
 | 
			
		||||
        this._banner.actor.connect('destroy', () => {
 | 
			
		||||
        this._banner.connect('destroy', () => {
 | 
			
		||||
            this._banner.disconnect(id);
 | 
			
		||||
            this._banner = null;
 | 
			
		||||
        });
 | 
			
		||||
@@ -477,7 +477,7 @@ var ChatSource = class extends MessageTray.Source {
 | 
			
		||||
            this._notification.appendMessage(pendingMessages[i], true);
 | 
			
		||||
 | 
			
		||||
        if (pendingMessages.length > 0)
 | 
			
		||||
            this.notify();
 | 
			
		||||
            this.showNotification();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    destroy(reason) {
 | 
			
		||||
@@ -546,15 +546,15 @@ var ChatSource = class extends MessageTray.Source {
 | 
			
		||||
        // Wait a bit before notifying for the received message, a handler
 | 
			
		||||
        // could ack it in the meantime.
 | 
			
		||||
        if (this._notifyTimeoutId != 0)
 | 
			
		||||
            Mainloop.source_remove(this._notifyTimeoutId);
 | 
			
		||||
        this._notifyTimeoutId = Mainloop.timeout_add(500,
 | 
			
		||||
            GLib.source_remove(this._notifyTimeoutId);
 | 
			
		||||
        this._notifyTimeoutId = GLib.timeout_add(GLib.PRIORITY_DEFAULT, 500,
 | 
			
		||||
            this._notifyTimeout.bind(this));
 | 
			
		||||
        GLib.Source.set_name_by_id(this._notifyTimeoutId, '[gnome-shell] this._notifyTimeout');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _notifyTimeout() {
 | 
			
		||||
        if (this._pendingMessages.length != 0)
 | 
			
		||||
            this.notify();
 | 
			
		||||
            this.showNotification();
 | 
			
		||||
 | 
			
		||||
        this._notifyTimeoutId = 0;
 | 
			
		||||
 | 
			
		||||
@@ -569,8 +569,8 @@ var ChatSource = class extends MessageTray.Source {
 | 
			
		||||
        this._notification.appendMessage(message);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    notify() {
 | 
			
		||||
        super.notify(this._notification);
 | 
			
		||||
    showNotification() {
 | 
			
		||||
        super.showNotification(this._notification);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    respond(text) {
 | 
			
		||||
@@ -584,7 +584,7 @@ var ChatSource = class extends MessageTray.Source {
 | 
			
		||||
 | 
			
		||||
        let msg = Tp.ClientMessage.new_text(type, text);
 | 
			
		||||
        this._channel.send_message_async(msg, 0, (src, result) => {
 | 
			
		||||
            this._channel.send_message_finish(result); 
 | 
			
		||||
            this._channel.send_message_finish(result);
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -626,12 +626,18 @@ var ChatSource = class extends MessageTray.Source {
 | 
			
		||||
        // 'pending-message-removed' for each one.
 | 
			
		||||
        this._channel.ack_all_pending_messages_async(null);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
}) : null;
 | 
			
		||||
 | 
			
		||||
var ChatNotification = class extends MessageTray.Notification {
 | 
			
		||||
    constructor(source) {
 | 
			
		||||
        super(source, source.title, null,
 | 
			
		||||
              { secondaryGIcon: source.getSecondaryIcon() });
 | 
			
		||||
var ChatNotification = HAVE_TP ? GObject.registerClass({
 | 
			
		||||
    Signals: {
 | 
			
		||||
        'message-removed': { param_types: [Tp.Message.$gtype] },
 | 
			
		||||
        'message-added': { param_types: [Tp.Message.$gtype] },
 | 
			
		||||
        'timestamp-changed': { param_types: [Tp.Message.$gtype] },
 | 
			
		||||
    }
 | 
			
		||||
}, class ChatNotification extends MessageTray.Notification {
 | 
			
		||||
    _init(source) {
 | 
			
		||||
        super._init(source, source.title, null,
 | 
			
		||||
            { secondaryGIcon: source.getSecondaryIcon() });
 | 
			
		||||
        this.setUrgency(MessageTray.Urgency.HIGH);
 | 
			
		||||
        this.setResident(true);
 | 
			
		||||
 | 
			
		||||
@@ -641,7 +647,7 @@ var ChatNotification = class extends MessageTray.Notification {
 | 
			
		||||
 | 
			
		||||
    destroy(reason) {
 | 
			
		||||
        if (this._timestampTimeoutId)
 | 
			
		||||
            Mainloop.source_remove(this._timestampTimeoutId);
 | 
			
		||||
            GLib.source_remove(this._timestampTimeoutId);
 | 
			
		||||
        this._timestampTimeoutId = 0;
 | 
			
		||||
        super.destroy(reason);
 | 
			
		||||
    }
 | 
			
		||||
@@ -654,7 +660,7 @@ var ChatNotification = class extends MessageTray.Notification {
 | 
			
		||||
     *   sender: the name of the sender,
 | 
			
		||||
     *   timestamp: the time the message was sent
 | 
			
		||||
     *   direction: a #NotificationDirection
 | 
			
		||||
     * 
 | 
			
		||||
     *
 | 
			
		||||
     * @noTimestamp: Whether to add a timestamp. If %true, no timestamp
 | 
			
		||||
     *   will be added, regardless of the difference since the
 | 
			
		||||
     *   last timestamp
 | 
			
		||||
@@ -674,8 +680,8 @@ var ChatNotification = class extends MessageTray.Notification {
 | 
			
		||||
                        { datetime: GLib.DateTime.new_from_unix_local (message.timestamp),
 | 
			
		||||
                          bannerMarkup: true });
 | 
			
		||||
 | 
			
		||||
        let group = (message.direction == NotificationDirection.RECEIVED ?
 | 
			
		||||
                     'received' : 'sent');
 | 
			
		||||
        let group = (message.direction == NotificationDirection.RECEIVED
 | 
			
		||||
            ? 'received' : 'sent');
 | 
			
		||||
 | 
			
		||||
        this._append({ body: messageBody,
 | 
			
		||||
                       group: group,
 | 
			
		||||
@@ -697,8 +703,8 @@ var ChatNotification = class extends MessageTray.Notification {
 | 
			
		||||
        // SCROLLBACK_RECENT_LENGTH previous messages. Otherwise
 | 
			
		||||
        // we'll keep SCROLLBACK_IDLE_LENGTH messages.
 | 
			
		||||
 | 
			
		||||
        let maxLength = (lastMessageTime < currentTime - SCROLLBACK_RECENT_TIME) ?
 | 
			
		||||
            SCROLLBACK_IDLE_LENGTH : SCROLLBACK_RECENT_LENGTH;
 | 
			
		||||
        let maxLength = (lastMessageTime < currentTime - SCROLLBACK_RECENT_TIME)
 | 
			
		||||
            ? SCROLLBACK_IDLE_LENGTH : SCROLLBACK_RECENT_LENGTH;
 | 
			
		||||
 | 
			
		||||
        let filteredHistory = this.messages.filter(item => item.realMessage);
 | 
			
		||||
        if (filteredHistory.length > maxLength) {
 | 
			
		||||
@@ -729,7 +735,7 @@ var ChatNotification = class extends MessageTray.Notification {
 | 
			
		||||
 | 
			
		||||
        // Reset the old message timeout
 | 
			
		||||
        if (this._timestampTimeoutId)
 | 
			
		||||
            Mainloop.source_remove(this._timestampTimeoutId);
 | 
			
		||||
            GLib.source_remove(this._timestampTimeoutId);
 | 
			
		||||
        this._timestampTimeoutId = 0;
 | 
			
		||||
 | 
			
		||||
        let message = { realMessage: props.group != 'meta',
 | 
			
		||||
@@ -747,7 +753,8 @@ var ChatNotification = class extends MessageTray.Notification {
 | 
			
		||||
            } else {
 | 
			
		||||
                // Schedule a new timestamp in SCROLLBACK_IMMEDIATE_TIME
 | 
			
		||||
                // from the timestamp of the message.
 | 
			
		||||
                this._timestampTimeoutId = Mainloop.timeout_add_seconds(
 | 
			
		||||
                this._timestampTimeoutId = GLib.timeout_add_seconds(
 | 
			
		||||
                    GLib.PRIORITY_DEFAULT,
 | 
			
		||||
                    SCROLLBACK_IMMEDIATE_TIME - (currentTime - timestamp),
 | 
			
		||||
                    this.appendTimestamp.bind(this));
 | 
			
		||||
                GLib.Source.set_name_by_id(this._timestampTimeoutId, '[gnome-shell] this.appendTimestamp');
 | 
			
		||||
@@ -782,7 +789,7 @@ var ChatNotification = class extends MessageTray.Notification {
 | 
			
		||||
 | 
			
		||||
        this._filterMessages();
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
}) : null;
 | 
			
		||||
 | 
			
		||||
var ChatLineBox = GObject.registerClass(
 | 
			
		||||
class ChatLineBox extends St.BoxLayout {
 | 
			
		||||
@@ -792,9 +799,10 @@ class ChatLineBox extends St.BoxLayout {
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
var ChatNotificationBanner = class extends MessageTray.NotificationBanner {
 | 
			
		||||
    constructor(notification) {
 | 
			
		||||
        super(notification);
 | 
			
		||||
var ChatNotificationBanner = GObject.registerClass(
 | 
			
		||||
class ChatNotificationBanner extends MessageTray.NotificationBanner {
 | 
			
		||||
    _init(notification) {
 | 
			
		||||
        super._init(notification);
 | 
			
		||||
 | 
			
		||||
        this._responseEntry = new St.Entry({ style_class: 'chat-response',
 | 
			
		||||
                                             x_expand: true,
 | 
			
		||||
@@ -879,8 +887,7 @@ var ChatNotificationBanner = class extends MessageTray.NotificationBanner {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _addMessage(message) {
 | 
			
		||||
        let highlighter = new MessageList.URLHighlighter(message.body, true, true);
 | 
			
		||||
        let body = highlighter.actor;
 | 
			
		||||
        let body = new MessageList.URLHighlighter(message.body, true, true);
 | 
			
		||||
 | 
			
		||||
        let styles = message.styles;
 | 
			
		||||
        for (let i = 0; i < styles.length; i++)
 | 
			
		||||
@@ -952,14 +959,15 @@ var ChatNotificationBanner = class extends MessageTray.NotificationBanner {
 | 
			
		||||
 | 
			
		||||
        // Remove composing timeout.
 | 
			
		||||
        if (this._composingTimeoutId > 0) {
 | 
			
		||||
            Mainloop.source_remove(this._composingTimeoutId);
 | 
			
		||||
            GLib.source_remove(this._composingTimeoutId);
 | 
			
		||||
            this._composingTimeoutId = 0;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (text != '') {
 | 
			
		||||
            this.notification.source.setChatState(Tp.ChannelChatState.COMPOSING);
 | 
			
		||||
 | 
			
		||||
            this._composingTimeoutId = Mainloop.timeout_add_seconds(
 | 
			
		||||
            this._composingTimeoutId = GLib.timeout_add_seconds(
 | 
			
		||||
                GLib.PRIORITY_DEFAULT,
 | 
			
		||||
                COMPOSING_STOP_TIMEOUT,
 | 
			
		||||
                this._composingStopTimeout.bind(this));
 | 
			
		||||
            GLib.Source.set_name_by_id(this._composingTimeoutId, '[gnome-shell] this._composingStopTimeout');
 | 
			
		||||
@@ -967,6 +975,6 @@ var ChatNotificationBanner = class extends MessageTray.NotificationBanner {
 | 
			
		||||
            this.notification.source.setChatState(Tp.ChannelChatState.ACTIVE);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
var Component = TelepathyComponent;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,8 @@
 | 
			
		||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
 | 
			
		||||
/* exported Dash */
 | 
			
		||||
 | 
			
		||||
const { Clutter, GLib, GObject, Meta, Shell, St } = imports.gi;
 | 
			
		||||
const Mainloop = imports.mainloop;
 | 
			
		||||
const Signals = imports.signals;
 | 
			
		||||
const { Clutter, GLib, GObject,
 | 
			
		||||
        Graphene, Meta, Shell, St } = imports.gi;
 | 
			
		||||
 | 
			
		||||
const AppDisplay = imports.ui.appDisplay;
 | 
			
		||||
const AppFavorites = imports.ui.appFavorites;
 | 
			
		||||
@@ -24,9 +23,10 @@ function getAppFromSource(source) {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var DashIcon = class DashIcon extends AppDisplay.AppIcon {
 | 
			
		||||
    constructor(app) {
 | 
			
		||||
        super(app, {
 | 
			
		||||
var DashIcon = GObject.registerClass(
 | 
			
		||||
class DashIcon extends AppDisplay.AppIcon {
 | 
			
		||||
    _init(app) {
 | 
			
		||||
        super._init(app, {
 | 
			
		||||
            setSizeManually: true,
 | 
			
		||||
            showLabel: false
 | 
			
		||||
        });
 | 
			
		||||
@@ -46,7 +46,7 @@ var DashIcon = class DashIcon extends AppDisplay.AppIcon {
 | 
			
		||||
    acceptDrop() {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
// A container like StBin, but taking the child's scale into account
 | 
			
		||||
// when requesting a size
 | 
			
		||||
@@ -54,7 +54,7 @@ var DashItemContainer = GObject.registerClass(
 | 
			
		||||
class DashItemContainer extends St.Widget {
 | 
			
		||||
    _init() {
 | 
			
		||||
        super._init({ style_class: 'dash-item-container',
 | 
			
		||||
                      pivot_point: new Clutter.Point({ x: .5, y: .5 }),
 | 
			
		||||
                      pivot_point: new Graphene.Point({ x: .5, y: .5 }),
 | 
			
		||||
                      scale_x: 0,
 | 
			
		||||
                      scale_y: 0,
 | 
			
		||||
                      opacity: 0,
 | 
			
		||||
@@ -331,8 +331,10 @@ class DashActor extends St.Widget {
 | 
			
		||||
 | 
			
		||||
const baseIconSizes = [16, 22, 24, 32, 48, 64];
 | 
			
		||||
 | 
			
		||||
var Dash = class Dash {
 | 
			
		||||
    constructor() {
 | 
			
		||||
var Dash = GObject.registerClass({
 | 
			
		||||
    Signals: { 'icon-size-changed': {} }
 | 
			
		||||
}, class Dash extends St.Bin {
 | 
			
		||||
    _init() {
 | 
			
		||||
        this._maxHeight = -1;
 | 
			
		||||
        this.iconSize = 64;
 | 
			
		||||
        this._shownInitially = false;
 | 
			
		||||
@@ -360,11 +362,11 @@ var Dash = class Dash {
 | 
			
		||||
 | 
			
		||||
        this._container.add_actor(this._showAppsIcon);
 | 
			
		||||
 | 
			
		||||
        this.actor = new St.Bin({ child: this._container });
 | 
			
		||||
        this.actor.connect('notify::height', () => {
 | 
			
		||||
            if (this._maxHeight != this.actor.height)
 | 
			
		||||
        super._init({ child: this._container });
 | 
			
		||||
        this.connect('notify::height', () => {
 | 
			
		||||
            if (this._maxHeight != this.height)
 | 
			
		||||
                this._queueRedisplay();
 | 
			
		||||
            this._maxHeight = this.actor.height;
 | 
			
		||||
            this._maxHeight = this.height;
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        this._workId = Main.initializeDeferredWork(this._box, this._redisplay.bind(this));
 | 
			
		||||
@@ -387,7 +389,7 @@ var Dash = class Dash {
 | 
			
		||||
 | 
			
		||||
        // Translators: this is the name of the dock/favorites area on
 | 
			
		||||
        // the left of the overview
 | 
			
		||||
        Main.ctrlAltTabManager.addGroup(this.actor, _("Dash"), 'user-bookmarks-symbolic');
 | 
			
		||||
        Main.ctrlAltTabManager.addGroup(this, _("Dash"), 'user-bookmarks-symbolic');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _onDragBegin() {
 | 
			
		||||
@@ -482,11 +484,11 @@ var Dash = class Dash {
 | 
			
		||||
                        });
 | 
			
		||||
 | 
			
		||||
        let item = new DashItemContainer();
 | 
			
		||||
        item.setChild(appIcon.actor);
 | 
			
		||||
        item.setChild(appIcon);
 | 
			
		||||
 | 
			
		||||
        // Override default AppIcon label_actor, now the
 | 
			
		||||
        // accessible_name is set at DashItemContainer.setLabelText
 | 
			
		||||
        appIcon.actor.label_actor = null;
 | 
			
		||||
        appIcon.label_actor = null;
 | 
			
		||||
        item.setLabelText(app.get_name());
 | 
			
		||||
 | 
			
		||||
        appIcon.icon.setIconSize(this.iconSize);
 | 
			
		||||
@@ -500,7 +502,7 @@ var Dash = class Dash {
 | 
			
		||||
        // that the notify::hover handler does everything we need to.
 | 
			
		||||
        if (opened) {
 | 
			
		||||
            if (this._showLabelTimeoutId > 0) {
 | 
			
		||||
                Mainloop.source_remove(this._showLabelTimeoutId);
 | 
			
		||||
                GLib.source_remove(this._showLabelTimeoutId);
 | 
			
		||||
                this._showLabelTimeoutId = 0;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
@@ -514,7 +516,7 @@ var Dash = class Dash {
 | 
			
		||||
        if (shouldShow) {
 | 
			
		||||
            if (this._showLabelTimeoutId == 0) {
 | 
			
		||||
                let timeout = this._labelShowing ? 0 : DASH_ITEM_HOVER_TIMEOUT;
 | 
			
		||||
                this._showLabelTimeoutId = Mainloop.timeout_add(timeout,
 | 
			
		||||
                this._showLabelTimeoutId = GLib.timeout_add(GLib.PRIORITY_DEFAULT, timeout,
 | 
			
		||||
                    () => {
 | 
			
		||||
                        this._labelShowing = true;
 | 
			
		||||
                        item.showLabel();
 | 
			
		||||
@@ -523,17 +525,17 @@ var Dash = class Dash {
 | 
			
		||||
                    });
 | 
			
		||||
                GLib.Source.set_name_by_id(this._showLabelTimeoutId, '[gnome-shell] item.showLabel');
 | 
			
		||||
                if (this._resetHoverTimeoutId > 0) {
 | 
			
		||||
                    Mainloop.source_remove(this._resetHoverTimeoutId);
 | 
			
		||||
                    GLib.source_remove(this._resetHoverTimeoutId);
 | 
			
		||||
                    this._resetHoverTimeoutId = 0;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            if (this._showLabelTimeoutId > 0)
 | 
			
		||||
                Mainloop.source_remove(this._showLabelTimeoutId);
 | 
			
		||||
                GLib.source_remove(this._showLabelTimeoutId);
 | 
			
		||||
            this._showLabelTimeoutId = 0;
 | 
			
		||||
            item.hideLabel();
 | 
			
		||||
            if (this._labelShowing) {
 | 
			
		||||
                this._resetHoverTimeoutId = Mainloop.timeout_add(DASH_ITEM_HOVER_TIMEOUT,
 | 
			
		||||
                this._resetHoverTimeoutId = GLib.timeout_add(GLib.PRIORITY_DEFAULT, DASH_ITEM_HOVER_TIMEOUT,
 | 
			
		||||
                    () => {
 | 
			
		||||
                        this._labelShowing = false;
 | 
			
		||||
                        this._resetHoverTimeoutId = 0;
 | 
			
		||||
@@ -624,7 +626,7 @@ var Dash = class Dash {
 | 
			
		||||
            icon.icon.ease({
 | 
			
		||||
                width: targetWidth,
 | 
			
		||||
                height: targetHeight,
 | 
			
		||||
                time: DASH_ANIMATION_TIME,
 | 
			
		||||
                duration: DASH_ANIMATION_TIME,
 | 
			
		||||
                mode: Clutter.AnimationMode.EASE_OUT_QUAD
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
@@ -704,8 +706,8 @@ var Dash = class Dash {
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // App moved
 | 
			
		||||
            let nextApp = newApps.length > newIndex + 1 ? newApps[newIndex + 1]
 | 
			
		||||
                                                        : null;
 | 
			
		||||
            let nextApp = newApps.length > newIndex + 1
 | 
			
		||||
                ? newApps[newIndex + 1] : null;
 | 
			
		||||
            let insertHere = nextApp && nextApp == oldApp;
 | 
			
		||||
            let alreadyRemoved = removedActors.reduce((result, actor) => {
 | 
			
		||||
                let removedApp = actor.child._delegate.app;
 | 
			
		||||
@@ -903,5 +905,4 @@ var Dash = class Dash {
 | 
			
		||||
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
Signals.addSignalMethods(Dash.prototype);
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -25,22 +25,26 @@ function _isToday(date) {
 | 
			
		||||
           now.getDate() == date.getDate();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var TodayButton = class TodayButton {
 | 
			
		||||
    constructor(calendar) {
 | 
			
		||||
function _gDateTimeToDate(datetime) {
 | 
			
		||||
    return new Date(datetime.to_unix() * 1000 + datetime.get_microsecond() / 1000);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var TodayButton = GObject.registerClass(
 | 
			
		||||
class TodayButton extends St.Button {
 | 
			
		||||
    _init(calendar) {
 | 
			
		||||
        // Having the ability to go to the current date if the user is already
 | 
			
		||||
        // on the current date can be confusing. So don't make the button reactive
 | 
			
		||||
        // until the selected date changes.
 | 
			
		||||
        this.actor = new St.Button({ style_class: 'datemenu-today-button',
 | 
			
		||||
                                     x_expand: true, x_align: St.Align.START,
 | 
			
		||||
                                     can_focus: true,
 | 
			
		||||
                                     reactive: false
 | 
			
		||||
                                   });
 | 
			
		||||
        this.actor.connect('clicked', () => {
 | 
			
		||||
            this._calendar.setDate(new Date(), false);
 | 
			
		||||
        super._init({
 | 
			
		||||
            style_class: 'datemenu-today-button',
 | 
			
		||||
            x_align: St.Align.START,
 | 
			
		||||
            x_expand: true,
 | 
			
		||||
            can_focus: true,
 | 
			
		||||
            reactive: false
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        let hbox = new St.BoxLayout({ vertical: true });
 | 
			
		||||
        this.actor.add_actor(hbox);
 | 
			
		||||
        this.add_actor(hbox);
 | 
			
		||||
 | 
			
		||||
        this._dayLabel = new St.Label({ style_class: 'day-label',
 | 
			
		||||
                                        x_align: Clutter.ActorAlign.START });
 | 
			
		||||
@@ -50,13 +54,17 @@ var TodayButton = class TodayButton {
 | 
			
		||||
        hbox.add_actor(this._dateLabel);
 | 
			
		||||
 | 
			
		||||
        this._calendar = calendar;
 | 
			
		||||
        this._calendar.connect('selected-date-changed', (calendar, date) => {
 | 
			
		||||
        this._calendar.connect('selected-date-changed', (_calendar, datetime) => {
 | 
			
		||||
            // Make the button reactive only if the selected date is not the
 | 
			
		||||
            // current date.
 | 
			
		||||
            this.actor.reactive = !_isToday(date);
 | 
			
		||||
            this.reactive = !_isToday(_gDateTimeToDate(datetime));
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    vfunc_clicked() {
 | 
			
		||||
        this._calendar.setDate(new Date(), false);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    setDate(date) {
 | 
			
		||||
        this._dayLabel.set_text(date.toLocaleFormat('%A'));
 | 
			
		||||
 | 
			
		||||
@@ -73,34 +81,29 @@ var TodayButton = class TodayButton {
 | 
			
		||||
         * date, e.g. "Tuesday February 17 2015".
 | 
			
		||||
         */
 | 
			
		||||
        dateFormat = Shell.util_translate_time_string (N_("%A %B %e %Y"));
 | 
			
		||||
        this.actor.accessible_name = date.toLocaleFormat(dateFormat);
 | 
			
		||||
        this.accessible_name = date.toLocaleFormat(dateFormat);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
var WorldClocksSection = class WorldClocksSection {
 | 
			
		||||
    constructor() {
 | 
			
		||||
var WorldClocksSection = GObject.registerClass(
 | 
			
		||||
class WorldClocksSection extends St.Button {
 | 
			
		||||
    _init() {
 | 
			
		||||
        super._init({
 | 
			
		||||
            style_class: 'world-clocks-button',
 | 
			
		||||
            x_fill: true,
 | 
			
		||||
            can_focus: true
 | 
			
		||||
        });
 | 
			
		||||
        this._clock = new GnomeDesktop.WallClock();
 | 
			
		||||
        this._clockNotifyId = 0;
 | 
			
		||||
 | 
			
		||||
        this._locations = [];
 | 
			
		||||
 | 
			
		||||
        this.actor = new St.Button({ style_class: 'world-clocks-button',
 | 
			
		||||
                                     x_fill: true,
 | 
			
		||||
                                     can_focus: true });
 | 
			
		||||
        this.actor.connect('clicked', () => {
 | 
			
		||||
            if (this._clocksApp)
 | 
			
		||||
                this._clocksApp.activate();
 | 
			
		||||
 | 
			
		||||
            Main.overview.hide();
 | 
			
		||||
            Main.panel.closeCalendar();
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        let layout = new Clutter.GridLayout({ orientation: Clutter.Orientation.VERTICAL });
 | 
			
		||||
        this._grid = new St.Widget({ style_class: 'world-clocks-grid',
 | 
			
		||||
                                     layout_manager: layout });
 | 
			
		||||
        layout.hookup_style(this._grid);
 | 
			
		||||
 | 
			
		||||
        this.actor.child = this._grid;
 | 
			
		||||
        this.child = this._grid;
 | 
			
		||||
 | 
			
		||||
        this._clocksApp = null;
 | 
			
		||||
        this._clocksProxy = new ClocksProxy(
 | 
			
		||||
@@ -123,9 +126,17 @@ var WorldClocksSection = class WorldClocksSection {
 | 
			
		||||
        this._sync();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    vfunc_clicked() {
 | 
			
		||||
        if (this._clocksApp)
 | 
			
		||||
            this._clocksApp.activate();
 | 
			
		||||
 | 
			
		||||
        Main.overview.hide();
 | 
			
		||||
        Main.panel.closeCalendar();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _sync() {
 | 
			
		||||
        this._clocksApp = this._appSystem.lookup_app('org.gnome.clocks.desktop');
 | 
			
		||||
        this.actor.visible = this._clocksApp != null;
 | 
			
		||||
        this.visible = this._clocksApp != null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _clocksChanged() {
 | 
			
		||||
@@ -146,13 +157,14 @@ var WorldClocksSection = class WorldClocksSection {
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        let layout = this._grid.layout_manager;
 | 
			
		||||
        let title = (this._locations.length == 0) ? _("Add world clocks…")
 | 
			
		||||
                                                  : _("World Clocks");
 | 
			
		||||
        let title = (this._locations.length == 0)
 | 
			
		||||
            ? _("Add world clocks…")
 | 
			
		||||
            : _("World Clocks");
 | 
			
		||||
        let header = new St.Label({ style_class: 'world-clocks-header',
 | 
			
		||||
                                    x_align: Clutter.ActorAlign.START,
 | 
			
		||||
                                    text: title });
 | 
			
		||||
        layout.attach(header, 0, 0, 2, 1);
 | 
			
		||||
        this.actor.label_actor = header;
 | 
			
		||||
        this.label_actor = header;
 | 
			
		||||
 | 
			
		||||
        let localOffset = GLib.DateTime.new_now_local().get_utc_offset();
 | 
			
		||||
 | 
			
		||||
@@ -233,30 +245,23 @@ var WorldClocksSection = class WorldClocksSection {
 | 
			
		||||
        this._settings.set_value('locations',
 | 
			
		||||
            new GLib.Variant('av', this._clocksProxy.Locations));
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
var WeatherSection = GObject.registerClass(
 | 
			
		||||
class WeatherSection extends St.Button {
 | 
			
		||||
    _init() {
 | 
			
		||||
        super._init({
 | 
			
		||||
            style_class: 'weather-button',
 | 
			
		||||
            x_fill: true,
 | 
			
		||||
            can_focus: true
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
var WeatherSection = class WeatherSection {
 | 
			
		||||
    constructor() {
 | 
			
		||||
        this._weatherClient = new Weather.WeatherClient();
 | 
			
		||||
 | 
			
		||||
        this.actor = new St.Button({ style_class: 'weather-button',
 | 
			
		||||
                                     x_fill: true,
 | 
			
		||||
                                     can_focus: true });
 | 
			
		||||
        this.actor.connect('clicked', () => {
 | 
			
		||||
            this._weatherClient.activateApp();
 | 
			
		||||
 | 
			
		||||
            Main.overview.hide();
 | 
			
		||||
            Main.panel.closeCalendar();
 | 
			
		||||
        });
 | 
			
		||||
        this.actor.connect('notify::mapped', () => {
 | 
			
		||||
            if (this.actor.mapped)
 | 
			
		||||
                this._weatherClient.update();
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        let box = new St.BoxLayout({ style_class: 'weather-box',
 | 
			
		||||
                                     vertical: true });
 | 
			
		||||
 | 
			
		||||
        this.actor.child = box;
 | 
			
		||||
        this.child = box;
 | 
			
		||||
 | 
			
		||||
        let titleBox = new St.BoxLayout();
 | 
			
		||||
        titleBox.add_child(new St.Label({ style_class: 'weather-header',
 | 
			
		||||
@@ -279,6 +284,18 @@ var WeatherSection = class WeatherSection {
 | 
			
		||||
        this._sync();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    vfunc_map() {
 | 
			
		||||
        this._weatherClient.update();
 | 
			
		||||
        super.vfunc_map();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    vfunc_clicked() {
 | 
			
		||||
        this._weatherClient.activateApp();
 | 
			
		||||
 | 
			
		||||
        Main.overview.hide();
 | 
			
		||||
        Main.panel.closeCalendar();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _getInfos() {
 | 
			
		||||
        let info = this._weatherClient.info;
 | 
			
		||||
        let forecasts = info.get_forecast_list();
 | 
			
		||||
@@ -369,23 +386,27 @@ var WeatherSection = class WeatherSection {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _sync() {
 | 
			
		||||
        this.actor.visible = this._weatherClient.available;
 | 
			
		||||
        this.visible = this._weatherClient.available;
 | 
			
		||||
 | 
			
		||||
        if (!this.actor.visible)
 | 
			
		||||
        if (!this.visible)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        this._titleLocation.visible = this._weatherClient.hasLocation;
 | 
			
		||||
 | 
			
		||||
        this._updateForecasts();
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
var MessagesIndicator = class MessagesIndicator {
 | 
			
		||||
    constructor() {
 | 
			
		||||
        this.actor = new St.Icon({ icon_name: 'message-indicator-symbolic',
 | 
			
		||||
                                   icon_size: 16,
 | 
			
		||||
                                   visible: false, y_expand: true,
 | 
			
		||||
                                   y_align: Clutter.ActorAlign.CENTER });
 | 
			
		||||
var MessagesIndicator = GObject.registerClass(
 | 
			
		||||
class MessagesIndicator extends St.Icon {
 | 
			
		||||
    _init() {
 | 
			
		||||
        super._init({
 | 
			
		||||
            icon_name: 'message-indicator-symbolic',
 | 
			
		||||
            icon_size: 16,
 | 
			
		||||
            visible: false,
 | 
			
		||||
            y_expand: true,
 | 
			
		||||
            y_align: Clutter.ActorAlign.CENTER
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        this._sources = [];
 | 
			
		||||
 | 
			
		||||
@@ -398,7 +419,7 @@ var MessagesIndicator = class MessagesIndicator {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _onSourceAdded(tray, source) {
 | 
			
		||||
        source.connect('count-updated', this._updateCount.bind(this));
 | 
			
		||||
        source.connect('notify::count', this._updateCount.bind(this));
 | 
			
		||||
        this._sources.push(source);
 | 
			
		||||
        this._updateCount();
 | 
			
		||||
    }
 | 
			
		||||
@@ -410,12 +431,12 @@ var MessagesIndicator = class MessagesIndicator {
 | 
			
		||||
 | 
			
		||||
    _updateCount() {
 | 
			
		||||
        let count = 0;
 | 
			
		||||
        this._sources.forEach(source => count += source.unseenCount);
 | 
			
		||||
        this._sources.forEach(source => (count += source.unseenCount));
 | 
			
		||||
        count -= Main.messageTray.queueCount;
 | 
			
		||||
 | 
			
		||||
        this.actor.visible = (count > 0);
 | 
			
		||||
        this.visible = (count > 0);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
var IndicatorPad = GObject.registerClass(
 | 
			
		||||
class IndicatorPad extends St.Widget {
 | 
			
		||||
@@ -508,9 +529,9 @@ class DateMenuButton extends PanelMenu.Button {
 | 
			
		||||
        this._indicator = new MessagesIndicator();
 | 
			
		||||
 | 
			
		||||
        let box = new St.BoxLayout();
 | 
			
		||||
        box.add_actor(new IndicatorPad(this._indicator.actor));
 | 
			
		||||
        box.add_actor(new IndicatorPad(this._indicator));
 | 
			
		||||
        box.add_actor(this._clockDisplay);
 | 
			
		||||
        box.add_actor(this._indicator.actor);
 | 
			
		||||
        box.add_actor(this._indicator);
 | 
			
		||||
 | 
			
		||||
        this.label_actor = this._clockDisplay;
 | 
			
		||||
        this.add_actor(box);
 | 
			
		||||
@@ -526,11 +547,11 @@ class DateMenuButton extends PanelMenu.Button {
 | 
			
		||||
        bin.add_actor(hbox);
 | 
			
		||||
 | 
			
		||||
        this._calendar = new Calendar.Calendar();
 | 
			
		||||
        this._calendar.connect('selected-date-changed',
 | 
			
		||||
                               (calendar, date) => {
 | 
			
		||||
                                   layout.frozen = !_isToday(date);
 | 
			
		||||
                                   this._messageList.setDate(date);
 | 
			
		||||
                               });
 | 
			
		||||
        this._calendar.connect('selected-date-changed', (_calendar, datetime) => {
 | 
			
		||||
            let date = _gDateTimeToDate(datetime);
 | 
			
		||||
            layout.frozen = !_isToday(date);
 | 
			
		||||
            this._messageList.setDate(date);
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        this.menu.connect('open-state-changed', (menu, isOpen) => {
 | 
			
		||||
            // Whenever the menu is opened, select today
 | 
			
		||||
@@ -544,19 +565,19 @@ class DateMenuButton extends PanelMenu.Button {
 | 
			
		||||
 | 
			
		||||
        // Fill up the first column
 | 
			
		||||
        this._messageList = new Calendar.CalendarMessageList();
 | 
			
		||||
        hbox.add(this._messageList.actor, { expand: true, y_fill: false, y_align: St.Align.START });
 | 
			
		||||
        hbox.add(this._messageList, { expand: true, y_fill: false, y_align: St.Align.START });
 | 
			
		||||
 | 
			
		||||
        // Fill up the second column
 | 
			
		||||
        let boxLayout = new CalendarColumnLayout(this._calendar.actor);
 | 
			
		||||
        let boxLayout = new CalendarColumnLayout(this._calendar);
 | 
			
		||||
        vbox = new St.Widget({ style_class: 'datemenu-calendar-column',
 | 
			
		||||
                               layout_manager: boxLayout });
 | 
			
		||||
        boxLayout.hookup_style(vbox);
 | 
			
		||||
        hbox.add(vbox);
 | 
			
		||||
 | 
			
		||||
        this._date = new TodayButton(this._calendar);
 | 
			
		||||
        vbox.add_actor(this._date.actor);
 | 
			
		||||
        vbox.add_actor(this._date);
 | 
			
		||||
 | 
			
		||||
        vbox.add_actor(this._calendar.actor);
 | 
			
		||||
        vbox.add_actor(this._calendar);
 | 
			
		||||
 | 
			
		||||
        this._displaysSection = new St.ScrollView({ style_class: 'datemenu-displays-section vfade',
 | 
			
		||||
                                                    x_expand: true, x_fill: true,
 | 
			
		||||
@@ -569,10 +590,10 @@ class DateMenuButton extends PanelMenu.Button {
 | 
			
		||||
        this._displaysSection.add_actor(displaysBox);
 | 
			
		||||
 | 
			
		||||
        this._clocksItem = new WorldClocksSection();
 | 
			
		||||
        displaysBox.add(this._clocksItem.actor, { x_fill: true });
 | 
			
		||||
        displaysBox.add(this._clocksItem, { x_fill: true });
 | 
			
		||||
 | 
			
		||||
        this._weatherItem = new WeatherSection();
 | 
			
		||||
        displaysBox.add(this._weatherItem.actor, { x_fill: true });
 | 
			
		||||
        displaysBox.add(this._weatherItem, { x_fill: true });
 | 
			
		||||
 | 
			
		||||
        // Done with hbox for calendar and event list
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										14
									
								
								js/ui/dnd.js
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								js/ui/dnd.js
									
									
									
									
									
								
							@@ -573,11 +573,15 @@ var _Draggable = class _Draggable {
 | 
			
		||||
        while (target) {
 | 
			
		||||
            if (target._delegate && target._delegate.acceptDrop) {
 | 
			
		||||
                let [r_, targX, targY] = target.transform_stage_point(dropX, dropY);
 | 
			
		||||
                if (target._delegate.acceptDrop(this.actor._delegate,
 | 
			
		||||
                                                this._dragActor,
 | 
			
		||||
                                                targX,
 | 
			
		||||
                                                targY,
 | 
			
		||||
                                                event.get_time())) {
 | 
			
		||||
                let accepted = false;
 | 
			
		||||
                try {
 | 
			
		||||
                    accepted = target._delegate.acceptDrop(this.actor._delegate,
 | 
			
		||||
                        this._dragActor, targX, targY, event.get_time());
 | 
			
		||||
                } catch (e) {
 | 
			
		||||
                    // On error, skip this target
 | 
			
		||||
                    logError(e, "Skipping drag target");
 | 
			
		||||
                }
 | 
			
		||||
                if (accepted) {
 | 
			
		||||
                    // If it accepted the drop without taking the actor,
 | 
			
		||||
                    // handle it ourselves.
 | 
			
		||||
                    if (this._dragActor && this._dragActor.get_parent() == Main.uiGroup) {
 | 
			
		||||
 
 | 
			
		||||
@@ -17,8 +17,6 @@
 | 
			
		||||
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
const Mainloop = imports.mainloop;
 | 
			
		||||
 | 
			
		||||
const { AccountsService, Clutter, Gio,
 | 
			
		||||
        GLib, GObject, Pango, Polkit, Shell, St }  = imports.gi;
 | 
			
		||||
 | 
			
		||||
@@ -209,10 +207,10 @@ function _setCheckBoxLabel(checkBox, text) {
 | 
			
		||||
 | 
			
		||||
    if (text) {
 | 
			
		||||
        label.set_text(text);
 | 
			
		||||
        checkBox.actor.show();
 | 
			
		||||
        checkBox.show();
 | 
			
		||||
    } else {
 | 
			
		||||
        label.set_text('');
 | 
			
		||||
        checkBox.actor.hide();
 | 
			
		||||
        checkBox.hide();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -299,8 +297,8 @@ class EndSessionDialog extends ModalDialog.ModalDialog {
 | 
			
		||||
                            y_align: St.Align.START });
 | 
			
		||||
 | 
			
		||||
        this._checkBox = new CheckBox.CheckBox();
 | 
			
		||||
        this._checkBox.actor.connect('clicked', this._sync.bind(this));
 | 
			
		||||
        messageLayout.add(this._checkBox.actor);
 | 
			
		||||
        this._checkBox.connect('clicked', this._sync.bind(this));
 | 
			
		||||
        messageLayout.add(this._checkBox);
 | 
			
		||||
 | 
			
		||||
        this._batteryWarning = new St.Label({ style_class: 'end-session-dialog-warning',
 | 
			
		||||
                                              text: _("Running on battery power: please plug in before installing updates.") });
 | 
			
		||||
@@ -378,12 +376,12 @@ class EndSessionDialog extends ModalDialog.ModalDialog {
 | 
			
		||||
        let subject = dialogContent.subject;
 | 
			
		||||
 | 
			
		||||
        // Use different title when we are installing updates
 | 
			
		||||
        if (dialogContent.subjectWithUpdates && this._checkBox.actor.checked)
 | 
			
		||||
        if (dialogContent.subjectWithUpdates && this._checkBox.checked)
 | 
			
		||||
            subject = dialogContent.subjectWithUpdates;
 | 
			
		||||
 | 
			
		||||
        if (dialogContent.showBatteryWarning) {
 | 
			
		||||
            // Warn when running on battery power
 | 
			
		||||
            if (this._powerProxy.OnBattery && this._checkBox.actor.checked)
 | 
			
		||||
            if (this._powerProxy.OnBattery && this._checkBox.checked)
 | 
			
		||||
                this._batteryWarning.opacity = 255;
 | 
			
		||||
            else
 | 
			
		||||
                this._batteryWarning.opacity = 0;
 | 
			
		||||
@@ -431,7 +429,7 @@ class EndSessionDialog extends ModalDialog.ModalDialog {
 | 
			
		||||
            let avatarWidget = new UserWidget.Avatar(this._user,
 | 
			
		||||
                                                     { iconSize: _DIALOG_ICON_SIZE,
 | 
			
		||||
                                                       styleClass: dialogContent.iconStyleClass });
 | 
			
		||||
            this._iconBin.child = avatarWidget.actor;
 | 
			
		||||
            this._iconBin.child = avatarWidget;
 | 
			
		||||
            avatarWidget.update();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@@ -451,14 +449,16 @@ class EndSessionDialog extends ModalDialog.ModalDialog {
 | 
			
		||||
        for (let i = 0; i < dialogContent.confirmButtons.length; i++) {
 | 
			
		||||
            let signal = dialogContent.confirmButtons[i].signal;
 | 
			
		||||
            let label = dialogContent.confirmButtons[i].label;
 | 
			
		||||
            buttons.push({ action: () => {
 | 
			
		||||
                               this.close(true);
 | 
			
		||||
                               let signalId = this.connect('closed', () => {
 | 
			
		||||
                                   this.disconnect(signalId);
 | 
			
		||||
                                   this._confirm(signal);
 | 
			
		||||
                               });
 | 
			
		||||
                           },
 | 
			
		||||
                           label: label });
 | 
			
		||||
            buttons.push({
 | 
			
		||||
                action: () => {
 | 
			
		||||
                    this.close(true);
 | 
			
		||||
                    let signalId = this.connect('closed', () => {
 | 
			
		||||
                        this.disconnect(signalId);
 | 
			
		||||
                        this._confirm(signal);
 | 
			
		||||
                    });
 | 
			
		||||
                },
 | 
			
		||||
                label: label,
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this.setButtons(buttons);
 | 
			
		||||
@@ -485,13 +485,13 @@ class EndSessionDialog extends ModalDialog.ModalDialog {
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        // Offline update not available; just emit the signal
 | 
			
		||||
        if (!this._checkBox.actor.visible) {
 | 
			
		||||
        if (!this._checkBox.visible) {
 | 
			
		||||
            callback();
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Trigger the offline update as requested
 | 
			
		||||
        if (this._checkBox.actor.checked) {
 | 
			
		||||
        if (this._checkBox.checked) {
 | 
			
		||||
            switch (signal) {
 | 
			
		||||
            case "ConfirmedReboot":
 | 
			
		||||
                this._triggerOfflineUpdateReboot(callback);
 | 
			
		||||
@@ -565,7 +565,7 @@ class EndSessionDialog extends ModalDialog.ModalDialog {
 | 
			
		||||
        let startTime = GLib.get_monotonic_time();
 | 
			
		||||
        this._secondsLeft = this._totalSecondsToStayOpen;
 | 
			
		||||
 | 
			
		||||
        this._timerId = Mainloop.timeout_add_seconds(1, () => {
 | 
			
		||||
        this._timerId = GLib.timeout_add_seconds(GLib.PRIORITY_DEFAULT, 1, () => {
 | 
			
		||||
            let currentTime = GLib.get_monotonic_time();
 | 
			
		||||
            let secondsElapsed = ((currentTime - startTime) / 1000000);
 | 
			
		||||
 | 
			
		||||
@@ -587,7 +587,7 @@ class EndSessionDialog extends ModalDialog.ModalDialog {
 | 
			
		||||
 | 
			
		||||
    _stopTimer() {
 | 
			
		||||
        if (this._timerId > 0) {
 | 
			
		||||
            Mainloop.source_remove(this._timerId);
 | 
			
		||||
            GLib.source_remove(this._timerId);
 | 
			
		||||
            this._timerId = 0;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@@ -656,7 +656,7 @@ class EndSessionDialog extends ModalDialog.ModalDialog {
 | 
			
		||||
 | 
			
		||||
        let actor = new St.BoxLayout({ style_class: 'end-session-dialog-session-list-item',
 | 
			
		||||
                                       can_focus: true });
 | 
			
		||||
        actor.add(avatar.actor);
 | 
			
		||||
        actor.add(avatar);
 | 
			
		||||
 | 
			
		||||
        let nameLabel = new St.Label({ text: userLabelText,
 | 
			
		||||
                                       style_class: 'end-session-dialog-session-list-item-name',
 | 
			
		||||
@@ -754,14 +754,14 @@ class EndSessionDialog extends ModalDialog.ModalDialog {
 | 
			
		||||
        let updatesAllowed = this._updatesPermission && this._updatesPermission.allowed;
 | 
			
		||||
 | 
			
		||||
        _setCheckBoxLabel(this._checkBox, dialogContent.checkBoxText || '');
 | 
			
		||||
        this._checkBox.actor.visible = (dialogContent.checkBoxText && updatePrepared && updatesAllowed);
 | 
			
		||||
        this._checkBox.actor.checked = (updatePrepared && updateTriggered);
 | 
			
		||||
        this._checkBox.visible = (dialogContent.checkBoxText && updatePrepared && updatesAllowed);
 | 
			
		||||
        this._checkBox.checked = (updatePrepared && updateTriggered);
 | 
			
		||||
 | 
			
		||||
        // We show the warning either together with the checkbox, or when
 | 
			
		||||
        // updates have already been triggered, but the user doesn't have
 | 
			
		||||
        // enough permissions to cancel them.
 | 
			
		||||
        this._batteryWarning.visible = (dialogContent.showBatteryWarning &&
 | 
			
		||||
                                        (this._checkBox.actor.visible || updatePrepared && updateTriggered && !updatesAllowed));
 | 
			
		||||
                                        (this._checkBox.visible || updatePrepared && updateTriggered && !updatesAllowed));
 | 
			
		||||
 | 
			
		||||
        this._updateButtons();
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -10,7 +10,7 @@ imports.gi.versions.Gtk = '3.0';
 | 
			
		||||
imports.gi.versions.TelepathyGLib = '0.12';
 | 
			
		||||
imports.gi.versions.TelepathyLogger = '0.2';
 | 
			
		||||
 | 
			
		||||
const { Clutter, GLib, Shell, St } = imports.gi;
 | 
			
		||||
const { Clutter, GLib, Meta, Shell, St } = imports.gi;
 | 
			
		||||
const Gettext = imports.gettext;
 | 
			
		||||
 | 
			
		||||
// We can't import shell JS modules yet, because they may have
 | 
			
		||||
@@ -58,17 +58,16 @@ function _patchLayoutClass(layoutClass, styleProps) {
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function _makeEaseCallback(params) {
 | 
			
		||||
function _makeEaseCallback(params, cleanup) {
 | 
			
		||||
    let onComplete = params.onComplete;
 | 
			
		||||
    delete params.onComplete;
 | 
			
		||||
 | 
			
		||||
    let onStopped = params.onStopped;
 | 
			
		||||
    delete params.onStopped;
 | 
			
		||||
 | 
			
		||||
    if (!onComplete && !onStopped)
 | 
			
		||||
        return null;
 | 
			
		||||
 | 
			
		||||
    return isFinished => {
 | 
			
		||||
        cleanup();
 | 
			
		||||
 | 
			
		||||
        if (onStopped)
 | 
			
		||||
            onStopped(isFinished);
 | 
			
		||||
        if (onComplete && isFinished)
 | 
			
		||||
@@ -106,11 +105,22 @@ function _easeActor(actor, params) {
 | 
			
		||||
        actor.set_easing_delay(params.delay);
 | 
			
		||||
    delete params.delay;
 | 
			
		||||
 | 
			
		||||
    let repeatCount = 0;
 | 
			
		||||
    if (params.repeatCount != undefined)
 | 
			
		||||
        repeatCount = params.repeatCount;
 | 
			
		||||
    delete params.repeatCount;
 | 
			
		||||
 | 
			
		||||
    let autoReverse = false;
 | 
			
		||||
    if (params.autoReverse != undefined)
 | 
			
		||||
        autoReverse = params.autoReverse;
 | 
			
		||||
    delete params.autoReverse;
 | 
			
		||||
 | 
			
		||||
    if (params.mode != undefined)
 | 
			
		||||
        actor.set_easing_mode(params.mode);
 | 
			
		||||
    delete params.mode;
 | 
			
		||||
 | 
			
		||||
    let callback = _makeEaseCallback(params);
 | 
			
		||||
    let cleanup = () => Meta.enable_unredirect_for_display(global.display);
 | 
			
		||||
    let callback = _makeEaseCallback(params, cleanup);
 | 
			
		||||
 | 
			
		||||
    // cancel overwritten transitions
 | 
			
		||||
    let animatedProps = Object.keys(params).map(p => p.replace('_', '-', 'g'));
 | 
			
		||||
@@ -119,13 +129,19 @@ function _easeActor(actor, params) {
 | 
			
		||||
    actor.set(params);
 | 
			
		||||
    actor.restore_easing_state();
 | 
			
		||||
 | 
			
		||||
    if (callback) {
 | 
			
		||||
        let transition = actor.get_transition(animatedProps[0]);
 | 
			
		||||
    let transition = animatedProps.map(p => actor.get_transition(p))
 | 
			
		||||
        .find(t => t !== null);
 | 
			
		||||
 | 
			
		||||
        if (transition)
 | 
			
		||||
            transition.connect('stopped', (t, finished) => callback(finished));
 | 
			
		||||
        else
 | 
			
		||||
            callback(true);
 | 
			
		||||
    if (transition && transition.delay)
 | 
			
		||||
        transition.connect('started', () => Meta.disable_unredirect_for_display(global.display));
 | 
			
		||||
    else
 | 
			
		||||
        Meta.disable_unredirect_for_display(global.display);
 | 
			
		||||
 | 
			
		||||
    if (transition) {
 | 
			
		||||
        transition.set({ repeatCount, autoReverse });
 | 
			
		||||
        transition.connect('stopped', (t, finished) => callback(finished));
 | 
			
		||||
    } else {
 | 
			
		||||
        callback(true);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -139,7 +155,23 @@ function _easeActorProperty(actor, propName, target, params) {
 | 
			
		||||
        params.duration = adjustAnimationTime(params.duration);
 | 
			
		||||
    let duration = Math.floor(params.duration || 0);
 | 
			
		||||
 | 
			
		||||
    let callback = _makeEaseCallback(params);
 | 
			
		||||
    let repeatCount = 0;
 | 
			
		||||
    if (params.repeatCount != undefined)
 | 
			
		||||
        repeatCount = params.repeatCount;
 | 
			
		||||
    delete params.repeatCount;
 | 
			
		||||
 | 
			
		||||
    let autoReverse = false;
 | 
			
		||||
    if (params.autoReverse != undefined)
 | 
			
		||||
        autoReverse = params.autoReverse;
 | 
			
		||||
    delete params.autoReverse;
 | 
			
		||||
 | 
			
		||||
    // Copy Clutter's behavior for implicit animations, see
 | 
			
		||||
    // should_skip_implicit_transition()
 | 
			
		||||
    if (actor instanceof Clutter.Actor && !actor.mapped)
 | 
			
		||||
        duration = 0;
 | 
			
		||||
 | 
			
		||||
    let cleanup = () => Meta.enable_unredirect_for_display(global.display);
 | 
			
		||||
    let callback = _makeEaseCallback(params, cleanup);
 | 
			
		||||
 | 
			
		||||
    // cancel overwritten transition
 | 
			
		||||
    actor.remove_transition(propName);
 | 
			
		||||
@@ -148,8 +180,8 @@ function _easeActorProperty(actor, propName, target, params) {
 | 
			
		||||
        let [obj, prop] = _getPropertyTarget(actor, propName);
 | 
			
		||||
        obj[prop] = target;
 | 
			
		||||
 | 
			
		||||
        if (callback)
 | 
			
		||||
            callback(true);
 | 
			
		||||
        Meta.disable_unredirect_for_display(global.display);
 | 
			
		||||
        callback(true);
 | 
			
		||||
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
@@ -158,14 +190,20 @@ function _easeActorProperty(actor, propName, target, params) {
 | 
			
		||||
    let transition = new Clutter.PropertyTransition(Object.assign({
 | 
			
		||||
        property_name: propName,
 | 
			
		||||
        interval: new Clutter.Interval({ value_type: pspec.value_type }),
 | 
			
		||||
        remove_on_complete: true
 | 
			
		||||
        remove_on_complete: true,
 | 
			
		||||
        repeat_count: repeatCount,
 | 
			
		||||
        auto_reverse: autoReverse,
 | 
			
		||||
    }, params));
 | 
			
		||||
    actor.add_transition(propName, transition);
 | 
			
		||||
 | 
			
		||||
    transition.set_to(target);
 | 
			
		||||
 | 
			
		||||
    if (callback)
 | 
			
		||||
        transition.connect('stopped', (t, finished) => callback(finished));
 | 
			
		||||
    if (transition.delay)
 | 
			
		||||
        transition.connect('started', () => Meta.disable_unredirect_for_display(global.display));
 | 
			
		||||
    else
 | 
			
		||||
        Meta.disable_unredirect_for_display(global.display);
 | 
			
		||||
 | 
			
		||||
    transition.connect('stopped', (t, finished) => callback(finished));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function _loggingFunc(...args) {
 | 
			
		||||
 
 | 
			
		||||
@@ -186,14 +186,15 @@ class InstallExtensionDialog extends ModalDialog.ModalDialog {
 | 
			
		||||
        this._info = info;
 | 
			
		||||
        this._invocation = invocation;
 | 
			
		||||
 | 
			
		||||
        this.setButtons([{ label: _("Cancel"),
 | 
			
		||||
                           action: this._onCancelButtonPressed.bind(this),
 | 
			
		||||
                           key: Clutter.Escape
 | 
			
		||||
                         },
 | 
			
		||||
                         { label: _("Install"),
 | 
			
		||||
                           action: this._onInstallButtonPressed.bind(this),
 | 
			
		||||
                           default: true
 | 
			
		||||
                         }]);
 | 
			
		||||
        this.setButtons([{
 | 
			
		||||
            label: _("Cancel"),
 | 
			
		||||
            action: this._onCancelButtonPressed.bind(this),
 | 
			
		||||
            key: Clutter.Escape,
 | 
			
		||||
        }, {
 | 
			
		||||
            label: _("Install"),
 | 
			
		||||
            action: this._onInstallButtonPressed.bind(this),
 | 
			
		||||
            default: true,
 | 
			
		||||
        }]);
 | 
			
		||||
 | 
			
		||||
        let content = new Dialog.MessageDialogContent({
 | 
			
		||||
            title: _("Download and install “%s” from extensions.gnome.org?").format(info.name),
 | 
			
		||||
 
 | 
			
		||||
@@ -17,7 +17,7 @@ const EXTENSION_DISABLE_VERSION_CHECK_KEY = 'disable-extension-version-validatio
 | 
			
		||||
 | 
			
		||||
var ExtensionManager = class {
 | 
			
		||||
    constructor() {
 | 
			
		||||
        this._initted = false;
 | 
			
		||||
        this._initialized = false;
 | 
			
		||||
        this._enabled = false;
 | 
			
		||||
 | 
			
		||||
        this._extensions = new Map();
 | 
			
		||||
@@ -98,6 +98,9 @@ var ExtensionManager = class {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _callExtensionEnable(uuid) {
 | 
			
		||||
        if (!Main.sessionMode.allowExtensions)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        let extension = this.lookup(uuid);
 | 
			
		||||
        if (!extension)
 | 
			
		||||
            return;
 | 
			
		||||
@@ -108,8 +111,6 @@ var ExtensionManager = class {
 | 
			
		||||
        if (extension.state != ExtensionState.DISABLED)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        this._extensionOrder.push(uuid);
 | 
			
		||||
 | 
			
		||||
        let stylesheetNames = [`${global.session_mode}.css`, 'stylesheet.css'];
 | 
			
		||||
        let theme = St.ThemeContext.get_for_stage(global.stage).get_theme();
 | 
			
		||||
        for (let i = 0; i < stylesheetNames.length; i++) {
 | 
			
		||||
@@ -121,7 +122,7 @@ var ExtensionManager = class {
 | 
			
		||||
            } catch (e) {
 | 
			
		||||
                if (e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.NOT_FOUND))
 | 
			
		||||
                    continue; // not an error
 | 
			
		||||
                log(`Failed to load stylesheet for extension ${uuid}: ${e.message}`);
 | 
			
		||||
                this.logExtensionError(uuid, e);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
@@ -129,15 +130,14 @@ var ExtensionManager = class {
 | 
			
		||||
        try {
 | 
			
		||||
            extension.stateObj.enable();
 | 
			
		||||
            extension.state = ExtensionState.ENABLED;
 | 
			
		||||
            this._extensionOrder.push(uuid);
 | 
			
		||||
            this.emit('extension-state-changed', extension);
 | 
			
		||||
            return;
 | 
			
		||||
        } catch (e) {
 | 
			
		||||
            if (extension.stylesheet) {
 | 
			
		||||
                theme.unload_stylesheet(extension.stylesheet);
 | 
			
		||||
                delete extension.stylesheet;
 | 
			
		||||
            }
 | 
			
		||||
            this.logExtensionError(uuid, e);
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -194,7 +194,7 @@ var ExtensionManager = class {
 | 
			
		||||
            extension.errors = [];
 | 
			
		||||
        extension.errors.push(message);
 | 
			
		||||
 | 
			
		||||
        log('Extension "%s" had error: %s'.format(uuid, message));
 | 
			
		||||
        logError(error, `Extension ${uuid}`);
 | 
			
		||||
        this.emit('extension-state-changed', extension);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -286,7 +286,7 @@ var ExtensionManager = class {
 | 
			
		||||
    reloadExtension(oldExtension) {
 | 
			
		||||
        // Grab the things we'll need to pass to createExtensionObject
 | 
			
		||||
        // to reload it.
 | 
			
		||||
        let { uuid: uuid, dir: dir, type: type } = oldExtension;
 | 
			
		||||
        let { uuid, dir, type } = oldExtension;
 | 
			
		||||
 | 
			
		||||
        // Then unload the old extension.
 | 
			
		||||
        this.unloadExtension(oldExtension);
 | 
			
		||||
@@ -304,12 +304,14 @@ var ExtensionManager = class {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _callExtensionInit(uuid) {
 | 
			
		||||
        if (!Main.sessionMode.allowExtensions)
 | 
			
		||||
            return false;
 | 
			
		||||
 | 
			
		||||
        let extension = this.lookup(uuid);
 | 
			
		||||
        let dir = extension.dir;
 | 
			
		||||
 | 
			
		||||
        if (!extension)
 | 
			
		||||
            throw new Error("Extension was not properly created. Call loadExtension first");
 | 
			
		||||
            throw new Error("Extension was not properly created. Call createExtensionObject first");
 | 
			
		||||
 | 
			
		||||
        let dir = extension.dir;
 | 
			
		||||
        let extensionJs = dir.get_child('extension.js');
 | 
			
		||||
        if (!extensionJs.query_exists(null)) {
 | 
			
		||||
            this.logExtensionError(uuid, new Error('Missing extension.js'));
 | 
			
		||||
@@ -388,9 +390,6 @@ var ExtensionManager = class {
 | 
			
		||||
    _onEnabledExtensionsChanged() {
 | 
			
		||||
        let newEnabledExtensions = this._getEnabledExtensions();
 | 
			
		||||
 | 
			
		||||
        if (!this._enabled)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        // Find and enable all the newly enabled extensions: UUIDs found in the
 | 
			
		||||
        // new setting, but not in the old one.
 | 
			
		||||
        newEnabledExtensions.filter(
 | 
			
		||||
@@ -401,9 +400,9 @@ var ExtensionManager = class {
 | 
			
		||||
 | 
			
		||||
        // Find and disable all the newly disabled extensions: UUIDs found in the
 | 
			
		||||
        // old setting, but not in the new one.
 | 
			
		||||
        this._enabledExtensions.filter(
 | 
			
		||||
            item => !newEnabledExtensions.includes(item)
 | 
			
		||||
        ).forEach(uuid => {
 | 
			
		||||
        this._extensionOrder.filter(
 | 
			
		||||
            uuid => !newEnabledExtensions.includes(uuid)
 | 
			
		||||
        ).reverse().forEach(uuid => {
 | 
			
		||||
            this._callExtensionDisable(uuid);
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
@@ -418,22 +417,19 @@ var ExtensionManager = class {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _onVersionValidationChanged() {
 | 
			
		||||
        // we want to reload all extensions, but only enable
 | 
			
		||||
        // extensions when allowed by the sessionMode, so
 | 
			
		||||
        // temporarily disable them all
 | 
			
		||||
        this._enabledExtensions = [];
 | 
			
		||||
        // Disabling extensions modifies the order array, so use a copy
 | 
			
		||||
        let extensionOrder = this._extensionOrder.slice();
 | 
			
		||||
 | 
			
		||||
        // The loop modifies the extensions map, so iterate over a copy
 | 
			
		||||
        let extensions = [...this._extensions.values()];
 | 
			
		||||
        for (let extension of extensions)
 | 
			
		||||
            this.reloadExtension(extension);
 | 
			
		||||
        this._enabledExtensions = this._getEnabledExtensions();
 | 
			
		||||
        // Disable enabled extensions in the reverse order first to avoid
 | 
			
		||||
        // the "rebasing" done in _callExtensionDisable...
 | 
			
		||||
        extensionOrder.slice().reverse().forEach(uuid => {
 | 
			
		||||
            this._callExtensionDisable(uuid);
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        if (Main.sessionMode.allowExtensions) {
 | 
			
		||||
            this._enabledExtensions.forEach(uuid => {
 | 
			
		||||
                this._callExtensionEnable(uuid);
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
        // ...and then reload and enable extensions in the correct order again.
 | 
			
		||||
        [...this._extensions.values()].sort((a, b) => {
 | 
			
		||||
            return extensionOrder.indexOf(a.uuid) - extensionOrder.indexOf(b.uuid);
 | 
			
		||||
        }).forEach(extension => this.reloadExtension(extension));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _loadExtensions() {
 | 
			
		||||
@@ -482,9 +478,9 @@ var ExtensionManager = class {
 | 
			
		||||
        if (this._enabled)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        if (!this._initted) {
 | 
			
		||||
        if (!this._initialized) {
 | 
			
		||||
            this._loadExtensions();
 | 
			
		||||
            this._initted = true;
 | 
			
		||||
            this._initialized = true;
 | 
			
		||||
        } else {
 | 
			
		||||
            this._enabledExtensions.forEach(uuid => {
 | 
			
		||||
                this._callExtensionEnable(uuid);
 | 
			
		||||
@@ -497,7 +493,7 @@ var ExtensionManager = class {
 | 
			
		||||
        if (!this._enabled)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        if (this._initted) {
 | 
			
		||||
        if (this._initialized) {
 | 
			
		||||
            this._extensionOrder.slice().reverse().forEach(uuid => {
 | 
			
		||||
                this._callExtensionDisable(uuid);
 | 
			
		||||
            });
 | 
			
		||||
@@ -512,8 +508,8 @@ var ExtensionManager = class {
 | 
			
		||||
        // property; it might make sense to make enabledExtensions independent
 | 
			
		||||
        // from allowExtensions in the future
 | 
			
		||||
        if (Main.sessionMode.allowExtensions) {
 | 
			
		||||
            if (this._initted)
 | 
			
		||||
                this._enabledExtensions = this._getEnabledExtensions();
 | 
			
		||||
            // Take care of added or removed sessionMode extensions
 | 
			
		||||
            this._onEnabledExtensionsChanged();
 | 
			
		||||
            this._enableAllExtensions();
 | 
			
		||||
        } else {
 | 
			
		||||
            this._disableAllExtensions();
 | 
			
		||||
 
 | 
			
		||||
@@ -1,8 +1,7 @@
 | 
			
		||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
 | 
			
		||||
/* exported CandidatePopup */
 | 
			
		||||
 | 
			
		||||
const { Clutter, IBus, St } = imports.gi;
 | 
			
		||||
const Signals = imports.signals;
 | 
			
		||||
const { Clutter, GObject, IBus, St } = imports.gi;
 | 
			
		||||
 | 
			
		||||
const BoxPointer = imports.ui.boxpointer;
 | 
			
		||||
const Main = imports.ui.main;
 | 
			
		||||
@@ -12,11 +11,23 @@ var MAX_CANDIDATES_PER_PAGE = 16;
 | 
			
		||||
var DEFAULT_INDEX_LABELS = ['1', '2', '3', '4', '5', '6', '7', '8',
 | 
			
		||||
                            '9', '0', 'a', 'b', 'c', 'd', 'e', 'f'];
 | 
			
		||||
 | 
			
		||||
var CandidateArea = class CandidateArea {
 | 
			
		||||
    constructor() {
 | 
			
		||||
        this.actor = new St.BoxLayout({ vertical: true,
 | 
			
		||||
                                        reactive: true,
 | 
			
		||||
                                        visible: false });
 | 
			
		||||
var CandidateArea = GObject.registerClass({
 | 
			
		||||
    Signals: {
 | 
			
		||||
        'candidate-clicked': { param_types: [GObject.TYPE_UINT,
 | 
			
		||||
                                             GObject.TYPE_UINT,
 | 
			
		||||
                                             Clutter.ModifierType.$gtype] },
 | 
			
		||||
        'cursor-down': {},
 | 
			
		||||
        'cursor-up': {},
 | 
			
		||||
        'next-page': {},
 | 
			
		||||
        'previous-page': {},
 | 
			
		||||
    }
 | 
			
		||||
}, class CandidateArea extends St.BoxLayout {
 | 
			
		||||
    _init() {
 | 
			
		||||
        super._init({
 | 
			
		||||
            vertical: true,
 | 
			
		||||
            reactive: true,
 | 
			
		||||
            visible: false
 | 
			
		||||
        });
 | 
			
		||||
        this._candidateBoxes = [];
 | 
			
		||||
        for (let i = 0; i < MAX_CANDIDATES_PER_PAGE; ++i) {
 | 
			
		||||
            let box = new St.BoxLayout({ style_class: 'candidate-box',
 | 
			
		||||
@@ -27,7 +38,7 @@ var CandidateArea = class CandidateArea {
 | 
			
		||||
            box.add(box._indexLabel, { y_fill: false });
 | 
			
		||||
            box.add(box._candidateLabel, { y_fill: false });
 | 
			
		||||
            this._candidateBoxes.push(box);
 | 
			
		||||
            this.actor.add(box);
 | 
			
		||||
            this.add(box);
 | 
			
		||||
 | 
			
		||||
            let j = i;
 | 
			
		||||
            box.connect('button-release-event', (actor, event) => {
 | 
			
		||||
@@ -36,19 +47,6 @@ var CandidateArea = class CandidateArea {
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this.actor.connect('scroll-event', (actor, event) => {
 | 
			
		||||
            let direction = event.get_scroll_direction();
 | 
			
		||||
            switch (direction) {
 | 
			
		||||
            case Clutter.ScrollDirection.UP:
 | 
			
		||||
                this.emit('cursor-up');
 | 
			
		||||
                break;
 | 
			
		||||
            case Clutter.ScrollDirection.DOWN:
 | 
			
		||||
                this.emit('cursor-down');
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            return Clutter.EVENT_PROPAGATE;
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        this._buttonBox = new St.BoxLayout({ style_class: 'candidate-page-button-box' });
 | 
			
		||||
 | 
			
		||||
        this._previousButton = new St.Button({ style_class: 'candidate-page-button candidate-page-button-previous button' });
 | 
			
		||||
@@ -59,7 +57,7 @@ var CandidateArea = class CandidateArea {
 | 
			
		||||
        this._nextButton.child = new St.Icon({ style_class: 'candidate-page-button-icon' });
 | 
			
		||||
        this._buttonBox.add(this._nextButton, { expand: true });
 | 
			
		||||
 | 
			
		||||
        this.actor.add(this._buttonBox);
 | 
			
		||||
        this.add(this._buttonBox);
 | 
			
		||||
 | 
			
		||||
        this._previousButton.connect('clicked', () => {
 | 
			
		||||
            this.emit('previous-page');
 | 
			
		||||
@@ -72,6 +70,18 @@ var CandidateArea = class CandidateArea {
 | 
			
		||||
        this._cursorPosition = 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    vfunc_scroll_event(scrollEvent) {
 | 
			
		||||
        switch (scrollEvent.direction) {
 | 
			
		||||
        case Clutter.ScrollDirection.UP:
 | 
			
		||||
            this.emit('cursor-up');
 | 
			
		||||
            break;
 | 
			
		||||
        case Clutter.ScrollDirection.DOWN:
 | 
			
		||||
            this.emit('cursor-down');
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
        return Clutter.EVENT_PROPAGATE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    setOrientation(orientation) {
 | 
			
		||||
        if (this._orientation == orientation)
 | 
			
		||||
            return;
 | 
			
		||||
@@ -79,15 +89,15 @@ var CandidateArea = class CandidateArea {
 | 
			
		||||
        this._orientation = orientation;
 | 
			
		||||
 | 
			
		||||
        if (this._orientation == IBus.Orientation.HORIZONTAL) {
 | 
			
		||||
            this.actor.vertical = false;
 | 
			
		||||
            this.actor.remove_style_class_name('vertical');
 | 
			
		||||
            this.actor.add_style_class_name('horizontal');
 | 
			
		||||
            this.vertical = false;
 | 
			
		||||
            this.remove_style_class_name('vertical');
 | 
			
		||||
            this.add_style_class_name('horizontal');
 | 
			
		||||
            this._previousButton.child.icon_name = 'go-previous-symbolic';
 | 
			
		||||
            this._nextButton.child.icon_name = 'go-next-symbolic';
 | 
			
		||||
        } else {                // VERTICAL || SYSTEM
 | 
			
		||||
            this.actor.vertical = true;
 | 
			
		||||
            this.actor.add_style_class_name('vertical');
 | 
			
		||||
            this.actor.remove_style_class_name('horizontal');
 | 
			
		||||
            this.vertical = true;
 | 
			
		||||
            this.add_style_class_name('vertical');
 | 
			
		||||
            this.remove_style_class_name('horizontal');
 | 
			
		||||
            this._previousButton.child.icon_name = 'go-up-symbolic';
 | 
			
		||||
            this._nextButton.child.icon_name = 'go-down-symbolic';
 | 
			
		||||
        }
 | 
			
		||||
@@ -121,19 +131,23 @@ var CandidateArea = class CandidateArea {
 | 
			
		||||
        this._previousButton.reactive = wrapsAround || page > 0;
 | 
			
		||||
        this._nextButton.reactive = wrapsAround || page < nPages - 1;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
Signals.addSignalMethods(CandidateArea.prototype);
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
var CandidatePopup = class CandidatePopup {
 | 
			
		||||
    constructor() {
 | 
			
		||||
        this._boxPointer = new BoxPointer.BoxPointer(St.Side.TOP);
 | 
			
		||||
        this._boxPointer.visible = false;
 | 
			
		||||
        this._boxPointer.style_class = 'candidate-popup-boxpointer';
 | 
			
		||||
        Main.layoutManager.addChrome(this._boxPointer);
 | 
			
		||||
var CandidatePopup = GObject.registerClass(
 | 
			
		||||
class IbusCandidatePopup extends BoxPointer.BoxPointer {
 | 
			
		||||
    _init() {
 | 
			
		||||
        super._init(St.Side.TOP);
 | 
			
		||||
        this.visible = false;
 | 
			
		||||
        this.style_class = 'candidate-popup-boxpointer';
 | 
			
		||||
 | 
			
		||||
        this._dummyCursor = new St.Widget({ opacity: 0 });
 | 
			
		||||
        Main.layoutManager.uiGroup.add_actor(this._dummyCursor);
 | 
			
		||||
 | 
			
		||||
        Main.layoutManager.addChrome(this);
 | 
			
		||||
 | 
			
		||||
        let box = new St.BoxLayout({ style_class: 'candidate-popup-content',
 | 
			
		||||
                                     vertical: true });
 | 
			
		||||
        this._boxPointer.bin.set_child(box);
 | 
			
		||||
        this.bin.set_child(box);
 | 
			
		||||
 | 
			
		||||
        this._preeditText = new St.Label({ style_class: 'candidate-popup-text',
 | 
			
		||||
                                           visible: false });
 | 
			
		||||
@@ -144,7 +158,7 @@ var CandidatePopup = class CandidatePopup {
 | 
			
		||||
        box.add(this._auxText);
 | 
			
		||||
 | 
			
		||||
        this._candidateArea = new CandidateArea();
 | 
			
		||||
        box.add(this._candidateArea.actor);
 | 
			
		||||
        box.add(this._candidateArea);
 | 
			
		||||
 | 
			
		||||
        this._candidateArea.connect('previous-page', () => {
 | 
			
		||||
            this._panelService.page_up();
 | 
			
		||||
@@ -222,7 +236,7 @@ var CandidatePopup = class CandidatePopup {
 | 
			
		||||
            this._updateVisibility();
 | 
			
		||||
        });
 | 
			
		||||
        panelService.connect('update-lookup-table', (_ps, lookupTable, visible) => {
 | 
			
		||||
            this._candidateArea.actor.visible = visible;
 | 
			
		||||
            this._candidateArea.visible = visible;
 | 
			
		||||
            this._updateVisibility();
 | 
			
		||||
 | 
			
		||||
            let nCandidates = lookupTable.get_number_of_candidates();
 | 
			
		||||
@@ -258,37 +272,39 @@ var CandidatePopup = class CandidatePopup {
 | 
			
		||||
            this._candidateArea.updateButtons(lookupTable.is_round(), page, nPages);
 | 
			
		||||
        });
 | 
			
		||||
        panelService.connect('show-lookup-table', () => {
 | 
			
		||||
            this._candidateArea.actor.show();
 | 
			
		||||
            this._candidateArea.show();
 | 
			
		||||
            this._updateVisibility();
 | 
			
		||||
        });
 | 
			
		||||
        panelService.connect('hide-lookup-table', () => {
 | 
			
		||||
            this._candidateArea.actor.hide();
 | 
			
		||||
            this._candidateArea.hide();
 | 
			
		||||
            this._updateVisibility();
 | 
			
		||||
        });
 | 
			
		||||
        panelService.connect('focus-out', () => {
 | 
			
		||||
            this._boxPointer.close(BoxPointer.PopupAnimation.NONE);
 | 
			
		||||
            this.close(BoxPointer.PopupAnimation.NONE);
 | 
			
		||||
            Main.keyboard.resetSuggestions();
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _setDummyCursorGeometry(x, y, w, h) {
 | 
			
		||||
        Main.layoutManager.setDummyCursorGeometry(x, y, w, h);
 | 
			
		||||
        if (this._boxPointer.visible)
 | 
			
		||||
            this._boxPointer.setPosition(Main.layoutManager.dummyCursor, 0);
 | 
			
		||||
        this._dummyCursor.set_position(Math.round(x), Math.round(y));
 | 
			
		||||
        this._dummyCursor.set_size(Math.round(w), Math.round(h));
 | 
			
		||||
 | 
			
		||||
        if (this.visible)
 | 
			
		||||
            this.setPosition(this._dummyCursor, 0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _updateVisibility() {
 | 
			
		||||
        let isVisible = (!Main.keyboard.visible &&
 | 
			
		||||
                         (this._preeditText.visible ||
 | 
			
		||||
                          this._auxText.visible ||
 | 
			
		||||
                          this._candidateArea.actor.visible));
 | 
			
		||||
                          this._candidateArea.visible));
 | 
			
		||||
 | 
			
		||||
        if (isVisible) {
 | 
			
		||||
            this._boxPointer.setPosition(Main.layoutManager.dummyCursor, 0);
 | 
			
		||||
            this._boxPointer.open(BoxPointer.PopupAnimation.NONE);
 | 
			
		||||
            this._boxPointer.raise_top();
 | 
			
		||||
            this.setPosition(this._dummyCursor, 0);
 | 
			
		||||
            this.open(BoxPointer.PopupAnimation.NONE);
 | 
			
		||||
            this.raise_top();
 | 
			
		||||
        } else {
 | 
			
		||||
            this._boxPointer.close(BoxPointer.PopupAnimation.NONE);
 | 
			
		||||
            this.close(BoxPointer.PopupAnimation.NONE);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -298,4 +314,4 @@ var CandidatePopup = class CandidatePopup {
 | 
			
		||||
            if (attr.get_attr_type() == IBus.AttrType.BACKGROUND)
 | 
			
		||||
                clutterText.set_selection(attr.get_start_index(), attr.get_end_index());
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,7 @@
 | 
			
		||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
 | 
			
		||||
/* exported BaseIcon, IconGrid, PaginatedIconGrid */
 | 
			
		||||
 | 
			
		||||
const { Clutter, GLib, GObject, Meta, St } = imports.gi;
 | 
			
		||||
const { Clutter, GLib, GObject, Graphene, Meta, St } = imports.gi;
 | 
			
		||||
 | 
			
		||||
const Params = imports.misc.params;
 | 
			
		||||
const Main = imports.ui.main;
 | 
			
		||||
@@ -142,6 +142,10 @@ class BaseIcon extends St.Bin {
 | 
			
		||||
        zoomOutActor(this.child);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    animateZoomOutAtPos(x, y) {
 | 
			
		||||
        zoomOutActorAtPos(this.child, x, y);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    update() {
 | 
			
		||||
        this._createIconTexture(this.iconSize);
 | 
			
		||||
    }
 | 
			
		||||
@@ -152,10 +156,15 @@ function clamp(value, min, max) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function zoomOutActor(actor) {
 | 
			
		||||
    let [x, y] = actor.get_transformed_position();
 | 
			
		||||
    zoomOutActorAtPos(actor, x, y);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function zoomOutActorAtPos(actor, x, y) {
 | 
			
		||||
    let actorClone = new Clutter.Clone({ source: actor,
 | 
			
		||||
                                         reactive: false });
 | 
			
		||||
    let [width, height] = actor.get_transformed_size();
 | 
			
		||||
    let [x, y] = actor.get_transformed_position();
 | 
			
		||||
 | 
			
		||||
    actorClone.set_size(width, height);
 | 
			
		||||
    actorClone.set_position(x, y);
 | 
			
		||||
    actorClone.opacity = 255;
 | 
			
		||||
@@ -222,18 +231,18 @@ var IconGrid = GObject.registerClass({
 | 
			
		||||
        this._fixedHItemSize = this._fixedVItemSize = undefined;
 | 
			
		||||
        this.connect('style-changed', this._onStyleChanged.bind(this));
 | 
			
		||||
 | 
			
		||||
        // Cancel animations when hiding the overview, to avoid icons
 | 
			
		||||
        // swarming into the void ...
 | 
			
		||||
        this.connect('notify::mapped', () => {
 | 
			
		||||
            if (!this.mapped)
 | 
			
		||||
                this._resetAnimationActors();
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        this.connect('actor-added', this._childAdded.bind(this));
 | 
			
		||||
        this.connect('actor-removed', this._childRemoved.bind(this));
 | 
			
		||||
        this.connect('destroy', this._onDestroy.bind(this));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    vfunc_unmap() {
 | 
			
		||||
        // Cancel animations when hiding the overview, to avoid icons
 | 
			
		||||
        // swarming into the void ...
 | 
			
		||||
        this._resetAnimationActors();
 | 
			
		||||
        super.vfunc_unmap();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _onDestroy() {
 | 
			
		||||
        if (this._updateIconSizesLaterId) {
 | 
			
		||||
            Meta.later_remove (this._updateIconSizesLaterId);
 | 
			
		||||
@@ -247,10 +256,23 @@ var IconGrid = GObject.registerClass({
 | 
			
		||||
 | 
			
		||||
    _childAdded(grid, child) {
 | 
			
		||||
        child._iconGridKeyFocusInId = child.connect('key-focus-in', this._keyFocusIn.bind(this));
 | 
			
		||||
 | 
			
		||||
        child._paintVisible = child.opacity > 0;
 | 
			
		||||
        child._opacityChangedId = child.connect('notify::opacity', () => {
 | 
			
		||||
            let paintVisible = child._paintVisible;
 | 
			
		||||
            child._paintVisible = child.opacity > 0;
 | 
			
		||||
            if (paintVisible !== child._paintVisible)
 | 
			
		||||
                this.queue_relayout();
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _childRemoved(grid, child) {
 | 
			
		||||
        child.disconnect(child._iconGridKeyFocusInId);
 | 
			
		||||
        delete child._iconGridKeyFocusInId;
 | 
			
		||||
 | 
			
		||||
        child.disconnect(child._opacityChangedId);
 | 
			
		||||
        delete child._opacityChangedId;
 | 
			
		||||
        delete child._paintVisible;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    vfunc_get_preferred_width(_forHeight) {
 | 
			
		||||
@@ -260,9 +282,9 @@ var IconGrid = GObject.registerClass({
 | 
			
		||||
            return [0, 0];
 | 
			
		||||
 | 
			
		||||
        let nChildren = this.get_n_children();
 | 
			
		||||
        let nColumns = this._colLimit ? Math.min(this._colLimit,
 | 
			
		||||
                                                 nChildren)
 | 
			
		||||
                                      : nChildren;
 | 
			
		||||
        let nColumns = this._colLimit
 | 
			
		||||
            ? Math.min(this._colLimit, nChildren)
 | 
			
		||||
            : nChildren;
 | 
			
		||||
        let totalSpacing = Math.max(0, nColumns - 1) * this._getSpacing();
 | 
			
		||||
        // Kind of a lie, but not really an issue right now.  If
 | 
			
		||||
        // we wanted to support some sort of hidden/overflow that would
 | 
			
		||||
@@ -380,7 +402,7 @@ var IconGrid = GObject.registerClass({
 | 
			
		||||
        let allocationBox = this.get_allocation_box();
 | 
			
		||||
        let paintBox = themeNode.get_paint_box(allocationBox);
 | 
			
		||||
 | 
			
		||||
        let origin = new Clutter.Vertex();
 | 
			
		||||
        let origin = new Graphene.Point3D();
 | 
			
		||||
        origin.x = paintBox.x1 - allocationBox.x1;
 | 
			
		||||
        origin.y = paintBox.y1 - allocationBox.y1;
 | 
			
		||||
        origin.z = 0.0;
 | 
			
		||||
@@ -414,7 +436,7 @@ var IconGrid = GObject.registerClass({
 | 
			
		||||
     * set of items to be animated.
 | 
			
		||||
     */
 | 
			
		||||
    _getChildrenToAnimate() {
 | 
			
		||||
        return this._getVisibleChildren();
 | 
			
		||||
        return this._getVisibleChildren().filter(child => child.opacity > 0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _resetAnimationActors() {
 | 
			
		||||
@@ -695,13 +717,13 @@ var IconGrid = GObject.registerClass({
 | 
			
		||||
 | 
			
		||||
        this._items.push(item);
 | 
			
		||||
        if (index !== undefined)
 | 
			
		||||
            this.insert_child_at_index(item.actor, index);
 | 
			
		||||
            this.insert_child_at_index(item, index);
 | 
			
		||||
        else
 | 
			
		||||
            this.add_actor(item.actor);
 | 
			
		||||
            this.add_actor(item);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    removeItem(item) {
 | 
			
		||||
        this.remove_child(item.actor);
 | 
			
		||||
        this.remove_child(item);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    getItemAtIndex(index) {
 | 
			
		||||
@@ -774,8 +796,9 @@ var IconGrid = GObject.registerClass({
 | 
			
		||||
            let neededWidth = this.usedWidthForNColumns(this._minColumns) - availWidth;
 | 
			
		||||
            let neededHeight = this.usedHeightForNRows(this._minRows) - availHeight;
 | 
			
		||||
 | 
			
		||||
            let neededSpacePerItem = (neededWidth > neededHeight) ? Math.ceil(neededWidth / this._minColumns)
 | 
			
		||||
                                                                  : Math.ceil(neededHeight / this._minRows);
 | 
			
		||||
            let neededSpacePerItem = (neededWidth > neededHeight)
 | 
			
		||||
                ? Math.ceil(neededWidth / this._minColumns)
 | 
			
		||||
                : Math.ceil(neededHeight / this._minRows);
 | 
			
		||||
            this._fixedHItemSize = Math.max(this._hItemSize - neededSpacePerItem, MIN_ICON_SIZE);
 | 
			
		||||
            this._fixedVItemSize = Math.max(this._vItemSize - neededSpacePerItem, MIN_ICON_SIZE);
 | 
			
		||||
 | 
			
		||||
@@ -871,7 +894,7 @@ var PaginatedIconGrid = GObject.registerClass({
 | 
			
		||||
 | 
			
		||||
    // Overridden from IconGrid
 | 
			
		||||
    _getChildrenToAnimate() {
 | 
			
		||||
        let children = this._getVisibleChildren();
 | 
			
		||||
        let children = super._getChildrenToAnimate();
 | 
			
		||||
        let firstIndex = this._childrenPerPage * this.currentPage;
 | 
			
		||||
        let lastIndex = firstIndex + this._childrenPerPage;
 | 
			
		||||
 | 
			
		||||
@@ -940,7 +963,7 @@ var PaginatedIconGrid = GObject.registerClass({
 | 
			
		||||
    */
 | 
			
		||||
    openExtraSpace(sourceItem, side, nRows) {
 | 
			
		||||
        let children = this._getVisibleChildren();
 | 
			
		||||
        let index = children.indexOf(sourceItem.actor);
 | 
			
		||||
        let index = children.indexOf(sourceItem);
 | 
			
		||||
        if (index == -1)
 | 
			
		||||
            throw new Error('Item not found.');
 | 
			
		||||
 | 
			
		||||
@@ -950,8 +973,7 @@ var PaginatedIconGrid = GObject.registerClass({
 | 
			
		||||
        let childrenPerRow = this._childrenPerPage / this._rowsPerPage;
 | 
			
		||||
        let sourceRow = Math.floor((index - pageOffset) / childrenPerRow);
 | 
			
		||||
 | 
			
		||||
        let nRowsAbove = (side == St.Side.TOP) ? sourceRow + 1
 | 
			
		||||
                                               : sourceRow;
 | 
			
		||||
        let nRowsAbove = (side == St.Side.TOP) ? sourceRow + 1 : sourceRow;
 | 
			
		||||
        let nRowsBelow = this._rowsPerPage - nRowsAbove;
 | 
			
		||||
 | 
			
		||||
        let nRowsUp, nRowsDown;
 | 
			
		||||
 
 | 
			
		||||
@@ -76,8 +76,9 @@ var InhibitShortcutsDialog = GObject.registerClass({
 | 
			
		||||
        let name = this._app ? this._app.get_name() : this._window.title;
 | 
			
		||||
 | 
			
		||||
        /* Translators: %s is an application name like "Settings" */
 | 
			
		||||
        let title = name ? _("%s wants to inhibit shortcuts").format(name)
 | 
			
		||||
                         : _("Application wants to inhibit shortcuts");
 | 
			
		||||
        let title = name
 | 
			
		||||
            ? _("%s wants to inhibit shortcuts").format(name)
 | 
			
		||||
            : _("Application wants to inhibit shortcuts");
 | 
			
		||||
        let icon = new Gio.ThemedIcon({ name: 'dialog-warning-symbolic' });
 | 
			
		||||
 | 
			
		||||
        let contentParams = { icon, title };
 | 
			
		||||
 
 | 
			
		||||
@@ -27,24 +27,24 @@ class KbdA11yDialog extends GObject.Object {
 | 
			
		||||
 | 
			
		||||
        if (whatChanged & Clutter.KeyboardA11yFlags.SLOW_KEYS_ENABLED) {
 | 
			
		||||
            key = KEY_SLOW_KEYS_ENABLED;
 | 
			
		||||
            enabled = (newFlags & Clutter.KeyboardA11yFlags.SLOW_KEYS_ENABLED) ? true : false;
 | 
			
		||||
            title = enabled ?
 | 
			
		||||
                    _("Slow Keys Turned On") :
 | 
			
		||||
                    _("Slow Keys Turned Off");
 | 
			
		||||
            enabled = (newFlags & Clutter.KeyboardA11yFlags.SLOW_KEYS_ENABLED) > 0;
 | 
			
		||||
            title = enabled
 | 
			
		||||
                ? _("Slow Keys Turned On")
 | 
			
		||||
                : _("Slow Keys Turned Off");
 | 
			
		||||
            body = _("You just held down the Shift key for 8 seconds. This is the shortcut " +
 | 
			
		||||
                     "for the Slow Keys feature, which affects the way your keyboard works.");
 | 
			
		||||
 | 
			
		||||
        } else  if (whatChanged & Clutter.KeyboardA11yFlags.STICKY_KEYS_ENABLED) {
 | 
			
		||||
            key = KEY_STICKY_KEYS_ENABLED;
 | 
			
		||||
            enabled = (newFlags & Clutter.KeyboardA11yFlags.STICKY_KEYS_ENABLED) ? true : false;
 | 
			
		||||
            title = enabled ?
 | 
			
		||||
                    _("Sticky Keys Turned On") :
 | 
			
		||||
                    _("Sticky Keys Turned Off");
 | 
			
		||||
            body = enabled ?
 | 
			
		||||
                   _("You just pressed the Shift key 5 times in a row. This is the shortcut " +
 | 
			
		||||
                     "for the Sticky Keys feature, which affects the way your keyboard works.") :
 | 
			
		||||
                   _("You just pressed two keys at once, or pressed the Shift key 5 times in a row. " +
 | 
			
		||||
                     "This turns off the Sticky Keys feature, which affects the way your keyboard works.");
 | 
			
		||||
            enabled = (newFlags & Clutter.KeyboardA11yFlags.STICKY_KEYS_ENABLED) > 0;
 | 
			
		||||
            title = enabled
 | 
			
		||||
                ? _("Sticky Keys Turned On")
 | 
			
		||||
                : _("Sticky Keys Turned Off");
 | 
			
		||||
            body = enabled
 | 
			
		||||
                ? _("You just pressed the Shift key 5 times in a row. This is the shortcut " +
 | 
			
		||||
                  "for the Sticky Keys feature, which affects the way your keyboard works.")
 | 
			
		||||
                : _("You just pressed two keys at once, or pressed the Shift key 5 times in a row. " +
 | 
			
		||||
                  "This turns off the Sticky Keys feature, which affects the way your keyboard works.");
 | 
			
		||||
        } else {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
 | 
			
		||||
/* exported Keyboard */
 | 
			
		||||
/* exported KeyboardManager */
 | 
			
		||||
 | 
			
		||||
const { Clutter, Gio, GLib, GObject, Meta, St } = imports.gi;
 | 
			
		||||
const Signals = imports.signals;
 | 
			
		||||
@@ -89,8 +89,11 @@ class KeyContainer extends St.Widget {
 | 
			
		||||
        let gridLayout = new Clutter.GridLayout({ orientation: Clutter.Orientation.HORIZONTAL,
 | 
			
		||||
                                                  column_homogeneous: true,
 | 
			
		||||
                                                  row_homogeneous: true });
 | 
			
		||||
        super._init({ layout_manager: gridLayout,
 | 
			
		||||
                      x_expand: true, y_expand: true });
 | 
			
		||||
        super._init({
 | 
			
		||||
            layout_manager: gridLayout,
 | 
			
		||||
            x_expand: true,
 | 
			
		||||
            y_expand: true
 | 
			
		||||
        });
 | 
			
		||||
        this._gridLayout = gridLayout;
 | 
			
		||||
        this._currentRow = 0;
 | 
			
		||||
        this._currentCol = 0;
 | 
			
		||||
@@ -104,9 +107,10 @@ class KeyContainer extends St.Widget {
 | 
			
		||||
        this._currentRow++;
 | 
			
		||||
        this._currentCol = 0;
 | 
			
		||||
 | 
			
		||||
        let row = new Object();
 | 
			
		||||
        row.keys = [];
 | 
			
		||||
        row.width = 0;
 | 
			
		||||
        let row = {
 | 
			
		||||
            keys: [],
 | 
			
		||||
            width: 0,
 | 
			
		||||
        };
 | 
			
		||||
        this._rows.push(row);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -160,24 +164,23 @@ class KeyContainer extends St.Widget {
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
var Suggestions = class {
 | 
			
		||||
    constructor() {
 | 
			
		||||
        this.actor = new St.BoxLayout({ style_class: 'word-suggestions',
 | 
			
		||||
                                        vertical: false });
 | 
			
		||||
        this.actor.show();
 | 
			
		||||
var Suggestions = GObject.registerClass(
 | 
			
		||||
class Suggestions extends St.BoxLayout {
 | 
			
		||||
    _init() {
 | 
			
		||||
        super._init({ style_class: 'word-suggestions', vertical: false });
 | 
			
		||||
        this.show();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    add(word, callback) {
 | 
			
		||||
        let button = new St.Button({ label: word });
 | 
			
		||||
        button.connect('clicked', callback);
 | 
			
		||||
        this.actor.add(button);
 | 
			
		||||
        this.add(button);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    clear() {
 | 
			
		||||
        this.actor.remove_all_children();
 | 
			
		||||
        this.remove_all_children();
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
Signals.addSignalMethods(Suggestions.prototype);
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
var LanguageSelectionPopup = class extends PopupMenu.PopupMenu {
 | 
			
		||||
    constructor(actor) {
 | 
			
		||||
@@ -193,12 +196,12 @@ var LanguageSelectionPopup = class extends PopupMenu.PopupMenu {
 | 
			
		||||
            item = this.addAction(is.displayName, () => {
 | 
			
		||||
                inputSourceManager.activateInputSource(is, true);
 | 
			
		||||
            });
 | 
			
		||||
            item.actor.can_focus = false;
 | 
			
		||||
            item.can_focus = false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
 | 
			
		||||
        item = this.addSettingsAction(_("Region & Language Settings"), 'gnome-region-panel.desktop');
 | 
			
		||||
        item.actor.can_focus = false;
 | 
			
		||||
        item.can_focus = false;
 | 
			
		||||
 | 
			
		||||
        this._capturedEventId = 0;
 | 
			
		||||
 | 
			
		||||
@@ -242,17 +245,25 @@ var LanguageSelectionPopup = class extends PopupMenu.PopupMenu {
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
var Key = class Key {
 | 
			
		||||
    constructor(key, extendedKeys) {
 | 
			
		||||
var Key = GObject.registerClass({
 | 
			
		||||
    Signals: {
 | 
			
		||||
        'activated': {},
 | 
			
		||||
        'long-press': {},
 | 
			
		||||
        'pressed': { param_types: [GObject.TYPE_UINT, GObject.TYPE_STRING] },
 | 
			
		||||
        'released': { param_types: [GObject.TYPE_UINT, GObject.TYPE_STRING] },
 | 
			
		||||
    }
 | 
			
		||||
}, class Key extends St.BoxLayout {
 | 
			
		||||
    _init(key, extendedKeys) {
 | 
			
		||||
        super._init({ style_class: 'key-container' });
 | 
			
		||||
 | 
			
		||||
        this.key = key || "";
 | 
			
		||||
        this.keyButton = this._makeKey(this.key);
 | 
			
		||||
 | 
			
		||||
        /* Add the key in a container, so keys can be padded without losing
 | 
			
		||||
         * logical proportions between those.
 | 
			
		||||
         */
 | 
			
		||||
        this.actor = new St.BoxLayout ({ style_class: 'key-container' });
 | 
			
		||||
        this.actor.add(this.keyButton, { expand: true, x_fill: true });
 | 
			
		||||
        this.actor.connect('destroy', this._onDestroy.bind(this));
 | 
			
		||||
        this.add(this.keyButton, { expand: true, x_fill: true });
 | 
			
		||||
        this.connect('destroy', this._onDestroy.bind(this));
 | 
			
		||||
 | 
			
		||||
        this._extended_keys = extendedKeys;
 | 
			
		||||
        this._extended_keyboard = null;
 | 
			
		||||
@@ -460,8 +471,7 @@ var Key = class Key {
 | 
			
		||||
        else
 | 
			
		||||
            this.keyButton.remove_style_pseudo_class('latched');
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
Signals.addSignalMethods(Key.prototype);
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
var KeyboardModel = class {
 | 
			
		||||
    constructor(groupName) {
 | 
			
		||||
@@ -589,7 +599,6 @@ var EmojiPager = GObject.registerClass({
 | 
			
		||||
            reactive: true,
 | 
			
		||||
            clip_to_allocation: true
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        this._sections = sections;
 | 
			
		||||
        this._nCols = nCols;
 | 
			
		||||
        this._nRows = nRows;
 | 
			
		||||
@@ -800,7 +809,7 @@ var EmojiPager = GObject.registerClass({
 | 
			
		||||
                this.emit('emoji', str);
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            gridLayout.attach(key.actor, col, row, 1, 1);
 | 
			
		||||
            gridLayout.attach(key, col, row, 1, 1);
 | 
			
		||||
 | 
			
		||||
            col++;
 | 
			
		||||
            if (col >= this._nCols) {
 | 
			
		||||
@@ -842,7 +851,7 @@ var EmojiPager = GObject.registerClass({
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let page = this._pages[nPage];
 | 
			
		||||
        this.emit('page-changed', page.section, page.page, page.nPages);
 | 
			
		||||
        this.emit('page-changed', page.section.label, page.page, page.nPages);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    setCurrentSection(section, nPage) {
 | 
			
		||||
@@ -857,8 +866,21 @@ var EmojiPager = GObject.registerClass({
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
var EmojiSelection = class EmojiSelection {
 | 
			
		||||
    constructor() {
 | 
			
		||||
var EmojiSelection = GObject.registerClass({
 | 
			
		||||
    Signals: {
 | 
			
		||||
        'emoji-selected': { param_types: [GObject.TYPE_STRING] },
 | 
			
		||||
        'close-request': {},
 | 
			
		||||
        'toggle': {},
 | 
			
		||||
    }
 | 
			
		||||
}, class EmojiSelection extends St.BoxLayout {
 | 
			
		||||
    _init() {
 | 
			
		||||
        super._init({
 | 
			
		||||
            style_class: 'emoji-panel',
 | 
			
		||||
            x_expand: true,
 | 
			
		||||
            y_expand: true,
 | 
			
		||||
            vertical: true
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        this._sections = [
 | 
			
		||||
            { first: 'grinning face', label: '🙂️' },
 | 
			
		||||
            { first: 'selfie', label: '👍️' },
 | 
			
		||||
@@ -873,38 +895,44 @@ var EmojiSelection = class EmojiSelection {
 | 
			
		||||
 | 
			
		||||
        this._populateSections();
 | 
			
		||||
 | 
			
		||||
        this.actor = new St.BoxLayout({ style_class: 'emoji-panel',
 | 
			
		||||
                                        x_expand: true,
 | 
			
		||||
                                        y_expand: true,
 | 
			
		||||
                                        vertical: true });
 | 
			
		||||
        this.actor.connect('notify::mapped', () => this._emojiPager.setCurrentPage(0));
 | 
			
		||||
 | 
			
		||||
        this._emojiPager = new EmojiPager(this._sections, 11, 3);
 | 
			
		||||
        this._emojiPager.connect('page-changed', (pager, section, page, nPages) => {
 | 
			
		||||
            this._onPageChanged(section, page, nPages);
 | 
			
		||||
        this._emojiPager.connect('page-changed', (pager, sectionLabel, page, nPages) => {
 | 
			
		||||
            this._onPageChanged(sectionLabel, page, nPages);
 | 
			
		||||
        });
 | 
			
		||||
        this._emojiPager.connect('emoji', (pager, str) => {
 | 
			
		||||
            this.emit('emoji-selected', str);
 | 
			
		||||
        });
 | 
			
		||||
        this.actor.add(this._emojiPager.actor, { expand: true });
 | 
			
		||||
        this.add(this._emojiPager, { expand: true });
 | 
			
		||||
 | 
			
		||||
        this._pageIndicator = new PageIndicators.PageIndicators(false);
 | 
			
		||||
        this.actor.add(this._pageIndicator, { expand: true, x_fill: false, y_fill: false });
 | 
			
		||||
        this._pageIndicator = new PageIndicators.PageIndicators(
 | 
			
		||||
            Clutter.Orientation.HORIZONTAL
 | 
			
		||||
        );
 | 
			
		||||
        this.add(this._pageIndicator, { expand: true, x_fill: false, y_fill: false });
 | 
			
		||||
        this._pageIndicator.setReactive(false);
 | 
			
		||||
 | 
			
		||||
        let bottomRow = this._createBottomRow();
 | 
			
		||||
        this.actor.add(bottomRow, { expand: true, x_fill: false, y_fill: false });
 | 
			
		||||
        this.add(bottomRow, { expand: true, x_fill: false, y_fill: false });
 | 
			
		||||
 | 
			
		||||
        this._emojiPager.setCurrentPage(0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _onPageChanged(section, page, nPages) {
 | 
			
		||||
    vfunc_map() {
 | 
			
		||||
        this._emojiPager.setCurrentPage(0);
 | 
			
		||||
        super.vfunc_map();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    vfunc_unmap() {
 | 
			
		||||
        super.vfunc_unmap();
 | 
			
		||||
        this._emojiPager.setCurrentPage(0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _onPageChanged(sectionLabel, page, nPages) {
 | 
			
		||||
        this._pageIndicator.setNPages(nPages);
 | 
			
		||||
        this._pageIndicator.setCurrentPage(page);
 | 
			
		||||
 | 
			
		||||
        for (let i = 0; i < this._sections.length; i++) {
 | 
			
		||||
            let sect = this._sections[i];
 | 
			
		||||
            sect.button.setLatched(section == sect);
 | 
			
		||||
            sect.button.setLatched(sectionLabel == sect.label);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -960,14 +988,14 @@ var EmojiSelection = class EmojiSelection {
 | 
			
		||||
        key = new Key('ABC', []);
 | 
			
		||||
        key.keyButton.add_style_class_name('default-key');
 | 
			
		||||
        key.connect('released', () => this.emit('toggle'));
 | 
			
		||||
        row.appendKey(key.actor, 1.5);
 | 
			
		||||
        row.appendKey(key, 1.5);
 | 
			
		||||
 | 
			
		||||
        for (let i = 0; i < this._sections.length; i++) {
 | 
			
		||||
            let section = this._sections[i];
 | 
			
		||||
 | 
			
		||||
            key = new Key(section.label, []);
 | 
			
		||||
            key.connect('released', () => this._emojiPager.setCurrentSection(section, 0));
 | 
			
		||||
            row.appendKey(key.actor);
 | 
			
		||||
            row.appendKey(key);
 | 
			
		||||
 | 
			
		||||
            section.button = key;
 | 
			
		||||
        }
 | 
			
		||||
@@ -976,9 +1004,9 @@ var EmojiSelection = class EmojiSelection {
 | 
			
		||||
        key.keyButton.add_style_class_name('default-key');
 | 
			
		||||
        key.keyButton.add_style_class_name('hide-key');
 | 
			
		||||
        key.connect('released', () => {
 | 
			
		||||
            this.emit('hide');
 | 
			
		||||
            this.emit('close-request');
 | 
			
		||||
        });
 | 
			
		||||
        row.appendKey(key.actor);
 | 
			
		||||
        row.appendKey(key);
 | 
			
		||||
        row.layoutButtons();
 | 
			
		||||
 | 
			
		||||
        let actor = new AspectContainer({ layout_manager: new Clutter.BinLayout(),
 | 
			
		||||
@@ -992,11 +1020,14 @@ var EmojiSelection = class EmojiSelection {
 | 
			
		||||
 | 
			
		||||
        return actor;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
Signals.addSignalMethods(EmojiSelection.prototype);
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
var Keypad = class Keypad {
 | 
			
		||||
    constructor() {
 | 
			
		||||
var Keypad = GObject.registerClass({
 | 
			
		||||
    Signals: {
 | 
			
		||||
        'keyval': { param_types: [GObject.TYPE_UINT] },
 | 
			
		||||
    }
 | 
			
		||||
}, class Keypad extends AspectContainer {
 | 
			
		||||
    _init() {
 | 
			
		||||
        let keys = [
 | 
			
		||||
            { label: '1', keyval: Clutter.KEY_1, left: 0, top: 0 },
 | 
			
		||||
            { label: '2', keyval: Clutter.KEY_2, left: 1, top: 0 },
 | 
			
		||||
@@ -1012,14 +1043,17 @@ var Keypad = class Keypad {
 | 
			
		||||
            { keyval: Clutter.KEY_Return, extraClassName: 'enter-key', left: 3, top: 1, height: 2 },
 | 
			
		||||
        ];
 | 
			
		||||
 | 
			
		||||
        this.actor = new AspectContainer({ layout_manager: new Clutter.BinLayout(),
 | 
			
		||||
                                           x_expand: true, y_expand: true });
 | 
			
		||||
        super._init({
 | 
			
		||||
            layout_manager: new Clutter.BinLayout(),
 | 
			
		||||
            x_expand: true,
 | 
			
		||||
            y_expand: true
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        let gridLayout = new Clutter.GridLayout({ orientation: Clutter.Orientation.HORIZONTAL,
 | 
			
		||||
                                                  column_homogeneous: true,
 | 
			
		||||
                                                  row_homogeneous: true });
 | 
			
		||||
        this._box = new St.Widget({ layout_manager: gridLayout, x_expand: true, y_expand: true });
 | 
			
		||||
        this.actor.add_child(this._box);
 | 
			
		||||
        this.add_child(this._box);
 | 
			
		||||
 | 
			
		||||
        for (let i = 0; i < keys.length; i++) {
 | 
			
		||||
            let cur = keys[i];
 | 
			
		||||
@@ -1031,86 +1065,32 @@ var Keypad = class Keypad {
 | 
			
		||||
            let w, h;
 | 
			
		||||
            w = cur.width || 1;
 | 
			
		||||
            h = cur.height || 1;
 | 
			
		||||
            gridLayout.attach(key.actor, cur.left, cur.top, w, h);
 | 
			
		||||
            gridLayout.attach(key, cur.left, cur.top, w, h);
 | 
			
		||||
 | 
			
		||||
            key.connect('released', () => {
 | 
			
		||||
                this.emit('keyval', cur.keyval);
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
Signals.addSignalMethods(Keypad.prototype);
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
var Keyboard = class Keyboard {
 | 
			
		||||
var KeyboardManager = class KeyBoardManager {
 | 
			
		||||
    constructor() {
 | 
			
		||||
        this.actor = null;
 | 
			
		||||
        this._focusInExtendedKeys = false;
 | 
			
		||||
        this._emojiActive = false;
 | 
			
		||||
 | 
			
		||||
        this._languagePopup = null;
 | 
			
		||||
        this._currentFocusWindow = null;
 | 
			
		||||
        this._animFocusedWindow = null;
 | 
			
		||||
        this._delayedAnimFocusWindow = null;
 | 
			
		||||
 | 
			
		||||
        this._enableKeyboard = false; // a11y settings value
 | 
			
		||||
        this._enabled = false; // enabled state (by setting or device type)
 | 
			
		||||
        this._latched = false; // current level is latched
 | 
			
		||||
 | 
			
		||||
        this._keyboard = null;
 | 
			
		||||
        this._a11yApplicationsSettings = new Gio.Settings({ schema_id: A11Y_APPLICATIONS_SCHEMA });
 | 
			
		||||
        this._a11yApplicationsSettings.connect('changed', this._syncEnabled.bind(this));
 | 
			
		||||
 | 
			
		||||
        this._lastDeviceId = null;
 | 
			
		||||
        this._suggestions = null;
 | 
			
		||||
        this._emojiKeyVisible = Meta.is_wayland_compositor();
 | 
			
		||||
        Meta.get_backend().connect('last-device-changed', (backend, deviceId) => {
 | 
			
		||||
            let manager = Clutter.DeviceManager.get_default();
 | 
			
		||||
            let device = manager.get_device(deviceId);
 | 
			
		||||
 | 
			
		||||
        this._focusTracker = new FocusTracker();
 | 
			
		||||
        this._focusTracker.connect('position-changed', this._onFocusPositionChanged.bind(this));
 | 
			
		||||
        this._focusTracker.connect('reset', () => {
 | 
			
		||||
            this._delayedAnimFocusWindow = null;
 | 
			
		||||
            this._animFocusedWindow = null;
 | 
			
		||||
            this._oskFocusWindow = null;
 | 
			
		||||
            if (device.get_device_name().indexOf('XTEST') < 0) {
 | 
			
		||||
                this._lastDeviceId = deviceId;
 | 
			
		||||
                this._syncEnabled();
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
        this._focusTracker.connect('focus-changed', (tracker, focused) => {
 | 
			
		||||
            // Valid only for X11
 | 
			
		||||
            if (Meta.is_wayland_compositor())
 | 
			
		||||
                return;
 | 
			
		||||
 | 
			
		||||
            if (focused)
 | 
			
		||||
                this.show(Main.layoutManager.focusIndex);
 | 
			
		||||
            else
 | 
			
		||||
                this.hide();
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        Meta.get_backend().connect('last-device-changed', 
 | 
			
		||||
            (backend, deviceId) => {
 | 
			
		||||
                let manager = Clutter.DeviceManager.get_default();
 | 
			
		||||
                let device = manager.get_device(deviceId);
 | 
			
		||||
 | 
			
		||||
                if (!device.get_device_name().includes('XTEST')) {
 | 
			
		||||
                    this._lastDeviceId = deviceId;
 | 
			
		||||
                    this._syncEnabled();
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
        this._syncEnabled();
 | 
			
		||||
 | 
			
		||||
        this._showIdleId = 0;
 | 
			
		||||
 | 
			
		||||
        this._keyboardVisible = false;
 | 
			
		||||
        Main.layoutManager.connect('keyboard-visible-changed', (o, visible) => {
 | 
			
		||||
            this._keyboardVisible = visible;
 | 
			
		||||
        });
 | 
			
		||||
        this._keyboardRequested = false;
 | 
			
		||||
        this._keyboardRestingId = 0;
 | 
			
		||||
 | 
			
		||||
        Main.layoutManager.connect('monitors-changed', this._relayout.bind(this));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    get visible() {
 | 
			
		||||
        return this._keyboardVisible;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _onFocusPositionChanged(focusTracker) {
 | 
			
		||||
        let rect = focusTracker.getCurrentRect();
 | 
			
		||||
        this.setCursorLocation(focusTracker.currentWindow, rect.x, rect.y, rect.width, rect.height);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _lastDeviceIsTouchscreen() {
 | 
			
		||||
@@ -1127,38 +1107,143 @@ var Keyboard = class Keyboard {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _syncEnabled() {
 | 
			
		||||
        let wasEnabled = this._enabled;
 | 
			
		||||
        this._enableKeyboard = this._a11yApplicationsSettings.get_boolean(SHOW_KEYBOARD);
 | 
			
		||||
        this._enabled = this._enableKeyboard || this._lastDeviceIsTouchscreen();
 | 
			
		||||
        if (!this._enabled && !this._keyboardController)
 | 
			
		||||
        let enableKeyboard = this._a11yApplicationsSettings.get_boolean(SHOW_KEYBOARD);
 | 
			
		||||
        let enabled = enableKeyboard || this._lastDeviceIsTouchscreen();
 | 
			
		||||
        if (!enabled && !this._keyboard)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        if (this._enabled && !this._keyboardController)
 | 
			
		||||
            this._setupKeyboard();
 | 
			
		||||
        else if (!this._enabled)
 | 
			
		||||
            this.setCursorLocation(null);
 | 
			
		||||
 | 
			
		||||
        if (!this._enabled && wasEnabled)
 | 
			
		||||
        if (enabled && !this._keyboard) {
 | 
			
		||||
            this._keyboard = new Keyboard();
 | 
			
		||||
        } else if (!enabled && this._keyboard) {
 | 
			
		||||
            this._keyboard.setCursorLocation(null);
 | 
			
		||||
            Main.layoutManager.hideKeyboard(true);
 | 
			
		||||
            this._keyboard.destroy();
 | 
			
		||||
            this._keyboard = null;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _destroyKeyboard() {
 | 
			
		||||
        if (this._keyboardNotifyId)
 | 
			
		||||
            this._keyboardController.disconnect(this._keyboardNotifyId);
 | 
			
		||||
        if (this._keyboardGroupsChangedId)
 | 
			
		||||
            this._keyboardController.disconnect(this._keyboardGroupsChangedId);
 | 
			
		||||
        if (this._keyboardStateId)
 | 
			
		||||
            this._keyboardController.disconnect(this._keyboardStateId);
 | 
			
		||||
        if (this._emojiKeyVisibleId)
 | 
			
		||||
            this._keyboardController.disconnect(this._emojiKeyVisibleId);
 | 
			
		||||
        if (this._keypadVisibleId)
 | 
			
		||||
            this._keyboardController.disconnect(this._keypadVisibleId);
 | 
			
		||||
        if (this._focusNotifyId)
 | 
			
		||||
            global.stage.disconnect(this._focusNotifyId);
 | 
			
		||||
    get keyboardActor() {
 | 
			
		||||
        return this._keyboard;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    get visible() {
 | 
			
		||||
        return this._keyboard && this._keyboard.visible;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    open(monitor) {
 | 
			
		||||
        if (this._keyboard)
 | 
			
		||||
            this._keyboard.open(monitor);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    close() {
 | 
			
		||||
        if (this._keyboard)
 | 
			
		||||
            this._keyboard.close();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    addSuggestion(text, callback) {
 | 
			
		||||
        if (this._keyboard)
 | 
			
		||||
            this._keyboard.addSuggestion(text, callback);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    resetSuggestions() {
 | 
			
		||||
        if (this._keyboard)
 | 
			
		||||
            this._keyboard.resetSuggestions();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    shouldTakeEvent(event) {
 | 
			
		||||
        if (!this._keyboard)
 | 
			
		||||
            return false;
 | 
			
		||||
 | 
			
		||||
        let actor = event.get_source();
 | 
			
		||||
        return Main.layoutManager.keyboardBox.contains(actor) ||
 | 
			
		||||
               !!actor._extended_keys || !!actor.extended_key;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
var Keyboard = GObject.registerClass(
 | 
			
		||||
class Keyboard extends St.BoxLayout {
 | 
			
		||||
    _init() {
 | 
			
		||||
        super._init({ name: 'keyboard', vertical: true });
 | 
			
		||||
        this._focusInExtendedKeys = false;
 | 
			
		||||
        this._emojiActive = false;
 | 
			
		||||
 | 
			
		||||
        this._languagePopup = null;
 | 
			
		||||
        this._currentFocusWindow = null;
 | 
			
		||||
        this._animFocusedWindow = null;
 | 
			
		||||
        this._delayedAnimFocusWindow = null;
 | 
			
		||||
 | 
			
		||||
        this._latched = false; // current level is latched
 | 
			
		||||
 | 
			
		||||
        this._suggestions = null;
 | 
			
		||||
        this._emojiKeyVisible = Meta.is_wayland_compositor();
 | 
			
		||||
 | 
			
		||||
        this._focusTracker = new FocusTracker();
 | 
			
		||||
        this._connectSignal(this._focusTracker, 'position-changed',
 | 
			
		||||
            this._onFocusPositionChanged.bind(this));
 | 
			
		||||
        this._connectSignal(this._focusTracker, 'reset', () => {
 | 
			
		||||
            this._delayedAnimFocusWindow = null;
 | 
			
		||||
            this._animFocusedWindow = null;
 | 
			
		||||
            this._oskFocusWindow = null;
 | 
			
		||||
        });
 | 
			
		||||
        // Valid only for X11
 | 
			
		||||
        if (!Meta.is_wayland_compositor()) {
 | 
			
		||||
            this._connectSignal(this._focusTracker, 'focus-changed', (_tracker, focused) => {
 | 
			
		||||
                if (focused)
 | 
			
		||||
                    this.open(Main.layoutManager.focusIndex);
 | 
			
		||||
                else
 | 
			
		||||
                    this.close();
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this._showIdleId = 0;
 | 
			
		||||
 | 
			
		||||
        this._keyboardVisible = false;
 | 
			
		||||
        this._connectSignal(Main.layoutManager, 'keyboard-visible-changed', (_lm, visible) => {
 | 
			
		||||
            this._keyboardVisible = visible;
 | 
			
		||||
        });
 | 
			
		||||
        this._keyboardRequested = false;
 | 
			
		||||
        this._keyboardRestingId = 0;
 | 
			
		||||
 | 
			
		||||
        this._connectSignal(Main.layoutManager, 'monitors-changed', this._relayout.bind(this));
 | 
			
		||||
 | 
			
		||||
        this._setupKeyboard();
 | 
			
		||||
 | 
			
		||||
        this.connect('destroy', this._onDestroy.bind(this));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _connectSignal(obj, signal, callback) {
 | 
			
		||||
        if (!this._connectionsIDs)
 | 
			
		||||
            this._connectionsIDs = [];
 | 
			
		||||
 | 
			
		||||
        let id = obj.connect(signal, callback);
 | 
			
		||||
        this._connectionsIDs.push([obj, id]);
 | 
			
		||||
        return id;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    get visible() {
 | 
			
		||||
        return this._keyboardVisible && super.visible;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _onFocusPositionChanged(focusTracker) {
 | 
			
		||||
        let rect = focusTracker.getCurrentRect();
 | 
			
		||||
        this.setCursorLocation(focusTracker.currentWindow, rect.x, rect.y, rect.width, rect.height);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _onDestroy() {
 | 
			
		||||
        for (let [obj, id] of this._connectionsIDs)
 | 
			
		||||
            obj.disconnect(id);
 | 
			
		||||
        delete this._connectionsIDs;
 | 
			
		||||
 | 
			
		||||
        this._clearShowIdle();
 | 
			
		||||
        this._keyboard = null;
 | 
			
		||||
        this.actor.destroy();
 | 
			
		||||
        this.actor = null;
 | 
			
		||||
 | 
			
		||||
        this._keyboardController = null;
 | 
			
		||||
        this._suggestions = null;
 | 
			
		||||
        this._aspectContainer = null;
 | 
			
		||||
        this._emojiSelection = null;
 | 
			
		||||
        this._keypad = null;
 | 
			
		||||
 | 
			
		||||
        Main.layoutManager.untrackChrome(this);
 | 
			
		||||
        Main.layoutManager.keyboardBox.remove_actor(this);
 | 
			
		||||
 | 
			
		||||
        if (this._languagePopup) {
 | 
			
		||||
            this._languagePopup.destroy();
 | 
			
		||||
@@ -1167,9 +1252,8 @@ var Keyboard = class Keyboard {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _setupKeyboard() {
 | 
			
		||||
        this.actor = new St.BoxLayout({ name: 'keyboard', vertical: true, reactive: true });
 | 
			
		||||
        Main.layoutManager.keyboardBox.add_actor(this.actor);
 | 
			
		||||
        Main.layoutManager.trackChrome(this.actor);
 | 
			
		||||
        Main.layoutManager.keyboardBox.add_actor(this);
 | 
			
		||||
        Main.layoutManager.trackChrome(this);
 | 
			
		||||
 | 
			
		||||
        this._keyboardController = new KeyboardController();
 | 
			
		||||
 | 
			
		||||
@@ -1177,30 +1261,28 @@ var Keyboard = class Keyboard {
 | 
			
		||||
        this._currentPage = null;
 | 
			
		||||
 | 
			
		||||
        this._suggestions = new Suggestions();
 | 
			
		||||
        this.actor.add(this._suggestions.actor,
 | 
			
		||||
                       { x_align: St.Align.MIDDLE,
 | 
			
		||||
                         x_fill: false });
 | 
			
		||||
        this.add(this._suggestions, { x_align: St.Align.MIDDLE, x_fill: false });
 | 
			
		||||
 | 
			
		||||
        this._aspectContainer = new AspectContainer({ layout_manager: new Clutter.BinLayout() });
 | 
			
		||||
        this.actor.add(this._aspectContainer, { expand: true });
 | 
			
		||||
        this.add(this._aspectContainer, { expand: true });
 | 
			
		||||
 | 
			
		||||
        this._emojiSelection = new EmojiSelection();
 | 
			
		||||
        this._emojiSelection.connect('toggle', this._toggleEmoji.bind(this));
 | 
			
		||||
        this._emojiSelection.connect('hide', () => this.hide());
 | 
			
		||||
        this._emojiSelection.connect('close-request', () => this.close());
 | 
			
		||||
        this._emojiSelection.connect('emoji-selected', (selection, emoji) => {
 | 
			
		||||
            this._keyboardController.commitString(emoji);
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        this._aspectContainer.add_child(this._emojiSelection.actor);
 | 
			
		||||
        this._emojiSelection.actor.hide();
 | 
			
		||||
        this._aspectContainer.add_child(this._emojiSelection);
 | 
			
		||||
        this._emojiSelection.hide();
 | 
			
		||||
 | 
			
		||||
        this._keypad = new Keypad();
 | 
			
		||||
        this._keypad.connect('keyval', (keypad, keyval) => {
 | 
			
		||||
        this._connectSignal(this._keypad, 'keyval', (_keypad, keyval) => {
 | 
			
		||||
            this._keyboardController.keyvalPress(keyval);
 | 
			
		||||
            this._keyboardController.keyvalRelease(keyval);
 | 
			
		||||
        });
 | 
			
		||||
        this._aspectContainer.add_child(this._keypad.actor);
 | 
			
		||||
        this._keypad.actor.hide();
 | 
			
		||||
        this._aspectContainer.add_child(this._keypad);
 | 
			
		||||
        this._keypad.hide();
 | 
			
		||||
        this._keypadVisible = false;
 | 
			
		||||
 | 
			
		||||
        this._ensureKeysForGroup(this._keyboardController.getCurrentGroup());
 | 
			
		||||
@@ -1209,16 +1291,22 @@ var Keyboard = class Keyboard {
 | 
			
		||||
        // Keyboard models are defined in LTR, we must override
 | 
			
		||||
        // the locale setting in order to avoid flipping the
 | 
			
		||||
        // keyboard on RTL locales.
 | 
			
		||||
        this.actor.text_direction = Clutter.TextDirection.LTR;
 | 
			
		||||
        this.text_direction = Clutter.TextDirection.LTR;
 | 
			
		||||
 | 
			
		||||
        this._keyboardNotifyId = this._keyboardController.connect('active-group', this._onGroupChanged.bind(this));
 | 
			
		||||
        this._keyboardGroupsChangedId = this._keyboardController.connect('groups-changed', this._onKeyboardGroupsChanged.bind(this));
 | 
			
		||||
        this._keyboardStateId = this._keyboardController.connect('panel-state', this._onKeyboardStateChanged.bind(this));
 | 
			
		||||
        this._keypadVisibleId = this._keyboardController.connect('keypad-visible', this._onKeypadVisible.bind(this));
 | 
			
		||||
        this._focusNotifyId = global.stage.connect('notify::key-focus', this._onKeyFocusChanged.bind(this));
 | 
			
		||||
        this._connectSignal(this._keyboardController, 'active-group',
 | 
			
		||||
            this._onGroupChanged.bind(this));
 | 
			
		||||
        this._connectSignal(this._keyboardController, 'groups-changed',
 | 
			
		||||
            this._onKeyboardGroupsChanged.bind(this));
 | 
			
		||||
        this._connectSignal(this._keyboardController, 'panel-state',
 | 
			
		||||
            this._onKeyboardStateChanged.bind(this));
 | 
			
		||||
        this._connectSignal(this._keyboardController, 'keypad-visible',
 | 
			
		||||
            this._onKeypadVisible.bind(this));
 | 
			
		||||
        this._connectSignal(global.stage, 'notify::key-focus',
 | 
			
		||||
            this._onKeyFocusChanged.bind(this));
 | 
			
		||||
 | 
			
		||||
        if (Meta.is_wayland_compositor())
 | 
			
		||||
            this._emojiKeyVisibleId = this._keyboardController.connect('emoji-visible', this._onEmojiKeyVisible.bind(this));
 | 
			
		||||
            this._connectSignal(this._keyboardController, 'emoji-visible',
 | 
			
		||||
                this._onEmojiKeyVisible.bind(this));
 | 
			
		||||
 | 
			
		||||
        this._relayout();
 | 
			
		||||
    }
 | 
			
		||||
@@ -1234,17 +1322,17 @@ var Keyboard = class Keyboard {
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        if (!(focus instanceof Clutter.Text)) {
 | 
			
		||||
            this.hide();
 | 
			
		||||
            this.close();
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!this._showIdleId) {
 | 
			
		||||
            this._showIdleId = GLib.idle_add(GLib.PRIORITY_DEFAULT_IDLE, () => {
 | 
			
		||||
                this.show(Main.layoutManager.focusIndex);
 | 
			
		||||
                this.open(Main.layoutManager.focusIndex);
 | 
			
		||||
                this._showIdleId = 0;
 | 
			
		||||
                return GLib.SOURCE_REMOVE;
 | 
			
		||||
            });
 | 
			
		||||
            GLib.Source.set_name_by_id(this._showIdleId, '[gnome-shell] this.show');
 | 
			
		||||
            GLib.Source.set_name_by_id(this._showIdleId, '[gnome-shell] this.open');
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -1308,7 +1396,7 @@ var Keyboard = class Keyboard {
 | 
			
		||||
                    this._setActiveLayer(0);
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            layout.appendKey(button.actor, button.keyButton.keyWidth);
 | 
			
		||||
            layout.appendKey(button, button.keyButton.keyWidth);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -1356,7 +1444,7 @@ var Keyboard = class Keyboard {
 | 
			
		||||
                if (keyval != null)
 | 
			
		||||
                    this._keyboardController.keyvalRelease(keyval);
 | 
			
		||||
                else if (action == 'hide')
 | 
			
		||||
                    this.hide();
 | 
			
		||||
                    this.close();
 | 
			
		||||
                else if (action == 'languageMenu')
 | 
			
		||||
                    this._popupLanguageMenu(actor);
 | 
			
		||||
                else if (action == 'emoji')
 | 
			
		||||
@@ -1379,7 +1467,7 @@ var Keyboard = class Keyboard {
 | 
			
		||||
                    /* Only hide the key actor, so the container still takes space */
 | 
			
		||||
                    extraButton.keyButton.hide();
 | 
			
		||||
                } else {
 | 
			
		||||
                    extraButton.actor.hide();
 | 
			
		||||
                    extraButton.hide();
 | 
			
		||||
                }
 | 
			
		||||
                extraButton.setWidth(1.5);
 | 
			
		||||
            } else if (key.right && numKeys > 8) {
 | 
			
		||||
@@ -1390,7 +1478,7 @@ var Keyboard = class Keyboard {
 | 
			
		||||
                extraButton.setWidth(1.5);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            layout.appendKey(extraButton.actor, extraButton.keyButton.keyWidth);
 | 
			
		||||
            layout.appendKey(extraButton, extraButton.keyButton.keyWidth);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -1401,7 +1489,7 @@ var Keyboard = class Keyboard {
 | 
			
		||||
 | 
			
		||||
    _setEmojiActive(active) {
 | 
			
		||||
        this._emojiActive = active;
 | 
			
		||||
        this._emojiSelection.actor.visible = this._emojiActive;
 | 
			
		||||
        this._emojiSelection.visible = this._emojiActive;
 | 
			
		||||
        this._updateCurrentPageVisible();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -1469,12 +1557,12 @@ var Keyboard = class Keyboard {
 | 
			
		||||
    _relayout() {
 | 
			
		||||
        let monitor = Main.layoutManager.keyboardMonitor;
 | 
			
		||||
 | 
			
		||||
        if (this.actor == null || monitor == null)
 | 
			
		||||
        if (!monitor)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        let maxHeight = monitor.height / 3;
 | 
			
		||||
        this.actor.width = monitor.width;
 | 
			
		||||
        this.actor.height = maxHeight;
 | 
			
		||||
        this.width = monitor.width;
 | 
			
		||||
        this.height = maxHeight;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _onGroupChanged() {
 | 
			
		||||
@@ -1483,7 +1571,7 @@ var Keyboard = class Keyboard {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _onKeyboardGroupsChanged() {
 | 
			
		||||
        let nonGroupActors = [this._emojiSelection.actor, this._keypad.actor];
 | 
			
		||||
        let nonGroupActors = [this._emojiSelection, this._keypad];
 | 
			
		||||
        this._aspectContainer.get_children().filter(c => !nonGroupActors.includes(c)).forEach(c => {
 | 
			
		||||
            c.destroy();
 | 
			
		||||
        });
 | 
			
		||||
@@ -1497,7 +1585,7 @@ var Keyboard = class Keyboard {
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        this._keypadVisible = visible;
 | 
			
		||||
        this._keypad.actor.visible = this._keypadVisible;
 | 
			
		||||
        this._keypad.visible = this._keypadVisible;
 | 
			
		||||
        this._updateCurrentPageVisible();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -1522,9 +1610,9 @@ var Keyboard = class Keyboard {
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        if (enabled)
 | 
			
		||||
            this.show(Main.layoutManager.focusIndex);
 | 
			
		||||
            this.open(Main.layoutManager.focusIndex);
 | 
			
		||||
        else
 | 
			
		||||
            this.hide();
 | 
			
		||||
            this.close();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _setActiveLayer(activeLevel) {
 | 
			
		||||
@@ -1551,12 +1639,6 @@ var Keyboard = class Keyboard {
 | 
			
		||||
        this._updateCurrentPageVisible();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    shouldTakeEvent(event) {
 | 
			
		||||
        let actor = event.get_source();
 | 
			
		||||
        return Main.layoutManager.keyboardBox.contains(actor) ||
 | 
			
		||||
               !!actor._extended_keys || !!actor.extended_key;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _clearKeyboardRestTimer() {
 | 
			
		||||
        if (!this._keyboardRestingId)
 | 
			
		||||
            return;
 | 
			
		||||
@@ -1564,10 +1646,7 @@ var Keyboard = class Keyboard {
 | 
			
		||||
        this._keyboardRestingId = 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    show(monitor) {
 | 
			
		||||
        if (!this._enabled)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
    open(monitor) {
 | 
			
		||||
        this._clearShowIdle();
 | 
			
		||||
        this._keyboardRequested = true;
 | 
			
		||||
 | 
			
		||||
@@ -1584,13 +1663,13 @@ var Keyboard = class Keyboard {
 | 
			
		||||
                                                   KEYBOARD_REST_TIME,
 | 
			
		||||
                                                   () => {
 | 
			
		||||
                                                       this._clearKeyboardRestTimer();
 | 
			
		||||
                                                       this._show(monitor);
 | 
			
		||||
                                                       this._open(monitor);
 | 
			
		||||
                                                       return GLib.SOURCE_REMOVE;
 | 
			
		||||
                                                   });
 | 
			
		||||
        GLib.Source.set_name_by_id(this._keyboardRestingId, '[gnome-shell] this._clearKeyboardRestTimer');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _show(monitor) {
 | 
			
		||||
    _open(monitor) {
 | 
			
		||||
        if (!this._keyboardRequested)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
@@ -1606,10 +1685,7 @@ var Keyboard = class Keyboard {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    hide() {
 | 
			
		||||
        if (!this._enabled)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
    close() {
 | 
			
		||||
        this._clearShowIdle();
 | 
			
		||||
        this._keyboardRequested = false;
 | 
			
		||||
 | 
			
		||||
@@ -1621,13 +1697,13 @@ var Keyboard = class Keyboard {
 | 
			
		||||
                                                   KEYBOARD_REST_TIME,
 | 
			
		||||
                                                   () => {
 | 
			
		||||
                                                       this._clearKeyboardRestTimer();
 | 
			
		||||
                                                       this._hide();
 | 
			
		||||
                                                       this._close();
 | 
			
		||||
                                                       return GLib.SOURCE_REMOVE;
 | 
			
		||||
                                                   });
 | 
			
		||||
        GLib.Source.set_name_by_id(this._keyboardRestingId, '[gnome-shell] this._clearKeyboardRestTimer');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _hide() {
 | 
			
		||||
    _close() {
 | 
			
		||||
        if (this._keyboardRequested)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
@@ -1644,7 +1720,7 @@ var Keyboard = class Keyboard {
 | 
			
		||||
        if (!this._suggestions)
 | 
			
		||||
            return;
 | 
			
		||||
        this._suggestions.add(text, callback);
 | 
			
		||||
        this._suggestions.actor.show();
 | 
			
		||||
        this._suggestions.show();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _clearShowIdle() {
 | 
			
		||||
@@ -1721,7 +1797,7 @@ var Keyboard = class Keyboard {
 | 
			
		||||
 | 
			
		||||
        this._oskFocusWindow = window;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
var KeyboardController = class {
 | 
			
		||||
    constructor() {
 | 
			
		||||
 
 | 
			
		||||
@@ -238,11 +238,12 @@ var LayoutManager = GObject.registerClass({
 | 
			
		||||
                                             reactive: true });
 | 
			
		||||
        this.addChrome(this.overviewGroup);
 | 
			
		||||
 | 
			
		||||
        this.screenShieldGroup = new St.Widget({ name: 'screenShieldGroup',
 | 
			
		||||
                                                 visible: false,
 | 
			
		||||
                                                 clip_to_allocation: true,
 | 
			
		||||
                                                 layout_manager: new Clutter.BinLayout(),
 | 
			
		||||
                                               });
 | 
			
		||||
        this.screenShieldGroup = new St.Widget({
 | 
			
		||||
            name: 'screenShieldGroup',
 | 
			
		||||
            visible: false,
 | 
			
		||||
            clip_to_allocation: true,
 | 
			
		||||
            layout_manager: new Clutter.BinLayout(),
 | 
			
		||||
        });
 | 
			
		||||
        this.addChrome(this.screenShieldGroup);
 | 
			
		||||
 | 
			
		||||
        this.panelBox = new St.BoxLayout({ name: 'panelBox',
 | 
			
		||||
@@ -605,17 +606,17 @@ var LayoutManager = GObject.registerClass({
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        this._systemBackground = new Background.SystemBackground();
 | 
			
		||||
        this._systemBackground.actor.hide();
 | 
			
		||||
        this._systemBackground.hide();
 | 
			
		||||
 | 
			
		||||
        global.stage.insert_child_below(this._systemBackground.actor, null);
 | 
			
		||||
        global.stage.insert_child_below(this._systemBackground, null);
 | 
			
		||||
 | 
			
		||||
        let constraint = new Clutter.BindConstraint({ source: global.stage,
 | 
			
		||||
                                                      coordinate: Clutter.BindCoordinate.ALL });
 | 
			
		||||
        this._systemBackground.actor.add_constraint(constraint);
 | 
			
		||||
        this._systemBackground.add_constraint(constraint);
 | 
			
		||||
 | 
			
		||||
        let signalId = this._systemBackground.connect('loaded', () => {
 | 
			
		||||
            this._systemBackground.disconnect(signalId);
 | 
			
		||||
            this._systemBackground.actor.show();
 | 
			
		||||
            this._systemBackground.show();
 | 
			
		||||
            global.stage.show();
 | 
			
		||||
 | 
			
		||||
            this._prepareStartupAnimation();
 | 
			
		||||
@@ -721,7 +722,7 @@ var LayoutManager = GObject.registerClass({
 | 
			
		||||
        this._coverPane.destroy();
 | 
			
		||||
        this._coverPane = null;
 | 
			
		||||
 | 
			
		||||
        this._systemBackground.actor.destroy();
 | 
			
		||||
        this._systemBackground.destroy();
 | 
			
		||||
        this._systemBackground = null;
 | 
			
		||||
 | 
			
		||||
        this._startingUp = false;
 | 
			
		||||
@@ -770,8 +771,7 @@ var LayoutManager = GObject.registerClass({
 | 
			
		||||
        this.keyboardBox.ease({
 | 
			
		||||
            anchor_y: 0,
 | 
			
		||||
            opacity: 0,
 | 
			
		||||
            duration: immediate ? 0
 | 
			
		||||
                                : KEYBOARD_ANIMATION_TIME,
 | 
			
		||||
            duration: immediate ? 0 : KEYBOARD_ANIMATION_TIME,
 | 
			
		||||
            mode: Clutter.AnimationMode.EASE_IN_QUAD,
 | 
			
		||||
            onComplete: () => {
 | 
			
		||||
                this._hideKeyboardComplete();
 | 
			
		||||
@@ -855,12 +855,13 @@ var LayoutManager = GObject.registerClass({
 | 
			
		||||
            index = this._findActor(ancestor);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let ancestorData = ancestor ? this._trackedActors[index]
 | 
			
		||||
                                    : defaultParams;
 | 
			
		||||
        let ancestorData = ancestor
 | 
			
		||||
            ? this._trackedActors[index]
 | 
			
		||||
            : defaultParams;
 | 
			
		||||
        // We can't use Params.parse here because we want to drop
 | 
			
		||||
        // the extra values like ancestorData.actor
 | 
			
		||||
        for (let prop in defaultParams) {
 | 
			
		||||
            if (!params.hasOwnProperty(prop))
 | 
			
		||||
            if (!Object.prototype.hasOwnProperty.call(params, prop))
 | 
			
		||||
                params[prop] = ancestorData[prop];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@@ -1014,11 +1015,6 @@ var LayoutManager = GObject.registerClass({
 | 
			
		||||
        if (Main.modalCount > 0)
 | 
			
		||||
            return GLib.SOURCE_REMOVE;
 | 
			
		||||
 | 
			
		||||
        // Bug workaround - get_transformed_position()/get_transformed_size() don't work after
 | 
			
		||||
        // a change in stage size until the first pick or paint.
 | 
			
		||||
        // https://bugzilla.gnome.org/show_bug.cgi?id=761565
 | 
			
		||||
        global.stage.get_actor_at_pos(Clutter.PickMode.ALL, 0, 0);
 | 
			
		||||
 | 
			
		||||
        let rects = [], struts = [], i;
 | 
			
		||||
        let isPopupMenuVisible = global.top_window_group.get_children().some(isPopupMetaWindow);
 | 
			
		||||
        let wantsInputRegion = !isPopupMenuVisible;
 | 
			
		||||
@@ -1074,16 +1070,17 @@ var LayoutManager = GObject.registerClass({
 | 
			
		||||
                        side = Meta.Side.RIGHT;
 | 
			
		||||
                    else
 | 
			
		||||
                        continue;
 | 
			
		||||
                } else if (x1 <= monitor.x)
 | 
			
		||||
                } else if (x1 <= monitor.x) {
 | 
			
		||||
                    side = Meta.Side.LEFT;
 | 
			
		||||
                else if (y1 <= monitor.y)
 | 
			
		||||
                } else if (y1 <= monitor.y) {
 | 
			
		||||
                    side = Meta.Side.TOP;
 | 
			
		||||
                else if (x2 >= monitor.x + monitor.width)
 | 
			
		||||
                } else if (x2 >= monitor.x + monitor.width) {
 | 
			
		||||
                    side = Meta.Side.RIGHT;
 | 
			
		||||
                else if (y2 >= monitor.y + monitor.height)
 | 
			
		||||
                } else if (y2 >= monitor.y + monitor.height) {
 | 
			
		||||
                    side = Meta.Side.BOTTOM;
 | 
			
		||||
                else
 | 
			
		||||
                } else {
 | 
			
		||||
                    continue;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                let strutRect = new Meta.Rectangle({ x: x1, y: y1, width: x2 - x1, height: y2 - y1 });
 | 
			
		||||
                let strut = new Meta.Strut({ rect: strutRect, side: side });
 | 
			
		||||
@@ -1115,8 +1112,11 @@ var LayoutManager = GObject.registerClass({
 | 
			
		||||
//
 | 
			
		||||
// This class manages a "hot corner" that can toggle switching to
 | 
			
		||||
// overview.
 | 
			
		||||
var HotCorner = class HotCorner {
 | 
			
		||||
    constructor(layoutManager, monitor, x, y) {
 | 
			
		||||
var HotCorner = GObject.registerClass(
 | 
			
		||||
class HotCorner extends Clutter.Actor {
 | 
			
		||||
    _init(layoutManager, monitor, x, y) {
 | 
			
		||||
        super._init();
 | 
			
		||||
 | 
			
		||||
        // We use this flag to mark the case where the user has entered the
 | 
			
		||||
        // hot corner and has not left both the hot corner and a surrounding
 | 
			
		||||
        // guard area (the "environs"). This avoids triggering the hot corner
 | 
			
		||||
@@ -1145,6 +1145,8 @@ var HotCorner = class HotCorner {
 | 
			
		||||
 | 
			
		||||
        this._ripples = new Ripples.Ripples(px, py, 'ripple-box');
 | 
			
		||||
        this._ripples.addTo(layoutManager.uiGroup);
 | 
			
		||||
 | 
			
		||||
        this.connect('destroy', this._onDestroy.bind(this));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    setBarrierSize(size) {
 | 
			
		||||
@@ -1184,11 +1186,14 @@ var HotCorner = class HotCorner {
 | 
			
		||||
 | 
			
		||||
    _setupFallbackCornerIfNeeded(layoutManager) {
 | 
			
		||||
        if (!global.display.supports_extended_barriers()) {
 | 
			
		||||
            this.actor = new Clutter.Actor({ name: 'hot-corner-environs',
 | 
			
		||||
                                             x: this._x, y: this._y,
 | 
			
		||||
                                             width: 3,
 | 
			
		||||
                                             height: 3,
 | 
			
		||||
                                             reactive: true });
 | 
			
		||||
            this.set({
 | 
			
		||||
                name: 'hot-corner-environs',
 | 
			
		||||
                x: this._x,
 | 
			
		||||
                y: this._y,
 | 
			
		||||
                width: 3,
 | 
			
		||||
                height: 3,
 | 
			
		||||
                reactive: true
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            this._corner = new Clutter.Actor({ name: 'hot-corner',
 | 
			
		||||
                                               width: 1,
 | 
			
		||||
@@ -1197,19 +1202,16 @@ var HotCorner = class HotCorner {
 | 
			
		||||
                                               reactive: true });
 | 
			
		||||
            this._corner._delegate = this;
 | 
			
		||||
 | 
			
		||||
            this.actor.add_child(this._corner);
 | 
			
		||||
            layoutManager.addChrome(this.actor);
 | 
			
		||||
            this.add_child(this._corner);
 | 
			
		||||
            layoutManager.addChrome(this);
 | 
			
		||||
 | 
			
		||||
            if (Clutter.get_default_text_direction() == Clutter.TextDirection.RTL) {
 | 
			
		||||
                this._corner.set_position(this.actor.width - this._corner.width, 0);
 | 
			
		||||
                this.actor.set_anchor_point_from_gravity(Clutter.Gravity.NORTH_EAST);
 | 
			
		||||
                this._corner.set_position(this.width - this._corner.width, 0);
 | 
			
		||||
                this.set_anchor_point_from_gravity(Clutter.Gravity.NORTH_EAST);
 | 
			
		||||
            } else {
 | 
			
		||||
                this._corner.set_position(0, 0);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            this.actor.connect('leave-event',
 | 
			
		||||
                               this._onEnvironsLeft.bind(this));
 | 
			
		||||
 | 
			
		||||
            this._corner.connect('enter-event',
 | 
			
		||||
                                 this._onCornerEntered.bind(this));
 | 
			
		||||
            this._corner.connect('leave-event',
 | 
			
		||||
@@ -1217,13 +1219,12 @@ var HotCorner = class HotCorner {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    destroy() {
 | 
			
		||||
    _onDestroy() {
 | 
			
		||||
        this.setBarrierSize(0);
 | 
			
		||||
        this._pressureBarrier.destroy();
 | 
			
		||||
        this._pressureBarrier = null;
 | 
			
		||||
 | 
			
		||||
        if (this.actor)
 | 
			
		||||
            this.actor.destroy();
 | 
			
		||||
        this._ripples.destroy();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _toggleOverview() {
 | 
			
		||||
@@ -1254,18 +1255,18 @@ var HotCorner = class HotCorner {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _onCornerLeft(actor, event) {
 | 
			
		||||
        if (event.get_related() != this.actor)
 | 
			
		||||
        if (event.get_related() != this)
 | 
			
		||||
            this._entered = false;
 | 
			
		||||
        // Consume event, otherwise this will confuse onEnvironsLeft
 | 
			
		||||
        return Clutter.EVENT_STOP;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _onEnvironsLeft(actor, event) {
 | 
			
		||||
        if (event.get_related() != this._corner)
 | 
			
		||||
    vfunc_leave_event(crossingEvent) {
 | 
			
		||||
        if (crossingEvent.related != this._corner)
 | 
			
		||||
            this._entered = false;
 | 
			
		||||
        return Clutter.EVENT_PROPAGATE;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
var PressureBarrier = class PressureBarrier {
 | 
			
		||||
    constructor(threshold, timeout, actionMode) {
 | 
			
		||||
 
 | 
			
		||||
@@ -2,7 +2,6 @@
 | 
			
		||||
/* exported Lightbox */
 | 
			
		||||
 | 
			
		||||
const { Clutter, GObject, Shell, St } = imports.gi;
 | 
			
		||||
const Signals = imports.signals;
 | 
			
		||||
 | 
			
		||||
const Params = imports.misc.params;
 | 
			
		||||
 | 
			
		||||
@@ -89,8 +88,8 @@ var RadialShaderEffect = GObject.registerClass({
 | 
			
		||||
 *           - inhibitEvents: whether to inhibit events for @container
 | 
			
		||||
 *           - width: shade actor width
 | 
			
		||||
 *           - height: shade actor height
 | 
			
		||||
 *           - fadeInTime: milliseconds used to fade in
 | 
			
		||||
 *           - fadeOutTime: milliseconds used to fade out
 | 
			
		||||
 *           - fadeFactor: fading opacity factor
 | 
			
		||||
 *           - radialEffect: whether to enable the GLSL radial effect
 | 
			
		||||
 *
 | 
			
		||||
 * Lightbox creates a dark translucent "shade" actor to hide the
 | 
			
		||||
 * contents of @container, and allows you to specify particular actors
 | 
			
		||||
@@ -106,41 +105,49 @@ var RadialShaderEffect = GObject.registerClass({
 | 
			
		||||
 * @container and will track any changes in its size. You can override
 | 
			
		||||
 * this by passing an explicit width and height in @params.
 | 
			
		||||
 */
 | 
			
		||||
var Lightbox = class Lightbox {
 | 
			
		||||
    constructor(container, params) {
 | 
			
		||||
        params = Params.parse(params, { inhibitEvents: false,
 | 
			
		||||
                                        width: null,
 | 
			
		||||
                                        height: null,
 | 
			
		||||
                                        fadeFactor: DEFAULT_FADE_FACTOR,
 | 
			
		||||
                                        radialEffect: false,
 | 
			
		||||
                                      });
 | 
			
		||||
var Lightbox = GObject.registerClass({
 | 
			
		||||
    Properties: {
 | 
			
		||||
        'active': GObject.ParamSpec.boolean(
 | 
			
		||||
            'active', 'active', 'active', GObject.ParamFlags.READABLE, false),
 | 
			
		||||
    }
 | 
			
		||||
}, class Lightbox extends St.Bin {
 | 
			
		||||
    _init(container, params) {
 | 
			
		||||
        params = Params.parse(params, {
 | 
			
		||||
            inhibitEvents: false,
 | 
			
		||||
            width: null,
 | 
			
		||||
            height: null,
 | 
			
		||||
            fadeFactor: DEFAULT_FADE_FACTOR,
 | 
			
		||||
            radialEffect: false,
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        super._init({
 | 
			
		||||
            reactive: params.inhibitEvents,
 | 
			
		||||
            width: params.width,
 | 
			
		||||
            height: params.height,
 | 
			
		||||
            visible: false
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        this._active = false;
 | 
			
		||||
        this._container = container;
 | 
			
		||||
        this._children = container.get_children();
 | 
			
		||||
        this._fadeFactor = params.fadeFactor;
 | 
			
		||||
        this._radialEffect = Clutter.feature_available(Clutter.FeatureFlags.SHADERS_GLSL) && params.radialEffect;
 | 
			
		||||
 | 
			
		||||
        this.actor = new St.Bin({ reactive: params.inhibitEvents });
 | 
			
		||||
 | 
			
		||||
        if (this._radialEffect)
 | 
			
		||||
            this.actor.add_effect(new RadialShaderEffect({ name: 'radial' }));
 | 
			
		||||
            this.add_effect(new RadialShaderEffect({ name: 'radial' }));
 | 
			
		||||
        else
 | 
			
		||||
            this.actor.set({ opacity: 0, style_class: 'lightbox' });
 | 
			
		||||
            this.set({ opacity: 0, style_class: 'lightbox' });
 | 
			
		||||
 | 
			
		||||
        container.add_actor(this.actor);
 | 
			
		||||
        this.actor.raise_top();
 | 
			
		||||
        this.actor.hide();
 | 
			
		||||
        this.shown = false;
 | 
			
		||||
        container.add_actor(this);
 | 
			
		||||
        this.raise_top();
 | 
			
		||||
 | 
			
		||||
        this.actor.connect('destroy', this._onDestroy.bind(this));
 | 
			
		||||
        this.connect('destroy', this._onDestroy.bind(this));
 | 
			
		||||
 | 
			
		||||
        if (params.width && params.height) {
 | 
			
		||||
            this.actor.width = params.width;
 | 
			
		||||
            this.actor.height = params.height;
 | 
			
		||||
        } else {
 | 
			
		||||
            let constraint = new Clutter.BindConstraint({ source: container,
 | 
			
		||||
                                                          coordinate: Clutter.BindCoordinate.ALL });
 | 
			
		||||
            this.actor.add_constraint(constraint);
 | 
			
		||||
        if (!params.width || !params.height) {
 | 
			
		||||
            this.add_constraint(new Clutter.BindConstraint({
 | 
			
		||||
                source: container,
 | 
			
		||||
                coordinate: Clutter.BindCoordinate.ALL
 | 
			
		||||
            }));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this._actorAddedSignalId = container.connect('actor-added', this._actorAdded.bind(this));
 | 
			
		||||
@@ -149,16 +156,20 @@ var Lightbox = class Lightbox {
 | 
			
		||||
        this._highlighted = null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    get active() {
 | 
			
		||||
        return this._active;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _actorAdded(container, newChild) {
 | 
			
		||||
        let children = this._container.get_children();
 | 
			
		||||
        let myIndex = children.indexOf(this.actor);
 | 
			
		||||
        let myIndex = children.indexOf(this);
 | 
			
		||||
        let newChildIndex = children.indexOf(newChild);
 | 
			
		||||
 | 
			
		||||
        if (newChildIndex > myIndex) {
 | 
			
		||||
            // The child was added above the shade (presumably it was
 | 
			
		||||
            // made the new top-most child). Move it below the shade,
 | 
			
		||||
            // and add it to this._children as the new topmost actor.
 | 
			
		||||
            newChild.lower(this.actor);
 | 
			
		||||
            this._container.set_child_above_sibling(this, newChild);
 | 
			
		||||
            this._children.push(newChild);
 | 
			
		||||
        } else if (newChildIndex == 0) {
 | 
			
		||||
            // Bottom of stack
 | 
			
		||||
@@ -171,67 +182,55 @@ var Lightbox = class Lightbox {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    show(fadeInTime) {
 | 
			
		||||
        fadeInTime = fadeInTime || 0;
 | 
			
		||||
    lightOn(fadeInTime) {
 | 
			
		||||
        this.remove_all_transitions();
 | 
			
		||||
 | 
			
		||||
        this.actor.remove_all_transitions();
 | 
			
		||||
 | 
			
		||||
        let onComplete = () => {
 | 
			
		||||
            this.shown = true;
 | 
			
		||||
            this.emit('shown');
 | 
			
		||||
        let easeProps = {
 | 
			
		||||
            duration: fadeInTime || 0,
 | 
			
		||||
            mode: Clutter.AnimationMode.EASE_OUT_QUAD
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        if (this._radialEffect) {
 | 
			
		||||
            this.actor.ease_property(
 | 
			
		||||
                '@effects.radial.brightness', VIGNETTE_BRIGHTNESS, {
 | 
			
		||||
                    duration: fadeInTime,
 | 
			
		||||
                    mode: Clutter.AnimationMode.EASE_OUT_QUAD
 | 
			
		||||
                });
 | 
			
		||||
            this.actor.ease_property(
 | 
			
		||||
                '@effects.radial.sharpness', VIGNETTE_SHARPNESS, {
 | 
			
		||||
                    duration: fadeInTime,
 | 
			
		||||
                    mode: Clutter.AnimationMode.EASE_OUT_QUAD,
 | 
			
		||||
                    onComplete
 | 
			
		||||
                });
 | 
			
		||||
        } else {
 | 
			
		||||
            this.actor.ease({
 | 
			
		||||
                opacity: 255 * this._fadeFactor,
 | 
			
		||||
                duration: fadeInTime,
 | 
			
		||||
                mode: Clutter.AnimationMode.EASE_OUT_QUAD,
 | 
			
		||||
                onComplete
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
        let onComplete = () => {
 | 
			
		||||
            this._active = true;
 | 
			
		||||
            this.notify('active');
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        this.actor.show();
 | 
			
		||||
        this.show();
 | 
			
		||||
 | 
			
		||||
        if (this._radialEffect) {
 | 
			
		||||
            this.ease_property(
 | 
			
		||||
                '@effects.radial.brightness', VIGNETTE_BRIGHTNESS, easeProps);
 | 
			
		||||
            this.ease_property(
 | 
			
		||||
                '@effects.radial.sharpness', VIGNETTE_SHARPNESS,
 | 
			
		||||
                Object.assign({ onComplete }, easeProps));
 | 
			
		||||
        } else {
 | 
			
		||||
            this.ease(Object.assign(easeProps, {
 | 
			
		||||
                opacity: 255 * this._fadeFactor,
 | 
			
		||||
                onComplete
 | 
			
		||||
            }));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    hide(fadeOutTime) {
 | 
			
		||||
        fadeOutTime = fadeOutTime || 0;
 | 
			
		||||
    lightOff(fadeOutTime) {
 | 
			
		||||
        this.remove_all_transitions();
 | 
			
		||||
 | 
			
		||||
        this.shown = false;
 | 
			
		||||
        this.actor.remove_all_transitions();
 | 
			
		||||
        this._active = false;
 | 
			
		||||
        this.notify('active');
 | 
			
		||||
 | 
			
		||||
        let onComplete = () => this.actor.hide();
 | 
			
		||||
        let easeProps = {
 | 
			
		||||
            duration: fadeOutTime || 0,
 | 
			
		||||
            mode: Clutter.AnimationMode.EASE_OUT_QUAD
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        let onComplete = () => this.hide();
 | 
			
		||||
 | 
			
		||||
        if (this._radialEffect) {
 | 
			
		||||
            this.actor.ease_property(
 | 
			
		||||
                '@effects.radial.brightness', 1.0, {
 | 
			
		||||
                    duration: fadeOutTime,
 | 
			
		||||
                    mode: Clutter.AnimationMode.EASE_OUT_QUAD
 | 
			
		||||
                });
 | 
			
		||||
            this.actor.ease_property(
 | 
			
		||||
                '@effects.radial.sharpness', 0.0, {
 | 
			
		||||
                    duration: fadeOutTime,
 | 
			
		||||
                    mode: Clutter.AnimationMode.EASE_OUT_QUAD,
 | 
			
		||||
                    onComplete
 | 
			
		||||
                });
 | 
			
		||||
            this.ease_property(
 | 
			
		||||
                '@effects.radial.brightness', 1.0, easeProps);
 | 
			
		||||
            this.ease_property(
 | 
			
		||||
                '@effects.radial.sharpness', 0.0, Object.assign({ onComplete }, easeProps));
 | 
			
		||||
        } else {
 | 
			
		||||
            this.actor.ease({
 | 
			
		||||
                opacity: 0,
 | 
			
		||||
                duration: fadeOutTime,
 | 
			
		||||
                mode: Clutter.AnimationMode.EASE_OUT_QUAD,
 | 
			
		||||
                onComplete
 | 
			
		||||
            });
 | 
			
		||||
            this.ease(Object.assign(easeProps, { opacity: 0, onComplete }));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -262,7 +261,7 @@ var Lightbox = class Lightbox {
 | 
			
		||||
        // case we may need to indicate some *other* actor as the new
 | 
			
		||||
        // sibling of the to-be-lowered one.
 | 
			
		||||
 | 
			
		||||
        let below = this.actor;
 | 
			
		||||
        let below = this;
 | 
			
		||||
        for (let i = this._children.length - 1; i >= 0; i--) {
 | 
			
		||||
            if (this._children[i] == window)
 | 
			
		||||
                this._children[i].raise_top();
 | 
			
		||||
@@ -275,15 +274,6 @@ var Lightbox = class Lightbox {
 | 
			
		||||
        this._highlighted = window;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * destroy:
 | 
			
		||||
     *
 | 
			
		||||
     * Destroys the lightbox.
 | 
			
		||||
     */
 | 
			
		||||
    destroy() {
 | 
			
		||||
        this.actor.destroy();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * _onDestroy:
 | 
			
		||||
     *
 | 
			
		||||
@@ -291,10 +281,15 @@ var Lightbox = class Lightbox {
 | 
			
		||||
     * by destroying its container or by explicitly calling this.destroy().
 | 
			
		||||
     */
 | 
			
		||||
    _onDestroy() {
 | 
			
		||||
        this._container.disconnect(this._actorAddedSignalId);
 | 
			
		||||
        this._container.disconnect(this._actorRemovedSignalId);
 | 
			
		||||
        if (this._actorAddedSignalId) {
 | 
			
		||||
            this._container.disconnect(this._actorAddedSignalId);
 | 
			
		||||
            this._actorAddedSignalId = 0;
 | 
			
		||||
        }
 | 
			
		||||
        if (this._actorRemovedSignalId) {
 | 
			
		||||
            this._container.disconnect(this._actorRemovedSignalId);
 | 
			
		||||
            this._actorRemovedSignalId = 0;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this.highlight(null);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
Signals.addSignalMethods(Lightbox.prototype);
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -11,12 +11,26 @@ const LOCATE_POINTER_SCHEMA = "org.gnome.desktop.interface";
 | 
			
		||||
var LocatePointer = class {
 | 
			
		||||
    constructor() {
 | 
			
		||||
        this._settings = new Gio.Settings({ schema_id: LOCATE_POINTER_SCHEMA });
 | 
			
		||||
        this._ripples = new Ripples.Ripples(0.5, 0.5, 'ripple-pointer-location');
 | 
			
		||||
        this._ripples.addTo(Main.uiGroup);
 | 
			
		||||
        this._settings.connect(`changed::${LOCATE_POINTER_KEY}`, () => this._syncEnabled());
 | 
			
		||||
        this._syncEnabled();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _syncEnabled() {
 | 
			
		||||
        let enabled = this._settings.get_boolean(LOCATE_POINTER_KEY);
 | 
			
		||||
        if (enabled == !!this._ripples)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        if (enabled) {
 | 
			
		||||
            this._ripples = new Ripples.Ripples(0.5, 0.5, 'ripple-pointer-location');
 | 
			
		||||
            this._ripples.addTo(Main.uiGroup);
 | 
			
		||||
        } else {
 | 
			
		||||
            this._ripples.destroy();
 | 
			
		||||
            this._ripples = null;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    show() {
 | 
			
		||||
        if (!this._settings.get_boolean(LOCATE_POINTER_KEY))
 | 
			
		||||
        if (!this._ripples)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        let [x, y] = global.get_pointer();
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,8 @@
 | 
			
		||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
 | 
			
		||||
/* exported LookingGlass */
 | 
			
		||||
 | 
			
		||||
const { Clutter, Cogl, Gio, GLib,
 | 
			
		||||
        GObject, Meta, Pango, Shell, St } = imports.gi;
 | 
			
		||||
const Mainloop = imports.mainloop;
 | 
			
		||||
const { Clutter, Cogl, Gio, GLib, GObject,
 | 
			
		||||
        Graphene, Meta, Pango, Shell, St } = imports.gi;
 | 
			
		||||
const Signals = imports.signals;
 | 
			
		||||
const System = imports.system;
 | 
			
		||||
 | 
			
		||||
@@ -20,7 +19,6 @@ const CHEVRON = '>>> ';
 | 
			
		||||
/* Imports...feel free to add here as needed */
 | 
			
		||||
var commandHeader = 'const { Clutter, Gio, GLib, GObject, Meta, Shell, St } = imports.gi; ' +
 | 
			
		||||
                    'const Main = imports.ui.main; ' +
 | 
			
		||||
                    'const Mainloop = imports.mainloop; ' +
 | 
			
		||||
                    /* Utility functions...we should probably be able to use these
 | 
			
		||||
                     * in the shell core code too. */
 | 
			
		||||
                    'const stage = global.stage; ' +
 | 
			
		||||
@@ -112,9 +110,11 @@ var AutoComplete = class AutoComplete {
 | 
			
		||||
Signals.addSignalMethods(AutoComplete.prototype);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
var Notebook = class Notebook {
 | 
			
		||||
    constructor() {
 | 
			
		||||
        this.actor = new St.BoxLayout({ vertical: true });
 | 
			
		||||
var Notebook = GObject.registerClass({
 | 
			
		||||
    Signals: { 'selection': { param_types: [Clutter.Actor.$gtype] } },
 | 
			
		||||
}, class Notebook extends St.BoxLayout {
 | 
			
		||||
    _init() {
 | 
			
		||||
        super._init({ vertical: true });
 | 
			
		||||
 | 
			
		||||
        this.tabControls = new St.BoxLayout({ style_class: 'labels' });
 | 
			
		||||
 | 
			
		||||
@@ -145,7 +145,7 @@ var Notebook = class Notebook {
 | 
			
		||||
                        _scrollToBottom: false };
 | 
			
		||||
        this._tabs.push(tabData);
 | 
			
		||||
        scrollview.hide();
 | 
			
		||||
        this.actor.add(scrollview, { expand: true });
 | 
			
		||||
        this.add(scrollview, { expand: true });
 | 
			
		||||
 | 
			
		||||
        let vAdjust = scrollview.vscroll.adjustment;
 | 
			
		||||
        vAdjust.connect('changed', () => this._onAdjustScopeChanged(tabData));
 | 
			
		||||
@@ -176,7 +176,7 @@ var Notebook = class Notebook {
 | 
			
		||||
        // Focus the new tab before unmapping the old one
 | 
			
		||||
        let tabData = this._tabs[index];
 | 
			
		||||
        if (!tabData.scrollView.navigate_focus(null, St.DirectionType.TAB_FORWARD, false))
 | 
			
		||||
            this.actor.grab_key_focus();
 | 
			
		||||
            this.grab_key_focus();
 | 
			
		||||
 | 
			
		||||
        this._unselect();
 | 
			
		||||
 | 
			
		||||
@@ -236,11 +236,10 @@ var Notebook = class Notebook {
 | 
			
		||||
 | 
			
		||||
        this.selectIndex(prevIndex);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
Signals.addSignalMethods(Notebook.prototype);
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
function objectToString(o) {
 | 
			
		||||
    if (typeof(o) == typeof(objectToString)) {
 | 
			
		||||
    if (typeof o == typeof objectToString) {
 | 
			
		||||
        // special case this since the default is way, way too verbose
 | 
			
		||||
        return '<js function>';
 | 
			
		||||
    } else {
 | 
			
		||||
@@ -248,57 +247,64 @@ function objectToString(o) {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var ObjLink = class ObjLink {
 | 
			
		||||
    constructor(lookingGlass, o, title) {
 | 
			
		||||
var ObjLink = GObject.registerClass(
 | 
			
		||||
class ObjLink extends St.Button {
 | 
			
		||||
    _init(lookingGlass, o, title) {
 | 
			
		||||
        let text;
 | 
			
		||||
        if (title)
 | 
			
		||||
            text = title;
 | 
			
		||||
        else
 | 
			
		||||
            text = objectToString(o);
 | 
			
		||||
        text = GLib.markup_escape_text(text, -1);
 | 
			
		||||
 | 
			
		||||
        super._init({
 | 
			
		||||
            reactive: true,
 | 
			
		||||
            track_hover: true,
 | 
			
		||||
            style_class: 'shell-link',
 | 
			
		||||
            label: text
 | 
			
		||||
        });
 | 
			
		||||
        this.get_child().single_line_mode = true;
 | 
			
		||||
 | 
			
		||||
        this._obj = o;
 | 
			
		||||
 | 
			
		||||
        this.actor = new St.Button({ reactive: true,
 | 
			
		||||
                                     track_hover: true,
 | 
			
		||||
                                     style_class: 'shell-link',
 | 
			
		||||
                                     label: text });
 | 
			
		||||
        this.actor.get_child().single_line_mode = true;
 | 
			
		||||
        this.actor.connect('clicked', this._onClicked.bind(this));
 | 
			
		||||
 | 
			
		||||
        this._lookingGlass = lookingGlass;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _onClicked() {
 | 
			
		||||
        this._lookingGlass.inspectObject(this._obj, this.actor);
 | 
			
		||||
    vfunc_clicked() {
 | 
			
		||||
        this._lookingGlass.inspectObject(this._obj, this);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
var Result = GObject.registerClass({
 | 
			
		||||
    GTypeName: 'LookingClass_Result'
 | 
			
		||||
}, class Result extends St.BoxLayout {
 | 
			
		||||
    _init(lookingGlass, command, o, index) {
 | 
			
		||||
        super._init({ vertical: true });
 | 
			
		||||
 | 
			
		||||
var Result = class Result {
 | 
			
		||||
    constructor(lookingGlass, command, o, index) {
 | 
			
		||||
        this.index = index;
 | 
			
		||||
        this.o = o;
 | 
			
		||||
 | 
			
		||||
        this.actor = new St.BoxLayout({ vertical: true });
 | 
			
		||||
        this._lookingGlass = lookingGlass;
 | 
			
		||||
 | 
			
		||||
        let cmdTxt = new St.Label({ text: command });
 | 
			
		||||
        cmdTxt.clutter_text.ellipsize = Pango.EllipsizeMode.END;
 | 
			
		||||
        this.actor.add(cmdTxt);
 | 
			
		||||
        this.add(cmdTxt);
 | 
			
		||||
        let box = new St.BoxLayout({});
 | 
			
		||||
        this.actor.add(box);
 | 
			
		||||
        this.add(box);
 | 
			
		||||
        let resultTxt = new St.Label({ text: `r(${index}) = ` });
 | 
			
		||||
        resultTxt.clutter_text.ellipsize = Pango.EllipsizeMode.END;
 | 
			
		||||
        box.add(resultTxt);
 | 
			
		||||
        let objLink = new ObjLink(this._lookingGlass, o);
 | 
			
		||||
        box.add(objLink.actor);
 | 
			
		||||
        box.add(objLink);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
var WindowList = class WindowList {
 | 
			
		||||
    constructor(lookingGlass) {
 | 
			
		||||
        this.actor = new St.BoxLayout({ name: 'Windows', vertical: true, style: 'spacing: 8px' });
 | 
			
		||||
var WindowList = GObject.registerClass({
 | 
			
		||||
    GTypeName: 'LookingClass_WindowList'
 | 
			
		||||
}, class WindowList extends St.BoxLayout {
 | 
			
		||||
    _init(lookingGlass) {
 | 
			
		||||
        super._init({ name: 'Windows', vertical: true, style: 'spacing: 8px' });
 | 
			
		||||
        let tracker = Shell.WindowTracker.get_default();
 | 
			
		||||
        this._updateId = Main.initializeDeferredWork(this.actor, this._updateWindowList.bind(this));
 | 
			
		||||
        this._updateId = Main.initializeDeferredWork(this, this._updateWindowList.bind(this));
 | 
			
		||||
        global.display.connect('window-created', this._updateWindowList.bind(this));
 | 
			
		||||
        tracker.connect('tracked-windows-changed', this._updateWindowList.bind(this));
 | 
			
		||||
 | 
			
		||||
@@ -306,7 +312,10 @@ var WindowList = class WindowList {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _updateWindowList() {
 | 
			
		||||
        this.actor.destroy_all_children();
 | 
			
		||||
        if (!this._lookingGlass.isOpen)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        this.destroy_all_children();
 | 
			
		||||
        let windows = global.get_window_actors();
 | 
			
		||||
        let tracker = Shell.WindowTracker.get_default();
 | 
			
		||||
        for (let i = 0; i < windows.length; i++) {
 | 
			
		||||
@@ -317,9 +326,9 @@ var WindowList = class WindowList {
 | 
			
		||||
                metaWindow._lookingGlassManaged = true;
 | 
			
		||||
            }
 | 
			
		||||
            let box = new St.BoxLayout({ vertical: true });
 | 
			
		||||
            this.actor.add(box);
 | 
			
		||||
            this.add(box);
 | 
			
		||||
            let windowLink = new ObjLink(this._lookingGlass, metaWindow, metaWindow.title);
 | 
			
		||||
            box.add(windowLink.actor, { x_align: St.Align.START, x_fill: false });
 | 
			
		||||
            box.add(windowLink, { x_align: St.Align.START, x_fill: false });
 | 
			
		||||
            let propsBox = new St.BoxLayout({ vertical: true, style: 'padding-left: 6px;' });
 | 
			
		||||
            box.add(propsBox);
 | 
			
		||||
            propsBox.add(new St.Label({ text: `wmclass: ${metaWindow.get_wm_class()}` }));
 | 
			
		||||
@@ -330,30 +339,38 @@ var WindowList = class WindowList {
 | 
			
		||||
                propsBox.add(propBox);
 | 
			
		||||
                propBox.add(new St.Label({ text: 'app: ' }), { y_fill: false });
 | 
			
		||||
                let appLink = new ObjLink(this._lookingGlass, app, app.get_id());
 | 
			
		||||
                propBox.add(appLink.actor, { y_fill: false });
 | 
			
		||||
                propBox.add(appLink, { y_fill: false });
 | 
			
		||||
                propBox.add(icon, { y_fill: false });
 | 
			
		||||
            } else {
 | 
			
		||||
                propsBox.add(new St.Label({ text: '<untracked>' }));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
Signals.addSignalMethods(WindowList.prototype);
 | 
			
		||||
 | 
			
		||||
var ObjInspector = class ObjInspector {
 | 
			
		||||
    constructor(lookingGlass) {
 | 
			
		||||
    update() {
 | 
			
		||||
        this._updateWindowList();
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
var ObjInspector = GObject.registerClass(
 | 
			
		||||
class ObjInspector extends St.ScrollView {
 | 
			
		||||
    _init(lookingGlass) {
 | 
			
		||||
        super._init({
 | 
			
		||||
            pivot_point: new Graphene.Point({ x: 0.5, y: 0.5 }),
 | 
			
		||||
            x_fill: true,
 | 
			
		||||
            y_fill: true
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        this._obj = null;
 | 
			
		||||
        this._previousObj = null;
 | 
			
		||||
 | 
			
		||||
        this._parentList = [];
 | 
			
		||||
 | 
			
		||||
        this.actor = new St.ScrollView({ pivot_point: new Clutter.Point({ x: 0.5, y: 0.5 }),
 | 
			
		||||
                                         x_fill: true, y_fill: true });
 | 
			
		||||
        this.actor.get_hscroll_bar().hide();
 | 
			
		||||
        this.get_hscroll_bar().hide();
 | 
			
		||||
        this._container = new St.BoxLayout({ name: 'LookingGlassPropertyInspector',
 | 
			
		||||
                                             style_class: 'lg-dialog',
 | 
			
		||||
                                             vertical: true });
 | 
			
		||||
        this.actor.add_actor(this._container);
 | 
			
		||||
        this.add_actor(this._container);
 | 
			
		||||
 | 
			
		||||
        this._lookingGlass = lookingGlass;
 | 
			
		||||
    }
 | 
			
		||||
@@ -369,7 +386,7 @@ var ObjInspector = class ObjInspector {
 | 
			
		||||
 | 
			
		||||
        let hbox = new St.BoxLayout({ style_class: 'lg-obj-inspector-title' });
 | 
			
		||||
        this._container.add_actor(hbox);
 | 
			
		||||
        let label = new St.Label({ text: 'Inspecting: %s: %s'.format(typeof(obj),
 | 
			
		||||
        let label = new St.Label({ text: 'Inspecting: %s: %s'.format(typeof obj,
 | 
			
		||||
                                                                     objectToString(obj)) });
 | 
			
		||||
        label.single_line_mode = true;
 | 
			
		||||
        hbox.add(label, { expand: true, y_fill: false });
 | 
			
		||||
@@ -387,7 +404,7 @@ var ObjInspector = class ObjInspector {
 | 
			
		||||
        button.add_actor(new St.Icon({ icon_name: 'window-close-symbolic' }));
 | 
			
		||||
        button.connect('clicked', this.close.bind(this));
 | 
			
		||||
        hbox.add(button);
 | 
			
		||||
        if (typeof(obj) == typeof({})) {
 | 
			
		||||
        if (typeof obj == typeof {}) {
 | 
			
		||||
            let properties = [];
 | 
			
		||||
            for (let propName in obj) {
 | 
			
		||||
                properties.push(propName);
 | 
			
		||||
@@ -399,7 +416,7 @@ var ObjInspector = class ObjInspector {
 | 
			
		||||
                let link;
 | 
			
		||||
                try {
 | 
			
		||||
                    let prop = obj[propName];
 | 
			
		||||
                    link = new ObjLink(this._lookingGlass, prop).actor;
 | 
			
		||||
                    link = new ObjLink(this._lookingGlass, prop);
 | 
			
		||||
                } catch (e) {
 | 
			
		||||
                    link = new St.Label({ text: '<error>' });
 | 
			
		||||
                }
 | 
			
		||||
@@ -416,17 +433,17 @@ var ObjInspector = class ObjInspector {
 | 
			
		||||
            return;
 | 
			
		||||
        this._previousObj = null;
 | 
			
		||||
        this._open = true;
 | 
			
		||||
        this.actor.show();
 | 
			
		||||
        this.show();
 | 
			
		||||
        if (sourceActor) {
 | 
			
		||||
            this.actor.set_scale(0, 0);
 | 
			
		||||
            this.actor.ease({
 | 
			
		||||
            this.set_scale(0, 0);
 | 
			
		||||
            this.ease({
 | 
			
		||||
                scale_x: 1,
 | 
			
		||||
                scale_y: 1,
 | 
			
		||||
                mode: Clutter.AnimationMode.EASE_OUT_QUAD,
 | 
			
		||||
                time: 200
 | 
			
		||||
                duration: 200
 | 
			
		||||
            });
 | 
			
		||||
        } else {
 | 
			
		||||
            this.actor.set_scale(1, 1);
 | 
			
		||||
            this.set_scale(1, 1);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -434,7 +451,7 @@ var ObjInspector = class ObjInspector {
 | 
			
		||||
        if (!this._open)
 | 
			
		||||
            return;
 | 
			
		||||
        this._open = false;
 | 
			
		||||
        this.actor.hide();
 | 
			
		||||
        this.hide();
 | 
			
		||||
        this._previousObj = null;
 | 
			
		||||
        this._obj = null;
 | 
			
		||||
    }
 | 
			
		||||
@@ -448,7 +465,7 @@ var ObjInspector = class ObjInspector {
 | 
			
		||||
    _onBack() {
 | 
			
		||||
        this.selectObject(this._previousObj, true);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
var RedBorderEffect = GObject.registerClass(
 | 
			
		||||
class RedBorderEffect extends Clutter.Effect {
 | 
			
		||||
@@ -460,16 +477,16 @@ class RedBorderEffect extends Clutter.Effect {
 | 
			
		||||
        color.init_from_4ub(0xff, 0, 0, 0xc4);
 | 
			
		||||
        Cogl.set_source_color(color);
 | 
			
		||||
 | 
			
		||||
        let geom = actor.get_allocation_geometry();
 | 
			
		||||
        let alloc = actor.get_allocation_box();
 | 
			
		||||
        let width = 2;
 | 
			
		||||
 | 
			
		||||
        // clockwise order
 | 
			
		||||
        Cogl.rectangle(0, 0, geom.width, width);
 | 
			
		||||
        Cogl.rectangle(geom.width - width, width,
 | 
			
		||||
                       geom.width, geom.height);
 | 
			
		||||
        Cogl.rectangle(0, geom.height,
 | 
			
		||||
                       geom.width - width, geom.height - width);
 | 
			
		||||
        Cogl.rectangle(0, geom.height - width,
 | 
			
		||||
        Cogl.rectangle(0, 0, alloc.get_width(), width);
 | 
			
		||||
        Cogl.rectangle(alloc.get_width() - width, width,
 | 
			
		||||
                       alloc.get_width(), alloc.get_height());
 | 
			
		||||
        Cogl.rectangle(0, alloc.get_height(),
 | 
			
		||||
                       alloc.get_width() - width, alloc.get_height() - width);
 | 
			
		||||
        Cogl.rectangle(0, alloc.get_height() - width,
 | 
			
		||||
                       width, width);
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
@@ -479,8 +496,7 @@ var Inspector = GObject.registerClass({
 | 
			
		||||
               'target': { param_types: [Clutter.Actor.$gtype, GObject.TYPE_DOUBLE, GObject.TYPE_DOUBLE] } },
 | 
			
		||||
}, class Inspector extends Clutter.Actor {
 | 
			
		||||
    _init(lookingGlass) {
 | 
			
		||||
        super._init({ width: 0,
 | 
			
		||||
                      height: 0 });
 | 
			
		||||
        super._init({ width: 0, height: 0 });
 | 
			
		||||
 | 
			
		||||
        Main.uiGroup.add_actor(this);
 | 
			
		||||
 | 
			
		||||
@@ -615,18 +631,20 @@ var Inspector = GObject.registerClass({
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
var Extensions = class Extensions {
 | 
			
		||||
    constructor(lookingGlass) {
 | 
			
		||||
var Extensions = GObject.registerClass({
 | 
			
		||||
    GTypeName: 'LookingClass_Extensions'
 | 
			
		||||
}, class Extensions extends St.BoxLayout {
 | 
			
		||||
    _init(lookingGlass) {
 | 
			
		||||
        super._init({ vertical: true, name: 'lookingGlassExtensions' });
 | 
			
		||||
 | 
			
		||||
        this._lookingGlass = lookingGlass;
 | 
			
		||||
        this.actor = new St.BoxLayout({ vertical: true,
 | 
			
		||||
                                        name: 'lookingGlassExtensions' });
 | 
			
		||||
        this._noExtensions = new St.Label({ style_class: 'lg-extensions-none',
 | 
			
		||||
                                            text: _("No extensions installed") });
 | 
			
		||||
        this._numExtensions = 0;
 | 
			
		||||
        this._extensionsList = new St.BoxLayout({ vertical: true,
 | 
			
		||||
                                                  style_class: 'lg-extensions-list' });
 | 
			
		||||
        this._extensionsList.add(this._noExtensions);
 | 
			
		||||
        this.actor.add(this._extensionsList);
 | 
			
		||||
        this.add(this._extensionsList);
 | 
			
		||||
 | 
			
		||||
        Main.extensionManager.getUuids().forEach(uuid => {
 | 
			
		||||
            this._loadExtension(null, uuid);
 | 
			
		||||
@@ -754,10 +772,19 @@ var Extensions = class Extensions {
 | 
			
		||||
 | 
			
		||||
        return box;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
var LookingGlass = GObject.registerClass(
 | 
			
		||||
class LookingGlass extends St.BoxLayout {
 | 
			
		||||
    _init() {
 | 
			
		||||
        super._init({
 | 
			
		||||
            name: 'LookingGlassDialog',
 | 
			
		||||
            style_class: 'lg-dialog',
 | 
			
		||||
            vertical: true,
 | 
			
		||||
            visible: false,
 | 
			
		||||
            reactive: true
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
var LookingGlass = class LookingGlass {
 | 
			
		||||
    constructor() {
 | 
			
		||||
        this._borderPaintTarget = null;
 | 
			
		||||
        this._redBorderEffect = new RedBorderEffect();
 | 
			
		||||
 | 
			
		||||
@@ -765,26 +792,18 @@ var LookingGlass = class LookingGlass {
 | 
			
		||||
 | 
			
		||||
        this._it = null;
 | 
			
		||||
        this._offset = 0;
 | 
			
		||||
        this._results = [];
 | 
			
		||||
 | 
			
		||||
        // Sort of magic, but...eh.
 | 
			
		||||
        this._maxItems = 150;
 | 
			
		||||
 | 
			
		||||
        this.actor = new St.BoxLayout({ name: 'LookingGlassDialog',
 | 
			
		||||
                                        style_class: 'lg-dialog',
 | 
			
		||||
                                        vertical: true,
 | 
			
		||||
                                        visible: false,
 | 
			
		||||
                                        reactive: true });
 | 
			
		||||
        this.actor.connect('key-press-event', this._globalKeyPressEvent.bind(this));
 | 
			
		||||
 | 
			
		||||
        this._interfaceSettings = new Gio.Settings({ schema_id: 'org.gnome.desktop.interface' });
 | 
			
		||||
        this._interfaceSettings.connect('changed::monospace-font-name',
 | 
			
		||||
                                        this._updateFont.bind(this));
 | 
			
		||||
        this._updateFont();
 | 
			
		||||
 | 
			
		||||
        // We want it to appear to slide out from underneath the panel
 | 
			
		||||
        Main.uiGroup.add_actor(this.actor);
 | 
			
		||||
        Main.uiGroup.set_child_below_sibling(this.actor,
 | 
			
		||||
        Main.uiGroup.add_actor(this);
 | 
			
		||||
        Main.uiGroup.set_child_below_sibling(this,
 | 
			
		||||
                                             Main.layoutManager.panelBox);
 | 
			
		||||
        Main.layoutManager.panelBox.connect('allocation-changed',
 | 
			
		||||
                                            this._queueResize.bind(this));
 | 
			
		||||
@@ -792,11 +811,11 @@ var LookingGlass = class LookingGlass {
 | 
			
		||||
                                               this._queueResize.bind(this));
 | 
			
		||||
 | 
			
		||||
        this._objInspector = new ObjInspector(this);
 | 
			
		||||
        Main.uiGroup.add_actor(this._objInspector.actor);
 | 
			
		||||
        this._objInspector.actor.hide();
 | 
			
		||||
        Main.uiGroup.add_actor(this._objInspector);
 | 
			
		||||
        this._objInspector.hide();
 | 
			
		||||
 | 
			
		||||
        let toolbar = new St.BoxLayout({ name: 'Toolbar' });
 | 
			
		||||
        this.actor.add_actor(toolbar);
 | 
			
		||||
        this.add_actor(toolbar);
 | 
			
		||||
        let inspectIcon = new St.Icon({ icon_name: 'gtk-color-picker',
 | 
			
		||||
                                        icon_size: 24 });
 | 
			
		||||
        toolbar.add_actor(inspectIcon);
 | 
			
		||||
@@ -807,10 +826,10 @@ var LookingGlass = class LookingGlass {
 | 
			
		||||
                this._pushResult(`inspect(${Math.round(stageX)}, ${Math.round(stageY)})`, target);
 | 
			
		||||
            });
 | 
			
		||||
            inspector.connect('closed', () => {
 | 
			
		||||
                this.actor.show();
 | 
			
		||||
                this.show();
 | 
			
		||||
                global.stage.set_key_focus(this._entry);
 | 
			
		||||
            });
 | 
			
		||||
            this.actor.hide();
 | 
			
		||||
            this.hide();
 | 
			
		||||
            return Clutter.EVENT_STOP;
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
@@ -821,7 +840,7 @@ var LookingGlass = class LookingGlass {
 | 
			
		||||
        gcIcon.connect('button-press-event', () => {
 | 
			
		||||
            gcIcon.icon_name = 'user-trash';
 | 
			
		||||
            System.gc();
 | 
			
		||||
            this._timeoutId = Mainloop.timeout_add(500, () => {
 | 
			
		||||
            this._timeoutId = GLib.timeout_add(GLib.PRIORITY_DEFAULT, 500, () => {
 | 
			
		||||
                gcIcon.icon_name = 'user-trash-full';
 | 
			
		||||
                this._timeoutId = 0;
 | 
			
		||||
                return GLib.SOURCE_REMOVE;
 | 
			
		||||
@@ -832,7 +851,7 @@ var LookingGlass = class LookingGlass {
 | 
			
		||||
 | 
			
		||||
        let notebook = new Notebook();
 | 
			
		||||
        this._notebook = notebook;
 | 
			
		||||
        this.actor.add(notebook.actor, { expand: true });
 | 
			
		||||
        this.add(notebook, { expand: true });
 | 
			
		||||
 | 
			
		||||
        let emptyBox = new St.Bin();
 | 
			
		||||
        toolbar.add(emptyBox, { expand: true });
 | 
			
		||||
@@ -855,10 +874,10 @@ var LookingGlass = class LookingGlass {
 | 
			
		||||
        this._entryArea.add(this._entry, { expand: true });
 | 
			
		||||
 | 
			
		||||
        this._windowList = new WindowList(this);
 | 
			
		||||
        notebook.appendPage('Windows', this._windowList.actor);
 | 
			
		||||
        notebook.appendPage('Windows', this._windowList);
 | 
			
		||||
 | 
			
		||||
        this._extensions = new Extensions(this);
 | 
			
		||||
        notebook.appendPage('Extensions', this._extensions.actor);
 | 
			
		||||
        notebook.appendPage('Extensions', this._extensions);
 | 
			
		||||
 | 
			
		||||
        this._entry.clutter_text.connect('activate', (o, _e) => {
 | 
			
		||||
            // Hide any completions we are currently showing
 | 
			
		||||
@@ -876,7 +895,7 @@ var LookingGlass = class LookingGlass {
 | 
			
		||||
            return true;
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        this._history = new History.HistoryManager({ gsettingsKey: HISTORY_KEY, 
 | 
			
		||||
        this._history = new History.HistoryManager({ gsettingsKey: HISTORY_KEY,
 | 
			
		||||
                                                     entry: this._entry.clutter_text });
 | 
			
		||||
 | 
			
		||||
        this._autoComplete = new AutoComplete(this._entry);
 | 
			
		||||
@@ -900,7 +919,7 @@ var LookingGlass = class LookingGlass {
 | 
			
		||||
        // monospace font to be bold/oblique/etc. Could easily be added here.
 | 
			
		||||
        let size = fontDesc.get_size() / 1024.;
 | 
			
		||||
        let unit = fontDesc.get_size_is_absolute() ? 'px' : 'pt';
 | 
			
		||||
        this.actor.style = `
 | 
			
		||||
        this.style = `
 | 
			
		||||
            font-size: ${size}${unit};
 | 
			
		||||
            font-family: "${fontDesc.get_family()}";`;
 | 
			
		||||
    }
 | 
			
		||||
@@ -914,17 +933,14 @@ var LookingGlass = class LookingGlass {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _pushResult(command, obj) {
 | 
			
		||||
        let index = this._results.length + this._offset;
 | 
			
		||||
        let index = this._resultsArea.get_n_children() + this._offset;
 | 
			
		||||
        let result = new Result(this, CHEVRON + command, obj, index);
 | 
			
		||||
        this._results.push(result);
 | 
			
		||||
        this._resultsArea.add(result.actor);
 | 
			
		||||
        this._resultsArea.add(result);
 | 
			
		||||
        if (obj instanceof Clutter.Actor)
 | 
			
		||||
            this.setBorderPaintTarget(obj);
 | 
			
		||||
 | 
			
		||||
        let children = this._resultsArea.get_children();
 | 
			
		||||
        if (children.length > this._maxItems) {
 | 
			
		||||
            this._results.shift();
 | 
			
		||||
            children[0].destroy();
 | 
			
		||||
        if (this._resultsArea.get_n_children() > this._maxItems) {
 | 
			
		||||
            this._resultsArea.get_first_child().destroy();
 | 
			
		||||
            this._offset++;
 | 
			
		||||
        }
 | 
			
		||||
        this._it = obj;
 | 
			
		||||
@@ -1010,7 +1026,11 @@ var LookingGlass = class LookingGlass {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    getResult(idx) {
 | 
			
		||||
        return this._results[idx - this._offset].o;
 | 
			
		||||
        try {
 | 
			
		||||
            return this._resultsArea.get_child_at_index(idx - this._offset).o;
 | 
			
		||||
        } catch (e) {
 | 
			
		||||
            throw new Error(`Unknown result at index ${idx}`);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    toggle() {
 | 
			
		||||
@@ -1032,15 +1052,15 @@ var LookingGlass = class LookingGlass {
 | 
			
		||||
        let myWidth = primary.width * 0.7;
 | 
			
		||||
        let availableHeight = primary.height - Main.layoutManager.keyboardBox.height;
 | 
			
		||||
        let myHeight = Math.min(primary.height * 0.7, availableHeight * 0.9);
 | 
			
		||||
        this.actor.x = primary.x + (primary.width - myWidth) / 2;
 | 
			
		||||
        this.x = primary.x + (primary.width - myWidth) / 2;
 | 
			
		||||
        this._hiddenY = primary.y + Main.layoutManager.panelBox.height - myHeight;
 | 
			
		||||
        this._targetY = this._hiddenY + myHeight;
 | 
			
		||||
        this.actor.y = this._hiddenY;
 | 
			
		||||
        this.actor.width = myWidth;
 | 
			
		||||
        this.actor.height = myHeight;
 | 
			
		||||
        this._objInspector.actor.set_size(Math.floor(myWidth * 0.8), Math.floor(myHeight * 0.8));
 | 
			
		||||
        this._objInspector.actor.set_position(this.actor.x + Math.floor(myWidth * 0.1),
 | 
			
		||||
                                              this._targetY + Math.floor(myHeight * 0.1));
 | 
			
		||||
        this.y = this._hiddenY;
 | 
			
		||||
        this.width = myWidth;
 | 
			
		||||
        this.height = myHeight;
 | 
			
		||||
        this._objInspector.set_size(Math.floor(myWidth * 0.8), Math.floor(myHeight * 0.8));
 | 
			
		||||
        this._objInspector.set_position(this.x + Math.floor(myWidth * 0.1),
 | 
			
		||||
                                        this._targetY + Math.floor(myHeight * 0.1));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    insertObject(obj) {
 | 
			
		||||
@@ -1053,11 +1073,10 @@ var LookingGlass = class LookingGlass {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Handle key events which are relevant for all tabs of the LookingGlass
 | 
			
		||||
    _globalKeyPressEvent(actor, event) {
 | 
			
		||||
        let symbol = event.get_key_symbol();
 | 
			
		||||
        let modifierState = event.get_state();
 | 
			
		||||
    vfunc_key_press_event(keyPressEvent) {
 | 
			
		||||
        let symbol = keyPressEvent.keyval;
 | 
			
		||||
        if (symbol == Clutter.Escape) {
 | 
			
		||||
            if (this._objInspector.actor.visible) {
 | 
			
		||||
            if (this._objInspector.visible) {
 | 
			
		||||
                this._objInspector.close();
 | 
			
		||||
            } else {
 | 
			
		||||
                this.close();
 | 
			
		||||
@@ -1065,7 +1084,7 @@ var LookingGlass = class LookingGlass {
 | 
			
		||||
            return Clutter.EVENT_STOP;
 | 
			
		||||
        }
 | 
			
		||||
        // Ctrl+PgUp and Ctrl+PgDown switches tabs in the notebook view
 | 
			
		||||
        if (modifierState & Clutter.ModifierType.CONTROL_MASK) {
 | 
			
		||||
        if (keyPressEvent.modifier_state & Clutter.ModifierType.CONTROL_MASK) {
 | 
			
		||||
            if (symbol == Clutter.KEY_Page_Up) {
 | 
			
		||||
                this._notebook.prevTab();
 | 
			
		||||
            } else if (symbol == Clutter.KEY_Page_Down) {
 | 
			
		||||
@@ -1083,30 +1102,32 @@ var LookingGlass = class LookingGlass {
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        this._notebook.selectIndex(0);
 | 
			
		||||
        this.actor.show();
 | 
			
		||||
        this.show();
 | 
			
		||||
        this._open = true;
 | 
			
		||||
        this._history.lastItem();
 | 
			
		||||
 | 
			
		||||
        this.actor.remove_all_transitions();
 | 
			
		||||
        this.remove_all_transitions();
 | 
			
		||||
 | 
			
		||||
        // We inverse compensate for the slow-down so you can change the factor
 | 
			
		||||
        // through LookingGlass without long waits.
 | 
			
		||||
        let duration = LG_ANIMATION_TIME / St.Settings.get().slow_down_factor;
 | 
			
		||||
        this.actor.ease({
 | 
			
		||||
        this.ease({
 | 
			
		||||
            y: this._targetY,
 | 
			
		||||
            duration,
 | 
			
		||||
            mode: Clutter.AnimationMode.EASE_OUT_QUAD
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        this._windowList.update();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    close() {
 | 
			
		||||
        if (!this._open)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        this._objInspector.actor.hide();
 | 
			
		||||
        this._objInspector.hide();
 | 
			
		||||
 | 
			
		||||
        this._open = false;
 | 
			
		||||
        this.actor.remove_all_transitions();
 | 
			
		||||
        this.remove_all_transitions();
 | 
			
		||||
 | 
			
		||||
        this.setBorderPaintTarget(null);
 | 
			
		||||
 | 
			
		||||
@@ -1115,12 +1136,15 @@ var LookingGlass = class LookingGlass {
 | 
			
		||||
        let settings = St.Settings.get();
 | 
			
		||||
        let duration = Math.min(LG_ANIMATION_TIME / settings.slow_down_factor,
 | 
			
		||||
                                LG_ANIMATION_TIME);
 | 
			
		||||
        this.actor.ease({
 | 
			
		||||
        this.ease({
 | 
			
		||||
            y: this._hiddenY,
 | 
			
		||||
            duration,
 | 
			
		||||
            mode: Clutter.AnimationMode.EASE_OUT_QUAD,
 | 
			
		||||
            onComplete: () => this.actor.hide()
 | 
			
		||||
            onComplete: () => this.hide()
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
Signals.addSignalMethods(LookingGlass.prototype);
 | 
			
		||||
 | 
			
		||||
    get isOpen() {
 | 
			
		||||
        return this._open;
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -2,7 +2,6 @@
 | 
			
		||||
 | 
			
		||||
const { Atspi, Clutter, GDesktopEnums,
 | 
			
		||||
        Gio, GLib, GObject, Meta, Shell, St } = imports.gi;
 | 
			
		||||
const Mainloop = imports.mainloop;
 | 
			
		||||
const Signals = imports.signals;
 | 
			
		||||
 | 
			
		||||
const Background = imports.ui.background;
 | 
			
		||||
@@ -265,7 +264,7 @@ var Magnifier = class Magnifier {
 | 
			
		||||
        zoomRegion.setViewPort(viewPort);
 | 
			
		||||
 | 
			
		||||
        // We ignore the redundant width/height on the ROI
 | 
			
		||||
        let fixedROI = new Object(roi);
 | 
			
		||||
        let fixedROI = Object.create(roi);
 | 
			
		||||
        fixedROI.width = viewPort.width / xMagFactor;
 | 
			
		||||
        fixedROI.height = viewPort.height / yMagFactor;
 | 
			
		||||
        zoomRegion.setROI(fixedROI);
 | 
			
		||||
@@ -452,15 +451,11 @@ var Magnifier = class Magnifier {
 | 
			
		||||
     * @clip:   Flag to indicate whether to clip the crosshairs.
 | 
			
		||||
     */
 | 
			
		||||
    setCrosshairsClip(clip) {
 | 
			
		||||
        if (clip) {
 | 
			
		||||
            if (this._crossHairs)
 | 
			
		||||
                this._crossHairs.setClip(CROSSHAIRS_CLIP_SIZE);
 | 
			
		||||
        } else {
 | 
			
		||||
            // Setting no clipping on crosshairs means a zero sized clip
 | 
			
		||||
            // rectangle.
 | 
			
		||||
            if (this._crossHairs)
 | 
			
		||||
                this._crossHairs.setClip([0, 0]);
 | 
			
		||||
        }
 | 
			
		||||
        if (!this._crossHairs)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        // Setting no clipping on crosshairs means a zero sized clip rectangle.
 | 
			
		||||
        this._crossHairs.setClip(clip ? CROSSHAIRS_CLIP_SIZE : [0, 0]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@@ -1144,7 +1139,7 @@ var ZoomRegion = class ZoomRegion {
 | 
			
		||||
 | 
			
		||||
    _clearScrollContentsTimer() {
 | 
			
		||||
        if (this._scrollContentsTimerId != 0) {
 | 
			
		||||
            Mainloop.source_remove(this._scrollContentsTimerId);
 | 
			
		||||
            GLib.source_remove(this._scrollContentsTimerId);
 | 
			
		||||
            this._scrollContentsTimerId = 0;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
@@ -1156,7 +1151,7 @@ var ZoomRegion = class ZoomRegion {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this._clearScrollContentsTimer();
 | 
			
		||||
        this._scrollContentsTimerId = Mainloop.timeout_add(POINTER_REST_TIME, () => {
 | 
			
		||||
        this._scrollContentsTimerId = GLib.timeout_add(GLib.PRIORITY_DEFAULT, POINTER_REST_TIME, () => {
 | 
			
		||||
            this._scrollContentsToDelayed(x, y);
 | 
			
		||||
            return GLib.SOURCE_REMOVE;
 | 
			
		||||
        });
 | 
			
		||||
@@ -1295,7 +1290,7 @@ var ZoomRegion = class ZoomRegion {
 | 
			
		||||
 | 
			
		||||
        // Add a background for when the magnified uiGroup is scrolled
 | 
			
		||||
        // out of view (don't want to see desktop showing through).
 | 
			
		||||
        this._background = (new Background.SystemBackground()).actor;
 | 
			
		||||
        this._background = new Background.SystemBackground();
 | 
			
		||||
        mainGroup.add_actor(this._background);
 | 
			
		||||
 | 
			
		||||
        // Clone the group that contains all of UI on the screen.  This is the
 | 
			
		||||
@@ -1592,8 +1587,9 @@ var ZoomRegion = class ZoomRegion {
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
var Crosshairs = class Crosshairs {
 | 
			
		||||
    constructor() {
 | 
			
		||||
var Crosshairs = GObject.registerClass(
 | 
			
		||||
class Crosshairs extends Clutter.Actor {
 | 
			
		||||
    _init() {
 | 
			
		||||
 | 
			
		||||
        // Set the group containing the crosshairs to three times the desktop
 | 
			
		||||
        // size in case the crosshairs need to appear to be infinite in
 | 
			
		||||
@@ -1601,7 +1597,7 @@ var Crosshairs = class Crosshairs {
 | 
			
		||||
        let groupWidth = global.screen_width * 3;
 | 
			
		||||
        let groupHeight = global.screen_height * 3;
 | 
			
		||||
 | 
			
		||||
        this._actor = new Clutter.Actor({
 | 
			
		||||
        super._init({
 | 
			
		||||
            clip_to_allocation: false,
 | 
			
		||||
            width: groupWidth,
 | 
			
		||||
            height: groupHeight
 | 
			
		||||
@@ -1610,10 +1606,10 @@ var Crosshairs = class Crosshairs {
 | 
			
		||||
        this._horizRightHair = new Clutter.Actor();
 | 
			
		||||
        this._vertTopHair = new Clutter.Actor();
 | 
			
		||||
        this._vertBottomHair = new Clutter.Actor();
 | 
			
		||||
        this._actor.add_actor(this._horizLeftHair);
 | 
			
		||||
        this._actor.add_actor(this._horizRightHair);
 | 
			
		||||
        this._actor.add_actor(this._vertTopHair);
 | 
			
		||||
        this._actor.add_actor(this._vertBottomHair);
 | 
			
		||||
        this.add_actor(this._horizLeftHair);
 | 
			
		||||
        this.add_actor(this._horizRightHair);
 | 
			
		||||
        this.add_actor(this._vertTopHair);
 | 
			
		||||
        this.add_actor(this._vertBottomHair);
 | 
			
		||||
        this._clipSize = [0, 0];
 | 
			
		||||
        this._clones = [];
 | 
			
		||||
        this.reCenter();
 | 
			
		||||
@@ -1623,7 +1619,7 @@ var Crosshairs = class Crosshairs {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _monitorsChanged() {
 | 
			
		||||
        this._actor.set_size(global.screen_width * 3, global.screen_height * 3);
 | 
			
		||||
        this.set_size(global.screen_width * 3, global.screen_height * 3);
 | 
			
		||||
        this.reCenter();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -1644,12 +1640,15 @@ var Crosshairs = class Crosshairs {
 | 
			
		||||
        if (zoomRegion && magnifiedMouse) {
 | 
			
		||||
            let container = magnifiedMouse.get_parent();
 | 
			
		||||
            if (container) {
 | 
			
		||||
                crosshairsActor = this._actor;
 | 
			
		||||
                if (this._actor.get_parent() != null) {
 | 
			
		||||
                    crosshairsActor = new Clutter.Clone({ source: this._actor });
 | 
			
		||||
                crosshairsActor = this;
 | 
			
		||||
                if (this.get_parent() != null) {
 | 
			
		||||
                    crosshairsActor = new Clutter.Clone({ source: this });
 | 
			
		||||
                    this._clones.push(crosshairsActor);
 | 
			
		||||
 | 
			
		||||
                    // Clones don't share visibility.
 | 
			
		||||
                    this.bind_property('visible', crosshairsActor, 'visible',
 | 
			
		||||
                                       GObject.BindingFlags.SYNC_CREATE);
 | 
			
		||||
                }
 | 
			
		||||
                crosshairsActor.visible = this._actor.visible;
 | 
			
		||||
 | 
			
		||||
                container.add_actor(crosshairsActor);
 | 
			
		||||
                container.raise_child(magnifiedMouse, crosshairsActor);
 | 
			
		||||
@@ -1668,7 +1667,7 @@ var Crosshairs = class Crosshairs {
 | 
			
		||||
     * child actor if it was just a clone of the crosshairs actor.
 | 
			
		||||
     */
 | 
			
		||||
    removeFromParent(childActor) {
 | 
			
		||||
        if (childActor == this._actor)
 | 
			
		||||
        if (childActor == this)
 | 
			
		||||
            childActor.get_parent().remove_actor(childActor);
 | 
			
		||||
        else
 | 
			
		||||
            childActor.destroy();
 | 
			
		||||
@@ -1778,28 +1777,6 @@ var Crosshairs = class Crosshairs {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * show:
 | 
			
		||||
     * Show the crosshairs.
 | 
			
		||||
     */
 | 
			
		||||
    show() {
 | 
			
		||||
        this._actor.show();
 | 
			
		||||
        // Clones don't share visibility.
 | 
			
		||||
        for (let i = 0; i < this._clones.length; i++)
 | 
			
		||||
            this._clones[i].show();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * hide:
 | 
			
		||||
     * Hide the crosshairs.
 | 
			
		||||
     */
 | 
			
		||||
    hide() {
 | 
			
		||||
        this._actor.hide();
 | 
			
		||||
        // Clones don't share visibility.
 | 
			
		||||
        for (let i = 0; i < this._clones.length; i++)
 | 
			
		||||
            this._clones[i].hide();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * reCenter:
 | 
			
		||||
     * Reposition the horizontal and vertical hairs such that they cross at
 | 
			
		||||
@@ -1808,7 +1785,7 @@ var Crosshairs = class Crosshairs {
 | 
			
		||||
     * @clipSize:  Optional.  If present, an array of the form [width, height].
 | 
			
		||||
     */
 | 
			
		||||
    reCenter(clipSize) {
 | 
			
		||||
        let [groupWidth, groupHeight] = this._actor.get_size();
 | 
			
		||||
        let [groupWidth, groupHeight] = this.get_size();
 | 
			
		||||
        let leftLength = this._horizLeftHair.get_width();
 | 
			
		||||
        let topLength = this._vertTopHair.get_height();
 | 
			
		||||
        let thickness = this._horizLeftHair.get_height();
 | 
			
		||||
@@ -1830,7 +1807,7 @@ var Crosshairs = class Crosshairs {
 | 
			
		||||
        this._vertTopHair.set_position((groupWidth - thickness) / 2, top);
 | 
			
		||||
        this._vertBottomHair.set_position((groupWidth - thickness) / 2, bottom);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
var MagShaderEffects = class MagShaderEffects {
 | 
			
		||||
    constructor(uiGroupClone) {
 | 
			
		||||
 
 | 
			
		||||
@@ -9,7 +9,6 @@
 | 
			
		||||
            initializeDeferredWork, getThemeStylesheet, setThemeStylesheet */
 | 
			
		||||
 | 
			
		||||
const { Clutter, Gio, GLib, GObject, Meta, Shell, St } = imports.gi;
 | 
			
		||||
const Mainloop = imports.mainloop;
 | 
			
		||||
 | 
			
		||||
const AccessDialog = imports.ui.accessDialog;
 | 
			
		||||
const AudioDeviceSelection = imports.ui.audioDeviceSelection;
 | 
			
		||||
@@ -190,7 +189,7 @@ function _initializeUI() {
 | 
			
		||||
 | 
			
		||||
    messageTray = new MessageTray.MessageTray();
 | 
			
		||||
    panel = new Panel.Panel();
 | 
			
		||||
    keyboard = new Keyboard.Keyboard();
 | 
			
		||||
    keyboard = new Keyboard.KeyboardManager();
 | 
			
		||||
    notificationDaemon = new NotificationDaemon.NotificationDaemon();
 | 
			
		||||
    windowAttentionHandler = new WindowAttentionHandler.WindowAttentionHandler();
 | 
			
		||||
    componentManager = new Components.ComponentManager();
 | 
			
		||||
@@ -230,7 +229,11 @@ function _initializeUI() {
 | 
			
		||||
    EndSessionDialog.init();
 | 
			
		||||
 | 
			
		||||
    // We're ready for the session manager to move to the next phase
 | 
			
		||||
    Meta.register_with_session();
 | 
			
		||||
    GLib.idle_add(GLib.PRIORITY_DEFAULT, () => {
 | 
			
		||||
        Shell.util_sd_notify();
 | 
			
		||||
        Meta.register_with_session();
 | 
			
		||||
        return GLib.SOURCE_REMOVE;
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    _startDate = new Date();
 | 
			
		||||
 | 
			
		||||
@@ -259,6 +262,19 @@ function _initializeUI() {
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let credentials = new Gio.Credentials();
 | 
			
		||||
        if (credentials.get_unix_user() === 0) {
 | 
			
		||||
            notify(_('Logged in as a privileged user'),
 | 
			
		||||
                   _('Running a session as a privileged user should be avoided for security reasons. If possible, you should log in as a normal user.'));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (sessionMode.currentMode !== 'gdm' &&
 | 
			
		||||
            sessionMode.currentMode !== 'initial-setup' &&
 | 
			
		||||
            screenShield === null) {
 | 
			
		||||
            notify(_('Screen Lock disabled'),
 | 
			
		||||
                   _('Screen Locking requires the GNOME display manager.'));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        LoginManager.registerSessionWithGDM();
 | 
			
		||||
 | 
			
		||||
        let perfModuleName = GLib.getenv("SHELL_PERF_MODULE");
 | 
			
		||||
@@ -387,7 +403,7 @@ function notify(msg, details) {
 | 
			
		||||
    messageTray.add(source);
 | 
			
		||||
    let notification = new MessageTray.Notification(source, msg, details);
 | 
			
		||||
    notification.setTransient(true);
 | 
			
		||||
    source.notify(notification);
 | 
			
		||||
    source.showNotification(notification);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -620,7 +636,7 @@ function _runDeferredWork(workId) {
 | 
			
		||||
    _deferredWorkQueue.splice(index, 1);
 | 
			
		||||
    _deferredWorkData[workId].callback();
 | 
			
		||||
    if (_deferredWorkQueue.length == 0 && _deferredTimeoutId > 0) {
 | 
			
		||||
        Mainloop.source_remove(_deferredTimeoutId);
 | 
			
		||||
        GLib.source_remove(_deferredTimeoutId);
 | 
			
		||||
        _deferredTimeoutId = 0;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -706,9 +722,8 @@ function queueDeferredWork(workId) {
 | 
			
		||||
        _deferredWorkQueue.push(workId);
 | 
			
		||||
    if (data.actor.mapped) {
 | 
			
		||||
        _queueBeforeRedraw(workId);
 | 
			
		||||
        return;
 | 
			
		||||
    } else if (_deferredTimeoutId == 0) {
 | 
			
		||||
        _deferredTimeoutId = Mainloop.timeout_add_seconds(DEFERRED_TIMEOUT_SECONDS, () => {
 | 
			
		||||
        _deferredTimeoutId = GLib.timeout_add_seconds(GLib.PRIORITY_DEFAULT, DEFERRED_TIMEOUT_SECONDS, () => {
 | 
			
		||||
            _runAllDeferredWork();
 | 
			
		||||
            _deferredTimeoutId = 0;
 | 
			
		||||
            return GLib.SOURCE_REMOVE;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,8 @@
 | 
			
		||||
const { Atk, Clutter, Gio, GLib, GObject, Meta, Pango, St } = imports.gi;
 | 
			
		||||
/* exported MessageListSection */
 | 
			
		||||
const { Atk, Clutter, Gio, GLib,
 | 
			
		||||
        GObject, Graphene, Meta, Pango, St } = imports.gi;
 | 
			
		||||
const Main = imports.ui.main;
 | 
			
		||||
const MessageTray = imports.ui.messageTray;
 | 
			
		||||
const Signals = imports.signals;
 | 
			
		||||
 | 
			
		||||
const Calendar = imports.ui.calendar;
 | 
			
		||||
const Util = imports.misc.util;
 | 
			
		||||
@@ -31,13 +32,18 @@ function _fixMarkup(text, allowMarkup) {
 | 
			
		||||
    return GLib.markup_escape_text(text, -1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var URLHighlighter = class URLHighlighter {
 | 
			
		||||
    constructor(text = '', lineWrap, allowMarkup) {
 | 
			
		||||
        this.actor = new St.Label({ reactive: true, style_class: 'url-highlighter',
 | 
			
		||||
                                    x_expand: true, x_align: Clutter.ActorAlign.START });
 | 
			
		||||
var URLHighlighter = GObject.registerClass(
 | 
			
		||||
class URLHighlighter extends St.Label {
 | 
			
		||||
    _init(text = '', lineWrap, allowMarkup) {
 | 
			
		||||
        super._init({
 | 
			
		||||
            reactive: true,
 | 
			
		||||
            style_class: 'url-highlighter',
 | 
			
		||||
            x_expand: true,
 | 
			
		||||
            x_align: Clutter.ActorAlign.START
 | 
			
		||||
        });
 | 
			
		||||
        this._linkColor = '#ccccff';
 | 
			
		||||
        this.actor.connect('style-changed', () => {
 | 
			
		||||
            let [hasColor, color] = this.actor.get_theme_node().lookup_color('link-color', false);
 | 
			
		||||
        this.connect('style-changed', () => {
 | 
			
		||||
            let [hasColor, color] = this.get_theme_node().lookup_color('link-color', false);
 | 
			
		||||
            if (hasColor) {
 | 
			
		||||
                let linkColor = color.to_string().substr(0, 7);
 | 
			
		||||
                if (linkColor != this._linkColor) {
 | 
			
		||||
@@ -46,70 +52,75 @@ var URLHighlighter = class URLHighlighter {
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
        this.actor.clutter_text.line_wrap = lineWrap;
 | 
			
		||||
        this.actor.clutter_text.line_wrap_mode = Pango.WrapMode.WORD_CHAR;
 | 
			
		||||
        this.clutter_text.line_wrap = lineWrap;
 | 
			
		||||
        this.clutter_text.line_wrap_mode = Pango.WrapMode.WORD_CHAR;
 | 
			
		||||
 | 
			
		||||
        this.setMarkup(text, allowMarkup);
 | 
			
		||||
        this.actor.connect('button-press-event', (actor, event) => {
 | 
			
		||||
            // Don't try to URL highlight when invisible.
 | 
			
		||||
            // The MessageTray doesn't actually hide us, so
 | 
			
		||||
            // we need to check for paint opacities as well.
 | 
			
		||||
            if (!actor.visible || actor.get_paint_opacity() == 0)
 | 
			
		||||
                return Clutter.EVENT_PROPAGATE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
            // Keep Notification.actor from seeing this and taking
 | 
			
		||||
            // a pointer grab, which would block our button-release-event
 | 
			
		||||
            // handler, if an URL is clicked
 | 
			
		||||
            return this._findUrlAtPos(event) != -1;
 | 
			
		||||
        });
 | 
			
		||||
        this.actor.connect('button-release-event', (actor, event) => {
 | 
			
		||||
            if (!actor.visible || actor.get_paint_opacity() == 0)
 | 
			
		||||
                return Clutter.EVENT_PROPAGATE;
 | 
			
		||||
 | 
			
		||||
            let urlId = this._findUrlAtPos(event);
 | 
			
		||||
            if (urlId != -1) {
 | 
			
		||||
                let url = this._urls[urlId].url;
 | 
			
		||||
                if (!url.includes(':'))
 | 
			
		||||
                    url = 'http://' + url;
 | 
			
		||||
 | 
			
		||||
                Gio.app_info_launch_default_for_uri(url, global.create_app_launch_context(0, -1));
 | 
			
		||||
                return Clutter.EVENT_STOP;
 | 
			
		||||
            }
 | 
			
		||||
    vfunc_button_press_event(buttonEvent) {
 | 
			
		||||
        // Don't try to URL highlight when invisible.
 | 
			
		||||
        // The MessageTray doesn't actually hide us, so
 | 
			
		||||
        // we need to check for paint opacities as well.
 | 
			
		||||
        if (!this.visible || this.get_paint_opacity() == 0)
 | 
			
		||||
            return Clutter.EVENT_PROPAGATE;
 | 
			
		||||
        });
 | 
			
		||||
        this.actor.connect('motion-event', (actor, event) => {
 | 
			
		||||
            if (!actor.visible || actor.get_paint_opacity() == 0)
 | 
			
		||||
                return Clutter.EVENT_PROPAGATE;
 | 
			
		||||
 | 
			
		||||
            let urlId = this._findUrlAtPos(event);
 | 
			
		||||
            if (urlId != -1 && !this._cursorChanged) {
 | 
			
		||||
                global.display.set_cursor(Meta.Cursor.POINTING_HAND);
 | 
			
		||||
                this._cursorChanged = true;
 | 
			
		||||
            } else if (urlId == -1) {
 | 
			
		||||
                global.display.set_cursor(Meta.Cursor.DEFAULT);
 | 
			
		||||
                this._cursorChanged = false;
 | 
			
		||||
            }
 | 
			
		||||
            return Clutter.EVENT_PROPAGATE;
 | 
			
		||||
        });
 | 
			
		||||
        this.actor.connect('leave-event', () => {
 | 
			
		||||
            if (!this.actor.visible || this.actor.get_paint_opacity() == 0)
 | 
			
		||||
                return Clutter.EVENT_PROPAGATE;
 | 
			
		||||
        // Keep Notification from seeing this and taking
 | 
			
		||||
        // a pointer grab, which would block our button-release-event
 | 
			
		||||
        // handler, if an URL is clicked
 | 
			
		||||
        return this._findUrlAtPos(buttonEvent) != -1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
            if (this._cursorChanged) {
 | 
			
		||||
                this._cursorChanged = false;
 | 
			
		||||
                global.display.set_cursor(Meta.Cursor.DEFAULT);
 | 
			
		||||
            }
 | 
			
		||||
    vfunc_button_release_event(buttonEvent) {
 | 
			
		||||
        if (!this.visible || this.get_paint_opacity() == 0)
 | 
			
		||||
            return Clutter.EVENT_PROPAGATE;
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        let urlId = this._findUrlAtPos(buttonEvent);
 | 
			
		||||
        if (urlId != -1) {
 | 
			
		||||
            let url = this._urls[urlId].url;
 | 
			
		||||
            if (!url.includes(':'))
 | 
			
		||||
                url = 'http://' + url;
 | 
			
		||||
 | 
			
		||||
            Gio.app_info_launch_default_for_uri(
 | 
			
		||||
                url, global.create_app_launch_context(0, -1));
 | 
			
		||||
            return Clutter.EVENT_STOP;
 | 
			
		||||
        }
 | 
			
		||||
        return Clutter.EVENT_PROPAGATE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    vfunc_motion_event(motionEvent) {
 | 
			
		||||
        if (!this.visible || this.get_paint_opacity() == 0)
 | 
			
		||||
            return Clutter.EVENT_PROPAGATE;
 | 
			
		||||
 | 
			
		||||
        let urlId = this._findUrlAtPos(motionEvent);
 | 
			
		||||
        if (urlId != -1 && !this._cursorChanged) {
 | 
			
		||||
            global.display.set_cursor(Meta.Cursor.POINTING_HAND);
 | 
			
		||||
            this._cursorChanged = true;
 | 
			
		||||
        } else if (urlId == -1) {
 | 
			
		||||
            global.display.set_cursor(Meta.Cursor.DEFAULT);
 | 
			
		||||
            this._cursorChanged = false;
 | 
			
		||||
        }
 | 
			
		||||
        return Clutter.EVENT_PROPAGATE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    vfunc_leave_event(crossingEvent) {
 | 
			
		||||
        if (!this.visible || this.get_paint_opacity() == 0)
 | 
			
		||||
            return Clutter.EVENT_PROPAGATE;
 | 
			
		||||
 | 
			
		||||
        if (this._cursorChanged) {
 | 
			
		||||
            this._cursorChanged = false;
 | 
			
		||||
            global.display.set_cursor(Meta.Cursor.DEFAULT);
 | 
			
		||||
        }
 | 
			
		||||
        return super.vfunc_leave_event(crossingEvent);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    setMarkup(text, allowMarkup) {
 | 
			
		||||
        text = text ? _fixMarkup(text, allowMarkup) : '';
 | 
			
		||||
        this._text = text;
 | 
			
		||||
 | 
			
		||||
        this.actor.clutter_text.set_markup(text);
 | 
			
		||||
        this.clutter_text.set_markup(text);
 | 
			
		||||
        /* clutter_text.text contain text without markup */
 | 
			
		||||
        this._urls = Util.findUrls(this.actor.clutter_text.text);
 | 
			
		||||
        this._urls = Util.findUrls(this.clutter_text.text);
 | 
			
		||||
        this._highlightUrls();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -125,16 +136,15 @@ var URLHighlighter = class URLHighlighter {
 | 
			
		||||
            pos = url.pos + url.url.length;
 | 
			
		||||
        }
 | 
			
		||||
        markup += this._text.substr(pos);
 | 
			
		||||
        this.actor.clutter_text.set_markup(markup);
 | 
			
		||||
        this.clutter_text.set_markup(markup);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _findUrlAtPos(event) {
 | 
			
		||||
        let success_;
 | 
			
		||||
        let [x, y] = event.get_coords();
 | 
			
		||||
        [success_, x, y] = this.actor.transform_stage_point(x, y);
 | 
			
		||||
        let { x, y } = event;
 | 
			
		||||
        [, x, y] = this.transform_stage_point(x, y);
 | 
			
		||||
        let findPos = -1;
 | 
			
		||||
        for (let i = 0; i < this.actor.clutter_text.text.length; i++) {
 | 
			
		||||
            let [success_, px, py, lineHeight] = this.actor.clutter_text.position_to_coords(i);
 | 
			
		||||
        for (let i = 0; i < this.clutter_text.text.length; i++) {
 | 
			
		||||
            let [, px, py, lineHeight] = this.clutter_text.position_to_coords(i);
 | 
			
		||||
            if (py > y || py + lineHeight < y || x < px)
 | 
			
		||||
                continue;
 | 
			
		||||
            findPos = i;
 | 
			
		||||
@@ -147,7 +157,7 @@ var URLHighlighter = class URLHighlighter {
 | 
			
		||||
        }
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
var ScaleLayout = GObject.registerClass(
 | 
			
		||||
class ScaleLayout extends Clutter.BinLayout {
 | 
			
		||||
@@ -283,21 +293,29 @@ var LabelExpanderLayout = GObject.registerClass({
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
var Message = class Message {
 | 
			
		||||
    constructor(title, body) {
 | 
			
		||||
        this.expanded = false;
 | 
			
		||||
 | 
			
		||||
var Message = GObject.registerClass({
 | 
			
		||||
    GTypeName: 'MessageList_Message',
 | 
			
		||||
    Signals: {
 | 
			
		||||
        'close': {},
 | 
			
		||||
        'expanded': {},
 | 
			
		||||
        'unexpanded': {},
 | 
			
		||||
    }
 | 
			
		||||
}, class Message extends St.Button {
 | 
			
		||||
    _init(title, body) {
 | 
			
		||||
        super._init({
 | 
			
		||||
            style_class: 'message',
 | 
			
		||||
            accessible_role: Atk.Role.NOTIFICATION,
 | 
			
		||||
            can_focus: true,
 | 
			
		||||
            x_expand: true,
 | 
			
		||||
            x_fill: true
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        this.expanded = false;
 | 
			
		||||
        this._useBodyMarkup = false;
 | 
			
		||||
 | 
			
		||||
        this.actor = new St.Button({ style_class: 'message',
 | 
			
		||||
                                     accessible_role: Atk.Role.NOTIFICATION,
 | 
			
		||||
                                     can_focus: true,
 | 
			
		||||
                                     x_expand: true, x_fill: true });
 | 
			
		||||
        this.actor.connect('key-press-event',
 | 
			
		||||
                           this._onKeyPressed.bind(this));
 | 
			
		||||
 | 
			
		||||
        let vbox = new St.BoxLayout({ vertical: true });
 | 
			
		||||
        this.actor.set_child(vbox);
 | 
			
		||||
        this.set_child(vbox);
 | 
			
		||||
 | 
			
		||||
        let hbox = new St.BoxLayout();
 | 
			
		||||
        vbox.add_actor(hbox);
 | 
			
		||||
@@ -341,15 +359,14 @@ var Message = class Message {
 | 
			
		||||
        contentBox.add_actor(this._bodyStack);
 | 
			
		||||
 | 
			
		||||
        this.bodyLabel = new URLHighlighter('', false, this._useBodyMarkup);
 | 
			
		||||
        this.bodyLabel.actor.add_style_class_name('message-body');
 | 
			
		||||
        this._bodyStack.add_actor(this.bodyLabel.actor);
 | 
			
		||||
        this.bodyLabel.add_style_class_name('message-body');
 | 
			
		||||
        this._bodyStack.add_actor(this.bodyLabel);
 | 
			
		||||
        this.setBody(body);
 | 
			
		||||
 | 
			
		||||
        this._closeButton.connect('clicked', this.close.bind(this));
 | 
			
		||||
        let actorHoverId = this.actor.connect('notify::hover', this._sync.bind(this));
 | 
			
		||||
        this._closeButton.connect('destroy', this.actor.disconnect.bind(this.actor, actorHoverId));
 | 
			
		||||
        this.actor.connect('clicked', this._onClicked.bind(this));
 | 
			
		||||
        this.actor.connect('destroy', this._onDestroy.bind(this));
 | 
			
		||||
        let actorHoverId = this.connect('notify::hover', this._sync.bind(this));
 | 
			
		||||
        this._closeButton.connect('destroy', this.disconnect.bind(this, actorHoverId));
 | 
			
		||||
        this.connect('destroy', this._onDestroy.bind(this));
 | 
			
		||||
        this._sync();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -435,7 +452,7 @@ var Message = class Message {
 | 
			
		||||
        if (this._bodyStack.get_n_children() < 2) {
 | 
			
		||||
            this._expandedLabel = new URLHighlighter(this._bodyText,
 | 
			
		||||
                                                     true, this._useBodyMarkup);
 | 
			
		||||
            this.setExpandedBody(this._expandedLabel.actor);
 | 
			
		||||
            this.setExpandedBody(this._expandedLabel);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (animate) {
 | 
			
		||||
@@ -488,19 +505,16 @@ var Message = class Message {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _sync() {
 | 
			
		||||
        let visible = this.actor.hover && this.canClose();
 | 
			
		||||
        let visible = this.hover && this.canClose();
 | 
			
		||||
        this._closeButton.opacity = visible ? 255 : 0;
 | 
			
		||||
        this._closeButton.reactive = visible;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _onClicked() {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _onDestroy() {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _onKeyPressed(a, event) {
 | 
			
		||||
        let keysym = event.get_key_symbol();
 | 
			
		||||
    vfunc_key_press_event(keyEvent) {
 | 
			
		||||
        let keysym = keyEvent.keyval;
 | 
			
		||||
 | 
			
		||||
        if (keysym == Clutter.KEY_Delete ||
 | 
			
		||||
            keysym == Clutter.KEY_KP_Delete) {
 | 
			
		||||
@@ -509,37 +523,66 @@ var Message = class Message {
 | 
			
		||||
        }
 | 
			
		||||
        return Clutter.EVENT_PROPAGATE;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
Signals.addSignalMethods(Message.prototype);
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
var MessageListSection = class MessageListSection {
 | 
			
		||||
    constructor() {
 | 
			
		||||
        this.actor = new St.BoxLayout({ style_class: 'message-list-section',
 | 
			
		||||
                                        clip_to_allocation: true,
 | 
			
		||||
                                        x_expand: true, vertical: true });
 | 
			
		||||
var MessageListSection = GObject.registerClass({
 | 
			
		||||
    Properties: {
 | 
			
		||||
        'can-clear': GObject.ParamSpec.boolean(
 | 
			
		||||
            'can-clear', 'can-clear', 'can-clear',
 | 
			
		||||
            GObject.ParamFlags.READABLE,
 | 
			
		||||
            false),
 | 
			
		||||
        'empty': GObject.ParamSpec.boolean(
 | 
			
		||||
            'empty', 'empty', 'empty',
 | 
			
		||||
            GObject.ParamFlags.READABLE,
 | 
			
		||||
            true),
 | 
			
		||||
    },
 | 
			
		||||
    Signals: {
 | 
			
		||||
        'can-clear-changed': {},
 | 
			
		||||
        'empty-changed': {},
 | 
			
		||||
        'message-focused': { param_types: [Message.$gtype] },
 | 
			
		||||
    }
 | 
			
		||||
}, class MessageListSection extends St.BoxLayout {
 | 
			
		||||
    _init() {
 | 
			
		||||
        super._init({
 | 
			
		||||
            style_class: 'message-list-section',
 | 
			
		||||
            clip_to_allocation: true,
 | 
			
		||||
            vertical: true,
 | 
			
		||||
            x_expand: true
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        this._list = new St.BoxLayout({ style_class: 'message-list-section-list',
 | 
			
		||||
                                        vertical: true });
 | 
			
		||||
        this.actor.add_actor(this._list);
 | 
			
		||||
        this.add_actor(this._list);
 | 
			
		||||
 | 
			
		||||
        this._list.connect('actor-added', this._sync.bind(this));
 | 
			
		||||
        this._list.connect('actor-removed', this._sync.bind(this));
 | 
			
		||||
 | 
			
		||||
        let id = Main.sessionMode.connect('updated',
 | 
			
		||||
                                          this._sync.bind(this));
 | 
			
		||||
        this.actor.connect('destroy', () => {
 | 
			
		||||
        this.connect('destroy', () => {
 | 
			
		||||
            Main.sessionMode.disconnect(id);
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        this._messages = new Map();
 | 
			
		||||
        this._date = new Date();
 | 
			
		||||
        this.empty = true;
 | 
			
		||||
        this.canClear = false;
 | 
			
		||||
        this._empty = true;
 | 
			
		||||
        this._canClear = false;
 | 
			
		||||
        this._sync();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _onKeyFocusIn(actor) {
 | 
			
		||||
        this.emit('key-focus-in', actor);
 | 
			
		||||
    get empty() {
 | 
			
		||||
        return this._empty;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    get canClear() {
 | 
			
		||||
        return this._canClear;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    get _messages() {
 | 
			
		||||
        return this._list.get_children().map(i => i.child);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _onKeyFocusIn(messageActor) {
 | 
			
		||||
        this.emit('message-focused', messageActor);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    get allowed() {
 | 
			
		||||
@@ -558,58 +601,62 @@ var MessageListSection = class MessageListSection {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    addMessageAtIndex(message, index, animate) {
 | 
			
		||||
        let obj = {
 | 
			
		||||
            container: null,
 | 
			
		||||
            destroyId: 0,
 | 
			
		||||
            keyFocusId: 0,
 | 
			
		||||
            closeId: 0
 | 
			
		||||
        };
 | 
			
		||||
        let pivot = new Clutter.Point({ x: .5, y: .5 });
 | 
			
		||||
        let scale = animate ? 0 : 1;
 | 
			
		||||
        obj.container = new St.Widget({ layout_manager: new ScaleLayout(),
 | 
			
		||||
                                        pivot_point: pivot,
 | 
			
		||||
                                        scale_x: scale, scale_y: scale });
 | 
			
		||||
        obj.keyFocusId = message.actor.connect('key-focus-in',
 | 
			
		||||
            this._onKeyFocusIn.bind(this));
 | 
			
		||||
        obj.destroyId = message.actor.connect('destroy', () => {
 | 
			
		||||
            this.removeMessage(message, false);
 | 
			
		||||
        if (this._messages.includes(message))
 | 
			
		||||
            throw new Error('Message was already added previously');
 | 
			
		||||
 | 
			
		||||
        let listItem = new St.Bin({
 | 
			
		||||
            child: message,
 | 
			
		||||
            x_fill: true,
 | 
			
		||||
            y_fill: true,
 | 
			
		||||
            layout_manager: new ScaleLayout(),
 | 
			
		||||
            pivot_point: new Graphene.Point({ x: .5, y: .5 }),
 | 
			
		||||
        });
 | 
			
		||||
        obj.closeId = message.connect('close', () => {
 | 
			
		||||
        listItem._connectionsIds = [];
 | 
			
		||||
 | 
			
		||||
        listItem._connectionsIds.push(message.connect('key-focus-in',
 | 
			
		||||
            this._onKeyFocusIn.bind(this)));
 | 
			
		||||
        listItem._connectionsIds.push(message.connect('close', () => {
 | 
			
		||||
            this.removeMessage(message, true);
 | 
			
		||||
        });
 | 
			
		||||
        }));
 | 
			
		||||
        listItem._connectionsIds.push(message.connect('destroy', () => {
 | 
			
		||||
            listItem._connectionsIds.forEach(id => message.disconnect(id));
 | 
			
		||||
            listItem.destroy();
 | 
			
		||||
        }));
 | 
			
		||||
 | 
			
		||||
        this._messages.set(message, obj);
 | 
			
		||||
        obj.container.add_actor(message.actor);
 | 
			
		||||
        this._list.insert_child_at_index(listItem, index);
 | 
			
		||||
 | 
			
		||||
        this._list.insert_child_at_index(obj.container, index);
 | 
			
		||||
 | 
			
		||||
        if (animate)
 | 
			
		||||
            obj.container.ease({
 | 
			
		||||
        if (animate) {
 | 
			
		||||
            listItem.set({ scale_x: 0, scale_y: 0 });
 | 
			
		||||
            listItem.ease({
 | 
			
		||||
                scale_x: 1,
 | 
			
		||||
                scale_y: 1,
 | 
			
		||||
                duration: MESSAGE_ANIMATION_TIME,
 | 
			
		||||
                mode: Clutter.AnimationMode.EASE_OUT_QUAD
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    moveMessage(message, index, animate) {
 | 
			
		||||
        let obj = this._messages.get(message);
 | 
			
		||||
        if (!this._messages.includes(message))
 | 
			
		||||
            throw new Error(`Impossible to move the untracked message ${message}`);
 | 
			
		||||
 | 
			
		||||
        let listItem = message.get_parent();
 | 
			
		||||
 | 
			
		||||
        if (!animate) {
 | 
			
		||||
            this._list.set_child_at_index(obj.container, index);
 | 
			
		||||
            this._list.set_child_at_index(listItem, index);
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let onComplete = () => {
 | 
			
		||||
            this._list.set_child_at_index(obj.container, index);
 | 
			
		||||
            obj.container.ease({
 | 
			
		||||
            this._list.set_child_at_index(listItem, index);
 | 
			
		||||
            listItem.ease({
 | 
			
		||||
                scale_x: 1,
 | 
			
		||||
                scale_y: 1,
 | 
			
		||||
                duration: MESSAGE_ANIMATION_TIME,
 | 
			
		||||
                mode: Clutter.AnimationMode.EASE_OUT_QUAD
 | 
			
		||||
            });
 | 
			
		||||
        };
 | 
			
		||||
        obj.container.ease({
 | 
			
		||||
        listItem.ease({
 | 
			
		||||
            scale_x: 0,
 | 
			
		||||
            scale_y: 0,
 | 
			
		||||
            duration: MESSAGE_ANIMATION_TIME,
 | 
			
		||||
@@ -619,33 +666,31 @@ var MessageListSection = class MessageListSection {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    removeMessage(message, animate) {
 | 
			
		||||
        let obj = this._messages.get(message);
 | 
			
		||||
        if (!this._messages.includes(message))
 | 
			
		||||
            throw new Error(`Impossible to remove the untracked message ${message}`);
 | 
			
		||||
 | 
			
		||||
        message.actor.disconnect(obj.destroyId);
 | 
			
		||||
        message.actor.disconnect(obj.keyFocusId);
 | 
			
		||||
        message.disconnect(obj.closeId);
 | 
			
		||||
 | 
			
		||||
        this._messages.delete(message);
 | 
			
		||||
        let listItem = message.get_parent();
 | 
			
		||||
        listItem._connectionsIds.forEach(id => message.disconnect(id));
 | 
			
		||||
 | 
			
		||||
        if (animate) {
 | 
			
		||||
            obj.container.ease({
 | 
			
		||||
            listItem.ease({
 | 
			
		||||
                scale_x: 0,
 | 
			
		||||
                scale_y: 0,
 | 
			
		||||
                duration: MESSAGE_ANIMATION_TIME,
 | 
			
		||||
                mode: Clutter.AnimationMode.EASE_OUT_QUAD,
 | 
			
		||||
                onComplete: () => {
 | 
			
		||||
                    obj.container.destroy();
 | 
			
		||||
                    listItem.destroy();
 | 
			
		||||
                    global.sync_pointer();
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
        } else {
 | 
			
		||||
            obj.container.destroy();
 | 
			
		||||
            listItem.destroy();
 | 
			
		||||
            global.sync_pointer();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    clear() {
 | 
			
		||||
        let messages = [...this._messages.keys()].filter(msg => msg.canClose());
 | 
			
		||||
        let messages = this._messages.filter(msg => msg.canClose());
 | 
			
		||||
 | 
			
		||||
        // If there are few messages, letting them all zoom out looks OK
 | 
			
		||||
        if (messages.length < 2) {
 | 
			
		||||
@@ -658,9 +703,8 @@ var MessageListSection = class MessageListSection {
 | 
			
		||||
            let delay = MESSAGE_ANIMATION_TIME / Math.max(messages.length, 5);
 | 
			
		||||
            for (let i = 0; i < messages.length; i++) {
 | 
			
		||||
                let message = messages[i];
 | 
			
		||||
                let obj = this._messages.get(message);
 | 
			
		||||
                obj.container.ease({
 | 
			
		||||
                    anchor_x: this._list.width,
 | 
			
		||||
                message.get_parent().ease({
 | 
			
		||||
                    translation_x: this._list.width,
 | 
			
		||||
                    opacity: 0,
 | 
			
		||||
                    duration: MESSAGE_ANIMATION_TIME,
 | 
			
		||||
                    delay: i * delay,
 | 
			
		||||
@@ -671,33 +715,25 @@ var MessageListSection = class MessageListSection {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _canClear() {
 | 
			
		||||
        for (let message of this._messages.keys())
 | 
			
		||||
            if (message.canClose())
 | 
			
		||||
                return true;
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _shouldShow() {
 | 
			
		||||
        return !this.empty;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _sync() {
 | 
			
		||||
        let empty = this._list.get_n_children() == 0;
 | 
			
		||||
        let changed = this.empty !== empty;
 | 
			
		||||
        this.empty = empty;
 | 
			
		||||
        let messages = this._messages;
 | 
			
		||||
        let empty = messages.length == 0;
 | 
			
		||||
 | 
			
		||||
        if (changed)
 | 
			
		||||
            this.emit('empty-changed');
 | 
			
		||||
        if (this._empty != empty) {
 | 
			
		||||
            this._empty = empty;
 | 
			
		||||
            this.notify('empty');
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let canClear = this._canClear();
 | 
			
		||||
        changed = this.canClear !== canClear;
 | 
			
		||||
        this.canClear = canClear;
 | 
			
		||||
        let canClear = messages.some(m => m.canClose());
 | 
			
		||||
        if (this._canClear != canClear) {
 | 
			
		||||
            this._canClear = canClear;
 | 
			
		||||
            this.notify('can-clear');
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (changed)
 | 
			
		||||
            this.emit('can-clear-changed');
 | 
			
		||||
 | 
			
		||||
        this.actor.visible = this.allowed && this._shouldShow();
 | 
			
		||||
        this.visible = this.allowed && this._shouldShow();
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
Signals.addSignalMethods(MessageListSection.prototype);
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -4,8 +4,6 @@
 | 
			
		||||
   SystemNotificationSource, MessageTray */
 | 
			
		||||
 | 
			
		||||
const { Clutter, Gio, GLib, GObject, Meta, Shell, St } = imports.gi;
 | 
			
		||||
const Mainloop = imports.mainloop;
 | 
			
		||||
const Signals = imports.signals;
 | 
			
		||||
 | 
			
		||||
const Calendar = imports.ui.calendar;
 | 
			
		||||
const GnomeSession = imports.misc.gnomeSession;
 | 
			
		||||
@@ -135,70 +133,84 @@ var FocusGrabber = class FocusGrabber {
 | 
			
		||||
// source, such as whether to play sound or honour the critical bit.
 | 
			
		||||
//
 | 
			
		||||
// A notification without a policy object will inherit the default one.
 | 
			
		||||
var NotificationPolicy = class NotificationPolicy {
 | 
			
		||||
    constructor(params) {
 | 
			
		||||
        params = Params.parse(params, { enable: true,
 | 
			
		||||
                                        enableSound: true,
 | 
			
		||||
                                        showBanners: true,
 | 
			
		||||
                                        forceExpanded: false,
 | 
			
		||||
                                        showInLockScreen: true,
 | 
			
		||||
                                        detailsInLockScreen: false
 | 
			
		||||
                                      });
 | 
			
		||||
        Object.getOwnPropertyNames(params).forEach(key => {
 | 
			
		||||
            let desc = Object.getOwnPropertyDescriptor(params, key);
 | 
			
		||||
            Object.defineProperty(this, `_${key}`, desc);
 | 
			
		||||
        });
 | 
			
		||||
var NotificationPolicy = GObject.registerClass({
 | 
			
		||||
    GTypeName: 'MessageTray_NotificationPolicy',
 | 
			
		||||
    Properties: {
 | 
			
		||||
        'enable': GObject.ParamSpec.boolean(
 | 
			
		||||
            'enable', 'enable', 'enable',
 | 
			
		||||
            GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY,
 | 
			
		||||
            true),
 | 
			
		||||
        'enable-sound': GObject.ParamSpec.boolean(
 | 
			
		||||
            'enable-sound', 'enable-sound', 'enable-sound',
 | 
			
		||||
            GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY,
 | 
			
		||||
            true),
 | 
			
		||||
        'show-banners': GObject.ParamSpec.boolean(
 | 
			
		||||
            'show-banners', 'show-banners', 'show-banners',
 | 
			
		||||
            GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY,
 | 
			
		||||
            true),
 | 
			
		||||
        'force-expanded': GObject.ParamSpec.boolean(
 | 
			
		||||
            'force-expanded', 'force-expanded', 'force-expanded',
 | 
			
		||||
            GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY,
 | 
			
		||||
            false),
 | 
			
		||||
        'show-in-lock-screen': GObject.ParamSpec.boolean(
 | 
			
		||||
            'show-in-lock-screen', 'show-in-lock-screen', 'show-in-lock-screen',
 | 
			
		||||
            GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY,
 | 
			
		||||
            false),
 | 
			
		||||
        'details-in-lock-screen': GObject.ParamSpec.boolean(
 | 
			
		||||
            'details-in-lock-screen', 'details-in-lock-screen', 'details-in-lock-screen',
 | 
			
		||||
            GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY,
 | 
			
		||||
            false),
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}, class NotificationPolicy extends GObject.Object {
 | 
			
		||||
    // Do nothing for the default policy. These methods are only useful for the
 | 
			
		||||
    // GSettings policy.
 | 
			
		||||
    store() { }
 | 
			
		||||
    destroy() { }
 | 
			
		||||
 | 
			
		||||
    get enable() {
 | 
			
		||||
        return this._enable;
 | 
			
		||||
    destroy() {
 | 
			
		||||
        this.run_dispose();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    get enableSound() {
 | 
			
		||||
        return this._enableSound;
 | 
			
		||||
        return this.enable_sound;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    get showBanners() {
 | 
			
		||||
        return this._showBanners;
 | 
			
		||||
        return this.show_banners;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    get forceExpanded() {
 | 
			
		||||
        return this._forceExpanded;
 | 
			
		||||
        return this.force_expanded;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    get showInLockScreen() {
 | 
			
		||||
        return this._showInLockScreen;
 | 
			
		||||
        return this.show_in_lock_screen;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    get detailsInLockScreen() {
 | 
			
		||||
        return this._detailsInLockScreen;
 | 
			
		||||
        return this.details_in_lock_screen;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
Signals.addSignalMethods(NotificationPolicy.prototype);
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
var NotificationGenericPolicy =
 | 
			
		||||
class NotificationGenericPolicy extends NotificationPolicy {
 | 
			
		||||
    constructor() {
 | 
			
		||||
        super();
 | 
			
		||||
var NotificationGenericPolicy = GObject.registerClass({
 | 
			
		||||
    GTypeName: 'MessageTray_NotificationGenericPolicy'
 | 
			
		||||
}, class NotificationGenericPolicy extends NotificationPolicy {
 | 
			
		||||
    _init() {
 | 
			
		||||
        super._init();
 | 
			
		||||
        this.id = 'generic';
 | 
			
		||||
 | 
			
		||||
        this._masterSettings = new Gio.Settings({ schema_id: 'org.gnome.desktop.notifications' });
 | 
			
		||||
        this._masterSettings.connect('changed', this._changed.bind(this));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    store() { }
 | 
			
		||||
 | 
			
		||||
    destroy() {
 | 
			
		||||
        this._masterSettings.run_dispose();
 | 
			
		||||
 | 
			
		||||
        super.destroy();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _changed(settings, key) {
 | 
			
		||||
        this.emit('policy-changed', key);
 | 
			
		||||
        if (this.constructor.find_property(key))
 | 
			
		||||
            this.notify(key);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    get showBanners() {
 | 
			
		||||
@@ -208,12 +220,13 @@ class NotificationGenericPolicy extends NotificationPolicy {
 | 
			
		||||
    get showInLockScreen() {
 | 
			
		||||
        return this._masterSettings.get_boolean('show-in-lock-screen');
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
var NotificationApplicationPolicy =
 | 
			
		||||
class NotificationApplicationPolicy extends NotificationPolicy {
 | 
			
		||||
    constructor(id) {
 | 
			
		||||
        super();
 | 
			
		||||
var NotificationApplicationPolicy = GObject.registerClass({
 | 
			
		||||
    GTypeName: 'MessageTray_NotificationApplicationPolicy'
 | 
			
		||||
}, class NotificationApplicationPolicy extends NotificationPolicy {
 | 
			
		||||
    _init(id) {
 | 
			
		||||
        super._init();
 | 
			
		||||
 | 
			
		||||
        this.id = id;
 | 
			
		||||
        this._canonicalId = this._canonicalizeId(id);
 | 
			
		||||
@@ -239,12 +252,13 @@ class NotificationApplicationPolicy extends NotificationPolicy {
 | 
			
		||||
    destroy() {
 | 
			
		||||
        this._masterSettings.run_dispose();
 | 
			
		||||
        this._settings.run_dispose();
 | 
			
		||||
 | 
			
		||||
        super.destroy();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _changed(settings, key) {
 | 
			
		||||
        this.emit('policy-changed', key);
 | 
			
		||||
        if (key == 'enable')
 | 
			
		||||
            this.emit('enable-changed');
 | 
			
		||||
        if (this.constructor.find_property(key))
 | 
			
		||||
            this.notify(key);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _canonicalizeId(id) {
 | 
			
		||||
@@ -278,7 +292,7 @@ class NotificationApplicationPolicy extends NotificationPolicy {
 | 
			
		||||
    get detailsInLockScreen() {
 | 
			
		||||
        return this._settings.get_boolean('details-in-lock-screen');
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
// Notification:
 | 
			
		||||
// @source: the notification's Source
 | 
			
		||||
@@ -334,13 +348,27 @@ class NotificationApplicationPolicy extends NotificationPolicy {
 | 
			
		||||
// event sound is played when the notification is shown (if the policy for
 | 
			
		||||
// @source allows playing sounds).
 | 
			
		||||
//
 | 
			
		||||
// [1] https://developer.gnome.org/notification-spec/#markup 
 | 
			
		||||
var Notification = class Notification {
 | 
			
		||||
    constructor(source, title, banner, params) {
 | 
			
		||||
// [1] https://developer.gnome.org/notification-spec/#markup
 | 
			
		||||
var Notification = GObject.registerClass({
 | 
			
		||||
    GTypeName: 'MessageTray_Notification',
 | 
			
		||||
    Properties: {
 | 
			
		||||
        'acknowledged': GObject.ParamSpec.boolean(
 | 
			
		||||
            'acknowledged', 'acknowledged', 'acknowledged',
 | 
			
		||||
            GObject.ParamFlags.READWRITE,
 | 
			
		||||
            false),
 | 
			
		||||
    },
 | 
			
		||||
    Signals: {
 | 
			
		||||
        'activated': {},
 | 
			
		||||
        'destroy': { param_types: [GObject.TYPE_UINT] },
 | 
			
		||||
        'updated': { param_types: [GObject.TYPE_BOOLEAN] },
 | 
			
		||||
    }
 | 
			
		||||
}, class Notification extends GObject.Object {
 | 
			
		||||
    _init(source, title, banner, params) {
 | 
			
		||||
        super._init();
 | 
			
		||||
 | 
			
		||||
        this.source = source;
 | 
			
		||||
        this.title = title;
 | 
			
		||||
        this.urgency = Urgency.NORMAL;
 | 
			
		||||
        this.resident = false;
 | 
			
		||||
        // 'transient' is a reserved keyword in JS, so we have to use an alternate variable name
 | 
			
		||||
        this.isTransient = false;
 | 
			
		||||
        this.privacyScope = PrivacyScope.USER;
 | 
			
		||||
@@ -352,6 +380,7 @@ var Notification = class Notification {
 | 
			
		||||
        this._soundFile = null;
 | 
			
		||||
        this._soundPlayed = false;
 | 
			
		||||
        this.actions = [];
 | 
			
		||||
        this.setResident(false);
 | 
			
		||||
 | 
			
		||||
        // If called with only one argument we assume the caller
 | 
			
		||||
        // will call .update() later on. This is the case of
 | 
			
		||||
@@ -421,7 +450,7 @@ var Notification = class Notification {
 | 
			
		||||
        if (this._acknowledged == v)
 | 
			
		||||
            return;
 | 
			
		||||
        this._acknowledged = v;
 | 
			
		||||
        this.emit('acknowledged-changed');
 | 
			
		||||
        this.notify('acknowledged');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    setUrgency(urgency) {
 | 
			
		||||
@@ -430,6 +459,15 @@ var Notification = class Notification {
 | 
			
		||||
 | 
			
		||||
    setResident(resident) {
 | 
			
		||||
        this.resident = resident;
 | 
			
		||||
 | 
			
		||||
        if (this.resident) {
 | 
			
		||||
            if (this._activatedId) {
 | 
			
		||||
                this.disconnect(this._activatedId);
 | 
			
		||||
                this._activatedId = 0;
 | 
			
		||||
            }
 | 
			
		||||
        } else if (!this._activatedId) {
 | 
			
		||||
            this._activatedId = this.connect_after('activated', () => this.destroy());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    setTransient(isTransient) {
 | 
			
		||||
@@ -471,23 +509,30 @@ var Notification = class Notification {
 | 
			
		||||
 | 
			
		||||
    activate() {
 | 
			
		||||
        this.emit('activated');
 | 
			
		||||
        if (!this.resident)
 | 
			
		||||
            this.destroy();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    destroy(reason = NotificationDestroyedReason.DISMISSED) {
 | 
			
		||||
        if (this._activatedId) {
 | 
			
		||||
            this.disconnect(this._activatedId);
 | 
			
		||||
            delete this._activatedId;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this.emit('destroy', reason);
 | 
			
		||||
        this.run_dispose();
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
Signals.addSignalMethods(Notification.prototype);
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
var NotificationBanner =
 | 
			
		||||
class NotificationBanner extends Calendar.NotificationMessage {
 | 
			
		||||
    constructor(notification) {
 | 
			
		||||
        super(notification);
 | 
			
		||||
var NotificationBanner = GObject.registerClass({
 | 
			
		||||
    Signals: {
 | 
			
		||||
        'done-displaying': {},
 | 
			
		||||
        'unfocused': {},
 | 
			
		||||
    }
 | 
			
		||||
}, class NotificationBanner extends Calendar.NotificationMessage {
 | 
			
		||||
    _init(notification) {
 | 
			
		||||
        super._init(notification);
 | 
			
		||||
 | 
			
		||||
        this.actor.can_focus = false;
 | 
			
		||||
        this.actor.add_style_class_name('notification-banner');
 | 
			
		||||
        this.can_focus = false;
 | 
			
		||||
        this.add_style_class_name('notification-banner');
 | 
			
		||||
 | 
			
		||||
        this._buttonBox = null;
 | 
			
		||||
 | 
			
		||||
@@ -574,7 +619,7 @@ class NotificationBanner extends Calendar.NotificationMessage {
 | 
			
		||||
 | 
			
		||||
        return this.addButton(button, callback);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
var SourceActor = GObject.registerClass(
 | 
			
		||||
class SourceActor extends St.Widget {
 | 
			
		||||
@@ -639,7 +684,7 @@ class SourceActorWithLabel extends SourceActor {
 | 
			
		||||
 | 
			
		||||
        this.add_actor(this._counterBin);
 | 
			
		||||
 | 
			
		||||
        this._countUpdatedId = this._source.connect('count-updated', this._updateCount.bind(this));
 | 
			
		||||
        this._countUpdatedId = this._source.connect('notify::count', this._updateCount.bind(this));
 | 
			
		||||
        this._updateCount();
 | 
			
		||||
 | 
			
		||||
        this.connect('destroy', () => {
 | 
			
		||||
@@ -687,11 +732,34 @@ class SourceActorWithLabel extends SourceActor {
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
var Source = class Source {
 | 
			
		||||
    constructor(title, iconName) {
 | 
			
		||||
var Source = GObject.registerClass({
 | 
			
		||||
    GTypeName: 'MessageTray_Source',
 | 
			
		||||
    Properties: {
 | 
			
		||||
        'count': GObject.ParamSpec.int(
 | 
			
		||||
            'count', 'count', 'count',
 | 
			
		||||
            GObject.ParamFlags.READABLE,
 | 
			
		||||
            0, GLib.MAXINT32, 0),
 | 
			
		||||
        'policy': GObject.ParamSpec.object(
 | 
			
		||||
            'policy', 'policy', 'policy',
 | 
			
		||||
            GObject.ParamFlags.READWRITE,
 | 
			
		||||
            NotificationPolicy.$gtype),
 | 
			
		||||
        'title': GObject.ParamSpec.string(
 | 
			
		||||
            'title', 'title', 'title',
 | 
			
		||||
            GObject.ParamFlags.READWRITE,
 | 
			
		||||
            null),
 | 
			
		||||
    },
 | 
			
		||||
    Signals: {
 | 
			
		||||
        'destroy': { param_types: [GObject.TYPE_UINT] },
 | 
			
		||||
        'icon-updated': {},
 | 
			
		||||
        'notification-added': { param_types: [Notification.$gtype] },
 | 
			
		||||
        'notification-show': { param_types: [Notification.$gtype] },
 | 
			
		||||
    }
 | 
			
		||||
}, class Source extends GObject.Object {
 | 
			
		||||
    _init(title, iconName) {
 | 
			
		||||
        super._init({ title: title });
 | 
			
		||||
 | 
			
		||||
        this.SOURCE_ICON_SIZE = 48;
 | 
			
		||||
 | 
			
		||||
        this.title = title;
 | 
			
		||||
        this.iconName = iconName;
 | 
			
		||||
 | 
			
		||||
        this.isChat = false;
 | 
			
		||||
@@ -726,7 +794,7 @@ var Source = class Source {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    countUpdated() {
 | 
			
		||||
        this.emit('count-updated');
 | 
			
		||||
        super.notify('count');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _createPolicy() {
 | 
			
		||||
@@ -734,13 +802,17 @@ var Source = class Source {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    get narrowestPrivacyScope() {
 | 
			
		||||
        return this.notifications.every(n => n.privacyScope == PrivacyScope.SYSTEM) ? PrivacyScope.SYSTEM
 | 
			
		||||
                                                                                    : PrivacyScope.USER;
 | 
			
		||||
        return this.notifications.every(n => n.privacyScope == PrivacyScope.SYSTEM)
 | 
			
		||||
            ? PrivacyScope.SYSTEM
 | 
			
		||||
            : PrivacyScope.USER;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    setTitle(newTitle) {
 | 
			
		||||
        if (this.title == newTitle)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        this.title = newTitle;
 | 
			
		||||
        this.emit('title-changed');
 | 
			
		||||
        this.notify('title');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    createBanner(notification) {
 | 
			
		||||
@@ -765,10 +837,10 @@ var Source = class Source {
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        this.notifications.splice(index, 1);
 | 
			
		||||
        this.countUpdated();
 | 
			
		||||
 | 
			
		||||
        if (this.notifications.length == 0)
 | 
			
		||||
            this.destroy();
 | 
			
		||||
 | 
			
		||||
        this.countUpdated();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pushNotification(notification) {
 | 
			
		||||
@@ -779,24 +851,39 @@ var Source = class Source {
 | 
			
		||||
            this.notifications.shift().destroy(NotificationDestroyedReason.EXPIRED);
 | 
			
		||||
 | 
			
		||||
        notification.connect('destroy', this._onNotificationDestroy.bind(this));
 | 
			
		||||
        notification.connect('acknowledged-changed', this.countUpdated.bind(this));
 | 
			
		||||
        notification.connect('notify::acknowledged', this.countUpdated.bind(this));
 | 
			
		||||
        this.notifications.push(notification);
 | 
			
		||||
        this.emit('notification-added', notification);
 | 
			
		||||
 | 
			
		||||
        this.countUpdated();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    notify(notification) {
 | 
			
		||||
    showNotification(notification) {
 | 
			
		||||
        notification.acknowledged = false;
 | 
			
		||||
        this.pushNotification(notification);
 | 
			
		||||
 | 
			
		||||
        if (this.policy.showBanners || notification.urgency == Urgency.CRITICAL) {
 | 
			
		||||
            this.emit('notify', notification);
 | 
			
		||||
            this.emit('notification-show', notification);
 | 
			
		||||
        } else {
 | 
			
		||||
            notification.playSound();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    notify(propName) {
 | 
			
		||||
        if (propName instanceof Notification) {
 | 
			
		||||
            try {
 | 
			
		||||
                throw new Error('Source.notify() has been moved to Source.showNotification()' +
 | 
			
		||||
                                'this code will break in the future');
 | 
			
		||||
            } catch (e) {
 | 
			
		||||
                logError(e);
 | 
			
		||||
                this.showNotification(propName);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        super.notify(propName);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    destroy(reason) {
 | 
			
		||||
        this.policy.destroy();
 | 
			
		||||
 | 
			
		||||
@@ -807,6 +894,8 @@ var Source = class Source {
 | 
			
		||||
            notifications[i].destroy(reason);
 | 
			
		||||
 | 
			
		||||
        this.emit('destroy', reason);
 | 
			
		||||
 | 
			
		||||
        this.run_dispose();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    iconUpdated() {
 | 
			
		||||
@@ -821,14 +910,23 @@ var Source = class Source {
 | 
			
		||||
        for (let i = this.notifications.length - 1; i >= 0; i--)
 | 
			
		||||
            if (!this.notifications[i].resident)
 | 
			
		||||
                this.notifications[i].destroy();
 | 
			
		||||
 | 
			
		||||
        this.countUpdated();
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
Signals.addSignalMethods(Source.prototype);
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
var MessageTray = GObject.registerClass({
 | 
			
		||||
    Signals: {
 | 
			
		||||
        'queue-changed': {},
 | 
			
		||||
        'source-added': { param_types: [Source.$gtype] },
 | 
			
		||||
        'source-removed': { param_types: [Source.$gtype] },
 | 
			
		||||
    }
 | 
			
		||||
}, class MessageTray extends St.Widget {
 | 
			
		||||
    _init() {
 | 
			
		||||
        super._init({
 | 
			
		||||
            visible: false,
 | 
			
		||||
            clip_to_allocation: true,
 | 
			
		||||
            layout_manager: new Clutter.BinLayout()
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
var MessageTray = class MessageTray {
 | 
			
		||||
    constructor() {
 | 
			
		||||
        this._presence = new GnomeSession.Presence((proxy, _error) => {
 | 
			
		||||
            this._onStatusChanged(proxy.status);
 | 
			
		||||
        });
 | 
			
		||||
@@ -845,18 +943,15 @@ var MessageTray = class MessageTray {
 | 
			
		||||
            // so fix up Clutter's view of the pointer position in
 | 
			
		||||
            // that case.
 | 
			
		||||
            let related = ev.get_related();
 | 
			
		||||
            if (!related || this.actor.contains(related))
 | 
			
		||||
            if (!related || this.contains(related))
 | 
			
		||||
                global.sync_pointer();
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        this.actor = new St.Widget({ visible: false,
 | 
			
		||||
                                     clip_to_allocation: true,
 | 
			
		||||
                                     layout_manager: new Clutter.BinLayout() });
 | 
			
		||||
        let constraint = new Layout.MonitorConstraint({ primary: true });
 | 
			
		||||
        Main.layoutManager.panelBox.bind_property('visible',
 | 
			
		||||
                                                  constraint, 'work-area',
 | 
			
		||||
                                                  GObject.BindingFlags.SYNC_CREATE);
 | 
			
		||||
        this.actor.add_constraint(constraint);
 | 
			
		||||
        this.add_constraint(constraint);
 | 
			
		||||
 | 
			
		||||
        this._bannerBin = new St.Widget({ name: 'notification-container',
 | 
			
		||||
                                          reactive: true,
 | 
			
		||||
@@ -870,7 +965,7 @@ var MessageTray = class MessageTray {
 | 
			
		||||
                                this._onNotificationKeyRelease.bind(this));
 | 
			
		||||
        this._bannerBin.connect('notify::hover',
 | 
			
		||||
                                this._onNotificationHoverChanged.bind(this));
 | 
			
		||||
        this.actor.add_actor(this._bannerBin);
 | 
			
		||||
        this.add_actor(this._bannerBin);
 | 
			
		||||
 | 
			
		||||
        this._notificationFocusGrabber = new FocusGrabber(this._bannerBin);
 | 
			
		||||
        this._notificationQueue = [];
 | 
			
		||||
@@ -899,7 +994,7 @@ var MessageTray = class MessageTray {
 | 
			
		||||
        this._notificationTimeoutId = 0;
 | 
			
		||||
        this._notificationRemoved = false;
 | 
			
		||||
 | 
			
		||||
        Main.layoutManager.addChrome(this.actor, { affectsInputRegion: false });
 | 
			
		||||
        Main.layoutManager.addChrome(this, { affectsInputRegion: false });
 | 
			
		||||
        Main.layoutManager.trackChrome(this._bannerBin, { affectsInputRegion: true });
 | 
			
		||||
 | 
			
		||||
        global.display.connect('in-fullscreen-changed', this._updateState.bind(this));
 | 
			
		||||
@@ -942,11 +1037,11 @@ var MessageTray = class MessageTray {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _onDragBegin() {
 | 
			
		||||
        Shell.util_set_hidden_from_pick(this.actor, true);
 | 
			
		||||
        Shell.util_set_hidden_from_pick(this, true);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _onDragEnd() {
 | 
			
		||||
        Shell.util_set_hidden_from_pick(this.actor, false);
 | 
			
		||||
        Shell.util_set_hidden_from_pick(this, false);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    get bannerAlignment() {
 | 
			
		||||
@@ -995,23 +1090,22 @@ var MessageTray = class MessageTray {
 | 
			
		||||
        // Register that we got a notification for this source
 | 
			
		||||
        source.policy.store();
 | 
			
		||||
 | 
			
		||||
        source.policy.connect('enable-changed', () => {
 | 
			
		||||
        source.policy.connect('notify::enable', () => {
 | 
			
		||||
            this._onSourceEnableChanged(source.policy, source);
 | 
			
		||||
        });
 | 
			
		||||
        source.policy.connect('policy-changed', this._updateState.bind(this));
 | 
			
		||||
        source.policy.connect('notify', this._updateState.bind(this));
 | 
			
		||||
        this._onSourceEnableChanged(source.policy, source);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _addSource(source) {
 | 
			
		||||
        let obj = {
 | 
			
		||||
            source: source,
 | 
			
		||||
            notifyId: 0,
 | 
			
		||||
            showId: 0,
 | 
			
		||||
            destroyId: 0,
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        this._sources.set(source, obj);
 | 
			
		||||
 | 
			
		||||
        obj.notifyId = source.connect('notify', this._onNotify.bind(this));
 | 
			
		||||
        obj.showId = source.connect('notification-show', this._onNotificationShow.bind(this));
 | 
			
		||||
        obj.destroyId = source.connect('destroy', this._onSourceDestroy.bind(this));
 | 
			
		||||
 | 
			
		||||
        this.emit('source-added', source);
 | 
			
		||||
@@ -1021,7 +1115,7 @@ var MessageTray = class MessageTray {
 | 
			
		||||
        let obj = this._sources.get(source);
 | 
			
		||||
        this._sources.delete(source);
 | 
			
		||||
 | 
			
		||||
        source.disconnect(obj.notifyId);
 | 
			
		||||
        source.disconnect(obj.showId);
 | 
			
		||||
        source.disconnect(obj.destroyId);
 | 
			
		||||
 | 
			
		||||
        this.emit('source-removed', source);
 | 
			
		||||
@@ -1062,7 +1156,7 @@ var MessageTray = class MessageTray {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _onNotify(source, notification) {
 | 
			
		||||
    _onNotificationShow(_source, notification) {
 | 
			
		||||
        if (this._notification == notification) {
 | 
			
		||||
            // If a notification that is being shown is updated, we update
 | 
			
		||||
            // how it is shown and extend the time until it auto-hides.
 | 
			
		||||
@@ -1091,7 +1185,7 @@ var MessageTray = class MessageTray {
 | 
			
		||||
    _resetNotificationLeftTimeout() {
 | 
			
		||||
        this._useLongerNotificationLeftTimeout = false;
 | 
			
		||||
        if (this._notificationLeftTimeoutId) {
 | 
			
		||||
            Mainloop.source_remove(this._notificationLeftTimeoutId);
 | 
			
		||||
            GLib.source_remove(this._notificationLeftTimeoutId);
 | 
			
		||||
            this._notificationLeftTimeoutId = 0;
 | 
			
		||||
            this._notificationLeftMouseX = -1;
 | 
			
		||||
            this._notificationLeftMouseY = -1;
 | 
			
		||||
@@ -1137,7 +1231,7 @@ var MessageTray = class MessageTray {
 | 
			
		||||
            // We wait for a longer period if the notification popped up where the mouse pointer was already positioned.
 | 
			
		||||
            // That gives the user more time to mouse away from the notification and mouse back in in order to expand it.
 | 
			
		||||
            let timeout = this._useLongerNotificationLeftTimeout ? LONGER_HIDE_TIMEOUT : HIDE_TIMEOUT;
 | 
			
		||||
            this._notificationLeftTimeoutId = Mainloop.timeout_add(timeout, this._onNotificationLeftTimeout.bind(this));
 | 
			
		||||
            this._notificationLeftTimeoutId = GLib.timeout_add(GLib.PRIORITY_DEFAULT, timeout, this._onNotificationLeftTimeout.bind(this));
 | 
			
		||||
            GLib.Source.set_name_by_id(this._notificationLeftTimeoutId, '[gnome-shell] this._onNotificationLeftTimeout');
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
@@ -1166,8 +1260,10 @@ var MessageTray = class MessageTray {
 | 
			
		||||
            x < this._notificationLeftMouseX + MOUSE_LEFT_ACTOR_THRESHOLD &&
 | 
			
		||||
            x > this._notificationLeftMouseX - MOUSE_LEFT_ACTOR_THRESHOLD) {
 | 
			
		||||
            this._notificationLeftMouseX = -1;
 | 
			
		||||
            this._notificationLeftTimeoutId = Mainloop.timeout_add(LONGER_HIDE_TIMEOUT,
 | 
			
		||||
                                                                   this._onNotificationLeftTimeout.bind(this));
 | 
			
		||||
            this._notificationLeftTimeoutId = GLib.timeout_add(
 | 
			
		||||
                GLib.PRIORITY_DEFAULT,
 | 
			
		||||
                LONGER_HIDE_TIMEOUT,
 | 
			
		||||
                this._onNotificationLeftTimeout.bind(this));
 | 
			
		||||
            GLib.Source.set_name_by_id(this._notificationLeftTimeoutId, '[gnome-shell] this._onNotificationLeftTimeout');
 | 
			
		||||
        } else {
 | 
			
		||||
            this._notificationLeftTimeoutId = 0;
 | 
			
		||||
@@ -1192,7 +1288,7 @@ var MessageTray = class MessageTray {
 | 
			
		||||
    // at the present time.
 | 
			
		||||
    _updateState() {
 | 
			
		||||
        let hasMonitor = Main.layoutManager.primaryMonitor != null;
 | 
			
		||||
        this.actor.visible = !this._bannerBlocked && hasMonitor && this._banner != null;
 | 
			
		||||
        this.visible = !this._bannerBlocked && hasMonitor && this._banner != null;
 | 
			
		||||
        if (this._bannerBlocked || !hasMonitor)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
@@ -1272,11 +1368,11 @@ var MessageTray = class MessageTray {
 | 
			
		||||
            this._updateState();
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        this._bannerBin.add_actor(this._banner.actor);
 | 
			
		||||
        this._bannerBin.add_actor(this._banner);
 | 
			
		||||
 | 
			
		||||
        this._bannerBin.opacity = 0;
 | 
			
		||||
        this._bannerBin.y = -this._banner.actor.height;
 | 
			
		||||
        this.actor.show();
 | 
			
		||||
        this._bannerBin.y = -this._banner.height;
 | 
			
		||||
        this.show();
 | 
			
		||||
 | 
			
		||||
        Meta.disable_unredirect_for_display(global.display);
 | 
			
		||||
        this._updateShowingNotification();
 | 
			
		||||
@@ -1345,13 +1441,13 @@ var MessageTray = class MessageTray {
 | 
			
		||||
 | 
			
		||||
    _updateNotificationTimeout(timeout) {
 | 
			
		||||
        if (this._notificationTimeoutId) {
 | 
			
		||||
            Mainloop.source_remove(this._notificationTimeoutId);
 | 
			
		||||
            GLib.source_remove(this._notificationTimeoutId);
 | 
			
		||||
            this._notificationTimeoutId = 0;
 | 
			
		||||
        }
 | 
			
		||||
        if (timeout > 0) {
 | 
			
		||||
            this._notificationTimeoutId =
 | 
			
		||||
                Mainloop.timeout_add(timeout,
 | 
			
		||||
                                     this._notificationTimeout.bind(this));
 | 
			
		||||
                GLib.timeout_add(GLib.PRIORITY_DEFAULT, timeout,
 | 
			
		||||
                    this._notificationTimeout.bind(this));
 | 
			
		||||
            GLib.Source.set_name_by_id(this._notificationTimeoutId, '[gnome-shell] this._notificationTimeout');
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
@@ -1423,16 +1519,16 @@ var MessageTray = class MessageTray {
 | 
			
		||||
    _hideNotificationCompleted() {
 | 
			
		||||
        let notification = this._notification;
 | 
			
		||||
        this._notification = null;
 | 
			
		||||
        if (notification.isTransient)
 | 
			
		||||
        if (!this._notificationRemoved && notification.isTransient)
 | 
			
		||||
            notification.destroy(NotificationDestroyedReason.EXPIRED);
 | 
			
		||||
 | 
			
		||||
        this._pointerInNotification = false;
 | 
			
		||||
        this._notificationRemoved = false;
 | 
			
		||||
        Meta.enable_unredirect_for_display(global.display);
 | 
			
		||||
 | 
			
		||||
        this._banner.actor.destroy();
 | 
			
		||||
        this._banner.destroy();
 | 
			
		||||
        this._banner = null;
 | 
			
		||||
        this.actor.hide();
 | 
			
		||||
        this.hide();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _expandActiveNotification() {
 | 
			
		||||
@@ -1454,15 +1550,15 @@ var MessageTray = class MessageTray {
 | 
			
		||||
    _ensureBannerFocused() {
 | 
			
		||||
        this._notificationFocusGrabber.grabFocus();
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
Signals.addSignalMethods(MessageTray.prototype);
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
var SystemNotificationSource = class SystemNotificationSource extends Source {
 | 
			
		||||
    constructor() {
 | 
			
		||||
        super(_("System Information"), 'dialog-information-symbolic');
 | 
			
		||||
var SystemNotificationSource = GObject.registerClass(
 | 
			
		||||
class SystemNotificationSource extends Source {
 | 
			
		||||
    _init() {
 | 
			
		||||
        super._init(_("System Information"), 'dialog-information-symbolic');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    open() {
 | 
			
		||||
        this.destroy();
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -121,7 +121,7 @@ var ModalDialog = GObject.registerClass({
 | 
			
		||||
 | 
			
		||||
        this.dialogLayout.opacity = 255;
 | 
			
		||||
        if (this._lightbox)
 | 
			
		||||
            this._lightbox.show();
 | 
			
		||||
            this._lightbox.lightOn();
 | 
			
		||||
        this.opacity = 0;
 | 
			
		||||
        this.show();
 | 
			
		||||
        this.ease({
 | 
			
		||||
@@ -253,7 +253,7 @@ var ModalDialog = GObject.registerClass({
 | 
			
		||||
            opacity: 0,
 | 
			
		||||
            duration: FADE_OUT_DIALOG_TIME,
 | 
			
		||||
            mode: Clutter.AnimationMode.EASE_OUT_QUAD,
 | 
			
		||||
            onComplete: () => this.state = State.FADED_OUT
 | 
			
		||||
            onComplete: () => (this.state = State.FADED_OUT)
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
/* exported MediaSection */
 | 
			
		||||
const { Gio, Shell, St } = imports.gi;
 | 
			
		||||
const { Gio, GObject, Shell, St } = imports.gi;
 | 
			
		||||
const Signals = imports.signals;
 | 
			
		||||
 | 
			
		||||
const Calendar = imports.ui.calendar;
 | 
			
		||||
@@ -19,9 +19,10 @@ const MprisPlayerProxy = Gio.DBusProxy.makeProxyWrapper(MprisPlayerIface);
 | 
			
		||||
 | 
			
		||||
const MPRIS_PLAYER_PREFIX = 'org.mpris.MediaPlayer2.';
 | 
			
		||||
 | 
			
		||||
var MediaMessage = class MediaMessage extends MessageList.Message {
 | 
			
		||||
    constructor(player) {
 | 
			
		||||
        super('', '');
 | 
			
		||||
var MediaMessage = GObject.registerClass(
 | 
			
		||||
class MediaMessage extends MessageList.Message {
 | 
			
		||||
    _init(player) {
 | 
			
		||||
        super._init('', '');
 | 
			
		||||
 | 
			
		||||
        this._player = player;
 | 
			
		||||
 | 
			
		||||
@@ -48,7 +49,7 @@ var MediaMessage = class MediaMessage extends MessageList.Message {
 | 
			
		||||
        this._update();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _onClicked() {
 | 
			
		||||
    vfunc_clicked() {
 | 
			
		||||
        this._player.raise();
 | 
			
		||||
        Main.panel.closeCalendar();
 | 
			
		||||
    }
 | 
			
		||||
@@ -71,14 +72,15 @@ var MediaMessage = class MediaMessage extends MessageList.Message {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let isPlaying = this._player.status == 'Playing';
 | 
			
		||||
        let iconName = isPlaying ? 'media-playback-pause-symbolic'
 | 
			
		||||
                                 : 'media-playback-start-symbolic';
 | 
			
		||||
        let iconName = isPlaying
 | 
			
		||||
            ? 'media-playback-pause-symbolic'
 | 
			
		||||
            : 'media-playback-start-symbolic';
 | 
			
		||||
        this._playPauseButton.child.icon_name = iconName;
 | 
			
		||||
 | 
			
		||||
        this._updateNavButton(this._prevButton, this._player.canGoPrevious);
 | 
			
		||||
        this._updateNavButton(this._nextButton, this._player.canGoNext);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
var MprisPlayer = class MprisPlayer {
 | 
			
		||||
    constructor(busName) {
 | 
			
		||||
@@ -193,9 +195,10 @@ var MprisPlayer = class MprisPlayer {
 | 
			
		||||
};
 | 
			
		||||
Signals.addSignalMethods(MprisPlayer.prototype);
 | 
			
		||||
 | 
			
		||||
var MediaSection = class MediaSection extends MessageList.MessageListSection {
 | 
			
		||||
    constructor() {
 | 
			
		||||
        super();
 | 
			
		||||
var MediaSection = GObject.registerClass(
 | 
			
		||||
class MediaSection extends MessageList.MessageListSection {
 | 
			
		||||
    _init() {
 | 
			
		||||
        super._init();
 | 
			
		||||
 | 
			
		||||
        this._players = new Map();
 | 
			
		||||
 | 
			
		||||
@@ -246,4 +249,4 @@ var MediaSection = class MediaSection extends MessageList.MessageListSection {
 | 
			
		||||
        if (newOwner && !oldOwner)
 | 
			
		||||
            this._addPlayer(name);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -1,8 +1,7 @@
 | 
			
		||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
 | 
			
		||||
/* exported NotificationDaemon */
 | 
			
		||||
 | 
			
		||||
const { GdkPixbuf, Gio, GLib, Shell, St } = imports.gi;
 | 
			
		||||
const Mainloop = imports.mainloop;
 | 
			
		||||
const { GdkPixbuf, Gio, GLib, GObject, Shell, St } = imports.gi;
 | 
			
		||||
 | 
			
		||||
const Config = imports.misc.config;
 | 
			
		||||
const Main = imports.ui.main;
 | 
			
		||||
@@ -171,7 +170,7 @@ var FdoNotificationDaemon = class FdoNotificationDaemon {
 | 
			
		||||
            // Ignore replacesId since we already sent back a
 | 
			
		||||
            // NotificationClosed for that id.
 | 
			
		||||
            id = this._nextNotificationId++;
 | 
			
		||||
            let idleId = Mainloop.idle_add(() => {
 | 
			
		||||
            let idleId = GLib.idle_add(GLib.PRIORITY_DEFAULT, () => {
 | 
			
		||||
                this._emitNotificationClosed(id, NotificationClosedReason.DISMISSED);
 | 
			
		||||
                return GLib.SOURCE_REMOVE;
 | 
			
		||||
            });
 | 
			
		||||
@@ -347,8 +346,9 @@ var FdoNotificationDaemon = class FdoNotificationDaemon {
 | 
			
		||||
        notification.setTransient(!!hints['transient']);
 | 
			
		||||
 | 
			
		||||
        let privacyScope = (hints['x-gnome-privacy-scope'] || 'user');
 | 
			
		||||
        notification.setPrivacyScope(privacyScope == 'system' ? MessageTray.PrivacyScope.SYSTEM
 | 
			
		||||
                                                              : MessageTray.PrivacyScope.USER);
 | 
			
		||||
        notification.setPrivacyScope(privacyScope == 'system'
 | 
			
		||||
            ? MessageTray.PrivacyScope.SYSTEM
 | 
			
		||||
            : MessageTray.PrivacyScope.USER);
 | 
			
		||||
 | 
			
		||||
        let sourceGIcon = source.useNotificationIcon ? gicon : null;
 | 
			
		||||
        source.processNotification(notification, sourceGIcon);
 | 
			
		||||
@@ -412,10 +412,10 @@ var FdoNotificationDaemon = class FdoNotificationDaemon {
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
var FdoNotificationDaemonSource =
 | 
			
		||||
var FdoNotificationDaemonSource = GObject.registerClass(
 | 
			
		||||
class FdoNotificationDaemonSource extends MessageTray.Source {
 | 
			
		||||
    constructor(title, pid, sender, appId) {
 | 
			
		||||
        super(title);
 | 
			
		||||
    _init(title, pid, sender, appId) {
 | 
			
		||||
        super._init(title);
 | 
			
		||||
 | 
			
		||||
        this.pid = pid;
 | 
			
		||||
        this.app = this._getApp(appId);
 | 
			
		||||
@@ -464,7 +464,7 @@ class FdoNotificationDaemonSource extends MessageTray.Source {
 | 
			
		||||
        if (notification.resident && this.app && tracker.focus_app == this.app)
 | 
			
		||||
            this.pushNotification(notification);
 | 
			
		||||
        else
 | 
			
		||||
            this.notify(notification);
 | 
			
		||||
            this.showNotification(notification);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _getApp(appId) {
 | 
			
		||||
@@ -526,7 +526,7 @@ class FdoNotificationDaemonSource extends MessageTray.Source {
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
const PRIORITY_URGENCY_MAP = {
 | 
			
		||||
    low: MessageTray.Urgency.LOW,
 | 
			
		||||
@@ -535,28 +535,29 @@ const PRIORITY_URGENCY_MAP = {
 | 
			
		||||
    urgent: MessageTray.Urgency.CRITICAL
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
var GtkNotificationDaemonNotification =
 | 
			
		||||
var GtkNotificationDaemonNotification = GObject.registerClass(
 | 
			
		||||
class GtkNotificationDaemonNotification extends MessageTray.Notification {
 | 
			
		||||
    constructor(source, notification) {
 | 
			
		||||
        super(source);
 | 
			
		||||
    _init(source, notification) {
 | 
			
		||||
        super._init(source);
 | 
			
		||||
        this._serialized = GLib.Variant.new('a{sv}', notification);
 | 
			
		||||
 | 
			
		||||
        let { "title": title,
 | 
			
		||||
              "body": body,
 | 
			
		||||
              "icon": gicon,
 | 
			
		||||
              "urgent": urgent,
 | 
			
		||||
              "priority": priority,
 | 
			
		||||
              "buttons": buttons,
 | 
			
		||||
        let { title,
 | 
			
		||||
              body,
 | 
			
		||||
              icon: gicon,
 | 
			
		||||
              urgent,
 | 
			
		||||
              priority,
 | 
			
		||||
              buttons,
 | 
			
		||||
              "default-action": defaultAction,
 | 
			
		||||
              "default-action-target": defaultActionTarget,
 | 
			
		||||
              "timestamp": time } = notification;
 | 
			
		||||
              timestamp: time } = notification;
 | 
			
		||||
 | 
			
		||||
        if (priority) {
 | 
			
		||||
            let urgency = PRIORITY_URGENCY_MAP[priority.unpack()];
 | 
			
		||||
            this.setUrgency(urgency != undefined ? urgency : MessageTray.Urgency.NORMAL);
 | 
			
		||||
        } else if (urgent) {
 | 
			
		||||
            this.setUrgency(urgent.unpack() ? MessageTray.Urgency.CRITICAL
 | 
			
		||||
                            : MessageTray.Urgency.NORMAL);
 | 
			
		||||
            this.setUrgency(urgent.unpack()
 | 
			
		||||
                ? MessageTray.Urgency.CRITICAL
 | 
			
		||||
                : MessageTray.Urgency.NORMAL);
 | 
			
		||||
        } else {
 | 
			
		||||
            this.setUrgency(MessageTray.Urgency.NORMAL);
 | 
			
		||||
        }
 | 
			
		||||
@@ -589,8 +590,8 @@ class GtkNotificationDaemonNotification extends MessageTray.Notification {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _onButtonClicked(button) {
 | 
			
		||||
        let { 'action': action, 'target': actionTarget } = button;
 | 
			
		||||
        this._activateAction(action.unpack(), actionTarget);
 | 
			
		||||
        let { action, target } = button;
 | 
			
		||||
        this._activateAction(action.unpack(), target);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    activate() {
 | 
			
		||||
@@ -601,7 +602,7 @@ class GtkNotificationDaemonNotification extends MessageTray.Notification {
 | 
			
		||||
    serialize() {
 | 
			
		||||
        return this._serialized;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
const FdoApplicationIface = loadInterfaceXML('org.freedesktop.Application');
 | 
			
		||||
const FdoApplicationProxy = Gio.DBusProxy.makeProxyWrapper(FdoApplicationIface);
 | 
			
		||||
@@ -617,9 +618,9 @@ function getPlatformData() {
 | 
			
		||||
 | 
			
		||||
function InvalidAppError() {}
 | 
			
		||||
 | 
			
		||||
var GtkNotificationDaemonAppSource = 
 | 
			
		||||
var GtkNotificationDaemonAppSource = GObject.registerClass(
 | 
			
		||||
class GtkNotificationDaemonAppSource extends MessageTray.Source {
 | 
			
		||||
    constructor(appId) {
 | 
			
		||||
    _init(appId) {
 | 
			
		||||
        let objectPath = objectPathFromAppId(appId);
 | 
			
		||||
        if (!GLib.Variant.is_object_path(objectPath))
 | 
			
		||||
            throw new InvalidAppError();
 | 
			
		||||
@@ -628,7 +629,7 @@ class GtkNotificationDaemonAppSource extends MessageTray.Source {
 | 
			
		||||
        if (!app)
 | 
			
		||||
            throw new InvalidAppError();
 | 
			
		||||
 | 
			
		||||
        super(app.get_name());
 | 
			
		||||
        super._init(app.get_name());
 | 
			
		||||
 | 
			
		||||
        this._appId = appId;
 | 
			
		||||
        this._app = app;
 | 
			
		||||
@@ -689,7 +690,7 @@ class GtkNotificationDaemonAppSource extends MessageTray.Source {
 | 
			
		||||
        this._notifications[notificationId] = notification;
 | 
			
		||||
 | 
			
		||||
        if (showBanner)
 | 
			
		||||
            this.notify(notification);
 | 
			
		||||
            this.showNotification(notification);
 | 
			
		||||
        else
 | 
			
		||||
            this.pushNotification(notification);
 | 
			
		||||
 | 
			
		||||
@@ -715,7 +716,7 @@ class GtkNotificationDaemonAppSource extends MessageTray.Source {
 | 
			
		||||
        }
 | 
			
		||||
        return [this._appId, notifications];
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
const GtkNotificationsIface = loadInterfaceXML('org.gtk.Notifications');
 | 
			
		||||
 | 
			
		||||
@@ -741,7 +742,7 @@ var GtkNotificationDaemon = class GtkNotificationDaemon {
 | 
			
		||||
            delete this._sources[appId];
 | 
			
		||||
            this._saveNotifications();
 | 
			
		||||
        });
 | 
			
		||||
        source.connect('count-updated', this._saveNotifications.bind(this));
 | 
			
		||||
        source.connect('notify::count', this._saveNotifications.bind(this));
 | 
			
		||||
        Main.messageTray.add(source);
 | 
			
		||||
        this._sources[appId] = source;
 | 
			
		||||
        return source;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,30 +1,33 @@
 | 
			
		||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
 | 
			
		||||
/* exported OsdMonitorLabeler */
 | 
			
		||||
 | 
			
		||||
const { Clutter, Gio, Meta, St } = imports.gi;
 | 
			
		||||
const { Clutter, Gio, GObject, Meta, St } = imports.gi;
 | 
			
		||||
 | 
			
		||||
const Main = imports.ui.main;
 | 
			
		||||
 | 
			
		||||
var OsdMonitorLabel = class {
 | 
			
		||||
    constructor(monitor, label) {
 | 
			
		||||
        this._actor = new St.Widget({ x_expand: true,
 | 
			
		||||
                                      y_expand: true });
 | 
			
		||||
var OsdMonitorLabel = GObject.registerClass(
 | 
			
		||||
class OsdMonitorLabel extends St.Widget {
 | 
			
		||||
    _init(monitor, label) {
 | 
			
		||||
        super._init({ x_expand: true, y_expand: true });
 | 
			
		||||
 | 
			
		||||
        this._monitor = monitor;
 | 
			
		||||
 | 
			
		||||
        this._box = new St.BoxLayout({ style_class: 'osd-window',
 | 
			
		||||
                                       vertical: true });
 | 
			
		||||
        this._actor.add_actor(this._box);
 | 
			
		||||
        this.add_actor(this._box);
 | 
			
		||||
 | 
			
		||||
        this._label = new St.Label({ style_class: 'osd-monitor-label',
 | 
			
		||||
                                     text: label });
 | 
			
		||||
        this._box.add(this._label);
 | 
			
		||||
 | 
			
		||||
        Main.uiGroup.add_child(this._actor);
 | 
			
		||||
        Main.uiGroup.set_child_above_sibling(this._actor, null);
 | 
			
		||||
        Main.uiGroup.add_child(this);
 | 
			
		||||
        Main.uiGroup.set_child_above_sibling(this, null);
 | 
			
		||||
        this._position();
 | 
			
		||||
 | 
			
		||||
        Meta.disable_unredirect_for_display(global.display);
 | 
			
		||||
        this.connect('destroy', () => {
 | 
			
		||||
            Meta.enable_unredirect_for_display(global.display);
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _position() {
 | 
			
		||||
@@ -37,12 +40,7 @@ var OsdMonitorLabel = class {
 | 
			
		||||
 | 
			
		||||
        this._box.y = workArea.y;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    destroy() {
 | 
			
		||||
        this._actor.destroy();
 | 
			
		||||
        Meta.enable_unredirect_for_display(global.display);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
var OsdMonitorLabeler = class {
 | 
			
		||||
    constructor() {
 | 
			
		||||
 
 | 
			
		||||
@@ -2,7 +2,6 @@
 | 
			
		||||
/* exported OsdWindowManager */
 | 
			
		||||
 | 
			
		||||
const { Clutter, GLib, GObject, Meta, St } = imports.gi;
 | 
			
		||||
const Mainloop = imports.mainloop;
 | 
			
		||||
 | 
			
		||||
const BarLevel = imports.ui.barLevel;
 | 
			
		||||
const Layout = imports.ui.layout;
 | 
			
		||||
@@ -42,22 +41,25 @@ class OsdWindowConstraint extends Clutter.Constraint {
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
var OsdWindow = class {
 | 
			
		||||
    constructor(monitorIndex) {
 | 
			
		||||
        this.actor = new St.Widget({ x_expand: true,
 | 
			
		||||
                                     y_expand: true,
 | 
			
		||||
                                     x_align: Clutter.ActorAlign.CENTER,
 | 
			
		||||
                                     y_align: Clutter.ActorAlign.CENTER });
 | 
			
		||||
var OsdWindow = GObject.registerClass(
 | 
			
		||||
class OsdWindow extends St.Widget {
 | 
			
		||||
    _init(monitorIndex) {
 | 
			
		||||
        super._init({
 | 
			
		||||
            x_expand: true,
 | 
			
		||||
            y_expand: true,
 | 
			
		||||
            x_align: Clutter.ActorAlign.CENTER,
 | 
			
		||||
            y_align: Clutter.ActorAlign.CENTER
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        this._monitorIndex = monitorIndex;
 | 
			
		||||
        let constraint = new Layout.MonitorConstraint({ index: monitorIndex });
 | 
			
		||||
        this.actor.add_constraint(constraint);
 | 
			
		||||
        this.add_constraint(constraint);
 | 
			
		||||
 | 
			
		||||
        this._boxConstraint = new OsdWindowConstraint();
 | 
			
		||||
        this._box = new St.BoxLayout({ style_class: 'osd-window',
 | 
			
		||||
                                       vertical: true });
 | 
			
		||||
        this._box.add_constraint(this._boxConstraint);
 | 
			
		||||
        this.actor.add_actor(this._box);
 | 
			
		||||
        this.add_actor(this._box);
 | 
			
		||||
 | 
			
		||||
        this._icon = new St.Icon();
 | 
			
		||||
        this._box.add(this._icon, { expand: true });
 | 
			
		||||
@@ -74,7 +76,7 @@ var OsdWindow = class {
 | 
			
		||||
        this._hideTimeoutId = 0;
 | 
			
		||||
        this._reset();
 | 
			
		||||
 | 
			
		||||
        this.actor.connect('destroy', this._onDestroy.bind(this));
 | 
			
		||||
        this.connect('destroy', this._onDestroy.bind(this));
 | 
			
		||||
 | 
			
		||||
        this._monitorsChangedId =
 | 
			
		||||
            Main.layoutManager.connect('monitors-changed',
 | 
			
		||||
@@ -84,7 +86,7 @@ var OsdWindow = class {
 | 
			
		||||
            themeContext.connect('notify::scale-factor',
 | 
			
		||||
                                 this._relayout.bind(this));
 | 
			
		||||
        this._relayout();
 | 
			
		||||
        Main.uiGroup.add_child(this.actor);
 | 
			
		||||
        Main.uiGroup.add_child(this);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _onDestroy() {
 | 
			
		||||
@@ -111,7 +113,7 @@ var OsdWindow = class {
 | 
			
		||||
    setLevel(value) {
 | 
			
		||||
        this._level.visible = (value != undefined);
 | 
			
		||||
        if (value != undefined) {
 | 
			
		||||
            if (this.actor.visible)
 | 
			
		||||
            if (this.visible)
 | 
			
		||||
                this._level.ease_property('value', value, {
 | 
			
		||||
                    mode: Clutter.AnimationMode.EASE_OUT_QUAD,
 | 
			
		||||
                    duration: LEVEL_ANIMATION_TIME
 | 
			
		||||
@@ -129,13 +131,13 @@ var OsdWindow = class {
 | 
			
		||||
        if (!this._icon.gicon)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        if (!this.actor.visible) {
 | 
			
		||||
        if (!this.visible) {
 | 
			
		||||
            Meta.disable_unredirect_for_display(global.display);
 | 
			
		||||
            this.actor.show();
 | 
			
		||||
            this.actor.opacity = 0;
 | 
			
		||||
            this.actor.get_parent().set_child_above_sibling(this.actor, null);
 | 
			
		||||
            super.show();
 | 
			
		||||
            this.opacity = 0;
 | 
			
		||||
            this.get_parent().set_child_above_sibling(this, null);
 | 
			
		||||
 | 
			
		||||
            this.actor.ease({
 | 
			
		||||
            this.ease({
 | 
			
		||||
                opacity: 255,
 | 
			
		||||
                duration: FADE_TIME,
 | 
			
		||||
                mode: Clutter.AnimationMode.EASE_OUT_QUAD
 | 
			
		||||
@@ -143,9 +145,9 @@ var OsdWindow = class {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (this._hideTimeoutId)
 | 
			
		||||
            Mainloop.source_remove(this._hideTimeoutId);
 | 
			
		||||
        this._hideTimeoutId = Mainloop.timeout_add(HIDE_TIMEOUT,
 | 
			
		||||
                                                   this._hide.bind(this));
 | 
			
		||||
            GLib.source_remove(this._hideTimeoutId);
 | 
			
		||||
        this._hideTimeoutId = GLib.timeout_add(
 | 
			
		||||
            GLib.PRIORITY_DEFAULT, HIDE_TIMEOUT, this._hide.bind(this));
 | 
			
		||||
        GLib.Source.set_name_by_id(this._hideTimeoutId, '[gnome-shell] this._hide');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -153,13 +155,13 @@ var OsdWindow = class {
 | 
			
		||||
        if (!this._hideTimeoutId)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        Mainloop.source_remove(this._hideTimeoutId);
 | 
			
		||||
        GLib.source_remove(this._hideTimeoutId);
 | 
			
		||||
        this._hide();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _hide() {
 | 
			
		||||
        this._hideTimeoutId = 0;
 | 
			
		||||
        this.actor.ease({
 | 
			
		||||
        this.ease({
 | 
			
		||||
            opacity: 0,
 | 
			
		||||
            duration: FADE_TIME,
 | 
			
		||||
            mode: Clutter.AnimationMode.EASE_OUT_QUAD,
 | 
			
		||||
@@ -172,7 +174,7 @@ var OsdWindow = class {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _reset() {
 | 
			
		||||
        this.actor.hide();
 | 
			
		||||
        super.hide();
 | 
			
		||||
        this.setLabel(null);
 | 
			
		||||
        this.setMaxLevel(null);
 | 
			
		||||
        this.setLevel(null);
 | 
			
		||||
@@ -194,7 +196,7 @@ var OsdWindow = class {
 | 
			
		||||
        this._box.translation_y = Math.round(monitor.height / 4);
 | 
			
		||||
        this._boxConstraint.minSize = popupSize;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
var OsdWindowManager = class {
 | 
			
		||||
    constructor() {
 | 
			
		||||
@@ -211,7 +213,7 @@ var OsdWindowManager = class {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        for (let i = Main.layoutManager.monitors.length; i < this._osdWindows.length; i++) {
 | 
			
		||||
            this._osdWindows[i].actor.destroy();
 | 
			
		||||
            this._osdWindows[i].destroy();
 | 
			
		||||
            this._osdWindows[i] = null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,8 +1,7 @@
 | 
			
		||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
 | 
			
		||||
/* exported Overview */
 | 
			
		||||
 | 
			
		||||
const { Clutter, GLib, Meta, Shell, St } = imports.gi;
 | 
			
		||||
const Mainloop = imports.mainloop;
 | 
			
		||||
const { Clutter, GLib, GObject, Meta, Shell, St } = imports.gi;
 | 
			
		||||
const Signals = imports.signals;
 | 
			
		||||
 | 
			
		||||
const Background = imports.ui.background;
 | 
			
		||||
@@ -43,9 +42,10 @@ var ShellInfo = class {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    setMessage(text, options) {
 | 
			
		||||
        options = Params.parse(options, { undoCallback: null,
 | 
			
		||||
                                          forFeedback: false
 | 
			
		||||
                                        });
 | 
			
		||||
        options = Params.parse(options, {
 | 
			
		||||
            undoCallback: null,
 | 
			
		||||
            forFeedback: false,
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        let undoCallback = options.undoCallback;
 | 
			
		||||
        let forFeedback = options.forFeedback;
 | 
			
		||||
@@ -72,36 +72,108 @@ var ShellInfo = class {
 | 
			
		||||
        if (undoCallback)
 | 
			
		||||
            notification.addAction(_("Undo"), this._onUndoClicked.bind(this));
 | 
			
		||||
 | 
			
		||||
        this._source.notify(notification);
 | 
			
		||||
        this._source.showNotification(notification);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
var OverviewActor = GObject.registerClass(
 | 
			
		||||
class OverviewActor extends St.BoxLayout {
 | 
			
		||||
    _init() {
 | 
			
		||||
        super._init({
 | 
			
		||||
            name: 'overview',
 | 
			
		||||
            /* Translators: This is the main view to select
 | 
			
		||||
                activities. See also note for "Activities" string. */
 | 
			
		||||
            accessible_name: _("Overview"),
 | 
			
		||||
            vertical: true
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        this.add_constraint(new LayoutManager.MonitorConstraint({ primary: true }));
 | 
			
		||||
 | 
			
		||||
        // Add a clone of the panel to the overview so spacing and such is
 | 
			
		||||
        // automatic
 | 
			
		||||
        let panelGhost = new St.Bin({
 | 
			
		||||
            child: new Clutter.Clone({ source: Main.panel }),
 | 
			
		||||
            reactive: false,
 | 
			
		||||
            opacity: 0
 | 
			
		||||
        });
 | 
			
		||||
        this.add_actor(panelGhost);
 | 
			
		||||
 | 
			
		||||
        this._searchEntry = new St.Entry({
 | 
			
		||||
            style_class: 'search-entry',
 | 
			
		||||
            /* Translators: this is the text displayed
 | 
			
		||||
               in the search entry when no search is
 | 
			
		||||
               active; it should not exceed ~30
 | 
			
		||||
               characters. */
 | 
			
		||||
            hint_text: _("Type to search…"),
 | 
			
		||||
            track_hover: true,
 | 
			
		||||
            can_focus: true
 | 
			
		||||
        });
 | 
			
		||||
        let searchEntryBin = new St.Bin({
 | 
			
		||||
            child: this._searchEntry,
 | 
			
		||||
            x_align: St.Align.MIDDLE
 | 
			
		||||
        });
 | 
			
		||||
        this.add_actor(searchEntryBin);
 | 
			
		||||
 | 
			
		||||
        this._controls = new OverviewControls.ControlsManager(this._searchEntry);
 | 
			
		||||
 | 
			
		||||
        // Add our same-line elements after the search entry
 | 
			
		||||
        this.add(this._controls, { y_fill: true, expand: true });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    get dash() {
 | 
			
		||||
        return this._controls.dash;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    get searchEntry() {
 | 
			
		||||
        return this._searchEntry;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    get viewSelector() {
 | 
			
		||||
        return this._controls.viewSelector;
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
var Overview = class {
 | 
			
		||||
    constructor() {
 | 
			
		||||
        this._overviewCreated = false;
 | 
			
		||||
        this._initCalled = false;
 | 
			
		||||
 | 
			
		||||
        Main.sessionMode.connect('updated', this._sessionUpdated.bind(this));
 | 
			
		||||
        this._sessionUpdated();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    get dash() {
 | 
			
		||||
        return this._overview.dash;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    get dashIconSize() {
 | 
			
		||||
        logError(new Error('Usage of Overview.\'dashIconSize\' is deprecated, ' +
 | 
			
		||||
            'use \'dash.iconSize\' property instead'));
 | 
			
		||||
        return this.dash.iconSize;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    get viewSelector() {
 | 
			
		||||
        return this._overview.viewSelector;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    get animationInProgress() {
 | 
			
		||||
        return this._animationInProgress;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    get visible() {
 | 
			
		||||
        return this._visible;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    get visibleTarget() {
 | 
			
		||||
        return this._visibleTarget;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _createOverview() {
 | 
			
		||||
        if (this._overviewCreated)
 | 
			
		||||
        if (this._overview)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        if (this.isDummy)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        this._overviewCreated = true;
 | 
			
		||||
 | 
			
		||||
        this._overview = new St.BoxLayout({ name: 'overview',
 | 
			
		||||
                                            /* Translators: This is the main view to select
 | 
			
		||||
                                               activities. See also note for "Activities" string. */
 | 
			
		||||
                                            accessible_name: _("Overview"),
 | 
			
		||||
                                            vertical: true });
 | 
			
		||||
        this._overview.add_constraint(new LayoutManager.MonitorConstraint({ primary: true }));
 | 
			
		||||
        this._overview._delegate = this;
 | 
			
		||||
 | 
			
		||||
        // The main Background actors are inside global.window_group which are
 | 
			
		||||
        // hidden when displaying the overview, so we create a new
 | 
			
		||||
        // one. Instances of this class share a single CoglTexture behind the
 | 
			
		||||
@@ -116,11 +188,11 @@ var Overview = class {
 | 
			
		||||
 | 
			
		||||
        this._activationTime = 0;
 | 
			
		||||
 | 
			
		||||
        this.visible = false;           // animating to overview, in overview, animating out
 | 
			
		||||
        this._visible = false;          // animating to overview, in overview, animating out
 | 
			
		||||
        this._shown = false;            // show() and not hide()
 | 
			
		||||
        this._modal = false;            // have a modal grab
 | 
			
		||||
        this.animationInProgress = false;
 | 
			
		||||
        this.visibleTarget = false;
 | 
			
		||||
        this._animationInProgress = false;
 | 
			
		||||
        this._visibleTarget = false;
 | 
			
		||||
 | 
			
		||||
        // During transitions, we raise this to the top to avoid having the overview
 | 
			
		||||
        // area be reactive; it causes too many issues such as double clicks on
 | 
			
		||||
@@ -129,9 +201,6 @@ var Overview = class {
 | 
			
		||||
                                              reactive: true });
 | 
			
		||||
        Main.layoutManager.overviewGroup.add_child(this._coverPane);
 | 
			
		||||
        this._coverPane.connect('event', () => Clutter.EVENT_STOP);
 | 
			
		||||
 | 
			
		||||
        Main.layoutManager.overviewGroup.add_child(this._overview);
 | 
			
		||||
 | 
			
		||||
        this._coverPane.hide();
 | 
			
		||||
 | 
			
		||||
        // XDND
 | 
			
		||||
@@ -213,41 +282,12 @@ var Overview = class {
 | 
			
		||||
        if (this.isDummy)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        this._overview = new OverviewActor();
 | 
			
		||||
        this._overview._delegate = this;
 | 
			
		||||
        Main.layoutManager.overviewGroup.add_child(this._overview);
 | 
			
		||||
 | 
			
		||||
        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 }),
 | 
			
		||||
                                        reactive: false,
 | 
			
		||||
                                        opacity: 0 });
 | 
			
		||||
        this._overview.add_actor(this._panelGhost);
 | 
			
		||||
 | 
			
		||||
        this._searchEntry = new St.Entry({ style_class: 'search-entry',
 | 
			
		||||
                                           /* Translators: this is the text displayed
 | 
			
		||||
                                              in the search entry when no search is
 | 
			
		||||
                                              active; it should not exceed ~30
 | 
			
		||||
                                              characters. */
 | 
			
		||||
                                           hint_text: _("Type to search…"),
 | 
			
		||||
                                           track_hover: true,
 | 
			
		||||
                                           can_focus: true });
 | 
			
		||||
        this._searchEntryBin = new St.Bin({ child: this._searchEntry,
 | 
			
		||||
                                            x_align: St.Align.MIDDLE });
 | 
			
		||||
        this._overview.add_actor(this._searchEntryBin);
 | 
			
		||||
 | 
			
		||||
        // Create controls
 | 
			
		||||
        this._controls = new OverviewControls.ControlsManager(this._searchEntry);
 | 
			
		||||
        this._dash = this._controls.dash;
 | 
			
		||||
        this.viewSelector = this._controls.viewSelector;
 | 
			
		||||
 | 
			
		||||
        // Add our same-line elements after the search entry
 | 
			
		||||
        this._overview.add(this._controls.actor, { y_fill: true, expand: true });
 | 
			
		||||
 | 
			
		||||
        // TODO - recalculate everything when desktop size changes
 | 
			
		||||
        this.dashIconSize = this._dash.iconSize;
 | 
			
		||||
        this._dash.connect('icon-size-changed', () => {
 | 
			
		||||
            this.dashIconSize = this._dash.iconSize;
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        Main.layoutManager.connect('monitors-changed', this._relayout.bind(this));
 | 
			
		||||
        this._relayout();
 | 
			
		||||
    }
 | 
			
		||||
@@ -300,7 +340,7 @@ var Overview = class {
 | 
			
		||||
 | 
			
		||||
    _resetWindowSwitchTimeout() {
 | 
			
		||||
        if (this._windowSwitchTimeoutId != 0) {
 | 
			
		||||
            Mainloop.source_remove(this._windowSwitchTimeoutId);
 | 
			
		||||
            GLib.source_remove(this._windowSwitchTimeoutId);
 | 
			
		||||
            this._windowSwitchTimeoutId = 0;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
@@ -323,7 +363,9 @@ var Overview = class {
 | 
			
		||||
 | 
			
		||||
        if (targetIsWindow) {
 | 
			
		||||
            this._lastHoveredWindow = dragEvent.targetActor._delegate.metaWindow;
 | 
			
		||||
            this._windowSwitchTimeoutId = Mainloop.timeout_add(DND_WINDOW_SWITCH_TIMEOUT,
 | 
			
		||||
            this._windowSwitchTimeoutId = GLib.timeout_add(
 | 
			
		||||
                GLib.PRIORITY_DEFAULT,
 | 
			
		||||
                DND_WINDOW_SWITCH_TIMEOUT,
 | 
			
		||||
                () => {
 | 
			
		||||
                    this._windowSwitchTimeoutId = 0;
 | 
			
		||||
                    Main.activateWindow(dragEvent.targetActor._delegate.metaWindow,
 | 
			
		||||
@@ -424,7 +466,7 @@ var Overview = class {
 | 
			
		||||
 | 
			
		||||
    focusSearch() {
 | 
			
		||||
        this.show();
 | 
			
		||||
        this._searchEntry.grab_key_focus();
 | 
			
		||||
        this._overview.searchEntry.grab_key_focus();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fadeInDesktop() {
 | 
			
		||||
@@ -450,7 +492,7 @@ var Overview = class {
 | 
			
		||||
        this._desktopFade.show();
 | 
			
		||||
        this._desktopFade.ease({
 | 
			
		||||
            opacity: 0,
 | 
			
		||||
            mode: Clutter.Animates.EASE_OUT_QUAD,
 | 
			
		||||
            mode: Clutter.AnimationMode.EASE_OUT_QUAD,
 | 
			
		||||
            duration: ANIMATION_TIME
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
@@ -462,11 +504,11 @@ var Overview = class {
 | 
			
		||||
    // the overview if the user both triggered the hot corner and
 | 
			
		||||
    // clicked the Activities button.
 | 
			
		||||
    shouldToggleByCornerOrButton() {
 | 
			
		||||
        if (this.animationInProgress)
 | 
			
		||||
        if (this._animationInProgress)
 | 
			
		||||
            return false;
 | 
			
		||||
        if (this._inItemDrag || this._inWindowDrag)
 | 
			
		||||
            return false;
 | 
			
		||||
        if (this._activationTime == 0 ||
 | 
			
		||||
        if (!this._activationTime ||
 | 
			
		||||
            GLib.get_monotonic_time() / GLib.USEC_PER_SEC - this._activationTime > OVERVIEW_ACTIVATION_TIMEOUT)
 | 
			
		||||
            return true;
 | 
			
		||||
        return false;
 | 
			
		||||
@@ -476,20 +518,18 @@ var Overview = class {
 | 
			
		||||
        // We delay grab changes during animation so that when removing the
 | 
			
		||||
        // overview we don't have a problem with the release of a press/release
 | 
			
		||||
        // going to an application.
 | 
			
		||||
        if (this.animationInProgress)
 | 
			
		||||
        if (this._animationInProgress)
 | 
			
		||||
            return true;
 | 
			
		||||
 | 
			
		||||
        if (this._shown) {
 | 
			
		||||
            let shouldBeModal = !this._inXdndDrag;
 | 
			
		||||
            if (shouldBeModal) {
 | 
			
		||||
                if (!this._modal) {
 | 
			
		||||
                    if (Main.pushModal(this._overview,
 | 
			
		||||
                                       { actionMode: Shell.ActionMode.OVERVIEW })) {
 | 
			
		||||
                        this._modal = true;
 | 
			
		||||
                    } else {
 | 
			
		||||
                        this.hide();
 | 
			
		||||
                        return false;
 | 
			
		||||
                    }
 | 
			
		||||
            if (shouldBeModal && !this._modal) {
 | 
			
		||||
                let actionMode = Shell.ActionMode.OVERVIEW;
 | 
			
		||||
                if (Main.pushModal(this._overview, { actionMode })) {
 | 
			
		||||
                    this._modal = true;
 | 
			
		||||
                } else {
 | 
			
		||||
                    this.hide();
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
@@ -520,12 +560,12 @@ var Overview = class {
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    _animateVisible() {
 | 
			
		||||
        if (this.visible || this.animationInProgress)
 | 
			
		||||
        if (this._visible || this._animationInProgress)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        this.visible = true;
 | 
			
		||||
        this.animationInProgress = true;
 | 
			
		||||
        this.visibleTarget = true;
 | 
			
		||||
        this._visible = true;
 | 
			
		||||
        this._animationInProgress = true;
 | 
			
		||||
        this._visibleTarget = true;
 | 
			
		||||
        this._activationTime = GLib.get_monotonic_time() / GLib.USEC_PER_SEC;
 | 
			
		||||
 | 
			
		||||
        Meta.disable_unredirect_for_display(global.display);
 | 
			
		||||
@@ -546,7 +586,7 @@ var Overview = class {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _showDone() {
 | 
			
		||||
        this.animationInProgress = false;
 | 
			
		||||
        this._animationInProgress = false;
 | 
			
		||||
        this._desktopFade.hide();
 | 
			
		||||
        this._coverPane.hide();
 | 
			
		||||
 | 
			
		||||
@@ -586,11 +626,11 @@ var Overview = class {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _animateNotVisible() {
 | 
			
		||||
        if (!this.visible || this.animationInProgress)
 | 
			
		||||
        if (!this._visible || this._animationInProgress)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        this.animationInProgress = true;
 | 
			
		||||
        this.visibleTarget = false;
 | 
			
		||||
        this._animationInProgress = true;
 | 
			
		||||
        this._visibleTarget = false;
 | 
			
		||||
 | 
			
		||||
        this.viewSelector.animateFromOverview();
 | 
			
		||||
 | 
			
		||||
@@ -616,8 +656,8 @@ var Overview = class {
 | 
			
		||||
        this._desktopFade.hide();
 | 
			
		||||
        this._coverPane.hide();
 | 
			
		||||
 | 
			
		||||
        this.visible = false;
 | 
			
		||||
        this.animationInProgress = false;
 | 
			
		||||
        this._visible = false;
 | 
			
		||||
        this._animationInProgress = false;
 | 
			
		||||
 | 
			
		||||
        this.emit('hidden');
 | 
			
		||||
        // Handle any calls to show* while we were hiding
 | 
			
		||||
@@ -633,14 +673,17 @@ var Overview = class {
 | 
			
		||||
        if (this.isDummy)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        if (this.visible)
 | 
			
		||||
        if (this._visible)
 | 
			
		||||
            this.hide();
 | 
			
		||||
        else
 | 
			
		||||
            this.show();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    getShowAppsButton() {
 | 
			
		||||
        return this._dash.showAppsButton;
 | 
			
		||||
        logError(new Error('Usage of Overview.\'getShowAppsButton\' is deprecated, ' +
 | 
			
		||||
            'use \'dash.showAppsButton\' property instead'));
 | 
			
		||||
 | 
			
		||||
        return this.dash.showAppsButton;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
Signals.addSignalMethods(Overview.prototype);
 | 
			
		||||
 
 | 
			
		||||
@@ -14,8 +14,8 @@ var SIDE_CONTROLS_ANIMATION_TIME = 160;
 | 
			
		||||
function getRtlSlideDirection(direction, actor) {
 | 
			
		||||
    let rtl = (actor.text_direction == Clutter.TextDirection.RTL);
 | 
			
		||||
    if (rtl)
 | 
			
		||||
        direction = (direction == SlideDirection.LEFT) ?
 | 
			
		||||
            SlideDirection.RIGHT : SlideDirection.LEFT;
 | 
			
		||||
        direction = (direction == SlideDirection.LEFT)
 | 
			
		||||
            ? SlideDirection.RIGHT : SlideDirection.LEFT;
 | 
			
		||||
 | 
			
		||||
    return direction;
 | 
			
		||||
}
 | 
			
		||||
@@ -67,8 +67,9 @@ var SlideLayout = GObject.registerClass({
 | 
			
		||||
        // flags only determine what to do if the allocated box is bigger
 | 
			
		||||
        // than the actor's box.
 | 
			
		||||
        let realDirection = getRtlSlideDirection(this._direction, child);
 | 
			
		||||
        let alignX = (realDirection == SlideDirection.LEFT) ? (availWidth - natWidth)
 | 
			
		||||
                                                            : (availWidth - natWidth * this._slideX);
 | 
			
		||||
        let alignX = (realDirection == SlideDirection.LEFT)
 | 
			
		||||
            ? availWidth - natWidth
 | 
			
		||||
            : availWidth - natWidth * this._slideX;
 | 
			
		||||
 | 
			
		||||
        let actorBox = new Clutter.ActorBox();
 | 
			
		||||
        actorBox.x1 = box.x1 + alignX + this._translationX;
 | 
			
		||||
@@ -117,18 +118,21 @@ var SlideLayout = GObject.registerClass({
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
var SlidingControl = class {
 | 
			
		||||
    constructor(params) {
 | 
			
		||||
var SlidingControl = GObject.registerClass(
 | 
			
		||||
class SlidingControl extends St.Widget {
 | 
			
		||||
    _init(params) {
 | 
			
		||||
        params = Params.parse(params, { slideDirection: SlideDirection.LEFT });
 | 
			
		||||
 | 
			
		||||
        this._visible = true;
 | 
			
		||||
        this._inDrag = false;
 | 
			
		||||
 | 
			
		||||
        this.layout = new SlideLayout();
 | 
			
		||||
        this.layout.slideDirection = params.slideDirection;
 | 
			
		||||
        this.actor = new St.Widget({ layout_manager: this.layout,
 | 
			
		||||
                                     style_class: 'overview-controls',
 | 
			
		||||
                                     clip_to_allocation: true });
 | 
			
		||||
        super._init({
 | 
			
		||||
            layout_manager: this.layout,
 | 
			
		||||
            style_class: 'overview-controls',
 | 
			
		||||
            clip_to_allocation: true
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        this._visible = true;
 | 
			
		||||
        this._inDrag = false;
 | 
			
		||||
 | 
			
		||||
        Main.overview.connect('hiding', this._onOverviewHiding.bind(this));
 | 
			
		||||
 | 
			
		||||
@@ -146,20 +150,20 @@ var SlidingControl = class {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _updateSlide() {
 | 
			
		||||
        this.actor.ease_property('@layout.slide-x', this._getSlide(), {
 | 
			
		||||
        this.ease_property('@layout.slide-x', this._getSlide(), {
 | 
			
		||||
            mode: Clutter.AnimationMode.EASE_OUT_QUAD,
 | 
			
		||||
            duration: SIDE_CONTROLS_ANIMATION_TIME,
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    getVisibleWidth() {
 | 
			
		||||
        let child = this.actor.get_first_child();
 | 
			
		||||
        let child = this.get_first_child();
 | 
			
		||||
        let [, , natWidth] = child.get_preferred_size();
 | 
			
		||||
        return natWidth;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _getTranslation() {
 | 
			
		||||
        let child = this.actor.get_first_child();
 | 
			
		||||
        let child = this.get_first_child();
 | 
			
		||||
        let direction = getRtlSlideDirection(this.layout.slideDirection, child);
 | 
			
		||||
        let visibleWidth = this.getVisibleWidth();
 | 
			
		||||
 | 
			
		||||
@@ -185,7 +189,7 @@ var SlidingControl = class {
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        this.layout.translation_x = translationStart;
 | 
			
		||||
        this.actor.ease_property('@layout.translation-x', translationEnd, {
 | 
			
		||||
        this.ease_property('@layout.translation-x', translationEnd, {
 | 
			
		||||
            mode: Clutter.AnimationMode.EASE_OUT_QUAD,
 | 
			
		||||
            duration: SIDE_CONTROLS_ANIMATION_TIME,
 | 
			
		||||
        });
 | 
			
		||||
@@ -217,7 +221,7 @@ var SlidingControl = class {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fadeIn() {
 | 
			
		||||
        this.actor.ease({
 | 
			
		||||
        this.ease({
 | 
			
		||||
            opacity: 255,
 | 
			
		||||
            duration: SIDE_CONTROLS_ANIMATION_TIME / 2,
 | 
			
		||||
            mode: Clutter.AnimationMode.EASE_IN_QUAD
 | 
			
		||||
@@ -225,7 +229,7 @@ var SlidingControl = class {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fadeHalf() {
 | 
			
		||||
        this.actor.ease({
 | 
			
		||||
        this.ease({
 | 
			
		||||
            opacity: 128,
 | 
			
		||||
            duration: SIDE_CONTROLS_ANIMATION_TIME / 2,
 | 
			
		||||
            mode: Clutter.AnimationMode.EASE_OUT_QUAD
 | 
			
		||||
@@ -248,36 +252,38 @@ var SlidingControl = class {
 | 
			
		||||
        // selector; this means we can now safely set the full slide for
 | 
			
		||||
        // the next page, since slideIn or slideOut might have been called,
 | 
			
		||||
        // changing the visiblity
 | 
			
		||||
        this.remove_transition('@layout.slide-x');
 | 
			
		||||
        this.layout.slide_x = this._getSlide();
 | 
			
		||||
        this._updateTranslation();
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
var ThumbnailsSlider = class extends SlidingControl {
 | 
			
		||||
    constructor(thumbnailsBox) {
 | 
			
		||||
        super({ slideDirection: SlideDirection.RIGHT });
 | 
			
		||||
var ThumbnailsSlider = GObject.registerClass(
 | 
			
		||||
class ThumbnailsSlider extends SlidingControl {
 | 
			
		||||
    _init(thumbnailsBox) {
 | 
			
		||||
        super._init({ slideDirection: SlideDirection.RIGHT });
 | 
			
		||||
 | 
			
		||||
        this._thumbnailsBox = thumbnailsBox;
 | 
			
		||||
 | 
			
		||||
        this.actor.request_mode = Clutter.RequestMode.WIDTH_FOR_HEIGHT;
 | 
			
		||||
        this.actor.reactive = true;
 | 
			
		||||
        this.actor.track_hover = true;
 | 
			
		||||
        this.actor.add_actor(this._thumbnailsBox);
 | 
			
		||||
        this.request_mode = Clutter.RequestMode.WIDTH_FOR_HEIGHT;
 | 
			
		||||
        this.reactive = true;
 | 
			
		||||
        this.track_hover = true;
 | 
			
		||||
        this.add_actor(this._thumbnailsBox);
 | 
			
		||||
 | 
			
		||||
        Main.layoutManager.connect('monitors-changed', this._updateSlide.bind(this));
 | 
			
		||||
        global.workspace_manager.connect('active-workspace-changed',
 | 
			
		||||
                                         this._updateSlide.bind(this));
 | 
			
		||||
        global.workspace_manager.connect('notify::n-workspaces',
 | 
			
		||||
                                         this._updateSlide.bind(this));
 | 
			
		||||
        this.actor.connect('notify::hover', this._updateSlide.bind(this));
 | 
			
		||||
        this._thumbnailsBox.bind_property('visible', this.actor, 'visible', GObject.BindingFlags.SYNC_CREATE);
 | 
			
		||||
        this.connect('notify::hover', this._updateSlide.bind(this));
 | 
			
		||||
        this._thumbnailsBox.bind_property('visible', this, 'visible', GObject.BindingFlags.SYNC_CREATE);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _getAlwaysZoomOut() {
 | 
			
		||||
        // Always show the pager on hover, during a drag, or if workspaces are
 | 
			
		||||
        // actually used, e.g. there are windows on any non-active workspace
 | 
			
		||||
        let workspaceManager = global.workspace_manager;
 | 
			
		||||
        let alwaysZoomOut = this.actor.hover ||
 | 
			
		||||
        let alwaysZoomOut = this.hover ||
 | 
			
		||||
                            this._inDrag ||
 | 
			
		||||
                            !Meta.prefs_get_dynamic_workspaces() ||
 | 
			
		||||
                            workspaceManager.n_workspaces > 2 ||
 | 
			
		||||
@@ -302,12 +308,12 @@ var ThumbnailsSlider = class extends SlidingControl {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    getNonExpandedWidth() {
 | 
			
		||||
        let child = this.actor.get_first_child();
 | 
			
		||||
        let child = this.get_first_child();
 | 
			
		||||
        return child.get_theme_node().get_length('visible-width');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _onDragEnd() {
 | 
			
		||||
        this.actor.sync_hover();
 | 
			
		||||
        this.sync_hover();
 | 
			
		||||
        super._onDragEnd();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -319,7 +325,7 @@ var ThumbnailsSlider = class extends SlidingControl {
 | 
			
		||||
        if (alwaysZoomOut)
 | 
			
		||||
            return 1;
 | 
			
		||||
 | 
			
		||||
        let child = this.actor.get_first_child();
 | 
			
		||||
        let child = this.get_first_child();
 | 
			
		||||
        let preferredHeight = child.get_preferred_height(-1)[1];
 | 
			
		||||
        let expandedWidth = child.get_preferred_width(preferredHeight)[1];
 | 
			
		||||
 | 
			
		||||
@@ -333,24 +339,25 @@ var ThumbnailsSlider = class extends SlidingControl {
 | 
			
		||||
        else
 | 
			
		||||
            return this.getNonExpandedWidth();
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
var DashSlider = class extends SlidingControl {
 | 
			
		||||
    constructor(dash) {
 | 
			
		||||
        super({ slideDirection: SlideDirection.LEFT });
 | 
			
		||||
var DashSlider = GObject.registerClass(
 | 
			
		||||
class DashSlider extends SlidingControl {
 | 
			
		||||
    _init(dash) {
 | 
			
		||||
        super._init({ slideDirection: SlideDirection.LEFT });
 | 
			
		||||
 | 
			
		||||
        this._dash = dash;
 | 
			
		||||
 | 
			
		||||
        // SlideLayout reads the actor's expand flags to decide
 | 
			
		||||
        // whether to allocate the natural size to its child, or the whole
 | 
			
		||||
        // available allocation
 | 
			
		||||
        this._dash.actor.x_expand = true;
 | 
			
		||||
        this._dash.x_expand = true;
 | 
			
		||||
 | 
			
		||||
        this.actor.x_expand = true;
 | 
			
		||||
        this.actor.x_align = Clutter.ActorAlign.START;
 | 
			
		||||
        this.actor.y_expand = true;
 | 
			
		||||
        this.x_expand = true;
 | 
			
		||||
        this.x_align = Clutter.ActorAlign.START;
 | 
			
		||||
        this.y_expand = true;
 | 
			
		||||
 | 
			
		||||
        this.actor.add_actor(this._dash.actor);
 | 
			
		||||
        this.add_actor(this._dash);
 | 
			
		||||
 | 
			
		||||
        this._dash.connect('icon-size-changed', this._updateSlide.bind(this));
 | 
			
		||||
    }
 | 
			
		||||
@@ -369,7 +376,7 @@ var DashSlider = class extends SlidingControl {
 | 
			
		||||
    _onWindowDragEnd() {
 | 
			
		||||
        this.fadeIn();
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
var DashSpacer = GObject.registerClass(
 | 
			
		||||
class DashSpacer extends St.Widget {
 | 
			
		||||
@@ -414,12 +421,21 @@ var ControlsLayout = GObject.registerClass({
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
var ControlsManager = class {
 | 
			
		||||
    constructor(searchEntry) {
 | 
			
		||||
var ControlsManager = GObject.registerClass(
 | 
			
		||||
class ControlsManager extends St.Widget {
 | 
			
		||||
    _init(searchEntry) {
 | 
			
		||||
        let layout = new ControlsLayout();
 | 
			
		||||
        super._init({
 | 
			
		||||
            layout_manager: layout,
 | 
			
		||||
            x_expand: true,
 | 
			
		||||
            y_expand: true,
 | 
			
		||||
            clip_to_allocation: true
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        this.dash = new Dash.Dash();
 | 
			
		||||
        this._dashSlider = new DashSlider(this.dash);
 | 
			
		||||
        this._dashSpacer = new DashSpacer();
 | 
			
		||||
        this._dashSpacer.setDashActor(this._dashSlider.actor);
 | 
			
		||||
        this._dashSpacer.setDashActor(this._dashSlider);
 | 
			
		||||
 | 
			
		||||
        this._thumbnailsBox = new WorkspaceThumbnail.ThumbnailsBox();
 | 
			
		||||
        this._thumbnailsSlider = new ThumbnailsSlider(this._thumbnailsBox);
 | 
			
		||||
@@ -429,20 +445,15 @@ var ControlsManager = class {
 | 
			
		||||
        this.viewSelector.connect('page-changed', this._setVisibility.bind(this));
 | 
			
		||||
        this.viewSelector.connect('page-empty', this._onPageEmpty.bind(this));
 | 
			
		||||
 | 
			
		||||
        let layout = new ControlsLayout();
 | 
			
		||||
        this.actor = new St.Widget({ layout_manager: layout,
 | 
			
		||||
                                     x_expand: true, y_expand: true,
 | 
			
		||||
                                     clip_to_allocation: true });
 | 
			
		||||
        this._group = new St.BoxLayout({ name: 'overview-group',
 | 
			
		||||
                                         x_expand: true, y_expand: true });
 | 
			
		||||
        this.actor.add_actor(this._group);
 | 
			
		||||
        this.add_actor(this._group);
 | 
			
		||||
 | 
			
		||||
        this.actor.add_actor(this._dashSlider.actor);
 | 
			
		||||
        this.add_actor(this._dashSlider);
 | 
			
		||||
 | 
			
		||||
        this._group.add_actor(this._dashSpacer);
 | 
			
		||||
        this._group.add(this.viewSelector.actor, { x_fill: true,
 | 
			
		||||
                                                   expand: true });
 | 
			
		||||
        this._group.add_actor(this._thumbnailsSlider.actor);
 | 
			
		||||
        this._group.add(this.viewSelector, { x_fill: true, expand: true });
 | 
			
		||||
        this._group.add_actor(this._thumbnailsSlider);
 | 
			
		||||
 | 
			
		||||
        layout.connect('allocation-changed', this._updateWorkspacesGeometry.bind(this));
 | 
			
		||||
 | 
			
		||||
@@ -450,18 +461,18 @@ var ControlsManager = class {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _updateWorkspacesGeometry() {
 | 
			
		||||
        let [x, y] = this.actor.get_transformed_position();
 | 
			
		||||
        let [width, height] = this.actor.get_transformed_size();
 | 
			
		||||
        let [x, y] = this.get_transformed_position();
 | 
			
		||||
        let [width, height] = this.get_transformed_size();
 | 
			
		||||
        let geometry = { x: x, y: y, width: width, height: height };
 | 
			
		||||
 | 
			
		||||
        let spacing = this.actor.get_theme_node().get_length('spacing');
 | 
			
		||||
        let spacing = this.get_theme_node().get_length('spacing');
 | 
			
		||||
        let dashWidth = this._dashSlider.getVisibleWidth() + spacing;
 | 
			
		||||
        let thumbnailsWidth = this._thumbnailsSlider.getNonExpandedWidth() + spacing;
 | 
			
		||||
 | 
			
		||||
        geometry.width -= dashWidth;
 | 
			
		||||
        geometry.width -= thumbnailsWidth;
 | 
			
		||||
 | 
			
		||||
        if (this.actor.get_text_direction() == Clutter.TextDirection.LTR)
 | 
			
		||||
        if (this.get_text_direction() == Clutter.TextDirection.LTR)
 | 
			
		||||
            geometry.x += dashWidth;
 | 
			
		||||
        else
 | 
			
		||||
            geometry.x += thumbnailsWidth;
 | 
			
		||||
@@ -508,4 +519,4 @@ var ControlsManager = class {
 | 
			
		||||
 | 
			
		||||
        this._updateSpacerVisibility();
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										178
									
								
								js/ui/padOsd.js
									
									
									
									
									
								
							
							
						
						
									
										178
									
								
								js/ui/padOsd.js
									
									
									
									
									
								
							@@ -1,5 +1,5 @@
 | 
			
		||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
 | 
			
		||||
/* exported PadOsdService */
 | 
			
		||||
/* exported PadOsd, PadOsdService */
 | 
			
		||||
 | 
			
		||||
const { Atk, Clutter, GDesktopEnums, Gio,
 | 
			
		||||
        GLib, GObject, Gtk, Meta, Rsvg, St } = imports.gi;
 | 
			
		||||
@@ -22,40 +22,45 @@ const CCW = 1;
 | 
			
		||||
const UP = 0;
 | 
			
		||||
const DOWN = 1;
 | 
			
		||||
 | 
			
		||||
var PadChooser = class {
 | 
			
		||||
    constructor(device, groupDevices) {
 | 
			
		||||
        this.actor = new St.Button({ style_class: 'pad-chooser-button',
 | 
			
		||||
                                     toggle_mode: true,
 | 
			
		||||
                                     x_fill: false,
 | 
			
		||||
                                     y_fill: false,
 | 
			
		||||
                                     x_align: St.Align.MIDDLE,
 | 
			
		||||
                                     y_align: St.Align.MIDDLE });
 | 
			
		||||
var PadChooser = GObject.registerClass({
 | 
			
		||||
    Signals: { 'pad-selected': { param_types: [Clutter.InputDevice.$gtype] } }
 | 
			
		||||
}, class PadChooser extends St.Button {
 | 
			
		||||
    _init(device, groupDevices) {
 | 
			
		||||
        super._init({
 | 
			
		||||
            style_class: 'pad-chooser-button',
 | 
			
		||||
            toggle_mode: true,
 | 
			
		||||
            x_fill: false,
 | 
			
		||||
            y_fill: false,
 | 
			
		||||
            x_align: St.Align.MIDDLE,
 | 
			
		||||
            y_align: St.Align.MIDDLE
 | 
			
		||||
        });
 | 
			
		||||
        this.currentDevice = device;
 | 
			
		||||
        this._padChooserMenu = null;
 | 
			
		||||
 | 
			
		||||
        let arrow = new St.Icon({ style_class: 'popup-menu-arrow',
 | 
			
		||||
                                  icon_name: 'pan-down-symbolic',
 | 
			
		||||
                                  accessible_role: Atk.Role.ARROW });
 | 
			
		||||
        this.actor.set_child(arrow);
 | 
			
		||||
        this.set_child(arrow);
 | 
			
		||||
        this._ensureMenu(groupDevices);
 | 
			
		||||
 | 
			
		||||
        this.actor.connect('destroy', this._onDestroy.bind(this));
 | 
			
		||||
        this.actor.connect('clicked', actor => {
 | 
			
		||||
            if (actor.get_checked()) {
 | 
			
		||||
                if (this._padChooserMenu != null)
 | 
			
		||||
                    this._padChooserMenu.open(true);
 | 
			
		||||
                else
 | 
			
		||||
                    this.set_checked(false);
 | 
			
		||||
            } else {
 | 
			
		||||
                this._padChooserMenu.close(true);
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
        this.connect('destroy', this._onDestroy.bind(this));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    vfunc_clicked() {
 | 
			
		||||
        if (this.get_checked()) {
 | 
			
		||||
            if (this._padChooserMenu != null)
 | 
			
		||||
                this._padChooserMenu.open(true);
 | 
			
		||||
            else
 | 
			
		||||
                this.set_checked(false);
 | 
			
		||||
        } else {
 | 
			
		||||
            this._padChooserMenu.close(true);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _ensureMenu(devices) {
 | 
			
		||||
        this._padChooserMenu =  new PopupMenu.PopupMenu(this.actor, 0.5, St.Side.TOP);
 | 
			
		||||
        this._padChooserMenu =  new PopupMenu.PopupMenu(this, 0.5, St.Side.TOP);
 | 
			
		||||
        this._padChooserMenu.connect('menu-closed', () => {
 | 
			
		||||
            this.actor.set_checked(false);
 | 
			
		||||
            this.set_checked(false);
 | 
			
		||||
        });
 | 
			
		||||
        this._padChooserMenu.actor.hide();
 | 
			
		||||
        Main.uiGroup.add_actor(this._padChooserMenu.actor);
 | 
			
		||||
@@ -78,24 +83,20 @@ var PadChooser = class {
 | 
			
		||||
    update(devices) {
 | 
			
		||||
        if (this._padChooserMenu)
 | 
			
		||||
            this._padChooserMenu.actor.destroy();
 | 
			
		||||
        this.actor.set_checked(false);
 | 
			
		||||
        this.set_checked(false);
 | 
			
		||||
        this._ensureMenu(devices);
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
    destroy() {
 | 
			
		||||
        this.actor.destroy();
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
Signals.addSignalMethods(PadChooser.prototype);
 | 
			
		||||
 | 
			
		||||
var KeybindingEntry = class {
 | 
			
		||||
    constructor() {
 | 
			
		||||
        this.actor = new St.Entry({ hint_text: _("New shortcut…"),
 | 
			
		||||
                                    style: 'width: 10em' });
 | 
			
		||||
        this.actor.connect('captured-event', this._onCapturedEvent.bind(this));
 | 
			
		||||
var KeybindingEntry = GObject.registerClass({
 | 
			
		||||
    GTypeName: 'PadOsd_KeybindingEntry',
 | 
			
		||||
    Signals: { 'keybinding-edited': {} }
 | 
			
		||||
}, class KeybindingEntry extends St.Entry {
 | 
			
		||||
    _init() {
 | 
			
		||||
        super._init({ hint_text: _("New shortcut…"), style: 'width: 10em' });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _onCapturedEvent(actor, event) {
 | 
			
		||||
    vfunc_captured_event(event) {
 | 
			
		||||
        if (event.type() != Clutter.EventType.KEY_PRESS)
 | 
			
		||||
            return Clutter.EVENT_PROPAGATE;
 | 
			
		||||
 | 
			
		||||
@@ -103,23 +104,24 @@ var KeybindingEntry = class {
 | 
			
		||||
                                                    event.get_key_symbol(),
 | 
			
		||||
                                                    event.get_key_code(),
 | 
			
		||||
                                                    event.get_state());
 | 
			
		||||
        this.actor.set_text(str);
 | 
			
		||||
        this.set_text(str);
 | 
			
		||||
        this.emit('keybinding-edited', str);
 | 
			
		||||
        return Clutter.EVENT_STOP;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
Signals.addSignalMethods(KeybindingEntry.prototype);
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
var ActionComboBox = class {
 | 
			
		||||
    constructor() {
 | 
			
		||||
        this.actor = new St.Button({ style_class: 'button' });
 | 
			
		||||
        this.actor.connect('clicked', this._onButtonClicked.bind(this));
 | 
			
		||||
        this.actor.set_toggle_mode(true);
 | 
			
		||||
var ActionComboBox = GObject.registerClass({
 | 
			
		||||
    GTypeName: 'PadOsd_ActionComboBox',
 | 
			
		||||
    Signals: { 'action-selected': { param_types: [GObject.TYPE_INT] } }
 | 
			
		||||
}, class ActionComboBox extends St.Button {
 | 
			
		||||
    _init() {
 | 
			
		||||
        super._init({ style_class: 'button' });
 | 
			
		||||
        this.set_toggle_mode(true);
 | 
			
		||||
 | 
			
		||||
        let boxLayout = new Clutter.BoxLayout({ orientation: Clutter.Orientation.HORIZONTAL,
 | 
			
		||||
                                                spacing: 6 });
 | 
			
		||||
        let box = new St.Widget({ layout_manager: boxLayout });
 | 
			
		||||
        this.actor.set_child(box);
 | 
			
		||||
        this.set_child(box);
 | 
			
		||||
 | 
			
		||||
        this._label = new St.Label({ style_class: 'combo-box-label' });
 | 
			
		||||
        box.add_child(this._label);
 | 
			
		||||
@@ -131,9 +133,9 @@ var ActionComboBox = class {
 | 
			
		||||
                                  y_align: Clutter.ActorAlign.CENTER });
 | 
			
		||||
        box.add_child(arrow);
 | 
			
		||||
 | 
			
		||||
        this._editMenu = new PopupMenu.PopupMenu(this.actor, 0, St.Side.TOP);
 | 
			
		||||
        this._editMenu = new PopupMenu.PopupMenu(this, 0, St.Side.TOP);
 | 
			
		||||
        this._editMenu.connect('menu-closed', () => {
 | 
			
		||||
            this.actor.set_checked(false);
 | 
			
		||||
            this.set_checked(false);
 | 
			
		||||
        });
 | 
			
		||||
        this._editMenu.actor.hide();
 | 
			
		||||
        Main.uiGroup.add_actor(this._editMenu.actor);
 | 
			
		||||
@@ -179,8 +181,8 @@ var ActionComboBox = class {
 | 
			
		||||
        this._editMenu.close(true);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _onButtonClicked() {
 | 
			
		||||
        if (this.actor.get_checked())
 | 
			
		||||
    vfunc_clicked() {
 | 
			
		||||
        if (this.get_checked())
 | 
			
		||||
            this.popup();
 | 
			
		||||
        else
 | 
			
		||||
            this.popdown();
 | 
			
		||||
@@ -189,38 +191,40 @@ var ActionComboBox = class {
 | 
			
		||||
    setButtonActionsActive(active) {
 | 
			
		||||
        this._buttonItems.forEach(item => item.setSensitive(active));
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
Signals.addSignalMethods(ActionComboBox.prototype);
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
var ActionEditor = class {
 | 
			
		||||
    constructor() {
 | 
			
		||||
var ActionEditor = GObject.registerClass({
 | 
			
		||||
    GTypeName: 'PadOsd_ActionEditor',
 | 
			
		||||
    Signals: { 'done': {} }
 | 
			
		||||
}, class ActionEditor extends St.Widget {
 | 
			
		||||
    _init() {
 | 
			
		||||
        let boxLayout = new Clutter.BoxLayout({ orientation: Clutter.Orientation.HORIZONTAL,
 | 
			
		||||
                                                spacing: 12 });
 | 
			
		||||
 | 
			
		||||
        this.actor = new St.Widget({ layout_manager: boxLayout });
 | 
			
		||||
        super._init({ layout_manager: boxLayout });
 | 
			
		||||
 | 
			
		||||
        this._actionComboBox = new ActionComboBox();
 | 
			
		||||
        this._actionComboBox.connect('action-selected', this._onActionSelected.bind(this));
 | 
			
		||||
        this.actor.add_actor(this._actionComboBox.actor);
 | 
			
		||||
        this.add_actor(this._actionComboBox);
 | 
			
		||||
 | 
			
		||||
        this._keybindingEdit = new KeybindingEntry();
 | 
			
		||||
        this._keybindingEdit.connect('keybinding-edited', this._onKeybindingEdited.bind(this));
 | 
			
		||||
        this.actor.add_actor(this._keybindingEdit.actor);
 | 
			
		||||
        this.add_actor(this._keybindingEdit);
 | 
			
		||||
 | 
			
		||||
        this._doneButton = new St.Button({ label: _("Done"),
 | 
			
		||||
                                           style_class: 'button',
 | 
			
		||||
                                           x_expand: false });
 | 
			
		||||
        this._doneButton.connect('clicked', this._onEditingDone.bind(this));
 | 
			
		||||
        this.actor.add_actor(this._doneButton);
 | 
			
		||||
        this.add_actor(this._doneButton);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _updateKeybindingEntryState() {
 | 
			
		||||
        if (this._currentAction == GDesktopEnums.PadButtonAction.KEYBINDING) {
 | 
			
		||||
            this._keybindingEdit.actor.set_text(this._currentKeybinding);
 | 
			
		||||
            this._keybindingEdit.actor.show();
 | 
			
		||||
            this._keybindingEdit.actor.grab_key_focus();
 | 
			
		||||
            this._keybindingEdit.set_text(this._currentKeybinding);
 | 
			
		||||
            this._keybindingEdit.show();
 | 
			
		||||
            this._keybindingEdit.grab_key_focus();
 | 
			
		||||
        } else {
 | 
			
		||||
            this._keybindingEdit.actor.hide();
 | 
			
		||||
            this._keybindingEdit.hide();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -238,7 +242,7 @@ var ActionEditor = class {
 | 
			
		||||
 | 
			
		||||
    close() {
 | 
			
		||||
        this._actionComboBox.popdown();
 | 
			
		||||
        this.actor.hide();
 | 
			
		||||
        this.hide();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _onKeybindingEdited(entry, keybinding) {
 | 
			
		||||
@@ -272,8 +276,7 @@ var ActionEditor = class {
 | 
			
		||||
        this.close();
 | 
			
		||||
        this.emit('done');
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
Signals.addSignalMethods(ActionEditor.prototype);
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
var PadDiagram = GObject.registerClass({
 | 
			
		||||
    Properties: {
 | 
			
		||||
@@ -615,8 +618,18 @@ var PadDiagram = GObject.registerClass({
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
var PadOsd = class {
 | 
			
		||||
    constructor(padDevice, settings, imagePath, editionMode, monitorIndex) {
 | 
			
		||||
var PadOsd = GObject.registerClass({
 | 
			
		||||
    Signals: { 'pad-selected': { param_types: [Clutter.InputDevice.$gtype] } }
 | 
			
		||||
}, class PadOsd extends St.BoxLayout {
 | 
			
		||||
    _init(padDevice, settings, imagePath, editionMode, monitorIndex) {
 | 
			
		||||
        super._init({
 | 
			
		||||
            style_class: 'pad-osd-window',
 | 
			
		||||
            vertical: true,
 | 
			
		||||
            x_expand: true,
 | 
			
		||||
            y_expand: true,
 | 
			
		||||
            reactive: true
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        this.padDevice = padDevice;
 | 
			
		||||
        this._groupPads = [padDevice];
 | 
			
		||||
        this._settings = settings;
 | 
			
		||||
@@ -653,23 +666,18 @@ var PadOsd = class {
 | 
			
		||||
                this._groupPads.push(device);
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        this.actor = new St.BoxLayout({ style_class: 'pad-osd-window',
 | 
			
		||||
                                        x_expand: true,
 | 
			
		||||
                                        y_expand: true,
 | 
			
		||||
                                        vertical: true,
 | 
			
		||||
                                        reactive: true });
 | 
			
		||||
        this.actor.connect('destroy', this._onDestroy.bind(this));
 | 
			
		||||
        Main.uiGroup.add_actor(this.actor);
 | 
			
		||||
        this.connect('destroy', this._onDestroy.bind(this));
 | 
			
		||||
        Main.uiGroup.add_actor(this);
 | 
			
		||||
 | 
			
		||||
        this._monitorIndex = monitorIndex;
 | 
			
		||||
        let constraint = new Layout.MonitorConstraint({ index: monitorIndex });
 | 
			
		||||
        this.actor.add_constraint(constraint);
 | 
			
		||||
        this.add_constraint(constraint);
 | 
			
		||||
 | 
			
		||||
        this._titleBox = new St.BoxLayout({ style_class: 'pad-osd-title-box',
 | 
			
		||||
                                            vertical: false,
 | 
			
		||||
                                            x_expand: false,
 | 
			
		||||
                                            x_align: Clutter.ActorAlign.CENTER });
 | 
			
		||||
        this.actor.add_actor(this._titleBox);
 | 
			
		||||
        this.add_actor(this._titleBox);
 | 
			
		||||
 | 
			
		||||
        let labelBox = new St.BoxLayout({ style_class: 'pad-osd-title-menu-box',
 | 
			
		||||
                                          vertical: true });
 | 
			
		||||
@@ -690,10 +698,10 @@ var PadOsd = class {
 | 
			
		||||
 | 
			
		||||
        this._padDiagram = new PadDiagram({ image: this._imagePath,
 | 
			
		||||
                                            left_handed: settings.get_boolean('left-handed'),
 | 
			
		||||
                                            editor_actor: this._actionEditor.actor,
 | 
			
		||||
                                            editor_actor: this._actionEditor,
 | 
			
		||||
                                            x_expand: true,
 | 
			
		||||
                                            y_expand: true });
 | 
			
		||||
        this.actor.add_actor(this._padDiagram);
 | 
			
		||||
        this.add_actor(this._padDiagram);
 | 
			
		||||
 | 
			
		||||
        // FIXME: Fix num buttons.
 | 
			
		||||
        let i = 0;
 | 
			
		||||
@@ -724,7 +732,7 @@ var PadOsd = class {
 | 
			
		||||
                                        x_expand: true,
 | 
			
		||||
                                        x_align: Clutter.ActorAlign.CENTER,
 | 
			
		||||
                                        y_align: Clutter.ActorAlign.CENTER });
 | 
			
		||||
        this.actor.add_actor(buttonBox);
 | 
			
		||||
        this.add_actor(buttonBox);
 | 
			
		||||
        this._editButton = new St.Button({ label: _("Edit…"),
 | 
			
		||||
                                           style_class: 'button',
 | 
			
		||||
                                           x_align: Clutter.ActorAlign.CENTER,
 | 
			
		||||
@@ -735,7 +743,7 @@ var PadOsd = class {
 | 
			
		||||
        buttonBox.add_actor(this._editButton);
 | 
			
		||||
 | 
			
		||||
        this._syncEditionMode();
 | 
			
		||||
        Main.pushModal(this.actor);
 | 
			
		||||
        Main.pushModal(this);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _updatePadChooser() {
 | 
			
		||||
@@ -745,7 +753,7 @@ var PadOsd = class {
 | 
			
		||||
                this._padChooser.connect('pad-selected', (chooser, pad) => {
 | 
			
		||||
                    this._requestForOtherPad(pad);
 | 
			
		||||
                });
 | 
			
		||||
                this._titleBox.add_child(this._padChooser.actor);
 | 
			
		||||
                this._titleBox.add_child(this._padChooser);
 | 
			
		||||
            } else {
 | 
			
		||||
                this._padChooser.update(this._groupPads);
 | 
			
		||||
            }
 | 
			
		||||
@@ -918,12 +926,8 @@ var PadOsd = class {
 | 
			
		||||
        this._syncEditionMode();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    destroy() {
 | 
			
		||||
        this.actor.destroy();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _onDestroy() {
 | 
			
		||||
        Main.popModal(this.actor);
 | 
			
		||||
        Main.popModal(this);
 | 
			
		||||
        this._actionEditor.close();
 | 
			
		||||
 | 
			
		||||
        let deviceManager = Clutter.DeviceManager.get_default();
 | 
			
		||||
@@ -941,11 +945,9 @@ var PadOsd = class {
 | 
			
		||||
            this._capturedEventId = 0;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this.actor = null;
 | 
			
		||||
        this.emit('closed');
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
Signals.addSignalMethods(PadOsd.prototype);
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
const PadOsdIface = loadInterfaceXML('org.gnome.Shell.Wacom.PadOsd');
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -20,14 +20,17 @@ var ANIMATION_DELAY = 100;
 | 
			
		||||
var PageIndicators = GObject.registerClass({
 | 
			
		||||
    Signals: { 'page-activated': { param_types: [GObject.TYPE_INT] } }
 | 
			
		||||
}, class PageIndicators extends St.BoxLayout {
 | 
			
		||||
    _init(vertical = true) {
 | 
			
		||||
        super._init({ style_class: 'page-indicators',
 | 
			
		||||
                      vertical,
 | 
			
		||||
                      x_expand: true, y_expand: true,
 | 
			
		||||
                      x_align: vertical ? Clutter.ActorAlign.END : Clutter.ActorAlign.CENTER,
 | 
			
		||||
                      y_align: vertical ? Clutter.ActorAlign.CENTER : Clutter.ActorAlign.END,
 | 
			
		||||
                      reactive: true,
 | 
			
		||||
                      clip_to_allocation: true });
 | 
			
		||||
    _init(orientation = Clutter.Orientation.VERTICAL) {
 | 
			
		||||
        let vertical = orientation == Clutter.Orientation.VERTICAL;
 | 
			
		||||
        super._init({
 | 
			
		||||
            style_class: 'page-indicators',
 | 
			
		||||
            vertical,
 | 
			
		||||
            x_expand: true, y_expand: true,
 | 
			
		||||
            x_align: vertical ? Clutter.ActorAlign.END : Clutter.ActorAlign.CENTER,
 | 
			
		||||
            y_align: vertical ? Clutter.ActorAlign.CENTER : Clutter.ActorAlign.END,
 | 
			
		||||
            reactive: true,
 | 
			
		||||
            clip_to_allocation: true
 | 
			
		||||
        });
 | 
			
		||||
        this._nPages = 0;
 | 
			
		||||
        this._currentPage = undefined;
 | 
			
		||||
        this._reactive = true;
 | 
			
		||||
@@ -93,18 +96,26 @@ var PageIndicators = GObject.registerClass({
 | 
			
		||||
var AnimatedPageIndicators = GObject.registerClass(
 | 
			
		||||
class AnimatedPageIndicators extends PageIndicators {
 | 
			
		||||
    _init() {
 | 
			
		||||
        super._init(true);
 | 
			
		||||
        super._init();
 | 
			
		||||
        this.connect('destroy', this._onDestroy.bind(this));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
        this.connect('notify::mapped', () => {
 | 
			
		||||
            if (!this.mapped)
 | 
			
		||||
                return;
 | 
			
		||||
    _onDestroy() {
 | 
			
		||||
        if (this.animateLater) {
 | 
			
		||||
            Meta.later_remove(this.animateLater);
 | 
			
		||||
            this.animateLater = 0;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
            // Implicit animations are skipped for unmapped actors, and our
 | 
			
		||||
            // children aren't mapped yet, so defer to a later handler
 | 
			
		||||
            Meta.later_add(Meta.LaterType.BEFORE_REDRAW, () => {
 | 
			
		||||
                this.animateIndicators(AnimationDirection.IN);
 | 
			
		||||
                return GLib.SOURCE_REMOVE;
 | 
			
		||||
            });
 | 
			
		||||
    vfunc_map() {
 | 
			
		||||
        super.vfunc_map();
 | 
			
		||||
 | 
			
		||||
        // Implicit animations are skipped for unmapped actors, and our
 | 
			
		||||
        // children aren't mapped yet, so defer to a later handler
 | 
			
		||||
        this.animateLater = Meta.later_add(Meta.LaterType.BEFORE_REDRAW, () => {
 | 
			
		||||
            this.animateLater = 0;
 | 
			
		||||
            this.animateIndicators(AnimationDirection.IN);
 | 
			
		||||
            return GLib.SOURCE_REMOVE;
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -126,12 +137,14 @@ class AnimatedPageIndicators extends PageIndicators {
 | 
			
		||||
            offset = children[0].width;
 | 
			
		||||
 | 
			
		||||
        let isAnimationIn = animationDirection == AnimationDirection.IN;
 | 
			
		||||
        let delay = isAnimationIn ? INDICATORS_ANIMATION_DELAY :
 | 
			
		||||
                                    INDICATORS_ANIMATION_DELAY_OUT;
 | 
			
		||||
        let delay = isAnimationIn
 | 
			
		||||
            ? INDICATORS_ANIMATION_DELAY
 | 
			
		||||
            : INDICATORS_ANIMATION_DELAY_OUT;
 | 
			
		||||
        let baseTime = isAnimationIn ? INDICATORS_BASE_TIME : INDICATORS_BASE_TIME_OUT;
 | 
			
		||||
        let totalAnimationTime = baseTime + delay * this._nPages;
 | 
			
		||||
        let maxTime = isAnimationIn ? INDICATORS_ANIMATION_MAX_TIME :
 | 
			
		||||
                                      INDICATORS_ANIMATION_MAX_TIME_OUT;
 | 
			
		||||
        let maxTime = isAnimationIn
 | 
			
		||||
            ? INDICATORS_ANIMATION_MAX_TIME
 | 
			
		||||
            : INDICATORS_ANIMATION_MAX_TIME_OUT;
 | 
			
		||||
        if (totalAnimationTime > maxTime)
 | 
			
		||||
            delay -= (totalAnimationTime - maxTime) / this._nPages;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										166
									
								
								js/ui/panel.js
									
									
									
									
									
								
							
							
						
						
									
										166
									
								
								js/ui/panel.js
									
									
									
									
									
								
							@@ -3,7 +3,6 @@
 | 
			
		||||
 | 
			
		||||
const { Atk, Clutter, Gio, GLib, GObject, Meta, Shell, St } = imports.gi;
 | 
			
		||||
const Cairo = imports.cairo;
 | 
			
		||||
const Mainloop = imports.mainloop;
 | 
			
		||||
 | 
			
		||||
const Animation = imports.ui.animation;
 | 
			
		||||
const Config = imports.misc.config;
 | 
			
		||||
@@ -236,7 +235,7 @@ var AppMenuButton = GObject.registerClass({
 | 
			
		||||
        this._overviewShowingId = Main.overview.connect('showing', this._sync.bind(this));
 | 
			
		||||
 | 
			
		||||
        this._spinner = new Animation.Spinner(PANEL_ICON_SIZE, true);
 | 
			
		||||
        this._container.add_actor(this._spinner.actor);
 | 
			
		||||
        this._container.add_actor(this._spinner);
 | 
			
		||||
 | 
			
		||||
        let menu = new AppMenu(this);
 | 
			
		||||
        this.setMenu(menu);
 | 
			
		||||
@@ -431,9 +430,6 @@ class ActivitiesButton extends PanelMenu.Button {
 | 
			
		||||
 | 
			
		||||
        this.label_actor = this._label;
 | 
			
		||||
 | 
			
		||||
        this.connect('captured-event', this._onCapturedEvent.bind(this));
 | 
			
		||||
        this.connect_after('key-release-event', this._onKeyRelease.bind(this));
 | 
			
		||||
 | 
			
		||||
        Main.overview.connect('showing', () => {
 | 
			
		||||
            this.add_style_pseudo_class('overview');
 | 
			
		||||
            this.add_accessible_state (Atk.StateType.CHECKED);
 | 
			
		||||
@@ -451,8 +447,8 @@ class ActivitiesButton extends PanelMenu.Button {
 | 
			
		||||
            return DND.DragMotionResult.CONTINUE;
 | 
			
		||||
 | 
			
		||||
        if (this._xdndTimeOut != 0)
 | 
			
		||||
            Mainloop.source_remove(this._xdndTimeOut);
 | 
			
		||||
        this._xdndTimeOut = Mainloop.timeout_add(BUTTON_DND_ACTIVATION_TIMEOUT, () => {
 | 
			
		||||
            GLib.source_remove(this._xdndTimeOut);
 | 
			
		||||
        this._xdndTimeOut = GLib.timeout_add(GLib.PRIORITY_DEFAULT, BUTTON_DND_ACTIVATION_TIMEOUT, () => {
 | 
			
		||||
            this._xdndToggleOverview();
 | 
			
		||||
        });
 | 
			
		||||
        GLib.Source.set_name_by_id(this._xdndTimeOut, '[gnome-shell] this._xdndToggleOverview');
 | 
			
		||||
@@ -460,7 +456,7 @@ class ActivitiesButton extends PanelMenu.Button {
 | 
			
		||||
        return DND.DragMotionResult.CONTINUE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _onCapturedEvent(actor, event) {
 | 
			
		||||
    vfunc_captured_event(event) {
 | 
			
		||||
        if (event.type() == Clutter.EventType.BUTTON_PRESS ||
 | 
			
		||||
            event.type() == Clutter.EventType.TOUCH_BEGIN) {
 | 
			
		||||
            if (!Main.overview.shouldToggleByCornerOrButton())
 | 
			
		||||
@@ -469,9 +465,7 @@ class ActivitiesButton extends PanelMenu.Button {
 | 
			
		||||
        return Clutter.EVENT_PROPAGATE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _onEvent(actor, event) {
 | 
			
		||||
        super._onEvent(actor, event);
 | 
			
		||||
 | 
			
		||||
    vfunc_event(event) {
 | 
			
		||||
        if (event.type() == Clutter.EventType.TOUCH_END ||
 | 
			
		||||
            event.type() == Clutter.EventType.BUTTON_RELEASE)
 | 
			
		||||
            if (Main.overview.shouldToggleByCornerOrButton())
 | 
			
		||||
@@ -480,13 +474,16 @@ class ActivitiesButton extends PanelMenu.Button {
 | 
			
		||||
        return Clutter.EVENT_PROPAGATE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _onKeyRelease(actor, event) {
 | 
			
		||||
        let symbol = event.get_key_symbol();
 | 
			
		||||
        if (symbol == Clutter.KEY_Return || symbol == Clutter.KEY_space) {
 | 
			
		||||
            if (Main.overview.shouldToggleByCornerOrButton())
 | 
			
		||||
                Main.overview.toggle();
 | 
			
		||||
    vfunc_key_release_event(keyEvent) {
 | 
			
		||||
        let ret = super.vfunc_key_release_event(keyEvent);
 | 
			
		||||
        if (ret == Clutter.EVENT_PROPAGATE) {
 | 
			
		||||
            let symbol = keyEvent.keyval;
 | 
			
		||||
            if (symbol == Clutter.KEY_Return || symbol == Clutter.KEY_space) {
 | 
			
		||||
                if (Main.overview.shouldToggleByCornerOrButton())
 | 
			
		||||
                    Main.overview.toggle();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return Clutter.EVENT_PROPAGATE;
 | 
			
		||||
        return ret;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _xdndToggleOverview() {
 | 
			
		||||
@@ -496,19 +493,18 @@ class ActivitiesButton extends PanelMenu.Button {
 | 
			
		||||
        if (pickedActor == this && Main.overview.shouldToggleByCornerOrButton())
 | 
			
		||||
            Main.overview.toggle();
 | 
			
		||||
 | 
			
		||||
        Mainloop.source_remove(this._xdndTimeOut);
 | 
			
		||||
        GLib.source_remove(this._xdndTimeOut);
 | 
			
		||||
        this._xdndTimeOut = 0;
 | 
			
		||||
        return GLib.SOURCE_REMOVE;
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
var PanelCorner = class {
 | 
			
		||||
    constructor(side) {
 | 
			
		||||
var PanelCorner = GObject.registerClass(
 | 
			
		||||
class PanelCorner extends St.DrawingArea {
 | 
			
		||||
    _init(side) {
 | 
			
		||||
        this._side = side;
 | 
			
		||||
 | 
			
		||||
        this.actor = new St.DrawingArea({ style_class: 'panel-corner' });
 | 
			
		||||
        this.actor.connect('style-changed', this._styleChanged.bind(this));
 | 
			
		||||
        this.actor.connect('repaint', this._repaint.bind(this));
 | 
			
		||||
        super._init({ style_class: 'panel-corner' });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _findRightmostButton(container) {
 | 
			
		||||
@@ -598,7 +594,7 @@ var PanelCorner = class {
 | 
			
		||||
            this._buttonStyleChangedSignalId = button.connect('style-changed',
 | 
			
		||||
                () => {
 | 
			
		||||
                    let pseudoClass = button.get_style_pseudo_class();
 | 
			
		||||
                    this.actor.set_style_pseudo_class(pseudoClass);
 | 
			
		||||
                    this.set_style_pseudo_class(pseudoClass);
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            // The corner doesn't support theme transitions, so override
 | 
			
		||||
@@ -607,8 +603,8 @@ var PanelCorner = class {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _repaint() {
 | 
			
		||||
        let node = this.actor.get_theme_node();
 | 
			
		||||
    vfunc_repaint() {
 | 
			
		||||
        let node = this.get_theme_node();
 | 
			
		||||
 | 
			
		||||
        let cornerRadius = node.get_length("-panel-corner-radius");
 | 
			
		||||
        let borderWidth = node.get_length('-panel-corner-border-width');
 | 
			
		||||
@@ -619,7 +615,7 @@ var PanelCorner = class {
 | 
			
		||||
        let overlap = borderColor.alpha != 0;
 | 
			
		||||
        let offsetY = overlap ? 0 : borderWidth;
 | 
			
		||||
 | 
			
		||||
        let cr = this.actor.get_context();
 | 
			
		||||
        let cr = this.get_context();
 | 
			
		||||
        cr.setOperator(Cairo.Operator.SOURCE);
 | 
			
		||||
 | 
			
		||||
        cr.moveTo(0, offsetY);
 | 
			
		||||
@@ -655,16 +651,17 @@ var PanelCorner = class {
 | 
			
		||||
        cr.$dispose();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _styleChanged() {
 | 
			
		||||
        let node = this.actor.get_theme_node();
 | 
			
		||||
    vfunc_style_changed() {
 | 
			
		||||
        super.vfunc_style_changed();
 | 
			
		||||
        let node = this.get_theme_node();
 | 
			
		||||
 | 
			
		||||
        let cornerRadius = node.get_length("-panel-corner-radius");
 | 
			
		||||
        let borderWidth = node.get_length('-panel-corner-border-width');
 | 
			
		||||
 | 
			
		||||
        this.actor.set_size(cornerRadius, borderWidth + cornerRadius);
 | 
			
		||||
        this.actor.set_anchor_point(0, borderWidth);
 | 
			
		||||
        this.set_size(cornerRadius, borderWidth + cornerRadius);
 | 
			
		||||
        this.set_anchor_point(0, borderWidth);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
var AggregateLayout = GObject.registerClass(
 | 
			
		||||
class AggregateLayout extends Clutter.BoxLayout {
 | 
			
		||||
@@ -729,20 +726,20 @@ class AggregateMenu extends PanelMenu.Button {
 | 
			
		||||
        this._nightLight = new imports.ui.status.nightLight.Indicator();
 | 
			
		||||
        this._thunderbolt = new imports.ui.status.thunderbolt.Indicator();
 | 
			
		||||
 | 
			
		||||
        this._indicators.add_child(this._thunderbolt.indicators);
 | 
			
		||||
        this._indicators.add_child(this._screencast.indicators);
 | 
			
		||||
        this._indicators.add_child(this._location.indicators);
 | 
			
		||||
        this._indicators.add_child(this._nightLight.indicators);
 | 
			
		||||
        this._indicators.add_child(this._thunderbolt);
 | 
			
		||||
        this._indicators.add_child(this._screencast);
 | 
			
		||||
        this._indicators.add_child(this._location);
 | 
			
		||||
        this._indicators.add_child(this._nightLight);
 | 
			
		||||
        if (this._network) {
 | 
			
		||||
            this._indicators.add_child(this._network.indicators);
 | 
			
		||||
            this._indicators.add_child(this._network);
 | 
			
		||||
        }
 | 
			
		||||
        if (this._bluetooth) {
 | 
			
		||||
            this._indicators.add_child(this._bluetooth.indicators);
 | 
			
		||||
            this._indicators.add_child(this._bluetooth);
 | 
			
		||||
        }
 | 
			
		||||
        this._indicators.add_child(this._remoteAccess.indicators);
 | 
			
		||||
        this._indicators.add_child(this._rfkill.indicators);
 | 
			
		||||
        this._indicators.add_child(this._volume.indicators);
 | 
			
		||||
        this._indicators.add_child(this._power.indicators);
 | 
			
		||||
        this._indicators.add_child(this._remoteAccess);
 | 
			
		||||
        this._indicators.add_child(this._rfkill);
 | 
			
		||||
        this._indicators.add_child(this._volume);
 | 
			
		||||
        this._indicators.add_child(this._power);
 | 
			
		||||
        this._indicators.add_child(PopupMenu.arrowIcon(St.Side.BOTTOM));
 | 
			
		||||
 | 
			
		||||
        this.menu.addMenuItem(this._volume.menu);
 | 
			
		||||
@@ -800,14 +797,10 @@ class Panel extends St.Widget {
 | 
			
		||||
        this.add_child(this._rightBox);
 | 
			
		||||
 | 
			
		||||
        this._leftCorner = new PanelCorner(St.Side.LEFT);
 | 
			
		||||
        this.add_child(this._leftCorner.actor);
 | 
			
		||||
        this.add_child(this._leftCorner);
 | 
			
		||||
 | 
			
		||||
        this._rightCorner = new PanelCorner(St.Side.RIGHT);
 | 
			
		||||
        this.add_child(this._rightCorner.actor);
 | 
			
		||||
 | 
			
		||||
        this.connect('button-press-event', this._onButtonPress.bind(this));
 | 
			
		||||
        this.connect('touch-event', this._onButtonPress.bind(this));
 | 
			
		||||
        this.connect('key-press-event', this._onKeyPress.bind(this));
 | 
			
		||||
        this.add_child(this._rightCorner);
 | 
			
		||||
 | 
			
		||||
        Main.overview.connect('showing', () => {
 | 
			
		||||
            this.add_style_pseudo_class('overview');
 | 
			
		||||
@@ -896,62 +889,65 @@ class Panel extends St.Widget {
 | 
			
		||||
 | 
			
		||||
        let cornerWidth, cornerHeight;
 | 
			
		||||
 | 
			
		||||
        [, cornerWidth] = this._leftCorner.actor.get_preferred_width(-1);
 | 
			
		||||
        [, cornerHeight] = this._leftCorner.actor.get_preferred_height(-1);
 | 
			
		||||
        [, cornerWidth] = this._leftCorner.get_preferred_width(-1);
 | 
			
		||||
        [, cornerHeight] = this._leftCorner.get_preferred_height(-1);
 | 
			
		||||
        childBox.x1 = 0;
 | 
			
		||||
        childBox.x2 = cornerWidth;
 | 
			
		||||
        childBox.y1 = allocHeight;
 | 
			
		||||
        childBox.y2 = allocHeight + cornerHeight;
 | 
			
		||||
        this._leftCorner.actor.allocate(childBox, flags);
 | 
			
		||||
        this._leftCorner.allocate(childBox, flags);
 | 
			
		||||
 | 
			
		||||
        [, cornerWidth] = this._rightCorner.actor.get_preferred_width(-1);
 | 
			
		||||
        [, cornerHeight] = this._rightCorner.actor.get_preferred_height(-1);
 | 
			
		||||
        [, cornerWidth] = this._rightCorner.get_preferred_width(-1);
 | 
			
		||||
        [, cornerHeight] = this._rightCorner.get_preferred_height(-1);
 | 
			
		||||
        childBox.x1 = allocWidth - cornerWidth;
 | 
			
		||||
        childBox.x2 = allocWidth;
 | 
			
		||||
        childBox.y1 = allocHeight;
 | 
			
		||||
        childBox.y2 = allocHeight + cornerHeight;
 | 
			
		||||
        this._rightCorner.actor.allocate(childBox, flags);
 | 
			
		||||
        this._rightCorner.allocate(childBox, flags);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _onButtonPress(actor, event) {
 | 
			
		||||
    _tryDragWindow(event) {
 | 
			
		||||
        if (Main.modalCount > 0)
 | 
			
		||||
            return Clutter.EVENT_PROPAGATE;
 | 
			
		||||
 | 
			
		||||
        if (event.get_source() != actor)
 | 
			
		||||
        if (event.source != this)
 | 
			
		||||
            return Clutter.EVENT_PROPAGATE;
 | 
			
		||||
 | 
			
		||||
        let type = event.type();
 | 
			
		||||
        let isPress = type == Clutter.EventType.BUTTON_PRESS;
 | 
			
		||||
        if (!isPress && type != Clutter.EventType.TOUCH_BEGIN)
 | 
			
		||||
            return Clutter.EVENT_PROPAGATE;
 | 
			
		||||
 | 
			
		||||
        let button = isPress ? event.get_button() : -1;
 | 
			
		||||
        if (isPress && button != 1)
 | 
			
		||||
            return Clutter.EVENT_PROPAGATE;
 | 
			
		||||
 | 
			
		||||
        let [stageX, stageY] = event.get_coords();
 | 
			
		||||
 | 
			
		||||
        let dragWindow = this._getDraggableWindowForPosition(stageX);
 | 
			
		||||
        let { x, y } = event;
 | 
			
		||||
        let dragWindow = this._getDraggableWindowForPosition(x);
 | 
			
		||||
 | 
			
		||||
        if (!dragWindow)
 | 
			
		||||
            return Clutter.EVENT_PROPAGATE;
 | 
			
		||||
 | 
			
		||||
        global.display.begin_grab_op(dragWindow,
 | 
			
		||||
                                     Meta.GrabOp.MOVING,
 | 
			
		||||
                                     false, /* pointer grab */
 | 
			
		||||
                                     true, /* frame action */
 | 
			
		||||
                                     button,
 | 
			
		||||
                                     event.get_state(),
 | 
			
		||||
                                     event.get_time(),
 | 
			
		||||
                                     stageX, stageY);
 | 
			
		||||
 | 
			
		||||
        return Clutter.EVENT_STOP;
 | 
			
		||||
        return global.display.begin_grab_op(
 | 
			
		||||
            dragWindow,
 | 
			
		||||
            Meta.GrabOp.MOVING,
 | 
			
		||||
            false, /* pointer grab */
 | 
			
		||||
            true, /* frame action */
 | 
			
		||||
            event.button || -1,
 | 
			
		||||
            event.modifier_state,
 | 
			
		||||
            event.time,
 | 
			
		||||
            x, y) ? Clutter.EVENT_STOP : Clutter.EVENT_PROPAGATE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _onKeyPress(actor, event) {
 | 
			
		||||
        let symbol = event.get_key_symbol();
 | 
			
		||||
    vfunc_button_press_event(buttonEvent) {
 | 
			
		||||
        if (buttonEvent.button != 1)
 | 
			
		||||
            return Clutter.EVENT_PROPAGATE;
 | 
			
		||||
 | 
			
		||||
        return this._tryDragWindow(buttonEvent);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    vfunc_touch_event(touchEvent) {
 | 
			
		||||
        if (touchEvent.type != Clutter.EventType.TOUCH_BEGIN)
 | 
			
		||||
            return Clutter.EVENT_PROPAGATE;
 | 
			
		||||
 | 
			
		||||
        return this._tryDragWindow(touchEvent);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    vfunc_key_press_event(keyEvent) {
 | 
			
		||||
        let symbol = keyEvent.keyval;
 | 
			
		||||
        if (symbol == Clutter.KEY_Escape) {
 | 
			
		||||
            global.display.focus_default_window(event.get_time());
 | 
			
		||||
            global.display.focus_default_window(keyEvent.time);
 | 
			
		||||
            return Clutter.EVENT_STOP;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@@ -1115,14 +1111,14 @@ class Panel extends St.Widget {
 | 
			
		||||
 | 
			
		||||
    _addStyleClassName(className) {
 | 
			
		||||
        this.add_style_class_name(className);
 | 
			
		||||
        this._rightCorner.actor.add_style_class_name(className);
 | 
			
		||||
        this._leftCorner.actor.add_style_class_name(className);
 | 
			
		||||
        this._rightCorner.add_style_class_name(className);
 | 
			
		||||
        this._leftCorner.add_style_class_name(className);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _removeStyleClassName(className) {
 | 
			
		||||
        this.remove_style_class_name(className);
 | 
			
		||||
        this._rightCorner.actor.remove_style_class_name(className);
 | 
			
		||||
        this._leftCorner.actor.remove_style_class_name(className);
 | 
			
		||||
        this._rightCorner.remove_style_class_name(className);
 | 
			
		||||
        this._leftCorner.remove_style_class_name(className);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _onMenuSet(indicator) {
 | 
			
		||||
 
 | 
			
		||||
@@ -2,7 +2,6 @@
 | 
			
		||||
/* exported Button, SystemIndicator */
 | 
			
		||||
 | 
			
		||||
const { Atk, Clutter, GObject, St } = imports.gi;
 | 
			
		||||
const Signals = imports.signals;
 | 
			
		||||
 | 
			
		||||
const Main = imports.ui.main;
 | 
			
		||||
const Params = imports.misc.params;
 | 
			
		||||
@@ -101,9 +100,6 @@ var Button = GObject.registerClass({
 | 
			
		||||
                      accessible_name: nameText ? nameText : "",
 | 
			
		||||
                      accessible_role: Atk.Role.MENU });
 | 
			
		||||
 | 
			
		||||
        this.connect('event', this._onEvent.bind(this));
 | 
			
		||||
        this.connect('notify::visible', this._onVisibilityChanged.bind(this));
 | 
			
		||||
 | 
			
		||||
        if (dontCreateMenu)
 | 
			
		||||
            this.menu = new PopupMenu.PopupDummyMenu(this);
 | 
			
		||||
        else
 | 
			
		||||
@@ -132,7 +128,7 @@ var Button = GObject.registerClass({
 | 
			
		||||
        this.emit('menu-set');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _onEvent(actor, event) {
 | 
			
		||||
    vfunc_event(event) {
 | 
			
		||||
        if (this.menu &&
 | 
			
		||||
            (event.type() == Clutter.EventType.TOUCH_BEGIN ||
 | 
			
		||||
             event.type() == Clutter.EventType.BUTTON_PRESS))
 | 
			
		||||
@@ -141,11 +137,10 @@ var Button = GObject.registerClass({
 | 
			
		||||
        return Clutter.EVENT_PROPAGATE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _onVisibilityChanged() {
 | 
			
		||||
        if (!this.menu)
 | 
			
		||||
            return;
 | 
			
		||||
    vfunc_hide() {
 | 
			
		||||
        super.vfunc_hide();
 | 
			
		||||
 | 
			
		||||
        if (!this.visible)
 | 
			
		||||
        if (this.menu)
 | 
			
		||||
            this.menu.close();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -200,24 +195,34 @@ var Button = GObject.registerClass({
 | 
			
		||||
 * of an icon and a menu section, which will be composed into the
 | 
			
		||||
 * aggregate menu.
 | 
			
		||||
 */
 | 
			
		||||
var SystemIndicator = class {
 | 
			
		||||
    constructor() {
 | 
			
		||||
        this.indicators = new St.BoxLayout({ style_class: 'panel-status-indicators-box',
 | 
			
		||||
                                             reactive: true });
 | 
			
		||||
        this.indicators.hide();
 | 
			
		||||
var SystemIndicator = GObject.registerClass({
 | 
			
		||||
    GTypeName: 'PanelMenu_SystemIndicator',
 | 
			
		||||
}, class SystemIndicator extends St.BoxLayout {
 | 
			
		||||
    _init() {
 | 
			
		||||
        super._init({
 | 
			
		||||
            style_class: 'panel-status-indicators-box',
 | 
			
		||||
            reactive: true,
 | 
			
		||||
            visible: false
 | 
			
		||||
        });
 | 
			
		||||
        this.menu = new PopupMenu.PopupMenuSection();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    get indicators() {
 | 
			
		||||
        let klass = this.constructor.name;
 | 
			
		||||
        let { stack } = new Error();
 | 
			
		||||
        log(`Usage of indicator.indicators is deprecated for ${klass}\n${stack}`);
 | 
			
		||||
        return this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _syncIndicatorsVisible() {
 | 
			
		||||
        this.indicators.visible = this.indicators.get_children().some(a => a.visible);
 | 
			
		||||
        this.visible = this.get_children().some(a => a.visible);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _addIndicator() {
 | 
			
		||||
        let icon = new St.Icon({ style_class: 'system-status-icon' });
 | 
			
		||||
        this.indicators.add_actor(icon);
 | 
			
		||||
        this.add_actor(icon);
 | 
			
		||||
        icon.connect('notify::visible', this._syncIndicatorsVisible.bind(this));
 | 
			
		||||
        this._syncIndicatorsVisible();
 | 
			
		||||
        return icon;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
Signals.addSignalMethods(SystemIndicator.prototype);
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
/* exported PointerA11yTimeout */
 | 
			
		||||
const { Clutter, GLib, GObject, Meta, St } = imports.gi;
 | 
			
		||||
const { Clutter, GObject, Meta, St } = imports.gi;
 | 
			
		||||
const Main = imports.ui.main;
 | 
			
		||||
const Cairo = imports.cairo;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -2,7 +2,6 @@
 | 
			
		||||
/* exported getPointerWatcher */
 | 
			
		||||
 | 
			
		||||
const { GLib, Meta } = imports.gi;
 | 
			
		||||
const Mainloop = imports.mainloop;
 | 
			
		||||
 | 
			
		||||
// We stop polling if the user is idle for more than this amount of time
 | 
			
		||||
var IDLE_TIME = 1000;
 | 
			
		||||
@@ -87,7 +86,7 @@ var PointerWatcher = class {
 | 
			
		||||
 | 
			
		||||
    _updateTimeout() {
 | 
			
		||||
        if (this._timeoutId) {
 | 
			
		||||
            Mainloop.source_remove(this._timeoutId);
 | 
			
		||||
            GLib.source_remove(this._timeoutId);
 | 
			
		||||
            this._timeoutId = 0;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@@ -98,8 +97,8 @@ var PointerWatcher = class {
 | 
			
		||||
        for (let i = 1; i < this._watches.length; i++)
 | 
			
		||||
            minInterval = Math.min(this._watches[i].interval, minInterval);
 | 
			
		||||
 | 
			
		||||
        this._timeoutId = Mainloop.timeout_add(minInterval,
 | 
			
		||||
                                               this._onTimeout.bind(this));
 | 
			
		||||
        this._timeoutId = GLib.timeout_add(GLib.PRIORITY_DEFAULT, minInterval,
 | 
			
		||||
            this._onTimeout.bind(this));
 | 
			
		||||
        GLib.Source.set_name_by_id(this._timeoutId, '[gnome-shell] this._onTimeout');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -3,7 +3,7 @@
 | 
			
		||||
            PopupImageMenuItem, PopupMenu, PopupDummyMenu, PopupSubMenu,
 | 
			
		||||
            PopupMenuSection, PopupSubMenuMenuItem, PopupMenuManager */
 | 
			
		||||
 | 
			
		||||
const { Atk, Clutter, Gio, GObject, Shell, St } = imports.gi;
 | 
			
		||||
const { Atk, Clutter, Gio, GObject, Graphene, Shell, St } = imports.gi;
 | 
			
		||||
const Signals = imports.signals;
 | 
			
		||||
 | 
			
		||||
const BoxPointer = imports.ui.boxpointer;
 | 
			
		||||
@@ -15,6 +15,7 @@ var Ornament = {
 | 
			
		||||
    NONE: 0,
 | 
			
		||||
    DOT: 1,
 | 
			
		||||
    CHECK: 2,
 | 
			
		||||
    HIDDEN: 3,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
function isPopupMenuItemVisible(child) {
 | 
			
		||||
@@ -57,11 +58,9 @@ var PopupBaseMenuItem = GObject.registerClass({
 | 
			
		||||
    Properties: {
 | 
			
		||||
        'active': GObject.ParamSpec.boolean('active', 'active', 'active',
 | 
			
		||||
                                            GObject.ParamFlags.READWRITE,
 | 
			
		||||
                                            GObject.TYPE_BOOLEAN,
 | 
			
		||||
                                            false),
 | 
			
		||||
        'sensitive': GObject.ParamSpec.boolean('sensitive', 'sensitive', 'sensitive',
 | 
			
		||||
                                               GObject.ParamFlags.READWRITE,
 | 
			
		||||
                                               GObject.TYPE_BOOLEAN,
 | 
			
		||||
                                               true),
 | 
			
		||||
    },
 | 
			
		||||
    Signals: {
 | 
			
		||||
@@ -69,12 +68,13 @@ var PopupBaseMenuItem = GObject.registerClass({
 | 
			
		||||
    }
 | 
			
		||||
}, class PopupBaseMenuItem extends St.BoxLayout {
 | 
			
		||||
    _init(params) {
 | 
			
		||||
        params = Params.parse (params, { reactive: true,
 | 
			
		||||
                                         activate: true,
 | 
			
		||||
                                         hover: true,
 | 
			
		||||
                                         style_class: null,
 | 
			
		||||
                                         can_focus: true
 | 
			
		||||
                                       });
 | 
			
		||||
        params = Params.parse (params, {
 | 
			
		||||
            reactive: true,
 | 
			
		||||
            activate: true,
 | 
			
		||||
            hover: true,
 | 
			
		||||
            style_class: null,
 | 
			
		||||
            can_focus: true,
 | 
			
		||||
        });
 | 
			
		||||
        super._init({ style_class: 'popup-menu-item',
 | 
			
		||||
                      reactive: params.reactive,
 | 
			
		||||
                      track_hover: params.reactive,
 | 
			
		||||
@@ -97,12 +97,6 @@ var PopupBaseMenuItem = GObject.registerClass({
 | 
			
		||||
        if (params.style_class)
 | 
			
		||||
            this.add_style_class_name(params.style_class);
 | 
			
		||||
 | 
			
		||||
        if (this._activatable) {
 | 
			
		||||
            this.connect('button-press-event', this._onButtonPressEvent.bind(this));
 | 
			
		||||
            this.connect('button-release-event', this._onButtonReleaseEvent.bind(this));
 | 
			
		||||
            this.connect('touch-event', this._onTouchEvent.bind(this));
 | 
			
		||||
            this.connect('key-press-event', this._onKeyPressEvent.bind(this));
 | 
			
		||||
        }
 | 
			
		||||
        if (params.reactive && params.hover)
 | 
			
		||||
            this.bind_property('hover', this, 'active', GObject.BindingFlags.SYNC_CREATE);
 | 
			
		||||
    }
 | 
			
		||||
@@ -124,32 +118,44 @@ var PopupBaseMenuItem = GObject.registerClass({
 | 
			
		||||
        this._parent = parent;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _onButtonPressEvent() {
 | 
			
		||||
    vfunc_button_press_event(buttonEvent) {
 | 
			
		||||
        if (!this._activatable)
 | 
			
		||||
            return super.vfunc_button_press_event(buttonEvent);
 | 
			
		||||
 | 
			
		||||
        // This is the CSS active state
 | 
			
		||||
        this.add_style_pseudo_class('active');
 | 
			
		||||
        return Clutter.EVENT_PROPAGATE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _onButtonReleaseEvent(actor, event) {
 | 
			
		||||
    vfunc_button_release_event(buttonEvent) {
 | 
			
		||||
        if (!this._activatable)
 | 
			
		||||
            return super.vfunc_button_release_event(buttonEvent);
 | 
			
		||||
 | 
			
		||||
        this.remove_style_pseudo_class('active');
 | 
			
		||||
        this.activate(event);
 | 
			
		||||
        this.activate(Clutter.get_current_event());
 | 
			
		||||
        return Clutter.EVENT_STOP;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _onTouchEvent(actor, event) {
 | 
			
		||||
        if (event.type() == Clutter.EventType.TOUCH_END) {
 | 
			
		||||
    vfunc_touch_event(touchEvent) {
 | 
			
		||||
        if (!this._activatable)
 | 
			
		||||
            return super.vfunc_touch_event(touchEvent);
 | 
			
		||||
 | 
			
		||||
        if (touchEvent.type == Clutter.EventType.TOUCH_END) {
 | 
			
		||||
            this.remove_style_pseudo_class('active');
 | 
			
		||||
            this.activate(event);
 | 
			
		||||
            this.activate(Clutter.get_current_event());
 | 
			
		||||
            return Clutter.EVENT_STOP;
 | 
			
		||||
        } else if (event.type() == Clutter.EventType.TOUCH_BEGIN) {
 | 
			
		||||
        } else if (touchEvent.type == Clutter.EventType.TOUCH_BEGIN) {
 | 
			
		||||
            // This is the CSS active state
 | 
			
		||||
            this.add_style_pseudo_class('active');
 | 
			
		||||
        }
 | 
			
		||||
        return Clutter.EVENT_PROPAGATE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _onKeyPressEvent(actor, event) {
 | 
			
		||||
        let state = event.get_state();
 | 
			
		||||
    vfunc_key_press_event(keyEvent) {
 | 
			
		||||
        if (!this._activatable)
 | 
			
		||||
            return super.vfunc_key_press_event(keyEvent);
 | 
			
		||||
 | 
			
		||||
        let state = keyEvent.modifier_state;
 | 
			
		||||
 | 
			
		||||
        // if user has a modifier down (except capslock and numlock)
 | 
			
		||||
        // then don't handle the key press here
 | 
			
		||||
@@ -160,9 +166,9 @@ var PopupBaseMenuItem = GObject.registerClass({
 | 
			
		||||
        if (state)
 | 
			
		||||
            return Clutter.EVENT_PROPAGATE;
 | 
			
		||||
 | 
			
		||||
        let symbol = event.get_key_symbol();
 | 
			
		||||
        let symbol = keyEvent.keyval;
 | 
			
		||||
        if (symbol == Clutter.KEY_space || symbol == Clutter.KEY_Return) {
 | 
			
		||||
            this.activate(event);
 | 
			
		||||
            this.activate(Clutter.get_current_event());
 | 
			
		||||
            return Clutter.EVENT_STOP;
 | 
			
		||||
        }
 | 
			
		||||
        return Clutter.EVENT_PROPAGATE;
 | 
			
		||||
@@ -249,10 +255,12 @@ var PopupBaseMenuItem = GObject.registerClass({
 | 
			
		||||
        } else if (ornament == Ornament.CHECK) {
 | 
			
		||||
            this._ornamentLabel.text = '\u2713';
 | 
			
		||||
            this.add_accessible_state(Atk.StateType.CHECKED);
 | 
			
		||||
        } else if (ornament == Ornament.NONE) {
 | 
			
		||||
        } else if (ornament == Ornament.NONE || ornament == Ornament.HIDDEN) {
 | 
			
		||||
            this._ornamentLabel.text = '';
 | 
			
		||||
            this.remove_accessible_state(Atk.StateType.CHECKED);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this._ornamentLabel.visible = ornament != Ornament.HIDDEN;
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
@@ -333,9 +341,10 @@ var PopupSwitchMenuItem = GObject.registerClass({
 | 
			
		||||
        this._statusBin = new St.Bin({ x_align: St.Align.END });
 | 
			
		||||
        this.add(this._statusBin, { expand: true, x_align: St.Align.END });
 | 
			
		||||
 | 
			
		||||
        this._statusLabel = new St.Label({ text: '',
 | 
			
		||||
                                           style_class: 'popup-status-menu-item'
 | 
			
		||||
                                         });
 | 
			
		||||
        this._statusLabel = new St.Label({
 | 
			
		||||
            text: '',
 | 
			
		||||
            style_class: 'popup-status-menu-item',
 | 
			
		||||
        });
 | 
			
		||||
        this._statusBin.child = this._switch;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -425,6 +434,7 @@ var PopupMenuBase = class {
 | 
			
		||||
            throw new TypeError(`Cannot instantiate abstract class ${this.constructor.name}`);
 | 
			
		||||
 | 
			
		||||
        this.sourceActor = sourceActor;
 | 
			
		||||
        this.focusActor = sourceActor;
 | 
			
		||||
        this._parent = null;
 | 
			
		||||
 | 
			
		||||
        if (styleClass !== undefined) {
 | 
			
		||||
@@ -549,7 +559,7 @@ var PopupMenuBase = class {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _connectItemSignals(menuItem) {
 | 
			
		||||
        menuItem._activeChangeId = menuItem.connect('notify::active', (menuItem) => {
 | 
			
		||||
        menuItem._activeChangeId = menuItem.connect('notify::active', menuItem => {
 | 
			
		||||
            let active = menuItem.active;
 | 
			
		||||
            if (active && this._activeMenuItem != menuItem) {
 | 
			
		||||
                if (this._activeMenuItem)
 | 
			
		||||
@@ -613,8 +623,8 @@ var PopupMenuBase = class {
 | 
			
		||||
        while (childBeforeIndex >= 0 && !isPopupMenuItemVisible(children[childBeforeIndex]))
 | 
			
		||||
            childBeforeIndex--;
 | 
			
		||||
 | 
			
		||||
        if (childBeforeIndex < 0
 | 
			
		||||
            || children[childBeforeIndex]._delegate instanceof PopupSeparatorMenuItem) {
 | 
			
		||||
        if (childBeforeIndex < 0 ||
 | 
			
		||||
            children[childBeforeIndex]._delegate instanceof PopupSeparatorMenuItem) {
 | 
			
		||||
            menuItem.actor.hide();
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
@@ -624,8 +634,8 @@ var PopupMenuBase = class {
 | 
			
		||||
        while (childAfterIndex < children.length && !isPopupMenuItemVisible(children[childAfterIndex]))
 | 
			
		||||
            childAfterIndex++;
 | 
			
		||||
 | 
			
		||||
        if (childAfterIndex >= children.length
 | 
			
		||||
            || children[childAfterIndex]._delegate instanceof PopupSeparatorMenuItem) {
 | 
			
		||||
        if (childAfterIndex >= children.length ||
 | 
			
		||||
            children[childAfterIndex]._delegate instanceof PopupSeparatorMenuItem) {
 | 
			
		||||
            menuItem.actor.hide();
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
@@ -718,10 +728,11 @@ var PopupMenuBase = class {
 | 
			
		||||
                this.disconnect(openStateChangeId);
 | 
			
		||||
                menuItem.disconnect(destroyId);
 | 
			
		||||
            });
 | 
			
		||||
        } else if (menuItem instanceof PopupBaseMenuItem)
 | 
			
		||||
        } else if (menuItem instanceof PopupBaseMenuItem) {
 | 
			
		||||
            this._connectItemSignals(menuItem);
 | 
			
		||||
        else
 | 
			
		||||
        } else {
 | 
			
		||||
            throw TypeError("Invalid argument to PopupMenuBase.addMenuItem()");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        menuItem._setParent(this);
 | 
			
		||||
 | 
			
		||||
@@ -1125,7 +1136,7 @@ class PopupSubMenuMenuItem extends PopupBaseMenuItem {
 | 
			
		||||
        this.add(expander, { expand: true });
 | 
			
		||||
 | 
			
		||||
        this._triangle = arrowIcon(St.Side.RIGHT);
 | 
			
		||||
        this._triangle.pivot_point = new Clutter.Point({ x: 0.5, y: 0.6 });
 | 
			
		||||
        this._triangle.pivot_point = new Graphene.Point({ x: 0.5, y: 0.6 });
 | 
			
		||||
 | 
			
		||||
        this._triangleBin = new St.Widget({ y_expand: true,
 | 
			
		||||
                                            y_align: Clutter.ActorAlign.CENTER });
 | 
			
		||||
@@ -1180,8 +1191,8 @@ class PopupSubMenuMenuItem extends PopupBaseMenuItem {
 | 
			
		||||
        return this.menu.isOpen;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _onKeyPressEvent(actor, event) {
 | 
			
		||||
        let symbol = event.get_key_symbol();
 | 
			
		||||
    vfunc_key_press_event(keyPressEvent) {
 | 
			
		||||
        let symbol = keyPressEvent.keyval;
 | 
			
		||||
 | 
			
		||||
        if (symbol == Clutter.KEY_Right) {
 | 
			
		||||
            this._setOpenState(true);
 | 
			
		||||
@@ -1192,14 +1203,14 @@ class PopupSubMenuMenuItem extends PopupBaseMenuItem {
 | 
			
		||||
            return Clutter.EVENT_STOP;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return super._onKeyPressEvent(actor, event);
 | 
			
		||||
        return super.vfunc_key_press_event(keyPressEvent);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    activate(_event) {
 | 
			
		||||
        this._setOpenState(true);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _onButtonReleaseEvent() {
 | 
			
		||||
    vfunc_button_release_event() {
 | 
			
		||||
        // Since we override the parent, we need to manage what the parent does
 | 
			
		||||
        // with the active style class
 | 
			
		||||
        this.remove_style_pseudo_class('active');
 | 
			
		||||
@@ -1207,8 +1218,8 @@ class PopupSubMenuMenuItem extends PopupBaseMenuItem {
 | 
			
		||||
        return Clutter.EVENT_PROPAGATE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _onTouchEvent(actor, event) {
 | 
			
		||||
        if (event.type() == Clutter.EventType.TOUCH_END) {
 | 
			
		||||
    vfunc_touch_event(touchEvent) {
 | 
			
		||||
        if (touchEvent.type == Clutter.EventType.TOUCH_END) {
 | 
			
		||||
            // Since we override the parent, we need to manage what the parent does
 | 
			
		||||
            // with the active style class
 | 
			
		||||
            this.remove_style_pseudo_class('active');
 | 
			
		||||
@@ -1296,18 +1307,20 @@ var PopupMenuManager = class {
 | 
			
		||||
        if (open) {
 | 
			
		||||
            if (this.activeMenu)
 | 
			
		||||
                this.activeMenu.close(BoxPointer.PopupAnimation.FADE);
 | 
			
		||||
            this._grabHelper.grab({ actor: menu.actor, focus: menu.sourceActor,
 | 
			
		||||
                                    onUngrab: isUser => {
 | 
			
		||||
                                        this._closeMenu(isUser, menu);
 | 
			
		||||
                                    } });
 | 
			
		||||
            this._grabHelper.grab({
 | 
			
		||||
                actor: menu.actor,
 | 
			
		||||
                focus: menu.focusActor,
 | 
			
		||||
                onUngrab: isUser => this._closeMenu(isUser, menu),
 | 
			
		||||
            });
 | 
			
		||||
        } else {
 | 
			
		||||
            this._grabHelper.ungrab({ actor: menu.actor });
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _changeMenu(newMenu) {
 | 
			
		||||
        newMenu.open(this.activeMenu ? BoxPointer.PopupAnimation.FADE
 | 
			
		||||
                                     : BoxPointer.PopupAnimation.FULL);
 | 
			
		||||
        newMenu.open(this.activeMenu
 | 
			
		||||
            ? BoxPointer.PopupAnimation.FADE
 | 
			
		||||
            : BoxPointer.PopupAnimation.FULL);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _onMenuSourceEnter(menu) {
 | 
			
		||||
 
 | 
			
		||||
@@ -34,6 +34,12 @@ var Ripples = class Ripples {
 | 
			
		||||
        this._ripple3.set_pivot_point(px, py);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    destroy() {
 | 
			
		||||
        this._ripple1.destroy();
 | 
			
		||||
        this._ripple2.destroy();
 | 
			
		||||
        this._ripple3.destroy();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _animRipple(ripple, delay, duration, startScale, startOpacity, finalScale) {
 | 
			
		||||
        // We draw a ripple by using a source image and animating it scaling
 | 
			
		||||
        // outwards and fading away. We want the ripples to move linearly
 | 
			
		||||
@@ -61,7 +67,7 @@ var Ripples = class Ripples {
 | 
			
		||||
            delay,
 | 
			
		||||
            duration,
 | 
			
		||||
            mode: Clutter.AnimationMode.LINEAR,
 | 
			
		||||
            onComplete: () => ripple.visible = false
 | 
			
		||||
            onComplete: () => (ripple.visible = false)
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -94,15 +94,17 @@ class RunDialog extends ModalDialog.ModalDialog {
 | 
			
		||||
 | 
			
		||||
        this._errorBox.hide();
 | 
			
		||||
 | 
			
		||||
        this.setButtons([{ action: this.close.bind(this),
 | 
			
		||||
                           label: _("Close"),
 | 
			
		||||
                           key: Clutter.Escape }]);
 | 
			
		||||
        this.setButtons([{
 | 
			
		||||
            action: this.close.bind(this),
 | 
			
		||||
            label: _("Close"),
 | 
			
		||||
            key: Clutter.Escape,
 | 
			
		||||
        }]);
 | 
			
		||||
 | 
			
		||||
        this._pathCompleter = new Gio.FilenameCompleter();
 | 
			
		||||
 | 
			
		||||
        this._history = new History.HistoryManager({ gsettingsKey: HISTORY_KEY,
 | 
			
		||||
                                                     entry: this._entryText });
 | 
			
		||||
        this._entryText.connect('activate', (o) => {
 | 
			
		||||
        this._entryText.connect('activate', o => {
 | 
			
		||||
            this.popModal();
 | 
			
		||||
            this._run(o.get_text(),
 | 
			
		||||
                      Clutter.get_current_event().get_state() & Clutter.ModifierType.CONTROL_MASK);
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,8 @@
 | 
			
		||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
 | 
			
		||||
 | 
			
		||||
const { AccountsService, Clutter, Cogl, Gio, GLib,
 | 
			
		||||
        GnomeDesktop, GObject, Meta, Shell, St } = imports.gi;
 | 
			
		||||
        GnomeDesktop, GObject, Graphene, Meta, Shell, St } = imports.gi;
 | 
			
		||||
const Cairo = imports.cairo;
 | 
			
		||||
const Mainloop = imports.mainloop;
 | 
			
		||||
const Signals = imports.signals;
 | 
			
		||||
 | 
			
		||||
const Background = imports.ui.background;
 | 
			
		||||
@@ -18,6 +17,8 @@ const MessageTray = imports.ui.messageTray;
 | 
			
		||||
const ShellDBus = imports.ui.shellDBus;
 | 
			
		||||
const SmartcardManager = imports.misc.smartcardManager;
 | 
			
		||||
 | 
			
		||||
const { adjustAnimationTime } = imports.ui.environment;
 | 
			
		||||
 | 
			
		||||
const SCREENSAVER_SCHEMA = 'org.gnome.desktop.screensaver';
 | 
			
		||||
const LOCK_ENABLED_KEY = 'lock-enabled';
 | 
			
		||||
const LOCK_DELAY_KEY = 'lock-delay';
 | 
			
		||||
@@ -47,21 +48,23 @@ var STANDARD_FADE_TIME = 10000;
 | 
			
		||||
var MANUAL_FADE_TIME = 300;
 | 
			
		||||
var CURTAIN_SLIDE_TIME = 300;
 | 
			
		||||
 | 
			
		||||
var Clock = class {
 | 
			
		||||
    constructor() {
 | 
			
		||||
        this.actor = new St.BoxLayout({ style_class: 'screen-shield-clock',
 | 
			
		||||
                                        vertical: true });
 | 
			
		||||
var Clock = GObject.registerClass(
 | 
			
		||||
class ScreenShieldClock extends St.BoxLayout {
 | 
			
		||||
    _init() {
 | 
			
		||||
        super._init({ style_class: 'screen-shield-clock', vertical: true });
 | 
			
		||||
 | 
			
		||||
        this._time = new St.Label({ style_class: 'screen-shield-clock-time' });
 | 
			
		||||
        this._date = new St.Label({ style_class: 'screen-shield-clock-date' });
 | 
			
		||||
 | 
			
		||||
        this.actor.add(this._time, { x_align: St.Align.MIDDLE });
 | 
			
		||||
        this.actor.add(this._date, { x_align: St.Align.MIDDLE });
 | 
			
		||||
        this.add(this._time, { x_align: St.Align.MIDDLE });
 | 
			
		||||
        this.add(this._date, { x_align: St.Align.MIDDLE });
 | 
			
		||||
 | 
			
		||||
        this._wallClock = new GnomeDesktop.WallClock({ time_only: true });
 | 
			
		||||
        this._wallClock.connect('notify::clock', this._updateClock.bind(this));
 | 
			
		||||
 | 
			
		||||
        this._updateClock();
 | 
			
		||||
 | 
			
		||||
        this.connect('destroy', this._onDestroy.bind(this));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _updateClock() {
 | 
			
		||||
@@ -74,17 +77,20 @@ var Clock = class {
 | 
			
		||||
        this._date.text = date.toLocaleFormat(dateFormat);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    destroy() {
 | 
			
		||||
        this.actor.destroy();
 | 
			
		||||
    _onDestroy() {
 | 
			
		||||
        this._wallClock.run_dispose();
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
var NotificationsBox = class {
 | 
			
		||||
    constructor() {
 | 
			
		||||
        this.actor = new St.BoxLayout({ vertical: true,
 | 
			
		||||
                                        name: 'screenShieldNotifications',
 | 
			
		||||
                                        style_class: 'screen-shield-notifications-container' });
 | 
			
		||||
var NotificationsBox = GObject.registerClass({
 | 
			
		||||
    Signals: { 'wake-up-screen': {} }
 | 
			
		||||
}, class NotificationsBox extends St.BoxLayout {
 | 
			
		||||
    _init() {
 | 
			
		||||
        super._init({
 | 
			
		||||
            vertical: true,
 | 
			
		||||
            name: 'screenShieldNotifications',
 | 
			
		||||
            style_class: 'screen-shield-notifications-container'
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        this._scrollView = new St.ScrollView({ x_fill: false, x_align: St.Align.START,
 | 
			
		||||
                                               hscrollbar_policy: St.PolicyType.NEVER });
 | 
			
		||||
@@ -92,7 +98,7 @@ var NotificationsBox = class {
 | 
			
		||||
                                                   style_class: 'screen-shield-notifications-container' });
 | 
			
		||||
        this._scrollView.add_actor(this._notificationBox);
 | 
			
		||||
 | 
			
		||||
        this.actor.add(this._scrollView, { x_fill: true, x_align: St.Align.START });
 | 
			
		||||
        this.add(this._scrollView, { x_fill: true, x_align: St.Align.START });
 | 
			
		||||
 | 
			
		||||
        this._sources = new Map();
 | 
			
		||||
        Main.messageTray.getSources().forEach(source => {
 | 
			
		||||
@@ -101,9 +107,11 @@ var NotificationsBox = class {
 | 
			
		||||
        this._updateVisibility();
 | 
			
		||||
 | 
			
		||||
        this._sourceAddedId = Main.messageTray.connect('source-added', this._sourceAdded.bind(this));
 | 
			
		||||
 | 
			
		||||
        this.connect('destroy', this._onDestroy.bind(this));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    destroy() {
 | 
			
		||||
    _onDestroy() {
 | 
			
		||||
        if (this._sourceAddedId) {
 | 
			
		||||
            Main.messageTray.disconnect(this._sourceAddedId);
 | 
			
		||||
            this._sourceAddedId = 0;
 | 
			
		||||
@@ -113,15 +121,13 @@ var NotificationsBox = class {
 | 
			
		||||
        for (let [source, obj] of items) {
 | 
			
		||||
            this._removeSource(source, obj);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this.actor.destroy();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _updateVisibility() {
 | 
			
		||||
        this._notificationBox.visible =
 | 
			
		||||
            this._notificationBox.get_children().some(a => a.visible);
 | 
			
		||||
 | 
			
		||||
        this.actor.visible = this._notificationBox.visible;
 | 
			
		||||
        this.visible = this._notificationBox.visible;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _makeNotificationCountText(count, isChat) {
 | 
			
		||||
@@ -174,8 +180,9 @@ var NotificationsBox = class {
 | 
			
		||||
 | 
			
		||||
            let body = '';
 | 
			
		||||
            if (n.bannerBodyText) {
 | 
			
		||||
                body = n.bannerBodyMarkup ? n.bannerBodyText
 | 
			
		||||
                                          : GLib.markup_escape_text(n.bannerBodyText, -1);
 | 
			
		||||
                body = n.bannerBodyMarkup
 | 
			
		||||
                    ? n.bannerBodyText
 | 
			
		||||
                    : GLib.markup_escape_text(n.bannerBodyText, -1);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            let label = new St.Label({ style_class: 'screen-shield-notification-count-text' });
 | 
			
		||||
@@ -222,14 +229,14 @@ var NotificationsBox = class {
 | 
			
		||||
        this._showSource(source, obj, obj.sourceBox);
 | 
			
		||||
        this._notificationBox.add(obj.sourceBox, { x_fill: false, x_align: St.Align.START });
 | 
			
		||||
 | 
			
		||||
        obj.sourceCountChangedId = source.connect('count-updated', source => {
 | 
			
		||||
        obj.sourceCountChangedId = source.connect('notify::count', source => {
 | 
			
		||||
            this._countChanged(source, obj);
 | 
			
		||||
        });
 | 
			
		||||
        obj.sourceTitleChangedId = source.connect('title-changed', source => {
 | 
			
		||||
        obj.sourceTitleChangedId = source.connect('notify::title', source => {
 | 
			
		||||
            this._titleChanged(source, obj);
 | 
			
		||||
        });
 | 
			
		||||
        obj.policyChangedId = source.policy.connect('policy-changed', (policy, key) => {
 | 
			
		||||
            if (key == 'show-in-lock-screen')
 | 
			
		||||
        obj.policyChangedId = source.policy.connect('notify', (policy, pspec) => {
 | 
			
		||||
            if (pspec.name == 'show-in-lock-screen')
 | 
			
		||||
                this._visibleChanged(source, obj);
 | 
			
		||||
            else
 | 
			
		||||
                this._detailedChanged(source, obj);
 | 
			
		||||
@@ -336,8 +343,7 @@ var NotificationsBox = class {
 | 
			
		||||
 | 
			
		||||
        this._sources.delete(source);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
Signals.addSignalMethods(NotificationsBox.prototype);
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
var Arrow = GObject.registerClass(
 | 
			
		||||
class ScreenShieldArrow extends St.Bin {
 | 
			
		||||
@@ -430,13 +436,14 @@ var ScreenShield = class {
 | 
			
		||||
        this.actor = Main.layoutManager.screenShieldGroup;
 | 
			
		||||
 | 
			
		||||
        this._lockScreenState = MessageTray.State.HIDDEN;
 | 
			
		||||
        this._lockScreenGroup = new St.Widget({ x_expand: true,
 | 
			
		||||
                                                y_expand: true,
 | 
			
		||||
                                                reactive: true,
 | 
			
		||||
                                                can_focus: true,
 | 
			
		||||
                                                name: 'lockScreenGroup',
 | 
			
		||||
                                                visible: false,
 | 
			
		||||
                                              });
 | 
			
		||||
        this._lockScreenGroup = new St.Widget({
 | 
			
		||||
            x_expand: true,
 | 
			
		||||
            y_expand: true,
 | 
			
		||||
            reactive: true,
 | 
			
		||||
            can_focus: true,
 | 
			
		||||
            name: 'lockScreenGroup',
 | 
			
		||||
            visible: false,
 | 
			
		||||
        });
 | 
			
		||||
        this._lockScreenGroup.connect('key-press-event',
 | 
			
		||||
                                      this._onLockScreenKeyPress.bind(this));
 | 
			
		||||
        this._lockScreenGroup.connect('scroll-event',
 | 
			
		||||
@@ -485,7 +492,7 @@ var ScreenShield = class {
 | 
			
		||||
        this._lockDialogGroup = new St.Widget({ x_expand: true,
 | 
			
		||||
                                                y_expand: true,
 | 
			
		||||
                                                reactive: true,
 | 
			
		||||
                                                pivot_point: new Clutter.Point({ x: 0.5, y: 0.5 }),
 | 
			
		||||
                                                pivot_point: new Graphene.Point({ x: 0.5, y: 0.5 }),
 | 
			
		||||
                                                name: 'lockDialogGroup' });
 | 
			
		||||
 | 
			
		||||
        this.actor.add_actor(this._lockDialogGroup);
 | 
			
		||||
@@ -556,11 +563,11 @@ var ScreenShield = class {
 | 
			
		||||
        this._longLightbox = new Lightbox.Lightbox(Main.uiGroup,
 | 
			
		||||
                                                   { inhibitEvents: true,
 | 
			
		||||
                                                     fadeFactor: 1 });
 | 
			
		||||
        this._longLightbox.connect('shown', this._onLongLightboxShown.bind(this));
 | 
			
		||||
        this._longLightbox.connect('notify::active', this._onLongLightbox.bind(this));
 | 
			
		||||
        this._shortLightbox = new Lightbox.Lightbox(Main.uiGroup,
 | 
			
		||||
                                                    { inhibitEvents: true,
 | 
			
		||||
                                                      fadeFactor: 1 });
 | 
			
		||||
        this._shortLightbox.connect('shown', this._onShortLightboxShown.bind(this));
 | 
			
		||||
        this._shortLightbox.connect('notify::active', this._onShortLightbox.bind(this));
 | 
			
		||||
 | 
			
		||||
        this.idleMonitor = Meta.IdleMonitor.get_core();
 | 
			
		||||
        this._cursorTracker = Meta.CursorTracker.get_for_display(global.display);
 | 
			
		||||
@@ -806,7 +813,7 @@ var ScreenShield = class {
 | 
			
		||||
 | 
			
		||||
        this._maybeCancelDialog();
 | 
			
		||||
 | 
			
		||||
        if (this._longLightbox.actor.visible) {
 | 
			
		||||
        if (this._longLightbox.visible) {
 | 
			
		||||
            // We're in the process of showing.
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
@@ -831,14 +838,16 @@ var ScreenShield = class {
 | 
			
		||||
 | 
			
		||||
        if (shouldLock) {
 | 
			
		||||
            let lockTimeout = Math.max(
 | 
			
		||||
                STANDARD_FADE_TIME,
 | 
			
		||||
                adjustAnimationTime(STANDARD_FADE_TIME),
 | 
			
		||||
                this._settings.get_uint(LOCK_DELAY_KEY) * 1000);
 | 
			
		||||
            this._lockTimeoutId = Mainloop.timeout_add(lockTimeout,
 | 
			
		||||
                                                       () => {
 | 
			
		||||
                                                           this._lockTimeoutId = 0;
 | 
			
		||||
                                                           this.lock(false);
 | 
			
		||||
                                                           return GLib.SOURCE_REMOVE;
 | 
			
		||||
                                                       });
 | 
			
		||||
            this._lockTimeoutId = GLib.timeout_add(
 | 
			
		||||
                GLib.PRIORITY_DEFAULT,
 | 
			
		||||
                lockTimeout,
 | 
			
		||||
                () => {
 | 
			
		||||
                    this._lockTimeoutId = 0;
 | 
			
		||||
                    this.lock(false);
 | 
			
		||||
                    return GLib.SOURCE_REMOVE;
 | 
			
		||||
                });
 | 
			
		||||
            GLib.Source.set_name_by_id(this._lockTimeoutId, '[gnome-shell] this.lock');
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@@ -846,8 +855,8 @@ var ScreenShield = class {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _activateFade(lightbox, time) {
 | 
			
		||||
        Main.uiGroup.set_child_above_sibling(lightbox.actor, null);
 | 
			
		||||
        lightbox.show(time);
 | 
			
		||||
        Main.uiGroup.set_child_above_sibling(lightbox, null);
 | 
			
		||||
        lightbox.lightOn(time);
 | 
			
		||||
 | 
			
		||||
        if (this._becameActiveId == 0)
 | 
			
		||||
            this._becameActiveId = this.idleMonitor.add_user_active_watch(this._onUserBecameActive.bind(this));
 | 
			
		||||
@@ -876,19 +885,21 @@ var ScreenShield = class {
 | 
			
		||||
        this._becameActiveId = 0;
 | 
			
		||||
 | 
			
		||||
        if (this._isActive || this._isLocked) {
 | 
			
		||||
            this._longLightbox.hide();
 | 
			
		||||
            this._shortLightbox.hide();
 | 
			
		||||
            this._longLightbox.lightOff();
 | 
			
		||||
            this._shortLightbox.lightOff();
 | 
			
		||||
        } else {
 | 
			
		||||
            this.deactivate(false);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _onLongLightboxShown() {
 | 
			
		||||
        this.activate(false);
 | 
			
		||||
    _onLongLightbox(lightBox) {
 | 
			
		||||
        if (lightBox.active)
 | 
			
		||||
            this.activate(false);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _onShortLightboxShown() {
 | 
			
		||||
        this._completeLockScreenShown();
 | 
			
		||||
    _onShortLightbox(lightBox) {
 | 
			
		||||
        if (lightBox.active)
 | 
			
		||||
            this._completeLockScreenShown();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    showDialog() {
 | 
			
		||||
@@ -913,8 +924,8 @@ var ScreenShield = class {
 | 
			
		||||
        this._lockScreenGroup.hide();
 | 
			
		||||
 | 
			
		||||
        if (this._dialog) {
 | 
			
		||||
            this._dialog.actor.grab_key_focus();
 | 
			
		||||
            this._dialog.actor.navigate_focus(null, St.DirectionType.TAB_FORWARD, false);
 | 
			
		||||
            this._dialog.grab_key_focus();
 | 
			
		||||
            this._dialog.navigate_focus(null, St.DirectionType.TAB_FORWARD, false);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -962,7 +973,6 @@ var ScreenShield = class {
 | 
			
		||||
 | 
			
		||||
            this._dialog = new constructor(this._lockDialogGroup);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            let time = global.get_current_time();
 | 
			
		||||
            if (!this._dialog.open(time, onPrimary)) {
 | 
			
		||||
                // This is kind of an impossible error: we're already modal
 | 
			
		||||
@@ -1028,7 +1038,7 @@ var ScreenShield = class {
 | 
			
		||||
        this._arrowActiveWatchId = 0;
 | 
			
		||||
 | 
			
		||||
        if (!this._arrowAnimationId) {
 | 
			
		||||
            this._arrowAnimationId = Mainloop.timeout_add(6000, this._animateArrows.bind(this));
 | 
			
		||||
            this._arrowAnimationId = GLib.timeout_add(GLib.PRIORITY_DEFAULT, 6000, this._animateArrows.bind(this));
 | 
			
		||||
            GLib.Source.set_name_by_id(this._arrowAnimationId, '[gnome-shell] this._animateArrows');
 | 
			
		||||
            this._animateArrows();
 | 
			
		||||
        }
 | 
			
		||||
@@ -1040,7 +1050,7 @@ var ScreenShield = class {
 | 
			
		||||
 | 
			
		||||
    _pauseArrowAnimation() {
 | 
			
		||||
        if (this._arrowAnimationId) {
 | 
			
		||||
            Mainloop.source_remove(this._arrowAnimationId);
 | 
			
		||||
            GLib.source_remove(this._arrowAnimationId);
 | 
			
		||||
            this._arrowAnimationId = 0;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@@ -1050,7 +1060,7 @@ var ScreenShield = class {
 | 
			
		||||
 | 
			
		||||
    _stopArrowAnimation() {
 | 
			
		||||
        if (this._arrowAnimationId) {
 | 
			
		||||
            Mainloop.source_remove(this._arrowAnimationId);
 | 
			
		||||
            GLib.source_remove(this._arrowAnimationId);
 | 
			
		||||
            this._arrowAnimationId = 0;
 | 
			
		||||
        }
 | 
			
		||||
        if (this._arrowActiveWatchId) {
 | 
			
		||||
@@ -1097,7 +1107,7 @@ var ScreenShield = class {
 | 
			
		||||
        if (params.fadeToBlack && params.animateFade) {
 | 
			
		||||
            // Take a beat
 | 
			
		||||
 | 
			
		||||
            let id = Mainloop.timeout_add(MANUAL_FADE_TIME, () => {
 | 
			
		||||
            let id = GLib.timeout_add(GLib.PRIORITY_DEFAULT, MANUAL_FADE_TIME, () => {
 | 
			
		||||
                this._activateFade(this._shortLightbox, MANUAL_FADE_TIME);
 | 
			
		||||
                return GLib.SOURCE_REMOVE;
 | 
			
		||||
            });
 | 
			
		||||
@@ -1128,16 +1138,20 @@ var ScreenShield = class {
 | 
			
		||||
                                                         vertical: true,
 | 
			
		||||
                                                         style_class: 'screen-shield-contents-box' });
 | 
			
		||||
        this._clock = new Clock();
 | 
			
		||||
        this._lockScreenContentsBox.add(this._clock.actor, { x_fill: true,
 | 
			
		||||
                                                             y_fill: true });
 | 
			
		||||
        this._lockScreenContentsBox.add(this._clock, {
 | 
			
		||||
            x_fill: true,
 | 
			
		||||
            y_fill: true
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        this._lockScreenContents.add_actor(this._lockScreenContentsBox);
 | 
			
		||||
 | 
			
		||||
        this._notificationsBox = new NotificationsBox();
 | 
			
		||||
        this._wakeUpScreenId = this._notificationsBox.connect('wake-up-screen', this._wakeUpScreen.bind(this));
 | 
			
		||||
        this._lockScreenContentsBox.add(this._notificationsBox.actor, { x_fill: true,
 | 
			
		||||
                                                                        y_fill: true,
 | 
			
		||||
                                                                        expand: true });
 | 
			
		||||
        this._lockScreenContentsBox.add(this._notificationsBox, {
 | 
			
		||||
            x_fill: true,
 | 
			
		||||
            y_fill: true,
 | 
			
		||||
            expand: true
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        this._hasLockScreen = true;
 | 
			
		||||
    }
 | 
			
		||||
@@ -1230,8 +1244,8 @@ var ScreenShield = class {
 | 
			
		||||
            this._dialog = null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this._longLightbox.hide();
 | 
			
		||||
        this._shortLightbox.hide();
 | 
			
		||||
        this._longLightbox.lightOff();
 | 
			
		||||
        this._shortLightbox.lightOff();
 | 
			
		||||
        this.actor.hide();
 | 
			
		||||
 | 
			
		||||
        if (this._becameActiveId != 0) {
 | 
			
		||||
@@ -1240,7 +1254,7 @@ var ScreenShield = class {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (this._lockTimeoutId != 0) {
 | 
			
		||||
            Mainloop.source_remove(this._lockTimeoutId);
 | 
			
		||||
            GLib.source_remove(this._lockTimeoutId);
 | 
			
		||||
            this._lockTimeoutId = 0;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,8 +1,7 @@
 | 
			
		||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
 | 
			
		||||
/* exported ScreenshotService */
 | 
			
		||||
 | 
			
		||||
const { Clutter, Gio, GLib, Meta, Shell, St } = imports.gi;
 | 
			
		||||
const Signals = imports.signals;
 | 
			
		||||
const { Clutter, Graphene, Gio, GObject, GLib, Meta, Shell, St } = imports.gi;
 | 
			
		||||
 | 
			
		||||
const GrabHelper = imports.ui.grabHelper;
 | 
			
		||||
const Lightbox = imports.ui.lightbox;
 | 
			
		||||
@@ -116,8 +115,8 @@ var ScreenshotService = class {
 | 
			
		||||
                try {
 | 
			
		||||
                    let [result, area, filenameUsed] =
 | 
			
		||||
                        screenshot.screenshot_area_finish(res);
 | 
			
		||||
                    this._onScreenshotComplete(result, area, filenameUsed,
 | 
			
		||||
                                               flash, invocation);
 | 
			
		||||
                    this._onScreenshotComplete(
 | 
			
		||||
                        result, area, filenameUsed, flash, invocation);
 | 
			
		||||
                } catch (e) {
 | 
			
		||||
                    invocation.return_gerror (e);
 | 
			
		||||
                }
 | 
			
		||||
@@ -134,8 +133,8 @@ var ScreenshotService = class {
 | 
			
		||||
                try {
 | 
			
		||||
                    let [result, area, filenameUsed] =
 | 
			
		||||
                        screenshot.screenshot_window_finish(res);
 | 
			
		||||
                    this._onScreenshotComplete(result, area, filenameUsed,
 | 
			
		||||
                                               flash, invocation);
 | 
			
		||||
                    this._onScreenshotComplete(
 | 
			
		||||
                        result, area, filenameUsed, flash, invocation);
 | 
			
		||||
                } catch (e) {
 | 
			
		||||
                    invocation.return_gerror (e);
 | 
			
		||||
                }
 | 
			
		||||
@@ -152,8 +151,8 @@ var ScreenshotService = class {
 | 
			
		||||
                try {
 | 
			
		||||
                    let [result, area, filenameUsed] =
 | 
			
		||||
                        screenshot.screenshot_finish(res);
 | 
			
		||||
                    this._onScreenshotComplete(result, area, filenameUsed,
 | 
			
		||||
                                               flash, invocation);
 | 
			
		||||
                    this._onScreenshotComplete(
 | 
			
		||||
                        result, area, filenameUsed, flash, invocation);
 | 
			
		||||
                } catch (e) {
 | 
			
		||||
                    invocation.return_gerror (e);
 | 
			
		||||
                }
 | 
			
		||||
@@ -198,7 +197,7 @@ var ScreenshotService = class {
 | 
			
		||||
                let screenshot = this._createScreenshot(invocation, false);
 | 
			
		||||
                if (!screenshot)
 | 
			
		||||
                    return;
 | 
			
		||||
                screenshot.pick_color(...coords, (o, res) => {
 | 
			
		||||
                screenshot.pick_color(coords.x, coords.y, (_o, res) => {
 | 
			
		||||
                    let [success_, color] = screenshot.pick_color_finish(res);
 | 
			
		||||
                    let { red, green, blue } = color;
 | 
			
		||||
                    let retval = GLib.Variant.new('(a{sv})', [{
 | 
			
		||||
@@ -219,62 +218,62 @@ var ScreenshotService = class {
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
var SelectArea = class {
 | 
			
		||||
    constructor() {
 | 
			
		||||
var SelectArea = GObject.registerClass({
 | 
			
		||||
    GTypeName: 'Screenshot_SelectArea',
 | 
			
		||||
    Signals: { 'finished': { param_types: [Meta.Rectangle.$gtype] } }
 | 
			
		||||
}, class SelectArea extends St.Widget {
 | 
			
		||||
    _init() {
 | 
			
		||||
        this._startX = -1;
 | 
			
		||||
        this._startY = -1;
 | 
			
		||||
        this._lastX = 0;
 | 
			
		||||
        this._lastY = 0;
 | 
			
		||||
        this._result = null;
 | 
			
		||||
 | 
			
		||||
        this._group = new St.Widget({ visible: false,
 | 
			
		||||
                                      reactive: true,
 | 
			
		||||
                                      x: 0,
 | 
			
		||||
                                      y: 0 });
 | 
			
		||||
        Main.uiGroup.add_actor(this._group);
 | 
			
		||||
        super._init({
 | 
			
		||||
            visible: false,
 | 
			
		||||
            reactive: true,
 | 
			
		||||
            x: 0,
 | 
			
		||||
            y: 0
 | 
			
		||||
        });
 | 
			
		||||
        Main.uiGroup.add_actor(this);
 | 
			
		||||
 | 
			
		||||
        this._grabHelper = new GrabHelper.GrabHelper(this._group);
 | 
			
		||||
 | 
			
		||||
        this._group.connect('button-press-event',
 | 
			
		||||
                            this._onButtonPress.bind(this));
 | 
			
		||||
        this._group.connect('button-release-event',
 | 
			
		||||
                            this._onButtonRelease.bind(this));
 | 
			
		||||
        this._group.connect('motion-event',
 | 
			
		||||
                            this._onMotionEvent.bind(this));
 | 
			
		||||
        this._grabHelper = new GrabHelper.GrabHelper(this);
 | 
			
		||||
 | 
			
		||||
        let constraint = new Clutter.BindConstraint({ source: global.stage,
 | 
			
		||||
                                                      coordinate: Clutter.BindCoordinate.ALL });
 | 
			
		||||
        this._group.add_constraint(constraint);
 | 
			
		||||
        this.add_constraint(constraint);
 | 
			
		||||
 | 
			
		||||
        this._rubberband = new St.Widget({
 | 
			
		||||
            style_class: 'select-area-rubberband',
 | 
			
		||||
            visible: false
 | 
			
		||||
        });
 | 
			
		||||
        this._group.add_actor(this._rubberband);
 | 
			
		||||
        this.add_actor(this._rubberband);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    show() {
 | 
			
		||||
        if (!this._grabHelper.grab({ actor: this._group,
 | 
			
		||||
    vfunc_show() {
 | 
			
		||||
        if (!this._grabHelper.grab({ actor: this,
 | 
			
		||||
                                     onUngrab: this._onUngrab.bind(this) }))
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        global.display.set_cursor(Meta.Cursor.CROSSHAIR);
 | 
			
		||||
        Main.uiGroup.set_child_above_sibling(this._group, null);
 | 
			
		||||
        this._group.visible = true;
 | 
			
		||||
        Main.uiGroup.set_child_above_sibling(this, null);
 | 
			
		||||
        super.vfunc_show();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _getGeometry() {
 | 
			
		||||
        return { x: Math.min(this._startX, this._lastX),
 | 
			
		||||
                 y: Math.min(this._startY, this._lastY),
 | 
			
		||||
                 width: Math.abs(this._startX - this._lastX) + 1,
 | 
			
		||||
                 height: Math.abs(this._startY - this._lastY) + 1 };
 | 
			
		||||
        return new Meta.Rectangle({
 | 
			
		||||
            x: Math.min(this._startX, this._lastX),
 | 
			
		||||
            y: Math.min(this._startY, this._lastY),
 | 
			
		||||
            width: Math.abs(this._startX - this._lastX) + 1,
 | 
			
		||||
            height: Math.abs(this._startY - this._lastY) + 1
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _onMotionEvent(actor, event) {
 | 
			
		||||
        if (this._startX == -1 || this._startY == -1)
 | 
			
		||||
    vfunc_motion_event(motionEvent) {
 | 
			
		||||
        if (this._startX == -1 || this._startY == -1 || this._result)
 | 
			
		||||
            return Clutter.EVENT_PROPAGATE;
 | 
			
		||||
 | 
			
		||||
        [this._lastX, this._lastY] = event.get_coords();
 | 
			
		||||
        [this._lastX, this._lastY] = [motionEvent.x, motionEvent.y];
 | 
			
		||||
        this._lastX = Math.floor(this._lastX);
 | 
			
		||||
        this._lastY = Math.floor(this._lastY);
 | 
			
		||||
        let geometry = this._getGeometry();
 | 
			
		||||
@@ -286,8 +285,8 @@ var SelectArea = class {
 | 
			
		||||
        return Clutter.EVENT_PROPAGATE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _onButtonPress(actor, event) {
 | 
			
		||||
        [this._startX, this._startY] = event.get_coords();
 | 
			
		||||
    vfunc_button_press_event(buttonEvent) {
 | 
			
		||||
        [this._startX, this._startY] = [buttonEvent.x, buttonEvent.y];
 | 
			
		||||
        this._startX = Math.floor(this._startX);
 | 
			
		||||
        this._startY = Math.floor(this._startY);
 | 
			
		||||
        this._rubberband.set_position(this._startX, this._startY);
 | 
			
		||||
@@ -295,9 +294,9 @@ var SelectArea = class {
 | 
			
		||||
        return Clutter.EVENT_PROPAGATE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _onButtonRelease() {
 | 
			
		||||
    vfunc_button_release_event() {
 | 
			
		||||
        this._result = this._getGeometry();
 | 
			
		||||
        this._group.ease({
 | 
			
		||||
        this.ease({
 | 
			
		||||
            opacity: 0,
 | 
			
		||||
            duration: 200,
 | 
			
		||||
            mode: Clutter.AnimationMode.EASE_OUT_QUAD,
 | 
			
		||||
@@ -311,43 +310,43 @@ var SelectArea = class {
 | 
			
		||||
        this.emit('finished', this._result);
 | 
			
		||||
 | 
			
		||||
        GLib.idle_add(GLib.PRIORITY_DEFAULT, () => {
 | 
			
		||||
            this._group.destroy();
 | 
			
		||||
            this.destroy();
 | 
			
		||||
            return GLib.SOURCE_REMOVE;
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
Signals.addSignalMethods(SelectArea.prototype);
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
var PickPixel = GObject.registerClass({
 | 
			
		||||
    GTypeName: 'Screenshot_PickPixel',
 | 
			
		||||
    Signals: { 'finished': { param_types: [Graphene.Point.$gtype] } }
 | 
			
		||||
}, class PickPixel extends St.Widget {
 | 
			
		||||
    _init() {
 | 
			
		||||
        super._init({ visible: false, reactive: true });
 | 
			
		||||
 | 
			
		||||
var PickPixel = class {
 | 
			
		||||
    constructor() {
 | 
			
		||||
        this._result = null;
 | 
			
		||||
 | 
			
		||||
        this._group = new St.Widget({ visible: false,
 | 
			
		||||
                                      reactive: true });
 | 
			
		||||
        Main.uiGroup.add_actor(this._group);
 | 
			
		||||
        Main.uiGroup.add_actor(this);
 | 
			
		||||
 | 
			
		||||
        this._grabHelper = new GrabHelper.GrabHelper(this._group);
 | 
			
		||||
 | 
			
		||||
        this._group.connect('button-release-event',
 | 
			
		||||
                            this._onButtonRelease.bind(this));
 | 
			
		||||
        this._grabHelper = new GrabHelper.GrabHelper(this);
 | 
			
		||||
 | 
			
		||||
        let constraint = new Clutter.BindConstraint({ source: global.stage,
 | 
			
		||||
                                                      coordinate: Clutter.BindCoordinate.ALL });
 | 
			
		||||
        this._group.add_constraint(constraint);
 | 
			
		||||
        this.add_constraint(constraint);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    show() {
 | 
			
		||||
        if (!this._grabHelper.grab({ actor: this._group,
 | 
			
		||||
    vfunc_show() {
 | 
			
		||||
        if (!this._grabHelper.grab({ actor: this,
 | 
			
		||||
                                     onUngrab: this._onUngrab.bind(this) }))
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        global.display.set_cursor(Meta.Cursor.CROSSHAIR);
 | 
			
		||||
        Main.uiGroup.set_child_above_sibling(this._group, null);
 | 
			
		||||
        this._group.visible = true;
 | 
			
		||||
        Main.uiGroup.set_child_above_sibling(this, null);
 | 
			
		||||
        super.vfunc_show();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _onButtonRelease(actor, event) {
 | 
			
		||||
        this._result = event.get_coords();
 | 
			
		||||
    vfunc_button_release_event(buttonEvent) {
 | 
			
		||||
        let { x, y } = buttonEvent;
 | 
			
		||||
        this._result = new Graphene.Point({ x, y });
 | 
			
		||||
        this._grabHelper.ungrab();
 | 
			
		||||
        return Clutter.EVENT_PROPAGATE;
 | 
			
		||||
    }
 | 
			
		||||
@@ -357,29 +356,29 @@ var PickPixel = class {
 | 
			
		||||
        this.emit('finished', this._result);
 | 
			
		||||
 | 
			
		||||
        GLib.idle_add(GLib.PRIORITY_DEFAULT, () => {
 | 
			
		||||
            this._group.destroy();
 | 
			
		||||
            this.destroy();
 | 
			
		||||
            return GLib.SOURCE_REMOVE;
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
Signals.addSignalMethods(PickPixel.prototype);
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
var FLASHSPOT_ANIMATION_OUT_TIME = 500; // milliseconds
 | 
			
		||||
 | 
			
		||||
var Flashspot = class extends Lightbox.Lightbox {
 | 
			
		||||
    constructor(area) {
 | 
			
		||||
        super(Main.uiGroup, { inhibitEvents: true,
 | 
			
		||||
                              width: area.width,
 | 
			
		||||
                              height: area.height });
 | 
			
		||||
 | 
			
		||||
        this.actor.style_class = 'flashspot';
 | 
			
		||||
        this.actor.set_position(area.x, area.y);
 | 
			
		||||
var Flashspot = GObject.registerClass(
 | 
			
		||||
class Flashspot extends Lightbox.Lightbox {
 | 
			
		||||
    _init(area) {
 | 
			
		||||
        super._init(Main.uiGroup, {
 | 
			
		||||
            inhibitEvents: true,
 | 
			
		||||
            width: area.width,
 | 
			
		||||
            height: area.height
 | 
			
		||||
        });
 | 
			
		||||
        this.style_class = 'flashspot';
 | 
			
		||||
        this.set_position(area.x, area.y);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fire(doneCallback) {
 | 
			
		||||
        this.actor.show();
 | 
			
		||||
        this.actor.opacity = 255;
 | 
			
		||||
        this.actor.ease({
 | 
			
		||||
        this.set({ visible: true, opacity: 255 });
 | 
			
		||||
        this.ease({
 | 
			
		||||
            opacity: 0,
 | 
			
		||||
            duration: FLASHSPOT_ANIMATION_OUT_TIME,
 | 
			
		||||
            mode: Clutter.AnimationMode.EASE_OUT_QUAD,
 | 
			
		||||
@@ -390,4 +389,4 @@ var Flashspot = class extends Lightbox.Lightbox {
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -4,7 +4,6 @@
 | 
			
		||||
            collectStatistics, runPerfScript */
 | 
			
		||||
 | 
			
		||||
const { Gio, GLib, Meta, Shell } = imports.gi;
 | 
			
		||||
const Mainloop = imports.mainloop;
 | 
			
		||||
 | 
			
		||||
const Main = imports.ui.main;
 | 
			
		||||
const Params = imports.misc.params;
 | 
			
		||||
@@ -41,7 +40,7 @@ const { loadInterfaceXML } = imports.misc.fileUtils;
 | 
			
		||||
 */
 | 
			
		||||
function sleep(milliseconds) {
 | 
			
		||||
    return new Promise(resolve => {
 | 
			
		||||
        let id = Mainloop.timeout_add(milliseconds, () => {
 | 
			
		||||
        let id = GLib.timeout_add(GLib.PRIORITY_DEFAULT, milliseconds, () => {
 | 
			
		||||
            resolve();
 | 
			
		||||
            return GLib.SOURCE_REMOVE;
 | 
			
		||||
        });
 | 
			
		||||
@@ -318,7 +317,7 @@ async function runPerfScript(scriptModule, outputFile) {
 | 
			
		||||
 | 
			
		||||
    for (let step of scriptModule.run()) {
 | 
			
		||||
        try {
 | 
			
		||||
            await step;
 | 
			
		||||
            await step; // eslint-disable-line no-await-in-loop
 | 
			
		||||
        } catch (err) {
 | 
			
		||||
            log(`Script failed: ${err}\n${err.stack}`);
 | 
			
		||||
            Meta.exit(Meta.ExitCode.ERROR);
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										244
									
								
								js/ui/search.js
									
									
									
									
									
								
							
							
						
						
									
										244
									
								
								js/ui/search.js
									
									
									
									
									
								
							@@ -1,7 +1,7 @@
 | 
			
		||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
 | 
			
		||||
/* exported SearchResultsView */
 | 
			
		||||
 | 
			
		||||
const { Clutter, Gio, GLib, GObject, Meta, Shell, St } = imports.gi;
 | 
			
		||||
const Signals = imports.signals;
 | 
			
		||||
 | 
			
		||||
const AppDisplay = imports.ui.appDisplay;
 | 
			
		||||
const IconGrid = imports.ui.iconGrid;
 | 
			
		||||
@@ -32,39 +32,47 @@ class MaxWidthBox extends St.BoxLayout {
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
var SearchResult = class {
 | 
			
		||||
    constructor(provider, metaInfo, resultsView) {
 | 
			
		||||
var SearchResult = GObject.registerClass(
 | 
			
		||||
class SearchResult extends St.Button {
 | 
			
		||||
    _init(provider, metaInfo, resultsView) {
 | 
			
		||||
        this.provider = provider;
 | 
			
		||||
        this.metaInfo = metaInfo;
 | 
			
		||||
        this._resultsView = resultsView;
 | 
			
		||||
 | 
			
		||||
        this.actor = new St.Button({ reactive: true,
 | 
			
		||||
                                     can_focus: true,
 | 
			
		||||
                                     track_hover: true,
 | 
			
		||||
                                     x_align: St.Align.START,
 | 
			
		||||
                                     y_fill: true });
 | 
			
		||||
        super._init({
 | 
			
		||||
            reactive: true,
 | 
			
		||||
            can_focus: true,
 | 
			
		||||
            track_hover: true,
 | 
			
		||||
            x_align: St.Align.START,
 | 
			
		||||
            y_fill: true
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
        this.actor._delegate = this;
 | 
			
		||||
        this.actor.connect('clicked', this.activate.bind(this));
 | 
			
		||||
    vfunc_clicked() {
 | 
			
		||||
        this.activate();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    activate() {
 | 
			
		||||
        this.emit('activate', this.metaInfo.id);
 | 
			
		||||
        this.provider.activateResult(this.metaInfo.id, this._resultsView.terms);
 | 
			
		||||
 | 
			
		||||
        if (this.metaInfo.clipboardText)
 | 
			
		||||
            St.Clipboard.get_default().set_text(
 | 
			
		||||
                St.ClipboardType.CLIPBOARD, this.metaInfo.clipboardText);
 | 
			
		||||
        Main.overview.toggle();
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
Signals.addSignalMethods(SearchResult.prototype);
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
var ListSearchResult = class extends SearchResult {
 | 
			
		||||
var ListSearchResult = GObject.registerClass(
 | 
			
		||||
class ListSearchResult extends SearchResult {
 | 
			
		||||
    _init(provider, metaInfo, resultsView) {
 | 
			
		||||
        super._init(provider, metaInfo, resultsView);
 | 
			
		||||
 | 
			
		||||
    constructor(provider, metaInfo, resultsView) {
 | 
			
		||||
        super(provider, metaInfo, resultsView);
 | 
			
		||||
 | 
			
		||||
        this.actor.style_class = 'list-search-result';
 | 
			
		||||
        this.actor.x_fill = true;
 | 
			
		||||
        this.style_class = 'list-search-result';
 | 
			
		||||
        this.x_fill = true;
 | 
			
		||||
 | 
			
		||||
        let content = new St.BoxLayout({ style_class: 'list-search-result-content',
 | 
			
		||||
                                         vertical: false });
 | 
			
		||||
        this.actor.set_child(content);
 | 
			
		||||
        this.set_child(content);
 | 
			
		||||
 | 
			
		||||
        this._termsChangedId = 0;
 | 
			
		||||
 | 
			
		||||
@@ -87,7 +95,7 @@ var ListSearchResult = class extends SearchResult {
 | 
			
		||||
                              x_align: St.Align.START,
 | 
			
		||||
                              y_align: St.Align.MIDDLE });
 | 
			
		||||
 | 
			
		||||
        this.actor.label_actor = title;
 | 
			
		||||
        this.label_actor = title;
 | 
			
		||||
 | 
			
		||||
        if (this.metaInfo['description']) {
 | 
			
		||||
            this._descriptionLabel = new St.Label({ style_class: 'list-search-result-description' });
 | 
			
		||||
@@ -103,7 +111,7 @@ var ListSearchResult = class extends SearchResult {
 | 
			
		||||
            this._highlightTerms();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this.actor.connect('destroy', this._onDestroy.bind(this));
 | 
			
		||||
        this.connect('destroy', this._onDestroy.bind(this));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    get ICON_SIZE() {
 | 
			
		||||
@@ -120,48 +128,56 @@ var ListSearchResult = class extends SearchResult {
 | 
			
		||||
            this._resultsView.disconnect(this._termsChangedId);
 | 
			
		||||
        this._termsChangedId = 0;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
var GridSearchResult = class extends SearchResult {
 | 
			
		||||
    constructor(provider, metaInfo, resultsView) {
 | 
			
		||||
        super(provider, metaInfo, resultsView);
 | 
			
		||||
var GridSearchResult = GObject.registerClass(
 | 
			
		||||
class GridSearchResult extends SearchResult {
 | 
			
		||||
    _init(provider, metaInfo, resultsView) {
 | 
			
		||||
        super._init(provider, metaInfo, resultsView);
 | 
			
		||||
 | 
			
		||||
        this.actor.style_class = 'grid-search-result';
 | 
			
		||||
        this.style_class = 'grid-search-result';
 | 
			
		||||
 | 
			
		||||
        this.icon = new IconGrid.BaseIcon(this.metaInfo['name'],
 | 
			
		||||
                                          { createIcon: this.metaInfo['createIcon'] });
 | 
			
		||||
        let content = new St.Bin({ child: this.icon });
 | 
			
		||||
        this.actor.set_child(content);
 | 
			
		||||
        this.actor.label_actor = this.icon.label;
 | 
			
		||||
        this.set_child(content);
 | 
			
		||||
        this.label_actor = this.icon.label;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
var SearchResultsBase = GObject.registerClass({
 | 
			
		||||
    GTypeFlags: GObject.TypeFlags.ABSTRACT,
 | 
			
		||||
    Properties: {
 | 
			
		||||
        'focus-child': GObject.ParamSpec.object(
 | 
			
		||||
            'focus-child', 'focus-child', 'focus-child',
 | 
			
		||||
            GObject.ParamFlags.READABLE,
 | 
			
		||||
            Clutter.Actor.$gtype),
 | 
			
		||||
    }
 | 
			
		||||
}, class SearchResultsBase extends St.BoxLayout {
 | 
			
		||||
    _init(provider, resultsView) {
 | 
			
		||||
        super._init({ style_class: 'search-section', vertical: true });
 | 
			
		||||
 | 
			
		||||
var SearchResultsBase = class {
 | 
			
		||||
    constructor(provider, resultsView) {
 | 
			
		||||
        this.provider = provider;
 | 
			
		||||
        this._resultsView = resultsView;
 | 
			
		||||
 | 
			
		||||
        this._terms = [];
 | 
			
		||||
 | 
			
		||||
        this.actor = new St.BoxLayout({ style_class: 'search-section',
 | 
			
		||||
                                        vertical: true });
 | 
			
		||||
        this._focusChild = null;
 | 
			
		||||
 | 
			
		||||
        this._resultDisplayBin = new St.Bin({ x_fill: true,
 | 
			
		||||
                                              y_fill: true });
 | 
			
		||||
        this.actor.add(this._resultDisplayBin, { expand: true });
 | 
			
		||||
        this.add(this._resultDisplayBin, { expand: true });
 | 
			
		||||
 | 
			
		||||
        let separator = new St.Widget({ style_class: 'search-section-separator' });
 | 
			
		||||
        this.actor.add(separator);
 | 
			
		||||
        this.add(separator);
 | 
			
		||||
 | 
			
		||||
        this._resultDisplays = {};
 | 
			
		||||
 | 
			
		||||
        this._clipboard = St.Clipboard.get_default();
 | 
			
		||||
 | 
			
		||||
        this._cancellable = new Gio.Cancellable();
 | 
			
		||||
 | 
			
		||||
        this.connect('destroy', this._onDestroy.bind(this));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    destroy() {
 | 
			
		||||
        this.actor.destroy();
 | 
			
		||||
    _onDestroy() {
 | 
			
		||||
        this._terms = [];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -175,21 +191,21 @@ var SearchResultsBase = class {
 | 
			
		||||
    clear() {
 | 
			
		||||
        this._cancellable.cancel();
 | 
			
		||||
        for (let resultId in this._resultDisplays)
 | 
			
		||||
            this._resultDisplays[resultId].actor.destroy();
 | 
			
		||||
            this._resultDisplays[resultId].destroy();
 | 
			
		||||
        this._resultDisplays = {};
 | 
			
		||||
        this._clearResultDisplay();
 | 
			
		||||
        this.actor.hide();
 | 
			
		||||
        this.hide();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    get focusChild() {
 | 
			
		||||
        return this._focusChild;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _keyFocusIn(actor) {
 | 
			
		||||
        this.emit('key-focus-in', actor);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _activateResult(result, id) {
 | 
			
		||||
        this.provider.activateResult(id, this._terms);
 | 
			
		||||
        if (result.metaInfo.clipboardText)
 | 
			
		||||
            this._clipboard.set_text(St.ClipboardType.CLIPBOARD, result.metaInfo.clipboardText);
 | 
			
		||||
        Main.overview.toggle();
 | 
			
		||||
        if (this._focusChild == actor)
 | 
			
		||||
            return;
 | 
			
		||||
        this._focusChild = actor;
 | 
			
		||||
        this.notify('focus-child');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _setMoreCount(_count) {
 | 
			
		||||
@@ -228,8 +244,7 @@ var SearchResultsBase = class {
 | 
			
		||||
                metasNeeded.forEach((resultId, i) => {
 | 
			
		||||
                    let meta = metas[i];
 | 
			
		||||
                    let display = this._createResultDisplay(meta);
 | 
			
		||||
                    display.connect('activate', this._activateResult.bind(this));
 | 
			
		||||
                    display.actor.connect('key-focus-in', this._keyFocusIn.bind(this));
 | 
			
		||||
                    display.connect('key-focus-in', this._keyFocusIn.bind(this));
 | 
			
		||||
                    this._resultDisplays[resultId] = display;
 | 
			
		||||
                });
 | 
			
		||||
                callback(true);
 | 
			
		||||
@@ -241,7 +256,7 @@ var SearchResultsBase = class {
 | 
			
		||||
        this._terms = terms;
 | 
			
		||||
        if (providerResults.length == 0) {
 | 
			
		||||
            this._clearResultDisplay();
 | 
			
		||||
            this.actor.hide();
 | 
			
		||||
            this.hide();
 | 
			
		||||
            callback();
 | 
			
		||||
        } else {
 | 
			
		||||
            let maxResults = this._getMaxDisplayedResults();
 | 
			
		||||
@@ -260,22 +275,23 @@ var SearchResultsBase = class {
 | 
			
		||||
                // To avoid CSS transitions causing flickering when
 | 
			
		||||
                // the first search result stays the same, we hide the
 | 
			
		||||
                // content while filling in the results.
 | 
			
		||||
                this.actor.hide();
 | 
			
		||||
                this.hide();
 | 
			
		||||
                this._clearResultDisplay();
 | 
			
		||||
                results.forEach(resultId => {
 | 
			
		||||
                    this._addItem(this._resultDisplays[resultId]);
 | 
			
		||||
                });
 | 
			
		||||
                this._setMoreCount(this.provider.canLaunchSearch ? moreCount : 0);
 | 
			
		||||
                this.actor.show();
 | 
			
		||||
                this.show();
 | 
			
		||||
                callback();
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
var ListSearchResults = class extends SearchResultsBase {
 | 
			
		||||
    constructor(provider, resultsView) {
 | 
			
		||||
        super(provider, resultsView);
 | 
			
		||||
var ListSearchResults = GObject.registerClass(
 | 
			
		||||
class ListSearchResults extends SearchResultsBase {
 | 
			
		||||
    _init(provider, resultsView) {
 | 
			
		||||
        super._init(provider, resultsView);
 | 
			
		||||
 | 
			
		||||
        this._container = new St.BoxLayout({ style_class: 'search-section-content' });
 | 
			
		||||
        this.providerInfo = new ProviderInfo(provider);
 | 
			
		||||
@@ -316,21 +332,21 @@ var ListSearchResults = class extends SearchResultsBase {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _addItem(display) {
 | 
			
		||||
        this._content.add_actor(display.actor);
 | 
			
		||||
        this._content.add_actor(display);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    getFirstResult() {
 | 
			
		||||
        if (this._content.get_n_children() > 0)
 | 
			
		||||
            return this._content.get_child_at_index(0)._delegate;
 | 
			
		||||
            return this._content.get_child_at_index(0);
 | 
			
		||||
        else
 | 
			
		||||
            return null;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
Signals.addSignalMethods(ListSearchResults.prototype);
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
var GridSearchResults = class extends SearchResultsBase {
 | 
			
		||||
    constructor(provider, resultsView) {
 | 
			
		||||
        super(provider, resultsView);
 | 
			
		||||
var GridSearchResults = GObject.registerClass(
 | 
			
		||||
class GridSearchResults extends SearchResultsBase {
 | 
			
		||||
    _init(provider, resultsView) {
 | 
			
		||||
        super._init(provider, resultsView);
 | 
			
		||||
 | 
			
		||||
        this._grid = new IconGrid.IconGrid({ rowLimit: MAX_GRID_SEARCH_RESULTS_ROWS,
 | 
			
		||||
                                             xAlign: St.Align.START });
 | 
			
		||||
@@ -341,14 +357,30 @@ var GridSearchResults = class extends SearchResultsBase {
 | 
			
		||||
        this._resultDisplayBin.set_child(this._bin);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _onDestroy() {
 | 
			
		||||
        if (this._updateSearchLater) {
 | 
			
		||||
            Meta.later_remove(this._updateSearchLater);
 | 
			
		||||
            delete this._updateSearchLater;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        super._onDestroy();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    updateSearch(...args) {
 | 
			
		||||
        if (this._notifyAllocationId)
 | 
			
		||||
            this.actor.disconnect(this._notifyAllocationId);
 | 
			
		||||
            this.disconnect(this._notifyAllocationId);
 | 
			
		||||
        if (this._updateSearchLater) {
 | 
			
		||||
            Meta.later_remove(this._updateSearchLater);
 | 
			
		||||
            delete this._updateSearchLater;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Make sure the maximum number of results calculated by
 | 
			
		||||
        // _getMaxDisplayedResults() is updated after width changes.
 | 
			
		||||
        this._notifyAllocationId = this.actor.connect('notify::allocation', () => {
 | 
			
		||||
            Meta.later_add(Meta.LaterType.BEFORE_REDRAW, () => {
 | 
			
		||||
        this._notifyAllocationId = this.connect('notify::allocation', () => {
 | 
			
		||||
            if (this._updateSearchLater)
 | 
			
		||||
                return;
 | 
			
		||||
            this._updateSearchLater = Meta.later_add(Meta.LaterType.BEFORE_REDRAW, () => {
 | 
			
		||||
                delete this._updateSearchLater;
 | 
			
		||||
                super.updateSearch(...args);
 | 
			
		||||
                return GLib.SOURCE_REMOVE;
 | 
			
		||||
            });
 | 
			
		||||
@@ -358,7 +390,7 @@ var GridSearchResults = class extends SearchResultsBase {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _getMaxDisplayedResults() {
 | 
			
		||||
        let width = this.actor.allocation.x2 - this.actor.allocation.x1;
 | 
			
		||||
        let width = this.allocation.get_width();
 | 
			
		||||
        if (width == 0)
 | 
			
		||||
            return -1;
 | 
			
		||||
 | 
			
		||||
@@ -381,17 +413,17 @@ var GridSearchResults = class extends SearchResultsBase {
 | 
			
		||||
 | 
			
		||||
    getFirstResult() {
 | 
			
		||||
        if (this._grid.visibleItemsCount() > 0)
 | 
			
		||||
            return this._grid.getItemAtIndex(0)._delegate;
 | 
			
		||||
            return this._grid.getItemAtIndex(0);
 | 
			
		||||
        else
 | 
			
		||||
            return null;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
Signals.addSignalMethods(GridSearchResults.prototype);
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
var SearchResults = class {
 | 
			
		||||
    constructor() {
 | 
			
		||||
        this.actor = new St.BoxLayout({ name: 'searchResults',
 | 
			
		||||
                                        vertical: true });
 | 
			
		||||
var SearchResultsView = GObject.registerClass({
 | 
			
		||||
    Signals: { 'terms-changed': {} }
 | 
			
		||||
}, class SearchResultsView extends St.BoxLayout {
 | 
			
		||||
    _init() {
 | 
			
		||||
        super._init({ name: 'searchResults', vertical: true });
 | 
			
		||||
 | 
			
		||||
        this._content = new MaxWidthBox({ name: 'searchResultsContent',
 | 
			
		||||
                                          vertical: true });
 | 
			
		||||
@@ -407,16 +439,18 @@ var SearchResults = class {
 | 
			
		||||
        action.connect('pan', this._onPan.bind(this));
 | 
			
		||||
        this._scrollView.add_action(action);
 | 
			
		||||
 | 
			
		||||
        this.actor.add(this._scrollView, { x_fill: true,
 | 
			
		||||
                                           y_fill: true,
 | 
			
		||||
                                           expand: true,
 | 
			
		||||
                                           x_align: St.Align.START,
 | 
			
		||||
                                           y_align: St.Align.START });
 | 
			
		||||
        this.add(this._scrollView, {
 | 
			
		||||
            x_fill: true,
 | 
			
		||||
            y_fill: true,
 | 
			
		||||
            expand: true,
 | 
			
		||||
            x_align: St.Align.START,
 | 
			
		||||
            y_align: St.Align.STAR
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        this._statusText = new St.Label({ style_class: 'search-statustext' });
 | 
			
		||||
        this._statusBin = new St.Bin({ x_align: St.Align.MIDDLE,
 | 
			
		||||
                                       y_align: St.Align.MIDDLE });
 | 
			
		||||
        this.actor.add(this._statusBin, { expand: true });
 | 
			
		||||
        this.add(this._statusBin, { expand: true });
 | 
			
		||||
        this._statusBin.add_actor(this._statusText);
 | 
			
		||||
 | 
			
		||||
        this._highlightDefault = false;
 | 
			
		||||
@@ -446,6 +480,10 @@ var SearchResults = class {
 | 
			
		||||
        this._reloadRemoteProviders();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    get terms() {
 | 
			
		||||
        return this._terms;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _reloadRemoteProviders() {
 | 
			
		||||
        let remoteProviders = this._providers.filter(p => p.isRemoteProvider);
 | 
			
		||||
        remoteProviders.forEach(provider => {
 | 
			
		||||
@@ -570,12 +608,12 @@ var SearchResults = class {
 | 
			
		||||
    _onPan(action) {
 | 
			
		||||
        let [dist_, dx_, dy] = action.get_motion_delta(0);
 | 
			
		||||
        let adjustment = this._scrollView.vscroll.adjustment;
 | 
			
		||||
        adjustment.value -= (dy / this.actor.height) * adjustment.page_size;
 | 
			
		||||
        adjustment.value -= (dy / this.height) * adjustment.page_size;
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _keyFocusIn(provider, actor) {
 | 
			
		||||
        Util.ensureActorVisibleInScrollView(this._scrollView, actor);
 | 
			
		||||
    _focusChildChanged(provider) {
 | 
			
		||||
        Util.ensureActorVisibleInScrollView(this._scrollView, provider.focusChild);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _ensureProviderDisplay(provider) {
 | 
			
		||||
@@ -588,9 +626,9 @@ var SearchResults = class {
 | 
			
		||||
        else
 | 
			
		||||
            providerDisplay = new GridSearchResults(provider, this);
 | 
			
		||||
 | 
			
		||||
        providerDisplay.connect('key-focus-in', this._keyFocusIn.bind(this));
 | 
			
		||||
        providerDisplay.actor.hide();
 | 
			
		||||
        this._content.add(providerDisplay.actor);
 | 
			
		||||
        providerDisplay.connect('notify::focus-child', this._focusChildChanged.bind(this));
 | 
			
		||||
        providerDisplay.hide();
 | 
			
		||||
        this._content.add(providerDisplay);
 | 
			
		||||
        provider.display = providerDisplay;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -608,7 +646,7 @@ var SearchResults = class {
 | 
			
		||||
            let provider = providers[i];
 | 
			
		||||
            let display = provider.display;
 | 
			
		||||
 | 
			
		||||
            if (!display.actor.visible)
 | 
			
		||||
            if (!display.visible)
 | 
			
		||||
                continue;
 | 
			
		||||
 | 
			
		||||
            let firstResult = display.getFirstResult();
 | 
			
		||||
@@ -683,21 +721,22 @@ var SearchResults = class {
 | 
			
		||||
            this._doSearch();
 | 
			
		||||
 | 
			
		||||
        if (this._defaultResult)
 | 
			
		||||
            this._defaultResult.actor.popup_menu();
 | 
			
		||||
            this._defaultResult.popup_menu();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    navigateFocus(direction) {
 | 
			
		||||
        let rtl = this.actor.get_text_direction() == Clutter.TextDirection.RTL;
 | 
			
		||||
        let rtl = this.get_text_direction() == Clutter.TextDirection.RTL;
 | 
			
		||||
        if (direction == St.DirectionType.TAB_BACKWARD ||
 | 
			
		||||
            direction == (rtl ? St.DirectionType.RIGHT
 | 
			
		||||
                              : St.DirectionType.LEFT) ||
 | 
			
		||||
            direction == (rtl
 | 
			
		||||
                ? St.DirectionType.RIGHT
 | 
			
		||||
                : St.DirectionType.LEFT) ||
 | 
			
		||||
            direction == St.DirectionType.UP) {
 | 
			
		||||
            this.actor.navigate_focus(null, direction, false);
 | 
			
		||||
            this.navigate_focus(null, direction, false);
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let from = this._defaultResult ? this._defaultResult.actor : null;
 | 
			
		||||
        this.actor.navigate_focus(from, direction, false);
 | 
			
		||||
        let from = this._defaultResult ? this._defaultResult : null;
 | 
			
		||||
        this.navigate_focus(from, direction, false);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _setSelected(result, selected) {
 | 
			
		||||
@@ -705,10 +744,10 @@ var SearchResults = class {
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        if (selected) {
 | 
			
		||||
            result.actor.add_style_pseudo_class('selected');
 | 
			
		||||
            Util.ensureActorVisibleInScrollView(this._scrollView, result.actor);
 | 
			
		||||
            result.add_style_pseudo_class('selected');
 | 
			
		||||
            Util.ensureActorVisibleInScrollView(this._scrollView, result);
 | 
			
		||||
        } else {
 | 
			
		||||
            result.actor.remove_style_pseudo_class('selected');
 | 
			
		||||
            result.remove_style_pseudo_class('selected');
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -721,8 +760,7 @@ var SearchResults = class {
 | 
			
		||||
 | 
			
		||||
        return description.replace(this._highlightRegex, '<b>$1</b>');
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
Signals.addSignalMethods(SearchResults.prototype);
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
var ProviderInfo = GObject.registerClass(
 | 
			
		||||
class ProviderInfo extends St.Button {
 | 
			
		||||
 
 | 
			
		||||
@@ -2,7 +2,6 @@
 | 
			
		||||
/* exported SessionMode, listModes */
 | 
			
		||||
 | 
			
		||||
const GLib = imports.gi.GLib;
 | 
			
		||||
const Mainloop = imports.mainloop;
 | 
			
		||||
const Signals = imports.signals;
 | 
			
		||||
 | 
			
		||||
const FileUtils = imports.misc.fileUtils;
 | 
			
		||||
@@ -93,11 +92,11 @@ const _modes = {
 | 
			
		||||
        isLocked: false,
 | 
			
		||||
        isPrimary: true,
 | 
			
		||||
        unlockDialog: imports.ui.unlockDialog.UnlockDialog,
 | 
			
		||||
        components: Config.HAVE_NETWORKMANAGER ?
 | 
			
		||||
                    ['networkAgent', 'polkitAgent', 'telepathyClient',
 | 
			
		||||
                     'keyring', 'autorunManager', 'automountManager'] :
 | 
			
		||||
                    ['polkitAgent', 'telepathyClient',
 | 
			
		||||
                     'keyring', 'autorunManager', 'automountManager'],
 | 
			
		||||
        components: Config.HAVE_NETWORKMANAGER
 | 
			
		||||
            ? ['networkAgent', 'polkitAgent', 'telepathyClient',
 | 
			
		||||
               'keyring', 'autorunManager', 'automountManager']
 | 
			
		||||
            : ['polkitAgent', 'telepathyClient',
 | 
			
		||||
               'keyring', 'autorunManager', 'automountManager'],
 | 
			
		||||
 | 
			
		||||
        panel: {
 | 
			
		||||
            left: ['activities', 'appMenu'],
 | 
			
		||||
@@ -112,7 +111,7 @@ function _loadMode(file, info) {
 | 
			
		||||
    let suffix = name.indexOf('.json');
 | 
			
		||||
    let modeName = suffix == -1 ? name : name.slice(name, suffix);
 | 
			
		||||
 | 
			
		||||
    if (_modes.hasOwnProperty(modeName))
 | 
			
		||||
    if (Object.prototype.hasOwnProperty.call(_modes, modeName))
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    let fileContent, success_, newMode;
 | 
			
		||||
@@ -141,15 +140,16 @@ function _loadModes() {
 | 
			
		||||
 | 
			
		||||
function listModes() {
 | 
			
		||||
    _loadModes();
 | 
			
		||||
    let id = Mainloop.idle_add(() => {
 | 
			
		||||
    let loop = new GLib.MainLoop(null, false);
 | 
			
		||||
    let id = GLib.idle_add(GLib.PRIORITY_DEFAULT, () => {
 | 
			
		||||
        let names = Object.getOwnPropertyNames(_modes);
 | 
			
		||||
        for (let i = 0; i < names.length; i++)
 | 
			
		||||
            if (_modes[names[i]].isPrimary)
 | 
			
		||||
                print(names[i]);
 | 
			
		||||
        Mainloop.quit('listModes');
 | 
			
		||||
        loop.quit();
 | 
			
		||||
    });
 | 
			
		||||
    GLib.Source.set_name_by_id(id, '[gnome-shell] listModes');
 | 
			
		||||
    Mainloop.run('listModes');
 | 
			
		||||
    loop.run();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var SessionMode = class {
 | 
			
		||||
 
 | 
			
		||||
@@ -151,9 +151,13 @@ var GnomeShell = class {
 | 
			
		||||
        let connection = this._dbusImpl.get_connection();
 | 
			
		||||
        let info = this._dbusImpl.get_info();
 | 
			
		||||
        let params = { 'device-id': GLib.Variant.new('u', device.get_device_id()),
 | 
			
		||||
                       'device-node': GLib.Variant.new('s', device.get_device_node()),
 | 
			
		||||
                       'timestamp': GLib.Variant.new('u', timestamp),
 | 
			
		||||
                       'action-mode': GLib.Variant.new('u', Main.actionMode) };
 | 
			
		||||
 | 
			
		||||
        let deviceNode = device.get_device_node();
 | 
			
		||||
        if (deviceNode)
 | 
			
		||||
            params['device-node'] = GLib.Variant.new('s', deviceNode);
 | 
			
		||||
 | 
			
		||||
        connection.emit_signal(destination,
 | 
			
		||||
                               this._dbusImpl.get_object_path(),
 | 
			
		||||
                               info ? info.name : null,
 | 
			
		||||
 
 | 
			
		||||
@@ -2,7 +2,6 @@
 | 
			
		||||
/* exported ShellMountOperation, GnomeShellMountOpHandler */
 | 
			
		||||
 | 
			
		||||
const { Clutter, Gio, GLib, GObject, Pango, Shell, St } = imports.gi;
 | 
			
		||||
const Signals = imports.signals;
 | 
			
		||||
 | 
			
		||||
const Animation = imports.ui.animation;
 | 
			
		||||
const CheckBox = imports.ui.checkBox;
 | 
			
		||||
@@ -26,9 +25,10 @@ function _setButtonsForChoices(dialog, choices) {
 | 
			
		||||
 | 
			
		||||
    for (let idx = 0; idx < choices.length; idx++) {
 | 
			
		||||
        let button = idx;
 | 
			
		||||
        buttons.unshift({ label: choices[idx],
 | 
			
		||||
                          action: () => dialog.emit('response', button)
 | 
			
		||||
                        });
 | 
			
		||||
        buttons.unshift({
 | 
			
		||||
            label: choices[idx],
 | 
			
		||||
            action: () => dialog.emit('response', button),
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    dialog.setButtons(buttons);
 | 
			
		||||
@@ -43,18 +43,22 @@ function _setLabelsForMessage(content, message) {
 | 
			
		||||
 | 
			
		||||
/* -------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
var ListItem = class {
 | 
			
		||||
    constructor(app) {
 | 
			
		||||
        this._app = app;
 | 
			
		||||
 | 
			
		||||
var ListItem = GObject.registerClass({
 | 
			
		||||
    GTypeName: 'ShellMountOperation_ListItem',
 | 
			
		||||
    Signals: { 'activate': {} }
 | 
			
		||||
}, class ListItem extends St.Button {
 | 
			
		||||
    _init(app) {
 | 
			
		||||
        let layout = new St.BoxLayout({ vertical: false });
 | 
			
		||||
        super._init({
 | 
			
		||||
            style_class: 'mount-dialog-app-list-item',
 | 
			
		||||
            can_focus: true,
 | 
			
		||||
            child: layout,
 | 
			
		||||
            reactive: true,
 | 
			
		||||
            x_align: St.Align.START,
 | 
			
		||||
            x_fill: true
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        this.actor = new St.Button({ style_class: 'mount-dialog-app-list-item',
 | 
			
		||||
                                     can_focus: true,
 | 
			
		||||
                                     child: layout,
 | 
			
		||||
                                     reactive: true,
 | 
			
		||||
                                     x_align: St.Align.START,
 | 
			
		||||
                                     x_fill: true });
 | 
			
		||||
        this._app = app;
 | 
			
		||||
 | 
			
		||||
        this._icon = this._app.create_icon_texture(LIST_ITEM_ICON_SIZE);
 | 
			
		||||
 | 
			
		||||
@@ -67,16 +71,13 @@ var ListItem = class {
 | 
			
		||||
        let labelBin = new St.Bin({ y_align: St.Align.MIDDLE,
 | 
			
		||||
                                    child: this._nameLabel });
 | 
			
		||||
        layout.add(labelBin);
 | 
			
		||||
 | 
			
		||||
        this.actor.connect('clicked', this._onClicked.bind(this));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _onClicked() {
 | 
			
		||||
    vfunc_clicked() {
 | 
			
		||||
        this.emit('activate');
 | 
			
		||||
        this._app.activate();
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
Signals.addSignalMethods(ListItem.prototype);
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
var ShellMountOperation = class {
 | 
			
		||||
    constructor(source, params) {
 | 
			
		||||
@@ -201,7 +202,7 @@ var ShellMountOperation = class {
 | 
			
		||||
    _onShowUnmountProgress(op, message, timeLeft, bytesLeft) {
 | 
			
		||||
        if (!this._notifier)
 | 
			
		||||
            this._notifier = new ShellUnmountNotifier();
 | 
			
		||||
            
 | 
			
		||||
 | 
			
		||||
        if (bytesLeft == 0)
 | 
			
		||||
            this._notifier.done(message);
 | 
			
		||||
        else
 | 
			
		||||
@@ -218,9 +219,10 @@ var ShellMountOperation = class {
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
var ShellUnmountNotifier = class extends MessageTray.Source {
 | 
			
		||||
    constructor() {
 | 
			
		||||
        super('', 'media-removable');
 | 
			
		||||
var ShellUnmountNotifier = GObject.registerClass(
 | 
			
		||||
class ShellUnmountNotifier extends MessageTray.Source {
 | 
			
		||||
    _init() {
 | 
			
		||||
        super._init('', 'media-removable');
 | 
			
		||||
 | 
			
		||||
        this._notification = null;
 | 
			
		||||
        Main.messageTray.add(this);
 | 
			
		||||
@@ -237,7 +239,7 @@ var ShellUnmountNotifier = class extends MessageTray.Source {
 | 
			
		||||
            this._notification.update(header, text);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this.notify(this._notification);
 | 
			
		||||
        this.showNotification(this._notification);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    done(message) {
 | 
			
		||||
@@ -250,10 +252,10 @@ var ShellUnmountNotifier = class extends MessageTray.Source {
 | 
			
		||||
            let notification = new MessageTray.Notification(this, message, null);
 | 
			
		||||
            notification.setTransient(true);
 | 
			
		||||
 | 
			
		||||
            this.notify(notification);
 | 
			
		||||
            this.showNotification(notification);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
var ShellMountQuestionDialog = GObject.registerClass({
 | 
			
		||||
    Signals: { 'response': { param_types: [GObject.TYPE_INT] } }
 | 
			
		||||
@@ -302,14 +304,14 @@ var ShellMountPasswordDialog = GObject.registerClass({
 | 
			
		||||
                                                  visible: false }));
 | 
			
		||||
 | 
			
		||||
            this._hiddenVolume = new CheckBox.CheckBox(_("Hidden Volume"));
 | 
			
		||||
            content.messageBox.add(this._hiddenVolume.actor);
 | 
			
		||||
            content.messageBox.add(this._hiddenVolume);
 | 
			
		||||
 | 
			
		||||
            this._systemVolume = new CheckBox.CheckBox(_("Windows System Volume"));
 | 
			
		||||
            content.messageBox.add(this._systemVolume.actor);
 | 
			
		||||
            content.messageBox.add(this._systemVolume);
 | 
			
		||||
 | 
			
		||||
            this._keyfilesCheckbox = new CheckBox.CheckBox(_("Uses Keyfiles"));
 | 
			
		||||
            this._keyfilesCheckbox.actor.connect("clicked", this._onKeyfilesCheckboxClicked.bind(this));
 | 
			
		||||
            content.messageBox.add(this._keyfilesCheckbox.actor);
 | 
			
		||||
            this._keyfilesCheckbox.connect("clicked", this._onKeyfilesCheckboxClicked.bind(this));
 | 
			
		||||
            content.messageBox.add(this._keyfilesCheckbox);
 | 
			
		||||
 | 
			
		||||
            this._keyfilesLabel.clutter_text.set_markup(
 | 
			
		||||
                /* Translators: %s is the Disks application */
 | 
			
		||||
@@ -359,7 +361,7 @@ var ShellMountPasswordDialog = GObject.registerClass({
 | 
			
		||||
        ShellEntry.addContextMenu(this._passwordEntry, { isPassword: true });
 | 
			
		||||
        this.setInitialKeyFocus(this._passwordEntry);
 | 
			
		||||
        this._workSpinner = new Animation.Spinner(WORK_SPINNER_ICON_SIZE, true);
 | 
			
		||||
        this._passwordEntry.secondary_icon = this._workSpinner.actor;
 | 
			
		||||
        this._passwordEntry.secondary_icon = this._workSpinner;
 | 
			
		||||
 | 
			
		||||
        if (rtl) {
 | 
			
		||||
            layout.attach(this._passwordEntry, 0, 1, 1, 1);
 | 
			
		||||
@@ -380,31 +382,33 @@ var ShellMountPasswordDialog = GObject.registerClass({
 | 
			
		||||
 | 
			
		||||
        if (flags & Gio.AskPasswordFlags.SAVING_SUPPORTED) {
 | 
			
		||||
            this._rememberChoice = new CheckBox.CheckBox(_("Remember Password"));
 | 
			
		||||
            this._rememberChoice.actor.checked =
 | 
			
		||||
            this._rememberChoice.checked =
 | 
			
		||||
                global.settings.get_boolean(REMEMBER_MOUNT_PASSWORD_KEY);
 | 
			
		||||
            content.messageBox.add(this._rememberChoice.actor);
 | 
			
		||||
            content.messageBox.add(this._rememberChoice);
 | 
			
		||||
        } else {
 | 
			
		||||
            this._rememberChoice = null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this._defaultButtons = [{ label: _("Cancel"),
 | 
			
		||||
                                  action: this._onCancelButton.bind(this),
 | 
			
		||||
                                  key: Clutter.Escape
 | 
			
		||||
                                },
 | 
			
		||||
                                { label: _("Unlock"),
 | 
			
		||||
                                  action: this._onUnlockButton.bind(this),
 | 
			
		||||
                                  default: true
 | 
			
		||||
                                }];
 | 
			
		||||
        this._defaultButtons = [{
 | 
			
		||||
            label: _("Cancel"),
 | 
			
		||||
            action: this._onCancelButton.bind(this),
 | 
			
		||||
            key: Clutter.Escape,
 | 
			
		||||
        }, {
 | 
			
		||||
            label: _("Unlock"),
 | 
			
		||||
            action: this._onUnlockButton.bind(this),
 | 
			
		||||
            default: true,
 | 
			
		||||
        }];
 | 
			
		||||
 | 
			
		||||
        this._usesKeyfilesButtons = [{ label: _("Cancel"),
 | 
			
		||||
                                       action: this._onCancelButton.bind(this),
 | 
			
		||||
                                       key: Clutter.Escape
 | 
			
		||||
                                     },
 | 
			
		||||
                                     { /* Translators: %s is the Disks application */
 | 
			
		||||
                                       label: _("Open %s").format(disksApp.get_name()),
 | 
			
		||||
                                       action: this._onOpenDisksButton.bind(this),
 | 
			
		||||
                                       default: true
 | 
			
		||||
                                     }];
 | 
			
		||||
        this._usesKeyfilesButtons = [{
 | 
			
		||||
            label: _("Cancel"),
 | 
			
		||||
            action: this._onCancelButton.bind(this),
 | 
			
		||||
            key: Clutter.Escape,
 | 
			
		||||
        }, {
 | 
			
		||||
            /* Translators: %s is the Disks application */
 | 
			
		||||
            label: _("Open %s").format(disksApp.get_name()),
 | 
			
		||||
            action: this._onOpenDisksButton.bind(this),
 | 
			
		||||
            default: true,
 | 
			
		||||
        }];
 | 
			
		||||
 | 
			
		||||
        this.setButtons(this._defaultButtons);
 | 
			
		||||
    }
 | 
			
		||||
@@ -436,22 +440,22 @@ var ShellMountPasswordDialog = GObject.registerClass({
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        global.settings.set_boolean(REMEMBER_MOUNT_PASSWORD_KEY,
 | 
			
		||||
            this._rememberChoice && this._rememberChoice.actor.checked);
 | 
			
		||||
            this._rememberChoice && this._rememberChoice.checked);
 | 
			
		||||
 | 
			
		||||
        this._workSpinner.play();
 | 
			
		||||
        this.emit('response', 1,
 | 
			
		||||
            this._passwordEntry.get_text(),
 | 
			
		||||
            this._rememberChoice &&
 | 
			
		||||
            this._rememberChoice.actor.checked,
 | 
			
		||||
            this._rememberChoice.checked,
 | 
			
		||||
            this._hiddenVolume &&
 | 
			
		||||
            this._hiddenVolume.actor.checked,
 | 
			
		||||
            this._hiddenVolume.checked,
 | 
			
		||||
            this._systemVolume &&
 | 
			
		||||
            this._systemVolume.actor.checked,
 | 
			
		||||
            this._systemVolume.checked,
 | 
			
		||||
            parseInt(pim));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _onKeyfilesCheckboxClicked() {
 | 
			
		||||
        let useKeyfiles = this._keyfilesCheckbox.actor.checked;
 | 
			
		||||
        let useKeyfiles = this._keyfilesCheckbox.checked;
 | 
			
		||||
        this._passwordEntry.reactive = !useKeyfiles;
 | 
			
		||||
        this._passwordEntry.can_focus = !useKeyfiles;
 | 
			
		||||
        this._passwordEntry.clutter_text.editable = !useKeyfiles;
 | 
			
		||||
@@ -460,8 +464,8 @@ var ShellMountPasswordDialog = GObject.registerClass({
 | 
			
		||||
        this._pimEntry.can_focus = !useKeyfiles;
 | 
			
		||||
        this._pimEntry.clutter_text.editable = !useKeyfiles;
 | 
			
		||||
        this._pimEntry.clutter_text.selectable = !useKeyfiles;
 | 
			
		||||
        this._rememberChoice.actor.reactive = !useKeyfiles;
 | 
			
		||||
        this._rememberChoice.actor.can_focus = !useKeyfiles;
 | 
			
		||||
        this._rememberChoice.reactive = !useKeyfiles;
 | 
			
		||||
        this._rememberChoice.can_focus = !useKeyfiles;
 | 
			
		||||
        this._keyfilesLabel.visible = useKeyfiles;
 | 
			
		||||
        this.setButtons(useKeyfiles ? this._usesKeyfilesButtons : this._defaultButtons);
 | 
			
		||||
    }
 | 
			
		||||
@@ -524,7 +528,7 @@ var ShellProcessesDialog = GObject.registerClass({
 | 
			
		||||
                return;
 | 
			
		||||
 | 
			
		||||
            let item = new ListItem(app);
 | 
			
		||||
            this._applicationList.add(item.actor, { x_fill: true });
 | 
			
		||||
            this._applicationList.add(item, { x_fill: true });
 | 
			
		||||
 | 
			
		||||
            item.connect('activate', () => {
 | 
			
		||||
                // use -1 to indicate Cancel
 | 
			
		||||
 
 | 
			
		||||
@@ -22,12 +22,7 @@ var Slider = GObject.registerClass({
 | 
			
		||||
            accessible_role: Atk.Role.SLIDER
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        this.connect('button-press-event', this._startDragging.bind(this));
 | 
			
		||||
        this.connect('touch-event', this._touchDragging.bind(this));
 | 
			
		||||
        this.connect('scroll-event', this._onScrollEvent.bind(this));
 | 
			
		||||
        this.connect('key-press-event', this.onKeyPressEvent.bind(this));
 | 
			
		||||
 | 
			
		||||
        this._releaseId = this._motionId = 0;
 | 
			
		||||
        this._releaseId = 0;
 | 
			
		||||
        this._dragging = false;
 | 
			
		||||
 | 
			
		||||
        this._customAccessible.connect('get-minimum-increment', this._getMinimumIncrement.bind(this));
 | 
			
		||||
@@ -62,8 +57,8 @@ var Slider = GObject.registerClass({
 | 
			
		||||
        cr.$dispose();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _startDragging(actor, event) {
 | 
			
		||||
        return this.startDragging(event);
 | 
			
		||||
    vfunc_button_press_event() {
 | 
			
		||||
        return this.startDragging(Clutter.get_current_event());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    startDragging(event) {
 | 
			
		||||
@@ -83,11 +78,6 @@ var Slider = GObject.registerClass({
 | 
			
		||||
        this._grabbedDevice = device;
 | 
			
		||||
        this._grabbedSequence = sequence;
 | 
			
		||||
 | 
			
		||||
        if (sequence == null) {
 | 
			
		||||
            this._releaseId = this.connect('button-release-event', this._endDragging.bind(this));
 | 
			
		||||
            this._motionId = this.connect('motion-event', this._motionEvent.bind(this));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // We need to emit 'drag-begin' before moving the handle to make
 | 
			
		||||
        // sure that no 'notify::value' signal is emitted before this one.
 | 
			
		||||
        this.emit('drag-begin');
 | 
			
		||||
@@ -100,10 +90,10 @@ var Slider = GObject.registerClass({
 | 
			
		||||
 | 
			
		||||
    _endDragging() {
 | 
			
		||||
        if (this._dragging) {
 | 
			
		||||
            if (this._releaseId)
 | 
			
		||||
            if (this._releaseId) {
 | 
			
		||||
                this.disconnect(this._releaseId);
 | 
			
		||||
            if (this._motionId)
 | 
			
		||||
                this.disconnect(this._motionId);
 | 
			
		||||
                this._releaseId = 0;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (this._grabbedSequence != null)
 | 
			
		||||
                this._grabbedDevice.sequence_ungrab(this._grabbedSequence);
 | 
			
		||||
@@ -119,7 +109,15 @@ var Slider = GObject.registerClass({
 | 
			
		||||
        return Clutter.EVENT_STOP;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _touchDragging(actor, event) {
 | 
			
		||||
    vfunc_button_release_event() {
 | 
			
		||||
        if (this._dragging && !this._grabbedSequence)
 | 
			
		||||
            return this._endDragging();
 | 
			
		||||
 | 
			
		||||
        return Clutter.EVENT_PROPAGATE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    vfunc_touch_event() {
 | 
			
		||||
        let event = Clutter.get_current_event();
 | 
			
		||||
        let device = event.get_device();
 | 
			
		||||
        let sequence = event.get_event_sequence();
 | 
			
		||||
 | 
			
		||||
@@ -127,9 +125,9 @@ var Slider = GObject.registerClass({
 | 
			
		||||
            event.type() == Clutter.EventType.TOUCH_BEGIN) {
 | 
			
		||||
            this.startDragging(event);
 | 
			
		||||
            return Clutter.EVENT_STOP;
 | 
			
		||||
        } else if (device.sequence_get_grabbed_actor(sequence) == actor) {
 | 
			
		||||
        } else if (device.sequence_get_grabbed_actor(sequence) == this) {
 | 
			
		||||
            if (event.type() == Clutter.EventType.TOUCH_UPDATE)
 | 
			
		||||
                return this._motionEvent(actor, event);
 | 
			
		||||
                return this._motionEvent(this, event);
 | 
			
		||||
            else if (event.type() == Clutter.EventType.TOUCH_END)
 | 
			
		||||
                return this._endDragging();
 | 
			
		||||
        }
 | 
			
		||||
@@ -160,8 +158,15 @@ var Slider = GObject.registerClass({
 | 
			
		||||
        return Clutter.EVENT_STOP;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _onScrollEvent(actor, event) {
 | 
			
		||||
        return this.scroll(event);
 | 
			
		||||
    vfunc_scroll_event() {
 | 
			
		||||
        return this.scroll(Clutter.get_current_event());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    vfunc_motion_event() {
 | 
			
		||||
        if (this._dragging && !this._grabbedSequence)
 | 
			
		||||
            return this._motionEvent(this, Clutter.get_current_event());
 | 
			
		||||
 | 
			
		||||
        return Clutter.EVENT_PROPAGATE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _motionEvent(actor, event) {
 | 
			
		||||
@@ -171,8 +176,8 @@ var Slider = GObject.registerClass({
 | 
			
		||||
        return Clutter.EVENT_STOP;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    onKeyPressEvent(actor, event) {
 | 
			
		||||
        let key = event.get_key_symbol();
 | 
			
		||||
    vfunc_key_press_event(keyPressEvent) {
 | 
			
		||||
        let key = keyPressEvent.keyval;
 | 
			
		||||
        if (key == Clutter.KEY_Right || key == Clutter.KEY_Left) {
 | 
			
		||||
            let delta = key == Clutter.KEY_Right ? 0.1 : -0.1;
 | 
			
		||||
            this.emit('drag-begin');
 | 
			
		||||
 
 | 
			
		||||
@@ -2,7 +2,6 @@
 | 
			
		||||
/* exported ATIndicator */
 | 
			
		||||
 | 
			
		||||
const { Gio, GLib, GObject, St } = imports.gi;
 | 
			
		||||
const Mainloop = imports.mainloop;
 | 
			
		||||
 | 
			
		||||
const PanelMenu = imports.ui.panelMenu;
 | 
			
		||||
const PopupMenu = imports.ui.popupMenu;
 | 
			
		||||
@@ -96,14 +95,14 @@ class ATIndicator extends PanelMenu.Button {
 | 
			
		||||
        if (this._syncMenuVisibilityIdle)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        this._syncMenuVisibilityIdle = Mainloop.idle_add(this._syncMenuVisibility.bind(this));
 | 
			
		||||
        this._syncMenuVisibilityIdle = GLib.idle_add(GLib.PRIORITY_DEFAULT, this._syncMenuVisibility.bind(this));
 | 
			
		||||
        GLib.Source.set_name_by_id(this._syncMenuVisibilityIdle, '[gnome-shell] this._syncMenuVisibility');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _buildItemExtended(string, initialValue, writable, onSet) {
 | 
			
		||||
        let widget = new PopupMenu.PopupSwitchMenuItem(string, initialValue);
 | 
			
		||||
        if (!writable)
 | 
			
		||||
            widget.actor.reactive = false;
 | 
			
		||||
            widget.reactive = false;
 | 
			
		||||
        else
 | 
			
		||||
            widget.connect('toggled', item => {
 | 
			
		||||
                onSet(item.state);
 | 
			
		||||
@@ -180,8 +179,8 @@ class ATIndicator extends PanelMenu.Button {
 | 
			
		||||
            settings.is_writable(KEY_TEXT_SCALING_FACTOR),
 | 
			
		||||
            enabled => {
 | 
			
		||||
                if (enabled)
 | 
			
		||||
                    settings.set_double(KEY_TEXT_SCALING_FACTOR,
 | 
			
		||||
                                        DPI_FACTOR_LARGE);
 | 
			
		||||
                    settings.set_double(
 | 
			
		||||
                        KEY_TEXT_SCALING_FACTOR, DPI_FACTOR_LARGE);
 | 
			
		||||
                else
 | 
			
		||||
                    settings.reset(KEY_TEXT_SCALING_FACTOR);
 | 
			
		||||
            });
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,7 @@
 | 
			
		||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
 | 
			
		||||
/* exported Indicator */
 | 
			
		||||
 | 
			
		||||
const { Gio, GnomeBluetooth } = imports.gi;
 | 
			
		||||
const { Gio, GnomeBluetooth, GObject } = imports.gi;
 | 
			
		||||
 | 
			
		||||
const Main = imports.ui.main;
 | 
			
		||||
const PanelMenu = imports.ui.panelMenu;
 | 
			
		||||
@@ -17,9 +17,11 @@ const RfkillManagerProxy = Gio.DBusProxy.makeProxyWrapper(RfkillManagerInterface
 | 
			
		||||
 | 
			
		||||
const HAD_BLUETOOTH_DEVICES_SETUP = 'had-bluetooth-devices-setup';
 | 
			
		||||
 | 
			
		||||
var Indicator = class extends PanelMenu.SystemIndicator {
 | 
			
		||||
    constructor() {
 | 
			
		||||
        super();
 | 
			
		||||
var Indicator = GObject.registerClass({
 | 
			
		||||
    GTypeName: 'Bluetooth_Indicator'
 | 
			
		||||
}, class Indicator extends PanelMenu.SystemIndicator {
 | 
			
		||||
    _init() {
 | 
			
		||||
        super._init();
 | 
			
		||||
 | 
			
		||||
        this._indicator = this._addIndicator();
 | 
			
		||||
        this._indicator.icon_name = 'bluetooth-active-symbolic';
 | 
			
		||||
@@ -133,4 +135,4 @@ var Indicator = class extends PanelMenu.SystemIndicator {
 | 
			
		||||
 | 
			
		||||
        this._toggleItem.label.text = this._proxy.BluetoothAirplaneMode ? _("Turn On") : _("Turn Off");
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -15,9 +15,11 @@ const OBJECT_PATH = '/org/gnome/SettingsDaemon/Power';
 | 
			
		||||
const BrightnessInterface = loadInterfaceXML('org.gnome.SettingsDaemon.Power.Screen');
 | 
			
		||||
const BrightnessProxy = Gio.DBusProxy.makeProxyWrapper(BrightnessInterface);
 | 
			
		||||
 | 
			
		||||
var Indicator = class extends PanelMenu.SystemIndicator {
 | 
			
		||||
    constructor() {
 | 
			
		||||
        super('display-brightness-symbolic');
 | 
			
		||||
var Indicator = GObject.registerClass({
 | 
			
		||||
    GTypeName: 'Brightness_Indicator'
 | 
			
		||||
}, class Indicator extends PanelMenu.SystemIndicator {
 | 
			
		||||
    _init() {
 | 
			
		||||
        super._init();
 | 
			
		||||
        this._proxy = new BrightnessProxy(Gio.DBus.session, BUS_NAME, OBJECT_PATH,
 | 
			
		||||
                                          (proxy, error) => {
 | 
			
		||||
                                              if (error) {
 | 
			
		||||
@@ -45,7 +47,7 @@ var Indicator = class extends PanelMenu.SystemIndicator {
 | 
			
		||||
            return this._slider.startDragging(event);
 | 
			
		||||
        });
 | 
			
		||||
        this._item.connect('key-press-event', (actor, event) => {
 | 
			
		||||
            return this._slider.onKeyPressEvent(actor, event);
 | 
			
		||||
            return this._slider.emit('key-press-event', event);
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
@@ -67,4 +69,4 @@ var Indicator = class extends PanelMenu.SystemIndicator {
 | 
			
		||||
        if (visible)
 | 
			
		||||
            this._changeSlider(this._proxy.Brightness / 100.0);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -13,8 +13,8 @@ const PanelMenu = imports.ui.panelMenu;
 | 
			
		||||
const SwitcherPopup = imports.ui.switcherPopup;
 | 
			
		||||
const Util = imports.misc.util;
 | 
			
		||||
 | 
			
		||||
const INPUT_SOURCE_TYPE_XKB = 'xkb';
 | 
			
		||||
const INPUT_SOURCE_TYPE_IBUS = 'ibus';
 | 
			
		||||
var INPUT_SOURCE_TYPE_XKB = 'xkb';
 | 
			
		||||
var INPUT_SOURCE_TYPE_IBUS = 'ibus';
 | 
			
		||||
 | 
			
		||||
var LayoutMenuItem = GObject.registerClass(
 | 
			
		||||
class LayoutMenuItem extends PopupMenu.PopupBaseMenuItem {
 | 
			
		||||
@@ -923,7 +923,7 @@ class InputSourceIndicator extends PanelMenu.Button {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _buildPropSection(properties) {
 | 
			
		||||
        this._propSeparator.actor.hide();
 | 
			
		||||
        this._propSeparator.hide();
 | 
			
		||||
        this._propSection.actor.hide();
 | 
			
		||||
        this._propSection.removeAll();
 | 
			
		||||
 | 
			
		||||
@@ -931,7 +931,7 @@ class InputSourceIndicator extends PanelMenu.Button {
 | 
			
		||||
 | 
			
		||||
        if (!this._propSection.isEmpty()) {
 | 
			
		||||
            this._propSection.actor.show();
 | 
			
		||||
            this._propSeparator.actor.show();
 | 
			
		||||
            this._propSeparator.show();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -976,8 +976,8 @@ class InputSourceIndicator extends PanelMenu.Button {
 | 
			
		||||
                item.prop = prop;
 | 
			
		||||
                radioGroup.push(item);
 | 
			
		||||
                item.radioGroup = radioGroup;
 | 
			
		||||
                item.setOrnament(prop.get_state() == IBus.PropState.CHECKED ?
 | 
			
		||||
                                 PopupMenu.Ornament.DOT : PopupMenu.Ornament.NONE);
 | 
			
		||||
                item.setOrnament(prop.get_state() == IBus.PropState.CHECKED
 | 
			
		||||
                    ? PopupMenu.Ornament.DOT : PopupMenu.Ornament.NONE);
 | 
			
		||||
                item.connect('activate', () => {
 | 
			
		||||
                    if (item.prop.get_state() == IBus.PropState.CHECKED)
 | 
			
		||||
                        return;
 | 
			
		||||
 
 | 
			
		||||
@@ -42,9 +42,11 @@ const GeoclueManager = Gio.DBusProxy.makeProxyWrapper(GeoclueIface);
 | 
			
		||||
 | 
			
		||||
var AgentIface = loadInterfaceXML('org.freedesktop.GeoClue2.Agent');
 | 
			
		||||
 | 
			
		||||
var Indicator = class extends PanelMenu.SystemIndicator {
 | 
			
		||||
    constructor() {
 | 
			
		||||
        super();
 | 
			
		||||
var Indicator = GObject.registerClass({
 | 
			
		||||
    GTypeName: 'Location_Indicator'
 | 
			
		||||
}, class Indicator extends PanelMenu.SystemIndicator {
 | 
			
		||||
    _init() {
 | 
			
		||||
        super._init();
 | 
			
		||||
 | 
			
		||||
        this._settings = new Gio.Settings({ schema_id: LOCATION_SCHEMA });
 | 
			
		||||
        this._settings.connect(`changed::${ENABLED}`,
 | 
			
		||||
@@ -168,8 +170,9 @@ var Indicator = class extends PanelMenu.SystemIndicator {
 | 
			
		||||
 | 
			
		||||
    _updateMenuLabels() {
 | 
			
		||||
        if (this._settings.get_boolean(ENABLED)) {
 | 
			
		||||
            this._item.label.text = this._indicator.visible ? _("Location In Use")
 | 
			
		||||
                                                            : _("Location Enabled");
 | 
			
		||||
            this._item.label.text = this._indicator.visible
 | 
			
		||||
                ? _("Location In Use")
 | 
			
		||||
                : _("Location Enabled");
 | 
			
		||||
            this._onOffAction.label.text = _("Disable");
 | 
			
		||||
        } else {
 | 
			
		||||
            this._item.label.text = _("Location Disabled");
 | 
			
		||||
@@ -221,7 +224,7 @@ var Indicator = class extends PanelMenu.SystemIndicator {
 | 
			
		||||
 | 
			
		||||
        this._permStoreProxy = proxy;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
function clamp(value, min, max) {
 | 
			
		||||
    return Math.max(min, Math.min(max, value));
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,6 @@
 | 
			
		||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
 | 
			
		||||
/* exported NMApplet */
 | 
			
		||||
const { Clutter, Gio, GLib, GObject, NM, St } = imports.gi;
 | 
			
		||||
const Mainloop = imports.mainloop;
 | 
			
		||||
const Signals = imports.signals;
 | 
			
		||||
 | 
			
		||||
const Animation = imports.ui.animation;
 | 
			
		||||
@@ -631,7 +630,6 @@ var NMWirelessDialogItem = GObject.registerClass({
 | 
			
		||||
                      can_focus: true,
 | 
			
		||||
                      reactive: true });
 | 
			
		||||
 | 
			
		||||
        this.connect('key-focus-in', () => this.emit('selected'));
 | 
			
		||||
        let action = new Clutter.ClickAction();
 | 
			
		||||
        action.connect('clicked', () => this.grab_key_focus());
 | 
			
		||||
        this.add_action(action);
 | 
			
		||||
@@ -660,6 +658,10 @@ var NMWirelessDialogItem = GObject.registerClass({
 | 
			
		||||
        this._sync();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    vfunc_key_focus_in() {
 | 
			
		||||
        this.emit('selected');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _sync() {
 | 
			
		||||
        this._signalIcon.icon_name = this._getSignalIcon();
 | 
			
		||||
    }
 | 
			
		||||
@@ -719,7 +721,7 @@ class NMWirelessDialog extends ModalDialog.ModalDialog {
 | 
			
		||||
        this._updateSensitivity();
 | 
			
		||||
        this._syncView();
 | 
			
		||||
 | 
			
		||||
        this._scanTimeoutId = Mainloop.timeout_add_seconds(15, this._onScanTimeout.bind(this));
 | 
			
		||||
        this._scanTimeoutId = GLib.timeout_add_seconds(GLib.PRIORITY_DEFAULT, 15, this._onScanTimeout.bind(this));
 | 
			
		||||
        GLib.Source.set_name_by_id(this._scanTimeoutId, '[gnome-shell] this._onScanTimeout');
 | 
			
		||||
        this._onScanTimeout();
 | 
			
		||||
 | 
			
		||||
@@ -757,7 +759,7 @@ class NMWirelessDialog extends ModalDialog.ModalDialog {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (this._scanTimeoutId) {
 | 
			
		||||
            Mainloop.source_remove(this._scanTimeoutId);
 | 
			
		||||
            GLib.source_remove(this._scanTimeoutId);
 | 
			
		||||
            this._scanTimeoutId = 0;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
@@ -861,7 +863,7 @@ class NMWirelessDialog extends ModalDialog.ModalDialog {
 | 
			
		||||
                                                 y_align: Clutter.ActorAlign.CENTER });
 | 
			
		||||
 | 
			
		||||
        this._noNetworksSpinner = new Animation.Spinner(16);
 | 
			
		||||
        this._noNetworksBox.add_actor(this._noNetworksSpinner.actor);
 | 
			
		||||
        this._noNetworksBox.add_actor(this._noNetworksSpinner);
 | 
			
		||||
        this._noNetworksBox.add_actor(new St.Label({ style_class: 'no-networks-label',
 | 
			
		||||
                                                     text: _("No Networks") }));
 | 
			
		||||
        this._stack.add_child(this._noNetworksBox);
 | 
			
		||||
@@ -874,7 +876,7 @@ class NMWirelessDialog extends ModalDialog.ModalDialog {
 | 
			
		||||
        this._airplaneHeadline = new St.Label({ style_class: 'nm-dialog-airplane-headline headline' });
 | 
			
		||||
        this._airplaneText = new St.Label({ style_class: 'nm-dialog-airplane-text' });
 | 
			
		||||
 | 
			
		||||
        let airplaneSubStack = new St.Widget({ layout_manager: new Clutter.BinLayout });
 | 
			
		||||
        let airplaneSubStack = new St.Widget({ layout_manager: new Clutter.BinLayout() });
 | 
			
		||||
        this._airplaneButton = new St.Button({ style_class: 'modal-dialog-button button' });
 | 
			
		||||
        this._airplaneButton.connect('clicked', () => {
 | 
			
		||||
            if (this._rfkill.airplaneMode)
 | 
			
		||||
@@ -910,8 +912,8 @@ class NMWirelessDialog extends ModalDialog.ModalDialog {
 | 
			
		||||
            this._client.activate_connection_async(connection, this._device, null, null, null);
 | 
			
		||||
        } else {
 | 
			
		||||
            let accessPoints = network.accessPoints;
 | 
			
		||||
            if ((accessPoints[0]._secType == NMAccessPointSecurity.WPA2_ENT)
 | 
			
		||||
                || (accessPoints[0]._secType == NMAccessPointSecurity.WPA_ENT)) {
 | 
			
		||||
            if ((accessPoints[0]._secType == NMAccessPointSecurity.WPA2_ENT) ||
 | 
			
		||||
                (accessPoints[0]._secType == NMAccessPointSecurity.WPA_ENT)) {
 | 
			
		||||
                // 802.1x-enabled APs require further configuration, so they're
 | 
			
		||||
                // handled in gnome-control-center
 | 
			
		||||
                Util.spawn(['gnome-control-center', 'wifi', 'connect-8021x-wifi',
 | 
			
		||||
@@ -1074,13 +1076,14 @@ class NMWirelessDialog extends ModalDialog.ModalDialog {
 | 
			
		||||
 | 
			
		||||
            this._resortItems();
 | 
			
		||||
        } else {
 | 
			
		||||
            network = { ssid: accessPoint.get_ssid(),
 | 
			
		||||
                        mode: accessPoint.mode,
 | 
			
		||||
                        security: this._getApSecurityType(accessPoint),
 | 
			
		||||
                        connections: [],
 | 
			
		||||
                        item: null,
 | 
			
		||||
                        accessPoints: [accessPoint]
 | 
			
		||||
                      };
 | 
			
		||||
            network = {
 | 
			
		||||
                ssid: accessPoint.get_ssid(),
 | 
			
		||||
                mode: accessPoint.mode,
 | 
			
		||||
                security: this._getApSecurityType(accessPoint),
 | 
			
		||||
                connections: [],
 | 
			
		||||
                item: null,
 | 
			
		||||
                accessPoints: [accessPoint],
 | 
			
		||||
            };
 | 
			
		||||
            network.ssidText = ssidToLabel(network.ssid);
 | 
			
		||||
            this._checkConnections(network, accessPoint);
 | 
			
		||||
 | 
			
		||||
@@ -1588,9 +1591,11 @@ var DeviceCategory = class extends PopupMenu.PopupMenuSection {
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
var NMApplet = class extends PanelMenu.SystemIndicator {
 | 
			
		||||
    constructor() {
 | 
			
		||||
        super();
 | 
			
		||||
var NMApplet = GObject.registerClass({
 | 
			
		||||
    GTypeName: 'Network_Indicator'
 | 
			
		||||
}, class Indicator extends PanelMenu.SystemIndicator {
 | 
			
		||||
    _init() {
 | 
			
		||||
        super._init();
 | 
			
		||||
 | 
			
		||||
        this._primaryIndicator = this._addIndicator();
 | 
			
		||||
        this._vpnIndicator = this._addIndicator();
 | 
			
		||||
@@ -1676,7 +1681,7 @@ var NMApplet = class extends PanelMenu.SystemIndicator {
 | 
			
		||||
                                                  'network-transmit-receive');
 | 
			
		||||
            this._source.policy = new MessageTray.NotificationApplicationPolicy('gnome-network-panel');
 | 
			
		||||
 | 
			
		||||
            this._source.connect('destroy', () => this._source = null);
 | 
			
		||||
            this._source.connect('destroy', () => (this._source = null));
 | 
			
		||||
            Main.messageTray.add(this._source);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
@@ -1706,7 +1711,7 @@ var NMApplet = class extends PanelMenu.SystemIndicator {
 | 
			
		||||
        this._notification.connect('destroy', () => {
 | 
			
		||||
            this._notification = null;
 | 
			
		||||
        });
 | 
			
		||||
        this._source.notify(this._notification);
 | 
			
		||||
        this._source.showNotification(this._notification);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _onActivationFailed(_device, _reason) {
 | 
			
		||||
@@ -1939,7 +1944,7 @@ var NMApplet = class extends PanelMenu.SystemIndicator {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _syncNMState() {
 | 
			
		||||
        this.indicators.visible = this._client.nm_running;
 | 
			
		||||
        this.visible = this._client.nm_running;
 | 
			
		||||
        this.menu.actor.visible = this._client.networking_enabled;
 | 
			
		||||
 | 
			
		||||
        this._updateIcon();
 | 
			
		||||
@@ -1976,7 +1981,6 @@ var NMApplet = class extends PanelMenu.SystemIndicator {
 | 
			
		||||
            // or we get to full connectivity through other means
 | 
			
		||||
        } else if (result == PortalHelperResult.COMPLETED) {
 | 
			
		||||
            this._closeConnectivityCheck(path);
 | 
			
		||||
            return;
 | 
			
		||||
        } else if (result == PortalHelperResult.RECHECK) {
 | 
			
		||||
            this._client.check_connectivity_async(null, (client, result) => {
 | 
			
		||||
                try {
 | 
			
		||||
@@ -2059,4 +2063,4 @@ var NMApplet = class extends PanelMenu.SystemIndicator {
 | 
			
		||||
        this._vpnIndicator.icon_name = this._vpnSection.getIndicatorIcon();
 | 
			
		||||
        this._vpnIndicator.visible = (this._vpnIndicator.icon_name != '');
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,7 @@
 | 
			
		||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
 | 
			
		||||
/* exported Indicator */
 | 
			
		||||
 | 
			
		||||
const Gio = imports.gi.Gio;
 | 
			
		||||
const { Gio, GObject } = imports.gi;
 | 
			
		||||
 | 
			
		||||
const Main = imports.ui.main;
 | 
			
		||||
const PanelMenu = imports.ui.panelMenu;
 | 
			
		||||
@@ -15,9 +15,11 @@ const OBJECT_PATH = '/org/gnome/SettingsDaemon/Color';
 | 
			
		||||
const ColorInterface = loadInterfaceXML('org.gnome.SettingsDaemon.Color');
 | 
			
		||||
const ColorProxy = Gio.DBusProxy.makeProxyWrapper(ColorInterface);
 | 
			
		||||
 | 
			
		||||
var Indicator = class extends PanelMenu.SystemIndicator {
 | 
			
		||||
    constructor() {
 | 
			
		||||
        super();
 | 
			
		||||
var Indicator = GObject.registerClass({
 | 
			
		||||
    GTypeName: 'NightLight_Indicator'
 | 
			
		||||
}, class Indicator extends PanelMenu.SystemIndicator {
 | 
			
		||||
    _init() {
 | 
			
		||||
        super._init();
 | 
			
		||||
 | 
			
		||||
        this._indicator = this._addIndicator();
 | 
			
		||||
        this._indicator.icon_name = 'night-light-symbolic';
 | 
			
		||||
@@ -58,10 +60,12 @@ var Indicator = class extends PanelMenu.SystemIndicator {
 | 
			
		||||
        let visible = this._proxy.NightLightActive;
 | 
			
		||||
        let disabled = this._proxy.DisabledUntilTomorrow;
 | 
			
		||||
 | 
			
		||||
        this._item.label.text = disabled ? _("Night Light Disabled")
 | 
			
		||||
                                         : _("Night Light On");
 | 
			
		||||
        this._disableItem.label.text = disabled ? _("Resume")
 | 
			
		||||
                                                : _("Disable Until Tomorrow");
 | 
			
		||||
        this._item.label.text = disabled
 | 
			
		||||
            ? _("Night Light Disabled")
 | 
			
		||||
            : _("Night Light On");
 | 
			
		||||
        this._disableItem.label.text = disabled
 | 
			
		||||
            ? _("Resume")
 | 
			
		||||
            : _("Disable Until Tomorrow");
 | 
			
		||||
        this._item.visible = this._indicator.visible = visible;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,7 @@
 | 
			
		||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
 | 
			
		||||
/* exported Indicator */
 | 
			
		||||
 | 
			
		||||
const { Clutter, Gio, St, UPowerGlib: UPower } = imports.gi;
 | 
			
		||||
const { Clutter, Gio, GObject, St, UPowerGlib: UPower } = imports.gi;
 | 
			
		||||
 | 
			
		||||
const Main = imports.ui.main;
 | 
			
		||||
const PanelMenu = imports.ui.panelMenu;
 | 
			
		||||
@@ -17,9 +17,11 @@ const PowerManagerProxy = Gio.DBusProxy.makeProxyWrapper(DisplayDeviceInterface)
 | 
			
		||||
 | 
			
		||||
const SHOW_BATTERY_PERCENTAGE       = 'show-battery-percentage';
 | 
			
		||||
 | 
			
		||||
var Indicator = class extends PanelMenu.SystemIndicator {
 | 
			
		||||
    constructor() {
 | 
			
		||||
        super();
 | 
			
		||||
var Indicator = GObject.registerClass({
 | 
			
		||||
    GTypeName: 'Power_Indicator'
 | 
			
		||||
}, class Indicator extends PanelMenu.SystemIndicator {
 | 
			
		||||
    _init() {
 | 
			
		||||
        super._init();
 | 
			
		||||
 | 
			
		||||
        this._desktopSettings = new Gio.Settings({ schema_id: 'org.gnome.desktop.interface' });
 | 
			
		||||
        this._desktopSettings.connect(`changed::${SHOW_BATTERY_PERCENTAGE}`,
 | 
			
		||||
@@ -28,8 +30,8 @@ var Indicator = class extends PanelMenu.SystemIndicator {
 | 
			
		||||
        this._indicator = this._addIndicator();
 | 
			
		||||
        this._percentageLabel = new St.Label({ y_expand: true,
 | 
			
		||||
                                               y_align: Clutter.ActorAlign.CENTER });
 | 
			
		||||
        this.indicators.add(this._percentageLabel, { expand: true, y_fill: true });
 | 
			
		||||
        this.indicators.add_style_class_name('power-status');
 | 
			
		||||
        this.add(this._percentageLabel, { expand: true, y_fill: true });
 | 
			
		||||
        this.add_style_class_name('power-status');
 | 
			
		||||
 | 
			
		||||
        this._proxy = new PowerManagerProxy(Gio.DBus.system, BUS_NAME, OBJECT_PATH,
 | 
			
		||||
                                            (proxy, error) => {
 | 
			
		||||
@@ -140,4 +142,4 @@ var Indicator = class extends PanelMenu.SystemIndicator {
 | 
			
		||||
        // The status label
 | 
			
		||||
        this._item.label.text = this._getStatus();
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -1,14 +1,16 @@
 | 
			
		||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
 | 
			
		||||
/* exported RemoteAccessApplet */
 | 
			
		||||
 | 
			
		||||
const Meta = imports.gi.Meta;
 | 
			
		||||
const { GObject, Meta } = imports.gi;
 | 
			
		||||
 | 
			
		||||
const PanelMenu = imports.ui.panelMenu;
 | 
			
		||||
const PopupMenu = imports.ui.popupMenu;
 | 
			
		||||
 | 
			
		||||
var RemoteAccessApplet = class extends PanelMenu.SystemIndicator {
 | 
			
		||||
    constructor() {
 | 
			
		||||
        super();
 | 
			
		||||
var RemoteAccessApplet = GObject.registerClass({
 | 
			
		||||
    GTypeName: 'RemoteAccess_Indicator'
 | 
			
		||||
}, class RemoteAccessApplet extends PanelMenu.SystemIndicator {
 | 
			
		||||
    _init() {
 | 
			
		||||
        super._init();
 | 
			
		||||
 | 
			
		||||
        let backend = Meta.get_backend();
 | 
			
		||||
        let controller = backend.get_remote_access_controller();
 | 
			
		||||
@@ -75,4 +77,4 @@ var RemoteAccessApplet = class extends PanelMenu.SystemIndicator {
 | 
			
		||||
            this._sync();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,7 @@
 | 
			
		||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
 | 
			
		||||
/* exported Indicator */
 | 
			
		||||
 | 
			
		||||
const Gio = imports.gi.Gio;
 | 
			
		||||
const { Gio, GObject } = imports.gi;
 | 
			
		||||
const Signals = imports.signals;
 | 
			
		||||
 | 
			
		||||
const Main = imports.ui.main;
 | 
			
		||||
@@ -61,9 +61,11 @@ function getRfkillManager() {
 | 
			
		||||
    return _manager;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var Indicator = class extends PanelMenu.SystemIndicator {
 | 
			
		||||
    constructor() {
 | 
			
		||||
        super();
 | 
			
		||||
var Indicator = GObject.registerClass({
 | 
			
		||||
    GTypeName: 'Rfkill_Indicator'
 | 
			
		||||
}, class Indicator extends PanelMenu.SystemIndicator {
 | 
			
		||||
    _init() {
 | 
			
		||||
        super._init();
 | 
			
		||||
 | 
			
		||||
        this._manager = getRfkillManager();
 | 
			
		||||
        this._manager.connect('airplane-mode-changed', this._sync.bind(this));
 | 
			
		||||
@@ -106,4 +108,4 @@ var Indicator = class extends PanelMenu.SystemIndicator {
 | 
			
		||||
        else
 | 
			
		||||
            this._offItem.label.text = _("Turn Off");
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -1,12 +1,16 @@
 | 
			
		||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
 | 
			
		||||
/* exported Indicator */
 | 
			
		||||
 | 
			
		||||
const GObject = imports.gi.GObject;
 | 
			
		||||
 | 
			
		||||
const Main = imports.ui.main;
 | 
			
		||||
const PanelMenu = imports.ui.panelMenu;
 | 
			
		||||
 | 
			
		||||
var Indicator = class extends PanelMenu.SystemIndicator {
 | 
			
		||||
    constructor() {
 | 
			
		||||
        super();
 | 
			
		||||
var Indicator = GObject.registerClass({
 | 
			
		||||
    GTypeName: 'Screencast_Indicator'
 | 
			
		||||
}, class Indicator extends PanelMenu.SystemIndicator {
 | 
			
		||||
    _init() {
 | 
			
		||||
        super._init();
 | 
			
		||||
 | 
			
		||||
        this._indicator = this._addIndicator();
 | 
			
		||||
        this._indicator.icon_name = 'media-record-symbolic';
 | 
			
		||||
@@ -19,4 +23,4 @@ var Indicator = class extends PanelMenu.SystemIndicator {
 | 
			
		||||
    _sync() {
 | 
			
		||||
        this._indicator.visible = Main.screencastService.isRecording;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -10,8 +10,10 @@ const PanelMenu = imports.ui.panelMenu;
 | 
			
		||||
const PopupMenu = imports.ui.popupMenu;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
var AltSwitcher = class {
 | 
			
		||||
    constructor(standard, alternate) {
 | 
			
		||||
var AltSwitcher = GObject.registerClass(
 | 
			
		||||
class AltSwitcher extends St.Bin {
 | 
			
		||||
    _init(standard, alternate) {
 | 
			
		||||
        super._init();
 | 
			
		||||
        this._standard = standard;
 | 
			
		||||
        this._standard.connect('notify::visible', this._sync.bind(this));
 | 
			
		||||
        if (this._standard instanceof St.Button)
 | 
			
		||||
@@ -31,9 +33,17 @@ var AltSwitcher = class {
 | 
			
		||||
        this._clickAction = new Clutter.ClickAction();
 | 
			
		||||
        this._clickAction.connect('long-press', this._onLongPress.bind(this));
 | 
			
		||||
 | 
			
		||||
        this.actor = new St.Bin();
 | 
			
		||||
        this.actor.connect('destroy', this._onDestroy.bind(this));
 | 
			
		||||
        this.actor.connect('notify::mapped', () => this._flipped = false);
 | 
			
		||||
        this.connect('destroy', this._onDestroy.bind(this));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    vfunc_map() {
 | 
			
		||||
        super.vfunc_map();
 | 
			
		||||
        this._flipped = false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    vfunc_unmap() {
 | 
			
		||||
        super.vfunc_unmap();
 | 
			
		||||
        this._flipped = false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _sync() {
 | 
			
		||||
@@ -51,11 +61,11 @@ var AltSwitcher = class {
 | 
			
		||||
        } else if (this._alternate.visible) {
 | 
			
		||||
            childToShow = this._alternate;
 | 
			
		||||
        } else {
 | 
			
		||||
            this.actor.hide();
 | 
			
		||||
            this.hide();
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let childShown = this.actor.get_child();
 | 
			
		||||
        let childShown = this.get_child();
 | 
			
		||||
        if (childShown != childToShow) {
 | 
			
		||||
            if (childShown) {
 | 
			
		||||
                if (childShown.fake_release)
 | 
			
		||||
@@ -64,8 +74,8 @@ var AltSwitcher = class {
 | 
			
		||||
            }
 | 
			
		||||
            childToShow.add_action(this._clickAction);
 | 
			
		||||
 | 
			
		||||
            let hasFocus = this.actor.contains(global.stage.get_key_focus());
 | 
			
		||||
            this.actor.set_child(childToShow);
 | 
			
		||||
            let hasFocus = this.contains(global.stage.get_key_focus());
 | 
			
		||||
            this.set_child(childToShow);
 | 
			
		||||
            if (hasFocus)
 | 
			
		||||
                childToShow.grab_key_focus();
 | 
			
		||||
 | 
			
		||||
@@ -74,7 +84,7 @@ var AltSwitcher = class {
 | 
			
		||||
            global.sync_pointer();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this.actor.show();
 | 
			
		||||
        this.show();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _onDestroy() {
 | 
			
		||||
@@ -104,11 +114,13 @@ var AltSwitcher = class {
 | 
			
		||||
        this._sync();
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
var Indicator = class extends PanelMenu.SystemIndicator {
 | 
			
		||||
    constructor() {
 | 
			
		||||
        super();
 | 
			
		||||
var Indicator = GObject.registerClass({
 | 
			
		||||
    GTypeName: 'System_Indicator'
 | 
			
		||||
}, class Indicator extends PanelMenu.SystemIndicator {
 | 
			
		||||
    _init() {
 | 
			
		||||
        super._init();
 | 
			
		||||
 | 
			
		||||
        let userManager = AccountsService.UserManager.get_default();
 | 
			
		||||
        this._user = userManager.get_user(GLib.get_user_name());
 | 
			
		||||
@@ -137,15 +149,6 @@ var Indicator = class extends PanelMenu.SystemIndicator {
 | 
			
		||||
        this._sessionUpdated();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _updateActionsVisibility() {
 | 
			
		||||
        let visible = (this._settingsAction.visible ||
 | 
			
		||||
                       this._orientationLockAction.visible ||
 | 
			
		||||
                       this._lockScreenAction.visible ||
 | 
			
		||||
                       this._altSwitcher.actor.visible);
 | 
			
		||||
 | 
			
		||||
        this.buttonGroup.visible = visible;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _sessionUpdated() {
 | 
			
		||||
        this._settingsAction.visible = Main.sessionMode.allowSettings;
 | 
			
		||||
    }
 | 
			
		||||
@@ -253,7 +256,7 @@ var Indicator = class extends PanelMenu.SystemIndicator {
 | 
			
		||||
 | 
			
		||||
        this._orientationLockAction = this._createActionButton('', _("Orientation Lock"));
 | 
			
		||||
        this._orientationLockAction.connect('clicked', () => {
 | 
			
		||||
            this.menu.itemActivated(BoxPointer.PopupAnimation.NONE),
 | 
			
		||||
            this.menu.itemActivated(BoxPointer.PopupAnimation.NONE);
 | 
			
		||||
            this._systemActions.activateLockOrientation();
 | 
			
		||||
        });
 | 
			
		||||
        item.add(this._orientationLockAction, { expand: true, x_fill: false });
 | 
			
		||||
@@ -298,19 +301,22 @@ var Indicator = class extends PanelMenu.SystemIndicator {
 | 
			
		||||
                                          bindFlags);
 | 
			
		||||
 | 
			
		||||
        this._altSwitcher = new AltSwitcher(this._powerOffAction, this._suspendAction);
 | 
			
		||||
        item.add(this._altSwitcher.actor, { expand: true, x_fill: false });
 | 
			
		||||
        item.add(this._altSwitcher, { expand: true, x_fill: false });
 | 
			
		||||
 | 
			
		||||
        this.menu.addMenuItem(item);
 | 
			
		||||
 | 
			
		||||
        let visibilityGroup = [
 | 
			
		||||
            this._settingsAction,
 | 
			
		||||
            this._orientationLockAction,
 | 
			
		||||
            this._lockScreenAction,
 | 
			
		||||
            this._altSwitcher,
 | 
			
		||||
        ];
 | 
			
		||||
 | 
			
		||||
        this._settingsAction.connect('notify::visible',
 | 
			
		||||
                                     () => this._updateActionsVisibility());
 | 
			
		||||
        this._orientationLockAction.connect('notify::visible',
 | 
			
		||||
                                            () => this._updateActionsVisibility());
 | 
			
		||||
        this._lockScreenAction.connect('notify::visible',
 | 
			
		||||
                                       () => this._updateActionsVisibility());
 | 
			
		||||
        this._altSwitcher.actor.connect('notify::visible',
 | 
			
		||||
                                        () => this._updateActionsVisibility());
 | 
			
		||||
        for (let actor of visibilityGroup) {
 | 
			
		||||
            actor.connect('notify::visible', () => {
 | 
			
		||||
                this.buttonGroup.visible = visibilityGroup.some(a => a.visible);
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _onSettingsClicked() {
 | 
			
		||||
@@ -318,4 +324,4 @@ var Indicator = class extends PanelMenu.SystemIndicator {
 | 
			
		||||
        Main.overview.hide();
 | 
			
		||||
        this._settingsApp.activate();
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -3,7 +3,7 @@
 | 
			
		||||
 | 
			
		||||
// the following is a modified version of bolt/contrib/js/client.js
 | 
			
		||||
 | 
			
		||||
const { Gio, GLib, Polkit, Shell } = imports.gi;
 | 
			
		||||
const { Gio, GLib, GObject, Polkit, Shell } = imports.gi;
 | 
			
		||||
const Signals = imports.signals;
 | 
			
		||||
 | 
			
		||||
const Main = imports.ui.main;
 | 
			
		||||
@@ -156,12 +156,12 @@ var AuthRobot = class {
 | 
			
		||||
 | 
			
		||||
        /* check if authorization is enabled in the daemon. if not
 | 
			
		||||
         * we won't even bother authorizing, because we will only
 | 
			
		||||
         * get an error back. The exact contents of AuthMode might 
 | 
			
		||||
         * get an error back. The exact contents of AuthMode might
 | 
			
		||||
         * change in the future, but must contain AuthMode.ENABLED
 | 
			
		||||
         * if it is enabled. */
 | 
			
		||||
        if (!cli.authMode.split('|').includes(AuthMode.ENABLED))
 | 
			
		||||
            return;
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
        /* check if we should enroll the device */
 | 
			
		||||
        let res = [false];
 | 
			
		||||
        this.emit('enroll-device', dev, res);
 | 
			
		||||
@@ -221,9 +221,11 @@ Signals.addSignalMethods(AuthRobot.prototype);
 | 
			
		||||
 | 
			
		||||
/* eof client.js  */
 | 
			
		||||
 | 
			
		||||
var Indicator = class extends PanelMenu.SystemIndicator {
 | 
			
		||||
    constructor() {
 | 
			
		||||
        super();
 | 
			
		||||
var Indicator = GObject.registerClass({
 | 
			
		||||
    GTypeName: 'Thunderbolt_Indicator'
 | 
			
		||||
}, class Indicator extends PanelMenu.SystemIndicator {
 | 
			
		||||
    _init() {
 | 
			
		||||
        super._init();
 | 
			
		||||
 | 
			
		||||
        this._indicator = this._addIndicator();
 | 
			
		||||
        this._indicator.icon_name = 'thunderbolt-symbolic';
 | 
			
		||||
@@ -260,7 +262,7 @@ var Indicator = class extends PanelMenu.SystemIndicator {
 | 
			
		||||
        if (!this._source) {
 | 
			
		||||
            this._source = new MessageTray.Source(_("Thunderbolt"),
 | 
			
		||||
                                                  'thunderbolt-symbolic');
 | 
			
		||||
            this._source.connect('destroy', () => this._source = null);
 | 
			
		||||
            this._source.connect('destroy', () => (this._source = null));
 | 
			
		||||
 | 
			
		||||
            Main.messageTray.add(this._source);
 | 
			
		||||
        }
 | 
			
		||||
@@ -284,7 +286,7 @@ var Indicator = class extends PanelMenu.SystemIndicator {
 | 
			
		||||
            if (app)
 | 
			
		||||
                app.activate();
 | 
			
		||||
        });
 | 
			
		||||
        this._source.notify(this._notification);
 | 
			
		||||
        this._source.showNotification(this._notification);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* Session callbacks */
 | 
			
		||||
@@ -334,4 +336,4 @@ var Indicator = class extends PanelMenu.SystemIndicator {
 | 
			
		||||
        const body = _("Could not authorize the Thunderbolt device: %s").format(error.message);
 | 
			
		||||
        this._notify(title, body);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -47,7 +47,7 @@ var StreamSlider = class {
 | 
			
		||||
            return this._slider.startDragging(event);
 | 
			
		||||
        });
 | 
			
		||||
        this.item.connect('key-press-event', (actor, event) => {
 | 
			
		||||
            return this._slider.onKeyPressEvent(actor, event);
 | 
			
		||||
            return this._slider.emit('key-press-event', event);
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        this._stream = null;
 | 
			
		||||
@@ -228,9 +228,9 @@ var OutputStreamSlider = class extends StreamSlider {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _updateSliderIcon() {
 | 
			
		||||
        this._icon.icon_name = (this._hasHeadphones ?
 | 
			
		||||
                                'audio-headphones-symbolic' :
 | 
			
		||||
                                'audio-speakers-symbolic');
 | 
			
		||||
        this._icon.icon_name = (this._hasHeadphones
 | 
			
		||||
            ? 'audio-headphones-symbolic'
 | 
			
		||||
            : 'audio-speakers-symbolic');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _portChanged() {
 | 
			
		||||
@@ -259,18 +259,17 @@ var InputStreamSlider = class extends StreamSlider {
 | 
			
		||||
    _maybeShowInput() {
 | 
			
		||||
        // only show input widgets if any application is recording audio
 | 
			
		||||
        let showInput = false;
 | 
			
		||||
        let recordingApps = this._control.get_source_outputs();
 | 
			
		||||
        if (this._stream && recordingApps) {
 | 
			
		||||
            for (let i = 0; i < recordingApps.length; i++) {
 | 
			
		||||
                let outputStream = recordingApps[i];
 | 
			
		||||
                let id = outputStream.get_application_id();
 | 
			
		||||
                // but skip gnome-volume-control and pavucontrol
 | 
			
		||||
                // (that appear as recording because they show the input level)
 | 
			
		||||
                if (!id || (id != 'org.gnome.VolumeControl' && id != 'org.PulseAudio.pavucontrol')) {
 | 
			
		||||
                    showInput = true;
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        if (this._stream) {
 | 
			
		||||
            // skip gnome-volume-control and pavucontrol which appear
 | 
			
		||||
            // as recording because they show the input level
 | 
			
		||||
            let skippedApps = [
 | 
			
		||||
                'org.gnome.VolumeControl',
 | 
			
		||||
                'org.PulseAudio.pavucontrol'
 | 
			
		||||
            ];
 | 
			
		||||
 | 
			
		||||
            showInput = this._control.get_source_outputs().some(output => {
 | 
			
		||||
                return !skippedApps.includes(output.get_application_id());
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this._showInput = showInput;
 | 
			
		||||
@@ -300,6 +299,9 @@ var VolumeMenu = class extends PopupMenu.PopupMenuSection {
 | 
			
		||||
        this.addMenuItem(this._output.item);
 | 
			
		||||
 | 
			
		||||
        this._input = new InputStreamSlider(this._control);
 | 
			
		||||
        this._input.item.connect('notify::visible', () => {
 | 
			
		||||
            this.emit('input-visible-changed');
 | 
			
		||||
        });
 | 
			
		||||
        this.addMenuItem(this._input.item);
 | 
			
		||||
 | 
			
		||||
        this.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
 | 
			
		||||
@@ -339,34 +341,44 @@ var VolumeMenu = class extends PopupMenu.PopupMenuSection {
 | 
			
		||||
    getMaxLevel() {
 | 
			
		||||
        return this._output.getMaxLevel();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    getInputVisible() {
 | 
			
		||||
        return this._input.item.visible;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
var Indicator = class extends PanelMenu.SystemIndicator {
 | 
			
		||||
    constructor() {
 | 
			
		||||
        super();
 | 
			
		||||
var Indicator = GObject.registerClass({
 | 
			
		||||
    GTypeName: 'Volume_Indicator'
 | 
			
		||||
}, class Indicator extends PanelMenu.SystemIndicator {
 | 
			
		||||
    _init() {
 | 
			
		||||
        super._init();
 | 
			
		||||
 | 
			
		||||
        this._primaryIndicator = this._addIndicator();
 | 
			
		||||
        this._inputIndicator = this._addIndicator();
 | 
			
		||||
 | 
			
		||||
        this._control = getMixerControl();
 | 
			
		||||
        this._volumeMenu = new VolumeMenu(this._control);
 | 
			
		||||
        this._volumeMenu.connect('icon-changed', () => {
 | 
			
		||||
            let icon = this._volumeMenu.getIcon();
 | 
			
		||||
 | 
			
		||||
            if (icon != null) {
 | 
			
		||||
                this.indicators.show();
 | 
			
		||||
            if (icon != null)
 | 
			
		||||
                this._primaryIndicator.icon_name = icon;
 | 
			
		||||
            } else {
 | 
			
		||||
                this.indicators.hide();
 | 
			
		||||
            }
 | 
			
		||||
            this._primaryIndicator.visible = icon !== null;
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        this._inputIndicator.set({
 | 
			
		||||
            icon_name: 'audio-input-microphone-symbolic',
 | 
			
		||||
            visible: this._volumeMenu.getInputVisible(),
 | 
			
		||||
        });
 | 
			
		||||
        this._volumeMenu.connect('input-visible-changed', () => {
 | 
			
		||||
            this._inputIndicator.visible = this._volumeMenu.getInputVisible();
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        this.menu.addMenuItem(this._volumeMenu);
 | 
			
		||||
 | 
			
		||||
        this.indicators.connect('scroll-event', this._onScrollEvent.bind(this));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _onScrollEvent(actor, event) {
 | 
			
		||||
        let result = this._volumeMenu.scroll(event);
 | 
			
		||||
    vfunc_scroll_event() {
 | 
			
		||||
        let result = this._volumeMenu.scroll(Clutter.get_current_event());
 | 
			
		||||
        if (result == Clutter.EVENT_PROPAGATE || this.menu.actor.mapped)
 | 
			
		||||
            return result;
 | 
			
		||||
 | 
			
		||||
@@ -376,4 +388,4 @@ var Indicator = class extends PanelMenu.SystemIndicator {
 | 
			
		||||
        Main.osdWindowManager.show(-1, gicon, null, level, maxLevel);
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user